1 /******************************************************************************
2 *
3 * Copyright(c) 2016 - 2019 Realtek Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 ******************************************************************************/
15
16 #include "halmac_efuse_88xx.h"
17 #include "halmac_88xx_cfg.h"
18 #include "halmac_common_88xx.h"
19 #include "halmac_init_88xx.h"
20
21 #if HALMAC_88XX_SUPPORT
22
23 #define RSVD_EFUSE_SIZE 16
24 #define RSVD_CS_EFUSE_SIZE 24
25 #define FEATURE_DUMP_PHY_EFUSE HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE
26 #define FEATURE_DUMP_LOG_EFUSE HALMAC_FEATURE_DUMP_LOGICAL_EFUSE
27 #define FEATURE_DUMP_LOG_EFUSE_MASK HALMAC_FEATURE_DUMP_LOGICAL_EFUSE_MASK
28
29 #define SUPER_USB_ZONE0_START 0x150
30 #define SUPER_USB_ZONE0_END 0x199
31 #define SUPER_USB_ZONE1_START 0x200
32 #define SUPER_USB_ZONE1_END 0x217
33 #define SUPER_USB_RE_PG_CK_ZONE0_START 0x15D
34 #define SUPER_USB_RE_PG_CK_ZONE0_END 0x164
35
36 static u8 bt_switch = 0;
37
38 static enum halmac_cmd_construct_state
39 efuse_cmd_cnstr_state_88xx(struct halmac_adapter *adapter);
40
41 static enum halmac_ret_status
42 proc_dump_efuse_88xx(struct halmac_adapter *adapter,
43 enum halmac_efuse_read_cfg cfg);
44
45 static enum halmac_ret_status
46 read_hw_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u32 size,
47 u8 *map);
48
49 static enum halmac_ret_status
50 read_log_efuse_map_88xx(struct halmac_adapter *adapter, u8 *map);
51
52 static enum halmac_ret_status
53 proc_pg_efuse_by_map_88xx(struct halmac_adapter *adapter,
54 struct halmac_pg_efuse_info *info,
55 enum halmac_efuse_read_cfg cfg);
56
57 static enum halmac_ret_status
58 dump_efuse_fw_88xx(struct halmac_adapter *adapter);
59
60 static enum halmac_ret_status
61 dump_efuse_drv_88xx(struct halmac_adapter *adapter);
62
63 static enum halmac_ret_status
64 proc_write_log_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u8 value);
65
66 static enum halmac_ret_status
67 proc_write_log_efuse_word_88xx(struct halmac_adapter *adapter, u32 offset,
68 u16 value);
69
70 static enum halmac_ret_status
71 update_eeprom_mask_88xx(struct halmac_adapter *adapter,
72 struct halmac_pg_efuse_info *info, u8 *updated_mask);
73
74 static enum halmac_ret_status
75 check_efuse_enough_88xx(struct halmac_adapter *adapter,
76 struct halmac_pg_efuse_info *info, u8 *updated_mask);
77
78 static enum halmac_ret_status
79 pg_extend_efuse_88xx(struct halmac_adapter *adapter,
80 struct halmac_pg_efuse_info *info, u8 word_en,
81 u8 pre_word_en, u32 eeprom_offset);
82
83 static enum halmac_ret_status
84 proc_pg_efuse_88xx(struct halmac_adapter *adapter,
85 struct halmac_pg_efuse_info *info, u8 word_en,
86 u8 pre_word_en, u32 eeprom_offset);
87
88 static enum halmac_ret_status
89 pg_super_usb_efuse_88xx(struct halmac_adapter *adapter,
90 struct halmac_pg_efuse_info *info, u8 word_en,
91 u8 pre_word_en, u32 eeprom_offset);
92
93 static enum halmac_ret_status
94 program_efuse_88xx(struct halmac_adapter *adapter,
95 struct halmac_pg_efuse_info *info, u8 *updated_mask);
96
97 static void
98 mask_eeprom_88xx(struct halmac_adapter *adapter,
99 struct halmac_pg_efuse_info *info);
100
101 static enum halmac_ret_status
102 proc_gen_super_usb_map_88xx(struct halmac_adapter *adapter, u8 *drv_map,
103 u8 *updated_map, u8 *updated_mask);
104
105 static enum halmac_ret_status
106 super_usb_efuse_parser_88xx(struct halmac_adapter *adapter, u8 *phy_map,
107 u8 *log_map, u8 *log_mask);
108
109 static enum halmac_ret_status
110 super_usb_chk_88xx(struct halmac_adapter *adapter, u8 *super_usb);
111
112 static enum halmac_ret_status
113 log_efuse_re_pg_chk_88xx(struct halmac_adapter *adapter, u8 *efuse_mask,
114 u32 addr, u8 *re_pg);
115
116 static enum halmac_ret_status
117 super_usb_fmt_chk_88xx(struct halmac_adapter *adapter, u8 *re_pg);
118
119 static enum halmac_ret_status
120 super_usb_re_pg_chk_88xx(struct halmac_adapter *adapter, u8 *phy_map,
121 u8 *re_pg);
122
123 /**
124 * dump_efuse_map_88xx() - dump "physical" efuse map
125 * @adapter : the adapter of halmac
126 * @cfg : dump efuse method
127 * Author : Ivan Lin/KaiYuan Chang
128 * Return : enum halmac_ret_status
129 * More details of status code can be found in prototype document
130 */
131 enum halmac_ret_status
dump_efuse_map_88xx(struct halmac_adapter * adapter,enum halmac_efuse_read_cfg cfg)132 dump_efuse_map_88xx(struct halmac_adapter *adapter,
133 enum halmac_efuse_read_cfg cfg)
134 {
135 u8 *map = NULL;
136 u8 *efuse_map;
137 u32 efuse_size = adapter->hw_cfg_info.efuse_size;
138 u32 prtct_efuse_size = adapter->hw_cfg_info.prtct_efuse_size;
139 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
140 enum halmac_cmd_process_status *proc_status;
141
142 proc_status = &adapter->halmac_state.efuse_state.proc_status;
143
144 if (cfg == HALMAC_EFUSE_R_FW &&
145 halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
146 return HALMAC_RET_NO_DLFW;
147
148 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
149 PLTFM_MSG_TRACE("[TRACE]cfg = %d\n", cfg);
150
151 if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
152 PLTFM_MSG_WARN("[WARN]Wait event(efuse)\n");
153 return HALMAC_RET_BUSY_STATE;
154 }
155
156 if (efuse_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_IDLE) {
157 PLTFM_MSG_WARN("[WARN]Not idle(efuse)\n");
158 return HALMAC_RET_ERROR_STATE;
159 }
160
161 if (adapter->halmac_state.mac_pwr == HALMAC_MAC_POWER_OFF)
162 PLTFM_MSG_ERR("[ERR]Dump efuse in suspend\n");
163
164 *proc_status = HALMAC_CMD_PROCESS_IDLE;
165 adapter->evnt.phy_efuse_map = 1;
166
167 status = switch_efuse_bank_88xx(adapter, HALMAC_EFUSE_BANK_WIFI);
168 if (status != HALMAC_RET_SUCCESS) {
169 PLTFM_MSG_ERR("[ERR]switch efuse bank!!\n");
170 return status;
171 }
172
173 status = proc_dump_efuse_88xx(adapter, cfg);
174 if (status != HALMAC_RET_SUCCESS) {
175 PLTFM_MSG_ERR("[ERR]dump efuse!!\n");
176 return status;
177 }
178
179 if (adapter->efuse_map_valid == 1) {
180 *proc_status = HALMAC_CMD_PROCESS_DONE;
181 efuse_map = adapter->efuse_map;
182
183 map = (u8 *)PLTFM_MALLOC(efuse_size);
184 if (!map) {
185 PLTFM_MSG_ERR("[ERR]malloc!!\n");
186 return HALMAC_RET_MALLOC_FAIL;
187 }
188 PLTFM_MEMSET(map, 0xFF, efuse_size);
189 PLTFM_MUTEX_LOCK(&adapter->efuse_mutex);
190 #if HALMAC_PLATFORM_WINDOWS
191 PLTFM_MEMCPY(map, efuse_map, efuse_size);
192 #else
193 PLTFM_MEMCPY(map, efuse_map, efuse_size - prtct_efuse_size);
194 PLTFM_MEMCPY(map + efuse_size - prtct_efuse_size +
195 RSVD_CS_EFUSE_SIZE,
196 efuse_map + efuse_size - prtct_efuse_size +
197 RSVD_CS_EFUSE_SIZE,
198 prtct_efuse_size - RSVD_EFUSE_SIZE -
199 RSVD_CS_EFUSE_SIZE);
200 #endif
201 PLTFM_MUTEX_UNLOCK(&adapter->efuse_mutex);
202
203 PLTFM_EVENT_SIG(HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE,
204 *proc_status, map, efuse_size);
205 adapter->evnt.phy_efuse_map = 0;
206
207 PLTFM_FREE(map, efuse_size);
208 }
209
210 if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
211 HALMAC_RET_SUCCESS)
212 return HALMAC_RET_ERROR_STATE;
213
214 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
215
216 return HALMAC_RET_SUCCESS;
217 }
218
219 /**
220 * dump_efuse_map_bt_88xx() - dump "BT physical" efuse map
221 * @adapter : the adapter of halmac
222 * @bank : bt efuse bank
223 * @size : bt efuse map size. get from halmac_get_efuse_size API
224 * @map : bt efuse map
225 * Author : Soar / Ivan Lin
226 * Return : enum halmac_ret_status
227 * More details of status code can be found in prototype document
228 */
229 enum halmac_ret_status
dump_efuse_map_bt_88xx(struct halmac_adapter * adapter,enum halmac_efuse_bank bank,u32 size,u8 * map)230 dump_efuse_map_bt_88xx(struct halmac_adapter *adapter,
231 enum halmac_efuse_bank bank, u32 size, u8 *map)
232 {
233 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
234 enum halmac_cmd_process_status *proc_status;
235
236 proc_status = &adapter->halmac_state.efuse_state.proc_status;
237
238 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
239
240 if (adapter->hw_cfg_info.bt_efuse_size != size)
241 return HALMAC_RET_EFUSE_SIZE_INCORRECT;
242
243 if (bank >= HALMAC_EFUSE_BANK_MAX || bank == HALMAC_EFUSE_BANK_WIFI) {
244 PLTFM_MSG_ERR("[ERR]Undefined BT bank\n");
245 return HALMAC_RET_EFUSE_BANK_INCORRECT;
246 }
247
248 if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
249 PLTFM_MSG_WARN("[WARN]Wait event(efuse)\n");
250 return HALMAC_RET_BUSY_STATE;
251 }
252
253 if (efuse_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_IDLE) {
254 PLTFM_MSG_WARN("[WARN]Not idle(efuse)\n");
255 return HALMAC_RET_ERROR_STATE;
256 }
257
258 status = switch_efuse_bank_88xx(adapter, bank);
259 if (status != HALMAC_RET_SUCCESS) {
260 PLTFM_MSG_ERR("[ERR]switch efuse bank!!\n");
261 return status;
262 }
263 bt_switch = 1;
264
265 status = read_hw_efuse_88xx(adapter, 0, size, map);
266 if (status != HALMAC_RET_SUCCESS) {
267 bt_switch = 0;
268 PLTFM_MSG_ERR("[ERR]read hw efuse\n");
269 return status;
270 }
271
272 status = switch_efuse_bank_88xx(adapter, HALMAC_EFUSE_BANK_WIFI);
273 if (status != HALMAC_RET_SUCCESS) {
274 bt_switch = 0;
275 PLTFM_MSG_ERR("[ERR]switch efuse bank!!\n");
276 return status;
277 }
278 bt_switch = 0;
279
280 if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
281 HALMAC_RET_SUCCESS)
282 return HALMAC_RET_ERROR_STATE;
283
284 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
285
286 return HALMAC_RET_SUCCESS;
287 }
288
289 /**
290 * write_efuse_bt_88xx() - write "BT physical" efuse offset
291 * @adapter : the adapter of halmac
292 * @offset : offset
293 * @value : Write value
294 * @map : bt efuse map
295 * Author : Soar
296 * Return : enum halmac_ret_status
297 * More details of status code can be found in prototype document
298 */
299 enum halmac_ret_status
write_efuse_bt_88xx(struct halmac_adapter * adapter,u32 offset,u8 value,enum halmac_efuse_bank bank)300 write_efuse_bt_88xx(struct halmac_adapter *adapter, u32 offset, u8 value,
301 enum halmac_efuse_bank bank)
302 {
303 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
304 enum halmac_cmd_process_status *proc_status;
305
306 proc_status = &adapter->halmac_state.efuse_state.proc_status;
307
308 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
309
310 if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
311 PLTFM_MSG_WARN("[WARN]Wait event(efuse)\n");
312 return HALMAC_RET_BUSY_STATE;
313 }
314
315 if (efuse_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_IDLE) {
316 PLTFM_MSG_WARN("[WARN]Not idle(efuse)\n");
317 return HALMAC_RET_ERROR_STATE;
318 }
319
320 if (offset >= adapter->hw_cfg_info.efuse_size) {
321 PLTFM_MSG_ERR("[ERR]Offset is too large\n");
322 return HALMAC_RET_EFUSE_SIZE_INCORRECT;
323 }
324
325 if (bank > HALMAC_EFUSE_BANK_MAX || bank == HALMAC_EFUSE_BANK_WIFI) {
326 PLTFM_MSG_ERR("[ERR]Undefined BT bank\n");
327 return HALMAC_RET_EFUSE_BANK_INCORRECT;
328 }
329
330 status = switch_efuse_bank_88xx(adapter, bank);
331 if (status != HALMAC_RET_SUCCESS) {
332 PLTFM_MSG_ERR("[ERR]switch efuse bank!!\n");
333 return status;
334 }
335 bt_switch = 1;
336
337 status = write_hw_efuse_88xx(adapter, offset, value);
338 if (status != HALMAC_RET_SUCCESS) {
339 bt_switch = 0;
340 PLTFM_MSG_ERR("[ERR]write efuse\n");
341 return status;
342 }
343
344 status = switch_efuse_bank_88xx(adapter, HALMAC_EFUSE_BANK_WIFI);
345 if (status != HALMAC_RET_SUCCESS) {
346 bt_switch = 0;
347 PLTFM_MSG_ERR("[ERR]switch efuse bank!!\n");
348 return status;
349 }
350 bt_switch = 0;
351
352 if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
353 HALMAC_RET_SUCCESS)
354 return HALMAC_RET_ERROR_STATE;
355
356 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
357
358 return HALMAC_RET_SUCCESS;
359 }
360
361 /**
362 * read_efuse_bt_88xx() - read "BT physical" efuse offset
363 * @adapter : the adapter of halmac
364 * @offset : offset
365 * @value : 1 byte efuse value
366 * @bank : efuse bank
367 * Author : Soar
368 * Return : enum halmac_ret_status
369 * More details of status code can be found in prototype document
370 */
371 enum halmac_ret_status
read_efuse_bt_88xx(struct halmac_adapter * adapter,u32 offset,u8 * value,enum halmac_efuse_bank bank)372 read_efuse_bt_88xx(struct halmac_adapter *adapter, u32 offset, u8 *value,
373 enum halmac_efuse_bank bank)
374 {
375 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
376 enum halmac_cmd_process_status *proc_status;
377
378 proc_status = &adapter->halmac_state.efuse_state.proc_status;
379
380 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
381
382 if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
383 PLTFM_MSG_WARN("[WARN]Wait event(efuse)\n");
384 return HALMAC_RET_BUSY_STATE;
385 }
386
387 if (efuse_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_IDLE) {
388 PLTFM_MSG_WARN("[WARN]Not idle(efuse)\n");
389 return HALMAC_RET_ERROR_STATE;
390 }
391
392 if (offset >= adapter->hw_cfg_info.efuse_size) {
393 PLTFM_MSG_ERR("[ERR]Offset is too large\n");
394 return HALMAC_RET_EFUSE_SIZE_INCORRECT;
395 }
396
397 if (bank > HALMAC_EFUSE_BANK_MAX || bank == HALMAC_EFUSE_BANK_WIFI) {
398 PLTFM_MSG_ERR("[ERR]Undefined BT bank\n");
399 return HALMAC_RET_EFUSE_BANK_INCORRECT;
400 }
401
402 status = switch_efuse_bank_88xx(adapter, bank);
403 if (status != HALMAC_RET_SUCCESS) {
404 PLTFM_MSG_ERR("[ERR]switch efuse bank\n");
405 return status;
406 }
407 bt_switch = 1;
408
409 status = read_efuse_88xx(adapter, offset, 1, value);
410 if (status != HALMAC_RET_SUCCESS) {
411 bt_switch = 0;
412 PLTFM_MSG_ERR("[ERR]read efuse\n");
413 return status;
414 }
415
416 status = switch_efuse_bank_88xx(adapter, HALMAC_EFUSE_BANK_WIFI);
417 if (status != HALMAC_RET_SUCCESS) {
418 bt_switch = 0;
419 PLTFM_MSG_ERR("[ERR]switch efuse bank!!\n");
420 return status;
421 }
422 bt_switch = 0;
423
424 if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
425 HALMAC_RET_SUCCESS)
426 return HALMAC_RET_ERROR_STATE;
427
428 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
429
430 return HALMAC_RET_SUCCESS;
431 }
432
433 /**
434 * cfg_efuse_auto_check_88xx() - check efuse after writing it
435 * @adapter : the adapter of halmac
436 * @enable : 1, enable efuse auto check. others, disable
437 * Author : Soar
438 * Return : enum halmac_ret_status
439 * More details of status code can be found in prototype document
440 */
441 enum halmac_ret_status
cfg_efuse_auto_check_88xx(struct halmac_adapter * adapter,u8 enable)442 cfg_efuse_auto_check_88xx(struct halmac_adapter *adapter, u8 enable)
443 {
444 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
445
446 adapter->efuse_auto_check_en = enable;
447
448 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
449
450 return HALMAC_RET_SUCCESS;
451 }
452
453 /**
454 * get_efuse_available_size_88xx() - get efuse available size
455 * @adapter : the adapter of halmac
456 * @size : physical efuse available size
457 * Author : Soar
458 * Return : enum halmac_ret_status
459 * More details of status code can be found in prototype document
460 */
461 enum halmac_ret_status
get_efuse_available_size_88xx(struct halmac_adapter * adapter,u32 * size)462 get_efuse_available_size_88xx(struct halmac_adapter *adapter, u32 *size)
463 {
464 enum halmac_ret_status status;
465
466 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
467
468 status = dump_log_efuse_map_88xx(adapter, HALMAC_EFUSE_R_DRV);
469
470 if (status != HALMAC_RET_SUCCESS)
471 return status;
472
473 *size = adapter->hw_cfg_info.efuse_size -
474 adapter->hw_cfg_info.prtct_efuse_size - adapter->efuse_end;
475
476 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
477
478 return HALMAC_RET_SUCCESS;
479 }
480
481 /**
482 * get_efuse_size_88xx() - get "physical" efuse size
483 * @adapter : the adapter of halmac
484 * @size : physical efuse size
485 * Author : Ivan Lin/KaiYuan Chang
486 * Return : enum halmac_ret_status
487 * More details of status code can be found in prototype document
488 */
489 enum halmac_ret_status
get_efuse_size_88xx(struct halmac_adapter * adapter,u32 * size)490 get_efuse_size_88xx(struct halmac_adapter *adapter, u32 *size)
491 {
492 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
493
494 *size = adapter->hw_cfg_info.efuse_size;
495
496 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
497
498 return HALMAC_RET_SUCCESS;
499 }
500
501 /**
502 * get_log_efuse_size_88xx() - get "logical" efuse size
503 * @adapter : the adapter of halmac
504 * @size : logical efuse size
505 * Author : Ivan Lin/KaiYuan Chang
506 * Return : enum halmac_ret_status
507 * More details of status code can be found in prototype document
508 */
509 enum halmac_ret_status
get_log_efuse_size_88xx(struct halmac_adapter * adapter,u32 * size)510 get_log_efuse_size_88xx(struct halmac_adapter *adapter, u32 *size)
511 {
512 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
513
514 *size = adapter->hw_cfg_info.eeprom_size;
515
516 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
517
518 return HALMAC_RET_SUCCESS;
519 }
520
521 /**
522 * dump_log_efuse_map_88xx() - dump "logical" efuse map
523 * @adapter : the adapter of halmac
524 * @cfg : dump efuse method
525 * Author : Soar
526 * Return : enum halmac_ret_status
527 * More details of status code can be found in prototype document
528 */
529 enum halmac_ret_status
dump_log_efuse_map_88xx(struct halmac_adapter * adapter,enum halmac_efuse_read_cfg cfg)530 dump_log_efuse_map_88xx(struct halmac_adapter *adapter,
531 enum halmac_efuse_read_cfg cfg)
532 {
533 u8 *map = NULL;
534 u32 size = adapter->hw_cfg_info.eeprom_size;
535 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
536 enum halmac_cmd_process_status *proc_status;
537
538 proc_status = &adapter->halmac_state.efuse_state.proc_status;
539
540 if (cfg == HALMAC_EFUSE_R_FW &&
541 halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
542 return HALMAC_RET_NO_DLFW;
543
544 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
545 PLTFM_MSG_TRACE("[TRACE]cfg = %d\n", cfg);
546
547 if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
548 PLTFM_MSG_WARN("[WARN]Wait event(efuse)\n");
549 return HALMAC_RET_BUSY_STATE;
550 }
551
552 if (efuse_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_IDLE) {
553 PLTFM_MSG_WARN("[WARN]Not idle(efuse)\n");
554 return HALMAC_RET_ERROR_STATE;
555 }
556
557 if (adapter->halmac_state.mac_pwr == HALMAC_MAC_POWER_OFF)
558 PLTFM_MSG_ERR("[ERR]Dump efuse in suspend\n");
559
560 *proc_status = HALMAC_CMD_PROCESS_IDLE;
561 adapter->evnt.log_efuse_map = 1;
562
563 status = switch_efuse_bank_88xx(adapter, HALMAC_EFUSE_BANK_WIFI);
564 if (status != HALMAC_RET_SUCCESS) {
565 PLTFM_MSG_ERR("[ERR]switch efuse bank\n");
566 return status;
567 }
568
569 status = proc_dump_efuse_88xx(adapter, cfg);
570 if (status != HALMAC_RET_SUCCESS) {
571 PLTFM_MSG_ERR("[ERR]dump efuse\n");
572 return status;
573 }
574
575 if (adapter->efuse_map_valid == 1) {
576 *proc_status = HALMAC_CMD_PROCESS_DONE;
577
578 map = (u8 *)PLTFM_MALLOC(size);
579 if (!map) {
580 PLTFM_MSG_ERR("[ERR]malloc map\n");
581 return HALMAC_RET_MALLOC_FAIL;
582 }
583 PLTFM_MEMSET(map, 0xFF, size);
584
585 if (eeprom_parser_88xx(adapter, adapter->efuse_map, map) !=
586 HALMAC_RET_SUCCESS) {
587 PLTFM_FREE(map, size);
588 return HALMAC_RET_EEPROM_PARSING_FAIL;
589 }
590
591 PLTFM_EVENT_SIG(HALMAC_FEATURE_DUMP_LOGICAL_EFUSE,
592 *proc_status, map, size);
593 adapter->evnt.log_efuse_map = 0;
594
595 PLTFM_FREE(map, size);
596 }
597
598 if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
599 HALMAC_RET_SUCCESS)
600 return HALMAC_RET_ERROR_STATE;
601
602 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
603
604 return HALMAC_RET_SUCCESS;
605 }
606
607 enum halmac_ret_status
dump_log_efuse_mask_88xx(struct halmac_adapter * adapter,enum halmac_efuse_read_cfg cfg)608 dump_log_efuse_mask_88xx(struct halmac_adapter *adapter,
609 enum halmac_efuse_read_cfg cfg)
610 {
611 u8 *map = NULL;
612 u32 size = adapter->hw_cfg_info.eeprom_size;
613 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
614 enum halmac_cmd_process_status *proc_status;
615
616 proc_status = &adapter->halmac_state.efuse_state.proc_status;
617
618 if (cfg == HALMAC_EFUSE_R_FW &&
619 halmac_fw_validate(adapter) != HALMAC_RET_SUCCESS)
620 return HALMAC_RET_NO_DLFW;
621
622 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
623 PLTFM_MSG_TRACE("[TRACE]cfg = %d\n", cfg);
624
625 if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
626 PLTFM_MSG_WARN("[WARN]Wait event(efuse)\n");
627 return HALMAC_RET_BUSY_STATE;
628 }
629
630 if (efuse_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_IDLE) {
631 PLTFM_MSG_WARN("[WARN]Not idle(efuse)\n");
632 return HALMAC_RET_ERROR_STATE;
633 }
634
635 if (adapter->halmac_state.mac_pwr == HALMAC_MAC_POWER_OFF)
636 PLTFM_MSG_ERR("[ERR]Dump efuse in suspend\n");
637
638 *proc_status = HALMAC_CMD_PROCESS_IDLE;
639 adapter->evnt.log_efuse_mask = 1;
640
641 status = switch_efuse_bank_88xx(adapter, HALMAC_EFUSE_BANK_WIFI);
642 if (status != HALMAC_RET_SUCCESS) {
643 PLTFM_MSG_ERR("[ERR]switch efuse bank\n");
644 return status;
645 }
646
647 status = proc_dump_efuse_88xx(adapter, cfg);
648 if (status != HALMAC_RET_SUCCESS) {
649 PLTFM_MSG_ERR("[ERR]dump efuse\n");
650 return status;
651 }
652
653 if (adapter->efuse_map_valid == 1) {
654 *proc_status = HALMAC_CMD_PROCESS_DONE;
655
656 map = (u8 *)PLTFM_MALLOC(size);
657 if (!map) {
658 PLTFM_MSG_ERR("[ERR]malloc map\n");
659 return HALMAC_RET_MALLOC_FAIL;
660 }
661 PLTFM_MEMSET(map, 0xFF, size);
662
663 if (eeprom_mask_parser_88xx(adapter, adapter->efuse_map, map) !=
664 HALMAC_RET_SUCCESS) {
665 PLTFM_FREE(map, size);
666 return HALMAC_RET_EEPROM_PARSING_FAIL;
667 }
668
669 PLTFM_EVENT_SIG(HALMAC_FEATURE_DUMP_LOGICAL_EFUSE_MASK,
670 *proc_status, map, size);
671 adapter->evnt.log_efuse_mask = 0;
672
673 PLTFM_FREE(map, size);
674 }
675
676 if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
677 HALMAC_RET_SUCCESS)
678 return HALMAC_RET_ERROR_STATE;
679
680 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
681
682 return HALMAC_RET_SUCCESS;
683 }
684
685 /**
686 * read_logical_efuse_88xx() - read logical efuse map 1 byte
687 * @adapter : the adapter of halmac
688 * @offset : offset
689 * @value : 1 byte efuse value
690 * Author : Soar
691 * Return : enum halmac_ret_status
692 * More details of status code can be found in prototype document
693 */
694 enum halmac_ret_status
read_logical_efuse_88xx(struct halmac_adapter * adapter,u32 offset,u8 * value)695 read_logical_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u8 *value)
696 {
697 u8 *map = NULL;
698 u32 size = adapter->hw_cfg_info.eeprom_size;
699 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
700 enum halmac_cmd_process_status *proc_status;
701
702 proc_status = &adapter->halmac_state.efuse_state.proc_status;
703
704 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
705
706 if (offset >= size) {
707 PLTFM_MSG_ERR("[ERR]Offset is too large\n");
708 return HALMAC_RET_EFUSE_SIZE_INCORRECT;
709 }
710
711 if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
712 PLTFM_MSG_WARN("[WARN]Wait event(efuse)\n");
713 return HALMAC_RET_BUSY_STATE;
714 }
715 if (efuse_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_IDLE) {
716 PLTFM_MSG_WARN("[WARN]Not idle(efuse)\n");
717 return HALMAC_RET_ERROR_STATE;
718 }
719
720 status = switch_efuse_bank_88xx(adapter, HALMAC_EFUSE_BANK_WIFI);
721 if (status != HALMAC_RET_SUCCESS) {
722 PLTFM_MSG_ERR("[ERR]switch efuse bank\n");
723 return status;
724 }
725
726 map = (u8 *)PLTFM_MALLOC(size);
727 if (!map) {
728 PLTFM_MSG_ERR("[ERR]malloc map\n");
729 return HALMAC_RET_MALLOC_FAIL;
730 }
731 PLTFM_MEMSET(map, 0xFF, size);
732
733 status = read_log_efuse_map_88xx(adapter, map);
734 if (status != HALMAC_RET_SUCCESS) {
735 PLTFM_MSG_ERR("[ERR]read logical efuse\n");
736 PLTFM_FREE(map, size);
737 return status;
738 }
739
740 *value = *(map + offset);
741
742 if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
743 HALMAC_RET_SUCCESS) {
744 PLTFM_FREE(map, size);
745 return HALMAC_RET_ERROR_STATE;
746 }
747
748 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
749
750 PLTFM_FREE(map, size);
751
752 return HALMAC_RET_SUCCESS;
753 }
754
755 /**
756 * write_log_efuse_88xx() - write "logical" efuse offset
757 * @adapter : the adapter of halmac
758 * @offset : offset
759 * @value : value
760 * Author : Soar
761 * Return : enum halmac_ret_status
762 * More details of status code can be found in prototype document
763 */
764 enum halmac_ret_status
write_log_efuse_88xx(struct halmac_adapter * adapter,u32 offset,u8 value)765 write_log_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u8 value)
766 {
767 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
768 enum halmac_cmd_process_status *proc_status;
769
770 proc_status = &adapter->halmac_state.efuse_state.proc_status;
771
772 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
773
774 if (offset >= adapter->hw_cfg_info.eeprom_size) {
775 PLTFM_MSG_ERR("[ERR]Offset is too large\n");
776 return HALMAC_RET_EFUSE_SIZE_INCORRECT;
777 }
778
779 if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
780 PLTFM_MSG_WARN("[WARN]Wait event(efuse)\n");
781 return HALMAC_RET_BUSY_STATE;
782 }
783
784 if (efuse_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_IDLE) {
785 PLTFM_MSG_WARN("[WARN]Not idle(efuse)\n");
786 return HALMAC_RET_ERROR_STATE;
787 }
788
789 status = switch_efuse_bank_88xx(adapter, HALMAC_EFUSE_BANK_WIFI);
790 if (status != HALMAC_RET_SUCCESS) {
791 PLTFM_MSG_ERR("[ERR]switch efuse bank\n");
792 return status;
793 }
794
795 status = proc_write_log_efuse_88xx(adapter, offset, value);
796 if (status != HALMAC_RET_SUCCESS) {
797 PLTFM_MSG_ERR("[ERR]write logical efuse\n");
798 return status;
799 }
800
801 if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
802 HALMAC_RET_SUCCESS)
803 return HALMAC_RET_ERROR_STATE;
804
805 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
806
807 return HALMAC_RET_SUCCESS;
808 }
809
810 /**
811 * write_log_efuse_word_88xx() - write "logical" efuse offset word
812 * @adapter : the adapter of halmac
813 * @offset : offset
814 * @value : value
815 * Author : Soar
816 * Return : enum halmac_ret_status
817 * More details of status code can be found in prototype document
818 */
819 enum halmac_ret_status
write_log_efuse_word_88xx(struct halmac_adapter * adapter,u32 offset,u16 value)820 write_log_efuse_word_88xx(struct halmac_adapter *adapter, u32 offset, u16 value)
821 {
822 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
823 enum halmac_cmd_process_status *proc_status;
824
825 proc_status = &adapter->halmac_state.efuse_state.proc_status;
826
827 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
828
829 if (offset >= adapter->hw_cfg_info.eeprom_size) {
830 PLTFM_MSG_ERR("[ERR]Offset is too large\n");
831 return HALMAC_RET_EFUSE_SIZE_INCORRECT;
832 }
833
834 if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
835 PLTFM_MSG_WARN("[WARN]Wait event(efuse)\n");
836 return HALMAC_RET_BUSY_STATE;
837 }
838
839 if (efuse_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_IDLE) {
840 PLTFM_MSG_WARN("[WARN]Not idle(efuse)\n");
841 return HALMAC_RET_ERROR_STATE;
842 }
843
844 status = switch_efuse_bank_88xx(adapter, HALMAC_EFUSE_BANK_WIFI);
845 if (status != HALMAC_RET_SUCCESS) {
846 PLTFM_MSG_ERR("[ERR]switch efuse bank\n");
847 return status;
848 }
849
850 status = proc_write_log_efuse_word_88xx(adapter, offset, value);
851 if (status != HALMAC_RET_SUCCESS) {
852 PLTFM_MSG_ERR("[ERR]write logical efuse\n");
853 return status;
854 }
855
856 if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
857 HALMAC_RET_SUCCESS)
858 return HALMAC_RET_ERROR_STATE;
859
860 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
861
862 return HALMAC_RET_SUCCESS;
863 }
864
865 /**
866 * pg_efuse_by_map_88xx() - pg logical efuse by map
867 * @adapter : the adapter of halmac
868 * @info : efuse map information
869 * @cfg : dump efuse method
870 * Author : Soar
871 * Return : enum halmac_ret_status
872 * More details of status code can be found in prototype document
873 */
874 enum halmac_ret_status
pg_efuse_by_map_88xx(struct halmac_adapter * adapter,struct halmac_pg_efuse_info * info,enum halmac_efuse_read_cfg cfg)875 pg_efuse_by_map_88xx(struct halmac_adapter *adapter,
876 struct halmac_pg_efuse_info *info,
877 enum halmac_efuse_read_cfg cfg)
878 {
879 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
880 enum halmac_cmd_process_status *proc_status;
881
882 proc_status = &adapter->halmac_state.efuse_state.proc_status;
883
884 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
885
886 if (info->efuse_map_size != adapter->hw_cfg_info.eeprom_size) {
887 PLTFM_MSG_ERR("[ERR]map size error\n");
888 return HALMAC_RET_EFUSE_SIZE_INCORRECT;
889 }
890
891 if ((info->efuse_map_size & 0xF) > 0) {
892 PLTFM_MSG_ERR("[ERR]not multiple of 16\n");
893 return HALMAC_RET_EFUSE_SIZE_INCORRECT;
894 }
895
896 if (info->efuse_mask_size != info->efuse_map_size >> 4) {
897 PLTFM_MSG_ERR("[ERR]mask size error\n");
898 return HALMAC_RET_EFUSE_SIZE_INCORRECT;
899 }
900
901 if (!info->efuse_map) {
902 PLTFM_MSG_ERR("[ERR]map is NULL\n");
903 return HALMAC_RET_NULL_POINTER;
904 }
905
906 if (!info->efuse_mask) {
907 PLTFM_MSG_ERR("[ERR]mask is NULL\n");
908 return HALMAC_RET_NULL_POINTER;
909 }
910
911 if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
912 PLTFM_MSG_WARN("[WARN]Wait event(efuse)\n");
913 return HALMAC_RET_BUSY_STATE;
914 }
915
916 if (efuse_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_IDLE) {
917 PLTFM_MSG_WARN("[WARN]Not idle(efuse)\n");
918 return HALMAC_RET_ERROR_STATE;
919 }
920
921 status = switch_efuse_bank_88xx(adapter, HALMAC_EFUSE_BANK_WIFI);
922 if (status != HALMAC_RET_SUCCESS) {
923 PLTFM_MSG_ERR("[ERR]switch efuse bank\n");
924 return status;
925 }
926
927 status = proc_pg_efuse_by_map_88xx(adapter, info, cfg);
928 if (status != HALMAC_RET_SUCCESS) {
929 PLTFM_MSG_ERR("[ERR]pg efuse\n");
930 return status;
931 }
932
933 if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
934 HALMAC_RET_SUCCESS)
935 return HALMAC_RET_ERROR_STATE;
936
937 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
938
939 return HALMAC_RET_SUCCESS;
940 }
941
942 /**
943 * mask_log_efuse_88xx() - mask logical efuse
944 * @adapter : the adapter of halmac
945 * @info : efuse map information
946 * Author : Soar
947 * Return : enum halmac_ret_status
948 * More details of status code can be found in prototype document
949 */
950 enum halmac_ret_status
mask_log_efuse_88xx(struct halmac_adapter * adapter,struct halmac_pg_efuse_info * info)951 mask_log_efuse_88xx(struct halmac_adapter *adapter,
952 struct halmac_pg_efuse_info *info)
953 {
954 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
955
956 if (info->efuse_map_size != adapter->hw_cfg_info.eeprom_size) {
957 PLTFM_MSG_ERR("[ERR]map size error\n");
958 return HALMAC_RET_EFUSE_SIZE_INCORRECT;
959 }
960
961 if ((info->efuse_map_size & 0xF) > 0) {
962 PLTFM_MSG_ERR("[ERR]not multiple of 16\n");
963 return HALMAC_RET_EFUSE_SIZE_INCORRECT;
964 }
965
966 if (info->efuse_mask_size != info->efuse_map_size >> 4) {
967 PLTFM_MSG_ERR("[ERR]mask size error\n");
968 return HALMAC_RET_EFUSE_SIZE_INCORRECT;
969 }
970
971 if (!info->efuse_map) {
972 PLTFM_MSG_ERR("[ERR]map is NULL\n");
973 return HALMAC_RET_NULL_POINTER;
974 }
975
976 if (!info->efuse_mask) {
977 PLTFM_MSG_ERR("[ERR]mask is NULL\n");
978 return HALMAC_RET_NULL_POINTER;
979 }
980
981 mask_eeprom_88xx(adapter, info);
982
983 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
984
985 return HALMAC_RET_SUCCESS;
986 }
987
988 static enum halmac_cmd_construct_state
efuse_cmd_cnstr_state_88xx(struct halmac_adapter * adapter)989 efuse_cmd_cnstr_state_88xx(struct halmac_adapter *adapter)
990 {
991 return adapter->halmac_state.efuse_state.cmd_cnstr_state;
992 }
993
994 enum halmac_ret_status
switch_efuse_bank_88xx(struct halmac_adapter * adapter,enum halmac_efuse_bank bank)995 switch_efuse_bank_88xx(struct halmac_adapter *adapter,
996 enum halmac_efuse_bank bank)
997 {
998 u8 reg_value;
999 struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
1000
1001 if (!bt_switch) {
1002 if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_BUSY) !=
1003 HALMAC_RET_SUCCESS)
1004 return HALMAC_RET_ERROR_STATE;
1005 }
1006
1007 reg_value = HALMAC_REG_R8(REG_LDO_EFUSE_CTRL + 1);
1008
1009 if (bank == (reg_value & (BIT(0) | BIT(1))))
1010 return HALMAC_RET_SUCCESS;
1011
1012 reg_value &= ~(BIT(0) | BIT(1));
1013 reg_value |= bank;
1014 HALMAC_REG_W8(REG_LDO_EFUSE_CTRL + 1, reg_value);
1015
1016 reg_value = HALMAC_REG_R8(REG_LDO_EFUSE_CTRL + 1);
1017 if ((reg_value & (BIT(0) | BIT(1))) != bank)
1018 return HALMAC_RET_SWITCH_EFUSE_BANK_FAIL;
1019
1020 return HALMAC_RET_SUCCESS;
1021 }
1022
1023 static enum halmac_ret_status
proc_dump_efuse_88xx(struct halmac_adapter * adapter,enum halmac_efuse_read_cfg cfg)1024 proc_dump_efuse_88xx(struct halmac_adapter *adapter,
1025 enum halmac_efuse_read_cfg cfg)
1026 {
1027 u32 h2c_init;
1028 struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
1029 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1030 enum halmac_cmd_process_status *proc_status;
1031
1032 proc_status = &adapter->halmac_state.efuse_state.proc_status;
1033
1034 *proc_status = HALMAC_CMD_PROCESS_SENDING;
1035
1036 if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_H2C_SENT) !=
1037 HALMAC_RET_SUCCESS)
1038 return HALMAC_RET_ERROR_STATE;
1039
1040 if (cfg == HALMAC_EFUSE_R_AUTO) {
1041 h2c_init = HALMAC_REG_R32(REG_H2C_PKT_READADDR);
1042 if (adapter->halmac_state.dlfw_state == HALMAC_DLFW_NONE ||
1043 h2c_init == 0)
1044 status = dump_efuse_drv_88xx(adapter);
1045 else
1046 status = dump_efuse_fw_88xx(adapter);
1047 } else if (cfg == HALMAC_EFUSE_R_FW) {
1048 status = dump_efuse_fw_88xx(adapter);
1049 } else {
1050 status = dump_efuse_drv_88xx(adapter);
1051 }
1052
1053 if (status != HALMAC_RET_SUCCESS) {
1054 PLTFM_MSG_ERR("[ERR]dump efsue drv/fw\n");
1055 return status;
1056 }
1057
1058 return status;
1059 }
1060
1061 enum halmac_ret_status
cnv_efuse_state_88xx(struct halmac_adapter * adapter,enum halmac_cmd_construct_state dest_state)1062 cnv_efuse_state_88xx(struct halmac_adapter *adapter,
1063 enum halmac_cmd_construct_state dest_state)
1064 {
1065 struct halmac_efuse_state *state = &adapter->halmac_state.efuse_state;
1066
1067 if (state->cmd_cnstr_state != HALMAC_CMD_CNSTR_IDLE &&
1068 state->cmd_cnstr_state != HALMAC_CMD_CNSTR_BUSY &&
1069 state->cmd_cnstr_state != HALMAC_CMD_CNSTR_H2C_SENT)
1070 return HALMAC_RET_ERROR_STATE;
1071
1072 if (state->cmd_cnstr_state == dest_state)
1073 return HALMAC_RET_ERROR_STATE;
1074
1075 if (dest_state == HALMAC_CMD_CNSTR_BUSY) {
1076 if (state->cmd_cnstr_state == HALMAC_CMD_CNSTR_H2C_SENT)
1077 return HALMAC_RET_ERROR_STATE;
1078 } else if (dest_state == HALMAC_CMD_CNSTR_H2C_SENT) {
1079 if (state->cmd_cnstr_state == HALMAC_CMD_CNSTR_IDLE)
1080 return HALMAC_RET_ERROR_STATE;
1081 }
1082
1083 state->cmd_cnstr_state = dest_state;
1084
1085 return HALMAC_RET_SUCCESS;
1086 }
1087
1088 static enum halmac_ret_status
read_hw_efuse_88xx(struct halmac_adapter * adapter,u32 offset,u32 size,u8 * map)1089 read_hw_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u32 size,
1090 u8 *map)
1091 {
1092 u8 enable;
1093 u32 value32;
1094 u32 addr;
1095 u32 tmp32;
1096 u32 cnt;
1097 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1098 struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
1099
1100 /* Read efuse no need 2.5V LDO */
1101 enable = 0;
1102 status = api->halmac_set_hw_value(adapter, HALMAC_HW_LDO25_EN, &enable);
1103 if (status != HALMAC_RET_SUCCESS) {
1104 PLTFM_MSG_ERR("[ERR]dis ldo25\n");
1105 return status;
1106 }
1107 value32 = HALMAC_REG_R32(REG_EFUSE_CTRL);
1108
1109 for (addr = offset; addr < offset + size; addr++) {
1110 value32 &= ~(BIT_MASK_EF_DATA | BITS_EF_ADDR);
1111 value32 |= ((addr & BIT_MASK_EF_ADDR) << BIT_SHIFT_EF_ADDR);
1112 HALMAC_REG_W32(REG_EFUSE_CTRL, value32 & (~BIT_EF_FLAG));
1113
1114 cnt = 1000000;
1115 do {
1116 PLTFM_DELAY_US(1);
1117 tmp32 = HALMAC_REG_R32(REG_EFUSE_CTRL);
1118 cnt--;
1119 if (cnt == 0) {
1120 PLTFM_MSG_ERR("[ERR]read\n");
1121 return HALMAC_RET_EFUSE_R_FAIL;
1122 }
1123 } while ((tmp32 & BIT_EF_FLAG) == 0);
1124
1125 *(map + addr - offset) = (u8)(tmp32 & BIT_MASK_EF_DATA);
1126 }
1127
1128 return HALMAC_RET_SUCCESS;
1129 }
1130
1131 enum halmac_ret_status
write_hw_efuse_88xx(struct halmac_adapter * adapter,u32 offset,u8 value)1132 write_hw_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u8 value)
1133 {
1134 const u8 unlock_code = 0x69;
1135 u8 value_read = 0;
1136 u8 enable;
1137 u32 value32;
1138 u32 tmp32;
1139 u32 cnt;
1140 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1141 struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
1142
1143 PLTFM_MUTEX_LOCK(&adapter->efuse_mutex);
1144 adapter->efuse_map_valid = 0;
1145 PLTFM_MUTEX_UNLOCK(&adapter->efuse_mutex);
1146
1147 HALMAC_REG_W8(REG_PMC_DBG_CTRL2 + 3, unlock_code);
1148
1149 /* Enable 2.5V LDO */
1150 enable = 1;
1151 status = api->halmac_set_hw_value(adapter, HALMAC_HW_LDO25_EN, &enable);
1152 if (status != HALMAC_RET_SUCCESS) {
1153 PLTFM_MSG_ERR("[ERR]en ldo25\n");
1154 return status;
1155 }
1156
1157 value32 = HALMAC_REG_R32(REG_EFUSE_CTRL);
1158 value32 &= ~(BIT_MASK_EF_DATA | BITS_EF_ADDR);
1159 value32 = value32 | ((offset & BIT_MASK_EF_ADDR) << BIT_SHIFT_EF_ADDR) |
1160 (value & BIT_MASK_EF_DATA);
1161 HALMAC_REG_W32(REG_EFUSE_CTRL, value32 | BIT_EF_FLAG);
1162
1163 cnt = 1000000;
1164 do {
1165 PLTFM_DELAY_US(1);
1166 tmp32 = HALMAC_REG_R32(REG_EFUSE_CTRL);
1167 cnt--;
1168 if (cnt == 0) {
1169 PLTFM_MSG_ERR("[ERR]write!!\n");
1170 return HALMAC_RET_EFUSE_W_FAIL;
1171 }
1172 } while (BIT_EF_FLAG == (tmp32 & BIT_EF_FLAG));
1173
1174 HALMAC_REG_W8(REG_PMC_DBG_CTRL2 + 3, 0x00);
1175
1176 /* Disable 2.5V LDO */
1177 enable = 0;
1178 status = api->halmac_set_hw_value(adapter, HALMAC_HW_LDO25_EN, &enable);
1179 if (status != HALMAC_RET_SUCCESS) {
1180 PLTFM_MSG_ERR("[ERR]dis ldo25\n");
1181 return status;
1182 }
1183
1184 if (adapter->efuse_auto_check_en == 1) {
1185 if (read_hw_efuse_88xx(adapter, offset, 1, &value_read) !=
1186 HALMAC_RET_SUCCESS)
1187 return HALMAC_RET_EFUSE_R_FAIL;
1188 if (value_read != value) {
1189 PLTFM_MSG_ERR("[ERR]efuse compare\n");
1190 return HALMAC_RET_EFUSE_W_FAIL;
1191 }
1192 }
1193
1194 return HALMAC_RET_SUCCESS;
1195 }
1196
1197 enum halmac_ret_status
eeprom_parser_88xx(struct halmac_adapter * adapter,u8 * phy_map,u8 * log_map)1198 eeprom_parser_88xx(struct halmac_adapter *adapter, u8 *phy_map, u8 *log_map)
1199 {
1200 u8 i;
1201 u8 value8;
1202 u8 blk_idx;
1203 u8 word_en;
1204 u8 valid;
1205 u8 hdr;
1206 u8 hdr2 = 0;
1207 u32 eeprom_idx;
1208 u32 efuse_idx = 0;
1209 u32 prtct_efuse_size = adapter->hw_cfg_info.prtct_efuse_size;
1210 struct halmac_hw_cfg_info *hw_info = &adapter->hw_cfg_info;
1211
1212 PLTFM_MEMSET(log_map, 0xFF, hw_info->eeprom_size);
1213
1214 do {
1215 value8 = *(phy_map + efuse_idx);
1216 hdr = value8;
1217
1218 if ((hdr & 0x1f) == 0x0f) {
1219 efuse_idx++;
1220 value8 = *(phy_map + efuse_idx);
1221 hdr2 = value8;
1222 if (hdr2 == 0xff)
1223 break;
1224 blk_idx = ((hdr2 & 0xF0) >> 1) | ((hdr >> 5) & 0x07);
1225 word_en = hdr2 & 0x0F;
1226 } else {
1227 blk_idx = (hdr & 0xF0) >> 4;
1228 word_en = hdr & 0x0F;
1229 }
1230
1231 if (hdr == 0xff)
1232 break;
1233
1234 efuse_idx++;
1235
1236 if (efuse_idx >= hw_info->efuse_size - prtct_efuse_size - 1)
1237 return HALMAC_RET_EEPROM_PARSING_FAIL;
1238
1239 for (i = 0; i < 4; i++) {
1240 valid = (u8)((~(word_en >> i)) & BIT(0));
1241 if (valid == 1) {
1242 eeprom_idx = (blk_idx << 3) + (i << 1);
1243
1244 if ((eeprom_idx + 1) > hw_info->eeprom_size) {
1245 PLTFM_MSG_ERR("[ERR]efuse idx:0x%X\n",
1246 efuse_idx - 1);
1247
1248 PLTFM_MSG_ERR("[ERR]read hdr:0x%X\n",
1249 hdr);
1250
1251 PLTFM_MSG_ERR("[ERR]rad hdr2:0x%X\n",
1252 hdr2);
1253
1254 return HALMAC_RET_EEPROM_PARSING_FAIL;
1255 }
1256
1257 value8 = *(phy_map + efuse_idx);
1258 *(log_map + eeprom_idx) = value8;
1259
1260 eeprom_idx++;
1261 efuse_idx++;
1262
1263 if (efuse_idx > hw_info->efuse_size -
1264 prtct_efuse_size - 1)
1265 return HALMAC_RET_EEPROM_PARSING_FAIL;
1266
1267 value8 = *(phy_map + efuse_idx);
1268 *(log_map + eeprom_idx) = value8;
1269
1270 efuse_idx++;
1271
1272 if (efuse_idx > hw_info->efuse_size -
1273 prtct_efuse_size)
1274 return HALMAC_RET_EEPROM_PARSING_FAIL;
1275 }
1276 }
1277 } while (1);
1278
1279 adapter->efuse_end = efuse_idx;
1280
1281 return HALMAC_RET_SUCCESS;
1282 }
1283
1284 enum halmac_ret_status
eeprom_mask_parser_88xx(struct halmac_adapter * adapter,u8 * phy_map,u8 * log_mask)1285 eeprom_mask_parser_88xx(struct halmac_adapter *adapter, u8 *phy_map,
1286 u8 *log_mask)
1287 {
1288 u8 i;
1289 u8 value8;
1290 u8 blk_idx;
1291 u8 word_en;
1292 u8 valid;
1293 u8 hdr;
1294 u8 hdr2 = 0;
1295 u32 eeprom_idx;
1296 u32 efuse_idx = 0;
1297 u32 prtct_efuse_size = adapter->hw_cfg_info.prtct_efuse_size;
1298 struct halmac_hw_cfg_info *hw_info = &adapter->hw_cfg_info;
1299
1300 PLTFM_MEMSET(log_mask, 0xFF, hw_info->eeprom_size);
1301
1302 do {
1303 value8 = *(phy_map + efuse_idx);
1304 hdr = value8;
1305
1306 if ((hdr & 0x1f) == 0x0f) {
1307 efuse_idx++;
1308 value8 = *(phy_map + efuse_idx);
1309 hdr2 = value8;
1310 if (hdr2 == 0xff)
1311 break;
1312 blk_idx = ((hdr2 & 0xF0) >> 1) | ((hdr >> 5) & 0x07);
1313 word_en = hdr2 & 0x0F;
1314 } else {
1315 blk_idx = (hdr & 0xF0) >> 4;
1316 word_en = hdr & 0x0F;
1317 }
1318
1319 if (hdr == 0xff)
1320 break;
1321
1322 efuse_idx++;
1323
1324 if (efuse_idx >= hw_info->efuse_size - prtct_efuse_size - 1)
1325 return HALMAC_RET_EEPROM_PARSING_FAIL;
1326
1327 for (i = 0; i < 4; i++) {
1328 valid = (u8)((~(word_en >> i)) & BIT(0));
1329 if (valid == 1) {
1330 eeprom_idx = (blk_idx << 3) + (i << 1);
1331
1332 if ((eeprom_idx + 1) > hw_info->eeprom_size) {
1333 PLTFM_MSG_ERR("[ERR]efuse idx:0x%X\n",
1334 efuse_idx - 1);
1335
1336 PLTFM_MSG_ERR("[ERR]read hdr:0x%X\n",
1337 hdr);
1338
1339 PLTFM_MSG_ERR("[ERR]read hdr2:0x%X\n",
1340 hdr2);
1341
1342 return HALMAC_RET_EEPROM_PARSING_FAIL;
1343 }
1344
1345 *(log_mask + eeprom_idx) = 0x00;
1346
1347 eeprom_idx++;
1348 efuse_idx++;
1349
1350 if (efuse_idx > hw_info->efuse_size -
1351 prtct_efuse_size - 1)
1352 return HALMAC_RET_EEPROM_PARSING_FAIL;
1353
1354 *(log_mask + eeprom_idx) = 0x00;
1355
1356 efuse_idx++;
1357
1358 if (efuse_idx > hw_info->efuse_size -
1359 prtct_efuse_size)
1360 return HALMAC_RET_EEPROM_PARSING_FAIL;
1361 }
1362 }
1363 } while (1);
1364
1365 adapter->efuse_end = efuse_idx;
1366
1367 return HALMAC_RET_SUCCESS;
1368 }
1369
1370 static enum halmac_ret_status
read_log_efuse_map_88xx(struct halmac_adapter * adapter,u8 * map)1371 read_log_efuse_map_88xx(struct halmac_adapter *adapter, u8 *map)
1372 {
1373 u8 *local_map = NULL;
1374 u32 efuse_size;
1375 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1376
1377 if (adapter->efuse_map_valid == 0) {
1378 efuse_size = adapter->hw_cfg_info.efuse_size;
1379
1380 local_map = (u8 *)PLTFM_MALLOC(efuse_size);
1381 if (!local_map) {
1382 PLTFM_MSG_ERR("[ERR]local map\n");
1383 return HALMAC_RET_MALLOC_FAIL;
1384 }
1385
1386 status = read_efuse_88xx(adapter, 0, efuse_size, local_map);
1387 if (status != HALMAC_RET_SUCCESS) {
1388 PLTFM_MSG_ERR("[ERR]read efuse\n");
1389 PLTFM_FREE(local_map, efuse_size);
1390 return status;
1391 }
1392
1393 if (!adapter->efuse_map) {
1394 adapter->efuse_map = (u8 *)PLTFM_MALLOC(efuse_size);
1395 if (!adapter->efuse_map) {
1396 PLTFM_MSG_ERR("[ERR]malloc adapter map\n");
1397 PLTFM_FREE(local_map, efuse_size);
1398 return HALMAC_RET_MALLOC_FAIL;
1399 }
1400 }
1401
1402 PLTFM_MUTEX_LOCK(&adapter->efuse_mutex);
1403 PLTFM_MEMCPY(adapter->efuse_map, local_map, efuse_size);
1404 adapter->efuse_map_valid = 1;
1405 PLTFM_MUTEX_UNLOCK(&adapter->efuse_mutex);
1406
1407 PLTFM_FREE(local_map, efuse_size);
1408 }
1409
1410 if (eeprom_parser_88xx(adapter, adapter->efuse_map, map) !=
1411 HALMAC_RET_SUCCESS)
1412 return HALMAC_RET_EEPROM_PARSING_FAIL;
1413
1414 return status;
1415 }
1416
1417 static enum halmac_ret_status
proc_pg_efuse_by_map_88xx(struct halmac_adapter * adapter,struct halmac_pg_efuse_info * info,enum halmac_efuse_read_cfg cfg)1418 proc_pg_efuse_by_map_88xx(struct halmac_adapter *adapter,
1419 struct halmac_pg_efuse_info *info,
1420 enum halmac_efuse_read_cfg cfg)
1421 {
1422 u8 *updated_mask = NULL;
1423 u8 *updated_map = NULL;
1424 u32 map_size = adapter->hw_cfg_info.eeprom_size;
1425 u32 mask_size = adapter->hw_cfg_info.eeprom_size >> 4;
1426 u8 super_usb;
1427 struct halmac_pg_efuse_info local_info;
1428 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1429
1430 status = super_usb_chk_88xx(adapter, &super_usb);
1431 if (status != HALMAC_RET_SUCCESS) {
1432 PLTFM_MSG_ERR("[ERR]super_usb_chk\n");
1433 return status;
1434 }
1435
1436 updated_mask = (u8 *)PLTFM_MALLOC(mask_size);
1437 if (!updated_mask) {
1438 PLTFM_MSG_ERR("[ERR]malloc updated mask\n");
1439 return HALMAC_RET_MALLOC_FAIL;
1440 }
1441 PLTFM_MEMSET(updated_mask, 0x00, mask_size);
1442
1443 status = update_eeprom_mask_88xx(adapter, info, updated_mask);
1444 if (status != HALMAC_RET_SUCCESS) {
1445 PLTFM_MSG_ERR("[ERR]update eeprom mask\n");
1446 PLTFM_FREE(updated_mask, mask_size);
1447 return status;
1448 }
1449
1450 if (super_usb) {
1451 updated_map = (u8 *)PLTFM_MALLOC(map_size);
1452 if (!updated_map) {
1453 PLTFM_MSG_ERR("[ERR]malloc updated map\n");
1454 PLTFM_FREE(updated_mask, mask_size);
1455 return HALMAC_RET_MALLOC_FAIL;
1456 }
1457 PLTFM_MEMSET(updated_map, 0xFF, map_size);
1458
1459 status = proc_gen_super_usb_map_88xx(adapter, info->efuse_map,
1460 updated_map, updated_mask);
1461 if (status != HALMAC_RET_SUCCESS) {
1462 PLTFM_MSG_ERR("[ERR]gen eeprom mask/map\n");
1463 PLTFM_FREE(updated_mask, mask_size);
1464 PLTFM_FREE(updated_map, map_size);
1465 return status;
1466 }
1467
1468 local_info.efuse_map = updated_map;
1469 local_info.efuse_mask = updated_mask;
1470 local_info.efuse_map_size = map_size;
1471 local_info.efuse_mask_size = mask_size;
1472 }
1473
1474 if (super_usb)
1475 status = check_efuse_enough_88xx(adapter, &local_info,
1476 updated_mask);
1477 else
1478 status = check_efuse_enough_88xx(adapter, info, updated_mask);
1479 if (status != HALMAC_RET_SUCCESS) {
1480 PLTFM_MSG_ERR("[ERR]chk efuse enough\n");
1481 PLTFM_FREE(updated_mask, mask_size);
1482 if (super_usb)
1483 PLTFM_FREE(updated_map, map_size);
1484 return status;
1485 }
1486
1487 if (super_usb)
1488 status = program_efuse_88xx(adapter, &local_info, updated_mask);
1489 else
1490 status = program_efuse_88xx(adapter, info, updated_mask);
1491 if (status != HALMAC_RET_SUCCESS) {
1492 PLTFM_MSG_ERR("[ERR]pg efuse\n");
1493 PLTFM_FREE(updated_mask, mask_size);
1494 if (super_usb)
1495 PLTFM_FREE(updated_map, map_size);
1496 return status;
1497 }
1498
1499 PLTFM_FREE(updated_mask, mask_size);
1500 if (super_usb)
1501 PLTFM_FREE(updated_map, map_size);
1502
1503 return HALMAC_RET_SUCCESS;
1504 }
1505
1506 static enum halmac_ret_status
dump_efuse_drv_88xx(struct halmac_adapter * adapter)1507 dump_efuse_drv_88xx(struct halmac_adapter *adapter)
1508 {
1509 u8 *map = NULL;
1510 u32 efuse_size = adapter->hw_cfg_info.efuse_size;
1511
1512 if (!adapter->efuse_map) {
1513 adapter->efuse_map = (u8 *)PLTFM_MALLOC(efuse_size);
1514 if (!adapter->efuse_map) {
1515 PLTFM_MSG_ERR("[ERR]malloc adapter map!!\n");
1516 reset_ofld_feature_88xx(adapter,
1517 FEATURE_DUMP_PHY_EFUSE);
1518 return HALMAC_RET_MALLOC_FAIL;
1519 }
1520 }
1521
1522 if (adapter->efuse_map_valid == 0) {
1523 map = (u8 *)PLTFM_MALLOC(efuse_size);
1524 if (!map) {
1525 PLTFM_MSG_ERR("[ERR]malloc map\n");
1526 return HALMAC_RET_MALLOC_FAIL;
1527 }
1528
1529 if (read_hw_efuse_88xx(adapter, 0, efuse_size, map) !=
1530 HALMAC_RET_SUCCESS) {
1531 PLTFM_FREE(map, efuse_size);
1532 return HALMAC_RET_EFUSE_R_FAIL;
1533 }
1534
1535 PLTFM_MUTEX_LOCK(&adapter->efuse_mutex);
1536 PLTFM_MEMCPY(adapter->efuse_map, map, efuse_size);
1537 adapter->efuse_map_valid = 1;
1538 PLTFM_MUTEX_UNLOCK(&adapter->efuse_mutex);
1539
1540 PLTFM_FREE(map, efuse_size);
1541 }
1542
1543 return HALMAC_RET_SUCCESS;
1544 }
1545
1546 static enum halmac_ret_status
dump_efuse_fw_88xx(struct halmac_adapter * adapter)1547 dump_efuse_fw_88xx(struct halmac_adapter *adapter)
1548 {
1549 u8 h2c_buf[H2C_PKT_SIZE_88XX] = { 0 };
1550 u16 seq_num = 0;
1551 u32 efuse_size = adapter->hw_cfg_info.efuse_size;
1552 struct halmac_h2c_header_info hdr_info;
1553 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1554
1555 hdr_info.sub_cmd_id = SUB_CMD_ID_DUMP_PHYSICAL_EFUSE;
1556 hdr_info.content_size = 0;
1557 hdr_info.ack = 1;
1558 set_h2c_pkt_hdr_88xx(adapter, h2c_buf, &hdr_info, &seq_num);
1559
1560 adapter->halmac_state.efuse_state.seq_num = seq_num;
1561
1562 if (!adapter->efuse_map) {
1563 adapter->efuse_map = (u8 *)PLTFM_MALLOC(efuse_size);
1564 if (!adapter->efuse_map) {
1565 PLTFM_MSG_ERR("[ERR]malloc adapter map\n");
1566 reset_ofld_feature_88xx(adapter,
1567 FEATURE_DUMP_PHY_EFUSE);
1568 return HALMAC_RET_MALLOC_FAIL;
1569 }
1570 }
1571
1572 if (adapter->efuse_map_valid == 0) {
1573 status = send_h2c_pkt_88xx(adapter, h2c_buf);
1574 if (status != HALMAC_RET_SUCCESS) {
1575 PLTFM_MSG_ERR("[ERR]send h2c pkt\n");
1576 reset_ofld_feature_88xx(adapter,
1577 FEATURE_DUMP_PHY_EFUSE);
1578 return status;
1579 }
1580 }
1581
1582 return HALMAC_RET_SUCCESS;
1583 }
1584
1585 static enum halmac_ret_status
proc_write_log_efuse_88xx(struct halmac_adapter * adapter,u32 offset,u8 value)1586 proc_write_log_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u8 value)
1587 {
1588 u8 byte1;
1589 u8 byte2;
1590 u8 blk;
1591 u8 blk_idx;
1592 u8 hdr;
1593 u8 hdr2;
1594 u8 *map = NULL;
1595 u32 eeprom_size = adapter->hw_cfg_info.eeprom_size;
1596 u32 prtct_efuse_size = adapter->hw_cfg_info.prtct_efuse_size;
1597 u32 end;
1598 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1599
1600 map = (u8 *)PLTFM_MALLOC(eeprom_size);
1601 if (!map) {
1602 PLTFM_MSG_ERR("[ERR]malloc map\n");
1603 return HALMAC_RET_MALLOC_FAIL;
1604 }
1605 PLTFM_MEMSET(map, 0xFF, eeprom_size);
1606
1607 status = read_log_efuse_map_88xx(adapter, map);
1608 if (status != HALMAC_RET_SUCCESS) {
1609 PLTFM_MSG_ERR("[ERR]read logical efuse\n");
1610 PLTFM_FREE(map, eeprom_size);
1611 return status;
1612 }
1613
1614 if (*(map + offset) != value) {
1615 end = adapter->efuse_end;
1616 blk = (u8)(offset >> 3);
1617 blk_idx = (u8)((offset & (8 - 1)) >> 1);
1618
1619 if (offset > 0x7f) {
1620 hdr = (((blk & 0x07) << 5) & 0xE0) | 0x0F;
1621 hdr2 = (u8)(((blk & 0x78) << 1) +
1622 ((0x1 << blk_idx) ^ 0x0F));
1623 } else {
1624 hdr = (u8)((blk << 4) + ((0x01 << blk_idx) ^ 0x0F));
1625 }
1626
1627 if ((offset & 1) == 0) {
1628 byte1 = value;
1629 byte2 = *(map + offset + 1);
1630 } else {
1631 byte1 = *(map + offset - 1);
1632 byte2 = value;
1633 }
1634
1635 if (offset > 0x7f) {
1636 if (adapter->hw_cfg_info.efuse_size <=
1637 4 + prtct_efuse_size + end) {
1638 PLTFM_FREE(map, eeprom_size);
1639 return HALMAC_RET_EFUSE_NOT_ENOUGH;
1640 }
1641
1642 status = write_hw_efuse_88xx(adapter, end, hdr);
1643 if (status != HALMAC_RET_SUCCESS) {
1644 PLTFM_FREE(map, eeprom_size);
1645 return status;
1646 }
1647
1648 status = write_hw_efuse_88xx(adapter, end + 1, hdr2);
1649 if (status != HALMAC_RET_SUCCESS) {
1650 PLTFM_FREE(map, eeprom_size);
1651 return status;
1652 }
1653
1654 status = write_hw_efuse_88xx(adapter, end + 2, byte1);
1655 if (status != HALMAC_RET_SUCCESS) {
1656 PLTFM_FREE(map, eeprom_size);
1657 return status;
1658 }
1659
1660 status = write_hw_efuse_88xx(adapter, end + 3, byte2);
1661 if (status != HALMAC_RET_SUCCESS) {
1662 PLTFM_FREE(map, eeprom_size);
1663 return status;
1664 }
1665 } else {
1666 if (adapter->hw_cfg_info.efuse_size <=
1667 3 + prtct_efuse_size + end) {
1668 PLTFM_FREE(map, eeprom_size);
1669 return HALMAC_RET_EFUSE_NOT_ENOUGH;
1670 }
1671
1672 status = write_hw_efuse_88xx(adapter, end, hdr);
1673 if (status != HALMAC_RET_SUCCESS) {
1674 PLTFM_FREE(map, eeprom_size);
1675 return status;
1676 }
1677
1678 status = write_hw_efuse_88xx(adapter, end + 1, byte1);
1679 if (status != HALMAC_RET_SUCCESS) {
1680 PLTFM_FREE(map, eeprom_size);
1681 return status;
1682 }
1683
1684 status = write_hw_efuse_88xx(adapter, end + 2, byte2);
1685 if (status != HALMAC_RET_SUCCESS) {
1686 PLTFM_FREE(map, eeprom_size);
1687 return status;
1688 }
1689 }
1690 }
1691
1692 PLTFM_FREE(map, eeprom_size);
1693
1694 return HALMAC_RET_SUCCESS;
1695 }
1696
1697 static enum halmac_ret_status
proc_write_log_efuse_word_88xx(struct halmac_adapter * adapter,u32 offset,u16 value)1698 proc_write_log_efuse_word_88xx(struct halmac_adapter *adapter, u32 offset,
1699 u16 value)
1700 {
1701 u8 byte1;
1702 u8 byte2;
1703 u8 blk;
1704 u8 blk_idx;
1705 u8 hdr;
1706 u8 hdr2;
1707 u8 *map = NULL;
1708 u32 eeprom_size = adapter->hw_cfg_info.eeprom_size;
1709 u32 prtct_efuse_size = adapter->hw_cfg_info.prtct_efuse_size;
1710 u32 end;
1711 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1712
1713 map = (u8 *)PLTFM_MALLOC(eeprom_size);
1714 if (!map) {
1715 PLTFM_MSG_ERR("[ERR]malloc map\n");
1716 return HALMAC_RET_MALLOC_FAIL;
1717 }
1718 PLTFM_MEMSET(map, 0xFF, eeprom_size);
1719
1720 status = read_log_efuse_map_88xx(adapter, map);
1721 if (status != HALMAC_RET_SUCCESS) {
1722 PLTFM_MSG_ERR("[ERR]read logical efuse\n");
1723 PLTFM_FREE(map, eeprom_size);
1724 return status;
1725 }
1726
1727 end = adapter->efuse_end;
1728 blk = (u8)(offset >> 3);
1729 blk_idx = (u8)((offset & (8 - 1)) >> 1);
1730
1731 if (offset > 0x7f) {
1732 hdr = (((blk & 0x07) << 5) & 0xE0) | 0x0F;
1733 hdr2 = (u8)(((blk & 0x78) << 1) +
1734 ((0x1 << blk_idx) ^ 0x0F));
1735 } else {
1736 hdr = (u8)((blk << 4) + ((0x01 << blk_idx) ^ 0x0F));
1737 }
1738
1739 if ((offset & 1) == 0) {
1740 byte1 = (u8)(value & 0xFF);
1741 byte2 = (u8)((value >> 8) & 0xFF);
1742 } else {
1743 PLTFM_FREE(map, eeprom_size);
1744 return HALMAC_RET_ADR_NOT_ALIGN;
1745 }
1746
1747 if (offset > 0x7f) {
1748 if (adapter->hw_cfg_info.efuse_size <=
1749 4 + prtct_efuse_size + end) {
1750 PLTFM_FREE(map, eeprom_size);
1751 return HALMAC_RET_EFUSE_NOT_ENOUGH;
1752 }
1753
1754 status = write_hw_efuse_88xx(adapter, end, hdr);
1755 if (status != HALMAC_RET_SUCCESS) {
1756 PLTFM_FREE(map, eeprom_size);
1757 return status;
1758 }
1759
1760 status = write_hw_efuse_88xx(adapter, end + 1, hdr2);
1761 if (status != HALMAC_RET_SUCCESS) {
1762 PLTFM_FREE(map, eeprom_size);
1763 return status;
1764 }
1765
1766 status = write_hw_efuse_88xx(adapter, end + 2, byte1);
1767 if (status != HALMAC_RET_SUCCESS) {
1768 PLTFM_FREE(map, eeprom_size);
1769 return status;
1770 }
1771
1772 status = write_hw_efuse_88xx(adapter, end + 3, byte2);
1773 if (status != HALMAC_RET_SUCCESS) {
1774 PLTFM_FREE(map, eeprom_size);
1775 return status;
1776 }
1777 } else {
1778 if (adapter->hw_cfg_info.efuse_size <=
1779 3 + prtct_efuse_size + end) {
1780 PLTFM_FREE(map, eeprom_size);
1781 return HALMAC_RET_EFUSE_NOT_ENOUGH;
1782 }
1783
1784 status = write_hw_efuse_88xx(adapter, end, hdr);
1785 if (status != HALMAC_RET_SUCCESS) {
1786 PLTFM_FREE(map, eeprom_size);
1787 return status;
1788 }
1789
1790 status = write_hw_efuse_88xx(adapter, end + 1, byte1);
1791 if (status != HALMAC_RET_SUCCESS) {
1792 PLTFM_FREE(map, eeprom_size);
1793 return status;
1794 }
1795
1796 status = write_hw_efuse_88xx(adapter, end + 2, byte2);
1797 if (status != HALMAC_RET_SUCCESS) {
1798 PLTFM_FREE(map, eeprom_size);
1799 return status;
1800 }
1801 }
1802
1803 PLTFM_FREE(map, eeprom_size);
1804
1805 return HALMAC_RET_SUCCESS;
1806 }
1807
1808 enum halmac_ret_status
read_efuse_88xx(struct halmac_adapter * adapter,u32 offset,u32 size,u8 * map)1809 read_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u32 size, u8 *map)
1810 {
1811 if (!map) {
1812 PLTFM_MSG_ERR("[ERR]malloc map\n");
1813 return HALMAC_RET_NULL_POINTER;
1814 }
1815
1816 if (adapter->efuse_map_valid == 1) {
1817 PLTFM_MEMCPY(map, adapter->efuse_map + offset, size);
1818 } else {
1819 if (read_hw_efuse_88xx(adapter, offset, size, map) !=
1820 HALMAC_RET_SUCCESS)
1821 return HALMAC_RET_EFUSE_R_FAIL;
1822 }
1823
1824 return HALMAC_RET_SUCCESS;
1825 }
1826
1827 static enum halmac_ret_status
update_eeprom_mask_88xx(struct halmac_adapter * adapter,struct halmac_pg_efuse_info * info,u8 * updated_mask)1828 update_eeprom_mask_88xx(struct halmac_adapter *adapter,
1829 struct halmac_pg_efuse_info *info, u8 *updated_mask)
1830 {
1831 u8 *map = NULL;
1832 u8 clr_bit = 0;
1833 u32 eeprom_size = adapter->hw_cfg_info.eeprom_size;
1834 u8 *map_pg;
1835 u8 *efuse_mask;
1836 u16 i;
1837 u16 j;
1838 u16 map_offset;
1839 u16 mask_offset;
1840 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1841
1842 map = (u8 *)PLTFM_MALLOC(eeprom_size);
1843 if (!map) {
1844 PLTFM_MSG_ERR("[ERR]malloc map\n");
1845 return HALMAC_RET_MALLOC_FAIL;
1846 }
1847 PLTFM_MEMSET(map, 0xFF, eeprom_size);
1848
1849 PLTFM_MEMSET(updated_mask, 0x00, info->efuse_mask_size);
1850
1851 status = read_log_efuse_map_88xx(adapter, map);
1852
1853 if (status != HALMAC_RET_SUCCESS) {
1854 PLTFM_FREE(map, eeprom_size);
1855 return status;
1856 }
1857
1858 map_pg = info->efuse_map;
1859 efuse_mask = info->efuse_mask;
1860
1861 for (i = 0; i < info->efuse_mask_size; i++)
1862 *(updated_mask + i) = *(efuse_mask + i);
1863
1864 for (i = 0; i < info->efuse_map_size; i += 16) {
1865 for (j = 0; j < 16; j += 2) {
1866 map_offset = i + j;
1867 mask_offset = i >> 4;
1868 if (*(u16 *)(map_pg + map_offset) ==
1869 *(u16 *)(map + map_offset)) {
1870 switch (j) {
1871 case 0:
1872 clr_bit = BIT(4);
1873 break;
1874 case 2:
1875 clr_bit = BIT(5);
1876 break;
1877 case 4:
1878 clr_bit = BIT(6);
1879 break;
1880 case 6:
1881 clr_bit = BIT(7);
1882 break;
1883 case 8:
1884 clr_bit = BIT(0);
1885 break;
1886 case 10:
1887 clr_bit = BIT(1);
1888 break;
1889 case 12:
1890 clr_bit = BIT(2);
1891 break;
1892 case 14:
1893 clr_bit = BIT(3);
1894 break;
1895 default:
1896 break;
1897 }
1898 *(updated_mask + mask_offset) &= ~clr_bit;
1899 }
1900 }
1901 }
1902
1903 PLTFM_FREE(map, eeprom_size);
1904
1905 return status;
1906 }
1907
1908 static enum halmac_ret_status
check_efuse_enough_88xx(struct halmac_adapter * adapter,struct halmac_pg_efuse_info * info,u8 * updated_mask)1909 check_efuse_enough_88xx(struct halmac_adapter *adapter,
1910 struct halmac_pg_efuse_info *info, u8 *updated_mask)
1911 {
1912 u8 pre_word_en;
1913 u16 i;
1914 u16 j;
1915 u32 eeprom_offset;
1916 u32 pg_num = 0;
1917 u8 super_usb;
1918 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1919
1920 status = super_usb_chk_88xx(adapter, &super_usb);
1921 if (status != HALMAC_RET_SUCCESS) {
1922 PLTFM_MSG_ERR("[ERR]super_usb_chk\n");
1923 return status;
1924 }
1925
1926 for (i = 0; i < info->efuse_map_size; i = i + 8) {
1927 eeprom_offset = i;
1928
1929 if ((eeprom_offset & 7) > 0)
1930 pre_word_en = (*(updated_mask + (i >> 4)) & 0x0F);
1931 else
1932 pre_word_en = (*(updated_mask + (i >> 4)) >> 4);
1933
1934 if (pre_word_en > 0) {
1935 if (super_usb &&
1936 ((eeprom_offset >= SUPER_USB_ZONE0_START &&
1937 eeprom_offset <= SUPER_USB_ZONE0_END) ||
1938 (eeprom_offset >= SUPER_USB_ZONE1_START &&
1939 eeprom_offset <= SUPER_USB_ZONE1_END))) {
1940 for (j = 0; j < 4; j++) {
1941 if (((pre_word_en >> j) & 0x1) > 0)
1942 pg_num += 4;
1943 }
1944 } else {
1945 if (eeprom_offset > 0x7f)
1946 pg_num += 2;
1947 else
1948 pg_num++;
1949
1950 for (j = 0; j < 4; j++) {
1951 if (((pre_word_en >> j) & 0x1) > 0)
1952 pg_num += 2;
1953 }
1954 }
1955 }
1956 }
1957
1958 if (adapter->hw_cfg_info.efuse_size <=
1959 (pg_num + adapter->hw_cfg_info.prtct_efuse_size +
1960 adapter->efuse_end))
1961 return HALMAC_RET_EFUSE_NOT_ENOUGH;
1962
1963 return HALMAC_RET_SUCCESS;
1964 }
1965
1966 static enum halmac_ret_status
pg_extend_efuse_88xx(struct halmac_adapter * adapter,struct halmac_pg_efuse_info * info,u8 word_en,u8 pre_word_en,u32 eeprom_offset)1967 pg_extend_efuse_88xx(struct halmac_adapter *adapter,
1968 struct halmac_pg_efuse_info *info, u8 word_en,
1969 u8 pre_word_en, u32 eeprom_offset)
1970 {
1971 u8 blk;
1972 u8 hdr;
1973 u8 hdr2;
1974 u16 i;
1975 u32 efuse_end;
1976 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
1977
1978 efuse_end = adapter->efuse_end;
1979
1980 blk = (u8)(eeprom_offset >> 3);
1981 hdr = (((blk & 0x07) << 5) & 0xE0) | 0x0F;
1982 hdr2 = (u8)(((blk & 0x78) << 1) + word_en);
1983
1984 status = write_hw_efuse_88xx(adapter, efuse_end, hdr);
1985 if (status != HALMAC_RET_SUCCESS) {
1986 PLTFM_MSG_ERR("[ERR]write efuse\n");
1987 return status;
1988 }
1989
1990 status = write_hw_efuse_88xx(adapter, efuse_end + 1, hdr2);
1991 if (status != HALMAC_RET_SUCCESS) {
1992 PLTFM_MSG_ERR("[ERR]write efuse(+1)\n");
1993 return status;
1994 }
1995
1996 efuse_end = efuse_end + 2;
1997 for (i = 0; i < 4; i++) {
1998 if (((pre_word_en >> i) & 0x1) > 0) {
1999 status = write_hw_efuse_88xx(adapter, efuse_end,
2000 *(info->efuse_map +
2001 eeprom_offset +
2002 (i << 1)));
2003 if (status != HALMAC_RET_SUCCESS) {
2004 PLTFM_MSG_ERR("[ERR]write efuse(<<1)\n");
2005 return status;
2006 }
2007
2008 status = write_hw_efuse_88xx(adapter, efuse_end + 1,
2009 *(info->efuse_map +
2010 eeprom_offset + (i << 1)
2011 + 1));
2012 if (status != HALMAC_RET_SUCCESS) {
2013 PLTFM_MSG_ERR("[ERR]write efuse(<<1)+1\n");
2014 return status;
2015 }
2016 efuse_end = efuse_end + 2;
2017 }
2018 }
2019 adapter->efuse_end = efuse_end;
2020 return status;
2021 }
2022
2023 static enum halmac_ret_status
proc_pg_efuse_88xx(struct halmac_adapter * adapter,struct halmac_pg_efuse_info * info,u8 word_en,u8 pre_word_en,u32 eeprom_offset)2024 proc_pg_efuse_88xx(struct halmac_adapter *adapter,
2025 struct halmac_pg_efuse_info *info, u8 word_en,
2026 u8 pre_word_en, u32 eeprom_offset)
2027 {
2028 u8 blk;
2029 u8 hdr;
2030 u16 i;
2031 u32 efuse_end;
2032 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2033
2034 efuse_end = adapter->efuse_end;
2035
2036 blk = (u8)(eeprom_offset >> 3);
2037 hdr = (u8)((blk << 4) + word_en);
2038
2039 status = write_hw_efuse_88xx(adapter, efuse_end, hdr);
2040 if (status != HALMAC_RET_SUCCESS) {
2041 PLTFM_MSG_ERR("[ERR]write efuse\n");
2042 return status;
2043 }
2044 efuse_end = efuse_end + 1;
2045 for (i = 0; i < 4; i++) {
2046 if (((pre_word_en >> i) & 0x1) > 0) {
2047 status = write_hw_efuse_88xx(adapter, efuse_end,
2048 *(info->efuse_map +
2049 eeprom_offset +
2050 (i << 1)));
2051 if (status != HALMAC_RET_SUCCESS) {
2052 PLTFM_MSG_ERR("[ERR]write efuse(<<1)\n");
2053 return status;
2054 }
2055 status = write_hw_efuse_88xx(adapter, efuse_end + 1,
2056 *(info->efuse_map +
2057 eeprom_offset + (i << 1)
2058 + 1));
2059 if (status != HALMAC_RET_SUCCESS) {
2060 PLTFM_MSG_ERR("[ERR]write efuse(<<1)+1\n");
2061 return status;
2062 }
2063 efuse_end = efuse_end + 2;
2064 }
2065 }
2066 adapter->efuse_end = efuse_end;
2067 return status;
2068 }
2069
2070 static enum halmac_ret_status
pg_super_usb_efuse_88xx(struct halmac_adapter * adapter,struct halmac_pg_efuse_info * info,u8 word_en,u8 pre_word_en,u32 eeprom_offset)2071 pg_super_usb_efuse_88xx(struct halmac_adapter *adapter,
2072 struct halmac_pg_efuse_info *info, u8 word_en,
2073 u8 pre_word_en, u32 eeprom_offset)
2074 {
2075 u8 blk;
2076 u8 hdr;
2077 u8 hdr2;
2078 u16 i;
2079 u32 efuse_end;
2080 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2081
2082 efuse_end = adapter->efuse_end;
2083
2084 blk = (u8)(eeprom_offset >> 3);
2085 hdr = (((blk & 0x07) << 5) & 0xE0) | 0x0F;
2086
2087 for (i = 0; i < 4; i++) {
2088 hdr = (((blk & 0x07) << 5) & 0xE0) | 0x0F;
2089 if (((pre_word_en >> i) & 0x1) > 0) {
2090 hdr2 = (u8)(((blk & 0x78) << 1) +
2091 ((pre_word_en & BIT(i)) ^ 0x0F));
2092
2093 status = write_hw_efuse_88xx(adapter, efuse_end, hdr);
2094 if (status != HALMAC_RET_SUCCESS) {
2095 PLTFM_MSG_ERR("[ERR]write efuse\n");
2096 return status;
2097 }
2098
2099 status = write_hw_efuse_88xx(adapter, efuse_end + 1,
2100 hdr2);
2101 if (status != HALMAC_RET_SUCCESS) {
2102 PLTFM_MSG_ERR("[ERR]write efuse(+1)\n");
2103 return status;
2104 }
2105
2106 efuse_end = efuse_end + 2;
2107
2108 status = write_hw_efuse_88xx(adapter, efuse_end,
2109 *(info->efuse_map +
2110 eeprom_offset +
2111 (i << 1)));
2112 if (status != HALMAC_RET_SUCCESS) {
2113 PLTFM_MSG_ERR("[ERR]write efuse(<<1)\n");
2114 return status;
2115 }
2116
2117 status = write_hw_efuse_88xx(adapter, efuse_end + 1,
2118 *(info->efuse_map +
2119 eeprom_offset + (i << 1)
2120 + 1));
2121 if (status != HALMAC_RET_SUCCESS) {
2122 PLTFM_MSG_ERR("[ERR]write efuse(<<1)+1\n");
2123 return status;
2124 }
2125 efuse_end = efuse_end + 2;
2126 }
2127 }
2128 adapter->efuse_end = efuse_end;
2129 return status;
2130 }
2131
2132 static enum halmac_ret_status
program_efuse_88xx(struct halmac_adapter * adapter,struct halmac_pg_efuse_info * info,u8 * updated_mask)2133 program_efuse_88xx(struct halmac_adapter *adapter,
2134 struct halmac_pg_efuse_info *info, u8 *updated_mask)
2135 {
2136 u8 pre_word_en;
2137 u8 word_en;
2138 u16 i;
2139 u32 eeprom_offset;
2140 u8 super_usb;
2141 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2142
2143 status = super_usb_chk_88xx(adapter, &super_usb);
2144 if (status != HALMAC_RET_SUCCESS) {
2145 PLTFM_MSG_ERR("[ERR]super_usb_chk\n");
2146 return status;
2147 }
2148
2149 for (i = 0; i < info->efuse_map_size; i = i + 8) {
2150 eeprom_offset = i;
2151
2152 if (((eeprom_offset >> 3) & 1) > 0) {
2153 pre_word_en = (*(updated_mask + (i >> 4)) & 0x0F);
2154 word_en = pre_word_en ^ 0x0F;
2155 } else {
2156 pre_word_en = (*(updated_mask + (i >> 4)) >> 4);
2157 word_en = pre_word_en ^ 0x0F;
2158 }
2159
2160 if (pre_word_en > 0) {
2161 if (super_usb &&
2162 ((eeprom_offset >= SUPER_USB_ZONE0_START &&
2163 eeprom_offset <= SUPER_USB_ZONE0_END) ||
2164 (eeprom_offset >= SUPER_USB_ZONE1_START &&
2165 eeprom_offset <= SUPER_USB_ZONE1_END))) {
2166 status = pg_super_usb_efuse_88xx(adapter, info,
2167 word_en,
2168 pre_word_en,
2169 eeprom_offset);
2170 if (status != HALMAC_RET_SUCCESS) {
2171 PLTFM_MSG_ERR("[ERR]super usb efuse\n");
2172 return status;
2173 }
2174 } else if (eeprom_offset > 0x7f) {
2175 status = pg_extend_efuse_88xx(adapter, info,
2176 word_en,
2177 pre_word_en,
2178 eeprom_offset);
2179 if (status != HALMAC_RET_SUCCESS) {
2180 PLTFM_MSG_ERR("[ERR]extend efuse\n");
2181 return status;
2182 }
2183 } else {
2184 status = proc_pg_efuse_88xx(adapter, info,
2185 word_en,
2186 pre_word_en,
2187 eeprom_offset);
2188 if (status != HALMAC_RET_SUCCESS) {
2189 PLTFM_MSG_ERR("[ERR]extend efuse");
2190 return status;
2191 }
2192 }
2193 }
2194 }
2195
2196 return status;
2197 }
2198
2199 static void
mask_eeprom_88xx(struct halmac_adapter * adapter,struct halmac_pg_efuse_info * info)2200 mask_eeprom_88xx(struct halmac_adapter *adapter,
2201 struct halmac_pg_efuse_info *info)
2202 {
2203 u8 pre_word_en;
2204 u8 *updated_mask;
2205 u8 *efuse_map;
2206 u16 i;
2207 u16 j;
2208 u32 offset;
2209
2210 updated_mask = info->efuse_mask;
2211 efuse_map = info->efuse_map;
2212
2213 for (i = 0; i < info->efuse_map_size; i = i + 8) {
2214 offset = i;
2215
2216 if (((offset >> 3) & 1) > 0)
2217 pre_word_en = (*(updated_mask + (i >> 4)) & 0x0F);
2218 else
2219 pre_word_en = (*(updated_mask + (i >> 4)) >> 4);
2220
2221 for (j = 0; j < 4; j++) {
2222 if (((pre_word_en >> j) & 0x1) == 0) {
2223 *(efuse_map + offset + (j << 1)) = 0xFF;
2224 *(efuse_map + offset + (j << 1) + 1) = 0xFF;
2225 }
2226 }
2227 }
2228 }
2229
2230 enum halmac_ret_status
get_efuse_data_88xx(struct halmac_adapter * adapter,u8 * buf,u32 size)2231 get_efuse_data_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
2232 {
2233 u8 seg_id;
2234 u8 seg_size;
2235 u8 seq_num;
2236 u8 fw_rc;
2237 u8 *map = NULL;
2238 u32 eeprom_size = adapter->hw_cfg_info.eeprom_size;
2239 struct halmac_efuse_state *state = &adapter->halmac_state.efuse_state;
2240 enum halmac_cmd_process_status proc_status;
2241
2242 seq_num = (u8)EFUSE_DATA_GET_H2C_SEQ(buf);
2243 PLTFM_MSG_TRACE("[TRACE]Seq num : h2c->%d c2h->%d\n",
2244 state->seq_num, seq_num);
2245 if (seq_num != state->seq_num) {
2246 PLTFM_MSG_ERR("[ERR]Seq num mismatch : h2c->%d c2h->%d\n",
2247 state->seq_num, seq_num);
2248 return HALMAC_RET_SUCCESS;
2249 }
2250
2251 if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) {
2252 PLTFM_MSG_ERR("[ERR]not cmd sending\n");
2253 return HALMAC_RET_SUCCESS;
2254 }
2255
2256 seg_id = (u8)EFUSE_DATA_GET_SEGMENT_ID(buf);
2257 seg_size = (u8)EFUSE_DATA_GET_SEGMENT_SIZE(buf);
2258 if (seg_id == 0)
2259 adapter->efuse_seg_size = seg_size;
2260
2261 map = (u8 *)PLTFM_MALLOC(eeprom_size);
2262 if (!map) {
2263 PLTFM_MSG_ERR("[ERR]malloc map\n");
2264 return HALMAC_RET_MALLOC_FAIL;
2265 }
2266 PLTFM_MEMSET(map, 0xFF, eeprom_size);
2267
2268 PLTFM_MUTEX_LOCK(&adapter->efuse_mutex);
2269 PLTFM_MEMCPY(adapter->efuse_map + seg_id * adapter->efuse_seg_size,
2270 buf + C2H_DATA_OFFSET_88XX, seg_size);
2271 PLTFM_MUTEX_UNLOCK(&adapter->efuse_mutex);
2272
2273 if (EFUSE_DATA_GET_END_SEGMENT(buf) == 0) {
2274 PLTFM_FREE(map, eeprom_size);
2275 return HALMAC_RET_SUCCESS;
2276 }
2277
2278 fw_rc = state->fw_rc;
2279
2280 if ((enum halmac_h2c_return_code)fw_rc == HALMAC_H2C_RETURN_SUCCESS) {
2281 proc_status = HALMAC_CMD_PROCESS_DONE;
2282 state->proc_status = proc_status;
2283
2284 PLTFM_MUTEX_LOCK(&adapter->efuse_mutex);
2285 adapter->efuse_map_valid = 1;
2286 PLTFM_MUTEX_UNLOCK(&adapter->efuse_mutex);
2287
2288 if (adapter->evnt.phy_efuse_map == 1) {
2289 PLTFM_EVENT_SIG(FEATURE_DUMP_PHY_EFUSE,
2290 proc_status, adapter->efuse_map,
2291 adapter->hw_cfg_info.efuse_size);
2292 adapter->evnt.phy_efuse_map = 0;
2293 }
2294
2295 if (adapter->evnt.log_efuse_map == 1) {
2296 if (eeprom_parser_88xx(adapter, adapter->efuse_map,
2297 map) != HALMAC_RET_SUCCESS) {
2298 PLTFM_FREE(map, eeprom_size);
2299 return HALMAC_RET_EEPROM_PARSING_FAIL;
2300 }
2301 PLTFM_EVENT_SIG(FEATURE_DUMP_LOG_EFUSE, proc_status,
2302 map, eeprom_size);
2303 adapter->evnt.log_efuse_map = 0;
2304 }
2305
2306 if (adapter->evnt.log_efuse_mask == 1) {
2307 if (eeprom_mask_parser_88xx(adapter, adapter->efuse_map,
2308 map)
2309 != HALMAC_RET_SUCCESS) {
2310 PLTFM_FREE(map, eeprom_size);
2311 return HALMAC_RET_EEPROM_PARSING_FAIL;
2312 }
2313 PLTFM_EVENT_SIG(FEATURE_DUMP_LOG_EFUSE_MASK,
2314 proc_status, map, eeprom_size);
2315 adapter->evnt.log_efuse_mask = 0;
2316 }
2317
2318 } else {
2319 proc_status = HALMAC_CMD_PROCESS_ERROR;
2320 state->proc_status = proc_status;
2321
2322 if (adapter->evnt.phy_efuse_map == 1) {
2323 PLTFM_EVENT_SIG(FEATURE_DUMP_PHY_EFUSE, proc_status,
2324 &state->fw_rc, 1);
2325 adapter->evnt.phy_efuse_map = 0;
2326 }
2327
2328 if (adapter->evnt.log_efuse_map == 1) {
2329 PLTFM_EVENT_SIG(FEATURE_DUMP_LOG_EFUSE, proc_status,
2330 &state->fw_rc, 1);
2331 adapter->evnt.log_efuse_map = 0;
2332 }
2333
2334 if (adapter->evnt.log_efuse_mask == 1) {
2335 PLTFM_EVENT_SIG(FEATURE_DUMP_LOG_EFUSE_MASK,
2336 proc_status, &state->fw_rc, 1);
2337 adapter->evnt.log_efuse_mask = 0;
2338 }
2339 }
2340
2341 PLTFM_FREE(map, eeprom_size);
2342
2343 return HALMAC_RET_SUCCESS;
2344 }
2345
2346 enum halmac_ret_status
get_dump_phy_efuse_status_88xx(struct halmac_adapter * adapter,enum halmac_cmd_process_status * proc_status,u8 * data,u32 * size)2347 get_dump_phy_efuse_status_88xx(struct halmac_adapter *adapter,
2348 enum halmac_cmd_process_status *proc_status,
2349 u8 *data, u32 *size)
2350 {
2351 u8 *map = NULL;
2352 u32 efuse_size = adapter->hw_cfg_info.efuse_size;
2353 u32 prtct_efuse_size = adapter->hw_cfg_info.prtct_efuse_size;
2354 struct halmac_efuse_state *state = &adapter->halmac_state.efuse_state;
2355
2356 *proc_status = state->proc_status;
2357
2358 if (!data)
2359 return HALMAC_RET_NULL_POINTER;
2360
2361 if (!size)
2362 return HALMAC_RET_NULL_POINTER;
2363
2364 if (*proc_status == HALMAC_CMD_PROCESS_DONE) {
2365 if (*size < efuse_size) {
2366 *size = efuse_size;
2367 return HALMAC_RET_BUFFER_TOO_SMALL;
2368 }
2369
2370 *size = efuse_size;
2371
2372 map = (u8 *)PLTFM_MALLOC(efuse_size);
2373 if (!map) {
2374 PLTFM_MSG_ERR("[ERR]malloc map\n");
2375 return HALMAC_RET_MALLOC_FAIL;
2376 }
2377 PLTFM_MEMSET(map, 0xFF, efuse_size);
2378 PLTFM_MUTEX_LOCK(&adapter->efuse_mutex);
2379 #if HALMAC_PLATFORM_WINDOWS
2380 PLTFM_MEMCPY(map, adapter->efuse_map, efuse_size);
2381 #else
2382 PLTFM_MEMCPY(map, adapter->efuse_map,
2383 efuse_size - prtct_efuse_size);
2384 PLTFM_MEMCPY(map + efuse_size - prtct_efuse_size +
2385 RSVD_CS_EFUSE_SIZE,
2386 adapter->efuse_map + efuse_size -
2387 prtct_efuse_size + RSVD_CS_EFUSE_SIZE,
2388 prtct_efuse_size - RSVD_EFUSE_SIZE -
2389 RSVD_CS_EFUSE_SIZE);
2390 #endif
2391 PLTFM_MUTEX_UNLOCK(&adapter->efuse_mutex);
2392
2393 PLTFM_MEMCPY(data, map, *size);
2394
2395 PLTFM_FREE(map, efuse_size);
2396 }
2397
2398 return HALMAC_RET_SUCCESS;
2399 }
2400
2401 enum halmac_ret_status
get_dump_log_efuse_status_88xx(struct halmac_adapter * adapter,enum halmac_cmd_process_status * proc_status,u8 * data,u32 * size)2402 get_dump_log_efuse_status_88xx(struct halmac_adapter *adapter,
2403 enum halmac_cmd_process_status *proc_status,
2404 u8 *data, u32 *size)
2405 {
2406 u8 *map = NULL;
2407 u32 eeprom_size = adapter->hw_cfg_info.eeprom_size;
2408 struct halmac_efuse_state *state = &adapter->halmac_state.efuse_state;
2409
2410 *proc_status = state->proc_status;
2411
2412 if (!data)
2413 return HALMAC_RET_NULL_POINTER;
2414
2415 if (!size)
2416 return HALMAC_RET_NULL_POINTER;
2417
2418 if (*proc_status == HALMAC_CMD_PROCESS_DONE) {
2419 if (*size < eeprom_size) {
2420 *size = eeprom_size;
2421 return HALMAC_RET_BUFFER_TOO_SMALL;
2422 }
2423
2424 *size = eeprom_size;
2425
2426 map = (u8 *)PLTFM_MALLOC(eeprom_size);
2427 if (!map) {
2428 PLTFM_MSG_ERR("[ERR]malloc map\n");
2429 return HALMAC_RET_MALLOC_FAIL;
2430 }
2431 PLTFM_MEMSET(map, 0xFF, eeprom_size);
2432
2433 if (eeprom_parser_88xx(adapter, adapter->efuse_map, map) !=
2434 HALMAC_RET_SUCCESS) {
2435 PLTFM_FREE(map, eeprom_size);
2436 return HALMAC_RET_EEPROM_PARSING_FAIL;
2437 }
2438
2439 PLTFM_MEMCPY(data, map, *size);
2440
2441 PLTFM_FREE(map, eeprom_size);
2442 }
2443
2444 return HALMAC_RET_SUCCESS;
2445 }
2446
2447 enum halmac_ret_status
get_dump_log_efuse_mask_status_88xx(struct halmac_adapter * adapter,enum halmac_cmd_process_status * proc_status,u8 * data,u32 * size)2448 get_dump_log_efuse_mask_status_88xx(struct halmac_adapter *adapter,
2449 enum halmac_cmd_process_status *proc_status,
2450 u8 *data, u32 *size)
2451 {
2452 u8 *map = NULL;
2453 u32 eeprom_size = adapter->hw_cfg_info.eeprom_size;
2454 struct halmac_efuse_state *state = &adapter->halmac_state.efuse_state;
2455
2456 *proc_status = state->proc_status;
2457
2458 if (!data)
2459 return HALMAC_RET_NULL_POINTER;
2460
2461 if (!size)
2462 return HALMAC_RET_NULL_POINTER;
2463
2464 if (*proc_status == HALMAC_CMD_PROCESS_DONE) {
2465 if (*size < eeprom_size) {
2466 *size = eeprom_size;
2467 return HALMAC_RET_BUFFER_TOO_SMALL;
2468 }
2469
2470 *size = eeprom_size;
2471
2472 map = (u8 *)PLTFM_MALLOC(eeprom_size);
2473 if (!map) {
2474 PLTFM_MSG_ERR("[ERR]malloc map\n");
2475 return HALMAC_RET_MALLOC_FAIL;
2476 }
2477 PLTFM_MEMSET(map, 0xFF, eeprom_size);
2478
2479 if (eeprom_mask_parser_88xx(adapter, adapter->efuse_map, map) !=
2480 HALMAC_RET_SUCCESS) {
2481 PLTFM_FREE(map, eeprom_size);
2482 return HALMAC_RET_EEPROM_PARSING_FAIL;
2483 }
2484
2485 PLTFM_MEMCPY(data, map, *size);
2486
2487 PLTFM_FREE(map, eeprom_size);
2488 }
2489
2490 return HALMAC_RET_SUCCESS;
2491 }
2492
2493 enum halmac_ret_status
get_h2c_ack_phy_efuse_88xx(struct halmac_adapter * adapter,u8 * buf,u32 size)2494 get_h2c_ack_phy_efuse_88xx(struct halmac_adapter *adapter, u8 *buf, u32 size)
2495 {
2496 u8 seq_num = 0;
2497 u8 fw_rc;
2498 struct halmac_efuse_state *state = &adapter->halmac_state.efuse_state;
2499
2500 seq_num = (u8)H2C_ACK_HDR_GET_H2C_SEQ(buf);
2501 PLTFM_MSG_TRACE("[TRACE]Seq num : h2c->%d c2h->%d\n",
2502 state->seq_num, seq_num);
2503 if (seq_num != state->seq_num) {
2504 PLTFM_MSG_ERR("[ERR]Seq num mismatch : h2c->%d c2h->%d\n",
2505 state->seq_num, seq_num);
2506 return HALMAC_RET_SUCCESS;
2507 }
2508
2509 if (state->proc_status != HALMAC_CMD_PROCESS_SENDING) {
2510 PLTFM_MSG_ERR("[ERR]not cmd sending\n");
2511 return HALMAC_RET_SUCCESS;
2512 }
2513
2514 fw_rc = (u8)H2C_ACK_HDR_GET_H2C_RETURN_CODE(buf);
2515 state->fw_rc = fw_rc;
2516
2517 return HALMAC_RET_SUCCESS;
2518 }
2519
2520 u32
get_rsvd_efuse_size_88xx(struct halmac_adapter * adapter)2521 get_rsvd_efuse_size_88xx(struct halmac_adapter *adapter)
2522 {
2523 return adapter->hw_cfg_info.prtct_efuse_size;
2524 }
2525
2526 /**
2527 * write_wifi_phy_efuse_88xx() - write wifi physical efuse
2528 * @adapter : the adapter of halmac
2529 * @offset : the efuse offset to be written
2530 * @value : the value to be written
2531 * Author : Yong-Ching Lin
2532 * Return : enum halmac_ret_status
2533 * More details of status code can be found in prototype document
2534 */
2535 enum halmac_ret_status
write_wifi_phy_efuse_88xx(struct halmac_adapter * adapter,u32 offset,u8 value)2536 write_wifi_phy_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u8 value)
2537 {
2538 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2539 enum halmac_cmd_process_status *proc_status;
2540
2541 proc_status = &adapter->halmac_state.efuse_state.proc_status;
2542
2543 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
2544
2545 if (offset >= adapter->hw_cfg_info.efuse_size) {
2546 PLTFM_MSG_ERR("[ERR]Offset is too large\n");
2547 return HALMAC_RET_EFUSE_SIZE_INCORRECT;
2548 }
2549
2550 if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
2551 PLTFM_MSG_WARN("[WARN]Wait event(efuse)\n");
2552 return HALMAC_RET_BUSY_STATE;
2553 }
2554
2555 if (efuse_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_IDLE) {
2556 PLTFM_MSG_WARN("[WARN]Not idle(efuse)\n");
2557 return HALMAC_RET_ERROR_STATE;
2558 }
2559
2560 status = switch_efuse_bank_88xx(adapter, HALMAC_EFUSE_BANK_WIFI);
2561 if (status != HALMAC_RET_SUCCESS) {
2562 PLTFM_MSG_ERR("[ERR]switch efuse bank\n");
2563 return status;
2564 }
2565
2566 status = write_hw_efuse_88xx(adapter, offset, value);
2567 if (status != HALMAC_RET_SUCCESS) {
2568 PLTFM_MSG_ERR("[ERR]write physical efuse\n");
2569 return status;
2570 }
2571
2572 if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
2573 HALMAC_RET_SUCCESS)
2574 return HALMAC_RET_ERROR_STATE;
2575
2576 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
2577
2578 return HALMAC_RET_SUCCESS;
2579 }
2580
2581 /**
2582 * read_wifi_phy_efuse_88xx() - read wifi physical efuse
2583 * @adapter : the adapter of halmac
2584 * @offset : the efuse offset to be read
2585 * @size : the length to be read
2586 * @value : pointer to the pre-allocated space where
2587 the efuse content is to be copied
2588 * Author : Yong-Ching Lin
2589 * Return : enum halmac_ret_status
2590 * More details of status code can be found in prototype document
2591 */
2592 enum halmac_ret_status
read_wifi_phy_efuse_88xx(struct halmac_adapter * adapter,u32 offset,u32 size,u8 * value)2593 read_wifi_phy_efuse_88xx(struct halmac_adapter *adapter, u32 offset, u32 size,
2594 u8 *value)
2595 {
2596 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2597 enum halmac_cmd_process_status *proc_status;
2598
2599 proc_status = &adapter->halmac_state.efuse_state.proc_status;
2600
2601 PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
2602
2603 if (offset >= adapter->hw_cfg_info.efuse_size ||
2604 offset + size >= adapter->hw_cfg_info.efuse_size) {
2605 PLTFM_MSG_ERR("[ERR] Wrong efuse index\n");
2606 return HALMAC_RET_EFUSE_SIZE_INCORRECT;
2607 }
2608
2609 if (*proc_status == HALMAC_CMD_PROCESS_SENDING) {
2610 PLTFM_MSG_WARN("[WARN]Wait event(efuse)\n");
2611 return HALMAC_RET_BUSY_STATE;
2612 }
2613
2614 if (efuse_cmd_cnstr_state_88xx(adapter) != HALMAC_CMD_CNSTR_IDLE) {
2615 PLTFM_MSG_WARN("[WARN]Not idle(efuse)\n");
2616 return HALMAC_RET_ERROR_STATE;
2617 }
2618
2619 status = switch_efuse_bank_88xx(adapter, HALMAC_EFUSE_BANK_WIFI);
2620 if (status != HALMAC_RET_SUCCESS) {
2621 PLTFM_MSG_ERR("[ERR]switch efuse bank\n");
2622 return status;
2623 }
2624
2625 status = read_hw_efuse_88xx(adapter, offset, size, value);
2626 if (status != HALMAC_RET_SUCCESS) {
2627 PLTFM_MSG_ERR("[ERR]read hw efuse\n");
2628 return status;
2629 }
2630
2631 if (cnv_efuse_state_88xx(adapter, HALMAC_CMD_CNSTR_IDLE) !=
2632 HALMAC_RET_SUCCESS)
2633 return HALMAC_RET_ERROR_STATE;
2634
2635 PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
2636
2637 return HALMAC_RET_SUCCESS;
2638 }
2639
2640 static enum halmac_ret_status
proc_gen_super_usb_map_88xx(struct halmac_adapter * adapter,u8 * drv_map,u8 * updated_map,u8 * updated_mask)2641 proc_gen_super_usb_map_88xx(struct halmac_adapter *adapter, u8 *drv_map,
2642 u8 *updated_map, u8 *updated_mask)
2643 {
2644 u8 *local_map = NULL;
2645 u8 *super_usb_map = NULL;
2646 u8 *super_usb_mask = NULL;
2647 u8 mask_val_0;
2648 u8 mask_val_1;
2649 u32 efuse_size;
2650 u32 i;
2651 u32 j;
2652 u32 val32;
2653 u32 map_size = adapter->hw_cfg_info.eeprom_size;
2654 u32 mask_size = adapter->hw_cfg_info.eeprom_size >> 4;
2655 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2656
2657 if (adapter->efuse_map_valid == 0) {
2658 efuse_size = adapter->hw_cfg_info.efuse_size;
2659
2660 local_map = (u8 *)PLTFM_MALLOC(efuse_size);
2661 if (!local_map) {
2662 PLTFM_MSG_ERR("[ERR]local map\n");
2663 return HALMAC_RET_MALLOC_FAIL;
2664 }
2665
2666 status = read_efuse_88xx(adapter, 0, efuse_size, local_map);
2667 if (status != HALMAC_RET_SUCCESS) {
2668 PLTFM_MSG_ERR("[ERR]read efuse\n");
2669 PLTFM_FREE(local_map, efuse_size);
2670 return status;
2671 }
2672
2673 if (!adapter->efuse_map) {
2674 adapter->efuse_map = (u8 *)PLTFM_MALLOC(efuse_size);
2675 if (!adapter->efuse_map) {
2676 PLTFM_MSG_ERR("[ERR]malloc adapter map\n");
2677 PLTFM_FREE(local_map, efuse_size);
2678 return HALMAC_RET_MALLOC_FAIL;
2679 }
2680 }
2681
2682 PLTFM_MUTEX_LOCK(&adapter->efuse_mutex);
2683 PLTFM_MEMCPY(adapter->efuse_map, local_map, efuse_size);
2684 adapter->efuse_map_valid = 1;
2685 PLTFM_MUTEX_UNLOCK(&adapter->efuse_mutex);
2686
2687 PLTFM_FREE(local_map, efuse_size);
2688 }
2689
2690 super_usb_mask = (u8 *)PLTFM_MALLOC(mask_size);
2691 if (!super_usb_mask) {
2692 PLTFM_MSG_ERR("[ERR]malloc updated mask\n");
2693 return HALMAC_RET_MALLOC_FAIL;
2694 }
2695 PLTFM_MEMSET(super_usb_mask, 0x00, mask_size);
2696
2697 super_usb_map = (u8 *)PLTFM_MALLOC(map_size);
2698 if (!super_usb_map) {
2699 PLTFM_MSG_ERR("[ERR]malloc updated map\n");
2700 PLTFM_FREE(super_usb_mask, mask_size);
2701 return HALMAC_RET_MALLOC_FAIL;
2702 }
2703 PLTFM_MEMSET(super_usb_map, 0xFF, map_size);
2704
2705 status = super_usb_efuse_parser_88xx(adapter, adapter->efuse_map,
2706 super_usb_map, super_usb_mask);
2707 if (status != HALMAC_RET_SUCCESS) {
2708 PLTFM_FREE(super_usb_mask, mask_size);
2709 PLTFM_FREE(super_usb_map, map_size);
2710 return HALMAC_RET_EEPROM_PARSING_FAIL;
2711 }
2712
2713 for (i = 0; i < map_size; i = i + 16) {
2714 mask_val_0 = *(updated_mask + (i >> 4));
2715 mask_val_1 = *(super_usb_mask + (i >> 4));
2716 if (mask_val_0 || mask_val_1) {
2717 for (j = 0; j < 4; j++) {
2718 val32 = i + (j << 1);
2719 if (mask_val_0 & BIT(j + 4)) {
2720 *(updated_map + val32) =
2721 *(drv_map + val32);
2722 *(updated_map + val32 + 1) =
2723 *(drv_map + val32 + 1);
2724 } else if (mask_val_1 & BIT(j + 4)) {
2725 *(updated_map + val32) =
2726 *(super_usb_map + val32);
2727 *(updated_map + val32 + 1) =
2728 *(super_usb_map + val32 + 1);
2729 }
2730 }
2731 for (j = 0; j < 4; j++) {
2732 val32 = i + (j << 1);
2733 if (mask_val_0 & BIT(j)) {
2734 *(updated_map + val32 + 8) =
2735 *(drv_map + val32 + 8);
2736 *(updated_map + val32 + 9) =
2737 *(drv_map + val32 + 9);
2738 } else if (mask_val_1 & BIT(j)) {
2739 *(updated_map + val32 + 8) =
2740 *(super_usb_map + val32 + 8);
2741 *(updated_map + val32 + 9) =
2742 *(super_usb_map + val32 + 9);
2743 }
2744 }
2745 *(updated_mask + (i >> 4)) |= mask_val_1;
2746 }
2747 }
2748
2749 PLTFM_FREE(super_usb_mask, mask_size);
2750 PLTFM_FREE(super_usb_map, map_size);
2751
2752 return status;
2753 }
2754
2755 static enum halmac_ret_status
super_usb_efuse_parser_88xx(struct halmac_adapter * adapter,u8 * phy_map,u8 * log_map,u8 * log_mask)2756 super_usb_efuse_parser_88xx(struct halmac_adapter *adapter, u8 *phy_map,
2757 u8 *log_map, u8 *log_mask)
2758 {
2759 u8 i;
2760 u8 value8;
2761 u8 blk_idx;
2762 u8 word_en;
2763 u8 valid;
2764 u8 hdr;
2765 u8 hdr2 = 0;
2766 u8 usb_addr;
2767 u32 eeprom_idx;
2768 u32 efuse_idx = 0;
2769 u32 start_offset;
2770 u32 prtct_efuse_size = adapter->hw_cfg_info.prtct_efuse_size;
2771 struct halmac_hw_cfg_info *hw_info = &adapter->hw_cfg_info;
2772
2773 do {
2774 value8 = *(phy_map + efuse_idx);
2775 hdr = value8;
2776
2777 if ((hdr & 0x1f) == 0x0f) {
2778 efuse_idx++;
2779 value8 = *(phy_map + efuse_idx);
2780 hdr2 = value8;
2781 if (hdr2 == 0xff)
2782 break;
2783 blk_idx = ((hdr2 & 0xF0) >> 1) | ((hdr >> 5) & 0x07);
2784 word_en = hdr2 & 0x0F;
2785 } else {
2786 blk_idx = (hdr & 0xF0) >> 4;
2787 word_en = hdr & 0x0F;
2788 }
2789
2790 if (hdr == 0xff)
2791 break;
2792
2793 efuse_idx++;
2794
2795 if (efuse_idx >= hw_info->efuse_size - prtct_efuse_size - 1)
2796 return HALMAC_RET_EEPROM_PARSING_FAIL;
2797
2798 for (i = 0; i < 4; i++) {
2799 valid = (u8)((~(word_en >> i)) & BIT(0));
2800 if (valid == 1) {
2801 eeprom_idx = (blk_idx << 3) + (i << 1);
2802
2803 if ((eeprom_idx + 1) > hw_info->eeprom_size) {
2804 PLTFM_MSG_ERR("[ERR]efuse idx:0x%X\n",
2805 efuse_idx - 1);
2806
2807 PLTFM_MSG_ERR("[ERR]read hdr:0x%X\n",
2808 hdr);
2809
2810 PLTFM_MSG_ERR("[ERR]rad hdr2:0x%X\n",
2811 hdr2);
2812
2813 return HALMAC_RET_EEPROM_PARSING_FAIL;
2814 }
2815
2816 value8 = *(phy_map + efuse_idx);
2817 *(log_map + eeprom_idx) = value8;
2818
2819 eeprom_idx++;
2820 efuse_idx++;
2821
2822 if (efuse_idx > hw_info->efuse_size -
2823 prtct_efuse_size - 1)
2824 return HALMAC_RET_EEPROM_PARSING_FAIL;
2825
2826 value8 = *(phy_map + efuse_idx);
2827 *(log_map + eeprom_idx) = value8;
2828
2829 efuse_idx++;
2830
2831 if (efuse_idx > hw_info->efuse_size -
2832 prtct_efuse_size)
2833 return HALMAC_RET_EEPROM_PARSING_FAIL;
2834 }
2835 }
2836
2837 start_offset = blk_idx << 3;
2838 if ((start_offset >= SUPER_USB_ZONE0_START &&
2839 start_offset <= SUPER_USB_ZONE0_END) ||
2840 (start_offset >= SUPER_USB_ZONE1_START &&
2841 start_offset <= SUPER_USB_ZONE1_END))
2842 usb_addr = 1;
2843 else
2844 usb_addr = 0;
2845 if (usb_addr) {
2846 if (word_en != 0xE && word_en != 0xD &&
2847 word_en != 0xB && word_en != 0x7) {
2848 if (blk_idx & 1)
2849 *(log_mask + (blk_idx >> 1)) |=
2850 ~word_en & 0x0F;
2851 else
2852 *(log_mask + (blk_idx >> 1)) |=
2853 ~(word_en << 4) & 0xF0;
2854 } else {
2855 if (blk_idx & 1)
2856 *(log_mask + (blk_idx >> 1)) &=
2857 word_en | 0xF0;
2858 else
2859 *(log_mask + (blk_idx >> 1)) &=
2860 (word_en << 4) | 0x0F;
2861 }
2862 }
2863 } while (1);
2864
2865 adapter->efuse_end = efuse_idx;
2866
2867 return HALMAC_RET_SUCCESS;
2868 }
2869
2870 static enum halmac_ret_status
super_usb_chk_88xx(struct halmac_adapter * adapter,u8 * super_usb)2871 super_usb_chk_88xx(struct halmac_adapter *adapter, u8 *super_usb)
2872 {
2873 u8 *local_map = NULL;
2874 u32 efuse_size;
2875 u8 re_pg;
2876 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2877
2878 if (adapter->chip_id == HALMAC_CHIP_ID_8822C &&
2879 (adapter->intf == HALMAC_INTERFACE_PCIE ||
2880 adapter->intf == HALMAC_INTERFACE_USB)) {
2881 *super_usb = 1;
2882 } else {
2883 *super_usb = 0;
2884 return HALMAC_RET_SUCCESS;
2885 }
2886
2887 if (adapter->efuse_map_valid == 0) {
2888 efuse_size = adapter->hw_cfg_info.efuse_size;
2889
2890 local_map = (u8 *)PLTFM_MALLOC(efuse_size);
2891 if (!local_map) {
2892 PLTFM_MSG_ERR("[ERR]local map\n");
2893 return HALMAC_RET_MALLOC_FAIL;
2894 }
2895
2896 status = read_efuse_88xx(adapter, 0, efuse_size, local_map);
2897 if (status != HALMAC_RET_SUCCESS) {
2898 PLTFM_MSG_ERR("[ERR]read efuse\n");
2899 PLTFM_FREE(local_map, efuse_size);
2900 return status;
2901 }
2902
2903 if (!adapter->efuse_map) {
2904 adapter->efuse_map = (u8 *)PLTFM_MALLOC(efuse_size);
2905 if (!adapter->efuse_map) {
2906 PLTFM_MSG_ERR("[ERR]malloc adapter map\n");
2907 PLTFM_FREE(local_map, efuse_size);
2908 return HALMAC_RET_MALLOC_FAIL;
2909 }
2910 }
2911
2912 PLTFM_MUTEX_LOCK(&adapter->efuse_mutex);
2913 PLTFM_MEMCPY(adapter->efuse_map, local_map, efuse_size);
2914 adapter->efuse_map_valid = 1;
2915 PLTFM_MUTEX_UNLOCK(&adapter->efuse_mutex);
2916
2917 PLTFM_FREE(local_map, efuse_size);
2918 }
2919
2920 status = super_usb_re_pg_chk_88xx(adapter, adapter->efuse_map, &re_pg);
2921 if (status != HALMAC_RET_SUCCESS)
2922 return status;
2923 if (re_pg) {
2924 status = super_usb_fmt_chk_88xx(adapter, &re_pg);
2925 if (status != HALMAC_RET_SUCCESS)
2926 return status;
2927 if (re_pg == 1) {
2928 *super_usb = 0;
2929 return HALMAC_RET_SUCCESS;
2930 }
2931 }
2932
2933 return status;
2934 }
2935
2936 static enum halmac_ret_status
log_efuse_re_pg_chk_88xx(struct halmac_adapter * adapter,u8 * efuse_mask,u32 addr,u8 * re_pg)2937 log_efuse_re_pg_chk_88xx(struct halmac_adapter *adapter, u8 *efuse_mask,
2938 u32 addr, u8 *re_pg)
2939 {
2940 u32 size = adapter->hw_cfg_info.eeprom_size;
2941 u8 mask_val;
2942 u8 mask_offset;
2943 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2944
2945 if (addr >= size) {
2946 PLTFM_MSG_ERR("[ERR]Offset is too large\n");
2947 return HALMAC_RET_EFUSE_SIZE_INCORRECT;
2948 }
2949
2950 mask_val = *(efuse_mask + (addr >> 4));
2951 if (addr & 0x8)
2952 mask_offset = BIT((addr & 0x7) >> 1);
2953 else
2954 mask_offset = BIT((addr & 0x7) >> 1) << 4;
2955
2956 if (mask_val & mask_offset)
2957 *re_pg = 1;
2958 else
2959 *re_pg = 0;
2960
2961 return status;
2962 }
2963
2964 static enum halmac_ret_status
super_usb_fmt_chk_88xx(struct halmac_adapter * adapter,u8 * re_pg)2965 super_usb_fmt_chk_88xx(struct halmac_adapter *adapter, u8 *re_pg)
2966 {
2967 u32 map_size = adapter->hw_cfg_info.eeprom_size;
2968 u32 mask_size = adapter->hw_cfg_info.eeprom_size >> 4;
2969 u32 addr;
2970 u8 *super_usb_map = NULL;
2971 u8 *super_usb_mask = NULL;
2972 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
2973
2974 super_usb_mask = (u8 *)PLTFM_MALLOC(mask_size);
2975 if (!super_usb_mask) {
2976 PLTFM_MSG_ERR("[ERR]malloc updated mask\n");
2977 return HALMAC_RET_MALLOC_FAIL;
2978 }
2979 PLTFM_MEMSET(super_usb_mask, 0x00, mask_size);
2980
2981 super_usb_map = (u8 *)PLTFM_MALLOC(map_size);
2982 if (!super_usb_map) {
2983 PLTFM_MSG_ERR("[ERR]malloc updated map\n");
2984 PLTFM_FREE(super_usb_mask, mask_size);
2985 return HALMAC_RET_MALLOC_FAIL;
2986 }
2987 PLTFM_MEMSET(super_usb_map, 0xFF, map_size);
2988
2989 status = super_usb_efuse_parser_88xx(adapter, adapter->efuse_map,
2990 super_usb_map, super_usb_mask);
2991 if (status != HALMAC_RET_SUCCESS) {
2992 PLTFM_FREE(super_usb_mask, mask_size);
2993 PLTFM_FREE(super_usb_map, map_size);
2994 return HALMAC_RET_EEPROM_PARSING_FAIL;
2995 }
2996
2997 for (addr = SUPER_USB_ZONE0_START;
2998 addr <= SUPER_USB_ZONE0_END; addr++) {
2999 status = log_efuse_re_pg_chk_88xx(adapter, super_usb_mask, addr,
3000 re_pg);
3001 if (status != HALMAC_RET_SUCCESS) {
3002 PLTFM_FREE(super_usb_mask, mask_size);
3003 PLTFM_FREE(super_usb_map, map_size);
3004 return status;
3005 }
3006 if (*re_pg == 1) {
3007 PLTFM_FREE(super_usb_mask, mask_size);
3008 PLTFM_FREE(super_usb_map, map_size);
3009 return status;
3010 }
3011 }
3012
3013 for (addr = SUPER_USB_ZONE1_START;
3014 addr <= SUPER_USB_ZONE1_END; addr++) {
3015 status = log_efuse_re_pg_chk_88xx(adapter, super_usb_mask, addr,
3016 re_pg);
3017 if (status != HALMAC_RET_SUCCESS) {
3018 PLTFM_FREE(super_usb_mask, mask_size);
3019 PLTFM_FREE(super_usb_map, map_size);
3020 return status;
3021 }
3022 if (*re_pg == 1) {
3023 PLTFM_FREE(super_usb_mask, mask_size);
3024 PLTFM_FREE(super_usb_map, map_size);
3025 return status;
3026 }
3027 }
3028
3029 *re_pg = 0;
3030
3031 PLTFM_FREE(super_usb_mask, mask_size);
3032 PLTFM_FREE(super_usb_map, map_size);
3033
3034 return status;
3035 }
3036
3037 static enum halmac_ret_status
super_usb_re_pg_chk_88xx(struct halmac_adapter * adapter,u8 * phy_map,u8 * re_pg)3038 super_usb_re_pg_chk_88xx(struct halmac_adapter *adapter, u8 *phy_map, u8 *re_pg)
3039 {
3040 u32 size = adapter->hw_cfg_info.eeprom_size;
3041 u32 addr;
3042 u8 *map = NULL;
3043 enum halmac_ret_status status = HALMAC_RET_SUCCESS;
3044
3045 map = (u8 *)PLTFM_MALLOC(size);
3046 if (!map) {
3047 PLTFM_MSG_ERR("[ERR]malloc map\n");
3048 return HALMAC_RET_MALLOC_FAIL;
3049 }
3050 PLTFM_MEMSET(map, 0xFF, size);
3051
3052 status = eeprom_mask_parser_88xx(adapter, phy_map, map);
3053 if (status != HALMAC_RET_SUCCESS) {
3054 PLTFM_FREE(map, size);
3055 return status;
3056 }
3057
3058 for (addr = SUPER_USB_RE_PG_CK_ZONE0_START;
3059 addr <= SUPER_USB_RE_PG_CK_ZONE0_END; addr++) {
3060 if (*(map + addr) != 0xFF) {
3061 PLTFM_FREE(map, size);
3062 *re_pg = 1;
3063 return status;
3064 }
3065 }
3066
3067 *re_pg = 0;
3068
3069 PLTFM_FREE(map, size);
3070
3071 return status;
3072 }
3073 #endif /* HALMAC_88XX_SUPPORT */
3074