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