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