linux/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright(c) 2009-2013  Realtek Corporation.*/
   3
   4#include "../wifi.h"
   5#include "../pci.h"
   6#include "../ps.h"
   7#include "reg.h"
   8#include "def.h"
   9#include "phy.h"
  10#include "rf.h"
  11#include "dm.h"
  12#include "table.h"
  13
  14static u32 _rtl88e_phy_rf_serial_read(struct ieee80211_hw *hw,
  15                                      enum radio_path rfpath, u32 offset);
  16static void _rtl88e_phy_rf_serial_write(struct ieee80211_hw *hw,
  17                                        enum radio_path rfpath, u32 offset,
  18                                        u32 data);
  19static u32 _rtl88e_phy_calculate_bit_shift(u32 bitmask)
  20{
  21        u32 i = ffs(bitmask);
  22
  23        return i ? i - 1 : 32;
  24}
  25static bool _rtl88e_phy_bb8188e_config_parafile(struct ieee80211_hw *hw);
  26static bool _rtl88e_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
  27static bool phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
  28                                          u8 configtype);
  29static bool phy_config_bb_with_pghdr(struct ieee80211_hw *hw,
  30                                     u8 configtype);
  31static void _rtl88e_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw);
  32static bool _rtl88e_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
  33                                             u32 cmdtableidx, u32 cmdtablesz,
  34                                             enum swchnlcmd_id cmdid, u32 para1,
  35                                             u32 para2, u32 msdelay);
  36static bool _rtl88e_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
  37                                             u8 channel, u8 *stage, u8 *step,
  38                                             u32 *delay);
  39
  40static long _rtl88e_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
  41                                         enum wireless_mode wirelessmode,
  42                                         u8 txpwridx);
  43static void rtl88ee_phy_set_rf_on(struct ieee80211_hw *hw);
  44static void rtl88e_phy_set_io(struct ieee80211_hw *hw);
  45
  46u32 rtl88e_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
  47{
  48        struct rtl_priv *rtlpriv = rtl_priv(hw);
  49        u32 returnvalue, originalvalue, bitshift;
  50
  51        rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
  52                "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask);
  53        originalvalue = rtl_read_dword(rtlpriv, regaddr);
  54        bitshift = _rtl88e_phy_calculate_bit_shift(bitmask);
  55        returnvalue = (originalvalue & bitmask) >> bitshift;
  56
  57        rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
  58                "BBR MASK=0x%x Addr[0x%x]=0x%x\n", bitmask,
  59                regaddr, originalvalue);
  60
  61        return returnvalue;
  62
  63}
  64
  65void rtl88e_phy_set_bb_reg(struct ieee80211_hw *hw,
  66                           u32 regaddr, u32 bitmask, u32 data)
  67{
  68        struct rtl_priv *rtlpriv = rtl_priv(hw);
  69        u32 originalvalue, bitshift;
  70
  71        rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
  72                "regaddr(%#x), bitmask(%#x), data(%#x)\n",
  73                regaddr, bitmask, data);
  74
  75        if (bitmask != MASKDWORD) {
  76                originalvalue = rtl_read_dword(rtlpriv, regaddr);
  77                bitshift = _rtl88e_phy_calculate_bit_shift(bitmask);
  78                data = ((originalvalue & (~bitmask)) | (data << bitshift));
  79        }
  80
  81        rtl_write_dword(rtlpriv, regaddr, data);
  82
  83        rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
  84                "regaddr(%#x), bitmask(%#x), data(%#x)\n",
  85                regaddr, bitmask, data);
  86}
  87
  88u32 rtl88e_phy_query_rf_reg(struct ieee80211_hw *hw,
  89                            enum radio_path rfpath, u32 regaddr, u32 bitmask)
  90{
  91        struct rtl_priv *rtlpriv = rtl_priv(hw);
  92        u32 original_value, readback_value, bitshift;
  93
  94        rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
  95                "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
  96                regaddr, rfpath, bitmask);
  97
  98        spin_lock(&rtlpriv->locks.rf_lock);
  99
 100
 101        original_value = _rtl88e_phy_rf_serial_read(hw, rfpath, regaddr);
 102        bitshift = _rtl88e_phy_calculate_bit_shift(bitmask);
 103        readback_value = (original_value & bitmask) >> bitshift;
 104
 105        spin_unlock(&rtlpriv->locks.rf_lock);
 106
 107        rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
 108                "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
 109                regaddr, rfpath, bitmask, original_value);
 110        return readback_value;
 111}
 112
 113void rtl88e_phy_set_rf_reg(struct ieee80211_hw *hw,
 114                           enum radio_path rfpath,
 115                           u32 regaddr, u32 bitmask, u32 data)
 116{
 117        struct rtl_priv *rtlpriv = rtl_priv(hw);
 118        u32 original_value, bitshift;
 119
 120        rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
 121                "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
 122                regaddr, bitmask, data, rfpath);
 123
 124        spin_lock(&rtlpriv->locks.rf_lock);
 125
 126        if (bitmask != RFREG_OFFSET_MASK) {
 127                        original_value = _rtl88e_phy_rf_serial_read(hw,
 128                                                                    rfpath,
 129                                                                    regaddr);
 130                        bitshift = _rtl88e_phy_calculate_bit_shift(bitmask);
 131                        data =
 132                            ((original_value & (~bitmask)) |
 133                             (data << bitshift));
 134                }
 135
 136        _rtl88e_phy_rf_serial_write(hw, rfpath, regaddr, data);
 137
 138
 139        spin_unlock(&rtlpriv->locks.rf_lock);
 140
 141        rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
 142                "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
 143                regaddr, bitmask, data, rfpath);
 144}
 145
 146static u32 _rtl88e_phy_rf_serial_read(struct ieee80211_hw *hw,
 147                                      enum radio_path rfpath, u32 offset)
 148{
 149        struct rtl_priv *rtlpriv = rtl_priv(hw);
 150        struct rtl_phy *rtlphy = &rtlpriv->phy;
 151        struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
 152        u32 newoffset;
 153        u32 tmplong, tmplong2;
 154        u8 rfpi_enable = 0;
 155        u32 retvalue;
 156
 157        offset &= 0xff;
 158        newoffset = offset;
 159        if (RT_CANNOT_IO(hw)) {
 160                pr_err("return all one\n");
 161                return 0xFFFFFFFF;
 162        }
 163        tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
 164        if (rfpath == RF90_PATH_A)
 165                tmplong2 = tmplong;
 166        else
 167                tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD);
 168        tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) |
 169            (newoffset << 23) | BLSSIREADEDGE;
 170        rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
 171                      tmplong & (~BLSSIREADEDGE));
 172        udelay(10);
 173        rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2);
 174        udelay(120);
 175        if (rfpath == RF90_PATH_A)
 176                rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
 177                                                BIT(8));
 178        else if (rfpath == RF90_PATH_B)
 179                rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1,
 180                                                BIT(8));
 181        if (rfpi_enable)
 182                retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi,
 183                                         BLSSIREADBACKDATA);
 184        else
 185                retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb,
 186                                         BLSSIREADBACKDATA);
 187        rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
 188                "RFR-%d Addr[0x%x]=0x%x\n",
 189                rfpath, pphyreg->rf_rb, retvalue);
 190        return retvalue;
 191}
 192
 193static void _rtl88e_phy_rf_serial_write(struct ieee80211_hw *hw,
 194                                        enum radio_path rfpath, u32 offset,
 195                                        u32 data)
 196{
 197        u32 data_and_addr;
 198        u32 newoffset;
 199        struct rtl_priv *rtlpriv = rtl_priv(hw);
 200        struct rtl_phy *rtlphy = &rtlpriv->phy;
 201        struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
 202
 203        if (RT_CANNOT_IO(hw)) {
 204                pr_err("stop\n");
 205                return;
 206        }
 207        offset &= 0xff;
 208        newoffset = offset;
 209        data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
 210        rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
 211        rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
 212                "RFW-%d Addr[0x%x]=0x%x\n",
 213                rfpath, pphyreg->rf3wire_offset, data_and_addr);
 214}
 215
 216bool rtl88e_phy_mac_config(struct ieee80211_hw *hw)
 217{
 218        struct rtl_priv *rtlpriv = rtl_priv(hw);
 219        bool rtstatus = _rtl88e_phy_config_mac_with_headerfile(hw);
 220
 221        rtl_write_byte(rtlpriv, 0x04CA, 0x0B);
 222        return rtstatus;
 223}
 224
 225bool rtl88e_phy_bb_config(struct ieee80211_hw *hw)
 226{
 227        bool rtstatus = true;
 228        struct rtl_priv *rtlpriv = rtl_priv(hw);
 229        u16 regval;
 230        u8 b_reg_hwparafile = 1;
 231        u32 tmp;
 232        _rtl88e_phy_init_bb_rf_register_definition(hw);
 233        regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
 234        rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
 235                       regval | BIT(13) | BIT(0) | BIT(1));
 236
 237        rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
 238        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
 239                       FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE |
 240                       FEN_BB_GLB_RSTN | FEN_BBRSTB);
 241        tmp = rtl_read_dword(rtlpriv, 0x4c);
 242        rtl_write_dword(rtlpriv, 0x4c, tmp | BIT(23));
 243        if (b_reg_hwparafile == 1)
 244                rtstatus = _rtl88e_phy_bb8188e_config_parafile(hw);
 245        return rtstatus;
 246}
 247
 248bool rtl88e_phy_rf_config(struct ieee80211_hw *hw)
 249{
 250        return rtl88e_phy_rf6052_config(hw);
 251}
 252
 253static bool _rtl88e_check_condition(struct ieee80211_hw *hw,
 254                                    const u32  condition)
 255{
 256        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 257        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 258        u32 _board = rtlefuse->board_type; /*need efuse define*/
 259        u32 _interface = rtlhal->interface;
 260        u32 _platform = 0x08;/*SupportPlatform */
 261        u32 cond;
 262
 263        if (condition == 0xCDCDCDCD)
 264                return true;
 265
 266        cond = condition & 0xFF;
 267        if ((_board & cond) == 0 && cond != 0x1F)
 268                return false;
 269
 270        cond = condition & 0xFF00;
 271        cond = cond >> 8;
 272        if ((_interface & cond) == 0 && cond != 0x07)
 273                return false;
 274
 275        cond = condition & 0xFF0000;
 276        cond = cond >> 16;
 277        if ((_platform & cond) == 0 && cond != 0x0F)
 278                return false;
 279        return true;
 280}
 281
 282static void _rtl8188e_config_rf_reg(struct ieee80211_hw *hw, u32 addr,
 283                                    u32 data, enum radio_path rfpath,
 284                                    u32 regaddr)
 285{
 286        if (addr == 0xffe) {
 287                mdelay(50);
 288        } else if (addr == 0xfd) {
 289                mdelay(5);
 290        } else if (addr == 0xfc) {
 291                mdelay(1);
 292        } else if (addr == 0xfb) {
 293                udelay(50);
 294        } else if (addr == 0xfa) {
 295                udelay(5);
 296        } else if (addr == 0xf9) {
 297                udelay(1);
 298        } else {
 299                rtl_set_rfreg(hw, rfpath, regaddr,
 300                              RFREG_OFFSET_MASK,
 301                              data);
 302                udelay(1);
 303        }
 304}
 305
 306static void _rtl8188e_config_rf_radio_a(struct ieee80211_hw *hw,
 307                                        u32 addr, u32 data)
 308{
 309        u32 content = 0x1000; /*RF Content: radio_a_txt*/
 310        u32 maskforphyset = (u32)(content & 0xE000);
 311
 312        _rtl8188e_config_rf_reg(hw, addr, data, RF90_PATH_A,
 313                addr | maskforphyset);
 314}
 315
 316static void _rtl8188e_config_bb_reg(struct ieee80211_hw *hw,
 317                                    u32 addr, u32 data)
 318{
 319        if (addr == 0xfe) {
 320                mdelay(50);
 321        } else if (addr == 0xfd) {
 322                mdelay(5);
 323        } else if (addr == 0xfc) {
 324                mdelay(1);
 325        } else if (addr == 0xfb) {
 326                udelay(50);
 327        } else if (addr == 0xfa) {
 328                udelay(5);
 329        } else if (addr == 0xf9) {
 330                udelay(1);
 331        } else {
 332                rtl_set_bbreg(hw, addr, MASKDWORD, data);
 333                udelay(1);
 334        }
 335}
 336
 337static bool _rtl88e_phy_bb8188e_config_parafile(struct ieee80211_hw *hw)
 338{
 339        struct rtl_priv *rtlpriv = rtl_priv(hw);
 340        struct rtl_phy *rtlphy = &rtlpriv->phy;
 341        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 342        bool rtstatus;
 343
 344        rtstatus = phy_config_bb_with_headerfile(hw, BASEBAND_CONFIG_PHY_REG);
 345        if (!rtstatus) {
 346                pr_err("Write BB Reg Fail!!\n");
 347                return false;
 348        }
 349
 350        if (!rtlefuse->autoload_failflag) {
 351                rtlphy->pwrgroup_cnt = 0;
 352                rtstatus =
 353                  phy_config_bb_with_pghdr(hw, BASEBAND_CONFIG_PHY_REG);
 354        }
 355        if (!rtstatus) {
 356                pr_err("BB_PG Reg Fail!!\n");
 357                return false;
 358        }
 359        rtstatus =
 360          phy_config_bb_with_headerfile(hw, BASEBAND_CONFIG_AGC_TAB);
 361        if (!rtstatus) {
 362                pr_err("AGC Table Fail\n");
 363                return false;
 364        }
 365        rtlphy->cck_high_power =
 366          (bool)(rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, 0x200));
 367
 368        return true;
 369}
 370
 371static bool _rtl88e_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
 372{
 373        struct rtl_priv *rtlpriv = rtl_priv(hw);
 374        u32 i;
 375        u32 arraylength;
 376        u32 *ptrarray;
 377
 378        rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl8188EMACPHY_Array\n");
 379        arraylength = RTL8188EEMAC_1T_ARRAYLEN;
 380        ptrarray = RTL8188EEMAC_1T_ARRAY;
 381        rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
 382                "Img:RTL8188EEMAC_1T_ARRAY LEN %d\n", arraylength);
 383        for (i = 0; i < arraylength; i = i + 2)
 384                rtl_write_byte(rtlpriv, ptrarray[i], (u8)ptrarray[i + 1]);
 385        return true;
 386}
 387
 388#define READ_NEXT_PAIR(v1, v2, i)                       \
 389        do {                                            \
 390                i += 2; v1 = array_table[i];            \
 391                v2 = array_table[i+1];                  \
 392        } while (0)
 393
 394static void handle_branch1(struct ieee80211_hw *hw, u16 arraylen,
 395                           u32 *array_table)
 396{
 397        u32 v1;
 398        u32 v2;
 399        int i;
 400
 401        for (i = 0; i < arraylen; i = i + 2) {
 402                v1 = array_table[i];
 403                v2 = array_table[i+1];
 404                if (v1 < 0xcdcdcdcd) {
 405                        _rtl8188e_config_bb_reg(hw, v1, v2);
 406                } else { /*This line is the start line of branch.*/
 407                        /* to protect READ_NEXT_PAIR not overrun */
 408                        if (i >= arraylen - 2)
 409                                break;
 410
 411                        if (!_rtl88e_check_condition(hw, array_table[i])) {
 412                                /*Discard the following (offset, data) pairs*/
 413                                READ_NEXT_PAIR(v1, v2, i);
 414                                while (v2 != 0xDEAD &&
 415                                       v2 != 0xCDEF &&
 416                                       v2 != 0xCDCD && i < arraylen - 2)
 417                                        READ_NEXT_PAIR(v1, v2, i);
 418                                i -= 2; /* prevent from for-loop += 2*/
 419                        } else { /* Configure matched pairs and skip
 420                                  * to end of if-else.
 421                                  */
 422                                READ_NEXT_PAIR(v1, v2, i);
 423                                while (v2 != 0xDEAD &&
 424                                       v2 != 0xCDEF &&
 425                                       v2 != 0xCDCD && i < arraylen - 2) {
 426                                        _rtl8188e_config_bb_reg(hw, v1, v2);
 427                                        READ_NEXT_PAIR(v1, v2, i);
 428                                }
 429
 430                                while (v2 != 0xDEAD && i < arraylen - 2)
 431                                        READ_NEXT_PAIR(v1, v2, i);
 432                        }
 433                }
 434        }
 435}
 436
 437static void handle_branch2(struct ieee80211_hw *hw, u16 arraylen,
 438                           u32 *array_table)
 439{
 440        struct rtl_priv *rtlpriv = rtl_priv(hw);
 441        u32 v1;
 442        u32 v2;
 443        int i;
 444
 445        for (i = 0; i < arraylen; i = i + 2) {
 446                v1 = array_table[i];
 447                v2 = array_table[i+1];
 448                if (v1 < 0xCDCDCDCD) {
 449                        rtl_set_bbreg(hw, array_table[i], MASKDWORD,
 450                                      array_table[i + 1]);
 451                        udelay(1);
 452                        continue;
 453                } else { /*This line is the start line of branch.*/
 454                        /* to protect READ_NEXT_PAIR not overrun */
 455                        if (i >= arraylen - 2)
 456                                break;
 457
 458                        if (!_rtl88e_check_condition(hw, array_table[i])) {
 459                                /*Discard the following (offset, data) pairs*/
 460                                READ_NEXT_PAIR(v1, v2, i);
 461                                while (v2 != 0xDEAD &&
 462                                       v2 != 0xCDEF &&
 463                                       v2 != 0xCDCD && i < arraylen - 2)
 464                                        READ_NEXT_PAIR(v1, v2, i);
 465                                i -= 2; /* prevent from for-loop += 2*/
 466                        } else { /* Configure matched pairs and skip
 467                                  * to end of if-else.
 468                                  */
 469                                READ_NEXT_PAIR(v1, v2, i);
 470                                while (v2 != 0xDEAD &&
 471                                       v2 != 0xCDEF &&
 472                                       v2 != 0xCDCD && i < arraylen - 2) {
 473                                        rtl_set_bbreg(hw, array_table[i],
 474                                                      MASKDWORD,
 475                                                      array_table[i + 1]);
 476                                        udelay(1);
 477                                        READ_NEXT_PAIR(v1, v2, i);
 478                                }
 479
 480                                while (v2 != 0xDEAD && i < arraylen - 2)
 481                                        READ_NEXT_PAIR(v1, v2, i);
 482                        }
 483                }
 484                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 485                        "The agctab_array_table[0] is %x Rtl818EEPHY_REGArray[1] is %x\n",
 486                        array_table[i], array_table[i + 1]);
 487        }
 488}
 489
 490static bool phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
 491                                          u8 configtype)
 492{
 493        u32 *array_table;
 494        u16 arraylen;
 495
 496        if (configtype == BASEBAND_CONFIG_PHY_REG) {
 497                arraylen = RTL8188EEPHY_REG_1TARRAYLEN;
 498                array_table = RTL8188EEPHY_REG_1TARRAY;
 499                handle_branch1(hw, arraylen, array_table);
 500        } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
 501                arraylen = RTL8188EEAGCTAB_1TARRAYLEN;
 502                array_table = RTL8188EEAGCTAB_1TARRAY;
 503                handle_branch2(hw, arraylen, array_table);
 504        }
 505        return true;
 506}
 507
 508static void store_pwrindex_rate_offset(struct ieee80211_hw *hw,
 509                                       u32 regaddr, u32 bitmask,
 510                                       u32 data)
 511{
 512        struct rtl_priv *rtlpriv = rtl_priv(hw);
 513        struct rtl_phy *rtlphy = &rtlpriv->phy;
 514        int count = rtlphy->pwrgroup_cnt;
 515
 516        if (regaddr == RTXAGC_A_RATE18_06) {
 517                rtlphy->mcs_txpwrlevel_origoffset[count][0] = data;
 518                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 519                        "MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n",
 520                        count,
 521                        rtlphy->mcs_txpwrlevel_origoffset[count][0]);
 522        }
 523        if (regaddr == RTXAGC_A_RATE54_24) {
 524                rtlphy->mcs_txpwrlevel_origoffset[count][1] = data;
 525                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 526                        "MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n",
 527                        count,
 528                        rtlphy->mcs_txpwrlevel_origoffset[count][1]);
 529        }
 530        if (regaddr == RTXAGC_A_CCK1_MCS32) {
 531                rtlphy->mcs_txpwrlevel_origoffset[count][6] = data;
 532                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 533                        "MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n",
 534                        count,
 535                        rtlphy->mcs_txpwrlevel_origoffset[count][6]);
 536        }
 537        if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) {
 538                rtlphy->mcs_txpwrlevel_origoffset[count][7] = data;
 539                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 540                        "MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n",
 541                        count,
 542                        rtlphy->mcs_txpwrlevel_origoffset[count][7]);
 543        }
 544        if (regaddr == RTXAGC_A_MCS03_MCS00) {
 545                rtlphy->mcs_txpwrlevel_origoffset[count][2] = data;
 546                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 547                        "MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n",
 548                        count,
 549                        rtlphy->mcs_txpwrlevel_origoffset[count][2]);
 550        }
 551        if (regaddr == RTXAGC_A_MCS07_MCS04) {
 552                rtlphy->mcs_txpwrlevel_origoffset[count][3] = data;
 553                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 554                        "MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n",
 555                        count,
 556                        rtlphy->mcs_txpwrlevel_origoffset[count][3]);
 557        }
 558        if (regaddr == RTXAGC_A_MCS11_MCS08) {
 559                rtlphy->mcs_txpwrlevel_origoffset[count][4] = data;
 560                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 561                        "MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n",
 562                        count,
 563                        rtlphy->mcs_txpwrlevel_origoffset[count][4]);
 564        }
 565        if (regaddr == RTXAGC_A_MCS15_MCS12) {
 566                rtlphy->mcs_txpwrlevel_origoffset[count][5] = data;
 567                if (get_rf_type(rtlphy) == RF_1T1R) {
 568                        count++;
 569                        rtlphy->pwrgroup_cnt = count;
 570                }
 571                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 572                        "MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n",
 573                        count,
 574                        rtlphy->mcs_txpwrlevel_origoffset[count][5]);
 575        }
 576        if (regaddr == RTXAGC_B_RATE18_06) {
 577                rtlphy->mcs_txpwrlevel_origoffset[count][8] = data;
 578                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 579                        "MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n",
 580                        count,
 581                        rtlphy->mcs_txpwrlevel_origoffset[count][8]);
 582        }
 583        if (regaddr == RTXAGC_B_RATE54_24) {
 584                rtlphy->mcs_txpwrlevel_origoffset[count][9] = data;
 585                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 586                        "MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n",
 587                        count,
 588                        rtlphy->mcs_txpwrlevel_origoffset[count][9]);
 589        }
 590        if (regaddr == RTXAGC_B_CCK1_55_MCS32) {
 591                rtlphy->mcs_txpwrlevel_origoffset[count][14] = data;
 592                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 593                        "MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n",
 594                        count,
 595                        rtlphy->mcs_txpwrlevel_origoffset[count][14]);
 596        }
 597        if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) {
 598                rtlphy->mcs_txpwrlevel_origoffset[count][15] = data;
 599                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 600                        "MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n",
 601                        count,
 602                        rtlphy->mcs_txpwrlevel_origoffset[count][15]);
 603        }
 604        if (regaddr == RTXAGC_B_MCS03_MCS00) {
 605                rtlphy->mcs_txpwrlevel_origoffset[count][10] = data;
 606                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 607                        "MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n",
 608                        count,
 609                        rtlphy->mcs_txpwrlevel_origoffset[count][10]);
 610        }
 611        if (regaddr == RTXAGC_B_MCS07_MCS04) {
 612                rtlphy->mcs_txpwrlevel_origoffset[count][11] = data;
 613                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 614                        "MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n",
 615                        count,
 616                        rtlphy->mcs_txpwrlevel_origoffset[count][11]);
 617        }
 618        if (regaddr == RTXAGC_B_MCS11_MCS08) {
 619                rtlphy->mcs_txpwrlevel_origoffset[count][12] = data;
 620                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 621                        "MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n",
 622                        count,
 623                        rtlphy->mcs_txpwrlevel_origoffset[count][12]);
 624        }
 625        if (regaddr == RTXAGC_B_MCS15_MCS12) {
 626                rtlphy->mcs_txpwrlevel_origoffset[count][13] = data;
 627                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 628                        "MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n",
 629                        count,
 630                        rtlphy->mcs_txpwrlevel_origoffset[count][13]);
 631                if (get_rf_type(rtlphy) != RF_1T1R) {
 632                        count++;
 633                        rtlphy->pwrgroup_cnt = count;
 634                }
 635        }
 636}
 637
 638static bool phy_config_bb_with_pghdr(struct ieee80211_hw *hw, u8 configtype)
 639{
 640        struct rtl_priv *rtlpriv = rtl_priv(hw);
 641        int i;
 642        u32 *phy_reg_page;
 643        u16 phy_reg_page_len;
 644        u32 v1 = 0, v2 = 0;
 645
 646        phy_reg_page_len = RTL8188EEPHY_REG_ARRAY_PGLEN;
 647        phy_reg_page = RTL8188EEPHY_REG_ARRAY_PG;
 648
 649        if (configtype == BASEBAND_CONFIG_PHY_REG) {
 650                for (i = 0; i < phy_reg_page_len; i = i + 3) {
 651                        v1 = phy_reg_page[i];
 652                        v2 = phy_reg_page[i+1];
 653
 654                        if (v1 < 0xcdcdcdcd) {
 655                                if (phy_reg_page[i] == 0xfe)
 656                                        mdelay(50);
 657                                else if (phy_reg_page[i] == 0xfd)
 658                                        mdelay(5);
 659                                else if (phy_reg_page[i] == 0xfc)
 660                                        mdelay(1);
 661                                else if (phy_reg_page[i] == 0xfb)
 662                                        udelay(50);
 663                                else if (phy_reg_page[i] == 0xfa)
 664                                        udelay(5);
 665                                else if (phy_reg_page[i] == 0xf9)
 666                                        udelay(1);
 667
 668                                store_pwrindex_rate_offset(hw, phy_reg_page[i],
 669                                                           phy_reg_page[i + 1],
 670                                                           phy_reg_page[i + 2]);
 671                                continue;
 672                        } else {
 673                                if (!_rtl88e_check_condition(hw,
 674                                                             phy_reg_page[i])) {
 675                                        /*don't need the hw_body*/
 676                                    i += 2; /* skip the pair of expression*/
 677                                    /* to protect 'i+1' 'i+2' not overrun */
 678                                    if (i >= phy_reg_page_len - 2)
 679                                        break;
 680
 681                                    v1 = phy_reg_page[i];
 682                                    v2 = phy_reg_page[i+1];
 683                                    while (v2 != 0xDEAD &&
 684                                           i < phy_reg_page_len - 5) {
 685                                        i += 3;
 686                                        v1 = phy_reg_page[i];
 687                                        v2 = phy_reg_page[i+1];
 688                                    }
 689                                }
 690                        }
 691                }
 692        } else {
 693                rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE,
 694                        "configtype != BaseBand_Config_PHY_REG\n");
 695        }
 696        return true;
 697}
 698
 699#define READ_NEXT_RF_PAIR(v1, v2, i) \
 700do { \
 701        i += 2; \
 702        v1 = radioa_array_table[i]; \
 703        v2 = radioa_array_table[i+1]; \
 704} while (0)
 705
 706static void process_path_a(struct ieee80211_hw *hw,
 707                           u16  radioa_arraylen,
 708                           u32 *radioa_array_table)
 709{
 710        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 711        u32 v1, v2;
 712        int i;
 713
 714        for (i = 0; i < radioa_arraylen; i = i + 2) {
 715                v1 = radioa_array_table[i];
 716                v2 = radioa_array_table[i+1];
 717                if (v1 < 0xcdcdcdcd) {
 718                        _rtl8188e_config_rf_radio_a(hw, v1, v2);
 719                } else { /*This line is the start line of branch.*/
 720                        /* to protect READ_NEXT_PAIR not overrun */
 721                        if (i >= radioa_arraylen - 2)
 722                                break;
 723
 724                        if (!_rtl88e_check_condition(hw, radioa_array_table[i])) {
 725                                /*Discard the following (offset, data) pairs*/
 726                                READ_NEXT_RF_PAIR(v1, v2, i);
 727                                while (v2 != 0xDEAD &&
 728                                       v2 != 0xCDEF &&
 729                                       v2 != 0xCDCD &&
 730                                       i < radioa_arraylen - 2) {
 731                                        READ_NEXT_RF_PAIR(v1, v2, i);
 732                                }
 733                                i -= 2; /* prevent from for-loop += 2*/
 734                        } else { /* Configure matched pairs and
 735                                  * skip to end of if-else.
 736                                  */
 737                                READ_NEXT_RF_PAIR(v1, v2, i);
 738                                while (v2 != 0xDEAD &&
 739                                       v2 != 0xCDEF &&
 740                                       v2 != 0xCDCD &&
 741                                       i < radioa_arraylen - 2) {
 742                                        _rtl8188e_config_rf_radio_a(hw, v1, v2);
 743                                        READ_NEXT_RF_PAIR(v1, v2, i);
 744                                }
 745
 746                                while (v2 != 0xDEAD &&
 747                                       i < radioa_arraylen - 2)
 748                                        READ_NEXT_RF_PAIR(v1, v2, i);
 749                        }
 750                }
 751        }
 752
 753        if (rtlhal->oem_id == RT_CID_819X_HP)
 754                _rtl8188e_config_rf_radio_a(hw, 0x52, 0x7E4BD);
 755}
 756
 757bool rtl88e_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
 758                                          enum radio_path rfpath)
 759{
 760        struct rtl_priv *rtlpriv = rtl_priv(hw);
 761        u32 *radioa_array_table;
 762        u16 radioa_arraylen;
 763
 764        radioa_arraylen = RTL8188EE_RADIOA_1TARRAYLEN;
 765        radioa_array_table = RTL8188EE_RADIOA_1TARRAY;
 766        rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
 767                "Radio_A:RTL8188EE_RADIOA_1TARRAY %d\n", radioa_arraylen);
 768        rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
 769        switch (rfpath) {
 770        case RF90_PATH_A:
 771                process_path_a(hw, radioa_arraylen, radioa_array_table);
 772                break;
 773        case RF90_PATH_B:
 774        case RF90_PATH_C:
 775        case RF90_PATH_D:
 776                break;
 777        }
 778        return true;
 779}
 780
 781void rtl88e_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
 782{
 783        struct rtl_priv *rtlpriv = rtl_priv(hw);
 784        struct rtl_phy *rtlphy = &rtlpriv->phy;
 785
 786        rtlphy->default_initialgain[0] =
 787            (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
 788        rtlphy->default_initialgain[1] =
 789            (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
 790        rtlphy->default_initialgain[2] =
 791            (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
 792        rtlphy->default_initialgain[3] =
 793            (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
 794
 795        rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 796                "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
 797                rtlphy->default_initialgain[0],
 798                rtlphy->default_initialgain[1],
 799                rtlphy->default_initialgain[2],
 800                rtlphy->default_initialgain[3]);
 801
 802        rtlphy->framesync = (u8)rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3,
 803                                              MASKBYTE0);
 804        rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
 805                                              MASKDWORD);
 806
 807        rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 808                "Default framesync (0x%x) = 0x%x\n",
 809                ROFDM0_RXDETECTOR3, rtlphy->framesync);
 810}
 811
 812static void _rtl88e_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
 813{
 814        struct rtl_priv *rtlpriv = rtl_priv(hw);
 815        struct rtl_phy *rtlphy = &rtlpriv->phy;
 816
 817        rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
 818        rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
 819        rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW;
 820        rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW;
 821
 822        rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB;
 823        rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB;
 824        rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB;
 825        rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB;
 826
 827        rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
 828        rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
 829
 830        rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
 831        rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
 832
 833        rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset =
 834            RFPGA0_XA_LSSIPARAMETER;
 835        rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset =
 836            RFPGA0_XB_LSSIPARAMETER;
 837
 838        rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = RFPGA0_XAB_RFPARAMETER;
 839        rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = RFPGA0_XAB_RFPARAMETER;
 840        rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = RFPGA0_XCD_RFPARAMETER;
 841        rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = RFPGA0_XCD_RFPARAMETER;
 842
 843        rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE;
 844        rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE;
 845        rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE;
 846        rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE;
 847
 848        rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1;
 849        rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1;
 850
 851        rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
 852        rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
 853
 854        rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl =
 855            RFPGA0_XAB_SWITCHCONTROL;
 856        rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl =
 857            RFPGA0_XAB_SWITCHCONTROL;
 858        rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl =
 859            RFPGA0_XCD_SWITCHCONTROL;
 860        rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl =
 861            RFPGA0_XCD_SWITCHCONTROL;
 862
 863        rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1;
 864        rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1;
 865        rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1;
 866        rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1;
 867
 868        rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2;
 869        rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2;
 870        rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2;
 871        rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2;
 872
 873        rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE;
 874        rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE;
 875        rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBANLANCE;
 876        rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE;
 877
 878        rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE;
 879        rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE;
 880        rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE;
 881        rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE;
 882
 883        rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE;
 884        rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE;
 885        rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE;
 886        rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE;
 887
 888        rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE;
 889        rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE;
 890
 891        rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK;
 892        rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK;
 893
 894        rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVEA_HSPI_READBACK;
 895        rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVEB_HSPI_READBACK;
 896}
 897
 898void rtl88e_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
 899{
 900        struct rtl_priv *rtlpriv = rtl_priv(hw);
 901        struct rtl_phy *rtlphy = &rtlpriv->phy;
 902        u8 txpwr_level;
 903        long txpwr_dbm;
 904
 905        txpwr_level = rtlphy->cur_cck_txpwridx;
 906        txpwr_dbm = _rtl88e_phy_txpwr_idx_to_dbm(hw,
 907                                                 WIRELESS_MODE_B, txpwr_level);
 908        txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
 909        if (_rtl88e_phy_txpwr_idx_to_dbm(hw,
 910                                         WIRELESS_MODE_G,
 911                                         txpwr_level) > txpwr_dbm)
 912                txpwr_dbm =
 913                    _rtl88e_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
 914                                                 txpwr_level);
 915        txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
 916        if (_rtl88e_phy_txpwr_idx_to_dbm(hw,
 917                                         WIRELESS_MODE_N_24G,
 918                                         txpwr_level) > txpwr_dbm)
 919                txpwr_dbm =
 920                    _rtl88e_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
 921                                                 txpwr_level);
 922        *powerlevel = txpwr_dbm;
 923}
 924
 925static void handle_path_a(struct rtl_efuse *rtlefuse, u8 index,
 926                          u8 *cckpowerlevel, u8 *ofdmpowerlevel,
 927                          u8 *bw20powerlevel, u8 *bw40powerlevel)
 928{
 929        cckpowerlevel[RF90_PATH_A] =
 930            rtlefuse->txpwrlevel_cck[RF90_PATH_A][index];
 931                /*-8~7 */
 932        if (rtlefuse->txpwr_ht20diff[RF90_PATH_A][index] > 0x0f)
 933                bw20powerlevel[RF90_PATH_A] =
 934                  rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index] -
 935                  (~(rtlefuse->txpwr_ht20diff[RF90_PATH_A][index]) + 1);
 936        else
 937                bw20powerlevel[RF90_PATH_A] =
 938                  rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index] +
 939                  rtlefuse->txpwr_ht20diff[RF90_PATH_A][index];
 940        if (rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][index] > 0xf)
 941                ofdmpowerlevel[RF90_PATH_A] =
 942                  rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index] -
 943                  (~(rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][index])+1);
 944        else
 945                ofdmpowerlevel[RF90_PATH_A] =
 946                rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index] +
 947                  rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][index];
 948        bw40powerlevel[RF90_PATH_A] =
 949          rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index];
 950}
 951
 952static void _rtl88e_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
 953                                      u8 *cckpowerlevel, u8 *ofdmpowerlevel,
 954                                      u8 *bw20powerlevel, u8 *bw40powerlevel)
 955{
 956        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 957        u8 index = (channel - 1);
 958        u8 rf_path = 0;
 959
 960        for (rf_path = 0; rf_path < 2; rf_path++) {
 961                if (rf_path == RF90_PATH_A) {
 962                        handle_path_a(rtlefuse, index, cckpowerlevel,
 963                                      ofdmpowerlevel, bw20powerlevel,
 964                                      bw40powerlevel);
 965                } else if (rf_path == RF90_PATH_B) {
 966                        cckpowerlevel[RF90_PATH_B] =
 967                          rtlefuse->txpwrlevel_cck[RF90_PATH_B][index];
 968                        bw20powerlevel[RF90_PATH_B] =
 969                          rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index] +
 970                          rtlefuse->txpwr_ht20diff[RF90_PATH_B][index];
 971                        ofdmpowerlevel[RF90_PATH_B] =
 972                          rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index] +
 973                          rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][index];
 974                        bw40powerlevel[RF90_PATH_B] =
 975                          rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index];
 976                }
 977        }
 978
 979}
 980
 981static void _rtl88e_ccxpower_index_check(struct ieee80211_hw *hw,
 982                                         u8 channel, u8 *cckpowerlevel,
 983                                         u8 *ofdmpowerlevel, u8 *bw20powerlevel,
 984                                         u8 *bw40powerlevel)
 985{
 986        struct rtl_priv *rtlpriv = rtl_priv(hw);
 987        struct rtl_phy *rtlphy = &rtlpriv->phy;
 988
 989        rtlphy->cur_cck_txpwridx = cckpowerlevel[0];
 990        rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0];
 991        rtlphy->cur_bw20_txpwridx = bw20powerlevel[0];
 992        rtlphy->cur_bw40_txpwridx = bw40powerlevel[0];
 993
 994}
 995
 996void rtl88e_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
 997{
 998        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 999        u8 cckpowerlevel[MAX_TX_COUNT]  = {0};
1000        u8 ofdmpowerlevel[MAX_TX_COUNT] = {0};
1001        u8 bw20powerlevel[MAX_TX_COUNT] = {0};
1002        u8 bw40powerlevel[MAX_TX_COUNT] = {0};
1003
1004        if (!rtlefuse->txpwr_fromeprom)
1005                return;
1006        _rtl88e_get_txpower_index(hw, channel,
1007                                  &cckpowerlevel[0], &ofdmpowerlevel[0],
1008                                  &bw20powerlevel[0], &bw40powerlevel[0]);
1009        _rtl88e_ccxpower_index_check(hw, channel,
1010                                     &cckpowerlevel[0], &ofdmpowerlevel[0],
1011                                     &bw20powerlevel[0], &bw40powerlevel[0]);
1012        rtl88e_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]);
1013        rtl88e_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0],
1014                                           &bw20powerlevel[0],
1015                                           &bw40powerlevel[0], channel);
1016}
1017
1018static long _rtl88e_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
1019                                         enum wireless_mode wirelessmode,
1020                                         u8 txpwridx)
1021{
1022        long offset;
1023        long pwrout_dbm;
1024
1025        switch (wirelessmode) {
1026        case WIRELESS_MODE_B:
1027                offset = -7;
1028                break;
1029        case WIRELESS_MODE_G:
1030        case WIRELESS_MODE_N_24G:
1031                offset = -8;
1032                break;
1033        default:
1034                offset = -8;
1035                break;
1036        }
1037        pwrout_dbm = txpwridx / 2 + offset;
1038        return pwrout_dbm;
1039}
1040
1041void rtl88e_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
1042{
1043        struct rtl_priv *rtlpriv = rtl_priv(hw);
1044        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1045        enum io_type iotype;
1046
1047        if (!is_hal_stop(rtlhal)) {
1048                switch (operation) {
1049                case SCAN_OPT_BACKUP_BAND0:
1050                        iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
1051                        rtlpriv->cfg->ops->set_hw_reg(hw,
1052                                                      HW_VAR_IO_CMD,
1053                                                      (u8 *)&iotype);
1054
1055                        break;
1056                case SCAN_OPT_RESTORE:
1057                        iotype = IO_CMD_RESUME_DM_BY_SCAN;
1058                        rtlpriv->cfg->ops->set_hw_reg(hw,
1059                                                      HW_VAR_IO_CMD,
1060                                                      (u8 *)&iotype);
1061                        break;
1062                default:
1063                        pr_err("Unknown Scan Backup operation.\n");
1064                        break;
1065                }
1066        }
1067}
1068
1069void rtl88e_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
1070{
1071        struct rtl_priv *rtlpriv = rtl_priv(hw);
1072        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1073        struct rtl_phy *rtlphy = &rtlpriv->phy;
1074        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1075        u8 reg_bw_opmode;
1076        u8 reg_prsr_rsc;
1077
1078        rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE,
1079                "Switch to %s bandwidth\n",
1080                rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
1081                "20MHz" : "40MHz");
1082
1083        if (is_hal_stop(rtlhal)) {
1084                rtlphy->set_bwmode_inprogress = false;
1085                return;
1086        }
1087
1088        reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
1089        reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
1090
1091        switch (rtlphy->current_chan_bw) {
1092        case HT_CHANNEL_WIDTH_20:
1093                reg_bw_opmode |= BW_OPMODE_20MHZ;
1094                rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1095                break;
1096        case HT_CHANNEL_WIDTH_20_40:
1097                reg_bw_opmode &= ~BW_OPMODE_20MHZ;
1098                rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1099                reg_prsr_rsc =
1100                    (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5);
1101                rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
1102                break;
1103        default:
1104                pr_err("unknown bandwidth: %#X\n",
1105                       rtlphy->current_chan_bw);
1106                break;
1107        }
1108
1109        switch (rtlphy->current_chan_bw) {
1110        case HT_CHANNEL_WIDTH_20:
1111                rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
1112                rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
1113        /*      rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);*/
1114                break;
1115        case HT_CHANNEL_WIDTH_20_40:
1116                rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
1117                rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
1118
1119                rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
1120                              (mac->cur_40_prime_sc >> 1));
1121                rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
1122                /*rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);*/
1123
1124                rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
1125                              (mac->cur_40_prime_sc ==
1126                               HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
1127                break;
1128        default:
1129                pr_err("unknown bandwidth: %#X\n",
1130                       rtlphy->current_chan_bw);
1131                break;
1132        }
1133        rtl88e_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
1134        rtlphy->set_bwmode_inprogress = false;
1135        rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
1136}
1137
1138void rtl88e_phy_set_bw_mode(struct ieee80211_hw *hw,
1139                            enum nl80211_channel_type ch_type)
1140{
1141        struct rtl_priv *rtlpriv = rtl_priv(hw);
1142        struct rtl_phy *rtlphy = &rtlpriv->phy;
1143        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1144        u8 tmp_bw = rtlphy->current_chan_bw;
1145
1146        if (rtlphy->set_bwmode_inprogress)
1147                return;
1148        rtlphy->set_bwmode_inprogress = true;
1149        if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1150                rtl88e_phy_set_bw_mode_callback(hw);
1151        } else {
1152                rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
1153                        "false driver sleep or unload\n");
1154                rtlphy->set_bwmode_inprogress = false;
1155                rtlphy->current_chan_bw = tmp_bw;
1156        }
1157}
1158
1159void rtl88e_phy_sw_chnl_callback(struct ieee80211_hw *hw)
1160{
1161        struct rtl_priv *rtlpriv = rtl_priv(hw);
1162        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1163        struct rtl_phy *rtlphy = &rtlpriv->phy;
1164        u32 delay;
1165
1166        rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE,
1167                "switch to channel%d\n", rtlphy->current_channel);
1168        if (is_hal_stop(rtlhal))
1169                return;
1170        do {
1171                if (!rtlphy->sw_chnl_inprogress)
1172                        break;
1173                if (!_rtl88e_phy_sw_chnl_step_by_step
1174                    (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage,
1175                     &rtlphy->sw_chnl_step, &delay)) {
1176                        if (delay > 0)
1177                                mdelay(delay);
1178                        else
1179                                continue;
1180                } else {
1181                        rtlphy->sw_chnl_inprogress = false;
1182                }
1183                break;
1184        } while (true);
1185        rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
1186}
1187
1188u8 rtl88e_phy_sw_chnl(struct ieee80211_hw *hw)
1189{
1190        struct rtl_priv *rtlpriv = rtl_priv(hw);
1191        struct rtl_phy *rtlphy = &rtlpriv->phy;
1192        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1193
1194        if (rtlphy->sw_chnl_inprogress)
1195                return 0;
1196        if (rtlphy->set_bwmode_inprogress)
1197                return 0;
1198        WARN_ONCE((rtlphy->current_channel > 14),
1199                  "rtl8188ee: WIRELESS_MODE_G but channel>14");
1200        rtlphy->sw_chnl_inprogress = true;
1201        rtlphy->sw_chnl_stage = 0;
1202        rtlphy->sw_chnl_step = 0;
1203        if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1204                rtl88e_phy_sw_chnl_callback(hw);
1205                rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD,
1206                        "sw_chnl_inprogress false schedule workitem current channel %d\n",
1207                        rtlphy->current_channel);
1208                rtlphy->sw_chnl_inprogress = false;
1209        } else {
1210                rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD,
1211                        "sw_chnl_inprogress false driver sleep or unload\n");
1212                rtlphy->sw_chnl_inprogress = false;
1213        }
1214        return 1;
1215}
1216
1217static bool _rtl88e_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
1218                                             u8 channel, u8 *stage, u8 *step,
1219                                             u32 *delay)
1220{
1221        struct rtl_priv *rtlpriv = rtl_priv(hw);
1222        struct rtl_phy *rtlphy = &rtlpriv->phy;
1223        struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
1224        u32 precommoncmdcnt;
1225        struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
1226        u32 postcommoncmdcnt;
1227        struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
1228        u32 rfdependcmdcnt;
1229        struct swchnlcmd *currentcmd = NULL;
1230        u8 rfpath;
1231        u8 num_total_rfpath = rtlphy->num_total_rfpath;
1232
1233        precommoncmdcnt = 0;
1234        _rtl88e_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1235                                         MAX_PRECMD_CNT,
1236                                         CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0);
1237        _rtl88e_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1238                                         MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
1239
1240        postcommoncmdcnt = 0;
1241
1242        _rtl88e_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
1243                                         MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
1244
1245        rfdependcmdcnt = 0;
1246
1247        WARN_ONCE((channel < 1 || channel > 14),
1248                  "rtl8188ee: illegal channel for Zebra: %d\n", channel);
1249
1250        _rtl88e_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1251                                         MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
1252                                         RF_CHNLBW, channel, 10);
1253
1254        _rtl88e_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1255                                         MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0,
1256                                         0);
1257
1258        do {
1259                switch (*stage) {
1260                case 0:
1261                        currentcmd = &precommoncmd[*step];
1262                        break;
1263                case 1:
1264                        currentcmd = &rfdependcmd[*step];
1265                        break;
1266                case 2:
1267                        currentcmd = &postcommoncmd[*step];
1268                        break;
1269                default:
1270                        pr_err("Invalid 'stage' = %d, Check it!\n",
1271                               *stage);
1272                        return true;
1273                }
1274
1275                if (currentcmd->cmdid == CMDID_END) {
1276                        if ((*stage) == 2)
1277                                return true;
1278                        (*stage)++;
1279                        (*step) = 0;
1280                        continue;
1281                }
1282
1283                switch (currentcmd->cmdid) {
1284                case CMDID_SET_TXPOWEROWER_LEVEL:
1285                        rtl88e_phy_set_txpower_level(hw, channel);
1286                        break;
1287                case CMDID_WRITEPORT_ULONG:
1288                        rtl_write_dword(rtlpriv, currentcmd->para1,
1289                                        currentcmd->para2);
1290                        break;
1291                case CMDID_WRITEPORT_USHORT:
1292                        rtl_write_word(rtlpriv, currentcmd->para1,
1293                                       (u16)currentcmd->para2);
1294                        break;
1295                case CMDID_WRITEPORT_UCHAR:
1296                        rtl_write_byte(rtlpriv, currentcmd->para1,
1297                                       (u8)currentcmd->para2);
1298                        break;
1299                case CMDID_RF_WRITEREG:
1300                        for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
1301                                rtlphy->rfreg_chnlval[rfpath] =
1302                                    ((rtlphy->rfreg_chnlval[rfpath] &
1303                                      0xfffffc00) | currentcmd->para2);
1304
1305                                rtl_set_rfreg(hw, (enum radio_path)rfpath,
1306                                              currentcmd->para1,
1307                                              RFREG_OFFSET_MASK,
1308                                              rtlphy->rfreg_chnlval[rfpath]);
1309                        }
1310                        break;
1311                default:
1312                        rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,
1313                                "switch case %#x not processed\n",
1314                                currentcmd->cmdid);
1315                        break;
1316                }
1317
1318                break;
1319        } while (true);
1320
1321        (*delay) = currentcmd->msdelay;
1322        (*step)++;
1323        return false;
1324}
1325
1326static bool _rtl88e_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
1327                                             u32 cmdtableidx, u32 cmdtablesz,
1328                                             enum swchnlcmd_id cmdid,
1329                                             u32 para1, u32 para2, u32 msdelay)
1330{
1331        struct swchnlcmd *pcmd;
1332
1333        if (cmdtable == NULL) {
1334                WARN_ONCE(true, "rtl8188ee: cmdtable cannot be NULL.\n");
1335                return false;
1336        }
1337
1338        if (cmdtableidx >= cmdtablesz)
1339                return false;
1340
1341        pcmd = cmdtable + cmdtableidx;
1342        pcmd->cmdid = cmdid;
1343        pcmd->para1 = para1;
1344        pcmd->para2 = para2;
1345        pcmd->msdelay = msdelay;
1346        return true;
1347}
1348
1349static u8 _rtl88e_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)
1350{
1351        u32 reg_eac, reg_e94, reg_e9c;
1352        u8 result = 0x00;
1353
1354        rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1c);
1355        rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x30008c1c);
1356        rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x8214032a);
1357        rtl_set_bbreg(hw, 0xe3c, MASKDWORD, 0x28160000);
1358
1359        rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x00462911);
1360        rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000);
1361        rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);
1362
1363        mdelay(IQK_DELAY_TIME);
1364
1365        reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1366        reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
1367        reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
1368        rtl_get_bbreg(hw, 0xea4, MASKDWORD);
1369
1370        if (!(reg_eac & BIT(28)) &&
1371            (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1372            (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1373                result |= 0x01;
1374        return result;
1375}
1376
1377static u8 _rtl88e_phy_path_b_iqk(struct ieee80211_hw *hw)
1378{
1379        u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc;
1380        u8 result = 0x00;
1381
1382        rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002);
1383        rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000);
1384        mdelay(IQK_DELAY_TIME);
1385        reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1386        reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD);
1387        reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD);
1388        reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD);
1389        reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD);
1390
1391        if (!(reg_eac & BIT(31)) &&
1392            (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&
1393            (((reg_ebc & 0x03FF0000) >> 16) != 0x42))
1394                result |= 0x01;
1395        else
1396                return result;
1397        if (!(reg_eac & BIT(30)) &&
1398            (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) &&
1399            (((reg_ecc & 0x03FF0000) >> 16) != 0x36))
1400                result |= 0x02;
1401        return result;
1402}
1403
1404static u8 _rtl88e_phy_path_a_rx_iqk(struct ieee80211_hw *hw, bool config_pathb)
1405{
1406        u32 reg_eac, reg_e94, reg_e9c, reg_ea4, u32temp;
1407        u8 result = 0x00;
1408
1409        /*Get TXIMR Setting*/
1410        /*Modify RX IQK mode table*/
1411        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1412        rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
1413        rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1414        rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f);
1415        rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf117b);
1416        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1417
1418        /*IQK Setting*/
1419        rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1420        rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x81004800);
1421
1422        /*path a IQK setting*/
1423        rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x10008c1c);
1424        rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x30008c1c);
1425        rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160804);
1426        rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28160000);
1427
1428        /*LO calibration Setting*/
1429        rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
1430        /*one shot,path A LOK & iqk*/
1431        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1432        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1433
1434        mdelay(IQK_DELAY_TIME);
1435
1436        reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1437        reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1438        reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1439
1440
1441        if (!(reg_eac & BIT(28)) &&
1442            (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1443            (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1444                result |= 0x01;
1445        else
1446                return result;
1447
1448        u32temp = 0x80007C00 | (reg_e94&0x3FF0000) |
1449                  ((reg_e9c&0x3FF0000) >> 16);
1450        rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32temp);
1451        /*RX IQK*/
1452        /*Modify RX IQK mode table*/
1453        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1454        rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
1455        rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1456        rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f);
1457        rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7ffa);
1458        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1459
1460        /*IQK Setting*/
1461        rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1462
1463        /*path a IQK setting*/
1464        rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x30008c1c);
1465        rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x10008c1c);
1466        rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160c05);
1467        rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28160c05);
1468
1469        /*LO calibration Setting*/
1470        rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
1471        /*one shot,path A LOK & iqk*/
1472        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1473        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1474
1475        mdelay(IQK_DELAY_TIME);
1476
1477        reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1478        reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1479        reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1480        reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD);
1481
1482        if (!(reg_eac & BIT(27)) &&
1483            (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
1484            (((reg_eac & 0x03FF0000) >> 16) != 0x36))
1485                result |= 0x02;
1486        return result;
1487}
1488
1489static void _rtl88e_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw,
1490                                               bool iqk_ok, long result[][8],
1491                                               u8 final_candidate, bool btxonly)
1492{
1493        u32 oldval_0, x, tx0_a, reg;
1494        long y, tx0_c;
1495
1496        if (final_candidate == 0xFF) {
1497                return;
1498        } else if (iqk_ok) {
1499                oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
1500                                          MASKDWORD) >> 22) & 0x3FF;
1501                x = result[final_candidate][0];
1502                if ((x & 0x00000200) != 0)
1503                        x = x | 0xFFFFFC00;
1504                tx0_a = (x * oldval_0) >> 8;
1505                rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a);
1506                rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31),
1507                              ((x * oldval_0 >> 7) & 0x1));
1508                y = result[final_candidate][1];
1509                if ((y & 0x00000200) != 0)
1510                        y = y | 0xFFFFFC00;
1511                tx0_c = (y * oldval_0) >> 8;
1512                rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000,
1513                              ((tx0_c & 0x3C0) >> 6));
1514                rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000,
1515                              (tx0_c & 0x3F));
1516                rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29),
1517                              ((y * oldval_0 >> 7) & 0x1));
1518                if (btxonly)
1519                        return;
1520                reg = result[final_candidate][2];
1521                rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg);
1522                reg = result[final_candidate][3] & 0x3F;
1523                rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg);
1524                reg = (result[final_candidate][3] >> 6) & 0xF;
1525                rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg);
1526        }
1527}
1528
1529static void _rtl88e_phy_save_adda_registers(struct ieee80211_hw *hw,
1530                                            u32 *addareg, u32 *addabackup,
1531                                            u32 registernum)
1532{
1533        u32 i;
1534
1535        for (i = 0; i < registernum; i++)
1536                addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD);
1537}
1538
1539static void _rtl88e_phy_save_mac_registers(struct ieee80211_hw *hw,
1540                                           u32 *macreg, u32 *macbackup)
1541{
1542        struct rtl_priv *rtlpriv = rtl_priv(hw);
1543        u32 i;
1544
1545        for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
1546                macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]);
1547        macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]);
1548}
1549
1550static void _rtl88e_phy_reload_adda_registers(struct ieee80211_hw *hw,
1551                                              u32 *addareg, u32 *addabackup,
1552                                              u32 regiesternum)
1553{
1554        u32 i;
1555
1556        for (i = 0; i < regiesternum; i++)
1557                rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]);
1558}
1559
1560static void _rtl88e_phy_reload_mac_registers(struct ieee80211_hw *hw,
1561                                             u32 *macreg, u32 *macbackup)
1562{
1563        struct rtl_priv *rtlpriv = rtl_priv(hw);
1564        u32 i;
1565
1566        for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
1567                rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]);
1568        rtl_write_dword(rtlpriv, macreg[i], macbackup[i]);
1569}
1570
1571static void _rtl88e_phy_path_adda_on(struct ieee80211_hw *hw,
1572                                     u32 *addareg, bool is_patha_on, bool is2t)
1573{
1574        u32 pathon;
1575        u32 i;
1576
1577        pathon = is_patha_on ? 0x04db25a4 : 0x0b1b25a4;
1578        if (!is2t) {
1579                pathon = 0x0bdb25a0;
1580                rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0);
1581        } else {
1582                rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathon);
1583        }
1584
1585        for (i = 1; i < IQK_ADDA_REG_NUM; i++)
1586                rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathon);
1587}
1588
1589static void _rtl88e_phy_mac_setting_calibration(struct ieee80211_hw *hw,
1590                                                u32 *macreg, u32 *macbackup)
1591{
1592        struct rtl_priv *rtlpriv = rtl_priv(hw);
1593        u32 i = 0;
1594
1595        rtl_write_byte(rtlpriv, macreg[i], 0x3F);
1596
1597        for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++)
1598                rtl_write_byte(rtlpriv, macreg[i],
1599                               (u8) (macbackup[i] & (~BIT(3))));
1600        rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5))));
1601}
1602
1603static void _rtl88e_phy_path_a_standby(struct ieee80211_hw *hw)
1604{
1605        rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0);
1606        rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
1607        rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1608}
1609
1610static void _rtl88e_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode)
1611{
1612        u32 mode;
1613
1614        mode = pi_mode ? 0x01000100 : 0x01000000;
1615        rtl_set_bbreg(hw, 0x820, MASKDWORD, mode);
1616        rtl_set_bbreg(hw, 0x828, MASKDWORD, mode);
1617}
1618
1619static bool _rtl88e_phy_simularity_compare(struct ieee80211_hw *hw,
1620                                           long result[][8], u8 c1, u8 c2)
1621{
1622        u32 i, j, diff, simularity_bitmap, bound;
1623        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1624
1625        u8 final_candidate[2] = { 0xFF, 0xFF };
1626        bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version);
1627
1628        if (is2t)
1629                bound = 8;
1630        else
1631                bound = 4;
1632
1633        simularity_bitmap = 0;
1634
1635        for (i = 0; i < bound; i++) {
1636                diff = (result[c1][i] > result[c2][i]) ?
1637                    (result[c1][i] - result[c2][i]) :
1638                    (result[c2][i] - result[c1][i]);
1639
1640                if (diff > MAX_TOLERANCE) {
1641                        if ((i == 2 || i == 6) && !simularity_bitmap) {
1642                                if (result[c1][i] + result[c1][i + 1] == 0)
1643                                        final_candidate[(i / 4)] = c2;
1644                                else if (result[c2][i] + result[c2][i + 1] == 0)
1645                                        final_candidate[(i / 4)] = c1;
1646                                else
1647                                        simularity_bitmap = simularity_bitmap |
1648                                            (1 << i);
1649                        } else
1650                                simularity_bitmap =
1651                                    simularity_bitmap | (1 << i);
1652                }
1653        }
1654
1655        if (simularity_bitmap == 0) {
1656                for (i = 0; i < (bound / 4); i++) {
1657                        if (final_candidate[i] != 0xFF) {
1658                                for (j = i * 4; j < (i + 1) * 4 - 2; j++)
1659                                        result[3][j] =
1660                                            result[final_candidate[i]][j];
1661                                bresult = false;
1662                        }
1663                }
1664                return bresult;
1665        } else if (!(simularity_bitmap & 0x0F)) {
1666                for (i = 0; i < 4; i++)
1667                        result[3][i] = result[c1][i];
1668                return false;
1669        } else if (!(simularity_bitmap & 0xF0) && is2t) {
1670                for (i = 4; i < 8; i++)
1671                        result[3][i] = result[c1][i];
1672                return false;
1673        } else {
1674                return false;
1675        }
1676
1677}
1678
1679static void _rtl88e_phy_iq_calibrate(struct ieee80211_hw *hw,
1680                                     long result[][8], u8 t, bool is2t)
1681{
1682        struct rtl_priv *rtlpriv = rtl_priv(hw);
1683        struct rtl_phy *rtlphy = &rtlpriv->phy;
1684        u32 i;
1685        u8 patha_ok, pathb_ok;
1686        u32 adda_reg[IQK_ADDA_REG_NUM] = {
1687                0x85c, 0xe6c, 0xe70, 0xe74,
1688                0xe78, 0xe7c, 0xe80, 0xe84,
1689                0xe88, 0xe8c, 0xed0, 0xed4,
1690                0xed8, 0xedc, 0xee0, 0xeec
1691        };
1692        u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
1693                0x522, 0x550, 0x551, 0x040
1694        };
1695        u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
1696                ROFDM0_TRXPATHENABLE, ROFDM0_TRMUXPAR,
1697                RFPGA0_XCD_RFINTERFACESW, 0xb68, 0xb6c,
1698                0x870, 0x860, 0x864, 0x800
1699        };
1700        const u32 retrycount = 2;
1701
1702        if (t == 0) {
1703                _rtl88e_phy_save_adda_registers(hw, adda_reg,
1704                                                rtlphy->adda_backup, 16);
1705                _rtl88e_phy_save_mac_registers(hw, iqk_mac_reg,
1706                                               rtlphy->iqk_mac_backup);
1707                _rtl88e_phy_save_adda_registers(hw, iqk_bb_reg,
1708                                                rtlphy->iqk_bb_backup,
1709                                                IQK_BB_REG_NUM);
1710        }
1711        _rtl88e_phy_path_adda_on(hw, adda_reg, true, is2t);
1712        if (t == 0) {
1713                rtlphy->rfpi_enable =
1714                  (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, BIT(8));
1715        }
1716
1717        if (!rtlphy->rfpi_enable)
1718                _rtl88e_phy_pi_mode_switch(hw, true);
1719        /*BB Setting*/
1720        rtl_set_bbreg(hw, 0x800, BIT(24), 0x00);
1721        rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
1722        rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
1723        rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
1724
1725        rtl_set_bbreg(hw, 0x870, BIT(10), 0x01);
1726        rtl_set_bbreg(hw, 0x870, BIT(26), 0x01);
1727        rtl_set_bbreg(hw, 0x860, BIT(10), 0x00);
1728        rtl_set_bbreg(hw, 0x864, BIT(10), 0x00);
1729
1730        if (is2t) {
1731                rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
1732                rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000);
1733        }
1734        _rtl88e_phy_mac_setting_calibration(hw, iqk_mac_reg,
1735                                            rtlphy->iqk_mac_backup);
1736        rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x0f600000);
1737        if (is2t)
1738                rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x0f600000);
1739
1740        rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1741        rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00);
1742        rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x81004800);
1743        for (i = 0; i < retrycount; i++) {
1744                patha_ok = _rtl88e_phy_path_a_iqk(hw, is2t);
1745                if (patha_ok == 0x01) {
1746                        rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
1747                                "Path A Tx IQK Success!!\n");
1748                        result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
1749                                        0x3FF0000) >> 16;
1750                        result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
1751                                        0x3FF0000) >> 16;
1752                        break;
1753                }
1754        }
1755
1756        for (i = 0; i < retrycount; i++) {
1757                patha_ok = _rtl88e_phy_path_a_rx_iqk(hw, is2t);
1758                if (patha_ok == 0x03) {
1759                        rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
1760                                "Path A Rx IQK Success!!\n");
1761                        result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &
1762                                        0x3FF0000) >> 16;
1763                        result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &
1764                                        0x3FF0000) >> 16;
1765                        break;
1766                } else {
1767                        rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
1768                                "Path a RX iqk fail!!!\n");
1769                }
1770        }
1771
1772        if (0 == patha_ok)
1773                rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
1774                        "Path A IQK Success!!\n");
1775        if (is2t) {
1776                _rtl88e_phy_path_a_standby(hw);
1777                _rtl88e_phy_path_adda_on(hw, adda_reg, false, is2t);
1778                for (i = 0; i < retrycount; i++) {
1779                        pathb_ok = _rtl88e_phy_path_b_iqk(hw);
1780                        if (pathb_ok == 0x03) {
1781                                result[t][4] = (rtl_get_bbreg(hw,
1782                                                              0xeb4,
1783                                                              MASKDWORD) &
1784                                                0x3FF0000) >> 16;
1785                                result[t][5] =
1786                                    (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
1787                                     0x3FF0000) >> 16;
1788                                result[t][6] =
1789                                    (rtl_get_bbreg(hw, 0xec4, MASKDWORD) &
1790                                     0x3FF0000) >> 16;
1791                                result[t][7] =
1792                                    (rtl_get_bbreg(hw, 0xecc, MASKDWORD) &
1793                                     0x3FF0000) >> 16;
1794                                break;
1795                        } else if (i == (retrycount - 1) && pathb_ok == 0x01) {
1796                                result[t][4] = (rtl_get_bbreg(hw,
1797                                                              0xeb4,
1798                                                              MASKDWORD) &
1799                                                0x3FF0000) >> 16;
1800                        }
1801                        result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
1802                                        0x3FF0000) >> 16;
1803                }
1804        }
1805
1806        rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);
1807
1808        if (t != 0) {
1809                if (!rtlphy->rfpi_enable)
1810                        _rtl88e_phy_pi_mode_switch(hw, false);
1811                _rtl88e_phy_reload_adda_registers(hw, adda_reg,
1812                                                  rtlphy->adda_backup, 16);
1813                _rtl88e_phy_reload_mac_registers(hw, iqk_mac_reg,
1814                                                 rtlphy->iqk_mac_backup);
1815                _rtl88e_phy_reload_adda_registers(hw, iqk_bb_reg,
1816                                                  rtlphy->iqk_bb_backup,
1817                                                  IQK_BB_REG_NUM);
1818
1819                rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3);
1820                if (is2t)
1821                        rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3);
1822                rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00);
1823                rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00);
1824        }
1825        rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "88ee IQK Finish!!\n");
1826}
1827
1828static void _rtl88e_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
1829{
1830        u8 tmpreg;
1831        u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
1832        struct rtl_priv *rtlpriv = rtl_priv(hw);
1833
1834        tmpreg = rtl_read_byte(rtlpriv, 0xd03);
1835
1836        if ((tmpreg & 0x70) != 0)
1837                rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
1838        else
1839                rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
1840
1841        if ((tmpreg & 0x70) != 0) {
1842                rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
1843
1844                if (is2t)
1845                        rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
1846                                                  MASK12BITS);
1847
1848                rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
1849                              (rf_a_mode & 0x8FFFF) | 0x10000);
1850
1851                if (is2t)
1852                        rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
1853                                      (rf_b_mode & 0x8FFFF) | 0x10000);
1854        }
1855        lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
1856
1857        rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000);
1858
1859        mdelay(100);
1860
1861        if ((tmpreg & 0x70) != 0) {
1862                rtl_write_byte(rtlpriv, 0xd03, tmpreg);
1863                rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
1864
1865                if (is2t)
1866                        rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
1867                                      rf_b_mode);
1868        } else {
1869                rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1870        }
1871        rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
1872}
1873
1874static void _rtl88e_phy_set_rfpath_switch(struct ieee80211_hw *hw,
1875                                          bool bmain, bool is2t)
1876{
1877        struct rtl_priv *rtlpriv = rtl_priv(hw);
1878        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1879        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1880        rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
1881
1882        if (is_hal_stop(rtlhal)) {
1883                u8 u1btmp;
1884                u1btmp = rtl_read_byte(rtlpriv, REG_LEDCFG0);
1885                rtl_write_byte(rtlpriv, REG_LEDCFG0, u1btmp | BIT(7));
1886                rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(13), 0x01);
1887        }
1888        if (is2t) {
1889                if (bmain)
1890                        rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1891                                      BIT(5) | BIT(6), 0x1);
1892                else
1893                        rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1894                                      BIT(5) | BIT(6), 0x2);
1895        } else {
1896                rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(8) | BIT(9), 0);
1897                rtl_set_bbreg(hw, 0x914, MASKLWORD, 0x0201);
1898
1899                /* We use the RF definition of MAIN and AUX,
1900                 * left antenna and right antenna repectively.
1901                 * Default output at AUX.
1902                 */
1903                if (bmain) {
1904                        rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE,
1905                                      BIT(14) | BIT(13) | BIT(12), 0);
1906                        rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1907                                      BIT(5) | BIT(4) | BIT(3), 0);
1908                        if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
1909                                rtl_set_bbreg(hw, RCONFIG_RAM64x16, BIT(31), 0);
1910                } else {
1911                        rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE,
1912                                      BIT(14) | BIT(13) | BIT(12), 1);
1913                        rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1914                                      BIT(5) | BIT(4) | BIT(3), 1);
1915                        if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
1916                                rtl_set_bbreg(hw, RCONFIG_RAM64x16, BIT(31), 1);
1917                }
1918        }
1919}
1920
1921#undef IQK_ADDA_REG_NUM
1922#undef IQK_DELAY_TIME
1923
1924void rtl88e_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
1925{
1926        struct rtl_priv *rtlpriv = rtl_priv(hw);
1927        struct rtl_phy *rtlphy = &rtlpriv->phy;
1928        long result[4][8];
1929        u8 i, final_candidate;
1930        bool b_patha_ok;
1931        long reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc,
1932            reg_tmp = 0;
1933        bool is12simular, is13simular, is23simular;
1934        u32 iqk_bb_reg[9] = {
1935                ROFDM0_XARXIQIMBALANCE,
1936                ROFDM0_XBRXIQIMBALANCE,
1937                ROFDM0_ECCATHRESHOLD,
1938                ROFDM0_AGCRSSITABLE,
1939                ROFDM0_XATXIQIMBALANCE,
1940                ROFDM0_XBTXIQIMBALANCE,
1941                ROFDM0_XCTXAFE,
1942                ROFDM0_XDTXAFE,
1943                ROFDM0_RXIQEXTANTA
1944        };
1945
1946        if (b_recovery) {
1947                _rtl88e_phy_reload_adda_registers(hw,
1948                                                  iqk_bb_reg,
1949                                                  rtlphy->iqk_bb_backup, 9);
1950                return;
1951        }
1952
1953        for (i = 0; i < 8; i++) {
1954                result[0][i] = 0;
1955                result[1][i] = 0;
1956                result[2][i] = 0;
1957                result[3][i] = 0;
1958        }
1959        final_candidate = 0xff;
1960        b_patha_ok = false;
1961        is12simular = false;
1962        is23simular = false;
1963        is13simular = false;
1964        for (i = 0; i < 3; i++) {
1965                if (get_rf_type(rtlphy) == RF_2T2R)
1966                        _rtl88e_phy_iq_calibrate(hw, result, i, true);
1967                else
1968                        _rtl88e_phy_iq_calibrate(hw, result, i, false);
1969                if (i == 1) {
1970                        is12simular =
1971                          _rtl88e_phy_simularity_compare(hw, result, 0, 1);
1972                        if (is12simular) {
1973                                final_candidate = 0;
1974                                break;
1975                        }
1976                }
1977                if (i == 2) {
1978                        is13simular =
1979                          _rtl88e_phy_simularity_compare(hw, result, 0, 2);
1980                        if (is13simular) {
1981                                final_candidate = 0;
1982                                break;
1983                        }
1984                        is23simular =
1985                           _rtl88e_phy_simularity_compare(hw, result, 1, 2);
1986                        if (is23simular) {
1987                                final_candidate = 1;
1988                        } else {
1989                                for (i = 0; i < 8; i++)
1990                                        reg_tmp += result[3][i];
1991
1992                                if (reg_tmp != 0)
1993                                        final_candidate = 3;
1994                                else
1995                                        final_candidate = 0xFF;
1996                        }
1997                }
1998        }
1999        for (i = 0; i < 4; i++) {
2000                reg_e94 = result[i][0];
2001                reg_e9c = result[i][1];
2002                reg_ea4 = result[i][2];
2003                reg_eb4 = result[i][4];
2004                reg_ebc = result[i][5];
2005        }
2006        if (final_candidate != 0xff) {
2007                reg_e94 = result[final_candidate][0];
2008                reg_e9c = result[final_candidate][1];
2009                reg_ea4 = result[final_candidate][2];
2010                reg_eb4 = result[final_candidate][4];
2011                reg_ebc = result[final_candidate][5];
2012                rtlphy->reg_eb4 = reg_eb4;
2013                rtlphy->reg_ebc = reg_ebc;
2014                rtlphy->reg_e94 = reg_e94;
2015                rtlphy->reg_e9c = reg_e9c;
2016                b_patha_ok = true;
2017        } else {
2018                rtlphy->reg_e94 = 0x100;
2019                rtlphy->reg_eb4 = 0x100;
2020                rtlphy->reg_e9c = 0x0;
2021                rtlphy->reg_ebc = 0x0;
2022        }
2023        if (reg_e94 != 0) /*&&(reg_ea4 != 0) */
2024                _rtl88e_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result,
2025                                                   final_candidate,
2026                                                   (reg_ea4 == 0));
2027        if (final_candidate != 0xFF) {
2028                for (i = 0; i < IQK_MATRIX_REG_NUM; i++)
2029                        rtlphy->iqk_matrix[0].value[0][i] =
2030                                result[final_candidate][i];
2031                rtlphy->iqk_matrix[0].iqk_done = true;
2032
2033        }
2034        _rtl88e_phy_save_adda_registers(hw, iqk_bb_reg,
2035                                        rtlphy->iqk_bb_backup, 9);
2036}
2037
2038void rtl88e_phy_lc_calibrate(struct ieee80211_hw *hw)
2039{
2040        struct rtl_priv *rtlpriv = rtl_priv(hw);
2041        struct rtl_phy *rtlphy = &rtlpriv->phy;
2042        struct rtl_hal *rtlhal = &rtlpriv->rtlhal;
2043        u32 timeout = 2000, timecount = 0;
2044
2045        while (rtlpriv->mac80211.act_scanning && timecount < timeout) {
2046                udelay(50);
2047                timecount += 50;
2048        }
2049
2050        rtlphy->lck_inprogress = true;
2051        RTPRINT(rtlpriv, FINIT, INIT_IQK,
2052                "LCK:Start!!! currentband %x delay %d ms\n",
2053                 rtlhal->current_bandtype, timecount);
2054
2055        _rtl88e_phy_lc_calibrate(hw, false);
2056
2057        rtlphy->lck_inprogress = false;
2058}
2059
2060void rtl88e_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
2061{
2062        _rtl88e_phy_set_rfpath_switch(hw, bmain, false);
2063}
2064
2065bool rtl88e_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
2066{
2067        struct rtl_priv *rtlpriv = rtl_priv(hw);
2068        struct rtl_phy *rtlphy = &rtlpriv->phy;
2069        bool postprocessing = false;
2070
2071        rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE,
2072                "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
2073                iotype, rtlphy->set_io_inprogress);
2074        do {
2075                switch (iotype) {
2076                case IO_CMD_RESUME_DM_BY_SCAN:
2077                        rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE,
2078                                "[IO CMD] Resume DM after scan.\n");
2079                        postprocessing = true;
2080                        break;
2081                case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
2082                        rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE,
2083                                "[IO CMD] Pause DM before scan.\n");
2084                        postprocessing = true;
2085                        break;
2086                default:
2087                        rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,
2088                                "switch case %#x not processed\n", iotype);
2089                        break;
2090                }
2091        } while (false);
2092        if (postprocessing && !rtlphy->set_io_inprogress) {
2093                rtlphy->set_io_inprogress = true;
2094                rtlphy->current_io_type = iotype;
2095        } else {
2096                return false;
2097        }
2098        rtl88e_phy_set_io(hw);
2099        rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
2100        return true;
2101}
2102
2103static void rtl88e_phy_set_io(struct ieee80211_hw *hw)
2104{
2105        struct rtl_priv *rtlpriv = rtl_priv(hw);
2106        struct rtl_phy *rtlphy = &rtlpriv->phy;
2107        struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
2108
2109        rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE,
2110                "--->Cmd(%#x), set_io_inprogress(%d)\n",
2111                rtlphy->current_io_type, rtlphy->set_io_inprogress);
2112        switch (rtlphy->current_io_type) {
2113        case IO_CMD_RESUME_DM_BY_SCAN:
2114                dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1;
2115                /*rtl92c_dm_write_dig(hw);*/
2116                rtl88e_phy_set_txpower_level(hw, rtlphy->current_channel);
2117                rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x83);
2118                break;
2119        case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
2120                rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
2121                dm_digtable->cur_igvalue = 0x17;
2122                rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x40);
2123                break;
2124        default:
2125                rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,
2126                        "switch case %#x not processed\n",
2127                        rtlphy->current_io_type);
2128                break;
2129        }
2130        rtlphy->set_io_inprogress = false;
2131        rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE,
2132                "(%#x)\n", rtlphy->current_io_type);
2133}
2134
2135static void rtl88ee_phy_set_rf_on(struct ieee80211_hw *hw)
2136{
2137        struct rtl_priv *rtlpriv = rtl_priv(hw);
2138
2139        rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
2140        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2141        /*rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);*/
2142        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2143        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2144        rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2145}
2146
2147static void _rtl88ee_phy_set_rf_sleep(struct ieee80211_hw *hw)
2148{
2149        struct rtl_priv *rtlpriv = rtl_priv(hw);
2150
2151        rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2152        rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
2153        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2154        rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
2155}
2156
2157static bool _rtl88ee_phy_set_rf_power_state(struct ieee80211_hw *hw,
2158                                            enum rf_pwrstate rfpwr_state)
2159{
2160        struct rtl_priv *rtlpriv = rtl_priv(hw);
2161        struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2162        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2163        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2164        bool bresult = true;
2165        u8 i, queue_id;
2166        struct rtl8192_tx_ring *ring = NULL;
2167
2168        switch (rfpwr_state) {
2169        case ERFON:
2170                if ((ppsc->rfpwr_state == ERFOFF) &&
2171                    RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
2172                        bool rtstatus;
2173                        u32 initializecount = 0;
2174
2175                        do {
2176                                initializecount++;
2177                                rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,
2178                                        "IPS Set eRf nic enable\n");
2179                                rtstatus = rtl_ps_enable_nic(hw);
2180                        } while (!rtstatus &&
2181                                 (initializecount < 10));
2182                        RT_CLEAR_PS_LEVEL(ppsc,
2183                                          RT_RF_OFF_LEVL_HALT_NIC);
2184                } else {
2185                        rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,
2186                                "Set ERFON slept:%d ms\n",
2187                                jiffies_to_msecs(jiffies -
2188                                                 ppsc->last_sleep_jiffies));
2189                        ppsc->last_awake_jiffies = jiffies;
2190                        rtl88ee_phy_set_rf_on(hw);
2191                }
2192                if (mac->link_state == MAC80211_LINKED) {
2193                        rtlpriv->cfg->ops->led_control(hw,
2194                                                       LED_CTL_LINK);
2195                } else {
2196                        rtlpriv->cfg->ops->led_control(hw,
2197                                                       LED_CTL_NO_LINK);
2198                }
2199                break;
2200        case ERFOFF:
2201                for (queue_id = 0, i = 0;
2202                     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2203                        ring = &pcipriv->dev.tx_ring[queue_id];
2204                        if (queue_id == BEACON_QUEUE ||
2205                            skb_queue_len(&ring->queue) == 0) {
2206                                queue_id++;
2207                                continue;
2208                        } else {
2209                                rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
2210                                        "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
2211                                        (i + 1), queue_id,
2212                                        skb_queue_len(&ring->queue));
2213
2214                                udelay(10);
2215                                i++;
2216                        }
2217                        if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2218                                rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
2219                                        "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
2220                                        MAX_DOZE_WAITING_TIMES_9x,
2221                                        queue_id,
2222                                        skb_queue_len(&ring->queue));
2223                                break;
2224                        }
2225                }
2226
2227                if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
2228                        rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,
2229                                "IPS Set eRf nic disable\n");
2230                        rtl_ps_disable_nic(hw);
2231                        RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2232                } else {
2233                        if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
2234                                rtlpriv->cfg->ops->led_control(hw,
2235                                                               LED_CTL_NO_LINK);
2236                        } else {
2237                                rtlpriv->cfg->ops->led_control(hw,
2238                                                               LED_CTL_POWER_OFF);
2239                        }
2240                }
2241                break;
2242        case ERFSLEEP:{
2243                        if (ppsc->rfpwr_state == ERFOFF)
2244                                break;
2245                        for (queue_id = 0, i = 0;
2246                             queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2247                                ring = &pcipriv->dev.tx_ring[queue_id];
2248                                if (skb_queue_len(&ring->queue) == 0) {
2249                                        queue_id++;
2250                                        continue;
2251                                } else {
2252                                        rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
2253                                                "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
2254                                                (i + 1), queue_id,
2255                                                skb_queue_len(&ring->queue));
2256
2257                                        udelay(10);
2258                                        i++;
2259                                }
2260                                if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2261                                        rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
2262                                                "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
2263                                                MAX_DOZE_WAITING_TIMES_9x,
2264                                                queue_id,
2265                                                skb_queue_len(&ring->queue));
2266                                        break;
2267                                }
2268                        }
2269                        rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,
2270                                "Set ERFSLEEP awaked:%d ms\n",
2271                                jiffies_to_msecs(jiffies -
2272                                ppsc->last_awake_jiffies));
2273                        ppsc->last_sleep_jiffies = jiffies;
2274                        _rtl88ee_phy_set_rf_sleep(hw);
2275                        break;
2276                }
2277        default:
2278                rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,
2279                        "switch case %#x not processed\n", rfpwr_state);
2280                bresult = false;
2281                break;
2282        }
2283        if (bresult)
2284                ppsc->rfpwr_state = rfpwr_state;
2285        return bresult;
2286}
2287
2288bool rtl88e_phy_set_rf_power_state(struct ieee80211_hw *hw,
2289                                   enum rf_pwrstate rfpwr_state)
2290{
2291        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2292
2293        bool bresult = false;
2294
2295        if (rfpwr_state == ppsc->rfpwr_state)
2296                return bresult;
2297        bresult = _rtl88ee_phy_set_rf_power_state(hw, rfpwr_state);
2298        return bresult;
2299}
2300