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