net: wireless: rockchip_wlan: add rtl8723cs support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8723cs / core / efuse / rtw_efuse.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2011 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  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20 #define _RTW_EFUSE_C_
21
22 #include <drv_types.h>
23 #include <hal_data.h>
24
25 #include "../hal/efuse/efuse_mask.h"
26
27 /*------------------------Define local variable------------------------------*/
28 u8      fakeEfuseBank = {0};
29 u32     fakeEfuseUsedBytes = {0};
30 u8      fakeEfuseContent[EFUSE_MAX_HW_SIZE] = {0};
31 u8      fakeEfuseInitMap[EFUSE_MAX_MAP_LEN] = {0};
32 u8      fakeEfuseModifiedMap[EFUSE_MAX_MAP_LEN] = {0};
33
34 u32     BTEfuseUsedBytes = {0};
35 u8      BTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE];
36 u8      BTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN] = {0};
37 u8      BTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN] = {0};
38
39 u32     fakeBTEfuseUsedBytes = {0};
40 u8      fakeBTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE];
41 u8      fakeBTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN] = {0};
42 u8      fakeBTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN] = {0};
43
44 u8      maskfileBuffer[64];
45 /*------------------------Define local variable------------------------------*/
46 BOOLEAN rtw_file_efuse_IsMasked(PADAPTER pAdapter, u16 Offset)
47 {
48         int r = Offset / 16;
49         int c = (Offset % 16) / 2;
50         int result = 0;
51
52         if (pAdapter->registrypriv.boffefusemask)
53                 return FALSE;
54
55         if (c < 4) /* Upper double word */
56                 result = (maskfileBuffer[r] & (0x10 << c));
57         else
58                 result = (maskfileBuffer[r] & (0x01 << (c - 4)));
59
60         return (result > 0) ? 0 : 1;
61 }
62
63 BOOLEAN efuse_IsMasked(PADAPTER pAdapter, u16 Offset)
64 {
65         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);
66
67         if (pAdapter->registrypriv.boffefusemask)
68                 return FALSE;
69
70 #if DEV_BUS_TYPE == RT_USB_INTERFACE
71 #if defined(CONFIG_RTL8188E)
72         if (IS_HARDWARE_TYPE_8188E(pAdapter))
73                 return (IS_MASKED(8188E, _MUSB, Offset)) ? TRUE : FALSE;
74 #endif
75 #if defined(CONFIG_RTL8812A)
76         if (IS_HARDWARE_TYPE_8812(pAdapter))
77                 return (IS_MASKED(8812A, _MUSB, Offset)) ? TRUE : FALSE;
78 #endif
79 #if defined(CONFIG_RTL8821A)
80 #if 0
81         if (IS_HARDWARE_TYPE_8811AU(pAdapter))
82                 return (IS_MASKED(8811A, _MUSB, Offset)) ? TRUE : FALSE;
83 #endif
84         if (IS_HARDWARE_TYPE_8821(pAdapter))
85                 return (IS_MASKED(8821A, _MUSB, Offset)) ? TRUE : FALSE;
86 #endif
87 #if defined(CONFIG_RTL8192E)
88         if (IS_HARDWARE_TYPE_8192E(pAdapter))
89                 return (IS_MASKED(8192E, _MUSB, Offset)) ? TRUE : FALSE;
90 #endif
91 #if defined(CONFIG_RTL8723B)
92         if (IS_HARDWARE_TYPE_8723B(pAdapter))
93                 return (IS_MASKED(8723B, _MUSB, Offset)) ? TRUE : FALSE;
94 #endif
95 #if defined(CONFIG_RTL8703B)
96         if (IS_HARDWARE_TYPE_8703B(pAdapter))
97                 return (IS_MASKED(8703B, _MUSB, Offset)) ? TRUE : FALSE;
98 #endif
99 #if defined(CONFIG_RTL8814A)
100         if (IS_HARDWARE_TYPE_8814A(pAdapter))
101                 return (IS_MASKED(8814A, _MUSB, Offset)) ? TRUE : FALSE;
102 #endif
103 #if defined(CONFIG_RTL8188F)
104         if (IS_HARDWARE_TYPE_8188F(pAdapter))
105                 return (IS_MASKED(8188F, _MUSB, Offset)) ? TRUE : FALSE;
106 #endif
107 #if defined(CONFIG_RTL8822B)
108         if (IS_HARDWARE_TYPE_8822B(pAdapter))
109                 return (IS_MASKED(8822B, _MUSB, Offset)) ? TRUE : FALSE;
110 #endif
111 #if defined(CONFIG_RTL8723D)
112         if (IS_HARDWARE_TYPE_8723D(pAdapter))
113                 return (IS_MASKED(8723D, _MUSB, Offset)) ? TRUE : FALSE;
114 #endif
115
116         /*#if defined(CONFIG_RTL8821C)
117                 if (IS_HARDWARE_TYPE_8821C(pAdapter))
118                         return (IS_MASKED(8821C,_MUSB,Offset)) ? TRUE : FALSE;
119         #endif*/
120
121 #elif DEV_BUS_TYPE == RT_PCI_INTERFACE
122 #if defined(CONFIG_RTL8188E)
123         if (IS_HARDWARE_TYPE_8188E(pAdapter))
124                 return (IS_MASKED(8188E, _MPCIE, Offset)) ? TRUE : FALSE;
125 #endif
126 #if defined(CONFIG_RTL8192E)
127         if (IS_HARDWARE_TYPE_8192E(pAdapter))
128                 return (IS_MASKED(8192E, _MPCIE, Offset)) ? TRUE : FALSE;
129 #endif
130 #if defined(CONFIG_RTL8812A)
131         if (IS_HARDWARE_TYPE_8812(pAdapter))
132                 return (IS_MASKED(8812A, _MPCIE, Offset)) ? TRUE : FALSE;
133 #endif
134 #if defined(CONFIG_RTL8821A)
135         if (IS_HARDWARE_TYPE_8821(pAdapter))
136                 return (IS_MASKED(8821A, _MPCIE, Offset)) ? TRUE : FALSE;
137 #endif
138 #if defined(CONFIG_RTL8723B)
139         if (IS_HARDWARE_TYPE_8723B(pAdapter))
140                 return (IS_MASKED(8723B, _MPCIE, Offset)) ? TRUE : FALSE;
141 #endif
142 #if defined(CONFIG_RTL8814A)
143         if (IS_HARDWARE_TYPE_8814A(pAdapter))
144                 return (IS_MASKED(8814A, _MPCIE, Offset)) ? TRUE : FALSE;
145 #endif
146 #if defined(CONFIG_RTL8822B)
147         if (IS_HARDWARE_TYPE_8822B(pAdapter))
148                 return (IS_MASKED(8822B, _MPCIE, Offset)) ? TRUE : FALSE;
149 #endif
150
151 #elif DEV_BUS_TYPE == RT_SDIO_INTERFACE
152 #ifdef CONFIG_RTL8188E_SDIO
153         if (IS_HARDWARE_TYPE_8188E(pAdapter))
154                 return (IS_MASKED(8188E, _MSDIO, Offset)) ? TRUE : FALSE;
155 #endif
156 #ifdef CONFIG_RTL8188F_SDIO
157         if (IS_HARDWARE_TYPE_8188F(pAdapter))
158                 return (IS_MASKED(8188F, _MSDIO, Offset)) ? TRUE : FALSE;
159 #endif
160 #if defined(CONFIG_RTL8821C)
161         if (IS_HARDWARE_TYPE_8821C(pAdapter))
162                 return (IS_MASKED(8821C, _MSDIO, Offset)) ? TRUE : FALSE;
163 #endif
164 #if defined(CONFIG_RTL8822B)
165         if (IS_HARDWARE_TYPE_8822B(pAdapter))
166                 return (IS_MASKED(8822B, _MSDIO, Offset)) ? TRUE : FALSE;
167 #endif
168 #endif
169
170         return FALSE;
171 }
172
173 void rtw_efuse_mask_array(PADAPTER pAdapter, u8 *pArray)
174 {
175         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);
176
177 #if DEV_BUS_TYPE == RT_USB_INTERFACE
178 #if defined(CONFIG_RTL8188E)
179         if (IS_HARDWARE_TYPE_8188E(pAdapter))
180                 GET_MASK_ARRAY(8188E, _MUSB, pArray);
181 #endif
182 #if defined(CONFIG_RTL8812A)
183         if (IS_HARDWARE_TYPE_8812(pAdapter))
184                 GET_MASK_ARRAY(8812A, _MUSB, pArray);
185 #endif
186 #if defined(CONFIG_RTL8821A)
187         if (IS_HARDWARE_TYPE_8821(pAdapter))
188                 GET_MASK_ARRAY(8821A, _MUSB, pArray);
189 #endif
190 #if defined(CONFIG_RTL8192E)
191         if (IS_HARDWARE_TYPE_8192E(pAdapter))
192                 GET_MASK_ARRAY(8192E, _MUSB, pArray);
193 #endif
194 #if defined(CONFIG_RTL8723B)
195         if (IS_HARDWARE_TYPE_8723B(pAdapter))
196                 GET_MASK_ARRAY(8723B, _MUSB, pArray);
197 #endif
198 #if defined(CONFIG_RTL8703B)
199         if (IS_HARDWARE_TYPE_8703B(pAdapter))
200                 GET_MASK_ARRAY(8703B, _MUSB, pArray);
201 #endif
202 #if defined(CONFIG_RTL8188F)
203         if (IS_HARDWARE_TYPE_8188F(pAdapter))
204                 GET_MASK_ARRAY(8188F, _MUSB, pArray);
205 #endif
206 #if defined(CONFIG_RTL8814A)
207         if (IS_HARDWARE_TYPE_8814A(pAdapter))
208                 GET_MASK_ARRAY(8814A, _MUSB, pArray);
209 #endif
210 #if defined(CONFIG_RTL8822B)
211         if (IS_HARDWARE_TYPE_8822B(pAdapter))
212                 GET_MASK_ARRAY(8822B, _MUSB, pArray);
213 #endif
214         /*#if defined(CONFIG_RTL8821C)
215                 if (IS_HARDWARE_TYPE_8821C(pAdapter))
216                         GET_MASK_ARRAY(8821C,_MUSB,pArray);
217         #endif*/
218 #elif DEV_BUS_TYPE == RT_PCI_INTERFACE
219 #if defined(CONFIG_RTL8188E)
220         if (IS_HARDWARE_TYPE_8188E(pAdapter))
221                 GET_MASK_ARRAY(8188E, _MPCIE, pArray);
222 #endif
223 #if defined(CONFIG_RTL8192E)
224         if (IS_HARDWARE_TYPE_8192E(pAdapter))
225                 GET_MASK_ARRAY(8192E, _MPCIE, pArray);
226 #endif
227 #if defined(CONFIG_RTL8812A)
228         if (IS_HARDWARE_TYPE_8812(pAdapter))
229                 GET_MASK_ARRAY(8812A, _MPCIE, pArray);
230 #endif
231 #if defined(CONFIG_RTL8821A)
232         if (IS_HARDWARE_TYPE_8821(pAdapter))
233                 GET_MASK_ARRAY(8821A, _MPCIE, pArray);
234 #endif
235 #if defined(CONFIG_RTL8723B)
236         if (IS_HARDWARE_TYPE_8723B(pAdapter))
237                 GET_MASK_ARRAY(8723B, _MPCIE, pArray);
238 #endif
239 #if defined(CONFIG_RTL8814A)
240         if (IS_HARDWARE_TYPE_8814A(pAdapter))
241                 GET_MASK_ARRAY(8814A, _MPCIE, pArray);
242 #endif
243 #if defined(CONFIG_RTL8822B)
244         if (IS_HARDWARE_TYPE_8822B(pAdapter))
245                 GET_MASK_ARRAY(8822B, _MPCIE, pArray);
246 #endif
247 #elif DEV_BUS_TYPE == RT_SDIO_INTERFACE
248 #if defined(CONFIG_RTL8188E)
249         if (IS_HARDWARE_TYPE_8188E(pAdapter))
250                 GET_MASK_ARRAY(8188E, _MSDIO, pArray);
251 #endif
252 #if defined(CONFIG_RTL8188F)
253         if (IS_HARDWARE_TYPE_8188F(pAdapter))
254                 GET_MASK_ARRAY(8188F, _MSDIO, pArray);
255 #endif
256 #if defined(CONFIG_RTL8821C)
257         if (IS_HARDWARE_TYPE_8821C(pAdapter))
258                 GET_MASK_ARRAY(8821C , _MSDIO, pArray);
259 #endif
260 #if defined(CONFIG_RTL8822B)
261         if (IS_HARDWARE_TYPE_8822B(pAdapter))
262                 GET_MASK_ARRAY(8822B , _MSDIO, pArray);
263 #endif
264 #endif /*#elif DEV_BUS_TYPE == RT_SDIO_INTERFACE*/
265 }
266
267 u16 rtw_get_efuse_mask_arraylen(PADAPTER pAdapter)
268 {
269         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(pAdapter);
270
271 #if DEV_BUS_TYPE == RT_USB_INTERFACE
272 #if defined(CONFIG_RTL8188E)
273         if (IS_HARDWARE_TYPE_8188E(pAdapter))
274                 return GET_MASK_ARRAY_LEN(8188E, _MUSB);
275 #endif
276 #if defined(CONFIG_RTL8812A)
277         if (IS_HARDWARE_TYPE_8812(pAdapter))
278                 return GET_MASK_ARRAY_LEN(8812A, _MUSB);
279 #endif
280 #if defined(CONFIG_RTL8821A)
281         if (IS_HARDWARE_TYPE_8821(pAdapter))
282                 return GET_MASK_ARRAY_LEN(8821A, _MUSB);
283 #endif
284 #if defined(CONFIG_RTL8192E)
285         if (IS_HARDWARE_TYPE_8192E(pAdapter))
286                 return GET_MASK_ARRAY_LEN(8192E, _MUSB);
287 #endif
288 #if defined(CONFIG_RTL8723B)
289         if (IS_HARDWARE_TYPE_8723B(pAdapter))
290                 return GET_MASK_ARRAY_LEN(8723B, _MUSB);
291 #endif
292 #if defined(CONFIG_RTL8703B)
293         if (IS_HARDWARE_TYPE_8703B(pAdapter))
294                 return GET_MASK_ARRAY_LEN(8703B, _MUSB);
295 #endif
296 #if defined(CONFIG_RTL8188F)
297         if (IS_HARDWARE_TYPE_8188F(pAdapter))
298                 return GET_MASK_ARRAY_LEN(8188F, _MUSB);
299 #endif
300 #if defined(CONFIG_RTL8814A)
301         if (IS_HARDWARE_TYPE_8814A(pAdapter))
302                 return GET_MASK_ARRAY_LEN(8814A, _MUSB);
303 #endif
304 #if defined(CONFIG_RTL8822B)
305         if (IS_HARDWARE_TYPE_8822B(pAdapter))
306                 return GET_MASK_ARRAY_LEN(8822B, _MUSB);
307 #endif
308         /*#if defined(CONFIG_RTL8821C)
309                 if (IS_HARDWARE_TYPE_8821C(pAdapter))
310                         return GET_MASK_ARRAY_LEN(8821C,_MUSB);
311         #endif*/
312 #elif DEV_BUS_TYPE == RT_PCI_INTERFACE
313 #if defined(CONFIG_RTL8188E)
314         if (IS_HARDWARE_TYPE_8188E(pAdapter))
315                 return GET_MASK_ARRAY_LEN(8188E, _MPCIE);
316 #endif
317 #if defined(CONFIG_RTL8192E)
318         if (IS_HARDWARE_TYPE_8192E(pAdapter))
319                 return GET_MASK_ARRAY_LEN(8192E, _MPCIE);
320 #endif
321 #if defined(CONFIG_RTL8812A)
322         if (IS_HARDWARE_TYPE_8812(pAdapter))
323                 return GET_MASK_ARRAY_LEN(8812A, _MPCIE);
324 #endif
325 #if defined(CONFIG_RTL8821A)
326         if (IS_HARDWARE_TYPE_8821(pAdapter))
327                 return GET_MASK_ARRAY_LEN(8821A, _MPCIE);
328 #endif
329 #if defined(CONFIG_RTL8723B)
330         if (IS_HARDWARE_TYPE_8723B(pAdapter))
331                 return GET_MASK_ARRAY_LEN(8723B, _MPCIE);
332 #endif
333 #if defined(CONFIG_RTL8814A)
334         if (IS_HARDWARE_TYPE_8814A(pAdapter))
335                 return GET_MASK_ARRAY_LEN(8814A, _MPCIE);
336 #endif
337 #if defined(CONFIG_RTL8822B)
338         if (IS_HARDWARE_TYPE_8822B(pAdapter))
339                 return GET_MASK_ARRAY_LEN(8822B, _MPCIE);
340 #endif
341 #elif DEV_BUS_TYPE == RT_SDIO_INTERFACE
342 #if defined(CONFIG_RTL8188E)
343         if (IS_HARDWARE_TYPE_8188E(pAdapter))
344                 return GET_MASK_ARRAY_LEN(8188E, _MSDIO);
345 #endif
346 #if defined(CONFIG_RTL8188F)
347         if (IS_HARDWARE_TYPE_8188F(pAdapter))
348                 return GET_MASK_ARRAY_LEN(8188F, _MSDIO);
349 #endif
350 #if defined(CONFIG_RTL8821C)
351         if (IS_HARDWARE_TYPE_8821C(pAdapter))
352                 return GET_MASK_ARRAY_LEN(8821C, _MSDIO);
353 #endif
354 #if defined(CONFIG_RTL8822B)
355         if (IS_HARDWARE_TYPE_8822B(pAdapter))
356                 return GET_MASK_ARRAY_LEN(8822B, _MSDIO);
357 #endif
358 #endif
359         return 0;
360 }
361
362 u8 rtw_efuse_mask_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data)
363 {
364         u8      ret = _SUCCESS;
365         u16     mapLen = 0, i = 0;
366
367         EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&mapLen, _FALSE);
368
369         ret = rtw_efuse_map_read(padapter, addr, cnts , data);
370
371         if (padapter->registrypriv.boffefusemask == 0) {
372
373                 for (i = 0; i < cnts; i++) {
374                         if (padapter->registrypriv.bFileMaskEfuse == _TRUE) {
375                                 if (rtw_file_efuse_IsMasked(padapter, addr + i)) /*use file efuse mask.*/
376                                         data[i] = 0xff;
377                         } else {
378                                 /*RTW_INFO(" %s , data[%d] = %x\n", __func__, i, data[i]);*/
379                                 if (efuse_IsMasked(padapter, addr + i)) {
380                                         data[i] = 0xff;
381                                         /*RTW_INFO(" %s ,mask data[%d] = %x\n", __func__, i, data[i]);*/
382                                 }
383                         }
384                 }
385
386         }
387         return ret;
388
389 }
390
391
392 #ifdef RTW_HALMAC
393 #include "../../hal/hal_halmac.h"
394
395 void Efuse_PowerSwitch(PADAPTER adapter, u8 write, u8 pwrstate)
396 {
397 }
398
399 void BTEfuse_PowerSwitch(PADAPTER adapter, u8 write, u8 pwrstate)
400 {
401 }
402
403 u8 efuse_GetCurrentSize(PADAPTER adapter, u16 *size)
404 {
405         *size = 0;
406
407         return _FAIL;
408 }
409
410 u16 efuse_GetMaxSize(PADAPTER adapter)
411 {
412         struct dvobj_priv *d;
413         u32 size = 0;
414         int err;
415
416         d = adapter_to_dvobj(adapter);
417         err = rtw_halmac_get_physical_efuse_size(d, &size);
418         if (err)
419                 return 0;
420
421         return size;
422 }
423
424 u16 efuse_GetavailableSize(PADAPTER adapter)
425 {
426         struct dvobj_priv *d;
427         u32 size = 0;
428         int err;
429
430         d = adapter_to_dvobj(adapter);
431         err = rtw_halmac_get_available_efuse_size(d, &size);
432         if (err)
433                 return 0;
434
435         return size;
436 }
437
438
439 u8 efuse_bt_GetCurrentSize(PADAPTER adapter, u16 *usesize)
440 {
441         u8 *efuse_map;
442
443         *usesize = 0;
444         efuse_map = rtw_malloc(EFUSE_BT_MAP_LEN);
445         if (efuse_map == NULL) {
446                 RTW_DBG("%s: malloc FAIL\n", __FUNCTION__);
447                 return _FAIL;
448         }
449
450         /* for get bt phy efuse last use byte */
451         hal_ReadEFuse_BT_logic_map(adapter, 0x00, EFUSE_BT_MAP_LEN, efuse_map);
452         *usesize = fakeBTEfuseUsedBytes;
453
454         if (efuse_map)
455                 rtw_mfree(efuse_map, EFUSE_BT_MAP_LEN);
456
457         return _SUCCESS;
458 }
459
460 u16 efuse_bt_GetMaxSize(PADAPTER adapter)
461 {
462         return EFUSE_BT_REAL_CONTENT_LEN;
463 }
464
465 void EFUSE_GetEfuseDefinition(PADAPTER adapter, u8 efusetype, u8 type, void *out, BOOLEAN test)
466 {
467         struct dvobj_priv *d;
468         u32 v32 = 0;
469
470
471         d = adapter_to_dvobj(adapter);
472
473         if (adapter->hal_func.EFUSEGetEfuseDefinition) {
474                 adapter->hal_func.EFUSEGetEfuseDefinition(adapter, efusetype, type, out, test);
475                 return;
476         }
477
478         if (EFUSE_WIFI == efusetype) {
479                 switch (type) {
480                 case TYPE_EFUSE_MAP_LEN:
481                         rtw_halmac_get_logical_efuse_size(d, &v32);
482                         *(u16 *)out = (u16)v32;
483                         return;
484
485                 case TYPE_EFUSE_REAL_CONTENT_LEN:       
486                         rtw_halmac_get_physical_efuse_size(d, &v32);
487                         *(u16 *)out = (u16)v32;
488                         return;
489                 }
490         } else if (EFUSE_BT == efusetype) {
491                 switch (type) {
492                 case TYPE_EFUSE_MAP_LEN:
493                         *(u16 *)out = EFUSE_BT_MAP_LEN;
494                         return;
495
496                 case TYPE_EFUSE_REAL_CONTENT_LEN:
497                         *(u16 *)out = EFUSE_BT_REAL_CONTENT_LEN;
498                         return;
499                 }
500         }
501 }
502
503 /*
504  * read/write raw efuse data
505  */
506 u8 rtw_efuse_access(PADAPTER adapter, u8 write, u16 addr, u16 cnts, u8 *data)
507 {
508         struct dvobj_priv *d;
509         u8 *efuse = NULL;
510         u32 size, i;
511         int err;
512
513
514         d = adapter_to_dvobj(adapter);
515         err = rtw_halmac_get_physical_efuse_size(d, &size);
516         if (err)
517                 size = EFUSE_MAX_SIZE;
518
519         if ((addr + cnts) > size)
520                 return _FAIL;
521
522         if (_TRUE == write) {
523                 err = rtw_halmac_write_physical_efuse(d, addr, cnts, data);
524                 if (err)
525                         return _FAIL;
526         } else {
527                 if (cnts > 16)
528                         efuse = rtw_zmalloc(size);
529
530                 if (efuse) {
531                         err = rtw_halmac_read_physical_efuse_map(d, efuse, size);
532                         if (err) {
533                                 rtw_mfree(efuse, size);
534                                 return _FAIL;
535                         }
536
537                         _rtw_memcpy(data, efuse + addr, cnts);
538                         rtw_mfree(efuse, size);
539                 } else {
540                         err = rtw_halmac_read_physical_efuse(d, addr, cnts, data);
541                         if (err)
542                                 return _FAIL;
543                 }
544         }
545
546         return _SUCCESS;
547 }
548
549 static inline void dump_buf(u8 *buf, u32 len)
550 {
551         u32 i;
552
553         RTW_INFO("-----------------Len %d----------------\n", len);
554         for (i = 0; i < len; i++)
555                 printk("%2.2x-", *(buf + i));
556         printk("\n");
557 }
558
559 /*
560  * read/write raw efuse data
561  */
562 u8 rtw_efuse_bt_access(PADAPTER adapter, u8 write, u16 addr, u16 cnts, u8 *data)
563 {
564         struct dvobj_priv *d;
565         u8 *efuse = NULL;
566         u32 size, i;
567         int err = _FAIL;
568
569
570         d = adapter_to_dvobj(adapter);
571
572         size = EFUSE_BT_REAL_CONTENT_LEN;
573
574         if ((addr + cnts) > size)
575                 return _FAIL;
576
577         if (_TRUE == write) {
578                 err = rtw_halmac_write_bt_physical_efuse(d, addr, cnts, data);
579                 if (err == -1) {
580                         RTW_ERR("%s: rtw_halmac_write_bt_physical_efuse fail!\n", __FUNCTION__);
581                         return _FAIL;
582                 }
583                 RTW_INFO("%s: rtw_halmac_write_bt_physical_efuse OK! data 0x%x\n", __FUNCTION__, *data);
584         } else {
585                 efuse = rtw_zmalloc(size);
586
587                 if (efuse) {
588                         err = rtw_halmac_read_bt_physical_efuse_map(d, efuse, size);
589                         
590                         if (err == -1) {
591                                 RTW_ERR("%s: rtw_halmac_read_bt_physical_efuse_map fail!\n", __FUNCTION__);
592                                 rtw_mfree(efuse, size);
593                                 return _FAIL;
594                         }
595                         dump_buf(efuse + addr, cnts);
596
597                         _rtw_memcpy(data, efuse + addr, cnts);
598
599                         RTW_INFO("%s: rtw_halmac_read_bt_physical_efuse_map ok! data 0x%x\n", __FUNCTION__, *data);
600                         rtw_mfree(efuse, size);
601                 }
602         }
603
604         return _SUCCESS;
605 }
606
607 u8 rtw_efuse_map_read(PADAPTER adapter, u16 addr, u16 cnts, u8 *data)
608 {
609         struct dvobj_priv *d;
610         u8 *efuse = NULL;
611         u32 size, i;
612         int err;
613
614
615         d = adapter_to_dvobj(adapter);
616         err = rtw_halmac_get_logical_efuse_size(d, &size);
617         if (err)
618                 return _FAIL;
619
620         /* size error handle */
621         if ((addr + cnts) > size) {
622                 if (addr < size)
623                         cnts = size - addr;
624                 else
625                         return _FAIL;
626         }
627
628         if (cnts > 16)
629                 efuse = rtw_zmalloc(size);
630
631         if (efuse) {
632                 err = rtw_halmac_read_logical_efuse_map(d, efuse, size);
633                 if (err) {
634                         rtw_mfree(efuse, size);
635                         return _FAIL;
636                 }
637
638                 _rtw_memcpy(data, efuse + addr, cnts);
639                 rtw_mfree(efuse, size);
640         } else {
641                 err = rtw_halmac_read_logical_efuse(d, addr, cnts, data);
642                 if (err)
643                         return _FAIL;
644         }
645
646         return _SUCCESS;
647 }
648
649 u8 rtw_efuse_map_write(PADAPTER adapter, u16 addr, u16 cnts, u8 *data)
650 {
651         struct dvobj_priv *d;
652         u8 *efuse = NULL;
653         u32 size, i;
654         int err;
655         u8 mask_buf[64] = "";
656         u16 mask_len = sizeof(u8) * rtw_get_efuse_mask_arraylen(adapter);
657
658         d = adapter_to_dvobj(adapter);
659         err = rtw_halmac_get_logical_efuse_size(d, &size);
660         if (err)
661                 return _FAIL;
662
663         if ((addr + cnts) > size)
664                 return _FAIL;
665
666         efuse = rtw_zmalloc(size);
667         if (!efuse)
668                 return _FAIL;
669
670         err = rtw_halmac_read_logical_efuse_map(d, efuse, size);
671         if (err) {
672                 rtw_mfree(efuse, size);
673                 return _FAIL;
674         }
675
676         _rtw_memcpy(efuse + addr, data, cnts);
677
678         if (adapter->registrypriv.boffefusemask == 0) {
679                 RTW_INFO("Use mask Array Len: %d\n", mask_len);
680
681                 if (mask_len != 0) {
682                         if (adapter->registrypriv.bFileMaskEfuse == _TRUE)
683                                 _rtw_memcpy(mask_buf, maskfileBuffer, mask_len);
684                         else
685                                 rtw_efuse_mask_array(adapter, mask_buf);
686
687                         err = rtw_halmac_write_logical_efuse_map(d, efuse, size, mask_buf, mask_len);
688                 } else
689                         err = rtw_halmac_write_logical_efuse_map(d, efuse, size, NULL, 0);
690         } else {
691                 _rtw_memset(mask_buf, 0xFF, sizeof(mask_buf));
692                 RTW_INFO("Efuse mask off\n");
693                 err = rtw_halmac_write_logical_efuse_map(d, efuse, size, mask_buf, size/16);
694         }
695
696         if (err) {
697                 rtw_mfree(efuse, size);
698                 return _FAIL;
699         }
700
701         rtw_mfree(efuse, size);
702
703         return _SUCCESS;
704 }
705
706 int Efuse_PgPacketRead(PADAPTER adapter, u8 offset, u8 *data, BOOLEAN test)
707 {
708         return _FALSE;
709 }
710
711 int Efuse_PgPacketWrite(PADAPTER adapter, u8 offset, u8 word_en, u8 *data, BOOLEAN test)
712 {
713         return _FALSE;
714 }
715
716 u8 rtw_BT_efuse_map_read(PADAPTER adapter, u16 addr, u16 cnts, u8 *data)
717 {
718         hal_ReadEFuse_BT_logic_map(adapter,addr, cnts, data);
719
720         return _SUCCESS;
721 }
722
723 u8 rtw_BT_efuse_map_write(PADAPTER adapter, u16 addr, u16 cnts, u8 *data)
724 {
725 #define RT_ASSERT_RET(expr)                                                                     \
726         if (!(expr)) {                                                                          \
727                 printk("Assertion failed! %s at ......\n", #expr);                              \
728                 printk("          ......%s,%s, line=%d\n",__FILE__, __FUNCTION__, __LINE__);    \
729                 return _FAIL;   \
730         }
731
732         u8      offset, word_en;
733         u8      *map;
734         u8      newdata[PGPKT_DATA_SIZE];
735         s32 i = 0, j = 0, idx;
736         u8      ret = _SUCCESS;
737         u16 mapLen = 1024;
738
739         if ((addr + cnts) > mapLen)
740                 return _FAIL;
741
742         RT_ASSERT_RET(PGPKT_DATA_SIZE == 8); /* have to be 8 byte alignment */
743         RT_ASSERT_RET((mapLen & 0x7) == 0); /* have to be PGPKT_DATA_SIZE alignment for memcpy */
744
745         map = rtw_zmalloc(mapLen);
746         if (map == NULL)
747                 return _FAIL;
748
749         ret = rtw_BT_efuse_map_read(adapter, 0, mapLen, map);
750         if (ret == _FAIL)
751                 goto exit;
752         RTW_INFO("OFFSET\tVALUE(hex)\n");
753         for (i = 0; i < mapLen; i += 16) { /* set 512 because the iwpriv's extra size have limit 0x7FF */
754                 RTW_INFO("0x%03x\t", i);
755                 for (j = 0; j < 8; j++)
756                         RTW_INFO("%02X ", map[i + j]);
757                 RTW_INFO("\t");
758                 for (; j < 16; j++)
759                         RTW_INFO("%02X ", map[i + j]);
760                 RTW_INFO("\n");
761         }
762         RTW_INFO("\n");
763
764         idx = 0;
765         offset = (addr >> 3);
766         while (idx < cnts) {
767                 word_en = 0xF;
768                 j = (addr + idx) & 0x7;
769                 _rtw_memcpy(newdata, &map[offset << 3], PGPKT_DATA_SIZE);
770                 for (i = j; i < PGPKT_DATA_SIZE && idx < cnts; i++, idx++) {
771                         if (data[idx] != map[addr + idx]) {
772                                 word_en &= ~BIT(i >> 1);
773                                 newdata[i] = data[idx];
774                         }
775                 }
776
777                 if (word_en != 0xF) {
778                         ret = EfusePgPacketWrite_BT(adapter, offset, word_en, newdata, _FALSE);
779                         RTW_INFO("offset=%x\n", offset);
780                         RTW_INFO("word_en=%x\n", word_en);
781                         RTW_INFO("%s: data=", __FUNCTION__);
782                         for (i = 0; i < PGPKT_DATA_SIZE; i++)
783                                 RTW_INFO("0x%02X ", newdata[i]);
784                         RTW_INFO("\n");
785                         if (ret == _FAIL)
786                                 break;
787                 }
788                 offset++;
789         }
790 exit:
791         rtw_mfree(map, mapLen);
792         return _SUCCESS;
793 }
794
795 VOID hal_ReadEFuse_BT_logic_map(
796         PADAPTER        padapter,
797         u16                     _offset,
798         u16                     _size_byte,
799         u8                      *pbuf
800 )
801 {
802
803         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(padapter);
804         PEFUSE_HAL              pEfuseHal = &pHalData->EfuseHal;
805
806         u8      *efuseTbl, *phyefuse;
807         u8      bank;
808         u16     eFuse_Addr = 0;
809         u8      efuseHeader, efuseExtHdr, efuseData;
810         u8      offset, wden;
811         u16     i, total, used;
812         u8      efuse_usage;
813
814
815         /* */
816         /* Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. */
817         /* */
818         if ((_offset + _size_byte) > EFUSE_BT_MAP_LEN) {
819                 RTW_INFO("%s: Invalid offset(%#x) with read bytes(%#x)!!\n", __FUNCTION__, _offset, _size_byte);
820                 return;
821         }
822
823         efuseTbl = rtw_malloc(EFUSE_BT_MAP_LEN);
824         phyefuse = rtw_malloc(EFUSE_BT_REAL_CONTENT_LEN);
825         if (efuseTbl == NULL || phyefuse == NULL) {
826                 RTW_INFO("%s: efuseTbl or phyefuse malloc fail!\n", __FUNCTION__);
827                 goto exit;
828         }
829
830         /* 0xff will be efuse default value instead of 0x00. */
831         _rtw_memset(efuseTbl, 0xFF, EFUSE_BT_MAP_LEN);
832         _rtw_memset(phyefuse, 0xFF, EFUSE_BT_REAL_CONTENT_LEN);
833
834         if (rtw_efuse_bt_access(padapter, _FALSE, 0, EFUSE_BT_REAL_CONTENT_LEN, phyefuse))
835                 dump_buf(phyefuse, EFUSE_BT_REAL_BANK_CONTENT_LEN);
836         
837         total = BANK_NUM;
838         for (bank = 1; bank <= total; bank++) { /* 8723d Max bake 0~2 */
839                 eFuse_Addr = 0;
840
841                 while (AVAILABLE_EFUSE_ADDR(eFuse_Addr)) {
842                         /* ReadEFuseByte(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest); */
843                         efuseHeader = phyefuse[eFuse_Addr++];
844
845                         if (efuseHeader == 0xFF)
846                                 break;
847                         RTW_INFO("%s: efuse[%#X]=0x%02x (header)\n", __FUNCTION__, (((bank - 1) * EFUSE_BT_REAL_CONTENT_LEN) + eFuse_Addr - 1), efuseHeader);
848
849                         /* Check PG header for section num. */
850                         if (EXT_HEADER(efuseHeader)) {  /* extended header */
851                                 offset = GET_HDR_OFFSET_2_0(efuseHeader);
852                                 RTW_INFO("%s: extended header offset_2_0=0x%X\n", __FUNCTION__, offset);
853
854                                 /* ReadEFuseByte(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest); */
855                                 efuseExtHdr = phyefuse[eFuse_Addr++];
856
857                                 RTW_INFO("%s: efuse[%#X]=0x%02x (ext header)\n", __FUNCTION__, (((bank - 1) * EFUSE_BT_REAL_CONTENT_LEN) + eFuse_Addr - 1), efuseExtHdr);
858                                 if (ALL_WORDS_DISABLED(efuseExtHdr))
859                                         continue;
860
861                                 offset |= ((efuseExtHdr & 0xF0) >> 1);
862                                 wden = (efuseExtHdr & 0x0F);
863                         } else {
864                                 offset = ((efuseHeader >> 4) & 0x0f);
865                                 wden = (efuseHeader & 0x0f);
866                         }
867
868                         if (offset < EFUSE_BT_MAX_SECTION) {
869                                 u16 addr;
870
871                                 /* Get word enable value from PG header */
872                                 RTW_INFO("%s: Offset=%d Worden=%#X\n", __FUNCTION__, offset, wden);
873
874                                 addr = offset * PGPKT_DATA_SIZE;
875                                 for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
876                                         /* Check word enable condition in the section */
877                                         if (!(wden & (0x01 << i))) {
878                                                 efuseData = 0;
879                                                 /* ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest); */
880                                                 efuseData = phyefuse[eFuse_Addr++];
881
882                                                 RTW_INFO("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr - 1, efuseData);
883                                                 efuseTbl[addr] = efuseData;
884
885                                                 efuseData = 0;
886                                                 /* ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest); */
887                                                 efuseData = phyefuse[eFuse_Addr++];
888
889                                                 RTW_INFO("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr - 1, efuseData);
890                                                 efuseTbl[addr + 1] = efuseData;
891                                         }
892                                         addr += 2;
893                                 }
894                         } else {
895                                 RTW_INFO("%s: offset(%d) is illegal!!\n", __FUNCTION__, offset);
896                                 eFuse_Addr += Efuse_CalculateWordCnts(wden) * 2;
897                         }
898                 }
899
900                 if ((eFuse_Addr - 1) < total) {
901                         RTW_INFO("%s: bank(%d) data end at %#x\n", __FUNCTION__, bank, eFuse_Addr - 1);
902                         break;
903                 }
904         }
905
906         /* switch bank back to bank 0 for later BT and wifi use. */
907         //hal_EfuseSwitchToBank(padapter, 0, bPseudoTest);
908
909         /* Copy from Efuse map to output pointer memory!!! */
910         for (i = 0; i < _size_byte; i++)
911                 pbuf[i] = efuseTbl[_offset + i];
912         /* Calculate Efuse utilization */
913         total = EFUSE_BT_REAL_BANK_CONTENT_LEN;
914
915         used = eFuse_Addr - 1;
916
917         if (total)
918                 efuse_usage = (u8)((used * 100) / total);
919         else
920                 efuse_usage = 100;
921
922         fakeBTEfuseUsedBytes = used;
923         RTW_INFO("%s: BTEfuseUsed last Bytes = %#x\n", __FUNCTION__, fakeBTEfuseUsedBytes);
924
925 exit:
926         if (efuseTbl)
927                 rtw_mfree(efuseTbl, EFUSE_BT_MAP_LEN);
928         if (phyefuse)
929                 rtw_mfree(phyefuse, EFUSE_BT_REAL_BANK_CONTENT_LEN);
930 }
931
932
933 static u8 hal_EfusePartialWriteCheck(
934         PADAPTER                padapter,
935         u8                              efuseType,
936         u16                             *pAddr,
937         PPGPKT_STRUCT   pTargetPkt,
938         u8                              bPseudoTest)
939 {
940         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(padapter);
941         PEFUSE_HAL              pEfuseHal = &pHalData->EfuseHal;
942         u8      bRet = _FALSE;
943         u16     startAddr = 0, efuse_max_available_len = EFUSE_BT_REAL_BANK_CONTENT_LEN, efuse_max = EFUSE_BT_REAL_BANK_CONTENT_LEN;
944         u8      efuse_data = 0;
945
946         startAddr = (u16)fakeBTEfuseUsedBytes;
947
948         startAddr %= efuse_max;
949         RTW_INFO("%s: startAddr=%#X\n", __FUNCTION__, startAddr);
950
951         while (1) {
952                 if (startAddr >= efuse_max_available_len) {
953                         bRet = _FALSE;
954                         RTW_INFO("%s: startAddr(%d) >= efuse_max_available_len(%d)\n",
955                                 __FUNCTION__, startAddr, efuse_max_available_len);
956                         break;
957                 }
958                 if (rtw_efuse_bt_access(padapter, _FALSE, startAddr, 1, &efuse_data)&& (efuse_data != 0xFF)) {
959                         bRet = _FALSE;
960                         RTW_INFO("%s: Something Wrong! last bytes(%#X=0x%02X) is not 0xFF\n",
961                                  __FUNCTION__, startAddr, efuse_data);
962                         break;
963                 } else {
964                         /* not used header, 0xff */
965                         *pAddr = startAddr;
966                         /*                      RTW_INFO("%s: Started from unused header offset=%d\n", __FUNCTION__, startAddr)); */
967                         bRet = _TRUE;
968                         break;
969                 }
970         }
971
972         return bRet;
973 }
974
975
976 static u8 hal_EfusePgPacketWrite2ByteHeader(
977         PADAPTER                padapter,
978         u8                              efuseType,
979         u16                             *pAddr,
980         PPGPKT_STRUCT   pTargetPkt,
981         u8                              bPseudoTest)
982 {
983         u16     efuse_addr, efuse_max_available_len = EFUSE_BT_REAL_BANK_CONTENT_LEN;
984         u8      pg_header = 0, tmp_header = 0;
985         u8      repeatcnt = 0;
986
987         /*      RTW_INFO("%s\n", __FUNCTION__); */
988
989         efuse_addr = *pAddr;
990         if (efuse_addr >= efuse_max_available_len) {
991                 RTW_INFO("%s: addr(%d) over avaliable(%d)!!\n", __FUNCTION__, efuse_addr, efuse_max_available_len);
992                 return _FALSE;
993         }
994
995         pg_header = ((pTargetPkt->offset & 0x07) << 5) | 0x0F;
996         /*      RTW_INFO("%s: pg_header=0x%x\n", __FUNCTION__, pg_header); */
997
998         do {
999                 
1000                 rtw_efuse_bt_access(padapter, _TRUE, efuse_addr, 1, &pg_header);
1001                 rtw_efuse_bt_access(padapter, _FALSE, efuse_addr, 1, &tmp_header);
1002
1003                 if (tmp_header != 0xFF)
1004                         break;
1005                 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {
1006                         RTW_INFO("%s: Repeat over limit for pg_header!!\n", __FUNCTION__);
1007                         return _FALSE;
1008                 }
1009         } while (1);
1010
1011         if (tmp_header != pg_header) {
1012                 RTW_ERR("%s: PG Header Fail!!(pg=0x%02X read=0x%02X)\n", __FUNCTION__, pg_header, tmp_header);
1013                 return _FALSE;
1014         }
1015
1016         /* to write ext_header */
1017         efuse_addr++;
1018         pg_header = ((pTargetPkt->offset & 0x78) << 1) | pTargetPkt->word_en;
1019
1020         do {
1021                 rtw_efuse_bt_access(padapter, _TRUE, efuse_addr, 1, &pg_header);
1022                 rtw_efuse_bt_access(padapter, _FALSE, efuse_addr, 1, &tmp_header);
1023
1024                 if (tmp_header != 0xFF)
1025                         break;
1026                 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {
1027                         RTW_INFO("%s: Repeat over limit for ext_header!!\n", __FUNCTION__);
1028                         return _FALSE;
1029                 }
1030         } while (1);
1031
1032         if (tmp_header != pg_header) {  /* offset PG fail */
1033                 RTW_ERR("%s: PG EXT Header Fail!!(pg=0x%02X read=0x%02X)\n", __FUNCTION__, pg_header, tmp_header);
1034                 return _FALSE;
1035         }
1036
1037         *pAddr = efuse_addr;
1038
1039         return _TRUE;
1040 }
1041
1042
1043 static u8 hal_EfusePgPacketWrite1ByteHeader(
1044         PADAPTER                pAdapter,
1045         u8                              efuseType,
1046         u16                             *pAddr,
1047         PPGPKT_STRUCT   pTargetPkt,
1048         u8                              bPseudoTest)
1049 {
1050         u8      bRet = _FALSE;
1051         u8      pg_header = 0, tmp_header = 0;
1052         u16     efuse_addr = *pAddr;
1053         u8      repeatcnt = 0;
1054
1055
1056         /*      RTW_INFO("%s\n", __FUNCTION__); */
1057         pg_header = ((pTargetPkt->offset << 4) & 0xf0) | pTargetPkt->word_en;
1058
1059         do {
1060                 rtw_efuse_bt_access(pAdapter, _TRUE, efuse_addr, 1, &pg_header);
1061                 rtw_efuse_bt_access(pAdapter, _FALSE, efuse_addr, 1, &tmp_header);
1062
1063                 if (tmp_header != 0xFF)
1064                         break;
1065                 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {
1066                         RTW_INFO("%s: Repeat over limit for pg_header!!\n", __FUNCTION__);
1067                         return _FALSE;
1068                 }
1069         } while (1);
1070
1071         if (tmp_header != pg_header) {
1072                 RTW_ERR("%s: PG Header Fail!!(pg=0x%02X read=0x%02X)\n", __FUNCTION__, pg_header, tmp_header);
1073                 return _FALSE;
1074         }
1075
1076         *pAddr = efuse_addr;
1077
1078         return _TRUE;
1079 }
1080
1081 static u8 hal_EfusePgPacketWriteHeader(
1082         PADAPTER                padapter,
1083         u8                              efuseType,
1084         u16                             *pAddr,
1085         PPGPKT_STRUCT   pTargetPkt,
1086         u8                              bPseudoTest)
1087 {
1088         u8 bRet = _FALSE;
1089
1090         if (pTargetPkt->offset >= EFUSE_MAX_SECTION_BASE)
1091                 bRet = hal_EfusePgPacketWrite2ByteHeader(padapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
1092         else
1093                 bRet = hal_EfusePgPacketWrite1ByteHeader(padapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
1094
1095         return bRet;
1096 }
1097
1098
1099 static u8
1100 Hal_EfuseWordEnableDataWrite(
1101         PADAPTER        padapter,
1102         u16                     efuse_addr,
1103         u8                      word_en,
1104         u8                      *data,
1105         u8                      bPseudoTest)
1106 {
1107         u16     tmpaddr = 0;
1108         u16     start_addr = efuse_addr;
1109         u8      badworden = 0x0F;
1110         u8      tmpdata[PGPKT_DATA_SIZE];
1111
1112
1113         /*      RTW_INFO("%s: efuse_addr=%#x word_en=%#x\n", __FUNCTION__, efuse_addr, word_en); */
1114         _rtw_memset(tmpdata, 0xFF, PGPKT_DATA_SIZE);
1115
1116         if (!(word_en & BIT(0))) {
1117                 tmpaddr = start_addr;
1118                 rtw_efuse_bt_access(padapter, _TRUE, start_addr++, 1, &data[0]);
1119                 rtw_efuse_bt_access(padapter, _TRUE, start_addr++, 1, &data[1]);
1120                 rtw_efuse_bt_access(padapter, _FALSE, tmpaddr, 1, &tmpdata[0]);
1121                 rtw_efuse_bt_access(padapter, _FALSE, tmpaddr + 1, 1, &tmpdata[1]);
1122                 if ((data[0] != tmpdata[0]) || (data[1] != tmpdata[1]))
1123                         badworden &= (~BIT(0));
1124         }
1125         if (!(word_en & BIT(1))) {
1126                 tmpaddr = start_addr;
1127                 rtw_efuse_bt_access(padapter, _TRUE, start_addr++, 1, &data[2]);
1128                 rtw_efuse_bt_access(padapter, _TRUE, start_addr++, 1, &data[3]);
1129                 rtw_efuse_bt_access(padapter, _FALSE, tmpaddr, 1, &tmpdata[2]);
1130                 rtw_efuse_bt_access(padapter, _FALSE, tmpaddr + 1, 1, &tmpdata[3]);
1131                 if ((data[2] != tmpdata[2]) || (data[3] != tmpdata[3]))
1132                         badworden &= (~BIT(1));
1133         }
1134         if (!(word_en & BIT(2))) {
1135                 tmpaddr = start_addr;
1136                 rtw_efuse_bt_access(padapter, _TRUE, start_addr++, 1, &data[4]);
1137                 rtw_efuse_bt_access(padapter, _TRUE, start_addr++, 1, &data[5]);
1138                 rtw_efuse_bt_access(padapter, _FALSE, tmpaddr, 1, &tmpdata[4]);
1139                 rtw_efuse_bt_access(padapter, _FALSE, tmpaddr + 1, 1, &tmpdata[5]);
1140                 if ((data[4] != tmpdata[4]) || (data[5] != tmpdata[5]))
1141                         badworden &= (~BIT(2));
1142         }
1143         if (!(word_en & BIT(3))) {
1144                 tmpaddr = start_addr;
1145                 rtw_efuse_bt_access(padapter, _TRUE, start_addr++, 1, &data[6]);
1146                 rtw_efuse_bt_access(padapter, _TRUE, start_addr++, 1, &data[7]);
1147                 rtw_efuse_bt_access(padapter, _FALSE, tmpaddr, 1, &tmpdata[6]);
1148                 rtw_efuse_bt_access(padapter, _FALSE, tmpaddr + 1, 1, &tmpdata[7]);
1149
1150                 if ((data[6] != tmpdata[6]) || (data[7] != tmpdata[7]))
1151                         badworden &= (~BIT(3));
1152         }
1153
1154         return badworden;
1155 }
1156
1157 static void
1158 hal_EfuseConstructPGPkt(
1159         u8                              offset,
1160         u8                              word_en,
1161         u8                              *pData,
1162         PPGPKT_STRUCT   pTargetPkt)
1163 {
1164         _rtw_memset(pTargetPkt->data, 0xFF, PGPKT_DATA_SIZE);
1165         pTargetPkt->offset = offset;
1166         pTargetPkt->word_en = word_en;
1167         efuse_WordEnableDataRead(word_en, pData, pTargetPkt->data);
1168         pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
1169 }
1170
1171 static u8
1172 hal_EfusePgPacketWriteData(
1173         PADAPTER                pAdapter,
1174         u8                              efuseType,
1175         u16                             *pAddr,
1176         PPGPKT_STRUCT   pTargetPkt,
1177         u8                              bPseudoTest)
1178 {
1179         u16     efuse_addr;
1180         u8      badworden;
1181
1182         efuse_addr = *pAddr;
1183         badworden = Hal_EfuseWordEnableDataWrite(pAdapter, efuse_addr + 1, pTargetPkt->word_en, pTargetPkt->data, bPseudoTest);
1184         if (badworden != 0x0F) {
1185                 RTW_INFO("%s: Fail!!\n", __FUNCTION__);
1186                 return _FALSE;
1187         } else
1188                 RTW_INFO("%s: OK!!\n", __FUNCTION__);
1189
1190         return _TRUE;
1191 }
1192
1193 /* ***********************************************************
1194  *                              Efuse related code
1195  * *********************************************************** */
1196 static u8
1197 hal_EfuseSwitchToBank(
1198         PADAPTER        padapter,
1199         u8                      bank,
1200         u8                      bPseudoTest)
1201 {
1202         u8 bRet = _FALSE;
1203         u32 value32 = 0;
1204 #ifdef HAL_EFUSE_MEMORY
1205         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1206         PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
1207 #endif
1208
1209
1210         RTW_INFO("%s: Efuse switch bank to %d\n", __FUNCTION__, bank);
1211         if (bPseudoTest) {
1212 #ifdef HAL_EFUSE_MEMORY
1213                 pEfuseHal->fakeEfuseBank = bank;
1214 #else
1215                 fakeEfuseBank = bank;
1216 #endif
1217                 bRet = _TRUE;
1218         } else {
1219                 value32 = rtw_read32(padapter, 0x34);
1220                 bRet = _TRUE;
1221                 switch (bank) {
1222                 case 0:
1223                         value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
1224                         break;
1225                 case 1:
1226                         value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_0);
1227                         break;
1228                 case 2:
1229                         value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_1);
1230                         break;
1231                 case 3:
1232                         value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_2);
1233                         break;
1234                 default:
1235                         value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
1236                         bRet = _FALSE;
1237                         break;
1238                 }
1239                 rtw_write32(padapter, 0x34, value32);
1240         }
1241
1242         return bRet;
1243 }
1244
1245
1246 #define EFUSE_CTRL                              0x30            /* E-Fuse Control. */
1247
1248 /*  11/16/2008 MH Read one byte from real Efuse. */
1249 u8
1250 efuse_OneByteRead(
1251         IN      PADAPTER        pAdapter,
1252         IN      u16                     addr,
1253         IN      u8                      *data,
1254         IN      BOOLEAN         bPseudoTest)
1255 {
1256         u32     tmpidx = 0;
1257         u8      bResult;
1258         u8      readbyte;
1259         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(pAdapter);
1260
1261         if (IS_HARDWARE_TYPE_8723B(pAdapter) ||
1262             (IS_HARDWARE_TYPE_8192E(pAdapter) && (!IS_A_CUT(pHalData->version_id))) ||
1263             (IS_VENDOR_8188E_I_CUT_SERIES(pAdapter)) || (IS_CHIP_VENDOR_SMIC(pHalData->version_id))
1264            ) {
1265                 /* <20130121, Kordan> For SMIC EFUSE specificatoin. */
1266                 /* 0x34[11]: SW force PGMEN input of efuse to high. (for the bank selected by 0x34[9:8])         */
1267                 /* phy_set_mac_reg(pAdapter, 0x34, BIT11, 0); */
1268                 rtw_write16(pAdapter, 0x34, rtw_read16(pAdapter, 0x34) & (~BIT11));
1269         }
1270
1271         /* -----------------e-fuse reg ctrl --------------------------------- */
1272         /* address                       */
1273         rtw_write8(pAdapter, EFUSE_CTRL + 1, (u8)(addr & 0xff));
1274         rtw_write8(pAdapter, EFUSE_CTRL + 2, ((u8)((addr >> 8) & 0x03)) |
1275                    (rtw_read8(pAdapter, EFUSE_CTRL + 2) & 0xFC));
1276
1277         /* rtw_write8(pAdapter, EFUSE_CTRL+3,  0x72); */ /* read cmd     */
1278         /* Write bit 32 0 */
1279         readbyte = rtw_read8(pAdapter, EFUSE_CTRL + 3);
1280         rtw_write8(pAdapter, EFUSE_CTRL + 3, (readbyte & 0x7f));
1281
1282         while (!(0x80 & rtw_read8(pAdapter, EFUSE_CTRL + 3)) && (tmpidx < 1000)) {
1283                 rtw_mdelay_os(1);
1284                 tmpidx++;
1285         }
1286         if (tmpidx < 100) {
1287                 *data = rtw_read8(pAdapter, EFUSE_CTRL);
1288                 bResult = _TRUE;
1289         } else {
1290                 *data = 0xff;
1291                 bResult = _FALSE;
1292                 RTW_INFO("%s: [ERROR] addr=0x%x bResult=%d time out 1s !!!\n", __FUNCTION__, addr, bResult);
1293                 RTW_INFO("%s: [ERROR] EFUSE_CTRL =0x%08x !!!\n", __FUNCTION__, rtw_read32(pAdapter, EFUSE_CTRL));
1294         }
1295
1296         return bResult;
1297 }
1298
1299
1300 static u16
1301 hal_EfuseGetCurrentSize_BT(
1302         PADAPTER        padapter,
1303         u8                      bPseudoTest)
1304 {
1305 #ifdef HAL_EFUSE_MEMORY
1306         PHAL_DATA_TYPE  pHalData = GET_HAL_DATA(padapter);
1307         PEFUSE_HAL              pEfuseHal = &pHalData->EfuseHal;
1308 #endif
1309         u16 btusedbytes;
1310         u16     efuse_addr;
1311         u8      bank, startBank;
1312         u8      hoffset = 0, hworden = 0;
1313         u8      efuse_data, word_cnts = 0;
1314         u16     retU2 = 0;
1315         u8 bContinual = _TRUE;
1316
1317
1318         btusedbytes = fakeBTEfuseUsedBytes;
1319
1320         efuse_addr = (u16)((btusedbytes % EFUSE_BT_REAL_BANK_CONTENT_LEN));
1321         startBank = (u8)(1 + (btusedbytes / EFUSE_BT_REAL_BANK_CONTENT_LEN));
1322
1323         RTW_INFO("%s: start from bank=%d addr=0x%X\n", __FUNCTION__, startBank, efuse_addr);
1324         retU2 = EFUSE_BT_REAL_CONTENT_LEN - EFUSE_PROTECT_BYTES_BANK;
1325
1326         for (bank = startBank; bank < 3; bank++) {
1327                 if (hal_EfuseSwitchToBank(padapter, bank, bPseudoTest) == _FALSE) {
1328                         RTW_ERR("%s: switch bank(%d) Fail!!\n", __FUNCTION__, bank);
1329                         /* bank = EFUSE_MAX_BANK; */
1330                         break;
1331                 }
1332
1333                 /* only when bank is switched we have to reset the efuse_addr. */
1334                 if (bank != startBank)
1335                         efuse_addr = 0;
1336
1337
1338                 while (AVAILABLE_EFUSE_ADDR(efuse_addr)) {
1339                         if (rtw_efuse_bt_access(padapter, _FALSE, efuse_addr, 1, &efuse_data) == _FALSE) {
1340                                 RTW_ERR("%s: efuse_OneByteRead Fail! addr=0x%X !!\n", __FUNCTION__, efuse_addr);
1341                                 /* bank = EFUSE_MAX_BANK; */
1342                                 break;
1343                         }
1344                         RTW_INFO("%s: efuse_OneByteRead ! addr=0x%X !efuse_data=0x%X! bank =%d\n", __FUNCTION__, efuse_addr, efuse_data, bank);
1345
1346                         if (efuse_data == 0xFF)
1347                                 break;
1348
1349                         if (EXT_HEADER(efuse_data)) {
1350                                 hoffset = GET_HDR_OFFSET_2_0(efuse_data);
1351                                 efuse_addr++;
1352                                 rtw_efuse_bt_access(padapter, _FALSE, efuse_addr, 1, &efuse_data);
1353                                 RTW_INFO("%s: efuse_OneByteRead EXT_HEADER ! addr=0x%X !efuse_data=0x%X! bank =%d\n", __FUNCTION__, efuse_addr, efuse_data, bank);
1354
1355                                 if (ALL_WORDS_DISABLED(efuse_data)) {
1356                                         efuse_addr++;
1357                                         continue;
1358                                 }
1359
1360                                 /*                              hoffset = ((hoffset & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1); */
1361                                 hoffset |= ((efuse_data & 0xF0) >> 1);
1362                                 hworden = efuse_data & 0x0F;
1363                         } else {
1364                                 hoffset = (efuse_data >> 4) & 0x0F;
1365                                 hworden =  efuse_data & 0x0F;
1366                         }
1367
1368                         RTW_INFO(FUNC_ADPT_FMT": Offset=%d Worden=%#X\n",
1369                                  FUNC_ADPT_ARG(padapter), hoffset, hworden);
1370
1371                         word_cnts = Efuse_CalculateWordCnts(hworden);
1372                         /* read next header */
1373                         efuse_addr += (word_cnts * 2) + 1;
1374                 }
1375                 /* Check if we need to check next bank efuse */
1376                 if (efuse_addr < retU2)
1377                         break;/* don't need to check next bank. */
1378         }
1379         retU2 = ((bank - 1) * EFUSE_BT_REAL_BANK_CONTENT_LEN) + efuse_addr;
1380
1381         fakeBTEfuseUsedBytes = retU2;
1382         RTW_INFO("%s: CurrentSize=%d\n", __FUNCTION__, retU2);
1383         return retU2;
1384 }
1385
1386
1387 static u8
1388 hal_BT_EfusePgCheckAvailableAddr(
1389         PADAPTER        pAdapter,
1390         u8              bPseudoTest)
1391 {
1392         u16     max_available = EFUSE_BT_REAL_CONTENT_LEN - EFUSE_PROTECT_BYTES_BANK;
1393         u16     current_size = 0;
1394
1395          RTW_INFO("%s: max_available=%d\n", __FUNCTION__, max_available);
1396         current_size = hal_EfuseGetCurrentSize_BT(pAdapter, bPseudoTest);
1397         if (current_size >= max_available) {
1398                 RTW_INFO("%s: Error!! current_size(%d)>max_available(%d)\n", __FUNCTION__, current_size, max_available);
1399                 return _FALSE;
1400         }
1401         return _TRUE;
1402 }
1403
1404 u8 EfusePgPacketWrite_BT(
1405         PADAPTER        pAdapter,
1406         u8                      offset,
1407         u8                      word_en,
1408         u8                      *pData,
1409         u8                      bPseudoTest)
1410 {
1411         PGPKT_STRUCT targetPkt;
1412         u16 startAddr = 0;
1413         u8 efuseType = EFUSE_BT;
1414
1415         if (!hal_BT_EfusePgCheckAvailableAddr(pAdapter, bPseudoTest))
1416                 return _FALSE;
1417
1418         hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);
1419
1420         if (!hal_EfusePartialWriteCheck(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
1421                 return _FALSE;
1422
1423         if (!hal_EfusePgPacketWriteHeader(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
1424                 return _FALSE;
1425
1426         if (!hal_EfusePgPacketWriteData(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
1427                 return _FALSE;
1428
1429         return _TRUE;
1430 }
1431
1432
1433 #else /* !RTW_HALMAC */
1434 /* ------------------------------------------------------------------------------ */
1435 #define REG_EFUSE_CTRL          0x0030
1436 #define EFUSE_CTRL                      REG_EFUSE_CTRL          /* E-Fuse Control. */
1437 /* ------------------------------------------------------------------------------ */
1438
1439 VOID efuse_PreUpdateAction(
1440         PADAPTER        pAdapter,
1441         pu4Byte BackupRegs)
1442 {
1443 #if defined(CONFIG_RTL8812A)
1444         if (IS_HARDWARE_TYPE_8812AU(pAdapter)) {
1445                 /* <20131115, Kordan> Turn off Rx to prevent from being busy when writing the EFUSE. (Asked by Chunchu.)*/
1446                 BackupRegs[0] = phy_query_mac_reg(pAdapter, REG_RCR, bMaskDWord);
1447                 BackupRegs[1] = phy_query_mac_reg(pAdapter, REG_RXFLTMAP0, bMaskDWord);
1448                 BackupRegs[2] = phy_query_mac_reg(pAdapter, REG_RXFLTMAP0+4, bMaskDWord);
1449                 BackupRegs[3] = phy_query_mac_reg(pAdapter, REG_AFE_MISC, bMaskDWord);
1450
1451                 PlatformEFIOWrite4Byte(pAdapter, REG_RCR, 0x1);
1452                 PlatformEFIOWrite1Byte(pAdapter, REG_RXFLTMAP0, 0);
1453                 PlatformEFIOWrite1Byte(pAdapter, REG_RXFLTMAP0+1, 0);
1454                 PlatformEFIOWrite1Byte(pAdapter, REG_RXFLTMAP0+2, 0);
1455                 PlatformEFIOWrite1Byte(pAdapter, REG_RXFLTMAP0+3, 0);
1456                 PlatformEFIOWrite1Byte(pAdapter, REG_RXFLTMAP0+4, 0);
1457                 PlatformEFIOWrite1Byte(pAdapter, REG_RXFLTMAP0+5, 0);
1458
1459                 /* <20140410, Kordan> 0x11 = 0x4E, lower down LX_SPS0 voltage. (Asked by Chunchu)*/
1460                 phy_set_mac_reg(pAdapter, REG_AFE_MISC, bMaskByte1, 0x4E);
1461                 }
1462 #endif
1463 }
1464
1465 VOID efuse_PostUpdateAction(
1466         PADAPTER        pAdapter,
1467         pu4Byte BackupRegs)
1468 {
1469 #if defined(CONFIG_RTL8812A)
1470         if (IS_HARDWARE_TYPE_8812AU(pAdapter)) {
1471                 /* <20131115, Kordan> Turn on Rx and restore the registers. (Asked by Chunchu.)*/
1472                 phy_set_mac_reg(pAdapter, REG_RCR, bMaskDWord, BackupRegs[0]);
1473                 phy_set_mac_reg(pAdapter, REG_RXFLTMAP0, bMaskDWord, BackupRegs[1]);
1474                 phy_set_mac_reg(pAdapter, REG_RXFLTMAP0+4, bMaskDWord, BackupRegs[2]);
1475                 phy_set_mac_reg(pAdapter, REG_AFE_MISC, bMaskDWord, BackupRegs[3]);
1476         }
1477 #endif
1478 }
1479
1480
1481 BOOLEAN
1482 Efuse_Read1ByteFromFakeContent(
1483         IN              PADAPTER        pAdapter,
1484         IN              u16             Offset,
1485         IN OUT  u8              *Value);
1486 BOOLEAN
1487 Efuse_Read1ByteFromFakeContent(
1488         IN              PADAPTER        pAdapter,
1489         IN              u16             Offset,
1490         IN OUT  u8              *Value)
1491 {
1492         if (Offset >= EFUSE_MAX_HW_SIZE)
1493                 return _FALSE;
1494         /* DbgPrint("Read fake content, offset = %d\n", Offset); */
1495         if (fakeEfuseBank == 0)
1496                 *Value = fakeEfuseContent[Offset];
1497         else
1498                 *Value = fakeBTEfuseContent[fakeEfuseBank - 1][Offset];
1499         return _TRUE;
1500 }
1501
1502 BOOLEAN
1503 Efuse_Write1ByteToFakeContent(
1504         IN              PADAPTER        pAdapter,
1505         IN              u16             Offset,
1506         IN              u8              Value);
1507 BOOLEAN
1508 Efuse_Write1ByteToFakeContent(
1509         IN              PADAPTER        pAdapter,
1510         IN              u16             Offset,
1511         IN              u8              Value)
1512 {
1513         if (Offset >= EFUSE_MAX_HW_SIZE)
1514                 return _FALSE;
1515         if (fakeEfuseBank == 0)
1516                 fakeEfuseContent[Offset] = Value;
1517         else
1518                 fakeBTEfuseContent[fakeEfuseBank - 1][Offset] = Value;
1519         return _TRUE;
1520 }
1521
1522 /*-----------------------------------------------------------------------------
1523  * Function:    Efuse_PowerSwitch
1524  *
1525  * Overview:    When we want to enable write operation, we should change to
1526  *                              pwr on state. When we stop write, we should switch to 500k mode
1527  *                              and disable LDO 2.5V.
1528  *
1529  * Input:       NONE
1530  *
1531  * Output:      NONE
1532  *
1533  * Return:      NONE
1534  *
1535  * Revised History:
1536  * When                 Who             Remark
1537  * 11/17/2008   MHC             Create Version 0.
1538  *
1539  *---------------------------------------------------------------------------*/
1540 VOID
1541 Efuse_PowerSwitch(
1542         IN      PADAPTER        pAdapter,
1543         IN      u8              bWrite,
1544         IN      u8              PwrState)
1545 {
1546         pAdapter->hal_func.EfusePowerSwitch(pAdapter, bWrite, PwrState);
1547 }
1548
1549 VOID
1550 BTEfuse_PowerSwitch(
1551         IN      PADAPTER        pAdapter,
1552         IN      u8              bWrite,
1553         IN      u8              PwrState)
1554 {
1555         if (pAdapter->hal_func.BTEfusePowerSwitch)
1556                 pAdapter->hal_func.BTEfusePowerSwitch(pAdapter, bWrite, PwrState);
1557 }
1558
1559 /*-----------------------------------------------------------------------------
1560  * Function:    efuse_GetCurrentSize
1561  *
1562  * Overview:    Get current efuse size!!!
1563  *
1564  * Input:       NONE
1565  *
1566  * Output:      NONE
1567  *
1568  * Return:      NONE
1569  *
1570  * Revised History:
1571  * When                 Who             Remark
1572  * 11/16/2008   MHC             Create Version 0.
1573  *
1574  *---------------------------------------------------------------------------*/
1575 u16
1576 Efuse_GetCurrentSize(
1577         IN PADAPTER             pAdapter,
1578         IN u8                   efuseType,
1579         IN BOOLEAN              bPseudoTest)
1580 {
1581         u16 ret = 0;
1582
1583         ret = pAdapter->hal_func.EfuseGetCurrentSize(pAdapter, efuseType, bPseudoTest);
1584
1585         return ret;
1586 }
1587
1588 /*
1589  *      Description:
1590  *              Execute E-Fuse read byte operation.
1591  *              Refered from SD1 Richard.
1592  *
1593  *      Assumption:
1594  *              1. Boot from E-Fuse and successfully auto-load.
1595  *              2. PASSIVE_LEVEL (USB interface)
1596  *
1597  *      Created by Roger, 2008.10.21.
1598  *   */
1599 VOID
1600 ReadEFuseByte(
1601         PADAPTER        Adapter,
1602         u16                     _offset,
1603         u8                      *pbuf,
1604         IN BOOLEAN      bPseudoTest)
1605 {
1606         u32     value32;
1607         u8      readbyte;
1608         u16     retry;
1609         /* u32 start=rtw_get_current_time(); */
1610
1611         if (bPseudoTest) {
1612                 Efuse_Read1ByteFromFakeContent(Adapter, _offset, pbuf);
1613                 return;
1614         }
1615         if (IS_HARDWARE_TYPE_8723B(Adapter)) {
1616                 /* <20130121, Kordan> For SMIC S55 EFUSE specificatoin. */
1617                 /* 0x34[11]: SW force PGMEN input of efuse to high. (for the bank selected by 0x34[9:8]) */
1618                 phy_set_mac_reg(Adapter, EFUSE_TEST, BIT11, 0);
1619         }
1620         /* Write Address */
1621         rtw_write8(Adapter, EFUSE_CTRL + 1, (_offset & 0xff));
1622         readbyte = rtw_read8(Adapter, EFUSE_CTRL + 2);
1623         rtw_write8(Adapter, EFUSE_CTRL + 2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
1624
1625         /* Write bit 32 0 */
1626         readbyte = rtw_read8(Adapter, EFUSE_CTRL + 3);
1627         rtw_write8(Adapter, EFUSE_CTRL + 3, (readbyte & 0x7f));
1628
1629         /* Check bit 32 read-ready */
1630         retry = 0;
1631         value32 = rtw_read32(Adapter, EFUSE_CTRL);
1632         /* while(!(((value32 >> 24) & 0xff) & 0x80)  && (retry<10)) */
1633         while (!(((value32 >> 24) & 0xff) & 0x80)  && (retry < 10000)) {
1634                 value32 = rtw_read32(Adapter, EFUSE_CTRL);
1635                 retry++;
1636         }
1637
1638         /* 20100205 Joseph: Add delay suggested by SD1 Victor. */
1639         /* This fix the problem that Efuse read error in high temperature condition. */
1640         /* Designer says that there shall be some delay after ready bit is set, or the */
1641         /* result will always stay on last data we read. */
1642         rtw_udelay_os(50);
1643         value32 = rtw_read32(Adapter, EFUSE_CTRL);
1644
1645         *pbuf = (u8)(value32 & 0xff);
1646         /* RTW_INFO("ReadEFuseByte _offset:%08u, in %d ms\n",_offset ,rtw_get_passing_time_ms(start)); */
1647
1648 }
1649
1650 /*
1651  *      Description:
1652  *              1. Execute E-Fuse read byte operation according as map offset and
1653  *                  save to E-Fuse table.
1654  *              2. Refered from SD1 Richard.
1655  *
1656  *      Assumption:
1657  *              1. Boot from E-Fuse and successfully auto-load.
1658  *              2. PASSIVE_LEVEL (USB interface)
1659  *
1660  *      Created by Roger, 2008.10.21.
1661  *
1662  *      2008/12/12 MH   1. Reorganize code flow and reserve bytes. and add description.
1663  *                                      2. Add efuse utilization collect.
1664  *      2008/12/22 MH   Read Efuse must check if we write section 1 data again!!! Sec1
1665  *                                      write addr must be after sec5.
1666  *   */
1667
1668 VOID
1669 efuse_ReadEFuse(
1670         PADAPTER        Adapter,
1671         u8              efuseType,
1672         u16             _offset,
1673         u16             _size_byte,
1674         u8      *pbuf,
1675         IN      BOOLEAN bPseudoTest
1676 );
1677 VOID
1678 efuse_ReadEFuse(
1679         PADAPTER        Adapter,
1680         u8              efuseType,
1681         u16             _offset,
1682         u16             _size_byte,
1683         u8      *pbuf,
1684         IN      BOOLEAN bPseudoTest
1685 )
1686 {
1687         Adapter->hal_func.ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
1688 }
1689
1690 VOID
1691 EFUSE_GetEfuseDefinition(
1692         IN              PADAPTER        pAdapter,
1693         IN              u8              efuseType,
1694         IN              u8              type,
1695         OUT             void            *pOut,
1696         IN              BOOLEAN         bPseudoTest
1697 )
1698 {
1699         pAdapter->hal_func.EFUSEGetEfuseDefinition(pAdapter, efuseType, type, pOut, bPseudoTest);
1700 }
1701
1702
1703 /*  11/16/2008 MH Read one byte from real Efuse. */
1704 u8
1705 efuse_OneByteRead(
1706         IN      PADAPTER        pAdapter,
1707         IN      u16                     addr,
1708         IN      u8                      *data,
1709         IN      BOOLEAN         bPseudoTest)
1710 {
1711         u32     tmpidx = 0;
1712         u8      bResult;
1713         u8      readbyte;
1714         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(pAdapter);
1715
1716         /* RTW_INFO("===> EFUSE_OneByteRead(), addr = %x\n", addr); */
1717         /* RTW_INFO("===> EFUSE_OneByteRead() start, 0x34 = 0x%X\n", rtw_read32(pAdapter, EFUSE_TEST)); */
1718
1719         if (bPseudoTest) {
1720                 bResult = Efuse_Read1ByteFromFakeContent(pAdapter, addr, data);
1721                 return bResult;
1722         }
1723
1724         if (IS_HARDWARE_TYPE_8723B(pAdapter) ||
1725             (IS_HARDWARE_TYPE_8192E(pAdapter) && (!IS_A_CUT(pHalData->version_id))) ||
1726             (IS_VENDOR_8188E_I_CUT_SERIES(pAdapter)) || (IS_CHIP_VENDOR_SMIC(pHalData->version_id))
1727            ) {
1728                 /* <20130121, Kordan> For SMIC EFUSE specificatoin. */
1729                 /* 0x34[11]: SW force PGMEN input of efuse to high. (for the bank selected by 0x34[9:8])         */
1730                 /* phy_set_mac_reg(pAdapter, 0x34, BIT11, 0); */
1731                 rtw_write16(pAdapter, 0x34, rtw_read16(pAdapter, 0x34) & (~BIT11));
1732         }
1733
1734         /* -----------------e-fuse reg ctrl --------------------------------- */
1735         /* address                       */
1736         rtw_write8(pAdapter, EFUSE_CTRL + 1, (u8)(addr & 0xff));
1737         rtw_write8(pAdapter, EFUSE_CTRL + 2, ((u8)((addr >> 8) & 0x03)) |
1738                    (rtw_read8(pAdapter, EFUSE_CTRL + 2) & 0xFC));
1739
1740         /* rtw_write8(pAdapter, EFUSE_CTRL+3,  0x72); */ /* read cmd     */
1741         /* Write bit 32 0 */
1742         readbyte = rtw_read8(pAdapter, EFUSE_CTRL + 3);
1743         rtw_write8(pAdapter, EFUSE_CTRL + 3, (readbyte & 0x7f));
1744
1745         while (!(0x80 & rtw_read8(pAdapter, EFUSE_CTRL + 3)) && (tmpidx < 1000)) {
1746                 rtw_mdelay_os(1);
1747                 tmpidx++;
1748         }
1749         if (tmpidx < 100) {
1750                 *data = rtw_read8(pAdapter, EFUSE_CTRL);
1751                 bResult = _TRUE;
1752         } else {
1753                 *data = 0xff;
1754                 bResult = _FALSE;
1755                 RTW_INFO("%s: [ERROR] addr=0x%x bResult=%d time out 1s !!!\n", __FUNCTION__, addr, bResult);
1756                 RTW_INFO("%s: [ERROR] EFUSE_CTRL =0x%08x !!!\n", __FUNCTION__, rtw_read32(pAdapter, EFUSE_CTRL));
1757         }
1758
1759         return bResult;
1760 }
1761
1762 /*  11/16/2008 MH Write one byte to reald Efuse. */
1763 u8
1764 efuse_OneByteWrite(
1765         IN      PADAPTER        pAdapter,
1766         IN      u16                     addr,
1767         IN      u8                      data,
1768         IN      BOOLEAN         bPseudoTest)
1769 {
1770         u8      tmpidx = 0;
1771         u8      bResult = _FALSE;
1772         u32 efuseValue = 0;
1773         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(pAdapter);
1774
1775         /* RTW_INFO("===> EFUSE_OneByteWrite(), addr = %x data=%x\n", addr, data); */
1776         /* RTW_INFO("===> EFUSE_OneByteWrite() start, 0x34 = 0x%X\n", rtw_read32(pAdapter, EFUSE_TEST)); */
1777
1778         if (bPseudoTest) {
1779                 bResult = Efuse_Write1ByteToFakeContent(pAdapter, addr, data);
1780                 return bResult;
1781         }
1782
1783         Efuse_PowerSwitch(pAdapter, _TRUE, _TRUE);
1784
1785         /* -----------------e-fuse reg ctrl ---------------------------------    */
1786         /* address                       */
1787
1788
1789         efuseValue = rtw_read32(pAdapter, EFUSE_CTRL);
1790         efuseValue |= (BIT21 | BIT31);
1791         efuseValue &= ~(0x3FFFF);
1792         efuseValue |= ((addr << 8 | data) & 0x3FFFF);
1793
1794         /* <20130227, Kordan> 8192E MP chip A-cut had better not set 0x34[11] until B-Cut. */
1795         if (IS_HARDWARE_TYPE_8723B(pAdapter) ||
1796             (IS_HARDWARE_TYPE_8192E(pAdapter) && (!IS_A_CUT(pHalData->version_id))) ||
1797             (IS_VENDOR_8188E_I_CUT_SERIES(pAdapter)) || (IS_CHIP_VENDOR_SMIC(pHalData->version_id))
1798            ) {
1799                 /* <20130121, Kordan> For SMIC EFUSE specificatoin. */
1800                 /* 0x34[11]: SW force PGMEN input of efuse to high. (for the bank selected by 0x34[9:8]) */
1801                 /* phy_set_mac_reg(pAdapter, 0x34, BIT11, 1); */
1802                 rtw_write16(pAdapter, 0x34, rtw_read16(pAdapter, 0x34) | (BIT11));
1803                 rtw_write32(pAdapter, EFUSE_CTRL, 0x90600000 | ((addr << 8 | data)));
1804         } else
1805                 rtw_write32(pAdapter, EFUSE_CTRL, efuseValue);
1806
1807         rtw_mdelay_os(1);
1808
1809         while ((0x80 &  rtw_read8(pAdapter, EFUSE_CTRL + 3)) && (tmpidx < 100)) {
1810                 rtw_mdelay_os(1);
1811                 tmpidx++;
1812         }
1813
1814         if (tmpidx < 100)
1815                 bResult = _TRUE;
1816         else {
1817                 bResult = _FALSE;
1818                 RTW_INFO("%s: [ERROR] addr=0x%x ,efuseValue=0x%x ,bResult=%d time out 1s !!!\n",
1819                          __FUNCTION__, addr, efuseValue, bResult);
1820                 RTW_INFO("%s: [ERROR] EFUSE_CTRL =0x%08x !!!\n", __FUNCTION__, rtw_read32(pAdapter, EFUSE_CTRL));
1821         }
1822
1823         /* disable Efuse program enable */
1824         if (IS_HARDWARE_TYPE_8723B(pAdapter) ||
1825             (IS_HARDWARE_TYPE_8192E(pAdapter) && (!IS_A_CUT(pHalData->version_id))) ||
1826             (IS_VENDOR_8188E_I_CUT_SERIES(pAdapter)) || (IS_CHIP_VENDOR_SMIC(pHalData->version_id))
1827            )
1828                 phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT(11), 0);
1829
1830         Efuse_PowerSwitch(pAdapter, _TRUE, _FALSE);
1831
1832         return bResult;
1833 }
1834
1835 int
1836 Efuse_PgPacketRead(IN   PADAPTER        pAdapter,
1837                    IN   u8                      offset,
1838                    IN   u8                      *data,
1839                    IN   BOOLEAN         bPseudoTest)
1840 {
1841         int     ret = 0;
1842
1843         ret =  pAdapter->hal_func.Efuse_PgPacketRead(pAdapter, offset, data, bPseudoTest);
1844
1845         return ret;
1846 }
1847
1848 int
1849 Efuse_PgPacketWrite(IN  PADAPTER        pAdapter,
1850                     IN  u8                      offset,
1851                     IN  u8                      word_en,
1852                     IN  u8                      *data,
1853                     IN  BOOLEAN         bPseudoTest)
1854 {
1855         int ret;
1856
1857         ret =  pAdapter->hal_func.Efuse_PgPacketWrite(pAdapter, offset, word_en, data, bPseudoTest);
1858
1859         return ret;
1860 }
1861
1862
1863 int
1864 Efuse_PgPacketWrite_BT(IN       PADAPTER        pAdapter,
1865                        IN       u8                      offset,
1866                        IN       u8                      word_en,
1867                        IN       u8                      *data,
1868                        IN       BOOLEAN         bPseudoTest)
1869 {
1870         int ret;
1871
1872         ret =  pAdapter->hal_func.Efuse_PgPacketWrite_BT(pAdapter, offset, word_en, data, bPseudoTest);
1873
1874         return ret;
1875 }
1876
1877
1878 u8
1879 Efuse_WordEnableDataWrite(IN    PADAPTER        pAdapter,
1880                           IN    u16             efuse_addr,
1881                           IN    u8              word_en,
1882                           IN    u8              *data,
1883                           IN    BOOLEAN         bPseudoTest)
1884 {
1885         u8      ret = 0;
1886
1887         ret =  pAdapter->hal_func.Efuse_WordEnableDataWrite(pAdapter, efuse_addr, word_en, data, bPseudoTest);
1888
1889         return ret;
1890 }
1891
1892 static u8 efuse_read8(PADAPTER padapter, u16 address, u8 *value)
1893 {
1894         return efuse_OneByteRead(padapter, address, value, _FALSE);
1895 }
1896
1897 static u8 efuse_write8(PADAPTER padapter, u16 address, u8 *value)
1898 {
1899         return efuse_OneByteWrite(padapter, address, *value, _FALSE);
1900 }
1901
1902 /*
1903  * read/wirte raw efuse data
1904  */
1905 u8 rtw_efuse_access(PADAPTER padapter, u8 bWrite, u16 start_addr, u16 cnts, u8 *data)
1906 {
1907         int i = 0;
1908         u16     real_content_len = 0, max_available_size = 0;
1909         u8 res = _FAIL ;
1910         u8(*rw8)(PADAPTER, u16, u8 *);
1911         u32     backupRegs[4] = {0};
1912
1913
1914         EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_REAL_CONTENT_LEN, (PVOID)&real_content_len, _FALSE);
1915         EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);
1916
1917         if (start_addr > real_content_len)
1918                 return _FAIL;
1919
1920         if (_TRUE == bWrite) {
1921                 if ((start_addr + cnts) > max_available_size)
1922                         return _FAIL;
1923                 rw8 = &efuse_write8;
1924         } else
1925                 rw8 = &efuse_read8;
1926
1927         efuse_PreUpdateAction(padapter, backupRegs);
1928
1929         Efuse_PowerSwitch(padapter, bWrite, _TRUE);
1930
1931         /* e-fuse one byte read / write */
1932         for (i = 0; i < cnts; i++) {
1933                 if (start_addr >= real_content_len) {
1934                         res = _FAIL;
1935                         break;
1936                 }
1937
1938                 res = rw8(padapter, start_addr++, data++);
1939                 if (_FAIL == res)
1940                         break;
1941         }
1942
1943         Efuse_PowerSwitch(padapter, bWrite, _FALSE);
1944
1945         efuse_PostUpdateAction(padapter, backupRegs);
1946
1947         return res;
1948 }
1949 /* ------------------------------------------------------------------------------ */
1950 u16 efuse_GetMaxSize(PADAPTER padapter)
1951 {
1952         u16     max_size;
1953
1954         max_size = 0;
1955         EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI , TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_size, _FALSE);
1956         return max_size;
1957 }
1958 /* ------------------------------------------------------------------------------ */
1959 u8 efuse_GetCurrentSize(PADAPTER padapter, u16 *size)
1960 {
1961         Efuse_PowerSwitch(padapter, _FALSE, _TRUE);
1962         *size = Efuse_GetCurrentSize(padapter, EFUSE_WIFI, _FALSE);
1963         Efuse_PowerSwitch(padapter, _FALSE, _FALSE);
1964
1965         return _SUCCESS;
1966 }
1967 /* ------------------------------------------------------------------------------ */
1968 u16 efuse_bt_GetMaxSize(PADAPTER padapter)
1969 {
1970         u16     max_size;
1971
1972         max_size = 0;
1973         EFUSE_GetEfuseDefinition(padapter, EFUSE_BT , TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_size, _FALSE);
1974         return max_size;
1975 }
1976
1977 u8 efuse_bt_GetCurrentSize(PADAPTER padapter, u16 *size)
1978 {
1979         Efuse_PowerSwitch(padapter, _FALSE, _TRUE);
1980         *size = Efuse_GetCurrentSize(padapter, EFUSE_BT, _FALSE);
1981         Efuse_PowerSwitch(padapter, _FALSE, _FALSE);
1982
1983         return _SUCCESS;
1984 }
1985
1986 u8 rtw_efuse_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data)
1987 {
1988         u16     mapLen = 0;
1989
1990         EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&mapLen, _FALSE);
1991
1992         if ((addr + cnts) > mapLen)
1993                 return _FAIL;
1994
1995         Efuse_PowerSwitch(padapter, _FALSE, _TRUE);
1996
1997         efuse_ReadEFuse(padapter, EFUSE_WIFI, addr, cnts, data, _FALSE);
1998
1999         Efuse_PowerSwitch(padapter, _FALSE, _FALSE);
2000
2001         return _SUCCESS;
2002 }
2003
2004 u8 rtw_BT_efuse_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data)
2005 {
2006         u16     mapLen = 0;
2007
2008         EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (PVOID)&mapLen, _FALSE);
2009
2010         if ((addr + cnts) > mapLen)
2011                 return _FAIL;
2012
2013         Efuse_PowerSwitch(padapter, _FALSE, _TRUE);
2014
2015         efuse_ReadEFuse(padapter, EFUSE_BT, addr, cnts, data, _FALSE);
2016
2017         Efuse_PowerSwitch(padapter, _FALSE, _FALSE);
2018
2019         return _SUCCESS;
2020 }
2021
2022 /* ------------------------------------------------------------------------------ */
2023 u8 rtw_efuse_map_write(PADAPTER padapter, u16 addr, u16 cnts, u8 *data)
2024 {
2025 #define RT_ASSERT_RET(expr)                                                                                             \
2026         if (!(expr)) {                                                                                                                  \
2027                 printk("Assertion failed! %s at ......\n", #expr);                                                      \
2028                 printk("      ......%s,%s, line=%d\n",__FILE__, __FUNCTION__, __LINE__);        \
2029                 return _FAIL;   \
2030         }
2031
2032         u8      offset, word_en;
2033         u8      *map;
2034         u8      newdata[PGPKT_DATA_SIZE];
2035         s32     i, j, idx, chk_total_byte;
2036         u8      ret = _SUCCESS;
2037         u16     mapLen = 0, startAddr = 0, efuse_max_available_len = 0;
2038         u32     backupRegs[4] = {0};
2039         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
2040         PEFUSE_HAL      pEfuseHal = &pHalData->EfuseHal;
2041
2042
2043         EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&mapLen, _FALSE);
2044         EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &efuse_max_available_len, _FALSE);
2045
2046         if ((addr + cnts) > mapLen)
2047                 return _FAIL;
2048
2049         RT_ASSERT_RET(PGPKT_DATA_SIZE == 8); /* have to be 8 byte alignment */
2050         RT_ASSERT_RET((mapLen & 0x7) == 0); /* have to be PGPKT_DATA_SIZE alignment for memcpy */
2051
2052         map = rtw_zmalloc(mapLen);
2053         if (map == NULL)
2054                 return _FAIL;
2055
2056         _rtw_memset(map, 0xFF, mapLen);
2057
2058         ret = rtw_efuse_map_read(padapter, 0, mapLen, map);
2059         if (ret == _FAIL)
2060                 goto exit;
2061
2062         if (padapter->registrypriv.boffefusemask == 0) {
2063                 for (i = 0; i < cnts; i++) {
2064                         if (padapter->registrypriv.bFileMaskEfuse == _TRUE) {
2065                                 if (rtw_file_efuse_IsMasked(padapter, addr + i))        /*use file efuse mask. */
2066                                         data[i] = map[addr + i];
2067                         } else {
2068                                 if (efuse_IsMasked(padapter, addr + i))
2069                                         data[i] = map[addr + i];
2070                         }
2071                         RTW_INFO("%s , data[%d] = %x, map[addr+i]= %x\n", __func__, i, data[i], map[addr + i]);
2072                 }
2073         }
2074         /*Efuse_PowerSwitch(padapter, _TRUE, _TRUE);*/
2075
2076         chk_total_byte = 0;
2077         idx = 0;
2078         offset = (addr >> 3);
2079
2080         while (idx < cnts) {
2081                 word_en = 0xF;
2082                 j = (addr + idx) & 0x7;
2083                 for (i = j; i < PGPKT_DATA_SIZE && idx < cnts; i++, idx++) {
2084                         if (data[idx] != map[addr + idx])
2085                                 word_en &= ~BIT(i >> 1);
2086                 }
2087
2088                 if (word_en != 0xF) {
2089                         chk_total_byte += Efuse_CalculateWordCnts(word_en) * 2;
2090
2091                         if (offset >= EFUSE_MAX_SECTION_BASE) /* Over EFUSE_MAX_SECTION 16 for 2 ByteHeader */
2092                                 chk_total_byte += 2;
2093                         else
2094                                 chk_total_byte += 1;
2095                 }
2096
2097                 offset++;
2098         }
2099
2100         RTW_INFO("Total PG bytes Count = %d\n", chk_total_byte);
2101         rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8 *)&startAddr);
2102
2103         if (startAddr == 0) {
2104                 startAddr = Efuse_GetCurrentSize(padapter, EFUSE_WIFI, _FALSE);
2105                 RTW_INFO("%s: Efuse_GetCurrentSize startAddr=%#X\n", __func__, startAddr);
2106         }
2107         RTW_DBG("%s: startAddr=%#X\n", __func__, startAddr);
2108
2109         if ((startAddr + chk_total_byte) >= efuse_max_available_len) {
2110                 RTW_INFO("%s: startAddr(0x%X) + PG data len %d >= efuse_max_available_len(0x%X)\n",
2111                          __func__, startAddr, chk_total_byte, efuse_max_available_len);
2112                 ret = _FAIL;
2113                 goto exit;
2114         }
2115
2116         efuse_PreUpdateAction(padapter, backupRegs);
2117
2118         idx = 0;
2119         offset = (addr >> 3);
2120         while (idx < cnts) {
2121                 word_en = 0xF;
2122                 j = (addr + idx) & 0x7;
2123                 _rtw_memcpy(newdata, &map[offset << 3], PGPKT_DATA_SIZE);
2124                 for (i = j; i < PGPKT_DATA_SIZE && idx < cnts; i++, idx++) {
2125                         if (data[idx] != map[addr + idx]) {
2126                                 word_en &= ~BIT(i >> 1);
2127                                 newdata[i] = data[idx];
2128 #ifdef CONFIG_RTL8723B
2129                                 if (addr + idx == 0x8) {
2130                                         if (IS_C_CUT(pHalData->version_id) || IS_B_CUT(pHalData->version_id)) {
2131                                                 if (pHalData->adjuseVoltageVal == 6) {
2132                                                         newdata[i] = map[addr + idx];
2133                                                         RTW_INFO(" %s ,\n adjuseVoltageVal = %d ,newdata[%d] = %x\n", __func__, pHalData->adjuseVoltageVal, i, newdata[i]);
2134                                                 }
2135                                         }
2136                                 }
2137 #endif
2138                         }
2139                 }
2140
2141                 if (word_en != 0xF) {
2142                         ret = Efuse_PgPacketWrite(padapter, offset, word_en, newdata, _FALSE);
2143                         RTW_INFO("offset=%x\n", offset);
2144                         RTW_INFO("word_en=%x\n", word_en);
2145
2146                         for (i = 0; i < PGPKT_DATA_SIZE; i++)
2147                                 RTW_INFO("data=%x \t", newdata[i]);
2148                         if (ret == _FAIL)
2149                                 break;
2150                 }
2151
2152                 offset++;
2153         }
2154
2155         /*Efuse_PowerSwitch(padapter, _TRUE, _FALSE);*/
2156
2157         efuse_PostUpdateAction(padapter, backupRegs);
2158
2159 exit:
2160
2161         rtw_mfree(map, mapLen);
2162
2163         return ret;
2164 }
2165
2166
2167 u8 rtw_BT_efuse_map_write(PADAPTER padapter, u16 addr, u16 cnts, u8 *data)
2168 {
2169 #define RT_ASSERT_RET(expr)                                                                                             \
2170         if (!(expr)) {                                                                                                                  \
2171                 printk("Assertion failed! %s at ......\n", #expr);                                                      \
2172                 printk("      ......%s,%s, line=%d\n",__FILE__, __FUNCTION__, __LINE__);        \
2173                 return _FAIL;   \
2174         }
2175
2176         u8      offset, word_en;
2177         u8      *map;
2178         u8      newdata[PGPKT_DATA_SIZE];
2179         s32     i = 0, j = 0, idx;
2180         u8      ret = _SUCCESS;
2181         u16     mapLen = 0;
2182
2183         EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (PVOID)&mapLen, _FALSE);
2184
2185         if ((addr + cnts) > mapLen)
2186                 return _FAIL;
2187
2188         RT_ASSERT_RET(PGPKT_DATA_SIZE == 8); /* have to be 8 byte alignment */
2189         RT_ASSERT_RET((mapLen & 0x7) == 0); /* have to be PGPKT_DATA_SIZE alignment for memcpy */
2190
2191         map = rtw_zmalloc(mapLen);
2192         if (map == NULL)
2193                 return _FAIL;
2194
2195         ret = rtw_BT_efuse_map_read(padapter, 0, mapLen, map);
2196         if (ret == _FAIL)
2197                 goto exit;
2198         RTW_INFO("OFFSET\tVALUE(hex)\n");
2199         for (i = 0; i < 1024; i += 16) { /* set 512 because the iwpriv's extra size have limit 0x7FF */
2200                 RTW_INFO("0x%03x\t", i);
2201                 for (j = 0; j < 8; j++)
2202                         RTW_INFO("%02X ", map[i + j]);
2203                 RTW_INFO("\t");
2204                 for (; j < 16; j++)
2205                         RTW_INFO("%02X ", map[i + j]);
2206                 RTW_INFO("\n");
2207         }
2208         RTW_INFO("\n");
2209         Efuse_PowerSwitch(padapter, _TRUE, _TRUE);
2210
2211         idx = 0;
2212         offset = (addr >> 3);
2213         while (idx < cnts) {
2214                 word_en = 0xF;
2215                 j = (addr + idx) & 0x7;
2216                 _rtw_memcpy(newdata, &map[offset << 3], PGPKT_DATA_SIZE);
2217                 for (i = j; i < PGPKT_DATA_SIZE && idx < cnts; i++, idx++) {
2218                         if (data[idx] != map[addr + idx]) {
2219                                 word_en &= ~BIT(i >> 1);
2220                                 newdata[i] = data[idx];
2221                         }
2222                 }
2223
2224                 if (word_en != 0xF) {
2225                         RTW_INFO("offset=%x\n", offset);
2226                         RTW_INFO("word_en=%x\n", word_en);
2227                         RTW_INFO("%s: data=", __FUNCTION__);
2228                         for (i = 0; i < PGPKT_DATA_SIZE; i++)
2229                                 RTW_INFO("0x%02X ", newdata[i]);
2230                         RTW_INFO("\n");
2231                         ret = Efuse_PgPacketWrite_BT(padapter, offset, word_en, newdata, _FALSE);
2232                         if (ret == _FAIL)
2233                                 break;
2234                 }
2235
2236                 offset++;
2237         }
2238
2239         Efuse_PowerSwitch(padapter, _TRUE, _FALSE);
2240
2241 exit:
2242
2243         rtw_mfree(map, mapLen);
2244
2245         return ret;
2246 }
2247
2248 /*-----------------------------------------------------------------------------
2249  * Function:    Efuse_ReadAllMap
2250  *
2251  * Overview:    Read All Efuse content
2252  *
2253  * Input:       NONE
2254  *
2255  * Output:      NONE
2256  *
2257  * Return:      NONE
2258  *
2259  * Revised History:
2260  * When                 Who             Remark
2261  * 11/11/2008   MHC             Create Version 0.
2262  *
2263  *---------------------------------------------------------------------------*/
2264 VOID
2265 Efuse_ReadAllMap(
2266         IN              PADAPTER        pAdapter,
2267         IN              u8              efuseType,
2268         IN OUT  u8              *Efuse,
2269         IN              BOOLEAN         bPseudoTest);
2270 VOID
2271 Efuse_ReadAllMap(
2272         IN              PADAPTER        pAdapter,
2273         IN              u8              efuseType,
2274         IN OUT  u8              *Efuse,
2275         IN              BOOLEAN         bPseudoTest)
2276 {
2277         u16     mapLen = 0;
2278
2279         Efuse_PowerSwitch(pAdapter, _FALSE, _TRUE);
2280
2281         EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (PVOID)&mapLen, bPseudoTest);
2282
2283         efuse_ReadEFuse(pAdapter, efuseType, 0, mapLen, Efuse, bPseudoTest);
2284
2285         Efuse_PowerSwitch(pAdapter, _FALSE, _FALSE);
2286 }
2287
2288 /*-----------------------------------------------------------------------------
2289  * Function:    efuse_ShadowRead1Byte
2290  *                      efuse_ShadowRead2Byte
2291  *                      efuse_ShadowRead4Byte
2292  *
2293  * Overview:    Read from efuse init map by one/two/four bytes !!!!!
2294  *
2295  * Input:       NONE
2296  *
2297  * Output:      NONE
2298  *
2299  * Return:      NONE
2300  *
2301  * Revised History:
2302  * When                 Who             Remark
2303  * 11/12/2008   MHC             Create Version 0.
2304  *
2305  *---------------------------------------------------------------------------*/
2306 static VOID
2307 efuse_ShadowRead1Byte(
2308         IN      PADAPTER        pAdapter,
2309         IN      u16             Offset,
2310         IN OUT  u8              *Value)
2311 {
2312         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);
2313
2314         *Value = pHalData->efuse_eeprom_data[Offset];
2315
2316 }       /* EFUSE_ShadowRead1Byte */
2317
2318 /* ---------------Read Two Bytes */
2319 static VOID
2320 efuse_ShadowRead2Byte(
2321         IN      PADAPTER        pAdapter,
2322         IN      u16             Offset,
2323         IN OUT  u16             *Value)
2324 {
2325         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);
2326
2327         *Value = pHalData->efuse_eeprom_data[Offset];
2328         *Value |= pHalData->efuse_eeprom_data[Offset + 1] << 8;
2329
2330 }       /* EFUSE_ShadowRead2Byte */
2331
2332 /* ---------------Read Four Bytes */
2333 static VOID
2334 efuse_ShadowRead4Byte(
2335         IN      PADAPTER        pAdapter,
2336         IN      u16             Offset,
2337         IN OUT  u32             *Value)
2338 {
2339         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);
2340
2341         *Value = pHalData->efuse_eeprom_data[Offset];
2342         *Value |= pHalData->efuse_eeprom_data[Offset + 1] << 8;
2343         *Value |= pHalData->efuse_eeprom_data[Offset + 2] << 16;
2344         *Value |= pHalData->efuse_eeprom_data[Offset + 3] << 24;
2345
2346 }       /* efuse_ShadowRead4Byte */
2347
2348
2349 /*-----------------------------------------------------------------------------
2350  * Function:    efuse_ShadowWrite1Byte
2351  *                      efuse_ShadowWrite2Byte
2352  *                      efuse_ShadowWrite4Byte
2353  *
2354  * Overview:    Write efuse modify map by one/two/four byte.
2355  *
2356  * Input:       NONE
2357  *
2358  * Output:      NONE
2359  *
2360  * Return:      NONE
2361  *
2362  * Revised History:
2363  * When                 Who             Remark
2364  * 11/12/2008   MHC             Create Version 0.
2365  *
2366  *---------------------------------------------------------------------------*/
2367 #ifdef PLATFORM
2368 static VOID
2369 efuse_ShadowWrite1Byte(
2370         IN      PADAPTER        pAdapter,
2371         IN      u16             Offset,
2372         IN      u8              Value);
2373 #endif /* PLATFORM */
2374 static VOID
2375 efuse_ShadowWrite1Byte(
2376         IN      PADAPTER        pAdapter,
2377         IN      u16             Offset,
2378         IN      u8              Value)
2379 {
2380         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);
2381
2382         pHalData->efuse_eeprom_data[Offset] = Value;
2383
2384 }       /* efuse_ShadowWrite1Byte */
2385
2386 /* ---------------Write Two Bytes */
2387 static VOID
2388 efuse_ShadowWrite2Byte(
2389         IN      PADAPTER        pAdapter,
2390         IN      u16             Offset,
2391         IN      u16             Value)
2392 {
2393
2394         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);
2395
2396
2397         pHalData->efuse_eeprom_data[Offset] = Value & 0x00FF;
2398         pHalData->efuse_eeprom_data[Offset + 1] = Value >> 8;
2399
2400 }       /* efuse_ShadowWrite1Byte */
2401
2402 /* ---------------Write Four Bytes */
2403 static VOID
2404 efuse_ShadowWrite4Byte(
2405         IN      PADAPTER        pAdapter,
2406         IN      u16             Offset,
2407         IN      u32             Value)
2408 {
2409         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);
2410
2411         pHalData->efuse_eeprom_data[Offset] = (u8)(Value & 0x000000FF);
2412         pHalData->efuse_eeprom_data[Offset + 1] = (u8)((Value >> 8) & 0x0000FF);
2413         pHalData->efuse_eeprom_data[Offset + 2] = (u8)((Value >> 16) & 0x00FF);
2414         pHalData->efuse_eeprom_data[Offset + 3] = (u8)((Value >> 24) & 0xFF);
2415
2416 }       /* efuse_ShadowWrite1Byte */
2417
2418
2419 /*-----------------------------------------------------------------------------
2420  * Function:    EFUSE_ShadowRead
2421  *
2422  * Overview:    Read from efuse init map !!!!!
2423  *
2424  * Input:       NONE
2425  *
2426  * Output:      NONE
2427  *
2428  * Return:      NONE
2429  *
2430  * Revised History:
2431  * When                 Who             Remark
2432  * 11/12/2008   MHC             Create Version 0.
2433  *
2434  *---------------------------------------------------------------------------*/
2435 void
2436 EFUSE_ShadowRead(
2437         IN              PADAPTER        pAdapter,
2438         IN              u8              Type,
2439         IN              u16             Offset,
2440         IN OUT  u32             *Value)
2441 {
2442         if (Type == 1)
2443                 efuse_ShadowRead1Byte(pAdapter, Offset, (u8 *)Value);
2444         else if (Type == 2)
2445                 efuse_ShadowRead2Byte(pAdapter, Offset, (u16 *)Value);
2446         else if (Type == 4)
2447                 efuse_ShadowRead4Byte(pAdapter, Offset, (u32 *)Value);
2448
2449 }       /* EFUSE_ShadowRead */
2450
2451 /*-----------------------------------------------------------------------------
2452  * Function:    EFUSE_ShadowWrite
2453  *
2454  * Overview:    Write efuse modify map for later update operation to use!!!!!
2455  *
2456  * Input:       NONE
2457  *
2458  * Output:      NONE
2459  *
2460  * Return:      NONE
2461  *
2462  * Revised History:
2463  * When                 Who             Remark
2464  * 11/12/2008   MHC             Create Version 0.
2465  *
2466  *---------------------------------------------------------------------------*/
2467 VOID
2468 EFUSE_ShadowWrite(
2469         IN      PADAPTER        pAdapter,
2470         IN      u8              Type,
2471         IN      u16             Offset,
2472         IN OUT  u32             Value);
2473 VOID
2474 EFUSE_ShadowWrite(
2475         IN      PADAPTER        pAdapter,
2476         IN      u8              Type,
2477         IN      u16             Offset,
2478         IN OUT  u32             Value)
2479 {
2480 #if (MP_DRIVER == 0)
2481         return;
2482 #endif
2483         if (pAdapter->registrypriv.mp_mode == 0)
2484                 return;
2485
2486
2487         if (Type == 1)
2488                 efuse_ShadowWrite1Byte(pAdapter, Offset, (u8)Value);
2489         else if (Type == 2)
2490                 efuse_ShadowWrite2Byte(pAdapter, Offset, (u16)Value);
2491         else if (Type == 4)
2492                 efuse_ShadowWrite4Byte(pAdapter, Offset, (u32)Value);
2493
2494 }       /* EFUSE_ShadowWrite */
2495
2496 VOID
2497 Efuse_InitSomeVar(
2498         IN              PADAPTER        pAdapter
2499 );
2500 VOID
2501 Efuse_InitSomeVar(
2502         IN              PADAPTER        pAdapter
2503 )
2504 {
2505         u8 i;
2506
2507         _rtw_memset((PVOID)&fakeEfuseContent[0], 0xff, EFUSE_MAX_HW_SIZE);
2508         _rtw_memset((PVOID)&fakeEfuseInitMap[0], 0xff, EFUSE_MAX_MAP_LEN);
2509         _rtw_memset((PVOID)&fakeEfuseModifiedMap[0], 0xff, EFUSE_MAX_MAP_LEN);
2510
2511         for (i = 0; i < EFUSE_MAX_BT_BANK; i++)
2512                 _rtw_memset((PVOID)&BTEfuseContent[i][0], EFUSE_MAX_HW_SIZE, 0xff);
2513         _rtw_memset((PVOID)&BTEfuseInitMap[0], 0xff, EFUSE_BT_MAX_MAP_LEN);
2514         _rtw_memset((PVOID)&BTEfuseModifiedMap[0], 0xff, EFUSE_BT_MAX_MAP_LEN);
2515
2516         for (i = 0; i < EFUSE_MAX_BT_BANK; i++)
2517                 _rtw_memset((PVOID)&fakeBTEfuseContent[i][0], 0xff, EFUSE_MAX_HW_SIZE);
2518         _rtw_memset((PVOID)&fakeBTEfuseInitMap[0], 0xff, EFUSE_BT_MAX_MAP_LEN);
2519         _rtw_memset((PVOID)&fakeBTEfuseModifiedMap[0], 0xff, EFUSE_BT_MAX_MAP_LEN);
2520 }
2521 #endif /* !RTW_HALMAC */
2522 /*  11/16/2008 MH Add description. Get current efuse area enabled word!!. */
2523 u8
2524 Efuse_CalculateWordCnts(IN u8   word_en)
2525 {
2526         u8 word_cnts = 0;
2527         if (!(word_en & BIT(0)))
2528                 word_cnts++; /* 0 : write enable */
2529         if (!(word_en & BIT(1)))
2530                 word_cnts++;
2531         if (!(word_en & BIT(2)))
2532                 word_cnts++;
2533         if (!(word_en & BIT(3)))
2534                 word_cnts++;
2535         return word_cnts;
2536 }
2537
2538 /*-----------------------------------------------------------------------------
2539  * Function:    efuse_WordEnableDataRead
2540  *
2541  * Overview:    Read allowed word in current efuse section data.
2542  *
2543  * Input:       NONE
2544  *
2545  * Output:      NONE
2546  *
2547  * Return:      NONE
2548  *
2549  * Revised History:
2550  * When                 Who             Remark
2551  * 11/16/2008   MHC             Create Version 0.
2552  * 11/21/2008   MHC             Fix Write bug when we only enable late word.
2553  *
2554  *---------------------------------------------------------------------------*/
2555 void
2556 efuse_WordEnableDataRead(IN     u8      word_en,
2557                          IN     u8      *sourdata,
2558                          IN     u8      *targetdata)
2559 {
2560         if (!(word_en & BIT(0))) {
2561                 targetdata[0] = sourdata[0];
2562                 targetdata[1] = sourdata[1];
2563         }
2564         if (!(word_en & BIT(1))) {
2565                 targetdata[2] = sourdata[2];
2566                 targetdata[3] = sourdata[3];
2567         }
2568         if (!(word_en & BIT(2))) {
2569                 targetdata[4] = sourdata[4];
2570                 targetdata[5] = sourdata[5];
2571         }
2572         if (!(word_en & BIT(3))) {
2573                 targetdata[6] = sourdata[6];
2574                 targetdata[7] = sourdata[7];
2575         }
2576 }
2577
2578 /*-----------------------------------------------------------------------------
2579  * Function:    EFUSE_ShadowMapUpdate
2580  *
2581  * Overview:    Transfer current EFUSE content to shadow init and modify map.
2582  *
2583  * Input:       NONE
2584  *
2585  * Output:      NONE
2586  *
2587  * Return:      NONE
2588  *
2589  * Revised History:
2590  * When                 Who             Remark
2591  * 11/13/2008   MHC             Create Version 0.
2592  *
2593  *---------------------------------------------------------------------------*/
2594 void EFUSE_ShadowMapUpdate(
2595         IN PADAPTER     pAdapter,
2596         IN u8           efuseType,
2597         IN BOOLEAN      bPseudoTest)
2598 {
2599         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);
2600         u16     mapLen = 0;
2601 #ifdef RTW_HALMAC
2602         u8 *efuse_map = NULL;
2603         int err;
2604
2605
2606         mapLen = EEPROM_MAX_SIZE;
2607         efuse_map = pHalData->efuse_eeprom_data;
2608         /* efuse default content is 0xFF */
2609         _rtw_memset(efuse_map, 0xFF, EEPROM_MAX_SIZE);
2610
2611         EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (PVOID)&mapLen, bPseudoTest);
2612         if (!mapLen) {
2613                 RTW_WARN("%s: <ERROR> fail to get efuse size!\n", __FUNCTION__);
2614                 mapLen = EEPROM_MAX_SIZE;
2615         }
2616         if (mapLen > EEPROM_MAX_SIZE) {
2617                 RTW_WARN("%s: <ERROR> size of efuse data(%d) is large than expected(%d)!\n",
2618                          __FUNCTION__, mapLen, EEPROM_MAX_SIZE);
2619                 mapLen = EEPROM_MAX_SIZE;
2620         }
2621
2622         if (pHalData->bautoload_fail_flag == _FALSE) {
2623                 err = rtw_halmac_read_logical_efuse_map(adapter_to_dvobj(pAdapter), efuse_map, mapLen);
2624                 if (err)
2625                         RTW_ERR("%s: <ERROR> fail to get efuse map!\n", __FUNCTION__);
2626         }
2627 #else /* !RTW_HALMAC */
2628         EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (PVOID)&mapLen, bPseudoTest);
2629
2630         if (pHalData->bautoload_fail_flag == _TRUE)
2631                 _rtw_memset(pHalData->efuse_eeprom_data, 0xFF, mapLen);
2632         else {
2633 #ifdef CONFIG_ADAPTOR_INFO_CACHING_FILE
2634                 if (_SUCCESS != retriveAdaptorInfoFile(pAdapter->registrypriv.adaptor_info_caching_file_path, pHalData->efuse_eeprom_data)) {
2635 #endif
2636
2637                         Efuse_ReadAllMap(pAdapter, efuseType, pHalData->efuse_eeprom_data, bPseudoTest);
2638
2639 #ifdef CONFIG_ADAPTOR_INFO_CACHING_FILE
2640                         storeAdaptorInfoFile(pAdapter->registrypriv.adaptor_info_caching_file_path, pHalData->efuse_eeprom_data);
2641                 }
2642 #endif
2643         }
2644
2645         /* PlatformMoveMemory((PVOID)&pHalData->EfuseMap[EFUSE_MODIFY_MAP][0], */
2646         /* (PVOID)&pHalData->EfuseMap[EFUSE_INIT_MAP][0], mapLen); */
2647 #endif /* !RTW_HALMAC */
2648
2649         rtw_dump_cur_efuse(pAdapter);
2650 } /* EFUSE_ShadowMapUpdate */
2651
2652 const u8 _mac_hidden_max_bw_to_hal_bw_cap[MAC_HIDDEN_MAX_BW_NUM] = {
2653         0,
2654         0,
2655         (BW_CAP_160M | BW_CAP_80M | BW_CAP_40M | BW_CAP_20M | BW_CAP_10M | BW_CAP_5M),
2656         (BW_CAP_5M),
2657         (BW_CAP_10M | BW_CAP_5M),
2658         (BW_CAP_20M | BW_CAP_10M | BW_CAP_5M),
2659         (BW_CAP_40M | BW_CAP_20M | BW_CAP_10M | BW_CAP_5M),
2660         (BW_CAP_80M | BW_CAP_40M | BW_CAP_20M | BW_CAP_10M | BW_CAP_5M),
2661 };
2662
2663 const u8 _mac_hidden_proto_to_hal_proto_cap[MAC_HIDDEN_PROTOCOL_NUM] = {
2664         0,
2665         0,
2666         (PROTO_CAP_11N | PROTO_CAP_11G | PROTO_CAP_11B),
2667         (PROTO_CAP_11AC | PROTO_CAP_11N | PROTO_CAP_11G | PROTO_CAP_11B),
2668 };
2669
2670 u8 mac_hidden_wl_func_to_hal_wl_func(u8 func)
2671 {
2672         u8 wl_func = 0;
2673
2674         if (func & BIT0)
2675                 wl_func |= WL_FUNC_MIRACAST;
2676         if (func & BIT1)
2677                 wl_func |= WL_FUNC_P2P;
2678         if (func & BIT2)
2679                 wl_func |= WL_FUNC_TDLS;
2680         if (func & BIT3)
2681                 wl_func |= WL_FUNC_FTM;
2682
2683         return wl_func;
2684 }
2685
2686 #ifdef PLATFORM_LINUX
2687 #ifdef CONFIG_ADAPTOR_INFO_CACHING_FILE
2688 /* #include <rtw_eeprom.h> */
2689
2690 int isAdaptorInfoFileValid(void)
2691 {
2692         return _TRUE;
2693 }
2694
2695 int storeAdaptorInfoFile(char *path, u8 *efuse_data)
2696 {
2697         int ret = _SUCCESS;
2698
2699         if (path && efuse_data) {
2700                 ret = rtw_store_to_file(path, efuse_data, EEPROM_MAX_SIZE_512);
2701                 if (ret == EEPROM_MAX_SIZE)
2702                         ret = _SUCCESS;
2703                 else
2704                         ret = _FAIL;
2705         } else {
2706                 RTW_INFO("%s NULL pointer\n", __FUNCTION__);
2707                 ret =  _FAIL;
2708         }
2709         return ret;
2710 }
2711
2712 int retriveAdaptorInfoFile(char *path, u8 *efuse_data)
2713 {
2714         int ret = _SUCCESS;
2715         mm_segment_t oldfs;
2716         struct file *fp;
2717
2718         if (path && efuse_data) {
2719
2720                 ret = rtw_retrieve_from_file(path, efuse_data, EEPROM_MAX_SIZE);
2721
2722                 if (ret == EEPROM_MAX_SIZE)
2723                         ret = _SUCCESS;
2724                 else
2725                         ret = _FAIL;
2726
2727 #if 0
2728                 if (isAdaptorInfoFileValid())
2729                         return 0;
2730                 else
2731                         return _FAIL;
2732 #endif
2733
2734         } else {
2735                 RTW_INFO("%s NULL pointer\n", __FUNCTION__);
2736                 ret = _FAIL;
2737         }
2738         return ret;
2739 }
2740 #endif /* CONFIG_ADAPTOR_INFO_CACHING_FILE */
2741
2742 u8 rtw_efuse_file_read(PADAPTER padapter, u8 *filepatch, u8 *buf, u32 len)
2743 {
2744         char *ptmpbuf = NULL, *ptr;
2745         u8 val8;
2746         u32 count, i, j;
2747         int err;
2748         u32 bufsize = 4096;
2749
2750         ptmpbuf = rtw_zmalloc(bufsize);
2751         if (ptmpbuf == NULL)
2752                 return _FALSE;
2753
2754         count = rtw_retrieve_from_file(filepatch, ptmpbuf, bufsize);
2755         if (count <= 100) {
2756                 rtw_mfree(ptmpbuf, bufsize);
2757                 RTW_ERR("%s, filepatch %s, size=%d, FAIL!!\n", __FUNCTION__, filepatch, count);
2758                 return _FALSE;
2759         }
2760
2761         i = 0;
2762         j = 0;
2763         ptr = ptmpbuf;
2764         while ((j < len) && (i < count)) {
2765                 if (ptmpbuf[i] == '\0')
2766                         break;
2767         
2768                 ptr = strpbrk(&ptmpbuf[i], " \t\n\r");
2769                 if (ptr) {
2770                         if (ptr == &ptmpbuf[i]) {
2771                                 i++;
2772                                 continue;
2773                         }
2774
2775                         /* Add string terminating null */
2776                         *ptr = 0;
2777                 } else {
2778                         ptr = &ptmpbuf[count-1];
2779                 }
2780
2781                 err = sscanf(&ptmpbuf[i], "%hhx", &val8);
2782                 if (err != 1) {
2783                         RTW_WARN("Something wrong to parse efuse file, string=%s\n", &ptmpbuf[i]);
2784                 } else {
2785                         buf[j] = val8;
2786                         RTW_DBG("i=%d, j=%d, 0x%02x\n", i, j, buf[j]);
2787                         j++;
2788                 }
2789
2790                 i = ptr - ptmpbuf + 1;
2791         }
2792
2793         rtw_mfree(ptmpbuf, bufsize);
2794         RTW_INFO("%s, filepatch %s, size=%d, done\n", __FUNCTION__, filepatch, count);
2795         return _TRUE;
2796 }
2797
2798 #ifdef CONFIG_EFUSE_CONFIG_FILE
2799 u32 rtw_read_efuse_from_file(const char *path, u8 *buf, int map_size)
2800 {
2801         u32 i;
2802         u8 c;
2803         u8 temp[3];
2804         u8 temp_i;
2805         u8 end = _FALSE;
2806         u32 ret = _FAIL;
2807
2808         u8 *file_data = NULL;
2809         u32 file_size, read_size, pos = 0;
2810         u8 *map = NULL;
2811
2812         if (rtw_is_file_readable_with_size(path, &file_size) != _TRUE) {
2813                 RTW_PRINT("%s %s is not readable\n", __func__, path);
2814                 goto exit;
2815         }
2816
2817         file_data = rtw_vmalloc(file_size);
2818         if (!file_data) {
2819                 RTW_ERR("%s rtw_vmalloc(%d) fail\n", __func__, file_size);
2820                 goto exit;
2821         }
2822
2823         read_size = rtw_retrieve_from_file(path, file_data, file_size);
2824         if (read_size == 0) {
2825                 RTW_ERR("%s read from %s fail\n", __func__, path);
2826                 goto exit;
2827         }
2828
2829         map = rtw_vmalloc(map_size);
2830         if (!map) {
2831                 RTW_ERR("%s rtw_vmalloc(%d) fail\n", __func__, map_size);
2832                 goto exit;
2833         }
2834         _rtw_memset(map, 0xff, map_size);
2835
2836         temp[2] = 0; /* end of string '\0' */
2837
2838         for (i = 0 ; i < map_size ; i++) {
2839                 temp_i = 0;
2840
2841                 while (1) {
2842                         if (pos >= read_size) {
2843                                 end = _TRUE;
2844                                 break;
2845                         }
2846                         c = file_data[pos++];
2847
2848                         /* bypass spece or eol or null before first hex digit */
2849                         if (temp_i == 0 && (is_eol(c) == _TRUE || is_space(c) == _TRUE || is_null(c) == _TRUE))
2850                                 continue;
2851
2852                         if (IsHexDigit(c) == _FALSE) {
2853                                 RTW_ERR("%s invalid 8-bit hex format for offset:0x%03x\n", __func__, i);
2854                                 goto exit;
2855                         }
2856
2857                         temp[temp_i++] = c;
2858
2859                         if (temp_i == 2) {
2860                                 /* parse value */
2861                                 if (sscanf(temp, "%hhx", &map[i]) != 1) {
2862                                         RTW_ERR("%s sscanf fail for offset:0x%03x\n", __func__, i);
2863                                         goto exit;
2864                                 }
2865                                 break;
2866                         }
2867                 }
2868
2869                 if (end == _TRUE) {
2870                         if (temp_i != 0) {
2871                                 RTW_ERR("%s incomplete 8-bit hex format for offset:0x%03x\n", __func__, i);
2872                                 goto exit;
2873                         }
2874                         break;
2875                 }
2876         }
2877
2878         RTW_PRINT("efuse file:%s, 0x%03x byte content read\n", path, i);
2879
2880         _rtw_memcpy(buf, map, map_size);
2881
2882         ret = _SUCCESS;
2883
2884 exit:
2885         if (file_data)
2886                 rtw_vmfree(file_data, file_size);
2887         if (map)
2888                 rtw_vmfree(map, map_size);
2889
2890         return ret;
2891 }
2892
2893 u32 rtw_read_macaddr_from_file(const char *path, u8 *buf)
2894 {
2895         u32 i;
2896         u8 temp[3];
2897         u32 ret = _FAIL;
2898
2899         u8 file_data[17];
2900         u32 read_size, pos = 0;
2901         u8 addr[ETH_ALEN];
2902
2903         if (rtw_is_file_readable(path) != _TRUE) {
2904                 RTW_PRINT("%s %s is not readable\n", __func__, path);
2905                 goto exit;
2906         }
2907
2908         read_size = rtw_retrieve_from_file(path, file_data, 17);
2909         if (read_size != 17) {
2910                 RTW_ERR("%s read from %s fail\n", __func__, path);
2911                 goto exit;
2912         }
2913
2914         temp[2] = 0; /* end of string '\0' */
2915
2916         for (i = 0 ; i < ETH_ALEN ; i++) {
2917                 if (IsHexDigit(file_data[i * 3]) == _FALSE || IsHexDigit(file_data[i * 3 + 1]) == _FALSE) {
2918                         RTW_ERR("%s invalid 8-bit hex format for address offset:%u\n", __func__, i);
2919                         goto exit;
2920                 }
2921
2922                 if (i < ETH_ALEN - 1 && file_data[i * 3 + 2] != ':') {
2923                         RTW_ERR("%s invalid separator after address offset:%u\n", __func__, i);
2924                         goto exit;
2925                 }
2926
2927                 temp[0] = file_data[i * 3];
2928                 temp[1] = file_data[i * 3 + 1];
2929                 if (sscanf(temp, "%hhx", &addr[i]) != 1) {
2930                         RTW_ERR("%s sscanf fail for address offset:0x%03x\n", __func__, i);
2931                         goto exit;
2932                 }
2933         }
2934
2935         _rtw_memcpy(buf, addr, ETH_ALEN);
2936
2937         RTW_PRINT("wifi_mac file: %s\n", path);
2938 #ifdef CONFIG_RTW_DEBUG
2939         RTW_INFO(MAC_FMT"\n", MAC_ARG(buf));
2940 #endif
2941
2942         ret = _SUCCESS;
2943
2944 exit:
2945         return ret;
2946 }
2947 #endif /* CONFIG_EFUSE_CONFIG_FILE */
2948
2949 #endif /* PLATFORM_LINUX */