]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/staging/rt3090/common/ee_efuse.c
Staging: rt2860: add RT3090 chipset support
[net-next-2.6.git] / drivers / staging / rt3090 / common / ee_efuse.c
CommitLineData
36c7928c
BZ
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
56typedef 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
70typedef 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
85static UCHAR eFuseReadRegisters(
86 IN PRTMP_ADAPTER pAd,
87 IN USHORT Offset,
88 IN USHORT Length,
89 OUT USHORT* pData);
90
91static VOID eFuseReadPhysical(
92 IN PRTMP_ADAPTER pAd,
93 IN PUSHORT lpInBuffer,
94 IN ULONG nInBufferSize,
95 OUT PUSHORT lpOutBuffer,
96 IN ULONG nOutBufferSize);
97
98static VOID eFusePhysicalWriteRegisters(
99 IN PRTMP_ADAPTER pAd,
100 IN USHORT Offset,
101 IN USHORT Length,
102 OUT USHORT* pData);
103
104static NTSTATUS eFuseWriteRegisters(
105 IN PRTMP_ADAPTER pAd,
106 IN USHORT Offset,
107 IN USHORT Length,
108 IN USHORT* pData);
109
110static VOID eFuseWritePhysical(
111 IN PRTMP_ADAPTER pAd,
112 PUSHORT lpInBuffer,
113 ULONG nInBufferSize,
114 PUCHAR lpOutBuffer,
115 ULONG nOutBufferSize);
116
117
118static 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*/
138UCHAR 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*/
226VOID 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*/
298static 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*/
332NTSTATUS 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*/
363static 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*/
476static 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*/
717static 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*/
763NTSTATUS 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*/
805INT 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
836INT set_eFusedump_Proc(
837 IN PRTMP_ADAPTER pAd,
838 IN PSTRING arg)
839{
840USHORT 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
859INT 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
953closeFile:
954 if (srcf)
955 RtmpOSFileClose(srcf);
956
957recoverFS:
958 RtmpOSFSInfoChange(&osfsInfo, FALSE);
959
960
961 if (memPtr)
962 kfree(memPtr);
963
964 return retval;
965}
966
967
968static 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
1282int 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
1298int 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
1314int 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
1327INT 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*/
1368INT 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
1430INT 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
1498VOID 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
1528INT 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}