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