• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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