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 	char i = 0;
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 channel_5g[CHANNEL_MAX_NUMBER_5G] = {
1476 		36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64,
1477 		100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122,
1478 		124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 149,
1479 		151, 153, 155, 157, 159, 161, 163, 165, 167, 168, 169, 171,
1480 		173, 175, 177};
1481 	u8  i = 0;
1482 	if (band == BAND_ON_2_4G)
1483 		channel_index = channel - 1;
1484 	else if (band == BAND_ON_5G) {
1485 		for (i = 0; i < sizeof(channel_5g)/sizeof(u8); ++i) {
1486 			if (channel_5g[i] == channel)
1487 				channel_index = i;
1488 		}
1489 	} else
1490 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid Band %d in %s",
1491 			 band,  __func__);
1492 
1493 	if (channel_index == -1)
1494 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1495 			 "Invalid Channel %d of Band %d in %s", channel,
1496 			 band, __func__);
1497 
1498 	return channel_index;
1499 }
1500 
1501 static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregulation,
1502 				      u8 *pband, u8 *pbandwidth,
1503 				      u8 *prate_section, u8 *prf_path,
1504 				      u8 *pchannel, u8 *ppower_limit)
1505 {
1506 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1507 	struct rtl_phy *rtlphy = &rtlpriv->phy;
1508 	u8 regulation = 0, bandwidth = 0, rate_section = 0, channel;
1509 	u8 channel_index;
1510 	char power_limit = 0, prev_power_limit, ret;
1511 
1512 	if (!_rtl8812ae_get_integer_from_string((char *)pchannel, &channel) ||
1513 	    !_rtl8812ae_get_integer_from_string((char *)ppower_limit,
1514 						&power_limit)) {
1515 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1516 			 "Illegal index of pwr_lmt table [chnl %d][val %d]\n",
1517 			  channel, power_limit);
1518 	}
1519 
1520 	power_limit = power_limit > MAX_POWER_INDEX ?
1521 		      MAX_POWER_INDEX : power_limit;
1522 
1523 	if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("FCC"), 3))
1524 		regulation = 0;
1525 	else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("MKK"), 3))
1526 		regulation = 1;
1527 	else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("ETSI"), 4))
1528 		regulation = 2;
1529 	else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("WW13"), 4))
1530 		regulation = 3;
1531 
1532 	if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("CCK"), 3))
1533 		rate_section = 0;
1534 	else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("OFDM"), 4))
1535 		rate_section = 1;
1536 	else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
1537 		 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("1T"), 2))
1538 		rate_section = 2;
1539 	else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
1540 		 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("2T"), 2))
1541 		rate_section = 3;
1542 	else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
1543 		 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("1T"), 2))
1544 		rate_section = 4;
1545 	else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
1546 		 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("2T"), 2))
1547 		rate_section = 5;
1548 
1549 	if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("20M"), 3))
1550 		bandwidth = 0;
1551 	else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("40M"), 3))
1552 		bandwidth = 1;
1553 	else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("80M"), 3))
1554 		bandwidth = 2;
1555 	else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("160M"), 4))
1556 		bandwidth = 3;
1557 
1558 	if (_rtl8812ae_eq_n_byte(pband, (u8 *)("2.4G"), 4)) {
1559 		ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
1560 							       BAND_ON_2_4G,
1561 							       channel);
1562 
1563 		if (ret == -1)
1564 			return;
1565 
1566 		channel_index = ret;
1567 
1568 		prev_power_limit = rtlphy->txpwr_limit_2_4g[regulation]
1569 						[bandwidth][rate_section]
1570 						[channel_index][RF90_PATH_A];
1571 
1572 		if (power_limit < prev_power_limit)
1573 			rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
1574 				[rate_section][channel_index][RF90_PATH_A] =
1575 								   power_limit;
1576 
1577 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1578 			 "2.4G [regula %d][bw %d][sec %d][chnl %d][val %d]\n",
1579 			  regulation, bandwidth, rate_section, channel_index,
1580 			  rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
1581 				[rate_section][channel_index][RF90_PATH_A]);
1582 	} else if (_rtl8812ae_eq_n_byte(pband, (u8 *)("5G"), 2)) {
1583 		ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
1584 							       BAND_ON_5G,
1585 							       channel);
1586 
1587 		if (ret == -1)
1588 			return;
1589 
1590 		channel_index = ret;
1591 
1592 		prev_power_limit = rtlphy->txpwr_limit_5g[regulation][bandwidth]
1593 						[rate_section][channel_index]
1594 						[RF90_PATH_A];
1595 
1596 		if (power_limit < prev_power_limit)
1597 			rtlphy->txpwr_limit_5g[regulation][bandwidth]
1598 			[rate_section][channel_index][RF90_PATH_A] = power_limit;
1599 
1600 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1601 			 "5G: [regul %d][bw %d][sec %d][chnl %d][val %d]\n",
1602 			  regulation, bandwidth, rate_section, channel,
1603 			  rtlphy->txpwr_limit_5g[regulation][bandwidth]
1604 				[rate_section][channel_index][RF90_PATH_A]);
1605 	} else {
1606 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1607 			 "Cannot recognize the band info in %s\n", pband);
1608 		return;
1609 	}
1610 }
1611 
1612 static void _rtl8812ae_phy_config_bb_txpwr_lmt(struct ieee80211_hw *hw,
1613 					  u8 *regulation, u8 *band,
1614 					  u8 *bandwidth, u8 *rate_section,
1615 					  u8 *rf_path, u8 *channel,
1616 					  u8 *power_limit)
1617 {
1618 	_rtl8812ae_phy_set_txpower_limit(hw, regulation, band, bandwidth,
1619 					 rate_section, rf_path, channel,
1620 					 power_limit);
1621 }
1622 
1623 static void _rtl8821ae_phy_read_and_config_txpwr_lmt(struct ieee80211_hw *hw)
1624 {
1625 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1626 	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1627 	u32 i = 0;
1628 	u32 array_len;
1629 	u8 **array;
1630 
1631 	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1632 		array_len = RTL8812AE_TXPWR_LMT_ARRAY_LEN;
1633 		array = RTL8812AE_TXPWR_LMT;
1634 	} else {
1635 		array_len = RTL8821AE_TXPWR_LMT_ARRAY_LEN;
1636 		array = RTL8821AE_TXPWR_LMT;
1637 	}
1638 
1639 	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1640 		 "\n");
1641 
1642 	for (i = 0; i < array_len; i += 7) {
1643 		u8 *regulation = array[i];
1644 		u8 *band = array[i+1];
1645 		u8 *bandwidth = array[i+2];
1646 		u8 *rate = array[i+3];
1647 		u8 *rf_path = array[i+4];
1648 		u8 *chnl = array[i+5];
1649 		u8 *val = array[i+6];
1650 
1651 		_rtl8812ae_phy_config_bb_txpwr_lmt(hw, regulation, band,
1652 						   bandwidth, rate, rf_path,
1653 						   chnl, val);
1654 	}
1655 }
1656 
1657 static bool _rtl8821ae_phy_bb8821a_config_parafile(struct ieee80211_hw *hw)
1658 {
1659 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1660 	struct rtl_phy *rtlphy = &rtlpriv->phy;
1661 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1662 	bool rtstatus;
1663 
1664 	_rtl8821ae_phy_init_txpower_limit(hw);
1665 
1666 	/* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
1667 	if (rtlefuse->eeprom_regulatory != 2)
1668 		_rtl8821ae_phy_read_and_config_txpwr_lmt(hw);
1669 
1670 	rtstatus = _rtl8821ae_phy_config_bb_with_headerfile(hw,
1671 						       BASEBAND_CONFIG_PHY_REG);
1672 	if (rtstatus != true) {
1673 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!");
1674 		return false;
1675 	}
1676 	_rtl8821ae_phy_init_tx_power_by_rate(hw);
1677 	if (rtlefuse->autoload_failflag == false) {
1678 		rtstatus = _rtl8821ae_phy_config_bb_with_pgheaderfile(hw,
1679 						    BASEBAND_CONFIG_PHY_REG);
1680 	}
1681 	if (rtstatus != true) {
1682 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!");
1683 		return false;
1684 	}
1685 
1686 	_rtl8821ae_phy_txpower_by_rate_configuration(hw);
1687 
1688 	/* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
1689 	if (rtlefuse->eeprom_regulatory != 2)
1690 		_rtl8812ae_phy_convert_txpower_limit_to_power_index(hw);
1691 
1692 	rtstatus = _rtl8821ae_phy_config_bb_with_headerfile(hw,
1693 						BASEBAND_CONFIG_AGC_TAB);
1694 
1695 	if (rtstatus != true) {
1696 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
1697 		return false;
1698 	}
1699 	rtlphy->cck_high_power = (bool)(rtl_get_bbreg(hw,
1700 			RFPGA0_XA_HSSIPARAMETER2, 0x200));
1701 	return true;
1702 }
1703 
1704 static bool _rtl8821ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
1705 {
1706 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1707 	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1708 	u32 i, v1, v2;
1709 	u32 arraylength;
1710 	u32 *ptrarray;
1711 
1712 	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read MAC_REG_Array\n");
1713 	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
1714 		arraylength = RTL8821AEMAC_1T_ARRAYLEN;
1715 		ptrarray = RTL8821AE_MAC_REG_ARRAY;
1716 	} else {
1717 		arraylength = RTL8812AEMAC_1T_ARRAYLEN;
1718 		ptrarray = RTL8812AE_MAC_REG_ARRAY;
1719 	}
1720 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1721 		 "Img: MAC_REG_ARRAY LEN %d\n", arraylength);
1722 	for (i = 0; i < arraylength; i += 2) {
1723 		v1 = ptrarray[i];
1724 		v2 = (u8)ptrarray[i + 1];
1725 		if (v1 < 0xCDCDCDCD) {
1726 			rtl_write_byte(rtlpriv, v1, (u8)v2);
1727 			continue;
1728 		} else {
1729 			if (!_rtl8821ae_check_condition(hw, v1)) {
1730 				/*Discard the following (offset, data) pairs*/
1731 				READ_NEXT_PAIR(ptrarray, v1, v2, i);
1732 				while (v2 != 0xDEAD &&
1733 				       v2 != 0xCDEF &&
1734 				       v2 != 0xCDCD && i < arraylength - 2) {
1735 					READ_NEXT_PAIR(ptrarray, v1, v2, i);
1736 				}
1737 				i -= 2; /* prevent from for-loop += 2*/
1738 			} else {/*Configure matched pairs and skip to end of if-else.*/
1739 				READ_NEXT_PAIR(ptrarray, v1, v2, i);
1740 				while (v2 != 0xDEAD &&
1741 				       v2 != 0xCDEF &&
1742 				       v2 != 0xCDCD && i < arraylength - 2) {
1743 					rtl_write_byte(rtlpriv, v1, v2);
1744 					READ_NEXT_PAIR(ptrarray, v1, v2, i);
1745 				}
1746 
1747 				while (v2 != 0xDEAD && i < arraylength - 2)
1748 					READ_NEXT_PAIR(ptrarray, v1, v2, i);
1749 			}
1750 		}
1751 	}
1752 	return true;
1753 }
1754 
1755 static bool _rtl8821ae_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
1756 						     u8 configtype)
1757 {
1758 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1759 	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1760 	int i;
1761 	u32 *array_table;
1762 	u16 arraylen;
1763 	u32 v1 = 0, v2 = 0;
1764 
1765 	if (configtype == BASEBAND_CONFIG_PHY_REG) {
1766 		if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1767 			arraylen = RTL8812AEPHY_REG_1TARRAYLEN;
1768 			array_table = RTL8812AE_PHY_REG_ARRAY;
1769 		} else {
1770 			arraylen = RTL8821AEPHY_REG_1TARRAYLEN;
1771 			array_table = RTL8821AE_PHY_REG_ARRAY;
1772 		}
1773 
1774 		for (i = 0; i < arraylen; i += 2) {
1775 			v1 = array_table[i];
1776 			v2 = array_table[i + 1];
1777 			if (v1 < 0xCDCDCDCD) {
1778 				_rtl8821ae_config_bb_reg(hw, v1, v2);
1779 				continue;
1780 			} else {/*This line is the start line of branch.*/
1781 				if (!_rtl8821ae_check_condition(hw, v1)) {
1782 					/*Discard the following (offset, data) pairs*/
1783 					READ_NEXT_PAIR(array_table, v1, v2, i);
1784 					while (v2 != 0xDEAD &&
1785 					       v2 != 0xCDEF &&
1786 					       v2 != 0xCDCD &&
1787 					       i < arraylen - 2) {
1788 						READ_NEXT_PAIR(array_table, v1,
1789 								v2, i);
1790 					}
1791 
1792 					i -= 2; /* prevent from for-loop += 2*/
1793 				} else {/*Configure matched pairs and skip to end of if-else.*/
1794 					READ_NEXT_PAIR(array_table, v1, v2, i);
1795 					while (v2 != 0xDEAD &&
1796 					       v2 != 0xCDEF &&
1797 					       v2 != 0xCDCD &&
1798 					       i < arraylen - 2) {
1799 						_rtl8821ae_config_bb_reg(hw, v1,
1800 									 v2);
1801 						READ_NEXT_PAIR(array_table, v1,
1802 							       v2, i);
1803 					}
1804 
1805 					while (v2 != 0xDEAD &&
1806 					       i < arraylen - 2) {
1807 						READ_NEXT_PAIR(array_table, v1,
1808 							       v2, i);
1809 					}
1810 				}
1811 			}
1812 		}
1813 	} else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
1814 		if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1815 			arraylen = RTL8812AEAGCTAB_1TARRAYLEN;
1816 			array_table = RTL8812AE_AGC_TAB_ARRAY;
1817 		} else {
1818 			arraylen = RTL8821AEAGCTAB_1TARRAYLEN;
1819 			array_table = RTL8821AE_AGC_TAB_ARRAY;
1820 		}
1821 
1822 		for (i = 0; i < arraylen; i = i + 2) {
1823 			v1 = array_table[i];
1824 			v2 = array_table[i+1];
1825 			if (v1 < 0xCDCDCDCD) {
1826 				rtl_set_bbreg(hw, v1, MASKDWORD, v2);
1827 				udelay(1);
1828 				continue;
1829 			} else {/*This line is the start line of branch.*/
1830 				if (!_rtl8821ae_check_condition(hw, v1)) {
1831 					/*Discard the following (offset, data) pairs*/
1832 					READ_NEXT_PAIR(array_table, v1, v2, i);
1833 					while (v2 != 0xDEAD &&
1834 					       v2 != 0xCDEF &&
1835 					       v2 != 0xCDCD &&
1836 					       i < arraylen - 2) {
1837 						READ_NEXT_PAIR(array_table, v1,
1838 								v2, i);
1839 					}
1840 					i -= 2; /* prevent from for-loop += 2*/
1841 				} else {/*Configure matched pairs and skip to end of if-else.*/
1842 					READ_NEXT_PAIR(array_table, v1, v2, i);
1843 					while (v2 != 0xDEAD &&
1844 					       v2 != 0xCDEF &&
1845 					       v2 != 0xCDCD &&
1846 					       i < arraylen - 2) {
1847 						rtl_set_bbreg(hw, v1, MASKDWORD,
1848 							      v2);
1849 						udelay(1);
1850 						READ_NEXT_PAIR(array_table, v1,
1851 							       v2, i);
1852 					}
1853 
1854 					while (v2 != 0xDEAD &&
1855 						i < arraylen - 2) {
1856 						READ_NEXT_PAIR(array_table, v1,
1857 								v2, i);
1858 					}
1859 				}
1860 				RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1861 					 "The agctab_array_table[0] is %x Rtl818EEPHY_REGArray[1] is %x\n",
1862 					  array_table[i],  array_table[i + 1]);
1863 			}
1864 		}
1865 	}
1866 	return true;
1867 }
1868 
1869 static u8 _rtl8821ae_get_rate_section_index(u32 regaddr)
1870 {
1871 	u8 index = 0;
1872 	regaddr &= 0xFFF;
1873 	if (regaddr >= 0xC20 && regaddr <= 0xC4C)
1874 		index = (u8)((regaddr - 0xC20) / 4);
1875 	else if (regaddr >= 0xE20 && regaddr <= 0xE4C)
1876 		index = (u8)((regaddr - 0xE20) / 4);
1877 	else
1878 		RT_ASSERT(!COMP_INIT,
1879 			  "Invalid RegAddr 0x%x\n", regaddr);
1880 	return index;
1881 }
1882 
1883 static void _rtl8821ae_store_tx_power_by_rate(struct ieee80211_hw *hw,
1884 					      u32 band, u32 rfpath,
1885 					      u32 txnum, u32 regaddr,
1886 					      u32 bitmask, u32 data)
1887 {
1888 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1889 	struct rtl_phy *rtlphy = &rtlpriv->phy;
1890 	u8 rate_section = _rtl8821ae_get_rate_section_index(regaddr);
1891 
1892 	if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
1893 		RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid Band %d\n", band);
1894 		band = BAND_ON_2_4G;
1895 	}
1896 	if (rfpath >= MAX_RF_PATH) {
1897 		RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid RfPath %d\n", rfpath);
1898 		rfpath = MAX_RF_PATH - 1;
1899 	}
1900 	if (txnum >= MAX_RF_PATH) {
1901 		RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid TxNum %d\n", txnum);
1902 		txnum = MAX_RF_PATH - 1;
1903 	}
1904 	rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] = data;
1905 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1906 		 "TxPwrByRateOffset[Band %d][RfPath %d][TxNum %d][RateSection %d] = 0x%x\n",
1907 		 band, rfpath, txnum, rate_section,
1908 		 rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section]);
1909 }
1910 
1911 static bool _rtl8821ae_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
1912 							u8 configtype)
1913 {
1914 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1915 	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1916 	int i;
1917 	u32 *array;
1918 	u16 arraylen;
1919 	u32 v1, v2, v3, v4, v5, v6;
1920 
1921 	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1922 		arraylen = RTL8812AEPHY_REG_ARRAY_PGLEN;
1923 		array = RTL8812AE_PHY_REG_ARRAY_PG;
1924 	} else {
1925 		arraylen = RTL8821AEPHY_REG_ARRAY_PGLEN;
1926 		array = RTL8821AE_PHY_REG_ARRAY_PG;
1927 	}
1928 
1929 	if (configtype != BASEBAND_CONFIG_PHY_REG) {
1930 		RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
1931 			 "configtype != BaseBand_Config_PHY_REG\n");
1932 		return true;
1933 	}
1934 	for (i = 0; i < arraylen; i += 6) {
1935 		v1 = array[i];
1936 		v2 = array[i+1];
1937 		v3 = array[i+2];
1938 		v4 = array[i+3];
1939 		v5 = array[i+4];
1940 		v6 = array[i+5];
1941 
1942 		if (v1 < 0xCDCDCDCD) {
1943 			if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE &&
1944 				(v4 == 0xfe || v4 == 0xffe)) {
1945 				msleep(50);
1946 				continue;
1947 			}
1948 
1949 			if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
1950 				if (v4 == 0xfe)
1951 					msleep(50);
1952 				else if (v4 == 0xfd)
1953 					mdelay(5);
1954 				else if (v4 == 0xfc)
1955 					mdelay(1);
1956 				else if (v4 == 0xfb)
1957 					udelay(50);
1958 				else if (v4 == 0xfa)
1959 					udelay(5);
1960 				else if (v4 == 0xf9)
1961 					udelay(1);
1962 			}
1963 			_rtl8821ae_store_tx_power_by_rate(hw, v1, v2, v3,
1964 							  v4, v5, v6);
1965 			continue;
1966 		} else {
1967 			 /*don't need the hw_body*/
1968 			if (!_rtl8821ae_check_condition(hw, v1)) {
1969 				i += 2; /* skip the pair of expression*/
1970 				v1 = array[i];
1971 				v2 = array[i+1];
1972 				v3 = array[i+2];
1973 				while (v2 != 0xDEAD) {
1974 					i += 3;
1975 					v1 = array[i];
1976 					v2 = array[i+1];
1977 					v3 = array[i+2];
1978 				}
1979 			}
1980 		}
1981 	}
1982 
1983 	return true;
1984 }
1985 
1986 bool rtl8812ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
1987 					     enum radio_path rfpath)
1988 {
1989 	int i;
1990 	bool rtstatus = true;
1991 	u32 *radioa_array_table_a, *radioa_array_table_b;
1992 	u16 radioa_arraylen_a, radioa_arraylen_b;
1993 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1994 	u32 v1 = 0, v2 = 0;
1995 
1996 	radioa_arraylen_a = RTL8812AE_RADIOA_1TARRAYLEN;
1997 	radioa_array_table_a = RTL8812AE_RADIOA_ARRAY;
1998 	radioa_arraylen_b = RTL8812AE_RADIOB_1TARRAYLEN;
1999 	radioa_array_table_b = RTL8812AE_RADIOB_ARRAY;
2000 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2001 		 "Radio_A:RTL8821AE_RADIOA_ARRAY %d\n", radioa_arraylen_a);
2002 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
2003 	rtstatus = true;
2004 	switch (rfpath) {
2005 	case RF90_PATH_A:
2006 		for (i = 0; i < radioa_arraylen_a; i = i + 2) {
2007 			v1 = radioa_array_table_a[i];
2008 			v2 = radioa_array_table_a[i+1];
2009 			if (v1 < 0xcdcdcdcd) {
2010 				_rtl8821ae_config_rf_radio_a(hw, v1, v2);
2011 				continue;
2012 			} else{/*This line is the start line of branch.*/
2013 				if (!_rtl8821ae_check_condition(hw, v1)) {
2014 					/*Discard the following (offset, data) pairs*/
2015 					READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2016 					while (v2 != 0xDEAD &&
2017 					       v2 != 0xCDEF &&
2018 					       v2 != 0xCDCD && i < radioa_arraylen_a-2)
2019 						READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2020 
2021 					i -= 2; /* prevent from for-loop += 2*/
2022 				} else {/*Configure matched pairs and skip to end of if-else.*/
2023 					READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2024 					while (v2 != 0xDEAD &&
2025 					       v2 != 0xCDEF &&
2026 					       v2 != 0xCDCD && i < radioa_arraylen_a - 2) {
2027 						_rtl8821ae_config_rf_radio_a(hw, v1, v2);
2028 						READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2029 					}
2030 
2031 					while (v2 != 0xDEAD && i < radioa_arraylen_a-2)
2032 						READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2033 
2034 				}
2035 			}
2036 		}
2037 		break;
2038 	case RF90_PATH_B:
2039 		for (i = 0; i < radioa_arraylen_b; i = i + 2) {
2040 			v1 = radioa_array_table_b[i];
2041 			v2 = radioa_array_table_b[i+1];
2042 			if (v1 < 0xcdcdcdcd) {
2043 				_rtl8821ae_config_rf_radio_b(hw, v1, v2);
2044 				continue;
2045 			} else{/*This line is the start line of branch.*/
2046 				if (!_rtl8821ae_check_condition(hw, v1)) {
2047 					/*Discard the following (offset, data) pairs*/
2048 					READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2049 					while (v2 != 0xDEAD &&
2050 					       v2 != 0xCDEF &&
2051 					       v2 != 0xCDCD && i < radioa_arraylen_b-2)
2052 						READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2053 
2054 					i -= 2; /* prevent from for-loop += 2*/
2055 				} else {/*Configure matched pairs and skip to end of if-else.*/
2056 					READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2057 					while (v2 != 0xDEAD &&
2058 					       v2 != 0xCDEF &&
2059 					       v2 != 0xCDCD && i < radioa_arraylen_b-2) {
2060 						_rtl8821ae_config_rf_radio_b(hw, v1, v2);
2061 						READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2062 					}
2063 
2064 					while (v2 != 0xDEAD && i < radioa_arraylen_b-2)
2065 						READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2066 				}
2067 			}
2068 		}
2069 		break;
2070 	case RF90_PATH_C:
2071 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2072 			 "switch case not process\n");
2073 		break;
2074 	case RF90_PATH_D:
2075 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2076 			 "switch case not process\n");
2077 		break;
2078 	}
2079 	return true;
2080 }
2081 
2082 bool rtl8821ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
2083 						enum radio_path rfpath)
2084 {
2085 	#define READ_NEXT_RF_PAIR(v1, v2, i) \
2086 	do { \
2087 		i += 2; \
2088 		v1 = radioa_array_table[i]; \
2089 		v2 = radioa_array_table[i+1]; \
2090 	} \
2091 	while (0)
2092 
2093 	int i;
2094 	bool rtstatus = true;
2095 	u32 *radioa_array_table;
2096 	u16 radioa_arraylen;
2097 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2098 	/* struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); */
2099 	u32 v1 = 0, v2 = 0;
2100 
2101 	radioa_arraylen = RTL8821AE_RADIOA_1TARRAYLEN;
2102 	radioa_array_table = RTL8821AE_RADIOA_ARRAY;
2103 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2104 		 "Radio_A:RTL8821AE_RADIOA_ARRAY %d\n", radioa_arraylen);
2105 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
2106 	rtstatus = true;
2107 	switch (rfpath) {
2108 	case RF90_PATH_A:
2109 		for (i = 0; i < radioa_arraylen; i = i + 2) {
2110 			v1 = radioa_array_table[i];
2111 			v2 = radioa_array_table[i+1];
2112 			if (v1 < 0xcdcdcdcd)
2113 				_rtl8821ae_config_rf_radio_a(hw, v1, v2);
2114 			else{/*This line is the start line of branch.*/
2115 				if (!_rtl8821ae_check_condition(hw, v1)) {
2116 					/*Discard the following (offset, data) pairs*/
2117 					READ_NEXT_RF_PAIR(v1, v2, i);
2118 					while (v2 != 0xDEAD &&
2119 						v2 != 0xCDEF &&
2120 						v2 != 0xCDCD && i < radioa_arraylen - 2)
2121 						READ_NEXT_RF_PAIR(v1, v2, i);
2122 
2123 					i -= 2; /* prevent from for-loop += 2*/
2124 				} else {/*Configure matched pairs and skip to end of if-else.*/
2125 					READ_NEXT_RF_PAIR(v1, v2, i);
2126 					while (v2 != 0xDEAD &&
2127 					       v2 != 0xCDEF &&
2128 					       v2 != 0xCDCD && i < radioa_arraylen - 2) {
2129 						_rtl8821ae_config_rf_radio_a(hw, v1, v2);
2130 						READ_NEXT_RF_PAIR(v1, v2, i);
2131 					}
2132 
2133 					while (v2 != 0xDEAD && i < radioa_arraylen - 2)
2134 						READ_NEXT_RF_PAIR(v1, v2, i);
2135 				}
2136 			}
2137 		}
2138 		break;
2139 
2140 	case RF90_PATH_B:
2141 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2142 			 "switch case not process\n");
2143 		break;
2144 	case RF90_PATH_C:
2145 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2146 			 "switch case not process\n");
2147 		break;
2148 	case RF90_PATH_D:
2149 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2150 			 "switch case not process\n");
2151 		break;
2152 	}
2153 	return true;
2154 }
2155 
2156 void rtl8821ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
2157 {
2158 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2159 	struct rtl_phy *rtlphy = &rtlpriv->phy;
2160 
2161 	rtlphy->default_initialgain[0] =
2162 	    (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
2163 	rtlphy->default_initialgain[1] =
2164 	    (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
2165 	rtlphy->default_initialgain[2] =
2166 	    (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
2167 	rtlphy->default_initialgain[3] =
2168 	    (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
2169 
2170 	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
2171 		 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
2172 		  rtlphy->default_initialgain[0],
2173 		  rtlphy->default_initialgain[1],
2174 		  rtlphy->default_initialgain[2],
2175 		  rtlphy->default_initialgain[3]);
2176 
2177 	rtlphy->framesync = (u8)rtl_get_bbreg(hw,
2178 					       ROFDM0_RXDETECTOR3, MASKBYTE0);
2179 	rtlphy->framesync_c34 = rtl_get_bbreg(hw,
2180 					      ROFDM0_RXDETECTOR2, MASKDWORD);
2181 
2182 	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
2183 		 "Default framesync (0x%x) = 0x%x\n",
2184 		  ROFDM0_RXDETECTOR3, rtlphy->framesync);
2185 }
2186 
2187 static void phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
2188 {
2189 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2190 	struct rtl_phy *rtlphy = &rtlpriv->phy;
2191 
2192 	rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
2193 	rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
2194 
2195 	rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
2196 	rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
2197 
2198 	rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
2199 	rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
2200 
2201 	rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = RA_LSSIWRITE_8821A;
2202 	rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = RB_LSSIWRITE_8821A;
2203 
2204 	rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RHSSIREAD_8821AE;
2205 	rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RHSSIREAD_8821AE;
2206 
2207 	rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RA_SIREAD_8821A;
2208 	rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RB_SIREAD_8821A;
2209 
2210 	rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = RA_PIREAD_8821A;
2211 	rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = RB_PIREAD_8821A;
2212 }
2213 
2214 void rtl8821ae_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
2215 {
2216 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2217 	struct rtl_phy *rtlphy = &rtlpriv->phy;
2218 	u8 txpwr_level;
2219 	long txpwr_dbm;
2220 
2221 	txpwr_level = rtlphy->cur_cck_txpwridx;
2222 	txpwr_dbm = _rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2223 						 WIRELESS_MODE_B, txpwr_level);
2224 	txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
2225 	if (_rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2226 					 WIRELESS_MODE_G,
2227 					 txpwr_level) > txpwr_dbm)
2228 		txpwr_dbm =
2229 		    _rtl8821ae_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
2230 						 txpwr_level);
2231 	txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
2232 	if (_rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2233 					 WIRELESS_MODE_N_24G,
2234 					 txpwr_level) > txpwr_dbm)
2235 		txpwr_dbm =
2236 		    _rtl8821ae_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
2237 						 txpwr_level);
2238 	*powerlevel = txpwr_dbm;
2239 }
2240 
2241 static bool _rtl8821ae_phy_get_chnl_index(u8 channel, u8 *chnl_index)
2242 {
2243 	u8 channel_5g[CHANNEL_MAX_NUMBER_5G] = {
2244 		36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62,
2245 		64, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118,
2246 		120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140,
2247 		142, 144, 149, 151, 153, 155, 157, 159, 161, 163, 165,
2248 		167, 168, 169, 171, 173, 175, 177
2249 	};
2250 	u8 i = 0;
2251 	bool in_24g = true;
2252 
2253 	if (channel <= 14) {
2254 		in_24g = true;
2255 		*chnl_index = channel - 1;
2256 	} else {
2257 		in_24g = false;
2258 
2259 		for (i = 0; i < CHANNEL_MAX_NUMBER_5G; ++i) {
2260 			if (channel_5g[i] == channel) {
2261 				*chnl_index = i;
2262 				return in_24g;
2263 			}
2264 		}
2265 	}
2266 	return in_24g;
2267 }
2268 
2269 static char _rtl8821ae_phy_get_ratesection_intxpower_byrate(u8 path, u8 rate)
2270 {
2271 	char rate_section = 0;
2272 	switch (rate) {
2273 	case DESC_RATE1M:
2274 	case DESC_RATE2M:
2275 	case DESC_RATE5_5M:
2276 	case DESC_RATE11M:
2277 		rate_section = 0;
2278 		break;
2279 	case DESC_RATE6M:
2280 	case DESC_RATE9M:
2281 	case DESC_RATE12M:
2282 	case DESC_RATE18M:
2283 		rate_section = 1;
2284 		break;
2285 	case DESC_RATE24M:
2286 	case DESC_RATE36M:
2287 	case DESC_RATE48M:
2288 	case DESC_RATE54M:
2289 		rate_section = 2;
2290 		break;
2291 	case DESC_RATEMCS0:
2292 	case DESC_RATEMCS1:
2293 	case DESC_RATEMCS2:
2294 	case DESC_RATEMCS3:
2295 		rate_section = 3;
2296 		break;
2297 	case DESC_RATEMCS4:
2298 	case DESC_RATEMCS5:
2299 	case DESC_RATEMCS6:
2300 	case DESC_RATEMCS7:
2301 		rate_section = 4;
2302 		break;
2303 	case DESC_RATEMCS8:
2304 	case DESC_RATEMCS9:
2305 	case DESC_RATEMCS10:
2306 	case DESC_RATEMCS11:
2307 		rate_section = 5;
2308 		break;
2309 	case DESC_RATEMCS12:
2310 	case DESC_RATEMCS13:
2311 	case DESC_RATEMCS14:
2312 	case DESC_RATEMCS15:
2313 		rate_section = 6;
2314 		break;
2315 	case DESC_RATEVHT1SS_MCS0:
2316 	case DESC_RATEVHT1SS_MCS1:
2317 	case DESC_RATEVHT1SS_MCS2:
2318 	case DESC_RATEVHT1SS_MCS3:
2319 		rate_section = 7;
2320 		break;
2321 	case DESC_RATEVHT1SS_MCS4:
2322 	case DESC_RATEVHT1SS_MCS5:
2323 	case DESC_RATEVHT1SS_MCS6:
2324 	case DESC_RATEVHT1SS_MCS7:
2325 		rate_section = 8;
2326 		break;
2327 	case DESC_RATEVHT1SS_MCS8:
2328 	case DESC_RATEVHT1SS_MCS9:
2329 	case DESC_RATEVHT2SS_MCS0:
2330 	case DESC_RATEVHT2SS_MCS1:
2331 		rate_section = 9;
2332 		break;
2333 	case DESC_RATEVHT2SS_MCS2:
2334 	case DESC_RATEVHT2SS_MCS3:
2335 	case DESC_RATEVHT2SS_MCS4:
2336 	case DESC_RATEVHT2SS_MCS5:
2337 		rate_section = 10;
2338 		break;
2339 	case DESC_RATEVHT2SS_MCS6:
2340 	case DESC_RATEVHT2SS_MCS7:
2341 	case DESC_RATEVHT2SS_MCS8:
2342 	case DESC_RATEVHT2SS_MCS9:
2343 		rate_section = 11;
2344 		break;
2345 	default:
2346 		RT_ASSERT(true, "Rate_Section is Illegal\n");
2347 		break;
2348 	}
2349 
2350 	return rate_section;
2351 }
2352 
2353 static char _rtl8812ae_phy_get_world_wide_limit(char  *limit_table)
2354 {
2355 	char min = limit_table[0];
2356 	u8 i = 0;
2357 
2358 	for (i = 0; i < MAX_REGULATION_NUM; ++i) {
2359 		if (limit_table[i] < min)
2360 			min = limit_table[i];
2361 	}
2362 	return min;
2363 }
2364 
2365 static char _rtl8812ae_phy_get_txpower_limit(struct ieee80211_hw *hw,
2366 					     u8 band,
2367 					     enum ht_channel_width bandwidth,
2368 					     enum radio_path rf_path,
2369 					     u8 rate, u8 channel)
2370 {
2371 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2372 	struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
2373 	struct rtl_phy *rtlphy = &rtlpriv->phy;
2374 	short band_temp = -1, regulation = -1, bandwidth_temp = -1,
2375 		 rate_section = -1, channel_temp = -1;
2376 	u16 bd, regu, bdwidth, sec, chnl;
2377 	char power_limit = MAX_POWER_INDEX;
2378 
2379 	if (rtlefuse->eeprom_regulatory == 2)
2380 		return MAX_POWER_INDEX;
2381 
2382 	regulation = TXPWR_LMT_WW;
2383 
2384 	if (band == BAND_ON_2_4G)
2385 		band_temp = 0;
2386 	else if (band == BAND_ON_5G)
2387 		band_temp = 1;
2388 
2389 	if (bandwidth == HT_CHANNEL_WIDTH_20)
2390 		bandwidth_temp = 0;
2391 	else if (bandwidth == HT_CHANNEL_WIDTH_20_40)
2392 		bandwidth_temp = 1;
2393 	else if (bandwidth == HT_CHANNEL_WIDTH_80)
2394 		bandwidth_temp = 2;
2395 
2396 	switch (rate) {
2397 	case DESC_RATE1M:
2398 	case DESC_RATE2M:
2399 	case DESC_RATE5_5M:
2400 	case DESC_RATE11M:
2401 		rate_section = 0;
2402 		break;
2403 	case DESC_RATE6M:
2404 	case DESC_RATE9M:
2405 	case DESC_RATE12M:
2406 	case DESC_RATE18M:
2407 	case DESC_RATE24M:
2408 	case DESC_RATE36M:
2409 	case DESC_RATE48M:
2410 	case DESC_RATE54M:
2411 		rate_section = 1;
2412 		break;
2413 	case DESC_RATEMCS0:
2414 	case DESC_RATEMCS1:
2415 	case DESC_RATEMCS2:
2416 	case DESC_RATEMCS3:
2417 	case DESC_RATEMCS4:
2418 	case DESC_RATEMCS5:
2419 	case DESC_RATEMCS6:
2420 	case DESC_RATEMCS7:
2421 		rate_section = 2;
2422 		break;
2423 	case DESC_RATEMCS8:
2424 	case DESC_RATEMCS9:
2425 	case DESC_RATEMCS10:
2426 	case DESC_RATEMCS11:
2427 	case DESC_RATEMCS12:
2428 	case DESC_RATEMCS13:
2429 	case DESC_RATEMCS14:
2430 	case DESC_RATEMCS15:
2431 		rate_section = 3;
2432 		break;
2433 	case DESC_RATEVHT1SS_MCS0:
2434 	case DESC_RATEVHT1SS_MCS1:
2435 	case DESC_RATEVHT1SS_MCS2:
2436 	case DESC_RATEVHT1SS_MCS3:
2437 	case DESC_RATEVHT1SS_MCS4:
2438 	case DESC_RATEVHT1SS_MCS5:
2439 	case DESC_RATEVHT1SS_MCS6:
2440 	case DESC_RATEVHT1SS_MCS7:
2441 	case DESC_RATEVHT1SS_MCS8:
2442 	case DESC_RATEVHT1SS_MCS9:
2443 		rate_section = 4;
2444 		break;
2445 	case DESC_RATEVHT2SS_MCS0:
2446 	case DESC_RATEVHT2SS_MCS1:
2447 	case DESC_RATEVHT2SS_MCS2:
2448 	case DESC_RATEVHT2SS_MCS3:
2449 	case DESC_RATEVHT2SS_MCS4:
2450 	case DESC_RATEVHT2SS_MCS5:
2451 	case DESC_RATEVHT2SS_MCS6:
2452 	case DESC_RATEVHT2SS_MCS7:
2453 	case DESC_RATEVHT2SS_MCS8:
2454 	case DESC_RATEVHT2SS_MCS9:
2455 		rate_section = 5;
2456 		break;
2457 	default:
2458 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2459 			"Wrong rate 0x%x\n", rate);
2460 		break;
2461 	}
2462 
2463 	if (band_temp == BAND_ON_5G  && rate_section == 0)
2464 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2465 			 "Wrong rate 0x%x: No CCK in 5G Band\n", rate);
2466 
2467 	/*workaround for wrong index combination to obtain tx power limit,
2468 	  OFDM only exists in BW 20M*/
2469 	if (rate_section == 1)
2470 		bandwidth_temp = 0;
2471 
2472 	/*workaround for wrong index combination to obtain tx power limit,
2473 	 *HT on 80M will reference to HT on 40M
2474 	 */
2475 	if ((rate_section == 2 || rate_section == 3) && band == BAND_ON_5G &&
2476 	    bandwidth_temp == 2)
2477 		bandwidth_temp = 1;
2478 
2479 	if (band == BAND_ON_2_4G)
2480 		channel_temp = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
2481 		BAND_ON_2_4G, channel);
2482 	else if (band == BAND_ON_5G)
2483 		channel_temp = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
2484 		BAND_ON_5G, channel);
2485 	else if (band == BAND_ON_BOTH)
2486 		;/* BAND_ON_BOTH don't care temporarily */
2487 
2488 	if (band_temp == -1 || regulation == -1 || bandwidth_temp == -1 ||
2489 		rate_section == -1 || channel_temp == -1) {
2490 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2491 			 "Wrong index value to access power limit table [band %d][regulation %d][bandwidth %d][rf_path %d][rate_section %d][chnl %d]\n",
2492 			 band_temp, regulation, bandwidth_temp, rf_path,
2493 			 rate_section, channel_temp);
2494 		return MAX_POWER_INDEX;
2495 	}
2496 
2497 	bd = band_temp;
2498 	regu = regulation;
2499 	bdwidth = bandwidth_temp;
2500 	sec = rate_section;
2501 	chnl = channel_temp;
2502 
2503 	if (band == BAND_ON_2_4G) {
2504 		char limits[10] = {0};
2505 		u8 i;
2506 
2507 		for (i = 0; i < 4; ++i)
2508 			limits[i] = rtlphy->txpwr_limit_2_4g[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_2_4g[regu][bdwidth]
2514 					[sec][chnl][rf_path];
2515 	} else if (band == BAND_ON_5G) {
2516 		char limits[10] = {0};
2517 		u8 i;
2518 
2519 		for (i = 0; i < MAX_REGULATION_NUM; ++i)
2520 			limits[i] = rtlphy->txpwr_limit_5g[i][bdwidth]
2521 			[sec][chnl][rf_path];
2522 
2523 		power_limit = (regulation == TXPWR_LMT_WW) ?
2524 			_rtl8812ae_phy_get_world_wide_limit(limits) :
2525 			rtlphy->txpwr_limit_5g[regu][chnl]
2526 			[sec][chnl][rf_path];
2527 	} else {
2528 		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2529 			 "No power limit table of the specified band\n");
2530 	}
2531 	return power_limit;
2532 }
2533 
2534 static char _rtl8821ae_phy_get_txpower_by_rate(struct ieee80211_hw *hw,
2535 					u8 band, u8 path, u8 rate)
2536 {
2537 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2538 	struct rtl_phy *rtlphy = &rtlpriv->phy;
2539 	u8 shift = 0, rate_section, tx_num;
2540 	char tx_pwr_diff = 0;
2541 	char limit = 0;
2542 
2543 	rate_section = _rtl8821ae_phy_get_ratesection_intxpower_byrate(path, rate);
2544 	tx_num = RF_TX_NUM_NONIMPLEMENT;
2545 
2546 	if (tx_num == RF_TX_NUM_NONIMPLEMENT) {
2547 		if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
2548 			(rate >= DESC_RATEVHT2SS_MCS2 && rate <= DESC_RATEVHT2SS_MCS9))
2549 			tx_num = RF_2TX;
2550 		else
2551 			tx_num = RF_1TX;
2552 	}
2553 
2554 	switch (rate) {
2555 	case DESC_RATE1M:
2556 	case DESC_RATE6M:
2557 	case DESC_RATE24M:
2558 	case DESC_RATEMCS0:
2559 	case DESC_RATEMCS4:
2560 	case DESC_RATEMCS8:
2561 	case DESC_RATEMCS12:
2562 	case DESC_RATEVHT1SS_MCS0:
2563 	case DESC_RATEVHT1SS_MCS4:
2564 	case DESC_RATEVHT1SS_MCS8:
2565 	case DESC_RATEVHT2SS_MCS2:
2566 	case DESC_RATEVHT2SS_MCS6:
2567 		shift = 0;
2568 		break;
2569 	case DESC_RATE2M:
2570 	case DESC_RATE9M:
2571 	case DESC_RATE36M:
2572 	case DESC_RATEMCS1:
2573 	case DESC_RATEMCS5:
2574 	case DESC_RATEMCS9:
2575 	case DESC_RATEMCS13:
2576 	case DESC_RATEVHT1SS_MCS1:
2577 	case DESC_RATEVHT1SS_MCS5:
2578 	case DESC_RATEVHT1SS_MCS9:
2579 	case DESC_RATEVHT2SS_MCS3:
2580 	case DESC_RATEVHT2SS_MCS7:
2581 		shift = 8;
2582 		break;
2583 	case DESC_RATE5_5M:
2584 	case DESC_RATE12M:
2585 	case DESC_RATE48M:
2586 	case DESC_RATEMCS2:
2587 	case DESC_RATEMCS6:
2588 	case DESC_RATEMCS10:
2589 	case DESC_RATEMCS14:
2590 	case DESC_RATEVHT1SS_MCS2:
2591 	case DESC_RATEVHT1SS_MCS6:
2592 	case DESC_RATEVHT2SS_MCS0:
2593 	case DESC_RATEVHT2SS_MCS4:
2594 	case DESC_RATEVHT2SS_MCS8:
2595 		shift = 16;
2596 		break;
2597 	case DESC_RATE11M:
2598 	case DESC_RATE18M:
2599 	case DESC_RATE54M:
2600 	case DESC_RATEMCS3:
2601 	case DESC_RATEMCS7:
2602 	case DESC_RATEMCS11:
2603 	case DESC_RATEMCS15:
2604 	case DESC_RATEVHT1SS_MCS3:
2605 	case DESC_RATEVHT1SS_MCS7:
2606 	case DESC_RATEVHT2SS_MCS1:
2607 	case DESC_RATEVHT2SS_MCS5:
2608 	case DESC_RATEVHT2SS_MCS9:
2609 		shift = 24;
2610 		break;
2611 	default:
2612 		RT_ASSERT(true, "Rate_Section is Illegal\n");
2613 		break;
2614 	}
2615 
2616 	tx_pwr_diff = (u8)(rtlphy->tx_power_by_rate_offset[band][path]
2617 		[tx_num][rate_section] >> shift) & 0xff;
2618 
2619 	/* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
2620 	if (rtlpriv->efuse.eeprom_regulatory != 2) {
2621 		limit = _rtl8812ae_phy_get_txpower_limit(hw, band,
2622 			rtlphy->current_chan_bw, path, rate,
2623 			rtlphy->current_channel);
2624 
2625 		if (rate == DESC_RATEVHT1SS_MCS8 || rate == DESC_RATEVHT1SS_MCS9  ||
2626 			 rate == DESC_RATEVHT2SS_MCS8 || rate == DESC_RATEVHT2SS_MCS9) {
2627 			if (limit < 0) {
2628 				if (tx_pwr_diff < (-limit))
2629 					tx_pwr_diff = -limit;
2630 			}
2631 		} else {
2632 			if (limit < 0)
2633 				tx_pwr_diff = limit;
2634 			else
2635 				tx_pwr_diff = tx_pwr_diff > limit ? limit : tx_pwr_diff;
2636 		}
2637 		RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2638 			"Maximum power by rate %d, final power by rate %d\n",
2639 			limit, tx_pwr_diff);
2640 	}
2641 
2642 	return	tx_pwr_diff;
2643 }
2644 
2645 static u8 _rtl8821ae_get_txpower_index(struct ieee80211_hw *hw, u8 path,
2646 					u8 rate, u8 bandwidth, u8 channel)
2647 {
2648 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2649 	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
2650 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2651 	u8 index = (channel - 1);
2652 	u8 txpower = 0;
2653 	bool in_24g = false;
2654 	char powerdiff_byrate = 0;
2655 
2656 	if (((rtlhal->current_bandtype == BAND_ON_2_4G) &&
2657 	    (channel > 14 || channel < 1)) ||
2658 	    ((rtlhal->current_bandtype == BAND_ON_5G) && (channel <= 14))) {
2659 		index = 0;
2660 		RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2661 			"Illegal channel!!\n");
2662 	}
2663 
2664 	in_24g = _rtl8821ae_phy_get_chnl_index(channel, &index);
2665 	if (in_24g) {
2666 		if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2667 			txpower = rtlefuse->txpwrlevel_cck[path][index];
2668 		else if (DESC_RATE6M <= rate)
2669 			txpower = rtlefuse->txpwrlevel_ht40_1s[path][index];
2670 		else
2671 			RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "invalid rate\n");
2672 
2673 		if (DESC_RATE6M <= rate && rate <= DESC_RATE54M &&
2674 		    !RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2675 			txpower += rtlefuse->txpwr_legacyhtdiff[path][TX_1S];
2676 
2677 		if (bandwidth == HT_CHANNEL_WIDTH_20) {
2678 			if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2679 				(DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2680 				txpower += rtlefuse->txpwr_ht20diff[path][TX_1S];
2681 			if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2682 				(DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2683 				txpower += rtlefuse->txpwr_ht20diff[path][TX_2S];
2684 		} else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
2685 			if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2686 				(DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2687 				txpower += rtlefuse->txpwr_ht40diff[path][TX_1S];
2688 			if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2689 				(DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2690 				txpower += rtlefuse->txpwr_ht40diff[path][TX_2S];
2691 		} else if (bandwidth == HT_CHANNEL_WIDTH_80) {
2692 			if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2693 			    (DESC_RATEVHT1SS_MCS0 <= rate &&
2694 			     rate <= DESC_RATEVHT2SS_MCS9))
2695 				txpower += rtlefuse->txpwr_ht40diff[path][TX_1S];
2696 			if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2697 			    (DESC_RATEVHT2SS_MCS0 <= rate &&
2698 			     rate <= DESC_RATEVHT2SS_MCS9))
2699 				txpower += rtlefuse->txpwr_ht40diff[path][TX_2S];
2700 		}
2701 	} else {
2702 		if (DESC_RATE6M <= rate)
2703 			txpower = rtlefuse->txpwr_5g_bw40base[path][index];
2704 		else
2705 			RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_WARNING,
2706 				 "INVALID Rate.\n");
2707 
2708 		if (DESC_RATE6M <= rate && rate <= DESC_RATE54M &&
2709 		    !RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2710 			txpower += rtlefuse->txpwr_5g_ofdmdiff[path][TX_1S];
2711 
2712 		if (bandwidth == HT_CHANNEL_WIDTH_20) {
2713 			if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2714 			    (DESC_RATEVHT1SS_MCS0 <= rate &&
2715 			     rate <= DESC_RATEVHT2SS_MCS9))
2716 				txpower += rtlefuse->txpwr_5g_bw20diff[path][TX_1S];
2717 			if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2718 			    (DESC_RATEVHT2SS_MCS0 <= rate &&
2719 			     rate <= DESC_RATEVHT2SS_MCS9))
2720 				txpower += rtlefuse->txpwr_5g_bw20diff[path][TX_2S];
2721 		} else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
2722 			if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2723 			    (DESC_RATEVHT1SS_MCS0 <= rate &&
2724 			     rate <= DESC_RATEVHT2SS_MCS9))
2725 				txpower += rtlefuse->txpwr_5g_bw40diff[path][TX_1S];
2726 			if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2727 			    (DESC_RATEVHT2SS_MCS0 <= rate &&
2728 			     rate <= DESC_RATEVHT2SS_MCS9))
2729 				txpower += rtlefuse->txpwr_5g_bw40diff[path][TX_2S];
2730 		} else if (bandwidth == HT_CHANNEL_WIDTH_80) {
2731 			u8 channel_5g_80m[CHANNEL_MAX_NUMBER_5G_80M] = {
2732 				42, 58, 106, 122, 138, 155, 171
2733 			};
2734 			u8 i;
2735 
2736 			for (i = 0; i < sizeof(channel_5g_80m) / sizeof(u8); ++i)
2737 				if (channel_5g_80m[i] == channel)
2738 					index = i;
2739 
2740 			if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2741 			    (DESC_RATEVHT1SS_MCS0 <= rate &&
2742 			     rate <= DESC_RATEVHT2SS_MCS9))
2743 				txpower = rtlefuse->txpwr_5g_bw80base[path][index]
2744 					+ rtlefuse->txpwr_5g_bw80diff[path][TX_1S];
2745 			if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2746 			    (DESC_RATEVHT2SS_MCS0 <= rate &&
2747 			     rate <= DESC_RATEVHT2SS_MCS9))
2748 				txpower = rtlefuse->txpwr_5g_bw80base[path][index]
2749 					+ rtlefuse->txpwr_5g_bw80diff[path][TX_1S]
2750 					+ rtlefuse->txpwr_5g_bw80diff[path][TX_2S];
2751 		    }
2752 	}
2753 	if (rtlefuse->eeprom_regulatory != 2)
2754 		powerdiff_byrate =
2755 		  _rtl8821ae_phy_get_txpower_by_rate(hw, (u8)(!in_24g),
2756 						     path, rate);
2757 
2758 	if (rate == DESC_RATEVHT1SS_MCS8 || rate == DESC_RATEVHT1SS_MCS9 ||
2759 	    rate == DESC_RATEVHT2SS_MCS8 || rate == DESC_RATEVHT2SS_MCS9)
2760 		txpower -= powerdiff_byrate;
2761 	else
2762 		txpower += powerdiff_byrate;
2763 
2764 	if (rate > DESC_RATE11M)
2765 		txpower += rtlpriv->dm.remnant_ofdm_swing_idx[path];
2766 	else
2767 		txpower += rtlpriv->dm.remnant_cck_idx;
2768 
2769 	if (txpower > MAX_POWER_INDEX)
2770 		txpower = MAX_POWER_INDEX;
2771 
2772 	return txpower;
2773 }
2774 
2775 static void _rtl8821ae_phy_set_txpower_index(struct ieee80211_hw *hw,
2776 					     u8 power_index, u8 path, u8 rate)
2777 {
2778 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2779 
2780 	if (path == RF90_PATH_A) {
2781 		switch (rate) {
2782 		case DESC_RATE1M:
2783 			rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2784 				      MASKBYTE0, power_index);
2785 			break;
2786 		case DESC_RATE2M:
2787 			rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2788 				      MASKBYTE1, power_index);
2789 			break;
2790 		case DESC_RATE5_5M:
2791 			rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2792 				      MASKBYTE2, power_index);
2793 			break;
2794 		case DESC_RATE11M:
2795 			rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2796 				      MASKBYTE3, power_index);
2797 			break;
2798 		case DESC_RATE6M:
2799 			rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2800 				      MASKBYTE0, power_index);
2801 			break;
2802 		case DESC_RATE9M:
2803 			rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2804 				      MASKBYTE1, power_index);
2805 			break;
2806 		case DESC_RATE12M:
2807 			rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2808 				      MASKBYTE2, power_index);
2809 			break;
2810 		case DESC_RATE18M:
2811 			rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2812 				      MASKBYTE3, power_index);
2813 			break;
2814 		case DESC_RATE24M:
2815 			rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2816 				      MASKBYTE0, power_index);
2817 			break;
2818 		case DESC_RATE36M:
2819 			rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2820 				      MASKBYTE1, power_index);
2821 			break;
2822 		case DESC_RATE48M:
2823 			rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2824 				      MASKBYTE2, power_index);
2825 			break;
2826 		case DESC_RATE54M:
2827 			rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2828 				      MASKBYTE3, power_index);
2829 			break;
2830 		case DESC_RATEMCS0:
2831 			rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2832 				      MASKBYTE0, power_index);
2833 			break;
2834 		case DESC_RATEMCS1:
2835 			rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2836 				      MASKBYTE1, power_index);
2837 			break;
2838 		case DESC_RATEMCS2:
2839 			rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2840 				      MASKBYTE2, power_index);
2841 			break;
2842 		case DESC_RATEMCS3:
2843 			rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2844 				      MASKBYTE3, power_index);
2845 			break;
2846 		case DESC_RATEMCS4:
2847 			rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2848 				      MASKBYTE0, power_index);
2849 			break;
2850 		case DESC_RATEMCS5:
2851 			rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2852 				      MASKBYTE1, power_index);
2853 			break;
2854 		case DESC_RATEMCS6:
2855 			rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2856 				      MASKBYTE2, power_index);
2857 			break;
2858 		case DESC_RATEMCS7:
2859 			rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2860 				      MASKBYTE3, power_index);
2861 			break;
2862 		case DESC_RATEMCS8:
2863 			rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2864 				      MASKBYTE0, power_index);
2865 			break;
2866 		case DESC_RATEMCS9:
2867 			rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2868 				      MASKBYTE1, power_index);
2869 			break;
2870 		case DESC_RATEMCS10:
2871 			rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2872 				      MASKBYTE2, power_index);
2873 			break;
2874 		case DESC_RATEMCS11:
2875 			rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2876 				      MASKBYTE3, power_index);
2877 			break;
2878 		case DESC_RATEMCS12:
2879 			rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2880 				      MASKBYTE0, power_index);
2881 			break;
2882 		case DESC_RATEMCS13:
2883 			rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2884 				      MASKBYTE1, power_index);
2885 			break;
2886 		case DESC_RATEMCS14:
2887 			rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2888 				      MASKBYTE2, power_index);
2889 			break;
2890 		case DESC_RATEMCS15:
2891 			rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2892 				      MASKBYTE3, power_index);
2893 			break;
2894 		case DESC_RATEVHT1SS_MCS0:
2895 			rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2896 				      MASKBYTE0, power_index);
2897 			break;
2898 		case DESC_RATEVHT1SS_MCS1:
2899 			rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2900 				      MASKBYTE1, power_index);
2901 			break;
2902 		case DESC_RATEVHT1SS_MCS2:
2903 			rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2904 				      MASKBYTE2, power_index);
2905 			break;
2906 		case DESC_RATEVHT1SS_MCS3:
2907 			rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2908 				      MASKBYTE3, power_index);
2909 			break;
2910 		case DESC_RATEVHT1SS_MCS4:
2911 			rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2912 				      MASKBYTE0, power_index);
2913 			break;
2914 		case DESC_RATEVHT1SS_MCS5:
2915 			rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2916 				      MASKBYTE1, power_index);
2917 			break;
2918 		case DESC_RATEVHT1SS_MCS6:
2919 			rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2920 				      MASKBYTE2, power_index);
2921 			break;
2922 		case DESC_RATEVHT1SS_MCS7:
2923 			rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2924 				      MASKBYTE3, power_index);
2925 			break;
2926 		case DESC_RATEVHT1SS_MCS8:
2927 			rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2928 				      MASKBYTE0, power_index);
2929 			break;
2930 		case DESC_RATEVHT1SS_MCS9:
2931 			rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2932 				      MASKBYTE1, power_index);
2933 			break;
2934 		case DESC_RATEVHT2SS_MCS0:
2935 			rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2936 				      MASKBYTE2, power_index);
2937 			break;
2938 		case DESC_RATEVHT2SS_MCS1:
2939 			rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2940 				      MASKBYTE3, power_index);
2941 			break;
2942 		case DESC_RATEVHT2SS_MCS2:
2943 			rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2944 				      MASKBYTE0, power_index);
2945 			break;
2946 		case DESC_RATEVHT2SS_MCS3:
2947 			rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2948 				      MASKBYTE1, power_index);
2949 			break;
2950 		case DESC_RATEVHT2SS_MCS4:
2951 			rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2952 				      MASKBYTE2, power_index);
2953 			break;
2954 		case DESC_RATEVHT2SS_MCS5:
2955 			rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2956 				      MASKBYTE3, power_index);
2957 			break;
2958 		case DESC_RATEVHT2SS_MCS6:
2959 			rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2960 				      MASKBYTE0, power_index);
2961 			break;
2962 		case DESC_RATEVHT2SS_MCS7:
2963 			rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2964 				      MASKBYTE1, power_index);
2965 			break;
2966 		case DESC_RATEVHT2SS_MCS8:
2967 			rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2968 				      MASKBYTE2, power_index);
2969 			break;
2970 		case DESC_RATEVHT2SS_MCS9:
2971 			rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2972 				      MASKBYTE3, power_index);
2973 			break;
2974 		default:
2975 			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2976 				"Invalid Rate!!\n");
2977 			break;
2978 		}
2979 	} else if (path == RF90_PATH_B) {
2980 		switch (rate) {
2981 		case DESC_RATE1M:
2982 			rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2983 				      MASKBYTE0, power_index);
2984 			break;
2985 		case DESC_RATE2M:
2986 			rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2987 				      MASKBYTE1, power_index);
2988 			break;
2989 		case DESC_RATE5_5M:
2990 			rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2991 				      MASKBYTE2, power_index);
2992 			break;
2993 		case DESC_RATE11M:
2994 			rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2995 				      MASKBYTE3, power_index);
2996 			break;
2997 		case DESC_RATE6M:
2998 			rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
2999 				      MASKBYTE0, power_index);
3000 			break;
3001 		case DESC_RATE9M:
3002 			rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
3003 				      MASKBYTE1, power_index);
3004 			break;
3005 		case DESC_RATE12M:
3006 			rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
3007 				      MASKBYTE2, power_index);
3008 			break;
3009 		case DESC_RATE18M:
3010 			rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
3011 				      MASKBYTE3, power_index);
3012 			break;
3013 		case DESC_RATE24M:
3014 			rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3015 				      MASKBYTE0, power_index);
3016 			break;
3017 		case DESC_RATE36M:
3018 			rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3019 				      MASKBYTE1, power_index);
3020 			break;
3021 		case DESC_RATE48M:
3022 			rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3023 				      MASKBYTE2, power_index);
3024 			break;
3025 		case DESC_RATE54M:
3026 			rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3027 				      MASKBYTE3, power_index);
3028 			break;
3029 		case DESC_RATEMCS0:
3030 			rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3031 				      MASKBYTE0, power_index);
3032 			break;
3033 		case DESC_RATEMCS1:
3034 			rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3035 				      MASKBYTE1, power_index);
3036 			break;
3037 		case DESC_RATEMCS2:
3038 			rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3039 				      MASKBYTE2, power_index);
3040 			break;
3041 		case DESC_RATEMCS3:
3042 			rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3043 				      MASKBYTE3, power_index);
3044 			break;
3045 		case DESC_RATEMCS4:
3046 			rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3047 				      MASKBYTE0, power_index);
3048 			break;
3049 		case DESC_RATEMCS5:
3050 			rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3051 				      MASKBYTE1, power_index);
3052 			break;
3053 		case DESC_RATEMCS6:
3054 			rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3055 				      MASKBYTE2, power_index);
3056 			break;
3057 		case DESC_RATEMCS7:
3058 			rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3059 				      MASKBYTE3, power_index);
3060 			break;
3061 		case DESC_RATEMCS8:
3062 			rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3063 				      MASKBYTE0, power_index);
3064 			break;
3065 		case DESC_RATEMCS9:
3066 			rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3067 				      MASKBYTE1, power_index);
3068 			break;
3069 		case DESC_RATEMCS10:
3070 			rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3071 				      MASKBYTE2, power_index);
3072 			break;
3073 		case DESC_RATEMCS11:
3074 			rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3075 				      MASKBYTE3, power_index);
3076 			break;
3077 		case DESC_RATEMCS12:
3078 			rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3079 				      MASKBYTE0, power_index);
3080 			break;
3081 		case DESC_RATEMCS13:
3082 			rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3083 				      MASKBYTE1, power_index);
3084 			break;
3085 		case DESC_RATEMCS14:
3086 			rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3087 				      MASKBYTE2, power_index);
3088 			break;
3089 		case DESC_RATEMCS15:
3090 			rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3091 				      MASKBYTE3, power_index);
3092 			break;
3093 		case DESC_RATEVHT1SS_MCS0:
3094 			rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3095 				      MASKBYTE0, power_index);
3096 			break;
3097 		case DESC_RATEVHT1SS_MCS1:
3098 			rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3099 				      MASKBYTE1, power_index);
3100 			break;
3101 		case DESC_RATEVHT1SS_MCS2:
3102 			rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3103 				      MASKBYTE2, power_index);
3104 			break;
3105 		case DESC_RATEVHT1SS_MCS3:
3106 			rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3107 				      MASKBYTE3, power_index);
3108 			break;
3109 		case DESC_RATEVHT1SS_MCS4:
3110 			rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3111 				      MASKBYTE0, power_index);
3112 			break;
3113 		case DESC_RATEVHT1SS_MCS5:
3114 			rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3115 				      MASKBYTE1, power_index);
3116 			break;
3117 		case DESC_RATEVHT1SS_MCS6:
3118 			rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3119 				      MASKBYTE2, power_index);
3120 			break;
3121 		case DESC_RATEVHT1SS_MCS7:
3122 			rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3123 				      MASKBYTE3, power_index);
3124 			break;
3125 		case DESC_RATEVHT1SS_MCS8:
3126 			rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3127 				      MASKBYTE0, power_index);
3128 			break;
3129 		case DESC_RATEVHT1SS_MCS9:
3130 			rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3131 				      MASKBYTE1, power_index);
3132 			break;
3133 		case DESC_RATEVHT2SS_MCS0:
3134 			rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3135 				      MASKBYTE2, power_index);
3136 			break;
3137 		case DESC_RATEVHT2SS_MCS1:
3138 			rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3139 				      MASKBYTE3, power_index);
3140 			break;
3141 		case DESC_RATEVHT2SS_MCS2:
3142 			rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3143 				      MASKBYTE0, power_index);
3144 			break;
3145 		case DESC_RATEVHT2SS_MCS3:
3146 			rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3147 				      MASKBYTE1, power_index);
3148 			break;
3149 		case DESC_RATEVHT2SS_MCS4:
3150 			rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3151 				      MASKBYTE2, power_index);
3152 			break;
3153 		case DESC_RATEVHT2SS_MCS5:
3154 			rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3155 				      MASKBYTE3, power_index);
3156 			break;
3157 		case DESC_RATEVHT2SS_MCS6:
3158 			rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3159 				      MASKBYTE0, power_index);
3160 			break;
3161 		case DESC_RATEVHT2SS_MCS7:
3162 			rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3163 				      MASKBYTE1, power_index);
3164 			break;
3165 		case DESC_RATEVHT2SS_MCS8:
3166 			rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3167 				      MASKBYTE2, power_index);
3168 			break;
3169 		case DESC_RATEVHT2SS_MCS9:
3170 			rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3171 				      MASKBYTE3, power_index);
3172 			break;
3173 		default:
3174 			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
3175 				 "Invalid Rate!!\n");
3176 			break;
3177 		}
3178 	} else {
3179 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
3180 			 "Invalid RFPath!!\n");
3181 	}
3182 }
3183 
3184 static void _rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
3185 						     u8 *array, u8 path,
3186 						     u8 channel, u8 size)
3187 {
3188 	struct rtl_priv *rtlpriv = rtl_priv(hw);
3189 	struct rtl_phy *rtlphy = &rtlpriv->phy;
3190 	u8 i;
3191 	u8 power_index;
3192 
3193 	for (i = 0; i < size; i++) {
3194 		power_index =
3195 		  _rtl8821ae_get_txpower_index(hw, path, array[i],
3196 					       rtlphy->current_chan_bw,
3197 					       channel);
3198 		_rtl8821ae_phy_set_txpower_index(hw, power_index, path,
3199 						 array[i]);
3200 	}
3201 }
3202 
3203 static void _rtl8821ae_phy_txpower_training_by_path(struct ieee80211_hw *hw,
3204 						    u8 bw, u8 channel, u8 path)
3205 {
3206 	struct rtl_priv *rtlpriv = rtl_priv(hw);
3207 	struct rtl_phy *rtlphy = &rtlpriv->phy;
3208 
3209 	u8 i;
3210 	u32 power_level, data, offset;
3211 
3212 	if (path >= rtlphy->num_total_rfpath)
3213 		return;
3214 
3215 	data = 0;
3216 	if (path == RF90_PATH_A) {
3217 		power_level =
3218 			_rtl8821ae_get_txpower_index(hw, RF90_PATH_A,
3219 			DESC_RATEMCS7, bw, channel);
3220 		offset =  RA_TXPWRTRAING;
3221 	} else {
3222 		power_level =
3223 			_rtl8821ae_get_txpower_index(hw, RF90_PATH_B,
3224 			DESC_RATEMCS7, bw, channel);
3225 		offset =  RB_TXPWRTRAING;
3226 	}
3227 
3228 	for (i = 0; i < 3; i++) {
3229 		if (i == 0)
3230 			power_level = power_level - 10;
3231 		else if (i == 1)
3232 			power_level = power_level - 8;
3233 		else
3234 			power_level = power_level - 6;
3235 
3236 		data |= (((power_level > 2) ? (power_level) : 2) << (i * 8));
3237 	}
3238 	rtl_set_bbreg(hw, offset, 0xffffff, data);
3239 }
3240 
3241 void rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
3242 					     u8 channel, u8 path)
3243 {
3244 	/* struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); */
3245 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3246 	struct rtl_priv *rtlpriv = rtl_priv(hw);
3247 	struct rtl_phy *rtlphy = &rtlpriv->phy;
3248 	u8 cck_rates[]  = {DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M,
3249 			      DESC_RATE11M};
3250 	u8 sizes_of_cck_retes = 4;
3251 	u8 ofdm_rates[]  = {DESC_RATE6M, DESC_RATE9M, DESC_RATE12M,
3252 				DESC_RATE18M, DESC_RATE24M, DESC_RATE36M,
3253 				DESC_RATE48M, DESC_RATE54M};
3254 	u8 sizes_of_ofdm_retes = 8;
3255 	u8 ht_rates_1t[]  = {DESC_RATEMCS0, DESC_RATEMCS1, DESC_RATEMCS2,
3256 				DESC_RATEMCS3, DESC_RATEMCS4, DESC_RATEMCS5,
3257 				DESC_RATEMCS6, DESC_RATEMCS7};
3258 	u8 sizes_of_ht_retes_1t = 8;
3259 	u8 ht_rates_2t[]  = {DESC_RATEMCS8, DESC_RATEMCS9,
3260 				DESC_RATEMCS10, DESC_RATEMCS11,
3261 				DESC_RATEMCS12, DESC_RATEMCS13,
3262 				DESC_RATEMCS14, DESC_RATEMCS15};
3263 	u8 sizes_of_ht_retes_2t = 8;
3264 	u8 vht_rates_1t[]  = {DESC_RATEVHT1SS_MCS0, DESC_RATEVHT1SS_MCS1,
3265 				DESC_RATEVHT1SS_MCS2, DESC_RATEVHT1SS_MCS3,
3266 				DESC_RATEVHT1SS_MCS4, DESC_RATEVHT1SS_MCS5,
3267 				DESC_RATEVHT1SS_MCS6, DESC_RATEVHT1SS_MCS7,
3268 			     DESC_RATEVHT1SS_MCS8, DESC_RATEVHT1SS_MCS9};
3269 	u8 vht_rates_2t[]  = {DESC_RATEVHT2SS_MCS0, DESC_RATEVHT2SS_MCS1,
3270 				DESC_RATEVHT2SS_MCS2, DESC_RATEVHT2SS_MCS3,
3271 				DESC_RATEVHT2SS_MCS4, DESC_RATEVHT2SS_MCS5,
3272 				DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7,
3273 				DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9};
3274 	u8 sizes_of_vht_retes = 10;
3275 
3276 	if (rtlhal->current_bandtype == BAND_ON_2_4G)
3277 		_rtl8821ae_phy_set_txpower_level_by_path(hw, cck_rates, path, channel,
3278 							 sizes_of_cck_retes);
3279 
3280 	_rtl8821ae_phy_set_txpower_level_by_path(hw, ofdm_rates, path, channel,
3281 						 sizes_of_ofdm_retes);
3282 	_rtl8821ae_phy_set_txpower_level_by_path(hw, ht_rates_1t, path, channel,
3283 						 sizes_of_ht_retes_1t);
3284 	_rtl8821ae_phy_set_txpower_level_by_path(hw, vht_rates_1t, path, channel,
3285 						 sizes_of_vht_retes);
3286 
3287 	if (rtlphy->num_total_rfpath >= 2) {
3288 		_rtl8821ae_phy_set_txpower_level_by_path(hw, ht_rates_2t, path,
3289 							 channel,
3290 							 sizes_of_ht_retes_2t);
3291 		_rtl8821ae_phy_set_txpower_level_by_path(hw, vht_rates_2t, path,
3292 							 channel,
3293 							 sizes_of_vht_retes);
3294 	}
3295 
3296 	_rtl8821ae_phy_txpower_training_by_path(hw, rtlphy->current_chan_bw,
3297 						channel, path);
3298 }
3299 
3300 /*just in case, write txpower in DW, to reduce time*/
3301 void rtl8821ae_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
3302 {
3303 	struct rtl_priv *rtlpriv = rtl_priv(hw);
3304 	struct rtl_phy *rtlphy = &rtlpriv->phy;
3305 	u8 path = 0;
3306 
3307 	for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; ++path)
3308 		rtl8821ae_phy_set_txpower_level_by_path(hw, channel, path);
3309 }
3310 
3311 static long _rtl8821ae_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
3312 					    enum wireless_mode wirelessmode,
3313 					    u8 txpwridx)
3314 {
3315 	long offset;
3316 	long pwrout_dbm;
3317 
3318 	switch (wirelessmode) {
3319 	case WIRELESS_MODE_B:
3320 		offset = -7;
3321 		break;
3322 	case WIRELESS_MODE_G:
3323 	case WIRELESS_MODE_N_24G:
3324 		offset = -8;
3325 		break;
3326 	default:
3327 		offset = -8;
3328 		break;
3329 	}
3330 	pwrout_dbm = txpwridx / 2 + offset;
3331 	return pwrout_dbm;
3332 }
3333 
3334 void rtl8821ae_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
3335 {
3336 	struct rtl_priv *rtlpriv = rtl_priv(hw);
3337 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3338 	enum io_type iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
3339 
3340 	if (!is_hal_stop(rtlhal)) {
3341 		switch (operation) {
3342 		case SCAN_OPT_BACKUP_BAND0:
3343 			iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
3344 			rtlpriv->cfg->ops->set_hw_reg(hw,
3345 						      HW_VAR_IO_CMD,
3346 						      (u8 *)&iotype);
3347 
3348 			break;
3349 		case SCAN_OPT_BACKUP_BAND1:
3350 			iotype = IO_CMD_PAUSE_BAND1_DM_BY_SCAN;
3351 			rtlpriv->cfg->ops->set_hw_reg(hw,
3352 						      HW_VAR_IO_CMD,
3353 						      (u8 *)&iotype);
3354 
3355 			break;
3356 		case SCAN_OPT_RESTORE:
3357 			iotype = IO_CMD_RESUME_DM_BY_SCAN;
3358 			rtlpriv->cfg->ops->set_hw_reg(hw,
3359 						      HW_VAR_IO_CMD,
3360 						      (u8 *)&iotype);
3361 			break;
3362 		default:
3363 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3364 				 "Unknown Scan Backup operation.\n");
3365 			break;
3366 		}
3367 	}
3368 }
3369 
3370 static void _rtl8821ae_phy_set_reg_bw(struct rtl_priv *rtlpriv, u8 bw)
3371 {
3372 	u16 reg_rf_mode_bw, tmp = 0;
3373 
3374 	reg_rf_mode_bw = rtl_read_word(rtlpriv, REG_TRXPTCL_CTL);
3375 	switch (bw) {
3376 	case HT_CHANNEL_WIDTH_20:
3377 		rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, reg_rf_mode_bw & 0xFE7F);
3378 		break;
3379 	case HT_CHANNEL_WIDTH_20_40:
3380 		tmp = reg_rf_mode_bw | BIT(7);
3381 		rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, tmp & 0xFEFF);
3382 		break;
3383 	case HT_CHANNEL_WIDTH_80:
3384 		tmp = reg_rf_mode_bw | BIT(8);
3385 		rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, tmp & 0xFF7F);
3386 		break;
3387 	default:
3388 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "unknown Bandwidth: 0x%x\n", bw);
3389 		break;
3390 	}
3391 }
3392 
3393 static u8 _rtl8821ae_phy_get_secondary_chnl(struct rtl_priv *rtlpriv)
3394 {
3395 	struct rtl_phy *rtlphy = &rtlpriv->phy;
3396 	struct rtl_mac *mac = rtl_mac(rtlpriv);
3397 	u8 sc_set_40 = 0, sc_set_20 = 0;
3398 
3399 	if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) {
3400 		if (mac->cur_80_prime_sc == PRIME_CHNL_OFFSET_LOWER)
3401 			sc_set_40 = VHT_DATA_SC_40_LOWER_OF_80MHZ;
3402 		else if (mac->cur_80_prime_sc == PRIME_CHNL_OFFSET_UPPER)
3403 			sc_set_40 = VHT_DATA_SC_40_UPPER_OF_80MHZ;
3404 		else
3405 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3406 				"SCMapping: Not Correct Primary40MHz Setting\n");
3407 
3408 		if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) &&
3409 			(mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER))
3410 			sc_set_20 = VHT_DATA_SC_20_LOWEST_OF_80MHZ;
3411 		else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) &&
3412 			(mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER))
3413 			sc_set_20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
3414 		else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) &&
3415 			(mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER))
3416 			sc_set_20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
3417 		else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) &&
3418 			(mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER))
3419 			sc_set_20 = VHT_DATA_SC_20_UPPERST_OF_80MHZ;
3420 		else
3421 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3422 				"SCMapping: Not Correct Primary40MHz Setting\n");
3423 	} else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
3424 		if (mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER)
3425 			sc_set_20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
3426 		else if (mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER)
3427 			sc_set_20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
3428 		else
3429 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3430 			 "SCMapping: Not Correct Primary40MHz Setting\n");
3431 	}
3432 	return (sc_set_40 << 4) | sc_set_20;
3433 }
3434 
3435 void rtl8821ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
3436 {
3437 	struct rtl_priv *rtlpriv = rtl_priv(hw);
3438 	struct rtl_phy *rtlphy = &rtlpriv->phy;
3439 	u8 sub_chnl = 0;
3440 	u8 l1pk_val = 0;
3441 
3442 	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3443 		 "Switch to %s bandwidth\n",
3444 		  (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
3445 		  "20MHz" :
3446 		  (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40 ?
3447 		  "40MHz" : "80MHz")));
3448 
3449 	_rtl8821ae_phy_set_reg_bw(rtlpriv, rtlphy->current_chan_bw);
3450 	sub_chnl = _rtl8821ae_phy_get_secondary_chnl(rtlpriv);
3451 	rtl_write_byte(rtlpriv, 0x0483, sub_chnl);
3452 
3453 	switch (rtlphy->current_chan_bw) {
3454 	case HT_CHANNEL_WIDTH_20:
3455 		rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300200);
3456 		rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
3457 
3458 		if (rtlphy->rf_type == RF_2T2R)
3459 			rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, 7);
3460 		else
3461 			rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, 8);
3462 		break;
3463 	case HT_CHANNEL_WIDTH_20_40:
3464 		rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300201);
3465 		rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
3466 		rtl_set_bbreg(hw, RRFMOD, 0x3C, sub_chnl);
3467 		rtl_set_bbreg(hw, RCCAONSEC, 0xf0000000, sub_chnl);
3468 
3469 		if (rtlphy->reg_837 & BIT(2))
3470 			l1pk_val = 6;
3471 		else {
3472 			if (rtlphy->rf_type == RF_2T2R)
3473 				l1pk_val = 7;
3474 			else
3475 				l1pk_val = 8;
3476 		}
3477 		/* 0x848[25:22] = 0x6 */
3478 		rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, l1pk_val);
3479 
3480 		if (sub_chnl == VHT_DATA_SC_20_UPPER_OF_80MHZ)
3481 			rtl_set_bbreg(hw, RCCK_SYSTEM, BCCK_SYSTEM, 1);
3482 		else
3483 			rtl_set_bbreg(hw, RCCK_SYSTEM, BCCK_SYSTEM, 0);
3484 		break;
3485 
3486 	case HT_CHANNEL_WIDTH_80:
3487 		 /* 0x8ac[21,20,9:6,1,0]=8'b11100010 */
3488 		rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300202);
3489 		/* 0x8c4[30] = 1 */
3490 		rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 1);
3491 		rtl_set_bbreg(hw, RRFMOD, 0x3C, sub_chnl);
3492 		rtl_set_bbreg(hw, RCCAONSEC, 0xf0000000, sub_chnl);
3493 
3494 		if (rtlphy->reg_837 & BIT(2))
3495 			l1pk_val = 5;
3496 		else {
3497 			if (rtlphy->rf_type == RF_2T2R)
3498 				l1pk_val = 6;
3499 			else
3500 				l1pk_val = 7;
3501 		}
3502 		rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, l1pk_val);
3503 
3504 		break;
3505 	default:
3506 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3507 			 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
3508 		break;
3509 	}
3510 
3511 	rtl8812ae_fixspur(hw, rtlphy->current_chan_bw, rtlphy->current_channel);
3512 
3513 	rtl8821ae_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
3514 	rtlphy->set_bwmode_inprogress = false;
3515 
3516 	RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
3517 }
3518 
3519 void rtl8821ae_phy_set_bw_mode(struct ieee80211_hw *hw,
3520 			    enum nl80211_channel_type ch_type)
3521 {
3522 	struct rtl_priv *rtlpriv = rtl_priv(hw);
3523 	struct rtl_phy *rtlphy = &rtlpriv->phy;
3524 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3525 	u8 tmp_bw = rtlphy->current_chan_bw;
3526 
3527 	if (rtlphy->set_bwmode_inprogress)
3528 		return;
3529 	rtlphy->set_bwmode_inprogress = true;
3530 	if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw)))
3531 		rtl8821ae_phy_set_bw_mode_callback(hw);
3532 	else {
3533 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
3534 			 "FALSE driver sleep or unload\n");
3535 		rtlphy->set_bwmode_inprogress = false;
3536 		rtlphy->current_chan_bw = tmp_bw;
3537 	}
3538 }
3539 
3540 void rtl8821ae_phy_sw_chnl_callback(struct ieee80211_hw *hw)
3541 {
3542 	struct rtl_priv *rtlpriv = rtl_priv(hw);
3543 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3544 	struct rtl_phy *rtlphy = &rtlpriv->phy;
3545 	u8 channel = rtlphy->current_channel;
3546 	u8 path;
3547 	u32 data;
3548 
3549 	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3550 		 "switch to channel%d\n", rtlphy->current_channel);
3551 	if (is_hal_stop(rtlhal))
3552 		return;
3553 
3554 	if (36 <= channel && channel <= 48)
3555 		data = 0x494;
3556 	else if (50 <= channel && channel <= 64)
3557 		data = 0x453;
3558 	else if (100 <= channel && channel <= 116)
3559 		data = 0x452;
3560 	else if (118 <= channel)
3561 		data = 0x412;
3562 	else
3563 		data = 0x96a;
3564 	rtl_set_bbreg(hw, RFC_AREA, 0x1ffe0000, data);
3565 
3566 	for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; path++) {
3567 		if (36 <= channel && channel <= 64)
3568 			data = 0x101;
3569 		else if (100 <= channel && channel <= 140)
3570 			data = 0x301;
3571 		else if (140 < channel)
3572 			data = 0x501;
3573 		else
3574 			data = 0x000;
3575 		rtl8821ae_phy_set_rf_reg(hw, path, RF_CHNLBW,
3576 			BIT(18)|BIT(17)|BIT(16)|BIT(9)|BIT(8), data);
3577 
3578 		rtl8821ae_phy_set_rf_reg(hw, path, RF_CHNLBW,
3579 			BMASKBYTE0, channel);
3580 
3581 		if (channel > 14) {
3582 			if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
3583 				if (36 <= channel && channel <= 64)
3584 					data = 0x114E9;
3585 				else if (100 <= channel && channel <= 140)
3586 					data = 0x110E9;
3587 				else
3588 					data = 0x110E9;
3589 				rtl8821ae_phy_set_rf_reg(hw, path, RF_APK,
3590 					BRFREGOFFSETMASK, data);
3591 			}
3592 		}
3593 	}
3594 	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
3595 }
3596 
3597 u8 rtl8821ae_phy_sw_chnl(struct ieee80211_hw *hw)
3598 {
3599 	struct rtl_priv *rtlpriv = rtl_priv(hw);
3600 	struct rtl_phy *rtlphy = &rtlpriv->phy;
3601 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3602 	u32 timeout = 1000, timecount = 0;
3603 	u8 channel = rtlphy->current_channel;
3604 
3605 	if (rtlphy->sw_chnl_inprogress)
3606 		return 0;
3607 	if (rtlphy->set_bwmode_inprogress)
3608 		return 0;
3609 
3610 	if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) {
3611 		RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
3612 			 "sw_chnl_inprogress false driver sleep or unload\n");
3613 		return 0;
3614 	}
3615 	while (rtlphy->lck_inprogress && timecount < timeout) {
3616 		mdelay(50);
3617 		timecount += 50;
3618 	}
3619 
3620 	if (rtlphy->current_channel > 14 && rtlhal->current_bandtype != BAND_ON_5G)
3621 		rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_5G);
3622 	else if (rtlphy->current_channel <= 14 && rtlhal->current_bandtype != BAND_ON_2_4G)
3623 		rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_2_4G);
3624 
3625 	rtlphy->sw_chnl_inprogress = true;
3626 	if (channel == 0)
3627 		channel = 1;
3628 
3629 	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3630 		 "switch to channel%d, band type is %d\n",
3631 		 rtlphy->current_channel, rtlhal->current_bandtype);
3632 
3633 	rtl8821ae_phy_sw_chnl_callback(hw);
3634 
3635 	rtl8821ae_dm_clear_txpower_tracking_state(hw);
3636 	rtl8821ae_phy_set_txpower_level(hw, rtlphy->current_channel);
3637 
3638 	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
3639 	rtlphy->sw_chnl_inprogress = false;
3640 	return 1;
3641 }
3642 
3643 u8 _rtl8812ae_get_right_chnl_place_for_iqk(u8 chnl)
3644 {
3645 	u8 channel_all[TARGET_CHNL_NUM_2G_5G_8812] = {
3646 		1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
3647 		14, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54,
3648 		56, 58, 60, 62, 64, 100, 102, 104, 106, 108,
3649 		110, 112, 114, 116, 118, 120, 122, 124, 126,
3650 		128, 130, 132, 134, 136, 138, 140, 149, 151,
3651 		153, 155, 157, 159, 161, 163, 165};
3652 	u8 place = chnl;
3653 
3654 	if (chnl > 14) {
3655 		for (place = 14; place < sizeof(channel_all); place++)
3656 			if (channel_all[place] == chnl)
3657 				return place-13;
3658 	}
3659 
3660 	return 0;
3661 }
3662 
3663 #define MACBB_REG_NUM 10
3664 #define AFE_REG_NUM 14
3665 #define RF_REG_NUM 3
3666 
3667 static void _rtl8821ae_iqk_backup_macbb(struct ieee80211_hw *hw,
3668 					u32 *macbb_backup,
3669 					u32 *backup_macbb_reg, u32 mac_bb_num)
3670 {
3671 	struct rtl_priv *rtlpriv = rtl_priv(hw);
3672 	u32 i;
3673 
3674 	rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3675 	/*save MACBB default value*/
3676 	for (i = 0; i < mac_bb_num; i++)
3677 		macbb_backup[i] = rtl_read_dword(rtlpriv, backup_macbb_reg[i]);
3678 
3679 	RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupMacBB Success!!!!\n");
3680 }
3681 
3682 static void _rtl8821ae_iqk_backup_afe(struct ieee80211_hw *hw, u32 *afe_backup,
3683 				      u32 *backup_afe_REG, u32 afe_num)
3684 {
3685 	struct rtl_priv *rtlpriv = rtl_priv(hw);
3686 	u32 i;
3687 
3688 	rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3689 	/*Save AFE Parameters */
3690 	for (i = 0; i < afe_num; i++)
3691 		afe_backup[i] = rtl_read_dword(rtlpriv, backup_afe_REG[i]);
3692 	RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupAFE Success!!!!\n");
3693 }
3694 
3695 static void _rtl8821ae_iqk_backup_rf(struct ieee80211_hw *hw, u32 *rfa_backup,
3696 				     u32 *rfb_backup, u32 *backup_rf_reg,
3697 				     u32 rf_num)
3698 {
3699 	struct rtl_priv *rtlpriv = rtl_priv(hw);
3700 	u32 i;
3701 
3702 	rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3703 	/*Save RF Parameters*/
3704 	for (i = 0; i < rf_num; i++) {
3705 		rfa_backup[i] = rtl_get_rfreg(hw, RF90_PATH_A, backup_rf_reg[i],
3706 					      BMASKDWORD);
3707 		rfb_backup[i] = rtl_get_rfreg(hw, RF90_PATH_B, backup_rf_reg[i],
3708 					      BMASKDWORD);
3709 	}
3710 	RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupRF Success!!!!\n");
3711 }
3712 
3713 static void _rtl8821ae_iqk_configure_mac(
3714 		struct ieee80211_hw *hw
3715 		)
3716 {
3717 	struct rtl_priv *rtlpriv = rtl_priv(hw);
3718 	/* ========MAC register setting========*/
3719 	rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3720 	rtl_write_byte(rtlpriv, 0x522, 0x3f);
3721 	rtl_set_bbreg(hw, 0x550, BIT(11) | BIT(3), 0x0);
3722 	rtl_write_byte(rtlpriv, 0x808, 0x00);		/*RX ante off*/
3723 	rtl_set_bbreg(hw, 0x838, 0xf, 0xc);		/*CCA off*/
3724 }
3725 
3726 static void _rtl8821ae_iqk_tx_fill_iqc(struct ieee80211_hw *hw,
3727 				       enum radio_path path, u32 tx_x, u32 tx_y)
3728 {
3729 	struct rtl_priv *rtlpriv = rtl_priv(hw);
3730 	switch (path) {
3731 	case RF90_PATH_A:
3732 		/* [31] = 1 --> Page C1 */
3733 		rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1);
3734 		rtl_write_dword(rtlpriv, 0xc90, 0x00000080);
3735 		rtl_write_dword(rtlpriv, 0xcc4, 0x20040000);
3736 		rtl_write_dword(rtlpriv, 0xcc8, 0x20000000);
3737 		rtl_set_bbreg(hw, 0xccc, 0x000007ff, tx_y);
3738 		rtl_set_bbreg(hw, 0xcd4, 0x000007ff, tx_x);
3739 		RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3740 			 "TX_X = %x;;TX_Y = %x =====> fill to IQC\n",
3741 			 tx_x, tx_y);
3742 		RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3743 			 "0xcd4 = %x;;0xccc = %x ====>fill to IQC\n",
3744 			 rtl_get_bbreg(hw, 0xcd4, 0x000007ff),
3745 			 rtl_get_bbreg(hw, 0xccc, 0x000007ff));
3746 		break;
3747 	default:
3748 		break;
3749 	}
3750 }
3751 
3752 static void _rtl8821ae_iqk_rx_fill_iqc(struct ieee80211_hw *hw,
3753 				       enum radio_path path, u32 rx_x, u32 rx_y)
3754 {
3755 	struct rtl_priv *rtlpriv = rtl_priv(hw);
3756 	switch (path) {
3757 	case RF90_PATH_A:
3758 		rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3759 		rtl_set_bbreg(hw, 0xc10, 0x000003ff, rx_x>>1);
3760 		rtl_set_bbreg(hw, 0xc10, 0x03ff0000, rx_y>>1);
3761 		RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3762 			 "rx_x = %x;;rx_y = %x ====>fill to IQC\n",
3763 			 rx_x>>1, rx_y>>1);
3764 		RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3765 			 "0xc10 = %x ====>fill to IQC\n",
3766 			 rtl_read_dword(rtlpriv, 0xc10));
3767 		break;
3768 	default:
3769 		break;
3770 	}
3771 }
3772 
3773 #define cal_num 10
3774 
3775 static void _rtl8821ae_iqk_tx(struct ieee80211_hw *hw, enum radio_path path)
3776 {
3777 	struct rtl_priv *rtlpriv = rtl_priv(hw);
3778 	struct rtl_phy *rtlphy = &rtlpriv->phy;
3779 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3780 
3781 	u32	tx_fail, rx_fail, delay_count, iqk_ready, cal_retry, cal = 0, temp_reg65;
3782 	int	tx_x = 0, tx_y = 0, rx_x = 0, rx_y = 0, tx_average = 0, rx_average = 0;
3783 	int	tx_x0[cal_num], tx_y0[cal_num], tx_x0_rxk[cal_num],
3784 		tx_y0_rxk[cal_num], rx_x0[cal_num], rx_y0[cal_num];
3785 	bool	tx0iqkok = false, rx0iqkok = false;
3786 	bool	vdf_enable = false;
3787 	int	i, k, vdf_y[3], vdf_x[3], tx_dt[3], rx_dt[3],
3788 		ii, dx = 0, dy = 0, tx_finish = 0, rx_finish = 0;
3789 
3790 	RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3791 			"BandWidth = %d.\n",
3792 			 rtlphy->current_chan_bw);
3793 	if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80)
3794 		vdf_enable = true;
3795 
3796 	while (cal < cal_num) {
3797 		switch (path) {
3798 		case RF90_PATH_A:
3799 			temp_reg65 = rtl_get_rfreg(hw, path, 0x65, 0xffffffff);
3800 			/* Path-A LOK */
3801 			rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3802 			/*========Path-A AFE all on========*/
3803 			/*Port 0 DAC/ADC on*/
3804 			rtl_write_dword(rtlpriv, 0xc60, 0x77777777);
3805 			rtl_write_dword(rtlpriv, 0xc64, 0x77777777);
3806 			rtl_write_dword(rtlpriv, 0xc68, 0x19791979);
3807 			rtl_write_dword(rtlpriv, 0xc6c, 0x19791979);
3808 			rtl_write_dword(rtlpriv, 0xc70, 0x19791979);
3809 			rtl_write_dword(rtlpriv, 0xc74, 0x19791979);
3810 			rtl_write_dword(rtlpriv, 0xc78, 0x19791979);
3811 			rtl_write_dword(rtlpriv, 0xc7c, 0x19791979);
3812 			rtl_write_dword(rtlpriv, 0xc80, 0x19791979);
3813 			rtl_write_dword(rtlpriv, 0xc84, 0x19791979);
3814 
3815 			rtl_set_bbreg(hw, 0xc00, 0xf, 0x4); /*hardware 3-wire off*/
3816 
3817 			/* LOK Setting */
3818 			/* ====== LOK ====== */
3819 			/*DAC/ADC sampling rate (160 MHz)*/
3820 			rtl_set_bbreg(hw, 0xc5c, BIT(26) | BIT(25) | BIT(24), 0x7);
3821 
3822 			/* 2. LoK RF Setting (at BW = 20M) */
3823 			rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80002);
3824 			rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x3);     /* BW 20M */
3825 			rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x20000);
3826 			rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0003f);
3827 			rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xf3fc3);
3828 			rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d5);
3829 			rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
3830 			rtl_set_bbreg(hw, 0xcb8, 0xf, 0xd);
3831 			rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
3832 			rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
3833 			rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1);
3834 			rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
3835 			rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
3836 			rtl_write_dword(rtlpriv, 0x984, 0x00462910);/* [0]:AGC_en, [15]:idac_K_Mask */
3837 
3838 			rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3839 			rtl_write_dword(rtlpriv, 0xc88, 0x821403f4);
3840 
3841 			if (rtlhal->current_bandtype)
3842 				rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96);
3843 			else
3844 				rtl_write_dword(rtlpriv, 0xc8c, 0x28163e96);
3845 
3846 			rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3847 			rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3848 			rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8ϥ\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3849 			rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3850 			rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3851 
3852 			mdelay(10); /* Delay 10ms */
3853 			rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
3854 
3855 			rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3856 			rtl_set_rfreg(hw, path, 0x58, 0x7fe00, rtl_get_rfreg(hw, path, 0x8, 0xffc00)); /* Load LOK */
3857 
3858 			switch (rtlphy->current_chan_bw) {
3859 			case 1:
3860 				rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x1);
3861 				break;
3862 			case 2:
3863 				rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x0);
3864 				break;
3865 			default:
3866 				break;
3867 			}
3868 
3869 			rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3870 
3871 			/* 3. TX RF Setting */
3872 			rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3873 			rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
3874 			rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x20000);
3875 			rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0003f);
3876 			rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xf3fc3);
3877 			rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d5);
3878 			rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
3879 			rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
3880 			/* ODM_SetBBReg(pDM_Odm, 0xcb8, 0xf, 0xd); */
3881 			rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
3882 			rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
3883 			rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1);
3884 			rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
3885 			rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
3886 			rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
3887 
3888 			rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3889 			rtl_write_dword(rtlpriv, 0xc88, 0x821403f1);
3890 			if (rtlhal->current_bandtype)
3891 				rtl_write_dword(rtlpriv, 0xc8c, 0x40163e96);
3892 			else
3893 				rtl_write_dword(rtlpriv, 0xc8c, 0x00163e96);
3894 
3895 			if (vdf_enable == 1) {
3896 				RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "VDF_enable\n");
3897 				for (k = 0; k <= 2; k++) {
3898 					switch (k) {
3899 					case 0:
3900 						rtl_write_dword(rtlpriv, 0xc80, 0x18008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3901 						rtl_write_dword(rtlpriv, 0xc84, 0x38008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3902 						rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);
3903 						break;
3904 					case 1:
3905 						rtl_set_bbreg(hw, 0xc80, BIT(28), 0x0);
3906 						rtl_set_bbreg(hw, 0xc84, BIT(28), 0x0);
3907 						rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);
3908 						break;
3909 					case 2:
3910 						RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3911 							"vdf_y[1] = %x;;;vdf_y[0] = %x\n", vdf_y[1]>>21 & 0x00007ff, vdf_y[0]>>21 & 0x00007ff);
3912 						RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3913 							"vdf_x[1] = %x;;;vdf_x[0] = %x\n", vdf_x[1]>>21 & 0x00007ff, vdf_x[0]>>21 & 0x00007ff);
3914 						tx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20);
3915 						tx_dt[cal] = ((16*tx_dt[cal])*10000/15708);
3916 						tx_dt[cal] = (tx_dt[cal] >> 1)+(tx_dt[cal] & BIT(0));
3917 						rtl_write_dword(rtlpriv, 0xc80, 0x18008c20);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3918 						rtl_write_dword(rtlpriv, 0xc84, 0x38008c20);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3919 						rtl_set_bbreg(hw, 0xce8, BIT(31), 0x1);
3920 						rtl_set_bbreg(hw, 0xce8, 0x3fff0000, tx_dt[cal] & 0x00003fff);
3921 						break;
3922 					default:
3923 						break;
3924 					}
3925 					rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8ϥ\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3926 					cal_retry = 0;
3927 					while (1) {
3928 						/* one shot */
3929 						rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3930 						rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3931 
3932 						mdelay(10); /* Delay 10ms */
3933 						rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
3934 						delay_count = 0;
3935 						while (1) {
3936 							iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
3937 							if ((~iqk_ready) || (delay_count > 20))
3938 								break;
3939 							else{
3940 								mdelay(1);
3941 								delay_count++;
3942 							}
3943 						}
3944 
3945 						if (delay_count < 20) {							/* If 20ms No Result, then cal_retry++ */
3946 							/* ============TXIQK Check============== */
3947 							tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
3948 
3949 							if (~tx_fail) {
3950 								rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
3951 								vdf_x[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
3952 								rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
3953 								vdf_y[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
3954 								tx0iqkok = true;
3955 								break;
3956 							} else {
3957 								rtl_set_bbreg(hw, 0xccc, 0x000007ff, 0x0);
3958 								rtl_set_bbreg(hw, 0xcd4, 0x000007ff, 0x200);
3959 								tx0iqkok = false;
3960 								cal_retry++;
3961 								if (cal_retry == 10)
3962 									break;
3963 							}
3964 						} else {
3965 							tx0iqkok = false;
3966 							cal_retry++;
3967 							if (cal_retry == 10)
3968 								break;
3969 						}
3970 					}
3971 				}
3972 				if (k == 3) {
3973 					tx_x0[cal] = vdf_x[k-1];
3974 					tx_y0[cal] = vdf_y[k-1];
3975 				}
3976 			} else {
3977 				rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3978 				rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3979 				rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8ϥ\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3980 				cal_retry = 0;
3981 				while (1) {
3982 					/* one shot */
3983 					rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3984 					rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3985 
3986 					mdelay(10); /* Delay 10ms */
3987 					rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
3988 					delay_count = 0;
3989 					while (1) {
3990 						iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
3991 						if ((~iqk_ready) || (delay_count > 20))
3992 							break;
3993 						else{
3994 							mdelay(1);
3995 							delay_count++;
3996 						}
3997 					}
3998 
3999 					if (delay_count < 20) {							/* If 20ms No Result, then cal_retry++ */
4000 						/* ============TXIQK Check============== */
4001 						tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4002 
4003 						if (~tx_fail) {
4004 							rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4005 							tx_x0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4006 							rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4007 							tx_y0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4008 							tx0iqkok = true;
4009 							break;
4010 						} else {
4011 							rtl_set_bbreg(hw, 0xccc, 0x000007ff, 0x0);
4012 							rtl_set_bbreg(hw, 0xcd4, 0x000007ff, 0x200);
4013 							tx0iqkok = false;
4014 							cal_retry++;
4015 							if (cal_retry == 10)
4016 								break;
4017 						}
4018 					} else {
4019 						tx0iqkok = false;
4020 						cal_retry++;
4021 						if (cal_retry == 10)
4022 							break;
4023 					}
4024 				}
4025 			}
4026 
4027 			if (tx0iqkok == false)
4028 				break;				/* TXK fail, Don't do RXK */
4029 
4030 			if (vdf_enable == 1) {
4031 				rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);    /* TX VDF Disable */
4032 				RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RXVDF Start\n");
4033 				for (k = 0; k <= 2; k++) {
4034 					/* ====== RX mode TXK (RXK Step 1) ====== */
4035 					rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4036 					/* 1. TX RF Setting */
4037 					rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4038 					rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4039 					rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x00029);
4040 					rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xd7ffb);
4041 					rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4042 					rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
4043 					rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4044 
4045 					rtl_set_bbreg(hw, 0xcb8, 0xf, 0xd);
4046 					rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
4047 					rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
4048 					rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
4049 					rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4050 					rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
4051 					rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4052 					switch (k) {
4053 					case 0:
4054 						{
4055 							rtl_write_dword(rtlpriv, 0xc80, 0x18008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4056 							rtl_write_dword(rtlpriv, 0xc84, 0x38008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4057 							rtl_set_bbreg(hw, 0xce8, BIT(30), 0x0);
4058 						}
4059 						break;
4060 					case 1:
4061 						{
4062 							rtl_write_dword(rtlpriv, 0xc80, 0x08008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4063 							rtl_write_dword(rtlpriv, 0xc84, 0x28008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4064 							rtl_set_bbreg(hw, 0xce8, BIT(30), 0x0);
4065 						}
4066 						break;
4067 					case 2:
4068 						{
4069 							RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4070 							"VDF_Y[1] = %x;;;VDF_Y[0] = %x\n",
4071 							vdf_y[1]>>21 & 0x00007ff, vdf_y[0]>>21 & 0x00007ff);
4072 							RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4073 							"VDF_X[1] = %x;;;VDF_X[0] = %x\n",
4074 							vdf_x[1]>>21 & 0x00007ff, vdf_x[0]>>21 & 0x00007ff);
4075 							rx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20);
4076 							RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "Rx_dt = %d\n", rx_dt[cal]);
4077 							rx_dt[cal] = ((16*rx_dt[cal])*10000/13823);
4078 							rx_dt[cal] = (rx_dt[cal] >> 1)+(rx_dt[cal] & BIT(0));
4079 							rtl_write_dword(rtlpriv, 0xc80, 0x18008c20);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4080 							rtl_write_dword(rtlpriv, 0xc84, 0x38008c20);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4081 							rtl_set_bbreg(hw, 0xce8, 0x00003fff, rx_dt[cal] & 0x00003fff);
4082 						}
4083 						break;
4084 					default:
4085 						break;
4086 					}
4087 					rtl_write_dword(rtlpriv, 0xc88, 0x821603e0);
4088 					rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96);
4089 					rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8ϥ\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4090 					cal_retry = 0;
4091 					while (1) {
4092 						/* one shot */
4093 						rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4094 						rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4095 
4096 						mdelay(10); /* Delay 10ms */
4097 						rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4098 						delay_count = 0;
4099 						while (1) {
4100 							iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4101 							if ((~iqk_ready) || (delay_count > 20))
4102 								break;
4103 							else{
4104 								mdelay(1);
4105 								delay_count++;
4106 							}
4107 						}
4108 
4109 						if (delay_count < 20) {							/* If 20ms No Result, then cal_retry++ */
4110 							/* ============TXIQK Check============== */
4111 							tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4112 
4113 							if (~tx_fail) {
4114 								rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4115 								tx_x0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4116 								rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4117 								tx_y0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4118 								tx0iqkok = true;
4119 								break;
4120 							} else{
4121 								tx0iqkok = false;
4122 								cal_retry++;
4123 								if (cal_retry == 10)
4124 									break;
4125 							}
4126 						} else {
4127 							tx0iqkok = false;
4128 							cal_retry++;
4129 							if (cal_retry == 10)
4130 								break;
4131 						}
4132 					}
4133 
4134 					if (tx0iqkok == false) {   /* If RX mode TXK fail, then take TXK Result */
4135 						tx_x0_rxk[cal] = tx_x0[cal];
4136 						tx_y0_rxk[cal] = tx_y0[cal];
4137 						tx0iqkok = true;
4138 						RT_TRACE(rtlpriv,
4139 							 COMP_IQK,
4140 							 DBG_LOUD,
4141 							 "RXK Step 1 fail\n");
4142 					}
4143 
4144 					/* ====== RX IQK ====== */
4145 					rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4146 					/* 1. RX RF Setting */
4147 					rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4148 					rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4149 					rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0002f);
4150 					rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xfffbb);
4151 					rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x88001);
4152 					rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d8);
4153 					rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4154 
4155 					rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0_rxk[cal])>>21&0x000007ff);
4156 					rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0_rxk[cal])>>21&0x000007ff);
4157 					rtl_set_bbreg(hw, 0x978, BIT(31), 0x1);
4158 					rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0);
4159 					rtl_set_bbreg(hw, 0xcb8, 0xF, 0xe);
4160 					rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4161 					rtl_write_dword(rtlpriv, 0x984, 0x0046a911);
4162 
4163 					rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4164 					rtl_set_bbreg(hw, 0xc80, BIT(29), 0x1);
4165 					rtl_set_bbreg(hw, 0xc84, BIT(29), 0x0);
4166 					rtl_write_dword(rtlpriv, 0xc88, 0x02140119);
4167 
4168 					rtl_write_dword(rtlpriv, 0xc8c, 0x28160d00); /* pDM_Odm->SupportInterface == 1 */
4169 
4170 					if (k == 2)
4171 						rtl_set_bbreg(hw, 0xce8, BIT(30), 0x1);  /* RX VDF Enable */
4172 					rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8ϥ\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4173 
4174 					cal_retry = 0;
4175 					while (1) {
4176 						/* one shot */
4177 						rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4178 						rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4179 
4180 						mdelay(10); /* Delay 10ms */
4181 						rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4182 						delay_count = 0;
4183 						while (1) {
4184 							iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4185 							if ((~iqk_ready) || (delay_count > 20))
4186 								break;
4187 							else{
4188 								mdelay(1);
4189 								delay_count++;
4190 							}
4191 						}
4192 
4193 						if (delay_count < 20) {	/* If 20ms No Result, then cal_retry++ */
4194 							/* ============RXIQK Check============== */
4195 							rx_fail = rtl_get_bbreg(hw, 0xd00, BIT(11));
4196 							if (rx_fail == 0) {
4197 								rtl_write_dword(rtlpriv, 0xcb8, 0x06000000);
4198 								vdf_x[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4199 								rtl_write_dword(rtlpriv, 0xcb8, 0x08000000);
4200 								vdf_y[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4201 								rx0iqkok = true;
4202 								break;
4203 							} else {
4204 								rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x200>>1);
4205 								rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0x0>>1);
4206 								rx0iqkok = false;
4207 								cal_retry++;
4208 								if (cal_retry == 10)
4209 									break;
4210 
4211 							}
4212 						} else{
4213 							rx0iqkok = false;
4214 							cal_retry++;
4215 							if (cal_retry == 10)
4216 								break;
4217 						}
4218 					}
4219 
4220 				}
4221 				if (k == 3) {
4222 					rx_x0[cal] = vdf_x[k-1];
4223 					rx_y0[cal] = vdf_y[k-1];
4224 				}
4225 				rtl_set_bbreg(hw, 0xce8, BIT(31), 0x1);    /* TX VDF Enable */
4226 			}
4227 
4228 			else{
4229 				/* ====== RX mode TXK (RXK Step 1) ====== */
4230 				rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4231 				/* 1. TX RF Setting */
4232 				rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4233 				rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4234 				rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x00029);
4235 				rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xd7ffb);
4236 				rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4237 				rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
4238 				rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4239 				rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4240 				rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
4241 				rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
4242 
4243 				rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4244 				rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4245 				rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4246 				rtl_write_dword(rtlpriv, 0xc88, 0x821603e0);
4247 				/* ODM_Write4Byte(pDM_Odm, 0xc8c, 0x68163e96); */
4248 				rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8ϥ\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4249 				cal_retry = 0;
4250 				while (1) {
4251 					/* one shot */
4252 					rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4253 					rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4254 
4255 					mdelay(10); /* Delay 10ms */
4256 					rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4257 					delay_count = 0;
4258 					while (1) {
4259 						iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4260 						if ((~iqk_ready) || (delay_count > 20))
4261 							break;
4262 						else{
4263 							mdelay(1);
4264 							delay_count++;
4265 						}
4266 					}
4267 
4268 					if (delay_count < 20) {							/* If 20ms No Result, then cal_retry++ */
4269 						/* ============TXIQK Check============== */
4270 						tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4271 
4272 						if (~tx_fail) {
4273 							rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4274 							tx_x0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4275 							rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4276 							tx_y0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4277 							tx0iqkok = true;
4278 							break;
4279 						} else {
4280 							tx0iqkok = false;
4281 							cal_retry++;
4282 							if (cal_retry == 10)
4283 								break;
4284 						}
4285 					} else{
4286 						tx0iqkok = false;
4287 						cal_retry++;
4288 						if (cal_retry == 10)
4289 							break;
4290 					}
4291 				}
4292 
4293 				if (tx0iqkok == false) {   /* If RX mode TXK fail, then take TXK Result */
4294 					tx_x0_rxk[cal] = tx_x0[cal];
4295 					tx_y0_rxk[cal] = tx_y0[cal];
4296 					tx0iqkok = true;
4297 					RT_TRACE(rtlpriv, COMP_IQK,
4298 						 DBG_LOUD, "1");
4299 				}
4300 
4301 				/* ====== RX IQK ====== */
4302 				rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4303 				/* 1. RX RF Setting */
4304 				rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4305 				rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4306 				rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0002f);
4307 				rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xfffbb);
4308 				rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x88001);
4309 				rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d8);
4310 				rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4311 
4312 				rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0_rxk[cal])>>21&0x000007ff);
4313 				rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0_rxk[cal])>>21&0x000007ff);
4314 				rtl_set_bbreg(hw, 0x978, BIT(31), 0x1);
4315 				rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0);
4316 				/* ODM_SetBBReg(pDM_Odm, 0xcb8, 0xF, 0xe); */
4317 				rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4318 				rtl_write_dword(rtlpriv, 0x984, 0x0046a911);
4319 
4320 				rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4321 				rtl_write_dword(rtlpriv, 0xc80, 0x38008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4322 				rtl_write_dword(rtlpriv, 0xc84, 0x18008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4323 				rtl_write_dword(rtlpriv, 0xc88, 0x02140119);
4324 
4325 				rtl_write_dword(rtlpriv, 0xc8c, 0x28160d00); /*pDM_Odm->SupportInterface == 1*/
4326 
4327 				rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8ϥ\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4328 
4329 				cal_retry = 0;
4330 				while (1) {
4331 					/* one shot */
4332 					rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4333 					rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4334 
4335 					mdelay(10); /* Delay 10ms */
4336 					rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4337 					delay_count = 0;
4338 					while (1) {
4339 						iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4340 						if ((~iqk_ready) || (delay_count > 20))
4341 							break;
4342 						else{
4343 							mdelay(1);
4344 							delay_count++;
4345 						}
4346 					}
4347 
4348 					if (delay_count < 20) {	/* If 20ms No Result, then cal_retry++ */
4349 						/* ============RXIQK Check============== */
4350 						rx_fail = rtl_get_bbreg(hw, 0xd00, BIT(11));
4351 						if (rx_fail == 0) {
4352 							rtl_write_dword(rtlpriv, 0xcb8, 0x06000000);
4353 							rx_x0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4354 							rtl_write_dword(rtlpriv, 0xcb8, 0x08000000);
4355 							rx_y0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4356 							rx0iqkok = true;
4357 							break;
4358 						} else{
4359 							rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x200>>1);
4360 							rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0x0>>1);
4361 							rx0iqkok = false;
4362 							cal_retry++;
4363 							if (cal_retry == 10)
4364 								break;
4365 
4366 						}
4367 					} else{
4368 						rx0iqkok = false;
4369 						cal_retry++;
4370 						if (cal_retry == 10)
4371 							break;
4372 					}
4373 				}
4374 			}
4375 
4376 			if (tx0iqkok)
4377 				tx_average++;
4378 			if (rx0iqkok)
4379 				rx_average++;
4380 			rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4381 			rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4382 			break;
4383 		default:
4384 			break;
4385 		}
4386 		cal++;
4387 	}
4388 
4389 	/* FillIQK Result */
4390 	switch (path) {
4391 	case RF90_PATH_A:
4392 		RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4393 			 "========Path_A =======\n");
4394 		if (tx_average == 0)
4395 			break;
4396 
4397 		for (i = 0; i < tx_average; i++) {
4398 			RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4399 				 "TX_X0_RXK[%d] = %x ;; TX_Y0_RXK[%d] = %x\n", i,
4400 				 (tx_x0_rxk[i])>>21&0x000007ff, i,
4401 				 (tx_y0_rxk[i])>>21&0x000007ff);
4402 			RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4403 				 "TX_X0[%d] = %x ;; TX_Y0[%d] = %x\n", i,
4404 				 (tx_x0[i])>>21&0x000007ff, i,
4405 				 (tx_y0[i])>>21&0x000007ff);
4406 		}
4407 		for (i = 0; i < tx_average; i++) {
4408 			for (ii = i+1; ii < tx_average; ii++) {
4409 				dx = (tx_x0[i]>>21) - (tx_x0[ii]>>21);
4410 				if (dx < 3 && dx > -3) {
4411 					dy = (tx_y0[i]>>21) - (tx_y0[ii]>>21);
4412 					if (dy < 3 && dy > -3) {
4413 						tx_x = ((tx_x0[i]>>21) + (tx_x0[ii]>>21))/2;
4414 						tx_y = ((tx_y0[i]>>21) + (tx_y0[ii]>>21))/2;
4415 						tx_finish = 1;
4416 						break;
4417 					}
4418 				}
4419 			}
4420 			if (tx_finish == 1)
4421 				break;
4422 		}
4423 
4424 		if (tx_finish == 1)
4425 			_rtl8821ae_iqk_tx_fill_iqc(hw, path, tx_x, tx_y); /* ? */
4426 		else
4427 			_rtl8821ae_iqk_tx_fill_iqc(hw, path, 0x200, 0x0);
4428 
4429 		if (rx_average == 0)
4430 			break;
4431 
4432 		for (i = 0; i < rx_average; i++)
4433 			RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4434 				"RX_X0[%d] = %x ;; RX_Y0[%d] = %x\n", i,
4435 				(rx_x0[i])>>21&0x000007ff, i,
4436 				(rx_y0[i])>>21&0x000007ff);
4437 		for (i = 0; i < rx_average; i++) {
4438 			for (ii = i+1; ii < rx_average; ii++) {
4439 				dx = (rx_x0[i]>>21) - (rx_x0[ii]>>21);
4440 				if (dx < 4 && dx > -4) {
4441 					dy = (rx_y0[i]>>21) - (rx_y0[ii]>>21);
4442 					if (dy < 4 && dy > -4) {
4443 						rx_x = ((rx_x0[i]>>21) + (rx_x0[ii]>>21))/2;
4444 						rx_y = ((rx_y0[i]>>21) + (rx_y0[ii]>>21))/2;
4445 						rx_finish = 1;
4446 						break;
4447 					}
4448 				}
4449 			}
4450 			if (rx_finish == 1)
4451 				break;
4452 		}
4453 
4454 		if (rx_finish == 1)
4455 			_rtl8821ae_iqk_rx_fill_iqc(hw, path, rx_x, rx_y);
4456 		else
4457 			_rtl8821ae_iqk_rx_fill_iqc(hw, path, 0x200, 0x0);
4458 		break;
4459 	default:
4460 		break;
4461 	}
4462 }
4463 
4464 static void _rtl8821ae_iqk_restore_rf(struct ieee80211_hw *hw,
4465 				      enum radio_path path,
4466 				      u32 *backup_rf_reg,
4467 				      u32 *rf_backup, u32 rf_reg_num)
4468 {
4469 	struct rtl_priv *rtlpriv = rtl_priv(hw);
4470 	u32 i;
4471 
4472 	rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4473 	for (i = 0; i < RF_REG_NUM; i++)
4474 		rtl_set_rfreg(hw, path, backup_rf_reg[i], RFREG_OFFSET_MASK,
4475 			      rf_backup[i]);
4476 
4477 	switch (path) {
4478 	case RF90_PATH_A:
4479 		RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4480 			 "RestoreRF Path A Success!!!!\n");
4481 		break;
4482 	default:
4483 			break;
4484 	}
4485 }
4486 
4487 static void _rtl8821ae_iqk_restore_afe(struct ieee80211_hw *hw,
4488 				       u32 *afe_backup, u32 *backup_afe_reg,
4489 				       u32 afe_num)
4490 {
4491 	u32 i;
4492 	struct rtl_priv *rtlpriv = rtl_priv(hw);
4493 
4494 	rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4495 	/* Reload AFE Parameters */
4496 	for (i = 0; i < afe_num; i++)
4497 		rtl_write_dword(rtlpriv, backup_afe_reg[i], afe_backup[i]);
4498 	rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4499 	rtl_write_dword(rtlpriv, 0xc80, 0x0);
4500 	rtl_write_dword(rtlpriv, 0xc84, 0x0);
4501 	rtl_write_dword(rtlpriv, 0xc88, 0x0);
4502 	rtl_write_dword(rtlpriv, 0xc8c, 0x3c000000);
4503 	rtl_write_dword(rtlpriv, 0xc90, 0x00000080);
4504 	rtl_write_dword(rtlpriv, 0xc94, 0x00000000);
4505 	rtl_write_dword(rtlpriv, 0xcc4, 0x20040000);
4506 	rtl_write_dword(rtlpriv, 0xcc8, 0x20000000);
4507 	rtl_write_dword(rtlpriv, 0xcb8, 0x0);
4508 	RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RestoreAFE Success!!!!\n");
4509 }
4510 
4511 static void _rtl8821ae_iqk_restore_macbb(struct ieee80211_hw *hw,
4512 					 u32 *macbb_backup,
4513 					 u32 *backup_macbb_reg,
4514 					 u32 macbb_num)
4515 {
4516 	u32 i;
4517 	struct rtl_priv *rtlpriv = rtl_priv(hw);
4518 
4519 	rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4520 	/* Reload MacBB Parameters */
4521 	for (i = 0; i < macbb_num; i++)
4522 		rtl_write_dword(rtlpriv, backup_macbb_reg[i], macbb_backup[i]);
4523 	RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RestoreMacBB Success!!!!\n");
4524 }
4525 
4526 #undef MACBB_REG_NUM
4527 #undef AFE_REG_NUM
4528 #undef RF_REG_NUM
4529 
4530 #define MACBB_REG_NUM 11
4531 #define AFE_REG_NUM 12
4532 #define RF_REG_NUM 3
4533 
4534 static void _rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw)
4535 {
4536 	u32	macbb_backup[MACBB_REG_NUM];
4537 	u32 afe_backup[AFE_REG_NUM];
4538 	u32 rfa_backup[RF_REG_NUM];
4539 	u32 rfb_backup[RF_REG_NUM];
4540 	u32 backup_macbb_reg[MACBB_REG_NUM] = {
4541 		0xb00, 0x520, 0x550, 0x808, 0x90c, 0xc00, 0xc50,
4542 		0xe00, 0xe50, 0x838, 0x82c
4543 	};
4544 	u32 backup_afe_reg[AFE_REG_NUM] = {
4545 		0xc5c, 0xc60, 0xc64, 0xc68, 0xc6c, 0xc70, 0xc74,
4546 		0xc78, 0xc7c, 0xc80, 0xc84, 0xcb8
4547 	};
4548 	u32	backup_rf_reg[RF_REG_NUM] = {0x65, 0x8f, 0x0};
4549 
4550 	_rtl8821ae_iqk_backup_macbb(hw, macbb_backup, backup_macbb_reg,
4551 				    MACBB_REG_NUM);
4552 	_rtl8821ae_iqk_backup_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM);
4553 	_rtl8821ae_iqk_backup_rf(hw, rfa_backup, rfb_backup, backup_rf_reg,
4554 				 RF_REG_NUM);
4555 
4556 	_rtl8821ae_iqk_configure_mac(hw);
4557 	_rtl8821ae_iqk_tx(hw, RF90_PATH_A);
4558 	_rtl8821ae_iqk_restore_rf(hw, RF90_PATH_A, backup_rf_reg, rfa_backup,
4559 				  RF_REG_NUM);
4560 
4561 	_rtl8821ae_iqk_restore_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM);
4562 	_rtl8821ae_iqk_restore_macbb(hw, macbb_backup, backup_macbb_reg,
4563 				     MACBB_REG_NUM);
4564 }
4565 
4566 static void _rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool main)
4567 {
4568 	struct rtl_priv *rtlpriv = rtl_priv(hw);
4569 	/* struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); */
4570 	/* struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); */
4571 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
4572 
4573 	if (main)
4574 		rtl_set_bbreg(hw, RA_RFE_PINMUX + 4, BIT(29) | BIT(28), 0x1);
4575 	else
4576 		rtl_set_bbreg(hw, RA_RFE_PINMUX + 4, BIT(29) | BIT(28), 0x2);
4577 }
4578 
4579 #undef IQK_ADDA_REG_NUM
4580 #undef IQK_DELAY_TIME
4581 
4582 void rtl8812ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
4583 {
4584 }
4585 
4586 void rtl8812ae_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index,
4587 		      u8 thermal_value, u8 threshold)
4588 {
4589 	struct rtl_dm	*rtldm = rtl_dm(rtl_priv(hw));
4590 
4591 	rtldm->thermalvalue_iqk = thermal_value;
4592 	rtl8812ae_phy_iq_calibrate(hw, false);
4593 }
4594 
4595 void rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
4596 {
4597 	struct rtl_priv *rtlpriv = rtl_priv(hw);
4598 	struct rtl_phy *rtlphy = &rtlpriv->phy;
4599 
4600 	if (!rtlphy->lck_inprogress) {
4601 		spin_lock(&rtlpriv->locks.iqk_lock);
4602 		rtlphy->lck_inprogress = true;
4603 		spin_unlock(&rtlpriv->locks.iqk_lock);
4604 
4605 		_rtl8821ae_phy_iq_calibrate(hw);
4606 
4607 		spin_lock(&rtlpriv->locks.iqk_lock);
4608 		rtlphy->lck_inprogress = false;
4609 		spin_unlock(&rtlpriv->locks.iqk_lock);
4610 	}
4611 }
4612 
4613 void rtl8821ae_reset_iqk_result(struct ieee80211_hw *hw)
4614 {
4615 	struct rtl_priv *rtlpriv = rtl_priv(hw);
4616 	struct rtl_phy *rtlphy = &rtlpriv->phy;
4617 	u8 i;
4618 
4619 	RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4620 		 "rtl8812ae_dm_reset_iqk_result:: settings regs %d default regs %d\n",
4621 		 (int)(sizeof(rtlphy->iqk_matrix) /
4622 		 sizeof(struct iqk_matrix_regs)),
4623 		 IQK_MATRIX_SETTINGS_NUM);
4624 
4625 	for (i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) {
4626 		rtlphy->iqk_matrix[i].value[0][0] = 0x100;
4627 		rtlphy->iqk_matrix[i].value[0][2] = 0x100;
4628 		rtlphy->iqk_matrix[i].value[0][4] = 0x100;
4629 		rtlphy->iqk_matrix[i].value[0][6] = 0x100;
4630 
4631 		rtlphy->iqk_matrix[i].value[0][1] = 0x0;
4632 		rtlphy->iqk_matrix[i].value[0][3] = 0x0;
4633 		rtlphy->iqk_matrix[i].value[0][5] = 0x0;
4634 		rtlphy->iqk_matrix[i].value[0][7] = 0x0;
4635 
4636 		rtlphy->iqk_matrix[i].iqk_done = false;
4637 	}
4638 }
4639 
4640 void rtl8821ae_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index,
4641 		      u8 thermal_value, u8 threshold)
4642 {
4643 	struct rtl_dm	*rtldm = rtl_dm(rtl_priv(hw));
4644 
4645 	rtl8821ae_reset_iqk_result(hw);
4646 
4647 	rtldm->thermalvalue_iqk = thermal_value;
4648 	rtl8821ae_phy_iq_calibrate(hw, false);
4649 }
4650 
4651 void rtl8821ae_phy_lc_calibrate(struct ieee80211_hw *hw)
4652 {
4653 }
4654 
4655 void rtl8821ae_phy_ap_calibrate(struct ieee80211_hw *hw, char delta)
4656 {
4657 }
4658 
4659 void rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
4660 {
4661 	_rtl8821ae_phy_set_rfpath_switch(hw, bmain);
4662 }
4663 
4664 bool rtl8821ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
4665 {
4666 	struct rtl_priv *rtlpriv = rtl_priv(hw);
4667 	struct rtl_phy *rtlphy = &rtlpriv->phy;
4668 	bool postprocessing = false;
4669 
4670 	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4671 		 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
4672 		  iotype, rtlphy->set_io_inprogress);
4673 	do {
4674 		switch (iotype) {
4675 		case IO_CMD_RESUME_DM_BY_SCAN:
4676 			RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4677 				 "[IO CMD] Resume DM after scan.\n");
4678 			postprocessing = true;
4679 			break;
4680 		case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
4681 		case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
4682 			RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4683 				 "[IO CMD] Pause DM before scan.\n");
4684 			postprocessing = true;
4685 			break;
4686 		default:
4687 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
4688 				 "switch case not process\n");
4689 			break;
4690 		}
4691 	} while (false);
4692 	if (postprocessing && !rtlphy->set_io_inprogress) {
4693 		rtlphy->set_io_inprogress = true;
4694 		rtlphy->current_io_type = iotype;
4695 	} else {
4696 		return false;
4697 	}
4698 	rtl8821ae_phy_set_io(hw);
4699 	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
4700 	return true;
4701 }
4702 
4703 static void rtl8821ae_phy_set_io(struct ieee80211_hw *hw)
4704 {
4705 	struct rtl_priv *rtlpriv = rtl_priv(hw);
4706 	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
4707 	struct rtl_phy *rtlphy = &rtlpriv->phy;
4708 
4709 	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4710 		 "--->Cmd(%#x), set_io_inprogress(%d)\n",
4711 		  rtlphy->current_io_type, rtlphy->set_io_inprogress);
4712 	switch (rtlphy->current_io_type) {
4713 	case IO_CMD_RESUME_DM_BY_SCAN:
4714 		if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
4715 			_rtl8821ae_resume_tx_beacon(hw);
4716 		rtl8821ae_dm_write_dig(hw, rtlphy->initgain_backup.xaagccore1);
4717 		rtl8821ae_dm_write_cck_cca_thres(hw,
4718 						 rtlphy->initgain_backup.cca);
4719 		break;
4720 	case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
4721 		if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
4722 			_rtl8821ae_stop_tx_beacon(hw);
4723 		rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
4724 		rtl8821ae_dm_write_dig(hw, 0x17);
4725 		rtlphy->initgain_backup.cca = dm_digtable->cur_cck_cca_thres;
4726 		rtl8821ae_dm_write_cck_cca_thres(hw, 0x40);
4727 		break;
4728 	case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
4729 		break;
4730 	default:
4731 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
4732 			 "switch case not process\n");
4733 		break;
4734 	}
4735 	rtlphy->set_io_inprogress = false;
4736 	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4737 		 "(%#x)\n", rtlphy->current_io_type);
4738 }
4739 
4740 static void rtl8821ae_phy_set_rf_on(struct ieee80211_hw *hw)
4741 {
4742 	struct rtl_priv *rtlpriv = rtl_priv(hw);
4743 
4744 	rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
4745 	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
4746 	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
4747 	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
4748 	rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
4749 }
4750 
4751 static bool _rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
4752 					      enum rf_pwrstate rfpwr_state)
4753 {
4754 	struct rtl_priv *rtlpriv = rtl_priv(hw);
4755 	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
4756 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
4757 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
4758 	bool bresult = true;
4759 	u8 i, queue_id;
4760 	struct rtl8192_tx_ring *ring = NULL;
4761 
4762 	switch (rfpwr_state) {
4763 	case ERFON:
4764 		if ((ppsc->rfpwr_state == ERFOFF) &&
4765 		    RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
4766 			bool rtstatus = false;
4767 			u32 initializecount = 0;
4768 
4769 			do {
4770 				initializecount++;
4771 				RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4772 					 "IPS Set eRf nic enable\n");
4773 				rtstatus = rtl_ps_enable_nic(hw);
4774 			} while (!rtstatus && (initializecount < 10));
4775 			RT_CLEAR_PS_LEVEL(ppsc,
4776 					  RT_RF_OFF_LEVL_HALT_NIC);
4777 		} else {
4778 			RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4779 				 "Set ERFON sleeped:%d ms\n",
4780 				  jiffies_to_msecs(jiffies -
4781 						   ppsc->
4782 						   last_sleep_jiffies));
4783 			ppsc->last_awake_jiffies = jiffies;
4784 			rtl8821ae_phy_set_rf_on(hw);
4785 		}
4786 		if (mac->link_state == MAC80211_LINKED) {
4787 			rtlpriv->cfg->ops->led_control(hw,
4788 						       LED_CTL_LINK);
4789 		} else {
4790 			rtlpriv->cfg->ops->led_control(hw,
4791 						       LED_CTL_NO_LINK);
4792 		}
4793 		break;
4794 	case ERFOFF:
4795 		for (queue_id = 0, i = 0;
4796 		     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
4797 			ring = &pcipriv->dev.tx_ring[queue_id];
4798 			if (queue_id == BEACON_QUEUE ||
4799 			    skb_queue_len(&ring->queue) == 0) {
4800 				queue_id++;
4801 				continue;
4802 			} else {
4803 				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
4804 					 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
4805 					 (i + 1), queue_id,
4806 					 skb_queue_len(&ring->queue));
4807 
4808 				udelay(10);
4809 				i++;
4810 			}
4811 			if (i >= MAX_DOZE_WAITING_TIMES_9x) {
4812 				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
4813 					 "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
4814 					  MAX_DOZE_WAITING_TIMES_9x,
4815 					  queue_id,
4816 					  skb_queue_len(&ring->queue));
4817 				break;
4818 			}
4819 		}
4820 
4821 		if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
4822 			RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4823 				 "IPS Set eRf nic disable\n");
4824 			rtl_ps_disable_nic(hw);
4825 			RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
4826 		} else {
4827 			if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
4828 				rtlpriv->cfg->ops->led_control(hw,
4829 							       LED_CTL_NO_LINK);
4830 			} else {
4831 				rtlpriv->cfg->ops->led_control(hw,
4832 							       LED_CTL_POWER_OFF);
4833 			}
4834 		}
4835 		break;
4836 	default:
4837 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
4838 			 "switch case not process\n");
4839 		bresult = false;
4840 		break;
4841 	}
4842 	if (bresult)
4843 		ppsc->rfpwr_state = rfpwr_state;
4844 	return bresult;
4845 }
4846 
4847 bool rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
4848 				      enum rf_pwrstate rfpwr_state)
4849 {
4850 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
4851 
4852 	bool bresult = false;
4853 
4854 	if (rfpwr_state == ppsc->rfpwr_state)
4855 		return bresult;
4856 	bresult = _rtl8821ae_phy_set_rf_power_state(hw, rfpwr_state);
4857 	return bresult;
4858 }
4859