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