linux/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright(c) 2009-2010  Realtek Corporation.*/
   3
   4#include "../wifi.h"
   5#include "../pci.h"
   6#include "../ps.h"
   7#include "reg.h"
   8#include "def.h"
   9#include "phy.h"
  10#include "rf.h"
  11#include "dm.h"
  12#include "table.h"
  13#include "trx.h"
  14#include "../btcoexist/halbt_precomp.h"
  15#include "hw.h"
  16#include "../efuse.h"
  17
  18#define READ_NEXT_PAIR(array_table, v1, v2, i) \
  19        do { \
  20                i += 2; \
  21                v1 = array_table[i]; \
  22                v2 = array_table[i+1]; \
  23        } while (0)
  24
  25static u32 _rtl8821ae_phy_rf_serial_read(struct ieee80211_hw *hw,
  26                                         enum radio_path rfpath, u32 offset);
  27static void _rtl8821ae_phy_rf_serial_write(struct ieee80211_hw *hw,
  28                                           enum radio_path rfpath, u32 offset,
  29                                           u32 data);
  30static u32 _rtl8821ae_phy_calculate_bit_shift(u32 bitmask);
  31static bool _rtl8821ae_phy_bb8821a_config_parafile(struct ieee80211_hw *hw);
  32/*static bool _rtl8812ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);*/
  33static bool _rtl8821ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
  34static bool _rtl8821ae_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
  35                                                     u8 configtype);
  36static bool _rtl8821ae_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
  37                                                       u8 configtype);
  38static void phy_init_bb_rf_register_definition(struct ieee80211_hw *hw);
  39
  40static long _rtl8821ae_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
  41                                            enum wireless_mode wirelessmode,
  42                                            u8 txpwridx);
  43static void rtl8821ae_phy_set_rf_on(struct ieee80211_hw *hw);
  44static void rtl8821ae_phy_set_io(struct ieee80211_hw *hw);
  45
  46static void rtl8812ae_fixspur(struct ieee80211_hw *hw,
  47                              enum ht_channel_width band_width, u8 channel)
  48{
  49        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  50
  51        /*C cut Item12 ADC FIFO CLOCK*/
  52        if (IS_VENDOR_8812A_C_CUT(rtlhal->version)) {
  53                if (band_width == HT_CHANNEL_WIDTH_20_40 && channel == 11)
  54                        rtl_set_bbreg(hw, RRFMOD, 0xC00, 0x3);
  55                        /* 0x8AC[11:10] = 2'b11*/
  56                else
  57                        rtl_set_bbreg(hw, RRFMOD, 0xC00, 0x2);
  58                        /* 0x8AC[11:10] = 2'b10*/
  59
  60                /* <20120914, Kordan> A workarould to resolve
  61                 * 2480Mhz spur by setting ADC clock as 160M. (Asked by Binson)
  62                 */
  63                if (band_width == HT_CHANNEL_WIDTH_20 &&
  64                    (channel == 13 || channel == 14)) {
  65                        rtl_set_bbreg(hw, RRFMOD, 0x300, 0x3);
  66                        /*0x8AC[9:8] = 2'b11*/
  67                        rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 1);
  68                        /* 0x8C4[30] = 1*/
  69                } else if (band_width == HT_CHANNEL_WIDTH_20_40 &&
  70                           channel == 11) {
  71                        rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 1);
  72                        /*0x8C4[30] = 1*/
  73                } else if (band_width != HT_CHANNEL_WIDTH_80) {
  74                        rtl_set_bbreg(hw, RRFMOD, 0x300, 0x2);
  75                        /*0x8AC[9:8] = 2'b10*/
  76                        rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
  77                        /*0x8C4[30] = 0*/
  78                }
  79        } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
  80                /* <20120914, Kordan> A workarould to resolve
  81                 * 2480Mhz spur by setting ADC clock as 160M.
  82                 */
  83                if (band_width == HT_CHANNEL_WIDTH_20 &&
  84                    (channel == 13 || channel == 14))
  85                        rtl_set_bbreg(hw, RRFMOD, 0x300, 0x3);
  86                        /*0x8AC[9:8] = 11*/
  87                else if (channel  <= 14) /*2.4G only*/
  88                        rtl_set_bbreg(hw, RRFMOD, 0x300, 0x2);
  89                        /*0x8AC[9:8] = 10*/
  90        }
  91}
  92
  93u32 rtl8821ae_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr,
  94                               u32 bitmask)
  95{
  96        struct rtl_priv *rtlpriv = rtl_priv(hw);
  97        u32 returnvalue, originalvalue, bitshift;
  98
  99        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 100                 "regaddr(%#x), bitmask(%#x)\n",
 101                 regaddr, bitmask);
 102        originalvalue = rtl_read_dword(rtlpriv, regaddr);
 103        bitshift = _rtl8821ae_phy_calculate_bit_shift(bitmask);
 104        returnvalue = (originalvalue & bitmask) >> bitshift;
 105
 106        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 107                 "BBR MASK=0x%x Addr[0x%x]=0x%x\n",
 108                 bitmask, regaddr, originalvalue);
 109        return returnvalue;
 110}
 111
 112void rtl8821ae_phy_set_bb_reg(struct ieee80211_hw *hw,
 113                              u32 regaddr, u32 bitmask, u32 data)
 114{
 115        struct rtl_priv *rtlpriv = rtl_priv(hw);
 116        u32 originalvalue, bitshift;
 117
 118        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 119                 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
 120                 regaddr, bitmask, data);
 121
 122        if (bitmask != MASKDWORD) {
 123                originalvalue = rtl_read_dword(rtlpriv, regaddr);
 124                bitshift = _rtl8821ae_phy_calculate_bit_shift(bitmask);
 125                data = ((originalvalue & (~bitmask)) |
 126                        ((data << bitshift) & bitmask));
 127        }
 128
 129        rtl_write_dword(rtlpriv, regaddr, data);
 130
 131        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 132                 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
 133                 regaddr, bitmask, data);
 134}
 135
 136u32 rtl8821ae_phy_query_rf_reg(struct ieee80211_hw *hw,
 137                               enum radio_path rfpath, u32 regaddr,
 138                               u32 bitmask)
 139{
 140        struct rtl_priv *rtlpriv = rtl_priv(hw);
 141        u32 original_value, readback_value, bitshift;
 142
 143        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 144                 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
 145                 regaddr, rfpath, bitmask);
 146
 147        spin_lock(&rtlpriv->locks.rf_lock);
 148
 149        original_value = _rtl8821ae_phy_rf_serial_read(hw, rfpath, regaddr);
 150        bitshift = _rtl8821ae_phy_calculate_bit_shift(bitmask);
 151        readback_value = (original_value & bitmask) >> bitshift;
 152
 153        spin_unlock(&rtlpriv->locks.rf_lock);
 154
 155        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 156                 "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
 157                 regaddr, rfpath, bitmask, original_value);
 158
 159        return readback_value;
 160}
 161
 162void rtl8821ae_phy_set_rf_reg(struct ieee80211_hw *hw,
 163                           enum radio_path rfpath,
 164                           u32 regaddr, u32 bitmask, u32 data)
 165{
 166        struct rtl_priv *rtlpriv = rtl_priv(hw);
 167        u32 original_value, bitshift;
 168
 169        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 170                 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
 171                  regaddr, bitmask, data, rfpath);
 172
 173        spin_lock(&rtlpriv->locks.rf_lock);
 174
 175        if (bitmask != RFREG_OFFSET_MASK) {
 176                original_value =
 177                   _rtl8821ae_phy_rf_serial_read(hw, rfpath, regaddr);
 178                bitshift = _rtl8821ae_phy_calculate_bit_shift(bitmask);
 179                data = ((original_value & (~bitmask)) | (data << bitshift));
 180        }
 181
 182        _rtl8821ae_phy_rf_serial_write(hw, rfpath, regaddr, data);
 183
 184        spin_unlock(&rtlpriv->locks.rf_lock);
 185
 186        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 187                 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
 188                 regaddr, bitmask, data, rfpath);
 189}
 190
 191static u32 _rtl8821ae_phy_rf_serial_read(struct ieee80211_hw *hw,
 192                                         enum radio_path rfpath, u32 offset)
 193{
 194        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 195        bool is_pi_mode = false;
 196        u32 retvalue = 0;
 197
 198        /* 2009/06/17 MH We can not execute IO for power
 199        save or other accident mode.*/
 200        if (RT_CANNOT_IO(hw)) {
 201                pr_err("return all one\n");
 202                return 0xFFFFFFFF;
 203        }
 204        /* <20120809, Kordan> CCA OFF(when entering),
 205                asked by James to avoid reading the wrong value.
 206            <20120828, Kordan> Toggling CCA would affect RF 0x0, skip it!*/
 207        if (offset != 0x0 &&
 208            !((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) ||
 209            (IS_VENDOR_8812A_C_CUT(rtlhal->version))))
 210                rtl_set_bbreg(hw, RCCAONSEC, 0x8, 1);
 211        offset &= 0xff;
 212
 213        if (rfpath == RF90_PATH_A)
 214                is_pi_mode = (bool)rtl_get_bbreg(hw, 0xC00, 0x4);
 215        else if (rfpath == RF90_PATH_B)
 216                is_pi_mode = (bool)rtl_get_bbreg(hw, 0xE00, 0x4);
 217
 218        rtl_set_bbreg(hw, RHSSIREAD_8821AE, 0xff, offset);
 219
 220        if ((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) ||
 221            (IS_VENDOR_8812A_C_CUT(rtlhal->version)))
 222                udelay(20);
 223
 224        if (is_pi_mode) {
 225                if (rfpath == RF90_PATH_A)
 226                        retvalue =
 227                          rtl_get_bbreg(hw, RA_PIREAD_8821A, BLSSIREADBACKDATA);
 228                else if (rfpath == RF90_PATH_B)
 229                        retvalue =
 230                          rtl_get_bbreg(hw, RB_PIREAD_8821A, BLSSIREADBACKDATA);
 231        } else {
 232                if (rfpath == RF90_PATH_A)
 233                        retvalue =
 234                          rtl_get_bbreg(hw, RA_SIREAD_8821A, BLSSIREADBACKDATA);
 235                else if (rfpath == RF90_PATH_B)
 236                        retvalue =
 237                          rtl_get_bbreg(hw, RB_SIREAD_8821A, BLSSIREADBACKDATA);
 238        }
 239
 240        /*<20120809, Kordan> CCA ON(when exiting),
 241         * asked by James to avoid reading the wrong value.
 242         *   <20120828, Kordan> Toggling CCA would affect RF 0x0, skip it!
 243         */
 244        if (offset != 0x0 &&
 245            !((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) ||
 246            (IS_VENDOR_8812A_C_CUT(rtlhal->version))))
 247                rtl_set_bbreg(hw, RCCAONSEC, 0x8, 0);
 248        return retvalue;
 249}
 250
 251static void _rtl8821ae_phy_rf_serial_write(struct ieee80211_hw *hw,
 252                                           enum radio_path rfpath, u32 offset,
 253                                           u32 data)
 254{
 255        struct rtl_priv *rtlpriv = rtl_priv(hw);
 256        struct rtl_phy *rtlphy = &rtlpriv->phy;
 257        struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
 258        u32 data_and_addr;
 259        u32 newoffset;
 260
 261        if (RT_CANNOT_IO(hw)) {
 262                pr_err("stop\n");
 263                return;
 264        }
 265        offset &= 0xff;
 266        newoffset = offset;
 267        data_and_addr = ((newoffset << 20) |
 268                         (data & 0x000fffff)) & 0x0fffffff;
 269        rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
 270        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 271                 "RFW-%d Addr[0x%x]=0x%x\n",
 272                 rfpath, pphyreg->rf3wire_offset, data_and_addr);
 273}
 274
 275static u32 _rtl8821ae_phy_calculate_bit_shift(u32 bitmask)
 276{
 277        u32 i;
 278
 279        for (i = 0; i <= 31; i++) {
 280                if (((bitmask >> i) & 0x1) == 1)
 281                        break;
 282        }
 283        return i;
 284}
 285
 286bool rtl8821ae_phy_mac_config(struct ieee80211_hw *hw)
 287{
 288        bool rtstatus = 0;
 289
 290        rtstatus = _rtl8821ae_phy_config_mac_with_headerfile(hw);
 291
 292        return rtstatus;
 293}
 294
 295bool rtl8821ae_phy_bb_config(struct ieee80211_hw *hw)
 296{
 297        bool rtstatus = true;
 298        struct rtl_priv *rtlpriv = rtl_priv(hw);
 299        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 300        struct rtl_phy *rtlphy = &rtlpriv->phy;
 301        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 302        u8 regval;
 303        u8 crystal_cap;
 304
 305        phy_init_bb_rf_register_definition(hw);
 306
 307        regval = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN);
 308        regval |= FEN_PCIEA;
 309        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, regval);
 310        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
 311                       regval | FEN_BB_GLB_RSTN | FEN_BBRSTB);
 312
 313        rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x7);
 314        rtl_write_byte(rtlpriv, REG_OPT_CTRL + 2, 0x7);
 315
 316        rtstatus = _rtl8821ae_phy_bb8821a_config_parafile(hw);
 317
 318        if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
 319                crystal_cap = rtlefuse->crystalcap & 0x3F;
 320                rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0x7FF80000,
 321                              (crystal_cap | (crystal_cap << 6)));
 322        } else {
 323                crystal_cap = rtlefuse->crystalcap & 0x3F;
 324                rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
 325                              (crystal_cap | (crystal_cap << 6)));
 326        }
 327        rtlphy->reg_837 = rtl_read_byte(rtlpriv, 0x837);
 328
 329        return rtstatus;
 330}
 331
 332bool rtl8821ae_phy_rf_config(struct ieee80211_hw *hw)
 333{
 334        return rtl8821ae_phy_rf6052_config(hw);
 335}
 336
 337static void _rtl8812ae_phy_set_rfe_reg_24g(struct ieee80211_hw *hw)
 338{
 339        struct rtl_priv *rtlpriv = rtl_priv(hw);
 340        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 341        u8 tmp;
 342
 343        switch (rtlhal->rfe_type) {
 344        case 3:
 345                rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 0x54337770);
 346                rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x54337770);
 347                rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x010);
 348                rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x010);
 349                rtl_set_bbreg(hw, 0x900, 0x00000303, 0x1);
 350                break;
 351        case 4:
 352                rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 0x77777777);
 353                rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x77777777);
 354                rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x001);
 355                rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x001);
 356                break;
 357        case 5:
 358                rtl_write_byte(rtlpriv, RA_RFE_PINMUX + 2, 0x77);
 359                rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x77777777);
 360                tmp = rtl_read_byte(rtlpriv, RA_RFE_INV + 3);
 361                rtl_write_byte(rtlpriv, RA_RFE_INV + 3, tmp & ~0x1);
 362                rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x000);
 363                break;
 364        case 1:
 365                if (rtlpriv->btcoexist.bt_coexistence) {
 366                        rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xffffff, 0x777777);
 367                        rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD,
 368                                      0x77777777);
 369                        rtl_set_bbreg(hw, RA_RFE_INV, 0x33f00000, 0x000);
 370                        rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x000);
 371                        break;
 372                }
 373                /* fall through */
 374        case 0:
 375        case 2:
 376        default:
 377                rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 0x77777777);
 378                rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x77777777);
 379                rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x000);
 380                rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x000);
 381                break;
 382        }
 383}
 384
 385static void _rtl8812ae_phy_set_rfe_reg_5g(struct ieee80211_hw *hw)
 386{
 387        struct rtl_priv *rtlpriv = rtl_priv(hw);
 388        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 389        u8 tmp;
 390
 391        switch (rtlhal->rfe_type) {
 392        case 0:
 393                rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 0x77337717);
 394                rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x77337717);
 395                rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x010);
 396                rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x010);
 397                break;
 398        case 1:
 399                if (rtlpriv->btcoexist.bt_coexistence) {
 400                        rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xffffff, 0x337717);
 401                        rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD,
 402                                      0x77337717);
 403                        rtl_set_bbreg(hw, RA_RFE_INV, 0x33f00000, 0x000);
 404                        rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x000);
 405                } else {
 406                        rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD,
 407                                      0x77337717);
 408                        rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD,
 409                                      0x77337717);
 410                        rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x000);
 411                        rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x000);
 412                }
 413                break;
 414        case 3:
 415                rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 0x54337717);
 416                rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x54337717);
 417                rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x010);
 418                rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x010);
 419                rtl_set_bbreg(hw, 0x900, 0x00000303, 0x1);
 420                break;
 421        case 5:
 422                rtl_write_byte(rtlpriv, RA_RFE_PINMUX + 2, 0x33);
 423                rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x77337777);
 424                tmp = rtl_read_byte(rtlpriv, RA_RFE_INV + 3);
 425                rtl_write_byte(rtlpriv, RA_RFE_INV + 3, tmp | 0x1);
 426                rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x010);
 427                break;
 428        case 2:
 429        case 4:
 430        default:
 431                rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 0x77337777);
 432                rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 0x77337777);
 433                rtl_set_bbreg(hw, RA_RFE_INV, BMASKRFEINV, 0x010);
 434                rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x010);
 435                break;
 436        }
 437}
 438
 439u32 phy_get_tx_swing_8812A(struct ieee80211_hw *hw, u8  band,
 440                           u8 rf_path)
 441{
 442        struct rtl_priv *rtlpriv = rtl_priv(hw);
 443        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 444        struct rtl_dm *rtldm = rtl_dm(rtlpriv);
 445        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 446        s8 reg_swing_2g = -1;/* 0xff; */
 447        s8 reg_swing_5g = -1;/* 0xff; */
 448        s8 swing_2g = -1 * reg_swing_2g;
 449        s8 swing_5g = -1 * reg_swing_5g;
 450        u32  out = 0x200;
 451        const s8 auto_temp = -1;
 452
 453        RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
 454                 "===> PHY_GetTXBBSwing_8812A, bbSwing_2G: %d, bbSwing_5G: %d,autoload_failflag=%d.\n",
 455                 (int)swing_2g, (int)swing_5g,
 456                 (int)rtlefuse->autoload_failflag);
 457
 458        if (rtlefuse->autoload_failflag) {
 459                if (band == BAND_ON_2_4G) {
 460                        rtldm->swing_diff_2g = swing_2g;
 461                        if (swing_2g == 0) {
 462                                out = 0x200; /* 0 dB */
 463                        } else if (swing_2g == -3) {
 464                                out = 0x16A; /* -3 dB */
 465                        } else if (swing_2g == -6) {
 466                                out = 0x101; /* -6 dB */
 467                        } else if (swing_2g == -9) {
 468                                out = 0x0B6; /* -9 dB */
 469                        } else {
 470                                rtldm->swing_diff_2g = 0;
 471                                out = 0x200;
 472                        }
 473                } else if (band == BAND_ON_5G) {
 474                        rtldm->swing_diff_5g = swing_5g;
 475                        if (swing_5g == 0) {
 476                                out = 0x200; /* 0 dB */
 477                        } else if (swing_5g == -3) {
 478                                out = 0x16A; /* -3 dB */
 479                        } else if (swing_5g == -6) {
 480                                out = 0x101; /* -6 dB */
 481                        } else if (swing_5g == -9) {
 482                                out = 0x0B6; /* -9 dB */
 483                        } else {
 484                                if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
 485                                        rtldm->swing_diff_5g = -3;
 486                                        out = 0x16A;
 487                                } else {
 488                                        rtldm->swing_diff_5g = 0;
 489                                        out = 0x200;
 490                                }
 491                        }
 492                } else {
 493                        rtldm->swing_diff_2g = -3;
 494                        rtldm->swing_diff_5g = -3;
 495                        out = 0x16A; /* -3 dB */
 496                }
 497        } else {
 498                u32 swing = 0, swing_a = 0, swing_b = 0;
 499
 500                if (band == BAND_ON_2_4G) {
 501                        if (reg_swing_2g == auto_temp) {
 502                                efuse_shadow_read(hw, 1, 0xC6, (u32 *)&swing);
 503                                swing = (swing == 0xFF) ? 0x00 : swing;
 504                        } else if (swing_2g ==  0) {
 505                                swing = 0x00; /* 0 dB */
 506                        } else if (swing_2g == -3) {
 507                                swing = 0x05; /* -3 dB */
 508                        } else if (swing_2g == -6) {
 509                                swing = 0x0A; /* -6 dB */
 510                        } else if (swing_2g == -9) {
 511                                swing = 0xFF; /* -9 dB */
 512                        } else {
 513                                swing = 0x00;
 514                        }
 515                } else {
 516                        if (reg_swing_5g == auto_temp) {
 517                                efuse_shadow_read(hw, 1, 0xC7, (u32 *)&swing);
 518                                swing = (swing == 0xFF) ? 0x00 : swing;
 519                        } else if (swing_5g ==  0) {
 520                                swing = 0x00; /* 0 dB */
 521                        } else if (swing_5g == -3) {
 522                                swing = 0x05; /* -3 dB */
 523                        } else if (swing_5g == -6) {
 524                                swing = 0x0A; /* -6 dB */
 525                        } else if (swing_5g == -9) {
 526                                swing = 0xFF; /* -9 dB */
 527                        } else {
 528                                swing = 0x00;
 529                        }
 530                }
 531
 532                swing_a = (swing & 0x3) >> 0; /* 0xC6/C7[1:0] */
 533                swing_b = (swing & 0xC) >> 2; /* 0xC6/C7[3:2] */
 534                RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
 535                         "===> PHY_GetTXBBSwing_8812A, swingA: 0x%X, swingB: 0x%X\n",
 536                         swing_a, swing_b);
 537
 538                /* 3 Path-A */
 539                if (swing_a == 0x0) {
 540                        if (band == BAND_ON_2_4G)
 541                                rtldm->swing_diff_2g = 0;
 542                        else
 543                                rtldm->swing_diff_5g = 0;
 544                        out = 0x200; /* 0 dB */
 545                } else if (swing_a == 0x1) {
 546                        if (band == BAND_ON_2_4G)
 547                                rtldm->swing_diff_2g = -3;
 548                        else
 549                                rtldm->swing_diff_5g = -3;
 550                        out = 0x16A; /* -3 dB */
 551                } else if (swing_a == 0x2) {
 552                        if (band == BAND_ON_2_4G)
 553                                rtldm->swing_diff_2g = -6;
 554                        else
 555                                rtldm->swing_diff_5g = -6;
 556                        out = 0x101; /* -6 dB */
 557                } else if (swing_a == 0x3) {
 558                        if (band == BAND_ON_2_4G)
 559                                rtldm->swing_diff_2g = -9;
 560                        else
 561                                rtldm->swing_diff_5g = -9;
 562                        out = 0x0B6; /* -9 dB */
 563                }
 564                /* 3 Path-B */
 565                if (swing_b == 0x0) {
 566                        if (band == BAND_ON_2_4G)
 567                                rtldm->swing_diff_2g = 0;
 568                        else
 569                                rtldm->swing_diff_5g = 0;
 570                        out = 0x200; /* 0 dB */
 571                } else if (swing_b == 0x1) {
 572                        if (band == BAND_ON_2_4G)
 573                                rtldm->swing_diff_2g = -3;
 574                        else
 575                                rtldm->swing_diff_5g = -3;
 576                        out = 0x16A; /* -3 dB */
 577                } else if (swing_b == 0x2) {
 578                        if (band == BAND_ON_2_4G)
 579                                rtldm->swing_diff_2g = -6;
 580                        else
 581                                rtldm->swing_diff_5g = -6;
 582                        out = 0x101; /* -6 dB */
 583                } else if (swing_b == 0x3) {
 584                        if (band == BAND_ON_2_4G)
 585                                rtldm->swing_diff_2g = -9;
 586                        else
 587                                rtldm->swing_diff_5g = -9;
 588                        out = 0x0B6; /* -9 dB */
 589                }
 590        }
 591
 592        RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
 593                 "<=== PHY_GetTXBBSwing_8812A, out = 0x%X\n", out);
 594        return out;
 595}
 596
 597void rtl8821ae_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band)
 598{
 599        struct rtl_priv *rtlpriv = rtl_priv(hw);
 600        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 601        struct rtl_dm *rtldm = rtl_dm(rtlpriv);
 602        u8 current_band = rtlhal->current_bandtype;
 603        u32 txpath, rxpath;
 604        s8 bb_diff_between_band;
 605
 606        txpath = rtl8821ae_phy_query_bb_reg(hw, RTXPATH, 0xf0);
 607        rxpath = rtl8821ae_phy_query_bb_reg(hw, RCCK_RX, 0x0f000000);
 608        rtlhal->current_bandtype = (enum band_type) band;
 609        /* reconfig BB/RF according to wireless mode */
 610        if (rtlhal->current_bandtype == BAND_ON_2_4G) {
 611                /* BB & RF Config */
 612                rtl_set_bbreg(hw, ROFDMCCKEN, BOFDMEN|BCCKEN, 0x03);
 613
 614                if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
 615                        /* 0xCB0[15:12] = 0x7 (LNA_On)*/
 616                        rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF000, 0x7);
 617                        /* 0xCB0[7:4] = 0x7 (PAPE_A)*/
 618                        rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF0, 0x7);
 619                }
 620
 621                if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
 622                        /*0x834[1:0] = 0x1*/
 623                        rtl_set_bbreg(hw, 0x834, 0x3, 0x1);
 624                }
 625
 626                if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
 627                        /* 0xC1C[11:8] = 0 */
 628                        rtl_set_bbreg(hw, RA_TXSCALE, 0xF00, 0);
 629                } else {
 630                        /* 0x82C[1:0] = 2b'00 */
 631                        rtl_set_bbreg(hw, 0x82c, 0x3, 0);
 632                }
 633
 634                if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
 635                        _rtl8812ae_phy_set_rfe_reg_24g(hw);
 636
 637                rtl_set_bbreg(hw, RTXPATH, 0xf0, 0x1);
 638                rtl_set_bbreg(hw, RCCK_RX, 0x0f000000, 0x1);
 639
 640                rtl_write_byte(rtlpriv, REG_CCK_CHECK, 0x0);
 641        } else {/* 5G band */
 642                u16 count, reg_41a;
 643
 644                if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
 645                        /*0xCB0[15:12] = 0x5 (LNA_On)*/
 646                        rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF000, 0x5);
 647                        /*0xCB0[7:4] = 0x4 (PAPE_A)*/
 648                        rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF0, 0x4);
 649                }
 650                /*CCK_CHECK_en*/
 651                rtl_write_byte(rtlpriv, REG_CCK_CHECK, 0x80);
 652
 653                count = 0;
 654                reg_41a = rtl_read_word(rtlpriv, REG_TXPKT_EMPTY);
 655                RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
 656                         "Reg41A value %d\n", reg_41a);
 657                reg_41a &= 0x30;
 658                while ((reg_41a != 0x30) && (count < 50)) {
 659                        udelay(50);
 660                        RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "Delay 50us\n");
 661
 662                        reg_41a = rtl_read_word(rtlpriv, REG_TXPKT_EMPTY);
 663                        reg_41a &= 0x30;
 664                        count++;
 665                        RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
 666                                 "Reg41A value %d\n", reg_41a);
 667                }
 668                if (count != 0)
 669                        RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
 670                                 "PHY_SwitchWirelessBand8812(): Switch to 5G Band. Count = %d reg41A=0x%x\n",
 671                                 count, reg_41a);
 672
 673                /* 2012/02/01, Sinda add registry to switch workaround
 674                without long-run verification for scan issue. */
 675                rtl_set_bbreg(hw, ROFDMCCKEN, BOFDMEN|BCCKEN, 0x03);
 676
 677                if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
 678                        /*0x834[1:0] = 0x2*/
 679                        rtl_set_bbreg(hw, 0x834, 0x3, 0x2);
 680                }
 681
 682                if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
 683                        /* AGC table select */
 684                        /* 0xC1C[11:8] = 1*/
 685                        rtl_set_bbreg(hw, RA_TXSCALE, 0xF00, 1);
 686                } else
 687                        /* 0x82C[1:0] = 2'b00 */
 688                        rtl_set_bbreg(hw, 0x82c, 0x3, 1);
 689
 690                if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
 691                        _rtl8812ae_phy_set_rfe_reg_5g(hw);
 692
 693                rtl_set_bbreg(hw, RTXPATH, 0xf0, 0);
 694                rtl_set_bbreg(hw, RCCK_RX, 0x0f000000, 0xf);
 695
 696                RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
 697                         "==>PHY_SwitchWirelessBand8812() BAND_ON_5G settings OFDM index 0x%x\n",
 698                         rtlpriv->dm.ofdm_index[RF90_PATH_A]);
 699        }
 700
 701        if ((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) ||
 702            (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)) {
 703                /* 0xC1C[31:21] */
 704                rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
 705                              phy_get_tx_swing_8812A(hw, band, RF90_PATH_A));
 706                /* 0xE1C[31:21] */
 707                rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000,
 708                              phy_get_tx_swing_8812A(hw, band, RF90_PATH_B));
 709
 710                /* <20121005, Kordan> When TxPowerTrack is ON,
 711                 *      we should take care of the change of BB swing.
 712                 *   That is, reset all info to trigger Tx power tracking.
 713                 */
 714                if (band != current_band) {
 715                        bb_diff_between_band =
 716                                (rtldm->swing_diff_2g - rtldm->swing_diff_5g);
 717                        bb_diff_between_band = (band == BAND_ON_2_4G) ?
 718                                                bb_diff_between_band :
 719                                                (-1 * bb_diff_between_band);
 720                        rtldm->default_ofdm_index += bb_diff_between_band * 2;
 721                }
 722                rtl8821ae_dm_clear_txpower_tracking_state(hw);
 723        }
 724
 725        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
 726                 "<==rtl8821ae_phy_switch_wirelessband():Switch Band OK.\n");
 727        return;
 728}
 729
 730static bool _rtl8821ae_check_positive(struct ieee80211_hw *hw,
 731                                      const u32 condition1,
 732                                      const u32 condition2)
 733{
 734        struct rtl_priv *rtlpriv = rtl_priv(hw);
 735        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
 736        u32 cut_ver = ((rtlhal->version & CHIP_VER_RTL_MASK)
 737                                        >> CHIP_VER_RTL_SHIFT);
 738        u32 intf = (rtlhal->interface == INTF_USB ? BIT(1) : BIT(0));
 739
 740        u8  board_type = ((rtlhal->board_type & BIT(4)) >> 4) << 0 | /* _GLNA */
 741                         ((rtlhal->board_type & BIT(3)) >> 3) << 1 | /* _GPA  */
 742                         ((rtlhal->board_type & BIT(7)) >> 7) << 2 | /* _ALNA */
 743                         ((rtlhal->board_type & BIT(6)) >> 6) << 3 | /* _APA  */
 744                         ((rtlhal->board_type & BIT(2)) >> 2) << 4;  /* _BT   */
 745
 746        u32 cond1 = condition1, cond2 = condition2;
 747        u32 driver1 = cut_ver << 24 |   /* CUT ver */
 748                      0 << 20 |                 /* interface 2/2 */
 749                      0x04 << 16 |              /* platform */
 750                      rtlhal->package_type << 12 |
 751                      intf << 8 |                       /* interface 1/2 */
 752                      board_type;
 753
 754        u32 driver2 = rtlhal->type_glna <<  0 |
 755                      rtlhal->type_gpa  <<  8 |
 756                      rtlhal->type_alna << 16 |
 757                      rtlhal->type_apa  << 24;
 758
 759        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 760                 "===> [8812A] CheckPositive (cond1, cond2) = (0x%X 0x%X)\n",
 761                 cond1, cond2);
 762        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 763                 "===> [8812A] CheckPositive (driver1, driver2) = (0x%X 0x%X)\n",
 764                 driver1, driver2);
 765
 766        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 767                 "      (Platform, Interface) = (0x%X, 0x%X)\n", 0x04, intf);
 768        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 769                 "      (Board, Package) = (0x%X, 0x%X)\n",
 770                 rtlhal->board_type, rtlhal->package_type);
 771
 772        /*============== Value Defined Check ===============*/
 773        /*QFN Type [15:12] and Cut Version [27:24] need to do value check*/
 774
 775        if (((cond1 & 0x0000F000) != 0) && ((cond1 & 0x0000F000) !=
 776                (driver1 & 0x0000F000)))
 777                return false;
 778        if (((cond1 & 0x0F000000) != 0) && ((cond1 & 0x0F000000) !=
 779                (driver1 & 0x0F000000)))
 780                return false;
 781
 782        /*=============== Bit Defined Check ================*/
 783        /* We don't care [31:28] */
 784
 785        cond1   &= 0x00FF0FFF;
 786        driver1 &= 0x00FF0FFF;
 787
 788        if ((cond1 & driver1) == cond1) {
 789                u32 mask = 0;
 790
 791                if ((cond1 & 0x0F) == 0) /* BoardType is DONTCARE*/
 792                        return true;
 793
 794                if ((cond1 & BIT(0)) != 0) /*GLNA*/
 795                        mask |= 0x000000FF;
 796                if ((cond1 & BIT(1)) != 0) /*GPA*/
 797                        mask |= 0x0000FF00;
 798                if ((cond1 & BIT(2)) != 0) /*ALNA*/
 799                        mask |= 0x00FF0000;
 800                if ((cond1 & BIT(3)) != 0) /*APA*/
 801                        mask |= 0xFF000000;
 802
 803                /* BoardType of each RF path is matched*/
 804                if ((cond2 & mask) == (driver2 & mask))
 805                        return true;
 806                else
 807                        return false;
 808        } else
 809                return false;
 810}
 811
 812static bool _rtl8821ae_check_condition(struct ieee80211_hw *hw,
 813                                       const u32 condition)
 814{
 815        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 816        u32 _board = rtlefuse->board_type; /*need efuse define*/
 817        u32 _interface = 0x01; /* ODM_ITRF_PCIE */
 818        u32 _platform = 0x08;/* ODM_WIN */
 819        u32 cond = condition;
 820
 821        if (condition == 0xCDCDCDCD)
 822                return true;
 823
 824        cond = condition & 0xFF;
 825        if ((_board != cond) && cond != 0xFF)
 826                return false;
 827
 828        cond = condition & 0xFF00;
 829        cond = cond >> 8;
 830        if ((_interface & cond) == 0 && cond != 0x07)
 831                return false;
 832
 833        cond = condition & 0xFF0000;
 834        cond = cond >> 16;
 835        if ((_platform & cond) == 0 && cond != 0x0F)
 836                return false;
 837        return true;
 838}
 839
 840static void _rtl8821ae_config_rf_reg(struct ieee80211_hw *hw,
 841                                     u32 addr, u32 data,
 842                                     enum radio_path rfpath, u32 regaddr)
 843{
 844        if (addr == 0xfe || addr == 0xffe) {
 845                /* In order not to disturb BT music when
 846                 * wifi init.(1ant NIC only)
 847                 */
 848                mdelay(50);
 849        } else {
 850                rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data);
 851                udelay(1);
 852        }
 853}
 854
 855static void _rtl8821ae_config_rf_radio_a(struct ieee80211_hw *hw,
 856                                         u32 addr, u32 data)
 857{
 858        u32 content = 0x1000; /*RF Content: radio_a_txt*/
 859        u32 maskforphyset = (u32)(content & 0xE000);
 860
 861        _rtl8821ae_config_rf_reg(hw, addr, data,
 862                                 RF90_PATH_A, addr | maskforphyset);
 863}
 864
 865static void _rtl8821ae_config_rf_radio_b(struct ieee80211_hw *hw,
 866                                         u32 addr, u32 data)
 867{
 868        u32 content = 0x1001; /*RF Content: radio_b_txt*/
 869        u32 maskforphyset = (u32)(content & 0xE000);
 870
 871        _rtl8821ae_config_rf_reg(hw, addr, data,
 872                                 RF90_PATH_B, addr | maskforphyset);
 873}
 874
 875static void _rtl8821ae_config_bb_reg(struct ieee80211_hw *hw,
 876                                     u32 addr, u32 data)
 877{
 878        if (addr == 0xfe)
 879                mdelay(50);
 880        else if (addr == 0xfd)
 881                mdelay(5);
 882        else if (addr == 0xfc)
 883                mdelay(1);
 884        else if (addr == 0xfb)
 885                udelay(50);
 886        else if (addr == 0xfa)
 887                udelay(5);
 888        else if (addr == 0xf9)
 889                udelay(1);
 890        else
 891                rtl_set_bbreg(hw, addr, MASKDWORD, data);
 892
 893        udelay(1);
 894}
 895
 896static void _rtl8821ae_phy_init_tx_power_by_rate(struct ieee80211_hw *hw)
 897{
 898        struct rtl_priv *rtlpriv = rtl_priv(hw);
 899        struct rtl_phy *rtlphy = &rtlpriv->phy;
 900        u8 band, rfpath, txnum, rate_section;
 901
 902        for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band)
 903                for (rfpath = 0; rfpath < TX_PWR_BY_RATE_NUM_RF; ++rfpath)
 904                        for (txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum)
 905                                for (rate_section = 0;
 906                                     rate_section < TX_PWR_BY_RATE_NUM_SECTION;
 907                                     ++rate_section)
 908                                        rtlphy->tx_power_by_rate_offset[band]
 909                                            [rfpath][txnum][rate_section] = 0;
 910}
 911
 912static void _rtl8821ae_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw,
 913                                          u8 band, u8 path,
 914                                          u8 rate_section,
 915                                          u8 txnum, u8 value)
 916{
 917        struct rtl_priv *rtlpriv = rtl_priv(hw);
 918        struct rtl_phy *rtlphy = &rtlpriv->phy;
 919
 920        if (path > RF90_PATH_D) {
 921                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 922                        "Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n", path);
 923                return;
 924        }
 925
 926        if (band == BAND_ON_2_4G) {
 927                switch (rate_section) {
 928                case CCK:
 929                        rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value;
 930                        break;
 931                case OFDM:
 932                        rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value;
 933                        break;
 934                case HT_MCS0_MCS7:
 935                        rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value;
 936                        break;
 937                case HT_MCS8_MCS15:
 938                        rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value;
 939                        break;
 940                case VHT_1SSMCS0_1SSMCS9:
 941                        rtlphy->txpwr_by_rate_base_24g[path][txnum][4] = value;
 942                        break;
 943                case VHT_2SSMCS0_2SSMCS9:
 944                        rtlphy->txpwr_by_rate_base_24g[path][txnum][5] = value;
 945                        break;
 946                default:
 947                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 948                                 "Invalid RateSection %d in Band 2.4G,Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n",
 949                                 rate_section, path, txnum);
 950                        break;
 951                }
 952        } else if (band == BAND_ON_5G) {
 953                switch (rate_section) {
 954                case OFDM:
 955                        rtlphy->txpwr_by_rate_base_5g[path][txnum][0] = value;
 956                        break;
 957                case HT_MCS0_MCS7:
 958                        rtlphy->txpwr_by_rate_base_5g[path][txnum][1] = value;
 959                        break;
 960                case HT_MCS8_MCS15:
 961                        rtlphy->txpwr_by_rate_base_5g[path][txnum][2] = value;
 962                        break;
 963                case VHT_1SSMCS0_1SSMCS9:
 964                        rtlphy->txpwr_by_rate_base_5g[path][txnum][3] = value;
 965                        break;
 966                case VHT_2SSMCS0_2SSMCS9:
 967                        rtlphy->txpwr_by_rate_base_5g[path][txnum][4] = value;
 968                        break;
 969                default:
 970                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 971                                "Invalid RateSection %d in Band 5G, Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n",
 972                                rate_section, path, txnum);
 973                        break;
 974                }
 975        } else {
 976                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 977                        "Invalid Band %d in PHY_SetTxPowerByRateBase()\n", band);
 978        }
 979}
 980
 981static u8 _rtl8821ae_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw,
 982                                                  u8 band, u8 path,
 983                                                  u8 txnum, u8 rate_section)
 984{
 985        struct rtl_priv *rtlpriv = rtl_priv(hw);
 986        struct rtl_phy *rtlphy = &rtlpriv->phy;
 987        u8 value = 0;
 988
 989        if (path > RF90_PATH_D) {
 990                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 991                         "Invalid Rf Path %d in PHY_GetTxPowerByRateBase()\n",
 992                         path);
 993                return 0;
 994        }
 995
 996        if (band == BAND_ON_2_4G) {
 997                switch (rate_section) {
 998                case CCK:
 999                        value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0];
1000                        break;
1001                case OFDM:
1002                        value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1];
1003                        break;
1004                case HT_MCS0_MCS7:
1005                        value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2];
1006                        break;
1007                case HT_MCS8_MCS15:
1008                        value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3];
1009                        break;
1010                case VHT_1SSMCS0_1SSMCS9:
1011                        value = rtlphy->txpwr_by_rate_base_24g[path][txnum][4];
1012                        break;
1013                case VHT_2SSMCS0_2SSMCS9:
1014                        value = rtlphy->txpwr_by_rate_base_24g[path][txnum][5];
1015                        break;
1016                default:
1017                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1018                                 "Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n",
1019                                 rate_section, path, txnum);
1020                        break;
1021                }
1022        } else if (band == BAND_ON_5G) {
1023                switch (rate_section) {
1024                case OFDM:
1025                        value = rtlphy->txpwr_by_rate_base_5g[path][txnum][0];
1026                        break;
1027                case HT_MCS0_MCS7:
1028                        value = rtlphy->txpwr_by_rate_base_5g[path][txnum][1];
1029                        break;
1030                case HT_MCS8_MCS15:
1031                        value = rtlphy->txpwr_by_rate_base_5g[path][txnum][2];
1032                        break;
1033                case VHT_1SSMCS0_1SSMCS9:
1034                        value = rtlphy->txpwr_by_rate_base_5g[path][txnum][3];
1035                        break;
1036                case VHT_2SSMCS0_2SSMCS9:
1037                        value = rtlphy->txpwr_by_rate_base_5g[path][txnum][4];
1038                        break;
1039                default:
1040                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1041                                 "Invalid RateSection %d in Band 5G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n",
1042                                 rate_section, path, txnum);
1043                        break;
1044                }
1045        } else {
1046                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1047                         "Invalid Band %d in PHY_GetTxPowerByRateBase()\n", band);
1048        }
1049
1050        return value;
1051}
1052
1053static void _rtl8821ae_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw)
1054{
1055        struct rtl_priv *rtlpriv = rtl_priv(hw);
1056        struct rtl_phy *rtlphy = &rtlpriv->phy;
1057        u16 rawvalue = 0;
1058        u8 base = 0, path = 0;
1059
1060        for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) {
1061                rawvalue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][0] >> 24) & 0xFF;
1062                base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
1063                _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, CCK, RF_1TX, base);
1064
1065                rawvalue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][2] >> 24) & 0xFF;
1066                base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
1067                _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, OFDM, RF_1TX, base);
1068
1069                rawvalue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][4] >> 24) & 0xFF;
1070                base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
1071                _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, HT_MCS0_MCS7, RF_1TX, base);
1072
1073                rawvalue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_2TX][6] >> 24) & 0xFF;
1074                base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
1075                _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, HT_MCS8_MCS15, RF_2TX, base);
1076
1077                rawvalue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][8] >> 24) & 0xFF;
1078                base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
1079                _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, VHT_1SSMCS0_1SSMCS9, RF_1TX, base);
1080
1081                rawvalue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_2TX][11] >> 8) & 0xFF;
1082                base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
1083                _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, VHT_2SSMCS0_2SSMCS9, RF_2TX, base);
1084
1085                rawvalue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][2] >> 24) & 0xFF;
1086                base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
1087                _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, OFDM, RF_1TX, base);
1088
1089                rawvalue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][4] >> 24) & 0xFF;
1090                base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
1091                _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, HT_MCS0_MCS7, RF_1TX, base);
1092
1093                rawvalue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_2TX][6] >> 24) & 0xFF;
1094                base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
1095                _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, HT_MCS8_MCS15, RF_2TX, base);
1096
1097                rawvalue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][8] >> 24) & 0xFF;
1098                base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
1099                _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, VHT_1SSMCS0_1SSMCS9, RF_1TX, base);
1100
1101                rawvalue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_2TX][11] >> 8) & 0xFF;
1102                base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
1103                _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, VHT_2SSMCS0_2SSMCS9, RF_2TX, base);
1104        }
1105}
1106
1107static void _phy_convert_txpower_dbm_to_relative_value(u32 *data, u8 start,
1108                                                u8 end, u8 base_val)
1109{
1110        int i;
1111        u8 temp_value = 0;
1112        u32 temp_data = 0;
1113
1114        for (i = 3; i >= 0; --i) {
1115                if (i >= start && i <= end) {
1116                        /* Get the exact value */
1117                        temp_value = (u8)(*data >> (i * 8)) & 0xF;
1118                        temp_value += ((u8)((*data >> (i * 8 + 4)) & 0xF)) * 10;
1119
1120                        /* Change the value to a relative value */
1121                        temp_value = (temp_value > base_val) ? temp_value -
1122                                        base_val : base_val - temp_value;
1123                } else {
1124                        temp_value = (u8)(*data >> (i * 8)) & 0xFF;
1125                }
1126                temp_data <<= 8;
1127                temp_data |= temp_value;
1128        }
1129        *data = temp_data;
1130}
1131
1132static void _rtl8812ae_phy_cross_reference_ht_and_vht_txpower_limit(struct ieee80211_hw *hw)
1133{
1134        struct rtl_priv *rtlpriv = rtl_priv(hw);
1135        struct rtl_phy *rtlphy = &rtlpriv->phy;
1136        u8 regulation, bw, channel, rate_section;
1137        s8 temp_pwrlmt = 0;
1138
1139        for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
1140                for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) {
1141                        for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G; ++channel) {
1142                                for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; ++rate_section) {
1143                                        temp_pwrlmt = rtlphy->txpwr_limit_5g[regulation]
1144                                                [bw][rate_section][channel][RF90_PATH_A];
1145                                        if (temp_pwrlmt == MAX_POWER_INDEX) {
1146                                                if (bw == 0 || bw == 1) { /*5G 20M 40M VHT and HT can cross reference*/
1147                                                        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1148                                                                "No power limit table of the specified band %d, bandwidth %d, ratesection %d, channel %d, rf path %d\n",
1149                                                                1, bw, rate_section, channel, RF90_PATH_A);
1150                                                        if (rate_section == 2) {
1151                                                                rtlphy->txpwr_limit_5g[regulation][bw][2][channel][RF90_PATH_A] =
1152                                                                        rtlphy->txpwr_limit_5g[regulation][bw][4][channel][RF90_PATH_A];
1153                                                        } else if (rate_section == 4) {
1154                                                                rtlphy->txpwr_limit_5g[regulation][bw][4][channel][RF90_PATH_A] =
1155                                                                        rtlphy->txpwr_limit_5g[regulation][bw][2][channel][RF90_PATH_A];
1156                                                        } else if (rate_section == 3) {
1157                                                                rtlphy->txpwr_limit_5g[regulation][bw][3][channel][RF90_PATH_A] =
1158                                                                        rtlphy->txpwr_limit_5g[regulation][bw][5][channel][RF90_PATH_A];
1159                                                        } else if (rate_section == 5) {
1160                                                                rtlphy->txpwr_limit_5g[regulation][bw][5][channel][RF90_PATH_A] =
1161                                                                        rtlphy->txpwr_limit_5g[regulation][bw][3][channel][RF90_PATH_A];
1162                                                        }
1163
1164                                                        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "use other value %d\n", temp_pwrlmt);
1165                                                }
1166                                        }
1167                                }
1168                        }
1169                }
1170        }
1171}
1172
1173static u8 _rtl8812ae_phy_get_txpower_by_rate_base_index(struct ieee80211_hw *hw,
1174                                                   enum band_type band, u8 rate)
1175{
1176        struct rtl_priv *rtlpriv = rtl_priv(hw);
1177        u8 index = 0;
1178        if (band == BAND_ON_2_4G) {
1179                switch (rate) {
1180                case MGN_1M:
1181                case MGN_2M:
1182                case MGN_5_5M:
1183                case MGN_11M:
1184                        index = 0;
1185                        break;
1186
1187                case MGN_6M:
1188                case MGN_9M:
1189                case MGN_12M:
1190                case MGN_18M:
1191                case MGN_24M:
1192                case MGN_36M:
1193                case MGN_48M:
1194                case MGN_54M:
1195                        index = 1;
1196                        break;
1197
1198                case MGN_MCS0:
1199                case MGN_MCS1:
1200                case MGN_MCS2:
1201                case MGN_MCS3:
1202                case MGN_MCS4:
1203                case MGN_MCS5:
1204                case MGN_MCS6:
1205                case MGN_MCS7:
1206                        index = 2;
1207                        break;
1208
1209                case MGN_MCS8:
1210                case MGN_MCS9:
1211                case MGN_MCS10:
1212                case MGN_MCS11:
1213                case MGN_MCS12:
1214                case MGN_MCS13:
1215                case MGN_MCS14:
1216                case MGN_MCS15:
1217                        index = 3;
1218                        break;
1219
1220                default:
1221                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1222                                "Wrong rate 0x%x to obtain index in 2.4G in PHY_GetTxPowerByRateBaseIndex()\n",
1223                                rate);
1224                        break;
1225                }
1226        } else if (band == BAND_ON_5G) {
1227                switch (rate) {
1228                case MGN_6M:
1229                case MGN_9M:
1230                case MGN_12M:
1231                case MGN_18M:
1232                case MGN_24M:
1233                case MGN_36M:
1234                case MGN_48M:
1235                case MGN_54M:
1236                        index = 0;
1237                        break;
1238
1239                case MGN_MCS0:
1240                case MGN_MCS1:
1241                case MGN_MCS2:
1242                case MGN_MCS3:
1243                case MGN_MCS4:
1244                case MGN_MCS5:
1245                case MGN_MCS6:
1246                case MGN_MCS7:
1247                        index = 1;
1248                        break;
1249
1250                case MGN_MCS8:
1251                case MGN_MCS9:
1252                case MGN_MCS10:
1253                case MGN_MCS11:
1254                case MGN_MCS12:
1255                case MGN_MCS13:
1256                case MGN_MCS14:
1257                case MGN_MCS15:
1258                        index = 2;
1259                        break;
1260
1261                case MGN_VHT1SS_MCS0:
1262                case MGN_VHT1SS_MCS1:
1263                case MGN_VHT1SS_MCS2:
1264                case MGN_VHT1SS_MCS3:
1265                case MGN_VHT1SS_MCS4:
1266                case MGN_VHT1SS_MCS5:
1267                case MGN_VHT1SS_MCS6:
1268                case MGN_VHT1SS_MCS7:
1269                case MGN_VHT1SS_MCS8:
1270                case MGN_VHT1SS_MCS9:
1271                        index = 3;
1272                        break;
1273
1274                case MGN_VHT2SS_MCS0:
1275                case MGN_VHT2SS_MCS1:
1276                case MGN_VHT2SS_MCS2:
1277                case MGN_VHT2SS_MCS3:
1278                case MGN_VHT2SS_MCS4:
1279                case MGN_VHT2SS_MCS5:
1280                case MGN_VHT2SS_MCS6:
1281                case MGN_VHT2SS_MCS7:
1282                case MGN_VHT2SS_MCS8:
1283                case MGN_VHT2SS_MCS9:
1284                        index = 4;
1285                        break;
1286
1287                default:
1288                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1289                                "Wrong rate 0x%x to obtain index in 5G in PHY_GetTxPowerByRateBaseIndex()\n",
1290                                rate);
1291                        break;
1292                }
1293        }
1294
1295        return index;
1296}
1297
1298static void _rtl8812ae_phy_convert_txpower_limit_to_power_index(struct ieee80211_hw *hw)
1299{
1300        struct rtl_priv *rtlpriv = rtl_priv(hw);
1301        struct rtl_phy *rtlphy = &rtlpriv->phy;
1302        u8 bw40_pwr_base_dbm2_4G, bw40_pwr_base_dbm5G;
1303        u8 regulation, bw, channel, rate_section;
1304        u8 base_index2_4G = 0;
1305        u8 base_index5G = 0;
1306        s8 temp_value = 0, temp_pwrlmt = 0;
1307        u8 rf_path = 0;
1308
1309        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1310                "=====> _rtl8812ae_phy_convert_txpower_limit_to_power_index()\n");
1311
1312        _rtl8812ae_phy_cross_reference_ht_and_vht_txpower_limit(hw);
1313
1314        for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
1315                for (bw = 0; bw < MAX_2_4G_BANDWIDTH_NUM; ++bw) {
1316                        for (channel = 0; channel < CHANNEL_MAX_NUMBER_2G; ++channel) {
1317                                for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; ++rate_section) {
1318                                        /* obtain the base dBm values in 2.4G band
1319                                         CCK => 11M, OFDM => 54M, HT 1T => MCS7, HT 2T => MCS15*/
1320                                        if (rate_section == 0) { /*CCK*/
1321                                                base_index2_4G =
1322                                                        _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1323                                                        BAND_ON_2_4G, MGN_11M);
1324                                        } else if (rate_section == 1) { /*OFDM*/
1325                                                base_index2_4G =
1326                                                        _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1327                                                        BAND_ON_2_4G, MGN_54M);
1328                                        } else if (rate_section == 2) { /*HT IT*/
1329                                                base_index2_4G =
1330                                                        _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1331                                                        BAND_ON_2_4G, MGN_MCS7);
1332                                        } else if (rate_section == 3) { /*HT 2T*/
1333                                                base_index2_4G =
1334                                                        _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1335                                                        BAND_ON_2_4G, MGN_MCS15);
1336                                        }
1337
1338                                        temp_pwrlmt = rtlphy->txpwr_limit_2_4g[regulation]
1339                                                [bw][rate_section][channel][RF90_PATH_A];
1340
1341                                        for (rf_path = RF90_PATH_A;
1342                                                rf_path < MAX_RF_PATH_NUM;
1343                                                ++rf_path) {
1344                                                if (rate_section == 3)
1345                                                        bw40_pwr_base_dbm2_4G =
1346                                                        rtlphy->txpwr_by_rate_base_24g[rf_path][RF_2TX][base_index2_4G];
1347                                                else
1348                                                        bw40_pwr_base_dbm2_4G =
1349                                                        rtlphy->txpwr_by_rate_base_24g[rf_path][RF_1TX][base_index2_4G];
1350
1351                                                if (temp_pwrlmt != MAX_POWER_INDEX) {
1352                                                        temp_value = temp_pwrlmt - bw40_pwr_base_dbm2_4G;
1353                                                        rtlphy->txpwr_limit_2_4g[regulation]
1354                                                                [bw][rate_section][channel][rf_path] =
1355                                                                temp_value;
1356                                                }
1357
1358                                                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1359                                                        "TxPwrLimit_2_4G[regulation %d][bw %d][rateSection %d][channel %d] = %d\n(TxPwrLimit in dBm %d - BW40PwrLmt2_4G[channel %d][rfpath %d] %d)\n",
1360                                                        regulation, bw, rate_section, channel,
1361                                                        rtlphy->txpwr_limit_2_4g[regulation][bw]
1362                                                        [rate_section][channel][rf_path], (temp_pwrlmt == 63)
1363                                                        ? 0 : temp_pwrlmt/2, channel, rf_path,
1364                                                        bw40_pwr_base_dbm2_4G);
1365                                        }
1366                                }
1367                        }
1368                }
1369        }
1370        for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
1371                for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) {
1372                        for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G; ++channel) {
1373                                for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; ++rate_section) {
1374                                        /* obtain the base dBm values in 5G band
1375                                         OFDM => 54M, HT 1T => MCS7, HT 2T => MCS15,
1376                                        VHT => 1SSMCS7, VHT 2T => 2SSMCS7*/
1377                                        if (rate_section == 1) { /*OFDM*/
1378                                                base_index5G =
1379                                                        _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1380                                                        BAND_ON_5G, MGN_54M);
1381                                        } else if (rate_section == 2) { /*HT 1T*/
1382                                                base_index5G =
1383                                                        _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1384                                                        BAND_ON_5G, MGN_MCS7);
1385                                        } else if (rate_section == 3) { /*HT 2T*/
1386                                                base_index5G =
1387                                                        _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1388                                                        BAND_ON_5G, MGN_MCS15);
1389                                        } else if (rate_section == 4) { /*VHT 1T*/
1390                                                base_index5G =
1391                                                        _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1392                                                        BAND_ON_5G, MGN_VHT1SS_MCS7);
1393                                        } else if (rate_section == 5) { /*VHT 2T*/
1394                                                base_index5G =
1395                                                        _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1396                                                        BAND_ON_5G, MGN_VHT2SS_MCS7);
1397                                        }
1398
1399                                        temp_pwrlmt = rtlphy->txpwr_limit_5g[regulation]
1400                                                [bw][rate_section][channel]
1401                                                [RF90_PATH_A];
1402
1403                                        for (rf_path = RF90_PATH_A;
1404                                             rf_path < MAX_RF_PATH_NUM;
1405                                             ++rf_path) {
1406                                                if (rate_section == 3 || rate_section == 5)
1407                                                        bw40_pwr_base_dbm5G =
1408                                                        rtlphy->txpwr_by_rate_base_5g[rf_path]
1409                                                        [RF_2TX][base_index5G];
1410                                                else
1411                                                        bw40_pwr_base_dbm5G =
1412                                                        rtlphy->txpwr_by_rate_base_5g[rf_path]
1413                                                        [RF_1TX][base_index5G];
1414
1415                                                if (temp_pwrlmt != MAX_POWER_INDEX) {
1416                                                        temp_value =
1417                                                                temp_pwrlmt - bw40_pwr_base_dbm5G;
1418                                                        rtlphy->txpwr_limit_5g[regulation]
1419                                                                [bw][rate_section][channel]
1420                                                                [rf_path] = temp_value;
1421                                                }
1422
1423                                                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1424                                                        "TxPwrLimit_5G[regulation %d][bw %d][rateSection %d][channel %d] =%d\n(TxPwrLimit in dBm %d - BW40PwrLmt5G[chnl group %d][rfpath %d] %d)\n",
1425                                                        regulation, bw, rate_section,
1426                                                        channel, rtlphy->txpwr_limit_5g[regulation]
1427                                                        [bw][rate_section][channel][rf_path],
1428                                                        temp_pwrlmt, channel, rf_path, bw40_pwr_base_dbm5G);
1429                                        }
1430                                }
1431                        }
1432                }
1433        }
1434        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1435                 "<===== _rtl8812ae_phy_convert_txpower_limit_to_power_index()\n");
1436}
1437
1438static void _rtl8821ae_phy_init_txpower_limit(struct ieee80211_hw *hw)
1439{
1440        struct rtl_priv *rtlpriv = rtl_priv(hw);
1441        struct rtl_phy *rtlphy = &rtlpriv->phy;
1442        u8 i, j, k, l, m;
1443
1444        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1445                 "=====> _rtl8821ae_phy_init_txpower_limit()!\n");
1446
1447        for (i = 0; i < MAX_REGULATION_NUM; ++i) {
1448                for (j = 0; j < MAX_2_4G_BANDWIDTH_NUM; ++j)
1449                        for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
1450                                for (m = 0; m < CHANNEL_MAX_NUMBER_2G; ++m)
1451                                        for (l = 0; l < MAX_RF_PATH_NUM; ++l)
1452                                                rtlphy->txpwr_limit_2_4g
1453                                                                [i][j][k][m][l]
1454                                                        = MAX_POWER_INDEX;
1455        }
1456        for (i = 0; i < MAX_REGULATION_NUM; ++i) {
1457                for (j = 0; j < MAX_5G_BANDWIDTH_NUM; ++j)
1458                        for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
1459                                for (m = 0; m < CHANNEL_MAX_NUMBER_5G; ++m)
1460                                        for (l = 0; l < MAX_RF_PATH_NUM; ++l)
1461                                                rtlphy->txpwr_limit_5g
1462                                                                [i][j][k][m][l]
1463                                                        = MAX_POWER_INDEX;
1464        }
1465
1466        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1467                 "<===== _rtl8821ae_phy_init_txpower_limit()!\n");
1468}
1469
1470static void _rtl8821ae_phy_convert_txpower_dbm_to_relative_value(struct ieee80211_hw *hw)
1471{
1472        struct rtl_priv *rtlpriv = rtl_priv(hw);
1473        struct rtl_phy *rtlphy = &rtlpriv->phy;
1474        u8 base = 0, rfpath = 0;
1475
1476        for (rfpath = RF90_PATH_A; rfpath <= RF90_PATH_B; ++rfpath) {
1477                base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfpath, RF_1TX, CCK);
1478                _phy_convert_txpower_dbm_to_relative_value(
1479                        &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][0],
1480                        0, 3, base);
1481
1482                base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfpath, RF_1TX, OFDM);
1483                _phy_convert_txpower_dbm_to_relative_value(
1484                        &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][1],
1485                        0, 3, base);
1486                _phy_convert_txpower_dbm_to_relative_value(
1487                        &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][2],
1488                        0, 3, base);
1489
1490                base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfpath, RF_1TX, HT_MCS0_MCS7);
1491                _phy_convert_txpower_dbm_to_relative_value(
1492                        &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][3],
1493                        0, 3, base);
1494                _phy_convert_txpower_dbm_to_relative_value(
1495                        &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][4],
1496                        0, 3, base);
1497
1498                base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfpath, RF_2TX, HT_MCS8_MCS15);
1499
1500                _phy_convert_txpower_dbm_to_relative_value(
1501                        &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_2TX][5],
1502                        0, 3, base);
1503
1504                _phy_convert_txpower_dbm_to_relative_value(
1505                        &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_2TX][6],
1506                        0, 3, base);
1507
1508                base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfpath, RF_1TX, VHT_1SSMCS0_1SSMCS9);
1509                _phy_convert_txpower_dbm_to_relative_value(
1510                        &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][7],
1511                        0, 3, base);
1512                _phy_convert_txpower_dbm_to_relative_value(
1513                        &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][8],
1514                        0, 3, base);
1515                _phy_convert_txpower_dbm_to_relative_value(
1516                        &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][9],
1517                        0, 1, base);
1518
1519                base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfpath, RF_2TX, VHT_2SSMCS0_2SSMCS9);
1520                _phy_convert_txpower_dbm_to_relative_value(
1521                        &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][9],
1522                        2, 3, base);
1523                _phy_convert_txpower_dbm_to_relative_value(
1524                        &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_2TX][10],
1525                        0, 3, base);
1526                _phy_convert_txpower_dbm_to_relative_value(
1527                        &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_2TX][11],
1528                        0, 3, base);
1529
1530                base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfpath, RF_1TX, OFDM);
1531                _phy_convert_txpower_dbm_to_relative_value(
1532                        &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfpath][RF_1TX][1],
1533                        0, 3, base);
1534                _phy_convert_txpower_dbm_to_relative_value(
1535                        &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfpath][RF_1TX][2],
1536                        0, 3, base);
1537
1538                base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfpath, RF_1TX, HT_MCS0_MCS7);
1539                _phy_convert_txpower_dbm_to_relative_value(
1540                        &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfpath][RF_1TX][3],
1541                        0, 3, base);
1542                _phy_convert_txpower_dbm_to_relative_value(
1543                        &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfpath][RF_1TX][4],
1544                        0, 3, base);
1545
1546                base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfpath, RF_2TX, HT_MCS8_MCS15);
1547                _phy_convert_txpower_dbm_to_relative_value(
1548                        &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfpath][RF_2TX][5],
1549                        0, 3, base);
1550                _phy_convert_txpower_dbm_to_relative_value(
1551                        &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfpath][RF_2TX][6],
1552                        0, 3, base);
1553
1554                base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfpath, RF_1TX, VHT_1SSMCS0_1SSMCS9);
1555                _phy_convert_txpower_dbm_to_relative_value(
1556                        &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfpath][RF_1TX][7],
1557                        0, 3, base);
1558                _phy_convert_txpower_dbm_to_relative_value(
1559                        &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfpath][RF_1TX][8],
1560                        0, 3, base);
1561                _phy_convert_txpower_dbm_to_relative_value(
1562                        &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfpath][RF_1TX][9],
1563                        0, 1, base);
1564
1565                base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfpath, RF_2TX, VHT_2SSMCS0_2SSMCS9);
1566                _phy_convert_txpower_dbm_to_relative_value(
1567                        &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfpath][RF_1TX][9],
1568                        2, 3, base);
1569                _phy_convert_txpower_dbm_to_relative_value(
1570                        &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfpath][RF_2TX][10],
1571                        0, 3, base);
1572                _phy_convert_txpower_dbm_to_relative_value(
1573                        &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfpath][RF_2TX][11],
1574                        0, 3, base);
1575        }
1576
1577        RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
1578                "<===_rtl8821ae_phy_convert_txpower_dbm_to_relative_value()\n");
1579}
1580
1581static void _rtl8821ae_phy_txpower_by_rate_configuration(struct ieee80211_hw *hw)
1582{
1583        _rtl8821ae_phy_store_txpower_by_rate_base(hw);
1584        _rtl8821ae_phy_convert_txpower_dbm_to_relative_value(hw);
1585}
1586
1587/* string is in decimal */
1588static bool _rtl8812ae_get_integer_from_string(char *str, u8 *pint)
1589{
1590        u16 i = 0;
1591        *pint = 0;
1592
1593        while (str[i] != '\0') {
1594                if (str[i] >= '0' && str[i] <= '9') {
1595                        *pint *= 10;
1596                        *pint += (str[i] - '0');
1597                } else {
1598                        return false;
1599                }
1600                ++i;
1601        }
1602
1603        return true;
1604}
1605
1606static bool _rtl8812ae_eq_n_byte(u8 *str1, u8 *str2, u32 num)
1607{
1608        if (num == 0)
1609                return false;
1610        while (num > 0) {
1611                num--;
1612                if (str1[num] != str2[num])
1613                        return false;
1614        }
1615        return true;
1616}
1617
1618static s8 _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(struct ieee80211_hw *hw,
1619                                              u8 band, u8 channel)
1620{
1621        struct rtl_priv *rtlpriv = rtl_priv(hw);
1622        s8 channel_index = -1;
1623        u8  i = 0;
1624
1625        if (band == BAND_ON_2_4G)
1626                channel_index = channel - 1;
1627        else if (band == BAND_ON_5G) {
1628                for (i = 0; i < sizeof(channel5g)/sizeof(u8); ++i) {
1629                        if (channel5g[i] == channel)
1630                                channel_index = i;
1631                }
1632        } else
1633                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid Band %d in %s\n",
1634                         band,  __func__);
1635
1636        if (channel_index == -1)
1637                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1638                         "Invalid Channel %d of Band %d in %s\n", channel,
1639                         band, __func__);
1640
1641        return channel_index;
1642}
1643
1644static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregulation,
1645                                      u8 *pband, u8 *pbandwidth,
1646                                      u8 *prate_section, u8 *prf_path,
1647                                      u8 *pchannel, u8 *ppower_limit)
1648{
1649        struct rtl_priv *rtlpriv = rtl_priv(hw);
1650        struct rtl_phy *rtlphy = &rtlpriv->phy;
1651        u8 regulation = 0, bandwidth = 0, rate_section = 0, channel;
1652        u8 channel_index;
1653        s8 power_limit = 0, prev_power_limit, ret;
1654
1655        if (!_rtl8812ae_get_integer_from_string((char *)pchannel, &channel) ||
1656            !_rtl8812ae_get_integer_from_string((char *)ppower_limit,
1657                                                &power_limit)) {
1658                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1659                         "Illegal index of pwr_lmt table [chnl %d][val %d]\n",
1660                          channel, power_limit);
1661        }
1662
1663        power_limit = power_limit > MAX_POWER_INDEX ?
1664                      MAX_POWER_INDEX : power_limit;
1665
1666        if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("FCC"), 3))
1667                regulation = 0;
1668        else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("MKK"), 3))
1669                regulation = 1;
1670        else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("ETSI"), 4))
1671                regulation = 2;
1672        else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("WW13"), 4))
1673                regulation = 3;
1674
1675        if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("CCK"), 3))
1676                rate_section = 0;
1677        else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("OFDM"), 4))
1678                rate_section = 1;
1679        else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
1680                 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("1T"), 2))
1681                rate_section = 2;
1682        else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
1683                 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("2T"), 2))
1684                rate_section = 3;
1685        else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
1686                 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("1T"), 2))
1687                rate_section = 4;
1688        else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
1689                 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("2T"), 2))
1690                rate_section = 5;
1691
1692        if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("20M"), 3))
1693                bandwidth = 0;
1694        else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("40M"), 3))
1695                bandwidth = 1;
1696        else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("80M"), 3))
1697                bandwidth = 2;
1698        else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("160M"), 4))
1699                bandwidth = 3;
1700
1701        if (_rtl8812ae_eq_n_byte(pband, (u8 *)("2.4G"), 4)) {
1702                ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
1703                                                               BAND_ON_2_4G,
1704                                                               channel);
1705
1706                if (ret == -1)
1707                        return;
1708
1709                channel_index = ret;
1710
1711                prev_power_limit = rtlphy->txpwr_limit_2_4g[regulation]
1712                                                [bandwidth][rate_section]
1713                                                [channel_index][RF90_PATH_A];
1714
1715                if (power_limit < prev_power_limit)
1716                        rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
1717                                [rate_section][channel_index][RF90_PATH_A] =
1718                                                                   power_limit;
1719
1720                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1721                         "2.4G [regula %d][bw %d][sec %d][chnl %d][val %d]\n",
1722                          regulation, bandwidth, rate_section, channel_index,
1723                          rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
1724                                [rate_section][channel_index][RF90_PATH_A]);
1725        } else if (_rtl8812ae_eq_n_byte(pband, (u8 *)("5G"), 2)) {
1726                ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
1727                                                               BAND_ON_5G,
1728                                                               channel);
1729
1730                if (ret == -1)
1731                        return;
1732
1733                channel_index = ret;
1734
1735                prev_power_limit = rtlphy->txpwr_limit_5g[regulation][bandwidth]
1736                                                [rate_section][channel_index]
1737                                                [RF90_PATH_A];
1738
1739                if (power_limit < prev_power_limit)
1740                        rtlphy->txpwr_limit_5g[regulation][bandwidth]
1741                        [rate_section][channel_index][RF90_PATH_A] = power_limit;
1742
1743                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1744                         "5G: [regul %d][bw %d][sec %d][chnl %d][val %d]\n",
1745                          regulation, bandwidth, rate_section, channel,
1746                          rtlphy->txpwr_limit_5g[regulation][bandwidth]
1747                                [rate_section][channel_index][RF90_PATH_A]);
1748        } else {
1749                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1750                         "Cannot recognize the band info in %s\n", pband);
1751                return;
1752        }
1753}
1754
1755static void _rtl8812ae_phy_config_bb_txpwr_lmt(struct ieee80211_hw *hw,
1756                                          u8 *regulation, u8 *band,
1757                                          u8 *bandwidth, u8 *rate_section,
1758                                          u8 *rf_path, u8 *channel,
1759                                          u8 *power_limit)
1760{
1761        _rtl8812ae_phy_set_txpower_limit(hw, regulation, band, bandwidth,
1762                                         rate_section, rf_path, channel,
1763                                         power_limit);
1764}
1765
1766static void _rtl8821ae_phy_read_and_config_txpwr_lmt(struct ieee80211_hw *hw)
1767{
1768        struct rtl_priv *rtlpriv = rtl_priv(hw);
1769        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1770        u32 i = 0;
1771        u32 array_len;
1772        u8 **array;
1773
1774        if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1775                array_len = RTL8812AE_TXPWR_LMT_ARRAY_LEN;
1776                array = RTL8812AE_TXPWR_LMT;
1777        } else {
1778                array_len = RTL8821AE_TXPWR_LMT_ARRAY_LEN;
1779                array = RTL8821AE_TXPWR_LMT;
1780        }
1781
1782        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1783                 "\n");
1784
1785        for (i = 0; i < array_len; i += 7) {
1786                u8 *regulation = array[i];
1787                u8 *band = array[i+1];
1788                u8 *bandwidth = array[i+2];
1789                u8 *rate = array[i+3];
1790                u8 *rf_path = array[i+4];
1791                u8 *chnl = array[i+5];
1792                u8 *val = array[i+6];
1793
1794                _rtl8812ae_phy_config_bb_txpwr_lmt(hw, regulation, band,
1795                                                   bandwidth, rate, rf_path,
1796                                                   chnl, val);
1797        }
1798}
1799
1800static bool _rtl8821ae_phy_bb8821a_config_parafile(struct ieee80211_hw *hw)
1801{
1802        struct rtl_priv *rtlpriv = rtl_priv(hw);
1803        struct rtl_phy *rtlphy = &rtlpriv->phy;
1804        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1805        bool rtstatus;
1806
1807        _rtl8821ae_phy_init_txpower_limit(hw);
1808
1809        /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
1810        if (rtlefuse->eeprom_regulatory != 2)
1811                _rtl8821ae_phy_read_and_config_txpwr_lmt(hw);
1812
1813        rtstatus = _rtl8821ae_phy_config_bb_with_headerfile(hw,
1814                                                       BASEBAND_CONFIG_PHY_REG);
1815        if (rtstatus != true) {
1816                pr_err("Write BB Reg Fail!!\n");
1817                return false;
1818        }
1819        _rtl8821ae_phy_init_tx_power_by_rate(hw);
1820        if (rtlefuse->autoload_failflag == false) {
1821                rtstatus = _rtl8821ae_phy_config_bb_with_pgheaderfile(hw,
1822                                                    BASEBAND_CONFIG_PHY_REG);
1823        }
1824        if (rtstatus != true) {
1825                pr_err("BB_PG Reg Fail!!\n");
1826                return false;
1827        }
1828
1829        _rtl8821ae_phy_txpower_by_rate_configuration(hw);
1830
1831        /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
1832        if (rtlefuse->eeprom_regulatory != 2)
1833                _rtl8812ae_phy_convert_txpower_limit_to_power_index(hw);
1834
1835        rtstatus = _rtl8821ae_phy_config_bb_with_headerfile(hw,
1836                                                BASEBAND_CONFIG_AGC_TAB);
1837
1838        if (rtstatus != true) {
1839                pr_err("AGC Table Fail\n");
1840                return false;
1841        }
1842        rtlphy->cck_high_power = (bool)(rtl_get_bbreg(hw,
1843                        RFPGA0_XA_HSSIPARAMETER2, 0x200));
1844        return true;
1845}
1846
1847static bool
1848__rtl8821ae_phy_config_with_headerfile(struct ieee80211_hw *hw,
1849                                       u32 *array_table, u16 arraylen,
1850                                       void (*set_reg)(struct ieee80211_hw *hw,
1851                                                       u32 regaddr, u32 data))
1852{
1853        #define COND_ELSE  2
1854        #define COND_ENDIF 3
1855
1856        int i = 0;
1857        u8 cond;
1858        bool matched = true, skipped = false;
1859
1860        while ((i + 1) < arraylen) {
1861                u32 v1 = array_table[i];
1862                u32 v2 = array_table[i + 1];
1863
1864                if (v1 & (BIT(31) | BIT(30))) {/*positive & negative condition*/
1865                        if (v1 & BIT(31)) {/* positive condition*/
1866                                cond  = (u8)((v1 & (BIT(29) | BIT(28))) >> 28);
1867                                if (cond == COND_ENDIF) {/*end*/
1868                                        matched = true;
1869                                        skipped = false;
1870                                } else if (cond == COND_ELSE) /*else*/
1871                                        matched = skipped ? false : true;
1872                                else {/*if , else if*/
1873                                        if (skipped) {
1874                                                matched = false;
1875                                        } else {
1876                                                if (_rtl8821ae_check_positive(
1877                                                                hw, v1, v2)) {
1878                                                        matched = true;
1879                                                        skipped = true;
1880                                                } else {
1881                                                        matched = false;
1882                                                        skipped = false;
1883                                                }
1884                                        }
1885                                }
1886                        } else if (v1 & BIT(30)) { /*negative condition*/
1887                        /*do nothing*/
1888                        }
1889                } else {
1890                        if (matched)
1891                                set_reg(hw, v1, v2);
1892                }
1893                i = i + 2;
1894        }
1895
1896        return true;
1897}
1898
1899static bool _rtl8821ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
1900{
1901        struct rtl_priv *rtlpriv = rtl_priv(hw);
1902        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1903        u32 arraylength;
1904        u32 *ptrarray;
1905
1906        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read MAC_REG_Array\n");
1907        if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
1908                arraylength = RTL8821AE_MAC_1T_ARRAYLEN;
1909                ptrarray = RTL8821AE_MAC_REG_ARRAY;
1910        } else {
1911                arraylength = RTL8812AE_MAC_1T_ARRAYLEN;
1912                ptrarray = RTL8812AE_MAC_REG_ARRAY;
1913        }
1914        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1915                 "Img: MAC_REG_ARRAY LEN %d\n", arraylength);
1916
1917        return __rtl8821ae_phy_config_with_headerfile(hw,
1918                        ptrarray, arraylength, rtl_write_byte_with_val32);
1919}
1920
1921static bool _rtl8821ae_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
1922                                                     u8 configtype)
1923{
1924        struct rtl_priv *rtlpriv = rtl_priv(hw);
1925        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1926        u32 *array_table;
1927        u16 arraylen;
1928
1929        if (configtype == BASEBAND_CONFIG_PHY_REG) {
1930                if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1931                        arraylen = RTL8812AE_PHY_REG_1TARRAYLEN;
1932                        array_table = RTL8812AE_PHY_REG_ARRAY;
1933                } else {
1934                        arraylen = RTL8821AE_PHY_REG_1TARRAYLEN;
1935                        array_table = RTL8821AE_PHY_REG_ARRAY;
1936                }
1937
1938                return __rtl8821ae_phy_config_with_headerfile(hw,
1939                                array_table, arraylen,
1940                                _rtl8821ae_config_bb_reg);
1941        } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
1942                if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1943                        arraylen = RTL8812AE_AGC_TAB_1TARRAYLEN;
1944                        array_table = RTL8812AE_AGC_TAB_ARRAY;
1945                } else {
1946                        arraylen = RTL8821AE_AGC_TAB_1TARRAYLEN;
1947                        array_table = RTL8821AE_AGC_TAB_ARRAY;
1948                }
1949
1950                return __rtl8821ae_phy_config_with_headerfile(hw,
1951                                array_table, arraylen,
1952                                rtl_set_bbreg_with_dwmask);
1953        }
1954        return true;
1955}
1956
1957static u8 _rtl8821ae_get_rate_section_index(u32 regaddr)
1958{
1959        u8 index = 0;
1960        regaddr &= 0xFFF;
1961        if (regaddr >= 0xC20 && regaddr <= 0xC4C)
1962                index = (u8)((regaddr - 0xC20) / 4);
1963        else if (regaddr >= 0xE20 && regaddr <= 0xE4C)
1964                index = (u8)((regaddr - 0xE20) / 4);
1965        else
1966                WARN_ONCE(true,
1967                          "rtl8821ae: Invalid RegAddr 0x%x\n", regaddr);
1968        return index;
1969}
1970
1971static void _rtl8821ae_store_tx_power_by_rate(struct ieee80211_hw *hw,
1972                                              u32 band, u32 rfpath,
1973                                              u32 txnum, u32 regaddr,
1974                                              u32 bitmask, u32 data)
1975{
1976        struct rtl_priv *rtlpriv = rtl_priv(hw);
1977        struct rtl_phy *rtlphy = &rtlpriv->phy;
1978        u8 rate_section = _rtl8821ae_get_rate_section_index(regaddr);
1979
1980        if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
1981                RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid Band %d\n", band);
1982                band = BAND_ON_2_4G;
1983        }
1984        if (rfpath >= MAX_RF_PATH) {
1985                RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid RfPath %d\n", rfpath);
1986                rfpath = MAX_RF_PATH - 1;
1987        }
1988        if (txnum >= MAX_RF_PATH) {
1989                RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid TxNum %d\n", txnum);
1990                txnum = MAX_RF_PATH - 1;
1991        }
1992        rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] = data;
1993        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1994                 "TxPwrByRateOffset[Band %d][RfPath %d][TxNum %d][RateSection %d] = 0x%x\n",
1995                 band, rfpath, txnum, rate_section,
1996                 rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section]);
1997}
1998
1999static bool _rtl8821ae_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
2000                                                        u8 configtype)
2001{
2002        struct rtl_priv *rtlpriv = rtl_priv(hw);
2003        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
2004        int i;
2005        u32 *array;
2006        u16 arraylen;
2007        u32 v1, v2, v3, v4, v5, v6;
2008
2009        if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
2010                arraylen = RTL8812AE_PHY_REG_ARRAY_PGLEN;
2011                array = RTL8812AE_PHY_REG_ARRAY_PG;
2012        } else {
2013                arraylen = RTL8821AE_PHY_REG_ARRAY_PGLEN;
2014                array = RTL8821AE_PHY_REG_ARRAY_PG;
2015        }
2016
2017        if (configtype != BASEBAND_CONFIG_PHY_REG) {
2018                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
2019                         "configtype != BaseBand_Config_PHY_REG\n");
2020                return true;
2021        }
2022        for (i = 0; i < arraylen; i += 6) {
2023                v1 = array[i];
2024                v2 = array[i+1];
2025                v3 = array[i+2];
2026                v4 = array[i+3];
2027                v5 = array[i+4];
2028                v6 = array[i+5];
2029
2030                if (v1 < 0xCDCDCDCD) {
2031                        if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE &&
2032                                (v4 == 0xfe || v4 == 0xffe)) {
2033                                msleep(50);
2034                                continue;
2035                        }
2036
2037                        if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
2038                                if (v4 == 0xfe)
2039                                        msleep(50);
2040                                else if (v4 == 0xfd)
2041                                        mdelay(5);
2042                                else if (v4 == 0xfc)
2043                                        mdelay(1);
2044                                else if (v4 == 0xfb)
2045                                        udelay(50);
2046                                else if (v4 == 0xfa)
2047                                        udelay(5);
2048                                else if (v4 == 0xf9)
2049                                        udelay(1);
2050                        }
2051                        _rtl8821ae_store_tx_power_by_rate(hw, v1, v2, v3,
2052                                                          v4, v5, v6);
2053                        continue;
2054                } else {
2055                         /*don't need the hw_body*/
2056                        if (!_rtl8821ae_check_condition(hw, v1)) {
2057                                i += 2; /* skip the pair of expression*/
2058                                v1 = array[i];
2059                                v2 = array[i+1];
2060                                v3 = array[i+2];
2061                                while (v2 != 0xDEAD) {
2062                                        i += 3;
2063                                        v1 = array[i];
2064                                        v2 = array[i+1];
2065                                        v3 = array[i+2];
2066                                }
2067                        }
2068                }
2069        }
2070
2071        return true;
2072}
2073
2074bool rtl8812ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
2075                                             enum radio_path rfpath)
2076{
2077        u32 *radioa_array_table_a, *radioa_array_table_b;
2078        u16 radioa_arraylen_a, radioa_arraylen_b;
2079        struct rtl_priv *rtlpriv = rtl_priv(hw);
2080
2081        radioa_arraylen_a = RTL8812AE_RADIOA_1TARRAYLEN;
2082        radioa_array_table_a = RTL8812AE_RADIOA_ARRAY;
2083        radioa_arraylen_b = RTL8812AE_RADIOB_1TARRAYLEN;
2084        radioa_array_table_b = RTL8812AE_RADIOB_ARRAY;
2085        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2086                 "Radio_A:RTL8821AE_RADIOA_ARRAY %d\n", radioa_arraylen_a);
2087        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
2088        switch (rfpath) {
2089        case RF90_PATH_A:
2090                return __rtl8821ae_phy_config_with_headerfile(hw,
2091                                radioa_array_table_a, radioa_arraylen_a,
2092                                _rtl8821ae_config_rf_radio_a);
2093                break;
2094        case RF90_PATH_B:
2095                return __rtl8821ae_phy_config_with_headerfile(hw,
2096                                radioa_array_table_b, radioa_arraylen_b,
2097                                _rtl8821ae_config_rf_radio_b);
2098                break;
2099        case RF90_PATH_C:
2100        case RF90_PATH_D:
2101                pr_err("switch case %#x not processed\n", rfpath);
2102                break;
2103        }
2104        return true;
2105}
2106
2107bool rtl8821ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
2108                                                enum radio_path rfpath)
2109{
2110        u32 *radioa_array_table;
2111        u16 radioa_arraylen;
2112        struct rtl_priv *rtlpriv = rtl_priv(hw);
2113
2114        radioa_arraylen = RTL8821AE_RADIOA_1TARRAYLEN;
2115        radioa_array_table = RTL8821AE_RADIOA_ARRAY;
2116        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2117                 "Radio_A:RTL8821AE_RADIOA_ARRAY %d\n", radioa_arraylen);
2118        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
2119        switch (rfpath) {
2120        case RF90_PATH_A:
2121                return __rtl8821ae_phy_config_with_headerfile(hw,
2122                        radioa_array_table, radioa_arraylen,
2123                        _rtl8821ae_config_rf_radio_a);
2124                break;
2125
2126        case RF90_PATH_B:
2127        case RF90_PATH_C:
2128        case RF90_PATH_D:
2129                pr_err("switch case %#x not processed\n", rfpath);
2130                break;
2131        }
2132        return true;
2133}
2134
2135void rtl8821ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
2136{
2137        struct rtl_priv *rtlpriv = rtl_priv(hw);
2138        struct rtl_phy *rtlphy = &rtlpriv->phy;
2139
2140        rtlphy->default_initialgain[0] =
2141            (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
2142        rtlphy->default_initialgain[1] =
2143            (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
2144        rtlphy->default_initialgain[2] =
2145            (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
2146        rtlphy->default_initialgain[3] =
2147            (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
2148
2149        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
2150                 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
2151                  rtlphy->default_initialgain[0],
2152                  rtlphy->default_initialgain[1],
2153                  rtlphy->default_initialgain[2],
2154                  rtlphy->default_initialgain[3]);
2155
2156        rtlphy->framesync = (u8)rtl_get_bbreg(hw,
2157                                               ROFDM0_RXDETECTOR3, MASKBYTE0);
2158        rtlphy->framesync_c34 = rtl_get_bbreg(hw,
2159                                              ROFDM0_RXDETECTOR2, MASKDWORD);
2160
2161        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
2162                 "Default framesync (0x%x) = 0x%x\n",
2163                  ROFDM0_RXDETECTOR3, rtlphy->framesync);
2164}
2165
2166static void phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
2167{
2168        struct rtl_priv *rtlpriv = rtl_priv(hw);
2169        struct rtl_phy *rtlphy = &rtlpriv->phy;
2170
2171        rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
2172        rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
2173
2174        rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
2175        rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
2176
2177        rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
2178        rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
2179
2180        rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = RA_LSSIWRITE_8821A;
2181        rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = RB_LSSIWRITE_8821A;
2182
2183        rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RHSSIREAD_8821AE;
2184        rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RHSSIREAD_8821AE;
2185
2186        rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RA_SIREAD_8821A;
2187        rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RB_SIREAD_8821A;
2188
2189        rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = RA_PIREAD_8821A;
2190        rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = RB_PIREAD_8821A;
2191}
2192
2193void rtl8821ae_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
2194{
2195        struct rtl_priv *rtlpriv = rtl_priv(hw);
2196        struct rtl_phy *rtlphy = &rtlpriv->phy;
2197        u8 txpwr_level;
2198        long txpwr_dbm;
2199
2200        txpwr_level = rtlphy->cur_cck_txpwridx;
2201        txpwr_dbm = _rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2202                                                 WIRELESS_MODE_B, txpwr_level);
2203        txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
2204        if (_rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2205                                         WIRELESS_MODE_G,
2206                                         txpwr_level) > txpwr_dbm)
2207                txpwr_dbm =
2208                    _rtl8821ae_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
2209                                                 txpwr_level);
2210        txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
2211        if (_rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2212                                         WIRELESS_MODE_N_24G,
2213                                         txpwr_level) > txpwr_dbm)
2214                txpwr_dbm =
2215                    _rtl8821ae_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
2216                                                 txpwr_level);
2217        *powerlevel = txpwr_dbm;
2218}
2219
2220static bool _rtl8821ae_phy_get_chnl_index(u8 channel, u8 *chnl_index)
2221{
2222        u8 i = 0;
2223        bool in_24g = true;
2224
2225        if (channel <= 14) {
2226                in_24g = true;
2227                *chnl_index = channel - 1;
2228        } else {
2229                in_24g = false;
2230
2231                for (i = 0; i < CHANNEL_MAX_NUMBER_5G; ++i) {
2232                        if (channel5g[i] == channel) {
2233                                *chnl_index = i;
2234                                return in_24g;
2235                        }
2236                }
2237        }
2238        return in_24g;
2239}
2240
2241static s8 _rtl8821ae_phy_get_ratesection_intxpower_byrate(u8 path, u8 rate)
2242{
2243        s8 rate_section = 0;
2244        switch (rate) {
2245        case DESC_RATE1M:
2246        case DESC_RATE2M:
2247        case DESC_RATE5_5M:
2248        case DESC_RATE11M:
2249                rate_section = 0;
2250                break;
2251        case DESC_RATE6M:
2252        case DESC_RATE9M:
2253        case DESC_RATE12M:
2254        case DESC_RATE18M:
2255                rate_section = 1;
2256                break;
2257        case DESC_RATE24M:
2258        case DESC_RATE36M:
2259        case DESC_RATE48M:
2260        case DESC_RATE54M:
2261                rate_section = 2;
2262                break;
2263        case DESC_RATEMCS0:
2264        case DESC_RATEMCS1:
2265        case DESC_RATEMCS2:
2266        case DESC_RATEMCS3:
2267                rate_section = 3;
2268                break;
2269        case DESC_RATEMCS4:
2270        case DESC_RATEMCS5:
2271        case DESC_RATEMCS6:
2272        case DESC_RATEMCS7:
2273                rate_section = 4;
2274                break;
2275        case DESC_RATEMCS8:
2276        case DESC_RATEMCS9:
2277        case DESC_RATEMCS10:
2278        case DESC_RATEMCS11:
2279                rate_section = 5;
2280                break;
2281        case DESC_RATEMCS12:
2282        case DESC_RATEMCS13:
2283        case DESC_RATEMCS14:
2284        case DESC_RATEMCS15:
2285                rate_section = 6;
2286                break;
2287        case DESC_RATEVHT1SS_MCS0:
2288        case DESC_RATEVHT1SS_MCS1:
2289        case DESC_RATEVHT1SS_MCS2:
2290        case DESC_RATEVHT1SS_MCS3:
2291                rate_section = 7;
2292                break;
2293        case DESC_RATEVHT1SS_MCS4:
2294        case DESC_RATEVHT1SS_MCS5:
2295        case DESC_RATEVHT1SS_MCS6:
2296        case DESC_RATEVHT1SS_MCS7:
2297                rate_section = 8;
2298                break;
2299        case DESC_RATEVHT1SS_MCS8:
2300        case DESC_RATEVHT1SS_MCS9:
2301        case DESC_RATEVHT2SS_MCS0:
2302        case DESC_RATEVHT2SS_MCS1:
2303                rate_section = 9;
2304                break;
2305        case DESC_RATEVHT2SS_MCS2:
2306        case DESC_RATEVHT2SS_MCS3:
2307        case DESC_RATEVHT2SS_MCS4:
2308        case DESC_RATEVHT2SS_MCS5:
2309                rate_section = 10;
2310                break;
2311        case DESC_RATEVHT2SS_MCS6:
2312        case DESC_RATEVHT2SS_MCS7:
2313        case DESC_RATEVHT2SS_MCS8:
2314        case DESC_RATEVHT2SS_MCS9:
2315                rate_section = 11;
2316                break;
2317        default:
2318                WARN_ONCE(true, "rtl8821ae: Rate_Section is Illegal\n");
2319                break;
2320        }
2321
2322        return rate_section;
2323}
2324
2325static s8 _rtl8812ae_phy_get_world_wide_limit(s8  *limit_table)
2326{
2327        s8 min = limit_table[0];
2328        u8 i = 0;
2329
2330        for (i = 0; i < MAX_REGULATION_NUM; ++i) {
2331                if (limit_table[i] < min)
2332                        min = limit_table[i];
2333        }
2334        return min;
2335}
2336
2337static s8 _rtl8812ae_phy_get_txpower_limit(struct ieee80211_hw *hw,
2338                                             u8 band,
2339                                             enum ht_channel_width bandwidth,
2340                                             enum radio_path rf_path,
2341                                             u8 rate, u8 channel)
2342{
2343        struct rtl_priv *rtlpriv = rtl_priv(hw);
2344        struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
2345        struct rtl_phy *rtlphy = &rtlpriv->phy;
2346        short band_temp = -1, regulation = -1, bandwidth_temp = -1,
2347                 rate_section = -1, channel_temp = -1;
2348        u16 regu, bdwidth, sec, chnl;
2349        s8 power_limit = MAX_POWER_INDEX;
2350
2351        if (rtlefuse->eeprom_regulatory == 2)
2352                return MAX_POWER_INDEX;
2353
2354        regulation = TXPWR_LMT_WW;
2355
2356        if (band == BAND_ON_2_4G)
2357                band_temp = 0;
2358        else if (band == BAND_ON_5G)
2359                band_temp = 1;
2360
2361        if (bandwidth == HT_CHANNEL_WIDTH_20)
2362                bandwidth_temp = 0;
2363        else if (bandwidth == HT_CHANNEL_WIDTH_20_40)
2364                bandwidth_temp = 1;
2365        else if (bandwidth == HT_CHANNEL_WIDTH_80)
2366                bandwidth_temp = 2;
2367
2368        switch (rate) {
2369        case DESC_RATE1M:
2370        case DESC_RATE2M:
2371        case DESC_RATE5_5M:
2372        case DESC_RATE11M:
2373                rate_section = 0;
2374                break;
2375        case DESC_RATE6M:
2376        case DESC_RATE9M:
2377        case DESC_RATE12M:
2378        case DESC_RATE18M:
2379        case DESC_RATE24M:
2380        case DESC_RATE36M:
2381        case DESC_RATE48M:
2382        case DESC_RATE54M:
2383                rate_section = 1;
2384                break;
2385        case DESC_RATEMCS0:
2386        case DESC_RATEMCS1:
2387        case DESC_RATEMCS2:
2388        case DESC_RATEMCS3:
2389        case DESC_RATEMCS4:
2390        case DESC_RATEMCS5:
2391        case DESC_RATEMCS6:
2392        case DESC_RATEMCS7:
2393                rate_section = 2;
2394                break;
2395        case DESC_RATEMCS8:
2396        case DESC_RATEMCS9:
2397        case DESC_RATEMCS10:
2398        case DESC_RATEMCS11:
2399        case DESC_RATEMCS12:
2400        case DESC_RATEMCS13:
2401        case DESC_RATEMCS14:
2402        case DESC_RATEMCS15:
2403                rate_section = 3;
2404                break;
2405        case DESC_RATEVHT1SS_MCS0:
2406        case DESC_RATEVHT1SS_MCS1:
2407        case DESC_RATEVHT1SS_MCS2:
2408        case DESC_RATEVHT1SS_MCS3:
2409        case DESC_RATEVHT1SS_MCS4:
2410        case DESC_RATEVHT1SS_MCS5:
2411        case DESC_RATEVHT1SS_MCS6:
2412        case DESC_RATEVHT1SS_MCS7:
2413        case DESC_RATEVHT1SS_MCS8:
2414        case DESC_RATEVHT1SS_MCS9:
2415                rate_section = 4;
2416                break;
2417        case DESC_RATEVHT2SS_MCS0:
2418        case DESC_RATEVHT2SS_MCS1:
2419        case DESC_RATEVHT2SS_MCS2:
2420        case DESC_RATEVHT2SS_MCS3:
2421        case DESC_RATEVHT2SS_MCS4:
2422        case DESC_RATEVHT2SS_MCS5:
2423        case DESC_RATEVHT2SS_MCS6:
2424        case DESC_RATEVHT2SS_MCS7:
2425        case DESC_RATEVHT2SS_MCS8:
2426        case DESC_RATEVHT2SS_MCS9:
2427                rate_section = 5;
2428                break;
2429        default:
2430                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2431                        "Wrong rate 0x%x\n", rate);
2432                break;
2433        }
2434
2435        if (band_temp == BAND_ON_5G  && rate_section == 0)
2436                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2437                         "Wrong rate 0x%x: No CCK in 5G Band\n", rate);
2438
2439        /*workaround for wrong index combination to obtain tx power limit,
2440          OFDM only exists in BW 20M*/
2441        if (rate_section == 1)
2442                bandwidth_temp = 0;
2443
2444        /*workaround for wrong index combination to obtain tx power limit,
2445         *HT on 80M will reference to HT on 40M
2446         */
2447        if ((rate_section == 2 || rate_section == 3) && band == BAND_ON_5G &&
2448            bandwidth_temp == 2)
2449                bandwidth_temp = 1;
2450
2451        if (band == BAND_ON_2_4G)
2452                channel_temp = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
2453                BAND_ON_2_4G, channel);
2454        else if (band == BAND_ON_5G)
2455                channel_temp = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
2456                BAND_ON_5G, channel);
2457        else if (band == BAND_ON_BOTH)
2458                ;/* BAND_ON_BOTH don't care temporarily */
2459
2460        if (band_temp == -1 || regulation == -1 || bandwidth_temp == -1 ||
2461                rate_section == -1 || channel_temp == -1) {
2462                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2463                         "Wrong index value to access power limit table [band %d][regulation %d][bandwidth %d][rf_path %d][rate_section %d][chnl %d]\n",
2464                         band_temp, regulation, bandwidth_temp, rf_path,
2465                         rate_section, channel_temp);
2466                return MAX_POWER_INDEX;
2467        }
2468
2469        regu = regulation;
2470        bdwidth = bandwidth_temp;
2471        sec = rate_section;
2472        chnl = channel_temp;
2473
2474        if (band == BAND_ON_2_4G) {
2475                s8 limits[10] = {0};
2476                u8 i;
2477
2478                for (i = 0; i < 4; ++i)
2479                        limits[i] = rtlphy->txpwr_limit_2_4g[i][bdwidth]
2480                        [sec][chnl][rf_path];
2481
2482                power_limit = (regulation == TXPWR_LMT_WW) ?
2483                        _rtl8812ae_phy_get_world_wide_limit(limits) :
2484                        rtlphy->txpwr_limit_2_4g[regu][bdwidth]
2485                                        [sec][chnl][rf_path];
2486        } else if (band == BAND_ON_5G) {
2487                s8 limits[10] = {0};
2488                u8 i;
2489
2490                for (i = 0; i < MAX_REGULATION_NUM; ++i)
2491                        limits[i] = rtlphy->txpwr_limit_5g[i][bdwidth]
2492                        [sec][chnl][rf_path];
2493
2494                power_limit = (regulation == TXPWR_LMT_WW) ?
2495                        _rtl8812ae_phy_get_world_wide_limit(limits) :
2496                        rtlphy->txpwr_limit_5g[regu][chnl]
2497                        [sec][chnl][rf_path];
2498        } else {
2499                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2500                         "No power limit table of the specified band\n");
2501        }
2502        return power_limit;
2503}
2504
2505static s8 _rtl8821ae_phy_get_txpower_by_rate(struct ieee80211_hw *hw,
2506                                        u8 band, u8 path, u8 rate)
2507{
2508        struct rtl_priv *rtlpriv = rtl_priv(hw);
2509        struct rtl_phy *rtlphy = &rtlpriv->phy;
2510        u8 shift = 0, rate_section, tx_num;
2511        s8 tx_pwr_diff = 0;
2512        s8 limit = 0;
2513
2514        rate_section = _rtl8821ae_phy_get_ratesection_intxpower_byrate(path, rate);
2515        tx_num = RF_TX_NUM_NONIMPLEMENT;
2516
2517        if (tx_num == RF_TX_NUM_NONIMPLEMENT) {
2518                if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
2519                        (rate >= DESC_RATEVHT2SS_MCS2 && rate <= DESC_RATEVHT2SS_MCS9))
2520                        tx_num = RF_2TX;
2521                else
2522                        tx_num = RF_1TX;
2523        }
2524
2525        switch (rate) {
2526        case DESC_RATE1M:
2527        case DESC_RATE6M:
2528        case DESC_RATE24M:
2529        case DESC_RATEMCS0:
2530        case DESC_RATEMCS4:
2531        case DESC_RATEMCS8:
2532        case DESC_RATEMCS12:
2533        case DESC_RATEVHT1SS_MCS0:
2534        case DESC_RATEVHT1SS_MCS4:
2535        case DESC_RATEVHT1SS_MCS8:
2536        case DESC_RATEVHT2SS_MCS2:
2537        case DESC_RATEVHT2SS_MCS6:
2538                shift = 0;
2539                break;
2540        case DESC_RATE2M:
2541        case DESC_RATE9M:
2542        case DESC_RATE36M:
2543        case DESC_RATEMCS1:
2544        case DESC_RATEMCS5:
2545        case DESC_RATEMCS9:
2546        case DESC_RATEMCS13:
2547        case DESC_RATEVHT1SS_MCS1:
2548        case DESC_RATEVHT1SS_MCS5:
2549        case DESC_RATEVHT1SS_MCS9:
2550        case DESC_RATEVHT2SS_MCS3:
2551        case DESC_RATEVHT2SS_MCS7:
2552                shift = 8;
2553                break;
2554        case DESC_RATE5_5M:
2555        case DESC_RATE12M:
2556        case DESC_RATE48M:
2557        case DESC_RATEMCS2:
2558        case DESC_RATEMCS6:
2559        case DESC_RATEMCS10:
2560        case DESC_RATEMCS14:
2561        case DESC_RATEVHT1SS_MCS2:
2562        case DESC_RATEVHT1SS_MCS6:
2563        case DESC_RATEVHT2SS_MCS0:
2564        case DESC_RATEVHT2SS_MCS4:
2565        case DESC_RATEVHT2SS_MCS8:
2566                shift = 16;
2567                break;
2568        case DESC_RATE11M:
2569        case DESC_RATE18M:
2570        case DESC_RATE54M:
2571        case DESC_RATEMCS3:
2572        case DESC_RATEMCS7:
2573        case DESC_RATEMCS11:
2574        case DESC_RATEMCS15:
2575        case DESC_RATEVHT1SS_MCS3:
2576        case DESC_RATEVHT1SS_MCS7:
2577        case DESC_RATEVHT2SS_MCS1:
2578        case DESC_RATEVHT2SS_MCS5:
2579        case DESC_RATEVHT2SS_MCS9:
2580                shift = 24;
2581                break;
2582        default:
2583                WARN_ONCE(true, "rtl8821ae: Rate_Section is Illegal\n");
2584                break;
2585        }
2586
2587        tx_pwr_diff = (u8)(rtlphy->tx_power_by_rate_offset[band][path]
2588                [tx_num][rate_section] >> shift) & 0xff;
2589
2590        /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
2591        if (rtlpriv->efuse.eeprom_regulatory != 2) {
2592                limit = _rtl8812ae_phy_get_txpower_limit(hw, band,
2593                        rtlphy->current_chan_bw, path, rate,
2594                        rtlphy->current_channel);
2595
2596                if (rate == DESC_RATEVHT1SS_MCS8 || rate == DESC_RATEVHT1SS_MCS9  ||
2597                         rate == DESC_RATEVHT2SS_MCS8 || rate == DESC_RATEVHT2SS_MCS9) {
2598                        if (limit < 0) {
2599                                if (tx_pwr_diff < (-limit))
2600                                        tx_pwr_diff = -limit;
2601                        }
2602                } else {
2603                        if (limit < 0)
2604                                tx_pwr_diff = limit;
2605                        else
2606                                tx_pwr_diff = tx_pwr_diff > limit ? limit : tx_pwr_diff;
2607                }
2608                RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2609                        "Maximum power by rate %d, final power by rate %d\n",
2610                        limit, tx_pwr_diff);
2611        }
2612
2613        return  tx_pwr_diff;
2614}
2615
2616static u8 _rtl8821ae_get_txpower_index(struct ieee80211_hw *hw, u8 path,
2617                                        u8 rate, u8 bandwidth, u8 channel)
2618{
2619        struct rtl_priv *rtlpriv = rtl_priv(hw);
2620        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
2621        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2622        u8 index = (channel - 1);
2623        u8 txpower = 0;
2624        bool in_24g = false;
2625        s8 powerdiff_byrate = 0;
2626
2627        if (((rtlhal->current_bandtype == BAND_ON_2_4G) &&
2628            (channel > 14 || channel < 1)) ||
2629            ((rtlhal->current_bandtype == BAND_ON_5G) && (channel <= 14))) {
2630                index = 0;
2631                RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2632                        "Illegal channel!!\n");
2633        }
2634
2635        in_24g = _rtl8821ae_phy_get_chnl_index(channel, &index);
2636        if (in_24g) {
2637                if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2638                        txpower = rtlefuse->txpwrlevel_cck[path][index];
2639                else if (DESC_RATE6M <= rate)
2640                        txpower = rtlefuse->txpwrlevel_ht40_1s[path][index];
2641                else
2642                        RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "invalid rate\n");
2643
2644                if (DESC_RATE6M <= rate && rate <= DESC_RATE54M &&
2645                    !RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2646                        txpower += rtlefuse->txpwr_legacyhtdiff[path][TX_1S];
2647
2648                if (bandwidth == HT_CHANNEL_WIDTH_20) {
2649                        if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2650                                (DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2651                                txpower += rtlefuse->txpwr_ht20diff[path][TX_1S];
2652                        if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2653                                (DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2654                                txpower += rtlefuse->txpwr_ht20diff[path][TX_2S];
2655                } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
2656                        if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2657                                (DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2658                                txpower += rtlefuse->txpwr_ht40diff[path][TX_1S];
2659                        if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2660                                (DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2661                                txpower += rtlefuse->txpwr_ht40diff[path][TX_2S];
2662                } else if (bandwidth == HT_CHANNEL_WIDTH_80) {
2663                        if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2664                            (DESC_RATEVHT1SS_MCS0 <= rate &&
2665                             rate <= DESC_RATEVHT2SS_MCS9))
2666                                txpower += rtlefuse->txpwr_ht40diff[path][TX_1S];
2667                        if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2668                            (DESC_RATEVHT2SS_MCS0 <= rate &&
2669                             rate <= DESC_RATEVHT2SS_MCS9))
2670                                txpower += rtlefuse->txpwr_ht40diff[path][TX_2S];
2671                }
2672        } else {
2673                if (DESC_RATE6M <= rate)
2674                        txpower = rtlefuse->txpwr_5g_bw40base[path][index];
2675                else
2676                        RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_WARNING,
2677                                 "INVALID Rate.\n");
2678
2679                if (DESC_RATE6M <= rate && rate <= DESC_RATE54M &&
2680                    !RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2681                        txpower += rtlefuse->txpwr_5g_ofdmdiff[path][TX_1S];
2682
2683                if (bandwidth == HT_CHANNEL_WIDTH_20) {
2684                        if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2685                            (DESC_RATEVHT1SS_MCS0 <= rate &&
2686                             rate <= DESC_RATEVHT2SS_MCS9))
2687                                txpower += rtlefuse->txpwr_5g_bw20diff[path][TX_1S];
2688                        if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2689                            (DESC_RATEVHT2SS_MCS0 <= rate &&
2690                             rate <= DESC_RATEVHT2SS_MCS9))
2691                                txpower += rtlefuse->txpwr_5g_bw20diff[path][TX_2S];
2692                } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
2693                        if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2694                            (DESC_RATEVHT1SS_MCS0 <= rate &&
2695                             rate <= DESC_RATEVHT2SS_MCS9))
2696                                txpower += rtlefuse->txpwr_5g_bw40diff[path][TX_1S];
2697                        if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2698                            (DESC_RATEVHT2SS_MCS0 <= rate &&
2699                             rate <= DESC_RATEVHT2SS_MCS9))
2700                                txpower += rtlefuse->txpwr_5g_bw40diff[path][TX_2S];
2701                } else if (bandwidth == HT_CHANNEL_WIDTH_80) {
2702                        u8 i;
2703
2704                        for (i = 0; i < sizeof(channel5g_80m) / sizeof(u8); ++i)
2705                                if (channel5g_80m[i] == channel)
2706                                        index = i;
2707
2708                        if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2709                            (DESC_RATEVHT1SS_MCS0 <= rate &&
2710                             rate <= DESC_RATEVHT2SS_MCS9))
2711                                txpower = rtlefuse->txpwr_5g_bw80base[path][index]
2712                                        + rtlefuse->txpwr_5g_bw80diff[path][TX_1S];
2713                        if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2714                            (DESC_RATEVHT2SS_MCS0 <= rate &&
2715                             rate <= DESC_RATEVHT2SS_MCS9))
2716                                txpower = rtlefuse->txpwr_5g_bw80base[path][index]
2717                                        + rtlefuse->txpwr_5g_bw80diff[path][TX_1S]
2718                                        + rtlefuse->txpwr_5g_bw80diff[path][TX_2S];
2719                    }
2720        }
2721        if (rtlefuse->eeprom_regulatory != 2)
2722                powerdiff_byrate =
2723                  _rtl8821ae_phy_get_txpower_by_rate(hw, (u8)(!in_24g),
2724                                                     path, rate);
2725
2726        if (rate == DESC_RATEVHT1SS_MCS8 || rate == DESC_RATEVHT1SS_MCS9 ||
2727            rate == DESC_RATEVHT2SS_MCS8 || rate == DESC_RATEVHT2SS_MCS9)
2728                txpower -= powerdiff_byrate;
2729        else
2730                txpower += powerdiff_byrate;
2731
2732        if (rate > DESC_RATE11M)
2733                txpower += rtlpriv->dm.remnant_ofdm_swing_idx[path];
2734        else
2735                txpower += rtlpriv->dm.remnant_cck_idx;
2736
2737        if (txpower > MAX_POWER_INDEX)
2738                txpower = MAX_POWER_INDEX;
2739
2740        return txpower;
2741}
2742
2743static void _rtl8821ae_phy_set_txpower_index(struct ieee80211_hw *hw,
2744                                             u8 power_index, u8 path, u8 rate)
2745{
2746        struct rtl_priv *rtlpriv = rtl_priv(hw);
2747
2748        if (path == RF90_PATH_A) {
2749                switch (rate) {
2750                case DESC_RATE1M:
2751                        rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2752                                      MASKBYTE0, power_index);
2753                        break;
2754                case DESC_RATE2M:
2755                        rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2756                                      MASKBYTE1, power_index);
2757                        break;
2758                case DESC_RATE5_5M:
2759                        rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2760                                      MASKBYTE2, power_index);
2761                        break;
2762                case DESC_RATE11M:
2763                        rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2764                                      MASKBYTE3, power_index);
2765                        break;
2766                case DESC_RATE6M:
2767                        rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2768                                      MASKBYTE0, power_index);
2769                        break;
2770                case DESC_RATE9M:
2771                        rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2772                                      MASKBYTE1, power_index);
2773                        break;
2774                case DESC_RATE12M:
2775                        rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2776                                      MASKBYTE2, power_index);
2777                        break;
2778                case DESC_RATE18M:
2779                        rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2780                                      MASKBYTE3, power_index);
2781                        break;
2782                case DESC_RATE24M:
2783                        rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2784                                      MASKBYTE0, power_index);
2785                        break;
2786                case DESC_RATE36M:
2787                        rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2788                                      MASKBYTE1, power_index);
2789                        break;
2790                case DESC_RATE48M:
2791                        rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2792                                      MASKBYTE2, power_index);
2793                        break;
2794                case DESC_RATE54M:
2795                        rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2796                                      MASKBYTE3, power_index);
2797                        break;
2798                case DESC_RATEMCS0:
2799                        rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2800                                      MASKBYTE0, power_index);
2801                        break;
2802                case DESC_RATEMCS1:
2803                        rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2804                                      MASKBYTE1, power_index);
2805                        break;
2806                case DESC_RATEMCS2:
2807                        rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2808                                      MASKBYTE2, power_index);
2809                        break;
2810                case DESC_RATEMCS3:
2811                        rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2812                                      MASKBYTE3, power_index);
2813                        break;
2814                case DESC_RATEMCS4:
2815                        rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2816                                      MASKBYTE0, power_index);
2817                        break;
2818                case DESC_RATEMCS5:
2819                        rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2820                                      MASKBYTE1, power_index);
2821                        break;
2822                case DESC_RATEMCS6:
2823                        rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2824                                      MASKBYTE2, power_index);
2825                        break;
2826                case DESC_RATEMCS7:
2827                        rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2828                                      MASKBYTE3, power_index);
2829                        break;
2830                case DESC_RATEMCS8:
2831                        rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2832                                      MASKBYTE0, power_index);
2833                        break;
2834                case DESC_RATEMCS9:
2835                        rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2836                                      MASKBYTE1, power_index);
2837                        break;
2838                case DESC_RATEMCS10:
2839                        rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2840                                      MASKBYTE2, power_index);
2841                        break;
2842                case DESC_RATEMCS11:
2843                        rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2844                                      MASKBYTE3, power_index);
2845                        break;
2846                case DESC_RATEMCS12:
2847                        rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2848                                      MASKBYTE0, power_index);
2849                        break;
2850                case DESC_RATEMCS13:
2851                        rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2852                                      MASKBYTE1, power_index);
2853                        break;
2854                case DESC_RATEMCS14:
2855                        rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2856                                      MASKBYTE2, power_index);
2857                        break;
2858                case DESC_RATEMCS15:
2859                        rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2860                                      MASKBYTE3, power_index);
2861                        break;
2862                case DESC_RATEVHT1SS_MCS0:
2863                        rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2864                                      MASKBYTE0, power_index);
2865                        break;
2866                case DESC_RATEVHT1SS_MCS1:
2867                        rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2868                                      MASKBYTE1, power_index);
2869                        break;
2870                case DESC_RATEVHT1SS_MCS2:
2871                        rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2872                                      MASKBYTE2, power_index);
2873                        break;
2874                case DESC_RATEVHT1SS_MCS3:
2875                        rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2876                                      MASKBYTE3, power_index);
2877                        break;
2878                case DESC_RATEVHT1SS_MCS4:
2879                        rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2880                                      MASKBYTE0, power_index);
2881                        break;
2882                case DESC_RATEVHT1SS_MCS5:
2883                        rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2884                                      MASKBYTE1, power_index);
2885                        break;
2886                case DESC_RATEVHT1SS_MCS6:
2887                        rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2888                                      MASKBYTE2, power_index);
2889                        break;
2890                case DESC_RATEVHT1SS_MCS7:
2891                        rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2892                                      MASKBYTE3, power_index);
2893                        break;
2894                case DESC_RATEVHT1SS_MCS8:
2895                        rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2896                                      MASKBYTE0, power_index);
2897                        break;
2898                case DESC_RATEVHT1SS_MCS9:
2899                        rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2900                                      MASKBYTE1, power_index);
2901                        break;
2902                case DESC_RATEVHT2SS_MCS0:
2903                        rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2904                                      MASKBYTE2, power_index);
2905                        break;
2906                case DESC_RATEVHT2SS_MCS1:
2907                        rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2908                                      MASKBYTE3, power_index);
2909                        break;
2910                case DESC_RATEVHT2SS_MCS2:
2911                        rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2912                                      MASKBYTE0, power_index);
2913                        break;
2914                case DESC_RATEVHT2SS_MCS3:
2915                        rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2916                                      MASKBYTE1, power_index);
2917                        break;
2918                case DESC_RATEVHT2SS_MCS4:
2919                        rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2920                                      MASKBYTE2, power_index);
2921                        break;
2922                case DESC_RATEVHT2SS_MCS5:
2923                        rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2924                                      MASKBYTE3, power_index);
2925                        break;
2926                case DESC_RATEVHT2SS_MCS6:
2927                        rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2928                                      MASKBYTE0, power_index);
2929                        break;
2930                case DESC_RATEVHT2SS_MCS7:
2931                        rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2932                                      MASKBYTE1, power_index);
2933                        break;
2934                case DESC_RATEVHT2SS_MCS8:
2935                        rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2936                                      MASKBYTE2, power_index);
2937                        break;
2938                case DESC_RATEVHT2SS_MCS9:
2939                        rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2940                                      MASKBYTE3, power_index);
2941                        break;
2942                default:
2943                        RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2944                                "Invalid Rate!!\n");
2945                        break;
2946                }
2947        } else if (path == RF90_PATH_B) {
2948                switch (rate) {
2949                case DESC_RATE1M:
2950                        rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2951                                      MASKBYTE0, power_index);
2952                        break;
2953                case DESC_RATE2M:
2954                        rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2955                                      MASKBYTE1, power_index);
2956                        break;
2957                case DESC_RATE5_5M:
2958                        rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2959                                      MASKBYTE2, power_index);
2960                        break;
2961                case DESC_RATE11M:
2962                        rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2963                                      MASKBYTE3, power_index);
2964                        break;
2965                case DESC_RATE6M:
2966                        rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
2967                                      MASKBYTE0, power_index);
2968                        break;
2969                case DESC_RATE9M:
2970                        rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
2971                                      MASKBYTE1, power_index);
2972                        break;
2973                case DESC_RATE12M:
2974                        rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
2975                                      MASKBYTE2, power_index);
2976                        break;
2977                case DESC_RATE18M:
2978                        rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
2979                                      MASKBYTE3, power_index);
2980                        break;
2981                case DESC_RATE24M:
2982                        rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
2983                                      MASKBYTE0, power_index);
2984                        break;
2985                case DESC_RATE36M:
2986                        rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
2987                                      MASKBYTE1, power_index);
2988                        break;
2989                case DESC_RATE48M:
2990                        rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
2991                                      MASKBYTE2, power_index);
2992                        break;
2993                case DESC_RATE54M:
2994                        rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
2995                                      MASKBYTE3, power_index);
2996                        break;
2997                case DESC_RATEMCS0:
2998                        rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
2999                                      MASKBYTE0, power_index);
3000                        break;
3001                case DESC_RATEMCS1:
3002                        rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3003                                      MASKBYTE1, power_index);
3004                        break;
3005                case DESC_RATEMCS2:
3006                        rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3007                                      MASKBYTE2, power_index);
3008                        break;
3009                case DESC_RATEMCS3:
3010                        rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3011                                      MASKBYTE3, power_index);
3012                        break;
3013                case DESC_RATEMCS4:
3014                        rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3015                                      MASKBYTE0, power_index);
3016                        break;
3017                case DESC_RATEMCS5:
3018                        rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3019                                      MASKBYTE1, power_index);
3020                        break;
3021                case DESC_RATEMCS6:
3022                        rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3023                                      MASKBYTE2, power_index);
3024                        break;
3025                case DESC_RATEMCS7:
3026                        rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3027                                      MASKBYTE3, power_index);
3028                        break;
3029                case DESC_RATEMCS8:
3030                        rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3031                                      MASKBYTE0, power_index);
3032                        break;
3033                case DESC_RATEMCS9:
3034                        rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3035                                      MASKBYTE1, power_index);
3036                        break;
3037                case DESC_RATEMCS10:
3038                        rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3039                                      MASKBYTE2, power_index);
3040                        break;
3041                case DESC_RATEMCS11:
3042                        rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3043                                      MASKBYTE3, power_index);
3044                        break;
3045                case DESC_RATEMCS12:
3046                        rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3047                                      MASKBYTE0, power_index);
3048                        break;
3049                case DESC_RATEMCS13:
3050                        rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3051                                      MASKBYTE1, power_index);
3052                        break;
3053                case DESC_RATEMCS14:
3054                        rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3055                                      MASKBYTE2, power_index);
3056                        break;
3057                case DESC_RATEMCS15:
3058                        rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3059                                      MASKBYTE3, power_index);
3060                        break;
3061                case DESC_RATEVHT1SS_MCS0:
3062                        rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3063                                      MASKBYTE0, power_index);
3064                        break;
3065                case DESC_RATEVHT1SS_MCS1:
3066                        rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3067                                      MASKBYTE1, power_index);
3068                        break;
3069                case DESC_RATEVHT1SS_MCS2:
3070                        rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3071                                      MASKBYTE2, power_index);
3072                        break;
3073                case DESC_RATEVHT1SS_MCS3:
3074                        rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3075                                      MASKBYTE3, power_index);
3076                        break;
3077                case DESC_RATEVHT1SS_MCS4:
3078                        rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3079                                      MASKBYTE0, power_index);
3080                        break;
3081                case DESC_RATEVHT1SS_MCS5:
3082                        rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3083                                      MASKBYTE1, power_index);
3084                        break;
3085                case DESC_RATEVHT1SS_MCS6:
3086                        rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3087                                      MASKBYTE2, power_index);
3088                        break;
3089                case DESC_RATEVHT1SS_MCS7:
3090                        rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3091                                      MASKBYTE3, power_index);
3092                        break;
3093                case DESC_RATEVHT1SS_MCS8:
3094                        rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3095                                      MASKBYTE0, power_index);
3096                        break;
3097                case DESC_RATEVHT1SS_MCS9:
3098                        rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3099                                      MASKBYTE1, power_index);
3100                        break;
3101                case DESC_RATEVHT2SS_MCS0:
3102                        rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3103                                      MASKBYTE2, power_index);
3104                        break;
3105                case DESC_RATEVHT2SS_MCS1:
3106                        rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3107                                      MASKBYTE3, power_index);
3108                        break;
3109                case DESC_RATEVHT2SS_MCS2:
3110                        rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3111                                      MASKBYTE0, power_index);
3112                        break;
3113                case DESC_RATEVHT2SS_MCS3:
3114                        rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3115                                      MASKBYTE1, power_index);
3116                        break;
3117                case DESC_RATEVHT2SS_MCS4:
3118                        rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3119                                      MASKBYTE2, power_index);
3120                        break;
3121                case DESC_RATEVHT2SS_MCS5:
3122                        rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3123                                      MASKBYTE3, power_index);
3124                        break;
3125                case DESC_RATEVHT2SS_MCS6:
3126                        rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3127                                      MASKBYTE0, power_index);
3128                        break;
3129                case DESC_RATEVHT2SS_MCS7:
3130                        rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3131                                      MASKBYTE1, power_index);
3132                        break;
3133                case DESC_RATEVHT2SS_MCS8:
3134                        rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3135                                      MASKBYTE2, power_index);
3136                        break;
3137                case DESC_RATEVHT2SS_MCS9:
3138                        rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3139                                      MASKBYTE3, power_index);
3140                        break;
3141                default:
3142                        RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
3143                                 "Invalid Rate!!\n");
3144                        break;
3145                }
3146        } else {
3147                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
3148                         "Invalid RFPath!!\n");
3149        }
3150}
3151
3152static void _rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
3153                                                     u8 *array, u8 path,
3154                                                     u8 channel, u8 size)
3155{
3156        struct rtl_priv *rtlpriv = rtl_priv(hw);
3157        struct rtl_phy *rtlphy = &rtlpriv->phy;
3158        u8 i;
3159        u8 power_index;
3160
3161        for (i = 0; i < size; i++) {
3162                power_index =
3163                  _rtl8821ae_get_txpower_index(hw, path, array[i],
3164                                               rtlphy->current_chan_bw,
3165                                               channel);
3166                _rtl8821ae_phy_set_txpower_index(hw, power_index, path,
3167                                                 array[i]);
3168        }
3169}
3170
3171static void _rtl8821ae_phy_txpower_training_by_path(struct ieee80211_hw *hw,
3172                                                    u8 bw, u8 channel, u8 path)
3173{
3174        struct rtl_priv *rtlpriv = rtl_priv(hw);
3175        struct rtl_phy *rtlphy = &rtlpriv->phy;
3176
3177        u8 i;
3178        u32 power_level, data, offset;
3179
3180        if (path >= rtlphy->num_total_rfpath)
3181                return;
3182
3183        data = 0;
3184        if (path == RF90_PATH_A) {
3185                power_level =
3186                        _rtl8821ae_get_txpower_index(hw, RF90_PATH_A,
3187                        DESC_RATEMCS7, bw, channel);
3188                offset =  RA_TXPWRTRAING;
3189        } else {
3190                power_level =
3191                        _rtl8821ae_get_txpower_index(hw, RF90_PATH_B,
3192                        DESC_RATEMCS7, bw, channel);
3193                offset =  RB_TXPWRTRAING;
3194        }
3195
3196        for (i = 0; i < 3; i++) {
3197                if (i == 0)
3198                        power_level = power_level - 10;
3199                else if (i == 1)
3200                        power_level = power_level - 8;
3201                else
3202                        power_level = power_level - 6;
3203
3204                data |= (((power_level > 2) ? (power_level) : 2) << (i * 8));
3205        }
3206        rtl_set_bbreg(hw, offset, 0xffffff, data);
3207}
3208
3209void rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
3210                                             u8 channel, u8 path)
3211{
3212        /* struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); */
3213        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3214        struct rtl_priv *rtlpriv = rtl_priv(hw);
3215        struct rtl_phy *rtlphy = &rtlpriv->phy;
3216        u8 cck_rates[]  = {DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M,
3217                              DESC_RATE11M};
3218        u8 sizes_of_cck_retes = 4;
3219        u8 ofdm_rates[]  = {DESC_RATE6M, DESC_RATE9M, DESC_RATE12M,
3220                                DESC_RATE18M, DESC_RATE24M, DESC_RATE36M,
3221                                DESC_RATE48M, DESC_RATE54M};
3222        u8 sizes_of_ofdm_retes = 8;
3223        u8 ht_rates_1t[]  = {DESC_RATEMCS0, DESC_RATEMCS1, DESC_RATEMCS2,
3224                                DESC_RATEMCS3, DESC_RATEMCS4, DESC_RATEMCS5,
3225                                DESC_RATEMCS6, DESC_RATEMCS7};
3226        u8 sizes_of_ht_retes_1t = 8;
3227        u8 ht_rates_2t[]  = {DESC_RATEMCS8, DESC_RATEMCS9,
3228                                DESC_RATEMCS10, DESC_RATEMCS11,
3229                                DESC_RATEMCS12, DESC_RATEMCS13,
3230                                DESC_RATEMCS14, DESC_RATEMCS15};
3231        u8 sizes_of_ht_retes_2t = 8;
3232        u8 vht_rates_1t[]  = {DESC_RATEVHT1SS_MCS0, DESC_RATEVHT1SS_MCS1,
3233                                DESC_RATEVHT1SS_MCS2, DESC_RATEVHT1SS_MCS3,
3234                                DESC_RATEVHT1SS_MCS4, DESC_RATEVHT1SS_MCS5,
3235                                DESC_RATEVHT1SS_MCS6, DESC_RATEVHT1SS_MCS7,
3236                             DESC_RATEVHT1SS_MCS8, DESC_RATEVHT1SS_MCS9};
3237        u8 vht_rates_2t[]  = {DESC_RATEVHT2SS_MCS0, DESC_RATEVHT2SS_MCS1,
3238                                DESC_RATEVHT2SS_MCS2, DESC_RATEVHT2SS_MCS3,
3239                                DESC_RATEVHT2SS_MCS4, DESC_RATEVHT2SS_MCS5,
3240                                DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7,
3241                                DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9};
3242        u8 sizes_of_vht_retes = 10;
3243
3244        if (rtlhal->current_bandtype == BAND_ON_2_4G)
3245                _rtl8821ae_phy_set_txpower_level_by_path(hw, cck_rates, path, channel,
3246                                                         sizes_of_cck_retes);
3247
3248        _rtl8821ae_phy_set_txpower_level_by_path(hw, ofdm_rates, path, channel,
3249                                                 sizes_of_ofdm_retes);
3250        _rtl8821ae_phy_set_txpower_level_by_path(hw, ht_rates_1t, path, channel,
3251                                                 sizes_of_ht_retes_1t);
3252        _rtl8821ae_phy_set_txpower_level_by_path(hw, vht_rates_1t, path, channel,
3253                                                 sizes_of_vht_retes);
3254
3255        if (rtlphy->num_total_rfpath >= 2) {
3256                _rtl8821ae_phy_set_txpower_level_by_path(hw, ht_rates_2t, path,
3257                                                         channel,
3258                                                         sizes_of_ht_retes_2t);
3259                _rtl8821ae_phy_set_txpower_level_by_path(hw, vht_rates_2t, path,
3260                                                         channel,
3261                                                         sizes_of_vht_retes);
3262        }
3263
3264        _rtl8821ae_phy_txpower_training_by_path(hw, rtlphy->current_chan_bw,
3265                                                channel, path);
3266}
3267
3268/*just in case, write txpower in DW, to reduce time*/
3269void rtl8821ae_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
3270{
3271        struct rtl_priv *rtlpriv = rtl_priv(hw);
3272        struct rtl_phy *rtlphy = &rtlpriv->phy;
3273        u8 path = 0;
3274
3275        for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; ++path)
3276                rtl8821ae_phy_set_txpower_level_by_path(hw, channel, path);
3277}
3278
3279static long _rtl8821ae_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
3280                                            enum wireless_mode wirelessmode,
3281                                            u8 txpwridx)
3282{
3283        long offset;
3284        long pwrout_dbm;
3285
3286        switch (wirelessmode) {
3287        case WIRELESS_MODE_B:
3288                offset = -7;
3289                break;
3290        case WIRELESS_MODE_G:
3291        case WIRELESS_MODE_N_24G:
3292                offset = -8;
3293                break;
3294        default:
3295                offset = -8;
3296                break;
3297        }
3298        pwrout_dbm = txpwridx / 2 + offset;
3299        return pwrout_dbm;
3300}
3301
3302void rtl8821ae_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
3303{
3304        struct rtl_priv *rtlpriv = rtl_priv(hw);
3305        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3306        enum io_type iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
3307
3308        if (!is_hal_stop(rtlhal)) {
3309                switch (operation) {
3310                case SCAN_OPT_BACKUP_BAND0:
3311                        iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
3312                        rtlpriv->cfg->ops->set_hw_reg(hw,
3313                                                      HW_VAR_IO_CMD,
3314                                                      (u8 *)&iotype);
3315
3316                        break;
3317                case SCAN_OPT_BACKUP_BAND1:
3318                        iotype = IO_CMD_PAUSE_BAND1_DM_BY_SCAN;
3319                        rtlpriv->cfg->ops->set_hw_reg(hw,
3320                                                      HW_VAR_IO_CMD,
3321                                                      (u8 *)&iotype);
3322
3323                        break;
3324                case SCAN_OPT_RESTORE:
3325                        iotype = IO_CMD_RESUME_DM_BY_SCAN;
3326                        rtlpriv->cfg->ops->set_hw_reg(hw,
3327                                                      HW_VAR_IO_CMD,
3328                                                      (u8 *)&iotype);
3329                        break;
3330                default:
3331                        pr_err("Unknown Scan Backup operation.\n");
3332                        break;
3333                }
3334        }
3335}
3336
3337static void _rtl8821ae_phy_set_reg_bw(struct rtl_priv *rtlpriv, u8 bw)
3338{
3339        u16 reg_rf_mode_bw, tmp = 0;
3340
3341        reg_rf_mode_bw = rtl_read_word(rtlpriv, REG_TRXPTCL_CTL);
3342        switch (bw) {
3343        case HT_CHANNEL_WIDTH_20:
3344                rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, reg_rf_mode_bw & 0xFE7F);
3345                break;
3346        case HT_CHANNEL_WIDTH_20_40:
3347                tmp = reg_rf_mode_bw | BIT(7);
3348                rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, tmp & 0xFEFF);
3349                break;
3350        case HT_CHANNEL_WIDTH_80:
3351                tmp = reg_rf_mode_bw | BIT(8);
3352                rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, tmp & 0xFF7F);
3353                break;
3354        default:
3355                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "unknown Bandwidth: 0x%x\n", bw);
3356                break;
3357        }
3358}
3359
3360static u8 _rtl8821ae_phy_get_secondary_chnl(struct rtl_priv *rtlpriv)
3361{
3362        struct rtl_phy *rtlphy = &rtlpriv->phy;
3363        struct rtl_mac *mac = rtl_mac(rtlpriv);
3364        u8 sc_set_40 = 0, sc_set_20 = 0;
3365
3366        if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) {
3367                if (mac->cur_80_prime_sc == PRIME_CHNL_OFFSET_LOWER)
3368                        sc_set_40 = VHT_DATA_SC_40_LOWER_OF_80MHZ;
3369                else if (mac->cur_80_prime_sc == PRIME_CHNL_OFFSET_UPPER)
3370                        sc_set_40 = VHT_DATA_SC_40_UPPER_OF_80MHZ;
3371                else
3372                        pr_err("SCMapping: Not Correct Primary40MHz Setting\n");
3373
3374                if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) &&
3375                        (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER))
3376                        sc_set_20 = VHT_DATA_SC_20_LOWEST_OF_80MHZ;
3377                else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) &&
3378                        (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER))
3379                        sc_set_20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
3380                else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) &&
3381                        (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER))
3382                        sc_set_20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
3383                else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) &&
3384                        (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER))
3385                        sc_set_20 = VHT_DATA_SC_20_UPPERST_OF_80MHZ;
3386                else
3387                        pr_err("SCMapping: Not Correct Primary40MHz Setting\n");
3388        } else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
3389                if (mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER)
3390                        sc_set_20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
3391                else if (mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER)
3392                        sc_set_20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
3393                else
3394                        pr_err("SCMapping: Not Correct Primary40MHz Setting\n");
3395        }
3396        return (sc_set_40 << 4) | sc_set_20;
3397}
3398
3399void rtl8821ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
3400{
3401        struct rtl_priv *rtlpriv = rtl_priv(hw);
3402        struct rtl_phy *rtlphy = &rtlpriv->phy;
3403        u8 sub_chnl = 0;
3404        u8 l1pk_val = 0;
3405
3406        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3407                 "Switch to %s bandwidth\n",
3408                  (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
3409                  "20MHz" :
3410                  (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40 ?
3411                  "40MHz" : "80MHz")));
3412
3413        _rtl8821ae_phy_set_reg_bw(rtlpriv, rtlphy->current_chan_bw);
3414        sub_chnl = _rtl8821ae_phy_get_secondary_chnl(rtlpriv);
3415        rtl_write_byte(rtlpriv, 0x0483, sub_chnl);
3416
3417        switch (rtlphy->current_chan_bw) {
3418        case HT_CHANNEL_WIDTH_20:
3419                rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300200);
3420                rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
3421
3422                if (rtlphy->rf_type == RF_2T2R)
3423                        rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, 7);
3424                else
3425                        rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, 8);
3426                break;
3427        case HT_CHANNEL_WIDTH_20_40:
3428                rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300201);
3429                rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
3430                rtl_set_bbreg(hw, RRFMOD, 0x3C, sub_chnl);
3431                rtl_set_bbreg(hw, RCCAONSEC, 0xf0000000, sub_chnl);
3432
3433                if (rtlphy->reg_837 & BIT(2))
3434                        l1pk_val = 6;
3435                else {
3436                        if (rtlphy->rf_type == RF_2T2R)
3437                                l1pk_val = 7;
3438                        else
3439                                l1pk_val = 8;
3440                }
3441                /* 0x848[25:22] = 0x6 */
3442                rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, l1pk_val);
3443
3444                if (sub_chnl == VHT_DATA_SC_20_UPPER_OF_80MHZ)
3445                        rtl_set_bbreg(hw, RCCK_SYSTEM, BCCK_SYSTEM, 1);
3446                else
3447                        rtl_set_bbreg(hw, RCCK_SYSTEM, BCCK_SYSTEM, 0);
3448                break;
3449
3450        case HT_CHANNEL_WIDTH_80:
3451                 /* 0x8ac[21,20,9:6,1,0]=8'b11100010 */
3452                rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300202);
3453                /* 0x8c4[30] = 1 */
3454                rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 1);
3455                rtl_set_bbreg(hw, RRFMOD, 0x3C, sub_chnl);
3456                rtl_set_bbreg(hw, RCCAONSEC, 0xf0000000, sub_chnl);
3457
3458                if (rtlphy->reg_837 & BIT(2))
3459                        l1pk_val = 5;
3460                else {
3461                        if (rtlphy->rf_type == RF_2T2R)
3462                                l1pk_val = 6;
3463                        else
3464                                l1pk_val = 7;
3465                }
3466                rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, l1pk_val);
3467
3468                break;
3469        default:
3470                pr_err("unknown bandwidth: %#X\n",
3471                       rtlphy->current_chan_bw);
3472                break;
3473        }
3474
3475        rtl8812ae_fixspur(hw, rtlphy->current_chan_bw, rtlphy->current_channel);
3476
3477        rtl8821ae_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
3478        rtlphy->set_bwmode_inprogress = false;
3479
3480        RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
3481}
3482
3483void rtl8821ae_phy_set_bw_mode(struct ieee80211_hw *hw,
3484                            enum nl80211_channel_type ch_type)
3485{
3486        struct rtl_priv *rtlpriv = rtl_priv(hw);
3487        struct rtl_phy *rtlphy = &rtlpriv->phy;
3488        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3489        u8 tmp_bw = rtlphy->current_chan_bw;
3490
3491        if (rtlphy->set_bwmode_inprogress)
3492                return;
3493        rtlphy->set_bwmode_inprogress = true;
3494        if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw)))
3495                rtl8821ae_phy_set_bw_mode_callback(hw);
3496        else {
3497                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
3498                         "FALSE driver sleep or unload\n");
3499                rtlphy->set_bwmode_inprogress = false;
3500                rtlphy->current_chan_bw = tmp_bw;
3501        }
3502}
3503
3504void rtl8821ae_phy_sw_chnl_callback(struct ieee80211_hw *hw)
3505{
3506        struct rtl_priv *rtlpriv = rtl_priv(hw);
3507        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3508        struct rtl_phy *rtlphy = &rtlpriv->phy;
3509        u8 channel = rtlphy->current_channel;
3510        u8 path;
3511        u32 data;
3512
3513        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3514                 "switch to channel%d\n", rtlphy->current_channel);
3515        if (is_hal_stop(rtlhal))
3516                return;
3517
3518        if (36 <= channel && channel <= 48)
3519                data = 0x494;
3520        else if (50 <= channel && channel <= 64)
3521                data = 0x453;
3522        else if (100 <= channel && channel <= 116)
3523                data = 0x452;
3524        else if (118 <= channel)
3525                data = 0x412;
3526        else
3527                data = 0x96a;
3528        rtl_set_bbreg(hw, RFC_AREA, 0x1ffe0000, data);
3529
3530        for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; path++) {
3531                if (36 <= channel && channel <= 64)
3532                        data = 0x101;
3533                else if (100 <= channel && channel <= 140)
3534                        data = 0x301;
3535                else if (140 < channel)
3536                        data = 0x501;
3537                else
3538                        data = 0x000;
3539                rtl8821ae_phy_set_rf_reg(hw, path, RF_CHNLBW,
3540                        BIT(18)|BIT(17)|BIT(16)|BIT(9)|BIT(8), data);
3541
3542                rtl8821ae_phy_set_rf_reg(hw, path, RF_CHNLBW,
3543                        BMASKBYTE0, channel);
3544
3545                if (channel > 14) {
3546                        if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
3547                                if (36 <= channel && channel <= 64)
3548                                        data = 0x114E9;
3549                                else
3550                                        data = 0x110E9;
3551                                rtl8821ae_phy_set_rf_reg(hw, path, RF_APK,
3552                                        BRFREGOFFSETMASK, data);
3553                        }
3554                }
3555        }
3556        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
3557}
3558
3559u8 rtl8821ae_phy_sw_chnl(struct ieee80211_hw *hw)
3560{
3561        struct rtl_priv *rtlpriv = rtl_priv(hw);
3562        struct rtl_phy *rtlphy = &rtlpriv->phy;
3563        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3564        u32 timeout = 1000, timecount = 0;
3565        u8 channel = rtlphy->current_channel;
3566
3567        if (rtlphy->sw_chnl_inprogress)
3568                return 0;
3569        if (rtlphy->set_bwmode_inprogress)
3570                return 0;
3571
3572        if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) {
3573                RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
3574                         "sw_chnl_inprogress false driver sleep or unload\n");
3575                return 0;
3576        }
3577        while (rtlphy->lck_inprogress && timecount < timeout) {
3578                mdelay(50);
3579                timecount += 50;
3580        }
3581
3582        if (rtlphy->current_channel > 14 && rtlhal->current_bandtype != BAND_ON_5G)
3583                rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_5G);
3584        else if (rtlphy->current_channel <= 14 && rtlhal->current_bandtype != BAND_ON_2_4G)
3585                rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_2_4G);
3586
3587        rtlphy->sw_chnl_inprogress = true;
3588        if (channel == 0)
3589                channel = 1;
3590
3591        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3592                 "switch to channel%d, band type is %d\n",
3593                 rtlphy->current_channel, rtlhal->current_bandtype);
3594
3595        rtl8821ae_phy_sw_chnl_callback(hw);
3596
3597        rtl8821ae_dm_clear_txpower_tracking_state(hw);
3598        rtl8821ae_phy_set_txpower_level(hw, rtlphy->current_channel);
3599
3600        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
3601        rtlphy->sw_chnl_inprogress = false;
3602        return 1;
3603}
3604
3605u8 _rtl8812ae_get_right_chnl_place_for_iqk(u8 chnl)
3606{
3607        static const u8 channel_all[TARGET_CHNL_NUM_2G_5G_8812] = {
3608                1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
3609                14, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54,
3610                56, 58, 60, 62, 64, 100, 102, 104, 106, 108,
3611                110, 112, 114, 116, 118, 120, 122, 124, 126,
3612                128, 130, 132, 134, 136, 138, 140, 149, 151,
3613                153, 155, 157, 159, 161, 163, 165};
3614        u8 place;
3615
3616        if (chnl > 14) {
3617                for (place = 14; place < sizeof(channel_all); place++)
3618                        if (channel_all[place] == chnl)
3619                                return place-13;
3620        }
3621
3622        return 0;
3623}
3624
3625#define MACBB_REG_NUM 10
3626#define AFE_REG_NUM 14
3627#define RF_REG_NUM 3
3628
3629static void _rtl8821ae_iqk_backup_macbb(struct ieee80211_hw *hw,
3630                                        u32 *macbb_backup,
3631                                        u32 *backup_macbb_reg, u32 mac_bb_num)
3632{
3633        struct rtl_priv *rtlpriv = rtl_priv(hw);
3634        u32 i;
3635
3636        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3637        /*save MACBB default value*/
3638        for (i = 0; i < mac_bb_num; i++)
3639                macbb_backup[i] = rtl_read_dword(rtlpriv, backup_macbb_reg[i]);
3640
3641        RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupMacBB Success!!!!\n");
3642}
3643
3644static void _rtl8821ae_iqk_backup_afe(struct ieee80211_hw *hw, u32 *afe_backup,
3645                                      u32 *backup_afe_REG, u32 afe_num)
3646{
3647        struct rtl_priv *rtlpriv = rtl_priv(hw);
3648        u32 i;
3649
3650        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3651        /*Save AFE Parameters */
3652        for (i = 0; i < afe_num; i++)
3653                afe_backup[i] = rtl_read_dword(rtlpriv, backup_afe_REG[i]);
3654        RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupAFE Success!!!!\n");
3655}
3656
3657static void _rtl8821ae_iqk_backup_rf(struct ieee80211_hw *hw, u32 *rfa_backup,
3658                                     u32 *rfb_backup, u32 *backup_rf_reg,
3659                                     u32 rf_num)
3660{
3661        struct rtl_priv *rtlpriv = rtl_priv(hw);
3662        u32 i;
3663
3664        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3665        /*Save RF Parameters*/
3666        for (i = 0; i < rf_num; i++) {
3667                rfa_backup[i] = rtl_get_rfreg(hw, RF90_PATH_A, backup_rf_reg[i],
3668                                              BMASKDWORD);
3669                rfb_backup[i] = rtl_get_rfreg(hw, RF90_PATH_B, backup_rf_reg[i],
3670                                              BMASKDWORD);
3671        }
3672        RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupRF Success!!!!\n");
3673}
3674
3675static void _rtl8821ae_iqk_configure_mac(
3676                struct ieee80211_hw *hw
3677                )
3678{
3679        struct rtl_priv *rtlpriv = rtl_priv(hw);
3680        /* ========MAC register setting========*/
3681        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3682        rtl_write_byte(rtlpriv, 0x522, 0x3f);
3683        rtl_set_bbreg(hw, 0x550, BIT(11) | BIT(3), 0x0);
3684        rtl_write_byte(rtlpriv, 0x808, 0x00);           /*RX ante off*/
3685        rtl_set_bbreg(hw, 0x838, 0xf, 0xc);             /*CCA off*/
3686}
3687
3688static void _rtl8821ae_iqk_tx_fill_iqc(struct ieee80211_hw *hw,
3689                                       enum radio_path path, u32 tx_x, u32 tx_y)
3690{
3691        struct rtl_priv *rtlpriv = rtl_priv(hw);
3692        switch (path) {
3693        case RF90_PATH_A:
3694                /* [31] = 1 --> Page C1 */
3695                rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1);
3696                rtl_write_dword(rtlpriv, 0xc90, 0x00000080);
3697                rtl_write_dword(rtlpriv, 0xcc4, 0x20040000);
3698                rtl_write_dword(rtlpriv, 0xcc8, 0x20000000);
3699                rtl_set_bbreg(hw, 0xccc, 0x000007ff, tx_y);
3700                rtl_set_bbreg(hw, 0xcd4, 0x000007ff, tx_x);
3701                RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3702                         "TX_X = %x;;TX_Y = %x =====> fill to IQC\n",
3703                         tx_x, tx_y);
3704                RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3705                         "0xcd4 = %x;;0xccc = %x ====>fill to IQC\n",
3706                         rtl_get_bbreg(hw, 0xcd4, 0x000007ff),
3707                         rtl_get_bbreg(hw, 0xccc, 0x000007ff));
3708                break;
3709        default:
3710                break;
3711        }
3712}
3713
3714static void _rtl8821ae_iqk_rx_fill_iqc(struct ieee80211_hw *hw,
3715                                       enum radio_path path, u32 rx_x, u32 rx_y)
3716{
3717        struct rtl_priv *rtlpriv = rtl_priv(hw);
3718        switch (path) {
3719        case RF90_PATH_A:
3720                rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3721                rtl_set_bbreg(hw, 0xc10, 0x000003ff, rx_x>>1);
3722                rtl_set_bbreg(hw, 0xc10, 0x03ff0000, rx_y>>1);
3723                RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3724                         "rx_x = %x;;rx_y = %x ====>fill to IQC\n",
3725                         rx_x>>1, rx_y>>1);
3726                RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3727                         "0xc10 = %x ====>fill to IQC\n",
3728                         rtl_read_dword(rtlpriv, 0xc10));
3729                break;
3730        default:
3731                break;
3732        }
3733}
3734
3735#define cal_num 10
3736
3737static void _rtl8821ae_iqk_tx(struct ieee80211_hw *hw, enum radio_path path)
3738{
3739        struct rtl_priv *rtlpriv = rtl_priv(hw);
3740        struct rtl_phy *rtlphy = &rtlpriv->phy;
3741        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3742
3743        u32     tx_fail, rx_fail, delay_count, iqk_ready, cal_retry, cal = 0, temp_reg65;
3744        int     tx_x = 0, tx_y = 0, rx_x = 0, rx_y = 0, tx_average = 0, rx_average = 0;
3745        int     tx_x0[cal_num], tx_y0[cal_num], tx_x0_rxk[cal_num],
3746                tx_y0_rxk[cal_num], rx_x0[cal_num], rx_y0[cal_num],
3747                tx_dt[cal_num], rx_dt[cal_num];
3748        bool    tx0iqkok = false, rx0iqkok = false;
3749        bool    vdf_enable = false;
3750        int     i, k, vdf_y[3], vdf_x[3],
3751                ii, dx = 0, dy = 0, tx_finish = 0, rx_finish = 0;
3752
3753        RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3754                        "BandWidth = %d.\n",
3755                         rtlphy->current_chan_bw);
3756        if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80)
3757                vdf_enable = true;
3758
3759        while (cal < cal_num) {
3760                switch (path) {
3761                case RF90_PATH_A:
3762                        temp_reg65 = rtl_get_rfreg(hw, path, 0x65, 0xffffffff);
3763                        /* Path-A LOK */
3764                        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3765                        /*========Path-A AFE all on========*/
3766                        /*Port 0 DAC/ADC on*/
3767                        rtl_write_dword(rtlpriv, 0xc60, 0x77777777);
3768                        rtl_write_dword(rtlpriv, 0xc64, 0x77777777);
3769                        rtl_write_dword(rtlpriv, 0xc68, 0x19791979);
3770                        rtl_write_dword(rtlpriv, 0xc6c, 0x19791979);
3771                        rtl_write_dword(rtlpriv, 0xc70, 0x19791979);
3772                        rtl_write_dword(rtlpriv, 0xc74, 0x19791979);
3773                        rtl_write_dword(rtlpriv, 0xc78, 0x19791979);
3774                        rtl_write_dword(rtlpriv, 0xc7c, 0x19791979);
3775                        rtl_write_dword(rtlpriv, 0xc80, 0x19791979);
3776                        rtl_write_dword(rtlpriv, 0xc84, 0x19791979);
3777
3778                        rtl_set_bbreg(hw, 0xc00, 0xf, 0x4); /*hardware 3-wire off*/
3779
3780                        /* LOK Setting */
3781                        /* ====== LOK ====== */
3782                        /*DAC/ADC sampling rate (160 MHz)*/
3783                        rtl_set_bbreg(hw, 0xc5c, BIT(26) | BIT(25) | BIT(24), 0x7);
3784
3785                        /* 2. LoK RF Setting (at BW = 20M) */
3786                        rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80002);
3787                        rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x3);     /* BW 20M */
3788                        rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x20000);
3789                        rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0003f);
3790                        rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xf3fc3);
3791                        rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d5);
3792                        rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
3793                        rtl_set_bbreg(hw, 0xcb8, 0xf, 0xd);
3794                        rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
3795                        rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
3796                        rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1);
3797                        rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
3798                        rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
3799                        rtl_write_dword(rtlpriv, 0x984, 0x00462910);/* [0]:AGC_en, [15]:idac_K_Mask */
3800
3801                        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3802                        rtl_write_dword(rtlpriv, 0xc88, 0x821403f4);
3803
3804                        if (rtlhal->current_bandtype)
3805                                rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96);
3806                        else
3807                                rtl_write_dword(rtlpriv, 0xc8c, 0x28163e96);
3808
3809                        rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3810                        rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3811                        rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8ϥ\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3812                        rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3813                        rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3814
3815                        mdelay(10); /* Delay 10ms */
3816                        rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
3817
3818                        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3819                        rtl_set_rfreg(hw, path, 0x58, 0x7fe00, rtl_get_rfreg(hw, path, 0x8, 0xffc00)); /* Load LOK */
3820
3821                        switch (rtlphy->current_chan_bw) {
3822                        case 1:
3823                                rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x1);
3824                                break;
3825                        case 2:
3826                                rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x0);
3827                                break;
3828                        default:
3829                                break;
3830                        }
3831
3832                        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3833
3834                        /* 3. TX RF Setting */
3835                        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3836                        rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
3837                        rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x20000);
3838                        rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0003f);
3839                        rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xf3fc3);
3840                        rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d5);
3841                        rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
3842                        rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
3843                        /* ODM_SetBBReg(pDM_Odm, 0xcb8, 0xf, 0xd); */
3844                        rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
3845                        rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
3846                        rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1);
3847                        rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
3848                        rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
3849                        rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
3850
3851                        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3852                        rtl_write_dword(rtlpriv, 0xc88, 0x821403f1);
3853                        if (rtlhal->current_bandtype)
3854                                rtl_write_dword(rtlpriv, 0xc8c, 0x40163e96);
3855                        else
3856                                rtl_write_dword(rtlpriv, 0xc8c, 0x00163e96);
3857
3858                        if (vdf_enable == 1) {
3859                                RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "VDF_enable\n");
3860                                for (k = 0; k <= 2; k++) {
3861                                        switch (k) {
3862                                        case 0:
3863                                                rtl_write_dword(rtlpriv, 0xc80, 0x18008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3864                                                rtl_write_dword(rtlpriv, 0xc84, 0x38008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3865                                                rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);
3866                                                break;
3867                                        case 1:
3868                                                rtl_set_bbreg(hw, 0xc80, BIT(28), 0x0);
3869                                                rtl_set_bbreg(hw, 0xc84, BIT(28), 0x0);
3870                                                rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);
3871                                                break;
3872                                        case 2:
3873                                                RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3874                                                        "vdf_y[1] = %x;;;vdf_y[0] = %x\n", vdf_y[1]>>21 & 0x00007ff, vdf_y[0]>>21 & 0x00007ff);
3875                                                RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3876                                                        "vdf_x[1] = %x;;;vdf_x[0] = %x\n", vdf_x[1]>>21 & 0x00007ff, vdf_x[0]>>21 & 0x00007ff);
3877                                                tx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20);
3878                                                tx_dt[cal] = ((16*tx_dt[cal])*10000/15708);
3879                                                tx_dt[cal] = (tx_dt[cal] >> 1)+(tx_dt[cal] & BIT(0));
3880                                                rtl_write_dword(rtlpriv, 0xc80, 0x18008c20);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3881                                                rtl_write_dword(rtlpriv, 0xc84, 0x38008c20);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3882                                                rtl_set_bbreg(hw, 0xce8, BIT(31), 0x1);
3883                                                rtl_set_bbreg(hw, 0xce8, 0x3fff0000, tx_dt[cal] & 0x00003fff);
3884                                                break;
3885                                        default:
3886                                                break;
3887                                        }
3888                                        rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8ϥ\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3889                                        cal_retry = 0;
3890                                        while (1) {
3891                                                /* one shot */
3892                                                rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3893                                                rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3894
3895                                                mdelay(10); /* Delay 10ms */
3896                                                rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
3897                                                delay_count = 0;
3898                                                while (1) {
3899                                                        iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
3900                                                        if ((~iqk_ready) || (delay_count > 20))
3901                                                                break;
3902                                                        else{
3903                                                                mdelay(1);
3904                                                                delay_count++;
3905                                                        }
3906                                                }
3907
3908                                                if (delay_count < 20) {                                                 /* If 20ms No Result, then cal_retry++ */
3909                                                        /* ============TXIQK Check============== */
3910                                                        tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
3911
3912                                                        if (~tx_fail) {
3913                                                                rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
3914                                                                vdf_x[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
3915                                                                rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
3916                                                                vdf_y[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
3917                                                                tx0iqkok = true;
3918                                                                break;
3919                                                        } else {
3920                                                                rtl_set_bbreg(hw, 0xccc, 0x000007ff, 0x0);
3921                                                                rtl_set_bbreg(hw, 0xcd4, 0x000007ff, 0x200);
3922                                                                tx0iqkok = false;
3923                                                                cal_retry++;
3924                                                                if (cal_retry == 10)
3925                                                                        break;
3926                                                        }
3927                                                } else {
3928                                                        tx0iqkok = false;
3929                                                        cal_retry++;
3930                                                        if (cal_retry == 10)
3931                                                                break;
3932                                                }
3933                                        }
3934                                }
3935                                if (k == 3) {
3936                                        tx_x0[cal] = vdf_x[k-1];
3937                                        tx_y0[cal] = vdf_y[k-1];
3938                                }
3939                        } else {
3940                                rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3941                                rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3942                                rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8ϥ\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3943                                cal_retry = 0;
3944                                while (1) {
3945                                        /* one shot */
3946                                        rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3947                                        rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3948
3949                                        mdelay(10); /* Delay 10ms */
3950                                        rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
3951                                        delay_count = 0;
3952                                        while (1) {
3953                                                iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
3954                                                if ((~iqk_ready) || (delay_count > 20))
3955                                                        break;
3956                                                else{
3957                                                        mdelay(1);
3958                                                        delay_count++;
3959                                                }
3960                                        }
3961
3962                                        if (delay_count < 20) {                                                 /* If 20ms No Result, then cal_retry++ */
3963                                                /* ============TXIQK Check============== */
3964                                                tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
3965
3966                                                if (~tx_fail) {
3967                                                        rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
3968                                                        tx_x0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
3969                                                        rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
3970                                                        tx_y0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
3971                                                        tx0iqkok = true;
3972                                                        break;
3973                                                } else {
3974                                                        rtl_set_bbreg(hw, 0xccc, 0x000007ff, 0x0);
3975                                                        rtl_set_bbreg(hw, 0xcd4, 0x000007ff, 0x200);
3976                                                        tx0iqkok = false;
3977                                                        cal_retry++;
3978                                                        if (cal_retry == 10)
3979                                                                break;
3980                                                }
3981                                        } else {
3982                                                tx0iqkok = false;
3983                                                cal_retry++;
3984                                                if (cal_retry == 10)
3985                                                        break;
3986                                        }
3987                                }
3988                        }
3989
3990                        if (tx0iqkok == false)
3991                                break;                          /* TXK fail, Don't do RXK */
3992
3993                        if (vdf_enable == 1) {
3994                                rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);    /* TX VDF Disable */
3995                                RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RXVDF Start\n");
3996                                for (k = 0; k <= 2; k++) {
3997                                        /* ====== RX mode TXK (RXK Step 1) ====== */
3998                                        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3999                                        /* 1. TX RF Setting */
4000                                        rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4001                                        rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4002                                        rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x00029);
4003                                        rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xd7ffb);
4004                                        rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4005                                        rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
4006                                        rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4007
4008                                        rtl_set_bbreg(hw, 0xcb8, 0xf, 0xd);
4009                                        rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
4010                                        rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
4011                                        rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
4012                                        rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4013                                        rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
4014                                        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4015                                        switch (k) {
4016                                        case 0:
4017                                                {
4018                                                        rtl_write_dword(rtlpriv, 0xc80, 0x18008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4019                                                        rtl_write_dword(rtlpriv, 0xc84, 0x38008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4020                                                        rtl_set_bbreg(hw, 0xce8, BIT(30), 0x0);
4021                                                }
4022                                                break;
4023                                        case 1:
4024                                                {
4025                                                        rtl_write_dword(rtlpriv, 0xc80, 0x08008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4026                                                        rtl_write_dword(rtlpriv, 0xc84, 0x28008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4027                                                        rtl_set_bbreg(hw, 0xce8, BIT(30), 0x0);
4028                                                }
4029                                                break;
4030                                        case 2:
4031                                                {
4032                                                        RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4033                                                        "VDF_Y[1] = %x;;;VDF_Y[0] = %x\n",
4034                                                        vdf_y[1]>>21 & 0x00007ff, vdf_y[0]>>21 & 0x00007ff);
4035                                                        RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4036                                                        "VDF_X[1] = %x;;;VDF_X[0] = %x\n",
4037                                                        vdf_x[1]>>21 & 0x00007ff, vdf_x[0]>>21 & 0x00007ff);
4038                                                        rx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20);
4039                                                        RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "Rx_dt = %d\n", rx_dt[cal]);
4040                                                        rx_dt[cal] = ((16*rx_dt[cal])*10000/13823);
4041                                                        rx_dt[cal] = (rx_dt[cal] >> 1)+(rx_dt[cal] & BIT(0));
4042                                                        rtl_write_dword(rtlpriv, 0xc80, 0x18008c20);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4043                                                        rtl_write_dword(rtlpriv, 0xc84, 0x38008c20);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4044                                                        rtl_set_bbreg(hw, 0xce8, 0x00003fff, rx_dt[cal] & 0x00003fff);
4045                                                }
4046                                                break;
4047                                        default:
4048                                                break;
4049                                        }
4050                                        rtl_write_dword(rtlpriv, 0xc88, 0x821603e0);
4051                                        rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96);
4052                                        rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8ϥ\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4053                                        cal_retry = 0;
4054                                        while (1) {
4055                                                /* one shot */
4056                                                rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4057                                                rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4058
4059                                                mdelay(10); /* Delay 10ms */
4060                                                rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4061                                                delay_count = 0;
4062                                                while (1) {
4063                                                        iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4064                                                        if ((~iqk_ready) || (delay_count > 20))
4065                                                                break;
4066                                                        else{
4067                                                                mdelay(1);
4068                                                                delay_count++;
4069                                                        }
4070                                                }
4071
4072                                                if (delay_count < 20) {                                                 /* If 20ms No Result, then cal_retry++ */
4073                                                        /* ============TXIQK Check============== */
4074                                                        tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4075
4076                                                        if (~tx_fail) {
4077                                                                rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4078                                                                tx_x0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4079                                                                rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4080                                                                tx_y0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4081                                                                tx0iqkok = true;
4082                                                                break;
4083                                                        } else{
4084                                                                tx0iqkok = false;
4085                                                                cal_retry++;
4086                                                                if (cal_retry == 10)
4087                                                                        break;
4088                                                        }
4089                                                } else {
4090                                                        tx0iqkok = false;
4091                                                        cal_retry++;
4092                                                        if (cal_retry == 10)
4093                                                                break;
4094                                                }
4095                                        }
4096
4097                                        if (tx0iqkok == false) {   /* If RX mode TXK fail, then take TXK Result */
4098                                                tx_x0_rxk[cal] = tx_x0[cal];
4099                                                tx_y0_rxk[cal] = tx_y0[cal];
4100                                                tx0iqkok = true;
4101                                                RT_TRACE(rtlpriv,
4102                                                         COMP_IQK,
4103                                                         DBG_LOUD,
4104                                                         "RXK Step 1 fail\n");
4105                                        }
4106
4107                                        /* ====== RX IQK ====== */
4108                                        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4109                                        /* 1. RX RF Setting */
4110                                        rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4111                                        rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4112                                        rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0002f);
4113                                        rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xfffbb);
4114                                        rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x88001);
4115                                        rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d8);
4116                                        rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4117
4118                                        rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0_rxk[cal])>>21&0x000007ff);
4119                                        rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0_rxk[cal])>>21&0x000007ff);
4120                                        rtl_set_bbreg(hw, 0x978, BIT(31), 0x1);
4121                                        rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0);
4122                                        rtl_set_bbreg(hw, 0xcb8, 0xF, 0xe);
4123                                        rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4124                                        rtl_write_dword(rtlpriv, 0x984, 0x0046a911);
4125
4126                                        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4127                                        rtl_set_bbreg(hw, 0xc80, BIT(29), 0x1);
4128                                        rtl_set_bbreg(hw, 0xc84, BIT(29), 0x0);
4129                                        rtl_write_dword(rtlpriv, 0xc88, 0x02140119);
4130
4131                                        rtl_write_dword(rtlpriv, 0xc8c, 0x28160d00); /* pDM_Odm->SupportInterface == 1 */
4132
4133                                        if (k == 2)
4134                                                rtl_set_bbreg(hw, 0xce8, BIT(30), 0x1);  /* RX VDF Enable */
4135                                        rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8ϥ\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4136
4137                                        cal_retry = 0;
4138                                        while (1) {
4139                                                /* one shot */
4140                                                rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4141                                                rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4142
4143                                                mdelay(10); /* Delay 10ms */
4144                                                rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4145                                                delay_count = 0;
4146                                                while (1) {
4147                                                        iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4148                                                        if ((~iqk_ready) || (delay_count > 20))
4149                                                                break;
4150                                                        else{
4151                                                                mdelay(1);
4152                                                                delay_count++;
4153                                                        }
4154                                                }
4155
4156                                                if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4157                                                        /* ============RXIQK Check============== */
4158                                                        rx_fail = rtl_get_bbreg(hw, 0xd00, BIT(11));
4159                                                        if (rx_fail == 0) {
4160                                                                rtl_write_dword(rtlpriv, 0xcb8, 0x06000000);
4161                                                                vdf_x[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4162                                                                rtl_write_dword(rtlpriv, 0xcb8, 0x08000000);
4163                                                                vdf_y[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4164                                                                rx0iqkok = true;
4165                                                                break;
4166                                                        } else {
4167                                                                rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x200>>1);
4168                                                                rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0x0>>1);
4169                                                                rx0iqkok = false;
4170                                                                cal_retry++;
4171                                                                if (cal_retry == 10)
4172                                                                        break;
4173
4174                                                        }
4175                                                } else{
4176                                                        rx0iqkok = false;
4177                                                        cal_retry++;
4178                                                        if (cal_retry == 10)
4179                                                                break;
4180                                                }
4181                                        }
4182
4183                                }
4184                                if (k == 3) {
4185                                        rx_x0[cal] = vdf_x[k-1];
4186                                        rx_y0[cal] = vdf_y[k-1];
4187                                }
4188                                rtl_set_bbreg(hw, 0xce8, BIT(31), 0x1);    /* TX VDF Enable */
4189                        }
4190
4191                        else{
4192                                /* ====== RX mode TXK (RXK Step 1) ====== */
4193                                rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4194                                /* 1. TX RF Setting */
4195                                rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4196                                rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4197                                rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x00029);
4198                                rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xd7ffb);
4199                                rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4200                                rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
4201                                rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4202                                rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4203                                rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
4204                                rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
4205
4206                                rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4207                                rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4208                                rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4209                                rtl_write_dword(rtlpriv, 0xc88, 0x821603e0);
4210                                /* ODM_Write4Byte(pDM_Odm, 0xc8c, 0x68163e96); */
4211                                rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8ϥ\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4212                                cal_retry = 0;
4213                                while (1) {
4214                                        /* one shot */
4215                                        rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4216                                        rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4217
4218                                        mdelay(10); /* Delay 10ms */
4219                                        rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4220                                        delay_count = 0;
4221                                        while (1) {
4222                                                iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4223                                                if ((~iqk_ready) || (delay_count > 20))
4224                                                        break;
4225                                                else{
4226                                                        mdelay(1);
4227                                                        delay_count++;
4228                                                }
4229                                        }
4230
4231                                        if (delay_count < 20) {                                                 /* If 20ms No Result, then cal_retry++ */
4232                                                /* ============TXIQK Check============== */
4233                                                tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4234
4235                                                if (~tx_fail) {
4236                                                        rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4237                                                        tx_x0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4238                                                        rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4239                                                        tx_y0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4240                                                        tx0iqkok = true;
4241                                                        break;
4242                                                } else {
4243                                                        tx0iqkok = false;
4244                                                        cal_retry++;
4245                                                        if (cal_retry == 10)
4246                                                                break;
4247                                                }
4248                                        } else{
4249                                                tx0iqkok = false;
4250                                                cal_retry++;
4251                                                if (cal_retry == 10)
4252                                                        break;
4253                                        }
4254                                }
4255
4256                                if (tx0iqkok == false) {   /* If RX mode TXK fail, then take TXK Result */
4257                                        tx_x0_rxk[cal] = tx_x0[cal];
4258                                        tx_y0_rxk[cal] = tx_y0[cal];
4259                                        tx0iqkok = true;
4260                                        RT_TRACE(rtlpriv, COMP_IQK,
4261                                                 DBG_LOUD, "1");
4262                                }
4263
4264                                /* ====== RX IQK ====== */
4265                                rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4266                                /* 1. RX RF Setting */
4267                                rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4268                                rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4269                                rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0002f);
4270                                rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xfffbb);
4271                                rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x88001);
4272                                rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d8);
4273                                rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4274
4275                                rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0_rxk[cal])>>21&0x000007ff);
4276                                rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0_rxk[cal])>>21&0x000007ff);
4277                                rtl_set_bbreg(hw, 0x978, BIT(31), 0x1);
4278                                rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0);
4279                                /* ODM_SetBBReg(pDM_Odm, 0xcb8, 0xF, 0xe); */
4280                                rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4281                                rtl_write_dword(rtlpriv, 0x984, 0x0046a911);
4282
4283                                rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4284                                rtl_write_dword(rtlpriv, 0xc80, 0x38008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4285                                rtl_write_dword(rtlpriv, 0xc84, 0x18008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4286                                rtl_write_dword(rtlpriv, 0xc88, 0x02140119);
4287
4288                                rtl_write_dword(rtlpriv, 0xc8c, 0x28160d00); /*pDM_Odm->SupportInterface == 1*/
4289
4290                                rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8ϥ\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4291
4292                                cal_retry = 0;
4293                                while (1) {
4294                                        /* one shot */
4295                                        rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4296                                        rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4297
4298                                        mdelay(10); /* Delay 10ms */
4299                                        rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4300                                        delay_count = 0;
4301                                        while (1) {
4302                                                iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4303                                                if ((~iqk_ready) || (delay_count > 20))
4304                                                        break;
4305                                                else{
4306                                                        mdelay(1);
4307                                                        delay_count++;
4308                                                }
4309                                        }
4310
4311                                        if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4312                                                /* ============RXIQK Check============== */
4313                                                rx_fail = rtl_get_bbreg(hw, 0xd00, BIT(11));
4314                                                if (rx_fail == 0) {
4315                                                        rtl_write_dword(rtlpriv, 0xcb8, 0x06000000);
4316                                                        rx_x0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4317                                                        rtl_write_dword(rtlpriv, 0xcb8, 0x08000000);
4318                                                        rx_y0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4319                                                        rx0iqkok = true;
4320                                                        break;
4321                                                } else{
4322                                                        rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x200>>1);
4323                                                        rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0x0>>1);
4324                                                        rx0iqkok = false;
4325                                                        cal_retry++;
4326                                                        if (cal_retry == 10)
4327                                                                break;
4328
4329                                                }
4330                                        } else{
4331                                                rx0iqkok = false;
4332                                                cal_retry++;
4333                                                if (cal_retry == 10)
4334                                                        break;
4335                                        }
4336                                }
4337                        }
4338
4339                        if (tx0iqkok)
4340                                tx_average++;
4341                        if (rx0iqkok)
4342                                rx_average++;
4343                        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4344                        rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4345                        break;
4346                default:
4347                        break;
4348                }
4349                cal++;
4350        }
4351
4352        /* FillIQK Result */
4353        switch (path) {
4354        case RF90_PATH_A:
4355                RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4356                         "========Path_A =======\n");
4357                if (tx_average == 0)
4358                        break;
4359
4360                for (i = 0; i < tx_average; i++) {
4361                        RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4362                                 "TX_X0_RXK[%d] = %x ;; TX_Y0_RXK[%d] = %x\n", i,
4363                                 (tx_x0_rxk[i])>>21&0x000007ff, i,
4364                                 (tx_y0_rxk[i])>>21&0x000007ff);
4365                        RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4366                                 "TX_X0[%d] = %x ;; TX_Y0[%d] = %x\n", i,
4367                                 (tx_x0[i])>>21&0x000007ff, i,
4368                                 (tx_y0[i])>>21&0x000007ff);
4369                }
4370                for (i = 0; i < tx_average; i++) {
4371                        for (ii = i+1; ii < tx_average; ii++) {
4372                                dx = (tx_x0[i]>>21) - (tx_x0[ii]>>21);
4373                                if (dx < 3 && dx > -3) {
4374                                        dy = (tx_y0[i]>>21) - (tx_y0[ii]>>21);
4375                                        if (dy < 3 && dy > -3) {
4376                                                tx_x = ((tx_x0[i]>>21) + (tx_x0[ii]>>21))/2;
4377                                                tx_y = ((tx_y0[i]>>21) + (tx_y0[ii]>>21))/2;
4378                                                tx_finish = 1;
4379                                                break;
4380                                        }
4381                                }
4382                        }
4383                        if (tx_finish == 1)
4384                                break;
4385                }
4386
4387                if (tx_finish == 1)
4388                        _rtl8821ae_iqk_tx_fill_iqc(hw, path, tx_x, tx_y); /* ? */
4389                else
4390                        _rtl8821ae_iqk_tx_fill_iqc(hw, path, 0x200, 0x0);
4391
4392                if (rx_average == 0)
4393                        break;
4394
4395                for (i = 0; i < rx_average; i++)
4396                        RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4397                                "RX_X0[%d] = %x ;; RX_Y0[%d] = %x\n", i,
4398                                (rx_x0[i])>>21&0x000007ff, i,
4399                                (rx_y0[i])>>21&0x000007ff);
4400                for (i = 0; i < rx_average; i++) {
4401                        for (ii = i+1; ii < rx_average; ii++) {
4402                                dx = (rx_x0[i]>>21) - (rx_x0[ii]>>21);
4403                                if (dx < 4 && dx > -4) {
4404                                        dy = (rx_y0[i]>>21) - (rx_y0[ii]>>21);
4405                                        if (dy < 4 && dy > -4) {
4406                                                rx_x = ((rx_x0[i]>>21) + (rx_x0[ii]>>21))/2;
4407                                                rx_y = ((rx_y0[i]>>21) + (rx_y0[ii]>>21))/2;
4408                                                rx_finish = 1;
4409                                                break;
4410                                        }
4411                                }
4412                        }
4413                        if (rx_finish == 1)
4414                                break;
4415                }
4416
4417                if (rx_finish == 1)
4418                        _rtl8821ae_iqk_rx_fill_iqc(hw, path, rx_x, rx_y);
4419                else
4420                        _rtl8821ae_iqk_rx_fill_iqc(hw, path, 0x200, 0x0);
4421                break;
4422        default:
4423                break;
4424        }
4425}
4426
4427static void _rtl8821ae_iqk_restore_rf(struct ieee80211_hw *hw,
4428                                      enum radio_path path,
4429                                      u32 *backup_rf_reg,
4430                                      u32 *rf_backup, u32 rf_reg_num)
4431{
4432        struct rtl_priv *rtlpriv = rtl_priv(hw);
4433        u32 i;
4434
4435        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4436        for (i = 0; i < RF_REG_NUM; i++)
4437                rtl_set_rfreg(hw, path, backup_rf_reg[i], RFREG_OFFSET_MASK,
4438                              rf_backup[i]);
4439
4440        switch (path) {
4441        case RF90_PATH_A:
4442                RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4443                         "RestoreRF Path A Success!!!!\n");
4444                break;
4445        default:
4446                        break;
4447        }
4448}
4449
4450static void _rtl8821ae_iqk_restore_afe(struct ieee80211_hw *hw,
4451                                       u32 *afe_backup, u32 *backup_afe_reg,
4452                                       u32 afe_num)
4453{
4454        u32 i;
4455        struct rtl_priv *rtlpriv = rtl_priv(hw);
4456
4457        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4458        /* Reload AFE Parameters */
4459        for (i = 0; i < afe_num; i++)
4460                rtl_write_dword(rtlpriv, backup_afe_reg[i], afe_backup[i]);
4461        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4462        rtl_write_dword(rtlpriv, 0xc80, 0x0);
4463        rtl_write_dword(rtlpriv, 0xc84, 0x0);
4464        rtl_write_dword(rtlpriv, 0xc88, 0x0);
4465        rtl_write_dword(rtlpriv, 0xc8c, 0x3c000000);
4466        rtl_write_dword(rtlpriv, 0xc90, 0x00000080);
4467        rtl_write_dword(rtlpriv, 0xc94, 0x00000000);
4468        rtl_write_dword(rtlpriv, 0xcc4, 0x20040000);
4469        rtl_write_dword(rtlpriv, 0xcc8, 0x20000000);
4470        rtl_write_dword(rtlpriv, 0xcb8, 0x0);
4471        RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RestoreAFE Success!!!!\n");
4472}
4473
4474static void _rtl8821ae_iqk_restore_macbb(struct ieee80211_hw *hw,
4475                                         u32 *macbb_backup,
4476                                         u32 *backup_macbb_reg,
4477                                         u32 macbb_num)
4478{
4479        u32 i;
4480        struct rtl_priv *rtlpriv = rtl_priv(hw);
4481
4482        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4483        /* Reload MacBB Parameters */
4484        for (i = 0; i < macbb_num; i++)
4485                rtl_write_dword(rtlpriv, backup_macbb_reg[i], macbb_backup[i]);
4486        RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RestoreMacBB Success!!!!\n");
4487}
4488
4489#undef MACBB_REG_NUM
4490#undef AFE_REG_NUM
4491#undef RF_REG_NUM
4492
4493#define MACBB_REG_NUM 11
4494#define AFE_REG_NUM 12
4495#define RF_REG_NUM 3
4496
4497static void _rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw)
4498{
4499        u32     macbb_backup[MACBB_REG_NUM];
4500        u32 afe_backup[AFE_REG_NUM];
4501        u32 rfa_backup[RF_REG_NUM];
4502        u32 rfb_backup[RF_REG_NUM];
4503        u32 backup_macbb_reg[MACBB_REG_NUM] = {
4504                0xb00, 0x520, 0x550, 0x808, 0x90c, 0xc00, 0xc50,
4505                0xe00, 0xe50, 0x838, 0x82c
4506        };
4507        u32 backup_afe_reg[AFE_REG_NUM] = {
4508                0xc5c, 0xc60, 0xc64, 0xc68, 0xc6c, 0xc70, 0xc74,
4509                0xc78, 0xc7c, 0xc80, 0xc84, 0xcb8
4510        };
4511        u32     backup_rf_reg[RF_REG_NUM] = {0x65, 0x8f, 0x0};
4512
4513        _rtl8821ae_iqk_backup_macbb(hw, macbb_backup, backup_macbb_reg,
4514                                    MACBB_REG_NUM);
4515        _rtl8821ae_iqk_backup_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM);
4516        _rtl8821ae_iqk_backup_rf(hw, rfa_backup, rfb_backup, backup_rf_reg,
4517                                 RF_REG_NUM);
4518
4519        _rtl8821ae_iqk_configure_mac(hw);
4520        _rtl8821ae_iqk_tx(hw, RF90_PATH_A);
4521        _rtl8821ae_iqk_restore_rf(hw, RF90_PATH_A, backup_rf_reg, rfa_backup,
4522                                  RF_REG_NUM);
4523
4524        _rtl8821ae_iqk_restore_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM);
4525        _rtl8821ae_iqk_restore_macbb(hw, macbb_backup, backup_macbb_reg,
4526                                     MACBB_REG_NUM);
4527}
4528
4529static void _rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool main)
4530{
4531        struct rtl_priv *rtlpriv = rtl_priv(hw);
4532        /* struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); */
4533        /* struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); */
4534        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
4535
4536        if (main)
4537                rtl_set_bbreg(hw, RA_RFE_PINMUX + 4, BIT(29) | BIT(28), 0x1);
4538        else
4539                rtl_set_bbreg(hw, RA_RFE_PINMUX + 4, BIT(29) | BIT(28), 0x2);
4540}
4541
4542#undef IQK_ADDA_REG_NUM
4543#undef IQK_DELAY_TIME
4544
4545void rtl8812ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
4546{
4547}
4548
4549void rtl8812ae_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index,
4550                      u8 thermal_value, u8 threshold)
4551{
4552        struct rtl_dm   *rtldm = rtl_dm(rtl_priv(hw));
4553
4554        rtldm->thermalvalue_iqk = thermal_value;
4555        rtl8812ae_phy_iq_calibrate(hw, false);
4556}
4557
4558void rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
4559{
4560        struct rtl_priv *rtlpriv = rtl_priv(hw);
4561        struct rtl_phy *rtlphy = &rtlpriv->phy;
4562
4563        if (!rtlphy->lck_inprogress) {
4564                spin_lock(&rtlpriv->locks.iqk_lock);
4565                rtlphy->lck_inprogress = true;
4566                spin_unlock(&rtlpriv->locks.iqk_lock);
4567
4568                _rtl8821ae_phy_iq_calibrate(hw);
4569
4570                spin_lock(&rtlpriv->locks.iqk_lock);
4571                rtlphy->lck_inprogress = false;
4572                spin_unlock(&rtlpriv->locks.iqk_lock);
4573        }
4574}
4575
4576void rtl8821ae_reset_iqk_result(struct ieee80211_hw *hw)
4577{
4578        struct rtl_priv *rtlpriv = rtl_priv(hw);
4579        struct rtl_phy *rtlphy = &rtlpriv->phy;
4580        u8 i;
4581
4582        RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4583                 "rtl8812ae_dm_reset_iqk_result:: settings regs %d default regs %d\n",
4584                 (int)(sizeof(rtlphy->iqk_matrix) /
4585                 sizeof(struct iqk_matrix_regs)),
4586                 IQK_MATRIX_SETTINGS_NUM);
4587
4588        for (i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) {
4589                rtlphy->iqk_matrix[i].value[0][0] = 0x100;
4590                rtlphy->iqk_matrix[i].value[0][2] = 0x100;
4591                rtlphy->iqk_matrix[i].value[0][4] = 0x100;
4592                rtlphy->iqk_matrix[i].value[0][6] = 0x100;
4593
4594                rtlphy->iqk_matrix[i].value[0][1] = 0x0;
4595                rtlphy->iqk_matrix[i].value[0][3] = 0x0;
4596                rtlphy->iqk_matrix[i].value[0][5] = 0x0;
4597                rtlphy->iqk_matrix[i].value[0][7] = 0x0;
4598
4599                rtlphy->iqk_matrix[i].iqk_done = false;
4600        }
4601}
4602
4603void rtl8821ae_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index,
4604                      u8 thermal_value, u8 threshold)
4605{
4606        struct rtl_dm   *rtldm = rtl_dm(rtl_priv(hw));
4607
4608        rtl8821ae_reset_iqk_result(hw);
4609
4610        rtldm->thermalvalue_iqk = thermal_value;
4611        rtl8821ae_phy_iq_calibrate(hw, false);
4612}
4613
4614void rtl8821ae_phy_lc_calibrate(struct ieee80211_hw *hw)
4615{
4616}
4617
4618void rtl8821ae_phy_ap_calibrate(struct ieee80211_hw *hw, s8 delta)
4619{
4620}
4621
4622void rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
4623{
4624        _rtl8821ae_phy_set_rfpath_switch(hw, bmain);
4625}
4626
4627bool rtl8821ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
4628{
4629        struct rtl_priv *rtlpriv = rtl_priv(hw);
4630        struct rtl_phy *rtlphy = &rtlpriv->phy;
4631        bool postprocessing = false;
4632
4633        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4634                 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
4635                  iotype, rtlphy->set_io_inprogress);
4636        do {
4637                switch (iotype) {
4638                case IO_CMD_RESUME_DM_BY_SCAN:
4639                        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4640                                 "[IO CMD] Resume DM after scan.\n");
4641                        postprocessing = true;
4642                        break;
4643                case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
4644                case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
4645                        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4646                                 "[IO CMD] Pause DM before scan.\n");
4647                        postprocessing = true;
4648                        break;
4649                default:
4650                        pr_err("switch case %#x not processed\n",
4651                               iotype);
4652                        break;
4653                }
4654        } while (false);
4655        if (postprocessing && !rtlphy->set_io_inprogress) {
4656                rtlphy->set_io_inprogress = true;
4657                rtlphy->current_io_type = iotype;
4658        } else {
4659                return false;
4660        }
4661        rtl8821ae_phy_set_io(hw);
4662        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
4663        return true;
4664}
4665
4666static void rtl8821ae_phy_set_io(struct ieee80211_hw *hw)
4667{
4668        struct rtl_priv *rtlpriv = rtl_priv(hw);
4669        struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
4670        struct rtl_phy *rtlphy = &rtlpriv->phy;
4671
4672        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4673                 "--->Cmd(%#x), set_io_inprogress(%d)\n",
4674                  rtlphy->current_io_type, rtlphy->set_io_inprogress);
4675        switch (rtlphy->current_io_type) {
4676        case IO_CMD_RESUME_DM_BY_SCAN:
4677                if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
4678                        _rtl8821ae_resume_tx_beacon(hw);
4679                rtl8821ae_dm_write_dig(hw, rtlphy->initgain_backup.xaagccore1);
4680                rtl8821ae_dm_write_cck_cca_thres(hw,
4681                                                 rtlphy->initgain_backup.cca);
4682                break;
4683        case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
4684                if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
4685                        _rtl8821ae_stop_tx_beacon(hw);
4686                rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
4687                rtl8821ae_dm_write_dig(hw, 0x17);
4688                rtlphy->initgain_backup.cca = dm_digtable->cur_cck_cca_thres;
4689                rtl8821ae_dm_write_cck_cca_thres(hw, 0x40);
4690                break;
4691        case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
4692                break;
4693        default:
4694                pr_err("switch case %#x not processed\n",
4695                       rtlphy->current_io_type);
4696                break;
4697        }
4698        rtlphy->set_io_inprogress = false;
4699        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4700                 "(%#x)\n", rtlphy->current_io_type);
4701}
4702
4703static void rtl8821ae_phy_set_rf_on(struct ieee80211_hw *hw)
4704{
4705        struct rtl_priv *rtlpriv = rtl_priv(hw);
4706
4707        rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
4708        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
4709        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
4710        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
4711        rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
4712}
4713
4714static bool _rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
4715                                              enum rf_pwrstate rfpwr_state)
4716{
4717        struct rtl_priv *rtlpriv = rtl_priv(hw);
4718        struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
4719        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
4720        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
4721        bool bresult = true;
4722        u8 i, queue_id;
4723        struct rtl8192_tx_ring *ring = NULL;
4724
4725        switch (rfpwr_state) {
4726        case ERFON:
4727                if ((ppsc->rfpwr_state == ERFOFF) &&
4728                    RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
4729                        bool rtstatus = false;
4730                        u32 initializecount = 0;
4731
4732                        do {
4733                                initializecount++;
4734                                RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4735                                         "IPS Set eRf nic enable\n");
4736                                rtstatus = rtl_ps_enable_nic(hw);
4737                        } while (!rtstatus && (initializecount < 10));
4738                        RT_CLEAR_PS_LEVEL(ppsc,
4739                                          RT_RF_OFF_LEVL_HALT_NIC);
4740                } else {
4741                        RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4742                                 "Set ERFON sleeped:%d ms\n",
4743                                  jiffies_to_msecs(jiffies -
4744                                                   ppsc->
4745                                                   last_sleep_jiffies));
4746                        ppsc->last_awake_jiffies = jiffies;
4747                        rtl8821ae_phy_set_rf_on(hw);
4748                }
4749                if (mac->link_state == MAC80211_LINKED) {
4750                        rtlpriv->cfg->ops->led_control(hw,
4751                                                       LED_CTL_LINK);
4752                } else {
4753                        rtlpriv->cfg->ops->led_control(hw,
4754                                                       LED_CTL_NO_LINK);
4755                }
4756                break;
4757        case ERFOFF:
4758                for (queue_id = 0, i = 0;
4759                     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
4760                        ring = &pcipriv->dev.tx_ring[queue_id];
4761                        if (queue_id == BEACON_QUEUE ||
4762                            skb_queue_len(&ring->queue) == 0) {
4763                                queue_id++;
4764                                continue;
4765                        } else {
4766                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
4767                                         "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
4768                                         (i + 1), queue_id,
4769                                         skb_queue_len(&ring->queue));
4770
4771                                udelay(10);
4772                                i++;
4773                        }
4774                        if (i >= MAX_DOZE_WAITING_TIMES_9x) {
4775                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
4776                                         "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
4777                                          MAX_DOZE_WAITING_TIMES_9x,
4778                                          queue_id,
4779                                          skb_queue_len(&ring->queue));
4780                                break;
4781                        }
4782                }
4783
4784                if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
4785                        RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4786                                 "IPS Set eRf nic disable\n");
4787                        rtl_ps_disable_nic(hw);
4788                        RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
4789                } else {
4790                        if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
4791                                rtlpriv->cfg->ops->led_control(hw,
4792                                                               LED_CTL_NO_LINK);
4793                        } else {
4794                                rtlpriv->cfg->ops->led_control(hw,
4795                                                               LED_CTL_POWER_OFF);
4796                        }
4797                }
4798                break;
4799        default:
4800                pr_err("switch case %#x not processed\n",
4801                       rfpwr_state);
4802                bresult = false;
4803                break;
4804        }
4805        if (bresult)
4806                ppsc->rfpwr_state = rfpwr_state;
4807        return bresult;
4808}
4809
4810bool rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
4811                                      enum rf_pwrstate rfpwr_state)
4812{
4813        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
4814
4815        bool bresult = false;
4816
4817        if (rfpwr_state == ppsc->rfpwr_state)
4818                return bresult;
4819        bresult = _rtl8821ae_phy_set_rf_power_state(hw, rfpwr_state);
4820        return bresult;
4821}
4822