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