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