File Index
Files and directories
Sign in
FILE

phy.c

File preview with syntax highlighting.

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