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