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