2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
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. *
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. *
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. *
25 *************************************************************************
31 Miniport generic portion header file
35 -------- ---------- ----------------------------------------------
39 #include "../rt_config.h"
43 #define EFUSE_USAGE_MAP_START 0x2d0
44 #define EFUSE_USAGE_MAP_END 0x2fc
45 #define EFUSE_USAGE_MAP_SIZE 45
49 #define EFUSE_EEPROM_DEFULT_FILE "RT30xxEEPROM.bin"
50 #define MAX_EEPROM_BIN_FILE_SIZE 1024
54 #define EFUSE_TAG 0x2fe
56 typedef union _EFUSE_CTRL_STRUC {
60 UINT32 EFSROM_LDO_OFF_TIME:6;
61 UINT32 EFSROM_LDO_ON_TIME:2;
68 } EFUSE_CTRL_STRUC, *PEFUSE_CTRL_STRUC;
71 ========================================================================
81 ========================================================================
83 UCHAR eFuseReadRegisters(
89 EFUSE_CTRL_STRUC eFuseCtrlStruc;
91 USHORT efuseDataOffset;
94 RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
96 //Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
97 //Use the eeprom logical address and covert to address to block number
98 eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
100 //Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 0.
101 eFuseCtrlStruc.field.EFSROM_MODE = 0;
103 //Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
104 eFuseCtrlStruc.field.EFSROM_KICK = 1;
106 NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
107 RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
109 //Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
113 //rtmp.HwMemoryReadDword(EFUSE_CTRL, (DWORD *) &eFuseCtrlStruc, 4);
114 RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
115 if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
123 //if EFSROM_AOUT is not found in physical address, write 0xffff
124 if (eFuseCtrlStruc.field.EFSROM_AOUT == 0x3f)
126 for(i=0; i<Length/2; i++)
127 *(pData+2*i) = 0xffff;
131 //Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x590-0x59C)
132 efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC);
133 //data hold 4 bytes data.
134 //In RTMP_IO_READ32 will automatically execute 32-bytes swapping
135 RTMP_IO_READ32(pAd, efuseDataOffset, &data);
136 //Decide the upper 2 bytes or the bottom 2 bytes.
137 // Little-endian S | S Big-endian
138 // addr 3 2 1 0 | 0 1 2 3
139 // Ori-V D C B A | A B C D
143 //The return byte statrs from S. Therefore, the little-endian will return BA, the Big-endian will return DC.
144 //For returning the bottom 2 bytes, the Big-endian should shift right 2-bytes.
145 data = data >> (8*(Offset & 0x3));
147 NdisMoveMemory(pData, &data, Length);
150 return (UCHAR) eFuseCtrlStruc.field.EFSROM_AOUT;
155 ========================================================================
165 ========================================================================
167 VOID eFusePhysicalReadRegisters(
168 IN PRTMP_ADAPTER pAd,
173 EFUSE_CTRL_STRUC eFuseCtrlStruc;
175 USHORT efuseDataOffset;
178 RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
180 //Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
181 eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
183 //Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
184 //Read in physical view
185 eFuseCtrlStruc.field.EFSROM_MODE = 1;
187 //Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
188 eFuseCtrlStruc.field.EFSROM_KICK = 1;
190 NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
191 RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
193 //Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
197 RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
198 if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
204 //Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
205 //Because the size of each EFUSE_DATA is 4 Bytes, the size of address of each is 2 bits.
206 //The previous 2 bits is the EFUSE_DATA number, the last 2 bits is used to decide which bytes
207 //Decide which EFUSE_DATA to read
212 efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC) ;
214 RTMP_IO_READ32(pAd, efuseDataOffset, &data);
216 data = data >> (8*(Offset & 0x3));
218 NdisMoveMemory(pData, &data, Length);
223 ========================================================================
233 ========================================================================
235 static VOID eFuseReadPhysical(
236 IN PRTMP_ADAPTER pAd,
237 IN PUSHORT lpInBuffer,
238 IN ULONG nInBufferSize,
239 OUT PUSHORT lpOutBuffer,
240 IN ULONG nOutBufferSize
243 USHORT* pInBuf = (USHORT*)lpInBuffer;
244 USHORT* pOutBuf = (USHORT*)lpOutBuffer;
246 USHORT Offset = pInBuf[0]; //addr
247 USHORT Length = pInBuf[1]; //length
250 for(i=0; i<Length; i+=2)
252 eFusePhysicalReadRegisters(pAd,Offset+i, 2, &pOutBuf[i/2]);
257 ========================================================================
267 ========================================================================
269 INT set_eFuseGetFreeBlockCount_Proc(
270 IN PRTMP_ADAPTER pAd,
274 USHORT LogicalAddress;
275 USHORT efusefreenum=0;
278 for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i+=2)
280 eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
281 if( (LogicalAddress & 0xff) == 0)
283 efusefreenum= (UCHAR) (EFUSE_USAGE_MAP_END-i+1);
286 else if(( (LogicalAddress >> 8) & 0xff) == 0)
288 efusefreenum = (UCHAR) (EFUSE_USAGE_MAP_END-i);
292 if(i == EFUSE_USAGE_MAP_END)
295 printk("efuseFreeNumber is %d\n",efusefreenum);
300 INT set_eFusedump_Proc(
301 IN PRTMP_ADAPTER pAd,
308 for(i =0; i<EFUSE_USAGE_MAP_END/2; i++)
314 eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
316 printk("\nBlock %x:",i/8);
317 printk("%04x ",InBuf[2]);
322 int rtmp_ee_efuse_read16(
323 IN RTMP_ADAPTER *pAd,
327 eFuseReadRegisters(pAd, Offset, 2, pValue);
331 int RtmpEfuseSupportCheck(
332 IN RTMP_ADAPTER *pAd)
338 eFusePhysicalReadRegisters(pAd, EFUSE_TAG, 2, &value);
339 pAd->EFuseTag = (value & 0xff);
344 VOID eFuseGetFreeBlockCount(IN PRTMP_ADAPTER pAd,
345 PUINT EfuseFreeBlock)
348 USHORT LogicalAddress;
351 DBGPRINT(RT_DEBUG_TRACE,("eFuseGetFreeBlockCount Only supports efuse Mode\n"));
354 for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i+=2)
356 eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
357 if( (LogicalAddress & 0xff) == 0)
359 *EfuseFreeBlock= (UCHAR) (EFUSE_USAGE_MAP_END-i+1);
362 else if(( (LogicalAddress >> 8) & 0xff) == 0)
364 *EfuseFreeBlock = (UCHAR) (EFUSE_USAGE_MAP_END-i);
368 if(i == EFUSE_USAGE_MAP_END)
371 DBGPRINT(RT_DEBUG_TRACE,("eFuseGetFreeBlockCount is 0x%x\n",*EfuseFreeBlock));
375 IN PRTMP_ADAPTER pAd)
377 UINT EfuseFreeBlock=0;
378 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));
379 eFuseGetFreeBlockCount(pAd, &EfuseFreeBlock);