Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.17-rc4 1233 lines 34 kB view raw
1/****************************************************************************** 2 * 3 * Copyright(c) 2009-2010 Realtek Corporation. 4 * 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. 8 * 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. 13 * 14 * The full GNU General Public License is included in this distribution in the 15 * file called LICENSE. 16 * 17 * Contact Information: 18 * wlanfae <wlanfae@realtek.com> 19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, 20 * Hsinchu 300, Taiwan. 21 * 22 * Larry Finger <Larry.Finger@lwfinger.net> 23 * 24 *****************************************************************************/ 25#include "wifi.h" 26#include "efuse.h" 27 28static const u8 MAX_PGPKT_SIZE = 9; 29static const u8 PGPKT_DATA_SIZE = 8; 30static const int EFUSE_MAX_SIZE = 512; 31 32static const struct efuse_map RTL8712_SDIO_EFUSE_TABLE[] = { 33 {0, 0, 0, 2}, 34 {0, 1, 0, 2}, 35 {0, 2, 0, 2}, 36 {1, 0, 0, 1}, 37 {1, 0, 1, 1}, 38 {1, 1, 0, 1}, 39 {1, 1, 1, 3}, 40 {1, 3, 0, 17}, 41 {3, 3, 1, 48}, 42 {10, 0, 0, 6}, 43 {10, 3, 0, 1}, 44 {10, 3, 1, 1}, 45 {11, 0, 0, 28} 46}; 47 48static void efuse92e_shadow_read_1byte(struct ieee80211_hw *hw, u16 offset, 49 u8 *value); 50static void efuse92e_shadow_read_2byte(struct ieee80211_hw *hw, u16 offset, 51 u16 *value); 52static void efuse92e_shadow_read_4byte(struct ieee80211_hw *hw, u16 offset, 53 u32 *value); 54static void efuse92e_shadow_write_1byte(struct ieee80211_hw *hw, u16 offset, 55 u8 value); 56static void efuse92e_shadow_write_2byte(struct ieee80211_hw *hw, u16 offset, 57 u16 value); 58static void efuse92e_shadow_write_4byte(struct ieee80211_hw *hw, u16 offset, 59 u32 value); 60static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, 61 u8 data); 62static void efuse_read_all_map(struct ieee80211_hw *hw, u8 *efuse); 63static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, 64 u8 *data); 65static int efuse_pg_packet_write(struct ieee80211_hw *hw, u8 offset, 66 u8 word_en, u8 *data); 67static void efuse_word_enable_data_read(u8 word_en, u8 *sourdata, 68 u8 *targetdata); 69static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw, 70 u16 efuse_addr, u8 word_en, u8 *data); 71static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite, 72 u8 pwrstate); 73static u16 efuse_get_current_size(struct ieee80211_hw *hw); 74static u8 efuse_calculate_word_cnts(u8 word_en); 75 76void efuse92e_initialize(struct ieee80211_hw *hw) 77{ 78 struct rtl_priv *rtlpriv = rtl_priv(hw); 79 u8 bytetemp; 80 u8 temp; 81 82 bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN] + 1); 83 temp = bytetemp | 0x20; 84 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN] + 1, temp); 85 86 bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[SYS_ISO_CTRL] + 1); 87 temp = bytetemp & 0xFE; 88 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[SYS_ISO_CTRL] + 1, temp); 89 90 bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST] + 3); 91 temp = bytetemp | 0x80; 92 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST] + 3, temp); 93 94 rtl_write_byte(rtlpriv, 0x2F8, 0x3); 95 96 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0x72); 97} 98 99u8 stg_efuse_read_1byte(struct ieee80211_hw *hw, u16 address) 100{ 101 struct rtl_priv *rtlpriv = rtl_priv(hw); 102 u8 data; 103 u8 bytetemp; 104 u8 temp; 105 u32 k = 0; 106 const u32 efuse_real_content_len = 107 rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE]; 108 109 if (address < efuse_real_content_len) { 110 temp = address & 0xFF; 111 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1, 112 temp); 113 bytetemp = rtl_read_byte(rtlpriv, 114 rtlpriv->cfg->maps[EFUSE_CTRL] + 2); 115 temp = ((address >> 8) & 0x03) | (bytetemp & 0xFC); 116 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2, 117 temp); 118 119 bytetemp = rtl_read_byte(rtlpriv, 120 rtlpriv->cfg->maps[EFUSE_CTRL] + 3); 121 temp = bytetemp & 0x7F; 122 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 123 temp); 124 125 bytetemp = rtl_read_byte(rtlpriv, 126 rtlpriv->cfg->maps[EFUSE_CTRL] + 3); 127 while (!(bytetemp & 0x80)) { 128 bytetemp = rtl_read_byte(rtlpriv, 129 rtlpriv->cfg-> 130 maps[EFUSE_CTRL] + 3); 131 k++; 132 if (k == 1000) { 133 k = 0; 134 break; 135 } 136 } 137 data = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]); 138 return data; 139 } else { 140 return 0xFF; 141 } 142} 143EXPORT_SYMBOL(stg_efuse_read_1byte); 144 145void efuse92e_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value) 146{ 147 struct rtl_priv *rtlpriv = rtl_priv(hw); 148 u8 bytetemp; 149 u8 temp; 150 u32 k = 0; 151 const u32 efuse_real_content_len = 152 rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE]; 153 154 RT_TRACE(COMP_EFUSE, DBG_LOUD, 155 ("Addr=%x Data =%x\n", address, value)); 156 157 if (address < efuse_real_content_len) { 158 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], value); 159 160 temp = address & 0xFF; 161 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1, 162 temp); 163 bytetemp = rtl_read_byte(rtlpriv, 164 rtlpriv->cfg->maps[EFUSE_CTRL] + 2); 165 166 temp = ((address >> 8) & 0x03) | (bytetemp & 0xFC); 167 rtl_write_byte(rtlpriv, 168 rtlpriv->cfg->maps[EFUSE_CTRL] + 2, temp); 169 170 bytetemp = rtl_read_byte(rtlpriv, 171 rtlpriv->cfg->maps[EFUSE_CTRL] + 3); 172 temp = bytetemp | 0x80; 173 rtl_write_byte(rtlpriv, 174 rtlpriv->cfg->maps[EFUSE_CTRL] + 3, temp); 175 176 bytetemp = rtl_read_byte(rtlpriv, 177 rtlpriv->cfg->maps[EFUSE_CTRL] + 3); 178 179 while (bytetemp & 0x80) { 180 bytetemp = rtl_read_byte(rtlpriv, 181 rtlpriv->cfg-> 182 maps[EFUSE_CTRL] + 3); 183 k++; 184 if (k == 100) { 185 k = 0; 186 break; 187 } 188 } 189 } 190} 191 192void read92e_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf) 193{ 194 struct rtl_priv *rtlpriv = rtl_priv(hw); 195 u32 value32; 196 u8 readbyte; 197 u16 retry; 198 199 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1, 200 (_offset & 0xff)); 201 readbyte = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2); 202 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2, 203 ((_offset >> 8) & 0x03) | (readbyte & 0xfc)); 204 205 readbyte = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3); 206 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 207 (readbyte & 0x7f)); 208 209 retry = 0; 210 value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]); 211 while (!(((value32 >> 24) & 0xff) & 0x80) && (retry < 10000)) { 212 value32 = rtl_read_dword(rtlpriv, 213 rtlpriv->cfg->maps[EFUSE_CTRL]); 214 retry++; 215 } 216 217 udelay(50); 218 value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]); 219 220 *pbuf = (u8) (value32 & 0xff); 221} 222 223void read92e_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, 224 u8 *pbuf) 225{ 226 struct rtl_priv *rtlpriv = rtl_priv(hw); 227 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 228 u8 *efuse_tbl; 229 u8 rtemp8[1]; 230 u16 efuse_addr = 0; 231 u8 offset, wren; 232 u8 u1temp = 0; 233 u16 i; 234 u16 j; 235 const u16 efuse_max_section = 236 rtlpriv->cfg->maps[EFUSE_MAX_SECTION_MAP]; 237 const u32 efuse_real_content_len = 238 rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE]; 239 u16 **efuse_word; 240 u16 efuse_utilized = 0; 241 u8 efuse_usage; 242 243 if ((_offset + _size_byte) > rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]) { 244 RT_TRACE(COMP_EFUSE, DBG_LOUD, 245 ("read92e_efuse(): Invalid offset(%#x) with read bytes(%#x)!!\n", 246 _offset, _size_byte)); 247 return; 248 } 249 250 /* allocate memory for efuse_tbl and efuse_word */ 251 efuse_tbl = kmalloc(rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE] * 252 sizeof(u8), GFP_ATOMIC); 253 if (!efuse_tbl) 254 return; 255 efuse_word = kzalloc(EFUSE_MAX_WORD_UNIT * sizeof(u16 *), GFP_ATOMIC); 256 if (!efuse_word) 257 goto out; 258 for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { 259 efuse_word[i] = kmalloc(efuse_max_section * sizeof(u16), 260 GFP_ATOMIC); 261 if (!efuse_word[i]) 262 goto done; 263 } 264 265 for (i = 0; i < efuse_max_section; i++) 266 for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) 267 efuse_word[j][j] = 0xFFFF; 268 269 read92e_efuse_byte(hw, efuse_addr, rtemp8); 270 if (*rtemp8 != 0xFF) { 271 efuse_utilized++; 272 RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL, 273 "Addr=%d\n", efuse_addr); 274 efuse_addr++; 275 } 276 277 while ((*rtemp8 != 0xFF) && (efuse_addr < efuse_real_content_len)) { 278 /* Check PG header for section num. */ 279 if ((*rtemp8 & 0x1F) == 0x0F) {/* extended header */ 280 u1temp = ((*rtemp8 & 0xE0) >> 5); 281 read92e_efuse_byte(hw, efuse_addr, rtemp8); 282 283 if ((*rtemp8 & 0x0F) == 0x0F) { 284 efuse_addr++; 285 read92e_efuse_byte(hw, efuse_addr, rtemp8); 286 287 if (*rtemp8 != 0xFF && 288 (efuse_addr < efuse_real_content_len)) { 289 efuse_addr++; 290 } 291 continue; 292 } else { 293 offset = ((*rtemp8 & 0xF0) >> 1) | u1temp; 294 wren = (*rtemp8 & 0x0F); 295 efuse_addr++; 296 } 297 } else { 298 offset = ((*rtemp8 >> 4) & 0x0f); 299 wren = (*rtemp8 & 0x0f); 300 } 301 302 if (offset < efuse_max_section) { 303 RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL, 304 "offset-%d Worden=%x\n", offset, wren); 305 306 for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { 307 if (!(wren & 0x01)) { 308 RTPRINT(rtlpriv, FEEPROM, 309 EFUSE_READ_ALL, "Addr=%d\n", 310 efuse_addr); 311 312 read92e_efuse_byte(hw, efuse_addr, 313 rtemp8); 314 efuse_addr++; 315 efuse_utilized++; 316 efuse_word[i][offset] = (*rtemp8 & 317 0xff); 318 319 if (efuse_addr >= 320 efuse_real_content_len) 321 break; 322 323 RTPRINT(rtlpriv, FEEPROM, 324 EFUSE_READ_ALL, "Addr=%d\n", 325 efuse_addr); 326 327 read92e_efuse_byte(hw, efuse_addr, 328 rtemp8); 329 efuse_addr++; 330 efuse_utilized++; 331 efuse_word[i][offset] |= 332 (((u16) *rtemp8 << 8) & 0xff00); 333 334 if (efuse_addr >= 335 efuse_real_content_len) 336 break; 337 } 338 339 wren >>= 1; 340 } 341 } 342 343 RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL, 344 "Addr=%d\n", efuse_addr); 345 read92e_efuse_byte(hw, efuse_addr, rtemp8); 346 if (*rtemp8 != 0xFF && (efuse_addr < efuse_real_content_len)) { 347 efuse_utilized++; 348 efuse_addr++; 349 } 350 } 351 352 for (i = 0; i < efuse_max_section; i++) { 353 for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) { 354 efuse_tbl[(i * 8) + (j * 2)] = 355 (efuse_word[j][i] & 0xff); 356 efuse_tbl[(i * 8) + ((j * 2) + 1)] = 357 ((efuse_word[j][i] >> 8) & 0xff); 358 } 359 } 360 361 for (i = 0; i < _size_byte; i++) 362 pbuf[i] = efuse_tbl[_offset + i]; 363 364 rtlefuse->efuse_usedbytes = efuse_utilized; 365 efuse_usage = (u8) ((efuse_utilized * 100) / efuse_real_content_len); 366 rtlefuse->efuse_usedpercentage = efuse_usage; 367 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_BYTES, 368 (u8 *)&efuse_utilized); 369 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_USAGE, 370 (u8 *)&efuse_usage); 371done: 372 for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) 373 kfree(efuse_word[i]); 374 kfree(efuse_word); 375out: 376 kfree(efuse_tbl); 377} 378 379bool efuse92e_shadow_update_chk(struct ieee80211_hw *hw) 380{ 381 struct rtl_priv *rtlpriv = rtl_priv(hw); 382 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 383 u8 section_idx, i, Base; 384 u16 words_need = 0, hdr_num = 0, totalbytes, efuse_used; 385 bool bwordchanged, bresult = true; 386 387 for (section_idx = 0; section_idx < 16; section_idx++) { 388 Base = section_idx * 8; 389 bwordchanged = false; 390 391 for (i = 0; i < 8; i = i + 2) { 392 if ((rtlefuse->efuse_map[EFUSE_INIT_MAP][Base + i] != 393 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][Base + i]) || 394 (rtlefuse->efuse_map[EFUSE_INIT_MAP][Base + i + 1] != 395 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][Base + i + 396 1])) { 397 words_need++; 398 bwordchanged = true; 399 } 400 } 401 402 if (bwordchanged) 403 hdr_num++; 404 } 405 406 totalbytes = hdr_num + words_need * 2; 407 efuse_used = rtlefuse->efuse_usedbytes; 408 409 if ((totalbytes + efuse_used) >= 410 (EFUSE_MAX_SIZE - rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN])) 411 bresult = false; 412 413 RT_TRACE(COMP_EFUSE, DBG_LOUD, 414 ("efuse92e_shadow_update_chk(): totalbytes(%#x), hdr_num(%#x), words_need(%#x), efuse_used(%d)\n", 415 totalbytes, hdr_num, words_need, efuse_used)); 416 417 return bresult; 418} 419 420void efuse92e_shadow_read(struct ieee80211_hw *hw, u8 type, 421 u16 offset, u32 *value) 422{ 423 if (type == 1) 424 efuse92e_shadow_read_1byte(hw, offset, (u8 *)value); 425 else if (type == 2) 426 efuse92e_shadow_read_2byte(hw, offset, (u16 *)value); 427 else if (type == 4) 428 efuse92e_shadow_read_4byte(hw, offset, (u32 *)value); 429} 430EXPORT_SYMBOL(efuse92e_shadow_read); 431 432void efuse92e_shadow_write(struct ieee80211_hw *hw, u8 type, u16 offset, 433 u32 value) 434{ 435 if (type == 1) 436 efuse92e_shadow_write_1byte(hw, offset, (u8)value); 437 else if (type == 2) 438 efuse92e_shadow_write_2byte(hw, offset, (u16)value); 439 else if (type == 4) 440 efuse92e_shadow_write_4byte(hw, offset, (u32)value); 441} 442 443bool efuse92e_shadow_update(struct ieee80211_hw *hw) 444{ 445 struct rtl_priv *rtlpriv = rtl_priv(hw); 446 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 447 u16 i, offset, base; 448 u8 word_en = 0x0F; 449 u8 first_pg = false; 450 451 RT_TRACE(COMP_EFUSE, DBG_LOUD, ("\n")); 452 453 if (!efuse92e_shadow_update_chk(hw)) { 454 efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]); 455 memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0], 456 &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], 457 rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); 458 459 RT_TRACE(COMP_EFUSE, DBG_LOUD, 460 ("efuse out of capacity!!\n")); 461 return false; 462 } 463 efuse_power_switch(hw, true, true); 464 465 for (offset = 0; offset < 16; offset++) { 466 word_en = 0x0F; 467 base = offset * 8; 468 469 for (i = 0; i < 8; i++) { 470 if (first_pg) { 471 word_en &= ~(BIT(i / 2)); 472 473 rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] = 474 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i]; 475 } else { 476 if (rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] != 477 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i]) { 478 word_en &= ~(BIT(i / 2)); 479 480 rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] = 481 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i]; 482 } 483 } 484 } 485 486 if (word_en != 0x0F) { 487 u8 tmpdata[8]; 488 memcpy(tmpdata, 489 (&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base]), 490 8); 491 RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, 492 "U-efuse\n", tmpdata, 8); 493 494 if (!efuse_pg_packet_write(hw, (u8) offset, word_en, 495 tmpdata)) { 496 RT_TRACE(COMP_ERR, DBG_WARNING, 497 ("PG section(%#x) fail!!\n", offset)); 498 break; 499 } 500 } 501 } 502 503 efuse_power_switch(hw, true, false); 504 efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]); 505 506 memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0], 507 &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], 508 rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); 509 510 RT_TRACE(COMP_EFUSE, DBG_LOUD, ("\n")); 511 return true; 512} 513 514void stg_rtl_efuse92e_shadow_map_update(struct ieee80211_hw *hw) 515{ 516 struct rtl_priv *rtlpriv = rtl_priv(hw); 517 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 518 519 if (rtlefuse->autoload_failflag) { 520 memset(&rtlefuse->efuse_map[EFUSE_INIT_MAP][0], 521 0xFF, rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); 522 } else { 523 efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]); 524 } 525 526 memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0], 527 &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], 528 rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); 529} 530EXPORT_SYMBOL(stg_rtl_efuse92e_shadow_map_update); 531 532void efuse92e_force_write_vendor_Id(struct ieee80211_hw *hw) 533{ 534 u8 tmpdata[8] = { 0xFF, 0xFF, 0xEC, 0x10, 0xFF, 0xFF, 0xFF, 0xFF }; 535 536 efuse_power_switch(hw, true, true); 537 efuse_pg_packet_write(hw, 1, 0xD, tmpdata); 538 efuse_power_switch(hw, true, false); 539} 540 541void efuse92e_re_pg_section(struct ieee80211_hw *hw, u8 section_idx) 542{ 543} 544 545static void efuse92e_shadow_read_1byte(struct ieee80211_hw *hw, 546 u16 offset, u8 *value) 547{ 548 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 549 *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset]; 550} 551 552static void efuse92e_shadow_read_2byte(struct ieee80211_hw *hw, 553 u16 offset, u16 *value) 554{ 555 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 556 557 *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset]; 558 *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] << 8; 559} 560 561static void efuse92e_shadow_read_4byte(struct ieee80211_hw *hw, 562 u16 offset, u32 *value) 563{ 564 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 565 566 *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset]; 567 *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] << 8; 568 *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 2] << 16; 569 *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 3] << 24; 570} 571 572static void efuse92e_shadow_write_1byte(struct ieee80211_hw *hw, 573 u16 offset, u8 value) 574{ 575 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 576 577 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] = value; 578} 579 580static void efuse92e_shadow_write_2byte(struct ieee80211_hw *hw, 581 u16 offset, u16 value) 582{ 583 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 584 585 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] = value & 0x00FF; 586 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] = value >> 8; 587} 588 589static void efuse92e_shadow_write_4byte(struct ieee80211_hw *hw, 590 u16 offset, u32 value) 591{ 592 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 593 594 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] = 595 (u8) (value & 0x000000FF); 596 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] = 597 (u8) ((value >> 8) & 0x0000FF); 598 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 2] = 599 (u8) ((value >> 16) & 0x00FF); 600 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 3] = 601 (u8) ((value >> 24) & 0xFF); 602} 603 604int stg_efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr, u8 *data) 605{ 606 struct rtl_priv *rtlpriv = rtl_priv(hw); 607 u8 tmpidx = 0; 608 int bresult; 609 610 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1, 611 (u8) (addr & 0xff)); 612 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2, 613 ((u8) ((addr >> 8) & 0x03)) | 614 (rtl_read_byte(rtlpriv, 615 rtlpriv->cfg->maps[EFUSE_CTRL] + 2) & 616 0xFC)); 617 618 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0x72); 619 620 while (!(0x80 & rtl_read_byte(rtlpriv, 621 rtlpriv->cfg->maps[EFUSE_CTRL] + 3)) && 622 (tmpidx < 100)) { 623 tmpidx++; 624 } 625 626 if (tmpidx < 100) { 627 *data = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]); 628 bresult = true; 629 } else { 630 *data = 0xff; 631 bresult = false; 632 } 633 return bresult; 634} 635EXPORT_SYMBOL(stg_efuse_one_byte_read); 636 637static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data) 638{ 639 struct rtl_priv *rtlpriv = rtl_priv(hw); 640 u8 tmpidx = 0; 641 bool bresult; 642 643 RT_TRACE(COMP_EFUSE, DBG_LOUD, 644 ("Addr = %x Data=%x\n", addr, data)); 645 646 rtl_write_byte(rtlpriv, 647 rtlpriv->cfg->maps[EFUSE_CTRL] + 1, (u8) (addr & 0xff)); 648 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2, 649 (rtl_read_byte(rtlpriv, 650 rtlpriv->cfg->maps[EFUSE_CTRL] + 651 2) & 0xFC) | (u8) ((addr >> 8) & 0x03)); 652 653 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], data); 654 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0xF2); 655 656 while ((0x80 & rtl_read_byte(rtlpriv, 657 rtlpriv->cfg->maps[EFUSE_CTRL] + 3)) && 658 (tmpidx < 100)) { 659 tmpidx++; 660 } 661 662 if (tmpidx < 100) 663 bresult = true; 664 else 665 bresult = false; 666 667 return bresult; 668} 669 670static void efuse_read_all_map(struct ieee80211_hw *hw, u8 *efuse) 671{ 672 struct rtl_priv *rtlpriv = rtl_priv(hw); 673 efuse_power_switch(hw, false, true); 674 read92e_efuse(hw, 0, rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE], efuse); 675 efuse_power_switch(hw, false, false); 676} 677 678static void efuse_read_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, 679 u8 efuse_data, u8 offset, u8 *tmpdata, 680 u8 *readstate) 681{ 682 bool bdataempty = true; 683 u8 hoffset; 684 u8 tmpidx; 685 u8 hworden; 686 u8 word_cnts; 687 688 hoffset = (efuse_data >> 4) & 0x0F; 689 hworden = efuse_data & 0x0F; 690 word_cnts = efuse_calculate_word_cnts(hworden); 691 692 if (hoffset == offset) { 693 for (tmpidx = 0; tmpidx < word_cnts * 2; tmpidx++) { 694 if (stg_efuse_one_byte_read(hw, *efuse_addr + 1 + tmpidx, 695 &efuse_data)) { 696 tmpdata[tmpidx] = efuse_data; 697 if (efuse_data != 0xff) 698 bdataempty = false; 699 } 700 } 701 702 if (!bdataempty) { 703 *readstate = PG_STATE_DATA; 704 } else { 705 *efuse_addr = *efuse_addr + (word_cnts * 2) + 1; 706 *readstate = PG_STATE_HEADER; 707 } 708 709 } else { 710 *efuse_addr = *efuse_addr + (word_cnts * 2) + 1; 711 *readstate = PG_STATE_HEADER; 712 } 713} 714 715static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data) 716{ 717 u8 readstate = PG_STATE_HEADER; 718 719 bool bcontinual = true; 720 721 u8 efuse_data, word_cnts = 0; 722 u16 efuse_addr = 0; 723 u8 hworden = 0; 724 u8 tmpdata[8]; 725 726 if (data == NULL) 727 return false; 728 if (offset > 15) 729 return false; 730 731 memset(data, 0xff, PGPKT_DATA_SIZE * sizeof(u8)); 732 memset(tmpdata, 0xff, PGPKT_DATA_SIZE * sizeof(u8)); 733 734 while (bcontinual && (efuse_addr < EFUSE_MAX_SIZE)) { 735 if (readstate & PG_STATE_HEADER) { 736 if (stg_efuse_one_byte_read(hw, efuse_addr, &efuse_data) && 737 (efuse_data != 0xFF)) 738 efuse_read_data_case1(hw, &efuse_addr, 739 efuse_data, offset, 740 tmpdata, &readstate); 741 else 742 bcontinual = false; 743 } else if (readstate & PG_STATE_DATA) { 744 efuse_word_enable_data_read(hworden, tmpdata, data); 745 efuse_addr = efuse_addr + (word_cnts * 2) + 1; 746 readstate = PG_STATE_HEADER; 747 } 748 } 749 750 if ((data[0] == 0xff) && (data[1] == 0xff) && 751 (data[2] == 0xff) && (data[3] == 0xff) && 752 (data[4] == 0xff) && (data[5] == 0xff) && 753 (data[6] == 0xff) && (data[7] == 0xff)) 754 return false; 755 else 756 return true; 757} 758 759static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, 760 u8 efuse_data, u8 offset, 761 int *bcontinual, u8 *write_state, 762 struct pgpkt_struct *target_pkt, 763 int *repeat_times, int *bresult, u8 word_en) 764{ 765 struct rtl_priv *rtlpriv = rtl_priv(hw); 766 struct pgpkt_struct tmp_pkt; 767 int bdataempty = true; 768 u8 originaldata[8 * sizeof(u8)]; 769 u8 badworden = 0x0F; 770 u8 match_word_en, tmp_word_en; 771 u8 tmpindex; 772 u8 tmp_header = efuse_data; 773 u8 tmp_word_cnts; 774 775 tmp_pkt.offset = (tmp_header >> 4) & 0x0F; 776 tmp_pkt.word_en = tmp_header & 0x0F; 777 tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en); 778 779 if (tmp_pkt.offset != target_pkt->offset) { 780 *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1; 781 *write_state = PG_STATE_HEADER; 782 } else { 783 for (tmpindex = 0; tmpindex < (tmp_word_cnts * 2); tmpindex++) { 784 if (stg_efuse_one_byte_read(hw, 785 (*efuse_addr + 1 + tmpindex), 786 &efuse_data) && 787 (efuse_data != 0xFF)) 788 bdataempty = false; 789 } 790 791 if (!bdataempty) { 792 *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1; 793 *write_state = PG_STATE_HEADER; 794 } else { 795 match_word_en = 0x0F; 796 if (!((target_pkt->word_en & BIT(0)) | 797 (tmp_pkt.word_en & BIT(0)))) 798 match_word_en &= (~BIT(0)); 799 800 if (!((target_pkt->word_en & BIT(1)) | 801 (tmp_pkt.word_en & BIT(1)))) 802 match_word_en &= (~BIT(1)); 803 804 if (!((target_pkt->word_en & BIT(2)) | 805 (tmp_pkt.word_en & BIT(2)))) 806 match_word_en &= (~BIT(2)); 807 808 if (!((target_pkt->word_en & BIT(3)) | 809 (tmp_pkt.word_en & BIT(3)))) 810 match_word_en &= (~BIT(3)); 811 812 if ((match_word_en & 0x0F) != 0x0F) { 813 badworden = efuse_word_enable_data_write(hw, 814 *efuse_addr + 1, 815 tmp_pkt.word_en, 816 target_pkt->data); 817 818 if (0x0F != (badworden & 0x0F)) { 819 u8 reorg_offset = offset; 820 u8 reorg_worden = badworden; 821 efuse_pg_packet_write(hw, reorg_offset, 822 reorg_worden, 823 originaldata); 824 } 825 826 tmp_word_en = 0x0F; 827 if ((target_pkt->word_en & BIT(0)) ^ 828 (match_word_en & BIT(0))) 829 tmp_word_en &= (~BIT(0)); 830 831 if ((target_pkt->word_en & BIT(1)) ^ 832 (match_word_en & BIT(1))) 833 tmp_word_en &= (~BIT(1)); 834 835 if ((target_pkt->word_en & BIT(2)) ^ 836 (match_word_en & BIT(2))) 837 tmp_word_en &= (~BIT(2)); 838 839 if ((target_pkt->word_en & BIT(3)) ^ 840 (match_word_en & BIT(3))) 841 tmp_word_en &= (~BIT(3)); 842 843 if ((tmp_word_en & 0x0F) != 0x0F) { 844 *efuse_addr = efuse_get_current_size(hw); 845 target_pkt->offset = offset; 846 target_pkt->word_en = tmp_word_en; 847 } else { 848 *bcontinual = false; 849 } 850 *write_state = PG_STATE_HEADER; 851 *repeat_times += 1; 852 if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) { 853 *bcontinual = false; 854 *bresult = false; 855 } 856 } else { 857 *efuse_addr += (2 * tmp_word_cnts) + 1; 858 target_pkt->offset = offset; 859 target_pkt->word_en = word_en; 860 *write_state = PG_STATE_HEADER; 861 } 862 } 863 } 864 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, "efuse PG_STATE_HEADER-1\n"); 865} 866 867static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr, 868 int *bcontinual, u8 *write_state, 869 struct pgpkt_struct target_pkt, 870 int *repeat_times, int *bresult) 871{ 872 struct rtl_priv *rtlpriv = rtl_priv(hw); 873 struct pgpkt_struct tmp_pkt; 874 u8 pg_header; 875 u8 tmp_header; 876 u8 originaldata[8 * sizeof(u8)]; 877 u8 tmp_word_cnts; 878 u8 badworden = 0x0F; 879 880 pg_header = ((target_pkt.offset << 4) & 0xf0) | target_pkt.word_en; 881 efuse_one_byte_write(hw, *efuse_addr, pg_header); 882 stg_efuse_one_byte_read(hw, *efuse_addr, &tmp_header); 883 884 if (tmp_header == pg_header) { 885 *write_state = PG_STATE_DATA; 886 } else if (tmp_header == 0xFF) { 887 *write_state = PG_STATE_HEADER; 888 *repeat_times += 1; 889 if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) { 890 *bcontinual = false; 891 *bresult = false; 892 } 893 } else { 894 tmp_pkt.offset = (tmp_header >> 4) & 0x0F; 895 tmp_pkt.word_en = tmp_header & 0x0F; 896 897 tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en); 898 899 memset(originaldata, 0xff, 8 * sizeof(u8)); 900 901 if (efuse_pg_packet_read(hw, tmp_pkt.offset, originaldata)) { 902 badworden = efuse_word_enable_data_write(hw, 903 *efuse_addr + 1, 904 tmp_pkt.word_en, 905 originaldata); 906 907 if (0x0F != (badworden & 0x0F)) { 908 u8 reorg_offset = tmp_pkt.offset; 909 u8 reorg_worden = badworden; 910 efuse_pg_packet_write(hw, reorg_offset, 911 reorg_worden, 912 originaldata); 913 *efuse_addr = efuse_get_current_size(hw); 914 } else { 915 *efuse_addr = *efuse_addr + 916 (tmp_word_cnts * 2) + 1; 917 } 918 } else { 919 *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1; 920 } 921 922 *write_state = PG_STATE_HEADER; 923 *repeat_times += 1; 924 if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) { 925 *bcontinual = false; 926 *bresult = false; 927 } 928 929 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, 930 "efuse PG_STATE_HEADER-2\n"); 931 } 932} 933 934static int efuse_pg_packet_write(struct ieee80211_hw *hw, 935 u8 offset, u8 word_en, u8 *data) 936{ 937 struct rtl_priv *rtlpriv = rtl_priv(hw); 938 struct pgpkt_struct target_pkt; 939 u8 write_state = PG_STATE_HEADER; 940 int bcontinual = true, bdataempty = true, bresult = true; 941 u16 efuse_addr = 0; 942 u8 efuse_data; 943 u8 target_word_cnts = 0; 944 u8 badworden = 0x0F; 945 static int repeat_times; 946 947 if (efuse_get_current_size(hw) >= (EFUSE_MAX_SIZE - 948 rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN])) { 949 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, 950 "efuse_pg_packet_write error\n"); 951 return false; 952 } 953 954 target_pkt.offset = offset; 955 target_pkt.word_en = word_en; 956 957 memset(target_pkt.data, 0xFF, 8 * sizeof(u8)); 958 959 efuse_word_enable_data_read(word_en, data, target_pkt.data); 960 target_word_cnts = efuse_calculate_word_cnts(target_pkt.word_en); 961 962 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, "efuse Power ON\n"); 963 964 while (bcontinual && (efuse_addr < (EFUSE_MAX_SIZE - 965 rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN]))) { 966 if (write_state == PG_STATE_HEADER) { 967 bdataempty = true; 968 badworden = 0x0F; 969 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, 970 "efuse PG_STATE_HEADER\n"); 971 972 if (stg_efuse_one_byte_read(hw, efuse_addr, &efuse_data) && 973 (efuse_data != 0xFF)) 974 efuse_write_data_case1(hw, &efuse_addr, 975 efuse_data, offset, 976 &bcontinual, 977 &write_state, 978 &target_pkt, 979 &repeat_times, &bresult, 980 word_en); 981 else 982 efuse_write_data_case2(hw, &efuse_addr, 983 &bcontinual, 984 &write_state, 985 target_pkt, 986 &repeat_times, 987 &bresult); 988 989 } else if (write_state == PG_STATE_DATA) { 990 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, 991 "efuse PG_STATE_DATA\n"); 992 badworden = 0x0f; 993 badworden = 994 efuse_word_enable_data_write(hw, efuse_addr + 1, 995 target_pkt.word_en, 996 target_pkt.data); 997 998 if ((badworden & 0x0F) == 0x0F) { 999 bcontinual = false; 1000 } else { 1001 efuse_addr = 1002 efuse_addr + (2 * target_word_cnts) + 1; 1003 1004 target_pkt.offset = offset; 1005 target_pkt.word_en = badworden; 1006 target_word_cnts = 1007 efuse_calculate_word_cnts(target_pkt. 1008 word_en); 1009 write_state = PG_STATE_HEADER; 1010 repeat_times++; 1011 if (repeat_times > EFUSE_REPEAT_THRESHOLD_) { 1012 bcontinual = false; 1013 bresult = false; 1014 } 1015 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, 1016 "efuse PG_STATE_HEADER-3\n"); 1017 } 1018 } 1019 } 1020 1021 if (efuse_addr >= (EFUSE_MAX_SIZE - 1022 rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN])) { 1023 RT_TRACE(COMP_EFUSE, DBG_LOUD, 1024 ("efuse_addr(%#x) Out of size!!\n", efuse_addr)); 1025 } 1026 1027 return true; 1028} 1029 1030static void efuse_word_enable_data_read(u8 word_en, u8 *sourdata, 1031 u8 *targetdata) 1032{ 1033 if (!(word_en & BIT(0))) { 1034 targetdata[0] = sourdata[0]; 1035 targetdata[1] = sourdata[1]; 1036 } 1037 1038 if (!(word_en & BIT(1))) { 1039 targetdata[2] = sourdata[2]; 1040 targetdata[3] = sourdata[3]; 1041 } 1042 1043 if (!(word_en & BIT(2))) { 1044 targetdata[4] = sourdata[4]; 1045 targetdata[5] = sourdata[5]; 1046 } 1047 1048 if (!(word_en & BIT(3))) { 1049 targetdata[6] = sourdata[6]; 1050 targetdata[7] = sourdata[7]; 1051 } 1052} 1053 1054static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw, 1055 u16 efuse_addr, u8 word_en, u8 *data) 1056{ 1057 struct rtl_priv *rtlpriv = rtl_priv(hw); 1058 u16 tmpaddr; 1059 u16 start_addr = efuse_addr; 1060 u8 badworden = 0x0F; 1061 u8 tmpdata[8]; 1062 1063 memset(tmpdata, 0xff, PGPKT_DATA_SIZE); 1064 RT_TRACE(COMP_EFUSE, DBG_LOUD, 1065 ("word_en = %x efuse_addr=%x\n", word_en, efuse_addr)); 1066 1067 if (!(word_en & BIT(0))) { 1068 tmpaddr = start_addr; 1069 efuse_one_byte_write(hw, start_addr++, data[0]); 1070 efuse_one_byte_write(hw, start_addr++, data[1]); 1071 1072 stg_efuse_one_byte_read(hw, tmpaddr, &tmpdata[0]); 1073 stg_efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[1]); 1074 if ((data[0] != tmpdata[0]) || (data[1] != tmpdata[1])) 1075 badworden &= (~BIT(0)); 1076 } 1077 1078 if (!(word_en & BIT(1))) { 1079 tmpaddr = start_addr; 1080 efuse_one_byte_write(hw, start_addr++, data[2]); 1081 efuse_one_byte_write(hw, start_addr++, data[3]); 1082 1083 stg_efuse_one_byte_read(hw, tmpaddr, &tmpdata[2]); 1084 stg_efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[3]); 1085 if ((data[2] != tmpdata[2]) || (data[3] != tmpdata[3])) 1086 badworden &= (~BIT(1)); 1087 } 1088 1089 if (!(word_en & BIT(2))) { 1090 tmpaddr = start_addr; 1091 efuse_one_byte_write(hw, start_addr++, data[4]); 1092 efuse_one_byte_write(hw, start_addr++, data[5]); 1093 1094 stg_efuse_one_byte_read(hw, tmpaddr, &tmpdata[4]); 1095 stg_efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[5]); 1096 if ((data[4] != tmpdata[4]) || (data[5] != tmpdata[5])) 1097 badworden &= (~BIT(2)); 1098 } 1099 1100 if (!(word_en & BIT(3))) { 1101 tmpaddr = start_addr; 1102 efuse_one_byte_write(hw, start_addr++, data[6]); 1103 efuse_one_byte_write(hw, start_addr++, data[7]); 1104 1105 stg_efuse_one_byte_read(hw, tmpaddr, &tmpdata[6]); 1106 stg_efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[7]); 1107 if ((data[6] != tmpdata[6]) || (data[7] != tmpdata[7])) 1108 badworden &= (~BIT(3)); 1109 } 1110 1111 return badworden; 1112} 1113 1114static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite, u8 pwrstate) 1115{ 1116 struct rtl_priv *rtlpriv = rtl_priv(hw); 1117 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 1118 u8 tempval; 1119 u16 tmpv16; 1120 1121 if (pwrstate && (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE)) { 1122 if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192CE && 1123 rtlhal->hw_type != HARDWARE_TYPE_RTL8192DE) { 1124 rtl_write_byte(rtlpriv, 1125 rtlpriv->cfg->maps[EFUSE_ACCESS], 0x69); 1126 } else { 1127 tmpv16 = rtl_read_word(rtlpriv, 1128 rtlpriv->cfg->maps[SYS_ISO_CTRL]); 1129 if (!(tmpv16 & rtlpriv->cfg->maps[EFUSE_PWC_EV12V])) { 1130 tmpv16 |= rtlpriv->cfg->maps[EFUSE_PWC_EV12V]; 1131 rtl_write_word(rtlpriv, 1132 rtlpriv->cfg->maps[SYS_ISO_CTRL], 1133 tmpv16); 1134 } 1135 } 1136 tmpv16 = rtl_read_word(rtlpriv, 1137 rtlpriv->cfg->maps[SYS_FUNC_EN]); 1138 if (!(tmpv16 & rtlpriv->cfg->maps[EFUSE_FEN_ELDR])) { 1139 tmpv16 |= rtlpriv->cfg->maps[EFUSE_FEN_ELDR]; 1140 rtl_write_word(rtlpriv, 1141 rtlpriv->cfg->maps[SYS_FUNC_EN], tmpv16); 1142 } 1143 1144 tmpv16 = rtl_read_word(rtlpriv, rtlpriv->cfg->maps[SYS_CLK]); 1145 if ((!(tmpv16 & rtlpriv->cfg->maps[EFUSE_LOADER_CLK_EN])) || 1146 (!(tmpv16 & rtlpriv->cfg->maps[EFUSE_ANA8M]))) { 1147 tmpv16 |= (rtlpriv->cfg->maps[EFUSE_LOADER_CLK_EN] | 1148 rtlpriv->cfg->maps[EFUSE_ANA8M]); 1149 rtl_write_word(rtlpriv, 1150 rtlpriv->cfg->maps[SYS_CLK], tmpv16); 1151 } 1152 } 1153 1154 if (pwrstate) { 1155 if (bwrite) { 1156 tempval = rtl_read_byte(rtlpriv, 1157 rtlpriv->cfg->maps[EFUSE_TEST] + 1158 3); 1159 1160 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { 1161 tempval &= ~(BIT(3) | BIT(4) | BIT(5) | BIT(6)); 1162 tempval |= (VOLTAGE_V25 << 3); 1163 } else if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE) { 1164 tempval &= 0x0F; 1165 tempval |= (VOLTAGE_V25 << 4); 1166 } 1167 1168 rtl_write_byte(rtlpriv, 1169 rtlpriv->cfg->maps[EFUSE_TEST] + 3, 1170 (tempval | 0x80)); 1171 } 1172 1173 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) { 1174 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CLK], 1175 0x03); 1176 } 1177 } else { 1178 if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192CE && 1179 rtlhal->hw_type != HARDWARE_TYPE_RTL8192DE) 1180 rtl_write_byte(rtlpriv, 1181 rtlpriv->cfg->maps[EFUSE_ACCESS], 0); 1182 if (bwrite) { 1183 tempval = rtl_read_byte(rtlpriv, 1184 rtlpriv->cfg->maps[EFUSE_TEST] + 1185 3); 1186 rtl_write_byte(rtlpriv, 1187 rtlpriv->cfg->maps[EFUSE_TEST] + 3, 1188 (tempval & 0x7F)); 1189 } 1190 1191 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) { 1192 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CLK], 1193 0x02); 1194 } 1195 } 1196} 1197 1198static u16 efuse_get_current_size(struct ieee80211_hw *hw) 1199{ 1200 int bcontinual = true; 1201 u16 efuse_addr = 0; 1202 u8 hoffset, hworden; 1203 u8 efuse_data, word_cnts; 1204 1205 while (bcontinual && 1206 stg_efuse_one_byte_read(hw, efuse_addr, &efuse_data) && 1207 (efuse_addr < EFUSE_MAX_SIZE)) { 1208 if (efuse_data != 0xFF) { 1209 hoffset = (efuse_data >> 4) & 0x0F; 1210 hworden = efuse_data & 0x0F; 1211 word_cnts = efuse_calculate_word_cnts(hworden); 1212 efuse_addr = efuse_addr + (word_cnts * 2) + 1; 1213 } else { 1214 bcontinual = false; 1215 } 1216 } 1217 1218 return efuse_addr; 1219} 1220 1221static u8 efuse_calculate_word_cnts(u8 word_en) 1222{ 1223 u8 word_cnts = 0; 1224 if (!(word_en & BIT(0))) 1225 word_cnts++; 1226 if (!(word_en & BIT(1))) 1227 word_cnts++; 1228 if (!(word_en & BIT(2))) 1229 word_cnts++; 1230 if (!(word_en & BIT(3))) 1231 word_cnts++; 1232 return word_cnts; 1233}