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