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
halmac_init_offload_feature_state_machine_88xx(struct halmac_adapter * halmac_adapter)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
halmac_dump_efuse_88xx(struct halmac_adapter * halmac_adapter,enum halmac_efuse_read_cfg cfg)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
halmac_func_read_efuse_88xx(struct halmac_adapter * halmac_adapter,u32 offset,u32 size,u8 * efuse_map)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
halmac_read_hw_efuse_88xx(struct halmac_adapter * halmac_adapter,u32 offset,u32 size,u8 * efuse_map)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
halmac_dump_efuse_drv_88xx(struct halmac_adapter * halmac_adapter)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
halmac_dump_efuse_fw_88xx(struct halmac_adapter * halmac_adapter)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
halmac_func_write_efuse_88xx(struct halmac_adapter * halmac_adapter,u32 offset,u8 value)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
halmac_func_switch_efuse_bank_88xx(struct halmac_adapter * halmac_adapter,enum halmac_efuse_bank efuse_bank)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
halmac_eeprom_parser_88xx(struct halmac_adapter * halmac_adapter,u8 * physical_efuse_map,u8 * logical_efuse_map)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
halmac_read_logical_efuse_map_88xx(struct halmac_adapter * halmac_adapter,u8 * map)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
halmac_func_write_logical_efuse_88xx(struct halmac_adapter * halmac_adapter,u32 offset,u8 value)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
halmac_func_pg_efuse_by_map_88xx(struct halmac_adapter * halmac_adapter,struct halmac_pg_efuse_info * pg_efuse_info,enum halmac_efuse_read_cfg cfg)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
halmac_update_eeprom_mask_88xx(struct halmac_adapter * halmac_adapter,struct halmac_pg_efuse_info * pg_efuse_info,u8 * eeprom_mask_updated)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
halmac_check_efuse_enough_88xx(struct halmac_adapter * halmac_adapter,struct halmac_pg_efuse_info * pg_efuse_info,u8 * eeprom_mask_updated)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
halmac_program_efuse_88xx(struct halmac_adapter * halmac_adapter,struct halmac_pg_efuse_info * pg_efuse_info,u8 * eeprom_mask_updated)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
halmac_dlfw_to_mem_88xx(struct halmac_adapter * halmac_adapter,u8 * ram_code,u32 dest,u32 code_size)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
halmac_send_fwpkt_88xx(struct halmac_adapter * halmac_adapter,u8 * ram_code,u32 code_size)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
halmac_iddma_dlfw_88xx(struct halmac_adapter * halmac_adapter,u32 source,u32 dest,u32 length,u8 first)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
halmac_check_fw_chksum_88xx(struct halmac_adapter * halmac_adapter,u32 memory_address)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
halmac_dlfw_end_flow_88xx(struct halmac_adapter * halmac_adapter)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
halmac_free_dl_fw_end_flow_88xx(struct halmac_adapter * halmac_adapter)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
halmac_pwr_seq_parser_88xx(struct halmac_adapter * halmac_adapter,u8 cut,u8 fab,u8 intf,struct halmac_wl_pwr_cfg_ ** pp_pwr_seq_cfg)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
halmac_pwr_sub_seq_parer_do_cmd_88xx(struct halmac_adapter * halmac_adapter,struct halmac_wl_pwr_cfg_ * sub_seq_cmd,bool * reti)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
halmac_pwr_sub_seq_parer_88xx(struct halmac_adapter * halmac_adapter,u8 cut,u8 fab,u8 intf,struct halmac_wl_pwr_cfg_ * pwr_sub_seq_cfg)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
halmac_get_h2c_buff_free_space_88xx(struct halmac_adapter * halmac_adapter)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
halmac_send_h2c_pkt_88xx(struct halmac_adapter * halmac_adapter,u8 * hal_h2c_cmd,u32 size,bool ack)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
halmac_download_rsvd_page_88xx(struct halmac_adapter * halmac_adapter,u8 * hal_buf,u32 size)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
halmac_set_h2c_header_88xx(struct halmac_adapter * halmac_adapter,u8 * hal_h2c_hdr,u16 * seq,bool ack)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
halmac_set_fw_offload_h2c_header_88xx(struct halmac_adapter * halmac_adapter,u8 * hal_h2c_hdr,struct halmac_h2c_header_info * h2c_header_info,u16 * seq_num)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
halmac_send_h2c_set_pwr_mode_88xx(struct halmac_adapter * halmac_adapter,struct halmac_fwlps_option * hal_fw_lps_opt)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
halmac_func_send_original_h2c_88xx(struct halmac_adapter * halmac_adapter,u8 * original_h2c,u16 * seq,u8 ack)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
halmac_media_status_rpt_88xx(struct halmac_adapter * halmac_adapter,u8 op_mode,u8 mac_id_ind,u8 mac_id,u8 mac_id_end)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
halmac_send_h2c_update_packet_88xx(struct halmac_adapter * halmac_adapter,enum halmac_packet_id pkt_id,u8 * pkt,u32 pkt_size)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
halmac_send_h2c_phy_parameter_88xx(struct halmac_adapter * halmac_adapter,struct halmac_phy_parameter_info * para_info,bool full_fifo)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
halmac_enqueue_para_buff_88xx(struct halmac_adapter * halmac_adapter,struct halmac_phy_parameter_info * para_info,u8 * curr_buff_wptr,bool * end_cmd)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
halmac_gen_cfg_para_h2c_88xx(struct halmac_adapter * halmac_adapter,u8 * h2c_buff)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
halmac_send_h2c_run_datapack_88xx(struct halmac_adapter * halmac_adapter,enum halmac_data_type halmac_data_type)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
halmac_send_bt_coex_cmd_88xx(struct halmac_adapter * halmac_adapter,u8 * bt_buf,u32 bt_size,u8 ack)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
halmac_func_ctrl_ch_switch_88xx(struct halmac_adapter * halmac_adapter,struct halmac_ch_switch_option * cs_option)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
halmac_func_send_general_info_88xx(struct halmac_adapter * halmac_adapter,struct halmac_general_info * general_info)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
halmac_send_h2c_update_bcn_parse_info_88xx(struct halmac_adapter * halmac_adapter,struct halmac_bcn_ie_info * bcn_ie_info)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
halmac_send_h2c_ps_tuning_para_88xx(struct halmac_adapter * halmac_adapter)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
halmac_parse_c2h_packet_88xx(struct halmac_adapter * halmac_adapter,u8 * halmac_buf,u32 halmac_size)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
halmac_parse_c2h_debug_88xx(struct halmac_adapter * halmac_adapter,u8 * c2h_buf,u32 c2h_size)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
halmac_parse_scan_status_rpt_88xx(struct halmac_adapter * halmac_adapter,u8 * c2h_buf,u32 c2h_size)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
halmac_parse_psd_data_88xx(struct halmac_adapter * halmac_adapter,u8 * c2h_buf,u32 c2h_size)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
halmac_parse_efuse_data_88xx(struct halmac_adapter * halmac_adapter,u8 * c2h_buf,u32 c2h_size)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
halmac_parse_h2c_ack_88xx(struct halmac_adapter * halmac_adapter,u8 * c2h_buf,u32 c2h_size)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
halmac_parse_h2c_ack_phy_efuse_88xx(struct halmac_adapter * halmac_adapter,u8 * c2h_buf,u32 c2h_size)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
halmac_parse_h2c_ack_cfg_para_88xx(struct halmac_adapter * halmac_adapter,u8 * c2h_buf,u32 c2h_size)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
halmac_parse_h2c_ack_update_packet_88xx(struct halmac_adapter * halmac_adapter,u8 * c2h_buf,u32 c2h_size)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
halmac_parse_h2c_ack_update_datapack_88xx(struct halmac_adapter * halmac_adapter,u8 * c2h_buf,u32 c2h_size)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
halmac_parse_h2c_ack_run_datapack_88xx(struct halmac_adapter * halmac_adapter,u8 * c2h_buf,u32 c2h_size)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
halmac_parse_h2c_ack_channel_switch_88xx(struct halmac_adapter * halmac_adapter,u8 * c2h_buf,u32 c2h_size)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
halmac_parse_h2c_ack_iqk_88xx(struct halmac_adapter * halmac_adapter,u8 * c2h_buf,u32 c2h_size)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
halmac_parse_h2c_ack_power_tracking_88xx(struct halmac_adapter * halmac_adapter,u8 * c2h_buf,u32 c2h_size)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
halmac_convert_to_sdio_bus_offset_88xx(struct halmac_adapter * halmac_adapter,u32 * halmac_offset)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
halmac_update_sdio_free_page_88xx(struct halmac_adapter * halmac_adapter)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
halmac_update_oqt_free_space_88xx(struct halmac_adapter * halmac_adapter)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
halmac_query_efuse_curr_state_88xx(struct halmac_adapter * halmac_adapter)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
halmac_transition_efuse_state_88xx(struct halmac_adapter * halmac_adapter,enum halmac_efuse_cmd_construct_state dest_state)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
halmac_query_cfg_para_curr_state_88xx(struct halmac_adapter * halmac_adapter)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
halmac_transition_cfg_para_state_88xx(struct halmac_adapter * halmac_adapter,enum halmac_cfg_para_cmd_construct_state dest_state)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
halmac_query_scan_curr_state_88xx(struct halmac_adapter * halmac_adapter)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
halmac_transition_scan_state_88xx(struct halmac_adapter * halmac_adapter,enum halmac_scan_cmd_construct_state dest_state)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
halmac_query_cfg_para_status_88xx(struct halmac_adapter * halmac_adapter,enum halmac_cmd_process_status * process_status,u8 * data,u32 * size)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
halmac_query_dump_physical_efuse_status_88xx(struct halmac_adapter * halmac_adapter,enum halmac_cmd_process_status * process_status,u8 * data,u32 * size)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
halmac_query_dump_logical_efuse_status_88xx(struct halmac_adapter * halmac_adapter,enum halmac_cmd_process_status * process_status,u8 * data,u32 * size)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
halmac_query_channel_switch_status_88xx(struct halmac_adapter * halmac_adapter,enum halmac_cmd_process_status * process_status,u8 * data,u32 * size)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
halmac_query_update_packet_status_88xx(struct halmac_adapter * halmac_adapter,enum halmac_cmd_process_status * process_status,u8 * data,u32 * size)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
halmac_query_iqk_status_88xx(struct halmac_adapter * halmac_adapter,enum halmac_cmd_process_status * process_status,u8 * data,u32 * size)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
halmac_query_power_tracking_status_88xx(struct halmac_adapter * halmac_adapter,enum halmac_cmd_process_status * process_status,u8 * data,u32 * size)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
halmac_query_psd_status_88xx(struct halmac_adapter * halmac_adapter,enum halmac_cmd_process_status * process_status,u8 * data,u32 * size)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
halmac_verify_io_88xx(struct halmac_adapter * halmac_adapter)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
halmac_verify_send_rsvd_page_88xx(struct halmac_adapter * halmac_adapter)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
halmac_power_save_cb_88xx(void * cb_data)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
halmac_buffer_read_88xx(struct halmac_adapter * halmac_adapter,u32 offset,u32 size,enum hal_fifo_sel halmac_fifo_sel,u8 * fifo_map)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
halmac_restore_mac_register_88xx(struct halmac_adapter * halmac_adapter,struct halmac_restore_info * restore_info,u32 restore_num)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
halmac_api_record_id_88xx(struct halmac_adapter * halmac_adapter,enum halmac_api_id api_id)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
halmac_set_usb_mode_88xx(struct halmac_adapter * halmac_adapter,enum halmac_usb_mode usb_mode)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
halmac_enable_bb_rf_88xx(struct halmac_adapter * halmac_adapter,u8 enable)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
halmac_config_sdio_tx_page_threshold_88xx(struct halmac_adapter * halmac_adapter,struct halmac_tx_page_threshold_info * threshold_info)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
halmac_config_ampdu_88xx(struct halmac_adapter * halmac_adapter,struct halmac_ampdu_config * ampdu_config)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
halmac_check_oqt_88xx(struct halmac_adapter * halmac_adapter,u32 tx_agg_num,u8 * halmac_buf)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
halmac_rqpn_parser_88xx(struct halmac_adapter * halmac_adapter,enum halmac_trx_mode halmac_trx_mode,struct halmac_rqpn_ * rqpn_table)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
halmac_pg_num_parser_88xx(struct halmac_adapter * halmac_adapter,enum halmac_trx_mode halmac_trx_mode,struct halmac_pg_num_ * pg_num_table)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
halmac_parse_intf_phy_88xx(struct halmac_adapter * halmac_adapter,struct halmac_intf_phy_para_ * intf_phy_para,enum halmac_intf_phy_platform platform,enum hal_intf_phy intf_phy)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
halmac_dbi_write32_88xx(struct halmac_adapter * halmac_adapter,u16 addr,u32 data)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
halmac_dbi_read32_88xx(struct halmac_adapter * halmac_adapter,u16 addr)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
halmac_dbi_write8_88xx(struct halmac_adapter * halmac_adapter,u16 addr,u8 data)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
halmac_dbi_read8_88xx(struct halmac_adapter * halmac_adapter,u16 addr)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
halmac_mdio_write_88xx(struct halmac_adapter * halmac_adapter,u8 addr,u16 data,u8 speed)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
halmac_mdio_read_88xx(struct halmac_adapter * halmac_adapter,u8 addr,u8 speed)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
halmac_usbphy_write_88xx(struct halmac_adapter * halmac_adapter,u8 addr,u16 data,u8 speed)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
halmac_usbphy_read_88xx(struct halmac_adapter * halmac_adapter,u8 addr,u8 speed)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 }
4466