KVM: nVMX: Fix returned value of MSR_IA32_VMX_VMCS_ENUM
[linux/fpc-iii.git] / drivers / staging / rtl8821ae / efuse.c
blob206012cf3601b46fcbe656f4b5d1f067d6ccca76
1 /******************************************************************************
3 * Copyright(c) 2009-2010 Realtek Corporation.
5 * This 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 * This 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
12 * more details.
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
18 * The 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 *****************************************************************************/
29 #include "wifi.h"
30 #include "efuse.h"
31 #include "btcoexist/halbt_precomp.h"
32 #include <linux/export.h>
34 static const u8 MAX_PGPKT_SIZE = 9;
35 static const u8 PGPKT_DATA_SIZE = 8;
36 static const int EFUSE_MAX_SIZE = 512;
38 static const struct efuse_map RTL8712_SDIO_EFUSE_TABLE[] = {
39 {0, 0, 0, 2},
40 {0, 1, 0, 2},
41 {0, 2, 0, 2},
42 {1, 0, 0, 1},
43 {1, 0, 1, 1},
44 {1, 1, 0, 1},
45 {1, 1, 1, 3},
46 {1, 3, 0, 17},
47 {3, 3, 1, 48},
48 {10, 0, 0, 6},
49 {10, 3, 0, 1},
50 {10, 3, 1, 1},
51 {11, 0, 0, 28}
54 static void efuse_shadow_read_1byte(struct ieee80211_hw *hw, u16 offset,
55 u8 * value);
56 static void efuse_shadow_read_2byte(struct ieee80211_hw *hw, u16 offset,
57 u16 * value);
58 static void efuse_shadow_read_4byte(struct ieee80211_hw *hw, u16 offset,
59 u32 * value);
60 static void efuse_shadow_write_1byte(struct ieee80211_hw *hw, u16 offset,
61 u8 value);
62 static void efuse_shadow_write_2byte(struct ieee80211_hw *hw, u16 offset,
63 u16 value);
64 static void efuse_shadow_write_4byte(struct ieee80211_hw *hw, u16 offset,
65 u32 value);
66 static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr,
67 u8 data);
68 static void efuse_read_all_map(struct ieee80211_hw *hw, u8 * efuse);
69 static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset,
70 u8 *data);
71 static int efuse_pg_packet_write(struct ieee80211_hw *hw, u8 offset,
72 u8 word_en, u8 * data);
73 static void efuse_word_enable_data_read(u8 word_en, u8 * sourdata,
74 u8 * targetdata);
75 static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw,
76 u16 efuse_addr, u8 word_en, u8 * data);
77 static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite,
78 u8 pwrstate);
79 static u16 efuse_get_current_size(struct ieee80211_hw *hw);
80 static u8 efuse_calculate_word_cnts(u8 word_en);
82 void efuse_initialize(struct ieee80211_hw *hw)
84 struct rtl_priv *rtlpriv = rtl_priv(hw);
85 u8 bytetemp;
86 u8 temp;
88 bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN] + 1);
89 temp = bytetemp | 0x20;
90 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN] + 1, temp);
92 bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[SYS_ISO_CTRL] + 1);
93 temp = bytetemp & 0xFE;
94 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[SYS_ISO_CTRL] + 1, temp);
96 bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST] + 3);
97 temp = bytetemp | 0x80;
98 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST] + 3, temp);
100 rtl_write_byte(rtlpriv, 0x2F8, 0x3);
102 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0x72);
106 u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address)
108 struct rtl_priv *rtlpriv = rtl_priv(hw);
109 u8 data;
110 u8 bytetemp;
111 u8 temp;
112 u32 k = 0;
113 const u32 efuse_real_content_len =
114 rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];
116 if (address < efuse_real_content_len) {
117 temp = address & 0xFF;
118 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
119 temp);
120 bytetemp = rtl_read_byte(rtlpriv,
121 rtlpriv->cfg->maps[EFUSE_CTRL] + 2);
122 temp = ((address >> 8) & 0x03) | (bytetemp & 0xFC);
123 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
124 temp);
126 bytetemp = rtl_read_byte(rtlpriv,
127 rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
128 temp = bytetemp & 0x7F;
129 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3,
130 temp);
132 bytetemp = rtl_read_byte(rtlpriv,
133 rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
134 while (!(bytetemp & 0x80)) {
135 bytetemp = rtl_read_byte(rtlpriv,
136 rtlpriv->cfg->
137 maps[EFUSE_CTRL] + 3);
138 k++;
139 if (k == 1000) {
140 k = 0;
141 break;
144 data = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
145 return data;
146 } else
147 return 0xFF;
150 /* EXPORT_SYMBOL(efuse_read_1byte); */
152 void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value)
154 struct rtl_priv *rtlpriv = rtl_priv(hw);
155 u8 bytetemp;
156 u8 temp;
157 u32 k = 0;
158 const u32 efuse_real_content_len =
159 rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];
161 RT_TRACE(COMP_EFUSE, DBG_LOUD,
162 ("Addr=%x Data =%x\n", address, value));
164 if (address < efuse_real_content_len) {
165 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], value);
167 temp = address & 0xFF;
168 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
169 temp);
170 bytetemp = rtl_read_byte(rtlpriv,
171 rtlpriv->cfg->maps[EFUSE_CTRL] + 2);
173 temp = ((address >> 8) & 0x03) | (bytetemp & 0xFC);
174 rtl_write_byte(rtlpriv,
175 rtlpriv->cfg->maps[EFUSE_CTRL] + 2, temp);
177 bytetemp = rtl_read_byte(rtlpriv,
178 rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
179 temp = bytetemp | 0x80;
180 rtl_write_byte(rtlpriv,
181 rtlpriv->cfg->maps[EFUSE_CTRL] + 3, temp);
183 bytetemp = rtl_read_byte(rtlpriv,
184 rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
186 while (bytetemp & 0x80) {
187 bytetemp = rtl_read_byte(rtlpriv,
188 rtlpriv->cfg->
189 maps[EFUSE_CTRL] + 3);
190 k++;
191 if (k == 100) {
192 k = 0;
193 break;
200 void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf)
202 struct rtl_priv *rtlpriv = rtl_priv(hw);
203 u32 value32;
204 u8 readbyte;
205 u16 retry;
207 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
208 (_offset & 0xff));
209 readbyte = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2);
210 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
211 ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
213 readbyte = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
214 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3,
215 (readbyte & 0x7f));
217 retry = 0;
218 value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
219 while (!(((value32 >> 24) & 0xff) & 0x80) && (retry < 10000)) {
220 value32 = rtl_read_dword(rtlpriv,
221 rtlpriv->cfg->maps[EFUSE_CTRL]);
222 retry++;
225 udelay(50);
226 value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
228 *pbuf = (u8) (value32 & 0xff);
231 void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
233 struct rtl_priv *rtlpriv = rtl_priv(hw);
234 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
235 u8 efuse_tbl[rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]];
236 u8 rtemp8[1];
237 u16 efuse_addr = 0;
238 u8 offset, wren;
239 u8 u1temp = 0;
240 u16 i;
241 u16 j;
242 const u16 efuse_max_section =
243 rtlpriv->cfg->maps[EFUSE_MAX_SECTION_MAP];
244 const u32 efuse_real_content_len =
245 rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];
246 u16 efuse_word[efuse_max_section][EFUSE_MAX_WORD_UNIT];
247 u16 efuse_utilized = 0;
248 u8 efuse_usage;
250 if ((_offset + _size_byte) > rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]) {
251 RT_TRACE(COMP_EFUSE, DBG_LOUD,
252 ("read_efuse(): Invalid offset(%#x) with read "
253 "bytes(%#x)!!\n", _offset, _size_byte));
254 return;
257 for (i = 0; i < efuse_max_section; i++)
258 for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
259 efuse_word[i][j] = 0xFFFF;
261 read_efuse_byte(hw, efuse_addr, rtemp8);
262 if (*rtemp8 != 0xFF) {
263 efuse_utilized++;
264 RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
265 ("Addr=%d\n", efuse_addr));
266 efuse_addr++;
269 while ((*rtemp8 != 0xFF) && (efuse_addr < efuse_real_content_len)) {
270 /* Check PG header for section num. */
271 if((*rtemp8 & 0x1F ) == 0x0F) {/* extended header */
272 u1temp =( (*rtemp8 & 0xE0) >> 5);
273 read_efuse_byte(hw, efuse_addr, rtemp8);
275 if((*rtemp8 & 0x0F) == 0x0F) {
276 efuse_addr++;
277 read_efuse_byte(hw, efuse_addr, rtemp8);
279 if (*rtemp8 != 0xFF &&
280 (efuse_addr < efuse_real_content_len)) {
281 efuse_addr++;
283 continue;
284 } else {
285 offset = ((*rtemp8 & 0xF0) >> 1) | u1temp;
286 wren = (*rtemp8 & 0x0F);
287 efuse_addr++;
289 } else {
290 offset = ((*rtemp8 >> 4) & 0x0f);
291 wren = (*rtemp8 & 0x0f);
294 if (offset < efuse_max_section) {
295 RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
296 ("offset-%d Worden=%x\n", offset, wren));
298 for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
299 if (!(wren & 0x01)) {
300 RTPRINT(rtlpriv, FEEPROM,
301 EFUSE_READ_ALL, ("Addr=%d\n",
302 efuse_addr));
304 read_efuse_byte(hw, efuse_addr, rtemp8);
305 efuse_addr++;
306 efuse_utilized++;
307 efuse_word[offset][i] = (*rtemp8 &
308 0xff);
310 if (efuse_addr >=
311 efuse_real_content_len)
312 break;
314 RTPRINT(rtlpriv, FEEPROM,
315 EFUSE_READ_ALL, ("Addr=%d\n",
316 efuse_addr));
318 read_efuse_byte(hw, efuse_addr, rtemp8);
319 efuse_addr++;
320 efuse_utilized++;
321 efuse_word[offset][i] |=
322 (((u16) * rtemp8 << 8) & 0xff00);
324 if (efuse_addr >= efuse_real_content_len)
325 break;
328 wren >>= 1;
332 RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
333 ("Addr=%d\n", efuse_addr));
334 read_efuse_byte(hw, efuse_addr, rtemp8);
335 if (*rtemp8 != 0xFF && (efuse_addr < efuse_real_content_len)) {
336 efuse_utilized++;
337 efuse_addr++;
341 for (i = 0; i < efuse_max_section; i++) {
342 for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {
343 efuse_tbl[(i * 8) + (j * 2)] =
344 (efuse_word[i][j] & 0xff);
345 efuse_tbl[(i * 8) + ((j * 2) + 1)] =
346 ((efuse_word[i][j] >> 8) & 0xff);
350 for (i = 0; i < _size_byte; i++)
351 pbuf[i] = efuse_tbl[_offset + i];
353 rtlefuse->efuse_usedbytes = efuse_utilized;
354 efuse_usage = (u8) ((efuse_utilized * 100) / efuse_real_content_len);
355 rtlefuse->efuse_usedpercentage = efuse_usage;
356 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_BYTES,
357 (u8 *) & efuse_utilized);
358 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_USAGE,
359 (u8 *) & efuse_usage);
362 bool efuse_shadow_update_chk(struct ieee80211_hw *hw)
364 struct rtl_priv *rtlpriv = rtl_priv(hw);
365 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
366 u8 section_idx, i, Base;
367 u16 words_need = 0, hdr_num = 0, totalbytes, efuse_used;
368 bool bwordchanged, bresult = true;
370 for (section_idx = 0; section_idx < 16; section_idx++) {
371 Base = section_idx * 8;
372 bwordchanged = false;
374 for (i = 0; i < 8; i = i + 2) {
375 if ((rtlefuse->efuse_map[EFUSE_INIT_MAP][Base + i] !=
376 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][Base + i]) ||
377 (rtlefuse->efuse_map[EFUSE_INIT_MAP][Base + i + 1] !=
378 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][Base + i +
379 1])) {
380 words_need++;
381 bwordchanged = true;
385 if (bwordchanged == true)
386 hdr_num++;
389 totalbytes = hdr_num + words_need * 2;
390 efuse_used = rtlefuse->efuse_usedbytes;
392 if ((totalbytes + efuse_used) >= (EFUSE_MAX_SIZE -
393 rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN]))
394 bresult = false;
396 RT_TRACE(COMP_EFUSE, DBG_LOUD,
397 ("efuse_shadow_update_chk(): totalbytes(%#x), "
398 "hdr_num(%#x), words_need(%#x), efuse_used(%d)\n",
399 totalbytes, hdr_num, words_need, efuse_used));
401 return bresult;
404 void efuse_shadow_read(struct ieee80211_hw *hw, u8 type,
405 u16 offset, u32 *value)
407 if (type == 1)
408 efuse_shadow_read_1byte(hw, offset, (u8 *) value);
409 else if (type == 2)
410 efuse_shadow_read_2byte(hw, offset, (u16 *) value);
411 else if (type == 4)
412 efuse_shadow_read_4byte(hw, offset, (u32 *) value);
416 void efuse_shadow_write(struct ieee80211_hw *hw, u8 type, u16 offset,
417 u32 value)
419 if (type == 1)
420 efuse_shadow_write_1byte(hw, offset, (u8) value);
421 else if (type == 2)
422 efuse_shadow_write_2byte(hw, offset, (u16) value);
423 else if (type == 4)
424 efuse_shadow_write_4byte(hw, offset, (u32) value);
428 bool efuse_shadow_update(struct ieee80211_hw *hw)
430 struct rtl_priv *rtlpriv = rtl_priv(hw);
431 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
432 u16 i, offset, base;
433 u8 word_en = 0x0F;
434 u8 first_pg = false;
436 RT_TRACE(COMP_EFUSE, DBG_LOUD, ("\n"));
438 if (!efuse_shadow_update_chk(hw)) {
439 efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]);
440 memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0],
441 &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
442 rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
444 RT_TRACE(COMP_EFUSE, DBG_LOUD,
445 ("efuse out of capacity!!\n"));
446 return false;
448 efuse_power_switch(hw, true, true);
450 for (offset = 0; offset < 16; offset++) {
452 word_en = 0x0F;
453 base = offset * 8;
455 for (i = 0; i < 8; i++) {
456 if (first_pg == true) {
458 word_en &= ~(BIT(i / 2));
460 rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] =
461 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i];
462 } else {
464 if (rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] !=
465 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i]) {
466 word_en &= ~(BIT(i / 2));
468 rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] =
469 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i];
474 if (word_en != 0x0F) {
475 u8 tmpdata[8];
476 memcpy(tmpdata, (&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base]), 8);
477 RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD,
478 ("U-efuse\n"), tmpdata, 8);
480 if (!efuse_pg_packet_write(hw, (u8) offset, word_en,
481 tmpdata)) {
482 RT_TRACE(COMP_ERR, DBG_WARNING,
483 ("PG section(%#x) fail!!\n", offset));
484 break;
490 efuse_power_switch(hw, true, false);
491 efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]);
493 memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0],
494 &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
495 rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
497 RT_TRACE(COMP_EFUSE, DBG_LOUD, ("\n"));
498 return true;
501 void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw)
503 struct rtl_priv *rtlpriv = rtl_priv(hw);
504 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
506 if (rtlefuse->autoload_failflag == true) {
507 memset((&rtlefuse->efuse_map[EFUSE_INIT_MAP][0]),
508 0xFF, rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
509 } else {
510 efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]);
513 memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0],
514 &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
515 rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
518 /* EXPORT_SYMBOL(rtl_efuse_shadow_map_update); */
520 void efuse_force_write_vendor_Id(struct ieee80211_hw *hw)
522 u8 tmpdata[8] = { 0xFF, 0xFF, 0xEC, 0x10, 0xFF, 0xFF, 0xFF, 0xFF };
524 efuse_power_switch(hw, true, true);
526 efuse_pg_packet_write(hw, 1, 0xD, tmpdata);
528 efuse_power_switch(hw, true, false);
532 void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx)
536 static void efuse_shadow_read_1byte(struct ieee80211_hw *hw,
537 u16 offset, u8 *value)
539 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
540 *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset];
543 static void efuse_shadow_read_2byte(struct ieee80211_hw *hw,
544 u16 offset, u16 *value)
546 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
548 *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset];
549 *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] << 8;
553 static void efuse_shadow_read_4byte(struct ieee80211_hw *hw,
554 u16 offset, u32 *value)
556 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
558 *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset];
559 *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] << 8;
560 *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 2] << 16;
561 *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 3] << 24;
564 static void efuse_shadow_write_1byte(struct ieee80211_hw *hw,
565 u16 offset, u8 value)
567 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
569 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] = value;
572 static void efuse_shadow_write_2byte(struct ieee80211_hw *hw,
573 u16 offset, u16 value)
575 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
577 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] = value & 0x00FF;
578 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] = value >> 8;
582 static void efuse_shadow_write_4byte(struct ieee80211_hw *hw,
583 u16 offset, u32 value)
585 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
587 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] =
588 (u8) (value & 0x000000FF);
589 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] =
590 (u8) ((value >> 8) & 0x0000FF);
591 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 2] =
592 (u8) ((value >> 16) & 0x00FF);
593 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 3] =
594 (u8) ((value >> 24) & 0xFF);
598 int efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr, u8 *data)
600 struct rtl_priv *rtlpriv = rtl_priv(hw);
601 u8 tmpidx = 0;
602 int bresult;
604 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
605 (u8) (addr & 0xff));
606 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
607 ((u8) ((addr >> 8) & 0x03)) |
608 (rtl_read_byte(rtlpriv,
609 rtlpriv->cfg->maps[EFUSE_CTRL] + 2) &
610 0xFC));
612 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0x72);
614 while (!(0x80 & rtl_read_byte(rtlpriv,
615 rtlpriv->cfg->maps[EFUSE_CTRL] + 3))
616 && (tmpidx < 100)) {
617 tmpidx++;
620 if (tmpidx < 100) {
621 *data = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
622 bresult = true;
623 } else {
624 *data = 0xff;
625 bresult = false;
627 return bresult;
629 /* EXPORT_SYMBOL(efuse_one_byte_read); */
631 static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data)
633 struct rtl_priv *rtlpriv = rtl_priv(hw);
634 u8 tmpidx = 0;
635 bool bresult;
637 RT_TRACE(COMP_EFUSE, DBG_LOUD,
638 ("Addr = %x Data=%x\n", addr, data));
640 rtl_write_byte(rtlpriv,
641 rtlpriv->cfg->maps[EFUSE_CTRL] + 1, (u8) (addr & 0xff));
642 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
643 (rtl_read_byte(rtlpriv,
644 rtlpriv->cfg->maps[EFUSE_CTRL] +
645 2) & 0xFC) | (u8) ((addr >> 8) & 0x03));
647 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], data);
648 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0xF2);
650 while ((0x80 & rtl_read_byte(rtlpriv,
651 rtlpriv->cfg->maps[EFUSE_CTRL] + 3))
652 && (tmpidx < 100)) {
653 tmpidx++;
656 if (tmpidx < 100)
657 bresult = true;
658 else
659 bresult = false;
661 return bresult;
664 static void efuse_read_all_map(struct ieee80211_hw *hw, u8 * efuse)
666 struct rtl_priv *rtlpriv = rtl_priv(hw);
667 efuse_power_switch(hw, false, true);
668 read_efuse(hw, 0, rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE], efuse);
669 efuse_power_switch(hw, false, false);
672 static void efuse_read_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
673 u8 efuse_data, u8 offset, u8 *tmpdata,
674 u8 *readstate)
676 bool bdataempty = true;
677 u8 hoffset;
678 u8 tmpidx;
679 u8 hworden;
680 u8 word_cnts;
682 hoffset = (efuse_data >> 4) & 0x0F;
683 hworden = efuse_data & 0x0F;
684 word_cnts = efuse_calculate_word_cnts(hworden);
686 if (hoffset == offset) {
687 for (tmpidx = 0; tmpidx < word_cnts * 2; tmpidx++) {
688 if (efuse_one_byte_read(hw, *efuse_addr + 1 + tmpidx,
689 &efuse_data)) {
690 tmpdata[tmpidx] = efuse_data;
691 if (efuse_data != 0xff)
692 bdataempty = true;
696 if (bdataempty == true) {
697 *readstate = PG_STATE_DATA;
698 } else {
699 *efuse_addr = *efuse_addr + (word_cnts * 2) + 1;
700 *readstate = PG_STATE_HEADER;
703 } else {
704 *efuse_addr = *efuse_addr + (word_cnts * 2) + 1;
705 *readstate = PG_STATE_HEADER;
709 static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data)
711 u8 readstate = PG_STATE_HEADER;
713 bool bcontinual = true;
715 u8 efuse_data, word_cnts = 0;
716 u16 efuse_addr = 0;
717 u8 hworden = 0;
718 u8 tmpdata[8];
720 if (data == NULL)
721 return false;
722 if (offset > 15)
723 return false;
725 memset(data, 0xff, PGPKT_DATA_SIZE * sizeof(u8));
726 memset(tmpdata, 0xff, PGPKT_DATA_SIZE * sizeof(u8));
728 while (bcontinual && (efuse_addr < EFUSE_MAX_SIZE)) {
729 if (readstate & PG_STATE_HEADER) {
730 if (efuse_one_byte_read(hw, efuse_addr, &efuse_data)
731 && (efuse_data != 0xFF))
732 efuse_read_data_case1(hw, &efuse_addr, efuse_data, offset,
733 tmpdata, &readstate);
734 else
735 bcontinual = false;
736 } else if (readstate & PG_STATE_DATA) {
737 efuse_word_enable_data_read(hworden, tmpdata, data);
738 efuse_addr = efuse_addr + (word_cnts * 2) + 1;
739 readstate = PG_STATE_HEADER;
744 if ((data[0] == 0xff) && (data[1] == 0xff) &&
745 (data[2] == 0xff) && (data[3] == 0xff) &&
746 (data[4] == 0xff) && (data[5] == 0xff) &&
747 (data[6] == 0xff) && (data[7] == 0xff))
748 return false;
749 else
750 return true;
754 static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
755 u8 efuse_data, u8 offset, int *bcontinual,
756 u8 *write_state, struct pgpkt_struct *target_pkt,
757 int *repeat_times, int *bresult, u8 word_en)
759 struct rtl_priv *rtlpriv = rtl_priv(hw);
760 struct pgpkt_struct tmp_pkt;
761 int bdataempty = true;
762 u8 originaldata[8 * sizeof(u8)];
763 u8 badworden = 0x0F;
764 u8 match_word_en, tmp_word_en;
765 u8 tmpindex;
766 u8 tmp_header = efuse_data;
767 u8 tmp_word_cnts;
769 tmp_pkt.offset = (tmp_header >> 4) & 0x0F;
770 tmp_pkt.word_en = tmp_header & 0x0F;
771 tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en);
773 if (tmp_pkt.offset != target_pkt->offset) {
774 *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
775 *write_state = PG_STATE_HEADER;
776 } else {
777 for (tmpindex = 0; tmpindex < (tmp_word_cnts * 2); tmpindex++) {
778 if (efuse_one_byte_read(hw,
779 (*efuse_addr + 1 + tmpindex),
780 &efuse_data) && (efuse_data != 0xFF))
781 bdataempty = false;
784 if (bdataempty == false) {
785 *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
786 *write_state = PG_STATE_HEADER;
787 } else {
788 match_word_en = 0x0F;
789 if (!((target_pkt->word_en & BIT(0)) |
790 (tmp_pkt.word_en & BIT(0))))
791 match_word_en &= (~BIT(0));
793 if (!((target_pkt->word_en & BIT(1)) |
794 (tmp_pkt.word_en & BIT(1))))
795 match_word_en &= (~BIT(1));
797 if (!((target_pkt->word_en & BIT(2)) |
798 (tmp_pkt.word_en & BIT(2))))
799 match_word_en &= (~BIT(2));
801 if (!((target_pkt->word_en & BIT(3)) |
802 (tmp_pkt.word_en & BIT(3))))
803 match_word_en &= (~BIT(3));
805 if ((match_word_en & 0x0F) != 0x0F) {
806 badworden = efuse_word_enable_data_write(hw,
807 *efuse_addr + 1,
808 tmp_pkt.word_en,
809 target_pkt->data);
811 if (0x0F != (badworden & 0x0F)) {
812 u8 reorg_offset = offset;
813 u8 reorg_worden = badworden;
814 efuse_pg_packet_write(hw, reorg_offset,
815 reorg_worden,
816 originaldata);
819 tmp_word_en = 0x0F;
820 if ((target_pkt->word_en & BIT(0)) ^
821 (match_word_en & BIT(0)))
822 tmp_word_en &= (~BIT(0));
824 if ((target_pkt->word_en & BIT(1)) ^
825 (match_word_en & BIT(1)))
826 tmp_word_en &= (~BIT(1));
828 if ((target_pkt->word_en & BIT(2)) ^
829 (match_word_en & BIT(2)))
830 tmp_word_en &= (~BIT(2));
832 if ((target_pkt->word_en & BIT(3)) ^
833 (match_word_en & BIT(3)))
834 tmp_word_en &= (~BIT(3));
836 if ((tmp_word_en & 0x0F) != 0x0F) {
837 *efuse_addr = efuse_get_current_size(hw);
838 target_pkt->offset = offset;
839 target_pkt->word_en = tmp_word_en;
840 } else {
841 *bcontinual = false;
843 *write_state = PG_STATE_HEADER;
844 *repeat_times += 1;
845 if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
846 *bcontinual = false;
847 *bresult = false;
849 } else {
850 *efuse_addr += (2 * tmp_word_cnts) + 1;
851 target_pkt->offset = offset;
852 target_pkt->word_en = word_en;
853 *write_state = PG_STATE_HEADER;
857 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse PG_STATE_HEADER-1\n"));
860 static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr,
861 int *bcontinual, u8 *write_state,
862 struct pgpkt_struct target_pkt,
863 int *repeat_times, int *bresult)
865 struct rtl_priv *rtlpriv = rtl_priv(hw);
866 struct pgpkt_struct tmp_pkt;
867 u8 pg_header;
868 u8 tmp_header;
869 u8 originaldata[8 * sizeof(u8)];
870 u8 tmp_word_cnts;
871 u8 badworden = 0x0F;
873 pg_header = ((target_pkt.offset << 4) & 0xf0) | target_pkt.word_en;
874 efuse_one_byte_write(hw, *efuse_addr, pg_header);
875 efuse_one_byte_read(hw, *efuse_addr, &tmp_header);
877 if (tmp_header == pg_header) {
878 *write_state = PG_STATE_DATA;
879 } else if (tmp_header == 0xFF) {
880 *write_state = PG_STATE_HEADER;
881 *repeat_times += 1;
882 if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
883 *bcontinual = false;
884 *bresult = false;
886 } else {
887 tmp_pkt.offset = (tmp_header >> 4) & 0x0F;
888 tmp_pkt.word_en = tmp_header & 0x0F;
890 tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en);
892 memset(originaldata, 0xff, 8 * sizeof(u8));
894 if (efuse_pg_packet_read(hw, tmp_pkt.offset, originaldata)) {
895 badworden = efuse_word_enable_data_write(hw,
896 *efuse_addr + 1,
897 tmp_pkt.word_en,
898 originaldata);
900 if (0x0F != (badworden & 0x0F)) {
901 u8 reorg_offset = tmp_pkt.offset;
902 u8 reorg_worden = badworden;
903 efuse_pg_packet_write(hw, reorg_offset,
904 reorg_worden,
905 originaldata);
906 *efuse_addr = efuse_get_current_size(hw);
907 } else {
908 *efuse_addr = *efuse_addr +
909 (tmp_word_cnts * 2) + 1;
911 } else {
912 *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
915 *write_state = PG_STATE_HEADER;
916 *repeat_times += 1;
917 if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
918 *bcontinual = false;
919 *bresult = false;
922 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
923 ("efuse PG_STATE_HEADER-2\n"));
927 static int efuse_pg_packet_write(struct ieee80211_hw *hw,
928 u8 offset, u8 word_en, u8 *data)
930 struct rtl_priv *rtlpriv = rtl_priv(hw);
931 struct pgpkt_struct target_pkt;
932 u8 write_state = PG_STATE_HEADER;
933 int bcontinual = true, bdataempty = true, bresult = true;
934 u16 efuse_addr = 0;
935 u8 efuse_data;
936 u8 target_word_cnts = 0;
937 u8 badworden = 0x0F;
938 static int repeat_times = 0;
940 if (efuse_get_current_size(hw) >= (EFUSE_MAX_SIZE -
941 rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN])) {
942 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
943 ("efuse_pg_packet_write error \n"));
944 return false;
947 target_pkt.offset = offset;
948 target_pkt.word_en = word_en;
950 memset(target_pkt.data, 0xFF, 8 * sizeof(u8));
952 efuse_word_enable_data_read(word_en, data, target_pkt.data);
953 target_word_cnts = efuse_calculate_word_cnts(target_pkt.word_en);
955 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse Power ON\n"));
957 while (bcontinual && (efuse_addr < (EFUSE_MAX_SIZE -
958 rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN]))) {
960 if (write_state == PG_STATE_HEADER) {
961 bdataempty = true;
962 badworden = 0x0F;
963 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
964 ("efuse PG_STATE_HEADER\n"));
966 if (efuse_one_byte_read(hw, efuse_addr, &efuse_data) &&
967 (efuse_data != 0xFF))
968 efuse_write_data_case1(hw, &efuse_addr,
969 efuse_data, offset,
970 &bcontinual,
971 &write_state,
972 &target_pkt,
973 &repeat_times, &bresult,
974 word_en);
975 else
976 efuse_write_data_case2(hw, &efuse_addr,
977 &bcontinual,
978 &write_state,
979 target_pkt,
980 &repeat_times,
981 &bresult);
983 } else if (write_state == PG_STATE_DATA) {
984 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
985 ("efuse PG_STATE_DATA\n"));
986 badworden = 0x0f;
987 badworden =
988 efuse_word_enable_data_write(hw, efuse_addr + 1,
989 target_pkt.word_en,
990 target_pkt.data);
992 if ((badworden & 0x0F) == 0x0F) {
993 bcontinual = false;
994 } else {
995 efuse_addr =
996 efuse_addr + (2 * target_word_cnts) + 1;
998 target_pkt.offset = offset;
999 target_pkt.word_en = badworden;
1000 target_word_cnts =
1001 efuse_calculate_word_cnts(target_pkt.
1002 word_en);
1003 write_state = PG_STATE_HEADER;
1004 repeat_times++;
1005 if (repeat_times > EFUSE_REPEAT_THRESHOLD_) {
1006 bcontinual = false;
1007 bresult = false;
1009 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
1010 ("efuse PG_STATE_HEADER-3\n"));
1015 if (efuse_addr >= (EFUSE_MAX_SIZE -
1016 rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN])) {
1017 RT_TRACE(COMP_EFUSE, DBG_LOUD,
1018 ("efuse_addr(%#x) Out of size!!\n", efuse_addr));
1021 return true;
1024 static void efuse_word_enable_data_read(u8 word_en, u8 * sourdata,
1025 u8 *targetdata)
1027 if (!(word_en & BIT(0))) {
1028 targetdata[0] = sourdata[0];
1029 targetdata[1] = sourdata[1];
1032 if (!(word_en & BIT(1))) {
1033 targetdata[2] = sourdata[2];
1034 targetdata[3] = sourdata[3];
1037 if (!(word_en & BIT(2))) {
1038 targetdata[4] = sourdata[4];
1039 targetdata[5] = sourdata[5];
1042 if (!(word_en & BIT(3))) {
1043 targetdata[6] = sourdata[6];
1044 targetdata[7] = sourdata[7];
1048 static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw,
1049 u16 efuse_addr, u8 word_en, u8 *data)
1051 struct rtl_priv *rtlpriv = rtl_priv(hw);
1052 u16 tmpaddr;
1053 u16 start_addr = efuse_addr;
1054 u8 badworden = 0x0F;
1055 u8 tmpdata[8];
1057 memset(tmpdata, 0xff, PGPKT_DATA_SIZE);
1058 RT_TRACE(COMP_EFUSE, DBG_LOUD,
1059 ("word_en = %x efuse_addr=%x\n", word_en, efuse_addr));
1061 if (!(word_en & BIT(0))) {
1062 tmpaddr = start_addr;
1063 efuse_one_byte_write(hw, start_addr++, data[0]);
1064 efuse_one_byte_write(hw, start_addr++, data[1]);
1066 efuse_one_byte_read(hw, tmpaddr, &tmpdata[0]);
1067 efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[1]);
1068 if ((data[0] != tmpdata[0]) || (data[1] != tmpdata[1]))
1069 badworden &= (~BIT(0));
1072 if (!(word_en & BIT(1))) {
1073 tmpaddr = start_addr;
1074 efuse_one_byte_write(hw, start_addr++, data[2]);
1075 efuse_one_byte_write(hw, start_addr++, data[3]);
1077 efuse_one_byte_read(hw, tmpaddr, &tmpdata[2]);
1078 efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[3]);
1079 if ((data[2] != tmpdata[2]) || (data[3] != tmpdata[3]))
1080 badworden &= (~BIT(1));
1083 if (!(word_en & BIT(2))) {
1084 tmpaddr = start_addr;
1085 efuse_one_byte_write(hw, start_addr++, data[4]);
1086 efuse_one_byte_write(hw, start_addr++, data[5]);
1088 efuse_one_byte_read(hw, tmpaddr, &tmpdata[4]);
1089 efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[5]);
1090 if ((data[4] != tmpdata[4]) || (data[5] != tmpdata[5]))
1091 badworden &= (~BIT(2));
1094 if (!(word_en & BIT(3))) {
1095 tmpaddr = start_addr;
1096 efuse_one_byte_write(hw, start_addr++, data[6]);
1097 efuse_one_byte_write(hw, start_addr++, data[7]);
1099 efuse_one_byte_read(hw, tmpaddr, &tmpdata[6]);
1100 efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[7]);
1101 if ((data[6] != tmpdata[6]) || (data[7] != tmpdata[7]))
1102 badworden &= (~BIT(3));
1105 return badworden;
1108 static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite, u8 pwrstate)
1110 struct rtl_priv *rtlpriv = rtl_priv(hw);
1111 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1112 u8 tempval;
1113 u16 tmpV16;
1115 if(rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
1117 if (pwrstate == true)
1119 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_ACCESS], 0x69);
1121 /* 1.2V Power: From VDDON with Power Cut(0x0000h[15]), default valid */
1122 tmpV16 = rtl_read_word(rtlpriv,
1123 rtlpriv->cfg->maps[SYS_ISO_CTRL]);
1125 printk("SYS_ISO_CTRL=%04x.\n",tmpV16);
1126 if( ! (tmpV16 & PWC_EV12V ) ){
1127 tmpV16 |= PWC_EV12V ;
1128 /* PlatformEFIOWrite2Byte(pAdapter,REG_SYS_ISO_CTRL,tmpV16); */
1130 /* Reset: 0x0000h[28], default valid */
1131 tmpV16 = rtl_read_word(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN]);
1132 printk("SYS_FUNC_EN=%04x.\n",tmpV16);
1133 if( !(tmpV16 & FEN_ELDR) ){
1134 tmpV16 |= FEN_ELDR ;
1135 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN], tmpV16);
1138 /* Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid */
1139 tmpV16 = rtl_read_word(rtlpriv, rtlpriv->cfg->maps[SYS_CLK] );
1140 printk("SYS_CLK=%04x.\n",tmpV16);
1141 if( (!(tmpV16 & LOADER_CLK_EN) ) ||(!(tmpV16 & ANA8M) ) )
1143 tmpV16 |= (LOADER_CLK_EN |ANA8M ) ;
1144 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[SYS_CLK], tmpV16);
1147 if(bwrite == true)
1149 /* Enable LDO 2.5V before read/write action */
1150 tempval = rtl_read_word(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST] + 3);
1151 printk("EFUSE_TEST=%04x.\n",tmpV16);
1152 tempval &= ~(BIT(3) | BIT(4) |BIT(5) | BIT(6));
1153 tempval |= (VOLTAGE_V25 << 3);
1154 tempval |= BIT(7);
1155 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST] + 3, tempval);
1158 else
1160 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_ACCESS], 0x00);
1161 if(bwrite == true){
1162 /* Disable LDO 2.5V after read/write action */
1163 tempval = rtl_read_word(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST] + 3);
1164 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST] + 3, (tempval & 0x7F));
1168 else
1170 if (pwrstate == true && (rtlhal->hw_type !=
1171 HARDWARE_TYPE_RTL8192SE)) {
1173 if(rtlhal->hw_type == HARDWARE_TYPE_RTL8188EE)
1174 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_ACCESS],
1175 0x69);
1177 tmpV16 = rtl_read_word(rtlpriv,
1178 rtlpriv->cfg->maps[SYS_ISO_CTRL]);
1179 if (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_PWC_EV12V])) {
1180 tmpV16 |= rtlpriv->cfg->maps[EFUSE_PWC_EV12V];
1181 rtl_write_word(rtlpriv,
1182 rtlpriv->cfg->maps[SYS_ISO_CTRL],
1183 tmpV16);
1186 tmpV16 = rtl_read_word(rtlpriv,
1187 rtlpriv->cfg->maps[SYS_FUNC_EN]);
1188 if (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_FEN_ELDR])) {
1189 tmpV16 |= rtlpriv->cfg->maps[EFUSE_FEN_ELDR];
1190 rtl_write_word(rtlpriv,
1191 rtlpriv->cfg->maps[SYS_FUNC_EN], tmpV16);
1194 tmpV16 = rtl_read_word(rtlpriv, rtlpriv->cfg->maps[SYS_CLK]);
1195 if ((!(tmpV16 & rtlpriv->cfg->maps[EFUSE_LOADER_CLK_EN])) ||
1196 (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_ANA8M]))) {
1197 tmpV16 |= (rtlpriv->cfg->maps[EFUSE_LOADER_CLK_EN] |
1198 rtlpriv->cfg->maps[EFUSE_ANA8M]);
1199 rtl_write_word(rtlpriv,
1200 rtlpriv->cfg->maps[SYS_CLK], tmpV16);
1204 if (pwrstate == true) {
1205 if (bwrite == true) {
1206 tempval = rtl_read_byte(rtlpriv,
1207 rtlpriv->cfg->maps[EFUSE_TEST] +
1210 if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE) {
1211 tempval &= 0x0F;
1212 tempval |= (VOLTAGE_V25 << 4);
1215 rtl_write_byte(rtlpriv,
1216 rtlpriv->cfg->maps[EFUSE_TEST] + 3,
1217 (tempval | 0x80));
1220 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) {
1221 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CLK],
1222 0x03);
1225 } else {
1226 if(rtlhal->hw_type == HARDWARE_TYPE_RTL8188EE)
1227 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_ACCESS], 0);
1229 if (bwrite == true) {
1230 tempval = rtl_read_byte(rtlpriv,
1231 rtlpriv->cfg->maps[EFUSE_TEST] +
1233 rtl_write_byte(rtlpriv,
1234 rtlpriv->cfg->maps[EFUSE_TEST] + 3,
1235 (tempval & 0x7F));
1238 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) {
1239 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CLK],
1240 0x02);
1248 static u16 efuse_get_current_size(struct ieee80211_hw *hw)
1250 int bcontinual = true;
1251 u16 efuse_addr = 0;
1252 u8 hoffset, hworden;
1253 u8 efuse_data, word_cnts;
1255 while (bcontinual && efuse_one_byte_read(hw, efuse_addr, &efuse_data)
1256 && (efuse_addr < EFUSE_MAX_SIZE)) {
1257 if (efuse_data != 0xFF) {
1258 hoffset = (efuse_data >> 4) & 0x0F;
1259 hworden = efuse_data & 0x0F;
1260 word_cnts = efuse_calculate_word_cnts(hworden);
1261 efuse_addr = efuse_addr + (word_cnts * 2) + 1;
1262 } else {
1263 bcontinual = false;
1267 return efuse_addr;
1270 static u8 efuse_calculate_word_cnts(u8 word_en)
1272 u8 word_cnts = 0;
1273 if (!(word_en & BIT(0)))
1274 word_cnts++;
1275 if (!(word_en & BIT(1)))
1276 word_cnts++;
1277 if (!(word_en & BIT(2)))
1278 word_cnts++;
1279 if (!(word_en & BIT(3)))
1280 word_cnts++;
1281 return word_cnts;