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