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