linux/drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright(c) 2009-2014  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 "../rtl8723com/phy_common.h"
  11#include "rf.h"
  12#include "dm.h"
  13#include "../rtl8723com/dm_common.h"
  14#include "table.h"
  15#include "trx.h"
  16#include <linux/kernel.h>
  17
  18static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw);
  19static bool _rtl8723be_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
  20static bool _rtl8723be_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
  21                                                     u8 configtype);
  22static bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
  23                                                       u8 configtype);
  24static bool _rtl8723be_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
  25                                                u8 channel, u8 *stage,
  26                                                u8 *step, u32 *delay);
  27
  28static void rtl8723be_phy_set_rf_on(struct ieee80211_hw *hw);
  29static void rtl8723be_phy_set_io(struct ieee80211_hw *hw);
  30
  31u32 rtl8723be_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
  32                               u32 regaddr, u32 bitmask)
  33{
  34        struct rtl_priv *rtlpriv = rtl_priv(hw);
  35        u32 original_value, readback_value, bitshift;
  36        unsigned long flags;
  37
  38        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
  39                 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
  40                  regaddr, rfpath, bitmask);
  41
  42        spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
  43
  44        original_value = rtl8723_phy_rf_serial_read(hw, rfpath, regaddr);
  45        bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
  46        readback_value = (original_value & bitmask) >> bitshift;
  47
  48        spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
  49
  50        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
  51                 "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
  52                 regaddr, rfpath, bitmask, original_value);
  53
  54        return readback_value;
  55}
  56
  57void rtl8723be_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path path,
  58                              u32 regaddr, u32 bitmask, u32 data)
  59{
  60        struct rtl_priv *rtlpriv = rtl_priv(hw);
  61        u32 original_value, bitshift;
  62        unsigned long flags;
  63
  64        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
  65                 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
  66                  regaddr, bitmask, data, path);
  67
  68        spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
  69
  70        if (bitmask != RFREG_OFFSET_MASK) {
  71                        original_value = rtl8723_phy_rf_serial_read(hw, path,
  72                                                                    regaddr);
  73                        bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
  74                        data = ((original_value & (~bitmask)) |
  75                                (data << bitshift));
  76                }
  77
  78        rtl8723_phy_rf_serial_write(hw, path, regaddr, data);
  79
  80        spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
  81
  82        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
  83                 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
  84                  regaddr, bitmask, data, path);
  85
  86}
  87
  88bool rtl8723be_phy_mac_config(struct ieee80211_hw *hw)
  89{
  90        struct rtl_priv *rtlpriv = rtl_priv(hw);
  91        bool rtstatus = _rtl8723be_phy_config_mac_with_headerfile(hw);
  92
  93        rtl_write_byte(rtlpriv, 0x04CA, 0x0B);
  94        return rtstatus;
  95}
  96
  97bool rtl8723be_phy_bb_config(struct ieee80211_hw *hw)
  98{
  99        bool rtstatus = true;
 100        struct rtl_priv *rtlpriv = rtl_priv(hw);
 101        u16 regval;
 102        u8 b_reg_hwparafile = 1;
 103        u32 tmp;
 104        u8 crystalcap = rtlpriv->efuse.crystalcap;
 105        rtl8723_phy_init_bb_rf_reg_def(hw);
 106        regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
 107        rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
 108                       regval | BIT(13) | BIT(0) | BIT(1));
 109
 110        rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
 111        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
 112                       FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE |
 113                       FEN_BB_GLB_RSTN | FEN_BBRSTB);
 114        tmp = rtl_read_dword(rtlpriv, 0x4c);
 115        rtl_write_dword(rtlpriv, 0x4c, tmp | BIT(23));
 116
 117        rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
 118
 119        if (b_reg_hwparafile == 1)
 120                rtstatus = _rtl8723be_phy_bb8723b_config_parafile(hw);
 121
 122        crystalcap = crystalcap & 0x3F;
 123        rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
 124                      (crystalcap | crystalcap << 6));
 125
 126        return rtstatus;
 127}
 128
 129bool rtl8723be_phy_rf_config(struct ieee80211_hw *hw)
 130{
 131        return rtl8723be_phy_rf6052_config(hw);
 132}
 133
 134static bool _rtl8723be_check_positive(struct ieee80211_hw *hw,
 135                                      const u32 condition1,
 136                                      const u32 condition2)
 137{
 138        struct rtl_priv *rtlpriv = rtl_priv(hw);
 139        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
 140        u32 cut_ver = ((rtlhal->version & CHIP_VER_RTL_MASK)
 141                                        >> CHIP_VER_RTL_SHIFT);
 142        u32 intf = (rtlhal->interface == INTF_USB ? BIT(1) : BIT(0));
 143
 144        u8  board_type = ((rtlhal->board_type & BIT(4)) >> 4) << 0 | /* _GLNA */
 145                         ((rtlhal->board_type & BIT(3)) >> 3) << 1 | /* _GPA  */
 146                         ((rtlhal->board_type & BIT(7)) >> 7) << 2 | /* _ALNA */
 147                         ((rtlhal->board_type & BIT(6)) >> 6) << 3 | /* _APA  */
 148                         ((rtlhal->board_type & BIT(2)) >> 2) << 4;  /* _BT   */
 149
 150        u32 cond1 = condition1, cond2 = condition2;
 151        u32 driver1 = cut_ver << 24 |   /* CUT ver */
 152                      0 << 20 |                 /* interface 2/2 */
 153                      0x04 << 16 |              /* platform */
 154                      rtlhal->package_type << 12 |
 155                      intf << 8 |                       /* interface 1/2 */
 156                      board_type;
 157
 158        u32 driver2 = rtlhal->type_glna <<  0 |
 159                      rtlhal->type_gpa  <<  8 |
 160                      rtlhal->type_alna << 16 |
 161                      rtlhal->type_apa  << 24;
 162
 163        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 164                 "===> [8812A] CheckPositive (cond1, cond2) = (0x%X 0x%X)\n",
 165                 cond1, cond2);
 166        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 167                 "===> [8812A] CheckPositive (driver1, driver2) = (0x%X 0x%X)\n",
 168                 driver1, driver2);
 169
 170        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 171                 "      (Platform, Interface) = (0x%X, 0x%X)\n", 0x04, intf);
 172        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 173                 "      (Board, Package) = (0x%X, 0x%X)\n",
 174                 rtlhal->board_type, rtlhal->package_type);
 175
 176        /*============== Value Defined Check ===============*/
 177        /*QFN Type [15:12] and Cut Version [27:24] need to do value check*/
 178
 179        if (((cond1 & 0x0000F000) != 0) && ((cond1 & 0x0000F000) !=
 180                (driver1 & 0x0000F000)))
 181                return false;
 182        if (((cond1 & 0x0F000000) != 0) && ((cond1 & 0x0F000000) !=
 183                (driver1 & 0x0F000000)))
 184                return false;
 185
 186        /*=============== Bit Defined Check ================*/
 187        /* We don't care [31:28] */
 188
 189        cond1   &= 0x00FF0FFF;
 190        driver1 &= 0x00FF0FFF;
 191
 192        if ((cond1 & driver1) == cond1) {
 193                u32 mask = 0;
 194
 195                if ((cond1 & 0x0F) == 0) /* BoardType is DONTCARE*/
 196                        return true;
 197
 198                if ((cond1 & BIT(0)) != 0) /*GLNA*/
 199                        mask |= 0x000000FF;
 200                if ((cond1 & BIT(1)) != 0) /*GPA*/
 201                        mask |= 0x0000FF00;
 202                if ((cond1 & BIT(2)) != 0) /*ALNA*/
 203                        mask |= 0x00FF0000;
 204                if ((cond1 & BIT(3)) != 0) /*APA*/
 205                        mask |= 0xFF000000;
 206
 207                /* BoardType of each RF path is matched*/
 208                if ((cond2 & mask) == (driver2 & mask))
 209                        return true;
 210                else
 211                        return false;
 212        }
 213        return false;
 214}
 215
 216static void _rtl8723be_config_rf_reg(struct ieee80211_hw *hw, u32 addr,
 217                                     u32 data, enum radio_path rfpath,
 218                                     u32 regaddr)
 219{
 220        if (addr == 0xfe || addr == 0xffe) {
 221                /* In order not to disturb BT music
 222                 *      when wifi init.(1ant NIC only)
 223                 */
 224                mdelay(50);
 225        } else {
 226                rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data);
 227                udelay(1);
 228        }
 229}
 230static void _rtl8723be_config_rf_radio_a(struct ieee80211_hw *hw,
 231                                         u32 addr, u32 data)
 232{
 233        u32 content = 0x1000; /*RF Content: radio_a_txt*/
 234        u32 maskforphyset = (u32)(content & 0xE000);
 235
 236        _rtl8723be_config_rf_reg(hw, addr, data, RF90_PATH_A,
 237                                 addr | maskforphyset);
 238
 239}
 240
 241static void _rtl8723be_phy_init_tx_power_by_rate(struct ieee80211_hw *hw)
 242{
 243        struct rtl_priv *rtlpriv = rtl_priv(hw);
 244        struct rtl_phy *rtlphy = &rtlpriv->phy;
 245
 246        u8 band, path, txnum, section;
 247
 248        for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band)
 249                for (path = 0; path < TX_PWR_BY_RATE_NUM_RF; ++path)
 250                        for (txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum)
 251                                for (section = 0;
 252                                     section < TX_PWR_BY_RATE_NUM_SECTION;
 253                                     ++section)
 254                                        rtlphy->tx_power_by_rate_offset
 255                                          [band][path][txnum][section] = 0;
 256}
 257
 258static void _rtl8723be_config_bb_reg(struct ieee80211_hw *hw,
 259                                     u32 addr, u32 data)
 260{
 261        if (addr == 0xfe) {
 262                mdelay(50);
 263        } else if (addr == 0xfd) {
 264                mdelay(5);
 265        } else if (addr == 0xfc) {
 266                mdelay(1);
 267        } else if (addr == 0xfb) {
 268                udelay(50);
 269        } else if (addr == 0xfa) {
 270                udelay(5);
 271        } else if (addr == 0xf9) {
 272                udelay(1);
 273        } else {
 274                rtl_set_bbreg(hw, addr, MASKDWORD, data);
 275                udelay(1);
 276        }
 277}
 278
 279static void _rtl8723be_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw,
 280                                                    u8 band,
 281                                                    u8 path, u8 rate_section,
 282                                                    u8 txnum, u8 value)
 283{
 284        struct rtl_priv *rtlpriv = rtl_priv(hw);
 285        struct rtl_phy *rtlphy = &rtlpriv->phy;
 286
 287        if (path > RF90_PATH_D) {
 288                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 289                         "Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n",
 290                          path);
 291                return;
 292        }
 293
 294        if (band == BAND_ON_2_4G) {
 295                switch (rate_section) {
 296                case CCK:
 297                        rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value;
 298                        break;
 299                case OFDM:
 300                        rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value;
 301                        break;
 302                case HT_MCS0_MCS7:
 303                        rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value;
 304                        break;
 305                case HT_MCS8_MCS15:
 306                        rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value;
 307                        break;
 308                default:
 309                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 310                                 "Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n",
 311                                 rate_section, path, txnum);
 312                        break;
 313                }
 314        } else {
 315                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 316                         "Invalid Band %d in PHY_SetTxPowerByRateBase()\n",
 317                         band);
 318        }
 319
 320}
 321
 322static u8 _rtl8723be_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw,
 323                                                  u8 band, u8 path, u8 txnum,
 324                                                  u8 rate_section)
 325{
 326        struct rtl_priv *rtlpriv = rtl_priv(hw);
 327        struct rtl_phy *rtlphy = &rtlpriv->phy;
 328        u8 value = 0;
 329        if (path > RF90_PATH_D) {
 330                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 331                         "Invalid Rf Path %d in PHY_GetTxPowerByRateBase()\n",
 332                          path);
 333                return 0;
 334        }
 335
 336        if (band == BAND_ON_2_4G) {
 337                switch (rate_section) {
 338                case CCK:
 339                        value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0];
 340                        break;
 341                case OFDM:
 342                        value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1];
 343                        break;
 344                case HT_MCS0_MCS7:
 345                        value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2];
 346                        break;
 347                case HT_MCS8_MCS15:
 348                        value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3];
 349                        break;
 350                default:
 351                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 352                                 "Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n",
 353                                 rate_section, path, txnum);
 354                        break;
 355                }
 356        } else {
 357                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 358                         "Invalid Band %d in PHY_GetTxPowerByRateBase()\n",
 359                         band);
 360        }
 361
 362        return value;
 363}
 364
 365static void _rtl8723be_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw)
 366{
 367        struct rtl_priv *rtlpriv = rtl_priv(hw);
 368        struct rtl_phy *rtlphy = &rtlpriv->phy;
 369        u16 rawvalue = 0;
 370        u8 base = 0, path = 0;
 371
 372        for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) {
 373                if (path == RF90_PATH_A) {
 374                        rawvalue = (u16)(rtlphy->tx_power_by_rate_offset
 375                                [BAND_ON_2_4G][path][RF_1TX][3] >> 24) & 0xFF;
 376                        base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
 377                        _rtl8723be_phy_set_txpower_by_rate_base(hw,
 378                                BAND_ON_2_4G, path, CCK, RF_1TX, base);
 379                } else if (path == RF90_PATH_B) {
 380                        rawvalue = (u16)(rtlphy->tx_power_by_rate_offset
 381                                [BAND_ON_2_4G][path][RF_1TX][3] >> 0) & 0xFF;
 382                        base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
 383                        _rtl8723be_phy_set_txpower_by_rate_base(hw,
 384                                                                BAND_ON_2_4G,
 385                                                                path, CCK,
 386                                                                RF_1TX, base);
 387                }
 388                rawvalue = (u16)(rtlphy->tx_power_by_rate_offset
 389                                [BAND_ON_2_4G][path][RF_1TX][1] >> 24) & 0xFF;
 390                base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
 391                _rtl8723be_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G,
 392                                                        path, OFDM, RF_1TX,
 393                                                        base);
 394
 395                rawvalue = (u16)(rtlphy->tx_power_by_rate_offset
 396                                [BAND_ON_2_4G][path][RF_1TX][5] >> 24) & 0xFF;
 397                base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
 398                _rtl8723be_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G,
 399                                                        path, HT_MCS0_MCS7,
 400                                                        RF_1TX, base);
 401
 402                rawvalue = (u16)(rtlphy->tx_power_by_rate_offset
 403                                [BAND_ON_2_4G][path][RF_2TX][7] >> 24) & 0xFF;
 404                base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
 405                _rtl8723be_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G,
 406                                                        path, HT_MCS8_MCS15,
 407                                                        RF_2TX, base);
 408        }
 409}
 410
 411static void _phy_convert_txpower_dbm_to_relative_value(u32 *data, u8 start,
 412                                                u8 end, u8 base_val)
 413{
 414        s8 i = 0;
 415        u8 temp_value = 0;
 416        u32 temp_data = 0;
 417
 418        for (i = 3; i >= 0; --i) {
 419                if (i >= start && i <= end) {
 420                        /* Get the exact value */
 421                        temp_value = (u8)(*data >> (i * 8)) & 0xF;
 422                        temp_value += ((u8)((*data >> (i*8 + 4)) & 0xF)) * 10;
 423
 424                        /* Change the value to a relative value */
 425                        temp_value = (temp_value > base_val) ?
 426                                     temp_value - base_val :
 427                                     base_val - temp_value;
 428                } else {
 429                        temp_value = (u8)(*data >> (i * 8)) & 0xFF;
 430                }
 431                temp_data <<= 8;
 432                temp_data |= temp_value;
 433        }
 434        *data = temp_data;
 435}
 436
 437static void _rtl8723be_phy_convert_txpower_dbm_to_relative_value(
 438                                                        struct ieee80211_hw *hw)
 439{
 440        struct rtl_priv *rtlpriv = rtl_priv(hw);
 441        struct rtl_phy *rtlphy = &rtlpriv->phy;
 442        u8 base = 0, rfpath = RF90_PATH_A;
 443
 444        base = _rtl8723be_phy_get_txpower_by_rate_base(hw,
 445                        BAND_ON_2_4G, rfpath, RF_1TX, CCK);
 446        _phy_convert_txpower_dbm_to_relative_value(
 447            &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][2],
 448            1, 1, base);
 449        _phy_convert_txpower_dbm_to_relative_value(
 450            &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][3],
 451            1, 3, base);
 452
 453        base = _rtl8723be_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfpath,
 454                                                       RF_1TX, OFDM);
 455        _phy_convert_txpower_dbm_to_relative_value(
 456            &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][0],
 457            0, 3, base);
 458        _phy_convert_txpower_dbm_to_relative_value(
 459            &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][1],
 460            0, 3, base);
 461
 462        base = _rtl8723be_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G,
 463                                                rfpath, RF_1TX, HT_MCS0_MCS7);
 464        _phy_convert_txpower_dbm_to_relative_value(
 465            &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][4],
 466            0, 3, base);
 467        _phy_convert_txpower_dbm_to_relative_value(
 468            &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][5],
 469            0, 3, base);
 470
 471        base = _rtl8723be_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G,
 472                                                       rfpath, RF_2TX,
 473                                                       HT_MCS8_MCS15);
 474        _phy_convert_txpower_dbm_to_relative_value(
 475            &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_2TX][6],
 476            0, 3, base);
 477
 478        _phy_convert_txpower_dbm_to_relative_value(
 479            &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_2TX][7],
 480            0, 3, base);
 481
 482        RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
 483            "<===_rtl8723be_phy_convert_txpower_dbm_to_relative_value()\n");
 484}
 485
 486static void phy_txpower_by_rate_config(struct ieee80211_hw *hw)
 487{
 488        _rtl8723be_phy_store_txpower_by_rate_base(hw);
 489        _rtl8723be_phy_convert_txpower_dbm_to_relative_value(hw);
 490}
 491
 492static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw)
 493{
 494        struct rtl_priv *rtlpriv = rtl_priv(hw);
 495        struct rtl_phy *rtlphy = &rtlpriv->phy;
 496        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 497        bool rtstatus;
 498
 499        /* switch ant to BT */
 500        if (rtlpriv->rtlhal.interface == INTF_USB) {
 501                rtl_write_dword(rtlpriv, 0x948, 0x0);
 502        } else {
 503                if (rtlpriv->btcoexist.btc_info.single_ant_path == 0)
 504                        rtl_write_dword(rtlpriv, 0x948, 0x280);
 505                else
 506                        rtl_write_dword(rtlpriv, 0x948, 0x0);
 507        }
 508
 509        rtstatus = _rtl8723be_phy_config_bb_with_headerfile(hw,
 510                                                BASEBAND_CONFIG_PHY_REG);
 511        if (!rtstatus) {
 512                pr_err("Write BB Reg Fail!!\n");
 513                return false;
 514        }
 515        _rtl8723be_phy_init_tx_power_by_rate(hw);
 516        if (!rtlefuse->autoload_failflag) {
 517                rtlphy->pwrgroup_cnt = 0;
 518                rtstatus = _rtl8723be_phy_config_bb_with_pgheaderfile(hw,
 519                                                BASEBAND_CONFIG_PHY_REG);
 520        }
 521        phy_txpower_by_rate_config(hw);
 522        if (!rtstatus) {
 523                pr_err("BB_PG Reg Fail!!\n");
 524                return false;
 525        }
 526        rtstatus = _rtl8723be_phy_config_bb_with_headerfile(hw,
 527                                                BASEBAND_CONFIG_AGC_TAB);
 528        if (!rtstatus) {
 529                pr_err("AGC Table Fail\n");
 530                return false;
 531        }
 532        rtlphy->cck_high_power = (bool)(rtl_get_bbreg(hw,
 533                                                      RFPGA0_XA_HSSIPARAMETER2,
 534                                                      0x200));
 535        return true;
 536}
 537
 538static bool rtl8723be_phy_config_with_headerfile(struct ieee80211_hw *hw,
 539                                                 u32 *array_table,
 540                                                 u16 arraylen,
 541                void (*set_reg)(struct ieee80211_hw *hw, u32 regaddr, u32 data))
 542{
 543        #define COND_ELSE  2
 544        #define COND_ENDIF 3
 545
 546        int i = 0;
 547        u8 cond;
 548        bool matched = true, skipped = false;
 549
 550        while ((i + 1) < arraylen) {
 551                u32 v1 = array_table[i];
 552                u32 v2 = array_table[i + 1];
 553
 554                if (v1 & (BIT(31) | BIT(30))) {/*positive & negative condition*/
 555                        if (v1 & BIT(31)) {/* positive condition*/
 556                                cond  = (u8)((v1 & (BIT(29) | BIT(28))) >> 28);
 557                                if (cond == COND_ENDIF) { /*end*/
 558                                        matched = true;
 559                                        skipped = false;
 560                                } else if (cond == COND_ELSE) { /*else*/
 561                                        matched = skipped ? false : true;
 562                                } else {/*if , else if*/
 563                                        if (skipped) {
 564                                                matched = false;
 565                                        } else {
 566                                                if (_rtl8723be_check_positive(
 567                                                                hw, v1, v2)) {
 568                                                        matched = true;
 569                                                        skipped = true;
 570                                                } else {
 571                                                        matched = false;
 572                                                        skipped = false;
 573                                                }
 574                                        }
 575                                }
 576                        } else if (v1 & BIT(30)) { /*negative condition*/
 577                        /*do nothing*/
 578                        }
 579                } else {
 580                        if (matched)
 581                                set_reg(hw, v1, v2);
 582                }
 583                i = i + 2;
 584        }
 585
 586        return true;
 587}
 588
 589static bool _rtl8723be_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
 590{
 591        struct rtl_priv *rtlpriv = rtl_priv(hw);
 592
 593        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read rtl8723beMACPHY_Array\n");
 594
 595        return rtl8723be_phy_config_with_headerfile(hw,
 596                        RTL8723BEMAC_1T_ARRAY, RTL8723BEMAC_1T_ARRAYLEN,
 597                        rtl_write_byte_with_val32);
 598}
 599
 600static bool _rtl8723be_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
 601                                                     u8 configtype)
 602{
 603
 604        if (configtype == BASEBAND_CONFIG_PHY_REG)
 605                return rtl8723be_phy_config_with_headerfile(hw,
 606                                RTL8723BEPHY_REG_1TARRAY,
 607                                RTL8723BEPHY_REG_1TARRAYLEN,
 608                                _rtl8723be_config_bb_reg);
 609        else if (configtype == BASEBAND_CONFIG_AGC_TAB)
 610                return rtl8723be_phy_config_with_headerfile(hw,
 611                                RTL8723BEAGCTAB_1TARRAY,
 612                                RTL8723BEAGCTAB_1TARRAYLEN,
 613                                rtl_set_bbreg_with_dwmask);
 614
 615        return false;
 616}
 617
 618static u8 _rtl8723be_get_rate_section_index(u32 regaddr)
 619{
 620        u8 index = 0;
 621
 622        switch (regaddr) {
 623        case RTXAGC_A_RATE18_06:
 624                index = 0;
 625        break;
 626        case RTXAGC_A_RATE54_24:
 627                index = 1;
 628        break;
 629        case RTXAGC_A_CCK1_MCS32:
 630                index = 2;
 631        break;
 632        case RTXAGC_B_CCK11_A_CCK2_11:
 633                index = 3;
 634        break;
 635        case RTXAGC_A_MCS03_MCS00:
 636                index = 4;
 637        break;
 638        case RTXAGC_A_MCS07_MCS04:
 639                index = 5;
 640        break;
 641        case RTXAGC_A_MCS11_MCS08:
 642                index = 6;
 643        break;
 644        case RTXAGC_A_MCS15_MCS12:
 645                index = 7;
 646        break;
 647        case RTXAGC_B_RATE18_06:
 648                index = 0;
 649        break;
 650        case RTXAGC_B_RATE54_24:
 651                index = 1;
 652        break;
 653        case RTXAGC_B_CCK1_55_MCS32:
 654                index = 2;
 655        break;
 656        case RTXAGC_B_MCS03_MCS00:
 657                index = 4;
 658        break;
 659        case RTXAGC_B_MCS07_MCS04:
 660                index = 5;
 661        break;
 662        case RTXAGC_B_MCS11_MCS08:
 663                index = 6;
 664        break;
 665        case RTXAGC_B_MCS15_MCS12:
 666                index = 7;
 667        break;
 668        default:
 669                regaddr &= 0xFFF;
 670                if (regaddr >= 0xC20 && regaddr <= 0xC4C)
 671                        index = (u8)((regaddr - 0xC20) / 4);
 672                else if (regaddr >= 0xE20 && regaddr <= 0xE4C)
 673                        index = (u8)((regaddr - 0xE20) / 4);
 674                break;
 675        }
 676        return index;
 677}
 678
 679static void _rtl8723be_store_tx_power_by_rate(struct ieee80211_hw *hw,
 680                                              u32 band, u32 rfpath,
 681                                              u32 txnum, u32 regaddr,
 682                                              u32 bitmask, u32 data)
 683{
 684        struct rtl_priv *rtlpriv = rtl_priv(hw);
 685        struct rtl_phy *rtlphy = &rtlpriv->phy;
 686        u8 rate_section = _rtl8723be_get_rate_section_index(regaddr);
 687
 688        if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
 689                RT_TRACE(rtlpriv, FPHY, PHY_TXPWR, "Invalid Band %d\n", band);
 690                return;
 691        }
 692        if (rfpath > MAX_RF_PATH - 1) {
 693                RT_TRACE(rtlpriv, FPHY, PHY_TXPWR,
 694                         "Invalid RfPath %d\n", rfpath);
 695                return;
 696        }
 697        if (txnum > MAX_RF_PATH - 1) {
 698                RT_TRACE(rtlpriv, FPHY, PHY_TXPWR, "Invalid TxNum %d\n", txnum);
 699                return;
 700        }
 701
 702        rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] =
 703                                                                        data;
 704
 705}
 706
 707static bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
 708                                                       u8 configtype)
 709{
 710        struct rtl_priv *rtlpriv = rtl_priv(hw);
 711        int i;
 712        u32 *phy_regarray_table_pg;
 713        u16 phy_regarray_pg_len;
 714        u32 v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0, v6 = 0;
 715
 716        phy_regarray_pg_len = RTL8723BEPHY_REG_ARRAY_PGLEN;
 717        phy_regarray_table_pg = RTL8723BEPHY_REG_ARRAY_PG;
 718
 719        if (configtype == BASEBAND_CONFIG_PHY_REG) {
 720                for (i = 0; i < phy_regarray_pg_len; i = i + 6) {
 721                        v1 = phy_regarray_table_pg[i];
 722                        v2 = phy_regarray_table_pg[i+1];
 723                        v3 = phy_regarray_table_pg[i+2];
 724                        v4 = phy_regarray_table_pg[i+3];
 725                        v5 = phy_regarray_table_pg[i+4];
 726                        v6 = phy_regarray_table_pg[i+5];
 727
 728                        if (v1 < 0xcdcdcdcd) {
 729                                if (phy_regarray_table_pg[i] == 0xfe ||
 730                                    phy_regarray_table_pg[i] == 0xffe)
 731                                        mdelay(50);
 732                                else
 733                                        _rtl8723be_store_tx_power_by_rate(hw,
 734                                                        v1, v2, v3, v4, v5, v6);
 735                                continue;
 736                        }
 737                }
 738        } else {
 739                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
 740                         "configtype != BaseBand_Config_PHY_REG\n");
 741        }
 742        return true;
 743}
 744
 745bool rtl8723be_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
 746                                             enum radio_path rfpath)
 747{
 748        struct rtl_priv *rtlpriv = rtl_priv(hw);
 749        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 750        bool ret = true;
 751
 752        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
 753        switch (rfpath) {
 754        case RF90_PATH_A:
 755                ret =  rtl8723be_phy_config_with_headerfile(hw,
 756                                RTL8723BE_RADIOA_1TARRAY,
 757                                RTL8723BE_RADIOA_1TARRAYLEN,
 758                                _rtl8723be_config_rf_radio_a);
 759
 760                if (rtlhal->oem_id == RT_CID_819X_HP)
 761                        _rtl8723be_config_rf_radio_a(hw, 0x52, 0x7E4BD);
 762                break;
 763        case RF90_PATH_B:
 764        case RF90_PATH_C:
 765                break;
 766        case RF90_PATH_D:
 767                RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
 768                         "switch case %#x not processed\n", rfpath);
 769                break;
 770        }
 771        return ret;
 772}
 773
 774void rtl8723be_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
 775{
 776        struct rtl_priv *rtlpriv = rtl_priv(hw);
 777        struct rtl_phy *rtlphy = &rtlpriv->phy;
 778
 779        rtlphy->default_initialgain[0] =
 780            (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
 781        rtlphy->default_initialgain[1] =
 782            (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
 783        rtlphy->default_initialgain[2] =
 784            (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
 785        rtlphy->default_initialgain[3] =
 786            (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
 787
 788        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 789                 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
 790                 rtlphy->default_initialgain[0],
 791                 rtlphy->default_initialgain[1],
 792                 rtlphy->default_initialgain[2],
 793                 rtlphy->default_initialgain[3]);
 794
 795        rtlphy->framesync = (u8)rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3,
 796                                               MASKBYTE0);
 797        rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
 798                                              MASKDWORD);
 799
 800        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 801                 "Default framesync (0x%x) = 0x%x\n",
 802                  ROFDM0_RXDETECTOR3, rtlphy->framesync);
 803}
 804
 805static u8 _rtl8723be_phy_get_ratesection_intxpower_byrate(enum radio_path path,
 806                                                          u8 rate)
 807{
 808        u8 rate_section = 0;
 809
 810        switch (rate) {
 811        case DESC92C_RATE1M:
 812                rate_section = 2;
 813                break;
 814
 815        case DESC92C_RATE2M:
 816        case DESC92C_RATE5_5M:
 817                if (path == RF90_PATH_A)
 818                        rate_section = 3;
 819                else if (path == RF90_PATH_B)
 820                        rate_section = 2;
 821                break;
 822
 823        case DESC92C_RATE11M:
 824                rate_section = 3;
 825                break;
 826
 827        case DESC92C_RATE6M:
 828        case DESC92C_RATE9M:
 829        case DESC92C_RATE12M:
 830        case DESC92C_RATE18M:
 831                rate_section = 0;
 832                break;
 833
 834        case DESC92C_RATE24M:
 835        case DESC92C_RATE36M:
 836        case DESC92C_RATE48M:
 837        case DESC92C_RATE54M:
 838                rate_section = 1;
 839                break;
 840
 841        case DESC92C_RATEMCS0:
 842        case DESC92C_RATEMCS1:
 843        case DESC92C_RATEMCS2:
 844        case DESC92C_RATEMCS3:
 845                rate_section = 4;
 846                break;
 847
 848        case DESC92C_RATEMCS4:
 849        case DESC92C_RATEMCS5:
 850        case DESC92C_RATEMCS6:
 851        case DESC92C_RATEMCS7:
 852                rate_section = 5;
 853                break;
 854
 855        case DESC92C_RATEMCS8:
 856        case DESC92C_RATEMCS9:
 857        case DESC92C_RATEMCS10:
 858        case DESC92C_RATEMCS11:
 859                rate_section = 6;
 860                break;
 861
 862        case DESC92C_RATEMCS12:
 863        case DESC92C_RATEMCS13:
 864        case DESC92C_RATEMCS14:
 865        case DESC92C_RATEMCS15:
 866                rate_section = 7;
 867                break;
 868
 869        default:
 870                WARN_ONCE(true, "rtl8723be: Rate_Section is Illegal\n");
 871                break;
 872        }
 873
 874        return rate_section;
 875}
 876
 877static u8 _rtl8723be_get_txpower_by_rate(struct ieee80211_hw *hw,
 878                                         enum band_type band,
 879                                         enum radio_path rfpath, u8 rate)
 880{
 881        struct rtl_priv *rtlpriv = rtl_priv(hw);
 882        struct rtl_phy *rtlphy = &rtlpriv->phy;
 883        u8 shift = 0, rate_section, tx_num;
 884        s8 tx_pwr_diff = 0;
 885
 886        rate_section = _rtl8723be_phy_get_ratesection_intxpower_byrate(rfpath,
 887                                                                       rate);
 888        tx_num = RF_TX_NUM_NONIMPLEMENT;
 889
 890        if (tx_num == RF_TX_NUM_NONIMPLEMENT) {
 891                if (rate >= DESC92C_RATEMCS8 && rate <= DESC92C_RATEMCS15)
 892                        tx_num = RF_2TX;
 893                else
 894                        tx_num = RF_1TX;
 895        }
 896
 897        switch (rate) {
 898        case DESC92C_RATE6M:
 899        case DESC92C_RATE24M:
 900        case DESC92C_RATEMCS0:
 901        case DESC92C_RATEMCS4:
 902        case DESC92C_RATEMCS8:
 903        case DESC92C_RATEMCS12:
 904                shift = 0;
 905                break;
 906        case DESC92C_RATE1M:
 907        case DESC92C_RATE2M:
 908        case DESC92C_RATE9M:
 909        case DESC92C_RATE36M:
 910        case DESC92C_RATEMCS1:
 911        case DESC92C_RATEMCS5:
 912        case DESC92C_RATEMCS9:
 913        case DESC92C_RATEMCS13:
 914                shift = 8;
 915                break;
 916        case DESC92C_RATE5_5M:
 917        case DESC92C_RATE12M:
 918        case DESC92C_RATE48M:
 919        case DESC92C_RATEMCS2:
 920        case DESC92C_RATEMCS6:
 921        case DESC92C_RATEMCS10:
 922        case DESC92C_RATEMCS14:
 923                shift = 16;
 924                break;
 925        case DESC92C_RATE11M:
 926        case DESC92C_RATE18M:
 927        case DESC92C_RATE54M:
 928        case DESC92C_RATEMCS3:
 929        case DESC92C_RATEMCS7:
 930        case DESC92C_RATEMCS11:
 931        case DESC92C_RATEMCS15:
 932                shift = 24;
 933                break;
 934        default:
 935                WARN_ONCE(true, "rtl8723be: Rate_Section is Illegal\n");
 936                break;
 937        }
 938        tx_pwr_diff = (u8)(rtlphy->tx_power_by_rate_offset[band][rfpath][tx_num]
 939                                          [rate_section] >> shift) & 0xff;
 940
 941        return  tx_pwr_diff;
 942}
 943
 944static u8 _rtl8723be_get_txpower_index(struct ieee80211_hw *hw, u8 path,
 945                                       u8 rate, u8 bandwidth, u8 channel)
 946{
 947        struct rtl_priv *rtlpriv = rtl_priv(hw);
 948        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 949        u8 index = (channel - 1);
 950        u8 txpower = 0;
 951        u8 power_diff_byrate = 0;
 952
 953        if (channel > 14 || channel < 1) {
 954                index = 0;
 955                RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
 956                         "Illegal channel!\n");
 957        }
 958        if (RX_HAL_IS_CCK_RATE(rate))
 959                txpower = rtlefuse->txpwrlevel_cck[path][index];
 960        else if (DESC92C_RATE6M <= rate)
 961                txpower = rtlefuse->txpwrlevel_ht40_1s[path][index];
 962        else
 963                RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
 964                         "invalid rate\n");
 965
 966        if (DESC92C_RATE6M <= rate && rate <= DESC92C_RATE54M &&
 967            !RX_HAL_IS_CCK_RATE(rate))
 968                txpower += rtlefuse->txpwr_legacyhtdiff[0][TX_1S];
 969
 970        if (bandwidth == HT_CHANNEL_WIDTH_20) {
 971                if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
 972                        txpower += rtlefuse->txpwr_ht20diff[0][TX_1S];
 973                if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
 974                        txpower += rtlefuse->txpwr_ht20diff[0][TX_2S];
 975        } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
 976                if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
 977                        txpower += rtlefuse->txpwr_ht40diff[0][TX_1S];
 978                if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
 979                        txpower += rtlefuse->txpwr_ht40diff[0][TX_2S];
 980        }
 981
 982        if (rtlefuse->eeprom_regulatory != 2)
 983                power_diff_byrate = _rtl8723be_get_txpower_by_rate(hw,
 984                                                                   BAND_ON_2_4G,
 985                                                                   path, rate);
 986
 987        txpower += power_diff_byrate;
 988
 989        if (txpower > MAX_POWER_INDEX)
 990                txpower = MAX_POWER_INDEX;
 991
 992        return txpower;
 993}
 994
 995static void _rtl8723be_phy_set_txpower_index(struct ieee80211_hw *hw,
 996                                             u8 power_index, u8 path, u8 rate)
 997{
 998        struct rtl_priv *rtlpriv = rtl_priv(hw);
 999        if (path == RF90_PATH_A) {
1000                switch (rate) {
1001                case DESC92C_RATE1M:
1002                        rtl8723_phy_set_bb_reg(hw, RTXAGC_A_CCK1_MCS32,
1003                                               MASKBYTE1, power_index);
1004                        break;
1005                case DESC92C_RATE2M:
1006                        rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1007                                               MASKBYTE1, power_index);
1008                        break;
1009                case DESC92C_RATE5_5M:
1010                        rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1011                                               MASKBYTE2, power_index);
1012                        break;
1013                case DESC92C_RATE11M:
1014                        rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1015                                               MASKBYTE3, power_index);
1016                        break;
1017
1018                case DESC92C_RATE6M:
1019                        rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1020                                               MASKBYTE0, power_index);
1021                        break;
1022                case DESC92C_RATE9M:
1023                        rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1024                                               MASKBYTE1, power_index);
1025                        break;
1026                case DESC92C_RATE12M:
1027                        rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1028                                               MASKBYTE2, power_index);
1029                        break;
1030                case DESC92C_RATE18M:
1031                        rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1032                                               MASKBYTE3, power_index);
1033                        break;
1034
1035                case DESC92C_RATE24M:
1036                        rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1037                                               MASKBYTE0, power_index);
1038                        break;
1039                case DESC92C_RATE36M:
1040                        rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1041                                               MASKBYTE1, power_index);
1042                        break;
1043                case DESC92C_RATE48M:
1044                        rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1045                                               MASKBYTE2, power_index);
1046                        break;
1047                case DESC92C_RATE54M:
1048                        rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1049                                               MASKBYTE3, power_index);
1050                        break;
1051
1052                case DESC92C_RATEMCS0:
1053                        rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1054                                               MASKBYTE0, power_index);
1055                        break;
1056                case DESC92C_RATEMCS1:
1057                        rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1058                                               MASKBYTE1, power_index);
1059                        break;
1060                case DESC92C_RATEMCS2:
1061                        rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1062                                               MASKBYTE2, power_index);
1063                        break;
1064                case DESC92C_RATEMCS3:
1065                        rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1066                                               MASKBYTE3, power_index);
1067                        break;
1068
1069                case DESC92C_RATEMCS4:
1070                        rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1071                                               MASKBYTE0, power_index);
1072                        break;
1073                case DESC92C_RATEMCS5:
1074                        rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1075                                               MASKBYTE1, power_index);
1076                        break;
1077                case DESC92C_RATEMCS6:
1078                        rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1079                                               MASKBYTE2, power_index);
1080                        break;
1081                case DESC92C_RATEMCS7:
1082                        rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1083                                               MASKBYTE3, power_index);
1084                        break;
1085
1086                case DESC92C_RATEMCS8:
1087                        rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1088                                               MASKBYTE0, power_index);
1089                        break;
1090                case DESC92C_RATEMCS9:
1091                        rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1092                                               MASKBYTE1, power_index);
1093                        break;
1094                case DESC92C_RATEMCS10:
1095                        rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1096                                               MASKBYTE2, power_index);
1097                        break;
1098                case DESC92C_RATEMCS11:
1099                        rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1100                                               MASKBYTE3, power_index);
1101                        break;
1102
1103                default:
1104                        RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid Rate!!\n");
1105                        break;
1106                }
1107        } else {
1108                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid RFPath!!\n");
1109        }
1110}
1111
1112void rtl8723be_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
1113{
1114        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1115        u8 cck_rates[]  = {DESC92C_RATE1M, DESC92C_RATE2M,
1116                           DESC92C_RATE5_5M, DESC92C_RATE11M};
1117        u8 ofdm_rates[]  = {DESC92C_RATE6M, DESC92C_RATE9M,
1118                            DESC92C_RATE12M, DESC92C_RATE18M,
1119                            DESC92C_RATE24M, DESC92C_RATE36M,
1120                            DESC92C_RATE48M, DESC92C_RATE54M};
1121        u8 ht_rates_1t[]  = {DESC92C_RATEMCS0, DESC92C_RATEMCS1,
1122                             DESC92C_RATEMCS2, DESC92C_RATEMCS3,
1123                             DESC92C_RATEMCS4, DESC92C_RATEMCS5,
1124                             DESC92C_RATEMCS6, DESC92C_RATEMCS7};
1125        u8 i;
1126        u8 power_index;
1127
1128        if (!rtlefuse->txpwr_fromeprom)
1129                return;
1130
1131        for (i = 0; i < ARRAY_SIZE(cck_rates); i++) {
1132                power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1133                                        cck_rates[i],
1134                                        rtl_priv(hw)->phy.current_chan_bw,
1135                                        channel);
1136                _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1137                                                 cck_rates[i]);
1138        }
1139        for (i = 0; i < ARRAY_SIZE(ofdm_rates); i++) {
1140                power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1141                                        ofdm_rates[i],
1142                                        rtl_priv(hw)->phy.current_chan_bw,
1143                                        channel);
1144                _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1145                                                 ofdm_rates[i]);
1146        }
1147        for (i = 0; i < ARRAY_SIZE(ht_rates_1t); i++) {
1148                power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1149                                        ht_rates_1t[i],
1150                                        rtl_priv(hw)->phy.current_chan_bw,
1151                                        channel);
1152                _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1153                                                 ht_rates_1t[i]);
1154        }
1155}
1156
1157void rtl8723be_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
1158{
1159        struct rtl_priv *rtlpriv = rtl_priv(hw);
1160        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1161        enum io_type iotype;
1162
1163        if (!is_hal_stop(rtlhal)) {
1164                switch (operation) {
1165                case SCAN_OPT_BACKUP_BAND0:
1166                        iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
1167                        rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1168                                                      (u8 *)&iotype);
1169
1170                        break;
1171                case SCAN_OPT_RESTORE:
1172                        iotype = IO_CMD_RESUME_DM_BY_SCAN;
1173                        rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1174                                                      (u8 *)&iotype);
1175                        break;
1176                default:
1177                        pr_err("Unknown Scan Backup operation.\n");
1178                        break;
1179                }
1180        }
1181}
1182
1183void rtl8723be_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
1184{
1185        struct rtl_priv *rtlpriv = rtl_priv(hw);
1186        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1187        struct rtl_phy *rtlphy = &rtlpriv->phy;
1188        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1189        u8 reg_bw_opmode;
1190        u8 reg_prsr_rsc;
1191
1192        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1193                 "Switch to %s bandwidth\n",
1194                  rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
1195                  "20MHz" : "40MHz");
1196
1197        if (is_hal_stop(rtlhal)) {
1198                rtlphy->set_bwmode_inprogress = false;
1199                return;
1200        }
1201
1202        reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
1203        reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
1204
1205        switch (rtlphy->current_chan_bw) {
1206        case HT_CHANNEL_WIDTH_20:
1207                reg_bw_opmode |= BW_OPMODE_20MHZ;
1208                rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1209                break;
1210        case HT_CHANNEL_WIDTH_20_40:
1211                reg_bw_opmode &= ~BW_OPMODE_20MHZ;
1212                rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1213                reg_prsr_rsc = (reg_prsr_rsc & 0x90) |
1214                               (mac->cur_40_prime_sc << 5);
1215                rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
1216                break;
1217        default:
1218                pr_err("unknown bandwidth: %#X\n",
1219                       rtlphy->current_chan_bw);
1220                break;
1221        }
1222
1223        switch (rtlphy->current_chan_bw) {
1224        case HT_CHANNEL_WIDTH_20:
1225                rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
1226                rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
1227        /*      rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);*/
1228                break;
1229        case HT_CHANNEL_WIDTH_20_40:
1230                rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
1231                rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
1232
1233                rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
1234                              (mac->cur_40_prime_sc >> 1));
1235                rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
1236                /*rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);*/
1237
1238                rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
1239                              (mac->cur_40_prime_sc ==
1240                               HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
1241                break;
1242        default:
1243                pr_err("unknown bandwidth: %#X\n",
1244                       rtlphy->current_chan_bw);
1245                break;
1246        }
1247        rtl8723be_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
1248        rtlphy->set_bwmode_inprogress = false;
1249        RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
1250}
1251
1252void rtl8723be_phy_set_bw_mode(struct ieee80211_hw *hw,
1253                            enum nl80211_channel_type ch_type)
1254{
1255        struct rtl_priv *rtlpriv = rtl_priv(hw);
1256        struct rtl_phy *rtlphy = &rtlpriv->phy;
1257        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1258        u8 tmp_bw = rtlphy->current_chan_bw;
1259
1260        if (rtlphy->set_bwmode_inprogress)
1261                return;
1262        rtlphy->set_bwmode_inprogress = true;
1263        if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1264                rtl8723be_phy_set_bw_mode_callback(hw);
1265        } else {
1266                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1267                         "false driver sleep or unload\n");
1268                rtlphy->set_bwmode_inprogress = false;
1269                rtlphy->current_chan_bw = tmp_bw;
1270        }
1271}
1272
1273void rtl8723be_phy_sw_chnl_callback(struct ieee80211_hw *hw)
1274{
1275        struct rtl_priv *rtlpriv = rtl_priv(hw);
1276        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1277        struct rtl_phy *rtlphy = &rtlpriv->phy;
1278        u32 delay = 0;
1279
1280        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1281                 "switch to channel%d\n", rtlphy->current_channel);
1282        if (is_hal_stop(rtlhal))
1283                return;
1284        do {
1285                if (!rtlphy->sw_chnl_inprogress)
1286                        break;
1287                if (!_rtl8723be_phy_sw_chnl_step_by_step(hw,
1288                                                         rtlphy->current_channel,
1289                                                         &rtlphy->sw_chnl_stage,
1290                                                         &rtlphy->sw_chnl_step,
1291                                                         &delay)) {
1292                        if (delay > 0)
1293                                mdelay(delay);
1294                        else
1295                                continue;
1296                } else {
1297                        rtlphy->sw_chnl_inprogress = false;
1298                }
1299                break;
1300        } while (true);
1301        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
1302}
1303
1304u8 rtl8723be_phy_sw_chnl(struct ieee80211_hw *hw)
1305{
1306        struct rtl_priv *rtlpriv = rtl_priv(hw);
1307        struct rtl_phy *rtlphy = &rtlpriv->phy;
1308        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1309
1310        if (rtlphy->sw_chnl_inprogress)
1311                return 0;
1312        if (rtlphy->set_bwmode_inprogress)
1313                return 0;
1314        WARN_ONCE((rtlphy->current_channel > 14),
1315                  "rtl8723be: WIRELESS_MODE_G but channel>14");
1316        rtlphy->sw_chnl_inprogress = true;
1317        rtlphy->sw_chnl_stage = 0;
1318        rtlphy->sw_chnl_step = 0;
1319        if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1320                rtl8723be_phy_sw_chnl_callback(hw);
1321                RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1322                         "sw_chnl_inprogress false schedule workitem current channel %d\n",
1323                         rtlphy->current_channel);
1324                rtlphy->sw_chnl_inprogress = false;
1325        } else {
1326                RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1327                         "sw_chnl_inprogress false driver sleep or unload\n");
1328                rtlphy->sw_chnl_inprogress = false;
1329        }
1330        return 1;
1331}
1332
1333static bool _rtl8723be_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
1334                                                u8 channel, u8 *stage,
1335                                                u8 *step, u32 *delay)
1336{
1337        struct rtl_priv *rtlpriv = rtl_priv(hw);
1338        struct rtl_phy *rtlphy = &rtlpriv->phy;
1339        struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
1340        u32 precommoncmdcnt;
1341        struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
1342        u32 postcommoncmdcnt;
1343        struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
1344        u32 rfdependcmdcnt;
1345        struct swchnlcmd *currentcmd = NULL;
1346        u8 rfpath;
1347        u8 num_total_rfpath = rtlphy->num_total_rfpath;
1348
1349        precommoncmdcnt = 0;
1350        rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1351                                         MAX_PRECMD_CNT,
1352                                         CMDID_SET_TXPOWEROWER_LEVEL,
1353                                         0, 0, 0);
1354        rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1355                                         MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
1356
1357        postcommoncmdcnt = 0;
1358
1359        rtl8723_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
1360                                         MAX_POSTCMD_CNT, CMDID_END,
1361                                            0, 0, 0);
1362
1363        rfdependcmdcnt = 0;
1364
1365        WARN_ONCE((channel < 1 || channel > 14),
1366                  "rtl8723be: illegal channel for Zebra: %d\n", channel);
1367
1368        rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1369                                         MAX_RFDEPENDCMD_CNT,
1370                                         CMDID_RF_WRITEREG,
1371                                         RF_CHNLBW, channel, 10);
1372
1373        rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1374                                         MAX_RFDEPENDCMD_CNT,
1375                                            CMDID_END, 0, 0, 0);
1376
1377        do {
1378                switch (*stage) {
1379                case 0:
1380                        currentcmd = &precommoncmd[*step];
1381                        break;
1382                case 1:
1383                        currentcmd = &rfdependcmd[*step];
1384                        break;
1385                case 2:
1386                        currentcmd = &postcommoncmd[*step];
1387                        break;
1388                default:
1389                        pr_err("Invalid 'stage' = %d, Check it!\n",
1390                               *stage);
1391                        return true;
1392                }
1393
1394                if (currentcmd->cmdid == CMDID_END) {
1395                        if ((*stage) == 2) {
1396                                return true;
1397                        } else {
1398                                (*stage)++;
1399                                (*step) = 0;
1400                                continue;
1401                        }
1402                }
1403
1404                switch (currentcmd->cmdid) {
1405                case CMDID_SET_TXPOWEROWER_LEVEL:
1406                        rtl8723be_phy_set_txpower_level(hw, channel);
1407                        break;
1408                case CMDID_WRITEPORT_ULONG:
1409                        rtl_write_dword(rtlpriv, currentcmd->para1,
1410                                        currentcmd->para2);
1411                        break;
1412                case CMDID_WRITEPORT_USHORT:
1413                        rtl_write_word(rtlpriv, currentcmd->para1,
1414                                       (u16)currentcmd->para2);
1415                        break;
1416                case CMDID_WRITEPORT_UCHAR:
1417                        rtl_write_byte(rtlpriv, currentcmd->para1,
1418                                       (u8)currentcmd->para2);
1419                        break;
1420                case CMDID_RF_WRITEREG:
1421                        for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
1422                                rtlphy->rfreg_chnlval[rfpath] =
1423                                    ((rtlphy->rfreg_chnlval[rfpath] &
1424                                      0xfffffc00) | currentcmd->para2);
1425
1426                                rtl_set_rfreg(hw, (enum radio_path)rfpath,
1427                                              currentcmd->para1,
1428                                              RFREG_OFFSET_MASK,
1429                                              rtlphy->rfreg_chnlval[rfpath]);
1430                        }
1431                        break;
1432                default:
1433                        RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
1434                                 "switch case %#x not processed\n",
1435                                 currentcmd->cmdid);
1436                        break;
1437                }
1438
1439                break;
1440        } while (true);
1441
1442        (*delay) = currentcmd->msdelay;
1443        (*step)++;
1444        return false;
1445}
1446
1447static u8 _rtl8723be_phy_path_a_iqk(struct ieee80211_hw *hw)
1448{
1449        u32 reg_eac, reg_e94, reg_e9c, tmp;
1450        u8 result = 0x00;
1451
1452        /* leave IQK mode */
1453        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1454        /* switch to path A */
1455        rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000000);
1456        /* enable path A PA in TXIQK mode */
1457        rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
1458        rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x20000);
1459        rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0003f);
1460        rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xc7f87);
1461
1462        /* 1. TX IQK */
1463        /* path-A IQK setting */
1464        /* IQK setting */
1465        rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1466        rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1467        /* path-A IQK setting */
1468        rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1469        rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1470        rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1471        rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1472
1473        rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x821403ea);
1474        rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28160000);
1475        rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1476        rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1477        /* LO calibration setting */
1478        rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911);
1479        /* enter IQK mode */
1480        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1481
1482        /* One shot, path A LOK & IQK */
1483        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1484        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1485
1486        mdelay(IQK_DELAY_TIME);
1487
1488        /* leave IQK mode */
1489        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1490
1491        /* Check failed */
1492        reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1493        reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
1494        reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
1495
1496        if (!(reg_eac & BIT(28)) &&
1497            (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1498            (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1499                result |= 0x01;
1500        else /* if Tx not OK, ignore Rx */
1501                return result;
1502
1503        /* Allen 20131125 */
1504        tmp = (reg_e9c & 0x03FF0000) >> 16;
1505        if ((tmp & 0x200) > 0)
1506                tmp = 0x400 - tmp;
1507
1508        if (!(reg_eac & BIT(28)) &&
1509            (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1510            (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1511            (tmp < 0xf))
1512                result |= 0x01;
1513        else /* if Tx not OK, ignore Rx */
1514                return result;
1515
1516        return result;
1517}
1518
1519/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
1520static u8 _rtl8723be_phy_path_a_rx_iqk(struct ieee80211_hw *hw)
1521{
1522        u32 reg_eac, reg_e94, reg_e9c, reg_ea4, u32tmp, tmp;
1523        u8 result = 0x00;
1524
1525        /* leave IQK mode */
1526        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1527
1528        /* switch to path A */
1529        rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000000);
1530
1531        /* 1 Get TXIMR setting */
1532        /* modify RXIQK mode table */
1533        rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1534        rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1535        rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1536        /* LNA2 off, PA on for Dcut */
1537        rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7fb7);
1538        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1539
1540        /* IQK setting */
1541        rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1542        rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1543
1544        /* path-A IQK setting */
1545        rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1546        rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1547        rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1548        rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1549
1550        rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160ff0);
1551        rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000);
1552        rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1553        rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1554
1555        /* LO calibration setting */
1556        rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
1557
1558        /* enter IQK mode */
1559        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1560
1561        /* One shot, path A LOK & IQK */
1562        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1563        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1564
1565        mdelay(IQK_DELAY_TIME);
1566
1567        /* leave IQK mode */
1568        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1569
1570        /* Check failed */
1571        reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1572        reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1573        reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1574
1575        if (!(reg_eac & BIT(28)) &&
1576            (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1577            (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1578                result |= 0x01;
1579        else /* if Tx not OK, ignore Rx */
1580                return result;
1581
1582        /* Allen 20131125 */
1583        tmp = (reg_e9c & 0x03FF0000) >> 16;
1584        if ((tmp & 0x200) > 0)
1585                tmp = 0x400 - tmp;
1586
1587        if (!(reg_eac & BIT(28)) &&
1588            (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1589            (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1590            (tmp < 0xf))
1591                result |= 0x01;
1592        else /* if Tx not OK, ignore Rx */
1593                return result;
1594
1595        u32tmp = 0x80007C00 | (reg_e94 & 0x3FF0000) |
1596                 ((reg_e9c & 0x3FF0000) >> 16);
1597        rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32tmp);
1598
1599        /* 1 RX IQK */
1600        /* modify RXIQK mode table */
1601        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1602        rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1603        rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1604        rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1605        /* LAN2 on, PA off for Dcut */
1606        rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7d77);
1607
1608        /* PA, PAD setting */
1609        rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0xf80);
1610        rtl_set_rfreg(hw, RF90_PATH_A, 0x55, RFREG_OFFSET_MASK, 0x4021f);
1611
1612        /* IQK setting */
1613        rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1614
1615        /* path-A IQK setting */
1616        rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1617        rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1618        rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1619        rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1620
1621        rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82110000);
1622        rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x2816001f);
1623        rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1624        rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1625
1626        /* LO calibration setting */
1627        rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a8d1);
1628
1629        /* enter IQK mode */
1630        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1631
1632        /* One shot, path A LOK & IQK */
1633        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1634        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1635
1636        mdelay(IQK_DELAY_TIME);
1637
1638        /* leave IQK mode */
1639        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1640
1641        /* Check failed */
1642        reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1643        reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD);
1644
1645        /* leave IQK mode */
1646        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1647        rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x780);
1648
1649        /* Allen 20131125 */
1650        tmp = (reg_eac & 0x03FF0000) >> 16;
1651        if ((tmp & 0x200) > 0)
1652                tmp = 0x400 - tmp;
1653        /* if Tx is OK, check whether Rx is OK */
1654        if (!(reg_eac & BIT(27)) &&
1655            (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
1656            (((reg_eac & 0x03FF0000) >> 16) != 0x36))
1657                result |= 0x02;
1658        else if (!(reg_eac & BIT(27)) &&
1659                 (((reg_ea4 & 0x03FF0000) >> 16) < 0x110) &&
1660                 (((reg_ea4 & 0x03FF0000) >> 16) > 0xf0) &&
1661                 (tmp < 0xf))
1662                result |= 0x02;
1663
1664        return result;
1665}
1666
1667static u8 _rtl8723be_phy_path_b_iqk(struct ieee80211_hw *hw)
1668{
1669        u32 reg_eac, reg_e94, reg_e9c, tmp;
1670        u8 result = 0x00;
1671
1672        /* leave IQK mode */
1673        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1674        /* switch to path B */
1675        rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000280);
1676
1677        /* enable path B PA in TXIQK mode */
1678        rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020);
1679        rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x40fc1);
1680
1681        /* 1 Tx IQK */
1682        /* IQK setting */
1683        rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1684        rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1685        /* path-A IQK setting */
1686        rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1687        rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1688        rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1689        rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1690
1691        rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x821403ea);
1692        rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000);
1693        rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1694        rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1695
1696        /* LO calibration setting */
1697        rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911);
1698
1699        /* enter IQK mode */
1700        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1701
1702        /* One shot, path B LOK & IQK */
1703        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1704        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1705
1706        mdelay(IQK_DELAY_TIME);
1707
1708        /* leave IQK mode */
1709        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1710
1711        /* Check failed */
1712        reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1713        reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1714        reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1715
1716        if (!(reg_eac & BIT(28)) &&
1717            (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1718            (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1719                result |= 0x01;
1720        else
1721                return result;
1722
1723        /* Allen 20131125 */
1724        tmp = (reg_e9c & 0x03FF0000) >> 16;
1725        if ((tmp & 0x200) > 0)
1726                tmp = 0x400 - tmp;
1727
1728        if (!(reg_eac & BIT(28)) &&
1729            (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1730            (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1731            (tmp < 0xf))
1732                result |= 0x01;
1733        else
1734                return result;
1735
1736        return result;
1737}
1738
1739/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
1740static u8 _rtl8723be_phy_path_b_rx_iqk(struct ieee80211_hw *hw)
1741{
1742        u32 reg_e94, reg_e9c, reg_ea4, reg_eac, u32tmp, tmp;
1743        u8 result = 0x00;
1744
1745        /* leave IQK mode */
1746        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1747        /* switch to path B */
1748        rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000280);
1749
1750        /* 1 Get TXIMR setting */
1751        /* modify RXIQK mode table */
1752        rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
1753        rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1754        rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1755        rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7ff7);
1756
1757        /* open PA S1 & SMIXER */
1758        rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020);
1759        rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x60fed);
1760
1761        /* IQK setting */
1762        rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1763        rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1764
1765        /* path-B IQK setting */
1766        rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1767        rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1768        rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1769        rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1770
1771        rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160ff0);
1772        rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000);
1773        rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1774        rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1775
1776        /* LO calibration setting */
1777        rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
1778        /* enter IQK mode */
1779        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1780
1781        /* One shot, path B TXIQK @ RXIQK */
1782        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1783        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1784
1785        mdelay(IQK_DELAY_TIME);
1786
1787        /* leave IQK mode */
1788        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1789        /* Check failed */
1790        reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1791        reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1792        reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1793
1794        if (!(reg_eac & BIT(28)) &&
1795            (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1796            (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1797                result |= 0x01;
1798        else    /* if Tx not OK, ignore Rx */
1799                return result;
1800
1801        /* Allen 20131125 */
1802        tmp = (reg_e9c & 0x03FF0000) >> 16;
1803        if ((tmp & 0x200) > 0)
1804                tmp = 0x400 - tmp;
1805
1806        if (!(reg_eac & BIT(28)) &&
1807            (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1808            (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1809            (tmp < 0xf))
1810                result |= 0x01;
1811        else
1812                return result;
1813
1814        u32tmp = 0x80007C00 | (reg_e94 & 0x3FF0000)  |
1815                 ((reg_e9c & 0x3FF0000) >> 16);
1816        rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32tmp);
1817
1818        /* 1 RX IQK */
1819
1820        /* <20121009, Kordan> RF Mode = 3 */
1821        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1822        rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1823        rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1824        rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1825        rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7d77);
1826        rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x0);
1827
1828        /* open PA S1 & close SMIXER */
1829        rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020);
1830        rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x60fbd);
1831
1832        /* IQK setting */
1833        rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1834
1835        /* path-B IQK setting */
1836        rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1837        rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1838        rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1839        rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1840
1841        rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82110000);
1842        rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x2816001f);
1843        rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1844        rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1845
1846        /* LO calibration setting */
1847        rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a8d1);
1848        /* enter IQK mode */
1849        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1850
1851        /* One shot, path B LOK & IQK */
1852        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1853        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1854
1855        mdelay(IQK_DELAY_TIME);
1856
1857        /* leave IQK mode */
1858        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1859        /* Check failed */
1860        reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1861        reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD);
1862
1863        /* Allen 20131125 */
1864        tmp = (reg_eac & 0x03FF0000) >> 16;
1865        if ((tmp & 0x200) > 0)
1866                tmp = 0x400 - tmp;
1867
1868        /* if Tx is OK, check whether Rx is OK */
1869        if (!(reg_eac & BIT(27)) &&
1870            (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
1871            (((reg_eac & 0x03FF0000) >> 16) != 0x36))
1872                result |= 0x02;
1873        else if (!(reg_eac & BIT(27)) &&
1874                 (((reg_ea4 & 0x03FF0000) >> 16) < 0x110) &&
1875                 (((reg_ea4 & 0x03FF0000) >> 16) > 0xf0) &&
1876                 (tmp < 0xf))
1877                result |= 0x02;
1878        else
1879                return result;
1880
1881        return result;
1882}
1883
1884static void _rtl8723be_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw,
1885                                                  bool b_iqk_ok,
1886                                                  long result[][8],
1887                                                  u8 final_candidate,
1888                                                  bool btxonly)
1889{
1890        u32 oldval_1, x, tx1_a, reg;
1891        long y, tx1_c;
1892
1893        if (final_candidate == 0xFF) {
1894                return;
1895        } else if (b_iqk_ok) {
1896                oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
1897                                          MASKDWORD) >> 22) & 0x3FF;
1898                x = result[final_candidate][4];
1899                if ((x & 0x00000200) != 0)
1900                        x = x | 0xFFFFFC00;
1901                tx1_a = (x * oldval_1) >> 8;
1902                rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a);
1903                rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27),
1904                              ((x * oldval_1 >> 7) & 0x1));
1905                y = result[final_candidate][5];
1906                if ((y & 0x00000200) != 0)
1907                        y = y | 0xFFFFFC00;
1908                tx1_c = (y * oldval_1) >> 8;
1909                rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000,
1910                              ((tx1_c & 0x3C0) >> 6));
1911                rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000,
1912                              (tx1_c & 0x3F));
1913                rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25),
1914                              ((y * oldval_1 >> 7) & 0x1));
1915                if (btxonly)
1916                        return;
1917                reg = result[final_candidate][6];
1918                rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg);
1919                reg = result[final_candidate][7] & 0x3F;
1920                rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg);
1921                reg = (result[final_candidate][7] >> 6) & 0xF;
1922                /* rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); */
1923        }
1924}
1925
1926static bool _rtl8723be_phy_simularity_compare(struct ieee80211_hw *hw,
1927                                              long result[][8], u8 c1, u8 c2)
1928{
1929        u32 i, j, diff, simularity_bitmap, bound = 0;
1930
1931        u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */
1932        bool bresult = true; /* is2t = true*/
1933        s32 tmp1 = 0, tmp2 = 0;
1934
1935        bound = 8;
1936
1937        simularity_bitmap = 0;
1938
1939        for (i = 0; i < bound; i++) {
1940                if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) {
1941                        if ((result[c1][i] & 0x00000200) != 0)
1942                                tmp1 = result[c1][i] | 0xFFFFFC00;
1943                        else
1944                                tmp1 = result[c1][i];
1945
1946                        if ((result[c2][i] & 0x00000200) != 0)
1947                                tmp2 = result[c2][i] | 0xFFFFFC00;
1948                        else
1949                                tmp2 = result[c2][i];
1950                } else {
1951                        tmp1 = result[c1][i];
1952                        tmp2 = result[c2][i];
1953                }
1954
1955                diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1);
1956
1957                if (diff > MAX_TOLERANCE) {
1958                        if ((i == 2 || i == 6) && !simularity_bitmap) {
1959                                if (result[c1][i] + result[c1][i + 1] == 0)
1960                                        final_candidate[(i / 4)] = c2;
1961                                else if (result[c2][i] + result[c2][i + 1] == 0)
1962                                        final_candidate[(i / 4)] = c1;
1963                                else
1964                                        simularity_bitmap |= (1 << i);
1965                        } else
1966                                simularity_bitmap |= (1 << i);
1967                }
1968        }
1969
1970        if (simularity_bitmap == 0) {
1971                for (i = 0; i < (bound / 4); i++) {
1972                        if (final_candidate[i] != 0xFF) {
1973                                for (j = i * 4; j < (i + 1) * 4 - 2; j++)
1974                                        result[3][j] =
1975                                                result[final_candidate[i]][j];
1976                                bresult = false;
1977                        }
1978                }
1979                return bresult;
1980        } else {
1981                if (!(simularity_bitmap & 0x03)) { /* path A TX OK */
1982                        for (i = 0; i < 2; i++)
1983                                result[3][i] = result[c1][i];
1984                }
1985                if (!(simularity_bitmap & 0x0c)) { /* path A RX OK */
1986                        for (i = 2; i < 4; i++)
1987                                result[3][i] = result[c1][i];
1988                }
1989                if (!(simularity_bitmap & 0x30)) { /* path B TX OK */
1990                        for (i = 4; i < 6; i++)
1991                                result[3][i] = result[c1][i];
1992                }
1993                if (!(simularity_bitmap & 0xc0)) { /* path B RX OK */
1994                        for (i = 6; i < 8; i++)
1995                                result[3][i] = result[c1][i];
1996                }
1997                return false;
1998        }
1999}
2000
2001static void _rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw,
2002                                        long result[][8], u8 t, bool is2t)
2003{
2004        struct rtl_priv *rtlpriv = rtl_priv(hw);
2005        struct rtl_phy *rtlphy = &rtlpriv->phy;
2006        u32 i;
2007        u8 patha_ok, pathb_ok;
2008        u32 adda_reg[IQK_ADDA_REG_NUM] = {
2009                0x85c, 0xe6c, 0xe70, 0xe74,
2010                0xe78, 0xe7c, 0xe80, 0xe84,
2011                0xe88, 0xe8c, 0xed0, 0xed4,
2012                0xed8, 0xedc, 0xee0, 0xeec
2013        };
2014
2015        u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
2016                0x522, 0x550, 0x551, 0x040
2017        };
2018        u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
2019                ROFDM0_TRXPATHENABLE, ROFDM0_TRMUXPAR,
2020                RFPGA0_XCD_RFINTERFACESW, 0xb68, 0xb6c,
2021                0x870, 0x860,
2022                0x864, 0xa04
2023        };
2024        const u32 retrycount = 2;
2025
2026        u32 path_sel_bb;/* path_sel_rf */
2027
2028        u8 tmp_reg_c50, tmp_reg_c58;
2029
2030        tmp_reg_c50 = rtl_get_bbreg(hw, 0xc50, MASKBYTE0);
2031        tmp_reg_c58 = rtl_get_bbreg(hw, 0xc58, MASKBYTE0);
2032
2033        if (t == 0) {
2034                rtl8723_save_adda_registers(hw, adda_reg,
2035                                            rtlphy->adda_backup, 16);
2036                rtl8723_phy_save_mac_registers(hw, iqk_mac_reg,
2037                                               rtlphy->iqk_mac_backup);
2038                rtl8723_save_adda_registers(hw, iqk_bb_reg,
2039                                            rtlphy->iqk_bb_backup,
2040                                            IQK_BB_REG_NUM);
2041        }
2042        rtl8723_phy_path_adda_on(hw, adda_reg, true, is2t);
2043        if (t == 0) {
2044                rtlphy->rfpi_enable = (u8)rtl_get_bbreg(hw,
2045                                                RFPGA0_XA_HSSIPARAMETER1,
2046                                                BIT(8));
2047        }
2048
2049        path_sel_bb = rtl_get_bbreg(hw, 0x948, MASKDWORD);
2050
2051        rtl8723_phy_mac_setting_calibration(hw, iqk_mac_reg,
2052                                            rtlphy->iqk_mac_backup);
2053        /*BB Setting*/
2054        rtl_set_bbreg(hw, 0xa04, 0x0f000000, 0xf);
2055        rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
2056        rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
2057        rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
2058
2059        /* path A TX IQK */
2060        for (i = 0; i < retrycount; i++) {
2061                patha_ok = _rtl8723be_phy_path_a_iqk(hw);
2062                if (patha_ok == 0x01) {
2063                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2064                                "Path A Tx IQK Success!!\n");
2065                        result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
2066                                        0x3FF0000) >> 16;
2067                        result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
2068                                        0x3FF0000) >> 16;
2069                        break;
2070                } else {
2071                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2072                                 "Path A Tx IQK Fail!!\n");
2073                }
2074        }
2075        /* path A RX IQK */
2076        for (i = 0; i < retrycount; i++) {
2077                patha_ok = _rtl8723be_phy_path_a_rx_iqk(hw);
2078                if (patha_ok == 0x03) {
2079                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2080                                 "Path A Rx IQK Success!!\n");
2081                        result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &
2082                                        0x3FF0000) >> 16;
2083                        result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &
2084                                        0x3FF0000) >> 16;
2085                        break;
2086                }
2087                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2088                         "Path A Rx IQK Fail!!\n");
2089        }
2090
2091        if (0x00 == patha_ok)
2092                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Path A IQK Fail!!\n");
2093
2094        if (is2t) {
2095                /* path B TX IQK */
2096                for (i = 0; i < retrycount; i++) {
2097                        pathb_ok = _rtl8723be_phy_path_b_iqk(hw);
2098                        if (pathb_ok == 0x01) {
2099                                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2100                                         "Path B Tx IQK Success!!\n");
2101                                result[t][4] = (rtl_get_bbreg(hw, 0xe94,
2102                                                              MASKDWORD) &
2103                                                              0x3FF0000) >> 16;
2104                                result[t][5] = (rtl_get_bbreg(hw, 0xe9c,
2105                                                              MASKDWORD) &
2106                                                              0x3FF0000) >> 16;
2107                                break;
2108                        }
2109                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2110                                 "Path B Tx IQK Fail!!\n");
2111                }
2112                /* path B RX IQK */
2113                for (i = 0; i < retrycount; i++) {
2114                        pathb_ok = _rtl8723be_phy_path_b_rx_iqk(hw);
2115                        if (pathb_ok == 0x03) {
2116                                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2117                                         "Path B Rx IQK Success!!\n");
2118                                result[t][6] = (rtl_get_bbreg(hw, 0xea4,
2119                                                              MASKDWORD) &
2120                                                              0x3FF0000) >> 16;
2121                                result[t][7] = (rtl_get_bbreg(hw, 0xeac,
2122                                                              MASKDWORD) &
2123                                                              0x3FF0000) >> 16;
2124                                break;
2125                        }
2126                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2127                                 "Path B Rx IQK Fail!!\n");
2128                }
2129        }
2130
2131        /* Back to BB mode, load original value */
2132        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0);
2133
2134        if (t != 0) {
2135                rtl8723_phy_reload_adda_registers(hw, adda_reg,
2136                                                  rtlphy->adda_backup, 16);
2137                rtl8723_phy_reload_mac_registers(hw, iqk_mac_reg,
2138                                                 rtlphy->iqk_mac_backup);
2139                rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
2140                                                  rtlphy->iqk_bb_backup,
2141                                                  IQK_BB_REG_NUM);
2142
2143                rtl_set_bbreg(hw, 0x948, MASKDWORD, path_sel_bb);
2144                /*rtl_set_rfreg(hw, RF90_PATH_B, 0xb0, 0xfffff, path_sel_rf);*/
2145
2146                rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50);
2147                rtl_set_bbreg(hw, 0xc50, MASKBYTE0, tmp_reg_c50);
2148                if (is2t) {
2149                        rtl_set_bbreg(hw, 0xc58, MASKBYTE0, 0x50);
2150                        rtl_set_bbreg(hw, 0xc58, MASKBYTE0, tmp_reg_c58);
2151                }
2152                rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00);
2153                rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00);
2154        }
2155        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "8723be IQK Finish!!\n");
2156}
2157
2158static u8 _get_right_chnl_place_for_iqk(u8 chnl)
2159{
2160        u8 channel_all[TARGET_CHNL_NUM_2G_5G] = {
2161                        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
2162                        13, 14, 36, 38, 40, 42, 44, 46,
2163                        48, 50, 52, 54, 56, 58, 60, 62, 64,
2164                        100, 102, 104, 106, 108, 110,
2165                        112, 114, 116, 118, 120, 122,
2166                        124, 126, 128, 130, 132, 134, 136,
2167                        138, 140, 149, 151, 153, 155, 157,
2168                        159, 161, 163, 165};
2169        u8 place = chnl;
2170
2171        if (chnl > 14) {
2172                for (place = 14; place < sizeof(channel_all); place++) {
2173                        if (channel_all[place] == chnl)
2174                                return place - 13;
2175                }
2176        }
2177        return 0;
2178}
2179
2180static void _rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
2181{
2182        u8 tmpreg;
2183        u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
2184        struct rtl_priv *rtlpriv = rtl_priv(hw);
2185
2186        tmpreg = rtl_read_byte(rtlpriv, 0xd03);
2187
2188        if ((tmpreg & 0x70) != 0)
2189                rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
2190        else
2191                rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2192
2193        if ((tmpreg & 0x70) != 0) {
2194                rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
2195
2196                if (is2t)
2197                        rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
2198                                                  MASK12BITS);
2199
2200                rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
2201                              (rf_a_mode & 0x8FFFF) | 0x10000);
2202
2203                if (is2t)
2204                        rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
2205                                      (rf_b_mode & 0x8FFFF) | 0x10000);
2206        }
2207        lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
2208
2209        rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdfbe0);
2210        rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, 0x8c0a);
2211
2212        /* In order not to disturb BT music when wifi init.(1ant NIC only) */
2213        /*mdelay(100);*/
2214        /* In order not to disturb BT music when wifi init.(1ant NIC only) */
2215        mdelay(50);
2216
2217        rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdffe0);
2218
2219        if ((tmpreg & 0x70) != 0) {
2220                rtl_write_byte(rtlpriv, 0xd03, tmpreg);
2221                rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
2222
2223                if (is2t)
2224                        rtl_set_rfreg(hw, RF90_PATH_B, 0x00,
2225                                      MASK12BITS, rf_b_mode);
2226        } else {
2227                rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2228        }
2229        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
2230}
2231
2232static void _rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw,
2233                                             bool bmain, bool is2t)
2234{
2235        struct rtl_priv *rtlpriv = rtl_priv(hw);
2236        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
2237
2238        if (bmain) /* left antenna */
2239                rtl_set_bbreg(hw, 0x92C, MASKDWORD, 0x1);
2240        else
2241                rtl_set_bbreg(hw, 0x92C, MASKDWORD, 0x2);
2242}
2243
2244#undef IQK_ADDA_REG_NUM
2245#undef IQK_DELAY_TIME
2246/* IQK is merge from Merge Temp */
2247void rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
2248{
2249        struct rtl_priv *rtlpriv = rtl_priv(hw);
2250        struct rtl_phy *rtlphy = &rtlpriv->phy;
2251        long result[4][8];
2252        u8 i, final_candidate, idx;
2253        bool b_patha_ok, b_pathb_ok;
2254        long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4;
2255        long reg_ecc, reg_tmp = 0;
2256        bool is12simular, is13simular, is23simular;
2257        u32 iqk_bb_reg[9] = {
2258                ROFDM0_XARXIQIMBALANCE,
2259                ROFDM0_XBRXIQIMBALANCE,
2260                ROFDM0_ECCATHRESHOLD,
2261                ROFDM0_AGCRSSITABLE,
2262                ROFDM0_XATXIQIMBALANCE,
2263                ROFDM0_XBTXIQIMBALANCE,
2264                ROFDM0_XCTXAFE,
2265                ROFDM0_XDTXAFE,
2266                ROFDM0_RXIQEXTANTA
2267        };
2268        u32 path_sel_bb = 0; /* path_sel_rf = 0 */
2269
2270        if (rtlphy->lck_inprogress)
2271                return;
2272
2273        spin_lock(&rtlpriv->locks.iqk_lock);
2274        rtlphy->lck_inprogress = true;
2275        spin_unlock(&rtlpriv->locks.iqk_lock);
2276
2277        if (b_recovery) {
2278                rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
2279                                                  rtlphy->iqk_bb_backup, 9);
2280                goto label_done;
2281        }
2282        /* Save RF Path */
2283        path_sel_bb = rtl_get_bbreg(hw, 0x948, MASKDWORD);
2284        /* path_sel_rf = rtl_get_rfreg(hw, RF90_PATH_A, 0xb0, 0xfffff); */
2285
2286        for (i = 0; i < 8; i++) {
2287                result[0][i] = 0;
2288                result[1][i] = 0;
2289                result[2][i] = 0;
2290                result[3][i] = 0;
2291        }
2292        final_candidate = 0xff;
2293        b_patha_ok = false;
2294        b_pathb_ok = false;
2295        is12simular = false;
2296        is23simular = false;
2297        is13simular = false;
2298        for (i = 0; i < 3; i++) {
2299                _rtl8723be_phy_iq_calibrate(hw, result, i, true);
2300                if (i == 1) {
2301                        is12simular = _rtl8723be_phy_simularity_compare(hw,
2302                                                                        result,
2303                                                                        0, 1);
2304                        if (is12simular) {
2305                                final_candidate = 0;
2306                                break;
2307                        }
2308                }
2309                if (i == 2) {
2310                        is13simular = _rtl8723be_phy_simularity_compare(hw,
2311                                                                        result,
2312                                                                        0, 2);
2313                        if (is13simular) {
2314                                final_candidate = 0;
2315                                break;
2316                        }
2317                        is23simular = _rtl8723be_phy_simularity_compare(hw,
2318                                                                        result,
2319                                                                        1, 2);
2320                        if (is23simular) {
2321                                final_candidate = 1;
2322                        } else {
2323                                for (i = 0; i < 8; i++)
2324                                        reg_tmp += result[3][i];
2325
2326                                if (reg_tmp != 0)
2327                                        final_candidate = 3;
2328                                else
2329                                        final_candidate = 0xFF;
2330                        }
2331                }
2332        }
2333        for (i = 0; i < 4; i++) {
2334                reg_e94 = result[i][0];
2335                reg_e9c = result[i][1];
2336                reg_ea4 = result[i][2];
2337                reg_eac = result[i][3];
2338                reg_eb4 = result[i][4];
2339                reg_ebc = result[i][5];
2340                reg_ec4 = result[i][6];
2341                reg_ecc = result[i][7];
2342        }
2343        if (final_candidate != 0xff) {
2344                reg_e94 = result[final_candidate][0];
2345                rtlphy->reg_e94 = reg_e94;
2346                reg_e9c = result[final_candidate][1];
2347                rtlphy->reg_e9c = reg_e9c;
2348                reg_ea4 = result[final_candidate][2];
2349                reg_eac = result[final_candidate][3];
2350                reg_eb4 = result[final_candidate][4];
2351                rtlphy->reg_eb4 = reg_eb4;
2352                reg_ebc = result[final_candidate][5];
2353                rtlphy->reg_ebc = reg_ebc;
2354                reg_ec4 = result[final_candidate][6];
2355                reg_ecc = result[final_candidate][7];
2356                b_patha_ok = true;
2357                b_pathb_ok = true;
2358        } else {
2359                rtlphy->reg_e94 = 0x100;
2360                rtlphy->reg_eb4 = 0x100;
2361                rtlphy->reg_e9c = 0x0;
2362                rtlphy->reg_ebc = 0x0;
2363        }
2364        if (reg_e94 != 0)
2365                rtl8723_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result,
2366                                                   final_candidate,
2367                                                   (reg_ea4 == 0));
2368        if (reg_eb4 != 0)
2369                _rtl8723be_phy_path_b_fill_iqk_matrix(hw, b_pathb_ok, result,
2370                                                      final_candidate,
2371                                                      (reg_ec4 == 0));
2372
2373        idx = _get_right_chnl_place_for_iqk(rtlphy->current_channel);
2374
2375        if (final_candidate < 4) {
2376                for (i = 0; i < IQK_MATRIX_REG_NUM; i++)
2377                        rtlphy->iqk_matrix[idx].value[0][i] =
2378                                                result[final_candidate][i];
2379                rtlphy->iqk_matrix[idx].iqk_done = true;
2380
2381        }
2382        rtl8723_save_adda_registers(hw, iqk_bb_reg,
2383                                    rtlphy->iqk_bb_backup, 9);
2384
2385        rtl_set_bbreg(hw, 0x948, MASKDWORD, path_sel_bb);
2386        /* rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, 0xfffff, path_sel_rf); */
2387
2388label_done:
2389        spin_lock(&rtlpriv->locks.iqk_lock);
2390        rtlphy->lck_inprogress = false;
2391        spin_unlock(&rtlpriv->locks.iqk_lock);
2392}
2393
2394void rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw)
2395{
2396        struct rtl_priv *rtlpriv = rtl_priv(hw);
2397        struct rtl_phy *rtlphy = &rtlpriv->phy;
2398        struct rtl_hal *rtlhal = &rtlpriv->rtlhal;
2399        u32 timeout = 2000, timecount = 0;
2400
2401        while (rtlpriv->mac80211.act_scanning && timecount < timeout) {
2402                udelay(50);
2403                timecount += 50;
2404        }
2405
2406        rtlphy->lck_inprogress = true;
2407        RTPRINT(rtlpriv, FINIT, INIT_IQK,
2408                "LCK:Start!!! currentband %x delay %d ms\n",
2409                 rtlhal->current_bandtype, timecount);
2410
2411        _rtl8723be_phy_lc_calibrate(hw, false);
2412
2413        rtlphy->lck_inprogress = false;
2414}
2415
2416void rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
2417{
2418        _rtl8723be_phy_set_rfpath_switch(hw, bmain, true);
2419}
2420
2421bool rtl8723be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
2422{
2423        struct rtl_priv *rtlpriv = rtl_priv(hw);
2424        struct rtl_phy *rtlphy = &rtlpriv->phy;
2425        bool b_postprocessing = false;
2426
2427        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2428                 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
2429                  iotype, rtlphy->set_io_inprogress);
2430        do {
2431                switch (iotype) {
2432                case IO_CMD_RESUME_DM_BY_SCAN:
2433                        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2434                                 "[IO CMD] Resume DM after scan.\n");
2435                        b_postprocessing = true;
2436                        break;
2437                case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
2438                        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2439                                 "[IO CMD] Pause DM before scan.\n");
2440                        b_postprocessing = true;
2441                        break;
2442                default:
2443                        RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
2444                                 "switch case %#x not processed\n", iotype);
2445                        break;
2446                }
2447        } while (false);
2448        if (b_postprocessing && !rtlphy->set_io_inprogress) {
2449                rtlphy->set_io_inprogress = true;
2450                rtlphy->current_io_type = iotype;
2451        } else {
2452                return false;
2453        }
2454        rtl8723be_phy_set_io(hw);
2455        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
2456        return true;
2457}
2458
2459static void rtl8723be_phy_set_io(struct ieee80211_hw *hw)
2460{
2461        struct rtl_priv *rtlpriv = rtl_priv(hw);
2462        struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
2463        struct rtl_phy *rtlphy = &rtlpriv->phy;
2464
2465        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2466                 "--->Cmd(%#x), set_io_inprogress(%d)\n",
2467                  rtlphy->current_io_type, rtlphy->set_io_inprogress);
2468        switch (rtlphy->current_io_type) {
2469        case IO_CMD_RESUME_DM_BY_SCAN:
2470                dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1;
2471                /*rtl92c_dm_write_dig(hw);*/
2472                rtl8723be_phy_set_txpower_level(hw, rtlphy->current_channel);
2473                rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x83);
2474                break;
2475        case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
2476                rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
2477                dm_digtable->cur_igvalue = 0x17;
2478                rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x40);
2479                break;
2480        default:
2481                RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
2482                         "switch case %#x not processed\n",
2483                         rtlphy->current_io_type);
2484                break;
2485        }
2486        rtlphy->set_io_inprogress = false;
2487        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2488                 "(%#x)\n", rtlphy->current_io_type);
2489}
2490
2491static void rtl8723be_phy_set_rf_on(struct ieee80211_hw *hw)
2492{
2493        struct rtl_priv *rtlpriv = rtl_priv(hw);
2494
2495        rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
2496        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2497        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2498        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2499        rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2500}
2501
2502static void _rtl8723be_phy_set_rf_sleep(struct ieee80211_hw *hw)
2503{
2504        struct rtl_priv *rtlpriv = rtl_priv(hw);
2505
2506        rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2507        rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
2508        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2509        rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
2510}
2511
2512static bool _rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2513                                              enum rf_pwrstate rfpwr_state)
2514{
2515        struct rtl_priv *rtlpriv = rtl_priv(hw);
2516        struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2517        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2518        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2519        bool bresult = true;
2520        u8 i, queue_id;
2521        struct rtl8192_tx_ring *ring = NULL;
2522
2523        switch (rfpwr_state) {
2524        case ERFON:
2525                if ((ppsc->rfpwr_state == ERFOFF) &&
2526                     RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
2527                        bool rtstatus;
2528                        u32 initializecount = 0;
2529                        do {
2530                                initializecount++;
2531                                RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2532                                         "IPS Set eRf nic enable\n");
2533                                rtstatus = rtl_ps_enable_nic(hw);
2534                        } while (!rtstatus && (initializecount < 10));
2535                        RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2536                } else {
2537                        RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2538                                 "Set ERFON sleeped:%d ms\n",
2539                                  jiffies_to_msecs(jiffies -
2540                                                   ppsc->last_sleep_jiffies));
2541                        ppsc->last_awake_jiffies = jiffies;
2542                        rtl8723be_phy_set_rf_on(hw);
2543                }
2544                if (mac->link_state == MAC80211_LINKED)
2545                        rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK);
2546                else
2547                        rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK);
2548
2549                break;
2550
2551        case ERFOFF:
2552                for (queue_id = 0, i = 0;
2553                     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2554                        ring = &pcipriv->dev.tx_ring[queue_id];
2555                        /* Don't check BEACON Q.
2556                         * BEACON Q is always not empty,
2557                         * because '_rtl8723be_cmd_send_packet'
2558                         */
2559                        if (queue_id == BEACON_QUEUE ||
2560                            skb_queue_len(&ring->queue) == 0) {
2561                                queue_id++;
2562                                continue;
2563                        } else {
2564                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2565                                         "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
2566                                         (i + 1), queue_id,
2567                                         skb_queue_len(&ring->queue));
2568
2569                                udelay(10);
2570                                i++;
2571                        }
2572                        if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2573                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2574                                         "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
2575                                          MAX_DOZE_WAITING_TIMES_9x,
2576                                          queue_id,
2577                                          skb_queue_len(&ring->queue));
2578                                break;
2579                        }
2580                }
2581
2582                if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
2583                        RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2584                                 "IPS Set eRf nic disable\n");
2585                        rtl_ps_disable_nic(hw);
2586                        RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2587                } else {
2588                        if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
2589                                rtlpriv->cfg->ops->led_control(hw,
2590                                                               LED_CTL_NO_LINK);
2591                        } else {
2592                                rtlpriv->cfg->ops->led_control(hw,
2593                                                             LED_CTL_POWER_OFF);
2594                        }
2595                }
2596                break;
2597
2598        case ERFSLEEP:
2599                if (ppsc->rfpwr_state == ERFOFF)
2600                        break;
2601                for (queue_id = 0, i = 0;
2602                     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2603                        ring = &pcipriv->dev.tx_ring[queue_id];
2604                        if (skb_queue_len(&ring->queue) == 0) {
2605                                queue_id++;
2606                                continue;
2607                        } else {
2608                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2609                                         "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
2610                                         (i + 1), queue_id,
2611                                         skb_queue_len(&ring->queue));
2612
2613                                udelay(10);
2614                                i++;
2615                        }
2616                        if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2617                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2618                                         "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
2619                                         MAX_DOZE_WAITING_TIMES_9x,
2620                                         queue_id,
2621                                         skb_queue_len(&ring->queue));
2622                                break;
2623                        }
2624                }
2625                RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2626                         "Set ERFSLEEP awaked:%d ms\n",
2627                          jiffies_to_msecs(jiffies -
2628                                           ppsc->last_awake_jiffies));
2629                ppsc->last_sleep_jiffies = jiffies;
2630                _rtl8723be_phy_set_rf_sleep(hw);
2631                break;
2632
2633        default:
2634                RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
2635                         "switch case %#x not processed\n", rfpwr_state);
2636                bresult = false;
2637                break;
2638        }
2639        if (bresult)
2640                ppsc->rfpwr_state = rfpwr_state;
2641        return bresult;
2642}
2643
2644bool rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2645                                      enum rf_pwrstate rfpwr_state)
2646{
2647        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2648
2649        bool bresult = false;
2650
2651        if (rfpwr_state == ppsc->rfpwr_state)
2652                return bresult;
2653        bresult = _rtl8723be_phy_set_rf_power_state(hw, rfpwr_state);
2654        return bresult;
2655}
2656