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