Input: wm97xx: add new AC97 bus support
[sfrench/cifs-2.6.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         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1622                         "%s!!\n", __func__);
1623
1624         driver_adapter = halmac_adapter->driver_adapter;
1625         h2c_header = h2c_buff;
1626         h2c_cmd = h2c_header + HALMAC_H2C_CMD_HDR_SIZE_88XX;
1627
1628         memset(h2c_buff, 0x00, HALMAC_H2C_CMD_SIZE_88XX);
1629
1630         SET_PWR_MODE_SET_CMD_ID(h2c_cmd, CMD_ID_SET_PWR_MODE);
1631         SET_PWR_MODE_SET_CLASS(h2c_cmd, CLASS_SET_PWR_MODE);
1632         SET_PWR_MODE_SET_MODE(h2c_cmd, hal_fw_lps_opt->mode);
1633         SET_PWR_MODE_SET_CLK_REQUEST(h2c_cmd, hal_fw_lps_opt->clk_request);
1634         SET_PWR_MODE_SET_RLBM(h2c_cmd, hal_fw_lps_opt->rlbm);
1635         SET_PWR_MODE_SET_SMART_PS(h2c_cmd, hal_fw_lps_opt->smart_ps);
1636         SET_PWR_MODE_SET_AWAKE_INTERVAL(h2c_cmd,
1637                                         hal_fw_lps_opt->awake_interval);
1638         SET_PWR_MODE_SET_B_ALL_QUEUE_UAPSD(h2c_cmd,
1639                                            hal_fw_lps_opt->all_queue_uapsd);
1640         SET_PWR_MODE_SET_PWR_STATE(h2c_cmd, hal_fw_lps_opt->pwr_state);
1641         SET_PWR_MODE_SET_ANT_AUTO_SWITCH(h2c_cmd,
1642                                          hal_fw_lps_opt->ant_auto_switch);
1643         SET_PWR_MODE_SET_PS_ALLOW_BT_HIGH_PRIORITY(
1644                 h2c_cmd, hal_fw_lps_opt->ps_allow_bt_high_priority);
1645         SET_PWR_MODE_SET_PROTECT_BCN(h2c_cmd, hal_fw_lps_opt->protect_bcn);
1646         SET_PWR_MODE_SET_SILENCE_PERIOD(h2c_cmd,
1647                                         hal_fw_lps_opt->silence_period);
1648         SET_PWR_MODE_SET_FAST_BT_CONNECT(h2c_cmd,
1649                                          hal_fw_lps_opt->fast_bt_connect);
1650         SET_PWR_MODE_SET_TWO_ANTENNA_EN(h2c_cmd,
1651                                         hal_fw_lps_opt->two_antenna_en);
1652         SET_PWR_MODE_SET_ADOPT_USER_SETTING(h2c_cmd,
1653                                             hal_fw_lps_opt->adopt_user_setting);
1654         SET_PWR_MODE_SET_DRV_BCN_EARLY_SHIFT(
1655                 h2c_cmd, hal_fw_lps_opt->drv_bcn_early_shift);
1656
1657         halmac_set_h2c_header_88xx(halmac_adapter, h2c_header, &seq, true);
1658
1659         status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
1660                                           HALMAC_H2C_CMD_SIZE_88XX, true);
1661
1662         if (status != HALMAC_RET_SUCCESS) {
1663                 pr_err("%s Fail = %x!!\n", __func__, status);
1664                 return status;
1665         }
1666
1667         return HALMAC_RET_SUCCESS;
1668 }
1669
1670 enum halmac_ret_status
1671 halmac_func_send_original_h2c_88xx(struct halmac_adapter *halmac_adapter,
1672                                    u8 *original_h2c, u16 *seq, u8 ack)
1673 {
1674         u8 H2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
1675         u8 *h2c_header, *h2c_cmd;
1676         void *driver_adapter = NULL;
1677         struct halmac_api *halmac_api;
1678         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1679
1680         driver_adapter = halmac_adapter->driver_adapter;
1681         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1682
1683         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1684                         "halmac_send_original_h2c ==========>\n");
1685
1686         h2c_header = H2c_buff;
1687         h2c_cmd = h2c_header + HALMAC_H2C_CMD_HDR_SIZE_88XX;
1688         memcpy(h2c_cmd, original_h2c, 8); /* Original H2C 8 byte */
1689
1690         halmac_set_h2c_header_88xx(halmac_adapter, h2c_header, seq, ack);
1691
1692         status = halmac_send_h2c_pkt_88xx(halmac_adapter, H2c_buff,
1693                                           HALMAC_H2C_CMD_SIZE_88XX, ack);
1694
1695         if (status != HALMAC_RET_SUCCESS) {
1696                 pr_err("halmac_send_original_h2c Fail = %x!!\n", status);
1697                 return status;
1698         }
1699
1700         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1701                         "halmac_send_original_h2c <==========\n");
1702
1703         return HALMAC_RET_SUCCESS;
1704 }
1705
1706 enum halmac_ret_status
1707 halmac_media_status_rpt_88xx(struct halmac_adapter *halmac_adapter, u8 op_mode,
1708                              u8 mac_id_ind, u8 mac_id, u8 mac_id_end)
1709 {
1710         u8 H2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
1711         u8 *h2c_header, *h2c_cmd;
1712         u16 seq = 0;
1713         void *driver_adapter = NULL;
1714         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1715
1716         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1717                         "halmac_send_h2c_set_pwr_mode_88xx!!\n");
1718
1719         driver_adapter = halmac_adapter->driver_adapter;
1720         h2c_header = H2c_buff;
1721         h2c_cmd = h2c_header + HALMAC_H2C_CMD_HDR_SIZE_88XX;
1722
1723         memset(H2c_buff, 0x00, HALMAC_H2C_CMD_SIZE_88XX);
1724
1725         MEDIA_STATUS_RPT_SET_CMD_ID(h2c_cmd, CMD_ID_MEDIA_STATUS_RPT);
1726         MEDIA_STATUS_RPT_SET_CLASS(h2c_cmd, CLASS_MEDIA_STATUS_RPT);
1727         MEDIA_STATUS_RPT_SET_OP_MODE(h2c_cmd, op_mode);
1728         MEDIA_STATUS_RPT_SET_MACID_IN(h2c_cmd, mac_id_ind);
1729         MEDIA_STATUS_RPT_SET_MACID(h2c_cmd, mac_id);
1730         MEDIA_STATUS_RPT_SET_MACID_END(h2c_cmd, mac_id_end);
1731
1732         halmac_set_h2c_header_88xx(halmac_adapter, h2c_header, &seq, true);
1733
1734         status = halmac_send_h2c_pkt_88xx(halmac_adapter, H2c_buff,
1735                                           HALMAC_H2C_CMD_SIZE_88XX, true);
1736
1737         if (status != HALMAC_RET_SUCCESS) {
1738                 pr_err("%s Fail = %x!!\n", __func__, status);
1739                 return status;
1740         }
1741
1742         return HALMAC_RET_SUCCESS;
1743 }
1744
1745 enum halmac_ret_status
1746 halmac_send_h2c_update_packet_88xx(struct halmac_adapter *halmac_adapter,
1747                                    enum halmac_packet_id pkt_id, u8 *pkt,
1748                                    u32 pkt_size)
1749 {
1750         u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
1751         u16 h2c_seq_mum = 0;
1752         void *driver_adapter = NULL;
1753         struct halmac_api *halmac_api;
1754         struct halmac_h2c_header_info h2c_header_info;
1755         enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
1756
1757         driver_adapter = halmac_adapter->driver_adapter;
1758         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1759
1760         HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
1761                             (u16)(halmac_adapter->txff_allocation
1762                                           .rsvd_h2c_extra_info_pg_bndy &
1763                                   BIT_MASK_BCN_HEAD_1_V1));
1764
1765         ret_status =
1766                 halmac_download_rsvd_page_88xx(halmac_adapter, pkt, pkt_size);
1767
1768         if (ret_status != HALMAC_RET_SUCCESS) {
1769                 pr_err("halmac_download_rsvd_page_88xx Fail = %x!!\n",
1770                        ret_status);
1771                 HALMAC_REG_WRITE_16(
1772                         halmac_adapter, REG_FIFOPAGE_CTRL_2,
1773                         (u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
1774                               BIT_MASK_BCN_HEAD_1_V1));
1775                 return ret_status;
1776         }
1777
1778         HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
1779                             (u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
1780                                   BIT_MASK_BCN_HEAD_1_V1));
1781
1782         UPDATE_PACKET_SET_SIZE(
1783                 h2c_buff,
1784                 pkt_size + halmac_adapter->hw_config_info.txdesc_size);
1785         UPDATE_PACKET_SET_PACKET_ID(h2c_buff, pkt_id);
1786         UPDATE_PACKET_SET_PACKET_LOC(
1787                 h2c_buff,
1788                 halmac_adapter->txff_allocation.rsvd_h2c_extra_info_pg_bndy -
1789                         halmac_adapter->txff_allocation.rsvd_pg_bndy);
1790
1791         h2c_header_info.sub_cmd_id = SUB_CMD_ID_UPDATE_PACKET;
1792         h2c_header_info.content_size = 8;
1793         h2c_header_info.ack = true;
1794         halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
1795                                               &h2c_header_info, &h2c_seq_mum);
1796         halmac_adapter->halmac_state.update_packet_set.seq_num = h2c_seq_mum;
1797
1798         ret_status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
1799                                               HALMAC_H2C_CMD_SIZE_88XX, true);
1800
1801         if (ret_status != HALMAC_RET_SUCCESS) {
1802                 pr_err("%s Fail = %x!!\n", __func__, ret_status);
1803                 return ret_status;
1804         }
1805
1806         return ret_status;
1807 }
1808
1809 enum halmac_ret_status
1810 halmac_send_h2c_phy_parameter_88xx(struct halmac_adapter *halmac_adapter,
1811                                    struct halmac_phy_parameter_info *para_info,
1812                                    bool full_fifo)
1813 {
1814         bool drv_trigger_send = false;
1815         u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
1816         u16 h2c_seq_mum = 0;
1817         u32 info_size = 0;
1818         void *driver_adapter = NULL;
1819         struct halmac_api *halmac_api;
1820         struct halmac_h2c_header_info h2c_header_info;
1821         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1822         struct halmac_config_para_info *config_para_info;
1823
1824         driver_adapter = halmac_adapter->driver_adapter;
1825         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
1826         config_para_info = &halmac_adapter->config_para_info;
1827
1828         if (!config_para_info->cfg_para_buf) {
1829                 if (full_fifo)
1830                         config_para_info->para_buf_size =
1831                                 HALMAC_EXTRA_INFO_BUFF_SIZE_FULL_FIFO_88XX;
1832                 else
1833                         config_para_info->para_buf_size =
1834                                 HALMAC_EXTRA_INFO_BUFF_SIZE_88XX;
1835
1836                 config_para_info->cfg_para_buf =
1837                         kzalloc(config_para_info->para_buf_size, GFP_KERNEL);
1838
1839                 if (config_para_info->cfg_para_buf) {
1840                         memset(config_para_info->cfg_para_buf, 0x00,
1841                                config_para_info->para_buf_size);
1842                         config_para_info->full_fifo_mode = full_fifo;
1843                         config_para_info->para_buf_w =
1844                                 config_para_info->cfg_para_buf;
1845                         config_para_info->para_num = 0;
1846                         config_para_info->avai_para_buf_size =
1847                                 config_para_info->para_buf_size;
1848                         config_para_info->value_accumulation = 0;
1849                         config_para_info->offset_accumulation = 0;
1850                 } else {
1851                         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C,
1852                                         DBG_DMESG,
1853                                         "Allocate cfg_para_buf fail!!\n");
1854                         return HALMAC_RET_MALLOC_FAIL;
1855                 }
1856         }
1857
1858         if (halmac_transition_cfg_para_state_88xx(
1859                     halmac_adapter,
1860                     HALMAC_CFG_PARA_CMD_CONSTRUCT_CONSTRUCTING) !=
1861             HALMAC_RET_SUCCESS)
1862                 return HALMAC_RET_ERROR_STATE;
1863
1864         halmac_enqueue_para_buff_88xx(halmac_adapter, para_info,
1865                                       config_para_info->para_buf_w,
1866                                       &drv_trigger_send);
1867
1868         if (para_info->cmd_id != HALMAC_PARAMETER_CMD_END) {
1869                 config_para_info->para_num++;
1870                 config_para_info->para_buf_w += HALMAC_FW_OFFLOAD_CMD_SIZE_88XX;
1871                 config_para_info->avai_para_buf_size =
1872                         config_para_info->avai_para_buf_size -
1873                         HALMAC_FW_OFFLOAD_CMD_SIZE_88XX;
1874         }
1875
1876         if ((config_para_info->avai_para_buf_size -
1877              halmac_adapter->hw_config_info.txdesc_size) >
1878                     HALMAC_FW_OFFLOAD_CMD_SIZE_88XX &&
1879             !drv_trigger_send)
1880                 return HALMAC_RET_SUCCESS;
1881
1882         if (config_para_info->para_num == 0) {
1883                 kfree(config_para_info->cfg_para_buf);
1884                 config_para_info->cfg_para_buf = NULL;
1885                 config_para_info->para_buf_w = NULL;
1886                 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_WARNING,
1887                                 "no cfg parameter element!!\n");
1888
1889                 if (halmac_transition_cfg_para_state_88xx(
1890                             halmac_adapter,
1891                             HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE) !=
1892                     HALMAC_RET_SUCCESS)
1893                         return HALMAC_RET_ERROR_STATE;
1894
1895                 return HALMAC_RET_SUCCESS;
1896         }
1897
1898         if (halmac_transition_cfg_para_state_88xx(
1899                     halmac_adapter, HALMAC_CFG_PARA_CMD_CONSTRUCT_H2C_SENT) !=
1900             HALMAC_RET_SUCCESS)
1901                 return HALMAC_RET_ERROR_STATE;
1902
1903         halmac_adapter->halmac_state.cfg_para_state_set.process_status =
1904                 HALMAC_CMD_PROCESS_SENDING;
1905
1906         if (config_para_info->full_fifo_mode)
1907                 HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2, 0);
1908         else
1909                 HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
1910                                     (u16)(halmac_adapter->txff_allocation
1911                                                   .rsvd_h2c_extra_info_pg_bndy &
1912                                           BIT_MASK_BCN_HEAD_1_V1));
1913
1914         info_size =
1915                 config_para_info->para_num * HALMAC_FW_OFFLOAD_CMD_SIZE_88XX;
1916
1917         status = halmac_download_rsvd_page_88xx(
1918                 halmac_adapter, (u8 *)config_para_info->cfg_para_buf,
1919                 info_size);
1920
1921         if (status != HALMAC_RET_SUCCESS) {
1922                 pr_err("halmac_download_rsvd_page_88xx Fail!!\n");
1923         } else {
1924                 halmac_gen_cfg_para_h2c_88xx(halmac_adapter, h2c_buff);
1925
1926                 h2c_header_info.sub_cmd_id = SUB_CMD_ID_CFG_PARAMETER;
1927                 h2c_header_info.content_size = 4;
1928                 h2c_header_info.ack = true;
1929                 halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
1930                                                       &h2c_header_info,
1931                                                       &h2c_seq_mum);
1932
1933                 halmac_adapter->halmac_state.cfg_para_state_set.seq_num =
1934                         h2c_seq_mum;
1935
1936                 status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
1937                                                   HALMAC_H2C_CMD_SIZE_88XX,
1938                                                   true);
1939
1940                 if (status != HALMAC_RET_SUCCESS)
1941                         pr_err("halmac_send_h2c_pkt_88xx Fail!!\n");
1942
1943                 HALMAC_RT_TRACE(
1944                         driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
1945                         "config parameter time = %d\n",
1946                         HALMAC_REG_READ_32(halmac_adapter, REG_FW_DBG6));
1947         }
1948
1949         kfree(config_para_info->cfg_para_buf);
1950         config_para_info->cfg_para_buf = NULL;
1951         config_para_info->para_buf_w = NULL;
1952
1953         /* Restore bcn head */
1954         HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
1955                             (u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
1956                                   BIT_MASK_BCN_HEAD_1_V1));
1957
1958         if (halmac_transition_cfg_para_state_88xx(
1959                     halmac_adapter, HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE) !=
1960             HALMAC_RET_SUCCESS)
1961                 return HALMAC_RET_ERROR_STATE;
1962
1963         if (!drv_trigger_send) {
1964                 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
1965                                 "Buffer full trigger sending H2C!!\n");
1966                 return HALMAC_RET_PARA_SENDING;
1967         }
1968
1969         return status;
1970 }
1971
1972 static enum halmac_ret_status
1973 halmac_enqueue_para_buff_88xx(struct halmac_adapter *halmac_adapter,
1974                               struct halmac_phy_parameter_info *para_info,
1975                               u8 *curr_buff_wptr, bool *end_cmd)
1976 {
1977         struct halmac_config_para_info *config_para_info =
1978                 &halmac_adapter->config_para_info;
1979
1980         *end_cmd = false;
1981
1982         PHY_PARAMETER_INFO_SET_LENGTH(curr_buff_wptr,
1983                                       HALMAC_FW_OFFLOAD_CMD_SIZE_88XX);
1984         PHY_PARAMETER_INFO_SET_IO_CMD(curr_buff_wptr, para_info->cmd_id);
1985
1986         switch (para_info->cmd_id) {
1987         case HALMAC_PARAMETER_CMD_BB_W8:
1988         case HALMAC_PARAMETER_CMD_BB_W16:
1989         case HALMAC_PARAMETER_CMD_BB_W32:
1990         case HALMAC_PARAMETER_CMD_MAC_W8:
1991         case HALMAC_PARAMETER_CMD_MAC_W16:
1992         case HALMAC_PARAMETER_CMD_MAC_W32:
1993                 PHY_PARAMETER_INFO_SET_IO_ADDR(
1994                         curr_buff_wptr, para_info->content.MAC_REG_W.offset);
1995                 PHY_PARAMETER_INFO_SET_DATA(curr_buff_wptr,
1996                                             para_info->content.MAC_REG_W.value);
1997                 PHY_PARAMETER_INFO_SET_MASK(curr_buff_wptr,
1998                                             para_info->content.MAC_REG_W.msk);
1999                 PHY_PARAMETER_INFO_SET_MSK_EN(
2000                         curr_buff_wptr, para_info->content.MAC_REG_W.msk_en);
2001                 config_para_info->value_accumulation +=
2002                         para_info->content.MAC_REG_W.value;
2003                 config_para_info->offset_accumulation +=
2004                         para_info->content.MAC_REG_W.offset;
2005                 break;
2006         case HALMAC_PARAMETER_CMD_RF_W:
2007                 /*In rf register, the address is only 1 byte*/
2008                 PHY_PARAMETER_INFO_SET_RF_ADDR(
2009                         curr_buff_wptr, para_info->content.RF_REG_W.offset);
2010                 PHY_PARAMETER_INFO_SET_RF_PATH(
2011                         curr_buff_wptr, para_info->content.RF_REG_W.rf_path);
2012                 PHY_PARAMETER_INFO_SET_DATA(curr_buff_wptr,
2013                                             para_info->content.RF_REG_W.value);
2014                 PHY_PARAMETER_INFO_SET_MASK(curr_buff_wptr,
2015                                             para_info->content.RF_REG_W.msk);
2016                 PHY_PARAMETER_INFO_SET_MSK_EN(
2017                         curr_buff_wptr, para_info->content.RF_REG_W.msk_en);
2018                 config_para_info->value_accumulation +=
2019                         para_info->content.RF_REG_W.value;
2020                 config_para_info->offset_accumulation +=
2021                         (para_info->content.RF_REG_W.offset +
2022                          (para_info->content.RF_REG_W.rf_path << 8));
2023                 break;
2024         case HALMAC_PARAMETER_CMD_DELAY_US:
2025         case HALMAC_PARAMETER_CMD_DELAY_MS:
2026                 PHY_PARAMETER_INFO_SET_DELAY_VALUE(
2027                         curr_buff_wptr,
2028                         para_info->content.DELAY_TIME.delay_time);
2029                 break;
2030         case HALMAC_PARAMETER_CMD_END:
2031                 *end_cmd = true;
2032                 break;
2033         default:
2034                 pr_err(" halmac_send_h2c_phy_parameter_88xx illegal cmd_id!!\n");
2035                 break;
2036         }
2037
2038         return HALMAC_RET_SUCCESS;
2039 }
2040
2041 static enum halmac_ret_status
2042 halmac_gen_cfg_para_h2c_88xx(struct halmac_adapter *halmac_adapter,
2043                              u8 *h2c_buff)
2044 {
2045         struct halmac_config_para_info *config_para_info =
2046                 &halmac_adapter->config_para_info;
2047
2048         CFG_PARAMETER_SET_NUM(h2c_buff, config_para_info->para_num);
2049
2050         if (config_para_info->full_fifo_mode) {
2051                 CFG_PARAMETER_SET_INIT_CASE(h2c_buff, 0x1);
2052                 CFG_PARAMETER_SET_PHY_PARAMETER_LOC(h2c_buff, 0);
2053         } else {
2054                 CFG_PARAMETER_SET_INIT_CASE(h2c_buff, 0x0);
2055                 CFG_PARAMETER_SET_PHY_PARAMETER_LOC(
2056                         h2c_buff,
2057                         halmac_adapter->txff_allocation
2058                                         .rsvd_h2c_extra_info_pg_bndy -
2059                                 halmac_adapter->txff_allocation.rsvd_pg_bndy);
2060         }
2061
2062         return HALMAC_RET_SUCCESS;
2063 }
2064
2065 enum halmac_ret_status
2066 halmac_send_h2c_run_datapack_88xx(struct halmac_adapter *halmac_adapter,
2067                                   enum halmac_data_type halmac_data_type)
2068 {
2069         u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
2070         u16 h2c_seq_mum = 0;
2071         void *driver_adapter = NULL;
2072         struct halmac_h2c_header_info h2c_header_info;
2073         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2074
2075         driver_adapter = halmac_adapter->driver_adapter;
2076
2077         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2078                         "%s!!\n", __func__);
2079
2080         RUN_DATAPACK_SET_DATAPACK_ID(h2c_buff, halmac_data_type);
2081
2082         h2c_header_info.sub_cmd_id = SUB_CMD_ID_RUN_DATAPACK;
2083         h2c_header_info.content_size = 4;
2084         h2c_header_info.ack = true;
2085         halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
2086                                               &h2c_header_info, &h2c_seq_mum);
2087
2088         status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
2089                                           HALMAC_H2C_CMD_SIZE_88XX, true);
2090
2091         if (status != HALMAC_RET_SUCCESS) {
2092                 pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
2093                 return status;
2094         }
2095
2096         return HALMAC_RET_SUCCESS;
2097 }
2098
2099 enum halmac_ret_status
2100 halmac_send_bt_coex_cmd_88xx(struct halmac_adapter *halmac_adapter, u8 *bt_buf,
2101                              u32 bt_size, u8 ack)
2102 {
2103         u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
2104         u16 h2c_seq_mum = 0;
2105         void *driver_adapter = NULL;
2106         struct halmac_h2c_header_info h2c_header_info;
2107         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2108
2109         driver_adapter = halmac_adapter->driver_adapter;
2110
2111         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2112                         "%s!!\n", __func__);
2113
2114         memcpy(h2c_buff + 8, bt_buf, bt_size);
2115
2116         h2c_header_info.sub_cmd_id = SUB_CMD_ID_BT_COEX;
2117         h2c_header_info.content_size = (u16)bt_size;
2118         h2c_header_info.ack = ack;
2119         halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
2120                                               &h2c_header_info, &h2c_seq_mum);
2121
2122         status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
2123                                           HALMAC_H2C_CMD_SIZE_88XX, ack);
2124
2125         if (status != HALMAC_RET_SUCCESS) {
2126                 pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
2127                 return status;
2128         }
2129
2130         return HALMAC_RET_SUCCESS;
2131 }
2132
2133 enum halmac_ret_status
2134 halmac_func_ctrl_ch_switch_88xx(struct halmac_adapter *halmac_adapter,
2135                                 struct halmac_ch_switch_option *cs_option)
2136 {
2137         u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
2138         u16 h2c_seq_mum = 0;
2139         void *driver_adapter = NULL;
2140         struct halmac_api *halmac_api;
2141         struct halmac_h2c_header_info h2c_header_info;
2142         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2143         enum halmac_cmd_process_status *process_status =
2144                 &halmac_adapter->halmac_state.scan_state_set.process_status;
2145
2146         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2147                         "halmac_ctrl_ch_switch!!\n");
2148
2149         driver_adapter = halmac_adapter->driver_adapter;
2150         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
2151
2152         if (halmac_transition_scan_state_88xx(
2153                     halmac_adapter, HALMAC_SCAN_CMD_CONSTRUCT_H2C_SENT) !=
2154             HALMAC_RET_SUCCESS)
2155                 return HALMAC_RET_ERROR_STATE;
2156
2157         *process_status = HALMAC_CMD_PROCESS_SENDING;
2158
2159         if (cs_option->switch_en != 0) {
2160                 HALMAC_REG_WRITE_16(halmac_adapter, REG_FIFOPAGE_CTRL_2,
2161                                     (u16)(halmac_adapter->txff_allocation
2162                                                   .rsvd_h2c_extra_info_pg_bndy &
2163                                           BIT_MASK_BCN_HEAD_1_V1));
2164
2165                 status = halmac_download_rsvd_page_88xx(
2166                         halmac_adapter, halmac_adapter->ch_sw_info.ch_info_buf,
2167                         halmac_adapter->ch_sw_info.total_size);
2168
2169                 if (status != HALMAC_RET_SUCCESS) {
2170                         pr_err("halmac_download_rsvd_page_88xx Fail = %x!!\n",
2171                                status);
2172                         HALMAC_REG_WRITE_16(
2173                                 halmac_adapter, REG_FIFOPAGE_CTRL_2,
2174                                 (u16)(halmac_adapter->txff_allocation
2175                                               .rsvd_pg_bndy &
2176                                       BIT_MASK_BCN_HEAD_1_V1));
2177                         return status;
2178                 }
2179
2180                 HALMAC_REG_WRITE_16(
2181                         halmac_adapter, REG_FIFOPAGE_CTRL_2,
2182                         (u16)(halmac_adapter->txff_allocation.rsvd_pg_bndy &
2183                               BIT_MASK_BCN_HEAD_1_V1));
2184         }
2185
2186         CHANNEL_SWITCH_SET_SWITCH_START(h2c_buff, cs_option->switch_en);
2187         CHANNEL_SWITCH_SET_CHANNEL_NUM(h2c_buff,
2188                                        halmac_adapter->ch_sw_info.ch_num);
2189         CHANNEL_SWITCH_SET_CHANNEL_INFO_LOC(
2190                 h2c_buff,
2191                 halmac_adapter->txff_allocation.rsvd_h2c_extra_info_pg_bndy -
2192                         halmac_adapter->txff_allocation.rsvd_pg_bndy);
2193         CHANNEL_SWITCH_SET_DEST_CH_EN(h2c_buff, cs_option->dest_ch_en);
2194         CHANNEL_SWITCH_SET_DEST_CH(h2c_buff, cs_option->dest_ch);
2195         CHANNEL_SWITCH_SET_PRI_CH_IDX(h2c_buff, cs_option->dest_pri_ch_idx);
2196         CHANNEL_SWITCH_SET_ABSOLUTE_TIME(h2c_buff, cs_option->absolute_time_en);
2197         CHANNEL_SWITCH_SET_TSF_LOW(h2c_buff, cs_option->tsf_low);
2198         CHANNEL_SWITCH_SET_PERIODIC_OPTION(h2c_buff,
2199                                            cs_option->periodic_option);
2200         CHANNEL_SWITCH_SET_NORMAL_CYCLE(h2c_buff, cs_option->normal_cycle);
2201         CHANNEL_SWITCH_SET_NORMAL_PERIOD(h2c_buff, cs_option->normal_period);
2202         CHANNEL_SWITCH_SET_SLOW_PERIOD(h2c_buff, cs_option->phase_2_period);
2203         CHANNEL_SWITCH_SET_CHANNEL_INFO_SIZE(
2204                 h2c_buff, halmac_adapter->ch_sw_info.total_size);
2205
2206         h2c_header_info.sub_cmd_id = SUB_CMD_ID_CHANNEL_SWITCH;
2207         h2c_header_info.content_size = 20;
2208         h2c_header_info.ack = true;
2209         halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
2210                                               &h2c_header_info, &h2c_seq_mum);
2211         halmac_adapter->halmac_state.scan_state_set.seq_num = h2c_seq_mum;
2212
2213         status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
2214                                           HALMAC_H2C_CMD_SIZE_88XX, true);
2215
2216         if (status != HALMAC_RET_SUCCESS)
2217                 pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
2218
2219         kfree(halmac_adapter->ch_sw_info.ch_info_buf);
2220         halmac_adapter->ch_sw_info.ch_info_buf = NULL;
2221         halmac_adapter->ch_sw_info.ch_info_buf_w = NULL;
2222         halmac_adapter->ch_sw_info.extra_info_en = 0;
2223         halmac_adapter->ch_sw_info.buf_size = 0;
2224         halmac_adapter->ch_sw_info.avai_buf_size = 0;
2225         halmac_adapter->ch_sw_info.total_size = 0;
2226         halmac_adapter->ch_sw_info.ch_num = 0;
2227
2228         if (halmac_transition_scan_state_88xx(halmac_adapter,
2229                                               HALMAC_SCAN_CMD_CONSTRUCT_IDLE) !=
2230             HALMAC_RET_SUCCESS)
2231                 return HALMAC_RET_ERROR_STATE;
2232
2233         return status;
2234 }
2235
2236 enum halmac_ret_status
2237 halmac_func_send_general_info_88xx(struct halmac_adapter *halmac_adapter,
2238                                    struct halmac_general_info *general_info)
2239 {
2240         u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
2241         u16 h2c_seq_mum = 0;
2242         void *driver_adapter = NULL;
2243         struct halmac_h2c_header_info h2c_header_info;
2244         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2245
2246         driver_adapter = halmac_adapter->driver_adapter;
2247
2248         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2249                         "halmac_send_general_info!!\n");
2250
2251         GENERAL_INFO_SET_REF_TYPE(h2c_buff, general_info->rfe_type);
2252         GENERAL_INFO_SET_RF_TYPE(h2c_buff, general_info->rf_type);
2253         GENERAL_INFO_SET_FW_TX_BOUNDARY(
2254                 h2c_buff,
2255                 halmac_adapter->txff_allocation.rsvd_fw_txbuff_pg_bndy -
2256                         halmac_adapter->txff_allocation.rsvd_pg_bndy);
2257
2258         h2c_header_info.sub_cmd_id = SUB_CMD_ID_GENERAL_INFO;
2259         h2c_header_info.content_size = 4;
2260         h2c_header_info.ack = false;
2261         halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
2262                                               &h2c_header_info, &h2c_seq_mum);
2263
2264         status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
2265                                           HALMAC_H2C_CMD_SIZE_88XX, true);
2266
2267         if (status != HALMAC_RET_SUCCESS)
2268                 pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
2269
2270         return status;
2271 }
2272
2273 enum halmac_ret_status halmac_send_h2c_update_bcn_parse_info_88xx(
2274         struct halmac_adapter *halmac_adapter,
2275         struct halmac_bcn_ie_info *bcn_ie_info)
2276 {
2277         u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
2278         u16 h2c_seq_mum = 0;
2279         void *driver_adapter = NULL;
2280         struct halmac_h2c_header_info h2c_header_info;
2281         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2282
2283         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2284                         "%s!!\n", __func__);
2285
2286         driver_adapter = halmac_adapter->driver_adapter;
2287
2288         UPDATE_BEACON_PARSING_INFO_SET_FUNC_EN(h2c_buff, bcn_ie_info->func_en);
2289         UPDATE_BEACON_PARSING_INFO_SET_SIZE_TH(h2c_buff, bcn_ie_info->size_th);
2290         UPDATE_BEACON_PARSING_INFO_SET_TIMEOUT(h2c_buff, bcn_ie_info->timeout);
2291
2292         UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_0(
2293                 h2c_buff, (u32)(bcn_ie_info->ie_bmp[0]));
2294         UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_1(
2295                 h2c_buff, (u32)(bcn_ie_info->ie_bmp[1]));
2296         UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_2(
2297                 h2c_buff, (u32)(bcn_ie_info->ie_bmp[2]));
2298         UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_3(
2299                 h2c_buff, (u32)(bcn_ie_info->ie_bmp[3]));
2300         UPDATE_BEACON_PARSING_INFO_SET_IE_ID_BMP_4(
2301                 h2c_buff, (u32)(bcn_ie_info->ie_bmp[4]));
2302
2303         h2c_header_info.sub_cmd_id = SUB_CMD_ID_UPDATE_BEACON_PARSING_INFO;
2304         h2c_header_info.content_size = 24;
2305         h2c_header_info.ack = true;
2306         halmac_set_fw_offload_h2c_header_88xx(halmac_adapter, h2c_buff,
2307                                               &h2c_header_info, &h2c_seq_mum);
2308
2309         status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
2310                                           HALMAC_H2C_CMD_SIZE_88XX, true);
2311
2312         if (status != HALMAC_RET_SUCCESS) {
2313                 pr_err("halmac_send_h2c_pkt_88xx Fail =%x !!\n", status);
2314                 return status;
2315         }
2316
2317         return status;
2318 }
2319
2320 enum halmac_ret_status
2321 halmac_send_h2c_ps_tuning_para_88xx(struct halmac_adapter *halmac_adapter)
2322 {
2323         u8 h2c_buff[HALMAC_H2C_CMD_SIZE_88XX] = {0};
2324         u8 *h2c_header, *h2c_cmd;
2325         u16 seq = 0;
2326         void *driver_adapter = NULL;
2327         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2328
2329         driver_adapter = halmac_adapter->driver_adapter;
2330
2331         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2332                         "%s!!\n", __func__);
2333
2334         h2c_header = h2c_buff;
2335         h2c_cmd = h2c_header + HALMAC_H2C_CMD_HDR_SIZE_88XX;
2336
2337         halmac_set_h2c_header_88xx(halmac_adapter, h2c_header, &seq, false);
2338
2339         status = halmac_send_h2c_pkt_88xx(halmac_adapter, h2c_buff,
2340                                           HALMAC_H2C_CMD_SIZE_88XX, false);
2341
2342         if (status != HALMAC_RET_SUCCESS) {
2343                 pr_err("halmac_send_h2c_pkt_88xx Fail = %x!!\n", status);
2344                 return status;
2345         }
2346
2347         return status;
2348 }
2349
2350 enum halmac_ret_status
2351 halmac_parse_c2h_packet_88xx(struct halmac_adapter *halmac_adapter,
2352                              u8 *halmac_buf, u32 halmac_size)
2353 {
2354         u8 c2h_cmd, c2h_sub_cmd_id;
2355         u8 *c2h_buf = halmac_buf + halmac_adapter->hw_config_info.rxdesc_size;
2356         u32 c2h_size = halmac_size - halmac_adapter->hw_config_info.rxdesc_size;
2357         void *driver_adapter = halmac_adapter->driver_adapter;
2358         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2359
2360         c2h_cmd = (u8)C2H_HDR_GET_CMD_ID(c2h_buf);
2361
2362         /* FW offload C2H cmd is 0xFF */
2363         if (c2h_cmd != 0xFF) {
2364                 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2365                                 "C2H_PKT not for FwOffloadC2HFormat!!\n");
2366                 return HALMAC_RET_C2H_NOT_HANDLED;
2367         }
2368
2369         /* Get C2H sub cmd ID */
2370         c2h_sub_cmd_id = (u8)C2H_HDR_GET_C2H_SUB_CMD_ID(c2h_buf);
2371
2372         switch (c2h_sub_cmd_id) {
2373         case C2H_SUB_CMD_ID_C2H_DBG:
2374                 status = halmac_parse_c2h_debug_88xx(halmac_adapter, c2h_buf,
2375                                                      c2h_size);
2376                 break;
2377         case C2H_SUB_CMD_ID_H2C_ACK_HDR:
2378                 status = halmac_parse_h2c_ack_88xx(halmac_adapter, c2h_buf,
2379                                                    c2h_size);
2380                 break;
2381         case C2H_SUB_CMD_ID_BT_COEX_INFO:
2382                 status = HALMAC_RET_C2H_NOT_HANDLED;
2383                 break;
2384         case C2H_SUB_CMD_ID_SCAN_STATUS_RPT:
2385                 status = halmac_parse_scan_status_rpt_88xx(halmac_adapter,
2386                                                            c2h_buf, c2h_size);
2387                 break;
2388         case C2H_SUB_CMD_ID_PSD_DATA:
2389                 status = halmac_parse_psd_data_88xx(halmac_adapter, c2h_buf,
2390                                                     c2h_size);
2391                 break;
2392
2393         case C2H_SUB_CMD_ID_EFUSE_DATA:
2394                 status = halmac_parse_efuse_data_88xx(halmac_adapter, c2h_buf,
2395                                                       c2h_size);
2396                 break;
2397         default:
2398                 pr_err("c2h_sub_cmd_id switch case out of boundary!!\n");
2399                 pr_err("[ERR]c2h pkt : %.8X %.8X!!\n", *(u32 *)c2h_buf,
2400                        *(u32 *)(c2h_buf + 4));
2401                 status = HALMAC_RET_C2H_NOT_HANDLED;
2402                 break;
2403         }
2404
2405         return status;
2406 }
2407
2408 static enum halmac_ret_status
2409 halmac_parse_c2h_debug_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
2410                             u32 c2h_size)
2411 {
2412         void *driver_adapter = NULL;
2413         u8 *c2h_buf_local = (u8 *)NULL;
2414         u32 c2h_size_local = 0;
2415         u8 dbg_content_length = 0;
2416         u8 dbg_seq_num = 0;
2417
2418         driver_adapter = halmac_adapter->driver_adapter;
2419         c2h_buf_local = c2h_buf;
2420         c2h_size_local = c2h_size;
2421
2422         dbg_content_length = (u8)C2H_HDR_GET_LEN((u8 *)c2h_buf_local);
2423
2424         if (dbg_content_length > C2H_DBG_CONTENT_MAX_LENGTH)
2425                 return HALMAC_RET_SUCCESS;
2426
2427         *(c2h_buf_local + C2H_DBG_HEADER_LENGTH + dbg_content_length - 2) =
2428                 '\n';
2429         dbg_seq_num = (u8)(*(c2h_buf_local + C2H_DBG_HEADER_LENGTH));
2430         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2431                         "[RTKFW, SEQ=%d]: %s", dbg_seq_num,
2432                         (char *)(c2h_buf_local + C2H_DBG_HEADER_LENGTH + 1));
2433
2434         return HALMAC_RET_SUCCESS;
2435 }
2436
2437 static enum halmac_ret_status
2438 halmac_parse_scan_status_rpt_88xx(struct halmac_adapter *halmac_adapter,
2439                                   u8 *c2h_buf, u32 c2h_size)
2440 {
2441         u8 h2c_return_code;
2442         void *driver_adapter = halmac_adapter->driver_adapter;
2443         enum halmac_cmd_process_status process_status;
2444
2445         h2c_return_code = (u8)SCAN_STATUS_RPT_GET_H2C_RETURN_CODE(c2h_buf);
2446         process_status = (enum halmac_h2c_return_code)h2c_return_code ==
2447                                          HALMAC_H2C_RETURN_SUCCESS ?
2448                                  HALMAC_CMD_PROCESS_DONE :
2449                                  HALMAC_CMD_PROCESS_ERROR;
2450
2451         PLATFORM_EVENT_INDICATION(driver_adapter, HALMAC_FEATURE_CHANNEL_SWITCH,
2452                                   process_status, NULL, 0);
2453
2454         halmac_adapter->halmac_state.scan_state_set.process_status =
2455                 process_status;
2456
2457         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2458                         "[TRACE]scan status : %X\n", process_status);
2459
2460         return HALMAC_RET_SUCCESS;
2461 }
2462
2463 static enum halmac_ret_status
2464 halmac_parse_psd_data_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
2465                            u32 c2h_size)
2466 {
2467         u8 segment_id = 0, segment_size = 0, h2c_seq = 0;
2468         u16 total_size;
2469         void *driver_adapter = halmac_adapter->driver_adapter;
2470         enum halmac_cmd_process_status process_status;
2471         struct halmac_psd_state_set *psd_set =
2472                 &halmac_adapter->halmac_state.psd_set;
2473
2474         h2c_seq = (u8)PSD_DATA_GET_H2C_SEQ(c2h_buf);
2475         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2476                         "[TRACE]Seq num : h2c -> %d c2h -> %d\n",
2477                         psd_set->seq_num, h2c_seq);
2478         if (h2c_seq != psd_set->seq_num) {
2479                 pr_err("[ERR]Seq num mismatch : h2c -> %d c2h -> %d\n",
2480                        psd_set->seq_num, h2c_seq);
2481                 return HALMAC_RET_SUCCESS;
2482         }
2483
2484         if (psd_set->process_status != HALMAC_CMD_PROCESS_SENDING) {
2485                 pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
2486                 return HALMAC_RET_SUCCESS;
2487         }
2488
2489         total_size = (u16)PSD_DATA_GET_TOTAL_SIZE(c2h_buf);
2490         segment_id = (u8)PSD_DATA_GET_SEGMENT_ID(c2h_buf);
2491         segment_size = (u8)PSD_DATA_GET_SEGMENT_SIZE(c2h_buf);
2492         psd_set->data_size = total_size;
2493
2494         if (!psd_set->data)
2495                 psd_set->data = kzalloc(psd_set->data_size, GFP_KERNEL);
2496
2497         if (segment_id == 0)
2498                 psd_set->segment_size = segment_size;
2499
2500         memcpy(psd_set->data + segment_id * psd_set->segment_size,
2501                c2h_buf + HALMAC_C2H_DATA_OFFSET_88XX, segment_size);
2502
2503         if (!PSD_DATA_GET_END_SEGMENT(c2h_buf))
2504                 return HALMAC_RET_SUCCESS;
2505
2506         process_status = HALMAC_CMD_PROCESS_DONE;
2507         psd_set->process_status = process_status;
2508
2509         PLATFORM_EVENT_INDICATION(driver_adapter, HALMAC_FEATURE_PSD,
2510                                   process_status, psd_set->data,
2511                                   psd_set->data_size);
2512
2513         return HALMAC_RET_SUCCESS;
2514 }
2515
2516 static enum halmac_ret_status
2517 halmac_parse_efuse_data_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
2518                              u32 c2h_size)
2519 {
2520         u8 segment_id = 0, segment_size = 0, h2c_seq = 0;
2521         u8 *eeprom_map = NULL;
2522         u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
2523         u8 h2c_return_code = 0;
2524         void *driver_adapter = halmac_adapter->driver_adapter;
2525         enum halmac_cmd_process_status process_status;
2526
2527         h2c_seq = (u8)EFUSE_DATA_GET_H2C_SEQ(c2h_buf);
2528         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2529                         "[TRACE]Seq num : h2c -> %d c2h -> %d\n",
2530                         halmac_adapter->halmac_state.efuse_state_set.seq_num,
2531                         h2c_seq);
2532         if (h2c_seq != halmac_adapter->halmac_state.efuse_state_set.seq_num) {
2533                 pr_err("[ERR]Seq num mismatch : h2c -> %d c2h -> %d\n",
2534                        halmac_adapter->halmac_state.efuse_state_set.seq_num,
2535                        h2c_seq);
2536                 return HALMAC_RET_SUCCESS;
2537         }
2538
2539         if (halmac_adapter->halmac_state.efuse_state_set.process_status !=
2540             HALMAC_CMD_PROCESS_SENDING) {
2541                 pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
2542                 return HALMAC_RET_SUCCESS;
2543         }
2544
2545         segment_id = (u8)EFUSE_DATA_GET_SEGMENT_ID(c2h_buf);
2546         segment_size = (u8)EFUSE_DATA_GET_SEGMENT_SIZE(c2h_buf);
2547         if (segment_id == 0)
2548                 halmac_adapter->efuse_segment_size = segment_size;
2549
2550         eeprom_map = kzalloc(eeprom_size, GFP_KERNEL);
2551         if (!eeprom_map) {
2552                 /* out of memory */
2553                 return HALMAC_RET_MALLOC_FAIL;
2554         }
2555         memset(eeprom_map, 0xFF, eeprom_size);
2556
2557         spin_lock(&halmac_adapter->efuse_lock);
2558         memcpy(halmac_adapter->hal_efuse_map +
2559                        segment_id * halmac_adapter->efuse_segment_size,
2560                c2h_buf + HALMAC_C2H_DATA_OFFSET_88XX, segment_size);
2561         spin_unlock(&halmac_adapter->efuse_lock);
2562
2563         if (!EFUSE_DATA_GET_END_SEGMENT(c2h_buf)) {
2564                 kfree(eeprom_map);
2565                 return HALMAC_RET_SUCCESS;
2566         }
2567
2568         h2c_return_code =
2569                 halmac_adapter->halmac_state.efuse_state_set.fw_return_code;
2570
2571         if ((enum halmac_h2c_return_code)h2c_return_code ==
2572             HALMAC_H2C_RETURN_SUCCESS) {
2573                 process_status = HALMAC_CMD_PROCESS_DONE;
2574                 halmac_adapter->halmac_state.efuse_state_set.process_status =
2575                         process_status;
2576
2577                 spin_lock(&halmac_adapter->efuse_lock);
2578                 halmac_adapter->hal_efuse_map_valid = true;
2579                 spin_unlock(&halmac_adapter->efuse_lock);
2580
2581                 if (halmac_adapter->event_trigger.physical_efuse_map == 1) {
2582                         PLATFORM_EVENT_INDICATION(
2583                                 driver_adapter,
2584                                 HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE,
2585                                 process_status, halmac_adapter->hal_efuse_map,
2586                                 halmac_adapter->hw_config_info.efuse_size);
2587                         halmac_adapter->event_trigger.physical_efuse_map = 0;
2588                 }
2589
2590                 if (halmac_adapter->event_trigger.logical_efuse_map == 1) {
2591                         if (halmac_eeprom_parser_88xx(
2592                                     halmac_adapter,
2593                                     halmac_adapter->hal_efuse_map,
2594                                     eeprom_map) != HALMAC_RET_SUCCESS) {
2595                                 kfree(eeprom_map);
2596                                 return HALMAC_RET_EEPROM_PARSING_FAIL;
2597                         }
2598                         PLATFORM_EVENT_INDICATION(
2599                                 driver_adapter,
2600                                 HALMAC_FEATURE_DUMP_LOGICAL_EFUSE,
2601                                 process_status, eeprom_map, eeprom_size);
2602                         halmac_adapter->event_trigger.logical_efuse_map = 0;
2603                 }
2604         } else {
2605                 process_status = HALMAC_CMD_PROCESS_ERROR;
2606                 halmac_adapter->halmac_state.efuse_state_set.process_status =
2607                         process_status;
2608
2609                 if (halmac_adapter->event_trigger.physical_efuse_map == 1) {
2610                         PLATFORM_EVENT_INDICATION(
2611                                 driver_adapter,
2612                                 HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE,
2613                                 process_status,
2614                                 &halmac_adapter->halmac_state.efuse_state_set
2615                                          .fw_return_code,
2616                                 1);
2617                         halmac_adapter->event_trigger.physical_efuse_map = 0;
2618                 }
2619
2620                 if (halmac_adapter->event_trigger.logical_efuse_map == 1) {
2621                         if (halmac_eeprom_parser_88xx(
2622                                     halmac_adapter,
2623                                     halmac_adapter->hal_efuse_map,
2624                                     eeprom_map) != HALMAC_RET_SUCCESS) {
2625                                 kfree(eeprom_map);
2626                                 return HALMAC_RET_EEPROM_PARSING_FAIL;
2627                         }
2628                         PLATFORM_EVENT_INDICATION(
2629                                 driver_adapter,
2630                                 HALMAC_FEATURE_DUMP_LOGICAL_EFUSE,
2631                                 process_status,
2632                                 &halmac_adapter->halmac_state.efuse_state_set
2633                                          .fw_return_code,
2634                                 1);
2635                         halmac_adapter->event_trigger.logical_efuse_map = 0;
2636                 }
2637         }
2638
2639         kfree(eeprom_map);
2640
2641         return HALMAC_RET_SUCCESS;
2642 }
2643
2644 static enum halmac_ret_status
2645 halmac_parse_h2c_ack_88xx(struct halmac_adapter *halmac_adapter, u8 *c2h_buf,
2646                           u32 c2h_size)
2647 {
2648         u8 h2c_cmd_id, h2c_sub_cmd_id;
2649         u8 h2c_return_code;
2650         void *driver_adapter = halmac_adapter->driver_adapter;
2651         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2652
2653         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2654                         "Ack for C2H!!\n");
2655
2656         h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
2657         if ((enum halmac_h2c_return_code)h2c_return_code !=
2658             HALMAC_H2C_RETURN_SUCCESS)
2659                 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2660                                 "C2H_PKT Status Error!! Status = %d\n",
2661                                 h2c_return_code);
2662
2663         h2c_cmd_id = (u8)H2C_ACK_HDR_GET_H2C_CMD_ID(c2h_buf);
2664
2665         if (h2c_cmd_id != 0xFF) {
2666                 pr_err("original h2c ack is not handled!!\n");
2667                 status = HALMAC_RET_C2H_NOT_HANDLED;
2668         } else {
2669                 h2c_sub_cmd_id = (u8)H2C_ACK_HDR_GET_H2C_SUB_CMD_ID(c2h_buf);
2670
2671                 switch (h2c_sub_cmd_id) {
2672                 case H2C_SUB_CMD_ID_DUMP_PHYSICAL_EFUSE_ACK:
2673                         status = halmac_parse_h2c_ack_phy_efuse_88xx(
2674                                 halmac_adapter, c2h_buf, c2h_size);
2675                         break;
2676                 case H2C_SUB_CMD_ID_CFG_PARAMETER_ACK:
2677                         status = halmac_parse_h2c_ack_cfg_para_88xx(
2678                                 halmac_adapter, c2h_buf, c2h_size);
2679                         break;
2680                 case H2C_SUB_CMD_ID_UPDATE_PACKET_ACK:
2681                         status = halmac_parse_h2c_ack_update_packet_88xx(
2682                                 halmac_adapter, c2h_buf, c2h_size);
2683                         break;
2684                 case H2C_SUB_CMD_ID_UPDATE_DATAPACK_ACK:
2685                         status = halmac_parse_h2c_ack_update_datapack_88xx(
2686                                 halmac_adapter, c2h_buf, c2h_size);
2687                         break;
2688                 case H2C_SUB_CMD_ID_RUN_DATAPACK_ACK:
2689                         status = halmac_parse_h2c_ack_run_datapack_88xx(
2690                                 halmac_adapter, c2h_buf, c2h_size);
2691                         break;
2692                 case H2C_SUB_CMD_ID_CHANNEL_SWITCH_ACK:
2693                         status = halmac_parse_h2c_ack_channel_switch_88xx(
2694                                 halmac_adapter, c2h_buf, c2h_size);
2695                         break;
2696                 case H2C_SUB_CMD_ID_IQK_ACK:
2697                         status = halmac_parse_h2c_ack_iqk_88xx(
2698                                 halmac_adapter, c2h_buf, c2h_size);
2699                         break;
2700                 case H2C_SUB_CMD_ID_POWER_TRACKING_ACK:
2701                         status = halmac_parse_h2c_ack_power_tracking_88xx(
2702                                 halmac_adapter, c2h_buf, c2h_size);
2703                         break;
2704                 case H2C_SUB_CMD_ID_PSD_ACK:
2705                         break;
2706                 default:
2707                         pr_err("h2c_sub_cmd_id switch case out of boundary!!\n");
2708                         status = HALMAC_RET_C2H_NOT_HANDLED;
2709                         break;
2710                 }
2711         }
2712
2713         return status;
2714 }
2715
2716 static enum halmac_ret_status
2717 halmac_parse_h2c_ack_phy_efuse_88xx(struct halmac_adapter *halmac_adapter,
2718                                     u8 *c2h_buf, u32 c2h_size)
2719 {
2720         u8 h2c_seq = 0;
2721         u8 h2c_return_code;
2722         void *driver_adapter = halmac_adapter->driver_adapter;
2723
2724         h2c_seq = (u8)H2C_ACK_HDR_GET_H2C_SEQ(c2h_buf);
2725         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2726                         "[TRACE]Seq num : h2c -> %d c2h -> %d\n",
2727                         halmac_adapter->halmac_state.efuse_state_set.seq_num,
2728                         h2c_seq);
2729         if (h2c_seq != halmac_adapter->halmac_state.efuse_state_set.seq_num) {
2730                 pr_err("[ERR]Seq num mismatch : h2c -> %d c2h -> %d\n",
2731                        halmac_adapter->halmac_state.efuse_state_set.seq_num,
2732                        h2c_seq);
2733                 return HALMAC_RET_SUCCESS;
2734         }
2735
2736         if (halmac_adapter->halmac_state.efuse_state_set.process_status !=
2737             HALMAC_CMD_PROCESS_SENDING) {
2738                 pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
2739                 return HALMAC_RET_SUCCESS;
2740         }
2741
2742         h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
2743         halmac_adapter->halmac_state.efuse_state_set.fw_return_code =
2744                 h2c_return_code;
2745
2746         return HALMAC_RET_SUCCESS;
2747 }
2748
2749 static enum halmac_ret_status
2750 halmac_parse_h2c_ack_cfg_para_88xx(struct halmac_adapter *halmac_adapter,
2751                                    u8 *c2h_buf, u32 c2h_size)
2752 {
2753         u8 h2c_seq = 0;
2754         u8 h2c_return_code;
2755         u32 offset_accu = 0, value_accu = 0;
2756         void *driver_adapter = halmac_adapter->driver_adapter;
2757         enum halmac_cmd_process_status process_status =
2758                 HALMAC_CMD_PROCESS_UNDEFINE;
2759
2760         h2c_seq = (u8)H2C_ACK_HDR_GET_H2C_SEQ(c2h_buf);
2761         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2762                         "Seq num : h2c -> %d c2h -> %d\n",
2763                         halmac_adapter->halmac_state.cfg_para_state_set.seq_num,
2764                         h2c_seq);
2765         if (h2c_seq !=
2766             halmac_adapter->halmac_state.cfg_para_state_set.seq_num) {
2767                 pr_err("Seq num mismatch : h2c -> %d c2h -> %d\n",
2768                        halmac_adapter->halmac_state.cfg_para_state_set.seq_num,
2769                        h2c_seq);
2770                 return HALMAC_RET_SUCCESS;
2771         }
2772
2773         if (halmac_adapter->halmac_state.cfg_para_state_set.process_status !=
2774             HALMAC_CMD_PROCESS_SENDING) {
2775                 pr_err("Not in HALMAC_CMD_PROCESS_SENDING\n");
2776                 return HALMAC_RET_SUCCESS;
2777         }
2778
2779         h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
2780         halmac_adapter->halmac_state.cfg_para_state_set.fw_return_code =
2781                 h2c_return_code;
2782         offset_accu = CFG_PARAMETER_ACK_GET_OFFSET_ACCUMULATION(c2h_buf);
2783         value_accu = CFG_PARAMETER_ACK_GET_VALUE_ACCUMULATION(c2h_buf);
2784
2785         if ((offset_accu !=
2786              halmac_adapter->config_para_info.offset_accumulation) ||
2787             (value_accu !=
2788              halmac_adapter->config_para_info.value_accumulation)) {
2789                 pr_err("[C2H]offset_accu : %x, value_accu : %x!!\n",
2790                        offset_accu, value_accu);
2791                 pr_err("[Adapter]offset_accu : %x, value_accu : %x!!\n",
2792                        halmac_adapter->config_para_info.offset_accumulation,
2793                        halmac_adapter->config_para_info.value_accumulation);
2794                 process_status = HALMAC_CMD_PROCESS_ERROR;
2795         }
2796
2797         if ((enum halmac_h2c_return_code)h2c_return_code ==
2798                     HALMAC_H2C_RETURN_SUCCESS &&
2799             process_status != HALMAC_CMD_PROCESS_ERROR) {
2800                 process_status = HALMAC_CMD_PROCESS_DONE;
2801                 halmac_adapter->halmac_state.cfg_para_state_set.process_status =
2802                         process_status;
2803                 PLATFORM_EVENT_INDICATION(driver_adapter,
2804                                           HALMAC_FEATURE_CFG_PARA,
2805                                           process_status, NULL, 0);
2806         } else {
2807                 process_status = HALMAC_CMD_PROCESS_ERROR;
2808                 halmac_adapter->halmac_state.cfg_para_state_set.process_status =
2809                         process_status;
2810                 PLATFORM_EVENT_INDICATION(
2811                         driver_adapter, HALMAC_FEATURE_CFG_PARA, process_status,
2812                         &halmac_adapter->halmac_state.cfg_para_state_set
2813                                  .fw_return_code,
2814                         1);
2815         }
2816
2817         return HALMAC_RET_SUCCESS;
2818 }
2819
2820 static enum halmac_ret_status
2821 halmac_parse_h2c_ack_update_packet_88xx(struct halmac_adapter *halmac_adapter,
2822                                         u8 *c2h_buf, u32 c2h_size)
2823 {
2824         u8 h2c_seq = 0;
2825         u8 h2c_return_code;
2826         void *driver_adapter = halmac_adapter->driver_adapter;
2827         enum halmac_cmd_process_status process_status;
2828
2829         h2c_seq = (u8)H2C_ACK_HDR_GET_H2C_SEQ(c2h_buf);
2830         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2831                         "[TRACE]Seq num : h2c -> %d c2h -> %d\n",
2832                         halmac_adapter->halmac_state.update_packet_set.seq_num,
2833                         h2c_seq);
2834         if (h2c_seq != halmac_adapter->halmac_state.update_packet_set.seq_num) {
2835                 pr_err("[ERR]Seq num mismatch : h2c -> %d c2h -> %d\n",
2836                        halmac_adapter->halmac_state.update_packet_set.seq_num,
2837                        h2c_seq);
2838                 return HALMAC_RET_SUCCESS;
2839         }
2840
2841         if (halmac_adapter->halmac_state.update_packet_set.process_status !=
2842             HALMAC_CMD_PROCESS_SENDING) {
2843                 pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
2844                 return HALMAC_RET_SUCCESS;
2845         }
2846
2847         h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
2848         halmac_adapter->halmac_state.update_packet_set.fw_return_code =
2849                 h2c_return_code;
2850
2851         if ((enum halmac_h2c_return_code)h2c_return_code ==
2852             HALMAC_H2C_RETURN_SUCCESS) {
2853                 process_status = HALMAC_CMD_PROCESS_DONE;
2854                 halmac_adapter->halmac_state.update_packet_set.process_status =
2855                         process_status;
2856                 PLATFORM_EVENT_INDICATION(driver_adapter,
2857                                           HALMAC_FEATURE_UPDATE_PACKET,
2858                                           process_status, NULL, 0);
2859         } else {
2860                 process_status = HALMAC_CMD_PROCESS_ERROR;
2861                 halmac_adapter->halmac_state.update_packet_set.process_status =
2862                         process_status;
2863                 PLATFORM_EVENT_INDICATION(
2864                         driver_adapter, HALMAC_FEATURE_UPDATE_PACKET,
2865                         process_status,
2866                         &halmac_adapter->halmac_state.update_packet_set
2867                                  .fw_return_code,
2868                         1);
2869         }
2870
2871         return HALMAC_RET_SUCCESS;
2872 }
2873
2874 static enum halmac_ret_status
2875 halmac_parse_h2c_ack_update_datapack_88xx(struct halmac_adapter *halmac_adapter,
2876                                           u8 *c2h_buf, u32 c2h_size)
2877 {
2878         void *driver_adapter = halmac_adapter->driver_adapter;
2879         enum halmac_cmd_process_status process_status =
2880                 HALMAC_CMD_PROCESS_UNDEFINE;
2881
2882         PLATFORM_EVENT_INDICATION(driver_adapter,
2883                                   HALMAC_FEATURE_UPDATE_DATAPACK,
2884                                   process_status, NULL, 0);
2885
2886         return HALMAC_RET_SUCCESS;
2887 }
2888
2889 static enum halmac_ret_status
2890 halmac_parse_h2c_ack_run_datapack_88xx(struct halmac_adapter *halmac_adapter,
2891                                        u8 *c2h_buf, u32 c2h_size)
2892 {
2893         void *driver_adapter = halmac_adapter->driver_adapter;
2894         enum halmac_cmd_process_status process_status =
2895                 HALMAC_CMD_PROCESS_UNDEFINE;
2896
2897         PLATFORM_EVENT_INDICATION(driver_adapter, HALMAC_FEATURE_RUN_DATAPACK,
2898                                   process_status, NULL, 0);
2899
2900         return HALMAC_RET_SUCCESS;
2901 }
2902
2903 static enum halmac_ret_status
2904 halmac_parse_h2c_ack_channel_switch_88xx(struct halmac_adapter *halmac_adapter,
2905                                          u8 *c2h_buf, u32 c2h_size)
2906 {
2907         u8 h2c_seq = 0;
2908         u8 h2c_return_code;
2909         void *driver_adapter = halmac_adapter->driver_adapter;
2910         enum halmac_cmd_process_status process_status;
2911
2912         h2c_seq = (u8)H2C_ACK_HDR_GET_H2C_SEQ(c2h_buf);
2913         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2914                         "[TRACE]Seq num : h2c -> %d c2h -> %d\n",
2915                         halmac_adapter->halmac_state.scan_state_set.seq_num,
2916                         h2c_seq);
2917         if (h2c_seq != halmac_adapter->halmac_state.scan_state_set.seq_num) {
2918                 pr_err("[ERR]Seq num misactch : h2c -> %d c2h -> %d\n",
2919                        halmac_adapter->halmac_state.scan_state_set.seq_num,
2920                        h2c_seq);
2921                 return HALMAC_RET_SUCCESS;
2922         }
2923
2924         if (halmac_adapter->halmac_state.scan_state_set.process_status !=
2925             HALMAC_CMD_PROCESS_SENDING) {
2926                 pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
2927                 return HALMAC_RET_SUCCESS;
2928         }
2929
2930         h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
2931         halmac_adapter->halmac_state.scan_state_set.fw_return_code =
2932                 h2c_return_code;
2933
2934         if ((enum halmac_h2c_return_code)h2c_return_code ==
2935             HALMAC_H2C_RETURN_SUCCESS) {
2936                 process_status = HALMAC_CMD_PROCESS_RCVD;
2937                 halmac_adapter->halmac_state.scan_state_set.process_status =
2938                         process_status;
2939                 PLATFORM_EVENT_INDICATION(driver_adapter,
2940                                           HALMAC_FEATURE_CHANNEL_SWITCH,
2941                                           process_status, NULL, 0);
2942         } else {
2943                 process_status = HALMAC_CMD_PROCESS_ERROR;
2944                 halmac_adapter->halmac_state.scan_state_set.process_status =
2945                         process_status;
2946                 PLATFORM_EVENT_INDICATION(
2947                         driver_adapter, HALMAC_FEATURE_CHANNEL_SWITCH,
2948                         process_status, &halmac_adapter->halmac_state
2949                                                  .scan_state_set.fw_return_code,
2950                         1);
2951         }
2952
2953         return HALMAC_RET_SUCCESS;
2954 }
2955
2956 static enum halmac_ret_status
2957 halmac_parse_h2c_ack_iqk_88xx(struct halmac_adapter *halmac_adapter,
2958                               u8 *c2h_buf, u32 c2h_size)
2959 {
2960         u8 h2c_seq = 0;
2961         u8 h2c_return_code;
2962         void *driver_adapter = halmac_adapter->driver_adapter;
2963         enum halmac_cmd_process_status process_status;
2964
2965         h2c_seq = (u8)H2C_ACK_HDR_GET_H2C_SEQ(c2h_buf);
2966         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
2967                         "[TRACE]Seq num : h2c -> %d c2h -> %d\n",
2968                         halmac_adapter->halmac_state.iqk_set.seq_num, h2c_seq);
2969         if (h2c_seq != halmac_adapter->halmac_state.iqk_set.seq_num) {
2970                 pr_err("[ERR]Seq num misactch : h2c -> %d c2h -> %d\n",
2971                        halmac_adapter->halmac_state.iqk_set.seq_num, h2c_seq);
2972                 return HALMAC_RET_SUCCESS;
2973         }
2974
2975         if (halmac_adapter->halmac_state.iqk_set.process_status !=
2976             HALMAC_CMD_PROCESS_SENDING) {
2977                 pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
2978                 return HALMAC_RET_SUCCESS;
2979         }
2980
2981         h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
2982         halmac_adapter->halmac_state.iqk_set.fw_return_code = h2c_return_code;
2983
2984         if ((enum halmac_h2c_return_code)h2c_return_code ==
2985             HALMAC_H2C_RETURN_SUCCESS) {
2986                 process_status = HALMAC_CMD_PROCESS_DONE;
2987                 halmac_adapter->halmac_state.iqk_set.process_status =
2988                         process_status;
2989                 PLATFORM_EVENT_INDICATION(driver_adapter, HALMAC_FEATURE_IQK,
2990                                           process_status, NULL, 0);
2991         } else {
2992                 process_status = HALMAC_CMD_PROCESS_ERROR;
2993                 halmac_adapter->halmac_state.iqk_set.process_status =
2994                         process_status;
2995                 PLATFORM_EVENT_INDICATION(
2996                         driver_adapter, HALMAC_FEATURE_IQK, process_status,
2997                         &halmac_adapter->halmac_state.iqk_set.fw_return_code,
2998                         1);
2999         }
3000
3001         return HALMAC_RET_SUCCESS;
3002 }
3003
3004 static enum halmac_ret_status
3005 halmac_parse_h2c_ack_power_tracking_88xx(struct halmac_adapter *halmac_adapter,
3006                                          u8 *c2h_buf, u32 c2h_size)
3007 {
3008         u8 h2c_seq = 0;
3009         u8 h2c_return_code;
3010         void *driver_adapter = halmac_adapter->driver_adapter;
3011         enum halmac_cmd_process_status process_status;
3012
3013         h2c_seq = (u8)H2C_ACK_HDR_GET_H2C_SEQ(c2h_buf);
3014         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_H2C, DBG_DMESG,
3015                         "[TRACE]Seq num : h2c -> %d c2h -> %d\n",
3016                         halmac_adapter->halmac_state.power_tracking_set.seq_num,
3017                         h2c_seq);
3018         if (h2c_seq !=
3019             halmac_adapter->halmac_state.power_tracking_set.seq_num) {
3020                 pr_err("[ERR]Seq num mismatch : h2c -> %d c2h -> %d\n",
3021                        halmac_adapter->halmac_state.power_tracking_set.seq_num,
3022                        h2c_seq);
3023                 return HALMAC_RET_SUCCESS;
3024         }
3025
3026         if (halmac_adapter->halmac_state.power_tracking_set.process_status !=
3027             HALMAC_CMD_PROCESS_SENDING) {
3028                 pr_err("[ERR]Not in HALMAC_CMD_PROCESS_SENDING\n");
3029                 return HALMAC_RET_SUCCESS;
3030         }
3031
3032         h2c_return_code = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(c2h_buf);
3033         halmac_adapter->halmac_state.power_tracking_set.fw_return_code =
3034                 h2c_return_code;
3035
3036         if ((enum halmac_h2c_return_code)h2c_return_code ==
3037             HALMAC_H2C_RETURN_SUCCESS) {
3038                 process_status = HALMAC_CMD_PROCESS_DONE;
3039                 halmac_adapter->halmac_state.power_tracking_set.process_status =
3040                         process_status;
3041                 PLATFORM_EVENT_INDICATION(driver_adapter,
3042                                           HALMAC_FEATURE_POWER_TRACKING,
3043                                           process_status, NULL, 0);
3044         } else {
3045                 process_status = HALMAC_CMD_PROCESS_ERROR;
3046                 halmac_adapter->halmac_state.power_tracking_set.process_status =
3047                         process_status;
3048                 PLATFORM_EVENT_INDICATION(
3049                         driver_adapter, HALMAC_FEATURE_POWER_TRACKING,
3050                         process_status,
3051                         &halmac_adapter->halmac_state.power_tracking_set
3052                                  .fw_return_code,
3053                         1);
3054         }
3055
3056         return HALMAC_RET_SUCCESS;
3057 }
3058
3059 enum halmac_ret_status
3060 halmac_convert_to_sdio_bus_offset_88xx(struct halmac_adapter *halmac_adapter,
3061                                        u32 *halmac_offset)
3062 {
3063         void *driver_adapter = NULL;
3064
3065         driver_adapter = halmac_adapter->driver_adapter;
3066
3067         switch ((*halmac_offset) & 0xFFFF0000) {
3068         case WLAN_IOREG_OFFSET:
3069                 *halmac_offset = (HALMAC_SDIO_CMD_ADDR_MAC_REG << 13) |
3070                                  (*halmac_offset & HALMAC_WLAN_MAC_REG_MSK);
3071                 break;
3072         case SDIO_LOCAL_OFFSET:
3073                 *halmac_offset = (HALMAC_SDIO_CMD_ADDR_SDIO_REG << 13) |
3074                                  (*halmac_offset & HALMAC_SDIO_LOCAL_MSK);
3075                 break;
3076         default:
3077                 *halmac_offset = 0xFFFFFFFF;
3078                 pr_err("Unknown base address!!\n");
3079                 return HALMAC_RET_CONVERT_SDIO_OFFSET_FAIL;
3080         }
3081
3082         return HALMAC_RET_SUCCESS;
3083 }
3084
3085 enum halmac_ret_status
3086 halmac_update_sdio_free_page_88xx(struct halmac_adapter *halmac_adapter)
3087 {
3088         u32 free_page = 0, free_page2 = 0, free_page3 = 0;
3089         void *driver_adapter = NULL;
3090         struct halmac_api *halmac_api;
3091         struct halmac_sdio_free_space *sdio_free_space;
3092         u8 data[12] = {0};
3093
3094         driver_adapter = halmac_adapter->driver_adapter;
3095         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3096
3097         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
3098                         "%s ==========>\n", __func__);
3099
3100         sdio_free_space = &halmac_adapter->sdio_free_space;
3101         /*need to use HALMAC_REG_READ_N, 20160316, Soar*/
3102         HALMAC_REG_SDIO_CMD53_READ_N(halmac_adapter, REG_SDIO_FREE_TXPG, 12,
3103                                      data);
3104         free_page =
3105                 data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
3106         free_page2 =
3107                 data[4] | (data[5] << 8) | (data[6] << 16) | (data[7] << 24);
3108         free_page3 =
3109                 data[8] | (data[9] << 8) | (data[10] << 16) | (data[11] << 24);
3110
3111         sdio_free_space->high_queue_number =
3112                 (u16)BIT_GET_HIQ_FREEPG_V1(free_page);
3113         sdio_free_space->normal_queue_number =
3114                 (u16)BIT_GET_MID_FREEPG_V1(free_page);
3115         sdio_free_space->low_queue_number =
3116                 (u16)BIT_GET_LOW_FREEPG_V1(free_page2);
3117         sdio_free_space->public_queue_number =
3118                 (u16)BIT_GET_PUB_FREEPG_V1(free_page2);
3119         sdio_free_space->extra_queue_number =
3120                 (u16)BIT_GET_EXQ_FREEPG_V1(free_page3);
3121         sdio_free_space->ac_oqt_number = (u8)((free_page3 >> 16) & 0xFF);
3122         sdio_free_space->non_ac_oqt_number = (u8)((free_page3 >> 24) & 0xFF);
3123
3124         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
3125                         "%s <==========\n", __func__);
3126
3127         return HALMAC_RET_SUCCESS;
3128 }
3129
3130 enum halmac_ret_status
3131 halmac_update_oqt_free_space_88xx(struct halmac_adapter *halmac_adapter)
3132 {
3133         void *driver_adapter = NULL;
3134         struct halmac_api *halmac_api;
3135         struct halmac_sdio_free_space *sdio_free_space;
3136
3137         driver_adapter = halmac_adapter->driver_adapter;
3138         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3139
3140         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
3141                         "%s ==========>\n", __func__);
3142
3143         sdio_free_space = &halmac_adapter->sdio_free_space;
3144
3145         sdio_free_space->ac_oqt_number = HALMAC_REG_READ_8(
3146                 halmac_adapter, REG_SDIO_OQT_FREE_TXPG_V1 + 2);
3147         sdio_free_space->ac_empty =
3148                 HALMAC_REG_READ_8(halmac_adapter, REG_TXPKT_EMPTY);
3149
3150         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT, DBG_DMESG,
3151                         "%s <==========\n", __func__);
3152
3153         return HALMAC_RET_SUCCESS;
3154 }
3155
3156 enum halmac_efuse_cmd_construct_state
3157 halmac_query_efuse_curr_state_88xx(struct halmac_adapter *halmac_adapter)
3158 {
3159         return halmac_adapter->halmac_state.efuse_state_set
3160                 .efuse_cmd_construct_state;
3161 }
3162
3163 enum halmac_ret_status halmac_transition_efuse_state_88xx(
3164         struct halmac_adapter *halmac_adapter,
3165         enum halmac_efuse_cmd_construct_state dest_state)
3166 {
3167         struct halmac_efuse_state_set *efuse_state =
3168                 &halmac_adapter->halmac_state.efuse_state_set;
3169
3170         if (efuse_state->efuse_cmd_construct_state !=
3171                     HALMAC_EFUSE_CMD_CONSTRUCT_IDLE &&
3172             efuse_state->efuse_cmd_construct_state !=
3173                     HALMAC_EFUSE_CMD_CONSTRUCT_BUSY &&
3174             efuse_state->efuse_cmd_construct_state !=
3175                     HALMAC_EFUSE_CMD_CONSTRUCT_H2C_SENT)
3176                 return HALMAC_RET_ERROR_STATE;
3177
3178         if (efuse_state->efuse_cmd_construct_state == dest_state)
3179                 return HALMAC_RET_ERROR_STATE;
3180
3181         if (dest_state == HALMAC_EFUSE_CMD_CONSTRUCT_BUSY) {
3182                 if (efuse_state->efuse_cmd_construct_state ==
3183                     HALMAC_EFUSE_CMD_CONSTRUCT_H2C_SENT)
3184                         return HALMAC_RET_ERROR_STATE;
3185         } else if (dest_state == HALMAC_EFUSE_CMD_CONSTRUCT_H2C_SENT) {
3186                 if (efuse_state->efuse_cmd_construct_state ==
3187                     HALMAC_EFUSE_CMD_CONSTRUCT_IDLE)
3188                         return HALMAC_RET_ERROR_STATE;
3189         }
3190
3191         efuse_state->efuse_cmd_construct_state = dest_state;
3192
3193         return HALMAC_RET_SUCCESS;
3194 }
3195
3196 enum halmac_cfg_para_cmd_construct_state
3197 halmac_query_cfg_para_curr_state_88xx(struct halmac_adapter *halmac_adapter)
3198 {
3199         return halmac_adapter->halmac_state.cfg_para_state_set
3200                 .cfg_para_cmd_construct_state;
3201 }
3202
3203 enum halmac_ret_status halmac_transition_cfg_para_state_88xx(
3204         struct halmac_adapter *halmac_adapter,
3205         enum halmac_cfg_para_cmd_construct_state dest_state)
3206 {
3207         struct halmac_cfg_para_state_set *cfg_para =
3208                 &halmac_adapter->halmac_state.cfg_para_state_set;
3209
3210         if (cfg_para->cfg_para_cmd_construct_state !=
3211                     HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE &&
3212             cfg_para->cfg_para_cmd_construct_state !=
3213                     HALMAC_CFG_PARA_CMD_CONSTRUCT_CONSTRUCTING &&
3214             cfg_para->cfg_para_cmd_construct_state !=
3215                     HALMAC_CFG_PARA_CMD_CONSTRUCT_H2C_SENT)
3216                 return HALMAC_RET_ERROR_STATE;
3217
3218         if (dest_state == HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE) {
3219                 if (cfg_para->cfg_para_cmd_construct_state ==
3220                     HALMAC_CFG_PARA_CMD_CONSTRUCT_CONSTRUCTING)
3221                         return HALMAC_RET_ERROR_STATE;
3222         } else if (dest_state == HALMAC_CFG_PARA_CMD_CONSTRUCT_CONSTRUCTING) {
3223                 if (cfg_para->cfg_para_cmd_construct_state ==
3224                     HALMAC_CFG_PARA_CMD_CONSTRUCT_H2C_SENT)
3225                         return HALMAC_RET_ERROR_STATE;
3226         } else if (dest_state == HALMAC_CFG_PARA_CMD_CONSTRUCT_H2C_SENT) {
3227                 if (cfg_para->cfg_para_cmd_construct_state ==
3228                             HALMAC_CFG_PARA_CMD_CONSTRUCT_IDLE ||
3229                     cfg_para->cfg_para_cmd_construct_state ==
3230                             HALMAC_CFG_PARA_CMD_CONSTRUCT_H2C_SENT)
3231                         return HALMAC_RET_ERROR_STATE;
3232         }
3233
3234         cfg_para->cfg_para_cmd_construct_state = dest_state;
3235
3236         return HALMAC_RET_SUCCESS;
3237 }
3238
3239 enum halmac_scan_cmd_construct_state
3240 halmac_query_scan_curr_state_88xx(struct halmac_adapter *halmac_adapter)
3241 {
3242         return halmac_adapter->halmac_state.scan_state_set
3243                 .scan_cmd_construct_state;
3244 }
3245
3246 enum halmac_ret_status halmac_transition_scan_state_88xx(
3247         struct halmac_adapter *halmac_adapter,
3248         enum halmac_scan_cmd_construct_state dest_state)
3249 {
3250         struct halmac_scan_state_set *scan =
3251                 &halmac_adapter->halmac_state.scan_state_set;
3252
3253         if (scan->scan_cmd_construct_state > HALMAC_SCAN_CMD_CONSTRUCT_H2C_SENT)
3254                 return HALMAC_RET_ERROR_STATE;
3255
3256         if (dest_state == HALMAC_SCAN_CMD_CONSTRUCT_IDLE) {
3257                 if (scan->scan_cmd_construct_state ==
3258                             HALMAC_SCAN_CMD_CONSTRUCT_BUFFER_CLEARED ||
3259                     scan->scan_cmd_construct_state ==
3260                             HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING)
3261                         return HALMAC_RET_ERROR_STATE;
3262         } else if (dest_state == HALMAC_SCAN_CMD_CONSTRUCT_BUFFER_CLEARED) {
3263                 if (scan->scan_cmd_construct_state ==
3264                     HALMAC_SCAN_CMD_CONSTRUCT_H2C_SENT)
3265                         return HALMAC_RET_ERROR_STATE;
3266         } else if (dest_state == HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING) {
3267                 if (scan->scan_cmd_construct_state ==
3268                             HALMAC_SCAN_CMD_CONSTRUCT_IDLE ||
3269                     scan->scan_cmd_construct_state ==
3270                             HALMAC_SCAN_CMD_CONSTRUCT_H2C_SENT)
3271                         return HALMAC_RET_ERROR_STATE;
3272         } else if (dest_state == HALMAC_SCAN_CMD_CONSTRUCT_H2C_SENT) {
3273                 if (scan->scan_cmd_construct_state !=
3274                             HALMAC_SCAN_CMD_CONSTRUCT_CONSTRUCTING &&
3275                     scan->scan_cmd_construct_state !=
3276                             HALMAC_SCAN_CMD_CONSTRUCT_BUFFER_CLEARED)
3277                         return HALMAC_RET_ERROR_STATE;
3278         }
3279
3280         scan->scan_cmd_construct_state = dest_state;
3281
3282         return HALMAC_RET_SUCCESS;
3283 }
3284
3285 enum halmac_ret_status halmac_query_cfg_para_status_88xx(
3286         struct halmac_adapter *halmac_adapter,
3287         enum halmac_cmd_process_status *process_status, u8 *data, u32 *size)
3288 {
3289         struct halmac_cfg_para_state_set *cfg_para_state_set =
3290                 &halmac_adapter->halmac_state.cfg_para_state_set;
3291
3292         *process_status = cfg_para_state_set->process_status;
3293
3294         return HALMAC_RET_SUCCESS;
3295 }
3296
3297 enum halmac_ret_status halmac_query_dump_physical_efuse_status_88xx(
3298         struct halmac_adapter *halmac_adapter,
3299         enum halmac_cmd_process_status *process_status, u8 *data, u32 *size)
3300 {
3301         void *driver_adapter = NULL;
3302         struct halmac_efuse_state_set *efuse_state_set =
3303                 &halmac_adapter->halmac_state.efuse_state_set;
3304
3305         driver_adapter = halmac_adapter->driver_adapter;
3306
3307         *process_status = efuse_state_set->process_status;
3308
3309         if (!data)
3310                 return HALMAC_RET_NULL_POINTER;
3311
3312         if (!size)
3313                 return HALMAC_RET_NULL_POINTER;
3314
3315         if (*process_status == HALMAC_CMD_PROCESS_DONE) {
3316                 if (*size < halmac_adapter->hw_config_info.efuse_size) {
3317                         *size = halmac_adapter->hw_config_info.efuse_size;
3318                         return HALMAC_RET_BUFFER_TOO_SMALL;
3319                 }
3320
3321                 *size = halmac_adapter->hw_config_info.efuse_size;
3322                 memcpy(data, halmac_adapter->hal_efuse_map, *size);
3323         }
3324
3325         return HALMAC_RET_SUCCESS;
3326 }
3327
3328 enum halmac_ret_status halmac_query_dump_logical_efuse_status_88xx(
3329         struct halmac_adapter *halmac_adapter,
3330         enum halmac_cmd_process_status *process_status, u8 *data, u32 *size)
3331 {
3332         u8 *eeprom_map = NULL;
3333         u32 eeprom_size = halmac_adapter->hw_config_info.eeprom_size;
3334         void *driver_adapter = NULL;
3335         struct halmac_efuse_state_set *efuse_state_set =
3336                 &halmac_adapter->halmac_state.efuse_state_set;
3337
3338         driver_adapter = halmac_adapter->driver_adapter;
3339
3340         *process_status = efuse_state_set->process_status;
3341
3342         if (!data)
3343                 return HALMAC_RET_NULL_POINTER;
3344
3345         if (!size)
3346                 return HALMAC_RET_NULL_POINTER;
3347
3348         if (*process_status == HALMAC_CMD_PROCESS_DONE) {
3349                 if (*size < eeprom_size) {
3350                         *size = eeprom_size;
3351                         return HALMAC_RET_BUFFER_TOO_SMALL;
3352                 }
3353
3354                 *size = eeprom_size;
3355
3356                 eeprom_map = kzalloc(eeprom_size, GFP_KERNEL);
3357                 if (!eeprom_map) {
3358                         /* out of memory */
3359                         return HALMAC_RET_MALLOC_FAIL;
3360                 }
3361                 memset(eeprom_map, 0xFF, eeprom_size);
3362
3363                 if (halmac_eeprom_parser_88xx(
3364                             halmac_adapter, halmac_adapter->hal_efuse_map,
3365                             eeprom_map) != HALMAC_RET_SUCCESS) {
3366                         kfree(eeprom_map);
3367                         return HALMAC_RET_EEPROM_PARSING_FAIL;
3368                 }
3369
3370                 memcpy(data, eeprom_map, *size);
3371
3372                 kfree(eeprom_map);
3373         }
3374
3375         return HALMAC_RET_SUCCESS;
3376 }
3377
3378 enum halmac_ret_status halmac_query_channel_switch_status_88xx(
3379         struct halmac_adapter *halmac_adapter,
3380         enum halmac_cmd_process_status *process_status, u8 *data, u32 *size)
3381 {
3382         struct halmac_scan_state_set *scan_state_set =
3383                 &halmac_adapter->halmac_state.scan_state_set;
3384
3385         *process_status = scan_state_set->process_status;
3386
3387         return HALMAC_RET_SUCCESS;
3388 }
3389
3390 enum halmac_ret_status halmac_query_update_packet_status_88xx(
3391         struct halmac_adapter *halmac_adapter,
3392         enum halmac_cmd_process_status *process_status, u8 *data, u32 *size)
3393 {
3394         struct halmac_update_packet_state_set *update_packet_set =
3395                 &halmac_adapter->halmac_state.update_packet_set;
3396
3397         *process_status = update_packet_set->process_status;
3398
3399         return HALMAC_RET_SUCCESS;
3400 }
3401
3402 enum halmac_ret_status
3403 halmac_query_iqk_status_88xx(struct halmac_adapter *halmac_adapter,
3404                              enum halmac_cmd_process_status *process_status,
3405                              u8 *data, u32 *size)
3406 {
3407         struct halmac_iqk_state_set *iqk_set =
3408                 &halmac_adapter->halmac_state.iqk_set;
3409
3410         *process_status = iqk_set->process_status;
3411
3412         return HALMAC_RET_SUCCESS;
3413 }
3414
3415 enum halmac_ret_status halmac_query_power_tracking_status_88xx(
3416         struct halmac_adapter *halmac_adapter,
3417         enum halmac_cmd_process_status *process_status, u8 *data, u32 *size)
3418 {
3419         struct halmac_power_tracking_state_set *power_tracking_state_set =
3420                 &halmac_adapter->halmac_state.power_tracking_set;
3421         ;
3422
3423         *process_status = power_tracking_state_set->process_status;
3424
3425         return HALMAC_RET_SUCCESS;
3426 }
3427
3428 enum halmac_ret_status
3429 halmac_query_psd_status_88xx(struct halmac_adapter *halmac_adapter,
3430                              enum halmac_cmd_process_status *process_status,
3431                              u8 *data, u32 *size)
3432 {
3433         void *driver_adapter = NULL;
3434         struct halmac_psd_state_set *psd_set =
3435                 &halmac_adapter->halmac_state.psd_set;
3436
3437         driver_adapter = halmac_adapter->driver_adapter;
3438
3439         *process_status = psd_set->process_status;
3440
3441         if (!data)
3442                 return HALMAC_RET_NULL_POINTER;
3443
3444         if (!size)
3445                 return HALMAC_RET_NULL_POINTER;
3446
3447         if (*process_status == HALMAC_CMD_PROCESS_DONE) {
3448                 if (*size < psd_set->data_size) {
3449                         *size = psd_set->data_size;
3450                         return HALMAC_RET_BUFFER_TOO_SMALL;
3451                 }
3452
3453                 *size = psd_set->data_size;
3454                 memcpy(data, psd_set->data, *size);
3455         }
3456
3457         return HALMAC_RET_SUCCESS;
3458 }
3459
3460 enum halmac_ret_status
3461 halmac_verify_io_88xx(struct halmac_adapter *halmac_adapter)
3462 {
3463         u8 value8, wvalue8;
3464         u32 value32, value32_2, wvalue32;
3465         u32 halmac_offset;
3466         void *driver_adapter = NULL;
3467         enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
3468
3469         driver_adapter = halmac_adapter->driver_adapter;
3470
3471         if (halmac_adapter->halmac_interface == HALMAC_INTERFACE_SDIO) {
3472                 halmac_offset = REG_PAGE5_DUMMY;
3473                 if ((halmac_offset & 0xFFFF0000) == 0)
3474                         halmac_offset |= WLAN_IOREG_OFFSET;
3475
3476                 ret_status = halmac_convert_to_sdio_bus_offset_88xx(
3477                         halmac_adapter, &halmac_offset);
3478
3479                 /* Verify CMD52 R/W */
3480                 wvalue8 = 0xab;
3481                 PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset,
3482                                           wvalue8);
3483
3484                 value8 =
3485                         PLATFORM_SDIO_CMD52_READ(driver_adapter, halmac_offset);
3486
3487                 if (value8 != wvalue8) {
3488                         pr_err("cmd52 r/w fail write = %X read = %X\n", wvalue8,
3489                                value8);
3490                         ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
3491                 } else {
3492                         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
3493                                         DBG_DMESG, "cmd52 r/w ok\n");
3494                 }
3495
3496                 /* Verify CMD53 R/W */
3497                 PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset, 0xaa);
3498                 PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset + 1,
3499                                           0xbb);
3500                 PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset + 2,
3501                                           0xcc);
3502                 PLATFORM_SDIO_CMD52_WRITE(driver_adapter, halmac_offset + 3,
3503                                           0xdd);
3504
3505                 value32 = PLATFORM_SDIO_CMD53_READ_32(driver_adapter,
3506                                                       halmac_offset);
3507
3508                 if (value32 != 0xddccbbaa) {
3509                         pr_err("cmd53 r fail : read = %X\n", value32);
3510                         ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
3511                 } else {
3512                         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
3513                                         DBG_DMESG, "cmd53 r ok\n");
3514                 }
3515
3516                 wvalue32 = 0x11223344;
3517                 PLATFORM_SDIO_CMD53_WRITE_32(driver_adapter, halmac_offset,
3518                                              wvalue32);
3519
3520                 value32 = PLATFORM_SDIO_CMD53_READ_32(driver_adapter,
3521                                                       halmac_offset);
3522
3523                 if (value32 != wvalue32) {
3524                         pr_err("cmd53 w fail\n");
3525                         ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
3526                 } else {
3527                         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
3528                                         DBG_DMESG, "cmd53 w ok\n");
3529                 }
3530
3531                 value32 = PLATFORM_SDIO_CMD53_READ_32(
3532                         driver_adapter,
3533                         halmac_offset + 2); /* value32 should be 0x33441122 */
3534
3535                 wvalue32 = 0x11225566;
3536                 PLATFORM_SDIO_CMD53_WRITE_32(driver_adapter, halmac_offset,
3537                                              wvalue32);
3538
3539                 value32_2 = PLATFORM_SDIO_CMD53_READ_32(
3540                         driver_adapter,
3541                         halmac_offset + 2); /* value32 should be 0x55661122 */
3542                 if (value32_2 == value32) {
3543                         pr_err("cmd52 is used for HAL_SDIO_CMD53_READ_32\n");
3544                         ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
3545                 } else {
3546                         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
3547                                         DBG_DMESG, "cmd53 is correctly used\n");
3548                 }
3549         } else {
3550                 wvalue32 = 0x77665511;
3551                 PLATFORM_REG_WRITE_32(driver_adapter, REG_PAGE5_DUMMY,
3552                                       wvalue32);
3553
3554                 value32 = PLATFORM_REG_READ_32(driver_adapter, REG_PAGE5_DUMMY);
3555                 if (value32 != wvalue32) {
3556                         pr_err("reg rw\n");
3557                         ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
3558                 } else {
3559                         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
3560                                         DBG_DMESG, "reg rw ok\n");
3561                 }
3562         }
3563
3564         return ret_status;
3565 }
3566
3567 enum halmac_ret_status
3568 halmac_verify_send_rsvd_page_88xx(struct halmac_adapter *halmac_adapter)
3569 {
3570         u8 *rsvd_buf = NULL;
3571         u8 *rsvd_page = NULL;
3572         u32 i;
3573         u32 h2c_pkt_verify_size = 64, h2c_pkt_verify_payload = 0xab;
3574         void *driver_adapter = NULL;
3575         enum halmac_ret_status ret_status = HALMAC_RET_SUCCESS;
3576
3577         driver_adapter = halmac_adapter->driver_adapter;
3578
3579         rsvd_buf = kzalloc(h2c_pkt_verify_size, GFP_KERNEL);
3580
3581         if (!rsvd_buf) {
3582                 /*pr_err("[ERR]rsvd buffer malloc fail!!\n");*/
3583                 return HALMAC_RET_MALLOC_FAIL;
3584         }
3585
3586         memset(rsvd_buf, (u8)h2c_pkt_verify_payload, h2c_pkt_verify_size);
3587
3588         ret_status = halmac_download_rsvd_page_88xx(halmac_adapter, rsvd_buf,
3589                                                     h2c_pkt_verify_size);
3590
3591         if (ret_status != HALMAC_RET_SUCCESS) {
3592                 kfree(rsvd_buf);
3593                 return ret_status;
3594         }
3595
3596         rsvd_page = kzalloc(h2c_pkt_verify_size +
3597                                     halmac_adapter->hw_config_info.txdesc_size,
3598                             GFP_KERNEL);
3599
3600         if (!rsvd_page) {
3601                 pr_err("[ERR]rsvd page malloc fail!!\n");
3602                 kfree(rsvd_buf);
3603                 return HALMAC_RET_MALLOC_FAIL;
3604         }
3605
3606         ret_status = halmac_dump_fifo_88xx(
3607                 halmac_adapter, HAL_FIFO_SEL_RSVD_PAGE, 0,
3608                 h2c_pkt_verify_size +
3609                         halmac_adapter->hw_config_info.txdesc_size,
3610                 rsvd_page);
3611
3612         if (ret_status != HALMAC_RET_SUCCESS) {
3613                 kfree(rsvd_buf);
3614                 kfree(rsvd_page);
3615                 return ret_status;
3616         }
3617
3618         for (i = 0; i < h2c_pkt_verify_size; i++) {
3619                 if (*(rsvd_buf + i) !=
3620                     *(rsvd_page +
3621                       (i + halmac_adapter->hw_config_info.txdesc_size))) {
3622                         pr_err("[ERR]Compare RSVD page Fail\n");
3623                         ret_status = HALMAC_RET_PLATFORM_API_INCORRECT;
3624                 }
3625         }
3626
3627         kfree(rsvd_buf);
3628         kfree(rsvd_page);
3629
3630         return ret_status;
3631 }
3632
3633 void halmac_power_save_cb_88xx(void *cb_data)
3634 {
3635         void *driver_adapter = NULL;
3636         struct halmac_adapter *halmac_adapter = (struct halmac_adapter *)NULL;
3637
3638         halmac_adapter = (struct halmac_adapter *)cb_data;
3639         driver_adapter = halmac_adapter->driver_adapter;
3640
3641         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
3642                         "%s\n", __func__);
3643 }
3644
3645 enum halmac_ret_status
3646 halmac_buffer_read_88xx(struct halmac_adapter *halmac_adapter, u32 offset,
3647                         u32 size, enum hal_fifo_sel halmac_fifo_sel,
3648                         u8 *fifo_map)
3649 {
3650         u32 start_page, value_read;
3651         u32 i, counter = 0, residue;
3652         struct halmac_api *halmac_api;
3653
3654         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3655
3656         if (halmac_fifo_sel == HAL_FIFO_SEL_RSVD_PAGE)
3657                 offset = offset +
3658                          (halmac_adapter->txff_allocation.rsvd_pg_bndy << 7);
3659
3660         start_page = offset >> 12;
3661         residue = offset & (4096 - 1);
3662
3663         if (halmac_fifo_sel == HAL_FIFO_SEL_TX ||
3664             halmac_fifo_sel == HAL_FIFO_SEL_RSVD_PAGE)
3665                 start_page += 0x780;
3666         else if (halmac_fifo_sel == HAL_FIFO_SEL_RX)
3667                 start_page += 0x700;
3668         else if (halmac_fifo_sel == HAL_FIFO_SEL_REPORT)
3669                 start_page += 0x660;
3670         else if (halmac_fifo_sel == HAL_FIFO_SEL_LLT)
3671                 start_page += 0x650;
3672         else
3673                 return HALMAC_RET_NOT_SUPPORT;
3674
3675         value_read = HALMAC_REG_READ_16(halmac_adapter, REG_PKTBUF_DBG_CTRL);
3676
3677         do {
3678                 HALMAC_REG_WRITE_16(halmac_adapter, REG_PKTBUF_DBG_CTRL,
3679                                     (u16)(start_page | (value_read & 0xF000)));
3680
3681                 for (i = 0x8000 + residue; i <= 0x8FFF; i += 4) {
3682                         *(u32 *)(fifo_map + counter) =
3683                                 HALMAC_REG_READ_32(halmac_adapter, i);
3684                         *(u32 *)(fifo_map + counter) =
3685                                 le32_to_cpu(*(__le32 *)(fifo_map + counter));
3686                         counter += 4;
3687                         if (size == counter)
3688                                 goto HALMAC_BUF_READ_OK;
3689                 }
3690
3691                 residue = 0;
3692                 start_page++;
3693         } while (1);
3694
3695 HALMAC_BUF_READ_OK:
3696         HALMAC_REG_WRITE_16(halmac_adapter, REG_PKTBUF_DBG_CTRL,
3697                             (u16)value_read);
3698
3699         return HALMAC_RET_SUCCESS;
3700 }
3701
3702 void halmac_restore_mac_register_88xx(struct halmac_adapter *halmac_adapter,
3703                                       struct halmac_restore_info *restore_info,
3704                                       u32 restore_num)
3705 {
3706         u8 value_length;
3707         u32 i;
3708         u32 mac_register;
3709         u32 mac_value;
3710         struct halmac_api *halmac_api;
3711         struct halmac_restore_info *curr_restore_info = restore_info;
3712
3713         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3714
3715         for (i = 0; i < restore_num; i++) {
3716                 mac_register = curr_restore_info->mac_register;
3717                 mac_value = curr_restore_info->value;
3718                 value_length = curr_restore_info->length;
3719
3720                 if (value_length == 1)
3721                         HALMAC_REG_WRITE_8(halmac_adapter, mac_register,
3722                                            (u8)mac_value);
3723                 else if (value_length == 2)
3724                         HALMAC_REG_WRITE_16(halmac_adapter, mac_register,
3725                                             (u16)mac_value);
3726                 else if (value_length == 4)
3727                         HALMAC_REG_WRITE_32(halmac_adapter, mac_register,
3728                                             mac_value);
3729
3730                 curr_restore_info++;
3731         }
3732 }
3733
3734 void halmac_api_record_id_88xx(struct halmac_adapter *halmac_adapter,
3735                                enum halmac_api_id api_id)
3736 {
3737 }
3738
3739 enum halmac_ret_status
3740 halmac_set_usb_mode_88xx(struct halmac_adapter *halmac_adapter,
3741                          enum halmac_usb_mode usb_mode)
3742 {
3743         u32 usb_temp;
3744         void *driver_adapter = NULL;
3745         struct halmac_api *halmac_api;
3746         enum halmac_usb_mode current_usb_mode;
3747
3748         driver_adapter = halmac_adapter->driver_adapter;
3749         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3750
3751         current_usb_mode =
3752                 HALMAC_REG_READ_8(halmac_adapter, REG_SYS_CFG2 + 3) == 0x20 ?
3753                         HALMAC_USB_MODE_U3 :
3754                         HALMAC_USB_MODE_U2;
3755
3756         /*check if HW supports usb2_usb3 swtich*/
3757         usb_temp = HALMAC_REG_READ_32(halmac_adapter, REG_PAD_CTRL2);
3758         if (!BIT_GET_USB23_SW_MODE_V1(usb_temp) &&
3759             !(usb_temp & BIT_USB3_USB2_TRANSITION)) {
3760                 pr_err("HALMAC_HW_USB_MODE usb mode HW unsupport\n");
3761                 return HALMAC_RET_USB2_3_SWITCH_UNSUPPORT;
3762         }
3763
3764         if (usb_mode == current_usb_mode) {
3765                 pr_err("HALMAC_HW_USB_MODE usb mode unchange\n");
3766                 return HALMAC_RET_USB_MODE_UNCHANGE;
3767         }
3768
3769         usb_temp &= ~(BIT_USB23_SW_MODE_V1(0x3));
3770
3771         if (usb_mode == HALMAC_USB_MODE_U2) {
3772                 /* usb3 to usb2 */
3773                 HALMAC_REG_WRITE_32(
3774                         halmac_adapter, REG_PAD_CTRL2,
3775                         usb_temp | BIT_USB23_SW_MODE_V1(HALMAC_USB_MODE_U2) |
3776                                 BIT_RSM_EN_V1);
3777         } else {
3778                 /* usb2 to usb3 */
3779                 HALMAC_REG_WRITE_32(
3780                         halmac_adapter, REG_PAD_CTRL2,
3781                         usb_temp | BIT_USB23_SW_MODE_V1(HALMAC_USB_MODE_U3) |
3782                                 BIT_RSM_EN_V1);
3783         }
3784
3785         HALMAC_REG_WRITE_8(halmac_adapter, REG_PAD_CTRL2 + 1,
3786                            4); /* set counter down timer 4x64 ms */
3787         HALMAC_REG_WRITE_16(
3788                 halmac_adapter, REG_SYS_PW_CTRL,
3789                 HALMAC_REG_READ_16(halmac_adapter, REG_SYS_PW_CTRL) |
3790                         BIT_APFM_OFFMAC);
3791         usleep_range(1000, 1100);
3792         HALMAC_REG_WRITE_32(halmac_adapter, REG_PAD_CTRL2,
3793                             HALMAC_REG_READ_32(halmac_adapter, REG_PAD_CTRL2) |
3794                                     BIT_NO_PDN_CHIPOFF_V1);
3795
3796         return HALMAC_RET_SUCCESS;
3797 }
3798
3799 void halmac_enable_bb_rf_88xx(struct halmac_adapter *halmac_adapter, u8 enable)
3800 {
3801         u8 value8;
3802         u32 value32;
3803         struct halmac_api *halmac_api;
3804
3805         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3806
3807         if (enable == 1) {
3808                 value8 = HALMAC_REG_READ_8(halmac_adapter, REG_SYS_FUNC_EN);
3809                 value8 = value8 | BIT(0) | BIT(1);
3810                 HALMAC_REG_WRITE_8(halmac_adapter, REG_SYS_FUNC_EN, value8);
3811
3812                 value8 = HALMAC_REG_READ_8(halmac_adapter, REG_RF_CTRL);
3813                 value8 = value8 | BIT(0) | BIT(1) | BIT(2);
3814                 HALMAC_REG_WRITE_8(halmac_adapter, REG_RF_CTRL, value8);
3815
3816                 value32 = HALMAC_REG_READ_32(halmac_adapter, REG_WLRF1);
3817                 value32 = value32 | BIT(24) | BIT(25) | BIT(26);
3818                 HALMAC_REG_WRITE_32(halmac_adapter, REG_WLRF1, value32);
3819         } else {
3820                 value8 = HALMAC_REG_READ_8(halmac_adapter, REG_SYS_FUNC_EN);
3821                 value8 = value8 & (~(BIT(0) | BIT(1)));
3822                 HALMAC_REG_WRITE_8(halmac_adapter, REG_SYS_FUNC_EN, value8);
3823
3824                 value8 = HALMAC_REG_READ_8(halmac_adapter, REG_RF_CTRL);
3825                 value8 = value8 & (~(BIT(0) | BIT(1) | BIT(2)));
3826                 HALMAC_REG_WRITE_8(halmac_adapter, REG_RF_CTRL, value8);
3827
3828                 value32 = HALMAC_REG_READ_32(halmac_adapter, REG_WLRF1);
3829                 value32 = value32 & (~(BIT(24) | BIT(25) | BIT(26)));
3830                 HALMAC_REG_WRITE_32(halmac_adapter, REG_WLRF1, value32);
3831         }
3832 }
3833
3834 void halmac_config_sdio_tx_page_threshold_88xx(
3835         struct halmac_adapter *halmac_adapter,
3836         struct halmac_tx_page_threshold_info *threshold_info)
3837 {
3838         struct halmac_api *halmac_api;
3839
3840         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3841
3842         switch (threshold_info->dma_queue_sel) {
3843         case HALMAC_MAP2_HQ:
3844                 HALMAC_REG_WRITE_32(halmac_adapter, REG_TQPNT1,
3845                                     threshold_info->threshold);
3846                 break;
3847         case HALMAC_MAP2_NQ:
3848                 HALMAC_REG_WRITE_32(halmac_adapter, REG_TQPNT2,
3849                                     threshold_info->threshold);
3850                 break;
3851         case HALMAC_MAP2_LQ:
3852                 HALMAC_REG_WRITE_32(halmac_adapter, REG_TQPNT3,
3853                                     threshold_info->threshold);
3854                 break;
3855         case HALMAC_MAP2_EXQ:
3856                 HALMAC_REG_WRITE_32(halmac_adapter, REG_TQPNT4,
3857                                     threshold_info->threshold);
3858                 break;
3859         default:
3860                 break;
3861         }
3862 }
3863
3864 void halmac_config_ampdu_88xx(struct halmac_adapter *halmac_adapter,
3865                               struct halmac_ampdu_config *ampdu_config)
3866 {
3867         struct halmac_api *halmac_api;
3868
3869         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3870
3871         HALMAC_REG_WRITE_8(halmac_adapter, REG_PROT_MODE_CTRL + 2,
3872                            ampdu_config->max_agg_num);
3873         HALMAC_REG_WRITE_8(halmac_adapter, REG_PROT_MODE_CTRL + 3,
3874                            ampdu_config->max_agg_num);
3875 };
3876
3877 enum halmac_ret_status
3878 halmac_check_oqt_88xx(struct halmac_adapter *halmac_adapter, u32 tx_agg_num,
3879                       u8 *halmac_buf)
3880 {
3881         u32 counter = 10;
3882
3883         /*S0, S1 are not allowed to use, 0x4E4[0] should be 0. Soar 20160323*/
3884         /*no need to check non_ac_oqt_number. HI and MGQ blocked will cause
3885          *protocal issue before H_OQT being full
3886          */
3887         switch ((enum halmac_queue_select)GET_TX_DESC_QSEL(halmac_buf)) {
3888         case HALMAC_QUEUE_SELECT_VO:
3889         case HALMAC_QUEUE_SELECT_VO_V2:
3890         case HALMAC_QUEUE_SELECT_VI:
3891         case HALMAC_QUEUE_SELECT_VI_V2:
3892         case HALMAC_QUEUE_SELECT_BE:
3893         case HALMAC_QUEUE_SELECT_BE_V2:
3894         case HALMAC_QUEUE_SELECT_BK:
3895         case HALMAC_QUEUE_SELECT_BK_V2:
3896                 counter = 10;
3897                 do {
3898                         if (halmac_adapter->sdio_free_space.ac_empty > 0) {
3899                                 halmac_adapter->sdio_free_space.ac_empty -= 1;
3900                                 break;
3901                         }
3902
3903                         if (halmac_adapter->sdio_free_space.ac_oqt_number >=
3904                             tx_agg_num) {
3905                                 halmac_adapter->sdio_free_space.ac_oqt_number -=
3906                                         (u8)tx_agg_num;
3907                                 break;
3908                         }
3909
3910                         halmac_update_oqt_free_space_88xx(halmac_adapter);
3911
3912                         counter--;
3913                         if (counter == 0)
3914                                 return HALMAC_RET_OQT_NOT_ENOUGH;
3915                 } while (1);
3916                 break;
3917         default:
3918                 break;
3919         }
3920
3921         return HALMAC_RET_SUCCESS;
3922 }
3923
3924 enum halmac_ret_status
3925 halmac_rqpn_parser_88xx(struct halmac_adapter *halmac_adapter,
3926                         enum halmac_trx_mode halmac_trx_mode,
3927                         struct halmac_rqpn_ *rqpn_table)
3928 {
3929         u8 search_flag;
3930         u32 i;
3931         void *driver_adapter = NULL;
3932         struct halmac_api *halmac_api;
3933
3934         driver_adapter = halmac_adapter->driver_adapter;
3935         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3936
3937         search_flag = 0;
3938         for (i = 0; i < HALMAC_TRX_MODE_MAX; i++) {
3939                 if (halmac_trx_mode == rqpn_table[i].mode) {
3940                         halmac_adapter
3941                                 ->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VO] =
3942                                 rqpn_table[i].dma_map_vo;
3943                         halmac_adapter
3944                                 ->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_VI] =
3945                                 rqpn_table[i].dma_map_vi;
3946                         halmac_adapter
3947                                 ->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BE] =
3948                                 rqpn_table[i].dma_map_be;
3949                         halmac_adapter
3950                                 ->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_BK] =
3951                                 rqpn_table[i].dma_map_bk;
3952                         halmac_adapter
3953                                 ->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_MG] =
3954                                 rqpn_table[i].dma_map_mg;
3955                         halmac_adapter
3956                                 ->halmac_ptcl_queue[HALMAC_PTCL_QUEUE_HI] =
3957                                 rqpn_table[i].dma_map_hi;
3958                         search_flag = 1;
3959                         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
3960                                         DBG_DMESG, "%s done\n", __func__);
3961                         break;
3962                 }
3963         }
3964
3965         if (search_flag == 0) {
3966                 pr_err("HALMAC_RET_TRX_MODE_NOT_SUPPORT 1 switch case not support\n");
3967                 return HALMAC_RET_TRX_MODE_NOT_SUPPORT;
3968         }
3969
3970         return HALMAC_RET_SUCCESS;
3971 }
3972
3973 enum halmac_ret_status
3974 halmac_pg_num_parser_88xx(struct halmac_adapter *halmac_adapter,
3975                           enum halmac_trx_mode halmac_trx_mode,
3976                           struct halmac_pg_num_ *pg_num_table)
3977 {
3978         u8 search_flag;
3979         u16 HPQ_num = 0, lpq_nnum = 0, NPQ_num = 0, GAPQ_num = 0;
3980         u16 EXPQ_num = 0, PUBQ_num = 0;
3981         u32 i = 0;
3982         void *driver_adapter = NULL;
3983         struct halmac_api *halmac_api;
3984
3985         driver_adapter = halmac_adapter->driver_adapter;
3986         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
3987
3988         search_flag = 0;
3989         for (i = 0; i < HALMAC_TRX_MODE_MAX; i++) {
3990                 if (halmac_trx_mode == pg_num_table[i].mode) {
3991                         HPQ_num = pg_num_table[i].hq_num;
3992                         lpq_nnum = pg_num_table[i].lq_num;
3993                         NPQ_num = pg_num_table[i].nq_num;
3994                         EXPQ_num = pg_num_table[i].exq_num;
3995                         GAPQ_num = pg_num_table[i].gap_num;
3996                         PUBQ_num = halmac_adapter->txff_allocation.ac_q_pg_num -
3997                                    HPQ_num - lpq_nnum - NPQ_num - EXPQ_num -
3998                                    GAPQ_num;
3999                         search_flag = 1;
4000                         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_INIT,
4001                                         DBG_DMESG, "%s done\n", __func__);
4002                         break;
4003                 }
4004         }
4005
4006         if (search_flag == 0) {
4007                 pr_err("HALMAC_RET_TRX_MODE_NOT_SUPPORT 1 switch case not support\n");
4008                 return HALMAC_RET_TRX_MODE_NOT_SUPPORT;
4009         }
4010
4011         if (halmac_adapter->txff_allocation.ac_q_pg_num <
4012             HPQ_num + lpq_nnum + NPQ_num + EXPQ_num + GAPQ_num)
4013                 return HALMAC_RET_CFG_TXFIFO_PAGE_FAIL;
4014
4015         halmac_adapter->txff_allocation.high_queue_pg_num = HPQ_num;
4016         halmac_adapter->txff_allocation.low_queue_pg_num = lpq_nnum;
4017         halmac_adapter->txff_allocation.normal_queue_pg_num = NPQ_num;
4018         halmac_adapter->txff_allocation.extra_queue_pg_num = EXPQ_num;
4019         halmac_adapter->txff_allocation.pub_queue_pg_num = PUBQ_num;
4020
4021         return HALMAC_RET_SUCCESS;
4022 }
4023
4024 enum halmac_ret_status
4025 halmac_parse_intf_phy_88xx(struct halmac_adapter *halmac_adapter,
4026                            struct halmac_intf_phy_para_ *intf_phy_para,
4027                            enum halmac_intf_phy_platform platform,
4028                            enum hal_intf_phy intf_phy)
4029 {
4030         u16 value;
4031         u16 curr_cut;
4032         u16 offset;
4033         u16 ip_sel;
4034         struct halmac_intf_phy_para_ *curr_phy_para;
4035         struct halmac_api *halmac_api;
4036         void *driver_adapter = NULL;
4037         u8 result = HALMAC_RET_SUCCESS;
4038
4039         driver_adapter = halmac_adapter->driver_adapter;
4040         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4041
4042         switch (halmac_adapter->chip_version) {
4043         case HALMAC_CHIP_VER_A_CUT:
4044                 curr_cut = (u16)HALMAC_INTF_PHY_CUT_A;
4045                 break;
4046         case HALMAC_CHIP_VER_B_CUT:
4047                 curr_cut = (u16)HALMAC_INTF_PHY_CUT_B;
4048                 break;
4049         case HALMAC_CHIP_VER_C_CUT:
4050                 curr_cut = (u16)HALMAC_INTF_PHY_CUT_C;
4051                 break;
4052         case HALMAC_CHIP_VER_D_CUT:
4053                 curr_cut = (u16)HALMAC_INTF_PHY_CUT_D;
4054                 break;
4055         case HALMAC_CHIP_VER_E_CUT:
4056                 curr_cut = (u16)HALMAC_INTF_PHY_CUT_E;
4057                 break;
4058         case HALMAC_CHIP_VER_F_CUT:
4059                 curr_cut = (u16)HALMAC_INTF_PHY_CUT_F;
4060                 break;
4061         case HALMAC_CHIP_VER_TEST:
4062                 curr_cut = (u16)HALMAC_INTF_PHY_CUT_TESTCHIP;
4063                 break;
4064         default:
4065                 return HALMAC_RET_FAIL;
4066         }
4067
4068         for (curr_phy_para = intf_phy_para;; curr_phy_para++) {
4069                 if (!(curr_phy_para->cut & curr_cut) ||
4070                     !(curr_phy_para->plaform & (u16)platform))
4071                         continue;
4072
4073                 offset = curr_phy_para->offset;
4074                 value = curr_phy_para->value;
4075                 ip_sel = curr_phy_para->ip_sel;
4076
4077                 if (offset == 0xFFFF)
4078                         break;
4079
4080                 if (ip_sel == HALMAC_IP_SEL_MAC) {
4081                         HALMAC_REG_WRITE_8(halmac_adapter, (u32)offset,
4082                                            (u8)value);
4083                 } else if (intf_phy == HAL_INTF_PHY_USB2) {
4084                         result = halmac_usbphy_write_88xx(halmac_adapter,
4085                                                           (u8)offset, value,
4086                                                           HAL_INTF_PHY_USB2);
4087
4088                         if (result != HALMAC_RET_SUCCESS)
4089                                 pr_err("[ERR]Write USB2PHY fail!\n");
4090
4091                 } else if (intf_phy == HAL_INTF_PHY_USB3) {
4092                         result = halmac_usbphy_write_88xx(halmac_adapter,
4093                                                           (u8)offset, value,
4094                                                           HAL_INTF_PHY_USB3);
4095
4096                         if (result != HALMAC_RET_SUCCESS)
4097                                 pr_err("[ERR]Write USB3PHY fail!\n");
4098
4099                 } else if (intf_phy == HAL_INTF_PHY_PCIE_GEN1) {
4100                         if (ip_sel == HALMAC_IP_SEL_INTF_PHY)
4101                                 result = halmac_mdio_write_88xx(
4102                                         halmac_adapter, (u8)offset, value,
4103                                         HAL_INTF_PHY_PCIE_GEN1);
4104                         else
4105                                 result = halmac_dbi_write8_88xx(
4106                                         halmac_adapter, offset, (u8)value);
4107
4108                         if (result != HALMAC_RET_SUCCESS)
4109                                 pr_err("[ERR]MDIO write GEN1 fail!\n");
4110
4111                 } else if (intf_phy == HAL_INTF_PHY_PCIE_GEN2) {
4112                         if (ip_sel == HALMAC_IP_SEL_INTF_PHY)
4113                                 result = halmac_mdio_write_88xx(
4114                                         halmac_adapter, (u8)offset, value,
4115                                         HAL_INTF_PHY_PCIE_GEN2);
4116                         else
4117                                 result = halmac_dbi_write8_88xx(
4118                                         halmac_adapter, offset, (u8)value);
4119
4120                         if (result != HALMAC_RET_SUCCESS)
4121                                 pr_err("[ERR]MDIO write GEN2 fail!\n");
4122                 } else {
4123                         pr_err("[ERR]Parse intf phy cfg error!\n");
4124                 }
4125         }
4126
4127         return HALMAC_RET_SUCCESS;
4128 }
4129
4130 enum halmac_ret_status
4131 halmac_dbi_write32_88xx(struct halmac_adapter *halmac_adapter, u16 addr,
4132                         u32 data)
4133 {
4134         u8 tmp_u1b = 0;
4135         u32 count = 0;
4136         u16 write_addr = 0;
4137         void *driver_adapter = NULL;
4138         struct halmac_api *halmac_api;
4139
4140         driver_adapter = halmac_adapter->driver_adapter;
4141         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4142
4143         HALMAC_REG_WRITE_32(halmac_adapter, REG_DBI_WDATA_V1, data);
4144
4145         write_addr = ((addr & 0x0ffc) | (0x000F << 12));
4146         HALMAC_REG_WRITE_16(halmac_adapter, REG_DBI_FLAG_V1, write_addr);
4147
4148         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_DBI, DBG_DMESG,
4149                         "WriteAddr = %x\n", write_addr);
4150
4151         HALMAC_REG_WRITE_8(halmac_adapter, REG_DBI_FLAG_V1 + 2, 0x01);
4152         tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4153
4154         count = 20;
4155         while (tmp_u1b && count != 0) {
4156                 udelay(10);
4157                 tmp_u1b =
4158                         HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4159                 count--;
4160         }
4161
4162         if (tmp_u1b) {
4163                 pr_err("DBI write fail!\n");
4164                 return HALMAC_RET_FAIL;
4165         } else {
4166                 return HALMAC_RET_SUCCESS;
4167         }
4168 }
4169
4170 u32 halmac_dbi_read32_88xx(struct halmac_adapter *halmac_adapter, u16 addr)
4171 {
4172         u16 read_addr = addr & 0x0ffc;
4173         u8 tmp_u1b = 0;
4174         u32 count = 0;
4175         u32 ret = 0;
4176         void *driver_adapter = NULL;
4177         struct halmac_api *halmac_api;
4178
4179         driver_adapter = halmac_adapter->driver_adapter;
4180         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4181
4182         HALMAC_REG_WRITE_16(halmac_adapter, REG_DBI_FLAG_V1, read_addr);
4183
4184         HALMAC_REG_WRITE_8(halmac_adapter, REG_DBI_FLAG_V1 + 2, 0x2);
4185         tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4186
4187         count = 20;
4188         while (tmp_u1b && count != 0) {
4189                 udelay(10);
4190                 tmp_u1b =
4191                         HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4192                 count--;
4193         }
4194
4195         if (tmp_u1b) {
4196                 ret = 0xFFFF;
4197                 pr_err("DBI read fail!\n");
4198         } else {
4199                 ret = HALMAC_REG_READ_32(halmac_adapter, REG_DBI_RDATA_V1);
4200                 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_DBI, DBG_DMESG,
4201                                 "Read Value = %x\n", ret);
4202         }
4203
4204         return ret;
4205 }
4206
4207 enum halmac_ret_status
4208 halmac_dbi_write8_88xx(struct halmac_adapter *halmac_adapter, u16 addr, u8 data)
4209 {
4210         u8 tmp_u1b = 0;
4211         u32 count = 0;
4212         u16 write_addr = 0;
4213         u16 remainder = addr & (4 - 1);
4214         void *driver_adapter = NULL;
4215         struct halmac_api *halmac_api;
4216
4217         driver_adapter = halmac_adapter->driver_adapter;
4218         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4219
4220         HALMAC_REG_WRITE_8(halmac_adapter, REG_DBI_WDATA_V1 + remainder, data);
4221
4222         write_addr = ((addr & 0x0ffc) | (BIT(0) << (remainder + 12)));
4223
4224         HALMAC_REG_WRITE_16(halmac_adapter, REG_DBI_FLAG_V1, write_addr);
4225
4226         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_DBI, DBG_DMESG,
4227                         "WriteAddr = %x\n", write_addr);
4228
4229         HALMAC_REG_WRITE_8(halmac_adapter, REG_DBI_FLAG_V1 + 2, 0x01);
4230
4231         tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4232
4233         count = 20;
4234         while (tmp_u1b && count != 0) {
4235                 udelay(10);
4236                 tmp_u1b =
4237                         HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4238                 count--;
4239         }
4240
4241         if (tmp_u1b) {
4242                 pr_err("DBI write fail!\n");
4243                 return HALMAC_RET_FAIL;
4244         } else {
4245                 return HALMAC_RET_SUCCESS;
4246         }
4247 }
4248
4249 u8 halmac_dbi_read8_88xx(struct halmac_adapter *halmac_adapter, u16 addr)
4250 {
4251         u16 read_addr = addr & 0x0ffc;
4252         u8 tmp_u1b = 0;
4253         u32 count = 0;
4254         u8 ret = 0;
4255         void *driver_adapter = NULL;
4256         struct halmac_api *halmac_api;
4257
4258         driver_adapter = halmac_adapter->driver_adapter;
4259         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4260
4261         HALMAC_REG_WRITE_16(halmac_adapter, REG_DBI_FLAG_V1, read_addr);
4262         HALMAC_REG_WRITE_8(halmac_adapter, REG_DBI_FLAG_V1 + 2, 0x2);
4263
4264         tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4265
4266         count = 20;
4267         while (tmp_u1b && count != 0) {
4268                 udelay(10);
4269                 tmp_u1b =
4270                         HALMAC_REG_READ_8(halmac_adapter, REG_DBI_FLAG_V1 + 2);
4271                 count--;
4272         }
4273
4274         if (tmp_u1b) {
4275                 ret = 0xFF;
4276                 pr_err("DBI read fail!\n");
4277         } else {
4278                 ret = HALMAC_REG_READ_8(halmac_adapter,
4279                                         REG_DBI_RDATA_V1 + (addr & (4 - 1)));
4280                 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_DBI, DBG_DMESG,
4281                                 "Read Value = %x\n", ret);
4282         }
4283
4284         return ret;
4285 }
4286
4287 enum halmac_ret_status
4288 halmac_mdio_write_88xx(struct halmac_adapter *halmac_adapter, u8 addr, u16 data,
4289                        u8 speed)
4290 {
4291         u8 tmp_u1b = 0;
4292         u32 count = 0;
4293         void *driver_adapter = NULL;
4294         struct halmac_api *halmac_api;
4295         u8 real_addr = 0;
4296
4297         driver_adapter = halmac_adapter->driver_adapter;
4298         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4299
4300         HALMAC_REG_WRITE_16(halmac_adapter, REG_MDIO_V1, data);
4301
4302         /* address : 5bit */
4303         real_addr = (addr & 0x1F);
4304         HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG, real_addr);
4305
4306         if (speed == HAL_INTF_PHY_PCIE_GEN1) {
4307                 /* GEN1 page 0 */
4308                 if (addr < 0x20) {
4309                         /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b00 */
4310                         HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4311                                            0x00);
4312
4313                         /* GEN1 page 1 */
4314                 } else {
4315                         /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b01 */
4316                         HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4317                                            0x01);
4318                 }
4319
4320         } else if (speed == HAL_INTF_PHY_PCIE_GEN2) {
4321                 /* GEN2 page 0 */
4322                 if (addr < 0x20) {
4323                         /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b10 */
4324                         HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4325                                            0x02);
4326
4327                         /* GEN2 page 1 */
4328                 } else {
4329                         /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b11 */
4330                         HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4331                                            0x03);
4332                 }
4333         } else {
4334                 pr_err("Error Speed !\n");
4335         }
4336
4337         HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG,
4338                            HALMAC_REG_READ_8(halmac_adapter, REG_PCIE_MIX_CFG) |
4339                                    BIT_MDIO_WFLAG_V1);
4340
4341         tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_PCIE_MIX_CFG) &
4342                   BIT_MDIO_WFLAG_V1;
4343         count = 20;
4344
4345         while (tmp_u1b && count != 0) {
4346                 udelay(10);
4347                 tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_PCIE_MIX_CFG) &
4348                           BIT_MDIO_WFLAG_V1;
4349                 count--;
4350         }
4351
4352         if (tmp_u1b) {
4353                 pr_err("MDIO write fail!\n");
4354                 return HALMAC_RET_FAIL;
4355         } else {
4356                 return HALMAC_RET_SUCCESS;
4357         }
4358 }
4359
4360 u16 halmac_mdio_read_88xx(struct halmac_adapter *halmac_adapter, u8 addr,
4361                           u8 speed
4362
4363                           )
4364 {
4365         u16 ret = 0;
4366         u8 tmp_u1b = 0;
4367         u32 count = 0;
4368         void *driver_adapter = NULL;
4369         struct halmac_api *halmac_api;
4370         u8 real_addr = 0;
4371
4372         driver_adapter = halmac_adapter->driver_adapter;
4373         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4374
4375         /* address : 5bit */
4376         real_addr = (addr & 0x1F);
4377         HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG, real_addr);
4378
4379         if (speed == HAL_INTF_PHY_PCIE_GEN1) {
4380                 /* GEN1 page 0 */
4381                 if (addr < 0x20) {
4382                         /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b00 */
4383                         HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4384                                            0x00);
4385
4386                         /* GEN1 page 1 */
4387                 } else {
4388                         /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b01 */
4389                         HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4390                                            0x01);
4391                 }
4392
4393         } else if (speed == HAL_INTF_PHY_PCIE_GEN2) {
4394                 /* GEN2 page 0 */
4395                 if (addr < 0x20) {
4396                         /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b10 */
4397                         HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4398                                            0x02);
4399
4400                         /* GEN2 page 1 */
4401                 } else {
4402                         /* select MDIO PHY Addr : reg 0x3F8[28:24]=5'b11 */
4403                         HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG + 3,
4404                                            0x03);
4405                 }
4406         } else {
4407                 pr_err("Error Speed !\n");
4408         }
4409
4410         HALMAC_REG_WRITE_8(halmac_adapter, REG_PCIE_MIX_CFG,
4411                            HALMAC_REG_READ_8(halmac_adapter, REG_PCIE_MIX_CFG) |
4412                                    BIT_MDIO_RFLAG_V1);
4413
4414         tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_PCIE_MIX_CFG) &
4415                   BIT_MDIO_RFLAG_V1;
4416         count = 20;
4417
4418         while (tmp_u1b && count != 0) {
4419                 udelay(10);
4420                 tmp_u1b = HALMAC_REG_READ_8(halmac_adapter, REG_PCIE_MIX_CFG) &
4421                           BIT_MDIO_RFLAG_V1;
4422                 count--;
4423         }
4424
4425         if (tmp_u1b) {
4426                 ret = 0xFFFF;
4427                 pr_err("MDIO read fail!\n");
4428
4429         } else {
4430                 ret = HALMAC_REG_READ_16(halmac_adapter, REG_MDIO_V1 + 2);
4431                 HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_MDIO, DBG_DMESG,
4432                                 "Read Value = %x\n", ret);
4433         }
4434
4435         return ret;
4436 }
4437
4438 enum halmac_ret_status
4439 halmac_usbphy_write_88xx(struct halmac_adapter *halmac_adapter, u8 addr,
4440                          u16 data, u8 speed)
4441 {
4442         void *driver_adapter = NULL;
4443         struct halmac_api *halmac_api;
4444
4445         driver_adapter = halmac_adapter->driver_adapter;
4446         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4447
4448         if (speed == HAL_INTF_PHY_USB3) {
4449                 HALMAC_REG_WRITE_8(halmac_adapter, 0xff0d, (u8)data);
4450                 HALMAC_REG_WRITE_8(halmac_adapter, 0xff0e, (u8)(data >> 8));
4451                 HALMAC_REG_WRITE_8(halmac_adapter, 0xff0c, addr | BIT(7));
4452         } else if (speed == HAL_INTF_PHY_USB2) {
4453                 HALMAC_REG_WRITE_8(halmac_adapter, 0xfe41, (u8)data);
4454                 HALMAC_REG_WRITE_8(halmac_adapter, 0xfe40, addr);
4455                 HALMAC_REG_WRITE_8(halmac_adapter, 0xfe42, 0x81);
4456         } else {
4457                 pr_err("[ERR]Error USB Speed !\n");
4458                 return HALMAC_RET_NOT_SUPPORT;
4459         }
4460
4461         return HALMAC_RET_SUCCESS;
4462 }
4463
4464 u16 halmac_usbphy_read_88xx(struct halmac_adapter *halmac_adapter, u8 addr,
4465                             u8 speed)
4466 {
4467         void *driver_adapter = NULL;
4468         struct halmac_api *halmac_api;
4469         u16 value = 0;
4470
4471         driver_adapter = halmac_adapter->driver_adapter;
4472         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
4473
4474         if (speed == HAL_INTF_PHY_USB3) {
4475                 HALMAC_REG_WRITE_8(halmac_adapter, 0xff0c, addr | BIT(6));
4476                 value = (u16)(HALMAC_REG_READ_32(halmac_adapter, 0xff0c) >> 8);
4477         } else if (speed == HAL_INTF_PHY_USB2) {
4478                 if ((addr >= 0xE0) /*&& (addr <= 0xFF)*/)
4479                         addr -= 0x20;
4480                 if ((addr >= 0xC0) && (addr <= 0xDF)) {
4481                         HALMAC_REG_WRITE_8(halmac_adapter, 0xfe40, addr);
4482                         HALMAC_REG_WRITE_8(halmac_adapter, 0xfe42, 0x81);
4483                         value = HALMAC_REG_READ_8(halmac_adapter, 0xfe43);
4484                 } else {
4485                         pr_err("[ERR]Error USB2PHY offset!\n");
4486                         return HALMAC_RET_NOT_SUPPORT;
4487                 }
4488         } else {
4489                 pr_err("[ERR]Error USB Speed !\n");
4490                 return HALMAC_RET_NOT_SUPPORT;
4491         }
4492
4493         return value;
4494 }