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			}
2039		}
2040	}
2041
2042	return true;
2043}
2044
2045bool rtl8812ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
2046					     enum radio_path rfpath)
2047{
2048	u32 *radioa_array_table_a, *radioa_array_table_b;
2049	u16 radioa_arraylen_a, radioa_arraylen_b;
2050	struct rtl_priv *rtlpriv = rtl_priv(hw);
2051
2052	radioa_arraylen_a = RTL8812AE_RADIOA_1TARRAYLEN;
2053	radioa_array_table_a = RTL8812AE_RADIOA_ARRAY;
2054	radioa_arraylen_b = RTL8812AE_RADIOB_1TARRAYLEN;
2055	radioa_array_table_b = RTL8812AE_RADIOB_ARRAY;
2056	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
2057		"Radio_A:RTL8821AE_RADIOA_ARRAY %d\n", radioa_arraylen_a);
2058	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
2059	switch (rfpath) {
2060	case RF90_PATH_A:
2061		return __rtl8821ae_phy_config_with_headerfile(hw,
2062				radioa_array_table_a, radioa_arraylen_a,
2063				_rtl8821ae_config_rf_radio_a);
2064	case RF90_PATH_B:
2065		return __rtl8821ae_phy_config_with_headerfile(hw,
2066				radioa_array_table_b, radioa_arraylen_b,
2067				_rtl8821ae_config_rf_radio_b);
2068	case RF90_PATH_C:
2069	case RF90_PATH_D:
2070		pr_err("switch case %#x not processed\n", rfpath);
2071		break;
2072	}
2073	return true;
2074}
2075
2076bool rtl8821ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
2077						enum radio_path rfpath)
2078{
2079	u32 *radioa_array_table;
2080	u16 radioa_arraylen;
2081	struct rtl_priv *rtlpriv = rtl_priv(hw);
2082
2083	radioa_arraylen = RTL8821AE_RADIOA_1TARRAYLEN;
2084	radioa_array_table = RTL8821AE_RADIOA_ARRAY;
2085	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
2086		"Radio_A:RTL8821AE_RADIOA_ARRAY %d\n", radioa_arraylen);
2087	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
2088	switch (rfpath) {
2089	case RF90_PATH_A:
2090		return __rtl8821ae_phy_config_with_headerfile(hw,
2091			radioa_array_table, radioa_arraylen,
2092			_rtl8821ae_config_rf_radio_a);
2093
2094	case RF90_PATH_B:
2095	case RF90_PATH_C:
2096	case RF90_PATH_D:
2097		pr_err("switch case %#x not processed\n", rfpath);
2098		break;
2099	}
2100	return true;
2101}
2102
2103void rtl8821ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
2104{
2105	struct rtl_priv *rtlpriv = rtl_priv(hw);
2106	struct rtl_phy *rtlphy = &rtlpriv->phy;
2107
2108	rtlphy->default_initialgain[0] =
2109	    (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
2110	rtlphy->default_initialgain[1] =
2111	    (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
2112	rtlphy->default_initialgain[2] =
2113	    (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
2114	rtlphy->default_initialgain[3] =
2115	    (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
2116
2117	rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
2118		"Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
2119		rtlphy->default_initialgain[0],
2120		rtlphy->default_initialgain[1],
2121		rtlphy->default_initialgain[2],
2122		rtlphy->default_initialgain[3]);
2123
2124	rtlphy->framesync = (u8)rtl_get_bbreg(hw,
2125					       ROFDM0_RXDETECTOR3, MASKBYTE0);
2126	rtlphy->framesync_c34 = rtl_get_bbreg(hw,
2127					      ROFDM0_RXDETECTOR2, MASKDWORD);
2128
2129	rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
2130		"Default framesync (0x%x) = 0x%x\n",
2131		ROFDM0_RXDETECTOR3, rtlphy->framesync);
2132}
2133
2134static void phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
2135{
2136	struct rtl_priv *rtlpriv = rtl_priv(hw);
2137	struct rtl_phy *rtlphy = &rtlpriv->phy;
2138
2139	rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
2140	rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
2141
2142	rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
2143	rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
2144
2145	rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
2146	rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
2147
2148	rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = RA_LSSIWRITE_8821A;
2149	rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = RB_LSSIWRITE_8821A;
2150
2151	rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RHSSIREAD_8821AE;
2152	rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RHSSIREAD_8821AE;
2153
2154	rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RA_SIREAD_8821A;
2155	rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RB_SIREAD_8821A;
2156
2157	rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = RA_PIREAD_8821A;
2158	rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = RB_PIREAD_8821A;
2159}
2160
2161void rtl8821ae_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
2162{
2163	struct rtl_priv *rtlpriv = rtl_priv(hw);
2164	struct rtl_phy *rtlphy = &rtlpriv->phy;
2165	u8 txpwr_level;
2166	long txpwr_dbm;
2167
2168	txpwr_level = rtlphy->cur_cck_txpwridx;
2169	txpwr_dbm = _rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2170						 WIRELESS_MODE_B, txpwr_level);
2171	txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
2172	if (_rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2173					 WIRELESS_MODE_G,
2174					 txpwr_level) > txpwr_dbm)
2175		txpwr_dbm =
2176		    _rtl8821ae_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
2177						 txpwr_level);
2178	txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
2179	if (_rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2180					 WIRELESS_MODE_N_24G,
2181					 txpwr_level) > txpwr_dbm)
2182		txpwr_dbm =
2183		    _rtl8821ae_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
2184						 txpwr_level);
2185	*powerlevel = txpwr_dbm;
2186}
2187
2188static bool _rtl8821ae_phy_get_chnl_index(u8 channel, u8 *chnl_index)
2189{
2190	u8 i = 0;
2191	bool in_24g = true;
2192
2193	if (channel <= 14) {
2194		in_24g = true;
2195		*chnl_index = channel - 1;
2196	} else {
2197		in_24g = false;
2198
2199		for (i = 0; i < CHANNEL_MAX_NUMBER_5G; ++i) {
2200			if (channel5g[i] == channel) {
2201				*chnl_index = i;
2202				return in_24g;
2203			}
2204		}
2205	}
2206	return in_24g;
2207}
2208
2209static s8 _rtl8821ae_phy_get_ratesection_intxpower_byrate(u8 path, u8 rate)
2210{
2211	s8 rate_section = 0;
2212	switch (rate) {
2213	case DESC_RATE1M:
2214	case DESC_RATE2M:
2215	case DESC_RATE5_5M:
2216	case DESC_RATE11M:
2217		rate_section = 0;
2218		break;
2219	case DESC_RATE6M:
2220	case DESC_RATE9M:
2221	case DESC_RATE12M:
2222	case DESC_RATE18M:
2223		rate_section = 1;
2224		break;
2225	case DESC_RATE24M:
2226	case DESC_RATE36M:
2227	case DESC_RATE48M:
2228	case DESC_RATE54M:
2229		rate_section = 2;
2230		break;
2231	case DESC_RATEMCS0:
2232	case DESC_RATEMCS1:
2233	case DESC_RATEMCS2:
2234	case DESC_RATEMCS3:
2235		rate_section = 3;
2236		break;
2237	case DESC_RATEMCS4:
2238	case DESC_RATEMCS5:
2239	case DESC_RATEMCS6:
2240	case DESC_RATEMCS7:
2241		rate_section = 4;
2242		break;
2243	case DESC_RATEMCS8:
2244	case DESC_RATEMCS9:
2245	case DESC_RATEMCS10:
2246	case DESC_RATEMCS11:
2247		rate_section = 5;
2248		break;
2249	case DESC_RATEMCS12:
2250	case DESC_RATEMCS13:
2251	case DESC_RATEMCS14:
2252	case DESC_RATEMCS15:
2253		rate_section = 6;
2254		break;
2255	case DESC_RATEVHT1SS_MCS0:
2256	case DESC_RATEVHT1SS_MCS1:
2257	case DESC_RATEVHT1SS_MCS2:
2258	case DESC_RATEVHT1SS_MCS3:
2259		rate_section = 7;
2260		break;
2261	case DESC_RATEVHT1SS_MCS4:
2262	case DESC_RATEVHT1SS_MCS5:
2263	case DESC_RATEVHT1SS_MCS6:
2264	case DESC_RATEVHT1SS_MCS7:
2265		rate_section = 8;
2266		break;
2267	case DESC_RATEVHT1SS_MCS8:
2268	case DESC_RATEVHT1SS_MCS9:
2269	case DESC_RATEVHT2SS_MCS0:
2270	case DESC_RATEVHT2SS_MCS1:
2271		rate_section = 9;
2272		break;
2273	case DESC_RATEVHT2SS_MCS2:
2274	case DESC_RATEVHT2SS_MCS3:
2275	case DESC_RATEVHT2SS_MCS4:
2276	case DESC_RATEVHT2SS_MCS5:
2277		rate_section = 10;
2278		break;
2279	case DESC_RATEVHT2SS_MCS6:
2280	case DESC_RATEVHT2SS_MCS7:
2281	case DESC_RATEVHT2SS_MCS8:
2282	case DESC_RATEVHT2SS_MCS9:
2283		rate_section = 11;
2284		break;
2285	default:
2286		WARN_ONCE(true, "rtl8821ae: Rate_Section is Illegal\n");
2287		break;
2288	}
2289
2290	return rate_section;
2291}
2292
2293static s8 _rtl8812ae_phy_get_world_wide_limit(s8  *limit_table)
2294{
2295	s8 min = limit_table[0];
2296	u8 i = 0;
2297
2298	for (i = 0; i < MAX_REGULATION_NUM; ++i) {
2299		if (limit_table[i] < min)
2300			min = limit_table[i];
2301	}
2302	return min;
2303}
2304
2305static s8 _rtl8812ae_phy_get_txpower_limit(struct ieee80211_hw *hw,
2306					     u8 band,
2307					     enum ht_channel_width bandwidth,
2308					     enum radio_path rf_path,
2309					     u8 rate, u8 channel)
2310{
2311	struct rtl_priv *rtlpriv = rtl_priv(hw);
2312	struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
2313	struct rtl_phy *rtlphy = &rtlpriv->phy;
2314	short band_temp = -1, regulation = -1, bandwidth_temp = -1,
2315		 rate_section = -1, channel_temp = -1;
2316	u16 regu, bdwidth, sec, chnl;
2317	s8 power_limit = MAX_POWER_INDEX;
2318
2319	if (rtlefuse->eeprom_regulatory == 2)
2320		return MAX_POWER_INDEX;
2321
2322	regulation = TXPWR_LMT_WW;
2323
2324	if (band == BAND_ON_2_4G)
2325		band_temp = 0;
2326	else if (band == BAND_ON_5G)
2327		band_temp = 1;
2328
2329	if (bandwidth == HT_CHANNEL_WIDTH_20)
2330		bandwidth_temp = 0;
2331	else if (bandwidth == HT_CHANNEL_WIDTH_20_40)
2332		bandwidth_temp = 1;
2333	else if (bandwidth == HT_CHANNEL_WIDTH_80)
2334		bandwidth_temp = 2;
2335
2336	switch (rate) {
2337	case DESC_RATE1M:
2338	case DESC_RATE2M:
2339	case DESC_RATE5_5M:
2340	case DESC_RATE11M:
2341		rate_section = 0;
2342		break;
2343	case DESC_RATE6M:
2344	case DESC_RATE9M:
2345	case DESC_RATE12M:
2346	case DESC_RATE18M:
2347	case DESC_RATE24M:
2348	case DESC_RATE36M:
2349	case DESC_RATE48M:
2350	case DESC_RATE54M:
2351		rate_section = 1;
2352		break;
2353	case DESC_RATEMCS0:
2354	case DESC_RATEMCS1:
2355	case DESC_RATEMCS2:
2356	case DESC_RATEMCS3:
2357	case DESC_RATEMCS4:
2358	case DESC_RATEMCS5:
2359	case DESC_RATEMCS6:
2360	case DESC_RATEMCS7:
2361		rate_section = 2;
2362		break;
2363	case DESC_RATEMCS8:
2364	case DESC_RATEMCS9:
2365	case DESC_RATEMCS10:
2366	case DESC_RATEMCS11:
2367	case DESC_RATEMCS12:
2368	case DESC_RATEMCS13:
2369	case DESC_RATEMCS14:
2370	case DESC_RATEMCS15:
2371		rate_section = 3;
2372		break;
2373	case DESC_RATEVHT1SS_MCS0:
2374	case DESC_RATEVHT1SS_MCS1:
2375	case DESC_RATEVHT1SS_MCS2:
2376	case DESC_RATEVHT1SS_MCS3:
2377	case DESC_RATEVHT1SS_MCS4:
2378	case DESC_RATEVHT1SS_MCS5:
2379	case DESC_RATEVHT1SS_MCS6:
2380	case DESC_RATEVHT1SS_MCS7:
2381	case DESC_RATEVHT1SS_MCS8:
2382	case DESC_RATEVHT1SS_MCS9:
2383		rate_section = 4;
2384		break;
2385	case DESC_RATEVHT2SS_MCS0:
2386	case DESC_RATEVHT2SS_MCS1:
2387	case DESC_RATEVHT2SS_MCS2:
2388	case DESC_RATEVHT2SS_MCS3:
2389	case DESC_RATEVHT2SS_MCS4:
2390	case DESC_RATEVHT2SS_MCS5:
2391	case DESC_RATEVHT2SS_MCS6:
2392	case DESC_RATEVHT2SS_MCS7:
2393	case DESC_RATEVHT2SS_MCS8:
2394	case DESC_RATEVHT2SS_MCS9:
2395		rate_section = 5;
2396		break;
2397	default:
2398		rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
2399			"Wrong rate 0x%x\n", rate);
2400		break;
2401	}
2402
2403	if (band_temp == BAND_ON_5G  && rate_section == 0)
2404		rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
2405			"Wrong rate 0x%x: No CCK in 5G Band\n", rate);
2406
2407	/*workaround for wrong index combination to obtain tx power limit,
2408	  OFDM only exists in BW 20M*/
2409	if (rate_section == 1)
2410		bandwidth_temp = 0;
2411
2412	/*workaround for wrong index combination to obtain tx power limit,
2413	 *HT on 80M will reference to HT on 40M
2414	 */
2415	if ((rate_section == 2 || rate_section == 3) && band == BAND_ON_5G &&
2416	    bandwidth_temp == 2)
2417		bandwidth_temp = 1;
2418
2419	if (band == BAND_ON_2_4G)
2420		channel_temp = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
2421		BAND_ON_2_4G, channel);
2422	else if (band == BAND_ON_5G)
2423		channel_temp = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
2424		BAND_ON_5G, channel);
2425	else if (band == BAND_ON_BOTH) {
2426		;/* BAND_ON_BOTH don't care temporarily */
2427	}
2428
2429	if (band_temp == -1 || regulation == -1 || bandwidth_temp == -1 ||
2430		rate_section == -1 || channel_temp == -1) {
2431		rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
2432			"Wrong index value to access power limit table [band %d][regulation %d][bandwidth %d][rf_path %d][rate_section %d][chnl %d]\n",
2433			band_temp, regulation, bandwidth_temp, rf_path,
2434			rate_section, channel_temp);
2435		return MAX_POWER_INDEX;
2436	}
2437
2438	regu = regulation;
2439	bdwidth = bandwidth_temp;
2440	sec = rate_section;
2441	chnl = channel_temp;
2442
2443	if (band == BAND_ON_2_4G) {
2444		s8 limits[10] = {0};
2445		u8 i;
2446
2447		for (i = 0; i < 4; ++i)
2448			limits[i] = rtlphy->txpwr_limit_2_4g[i][bdwidth]
2449			[sec][chnl][rf_path];
2450
2451		power_limit = (regulation == TXPWR_LMT_WW) ?
2452			_rtl8812ae_phy_get_world_wide_limit(limits) :
2453			rtlphy->txpwr_limit_2_4g[regu][bdwidth]
2454					[sec][chnl][rf_path];
2455	} else if (band == BAND_ON_5G) {
2456		s8 limits[10] = {0};
2457		u8 i;
2458
2459		for (i = 0; i < MAX_REGULATION_NUM; ++i)
2460			limits[i] = rtlphy->txpwr_limit_5g[i][bdwidth]
2461			[sec][chnl][rf_path];
2462
2463		power_limit = (regulation == TXPWR_LMT_WW) ?
2464			_rtl8812ae_phy_get_world_wide_limit(limits) :
2465			rtlphy->txpwr_limit_5g[regu][chnl]
2466			[sec][chnl][rf_path];
2467	} else {
2468		rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
2469			"No power limit table of the specified band\n");
2470	}
2471	return power_limit;
2472}
2473
2474static s8 _rtl8821ae_phy_get_txpower_by_rate(struct ieee80211_hw *hw,
2475					u8 band, u8 path, u8 rate)
2476{
2477	struct rtl_priv *rtlpriv = rtl_priv(hw);
2478	struct rtl_phy *rtlphy = &rtlpriv->phy;
2479	u8 shift = 0, rate_section, tx_num;
2480	s8 tx_pwr_diff = 0;
2481	s8 limit = 0;
2482
2483	rate_section = _rtl8821ae_phy_get_ratesection_intxpower_byrate(path, rate);
2484	tx_num = RF_TX_NUM_NONIMPLEMENT;
2485
2486	if (tx_num == RF_TX_NUM_NONIMPLEMENT) {
2487		if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
2488			(rate >= DESC_RATEVHT2SS_MCS2 && rate <= DESC_RATEVHT2SS_MCS9))
2489			tx_num = RF_2TX;
2490		else
2491			tx_num = RF_1TX;
2492	}
2493
2494	switch (rate) {
2495	case DESC_RATE1M:
2496	case DESC_RATE6M:
2497	case DESC_RATE24M:
2498	case DESC_RATEMCS0:
2499	case DESC_RATEMCS4:
2500	case DESC_RATEMCS8:
2501	case DESC_RATEMCS12:
2502	case DESC_RATEVHT1SS_MCS0:
2503	case DESC_RATEVHT1SS_MCS4:
2504	case DESC_RATEVHT1SS_MCS8:
2505	case DESC_RATEVHT2SS_MCS2:
2506	case DESC_RATEVHT2SS_MCS6:
2507		shift = 0;
2508		break;
2509	case DESC_RATE2M:
2510	case DESC_RATE9M:
2511	case DESC_RATE36M:
2512	case DESC_RATEMCS1:
2513	case DESC_RATEMCS5:
2514	case DESC_RATEMCS9:
2515	case DESC_RATEMCS13:
2516	case DESC_RATEVHT1SS_MCS1:
2517	case DESC_RATEVHT1SS_MCS5:
2518	case DESC_RATEVHT1SS_MCS9:
2519	case DESC_RATEVHT2SS_MCS3:
2520	case DESC_RATEVHT2SS_MCS7:
2521		shift = 8;
2522		break;
2523	case DESC_RATE5_5M:
2524	case DESC_RATE12M:
2525	case DESC_RATE48M:
2526	case DESC_RATEMCS2:
2527	case DESC_RATEMCS6:
2528	case DESC_RATEMCS10:
2529	case DESC_RATEMCS14:
2530	case DESC_RATEVHT1SS_MCS2:
2531	case DESC_RATEVHT1SS_MCS6:
2532	case DESC_RATEVHT2SS_MCS0:
2533	case DESC_RATEVHT2SS_MCS4:
2534	case DESC_RATEVHT2SS_MCS8:
2535		shift = 16;
2536		break;
2537	case DESC_RATE11M:
2538	case DESC_RATE18M:
2539	case DESC_RATE54M:
2540	case DESC_RATEMCS3:
2541	case DESC_RATEMCS7:
2542	case DESC_RATEMCS11:
2543	case DESC_RATEMCS15:
2544	case DESC_RATEVHT1SS_MCS3:
2545	case DESC_RATEVHT1SS_MCS7:
2546	case DESC_RATEVHT2SS_MCS1:
2547	case DESC_RATEVHT2SS_MCS5:
2548	case DESC_RATEVHT2SS_MCS9:
2549		shift = 24;
2550		break;
2551	default:
2552		WARN_ONCE(true, "rtl8821ae: Rate_Section is Illegal\n");
2553		break;
2554	}
2555
2556	tx_pwr_diff = (u8)(rtlphy->tx_power_by_rate_offset[band][path]
2557		[tx_num][rate_section] >> shift) & 0xff;
2558
2559	/* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
2560	if (rtlpriv->efuse.eeprom_regulatory != 2) {
2561		limit = _rtl8812ae_phy_get_txpower_limit(hw, band,
2562			rtlphy->current_chan_bw, path, rate,
2563			rtlphy->current_channel);
2564
2565		if (rate == DESC_RATEVHT1SS_MCS8 || rate == DESC_RATEVHT1SS_MCS9  ||
2566			 rate == DESC_RATEVHT2SS_MCS8 || rate == DESC_RATEVHT2SS_MCS9) {
2567			if (limit < 0) {
2568				if (tx_pwr_diff < (-limit))
2569					tx_pwr_diff = -limit;
2570			}
2571		} else {
2572			if (limit < 0)
2573				tx_pwr_diff = limit;
2574			else
2575				tx_pwr_diff = tx_pwr_diff > limit ? limit : tx_pwr_diff;
2576		}
2577		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2578			"Maximum power by rate %d, final power by rate %d\n",
2579			limit, tx_pwr_diff);
2580	}
2581
2582	return	tx_pwr_diff;
2583}
2584
2585static u8 _rtl8821ae_get_txpower_index(struct ieee80211_hw *hw, u8 path,
2586					u8 rate, u8 bandwidth, u8 channel)
2587{
2588	struct rtl_priv *rtlpriv = rtl_priv(hw);
2589	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
2590	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2591	u8 index = (channel - 1);
2592	u8 txpower = 0;
2593	bool in_24g = false;
2594	s8 powerdiff_byrate = 0;
2595
2596	if (((rtlhal->current_bandtype == BAND_ON_2_4G) &&
2597	    (channel > 14 || channel < 1)) ||
2598	    ((rtlhal->current_bandtype == BAND_ON_5G) && (channel <= 14))) {
2599		index = 0;
2600		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2601			"Illegal channel!!\n");
2602	}
2603
2604	in_24g = _rtl8821ae_phy_get_chnl_index(channel, &index);
2605	if (in_24g) {
2606		if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2607			txpower = rtlefuse->txpwrlevel_cck[path][index];
2608		else if (DESC_RATE6M <= rate)
2609			txpower = rtlefuse->txpwrlevel_ht40_1s[path][index];
2610		else
2611			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "invalid rate\n");
2612
2613		if (DESC_RATE6M <= rate && rate <= DESC_RATE54M &&
2614		    !RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2615			txpower += rtlefuse->txpwr_legacyhtdiff[path][TX_1S];
2616
2617		if (bandwidth == HT_CHANNEL_WIDTH_20) {
2618			if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2619				(DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2620				txpower += rtlefuse->txpwr_ht20diff[path][TX_1S];
2621			if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2622				(DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2623				txpower += rtlefuse->txpwr_ht20diff[path][TX_2S];
2624		} else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
2625			if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2626				(DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2627				txpower += rtlefuse->txpwr_ht40diff[path][TX_1S];
2628			if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2629				(DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2630				txpower += rtlefuse->txpwr_ht40diff[path][TX_2S];
2631		} else if (bandwidth == HT_CHANNEL_WIDTH_80) {
2632			if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2633			    (DESC_RATEVHT1SS_MCS0 <= rate &&
2634			     rate <= DESC_RATEVHT2SS_MCS9))
2635				txpower += rtlefuse->txpwr_ht40diff[path][TX_1S];
2636			if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2637			    (DESC_RATEVHT2SS_MCS0 <= rate &&
2638			     rate <= DESC_RATEVHT2SS_MCS9))
2639				txpower += rtlefuse->txpwr_ht40diff[path][TX_2S];
2640		}
2641	} else {
2642		if (DESC_RATE6M <= rate)
2643			txpower = rtlefuse->txpwr_5g_bw40base[path][index];
2644		else
2645			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_WARNING,
2646				"INVALID Rate.\n");
2647
2648		if (DESC_RATE6M <= rate && rate <= DESC_RATE54M &&
2649		    !RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2650			txpower += rtlefuse->txpwr_5g_ofdmdiff[path][TX_1S];
2651
2652		if (bandwidth == HT_CHANNEL_WIDTH_20) {
2653			if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2654			    (DESC_RATEVHT1SS_MCS0 <= rate &&
2655			     rate <= DESC_RATEVHT2SS_MCS9))
2656				txpower += rtlefuse->txpwr_5g_bw20diff[path][TX_1S];
2657			if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2658			    (DESC_RATEVHT2SS_MCS0 <= rate &&
2659			     rate <= DESC_RATEVHT2SS_MCS9))
2660				txpower += rtlefuse->txpwr_5g_bw20diff[path][TX_2S];
2661		} else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
2662			if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2663			    (DESC_RATEVHT1SS_MCS0 <= rate &&
2664			     rate <= DESC_RATEVHT2SS_MCS9))
2665				txpower += rtlefuse->txpwr_5g_bw40diff[path][TX_1S];
2666			if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2667			    (DESC_RATEVHT2SS_MCS0 <= rate &&
2668			     rate <= DESC_RATEVHT2SS_MCS9))
2669				txpower += rtlefuse->txpwr_5g_bw40diff[path][TX_2S];
2670		} else if (bandwidth == HT_CHANNEL_WIDTH_80) {
2671			u8 i;
2672
2673			for (i = 0; i < sizeof(channel5g_80m) / sizeof(u8); ++i)
2674				if (channel5g_80m[i] == channel)
2675					index = i;
2676
2677			if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2678			    (DESC_RATEVHT1SS_MCS0 <= rate &&
2679			     rate <= DESC_RATEVHT2SS_MCS9))
2680				txpower = rtlefuse->txpwr_5g_bw80base[path][index]
2681					+ rtlefuse->txpwr_5g_bw80diff[path][TX_1S];
2682			if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2683			    (DESC_RATEVHT2SS_MCS0 <= rate &&
2684			     rate <= DESC_RATEVHT2SS_MCS9))
2685				txpower = rtlefuse->txpwr_5g_bw80base[path][index]
2686					+ rtlefuse->txpwr_5g_bw80diff[path][TX_1S]
2687					+ rtlefuse->txpwr_5g_bw80diff[path][TX_2S];
2688		    }
2689	}
2690	if (rtlefuse->eeprom_regulatory != 2)
2691		powerdiff_byrate =
2692		  _rtl8821ae_phy_get_txpower_by_rate(hw, (u8)(!in_24g),
2693						     path, rate);
2694
2695	if (rate == DESC_RATEVHT1SS_MCS8 || rate == DESC_RATEVHT1SS_MCS9 ||
2696	    rate == DESC_RATEVHT2SS_MCS8 || rate == DESC_RATEVHT2SS_MCS9)
2697		txpower -= powerdiff_byrate;
2698	else
2699		txpower += powerdiff_byrate;
2700
2701	if (rate > DESC_RATE11M)
2702		txpower += rtlpriv->dm.remnant_ofdm_swing_idx[path];
2703	else
2704		txpower += rtlpriv->dm.remnant_cck_idx;
2705
2706	if (txpower > MAX_POWER_INDEX)
2707		txpower = MAX_POWER_INDEX;
2708
2709	return txpower;
2710}
2711
2712static void _rtl8821ae_phy_set_txpower_index(struct ieee80211_hw *hw,
2713					     u8 power_index, u8 path, u8 rate)
2714{
2715	struct rtl_priv *rtlpriv = rtl_priv(hw);
2716
2717	if (path == RF90_PATH_A) {
2718		switch (rate) {
2719		case DESC_RATE1M:
2720			rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2721				      MASKBYTE0, power_index);
2722			break;
2723		case DESC_RATE2M:
2724			rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2725				      MASKBYTE1, power_index);
2726			break;
2727		case DESC_RATE5_5M:
2728			rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2729				      MASKBYTE2, power_index);
2730			break;
2731		case DESC_RATE11M:
2732			rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2733				      MASKBYTE3, power_index);
2734			break;
2735		case DESC_RATE6M:
2736			rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2737				      MASKBYTE0, power_index);
2738			break;
2739		case DESC_RATE9M:
2740			rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2741				      MASKBYTE1, power_index);
2742			break;
2743		case DESC_RATE12M:
2744			rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2745				      MASKBYTE2, power_index);
2746			break;
2747		case DESC_RATE18M:
2748			rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2749				      MASKBYTE3, power_index);
2750			break;
2751		case DESC_RATE24M:
2752			rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2753				      MASKBYTE0, power_index);
2754			break;
2755		case DESC_RATE36M:
2756			rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2757				      MASKBYTE1, power_index);
2758			break;
2759		case DESC_RATE48M:
2760			rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2761				      MASKBYTE2, power_index);
2762			break;
2763		case DESC_RATE54M:
2764			rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2765				      MASKBYTE3, power_index);
2766			break;
2767		case DESC_RATEMCS0:
2768			rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2769				      MASKBYTE0, power_index);
2770			break;
2771		case DESC_RATEMCS1:
2772			rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2773				      MASKBYTE1, power_index);
2774			break;
2775		case DESC_RATEMCS2:
2776			rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2777				      MASKBYTE2, power_index);
2778			break;
2779		case DESC_RATEMCS3:
2780			rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2781				      MASKBYTE3, power_index);
2782			break;
2783		case DESC_RATEMCS4:
2784			rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2785				      MASKBYTE0, power_index);
2786			break;
2787		case DESC_RATEMCS5:
2788			rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2789				      MASKBYTE1, power_index);
2790			break;
2791		case DESC_RATEMCS6:
2792			rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2793				      MASKBYTE2, power_index);
2794			break;
2795		case DESC_RATEMCS7:
2796			rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2797				      MASKBYTE3, power_index);
2798			break;
2799		case DESC_RATEMCS8:
2800			rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2801				      MASKBYTE0, power_index);
2802			break;
2803		case DESC_RATEMCS9:
2804			rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2805				      MASKBYTE1, power_index);
2806			break;
2807		case DESC_RATEMCS10:
2808			rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2809				      MASKBYTE2, power_index);
2810			break;
2811		case DESC_RATEMCS11:
2812			rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2813				      MASKBYTE3, power_index);
2814			break;
2815		case DESC_RATEMCS12:
2816			rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2817				      MASKBYTE0, power_index);
2818			break;
2819		case DESC_RATEMCS13:
2820			rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2821				      MASKBYTE1, power_index);
2822			break;
2823		case DESC_RATEMCS14:
2824			rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2825				      MASKBYTE2, power_index);
2826			break;
2827		case DESC_RATEMCS15:
2828			rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2829				      MASKBYTE3, power_index);
2830			break;
2831		case DESC_RATEVHT1SS_MCS0:
2832			rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2833				      MASKBYTE0, power_index);
2834			break;
2835		case DESC_RATEVHT1SS_MCS1:
2836			rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2837				      MASKBYTE1, power_index);
2838			break;
2839		case DESC_RATEVHT1SS_MCS2:
2840			rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2841				      MASKBYTE2, power_index);
2842			break;
2843		case DESC_RATEVHT1SS_MCS3:
2844			rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2845				      MASKBYTE3, power_index);
2846			break;
2847		case DESC_RATEVHT1SS_MCS4:
2848			rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2849				      MASKBYTE0, power_index);
2850			break;
2851		case DESC_RATEVHT1SS_MCS5:
2852			rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2853				      MASKBYTE1, power_index);
2854			break;
2855		case DESC_RATEVHT1SS_MCS6:
2856			rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2857				      MASKBYTE2, power_index);
2858			break;
2859		case DESC_RATEVHT1SS_MCS7:
2860			rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2861				      MASKBYTE3, power_index);
2862			break;
2863		case DESC_RATEVHT1SS_MCS8:
2864			rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2865				      MASKBYTE0, power_index);
2866			break;
2867		case DESC_RATEVHT1SS_MCS9:
2868			rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2869				      MASKBYTE1, power_index);
2870			break;
2871		case DESC_RATEVHT2SS_MCS0:
2872			rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2873				      MASKBYTE2, power_index);
2874			break;
2875		case DESC_RATEVHT2SS_MCS1:
2876			rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2877				      MASKBYTE3, power_index);
2878			break;
2879		case DESC_RATEVHT2SS_MCS2:
2880			rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2881				      MASKBYTE0, power_index);
2882			break;
2883		case DESC_RATEVHT2SS_MCS3:
2884			rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2885				      MASKBYTE1, power_index);
2886			break;
2887		case DESC_RATEVHT2SS_MCS4:
2888			rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2889				      MASKBYTE2, power_index);
2890			break;
2891		case DESC_RATEVHT2SS_MCS5:
2892			rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2893				      MASKBYTE3, power_index);
2894			break;
2895		case DESC_RATEVHT2SS_MCS6:
2896			rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2897				      MASKBYTE0, power_index);
2898			break;
2899		case DESC_RATEVHT2SS_MCS7:
2900			rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2901				      MASKBYTE1, power_index);
2902			break;
2903		case DESC_RATEVHT2SS_MCS8:
2904			rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2905				      MASKBYTE2, power_index);
2906			break;
2907		case DESC_RATEVHT2SS_MCS9:
2908			rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2909				      MASKBYTE3, power_index);
2910			break;
2911		default:
2912			rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
2913				"Invalid Rate!!\n");
2914			break;
2915		}
2916	} else if (path == RF90_PATH_B) {
2917		switch (rate) {
2918		case DESC_RATE1M:
2919			rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2920				      MASKBYTE0, power_index);
2921			break;
2922		case DESC_RATE2M:
2923			rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2924				      MASKBYTE1, power_index);
2925			break;
2926		case DESC_RATE5_5M:
2927			rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2928				      MASKBYTE2, power_index);
2929			break;
2930		case DESC_RATE11M:
2931			rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2932				      MASKBYTE3, power_index);
2933			break;
2934		case DESC_RATE6M:
2935			rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
2936				      MASKBYTE0, power_index);
2937			break;
2938		case DESC_RATE9M:
2939			rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
2940				      MASKBYTE1, power_index);
2941			break;
2942		case DESC_RATE12M:
2943			rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
2944				      MASKBYTE2, power_index);
2945			break;
2946		case DESC_RATE18M:
2947			rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
2948				      MASKBYTE3, power_index);
2949			break;
2950		case DESC_RATE24M:
2951			rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
2952				      MASKBYTE0, power_index);
2953			break;
2954		case DESC_RATE36M:
2955			rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
2956				      MASKBYTE1, power_index);
2957			break;
2958		case DESC_RATE48M:
2959			rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
2960				      MASKBYTE2, power_index);
2961			break;
2962		case DESC_RATE54M:
2963			rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
2964				      MASKBYTE3, power_index);
2965			break;
2966		case DESC_RATEMCS0:
2967			rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
2968				      MASKBYTE0, power_index);
2969			break;
2970		case DESC_RATEMCS1:
2971			rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
2972				      MASKBYTE1, power_index);
2973			break;
2974		case DESC_RATEMCS2:
2975			rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
2976				      MASKBYTE2, power_index);
2977			break;
2978		case DESC_RATEMCS3:
2979			rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
2980				      MASKBYTE3, power_index);
2981			break;
2982		case DESC_RATEMCS4:
2983			rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
2984				      MASKBYTE0, power_index);
2985			break;
2986		case DESC_RATEMCS5:
2987			rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
2988				      MASKBYTE1, power_index);
2989			break;
2990		case DESC_RATEMCS6:
2991			rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
2992				      MASKBYTE2, power_index);
2993			break;
2994		case DESC_RATEMCS7:
2995			rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
2996				      MASKBYTE3, power_index);
2997			break;
2998		case DESC_RATEMCS8:
2999			rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3000				      MASKBYTE0, power_index);
3001			break;
3002		case DESC_RATEMCS9:
3003			rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3004				      MASKBYTE1, power_index);
3005			break;
3006		case DESC_RATEMCS10:
3007			rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3008				      MASKBYTE2, power_index);
3009			break;
3010		case DESC_RATEMCS11:
3011			rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3012				      MASKBYTE3, power_index);
3013			break;
3014		case DESC_RATEMCS12:
3015			rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3016				      MASKBYTE0, power_index);
3017			break;
3018		case DESC_RATEMCS13:
3019			rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3020				      MASKBYTE1, power_index);
3021			break;
3022		case DESC_RATEMCS14:
3023			rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3024				      MASKBYTE2, power_index);
3025			break;
3026		case DESC_RATEMCS15:
3027			rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3028				      MASKBYTE3, power_index);
3029			break;
3030		case DESC_RATEVHT1SS_MCS0:
3031			rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3032				      MASKBYTE0, power_index);
3033			break;
3034		case DESC_RATEVHT1SS_MCS1:
3035			rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3036				      MASKBYTE1, power_index);
3037			break;
3038		case DESC_RATEVHT1SS_MCS2:
3039			rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3040				      MASKBYTE2, power_index);
3041			break;
3042		case DESC_RATEVHT1SS_MCS3:
3043			rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3044				      MASKBYTE3, power_index);
3045			break;
3046		case DESC_RATEVHT1SS_MCS4:
3047			rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3048				      MASKBYTE0, power_index);
3049			break;
3050		case DESC_RATEVHT1SS_MCS5:
3051			rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3052				      MASKBYTE1, power_index);
3053			break;
3054		case DESC_RATEVHT1SS_MCS6:
3055			rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3056				      MASKBYTE2, power_index);
3057			break;
3058		case DESC_RATEVHT1SS_MCS7:
3059			rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3060				      MASKBYTE3, power_index);
3061			break;
3062		case DESC_RATEVHT1SS_MCS8:
3063			rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3064				      MASKBYTE0, power_index);
3065			break;
3066		case DESC_RATEVHT1SS_MCS9:
3067			rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3068				      MASKBYTE1, power_index);
3069			break;
3070		case DESC_RATEVHT2SS_MCS0:
3071			rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3072				      MASKBYTE2, power_index);
3073			break;
3074		case DESC_RATEVHT2SS_MCS1:
3075			rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3076				      MASKBYTE3, power_index);
3077			break;
3078		case DESC_RATEVHT2SS_MCS2:
3079			rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3080				      MASKBYTE0, power_index);
3081			break;
3082		case DESC_RATEVHT2SS_MCS3:
3083			rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3084				      MASKBYTE1, power_index);
3085			break;
3086		case DESC_RATEVHT2SS_MCS4:
3087			rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3088				      MASKBYTE2, power_index);
3089			break;
3090		case DESC_RATEVHT2SS_MCS5:
3091			rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3092				      MASKBYTE3, power_index);
3093			break;
3094		case DESC_RATEVHT2SS_MCS6:
3095			rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3096				      MASKBYTE0, power_index);
3097			break;
3098		case DESC_RATEVHT2SS_MCS7:
3099			rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3100				      MASKBYTE1, power_index);
3101			break;
3102		case DESC_RATEVHT2SS_MCS8:
3103			rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3104				      MASKBYTE2, power_index);
3105			break;
3106		case DESC_RATEVHT2SS_MCS9:
3107			rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3108				      MASKBYTE3, power_index);
3109			break;
3110		default:
3111			rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
3112				"Invalid Rate!!\n");
3113			break;
3114		}
3115	} else {
3116		rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
3117			"Invalid RFPath!!\n");
3118	}
3119}
3120
3121static void _rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
3122						     u8 *array, u8 path,
3123						     u8 channel, u8 size)
3124{
3125	struct rtl_priv *rtlpriv = rtl_priv(hw);
3126	struct rtl_phy *rtlphy = &rtlpriv->phy;
3127	u8 i;
3128	u8 power_index;
3129
3130	for (i = 0; i < size; i++) {
3131		power_index =
3132		  _rtl8821ae_get_txpower_index(hw, path, array[i],
3133					       rtlphy->current_chan_bw,
3134					       channel);
3135		_rtl8821ae_phy_set_txpower_index(hw, power_index, path,
3136						 array[i]);
3137	}
3138}
3139
3140static void _rtl8821ae_phy_txpower_training_by_path(struct ieee80211_hw *hw,
3141						    u8 bw, u8 channel, u8 path)
3142{
3143	struct rtl_priv *rtlpriv = rtl_priv(hw);
3144	struct rtl_phy *rtlphy = &rtlpriv->phy;
3145
3146	u8 i;
3147	u32 power_level, data, offset;
3148
3149	if (path >= rtlphy->num_total_rfpath)
3150		return;
3151
3152	data = 0;
3153	if (path == RF90_PATH_A) {
3154		power_level =
3155			_rtl8821ae_get_txpower_index(hw, RF90_PATH_A,
3156			DESC_RATEMCS7, bw, channel);
3157		offset =  RA_TXPWRTRAING;
3158	} else {
3159		power_level =
3160			_rtl8821ae_get_txpower_index(hw, RF90_PATH_B,
3161			DESC_RATEMCS7, bw, channel);
3162		offset =  RB_TXPWRTRAING;
3163	}
3164
3165	for (i = 0; i < 3; i++) {
3166		if (i == 0)
3167			power_level = power_level - 10;
3168		else if (i == 1)
3169			power_level = power_level - 8;
3170		else
3171			power_level = power_level - 6;
3172
3173		data |= (((power_level > 2) ? (power_level) : 2) << (i * 8));
3174	}
3175	rtl_set_bbreg(hw, offset, 0xffffff, data);
3176}
3177
3178void rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
3179					     u8 channel, u8 path)
3180{
3181	/* struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); */
3182	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3183	struct rtl_priv *rtlpriv = rtl_priv(hw);
3184	struct rtl_phy *rtlphy = &rtlpriv->phy;
3185	u8 cck_rates[]  = {DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M,
3186			      DESC_RATE11M};
3187	u8 sizes_of_cck_retes = 4;
3188	u8 ofdm_rates[]  = {DESC_RATE6M, DESC_RATE9M, DESC_RATE12M,
3189				DESC_RATE18M, DESC_RATE24M, DESC_RATE36M,
3190				DESC_RATE48M, DESC_RATE54M};
3191	u8 sizes_of_ofdm_retes = 8;
3192	u8 ht_rates_1t[]  = {DESC_RATEMCS0, DESC_RATEMCS1, DESC_RATEMCS2,
3193				DESC_RATEMCS3, DESC_RATEMCS4, DESC_RATEMCS5,
3194				DESC_RATEMCS6, DESC_RATEMCS7};
3195	u8 sizes_of_ht_retes_1t = 8;
3196	u8 ht_rates_2t[]  = {DESC_RATEMCS8, DESC_RATEMCS9,
3197				DESC_RATEMCS10, DESC_RATEMCS11,
3198				DESC_RATEMCS12, DESC_RATEMCS13,
3199				DESC_RATEMCS14, DESC_RATEMCS15};
3200	u8 sizes_of_ht_retes_2t = 8;
3201	u8 vht_rates_1t[]  = {DESC_RATEVHT1SS_MCS0, DESC_RATEVHT1SS_MCS1,
3202				DESC_RATEVHT1SS_MCS2, DESC_RATEVHT1SS_MCS3,
3203				DESC_RATEVHT1SS_MCS4, DESC_RATEVHT1SS_MCS5,
3204				DESC_RATEVHT1SS_MCS6, DESC_RATEVHT1SS_MCS7,
3205			     DESC_RATEVHT1SS_MCS8, DESC_RATEVHT1SS_MCS9};
3206	u8 vht_rates_2t[]  = {DESC_RATEVHT2SS_MCS0, DESC_RATEVHT2SS_MCS1,
3207				DESC_RATEVHT2SS_MCS2, DESC_RATEVHT2SS_MCS3,
3208				DESC_RATEVHT2SS_MCS4, DESC_RATEVHT2SS_MCS5,
3209				DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7,
3210				DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9};
3211	u8 sizes_of_vht_retes = 10;
3212
3213	if (rtlhal->current_bandtype == BAND_ON_2_4G)
3214		_rtl8821ae_phy_set_txpower_level_by_path(hw, cck_rates, path, channel,
3215							 sizes_of_cck_retes);
3216
3217	_rtl8821ae_phy_set_txpower_level_by_path(hw, ofdm_rates, path, channel,
3218						 sizes_of_ofdm_retes);
3219	_rtl8821ae_phy_set_txpower_level_by_path(hw, ht_rates_1t, path, channel,
3220						 sizes_of_ht_retes_1t);
3221	_rtl8821ae_phy_set_txpower_level_by_path(hw, vht_rates_1t, path, channel,
3222						 sizes_of_vht_retes);
3223
3224	if (rtlphy->num_total_rfpath >= 2) {
3225		_rtl8821ae_phy_set_txpower_level_by_path(hw, ht_rates_2t, path,
3226							 channel,
3227							 sizes_of_ht_retes_2t);
3228		_rtl8821ae_phy_set_txpower_level_by_path(hw, vht_rates_2t, path,
3229							 channel,
3230							 sizes_of_vht_retes);
3231	}
3232
3233	_rtl8821ae_phy_txpower_training_by_path(hw, rtlphy->current_chan_bw,
3234						channel, path);
3235}
3236
3237/*just in case, write txpower in DW, to reduce time*/
3238void rtl8821ae_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
3239{
3240	struct rtl_priv *rtlpriv = rtl_priv(hw);
3241	struct rtl_phy *rtlphy = &rtlpriv->phy;
3242	u8 path = 0;
3243
3244	for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; ++path)
3245		rtl8821ae_phy_set_txpower_level_by_path(hw, channel, path);
3246}
3247
3248static long _rtl8821ae_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
3249					    enum wireless_mode wirelessmode,
3250					    u8 txpwridx)
3251{
3252	long offset;
3253	long pwrout_dbm;
3254
3255	switch (wirelessmode) {
3256	case WIRELESS_MODE_B:
3257		offset = -7;
3258		break;
3259	case WIRELESS_MODE_G:
3260	case WIRELESS_MODE_N_24G:
3261		offset = -8;
3262		break;
3263	default:
3264		offset = -8;
3265		break;
3266	}
3267	pwrout_dbm = txpwridx / 2 + offset;
3268	return pwrout_dbm;
3269}
3270
3271void rtl8821ae_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
3272{
3273	struct rtl_priv *rtlpriv = rtl_priv(hw);
3274	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3275	enum io_type iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
3276
3277	if (!is_hal_stop(rtlhal)) {
3278		switch (operation) {
3279		case SCAN_OPT_BACKUP_BAND0:
3280			iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
3281			rtlpriv->cfg->ops->set_hw_reg(hw,
3282						      HW_VAR_IO_CMD,
3283						      (u8 *)&iotype);
3284
3285			break;
3286		case SCAN_OPT_BACKUP_BAND1:
3287			iotype = IO_CMD_PAUSE_BAND1_DM_BY_SCAN;
3288			rtlpriv->cfg->ops->set_hw_reg(hw,
3289						      HW_VAR_IO_CMD,
3290						      (u8 *)&iotype);
3291
3292			break;
3293		case SCAN_OPT_RESTORE:
3294			iotype = IO_CMD_RESUME_DM_BY_SCAN;
3295			rtlpriv->cfg->ops->set_hw_reg(hw,
3296						      HW_VAR_IO_CMD,
3297						      (u8 *)&iotype);
3298			break;
3299		default:
3300			pr_err("Unknown Scan Backup operation.\n");
3301			break;
3302		}
3303	}
3304}
3305
3306static void _rtl8821ae_phy_set_reg_bw(struct rtl_priv *rtlpriv, u8 bw)
3307{
3308	u16 reg_rf_mode_bw, tmp = 0;
3309
3310	reg_rf_mode_bw = rtl_read_word(rtlpriv, REG_TRXPTCL_CTL);
3311	switch (bw) {
3312	case HT_CHANNEL_WIDTH_20:
3313		rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, reg_rf_mode_bw & 0xFE7F);
3314		break;
3315	case HT_CHANNEL_WIDTH_20_40:
3316		tmp = reg_rf_mode_bw | BIT(7);
3317		rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, tmp & 0xFEFF);
3318		break;
3319	case HT_CHANNEL_WIDTH_80:
3320		tmp = reg_rf_mode_bw | BIT(8);
3321		rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, tmp & 0xFF7F);
3322		break;
3323	default:
3324		rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, "unknown Bandwidth: 0x%x\n", bw);
3325		break;
3326	}
3327}
3328
3329static u8 _rtl8821ae_phy_get_secondary_chnl(struct rtl_priv *rtlpriv)
3330{
3331	struct rtl_phy *rtlphy = &rtlpriv->phy;
3332	struct rtl_mac *mac = rtl_mac(rtlpriv);
3333	u8 sc_set_40 = 0, sc_set_20 = 0;
3334
3335	if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) {
3336		if (mac->cur_80_prime_sc == PRIME_CHNL_OFFSET_LOWER)
3337			sc_set_40 = VHT_DATA_SC_40_LOWER_OF_80MHZ;
3338		else if (mac->cur_80_prime_sc == PRIME_CHNL_OFFSET_UPPER)
3339			sc_set_40 = VHT_DATA_SC_40_UPPER_OF_80MHZ;
3340		else
3341			pr_err("SCMapping: Not Correct Primary40MHz Setting\n");
3342
3343		if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) &&
3344			(mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER))
3345			sc_set_20 = VHT_DATA_SC_20_LOWEST_OF_80MHZ;
3346		else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) &&
3347			(mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER))
3348			sc_set_20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
3349		else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) &&
3350			(mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER))
3351			sc_set_20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
3352		else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) &&
3353			(mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER))
3354			sc_set_20 = VHT_DATA_SC_20_UPPERST_OF_80MHZ;
3355		else
3356			pr_err("SCMapping: Not Correct Primary40MHz Setting\n");
3357	} else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
3358		if (mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER)
3359			sc_set_20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
3360		else if (mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER)
3361			sc_set_20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
3362		else
3363			pr_err("SCMapping: Not Correct Primary40MHz Setting\n");
3364	}
3365	return (sc_set_40 << 4) | sc_set_20;
3366}
3367
3368void rtl8821ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
3369{
3370	struct rtl_priv *rtlpriv = rtl_priv(hw);
3371	struct rtl_phy *rtlphy = &rtlpriv->phy;
3372	u8 sub_chnl = 0;
3373	u8 l1pk_val = 0;
3374
3375	rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE,
3376		"Switch to %s bandwidth\n",
3377		(rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
3378		 "20MHz" :
3379		 (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40 ?
3380		  "40MHz" : "80MHz")));
3381
3382	_rtl8821ae_phy_set_reg_bw(rtlpriv, rtlphy->current_chan_bw);
3383	sub_chnl = _rtl8821ae_phy_get_secondary_chnl(rtlpriv);
3384	rtl_write_byte(rtlpriv, 0x0483, sub_chnl);
3385
3386	switch (rtlphy->current_chan_bw) {
3387	case HT_CHANNEL_WIDTH_20:
3388		rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300200);
3389		rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
3390
3391		if (rtlphy->rf_type == RF_2T2R)
3392			rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, 7);
3393		else
3394			rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, 8);
3395		break;
3396	case HT_CHANNEL_WIDTH_20_40:
3397		rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300201);
3398		rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
3399		rtl_set_bbreg(hw, RRFMOD, 0x3C, sub_chnl);
3400		rtl_set_bbreg(hw, RCCAONSEC, 0xf0000000, sub_chnl);
3401
3402		if (rtlphy->reg_837 & BIT(2))
3403			l1pk_val = 6;
3404		else {
3405			if (rtlphy->rf_type == RF_2T2R)
3406				l1pk_val = 7;
3407			else
3408				l1pk_val = 8;
3409		}
3410		/* 0x848[25:22] = 0x6 */
3411		rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, l1pk_val);
3412
3413		if (sub_chnl == VHT_DATA_SC_20_UPPER_OF_80MHZ)
3414			rtl_set_bbreg(hw, RCCK_SYSTEM, BCCK_SYSTEM, 1);
3415		else
3416			rtl_set_bbreg(hw, RCCK_SYSTEM, BCCK_SYSTEM, 0);
3417		break;
3418
3419	case HT_CHANNEL_WIDTH_80:
3420		 /* 0x8ac[21,20,9:6,1,0]=8'b11100010 */
3421		rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300202);
3422		/* 0x8c4[30] = 1 */
3423		rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 1);
3424		rtl_set_bbreg(hw, RRFMOD, 0x3C, sub_chnl);
3425		rtl_set_bbreg(hw, RCCAONSEC, 0xf0000000, sub_chnl);
3426
3427		if (rtlphy->reg_837 & BIT(2))
3428			l1pk_val = 5;
3429		else {
3430			if (rtlphy->rf_type == RF_2T2R)
3431				l1pk_val = 6;
3432			else
3433				l1pk_val = 7;
3434		}
3435		rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, l1pk_val);
3436
3437		break;
3438	default:
3439		pr_err("unknown bandwidth: %#X\n",
3440		       rtlphy->current_chan_bw);
3441		break;
3442	}
3443
3444	rtl8812ae_fixspur(hw, rtlphy->current_chan_bw, rtlphy->current_channel);
3445
3446	rtl8821ae_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
3447	rtlphy->set_bwmode_inprogress = false;
3448
3449	rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
3450}
3451
3452void rtl8821ae_phy_set_bw_mode(struct ieee80211_hw *hw,
3453			    enum nl80211_channel_type ch_type)
3454{
3455	struct rtl_priv *rtlpriv = rtl_priv(hw);
3456	struct rtl_phy *rtlphy = &rtlpriv->phy;
3457	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3458	u8 tmp_bw = rtlphy->current_chan_bw;
3459
3460	if (rtlphy->set_bwmode_inprogress)
3461		return;
3462	rtlphy->set_bwmode_inprogress = true;
3463	if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw)))
3464		rtl8821ae_phy_set_bw_mode_callback(hw);
3465	else {
3466		rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
3467			"FALSE driver sleep or unload\n");
3468		rtlphy->set_bwmode_inprogress = false;
3469		rtlphy->current_chan_bw = tmp_bw;
3470	}
3471}
3472
3473void rtl8821ae_phy_sw_chnl_callback(struct ieee80211_hw *hw)
3474{
3475	struct rtl_priv *rtlpriv = rtl_priv(hw);
3476	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3477	struct rtl_phy *rtlphy = &rtlpriv->phy;
3478	u8 channel = rtlphy->current_channel;
3479	u8 path;
3480	u32 data;
3481
3482	rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE,
3483		"switch to channel%d\n", rtlphy->current_channel);
3484	if (is_hal_stop(rtlhal))
3485		return;
3486
3487	if (36 <= channel && channel <= 48)
3488		data = 0x494;
3489	else if (50 <= channel && channel <= 64)
3490		data = 0x453;
3491	else if (100 <= channel && channel <= 116)
3492		data = 0x452;
3493	else if (118 <= channel)
3494		data = 0x412;
3495	else
3496		data = 0x96a;
3497	rtl_set_bbreg(hw, RFC_AREA, 0x1ffe0000, data);
3498
3499	for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; path++) {
3500		if (36 <= channel && channel <= 64)
3501			data = 0x101;
3502		else if (100 <= channel && channel <= 140)
3503			data = 0x301;
3504		else if (140 < channel)
3505			data = 0x501;
3506		else
3507			data = 0x000;
3508		rtl8821ae_phy_set_rf_reg(hw, path, RF_CHNLBW,
3509			BIT(18)|BIT(17)|BIT(16)|BIT(9)|BIT(8), data);
3510
3511		rtl8821ae_phy_set_rf_reg(hw, path, RF_CHNLBW,
3512			BMASKBYTE0, channel);
3513
3514		if (channel > 14) {
3515			if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
3516				if (36 <= channel && channel <= 64)
3517					data = 0x114E9;
3518				else
3519					data = 0x110E9;
3520				rtl8821ae_phy_set_rf_reg(hw, path, RF_APK,
3521					BRFREGOFFSETMASK, data);
3522			}
3523		}
3524	}
3525	rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
3526}
3527
3528u8 rtl8821ae_phy_sw_chnl(struct ieee80211_hw *hw)
3529{
3530	struct rtl_priv *rtlpriv = rtl_priv(hw);
3531	struct rtl_phy *rtlphy = &rtlpriv->phy;
3532	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3533	u32 timeout = 1000, timecount = 0;
3534
3535	if (rtlphy->sw_chnl_inprogress)
3536		return 0;
3537	if (rtlphy->set_bwmode_inprogress)
3538		return 0;
3539
3540	if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) {
3541		rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD,
3542			"sw_chnl_inprogress false driver sleep or unload\n");
3543		return 0;
3544	}
3545	while (rtlphy->lck_inprogress && timecount < timeout) {
3546		mdelay(50);
3547		timecount += 50;
3548	}
3549
3550	if (rtlphy->current_channel > 14 && rtlhal->current_bandtype != BAND_ON_5G)
3551		rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_5G);
3552	else if (rtlphy->current_channel <= 14 && rtlhal->current_bandtype != BAND_ON_2_4G)
3553		rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_2_4G);
3554
3555	rtlphy->sw_chnl_inprogress = true;
3556
3557	rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE,
3558		"switch to channel%d, band type is %d\n",
3559		rtlphy->current_channel, rtlhal->current_bandtype);
3560
3561	rtl8821ae_phy_sw_chnl_callback(hw);
3562
3563	rtl8821ae_dm_clear_txpower_tracking_state(hw);
3564	rtl8821ae_phy_set_txpower_level(hw, rtlphy->current_channel);
3565
3566	rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
3567	rtlphy->sw_chnl_inprogress = false;
3568	return 1;
3569}
3570
3571u8 _rtl8812ae_get_right_chnl_place_for_iqk(u8 chnl)
3572{
3573	static const u8 channel_all[TARGET_CHNL_NUM_2G_5G_8812] = {
3574		1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
3575		14, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54,
3576		56, 58, 60, 62, 64, 100, 102, 104, 106, 108,
3577		110, 112, 114, 116, 118, 120, 122, 124, 126,
3578		128, 130, 132, 134, 136, 138, 140, 149, 151,
3579		153, 155, 157, 159, 161, 163, 165};
3580	u8 place;
3581
3582	if (chnl > 14) {
3583		for (place = 14; place < sizeof(channel_all); place++)
3584			if (channel_all[place] == chnl)
3585				return place-13;
3586	}
3587
3588	return 0;
3589}
3590
3591#define MACBB_REG_NUM 10
3592#define AFE_REG_NUM 14
3593#define RF_REG_NUM 3
3594
3595static void _rtl8821ae_iqk_backup_macbb(struct ieee80211_hw *hw,
3596					u32 *macbb_backup,
3597					u32 *backup_macbb_reg, u32 mac_bb_num)
3598{
3599	struct rtl_priv *rtlpriv = rtl_priv(hw);
3600	u32 i;
3601
3602	rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3603	/*save MACBB default value*/
3604	for (i = 0; i < mac_bb_num; i++)
3605		macbb_backup[i] = rtl_read_dword(rtlpriv, backup_macbb_reg[i]);
3606
3607	rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, "BackupMacBB Success!!!!\n");
3608}
3609
3610static void _rtl8821ae_iqk_backup_afe(struct ieee80211_hw *hw, u32 *afe_backup,
3611				      u32 *backup_afe_REG, u32 afe_num)
3612{
3613	struct rtl_priv *rtlpriv = rtl_priv(hw);
3614	u32 i;
3615
3616	rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3617	/*Save AFE Parameters */
3618	for (i = 0; i < afe_num; i++)
3619		afe_backup[i] = rtl_read_dword(rtlpriv, backup_afe_REG[i]);
3620	rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, "BackupAFE Success!!!!\n");
3621}
3622
3623static void _rtl8821ae_iqk_backup_rf(struct ieee80211_hw *hw, u32 *rfa_backup,
3624				     u32 *rfb_backup, u32 *backup_rf_reg,
3625				     u32 rf_num)
3626{
3627	struct rtl_priv *rtlpriv = rtl_priv(hw);
3628	u32 i;
3629
3630	rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3631	/*Save RF Parameters*/
3632	for (i = 0; i < rf_num; i++) {
3633		rfa_backup[i] = rtl_get_rfreg(hw, RF90_PATH_A, backup_rf_reg[i],
3634					      BMASKDWORD);
3635		rfb_backup[i] = rtl_get_rfreg(hw, RF90_PATH_B, backup_rf_reg[i],
3636					      BMASKDWORD);
3637	}
3638	rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, "BackupRF Success!!!!\n");
3639}
3640
3641static void _rtl8821ae_iqk_configure_mac(
3642		struct ieee80211_hw *hw
3643		)
3644{
3645	struct rtl_priv *rtlpriv = rtl_priv(hw);
3646	/* ========MAC register setting========*/
3647	rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3648	rtl_write_byte(rtlpriv, 0x522, 0x3f);
3649	rtl_set_bbreg(hw, 0x550, BIT(11) | BIT(3), 0x0);
3650	rtl_write_byte(rtlpriv, 0x808, 0x00);		/*RX ante off*/
3651	rtl_set_bbreg(hw, 0x838, 0xf, 0xc);		/*CCA off*/
3652}
3653
3654static void _rtl8821ae_iqk_tx_fill_iqc(struct ieee80211_hw *hw,
3655				       enum radio_path path, u32 tx_x, u32 tx_y)
3656{
3657	struct rtl_priv *rtlpriv = rtl_priv(hw);
3658	switch (path) {
3659	case RF90_PATH_A:
3660		/* [31] = 1 --> Page C1 */
3661		rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1);
3662		rtl_write_dword(rtlpriv, 0xc90, 0x00000080);
3663		rtl_write_dword(rtlpriv, 0xcc4, 0x20040000);
3664		rtl_write_dword(rtlpriv, 0xcc8, 0x20000000);
3665		rtl_set_bbreg(hw, 0xccc, 0x000007ff, tx_y);
3666		rtl_set_bbreg(hw, 0xcd4, 0x000007ff, tx_x);
3667		rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD,
3668			"TX_X = %x;;TX_Y = %x =====> fill to IQC\n",
3669			tx_x, tx_y);
3670		rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD,
3671			"0xcd4 = %x;;0xccc = %x ====>fill to IQC\n",
3672			rtl_get_bbreg(hw, 0xcd4, 0x000007ff),
3673			rtl_get_bbreg(hw, 0xccc, 0x000007ff));
3674		break;
3675	default:
3676		break;
3677	}
3678}
3679
3680static void _rtl8821ae_iqk_rx_fill_iqc(struct ieee80211_hw *hw,
3681				       enum radio_path path, u32 rx_x, u32 rx_y)
3682{
3683	struct rtl_priv *rtlpriv = rtl_priv(hw);
3684	switch (path) {
3685	case RF90_PATH_A:
3686		rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3687		rtl_set_bbreg(hw, 0xc10, 0x000003ff, rx_x>>1);
3688		rtl_set_bbreg(hw, 0xc10, 0x03ff0000, rx_y>>1);
3689		rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD,
3690			"rx_x = %x;;rx_y = %x ====>fill to IQC\n",
3691			rx_x >> 1, rx_y >> 1);
3692		rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD,
3693			"0xc10 = %x ====>fill to IQC\n",
3694			rtl_read_dword(rtlpriv, 0xc10));
3695		break;
3696	default:
3697		break;
3698	}
3699}
3700
3701#define cal_num 10
3702
3703static void _rtl8821ae_iqk_tx(struct ieee80211_hw *hw, enum radio_path path)
3704{
3705	struct rtl_priv *rtlpriv = rtl_priv(hw);
3706	struct rtl_phy *rtlphy = &rtlpriv->phy;
3707	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3708
3709	u32	tx_fail, rx_fail, delay_count, iqk_ready, cal_retry, cal = 0, temp_reg65;
3710	int	tx_x = 0, tx_y = 0, rx_x = 0, rx_y = 0, tx_average = 0, rx_average = 0;
3711	int	tx_x0[cal_num], tx_y0[cal_num], tx_x0_rxk[cal_num],
3712		tx_y0_rxk[cal_num], rx_x0[cal_num], rx_y0[cal_num],
3713		tx_dt[cal_num], rx_dt[cal_num];
3714	bool	tx0iqkok = false, rx0iqkok = false;
3715	bool	vdf_enable = false;
3716	int	i, k, vdf_y[3], vdf_x[3],
3717		ii, dx = 0, dy = 0, tx_finish = 0, rx_finish = 0;
3718
3719	rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD,
3720		"BandWidth = %d.\n",
3721		rtlphy->current_chan_bw);
3722	if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80)
3723		vdf_enable = true;
3724
3725	while (cal < cal_num) {
3726		switch (path) {
3727		case RF90_PATH_A:
3728			temp_reg65 = rtl_get_rfreg(hw, path, 0x65, 0xffffffff);
3729			/* Path-A LOK */
3730			rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3731			/*========Path-A AFE all on========*/
3732			/*Port 0 DAC/ADC on*/
3733			rtl_write_dword(rtlpriv, 0xc60, 0x77777777);
3734			rtl_write_dword(rtlpriv, 0xc64, 0x77777777);
3735			rtl_write_dword(rtlpriv, 0xc68, 0x19791979);
3736			rtl_write_dword(rtlpriv, 0xc6c, 0x19791979);
3737			rtl_write_dword(rtlpriv, 0xc70, 0x19791979);
3738			rtl_write_dword(rtlpriv, 0xc74, 0x19791979);
3739			rtl_write_dword(rtlpriv, 0xc78, 0x19791979);
3740			rtl_write_dword(rtlpriv, 0xc7c, 0x19791979);
3741			rtl_write_dword(rtlpriv, 0xc80, 0x19791979);
3742			rtl_write_dword(rtlpriv, 0xc84, 0x19791979);
3743
3744			rtl_set_bbreg(hw, 0xc00, 0xf, 0x4); /*hardware 3-wire off*/
3745
3746			/* LOK Setting */
3747			/* ====== LOK ====== */
3748			/*DAC/ADC sampling rate (160 MHz)*/
3749			rtl_set_bbreg(hw, 0xc5c, BIT(26) | BIT(25) | BIT(24), 0x7);
3750
3751			/* 2. LoK RF Setting (at BW = 20M) */
3752			rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80002);
3753			rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x3);     /* BW 20M */
3754			rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x20000);
3755			rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0003f);
3756			rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xf3fc3);
3757			rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d5);
3758			rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
3759			rtl_set_bbreg(hw, 0xcb8, 0xf, 0xd);
3760			rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
3761			rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
3762			rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1);
3763			rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
3764			rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
3765			rtl_write_dword(rtlpriv, 0x984, 0x00462910);/* [0]:AGC_en, [15]:idac_K_Mask */
3766
3767			rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3768			rtl_write_dword(rtlpriv, 0xc88, 0x821403f4);
3769
3770			if (rtlhal->current_bandtype)
3771				rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96);
3772			else
3773				rtl_write_dword(rtlpriv, 0xc8c, 0x28163e96);
3774
3775			rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3776			rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3777			rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8��\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3778			rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3779			rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3780
3781			mdelay(10); /* Delay 10ms */
3782			rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
3783
3784			rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3785			rtl_set_rfreg(hw, path, 0x58, 0x7fe00, rtl_get_rfreg(hw, path, 0x8, 0xffc00)); /* Load LOK */
3786
3787			switch (rtlphy->current_chan_bw) {
3788			case 1:
3789				rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x1);
3790				break;
3791			case 2:
3792				rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x0);
3793				break;
3794			default:
3795				break;
3796			}
3797
3798			rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3799
3800			/* 3. TX RF Setting */
3801			rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3802			rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
3803			rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x20000);
3804			rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0003f);
3805			rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xf3fc3);
3806			rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d5);
3807			rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
3808			rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
3809			/* ODM_SetBBReg(pDM_Odm, 0xcb8, 0xf, 0xd); */
3810			rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
3811			rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
3812			rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1);
3813			rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
3814			rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
3815			rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
3816
3817			rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3818			rtl_write_dword(rtlpriv, 0xc88, 0x821403f1);
3819			if (rtlhal->current_bandtype)
3820				rtl_write_dword(rtlpriv, 0xc8c, 0x40163e96);
3821			else
3822				rtl_write_dword(rtlpriv, 0xc8c, 0x00163e96);
3823
3824			if (vdf_enable) {
3825				rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, "VDF_enable\n");
3826				for (k = 0; k <= 2; k++) {
3827					switch (k) {
3828					case 0:
3829						rtl_write_dword(rtlpriv, 0xc80, 0x18008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3830						rtl_write_dword(rtlpriv, 0xc84, 0x38008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3831						rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);
3832						break;
3833					case 1:
3834						rtl_set_bbreg(hw, 0xc80, BIT(28), 0x0);
3835						rtl_set_bbreg(hw, 0xc84, BIT(28), 0x0);
3836						rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);
3837						break;
3838					case 2:
3839						rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD,
3840							"vdf_y[1] = %x;;;vdf_y[0] = %x\n", vdf_y[1]>>21 & 0x00007ff, vdf_y[0]>>21 & 0x00007ff);
3841						rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD,
3842							"vdf_x[1] = %x;;;vdf_x[0] = %x\n", vdf_x[1]>>21 & 0x00007ff, vdf_x[0]>>21 & 0x00007ff);
3843						tx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20);
3844						tx_dt[cal] = ((16*tx_dt[cal])*10000/15708);
3845						tx_dt[cal] = (tx_dt[cal] >> 1)+(tx_dt[cal] & BIT(0));
3846						rtl_write_dword(rtlpriv, 0xc80, 0x18008c20);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3847						rtl_write_dword(rtlpriv, 0xc84, 0x38008c20);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3848						rtl_set_bbreg(hw, 0xce8, BIT(31), 0x1);
3849						rtl_set_bbreg(hw, 0xce8, 0x3fff0000, tx_dt[cal] & 0x00003fff);
3850						break;
3851					default:
3852						break;
3853					}
3854					rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8��\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3855					cal_retry = 0;
3856					while (1) {
3857						/* one shot */
3858						rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3859						rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3860
3861						mdelay(10); /* Delay 10ms */
3862						rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
3863						delay_count = 0;
3864						while (1) {
3865							iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
3866							if ((~iqk_ready) || (delay_count > 20))
3867								break;
3868							else{
3869								mdelay(1);
3870								delay_count++;
3871							}
3872						}
3873
3874						if (delay_count < 20) {							/* If 20ms No Result, then cal_retry++ */
3875							/* ============TXIQK Check============== */
3876							tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
3877
3878							if (~tx_fail) {
3879								rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
3880								vdf_x[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
3881								rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
3882								vdf_y[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
3883								tx0iqkok = true;
3884								break;
3885							} else {
3886								rtl_set_bbreg(hw, 0xccc, 0x000007ff, 0x0);
3887								rtl_set_bbreg(hw, 0xcd4, 0x000007ff, 0x200);
3888								tx0iqkok = false;
3889								cal_retry++;
3890								if (cal_retry == 10)
3891									break;
3892							}
3893						} else {
3894							tx0iqkok = false;
3895							cal_retry++;
3896							if (cal_retry == 10)
3897								break;
3898						}
3899					}
3900				}
3901				if (k == 3) {
3902					tx_x0[cal] = vdf_x[k-1];
3903					tx_y0[cal] = vdf_y[k-1];
3904				}
3905			} else {
3906				rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3907				rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3908				rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8��\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3909				cal_retry = 0;
3910				while (1) {
3911					/* one shot */
3912					rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3913					rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3914
3915					mdelay(10); /* Delay 10ms */
3916					rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
3917					delay_count = 0;
3918					while (1) {
3919						iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
3920						if ((~iqk_ready) || (delay_count > 20))
3921							break;
3922						else{
3923							mdelay(1);
3924							delay_count++;
3925						}
3926					}
3927
3928					if (delay_count < 20) {							/* If 20ms No Result, then cal_retry++ */
3929						/* ============TXIQK Check============== */
3930						tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
3931
3932						if (~tx_fail) {
3933							rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
3934							tx_x0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
3935							rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
3936							tx_y0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
3937							tx0iqkok = true;
3938							break;
3939						} else {
3940							rtl_set_bbreg(hw, 0xccc, 0x000007ff, 0x0);
3941							rtl_set_bbreg(hw, 0xcd4, 0x000007ff, 0x200);
3942							tx0iqkok = false;
3943							cal_retry++;
3944							if (cal_retry == 10)
3945								break;
3946						}
3947					} else {
3948						tx0iqkok = false;
3949						cal_retry++;
3950						if (cal_retry == 10)
3951							break;
3952					}
3953				}
3954			}
3955
3956			if (!tx0iqkok)
3957				break;				/* TXK fail, Don't do RXK */
3958
3959			if (vdf_enable == 1) {
3960				rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);    /* TX VDF Disable */
3961				rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, "RXVDF Start\n");
3962				for (k = 0; k <= 2; k++) {
3963					/* ====== RX mode TXK (RXK Step 1) ====== */
3964					rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3965					/* 1. TX RF Setting */
3966					rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
3967					rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
3968					rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x00029);
3969					rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xd7ffb);
3970					rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
3971					rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
3972					rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
3973
3974					rtl_set_bbreg(hw, 0xcb8, 0xf, 0xd);
3975					rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
3976					rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
3977					rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
3978					rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
3979					rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
3980					rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3981					switch (k) {
3982					case 0:
3983						{
3984							rtl_write_dword(rtlpriv, 0xc80, 0x18008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3985							rtl_write_dword(rtlpriv, 0xc84, 0x38008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3986							rtl_set_bbreg(hw, 0xce8, BIT(30), 0x0);
3987						}
3988						break;
3989					case 1:
3990						{
3991							rtl_write_dword(rtlpriv, 0xc80, 0x08008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3992							rtl_write_dword(rtlpriv, 0xc84, 0x28008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3993							rtl_set_bbreg(hw, 0xce8, BIT(30), 0x0);
3994						}
3995						break;
3996					case 2:
3997						{
3998							rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD,
3999								"VDF_Y[1] = %x;;;VDF_Y[0] = %x\n",
4000								vdf_y[1] >> 21 & 0x00007ff,
4001								vdf_y[0] >> 21 & 0x00007ff);
4002							rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD,
4003								"VDF_X[1] = %x;;;VDF_X[0] = %x\n",
4004								vdf_x[1] >> 21 & 0x00007ff,
4005								vdf_x[0] >> 21 & 0x00007ff);
4006							rx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20);
4007							rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, "Rx_dt = %d\n",
4008								rx_dt[cal]);
4009							rx_dt[cal] = ((16*rx_dt[cal])*10000/13823);
4010							rx_dt[cal] = (rx_dt[cal] >> 1)+(rx_dt[cal] & BIT(0));
4011							rtl_write_dword(rtlpriv, 0xc80, 0x18008c20);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4012							rtl_write_dword(rtlpriv, 0xc84, 0x38008c20);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4013							rtl_set_bbreg(hw, 0xce8, 0x00003fff, rx_dt[cal] & 0x00003fff);
4014						}
4015						break;
4016					default:
4017						break;
4018					}
4019					rtl_write_dword(rtlpriv, 0xc88, 0x821603e0);
4020					rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96);
4021					rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8��\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4022					cal_retry = 0;
4023					while (1) {
4024						/* one shot */
4025						rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4026						rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4027
4028						mdelay(10); /* Delay 10ms */
4029						rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4030						delay_count = 0;
4031						while (1) {
4032							iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4033							if ((~iqk_ready) || (delay_count > 20))
4034								break;
4035							else{
4036								mdelay(1);
4037								delay_count++;
4038							}
4039						}
4040
4041						if (delay_count < 20) {							/* If 20ms No Result, then cal_retry++ */
4042							/* ============TXIQK Check============== */
4043							tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4044
4045							if (~tx_fail) {
4046								rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4047								tx_x0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4048								rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4049								tx_y0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4050								tx0iqkok = true;
4051								break;
4052							} else{
4053								tx0iqkok = false;
4054								cal_retry++;
4055								if (cal_retry == 10)
4056									break;
4057							}
4058						} else {
4059							tx0iqkok = false;
4060							cal_retry++;
4061							if (cal_retry == 10)
4062								break;
4063						}
4064					}
4065
4066					if (!tx0iqkok) {   /* If RX mode TXK fail, then take TXK Result */
4067						tx_x0_rxk[cal] = tx_x0[cal];
4068						tx_y0_rxk[cal] = tx_y0[cal];
4069						tx0iqkok = true;
4070						rtl_dbg(rtlpriv,
4071							COMP_IQK,
4072							DBG_LOUD,
4073							"RXK Step 1 fail\n");
4074					}
4075
4076					/* ====== RX IQK ====== */
4077					rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4078					/* 1. RX RF Setting */
4079					rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4080					rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4081					rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0002f);
4082					rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xfffbb);
4083					rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x88001);
4084					rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d8);
4085					rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4086
4087					rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0_rxk[cal])>>21&0x000007ff);
4088					rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0_rxk[cal])>>21&0x000007ff);
4089					rtl_set_bbreg(hw, 0x978, BIT(31), 0x1);
4090					rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0);
4091					rtl_set_bbreg(hw, 0xcb8, 0xF, 0xe);
4092					rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4093					rtl_write_dword(rtlpriv, 0x984, 0x0046a911);
4094
4095					rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4096					rtl_set_bbreg(hw, 0xc80, BIT(29), 0x1);
4097					rtl_set_bbreg(hw, 0xc84, BIT(29), 0x0);
4098					rtl_write_dword(rtlpriv, 0xc88, 0x02140119);
4099
4100					rtl_write_dword(rtlpriv, 0xc8c, 0x28160d00); /* pDM_Odm->SupportInterface == 1 */
4101
4102					if (k == 2)
4103						rtl_set_bbreg(hw, 0xce8, BIT(30), 0x1);  /* RX VDF Enable */
4104					rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8��\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4105
4106					cal_retry = 0;
4107					while (1) {
4108						/* one shot */
4109						rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4110						rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4111
4112						mdelay(10); /* Delay 10ms */
4113						rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4114						delay_count = 0;
4115						while (1) {
4116							iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4117							if ((~iqk_ready) || (delay_count > 20))
4118								break;
4119							else{
4120								mdelay(1);
4121								delay_count++;
4122							}
4123						}
4124
4125						if (delay_count < 20) {	/* If 20ms No Result, then cal_retry++ */
4126							/* ============RXIQK Check============== */
4127							rx_fail = rtl_get_bbreg(hw, 0xd00, BIT(11));
4128							if (rx_fail == 0) {
4129								rtl_write_dword(rtlpriv, 0xcb8, 0x06000000);
4130								vdf_x[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4131								rtl_write_dword(rtlpriv, 0xcb8, 0x08000000);
4132								vdf_y[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4133								rx0iqkok = true;
4134								break;
4135							} else {
4136								rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x200>>1);
4137								rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0x0>>1);
4138								rx0iqkok = false;
4139								cal_retry++;
4140								if (cal_retry == 10)
4141									break;
4142
4143							}
4144						} else{
4145							rx0iqkok = false;
4146							cal_retry++;
4147							if (cal_retry == 10)
4148								break;
4149						}
4150					}
4151
4152				}
4153				if (k == 3) {
4154					rx_x0[cal] = vdf_x[k-1];
4155					rx_y0[cal] = vdf_y[k-1];
4156				}
4157				rtl_set_bbreg(hw, 0xce8, BIT(31), 0x1);    /* TX VDF Enable */
4158			}
4159
4160			else{
4161				/* ====== RX mode TXK (RXK Step 1) ====== */
4162				rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4163				/* 1. TX RF Setting */
4164				rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4165				rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4166				rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x00029);
4167				rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xd7ffb);
4168				rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4169				rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
4170				rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4171				rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4172				rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
4173				rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
4174
4175				rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4176				rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4177				rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4178				rtl_write_dword(rtlpriv, 0xc88, 0x821603e0);
4179				/* ODM_Write4Byte(pDM_Odm, 0xc8c, 0x68163e96); */
4180				rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8��\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4181				cal_retry = 0;
4182				while (1) {
4183					/* one shot */
4184					rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4185					rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4186
4187					mdelay(10); /* Delay 10ms */
4188					rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4189					delay_count = 0;
4190					while (1) {
4191						iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4192						if ((~iqk_ready) || (delay_count > 20))
4193							break;
4194						else{
4195							mdelay(1);
4196							delay_count++;
4197						}
4198					}
4199
4200					if (delay_count < 20) {							/* If 20ms No Result, then cal_retry++ */
4201						/* ============TXIQK Check============== */
4202						tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4203
4204						if (~tx_fail) {
4205							rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4206							tx_x0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4207							rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4208							tx_y0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4209							tx0iqkok = true;
4210							break;
4211						} else {
4212							tx0iqkok = false;
4213							cal_retry++;
4214							if (cal_retry == 10)
4215								break;
4216						}
4217					} else{
4218						tx0iqkok = false;
4219						cal_retry++;
4220						if (cal_retry == 10)
4221							break;
4222					}
4223				}
4224
4225				if (!tx0iqkok) {   /* If RX mode TXK fail, then take TXK Result */
4226					tx_x0_rxk[cal] = tx_x0[cal];
4227					tx_y0_rxk[cal] = tx_y0[cal];
4228					tx0iqkok = true;
4229					rtl_dbg(rtlpriv, COMP_IQK,
4230						DBG_LOUD, "1");
4231				}
4232
4233				/* ====== RX IQK ====== */
4234				rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4235				/* 1. RX RF Setting */
4236				rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4237				rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4238				rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0002f);
4239				rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xfffbb);
4240				rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x88001);
4241				rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d8);
4242				rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4243
4244				rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0_rxk[cal])>>21&0x000007ff);
4245				rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0_rxk[cal])>>21&0x000007ff);
4246				rtl_set_bbreg(hw, 0x978, BIT(31), 0x1);
4247				rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0);
4248				/* ODM_SetBBReg(pDM_Odm, 0xcb8, 0xF, 0xe); */
4249				rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4250				rtl_write_dword(rtlpriv, 0x984, 0x0046a911);
4251
4252				rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4253				rtl_write_dword(rtlpriv, 0xc80, 0x38008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4254				rtl_write_dword(rtlpriv, 0xc84, 0x18008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4255				rtl_write_dword(rtlpriv, 0xc88, 0x02140119);
4256
4257				rtl_write_dword(rtlpriv, 0xc8c, 0x28160d00); /*pDM_Odm->SupportInterface == 1*/
4258
4259				rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8��\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4260
4261				cal_retry = 0;
4262				while (1) {
4263					/* one shot */
4264					rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4265					rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4266
4267					mdelay(10); /* Delay 10ms */
4268					rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4269					delay_count = 0;
4270					while (1) {
4271						iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4272						if ((~iqk_ready) || (delay_count > 20))
4273							break;
4274						else{
4275							mdelay(1);
4276							delay_count++;
4277						}
4278					}
4279
4280					if (delay_count < 20) {	/* If 20ms No Result, then cal_retry++ */
4281						/* ============RXIQK Check============== */
4282						rx_fail = rtl_get_bbreg(hw, 0xd00, BIT(11));
4283						if (rx_fail == 0) {
4284							rtl_write_dword(rtlpriv, 0xcb8, 0x06000000);
4285							rx_x0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4286							rtl_write_dword(rtlpriv, 0xcb8, 0x08000000);
4287							rx_y0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4288							rx0iqkok = true;
4289							break;
4290						} else{
4291							rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x200>>1);
4292							rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0x0>>1);
4293							rx0iqkok = false;
4294							cal_retry++;
4295							if (cal_retry == 10)
4296								break;
4297
4298						}
4299					} else{
4300						rx0iqkok = false;
4301						cal_retry++;
4302						if (cal_retry == 10)
4303							break;
4304					}
4305				}
4306			}
4307
4308			if (tx0iqkok)
4309				tx_average++;
4310			if (rx0iqkok)
4311				rx_average++;
4312			rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4313			rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4314			break;
4315		default:
4316			break;
4317		}
4318		cal++;
4319	}
4320
4321	/* FillIQK Result */
4322	switch (path) {
4323	case RF90_PATH_A:
4324		rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD,
4325			"========Path_A =======\n");
4326		if (tx_average == 0)
4327			break;
4328
4329		for (i = 0; i < tx_average; i++) {
4330			rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD,
4331				"TX_X0_RXK[%d] = %x ;; TX_Y0_RXK[%d] = %x\n", i,
4332				(tx_x0_rxk[i]) >> 21 & 0x000007ff, i,
4333				(tx_y0_rxk[i]) >> 21 & 0x000007ff);
4334			rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD,
4335				"TX_X0[%d] = %x ;; TX_Y0[%d] = %x\n", i,
4336				(tx_x0[i]) >> 21 & 0x000007ff, i,
4337				(tx_y0[i]) >> 21 & 0x000007ff);
4338		}
4339		for (i = 0; i < tx_average; i++) {
4340			for (ii = i+1; ii < tx_average; ii++) {
4341				dx = (tx_x0[i]>>21) - (tx_x0[ii]>>21);
4342				if (dx < 3 && dx > -3) {
4343					dy = (tx_y0[i]>>21) - (tx_y0[ii]>>21);
4344					if (dy < 3 && dy > -3) {
4345						tx_x = ((tx_x0[i]>>21) + (tx_x0[ii]>>21))/2;
4346						tx_y = ((tx_y0[i]>>21) + (tx_y0[ii]>>21))/2;
4347						tx_finish = 1;
4348						break;
4349					}
4350				}
4351			}
4352			if (tx_finish == 1)
4353				break;
4354		}
4355
4356		if (tx_finish == 1)
4357			_rtl8821ae_iqk_tx_fill_iqc(hw, path, tx_x, tx_y); /* ? */
4358		else
4359			_rtl8821ae_iqk_tx_fill_iqc(hw, path, 0x200, 0x0);
4360
4361		if (rx_average == 0)
4362			break;
4363
4364		for (i = 0; i < rx_average; i++)
4365			rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD,
4366				"RX_X0[%d] = %x ;; RX_Y0[%d] = %x\n", i,
4367				(rx_x0[i])>>21&0x000007ff, i,
4368				(rx_y0[i])>>21&0x000007ff);
4369		for (i = 0; i < rx_average; i++) {
4370			for (ii = i+1; ii < rx_average; ii++) {
4371				dx = (rx_x0[i]>>21) - (rx_x0[ii]>>21);
4372				if (dx < 4 && dx > -4) {
4373					dy = (rx_y0[i]>>21) - (rx_y0[ii]>>21);
4374					if (dy < 4 && dy > -4) {
4375						rx_x = ((rx_x0[i]>>21) + (rx_x0[ii]>>21))/2;
4376						rx_y = ((rx_y0[i]>>21) + (rx_y0[ii]>>21))/2;
4377						rx_finish = 1;
4378						break;
4379					}
4380				}
4381			}
4382			if (rx_finish == 1)
4383				break;
4384		}
4385
4386		if (rx_finish == 1)
4387			_rtl8821ae_iqk_rx_fill_iqc(hw, path, rx_x, rx_y);
4388		else
4389			_rtl8821ae_iqk_rx_fill_iqc(hw, path, 0x200, 0x0);
4390		break;
4391	default:
4392		break;
4393	}
4394}
4395
4396static void _rtl8821ae_iqk_restore_rf(struct ieee80211_hw *hw,
4397				      enum radio_path path,
4398				      u32 *backup_rf_reg,
4399				      u32 *rf_backup, u32 rf_reg_num)
4400{
4401	struct rtl_priv *rtlpriv = rtl_priv(hw);
4402	u32 i;
4403
4404	rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4405	for (i = 0; i < RF_REG_NUM; i++)
4406		rtl_set_rfreg(hw, path, backup_rf_reg[i], RFREG_OFFSET_MASK,
4407			      rf_backup[i]);
4408
4409	switch (path) {
4410	case RF90_PATH_A:
4411		rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD,
4412			"RestoreRF Path A Success!!!!\n");
4413		break;
4414	default:
4415			break;
4416	}
4417}
4418
4419static void _rtl8821ae_iqk_restore_afe(struct ieee80211_hw *hw,
4420				       u32 *afe_backup, u32 *backup_afe_reg,
4421				       u32 afe_num)
4422{
4423	u32 i;
4424	struct rtl_priv *rtlpriv = rtl_priv(hw);
4425
4426	rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4427	/* Reload AFE Parameters */
4428	for (i = 0; i < afe_num; i++)
4429		rtl_write_dword(rtlpriv, backup_afe_reg[i], afe_backup[i]);
4430	rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4431	rtl_write_dword(rtlpriv, 0xc80, 0x0);
4432	rtl_write_dword(rtlpriv, 0xc84, 0x0);
4433	rtl_write_dword(rtlpriv, 0xc88, 0x0);
4434	rtl_write_dword(rtlpriv, 0xc8c, 0x3c000000);
4435	rtl_write_dword(rtlpriv, 0xc90, 0x00000080);
4436	rtl_write_dword(rtlpriv, 0xc94, 0x00000000);
4437	rtl_write_dword(rtlpriv, 0xcc4, 0x20040000);
4438	rtl_write_dword(rtlpriv, 0xcc8, 0x20000000);
4439	rtl_write_dword(rtlpriv, 0xcb8, 0x0);
4440	rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, "RestoreAFE Success!!!!\n");
4441}
4442
4443static void _rtl8821ae_iqk_restore_macbb(struct ieee80211_hw *hw,
4444					 u32 *macbb_backup,
4445					 u32 *backup_macbb_reg,
4446					 u32 macbb_num)
4447{
4448	u32 i;
4449	struct rtl_priv *rtlpriv = rtl_priv(hw);
4450
4451	rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4452	/* Reload MacBB Parameters */
4453	for (i = 0; i < macbb_num; i++)
4454		rtl_write_dword(rtlpriv, backup_macbb_reg[i], macbb_backup[i]);
4455	rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD, "RestoreMacBB Success!!!!\n");
4456}
4457
4458#undef MACBB_REG_NUM
4459#undef AFE_REG_NUM
4460#undef RF_REG_NUM
4461
4462#define MACBB_REG_NUM 11
4463#define AFE_REG_NUM 12
4464#define RF_REG_NUM 3
4465
4466static void _rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw)
4467{
4468	u32	macbb_backup[MACBB_REG_NUM];
4469	u32 afe_backup[AFE_REG_NUM];
4470	u32 rfa_backup[RF_REG_NUM];
4471	u32 rfb_backup[RF_REG_NUM];
4472	u32 backup_macbb_reg[MACBB_REG_NUM] = {
4473		0xb00, 0x520, 0x550, 0x808, 0x90c, 0xc00, 0xc50,
4474		0xe00, 0xe50, 0x838, 0x82c
4475	};
4476	u32 backup_afe_reg[AFE_REG_NUM] = {
4477		0xc5c, 0xc60, 0xc64, 0xc68, 0xc6c, 0xc70, 0xc74,
4478		0xc78, 0xc7c, 0xc80, 0xc84, 0xcb8
4479	};
4480	u32	backup_rf_reg[RF_REG_NUM] = {0x65, 0x8f, 0x0};
4481
4482	_rtl8821ae_iqk_backup_macbb(hw, macbb_backup, backup_macbb_reg,
4483				    MACBB_REG_NUM);
4484	_rtl8821ae_iqk_backup_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM);
4485	_rtl8821ae_iqk_backup_rf(hw, rfa_backup, rfb_backup, backup_rf_reg,
4486				 RF_REG_NUM);
4487
4488	_rtl8821ae_iqk_configure_mac(hw);
4489	_rtl8821ae_iqk_tx(hw, RF90_PATH_A);
4490	_rtl8821ae_iqk_restore_rf(hw, RF90_PATH_A, backup_rf_reg, rfa_backup,
4491				  RF_REG_NUM);
4492
4493	_rtl8821ae_iqk_restore_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM);
4494	_rtl8821ae_iqk_restore_macbb(hw, macbb_backup, backup_macbb_reg,
4495				     MACBB_REG_NUM);
4496}
4497
4498static void _rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool main)
4499{
4500	struct rtl_priv *rtlpriv = rtl_priv(hw);
4501	/* struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); */
4502	/* struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); */
4503	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
4504
4505	if (main)
4506		rtl_set_bbreg(hw, RA_RFE_PINMUX + 4, BIT(29) | BIT(28), 0x1);
4507	else
4508		rtl_set_bbreg(hw, RA_RFE_PINMUX + 4, BIT(29) | BIT(28), 0x2);
4509}
4510
4511#undef IQK_ADDA_REG_NUM
4512#undef IQK_DELAY_TIME
4513
4514void rtl8812ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
4515{
4516}
4517
4518void rtl8812ae_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index,
4519		      u8 thermal_value, u8 threshold)
4520{
4521	struct rtl_dm	*rtldm = rtl_dm(rtl_priv(hw));
4522
4523	rtldm->thermalvalue_iqk = thermal_value;
4524	rtl8812ae_phy_iq_calibrate(hw, false);
4525}
4526
4527void rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
4528{
4529	struct rtl_priv *rtlpriv = rtl_priv(hw);
4530	struct rtl_phy *rtlphy = &rtlpriv->phy;
4531
4532	if (!rtlphy->lck_inprogress) {
4533		spin_lock(&rtlpriv->locks.iqk_lock);
4534		rtlphy->lck_inprogress = true;
4535		spin_unlock(&rtlpriv->locks.iqk_lock);
4536
4537		_rtl8821ae_phy_iq_calibrate(hw);
4538
4539		spin_lock(&rtlpriv->locks.iqk_lock);
4540		rtlphy->lck_inprogress = false;
4541		spin_unlock(&rtlpriv->locks.iqk_lock);
4542	}
4543}
4544
4545void rtl8821ae_reset_iqk_result(struct ieee80211_hw *hw)
4546{
4547	struct rtl_priv *rtlpriv = rtl_priv(hw);
4548	struct rtl_phy *rtlphy = &rtlpriv->phy;
4549	u8 i;
4550
4551	rtl_dbg(rtlpriv, COMP_IQK, DBG_LOUD,
4552		"rtl8812ae_dm_reset_iqk_result:: settings regs %d default regs %d\n",
4553		(int)(sizeof(rtlphy->iqk_matrix) /
4554		sizeof(struct iqk_matrix_regs)),
4555		IQK_MATRIX_SETTINGS_NUM);
4556
4557	for (i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) {
4558		rtlphy->iqk_matrix[i].value[0][0] = 0x100;
4559		rtlphy->iqk_matrix[i].value[0][2] = 0x100;
4560		rtlphy->iqk_matrix[i].value[0][4] = 0x100;
4561		rtlphy->iqk_matrix[i].value[0][6] = 0x100;
4562
4563		rtlphy->iqk_matrix[i].value[0][1] = 0x0;
4564		rtlphy->iqk_matrix[i].value[0][3] = 0x0;
4565		rtlphy->iqk_matrix[i].value[0][5] = 0x0;
4566		rtlphy->iqk_matrix[i].value[0][7] = 0x0;
4567
4568		rtlphy->iqk_matrix[i].iqk_done = false;
4569	}
4570}
4571
4572void rtl8821ae_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index,
4573		      u8 thermal_value, u8 threshold)
4574{
4575	struct rtl_dm	*rtldm = rtl_dm(rtl_priv(hw));
4576
4577	rtl8821ae_reset_iqk_result(hw);
4578
4579	rtldm->thermalvalue_iqk = thermal_value;
4580	rtl8821ae_phy_iq_calibrate(hw, false);
4581}
4582
4583void rtl8821ae_phy_lc_calibrate(struct ieee80211_hw *hw)
4584{
4585}
4586
4587void rtl8821ae_phy_ap_calibrate(struct ieee80211_hw *hw, s8 delta)
4588{
4589}
4590
4591void rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
4592{
4593	_rtl8821ae_phy_set_rfpath_switch(hw, bmain);
4594}
4595
4596bool rtl8821ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
4597{
4598	struct rtl_priv *rtlpriv = rtl_priv(hw);
4599	struct rtl_phy *rtlphy = &rtlpriv->phy;
4600	bool postprocessing = false;
4601
4602	rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE,
4603		"-->IO Cmd(%#x), set_io_inprogress(%d)\n",
4604		iotype, rtlphy->set_io_inprogress);
4605	do {
4606		switch (iotype) {
4607		case IO_CMD_RESUME_DM_BY_SCAN:
4608			rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE,
4609				"[IO CMD] Resume DM after scan.\n");
4610			postprocessing = true;
4611			break;
4612		case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
4613		case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
4614			rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE,
4615				"[IO CMD] Pause DM before scan.\n");
4616			postprocessing = true;
4617			break;
4618		default:
4619			pr_err("switch case %#x not processed\n",
4620			       iotype);
4621			break;
4622		}
4623	} while (false);
4624	if (postprocessing && !rtlphy->set_io_inprogress) {
4625		rtlphy->set_io_inprogress = true;
4626		rtlphy->current_io_type = iotype;
4627	} else {
4628		return false;
4629	}
4630	rtl8821ae_phy_set_io(hw);
4631	rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
4632	return true;
4633}
4634
4635static void rtl8821ae_phy_set_io(struct ieee80211_hw *hw)
4636{
4637	struct rtl_priv *rtlpriv = rtl_priv(hw);
4638	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
4639	struct rtl_phy *rtlphy = &rtlpriv->phy;
4640
4641	rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE,
4642		"--->Cmd(%#x), set_io_inprogress(%d)\n",
4643		rtlphy->current_io_type, rtlphy->set_io_inprogress);
4644	switch (rtlphy->current_io_type) {
4645	case IO_CMD_RESUME_DM_BY_SCAN:
4646		if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
4647			_rtl8821ae_resume_tx_beacon(hw);
4648		rtl8821ae_dm_write_dig(hw, rtlphy->initgain_backup.xaagccore1);
4649		rtl8821ae_dm_write_cck_cca_thres(hw,
4650						 rtlphy->initgain_backup.cca);
4651		break;
4652	case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
4653		if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
4654			_rtl8821ae_stop_tx_beacon(hw);
4655		rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
4656		rtl8821ae_dm_write_dig(hw, 0x17);
4657		rtlphy->initgain_backup.cca = dm_digtable->cur_cck_cca_thres;
4658		rtl8821ae_dm_write_cck_cca_thres(hw, 0x40);
4659		break;
4660	case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
4661		break;
4662	default:
4663		pr_err("switch case %#x not processed\n",
4664		       rtlphy->current_io_type);
4665		break;
4666	}
4667	rtlphy->set_io_inprogress = false;
4668	rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE,
4669		"(%#x)\n", rtlphy->current_io_type);
4670}
4671
4672static void rtl8821ae_phy_set_rf_on(struct ieee80211_hw *hw)
4673{
4674	struct rtl_priv *rtlpriv = rtl_priv(hw);
4675
4676	rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
4677	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
4678	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
4679	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
4680	rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
4681}
4682
4683static bool _rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
4684					      enum rf_pwrstate rfpwr_state)
4685{
4686	struct rtl_priv *rtlpriv = rtl_priv(hw);
4687	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
4688	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
4689	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
4690	bool bresult = true;
4691	u8 i, queue_id;
4692	struct rtl8192_tx_ring *ring = NULL;
4693
4694	switch (rfpwr_state) {
4695	case ERFON:
4696		if ((ppsc->rfpwr_state == ERFOFF) &&
4697		    RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
4698			bool rtstatus = false;
4699			u32 initializecount = 0;
4700
4701			do {
4702				initializecount++;
4703				rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,
4704					"IPS Set eRf nic enable\n");
4705				rtstatus = rtl_ps_enable_nic(hw);
4706			} while (!rtstatus && (initializecount < 10));
4707			RT_CLEAR_PS_LEVEL(ppsc,
4708					  RT_RF_OFF_LEVL_HALT_NIC);
4709		} else {
4710			rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,
4711				"Set ERFON slept:%d ms\n",
4712				jiffies_to_msecs(jiffies -
4713						 ppsc->last_sleep_jiffies));
4714			ppsc->last_awake_jiffies = jiffies;
4715			rtl8821ae_phy_set_rf_on(hw);
4716		}
4717		if (mac->link_state == MAC80211_LINKED) {
4718			rtlpriv->cfg->ops->led_control(hw,
4719						       LED_CTL_LINK);
4720		} else {
4721			rtlpriv->cfg->ops->led_control(hw,
4722						       LED_CTL_NO_LINK);
4723		}
4724		break;
4725	case ERFOFF:
4726		for (queue_id = 0, i = 0;
4727		     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
4728			ring = &pcipriv->dev.tx_ring[queue_id];
4729			if (queue_id == BEACON_QUEUE ||
4730			    skb_queue_len(&ring->queue) == 0) {
4731				queue_id++;
4732				continue;
4733			} else {
4734				rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
4735					"eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
4736					(i + 1), queue_id,
4737					skb_queue_len(&ring->queue));
4738
4739				udelay(10);
4740				i++;
4741			}
4742			if (i >= MAX_DOZE_WAITING_TIMES_9x) {
4743				rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
4744					"\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
4745					MAX_DOZE_WAITING_TIMES_9x,
4746					queue_id,
4747					skb_queue_len(&ring->queue));
4748				break;
4749			}
4750		}
4751
4752		if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
4753			rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,
4754				"IPS Set eRf nic disable\n");
4755			rtl_ps_disable_nic(hw);
4756			RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
4757		} else {
4758			if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
4759				rtlpriv->cfg->ops->led_control(hw,
4760							       LED_CTL_NO_LINK);
4761			} else {
4762				rtlpriv->cfg->ops->led_control(hw,
4763							       LED_CTL_POWER_OFF);
4764			}
4765		}
4766		break;
4767	default:
4768		pr_err("switch case %#x not processed\n",
4769		       rfpwr_state);
4770		bresult = false;
4771		break;
4772	}
4773	if (bresult)
4774		ppsc->rfpwr_state = rfpwr_state;
4775	return bresult;
4776}
4777
4778bool rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
4779				      enum rf_pwrstate rfpwr_state)
4780{
4781	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
4782
4783	bool bresult = false;
4784
4785	if (rfpwr_state == ppsc->rfpwr_state)
4786		return bresult;
4787	bresult = _rtl8821ae_phy_set_rf_power_state(hw, rfpwr_state);
4788	return bresult;
4789}
4790