net: wireless: rockchip_wlan: add rtl8723bs support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8723bs / 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[32];
45 /*------------------------Define local variable------------------------------*/
46
47 //------------------------------------------------------------------------------
48 #define REG_EFUSE_CTRL          0x0030
49 #define EFUSE_CTRL                      REG_EFUSE_CTRL          // E-Fuse Control.
50 //------------------------------------------------------------------------------
51
52 BOOLEAN
53 Efuse_Read1ByteFromFakeContent(
54         IN              PADAPTER        pAdapter,
55         IN              u16             Offset,
56         IN OUT  u8              *Value  );
57 BOOLEAN
58 Efuse_Read1ByteFromFakeContent(
59         IN              PADAPTER        pAdapter,
60         IN              u16             Offset,
61         IN OUT  u8              *Value  )
62 {
63         if(Offset >= EFUSE_MAX_HW_SIZE)
64         {
65                 return _FALSE;
66         }
67         //DbgPrint("Read fake content, offset = %d\n", Offset);
68         if(fakeEfuseBank == 0)
69                 *Value = fakeEfuseContent[Offset];
70         else
71                 *Value = fakeBTEfuseContent[fakeEfuseBank-1][Offset];
72         return _TRUE;
73 }
74
75 BOOLEAN
76 Efuse_Write1ByteToFakeContent(
77         IN              PADAPTER        pAdapter,
78         IN              u16             Offset,
79         IN              u8              Value   );
80 BOOLEAN
81 Efuse_Write1ByteToFakeContent(
82         IN              PADAPTER        pAdapter,
83         IN              u16             Offset,
84         IN              u8              Value   )
85 {
86         if(Offset >= EFUSE_MAX_HW_SIZE)
87         {
88                 return _FALSE;
89         }
90         if(fakeEfuseBank == 0)
91                 fakeEfuseContent[Offset] = Value;
92         else
93         {
94                 fakeBTEfuseContent[fakeEfuseBank-1][Offset] = Value;
95         }
96         return _TRUE;
97 }
98
99 /*-----------------------------------------------------------------------------
100  * Function:    Efuse_PowerSwitch
101  *
102  * Overview:    When we want to enable write operation, we should change to 
103  *                              pwr on state. When we stop write, we should switch to 500k mode
104  *                              and disable LDO 2.5V.
105  *
106  * Input:       NONE
107  *
108  * Output:      NONE
109  *
110  * Return:      NONE
111  *
112  * Revised History:
113  * When                 Who             Remark
114  * 11/17/2008   MHC             Create Version 0.
115  *
116  *---------------------------------------------------------------------------*/
117 VOID
118 Efuse_PowerSwitch(
119         IN      PADAPTER        pAdapter,
120         IN      u8              bWrite,
121         IN      u8              PwrState)
122 {
123         pAdapter->HalFunc.EfusePowerSwitch(pAdapter, bWrite, PwrState);
124 }
125
126 VOID
127 BTEfuse_PowerSwitch(
128         IN      PADAPTER        pAdapter,
129         IN      u8              bWrite,
130         IN      u8              PwrState)
131 {
132         if(pAdapter->HalFunc.BTEfusePowerSwitch)
133                 pAdapter->HalFunc.BTEfusePowerSwitch(pAdapter, bWrite, PwrState);
134 }
135
136 /*-----------------------------------------------------------------------------
137  * Function:    efuse_GetCurrentSize
138  *
139  * Overview:    Get current efuse size!!!
140  *
141  * Input:       NONE
142  *
143  * Output:      NONE
144  *
145  * Return:      NONE
146  *
147  * Revised History:
148  * When                 Who             Remark
149  * 11/16/2008   MHC             Create Version 0.
150  *
151  *---------------------------------------------------------------------------*/
152 u16
153 Efuse_GetCurrentSize(
154         IN PADAPTER             pAdapter,
155         IN u8                   efuseType,
156         IN BOOLEAN              bPseudoTest)
157 {
158         u16 ret=0;
159
160         ret = pAdapter->HalFunc.EfuseGetCurrentSize(pAdapter, efuseType, bPseudoTest);
161
162         return ret;
163 }
164
165 /*  11/16/2008 MH Add description. Get current efuse area enabled word!!. */
166 u8
167 Efuse_CalculateWordCnts(IN u8   word_en)
168 {
169         u8 word_cnts = 0;
170         if(!(word_en & BIT(0))) word_cnts++; // 0 : write enable
171         if(!(word_en & BIT(1))) word_cnts++;
172         if(!(word_en & BIT(2))) word_cnts++;
173         if(!(word_en & BIT(3))) word_cnts++;
174         return word_cnts;
175 }
176
177 //
178 //      Description:
179 //              Execute E-Fuse read byte operation.
180 //              Refered from SD1 Richard.
181 //
182 //      Assumption:
183 //              1. Boot from E-Fuse and successfully auto-load.
184 //              2. PASSIVE_LEVEL (USB interface)
185 //
186 //      Created by Roger, 2008.10.21.
187 //
188 VOID
189 ReadEFuseByte(
190                 PADAPTER        Adapter,
191                 u16                     _offset, 
192                 u8                      *pbuf, 
193                 IN BOOLEAN      bPseudoTest) 
194 {
195         u32     value32;
196         u8      readbyte;
197         u16     retry;
198         //u32 start=rtw_get_current_time();
199
200         if(bPseudoTest)
201         {
202                 Efuse_Read1ByteFromFakeContent(Adapter, _offset, pbuf);
203                 return;
204         }
205         if (IS_HARDWARE_TYPE_8723B(Adapter))
206         {
207                 // <20130121, Kordan> For SMIC S55 EFUSE specificatoin.
208                 //0x34[11]: SW force PGMEN input of efuse to high. (for the bank selected by 0x34[9:8])
209                 PHY_SetMacReg(Adapter, EFUSE_TEST, BIT11, 0);
210         }
211         //Write Address
212         rtw_write8(Adapter, EFUSE_CTRL+1, (_offset & 0xff));            
213         readbyte = rtw_read8(Adapter, EFUSE_CTRL+2);
214         rtw_write8(Adapter, EFUSE_CTRL+2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc));                 
215
216         //Write bit 32 0
217         readbyte = rtw_read8(Adapter, EFUSE_CTRL+3);            
218         rtw_write8(Adapter, EFUSE_CTRL+3, (readbyte & 0x7f));   
219         
220         //Check bit 32 read-ready
221         retry = 0;
222         value32 = rtw_read32(Adapter, EFUSE_CTRL);
223         //while(!(((value32 >> 24) & 0xff) & 0x80)  && (retry<10))
224         while(!(((value32 >> 24) & 0xff) & 0x80)  && (retry<10000))
225         {
226                 value32 = rtw_read32(Adapter, EFUSE_CTRL);
227                 retry++;
228         }
229
230         // 20100205 Joseph: Add delay suggested by SD1 Victor.
231         // This fix the problem that Efuse read error in high temperature condition.
232         // Designer says that there shall be some delay after ready bit is set, or the
233         // result will always stay on last data we read.
234         rtw_udelay_os(50);
235         value32 = rtw_read32(Adapter, EFUSE_CTRL);
236         
237         *pbuf = (u8)(value32 & 0xff);
238         //DBG_871X("ReadEFuseByte _offset:%08u, in %d ms\n",_offset ,rtw_get_passing_time_ms(start));
239         
240 }
241
242 //
243 //      Description:
244 //              1. Execute E-Fuse read byte operation according as map offset and 
245 //                  save to E-Fuse table.
246 //              2. Refered from SD1 Richard.
247 //
248 //      Assumption:
249 //              1. Boot from E-Fuse and successfully auto-load.
250 //              2. PASSIVE_LEVEL (USB interface)
251 //
252 //      Created by Roger, 2008.10.21.
253 //
254 //      2008/12/12 MH   1. Reorganize code flow and reserve bytes. and add description.
255 //                                      2. Add efuse utilization collect.
256 //      2008/12/22 MH   Read Efuse must check if we write section 1 data again!!! Sec1
257 //                                      write addr must be after sec5.
258 //
259
260 VOID
261 efuse_ReadEFuse(
262         PADAPTER        Adapter,
263         u8              efuseType,
264         u16             _offset,
265         u16             _size_byte,
266         u8              *pbuf,
267         IN      BOOLEAN bPseudoTest
268         );
269 VOID
270 efuse_ReadEFuse(
271         PADAPTER        Adapter,
272         u8              efuseType,
273         u16             _offset,
274         u16             _size_byte,
275         u8              *pbuf,
276         IN      BOOLEAN bPseudoTest
277         )
278 {
279         Adapter->HalFunc.ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
280 }
281
282 VOID
283 EFUSE_GetEfuseDefinition(
284         IN              PADAPTER        pAdapter,
285         IN              u8              efuseType,
286         IN              u8              type,
287         OUT             void            *pOut,
288         IN              BOOLEAN         bPseudoTest
289         )
290 {
291         pAdapter->HalFunc.EFUSEGetEfuseDefinition(pAdapter, efuseType, type, pOut, bPseudoTest);
292 }
293
294 /*-----------------------------------------------------------------------------
295  * Function:    EFUSE_Read1Byte
296  *
297  * Overview:    Copy from WMAC fot EFUSE read 1 byte.
298  *
299  * Input:       NONE
300  *
301  * Output:      NONE
302  *
303  * Return:      NONE
304  *
305  * Revised History:
306  * When                 Who             Remark
307  * 09/23/2008   MHC             Copy from WMAC.
308  *
309  *---------------------------------------------------------------------------*/
310 u8
311 EFUSE_Read1Byte(        
312         IN      PADAPTER        Adapter, 
313         IN      u16             Address)
314 {
315         u8      data;
316         u8      Bytetemp = {0x00};
317         u8      temp = {0x00};
318         u32     k=0;
319         u16     contentLen=0;
320
321         EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI , TYPE_EFUSE_REAL_CONTENT_LEN, (PVOID)&contentLen, _FALSE);
322
323         if (Address < contentLen)       //E-fuse 512Byte
324         {
325                 //Write E-fuse Register address bit0~7
326                 temp = Address & 0xFF;  
327                 rtw_write8(Adapter, EFUSE_CTRL+1, temp);        
328                 Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+2);    
329                 //Write E-fuse Register address bit8~9
330                 temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);     
331                 rtw_write8(Adapter, EFUSE_CTRL+2, temp);        
332
333                 //Write 0x30[31]=0
334                 Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
335                 temp = Bytetemp & 0x7F;
336                 rtw_write8(Adapter, EFUSE_CTRL+3, temp);
337
338                 //Wait Write-ready (0x30[31]=1)
339                 Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
340                 while(!(Bytetemp & 0x80))
341                 {                               
342                         Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
343                         k++;
344                         if(k==1000)
345                         {
346                                 k=0;
347                                 break;
348                         }
349                 }
350                 data=rtw_read8(Adapter, EFUSE_CTRL);
351                 return data;
352         }
353         else
354                 return 0xFF;
355         
356 }/* EFUSE_Read1Byte */
357
358 /*-----------------------------------------------------------------------------
359  * Function:    EFUSE_Write1Byte
360  *
361  * Overview:    Copy from WMAC fot EFUSE write 1 byte.
362  *
363  * Input:       NONE
364  *
365  * Output:      NONE
366  *
367  * Return:      NONE
368  *
369  * Revised History:
370  * When                 Who             Remark
371  * 09/23/2008   MHC             Copy from WMAC.
372  *
373  *---------------------------------------------------------------------------*/
374
375 void    
376 EFUSE_Write1Byte(       
377         IN      PADAPTER        Adapter, 
378         IN      u16             Address,
379         IN      u8              Value);
380 void    
381 EFUSE_Write1Byte(       
382         IN      PADAPTER        Adapter, 
383         IN      u16             Address,
384         IN      u8              Value)
385 {
386         u8      Bytetemp = {0x00};
387         u8      temp = {0x00};
388         u32     k=0;
389         u16     contentLen=0;
390
391         //RT_TRACE(COMP_EFUSE, DBG_LOUD, ("Addr=%x Data =%x\n", Address, Value));
392         EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI , TYPE_EFUSE_REAL_CONTENT_LEN, (PVOID)&contentLen, _FALSE);
393
394         if( Address < contentLen)       //E-fuse 512Byte
395         {
396                 rtw_write8(Adapter, EFUSE_CTRL, Value);
397
398                 //Write E-fuse Register address bit0~7
399                 temp = Address & 0xFF;  
400                 rtw_write8(Adapter, EFUSE_CTRL+1, temp);        
401                 Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+2);    
402                 
403                 //Write E-fuse Register address bit8~9
404                 temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);     
405                 rtw_write8(Adapter, EFUSE_CTRL+2, temp);        
406
407                 //Write 0x30[31]=1
408                 Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
409                 temp = Bytetemp | 0x80;
410                 rtw_write8(Adapter, EFUSE_CTRL+3, temp);
411
412                 //Wait Write-ready (0x30[31]=0)
413                 Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
414                 while(Bytetemp & 0x80)
415                 {
416                         Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);                    
417                         k++;
418                         if(k==100)
419                         {
420                                 k=0;
421                                 break;
422                         }
423                 }
424         }
425 }/* EFUSE_Write1Byte */
426
427
428 /*  11/16/2008 MH Read one byte from real Efuse. */
429 u8
430 efuse_OneByteRead(
431         IN      PADAPTER        pAdapter, 
432         IN      u16                     addr,
433         IN      u8                      *data,
434         IN      BOOLEAN         bPseudoTest)
435 {
436         u32     tmpidx = 0;
437         u8      bResult;
438         u8      readbyte;
439         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(pAdapter);
440         
441         //DBG_871X("===> EFUSE_OneByteRead(), addr = %x\n", addr);
442         //DBG_871X("===> EFUSE_OneByteRead() start, 0x34 = 0x%X\n", rtw_read32(pAdapter, EFUSE_TEST));
443
444         if(bPseudoTest)
445         {
446                 bResult = Efuse_Read1ByteFromFakeContent(pAdapter, addr, data);
447                 return bResult;
448         }
449         
450         if(     IS_HARDWARE_TYPE_8723B(pAdapter) ||
451                 (IS_HARDWARE_TYPE_8192E(pAdapter) && (!IS_A_CUT(pHalData->VersionID))) ||
452                 (IS_VENDOR_8188E_I_CUT_SERIES(pAdapter)) || (IS_CHIP_VENDOR_SMIC(pHalData->VersionID))
453           )
454         {
455                 // <20130121, Kordan> For SMIC EFUSE specificatoin.
456                 //0x34[11]: SW force PGMEN input of efuse to high. (for the bank selected by 0x34[9:8]) 
457                 //PHY_SetMacReg(pAdapter, 0x34, BIT11, 0);
458                 rtw_write16(pAdapter, 0x34, rtw_read16(pAdapter,0x34)& (~BIT11) ); 
459         }
460
461         // -----------------e-fuse reg ctrl ---------------------------------
462         //address                       
463         rtw_write8(pAdapter, EFUSE_CTRL+1, (u8)(addr&0xff));            
464         rtw_write8(pAdapter, EFUSE_CTRL+2, ((u8)((addr>>8) &0x03) ) |
465         (rtw_read8(pAdapter, EFUSE_CTRL+2)&0xFC ));     
466
467         //rtw_write8(pAdapter, EFUSE_CTRL+3,  0x72);//read cmd  
468         //Write bit 32 0
469         readbyte = rtw_read8(pAdapter, EFUSE_CTRL+3);           
470         rtw_write8(pAdapter, EFUSE_CTRL+3, (readbyte & 0x7f));
471
472         while(!(0x80 &rtw_read8(pAdapter, EFUSE_CTRL+3))&&(tmpidx<1000))
473         {
474                 rtw_mdelay_os(1);
475                 tmpidx++;
476         }
477         if(tmpidx<100)
478         {                       
479                 *data=rtw_read8(pAdapter, EFUSE_CTRL);          
480                 bResult = _TRUE;
481         }
482         else
483         {
484                 *data = 0xff;   
485                 bResult = _FALSE;
486                 DBG_871X("%s: [ERROR] addr=0x%x bResult=%d time out 1s !!!\n", __FUNCTION__, addr, bResult);
487                 DBG_871X("%s: [ERROR] EFUSE_CTRL =0x%08x !!!\n", __FUNCTION__, rtw_read32(pAdapter, EFUSE_CTRL));
488         }
489
490         return bResult;
491 }
492                 
493 /*  11/16/2008 MH Write one byte to reald Efuse. */
494 u8
495 efuse_OneByteWrite(
496         IN      PADAPTER        pAdapter,  
497         IN      u16                     addr, 
498         IN      u8                      data,
499         IN      BOOLEAN         bPseudoTest)
500 {
501         u8      tmpidx = 0;
502         u8      bResult=_FALSE;
503         u32 efuseValue = 0;
504         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(pAdapter);
505         
506         //DBG_871X("===> EFUSE_OneByteWrite(), addr = %x data=%x\n", addr, data);
507         //DBG_871X("===> EFUSE_OneByteWrite() start, 0x34 = 0x%X\n", rtw_read32(pAdapter, EFUSE_TEST));
508
509         if(bPseudoTest)
510         {
511                 bResult = Efuse_Write1ByteToFakeContent(pAdapter, addr, data);
512                 return bResult;
513         }
514
515         Efuse_PowerSwitch(pAdapter, _TRUE, _TRUE);
516
517         // -----------------e-fuse reg ctrl ---------------------------------   
518         //address                       
519
520         
521         efuseValue = rtw_read32(pAdapter, EFUSE_CTRL);
522         efuseValue |= (BIT21|BIT31);
523         efuseValue &= ~(0x3FFFF);
524         efuseValue |= ((addr<<8 | data) & 0x3FFFF);
525
526         // <20130227, Kordan> 8192E MP chip A-cut had better not set 0x34[11] until B-Cut.
527         if (    IS_HARDWARE_TYPE_8723B(pAdapter) ||
528                 (IS_HARDWARE_TYPE_8192E(pAdapter) && (!IS_A_CUT(pHalData->VersionID))) ||
529                 (IS_VENDOR_8188E_I_CUT_SERIES(pAdapter)) || (IS_CHIP_VENDOR_SMIC(pHalData->VersionID))
530                 ) {
531                 // <20130121, Kordan> For SMIC EFUSE specificatoin.
532                 //0x34[11]: SW force PGMEN input of efuse to high. (for the bank selected by 0x34[9:8])
533                 //PHY_SetMacReg(pAdapter, 0x34, BIT11, 1);
534                 rtw_write16(pAdapter, 0x34, rtw_read16(pAdapter,0x34)| (BIT11) );
535                 rtw_write32(pAdapter, EFUSE_CTRL, 0x90600000|((addr<<8 | data)) );
536         }
537         else
538         {
539                 rtw_write32(pAdapter, EFUSE_CTRL, efuseValue);
540         }
541
542         while((0x80 &  rtw_read8(pAdapter, EFUSE_CTRL+3)) && (tmpidx<100) ){
543                 rtw_mdelay_os(1);
544                 tmpidx++;
545         }
546
547         if(tmpidx<100)
548         {
549                 bResult = _TRUE;
550         }
551         else
552         {
553                 bResult = _FALSE;
554                 DBG_871X("%s: [ERROR] addr=0x%x ,efuseValue=0x%x ,bResult=%d time out 1s !!! \n",
555                                         __FUNCTION__, addr, efuseValue, bResult);
556                 DBG_871X("%s: [ERROR] EFUSE_CTRL =0x%08x !!!\n", __FUNCTION__, rtw_read32(pAdapter, EFUSE_CTRL));
557         }
558
559         // disable Efuse program enable
560         if (    IS_HARDWARE_TYPE_8723B(pAdapter) ||
561                 (IS_HARDWARE_TYPE_8192E(pAdapter) && (!IS_A_CUT(pHalData->VersionID))) ||
562                 (IS_VENDOR_8188E_I_CUT_SERIES(pAdapter)) || (IS_CHIP_VENDOR_SMIC(pHalData->VersionID))
563                 ) {
564                 PHY_SetMacReg(pAdapter, EFUSE_TEST, BIT(11), 0);
565         }
566
567         Efuse_PowerSwitch(pAdapter, _TRUE, _FALSE);
568
569         return bResult;
570 }
571
572 int
573 Efuse_PgPacketRead(     IN      PADAPTER        pAdapter,
574                                         IN      u8                      offset,
575                                         IN      u8                      *data,
576                                         IN      BOOLEAN         bPseudoTest)
577 {
578         int     ret=0;
579
580         ret =  pAdapter->HalFunc.Efuse_PgPacketRead(pAdapter, offset, data, bPseudoTest);
581
582         return ret;
583 }
584
585 int 
586 Efuse_PgPacketWrite(IN  PADAPTER        pAdapter, 
587                                         IN      u8                      offset,
588                                         IN      u8                      word_en,
589                                         IN      u8                      *data,
590                                         IN      BOOLEAN         bPseudoTest)
591 {
592         int ret;
593
594         ret =  pAdapter->HalFunc.Efuse_PgPacketWrite(pAdapter, offset, word_en, data, bPseudoTest);
595
596         return ret;
597 }
598
599
600 int 
601 Efuse_PgPacketWrite_BT(IN       PADAPTER        pAdapter, 
602                                         IN      u8                      offset,
603                                         IN      u8                      word_en,
604                                         IN      u8                      *data,
605                                         IN      BOOLEAN         bPseudoTest)
606 {
607         int ret;
608
609         ret =  pAdapter->HalFunc.Efuse_PgPacketWrite_BT(pAdapter, offset, word_en, data, bPseudoTest);
610
611         return ret;
612 }
613
614 /*-----------------------------------------------------------------------------
615  * Function:    efuse_WordEnableDataRead
616  *
617  * Overview:    Read allowed word in current efuse section data.
618  *
619  * Input:       NONE
620  *
621  * Output:      NONE
622  *
623  * Return:      NONE
624  *
625  * Revised History:
626  * When                 Who             Remark
627  * 11/16/2008   MHC             Create Version 0.
628  * 11/21/2008   MHC             Fix Write bug when we only enable late word.
629  *
630  *---------------------------------------------------------------------------*/
631 void
632 efuse_WordEnableDataRead(IN     u8      word_en,
633                                                         IN      u8      *sourdata,
634                                                         IN      u8      *targetdata)
635 {       
636         if (!(word_en&BIT(0)))
637         {
638                 targetdata[0] = sourdata[0];
639                 targetdata[1] = sourdata[1];
640         }
641         if (!(word_en&BIT(1)))
642         {
643                 targetdata[2] = sourdata[2];
644                 targetdata[3] = sourdata[3];
645         }
646         if (!(word_en&BIT(2)))
647         {
648                 targetdata[4] = sourdata[4];
649                 targetdata[5] = sourdata[5];
650         }
651         if (!(word_en&BIT(3)))
652         {
653                 targetdata[6] = sourdata[6];
654                 targetdata[7] = sourdata[7];
655         }
656 }
657
658
659 u8
660 Efuse_WordEnableDataWrite(      IN      PADAPTER        pAdapter,
661                                                         IN      u16             efuse_addr,
662                                                         IN      u8              word_en, 
663                                                         IN      u8              *data,
664                                                         IN      BOOLEAN         bPseudoTest)
665 {
666         u8      ret=0;
667
668         ret =  pAdapter->HalFunc.Efuse_WordEnableDataWrite(pAdapter, efuse_addr, word_en, data, bPseudoTest);
669         
670         return ret;
671 }
672
673 static u8 efuse_read8(PADAPTER padapter, u16 address, u8 *value)
674 {
675         return efuse_OneByteRead(padapter,address, value, _FALSE);
676 }
677
678 static u8 efuse_write8(PADAPTER padapter, u16 address, u8 *value)
679 {
680         return efuse_OneByteWrite(padapter,address, *value, _FALSE);
681 }
682
683 /*
684  * read/wirte raw efuse data
685  */
686 u8 rtw_efuse_access(PADAPTER padapter, u8 bWrite, u16 start_addr, u16 cnts, u8 *data)
687 {
688         int i = 0;
689         u16     real_content_len = 0, max_available_size = 0;
690         u8 res = _FAIL ;
691         u8 (*rw8)(PADAPTER, u16, u8*);
692
693         EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_REAL_CONTENT_LEN, (PVOID)&real_content_len, _FALSE);
694         EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);
695
696         if (start_addr > real_content_len)
697                 return _FAIL;
698
699         if (_TRUE == bWrite) {
700                 if ((start_addr + cnts) > max_available_size)
701                         return _FAIL;
702                 rw8 = &efuse_write8;
703         } else
704                 rw8 = &efuse_read8;
705
706         Efuse_PowerSwitch(padapter, bWrite, _TRUE);
707
708         // e-fuse one byte read / write
709         for (i = 0; i < cnts; i++) {
710                 if (start_addr >= real_content_len) {
711                         res = _FAIL;
712                         break;
713                 }
714
715                 res = rw8(padapter, start_addr++, data++);
716                 if (_FAIL == res) break;
717         }
718
719         Efuse_PowerSwitch(padapter, bWrite, _FALSE);
720
721         return res;
722 }
723 //------------------------------------------------------------------------------
724 u16 efuse_GetMaxSize(PADAPTER padapter)
725 {
726         u16     max_size;
727
728         max_size = 0;
729         EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI , TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_size, _FALSE);
730         return max_size;
731 }
732 //------------------------------------------------------------------------------
733 u8 efuse_GetCurrentSize(PADAPTER padapter, u16 *size)
734 {
735         Efuse_PowerSwitch(padapter, _FALSE, _TRUE);
736         *size = Efuse_GetCurrentSize(padapter, EFUSE_WIFI, _FALSE);
737         Efuse_PowerSwitch(padapter, _FALSE, _FALSE);
738
739         return _SUCCESS;
740 }
741 //------------------------------------------------------------------------------
742 u16 efuse_bt_GetMaxSize(PADAPTER padapter)
743 {
744         u16     max_size;
745
746         max_size = 0;
747         EFUSE_GetEfuseDefinition(padapter, EFUSE_BT , TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_size, _FALSE);
748         return max_size;
749 }
750
751 u8 efuse_bt_GetCurrentSize(PADAPTER padapter, u16 *size)
752 {
753         Efuse_PowerSwitch(padapter, _FALSE, _TRUE);
754         *size = Efuse_GetCurrentSize(padapter, EFUSE_BT, _FALSE);
755         Efuse_PowerSwitch(padapter, _FALSE, _FALSE);
756
757         return _SUCCESS;
758 }
759
760 u8 rtw_efuse_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data)
761 {
762         u16     mapLen=0;
763
764         EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&mapLen, _FALSE);
765
766         if ((addr + cnts) > mapLen)
767                 return _FAIL;
768
769         Efuse_PowerSwitch(padapter, _FALSE, _TRUE);
770
771         efuse_ReadEFuse(padapter, EFUSE_WIFI, addr, cnts, data, _FALSE);
772
773         Efuse_PowerSwitch(padapter, _FALSE, _FALSE);
774
775         return _SUCCESS;
776 }
777
778 u8 rtw_BT_efuse_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data)
779 {
780         u16     mapLen=0;
781
782         EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (PVOID)&mapLen, _FALSE);
783
784         if ((addr + cnts) > mapLen)
785                 return _FAIL;
786
787         Efuse_PowerSwitch(padapter, _FALSE, _TRUE);
788
789         efuse_ReadEFuse(padapter, EFUSE_BT, addr, cnts, data, _FALSE);
790
791         Efuse_PowerSwitch(padapter, _FALSE, _FALSE);
792
793         return _SUCCESS;
794 }
795
796 BOOLEAN rtw_file_efuse_IsMasked(
797         PADAPTER        pAdapter,
798         u16             Offset
799         )
800 {
801         int r = Offset/16;
802         int c = (Offset%16) / 2;
803         int result = 0;
804         
805         if(pAdapter->registrypriv.boffefusemask)
806                 return FALSE;
807
808         //DBG_871X(" %s ,Offset=%x r= %d , c=%d , maskfileBuffer[r]= %x \n",__func__,Offset,r,c,maskfileBuffer[r]);
809         if (c < 4) // Upper double word
810             result = (maskfileBuffer[r] & (0x10 << c));
811         else
812             result = (maskfileBuffer[r] & (0x01 << (c-4)));
813         
814         return (result > 0) ? 0 : 1;
815
816 }
817
818
819 u8 rtw_efuse_file_read(PADAPTER padapter,u8 *filepatch,u8 *buf,u32 len)
820 {
821         char *ptmp;
822         char *ptmpbuf=NULL;
823         u32 rtStatus;
824         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
825
826         ptmpbuf = rtw_zmalloc(2048);
827
828         if (ptmpbuf == NULL)
829                 return _FALSE;
830
831         _rtw_memset(ptmpbuf,'\0',2048);
832         
833         rtStatus = rtw_retrieve_from_file(filepatch, ptmpbuf, 2048);
834
835         if( rtStatus > 100 )
836         {
837                 u32 i,j;
838                 for(i=0,j=0;j<len;i+=2,j++)
839                 {
840                         if (( ptmpbuf[i] == ' ' ) && (ptmpbuf[i+1] != '\n' && ptmpbuf[i+1] != '\0')) {
841                                 i++;
842                         }
843                         if( (ptmpbuf[i+1] != '\n' && ptmpbuf[i+1] != '\0'))
844                         {
845                                         buf[j] = simple_strtoul(&ptmpbuf[i],&ptmp, 16);
846                                         DBG_871X(" i=%d,j=%d, %x \n",i,j,buf[j]);
847
848                         } else {
849                                 j--;
850                         }
851                         
852                 }
853
854         } else {
855                 DBG_871X(" %s ,filepatch %s , FAIL %d\n", __func__, filepatch, rtStatus);
856                 return _FALSE;
857         }
858         rtw_mfree(ptmpbuf, 2048);
859         DBG_871X(" %s ,filepatch %s , done %d\n", __func__, filepatch, rtStatus);
860         return _TRUE;
861 }
862
863
864 BOOLEAN 
865 efuse_IsMasked(
866         PADAPTER        pAdapter,
867         u16             Offset
868         )
869 {
870         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(pAdapter);
871         
872
873         //if (bEfuseMaskOFF(pAdapter))
874         if(pAdapter->registrypriv.boffefusemask)
875                 return FALSE;
876                 
877 #if DEV_BUS_TYPE == RT_USB_INTERFACE
878 #if defined(CONFIG_RTL8188E)
879         if (IS_HARDWARE_TYPE_8188E(pAdapter))  
880                 return (IS_MASKED(8188E,_MUSB,Offset)) ? TRUE : FALSE;
881 #endif
882 #if defined(CONFIG_RTL8812A)
883         if (IS_HARDWARE_TYPE_8812(pAdapter))  
884                 return (IS_MASKED(8812A,_MUSB,Offset)) ? TRUE : FALSE;
885 #endif
886 #if defined(CONFIG_RTL8821A)
887         //if (IS_HARDWARE_TYPE_8811AU(pAdapter))  
888         //      return (IS_MASKED(8811A,_MUSB,Offset)) ? TRUE : FALSE;
889         if (IS_HARDWARE_TYPE_8821(pAdapter))  
890                 return (IS_MASKED(8821A,_MUSB,Offset)) ? TRUE : FALSE;          
891 #endif          
892 #if defined(CONFIG_RTL8192E)
893         if (IS_HARDWARE_TYPE_8192E(pAdapter))  
894                 return (IS_MASKED(8192E,_MUSB,Offset)) ? TRUE : FALSE;
895 #endif
896 #if defined(CONFIG_RTL8723B)
897         if (IS_HARDWARE_TYPE_8723B(pAdapter))  
898                 return (IS_MASKED(8723B,_MUSB,Offset)) ? TRUE : FALSE;
899 #endif
900 #if defined(CONFIG_RTL8703B)
901         if (IS_HARDWARE_TYPE_8703B(pAdapter))
902                 return (IS_MASKED(8703B, _MUSB, Offset)) ? TRUE : FALSE;
903 #endif
904 #if defined(CONFIG_RTL8814A)
905         if (IS_HARDWARE_TYPE_8814A(pAdapter))
906                 return (IS_MASKED(8814A, _MUSB, Offset)) ? TRUE : FALSE;
907 #endif
908 #if defined(CONFIG_RTL8188F)
909         if (IS_HARDWARE_TYPE_8188F(pAdapter))
910                 return (IS_MASKED(8188F, _MUSB, Offset)) ? TRUE : FALSE;
911 #endif
912 #elif DEV_BUS_TYPE == RT_PCI_INTERFACE
913 #if defined(CONFIG_RTL8188E)
914         if (IS_HARDWARE_TYPE_8188E(pAdapter))  
915                 return (IS_MASKED(8188E,_MPCIE,Offset)) ? TRUE : FALSE;
916 #endif
917 #if defined(CONFIG_RTL8192E)
918         if (IS_HARDWARE_TYPE_8192E(pAdapter))   
919                 return (IS_MASKED(8192E,_MPCIE,Offset)) ? TRUE : FALSE;
920 #endif  
921 #if defined(CONFIG_RTL8812A)
922         if (IS_HARDWARE_TYPE_8812(pAdapter))  
923                 return (IS_MASKED(8812A,_MPCIE,Offset)) ? TRUE : FALSE;
924 #endif  
925 #if defined(CONFIG_RTL8821A)
926         if (IS_HARDWARE_TYPE_8821(pAdapter))  
927                 return (IS_MASKED(8821A,_MPCIE,Offset)) ? TRUE : FALSE;
928 #endif
929 #if defined(CONFIG_RTL8723B)
930         if (IS_HARDWARE_TYPE_8723B(pAdapter))  
931                 return (IS_MASKED(8723B,_MPCIE,Offset)) ? TRUE : FALSE; 
932 #endif
933 #if defined(CONFIG_RTL8814A)
934         if (IS_HARDWARE_TYPE_8814A(pAdapter))
935                 return (IS_MASKED(8814A, _MPCIE, Offset)) ? TRUE : FALSE;
936 #endif
937         //else if (IS_HARDWARE_TYPE_8821B(pAdapter))  
938         //      return (IS_MASKED(8821B,_MPCIE,Offset)) ? TRUE : FALSE; 
939
940 #elif DEV_BUS_TYPE == RT_SDIO_INTERFACE
941 #ifdef CONFIG_RTL8188E_SDIO
942         if (IS_HARDWARE_TYPE_8188E(pAdapter))  
943                 return (IS_MASKED(8188E,_MSDIO,Offset)) ? TRUE : FALSE;
944 #endif
945 #ifdef CONFIG_RTL8188F_SDIO
946         if (IS_HARDWARE_TYPE_8188F(pAdapter))  
947                 return (IS_MASKED(8188F, _MSDIO, Offset)) ? TRUE : FALSE;
948 #endif
949 #endif
950
951         return FALSE;   
952 }
953
954 //------------------------------------------------------------------------------
955 u8 rtw_efuse_map_write(PADAPTER padapter, u16 addr, u16 cnts, u8 *data)
956 {
957 #define RT_ASSERT_RET(expr)                                                                                             \
958         if(!(expr)) {                                                                                                                   \
959                 printk( "Assertion failed! %s at ......\n", #expr);                                                     \
960                 printk( "      ......%s,%s,line=%d\n",__FILE__,__FUNCTION__,__LINE__);  \
961                 return _FAIL;   \
962         }
963
964         u8      offset, word_en;
965         u8      *map;
966         u8      newdata[PGPKT_DATA_SIZE];
967         s32     i, j, idx;
968         u8      ret = _SUCCESS;
969         u16     mapLen=0;
970         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
971
972         EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&mapLen, _FALSE);
973
974         if ((addr + cnts) > mapLen)
975                 return _FAIL;
976
977         RT_ASSERT_RET(PGPKT_DATA_SIZE == 8); // have to be 8 byte alignment
978         RT_ASSERT_RET((mapLen & 0x7) == 0); // have to be PGPKT_DATA_SIZE alignment for memcpy
979
980         map = rtw_zmalloc(mapLen);
981         if(map == NULL){
982                 return _FAIL;
983         }
984         
985         _rtw_memset(map, 0xFF, mapLen);
986         
987         ret = rtw_efuse_map_read(padapter, 0, mapLen, map);
988         if (ret == _FAIL) goto exit;
989
990         if(padapter->registrypriv.boffefusemask==0)
991         {
992                 for (i =0; i < cnts; i++)
993                 { 
994                         if(padapter->registrypriv.bFileMaskEfuse==_TRUE)
995                         {
996                                 if (rtw_file_efuse_IsMasked(padapter, addr+i))  /*use file efuse mask. */
997                                                 data[i] = map[addr+i];
998                         }
999                         else
1000                         {
1001                                 if ( efuse_IsMasked(padapter, addr+i ))
1002                                                 data[i] = map[addr+i];
1003                         }
1004                         DBG_8192C("%s , data[%d] = %x, map[addr+i]= %x\n", __func__, i, data[i], map[addr+i]);
1005                 }
1006         }
1007         /*Efuse_PowerSwitch(padapter, _TRUE, _TRUE);*/
1008
1009         idx = 0;
1010         offset = (addr >> 3);
1011         while (idx < cnts)
1012         {
1013                 word_en = 0xF;
1014                 j = (addr + idx) & 0x7;
1015                 _rtw_memcpy(newdata, &map[offset << 3], PGPKT_DATA_SIZE);
1016                 for (i = j; i<PGPKT_DATA_SIZE && idx < cnts; i++, idx++)
1017                 {
1018                         if (data[idx] != map[addr + idx])
1019                         {
1020                                 word_en &= ~BIT(i >> 1);
1021                                 newdata[i] = data[idx];
1022 #ifdef CONFIG_RTL8723B                                  
1023                                  if( addr + idx == 0x8)
1024                                  {      
1025                                         if (IS_C_CUT(pHalData->VersionID) || IS_B_CUT(pHalData->VersionID))
1026                                         {
1027                                                 if(pHalData->adjuseVoltageVal == 6)
1028                                                 {
1029                                                                 newdata[i] = map[addr + idx];
1030                                                                 DBG_8192C(" %s ,\n adjuseVoltageVal = %d ,newdata[%d] = %x \n",__func__,pHalData->adjuseVoltageVal,i,newdata[i]);        
1031                                                 }
1032                                         }
1033                                   }
1034 #endif
1035                         }
1036                 }
1037
1038                 if (word_en != 0xF) {
1039                         ret = Efuse_PgPacketWrite(padapter, offset, word_en, newdata, _FALSE);
1040                         DBG_871X("offset=%x \n",offset);
1041                         DBG_871X("word_en=%x \n",word_en);
1042
1043                         for(i=0;i<PGPKT_DATA_SIZE;i++)
1044                         {
1045                                 DBG_871X("data=%x \t",newdata[i]);
1046                         }
1047                         if (ret == _FAIL) break;
1048                 }
1049
1050                 offset++;
1051         }
1052
1053         /*Efuse_PowerSwitch(padapter, _TRUE, _FALSE);*/
1054
1055 exit:
1056
1057         rtw_mfree(map, mapLen);
1058
1059         return ret;
1060 }
1061
1062 u8 rtw_efuse_mask_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data)
1063 {
1064         u8      ret = _SUCCESS;
1065         u16     mapLen = 0, i = 0;
1066         
1067         EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&mapLen, _FALSE);
1068         
1069         ret = rtw_efuse_map_read(padapter, addr, cnts , data);
1070
1071         if (padapter->registrypriv.boffefusemask == 0) {
1072
1073                         for (i = 0; i < cnts; i++) { 
1074                                 if (padapter->registrypriv.bFileMaskEfuse == _TRUE) {
1075                                         if (rtw_file_efuse_IsMasked(padapter, addr+i)) /*use file efuse mask.*/ 
1076                                                         data[i] = 0xff;
1077                                 } else {
1078                                         /*DBG_8192C(" %s , data[%d] = %x\n", __func__, i, data[i]);*/
1079                                         if (efuse_IsMasked(padapter, addr+i)) {
1080                                                 data[i] = 0xff;
1081                                                 /*DBG_8192C(" %s ,mask data[%d] = %x\n", __func__, i, data[i]);*/
1082                                         }
1083                                 }
1084                         }
1085         
1086         }
1087         return ret;
1088
1089 }
1090
1091 u8 rtw_BT_efuse_map_write(PADAPTER padapter, u16 addr, u16 cnts, u8 *data)
1092 {
1093 #define RT_ASSERT_RET(expr)                                                                                             \
1094         if(!(expr)) {                                                                                                                   \
1095                 printk( "Assertion failed! %s at ......\n", #expr);                                                     \
1096                 printk( "      ......%s,%s,line=%d\n",__FILE__,__FUNCTION__,__LINE__);  \
1097                 return _FAIL;   \
1098         }
1099
1100         u8      offset, word_en;
1101         u8      *map;
1102         u8      newdata[PGPKT_DATA_SIZE];
1103         s32     i=0, j=0, idx;
1104         u8      ret = _SUCCESS;
1105         u16     mapLen=0;
1106
1107         EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (PVOID)&mapLen, _FALSE);
1108
1109         if ((addr + cnts) > mapLen)
1110                 return _FAIL;
1111
1112         RT_ASSERT_RET(PGPKT_DATA_SIZE == 8); // have to be 8 byte alignment
1113         RT_ASSERT_RET((mapLen & 0x7) == 0); // have to be PGPKT_DATA_SIZE alignment for memcpy
1114
1115         map = rtw_zmalloc(mapLen);
1116         if(map == NULL){
1117                 return _FAIL;
1118         }
1119
1120         ret = rtw_BT_efuse_map_read(padapter, 0, mapLen, map);
1121         if (ret == _FAIL) goto exit;
1122         DBG_871X("OFFSET\tVALUE(hex)\n");
1123         for (i=0; i<1024; i+=16) // set 512 because the iwpriv's extra size have limit 0x7FF
1124         {
1125                         DBG_871X("0x%03x\t", i);
1126                         for (j=0; j<8; j++) {
1127                                 DBG_871X("%02X ", map[i+j]);
1128                         }
1129                         DBG_871X("\t");
1130                         for (; j<16; j++) {
1131                                 DBG_871X("%02X ", map[i+j]);
1132                         }
1133                         DBG_871X("\n");
1134         }
1135         DBG_871X("\n");
1136         Efuse_PowerSwitch(padapter, _TRUE, _TRUE);
1137
1138         idx = 0;
1139         offset = (addr >> 3);
1140         while (idx < cnts)
1141         {
1142                 word_en = 0xF;
1143                 j = (addr + idx) & 0x7;
1144                 _rtw_memcpy(newdata, &map[offset << 3], PGPKT_DATA_SIZE);
1145                 for (i = j; i<PGPKT_DATA_SIZE && idx < cnts; i++, idx++)
1146                 {
1147                         if (data[idx] != map[addr + idx])
1148                         {
1149                                 word_en &= ~BIT(i >> 1);
1150                                 newdata[i] = data[idx];
1151                         }
1152                 }
1153
1154                 if (word_en != 0xF) {
1155                         DBG_871X("offset=%x \n",offset);
1156                         DBG_871X("word_en=%x \n",word_en);
1157                         DBG_871X("%s: data=", __FUNCTION__);
1158                         for(i=0;i<PGPKT_DATA_SIZE;i++)
1159                         {
1160                                 DBG_871X("0x%02X ", newdata[i]);
1161                         }
1162                         DBG_871X("\n");
1163                         ret = Efuse_PgPacketWrite_BT(padapter, offset, word_en, newdata, _FALSE);
1164                         if (ret == _FAIL) break;
1165                 }
1166
1167                 offset++;
1168         }
1169
1170         Efuse_PowerSwitch(padapter, _TRUE, _FALSE);
1171
1172 exit:
1173
1174         rtw_mfree(map, mapLen);
1175
1176         return ret;
1177 }
1178
1179 /*-----------------------------------------------------------------------------
1180  * Function:    Efuse_ReadAllMap
1181  *
1182  * Overview:    Read All Efuse content
1183  *
1184  * Input:       NONE
1185  *
1186  * Output:      NONE
1187  *
1188  * Return:      NONE
1189  *
1190  * Revised History:
1191  * When                 Who             Remark
1192  * 11/11/2008   MHC             Create Version 0.
1193  *
1194  *---------------------------------------------------------------------------*/
1195 VOID 
1196 Efuse_ReadAllMap(
1197         IN              PADAPTER        pAdapter, 
1198         IN              u8              efuseType,
1199         IN OUT  u8              *Efuse,
1200         IN              BOOLEAN         bPseudoTest);
1201 VOID 
1202 Efuse_ReadAllMap(
1203         IN              PADAPTER        pAdapter, 
1204         IN              u8              efuseType,
1205         IN OUT  u8              *Efuse,
1206         IN              BOOLEAN         bPseudoTest)
1207 {
1208         u16     mapLen=0;
1209
1210         Efuse_PowerSwitch(pAdapter,_FALSE, _TRUE);
1211
1212         EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (PVOID)&mapLen, bPseudoTest);
1213
1214         efuse_ReadEFuse(pAdapter, efuseType, 0, mapLen, Efuse, bPseudoTest);
1215
1216         Efuse_PowerSwitch(pAdapter,_FALSE, _FALSE);
1217 }
1218
1219 /*-----------------------------------------------------------------------------
1220  * Function:    efuse_ShadowRead1Byte
1221  *                      efuse_ShadowRead2Byte
1222  *                      efuse_ShadowRead4Byte
1223  *
1224  * Overview:    Read from efuse init map by one/two/four bytes !!!!!
1225  *
1226  * Input:       NONE
1227  *
1228  * Output:      NONE
1229  *
1230  * Return:      NONE
1231  *
1232  * Revised History:
1233  * When                 Who             Remark
1234  * 11/12/2008   MHC             Create Version 0.
1235  *
1236  *---------------------------------------------------------------------------*/
1237 static VOID
1238 efuse_ShadowRead1Byte(
1239         IN      PADAPTER        pAdapter,
1240         IN      u16             Offset,
1241         IN OUT  u8              *Value)
1242 {
1243         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);
1244
1245         *Value = pHalData->efuse_eeprom_data[Offset];
1246
1247 }       // EFUSE_ShadowRead1Byte
1248
1249 //---------------Read Two Bytes
1250 static VOID
1251 efuse_ShadowRead2Byte(
1252         IN      PADAPTER        pAdapter,
1253         IN      u16             Offset,
1254         IN OUT  u16             *Value)
1255 {
1256         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);
1257
1258         *Value = pHalData->efuse_eeprom_data[Offset];
1259         *Value |= pHalData->efuse_eeprom_data[Offset+1]<<8;
1260
1261 }       // EFUSE_ShadowRead2Byte
1262
1263 //---------------Read Four Bytes
1264 static VOID
1265 efuse_ShadowRead4Byte(
1266         IN      PADAPTER        pAdapter,
1267         IN      u16             Offset,
1268         IN OUT  u32             *Value)
1269 {
1270         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);
1271
1272         *Value = pHalData->efuse_eeprom_data[Offset];
1273         *Value |= pHalData->efuse_eeprom_data[Offset+1]<<8;
1274         *Value |= pHalData->efuse_eeprom_data[Offset+2]<<16;
1275         *Value |= pHalData->efuse_eeprom_data[Offset+3]<<24;
1276
1277 }       // efuse_ShadowRead4Byte
1278
1279
1280 /*-----------------------------------------------------------------------------
1281  * Function:    efuse_ShadowWrite1Byte
1282  *                      efuse_ShadowWrite2Byte
1283  *                      efuse_ShadowWrite4Byte
1284  *
1285  * Overview:    Write efuse modify map by one/two/four byte.
1286  *
1287  * Input:       NONE
1288  *
1289  * Output:      NONE
1290  *
1291  * Return:      NONE
1292  *
1293  * Revised History:
1294  * When                 Who             Remark
1295  * 11/12/2008   MHC             Create Version 0.
1296  *
1297  *---------------------------------------------------------------------------*/
1298 #ifdef PLATFORM
1299 static VOID
1300 efuse_ShadowWrite1Byte(
1301         IN      PADAPTER        pAdapter,
1302         IN      u16             Offset,
1303         IN      u8              Value);
1304 #endif //PLATFORM
1305 static VOID
1306 efuse_ShadowWrite1Byte(
1307         IN      PADAPTER        pAdapter,
1308         IN      u16             Offset,
1309         IN      u8              Value)
1310 {
1311         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);
1312
1313         pHalData->efuse_eeprom_data[Offset] = Value;
1314
1315 }       // efuse_ShadowWrite1Byte
1316
1317 //---------------Write Two Bytes
1318 static VOID
1319 efuse_ShadowWrite2Byte(
1320         IN      PADAPTER        pAdapter,
1321         IN      u16             Offset,
1322         IN      u16             Value)
1323 {
1324         
1325         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);
1326         
1327
1328         pHalData->efuse_eeprom_data[Offset] = Value&0x00FF;
1329         pHalData->efuse_eeprom_data[Offset+1] = Value>>8;
1330
1331 }       // efuse_ShadowWrite1Byte
1332
1333 //---------------Write Four Bytes
1334 static VOID
1335 efuse_ShadowWrite4Byte(
1336         IN      PADAPTER        pAdapter,
1337         IN      u16             Offset,
1338         IN      u32             Value)
1339 {
1340         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);
1341
1342         pHalData->efuse_eeprom_data[Offset] = (u8)(Value&0x000000FF);
1343         pHalData->efuse_eeprom_data[Offset+1] = (u8)((Value>>8)&0x0000FF);
1344         pHalData->efuse_eeprom_data[Offset+2] = (u8)((Value>>16)&0x00FF);
1345         pHalData->efuse_eeprom_data[Offset+3] = (u8)((Value>>24)&0xFF);
1346
1347 }       // efuse_ShadowWrite1Byte
1348
1349 /*-----------------------------------------------------------------------------
1350  * Function:    EFUSE_ShadowMapUpdate
1351  *
1352  * Overview:    Transfer current EFUSE content to shadow init and modify map.
1353  *
1354  * Input:       NONE
1355  *
1356  * Output:      NONE
1357  *
1358  * Return:      NONE
1359  *
1360  * Revised History:
1361  * When                 Who             Remark
1362  * 11/13/2008   MHC             Create Version 0.
1363  *
1364  *---------------------------------------------------------------------------*/
1365 void EFUSE_ShadowMapUpdate(
1366         IN PADAPTER     pAdapter,
1367         IN u8           efuseType,
1368         IN BOOLEAN      bPseudoTest)
1369 {
1370         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);
1371         u16     mapLen=0;
1372
1373         EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (PVOID)&mapLen, bPseudoTest);
1374
1375         if (pHalData->bautoload_fail_flag == _TRUE)
1376         {
1377                 _rtw_memset(pHalData->efuse_eeprom_data, 0xFF, mapLen);
1378         }
1379         else
1380         {
1381                 #ifdef CONFIG_ADAPTOR_INFO_CACHING_FILE                 
1382                 if(_SUCCESS != retriveAdaptorInfoFile(pAdapter->registrypriv.adaptor_info_caching_file_path, pHalData->efuse_eeprom_data)) {
1383                 #endif
1384                 
1385                 Efuse_ReadAllMap(pAdapter, efuseType, pHalData->efuse_eeprom_data, bPseudoTest);
1386                 
1387                 #ifdef CONFIG_ADAPTOR_INFO_CACHING_FILE
1388                         storeAdaptorInfoFile(pAdapter->registrypriv.adaptor_info_caching_file_path, pHalData->efuse_eeprom_data);
1389                 }
1390                 #endif
1391         }
1392
1393         //PlatformMoveMemory((PVOID)&pHalData->EfuseMap[EFUSE_MODIFY_MAP][0], 
1394         //(PVOID)&pHalData->EfuseMap[EFUSE_INIT_MAP][0], mapLen);
1395 }// EFUSE_ShadowMapUpdate
1396
1397
1398 /*-----------------------------------------------------------------------------
1399  * Function:    EFUSE_ShadowRead
1400  *
1401  * Overview:    Read from efuse init map !!!!!
1402  *
1403  * Input:       NONE
1404  *
1405  * Output:      NONE
1406  *
1407  * Return:      NONE
1408  *
1409  * Revised History:
1410  * When                 Who             Remark
1411  * 11/12/2008   MHC             Create Version 0.
1412  *
1413  *---------------------------------------------------------------------------*/
1414 void
1415 EFUSE_ShadowRead(
1416         IN              PADAPTER        pAdapter,
1417         IN              u8              Type,
1418         IN              u16             Offset,
1419         IN OUT  u32             *Value  )
1420 {
1421         if (Type == 1)
1422                 efuse_ShadowRead1Byte(pAdapter, Offset, (u8 *)Value);
1423         else if (Type == 2)
1424                 efuse_ShadowRead2Byte(pAdapter, Offset, (u16 *)Value);
1425         else if (Type == 4)
1426                 efuse_ShadowRead4Byte(pAdapter, Offset, (u32 *)Value);
1427         
1428 }       // EFUSE_ShadowRead
1429
1430 /*-----------------------------------------------------------------------------
1431  * Function:    EFUSE_ShadowWrite
1432  *
1433  * Overview:    Write efuse modify map for later update operation to use!!!!!
1434  *
1435  * Input:       NONE
1436  *
1437  * Output:      NONE
1438  *
1439  * Return:      NONE
1440  *
1441  * Revised History:
1442  * When                 Who             Remark
1443  * 11/12/2008   MHC             Create Version 0.
1444  *
1445  *---------------------------------------------------------------------------*/
1446 VOID
1447 EFUSE_ShadowWrite(
1448         IN      PADAPTER        pAdapter,
1449         IN      u8              Type,
1450         IN      u16             Offset,
1451         IN OUT  u32             Value);
1452 VOID
1453 EFUSE_ShadowWrite(
1454         IN      PADAPTER        pAdapter,
1455         IN      u8              Type,
1456         IN      u16             Offset,
1457         IN OUT  u32             Value)
1458 {
1459 #if (MP_DRIVER == 0)
1460         return;
1461 #endif
1462         if ( pAdapter->registrypriv.mp_mode == 0)
1463                 return;
1464
1465
1466         if (Type == 1)
1467                 efuse_ShadowWrite1Byte(pAdapter, Offset, (u8)Value);
1468         else if (Type == 2)
1469                 efuse_ShadowWrite2Byte(pAdapter, Offset, (u16)Value);
1470         else if (Type == 4)
1471                 efuse_ShadowWrite4Byte(pAdapter, Offset, (u32)Value);
1472
1473 }       // EFUSE_ShadowWrite
1474
1475 VOID
1476 Efuse_InitSomeVar(
1477         IN              PADAPTER        pAdapter
1478         );
1479 VOID
1480 Efuse_InitSomeVar(
1481         IN              PADAPTER        pAdapter
1482         )
1483 {
1484         u8 i;
1485         
1486         _rtw_memset((PVOID)&fakeEfuseContent[0], 0xff, EFUSE_MAX_HW_SIZE);
1487         _rtw_memset((PVOID)&fakeEfuseInitMap[0], 0xff, EFUSE_MAX_MAP_LEN);
1488         _rtw_memset((PVOID)&fakeEfuseModifiedMap[0], 0xff, EFUSE_MAX_MAP_LEN);
1489
1490         for(i=0; i<EFUSE_MAX_BT_BANK; i++)
1491         {
1492                 _rtw_memset((PVOID)&BTEfuseContent[i][0], EFUSE_MAX_HW_SIZE, 0xff);
1493         }
1494         _rtw_memset((PVOID)&BTEfuseInitMap[0], 0xff, EFUSE_BT_MAX_MAP_LEN);
1495         _rtw_memset((PVOID)&BTEfuseModifiedMap[0], 0xff, EFUSE_BT_MAX_MAP_LEN);
1496
1497         for(i=0; i<EFUSE_MAX_BT_BANK; i++)
1498         {
1499                 _rtw_memset((PVOID)&fakeBTEfuseContent[i][0], 0xff, EFUSE_MAX_HW_SIZE);
1500         }
1501         _rtw_memset((PVOID)&fakeBTEfuseInitMap[0], 0xff, EFUSE_BT_MAX_MAP_LEN);
1502         _rtw_memset((PVOID)&fakeBTEfuseModifiedMap[0], 0xff, EFUSE_BT_MAX_MAP_LEN);
1503 }
1504
1505 const u8 _mac_hidden_max_bw_to_hal_bw_cap[MAC_HIDDEN_MAX_BW_NUM] = {
1506         0,
1507         0,
1508         (BW_CAP_160M|BW_CAP_80M|BW_CAP_40M|BW_CAP_20M|BW_CAP_10M|BW_CAP_5M),
1509         (BW_CAP_5M),
1510         (BW_CAP_10M|BW_CAP_5M),
1511         (BW_CAP_20M|BW_CAP_10M|BW_CAP_5M),
1512         (BW_CAP_40M|BW_CAP_20M|BW_CAP_10M|BW_CAP_5M),
1513         (BW_CAP_80M|BW_CAP_40M|BW_CAP_20M|BW_CAP_10M|BW_CAP_5M),
1514 };
1515
1516 const u8 _mac_hidden_proto_to_hal_proto_cap[MAC_HIDDEN_PROTOCOL_NUM] = {
1517         0,
1518         0,
1519         (PROTO_CAP_11N|PROTO_CAP_11G|PROTO_CAP_11B),
1520         (PROTO_CAP_11AC|PROTO_CAP_11N|PROTO_CAP_11G|PROTO_CAP_11B),
1521 };
1522
1523 u8 mac_hidden_wl_func_to_hal_wl_func(u8 func)
1524 {
1525         u8 wl_func = 0;
1526
1527         if (func & BIT0)
1528                 wl_func |= WL_FUNC_MIRACAST;
1529         if (func & BIT1)
1530                 wl_func |= WL_FUNC_P2P;
1531         if (func & BIT2)
1532                 wl_func |= WL_FUNC_TDLS;
1533         if (func & BIT3)
1534                 wl_func |= WL_FUNC_FTM;
1535
1536         return wl_func;
1537 }
1538
1539 #ifdef PLATFORM_LINUX
1540 #ifdef CONFIG_ADAPTOR_INFO_CACHING_FILE
1541 //#include <rtw_eeprom.h>
1542
1543  int isAdaptorInfoFileValid(void)
1544 {
1545         return _TRUE;
1546 }
1547
1548 int storeAdaptorInfoFile(char *path, u8* efuse_data)
1549 {
1550         int ret =_SUCCESS;
1551
1552         if(path && efuse_data) {
1553                 ret = rtw_store_to_file(path, efuse_data, EEPROM_MAX_SIZE_512);
1554                 if(ret == EEPROM_MAX_SIZE)
1555                         ret = _SUCCESS;
1556                 else
1557                         ret = _FAIL;
1558         } else {
1559                 DBG_871X("%s NULL pointer\n",__FUNCTION__);
1560                 ret =  _FAIL;
1561         }
1562         return ret;
1563 }
1564
1565 int retriveAdaptorInfoFile(char *path, u8* efuse_data)
1566 {
1567         int ret = _SUCCESS;
1568         mm_segment_t oldfs;
1569         struct file *fp;
1570         
1571         if(path && efuse_data) {
1572
1573                 ret = rtw_retrieve_from_file(path, efuse_data, EEPROM_MAX_SIZE);
1574                 
1575                 if(ret == EEPROM_MAX_SIZE)
1576                         ret = _SUCCESS;
1577                 else
1578                         ret = _FAIL;
1579
1580                 #if 0
1581                 if(isAdaptorInfoFileValid()) {  
1582                         return 0;
1583                 } else {
1584                         return _FAIL;
1585                 }
1586                 #endif
1587                 
1588         } else {
1589                 DBG_871X("%s NULL pointer\n",__FUNCTION__);
1590                 ret = _FAIL;
1591         }
1592         return ret;
1593 }
1594 #endif /* CONFIG_ADAPTOR_INFO_CACHING_FILE */
1595
1596 #ifdef CONFIG_EFUSE_CONFIG_FILE
1597 u32 rtw_read_efuse_from_file(const char *path, u8 *buf)
1598 {
1599         u32 i;
1600         u8 temp[3];
1601         u32 ret = _FAIL;
1602
1603         struct file *fp;
1604         mm_segment_t fs;
1605         loff_t pos = 0;
1606
1607         fp = filp_open(path, O_RDONLY, 0);
1608         if (fp == NULL || IS_ERR(fp)) {
1609                 if (fp != NULL)
1610                         DBG_871X_LEVEL(_drv_always_, "%s open %s fail, err:%ld\n"
1611                                 , __func__, path, PTR_ERR(fp));
1612                 else
1613                         DBG_871X_LEVEL(_drv_always_, "%s open %s fail, fp is NULL\n"
1614                                 , __func__, path);
1615
1616                 goto exit;
1617         }
1618
1619         temp[2] = 0; /* add end of string '\0' */
1620
1621         fs = get_fs();
1622         set_fs(KERNEL_DS);
1623
1624         for (i = 0 ; i < HWSET_MAX_SIZE ; i++) {
1625                 vfs_read(fp, temp, 2, &pos);
1626                 if (sscanf(temp, "%hhx", &buf[i]) != 1) {
1627                         if (0)
1628                                 DBG_871X_LEVEL(_drv_err_, "%s sscanf fail\n", __func__);
1629                         buf[i] = 0xFF;
1630                 }
1631                 if ((i % EFUSE_FILE_COLUMN_NUM) == (EFUSE_FILE_COLUMN_NUM - 1)) {
1632                         /* Filter the lates space char. */
1633                         vfs_read(fp, temp, 1, &pos);
1634                         if (strchr(temp, ' ') == NULL) {
1635                                 pos--;
1636                                 vfs_read(fp, temp, 2, &pos);
1637                         }
1638                 } else {
1639                         pos += 1; /* Filter the space character */
1640                 }
1641         }
1642
1643         set_fs(fs);
1644
1645         DBG_871X_LEVEL(_drv_always_, "efuse file: %s\n", path);
1646 #ifdef CONFIG_DEBUG
1647         for (i = 0; i < HWSET_MAX_SIZE; i++) {
1648                 if (i % 16 == 0)
1649                         DBG_871X_SEL_NL(RTW_DBGDUMP, "0x%03x: ", i);
1650
1651                 DBG_871X_SEL(RTW_DBGDUMP, "%02X%s"
1652                         , buf[i]
1653                         , ((i + 1) % 16 == 0) ? "\n" : (((i + 1) % 8 == 0) ? "    " : " ")
1654                 );
1655         }
1656         DBG_871X_SEL(RTW_DBGDUMP, "\n");
1657 #endif
1658
1659         ret = _SUCCESS;
1660
1661 exit:
1662         return ret;
1663 }
1664
1665 u32 rtw_read_macaddr_from_file(const char *path, u8 *buf)
1666 {
1667         struct file *fp;
1668         mm_segment_t fs;
1669         loff_t pos = 0;
1670
1671         u8 source_addr[18];
1672         u8 *head, *end;
1673         int i;
1674         u32 ret = _FAIL;
1675
1676         _rtw_memset(source_addr, 0, 18);
1677
1678         fp = filp_open(path, O_RDONLY, 0);
1679         if (fp == NULL || IS_ERR(fp)) {
1680                 if (fp != NULL)
1681                         DBG_871X_LEVEL(_drv_always_, "%s open %s fail, err:%ld\n"
1682                                 , __func__, path, PTR_ERR(fp));
1683                 else
1684                         DBG_871X_LEVEL(_drv_always_, "%s open %s fail, fp is NULL\n"
1685                                 , __func__, path);
1686
1687                 goto exit;
1688         }
1689
1690         fs = get_fs();
1691         set_fs(KERNEL_DS);
1692
1693         vfs_read(fp, source_addr, 18, &pos);
1694         source_addr[17] = ':';
1695
1696         head = end = source_addr;
1697         for (i = 0; i < ETH_ALEN; i++) {
1698                 while (end && (*end != ':'))
1699                         end++;
1700
1701                 if (end && (*end == ':'))
1702                         *end = '\0';
1703
1704                 if (sscanf(head, "%hhx", &buf[i]) != 1) {
1705                         if (0)
1706                                 DBG_871X_LEVEL(_drv_err_, "%s sscanf fail\n", __func__);
1707                         buf[i] = 0xFF;
1708                 }
1709
1710                 if (end) {
1711                         end++;
1712                         head = end;
1713                 }
1714         }
1715
1716         set_fs(fs);
1717
1718         DBG_871X_LEVEL(_drv_always_, "wifi_mac file: %s\n", path);
1719 #ifdef CONFIG_DEBUG
1720         DBG_871X(MAC_FMT"\n", MAC_ARG(buf));
1721 #endif
1722
1723         ret = _SUCCESS;
1724
1725 exit:
1726         return ret;
1727 }
1728 #endif /* CONFIG_EFUSE_CONFIG_FILE */
1729
1730 #endif /* PLATFORM_LINUX */
1731