linux/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/phy.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright(c) 2009-2012  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#include "../rtl8723com/phy_common.h"
  14
  15static void _rtl8723e_phy_fw_rf_serial_write(struct ieee80211_hw *hw,
  16                                             enum radio_path rfpath, u32 offset,
  17                                             u32 data);
  18static bool _rtl8723e_phy_bb8192c_config_parafile(struct ieee80211_hw *hw);
  19static bool _rtl8723e_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
  20static bool _rtl8723e_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
  21                                                    u8 configtype);
  22static bool _rtl8723e_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
  23                                                      u8 configtype);
  24static bool _rtl8723e_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
  25                                               u8 channel, u8 *stage, u8 *step,
  26                                               u32 *delay);
  27static u8 _rtl8723e_phy_dbm_to_txpwr_idx(struct ieee80211_hw *hw,
  28                                         enum wireless_mode wirelessmode,
  29                                         long power_indbm);
  30static void rtl8723e_phy_set_rf_on(struct ieee80211_hw *hw);
  31static void rtl8723e_phy_set_io(struct ieee80211_hw *hw);
  32
  33u32 rtl8723e_phy_query_rf_reg(struct ieee80211_hw *hw,
  34                              enum radio_path rfpath,
  35                              u32 regaddr, u32 bitmask)
  36{
  37        struct rtl_priv *rtlpriv = rtl_priv(hw);
  38        u32 original_value = 0, readback_value, bitshift;
  39        struct rtl_phy *rtlphy = &rtlpriv->phy;
  40
  41        rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
  42                "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
  43                regaddr, rfpath, bitmask);
  44
  45        spin_lock(&rtlpriv->locks.rf_lock);
  46
  47        if (rtlphy->rf_mode != RF_OP_BY_FW) {
  48                original_value = rtl8723_phy_rf_serial_read(hw,
  49                                                            rfpath, regaddr);
  50        }
  51
  52        bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
  53        readback_value = (original_value & bitmask) >> bitshift;
  54
  55        spin_unlock(&rtlpriv->locks.rf_lock);
  56
  57        rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
  58                "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
  59                regaddr, rfpath, bitmask, original_value);
  60
  61        return readback_value;
  62}
  63
  64void rtl8723e_phy_set_rf_reg(struct ieee80211_hw *hw,
  65                             enum radio_path rfpath,
  66                           u32 regaddr, u32 bitmask, u32 data)
  67{
  68        struct rtl_priv *rtlpriv = rtl_priv(hw);
  69        struct rtl_phy *rtlphy = &rtlpriv->phy;
  70        u32 original_value = 0, bitshift;
  71
  72        rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
  73                "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
  74                regaddr, bitmask, data, rfpath);
  75
  76        spin_lock(&rtlpriv->locks.rf_lock);
  77
  78        if (rtlphy->rf_mode != RF_OP_BY_FW) {
  79                if (bitmask != RFREG_OFFSET_MASK) {
  80                        original_value = rtl8723_phy_rf_serial_read(hw,
  81                                                                    rfpath,
  82                                                                    regaddr);
  83                        bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
  84                        data =
  85                            ((original_value & (~bitmask)) |
  86                             (data << bitshift));
  87                }
  88
  89                rtl8723_phy_rf_serial_write(hw, rfpath, regaddr, data);
  90        } else {
  91                if (bitmask != RFREG_OFFSET_MASK) {
  92                        bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
  93                        data =
  94                            ((original_value & (~bitmask)) |
  95                             (data << bitshift));
  96                }
  97                _rtl8723e_phy_fw_rf_serial_write(hw, rfpath, regaddr, data);
  98        }
  99
 100        spin_unlock(&rtlpriv->locks.rf_lock);
 101
 102        rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
 103                "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
 104                regaddr, bitmask, data, rfpath);
 105
 106}
 107
 108static void _rtl8723e_phy_fw_rf_serial_write(struct ieee80211_hw *hw,
 109                                             enum radio_path rfpath, u32 offset,
 110                                             u32 data)
 111{
 112        WARN_ONCE(true, "rtl8723ae: _rtl8723e_phy_fw_rf_serial_write deprecated!\n");
 113}
 114
 115static void _rtl8723e_phy_bb_config_1t(struct ieee80211_hw *hw)
 116{
 117        rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2);
 118        rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022);
 119        rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45);
 120        rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23);
 121        rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1);
 122        rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2);
 123        rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2);
 124        rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2);
 125        rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2);
 126        rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2);
 127}
 128
 129bool rtl8723e_phy_mac_config(struct ieee80211_hw *hw)
 130{
 131        struct rtl_priv *rtlpriv = rtl_priv(hw);
 132        bool rtstatus = _rtl8723e_phy_config_mac_with_headerfile(hw);
 133        rtl_write_byte(rtlpriv, 0x04CA, 0x0A);
 134        return rtstatus;
 135}
 136
 137bool rtl8723e_phy_bb_config(struct ieee80211_hw *hw)
 138{
 139        bool rtstatus = true;
 140        struct rtl_priv *rtlpriv = rtl_priv(hw);
 141        u8 tmpu1b;
 142        u8 b_reg_hwparafile = 1;
 143
 144        rtl8723_phy_init_bb_rf_reg_def(hw);
 145
 146        /* 1. 0x28[1] = 1 */
 147        tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_PLL_CTRL);
 148        udelay(2);
 149        rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, (tmpu1b|BIT(1)));
 150        udelay(2);
 151        /* 2. 0x29[7:0] = 0xFF */
 152        rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL+1, 0xff);
 153        udelay(2);
 154
 155        /* 3. 0x02[1:0] = 2b'11 */
 156        tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN);
 157        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
 158                       (tmpu1b | FEN_BB_GLB_RSTN | FEN_BBRSTB));
 159
 160        /* 4. 0x25[6] = 0 */
 161        tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+1);
 162        rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+1, (tmpu1b & (~BIT(6))));
 163
 164        /* 5. 0x24[20] = 0      //Advised by SD3 Alex Wang. 2011.02.09. */
 165        tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+2);
 166        rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+2, (tmpu1b & (~BIT(4))));
 167
 168        /* 6. 0x1f[7:0] = 0x07 */
 169        rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x07);
 170
 171        if (b_reg_hwparafile == 1)
 172                rtstatus = _rtl8723e_phy_bb8192c_config_parafile(hw);
 173        return rtstatus;
 174}
 175
 176bool rtl8723e_phy_rf_config(struct ieee80211_hw *hw)
 177{
 178        return rtl8723e_phy_rf6052_config(hw);
 179}
 180
 181static bool _rtl8723e_phy_bb8192c_config_parafile(struct ieee80211_hw *hw)
 182{
 183        struct rtl_priv *rtlpriv = rtl_priv(hw);
 184        struct rtl_phy *rtlphy = &rtlpriv->phy;
 185        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 186        bool rtstatus;
 187
 188        rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "\n");
 189        rtstatus = _rtl8723e_phy_config_bb_with_headerfile(hw,
 190                                                BASEBAND_CONFIG_PHY_REG);
 191        if (!rtstatus) {
 192                pr_err("Write BB Reg Fail!!\n");
 193                return false;
 194        }
 195
 196        if (rtlphy->rf_type == RF_1T2R) {
 197                _rtl8723e_phy_bb_config_1t(hw);
 198                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n");
 199        }
 200        if (rtlefuse->autoload_failflag == false) {
 201                rtlphy->pwrgroup_cnt = 0;
 202                rtstatus = _rtl8723e_phy_config_bb_with_pgheaderfile(hw,
 203                                        BASEBAND_CONFIG_PHY_REG);
 204        }
 205        if (!rtstatus) {
 206                pr_err("BB_PG Reg Fail!!\n");
 207                return false;
 208        }
 209        rtstatus =
 210          _rtl8723e_phy_config_bb_with_headerfile(hw, BASEBAND_CONFIG_AGC_TAB);
 211        if (!rtstatus) {
 212                pr_err("AGC Table Fail\n");
 213                return false;
 214        }
 215        rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw,
 216                                        RFPGA0_XA_HSSIPARAMETER2,
 217                                        0x200));
 218
 219        return true;
 220}
 221
 222static bool _rtl8723e_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
 223{
 224        struct rtl_priv *rtlpriv = rtl_priv(hw);
 225        u32 i;
 226        u32 arraylength;
 227        u32 *ptrarray;
 228
 229        rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl723MACPHY_Array\n");
 230        arraylength = RTL8723E_MACARRAYLENGTH;
 231        ptrarray = RTL8723EMAC_ARRAY;
 232
 233        rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 234                "Img:RTL8192CEMAC_2T_ARRAY\n");
 235        for (i = 0; i < arraylength; i = i + 2)
 236                rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
 237        return true;
 238}
 239
 240static bool _rtl8723e_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
 241                                                    u8 configtype)
 242{
 243        int i;
 244        u32 *phy_regarray_table;
 245        u32 *agctab_array_table;
 246        u16 phy_reg_arraylen, agctab_arraylen;
 247        struct rtl_priv *rtlpriv = rtl_priv(hw);
 248
 249        agctab_arraylen = RTL8723E_AGCTAB_1TARRAYLENGTH;
 250        agctab_array_table = RTL8723EAGCTAB_1TARRAY;
 251        phy_reg_arraylen = RTL8723E_PHY_REG_1TARRAY_LENGTH;
 252        phy_regarray_table = RTL8723EPHY_REG_1TARRAY;
 253        if (configtype == BASEBAND_CONFIG_PHY_REG) {
 254                for (i = 0; i < phy_reg_arraylen; i = i + 2) {
 255                        if (phy_regarray_table[i] == 0xfe)
 256                                mdelay(50);
 257                        else if (phy_regarray_table[i] == 0xfd)
 258                                mdelay(5);
 259                        else if (phy_regarray_table[i] == 0xfc)
 260                                mdelay(1);
 261                        else if (phy_regarray_table[i] == 0xfb)
 262                                udelay(50);
 263                        else if (phy_regarray_table[i] == 0xfa)
 264                                udelay(5);
 265                        else if (phy_regarray_table[i] == 0xf9)
 266                                udelay(1);
 267                        rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD,
 268                                      phy_regarray_table[i + 1]);
 269                        udelay(1);
 270                        rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 271                                "The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n",
 272                                phy_regarray_table[i],
 273                                phy_regarray_table[i + 1]);
 274                }
 275        } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
 276                for (i = 0; i < agctab_arraylen; i = i + 2) {
 277                        rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD,
 278                                      agctab_array_table[i + 1]);
 279                        udelay(1);
 280                        rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 281                                "The agctab_array_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n",
 282                                agctab_array_table[i],
 283                                agctab_array_table[i + 1]);
 284                }
 285        }
 286        return true;
 287}
 288
 289static void store_pwrindex_diffrate_offset(struct ieee80211_hw *hw,
 290                                           u32 regaddr, u32 bitmask,
 291                                           u32 data)
 292{
 293        struct rtl_priv *rtlpriv = rtl_priv(hw);
 294        struct rtl_phy *rtlphy = &rtlpriv->phy;
 295
 296        if (regaddr == RTXAGC_A_RATE18_06) {
 297                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] =
 298                    data;
 299                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 300                        "MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n",
 301                        rtlphy->pwrgroup_cnt,
 302                        rtlphy->mcs_txpwrlevel_origoffset
 303                        [rtlphy->pwrgroup_cnt][0]);
 304        }
 305        if (regaddr == RTXAGC_A_RATE54_24) {
 306                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] =
 307                    data;
 308                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 309                        "MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n",
 310                        rtlphy->pwrgroup_cnt,
 311                        rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
 312                                                            pwrgroup_cnt][1]);
 313        }
 314        if (regaddr == RTXAGC_A_CCK1_MCS32) {
 315                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] =
 316                    data;
 317                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 318                        "MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n",
 319                        rtlphy->pwrgroup_cnt,
 320                        rtlphy->mcs_txpwrlevel_origoffset
 321                        [rtlphy->pwrgroup_cnt][6]);
 322        }
 323        if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) {
 324                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][7] =
 325                    data;
 326                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 327                        "MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n",
 328                        rtlphy->pwrgroup_cnt,
 329                        rtlphy->mcs_txpwrlevel_origoffset
 330                        [rtlphy->pwrgroup_cnt][7]);
 331        }
 332        if (regaddr == RTXAGC_A_MCS03_MCS00) {
 333                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] =
 334                    data;
 335                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 336                        "MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n",
 337                        rtlphy->pwrgroup_cnt,
 338                        rtlphy->mcs_txpwrlevel_origoffset
 339                        [rtlphy->pwrgroup_cnt][2]);
 340        }
 341        if (regaddr == RTXAGC_A_MCS07_MCS04) {
 342                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] =
 343                    data;
 344                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 345                        "MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n",
 346                        rtlphy->pwrgroup_cnt,
 347                        rtlphy->mcs_txpwrlevel_origoffset
 348                        [rtlphy->pwrgroup_cnt][3]);
 349        }
 350        if (regaddr == RTXAGC_A_MCS11_MCS08) {
 351                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] =
 352                    data;
 353                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 354                        "MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n",
 355                        rtlphy->pwrgroup_cnt,
 356                        rtlphy->mcs_txpwrlevel_origoffset
 357                        [rtlphy->pwrgroup_cnt][4]);
 358        }
 359        if (regaddr == RTXAGC_A_MCS15_MCS12) {
 360                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] =
 361                    data;
 362                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 363                        "MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n",
 364                        rtlphy->pwrgroup_cnt,
 365                        rtlphy->mcs_txpwrlevel_origoffset
 366                        [rtlphy->pwrgroup_cnt][5]);
 367        }
 368        if (regaddr == RTXAGC_B_RATE18_06) {
 369                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][8] =
 370                    data;
 371                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 372                        "MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n",
 373                        rtlphy->pwrgroup_cnt,
 374                        rtlphy->mcs_txpwrlevel_origoffset
 375                        [rtlphy->pwrgroup_cnt][8]);
 376        }
 377        if (regaddr == RTXAGC_B_RATE54_24) {
 378                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][9] =
 379                    data;
 380                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 381                        "MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n",
 382                        rtlphy->pwrgroup_cnt,
 383                        rtlphy->mcs_txpwrlevel_origoffset
 384                        [rtlphy->pwrgroup_cnt][9]);
 385        }
 386        if (regaddr == RTXAGC_B_CCK1_55_MCS32) {
 387                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][14] =
 388                    data;
 389                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 390                        "MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n",
 391                        rtlphy->pwrgroup_cnt,
 392                        rtlphy->mcs_txpwrlevel_origoffset
 393                        [rtlphy->pwrgroup_cnt][14]);
 394        }
 395        if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) {
 396                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][15] =
 397                    data;
 398                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 399                        "MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n",
 400                        rtlphy->pwrgroup_cnt,
 401                        rtlphy->mcs_txpwrlevel_origoffset
 402                        [rtlphy->pwrgroup_cnt][15]);
 403        }
 404        if (regaddr == RTXAGC_B_MCS03_MCS00) {
 405                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][10] =
 406                    data;
 407                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 408                        "MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n",
 409                        rtlphy->pwrgroup_cnt,
 410                        rtlphy->mcs_txpwrlevel_origoffset
 411                        [rtlphy->pwrgroup_cnt][10]);
 412        }
 413        if (regaddr == RTXAGC_B_MCS07_MCS04) {
 414                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][11] =
 415                    data;
 416                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 417                        "MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n",
 418                        rtlphy->pwrgroup_cnt,
 419                        rtlphy->mcs_txpwrlevel_origoffset
 420                        [rtlphy->pwrgroup_cnt][11]);
 421        }
 422        if (regaddr == RTXAGC_B_MCS11_MCS08) {
 423                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][12] =
 424                    data;
 425                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 426                        "MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n",
 427                        rtlphy->pwrgroup_cnt,
 428                        rtlphy->mcs_txpwrlevel_origoffset
 429                        [rtlphy->pwrgroup_cnt][12]);
 430        }
 431        if (regaddr == RTXAGC_B_MCS15_MCS12) {
 432                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][13] =
 433                    data;
 434                rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 435                        "MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n",
 436                        rtlphy->pwrgroup_cnt,
 437                        rtlphy->mcs_txpwrlevel_origoffset
 438                        [rtlphy->pwrgroup_cnt][13]);
 439
 440                rtlphy->pwrgroup_cnt++;
 441        }
 442}
 443
 444static bool _rtl8723e_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
 445                                                      u8 configtype)
 446{
 447        struct rtl_priv *rtlpriv = rtl_priv(hw);
 448        int i;
 449        u32 *phy_regarray_table_pg;
 450        u16 phy_regarray_pg_len;
 451
 452        phy_regarray_pg_len = RTL8723E_PHY_REG_ARRAY_PGLENGTH;
 453        phy_regarray_table_pg = RTL8723EPHY_REG_ARRAY_PG;
 454
 455        if (configtype == BASEBAND_CONFIG_PHY_REG) {
 456                for (i = 0; i < phy_regarray_pg_len; i = i + 3) {
 457                        if (phy_regarray_table_pg[i] == 0xfe)
 458                                mdelay(50);
 459                        else if (phy_regarray_table_pg[i] == 0xfd)
 460                                mdelay(5);
 461                        else if (phy_regarray_table_pg[i] == 0xfc)
 462                                mdelay(1);
 463                        else if (phy_regarray_table_pg[i] == 0xfb)
 464                                udelay(50);
 465                        else if (phy_regarray_table_pg[i] == 0xfa)
 466                                udelay(5);
 467                        else if (phy_regarray_table_pg[i] == 0xf9)
 468                                udelay(1);
 469
 470                        store_pwrindex_diffrate_offset(hw,
 471                                                phy_regarray_table_pg[i],
 472                                                phy_regarray_table_pg[i + 1],
 473                                                phy_regarray_table_pg[i + 2]);
 474                }
 475        } else {
 476                rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE,
 477                        "configtype != BaseBand_Config_PHY_REG\n");
 478        }
 479        return true;
 480}
 481
 482bool rtl8723e_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
 483                                            enum radio_path rfpath)
 484{
 485        int i;
 486        u32 *radioa_array_table;
 487        u16 radioa_arraylen;
 488
 489        radioa_arraylen = RTL8723ERADIOA_1TARRAYLENGTH;
 490        radioa_array_table = RTL8723E_RADIOA_1TARRAY;
 491
 492        switch (rfpath) {
 493        case RF90_PATH_A:
 494                for (i = 0; i < radioa_arraylen; i = i + 2) {
 495                        if (radioa_array_table[i] == 0xfe) {
 496                                mdelay(50);
 497                        } else if (radioa_array_table[i] == 0xfd) {
 498                                mdelay(5);
 499                        } else if (radioa_array_table[i] == 0xfc) {
 500                                mdelay(1);
 501                        } else if (radioa_array_table[i] == 0xfb) {
 502                                udelay(50);
 503                        } else if (radioa_array_table[i] == 0xfa) {
 504                                udelay(5);
 505                        } else if (radioa_array_table[i] == 0xf9) {
 506                                udelay(1);
 507                        } else {
 508                                rtl_set_rfreg(hw, rfpath, radioa_array_table[i],
 509                                              RFREG_OFFSET_MASK,
 510                                              radioa_array_table[i + 1]);
 511                                udelay(1);
 512                        }
 513                }
 514                break;
 515        case RF90_PATH_B:
 516        case RF90_PATH_C:
 517        case RF90_PATH_D:
 518                break;
 519        }
 520        return true;
 521}
 522
 523void rtl8723e_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
 524{
 525        struct rtl_priv *rtlpriv = rtl_priv(hw);
 526        struct rtl_phy *rtlphy = &rtlpriv->phy;
 527
 528        rtlphy->default_initialgain[0] =
 529            (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
 530        rtlphy->default_initialgain[1] =
 531            (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
 532        rtlphy->default_initialgain[2] =
 533            (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
 534        rtlphy->default_initialgain[3] =
 535            (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
 536
 537        rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 538                "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
 539                rtlphy->default_initialgain[0],
 540                rtlphy->default_initialgain[1],
 541                rtlphy->default_initialgain[2],
 542                rtlphy->default_initialgain[3]);
 543
 544        rtlphy->framesync = (u8) rtl_get_bbreg(hw,
 545                                               ROFDM0_RXDETECTOR3, MASKBYTE0);
 546        rtlphy->framesync_c34 = rtl_get_bbreg(hw,
 547                                              ROFDM0_RXDETECTOR2, MASKDWORD);
 548
 549        rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 550                "Default framesync (0x%x) = 0x%x\n",
 551                ROFDM0_RXDETECTOR3, rtlphy->framesync);
 552}
 553
 554void rtl8723e_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
 555{
 556        struct rtl_priv *rtlpriv = rtl_priv(hw);
 557        struct rtl_phy *rtlphy = &rtlpriv->phy;
 558        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 559        u8 txpwr_level;
 560        long txpwr_dbm;
 561
 562        txpwr_level = rtlphy->cur_cck_txpwridx;
 563        txpwr_dbm = rtl8723_phy_txpwr_idx_to_dbm(hw,
 564                                                 WIRELESS_MODE_B, txpwr_level);
 565        txpwr_level = rtlphy->cur_ofdm24g_txpwridx +
 566            rtlefuse->legacy_ht_txpowerdiff;
 567        if (rtl8723_phy_txpwr_idx_to_dbm(hw,
 568                                         WIRELESS_MODE_G,
 569                                         txpwr_level) > txpwr_dbm)
 570                txpwr_dbm =
 571                    rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
 572                                                 txpwr_level);
 573        txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
 574        if (rtl8723_phy_txpwr_idx_to_dbm(hw,
 575                                         WIRELESS_MODE_N_24G,
 576                                         txpwr_level) > txpwr_dbm)
 577                txpwr_dbm =
 578                    rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
 579                                                 txpwr_level);
 580        *powerlevel = txpwr_dbm;
 581}
 582
 583static void _rtl8723e_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
 584                                        u8 *cckpowerlevel, u8 *ofdmpowerlevel)
 585{
 586        struct rtl_priv *rtlpriv = rtl_priv(hw);
 587        struct rtl_phy *rtlphy = &rtlpriv->phy;
 588        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 589        u8 index = (channel - 1);
 590
 591        cckpowerlevel[RF90_PATH_A] =
 592            rtlefuse->txpwrlevel_cck[RF90_PATH_A][index];
 593        cckpowerlevel[RF90_PATH_B] =
 594            rtlefuse->txpwrlevel_cck[RF90_PATH_B][index];
 595        if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) {
 596                ofdmpowerlevel[RF90_PATH_A] =
 597                    rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index];
 598                ofdmpowerlevel[RF90_PATH_B] =
 599                    rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index];
 600        } else if (get_rf_type(rtlphy) == RF_2T2R) {
 601                ofdmpowerlevel[RF90_PATH_A] =
 602                    rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index];
 603                ofdmpowerlevel[RF90_PATH_B] =
 604                    rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index];
 605        }
 606}
 607
 608static void _rtl8723e_ccxpower_index_check(struct ieee80211_hw *hw,
 609                                           u8 channel, u8 *cckpowerlevel,
 610                                           u8 *ofdmpowerlevel)
 611{
 612        struct rtl_priv *rtlpriv = rtl_priv(hw);
 613        struct rtl_phy *rtlphy = &rtlpriv->phy;
 614
 615        rtlphy->cur_cck_txpwridx = cckpowerlevel[0];
 616        rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0];
 617
 618}
 619
 620void rtl8723e_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
 621{
 622        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 623        u8 cckpowerlevel[2], ofdmpowerlevel[2];
 624
 625        if (!rtlefuse->txpwr_fromeprom)
 626                return;
 627        _rtl8723e_get_txpower_index(hw, channel,
 628                                    &cckpowerlevel[0], &ofdmpowerlevel[0]);
 629        _rtl8723e_ccxpower_index_check(hw,
 630                                       channel, &cckpowerlevel[0],
 631                                       &ofdmpowerlevel[0]);
 632        rtl8723e_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]);
 633        rtl8723e_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel);
 634}
 635
 636bool rtl8723e_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm)
 637{
 638        struct rtl_priv *rtlpriv = rtl_priv(hw);
 639        struct rtl_phy *rtlphy = &rtlpriv->phy;
 640        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 641        u8 idx;
 642        u8 rf_path;
 643        u8 ccktxpwridx = _rtl8723e_phy_dbm_to_txpwr_idx(hw,
 644                                                      WIRELESS_MODE_B,
 645                                                      power_indbm);
 646        u8 ofdmtxpwridx = _rtl8723e_phy_dbm_to_txpwr_idx(hw,
 647                                                       WIRELESS_MODE_N_24G,
 648                                                       power_indbm);
 649        if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0)
 650                ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff;
 651        else
 652                ofdmtxpwridx = 0;
 653        rtl_dbg(rtlpriv, COMP_TXAGC, DBG_TRACE,
 654                "%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n",
 655                power_indbm, ccktxpwridx, ofdmtxpwridx);
 656        for (idx = 0; idx < 14; idx++) {
 657                for (rf_path = 0; rf_path < 2; rf_path++) {
 658                        rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx;
 659                        rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] =
 660                            ofdmtxpwridx;
 661                        rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] =
 662                            ofdmtxpwridx;
 663                }
 664        }
 665        rtl8723e_phy_set_txpower_level(hw, rtlphy->current_channel);
 666        return true;
 667}
 668
 669static u8 _rtl8723e_phy_dbm_to_txpwr_idx(struct ieee80211_hw *hw,
 670                                         enum wireless_mode wirelessmode,
 671                                         long power_indbm)
 672{
 673        u8 txpwridx;
 674        long offset;
 675
 676        switch (wirelessmode) {
 677        case WIRELESS_MODE_B:
 678                offset = -7;
 679                break;
 680        case WIRELESS_MODE_G:
 681        case WIRELESS_MODE_N_24G:
 682                offset = -8;
 683                break;
 684        default:
 685                offset = -8;
 686                break;
 687        }
 688
 689        if ((power_indbm - offset) > 0)
 690                txpwridx = (u8)((power_indbm - offset) * 2);
 691        else
 692                txpwridx = 0;
 693
 694        if (txpwridx > MAX_TXPWR_IDX_NMODE_92S)
 695                txpwridx = MAX_TXPWR_IDX_NMODE_92S;
 696
 697        return txpwridx;
 698}
 699
 700void rtl8723e_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
 701{
 702        struct rtl_priv *rtlpriv = rtl_priv(hw);
 703        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 704        enum io_type iotype;
 705
 706        if (!is_hal_stop(rtlhal)) {
 707                switch (operation) {
 708                case SCAN_OPT_BACKUP_BAND0:
 709                        iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
 710                        rtlpriv->cfg->ops->set_hw_reg(hw,
 711                                                      HW_VAR_IO_CMD,
 712                                                      (u8 *)&iotype);
 713
 714                        break;
 715                case SCAN_OPT_RESTORE:
 716                        iotype = IO_CMD_RESUME_DM_BY_SCAN;
 717                        rtlpriv->cfg->ops->set_hw_reg(hw,
 718                                                      HW_VAR_IO_CMD,
 719                                                      (u8 *)&iotype);
 720                        break;
 721                default:
 722                        pr_err("Unknown Scan Backup operation.\n");
 723                        break;
 724                }
 725        }
 726}
 727
 728void rtl8723e_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
 729{
 730        struct rtl_priv *rtlpriv = rtl_priv(hw);
 731        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 732        struct rtl_phy *rtlphy = &rtlpriv->phy;
 733        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 734        u8 reg_bw_opmode;
 735        u8 reg_prsr_rsc;
 736
 737        rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE,
 738                "Switch to %s bandwidth\n",
 739                rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
 740                "20MHz" : "40MHz");
 741
 742        if (is_hal_stop(rtlhal)) {
 743                rtlphy->set_bwmode_inprogress = false;
 744                return;
 745        }
 746
 747        reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
 748        reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
 749
 750        switch (rtlphy->current_chan_bw) {
 751        case HT_CHANNEL_WIDTH_20:
 752                reg_bw_opmode |= BW_OPMODE_20MHZ;
 753                rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
 754                break;
 755        case HT_CHANNEL_WIDTH_20_40:
 756                reg_bw_opmode &= ~BW_OPMODE_20MHZ;
 757                rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
 758                reg_prsr_rsc =
 759                    (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5);
 760                rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
 761                break;
 762        default:
 763                pr_err("unknown bandwidth: %#X\n",
 764                       rtlphy->current_chan_bw);
 765                break;
 766        }
 767
 768        switch (rtlphy->current_chan_bw) {
 769        case HT_CHANNEL_WIDTH_20:
 770                rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
 771                rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
 772                rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);
 773                break;
 774        case HT_CHANNEL_WIDTH_20_40:
 775                rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
 776                rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
 777
 778                rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
 779                              (mac->cur_40_prime_sc >> 1));
 780                rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
 781                rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);
 782
 783                rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
 784                              (mac->cur_40_prime_sc ==
 785                               HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
 786                break;
 787        default:
 788                pr_err("unknown bandwidth: %#X\n",
 789                       rtlphy->current_chan_bw);
 790                break;
 791        }
 792        rtl8723e_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
 793        rtlphy->set_bwmode_inprogress = false;
 794        rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
 795}
 796
 797void rtl8723e_phy_set_bw_mode(struct ieee80211_hw *hw,
 798                              enum nl80211_channel_type ch_type)
 799{
 800        struct rtl_priv *rtlpriv = rtl_priv(hw);
 801        struct rtl_phy *rtlphy = &rtlpriv->phy;
 802        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 803        u8 tmp_bw = rtlphy->current_chan_bw;
 804
 805        if (rtlphy->set_bwmode_inprogress)
 806                return;
 807        rtlphy->set_bwmode_inprogress = true;
 808        if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
 809                rtl8723e_phy_set_bw_mode_callback(hw);
 810        } else {
 811                rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
 812                        "false driver sleep or unload\n");
 813                rtlphy->set_bwmode_inprogress = false;
 814                rtlphy->current_chan_bw = tmp_bw;
 815        }
 816}
 817
 818void rtl8723e_phy_sw_chnl_callback(struct ieee80211_hw *hw)
 819{
 820        struct rtl_priv *rtlpriv = rtl_priv(hw);
 821        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 822        struct rtl_phy *rtlphy = &rtlpriv->phy;
 823        u32 delay;
 824
 825        rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE,
 826                "switch to channel%d\n", rtlphy->current_channel);
 827        if (is_hal_stop(rtlhal))
 828                return;
 829        do {
 830                if (!rtlphy->sw_chnl_inprogress)
 831                        break;
 832                if (!_rtl8723e_phy_sw_chnl_step_by_step
 833                    (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage,
 834                     &rtlphy->sw_chnl_step, &delay)) {
 835                        if (delay > 0)
 836                                mdelay(delay);
 837                        else
 838                                continue;
 839                } else {
 840                        rtlphy->sw_chnl_inprogress = false;
 841                }
 842                break;
 843        } while (true);
 844        rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
 845}
 846
 847u8 rtl8723e_phy_sw_chnl(struct ieee80211_hw *hw)
 848{
 849        struct rtl_priv *rtlpriv = rtl_priv(hw);
 850        struct rtl_phy *rtlphy = &rtlpriv->phy;
 851        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 852
 853        if (rtlphy->sw_chnl_inprogress)
 854                return 0;
 855        if (rtlphy->set_bwmode_inprogress)
 856                return 0;
 857        WARN_ONCE((rtlphy->current_channel > 14),
 858                  "rtl8723ae: WIRELESS_MODE_G but channel>14");
 859        rtlphy->sw_chnl_inprogress = true;
 860        rtlphy->sw_chnl_stage = 0;
 861        rtlphy->sw_chnl_step = 0;
 862        if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
 863                rtl8723e_phy_sw_chnl_callback(hw);
 864                rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD,
 865                        "sw_chnl_inprogress false schedule workitem\n");
 866                rtlphy->sw_chnl_inprogress = false;
 867        } else {
 868                rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD,
 869                        "sw_chnl_inprogress false driver sleep or unload\n");
 870                rtlphy->sw_chnl_inprogress = false;
 871        }
 872        return 1;
 873}
 874
 875static void _rtl8723e_phy_sw_rf_seting(struct ieee80211_hw *hw, u8 channel)
 876{
 877        struct rtl_priv *rtlpriv = rtl_priv(hw);
 878        struct rtl_phy *rtlphy = &rtlpriv->phy;
 879        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 880
 881        if (IS_81XXC_VENDOR_UMC_B_CUT(rtlhal->version)) {
 882                if (channel == 6 && rtlphy->current_chan_bw ==
 883                                HT_CHANNEL_WIDTH_20)
 884                        rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1,
 885                                      MASKDWORD, 0x00255);
 886                else{
 887                        u32 backuprf0x1a = (u32)rtl_get_rfreg(hw,
 888                                        RF90_PATH_A, RF_RX_G1,
 889                                        RFREG_OFFSET_MASK);
 890                        rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1,
 891                                      MASKDWORD, backuprf0x1a);
 892                }
 893        }
 894}
 895
 896static bool _rtl8723e_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
 897                                               u8 channel, u8 *stage, u8 *step,
 898                                               u32 *delay)
 899{
 900        struct rtl_priv *rtlpriv = rtl_priv(hw);
 901        struct rtl_phy *rtlphy = &rtlpriv->phy;
 902        struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
 903        u32 precommoncmdcnt;
 904        struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
 905        u32 postcommoncmdcnt;
 906        struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
 907        u32 rfdependcmdcnt;
 908        struct swchnlcmd *currentcmd = NULL;
 909        u8 rfpath;
 910        u8 num_total_rfpath = rtlphy->num_total_rfpath;
 911
 912        precommoncmdcnt = 0;
 913        rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
 914                                         MAX_PRECMD_CNT,
 915                                         CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0);
 916        rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
 917                                         MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
 918
 919        postcommoncmdcnt = 0;
 920
 921        rtl8723_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
 922                                         MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
 923
 924        rfdependcmdcnt = 0;
 925
 926        WARN_ONCE((channel < 1 || channel > 14),
 927                  "rtl8723ae: illegal channel for Zebra: %d\n", channel);
 928
 929        rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
 930                                         MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
 931                                         RF_CHNLBW, channel, 10);
 932
 933        rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
 934                                         MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0,
 935                                         0);
 936
 937        do {
 938                switch (*stage) {
 939                case 0:
 940                        currentcmd = &precommoncmd[*step];
 941                        break;
 942                case 1:
 943                        currentcmd = &rfdependcmd[*step];
 944                        break;
 945                case 2:
 946                        currentcmd = &postcommoncmd[*step];
 947                        break;
 948                default:
 949                        pr_err("Invalid 'stage' = %d, Check it!\n",
 950                               *stage);
 951                        return true;
 952                }
 953
 954                if (currentcmd->cmdid == CMDID_END) {
 955                        if ((*stage) == 2) {
 956                                return true;
 957                        } else {
 958                                (*stage)++;
 959                                (*step) = 0;
 960                                continue;
 961                        }
 962                }
 963
 964                switch (currentcmd->cmdid) {
 965                case CMDID_SET_TXPOWEROWER_LEVEL:
 966                        rtl8723e_phy_set_txpower_level(hw, channel);
 967                        break;
 968                case CMDID_WRITEPORT_ULONG:
 969                        rtl_write_dword(rtlpriv, currentcmd->para1,
 970                                        currentcmd->para2);
 971                        break;
 972                case CMDID_WRITEPORT_USHORT:
 973                        rtl_write_word(rtlpriv, currentcmd->para1,
 974                                       (u16) currentcmd->para2);
 975                        break;
 976                case CMDID_WRITEPORT_UCHAR:
 977                        rtl_write_byte(rtlpriv, currentcmd->para1,
 978                                       (u8) currentcmd->para2);
 979                        break;
 980                case CMDID_RF_WRITEREG:
 981                        for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
 982                                rtlphy->rfreg_chnlval[rfpath] =
 983                                    ((rtlphy->rfreg_chnlval[rfpath] &
 984                                      0xfffffc00) | currentcmd->para2);
 985
 986                                rtl_set_rfreg(hw, (enum radio_path)rfpath,
 987                                              currentcmd->para1,
 988                                              RFREG_OFFSET_MASK,
 989                                              rtlphy->rfreg_chnlval[rfpath]);
 990                        }
 991                        _rtl8723e_phy_sw_rf_seting(hw, channel);
 992                        break;
 993                default:
 994                        rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,
 995                                "switch case %#x not processed\n",
 996                                currentcmd->cmdid);
 997                        break;
 998                }
 999
1000                break;
1001        } while (true);
1002
1003        (*delay) = currentcmd->msdelay;
1004        (*step)++;
1005        return false;
1006}
1007
1008static u8 _rtl8723e_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)
1009{
1010        u32 reg_eac, reg_e94, reg_e9c, reg_ea4;
1011        u8 result = 0x00;
1012
1013        rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f);
1014        rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f);
1015        rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102);
1016        rtl_set_bbreg(hw, 0xe3c, MASKDWORD,
1017                      config_pathb ? 0x28160202 : 0x28160502);
1018
1019        if (config_pathb) {
1020                rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22);
1021                rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22);
1022                rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102);
1023                rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202);
1024        }
1025
1026        rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1);
1027        rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000);
1028        rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);
1029
1030        mdelay(IQK_DELAY_TIME);
1031
1032        reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1033        reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
1034        reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
1035        reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD);
1036
1037        if (!(reg_eac & BIT(28)) &&
1038            (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1039            (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1040                result |= 0x01;
1041        else
1042                return result;
1043
1044        if (!(reg_eac & BIT(27)) &&
1045            (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
1046            (((reg_eac & 0x03FF0000) >> 16) != 0x36))
1047                result |= 0x02;
1048        return result;
1049}
1050
1051static u8 _rtl8723e_phy_path_b_iqk(struct ieee80211_hw *hw)
1052{
1053        u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc;
1054        u8 result = 0x00;
1055
1056        rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002);
1057        rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000);
1058        mdelay(IQK_DELAY_TIME);
1059        reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1060        reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD);
1061        reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD);
1062        reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD);
1063        reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD);
1064
1065        if (!(reg_eac & BIT(31)) &&
1066            (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&
1067            (((reg_ebc & 0x03FF0000) >> 16) != 0x42))
1068                result |= 0x01;
1069        else
1070                return result;
1071        if (!(reg_eac & BIT(30)) &&
1072            (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) &&
1073            (((reg_ecc & 0x03FF0000) >> 16) != 0x36))
1074                result |= 0x02;
1075        return result;
1076}
1077
1078static bool _rtl8723e_phy_simularity_compare(struct ieee80211_hw *hw,
1079                                             long result[][8], u8 c1, u8 c2)
1080{
1081        u32 i, j, diff, simularity_bitmap, bound;
1082
1083        u8 final_candidate[2] = { 0xFF, 0xFF };
1084        bool bresult = true;
1085
1086        bound = 4;
1087
1088        simularity_bitmap = 0;
1089
1090        for (i = 0; i < bound; i++) {
1091                diff = (result[c1][i] > result[c2][i]) ?
1092                    (result[c1][i] - result[c2][i]) :
1093                    (result[c2][i] - result[c1][i]);
1094
1095                if (diff > MAX_TOLERANCE) {
1096                        if ((i == 2 || i == 6) && !simularity_bitmap) {
1097                                if (result[c1][i] + result[c1][i + 1] == 0)
1098                                        final_candidate[(i / 4)] = c2;
1099                                else if (result[c2][i] + result[c2][i + 1] == 0)
1100                                        final_candidate[(i / 4)] = c1;
1101                                else
1102                                        simularity_bitmap = simularity_bitmap |
1103                                            (1 << i);
1104                        } else
1105                                simularity_bitmap =
1106                                    simularity_bitmap | (1 << i);
1107                }
1108        }
1109
1110        if (simularity_bitmap == 0) {
1111                for (i = 0; i < (bound / 4); i++) {
1112                        if (final_candidate[i] != 0xFF) {
1113                                for (j = i * 4; j < (i + 1) * 4 - 2; j++)
1114                                        result[3][j] =
1115                                            result[final_candidate[i]][j];
1116                                bresult = false;
1117                        }
1118                }
1119                return bresult;
1120        } else if (!(simularity_bitmap & 0x0F)) {
1121                for (i = 0; i < 4; i++)
1122                        result[3][i] = result[c1][i];
1123                return false;
1124        } else {
1125                return false;
1126        }
1127
1128}
1129
1130static void _rtl8723e_phy_iq_calibrate(struct ieee80211_hw *hw,
1131                                       long result[][8], u8 t, bool is2t)
1132{
1133        struct rtl_priv *rtlpriv = rtl_priv(hw);
1134        struct rtl_phy *rtlphy = &rtlpriv->phy;
1135        u32 i;
1136        u8 patha_ok, pathb_ok;
1137        u32 adda_reg[IQK_ADDA_REG_NUM] = {
1138                0x85c, 0xe6c, 0xe70, 0xe74,
1139                0xe78, 0xe7c, 0xe80, 0xe84,
1140                0xe88, 0xe8c, 0xed0, 0xed4,
1141                0xed8, 0xedc, 0xee0, 0xeec
1142        };
1143
1144        u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
1145                0x522, 0x550, 0x551, 0x040
1146        };
1147
1148        const u32 retrycount = 2;
1149
1150        if (t == 0) {
1151                rtl_get_bbreg(hw, 0x800, MASKDWORD);
1152
1153                rtl8723_save_adda_registers(hw, adda_reg,
1154                                            rtlphy->adda_backup, 16);
1155                rtl8723_phy_save_mac_registers(hw, iqk_mac_reg,
1156                                               rtlphy->iqk_mac_backup);
1157        }
1158        rtl8723_phy_path_adda_on(hw, adda_reg, true, is2t);
1159        if (t == 0) {
1160                rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw,
1161                                        RFPGA0_XA_HSSIPARAMETER1,
1162                                        BIT(8));
1163        }
1164
1165        if (!rtlphy->rfpi_enable)
1166                rtl8723_phy_pi_mode_switch(hw, true);
1167        if (t == 0) {
1168                rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD);
1169                rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD);
1170                rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD);
1171        }
1172        rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
1173        rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
1174        rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
1175        if (is2t) {
1176                rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
1177                rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000);
1178        }
1179        rtl8723_phy_mac_setting_calibration(hw, iqk_mac_reg,
1180                                            rtlphy->iqk_mac_backup);
1181        rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000);
1182        if (is2t)
1183                rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000);
1184        rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1185        rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00);
1186        rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800);
1187        for (i = 0; i < retrycount; i++) {
1188                patha_ok = _rtl8723e_phy_path_a_iqk(hw, is2t);
1189                if (patha_ok == 0x03) {
1190                        result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
1191                                        0x3FF0000) >> 16;
1192                        result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
1193                                        0x3FF0000) >> 16;
1194                        result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &
1195                                        0x3FF0000) >> 16;
1196                        result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &
1197                                        0x3FF0000) >> 16;
1198                        break;
1199                } else if (i == (retrycount - 1) && patha_ok == 0x01)
1200
1201                        result[t][0] = (rtl_get_bbreg(hw, 0xe94,
1202                                                      MASKDWORD) & 0x3FF0000) >>
1203                            16;
1204                result[t][1] =
1205                    (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16;
1206
1207        }
1208
1209        if (is2t) {
1210                rtl8723_phy_path_a_standby(hw);
1211                rtl8723_phy_path_adda_on(hw, adda_reg, false, is2t);
1212                for (i = 0; i < retrycount; i++) {
1213                        pathb_ok = _rtl8723e_phy_path_b_iqk(hw);
1214                        if (pathb_ok == 0x03) {
1215                                result[t][4] = (rtl_get_bbreg(hw,
1216                                                              0xeb4,
1217                                                              MASKDWORD) &
1218                                                0x3FF0000) >> 16;
1219                                result[t][5] =
1220                                    (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
1221                                     0x3FF0000) >> 16;
1222                                result[t][6] =
1223                                    (rtl_get_bbreg(hw, 0xec4, MASKDWORD) &
1224                                     0x3FF0000) >> 16;
1225                                result[t][7] =
1226                                    (rtl_get_bbreg(hw, 0xecc, MASKDWORD) &
1227                                     0x3FF0000) >> 16;
1228                                break;
1229                        } else if (i == (retrycount - 1) && pathb_ok == 0x01) {
1230                                result[t][4] = (rtl_get_bbreg(hw,
1231                                                              0xeb4,
1232                                                              MASKDWORD) &
1233                                                0x3FF0000) >> 16;
1234                        }
1235                        result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
1236                                        0x3FF0000) >> 16;
1237                }
1238        }
1239        rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04);
1240        rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874);
1241        rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08);
1242        rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);
1243        rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3);
1244        if (is2t)
1245                rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3);
1246        if (t != 0) {
1247                if (!rtlphy->rfpi_enable)
1248                        rtl8723_phy_pi_mode_switch(hw, false);
1249                rtl8723_phy_reload_adda_registers(hw, adda_reg,
1250                                                  rtlphy->adda_backup, 16);
1251                rtl8723_phy_reload_mac_registers(hw, iqk_mac_reg,
1252                                                 rtlphy->iqk_mac_backup);
1253        }
1254}
1255
1256static void _rtl8723e_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
1257{
1258        u8 tmpreg;
1259        u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
1260        struct rtl_priv *rtlpriv = rtl_priv(hw);
1261
1262        tmpreg = rtl_read_byte(rtlpriv, 0xd03);
1263
1264        if ((tmpreg & 0x70) != 0)
1265                rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
1266        else
1267                rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
1268
1269        if ((tmpreg & 0x70) != 0) {
1270                rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
1271
1272                if (is2t)
1273                        rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
1274                                                  MASK12BITS);
1275
1276                rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
1277                              (rf_a_mode & 0x8FFFF) | 0x10000);
1278
1279                if (is2t)
1280                        rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
1281                                      (rf_b_mode & 0x8FFFF) | 0x10000);
1282        }
1283        lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
1284
1285        rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000);
1286
1287        mdelay(100);
1288
1289        if ((tmpreg & 0x70) != 0) {
1290                rtl_write_byte(rtlpriv, 0xd03, tmpreg);
1291                rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
1292
1293                if (is2t)
1294                        rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
1295                                      rf_b_mode);
1296        } else {
1297                rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1298        }
1299}
1300
1301static void _rtl8723e_phy_set_rfpath_switch(struct ieee80211_hw *hw,
1302                                            bool bmain, bool is2t)
1303{
1304        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1305
1306        if (is_hal_stop(rtlhal)) {
1307                rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01);
1308                rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(13), 0x01);
1309        }
1310        if (is2t) {
1311                if (bmain)
1312                        rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1313                                      BIT(5) | BIT(6), 0x1);
1314                else
1315                        rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1316                                      BIT(5) | BIT(6), 0x2);
1317        } else {
1318                if (bmain)
1319                        rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2);
1320                else
1321                        rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1);
1322
1323        }
1324
1325}
1326
1327#undef IQK_ADDA_REG_NUM
1328#undef IQK_DELAY_TIME
1329
1330void rtl8723e_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
1331{
1332        struct rtl_priv *rtlpriv = rtl_priv(hw);
1333        struct rtl_phy *rtlphy = &rtlpriv->phy;
1334
1335        long result[4][8];
1336        u8 i, final_candidate;
1337        bool b_patha_ok;
1338        long reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc,
1339           reg_tmp = 0;
1340        bool is12simular, is13simular, is23simular;
1341        u32 iqk_bb_reg[10] = {
1342                ROFDM0_XARXIQIMBALANCE,
1343                ROFDM0_XBRXIQIMBALANCE,
1344                ROFDM0_ECCATHRESHOLD,
1345                ROFDM0_AGCRSSITABLE,
1346                ROFDM0_XATXIQIMBALANCE,
1347                ROFDM0_XBTXIQIMBALANCE,
1348                ROFDM0_XCTXIQIMBALANCE,
1349                ROFDM0_XCTXAFE,
1350                ROFDM0_XDTXAFE,
1351                ROFDM0_RXIQEXTANTA
1352        };
1353
1354        if (b_recovery) {
1355                rtl8723_phy_reload_adda_registers(hw,
1356                                                  iqk_bb_reg,
1357                                                  rtlphy->iqk_bb_backup, 10);
1358                return;
1359        }
1360        for (i = 0; i < 8; i++) {
1361                result[0][i] = 0;
1362                result[1][i] = 0;
1363                result[2][i] = 0;
1364                result[3][i] = 0;
1365        }
1366        final_candidate = 0xff;
1367        b_patha_ok = false;
1368        is12simular = false;
1369        is23simular = false;
1370        is13simular = false;
1371        for (i = 0; i < 3; i++) {
1372                _rtl8723e_phy_iq_calibrate(hw, result, i, false);
1373                if (i == 1) {
1374                        is12simular =
1375                          _rtl8723e_phy_simularity_compare(hw, result, 0, 1);
1376                        if (is12simular) {
1377                                final_candidate = 0;
1378                                break;
1379                        }
1380                }
1381                if (i == 2) {
1382                        is13simular =
1383                          _rtl8723e_phy_simularity_compare(hw, result, 0, 2);
1384                        if (is13simular) {
1385                                final_candidate = 0;
1386                                break;
1387                        }
1388                        is23simular =
1389                          _rtl8723e_phy_simularity_compare(hw, result, 1, 2);
1390                        if (is23simular)
1391                                final_candidate = 1;
1392                        else {
1393                                for (i = 0; i < 8; i++)
1394                                        reg_tmp += result[3][i];
1395
1396                                if (reg_tmp != 0)
1397                                        final_candidate = 3;
1398                                else
1399                                        final_candidate = 0xFF;
1400                        }
1401                }
1402        }
1403        for (i = 0; i < 4; i++) {
1404                reg_e94 = result[i][0];
1405                reg_e9c = result[i][1];
1406                reg_ea4 = result[i][2];
1407                reg_eb4 = result[i][4];
1408                reg_ebc = result[i][5];
1409        }
1410        if (final_candidate != 0xff) {
1411                rtlphy->reg_e94 = reg_e94 = result[final_candidate][0];
1412                rtlphy->reg_e9c = reg_e9c = result[final_candidate][1];
1413                reg_ea4 = result[final_candidate][2];
1414                rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4];
1415                rtlphy->reg_ebc = reg_ebc = result[final_candidate][5];
1416                b_patha_ok = true;
1417        } else {
1418                rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100;
1419                rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0;
1420        }
1421        if (reg_e94 != 0)
1422                rtl8723_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result,
1423                                                   final_candidate,
1424                                                   (reg_ea4 == 0));
1425        rtl8723_save_adda_registers(hw, iqk_bb_reg,
1426                                    rtlphy->iqk_bb_backup, 10);
1427}
1428
1429void rtl8723e_phy_lc_calibrate(struct ieee80211_hw *hw)
1430{
1431        _rtl8723e_phy_lc_calibrate(hw, false);
1432}
1433
1434void rtl8723e_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
1435{
1436        _rtl8723e_phy_set_rfpath_switch(hw, bmain, false);
1437}
1438
1439bool rtl8723e_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
1440{
1441        struct rtl_priv *rtlpriv = rtl_priv(hw);
1442        struct rtl_phy *rtlphy = &rtlpriv->phy;
1443        bool postprocessing = false;
1444
1445        rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE,
1446                "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
1447                iotype, rtlphy->set_io_inprogress);
1448        do {
1449                switch (iotype) {
1450                case IO_CMD_RESUME_DM_BY_SCAN:
1451                        rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE,
1452                                "[IO CMD] Resume DM after scan.\n");
1453                        postprocessing = true;
1454                        break;
1455                case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
1456                        rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE,
1457                                "[IO CMD] Pause DM before scan.\n");
1458                        postprocessing = true;
1459                        break;
1460                default:
1461                        rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,
1462                                "switch case %#x not processed\n", iotype);
1463                        break;
1464                }
1465        } while (false);
1466        if (postprocessing && !rtlphy->set_io_inprogress) {
1467                rtlphy->set_io_inprogress = true;
1468                rtlphy->current_io_type = iotype;
1469        } else {
1470                return false;
1471        }
1472        rtl8723e_phy_set_io(hw);
1473        rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
1474        return true;
1475}
1476
1477static void rtl8723e_phy_set_io(struct ieee80211_hw *hw)
1478{
1479        struct rtl_priv *rtlpriv = rtl_priv(hw);
1480        struct rtl_phy *rtlphy = &rtlpriv->phy;
1481        struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
1482
1483        rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE,
1484                "--->Cmd(%#x), set_io_inprogress(%d)\n",
1485                rtlphy->current_io_type, rtlphy->set_io_inprogress);
1486        switch (rtlphy->current_io_type) {
1487        case IO_CMD_RESUME_DM_BY_SCAN:
1488                dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1;
1489                rtl8723e_dm_write_dig(hw);
1490                rtl8723e_phy_set_txpower_level(hw, rtlphy->current_channel);
1491                break;
1492        case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
1493                rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
1494                dm_digtable->cur_igvalue = 0x17;
1495                rtl8723e_dm_write_dig(hw);
1496                break;
1497        default:
1498                rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,
1499                        "switch case %#x not processed\n",
1500                        rtlphy->current_io_type);
1501                break;
1502        }
1503        rtlphy->set_io_inprogress = false;
1504        rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE,
1505                "(%#x)\n", rtlphy->current_io_type);
1506}
1507
1508static void rtl8723e_phy_set_rf_on(struct ieee80211_hw *hw)
1509{
1510        struct rtl_priv *rtlpriv = rtl_priv(hw);
1511
1512        rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
1513        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
1514        rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
1515        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
1516        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
1517        rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1518}
1519
1520static void _rtl8723e_phy_set_rf_sleep(struct ieee80211_hw *hw)
1521{
1522        u32 u4b_tmp;
1523        u8 delay = 5;
1524        struct rtl_priv *rtlpriv = rtl_priv(hw);
1525
1526        rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
1527        rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
1528        rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
1529        u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
1530        while (u4b_tmp != 0 && delay > 0) {
1531                rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0);
1532                rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
1533                rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
1534                u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
1535                delay--;
1536        }
1537        if (delay == 0) {
1538                rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
1539                rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
1540                rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
1541                rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1542                rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE,
1543                        "Switch RF timeout !!!.\n");
1544                return;
1545        }
1546        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
1547        rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
1548}
1549
1550static bool _rtl8723e_phy_set_rf_power_state(struct ieee80211_hw *hw,
1551                                             enum rf_pwrstate rfpwr_state)
1552{
1553        struct rtl_priv *rtlpriv = rtl_priv(hw);
1554        struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
1555        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1556        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1557        bool bresult = true;
1558        u8 i, queue_id;
1559        struct rtl8192_tx_ring *ring = NULL;
1560
1561        switch (rfpwr_state) {
1562        case ERFON:
1563                if ((ppsc->rfpwr_state == ERFOFF) &&
1564                    RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
1565                        bool rtstatus;
1566                        u32 initializecount = 0;
1567
1568                        do {
1569                                initializecount++;
1570                                rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,
1571                                        "IPS Set eRf nic enable\n");
1572                                rtstatus = rtl_ps_enable_nic(hw);
1573                        } while (!rtstatus && (initializecount < 10));
1574                        RT_CLEAR_PS_LEVEL(ppsc,
1575                                          RT_RF_OFF_LEVL_HALT_NIC);
1576                } else {
1577                        rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,
1578                                "Set ERFON slept:%d ms\n",
1579                                jiffies_to_msecs(jiffies -
1580                                           ppsc->last_sleep_jiffies));
1581                        ppsc->last_awake_jiffies = jiffies;
1582                        rtl8723e_phy_set_rf_on(hw);
1583                }
1584                if (mac->link_state == MAC80211_LINKED) {
1585                        rtlpriv->cfg->ops->led_control(hw,
1586                                                       LED_CTL_LINK);
1587                } else {
1588                        rtlpriv->cfg->ops->led_control(hw,
1589                                                       LED_CTL_NO_LINK);
1590                }
1591                break;
1592        case ERFOFF:
1593                if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
1594                        rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,
1595                                "IPS Set eRf nic disable\n");
1596                        rtl_ps_disable_nic(hw);
1597                        RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
1598                } else {
1599                        if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
1600                                rtlpriv->cfg->ops->led_control(hw,
1601                                                LED_CTL_NO_LINK);
1602                        } else {
1603                                rtlpriv->cfg->ops->led_control(hw,
1604                                                LED_CTL_POWER_OFF);
1605                        }
1606                }
1607                break;
1608        case ERFSLEEP:
1609                if (ppsc->rfpwr_state == ERFOFF)
1610                        break;
1611                for (queue_id = 0, i = 0;
1612                     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
1613                        ring = &pcipriv->dev.tx_ring[queue_id];
1614                        if (queue_id == BEACON_QUEUE ||
1615                            skb_queue_len(&ring->queue) == 0) {
1616                                queue_id++;
1617                                continue;
1618                        } else {
1619                                rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
1620                                        "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
1621                                        (i + 1), queue_id,
1622                                        skb_queue_len(&ring->queue));
1623
1624                                udelay(10);
1625                                i++;
1626                        }
1627                        if (i >= MAX_DOZE_WAITING_TIMES_9x) {
1628                                rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
1629                                        "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
1630                                        MAX_DOZE_WAITING_TIMES_9x,
1631                                        queue_id,
1632                                        skb_queue_len(&ring->queue));
1633                                break;
1634                        }
1635                }
1636                rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,
1637                        "Set ERFSLEEP awaked:%d ms\n",
1638                        jiffies_to_msecs(jiffies -
1639                           ppsc->last_awake_jiffies));
1640                ppsc->last_sleep_jiffies = jiffies;
1641                _rtl8723e_phy_set_rf_sleep(hw);
1642                break;
1643        default:
1644                rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,
1645                        "switch case %#x not processed\n", rfpwr_state);
1646                bresult = false;
1647                break;
1648        }
1649        if (bresult)
1650                ppsc->rfpwr_state = rfpwr_state;
1651        return bresult;
1652}
1653
1654bool rtl8723e_phy_set_rf_power_state(struct ieee80211_hw *hw,
1655                                     enum rf_pwrstate rfpwr_state)
1656{
1657        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1658
1659        bool bresult = false;
1660
1661        if (rfpwr_state == ppsc->rfpwr_state)
1662                return bresult;
1663        bresult = _rtl8723e_phy_set_rf_power_state(hw, rfpwr_state);
1664        return bresult;
1665}
1666