Merge branch 'linux-next' of git://git.infradead.org/ubi-2.6
[linux-2.6] / drivers / staging / rt3070 / common / eeprom.c
1 /*
2  *************************************************************************
3  * Ralink Tech Inc.
4  * 5F., No.36, Taiyuan St., Jhubei City,
5  * Hsinchu County 302,
6  * Taiwan, R.O.C.
7  *
8  * (c) Copyright 2002-2007, Ralink Technology, Inc.
9  *
10  * This program is free software; you can redistribute it and/or modify  *
11  * it under the terms of the GNU General Public License as published by  *
12  * the Free Software Foundation; either version 2 of the License, or     *
13  * (at your option) any later version.                                   *
14  *                                                                       *
15  * This program is distributed in the hope that it will be useful,       *
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18  * GNU General Public License for more details.                          *
19  *                                                                       *
20  * You should have received a copy of the GNU General Public License     *
21  * along with this program; if not, write to the                         *
22  * Free Software Foundation, Inc.,                                       *
23  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
24  *                                                                       *
25  *************************************************************************
26
27         Module Name:
28         eeprom.c
29
30         Abstract:
31
32         Revision History:
33         Who                     When                    What
34         --------        ----------              ----------------------------------------------
35         Name            Date                    Modification logs
36 */
37 #include        "../rt_config.h"
38
39 // IRQL = PASSIVE_LEVEL
40 VOID RaiseClock(
41     IN  PRTMP_ADAPTER   pAd,
42     IN  UINT32 *x)
43 {
44     *x = *x | EESK;
45     RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
46     RTMPusecDelay(1);                           // Max frequency = 1MHz in Spec. definition
47 }
48
49 // IRQL = PASSIVE_LEVEL
50 VOID LowerClock(
51     IN  PRTMP_ADAPTER   pAd,
52     IN  UINT32 *x)
53 {
54     *x = *x & ~EESK;
55     RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
56     RTMPusecDelay(1);
57 }
58
59 // IRQL = PASSIVE_LEVEL
60 USHORT ShiftInBits(
61     IN  PRTMP_ADAPTER   pAd)
62 {
63     UINT32              x,i;
64         USHORT      data=0;
65
66     RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
67
68     x &= ~( EEDO | EEDI);
69
70     for(i=0; i<16; i++)
71     {
72         data = data << 1;
73         RaiseClock(pAd, &x);
74
75         RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
76                 LowerClock(pAd, &x); //prevent read failed
77
78         x &= ~(EEDI);
79         if(x & EEDO)
80             data |= 1;
81     }
82
83     return data;
84 }
85
86 // IRQL = PASSIVE_LEVEL
87 VOID ShiftOutBits(
88     IN  PRTMP_ADAPTER   pAd,
89     IN  USHORT data,
90     IN  USHORT count)
91 {
92     UINT32       x,mask;
93
94     mask = 0x01 << (count - 1);
95     RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
96
97     x &= ~(EEDO | EEDI);
98
99     do
100     {
101         x &= ~EEDI;
102         if(data & mask)         x |= EEDI;
103
104         RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
105
106         RaiseClock(pAd, &x);
107         LowerClock(pAd, &x);
108
109         mask = mask >> 1;
110     } while(mask);
111
112     x &= ~EEDI;
113     RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
114 }
115
116 // IRQL = PASSIVE_LEVEL
117 VOID EEpromCleanup(
118     IN  PRTMP_ADAPTER   pAd)
119 {
120     UINT32 x;
121
122     RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
123
124     x &= ~(EECS | EEDI);
125     RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
126
127     RaiseClock(pAd, &x);
128     LowerClock(pAd, &x);
129 }
130
131 VOID EWEN(
132         IN      PRTMP_ADAPTER   pAd)
133 {
134     UINT32      x;
135
136     // reset bits and set EECS
137     RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
138     x &= ~(EEDI | EEDO | EESK);
139     x |= EECS;
140     RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
141
142         // kick a pulse
143         RaiseClock(pAd, &x);
144         LowerClock(pAd, &x);
145
146     // output the read_opcode and six pulse in that order
147     ShiftOutBits(pAd, EEPROM_EWEN_OPCODE, 5);
148     ShiftOutBits(pAd, 0, 6);
149
150     EEpromCleanup(pAd);
151 }
152
153 VOID EWDS(
154         IN      PRTMP_ADAPTER   pAd)
155 {
156     UINT32      x;
157
158     // reset bits and set EECS
159     RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
160     x &= ~(EEDI | EEDO | EESK);
161     x |= EECS;
162     RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
163
164         // kick a pulse
165         RaiseClock(pAd, &x);
166         LowerClock(pAd, &x);
167
168     // output the read_opcode and six pulse in that order
169     ShiftOutBits(pAd, EEPROM_EWDS_OPCODE, 5);
170     ShiftOutBits(pAd, 0, 6);
171
172     EEpromCleanup(pAd);
173 }
174
175 // IRQL = PASSIVE_LEVEL
176 USHORT RTMP_EEPROM_READ16(
177     IN  PRTMP_ADAPTER   pAd,
178     IN  USHORT Offset)
179 {
180     UINT32              x;
181     USHORT              data;
182
183         if (pAd->NicConfig2.field.AntDiversity)
184     {
185         pAd->EepromAccess = TRUE;
186     }
187 //2008/09/11:KH add to support efuse<--
188 //2008/09/11:KH add to support efuse-->
189 {
190     Offset /= 2;
191     // reset bits and set EECS
192     RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
193     x &= ~(EEDI | EEDO | EESK);
194     x |= EECS;
195     RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
196
197         // patch can not access e-Fuse issue
198     if (!IS_RT3090(pAd))
199     {
200         // kick a pulse
201         RaiseClock(pAd, &x);
202         LowerClock(pAd, &x);
203     }
204
205     // output the read_opcode and register number in that order
206     ShiftOutBits(pAd, EEPROM_READ_OPCODE, 3);
207     ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
208
209     // Now read the data (16 bits) in from the selected EEPROM word
210     data = ShiftInBits(pAd);
211
212     EEpromCleanup(pAd);
213
214         // Antenna and EEPROM access are both using EESK pin,
215     // Therefor we should avoid accessing EESK at the same time
216     // Then restore antenna after EEPROM access
217         if ((pAd->NicConfig2.field.AntDiversity) || (pAd->RfIcType == RFIC_3020))
218     {
219             pAd->EepromAccess = FALSE;
220             AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
221     }
222 }
223     return data;
224 }       //ReadEEprom
225
226 VOID RTMP_EEPROM_WRITE16(
227     IN  PRTMP_ADAPTER   pAd,
228     IN  USHORT Offset,
229     IN  USHORT Data)
230 {
231     UINT32 x;
232
233         if (pAd->NicConfig2.field.AntDiversity)
234     {
235         pAd->EepromAccess = TRUE;
236     }
237         //2008/09/11:KH add to support efuse<--
238 //2008/09/11:KH add to support efuse-->
239         {
240         Offset /= 2;
241
242         EWEN(pAd);
243
244     // reset bits and set EECS
245     RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
246     x &= ~(EEDI | EEDO | EESK);
247     x |= EECS;
248     RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
249
250         // patch can not access e-Fuse issue
251     if (!IS_RT3090(pAd))
252     {
253         // kick a pulse
254         RaiseClock(pAd, &x);
255         LowerClock(pAd, &x);
256     }
257
258     // output the read_opcode ,register number and data in that order
259     ShiftOutBits(pAd, EEPROM_WRITE_OPCODE, 3);
260     ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
261         ShiftOutBits(pAd, Data, 16);            // 16-bit access
262
263     // read DO status
264     RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
265
266         EEpromCleanup(pAd);
267
268         RTMPusecDelay(10000);   //delay for twp(MAX)=10ms
269
270         EWDS(pAd);
271
272     EEpromCleanup(pAd);
273
274         // Antenna and EEPROM access are both using EESK pin,
275     // Therefor we should avoid accessing EESK at the same time
276     // Then restore antenna after EEPROM access
277         if ((pAd->NicConfig2.field.AntDiversity) || (pAd->RfIcType == RFIC_3020))
278     {
279             pAd->EepromAccess = FALSE;
280             AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
281     }
282 }
283 }
284
285 //2008/09/11:KH add to support efuse<--
286 #ifdef RT30xx
287 /*
288         ========================================================================
289
290         Routine Description:
291
292         Arguments:
293
294         Return Value:
295
296         IRQL =
297
298         Note:
299
300         ========================================================================
301 */
302 UCHAR eFuseReadRegisters(
303         IN      PRTMP_ADAPTER   pAd,
304         IN      USHORT Offset,
305         IN      USHORT Length,
306         OUT     USHORT* pData)
307 {
308         EFUSE_CTRL_STRUC                eFuseCtrlStruc;
309         int     i;
310         USHORT  efuseDataOffset;
311         UINT32  data;
312
313         RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
314
315         //Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
316         //Use the eeprom logical address and covert to address to block number
317         eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
318
319         //Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 0.
320         eFuseCtrlStruc.field.EFSROM_MODE = 0;
321
322         //Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
323         eFuseCtrlStruc.field.EFSROM_KICK = 1;
324
325         NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
326         RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
327
328         //Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
329         i = 0;
330         while(i < 100)
331         {
332                 //rtmp.HwMemoryReadDword(EFUSE_CTRL, (DWORD *) &eFuseCtrlStruc, 4);
333                 RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
334                 if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
335                 {
336                         break;
337                 }
338                 RTMPusecDelay(2);
339                 i++;
340         }
341
342         //if EFSROM_AOUT is not found in physical address, write 0xffff
343         if (eFuseCtrlStruc.field.EFSROM_AOUT == 0x3f)
344         {
345                 for(i=0; i<Length/2; i++)
346                         *(pData+2*i) = 0xffff;
347         }
348         else
349         {
350                 //Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x590-0x59C)
351                 efuseDataOffset =  EFUSE_DATA3 - (Offset & 0xC)  ;
352                 //data hold 4 bytes data.
353                 //In RTMP_IO_READ32 will automatically execute 32-bytes swapping
354                 RTMP_IO_READ32(pAd, efuseDataOffset, &data);
355                 //Decide the upper 2 bytes or the bottom 2 bytes.
356                 // Little-endian                S       |       S       Big-endian
357                 // addr 3       2       1       0       |       0       1       2       3
358                 // Ori-V        D       C       B       A       |       A       B       C       D
359                 //After swapping
360                 //              D       C       B       A       |       D       C       B       A
361                 //Return 2-bytes
362                 //The return byte statrs from S. Therefore, the little-endian will return BA, the Big-endian will return DC.
363                 //For returning the bottom 2 bytes, the Big-endian should shift right 2-bytes.
364 #ifdef RT_BIG_ENDIAN
365                 data = data << (8*((Offset & 0x3)^0x2));
366 #else
367                 data = data >> (8*(Offset & 0x3));
368 #endif
369
370                 NdisMoveMemory(pData, &data, Length);
371         }
372
373         return (UCHAR) eFuseCtrlStruc.field.EFSROM_AOUT;
374
375 }
376
377 /*
378         ========================================================================
379
380         Routine Description:
381
382         Arguments:
383
384         Return Value:
385
386         IRQL =
387
388         Note:
389
390         ========================================================================
391 */
392 VOID eFusePhysicalReadRegisters(
393         IN      PRTMP_ADAPTER   pAd,
394         IN      USHORT Offset,
395         IN      USHORT Length,
396         OUT     USHORT* pData)
397 {
398         EFUSE_CTRL_STRUC                eFuseCtrlStruc;
399         int     i;
400         USHORT  efuseDataOffset;
401         UINT32  data;
402
403         RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
404
405         //Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
406         eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
407
408         //Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
409         //Read in physical view
410         eFuseCtrlStruc.field.EFSROM_MODE = 1;
411
412         //Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
413         eFuseCtrlStruc.field.EFSROM_KICK = 1;
414
415         NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
416         RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
417
418         //Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
419         i = 0;
420         while(i < 100)
421         {
422                 RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
423                 if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
424                         break;
425                 RTMPusecDelay(2);
426                 i++;
427         }
428
429         //Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
430         //Because the size of each EFUSE_DATA is 4 Bytes, the size of address of each is 2 bits.
431         //The previous 2 bits is the EFUSE_DATA number, the last 2 bits is used to decide which bytes
432         //Decide which EFUSE_DATA to read
433         //590:F E D C
434         //594:B A 9 8
435         //598:7 6 5 4
436         //59C:3 2 1 0
437         efuseDataOffset =  EFUSE_DATA3 - (Offset & 0xC)  ;
438
439         RTMP_IO_READ32(pAd, efuseDataOffset, &data);
440
441 #ifdef RT_BIG_ENDIAN
442                 data = data << (8*((Offset & 0x3)^0x2));
443 #else
444         data = data >> (8*(Offset & 0x3));
445 #endif
446
447         NdisMoveMemory(pData, &data, Length);
448
449 }
450
451 /*
452         ========================================================================
453
454         Routine Description:
455
456         Arguments:
457
458         Return Value:
459
460         IRQL =
461
462         Note:
463
464         ========================================================================
465 */
466 VOID eFuseReadPhysical(
467         IN      PRTMP_ADAPTER   pAd,
468         IN      PUSHORT lpInBuffer,
469         IN      ULONG nInBufferSize,
470         OUT     PUSHORT lpOutBuffer,
471         IN      ULONG nOutBufferSize
472 )
473 {
474         USHORT* pInBuf = (USHORT*)lpInBuffer;
475         USHORT* pOutBuf = (USHORT*)lpOutBuffer;
476
477         USHORT Offset = pInBuf[0];                                      //addr
478         USHORT Length = pInBuf[1];                                      //length
479         int             i;
480
481         for(i=0; i<Length; i+=2)
482         {
483                 eFusePhysicalReadRegisters(pAd,Offset+i, 2, &pOutBuf[i/2]);
484         }
485 }
486
487 /*
488         ========================================================================
489
490         Routine Description:
491
492         Arguments:
493
494         Return Value:
495
496         IRQL =
497
498         Note:
499
500         ========================================================================
501 */
502 NTSTATUS eFuseRead(
503         IN      PRTMP_ADAPTER   pAd,
504         IN      USHORT                  Offset,
505         OUT     PUCHAR                  pData,
506         IN      USHORT                  Length)
507 {
508         USHORT* pOutBuf = (USHORT*)pData;
509         NTSTATUS        Status = STATUS_SUCCESS;
510         UCHAR   EFSROM_AOUT;
511         int     i;
512
513         for(i=0; i<Length; i+=2)
514         {
515                 EFSROM_AOUT = eFuseReadRegisters(pAd, Offset+i, 2, &pOutBuf[i/2]);
516         }
517         return Status;
518 }
519
520 /*
521         ========================================================================
522
523         Routine Description:
524
525         Arguments:
526
527         Return Value:
528
529         IRQL =
530
531         Note:
532
533         ========================================================================
534 */
535 VOID eFusePhysicalWriteRegisters(
536         IN      PRTMP_ADAPTER   pAd,
537         IN      USHORT Offset,
538         IN      USHORT Length,
539         OUT     USHORT* pData)
540 {
541         EFUSE_CTRL_STRUC                eFuseCtrlStruc;
542         int     i;
543         USHORT  efuseDataOffset;
544         UINT32  data, eFuseDataBuffer[4];
545
546         //Step0. Write 16-byte of data to EFUSE_DATA0-3 (0x590-0x59C), where EFUSE_DATA0 is the LSB DW, EFUSE_DATA3 is the MSB DW.
547
548         /////////////////////////////////////////////////////////////////
549         //read current values of 16-byte block
550         RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
551
552         //Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
553         eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
554
555         //Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
556         eFuseCtrlStruc.field.EFSROM_MODE = 1;
557
558         //Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
559         eFuseCtrlStruc.field.EFSROM_KICK = 1;
560
561         NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
562         RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
563
564         //Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
565         i = 0;
566         while(i < 100)
567         {
568                 RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
569
570                 if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
571                         break;
572                 RTMPusecDelay(2);
573                 i++;
574         }
575
576         //Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
577         efuseDataOffset =  EFUSE_DATA3;
578         for(i=0; i< 4; i++)
579         {
580                 RTMP_IO_READ32(pAd, efuseDataOffset, (PUINT32) &eFuseDataBuffer[i]);
581                 efuseDataOffset -=  4;
582         }
583
584         //Update the value, the offset is multiple of 2, length is 2
585         efuseDataOffset = (Offset & 0xc) >> 2;
586         data = pData[0] & 0xffff;
587         //The offset should be 0x***10 or 0x***00
588         if((Offset % 4) != 0)
589         {
590                 eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff) | (data << 16);
591         }
592         else
593         {
594                 eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff0000) | data;
595         }
596
597         efuseDataOffset =  EFUSE_DATA3;
598         for(i=0; i< 4; i++)
599         {
600                 RTMP_IO_WRITE32(pAd, efuseDataOffset, eFuseDataBuffer[i]);
601                 efuseDataOffset -= 4;
602         }
603         /////////////////////////////////////////////////////////////////
604
605         //Step1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
606         eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
607
608         //Step2. Write EFSROM_MODE (0x580, bit7:bit6) to 3.
609         eFuseCtrlStruc.field.EFSROM_MODE = 3;
610
611         //Step3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure.
612         eFuseCtrlStruc.field.EFSROM_KICK = 1;
613
614         NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
615         RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
616
617         //Step4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It¡¦s done.
618         i = 0;
619         while(i < 100)
620         {
621                 RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
622
623                 if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
624                         break;
625
626                 RTMPusecDelay(2);
627                 i++;
628         }
629 }
630
631 /*
632         ========================================================================
633
634         Routine Description:
635
636         Arguments:
637
638         Return Value:
639
640         IRQL =
641
642         Note:
643
644         ========================================================================
645 */
646 NTSTATUS eFuseWriteRegisters(
647         IN      PRTMP_ADAPTER   pAd,
648         IN      USHORT Offset,
649         IN      USHORT Length,
650         IN      USHORT* pData)
651 {
652         USHORT  i;
653         USHORT  eFuseData;
654         USHORT  LogicalAddress, BlkNum = 0xffff;
655         UCHAR   EFSROM_AOUT;
656
657         USHORT addr,tmpaddr, InBuf[3], tmpOffset;
658         USHORT buffer[8];
659         BOOLEAN         bWriteSuccess = TRUE;
660
661         DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters Offset=%x, pData=%x\n", Offset, *pData));
662
663         //Step 0. find the entry in the mapping table
664         //The address of EEPROM is 2-bytes alignment.
665         //The last bit is used for alignment, so it must be 0.
666         tmpOffset = Offset & 0xfffe;
667         EFSROM_AOUT = eFuseReadRegisters(pAd, tmpOffset, 2, &eFuseData);
668
669         if( EFSROM_AOUT == 0x3f)
670         {       //find available logical address pointer
671                 //the logical address does not exist, find an empty one
672                 //from the first address of block 45=16*45=0x2d0 to the last address of block 47
673                 //==>48*16-3(reserved)=2FC
674                 for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
675                 {
676                         //Retrive the logical block nubmer form each logical address pointer
677                         //It will access two logical address pointer each time.
678                         eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
679                         if( (LogicalAddress & 0xff) == 0)
680                         {//Not used logical address pointer
681                                 BlkNum = i-EFUSE_USAGE_MAP_START;
682                                 break;
683                         }
684                         else if(( (LogicalAddress >> 8) & 0xff) == 0)
685                         {//Not used logical address pointer
686                                 if (i != EFUSE_USAGE_MAP_END)
687                                 {
688                                         BlkNum = i-EFUSE_USAGE_MAP_START+1;
689                                 }
690                                 break;
691                         }
692                 }
693         }
694         else
695         {
696                 BlkNum = EFSROM_AOUT;
697         }
698
699         DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum));
700
701         if(BlkNum == 0xffff)
702         {
703                 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
704                 return FALSE;
705         }
706
707         //Step 1. Save data of this block       which is pointed by the avaible logical address pointer
708         // read and save the original block data
709         for(i =0; i<8; i++)
710         {
711                 addr = BlkNum * 0x10 ;
712
713                 InBuf[0] = addr+2*i;
714                 InBuf[1] = 2;
715                 InBuf[2] = 0x0;
716
717                 eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
718
719                 buffer[i] = InBuf[2];
720         }
721
722         //Step 2. Update the data in buffer, and write the data to Efuse
723         buffer[ (Offset >> 1) % 8] = pData[0];
724
725         do
726         {
727                 //Step 3. Write the data to Efuse
728                 if(!bWriteSuccess)
729                 {
730                         for(i =0; i<8; i++)
731                         {
732                                 addr = BlkNum * 0x10 ;
733
734                                 InBuf[0] = addr+2*i;
735                                 InBuf[1] = 2;
736                                 InBuf[2] = buffer[i];
737
738                                 eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
739                         }
740                 }
741                 else
742                 {
743                                 addr = BlkNum * 0x10 ;
744
745                                 InBuf[0] = addr+(Offset % 16);
746                                 InBuf[1] = 2;
747                                 InBuf[2] = pData[0];
748
749                                 eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
750                 }
751
752                 //Step 4. Write mapping table
753                 addr = EFUSE_USAGE_MAP_START+BlkNum;
754
755                 tmpaddr = addr;
756
757                 if(addr % 2 != 0)
758                         addr = addr -1;
759                 InBuf[0] = addr;
760                 InBuf[1] = 2;
761
762                 //convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry
763                 tmpOffset = Offset;
764                 tmpOffset >>= 4;
765                 tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^  (tmpOffset >> 2 & 0x01) ^  (tmpOffset >> 3 & 0x01))) << 6) & 0x40;
766                 tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80;
767
768                 // write the logical address
769                 if(tmpaddr%2 != 0)
770                         InBuf[2] = tmpOffset<<8;
771                 else
772                         InBuf[2] = tmpOffset;
773
774                 eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0);
775
776                 //Step 5. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted
777                 bWriteSuccess = TRUE;
778                 for(i =0; i<8; i++)
779                 {
780                         addr = BlkNum * 0x10 ;
781
782                         InBuf[0] = addr+2*i;
783                         InBuf[1] = 2;
784                         InBuf[2] = 0x0;
785
786                         eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
787
788                         if(buffer[i] != InBuf[2])
789                         {
790                                 bWriteSuccess = FALSE;
791                                 break;
792                         }
793                 }
794
795                 //Step 6. invlidate mapping entry and find a free mapping entry if not succeed
796                 if (!bWriteSuccess)
797                 {
798                         DBGPRINT(RT_DEBUG_TRACE, ("Not bWriteSuccess BlkNum = %d\n", BlkNum));
799
800                         // the offset of current mapping entry
801                         addr = EFUSE_USAGE_MAP_START+BlkNum;
802
803                         //find a new mapping entry
804                         BlkNum = 0xffff;
805                         for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
806                         {
807                                 eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
808                                 if( (LogicalAddress & 0xff) == 0)
809                                 {
810                                         BlkNum = i-EFUSE_USAGE_MAP_START;
811                                         break;
812                                 }
813                                 else if(( (LogicalAddress >> 8) & 0xff) == 0)
814                                 {
815                                         if (i != EFUSE_USAGE_MAP_END)
816                                         {
817                                                 BlkNum = i+1-EFUSE_USAGE_MAP_START;
818                                         }
819                                         break;
820                                 }
821                         }
822                         DBGPRINT(RT_DEBUG_TRACE, ("Not bWriteSuccess new BlkNum = %d\n", BlkNum));
823                         if(BlkNum == 0xffff)
824                         {
825                                 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
826                                 return FALSE;
827                         }
828
829                         //invalidate the original mapping entry if new entry is not found
830                         tmpaddr = addr;
831
832                         if(addr % 2 != 0)
833                                 addr = addr -1;
834                         InBuf[0] = addr;
835                         InBuf[1] = 2;
836
837                         eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
838
839                         // write the logical address
840                         if(tmpaddr%2 != 0)
841                         {
842                                 // Invalidate the high byte
843                                 for (i=8; i<15; i++)
844                                 {
845                                         if( ( (InBuf[2] >> i) & 0x01) == 0)
846                                         {
847                                                 InBuf[2] |= (0x1 <<i);
848                                                 break;
849                                         }
850                                 }
851                         }
852                         else
853                         {
854                                 // invalidate the low byte
855                                 for (i=0; i<8; i++)
856                                 {
857                                         if( ( (InBuf[2] >> i) & 0x01) == 0)
858                                         {
859                                                 InBuf[2] |= (0x1 <<i);
860                                                 break;
861                                         }
862                                 }
863                         }
864                         eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 0);
865                 }
866         }
867         while(!bWriteSuccess);
868
869         return TRUE;
870 }
871
872 /*
873         ========================================================================
874
875         Routine Description:
876
877         Arguments:
878
879         Return Value:
880
881         IRQL =
882
883         Note:
884
885         ========================================================================
886 */
887 VOID eFuseWritePhysical(
888         IN      PRTMP_ADAPTER   pAd,
889         PUSHORT lpInBuffer,
890         ULONG nInBufferSize,
891         PUCHAR lpOutBuffer,
892         ULONG nOutBufferSize
893 )
894 {
895         USHORT* pInBuf = (USHORT*)lpInBuffer;
896         int             i;
897         //USHORT* pOutBuf = (USHORT*)ioBuffer;
898
899         USHORT Offset = pInBuf[0];                                      //addr
900         USHORT Length = pInBuf[1];                                      //length
901         USHORT* pValueX = &pInBuf[2];                           //value ...
902                 // Little-endian                S       |       S       Big-endian
903                 // addr 3       2       1       0       |       0       1       2       3
904                 // Ori-V        D       C       B       A       |       A       B       C       D
905                 //After swapping
906                 //              D       C       B       A       |       D       C       B       A
907                 //Both the little and big-endian use the same sequence to write  data.
908                 //Therefore, we only need swap data when read the data.
909         for(i=0; i<Length; i+=2)
910         {
911                 eFusePhysicalWriteRegisters(pAd, Offset+i, 2, &pValueX[i/2]);
912         }
913 }
914
915
916 /*
917         ========================================================================
918
919         Routine Description:
920
921         Arguments:
922
923         Return Value:
924
925         IRQL =
926
927         Note:
928
929         ========================================================================
930 */
931 NTSTATUS eFuseWrite(
932         IN      PRTMP_ADAPTER   pAd,
933         IN      USHORT                  Offset,
934         IN      PUCHAR                  pData,
935         IN      USHORT                  length)
936 {
937         int i;
938
939         USHORT* pValueX = (PUSHORT) pData;                              //value ...
940                 //The input value=3070 will be stored as following
941                 // Little-endian                S       |       S       Big-endian
942                 // addr                 1       0       |       0       1
943                 // Ori-V                        30      70      |       30      70
944                 //After swapping
945                 //                              30      70      |       70      30
946                 //Casting
947                 //                              3070    |       7030 (x)
948                 //The swapping should be removed for big-endian
949         for(i=0; i<length; i+=2)
950         {
951                 eFuseWriteRegisters(pAd, Offset+i, 2, &pValueX[i/2]);
952         }
953
954         return TRUE;
955 }
956
957 /*
958         ========================================================================
959
960         Routine Description:
961
962         Arguments:
963
964         Return Value:
965
966         IRQL =
967
968         Note:
969
970         ========================================================================
971 */
972 INT set_eFuseGetFreeBlockCount_Proc(
973         IN      PRTMP_ADAPTER   pAd,
974         IN      PUCHAR                  arg)
975 {
976         USHORT i;
977         USHORT  LogicalAddress;
978         USHORT efusefreenum=0;
979         if(!pAd->bUseEfuse)
980                 return FALSE;
981         for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i+=2)
982         {
983                 eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
984                 if( (LogicalAddress & 0xff) == 0)
985                 {
986                         efusefreenum= (UCHAR) (EFUSE_USAGE_MAP_END-i+1);
987                         break;
988                 }
989                 else if(( (LogicalAddress >> 8) & 0xff) == 0)
990                 {
991                         efusefreenum = (UCHAR) (EFUSE_USAGE_MAP_END-i);
992                         break;
993                 }
994
995                 if(i == EFUSE_USAGE_MAP_END)
996                         efusefreenum = 0;
997         }
998         printk("efuseFreeNumber is %d\n",efusefreenum);
999         return TRUE;
1000 }
1001 INT set_eFusedump_Proc(
1002         IN      PRTMP_ADAPTER   pAd,
1003         IN      PUCHAR                  arg)
1004 {
1005 USHORT InBuf[3];
1006         INT i=0;
1007         if(!pAd->bUseEfuse)
1008                 return FALSE;
1009         for(i =0; i<EFUSE_USAGE_MAP_END/2; i++)
1010         {
1011                 InBuf[0] = 2*i;
1012                 InBuf[1] = 2;
1013                 InBuf[2] = 0x0;
1014
1015                 eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
1016                 if(i%4==0)
1017                 printk("\nBlock %x:",i/8);
1018                 printk("%04x ",InBuf[2]);
1019         }
1020         return TRUE;
1021 }
1022 INT     set_eFuseLoadFromBin_Proc(
1023         IN      PRTMP_ADAPTER   pAd,
1024         IN      PUCHAR                  arg)
1025 {
1026         CHAR                                    *src;
1027         struct file                             *srcf;
1028         INT                                     retval, orgfsuid, orgfsgid;
1029         mm_segment_t                    orgfs;
1030         UCHAR                                   *buffer;
1031         UCHAR                                   BinFileSize=0;
1032         INT                                             i = 0,j=0,k=1;
1033         USHORT                                  *PDATA;
1034         USHORT                                  DATA;
1035         BinFileSize=strlen("RT30xxEEPROM.bin");
1036         src = kmalloc(128, MEM_ALLOC_FLAG);
1037         NdisZeroMemory(src, 128);
1038
1039         if(strlen(arg)>0)
1040         {
1041
1042                 NdisMoveMemory(src, arg, strlen(arg));
1043         }
1044
1045         else
1046         {
1047
1048                 NdisMoveMemory(src, "RT30xxEEPROM.bin", BinFileSize);
1049         }
1050
1051         DBGPRINT(RT_DEBUG_TRACE, ("FileName=%s\n",src));
1052         buffer = kmalloc(MAX_EEPROM_BIN_FILE_SIZE, MEM_ALLOC_FLAG);
1053
1054         if(buffer == NULL)
1055         {
1056                 kfree(src);
1057                  return FALSE;
1058 }
1059         PDATA=kmalloc(sizeof(USHORT)*8,MEM_ALLOC_FLAG);
1060
1061         if(PDATA==NULL)
1062         {
1063                 kfree(src);
1064
1065                 kfree(buffer);
1066                 return FALSE;
1067         }
1068         /* Don't change to uid 0, let the file be opened as the "normal" user */
1069 #if 0
1070         orgfsuid = current->fsuid;
1071         orgfsgid = current->fsgid;
1072         current->fsuid=current->fsgid = 0;
1073 #endif
1074         orgfs = get_fs();
1075          set_fs(KERNEL_DS);
1076
1077         if (src && *src)
1078         {
1079                 srcf = filp_open(src, O_RDONLY, 0);
1080                 if (IS_ERR(srcf))
1081                 {
1082                         DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld opening %s\n", -PTR_ERR(srcf),src));
1083                         return FALSE;
1084                 }
1085                 else
1086                 {
1087                         // The object must have a read method
1088                         if (srcf->f_op && srcf->f_op->read)
1089                         {
1090                                 memset(buffer, 0x00, MAX_EEPROM_BIN_FILE_SIZE);
1091                                 while(srcf->f_op->read(srcf, &buffer[i], 1, &srcf->f_pos)==1)
1092                                 {
1093                                         DBGPRINT(RT_DEBUG_TRACE, ("%02X ",buffer[i]));
1094                                         if((i+1)%8==0)
1095                                                 DBGPRINT(RT_DEBUG_TRACE, ("\n"));
1096                                 i++;
1097                                                 if(i>=MAX_EEPROM_BIN_FILE_SIZE)
1098                                                         {
1099                                                                 DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld reading %s, The file is too large[1024]\n", -PTR_ERR(srcf),src));
1100                                                                 kfree(PDATA);
1101                                                                 kfree(buffer);
1102                                                                 kfree(src);
1103                                                                 return FALSE;
1104                                                         }
1105                                }
1106                         }
1107                         else
1108                         {
1109                                                 DBGPRINT(RT_DEBUG_ERROR, ("--> Error!! System doest not support read function\n"));
1110                                                 kfree(PDATA);
1111                                                 kfree(buffer);
1112                                                 kfree(src);
1113                                                 return FALSE;
1114                         }
1115                 }
1116
1117
1118         }
1119         else
1120                 {
1121                                         DBGPRINT(RT_DEBUG_ERROR, ("--> Error src  or srcf is null\n"));
1122                                         kfree(PDATA);
1123                                         kfree(buffer);
1124                                         return FALSE;
1125
1126                 }
1127
1128
1129         retval=filp_close(srcf,NULL);
1130
1131         if (retval)
1132         {
1133                 DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src));
1134         }
1135         set_fs(orgfs);
1136 #if 0
1137         current->fsuid = orgfsuid;
1138         current->fsgid = orgfsgid;
1139 #endif
1140         for(j=0;j<i;j++)
1141         {
1142                 DBGPRINT(RT_DEBUG_TRACE, ("%02X ",buffer[j]));
1143                 if((j+1)%2==0)
1144                         PDATA[j/2%8]=((buffer[j]<<8)&0xff00)|(buffer[j-1]&0xff);
1145                 if(j%16==0)
1146                 {
1147                         k=buffer[j];
1148                 }
1149                 else
1150                 {
1151                         k&=buffer[j];
1152                         if((j+1)%16==0)
1153                         {
1154
1155                                 DBGPRINT(RT_DEBUG_TRACE, (" result=%02X,blk=%02x\n",k,j/16));
1156
1157                                 if(k!=0xff)
1158                                         eFuseWriteRegistersFromBin(pAd,(USHORT)j-15, 16, PDATA);
1159                                 else
1160                                         {
1161                                                 if(eFuseReadRegisters(pAd,j, 2,(PUSHORT)&DATA)!=0x3f)
1162                                                         eFuseWriteRegistersFromBin(pAd,(USHORT)j-15, 16, PDATA);
1163                                         }
1164                                 /*
1165                                 for(l=0;l<8;l++)
1166                                         printk("%04x ",PDATA[l]);
1167                                 printk("\n");
1168                                 */
1169                                 NdisZeroMemory(PDATA,16);
1170
1171
1172                         }
1173                 }
1174
1175
1176         }
1177
1178
1179         kfree(PDATA);
1180         kfree(buffer);
1181         kfree(src);
1182         return TRUE;
1183 }
1184 NTSTATUS eFuseWriteRegistersFromBin(
1185         IN      PRTMP_ADAPTER   pAd,
1186         IN      USHORT Offset,
1187         IN      USHORT Length,
1188         IN      USHORT* pData)
1189 {
1190         USHORT  i;
1191         USHORT  eFuseData;
1192         USHORT  LogicalAddress, BlkNum = 0xffff;
1193         UCHAR   EFSROM_AOUT,Loop=0;
1194         EFUSE_CTRL_STRUC                eFuseCtrlStruc;
1195         USHORT  efuseDataOffset;
1196         UINT32  data,tempbuffer;
1197         USHORT addr,tmpaddr, InBuf[3], tmpOffset;
1198         UINT32 buffer[4];
1199         BOOLEAN         bWriteSuccess = TRUE;
1200         BOOLEAN         bNotWrite=TRUE;
1201         BOOLEAN         bAllocateNewBlk=TRUE;
1202
1203         DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin Offset=%x, pData=%04x:%04x:%04x:%04x\n", Offset, *pData,*(pData+1),*(pData+2),*(pData+3)));
1204
1205         do
1206         {
1207         //Step 0. find the entry in the mapping table
1208         //The address of EEPROM is 2-bytes alignment.
1209         //The last bit is used for alignment, so it must be 0.
1210         Loop++;
1211         tmpOffset = Offset & 0xfffe;
1212         EFSROM_AOUT = eFuseReadRegisters(pAd, tmpOffset, 2, &eFuseData);
1213
1214         if( EFSROM_AOUT == 0x3f)
1215         {       //find available logical address pointer
1216                 //the logical address does not exist, find an empty one
1217                 //from the first address of block 45=16*45=0x2d0 to the last address of block 47
1218                 //==>48*16-3(reserved)=2FC
1219                 bAllocateNewBlk=TRUE;
1220                 for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
1221                 {
1222                         //Retrive the logical block nubmer form each logical address pointer
1223                         //It will access two logical address pointer each time.
1224                         eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
1225                         if( (LogicalAddress & 0xff) == 0)
1226                         {//Not used logical address pointer
1227                                 BlkNum = i-EFUSE_USAGE_MAP_START;
1228                                 break;
1229                         }
1230                         else if(( (LogicalAddress >> 8) & 0xff) == 0)
1231                         {//Not used logical address pointer
1232                                 if (i != EFUSE_USAGE_MAP_END)
1233                                 {
1234                                         BlkNum = i-EFUSE_USAGE_MAP_START+1;
1235                                 }
1236                                 break;
1237                         }
1238                 }
1239         }
1240         else
1241         {
1242                 bAllocateNewBlk=FALSE;
1243                 BlkNum = EFSROM_AOUT;
1244         }
1245
1246         DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum));
1247
1248         if(BlkNum == 0xffff)
1249         {
1250                 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
1251                 return FALSE;
1252         }
1253         //Step 1.1.0
1254         //If the block is not existing in mapping table, create one
1255         //and write down the 16-bytes data to the new block
1256         if(bAllocateNewBlk)
1257         {
1258                 DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk\n"));
1259                 efuseDataOffset =  EFUSE_DATA3;
1260                 for(i=0; i< 4; i++)
1261                 {
1262                         DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk, Data%d=%04x%04x\n",3-i,pData[2*i+1],pData[2*i]));
1263                         tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i];
1264
1265
1266                         RTMP_IO_WRITE32(pAd, efuseDataOffset,tempbuffer);
1267                         efuseDataOffset -= 4;
1268
1269                 }
1270                 /////////////////////////////////////////////////////////////////
1271
1272                 //Step1.1.1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
1273                 eFuseCtrlStruc.field.EFSROM_AIN = BlkNum* 0x10 ;
1274
1275                 //Step1.1.2. Write EFSROM_MODE (0x580, bit7:bit6) to 3.
1276                 eFuseCtrlStruc.field.EFSROM_MODE = 3;
1277
1278                 //Step1.1.3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure.
1279                 eFuseCtrlStruc.field.EFSROM_KICK = 1;
1280
1281                 NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
1282
1283                 RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
1284
1285                 //Step1.1.4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It¡¦s done.
1286                 i = 0;
1287                 while(i < 100)
1288                 {
1289                         RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
1290
1291                         if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
1292                                 break;
1293
1294                         RTMPusecDelay(2);
1295                         i++;
1296                 }
1297
1298         }
1299         else
1300         {       //Step1.2.
1301                 //If the same logical number is existing, check if the writting data and the data
1302                 //saving in this block are the same.
1303                 /////////////////////////////////////////////////////////////////
1304                 //read current values of 16-byte block
1305                 RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
1306
1307                 //Step1.2.0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
1308                 eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
1309
1310                 //Step1.2.1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
1311                 eFuseCtrlStruc.field.EFSROM_MODE = 0;
1312
1313                 //Step1.2.2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
1314                 eFuseCtrlStruc.field.EFSROM_KICK = 1;
1315
1316                 NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
1317                 RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
1318
1319                 //Step1.2.3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
1320                 i = 0;
1321                 while(i < 100)
1322                 {
1323                         RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
1324
1325                         if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
1326                                 break;
1327                         RTMPusecDelay(2);
1328                         i++;
1329                 }
1330
1331                 //Step1.2.4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
1332                 efuseDataOffset =  EFUSE_DATA3;
1333                 for(i=0; i< 4; i++)
1334                 {
1335                         RTMP_IO_READ32(pAd, efuseDataOffset, (PUINT32) &buffer[i]);
1336                         efuseDataOffset -=  4;
1337                 }
1338                 //Step1.2.5. Check if the data of efuse and the writing data are the same.
1339                 for(i =0; i<4; i++)
1340                 {
1341                         tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i];
1342                         DBGPRINT(RT_DEBUG_TRACE, ("buffer[%d]=%x,pData[%d]=%x,pData[%d]=%x,tempbuffer=%x\n",i,buffer[i],2*i,pData[2*i],2*i+1,pData[2*i+1],tempbuffer));
1343
1344                         if(((buffer[i]&0xffff0000)==(pData[2*i+1]<<16))&&((buffer[i]&0xffff)==pData[2*i]))
1345                                 bNotWrite&=TRUE;
1346                         else
1347                         {
1348                                 bNotWrite&=FALSE;
1349                                 break;
1350                         }
1351                 }
1352                 if(!bNotWrite)
1353                 {
1354                 printk("The data is not the same\n");
1355
1356                         for(i =0; i<8; i++)
1357                         {
1358                                 addr = BlkNum * 0x10 ;
1359
1360                                 InBuf[0] = addr+2*i;
1361                                 InBuf[1] = 2;
1362                                 InBuf[2] = pData[i];
1363
1364                                 eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
1365                         }
1366
1367                 }
1368                 else
1369                         return TRUE;
1370              }
1371
1372
1373
1374                 //Step 2. Write mapping table
1375                 addr = EFUSE_USAGE_MAP_START+BlkNum;
1376
1377                 tmpaddr = addr;
1378
1379                 if(addr % 2 != 0)
1380                         addr = addr -1;
1381                 InBuf[0] = addr;
1382                 InBuf[1] = 2;
1383
1384                 //convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry
1385                 tmpOffset = Offset;
1386                 tmpOffset >>= 4;
1387                 tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^  (tmpOffset >> 2 & 0x01) ^  (tmpOffset >> 3 & 0x01))) << 6) & 0x40;
1388                 tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80;
1389
1390                 // write the logical address
1391                 if(tmpaddr%2 != 0)
1392                         InBuf[2] = tmpOffset<<8;
1393                 else
1394                         InBuf[2] = tmpOffset;
1395
1396                 eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0);
1397
1398                 //Step 3. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted
1399                 bWriteSuccess = TRUE;
1400                 for(i =0; i<8; i++)
1401                 {
1402                         addr = BlkNum * 0x10 ;
1403
1404                         InBuf[0] = addr+2*i;
1405                         InBuf[1] = 2;
1406                         InBuf[2] = 0x0;
1407
1408                         eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
1409                         DBGPRINT(RT_DEBUG_TRACE, ("addr=%x, buffer[i]=%x,InBuf[2]=%x\n",InBuf[0],pData[i],InBuf[2]));
1410                         if(pData[i] != InBuf[2])
1411                         {
1412                                 bWriteSuccess = FALSE;
1413                                 break;
1414                         }
1415                 }
1416
1417                 //Step 4. invlidate mapping entry and find a free mapping entry if not succeed
1418
1419                 if (!bWriteSuccess&&Loop<2)
1420                 {
1421                         DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess BlkNum = %d\n", BlkNum));
1422
1423                         // the offset of current mapping entry
1424                         addr = EFUSE_USAGE_MAP_START+BlkNum;
1425
1426                         //find a new mapping entry
1427                         BlkNum = 0xffff;
1428                         for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
1429                         {
1430                                 eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
1431                                 if( (LogicalAddress & 0xff) == 0)
1432                                 {
1433                                         BlkNum = i-EFUSE_USAGE_MAP_START;
1434                                         break;
1435                                 }
1436                                 else if(( (LogicalAddress >> 8) & 0xff) == 0)
1437                                 {
1438                                         if (i != EFUSE_USAGE_MAP_END)
1439                                         {
1440                                                 BlkNum = i+1-EFUSE_USAGE_MAP_START;
1441                                         }
1442                                         break;
1443                                 }
1444                         }
1445                         DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess new BlkNum = %d\n", BlkNum));
1446                         if(BlkNum == 0xffff)
1447                         {
1448                                 DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin: out of free E-fuse space!!!\n"));
1449                                 return FALSE;
1450                         }
1451
1452                         //invalidate the original mapping entry if new entry is not found
1453                         tmpaddr = addr;
1454
1455                         if(addr % 2 != 0)
1456                                 addr = addr -1;
1457                         InBuf[0] = addr;
1458                         InBuf[1] = 2;
1459
1460                         eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
1461
1462                         // write the logical address
1463                         if(tmpaddr%2 != 0)
1464                         {
1465                                 // Invalidate the high byte
1466                                 for (i=8; i<15; i++)
1467                                 {
1468                                         if( ( (InBuf[2] >> i) & 0x01) == 0)
1469                                         {
1470                                                 InBuf[2] |= (0x1 <<i);
1471                                                 break;
1472                                         }
1473                                 }
1474                         }
1475                         else
1476                         {
1477                                 // invalidate the low byte
1478                                 for (i=0; i<8; i++)
1479                                 {
1480                                         if( ( (InBuf[2] >> i) & 0x01) == 0)
1481                                         {
1482                                                 InBuf[2] |= (0x1 <<i);
1483                                                 break;
1484                                         }
1485                                 }
1486                         }
1487                         eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 0);
1488                 }
1489
1490         }
1491         while(!bWriteSuccess&&Loop<2);
1492
1493         return TRUE;
1494 }
1495
1496 #endif // RT30xx //
1497 //2008/09/11:KH add to support efuse-->
1498