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 u32 EFSROM_LDO_OFF_TIME
:6;
54 u32 EFSROM_LDO_ON_TIME
:2;
61 } EFUSE_CTRL_STRUC
, *PEFUSE_CTRL_STRUC
;
64 ========================================================================
74 ========================================================================
76 u8
eFuseReadRegisters(struct rt_rtmp_adapter
*pAd
,
77 u16 Offset
, u16 Length
, u16
* pData
)
79 EFUSE_CTRL_STRUC eFuseCtrlStruc
;
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 */
126 /* D C B A | D C B A */
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 (u8
)eFuseCtrlStruc
.field
.EFSROM_AOUT
;
140 ========================================================================
150 ========================================================================
152 void eFusePhysicalReadRegisters(struct rt_rtmp_adapter
*pAd
,
154 u16 Length
, u16
* pData
)
156 EFUSE_CTRL_STRUC eFuseCtrlStruc
;
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(struct rt_rtmp_adapter
*pAd
,
219 unsigned long nInBufferSize
,
220 u16
*lpOutBuffer
, unsigned long nOutBufferSize
)
222 u16
*pInBuf
= (u16
*) lpInBuffer
;
223 u16
*pOutBuf
= (u16
*) lpOutBuffer
;
225 u16 Offset
= pInBuf
[0]; /*addr */
226 u16 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(struct rt_rtmp_adapter
*pAd
, char *arg
)
251 u16 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
= (u8
)(EFUSE_USAGE_MAP_END
- i
+ 1);
259 } else if (((LogicalAddress
>> 8) & 0xff) == 0) {
260 efusefreenum
= (u8
)(EFUSE_USAGE_MAP_END
- i
);
264 if (i
== EFUSE_USAGE_MAP_END
)
267 printk(KERN_DEBUG
"efuseFreeNumber is %d\n", efusefreenum
);
271 int set_eFusedump_Proc(struct rt_rtmp_adapter
*pAd
, char *arg
)
278 printk(KERN_DEBUG
"Block 0: ");
280 for (i
= 0; i
< EFUSE_USAGE_MAP_END
/ 2; i
++) {
285 eFuseReadPhysical(pAd
, &InBuf
[0], 4, &InBuf
[2], 2);
286 if (i
&& i
% 4 == 0) {
287 printk(KERN_CONT
"\n");
288 printk(KERN_DEBUG
"Block %x:", i
/ 8);
290 printk(KERN_CONT
"%04x ", InBuf
[2]);
292 printk(KERN_CONT
"\n");
297 int rtmp_ee_efuse_read16(struct rt_rtmp_adapter
*pAd
,
298 u16 Offset
, u16
* pValue
)
300 eFuseReadRegisters(pAd
, Offset
, 2, pValue
);
304 int RtmpEfuseSupportCheck(struct rt_rtmp_adapter
*pAd
)
308 if (IS_RT30xx(pAd
)) {
309 eFusePhysicalReadRegisters(pAd
, EFUSE_TAG
, 2, &value
);
310 pAd
->EFuseTag
= (value
& 0xff);
315 void eFuseGetFreeBlockCount(struct rt_rtmp_adapter
*pAd
, u32
*EfuseFreeBlock
)
319 if (!pAd
->bUseEfuse
) {
320 DBGPRINT(RT_DEBUG_TRACE
,
321 ("eFuseGetFreeBlockCount Only supports efuse Mode\n"));
324 for (i
= EFUSE_USAGE_MAP_START
; i
<= EFUSE_USAGE_MAP_END
; i
+= 2) {
325 eFusePhysicalReadRegisters(pAd
, i
, 2, &LogicalAddress
);
326 if ((LogicalAddress
& 0xff) == 0) {
327 *EfuseFreeBlock
= (u8
)(EFUSE_USAGE_MAP_END
- i
+ 1);
329 } else if (((LogicalAddress
>> 8) & 0xff) == 0) {
330 *EfuseFreeBlock
= (u8
)(EFUSE_USAGE_MAP_END
- i
);
334 if (i
== EFUSE_USAGE_MAP_END
)
337 DBGPRINT(RT_DEBUG_TRACE
,
338 ("eFuseGetFreeBlockCount is 0x%x\n", *EfuseFreeBlock
));
341 int eFuse_init(struct rt_rtmp_adapter
*pAd
)
343 u32 EfuseFreeBlock
= 0;
344 DBGPRINT(RT_DEBUG_ERROR
,
345 ("NVM is Efuse and its size =%x[%x-%x] \n",
346 EFUSE_USAGE_MAP_SIZE
, EFUSE_USAGE_MAP_START
,
347 EFUSE_USAGE_MAP_END
));
348 eFuseGetFreeBlockCount(pAd
, &EfuseFreeBlock
);