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