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