1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38#include "../rt_config.h"
39
40#define EFUSE_USAGE_MAP_START 0x2d0
41#define EFUSE_USAGE_MAP_END 0x2fc
42#define EFUSE_USAGE_MAP_SIZE 45
43
44#define EFUSE_EEPROM_DEFULT_FILE "RT30xxEEPROM.bin"
45#define MAX_EEPROM_BIN_FILE_SIZE 1024
46
47#define EFUSE_TAG 0x2fe
48
49typedef union _EFUSE_CTRL_STRUC {
50 struct {
51 u32 EFSROM_AOUT:6;
52 u32 EFSROM_MODE:2;
53 u32 EFSROM_LDO_OFF_TIME:6;
54 u32 EFSROM_LDO_ON_TIME:2;
55 u32 EFSROM_AIN:10;
56 u32 RESERVED:4;
57 u32 EFSROM_KICK:1;
58 u32 SEL_EFUSE:1;
59 } field;
60 u32 word;
61} EFUSE_CTRL_STRUC, *PEFUSE_CTRL_STRUC;
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76u8 eFuseReadRegisters(struct rt_rtmp_adapter *pAd,
77 u16 Offset, u16 Length, u16 * pData)
78{
79 EFUSE_CTRL_STRUC eFuseCtrlStruc;
80 int i;
81 u16 efuseDataOffset;
82 u32 data;
83
84 RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
85
86
87
88 eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
89
90
91 eFuseCtrlStruc.field.EFSROM_MODE = 0;
92
93
94 eFuseCtrlStruc.field.EFSROM_KICK = 1;
95
96 NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
97 RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
98
99
100 i = 0;
101 while (i < 500) {
102
103 RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
104 if (eFuseCtrlStruc.field.EFSROM_KICK == 0) {
105 break;
106 }
107 RTMPusecDelay(2);
108 i++;
109 }
110
111
112 if (eFuseCtrlStruc.field.EFSROM_AOUT == 0x3f) {
113 for (i = 0; i < Length / 2; i++)
114 *(pData + 2 * i) = 0xffff;
115 } else {
116
117 efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC);
118
119
120 RTMP_IO_READ32(pAd, efuseDataOffset, &data);
121
122
123
124
125
126
127
128
129
130 data = data >> (8 * (Offset & 0x3));
131
132 NdisMoveMemory(pData, &data, Length);
133 }
134
135 return (u8)eFuseCtrlStruc.field.EFSROM_AOUT;
136
137}
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152void eFusePhysicalReadRegisters(struct rt_rtmp_adapter *pAd,
153 u16 Offset,
154 u16 Length, u16 * pData)
155{
156 EFUSE_CTRL_STRUC eFuseCtrlStruc;
157 int i;
158 u16 efuseDataOffset;
159 u32 data;
160
161 RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
162
163
164 eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
165
166
167
168 eFuseCtrlStruc.field.EFSROM_MODE = 1;
169
170
171 eFuseCtrlStruc.field.EFSROM_KICK = 1;
172
173 NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
174 RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
175
176
177 i = 0;
178 while (i < 500) {
179 RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
180 if (eFuseCtrlStruc.field.EFSROM_KICK == 0)
181 break;
182 RTMPusecDelay(2);
183 i++;
184 }
185
186
187
188
189
190
191
192
193
194 efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC);
195
196 RTMP_IO_READ32(pAd, efuseDataOffset, &data);
197
198 data = data >> (8 * (Offset & 0x3));
199
200 NdisMoveMemory(pData, &data, Length);
201
202}
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217static void eFuseReadPhysical(struct rt_rtmp_adapter *pAd,
218 u16 *lpInBuffer,
219 unsigned long nInBufferSize,
220 u16 *lpOutBuffer, unsigned long nOutBufferSize)
221{
222 u16 *pInBuf = (u16 *) lpInBuffer;
223 u16 *pOutBuf = (u16 *) lpOutBuffer;
224
225 u16 Offset = pInBuf[0];
226 u16 Length = pInBuf[1];
227 int i;
228
229 for (i = 0; i < Length; i += 2) {
230 eFusePhysicalReadRegisters(pAd, Offset + i, 2, &pOutBuf[i / 2]);
231 }
232}
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247int set_eFuseGetFreeBlockCount_Proc(struct rt_rtmp_adapter *pAd, char *arg)
248{
249 u16 i;
250 u16 LogicalAddress;
251 u16 efusefreenum = 0;
252 if (!pAd->bUseEfuse)
253 return FALSE;
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);
258 break;
259 } else if (((LogicalAddress >> 8) & 0xff) == 0) {
260 efusefreenum = (u8)(EFUSE_USAGE_MAP_END - i);
261 break;
262 }
263
264 if (i == EFUSE_USAGE_MAP_END)
265 efusefreenum = 0;
266 }
267 printk("efuseFreeNumber is %d\n", efusefreenum);
268 return TRUE;
269}
270
271int set_eFusedump_Proc(struct rt_rtmp_adapter *pAd, char *arg)
272{
273 u16 InBuf[3];
274 int i = 0;
275 if (!pAd->bUseEfuse)
276 return FALSE;
277 for (i = 0; i < EFUSE_USAGE_MAP_END / 2; i++) {
278 InBuf[0] = 2 * i;
279 InBuf[1] = 2;
280 InBuf[2] = 0x0;
281
282 eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
283 if (i % 4 == 0)
284 printk("\nBlock %x:", i / 8);
285 printk("%04x ", InBuf[2]);
286 }
287 return TRUE;
288}
289
290int rtmp_ee_efuse_read16(struct rt_rtmp_adapter *pAd,
291 u16 Offset, u16 * pValue)
292{
293 eFuseReadRegisters(pAd, Offset, 2, pValue);
294 return (*pValue);
295}
296
297int RtmpEfuseSupportCheck(struct rt_rtmp_adapter *pAd)
298{
299 u16 value;
300
301 if (IS_RT30xx(pAd)) {
302 eFusePhysicalReadRegisters(pAd, EFUSE_TAG, 2, &value);
303 pAd->EFuseTag = (value & 0xff);
304 }
305 return 0;
306}
307
308void eFuseGetFreeBlockCount(struct rt_rtmp_adapter *pAd, u32 *EfuseFreeBlock)
309{
310 u16 i;
311 u16 LogicalAddress;
312 if (!pAd->bUseEfuse) {
313 DBGPRINT(RT_DEBUG_TRACE,
314 ("eFuseGetFreeBlockCount Only supports efuse Mode\n"));
315 return;
316 }
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 = (u8)(EFUSE_USAGE_MAP_END - i + 1);
321 break;
322 } else if (((LogicalAddress >> 8) & 0xff) == 0) {
323 *EfuseFreeBlock = (u8)(EFUSE_USAGE_MAP_END - i);
324 break;
325 }
326
327 if (i == EFUSE_USAGE_MAP_END)
328 *EfuseFreeBlock = 0;
329 }
330 DBGPRINT(RT_DEBUG_TRACE,
331 ("eFuseGetFreeBlockCount is 0x%x\n", *EfuseFreeBlock));
332}
333
334int eFuse_init(struct rt_rtmp_adapter *pAd)
335{
336 u32 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);
342
343 return 0;
344}
345