root/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rtl8812ae_fixspur
  2. rtl8821ae_phy_query_bb_reg
  3. rtl8821ae_phy_set_bb_reg
  4. rtl8821ae_phy_query_rf_reg
  5. rtl8821ae_phy_set_rf_reg
  6. _rtl8821ae_phy_rf_serial_read
  7. _rtl8821ae_phy_rf_serial_write
  8. _rtl8821ae_phy_calculate_bit_shift
  9. rtl8821ae_phy_mac_config
  10. rtl8821ae_phy_bb_config
  11. rtl8821ae_phy_rf_config
  12. _rtl8812ae_phy_set_rfe_reg_24g
  13. _rtl8812ae_phy_set_rfe_reg_5g
  14. phy_get_tx_swing_8812A
  15. rtl8821ae_phy_switch_wirelessband
  16. _rtl8821ae_check_positive
  17. _rtl8821ae_check_condition
  18. _rtl8821ae_config_rf_reg
  19. _rtl8821ae_config_rf_radio_a
  20. _rtl8821ae_config_rf_radio_b
  21. _rtl8821ae_config_bb_reg
  22. _rtl8821ae_phy_init_tx_power_by_rate
  23. _rtl8821ae_phy_set_txpower_by_rate_base
  24. _rtl8821ae_phy_get_txpower_by_rate_base
  25. _rtl8821ae_phy_store_txpower_by_rate_base
  26. _phy_convert_txpower_dbm_to_relative_value
  27. _rtl8812ae_phy_cross_reference_ht_and_vht_txpower_limit
  28. _rtl8812ae_phy_get_txpower_by_rate_base_index
  29. _rtl8812ae_phy_convert_txpower_limit_to_power_index
  30. _rtl8821ae_phy_init_txpower_limit
  31. _rtl8821ae_phy_convert_txpower_dbm_to_relative_value
  32. _rtl8821ae_phy_txpower_by_rate_configuration
  33. _rtl8812ae_get_integer_from_string
  34. _rtl8812ae_eq_n_byte
  35. _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt
  36. _rtl8812ae_phy_set_txpower_limit
  37. _rtl8812ae_phy_config_bb_txpwr_lmt
  38. _rtl8821ae_phy_read_and_config_txpwr_lmt
  39. _rtl8821ae_phy_bb8821a_config_parafile
  40. __rtl8821ae_phy_config_with_headerfile
  41. _rtl8821ae_phy_config_mac_with_headerfile
  42. _rtl8821ae_phy_config_bb_with_headerfile
  43. _rtl8821ae_get_rate_section_index
  44. _rtl8821ae_store_tx_power_by_rate
  45. _rtl8821ae_phy_config_bb_with_pgheaderfile
  46. rtl8812ae_phy_config_rf_with_headerfile
  47. rtl8821ae_phy_config_rf_with_headerfile
  48. rtl8821ae_phy_get_hw_reg_originalvalue
  49. phy_init_bb_rf_register_definition
  50. rtl8821ae_phy_get_txpower_level
  51. _rtl8821ae_phy_get_chnl_index
  52. _rtl8821ae_phy_get_ratesection_intxpower_byrate
  53. _rtl8812ae_phy_get_world_wide_limit
  54. _rtl8812ae_phy_get_txpower_limit
  55. _rtl8821ae_phy_get_txpower_by_rate
  56. _rtl8821ae_get_txpower_index
  57. _rtl8821ae_phy_set_txpower_index
  58. _rtl8821ae_phy_set_txpower_level_by_path
  59. _rtl8821ae_phy_txpower_training_by_path
  60. rtl8821ae_phy_set_txpower_level_by_path
  61. rtl8821ae_phy_set_txpower_level
  62. _rtl8821ae_phy_txpwr_idx_to_dbm
  63. rtl8821ae_phy_scan_operation_backup
  64. _rtl8821ae_phy_set_reg_bw
  65. _rtl8821ae_phy_get_secondary_chnl
  66. rtl8821ae_phy_set_bw_mode_callback
  67. rtl8821ae_phy_set_bw_mode
  68. rtl8821ae_phy_sw_chnl_callback
  69. rtl8821ae_phy_sw_chnl
  70. _rtl8812ae_get_right_chnl_place_for_iqk
  71. _rtl8821ae_iqk_backup_macbb
  72. _rtl8821ae_iqk_backup_afe
  73. _rtl8821ae_iqk_backup_rf
  74. _rtl8821ae_iqk_configure_mac
  75. _rtl8821ae_iqk_tx_fill_iqc
  76. _rtl8821ae_iqk_rx_fill_iqc
  77. _rtl8821ae_iqk_tx
  78. _rtl8821ae_iqk_restore_rf
  79. _rtl8821ae_iqk_restore_afe
  80. _rtl8821ae_iqk_restore_macbb
  81. _rtl8821ae_phy_iq_calibrate
  82. _rtl8821ae_phy_set_rfpath_switch
  83. rtl8812ae_phy_iq_calibrate
  84. rtl8812ae_do_iqk
  85. rtl8821ae_phy_iq_calibrate
  86. rtl8821ae_reset_iqk_result
  87. rtl8821ae_do_iqk
  88. rtl8821ae_phy_lc_calibrate
  89. rtl8821ae_phy_ap_calibrate
  90. rtl8821ae_phy_set_rfpath_switch
  91. rtl8821ae_phy_set_io_cmd
  92. rtl8821ae_phy_set_io
  93. rtl8821ae_phy_set_rf_on
  94. _rtl8821ae_phy_set_rf_power_state
  95. rtl8821ae_phy_set_rf_power_state

   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 
  25 static u32 _rtl8821ae_phy_rf_serial_read(struct ieee80211_hw *hw,
  26                                          enum radio_path rfpath, u32 offset);
  27 static void _rtl8821ae_phy_rf_serial_write(struct ieee80211_hw *hw,
  28                                            enum radio_path rfpath, u32 offset,
  29                                            u32 data);
  30 static u32 _rtl8821ae_phy_calculate_bit_shift(u32 bitmask);
  31 static bool _rtl8821ae_phy_bb8821a_config_parafile(struct ieee80211_hw *hw);
  32 /*static bool _rtl8812ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);*/
  33 static bool _rtl8821ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
  34 static bool _rtl8821ae_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
  35                                                      u8 configtype);
  36 static bool _rtl8821ae_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
  37                                                        u8 configtype);
  38 static void phy_init_bb_rf_register_definition(struct ieee80211_hw *hw);
  39 
  40 static long _rtl8821ae_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
  41                                             enum wireless_mode wirelessmode,
  42                                             u8 txpwridx);
  43 static void rtl8821ae_phy_set_rf_on(struct ieee80211_hw *hw);
  44 static void rtl8821ae_phy_set_io(struct ieee80211_hw *hw);
  45 
  46 static 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 
  93 u32 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 
 112 void 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 
 136 u32 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 
 163 void 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 
 193 static 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 
 253 static 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 
 277 static 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 
 288 bool 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 
 297 bool 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 
 334 bool rtl8821ae_phy_rf_config(struct ieee80211_hw *hw)
 335 {
 336         return rtl8821ae_phy_rf6052_config(hw);
 337 }
 338 
 339 static 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 
 387 static 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 
 441 u32 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 
 599 void 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 
 732 static 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 
 814 static 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 
 842 static 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 
 857 static 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 
 867 static 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 
 877 static 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 
 898 static 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 
 914 static 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 
 983 static 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 
1055 static 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 
1109 static 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 
1134 static 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 
1175 static 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 
1300 static 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 
1440 static 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 
1472 static 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 
1583 static 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 */
1590 static 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 
1608 static 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 
1620 static 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 
1646 static 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 
1757 static 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 
1768 static 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 
1802 static 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 
1849 static 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 
1901 static 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 
1923 static 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 
1959 static 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 
1973 static 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 
2001 static 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 
2076 bool 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 
2111 bool 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 
2141 void 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 
2172 static 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 
2199 void 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 
2226 static 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 
2247 static 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 
2331 static 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 
2343 static 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 
2512 static 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 
2623 static 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 
2750 static 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 
3159 static 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 
3178 static 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 
3216 void 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*/
3276 void 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 
3286 static 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 
3309 void 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 
3344 static 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 
3367 static 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 
3406 void 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 
3490 void 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 
3511 void 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 
3568 u8 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 
3614 u8 _rtl8812ae_get_right_chnl_place_for_iqk(u8 chnl)
3615 {
3616         static const 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;
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 
3638 static 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 
3653 static 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 
3666 static 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 
3684 static 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 
3697 static 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 
3723 static 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 
3746 static 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 
4436 static 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 
4459 static 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 
4483 static 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 
4506 static 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 
4538 static 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 
4554 void rtl8812ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
4555 {
4556 }
4557 
4558 void 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 
4567 void 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 
4585 void 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 
4612 void 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 
4623 void rtl8821ae_phy_lc_calibrate(struct ieee80211_hw *hw)
4624 {
4625 }
4626 
4627 void rtl8821ae_phy_ap_calibrate(struct ieee80211_hw *hw, s8 delta)
4628 {
4629 }
4630 
4631 void rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
4632 {
4633         _rtl8821ae_phy_set_rfpath_switch(hw, bmain);
4634 }
4635 
4636 bool 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 
4675 static 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 
4712 static 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 
4723 static 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 
4819 bool 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 }

/* [<][>][^][v][top][bottom][index][help] */