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