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