linux/drivers/net/wireless/realtek/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        s8 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!!\n");
 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!!\n");
 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 %#x not processed\n", rfpath);
 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        s8 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 = 0;
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 schedule 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 %#x not processed\n",
1511                                 currentcmd->cmdid);
1512                        break;
1513                }
1514
1515                break;
1516        } while (true);
1517
1518        (*delay) = currentcmd->msdelay;
1519        (*step)++;
1520        return false;
1521}
1522
1523static u8 _rtl8723be_phy_path_a_iqk(struct ieee80211_hw *hw)
1524{
1525        u32 reg_eac, reg_e94, reg_e9c, tmp;
1526        u8 result = 0x00;
1527
1528        /* leave IQK mode */
1529        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1530        /* switch to path A */
1531        rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000000);
1532        /* enable path A PA in TXIQK mode */
1533        rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
1534        rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x20000);
1535        rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0003f);
1536        rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xc7f87);
1537
1538        /* 1. TX IQK */
1539        /* path-A IQK setting */
1540        /* IQK setting */
1541        rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1542        rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1543        /* path-A IQK setting */
1544        rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1545        rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1546        rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1547        rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1548
1549        rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x821403ea);
1550        rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28160000);
1551        rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1552        rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1553        /* LO calibration setting */
1554        rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911);
1555        /* enter IQK mode */
1556        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1557
1558        /* One shot, path A LOK & IQK */
1559        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1560        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1561
1562        mdelay(IQK_DELAY_TIME);
1563
1564        /* leave IQK mode */
1565        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1566
1567        /* Check failed */
1568        reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1569        reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
1570        reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
1571
1572        if (!(reg_eac & BIT(28)) &&
1573            (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1574            (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1575                result |= 0x01;
1576        else /* if Tx not OK, ignore Rx */
1577                return result;
1578
1579        /* Allen 20131125 */
1580        tmp = (reg_e9c & 0x03FF0000) >> 16;
1581        if ((tmp & 0x200) > 0)
1582                tmp = 0x400 - tmp;
1583
1584        if (!(reg_eac & BIT(28)) &&
1585            (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1586            (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1587            (tmp < 0xf))
1588                result |= 0x01;
1589        else /* if Tx not OK, ignore Rx */
1590                return result;
1591
1592        return result;
1593}
1594
1595/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
1596static u8 _rtl8723be_phy_path_a_rx_iqk(struct ieee80211_hw *hw)
1597{
1598        u32 reg_eac, reg_e94, reg_e9c, reg_ea4, u32tmp, tmp;
1599        u8 result = 0x00;
1600
1601        /* leave IQK mode */
1602        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1603
1604        /* switch to path A */
1605        rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000000);
1606
1607        /* 1 Get TXIMR setting */
1608        /* modify RXIQK mode table */
1609        rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1610        rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1611        rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1612        /* LNA2 off, PA on for Dcut */
1613        rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7fb7);
1614        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1615
1616        /* IQK setting */
1617        rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1618        rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1619
1620        /* path-A IQK setting */
1621        rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1622        rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1623        rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1624        rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1625
1626        rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160ff0);
1627        rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000);
1628        rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1629        rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1630
1631        /* LO calibration setting */
1632        rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
1633
1634        /* enter IQK mode */
1635        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1636
1637        /* One shot, path A LOK & IQK */
1638        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1639        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1640
1641        mdelay(IQK_DELAY_TIME);
1642
1643        /* leave IQK mode */
1644        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1645
1646        /* Check failed */
1647        reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1648        reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1649        reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1650
1651        if (!(reg_eac & BIT(28)) &&
1652            (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1653            (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1654                result |= 0x01;
1655        else /* if Tx not OK, ignore Rx */
1656                return result;
1657
1658        /* Allen 20131125 */
1659        tmp = (reg_e9c & 0x03FF0000) >> 16;
1660        if ((tmp & 0x200) > 0)
1661                tmp = 0x400 - tmp;
1662
1663        if (!(reg_eac & BIT(28)) &&
1664            (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1665            (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1666            (tmp < 0xf))
1667                result |= 0x01;
1668        else /* if Tx not OK, ignore Rx */
1669                return result;
1670
1671        u32tmp = 0x80007C00 | (reg_e94 & 0x3FF0000) |
1672                 ((reg_e9c & 0x3FF0000) >> 16);
1673        rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32tmp);
1674
1675        /* 1 RX IQK */
1676        /* modify RXIQK mode table */
1677        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1678        rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1679        rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1680        rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1681        /* LAN2 on, PA off for Dcut */
1682        rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7d77);
1683
1684        /* PA, PAD setting */
1685        rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0xf80);
1686        rtl_set_rfreg(hw, RF90_PATH_A, 0x55, RFREG_OFFSET_MASK, 0x4021f);
1687
1688        /* IQK setting */
1689        rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1690
1691        /* path-A IQK setting */
1692        rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1693        rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1694        rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1695        rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1696
1697        rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82110000);
1698        rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x2816001f);
1699        rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1700        rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1701
1702        /* LO calibration setting */
1703        rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a8d1);
1704
1705        /* enter IQK mode */
1706        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1707
1708        /* One shot, path A LOK & IQK */
1709        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1710        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1711
1712        mdelay(IQK_DELAY_TIME);
1713
1714        /* leave IQK mode */
1715        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1716
1717        /* Check failed */
1718        reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1719        reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD);
1720
1721        /* leave IQK mode */
1722        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1723        rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x780);
1724
1725        /* Allen 20131125 */
1726        tmp = (reg_eac & 0x03FF0000) >> 16;
1727        if ((tmp & 0x200) > 0)
1728                tmp = 0x400 - tmp;
1729        /* if Tx is OK, check whether Rx is OK */
1730        if (!(reg_eac & BIT(27)) &&
1731            (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
1732            (((reg_eac & 0x03FF0000) >> 16) != 0x36))
1733                result |= 0x02;
1734        else if (!(reg_eac & BIT(27)) &&
1735                 (((reg_ea4 & 0x03FF0000) >> 16) < 0x110) &&
1736                 (((reg_ea4 & 0x03FF0000) >> 16) > 0xf0) &&
1737                 (tmp < 0xf))
1738                result |= 0x02;
1739
1740        return result;
1741}
1742
1743static u8 _rtl8723be_phy_path_b_iqk(struct ieee80211_hw *hw)
1744{
1745        u32 reg_eac, reg_e94, reg_e9c, tmp;
1746        u8 result = 0x00;
1747
1748        /* leave IQK mode */
1749        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1750        /* switch to path B */
1751        rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000280);
1752
1753        /* enable path B PA in TXIQK mode */
1754        rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020);
1755        rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x40fc1);
1756
1757        /* 1 Tx IQK */
1758        /* IQK setting */
1759        rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1760        rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1761        /* path-A IQK setting */
1762        rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1763        rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1764        rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1765        rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1766
1767        rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x821403ea);
1768        rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000);
1769        rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1770        rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1771
1772        /* LO calibration setting */
1773        rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911);
1774
1775        /* enter IQK mode */
1776        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1777
1778        /* One shot, path B LOK & IQK */
1779        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1780        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1781
1782        mdelay(IQK_DELAY_TIME);
1783
1784        /* leave IQK mode */
1785        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1786
1787        /* Check failed */
1788        reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1789        reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1790        reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1791
1792        if (!(reg_eac & BIT(28)) &&
1793            (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1794            (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1795                result |= 0x01;
1796        else
1797                return result;
1798
1799        /* Allen 20131125 */
1800        tmp = (reg_e9c & 0x03FF0000) >> 16;
1801        if ((tmp & 0x200) > 0)
1802                tmp = 0x400 - tmp;
1803
1804        if (!(reg_eac & BIT(28)) &&
1805            (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1806            (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1807            (tmp < 0xf))
1808                result |= 0x01;
1809        else
1810                return result;
1811
1812        return result;
1813}
1814
1815/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
1816static u8 _rtl8723be_phy_path_b_rx_iqk(struct ieee80211_hw *hw)
1817{
1818        u32 reg_e94, reg_e9c, reg_ea4, reg_eac, u32tmp, tmp;
1819        u8 result = 0x00;
1820
1821        /* leave IQK mode */
1822        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1823        /* switch to path B */
1824        rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000280);
1825
1826        /* 1 Get TXIMR setting */
1827        /* modify RXIQK mode table */
1828        rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
1829        rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1830        rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1831        rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7ff7);
1832
1833        /* open PA S1 & SMIXER */
1834        rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020);
1835        rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x60fed);
1836
1837        /* IQK setting */
1838        rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1839        rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1840
1841        /* path-B IQK setting */
1842        rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1843        rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1844        rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1845        rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1846
1847        rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160ff0);
1848        rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000);
1849        rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1850        rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1851
1852        /* LO calibration setting */
1853        rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
1854        /* enter IQK mode */
1855        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1856
1857        /* One shot, path B TXIQK @ RXIQK */
1858        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1859        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1860
1861        mdelay(IQK_DELAY_TIME);
1862
1863        /* leave IQK mode */
1864        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1865        /* Check failed */
1866        reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1867        reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1868        reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1869
1870        if (!(reg_eac & BIT(28)) &&
1871            (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1872            (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1873                result |= 0x01;
1874        else    /* if Tx not OK, ignore Rx */
1875                return result;
1876
1877        /* Allen 20131125 */
1878        tmp = (reg_e9c & 0x03FF0000) >> 16;
1879        if ((tmp & 0x200) > 0)
1880                tmp = 0x400 - tmp;
1881
1882        if (!(reg_eac & BIT(28)) &&
1883            (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1884            (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1885            (tmp < 0xf))
1886                result |= 0x01;
1887        else
1888                return result;
1889
1890        u32tmp = 0x80007C00 | (reg_e94 & 0x3FF0000)  |
1891                 ((reg_e9c & 0x3FF0000) >> 16);
1892        rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32tmp);
1893
1894        /* 1 RX IQK */
1895
1896        /* <20121009, Kordan> RF Mode = 3 */
1897        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1898        rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1899        rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1900        rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1901        rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7d77);
1902        rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x0);
1903
1904        /* open PA S1 & close SMIXER */
1905        rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020);
1906        rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x60fbd);
1907
1908        /* IQK setting */
1909        rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1910
1911        /* path-B IQK setting */
1912        rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1913        rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1914        rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1915        rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1916
1917        rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82110000);
1918        rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x2816001f);
1919        rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1920        rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1921
1922        /* LO calibration setting */
1923        rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a8d1);
1924        /* enter IQK mode */
1925        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1926
1927        /* One shot, path B LOK & IQK */
1928        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1929        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1930
1931        mdelay(IQK_DELAY_TIME);
1932
1933        /* leave IQK mode */
1934        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1935        /* Check failed */
1936        reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1937        reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD);
1938
1939        /* Allen 20131125 */
1940        tmp = (reg_eac & 0x03FF0000) >> 16;
1941        if ((tmp & 0x200) > 0)
1942                tmp = 0x400 - tmp;
1943
1944        /* if Tx is OK, check whether Rx is OK */
1945        if (!(reg_eac & BIT(27)) &&
1946            (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
1947            (((reg_eac & 0x03FF0000) >> 16) != 0x36))
1948                result |= 0x02;
1949        else if (!(reg_eac & BIT(27)) &&
1950                 (((reg_ea4 & 0x03FF0000) >> 16) < 0x110) &&
1951                 (((reg_ea4 & 0x03FF0000) >> 16) > 0xf0) &&
1952                 (tmp < 0xf))
1953                result |= 0x02;
1954        else
1955                return result;
1956
1957        return result;
1958}
1959
1960static void _rtl8723be_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw,
1961                                                  bool b_iqk_ok,
1962                                                  long result[][8],
1963                                                  u8 final_candidate,
1964                                                  bool btxonly)
1965{
1966        u32 oldval_1, x, tx1_a, reg;
1967        long y, tx1_c;
1968
1969        if (final_candidate == 0xFF) {
1970                return;
1971        } else if (b_iqk_ok) {
1972                oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
1973                                          MASKDWORD) >> 22) & 0x3FF;
1974                x = result[final_candidate][4];
1975                if ((x & 0x00000200) != 0)
1976                        x = x | 0xFFFFFC00;
1977                tx1_a = (x * oldval_1) >> 8;
1978                rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a);
1979                rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27),
1980                              ((x * oldval_1 >> 7) & 0x1));
1981                y = result[final_candidate][5];
1982                if ((y & 0x00000200) != 0)
1983                        y = y | 0xFFFFFC00;
1984                tx1_c = (y * oldval_1) >> 8;
1985                rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000,
1986                              ((tx1_c & 0x3C0) >> 6));
1987                rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000,
1988                              (tx1_c & 0x3F));
1989                rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25),
1990                              ((y * oldval_1 >> 7) & 0x1));
1991                if (btxonly)
1992                        return;
1993                reg = result[final_candidate][6];
1994                rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg);
1995                reg = result[final_candidate][7] & 0x3F;
1996                rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg);
1997                reg = (result[final_candidate][7] >> 6) & 0xF;
1998                /* rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); */
1999        }
2000}
2001
2002static bool _rtl8723be_phy_simularity_compare(struct ieee80211_hw *hw,
2003                                              long result[][8], u8 c1, u8 c2)
2004{
2005        u32 i, j, diff, simularity_bitmap, bound = 0;
2006
2007        u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */
2008        bool bresult = true; /* is2t = true*/
2009        s32 tmp1 = 0, tmp2 = 0;
2010
2011        bound = 8;
2012
2013        simularity_bitmap = 0;
2014
2015        for (i = 0; i < bound; i++) {
2016                if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) {
2017                        if ((result[c1][i] & 0x00000200) != 0)
2018                                tmp1 = result[c1][i] | 0xFFFFFC00;
2019                        else
2020                                tmp1 = result[c1][i];
2021
2022                        if ((result[c2][i] & 0x00000200) != 0)
2023                                tmp2 = result[c2][i] | 0xFFFFFC00;
2024                        else
2025                                tmp2 = result[c2][i];
2026                } else {
2027                        tmp1 = result[c1][i];
2028                        tmp2 = result[c2][i];
2029                }
2030
2031                diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1);
2032
2033                if (diff > MAX_TOLERANCE) {
2034                        if ((i == 2 || i == 6) && !simularity_bitmap) {
2035                                if (result[c1][i] + result[c1][i + 1] == 0)
2036                                        final_candidate[(i / 4)] = c2;
2037                                else if (result[c2][i] + result[c2][i + 1] == 0)
2038                                        final_candidate[(i / 4)] = c1;
2039                                else
2040                                        simularity_bitmap |= (1 << i);
2041                        } else
2042                                simularity_bitmap |= (1 << i);
2043                }
2044        }
2045
2046        if (simularity_bitmap == 0) {
2047                for (i = 0; i < (bound / 4); i++) {
2048                        if (final_candidate[i] != 0xFF) {
2049                                for (j = i * 4; j < (i + 1) * 4 - 2; j++)
2050                                        result[3][j] =
2051                                                result[final_candidate[i]][j];
2052                                bresult = false;
2053                        }
2054                }
2055                return bresult;
2056        } else {
2057                if (!(simularity_bitmap & 0x03)) { /* path A TX OK */
2058                        for (i = 0; i < 2; i++)
2059                                result[3][i] = result[c1][i];
2060                }
2061                if (!(simularity_bitmap & 0x0c)) { /* path A RX OK */
2062                        for (i = 2; i < 4; i++)
2063                                result[3][i] = result[c1][i];
2064                }
2065                if (!(simularity_bitmap & 0x30)) { /* path B TX OK */
2066                        for (i = 4; i < 6; i++)
2067                                result[3][i] = result[c1][i];
2068                }
2069                if (!(simularity_bitmap & 0xc0)) { /* path B RX OK */
2070                        for (i = 6; i < 8; i++)
2071                                result[3][i] = result[c1][i];
2072                }
2073                return false;
2074        }
2075}
2076
2077static void _rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw,
2078                                        long result[][8], u8 t, bool is2t)
2079{
2080        struct rtl_priv *rtlpriv = rtl_priv(hw);
2081        struct rtl_phy *rtlphy = &rtlpriv->phy;
2082        u32 i;
2083        u8 patha_ok, pathb_ok;
2084        u32 adda_reg[IQK_ADDA_REG_NUM] = {
2085                0x85c, 0xe6c, 0xe70, 0xe74,
2086                0xe78, 0xe7c, 0xe80, 0xe84,
2087                0xe88, 0xe8c, 0xed0, 0xed4,
2088                0xed8, 0xedc, 0xee0, 0xeec
2089        };
2090
2091        u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
2092                0x522, 0x550, 0x551, 0x040
2093        };
2094        u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
2095                ROFDM0_TRXPATHENABLE, ROFDM0_TRMUXPAR,
2096                RFPGA0_XCD_RFINTERFACESW, 0xb68, 0xb6c,
2097                0x870, 0x860,
2098                0x864, 0xa04
2099        };
2100        const u32 retrycount = 2;
2101
2102        u32 path_sel_bb;/* path_sel_rf */
2103
2104        u8 tmp_reg_c50, tmp_reg_c58;
2105
2106        tmp_reg_c50 = rtl_get_bbreg(hw, 0xc50, MASKBYTE0);
2107        tmp_reg_c58 = rtl_get_bbreg(hw, 0xc58, MASKBYTE0);
2108
2109        if (t == 0) {
2110                rtl8723_save_adda_registers(hw, adda_reg,
2111                                            rtlphy->adda_backup, 16);
2112                rtl8723_phy_save_mac_registers(hw, iqk_mac_reg,
2113                                               rtlphy->iqk_mac_backup);
2114                rtl8723_save_adda_registers(hw, iqk_bb_reg,
2115                                            rtlphy->iqk_bb_backup,
2116                                            IQK_BB_REG_NUM);
2117        }
2118        rtl8723_phy_path_adda_on(hw, adda_reg, true, is2t);
2119        if (t == 0) {
2120                rtlphy->rfpi_enable = (u8)rtl_get_bbreg(hw,
2121                                                RFPGA0_XA_HSSIPARAMETER1,
2122                                                BIT(8));
2123        }
2124
2125        path_sel_bb = rtl_get_bbreg(hw, 0x948, MASKDWORD);
2126
2127        rtl8723_phy_mac_setting_calibration(hw, iqk_mac_reg,
2128                                            rtlphy->iqk_mac_backup);
2129        /*BB Setting*/
2130        rtl_set_bbreg(hw, 0xa04, 0x0f000000, 0xf);
2131        rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
2132        rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
2133        rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
2134
2135        /* path A TX IQK */
2136        for (i = 0; i < retrycount; i++) {
2137                patha_ok = _rtl8723be_phy_path_a_iqk(hw);
2138                if (patha_ok == 0x01) {
2139                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2140                                "Path A Tx IQK Success!!\n");
2141                        result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
2142                                        0x3FF0000) >> 16;
2143                        result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
2144                                        0x3FF0000) >> 16;
2145                        break;
2146                } else {
2147                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2148                                 "Path A Tx IQK Fail!!\n");
2149                }
2150        }
2151        /* path A RX IQK */
2152        for (i = 0; i < retrycount; i++) {
2153                patha_ok = _rtl8723be_phy_path_a_rx_iqk(hw);
2154                if (patha_ok == 0x03) {
2155                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2156                                 "Path A Rx IQK Success!!\n");
2157                        result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &
2158                                        0x3FF0000) >> 16;
2159                        result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &
2160                                        0x3FF0000) >> 16;
2161                        break;
2162                }
2163                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2164                         "Path A Rx IQK Fail!!\n");
2165        }
2166
2167        if (0x00 == patha_ok)
2168                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Path A IQK Fail!!\n");
2169
2170        if (is2t) {
2171                /* path B TX IQK */
2172                for (i = 0; i < retrycount; i++) {
2173                        pathb_ok = _rtl8723be_phy_path_b_iqk(hw);
2174                        if (pathb_ok == 0x01) {
2175                                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2176                                         "Path B Tx IQK Success!!\n");
2177                                result[t][4] = (rtl_get_bbreg(hw, 0xe94,
2178                                                              MASKDWORD) &
2179                                                              0x3FF0000) >> 16;
2180                                result[t][5] = (rtl_get_bbreg(hw, 0xe9c,
2181                                                              MASKDWORD) &
2182                                                              0x3FF0000) >> 16;
2183                                break;
2184                        }
2185                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2186                                 "Path B Tx IQK Fail!!\n");
2187                }
2188                /* path B RX IQK */
2189                for (i = 0; i < retrycount; i++) {
2190                        pathb_ok = _rtl8723be_phy_path_b_rx_iqk(hw);
2191                        if (pathb_ok == 0x03) {
2192                                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2193                                         "Path B Rx IQK Success!!\n");
2194                                result[t][6] = (rtl_get_bbreg(hw, 0xea4,
2195                                                              MASKDWORD) &
2196                                                              0x3FF0000) >> 16;
2197                                result[t][7] = (rtl_get_bbreg(hw, 0xeac,
2198                                                              MASKDWORD) &
2199                                                              0x3FF0000) >> 16;
2200                                break;
2201                        }
2202                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2203                                 "Path B Rx IQK Fail!!\n");
2204                }
2205        }
2206
2207        /* Back to BB mode, load original value */
2208        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0);
2209
2210        if (t != 0) {
2211                rtl8723_phy_reload_adda_registers(hw, adda_reg,
2212                                                  rtlphy->adda_backup, 16);
2213                rtl8723_phy_reload_mac_registers(hw, iqk_mac_reg,
2214                                                 rtlphy->iqk_mac_backup);
2215                rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
2216                                                  rtlphy->iqk_bb_backup,
2217                                                  IQK_BB_REG_NUM);
2218
2219                rtl_set_bbreg(hw, 0x948, MASKDWORD, path_sel_bb);
2220                /*rtl_set_rfreg(hw, RF90_PATH_B, 0xb0, 0xfffff, path_sel_rf);*/
2221
2222                rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50);
2223                rtl_set_bbreg(hw, 0xc50, MASKBYTE0, tmp_reg_c50);
2224                if (is2t) {
2225                        rtl_set_bbreg(hw, 0xc58, MASKBYTE0, 0x50);
2226                        rtl_set_bbreg(hw, 0xc58, MASKBYTE0, tmp_reg_c58);
2227                }
2228                rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00);
2229                rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00);
2230        }
2231        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "8723be IQK Finish!!\n");
2232}
2233
2234static u8 _get_right_chnl_place_for_iqk(u8 chnl)
2235{
2236        u8 channel_all[TARGET_CHNL_NUM_2G_5G] = {
2237                        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
2238                        13, 14, 36, 38, 40, 42, 44, 46,
2239                        48, 50, 52, 54, 56, 58, 60, 62, 64,
2240                        100, 102, 104, 106, 108, 110,
2241                        112, 114, 116, 118, 120, 122,
2242                        124, 126, 128, 130, 132, 134, 136,
2243                        138, 140, 149, 151, 153, 155, 157,
2244                        159, 161, 163, 165};
2245        u8 place = chnl;
2246
2247        if (chnl > 14) {
2248                for (place = 14; place < sizeof(channel_all); place++) {
2249                        if (channel_all[place] == chnl)
2250                                return place - 13;
2251                }
2252        }
2253        return 0;
2254}
2255
2256static void _rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
2257{
2258        u8 tmpreg;
2259        u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
2260        struct rtl_priv *rtlpriv = rtl_priv(hw);
2261
2262        tmpreg = rtl_read_byte(rtlpriv, 0xd03);
2263
2264        if ((tmpreg & 0x70) != 0)
2265                rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
2266        else
2267                rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2268
2269        if ((tmpreg & 0x70) != 0) {
2270                rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
2271
2272                if (is2t)
2273                        rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
2274                                                  MASK12BITS);
2275
2276                rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
2277                              (rf_a_mode & 0x8FFFF) | 0x10000);
2278
2279                if (is2t)
2280                        rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
2281                                      (rf_b_mode & 0x8FFFF) | 0x10000);
2282        }
2283        lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
2284
2285        rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdfbe0);
2286        rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, 0x8c0a);
2287
2288        /* In order not to disturb BT music when wifi init.(1ant NIC only) */
2289        /*mdelay(100);*/
2290        /* In order not to disturb BT music when wifi init.(1ant NIC only) */
2291        mdelay(50);
2292
2293        rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdffe0);
2294
2295        if ((tmpreg & 0x70) != 0) {
2296                rtl_write_byte(rtlpriv, 0xd03, tmpreg);
2297                rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
2298
2299                if (is2t)
2300                        rtl_set_rfreg(hw, RF90_PATH_B, 0x00,
2301                                      MASK12BITS, rf_b_mode);
2302        } else {
2303                rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2304        }
2305        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
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 %#x not processed\n", iotype);
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 %#x not processed\n",
2558                         rtlphy->current_io_type);
2559                break;
2560        }
2561        rtlphy->set_io_inprogress = false;
2562        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2563                 "(%#x)\n", rtlphy->current_io_type);
2564}
2565
2566static void rtl8723be_phy_set_rf_on(struct ieee80211_hw *hw)
2567{
2568        struct rtl_priv *rtlpriv = rtl_priv(hw);
2569
2570        rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
2571        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2572        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2573        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2574        rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2575}
2576
2577static void _rtl8723be_phy_set_rf_sleep(struct ieee80211_hw *hw)
2578{
2579        struct rtl_priv *rtlpriv = rtl_priv(hw);
2580
2581        rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2582        rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
2583        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2584        rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
2585}
2586
2587static bool _rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2588                                              enum rf_pwrstate rfpwr_state)
2589{
2590        struct rtl_priv *rtlpriv = rtl_priv(hw);
2591        struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2592        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2593        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2594        bool bresult = true;
2595        u8 i, queue_id;
2596        struct rtl8192_tx_ring *ring = NULL;
2597
2598        switch (rfpwr_state) {
2599        case ERFON:
2600                if ((ppsc->rfpwr_state == ERFOFF) &&
2601                     RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
2602                        bool rtstatus;
2603                        u32 initializecount = 0;
2604                        do {
2605                                initializecount++;
2606                                RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2607                                         "IPS Set eRf nic enable\n");
2608                                rtstatus = rtl_ps_enable_nic(hw);
2609                        } while (!rtstatus && (initializecount < 10));
2610                        RT_CLEAR_PS_LEVEL(ppsc, 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 %#x not processed\n", rfpwr_state);
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