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