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 -------- ---------- ----------------------------------------------
38 #include "../rt_config.h"
40 #define EFUSE_USAGE_MAP_START 0x2d0
41 #define EFUSE_USAGE_MAP_END 0x2fc
42 #define EFUSE_USAGE_MAP_SIZE 45
44 #define EFUSE_EEPROM_DEFULT_FILE "RT30xxEEPROM.bin"
45 #define MAX_EEPROM_BIN_FILE_SIZE 1024
47 #define EFUSE_TAG 0x2fe
49 typedef union _EFUSE_CTRL_STRUC {
53 UINT32 EFSROM_LDO_OFF_TIME:6;
54 UINT32 EFSROM_LDO_ON_TIME:2;
61 } EFUSE_CTRL_STRUC, *PEFUSE_CTRL_STRUC;
64 ========================================================================
74 ========================================================================
76 UCHAR eFuseReadRegisters(IN PRTMP_ADAPTER pAd,
77 IN USHORT Offset, IN USHORT Length, OUT USHORT * pData)
79 EFUSE_CTRL_STRUC eFuseCtrlStruc;
81 USHORT efuseDataOffset;
84 RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
86 //Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
87 //Use the eeprom logical address and covert to address to block number
88 eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
90 //Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 0.
91 eFuseCtrlStruc.field.EFSROM_MODE = 0;
93 //Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
94 eFuseCtrlStruc.field.EFSROM_KICK = 1;
96 NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
97 RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
99 //Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
102 //rtmp.HwMemoryReadDword(EFUSE_CTRL, (DWORD *) &eFuseCtrlStruc, 4);
103 RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
104 if (eFuseCtrlStruc.field.EFSROM_KICK == 0) {
111 //if EFSROM_AOUT is not found in physical address, write 0xffff
112 if (eFuseCtrlStruc.field.EFSROM_AOUT == 0x3f) {
113 for (i = 0; i < Length / 2; i++)
114 *(pData + 2 * i) = 0xffff;
116 //Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x590-0x59C)
117 efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC);
118 //data hold 4 bytes data.
119 //In RTMP_IO_READ32 will automatically execute 32-bytes swapping
120 RTMP_IO_READ32(pAd, efuseDataOffset, &data);
121 //Decide the upper 2 bytes or the bottom 2 bytes.
122 // Little-endian S | S Big-endian
123 // addr 3 2 1 0 | 0 1 2 3
124 // Ori-V D C B A | A B C D
128 //The return byte statrs from S. Therefore, the little-endian will return BA, the Big-endian will return DC.
129 //For returning the bottom 2 bytes, the Big-endian should shift right 2-bytes.
130 data = data >> (8 * (Offset & 0x3));
132 NdisMoveMemory(pData, &data, Length);
135 return (UCHAR) eFuseCtrlStruc.field.EFSROM_AOUT;
140 ========================================================================
150 ========================================================================
152 VOID eFusePhysicalReadRegisters(IN PRTMP_ADAPTER pAd,
154 IN USHORT Length, OUT USHORT * pData)
156 EFUSE_CTRL_STRUC eFuseCtrlStruc;
158 USHORT efuseDataOffset;
161 RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
163 //Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
164 eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
166 //Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
167 //Read in physical view
168 eFuseCtrlStruc.field.EFSROM_MODE = 1;
170 //Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
171 eFuseCtrlStruc.field.EFSROM_KICK = 1;
173 NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
174 RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
176 //Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
179 RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
180 if (eFuseCtrlStruc.field.EFSROM_KICK == 0)
186 //Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
187 //Because the size of each EFUSE_DATA is 4 Bytes, the size of address of each is 2 bits.
188 //The previous 2 bits is the EFUSE_DATA number, the last 2 bits is used to decide which bytes
189 //Decide which EFUSE_DATA to read
194 efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC);
196 RTMP_IO_READ32(pAd, efuseDataOffset, &data);
198 data = data >> (8 * (Offset & 0x3));
200 NdisMoveMemory(pData, &data, Length);
205 ========================================================================
215 ========================================================================
217 static VOID eFuseReadPhysical(IN PRTMP_ADAPTER pAd,
218 IN PUSHORT lpInBuffer,
219 IN ULONG nInBufferSize,
220 OUT PUSHORT lpOutBuffer, IN ULONG nOutBufferSize)
222 USHORT *pInBuf = (USHORT *) lpInBuffer;
223 USHORT *pOutBuf = (USHORT *) lpOutBuffer;
225 USHORT Offset = pInBuf[0]; //addr
226 USHORT Length = pInBuf[1]; //length
229 for (i = 0; i < Length; i += 2) {
230 eFusePhysicalReadRegisters(pAd, Offset + i, 2, &pOutBuf[i / 2]);
235 ========================================================================
245 ========================================================================
247 INT set_eFuseGetFreeBlockCount_Proc(IN PRTMP_ADAPTER pAd, IN PSTRING arg)
250 USHORT LogicalAddress;
251 USHORT efusefreenum = 0;
254 for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i += 2) {
255 eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
256 if ((LogicalAddress & 0xff) == 0) {
257 efusefreenum = (UCHAR) (EFUSE_USAGE_MAP_END - i + 1);
259 } else if (((LogicalAddress >> 8) & 0xff) == 0) {
260 efusefreenum = (UCHAR) (EFUSE_USAGE_MAP_END - i);
264 if (i == EFUSE_USAGE_MAP_END)
267 printk("efuseFreeNumber is %d\n", efusefreenum);
271 INT set_eFusedump_Proc(IN PRTMP_ADAPTER pAd, IN PSTRING arg)
277 for (i = 0; i < EFUSE_USAGE_MAP_END / 2; i++) {
282 eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
284 printk("\nBlock %x:", i / 8);
285 printk("%04x ", InBuf[2]);
290 int rtmp_ee_efuse_read16(IN RTMP_ADAPTER * pAd,
291 IN USHORT Offset, OUT USHORT * pValue)
293 eFuseReadRegisters(pAd, Offset, 2, pValue);
297 int RtmpEfuseSupportCheck(IN RTMP_ADAPTER * pAd)
301 if (IS_RT30xx(pAd)) {
302 eFusePhysicalReadRegisters(pAd, EFUSE_TAG, 2, &value);
303 pAd->EFuseTag = (value & 0xff);
308 VOID eFuseGetFreeBlockCount(IN PRTMP_ADAPTER pAd, PUINT EfuseFreeBlock)
311 USHORT LogicalAddress;
312 if (!pAd->bUseEfuse) {
313 DBGPRINT(RT_DEBUG_TRACE,
314 ("eFuseGetFreeBlockCount Only supports efuse Mode\n"));
317 for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i += 2) {
318 eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
319 if ((LogicalAddress & 0xff) == 0) {
320 *EfuseFreeBlock = (UCHAR) (EFUSE_USAGE_MAP_END - i + 1);
322 } else if (((LogicalAddress >> 8) & 0xff) == 0) {
323 *EfuseFreeBlock = (UCHAR) (EFUSE_USAGE_MAP_END - i);
327 if (i == EFUSE_USAGE_MAP_END)
330 DBGPRINT(RT_DEBUG_TRACE,
331 ("eFuseGetFreeBlockCount is 0x%x\n", *EfuseFreeBlock));
334 INT eFuse_init(IN PRTMP_ADAPTER pAd)
336 UINT EfuseFreeBlock = 0;
337 DBGPRINT(RT_DEBUG_ERROR,
338 ("NVM is Efuse and its size =%x[%x-%x] \n",
339 EFUSE_USAGE_MAP_SIZE, EFUSE_USAGE_MAP_START,
340 EFUSE_USAGE_MAP_END));
341 eFuseGetFreeBlockCount(pAd, &EfuseFreeBlock);