GNU Linux-libre 4.14.266-gnu1
[releases.git] / drivers / staging / rtlwifi / halmac / halmac_88xx / halmac_func_88xx.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2016  Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  * The full GNU General Public License is included in this distribution in the
15  * file called LICENSE.
16  *
17  * Contact Information:
18  * wlanfae <wlanfae@realtek.com>
19  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20  * Hsinchu 300, Taiwan.
21  *
22  * Larry Finger <Larry.Finger@lwfinger.net>
23  *
24  *****************************************************************************/
25 #include "halmac_88xx_cfg.h"
26
27 static enum halmac_ret_status
28 halmac_dump_efuse_fw_88xx(struct halmac_adapter *halmac_adapter);
29
30 static enum halmac_ret_status
31 halmac_dump_efuse_drv_88xx(struct halmac_adapter *halmac_adapter);
32
33 static enum halmac_ret_status
34 halmac_update_eeprom_mask_88xx(struct halmac_adapter *halmac_adapter,
35                                struct halmac_pg_efuse_info *pg_efuse_info,
36                                u8 *eeprom_mask_updated);
37
38 static enum halmac_ret_status
39 halmac_check_efuse_enough_88xx(struct halmac_adapter *halmac_adapter,
40                                struct halmac_pg_efuse_info *pg_efuse_info,
41                                u8 *eeprom_mask_updated);
42
43 static enum halmac_ret_status
44 halmac_program_efuse_88xx(struct halmac_adapter *halmac_adapter,
45                           struct halmac_pg_efuse_info *pg_efuse_info,
46                           u8 *eeprom_mask_updated);
47
48 static enum halmac_ret_status
49 halmac_pwr_sub_seq_parer_88xx(struct halmac_adapter *halmac_adapter, u8 cut,
50                               u8 fab, u8 intf,
51                               struct halmac_wl_pwr_cfg_ *pwr_sub_seq_cfg);
52
53 static enum halmac_ret_status
54 halmac_parse_c2h_debug_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
55                             u32 c2h_size);
56
57 static enum halmac_ret_status
58 halmac_parse_scan_status_rpt_88xx(struct halmac_adapter *halmac_adapter,
59                                   u8 *c2h_buf, u32 c2h_size);
60
61 static enum halmac_ret_status
62 halmac_parse_psd_data_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
63                            u32 c2h_size);
64
65 static enum halmac_ret_status
66 halmac_parse_efuse_data_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
67                              u32 c2h_size);
68
69 static enum halmac_ret_status
70 halmac_parse_h2c_ack_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
71                           u32 c2h_size);
72
73 static enum halmac_ret_status
74 halmac_enqueue_para_buff_88xx(struct halmac_adapter *halmac_adapter,
75                               struct halmac_phy_parameter_info *para_info,
76                               u8 *curr_buff_wptr, bool *end_cmd);
77
78 static enum halmac_ret_status
79 halmac_parse_h2c_ack_phy_efuse_88xx(struct halmac_adapter *halmac_adapter,
80                                     u8 *c2h_buf, u32 c2h_size);
81
82 static enum halmac_ret_status
83 halmac_parse_h2c_ack_cfg_para_88xx(struct halmac_adapter *halmac_adapter,
84                                    u8 *c2h_buf, u32 c2h_size);
85
86 static enum halmac_ret_status
87 halmac_gen_cfg_para_h2c_88xx(struct halmac_adapter *halmac_adapter,
88                              u8 *h2c_buff);
89
90 static enum halmac_ret_status
91 halmac_parse_h2c_ack_update_packet_88xx(struct halmac_adapter *halmac_adapter,
92                                         u8 *c2h_buf, u32 c2h_size);
93
94 static enum halmac_ret_status
95 halmac_parse_h2c_ack_update_datapack_88xx(struct halmac_adapter *halmac_adapter,
96                                           u8 *c2h_buf, u32 c2h_size);
97
98 static enum halmac_ret_status
99 halmac_parse_h2c_ack_run_datapack_88xx(struct halmac_adapter *halmac_adapter,
100                                        u8 *c2h_buf, u32 c2h_size);
101
102 static enum halmac_ret_status
103 halmac_parse_h2c_ack_channel_switch_88xx(struct halmac_adapter *halmac_adapter,
104                                          u8 *c2h_buf, u32 c2h_size);
105
106 static enum halmac_ret_status
107 halmac_parse_h2c_ack_iqk_88xx(struct halmac_adapter *halmac_adapter,
108                               u8 *c2h_buf, u32 c2h_size);
109
110 static enum halmac_ret_status
111 halmac_parse_h2c_ack_power_tracking_88xx(struct halmac_adapter *halmac_adapter,
112                                          u8 *c2h_buf, u32 c2h_size);
113
114 void halmac_init_offload_feature_state_machine_88xx(
115         struct halmac_adapter *halmac_adapter)
116 {
117         struct halmac_state *state = &halmac_adapter->halmac_state;
118
119         state->efuse_state_set.efuse_cmd_construct_state =
120                 HALMAC_EFUSE_CMD_CONSTRUCT_IDLE;
121         state->efuse_state_set.process_status = HALMAC_CMD_PROCESS_IDLE;
122         state->efuse_state_set.seq_num = halmac_adapter->h2c_packet_seq;
123
124         state->cfg_para_state_set.cfg_para_cmd_construct_state =
125                 HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE;
126         state->cfg_para_state_set.process_status = HALMAC_CMD_PROCESS_IDLE;
127         state->cfg_para_state_set.seq_num = halmac_adapter->h2c_packet_seq;
128
129         state->scan_state_set.scan_cmd_construct_state =
130                 HALMAC_SCAN_CMD_CONSTRUCT_IDLE;
131         state->scan_state_set.process_status = HALMAC_CMD_PROCESS_IDLE;
132         state->scan_state_set.seq_num = halmac_adapter->h2c_packet_seq;
133
134         state->update_packet_set.process_status = HALMAC_CMD_PROCESS_IDLE;
135         state->update_packet_set.seq_num = halmac_adapter->h2c_packet_seq;
136
137         state->iqk_set.process_status = HALMAC_CMD_PROCESS_IDLE;
138         state->iqk_set.seq_num = halmac_adapter->h2c_packet_seq;
139
140         state->power_tracking_set.process_status = HALMAC_CMD_PROCESS_IDLE;
141         state->power_tracking_set.seq_num = halmac_adapter->h2c_packet_seq;
142
143         state->psd_set.process_status = HALMAC_CMD_PROCESS_IDLE;
144         state->psd_set.seq_num = halmac_adapter->h2c_packet_seq;
145         state->psd_set.data_size = 0;
146         state->psd_set.segment_size = 0;
147         state->psd_set.data = NULL;
148 }
149
150 enum halmac_ret_status
151 halmac_dump_efuse_88xx(struct halmac_adapter *halmac_adapter,
152                        enum halmac_efuse_read_cfg cfg)
153 {
154         u32 chk_h2c_init;
155         void *driver_adapter = NULL;
156         struct halmac_api *halmac_api =
157                 (struct halmac_api *)halmac_adapter->halmac_api;
158         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
159         enum halmac_cmd_process_status *process_status =
160                 &halmac_adapter->halmac_state.efuse_state_set.process_status;
161
162         driver_adapter = halmac_adapter->driver_adapter;
163
164         *process_status = HALMAC_CMD_PROCESS_SENDING;
165
166         if (halmac_transition_efuse_state_88xx(
167                     halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_H2C_SENT) !=
168             HALMAC_RET_SUCCESS)
169                 return HALMAC_RET_ERROR_STATE;
170
171         if (cfg == HALMAC_EFUSE_R_AUTO) {
172                 chk_h2c_init = HALMAC_REG_READ_32(halmac_adapter,
173                                                   REG_H2C_PKT_READADDR);
174                 if (halmac_adapter->halmac_state.dlfw_state ==
175                             HALMAC_DLFW_NONE ||
176                     chk_h2c_init == 0)
177                         status = halmac_dump_efuse_drv_88xx(halmac_adapter);
178                 else
179                         status = halmac_dump_efuse_fw_88xx(halmac_adapter);
180         } else if (cfg == HALMAC_EFUSE_R_FW) {
181                 status = halmac_dump_efuse_fw_88xx(halmac_adapter);
182         } else {
183                 status = halmac_dump_efuse_drv_88xx(halmac_adapter);
184         }
185
186         if (status != HALMAC_RET_SUCCESS) {
187                 pr_err("halmac_read_efuse error = %x\n", status);
188                 return status;
189         }
190
191         return status;
192 }
193
194 enum halmac_ret_status
195 halmac_func_read_efuse_88xx(struct halmac_adapter *halmac_adapter, u32 offset,
196                             u32 size, u8 *efuse_map)
197 {
198         void *driver_adapter = NULL;
199
200         driver_adapter = halmac_adapter->driver_adapter;
201
202         if (!efuse_map) {
203                 pr_err("Malloc for dump efuse map error\n");
204                 return HALMAC_RET_NULL_POINTER;
205         }
206
207         if (halmac_adapter->hal_efuse_map_valid)
208                 memcpy(efuse_map, halmac_adapter->hal_efuse_map + offset, size);
209         else if (halmac_read_hw_efuse_88xx(halmac_adapter, offset, size,
210                                            efuse_map) != HALMAC_RET_SUCCESS)
211                 return HALMAC_RET_EFUSE_R_FAIL;
212
213         return HALMAC_RET_SUCCESS;
214 }
215
216 enum halmac_ret_status
217 halmac_read_hw_efuse_88xx(struct halmac_adapter *halmac_adapter, u32 offset,
218                           u32 size, u8 *efuse_map)
219 {
220         u8 value8;
221         u32 value32;
222         u32 address;
223         u32 tmp32, counter;
224         void *driver_adapter = NULL;
225         struct halmac_api *halmac_api;
226
227         driver_adapter = halmac_adapter->driver_adapter;
228         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
229
230         /* Read efuse no need 2.5V LDO */
231         value8 = HALMAC_REG_READ_8(halmac_adapter, REG_LDO_EFUSE_CTRL + 3);
232         if (value8 & BIT(7))
233                 HALMAC_REG_WRITE_8(halmac_adapter, REG_LDO_EFUSE_CTRL + 3,
234                                    (u8)(value8 & ~(BIT(7))));
235
236         value32 = HALMAC_REG_READ_32(halmac_adapter, REG_EFUSE_CTRL);
237
238         for (address = offset; address < offset + size; address++) {
239                 value32 = value32 &
240                           ~((BIT_MASK_EF_DATA) |
241                             (BIT_MASK_EF_ADDR << BIT_SHIFT_EF_ADDR));
242                 value32 = value32 |
243                           ((address & BIT_MASK_EF_ADDR) << BIT_SHIFT_EF_ADDR);
244                 HALMAC_REG_WRITE_32(halmac_adapter, REG_EFUSE_CTRL,
245                                     value32 & (~BIT_EF_FLAG));
246
247                 counter = 1000000;
248                 do {
249                         udelay(1);
250                         tmp32 = HALMAC_REG_READ_32(halmac_adapter,
251                                                    REG_EFUSE_CTRL);
252                         counter--;
253                         if (counter == 0) {
254                                 pr_err("HALMAC_RET_EFUSE_R_FAIL\n");
255                                 return HALMAC_RET_EFUSE_R_FAIL;
256                         }
257                 } while ((tmp32 & BIT_EF_FLAG) == 0);
258
259                 *(efuse_map + address - offset) =
260                         (u8)(tmp32 & BIT_MASK_EF_DATA);
261         }
262
263         return HALMAC_RET_SUCCESS;
264 }
265
266 static enum halmac_ret_status
267 halmac_dump_efuse_drv_88xx(struct halmac_adapter *halmac_adapter)
268 {
269         u8 *efuse_map = NULL;
270         u32 efuse_size;
271         void *driver_adapter = NULL;
272
273         driver_adapter = halmac_adapter->driver_adapter;
274
275         efuse_size = halmac_adapter->hw_config_info.efuse_size;
276
277         if (!halmac_adapter->hal_efuse_map) {
278                 halmac_adapter->hal_efuse_map = kzalloc(efuse_size, GFP_KERNEL);
279                 if (!halmac_adapter->hal_efuse_map) {
280                         pr_err("[ERR]halmac allocate efuse map Fail!!\n");
281                         return HALMAC_RET_MALLOC_FAIL;
282                 }
283         }
284
285         efuse_map = kzalloc(efuse_size, GFP_KERNEL);
286         if (!efuse_map) {
287                 /* out of memory */
288                 return HALMAC_RET_MALLOC_FAIL;
289         }
290
291         if (halmac_read_hw_efuse_88xx(halmac_adapter, 0, efuse_size,
292                                       efuse_map) != HALMAC_RET_SUCCESS) {
293                 kfree(efuse_map);
294                 return HALMAC_RET_EFUSE_R_FAIL;
295         }
296
297         spin_lock(&halmac_adapter->efuse_lock);
298         memcpy(halmac_adapter->hal_efuse_map, efuse_map, efuse_size);
299         halmac_adapter->hal_efuse_map_valid = true;
300         spin_unlock(&halmac_adapter->efuse_lock);
301
302         kfree(efuse_map);
303
304         return HALMAC_RET_SUCCESS;
305 }
306
307 static enum halmac_ret_status
308 halmac_dump_efuse_fw_88xx(struct halmac_adapter *halmac_adapter)
309 {
310         u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
311         u16 h2c_seq_mum = 0;
312         void *driver_adapter = NULL;
313         struct halmac_h2c_header_info h2c_header_info;
314         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
315
316         driver_adapter = halmac_adapter->driver_adapter;
317
318         h2c_header_info.sub_cmd_id = SUB_CMD_ID_DUMP_PHYSICAL_EFUSE;
319         h2c_header_info.content_size = 0;
320         h2c_header_info.ack = true;
321         halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
322                                               &h2c_header_info, &h2c_seq_mum);
323         halmac_adapter->halmac_state.efuse_state_set.seq_num = h2c_seq_mum;
324
325         if (!halmac_adapter->hal_efuse_map) {
326                 halmac_adapter->hal_efuse_map = kzalloc(
327                         halmac_adapter->hw_config_info.efuse_size, GFP_KERNEL);
328                 if (!halmac_adapter->hal_efuse_map) {
329                         /* out of memory */
330                         return HALMAC_RET_MALLOC_FAIL;
331                 }
332         }
333
334         if (!halmac_adapter->hal_efuse_map_valid) {
335                 status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
336                                                   HALMAC_H2C_CMD_SIZE_88XX,
337                                                   true);
338                 if (status != HALMAC_RET_SUCCESS) {
339                         pr_err("halmac_read_efuse_fw Fail = %x!!\n", status);
340                         return status;
341                 }
342         }
343
344         return HALMAC_RET_SUCCESS;
345 }
346
347 enum halmac_ret_status
348 halmac_func_write_efuse_88xx(struct halmac_adapter *halmac_adapter, u32 offset,
349                              u8 value)
350 {
351         const u8 wite_protect_code = 0x69;
352         u32 value32, tmp32, counter;
353         void *driver_adapter = NULL;
354         struct halmac_api *halmac_api;
355
356         driver_adapter = halmac_adapter->driver_adapter;
357         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
358
359         spin_lock(&halmac_adapter->efuse_lock);
360         halmac_adapter->hal_efuse_map_valid = false;
361         spin_unlock(&halmac_adapter->efuse_lock);
362
363         HALMAC_REG_WRITE_8(halmac_adapter, REG_PMC_DBG_CTRL2 + 3,
364                            wite_protect_code);
365
366         /* Enable 2.5V LDO */
367         HALMAC_REG_WRITE_8(
368                 halmac_adapter, REG_LDO_EFUSE_CTRL + 3,
369                 (u8)(HALMAC_REG_READ_8(halmac_adapter, REG_LDO_EFUSE_CTRL + 3) |
370                      BIT(7)));
371
372         value32 = HALMAC_REG_READ_32(halmac_adapter, REG_EFUSE_CTRL);
373         value32 =
374                 value32 &
375                 ~((BIT_MASK_EF_DATA) | (BIT_MASK_EF_ADDR << BIT_SHIFT_EF_ADDR));
376         value32 = value32 | ((offset & BIT_MASK_EF_ADDR) << BIT_SHIFT_EF_ADDR) |
377                   (value & BIT_MASK_EF_DATA);
378         HALMAC_REG_WRITE_32(halmac_adapter, REG_EFUSE_CTRL,
379                             value32 | BIT_EF_FLAG);
380
381         counter = 1000000;
382         do {
383                 udelay(1);
384                 tmp32 = HALMAC_REG_READ_32(halmac_adapter, REG_EFUSE_CTRL);
385                 counter--;
386                 if (counter == 0) {
387                         pr_err("halmac_write_efuse Fail !!\n");
388                         return HALMAC_RET_EFUSE_W_FAIL;
389                 }
390         } while ((tmp32 & BIT_EF_FLAG) == BIT_EF_FLAG);
391
392         HALMAC_REG_WRITE_8(halmac_adapter, REG_PMC_DBG_CTRL2 + 3, 0x00);
393
394         /* Disable 2.5V LDO */
395         HALMAC_REG_WRITE_8(
396                 halmac_adapter, REG_LDO_EFUSE_CTRL + 3,
397                 (u8)(HALMAC_REG_READ_8(halmac_adapter, REG_LDO_EFUSE_CTRL + 3) &
398                      ~(BIT(7))));
399
400         return HALMAC_RET_SUCCESS;
401 }
402
403 enum halmac_ret_status
404 halmac_func_switch_efuse_bank_88xx(struct halmac_adapter *halmac_adapter,
405                                    enum halmac_efuse_bank efuse_bank)
406 {
407         u8 reg_value;
408         struct halmac_api *halmac_api;
409
410         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
411
412         if (halmac_transition_efuse_state_88xx(
413                     halmac_adapter, HALMAC_EFUSE_CMD_CONSTRUCT_BUSY) !=
414             HALMAC_RET_SUCCESS)
415                 return HALMAC_RET_ERROR_STATE;
416
417         reg_value = HALMAC_REG_READ_8(halmac_adapter, REG_LDO_EFUSE_CTRL + 1);
418
419         if (efuse_bank == (reg_value & (BIT(0) | BIT(1))))
420                 return HALMAC_RET_SUCCESS;
421
422         reg_value &= ~(BIT(0) | BIT(1));
423         reg_value |= efuse_bank;
424         HALMAC_REG_WRITE_8(halmac_adapter, REG_LDO_EFUSE_CTRL + 1, reg_value);
425
426         if ((HALMAC_REG_READ_8(halmac_adapter, REG_LDO_EFUSE_CTRL + 1) &
427              (BIT(0) | BIT(1))) != efuse_bank)
428                 return HALMAC_RET_SWITCH_EFUSE_BANK_FAIL;
429
430         return HALMAC_RET_SUCCESS;
431 }
432
433 enum halmac_ret_status
434 halmac_eeprom_parser_88xx(struct halmac_adapter *halmac_adapter,
435                           u8 *physical_efuse_map, u8 *logical_efuse_map)
436 {
437         u8 j;
438         u8 value8;
439         u8 block_index;
440         u8 valid_word_enable, word_enable;
441         u8 efuse_read_header, efuse_read_header2 = 0;
442         u32 eeprom_index;
443         u32 efuse_index = 0;
444         u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
445         void *driver_adapter = NULL;
446
447         driver_adapter = halmac_adapter->driver_adapter;
448
449         memset(logical_efuse_map, 0xFF, eeprom_size);
450
451         do {
452                 value8 = *(physical_efuse_map + efuse_index);
453                 efuse_read_header = value8;
454
455                 if ((efuse_read_header & 0x1f) == 0x0f) {
456                         efuse_index++;
457                         value8 = *(physical_efuse_map + efuse_index);
458                         efuse_read_header2 = value8;
459                         block_index = ((efuse_read_header2 & 0xF0) >> 1) |
460                                       ((efuse_read_header >> 5) & 0x07);
461                         word_enable = efuse_read_header2 & 0x0F;
462                 } else {
463                         block_index = (efuse_read_header & 0xF0) >> 4;
464                         word_enable = efuse_read_header & 0x0F;
465                 }
466
467                 if (efuse_read_header == 0xff)
468                         break;
469
470                 efuse_index++;
471
472                 if (efuse_index >= halmac_adapter->hw_config_info.efuse_size -
473                                            HALMAC_PROTECTED_EFUSE_SIZE_88XX - 1)
474                         return HALMAC_RET_EEPROM_PARSING_FAIL;
475
476                 for (j = 0; j < 4; j++) {
477                         valid_word_enable =
478                                 (u8)((~(word_enable >> j)) & BIT(0));
479                         if (valid_word_enable != 1)
480                                 continue;
481
482                         eeprom_index = (block_index << 3) + (j << 1);
483
484                         if ((eeprom_index + 1) > eeprom_size) {
485                                 pr_err("Error: EEPROM addr exceeds eeprom_size:0x%X, at eFuse 0x%X\n",
486                                        eeprom_size, efuse_index - 1);
487                                 if ((efuse_read_header & 0x1f) == 0x0f)
488                                         pr_err("Error: EEPROM header: 0x%X, 0x%X,\n",
489                                                efuse_read_header,
490                                                efuse_read_header2);
491                                 else
492                                         pr_err("Error: EEPROM header: 0x%X,\n",
493                                                efuse_read_header);
494
495                                 return HALMAC_RET_EEPROM_PARSING_FAIL;
496                         }
497
498                         value8 = *(physical_efuse_map + efuse_index);
499                         *(logical_efuse_map + eeprom_index) = value8;
500
501                         eeprom_index++;
502                         efuse_index++;
503
504                         if (efuse_index >
505                             halmac_adapter->hw_config_info.efuse_size -
506                                     HALMAC_PROTECTED_EFUSE_SIZE_88XX - 1)
507                                 return HALMAC_RET_EEPROM_PARSING_FAIL;
508
509                         value8 = *(physical_efuse_map + efuse_index);
510                         *(logical_efuse_map + eeprom_index) = value8;
511
512                         efuse_index++;
513
514                         if (efuse_index >
515                             halmac_adapter->hw_config_info.efuse_size -
516                                     HALMAC_PROTECTED_EFUSE_SIZE_88XX)
517                                 return HALMAC_RET_EEPROM_PARSING_FAIL;
518                 }
519         } while (1);
520
521         halmac_adapter->efuse_end = efuse_index;
522
523         return HALMAC_RET_SUCCESS;
524 }
525
526 enum halmac_ret_status
527 halmac_read_logical_efuse_map_88xx(struct halmac_adapter *halmac_adapter,
528                                    u8 *map)
529 {
530         u8 *efuse_map = NULL;
531         u32 efuse_size;
532         void *driver_adapter = NULL;
533         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
534
535         driver_adapter = halmac_adapter->driver_adapter;
536         efuse_size = halmac_adapter->hw_config_info.efuse_size;
537
538         if (!halmac_adapter->hal_efuse_map_valid) {
539                 efuse_map = kzalloc(efuse_size, GFP_KERNEL);
540                 if (!efuse_map) {
541                         pr_err("[ERR]halmac allocate local efuse map Fail!!\n");
542                         return HALMAC_RET_MALLOC_FAIL;
543                 }
544
545                 status = halmac_func_read_efuse_88xx(halmac_adapter, 0,
546                                                      efuse_size, efuse_map);
547                 if (status != HALMAC_RET_SUCCESS) {
548                         pr_err("[ERR]halmac_read_efuse error = %x\n", status);
549                         kfree(efuse_map);
550                         return status;
551                 }
552
553                 if (!halmac_adapter->hal_efuse_map) {
554                         halmac_adapter->hal_efuse_map =
555                                 kzalloc(efuse_size, GFP_KERNEL);
556                         if (!halmac_adapter->hal_efuse_map) {
557                                 pr_err("[ERR]halmac allocate efuse map Fail!!\n");
558                                 kfree(efuse_map);
559                                 return HALMAC_RET_MALLOC_FAIL;
560                         }
561                 }
562
563                 spin_lock(&halmac_adapter->efuse_lock);
564                 memcpy(halmac_adapter->hal_efuse_map, efuse_map, efuse_size);
565                 halmac_adapter->hal_efuse_map_valid = true;
566                 spin_unlock(&halmac_adapter->efuse_lock);
567
568                 kfree(efuse_map);
569         }
570
571         if (halmac_eeprom_parser_88xx(halmac_adapter,
572                                       halmac_adapter->hal_efuse_map,
573                                       map) != HALMAC_RET_SUCCESS)
574                 return HALMAC_RET_EEPROM_PARSING_FAIL;
575
576         return status;
577 }
578
579 enum halmac_ret_status
580 halmac_func_write_logical_efuse_88xx(struct halmac_adapter *halmac_adapter,
581                                      u32 offset, u8 value)
582 {
583         u8 pg_efuse_byte1, pg_efuse_byte2;
584         u8 pg_block, pg_block_index;
585         u8 pg_efuse_header, pg_efuse_header2;
586         u8 *eeprom_map = NULL;
587         u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
588         u32 efuse_end, pg_efuse_num;
589         void *driver_adapter = NULL;
590         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
591
592         driver_adapter = halmac_adapter->driver_adapter;
593
594         eeprom_map = kzalloc(eeprom_size, GFP_KERNEL);
595         if (!eeprom_map) {
596                 /* out of memory */
597                 return HALMAC_RET_MALLOC_FAIL;
598         }
599         memset(eeprom_map, 0xFF, eeprom_size);
600
601         status = halmac_read_logical_efuse_map_88xx(halmac_adapter, eeprom_map);
602         if (status != HALMAC_RET_SUCCESS) {
603                 pr_err("[ERR]halmac_read_logical_efuse_map_88xx error = %x\n",
604                        status);
605                 kfree(eeprom_map);
606                 return status;
607         }
608
609         if (*(eeprom_map + offset) != value) {
610                 efuse_end = halmac_adapter->efuse_end;
611                 pg_block = (u8)(offset >> 3);
612                 pg_block_index = (u8)((offset & (8 - 1)) >> 1);
613
614                 if (offset > 0x7f) {
615                         pg_efuse_header =
616                                 (((pg_block & 0x07) << 5) & 0xE0) | 0x0F;
617                         pg_efuse_header2 =
618                                 (u8)(((pg_block & 0x78) << 1) +
619                                      ((0x1 << pg_block_index) ^ 0x0F));
620                 } else {
621                         pg_efuse_header =
622                                 (u8)((pg_block << 4) +
623                                      ((0x01 << pg_block_index) ^ 0x0F));
624                 }
625
626                 if ((offset & 1) == 0) {
627                         pg_efuse_byte1 = value;
628                         pg_efuse_byte2 = *(eeprom_map + offset + 1);
629                 } else {
630                         pg_efuse_byte1 = *(eeprom_map + offset - 1);
631                         pg_efuse_byte2 = value;
632                 }
633
634                 if (offset > 0x7f) {
635                         pg_efuse_num = 4;
636                         if (halmac_adapter->hw_config_info.efuse_size <=
637                             (pg_efuse_num + HALMAC_PROTECTED_EFUSE_SIZE_88XX +
638                              halmac_adapter->efuse_end)) {
639                                 kfree(eeprom_map);
640                                 return HALMAC_RET_EFUSE_NOT_ENOUGH;
641                         }
642                         halmac_func_write_efuse_88xx(halmac_adapter, efuse_end,
643                                                      pg_efuse_header);
644                         halmac_func_write_efuse_88xx(halmac_adapter,
645                                                      efuse_end + 1,
646                                                      pg_efuse_header2);
647                         halmac_func_write_efuse_88xx(
648                                 halmac_adapter, efuse_end + 2, pg_efuse_byte1);
649                         status = halmac_func_write_efuse_88xx(
650                                 halmac_adapter, efuse_end + 3, pg_efuse_byte2);
651                 } else {
652                         pg_efuse_num = 3;
653                         if (halmac_adapter->hw_config_info.efuse_size <=
654                             (pg_efuse_num + HALMAC_PROTECTED_EFUSE_SIZE_88XX +
655                              halmac_adapter->efuse_end)) {
656                                 kfree(eeprom_map);
657                                 return HALMAC_RET_EFUSE_NOT_ENOUGH;
658                         }
659                         halmac_func_write_efuse_88xx(halmac_adapter, efuse_end,
660                                                      pg_efuse_header);
661                         halmac_func_write_efuse_88xx(
662                                 halmac_adapter, efuse_end + 1, pg_efuse_byte1);
663                         status = halmac_func_write_efuse_88xx(
664                                 halmac_adapter, efuse_end + 2, pg_efuse_byte2);
665                 }
666
667                 if (status != HALMAC_RET_SUCCESS) {
668                         pr_err("[ERR]halmac_write_logical_efuse error = %x\n",
669                                status);
670                         kfree(eeprom_map);
671                         return status;
672                 }
673         }
674
675         kfree(eeprom_map);
676
677         return HALMAC_RET_SUCCESS;
678 }
679
680 enum halmac_ret_status
681 halmac_func_pg_efuse_by_map_88xx(struct halmac_adapter *halmac_adapter,
682                                  struct halmac_pg_efuse_info *pg_efuse_info,
683                                  enum halmac_efuse_read_cfg cfg)
684 {
685         u8 *eeprom_mask_updated = NULL;
686         u32 eeprom_mask_size = halmac_adapter->hw_config_info.eeprom_size >> 4;
687         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
688
689         eeprom_mask_updated = kzalloc(eeprom_mask_size, GFP_KERNEL);
690         if (!eeprom_mask_updated) {
691                 /* out of memory */
692                 return HALMAC_RET_MALLOC_FAIL;
693         }
694
695         status = halmac_update_eeprom_mask_88xx(halmac_adapter, pg_efuse_info,
696                                                 eeprom_mask_updated);
697
698         if (status != HALMAC_RET_SUCCESS) {
699                 pr_err("[ERR]halmac_update_eeprom_mask_88xx error = %x\n",
700                        status);
701                 kfree(eeprom_mask_updated);
702                 return status;
703         }
704
705         status = halmac_check_efuse_enough_88xx(halmac_adapter, pg_efuse_info,
706                                                 eeprom_mask_updated);
707
708         if (status != HALMAC_RET_SUCCESS) {
709                 pr_err("[ERR]halmac_check_efuse_enough_88xx error = %x\n",
710                        status);
711                 kfree(eeprom_mask_updated);
712                 return status;
713         }
714
715         status = halmac_program_efuse_88xx(halmac_adapter, pg_efuse_info,
716                                            eeprom_mask_updated);
717
718         if (status != HALMAC_RET_SUCCESS) {
719                 pr_err("[ERR]halmac_program_efuse_88xx error = %x\n", status);
720                 kfree(eeprom_mask_updated);
721                 return status;
722         }
723
724         kfree(eeprom_mask_updated);
725
726         return HALMAC_RET_SUCCESS;
727 }
728
729 static enum halmac_ret_status
730 halmac_update_eeprom_mask_88xx(struct halmac_adapter *halmac_adapter,
731                                struct halmac_pg_efuse_info *pg_efuse_info,
732                                u8 *eeprom_mask_updated)
733 {
734         u8 *eeprom_map = NULL;
735         u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
736         u8 *eeprom_map_pg, *eeprom_mask;
737         u16 i, j;
738         u16 map_byte_offset, mask_byte_offset;
739         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
740
741         void *driver_adapter = NULL;
742
743         driver_adapter = halmac_adapter->driver_adapter;
744
745         eeprom_map = kzalloc(eeprom_size, GFP_KERNEL);
746         if (!eeprom_map) {
747                 /* out of memory */
748                 return HALMAC_RET_MALLOC_FAIL;
749         }
750         memset(eeprom_map, 0xFF, eeprom_size);
751
752         memset(eeprom_mask_updated, 0x00, pg_efuse_info->efuse_mask_size);
753
754         status = halmac_read_logical_efuse_map_88xx(halmac_adapter, eeprom_map);
755
756         if (status != HALMAC_RET_SUCCESS) {
757                 kfree(eeprom_map);
758                 return status;
759         }
760
761         eeprom_map_pg = pg_efuse_info->efuse_map;
762         eeprom_mask = pg_efuse_info->efuse_mask;
763
764         for (i = 0; i < pg_efuse_info->efuse_mask_size; i++)
765                 *(eeprom_mask_updated + i) = *(eeprom_mask + i);
766
767         for (i = 0; i < pg_efuse_info->efuse_map_size; i = i + 16) {
768                 for (j = 0; j < 16; j = j + 2) {
769                         map_byte_offset = i + j;
770                         mask_byte_offset = i >> 4;
771                         if (*(eeprom_map_pg + map_byte_offset) ==
772                             *(eeprom_map + map_byte_offset)) {
773                                 if (*(eeprom_map_pg + map_byte_offset + 1) ==
774                                     *(eeprom_map + map_byte_offset + 1)) {
775                                         switch (j) {
776                                         case 0:
777                                                 *(eeprom_mask_updated +
778                                                   mask_byte_offset) =
779                                                         *(eeprom_mask_updated +
780                                                           mask_byte_offset) &
781                                                         (BIT(4) ^ 0xFF);
782                                                 break;
783                                         case 2:
784                                                 *(eeprom_mask_updated +
785                                                   mask_byte_offset) =
786                                                         *(eeprom_mask_updated +
787                                                           mask_byte_offset) &
788                                                         (BIT(5) ^ 0xFF);
789                                                 break;
790                                         case 4:
791                                                 *(eeprom_mask_updated +
792                                                   mask_byte_offset) =
793                                                         *(eeprom_mask_updated +
794                                                           mask_byte_offset) &
795                                                         (BIT(6) ^ 0xFF);
796                                                 break;
797                                         case 6:
798                                                 *(eeprom_mask_updated +
799                                                   mask_byte_offset) =
800                                                         *(eeprom_mask_updated +
801                                                           mask_byte_offset) &
802                                                         (BIT(7) ^ 0xFF);
803                                                 break;
804                                         case 8:
805                                                 *(eeprom_mask_updated +
806                                                   mask_byte_offset) =
807                                                         *(eeprom_mask_updated +
808                                                           mask_byte_offset) &
809                                                         (BIT(0) ^ 0xFF);
810                                                 break;
811                                         case 10:
812                                                 *(eeprom_mask_updated +
813                                                   mask_byte_offset) =
814                                                         *(eeprom_mask_updated +
815                                                           mask_byte_offset) &
816                                                         (BIT(1) ^ 0xFF);
817                                                 break;
818                                         case 12:
819                                                 *(eeprom_mask_updated +
820                                                   mask_byte_offset) =
821                                                         *(eeprom_mask_updated +
822                                                           mask_byte_offset) &
823                                                         (BIT(2) ^ 0xFF);
824                                                 break;
825                                         case 14:
826                                                 *(eeprom_mask_updated +
827                                                   mask_byte_offset) =
828                                                         *(eeprom_mask_updated +
829                                                           mask_byte_offset) &
830                                                         (BIT(3) ^ 0xFF);
831                                                 break;
832                                         default:
833                                                 break;
834                                         }
835                                 }
836                         }
837                 }
838         }
839
840         kfree(eeprom_map);
841
842         return status;
843 }
844
845 static enum halmac_ret_status
846 halmac_check_efuse_enough_88xx(struct halmac_adapter *halmac_adapter,
847                                struct halmac_pg_efuse_info *pg_efuse_info,
848                                u8 *eeprom_mask_updated)
849 {
850         u8 pre_word_enb, word_enb;
851         u8 pg_efuse_header, pg_efuse_header2;
852         u8 pg_block;
853         u16 i, j;
854         u32 efuse_end;
855         u32 tmp_eeprom_offset, pg_efuse_num = 0;
856
857         efuse_end = halmac_adapter->efuse_end;
858
859         for (i = 0; i < pg_efuse_info->efuse_map_size; i = i + 8) {
860                 tmp_eeprom_offset = i;
861
862                 if ((tmp_eeprom_offset & 7) > 0) {
863                         pre_word_enb =
864                                 (*(eeprom_mask_updated + (i >> 4)) & 0x0F);
865                         word_enb = pre_word_enb ^ 0x0F;
866                 } else {
867                         pre_word_enb = (*(eeprom_mask_updated + (i >> 4)) >> 4);
868                         word_enb = pre_word_enb ^ 0x0F;
869                 }
870
871                 pg_block = (u8)(tmp_eeprom_offset >> 3);
872
873                 if (pre_word_enb > 0) {
874                         if (tmp_eeprom_offset > 0x7f) {
875                                 pg_efuse_header =
876                                         (((pg_block & 0x07) << 5) & 0xE0) |
877                                         0x0F;
878                                 pg_efuse_header2 = (u8)(
879                                         ((pg_block & 0x78) << 1) + word_enb);
880                         } else {
881                                 pg_efuse_header =
882                                         (u8)((pg_block << 4) + word_enb);
883                         }
884
885                         if (tmp_eeprom_offset > 0x7f) {
886                                 pg_efuse_num++;
887                                 pg_efuse_num++;
888                                 efuse_end = efuse_end + 2;
889                                 for (j = 0; j < 4; j++) {
890                                         if (((pre_word_enb >> j) & 0x1) > 0) {
891                                                 pg_efuse_num++;
892                                                 pg_efuse_num++;
893                                                 efuse_end = efuse_end + 2;
894                                         }
895                                 }
896                         } else {
897                                 pg_efuse_num++;
898                                 efuse_end = efuse_end + 1;
899                                 for (j = 0; j < 4; j++) {
900                                         if (((pre_word_enb >> j) & 0x1) > 0) {
901                                                 pg_efuse_num++;
902                                                 pg_efuse_num++;
903                                                 efuse_end = efuse_end + 2;
904                                         }
905                                 }
906                         }
907                 }
908         }
909
910         if (halmac_adapter->hw_config_info.efuse_size <=
911             (pg_efuse_num + HALMAC_PROTECTED_EFUSE_SIZE_88XX +
912              halmac_adapter->efuse_end))
913                 return HALMAC_RET_EFUSE_NOT_ENOUGH;
914
915         return HALMAC_RET_SUCCESS;
916 }
917
918 static enum halmac_ret_status
919 halmac_program_efuse_88xx(struct halmac_adapter *halmac_adapter,
920                           struct halmac_pg_efuse_info *pg_efuse_info,
921                           u8 *eeprom_mask_updated)
922 {
923         u8 pre_word_enb, word_enb;
924         u8 pg_efuse_header, pg_efuse_header2;
925         u8 pg_block;
926         u16 i, j;
927         u32 efuse_end;
928         u32 tmp_eeprom_offset;
929         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
930
931         efuse_end = halmac_adapter->efuse_end;
932
933         for (i = 0; i < pg_efuse_info->efuse_map_size; i = i + 8) {
934                 tmp_eeprom_offset = i;
935
936                 if (((tmp_eeprom_offset >> 3) & 1) > 0) {
937                         pre_word_enb =
938                                 (*(eeprom_mask_updated + (i >> 4)) & 0x0F);
939                         word_enb = pre_word_enb ^ 0x0F;
940                 } else {
941                         pre_word_enb = (*(eeprom_mask_updated + (i >> 4)) >> 4);
942                         word_enb = pre_word_enb ^ 0x0F;
943                 }
944
945                 pg_block = (u8)(tmp_eeprom_offset >> 3);
946
947                 if (pre_word_enb <= 0)
948                         continue;
949
950                 if (tmp_eeprom_offset > 0x7f) {
951                         pg_efuse_header =
952                                 (((pg_block & 0x07) << 5) & 0xE0) | 0x0F;
953                         pg_efuse_header2 =
954                                 (u8)(((pg_block & 0x78) << 1) + word_enb);
955                 } else {
956                         pg_efuse_header = (u8)((pg_block << 4) + word_enb);
957                 }
958
959                 if (tmp_eeprom_offset > 0x7f) {
960                         halmac_func_write_efuse_88xx(halmac_adapter, efuse_end,
961                                                      pg_efuse_header);
962                         status = halmac_func_write_efuse_88xx(halmac_adapter,
963                                                               efuse_end + 1,
964                                                               pg_efuse_header2);
965                         efuse_end = efuse_end + 2;
966                         for (j = 0; j < 4; j++) {
967                                 if (((pre_word_enb >> j) & 0x1) > 0) {
968                                         halmac_func_write_efuse_88xx(
969                                                 halmac_adapter, efuse_end,
970                                                 *(pg_efuse_info->efuse_map +
971                                                   tmp_eeprom_offset +
972                                                   (j << 1)));
973                                         status = halmac_func_write_efuse_88xx(
974                                                 halmac_adapter, efuse_end + 1,
975                                                 *(pg_efuse_info->efuse_map +
976                                                   tmp_eeprom_offset + (j << 1) +
977                                                   1));
978                                         efuse_end = efuse_end + 2;
979                                 }
980                         }
981                 } else {
982                         status = halmac_func_write_efuse_88xx(
983                                 halmac_adapter, efuse_end, pg_efuse_header);
984                         efuse_end = efuse_end + 1;
985                         for (j = 0; j < 4; j++) {
986                                 if (((pre_word_enb >> j) & 0x1) > 0) {
987                                         halmac_func_write_efuse_88xx(
988                                                 halmac_adapter, efuse_end,
989                                                 *(pg_efuse_info->efuse_map +
990                                                   tmp_eeprom_offset +
991                                                   (j << 1)));
992                                         status = halmac_func_write_efuse_88xx(
993                                                 halmac_adapter, efuse_end + 1,
994                                                 *(pg_efuse_info->efuse_map +
995                                                   tmp_eeprom_offset + (j << 1) +
996                                                   1));
997                                         efuse_end = efuse_end + 2;
998                                 }
999                         }
1000                 }
1001         }
1002
1003         return status;
1004 }
1005
1006 enum halmac_ret_status
1007 halmac_dlfw_to_mem_88xx(struct halmac_adapter *halmac_adapter, u8 *ram_code,
1008                         u32 dest, u32 code_size)
1009 {
1010         u8 *code_ptr;
1011         u8 first_part;
1012         u32 mem_offset;
1013         u32 pkt_size_tmp, send_pkt_size;
1014         void *driver_adapter = NULL;
1015         struct halmac_api *halmac_api;
1016
1017         driver_adapter = halmac_adapter->driver_adapter;
1018         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1019
1020         code_ptr = ram_code;
1021         mem_offset = 0;
1022         first_part = 1;
1023         pkt_size_tmp = code_size;
1024
1025         HALMAC_REG_WRITE_32(
1026                 halmac_adapter, REG_DDMA_CH0CTRL,
1027                 HALMAC_REG_READ_32(halmac_adapter, REG_DDMA_CH0CTRL) |
1028                         BIT_DDMACH0_RESET_CHKSUM_STS);
1029
1030         while (pkt_size_tmp != 0) {
1031                 if (pkt_size_tmp >= halmac_adapter->max_download_size)
1032                         send_pkt_size = halmac_adapter->max_download_size;
1033                 else
1034                         send_pkt_size = pkt_size_tmp;
1035
1036                 if (halmac_send_fwpkt_88xx(
1037                             halmac_adapter, code_ptr + mem_offset,
1038                             send_pkt_size) != HALMAC_RET_SUCCESS) {
1039                         pr_err("halmac_send_fwpkt_88xx fail!!");
1040                         return HALMAC_RET_DLFW_FAIL;
1041                 }
1042
1043                 if (halmac_iddma_dlfw_88xx(
1044                             halmac_adapter,
1045                             HALMAC_OCPBASE_TXBUF_88XX +
1046                                     halmac_adapter->hw_config_info.txdesc_size,
1047                             dest + mem_offset, send_pkt_size,
1048                             first_part) != HALMAC_RET_SUCCESS) {
1049                         pr_err("halmac_iddma_dlfw_88xx fail!!");
1050                         return HALMAC_RET_DLFW_FAIL;
1051                 }
1052
1053                 first_part = 0;
1054                 mem_offset += send_pkt_size;
1055                 pkt_size_tmp -= send_pkt_size;
1056         }
1057
1058         if (halmac_check_fw_chksum_88xx(halmac_adapter, dest) !=
1059             HALMAC_RET_SUCCESS) {
1060                 pr_err("halmac_check_fw_chksum_88xx fail!!");
1061                 return HALMAC_RET_DLFW_FAIL;
1062         }
1063
1064         return HALMAC_RET_SUCCESS;
1065 }
1066
1067 enum halmac_ret_status
1068 halmac_send_fwpkt_88xx(struct halmac_adapter *halmac_adapter, u8 *ram_code,
1069                        u32 code_size)
1070 {
1071         if (halmac_download_rsvd_page_88xx(halmac_adapter, ram_code,
1072                                            code_size) != HALMAC_RET_SUCCESS) {
1073                 pr_err("PLATFORM_SEND_RSVD_PAGE 0 error!!\n");
1074                 return HALMAC_RET_DL_RSVD_PAGE_FAIL;
1075         }
1076
1077         return HALMAC_RET_SUCCESS;
1078 }
1079
1080 enum halmac_ret_status
1081 halmac_iddma_dlfw_88xx(struct halmac_adapter *halmac_adapter, u32 source,
1082                        u32 dest, u32 length, u8 first)
1083 {
1084         u32 counter;
1085         u32 ch0_control = (u32)(BIT_DDMACH0_CHKSUM_EN | BIT_DDMACH0_OWN);
1086         void *driver_adapter = NULL;
1087         struct halmac_api *halmac_api;
1088
1089         driver_adapter = halmac_adapter->driver_adapter;
1090         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1091
1092         counter = HALMC_DDMA_POLLING_COUNT;
1093         while (HALMAC_REG_READ_32(halmac_adapter, REG_DDMA_CH0CTRL) &
1094                BIT_DDMACH0_OWN) {
1095                 counter--;
1096                 if (counter == 0) {
1097                         pr_err("%s error-1!!\n", __func__);
1098                         return HALMAC_RET_DDMA_FAIL;
1099                 }
1100         }
1101
1102         ch0_control |= (length & BIT_MASK_DDMACH0_DLEN);
1103         if (first == 0)
1104                 ch0_control |= BIT_DDMACH0_CHKSUM_CONT;
1105
1106         HALMAC_REG_WRITE_32(halmac_adapter, REG_DDMA_CH0SA, source);
1107         HALMAC_REG_WRITE_32(halmac_adapter, REG_DDMA_CH0DA, dest);
1108         HALMAC_REG_WRITE_32(halmac_adapter, REG_DDMA_CH0CTRL, ch0_control);
1109
1110         counter = HALMC_DDMA_POLLING_COUNT;
1111         while (HALMAC_REG_READ_32(halmac_adapter, REG_DDMA_CH0CTRL) &
1112                BIT_DDMACH0_OWN) {
1113                 counter--;
1114                 if (counter == 0) {
1115                         pr_err("%s error-2!!\n", __func__);
1116                         return HALMAC_RET_DDMA_FAIL;
1117                 }
1118         }
1119
1120         return HALMAC_RET_SUCCESS;
1121 }
1122
1123 enum halmac_ret_status
1124 halmac_check_fw_chksum_88xx(struct halmac_adapter *halmac_adapter,
1125                             u32 memory_address)
1126 {
1127         u8 mcu_fw_ctrl;
1128         void *driver_adapter = NULL;
1129         struct halmac_api *halmac_api;
1130         enum halmac_ret_status status;
1131
1132         driver_adapter = halmac_adapter->driver_adapter;
1133         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1134
1135         mcu_fw_ctrl = HALMAC_REG_READ_8(halmac_adapter, REG_MCUFW_CTRL);
1136
1137         if (HALMAC_REG_READ_32(halmac_adapter, REG_DDMA_CH0CTRL) &
1138             BIT_DDMACH0_CHKSUM_STS) {
1139                 if (memory_address < HALMAC_OCPBASE_DMEM_88XX) {
1140                         mcu_fw_ctrl |= BIT_IMEM_DW_OK;
1141                         HALMAC_REG_WRITE_8(
1142                                 halmac_adapter, REG_MCUFW_CTRL,
1143                                 (u8)(mcu_fw_ctrl & ~(BIT_IMEM_CHKSUM_OK)));
1144                 } else {
1145                         mcu_fw_ctrl |= BIT_DMEM_DW_OK;
1146                         HALMAC_REG_WRITE_8(
1147                                 halmac_adapter, REG_MCUFW_CTRL,
1148                                 (u8)(mcu_fw_ctrl & ~(BIT_DMEM_CHKSUM_OK)));
1149                 }
1150
1151                 pr_err("%s error!!\n", __func__);
1152
1153                 status = HALMAC_RET_FW_CHECKSUM_FAIL;
1154         } else {
1155                 if (memory_address < HALMAC_OCPBASE_DMEM_88XX) {
1156                         mcu_fw_ctrl |= BIT_IMEM_DW_OK;
1157                         HALMAC_REG_WRITE_8(
1158                                 halmac_adapter, REG_MCUFW_CTRL,
1159                                 (u8)(mcu_fw_ctrl | BIT_IMEM_CHKSUM_OK));
1160                 } else {
1161                         mcu_fw_ctrl |= BIT_DMEM_DW_OK;
1162                         HALMAC_REG_WRITE_8(
1163                                 halmac_adapter, REG_MCUFW_CTRL,
1164                                 (u8)(mcu_fw_ctrl | BIT_DMEM_CHKSUM_OK));
1165                 }
1166
1167                 status = HALMAC_RET_SUCCESS;
1168         }
1169
1170         return status;
1171 }
1172
1173 enum halmac_ret_status
1174 halmac_dlfw_end_flow_88xx(struct halmac_adapter *halmac_adapter)
1175 {
1176         u8 value8;
1177         u32 counter;
1178         void *driver_adapter = halmac_adapter->driver_adapter;
1179         struct halmac_api *halmac_api =
1180                 (struct halmac_api *)halmac_adapter->halmac_api;
1181
1182         HALMAC_REG_WRITE_32(halmac_adapter, REG_TXDMA_STATUS, BIT(2));
1183
1184         /* Check IMEM & DMEM checksum is OK or not */
1185         if ((HALMAC_REG_READ_8(halmac_adapter, REG_MCUFW_CTRL) & 0x50) == 0x50)
1186                 HALMAC_REG_WRITE_16(halmac_adapter, REG_MCUFW_CTRL,
1187                                     (u16)(HALMAC_REG_READ_16(halmac_adapter,
1188                                                              REG_MCUFW_CTRL) |
1189                                           BIT_FW_DW_RDY));
1190         else
1191                 return HALMAC_RET_DLFW_FAIL;
1192
1193         HALMAC_REG_WRITE_8(
1194                 halmac_adapter, REG_MCUFW_CTRL,
1195                 (u8)(HALMAC_REG_READ_8(halmac_adapter, REG_MCUFW_CTRL) &
1196                      ~(BIT(0))));
1197
1198         value8 = HALMAC_REG_READ_8(halmac_adapter, REG_RSV_CTRL + 1);
1199         value8 = (u8)(value8 | BIT(0));
1200         HALMAC_REG_WRITE_8(halmac_adapter, REG_RSV_CTRL + 1, value8);
1201
1202         value8 = HALMAC_REG_READ_8(halmac_adapter, REG_SYS_FUNC_EN + 1);
1203         value8 = (u8)(value8 | BIT(2));
1204         HALMAC_REG_WRITE_8(halmac_adapter, REG_SYS_FUNC_EN + 1,
1205                            value8); /* Release MCU reset */
1206         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1207                         "Download Finish, Reset CPU\n");
1208
1209         counter = 10000;
1210         while (HALMAC_REG_READ_16(halmac_adapter, REG_MCUFW_CTRL) != 0xC078) {
1211                 if (counter == 0) {
1212                         pr_err("Check 0x80 = 0xC078 fail\n");
1213                         if ((HALMAC_REG_READ_32(halmac_adapter, REG_FW_DBG7) &
1214                              0xFFFFFF00) == 0xFAAAAA00)
1215                                 pr_err("Key fail\n");
1216                         return HALMAC_RET_DLFW_FAIL;
1217                 }
1218                 counter--;
1219                 usleep_range(50, 60);
1220         }
1221
1222         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1223                         "Check 0x80 = 0xC078 counter = %d\n", counter);
1224
1225         return HALMAC_RET_SUCCESS;
1226 }
1227
1228 enum halmac_ret_status
1229 halmac_free_dl_fw_end_flow_88xx(struct halmac_adapter *halmac_adapter)
1230 {
1231         u32 counter;
1232         struct halmac_api *halmac_api =
1233                 (struct halmac_api *)halmac_adapter->halmac_api;
1234
1235         counter = 100;
1236         while (HALMAC_REG_READ_8(halmac_adapter, REG_HMETFR + 3) != 0) {
1237                 counter--;
1238                 if (counter == 0) {
1239                         pr_err("[ERR]0x1CF != 0\n");
1240                         return HALMAC_RET_DLFW_FAIL;
1241                 }
1242                 usleep_range(50, 60);
1243         }
1244
1245         HALMAC_REG_WRITE_8(halmac_adapter, REG_HMETFR + 3,
1246                            ID_INFORM_DLEMEM_RDY);
1247
1248         counter = 10000;
1249         while (HALMAC_REG_READ_8(halmac_adapter, REG_C2HEVT_3 + 3) !=
1250                ID_INFORM_DLEMEM_RDY) {
1251                 counter--;
1252                 if (counter == 0) {
1253                         pr_err("[ERR]0x1AF != 0x80\n");
1254                         return HALMAC_RET_DLFW_FAIL;
1255                 }
1256                 usleep_range(50, 60);
1257         }
1258
1259         HALMAC_REG_WRITE_8(halmac_adapter, REG_C2HEVT_3 + 3, 0);
1260
1261         return HALMAC_RET_SUCCESS;
1262 }
1263
1264 enum halmac_ret_status
1265 halmac_pwr_seq_parser_88xx(struct halmac_adapter *halmac_adapter, u8 cut,
1266                            u8 fab, u8 intf,
1267                            struct halmac_wl_pwr_cfg_ **pp_pwr_seq_cfg)
1268 {
1269         u32 seq_idx = 0;
1270         void *driver_adapter = NULL;
1271         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1272         struct halmac_wl_pwr_cfg_ *seq_cmd;
1273
1274         driver_adapter = halmac_adapter->driver_adapter;
1275
1276         do {
1277                 seq_cmd = pp_pwr_seq_cfg[seq_idx];
1278
1279                 if (!seq_cmd)
1280                         break;
1281
1282                 status = halmac_pwr_sub_seq_parer_88xx(halmac_adapter, cut, fab,
1283                                                        intf, seq_cmd);
1284                 if (status != HALMAC_RET_SUCCESS) {
1285                         pr_err("[Err]pwr sub seq parser fail, status = 0x%X!\n",
1286                                status);
1287                         return status;
1288                 }
1289
1290                 seq_idx++;
1291         } while (1);
1292
1293         return status;
1294 }
1295
1296 static enum halmac_ret_status
1297 halmac_pwr_sub_seq_parer_do_cmd_88xx(struct halmac_adapter *halmac_adapter,
1298                                      struct halmac_wl_pwr_cfg_ *sub_seq_cmd,
1299                                      bool *reti)
1300 {
1301         void *driver_adapter = NULL;
1302         struct halmac_api *halmac_api;
1303         u8 value, flag;
1304         u8 polling_bit;
1305         u32 polling_count;
1306         static u32 poll_to_static;
1307         u32 offset;
1308
1309         driver_adapter = halmac_adapter->driver_adapter;
1310         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1311         *reti = true;
1312
1313         switch (sub_seq_cmd->cmd) {
1314         case HALMAC_PWR_CMD_WRITE:
1315                 if (sub_seq_cmd->base == HALMAC_PWR_BASEADDR_SDIO)
1316                         offset = sub_seq_cmd->offset | SDIO_LOCAL_OFFSET;
1317                 else
1318                         offset = sub_seq_cmd->offset;
1319
1320                 value = HALMAC_REG_READ_8(halmac_adapter, offset);
1321                 value = (u8)(value & (u8)(~(sub_seq_cmd->msk)));
1322                 value = (u8)(value |
1323                              (u8)(sub_seq_cmd->value & sub_seq_cmd->msk));
1324
1325                 HALMAC_REG_WRITE_8(halmac_adapter, offset, value);
1326                 break;
1327         case HALMAC_PWR_CMD_POLLING:
1328                 polling_bit = 0;
1329                 polling_count = HALMAC_POLLING_READY_TIMEOUT_COUNT;
1330                 flag = 0;
1331
1332                 if (sub_seq_cmd->base == HALMAC_PWR_BASEADDR_SDIO)
1333                         offset = sub_seq_cmd->offset | SDIO_LOCAL_OFFSET;
1334                 else
1335                         offset = sub_seq_cmd->offset;
1336
1337                 do {
1338                         polling_count--;
1339                         value = HALMAC_REG_READ_8(halmac_adapter, offset);
1340                         value = (u8)(value & sub_seq_cmd->msk);
1341
1342                         if (value == (sub_seq_cmd->value & sub_seq_cmd->msk)) {
1343                                 polling_bit = 1;
1344                                 continue;
1345                         }
1346
1347                         if (polling_count != 0) {
1348                                 usleep_range(50, 60);
1349                                 continue;
1350                         }
1351
1352                         if (halmac_adapter->halmac_interface ==
1353                                     HALMAC_INTERFACE_PCIE &&
1354                             flag == 0) {
1355                                 /* For PCIE + USB package poll power bit
1356                                  * timeout issue
1357                                  */
1358                                 poll_to_static++;
1359                                 HALMAC_RT_TRACE(
1360                                         driver_adapter, HALMAC_MSG_PWR,
1361                                         DBG_WARNING,
1362                                         "[WARN]PCIE polling timeout : %d!!\n",
1363                                         poll_to_static);
1364                                 HALMAC_REG_WRITE_8(
1365                                         halmac_adapter, REG_SYS_PW_CTRL,
1366                                         HALMAC_REG_READ_8(halmac_adapter,
1367                                                           REG_SYS_PW_CTRL) |
1368                                                 BIT(3));
1369                                 HALMAC_REG_WRITE_8(
1370                                         halmac_adapter, REG_SYS_PW_CTRL,
1371                                         HALMAC_REG_READ_8(halmac_adapter,
1372                                                           REG_SYS_PW_CTRL) &
1373                                                 ~BIT(3));
1374                                 polling_bit = 0;
1375                                 polling_count =
1376                                         HALMAC_POLLING_READY_TIMEOUT_COUNT;
1377                                 flag = 1;
1378                         } else {
1379                                 pr_err("[ERR]Pwr cmd polling timeout!!\n");
1380                                 pr_err("[ERR]Pwr cmd offset : %X!!\n",
1381                                        sub_seq_cmd->offset);
1382                                 pr_err("[ERR]Pwr cmd value : %X!!\n",
1383                                        sub_seq_cmd->value);
1384                                 pr_err("[ERR]Pwr cmd msk : %X!!\n",
1385                                        sub_seq_cmd->msk);
1386                                 pr_err("[ERR]Read offset = %X value = %X!!\n",
1387                                        offset, value);
1388                                 return HALMAC_RET_PWRSEQ_POLLING_FAIL;
1389                         }
1390                 } while (!polling_bit);
1391                 break;
1392         case HALMAC_PWR_CMD_DELAY:
1393                 if (sub_seq_cmd->value == HALMAC_PWRSEQ_DELAY_US)
1394                         udelay(sub_seq_cmd->offset);
1395                 else
1396                         usleep_range(1000 * sub_seq_cmd->offset,
1397                                      1000 * sub_seq_cmd->offset + 100);
1398
1399                 break;
1400         case HALMAC_PWR_CMD_READ:
1401                 break;
1402         case HALMAC_PWR_CMD_END:
1403                 return HALMAC_RET_SUCCESS;
1404         default:
1405                 return HALMAC_RET_PWRSEQ_CMD_INCORRECT;
1406         }
1407
1408         *reti = false;
1409
1410         return HALMAC_RET_SUCCESS;
1411 }
1412
1413 static enum halmac_ret_status
1414 halmac_pwr_sub_seq_parer_88xx(struct halmac_adapter *halmac_adapter, u8 cut,
1415                               u8 fab, u8 intf,
1416                               struct halmac_wl_pwr_cfg_ *pwr_sub_seq_cfg)
1417 {
1418         struct halmac_wl_pwr_cfg_ *sub_seq_cmd;
1419         bool reti;
1420         enum halmac_ret_status status;
1421
1422         for (sub_seq_cmd = pwr_sub_seq_cfg;; sub_seq_cmd++) {
1423                 if ((sub_seq_cmd->interface_msk & intf) &&
1424                     (sub_seq_cmd->fab_msk & fab) &&
1425                     (sub_seq_cmd->cut_msk & cut)) {
1426                         status = halmac_pwr_sub_seq_parer_do_cmd_88xx(
1427                                 halmac_adapter, sub_seq_cmd, &reti);
1428
1429                         if (reti)
1430                                 return status;
1431                 }
1432         }
1433
1434         return HALMAC_RET_SUCCESS;
1435 }
1436
1437 enum halmac_ret_status
1438 halmac_get_h2c_buff_free_space_88xx(struct halmac_adapter *halmac_adapter)
1439 {
1440         u32 hw_wptr, fw_rptr;
1441         struct halmac_api *halmac_api =
1442                 (struct halmac_api *)halmac_adapter->halmac_api;
1443
1444         hw_wptr = HALMAC_REG_READ_32(halmac_adapter, REG_H2C_PKT_WRITEADDR) &
1445                   BIT_MASK_H2C_WR_ADDR;
1446         fw_rptr = HALMAC_REG_READ_32(halmac_adapter, REG_H2C_PKT_READADDR) &
1447                   BIT_MASK_H2C_READ_ADDR;
1448
1449         if (hw_wptr >= fw_rptr)
1450                 halmac_adapter->h2c_buf_free_space =
1451                         halmac_adapter->h2c_buff_size - (hw_wptr - fw_rptr);
1452         else
1453                 halmac_adapter->h2c_buf_free_space = fw_rptr - hw_wptr;
1454
1455         return HALMAC_RET_SUCCESS;
1456 }
1457
1458 enum halmac_ret_status
1459 halmac_send_h2c_pkt_88xx(struct halmac_adapter *halmac_adapter, u8 *hal_h2c_cmd,
1460                          u32 size, bool ack)
1461 {
1462         u32 counter = 100;
1463         void *driver_adapter = halmac_adapter->driver_adapter;
1464         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1465
1466         while (halmac_adapter->h2c_buf_free_space <=
1467                HALMAC_H2C_CMD_SIZE_UNIT_88XX) {
1468                 halmac_get_h2c_buff_free_space_88xx(halmac_adapter);
1469                 counter--;
1470                 if (counter == 0) {
1471                         pr_err("h2c free space is not enough!!\n");
1472                         return HALMAC_RET_H2C_SPACE_FULL;
1473                 }
1474         }
1475
1476         /* Send TxDesc + H2C_CMD */
1477         if (!PLATFORM_SEND_H2C_PKT(driver_adapter, hal_h2c_cmd, size)) {
1478                 pr_err("Send H2C_CMD pkt error!!\n");
1479                 return HALMAC_RET_SEND_H2C_FAIL;
1480         }
1481
1482         halmac_adapter->h2c_buf_free_space -= HALMAC_H2C_CMD_SIZE_UNIT_88XX;
1483
1484         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1485                         "H2C free space : %d\n",
1486                         halmac_adapter->h2c_buf_free_space);
1487
1488         return status;
1489 }
1490
1491 enum halmac_ret_status
1492 halmac_download_rsvd_page_88xx(struct halmac_adapter *halmac_adapter,
1493                                u8 *hal_buf, u32 size)
1494 {
1495         u8 restore[3];
1496         u8 value8;
1497         u32 counter;
1498         void *driver_adapter = NULL;
1499         struct halmac_api *halmac_api;
1500         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1501
1502         driver_adapter = halmac_adapter->driver_adapter;
1503         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1504
1505         if (size == 0) {
1506                 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1507                                 "Rsvd page packet size is zero!!\n");
1508                 return HALMAC_RET_ZERO_LEN_RSVD_PACKET;
1509         }
1510
1511         value8 = HALMAC_REG_READ_8(halmac_adapter, REG_FIFOPAGE_CTRL_2 + 1);
1512         value8 = (u8)(value8 | BIT(7));
1513         HALMAC_REG_WRITE_8(halmac_adapter, REG_FIFOPAGE_CTRL_2 + 1, value8);
1514
1515         value8 = HALMAC_REG_READ_8(halmac_adapter, REG_CR + 1);
1516         restore[0] = value8;
1517         value8 = (u8)(value8 | BIT(0));
1518         HALMAC_REG_WRITE_8(halmac_adapter, REG_CR + 1, value8);
1519
1520         value8 = HALMAC_REG_READ_8(halmac_adapter, REG_BCN_CTRL);
1521         restore[1] = value8;
1522         value8 = (u8)((value8 & ~(BIT(3))) | BIT(4));
1523         HALMAC_REG_WRITE_8(halmac_adapter, REG_BCN_CTRL, value8);
1524
1525         value8 = HALMAC_REG_READ_8(halmac_adapter, REG_FWHW_TXQ_CTRL + 2);
1526         restore[2] = value8;
1527         value8 = (u8)(value8 & ~(BIT(6)));
1528         HALMAC_REG_WRITE_8(halmac_adapter, REG_FWHW_TXQ_CTRL + 2, value8);
1529
1530         if (!PLATFORM_SEND_RSVD_PAGE(driver_adapter, hal_buf, size)) {
1531                 pr_err("PLATFORM_SEND_RSVD_PAGE 1 error!!\n");
1532                 status = HALMAC_RET_DL_RSVD_PAGE_FAIL;
1533         }
1534
1535         /* Check Bcn_Valid_Bit */
1536         counter = 1000;
1537         while (!(HALMAC_REG_READ_8(halmac_adapter, REG_FIFOPAGE_CTRL_2 + 1) &
1538                  BIT(7))) {
1539                 udelay(10);
1540                 counter--;
1541                 if (counter == 0) {
1542                         pr_err("Polling Bcn_Valid_Fail error!!\n");
1543                         status = HALMAC_RET_POLLING_BCN_VALID_FAIL;
1544                         break;
1545                 }
1546         }
1547
1548         value8 = HALMAC_REG_READ_8(halmac_adapter, REG_FIFOPAGE_CTRL_2 + 1);
1549         HALMAC_REG_WRITE_8(halmac_adapter, REG_FIFOPAGE_CTRL_2 + 1,
1550                            (value8 | BIT(7)));
1551
1552         HALMAC_REG_WRITE_8(halmac_adapter, REG_FWHW_TXQ_CTRL + 2, restore[2]);
1553         HALMAC_REG_WRITE_8(halmac_adapter, REG_BCN_CTRL, restore[1]);
1554         HALMAC_REG_WRITE_8(halmac_adapter, REG_CR + 1, restore[0]);
1555
1556         return status;
1557 }
1558
1559 enum halmac_ret_status
1560 halmac_set_h2c_header_88xx(struct halmac_adapter *halmac_adapter,
1561                            u8 *hal_h2c_hdr, u16 *seq, bool ack)
1562 {
1563         void *driver_adapter = halmac_adapter->driver_adapter;
1564
1565         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1566                         "%s!!\n", __func__);
1567
1568         H2C_CMD_HEADER_SET_CATEGORY(hal_h2c_hdr, 0x00);
1569         H2C_CMD_HEADER_SET_TOTAL_LEN(hal_h2c_hdr, 16);
1570
1571         spin_lock(&halmac_adapter->h2c_seq_lock);
1572         H2C_CMD_HEADER_SET_SEQ_NUM(hal_h2c_hdr, halmac_adapter->h2c_packet_seq);
1573         *seq = halmac_adapter->h2c_packet_seq;
1574         halmac_adapter->h2c_packet_seq++;
1575         spin_unlock(&halmac_adapter->h2c_seq_lock);
1576
1577         if (ack)
1578                 H2C_CMD_HEADER_SET_ACK(hal_h2c_hdr, 1);
1579
1580         return HALMAC_RET_SUCCESS;
1581 }
1582
1583 enum halmac_ret_status halmac_set_fw_offload_h2c_header_88xx(
1584         struct halmac_adapter *halmac_adapter, u8 *hal_h2c_hdr,
1585         struct halmac_h2c_header_info *h2c_header_info, u16 *seq_num)
1586 {
1587         void *driver_adapter = halmac_adapter->driver_adapter;
1588
1589         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1590                         "%s!!\n", __func__);
1591
1592         FW_OFFLOAD_H2C_SET_TOTAL_LEN(hal_h2c_hdr,
1593                                      8 + h2c_header_info->content_size);
1594         FW_OFFLOAD_H2C_SET_SUB_CMD_ID(hal_h2c_hdr, h2c_header_info->sub_cmd_id);
1595
1596         FW_OFFLOAD_H2C_SET_CATEGORY(hal_h2c_hdr, 0x01);
1597         FW_OFFLOAD_H2C_SET_CMD_ID(hal_h2c_hdr, 0xFF);
1598
1599         spin_lock(&halmac_adapter->h2c_seq_lock);
1600         FW_OFFLOAD_H2C_SET_SEQ_NUM(hal_h2c_hdr, halmac_adapter->h2c_packet_seq);
1601         *seq_num = halmac_adapter->h2c_packet_seq;
1602         halmac_adapter->h2c_packet_seq++;
1603         spin_unlock(&halmac_adapter->h2c_seq_lock);
1604
1605         if (h2c_header_info->ack)
1606                 FW_OFFLOAD_H2C_SET_ACK(hal_h2c_hdr, 1);
1607
1608         return HALMAC_RET_SUCCESS;
1609 }
1610
1611 enum halmac_ret_status
1612 halmac_send_h2c_set_pwr_mode_88xx(struct halmac_adapter *halmac_adapter,
1613                                   struct halmac_fwlps_option *hal_fw_lps_opt)
1614 {
1615         u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX];
1616         u8 *h2c_header, *h2c_cmd;
1617         u16 seq = 0;
1618         void *driver_adapter = NULL;
1619         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1620
1621         driver_adapter = halmac_adapter->driver_adapter;
1622
1623         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1624                         "%s!!\n", __func__);
1625
1626         h2c_header = h2c_buff;
1627         h2c_cmd = h2c_header + HALMAC_H2C_CMD_HDR_SIZE_88XX;
1628
1629         memset(h2c_buff, 0x00, HALMAC_H2C_CMD_SIZE_88XX);
1630
1631         SET_PWR_MODE_SET_CMD_ID(h2c_cmd, CMD_ID_SET_PWR_MODE);
1632         SET_PWR_MODE_SET_CLASS(h2c_cmd, CLASS_SET_PWR_MODE);
1633         SET_PWR_MODE_SET_MODE(h2c_cmd, hal_fw_lps_opt->mode);
1634         SET_PWR_MODE_SET_CLK_REQUEST(h2c_cmd, hal_fw_lps_opt->clk_request);
1635         SET_PWR_MODE_SET_RLBM(h2c_cmd, hal_fw_lps_opt->rlbm);
1636         SET_PWR_MODE_SET_SMART_PS(h2c_cmd, hal_fw_lps_opt->smart_ps);
1637         SET_PWR_MODE_SET_AWAKE_INTERVAL(h2c_cmd,
1638                                         hal_fw_lps_opt->awake_interval);
1639         SET_PWR_MODE_SET_B_ALL_QUEUE_UAPSD(h2c_cmd,
1640                                            hal_fw_lps_opt->all_queue_uapsd);
1641         SET_PWR_MODE_SET_PWR_STATE(h2c_cmd, hal_fw_lps_opt->pwr_state);
1642         SET_PWR_MODE_SET_ANT_AUTO_SWITCH(h2c_cmd,
1643                                          hal_fw_lps_opt->ant_auto_switch);
1644         SET_PWR_MODE_SET_PS_ALLOW_BT_HIGH_PRIORITY(
1645                 h2c_cmd, hal_fw_lps_opt->ps_allow_bt_high_priority);
1646         SET_PWR_MODE_SET_PROTECT_BCN(h2c_cmd, hal_fw_lps_opt->protect_bcn);
1647         SET_PWR_MODE_SET_SILENCE_PERIOD(h2c_cmd,
1648                                         hal_fw_lps_opt->silence_period);
1649         SET_PWR_MODE_SET_FAST_BT_CONNECT(h2c_cmd,
1650                                          hal_fw_lps_opt->fast_bt_connect);
1651         SET_PWR_MODE_SET_TWO_ANTENNA_EN(h2c_cmd,
1652                                         hal_fw_lps_opt->two_antenna_en);
1653         SET_PWR_MODE_SET_ADOPT_USER_SETTING(h2c_cmd,
1654                                             hal_fw_lps_opt->adopt_user_setting);
1655         SET_PWR_MODE_SET_DRV_BCN_EARLY_SHIFT(
1656                 h2c_cmd, hal_fw_lps_opt->drv_bcn_early_shift);
1657
1658         halmac_set_h2c_header_88xx(halmac_adapter, h2c_header, &seq, true);
1659
1660         status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
1661                                           HALMAC_H2C_CMD_SIZE_88XX, true);
1662
1663         if (status != HALMAC_RET_SUCCESS) {
1664                 pr_err("%s Fail = %x!!\n", __func__, status);
1665                 return status;
1666         }
1667
1668         return HALMAC_RET_SUCCESS;
1669 }
1670
1671 enum halmac_ret_status
1672 halmac_func_send_original_h2c_88xx(struct halmac_adapter *halmac_adapter,
1673                                    u8 *original_h2c, u16 *seq, u8 ack)
1674 {
1675         u8 H2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
1676         u8 *h2c_header, *h2c_cmd;
1677         void *driver_adapter = NULL;
1678         struct halmac_api *halmac_api;
1679         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1680
1681         driver_adapter = halmac_adapter->driver_adapter;
1682         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1683
1684         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1685                         "halmac_send_original_h2c ==========>\n");
1686
1687         h2c_header = H2c_buff;
1688         h2c_cmd = h2c_header + HALMAC_H2C_CMD_HDR_SIZE_88XX;
1689         memcpy(h2c_cmd, original_h2c, 8); /* Original H2C 8 byte */
1690
1691         halmac_set_h2c_header_88xx(halmac_adapter, h2c_header, seq, ack);
1692
1693         status = halmac_send_h2c_pkt_88xx(halmac_adapter, H2c_buff,
1694                                           HALMAC_H2C_CMD_SIZE_88XX, ack);
1695
1696         if (status != HALMAC_RET_SUCCESS) {
1697                 pr_err("halmac_send_original_h2c Fail = %x!!\n", status);
1698                 return status;
1699         }
1700
1701         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1702                         "halmac_send_original_h2c <==========\n");
1703
1704         return HALMAC_RET_SUCCESS;
1705 }
1706
1707 enum halmac_ret_status
1708 halmac_media_status_rpt_88xx(struct halmac_adapter *halmac_adapter, u8 op_mode,
1709                              u8 mac_id_ind, u8 mac_id, u8 mac_id_end)
1710 {
1711         u8 H2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
1712         u8 *h2c_header, *h2c_cmd;
1713         u16 seq = 0;
1714         void *driver_adapter = NULL;
1715         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1716
1717         driver_adapter = halmac_adapter->driver_adapter;
1718
1719         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1720                         "halmac_send_h2c_set_pwr_mode_88xx!!\n");
1721
1722         h2c_header = H2c_buff;
1723         h2c_cmd = h2c_header + HALMAC_H2C_CMD_HDR_SIZE_88XX;
1724
1725         memset(H2c_buff, 0x00, HALMAC_H2C_CMD_SIZE_88XX);
1726
1727         MEDIA_STATUS_RPT_SET_CMD_ID(h2c_cmd, CMD_ID_MEDIA_STATUS_RPT);
1728         MEDIA_STATUS_RPT_SET_CLASS(h2c_cmd, CLASS_MEDIA_STATUS_RPT);
1729         MEDIA_STATUS_RPT_SET_OP_MODE(h2c_cmd, op_mode);
1730         MEDIA_STATUS_RPT_SET_MACID_IN(h2c_cmd, mac_id_ind);
1731         MEDIA_STATUS_RPT_SET_MACID(h2c_cmd, mac_id);
1732         MEDIA_STATUS_RPT_SET_MACID_END(h2c_cmd, mac_id_end);
1733
1734         halmac_set_h2c_header_88xx(halmac_adapter, h2c_header, &seq, true);
1735
1736         status = halmac_send_h2c_pkt_88xx(halmac_adapter, H2c_buff,
1737                                           HALMAC_H2C_CMD_SIZE_88XX, true);
1738
1739         if (status != HALMAC_RET_SUCCESS) {
1740                 pr_err("%s Fail = %x!!\n", __func__, status);
1741                 return status;
1742         }
1743
1744         return HALMAC_RET_SUCCESS;
1745 }
1746
1747 enum halmac_ret_status
1748 halmac_send_h2c_update_packet_88xx(struct halmac_adapter *halmac_adapter,
1749                                    enum halmac_packet_id pkt_id, u8 *pkt,
1750                                    u32 pkt_size)
1751 {
1752         u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
1753         u16 h2c_seq_mum = 0;
1754         void *driver_adapter = NULL;
1755         struct halmac_api *halmac_api;
1756         struct halmac_h2c_header_info h2c_header_info;
1757         enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
1758
1759         driver_adapter = halmac_adapter->driver_adapter;
1760         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1761
1762         HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
1763                             (u16)(halmac_adapter->txff_allocation
1764                                           .rsvd_h2c_extra_info_pg_bndy &
1765                                   BIT_MASK_BCN_HEAD_1_V1));
1766
1767         ret_status =
1768                 halmac_download_rsvd_page_88xx(halmac_adapter, pkt, pkt_size);
1769
1770         if (ret_status != HALMAC_RET_SUCCESS) {
1771                 pr_err("halmac_download_rsvd_page_88xx Fail = %x!!\n",
1772                        ret_status);
1773                 HALMAC_REG_WRITE_16(
1774                         halmac_adapter, REG_FIFOPAGE_CTRL_2,
1775                         (u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
1776                               BIT_MASK_BCN_HEAD_1_V1));
1777                 return ret_status;
1778         }
1779
1780         HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
1781                             (u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
1782                                   BIT_MASK_BCN_HEAD_1_V1));
1783
1784         UPDATE_PACKET_SET_SIZE(
1785                 h2c_buff,
1786                 pkt_size + halmac_adapter->hw_config_info.txdesc_size);
1787         UPDATE_PACKET_SET_PACKET_ID(h2c_buff, pkt_id);
1788         UPDATE_PACKET_SET_PACKET_LOC(
1789                 h2c_buff,
1790                 halmac_adapter->txff_allocation.rsvd_h2c_extra_info_pg_bndy -
1791                         halmac_adapter->txff_allocation.rsvd_pg_bndy);
1792
1793         h2c_header_info.sub_cmd_id = SUB_CMD_ID_UPDATE_PACKET;
1794         h2c_header_info.content_size = 8;
1795         h2c_header_info.ack = true;
1796         halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
1797                                               &h2c_header_info, &h2c_seq_mum);
1798         halmac_adapter->halmac_state.update_packet_set.seq_num = h2c_seq_mum;
1799
1800         ret_status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
1801                                               HALMAC_H2C_CMD_SIZE_88XX, true);
1802
1803         if (ret_status != HALMAC_RET_SUCCESS) {
1804                 pr_err("%s Fail = %x!!\n", __func__, ret_status);
1805                 return ret_status;
1806         }
1807
1808         return ret_status;
1809 }
1810
1811 enum halmac_ret_status
1812 halmac_send_h2c_phy_parameter_88xx(struct halmac_adapter *halmac_adapter,
1813                                    struct halmac_phy_parameter_info *para_info,
1814                                    bool full_fifo)
1815 {
1816         bool drv_trigger_send = false;
1817         u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
1818         u16 h2c_seq_mum = 0;
1819         u32 info_size = 0;
1820         void *driver_adapter = NULL;
1821         struct halmac_api *halmac_api;
1822         struct halmac_h2c_header_info h2c_header_info;
1823         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1824         struct halmac_config_para_info *config_para_info;
1825
1826         driver_adapter = halmac_adapter->driver_adapter;
1827         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1828         config_para_info = &halmac_adapter->config_para_info;
1829
1830         if (!config_para_info->cfg_para_buf) {
1831                 if (full_fifo)
1832                         config_para_info->para_buf_size =
1833                                 HALMAC_EXTRA_INFO_BUFF_SIZE_FULL_FIFO_88XX;
1834                 else
1835                         config_para_info->para_buf_size =
1836                                 HALMAC_EXTRA_INFO_BUFF_SIZE_88XX;
1837
1838                 config_para_info->cfg_para_buf =
1839                         kzalloc(config_para_info->para_buf_size, GFP_KERNEL);
1840
1841                 if (config_para_info->cfg_para_buf) {
1842                         memset(config_para_info->cfg_para_buf, 0x00,
1843                                config_para_info->para_buf_size);
1844                         config_para_info->full_fifo_mode = full_fifo;
1845                         config_para_info->para_buf_w =
1846                                 config_para_info->cfg_para_buf;
1847                         config_para_info->para_num = 0;
1848                         config_para_info->avai_para_buf_size =
1849                                 config_para_info->para_buf_size;
1850                         config_para_info->value_accumulation = 0;
1851                         config_para_info->offset_accumulation = 0;
1852                 } else {
1853                         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C,
1854                                         DBG_DMESG,
1855                                         "Allocate cfg_para_buf fail!!\n");
1856                         return HALMAC_RET_MALLOC_FAIL;
1857                 }
1858         }
1859
1860         if (halmac_transition_cfg_para_state_88xx(
1861                     halmac_adapter,
1862                     HALMAC_CFG_PARA_CMD_CONSTRUCT_CONSTRUCTING) !=
1863             HALMAC_RET_SUCCESS)
1864                 return HALMAC_RET_ERROR_STATE;
1865
1866         halmac_enqueue_para_buff_88xx(halmac_adapter, para_info,
1867                                       config_para_info->para_buf_w,
1868                                       &drv_trigger_send);
1869
1870         if (para_info->cmd_id != HALMAC_PARAMETER_CMD_END) {
1871                 config_para_info->para_num++;
1872                 config_para_info->para_buf_w += HALMAC_FW_OFFLOAD_CMD_SIZE_88XX;
1873                 config_para_info->avai_para_buf_size =
1874                         config_para_info->avai_para_buf_size -
1875                         HALMAC_FW_OFFLOAD_CMD_SIZE_88XX;
1876         }
1877
1878         if ((config_para_info->avai_para_buf_size -
1879              halmac_adapter->hw_config_info.txdesc_size) >
1880                     HALMAC_FW_OFFLOAD_CMD_SIZE_88XX &&
1881             !drv_trigger_send)
1882                 return HALMAC_RET_SUCCESS;
1883
1884         if (config_para_info->para_num == 0) {
1885                 kfree(config_para_info->cfg_para_buf);
1886                 config_para_info->cfg_para_buf = NULL;
1887                 config_para_info->para_buf_w = NULL;
1888                 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_WARNING,
1889                                 "no cfg parameter element!!\n");
1890
1891                 if (halmac_transition_cfg_para_state_88xx(
1892                             halmac_adapter,
1893                             HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE) !=
1894                     HALMAC_RET_SUCCESS)
1895                         return HALMAC_RET_ERROR_STATE;
1896
1897                 return HALMAC_RET_SUCCESS;
1898         }
1899
1900         if (halmac_transition_cfg_para_state_88xx(
1901                     halmac_adapter, HALMAC_CFG_PARA_CMD_CONSTRUCT_H2C_SENT) !=
1902             HALMAC_RET_SUCCESS)
1903                 return HALMAC_RET_ERROR_STATE;
1904
1905         halmac_adapter->halmac_state.cfg_para_state_set.process_status =
1906                 HALMAC_CMD_PROCESS_SENDING;
1907
1908         if (config_para_info->full_fifo_mode)
1909                 HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2, 0);
1910         else
1911                 HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
1912                                     (u16)(halmac_adapter->txff_allocation
1913                                                   .rsvd_h2c_extra_info_pg_bndy &
1914                                           BIT_MASK_BCN_HEAD_1_V1));
1915
1916         info_size =
1917                 config_para_info->para_num * HALMAC_FW_OFFLOAD_CMD_SIZE_88XX;
1918
1919         status = halmac_download_rsvd_page_88xx(
1920                 halmac_adapter, (u8 *)config_para_info->cfg_para_buf,
1921                 info_size);
1922
1923         if (status != HALMAC_RET_SUCCESS) {
1924                 pr_err("halmac_download_rsvd_page_88xx Fail!!\n");
1925         } else {
1926                 halmac_gen_cfg_para_h2c_88xx(halmac_adapter, h2c_buff);
1927
1928                 h2c_header_info.sub_cmd_id = SUB_CMD_ID_CFG_PARAMETER;
1929                 h2c_header_info.content_size = 4;
1930                 h2c_header_info.ack = true;
1931                 halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
1932                                                       &h2c_header_info,
1933                                                       &h2c_seq_mum);
1934
1935                 halmac_adapter->halmac_state.cfg_para_state_set.seq_num =
1936                         h2c_seq_mum;
1937
1938                 status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
1939                                                   HALMAC_H2C_CMD_SIZE_88XX,
1940                                                   true);
1941
1942                 if (status != HALMAC_RET_SUCCESS)
1943                         pr_err("halmac_send_h2c_pkt_88xx Fail!!\n");
1944
1945                 HALMAC_RT_TRACE(
1946                         driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1947                         "config parameter time = %d\n",
1948                         HALMAC_REG_READ_32(halmac_adapter, REG_FW_DBG6));
1949         }
1950
1951         kfree(config_para_info->cfg_para_buf);
1952         config_para_info->cfg_para_buf = NULL;
1953         config_para_info->para_buf_w = NULL;
1954
1955         /* Restore bcn head */
1956         HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
1957                             (u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
1958                                   BIT_MASK_BCN_HEAD_1_V1));
1959
1960         if (halmac_transition_cfg_para_state_88xx(
1961                     halmac_adapter, HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE) !=
1962             HALMAC_RET_SUCCESS)
1963                 return HALMAC_RET_ERROR_STATE;
1964
1965         if (!drv_trigger_send) {
1966                 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1967                                 "Buffer full trigger sending H2C!!\n");
1968                 return HALMAC_RET_PARA_SENDING;
1969         }
1970
1971         return status;
1972 }
1973
1974 static enum halmac_ret_status
1975 halmac_enqueue_para_buff_88xx(struct halmac_adapter *halmac_adapter,
1976                               struct halmac_phy_parameter_info *para_info,
1977                               u8 *curr_buff_wptr, bool *end_cmd)
1978 {
1979         struct halmac_config_para_info *config_para_info =
1980                 &halmac_adapter->config_para_info;
1981
1982         *end_cmd = false;
1983
1984         PHY_PARAMETER_INFO_SET_LENGTH(curr_buff_wptr,
1985                                       HALMAC_FW_OFFLOAD_CMD_SIZE_88XX);
1986         PHY_PARAMETER_INFO_SET_IO_CMD(curr_buff_wptr, para_info->cmd_id);
1987
1988         switch (para_info->cmd_id) {
1989         case HALMAC_PARAMETER_CMD_BB_W8:
1990         case HALMAC_PARAMETER_CMD_BB_W16:
1991         case HALMAC_PARAMETER_CMD_BB_W32:
1992         case HALMAC_PARAMETER_CMD_MAC_W8:
1993         case HALMAC_PARAMETER_CMD_MAC_W16:
1994         case HALMAC_PARAMETER_CMD_MAC_W32:
1995                 PHY_PARAMETER_INFO_SET_IO_ADDR(
1996                         curr_buff_wptr, para_info->content.MAC_REG_W.offset);
1997                 PHY_PARAMETER_INFO_SET_DATA(curr_buff_wptr,
1998                                             para_info->content.MAC_REG_W.value);
1999                 PHY_PARAMETER_INFO_SET_MASK(curr_buff_wptr,
2000                                             para_info->content.MAC_REG_W.msk);
2001                 PHY_PARAMETER_INFO_SET_MSK_EN(
2002                         curr_buff_wptr, para_info->content.MAC_REG_W.msk_en);
2003                 config_para_info->value_accumulation +=
2004                         para_info->content.MAC_REG_W.value;
2005                 config_para_info->offset_accumulation +=
2006                         para_info->content.MAC_REG_W.offset;
2007                 break;
2008         case HALMAC_PARAMETER_CMD_RF_W:
2009                 /*In rf register, the address is only 1 byte*/
2010                 PHY_PARAMETER_INFO_SET_RF_ADDR(
2011                         curr_buff_wptr, para_info->content.RF_REG_W.offset);
2012                 PHY_PARAMETER_INFO_SET_RF_PATH(
2013                         curr_buff_wptr, para_info->content.RF_REG_W.rf_path);
2014                 PHY_PARAMETER_INFO_SET_DATA(curr_buff_wptr,
2015                                             para_info->content.RF_REG_W.value);
2016                 PHY_PARAMETER_INFO_SET_MASK(curr_buff_wptr,
2017                                             para_info->content.RF_REG_W.msk);
2018                 PHY_PARAMETER_INFO_SET_MSK_EN(
2019                         curr_buff_wptr, para_info->content.RF_REG_W.msk_en);
2020                 config_para_info->value_accumulation +=
2021                         para_info->content.RF_REG_W.value;
2022                 config_para_info->offset_accumulation +=
2023                         (para_info->content.RF_REG_W.offset +
2024                          (para_info->content.RF_REG_W.rf_path << 8));
2025                 break;
2026         case HALMAC_PARAMETER_CMD_DELAY_US:
2027         case HALMAC_PARAMETER_CMD_DELAY_MS:
2028                 PHY_PARAMETER_INFO_SET_DELAY_VALUE(
2029                         curr_buff_wptr,
2030                         para_info->content.DELAY_TIME.delay_time);
2031                 break;
2032         case HALMAC_PARAMETER_CMD_END:
2033                 *end_cmd = true;
2034                 break;
2035         default:
2036                 pr_err(" halmac_send_h2c_phy_parameter_88xx illegal cmd_id!!\n");
2037                 break;
2038         }
2039
2040         return HALMAC_RET_SUCCESS;
2041 }
2042
2043 static enum halmac_ret_status
2044 halmac_gen_cfg_para_h2c_88xx(struct halmac_adapter *halmac_adapter,
2045                              u8 *h2c_buff)
2046 {
2047         struct halmac_config_para_info *config_para_info =
2048                 &halmac_adapter->config_para_info;
2049
2050         CFG_PARAMETER_SET_NUM(h2c_buff, config_para_info->para_num);
2051
2052         if (config_para_info->full_fifo_mode) {
2053                 CFG_PARAMETER_SET_INIT_CASE(h2c_buff, 0x1);
2054                 CFG_PARAMETER_SET_PHY_PARAMETER_LOC(h2c_buff, 0);
2055         } else {
2056                 CFG_PARAMETER_SET_INIT_CASE(h2c_buff, 0x0);
2057                 CFG_PARAMETER_SET_PHY_PARAMETER_LOC(
2058                         h2c_buff,
2059                         halmac_adapter->txff_allocation
2060                                         .rsvd_h2c_extra_info_pg_bndy -
2061                                 halmac_adapter->txff_allocation.rsvd_pg_bndy);
2062         }
2063
2064         return HALMAC_RET_SUCCESS;
2065 }
2066
2067 enum halmac_ret_status
2068 halmac_send_h2c_run_datapack_88xx(struct halmac_adapter *halmac_adapter,
2069                                   enum halmac_data_type halmac_data_type)
2070 {
2071         u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
2072         u16 h2c_seq_mum = 0;
2073         void *driver_adapter = NULL;
2074         struct halmac_h2c_header_info h2c_header_info;
2075         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2076
2077         driver_adapter = halmac_adapter->driver_adapter;
2078
2079         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2080                         "%s!!\n", __func__);
2081
2082         RUN_DATAPACK_SET_DATAPACK_ID(h2c_buff, halmac_data_type);
2083
2084         h2c_header_info.sub_cmd_id = SUB_CMD_ID_RUN_DATAPACK;
2085         h2c_header_info.content_size = 4;
2086         h2c_header_info.ack = true;
2087         halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
2088                                               &h2c_header_info, &h2c_seq_mum);
2089
2090         status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
2091                                           HALMAC_H2C_CMD_SIZE_88XX, true);
2092
2093         if (status != HALMAC_RET_SUCCESS) {
2094                 pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
2095                 return status;
2096         }
2097
2098         return HALMAC_RET_SUCCESS;
2099 }
2100
2101 enum halmac_ret_status
2102 halmac_send_bt_coex_cmd_88xx(struct halmac_adapter *halmac_adapter, u8 *bt_buf,
2103                              u32 bt_size, u8 ack)
2104 {
2105         u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
2106         u16 h2c_seq_mum = 0;
2107         void *driver_adapter = NULL;
2108         struct halmac_h2c_header_info h2c_header_info;
2109         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2110
2111         driver_adapter = halmac_adapter->driver_adapter;
2112
2113         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2114                         "%s!!\n", __func__);
2115
2116         memcpy(h2c_buff + 8, bt_buf, bt_size);
2117
2118         h2c_header_info.sub_cmd_id = SUB_CMD_ID_BT_COEX;
2119         h2c_header_info.content_size = (u16)bt_size;
2120         h2c_header_info.ack = ack;
2121         halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
2122                                               &h2c_header_info, &h2c_seq_mum);
2123
2124         status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
2125                                           HALMAC_H2C_CMD_SIZE_88XX, ack);
2126
2127         if (status != HALMAC_RET_SUCCESS) {
2128                 pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
2129                 return status;
2130         }
2131
2132         return HALMAC_RET_SUCCESS;
2133 }
2134
2135 enum halmac_ret_status
2136 halmac_func_ctrl_ch_switch_88xx(struct halmac_adapter *halmac_adapter,
2137                                 struct halmac_ch_switch_option *cs_option)
2138 {
2139         u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
2140         u16 h2c_seq_mum = 0;
2141         void *driver_adapter = NULL;
2142         struct halmac_api *halmac_api;
2143         struct halmac_h2c_header_info h2c_header_info;
2144         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2145         enum halmac_cmd_process_status *process_status =
2146                 &halmac_adapter->halmac_state.scan_state_set.process_status;
2147
2148         driver_adapter = halmac_adapter->driver_adapter;
2149
2150         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2151                         "halmac_ctrl_ch_switch!!\n");
2152
2153         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
2154
2155         if (halmac_transition_scan_state_88xx(
2156                     halmac_adapter, HALMAC_SCAN_CMD_CONSTRUCT_H2C_SENT) !=
2157             HALMAC_RET_SUCCESS)
2158                 return HALMAC_RET_ERROR_STATE;
2159
2160         *process_status = HALMAC_CMD_PROCESS_SENDING;
2161
2162         if (cs_option->switch_en != 0) {
2163                 HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
2164                                     (u16)(halmac_adapter->txff_allocation
2165                                                   .rsvd_h2c_extra_info_pg_bndy &
2166                                           BIT_MASK_BCN_HEAD_1_V1));
2167
2168                 status = halmac_download_rsvd_page_88xx(
2169                         halmac_adapter, halmac_adapter->ch_sw_info.ch_info_buf,
2170                         halmac_adapter->ch_sw_info.total_size);
2171
2172                 if (status != HALMAC_RET_SUCCESS) {
2173                         pr_err("halmac_download_rsvd_page_88xx Fail = %x!!\n",
2174                                status);
2175                         HALMAC_REG_WRITE_16(
2176                                 halmac_adapter, REG_FIFOPAGE_CTRL_2,
2177                                 (u16)(halmac_adapter->txff_allocation
2178                                               .rsvd_pg_bndy &
2179                                       BIT_MASK_BCN_HEAD_1_V1));
2180                         return status;
2181                 }
2182
2183                 HALMAC_REG_WRITE_16(
2184                         halmac_adapter, REG_FIFOPAGE_CTRL_2,
2185                         (u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
2186                               BIT_MASK_BCN_HEAD_1_V1));
2187         }
2188
2189         CHANNEL_SWITCH_SET_SWITCH_START(h2c_buff, cs_option->switch_en);
2190         CHANNEL_SWITCH_SET_CHANNEL_NUM(h2c_buff,
2191                                        halmac_adapter->ch_sw_info.ch_num);
2192         CHANNEL_SWITCH_SET_CHANNEL_INFO_LOC(
2193                 h2c_buff,
2194                 halmac_adapter->txff_allocation.rsvd_h2c_extra_info_pg_bndy -
2195                         halmac_adapter->txff_allocation.rsvd_pg_bndy);
2196         CHANNEL_SWITCH_SET_DEST_CH_EN(h2c_buff, cs_option->dest_ch_en);
2197         CHANNEL_SWITCH_SET_DEST_CH(h2c_buff, cs_option->dest_ch);
2198         CHANNEL_SWITCH_SET_PRI_CH_IDX(h2c_buff, cs_option->dest_pri_ch_idx);
2199         CHANNEL_SWITCH_SET_ABSOLUTE_TIME(h2c_buff, cs_option->absolute_time_en);
2200         CHANNEL_SWITCH_SET_TSF_LOW(h2c_buff, cs_option->tsf_low);
2201         CHANNEL_SWITCH_SET_PERIODIC_OPTION(h2c_buff,
2202                                            cs_option->periodic_option);
2203         CHANNEL_SWITCH_SET_NORMAL_CYCLE(h2c_buff, cs_option->normal_cycle);
2204         CHANNEL_SWITCH_SET_NORMAL_PERIOD(h2c_buff, cs_option->normal_period);
2205         CHANNEL_SWITCH_SET_SLOW_PERIOD(h2c_buff, cs_option->phase_2_period);
2206         CHANNEL_SWITCH_SET_CHANNEL_INFO_SIZE(
2207                 h2c_buff, halmac_adapter->ch_sw_info.total_size);
2208
2209         h2c_header_info.sub_cmd_id = SUB_CMD_ID_CHANNEL_SWITCH;
2210         h2c_header_info.content_size = 20;
2211         h2c_header_info.ack = true;
2212         halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
2213                                               &h2c_header_info, &h2c_seq_mum);
2214         halmac_adapter->halmac_state.scan_state_set.seq_num = h2c_seq_mum;
2215
2216         status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
2217                                           HALMAC_H2C_CMD_SIZE_88XX, true);
2218
2219         if (status != HALMAC_RET_SUCCESS)
2220                 pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
2221
2222         kfree(halmac_adapter->ch_sw_info.ch_info_buf);
2223         halmac_adapter->ch_sw_info.ch_info_buf = NULL;
2224         halmac_adapter->ch_sw_info.ch_info_buf_w = NULL;
2225         halmac_adapter->ch_sw_info.extra_info_en = 0;
2226         halmac_adapter->ch_sw_info.buf_size = 0;
2227         halmac_adapter->ch_sw_info.avai_buf_size = 0;
2228         halmac_adapter->ch_sw_info.total_size = 0;
2229         halmac_adapter->ch_sw_info.ch_num = 0;
2230
2231         if (halmac_transition_scan_state_88xx(halmac_adapter,
2232                                               HALMAC_SCAN_CMD_CONSTRUCT_IDLE) !=
2233             HALMAC_RET_SUCCESS)
2234                 return HALMAC_RET_ERROR_STATE;
2235
2236         return status;
2237 }
2238
2239 enum halmac_ret_status
2240 halmac_func_send_general_info_88xx(struct halmac_adapter *halmac_adapter,
2241                                    struct halmac_general_info *general_info)
2242 {
2243         u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
2244         u16 h2c_seq_mum = 0;
2245         void *driver_adapter = NULL;
2246         struct halmac_h2c_header_info h2c_header_info;
2247         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2248
2249         driver_adapter = halmac_adapter->driver_adapter;
2250
2251         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2252                         "halmac_send_general_info!!\n");
2253
2254         GENERAL_INFO_SET_REF_TYPE(h2c_buff, general_info->rfe_type);
2255         GENERAL_INFO_SET_RF_TYPE(h2c_buff, general_info->rf_type);
2256         GENERAL_INFO_SET_FW_TX_BOUNDARY(
2257                 h2c_buff,
2258                 halmac_adapter->txff_allocation.rsvd_fw_txbuff_pg_bndy -
2259                         halmac_adapter->txff_allocation.rsvd_pg_bndy);
2260
2261         h2c_header_info.sub_cmd_id = SUB_CMD_ID_GENERAL_INFO;
2262         h2c_header_info.content_size = 4;
2263         h2c_header_info.ack = false;
2264         halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
2265                                               &h2c_header_info, &h2c_seq_mum);
2266
2267         status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
2268                                           HALMAC_H2C_CMD_SIZE_88XX, true);
2269
2270         if (status != HALMAC_RET_SUCCESS)
2271                 pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
2272
2273         return status;
2274 }
2275
2276 enum halmac_ret_status halmac_send_h2c_update_bcn_parse_info_88xx(
2277         struct halmac_adapter *halmac_adapter,
2278         struct halmac_bcn_ie_info *bcn_ie_info)
2279 {
2280         u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
2281         u16 h2c_seq_mum = 0;
2282         void *driver_adapter = halmac_adapter->driver_adapter;
2283         struct halmac_h2c_header_info h2c_header_info;
2284         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2285
2286         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2287                         "%s!!\n", __func__);
2288
2289         UPDATE_BEACON_PARSING_INFO_SET_FUNC_EN(h2c_buff, bcn_ie_info->func_en);
2290         UPDATE_BEACON_PARSING_INFO_SET_SIZE_TH(h2c_buff, bcn_ie_info->size_th);
2291         UPDATE_BEACON_PARSING_INFO_SET_TIMEOUT(h2c_buff, bcn_ie_info->timeout);
2292
2293         UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_0(
2294                 h2c_buff, (u32)(bcn_ie_info->ie_bmp[0]));
2295         UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_1(
2296                 h2c_buff, (u32)(bcn_ie_info->ie_bmp[1]));
2297         UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_2(
2298                 h2c_buff, (u32)(bcn_ie_info->ie_bmp[2]));
2299         UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_3(
2300                 h2c_buff, (u32)(bcn_ie_info->ie_bmp[3]));
2301         UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_4(
2302                 h2c_buff, (u32)(bcn_ie_info->ie_bmp[4]));
2303
2304         h2c_header_info.sub_cmd_id = SUB_CMD_ID_UPDATE_BEACON_PARSING_INFO;
2305         h2c_header_info.content_size = 24;
2306         h2c_header_info.ack = true;
2307         halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
2308                                               &h2c_header_info, &h2c_seq_mum);
2309
2310         status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
2311                                           HALMAC_H2C_CMD_SIZE_88XX, true);
2312
2313         if (status != HALMAC_RET_SUCCESS) {
2314                 pr_err("halmac_send_h2c_pkt_88xx Fail =%x !!\n", status);
2315                 return status;
2316         }
2317
2318         return status;
2319 }
2320
2321 enum halmac_ret_status
2322 halmac_send_h2c_ps_tuning_para_88xx(struct halmac_adapter *halmac_adapter)
2323 {
2324         u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
2325         u8 *h2c_header, *h2c_cmd;
2326         u16 seq = 0;
2327         void *driver_adapter = NULL;
2328         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2329
2330         driver_adapter = halmac_adapter->driver_adapter;
2331
2332         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2333                         "%s!!\n", __func__);
2334
2335         h2c_header = h2c_buff;
2336         h2c_cmd = h2c_header + HALMAC_H2C_CMD_HDR_SIZE_88XX;
2337
2338         halmac_set_h2c_header_88xx(halmac_adapter, h2c_header, &seq, false);
2339
2340         status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
2341                                           HALMAC_H2C_CMD_SIZE_88XX, false);
2342
2343         if (status != HALMAC_RET_SUCCESS) {
2344                 pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
2345                 return status;
2346         }
2347
2348         return status;
2349 }
2350
2351 enum halmac_ret_status
2352 halmac_parse_c2h_packet_88xx(struct halmac_adapter *halmac_adapter,
2353                              u8 *halmac_buf, u32 halmac_size)
2354 {
2355         u8 c2h_cmd, c2h_sub_cmd_id;
2356         u8 *c2h_buf = halmac_buf + halmac_adapter->hw_config_info.rxdesc_size;
2357         u32 c2h_size = halmac_size - halmac_adapter->hw_config_info.rxdesc_size;
2358         void *driver_adapter = halmac_adapter->driver_adapter;
2359         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2360
2361         c2h_cmd = (u8)C2H_HDR_GET_CMD_ID(c2h_buf);
2362
2363         /* FW offload C2H cmd is 0xFF */
2364         if (c2h_cmd != 0xFF) {
2365                 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2366                                 "C2H_PKT not for FwOffloadC2HFormat!!\n");
2367                 return HALMAC_RET_C2H_NOT_HANDLED;
2368         }
2369
2370         /* Get C2H sub cmd ID */
2371         c2h_sub_cmd_id = (u8)C2H_HDR_GET_C2H_SUB_CMD_ID(c2h_buf);
2372
2373         switch (c2h_sub_cmd_id) {
2374         case C2H_SUB_CMD_ID_C2H_DBG:
2375                 status = halmac_parse_c2h_debug_88xx(halmac_adapter, c2h_buf,
2376                                                      c2h_size);
2377                 break;
2378         case C2H_SUB_CMD_ID_H2C_ACK_HDR:
2379                 status = halmac_parse_h2c_ack_88xx(halmac_adapter, c2h_buf,
2380                                                    c2h_size);
2381                 break;
2382         case C2H_SUB_CMD_ID_BT_COEX_INFO:
2383                 status = HALMAC_RET_C2H_NOT_HANDLED;
2384                 break;
2385         case C2H_SUB_CMD_ID_SCAN_STATUS_RPT:
2386                 status = halmac_parse_scan_status_rpt_88xx(halmac_adapter,
2387                                                            c2h_buf, c2h_size);
2388                 break;
2389         case C2H_SUB_CMD_ID_PSD_DATA:
2390                 status = halmac_parse_psd_data_88xx(halmac_adapter, c2h_buf,
2391                                                     c2h_size);
2392                 break;
2393
2394         case C2H_SUB_CMD_ID_EFUSE_DATA:
2395                 status = halmac_parse_efuse_data_88xx(halmac_adapter, c2h_buf,
2396                                                       c2h_size);
2397                 break;
2398         default:
2399                 pr_err("c2h_sub_cmd_id switch case out of boundary!!\n");
2400                 pr_err("[ERR]c2h pkt : %.8X %.8X!!\n", *(u32 *)c2h_buf,
2401                        *(u32 *)(c2h_buf + 4));
2402                 status = HALMAC_RET_C2H_NOT_HANDLED;
2403                 break;
2404         }
2405
2406         return status;
2407 }
2408
2409 static enum halmac_ret_status
2410 halmac_parse_c2h_debug_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
2411                             u32 c2h_size)
2412 {
2413         void *driver_adapter = NULL;
2414         u8 *c2h_buf_local = (u8 *)NULL;
2415         u32 c2h_size_local = 0;
2416         u8 dbg_content_length = 0;
2417         u8 dbg_seq_num = 0;
2418
2419         driver_adapter = halmac_adapter->driver_adapter;
2420         c2h_buf_local = c2h_buf;
2421         c2h_size_local = c2h_size;
2422
2423         dbg_content_length = (u8)C2H_HDR_GET_LEN((u8 *)c2h_buf_local);
2424
2425         if (dbg_content_length > C2H_DBG_CONTENT_MAX_LENGTH)
2426                 return HALMAC_RET_SUCCESS;
2427
2428         *(c2h_buf_local + C2H_DBG_HEADER_LENGTH + dbg_content_length - 2) =
2429                 '\n';
2430         dbg_seq_num = (u8)(*(c2h_buf_local + C2H_DBG_HEADER_LENGTH));
2431         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2432                         "[RTKFW, SEQ=%d]: %s", dbg_seq_num,
2433                         (char *)(c2h_buf_local + C2H_DBG_HEADER_LENGTH + 1));
2434
2435         return HALMAC_RET_SUCCESS;
2436 }
2437
2438 static enum halmac_ret_status
2439 halmac_parse_scan_status_rpt_88xx(struct halmac_adapter *halmac_adapter,
2440                                   u8 *c2h_buf, u32 c2h_size)
2441 {
2442         u8 h2c_return_code;
2443         void *driver_adapter = halmac_adapter->driver_adapter;
2444         enum halmac_cmd_process_status process_status;
2445
2446         h2c_return_code = (u8)SCAN_STATUS_RPT_GET_H2C_RETURN_CODE(c2h_buf);
2447         process_status = (enum halmac_h2c_return_code)h2c_return_code ==
2448                                          HALMAC_H2C_RETURN_SUCCESS ?
2449                                  HALMAC_CMD_PROCESS_DONE :
2450                                  HALMAC_CMD_PROCESS_ERROR;
2451
2452         PLATFORM_EVENT_INDICATION(driver_adapter, HALMAC_FEATURE_CHANNEL_SWITCH,
2453                                   process_status, NULL, 0);
2454
2455         halmac_adapter->halmac_state.scan_state_set.process_status =
2456                 process_status;
2457
2458         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2459                         "[TRACE]scan status : %X\n", process_status);
2460
2461         return HALMAC_RET_SUCCESS;
2462 }
2463
2464 static enum halmac_ret_status
2465 halmac_parse_psd_data_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
2466                            u32 c2h_size)
2467 {
2468         u8 segment_id = 0, segment_size = 0, h2c_seq = 0;
2469         u16 total_size;
2470         void *driver_adapter = halmac_adapter->driver_adapter;
2471         enum halmac_cmd_process_status process_status;
2472         struct halmac_psd_state_set *psd_set =
2473                 &halmac_adapter->halmac_state.psd_set;
2474
2475         h2c_seq = (u8)PSD_DATA_GET_H2C_SEQ(c2h_buf);
2476         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2477                         "[TRACE]Seq num : h2c -> %d c2h -> %d\n",
2478                         psd_set->seq_num, h2c_seq);
2479         if (h2c_seq != psd_set->seq_num) {
2480                 pr_err("[ERR]Seq num mismatch : h2c -> %d c2h -> %d\n",
2481                        psd_set->seq_num, h2c_seq);
2482                 return HALMAC_RET_SUCCESS;
2483         }
2484
2485         if (psd_set->process_status != HALMAC_CMD_PROCESS_SENDING) {
2486                 pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
2487                 return HALMAC_RET_SUCCESS;
2488         }
2489
2490         total_size = (u16)PSD_DATA_GET_TOTAL_SIZE(c2h_buf);
2491         segment_id = (u8)PSD_DATA_GET_SEGMENT_ID(c2h_buf);
2492         segment_size = (u8)PSD_DATA_GET_SEGMENT_SIZE(c2h_buf);
2493         psd_set->data_size = total_size;
2494
2495         if (!psd_set->data) {
2496                 psd_set->data = kzalloc(psd_set->data_size, GFP_KERNEL);
2497                 if (!psd_set->data)
2498                         return HALMAC_RET_MALLOC_FAIL;
2499         }
2500
2501         if (segment_id == 0)
2502                 psd_set->segment_size = segment_size;
2503
2504         memcpy(psd_set->data + segment_id * psd_set->segment_size,
2505                c2h_buf + HALMAC_C2H_DATA_OFFSET_88XX, segment_size);
2506
2507         if (!PSD_DATA_GET_END_SEGMENT(c2h_buf))
2508                 return HALMAC_RET_SUCCESS;
2509
2510         process_status = HALMAC_CMD_PROCESS_DONE;
2511         psd_set->process_status = process_status;
2512
2513         PLATFORM_EVENT_INDICATION(driver_adapter, HALMAC_FEATURE_PSD,
2514                                   process_status, psd_set->data,
2515                                   psd_set->data_size);
2516
2517         return HALMAC_RET_SUCCESS;
2518 }
2519
2520 static enum halmac_ret_status
2521 halmac_parse_efuse_data_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
2522                              u32 c2h_size)
2523 {
2524         u8 segment_id = 0, segment_size = 0, h2c_seq = 0;
2525         u8 *eeprom_map = NULL;
2526         u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
2527         u8 h2c_return_code = 0;
2528         void *driver_adapter = halmac_adapter->driver_adapter;
2529         enum halmac_cmd_process_status process_status;
2530
2531         h2c_seq = (u8)EFUSE_DATA_GET_H2C_SEQ(c2h_buf);
2532         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2533                         "[TRACE]Seq num : h2c -> %d c2h -> %d\n",
2534                         halmac_adapter->halmac_state.efuse_state_set.seq_num,
2535                         h2c_seq);
2536         if (h2c_seq != halmac_adapter->halmac_state.efuse_state_set.seq_num) {
2537                 pr_err("[ERR]Seq num mismatch : h2c -> %d c2h -> %d\n",
2538                        halmac_adapter->halmac_state.efuse_state_set.seq_num,
2539                        h2c_seq);
2540                 return HALMAC_RET_SUCCESS;
2541         }
2542
2543         if (halmac_adapter->halmac_state.efuse_state_set.process_status !=
2544             HALMAC_CMD_PROCESS_SENDING) {
2545                 pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
2546                 return HALMAC_RET_SUCCESS;
2547         }
2548
2549         segment_id = (u8)EFUSE_DATA_GET_SEGMENT_ID(c2h_buf);
2550         segment_size = (u8)EFUSE_DATA_GET_SEGMENT_SIZE(c2h_buf);
2551         if (segment_id == 0)
2552                 halmac_adapter->efuse_segment_size = segment_size;
2553
2554         eeprom_map = kzalloc(eeprom_size, GFP_KERNEL);
2555         if (!eeprom_map) {
2556                 /* out of memory */
2557                 return HALMAC_RET_MALLOC_FAIL;
2558         }
2559         memset(eeprom_map, 0xFF, eeprom_size);
2560
2561         spin_lock(&halmac_adapter->efuse_lock);
2562         memcpy(halmac_adapter->hal_efuse_map +
2563                        segment_id * halmac_adapter->efuse_segment_size,
2564                c2h_buf + HALMAC_C2H_DATA_OFFSET_88XX, segment_size);
2565         spin_unlock(&halmac_adapter->efuse_lock);
2566
2567         if (!EFUSE_DATA_GET_END_SEGMENT(c2h_buf)) {
2568                 kfree(eeprom_map);
2569                 return HALMAC_RET_SUCCESS;
2570         }
2571
2572         h2c_return_code =
2573                 halmac_adapter->halmac_state.efuse_state_set.fw_return_code;
2574
2575         if ((enum halmac_h2c_return_code)h2c_return_code ==
2576             HALMAC_H2C_RETURN_SUCCESS) {
2577                 process_status = HALMAC_CMD_PROCESS_DONE;
2578                 halmac_adapter->halmac_state.efuse_state_set.process_status =
2579                         process_status;
2580
2581                 spin_lock(&halmac_adapter->efuse_lock);
2582                 halmac_adapter->hal_efuse_map_valid = true;
2583                 spin_unlock(&halmac_adapter->efuse_lock);
2584
2585                 if (halmac_adapter->event_trigger.physical_efuse_map == 1) {
2586                         PLATFORM_EVENT_INDICATION(
2587                                 driver_adapter,
2588                                 HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE,
2589                                 process_status, halmac_adapter->hal_efuse_map,
2590                                 halmac_adapter->hw_config_info.efuse_size);
2591                         halmac_adapter->event_trigger.physical_efuse_map = 0;
2592                 }
2593
2594                 if (halmac_adapter->event_trigger.logical_efuse_map == 1) {
2595                         if (halmac_eeprom_parser_88xx(
2596                                     halmac_adapter,
2597                                     halmac_adapter->hal_efuse_map,
2598                                     eeprom_map) != HALMAC_RET_SUCCESS) {
2599                                 kfree(eeprom_map);
2600                                 return HALMAC_RET_EEPROM_PARSING_FAIL;
2601                         }
2602                         PLATFORM_EVENT_INDICATION(
2603                                 driver_adapter,
2604                                 HALMAC_FEATURE_DUMP_LOGICAL_EFUSE,
2605                                 process_status, eeprom_map, eeprom_size);
2606                         halmac_adapter->event_trigger.logical_efuse_map = 0;
2607                 }
2608         } else {
2609                 process_status = HALMAC_CMD_PROCESS_ERROR;
2610                 halmac_adapter->halmac_state.efuse_state_set.process_status =
2611                         process_status;
2612
2613                 if (halmac_adapter->event_trigger.physical_efuse_map == 1) {
2614                         PLATFORM_EVENT_INDICATION(
2615                                 driver_adapter,
2616                                 HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE,
2617                                 process_status,
2618                                 &halmac_adapter->halmac_state.efuse_state_set
2619                                          .fw_return_code,
2620                                 1);
2621                         halmac_adapter->event_trigger.physical_efuse_map = 0;
2622                 }
2623
2624                 if (halmac_adapter->event_trigger.logical_efuse_map == 1) {
2625                         if (halmac_eeprom_parser_88xx(
2626                                     halmac_adapter,
2627                                     halmac_adapter->hal_efuse_map,
2628                                     eeprom_map) != HALMAC_RET_SUCCESS) {
2629                                 kfree(eeprom_map);
2630                                 return HALMAC_RET_EEPROM_PARSING_FAIL;
2631                         }
2632                         PLATFORM_EVENT_INDICATION(
2633                                 driver_adapter,
2634                                 HALMAC_FEATURE_DUMP_LOGICAL_EFUSE,
2635                                 process_status,
2636                                 &halmac_adapter->halmac_state.efuse_state_set
2637                                          .fw_return_code,
2638                                 1);
2639                         halmac_adapter->event_trigger.logical_efuse_map = 0;
2640                 }
2641         }
2642
2643         kfree(eeprom_map);
2644
2645         return HALMAC_RET_SUCCESS;
2646 }
2647
2648 static enum halmac_ret_status
2649 halmac_parse_h2c_ack_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
2650                           u32 c2h_size)
2651 {
2652         u8 h2c_cmd_id, h2c_sub_cmd_id;
2653         u8 h2c_return_code;
2654         void *driver_adapter = halmac_adapter->driver_adapter;
2655         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2656
2657         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2658                         "Ack for C2H!!\n");
2659
2660         h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
2661         if ((enum halmac_h2c_return_code)h2c_return_code !=
2662             HALMAC_H2C_RETURN_SUCCESS)
2663                 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2664                                 "C2H_PKT Status Error!! Status = %d\n",
2665                                 h2c_return_code);
2666
2667         h2c_cmd_id = (u8)H2C_ACK_HDR_GET_H2C_CMD_ID(c2h_buf);
2668
2669         if (h2c_cmd_id != 0xFF) {
2670                 pr_err("original h2c ack is not handled!!\n");
2671                 status = HALMAC_RET_C2H_NOT_HANDLED;
2672         } else {
2673                 h2c_sub_cmd_id = (u8)H2C_ACK_HDR_GET_H2C_SUB_CMD_ID(c2h_buf);
2674
2675                 switch (h2c_sub_cmd_id) {
2676                 case H2C_SUB_CMD_ID_DUMP_PHYSICAL_EFUSE_ACK:
2677                         status = halmac_parse_h2c_ack_phy_efuse_88xx(
2678                                 halmac_adapter, c2h_buf, c2h_size);
2679                         break;
2680                 case H2C_SUB_CMD_ID_CFG_PARAMETER_ACK:
2681                         status = halmac_parse_h2c_ack_cfg_para_88xx(
2682                                 halmac_adapter, c2h_buf, c2h_size);
2683                         break;
2684                 case H2C_SUB_CMD_ID_UPDATE_PACKET_ACK:
2685                         status = halmac_parse_h2c_ack_update_packet_88xx(
2686                                 halmac_adapter, c2h_buf, c2h_size);
2687                         break;
2688                 case H2C_SUB_CMD_ID_UPDATE_DATAPACK_ACK:
2689                         status = halmac_parse_h2c_ack_update_datapack_88xx(
2690                                 halmac_adapter, c2h_buf, c2h_size);
2691                         break;
2692                 case H2C_SUB_CMD_ID_RUN_DATAPACK_ACK:
2693                         status = halmac_parse_h2c_ack_run_datapack_88xx(
2694                                 halmac_adapter, c2h_buf, c2h_size);
2695                         break;
2696                 case H2C_SUB_CMD_ID_CHANNEL_SWITCH_ACK:
2697                         status = halmac_parse_h2c_ack_channel_switch_88xx(
2698                                 halmac_adapter, c2h_buf, c2h_size);
2699                         break;
2700                 case H2C_SUB_CMD_ID_IQK_ACK:
2701                         status = halmac_parse_h2c_ack_iqk_88xx(
2702                                 halmac_adapter, c2h_buf, c2h_size);
2703                         break;
2704                 case H2C_SUB_CMD_ID_POWER_TRACKING_ACK:
2705                         status = halmac_parse_h2c_ack_power_tracking_88xx(
2706                                 halmac_adapter, c2h_buf, c2h_size);
2707                         break;
2708                 case H2C_SUB_CMD_ID_PSD_ACK:
2709                         break;
2710                 default:
2711                         pr_err("h2c_sub_cmd_id switch case out of boundary!!\n");
2712                         status = HALMAC_RET_C2H_NOT_HANDLED;
2713                         break;
2714                 }
2715         }
2716
2717         return status;
2718 }
2719
2720 static enum halmac_ret_status
2721 halmac_parse_h2c_ack_phy_efuse_88xx(struct halmac_adapter *halmac_adapter,
2722                                     u8 *c2h_buf, u32 c2h_size)
2723 {
2724         u8 h2c_seq = 0;
2725         u8 h2c_return_code;
2726         void *driver_adapter = halmac_adapter->driver_adapter;
2727
2728         h2c_seq = (u8)H2C_ACK_HDR_GET_H2C_SEQ(c2h_buf);
2729         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2730                         "[TRACE]Seq num : h2c -> %d c2h -> %d\n",
2731                         halmac_adapter->halmac_state.efuse_state_set.seq_num,
2732                         h2c_seq);
2733         if (h2c_seq != halmac_adapter->halmac_state.efuse_state_set.seq_num) {
2734                 pr_err("[ERR]Seq num mismatch : h2c -> %d c2h -> %d\n",
2735                        halmac_adapter->halmac_state.efuse_state_set.seq_num,
2736                        h2c_seq);
2737                 return HALMAC_RET_SUCCESS;
2738         }
2739
2740         if (halmac_adapter->halmac_state.efuse_state_set.process_status !=
2741             HALMAC_CMD_PROCESS_SENDING) {
2742                 pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
2743                 return HALMAC_RET_SUCCESS;
2744         }
2745
2746         h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
2747         halmac_adapter->halmac_state.efuse_state_set.fw_return_code =
2748                 h2c_return_code;
2749
2750         return HALMAC_RET_SUCCESS;
2751 }
2752
2753 static enum halmac_ret_status
2754 halmac_parse_h2c_ack_cfg_para_88xx(struct halmac_adapter *halmac_adapter,
2755                                    u8 *c2h_buf, u32 c2h_size)
2756 {
2757         u8 h2c_seq = 0;
2758         u8 h2c_return_code;
2759         u32 offset_accu = 0, value_accu = 0;
2760         void *driver_adapter = halmac_adapter->driver_adapter;
2761         enum halmac_cmd_process_status process_status =
2762                 HALMAC_CMD_PROCESS_UNDEFINE;
2763
2764         h2c_seq = (u8)H2C_ACK_HDR_GET_H2C_SEQ(c2h_buf);
2765         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2766                         "Seq num : h2c -> %d c2h -> %d\n",
2767                         halmac_adapter->halmac_state.cfg_para_state_set.seq_num,
2768                         h2c_seq);
2769         if (h2c_seq !=
2770             halmac_adapter->halmac_state.cfg_para_state_set.seq_num) {
2771                 pr_err("Seq num mismatch : h2c -> %d c2h -> %d\n",
2772                        halmac_adapter->halmac_state.cfg_para_state_set.seq_num,
2773                        h2c_seq);
2774                 return HALMAC_RET_SUCCESS;
2775         }
2776
2777         if (halmac_adapter->halmac_state.cfg_para_state_set.process_status !=
2778             HALMAC_CMD_PROCESS_SENDING) {
2779                 pr_err("Not in HALMAC_CMD_PROCESS_SENDING\n");
2780                 return HALMAC_RET_SUCCESS;
2781         }
2782
2783         h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
2784         halmac_adapter->halmac_state.cfg_para_state_set.fw_return_code =
2785                 h2c_return_code;
2786         offset_accu = CFG_PARAMETER_ACK_GET_OFFSET_ACCUMULATION(c2h_buf);
2787         value_accu = CFG_PARAMETER_ACK_GET_VALUE_ACCUMULATION(c2h_buf);
2788
2789         if ((offset_accu !=
2790              halmac_adapter->config_para_info.offset_accumulation) ||
2791             (value_accu !=
2792              halmac_adapter->config_para_info.value_accumulation)) {
2793                 pr_err("[C2H]offset_accu : %x, value_accu : %x!!\n",
2794                        offset_accu, value_accu);
2795                 pr_err("[Adapter]offset_accu : %x, value_accu : %x!!\n",
2796                        halmac_adapter->config_para_info.offset_accumulation,
2797                        halmac_adapter->config_para_info.value_accumulation);
2798                 process_status = HALMAC_CMD_PROCESS_ERROR;
2799         }
2800
2801         if ((enum halmac_h2c_return_code)h2c_return_code ==
2802                     HALMAC_H2C_RETURN_SUCCESS &&
2803             process_status != HALMAC_CMD_PROCESS_ERROR) {
2804                 process_status = HALMAC_CMD_PROCESS_DONE;
2805                 halmac_adapter->halmac_state.cfg_para_state_set.process_status =
2806                         process_status;
2807                 PLATFORM_EVENT_INDICATION(driver_adapter,
2808                                           HALMAC_FEATURE_CFG_PARA,
2809                                           process_status, NULL, 0);
2810         } else {
2811                 process_status = HALMAC_CMD_PROCESS_ERROR;
2812                 halmac_adapter->halmac_state.cfg_para_state_set.process_status =
2813                         process_status;
2814                 PLATFORM_EVENT_INDICATION(
2815                         driver_adapter, HALMAC_FEATURE_CFG_PARA, process_status,
2816                         &halmac_adapter->halmac_state.cfg_para_state_set
2817                                  .fw_return_code,
2818                         1);
2819         }
2820
2821         return HALMAC_RET_SUCCESS;
2822 }
2823
2824 static enum halmac_ret_status
2825 halmac_parse_h2c_ack_update_packet_88xx(struct halmac_adapter *halmac_adapter,
2826                                         u8 *c2h_buf, u32 c2h_size)
2827 {
2828         u8 h2c_seq = 0;
2829         u8 h2c_return_code;
2830         void *driver_adapter = halmac_adapter->driver_adapter;
2831         enum halmac_cmd_process_status process_status;
2832
2833         h2c_seq = (u8)H2C_ACK_HDR_GET_H2C_SEQ(c2h_buf);
2834         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2835                         "[TRACE]Seq num : h2c -> %d c2h -> %d\n",
2836                         halmac_adapter->halmac_state.update_packet_set.seq_num,
2837                         h2c_seq);
2838         if (h2c_seq != halmac_adapter->halmac_state.update_packet_set.seq_num) {
2839                 pr_err("[ERR]Seq num mismatch : h2c -> %d c2h -> %d\n",
2840                        halmac_adapter->halmac_state.update_packet_set.seq_num,
2841                        h2c_seq);
2842                 return HALMAC_RET_SUCCESS;
2843         }
2844
2845         if (halmac_adapter->halmac_state.update_packet_set.process_status !=
2846             HALMAC_CMD_PROCESS_SENDING) {
2847                 pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
2848                 return HALMAC_RET_SUCCESS;
2849         }
2850
2851         h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
2852         halmac_adapter->halmac_state.update_packet_set.fw_return_code =
2853                 h2c_return_code;
2854
2855         if ((enum halmac_h2c_return_code)h2c_return_code ==
2856             HALMAC_H2C_RETURN_SUCCESS) {
2857                 process_status = HALMAC_CMD_PROCESS_DONE;
2858                 halmac_adapter->halmac_state.update_packet_set.process_status =
2859                         process_status;
2860                 PLATFORM_EVENT_INDICATION(driver_adapter,
2861                                           HALMAC_FEATURE_UPDATE_PACKET,
2862                                           process_status, NULL, 0);
2863         } else {
2864                 process_status = HALMAC_CMD_PROCESS_ERROR;
2865                 halmac_adapter->halmac_state.update_packet_set.process_status =
2866                         process_status;
2867                 PLATFORM_EVENT_INDICATION(
2868                         driver_adapter, HALMAC_FEATURE_UPDATE_PACKET,
2869                         process_status,
2870                         &halmac_adapter->halmac_state.update_packet_set
2871                                  .fw_return_code,
2872                         1);
2873         }
2874
2875         return HALMAC_RET_SUCCESS;
2876 }
2877
2878 static enum halmac_ret_status
2879 halmac_parse_h2c_ack_update_datapack_88xx(struct halmac_adapter *halmac_adapter,
2880                                           u8 *c2h_buf, u32 c2h_size)
2881 {
2882         void *driver_adapter = halmac_adapter->driver_adapter;
2883         enum halmac_cmd_process_status process_status =
2884                 HALMAC_CMD_PROCESS_UNDEFINE;
2885
2886         PLATFORM_EVENT_INDICATION(driver_adapter,
2887                                   HALMAC_FEATURE_UPDATE_DATAPACK,
2888                                   process_status, NULL, 0);
2889
2890         return HALMAC_RET_SUCCESS;
2891 }
2892
2893 static enum halmac_ret_status
2894 halmac_parse_h2c_ack_run_datapack_88xx(struct halmac_adapter *halmac_adapter,
2895                                        u8 *c2h_buf, u32 c2h_size)
2896 {
2897         void *driver_adapter = halmac_adapter->driver_adapter;
2898         enum halmac_cmd_process_status process_status =
2899                 HALMAC_CMD_PROCESS_UNDEFINE;
2900
2901         PLATFORM_EVENT_INDICATION(driver_adapter, HALMAC_FEATURE_RUN_DATAPACK,
2902                                   process_status, NULL, 0);
2903
2904         return HALMAC_RET_SUCCESS;
2905 }
2906
2907 static enum halmac_ret_status
2908 halmac_parse_h2c_ack_channel_switch_88xx(struct halmac_adapter *halmac_adapter,
2909                                          u8 *c2h_buf, u32 c2h_size)
2910 {
2911         u8 h2c_seq = 0;
2912         u8 h2c_return_code;
2913         void *driver_adapter = halmac_adapter->driver_adapter;
2914         enum halmac_cmd_process_status process_status;
2915
2916         h2c_seq = (u8)H2C_ACK_HDR_GET_H2C_SEQ(c2h_buf);
2917         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2918                         "[TRACE]Seq num : h2c -> %d c2h -> %d\n",
2919                         halmac_adapter->halmac_state.scan_state_set.seq_num,
2920                         h2c_seq);
2921         if (h2c_seq != halmac_adapter->halmac_state.scan_state_set.seq_num) {
2922                 pr_err("[ERR]Seq num misactch : h2c -> %d c2h -> %d\n",
2923                        halmac_adapter->halmac_state.scan_state_set.seq_num,
2924                        h2c_seq);
2925                 return HALMAC_RET_SUCCESS;
2926         }
2927
2928         if (halmac_adapter->halmac_state.scan_state_set.process_status !=
2929             HALMAC_CMD_PROCESS_SENDING) {
2930                 pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
2931                 return HALMAC_RET_SUCCESS;
2932         }
2933
2934         h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
2935         halmac_adapter->halmac_state.scan_state_set.fw_return_code =
2936                 h2c_return_code;
2937
2938         if ((enum halmac_h2c_return_code)h2c_return_code ==
2939             HALMAC_H2C_RETURN_SUCCESS) {
2940                 process_status = HALMAC_CMD_PROCESS_RCVD;
2941                 halmac_adapter->halmac_state.scan_state_set.process_status =
2942                         process_status;
2943                 PLATFORM_EVENT_INDICATION(driver_adapter,
2944                                           HALMAC_FEATURE_CHANNEL_SWITCH,
2945                                           process_status, NULL, 0);
2946         } else {
2947                 process_status = HALMAC_CMD_PROCESS_ERROR;
2948                 halmac_adapter->halmac_state.scan_state_set.process_status =
2949                         process_status;
2950                 PLATFORM_EVENT_INDICATION(
2951                         driver_adapter, HALMAC_FEATURE_CHANNEL_SWITCH,
2952                         process_status, &halmac_adapter->halmac_state
2953                                                  .scan_state_set.fw_return_code,
2954                         1);
2955         }
2956
2957         return HALMAC_RET_SUCCESS;
2958 }
2959
2960 static enum halmac_ret_status
2961 halmac_parse_h2c_ack_iqk_88xx(struct halmac_adapter *halmac_adapter,
2962                               u8 *c2h_buf, u32 c2h_size)
2963 {
2964         u8 h2c_seq = 0;
2965         u8 h2c_return_code;
2966         void *driver_adapter = halmac_adapter->driver_adapter;
2967         enum halmac_cmd_process_status process_status;
2968
2969         h2c_seq = (u8)H2C_ACK_HDR_GET_H2C_SEQ(c2h_buf);
2970         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2971                         "[TRACE]Seq num : h2c -> %d c2h -> %d\n",
2972                         halmac_adapter->halmac_state.iqk_set.seq_num, h2c_seq);
2973         if (h2c_seq != halmac_adapter->halmac_state.iqk_set.seq_num) {
2974                 pr_err("[ERR]Seq num misactch : h2c -> %d c2h -> %d\n",
2975                        halmac_adapter->halmac_state.iqk_set.seq_num, h2c_seq);
2976                 return HALMAC_RET_SUCCESS;
2977         }
2978
2979         if (halmac_adapter->halmac_state.iqk_set.process_status !=
2980             HALMAC_CMD_PROCESS_SENDING) {
2981                 pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
2982                 return HALMAC_RET_SUCCESS;
2983         }
2984
2985         h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
2986         halmac_adapter->halmac_state.iqk_set.fw_return_code = h2c_return_code;
2987
2988         if ((enum halmac_h2c_return_code)h2c_return_code ==
2989             HALMAC_H2C_RETURN_SUCCESS) {
2990                 process_status = HALMAC_CMD_PROCESS_DONE;
2991                 halmac_adapter->halmac_state.iqk_set.process_status =
2992                         process_status;
2993                 PLATFORM_EVENT_INDICATION(driver_adapter, HALMAC_FEATURE_IQK,
2994                                           process_status, NULL, 0);
2995         } else {
2996                 process_status = HALMAC_CMD_PROCESS_ERROR;
2997                 halmac_adapter->halmac_state.iqk_set.process_status =
2998                         process_status;
2999                 PLATFORM_EVENT_INDICATION(
3000                         driver_adapter, HALMAC_FEATURE_IQK, process_status,
3001                         &halmac_adapter->halmac_state.iqk_set.fw_return_code,
3002                         1);
3003         }
3004
3005         return HALMAC_RET_SUCCESS;
3006 }
3007
3008 static enum halmac_ret_status
3009 halmac_parse_h2c_ack_power_tracking_88xx(struct halmac_adapter *halmac_adapter,
3010                                          u8 *c2h_buf, u32 c2h_size)
3011 {
3012         u8 h2c_seq = 0;
3013         u8 h2c_return_code;
3014         void *driver_adapter = halmac_adapter->driver_adapter;
3015         enum halmac_cmd_process_status process_status;
3016
3017         h2c_seq = (u8)H2C_ACK_HDR_GET_H2C_SEQ(c2h_buf);
3018         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
3019                         "[TRACE]Seq num : h2c -> %d c2h -> %d\n",
3020                         halmac_adapter->halmac_state.power_tracking_set.seq_num,
3021                         h2c_seq);
3022         if (h2c_seq !=
3023             halmac_adapter->halmac_state.power_tracking_set.seq_num) {
3024                 pr_err("[ERR]Seq num mismatch : h2c -> %d c2h -> %d\n",
3025                        halmac_adapter->halmac_state.power_tracking_set.seq_num,
3026                        h2c_seq);
3027                 return HALMAC_RET_SUCCESS;
3028         }
3029
3030         if (halmac_adapter->halmac_state.power_tracking_set.process_status !=
3031             HALMAC_CMD_PROCESS_SENDING) {
3032                 pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
3033                 return HALMAC_RET_SUCCESS;
3034         }
3035
3036         h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
3037         halmac_adapter->halmac_state.power_tracking_set.fw_return_code =
3038                 h2c_return_code;
3039
3040         if ((enum halmac_h2c_return_code)h2c_return_code ==
3041             HALMAC_H2C_RETURN_SUCCESS) {
3042                 process_status = HALMAC_CMD_PROCESS_DONE;
3043                 halmac_adapter->halmac_state.power_tracking_set.process_status =
3044                         process_status;
3045                 PLATFORM_EVENT_INDICATION(driver_adapter,
3046                                           HALMAC_FEATURE_POWER_TRACKING,
3047                                           process_status, NULL, 0);
3048         } else {
3049                 process_status = HALMAC_CMD_PROCESS_ERROR;
3050                 halmac_adapter->halmac_state.power_tracking_set.process_status =
3051                         process_status;
3052                 PLATFORM_EVENT_INDICATION(
3053                         driver_adapter, HALMAC_FEATURE_POWER_TRACKING,
3054                         process_status,
3055                         &halmac_adapter->halmac_state.power_tracking_set
3056                                  .fw_return_code,
3057                         1);
3058         }
3059
3060         return HALMAC_RET_SUCCESS;
3061 }
3062
3063 enum halmac_ret_status
3064 halmac_convert_to_sdio_bus_offset_88xx(struct halmac_adapter *halmac_adapter,
3065                                        u32 *halmac_offset)
3066 {
3067         void *driver_adapter = NULL;
3068
3069         driver_adapter = halmac_adapter->driver_adapter;
3070
3071         switch ((*halmac_offset) & 0xFFFF0000) {
3072         case WLAN_IOREG_OFFSET:
3073                 *halmac_offset = (HALMAC_SDIO_CMD_ADDR_MAC_REG << 13) |
3074                                  (*halmac_offset & HALMAC_WLAN_MAC_REG_MSK);
3075                 break;
3076         case SDIO_LOCAL_OFFSET:
3077                 *halmac_offset = (HALMAC_SDIO_CMD_ADDR_SDIO_REG << 13) |
3078                                  (*halmac_offset & HALMAC_SDIO_LOCAL_MSK);
3079                 break;
3080         default:
3081                 *halmac_offset = 0xFFFFFFFF;
3082                 pr_err("Unknown base address!!\n");
3083                 return HALMAC_RET_CONVERT_SDIO_OFFSET_FAIL;
3084         }
3085
3086         return HALMAC_RET_SUCCESS;
3087 }
3088
3089 enum halmac_ret_status
3090 halmac_update_sdio_free_page_88xx(struct halmac_adapter *halmac_adapter)
3091 {
3092         u32 free_page = 0, free_page2 = 0, free_page3 = 0;
3093         void *driver_adapter = NULL;
3094         struct halmac_api *halmac_api;
3095         struct halmac_sdio_free_space *sdio_free_space;
3096         u8 data[12] = {0};
3097
3098         driver_adapter = halmac_adapter->driver_adapter;
3099         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3100
3101         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
3102                         "%s ==========>\n", __func__);
3103
3104         sdio_free_space = &halmac_adapter->sdio_free_space;
3105         /*need to use HALMAC_REG_READ_N, 20160316, Soar*/
3106         HALMAC_REG_SDIO_CMD53_READ_N(halmac_adapter, REG_SDIO_FREE_TXPG, 12,
3107                                      data);
3108         free_page =
3109                 data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
3110         free_page2 =
3111                 data[4] | (data[5] << 8) | (data[6] << 16) | (data[7] << 24);
3112         free_page3 =
3113                 data[8] | (data[9] << 8) | (data[10] << 16) | (data[11] << 24);
3114
3115         sdio_free_space->high_queue_number =
3116                 (u16)BIT_GET_HIQ_FREEPG_V1(free_page);
3117         sdio_free_space->normal_queue_number =
3118                 (u16)BIT_GET_MID_FREEPG_V1(free_page);
3119         sdio_free_space->low_queue_number =
3120                 (u16)BIT_GET_LOW_FREEPG_V1(free_page2);
3121         sdio_free_space->public_queue_number =
3122                 (u16)BIT_GET_PUB_FREEPG_V1(free_page2);
3123         sdio_free_space->extra_queue_number =
3124                 (u16)BIT_GET_EXQ_FREEPG_V1(free_page3);
3125         sdio_free_space->ac_oqt_number = (u8)((free_page3 >> 16) & 0xFF);
3126         sdio_free_space->non_ac_oqt_number = (u8)((free_page3 >> 24) & 0xFF);
3127
3128         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
3129                         "%s <==========\n", __func__);
3130
3131         return HALMAC_RET_SUCCESS;
3132 }
3133
3134 enum halmac_ret_status
3135 halmac_update_oqt_free_space_88xx(struct halmac_adapter *halmac_adapter)
3136 {
3137         void *driver_adapter = NULL;
3138         struct halmac_api *halmac_api;
3139         struct halmac_sdio_free_space *sdio_free_space;
3140
3141         driver_adapter = halmac_adapter->driver_adapter;
3142         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3143
3144         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
3145                         "%s ==========>\n", __func__);
3146
3147         sdio_free_space = &halmac_adapter->sdio_free_space;
3148
3149         sdio_free_space->ac_oqt_number = HALMAC_REG_READ_8(
3150                 halmac_adapter, REG_SDIO_OQT_FREE_TXPG_V1 + 2);
3151         sdio_free_space->ac_empty =
3152                 HALMAC_REG_READ_8(halmac_adapter, REG_TXPKT_EMPTY);
3153
3154         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
3155                         "%s <==========\n", __func__);
3156
3157         return HALMAC_RET_SUCCESS;
3158 }
3159
3160 enum halmac_efuse_cmd_construct_state
3161 halmac_query_efuse_curr_state_88xx(struct halmac_adapter *halmac_adapter)
3162 {
3163         return halmac_adapter->halmac_state.efuse_state_set
3164                 .efuse_cmd_construct_state;
3165 }
3166
3167 enum halmac_ret_status halmac_transition_efuse_state_88xx(
3168         struct halmac_adapter *halmac_adapter,
3169         enum halmac_efuse_cmd_construct_state dest_state)
3170 {
3171         struct halmac_efuse_state_set *efuse_state =
3172                 &halmac_adapter->halmac_state.efuse_state_set;
3173
3174         if (efuse_state->efuse_cmd_construct_state !=
3175                     HALMAC_EFUSE_CMD_CONSTRUCT_IDLE &&
3176             efuse_state->efuse_cmd_construct_state !=
3177                     HALMAC_EFUSE_CMD_CONSTRUCT_BUSY &&
3178             efuse_state->efuse_cmd_construct_state !=
3179                     HALMAC_EFUSE_CMD_CONSTRUCT_H2C_SENT)
3180                 return HALMAC_RET_ERROR_STATE;
3181
3182         if (efuse_state->efuse_cmd_construct_state == dest_state)
3183                 return HALMAC_RET_ERROR_STATE;
3184
3185         if (dest_state == HALMAC_EFUSE_CMD_CONSTRUCT_BUSY) {
3186                 if (efuse_state->efuse_cmd_construct_state ==
3187                     HALMAC_EFUSE_CMD_CONSTRUCT_H2C_SENT)
3188                         return HALMAC_RET_ERROR_STATE;
3189         } else if (dest_state == HALMAC_EFUSE_CMD_CONSTRUCT_H2C_SENT) {
3190                 if (efuse_state->efuse_cmd_construct_state ==
3191                     HALMAC_EFUSE_CMD_CONSTRUCT_IDLE)
3192                         return HALMAC_RET_ERROR_STATE;
3193         }
3194
3195         efuse_state->efuse_cmd_construct_state = dest_state;
3196
3197         return HALMAC_RET_SUCCESS;
3198 }
3199
3200 enum halmac_cfg_para_cmd_construct_state
3201 halmac_query_cfg_para_curr_state_88xx(struct halmac_adapter *halmac_adapter)
3202 {
3203         return halmac_adapter->halmac_state.cfg_para_state_set
3204                 .cfg_para_cmd_construct_state;
3205 }
3206
3207 enum halmac_ret_status halmac_transition_cfg_para_state_88xx(
3208         struct halmac_adapter *halmac_adapter,
3209         enum halmac_cfg_para_cmd_construct_state dest_state)
3210 {
3211         struct halmac_cfg_para_state_set *cfg_para =
3212                 &halmac_adapter->halmac_state.cfg_para_state_set;
3213
3214         if (cfg_para->cfg_para_cmd_construct_state !=
3215                     HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE &&
3216             cfg_para->cfg_para_cmd_construct_state !=
3217                     HALMAC_CFG_PARA_CMD_CONSTRUCT_CONSTRUCTING &&
3218             cfg_para->cfg_para_cmd_construct_state !=
3219                     HALMAC_CFG_PARA_CMD_CONSTRUCT_H2C_SENT)
3220                 return HALMAC_RET_ERROR_STATE;
3221
3222         if (dest_state == HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE) {
3223                 if (cfg_para->cfg_para_cmd_construct_state ==
3224                     HALMAC_CFG_PARA_CMD_CONSTRUCT_CONSTRUCTING)
3225                         return HALMAC_RET_ERROR_STATE;
3226         } else if (dest_state == HALMAC_CFG_PARA_CMD_CONSTRUCT_CONSTRUCTING) {
3227                 if (cfg_para->cfg_para_cmd_construct_state ==
3228                     HALMAC_CFG_PARA_CMD_CONSTRUCT_H2C_SENT)
3229                         return HALMAC_RET_ERROR_STATE;
3230         } else if (dest_state == HALMAC_CFG_PARA_CMD_CONSTRUCT_H2C_SENT) {
3231                 if (cfg_para->cfg_para_cmd_construct_state ==
3232                             HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE ||
3233                     cfg_para->cfg_para_cmd_construct_state ==
3234                             HALMAC_CFG_PARA_CMD_CONSTRUCT_H2C_SENT)
3235                         return HALMAC_RET_ERROR_STATE;
3236         }
3237
3238         cfg_para->cfg_para_cmd_construct_state = dest_state;
3239
3240         return HALMAC_RET_SUCCESS;
3241 }
3242
3243 enum halmac_scan_cmd_construct_state
3244 halmac_query_scan_curr_state_88xx(struct halmac_adapter *halmac_adapter)
3245 {
3246         return halmac_adapter->halmac_state.scan_state_set
3247                 .scan_cmd_construct_state;
3248 }
3249
3250 enum halmac_ret_status halmac_transition_scan_state_88xx(
3251         struct halmac_adapter *halmac_adapter,
3252         enum halmac_scan_cmd_construct_state dest_state)
3253 {
3254         struct halmac_scan_state_set *scan =
3255                 &halmac_adapter->halmac_state.scan_state_set;
3256
3257         if (scan->scan_cmd_construct_state > HALMAC_SCAN_CMD_CONSTRUCT_H2C_SENT)
3258                 return HALMAC_RET_ERROR_STATE;
3259
3260         if (dest_state == HALMAC_SCAN_CMD_CONSTRUCT_IDLE) {
3261                 if (scan->scan_cmd_construct_state ==
3262                             HALMAC_SCAN_CMD_CONSTRUCT_BUFFER_CLEARED ||
3263                     scan->scan_cmd_construct_state ==
3264                             HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING)
3265                         return HALMAC_RET_ERROR_STATE;
3266         } else if (dest_state == HALMAC_SCAN_CMD_CONSTRUCT_BUFFER_CLEARED) {
3267                 if (scan->scan_cmd_construct_state ==
3268                     HALMAC_SCAN_CMD_CONSTRUCT_H2C_SENT)
3269                         return HALMAC_RET_ERROR_STATE;
3270         } else if (dest_state == HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING) {
3271                 if (scan->scan_cmd_construct_state ==
3272                             HALMAC_SCAN_CMD_CONSTRUCT_IDLE ||
3273                     scan->scan_cmd_construct_state ==
3274                             HALMAC_SCAN_CMD_CONSTRUCT_H2C_SENT)
3275                         return HALMAC_RET_ERROR_STATE;
3276         } else if (dest_state == HALMAC_SCAN_CMD_CONSTRUCT_H2C_SENT) {
3277                 if (scan->scan_cmd_construct_state !=
3278                             HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING &&
3279                     scan->scan_cmd_construct_state !=
3280                             HALMAC_SCAN_CMD_CONSTRUCT_BUFFER_CLEARED)
3281                         return HALMAC_RET_ERROR_STATE;
3282         }
3283
3284         scan->scan_cmd_construct_state = dest_state;
3285
3286         return HALMAC_RET_SUCCESS;
3287 }
3288
3289 enum halmac_ret_status halmac_query_cfg_para_status_88xx(
3290         struct halmac_adapter *halmac_adapter,
3291         enum halmac_cmd_process_status *process_status, u8 *data, u32 *size)
3292 {
3293         struct halmac_cfg_para_state_set *cfg_para_state_set =
3294                 &halmac_adapter->halmac_state.cfg_para_state_set;
3295
3296         *process_status = cfg_para_state_set->process_status;
3297
3298         return HALMAC_RET_SUCCESS;
3299 }
3300
3301 enum halmac_ret_status halmac_query_dump_physical_efuse_status_88xx(
3302         struct halmac_adapter *halmac_adapter,
3303         enum halmac_cmd_process_status *process_status, u8 *data, u32 *size)
3304 {
3305         void *driver_adapter = NULL;
3306         struct halmac_efuse_state_set *efuse_state_set =
3307                 &halmac_adapter->halmac_state.efuse_state_set;
3308
3309         driver_adapter = halmac_adapter->driver_adapter;
3310
3311         *process_status = efuse_state_set->process_status;
3312
3313         if (!data)
3314                 return HALMAC_RET_NULL_POINTER;
3315
3316         if (!size)
3317                 return HALMAC_RET_NULL_POINTER;
3318
3319         if (*process_status == HALMAC_CMD_PROCESS_DONE) {
3320                 if (*size < halmac_adapter->hw_config_info.efuse_size) {
3321                         *size = halmac_adapter->hw_config_info.efuse_size;
3322                         return HALMAC_RET_BUFFER_TOO_SMALL;
3323                 }
3324
3325                 *size = halmac_adapter->hw_config_info.efuse_size;
3326                 memcpy(data, halmac_adapter->hal_efuse_map, *size);
3327         }
3328
3329         return HALMAC_RET_SUCCESS;
3330 }
3331
3332 enum halmac_ret_status halmac_query_dump_logical_efuse_status_88xx(
3333         struct halmac_adapter *halmac_adapter,
3334         enum halmac_cmd_process_status *process_status, u8 *data, u32 *size)
3335 {
3336         u8 *eeprom_map = NULL;
3337         u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
3338         void *driver_adapter = NULL;
3339         struct halmac_efuse_state_set *efuse_state_set =
3340                 &halmac_adapter->halmac_state.efuse_state_set;
3341
3342         driver_adapter = halmac_adapter->driver_adapter;
3343
3344         *process_status = efuse_state_set->process_status;
3345
3346         if (!data)
3347                 return HALMAC_RET_NULL_POINTER;
3348
3349         if (!size)
3350                 return HALMAC_RET_NULL_POINTER;
3351
3352         if (*process_status == HALMAC_CMD_PROCESS_DONE) {
3353                 if (*size < eeprom_size) {
3354                         *size = eeprom_size;
3355                         return HALMAC_RET_BUFFER_TOO_SMALL;
3356                 }
3357
3358                 *size = eeprom_size;
3359
3360                 eeprom_map = kzalloc(eeprom_size, GFP_KERNEL);
3361                 if (!eeprom_map) {
3362                         /* out of memory */
3363                         return HALMAC_RET_MALLOC_FAIL;
3364                 }
3365                 memset(eeprom_map, 0xFF, eeprom_size);
3366
3367                 if (halmac_eeprom_parser_88xx(
3368                             halmac_adapter, halmac_adapter->hal_efuse_map,
3369                             eeprom_map) != HALMAC_RET_SUCCESS) {
3370                         kfree(eeprom_map);
3371                         return HALMAC_RET_EEPROM_PARSING_FAIL;
3372                 }
3373
3374                 memcpy(data, eeprom_map, *size);
3375
3376                 kfree(eeprom_map);
3377         }
3378
3379         return HALMAC_RET_SUCCESS;
3380 }
3381
3382 enum halmac_ret_status halmac_query_channel_switch_status_88xx(
3383         struct halmac_adapter *halmac_adapter,
3384         enum halmac_cmd_process_status *process_status, u8 *data, u32 *size)
3385 {
3386         struct halmac_scan_state_set *scan_state_set =
3387                 &halmac_adapter->halmac_state.scan_state_set;
3388
3389         *process_status = scan_state_set->process_status;
3390
3391         return HALMAC_RET_SUCCESS;
3392 }
3393
3394 enum halmac_ret_status halmac_query_update_packet_status_88xx(
3395         struct halmac_adapter *halmac_adapter,
3396         enum halmac_cmd_process_status *process_status, u8 *data, u32 *size)
3397 {
3398         struct halmac_update_packet_state_set *update_packet_set =
3399                 &halmac_adapter->halmac_state.update_packet_set;
3400
3401         *process_status = update_packet_set->process_status;
3402
3403         return HALMAC_RET_SUCCESS;
3404 }
3405
3406 enum halmac_ret_status
3407 halmac_query_iqk_status_88xx(struct halmac_adapter *halmac_adapter,
3408                              enum halmac_cmd_process_status *process_status,
3409                              u8 *data, u32 *size)
3410 {
3411         struct halmac_iqk_state_set *iqk_set =
3412                 &halmac_adapter->halmac_state.iqk_set;
3413
3414         *process_status = iqk_set->process_status;
3415
3416         return HALMAC_RET_SUCCESS;
3417 }
3418
3419 enum halmac_ret_status halmac_query_power_tracking_status_88xx(
3420         struct halmac_adapter *halmac_adapter,
3421         enum halmac_cmd_process_status *process_status, u8 *data, u32 *size)
3422 {
3423         struct halmac_power_tracking_state_set *power_tracking_state_set =
3424                 &halmac_adapter->halmac_state.power_tracking_set;
3425         ;
3426
3427         *process_status = power_tracking_state_set->process_status;
3428
3429         return HALMAC_RET_SUCCESS;
3430 }
3431
3432 enum halmac_ret_status
3433 halmac_query_psd_status_88xx(struct halmac_adapter *halmac_adapter,
3434                              enum halmac_cmd_process_status *process_status,
3435                              u8 *data, u32 *size)
3436 {
3437         void *driver_adapter = NULL;
3438         struct halmac_psd_state_set *psd_set =
3439                 &halmac_adapter->halmac_state.psd_set;
3440
3441         driver_adapter = halmac_adapter->driver_adapter;
3442
3443         *process_status = psd_set->process_status;
3444
3445         if (!data)
3446                 return HALMAC_RET_NULL_POINTER;
3447
3448         if (!size)
3449                 return HALMAC_RET_NULL_POINTER;
3450
3451         if (*process_status == HALMAC_CMD_PROCESS_DONE) {
3452                 if (*size < psd_set->data_size) {
3453                         *size = psd_set->data_size;
3454                         return HALMAC_RET_BUFFER_TOO_SMALL;
3455                 }
3456
3457                 *size = psd_set->data_size;
3458                 memcpy(data, psd_set->data, *size);
3459         }
3460
3461         return HALMAC_RET_SUCCESS;
3462 }
3463
3464 enum halmac_ret_status
3465 halmac_verify_io_88xx(struct halmac_adapter *halmac_adapter)
3466 {
3467         u8 value8, wvalue8;
3468         u32 value32, value32_2, wvalue32;
3469         u32 halmac_offset;
3470         void *driver_adapter = NULL;
3471         enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
3472
3473         driver_adapter = halmac_adapter->driver_adapter;
3474
3475         if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
3476                 halmac_offset = REG_PAGE5_DUMMY;
3477                 if ((halmac_offset & 0xFFFF0000) == 0)
3478                         halmac_offset |= WLAN_IOREG_OFFSET;
3479
3480                 ret_status = halmac_convert_to_sdio_bus_offset_88xx(
3481                         halmac_adapter, &halmac_offset);
3482
3483                 /* Verify CMD52 R/W */
3484                 wvalue8 = 0xab;
3485                 PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset,
3486                                           wvalue8);
3487
3488                 value8 =
3489                         PLATFORM_SDIO_CMD52_READ(driver_adapter, halmac_offset);
3490
3491                 if (value8 != wvalue8) {
3492                         pr_err("cmd52 r/w fail write = %X read = %X\n", wvalue8,
3493                                value8);
3494                         ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
3495                 } else {
3496                         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
3497                                         DBG_DMESG, "cmd52 r/w ok\n");
3498                 }
3499
3500                 /* Verify CMD53 R/W */
3501                 PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset, 0xaa);
3502                 PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset + 1,
3503                                           0xbb);
3504                 PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset + 2,
3505                                           0xcc);
3506                 PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset + 3,
3507                                           0xdd);
3508
3509                 value32 = PLATFORM_SDIO_CMD53_READ_32(driver_adapter,
3510                                                       halmac_offset);
3511
3512                 if (value32 != 0xddccbbaa) {
3513                         pr_err("cmd53 r fail : read = %X\n", value32);
3514                         ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
3515                 } else {
3516                         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
3517                                         DBG_DMESG, "cmd53 r ok\n");
3518                 }
3519
3520                 wvalue32 = 0x11223344;
3521                 PLATFORM_SDIO_CMD53_WRITE_32(driver_adapter, halmac_offset,
3522                                              wvalue32);
3523
3524                 value32 = PLATFORM_SDIO_CMD53_READ_32(driver_adapter,
3525                                                       halmac_offset);
3526
3527                 if (value32 != wvalue32) {
3528                         pr_err("cmd53 w fail\n");
3529                         ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
3530                 } else {
3531                         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
3532                                         DBG_DMESG, "cmd53 w ok\n");
3533                 }
3534
3535                 value32 = PLATFORM_SDIO_CMD53_READ_32(
3536                         driver_adapter,
3537                         halmac_offset + 2); /* value32 should be 0x33441122 */
3538
3539                 wvalue32 = 0x11225566;
3540                 PLATFORM_SDIO_CMD53_WRITE_32(driver_adapter, halmac_offset,
3541                                              wvalue32);
3542
3543                 value32_2 = PLATFORM_SDIO_CMD53_READ_32(
3544                         driver_adapter,
3545                         halmac_offset + 2); /* value32 should be 0x55661122 */
3546                 if (value32_2 == value32) {
3547                         pr_err("cmd52 is used for HAL_SDIO_CMD53_READ_32\n");
3548                         ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
3549                 } else {
3550                         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
3551                                         DBG_DMESG, "cmd53 is correctly used\n");
3552                 }
3553         } else {
3554                 wvalue32 = 0x77665511;
3555                 PLATFORM_REG_WRITE_32(driver_adapter, REG_PAGE5_DUMMY,
3556                                       wvalue32);
3557
3558                 value32 = PLATFORM_REG_READ_32(driver_adapter, REG_PAGE5_DUMMY);
3559                 if (value32 != wvalue32) {
3560                         pr_err("reg rw\n");
3561                         ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
3562                 } else {
3563                         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
3564                                         DBG_DMESG, "reg rw ok\n");
3565                 }
3566         }
3567
3568         return ret_status;
3569 }
3570
3571 enum halmac_ret_status
3572 halmac_verify_send_rsvd_page_88xx(struct halmac_adapter *halmac_adapter)
3573 {
3574         u8 *rsvd_buf = NULL;
3575         u8 *rsvd_page = NULL;
3576         u32 i;
3577         u32 h2c_pkt_verify_size = 64, h2c_pkt_verify_payload = 0xab;
3578         void *driver_adapter = NULL;
3579         enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
3580
3581         driver_adapter = halmac_adapter->driver_adapter;
3582
3583         rsvd_buf = kzalloc(h2c_pkt_verify_size, GFP_KERNEL);
3584
3585         if (!rsvd_buf) {
3586                 /*pr_err("[ERR]rsvd buffer malloc fail!!\n");*/
3587                 return HALMAC_RET_MALLOC_FAIL;
3588         }
3589
3590         memset(rsvd_buf, (u8)h2c_pkt_verify_payload, h2c_pkt_verify_size);
3591
3592         ret_status = halmac_download_rsvd_page_88xx(halmac_adapter, rsvd_buf,
3593                                                     h2c_pkt_verify_size);
3594
3595         if (ret_status != HALMAC_RET_SUCCESS) {
3596                 kfree(rsvd_buf);
3597                 return ret_status;
3598         }
3599
3600         rsvd_page = kzalloc(h2c_pkt_verify_size +
3601                                     halmac_adapter->hw_config_info.txdesc_size,
3602                             GFP_KERNEL);
3603
3604         if (!rsvd_page) {
3605                 pr_err("[ERR]rsvd page malloc fail!!\n");
3606                 kfree(rsvd_buf);
3607                 return HALMAC_RET_MALLOC_FAIL;
3608         }
3609
3610         ret_status = halmac_dump_fifo_88xx(
3611                 halmac_adapter, HAL_FIFO_SEL_RSVD_PAGE, 0,
3612                 h2c_pkt_verify_size +
3613                         halmac_adapter->hw_config_info.txdesc_size,
3614                 rsvd_page);
3615
3616         if (ret_status != HALMAC_RET_SUCCESS) {
3617                 kfree(rsvd_buf);
3618                 kfree(rsvd_page);
3619                 return ret_status;
3620         }
3621
3622         for (i = 0; i < h2c_pkt_verify_size; i++) {
3623                 if (*(rsvd_buf + i) !=
3624                     *(rsvd_page +
3625                       (i + halmac_adapter->hw_config_info.txdesc_size))) {
3626                         pr_err("[ERR]Compare RSVD page Fail\n");
3627                         ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
3628                 }
3629         }
3630
3631         kfree(rsvd_buf);
3632         kfree(rsvd_page);
3633
3634         return ret_status;
3635 }
3636
3637 void halmac_power_save_cb_88xx(void *cb_data)
3638 {
3639         void *driver_adapter = NULL;
3640         struct halmac_adapter *halmac_adapter = (struct halmac_adapter *)NULL;
3641
3642         halmac_adapter = (struct halmac_adapter *)cb_data;
3643         driver_adapter = halmac_adapter->driver_adapter;
3644
3645         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
3646                         "%s\n", __func__);
3647 }
3648
3649 enum halmac_ret_status
3650 halmac_buffer_read_88xx(struct halmac_adapter *halmac_adapter, u32 offset,
3651                         u32 size, enum hal_fifo_sel halmac_fifo_sel,
3652                         u8 *fifo_map)
3653 {
3654         u32 start_page, value_read;
3655         u32 i, counter = 0, residue;
3656         struct halmac_api *halmac_api;
3657
3658         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3659
3660         if (halmac_fifo_sel == HAL_FIFO_SEL_RSVD_PAGE)
3661                 offset = offset +
3662                          (halmac_adapter->txff_allocation.rsvd_pg_bndy << 7);
3663
3664         start_page = offset >> 12;
3665         residue = offset & (4096 - 1);
3666
3667         if (halmac_fifo_sel == HAL_FIFO_SEL_TX ||
3668             halmac_fifo_sel == HAL_FIFO_SEL_RSVD_PAGE)
3669                 start_page += 0x780;
3670         else if (halmac_fifo_sel == HAL_FIFO_SEL_RX)
3671                 start_page += 0x700;
3672         else if (halmac_fifo_sel == HAL_FIFO_SEL_REPORT)
3673                 start_page += 0x660;
3674         else if (halmac_fifo_sel == HAL_FIFO_SEL_LLT)
3675                 start_page += 0x650;
3676         else
3677                 return HALMAC_RET_NOT_SUPPORT;
3678
3679         value_read = HALMAC_REG_READ_16(halmac_adapter, REG_PKTBUF_DBG_CTRL);
3680
3681         do {
3682                 HALMAC_REG_WRITE_16(halmac_adapter, REG_PKTBUF_DBG_CTRL,
3683                                     (u16)(start_page | (value_read & 0xF000)));
3684
3685                 for (i = 0x8000 + residue; i <= 0x8FFF; i += 4) {
3686                         *(u32 *)(fifo_map + counter) =
3687                                 HALMAC_REG_READ_32(halmac_adapter, i);
3688                         *(u32 *)(fifo_map + counter) =
3689                                 le32_to_cpu(*(__le32 *)(fifo_map + counter));
3690                         counter += 4;
3691                         if (size == counter)
3692                                 goto HALMAC_BUF_READ_OK;
3693                 }
3694
3695                 residue = 0;
3696                 start_page++;
3697         } while (1);
3698
3699 HALMAC_BUF_READ_OK:
3700         HALMAC_REG_WRITE_16(halmac_adapter, REG_PKTBUF_DBG_CTRL,
3701                             (u16)value_read);
3702
3703         return HALMAC_RET_SUCCESS;
3704 }
3705
3706 void halmac_restore_mac_register_88xx(struct halmac_adapter *halmac_adapter,
3707                                       struct halmac_restore_info *restore_info,
3708                                       u32 restore_num)
3709 {
3710         u8 value_length;
3711         u32 i;
3712         u32 mac_register;
3713         u32 mac_value;
3714         struct halmac_api *halmac_api;
3715         struct halmac_restore_info *curr_restore_info = restore_info;
3716
3717         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3718
3719         for (i = 0; i < restore_num; i++) {
3720                 mac_register = curr_restore_info->mac_register;
3721                 mac_value = curr_restore_info->value;
3722                 value_length = curr_restore_info->length;
3723
3724                 if (value_length == 1)
3725                         HALMAC_REG_WRITE_8(halmac_adapter, mac_register,
3726                                            (u8)mac_value);
3727                 else if (value_length == 2)
3728                         HALMAC_REG_WRITE_16(halmac_adapter, mac_register,
3729                                             (u16)mac_value);
3730                 else if (value_length == 4)
3731                         HALMAC_REG_WRITE_32(halmac_adapter, mac_register,
3732                                             mac_value);
3733
3734                 curr_restore_info++;
3735         }
3736 }
3737
3738 void halmac_api_record_id_88xx(struct halmac_adapter *halmac_adapter,
3739                                enum halmac_api_id api_id)
3740 {
3741 }
3742
3743 enum halmac_ret_status
3744 halmac_set_usb_mode_88xx(struct halmac_adapter *halmac_adapter,
3745                          enum halmac_usb_mode usb_mode)
3746 {
3747         u32 usb_temp;
3748         void *driver_adapter = NULL;
3749         struct halmac_api *halmac_api;
3750         enum halmac_usb_mode current_usb_mode;
3751
3752         driver_adapter = halmac_adapter->driver_adapter;
3753         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3754
3755         current_usb_mode =
3756                 HALMAC_REG_READ_8(halmac_adapter, REG_SYS_CFG2 + 3) == 0x20 ?
3757                         HALMAC_USB_MODE_U3 :
3758                         HALMAC_USB_MODE_U2;
3759
3760         /*check if HW supports usb2_usb3 swtich*/
3761         usb_temp = HALMAC_REG_READ_32(halmac_adapter, REG_PAD_CTRL2);
3762         if (!BIT_GET_USB23_SW_MODE_V1(usb_temp) &&
3763             !(usb_temp & BIT_USB3_USB2_TRANSITION)) {
3764                 pr_err("HALMAC_HW_USB_MODE usb mode HW unsupport\n");
3765                 return HALMAC_RET_USB2_3_SWITCH_UNSUPPORT;
3766         }
3767
3768         if (usb_mode == current_usb_mode) {
3769                 pr_err("HALMAC_HW_USB_MODE usb mode unchange\n");
3770                 return HALMAC_RET_USB_MODE_UNCHANGE;
3771         }
3772
3773         usb_temp &= ~(BIT_USB23_SW_MODE_V1(0x3));
3774
3775         if (usb_mode == HALMAC_USB_MODE_U2) {
3776                 /* usb3 to usb2 */
3777                 HALMAC_REG_WRITE_32(
3778                         halmac_adapter, REG_PAD_CTRL2,
3779                         usb_temp | BIT_USB23_SW_MODE_V1(HALMAC_USB_MODE_U2) |
3780                                 BIT_RSM_EN_V1);
3781         } else {
3782                 /* usb2 to usb3 */
3783                 HALMAC_REG_WRITE_32(
3784                         halmac_adapter, REG_PAD_CTRL2,
3785                         usb_temp | BIT_USB23_SW_MODE_V1(HALMAC_USB_MODE_U3) |
3786                                 BIT_RSM_EN_V1);
3787         }
3788
3789         HALMAC_REG_WRITE_8(halmac_adapter, REG_PAD_CTRL2 + 1,
3790                            4); /* set counter down timer 4x64 ms */
3791         HALMAC_REG_WRITE_16(
3792                 halmac_adapter, REG_SYS_PW_CTRL,
3793                 HALMAC_REG_READ_16(halmac_adapter, REG_SYS_PW_CTRL) |
3794                         BIT_APFM_OFFMAC);
3795         usleep_range(1000, 1100);
3796         HALMAC_REG_WRITE_32(halmac_adapter, REG_PAD_CTRL2,
3797                             HALMAC_REG_READ_32(halmac_adapter, REG_PAD_CTRL2) |
3798                                     BIT_NO_PDN_CHIPOFF_V1);
3799
3800         return HALMAC_RET_SUCCESS;
3801 }
3802
3803 void halmac_enable_bb_rf_88xx(struct halmac_adapter *halmac_adapter, u8 enable)
3804 {
3805         u8 value8;
3806         u32 value32;
3807         struct halmac_api *halmac_api;
3808
3809         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3810
3811         if (enable == 1) {
3812                 value8 = HALMAC_REG_READ_8(halmac_adapter, REG_SYS_FUNC_EN);
3813                 value8 = value8 | BIT(0) | BIT(1);
3814                 HALMAC_REG_WRITE_8(halmac_adapter, REG_SYS_FUNC_EN, value8);
3815
3816                 value8 = HALMAC_REG_READ_8(halmac_adapter, REG_RF_CTRL);
3817                 value8 = value8 | BIT(0) | BIT(1) | BIT(2);
3818                 HALMAC_REG_WRITE_8(halmac_adapter, REG_RF_CTRL, value8);
3819
3820                 value32 = HALMAC_REG_READ_32(halmac_adapter, REG_WLRF1);
3821                 value32 = value32 | BIT(24) | BIT(25) | BIT(26);
3822                 HALMAC_REG_WRITE_32(halmac_adapter, REG_WLRF1, value32);
3823         } else {
3824                 value8 = HALMAC_REG_READ_8(halmac_adapter, REG_SYS_FUNC_EN);
3825                 value8 = value8 & (~(BIT(0) | BIT(1)));
3826                 HALMAC_REG_WRITE_8(halmac_adapter, REG_SYS_FUNC_EN, value8);
3827
3828                 value8 = HALMAC_REG_READ_8(halmac_adapter, REG_RF_CTRL);
3829                 value8 = value8 & (~(BIT(0) | BIT(1) | BIT(2)));
3830                 HALMAC_REG_WRITE_8(halmac_adapter, REG_RF_CTRL, value8);
3831
3832                 value32 = HALMAC_REG_READ_32(halmac_adapter, REG_WLRF1);
3833                 value32 = value32 & (~(BIT(24) | BIT(25) | BIT(26)));
3834                 HALMAC_REG_WRITE_32(halmac_adapter, REG_WLRF1, value32);
3835         }
3836 }
3837
3838 void halmac_config_sdio_tx_page_threshold_88xx(
3839         struct halmac_adapter *halmac_adapter,
3840         struct halmac_tx_page_threshold_info *threshold_info)
3841 {
3842         struct halmac_api *halmac_api;
3843
3844         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3845
3846         switch (threshold_info->dma_queue_sel) {
3847         case HALMAC_MAP2_HQ:
3848                 HALMAC_REG_WRITE_32(halmac_adapter, REG_TQPNT1,
3849                                     threshold_info->threshold);
3850                 break;
3851         case HALMAC_MAP2_NQ:
3852                 HALMAC_REG_WRITE_32(halmac_adapter, REG_TQPNT2,
3853                                     threshold_info->threshold);
3854                 break;
3855         case HALMAC_MAP2_LQ:
3856                 HALMAC_REG_WRITE_32(halmac_adapter, REG_TQPNT3,
3857                                     threshold_info->threshold);
3858                 break;
3859         case HALMAC_MAP2_EXQ:
3860                 HALMAC_REG_WRITE_32(halmac_adapter, REG_TQPNT4,
3861                                     threshold_info->threshold);
3862                 break;
3863         default:
3864                 break;
3865         }
3866 }
3867
3868 void halmac_config_ampdu_88xx(struct halmac_adapter *halmac_adapter,
3869                               struct halmac_ampdu_config *ampdu_config)
3870 {
3871         struct halmac_api *halmac_api;
3872
3873         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3874
3875         HALMAC_REG_WRITE_8(halmac_adapter, REG_PROT_MODE_CTRL + 2,
3876                            ampdu_config->max_agg_num);
3877         HALMAC_REG_WRITE_8(halmac_adapter, REG_PROT_MODE_CTRL + 3,
3878                            ampdu_config->max_agg_num);
3879 };
3880
3881 enum halmac_ret_status
3882 halmac_check_oqt_88xx(struct halmac_adapter *halmac_adapter, u32 tx_agg_num,
3883                       u8 *halmac_buf)
3884 {
3885         u32 counter = 10;
3886
3887         /*S0, S1 are not allowed to use, 0x4E4[0] should be 0. Soar 20160323*/
3888         /*no need to check non_ac_oqt_number. HI and MGQ blocked will cause
3889          *protocal issue before H_OQT being full
3890          */
3891         switch ((enum halmac_queue_select)GET_TX_DESC_QSEL(halmac_buf)) {
3892         case HALMAC_QUEUE_SELECT_VO:
3893         case HALMAC_QUEUE_SELECT_VO_V2:
3894         case HALMAC_QUEUE_SELECT_VI:
3895         case HALMAC_QUEUE_SELECT_VI_V2:
3896         case HALMAC_QUEUE_SELECT_BE:
3897         case HALMAC_QUEUE_SELECT_BE_V2:
3898         case HALMAC_QUEUE_SELECT_BK:
3899         case HALMAC_QUEUE_SELECT_BK_V2:
3900                 counter = 10;
3901                 do {
3902                         if (halmac_adapter->sdio_free_space.ac_empty > 0) {
3903                                 halmac_adapter->sdio_free_space.ac_empty -= 1;
3904                                 break;
3905                         }
3906
3907                         if (halmac_adapter->sdio_free_space.ac_oqt_number >=
3908                             tx_agg_num) {
3909                                 halmac_adapter->sdio_free_space.ac_oqt_number -=
3910                                         (u8)tx_agg_num;
3911                                 break;
3912                         }
3913
3914                         halmac_update_oqt_free_space_88xx(halmac_adapter);
3915
3916                         counter--;
3917                         if (counter == 0)
3918                                 return HALMAC_RET_OQT_NOT_ENOUGH;
3919                 } while (1);
3920                 break;
3921         default:
3922                 break;
3923         }
3924
3925         return HALMAC_RET_SUCCESS;
3926 }
3927
3928 enum halmac_ret_status
3929 halmac_rqpn_parser_88xx(struct halmac_adapter *halmac_adapter,
3930                         enum halmac_trx_mode halmac_trx_mode,
3931                         struct halmac_rqpn_ *rqpn_table)
3932 {
3933         u8 search_flag;
3934         u32 i;
3935         void *driver_adapter = NULL;
3936         struct halmac_api *halmac_api;
3937
3938         driver_adapter = halmac_adapter->driver_adapter;
3939         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3940
3941         search_flag = 0;
3942         for (i = 0; i < HALMAC_TRX_MODE_MAX; i++) {
3943                 if (halmac_trx_mode == rqpn_table[i].mode) {
3944                         halmac_adapter
3945                                 ->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VO] =
3946                                 rqpn_table[i].dma_map_vo;
3947                         halmac_adapter
3948                                 ->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VI] =
3949                                 rqpn_table[i].dma_map_vi;
3950                         halmac_adapter
3951                                 ->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BE] =
3952                                 rqpn_table[i].dma_map_be;
3953                         halmac_adapter
3954                                 ->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BK] =
3955                                 rqpn_table[i].dma_map_bk;
3956                         halmac_adapter
3957                                 ->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_MG] =
3958                                 rqpn_table[i].dma_map_mg;
3959                         halmac_adapter
3960                                 ->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_HI] =
3961                                 rqpn_table[i].dma_map_hi;
3962                         search_flag = 1;
3963                         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
3964                                         DBG_DMESG, "%s done\n", __func__);
3965                         break;
3966                 }
3967         }
3968
3969         if (search_flag == 0) {
3970                 pr_err("HALMAC_RET_TRX_MODE_NOT_SUPPORT 1 switch case not support\n");
3971                 return HALMAC_RET_TRX_MODE_NOT_SUPPORT;
3972         }
3973
3974         return HALMAC_RET_SUCCESS;
3975 }
3976
3977 enum halmac_ret_status
3978 halmac_pg_num_parser_88xx(struct halmac_adapter *halmac_adapter,
3979                           enum halmac_trx_mode halmac_trx_mode,
3980                           struct halmac_pg_num_ *pg_num_table)
3981 {
3982         u8 search_flag;
3983         u16 HPQ_num = 0, lpq_nnum = 0, NPQ_num = 0, GAPQ_num = 0;
3984         u16 EXPQ_num = 0, PUBQ_num = 0;
3985         u32 i = 0;
3986         void *driver_adapter = NULL;
3987         struct halmac_api *halmac_api;
3988
3989         driver_adapter = halmac_adapter->driver_adapter;
3990         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3991
3992         search_flag = 0;
3993         for (i = 0; i < HALMAC_TRX_MODE_MAX; i++) {
3994                 if (halmac_trx_mode == pg_num_table[i].mode) {
3995                         HPQ_num = pg_num_table[i].hq_num;
3996                         lpq_nnum = pg_num_table[i].lq_num;
3997                         NPQ_num = pg_num_table[i].nq_num;
3998                         EXPQ_num = pg_num_table[i].exq_num;
3999                         GAPQ_num = pg_num_table[i].gap_num;
4000                         PUBQ_num = halmac_adapter->txff_allocation.ac_q_pg_num -
4001                                    HPQ_num - lpq_nnum - NPQ_num - EXPQ_num -
4002                                    GAPQ_num;
4003                         search_flag = 1;
4004                         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
4005                                         DBG_DMESG, "%s done\n", __func__);
4006                         break;
4007                 }
4008         }
4009
4010         if (search_flag == 0) {
4011                 pr_err("HALMAC_RET_TRX_MODE_NOT_SUPPORT 1 switch case not support\n");
4012                 return HALMAC_RET_TRX_MODE_NOT_SUPPORT;
4013         }
4014
4015         if (halmac_adapter->txff_allocation.ac_q_pg_num <
4016             HPQ_num + lpq_nnum + NPQ_num + EXPQ_num + GAPQ_num)
4017                 return HALMAC_RET_CFG_TXFIFO_PAGE_FAIL;
4018
4019         halmac_adapter->txff_allocation.high_queue_pg_num = HPQ_num;
4020         halmac_adapter->txff_allocation.low_queue_pg_num = lpq_nnum;
4021         halmac_adapter->txff_allocation.normal_queue_pg_num = NPQ_num;
4022         halmac_adapter->txff_allocation.extra_queue_pg_num = EXPQ_num;
4023         halmac_adapter->txff_allocation.pub_queue_pg_num = PUBQ_num;
4024
4025         return HALMAC_RET_SUCCESS;
4026 }
4027
4028 enum halmac_ret_status
4029 halmac_parse_intf_phy_88xx(struct halmac_adapter *halmac_adapter,
4030                            struct halmac_intf_phy_para_ *intf_phy_para,
4031                            enum halmac_intf_phy_platform platform,
4032                            enum hal_intf_phy intf_phy)
4033 {
4034         u16 value;
4035         u16 curr_cut;
4036         u16 offset;
4037         u16 ip_sel;
4038         struct halmac_intf_phy_para_ *curr_phy_para;
4039         struct halmac_api *halmac_api;
4040         void *driver_adapter = NULL;
4041         u8 result = HALMAC_RET_SUCCESS;
4042
4043         driver_adapter = halmac_adapter->driver_adapter;
4044         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4045
4046         switch (halmac_adapter->chip_version) {
4047         case HALMAC_CHIP_VER_A_CUT:
4048                 curr_cut = (u16)HALMAC_INTF_PHY_CUT_A;
4049                 break;
4050         case HALMAC_CHIP_VER_B_CUT:
4051                 curr_cut = (u16)HALMAC_INTF_PHY_CUT_B;
4052                 break;
4053         case HALMAC_CHIP_VER_C_CUT:
4054                 curr_cut = (u16)HALMAC_INTF_PHY_CUT_C;
4055                 break;
4056         case HALMAC_CHIP_VER_D_CUT:
4057                 curr_cut = (u16)HALMAC_INTF_PHY_CUT_D;
4058                 break;
4059         case HALMAC_CHIP_VER_E_CUT:
4060                 curr_cut = (u16)HALMAC_INTF_PHY_CUT_E;
4061                 break;
4062         case HALMAC_CHIP_VER_F_CUT:
4063                 curr_cut = (u16)HALMAC_INTF_PHY_CUT_F;
4064                 break;
4065         case HALMAC_CHIP_VER_TEST:
4066                 curr_cut = (u16)HALMAC_INTF_PHY_CUT_TESTCHIP;
4067                 break;
4068         default:
4069                 return HALMAC_RET_FAIL;
4070         }
4071
4072         for (curr_phy_para = intf_phy_para;; curr_phy_para++) {
4073                 if (!(curr_phy_para->cut & curr_cut) ||
4074                     !(curr_phy_para->plaform & (u16)platform))
4075                         continue;
4076
4077                 offset = curr_phy_para->offset;
4078                 value = curr_phy_para->value;
4079                 ip_sel = curr_phy_para->ip_sel;
4080
4081                 if (offset == 0xFFFF)
4082                         break;
4083
4084                 if (ip_sel == HALMAC_IP_SEL_MAC) {
4085                         HALMAC_REG_WRITE_8(halmac_adapter, (u32)offset,
4086                                            (u8)value);
4087                 } else if (intf_phy == HAL_INTF_PHY_USB2) {
4088                         result = halmac_usbphy_write_88xx(halmac_adapter,
4089                                                           (u8)offset, value,
4090                                                           HAL_INTF_PHY_USB2);
4091
4092                         if (result != HALMAC_RET_SUCCESS)
4093                                 pr_err("[ERR]Write USB2PHY fail!\n");
4094
4095                 } else if (intf_phy == HAL_INTF_PHY_USB3) {
4096                         result = halmac_usbphy_write_88xx(halmac_adapter,
4097                                                           (u8)offset, value,
4098                                                           HAL_INTF_PHY_USB3);
4099
4100                         if (result != HALMAC_RET_SUCCESS)
4101                                 pr_err("[ERR]Write USB3PHY fail!\n");
4102
4103                 } else if (intf_phy == HAL_INTF_PHY_PCIE_GEN1) {
4104                         if (ip_sel == HALMAC_IP_SEL_INTF_PHY)
4105                                 result = halmac_mdio_write_88xx(
4106                                         halmac_adapter, (u8)offset, value,
4107                                         HAL_INTF_PHY_PCIE_GEN1);
4108                         else
4109                                 result = halmac_dbi_write8_88xx(
4110                                         halmac_adapter, offset, (u8)value);
4111
4112                         if (result != HALMAC_RET_SUCCESS)
4113                                 pr_err("[ERR]MDIO write GEN1 fail!\n");
4114
4115                 } else if (intf_phy == HAL_INTF_PHY_PCIE_GEN2) {
4116                         if (ip_sel == HALMAC_IP_SEL_INTF_PHY)
4117                                 result = halmac_mdio_write_88xx(
4118                                         halmac_adapter, (u8)offset, value,
4119                                         HAL_INTF_PHY_PCIE_GEN2);
4120                         else
4121                                 result = halmac_dbi_write8_88xx(
4122                                         halmac_adapter, offset, (u8)value);
4123
4124                         if (result != HALMAC_RET_SUCCESS)
4125                                 pr_err("[ERR]MDIO write GEN2 fail!\n");
4126                 } else {
4127                         pr_err("[ERR]Parse intf phy cfg error!\n");
4128                 }
4129         }
4130
4131         return HALMAC_RET_SUCCESS;
4132 }
4133
4134 enum halmac_ret_status
4135 halmac_dbi_write32_88xx(struct halmac_adapter *halmac_adapter, u16 addr,
4136                         u32 data)
4137 {
4138         u8 tmp_u1b = 0;
4139         u32 count = 0;
4140         u16 write_addr = 0;
4141         void *driver_adapter = NULL;
4142         struct halmac_api *halmac_api;
4143
4144         driver_adapter = halmac_adapter->driver_adapter;
4145         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4146
4147         HALMAC_REG_WRITE_32(halmac_adapter, REG_DBI_WDATA_V1, data);
4148
4149         write_addr = ((addr & 0x0ffc) | (0x000F << 12));
4150         HALMAC_REG_WRITE_16(halmac_adapter, REG_DBI_FLAG_V1, write_addr);
4151
4152         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_DBI, DBG_DMESG,
4153                         "WriteAddr = %x\n", write_addr);
4154
4155         HALMAC_REG_WRITE_8(halmac_adapter, REG_DBI_FLAG_V1 + 2, 0x01);
4156         tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4157
4158         count = 20;
4159         while (tmp_u1b && count != 0) {
4160                 udelay(10);
4161                 tmp_u1b =
4162                         HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4163                 count--;
4164         }
4165
4166         if (tmp_u1b) {
4167                 pr_err("DBI write fail!\n");
4168                 return HALMAC_RET_FAIL;
4169         } else {
4170                 return HALMAC_RET_SUCCESS;
4171         }
4172 }
4173
4174 u32 halmac_dbi_read32_88xx(struct halmac_adapter *halmac_adapter, u16 addr)
4175 {
4176         u16 read_addr = addr & 0x0ffc;
4177         u8 tmp_u1b = 0;
4178         u32 count = 0;
4179         u32 ret = 0;
4180         void *driver_adapter = NULL;
4181         struct halmac_api *halmac_api;
4182
4183         driver_adapter = halmac_adapter->driver_adapter;
4184         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4185
4186         HALMAC_REG_WRITE_16(halmac_adapter, REG_DBI_FLAG_V1, read_addr);
4187
4188         HALMAC_REG_WRITE_8(halmac_adapter, REG_DBI_FLAG_V1 + 2, 0x2);
4189         tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4190
4191         count = 20;
4192         while (tmp_u1b && count != 0) {
4193                 udelay(10);
4194                 tmp_u1b =
4195                         HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4196                 count--;
4197         }
4198
4199         if (tmp_u1b) {
4200                 ret = 0xFFFF;
4201                 pr_err("DBI read fail!\n");
4202         } else {
4203                 ret = HALMAC_REG_READ_32(halmac_adapter, REG_DBI_RDATA_V1);
4204                 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_DBI, DBG_DMESG,
4205                                 "Read Value = %x\n", ret);
4206         }
4207
4208         return ret;
4209 }
4210
4211 enum halmac_ret_status
4212 halmac_dbi_write8_88xx(struct halmac_adapter *halmac_adapter, u16 addr, u8 data)
4213 {
4214         u8 tmp_u1b = 0;
4215         u32 count = 0;
4216         u16 write_addr = 0;
4217         u16 remainder = addr & (4 - 1);
4218         void *driver_adapter = NULL;
4219         struct halmac_api *halmac_api;
4220
4221         driver_adapter = halmac_adapter->driver_adapter;
4222         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4223
4224         HALMAC_REG_WRITE_8(halmac_adapter, REG_DBI_WDATA_V1 + remainder, data);
4225
4226         write_addr = ((addr & 0x0ffc) | (BIT(0) << (remainder + 12)));
4227
4228         HALMAC_REG_WRITE_16(halmac_adapter, REG_DBI_FLAG_V1, write_addr);
4229
4230         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_DBI, DBG_DMESG,
4231                         "WriteAddr = %x\n", write_addr);
4232
4233         HALMAC_REG_WRITE_8(halmac_adapter, REG_DBI_FLAG_V1 + 2, 0x01);
4234
4235         tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4236
4237         count = 20;
4238         while (tmp_u1b && count != 0) {
4239                 udelay(10);
4240                 tmp_u1b =
4241                         HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4242                 count--;
4243         }
4244
4245         if (tmp_u1b) {
4246                 pr_err("DBI write fail!\n");
4247                 return HALMAC_RET_FAIL;
4248         } else {
4249                 return HALMAC_RET_SUCCESS;
4250         }
4251 }
4252
4253 u8 halmac_dbi_read8_88xx(struct halmac_adapter *halmac_adapter, u16 addr)
4254 {
4255         u16 read_addr = addr & 0x0ffc;
4256         u8 tmp_u1b = 0;
4257         u32 count = 0;
4258         u8 ret = 0;
4259         void *driver_adapter = NULL;
4260         struct halmac_api *halmac_api;
4261
4262         driver_adapter = halmac_adapter->driver_adapter;
4263         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4264
4265         HALMAC_REG_WRITE_16(halmac_adapter, REG_DBI_FLAG_V1, read_addr);
4266         HALMAC_REG_WRITE_8(halmac_adapter, REG_DBI_FLAG_V1 + 2, 0x2);
4267
4268         tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4269
4270         count = 20;
4271         while (tmp_u1b && count != 0) {
4272                 udelay(10);
4273                 tmp_u1b =
4274                         HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4275                 count--;
4276         }
4277
4278         if (tmp_u1b) {
4279                 ret = 0xFF;
4280                 pr_err("DBI read fail!\n");
4281         } else {
4282                 ret = HALMAC_REG_READ_8(halmac_adapter,
4283                                         REG_DBI_RDATA_V1 + (addr & (4 - 1)));
4284                 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_DBI, DBG_DMESG,
4285                                 "Read Value = %x\n", ret);
4286         }
4287
4288         return ret;
4289 }
4290
4291 enum halmac_ret_status
4292 halmac_mdio_write_88xx(struct halmac_adapter *halmac_adapter, u8 addr, u16 data,
4293                        u8 speed)
4294 {
4295         u8 tmp_u1b = 0;
4296         u32 count = 0;
4297         void *driver_adapter = NULL;
4298         struct halmac_api *halmac_api;
4299         u8 real_addr = 0;
4300
4301         driver_adapter = halmac_adapter->driver_adapter;
4302         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4303
4304         HALMAC_REG_WRITE_16(halmac_adapter, REG_MDIO_V1, data);
4305
4306         /* address : 5bit */
4307         real_addr = (addr & 0x1F);
4308         HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG, real_addr);
4309
4310         if (speed == HAL_INTF_PHY_PCIE_GEN1) {
4311                 /* GEN1 page 0 */
4312                 if (addr < 0x20) {
4313                         /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b00 */
4314                         HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4315                                            0x00);
4316
4317                         /* GEN1 page 1 */
4318                 } else {
4319                         /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b01 */
4320                         HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4321                                            0x01);
4322                 }
4323
4324         } else if (speed == HAL_INTF_PHY_PCIE_GEN2) {
4325                 /* GEN2 page 0 */
4326                 if (addr < 0x20) {
4327                         /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b10 */
4328                         HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4329                                            0x02);
4330
4331                         /* GEN2 page 1 */
4332                 } else {
4333                         /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b11 */
4334                         HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4335                                            0x03);
4336                 }
4337         } else {
4338                 pr_err("Error Speed !\n");
4339         }
4340
4341         HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG,
4342                            HALMAC_REG_READ_8(halmac_adapter, REG_PCIE_MIX_CFG) |
4343                                    BIT_MDIO_WFLAG_V1);
4344
4345         tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_PCIE_MIX_CFG) &
4346                   BIT_MDIO_WFLAG_V1;
4347         count = 20;
4348
4349         while (tmp_u1b && count != 0) {
4350                 udelay(10);
4351                 tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_PCIE_MIX_CFG) &
4352                           BIT_MDIO_WFLAG_V1;
4353                 count--;
4354         }
4355
4356         if (tmp_u1b) {
4357                 pr_err("MDIO write fail!\n");
4358                 return HALMAC_RET_FAIL;
4359         } else {
4360                 return HALMAC_RET_SUCCESS;
4361         }
4362 }
4363
4364 u16 halmac_mdio_read_88xx(struct halmac_adapter *halmac_adapter, u8 addr,
4365                           u8 speed
4366
4367                           )
4368 {
4369         u16 ret = 0;
4370         u8 tmp_u1b = 0;
4371         u32 count = 0;
4372         void *driver_adapter = NULL;
4373         struct halmac_api *halmac_api;
4374         u8 real_addr = 0;
4375
4376         driver_adapter = halmac_adapter->driver_adapter;
4377         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4378
4379         /* address : 5bit */
4380         real_addr = (addr & 0x1F);
4381         HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG, real_addr);
4382
4383         if (speed == HAL_INTF_PHY_PCIE_GEN1) {
4384                 /* GEN1 page 0 */
4385                 if (addr < 0x20) {
4386                         /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b00 */
4387                         HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4388                                            0x00);
4389
4390                         /* GEN1 page 1 */
4391                 } else {
4392                         /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b01 */
4393                         HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4394                                            0x01);
4395                 }
4396
4397         } else if (speed == HAL_INTF_PHY_PCIE_GEN2) {
4398                 /* GEN2 page 0 */
4399                 if (addr < 0x20) {
4400                         /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b10 */
4401                         HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4402                                            0x02);
4403
4404                         /* GEN2 page 1 */
4405                 } else {
4406                         /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b11 */
4407                         HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4408                                            0x03);
4409                 }
4410         } else {
4411                 pr_err("Error Speed !\n");
4412         }
4413
4414         HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG,
4415                            HALMAC_REG_READ_8(halmac_adapter, REG_PCIE_MIX_CFG) |
4416                                    BIT_MDIO_RFLAG_V1);
4417
4418         tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_PCIE_MIX_CFG) &
4419                   BIT_MDIO_RFLAG_V1;
4420         count = 20;
4421
4422         while (tmp_u1b && count != 0) {
4423                 udelay(10);
4424                 tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_PCIE_MIX_CFG) &
4425                           BIT_MDIO_RFLAG_V1;
4426                 count--;
4427         }
4428
4429         if (tmp_u1b) {
4430                 ret = 0xFFFF;
4431                 pr_err("MDIO read fail!\n");
4432
4433         } else {
4434                 ret = HALMAC_REG_READ_16(halmac_adapter, REG_MDIO_V1 + 2);
4435                 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_MDIO, DBG_DMESG,
4436                                 "Read Value = %x\n", ret);
4437         }
4438
4439         return ret;
4440 }
4441
4442 enum halmac_ret_status
4443 halmac_usbphy_write_88xx(struct halmac_adapter *halmac_adapter, u8 addr,
4444                          u16 data, u8 speed)
4445 {
4446         void *driver_adapter = NULL;
4447         struct halmac_api *halmac_api;
4448
4449         driver_adapter = halmac_adapter->driver_adapter;
4450         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4451
4452         if (speed == HAL_INTF_PHY_USB3) {
4453                 HALMAC_REG_WRITE_8(halmac_adapter, 0xff0d, (u8)data);
4454                 HALMAC_REG_WRITE_8(halmac_adapter, 0xff0e, (u8)(data >> 8));
4455                 HALMAC_REG_WRITE_8(halmac_adapter, 0xff0c, addr | BIT(7));
4456         } else if (speed == HAL_INTF_PHY_USB2) {
4457                 HALMAC_REG_WRITE_8(halmac_adapter, 0xfe41, (u8)data);
4458                 HALMAC_REG_WRITE_8(halmac_adapter, 0xfe40, addr);
4459                 HALMAC_REG_WRITE_8(halmac_adapter, 0xfe42, 0x81);
4460         } else {
4461                 pr_err("[ERR]Error USB Speed !\n");
4462                 return HALMAC_RET_NOT_SUPPORT;
4463         }
4464
4465         return HALMAC_RET_SUCCESS;
4466 }
4467
4468 u16 halmac_usbphy_read_88xx(struct halmac_adapter *halmac_adapter, u8 addr,
4469                             u8 speed)
4470 {
4471         void *driver_adapter = NULL;
4472         struct halmac_api *halmac_api;
4473         u16 value = 0;
4474
4475         driver_adapter = halmac_adapter->driver_adapter;
4476         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4477
4478         if (speed == HAL_INTF_PHY_USB3) {
4479                 HALMAC_REG_WRITE_8(halmac_adapter, 0xff0c, addr | BIT(6));
4480                 value = (u16)(HALMAC_REG_READ_32(halmac_adapter, 0xff0c) >> 8);
4481         } else if (speed == HAL_INTF_PHY_USB2) {
4482                 if ((addr >= 0xE0) /*&& (addr <= 0xFF)*/)
4483                         addr -= 0x20;
4484                 if ((addr >= 0xC0) && (addr <= 0xDF)) {
4485                         HALMAC_REG_WRITE_8(halmac_adapter, 0xfe40, addr);
4486                         HALMAC_REG_WRITE_8(halmac_adapter, 0xfe42, 0x81);
4487                         value = HALMAC_REG_READ_8(halmac_adapter, 0xfe43);
4488                 } else {
4489                         pr_err("[ERR]Error USB2PHY offset!\n");
4490                         return HALMAC_RET_NOT_SUPPORT;
4491                 }
4492         } else {
4493                 pr_err("[ERR]Error USB Speed !\n");
4494                 return HALMAC_RET_NOT_SUPPORT;
4495         }
4496
4497         return value;
4498 }