xref: /linux/drivers/net/wireless/realtek/rtlwifi/rtl8192du/phy.c (revision a1ff5a7d78a036d6c2178ee5acd6ba4946243800)
1*af46caf0SBitterblue Smith // SPDX-License-Identifier: GPL-2.0
2*af46caf0SBitterblue Smith /* Copyright(c) 2024  Realtek Corporation.*/
3*af46caf0SBitterblue Smith 
4*af46caf0SBitterblue Smith #include "../wifi.h"
5*af46caf0SBitterblue Smith #include "../ps.h"
6*af46caf0SBitterblue Smith #include "../core.h"
7*af46caf0SBitterblue Smith #include "../efuse.h"
8*af46caf0SBitterblue Smith #include "../usb.h"
9*af46caf0SBitterblue Smith #include "../rtl8192d/reg.h"
10*af46caf0SBitterblue Smith #include "../rtl8192d/def.h"
11*af46caf0SBitterblue Smith #include "../rtl8192d/phy_common.h"
12*af46caf0SBitterblue Smith #include "../rtl8192d/rf_common.h"
13*af46caf0SBitterblue Smith #include "phy.h"
14*af46caf0SBitterblue Smith #include "rf.h"
15*af46caf0SBitterblue Smith #include "table.h"
16*af46caf0SBitterblue Smith 
17*af46caf0SBitterblue Smith #define MAX_RF_IMR_INDEX			12
18*af46caf0SBitterblue Smith #define MAX_RF_IMR_INDEX_NORMAL			13
19*af46caf0SBitterblue Smith #define RF_REG_NUM_FOR_C_CUT_5G			6
20*af46caf0SBitterblue Smith #define RF_REG_NUM_FOR_C_CUT_5G_INTERNALPA	7
21*af46caf0SBitterblue Smith #define RF_REG_NUM_FOR_C_CUT_2G			5
22*af46caf0SBitterblue Smith #define RF_CHNL_NUM_5G				19
23*af46caf0SBitterblue Smith #define RF_CHNL_NUM_5G_40M			17
24*af46caf0SBitterblue Smith #define CV_CURVE_CNT				64
25*af46caf0SBitterblue Smith 
26*af46caf0SBitterblue Smith static const u32 rf_reg_for_5g_swchnl_normal[MAX_RF_IMR_INDEX_NORMAL] = {
27*af46caf0SBitterblue Smith 	0, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x0
28*af46caf0SBitterblue Smith };
29*af46caf0SBitterblue Smith 
30*af46caf0SBitterblue Smith static const u8 rf_reg_for_c_cut_5g[RF_REG_NUM_FOR_C_CUT_5G] = {
31*af46caf0SBitterblue Smith 	RF_SYN_G1, RF_SYN_G2, RF_SYN_G3, RF_SYN_G4, RF_SYN_G5, RF_SYN_G6
32*af46caf0SBitterblue Smith };
33*af46caf0SBitterblue Smith 
34*af46caf0SBitterblue Smith static const u8 rf_reg_for_c_cut_2g[RF_REG_NUM_FOR_C_CUT_2G] = {
35*af46caf0SBitterblue Smith 	RF_SYN_G1, RF_SYN_G2, RF_SYN_G3, RF_SYN_G7, RF_SYN_G8
36*af46caf0SBitterblue Smith };
37*af46caf0SBitterblue Smith 
38*af46caf0SBitterblue Smith static const u8 rf_for_c_cut_5g_internal_pa[RF_REG_NUM_FOR_C_CUT_5G_INTERNALPA] = {
39*af46caf0SBitterblue Smith 	0x0B, 0x48, 0x49, 0x4B, 0x03, 0x04, 0x0E
40*af46caf0SBitterblue Smith };
41*af46caf0SBitterblue Smith 
42*af46caf0SBitterblue Smith static const u32 rf_reg_mask_for_c_cut_2g[RF_REG_NUM_FOR_C_CUT_2G] = {
43*af46caf0SBitterblue Smith 	BIT(19) | BIT(18) | BIT(17) | BIT(14) | BIT(1),
44*af46caf0SBitterblue Smith 	BIT(10) | BIT(9),
45*af46caf0SBitterblue Smith 	BIT(18) | BIT(17) | BIT(16) | BIT(1),
46*af46caf0SBitterblue Smith 	BIT(2) | BIT(1),
47*af46caf0SBitterblue Smith 	BIT(15) | BIT(14) | BIT(13) | BIT(12) | BIT(11)
48*af46caf0SBitterblue Smith };
49*af46caf0SBitterblue Smith 
50*af46caf0SBitterblue Smith static const u8 rf_chnl_5g[RF_CHNL_NUM_5G] = {
51*af46caf0SBitterblue Smith 	36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108,
52*af46caf0SBitterblue Smith 	112, 116, 120, 124, 128, 132, 136, 140
53*af46caf0SBitterblue Smith };
54*af46caf0SBitterblue Smith 
55*af46caf0SBitterblue Smith static const u8 rf_chnl_5g_40m[RF_CHNL_NUM_5G_40M] = {
56*af46caf0SBitterblue Smith 	38, 42, 46, 50, 54, 58, 62, 102, 106, 110, 114,
57*af46caf0SBitterblue Smith 	118, 122, 126, 130, 134, 138
58*af46caf0SBitterblue Smith };
59*af46caf0SBitterblue Smith 
60*af46caf0SBitterblue Smith static const u32 rf_reg_pram_c_5g[5][RF_REG_NUM_FOR_C_CUT_5G] = {
61*af46caf0SBitterblue Smith 	{0xE43BE, 0xFC638, 0x77C0A, 0xDE471, 0xd7110, 0x8EB04},
62*af46caf0SBitterblue Smith 	{0xE43BE, 0xFC078, 0xF7C1A, 0xE0C71, 0xD7550, 0xAEB04},
63*af46caf0SBitterblue Smith 	{0xE43BF, 0xFF038, 0xF7C0A, 0xDE471, 0xE5550, 0xAEB04},
64*af46caf0SBitterblue Smith 	{0xE43BF, 0xFF079, 0xF7C1A, 0xDE471, 0xE5550, 0xAEB04},
65*af46caf0SBitterblue Smith 	{0xE43BF, 0xFF038, 0xF7C1A, 0xDE471, 0xd7550, 0xAEB04}
66*af46caf0SBitterblue Smith };
67*af46caf0SBitterblue Smith 
68*af46caf0SBitterblue Smith static const u32 rf_reg_param_for_c_cut_2g[3][RF_REG_NUM_FOR_C_CUT_2G] = {
69*af46caf0SBitterblue Smith 	{0x643BC, 0xFC038, 0x77C1A, 0x41289, 0x01840},
70*af46caf0SBitterblue Smith 	{0x643BC, 0xFC038, 0x07C1A, 0x41289, 0x01840},
71*af46caf0SBitterblue Smith 	{0x243BC, 0xFC438, 0x07C1A, 0x4128B, 0x0FC41}
72*af46caf0SBitterblue Smith };
73*af46caf0SBitterblue Smith 
74*af46caf0SBitterblue Smith static const u32 rf_syn_g4_for_c_cut_2g = 0xD1C31 & 0x7FF;
75*af46caf0SBitterblue Smith 
76*af46caf0SBitterblue Smith static const u32 rf_pram_c_5g_int_pa[3][RF_REG_NUM_FOR_C_CUT_5G_INTERNALPA] = {
77*af46caf0SBitterblue Smith 	{0x01a00, 0x40443, 0x00eb5, 0x89bec, 0x94a12, 0x94a12, 0x94a12},
78*af46caf0SBitterblue Smith 	{0x01800, 0xc0443, 0x00730, 0x896ee, 0x94a52, 0x94a52, 0x94a52},
79*af46caf0SBitterblue Smith 	{0x01800, 0xc0443, 0x00730, 0x896ee, 0x94a12, 0x94a12, 0x94a12}
80*af46caf0SBitterblue Smith };
81*af46caf0SBitterblue Smith 
82*af46caf0SBitterblue Smith /* [patha+b][reg] */
83*af46caf0SBitterblue Smith static const u32 rf_imr_param_normal[3][MAX_RF_IMR_INDEX_NORMAL] = {
84*af46caf0SBitterblue Smith 	/* channels 1-14. */
85*af46caf0SBitterblue Smith 	{
86*af46caf0SBitterblue Smith 		0x70000, 0x00ff0, 0x4400f, 0x00ff0, 0x0, 0x0, 0x0,
87*af46caf0SBitterblue Smith 		0x0, 0x0, 0x64888, 0xe266c, 0x00090, 0x22fff
88*af46caf0SBitterblue Smith 	},
89*af46caf0SBitterblue Smith 	/* channels 36-64 */
90*af46caf0SBitterblue Smith 	{
91*af46caf0SBitterblue Smith 		0x70000, 0x22880, 0x4470f, 0x55880, 0x00070, 0x88000,
92*af46caf0SBitterblue Smith 		0x0, 0x88080, 0x70000, 0x64a82, 0xe466c, 0x00090,
93*af46caf0SBitterblue Smith 		0x32c9a
94*af46caf0SBitterblue Smith 	},
95*af46caf0SBitterblue Smith 	/* channels 100-165 */
96*af46caf0SBitterblue Smith 	{
97*af46caf0SBitterblue Smith 		0x70000, 0x44880, 0x4477f, 0x77880, 0x00070, 0x88000,
98*af46caf0SBitterblue Smith 		0x0, 0x880b0, 0x0, 0x64b82, 0xe466c, 0x00090, 0x32c9a
99*af46caf0SBitterblue Smith 	}
100*af46caf0SBitterblue Smith };
101*af46caf0SBitterblue Smith 
102*af46caf0SBitterblue Smith static const u32 targetchnl_5g[TARGET_CHNL_NUM_5G] = {
103*af46caf0SBitterblue Smith 	25141, 25116, 25091, 25066, 25041,
104*af46caf0SBitterblue Smith 	25016, 24991, 24966, 24941, 24917,
105*af46caf0SBitterblue Smith 	24892, 24867, 24843, 24818, 24794,
106*af46caf0SBitterblue Smith 	24770, 24765, 24721, 24697, 24672,
107*af46caf0SBitterblue Smith 	24648, 24624, 24600, 24576, 24552,
108*af46caf0SBitterblue Smith 	24528, 24504, 24480, 24457, 24433,
109*af46caf0SBitterblue Smith 	24409, 24385, 24362, 24338, 24315,
110*af46caf0SBitterblue Smith 	24291, 24268, 24245, 24221, 24198,
111*af46caf0SBitterblue Smith 	24175, 24151, 24128, 24105, 24082,
112*af46caf0SBitterblue Smith 	24059, 24036, 24013, 23990, 23967,
113*af46caf0SBitterblue Smith 	23945, 23922, 23899, 23876, 23854,
114*af46caf0SBitterblue Smith 	23831, 23809, 23786, 23764, 23741,
115*af46caf0SBitterblue Smith 	23719, 23697, 23674, 23652, 23630,
116*af46caf0SBitterblue Smith 	23608, 23586, 23564, 23541, 23519,
117*af46caf0SBitterblue Smith 	23498, 23476, 23454, 23432, 23410,
118*af46caf0SBitterblue Smith 	23388, 23367, 23345, 23323, 23302,
119*af46caf0SBitterblue Smith 	23280, 23259, 23237, 23216, 23194,
120*af46caf0SBitterblue Smith 	23173, 23152, 23130, 23109, 23088,
121*af46caf0SBitterblue Smith 	23067, 23046, 23025, 23003, 22982,
122*af46caf0SBitterblue Smith 	22962, 22941, 22920, 22899, 22878,
123*af46caf0SBitterblue Smith 	22857, 22837, 22816, 22795, 22775,
124*af46caf0SBitterblue Smith 	22754, 22733, 22713, 22692, 22672,
125*af46caf0SBitterblue Smith 	22652, 22631, 22611, 22591, 22570,
126*af46caf0SBitterblue Smith 	22550, 22530, 22510, 22490, 22469,
127*af46caf0SBitterblue Smith 	22449, 22429, 22409, 22390, 22370,
128*af46caf0SBitterblue Smith 	22350, 22336, 22310, 22290, 22271,
129*af46caf0SBitterblue Smith 	22251, 22231, 22212, 22192, 22173,
130*af46caf0SBitterblue Smith 	22153, 22134, 22114, 22095, 22075,
131*af46caf0SBitterblue Smith 	22056, 22037, 22017, 21998, 21979,
132*af46caf0SBitterblue Smith 	21960, 21941, 21921, 21902, 21883,
133*af46caf0SBitterblue Smith 	21864, 21845, 21826, 21807, 21789,
134*af46caf0SBitterblue Smith 	21770, 21751, 21732, 21713, 21695,
135*af46caf0SBitterblue Smith 	21676, 21657, 21639, 21620, 21602,
136*af46caf0SBitterblue Smith 	21583, 21565, 21546, 21528, 21509,
137*af46caf0SBitterblue Smith 	21491, 21473, 21454, 21436, 21418,
138*af46caf0SBitterblue Smith 	21400, 21381, 21363, 21345, 21327,
139*af46caf0SBitterblue Smith 	21309, 21291, 21273, 21255, 21237,
140*af46caf0SBitterblue Smith 	21219, 21201, 21183, 21166, 21148,
141*af46caf0SBitterblue Smith 	21130, 21112, 21095, 21077, 21059,
142*af46caf0SBitterblue Smith 	21042, 21024, 21007, 20989, 20972,
143*af46caf0SBitterblue Smith 	25679, 25653, 25627, 25601, 25575,
144*af46caf0SBitterblue Smith 	25549, 25523, 25497, 25471, 25446,
145*af46caf0SBitterblue Smith 	25420, 25394, 25369, 25343, 25318,
146*af46caf0SBitterblue Smith 	25292, 25267, 25242, 25216, 25191,
147*af46caf0SBitterblue Smith 	25166
148*af46caf0SBitterblue Smith };
149*af46caf0SBitterblue Smith 
150*af46caf0SBitterblue Smith /* channel 1~14 */
151*af46caf0SBitterblue Smith static const u32 targetchnl_2g[TARGET_CHNL_NUM_2G] = {
152*af46caf0SBitterblue Smith 	26084, 26030, 25976, 25923, 25869, 25816, 25764,
153*af46caf0SBitterblue Smith 	25711, 25658, 25606, 25554, 25502, 25451, 25328
154*af46caf0SBitterblue Smith };
155*af46caf0SBitterblue Smith 
rtl92du_phy_query_bb_reg(struct ieee80211_hw * hw,u32 regaddr,u32 bitmask)156*af46caf0SBitterblue Smith u32 rtl92du_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
157*af46caf0SBitterblue Smith {
158*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
159*af46caf0SBitterblue Smith 	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
160*af46caf0SBitterblue Smith 	u32 returnvalue, originalvalue, bitshift;
161*af46caf0SBitterblue Smith 
162*af46caf0SBitterblue Smith 	rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n",
163*af46caf0SBitterblue Smith 		regaddr, bitmask);
164*af46caf0SBitterblue Smith 
165*af46caf0SBitterblue Smith 	if (rtlhal->during_mac1init_radioa)
166*af46caf0SBitterblue Smith 		regaddr |= MAC1_ACCESS_PHY0;
167*af46caf0SBitterblue Smith 	else if (rtlhal->during_mac0init_radiob)
168*af46caf0SBitterblue Smith 		regaddr |= MAC0_ACCESS_PHY1;
169*af46caf0SBitterblue Smith 
170*af46caf0SBitterblue Smith 	originalvalue = rtl_read_dword(rtlpriv, regaddr);
171*af46caf0SBitterblue Smith 	bitshift = calculate_bit_shift(bitmask);
172*af46caf0SBitterblue Smith 	returnvalue = (originalvalue & bitmask) >> bitshift;
173*af46caf0SBitterblue Smith 	rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
174*af46caf0SBitterblue Smith 		"BBR MASK=0x%x Addr[0x%x]=0x%x\n",
175*af46caf0SBitterblue Smith 		bitmask, regaddr, originalvalue);
176*af46caf0SBitterblue Smith 	return returnvalue;
177*af46caf0SBitterblue Smith }
178*af46caf0SBitterblue Smith 
rtl92du_phy_set_bb_reg(struct ieee80211_hw * hw,u32 regaddr,u32 bitmask,u32 data)179*af46caf0SBitterblue Smith void rtl92du_phy_set_bb_reg(struct ieee80211_hw *hw,
180*af46caf0SBitterblue Smith 			    u32 regaddr, u32 bitmask, u32 data)
181*af46caf0SBitterblue Smith {
182*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
183*af46caf0SBitterblue Smith 	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
184*af46caf0SBitterblue Smith 	u32 originalvalue, bitshift;
185*af46caf0SBitterblue Smith 
186*af46caf0SBitterblue Smith 	rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
187*af46caf0SBitterblue Smith 		"regaddr(%#x), bitmask(%#x), data(%#x)\n",
188*af46caf0SBitterblue Smith 		regaddr, bitmask, data);
189*af46caf0SBitterblue Smith 
190*af46caf0SBitterblue Smith 	if (rtlhal->during_mac1init_radioa)
191*af46caf0SBitterblue Smith 		regaddr |= MAC1_ACCESS_PHY0;
192*af46caf0SBitterblue Smith 	else if (rtlhal->during_mac0init_radiob)
193*af46caf0SBitterblue Smith 		regaddr |= MAC0_ACCESS_PHY1;
194*af46caf0SBitterblue Smith 
195*af46caf0SBitterblue Smith 	if (bitmask != MASKDWORD) {
196*af46caf0SBitterblue Smith 		originalvalue = rtl_read_dword(rtlpriv, regaddr);
197*af46caf0SBitterblue Smith 		bitshift = calculate_bit_shift(bitmask);
198*af46caf0SBitterblue Smith 		data = (originalvalue & (~bitmask)) |
199*af46caf0SBitterblue Smith 			((data << bitshift) & bitmask);
200*af46caf0SBitterblue Smith 	}
201*af46caf0SBitterblue Smith 
202*af46caf0SBitterblue Smith 	rtl_write_dword(rtlpriv, regaddr, data);
203*af46caf0SBitterblue Smith 	rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
204*af46caf0SBitterblue Smith 		"regaddr(%#x), bitmask(%#x), data(%#x)\n",
205*af46caf0SBitterblue Smith 		regaddr, bitmask, data);
206*af46caf0SBitterblue Smith }
207*af46caf0SBitterblue Smith 
208*af46caf0SBitterblue Smith /* To avoid miswrite Reg0x800 for 92D */
rtl92du_phy_set_bb_reg_1byte(struct ieee80211_hw * hw,u32 regaddr,u32 bitmask,u32 data)209*af46caf0SBitterblue Smith static void rtl92du_phy_set_bb_reg_1byte(struct ieee80211_hw *hw,
210*af46caf0SBitterblue Smith 					 u32 regaddr, u32 bitmask, u32 data)
211*af46caf0SBitterblue Smith {
212*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
213*af46caf0SBitterblue Smith 	u32 originalvalue, bitshift, offset;
214*af46caf0SBitterblue Smith 	u8 value;
215*af46caf0SBitterblue Smith 
216*af46caf0SBitterblue Smith 	/* BitMask only support bit0~bit7 or bit8~bit15, bit16~bit23,
217*af46caf0SBitterblue Smith 	 * bit24~bit31, should be in 1 byte scale;
218*af46caf0SBitterblue Smith 	 */
219*af46caf0SBitterblue Smith 	bitshift = calculate_bit_shift(bitmask);
220*af46caf0SBitterblue Smith 	offset = bitshift / 8;
221*af46caf0SBitterblue Smith 
222*af46caf0SBitterblue Smith 	originalvalue = rtl_read_dword(rtlpriv, regaddr);
223*af46caf0SBitterblue Smith 	data = (originalvalue & (~bitmask)) | ((data << bitshift) & bitmask);
224*af46caf0SBitterblue Smith 
225*af46caf0SBitterblue Smith 	value = data >> (8 * offset);
226*af46caf0SBitterblue Smith 
227*af46caf0SBitterblue Smith 	rtl_write_byte(rtlpriv, regaddr + offset, value);
228*af46caf0SBitterblue Smith }
229*af46caf0SBitterblue Smith 
rtl92du_phy_mac_config(struct ieee80211_hw * hw)230*af46caf0SBitterblue Smith bool rtl92du_phy_mac_config(struct ieee80211_hw *hw)
231*af46caf0SBitterblue Smith {
232*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
233*af46caf0SBitterblue Smith 	u32 arraylength;
234*af46caf0SBitterblue Smith 	const u32 *ptrarray;
235*af46caf0SBitterblue Smith 	u32 i;
236*af46caf0SBitterblue Smith 
237*af46caf0SBitterblue Smith 	rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n");
238*af46caf0SBitterblue Smith 
239*af46caf0SBitterblue Smith 	arraylength = MAC_2T_ARRAYLENGTH;
240*af46caf0SBitterblue Smith 	ptrarray = rtl8192du_mac_2tarray;
241*af46caf0SBitterblue Smith 
242*af46caf0SBitterblue Smith 	for (i = 0; i < arraylength; i = i + 2)
243*af46caf0SBitterblue Smith 		rtl_write_byte(rtlpriv, ptrarray[i], (u8)ptrarray[i + 1]);
244*af46caf0SBitterblue Smith 
245*af46caf0SBitterblue Smith 	if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY) {
246*af46caf0SBitterblue Smith 		/* improve 2-stream TX EVM */
247*af46caf0SBitterblue Smith 		/* rtl_write_byte(rtlpriv, 0x14,0x71); */
248*af46caf0SBitterblue Smith 		/* AMPDU aggregation number 9 */
249*af46caf0SBitterblue Smith 		/* rtl_write_word(rtlpriv, REG_MAX_AGGR_NUM, MAX_AGGR_NUM); */
250*af46caf0SBitterblue Smith 		rtl_write_byte(rtlpriv, REG_MAX_AGGR_NUM, 0x0B);
251*af46caf0SBitterblue Smith 	} else {
252*af46caf0SBitterblue Smith 		/* 92D need to test to decide the num. */
253*af46caf0SBitterblue Smith 		rtl_write_byte(rtlpriv, REG_MAX_AGGR_NUM, 0x07);
254*af46caf0SBitterblue Smith 	}
255*af46caf0SBitterblue Smith 
256*af46caf0SBitterblue Smith 	return true;
257*af46caf0SBitterblue Smith }
258*af46caf0SBitterblue Smith 
_rtl92du_phy_config_bb(struct ieee80211_hw * hw,u8 configtype)259*af46caf0SBitterblue Smith static bool _rtl92du_phy_config_bb(struct ieee80211_hw *hw, u8 configtype)
260*af46caf0SBitterblue Smith {
261*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
262*af46caf0SBitterblue Smith 	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
263*af46caf0SBitterblue Smith 	u16 phy_reg_arraylen, agctab_arraylen = 0;
264*af46caf0SBitterblue Smith 	const u32 *agctab_array_table = NULL;
265*af46caf0SBitterblue Smith 	const u32 *phy_regarray_table;
266*af46caf0SBitterblue Smith 	int i;
267*af46caf0SBitterblue Smith 
268*af46caf0SBitterblue Smith 	/* Normal chip, Mac0 use AGC_TAB.txt for 2G and 5G band. */
269*af46caf0SBitterblue Smith 	if (rtlhal->interfaceindex == 0) {
270*af46caf0SBitterblue Smith 		agctab_arraylen = AGCTAB_ARRAYLENGTH;
271*af46caf0SBitterblue Smith 		agctab_array_table = rtl8192du_agctab_array;
272*af46caf0SBitterblue Smith 		rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
273*af46caf0SBitterblue Smith 			" ===> phy:MAC0, Rtl819XAGCTAB_Array\n");
274*af46caf0SBitterblue Smith 	} else {
275*af46caf0SBitterblue Smith 		if (rtlhal->current_bandtype == BAND_ON_2_4G) {
276*af46caf0SBitterblue Smith 			agctab_arraylen = AGCTAB_2G_ARRAYLENGTH;
277*af46caf0SBitterblue Smith 			agctab_array_table = rtl8192du_agctab_2garray;
278*af46caf0SBitterblue Smith 			rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
279*af46caf0SBitterblue Smith 				" ===> phy:MAC1, Rtl819XAGCTAB_2GArray\n");
280*af46caf0SBitterblue Smith 		} else {
281*af46caf0SBitterblue Smith 			agctab_arraylen = AGCTAB_5G_ARRAYLENGTH;
282*af46caf0SBitterblue Smith 			agctab_array_table = rtl8192du_agctab_5garray;
283*af46caf0SBitterblue Smith 			rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
284*af46caf0SBitterblue Smith 				" ===> phy:MAC1, Rtl819XAGCTAB_5GArray\n");
285*af46caf0SBitterblue Smith 		}
286*af46caf0SBitterblue Smith 	}
287*af46caf0SBitterblue Smith 	phy_reg_arraylen = PHY_REG_2T_ARRAYLENGTH;
288*af46caf0SBitterblue Smith 	phy_regarray_table = rtl8192du_phy_reg_2tarray;
289*af46caf0SBitterblue Smith 	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
290*af46caf0SBitterblue Smith 		" ===> phy:Rtl819XPHY_REG_Array_PG\n");
291*af46caf0SBitterblue Smith 
292*af46caf0SBitterblue Smith 	if (configtype == BASEBAND_CONFIG_PHY_REG) {
293*af46caf0SBitterblue Smith 		for (i = 0; i < phy_reg_arraylen; i = i + 2) {
294*af46caf0SBitterblue Smith 			rtl_addr_delay(phy_regarray_table[i]);
295*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD,
296*af46caf0SBitterblue Smith 				      phy_regarray_table[i + 1]);
297*af46caf0SBitterblue Smith 			udelay(1);
298*af46caf0SBitterblue Smith 			rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
299*af46caf0SBitterblue Smith 				"The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n",
300*af46caf0SBitterblue Smith 				phy_regarray_table[i],
301*af46caf0SBitterblue Smith 				phy_regarray_table[i + 1]);
302*af46caf0SBitterblue Smith 		}
303*af46caf0SBitterblue Smith 	} else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
304*af46caf0SBitterblue Smith 		for (i = 0; i < agctab_arraylen; i = i + 2) {
305*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, agctab_array_table[i],
306*af46caf0SBitterblue Smith 				      MASKDWORD, agctab_array_table[i + 1]);
307*af46caf0SBitterblue Smith 
308*af46caf0SBitterblue Smith 			/* Add 1us delay between BB/RF register setting. */
309*af46caf0SBitterblue Smith 			udelay(1);
310*af46caf0SBitterblue Smith 
311*af46caf0SBitterblue Smith 			rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
312*af46caf0SBitterblue Smith 				"AGC table %u %u\n",
313*af46caf0SBitterblue Smith 				agctab_array_table[i],
314*af46caf0SBitterblue Smith 				agctab_array_table[i + 1]);
315*af46caf0SBitterblue Smith 		}
316*af46caf0SBitterblue Smith 		rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
317*af46caf0SBitterblue Smith 			"Normal Chip, loaded AGC table\n");
318*af46caf0SBitterblue Smith 	}
319*af46caf0SBitterblue Smith 	return true;
320*af46caf0SBitterblue Smith }
321*af46caf0SBitterblue Smith 
_rtl92du_phy_config_bb_pg(struct ieee80211_hw * hw,u8 configtype)322*af46caf0SBitterblue Smith static bool _rtl92du_phy_config_bb_pg(struct ieee80211_hw *hw, u8 configtype)
323*af46caf0SBitterblue Smith {
324*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
325*af46caf0SBitterblue Smith 	const u32 *phy_regarray_table_pg;
326*af46caf0SBitterblue Smith 	u16 phy_regarray_pg_len;
327*af46caf0SBitterblue Smith 	int i;
328*af46caf0SBitterblue Smith 
329*af46caf0SBitterblue Smith 	phy_regarray_pg_len = PHY_REG_ARRAY_PG_LENGTH;
330*af46caf0SBitterblue Smith 	phy_regarray_table_pg = rtl8192du_phy_reg_array_pg;
331*af46caf0SBitterblue Smith 
332*af46caf0SBitterblue Smith 	if (configtype == BASEBAND_CONFIG_PHY_REG) {
333*af46caf0SBitterblue Smith 		for (i = 0; i < phy_regarray_pg_len; i = i + 3) {
334*af46caf0SBitterblue Smith 			rtl_addr_delay(phy_regarray_table_pg[i]);
335*af46caf0SBitterblue Smith 			rtl92d_store_pwrindex_diffrate_offset(hw,
336*af46caf0SBitterblue Smith 				phy_regarray_table_pg[i],
337*af46caf0SBitterblue Smith 				phy_regarray_table_pg[i + 1],
338*af46caf0SBitterblue Smith 				phy_regarray_table_pg[i + 2]);
339*af46caf0SBitterblue Smith 		}
340*af46caf0SBitterblue Smith 	} else {
341*af46caf0SBitterblue Smith 		rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE,
342*af46caf0SBitterblue Smith 			"configtype != BaseBand_Config_PHY_REG\n");
343*af46caf0SBitterblue Smith 	}
344*af46caf0SBitterblue Smith 	return true;
345*af46caf0SBitterblue Smith }
346*af46caf0SBitterblue Smith 
_rtl92du_phy_bb_config(struct ieee80211_hw * hw)347*af46caf0SBitterblue Smith static bool _rtl92du_phy_bb_config(struct ieee80211_hw *hw)
348*af46caf0SBitterblue Smith {
349*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
350*af46caf0SBitterblue Smith 	struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
351*af46caf0SBitterblue Smith 	struct rtl_phy *rtlphy = &rtlpriv->phy;
352*af46caf0SBitterblue Smith 	bool ret;
353*af46caf0SBitterblue Smith 
354*af46caf0SBitterblue Smith 	rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "==>\n");
355*af46caf0SBitterblue Smith 	ret = _rtl92du_phy_config_bb(hw, BASEBAND_CONFIG_PHY_REG);
356*af46caf0SBitterblue Smith 	if (!ret) {
357*af46caf0SBitterblue Smith 		pr_err("Write BB Reg Fail!!\n");
358*af46caf0SBitterblue Smith 		return false;
359*af46caf0SBitterblue Smith 	}
360*af46caf0SBitterblue Smith 
361*af46caf0SBitterblue Smith 	if (!rtlefuse->autoload_failflag) {
362*af46caf0SBitterblue Smith 		rtlphy->pwrgroup_cnt = 0;
363*af46caf0SBitterblue Smith 		ret = _rtl92du_phy_config_bb_pg(hw, BASEBAND_CONFIG_PHY_REG);
364*af46caf0SBitterblue Smith 	}
365*af46caf0SBitterblue Smith 	if (!ret) {
366*af46caf0SBitterblue Smith 		pr_err("BB_PG Reg Fail!!\n");
367*af46caf0SBitterblue Smith 		return false;
368*af46caf0SBitterblue Smith 	}
369*af46caf0SBitterblue Smith 
370*af46caf0SBitterblue Smith 	ret = _rtl92du_phy_config_bb(hw, BASEBAND_CONFIG_AGC_TAB);
371*af46caf0SBitterblue Smith 	if (!ret) {
372*af46caf0SBitterblue Smith 		pr_err("AGC Table Fail\n");
373*af46caf0SBitterblue Smith 		return false;
374*af46caf0SBitterblue Smith 	}
375*af46caf0SBitterblue Smith 
376*af46caf0SBitterblue Smith 	rtlphy->cck_high_power = (bool)rtl_get_bbreg(hw,
377*af46caf0SBitterblue Smith 						     RFPGA0_XA_HSSIPARAMETER2,
378*af46caf0SBitterblue Smith 						     0x200);
379*af46caf0SBitterblue Smith 
380*af46caf0SBitterblue Smith 	return true;
381*af46caf0SBitterblue Smith }
382*af46caf0SBitterblue Smith 
rtl92du_phy_bb_config(struct ieee80211_hw * hw)383*af46caf0SBitterblue Smith bool rtl92du_phy_bb_config(struct ieee80211_hw *hw)
384*af46caf0SBitterblue Smith {
385*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
386*af46caf0SBitterblue Smith 	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
387*af46caf0SBitterblue Smith 	bool rtstatus;
388*af46caf0SBitterblue Smith 	u32 regvaldw;
389*af46caf0SBitterblue Smith 	u16 regval;
390*af46caf0SBitterblue Smith 	u8 value;
391*af46caf0SBitterblue Smith 
392*af46caf0SBitterblue Smith 	rtl92d_phy_init_bb_rf_register_definition(hw);
393*af46caf0SBitterblue Smith 
394*af46caf0SBitterblue Smith 	regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
395*af46caf0SBitterblue Smith 	rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
396*af46caf0SBitterblue Smith 		       regval | BIT(13) | BIT(0) | BIT(1));
397*af46caf0SBitterblue Smith 
398*af46caf0SBitterblue Smith 	rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83);
399*af46caf0SBitterblue Smith 	rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb);
400*af46caf0SBitterblue Smith 
401*af46caf0SBitterblue Smith 	/* 0x1f bit7 bit6 represent for mac0/mac1 driver ready */
402*af46caf0SBitterblue Smith 	value = rtl_read_byte(rtlpriv, REG_RF_CTRL);
403*af46caf0SBitterblue Smith 	rtl_write_byte(rtlpriv, REG_RF_CTRL, value | RF_EN | RF_RSTB |
404*af46caf0SBitterblue Smith 		RF_SDMRSTB);
405*af46caf0SBitterblue Smith 
406*af46caf0SBitterblue Smith 	value = FEN_BB_GLB_RSTN | FEN_BBRSTB;
407*af46caf0SBitterblue Smith 	if (rtlhal->interface == INTF_PCI)
408*af46caf0SBitterblue Smith 		value |= FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE;
409*af46caf0SBitterblue Smith 	else if (rtlhal->interface == INTF_USB)
410*af46caf0SBitterblue Smith 		value |= FEN_USBA | FEN_USBD;
411*af46caf0SBitterblue Smith 	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, value);
412*af46caf0SBitterblue Smith 
413*af46caf0SBitterblue Smith 	regvaldw = rtl_read_dword(rtlpriv, RFPGA0_XCD_RFPARAMETER);
414*af46caf0SBitterblue Smith 	regvaldw &= ~BIT(31);
415*af46caf0SBitterblue Smith 	rtl_write_dword(rtlpriv, RFPGA0_XCD_RFPARAMETER, regvaldw);
416*af46caf0SBitterblue Smith 
417*af46caf0SBitterblue Smith 	/* To Fix MAC loopback mode fail. */
418*af46caf0SBitterblue Smith 	rtl_write_byte(rtlpriv, REG_LDOHCI12_CTRL, 0x0f);
419*af46caf0SBitterblue Smith 	rtl_write_byte(rtlpriv, 0x15, 0xe9);
420*af46caf0SBitterblue Smith 
421*af46caf0SBitterblue Smith 	rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
422*af46caf0SBitterblue Smith 	if (!(IS_92D_SINGLEPHY(rtlpriv->rtlhal.version)) &&
423*af46caf0SBitterblue Smith 	    rtlhal->interface == INTF_PCI) {
424*af46caf0SBitterblue Smith 		regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0);
425*af46caf0SBitterblue Smith 		rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23));
426*af46caf0SBitterblue Smith 	}
427*af46caf0SBitterblue Smith 
428*af46caf0SBitterblue Smith 	rtstatus = _rtl92du_phy_bb_config(hw);
429*af46caf0SBitterblue Smith 
430*af46caf0SBitterblue Smith 	/* Crystal calibration */
431*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, REG_AFE_XTAL_CTRL, 0xf0,
432*af46caf0SBitterblue Smith 		      rtlpriv->efuse.crystalcap & 0x0f);
433*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, REG_AFE_PLL_CTRL, 0xf0000000,
434*af46caf0SBitterblue Smith 		      (rtlpriv->efuse.crystalcap & 0xf0) >> 4);
435*af46caf0SBitterblue Smith 
436*af46caf0SBitterblue Smith 	return rtstatus;
437*af46caf0SBitterblue Smith }
438*af46caf0SBitterblue Smith 
rtl92du_phy_rf_config(struct ieee80211_hw * hw)439*af46caf0SBitterblue Smith bool rtl92du_phy_rf_config(struct ieee80211_hw *hw)
440*af46caf0SBitterblue Smith {
441*af46caf0SBitterblue Smith 	return rtl92du_phy_rf6052_config(hw);
442*af46caf0SBitterblue Smith }
443*af46caf0SBitterblue Smith 
rtl92du_phy_config_rf_with_headerfile(struct ieee80211_hw * hw,enum rf_content content,enum radio_path rfpath)444*af46caf0SBitterblue Smith bool rtl92du_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
445*af46caf0SBitterblue Smith 					   enum rf_content content,
446*af46caf0SBitterblue Smith 					   enum radio_path rfpath)
447*af46caf0SBitterblue Smith {
448*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
449*af46caf0SBitterblue Smith 	u16 radioa_arraylen, radiob_arraylen;
450*af46caf0SBitterblue Smith 	const u32 *radioa_array_table;
451*af46caf0SBitterblue Smith 	const u32 *radiob_array_table;
452*af46caf0SBitterblue Smith 	int i;
453*af46caf0SBitterblue Smith 
454*af46caf0SBitterblue Smith 	radioa_arraylen = RADIOA_2T_ARRAYLENGTH;
455*af46caf0SBitterblue Smith 	radioa_array_table = rtl8192du_radioa_2tarray;
456*af46caf0SBitterblue Smith 	radiob_arraylen = RADIOB_2T_ARRAYLENGTH;
457*af46caf0SBitterblue Smith 	radiob_array_table = rtl8192du_radiob_2tarray;
458*af46caf0SBitterblue Smith 	if (rtlpriv->efuse.internal_pa_5g[0]) {
459*af46caf0SBitterblue Smith 		radioa_arraylen = RADIOA_2T_INT_PA_ARRAYLENGTH;
460*af46caf0SBitterblue Smith 		radioa_array_table = rtl8192du_radioa_2t_int_paarray;
461*af46caf0SBitterblue Smith 	}
462*af46caf0SBitterblue Smith 	if (rtlpriv->efuse.internal_pa_5g[1]) {
463*af46caf0SBitterblue Smith 		radiob_arraylen = RADIOB_2T_INT_PA_ARRAYLENGTH;
464*af46caf0SBitterblue Smith 		radiob_array_table = rtl8192du_radiob_2t_int_paarray;
465*af46caf0SBitterblue Smith 	}
466*af46caf0SBitterblue Smith 	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
467*af46caf0SBitterblue Smith 		"PHY_ConfigRFWithHeaderFile() Radio_A:Rtl819XRadioA_1TArray\n");
468*af46caf0SBitterblue Smith 	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
469*af46caf0SBitterblue Smith 		"PHY_ConfigRFWithHeaderFile() Radio_B:Rtl819XRadioB_1TArray\n");
470*af46caf0SBitterblue Smith 	rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath);
471*af46caf0SBitterblue Smith 
472*af46caf0SBitterblue Smith 	/* this only happens when DMDP, mac0 start on 2.4G,
473*af46caf0SBitterblue Smith 	 * mac1 start on 5G, mac 0 has to set phy0 & phy1
474*af46caf0SBitterblue Smith 	 * pathA or mac1 has to set phy0 & phy1 pathA
475*af46caf0SBitterblue Smith 	 */
476*af46caf0SBitterblue Smith 	if (content == radiob_txt && rfpath == RF90_PATH_A) {
477*af46caf0SBitterblue Smith 		rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
478*af46caf0SBitterblue Smith 			" ===> althougth Path A, we load radiob.txt\n");
479*af46caf0SBitterblue Smith 		radioa_arraylen = radiob_arraylen;
480*af46caf0SBitterblue Smith 		radioa_array_table = radiob_array_table;
481*af46caf0SBitterblue Smith 	}
482*af46caf0SBitterblue Smith 
483*af46caf0SBitterblue Smith 	switch (rfpath) {
484*af46caf0SBitterblue Smith 	case RF90_PATH_A:
485*af46caf0SBitterblue Smith 		for (i = 0; i < radioa_arraylen; i = i + 2) {
486*af46caf0SBitterblue Smith 			rtl_rfreg_delay(hw, rfpath, radioa_array_table[i],
487*af46caf0SBitterblue Smith 					RFREG_OFFSET_MASK,
488*af46caf0SBitterblue Smith 					radioa_array_table[i + 1]);
489*af46caf0SBitterblue Smith 		}
490*af46caf0SBitterblue Smith 		break;
491*af46caf0SBitterblue Smith 	case RF90_PATH_B:
492*af46caf0SBitterblue Smith 		for (i = 0; i < radiob_arraylen; i = i + 2) {
493*af46caf0SBitterblue Smith 			rtl_rfreg_delay(hw, rfpath, radiob_array_table[i],
494*af46caf0SBitterblue Smith 					RFREG_OFFSET_MASK,
495*af46caf0SBitterblue Smith 					radiob_array_table[i + 1]);
496*af46caf0SBitterblue Smith 		}
497*af46caf0SBitterblue Smith 		break;
498*af46caf0SBitterblue Smith 	case RF90_PATH_C:
499*af46caf0SBitterblue Smith 	case RF90_PATH_D:
500*af46caf0SBitterblue Smith 		pr_err("switch case %#x not processed\n", rfpath);
501*af46caf0SBitterblue Smith 		break;
502*af46caf0SBitterblue Smith 	}
503*af46caf0SBitterblue Smith 
504*af46caf0SBitterblue Smith 	return true;
505*af46caf0SBitterblue Smith }
506*af46caf0SBitterblue Smith 
rtl92du_phy_set_bw_mode(struct ieee80211_hw * hw,enum nl80211_channel_type ch_type)507*af46caf0SBitterblue Smith void rtl92du_phy_set_bw_mode(struct ieee80211_hw *hw,
508*af46caf0SBitterblue Smith 			     enum nl80211_channel_type ch_type)
509*af46caf0SBitterblue Smith {
510*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
511*af46caf0SBitterblue Smith 	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
512*af46caf0SBitterblue Smith 	struct rtl_phy *rtlphy = &rtlpriv->phy;
513*af46caf0SBitterblue Smith 	struct rtl_mac *mac = rtl_mac(rtlpriv);
514*af46caf0SBitterblue Smith 	u8 reg_bw_opmode;
515*af46caf0SBitterblue Smith 	u8 reg_prsr_rsc;
516*af46caf0SBitterblue Smith 
517*af46caf0SBitterblue Smith 	if (rtlphy->set_bwmode_inprogress)
518*af46caf0SBitterblue Smith 		return;
519*af46caf0SBitterblue Smith 
520*af46caf0SBitterblue Smith 	if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) {
521*af46caf0SBitterblue Smith 		rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
522*af46caf0SBitterblue Smith 			"FALSE driver sleep or unload\n");
523*af46caf0SBitterblue Smith 		return;
524*af46caf0SBitterblue Smith 	}
525*af46caf0SBitterblue Smith 
526*af46caf0SBitterblue Smith 	rtlphy->set_bwmode_inprogress = true;
527*af46caf0SBitterblue Smith 
528*af46caf0SBitterblue Smith 	rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n",
529*af46caf0SBitterblue Smith 		rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
530*af46caf0SBitterblue Smith 		"20MHz" : "40MHz");
531*af46caf0SBitterblue Smith 
532*af46caf0SBitterblue Smith 	reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
533*af46caf0SBitterblue Smith 	reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
534*af46caf0SBitterblue Smith 
535*af46caf0SBitterblue Smith 	switch (rtlphy->current_chan_bw) {
536*af46caf0SBitterblue Smith 	case HT_CHANNEL_WIDTH_20:
537*af46caf0SBitterblue Smith 		reg_bw_opmode |= BW_OPMODE_20MHZ;
538*af46caf0SBitterblue Smith 		rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
539*af46caf0SBitterblue Smith 		break;
540*af46caf0SBitterblue Smith 	case HT_CHANNEL_WIDTH_20_40:
541*af46caf0SBitterblue Smith 		reg_bw_opmode &= ~BW_OPMODE_20MHZ;
542*af46caf0SBitterblue Smith 		rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
543*af46caf0SBitterblue Smith 
544*af46caf0SBitterblue Smith 		reg_prsr_rsc = (reg_prsr_rsc & 0x90) |
545*af46caf0SBitterblue Smith 			       (mac->cur_40_prime_sc << 5);
546*af46caf0SBitterblue Smith 		rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
547*af46caf0SBitterblue Smith 		break;
548*af46caf0SBitterblue Smith 	default:
549*af46caf0SBitterblue Smith 		pr_err("unknown bandwidth: %#X\n",
550*af46caf0SBitterblue Smith 		       rtlphy->current_chan_bw);
551*af46caf0SBitterblue Smith 		break;
552*af46caf0SBitterblue Smith 	}
553*af46caf0SBitterblue Smith 
554*af46caf0SBitterblue Smith 	switch (rtlphy->current_chan_bw) {
555*af46caf0SBitterblue Smith 	case HT_CHANNEL_WIDTH_20:
556*af46caf0SBitterblue Smith 		rtl92du_phy_set_bb_reg_1byte(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
557*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
558*af46caf0SBitterblue Smith 		/* SET BIT10 BIT11  for receive cck */
559*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10) | BIT(11), 3);
560*af46caf0SBitterblue Smith 		break;
561*af46caf0SBitterblue Smith 	case HT_CHANNEL_WIDTH_20_40:
562*af46caf0SBitterblue Smith 		rtl92du_phy_set_bb_reg_1byte(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
563*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
564*af46caf0SBitterblue Smith 		/* Set Control channel to upper or lower.
565*af46caf0SBitterblue Smith 		 * These settings are required only for 40MHz
566*af46caf0SBitterblue Smith 		 */
567*af46caf0SBitterblue Smith 		if (rtlhal->current_bandtype == BAND_ON_2_4G)
568*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCKSIDEBAND,
569*af46caf0SBitterblue Smith 				      mac->cur_40_prime_sc >> 1);
570*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
571*af46caf0SBitterblue Smith 		/* SET BIT10 BIT11  for receive cck */
572*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2,
573*af46caf0SBitterblue Smith 			      BIT(10) | BIT(11), 0);
574*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, 0x818, BIT(26) | BIT(27),
575*af46caf0SBitterblue Smith 			      mac->cur_40_prime_sc ==
576*af46caf0SBitterblue Smith 			      HAL_PRIME_CHNL_OFFSET_LOWER ? 2 : 1);
577*af46caf0SBitterblue Smith 		break;
578*af46caf0SBitterblue Smith 	default:
579*af46caf0SBitterblue Smith 		pr_err("unknown bandwidth: %#X\n",
580*af46caf0SBitterblue Smith 		       rtlphy->current_chan_bw);
581*af46caf0SBitterblue Smith 		break;
582*af46caf0SBitterblue Smith 	}
583*af46caf0SBitterblue Smith 
584*af46caf0SBitterblue Smith 	rtl92d_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
585*af46caf0SBitterblue Smith 
586*af46caf0SBitterblue Smith 	rtlphy->set_bwmode_inprogress = false;
587*af46caf0SBitterblue Smith 	rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
588*af46caf0SBitterblue Smith }
589*af46caf0SBitterblue Smith 
_rtl92du_phy_stop_trx_before_changeband(struct ieee80211_hw * hw)590*af46caf0SBitterblue Smith static void _rtl92du_phy_stop_trx_before_changeband(struct ieee80211_hw *hw)
591*af46caf0SBitterblue Smith {
592*af46caf0SBitterblue Smith 	rtl92du_phy_set_bb_reg_1byte(hw, RFPGA0_RFMOD, BCCKEN | BOFDMEN, 0);
593*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x00);
594*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0x0);
595*af46caf0SBitterblue Smith }
596*af46caf0SBitterblue Smith 
rtl92du_phy_switch_wirelessband(struct ieee80211_hw * hw,u8 band)597*af46caf0SBitterblue Smith static void rtl92du_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band)
598*af46caf0SBitterblue Smith {
599*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
600*af46caf0SBitterblue Smith 	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
601*af46caf0SBitterblue Smith 	u16 basic_rates;
602*af46caf0SBitterblue Smith 	u32 reg_mac;
603*af46caf0SBitterblue Smith 	u8 value8;
604*af46caf0SBitterblue Smith 
605*af46caf0SBitterblue Smith 	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "==>\n");
606*af46caf0SBitterblue Smith 	rtlhal->bandset = band;
607*af46caf0SBitterblue Smith 	rtlhal->current_bandtype = band;
608*af46caf0SBitterblue Smith 	if (IS_92D_SINGLEPHY(rtlhal->version))
609*af46caf0SBitterblue Smith 		rtlhal->bandset = BAND_ON_BOTH;
610*af46caf0SBitterblue Smith 
611*af46caf0SBitterblue Smith 	/* stop RX/Tx */
612*af46caf0SBitterblue Smith 	_rtl92du_phy_stop_trx_before_changeband(hw);
613*af46caf0SBitterblue Smith 
614*af46caf0SBitterblue Smith 	/* reconfig BB/RF according to wireless mode */
615*af46caf0SBitterblue Smith 	if (rtlhal->current_bandtype == BAND_ON_2_4G)
616*af46caf0SBitterblue Smith 		/* BB & RF Config */
617*af46caf0SBitterblue Smith 		rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "====>2.4G\n");
618*af46caf0SBitterblue Smith 	else
619*af46caf0SBitterblue Smith 		/* 5G band */
620*af46caf0SBitterblue Smith 		rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "====>5G\n");
621*af46caf0SBitterblue Smith 
622*af46caf0SBitterblue Smith 	if (rtlhal->interfaceindex == 1)
623*af46caf0SBitterblue Smith 		_rtl92du_phy_config_bb(hw, BASEBAND_CONFIG_AGC_TAB);
624*af46caf0SBitterblue Smith 
625*af46caf0SBitterblue Smith 	rtl92du_update_bbrf_configuration(hw);
626*af46caf0SBitterblue Smith 
627*af46caf0SBitterblue Smith 	basic_rates = RRSR_6M | RRSR_12M | RRSR_24M;
628*af46caf0SBitterblue Smith 	if (rtlhal->current_bandtype == BAND_ON_2_4G)
629*af46caf0SBitterblue Smith 		basic_rates |= RRSR_1M | RRSR_2M | RRSR_5_5M | RRSR_11M;
630*af46caf0SBitterblue Smith 	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
631*af46caf0SBitterblue Smith 				      (u8 *)&basic_rates);
632*af46caf0SBitterblue Smith 
633*af46caf0SBitterblue Smith 	rtl92du_phy_set_bb_reg_1byte(hw, RFPGA0_RFMOD, BCCKEN | BOFDMEN, 0x3);
634*af46caf0SBitterblue Smith 
635*af46caf0SBitterblue Smith 	/* 20M BW. */
636*af46caf0SBitterblue Smith 	/* rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); */
637*af46caf0SBitterblue Smith 	rtlhal->reloadtxpowerindex = true;
638*af46caf0SBitterblue Smith 
639*af46caf0SBitterblue Smith 	reg_mac = rtlhal->interfaceindex == 0 ? REG_MAC0 : REG_MAC1;
640*af46caf0SBitterblue Smith 
641*af46caf0SBitterblue Smith 	/* notice fw know band status  0x81[1]/0x53[1] = 0: 5G, 1: 2G */
642*af46caf0SBitterblue Smith 	if (rtlhal->current_bandtype == BAND_ON_2_4G) {
643*af46caf0SBitterblue Smith 		value8 = rtl_read_byte(rtlpriv,	reg_mac);
644*af46caf0SBitterblue Smith 		value8 |= BIT(1);
645*af46caf0SBitterblue Smith 		rtl_write_byte(rtlpriv, reg_mac, value8);
646*af46caf0SBitterblue Smith 	} else {
647*af46caf0SBitterblue Smith 		value8 = rtl_read_byte(rtlpriv, reg_mac);
648*af46caf0SBitterblue Smith 		value8 &= ~BIT(1);
649*af46caf0SBitterblue Smith 		rtl_write_byte(rtlpriv, reg_mac, value8);
650*af46caf0SBitterblue Smith 	}
651*af46caf0SBitterblue Smith 	mdelay(1);
652*af46caf0SBitterblue Smith 	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "<==Switch Band OK\n");
653*af46caf0SBitterblue Smith }
654*af46caf0SBitterblue Smith 
_rtl92du_phy_reload_imr_setting(struct ieee80211_hw * hw,u8 channel,u8 rfpath)655*af46caf0SBitterblue Smith static void _rtl92du_phy_reload_imr_setting(struct ieee80211_hw *hw,
656*af46caf0SBitterblue Smith 					    u8 channel, u8 rfpath)
657*af46caf0SBitterblue Smith {
658*af46caf0SBitterblue Smith 	struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
659*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
660*af46caf0SBitterblue Smith 	u8 group, i;
661*af46caf0SBitterblue Smith 
662*af46caf0SBitterblue Smith 	if (rtlusb->udev->speed != USB_SPEED_HIGH)
663*af46caf0SBitterblue Smith 		return;
664*af46caf0SBitterblue Smith 
665*af46caf0SBitterblue Smith 	rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "====>path %d\n", rfpath);
666*af46caf0SBitterblue Smith 	if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) {
667*af46caf0SBitterblue Smith 		rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "====>5G\n");
668*af46caf0SBitterblue Smith 		rtl92du_phy_set_bb_reg_1byte(hw, RFPGA0_RFMOD,
669*af46caf0SBitterblue Smith 					     BOFDMEN | BCCKEN, 0);
670*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0xf);
671*af46caf0SBitterblue Smith 
672*af46caf0SBitterblue Smith 		/* fc area 0xd2c */
673*af46caf0SBitterblue Smith 		if (channel >= 149)
674*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(13) |
675*af46caf0SBitterblue Smith 				      BIT(14), 2);
676*af46caf0SBitterblue Smith 		else
677*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(13) |
678*af46caf0SBitterblue Smith 				      BIT(14), 1);
679*af46caf0SBitterblue Smith 
680*af46caf0SBitterblue Smith 		/* leave 0 for channel1-14. */
681*af46caf0SBitterblue Smith 		group = channel <= 64 ? 1 : 2;
682*af46caf0SBitterblue Smith 		for (i = 0; i < MAX_RF_IMR_INDEX_NORMAL; i++)
683*af46caf0SBitterblue Smith 			rtl_set_rfreg(hw, (enum radio_path)rfpath,
684*af46caf0SBitterblue Smith 				      rf_reg_for_5g_swchnl_normal[i],
685*af46caf0SBitterblue Smith 				      RFREG_OFFSET_MASK,
686*af46caf0SBitterblue Smith 				      rf_imr_param_normal[group][i]);
687*af46caf0SBitterblue Smith 
688*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0);
689*af46caf0SBitterblue Smith 		rtl92du_phy_set_bb_reg_1byte(hw, RFPGA0_RFMOD,
690*af46caf0SBitterblue Smith 					     BOFDMEN | BCCKEN, 3);
691*af46caf0SBitterblue Smith 	} else {
692*af46caf0SBitterblue Smith 		/* G band. */
693*af46caf0SBitterblue Smith 		rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD,
694*af46caf0SBitterblue Smith 			"Load RF IMR parameters for G band. IMR already setting %d\n",
695*af46caf0SBitterblue Smith 			rtlpriv->rtlhal.load_imrandiqk_setting_for2g);
696*af46caf0SBitterblue Smith 		rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "====>2.4G\n");
697*af46caf0SBitterblue Smith 
698*af46caf0SBitterblue Smith 		if (!rtlpriv->rtlhal.load_imrandiqk_setting_for2g) {
699*af46caf0SBitterblue Smith 			rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD,
700*af46caf0SBitterblue Smith 				"Load RF IMR parameters for G band. %d\n",
701*af46caf0SBitterblue Smith 				rfpath);
702*af46caf0SBitterblue Smith 			rtl92du_phy_set_bb_reg_1byte(hw, RFPGA0_RFMOD,
703*af46caf0SBitterblue Smith 						     BOFDMEN | BCCKEN, 0);
704*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4,
705*af46caf0SBitterblue Smith 				      0x00f00000, 0xf);
706*af46caf0SBitterblue Smith 
707*af46caf0SBitterblue Smith 			for (i = 0; i < MAX_RF_IMR_INDEX_NORMAL; i++) {
708*af46caf0SBitterblue Smith 				rtl_set_rfreg(hw, (enum radio_path)rfpath,
709*af46caf0SBitterblue Smith 					      rf_reg_for_5g_swchnl_normal[i],
710*af46caf0SBitterblue Smith 					      RFREG_OFFSET_MASK,
711*af46caf0SBitterblue Smith 					      rf_imr_param_normal[0][i]);
712*af46caf0SBitterblue Smith 			}
713*af46caf0SBitterblue Smith 
714*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4,
715*af46caf0SBitterblue Smith 				      0x00f00000, 0);
716*af46caf0SBitterblue Smith 			rtl92du_phy_set_bb_reg_1byte(hw, RFPGA0_RFMOD,
717*af46caf0SBitterblue Smith 						     BOFDMEN | BCCKEN, 3);
718*af46caf0SBitterblue Smith 		}
719*af46caf0SBitterblue Smith 	}
720*af46caf0SBitterblue Smith 	rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n");
721*af46caf0SBitterblue Smith }
722*af46caf0SBitterblue Smith 
_rtl92du_phy_switch_rf_setting(struct ieee80211_hw * hw,u8 channel)723*af46caf0SBitterblue Smith static void _rtl92du_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)
724*af46caf0SBitterblue Smith {
725*af46caf0SBitterblue Smith 	struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
726*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
727*af46caf0SBitterblue Smith 	struct rtl_hal *rtlhal = &rtlpriv->rtlhal;
728*af46caf0SBitterblue Smith 	struct rtl_phy *rtlphy = &rtlpriv->phy;
729*af46caf0SBitterblue Smith 	u8 path = rtlhal->current_bandtype == BAND_ON_5G ? RF90_PATH_A
730*af46caf0SBitterblue Smith 							 : RF90_PATH_B;
731*af46caf0SBitterblue Smith 	u32 u4regvalue, mask = 0x1C000, value = 0, u4tmp, u4tmp2;
732*af46caf0SBitterblue Smith 	bool need_pwr_down = false, internal_pa = false;
733*af46caf0SBitterblue Smith 	u32 regb30 = rtl_get_bbreg(hw, 0xb30, BIT(27));
734*af46caf0SBitterblue Smith 	u8 index = 0, i, rfpath;
735*af46caf0SBitterblue Smith 
736*af46caf0SBitterblue Smith 	if (rtlusb->udev->speed != USB_SPEED_HIGH)
737*af46caf0SBitterblue Smith 		return;
738*af46caf0SBitterblue Smith 
739*af46caf0SBitterblue Smith 	rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "====>\n");
740*af46caf0SBitterblue Smith 	/* config path A for 5G */
741*af46caf0SBitterblue Smith 	if (rtlhal->current_bandtype == BAND_ON_5G) {
742*af46caf0SBitterblue Smith 		rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "====>5G\n");
743*af46caf0SBitterblue Smith 		u4tmp = rtlpriv->curveindex_5g[channel - 1];
744*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
745*af46caf0SBitterblue Smith 			"ver 1 set RF-A, 5G, 0x28 = 0x%x !!\n", u4tmp);
746*af46caf0SBitterblue Smith 
747*af46caf0SBitterblue Smith 		for (i = 0; i < RF_CHNL_NUM_5G; i++) {
748*af46caf0SBitterblue Smith 			if (channel == rf_chnl_5g[i] && channel <= 140)
749*af46caf0SBitterblue Smith 				index = 0;
750*af46caf0SBitterblue Smith 		}
751*af46caf0SBitterblue Smith 		for (i = 0; i < RF_CHNL_NUM_5G_40M; i++) {
752*af46caf0SBitterblue Smith 			if (channel == rf_chnl_5g_40m[i] && channel <= 140)
753*af46caf0SBitterblue Smith 				index = 1;
754*af46caf0SBitterblue Smith 		}
755*af46caf0SBitterblue Smith 		if (channel == 149 || channel == 155 || channel == 161)
756*af46caf0SBitterblue Smith 			index = 2;
757*af46caf0SBitterblue Smith 		else if (channel == 151 || channel == 153 || channel == 163 ||
758*af46caf0SBitterblue Smith 			 channel == 165)
759*af46caf0SBitterblue Smith 			index = 3;
760*af46caf0SBitterblue Smith 		else if (channel == 157 || channel == 159)
761*af46caf0SBitterblue Smith 			index = 4;
762*af46caf0SBitterblue Smith 
763*af46caf0SBitterblue Smith 		if (rtlhal->macphymode == DUALMAC_DUALPHY &&
764*af46caf0SBitterblue Smith 		    rtlhal->interfaceindex == 1) {
765*af46caf0SBitterblue Smith 			need_pwr_down = rtl92du_phy_enable_anotherphy(hw, false);
766*af46caf0SBitterblue Smith 			rtlhal->during_mac1init_radioa = true;
767*af46caf0SBitterblue Smith 			/* asume no this case */
768*af46caf0SBitterblue Smith 			if (need_pwr_down)
769*af46caf0SBitterblue Smith 				rtl92d_phy_enable_rf_env(hw, path,
770*af46caf0SBitterblue Smith 							 &u4regvalue);
771*af46caf0SBitterblue Smith 		}
772*af46caf0SBitterblue Smith 
773*af46caf0SBitterblue Smith 		/* DMDP, if band = 5G, Mac0 need to set PHY1 when regB30[27]=1 */
774*af46caf0SBitterblue Smith 		if (regb30 && rtlhal->interfaceindex == 0) {
775*af46caf0SBitterblue Smith 			need_pwr_down = rtl92du_phy_enable_anotherphy(hw, true);
776*af46caf0SBitterblue Smith 			rtlhal->during_mac0init_radiob = true;
777*af46caf0SBitterblue Smith 			if (need_pwr_down)
778*af46caf0SBitterblue Smith 				rtl92d_phy_enable_rf_env(hw, path,
779*af46caf0SBitterblue Smith 							 &u4regvalue);
780*af46caf0SBitterblue Smith 		}
781*af46caf0SBitterblue Smith 
782*af46caf0SBitterblue Smith 		for (i = 0; i < RF_REG_NUM_FOR_C_CUT_5G; i++) {
783*af46caf0SBitterblue Smith 			if (i == 0 && rtlhal->macphymode == DUALMAC_DUALPHY) {
784*af46caf0SBitterblue Smith 				rtl_set_rfreg(hw, (enum radio_path)path,
785*af46caf0SBitterblue Smith 					      rf_reg_for_c_cut_5g[i],
786*af46caf0SBitterblue Smith 					      RFREG_OFFSET_MASK, 0xE439D);
787*af46caf0SBitterblue Smith 			} else if (rf_reg_for_c_cut_5g[i] == RF_SYN_G4) {
788*af46caf0SBitterblue Smith 				u4tmp2 = (rf_reg_pram_c_5g[index][i] &
789*af46caf0SBitterblue Smith 				     0x7FF) | (u4tmp << 11);
790*af46caf0SBitterblue Smith 				if (channel == 36)
791*af46caf0SBitterblue Smith 					u4tmp2 &= ~(BIT(7) | BIT(6));
792*af46caf0SBitterblue Smith 				rtl_set_rfreg(hw, (enum radio_path)path,
793*af46caf0SBitterblue Smith 					      rf_reg_for_c_cut_5g[i],
794*af46caf0SBitterblue Smith 					      RFREG_OFFSET_MASK, u4tmp2);
795*af46caf0SBitterblue Smith 			} else {
796*af46caf0SBitterblue Smith 				rtl_set_rfreg(hw, (enum radio_path)path,
797*af46caf0SBitterblue Smith 					      rf_reg_for_c_cut_5g[i],
798*af46caf0SBitterblue Smith 					      RFREG_OFFSET_MASK,
799*af46caf0SBitterblue Smith 					      rf_reg_pram_c_5g[index][i]);
800*af46caf0SBitterblue Smith 			}
801*af46caf0SBitterblue Smith 			rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
802*af46caf0SBitterblue Smith 				"offset 0x%x value 0x%x path %d index %d readback 0x%x\n",
803*af46caf0SBitterblue Smith 				rf_reg_for_c_cut_5g[i],
804*af46caf0SBitterblue Smith 				rf_reg_pram_c_5g[index][i],
805*af46caf0SBitterblue Smith 				path, index,
806*af46caf0SBitterblue Smith 				rtl_get_rfreg(hw, (enum radio_path)path,
807*af46caf0SBitterblue Smith 					      rf_reg_for_c_cut_5g[i],
808*af46caf0SBitterblue Smith 					      RFREG_OFFSET_MASK));
809*af46caf0SBitterblue Smith 		}
810*af46caf0SBitterblue Smith 		if (rtlhal->macphymode == DUALMAC_DUALPHY &&
811*af46caf0SBitterblue Smith 		    rtlhal->interfaceindex == 1) {
812*af46caf0SBitterblue Smith 			if (need_pwr_down)
813*af46caf0SBitterblue Smith 				rtl92d_phy_restore_rf_env(hw, path, &u4regvalue);
814*af46caf0SBitterblue Smith 
815*af46caf0SBitterblue Smith 			rtl92du_phy_powerdown_anotherphy(hw, false);
816*af46caf0SBitterblue Smith 		}
817*af46caf0SBitterblue Smith 
818*af46caf0SBitterblue Smith 		if (regb30 && rtlhal->interfaceindex == 0) {
819*af46caf0SBitterblue Smith 			if (need_pwr_down)
820*af46caf0SBitterblue Smith 				rtl92d_phy_restore_rf_env(hw, path, &u4regvalue);
821*af46caf0SBitterblue Smith 
822*af46caf0SBitterblue Smith 			rtl92du_phy_powerdown_anotherphy(hw, true);
823*af46caf0SBitterblue Smith 		}
824*af46caf0SBitterblue Smith 
825*af46caf0SBitterblue Smith 		if (channel < 149)
826*af46caf0SBitterblue Smith 			value = 0x07;
827*af46caf0SBitterblue Smith 		else if (channel >= 149)
828*af46caf0SBitterblue Smith 			value = 0x02;
829*af46caf0SBitterblue Smith 		if (channel >= 36 && channel <= 64)
830*af46caf0SBitterblue Smith 			index = 0;
831*af46caf0SBitterblue Smith 		else if (channel >= 100 && channel <= 140)
832*af46caf0SBitterblue Smith 			index = 1;
833*af46caf0SBitterblue Smith 		else
834*af46caf0SBitterblue Smith 			index = 2;
835*af46caf0SBitterblue Smith 
836*af46caf0SBitterblue Smith 		for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
837*af46caf0SBitterblue Smith 			rfpath++) {
838*af46caf0SBitterblue Smith 			if (rtlhal->macphymode == DUALMAC_DUALPHY &&
839*af46caf0SBitterblue Smith 			    rtlhal->interfaceindex == 1) /* MAC 1 5G */
840*af46caf0SBitterblue Smith 				internal_pa = rtlpriv->efuse.internal_pa_5g[1];
841*af46caf0SBitterblue Smith 			else
842*af46caf0SBitterblue Smith 				internal_pa =
843*af46caf0SBitterblue Smith 					 rtlpriv->efuse.internal_pa_5g[rfpath];
844*af46caf0SBitterblue Smith 
845*af46caf0SBitterblue Smith 			if (internal_pa) {
846*af46caf0SBitterblue Smith 				for (i = 0;
847*af46caf0SBitterblue Smith 				     i < RF_REG_NUM_FOR_C_CUT_5G_INTERNALPA;
848*af46caf0SBitterblue Smith 				     i++) {
849*af46caf0SBitterblue Smith 					if (rf_for_c_cut_5g_internal_pa[i] == 0x03 &&
850*af46caf0SBitterblue Smith 					    channel >= 36 && channel <= 64)
851*af46caf0SBitterblue Smith 						rtl_set_rfreg(hw, rfpath,
852*af46caf0SBitterblue Smith 							rf_for_c_cut_5g_internal_pa[i],
853*af46caf0SBitterblue Smith 							RFREG_OFFSET_MASK,
854*af46caf0SBitterblue Smith 							0x7bdef);
855*af46caf0SBitterblue Smith 					else
856*af46caf0SBitterblue Smith 						rtl_set_rfreg(hw, rfpath,
857*af46caf0SBitterblue Smith 							rf_for_c_cut_5g_internal_pa[i],
858*af46caf0SBitterblue Smith 							RFREG_OFFSET_MASK,
859*af46caf0SBitterblue Smith 							rf_pram_c_5g_int_pa[index][i]);
860*af46caf0SBitterblue Smith 					rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD,
861*af46caf0SBitterblue Smith 						"offset 0x%x value 0x%x path %d index %d\n",
862*af46caf0SBitterblue Smith 						rf_for_c_cut_5g_internal_pa[i],
863*af46caf0SBitterblue Smith 						rf_pram_c_5g_int_pa[index][i],
864*af46caf0SBitterblue Smith 						rfpath, index);
865*af46caf0SBitterblue Smith 				}
866*af46caf0SBitterblue Smith 			} else {
867*af46caf0SBitterblue Smith 				rtl_set_rfreg(hw, (enum radio_path)rfpath, RF_TXPA_AG,
868*af46caf0SBitterblue Smith 					      mask, value);
869*af46caf0SBitterblue Smith 			}
870*af46caf0SBitterblue Smith 		}
871*af46caf0SBitterblue Smith 	} else if (rtlhal->current_bandtype == BAND_ON_2_4G) {
872*af46caf0SBitterblue Smith 		rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "====>2.4G\n");
873*af46caf0SBitterblue Smith 		u4tmp = rtlpriv->curveindex_2g[channel - 1];
874*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
875*af46caf0SBitterblue Smith 			"ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", u4tmp);
876*af46caf0SBitterblue Smith 
877*af46caf0SBitterblue Smith 		if (channel == 1 || channel == 2 || channel == 4 ||
878*af46caf0SBitterblue Smith 		    channel == 9 || channel == 10 || channel == 11 ||
879*af46caf0SBitterblue Smith 		    channel == 12)
880*af46caf0SBitterblue Smith 			index = 0;
881*af46caf0SBitterblue Smith 		else if (channel == 3 || channel == 13 || channel == 14)
882*af46caf0SBitterblue Smith 			index = 1;
883*af46caf0SBitterblue Smith 		else if (channel >= 5 && channel <= 8)
884*af46caf0SBitterblue Smith 			index = 2;
885*af46caf0SBitterblue Smith 
886*af46caf0SBitterblue Smith 		if (rtlhal->macphymode == DUALMAC_DUALPHY) {
887*af46caf0SBitterblue Smith 			path = RF90_PATH_A;
888*af46caf0SBitterblue Smith 			if (rtlhal->interfaceindex == 0) {
889*af46caf0SBitterblue Smith 				need_pwr_down =
890*af46caf0SBitterblue Smith 					 rtl92du_phy_enable_anotherphy(hw, true);
891*af46caf0SBitterblue Smith 				rtlhal->during_mac0init_radiob = true;
892*af46caf0SBitterblue Smith 
893*af46caf0SBitterblue Smith 				if (need_pwr_down)
894*af46caf0SBitterblue Smith 					rtl92d_phy_enable_rf_env(hw, path,
895*af46caf0SBitterblue Smith 								 &u4regvalue);
896*af46caf0SBitterblue Smith 			}
897*af46caf0SBitterblue Smith 
898*af46caf0SBitterblue Smith 			/* DMDP, if band = 2G, MAC1 need to set PHY0 when regB30[27]=1 */
899*af46caf0SBitterblue Smith 			if (regb30 && rtlhal->interfaceindex == 1) {
900*af46caf0SBitterblue Smith 				need_pwr_down =
901*af46caf0SBitterblue Smith 					 rtl92du_phy_enable_anotherphy(hw, false);
902*af46caf0SBitterblue Smith 				rtlhal->during_mac1init_radioa = true;
903*af46caf0SBitterblue Smith 
904*af46caf0SBitterblue Smith 				if (need_pwr_down)
905*af46caf0SBitterblue Smith 					rtl92d_phy_enable_rf_env(hw, path,
906*af46caf0SBitterblue Smith 								 &u4regvalue);
907*af46caf0SBitterblue Smith 			}
908*af46caf0SBitterblue Smith 		}
909*af46caf0SBitterblue Smith 
910*af46caf0SBitterblue Smith 		for (i = 0; i < RF_REG_NUM_FOR_C_CUT_2G; i++) {
911*af46caf0SBitterblue Smith 			if (rf_reg_for_c_cut_2g[i] == RF_SYN_G7)
912*af46caf0SBitterblue Smith 				rtl_set_rfreg(hw, (enum radio_path)path,
913*af46caf0SBitterblue Smith 					      rf_reg_for_c_cut_2g[i],
914*af46caf0SBitterblue Smith 					      RFREG_OFFSET_MASK,
915*af46caf0SBitterblue Smith 					      rf_reg_param_for_c_cut_2g[index][i] |
916*af46caf0SBitterblue Smith 					      BIT(17));
917*af46caf0SBitterblue Smith 			else
918*af46caf0SBitterblue Smith 				rtl_set_rfreg(hw, (enum radio_path)path,
919*af46caf0SBitterblue Smith 					      rf_reg_for_c_cut_2g[i],
920*af46caf0SBitterblue Smith 					      RFREG_OFFSET_MASK,
921*af46caf0SBitterblue Smith 					      rf_reg_param_for_c_cut_2g
922*af46caf0SBitterblue Smith 					      [index][i]);
923*af46caf0SBitterblue Smith 
924*af46caf0SBitterblue Smith 			rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
925*af46caf0SBitterblue Smith 				"offset 0x%x value 0x%x mak 0x%x path %d index %d readback 0x%x\n",
926*af46caf0SBitterblue Smith 				rf_reg_for_c_cut_2g[i],
927*af46caf0SBitterblue Smith 				rf_reg_param_for_c_cut_2g[index][i],
928*af46caf0SBitterblue Smith 				rf_reg_mask_for_c_cut_2g[i], path, index,
929*af46caf0SBitterblue Smith 				rtl_get_rfreg(hw, (enum radio_path)path,
930*af46caf0SBitterblue Smith 					      rf_reg_for_c_cut_2g[i],
931*af46caf0SBitterblue Smith 					      RFREG_OFFSET_MASK));
932*af46caf0SBitterblue Smith 		}
933*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
934*af46caf0SBitterblue Smith 			"cosa ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n",
935*af46caf0SBitterblue Smith 			rf_syn_g4_for_c_cut_2g | (u4tmp << 11));
936*af46caf0SBitterblue Smith 
937*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, (enum radio_path)path, RF_SYN_G4,
938*af46caf0SBitterblue Smith 			      RFREG_OFFSET_MASK,
939*af46caf0SBitterblue Smith 			      rf_syn_g4_for_c_cut_2g | (u4tmp << 11));
940*af46caf0SBitterblue Smith 
941*af46caf0SBitterblue Smith 		if (rtlhal->macphymode == DUALMAC_DUALPHY &&
942*af46caf0SBitterblue Smith 		    rtlhal->interfaceindex == 0) {
943*af46caf0SBitterblue Smith 			if (need_pwr_down)
944*af46caf0SBitterblue Smith 				rtl92d_phy_restore_rf_env(hw, path, &u4regvalue);
945*af46caf0SBitterblue Smith 
946*af46caf0SBitterblue Smith 			rtl92du_phy_powerdown_anotherphy(hw, true);
947*af46caf0SBitterblue Smith 		}
948*af46caf0SBitterblue Smith 
949*af46caf0SBitterblue Smith 		if (regb30 && rtlhal->interfaceindex == 1) {
950*af46caf0SBitterblue Smith 			if (need_pwr_down)
951*af46caf0SBitterblue Smith 				rtl92d_phy_restore_rf_env(hw, path, &u4regvalue);
952*af46caf0SBitterblue Smith 
953*af46caf0SBitterblue Smith 			rtl92du_phy_powerdown_anotherphy(hw, false);
954*af46caf0SBitterblue Smith 		}
955*af46caf0SBitterblue Smith 	}
956*af46caf0SBitterblue Smith 	rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n");
957*af46caf0SBitterblue Smith }
958*af46caf0SBitterblue Smith 
959*af46caf0SBitterblue Smith /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
_rtl92du_phy_patha_iqk(struct ieee80211_hw * hw,bool configpathb)960*af46caf0SBitterblue Smith static u8 _rtl92du_phy_patha_iqk(struct ieee80211_hw *hw, bool configpathb)
961*af46caf0SBitterblue Smith {
962*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
963*af46caf0SBitterblue Smith 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
964*af46caf0SBitterblue Smith 	u32 regeac, rege94, rege9c, regea4;
965*af46caf0SBitterblue Smith 	u8 result = 0;
966*af46caf0SBitterblue Smith 
967*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path-A IQK setting!\n");
968*af46caf0SBitterblue Smith 
969*af46caf0SBitterblue Smith 	if (rtlhal->interfaceindex == 0) {
970*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x10008c1f);
971*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x10008c1f);
972*af46caf0SBitterblue Smith 	} else {
973*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x10008c22);
974*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x10008c22);
975*af46caf0SBitterblue Smith 	}
976*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82140102);
977*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD,
978*af46caf0SBitterblue Smith 		      configpathb ? 0x28160202 : 0x28160502);
979*af46caf0SBitterblue Smith 	/* path-B IQK setting */
980*af46caf0SBitterblue Smith 	if (configpathb) {
981*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x10008c22);
982*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x10008c22);
983*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82140102);
984*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28160206);
985*af46caf0SBitterblue Smith 	}
986*af46caf0SBitterblue Smith 
987*af46caf0SBitterblue Smith 	/* LO calibration setting */
988*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "LO calibration setting!\n");
989*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911);
990*af46caf0SBitterblue Smith 
991*af46caf0SBitterblue Smith 	/* One shot, path A LOK & IQK */
992*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "One shot, path A LOK & IQK!\n");
993*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
994*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
995*af46caf0SBitterblue Smith 
996*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,
997*af46caf0SBitterblue Smith 		"Delay %d ms for One shot, path A LOK & IQK\n",
998*af46caf0SBitterblue Smith 		IQK_DELAY_TIME);
999*af46caf0SBitterblue Smith 	mdelay(IQK_DELAY_TIME);
1000*af46caf0SBitterblue Smith 
1001*af46caf0SBitterblue Smith 	/* Check failed */
1002*af46caf0SBitterblue Smith 	regeac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1003*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xeac = 0x%x\n", regeac);
1004*af46caf0SBitterblue Smith 	rege94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1005*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xe94 = 0x%x\n", rege94);
1006*af46caf0SBitterblue Smith 	rege9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1007*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xe9c = 0x%x\n", rege9c);
1008*af46caf0SBitterblue Smith 	regea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD);
1009*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xea4 = 0x%x\n", regea4);
1010*af46caf0SBitterblue Smith 
1011*af46caf0SBitterblue Smith 	if (!(regeac & BIT(28)) &&
1012*af46caf0SBitterblue Smith 	    (((rege94 & 0x03FF0000) >> 16) != 0x142) &&
1013*af46caf0SBitterblue Smith 	    (((rege9c & 0x03FF0000) >> 16) != 0x42))
1014*af46caf0SBitterblue Smith 		result |= 0x01;
1015*af46caf0SBitterblue Smith 	else /* if Tx not OK, ignore Rx */
1016*af46caf0SBitterblue Smith 		return result;
1017*af46caf0SBitterblue Smith 
1018*af46caf0SBitterblue Smith 	/* if Tx is OK, check whether Rx is OK */
1019*af46caf0SBitterblue Smith 	if (!(regeac & BIT(27)) &&
1020*af46caf0SBitterblue Smith 	    (((regea4 & 0x03FF0000) >> 16) != 0x132) &&
1021*af46caf0SBitterblue Smith 	    (((regeac & 0x03FF0000) >> 16) != 0x36))
1022*af46caf0SBitterblue Smith 		result |= 0x02;
1023*af46caf0SBitterblue Smith 	else
1024*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path A Rx IQK fail!!\n");
1025*af46caf0SBitterblue Smith 
1026*af46caf0SBitterblue Smith 	return result;
1027*af46caf0SBitterblue Smith }
1028*af46caf0SBitterblue Smith 
1029*af46caf0SBitterblue Smith /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
_rtl92du_phy_patha_iqk_5g_normal(struct ieee80211_hw * hw,bool configpathb)1030*af46caf0SBitterblue Smith static u8 _rtl92du_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw,
1031*af46caf0SBitterblue Smith 					   bool configpathb)
1032*af46caf0SBitterblue Smith {
1033*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1034*af46caf0SBitterblue Smith 	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1035*af46caf0SBitterblue Smith 	struct rtl_phy *rtlphy = &rtlpriv->phy;
1036*af46caf0SBitterblue Smith 	u32 TXOKBIT = BIT(28), RXOKBIT = BIT(27);
1037*af46caf0SBitterblue Smith 	u32 regeac, rege94, rege9c, regea4;
1038*af46caf0SBitterblue Smith 	u8 timeout = 20, timecount = 0;
1039*af46caf0SBitterblue Smith 	u8 retrycount = 2;
1040*af46caf0SBitterblue Smith 	u8 result = 0;
1041*af46caf0SBitterblue Smith 	u8 i;
1042*af46caf0SBitterblue Smith 
1043*af46caf0SBitterblue Smith 	if (rtlhal->interfaceindex == 1) { /* PHY1 */
1044*af46caf0SBitterblue Smith 		TXOKBIT = BIT(31);
1045*af46caf0SBitterblue Smith 		RXOKBIT = BIT(30);
1046*af46caf0SBitterblue Smith 	}
1047*af46caf0SBitterblue Smith 
1048*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path-A IQK setting!\n");
1049*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1f);
1050*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1f);
1051*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82140307);
1052*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x68160960);
1053*af46caf0SBitterblue Smith 	/* path-B IQK setting */
1054*af46caf0SBitterblue Smith 	if (configpathb) {
1055*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x18008c2f);
1056*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x18008c2f);
1057*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1058*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x68110000);
1059*af46caf0SBitterblue Smith 	}
1060*af46caf0SBitterblue Smith 
1061*af46caf0SBitterblue Smith 	/* LO calibration setting */
1062*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "LO calibration setting!\n");
1063*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911);
1064*af46caf0SBitterblue Smith 
1065*af46caf0SBitterblue Smith 	/* path-A PA on */
1066*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, MASKDWORD, 0x07000f60);
1067*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, MASKDWORD, 0x66e60e30);
1068*af46caf0SBitterblue Smith 
1069*af46caf0SBitterblue Smith 	for (i = 0; i < retrycount; i++) {
1070*af46caf0SBitterblue Smith 		/* One shot, path A LOK & IQK */
1071*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
1072*af46caf0SBitterblue Smith 			"One shot, path A LOK & IQK!\n");
1073*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1074*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1075*af46caf0SBitterblue Smith 
1076*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
1077*af46caf0SBitterblue Smith 			"Delay %d ms for One shot, path A LOK & IQK.\n",
1078*af46caf0SBitterblue Smith 			IQK_DELAY_TIME);
1079*af46caf0SBitterblue Smith 		mdelay(IQK_DELAY_TIME * 10);
1080*af46caf0SBitterblue Smith 
1081*af46caf0SBitterblue Smith 		while (timecount < timeout &&
1082*af46caf0SBitterblue Smith 		       rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, BIT(26)) == 0) {
1083*af46caf0SBitterblue Smith 			udelay(IQK_DELAY_TIME * 1000 * 2);
1084*af46caf0SBitterblue Smith 			timecount++;
1085*af46caf0SBitterblue Smith 		}
1086*af46caf0SBitterblue Smith 
1087*af46caf0SBitterblue Smith 		timecount = 0;
1088*af46caf0SBitterblue Smith 		while (timecount < timeout &&
1089*af46caf0SBitterblue Smith 		       rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASK_IQK_RESULT) == 0) {
1090*af46caf0SBitterblue Smith 			udelay(IQK_DELAY_TIME * 1000 * 2);
1091*af46caf0SBitterblue Smith 			timecount++;
1092*af46caf0SBitterblue Smith 		}
1093*af46caf0SBitterblue Smith 
1094*af46caf0SBitterblue Smith 		/* Check failed */
1095*af46caf0SBitterblue Smith 		regeac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1096*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xeac = 0x%x\n", regeac);
1097*af46caf0SBitterblue Smith 		rege94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1098*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xe94 = 0x%x\n", rege94);
1099*af46caf0SBitterblue Smith 		rege9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1100*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xe9c = 0x%x\n", rege9c);
1101*af46caf0SBitterblue Smith 		regea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD);
1102*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xea4 = 0x%x\n", regea4);
1103*af46caf0SBitterblue Smith 
1104*af46caf0SBitterblue Smith 		if (!(regeac & TXOKBIT) &&
1105*af46caf0SBitterblue Smith 		    (((rege94 & 0x03FF0000) >> 16) != 0x142)) {
1106*af46caf0SBitterblue Smith 			result |= 0x01;
1107*af46caf0SBitterblue Smith 		} else { /* if Tx not OK, ignore Rx */
1108*af46caf0SBitterblue Smith 			RTPRINT(rtlpriv, FINIT, INIT_IQK,
1109*af46caf0SBitterblue Smith 				"Path A Tx IQK fail!!\n");
1110*af46caf0SBitterblue Smith 			continue;
1111*af46caf0SBitterblue Smith 		}
1112*af46caf0SBitterblue Smith 
1113*af46caf0SBitterblue Smith 		/* if Tx is OK, check whether Rx is OK */
1114*af46caf0SBitterblue Smith 		if (!(regeac & RXOKBIT) &&
1115*af46caf0SBitterblue Smith 		    (((regea4 & 0x03FF0000) >> 16) != 0x132)) {
1116*af46caf0SBitterblue Smith 			result |= 0x02;
1117*af46caf0SBitterblue Smith 			break;
1118*af46caf0SBitterblue Smith 		}
1119*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A Rx IQK fail!!\n");
1120*af46caf0SBitterblue Smith 	}
1121*af46caf0SBitterblue Smith 
1122*af46caf0SBitterblue Smith 	/* path A PA off */
1123*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, MASKDWORD,
1124*af46caf0SBitterblue Smith 		      rtlphy->iqk_bb_backup[0]);
1125*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, MASKDWORD,
1126*af46caf0SBitterblue Smith 		      rtlphy->iqk_bb_backup[1]);
1127*af46caf0SBitterblue Smith 
1128*af46caf0SBitterblue Smith 	if (!(result & 0x01)) /* Tx IQK fail */
1129*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x19008c00);
1130*af46caf0SBitterblue Smith 
1131*af46caf0SBitterblue Smith 	if (!(result & 0x02)) { /* Rx IQK fail */
1132*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, MASKDWORD, 0x40000100);
1133*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x19008c00);
1134*af46caf0SBitterblue Smith 
1135*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
1136*af46caf0SBitterblue Smith 			"Path A Rx IQK fail!! 0xe34 = %#x\n",
1137*af46caf0SBitterblue Smith 			rtl_get_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD));
1138*af46caf0SBitterblue Smith 	}
1139*af46caf0SBitterblue Smith 
1140*af46caf0SBitterblue Smith 	return result;
1141*af46caf0SBitterblue Smith }
1142*af46caf0SBitterblue Smith 
1143*af46caf0SBitterblue Smith /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
_rtl92du_phy_pathb_iqk(struct ieee80211_hw * hw)1144*af46caf0SBitterblue Smith static u8 _rtl92du_phy_pathb_iqk(struct ieee80211_hw *hw)
1145*af46caf0SBitterblue Smith {
1146*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1147*af46caf0SBitterblue Smith 	u32 regeac, regeb4, regebc, regec4, regecc;
1148*af46caf0SBitterblue Smith 	u8 result = 0;
1149*af46caf0SBitterblue Smith 
1150*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "One shot, path B LOK & IQK!\n");
1151*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RIQK_AGC_CONT, MASKDWORD, 0x00000002);
1152*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RIQK_AGC_CONT, MASKDWORD, 0x00000000);
1153*af46caf0SBitterblue Smith 
1154*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,
1155*af46caf0SBitterblue Smith 		"Delay %d ms for One shot, path B LOK & IQK\n", IQK_DELAY_TIME);
1156*af46caf0SBitterblue Smith 	mdelay(IQK_DELAY_TIME);
1157*af46caf0SBitterblue Smith 
1158*af46caf0SBitterblue Smith 	/* Check failed */
1159*af46caf0SBitterblue Smith 	regeac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1160*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xeac = 0x%x\n", regeac);
1161*af46caf0SBitterblue Smith 	regeb4 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_B, MASKDWORD);
1162*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xeb4 = 0x%x\n", regeb4);
1163*af46caf0SBitterblue Smith 	regebc = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_B, MASKDWORD);
1164*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xebc = 0x%x\n", regebc);
1165*af46caf0SBitterblue Smith 	regec4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_B_2, MASKDWORD);
1166*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xec4 = 0x%x\n", regec4);
1167*af46caf0SBitterblue Smith 	regecc = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_B_2, MASKDWORD);
1168*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xecc = 0x%x\n", regecc);
1169*af46caf0SBitterblue Smith 
1170*af46caf0SBitterblue Smith 	if (!(regeac & BIT(31)) &&
1171*af46caf0SBitterblue Smith 	    (((regeb4 & 0x03FF0000) >> 16) != 0x142) &&
1172*af46caf0SBitterblue Smith 	    (((regebc & 0x03FF0000) >> 16) != 0x42))
1173*af46caf0SBitterblue Smith 		result |= 0x01;
1174*af46caf0SBitterblue Smith 	else
1175*af46caf0SBitterblue Smith 		return result;
1176*af46caf0SBitterblue Smith 
1177*af46caf0SBitterblue Smith 	if (!(regeac & BIT(30)) &&
1178*af46caf0SBitterblue Smith 	    (((regec4 & 0x03FF0000) >> 16) != 0x132) &&
1179*af46caf0SBitterblue Smith 	    (((regecc & 0x03FF0000) >> 16) != 0x36))
1180*af46caf0SBitterblue Smith 		result |= 0x02;
1181*af46caf0SBitterblue Smith 	else
1182*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path B Rx IQK fail!!\n");
1183*af46caf0SBitterblue Smith 
1184*af46caf0SBitterblue Smith 	return result;
1185*af46caf0SBitterblue Smith }
1186*af46caf0SBitterblue Smith 
1187*af46caf0SBitterblue Smith /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
_rtl92du_phy_pathb_iqk_5g_normal(struct ieee80211_hw * hw)1188*af46caf0SBitterblue Smith static u8 _rtl92du_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw)
1189*af46caf0SBitterblue Smith {
1190*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1191*af46caf0SBitterblue Smith 	struct rtl_phy *rtlphy = &rtlpriv->phy;
1192*af46caf0SBitterblue Smith 	u32 regeac, regeb4, regebc, regec4, regecc;
1193*af46caf0SBitterblue Smith 	u8 timeout = 20, timecount = 0;
1194*af46caf0SBitterblue Smith 	u8 retrycount = 2;
1195*af46caf0SBitterblue Smith 	u8 result = 0;
1196*af46caf0SBitterblue Smith 	u8 i;
1197*af46caf0SBitterblue Smith 
1198*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path-B IQK setting!\n");
1199*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1f);
1200*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1f);
1201*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82110000);
1202*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x68110000);
1203*af46caf0SBitterblue Smith 
1204*af46caf0SBitterblue Smith 	/* path-B IQK setting */
1205*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x18008c2f);
1206*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x18008c2f);
1207*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82140307);
1208*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x68160960);
1209*af46caf0SBitterblue Smith 
1210*af46caf0SBitterblue Smith 	/* LO calibration setting */
1211*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "LO calibration setting!\n");
1212*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911);
1213*af46caf0SBitterblue Smith 
1214*af46caf0SBitterblue Smith 	/* path-B PA on */
1215*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, MASKDWORD, 0x0f600700);
1216*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, MASKDWORD, 0x061f0d30);
1217*af46caf0SBitterblue Smith 
1218*af46caf0SBitterblue Smith 	for (i = 0; i < retrycount; i++) {
1219*af46caf0SBitterblue Smith 		/* One shot, path B LOK & IQK */
1220*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
1221*af46caf0SBitterblue Smith 			"One shot, path A LOK & IQK!\n");
1222*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000);
1223*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1224*af46caf0SBitterblue Smith 
1225*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
1226*af46caf0SBitterblue Smith 			"Delay %d ms for One shot, path B LOK & IQK.\n", 10);
1227*af46caf0SBitterblue Smith 		mdelay(IQK_DELAY_TIME * 10);
1228*af46caf0SBitterblue Smith 
1229*af46caf0SBitterblue Smith 		while (timecount < timeout &&
1230*af46caf0SBitterblue Smith 		       rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, BIT(29)) == 0) {
1231*af46caf0SBitterblue Smith 			udelay(IQK_DELAY_TIME * 1000 * 2);
1232*af46caf0SBitterblue Smith 			timecount++;
1233*af46caf0SBitterblue Smith 		}
1234*af46caf0SBitterblue Smith 
1235*af46caf0SBitterblue Smith 		timecount = 0;
1236*af46caf0SBitterblue Smith 		while (timecount < timeout &&
1237*af46caf0SBitterblue Smith 		       rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_B_2, MASK_IQK_RESULT) == 0) {
1238*af46caf0SBitterblue Smith 			udelay(IQK_DELAY_TIME * 1000 * 2);
1239*af46caf0SBitterblue Smith 			timecount++;
1240*af46caf0SBitterblue Smith 		}
1241*af46caf0SBitterblue Smith 
1242*af46caf0SBitterblue Smith 		/* Check failed */
1243*af46caf0SBitterblue Smith 		regeac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1244*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xeac = 0x%x\n", regeac);
1245*af46caf0SBitterblue Smith 		regeb4 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_B, MASKDWORD);
1246*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xeb4 = 0x%x\n", regeb4);
1247*af46caf0SBitterblue Smith 		regebc = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_B, MASKDWORD);
1248*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xebc = 0x%x\n", regebc);
1249*af46caf0SBitterblue Smith 		regec4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_B_2, MASKDWORD);
1250*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xec4 = 0x%x\n", regec4);
1251*af46caf0SBitterblue Smith 		regecc = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_B_2, MASKDWORD);
1252*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xecc = 0x%x\n", regecc);
1253*af46caf0SBitterblue Smith 
1254*af46caf0SBitterblue Smith 		if (!(regeac & BIT(31)) &&
1255*af46caf0SBitterblue Smith 		    (((regeb4 & 0x03FF0000) >> 16) != 0x142))
1256*af46caf0SBitterblue Smith 			result |= 0x01;
1257*af46caf0SBitterblue Smith 		else
1258*af46caf0SBitterblue Smith 			continue;
1259*af46caf0SBitterblue Smith 
1260*af46caf0SBitterblue Smith 		if (!(regeac & BIT(30)) &&
1261*af46caf0SBitterblue Smith 		    (((regec4 & 0x03FF0000) >> 16) != 0x132)) {
1262*af46caf0SBitterblue Smith 			result |= 0x02;
1263*af46caf0SBitterblue Smith 			break;
1264*af46caf0SBitterblue Smith 		}
1265*af46caf0SBitterblue Smith 
1266*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B Rx IQK fail!!\n");
1267*af46caf0SBitterblue Smith 	}
1268*af46caf0SBitterblue Smith 
1269*af46caf0SBitterblue Smith 	/* path B PA off */
1270*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, MASKDWORD,
1271*af46caf0SBitterblue Smith 		      rtlphy->iqk_bb_backup[0]);
1272*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, MASKDWORD,
1273*af46caf0SBitterblue Smith 		      rtlphy->iqk_bb_backup[2]);
1274*af46caf0SBitterblue Smith 
1275*af46caf0SBitterblue Smith 	if (!(result & 0x01))
1276*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x19008c00);
1277*af46caf0SBitterblue Smith 
1278*af46caf0SBitterblue Smith 	if (!(result & 0x02)) {
1279*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, MASKDWORD, 0x40000100);
1280*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x19008c00);
1281*af46caf0SBitterblue Smith 
1282*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
1283*af46caf0SBitterblue Smith 			"Path B Rx IQK fail!! 0xe54 = %#x\n",
1284*af46caf0SBitterblue Smith 			rtl_get_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD));
1285*af46caf0SBitterblue Smith 	}
1286*af46caf0SBitterblue Smith 
1287*af46caf0SBitterblue Smith 	return result;
1288*af46caf0SBitterblue Smith }
1289*af46caf0SBitterblue Smith 
_rtl92du_phy_reload_adda_registers(struct ieee80211_hw * hw,const u32 * adda_reg,u32 * adda_backup,u32 regnum)1290*af46caf0SBitterblue Smith static void _rtl92du_phy_reload_adda_registers(struct ieee80211_hw *hw,
1291*af46caf0SBitterblue Smith 					       const u32 *adda_reg,
1292*af46caf0SBitterblue Smith 					       u32 *adda_backup, u32 regnum)
1293*af46caf0SBitterblue Smith {
1294*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1295*af46caf0SBitterblue Smith 	u32 i;
1296*af46caf0SBitterblue Smith 
1297*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,
1298*af46caf0SBitterblue Smith 		"Reload ADDA power saving parameters !\n");
1299*af46caf0SBitterblue Smith 	for (i = 0; i < regnum; i++) {
1300*af46caf0SBitterblue Smith 		/* path-A/B BB to initial gain */
1301*af46caf0SBitterblue Smith 		if (adda_reg[i] == ROFDM0_XAAGCCORE1 ||
1302*af46caf0SBitterblue Smith 		    adda_reg[i] == ROFDM0_XBAGCCORE1)
1303*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, adda_reg[i], MASKDWORD, 0x50);
1304*af46caf0SBitterblue Smith 
1305*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, adda_reg[i], MASKDWORD, adda_backup[i]);
1306*af46caf0SBitterblue Smith 	}
1307*af46caf0SBitterblue Smith }
1308*af46caf0SBitterblue Smith 
_rtl92du_phy_reload_mac_registers(struct ieee80211_hw * hw,const u32 * macreg,u32 * macbackup)1309*af46caf0SBitterblue Smith static void _rtl92du_phy_reload_mac_registers(struct ieee80211_hw *hw,
1310*af46caf0SBitterblue Smith 					      const u32 *macreg, u32 *macbackup)
1311*af46caf0SBitterblue Smith {
1312*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1313*af46caf0SBitterblue Smith 	u32 i;
1314*af46caf0SBitterblue Smith 
1315*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK, "Reload MAC parameters !\n");
1316*af46caf0SBitterblue Smith 	for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
1317*af46caf0SBitterblue Smith 		rtl_write_byte(rtlpriv, macreg[i], (u8)macbackup[i]);
1318*af46caf0SBitterblue Smith 	rtl_write_dword(rtlpriv, macreg[i], macbackup[i]);
1319*af46caf0SBitterblue Smith }
1320*af46caf0SBitterblue Smith 
_rtl92du_phy_patha_standby(struct ieee80211_hw * hw)1321*af46caf0SBitterblue Smith static void _rtl92du_phy_patha_standby(struct ieee80211_hw *hw)
1322*af46caf0SBitterblue Smith {
1323*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1324*af46caf0SBitterblue Smith 
1325*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A standby mode!\n");
1326*af46caf0SBitterblue Smith 
1327*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RFPGA0_IQK, MASKH3BYTES, 0x0);
1328*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RFPGA0_XA_LSSIPARAMETER, MASKDWORD, 0x00010000);
1329*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RFPGA0_IQK, MASKH3BYTES, 0x808000);
1330*af46caf0SBitterblue Smith }
1331*af46caf0SBitterblue Smith 
_rtl92du_phy_pimode_switch(struct ieee80211_hw * hw,bool pi_mode)1332*af46caf0SBitterblue Smith static void _rtl92du_phy_pimode_switch(struct ieee80211_hw *hw, bool pi_mode)
1333*af46caf0SBitterblue Smith {
1334*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1335*af46caf0SBitterblue Smith 	u32 mode;
1336*af46caf0SBitterblue Smith 
1337*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,
1338*af46caf0SBitterblue Smith 		"BB Switch to %s mode!\n", pi_mode ? "PI" : "SI");
1339*af46caf0SBitterblue Smith 	mode = pi_mode ? 0x01000100 : 0x01000000;
1340*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, MASKDWORD, mode);
1341*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, MASKDWORD, mode);
1342*af46caf0SBitterblue Smith }
1343*af46caf0SBitterblue Smith 
_rtl92du_phy_iq_calibrate(struct ieee80211_hw * hw,long result[][8],u8 t,bool is2t)1344*af46caf0SBitterblue Smith static void _rtl92du_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],
1345*af46caf0SBitterblue Smith 				      u8 t, bool is2t)
1346*af46caf0SBitterblue Smith {
1347*af46caf0SBitterblue Smith 	static const u32 adda_reg[IQK_ADDA_REG_NUM] = {
1348*af46caf0SBitterblue Smith 		RFPGA0_XCD_SWITCHCONTROL, RBLUE_TOOTH, RRX_WAIT_CCA,
1349*af46caf0SBitterblue Smith 		RTX_CCK_RFON, RTX_CCK_BBON, RTX_OFDM_RFON, RTX_OFDM_BBON,
1350*af46caf0SBitterblue Smith 		RTX_TO_RX, RTX_TO_TX, RRX_CCK, RRX_OFDM, RRX_WAIT_RIFS,
1351*af46caf0SBitterblue Smith 		RRX_TO_RX, RSTANDBY, RSLEEP, RPMPD_ANAEN
1352*af46caf0SBitterblue Smith 	};
1353*af46caf0SBitterblue Smith 	static const u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
1354*af46caf0SBitterblue Smith 		REG_TXPAUSE, REG_BCN_CTRL, REG_BCN_CTRL_1, REG_GPIO_MUXCFG
1355*af46caf0SBitterblue Smith 	};
1356*af46caf0SBitterblue Smith 	static const u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
1357*af46caf0SBitterblue Smith 		RFPGA0_XAB_RFINTERFACESW, RFPGA0_XA_RFINTERFACEOE,
1358*af46caf0SBitterblue Smith 		RFPGA0_XB_RFINTERFACEOE, ROFDM0_TRMUXPAR,
1359*af46caf0SBitterblue Smith 		RFPGA0_XCD_RFINTERFACESW, ROFDM0_TRXPATHENABLE,
1360*af46caf0SBitterblue Smith 		RFPGA0_RFMOD, RFPGA0_ANALOGPARAMETER4,
1361*af46caf0SBitterblue Smith 		ROFDM0_XAAGCCORE1, ROFDM0_XBAGCCORE1
1362*af46caf0SBitterblue Smith 	};
1363*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1364*af46caf0SBitterblue Smith 	struct rtl_phy *rtlphy = &rtlpriv->phy;
1365*af46caf0SBitterblue Smith 	const u32 retrycount = 2;
1366*af46caf0SBitterblue Smith 	u8 patha_ok, pathb_ok;
1367*af46caf0SBitterblue Smith 	u32 bbvalue;
1368*af46caf0SBitterblue Smith 	u32 i;
1369*af46caf0SBitterblue Smith 
1370*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "IQK for 2.4G :Start!!!\n");
1371*af46caf0SBitterblue Smith 	if (t == 0) {
1372*af46caf0SBitterblue Smith 		bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, MASKDWORD);
1373*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "==>0x%08x\n", bbvalue);
1374*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQ Calibration for %s\n",
1375*af46caf0SBitterblue Smith 			is2t ? "2T2R" : "1T1R");
1376*af46caf0SBitterblue Smith 
1377*af46caf0SBitterblue Smith 		/*  Save ADDA parameters, turn Path A ADDA on */
1378*af46caf0SBitterblue Smith 		rtl92d_phy_save_adda_registers(hw, adda_reg,
1379*af46caf0SBitterblue Smith 					       rtlphy->adda_backup,
1380*af46caf0SBitterblue Smith 					       IQK_ADDA_REG_NUM);
1381*af46caf0SBitterblue Smith 		rtl92d_phy_save_mac_registers(hw, iqk_mac_reg,
1382*af46caf0SBitterblue Smith 					      rtlphy->iqk_mac_backup);
1383*af46caf0SBitterblue Smith 		rtl92d_phy_save_adda_registers(hw, iqk_bb_reg,
1384*af46caf0SBitterblue Smith 					       rtlphy->iqk_bb_backup,
1385*af46caf0SBitterblue Smith 					       IQK_BB_REG_NUM);
1386*af46caf0SBitterblue Smith 	}
1387*af46caf0SBitterblue Smith 	rtl92d_phy_path_adda_on(hw, adda_reg, true, is2t);
1388*af46caf0SBitterblue Smith 
1389*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RPDP_ANTA, MASKDWORD, 0x01017038);
1390*af46caf0SBitterblue Smith 
1391*af46caf0SBitterblue Smith 	if (t == 0)
1392*af46caf0SBitterblue Smith 		rtlphy->rfpi_enable = (u8)rtl_get_bbreg(hw,
1393*af46caf0SBitterblue Smith 				RFPGA0_XA_HSSIPARAMETER1, BIT(8));
1394*af46caf0SBitterblue Smith 
1395*af46caf0SBitterblue Smith 	/*  Switch BB to PI mode to do IQ Calibration. */
1396*af46caf0SBitterblue Smith 	if (!rtlphy->rfpi_enable)
1397*af46caf0SBitterblue Smith 		_rtl92du_phy_pimode_switch(hw, true);
1398*af46caf0SBitterblue Smith 
1399*af46caf0SBitterblue Smith 	rtl92du_phy_set_bb_reg_1byte(hw, RFPGA0_RFMOD, BCCKEN, 0x00);
1400*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKDWORD, 0x03a05600);
1401*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, ROFDM0_TRMUXPAR, MASKDWORD, 0x000800e4);
1402*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, MASKDWORD, 0x22204000);
1403*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xf00000, 0x0f);
1404*af46caf0SBitterblue Smith 	if (is2t) {
1405*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RFPGA0_XA_LSSIPARAMETER, MASKDWORD,
1406*af46caf0SBitterblue Smith 			      0x00010000);
1407*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RFPGA0_XB_LSSIPARAMETER, MASKDWORD,
1408*af46caf0SBitterblue Smith 			      0x00010000);
1409*af46caf0SBitterblue Smith 	}
1410*af46caf0SBitterblue Smith 
1411*af46caf0SBitterblue Smith 	/* MAC settings */
1412*af46caf0SBitterblue Smith 	rtl92d_phy_mac_setting_calibration(hw, iqk_mac_reg,
1413*af46caf0SBitterblue Smith 					   rtlphy->iqk_mac_backup);
1414*af46caf0SBitterblue Smith 
1415*af46caf0SBitterblue Smith 	/* Page B init */
1416*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RCONFIG_ANTA, MASKDWORD, 0x0f600000);
1417*af46caf0SBitterblue Smith 	if (is2t)
1418*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RCONFIG_ANTB, MASKDWORD, 0x0f600000);
1419*af46caf0SBitterblue Smith 
1420*af46caf0SBitterblue Smith 	/* IQ calibration setting */
1421*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "IQK setting!\n");
1422*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RFPGA0_IQK, MASKH3BYTES, 0x808000);
1423*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1424*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1425*af46caf0SBitterblue Smith 
1426*af46caf0SBitterblue Smith 	for (i = 0; i < retrycount; i++) {
1427*af46caf0SBitterblue Smith 		patha_ok = _rtl92du_phy_patha_iqk(hw, is2t);
1428*af46caf0SBitterblue Smith 		if (patha_ok == 0x03) {
1429*af46caf0SBitterblue Smith 			RTPRINT(rtlpriv, FINIT, INIT_IQK,
1430*af46caf0SBitterblue Smith 				"Path A IQK Success!!\n");
1431*af46caf0SBitterblue Smith 			result[t][0] = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A,
1432*af46caf0SBitterblue Smith 						     MASK_IQK_RESULT);
1433*af46caf0SBitterblue Smith 			result[t][1] = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A,
1434*af46caf0SBitterblue Smith 						     MASK_IQK_RESULT);
1435*af46caf0SBitterblue Smith 			result[t][2] = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2,
1436*af46caf0SBitterblue Smith 						     MASK_IQK_RESULT);
1437*af46caf0SBitterblue Smith 			result[t][3] = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2,
1438*af46caf0SBitterblue Smith 						     MASK_IQK_RESULT);
1439*af46caf0SBitterblue Smith 			break;
1440*af46caf0SBitterblue Smith 		} else if (i == (retrycount - 1) && patha_ok == 0x01) {
1441*af46caf0SBitterblue Smith 			/* Tx IQK OK */
1442*af46caf0SBitterblue Smith 			RTPRINT(rtlpriv, FINIT, INIT_IQK,
1443*af46caf0SBitterblue Smith 				"Path A IQK Only  Tx Success!!\n");
1444*af46caf0SBitterblue Smith 
1445*af46caf0SBitterblue Smith 			result[t][0] = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A,
1446*af46caf0SBitterblue Smith 						     MASK_IQK_RESULT);
1447*af46caf0SBitterblue Smith 			result[t][1] = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A,
1448*af46caf0SBitterblue Smith 						     MASK_IQK_RESULT);
1449*af46caf0SBitterblue Smith 		}
1450*af46caf0SBitterblue Smith 	}
1451*af46caf0SBitterblue Smith 	if (patha_ok == 0x00)
1452*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK failed!!\n");
1453*af46caf0SBitterblue Smith 
1454*af46caf0SBitterblue Smith 	if (is2t) {
1455*af46caf0SBitterblue Smith 		_rtl92du_phy_patha_standby(hw);
1456*af46caf0SBitterblue Smith 		/* Turn Path B ADDA on */
1457*af46caf0SBitterblue Smith 		rtl92d_phy_path_adda_on(hw, adda_reg, false, is2t);
1458*af46caf0SBitterblue Smith 
1459*af46caf0SBitterblue Smith 		for (i = 0; i < retrycount; i++) {
1460*af46caf0SBitterblue Smith 			pathb_ok = _rtl92du_phy_pathb_iqk(hw);
1461*af46caf0SBitterblue Smith 			if (pathb_ok == 0x03) {
1462*af46caf0SBitterblue Smith 				RTPRINT(rtlpriv, FINIT, INIT_IQK,
1463*af46caf0SBitterblue Smith 					"Path B IQK Success!!\n");
1464*af46caf0SBitterblue Smith 				result[t][4] = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_B,
1465*af46caf0SBitterblue Smith 							     MASK_IQK_RESULT);
1466*af46caf0SBitterblue Smith 				result[t][5] = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_B,
1467*af46caf0SBitterblue Smith 							     MASK_IQK_RESULT);
1468*af46caf0SBitterblue Smith 				result[t][6] = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_B_2,
1469*af46caf0SBitterblue Smith 							     MASK_IQK_RESULT);
1470*af46caf0SBitterblue Smith 				result[t][7] = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_B_2,
1471*af46caf0SBitterblue Smith 							     MASK_IQK_RESULT);
1472*af46caf0SBitterblue Smith 				break;
1473*af46caf0SBitterblue Smith 			} else if (i == (retrycount - 1) && pathb_ok == 0x01) {
1474*af46caf0SBitterblue Smith 				/* Tx IQK OK */
1475*af46caf0SBitterblue Smith 				RTPRINT(rtlpriv, FINIT, INIT_IQK,
1476*af46caf0SBitterblue Smith 					"Path B Only Tx IQK Success!!\n");
1477*af46caf0SBitterblue Smith 				result[t][4] = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_B,
1478*af46caf0SBitterblue Smith 							     MASK_IQK_RESULT);
1479*af46caf0SBitterblue Smith 				result[t][5] = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_B,
1480*af46caf0SBitterblue Smith 							     MASK_IQK_RESULT);
1481*af46caf0SBitterblue Smith 			}
1482*af46caf0SBitterblue Smith 		}
1483*af46caf0SBitterblue Smith 		if (pathb_ok == 0x00)
1484*af46caf0SBitterblue Smith 			RTPRINT(rtlpriv, FINIT, INIT_IQK,
1485*af46caf0SBitterblue Smith 				"Path B IQK failed!!\n");
1486*af46caf0SBitterblue Smith 	}
1487*af46caf0SBitterblue Smith 
1488*af46caf0SBitterblue Smith 	/* Back to BB mode, load original value */
1489*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,
1490*af46caf0SBitterblue Smith 		"IQK:Back to BB mode, load original value!\n");
1491*af46caf0SBitterblue Smith 
1492*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RFPGA0_IQK, MASKH3BYTES, 0x000000);
1493*af46caf0SBitterblue Smith 
1494*af46caf0SBitterblue Smith 	if (t != 0) {
1495*af46caf0SBitterblue Smith 		/* Switch back BB to SI mode after finish IQ Calibration. */
1496*af46caf0SBitterblue Smith 		if (!rtlphy->rfpi_enable)
1497*af46caf0SBitterblue Smith 			_rtl92du_phy_pimode_switch(hw, false);
1498*af46caf0SBitterblue Smith 
1499*af46caf0SBitterblue Smith 		/* Reload ADDA power saving parameters */
1500*af46caf0SBitterblue Smith 		_rtl92du_phy_reload_adda_registers(hw, adda_reg,
1501*af46caf0SBitterblue Smith 						   rtlphy->adda_backup,
1502*af46caf0SBitterblue Smith 						   IQK_ADDA_REG_NUM);
1503*af46caf0SBitterblue Smith 
1504*af46caf0SBitterblue Smith 		/* Reload MAC parameters */
1505*af46caf0SBitterblue Smith 		_rtl92du_phy_reload_mac_registers(hw, iqk_mac_reg,
1506*af46caf0SBitterblue Smith 						  rtlphy->iqk_mac_backup);
1507*af46caf0SBitterblue Smith 
1508*af46caf0SBitterblue Smith 		if (is2t)
1509*af46caf0SBitterblue Smith 			_rtl92du_phy_reload_adda_registers(hw, iqk_bb_reg,
1510*af46caf0SBitterblue Smith 							   rtlphy->iqk_bb_backup,
1511*af46caf0SBitterblue Smith 							   IQK_BB_REG_NUM);
1512*af46caf0SBitterblue Smith 		else
1513*af46caf0SBitterblue Smith 			_rtl92du_phy_reload_adda_registers(hw, iqk_bb_reg,
1514*af46caf0SBitterblue Smith 							   rtlphy->iqk_bb_backup,
1515*af46caf0SBitterblue Smith 							   IQK_BB_REG_NUM - 1);
1516*af46caf0SBitterblue Smith 
1517*af46caf0SBitterblue Smith 		/* load 0xe30 IQC default value */
1518*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x01008c00);
1519*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x01008c00);
1520*af46caf0SBitterblue Smith 	}
1521*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "<==\n");
1522*af46caf0SBitterblue Smith }
1523*af46caf0SBitterblue Smith 
_rtl92du_phy_iq_calibrate_5g_normal(struct ieee80211_hw * hw,long result[][8],u8 t)1524*af46caf0SBitterblue Smith static void _rtl92du_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw,
1525*af46caf0SBitterblue Smith 						long result[][8], u8 t)
1526*af46caf0SBitterblue Smith {
1527*af46caf0SBitterblue Smith 	static const u32 adda_reg[IQK_ADDA_REG_NUM] = {
1528*af46caf0SBitterblue Smith 		RFPGA0_XCD_SWITCHCONTROL, RBLUE_TOOTH, RRX_WAIT_CCA,
1529*af46caf0SBitterblue Smith 		RTX_CCK_RFON, RTX_CCK_BBON, RTX_OFDM_RFON, RTX_OFDM_BBON,
1530*af46caf0SBitterblue Smith 		RTX_TO_RX, RTX_TO_TX, RRX_CCK, RRX_OFDM, RRX_WAIT_RIFS,
1531*af46caf0SBitterblue Smith 		RRX_TO_RX, RSTANDBY, RSLEEP, RPMPD_ANAEN
1532*af46caf0SBitterblue Smith 	};
1533*af46caf0SBitterblue Smith 	static const u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
1534*af46caf0SBitterblue Smith 		REG_TXPAUSE, REG_BCN_CTRL, REG_BCN_CTRL_1, REG_GPIO_MUXCFG
1535*af46caf0SBitterblue Smith 	};
1536*af46caf0SBitterblue Smith 	static const u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
1537*af46caf0SBitterblue Smith 		RFPGA0_XAB_RFINTERFACESW, RFPGA0_XA_RFINTERFACEOE,
1538*af46caf0SBitterblue Smith 		RFPGA0_XB_RFINTERFACEOE, ROFDM0_TRMUXPAR,
1539*af46caf0SBitterblue Smith 		RFPGA0_XCD_RFINTERFACESW, ROFDM0_TRXPATHENABLE,
1540*af46caf0SBitterblue Smith 		RFPGA0_RFMOD, RFPGA0_ANALOGPARAMETER4,
1541*af46caf0SBitterblue Smith 		ROFDM0_XAAGCCORE1, ROFDM0_XBAGCCORE1
1542*af46caf0SBitterblue Smith 	};
1543*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1544*af46caf0SBitterblue Smith 	struct rtl_phy *rtlphy = &rtlpriv->phy;
1545*af46caf0SBitterblue Smith 	struct rtl_hal *rtlhal = &rtlpriv->rtlhal;
1546*af46caf0SBitterblue Smith 	bool is2t = IS_92D_SINGLEPHY(rtlhal->version);
1547*af46caf0SBitterblue Smith 	u8 patha_ok, pathb_ok;
1548*af46caf0SBitterblue Smith 	bool rf_path_div;
1549*af46caf0SBitterblue Smith 	u32 bbvalue;
1550*af46caf0SBitterblue Smith 
1551*af46caf0SBitterblue Smith 	/* Note: IQ calibration must be performed after loading
1552*af46caf0SBitterblue Smith 	 * PHY_REG.txt , and radio_a, radio_b.txt
1553*af46caf0SBitterblue Smith 	 */
1554*af46caf0SBitterblue Smith 
1555*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "IQK for 5G NORMAL:Start!!!\n");
1556*af46caf0SBitterblue Smith 
1557*af46caf0SBitterblue Smith 	mdelay(IQK_DELAY_TIME * 20);
1558*af46caf0SBitterblue Smith 
1559*af46caf0SBitterblue Smith 	if (t == 0) {
1560*af46caf0SBitterblue Smith 		bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, MASKDWORD);
1561*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "==>0x%08x\n", bbvalue);
1562*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQ Calibration for %s\n",
1563*af46caf0SBitterblue Smith 			is2t ? "2T2R" : "1T1R");
1564*af46caf0SBitterblue Smith 
1565*af46caf0SBitterblue Smith 		/* Save ADDA parameters, turn Path A ADDA on */
1566*af46caf0SBitterblue Smith 		rtl92d_phy_save_adda_registers(hw, adda_reg,
1567*af46caf0SBitterblue Smith 					       rtlphy->adda_backup,
1568*af46caf0SBitterblue Smith 					       IQK_ADDA_REG_NUM);
1569*af46caf0SBitterblue Smith 		rtl92d_phy_save_mac_registers(hw, iqk_mac_reg,
1570*af46caf0SBitterblue Smith 					      rtlphy->iqk_mac_backup);
1571*af46caf0SBitterblue Smith 		if (is2t)
1572*af46caf0SBitterblue Smith 			rtl92d_phy_save_adda_registers(hw, iqk_bb_reg,
1573*af46caf0SBitterblue Smith 						       rtlphy->iqk_bb_backup,
1574*af46caf0SBitterblue Smith 						       IQK_BB_REG_NUM);
1575*af46caf0SBitterblue Smith 		else
1576*af46caf0SBitterblue Smith 			rtl92d_phy_save_adda_registers(hw, iqk_bb_reg,
1577*af46caf0SBitterblue Smith 						       rtlphy->iqk_bb_backup,
1578*af46caf0SBitterblue Smith 						       IQK_BB_REG_NUM - 1);
1579*af46caf0SBitterblue Smith 	}
1580*af46caf0SBitterblue Smith 
1581*af46caf0SBitterblue Smith 	rf_path_div = rtl_get_bbreg(hw, 0xb30, BIT(27));
1582*af46caf0SBitterblue Smith 	rtl92d_phy_path_adda_on(hw, adda_reg, !rf_path_div, is2t);
1583*af46caf0SBitterblue Smith 
1584*af46caf0SBitterblue Smith 	if (t == 0)
1585*af46caf0SBitterblue Smith 		rtlphy->rfpi_enable = rtl_get_bbreg(hw,
1586*af46caf0SBitterblue Smith 						    RFPGA0_XA_HSSIPARAMETER1,
1587*af46caf0SBitterblue Smith 						    BIT(8));
1588*af46caf0SBitterblue Smith 
1589*af46caf0SBitterblue Smith 	/*  Switch BB to PI mode to do IQ Calibration. */
1590*af46caf0SBitterblue Smith 	if (!rtlphy->rfpi_enable)
1591*af46caf0SBitterblue Smith 		_rtl92du_phy_pimode_switch(hw, true);
1592*af46caf0SBitterblue Smith 
1593*af46caf0SBitterblue Smith 	/* MAC settings */
1594*af46caf0SBitterblue Smith 	rtl92d_phy_mac_setting_calibration(hw, iqk_mac_reg,
1595*af46caf0SBitterblue Smith 					   rtlphy->iqk_mac_backup);
1596*af46caf0SBitterblue Smith 
1597*af46caf0SBitterblue Smith 	rtl92du_phy_set_bb_reg_1byte(hw, RFPGA0_RFMOD, BCCKEN, 0x00);
1598*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKDWORD, 0x03a05600);
1599*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, ROFDM0_TRMUXPAR, MASKDWORD, 0x000800e4);
1600*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, MASKDWORD, 0x22208000);
1601*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xf00000, 0x0f);
1602*af46caf0SBitterblue Smith 
1603*af46caf0SBitterblue Smith 	/* Page A AP setting for IQK */
1604*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RPDP_ANTA, MASKDWORD, 0);
1605*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RCONFIG_ANTA, MASKDWORD, 0x20000000);
1606*af46caf0SBitterblue Smith 	if (is2t) {
1607*af46caf0SBitterblue Smith 		/* Page B AP setting for IQK */
1608*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RPDP_ANTB, MASKDWORD, 0);
1609*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RCONFIG_ANTB, MASKDWORD, 0x20000000);
1610*af46caf0SBitterblue Smith 	}
1611*af46caf0SBitterblue Smith 
1612*af46caf0SBitterblue Smith 	/* IQ calibration setting  */
1613*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "IQK setting!\n");
1614*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RFPGA0_IQK, MASKH3BYTES, 0x808000);
1615*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x10007c00);
1616*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1617*af46caf0SBitterblue Smith 
1618*af46caf0SBitterblue Smith 	patha_ok = _rtl92du_phy_patha_iqk_5g_normal(hw, is2t);
1619*af46caf0SBitterblue Smith 	if (patha_ok == 0x03) {
1620*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path A IQK Success!!\n");
1621*af46caf0SBitterblue Smith 		result[t][0] = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A,
1622*af46caf0SBitterblue Smith 					     MASK_IQK_RESULT);
1623*af46caf0SBitterblue Smith 		result[t][1] = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A,
1624*af46caf0SBitterblue Smith 					     MASK_IQK_RESULT);
1625*af46caf0SBitterblue Smith 		result[t][2] = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2,
1626*af46caf0SBitterblue Smith 					     MASK_IQK_RESULT);
1627*af46caf0SBitterblue Smith 		result[t][3] = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2,
1628*af46caf0SBitterblue Smith 					     MASK_IQK_RESULT);
1629*af46caf0SBitterblue Smith 	} else if (patha_ok == 0x01) {	/* Tx IQK OK */
1630*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
1631*af46caf0SBitterblue Smith 			"Path A IQK Only  Tx Success!!\n");
1632*af46caf0SBitterblue Smith 
1633*af46caf0SBitterblue Smith 		result[t][0] = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A,
1634*af46caf0SBitterblue Smith 					     MASK_IQK_RESULT);
1635*af46caf0SBitterblue Smith 		result[t][1] = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A,
1636*af46caf0SBitterblue Smith 					     MASK_IQK_RESULT);
1637*af46caf0SBitterblue Smith 	} else {
1638*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RFPGA0_IQK, MASKH3BYTES, 0x000000);
1639*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe70 = %#x\n",
1640*af46caf0SBitterblue Smith 			rtl_get_bbreg(hw, RRX_WAIT_CCA, MASKDWORD));
1641*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK, "RF path A 0x0 = %#x\n",
1642*af46caf0SBitterblue Smith 			rtl_get_rfreg(hw, RF90_PATH_A, RF_AC, RFREG_OFFSET_MASK));
1643*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RFPGA0_IQK, MASKH3BYTES, 0x808000);
1644*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path A IQK Fail!!\n");
1645*af46caf0SBitterblue Smith 	}
1646*af46caf0SBitterblue Smith 
1647*af46caf0SBitterblue Smith 	if (is2t) {
1648*af46caf0SBitterblue Smith 		/* _rtl92d_phy_patha_standby(hw); */
1649*af46caf0SBitterblue Smith 		/* Turn Path B ADDA on  */
1650*af46caf0SBitterblue Smith 		rtl92d_phy_path_adda_on(hw, adda_reg, false, is2t);
1651*af46caf0SBitterblue Smith 
1652*af46caf0SBitterblue Smith 		pathb_ok = _rtl92du_phy_pathb_iqk_5g_normal(hw);
1653*af46caf0SBitterblue Smith 		if (pathb_ok == 0x03) {
1654*af46caf0SBitterblue Smith 			RTPRINT(rtlpriv, FINIT, INIT_IQK,
1655*af46caf0SBitterblue Smith 				"Path B IQK Success!!\n");
1656*af46caf0SBitterblue Smith 			result[t][4] = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_B,
1657*af46caf0SBitterblue Smith 						     MASK_IQK_RESULT);
1658*af46caf0SBitterblue Smith 			result[t][5] = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_B,
1659*af46caf0SBitterblue Smith 						     MASK_IQK_RESULT);
1660*af46caf0SBitterblue Smith 			result[t][6] = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_B_2,
1661*af46caf0SBitterblue Smith 						     MASK_IQK_RESULT);
1662*af46caf0SBitterblue Smith 			result[t][7] = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_B_2,
1663*af46caf0SBitterblue Smith 						     MASK_IQK_RESULT);
1664*af46caf0SBitterblue Smith 		} else if (pathb_ok == 0x01) { /* Tx IQK OK */
1665*af46caf0SBitterblue Smith 			RTPRINT(rtlpriv, FINIT, INIT_IQK,
1666*af46caf0SBitterblue Smith 				"Path B Only Tx IQK Success!!\n");
1667*af46caf0SBitterblue Smith 			result[t][4] = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_B,
1668*af46caf0SBitterblue Smith 						     MASK_IQK_RESULT);
1669*af46caf0SBitterblue Smith 			result[t][5] = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_B,
1670*af46caf0SBitterblue Smith 						     MASK_IQK_RESULT);
1671*af46caf0SBitterblue Smith 		} else {
1672*af46caf0SBitterblue Smith 			RTPRINT(rtlpriv, FINIT, INIT_IQK,
1673*af46caf0SBitterblue Smith 				"Path B IQK failed!!\n");
1674*af46caf0SBitterblue Smith 		}
1675*af46caf0SBitterblue Smith 	}
1676*af46caf0SBitterblue Smith 
1677*af46caf0SBitterblue Smith 	/* Back to BB mode, load original value */
1678*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,
1679*af46caf0SBitterblue Smith 		"IQK:Back to BB mode, load original value!\n");
1680*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RFPGA0_IQK, MASKH3BYTES, 0);
1681*af46caf0SBitterblue Smith 
1682*af46caf0SBitterblue Smith 	if (is2t)
1683*af46caf0SBitterblue Smith 		_rtl92du_phy_reload_adda_registers(hw, iqk_bb_reg,
1684*af46caf0SBitterblue Smith 						   rtlphy->iqk_bb_backup,
1685*af46caf0SBitterblue Smith 						   IQK_BB_REG_NUM);
1686*af46caf0SBitterblue Smith 	else
1687*af46caf0SBitterblue Smith 		_rtl92du_phy_reload_adda_registers(hw, iqk_bb_reg,
1688*af46caf0SBitterblue Smith 						   rtlphy->iqk_bb_backup,
1689*af46caf0SBitterblue Smith 						   IQK_BB_REG_NUM - 1);
1690*af46caf0SBitterblue Smith 
1691*af46caf0SBitterblue Smith 	/* path A IQ path to DP block */
1692*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RPDP_ANTA, MASKDWORD, 0x010170b8);
1693*af46caf0SBitterblue Smith 	if (is2t) /* path B IQ path to DP block */
1694*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RPDP_ANTB, MASKDWORD, 0x010170b8);
1695*af46caf0SBitterblue Smith 
1696*af46caf0SBitterblue Smith 	/* Reload MAC parameters */
1697*af46caf0SBitterblue Smith 	_rtl92du_phy_reload_mac_registers(hw, iqk_mac_reg,
1698*af46caf0SBitterblue Smith 					  rtlphy->iqk_mac_backup);
1699*af46caf0SBitterblue Smith 
1700*af46caf0SBitterblue Smith 	/* Switch back BB to SI mode after finish IQ Calibration. */
1701*af46caf0SBitterblue Smith 	if (!rtlphy->rfpi_enable)
1702*af46caf0SBitterblue Smith 		_rtl92du_phy_pimode_switch(hw, false);
1703*af46caf0SBitterblue Smith 
1704*af46caf0SBitterblue Smith 	/* Reload ADDA power saving parameters */
1705*af46caf0SBitterblue Smith 	_rtl92du_phy_reload_adda_registers(hw, adda_reg,
1706*af46caf0SBitterblue Smith 					   rtlphy->adda_backup,
1707*af46caf0SBitterblue Smith 					   IQK_ADDA_REG_NUM);
1708*af46caf0SBitterblue Smith 
1709*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "<==\n");
1710*af46caf0SBitterblue Smith }
1711*af46caf0SBitterblue Smith 
_rtl92du_phy_simularity_compare(struct ieee80211_hw * hw,long result[][8],u8 c1,u8 c2)1712*af46caf0SBitterblue Smith static bool _rtl92du_phy_simularity_compare(struct ieee80211_hw *hw,
1713*af46caf0SBitterblue Smith 					    long result[][8], u8 c1, u8 c2)
1714*af46caf0SBitterblue Smith {
1715*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1716*af46caf0SBitterblue Smith 	struct rtl_hal *rtlhal = &rtlpriv->rtlhal;
1717*af46caf0SBitterblue Smith 	u32 i, j, diff, sim_bitmap, bound, u4temp = 0;
1718*af46caf0SBitterblue Smith 	u8 final_candidate[2] = {0xFF, 0xFF};	/* for path A and path B */
1719*af46caf0SBitterblue Smith 	bool is2t = IS_92D_SINGLEPHY(rtlhal->version);
1720*af46caf0SBitterblue Smith 	bool bresult = true;
1721*af46caf0SBitterblue Smith 
1722*af46caf0SBitterblue Smith 	if (is2t)
1723*af46caf0SBitterblue Smith 		bound = 8;
1724*af46caf0SBitterblue Smith 	else
1725*af46caf0SBitterblue Smith 		bound = 4;
1726*af46caf0SBitterblue Smith 
1727*af46caf0SBitterblue Smith 	sim_bitmap = 0;
1728*af46caf0SBitterblue Smith 
1729*af46caf0SBitterblue Smith 	for (i = 0; i < bound; i++) {
1730*af46caf0SBitterblue Smith 		diff = abs_diff(result[c1][i], result[c2][i]);
1731*af46caf0SBitterblue Smith 
1732*af46caf0SBitterblue Smith 		if (diff > MAX_TOLERANCE_92D) {
1733*af46caf0SBitterblue Smith 			if ((i == 2 || i == 6) && !sim_bitmap) {
1734*af46caf0SBitterblue Smith 				if (result[c1][i] + result[c1][i + 1] == 0)
1735*af46caf0SBitterblue Smith 					final_candidate[(i / 4)] = c2;
1736*af46caf0SBitterblue Smith 				else if (result[c2][i] + result[c2][i + 1] == 0)
1737*af46caf0SBitterblue Smith 					final_candidate[(i / 4)] = c1;
1738*af46caf0SBitterblue Smith 				else
1739*af46caf0SBitterblue Smith 					sim_bitmap = sim_bitmap | (1 << i);
1740*af46caf0SBitterblue Smith 			} else {
1741*af46caf0SBitterblue Smith 				sim_bitmap = sim_bitmap | (1 << i);
1742*af46caf0SBitterblue Smith 			}
1743*af46caf0SBitterblue Smith 		}
1744*af46caf0SBitterblue Smith 	}
1745*af46caf0SBitterblue Smith 
1746*af46caf0SBitterblue Smith 	if (sim_bitmap == 0) {
1747*af46caf0SBitterblue Smith 		for (i = 0; i < (bound / 4); i++) {
1748*af46caf0SBitterblue Smith 			if (final_candidate[i] != 0xFF) {
1749*af46caf0SBitterblue Smith 				for (j = i * 4; j < (i + 1) * 4 - 2; j++)
1750*af46caf0SBitterblue Smith 					result[3][j] =
1751*af46caf0SBitterblue Smith 						 result[final_candidate[i]][j];
1752*af46caf0SBitterblue Smith 				bresult = false;
1753*af46caf0SBitterblue Smith 			}
1754*af46caf0SBitterblue Smith 		}
1755*af46caf0SBitterblue Smith 
1756*af46caf0SBitterblue Smith 		for (i = 0; i < bound; i++)
1757*af46caf0SBitterblue Smith 			u4temp += result[c1][i] + result[c2][i];
1758*af46caf0SBitterblue Smith 
1759*af46caf0SBitterblue Smith 		if (u4temp == 0) /* IQK fail for c1 & c2 */
1760*af46caf0SBitterblue Smith 			bresult = false;
1761*af46caf0SBitterblue Smith 
1762*af46caf0SBitterblue Smith 		return bresult;
1763*af46caf0SBitterblue Smith 	}
1764*af46caf0SBitterblue Smith 
1765*af46caf0SBitterblue Smith 	if (!(sim_bitmap & 0x0F)) { /* path A OK */
1766*af46caf0SBitterblue Smith 		for (i = 0; i < 4; i++)
1767*af46caf0SBitterblue Smith 			result[3][i] = result[c1][i];
1768*af46caf0SBitterblue Smith 	} else if (!(sim_bitmap & 0x03)) { /* path A, Tx OK */
1769*af46caf0SBitterblue Smith 		for (i = 0; i < 2; i++)
1770*af46caf0SBitterblue Smith 			result[3][i] = result[c1][i];
1771*af46caf0SBitterblue Smith 	}
1772*af46caf0SBitterblue Smith 
1773*af46caf0SBitterblue Smith 	if (!(sim_bitmap & 0xF0) && is2t) { /* path B OK */
1774*af46caf0SBitterblue Smith 		for (i = 4; i < 8; i++)
1775*af46caf0SBitterblue Smith 			result[3][i] = result[c1][i];
1776*af46caf0SBitterblue Smith 	} else if (!(sim_bitmap & 0x30)) { /* path B, Tx OK */
1777*af46caf0SBitterblue Smith 		for (i = 4; i < 6; i++)
1778*af46caf0SBitterblue Smith 			result[3][i] = result[c1][i];
1779*af46caf0SBitterblue Smith 	}
1780*af46caf0SBitterblue Smith 
1781*af46caf0SBitterblue Smith 	return false;
1782*af46caf0SBitterblue Smith }
1783*af46caf0SBitterblue Smith 
_rtl92du_phy_patha_fill_iqk_matrix_5g_normal(struct ieee80211_hw * hw,bool iqk_ok,long result[][8],u8 final_candidate,bool txonly)1784*af46caf0SBitterblue Smith static void _rtl92du_phy_patha_fill_iqk_matrix_5g_normal(struct ieee80211_hw *hw,
1785*af46caf0SBitterblue Smith 							 bool iqk_ok,
1786*af46caf0SBitterblue Smith 							 long result[][8],
1787*af46caf0SBitterblue Smith 							 u8 final_candidate,
1788*af46caf0SBitterblue Smith 							 bool txonly)
1789*af46caf0SBitterblue Smith {
1790*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1791*af46caf0SBitterblue Smith 	struct rtl_hal *rtlhal = &rtlpriv->rtlhal;
1792*af46caf0SBitterblue Smith 	u32 val_x, reg;
1793*af46caf0SBitterblue Smith 	int val_y;
1794*af46caf0SBitterblue Smith 
1795*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,
1796*af46caf0SBitterblue Smith 		"Path A IQ Calibration %s !\n", iqk_ok ? "Success" : "Failed");
1797*af46caf0SBitterblue Smith 	if (iqk_ok && final_candidate != 0xFF) {
1798*af46caf0SBitterblue Smith 		val_x = result[final_candidate][0];
1799*af46caf0SBitterblue Smith 		if ((val_x & 0x00000200) != 0)
1800*af46caf0SBitterblue Smith 			val_x = val_x | 0xFFFFFC00;
1801*af46caf0SBitterblue Smith 
1802*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK, "X = 0x%x\n", val_x);
1803*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RTX_IQK_TONE_A, 0x3FF0000, val_x);
1804*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24), 0);
1805*af46caf0SBitterblue Smith 
1806*af46caf0SBitterblue Smith 		val_y = result[final_candidate][1];
1807*af46caf0SBitterblue Smith 		if ((val_y & 0x00000200) != 0)
1808*af46caf0SBitterblue Smith 			val_y = val_y | 0xFFFFFC00;
1809*af46caf0SBitterblue Smith 
1810*af46caf0SBitterblue Smith 		/* path B IQK result + 3 */
1811*af46caf0SBitterblue Smith 		if (rtlhal->current_bandtype == BAND_ON_5G)
1812*af46caf0SBitterblue Smith 			val_y += 3;
1813*af46caf0SBitterblue Smith 
1814*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK, "Y = 0x%x\n", val_y);
1815*af46caf0SBitterblue Smith 
1816*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RTX_IQK_TONE_A, 0x3FF, val_y);
1817*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(26), 0);
1818*af46caf0SBitterblue Smith 
1819*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe30 = 0x%x\n",
1820*af46caf0SBitterblue Smith 			rtl_get_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD));
1821*af46caf0SBitterblue Smith 
1822*af46caf0SBitterblue Smith 		if (txonly) {
1823*af46caf0SBitterblue Smith 			RTPRINT(rtlpriv, FINIT, INIT_IQK, "only Tx OK\n");
1824*af46caf0SBitterblue Smith 			return;
1825*af46caf0SBitterblue Smith 		}
1826*af46caf0SBitterblue Smith 
1827*af46caf0SBitterblue Smith 		reg = result[final_candidate][2];
1828*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg);
1829*af46caf0SBitterblue Smith 		reg = result[final_candidate][3] & 0x3F;
1830*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg);
1831*af46caf0SBitterblue Smith 		reg = (result[final_candidate][3] >> 6) & 0xF;
1832*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, ROFDM0_RXIQEXTANTA, 0xF0000000, reg);
1833*af46caf0SBitterblue Smith 	} else {
1834*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
1835*af46caf0SBitterblue Smith 			"%s: Tx/Rx fail restore default value\n", __func__);
1836*af46caf0SBitterblue Smith 
1837*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x19008c00);
1838*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, MASKDWORD, 0x40000100);
1839*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x19008c00);
1840*af46caf0SBitterblue Smith 	}
1841*af46caf0SBitterblue Smith }
1842*af46caf0SBitterblue Smith 
_rtl92du_phy_patha_fill_iqk_matrix(struct ieee80211_hw * hw,bool iqk_ok,long result[][8],u8 final_candidate,bool txonly)1843*af46caf0SBitterblue Smith static void _rtl92du_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw,
1844*af46caf0SBitterblue Smith 					       bool iqk_ok, long result[][8],
1845*af46caf0SBitterblue Smith 					       u8 final_candidate, bool txonly)
1846*af46caf0SBitterblue Smith {
1847*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1848*af46caf0SBitterblue Smith 	struct rtl_hal *rtlhal = &rtlpriv->rtlhal;
1849*af46caf0SBitterblue Smith 	u32 oldval_0, val_x, tx0_a, reg;
1850*af46caf0SBitterblue Smith 	long val_y, tx0_c;
1851*af46caf0SBitterblue Smith 	bool is2t = IS_92D_SINGLEPHY(rtlhal->version) ||
1852*af46caf0SBitterblue Smith 		    rtlhal->macphymode == DUALMAC_DUALPHY;
1853*af46caf0SBitterblue Smith 
1854*af46caf0SBitterblue Smith 	if (rtlhal->current_bandtype == BAND_ON_5G) {
1855*af46caf0SBitterblue Smith 		_rtl92du_phy_patha_fill_iqk_matrix_5g_normal(hw, iqk_ok, result,
1856*af46caf0SBitterblue Smith 							     final_candidate,
1857*af46caf0SBitterblue Smith 							     txonly);
1858*af46caf0SBitterblue Smith 		return;
1859*af46caf0SBitterblue Smith 	}
1860*af46caf0SBitterblue Smith 
1861*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,
1862*af46caf0SBitterblue Smith 		"Path A IQ Calibration %s !\n", iqk_ok ? "Success" : "Failed");
1863*af46caf0SBitterblue Smith 	if (final_candidate == 0xFF || !iqk_ok)
1864*af46caf0SBitterblue Smith 		return;
1865*af46caf0SBitterblue Smith 
1866*af46caf0SBitterblue Smith 	/* OFDM0_D */
1867*af46caf0SBitterblue Smith 	oldval_0 = rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0xffc00000);
1868*af46caf0SBitterblue Smith 
1869*af46caf0SBitterblue Smith 	val_x = result[final_candidate][0];
1870*af46caf0SBitterblue Smith 	if ((val_x & 0x00000200) != 0)
1871*af46caf0SBitterblue Smith 		val_x = val_x | 0xFFFFFC00;
1872*af46caf0SBitterblue Smith 
1873*af46caf0SBitterblue Smith 	tx0_a = (val_x * oldval_0) >> 8;
1874*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,
1875*af46caf0SBitterblue Smith 		"X = 0x%x, tx0_a = 0x%x, oldval_0 0x%x\n",
1876*af46caf0SBitterblue Smith 		val_x, tx0_a, oldval_0);
1877*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a);
1878*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24),
1879*af46caf0SBitterblue Smith 		      ((val_x * oldval_0 >> 7) & 0x1));
1880*af46caf0SBitterblue Smith 
1881*af46caf0SBitterblue Smith 	val_y = result[final_candidate][1];
1882*af46caf0SBitterblue Smith 	if ((val_y & 0x00000200) != 0)
1883*af46caf0SBitterblue Smith 		val_y = val_y | 0xFFFFFC00;
1884*af46caf0SBitterblue Smith 
1885*af46caf0SBitterblue Smith 	/* path B IQK result + 3 */
1886*af46caf0SBitterblue Smith 	if (rtlhal->interfaceindex == 1 &&
1887*af46caf0SBitterblue Smith 	    rtlhal->current_bandtype == BAND_ON_5G)
1888*af46caf0SBitterblue Smith 		val_y += 3;
1889*af46caf0SBitterblue Smith 
1890*af46caf0SBitterblue Smith 	tx0_c = (val_y * oldval_0) >> 8;
1891*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,
1892*af46caf0SBitterblue Smith 		"Y = 0x%lx, tx0_c = 0x%lx\n",
1893*af46caf0SBitterblue Smith 		val_y, tx0_c);
1894*af46caf0SBitterblue Smith 
1895*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000, (tx0_c & 0x3C0) >> 6);
1896*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000, tx0_c & 0x3F);
1897*af46caf0SBitterblue Smith 	if (is2t)
1898*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(26),
1899*af46caf0SBitterblue Smith 			      (val_y * oldval_0 >> 7) & 0x1);
1900*af46caf0SBitterblue Smith 
1901*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xC80 = 0x%x\n",
1902*af46caf0SBitterblue Smith 		rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
1903*af46caf0SBitterblue Smith 			      MASKDWORD));
1904*af46caf0SBitterblue Smith 
1905*af46caf0SBitterblue Smith 	if (txonly) {
1906*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK, "only Tx OK\n");
1907*af46caf0SBitterblue Smith 		return;
1908*af46caf0SBitterblue Smith 	}
1909*af46caf0SBitterblue Smith 
1910*af46caf0SBitterblue Smith 	reg = result[final_candidate][2];
1911*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg);
1912*af46caf0SBitterblue Smith 	reg = result[final_candidate][3] & 0x3F;
1913*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg);
1914*af46caf0SBitterblue Smith 	reg = (result[final_candidate][3] >> 6) & 0xF;
1915*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, ROFDM0_RXIQEXTANTA, 0xF0000000, reg);
1916*af46caf0SBitterblue Smith }
1917*af46caf0SBitterblue Smith 
_rtl92du_phy_pathb_fill_iqk_matrix_5g_normal(struct ieee80211_hw * hw,bool iqk_ok,long result[][8],u8 final_candidate,bool txonly)1918*af46caf0SBitterblue Smith static void _rtl92du_phy_pathb_fill_iqk_matrix_5g_normal(struct ieee80211_hw *hw,
1919*af46caf0SBitterblue Smith 							 bool iqk_ok,
1920*af46caf0SBitterblue Smith 							 long result[][8],
1921*af46caf0SBitterblue Smith 							 u8 final_candidate,
1922*af46caf0SBitterblue Smith 							 bool txonly)
1923*af46caf0SBitterblue Smith {
1924*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1925*af46caf0SBitterblue Smith 	struct rtl_hal *rtlhal = &rtlpriv->rtlhal;
1926*af46caf0SBitterblue Smith 	u32 val_x, reg;
1927*af46caf0SBitterblue Smith 	int val_y;
1928*af46caf0SBitterblue Smith 
1929*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,
1930*af46caf0SBitterblue Smith 		"Path B IQ Calibration %s !\n", iqk_ok ? "Success" : "Failed");
1931*af46caf0SBitterblue Smith 	if (iqk_ok && final_candidate != 0xFF) {
1932*af46caf0SBitterblue Smith 		val_x = result[final_candidate][4];
1933*af46caf0SBitterblue Smith 		if ((val_x & 0x00000200) != 0)
1934*af46caf0SBitterblue Smith 			val_x = val_x | 0xFFFFFC00;
1935*af46caf0SBitterblue Smith 
1936*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK, "X = 0x%x\n", val_x);
1937*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RTX_IQK_TONE_B, 0x3FF0000, val_x);
1938*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(28), 0);
1939*af46caf0SBitterblue Smith 
1940*af46caf0SBitterblue Smith 		val_y = result[final_candidate][5];
1941*af46caf0SBitterblue Smith 		if ((val_y & 0x00000200) != 0)
1942*af46caf0SBitterblue Smith 			val_y = val_y | 0xFFFFFC00;
1943*af46caf0SBitterblue Smith 
1944*af46caf0SBitterblue Smith 		/* path B IQK result + 3 */
1945*af46caf0SBitterblue Smith 		if (rtlhal->current_bandtype == BAND_ON_5G)
1946*af46caf0SBitterblue Smith 			val_y += 3;
1947*af46caf0SBitterblue Smith 
1948*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK, "Y = 0x%x\n", val_y);
1949*af46caf0SBitterblue Smith 
1950*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RTX_IQK_TONE_B, 0x3FF, val_y);
1951*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(30), 0);
1952*af46caf0SBitterblue Smith 
1953*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe50 = 0x%x\n",
1954*af46caf0SBitterblue Smith 			rtl_get_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD));
1955*af46caf0SBitterblue Smith 
1956*af46caf0SBitterblue Smith 		if (txonly) {
1957*af46caf0SBitterblue Smith 			RTPRINT(rtlpriv, FINIT, INIT_IQK, "only Tx OK\n");
1958*af46caf0SBitterblue Smith 			return;
1959*af46caf0SBitterblue Smith 		}
1960*af46caf0SBitterblue Smith 
1961*af46caf0SBitterblue Smith 		reg = result[final_candidate][6];
1962*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg);
1963*af46caf0SBitterblue Smith 		reg = result[final_candidate][7] & 0x3F;
1964*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg);
1965*af46caf0SBitterblue Smith 		reg = (result[final_candidate][7] >> 6) & 0xF;
1966*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, reg);
1967*af46caf0SBitterblue Smith 	} else {
1968*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
1969*af46caf0SBitterblue Smith 			"%s: Tx/Rx fail restore default value\n", __func__);
1970*af46caf0SBitterblue Smith 
1971*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x19008c00);
1972*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, MASKDWORD, 0x40000100);
1973*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x19008c00);
1974*af46caf0SBitterblue Smith 	}
1975*af46caf0SBitterblue Smith }
1976*af46caf0SBitterblue Smith 
_rtl92du_phy_pathb_fill_iqk_matrix(struct ieee80211_hw * hw,bool iqk_ok,long result[][8],u8 final_candidate,bool txonly)1977*af46caf0SBitterblue Smith static void _rtl92du_phy_pathb_fill_iqk_matrix(struct ieee80211_hw *hw,
1978*af46caf0SBitterblue Smith 					       bool iqk_ok, long result[][8],
1979*af46caf0SBitterblue Smith 					       u8 final_candidate, bool txonly)
1980*af46caf0SBitterblue Smith {
1981*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1982*af46caf0SBitterblue Smith 	struct rtl_hal *rtlhal = &rtlpriv->rtlhal;
1983*af46caf0SBitterblue Smith 	u32 oldval_1, val_x, tx1_a, reg;
1984*af46caf0SBitterblue Smith 	long val_y, tx1_c;
1985*af46caf0SBitterblue Smith 
1986*af46caf0SBitterblue Smith 	if (rtlhal->current_bandtype == BAND_ON_5G) {
1987*af46caf0SBitterblue Smith 		_rtl92du_phy_pathb_fill_iqk_matrix_5g_normal(hw, iqk_ok, result,
1988*af46caf0SBitterblue Smith 							     final_candidate,
1989*af46caf0SBitterblue Smith 							     txonly);
1990*af46caf0SBitterblue Smith 		return;
1991*af46caf0SBitterblue Smith 	}
1992*af46caf0SBitterblue Smith 
1993*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B IQ Calibration %s !\n",
1994*af46caf0SBitterblue Smith 		iqk_ok ? "Success" : "Failed");
1995*af46caf0SBitterblue Smith 
1996*af46caf0SBitterblue Smith 	if (final_candidate == 0xFF || !iqk_ok)
1997*af46caf0SBitterblue Smith 		return;
1998*af46caf0SBitterblue Smith 
1999*af46caf0SBitterblue Smith 	oldval_1 = rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0xffc00000);
2000*af46caf0SBitterblue Smith 
2001*af46caf0SBitterblue Smith 	val_x = result[final_candidate][4];
2002*af46caf0SBitterblue Smith 	if ((val_x & 0x00000200) != 0)
2003*af46caf0SBitterblue Smith 		val_x = val_x | 0xFFFFFC00;
2004*af46caf0SBitterblue Smith 
2005*af46caf0SBitterblue Smith 	tx1_a = (val_x * oldval_1) >> 8;
2006*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK, "X = 0x%x, tx1_a = 0x%x\n",
2007*af46caf0SBitterblue Smith 		val_x, tx1_a);
2008*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a);
2009*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(28),
2010*af46caf0SBitterblue Smith 		      (val_x * oldval_1 >> 7) & 0x1);
2011*af46caf0SBitterblue Smith 
2012*af46caf0SBitterblue Smith 	val_y = result[final_candidate][5];
2013*af46caf0SBitterblue Smith 	if ((val_y & 0x00000200) != 0)
2014*af46caf0SBitterblue Smith 		val_y = val_y | 0xFFFFFC00;
2015*af46caf0SBitterblue Smith 
2016*af46caf0SBitterblue Smith 	if (rtlhal->current_bandtype == BAND_ON_5G)
2017*af46caf0SBitterblue Smith 		val_y += 3;
2018*af46caf0SBitterblue Smith 
2019*af46caf0SBitterblue Smith 	tx1_c = (val_y * oldval_1) >> 8;
2020*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK, "Y = 0x%lx, tx1_c = 0x%lx\n",
2021*af46caf0SBitterblue Smith 		val_y, tx1_c);
2022*af46caf0SBitterblue Smith 
2023*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000, (tx1_c & 0x3C0) >> 6);
2024*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000, tx1_c & 0x3F);
2025*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(30),
2026*af46caf0SBitterblue Smith 		      (val_y * oldval_1 >> 7) & 0x1);
2027*af46caf0SBitterblue Smith 
2028*af46caf0SBitterblue Smith 	if (txonly)
2029*af46caf0SBitterblue Smith 		return;
2030*af46caf0SBitterblue Smith 
2031*af46caf0SBitterblue Smith 	reg = result[final_candidate][6];
2032*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg);
2033*af46caf0SBitterblue Smith 	reg = result[final_candidate][7] & 0x3F;
2034*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg);
2035*af46caf0SBitterblue Smith 	reg = (result[final_candidate][7] >> 6) & 0xF;
2036*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, reg);
2037*af46caf0SBitterblue Smith }
2038*af46caf0SBitterblue Smith 
rtl92du_phy_iq_calibrate(struct ieee80211_hw * hw)2039*af46caf0SBitterblue Smith void rtl92du_phy_iq_calibrate(struct ieee80211_hw *hw)
2040*af46caf0SBitterblue Smith {
2041*af46caf0SBitterblue Smith 	long rege94, rege9c, regea4, regeac, regeb4;
2042*af46caf0SBitterblue Smith 	bool is12simular, is13simular, is23simular;
2043*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2044*af46caf0SBitterblue Smith 	struct rtl_hal *rtlhal = &rtlpriv->rtlhal;
2045*af46caf0SBitterblue Smith 	long regebc, regec4, regecc, regtmp = 0;
2046*af46caf0SBitterblue Smith 	struct rtl_phy *rtlphy = &rtlpriv->phy;
2047*af46caf0SBitterblue Smith 	u8 i, final_candidate, indexforchannel;
2048*af46caf0SBitterblue Smith 	bool patha_ok, pathb_ok;
2049*af46caf0SBitterblue Smith 	long result[4][8] = {};
2050*af46caf0SBitterblue Smith 
2051*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,
2052*af46caf0SBitterblue Smith 		"IQK:Start!!!channel %d\n", rtlphy->current_channel);
2053*af46caf0SBitterblue Smith 
2054*af46caf0SBitterblue Smith 	final_candidate = 0xff;
2055*af46caf0SBitterblue Smith 	patha_ok = false;
2056*af46caf0SBitterblue Smith 	pathb_ok = false;
2057*af46caf0SBitterblue Smith 	is12simular = false;
2058*af46caf0SBitterblue Smith 	is23simular = false;
2059*af46caf0SBitterblue Smith 	is13simular = false;
2060*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,
2061*af46caf0SBitterblue Smith 		"IQK !!!currentband %d\n", rtlhal->current_bandtype);
2062*af46caf0SBitterblue Smith 
2063*af46caf0SBitterblue Smith 	for (i = 0; i < 3; i++) {
2064*af46caf0SBitterblue Smith 		if (rtlhal->current_bandtype == BAND_ON_5G) {
2065*af46caf0SBitterblue Smith 			_rtl92du_phy_iq_calibrate_5g_normal(hw, result, i);
2066*af46caf0SBitterblue Smith 		} else if (rtlhal->current_bandtype == BAND_ON_2_4G) {
2067*af46caf0SBitterblue Smith 			if (IS_92D_SINGLEPHY(rtlhal->version))
2068*af46caf0SBitterblue Smith 				_rtl92du_phy_iq_calibrate(hw, result, i, true);
2069*af46caf0SBitterblue Smith 			else
2070*af46caf0SBitterblue Smith 				_rtl92du_phy_iq_calibrate(hw, result, i, false);
2071*af46caf0SBitterblue Smith 		}
2072*af46caf0SBitterblue Smith 
2073*af46caf0SBitterblue Smith 		if (i == 1) {
2074*af46caf0SBitterblue Smith 			is12simular = _rtl92du_phy_simularity_compare(hw, result,
2075*af46caf0SBitterblue Smith 								      0, 1);
2076*af46caf0SBitterblue Smith 			if (is12simular) {
2077*af46caf0SBitterblue Smith 				final_candidate = 0;
2078*af46caf0SBitterblue Smith 				break;
2079*af46caf0SBitterblue Smith 			}
2080*af46caf0SBitterblue Smith 		}
2081*af46caf0SBitterblue Smith 
2082*af46caf0SBitterblue Smith 		if (i == 2) {
2083*af46caf0SBitterblue Smith 			is13simular = _rtl92du_phy_simularity_compare(hw, result,
2084*af46caf0SBitterblue Smith 								      0, 2);
2085*af46caf0SBitterblue Smith 			if (is13simular) {
2086*af46caf0SBitterblue Smith 				final_candidate = 0;
2087*af46caf0SBitterblue Smith 				break;
2088*af46caf0SBitterblue Smith 			}
2089*af46caf0SBitterblue Smith 
2090*af46caf0SBitterblue Smith 			is23simular = _rtl92du_phy_simularity_compare(hw, result,
2091*af46caf0SBitterblue Smith 								      1, 2);
2092*af46caf0SBitterblue Smith 			if (is23simular) {
2093*af46caf0SBitterblue Smith 				final_candidate = 1;
2094*af46caf0SBitterblue Smith 			} else {
2095*af46caf0SBitterblue Smith 				for (i = 0; i < 8; i++)
2096*af46caf0SBitterblue Smith 					regtmp += result[3][i];
2097*af46caf0SBitterblue Smith 
2098*af46caf0SBitterblue Smith 				if (regtmp != 0)
2099*af46caf0SBitterblue Smith 					final_candidate = 3;
2100*af46caf0SBitterblue Smith 				else
2101*af46caf0SBitterblue Smith 					final_candidate = 0xFF;
2102*af46caf0SBitterblue Smith 			}
2103*af46caf0SBitterblue Smith 		}
2104*af46caf0SBitterblue Smith 	}
2105*af46caf0SBitterblue Smith 
2106*af46caf0SBitterblue Smith 	for (i = 0; i < 4; i++) {
2107*af46caf0SBitterblue Smith 		rege94 = result[i][0];
2108*af46caf0SBitterblue Smith 		rege9c = result[i][1];
2109*af46caf0SBitterblue Smith 		regea4 = result[i][2];
2110*af46caf0SBitterblue Smith 		regeac = result[i][3];
2111*af46caf0SBitterblue Smith 		regeb4 = result[i][4];
2112*af46caf0SBitterblue Smith 		regebc = result[i][5];
2113*af46caf0SBitterblue Smith 		regec4 = result[i][6];
2114*af46caf0SBitterblue Smith 		regecc = result[i][7];
2115*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
2116*af46caf0SBitterblue Smith 			"IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n",
2117*af46caf0SBitterblue Smith 			rege94, rege9c, regea4, regeac, regeb4, regebc, regec4,
2118*af46caf0SBitterblue Smith 			regecc);
2119*af46caf0SBitterblue Smith 	}
2120*af46caf0SBitterblue Smith 
2121*af46caf0SBitterblue Smith 	if (final_candidate != 0xff) {
2122*af46caf0SBitterblue Smith 		rege94 = result[final_candidate][0];
2123*af46caf0SBitterblue Smith 		rtlphy->reg_e94 = rege94;
2124*af46caf0SBitterblue Smith 		rege9c = result[final_candidate][1];
2125*af46caf0SBitterblue Smith 		rtlphy->reg_e9c = rege9c;
2126*af46caf0SBitterblue Smith 		regea4 = result[final_candidate][2];
2127*af46caf0SBitterblue Smith 		regeac = result[final_candidate][3];
2128*af46caf0SBitterblue Smith 		regeb4 = result[final_candidate][4];
2129*af46caf0SBitterblue Smith 		rtlphy->reg_eb4 = regeb4;
2130*af46caf0SBitterblue Smith 		regebc = result[final_candidate][5];
2131*af46caf0SBitterblue Smith 		rtlphy->reg_ebc = regebc;
2132*af46caf0SBitterblue Smith 		regec4 = result[final_candidate][6];
2133*af46caf0SBitterblue Smith 		regecc = result[final_candidate][7];
2134*af46caf0SBitterblue Smith 
2135*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
2136*af46caf0SBitterblue Smith 			"IQK: final_candidate is %x\n", final_candidate);
2137*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
2138*af46caf0SBitterblue Smith 			"IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n",
2139*af46caf0SBitterblue Smith 			rege94, rege9c, regea4, regeac, regeb4, regebc, regec4,
2140*af46caf0SBitterblue Smith 			regecc);
2141*af46caf0SBitterblue Smith 
2142*af46caf0SBitterblue Smith 		patha_ok = true;
2143*af46caf0SBitterblue Smith 		pathb_ok = true;
2144*af46caf0SBitterblue Smith 	} else {
2145*af46caf0SBitterblue Smith 		rtlphy->reg_e94 = 0x100;
2146*af46caf0SBitterblue Smith 		rtlphy->reg_eb4 = 0x100; /* X default value */
2147*af46caf0SBitterblue Smith 		rtlphy->reg_e9c = 0x0;
2148*af46caf0SBitterblue Smith 		rtlphy->reg_ebc = 0x0;   /* Y default value */
2149*af46caf0SBitterblue Smith 	}
2150*af46caf0SBitterblue Smith 	if (rege94 != 0 /*&& regea4 != 0*/)
2151*af46caf0SBitterblue Smith 		_rtl92du_phy_patha_fill_iqk_matrix(hw, patha_ok, result,
2152*af46caf0SBitterblue Smith 						   final_candidate,
2153*af46caf0SBitterblue Smith 						   regea4 == 0);
2154*af46caf0SBitterblue Smith 	if (IS_92D_SINGLEPHY(rtlhal->version) &&
2155*af46caf0SBitterblue Smith 	    regeb4 != 0 /*&& regec4 != 0*/)
2156*af46caf0SBitterblue Smith 		_rtl92du_phy_pathb_fill_iqk_matrix(hw, pathb_ok, result,
2157*af46caf0SBitterblue Smith 						   final_candidate,
2158*af46caf0SBitterblue Smith 						   regec4 == 0);
2159*af46caf0SBitterblue Smith 
2160*af46caf0SBitterblue Smith 	if (final_candidate != 0xFF) {
2161*af46caf0SBitterblue Smith 		indexforchannel =
2162*af46caf0SBitterblue Smith 			rtl92d_get_rightchnlplace_for_iqk(rtlphy->current_channel);
2163*af46caf0SBitterblue Smith 
2164*af46caf0SBitterblue Smith 		for (i = 0; i < IQK_MATRIX_REG_NUM; i++)
2165*af46caf0SBitterblue Smith 			rtlphy->iqk_matrix[indexforchannel].value[0][i] =
2166*af46caf0SBitterblue Smith 				result[final_candidate][i];
2167*af46caf0SBitterblue Smith 
2168*af46caf0SBitterblue Smith 		rtlphy->iqk_matrix[indexforchannel].iqk_done = true;
2169*af46caf0SBitterblue Smith 
2170*af46caf0SBitterblue Smith 		rtl_dbg(rtlpriv, COMP_SCAN | COMP_MLME, DBG_LOUD,
2171*af46caf0SBitterblue Smith 			"IQK OK indexforchannel %d\n", indexforchannel);
2172*af46caf0SBitterblue Smith 	}
2173*af46caf0SBitterblue Smith }
2174*af46caf0SBitterblue Smith 
rtl92du_phy_reload_iqk_setting(struct ieee80211_hw * hw,u8 channel)2175*af46caf0SBitterblue Smith void rtl92du_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel)
2176*af46caf0SBitterblue Smith {
2177*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2178*af46caf0SBitterblue Smith 	struct rtl_hal *rtlhal = &rtlpriv->rtlhal;
2179*af46caf0SBitterblue Smith 	struct rtl_phy *rtlphy = &rtlpriv->phy;
2180*af46caf0SBitterblue Smith 	struct rtl_mac *mac = rtl_mac(rtlpriv);
2181*af46caf0SBitterblue Smith 	u8 indexforchannel;
2182*af46caf0SBitterblue Smith 	bool need_iqk;
2183*af46caf0SBitterblue Smith 
2184*af46caf0SBitterblue Smith 	rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "channel %d\n", channel);
2185*af46caf0SBitterblue Smith 	/*------Do IQK for normal chip and test chip 5G band------- */
2186*af46caf0SBitterblue Smith 
2187*af46caf0SBitterblue Smith 	indexforchannel = rtl92d_get_rightchnlplace_for_iqk(channel);
2188*af46caf0SBitterblue Smith 	rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "indexforchannel %d done %d\n",
2189*af46caf0SBitterblue Smith 		indexforchannel,
2190*af46caf0SBitterblue Smith 		rtlphy->iqk_matrix[indexforchannel].iqk_done);
2191*af46caf0SBitterblue Smith 
2192*af46caf0SBitterblue Smith 	/* We need to do IQK if we're about to connect to a network on 5 GHz.
2193*af46caf0SBitterblue Smith 	 * On 5 GHz a channel switch outside of scanning happens only before
2194*af46caf0SBitterblue Smith 	 * connecting.
2195*af46caf0SBitterblue Smith 	 */
2196*af46caf0SBitterblue Smith 	need_iqk = !mac->act_scanning;
2197*af46caf0SBitterblue Smith 
2198*af46caf0SBitterblue Smith 	if (!rtlphy->iqk_matrix[indexforchannel].iqk_done && need_iqk) {
2199*af46caf0SBitterblue Smith 		rtl_dbg(rtlpriv, COMP_SCAN | COMP_INIT, DBG_LOUD,
2200*af46caf0SBitterblue Smith 			"Do IQK Matrix reg for channel:%d....\n", channel);
2201*af46caf0SBitterblue Smith 		rtl92du_phy_iq_calibrate(hw);
2202*af46caf0SBitterblue Smith 		return;
2203*af46caf0SBitterblue Smith 	}
2204*af46caf0SBitterblue Smith 
2205*af46caf0SBitterblue Smith 	/* Just load the value. */
2206*af46caf0SBitterblue Smith 	/* 2G band just load once. */
2207*af46caf0SBitterblue Smith 	if ((!rtlhal->load_imrandiqk_setting_for2g && indexforchannel == 0) ||
2208*af46caf0SBitterblue Smith 	    indexforchannel > 0) {
2209*af46caf0SBitterblue Smith 		rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD,
2210*af46caf0SBitterblue Smith 			"Just Read IQK Matrix reg for channel:%d....\n",
2211*af46caf0SBitterblue Smith 			channel);
2212*af46caf0SBitterblue Smith 
2213*af46caf0SBitterblue Smith 		if (rtlphy->iqk_matrix[indexforchannel].value[0][0] != 0)
2214*af46caf0SBitterblue Smith 			_rtl92du_phy_patha_fill_iqk_matrix(hw, true,
2215*af46caf0SBitterblue Smith 				rtlphy->iqk_matrix[indexforchannel].value, 0,
2216*af46caf0SBitterblue Smith 				rtlphy->iqk_matrix[indexforchannel].value[0][2] == 0);
2217*af46caf0SBitterblue Smith 
2218*af46caf0SBitterblue Smith 		if (IS_92D_SINGLEPHY(rtlhal->version) &&
2219*af46caf0SBitterblue Smith 		    rtlphy->iqk_matrix[indexforchannel].value[0][4] != 0)
2220*af46caf0SBitterblue Smith 			_rtl92du_phy_pathb_fill_iqk_matrix(hw, true,
2221*af46caf0SBitterblue Smith 				rtlphy->iqk_matrix[indexforchannel].value, 0,
2222*af46caf0SBitterblue Smith 				rtlphy->iqk_matrix[indexforchannel].value[0][6] == 0);
2223*af46caf0SBitterblue Smith 	}
2224*af46caf0SBitterblue Smith 	rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n");
2225*af46caf0SBitterblue Smith }
2226*af46caf0SBitterblue Smith 
_rtl92du_phy_reload_lck_setting(struct ieee80211_hw * hw,u8 channel)2227*af46caf0SBitterblue Smith static void _rtl92du_phy_reload_lck_setting(struct ieee80211_hw *hw, u8 channel)
2228*af46caf0SBitterblue Smith {
2229*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2230*af46caf0SBitterblue Smith 	struct rtl_hal *rtlhal = &rtlpriv->rtlhal;
2231*af46caf0SBitterblue Smith 	u8 erfpath = rtlhal->current_bandtype == BAND_ON_5G ? RF90_PATH_A :
2232*af46caf0SBitterblue Smith 		IS_92D_SINGLEPHY(rtlhal->version) ? RF90_PATH_B : RF90_PATH_A;
2233*af46caf0SBitterblue Smith 	bool bneed_powerdown_radio = false;
2234*af46caf0SBitterblue Smith 	u32 u4tmp, u4regvalue;
2235*af46caf0SBitterblue Smith 
2236*af46caf0SBitterblue Smith 	rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "path %d\n", erfpath);
2237*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK, "band type = %d\n",
2238*af46caf0SBitterblue Smith 		rtlpriv->rtlhal.current_bandtype);
2239*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "channel = %d\n", channel);
2240*af46caf0SBitterblue Smith 
2241*af46caf0SBitterblue Smith 	if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) {/* Path-A for 5G */
2242*af46caf0SBitterblue Smith 		u4tmp = rtlpriv->curveindex_5g[channel - 1];
2243*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
2244*af46caf0SBitterblue Smith 			"ver 1 set RF-A, 5G,	0x28 = 0x%x !!\n", u4tmp);
2245*af46caf0SBitterblue Smith 
2246*af46caf0SBitterblue Smith 		if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY &&
2247*af46caf0SBitterblue Smith 		    rtlpriv->rtlhal.interfaceindex == 1) {
2248*af46caf0SBitterblue Smith 			bneed_powerdown_radio =
2249*af46caf0SBitterblue Smith 				rtl92du_phy_enable_anotherphy(hw, false);
2250*af46caf0SBitterblue Smith 			rtlpriv->rtlhal.during_mac1init_radioa = true;
2251*af46caf0SBitterblue Smith 			/* asume no this case */
2252*af46caf0SBitterblue Smith 			if (bneed_powerdown_radio)
2253*af46caf0SBitterblue Smith 				rtl92d_phy_enable_rf_env(hw, erfpath,
2254*af46caf0SBitterblue Smith 							 &u4regvalue);
2255*af46caf0SBitterblue Smith 		}
2256*af46caf0SBitterblue Smith 
2257*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800, u4tmp);
2258*af46caf0SBitterblue Smith 
2259*af46caf0SBitterblue Smith 		if (bneed_powerdown_radio) {
2260*af46caf0SBitterblue Smith 			rtl92d_phy_restore_rf_env(hw, erfpath, &u4regvalue);
2261*af46caf0SBitterblue Smith 			rtl92du_phy_powerdown_anotherphy(hw, false);
2262*af46caf0SBitterblue Smith 		}
2263*af46caf0SBitterblue Smith 	} else if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) {
2264*af46caf0SBitterblue Smith 		u4tmp = rtlpriv->curveindex_2g[channel - 1];
2265*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
2266*af46caf0SBitterblue Smith 			"ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", u4tmp);
2267*af46caf0SBitterblue Smith 
2268*af46caf0SBitterblue Smith 		if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY &&
2269*af46caf0SBitterblue Smith 		    rtlpriv->rtlhal.interfaceindex == 0) {
2270*af46caf0SBitterblue Smith 			bneed_powerdown_radio =
2271*af46caf0SBitterblue Smith 				rtl92du_phy_enable_anotherphy(hw, true);
2272*af46caf0SBitterblue Smith 			rtlpriv->rtlhal.during_mac0init_radiob = true;
2273*af46caf0SBitterblue Smith 			if (bneed_powerdown_radio)
2274*af46caf0SBitterblue Smith 				rtl92d_phy_enable_rf_env(hw, erfpath,
2275*af46caf0SBitterblue Smith 							 &u4regvalue);
2276*af46caf0SBitterblue Smith 		}
2277*af46caf0SBitterblue Smith 
2278*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800, u4tmp);
2279*af46caf0SBitterblue Smith 
2280*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
2281*af46caf0SBitterblue Smith 			"ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n",
2282*af46caf0SBitterblue Smith 			rtl_get_rfreg(hw,  erfpath, RF_SYN_G4, 0x3f800));
2283*af46caf0SBitterblue Smith 
2284*af46caf0SBitterblue Smith 		if (bneed_powerdown_radio) {
2285*af46caf0SBitterblue Smith 			rtl92d_phy_restore_rf_env(hw, erfpath, &u4regvalue);
2286*af46caf0SBitterblue Smith 			rtl92du_phy_powerdown_anotherphy(hw, true);
2287*af46caf0SBitterblue Smith 		}
2288*af46caf0SBitterblue Smith 	}
2289*af46caf0SBitterblue Smith 	rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n");
2290*af46caf0SBitterblue Smith }
2291*af46caf0SBitterblue Smith 
_rtl92du_phy_lc_calibrate_sw(struct ieee80211_hw * hw,bool is2t)2292*af46caf0SBitterblue Smith static void _rtl92du_phy_lc_calibrate_sw(struct ieee80211_hw *hw, bool is2t)
2293*af46caf0SBitterblue Smith {
2294*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2295*af46caf0SBitterblue Smith 	struct rtl_hal *rtlhal = &rtlpriv->rtlhal;
2296*af46caf0SBitterblue Smith 	u32 curvecount_val[CV_CURVE_CNT * 2];
2297*af46caf0SBitterblue Smith 	u16 timeout = 800, timecount = 0;
2298*af46caf0SBitterblue Smith 	u32 u4tmp, offset, rf_syn_g4[2];
2299*af46caf0SBitterblue Smith 	u8 tmpreg, index, rf_mode[2];
2300*af46caf0SBitterblue Smith 	u8 path = is2t ? 2 : 1;
2301*af46caf0SBitterblue Smith 	u8 i;
2302*af46caf0SBitterblue Smith 
2303*af46caf0SBitterblue Smith 	/* Check continuous TX and Packet TX */
2304*af46caf0SBitterblue Smith 	tmpreg = rtl_read_byte(rtlpriv, 0xd03);
2305*af46caf0SBitterblue Smith 	if ((tmpreg & 0x70) != 0)
2306*af46caf0SBitterblue Smith 		/* if Deal with contisuous TX case, disable all continuous TX */
2307*af46caf0SBitterblue Smith 		rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
2308*af46caf0SBitterblue Smith 	else
2309*af46caf0SBitterblue Smith 		/* if Deal with Packet TX case, block all queues */
2310*af46caf0SBitterblue Smith 		rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2311*af46caf0SBitterblue Smith 
2312*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xF00000, 0x0F);
2313*af46caf0SBitterblue Smith 
2314*af46caf0SBitterblue Smith 	for (index = 0; index < path; index++) {
2315*af46caf0SBitterblue Smith 		/* 1. Read original RF mode */
2316*af46caf0SBitterblue Smith 		offset = index == 0 ? ROFDM0_XAAGCCORE1 : ROFDM0_XBAGCCORE1;
2317*af46caf0SBitterblue Smith 		rf_mode[index] = rtl_read_byte(rtlpriv, offset);
2318*af46caf0SBitterblue Smith 
2319*af46caf0SBitterblue Smith 		/* 2. Set RF mode = standby mode */
2320*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, (enum radio_path)index, RF_AC,
2321*af46caf0SBitterblue Smith 			      RFREG_OFFSET_MASK, 0x010000);
2322*af46caf0SBitterblue Smith 
2323*af46caf0SBitterblue Smith 		rf_syn_g4[index] = rtl_get_rfreg(hw, index, RF_SYN_G4,
2324*af46caf0SBitterblue Smith 						 RFREG_OFFSET_MASK);
2325*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, index, RF_SYN_G4, 0x700, 0x7);
2326*af46caf0SBitterblue Smith 
2327*af46caf0SBitterblue Smith 		/* switch CV-curve control by LC-calibration */
2328*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, (enum radio_path)index, RF_SYN_G7,
2329*af46caf0SBitterblue Smith 			      BIT(17), 0x0);
2330*af46caf0SBitterblue Smith 
2331*af46caf0SBitterblue Smith 		/* 4. Set LC calibration begin */
2332*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, (enum radio_path)index, RF_CHNLBW,
2333*af46caf0SBitterblue Smith 			      0x08000, 0x01);
2334*af46caf0SBitterblue Smith 	}
2335*af46caf0SBitterblue Smith 
2336*af46caf0SBitterblue Smith 	for (index = 0; index < path; index++) {
2337*af46caf0SBitterblue Smith 		u4tmp = rtl_get_rfreg(hw, (enum radio_path)index, RF_SYN_G6,
2338*af46caf0SBitterblue Smith 				      RFREG_OFFSET_MASK);
2339*af46caf0SBitterblue Smith 
2340*af46caf0SBitterblue Smith 		while ((!(u4tmp & BIT(11))) && timecount <= timeout) {
2341*af46caf0SBitterblue Smith 			mdelay(50);
2342*af46caf0SBitterblue Smith 			timecount += 50;
2343*af46caf0SBitterblue Smith 			u4tmp = rtl_get_rfreg(hw, (enum radio_path)index,
2344*af46caf0SBitterblue Smith 					      RF_SYN_G6, RFREG_OFFSET_MASK);
2345*af46caf0SBitterblue Smith 		}
2346*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
2347*af46caf0SBitterblue Smith 			"PHY_LCK finish delay for %d ms=2\n", timecount);
2348*af46caf0SBitterblue Smith 	}
2349*af46caf0SBitterblue Smith 
2350*af46caf0SBitterblue Smith 	if ((tmpreg & 0x70) != 0)
2351*af46caf0SBitterblue Smith 		rtl_write_byte(rtlpriv, 0xd03, tmpreg);
2352*af46caf0SBitterblue Smith 	else /* Deal with Packet TX case */
2353*af46caf0SBitterblue Smith 		rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2354*af46caf0SBitterblue Smith 
2355*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xF00000, 0x00);
2356*af46caf0SBitterblue Smith 
2357*af46caf0SBitterblue Smith 	for (index = 0; index < path; index++) {
2358*af46caf0SBitterblue Smith 		rtl_get_rfreg(hw, index, RF_SYN_G4, RFREG_OFFSET_MASK);
2359*af46caf0SBitterblue Smith 
2360*af46caf0SBitterblue Smith 		if (index == 0 && rtlhal->interfaceindex == 0) {
2361*af46caf0SBitterblue Smith 			RTPRINT(rtlpriv, FINIT, INIT_IQK,
2362*af46caf0SBitterblue Smith 				"path-A / 5G LCK\n");
2363*af46caf0SBitterblue Smith 		} else {
2364*af46caf0SBitterblue Smith 			RTPRINT(rtlpriv, FINIT, INIT_IQK,
2365*af46caf0SBitterblue Smith 				"path-B / 2.4G LCK\n");
2366*af46caf0SBitterblue Smith 		}
2367*af46caf0SBitterblue Smith 
2368*af46caf0SBitterblue Smith 		memset(curvecount_val, 0, sizeof(curvecount_val));
2369*af46caf0SBitterblue Smith 
2370*af46caf0SBitterblue Smith 		/* Set LC calibration off */
2371*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, (enum radio_path)index, RF_CHNLBW,
2372*af46caf0SBitterblue Smith 			      0x08000, 0x0);
2373*af46caf0SBitterblue Smith 
2374*af46caf0SBitterblue Smith 		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "set RF 0x18[15] = 0\n");
2375*af46caf0SBitterblue Smith 
2376*af46caf0SBitterblue Smith 		/* save Curve-counting number */
2377*af46caf0SBitterblue Smith 		for (i = 0; i < CV_CURVE_CNT; i++) {
2378*af46caf0SBitterblue Smith 			u32 readval = 0, readval2 = 0;
2379*af46caf0SBitterblue Smith 
2380*af46caf0SBitterblue Smith 			rtl_set_rfreg(hw, (enum radio_path)index, 0x3F,
2381*af46caf0SBitterblue Smith 				      0x7f, i);
2382*af46caf0SBitterblue Smith 
2383*af46caf0SBitterblue Smith 			rtl_set_rfreg(hw, (enum radio_path)index, 0x4D,
2384*af46caf0SBitterblue Smith 				      RFREG_OFFSET_MASK, 0x0);
2385*af46caf0SBitterblue Smith 
2386*af46caf0SBitterblue Smith 			readval = rtl_get_rfreg(hw, (enum radio_path)index,
2387*af46caf0SBitterblue Smith 						0x4F, RFREG_OFFSET_MASK);
2388*af46caf0SBitterblue Smith 			curvecount_val[2 * i + 1] = (readval & 0xfffe0) >> 5;
2389*af46caf0SBitterblue Smith 
2390*af46caf0SBitterblue Smith 			/* reg 0x4f [4:0] */
2391*af46caf0SBitterblue Smith 			/* reg 0x50 [19:10] */
2392*af46caf0SBitterblue Smith 			readval2 = rtl_get_rfreg(hw, (enum radio_path)index,
2393*af46caf0SBitterblue Smith 						 0x50, 0xffc00);
2394*af46caf0SBitterblue Smith 			curvecount_val[2 * i] = (((readval & 0x1F) << 10) |
2395*af46caf0SBitterblue Smith 						 readval2);
2396*af46caf0SBitterblue Smith 		}
2397*af46caf0SBitterblue Smith 
2398*af46caf0SBitterblue Smith 		if (index == 0 && rtlhal->interfaceindex == 0)
2399*af46caf0SBitterblue Smith 			rtl92d_phy_calc_curvindex(hw, targetchnl_5g,
2400*af46caf0SBitterblue Smith 						  curvecount_val,
2401*af46caf0SBitterblue Smith 						  true, rtlpriv->curveindex_5g);
2402*af46caf0SBitterblue Smith 		else
2403*af46caf0SBitterblue Smith 			rtl92d_phy_calc_curvindex(hw, targetchnl_2g,
2404*af46caf0SBitterblue Smith 						  curvecount_val,
2405*af46caf0SBitterblue Smith 						  false, rtlpriv->curveindex_2g);
2406*af46caf0SBitterblue Smith 
2407*af46caf0SBitterblue Smith 		/* switch CV-curve control mode */
2408*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, (enum radio_path)index, RF_SYN_G7,
2409*af46caf0SBitterblue Smith 			      BIT(17), 0x1);
2410*af46caf0SBitterblue Smith 	}
2411*af46caf0SBitterblue Smith 
2412*af46caf0SBitterblue Smith 	/* Restore original situation  */
2413*af46caf0SBitterblue Smith 	for (index = 0; index < path; index++) {
2414*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, index, RF_SYN_G4, RFREG_OFFSET_MASK,
2415*af46caf0SBitterblue Smith 			      rf_syn_g4[index]);
2416*af46caf0SBitterblue Smith 
2417*af46caf0SBitterblue Smith 		offset = index == 0 ? ROFDM0_XAAGCCORE1 : ROFDM0_XBAGCCORE1;
2418*af46caf0SBitterblue Smith 		rtl_write_byte(rtlpriv, offset, 0x50);
2419*af46caf0SBitterblue Smith 		rtl_write_byte(rtlpriv, offset, rf_mode[index]);
2420*af46caf0SBitterblue Smith 	}
2421*af46caf0SBitterblue Smith 
2422*af46caf0SBitterblue Smith 	_rtl92du_phy_reload_lck_setting(hw, rtlpriv->phy.current_channel);
2423*af46caf0SBitterblue Smith }
2424*af46caf0SBitterblue Smith 
rtl92du_phy_lc_calibrate(struct ieee80211_hw * hw,bool is2t)2425*af46caf0SBitterblue Smith void rtl92du_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
2426*af46caf0SBitterblue Smith {
2427*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2428*af46caf0SBitterblue Smith 	struct rtl_hal *rtlhal = &rtlpriv->rtlhal;
2429*af46caf0SBitterblue Smith 	struct rtl_phy *rtlphy = &rtlpriv->phy;
2430*af46caf0SBitterblue Smith 	u32 timeout = 2000, timecount = 0;
2431*af46caf0SBitterblue Smith 
2432*af46caf0SBitterblue Smith 	while (rtlpriv->mac80211.act_scanning && timecount < timeout) {
2433*af46caf0SBitterblue Smith 		udelay(50);
2434*af46caf0SBitterblue Smith 		timecount += 50;
2435*af46caf0SBitterblue Smith 	}
2436*af46caf0SBitterblue Smith 
2437*af46caf0SBitterblue Smith 	rtlphy->lck_inprogress = true;
2438*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,
2439*af46caf0SBitterblue Smith 		"LCK:Start!!! currentband %x delay %d ms\n",
2440*af46caf0SBitterblue Smith 		rtlhal->current_bandtype, timecount);
2441*af46caf0SBitterblue Smith 
2442*af46caf0SBitterblue Smith 	_rtl92du_phy_lc_calibrate_sw(hw, is2t);
2443*af46caf0SBitterblue Smith 
2444*af46caf0SBitterblue Smith 	rtlphy->lck_inprogress = false;
2445*af46caf0SBitterblue Smith 	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "LCK:Finish!!!\n");
2446*af46caf0SBitterblue Smith }
2447*af46caf0SBitterblue Smith 
rtl92du_phy_ap_calibrate(struct ieee80211_hw * hw,s8 delta)2448*af46caf0SBitterblue Smith void rtl92du_phy_ap_calibrate(struct ieee80211_hw *hw, s8 delta)
2449*af46caf0SBitterblue Smith {
2450*af46caf0SBitterblue Smith 	/* Nothing to do. */
2451*af46caf0SBitterblue Smith }
2452*af46caf0SBitterblue Smith 
rtl92du_phy_sw_chnl(struct ieee80211_hw * hw)2453*af46caf0SBitterblue Smith u8 rtl92du_phy_sw_chnl(struct ieee80211_hw *hw)
2454*af46caf0SBitterblue Smith {
2455*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2456*af46caf0SBitterblue Smith 	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
2457*af46caf0SBitterblue Smith 	struct rtl_phy *rtlphy = &rtlpriv->phy;
2458*af46caf0SBitterblue Smith 	u8 num_total_rfpath = rtlphy->num_total_rfpath;
2459*af46caf0SBitterblue Smith 	u8 channel = rtlphy->current_channel;
2460*af46caf0SBitterblue Smith 	u32 timeout = 1000, timecount = 0;
2461*af46caf0SBitterblue Smith 	u32 ret_value;
2462*af46caf0SBitterblue Smith 	u8 rfpath;
2463*af46caf0SBitterblue Smith 
2464*af46caf0SBitterblue Smith 	if (rtlphy->sw_chnl_inprogress)
2465*af46caf0SBitterblue Smith 		return 0;
2466*af46caf0SBitterblue Smith 	if (rtlphy->set_bwmode_inprogress)
2467*af46caf0SBitterblue Smith 		return 0;
2468*af46caf0SBitterblue Smith 
2469*af46caf0SBitterblue Smith 	if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) {
2470*af46caf0SBitterblue Smith 		rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD,
2471*af46caf0SBitterblue Smith 			"sw_chnl_inprogress false driver sleep or unload\n");
2472*af46caf0SBitterblue Smith 		return 0;
2473*af46caf0SBitterblue Smith 	}
2474*af46caf0SBitterblue Smith 
2475*af46caf0SBitterblue Smith 	while (rtlphy->lck_inprogress && timecount < timeout) {
2476*af46caf0SBitterblue Smith 		mdelay(50);
2477*af46caf0SBitterblue Smith 		timecount += 50;
2478*af46caf0SBitterblue Smith 	}
2479*af46caf0SBitterblue Smith 
2480*af46caf0SBitterblue Smith 	if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY &&
2481*af46caf0SBitterblue Smith 	    rtlhal->bandset == BAND_ON_BOTH) {
2482*af46caf0SBitterblue Smith 		ret_value = rtl_get_bbreg(hw, RFPGA0_XAB_RFPARAMETER,
2483*af46caf0SBitterblue Smith 					  MASKDWORD);
2484*af46caf0SBitterblue Smith 		if (rtlphy->current_channel > 14 && !(ret_value & BIT(0)))
2485*af46caf0SBitterblue Smith 			rtl92du_phy_switch_wirelessband(hw, BAND_ON_5G);
2486*af46caf0SBitterblue Smith 		else if (rtlphy->current_channel <= 14 && (ret_value & BIT(0)))
2487*af46caf0SBitterblue Smith 			rtl92du_phy_switch_wirelessband(hw, BAND_ON_2_4G);
2488*af46caf0SBitterblue Smith 	}
2489*af46caf0SBitterblue Smith 
2490*af46caf0SBitterblue Smith 	switch (rtlhal->current_bandtype) {
2491*af46caf0SBitterblue Smith 	case BAND_ON_5G:
2492*af46caf0SBitterblue Smith 		/* Get first channel error when change between
2493*af46caf0SBitterblue Smith 		 * 5G and 2.4G band.
2494*af46caf0SBitterblue Smith 		 */
2495*af46caf0SBitterblue Smith 		if (WARN_ONCE(channel <= 14, "rtl8192du: 5G but channel<=14\n"))
2496*af46caf0SBitterblue Smith 			return 0;
2497*af46caf0SBitterblue Smith 		break;
2498*af46caf0SBitterblue Smith 	case BAND_ON_2_4G:
2499*af46caf0SBitterblue Smith 		/* Get first channel error when change between
2500*af46caf0SBitterblue Smith 		 * 5G and 2.4G band.
2501*af46caf0SBitterblue Smith 		 */
2502*af46caf0SBitterblue Smith 		if (WARN_ONCE(channel > 14, "rtl8192du: 2G but channel>14\n"))
2503*af46caf0SBitterblue Smith 			return 0;
2504*af46caf0SBitterblue Smith 		break;
2505*af46caf0SBitterblue Smith 	default:
2506*af46caf0SBitterblue Smith 		WARN_ONCE(true, "rtl8192du: Invalid WirelessMode(%#x)!!\n",
2507*af46caf0SBitterblue Smith 			  rtlpriv->mac80211.mode);
2508*af46caf0SBitterblue Smith 		break;
2509*af46caf0SBitterblue Smith 	}
2510*af46caf0SBitterblue Smith 
2511*af46caf0SBitterblue Smith 	rtlphy->sw_chnl_inprogress = true;
2512*af46caf0SBitterblue Smith 
2513*af46caf0SBitterblue Smith 	rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE,
2514*af46caf0SBitterblue Smith 		"switch to channel%d\n", rtlphy->current_channel);
2515*af46caf0SBitterblue Smith 
2516*af46caf0SBitterblue Smith 	rtl92d_phy_set_txpower_level(hw, channel);
2517*af46caf0SBitterblue Smith 
2518*af46caf0SBitterblue Smith 	for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
2519*af46caf0SBitterblue Smith 		u32p_replace_bits(&rtlphy->rfreg_chnlval[rfpath],
2520*af46caf0SBitterblue Smith 				  channel, 0xff);
2521*af46caf0SBitterblue Smith 
2522*af46caf0SBitterblue Smith 		if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) {
2523*af46caf0SBitterblue Smith 			if (channel > 99)
2524*af46caf0SBitterblue Smith 				rtlphy->rfreg_chnlval[rfpath] |= (BIT(18));
2525*af46caf0SBitterblue Smith 			else
2526*af46caf0SBitterblue Smith 				rtlphy->rfreg_chnlval[rfpath] &= ~BIT(18);
2527*af46caf0SBitterblue Smith 			rtlphy->rfreg_chnlval[rfpath] |= (BIT(16) | BIT(8));
2528*af46caf0SBitterblue Smith 		} else {
2529*af46caf0SBitterblue Smith 			rtlphy->rfreg_chnlval[rfpath] &=
2530*af46caf0SBitterblue Smith 				~(BIT(8) | BIT(16) | BIT(18));
2531*af46caf0SBitterblue Smith 		}
2532*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, rfpath, RF_CHNLBW, RFREG_OFFSET_MASK,
2533*af46caf0SBitterblue Smith 			      rtlphy->rfreg_chnlval[rfpath]);
2534*af46caf0SBitterblue Smith 
2535*af46caf0SBitterblue Smith 		_rtl92du_phy_reload_imr_setting(hw, channel, rfpath);
2536*af46caf0SBitterblue Smith 	}
2537*af46caf0SBitterblue Smith 
2538*af46caf0SBitterblue Smith 	_rtl92du_phy_switch_rf_setting(hw, channel);
2539*af46caf0SBitterblue Smith 
2540*af46caf0SBitterblue Smith 	/* do IQK when all parameters are ready */
2541*af46caf0SBitterblue Smith 	rtl92du_phy_reload_iqk_setting(hw, channel);
2542*af46caf0SBitterblue Smith 
2543*af46caf0SBitterblue Smith 	rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
2544*af46caf0SBitterblue Smith 	rtlphy->sw_chnl_inprogress = false;
2545*af46caf0SBitterblue Smith 	return 1;
2546*af46caf0SBitterblue Smith }
2547*af46caf0SBitterblue Smith 
_rtl92du_phy_set_rfon(struct ieee80211_hw * hw)2548*af46caf0SBitterblue Smith static void _rtl92du_phy_set_rfon(struct ieee80211_hw *hw)
2549*af46caf0SBitterblue Smith {
2550*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2551*af46caf0SBitterblue Smith 
2552*af46caf0SBitterblue Smith 	/* a.  SYS_CLKR 0x08[11] = 1  restore MAC clock */
2553*af46caf0SBitterblue Smith 	/* b.  SPS_CTRL 0x11[7:0] = 0x2b */
2554*af46caf0SBitterblue Smith 	if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY)
2555*af46caf0SBitterblue Smith 		rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
2556*af46caf0SBitterblue Smith 
2557*af46caf0SBitterblue Smith 	/* c.  For PCIE: SYS_FUNC_EN 0x02[7:0] = 0xE3 enable BB TRX function */
2558*af46caf0SBitterblue Smith 	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2559*af46caf0SBitterblue Smith 
2560*af46caf0SBitterblue Smith 	/* RF_ON_EXCEP(d~g): */
2561*af46caf0SBitterblue Smith 	/* d.  APSD_CTRL 0x600[7:0] = 0x00 */
2562*af46caf0SBitterblue Smith 	rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
2563*af46caf0SBitterblue Smith 
2564*af46caf0SBitterblue Smith 	/* e.  SYS_FUNC_EN 0x02[7:0] = 0xE2  reset BB TRX function again */
2565*af46caf0SBitterblue Smith 	/* f.  SYS_FUNC_EN 0x02[7:0] = 0xE3  enable BB TRX function*/
2566*af46caf0SBitterblue Smith 	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2567*af46caf0SBitterblue Smith 	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2568*af46caf0SBitterblue Smith 
2569*af46caf0SBitterblue Smith 	/* g.   txpause 0x522[7:0] = 0x00  enable mac tx queue */
2570*af46caf0SBitterblue Smith 	rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2571*af46caf0SBitterblue Smith }
2572*af46caf0SBitterblue Smith 
_rtl92du_phy_set_rfsleep(struct ieee80211_hw * hw)2573*af46caf0SBitterblue Smith static void _rtl92du_phy_set_rfsleep(struct ieee80211_hw *hw)
2574*af46caf0SBitterblue Smith {
2575*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2576*af46caf0SBitterblue Smith 	u32 u4btmp;
2577*af46caf0SBitterblue Smith 	u8 retry = 5;
2578*af46caf0SBitterblue Smith 
2579*af46caf0SBitterblue Smith 	/* a.   TXPAUSE 0x522[7:0] = 0xFF  Pause MAC TX queue  */
2580*af46caf0SBitterblue Smith 	rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2581*af46caf0SBitterblue Smith 
2582*af46caf0SBitterblue Smith 	/* b.   RF path 0 offset 0x00 = 0x00  disable RF  */
2583*af46caf0SBitterblue Smith 	rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
2584*af46caf0SBitterblue Smith 
2585*af46caf0SBitterblue Smith 	/* c.   APSD_CTRL 0x600[7:0] = 0x40 */
2586*af46caf0SBitterblue Smith 	rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
2587*af46caf0SBitterblue Smith 
2588*af46caf0SBitterblue Smith 	/* d. APSD_CTRL 0x600[7:0] = 0x00
2589*af46caf0SBitterblue Smith 	 * APSD_CTRL 0x600[7:0] = 0x00
2590*af46caf0SBitterblue Smith 	 * RF path 0 offset 0x00 = 0x00
2591*af46caf0SBitterblue Smith 	 * APSD_CTRL 0x600[7:0] = 0x40
2592*af46caf0SBitterblue Smith 	 */
2593*af46caf0SBitterblue Smith 	u4btmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
2594*af46caf0SBitterblue Smith 	while (u4btmp != 0 && retry > 0) {
2595*af46caf0SBitterblue Smith 		rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0);
2596*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
2597*af46caf0SBitterblue Smith 		rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
2598*af46caf0SBitterblue Smith 		u4btmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
2599*af46caf0SBitterblue Smith 		retry--;
2600*af46caf0SBitterblue Smith 	}
2601*af46caf0SBitterblue Smith 	if (retry == 0) {
2602*af46caf0SBitterblue Smith 		/* Jump out the LPS turn off sequence to RF_ON_EXCEP */
2603*af46caf0SBitterblue Smith 		rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
2604*af46caf0SBitterblue Smith 
2605*af46caf0SBitterblue Smith 		rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2606*af46caf0SBitterblue Smith 		rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2607*af46caf0SBitterblue Smith 		rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2608*af46caf0SBitterblue Smith 		rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
2609*af46caf0SBitterblue Smith 			"Fail !!! Switch RF timeout\n");
2610*af46caf0SBitterblue Smith 		return;
2611*af46caf0SBitterblue Smith 	}
2612*af46caf0SBitterblue Smith 
2613*af46caf0SBitterblue Smith 	/* e.   For PCIE: SYS_FUNC_EN 0x02[7:0] = 0xE2 reset BB TRX function */
2614*af46caf0SBitterblue Smith 	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2615*af46caf0SBitterblue Smith 
2616*af46caf0SBitterblue Smith 	/* f.   SPS_CTRL 0x11[7:0] = 0x22 */
2617*af46caf0SBitterblue Smith 	if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY)
2618*af46caf0SBitterblue Smith 		rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
2619*af46caf0SBitterblue Smith }
2620*af46caf0SBitterblue Smith 
rtl92du_phy_set_rf_power_state(struct ieee80211_hw * hw,enum rf_pwrstate rfpwr_state)2621*af46caf0SBitterblue Smith bool rtl92du_phy_set_rf_power_state(struct ieee80211_hw *hw,
2622*af46caf0SBitterblue Smith 				    enum rf_pwrstate rfpwr_state)
2623*af46caf0SBitterblue Smith {
2624*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2625*af46caf0SBitterblue Smith 	struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
2626*af46caf0SBitterblue Smith 	struct rtl_mac *mac = rtl_mac(rtlpriv);
2627*af46caf0SBitterblue Smith 	bool bresult = true;
2628*af46caf0SBitterblue Smith 
2629*af46caf0SBitterblue Smith 	if (rfpwr_state == ppsc->rfpwr_state)
2630*af46caf0SBitterblue Smith 		return false;
2631*af46caf0SBitterblue Smith 
2632*af46caf0SBitterblue Smith 	switch (rfpwr_state) {
2633*af46caf0SBitterblue Smith 	case ERFON:
2634*af46caf0SBitterblue Smith 		if (ppsc->rfpwr_state == ERFOFF &&
2635*af46caf0SBitterblue Smith 		    RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
2636*af46caf0SBitterblue Smith 			u32 initializecount = 0;
2637*af46caf0SBitterblue Smith 			bool rtstatus;
2638*af46caf0SBitterblue Smith 
2639*af46caf0SBitterblue Smith 			do {
2640*af46caf0SBitterblue Smith 				initializecount++;
2641*af46caf0SBitterblue Smith 				rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,
2642*af46caf0SBitterblue Smith 					"IPS Set eRf nic enable\n");
2643*af46caf0SBitterblue Smith 				rtstatus = rtl_ps_enable_nic(hw);
2644*af46caf0SBitterblue Smith 			} while (!rtstatus && (initializecount < 10));
2645*af46caf0SBitterblue Smith 
2646*af46caf0SBitterblue Smith 			RT_CLEAR_PS_LEVEL(ppsc,
2647*af46caf0SBitterblue Smith 					  RT_RF_OFF_LEVL_HALT_NIC);
2648*af46caf0SBitterblue Smith 		} else {
2649*af46caf0SBitterblue Smith 			rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG,
2650*af46caf0SBitterblue Smith 				"awake, slept:%d ms state_inap:%x\n",
2651*af46caf0SBitterblue Smith 				jiffies_to_msecs(jiffies -
2652*af46caf0SBitterblue Smith 						 ppsc->last_sleep_jiffies),
2653*af46caf0SBitterblue Smith 				 rtlpriv->psc.state_inap);
2654*af46caf0SBitterblue Smith 			ppsc->last_awake_jiffies = jiffies;
2655*af46caf0SBitterblue Smith 			_rtl92du_phy_set_rfon(hw);
2656*af46caf0SBitterblue Smith 		}
2657*af46caf0SBitterblue Smith 
2658*af46caf0SBitterblue Smith 		if (mac->link_state == MAC80211_LINKED)
2659*af46caf0SBitterblue Smith 			rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK);
2660*af46caf0SBitterblue Smith 		else
2661*af46caf0SBitterblue Smith 			rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK);
2662*af46caf0SBitterblue Smith 		break;
2663*af46caf0SBitterblue Smith 	case ERFOFF:
2664*af46caf0SBitterblue Smith 		if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
2665*af46caf0SBitterblue Smith 			rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,
2666*af46caf0SBitterblue Smith 				"IPS Set eRf nic disable\n");
2667*af46caf0SBitterblue Smith 			rtl_ps_disable_nic(hw);
2668*af46caf0SBitterblue Smith 			RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2669*af46caf0SBitterblue Smith 		} else {
2670*af46caf0SBitterblue Smith 			if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
2671*af46caf0SBitterblue Smith 				rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK);
2672*af46caf0SBitterblue Smith 			else
2673*af46caf0SBitterblue Smith 				rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
2674*af46caf0SBitterblue Smith 		}
2675*af46caf0SBitterblue Smith 		break;
2676*af46caf0SBitterblue Smith 	case ERFSLEEP:
2677*af46caf0SBitterblue Smith 		if (ppsc->rfpwr_state == ERFOFF)
2678*af46caf0SBitterblue Smith 			return false;
2679*af46caf0SBitterblue Smith 
2680*af46caf0SBitterblue Smith 		rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG,
2681*af46caf0SBitterblue Smith 			"sleep awakened:%d ms state_inap:%x\n",
2682*af46caf0SBitterblue Smith 			jiffies_to_msecs(jiffies -
2683*af46caf0SBitterblue Smith 					 ppsc->last_awake_jiffies),
2684*af46caf0SBitterblue Smith 			rtlpriv->psc.state_inap);
2685*af46caf0SBitterblue Smith 		ppsc->last_sleep_jiffies = jiffies;
2686*af46caf0SBitterblue Smith 		_rtl92du_phy_set_rfsleep(hw);
2687*af46caf0SBitterblue Smith 		break;
2688*af46caf0SBitterblue Smith 	default:
2689*af46caf0SBitterblue Smith 		pr_err("switch case %#x not processed\n",
2690*af46caf0SBitterblue Smith 		       rfpwr_state);
2691*af46caf0SBitterblue Smith 		return false;
2692*af46caf0SBitterblue Smith 	}
2693*af46caf0SBitterblue Smith 
2694*af46caf0SBitterblue Smith 	if (bresult)
2695*af46caf0SBitterblue Smith 		ppsc->rfpwr_state = rfpwr_state;
2696*af46caf0SBitterblue Smith 
2697*af46caf0SBitterblue Smith 	return bresult;
2698*af46caf0SBitterblue Smith }
2699*af46caf0SBitterblue Smith 
rtl92du_phy_set_poweron(struct ieee80211_hw * hw)2700*af46caf0SBitterblue Smith void rtl92du_phy_set_poweron(struct ieee80211_hw *hw)
2701*af46caf0SBitterblue Smith {
2702*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2703*af46caf0SBitterblue Smith 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2704*af46caf0SBitterblue Smith 	u32 mac_reg = (rtlhal->interfaceindex == 0 ? REG_MAC0 : REG_MAC1);
2705*af46caf0SBitterblue Smith 	u8 value8;
2706*af46caf0SBitterblue Smith 	u16 i;
2707*af46caf0SBitterblue Smith 
2708*af46caf0SBitterblue Smith 	/* notice fw know band status  0x81[1]/0x53[1] = 0: 5G, 1: 2G */
2709*af46caf0SBitterblue Smith 	if (rtlhal->current_bandtype == BAND_ON_2_4G) {
2710*af46caf0SBitterblue Smith 		value8 = rtl_read_byte(rtlpriv, mac_reg);
2711*af46caf0SBitterblue Smith 		value8 |= BIT(1);
2712*af46caf0SBitterblue Smith 		rtl_write_byte(rtlpriv, mac_reg, value8);
2713*af46caf0SBitterblue Smith 	} else {
2714*af46caf0SBitterblue Smith 		value8 = rtl_read_byte(rtlpriv, mac_reg);
2715*af46caf0SBitterblue Smith 		value8 &= ~BIT(1);
2716*af46caf0SBitterblue Smith 		rtl_write_byte(rtlpriv, mac_reg, value8);
2717*af46caf0SBitterblue Smith 	}
2718*af46caf0SBitterblue Smith 
2719*af46caf0SBitterblue Smith 	if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY) {
2720*af46caf0SBitterblue Smith 		value8 = rtl_read_byte(rtlpriv, REG_MAC0);
2721*af46caf0SBitterblue Smith 		rtl_write_byte(rtlpriv, REG_MAC0, value8 | MAC0_ON);
2722*af46caf0SBitterblue Smith 	} else {
2723*af46caf0SBitterblue Smith 		mutex_lock(rtlpriv->mutex_for_power_on_off);
2724*af46caf0SBitterblue Smith 		if (rtlhal->interfaceindex == 0) {
2725*af46caf0SBitterblue Smith 			value8 = rtl_read_byte(rtlpriv, REG_MAC0);
2726*af46caf0SBitterblue Smith 			rtl_write_byte(rtlpriv, REG_MAC0, value8 | MAC0_ON);
2727*af46caf0SBitterblue Smith 		} else {
2728*af46caf0SBitterblue Smith 			value8 = rtl_read_byte(rtlpriv, REG_MAC1);
2729*af46caf0SBitterblue Smith 			rtl_write_byte(rtlpriv, REG_MAC1, value8 | MAC1_ON);
2730*af46caf0SBitterblue Smith 		}
2731*af46caf0SBitterblue Smith 		value8 = rtl_read_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS);
2732*af46caf0SBitterblue Smith 		mutex_unlock(rtlpriv->mutex_for_power_on_off);
2733*af46caf0SBitterblue Smith 
2734*af46caf0SBitterblue Smith 		for (i = 0; i < 200; i++) {
2735*af46caf0SBitterblue Smith 			if ((value8 & BIT(7)) == 0)
2736*af46caf0SBitterblue Smith 				break;
2737*af46caf0SBitterblue Smith 
2738*af46caf0SBitterblue Smith 			udelay(500);
2739*af46caf0SBitterblue Smith 			mutex_lock(rtlpriv->mutex_for_power_on_off);
2740*af46caf0SBitterblue Smith 			value8 = rtl_read_byte(rtlpriv,
2741*af46caf0SBitterblue Smith 					       REG_POWER_OFF_IN_PROCESS);
2742*af46caf0SBitterblue Smith 			mutex_unlock(rtlpriv->mutex_for_power_on_off);
2743*af46caf0SBitterblue Smith 		}
2744*af46caf0SBitterblue Smith 		if (i == 200)
2745*af46caf0SBitterblue Smith 			WARN_ONCE(true, "rtl8192du: Another mac power off over time\n");
2746*af46caf0SBitterblue Smith 	}
2747*af46caf0SBitterblue Smith }
2748*af46caf0SBitterblue Smith 
rtl92du_update_bbrf_configuration(struct ieee80211_hw * hw)2749*af46caf0SBitterblue Smith void rtl92du_update_bbrf_configuration(struct ieee80211_hw *hw)
2750*af46caf0SBitterblue Smith {
2751*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2752*af46caf0SBitterblue Smith 	struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
2753*af46caf0SBitterblue Smith 	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
2754*af46caf0SBitterblue Smith 	struct rtl_phy *rtlphy = &rtlpriv->phy;
2755*af46caf0SBitterblue Smith 	u8 rfpath, i;
2756*af46caf0SBitterblue Smith 
2757*af46caf0SBitterblue Smith 	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "==>\n");
2758*af46caf0SBitterblue Smith 	/* r_select_5G for path_A/B 0 for 2.4G, 1 for 5G */
2759*af46caf0SBitterblue Smith 	if (rtlhal->current_bandtype == BAND_ON_2_4G) {
2760*af46caf0SBitterblue Smith 		/* r_select_5G for path_A/B, 0x878 */
2761*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(0), 0x0);
2762*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(15), 0x0);
2763*af46caf0SBitterblue Smith 		if (rtlhal->macphymode != DUALMAC_DUALPHY) {
2764*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(16), 0x0);
2765*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(31), 0x0);
2766*af46caf0SBitterblue Smith 		}
2767*af46caf0SBitterblue Smith 
2768*af46caf0SBitterblue Smith 		/* rssi_table_select: index 0 for 2.4G. 1~3 for 5G, 0xc78 */
2769*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, BIT(6) | BIT(7), 0x0);
2770*af46caf0SBitterblue Smith 
2771*af46caf0SBitterblue Smith 		/* fc_area  0xd2c */
2772*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(14) | BIT(13), 0x0);
2773*af46caf0SBitterblue Smith 
2774*af46caf0SBitterblue Smith 		/* 5G LAN ON */
2775*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, 0xB30, 0x00F00000, 0xa);
2776*af46caf0SBitterblue Smith 
2777*af46caf0SBitterblue Smith 		/* TX BB gain shift*1, Just for testchip, 0xc80, 0xc88 */
2778*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD, 0x40000100);
2779*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, MASKDWORD, 0x40000100);
2780*af46caf0SBitterblue Smith 		if (rtlhal->macphymode == DUALMAC_DUALPHY) {
2781*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW,
2782*af46caf0SBitterblue Smith 				      BIT(10) | BIT(6) | BIT(5),
2783*af46caf0SBitterblue Smith 				      ((rtlefuse->eeprom_c9 & BIT(3)) >> 3) |
2784*af46caf0SBitterblue Smith 				      (rtlefuse->eeprom_c9 & BIT(1)) |
2785*af46caf0SBitterblue Smith 				      ((rtlefuse->eeprom_cc & BIT(1)) << 4));
2786*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE,
2787*af46caf0SBitterblue Smith 				      BIT(10) | BIT(6) | BIT(5),
2788*af46caf0SBitterblue Smith 				      ((rtlefuse->eeprom_c9 & BIT(2)) >> 2) |
2789*af46caf0SBitterblue Smith 				      ((rtlefuse->eeprom_c9 & BIT(0)) << 1) |
2790*af46caf0SBitterblue Smith 				      ((rtlefuse->eeprom_cc & BIT(0)) << 5));
2791*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(15), 0);
2792*af46caf0SBitterblue Smith 
2793*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RPDP_ANTA, MASKDWORD, 0x01017038);
2794*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RCONFIG_ANTA, MASKDWORD, 0x0f600000);
2795*af46caf0SBitterblue Smith 		} else {
2796*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW,
2797*af46caf0SBitterblue Smith 				      BIT(26) | BIT(22) | BIT(21) | BIT(10) |
2798*af46caf0SBitterblue Smith 				      BIT(6) | BIT(5),
2799*af46caf0SBitterblue Smith 				      ((rtlefuse->eeprom_c9 & BIT(3)) >> 3) |
2800*af46caf0SBitterblue Smith 				      (rtlefuse->eeprom_c9 & BIT(1)) |
2801*af46caf0SBitterblue Smith 				      ((rtlefuse->eeprom_cc & BIT(1)) << 4) |
2802*af46caf0SBitterblue Smith 				      ((rtlefuse->eeprom_c9 & BIT(7)) << 9) |
2803*af46caf0SBitterblue Smith 				      ((rtlefuse->eeprom_c9 & BIT(5)) << 12) |
2804*af46caf0SBitterblue Smith 				      ((rtlefuse->eeprom_cc & BIT(3)) << 18));
2805*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE,
2806*af46caf0SBitterblue Smith 				      BIT(10) | BIT(6) | BIT(5),
2807*af46caf0SBitterblue Smith 				      ((rtlefuse->eeprom_c9 & BIT(2)) >> 2) |
2808*af46caf0SBitterblue Smith 				      ((rtlefuse->eeprom_c9 & BIT(0)) << 1) |
2809*af46caf0SBitterblue Smith 				      ((rtlefuse->eeprom_cc & BIT(0)) << 5));
2810*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
2811*af46caf0SBitterblue Smith 				      BIT(10) | BIT(6) | BIT(5),
2812*af46caf0SBitterblue Smith 				      ((rtlefuse->eeprom_c9 & BIT(6)) >> 6) |
2813*af46caf0SBitterblue Smith 				      ((rtlefuse->eeprom_c9 & BIT(4)) >> 3) |
2814*af46caf0SBitterblue Smith 				      ((rtlefuse->eeprom_cc & BIT(2)) << 3));
2815*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER,
2816*af46caf0SBitterblue Smith 				      BIT(31) | BIT(15), 0);
2817*af46caf0SBitterblue Smith 
2818*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RPDP_ANTA, MASKDWORD, 0x01017038);
2819*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RPDP_ANTB, MASKDWORD, 0x01017038);
2820*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RCONFIG_ANTA, MASKDWORD, 0x0f600000);
2821*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RCONFIG_ANTB, MASKDWORD, 0x0f600000);
2822*af46caf0SBitterblue Smith 		}
2823*af46caf0SBitterblue Smith 		/* 1.5V_LDO */
2824*af46caf0SBitterblue Smith 	} else {
2825*af46caf0SBitterblue Smith 		/* r_select_5G for path_A/B */
2826*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(0), 0x1);
2827*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(15), 0x1);
2828*af46caf0SBitterblue Smith 		if (rtlhal->macphymode != DUALMAC_DUALPHY) {
2829*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(16), 0x1);
2830*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(31), 0x1);
2831*af46caf0SBitterblue Smith 		}
2832*af46caf0SBitterblue Smith 
2833*af46caf0SBitterblue Smith 		/* rssi_table_select: index 0 for 2.4G. 1~3 for 5G */
2834*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, BIT(6) | BIT(7), 0x1);
2835*af46caf0SBitterblue Smith 
2836*af46caf0SBitterblue Smith 		/* fc_area */
2837*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(14) | BIT(13), 0x1);
2838*af46caf0SBitterblue Smith 
2839*af46caf0SBitterblue Smith 		/* 5G LAN ON */
2840*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, 0xB30, 0x00F00000, 0x0);
2841*af46caf0SBitterblue Smith 
2842*af46caf0SBitterblue Smith 		/* TX BB gain shift, Just for testchip, 0xc80, 0xc88 */
2843*af46caf0SBitterblue Smith 		if (rtlefuse->internal_pa_5g[rtlhal->interfaceindex])
2844*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD,
2845*af46caf0SBitterblue Smith 				      0x2d4000b5);
2846*af46caf0SBitterblue Smith 		else
2847*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD,
2848*af46caf0SBitterblue Smith 				      0x20000080);
2849*af46caf0SBitterblue Smith 
2850*af46caf0SBitterblue Smith 		if (rtlhal->macphymode != DUALMAC_DUALPHY) {
2851*af46caf0SBitterblue Smith 			if (rtlefuse->internal_pa_5g[1])
2852*af46caf0SBitterblue Smith 				rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
2853*af46caf0SBitterblue Smith 					      MASKDWORD, 0x2d4000b5);
2854*af46caf0SBitterblue Smith 			else
2855*af46caf0SBitterblue Smith 				rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
2856*af46caf0SBitterblue Smith 					      MASKDWORD, 0x20000080);
2857*af46caf0SBitterblue Smith 		}
2858*af46caf0SBitterblue Smith 
2859*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, 0xB30, BIT(27), 0);
2860*af46caf0SBitterblue Smith 
2861*af46caf0SBitterblue Smith 		if (rtlhal->macphymode == DUALMAC_DUALPHY) {
2862*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW,
2863*af46caf0SBitterblue Smith 				      BIT(10) | BIT(6) | BIT(5),
2864*af46caf0SBitterblue Smith 				      (rtlefuse->eeprom_cc & BIT(5)));
2865*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BIT(10),
2866*af46caf0SBitterblue Smith 				      ((rtlefuse->eeprom_cc & BIT(4)) >> 4));
2867*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(15),
2868*af46caf0SBitterblue Smith 				      (rtlefuse->eeprom_cc & BIT(4)) >> 4);
2869*af46caf0SBitterblue Smith 
2870*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RPDP_ANTA, MASKDWORD, 0x01017098);
2871*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RCONFIG_ANTA, MASKDWORD, 0x20000000);
2872*af46caf0SBitterblue Smith 		} else {
2873*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW,
2874*af46caf0SBitterblue Smith 				      BIT(26) | BIT(22) | BIT(21) | BIT(10) |
2875*af46caf0SBitterblue Smith 				      BIT(6) | BIT(5),
2876*af46caf0SBitterblue Smith 				      (rtlefuse->eeprom_cc & BIT(5)) |
2877*af46caf0SBitterblue Smith 				      ((rtlefuse->eeprom_cc & BIT(7)) << 14));
2878*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BIT(10),
2879*af46caf0SBitterblue Smith 				      ((rtlefuse->eeprom_cc & BIT(4)) >> 4));
2880*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, BIT(10),
2881*af46caf0SBitterblue Smith 				      ((rtlefuse->eeprom_cc & BIT(6)) >> 6));
2882*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER,
2883*af46caf0SBitterblue Smith 				      BIT(31) | BIT(15),
2884*af46caf0SBitterblue Smith 				      ((rtlefuse->eeprom_cc & BIT(4)) >> 4) |
2885*af46caf0SBitterblue Smith 				      ((rtlefuse->eeprom_cc & BIT(6)) << 10));
2886*af46caf0SBitterblue Smith 
2887*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RPDP_ANTA, MASKDWORD, 0x01017098);
2888*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RPDP_ANTB, MASKDWORD, 0x01017098);
2889*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RCONFIG_ANTA, MASKDWORD, 0x20000000);
2890*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RCONFIG_ANTB, MASKDWORD, 0x20000000);
2891*af46caf0SBitterblue Smith 		}
2892*af46caf0SBitterblue Smith 	}
2893*af46caf0SBitterblue Smith 
2894*af46caf0SBitterblue Smith 	/* update IQK related settings */
2895*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, MASKDWORD, 0x40000100);
2896*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, MASKDWORD, 0x40000100);
2897*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000, 0x00);
2898*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(30) | BIT(28) |
2899*af46caf0SBitterblue Smith 		      BIT(26) | BIT(24), 0x00);
2900*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000, 0x00);
2901*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, ROFDM0_RXIQEXTANTA, 0xF0000000, 0x00);
2902*af46caf0SBitterblue Smith 	rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, 0x00);
2903*af46caf0SBitterblue Smith 
2904*af46caf0SBitterblue Smith 	/* Update RF */
2905*af46caf0SBitterblue Smith 	for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
2906*af46caf0SBitterblue Smith 	     rfpath++) {
2907*af46caf0SBitterblue Smith 		if (rtlhal->current_bandtype == BAND_ON_2_4G) {
2908*af46caf0SBitterblue Smith 			/* MOD_AG for RF path_A 0x18 BIT8,BIT16 */
2909*af46caf0SBitterblue Smith 			rtl_set_rfreg(hw, rfpath, RF_CHNLBW, BIT(8) | BIT(16) |
2910*af46caf0SBitterblue Smith 				      BIT(18) | 0xff, 1);
2911*af46caf0SBitterblue Smith 
2912*af46caf0SBitterblue Smith 			/* RF0x0b[16:14] =3b'111 */
2913*af46caf0SBitterblue Smith 			rtl_set_rfreg(hw, (enum radio_path)rfpath, 0x0B,
2914*af46caf0SBitterblue Smith 				      0x1c000, 0x07);
2915*af46caf0SBitterblue Smith 		} else {
2916*af46caf0SBitterblue Smith 			/* MOD_AG for RF path_A 0x18 BIT8,BIT16 */
2917*af46caf0SBitterblue Smith 			rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK,
2918*af46caf0SBitterblue Smith 				      0x97524);
2919*af46caf0SBitterblue Smith 		}
2920*af46caf0SBitterblue Smith 
2921*af46caf0SBitterblue Smith 		/* Set right channel on RF reg0x18 for another mac. */
2922*af46caf0SBitterblue Smith 		if (rtlhal->interfaceindex == 0 && rtlhal->bandset == BAND_ON_2_4G) {
2923*af46caf0SBitterblue Smith 			/* Set MAC1 default channel if MAC1 not up. */
2924*af46caf0SBitterblue Smith 			if (!(rtl_read_byte(rtlpriv, REG_MAC1) & MAC1_ON)) {
2925*af46caf0SBitterblue Smith 				rtl92du_phy_enable_anotherphy(hw, true);
2926*af46caf0SBitterblue Smith 				rtlhal->during_mac0init_radiob = true;
2927*af46caf0SBitterblue Smith 				rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW,
2928*af46caf0SBitterblue Smith 					      RFREG_OFFSET_MASK, 0x97524);
2929*af46caf0SBitterblue Smith 				rtl92du_phy_powerdown_anotherphy(hw, true);
2930*af46caf0SBitterblue Smith 			}
2931*af46caf0SBitterblue Smith 		} else if (rtlhal->interfaceindex == 1 && rtlhal->bandset == BAND_ON_5G) {
2932*af46caf0SBitterblue Smith 			/* Set MAC0 default channel */
2933*af46caf0SBitterblue Smith 			if (!(rtl_read_byte(rtlpriv, REG_MAC0) & MAC0_ON)) {
2934*af46caf0SBitterblue Smith 				rtl92du_phy_enable_anotherphy(hw, false);
2935*af46caf0SBitterblue Smith 				rtlhal->during_mac1init_radioa = true;
2936*af46caf0SBitterblue Smith 				rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW,
2937*af46caf0SBitterblue Smith 					      RFREG_OFFSET_MASK, 0x87401);
2938*af46caf0SBitterblue Smith 				rtl92du_phy_powerdown_anotherphy(hw, false);
2939*af46caf0SBitterblue Smith 			}
2940*af46caf0SBitterblue Smith 		}
2941*af46caf0SBitterblue Smith 	}
2942*af46caf0SBitterblue Smith 
2943*af46caf0SBitterblue Smith 	/* Update for all band. */
2944*af46caf0SBitterblue Smith 	/* DMDP */
2945*af46caf0SBitterblue Smith 	if (rtlphy->rf_type == RF_1T1R) {
2946*af46caf0SBitterblue Smith 		/* Use antenna 0, 0xc04, 0xd04 */
2947*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x11);
2948*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0x1);
2949*af46caf0SBitterblue Smith 
2950*af46caf0SBitterblue Smith 		/* enable ad/da clock1 for dual-phy reg0x888 */
2951*af46caf0SBitterblue Smith 		if (rtlhal->interfaceindex == 0) {
2952*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RFPGA0_ADDALLOCKEN, BIT(12) |
2953*af46caf0SBitterblue Smith 				      BIT(13), 0x3);
2954*af46caf0SBitterblue Smith 		} else if (rtl92du_phy_enable_anotherphy(hw, false)) {
2955*af46caf0SBitterblue Smith 			rtlhal->during_mac1init_radioa = true;
2956*af46caf0SBitterblue Smith 			rtl_set_bbreg(hw, RFPGA0_ADDALLOCKEN,
2957*af46caf0SBitterblue Smith 				      BIT(12) | BIT(13), 0x3);
2958*af46caf0SBitterblue Smith 			rtl92du_phy_powerdown_anotherphy(hw, false);
2959*af46caf0SBitterblue Smith 		}
2960*af46caf0SBitterblue Smith 
2961*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(19) | BIT(20), 0x0);
2962*af46caf0SBitterblue Smith 	} else {
2963*af46caf0SBitterblue Smith 		/* Single PHY */
2964*af46caf0SBitterblue Smith 		/* Use antenna 0 & 1, 0xc04, 0xd04 */
2965*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x33);
2966*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0x3);
2967*af46caf0SBitterblue Smith 		/* disable ad/da clock1,0x888 */
2968*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, RFPGA0_ADDALLOCKEN, BIT(12) | BIT(13), 0);
2969*af46caf0SBitterblue Smith 
2970*af46caf0SBitterblue Smith 		rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(19) | BIT(20), 0x1);
2971*af46caf0SBitterblue Smith 	}
2972*af46caf0SBitterblue Smith 
2973*af46caf0SBitterblue Smith 	for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
2974*af46caf0SBitterblue Smith 	     rfpath++) {
2975*af46caf0SBitterblue Smith 		rtlphy->rfreg_chnlval[rfpath] = rtl_get_rfreg(hw, rfpath,
2976*af46caf0SBitterblue Smith 							      RF_CHNLBW,
2977*af46caf0SBitterblue Smith 							      RFREG_OFFSET_MASK);
2978*af46caf0SBitterblue Smith 		rtlphy->reg_rf3c[rfpath] = rtl_get_rfreg(hw, rfpath, 0x3C,
2979*af46caf0SBitterblue Smith 							 RFREG_OFFSET_MASK);
2980*af46caf0SBitterblue Smith 	}
2981*af46caf0SBitterblue Smith 
2982*af46caf0SBitterblue Smith 	for (i = 0; i < 2; i++)
2983*af46caf0SBitterblue Smith 		rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, "RF 0x18 = 0x%x\n",
2984*af46caf0SBitterblue Smith 			rtlphy->rfreg_chnlval[i]);
2985*af46caf0SBitterblue Smith 
2986*af46caf0SBitterblue Smith 	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "<==\n");
2987*af46caf0SBitterblue Smith }
2988*af46caf0SBitterblue Smith 
rtl92du_phy_check_poweroff(struct ieee80211_hw * hw)2989*af46caf0SBitterblue Smith bool rtl92du_phy_check_poweroff(struct ieee80211_hw *hw)
2990*af46caf0SBitterblue Smith {
2991*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2992*af46caf0SBitterblue Smith 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2993*af46caf0SBitterblue Smith 	u8 u1btmp;
2994*af46caf0SBitterblue Smith 
2995*af46caf0SBitterblue Smith 	if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY) {
2996*af46caf0SBitterblue Smith 		u1btmp = rtl_read_byte(rtlpriv, REG_MAC0);
2997*af46caf0SBitterblue Smith 		rtl_write_byte(rtlpriv, REG_MAC0, u1btmp & ~MAC0_ON);
2998*af46caf0SBitterblue Smith 		return true;
2999*af46caf0SBitterblue Smith 	}
3000*af46caf0SBitterblue Smith 
3001*af46caf0SBitterblue Smith 	mutex_lock(rtlpriv->mutex_for_power_on_off);
3002*af46caf0SBitterblue Smith 	if (rtlhal->interfaceindex == 0) {
3003*af46caf0SBitterblue Smith 		u1btmp = rtl_read_byte(rtlpriv, REG_MAC0);
3004*af46caf0SBitterblue Smith 		rtl_write_byte(rtlpriv, REG_MAC0, u1btmp & ~MAC0_ON);
3005*af46caf0SBitterblue Smith 		u1btmp = rtl_read_byte(rtlpriv, REG_MAC1);
3006*af46caf0SBitterblue Smith 		u1btmp &= MAC1_ON;
3007*af46caf0SBitterblue Smith 	} else {
3008*af46caf0SBitterblue Smith 		u1btmp = rtl_read_byte(rtlpriv, REG_MAC1);
3009*af46caf0SBitterblue Smith 		rtl_write_byte(rtlpriv, REG_MAC1, u1btmp & ~MAC1_ON);
3010*af46caf0SBitterblue Smith 		u1btmp = rtl_read_byte(rtlpriv, REG_MAC0);
3011*af46caf0SBitterblue Smith 		u1btmp &= MAC0_ON;
3012*af46caf0SBitterblue Smith 	}
3013*af46caf0SBitterblue Smith 	if (u1btmp) {
3014*af46caf0SBitterblue Smith 		mutex_unlock(rtlpriv->mutex_for_power_on_off);
3015*af46caf0SBitterblue Smith 		return false;
3016*af46caf0SBitterblue Smith 	}
3017*af46caf0SBitterblue Smith 	u1btmp = rtl_read_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS);
3018*af46caf0SBitterblue Smith 	u1btmp |= BIT(7);
3019*af46caf0SBitterblue Smith 	rtl_write_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS, u1btmp);
3020*af46caf0SBitterblue Smith 	mutex_unlock(rtlpriv->mutex_for_power_on_off);
3021*af46caf0SBitterblue Smith 
3022*af46caf0SBitterblue Smith 	return true;
3023*af46caf0SBitterblue Smith }
3024*af46caf0SBitterblue Smith 
rtl92du_phy_init_pa_bias(struct ieee80211_hw * hw)3025*af46caf0SBitterblue Smith void rtl92du_phy_init_pa_bias(struct ieee80211_hw *hw)
3026*af46caf0SBitterblue Smith {
3027*af46caf0SBitterblue Smith 	struct rtl_priv *rtlpriv = rtl_priv(hw);
3028*af46caf0SBitterblue Smith 	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
3029*af46caf0SBitterblue Smith 	bool is_single_mac = rtlhal->macphymode == SINGLEMAC_SINGLEPHY;
3030*af46caf0SBitterblue Smith 	enum radio_path rf_path;
3031*af46caf0SBitterblue Smith 	u8 val8;
3032*af46caf0SBitterblue Smith 
3033*af46caf0SBitterblue Smith 	read_efuse_byte(hw, 0x3FA, &val8);
3034*af46caf0SBitterblue Smith 
3035*af46caf0SBitterblue Smith 	rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "%s: 0x3FA %#x\n",
3036*af46caf0SBitterblue Smith 		__func__, val8);
3037*af46caf0SBitterblue Smith 
3038*af46caf0SBitterblue Smith 	if (!(val8 & BIT(0)) && (is_single_mac || rtlhal->interfaceindex == 0)) {
3039*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, 0x07401);
3040*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, RF90_PATH_A, RF_AC, RFREG_OFFSET_MASK, 0x70000);
3041*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, RFREG_OFFSET_MASK, 0x0F425);
3042*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, RFREG_OFFSET_MASK, 0x4F425);
3043*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, RFREG_OFFSET_MASK, 0x8F425);
3044*af46caf0SBitterblue Smith 
3045*af46caf0SBitterblue Smith 		/* Back to RX Mode */
3046*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, RF90_PATH_A, RF_AC, RFREG_OFFSET_MASK, 0x30000);
3047*af46caf0SBitterblue Smith 
3048*af46caf0SBitterblue Smith 		rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "2G PA BIAS path A\n");
3049*af46caf0SBitterblue Smith 	}
3050*af46caf0SBitterblue Smith 
3051*af46caf0SBitterblue Smith 	if (!(val8 & BIT(1)) && (is_single_mac || rtlhal->interfaceindex == 1)) {
3052*af46caf0SBitterblue Smith 		rf_path = rtlhal->interfaceindex == 1 ? RF90_PATH_A : RF90_PATH_B;
3053*af46caf0SBitterblue Smith 
3054*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, rf_path, RF_CHNLBW, RFREG_OFFSET_MASK, 0x07401);
3055*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, rf_path, RF_AC, RFREG_OFFSET_MASK, 0x70000);
3056*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, rf_path, RF_IPA, RFREG_OFFSET_MASK, 0x0F425);
3057*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, rf_path, RF_IPA, RFREG_OFFSET_MASK, 0x4F425);
3058*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, rf_path, RF_IPA, RFREG_OFFSET_MASK, 0x8F425);
3059*af46caf0SBitterblue Smith 
3060*af46caf0SBitterblue Smith 		/* Back to RX Mode */
3061*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, rf_path, RF_AC, RFREG_OFFSET_MASK, 0x30000);
3062*af46caf0SBitterblue Smith 
3063*af46caf0SBitterblue Smith 		rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "2G PA BIAS path B\n");
3064*af46caf0SBitterblue Smith 	}
3065*af46caf0SBitterblue Smith 
3066*af46caf0SBitterblue Smith 	if (!(val8 & BIT(2)) && (is_single_mac || rtlhal->interfaceindex == 0)) {
3067*af46caf0SBitterblue Smith 		/* 5GL_channel */
3068*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, 0x17524);
3069*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, RF90_PATH_A, RF_AC, RFREG_OFFSET_MASK, 0x70000);
3070*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, RFREG_OFFSET_MASK, 0x0F496);
3071*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, RFREG_OFFSET_MASK, 0x4F496);
3072*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, RFREG_OFFSET_MASK, 0x8F496);
3073*af46caf0SBitterblue Smith 
3074*af46caf0SBitterblue Smith 		/* 5GM_channel */
3075*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, 0x37564);
3076*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, RF90_PATH_A, RF_AC, RFREG_OFFSET_MASK, 0x70000);
3077*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, RFREG_OFFSET_MASK, 0x0F496);
3078*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, RFREG_OFFSET_MASK, 0x4F496);
3079*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, RFREG_OFFSET_MASK, 0x8F496);
3080*af46caf0SBitterblue Smith 
3081*af46caf0SBitterblue Smith 		/* 5GH_channel */
3082*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, 0x57595);
3083*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, RF90_PATH_A, RF_AC, RFREG_OFFSET_MASK, 0x70000);
3084*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, RFREG_OFFSET_MASK, 0x0F496);
3085*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, RFREG_OFFSET_MASK, 0x4F496);
3086*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, RFREG_OFFSET_MASK, 0x8F496);
3087*af46caf0SBitterblue Smith 
3088*af46caf0SBitterblue Smith 		/* Back to RX Mode */
3089*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, RF90_PATH_A, RF_AC, RFREG_OFFSET_MASK, 0x30000);
3090*af46caf0SBitterblue Smith 
3091*af46caf0SBitterblue Smith 		rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "5G PA BIAS path A\n");
3092*af46caf0SBitterblue Smith 	}
3093*af46caf0SBitterblue Smith 
3094*af46caf0SBitterblue Smith 	if (!(val8 & BIT(3)) && (is_single_mac || rtlhal->interfaceindex == 1)) {
3095*af46caf0SBitterblue Smith 		rf_path = rtlhal->interfaceindex == 1 ? RF90_PATH_A : RF90_PATH_B;
3096*af46caf0SBitterblue Smith 
3097*af46caf0SBitterblue Smith 		/* 5GL_channel */
3098*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, rf_path, RF_CHNLBW, RFREG_OFFSET_MASK, 0x17524);
3099*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, rf_path, RF_AC, RFREG_OFFSET_MASK, 0x70000);
3100*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, rf_path, RF_IPA, RFREG_OFFSET_MASK, 0x0F496);
3101*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, rf_path, RF_IPA, RFREG_OFFSET_MASK, 0x4F496);
3102*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, rf_path, RF_IPA, RFREG_OFFSET_MASK, 0x8F496);
3103*af46caf0SBitterblue Smith 
3104*af46caf0SBitterblue Smith 		/* 5GM_channel */
3105*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, rf_path, RF_CHNLBW, RFREG_OFFSET_MASK, 0x37564);
3106*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, rf_path, RF_AC, RFREG_OFFSET_MASK, 0x70000);
3107*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, rf_path, RF_IPA, RFREG_OFFSET_MASK, 0x0F496);
3108*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, rf_path, RF_IPA, RFREG_OFFSET_MASK, 0x4F496);
3109*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, rf_path, RF_IPA, RFREG_OFFSET_MASK, 0x8F496);
3110*af46caf0SBitterblue Smith 
3111*af46caf0SBitterblue Smith 		/* 5GH_channel */
3112*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, rf_path, RF_CHNLBW, RFREG_OFFSET_MASK, 0x57595);
3113*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, rf_path, RF_AC, RFREG_OFFSET_MASK, 0x70000);
3114*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, rf_path, RF_IPA, RFREG_OFFSET_MASK, 0x0F496);
3115*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, rf_path, RF_IPA, RFREG_OFFSET_MASK, 0x4F496);
3116*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, rf_path, RF_IPA, RFREG_OFFSET_MASK, 0x8F496);
3117*af46caf0SBitterblue Smith 
3118*af46caf0SBitterblue Smith 		/* Back to RX Mode */
3119*af46caf0SBitterblue Smith 		rtl_set_rfreg(hw, rf_path, RF_AC, RFREG_OFFSET_MASK, 0x30000);
3120*af46caf0SBitterblue Smith 
3121*af46caf0SBitterblue Smith 		rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "5G PA BIAS path B\n");
3122*af46caf0SBitterblue Smith 	}
3123*af46caf0SBitterblue Smith }
3124