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