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