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