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