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