OSDN Git Service

Only ODM_SUPPORTED_TYPE == ODM_CE is compiled on Linux
[android-x86/external-modules-rtl8723au.git] / core / 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_conf.h>
23 #include <osdep_service.h>
24 #include <drv_types.h>
25
26 #include <rtw_efuse.h>
27
28 /*------------------------Define local variable------------------------------*/
29 u8      fakeEfuseBank=0;
30 u32     fakeEfuseUsedBytes=0;
31 u8      fakeEfuseContent[EFUSE_MAX_HW_SIZE]={0};
32 u8      fakeEfuseInitMap[EFUSE_MAX_MAP_LEN]={0};
33 u8      fakeEfuseModifiedMap[EFUSE_MAX_MAP_LEN]={0};
34
35 u32     BTEfuseUsedBytes=0;
36 u8      BTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE];
37 u8      BTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN]={0};
38 u8      BTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN]={0};
39
40 u32     fakeBTEfuseUsedBytes=0;
41 u8      fakeBTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE];
42 u8      fakeBTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN]={0};
43 u8      fakeBTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN]={0};
44 /*------------------------Define local variable------------------------------*/
45
46 /*  */
47 #define REG_EFUSE_CTRL          0x0030
48 #define EFUSE_CTRL                      REG_EFUSE_CTRL          /*  E-Fuse Control. */
49 /*  */
50
51 bool
52 Efuse_Read1ByteFromFakeContent(
53                 PADAPTER        pAdapter,
54                 u16             Offset,
55         u8              *Value  );
56 bool
57 Efuse_Read1ByteFromFakeContent(
58                 PADAPTER        pAdapter,
59                 u16             Offset,
60         u8              *Value  )
61 {
62         if(Offset >= EFUSE_MAX_HW_SIZE)
63         {
64                 return _FALSE;
65         }
66         /* DbgPrint("Read fake content, offset = %d\n", Offset); */
67         if(fakeEfuseBank == 0)
68                 *Value = fakeEfuseContent[Offset];
69         else
70                 *Value = fakeBTEfuseContent[fakeEfuseBank-1][Offset];
71         return _TRUE;
72 }
73
74 bool
75 Efuse_Write1ByteToFakeContent(
76                 PADAPTER        pAdapter,
77                 u16             Offset,
78                 u8              Value   );
79 bool
80 Efuse_Write1ByteToFakeContent(
81                 PADAPTER        pAdapter,
82                 u16             Offset,
83                 u8              Value   )
84 {
85         if(Offset >= EFUSE_MAX_HW_SIZE)
86         {
87                 return _FALSE;
88         }
89         if(fakeEfuseBank == 0)
90                 fakeEfuseContent[Offset] = Value;
91         else
92         {
93                 fakeBTEfuseContent[fakeEfuseBank-1][Offset] = Value;
94         }
95         return _TRUE;
96 }
97
98 /*-----------------------------------------------------------------------------
99  * Function:    Efuse_PowerSwitch
100  *
101  * Overview:    When we want to enable write operation, we should change to
102  *                              pwr on state. When we stop write, we should switch to 500k mode
103  *                              and disable LDO 2.5V.
104  *
105  * Input:       NONE
106  *
107  * Output:      NONE
108  *
109  * Return:      NONE
110  *
111  * Revised History:
112  * When                 Who             Remark
113  * 11/17/2008   MHC             Create Version 0.
114  *
115  *---------------------------------------------------------------------------*/
116 void
117 Efuse_PowerSwitch(
118         PADAPTER        pAdapter,
119         u8              bWrite,
120         u8              PwrState)
121 {
122         pAdapter->HalFunc.EfusePowerSwitch(pAdapter, bWrite, PwrState);
123 }
124
125 /*-----------------------------------------------------------------------------
126  * Function:    efuse_GetCurrentSize
127  *
128  * Overview:    Get current efuse size!!!
129  *
130  * Input:       NONE
131  *
132  * Output:      NONE
133  *
134  * Return:      NONE
135  *
136  * Revised History:
137  * When                 Who             Remark
138  * 11/16/2008   MHC             Create Version 0.
139  *
140  *---------------------------------------------------------------------------*/
141 u16
142 Efuse_GetCurrentSize(
143  PADAPTER               pAdapter,
144  u8                     efuseType,
145  bool           bPseudoTest)
146 {
147         u16 ret=0;
148
149         ret = pAdapter->HalFunc.EfuseGetCurrentSize(pAdapter, efuseType, bPseudoTest);
150
151         return ret;
152 }
153
154 /*  11/16/2008 MH Add description. Get current efuse area enabled word!!. */
155 u8
156 Efuse_CalculateWordCnts(u8 word_en)
157 {
158         u8 word_cnts = 0;
159         if(!(word_en & BIT(0))) word_cnts++; /*  0 : write enable */
160         if(!(word_en & BIT(1))) word_cnts++;
161         if(!(word_en & BIT(2))) word_cnts++;
162         if(!(word_en & BIT(3))) word_cnts++;
163         return word_cnts;
164 }
165
166 /*  */
167 /*      Description: */
168 /*              Execute E-Fuse read byte operation. */
169 /*              Refered from SD1 Richard. */
170 /*  */
171 /*      Assumption: */
172 /*              1. Boot from E-Fuse and successfully auto-load. */
173 /*              2. PASSIVE_LEVEL (USB interface) */
174 /*  */
175 /*      Created by Roger, 2008.10.21. */
176 /*  */
177 void
178 ReadEFuseByte(
179                 PADAPTER        Adapter,
180                 u16                     _offset,
181                 u8                      *pbuf,
182          bool   bPseudoTest)
183 {
184         u32     value32;
185         u8      readbyte;
186         u16     retry;
187         /* u32 start=rtw_get_current_time(); */
188
189         if(bPseudoTest)
190         {
191                 Efuse_Read1ByteFromFakeContent(Adapter, _offset, pbuf);
192                 return;
193         }
194
195         /* Write Address */
196         rtw_write8(Adapter, EFUSE_CTRL+1, (_offset & 0xff));
197         readbyte = rtw_read8(Adapter, EFUSE_CTRL+2);
198         rtw_write8(Adapter, EFUSE_CTRL+2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
199
200         /* Write bit 32 0 */
201         readbyte = rtw_read8(Adapter, EFUSE_CTRL+3);
202         rtw_write8(Adapter, EFUSE_CTRL+3, (readbyte & 0x7f));
203
204         /* Check bit 32 read-ready */
205         retry = 0;
206         value32 = rtw_read32(Adapter, EFUSE_CTRL);
207         /* while(!(((value32 >> 24) & 0xff) & 0x80)  && (retry<10)) */
208         while(!(((value32 >> 24) & 0xff) & 0x80)  && (retry<10000))
209         {
210                 value32 = rtw_read32(Adapter, EFUSE_CTRL);
211                 retry++;
212         }
213
214         /*  20100205 Joseph: Add delay suggested by SD1 Victor. */
215         /*  This fix the problem that Efuse read error in high temperature condition. */
216         /*  Designer says that there shall be some delay after ready bit is set, or the */
217         /*  result will always stay on last data we read. */
218         rtw_udelay_os(50);
219         value32 = rtw_read32(Adapter, EFUSE_CTRL);
220
221         *pbuf = (u8)(value32 & 0xff);
222         /* DBG_8723A("ReadEFuseByte _offset:%08u, in %d ms\n",_offset ,rtw_get_passing_time_ms(start)); */
223 }
224
225 /*  */
226 /*      Description: */
227 /*              1. Execute E-Fuse read byte operation according as map offset and */
228 /*                  save to E-Fuse table. */
229 /*              2. Refered from SD1 Richard. */
230 /*  */
231 /*      Assumption: */
232 /*              1. Boot from E-Fuse and successfully auto-load. */
233 /*              2. PASSIVE_LEVEL (USB interface) */
234 /*  */
235 /*      Created by Roger, 2008.10.21. */
236 /*  */
237 /*      2008/12/12 MH   1. Reorganize code flow and reserve bytes. and add description. */
238 /*                                      2. Add efuse utilization collect. */
239 /*      2008/12/22 MH   Read Efuse must check if we write section 1 data again!!! Sec1 */
240 /*                                      write addr must be after sec5. */
241 /*  */
242
243 void
244 efuse_ReadEFuse(
245         PADAPTER        Adapter,
246         u8              efuseType,
247         u16             _offset,
248         u16             _size_byte,
249         u8              *pbuf,
250         bool    bPseudoTest
251         );
252 void
253 efuse_ReadEFuse(
254         PADAPTER        Adapter,
255         u8              efuseType,
256         u16             _offset,
257         u16             _size_byte,
258         u8              *pbuf,
259         bool    bPseudoTest
260         )
261 {
262         Adapter->HalFunc.ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
263 }
264
265 void
266 EFUSE_GetEfuseDefinition(
267                 PADAPTER        pAdapter,
268                 u8              efuseType,
269                 u8              type,
270                 void            *pOut,
271                 bool            bPseudoTest
272         )
273 {
274         pAdapter->HalFunc.EFUSEGetEfuseDefinition(pAdapter, efuseType, type, pOut, bPseudoTest);
275 }
276
277 /*-----------------------------------------------------------------------------
278  * Function:    EFUSE_Read1Byte
279  *
280  * Overview:    Copy from WMAC fot EFUSE read 1 byte.
281  *
282  * Input:       NONE
283  *
284  * Output:      NONE
285  *
286  * Return:      NONE
287  *
288  * Revised History:
289  * When                 Who             Remark
290  * 09/23/2008   MHC             Copy from WMAC.
291  *
292  *---------------------------------------------------------------------------*/
293 u8
294 EFUSE_Read1Byte(
295         PADAPTER        Adapter,
296         u16             Address)
297 {
298         u8      data;
299         u8      Bytetemp = {0x00};
300         u8      temp = {0x00};
301         u32     k=0;
302         u16     contentLen=0;
303
304         EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI , TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&contentLen, _FALSE);
305
306         if (Address < contentLen)       /* E-fuse 512Byte */
307         {
308                 /* Write E-fuse Register address bit0~7 */
309                 temp = Address & 0xFF;
310                 rtw_write8(Adapter, EFUSE_CTRL+1, temp);
311                 Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+2);
312                 /* Write E-fuse Register address bit8~9 */
313                 temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
314                 rtw_write8(Adapter, EFUSE_CTRL+2, temp);
315
316                 /* Write 0x30[31]=0 */
317                 Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
318                 temp = Bytetemp & 0x7F;
319                 rtw_write8(Adapter, EFUSE_CTRL+3, temp);
320
321                 /* Wait Write-ready (0x30[31]=1) */
322                 Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
323                 while(!(Bytetemp & 0x80))
324                 {
325                         Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
326                         k++;
327                         if(k==1000)
328                         {
329                                 k=0;
330                                 break;
331                         }
332                 }
333                 data=rtw_read8(Adapter, EFUSE_CTRL);
334                 return data;
335         }
336         else
337                 return 0xFF;
338 }/* EFUSE_Read1Byte */
339
340 /*-----------------------------------------------------------------------------
341  * Function:    EFUSE_Write1Byte
342  *
343  * Overview:    Copy from WMAC fot EFUSE write 1 byte.
344  *
345  * Input:       NONE
346  *
347  * Output:      NONE
348  *
349  * Return:      NONE
350  *
351  * Revised History:
352  * When                 Who             Remark
353  * 09/23/2008   MHC             Copy from WMAC.
354  *
355  *---------------------------------------------------------------------------*/
356
357 void
358 EFUSE_Write1Byte(
359         PADAPTER        Adapter,
360         u16             Address,
361         u8              Value);
362 void
363 EFUSE_Write1Byte(
364         PADAPTER        Adapter,
365         u16             Address,
366         u8              Value)
367 {
368         u8      Bytetemp = {0x00};
369         u8      temp = {0x00};
370         u32     k=0;
371         u16     contentLen=0;
372
373         /* RT_TRACE(COMP_EFUSE, DBG_LOUD, ("Addr=%x Data =%x\n", Address, Value)); */
374         EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI , TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&contentLen, _FALSE);
375
376         if( Address < contentLen)       /* E-fuse 512Byte */
377         {
378                 rtw_write8(Adapter, EFUSE_CTRL, Value);
379
380                 /* Write E-fuse Register address bit0~7 */
381                 temp = Address & 0xFF;
382                 rtw_write8(Adapter, EFUSE_CTRL+1, temp);
383                 Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+2);
384
385                 /* Write E-fuse Register address bit8~9 */
386                 temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
387                 rtw_write8(Adapter, EFUSE_CTRL+2, temp);
388
389                 /* Write 0x30[31]=1 */
390                 Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
391                 temp = Bytetemp | 0x80;
392                 rtw_write8(Adapter, EFUSE_CTRL+3, temp);
393
394                 /* Wait Write-ready (0x30[31]=0) */
395                 Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
396                 while(Bytetemp & 0x80)
397                 {
398                         Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
399                         k++;
400                         if(k==100)
401                         {
402                                 k=0;
403                                 break;
404                         }
405                 }
406         }
407 }/* EFUSE_Write1Byte */
408
409 /*  11/16/2008 MH Read one byte from real Efuse. */
410 u8
411 efuse_OneByteRead(
412         PADAPTER        pAdapter,
413         u16                     addr,
414         u8                      *data,
415         bool            bPseudoTest)
416 {
417         u8      tmpidx = 0;
418         u8      bResult;
419
420         if(bPseudoTest)
421         {
422                 bResult = Efuse_Read1ByteFromFakeContent(pAdapter, addr, data);
423                 return bResult;
424         }
425         /*  -----------------e-fuse reg ctrl --------------------------------- */
426         /* address */
427         rtw_write8(pAdapter, EFUSE_CTRL+1, (u8)(addr&0xff));
428         rtw_write8(pAdapter, EFUSE_CTRL+2, ((u8)((addr>>8) &0x03) ) |
429         (rtw_read8(pAdapter, EFUSE_CTRL+2)&0xFC ));
430
431         rtw_write8(pAdapter, EFUSE_CTRL+3,  0x72);/* read cmd */
432
433         while(!(0x80 &rtw_read8(pAdapter, EFUSE_CTRL+3))&&(tmpidx<100))
434         {
435                 tmpidx++;
436         }
437         if(tmpidx<100)
438         {
439                 *data=rtw_read8(pAdapter, EFUSE_CTRL);
440                 bResult = _TRUE;
441         }
442         else
443         {
444                 *data = 0xff;
445                 bResult = _FALSE;
446         }
447         return bResult;
448 }
449
450 /*  11/16/2008 MH Write one byte to reald Efuse. */
451 u8
452 efuse_OneByteWrite(
453         PADAPTER        pAdapter,
454         u16                     addr,
455         u8                      data,
456         bool            bPseudoTest)
457 {
458         u8      tmpidx = 0;
459         u8      bResult;
460
461         if(bPseudoTest)
462         {
463                 bResult = Efuse_Write1ByteToFakeContent(pAdapter, addr, data);
464                 return bResult;
465         }
466         /* RT_TRACE(COMP_EFUSE, DBG_LOUD, ("Addr = %x Data=%x\n", addr, data)); */
467
468         /* return       0; */
469
470         /*  -----------------e-fuse reg ctrl --------------------------------- */
471         /* address */
472         rtw_write8(pAdapter, EFUSE_CTRL+1, (u8)(addr&0xff));
473         rtw_write8(pAdapter, EFUSE_CTRL+2,
474         (rtw_read8(pAdapter, EFUSE_CTRL+2)&0xFC )|(u8)((addr>>8)&0x03) );
475         rtw_write8(pAdapter, EFUSE_CTRL, data);/* data */
476
477         rtw_write8(pAdapter, EFUSE_CTRL+3, 0xF2);/* write cmd */
478
479         while((0x80 &  rtw_read8(pAdapter, EFUSE_CTRL+3)) && (tmpidx<100) ){
480                 tmpidx++;
481         }
482
483         if(tmpidx<100)
484         {
485                 bResult = _TRUE;
486         }
487         else
488         {
489                 bResult = _FALSE;
490         }
491
492         return bResult;
493 }
494
495 int
496 Efuse_PgPacketRead(     PADAPTER        pAdapter,
497                                         u8                      offset,
498                                         u8                      *data,
499                                         bool            bPseudoTest)
500 {
501         int     ret=0;
502
503         ret =  pAdapter->HalFunc.Efuse_PgPacketRead(pAdapter, offset, data, bPseudoTest);
504
505         return ret;
506 }
507
508 int
509 Efuse_PgPacketWrite(PADAPTER pAdapter,
510                     u8                  offset,
511                     u8                  word_en,
512                     u8                  *data,
513                     bool                bPseudoTest)
514 {
515         int ret;
516
517         ret =  pAdapter->HalFunc.Efuse_PgPacketWrite(pAdapter, offset, word_en, data, bPseudoTest);
518
519         return ret;
520 }
521
522 int
523 Efuse_PgPacketWrite_BT(PADAPTER pAdapter,
524                        u8                       offset,
525                        u8                       word_en,
526                        u8                       *data,
527                        bool             bPseudoTest)
528 {
529         int ret;
530
531         ret =  pAdapter->HalFunc.Efuse_PgPacketWrite_BT(pAdapter, offset, word_en, data, bPseudoTest);
532
533         return ret;
534 }
535
536 /*-----------------------------------------------------------------------------
537  * Function:    efuse_WordEnableDataRead
538  *
539  * Overview:    Read allowed word in current efuse section data.
540  *
541  * Input:       NONE
542  *
543  * Output:      NONE
544  *
545  * Return:      NONE
546  *
547  * Revised History:
548  * When                 Who             Remark
549  * 11/16/2008   MHC             Create Version 0.
550  * 11/21/2008   MHC             Fix Write bug when we only enable late word.
551  *
552  *---------------------------------------------------------------------------*/
553 void
554 efuse_WordEnableDataRead(u8     word_en,
555                          u8     *sourdata,
556                          u8     *targetdata)
557 {
558         if (!(word_en&BIT(0)))
559         {
560                 targetdata[0] = sourdata[0];
561                 targetdata[1] = sourdata[1];
562         }
563         if (!(word_en&BIT(1)))
564         {
565                 targetdata[2] = sourdata[2];
566                 targetdata[3] = sourdata[3];
567         }
568         if (!(word_en&BIT(2)))
569         {
570                 targetdata[4] = sourdata[4];
571                 targetdata[5] = sourdata[5];
572         }
573         if (!(word_en&BIT(3)))
574         {
575                 targetdata[6] = sourdata[6];
576                 targetdata[7] = sourdata[7];
577         }
578 }
579
580 u8
581 Efuse_WordEnableDataWrite(      PADAPTER        pAdapter,
582                                                         u16             efuse_addr,
583                                                         u8              word_en,
584                                                         u8              *data,
585                                                         bool            bPseudoTest)
586 {
587         u8      ret=0;
588
589         ret =  pAdapter->HalFunc.Efuse_WordEnableDataWrite(pAdapter, efuse_addr, word_en, data, bPseudoTest);
590
591         return ret;
592 }
593
594 static u8 efuse_read8(PADAPTER padapter, u16 address, u8 *value)
595 {
596         return efuse_OneByteRead(padapter,address, value, _FALSE);
597 }
598
599 static u8 efuse_write8(PADAPTER padapter, u16 address, u8 *value)
600 {
601         return efuse_OneByteWrite(padapter,address, *value, _FALSE);
602 }
603
604 /*
605  * read/wirte raw efuse data
606  */
607 u8 rtw_efuse_access(PADAPTER padapter, u8 bWrite, u16 start_addr, u16 cnts, u8 *data)
608 {
609         int i = 0;
610         u16     real_content_len = 0, max_available_size = 0;
611         u8 res = _FAIL ;
612         u8 (*rw8)(PADAPTER, u16, u8*);
613
614         EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&real_content_len, _FALSE);
615         EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, _FALSE);
616
617         if (start_addr > real_content_len)
618                 return _FAIL;
619
620         if (_TRUE == bWrite) {
621                 if ((start_addr + cnts) > max_available_size)
622                         return _FAIL;
623                 rw8 = &efuse_write8;
624         } else
625                 rw8 = &efuse_read8;
626
627         Efuse_PowerSwitch(padapter, bWrite, _TRUE);
628
629         /*  e-fuse one byte read / write */
630         for (i = 0; i < cnts; i++) {
631                 if (start_addr >= real_content_len) {
632                         res = _FAIL;
633                         break;
634                 }
635
636                 res = rw8(padapter, start_addr++, data++);
637                 if (_FAIL == res) break;
638         }
639
640         Efuse_PowerSwitch(padapter, bWrite, _FALSE);
641
642         return res;
643 }
644 /*  */
645 u16 efuse_GetMaxSize(PADAPTER padapter)
646 {
647         u16     max_size;
648         EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI , TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_size, _FALSE);
649         return max_size;
650 }
651 /*  */
652 u8 efuse_GetCurrentSize(PADAPTER padapter, u16 *size)
653 {
654         Efuse_PowerSwitch(padapter, _FALSE, _TRUE);
655         *size = Efuse_GetCurrentSize(padapter, EFUSE_WIFI, _FALSE);
656         Efuse_PowerSwitch(padapter, _FALSE, _FALSE);
657
658         return _SUCCESS;
659 }
660 /*  */
661 u8 rtw_efuse_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data)
662 {
663         u16     mapLen=0;
664
665         EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, _FALSE);
666
667         if ((addr + cnts) > mapLen)
668                 return _FAIL;
669
670         Efuse_PowerSwitch(padapter, _FALSE, _TRUE);
671
672         efuse_ReadEFuse(padapter, EFUSE_WIFI, addr, cnts, data, _FALSE);
673
674         Efuse_PowerSwitch(padapter, _FALSE, _FALSE);
675
676         return _SUCCESS;
677 }
678
679 u8 rtw_BT_efuse_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data)
680 {
681         u16     mapLen=0;
682
683         EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, _FALSE);
684
685         if ((addr + cnts) > mapLen)
686                 return _FAIL;
687
688         Efuse_PowerSwitch(padapter, _FALSE, _TRUE);
689
690         efuse_ReadEFuse(padapter, EFUSE_BT, addr, cnts, data, _FALSE);
691
692         Efuse_PowerSwitch(padapter, _FALSE, _FALSE);
693
694         return _SUCCESS;
695 }
696 /*  */
697 u8 rtw_efuse_map_write(PADAPTER padapter, u16 addr, u16 cnts, u8 *data)
698 {
699         u8      offset, word_en;
700         u8      *map;
701         u8      newdata[PGPKT_DATA_SIZE + 1];
702         s32     i, j, idx;
703         u8      ret = _SUCCESS;
704         u16     mapLen=0;
705
706         EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, _FALSE);
707
708         if ((addr + cnts) > mapLen)
709                 return _FAIL;
710
711         map = rtw_zmalloc(mapLen);
712         if(map == NULL){
713                 return _FAIL;
714         }
715
716         ret = rtw_efuse_map_read(padapter, 0, mapLen, map);
717         if (ret == _FAIL) goto exit;
718
719         Efuse_PowerSwitch(padapter, _TRUE, _TRUE);
720
721         offset = (addr >> 3);
722         word_en = 0xF;
723         memset(newdata, 0xFF, PGPKT_DATA_SIZE);
724         i = addr & 0x7; /*  index of one package */
725         j = 0;          /*  index of new package */
726         idx = 0;        /*  data index */
727
728         if (i & 0x1) {
729                 /*  odd start */
730                 if (data[idx] != map[addr+idx]) {
731                         word_en &= ~BIT(i >> 1);
732                         newdata[i-1] = map[addr+idx-1];
733                         newdata[i] = data[idx];
734                 }
735                 i++;
736                 idx++;
737         }
738         do {
739                 for (; i < PGPKT_DATA_SIZE; i += 2)
740                 {
741                         if (cnts == idx) break;
742                         if ((cnts - idx) == 1) {
743                                 if (data[idx] != map[addr+idx]) {
744                                         word_en &= ~BIT(i >> 1);
745                                         newdata[i] = data[idx];
746                                         newdata[i+1] = map[addr+idx+1];
747                                 }
748                                 idx++;
749                                 break;
750                         } else {
751                                 if ((data[idx] != map[addr+idx]) ||
752                                     (data[idx+1] != map[addr+idx+1]))
753                                 {
754                                         word_en &= ~BIT(i >> 1);
755                                         newdata[i] = data[idx];
756                                         newdata[i+1] = data[idx + 1];
757                                 }
758                                 idx += 2;
759                         }
760                         if (idx == cnts) break;
761                 }
762
763                 if (word_en != 0xF) {
764                         ret = Efuse_PgPacketWrite(padapter, offset, word_en, newdata, _FALSE);
765                         DBG_8723A("offset=%x \n",offset);
766                         DBG_8723A("word_en=%x \n",word_en);
767
768                         for(i=0;i<PGPKT_DATA_SIZE;i++)
769                         {
770                                 DBG_8723A("data=%x \t",newdata[i]);
771                         }
772                         if (ret == _FAIL) break;
773                 }
774
775                 if (idx == cnts) break;
776
777                 offset++;
778                 i = 0;
779                 j = 0;
780                 word_en = 0xF;
781                 memset(newdata, 0xFF, PGPKT_DATA_SIZE);
782         } while (1);
783
784         Efuse_PowerSwitch(padapter, _TRUE, _FALSE);
785
786 exit:
787
788         rtw_mfree(map, mapLen);
789
790         return ret;
791 }
792
793 /*  */
794 u8 rtw_BT_efuse_map_write(PADAPTER padapter, u16 addr, u16 cnts, u8 *data)
795 {
796         u8      offset, word_en;
797         u8      *map;
798         u8      newdata[PGPKT_DATA_SIZE + 1];
799         s32     i, j, idx;
800         u8      ret = _SUCCESS;
801         u16     mapLen=0;
802
803         EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, _FALSE);
804
805         if ((addr + cnts) > mapLen)
806                 return _FAIL;
807
808         map = rtw_zmalloc(mapLen);
809         if(map == NULL){
810                 return _FAIL;
811         }
812
813         ret = rtw_BT_efuse_map_read(padapter, 0, mapLen, map);
814         if (ret == _FAIL) goto exit;
815
816         Efuse_PowerSwitch(padapter, _TRUE, _TRUE);
817
818         offset = (addr >> 3);
819         word_en = 0xF;
820         memset(newdata, 0xFF, PGPKT_DATA_SIZE);
821         i = addr & 0x7; /*  index of one package */
822         j = 0;          /*  index of new package */
823         idx = 0;        /*  data index */
824
825         if (i & 0x1) {
826                 /*  odd start */
827                 if (data[idx] != map[addr+idx]) {
828                         word_en &= ~BIT(i >> 1);
829                         newdata[i-1] = map[addr+idx-1];
830                         newdata[i] = data[idx];
831                 }
832                 i++;
833                 idx++;
834         }
835         do {
836                 for (; i < PGPKT_DATA_SIZE; i += 2)
837                 {
838                         if (cnts == idx) break;
839                         if ((cnts - idx) == 1) {
840                                 if (data[idx] != map[addr+idx]) {
841                                         word_en &= ~BIT(i >> 1);
842                                         newdata[i] = data[idx];
843                                         newdata[i+1] = map[addr+idx+1];
844                                 }
845                                 idx++;
846                                 break;
847                         } else {
848                                 if ((data[idx] != map[addr+idx]) ||
849                                     (data[idx+1] != map[addr+idx+1]))
850                                 {
851                                         word_en &= ~BIT(i >> 1);
852                                         newdata[i] = data[idx];
853                                         newdata[i+1] = data[idx + 1];
854                                 }
855                                 idx += 2;
856                         }
857                         if (idx == cnts) break;
858                 }
859
860                 if (word_en != 0xF)
861                 {
862                         DBG_8723A("%s: offset=%#X\n", __FUNCTION__, offset);
863                         DBG_8723A("%s: word_en=%#X\n", __FUNCTION__, word_en);
864                         DBG_8723A("%s: data=", __FUNCTION__);
865                         for (i=0; i<PGPKT_DATA_SIZE; i++)
866                         {
867                                 DBG_8723A("0x%02X ", newdata[i]);
868                         }
869                         DBG_8723A("\n");
870
871                         ret = Efuse_PgPacketWrite_BT(padapter, offset, word_en, newdata, _FALSE);
872                         if (ret == _FAIL) break;
873                 }
874
875                 if (idx == cnts) break;
876
877                 offset++;
878                 i = 0;
879                 j = 0;
880                 word_en = 0xF;
881                 memset(newdata, 0xFF, PGPKT_DATA_SIZE);
882         } while (1);
883
884         Efuse_PowerSwitch(padapter, _TRUE, _FALSE);
885
886 exit:
887
888         rtw_mfree(map, mapLen);
889
890         return ret;
891 }
892
893 /*-----------------------------------------------------------------------------
894  * Function:    Efuse_ReadAllMap
895  *
896  * Overview:    Read All Efuse content
897  *
898  * Input:       NONE
899  *
900  * Output:      NONE
901  *
902  * Return:      NONE
903  *
904  * Revised History:
905  * When                 Who             Remark
906  * 11/11/2008   MHC             Create Version 0.
907  *
908  *---------------------------------------------------------------------------*/
909 void
910 Efuse_ReadAllMap(
911                 PADAPTER        pAdapter,
912                 u8              efuseType,
913         u8              *Efuse,
914                 bool            bPseudoTest);
915 void
916 Efuse_ReadAllMap(
917                 PADAPTER        pAdapter,
918                 u8              efuseType,
919         u8              *Efuse,
920                 bool            bPseudoTest)
921 {
922         u16     mapLen=0;
923
924         Efuse_PowerSwitch(pAdapter,_FALSE, _TRUE);
925
926         EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, bPseudoTest);
927
928         efuse_ReadEFuse(pAdapter, efuseType, 0, mapLen, Efuse, bPseudoTest);
929
930         Efuse_PowerSwitch(pAdapter,_FALSE, _FALSE);
931 }
932
933 /*-----------------------------------------------------------------------------
934  * Function:    efuse_ShadowRead1Byte
935  *                      efuse_ShadowRead2Byte
936  *                      efuse_ShadowRead4Byte
937  *
938  * Overview:    Read from efuse init map by one/two/four bytes !!!!!
939  *
940  * Input:       NONE
941  *
942  * Output:      NONE
943  *
944  * Return:      NONE
945  *
946  * Revised History:
947  * When                 Who             Remark
948  * 11/12/2008   MHC             Create Version 0.
949  *
950  *---------------------------------------------------------------------------*/
951 static void
952 efuse_ShadowRead1Byte(
953         PADAPTER        pAdapter,
954         u16             Offset,
955         u8              *Value)
956 {
957         EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
958
959         *Value = pEEPROM->efuse_eeprom_data[Offset];
960 }       /*  EFUSE_ShadowRead1Byte */
961
962 /* Read Two Bytes */
963 static void
964 efuse_ShadowRead2Byte(
965         PADAPTER        pAdapter,
966         u16             Offset,
967         u16             *Value)
968 {
969         EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
970
971         *Value = pEEPROM->efuse_eeprom_data[Offset];
972         *Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8;
973 }       /*  EFUSE_ShadowRead2Byte */
974
975 /* Read Four Bytes */
976 static void
977 efuse_ShadowRead4Byte(
978         PADAPTER        pAdapter,
979         u16             Offset,
980         u32             *Value)
981 {
982         EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
983
984         *Value = pEEPROM->efuse_eeprom_data[Offset];
985         *Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8;
986         *Value |= pEEPROM->efuse_eeprom_data[Offset+2]<<16;
987         *Value |= pEEPROM->efuse_eeprom_data[Offset+3]<<24;
988 }       /*  efuse_ShadowRead4Byte */
989
990 /*-----------------------------------------------------------------------------
991  * Function:    efuse_ShadowWrite1Byte
992  *                      efuse_ShadowWrite2Byte
993  *                      efuse_ShadowWrite4Byte
994  *
995  * Overview:    Write efuse modify map by one/two/four byte.
996  *
997  * Input:       NONE
998  *
999  * Output:      NONE
1000  *
1001  * Return:      NONE
1002  *
1003  * Revised History:
1004  * When                 Who             Remark
1005  * 11/12/2008   MHC             Create Version 0.
1006  *
1007  *---------------------------------------------------------------------------*/
1008 #ifdef PLATFORM
1009 static void
1010 efuse_ShadowWrite1Byte(
1011         PADAPTER        pAdapter,
1012         u16             Offset,
1013         u8              Value);
1014 #endif /* PLATFORM */
1015 static void
1016 efuse_ShadowWrite1Byte(
1017         PADAPTER        pAdapter,
1018         u16             Offset,
1019         u8              Value)
1020 {
1021         EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
1022
1023         pEEPROM->efuse_eeprom_data[Offset] = Value;
1024 }       /*  efuse_ShadowWrite1Byte */
1025
1026 /* Write Two Bytes */
1027 static void
1028 efuse_ShadowWrite2Byte(
1029         PADAPTER        pAdapter,
1030         u16             Offset,
1031         u16             Value)
1032 {
1033         EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
1034
1035         pEEPROM->efuse_eeprom_data[Offset] = Value&0x00FF;
1036         pEEPROM->efuse_eeprom_data[Offset+1] = Value>>8;
1037 }       /*  efuse_ShadowWrite1Byte */
1038
1039 /* Write Four Bytes */
1040 static void
1041 efuse_ShadowWrite4Byte(
1042         PADAPTER        pAdapter,
1043         u16             Offset,
1044         u32             Value)
1045 {
1046         EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
1047
1048         pEEPROM->efuse_eeprom_data[Offset] = (u8)(Value&0x000000FF);
1049         pEEPROM->efuse_eeprom_data[Offset+1] = (u8)((Value>>8)&0x0000FF);
1050         pEEPROM->efuse_eeprom_data[Offset+2] = (u8)((Value>>16)&0x00FF);
1051         pEEPROM->efuse_eeprom_data[Offset+3] = (u8)((Value>>24)&0xFF);
1052 }       /*  efuse_ShadowWrite1Byte */
1053
1054 /*-----------------------------------------------------------------------------
1055  * Function:    EFUSE_ShadowMapUpdate
1056  *
1057  * Overview:    Transfer current EFUSE content to shadow init and modify map.
1058  *
1059  * Input:       NONE
1060  *
1061  * Output:      NONE
1062  *
1063  * Return:      NONE
1064  *
1065  * Revised History:
1066  * When                 Who             Remark
1067  * 11/13/2008   MHC             Create Version 0.
1068  *
1069  *---------------------------------------------------------------------------*/
1070 void EFUSE_ShadowMapUpdate(
1071  PADAPTER       pAdapter,
1072  u8             efuseType,
1073  bool   bPseudoTest)
1074 {
1075         EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
1076         u16     mapLen=0;
1077
1078         EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, bPseudoTest);
1079
1080         if (pEEPROM->bautoload_fail_flag == _TRUE)
1081         {
1082                 memset(pEEPROM->efuse_eeprom_data, 0xFF, mapLen);
1083         }
1084         else
1085         {
1086                 #ifdef CONFIG_ADAPTOR_INFO_CACHING_FILE
1087                 if(_SUCCESS != retriveAdaptorInfoFile(pAdapter->registrypriv.adaptor_info_caching_file_path, pEEPROM)) {
1088                 #endif
1089
1090                 Efuse_ReadAllMap(pAdapter, efuseType, pEEPROM->efuse_eeprom_data, bPseudoTest);
1091
1092                 #ifdef CONFIG_ADAPTOR_INFO_CACHING_FILE
1093                         storeAdaptorInfoFile(pAdapter->registrypriv.adaptor_info_caching_file_path, pEEPROM);
1094                 }
1095                 #endif
1096         }
1097
1098         /* PlatformMoveMemory((void *)&pHalData->EfuseMap[EFUSE_MODIFY_MAP][0], */
1099         /* void *)&pHalData->EfuseMap[EFUSE_INIT_MAP][0], mapLen); */
1100 }/*  EFUSE_ShadowMapUpdate */
1101
1102 /*-----------------------------------------------------------------------------
1103  * Function:    EFUSE_ShadowRead
1104  *
1105  * Overview:    Read from efuse init map !!!!!
1106  *
1107  * Input:       NONE
1108  *
1109  * Output:      NONE
1110  *
1111  * Return:      NONE
1112  *
1113  * Revised History:
1114  * When                 Who             Remark
1115  * 11/12/2008   MHC             Create Version 0.
1116  *
1117  *---------------------------------------------------------------------------*/
1118 void
1119 EFUSE_ShadowRead(
1120         PADAPTER        pAdapter,
1121         u8              Type,
1122         u16             Offset,
1123         u32             *Value  )
1124 {
1125         if (Type == 1)
1126                 efuse_ShadowRead1Byte(pAdapter, Offset, (u8 *)Value);
1127         else if (Type == 2)
1128                 efuse_ShadowRead2Byte(pAdapter, Offset, (u16 *)Value);
1129         else if (Type == 4)
1130                 efuse_ShadowRead4Byte(pAdapter, Offset, (u32 *)Value);
1131 }       /*  EFUSE_ShadowRead */
1132
1133 /*-----------------------------------------------------------------------------
1134  * Function:    EFUSE_ShadowWrite
1135  *
1136  * Overview:    Write efuse modify map for later update operation to use!!!!!
1137  *
1138  * Input:       NONE
1139  *
1140  * Output:      NONE
1141  *
1142  * Return:      NONE
1143  *
1144  * Revised History:
1145  * When                 Who             Remark
1146  * 11/12/2008   MHC             Create Version 0.
1147  *
1148  *---------------------------------------------------------------------------*/
1149 void
1150 EFUSE_ShadowWrite(
1151         PADAPTER        pAdapter,
1152         u8              Type,
1153         u16             Offset,
1154         u32             Value);
1155 void
1156 EFUSE_ShadowWrite(
1157         PADAPTER        pAdapter,
1158         u8              Type,
1159         u16             Offset,
1160         u32             Value)
1161 {
1162         return;
1163 }       /*  EFUSE_ShadowWrite */
1164
1165 void
1166 Efuse_InitSomeVar(
1167                 PADAPTER        pAdapter
1168         );
1169 void
1170 Efuse_InitSomeVar(
1171                 PADAPTER        pAdapter
1172         )
1173 {
1174         u8 i;
1175
1176         memset(&fakeEfuseContent[0], 0xff, EFUSE_MAX_HW_SIZE);
1177         memset(&fakeEfuseInitMap[0], 0xff, EFUSE_MAX_MAP_LEN);
1178         memset(&fakeEfuseModifiedMap[0], 0xff, EFUSE_MAX_MAP_LEN);
1179
1180         for(i=0; i<EFUSE_MAX_BT_BANK; i++)
1181         {
1182                 memset(&BTEfuseContent[i][0], EFUSE_MAX_HW_SIZE, 0xff);
1183         }
1184         memset(&BTEfuseInitMap[0], 0xff, EFUSE_BT_MAX_MAP_LEN);
1185         memset(&BTEfuseModifiedMap[0], 0xff, EFUSE_BT_MAX_MAP_LEN);
1186
1187         for(i=0; i<EFUSE_MAX_BT_BANK; i++)
1188         {
1189                 memset(&fakeBTEfuseContent[i][0], 0xff, EFUSE_MAX_HW_SIZE);
1190         }
1191         memset(&fakeBTEfuseInitMap[0], 0xff, EFUSE_BT_MAX_MAP_LEN);
1192         memset(&fakeBTEfuseModifiedMap[0], 0xff, EFUSE_BT_MAX_MAP_LEN);
1193 }
1194
1195 #ifdef CONFIG_ADAPTOR_INFO_CACHING_FILE
1196 /* include <rtw_eeprom.h> */
1197
1198  int isAdaptorInfoFileValid(void)
1199 {
1200         return _TRUE;
1201 }
1202
1203 int storeAdaptorInfoFile(char *path, struct eeprom_priv * eeprom_priv)
1204 {
1205         int ret =_SUCCESS;
1206
1207         if(path && eeprom_priv) {
1208                 ret = rtw_store_to_file(path, eeprom_priv->efuse_eeprom_data, EEPROM_MAX_SIZE_512);
1209                 if(ret == EEPROM_MAX_SIZE)
1210                         ret = _SUCCESS;
1211                 else
1212                         ret = _FAIL;
1213         } else {
1214                 DBG_8723A("%s NULL pointer\n",__FUNCTION__);
1215                 ret =  _FAIL;
1216         }
1217         return ret;
1218 }
1219
1220 int retriveAdaptorInfoFile(char *path, struct eeprom_priv * eeprom_priv)
1221 {
1222         int ret = _SUCCESS;
1223         mm_segment_t oldfs;
1224         struct file *fp;
1225
1226         if(path && eeprom_priv) {
1227
1228                 ret = rtw_retrive_from_file(path, eeprom_priv->efuse_eeprom_data, EEPROM_MAX_SIZE);
1229
1230                 if(ret == EEPROM_MAX_SIZE)
1231                         ret = _SUCCESS;
1232                 else
1233                         ret = _FAIL;
1234
1235                 #if 0
1236                 if(isAdaptorInfoFileValid()) {
1237                         return 0;
1238                 } else {
1239                         return _FAIL;
1240                 }
1241                 #endif
1242
1243         } else {
1244                 DBG_8723A("%s NULL pointer\n",__FUNCTION__);
1245                 ret = _FAIL;
1246         }
1247         return ret;
1248 }
1249 #endif /* CONFIG_ADAPTOR_INFO_CACHING_FILE */