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