Merge branch 'for-3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata
[cascardo/linux.git] / drivers / staging / rtl8188eu / 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 <osdep_service.h>
23 #include <drv_types.h>
24 #include <rtw_efuse.h>
25
26
27
28 /*------------------------Define local variable------------------------------*/
29 u8 fakeEfuseBank;
30 u32 fakeEfuseUsedBytes;
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;
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;
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                         struct adapter *pAdapter,
54                         u16 Offset,
55                 u8 *Value);
56 bool
57 Efuse_Read1ByteFromFakeContent(
58                         struct adapter *pAdapter,
59                         u16 Offset,
60                 u8 *Value)
61 {
62         if (Offset >= EFUSE_MAX_HW_SIZE)
63                 return false;
64         if (fakeEfuseBank == 0)
65                 *Value = fakeEfuseContent[Offset];
66         else
67                 *Value = fakeBTEfuseContent[fakeEfuseBank-1][Offset];
68         return true;
69 }
70
71 static bool
72 Efuse_Write1ByteToFakeContent(
73                         struct adapter *pAdapter,
74                         u16 Offset,
75                         u8 Value)
76 {
77         if (Offset >= EFUSE_MAX_HW_SIZE)
78                 return false;
79         if (fakeEfuseBank == 0) {
80                 fakeEfuseContent[Offset] = Value;
81         } else {
82                 fakeBTEfuseContent[fakeEfuseBank-1][Offset] = Value;
83         }
84         return true;
85 }
86
87 /*-----------------------------------------------------------------------------
88  * Function:    Efuse_PowerSwitch
89  *
90  * Overview:    When we want to enable write operation, we should change to
91  *                              pwr on state. When we stop write, we should switch to 500k mode
92  *                              and disable LDO 2.5V.
93  *
94  * Input:       NONE
95  *
96  * Output:      NONE
97  *
98  * Return:      NONE
99  *
100  * Revised History:
101  * When                 Who             Remark
102  * 11/17/2008   MHC             Create Version 0.
103  *
104  *---------------------------------------------------------------------------*/
105 void
106 Efuse_PowerSwitch(
107                 struct adapter *pAdapter,
108                 u8 write,
109                 u8 PwrState)
110 {
111         pAdapter->HalFunc.EfusePowerSwitch(pAdapter, write, PwrState);
112 }
113
114 /*-----------------------------------------------------------------------------
115  * Function:    efuse_GetCurrentSize
116  *
117  * Overview:    Get current efuse size!!!
118  *
119  * Input:       NONE
120  *
121  * Output:      NONE
122  *
123  * Return:      NONE
124  *
125  * Revised History:
126  * When                 Who             Remark
127  * 11/16/2008   MHC             Create Version 0.
128  *
129  *---------------------------------------------------------------------------*/
130 u16
131 Efuse_GetCurrentSize(
132         struct adapter *pAdapter,
133         u8 efuseType,
134         bool pseudo)
135 {
136         u16 ret = 0;
137
138         ret = pAdapter->HalFunc.EfuseGetCurrentSize(pAdapter, efuseType, pseudo);
139
140         return ret;
141 }
142
143 /*  11/16/2008 MH Add description. Get current efuse area enabled word!!. */
144 u8
145 Efuse_CalculateWordCnts(u8 word_en)
146 {
147         u8 word_cnts = 0;
148         if (!(word_en & BIT(0)))
149                 word_cnts++; /*  0 : write enable */
150         if (!(word_en & BIT(1)))
151                 word_cnts++;
152         if (!(word_en & BIT(2)))
153                 word_cnts++;
154         if (!(word_en & BIT(3)))
155                 word_cnts++;
156         return word_cnts;
157 }
158
159 /*  */
160 /*      Description: */
161 /*              Execute E-Fuse read byte operation. */
162 /*              Referred from SD1 Richard. */
163 /*  */
164 /*      Assumption: */
165 /*              1. Boot from E-Fuse and successfully auto-load. */
166 /*              2. PASSIVE_LEVEL (USB interface) */
167 /*  */
168 /*      Created by Roger, 2008.10.21. */
169 /*  */
170 void
171 ReadEFuseByte(
172                 struct adapter *Adapter,
173                 u16 _offset,
174                 u8 *pbuf,
175                 bool pseudo)
176 {
177         u32 value32;
178         u8 readbyte;
179         u16 retry;
180
181         if (pseudo) {
182                 Efuse_Read1ByteFromFakeContent(Adapter, _offset, pbuf);
183                 return;
184         }
185
186         /* Write Address */
187         rtw_write8(Adapter, EFUSE_CTRL+1, (_offset & 0xff));
188         readbyte = rtw_read8(Adapter, EFUSE_CTRL+2);
189         rtw_write8(Adapter, EFUSE_CTRL+2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
190
191         /* Write bit 32 0 */
192         readbyte = rtw_read8(Adapter, EFUSE_CTRL+3);
193         rtw_write8(Adapter, EFUSE_CTRL+3, (readbyte & 0x7f));
194
195         /* Check bit 32 read-ready */
196         retry = 0;
197         value32 = rtw_read32(Adapter, EFUSE_CTRL);
198         while (!(((value32 >> 24) & 0xff) & 0x80)  && (retry < 10000)) {
199                 value32 = rtw_read32(Adapter, EFUSE_CTRL);
200                 retry++;
201         }
202
203         /*  20100205 Joseph: Add delay suggested by SD1 Victor. */
204         /*  This fix the problem that Efuse read error in high temperature condition. */
205         /*  Designer says that there shall be some delay after ready bit is set, or the */
206         /*  result will always stay on last data we read. */
207         udelay(50);
208         value32 = rtw_read32(Adapter, EFUSE_CTRL);
209
210         *pbuf = (u8)(value32 & 0xff);
211 }
212
213 /*  */
214 /*      Description: */
215 /*              1. Execute E-Fuse read byte operation according as map offset and */
216 /*                  save to E-Fuse table. */
217 /*              2. Referred from SD1 Richard. */
218 /*  */
219 /*      Assumption: */
220 /*              1. Boot from E-Fuse and successfully auto-load. */
221 /*              2. PASSIVE_LEVEL (USB interface) */
222 /*  */
223 /*      Created by Roger, 2008.10.21. */
224 /*  */
225 /*      2008/12/12 MH   1. Reorganize code flow and reserve bytes. and add description. */
226 /*                                      2. Add efuse utilization collect. */
227 /*      2008/12/22 MH   Read Efuse must check if we write section 1 data again!!! Sec1 */
228 /*                                      write addr must be after sec5. */
229 /*  */
230
231 static void efuse_ReadEFuse(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool pseudo)
232 {
233         Adapter->HalFunc.ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, pseudo);
234 }
235
236 void EFUSE_GetEfuseDefinition(struct adapter *pAdapter, u8 efuseType, u8 type, void *pOut, bool pseudo
237         )
238 {
239         pAdapter->HalFunc.EFUSEGetEfuseDefinition(pAdapter, efuseType, type, pOut, pseudo);
240 }
241
242 /*-----------------------------------------------------------------------------
243  * Function:    EFUSE_Read1Byte
244  *
245  * Overview:    Copy from WMAC fot EFUSE read 1 byte.
246  *
247  * Input:       NONE
248  *
249  * Output:      NONE
250  *
251  * Return:      NONE
252  *
253  * Revised History:
254  * When                 Who             Remark
255  * 09/23/2008   MHC             Copy from WMAC.
256  *
257  *---------------------------------------------------------------------------*/
258 u8 EFUSE_Read1Byte(struct adapter *Adapter, u16 Address)
259 {
260         u8 data;
261         u8 Bytetemp = {0x00};
262         u8 temp = {0x00};
263         u32 k = 0;
264         u16 contentLen = 0;
265
266         EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI , TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&contentLen, false);
267
268         if (Address < contentLen) {     /* E-fuse 512Byte */
269                 /* Write E-fuse Register address bit0~7 */
270                 temp = Address & 0xFF;
271                 rtw_write8(Adapter, EFUSE_CTRL+1, temp);
272                 Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+2);
273                 /* Write E-fuse Register address bit8~9 */
274                 temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
275                 rtw_write8(Adapter, EFUSE_CTRL+2, temp);
276
277                 /* Write 0x30[31]= 0 */
278                 Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
279                 temp = Bytetemp & 0x7F;
280                 rtw_write8(Adapter, EFUSE_CTRL+3, temp);
281
282                 /* Wait Write-ready (0x30[31]= 1) */
283                 Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
284                 while (!(Bytetemp & 0x80)) {
285                         Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
286                         k++;
287                         if (k == 1000) {
288                                 k = 0;
289                                 break;
290                         }
291                 }
292                 data = rtw_read8(Adapter, EFUSE_CTRL);
293                 return data;
294         } else {
295                 return 0xFF;
296         }
297
298 } /* EFUSE_Read1Byte */
299
300 /*  11/16/2008 MH Read one byte from real Efuse. */
301 u8 efuse_OneByteRead(struct adapter *pAdapter, u16 addr, u8 *data, bool pseudo)
302 {
303         u8 tmpidx = 0;
304         u8 result;
305
306         if (pseudo) {
307                 result = Efuse_Read1ByteFromFakeContent(pAdapter, addr, data);
308                 return result;
309         }
310         /*  -----------------e-fuse reg ctrl --------------------------------- */
311         /* address */
312         rtw_write8(pAdapter, EFUSE_CTRL+1, (u8)(addr & 0xff));
313         rtw_write8(pAdapter, EFUSE_CTRL+2, ((u8)((addr>>8) & 0x03)) |
314                    (rtw_read8(pAdapter, EFUSE_CTRL+2) & 0xFC));
315
316         rtw_write8(pAdapter, EFUSE_CTRL+3,  0x72);/* read cmd */
317
318         while (!(0x80 & rtw_read8(pAdapter, EFUSE_CTRL+3)) && (tmpidx < 100))
319                 tmpidx++;
320         if (tmpidx < 100) {
321                 *data = rtw_read8(pAdapter, EFUSE_CTRL);
322                 result = true;
323         } else {
324                 *data = 0xff;
325                 result = false;
326         }
327         return result;
328 }
329
330 /*  11/16/2008 MH Write one byte to reald Efuse. */
331 u8 efuse_OneByteWrite(struct adapter *pAdapter, u16 addr, u8 data, bool pseudo)
332 {
333         u8 tmpidx = 0;
334         u8 result;
335
336         if (pseudo) {
337                 result = Efuse_Write1ByteToFakeContent(pAdapter, addr, data);
338                 return result;
339         }
340
341         /*  -----------------e-fuse reg ctrl --------------------------------- */
342         /* address */
343         rtw_write8(pAdapter, EFUSE_CTRL+1, (u8)(addr&0xff));
344         rtw_write8(pAdapter, EFUSE_CTRL+2,
345                    (rtw_read8(pAdapter, EFUSE_CTRL+2) & 0xFC) |
346                    (u8)((addr>>8) & 0x03));
347         rtw_write8(pAdapter, EFUSE_CTRL, data);/* data */
348
349         rtw_write8(pAdapter, EFUSE_CTRL+3, 0xF2);/* write cmd */
350
351         while ((0x80 &  rtw_read8(pAdapter, EFUSE_CTRL+3)) && (tmpidx < 100))
352                 tmpidx++;
353
354         if (tmpidx < 100)
355                 result = true;
356         else
357                 result = false;
358
359         return result;
360 }
361
362 int Efuse_PgPacketRead(struct adapter *pAdapter, u8 offset, u8 *data, bool pseudo)
363 {
364         int     ret = 0;
365
366         ret =  pAdapter->HalFunc.Efuse_PgPacketRead(pAdapter, offset, data, pseudo);
367
368         return ret;
369 }
370
371 int Efuse_PgPacketWrite(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *data, bool pseudo)
372 {
373         int ret;
374
375         ret =  pAdapter->HalFunc.Efuse_PgPacketWrite(pAdapter, offset, word_en, data, pseudo);
376
377         return ret;
378 }
379
380
381 static int Efuse_PgPacketWrite_BT(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *data, bool pseudo)
382 {
383         int ret;
384
385         ret =  pAdapter->HalFunc.Efuse_PgPacketWrite_BT(pAdapter, offset, word_en, data, pseudo);
386
387         return ret;
388 }
389
390 /*-----------------------------------------------------------------------------
391  * Function:    efuse_WordEnableDataRead
392  *
393  * Overview:    Read allowed word in current efuse section data.
394  *
395  * Input:       NONE
396  *
397  * Output:      NONE
398  *
399  * Return:      NONE
400  *
401  * Revised History:
402  * When                 Who             Remark
403  * 11/16/2008   MHC             Create Version 0.
404  * 11/21/2008   MHC             Fix Write bug when we only enable late word.
405  *
406  *---------------------------------------------------------------------------*/
407 void efuse_WordEnableDataRead(u8 word_en, u8 *sourdata, u8 *targetdata)
408 {
409         if (!(word_en&BIT(0))) {
410                 targetdata[0] = sourdata[0];
411                 targetdata[1] = sourdata[1];
412         }
413         if (!(word_en&BIT(1))) {
414                 targetdata[2] = sourdata[2];
415                 targetdata[3] = sourdata[3];
416         }
417         if (!(word_en&BIT(2))) {
418                 targetdata[4] = sourdata[4];
419                 targetdata[5] = sourdata[5];
420         }
421         if (!(word_en&BIT(3))) {
422                 targetdata[6] = sourdata[6];
423                 targetdata[7] = sourdata[7];
424         }
425 }
426
427 u8 Efuse_WordEnableDataWrite(struct adapter *pAdapter, u16 efuse_addr, u8 word_en, u8 *data, bool pseudo)
428 {
429         u8 ret = 0;
430
431         ret =  pAdapter->HalFunc.Efuse_WordEnableDataWrite(pAdapter, efuse_addr, word_en, data, pseudo);
432
433         return ret;
434 }
435
436 static u8 efuse_read8(struct adapter *padapter, u16 address, u8 *value)
437 {
438         return efuse_OneByteRead(padapter, address, value, false);
439 }
440
441 static u8 efuse_write8(struct adapter *padapter, u16 address, u8 *value)
442 {
443         return efuse_OneByteWrite(padapter, address, *value, false);
444 }
445
446 /*
447  * read/wirte raw efuse data
448  */
449 u8 rtw_efuse_access(struct adapter *padapter, u8 write, u16 start_addr, u16 cnts, u8 *data)
450 {
451         int i = 0;
452         u16 real_content_len = 0, max_available_size = 0;
453         u8 res = _FAIL ;
454         u8 (*rw8)(struct adapter *, u16, u8*);
455
456         EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&real_content_len, false);
457         EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false);
458
459         if (start_addr > real_content_len)
460                 return _FAIL;
461
462         if (write) {
463                 if ((start_addr + cnts) > max_available_size)
464                         return _FAIL;
465                 rw8 = &efuse_write8;
466         } else {
467                 rw8 = &efuse_read8;
468         }
469
470         Efuse_PowerSwitch(padapter, write, true);
471
472         /*  e-fuse one byte read / write */
473         for (i = 0; i < cnts; i++) {
474                 if (start_addr >= real_content_len) {
475                         res = _FAIL;
476                         break;
477                 }
478
479                 res = rw8(padapter, start_addr++, data++);
480                 if (_FAIL == res)
481                         break;
482         }
483
484         Efuse_PowerSwitch(padapter, write, false);
485
486         return res;
487 }
488 /*  */
489 u16 efuse_GetMaxSize(struct adapter *padapter)
490 {
491         u16 max_size;
492         EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI , TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_size, false);
493         return max_size;
494 }
495 /*  */
496 u8 efuse_GetCurrentSize(struct adapter *padapter, u16 *size)
497 {
498         Efuse_PowerSwitch(padapter, false, true);
499         *size = Efuse_GetCurrentSize(padapter, EFUSE_WIFI, false);
500         Efuse_PowerSwitch(padapter, false, false);
501
502         return _SUCCESS;
503 }
504 /*  */
505 u8 rtw_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
506 {
507         u16 mapLen = 0;
508
509         EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false);
510
511         if ((addr + cnts) > mapLen)
512                 return _FAIL;
513
514         Efuse_PowerSwitch(padapter, false, true);
515
516         efuse_ReadEFuse(padapter, EFUSE_WIFI, addr, cnts, data, false);
517
518         Efuse_PowerSwitch(padapter, false, false);
519
520         return _SUCCESS;
521 }
522
523 u8 rtw_BT_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
524 {
525         u16 mapLen = 0;
526
527         EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false);
528
529         if ((addr + cnts) > mapLen)
530                 return _FAIL;
531
532         Efuse_PowerSwitch(padapter, false, true);
533
534         efuse_ReadEFuse(padapter, EFUSE_BT, addr, cnts, data, false);
535
536         Efuse_PowerSwitch(padapter, false, false);
537
538         return _SUCCESS;
539 }
540 /*  */
541 u8 rtw_efuse_map_write(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
542 {
543         u8 offset, word_en;
544         u8 *map;
545         u8 newdata[PGPKT_DATA_SIZE + 1];
546         s32     i, idx;
547         u8 ret = _SUCCESS;
548         u16 mapLen = 0;
549
550         EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false);
551
552         if ((addr + cnts) > mapLen)
553                 return _FAIL;
554
555         map = rtw_zmalloc(mapLen);
556         if (map == NULL)
557                 return _FAIL;
558
559         ret = rtw_efuse_map_read(padapter, 0, mapLen, map);
560         if (ret == _FAIL)
561                 goto exit;
562
563         Efuse_PowerSwitch(padapter, true, true);
564
565         offset = (addr >> 3);
566         word_en = 0xF;
567         _rtw_memset(newdata, 0xFF, PGPKT_DATA_SIZE + 1);
568         i = addr & 0x7; /*  index of one package */
569         idx = 0;        /*  data index */
570
571         if (i & 0x1) {
572                 /*  odd start */
573                 if (data[idx] != map[addr+idx]) {
574                         word_en &= ~BIT(i >> 1);
575                         newdata[i-1] = map[addr+idx-1];
576                         newdata[i] = data[idx];
577                 }
578                 i++;
579                 idx++;
580         }
581         do {
582                 for (; i < PGPKT_DATA_SIZE; i += 2) {
583                         if (cnts == idx)
584                                 break;
585                         if ((cnts - idx) == 1) {
586                                 if (data[idx] != map[addr+idx]) {
587                                         word_en &= ~BIT(i >> 1);
588                                         newdata[i] = data[idx];
589                                         newdata[i+1] = map[addr+idx+1];
590                                 }
591                                 idx++;
592                                 break;
593                         } else {
594                                 if ((data[idx] != map[addr+idx]) ||
595                                     (data[idx+1] != map[addr+idx+1])) {
596                                         word_en &= ~BIT(i >> 1);
597                                         newdata[i] = data[idx];
598                                         newdata[i+1] = data[idx + 1];
599                                 }
600                                 idx += 2;
601                         }
602                         if (idx == cnts)
603                                 break;
604                 }
605
606                 if (word_en != 0xF) {
607                         ret = Efuse_PgPacketWrite(padapter, offset, word_en, newdata, false);
608                         DBG_88E("offset=%x\n", offset);
609                         DBG_88E("word_en=%x\n", word_en);
610
611                         for (i = 0; i < PGPKT_DATA_SIZE; i++)
612                                 DBG_88E("data=%x \t", newdata[i]);
613                         if (ret == _FAIL)
614                                 break;
615                 }
616
617                 if (idx == cnts)
618                         break;
619
620                 offset++;
621                 i = 0;
622                 word_en = 0xF;
623                 _rtw_memset(newdata, 0xFF, PGPKT_DATA_SIZE);
624         } while (1);
625
626         Efuse_PowerSwitch(padapter, true, false);
627 exit:
628         kfree(map);
629         return ret;
630 }
631
632 /*  */
633 u8 rtw_BT_efuse_map_write(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
634 {
635         u8 offset, word_en;
636         u8 *map;
637         u8 newdata[PGPKT_DATA_SIZE + 1];
638         s32     i, idx;
639         u8 ret = _SUCCESS;
640         u16 mapLen = 0;
641
642         EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false);
643
644         if ((addr + cnts) > mapLen)
645                 return _FAIL;
646
647         map = rtw_zmalloc(mapLen);
648         if (map == NULL)
649                 return _FAIL;
650
651         ret = rtw_BT_efuse_map_read(padapter, 0, mapLen, map);
652         if (ret == _FAIL)
653                 goto exit;
654
655         Efuse_PowerSwitch(padapter, true, true);
656
657         offset = (addr >> 3);
658         word_en = 0xF;
659         _rtw_memset(newdata, 0xFF, PGPKT_DATA_SIZE + 1);
660         i = addr & 0x7; /*  index of one package */
661         idx = 0;        /*  data index */
662
663         if (i & 0x1) {
664                 /*  odd start */
665                 if (data[idx] != map[addr+idx]) {
666                         word_en &= ~BIT(i >> 1);
667                         newdata[i-1] = map[addr+idx-1];
668                         newdata[i] = data[idx];
669                 }
670                 i++;
671                 idx++;
672         }
673         do {
674                 for (; i < PGPKT_DATA_SIZE; i += 2) {
675                         if (cnts == idx)
676                                 break;
677                         if ((cnts - idx) == 1) {
678                                 if (data[idx] != map[addr+idx]) {
679                                         word_en &= ~BIT(i >> 1);
680                                         newdata[i] = data[idx];
681                                         newdata[i+1] = map[addr+idx+1];
682                                 }
683                                 idx++;
684                                 break;
685                         } else {
686                                 if ((data[idx] != map[addr+idx]) ||
687                                     (data[idx+1] != map[addr+idx+1])) {
688                                         word_en &= ~BIT(i >> 1);
689                                         newdata[i] = data[idx];
690                                         newdata[i+1] = data[idx + 1];
691                                 }
692                                 idx += 2;
693                         }
694                         if (idx == cnts)
695                                 break;
696                 }
697
698                 if (word_en != 0xF) {
699                         DBG_88E("%s: offset=%#X\n", __func__, offset);
700                         DBG_88E("%s: word_en=%#X\n", __func__, word_en);
701                         DBG_88E("%s: data=", __func__);
702                         for (i = 0; i < PGPKT_DATA_SIZE; i++)
703                                 DBG_88E("0x%02X ", newdata[i]);
704                         DBG_88E("\n");
705
706                         ret = Efuse_PgPacketWrite_BT(padapter, offset, word_en, newdata, false);
707                         if (ret == _FAIL)
708                                 break;
709                 }
710
711                 if (idx == cnts)
712                         break;
713
714                 offset++;
715                 i = 0;
716                 word_en = 0xF;
717                 _rtw_memset(newdata, 0xFF, PGPKT_DATA_SIZE);
718         } while (1);
719
720         Efuse_PowerSwitch(padapter, true, false);
721
722 exit:
723
724         kfree(map);
725
726         return ret;
727 }
728
729 /*-----------------------------------------------------------------------------
730  * Function:    efuse_ShadowRead1Byte
731  *                      efuse_ShadowRead2Byte
732  *                      efuse_ShadowRead4Byte
733  *
734  * Overview:    Read from efuse init map by one/two/four bytes !!!!!
735  *
736  * Input:       NONE
737  *
738  * Output:      NONE
739  *
740  * Return:      NONE
741  *
742  * Revised History:
743  * When                 Who             Remark
744  * 11/12/2008   MHC             Create Version 0.
745  *
746  *---------------------------------------------------------------------------*/
747 static void
748 efuse_ShadowRead1Byte(
749                 struct adapter *pAdapter,
750                 u16 Offset,
751                 u8 *Value)
752 {
753         struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
754
755         *Value = pEEPROM->efuse_eeprom_data[Offset];
756
757 }       /*  EFUSE_ShadowRead1Byte */
758
759 /* Read Two Bytes */
760 static void
761 efuse_ShadowRead2Byte(
762                 struct adapter *pAdapter,
763                 u16 Offset,
764                 u16 *Value)
765 {
766         struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
767
768         *Value = pEEPROM->efuse_eeprom_data[Offset];
769         *Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8;
770
771 }       /*  EFUSE_ShadowRead2Byte */
772
773 /* Read Four Bytes */
774 static void
775 efuse_ShadowRead4Byte(
776                 struct adapter *pAdapter,
777                 u16 Offset,
778                 u32 *Value)
779 {
780         struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
781
782         *Value = pEEPROM->efuse_eeprom_data[Offset];
783         *Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8;
784         *Value |= pEEPROM->efuse_eeprom_data[Offset+2]<<16;
785         *Value |= pEEPROM->efuse_eeprom_data[Offset+3]<<24;
786
787 }       /*  efuse_ShadowRead4Byte */
788
789 /*-----------------------------------------------------------------------------
790  * Function:    Efuse_ReadAllMap
791  *
792  * Overview:    Read All Efuse content
793  *
794  * Input:       NONE
795  *
796  * Output:      NONE
797  *
798  * Return:      NONE
799  *
800  * Revised History:
801  * When                 Who             Remark
802  * 11/11/2008   MHC             Create Version 0.
803  *
804  *---------------------------------------------------------------------------*/
805 static void Efuse_ReadAllMap(struct adapter *pAdapter, u8 efuseType, u8 *Efuse, bool pseudo)
806 {
807         u16 mapLen = 0;
808
809         Efuse_PowerSwitch(pAdapter, false, true);
810
811         EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, pseudo);
812
813         efuse_ReadEFuse(pAdapter, efuseType, 0, mapLen, Efuse, pseudo);
814
815         Efuse_PowerSwitch(pAdapter, false, false);
816 }
817
818 /*-----------------------------------------------------------------------------
819  * Function:    EFUSE_ShadowMapUpdate
820  *
821  * Overview:    Transfer current EFUSE content to shadow init and modify map.
822  *
823  * Input:       NONE
824  *
825  * Output:      NONE
826  *
827  * Return:      NONE
828  *
829  * Revised History:
830  * When                 Who             Remark
831  * 11/13/2008   MHC             Create Version 0.
832  *
833  *---------------------------------------------------------------------------*/
834 void EFUSE_ShadowMapUpdate(
835         struct adapter *pAdapter,
836         u8 efuseType,
837         bool pseudo)
838 {
839         struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
840         u16 mapLen = 0;
841
842         EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, pseudo);
843
844         if (pEEPROM->bautoload_fail_flag)
845                 _rtw_memset(pEEPROM->efuse_eeprom_data, 0xFF, mapLen);
846         else
847                 Efuse_ReadAllMap(pAdapter, efuseType, pEEPROM->efuse_eeprom_data, pseudo);
848 } /*  EFUSE_ShadowMapUpdate */
849
850 /*-----------------------------------------------------------------------------
851  * Function:    EFUSE_ShadowRead
852  *
853  * Overview:    Read from efuse init map !!!!!
854  *
855  * Input:       NONE
856  *
857  * Output:      NONE
858  *
859  * Return:      NONE
860  *
861  * Revised History:
862  * When                 Who             Remark
863  * 11/12/2008   MHC             Create Version 0.
864  *
865  *---------------------------------------------------------------------------*/
866 void EFUSE_ShadowRead(struct adapter *pAdapter, u8 Type, u16 Offset, u32 *Value)
867 {
868         if (Type == 1)
869                 efuse_ShadowRead1Byte(pAdapter, Offset, (u8 *)Value);
870         else if (Type == 2)
871                 efuse_ShadowRead2Byte(pAdapter, Offset, (u16 *)Value);
872         else if (Type == 4)
873                 efuse_ShadowRead4Byte(pAdapter, Offset, (u32 *)Value);
874
875 }       /*  EFUSE_ShadowRead */