1 /******************************************************************************
3 * Copyright(c) 2009-2010 Realtek Corporation.
5 * Tmis program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * Tmis program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * tmis program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
18 * Tme full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
26 * Larry Finger <Larry.Finger@lwfinger.net>
28 *****************************************************************************/
33 static const u8 MAX_PGPKT_SIZE
= 9;
34 static const u8 PGPKT_DATA_SIZE
= 8;
35 static const int EFUSE_MAX_SIZE
= 512;
37 static const u8 EFUSE_OOB_PROTECT_BYTES
= 15;
39 static const struct efuse_map RTL8712_SDIO_EFUSE_TABLE
[] = {
55 static void read_efuse_byte(struct ieee80211_hw
*hw
, u16 _offset
,
57 static void efuse_shadow_read_1byte(struct ieee80211_hw
*hw
, u16 offset
,
59 static void efuse_shadow_read_2byte(struct ieee80211_hw
*hw
, u16 offset
,
61 static void efuse_shadow_read_4byte(struct ieee80211_hw
*hw
, u16 offset
,
63 static void efuse_shadow_write_1byte(struct ieee80211_hw
*hw
, u16 offset
,
65 static void efuse_shadow_write_2byte(struct ieee80211_hw
*hw
, u16 offset
,
67 static void efuse_shadow_write_4byte(struct ieee80211_hw
*hw
, u16 offset
,
69 static int efuse_one_byte_read(struct ieee80211_hw
*hw
, u16 addr
,
71 static int efuse_one_byte_write(struct ieee80211_hw
*hw
, u16 addr
,
73 static void efuse_read_all_map(struct ieee80211_hw
*hw
, u8
*efuse
);
74 static int efuse_pg_packet_read(struct ieee80211_hw
*hw
, u8 offset
,
76 static int efuse_pg_packet_write(struct ieee80211_hw
*hw
, u8 offset
,
77 u8 word_en
, u8
*data
);
78 static void efuse_word_enable_data_read(u8 word_en
, u8
*sourdata
,
80 static u8
efuse_word_enable_data_write(struct ieee80211_hw
*hw
,
81 u16 efuse_addr
, u8 word_en
, u8
*data
);
82 static void efuse_power_switch(struct ieee80211_hw
*hw
, u8 bwrite
,
84 static u16
efuse_get_current_size(struct ieee80211_hw
*hw
);
85 static u8
efuse_calculate_word_cnts(u8 word_en
);
87 void efuse_initialize(struct ieee80211_hw
*hw
)
89 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
93 bytetemp
= rtl_read_byte(rtlpriv
, rtlpriv
->cfg
->maps
[SYS_FUNC_EN
] + 1);
94 temp
= bytetemp
| 0x20;
95 rtl_write_byte(rtlpriv
, rtlpriv
->cfg
->maps
[SYS_FUNC_EN
] + 1, temp
);
97 bytetemp
= rtl_read_byte(rtlpriv
, rtlpriv
->cfg
->maps
[SYS_ISO_CTRL
] + 1);
98 temp
= bytetemp
& 0xFE;
99 rtl_write_byte(rtlpriv
, rtlpriv
->cfg
->maps
[SYS_ISO_CTRL
] + 1, temp
);
101 bytetemp
= rtl_read_byte(rtlpriv
, rtlpriv
->cfg
->maps
[EFUSE_TEST
] + 3);
102 temp
= bytetemp
| 0x80;
103 rtl_write_byte(rtlpriv
, rtlpriv
->cfg
->maps
[EFUSE_TEST
] + 3, temp
);
105 rtl_write_byte(rtlpriv
, 0x2F8, 0x3);
107 rtl_write_byte(rtlpriv
, rtlpriv
->cfg
->maps
[EFUSE_CTRL
] + 3, 0x72);
111 u8
efuse_read_1byte(struct ieee80211_hw
*hw
, u16 address
)
113 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
119 if (address
< EFUSE_REAL_CONTENT_LEN
) {
120 temp
= address
& 0xFF;
121 rtl_write_byte(rtlpriv
, rtlpriv
->cfg
->maps
[EFUSE_CTRL
] + 1,
123 bytetemp
= rtl_read_byte(rtlpriv
,
124 rtlpriv
->cfg
->maps
[EFUSE_CTRL
] + 2);
125 temp
= ((address
>> 8) & 0x03) | (bytetemp
& 0xFC);
126 rtl_write_byte(rtlpriv
, rtlpriv
->cfg
->maps
[EFUSE_CTRL
] + 2,
129 bytetemp
= rtl_read_byte(rtlpriv
,
130 rtlpriv
->cfg
->maps
[EFUSE_CTRL
] + 3);
131 temp
= bytetemp
& 0x7F;
132 rtl_write_byte(rtlpriv
, rtlpriv
->cfg
->maps
[EFUSE_CTRL
] + 3,
135 bytetemp
= rtl_read_byte(rtlpriv
,
136 rtlpriv
->cfg
->maps
[EFUSE_CTRL
] + 3);
137 while (!(bytetemp
& 0x80)) {
138 bytetemp
= rtl_read_byte(rtlpriv
,
140 maps
[EFUSE_CTRL
] + 3);
147 data
= rtl_read_byte(rtlpriv
, rtlpriv
->cfg
->maps
[EFUSE_CTRL
]);
153 EXPORT_SYMBOL(efuse_read_1byte
);
155 void efuse_write_1byte(struct ieee80211_hw
*hw
, u16 address
, u8 value
)
157 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
162 RT_TRACE(rtlpriv
, COMP_EFUSE
, DBG_LOUD
,
163 ("Addr=%x Data =%x\n", address
, value
));
165 if (address
< EFUSE_REAL_CONTENT_LEN
) {
166 rtl_write_byte(rtlpriv
, rtlpriv
->cfg
->maps
[EFUSE_CTRL
], value
);
168 temp
= address
& 0xFF;
169 rtl_write_byte(rtlpriv
, rtlpriv
->cfg
->maps
[EFUSE_CTRL
] + 1,
171 bytetemp
= rtl_read_byte(rtlpriv
,
172 rtlpriv
->cfg
->maps
[EFUSE_CTRL
] + 2);
174 temp
= ((address
>> 8) & 0x03) | (bytetemp
& 0xFC);
175 rtl_write_byte(rtlpriv
,
176 rtlpriv
->cfg
->maps
[EFUSE_CTRL
] + 2, temp
);
178 bytetemp
= rtl_read_byte(rtlpriv
,
179 rtlpriv
->cfg
->maps
[EFUSE_CTRL
] + 3);
180 temp
= bytetemp
| 0x80;
181 rtl_write_byte(rtlpriv
,
182 rtlpriv
->cfg
->maps
[EFUSE_CTRL
] + 3, temp
);
184 bytetemp
= rtl_read_byte(rtlpriv
,
185 rtlpriv
->cfg
->maps
[EFUSE_CTRL
] + 3);
187 while (bytetemp
& 0x80) {
188 bytetemp
= rtl_read_byte(rtlpriv
,
190 maps
[EFUSE_CTRL
] + 3);
201 static void read_efuse_byte(struct ieee80211_hw
*hw
, u16 _offset
, u8
*pbuf
)
203 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
208 rtl_write_byte(rtlpriv
, rtlpriv
->cfg
->maps
[EFUSE_CTRL
] + 1,
210 readbyte
= rtl_read_byte(rtlpriv
, rtlpriv
->cfg
->maps
[EFUSE_CTRL
] + 2);
211 rtl_write_byte(rtlpriv
, rtlpriv
->cfg
->maps
[EFUSE_CTRL
] + 2,
212 ((_offset
>> 8) & 0x03) | (readbyte
& 0xfc));
214 readbyte
= rtl_read_byte(rtlpriv
, rtlpriv
->cfg
->maps
[EFUSE_CTRL
] + 3);
215 rtl_write_byte(rtlpriv
, rtlpriv
->cfg
->maps
[EFUSE_CTRL
] + 3,
219 value32
= rtl_read_dword(rtlpriv
, rtlpriv
->cfg
->maps
[EFUSE_CTRL
]);
220 while (!(((value32
>> 24) & 0xff) & 0x80) && (retry
< 10000)) {
221 value32
= rtl_read_dword(rtlpriv
,
222 rtlpriv
->cfg
->maps
[EFUSE_CTRL
]);
227 value32
= rtl_read_dword(rtlpriv
, rtlpriv
->cfg
->maps
[EFUSE_CTRL
]);
229 *pbuf
= (u8
) (value32
& 0xff);
232 void read_efuse(struct ieee80211_hw
*hw
, u16 _offset
, u16 _size_byte
, u8
*pbuf
)
234 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
235 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
236 u8 efuse_tbl
[EFUSE_MAP_LEN
];
242 u16 efuse_word
[EFUSE_MAX_SECTION
][EFUSE_MAX_WORD_UNIT
];
243 u16 efuse_utilized
= 0;
246 if ((_offset
+ _size_byte
) > EFUSE_MAP_LEN
) {
247 RT_TRACE(rtlpriv
, COMP_EFUSE
, DBG_LOUD
,
248 ("read_efuse(): Invalid offset(%#x) with read "
249 "bytes(%#x)!!\n", _offset
, _size_byte
));
253 for (i
= 0; i
< EFUSE_MAX_SECTION
; i
++)
254 for (j
= 0; j
< EFUSE_MAX_WORD_UNIT
; j
++)
255 efuse_word
[i
][j
] = 0xFFFF;
257 read_efuse_byte(hw
, efuse_addr
, rtemp8
);
258 if (*rtemp8
!= 0xFF) {
260 RTPRINT(rtlpriv
, FEEPROM
, EFUSE_READ_ALL
,
261 ("Addr=%d\n", efuse_addr
));
265 while ((*rtemp8
!= 0xFF) && (efuse_addr
< EFUSE_REAL_CONTENT_LEN
)) {
266 offset
= ((*rtemp8
>> 4) & 0x0f);
268 if (offset
< EFUSE_MAX_SECTION
) {
269 wren
= (*rtemp8
& 0x0f);
270 RTPRINT(rtlpriv
, FEEPROM
, EFUSE_READ_ALL
,
271 ("offset-%d Worden=%x\n", offset
, wren
));
273 for (i
= 0; i
< EFUSE_MAX_WORD_UNIT
; i
++) {
274 if (!(wren
& 0x01)) {
275 RTPRINT(rtlpriv
, FEEPROM
,
276 EFUSE_READ_ALL
, ("Addr=%d\n",
279 read_efuse_byte(hw
, efuse_addr
, rtemp8
);
282 efuse_word
[offset
][i
] = (*rtemp8
& 0xff);
284 if (efuse_addr
>= EFUSE_REAL_CONTENT_LEN
)
287 RTPRINT(rtlpriv
, FEEPROM
,
288 EFUSE_READ_ALL
, ("Addr=%d\n",
291 read_efuse_byte(hw
, efuse_addr
, rtemp8
);
294 efuse_word
[offset
][i
] |=
295 (((u16
)*rtemp8
<< 8) & 0xff00);
297 if (efuse_addr
>= EFUSE_REAL_CONTENT_LEN
)
305 RTPRINT(rtlpriv
, FEEPROM
, EFUSE_READ_ALL
,
306 ("Addr=%d\n", efuse_addr
));
307 read_efuse_byte(hw
, efuse_addr
, rtemp8
);
308 if (*rtemp8
!= 0xFF && (efuse_addr
< 512)) {
314 for (i
= 0; i
< EFUSE_MAX_SECTION
; i
++) {
315 for (j
= 0; j
< EFUSE_MAX_WORD_UNIT
; j
++) {
316 efuse_tbl
[(i
* 8) + (j
* 2)] =
317 (efuse_word
[i
][j
] & 0xff);
318 efuse_tbl
[(i
* 8) + ((j
* 2) + 1)] =
319 ((efuse_word
[i
][j
] >> 8) & 0xff);
323 for (i
= 0; i
< _size_byte
; i
++)
324 pbuf
[i
] = efuse_tbl
[_offset
+ i
];
326 rtlefuse
->efuse_usedbytes
= efuse_utilized
;
327 efuse_usage
= (u8
)((efuse_utilized
* 100) / EFUSE_REAL_CONTENT_LEN
);
328 rtlefuse
->efuse_usedpercentage
= efuse_usage
;
329 rtlpriv
->cfg
->ops
->set_hw_reg(hw
, HW_VAR_EFUSE_BYTES
,
330 (u8
*)&efuse_utilized
);
331 rtlpriv
->cfg
->ops
->set_hw_reg(hw
, HW_VAR_EFUSE_USAGE
,
335 bool efuse_shadow_update_chk(struct ieee80211_hw
*hw
)
337 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
338 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
339 u8 section_idx
, i
, Base
;
340 u16 words_need
= 0, hdr_num
= 0, totalbytes
, efuse_used
;
341 bool bwordchanged
, bresult
= true;
343 for (section_idx
= 0; section_idx
< 16; section_idx
++) {
344 Base
= section_idx
* 8;
345 bwordchanged
= false;
347 for (i
= 0; i
< 8; i
= i
+ 2) {
348 if ((rtlefuse
->efuse_map
[EFUSE_INIT_MAP
][Base
+ i
] !=
349 rtlefuse
->efuse_map
[EFUSE_MODIFY_MAP
][Base
+ i
]) ||
350 (rtlefuse
->efuse_map
[EFUSE_INIT_MAP
][Base
+ i
+ 1] !=
351 rtlefuse
->efuse_map
[EFUSE_MODIFY_MAP
][Base
+ i
+
358 if (bwordchanged
== true)
362 totalbytes
= hdr_num
+ words_need
* 2;
363 efuse_used
= rtlefuse
->efuse_usedbytes
;
365 if ((totalbytes
+ efuse_used
) >=
366 (EFUSE_MAX_SIZE
- EFUSE_OOB_PROTECT_BYTES
))
369 RT_TRACE(rtlpriv
, COMP_EFUSE
, DBG_LOUD
,
370 ("efuse_shadow_update_chk(): totalbytes(%#x), "
371 "hdr_num(%#x), words_need(%#x), efuse_used(%d)\n",
372 totalbytes
, hdr_num
, words_need
, efuse_used
));
377 void efuse_shadow_read(struct ieee80211_hw
*hw
, u8 type
,
378 u16 offset
, u32
*value
)
381 efuse_shadow_read_1byte(hw
, offset
, (u8
*) value
);
383 efuse_shadow_read_2byte(hw
, offset
, (u16
*) value
);
385 efuse_shadow_read_4byte(hw
, offset
, (u32
*) value
);
389 void efuse_shadow_write(struct ieee80211_hw
*hw
, u8 type
, u16 offset
,
393 efuse_shadow_write_1byte(hw
, offset
, (u8
) value
);
395 efuse_shadow_write_2byte(hw
, offset
, (u16
) value
);
397 efuse_shadow_write_4byte(hw
, offset
, (u32
) value
);
401 bool efuse_shadow_update(struct ieee80211_hw
*hw
)
403 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
404 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
409 RT_TRACE(rtlpriv
, COMP_EFUSE
, DBG_LOUD
, ("--->\n"));
411 if (!efuse_shadow_update_chk(hw
)) {
412 efuse_read_all_map(hw
, &rtlefuse
->efuse_map
[EFUSE_INIT_MAP
][0]);
413 memcpy((void *)&rtlefuse
->efuse_map
[EFUSE_MODIFY_MAP
][0],
414 (void *)&rtlefuse
->efuse_map
[EFUSE_INIT_MAP
][0],
415 rtlpriv
->cfg
->maps
[EFUSE_HWSET_MAX_SIZE
]);
417 RT_TRACE(rtlpriv
, COMP_EFUSE
, DBG_LOUD
,
418 ("<---efuse out of capacity!!\n"));
421 efuse_power_switch(hw
, true, true);
423 for (offset
= 0; offset
< 16; offset
++) {
428 for (i
= 0; i
< 8; i
++) {
429 if (first_pg
== true) {
431 word_en
&= ~(BIT(i
/ 2));
433 rtlefuse
->efuse_map
[EFUSE_INIT_MAP
][base
+ i
] =
434 rtlefuse
->efuse_map
[EFUSE_MODIFY_MAP
][base
+ i
];
437 if (rtlefuse
->efuse_map
[EFUSE_INIT_MAP
][base
+ i
] !=
438 rtlefuse
->efuse_map
[EFUSE_MODIFY_MAP
][base
+ i
]) {
439 word_en
&= ~(BIT(i
/ 2));
441 rtlefuse
->efuse_map
[EFUSE_INIT_MAP
][base
+ i
] =
442 rtlefuse
->efuse_map
[EFUSE_MODIFY_MAP
][base
+ i
];
447 if (word_en
!= 0x0F) {
449 memcpy((void *)tmpdata
,
451 efuse_map
[EFUSE_MODIFY_MAP
][base
]), 8);
452 RT_PRINT_DATA(rtlpriv
, COMP_INIT
, DBG_LOUD
,
453 ("U-efuse\n"), tmpdata
, 8);
455 if (!efuse_pg_packet_write(hw
, (u8
) offset
, word_en
,
457 RT_TRACE(rtlpriv
, COMP_ERR
, DBG_WARNING
,
458 ("PG section(%#x) fail!!\n", offset
));
465 efuse_power_switch(hw
, true, false);
466 efuse_read_all_map(hw
, &rtlefuse
->efuse_map
[EFUSE_INIT_MAP
][0]);
468 memcpy((void *)&rtlefuse
->efuse_map
[EFUSE_MODIFY_MAP
][0],
469 (void *)&rtlefuse
->efuse_map
[EFUSE_INIT_MAP
][0],
470 rtlpriv
->cfg
->maps
[EFUSE_HWSET_MAX_SIZE
]);
472 RT_TRACE(rtlpriv
, COMP_EFUSE
, DBG_LOUD
, ("<---\n"));
476 void rtl_efuse_shadow_map_update(struct ieee80211_hw
*hw
)
478 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
479 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
481 if (rtlefuse
->autoload_failflag
== true) {
482 memset((void *)(&rtlefuse
->efuse_map
[EFUSE_INIT_MAP
][0]), 128,
485 efuse_read_all_map(hw
, &rtlefuse
->efuse_map
[EFUSE_INIT_MAP
][0]);
487 memcpy((void *)&rtlefuse
->efuse_map
[EFUSE_MODIFY_MAP
][0],
488 (void *)&rtlefuse
->efuse_map
[EFUSE_INIT_MAP
][0],
489 rtlpriv
->cfg
->maps
[EFUSE_HWSET_MAX_SIZE
]);
492 EXPORT_SYMBOL(rtl_efuse_shadow_map_update
);
494 void efuse_force_write_vendor_Id(struct ieee80211_hw
*hw
)
496 u8 tmpdata
[8] = { 0xFF, 0xFF, 0xEC, 0x10, 0xFF, 0xFF, 0xFF, 0xFF };
498 efuse_power_switch(hw
, true, true);
500 efuse_pg_packet_write(hw
, 1, 0xD, tmpdata
);
502 efuse_power_switch(hw
, true, false);
506 void efuse_re_pg_section(struct ieee80211_hw
*hw
, u8 section_idx
)
510 static void efuse_shadow_read_1byte(struct ieee80211_hw
*hw
,
511 u16 offset
, u8
*value
)
513 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
514 *value
= rtlefuse
->efuse_map
[EFUSE_MODIFY_MAP
][offset
];
517 static void efuse_shadow_read_2byte(struct ieee80211_hw
*hw
,
518 u16 offset
, u16
*value
)
520 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
522 *value
= rtlefuse
->efuse_map
[EFUSE_MODIFY_MAP
][offset
];
523 *value
|= rtlefuse
->efuse_map
[EFUSE_MODIFY_MAP
][offset
+ 1] << 8;
527 static void efuse_shadow_read_4byte(struct ieee80211_hw
*hw
,
528 u16 offset
, u32
*value
)
530 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
532 *value
= rtlefuse
->efuse_map
[EFUSE_MODIFY_MAP
][offset
];
533 *value
|= rtlefuse
->efuse_map
[EFUSE_MODIFY_MAP
][offset
+ 1] << 8;
534 *value
|= rtlefuse
->efuse_map
[EFUSE_MODIFY_MAP
][offset
+ 2] << 16;
535 *value
|= rtlefuse
->efuse_map
[EFUSE_MODIFY_MAP
][offset
+ 3] << 24;
538 static void efuse_shadow_write_1byte(struct ieee80211_hw
*hw
,
539 u16 offset
, u8 value
)
541 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
543 rtlefuse
->efuse_map
[EFUSE_MODIFY_MAP
][offset
] = value
;
546 static void efuse_shadow_write_2byte(struct ieee80211_hw
*hw
,
547 u16 offset
, u16 value
)
549 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
551 rtlefuse
->efuse_map
[EFUSE_MODIFY_MAP
][offset
] = value
& 0x00FF;
552 rtlefuse
->efuse_map
[EFUSE_MODIFY_MAP
][offset
+ 1] = value
>> 8;
556 static void efuse_shadow_write_4byte(struct ieee80211_hw
*hw
,
557 u16 offset
, u32 value
)
559 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
561 rtlefuse
->efuse_map
[EFUSE_MODIFY_MAP
][offset
] =
562 (u8
) (value
& 0x000000FF);
563 rtlefuse
->efuse_map
[EFUSE_MODIFY_MAP
][offset
+ 1] =
564 (u8
) ((value
>> 8) & 0x0000FF);
565 rtlefuse
->efuse_map
[EFUSE_MODIFY_MAP
][offset
+ 2] =
566 (u8
) ((value
>> 16) & 0x00FF);
567 rtlefuse
->efuse_map
[EFUSE_MODIFY_MAP
][offset
+ 3] =
568 (u8
) ((value
>> 24) & 0xFF);
572 static int efuse_one_byte_read(struct ieee80211_hw
*hw
, u16 addr
, u8
*data
)
574 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
578 rtl_write_byte(rtlpriv
, rtlpriv
->cfg
->maps
[EFUSE_CTRL
] + 1,
580 rtl_write_byte(rtlpriv
, rtlpriv
->cfg
->maps
[EFUSE_CTRL
] + 2,
581 ((u8
) ((addr
>> 8) & 0x03)) |
582 (rtl_read_byte(rtlpriv
,
583 rtlpriv
->cfg
->maps
[EFUSE_CTRL
] + 2) &
586 rtl_write_byte(rtlpriv
, rtlpriv
->cfg
->maps
[EFUSE_CTRL
] + 3, 0x72);
588 while (!(0x80 & rtl_read_byte(rtlpriv
,
589 rtlpriv
->cfg
->maps
[EFUSE_CTRL
] + 3))
595 *data
= rtl_read_byte(rtlpriv
, rtlpriv
->cfg
->maps
[EFUSE_CTRL
]);
604 static int efuse_one_byte_write(struct ieee80211_hw
*hw
, u16 addr
, u8 data
)
606 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
610 RT_TRACE(rtlpriv
, COMP_EFUSE
, DBG_LOUD
,
611 ("Addr = %x Data=%x\n", addr
, data
));
613 rtl_write_byte(rtlpriv
,
614 rtlpriv
->cfg
->maps
[EFUSE_CTRL
] + 1, (u8
) (addr
& 0xff));
615 rtl_write_byte(rtlpriv
, rtlpriv
->cfg
->maps
[EFUSE_CTRL
] + 2,
616 (rtl_read_byte(rtlpriv
,
617 rtlpriv
->cfg
->maps
[EFUSE_CTRL
] +
618 2) & 0xFC) | (u8
) ((addr
>> 8) & 0x03));
620 rtl_write_byte(rtlpriv
, rtlpriv
->cfg
->maps
[EFUSE_CTRL
], data
);
621 rtl_write_byte(rtlpriv
, rtlpriv
->cfg
->maps
[EFUSE_CTRL
] + 3, 0xF2);
623 while ((0x80 & rtl_read_byte(rtlpriv
,
624 rtlpriv
->cfg
->maps
[EFUSE_CTRL
] + 3))
637 static void efuse_read_all_map(struct ieee80211_hw
*hw
, u8
* efuse
)
639 efuse_power_switch(hw
, false, true);
640 read_efuse(hw
, 0, 128, efuse
);
641 efuse_power_switch(hw
, false, false);
644 static void efuse_read_data_case1(struct ieee80211_hw
*hw
, u16
*efuse_addr
,
645 u8 efuse_data
, u8 offset
, u8
*tmpdata
,
648 bool bdataempty
= true;
654 hoffset
= (efuse_data
>> 4) & 0x0F;
655 hworden
= efuse_data
& 0x0F;
656 word_cnts
= efuse_calculate_word_cnts(hworden
);
658 if (hoffset
== offset
) {
659 for (tmpidx
= 0; tmpidx
< word_cnts
* 2; tmpidx
++) {
660 if (efuse_one_byte_read(hw
, *efuse_addr
+ 1 + tmpidx
,
662 tmpdata
[tmpidx
] = efuse_data
;
663 if (efuse_data
!= 0xff)
668 if (bdataempty
== true)
669 *readstate
= PG_STATE_DATA
;
671 *efuse_addr
= *efuse_addr
+ (word_cnts
* 2) + 1;
672 *readstate
= PG_STATE_HEADER
;
676 *efuse_addr
= *efuse_addr
+ (word_cnts
* 2) + 1;
677 *readstate
= PG_STATE_HEADER
;
681 static int efuse_pg_packet_read(struct ieee80211_hw
*hw
, u8 offset
, u8
*data
)
683 u8 readstate
= PG_STATE_HEADER
;
685 bool bcontinual
= true;
687 u8 efuse_data
, word_cnts
= 0;
697 memset((void *)data
, PGPKT_DATA_SIZE
* sizeof(u8
), 0xff);
698 memset((void *)tmpdata
, PGPKT_DATA_SIZE
* sizeof(u8
), 0xff);
700 while (bcontinual
&& (efuse_addr
< EFUSE_MAX_SIZE
)) {
701 if (readstate
& PG_STATE_HEADER
) {
702 if (efuse_one_byte_read(hw
, efuse_addr
, &efuse_data
)
703 && (efuse_data
!= 0xFF))
704 efuse_read_data_case1(hw
, &efuse_addr
,
710 } else if (readstate
& PG_STATE_DATA
) {
711 efuse_word_enable_data_read(hworden
, tmpdata
, data
);
712 efuse_addr
= efuse_addr
+ (word_cnts
* 2) + 1;
713 readstate
= PG_STATE_HEADER
;
718 if ((data
[0] == 0xff) && (data
[1] == 0xff) &&
719 (data
[2] == 0xff) && (data
[3] == 0xff) &&
720 (data
[4] == 0xff) && (data
[5] == 0xff) &&
721 (data
[6] == 0xff) && (data
[7] == 0xff))
728 static void efuse_write_data_case1(struct ieee80211_hw
*hw
, u16
*efuse_addr
,
729 u8 efuse_data
, u8 offset
, int *bcontinual
,
730 u8
*write_state
, struct pgpkt_struct target_pkt
,
731 int *repeat_times
, int *bresult
, u8 word_en
)
733 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
734 struct pgpkt_struct tmp_pkt
;
735 int bdataempty
= true;
736 u8 originaldata
[8 * sizeof(u8
)];
738 u8 match_word_en
, tmp_word_en
;
740 u8 tmp_header
= efuse_data
;
743 tmp_pkt
.offset
= (tmp_header
>> 4) & 0x0F;
744 tmp_pkt
.word_en
= tmp_header
& 0x0F;
745 tmp_word_cnts
= efuse_calculate_word_cnts(tmp_pkt
.word_en
);
747 if (tmp_pkt
.offset
!= target_pkt
.offset
) {
748 efuse_addr
= efuse_addr
+ (tmp_word_cnts
* 2) + 1;
749 *write_state
= PG_STATE_HEADER
;
751 for (tmpindex
= 0; tmpindex
< (tmp_word_cnts
* 2); tmpindex
++) {
752 u16 address
= *efuse_addr
+ 1 + tmpindex
;
753 if (efuse_one_byte_read(hw
, address
,
754 &efuse_data
) && (efuse_data
!= 0xFF))
758 if (bdataempty
== false) {
759 efuse_addr
= efuse_addr
+ (tmp_word_cnts
* 2) + 1;
760 *write_state
= PG_STATE_HEADER
;
762 match_word_en
= 0x0F;
763 if (!((target_pkt
.word_en
& BIT(0)) |
764 (tmp_pkt
.word_en
& BIT(0))))
765 match_word_en
&= (~BIT(0));
767 if (!((target_pkt
.word_en
& BIT(1)) |
768 (tmp_pkt
.word_en
& BIT(1))))
769 match_word_en
&= (~BIT(1));
771 if (!((target_pkt
.word_en
& BIT(2)) |
772 (tmp_pkt
.word_en
& BIT(2))))
773 match_word_en
&= (~BIT(2));
775 if (!((target_pkt
.word_en
& BIT(3)) |
776 (tmp_pkt
.word_en
& BIT(3))))
777 match_word_en
&= (~BIT(3));
779 if ((match_word_en
& 0x0F) != 0x0F) {
780 badworden
= efuse_word_enable_data_write(
785 if (0x0F != (badworden
& 0x0F)) {
786 u8 reorg_offset
= offset
;
787 u8 reorg_worden
= badworden
;
788 efuse_pg_packet_write(hw
, reorg_offset
,
794 if ((target_pkt
.word_en
& BIT(0)) ^
795 (match_word_en
& BIT(0)))
796 tmp_word_en
&= (~BIT(0));
798 if ((target_pkt
.word_en
& BIT(1)) ^
799 (match_word_en
& BIT(1)))
800 tmp_word_en
&= (~BIT(1));
802 if ((target_pkt
.word_en
& BIT(2)) ^
803 (match_word_en
& BIT(2)))
804 tmp_word_en
&= (~BIT(2));
806 if ((target_pkt
.word_en
& BIT(3)) ^
807 (match_word_en
& BIT(3)))
808 tmp_word_en
&= (~BIT(3));
810 if ((tmp_word_en
& 0x0F) != 0x0F) {
811 *efuse_addr
= efuse_get_current_size(hw
);
812 target_pkt
.offset
= offset
;
813 target_pkt
.word_en
= tmp_word_en
;
816 *write_state
= PG_STATE_HEADER
;
818 if (*repeat_times
> EFUSE_REPEAT_THRESHOLD_
) {
823 *efuse_addr
+= (2 * tmp_word_cnts
) + 1;
824 target_pkt
.offset
= offset
;
825 target_pkt
.word_en
= word_en
;
826 *write_state
= PG_STATE_HEADER
;
830 RTPRINT(rtlpriv
, FEEPROM
, EFUSE_PG
, ("efuse PG_STATE_HEADER-1\n"));
833 static void efuse_write_data_case2(struct ieee80211_hw
*hw
, u16
*efuse_addr
,
834 int *bcontinual
, u8
*write_state
,
835 struct pgpkt_struct target_pkt
,
836 int *repeat_times
, int *bresult
)
838 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
839 struct pgpkt_struct tmp_pkt
;
842 u8 originaldata
[8 * sizeof(u8
)];
846 pg_header
= ((target_pkt
.offset
<< 4) & 0xf0) | target_pkt
.word_en
;
847 efuse_one_byte_write(hw
, *efuse_addr
, pg_header
);
848 efuse_one_byte_read(hw
, *efuse_addr
, &tmp_header
);
850 if (tmp_header
== pg_header
)
851 *write_state
= PG_STATE_DATA
;
852 else if (tmp_header
== 0xFF) {
853 *write_state
= PG_STATE_HEADER
;
855 if (*repeat_times
> EFUSE_REPEAT_THRESHOLD_
) {
860 tmp_pkt
.offset
= (tmp_header
>> 4) & 0x0F;
861 tmp_pkt
.word_en
= tmp_header
& 0x0F;
863 tmp_word_cnts
= efuse_calculate_word_cnts(tmp_pkt
.word_en
);
865 memset((void *)originaldata
, 8 * sizeof(u8
), 0xff);
867 if (efuse_pg_packet_read(hw
, tmp_pkt
.offset
, originaldata
)) {
868 badworden
= efuse_word_enable_data_write(hw
,
869 *efuse_addr
+ 1, tmp_pkt
.word_en
,
872 if (0x0F != (badworden
& 0x0F)) {
873 u8 reorg_offset
= tmp_pkt
.offset
;
874 u8 reorg_worden
= badworden
;
875 efuse_pg_packet_write(hw
, reorg_offset
,
878 *efuse_addr
= efuse_get_current_size(hw
);
880 *efuse_addr
= *efuse_addr
+ (tmp_word_cnts
* 2)
883 *efuse_addr
= *efuse_addr
+ (tmp_word_cnts
* 2) + 1;
885 *write_state
= PG_STATE_HEADER
;
887 if (*repeat_times
> EFUSE_REPEAT_THRESHOLD_
) {
892 RTPRINT(rtlpriv
, FEEPROM
, EFUSE_PG
,
893 ("efuse PG_STATE_HEADER-2\n"));
897 static int efuse_pg_packet_write(struct ieee80211_hw
*hw
,
898 u8 offset
, u8 word_en
, u8
*data
)
900 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
901 struct pgpkt_struct target_pkt
;
902 u8 write_state
= PG_STATE_HEADER
;
903 int bcontinual
= true, bdataempty
= true, bresult
= true;
906 u8 target_word_cnts
= 0;
908 static int repeat_times
;
910 if (efuse_get_current_size(hw
) >=
911 (EFUSE_MAX_SIZE
- EFUSE_OOB_PROTECT_BYTES
)) {
912 RTPRINT(rtlpriv
, FEEPROM
, EFUSE_PG
,
913 ("efuse_pg_packet_write error\n"));
917 target_pkt
.offset
= offset
;
918 target_pkt
.word_en
= word_en
;
920 memset((void *)target_pkt
.data
, 8 * sizeof(u8
), 0xFF);
922 efuse_word_enable_data_read(word_en
, data
, target_pkt
.data
);
923 target_word_cnts
= efuse_calculate_word_cnts(target_pkt
.word_en
);
925 RTPRINT(rtlpriv
, FEEPROM
, EFUSE_PG
, ("efuse Power ON\n"));
927 while (bcontinual
&& (efuse_addr
<
928 (EFUSE_MAX_SIZE
- EFUSE_OOB_PROTECT_BYTES
))) {
930 if (write_state
== PG_STATE_HEADER
) {
933 RTPRINT(rtlpriv
, FEEPROM
, EFUSE_PG
,
934 ("efuse PG_STATE_HEADER\n"));
936 if (efuse_one_byte_read(hw
, efuse_addr
, &efuse_data
) &&
937 (efuse_data
!= 0xFF))
938 efuse_write_data_case1(hw
, &efuse_addr
,
941 &write_state
, target_pkt
,
942 &repeat_times
, &bresult
,
945 efuse_write_data_case2(hw
, &efuse_addr
,
952 } else if (write_state
== PG_STATE_DATA
) {
953 RTPRINT(rtlpriv
, FEEPROM
, EFUSE_PG
,
954 ("efuse PG_STATE_DATA\n"));
957 efuse_word_enable_data_write(hw
, efuse_addr
+ 1,
961 if ((badworden
& 0x0F) == 0x0F) {
965 efuse_addr
+ (2 * target_word_cnts
) + 1;
967 target_pkt
.offset
= offset
;
968 target_pkt
.word_en
= badworden
;
970 efuse_calculate_word_cnts(target_pkt
.
972 write_state
= PG_STATE_HEADER
;
974 if (repeat_times
> EFUSE_REPEAT_THRESHOLD_
) {
978 RTPRINT(rtlpriv
, FEEPROM
, EFUSE_PG
,
979 ("efuse PG_STATE_HEADER-3\n"));
984 if (efuse_addr
>= (EFUSE_MAX_SIZE
- EFUSE_OOB_PROTECT_BYTES
)) {
985 RT_TRACE(rtlpriv
, COMP_EFUSE
, DBG_LOUD
,
986 ("efuse_addr(%#x) Out of size!!\n", efuse_addr
));
992 static void efuse_word_enable_data_read(u8 word_en
,
993 u8
*sourdata
, u8
*targetdata
)
995 if (!(word_en
& BIT(0))) {
996 targetdata
[0] = sourdata
[0];
997 targetdata
[1] = sourdata
[1];
1000 if (!(word_en
& BIT(1))) {
1001 targetdata
[2] = sourdata
[2];
1002 targetdata
[3] = sourdata
[3];
1005 if (!(word_en
& BIT(2))) {
1006 targetdata
[4] = sourdata
[4];
1007 targetdata
[5] = sourdata
[5];
1010 if (!(word_en
& BIT(3))) {
1011 targetdata
[6] = sourdata
[6];
1012 targetdata
[7] = sourdata
[7];
1016 static u8
efuse_word_enable_data_write(struct ieee80211_hw
*hw
,
1017 u16 efuse_addr
, u8 word_en
, u8
*data
)
1019 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1021 u16 start_addr
= efuse_addr
;
1022 u8 badworden
= 0x0F;
1025 memset((void *)tmpdata
, PGPKT_DATA_SIZE
, 0xff);
1026 RT_TRACE(rtlpriv
, COMP_EFUSE
, DBG_LOUD
,
1027 ("word_en = %x efuse_addr=%x\n", word_en
, efuse_addr
));
1029 if (!(word_en
& BIT(0))) {
1030 tmpaddr
= start_addr
;
1031 efuse_one_byte_write(hw
, start_addr
++, data
[0]);
1032 efuse_one_byte_write(hw
, start_addr
++, data
[1]);
1034 efuse_one_byte_read(hw
, tmpaddr
, &tmpdata
[0]);
1035 efuse_one_byte_read(hw
, tmpaddr
+ 1, &tmpdata
[1]);
1036 if ((data
[0] != tmpdata
[0]) || (data
[1] != tmpdata
[1]))
1037 badworden
&= (~BIT(0));
1040 if (!(word_en
& BIT(1))) {
1041 tmpaddr
= start_addr
;
1042 efuse_one_byte_write(hw
, start_addr
++, data
[2]);
1043 efuse_one_byte_write(hw
, start_addr
++, data
[3]);
1045 efuse_one_byte_read(hw
, tmpaddr
, &tmpdata
[2]);
1046 efuse_one_byte_read(hw
, tmpaddr
+ 1, &tmpdata
[3]);
1047 if ((data
[2] != tmpdata
[2]) || (data
[3] != tmpdata
[3]))
1048 badworden
&= (~BIT(1));
1051 if (!(word_en
& BIT(2))) {
1052 tmpaddr
= start_addr
;
1053 efuse_one_byte_write(hw
, start_addr
++, data
[4]);
1054 efuse_one_byte_write(hw
, start_addr
++, data
[5]);
1056 efuse_one_byte_read(hw
, tmpaddr
, &tmpdata
[4]);
1057 efuse_one_byte_read(hw
, tmpaddr
+ 1, &tmpdata
[5]);
1058 if ((data
[4] != tmpdata
[4]) || (data
[5] != tmpdata
[5]))
1059 badworden
&= (~BIT(2));
1062 if (!(word_en
& BIT(3))) {
1063 tmpaddr
= start_addr
;
1064 efuse_one_byte_write(hw
, start_addr
++, data
[6]);
1065 efuse_one_byte_write(hw
, start_addr
++, data
[7]);
1067 efuse_one_byte_read(hw
, tmpaddr
, &tmpdata
[6]);
1068 efuse_one_byte_read(hw
, tmpaddr
+ 1, &tmpdata
[7]);
1069 if ((data
[6] != tmpdata
[6]) || (data
[7] != tmpdata
[7]))
1070 badworden
&= (~BIT(3));
1076 static void efuse_power_switch(struct ieee80211_hw
*hw
, u8 bwrite
, u8 pwrstate
)
1078 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1082 if (pwrstate
== true) {
1083 tmpV16
= rtl_read_word(rtlpriv
,
1084 rtlpriv
->cfg
->maps
[SYS_ISO_CTRL
]);
1085 if (!(tmpV16
& rtlpriv
->cfg
->maps
[EFUSE_PWC_EV12V
])) {
1086 tmpV16
|= rtlpriv
->cfg
->maps
[EFUSE_PWC_EV12V
];
1087 rtl_write_word(rtlpriv
,
1088 rtlpriv
->cfg
->maps
[SYS_ISO_CTRL
],
1092 tmpV16
= rtl_read_word(rtlpriv
,
1093 rtlpriv
->cfg
->maps
[SYS_FUNC_EN
]);
1094 if (!(tmpV16
& rtlpriv
->cfg
->maps
[EFUSE_FEN_ELDR
])) {
1095 tmpV16
|= rtlpriv
->cfg
->maps
[EFUSE_FEN_ELDR
];
1096 rtl_write_word(rtlpriv
,
1097 rtlpriv
->cfg
->maps
[SYS_FUNC_EN
], tmpV16
);
1100 tmpV16
= rtl_read_word(rtlpriv
, rtlpriv
->cfg
->maps
[SYS_CLK
]);
1101 if ((!(tmpV16
& rtlpriv
->cfg
->maps
[EFUSE_LOADER_CLK_EN
])) ||
1102 (!(tmpV16
& rtlpriv
->cfg
->maps
[EFUSE_ANA8M
]))) {
1103 tmpV16
|= (rtlpriv
->cfg
->maps
[EFUSE_LOADER_CLK_EN
] |
1104 rtlpriv
->cfg
->maps
[EFUSE_ANA8M
]);
1105 rtl_write_word(rtlpriv
,
1106 rtlpriv
->cfg
->maps
[SYS_CLK
], tmpV16
);
1110 if (pwrstate
== true) {
1111 if (bwrite
== true) {
1112 tempval
= rtl_read_byte(rtlpriv
,
1113 rtlpriv
->cfg
->maps
[EFUSE_TEST
] +
1116 tempval
|= (VOLTAGE_V25
<< 4);
1117 rtl_write_byte(rtlpriv
,
1118 rtlpriv
->cfg
->maps
[EFUSE_TEST
] + 3,
1123 if (bwrite
== true) {
1124 tempval
= rtl_read_byte(rtlpriv
,
1125 rtlpriv
->cfg
->maps
[EFUSE_TEST
] +
1127 rtl_write_byte(rtlpriv
,
1128 rtlpriv
->cfg
->maps
[EFUSE_TEST
] + 3,
1136 static u16
efuse_get_current_size(struct ieee80211_hw
*hw
)
1138 int bcontinual
= true;
1140 u8 hoffset
, hworden
;
1141 u8 efuse_data
, word_cnts
;
1143 while (bcontinual
&& efuse_one_byte_read(hw
, efuse_addr
, &efuse_data
)
1144 && (efuse_addr
< EFUSE_MAX_SIZE
)) {
1145 if (efuse_data
!= 0xFF) {
1146 hoffset
= (efuse_data
>> 4) & 0x0F;
1147 hworden
= efuse_data
& 0x0F;
1148 word_cnts
= efuse_calculate_word_cnts(hworden
);
1149 efuse_addr
= efuse_addr
+ (word_cnts
* 2) + 1;
1158 static u8
efuse_calculate_word_cnts(u8 word_en
)
1161 if (!(word_en
& BIT(0)))
1163 if (!(word_en
& BIT(1)))
1165 if (!(word_en
& BIT(2)))
1167 if (!(word_en
& BIT(3)))
1172 void efuse_reset_loader(struct ieee80211_hw
*hw
)
1174 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
1177 tmp_u2b
= rtl_read_word(rtlpriv
, rtlpriv
->cfg
->maps
[SYS_FUNC_EN
]);
1178 rtl_write_word(rtlpriv
, rtlpriv
->cfg
->maps
[SYS_FUNC_EN
],
1179 (tmp_u2b
& ~(BIT(12))));
1181 rtl_write_word(rtlpriv
, rtlpriv
->cfg
->maps
[SYS_FUNC_EN
],
1182 (tmp_u2b
| BIT(12)));
1186 bool efuse_program_map(struct ieee80211_hw
*hw
, char *p_filename
, u8 tabletype
)