1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20 #define _RTL8188E_PHYCFG_C_
21 
22 #include <osdep_service.h>
23 #include <drv_types.h>
24 #include <rtw_iol.h>
25 #include <rtl8188e_hal.h>
26 #include <rf.h>
27 #include <phy.h>
28 
29 #define MAX_PRECMD_CNT 16
30 #define MAX_RFDEPENDCMD_CNT 16
31 #define MAX_POSTCMD_CNT 16
32 
33 #define MAX_DOZE_WAITING_TIMES_9x 64
34 
cal_bit_shift(u32 bitmask)35 static u32 cal_bit_shift(u32 bitmask)
36 {
37 	u32 i;
38 
39 	for (i = 0; i <= 31; i++) {
40 		if (((bitmask >> i) & 0x1) == 1)
41 			break;
42 	}
43 	return i;
44 }
45 
phy_query_bb_reg(struct adapter * adapt,u32 regaddr,u32 bitmask)46 u32 phy_query_bb_reg(struct adapter *adapt, u32 regaddr, u32 bitmask)
47 {
48 	u32 return_value = 0, original_value, bit_shift;
49 
50 	original_value = usb_read32(adapt, regaddr);
51 	bit_shift = cal_bit_shift(bitmask);
52 	return_value = (original_value & bitmask) >> bit_shift;
53 	return return_value;
54 }
55 
phy_set_bb_reg(struct adapter * adapt,u32 regaddr,u32 bitmask,u32 data)56 void phy_set_bb_reg(struct adapter *adapt, u32 regaddr, u32 bitmask, u32 data)
57 {
58 	u32 original_value, bit_shift;
59 
60 	if (bitmask != bMaskDWord) { /* if not "double word" write */
61 		original_value = usb_read32(adapt, regaddr);
62 		bit_shift = cal_bit_shift(bitmask);
63 		data = (original_value & (~bitmask)) | (data << bit_shift);
64 	}
65 
66 	usb_write32(adapt, regaddr, data);
67 }
68 
rf_serial_read(struct adapter * adapt,enum rf_radio_path rfpath,u32 offset)69 static u32 rf_serial_read(struct adapter *adapt,
70 			enum rf_radio_path rfpath, u32 offset)
71 {
72 	u32 ret = 0;
73 	struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
74 	struct bb_reg_def *phyreg = &hal_data->PHYRegDef[rfpath];
75 	u32 tmplong, tmplong2;
76 	u8 rfpi_enable = 0;
77 
78 	offset &= 0xff;
79 
80 	tmplong = phy_query_bb_reg(adapt, rFPGA0_XA_HSSIParameter2, bMaskDWord);
81 	if (rfpath == RF_PATH_A)
82 		tmplong2 = tmplong;
83 	else
84 		tmplong2 = phy_query_bb_reg(adapt, phyreg->rfHSSIPara2,
85 					    bMaskDWord);
86 
87 	tmplong2 = (tmplong2 & (~bLSSIReadAddress)) |
88 		   (offset<<23) | bLSSIReadEdge;
89 
90 	phy_set_bb_reg(adapt, rFPGA0_XA_HSSIParameter2, bMaskDWord,
91 		       tmplong&(~bLSSIReadEdge));
92 	udelay(10);
93 
94 	phy_set_bb_reg(adapt, phyreg->rfHSSIPara2, bMaskDWord, tmplong2);
95 	udelay(100);
96 
97 	udelay(10);
98 
99 	if (rfpath == RF_PATH_A)
100 		rfpi_enable = (u8)phy_query_bb_reg(adapt, rFPGA0_XA_HSSIParameter1, BIT(8));
101 	else if (rfpath == RF_PATH_B)
102 		rfpi_enable = (u8)phy_query_bb_reg(adapt, rFPGA0_XB_HSSIParameter1, BIT(8));
103 
104 	if (rfpi_enable)
105 		ret = phy_query_bb_reg(adapt, phyreg->rfLSSIReadBackPi,
106 				       bLSSIReadBackData);
107 	else
108 		ret = phy_query_bb_reg(adapt, phyreg->rfLSSIReadBack,
109 				       bLSSIReadBackData);
110 	return ret;
111 }
112 
rf_serial_write(struct adapter * adapt,enum rf_radio_path rfpath,u32 offset,u32 data)113 static void rf_serial_write(struct adapter *adapt,
114 			    enum rf_radio_path rfpath, u32 offset,
115 			    u32 data)
116 {
117 	u32 data_and_addr = 0;
118 	struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
119 	struct bb_reg_def *phyreg = &hal_data->PHYRegDef[rfpath];
120 
121 	offset &= 0xff;
122 	data_and_addr = ((offset<<20) | (data&0x000fffff)) & 0x0fffffff;
123 	phy_set_bb_reg(adapt, phyreg->rf3wireOffset, bMaskDWord, data_and_addr);
124 }
125 
phy_query_rf_reg(struct adapter * adapt,enum rf_radio_path rf_path,u32 reg_addr,u32 bit_mask)126 u32 phy_query_rf_reg(struct adapter *adapt, enum rf_radio_path rf_path,
127 		     u32 reg_addr, u32 bit_mask)
128 {
129 	u32 original_value, readback_value, bit_shift;
130 
131 	original_value = rf_serial_read(adapt, rf_path, reg_addr);
132 	bit_shift =  cal_bit_shift(bit_mask);
133 	readback_value = (original_value & bit_mask) >> bit_shift;
134 	return readback_value;
135 }
136 
phy_set_rf_reg(struct adapter * adapt,enum rf_radio_path rf_path,u32 reg_addr,u32 bit_mask,u32 data)137 void phy_set_rf_reg(struct adapter *adapt, enum rf_radio_path rf_path,
138 		     u32 reg_addr, u32 bit_mask, u32 data)
139 {
140 	u32 original_value, bit_shift;
141 
142 	/*  RF data is 12 bits only */
143 	if (bit_mask != bRFRegOffsetMask) {
144 		original_value = rf_serial_read(adapt, rf_path, reg_addr);
145 		bit_shift =  cal_bit_shift(bit_mask);
146 		data = (original_value & (~bit_mask)) | (data << bit_shift);
147 	}
148 
149 	rf_serial_write(adapt, rf_path, reg_addr, data);
150 }
151 
get_tx_power_index(struct adapter * adapt,u8 channel,u8 * cck_pwr,u8 * ofdm_pwr,u8 * bw20_pwr,u8 * bw40_pwr)152 static void get_tx_power_index(struct adapter *adapt, u8 channel, u8 *cck_pwr,
153 			       u8 *ofdm_pwr, u8 *bw20_pwr, u8 *bw40_pwr)
154 {
155 	struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
156 	u8 index = (channel - 1);
157 	u8 TxCount = 0, path_nums;
158 
159 	if ((RF_1T2R == hal_data->rf_type) || (RF_1T1R == hal_data->rf_type))
160 		path_nums = 1;
161 	else
162 		path_nums = 2;
163 
164 	for (TxCount = 0; TxCount < path_nums; TxCount++) {
165 		if (TxCount == RF_PATH_A) {
166 			cck_pwr[TxCount] = hal_data->Index24G_CCK_Base[TxCount][index];
167 			ofdm_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+
168 					    hal_data->OFDM_24G_Diff[TxCount][RF_PATH_A];
169 
170 			bw20_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+
171 					    hal_data->BW20_24G_Diff[TxCount][RF_PATH_A];
172 			bw40_pwr[TxCount] = hal_data->Index24G_BW40_Base[TxCount][index];
173 		} else if (TxCount == RF_PATH_B) {
174 			cck_pwr[TxCount] = hal_data->Index24G_CCK_Base[TxCount][index];
175 			ofdm_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+
176 			hal_data->BW20_24G_Diff[RF_PATH_A][index]+
177 			hal_data->BW20_24G_Diff[TxCount][index];
178 
179 			bw20_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+
180 			hal_data->BW20_24G_Diff[TxCount][RF_PATH_A]+
181 			hal_data->BW20_24G_Diff[TxCount][index];
182 			bw40_pwr[TxCount] = hal_data->Index24G_BW40_Base[TxCount][index];
183 		} else if (TxCount == RF_PATH_C) {
184 			cck_pwr[TxCount] = hal_data->Index24G_CCK_Base[TxCount][index];
185 			ofdm_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+
186 			hal_data->BW20_24G_Diff[RF_PATH_A][index]+
187 			hal_data->BW20_24G_Diff[RF_PATH_B][index]+
188 			hal_data->BW20_24G_Diff[TxCount][index];
189 
190 			bw20_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+
191 			hal_data->BW20_24G_Diff[RF_PATH_A][index]+
192 			hal_data->BW20_24G_Diff[RF_PATH_B][index]+
193 			hal_data->BW20_24G_Diff[TxCount][index];
194 			bw40_pwr[TxCount] = hal_data->Index24G_BW40_Base[TxCount][index];
195 		} else if (TxCount == RF_PATH_D) {
196 			cck_pwr[TxCount] = hal_data->Index24G_CCK_Base[TxCount][index];
197 			ofdm_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+
198 			hal_data->BW20_24G_Diff[RF_PATH_A][index]+
199 			hal_data->BW20_24G_Diff[RF_PATH_B][index]+
200 			hal_data->BW20_24G_Diff[RF_PATH_C][index]+
201 			hal_data->BW20_24G_Diff[TxCount][index];
202 
203 			bw20_pwr[TxCount] = hal_data->Index24G_BW40_Base[RF_PATH_A][index]+
204 			hal_data->BW20_24G_Diff[RF_PATH_A][index]+
205 			hal_data->BW20_24G_Diff[RF_PATH_B][index]+
206 			hal_data->BW20_24G_Diff[RF_PATH_C][index]+
207 			hal_data->BW20_24G_Diff[TxCount][index];
208 			bw40_pwr[TxCount] = hal_data->Index24G_BW40_Base[TxCount][index];
209 		}
210 	}
211 }
212 
phy_power_index_check(struct adapter * adapt,u8 channel,u8 * cck_pwr,u8 * ofdm_pwr,u8 * bw20_pwr,u8 * bw40_pwr)213 static void phy_power_index_check(struct adapter *adapt, u8 channel,
214 				  u8 *cck_pwr, u8 *ofdm_pwr, u8 *bw20_pwr,
215 				  u8 *bw40_pwr)
216 {
217 	struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
218 
219 	hal_data->CurrentCckTxPwrIdx = cck_pwr[0];
220 	hal_data->CurrentOfdm24GTxPwrIdx = ofdm_pwr[0];
221 	hal_data->CurrentBW2024GTxPwrIdx = bw20_pwr[0];
222 	hal_data->CurrentBW4024GTxPwrIdx = bw40_pwr[0];
223 }
224 
phy_set_tx_power_level(struct adapter * adapt,u8 channel)225 void phy_set_tx_power_level(struct adapter *adapt, u8 channel)
226 {
227 	u8 cck_pwr[MAX_TX_COUNT] = {0};
228 	u8 ofdm_pwr[MAX_TX_COUNT] = {0};/*  [0]:RF-A, [1]:RF-B */
229 	u8 bw20_pwr[MAX_TX_COUNT] = {0};
230 	u8 bw40_pwr[MAX_TX_COUNT] = {0};
231 
232 	get_tx_power_index(adapt, channel, &cck_pwr[0], &ofdm_pwr[0],
233 			   &bw20_pwr[0], &bw40_pwr[0]);
234 
235 	phy_power_index_check(adapt, channel, &cck_pwr[0], &ofdm_pwr[0],
236 			      &bw20_pwr[0], &bw40_pwr[0]);
237 
238 	rtl88eu_phy_rf6052_set_cck_txpower(adapt, &cck_pwr[0]);
239 	rtl88eu_phy_rf6052_set_ofdm_txpower(adapt, &ofdm_pwr[0], &bw20_pwr[0],
240 					  &bw40_pwr[0], channel);
241 }
242 
phy_set_bw_mode_callback(struct adapter * adapt)243 static void phy_set_bw_mode_callback(struct adapter *adapt)
244 {
245 	struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
246 	u8 reg_bw_opmode;
247 	u8 reg_prsr_rsc;
248 
249 	if (hal_data->rf_chip == RF_PSEUDO_11N)
250 		return;
251 
252 	/*  There is no 40MHz mode in RF_8225. */
253 	if (hal_data->rf_chip == RF_8225)
254 		return;
255 
256 	if (adapt->bDriverStopped)
257 		return;
258 
259 	/* Set MAC register */
260 
261 	reg_bw_opmode = usb_read8(adapt, REG_BWOPMODE);
262 	reg_prsr_rsc = usb_read8(adapt, REG_RRSR+2);
263 
264 	switch (hal_data->CurrentChannelBW) {
265 	case HT_CHANNEL_WIDTH_20:
266 		reg_bw_opmode |= BW_OPMODE_20MHZ;
267 		usb_write8(adapt, REG_BWOPMODE, reg_bw_opmode);
268 		break;
269 	case HT_CHANNEL_WIDTH_40:
270 		reg_bw_opmode &= ~BW_OPMODE_20MHZ;
271 		usb_write8(adapt, REG_BWOPMODE, reg_bw_opmode);
272 		reg_prsr_rsc = (reg_prsr_rsc&0x90) |
273 			       (hal_data->nCur40MhzPrimeSC<<5);
274 		usb_write8(adapt, REG_RRSR+2, reg_prsr_rsc);
275 		break;
276 	default:
277 		break;
278 	}
279 
280 	/* Set PHY related register */
281 	switch (hal_data->CurrentChannelBW) {
282 	case HT_CHANNEL_WIDTH_20:
283 		phy_set_bb_reg(adapt, rFPGA0_RFMOD, bRFMOD, 0x0);
284 		phy_set_bb_reg(adapt, rFPGA1_RFMOD, bRFMOD, 0x0);
285 		break;
286 	case HT_CHANNEL_WIDTH_40:
287 		phy_set_bb_reg(adapt, rFPGA0_RFMOD, bRFMOD, 0x1);
288 		phy_set_bb_reg(adapt, rFPGA1_RFMOD, bRFMOD, 0x1);
289 		/* Set Control channel to upper or lower.
290 		 * These settings are required only for 40MHz
291 		 */
292 		phy_set_bb_reg(adapt, rCCK0_System, bCCKSideBand,
293 		    (hal_data->nCur40MhzPrimeSC>>1));
294 		phy_set_bb_reg(adapt, rOFDM1_LSTF, 0xC00,
295 			       hal_data->nCur40MhzPrimeSC);
296 		phy_set_bb_reg(adapt, 0x818, (BIT(26) | BIT(27)),
297 		   (hal_data->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
298 		break;
299 	default:
300 		break;
301 	}
302 
303 	/* Set RF related register */
304 	if (hal_data->rf_chip == RF_6052)
305 		rtl88eu_phy_rf6052_set_bandwidth(adapt, hal_data->CurrentChannelBW);
306 }
307 
phy_set_bw_mode(struct adapter * adapt,enum ht_channel_width bandwidth,unsigned char offset)308 void phy_set_bw_mode(struct adapter *adapt, enum ht_channel_width bandwidth,
309 		     unsigned char offset)
310 {
311 	struct hal_data_8188e	*hal_data = GET_HAL_DATA(adapt);
312 	enum ht_channel_width tmp_bw = hal_data->CurrentChannelBW;
313 
314 	hal_data->CurrentChannelBW = bandwidth;
315 	hal_data->nCur40MhzPrimeSC = offset;
316 
317 	if ((!adapt->bDriverStopped) && (!adapt->bSurpriseRemoved))
318 		phy_set_bw_mode_callback(adapt);
319 	else
320 		hal_data->CurrentChannelBW = tmp_bw;
321 }
322 
phy_sw_chnl_callback(struct adapter * adapt,u8 channel)323 static void phy_sw_chnl_callback(struct adapter *adapt, u8 channel)
324 {
325 	u8 rf_path;
326 	u32 param1, param2;
327 	struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
328 
329 	if (adapt->bNotifyChannelChange)
330 		DBG_88E("[%s] ch = %d\n", __func__, channel);
331 
332 	phy_set_tx_power_level(adapt, channel);
333 
334 	param1 = RF_CHNLBW;
335 	param2 = channel;
336 	for (rf_path = 0; rf_path < hal_data->NumTotalRFPath; rf_path++) {
337 		hal_data->RfRegChnlVal[rf_path] = (hal_data->RfRegChnlVal[rf_path] &
338 						  0xfffffc00) | param2;
339 		phy_set_rf_reg(adapt, (enum rf_radio_path)rf_path, param1,
340 			       bRFRegOffsetMask, hal_data->RfRegChnlVal[rf_path]);
341 	}
342 }
343 
phy_sw_chnl(struct adapter * adapt,u8 channel)344 void phy_sw_chnl(struct adapter *adapt, u8 channel)
345 {
346 	struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
347 	u8 tmpchannel = hal_data->CurrentChannel;
348 
349 	if (hal_data->rf_chip == RF_PSEUDO_11N)
350 		return;
351 
352 	if (channel == 0)
353 		channel = 1;
354 
355 	hal_data->CurrentChannel = channel;
356 
357 	if ((!adapt->bDriverStopped) && (!adapt->bSurpriseRemoved))
358 		phy_sw_chnl_callback(adapt, channel);
359 	else
360 		hal_data->CurrentChannel = tmpchannel;
361 }
362 
363 #define ODM_TXPWRTRACK_MAX_IDX_88E  6
364 
get_right_chnl_for_iqk(u8 chnl)365 static u8 get_right_chnl_for_iqk(u8 chnl)
366 {
367 	u8 place;
368 	u8 channel_all[ODM_TARGET_CHNL_NUM_2G_5G] = {
369 		36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64,
370 		100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122,
371 		124, 126, 128, 130, 132, 134, 136, 138, 140, 149, 151, 153,
372 		155, 157, 159, 161, 163, 165
373 	};
374 
375 	if (chnl > 14) {
376 		for (place = 0; place < sizeof(channel_all); place++) {
377 			if (channel_all[place] == chnl)
378 				return ++place;
379 		}
380 	}
381 	return 0;
382 }
383 
rtl88eu_dm_txpower_track_adjust(struct odm_dm_struct * dm_odm,u8 type,u8 * direction,u32 * out_write_val)384 void rtl88eu_dm_txpower_track_adjust(struct odm_dm_struct *dm_odm, u8 type,
385 				     u8 *direction, u32 *out_write_val)
386 {
387 	u8 pwr_value = 0;
388 	/*  Tx power tracking BB swing table. */
389 	if (type == 0) { /* For OFDM adjust */
390 		ODM_RT_TRACE(dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
391 			     ("BbSwingIdxOfdm = %d BbSwingFlagOfdm=%d\n",
392 			     dm_odm->BbSwingIdxOfdm, dm_odm->BbSwingFlagOfdm));
393 
394 		if (dm_odm->BbSwingIdxOfdm <= dm_odm->BbSwingIdxOfdmBase) {
395 			*direction = 1;
396 			pwr_value = dm_odm->BbSwingIdxOfdmBase -
397 				     dm_odm->BbSwingIdxOfdm;
398 		} else {
399 			*direction = 2;
400 			pwr_value = dm_odm->BbSwingIdxOfdm -
401 				     dm_odm->BbSwingIdxOfdmBase;
402 		}
403 
404 	} else if (type == 1) { /* For CCK adjust. */
405 		ODM_RT_TRACE(dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
406 			     ("dm_odm->BbSwingIdxCck = %d dm_odm->BbSwingIdxCckBase = %d\n",
407 			     dm_odm->BbSwingIdxCck, dm_odm->BbSwingIdxCckBase));
408 
409 		if (dm_odm->BbSwingIdxCck <= dm_odm->BbSwingIdxCckBase) {
410 			*direction = 1;
411 			pwr_value = dm_odm->BbSwingIdxCckBase -
412 				     dm_odm->BbSwingIdxCck;
413 		} else {
414 			*direction = 2;
415 			pwr_value = dm_odm->BbSwingIdxCck -
416 				     dm_odm->BbSwingIdxCckBase;
417 		}
418 
419 	}
420 
421 	if (pwr_value >= ODM_TXPWRTRACK_MAX_IDX_88E && *direction == 1)
422 		pwr_value = ODM_TXPWRTRACK_MAX_IDX_88E;
423 
424 	*out_write_val = pwr_value | (pwr_value<<8) | (pwr_value<<16) |
425 			 (pwr_value<<24);
426 }
427 
dm_txpwr_track_setpwr(struct odm_dm_struct * dm_odm)428 static void dm_txpwr_track_setpwr(struct odm_dm_struct *dm_odm)
429 {
430 	if (dm_odm->BbSwingFlagOfdm || dm_odm->BbSwingFlagCck) {
431 		ODM_RT_TRACE(dm_odm, ODM_COMP_TX_PWR_TRACK, ODM_DBG_LOUD,
432 			     ("dm_txpwr_track_setpwr CH=%d\n", *(dm_odm->pChannel)));
433 		phy_set_tx_power_level(dm_odm->Adapter, *(dm_odm->pChannel));
434 		dm_odm->BbSwingFlagOfdm = false;
435 		dm_odm->BbSwingFlagCck = false;
436 	}
437 }
438 
rtl88eu_dm_txpower_tracking_callback_thermalmeter(struct adapter * adapt)439 void rtl88eu_dm_txpower_tracking_callback_thermalmeter(struct adapter *adapt)
440 {
441 	struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
442 	u8 thermal_val = 0, delta, delta_lck, delta_iqk, offset;
443 	u8 thermal_avg_count = 0;
444 	u32 thermal_avg = 0;
445 	s32 ele_d, temp_cck;
446 	s8 ofdm_index[2], cck_index = 0;
447 	s8 ofdm_index_old[2] = {0, 0}, cck_index_old = 0;
448 	u32 i = 0, j = 0;
449 	bool is2t = false;
450 
451 	u8 ofdm_min_index = 6, rf; /* OFDM BB Swing should be less than +3.0dB */
452 	s8 ofdm_index_mapping[2][index_mapping_NUM_88E] = {
453 		/* 2.4G, decrease power */
454 		{0, 0, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11},
455 		/* 2.4G, increase power */
456 		{0, 0, -1, -2, -3, -4, -4, -4, -4, -5, -7, -8, -9, -9, -10},
457 	};
458 	u8 thermal_mapping[2][index_mapping_NUM_88E] = {
459 		/* 2.4G, decrease power */
460 		{0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 27},
461 		/* 2.4G, increase power */
462 		{0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 25, 25, 25},
463 	};
464 	struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
465 
466 	dm_txpwr_track_setpwr(dm_odm);
467 
468 	dm_odm->RFCalibrateInfo.TXPowerTrackingCallbackCnt++;
469 	dm_odm->RFCalibrateInfo.bTXPowerTrackingInit = true;
470 
471 	dm_odm->RFCalibrateInfo.RegA24 = 0x090e1317;
472 
473 	thermal_val = (u8)phy_query_rf_reg(adapt, RF_PATH_A,
474 					   RF_T_METER_88E, 0xfc00);
475 
476 	if (is2t)
477 		rf = 2;
478 	else
479 		rf = 1;
480 
481 	if (thermal_val) {
482 		/* Query OFDM path A default setting */
483 		ele_d = phy_query_bb_reg(adapt, rOFDM0_XATxIQImbalance, bMaskDWord)&bMaskOFDM_D;
484 		for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) {
485 			if (ele_d == (OFDMSwingTable[i]&bMaskOFDM_D)) {
486 				ofdm_index_old[0] = (u8)i;
487 				dm_odm->BbSwingIdxOfdmBase = (u8)i;
488 				break;
489 			}
490 		}
491 
492 		/* Query OFDM path B default setting */
493 		if (is2t) {
494 			ele_d = phy_query_bb_reg(adapt, rOFDM0_XBTxIQImbalance, bMaskDWord)&bMaskOFDM_D;
495 			for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) {
496 				if (ele_d == (OFDMSwingTable[i]&bMaskOFDM_D)) {
497 					ofdm_index_old[1] = (u8)i;
498 					break;
499 				}
500 			}
501 		}
502 
503 		/* Query CCK default setting From 0xa24 */
504 		temp_cck = dm_odm->RFCalibrateInfo.RegA24;
505 
506 		for (i = 0; i < CCK_TABLE_SIZE; i++) {
507 			if ((dm_odm->RFCalibrateInfo.bCCKinCH14 &&
508 				memcmp(&temp_cck, &CCKSwingTable_Ch14[i][2], 4)) ||
509 				memcmp(&temp_cck, &CCKSwingTable_Ch1_Ch13[i][2], 4)) {
510 					cck_index_old = (u8)i;
511 					dm_odm->BbSwingIdxCckBase = (u8)i;
512 					break;
513 			}
514 		}
515 
516 		if (!dm_odm->RFCalibrateInfo.ThermalValue) {
517 			dm_odm->RFCalibrateInfo.ThermalValue = hal_data->EEPROMThermalMeter;
518 			dm_odm->RFCalibrateInfo.ThermalValue_LCK = thermal_val;
519 			dm_odm->RFCalibrateInfo.ThermalValue_IQK = thermal_val;
520 
521 			for (i = 0; i < rf; i++)
522 				dm_odm->RFCalibrateInfo.OFDM_index[i] = ofdm_index_old[i];
523 			dm_odm->RFCalibrateInfo.CCK_index = cck_index_old;
524 		}
525 
526 		/* calculate average thermal meter */
527 		dm_odm->RFCalibrateInfo.ThermalValue_AVG[dm_odm->RFCalibrateInfo.ThermalValue_AVG_index] = thermal_val;
528 		dm_odm->RFCalibrateInfo.ThermalValue_AVG_index++;
529 		if (dm_odm->RFCalibrateInfo.ThermalValue_AVG_index == AVG_THERMAL_NUM_88E)
530 			dm_odm->RFCalibrateInfo.ThermalValue_AVG_index = 0;
531 
532 		for (i = 0; i < AVG_THERMAL_NUM_88E; i++) {
533 			if (dm_odm->RFCalibrateInfo.ThermalValue_AVG[i]) {
534 				thermal_avg += dm_odm->RFCalibrateInfo.ThermalValue_AVG[i];
535 				thermal_avg_count++;
536 			}
537 		}
538 
539 		if (thermal_avg_count)
540 			thermal_val = (u8)(thermal_avg / thermal_avg_count);
541 
542 		if (dm_odm->RFCalibrateInfo.bDoneTxpower &&
543 			!dm_odm->RFCalibrateInfo.bReloadtxpowerindex)
544 			delta = abs(thermal_val - dm_odm->RFCalibrateInfo.ThermalValue);
545 		else {
546 			delta = abs(thermal_val - hal_data->EEPROMThermalMeter);
547 			if (dm_odm->RFCalibrateInfo.bReloadtxpowerindex) {
548 				dm_odm->RFCalibrateInfo.bReloadtxpowerindex = false;
549 				dm_odm->RFCalibrateInfo.bDoneTxpower = false;
550 			}
551 		}
552 
553 		delta_lck = abs(dm_odm->RFCalibrateInfo.ThermalValue_LCK - thermal_val);
554 		delta_iqk = abs(dm_odm->RFCalibrateInfo.ThermalValue_IQK - thermal_val);
555 
556 		/* Delta temperature is equal to or larger than 20 centigrade.*/
557 		if ((delta_lck >= 8)) {
558 			dm_odm->RFCalibrateInfo.ThermalValue_LCK = thermal_val;
559 			rtl88eu_phy_lc_calibrate(adapt);
560 		}
561 
562 		if (delta > 0 && dm_odm->RFCalibrateInfo.TxPowerTrackControl) {
563 			delta = abs(hal_data->EEPROMThermalMeter - thermal_val);
564 
565 			/* calculate new OFDM / CCK offset */
566 			if (thermal_val > hal_data->EEPROMThermalMeter)
567 				j = 1;
568 			else
569 				j = 0;
570 			for (offset = 0; offset < index_mapping_NUM_88E; offset++) {
571 				if (delta < thermal_mapping[j][offset]) {
572 					if (offset != 0)
573 						offset--;
574 					break;
575 				}
576 			}
577 			if (offset >= index_mapping_NUM_88E)
578 				offset = index_mapping_NUM_88E-1;
579 
580 			/* Updating ofdm_index values with new OFDM / CCK offset */
581 			for (i = 0; i < rf; i++) {
582 				ofdm_index[i] = dm_odm->RFCalibrateInfo.OFDM_index[i] + ofdm_index_mapping[j][offset];
583 				if (ofdm_index[i] > OFDM_TABLE_SIZE_92D-1)
584 					ofdm_index[i] = OFDM_TABLE_SIZE_92D-1;
585 				else if (ofdm_index[i] < ofdm_min_index)
586 					ofdm_index[i] = ofdm_min_index;
587 			}
588 
589 			cck_index = dm_odm->RFCalibrateInfo.CCK_index + ofdm_index_mapping[j][offset];
590 			if (cck_index > CCK_TABLE_SIZE-1)
591 				cck_index = CCK_TABLE_SIZE-1;
592 			else if (cck_index < 0)
593 				cck_index = 0;
594 
595 			/* 2 temporarily remove bNOPG */
596 			/* Config by SwingTable */
597 			if (dm_odm->RFCalibrateInfo.TxPowerTrackControl) {
598 				dm_odm->RFCalibrateInfo.bDoneTxpower = true;
599 
600 				/*  Revse TX power table. */
601 				dm_odm->BbSwingIdxOfdm = (u8)ofdm_index[0];
602 				dm_odm->BbSwingIdxCck = (u8)cck_index;
603 
604 				if (dm_odm->BbSwingIdxOfdmCurrent != dm_odm->BbSwingIdxOfdm) {
605 					dm_odm->BbSwingIdxOfdmCurrent = dm_odm->BbSwingIdxOfdm;
606 					dm_odm->BbSwingFlagOfdm = true;
607 				}
608 
609 				if (dm_odm->BbSwingIdxCckCurrent != dm_odm->BbSwingIdxCck) {
610 					dm_odm->BbSwingIdxCckCurrent = dm_odm->BbSwingIdxCck;
611 					dm_odm->BbSwingFlagCck = true;
612 				}
613 			}
614 		}
615 
616 		/* Delta temperature is equal to or larger than 20 centigrade.*/
617 		if (delta_iqk >= 8) {
618 			dm_odm->RFCalibrateInfo.ThermalValue_IQK = thermal_val;
619 			rtl88eu_phy_iq_calibrate(adapt, false);
620 		}
621 		/* update thermal meter value */
622 		if (dm_odm->RFCalibrateInfo.TxPowerTrackControl)
623 			dm_odm->RFCalibrateInfo.ThermalValue = thermal_val;
624 	}
625 	dm_odm->RFCalibrateInfo.TXPowercount = 0;
626 }
627 
628 #define MAX_TOLERANCE 5
629 
phy_path_a_iqk(struct adapter * adapt,bool config_pathb)630 static u8 phy_path_a_iqk(struct adapter *adapt, bool config_pathb)
631 {
632 	u32 reg_eac, reg_e94, reg_e9c;
633 	u8 result = 0x00;
634 
635 	/* 1 Tx IQK */
636 	/* path-A IQK setting */
637 	phy_set_bb_reg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1c);
638 	phy_set_bb_reg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x30008c1c);
639 	phy_set_bb_reg(adapt, rTx_IQK_PI_A, bMaskDWord, 0x8214032a);
640 	phy_set_bb_reg(adapt, rRx_IQK_PI_A, bMaskDWord, 0x28160000);
641 
642 	/* LO calibration setting */
643 	phy_set_bb_reg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x00462911);
644 
645 	/* One shot, path A LOK & IQK */
646 	phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
647 	phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
648 
649 	mdelay(IQK_DELAY_TIME_88E);
650 
651 	reg_eac = phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord);
652 	reg_e94 = phy_query_bb_reg(adapt, rTx_Power_Before_IQK_A, bMaskDWord);
653 	reg_e9c = phy_query_bb_reg(adapt, rTx_Power_After_IQK_A, bMaskDWord);
654 
655 	if (!(reg_eac & BIT(28)) &&
656 	    (((reg_e94 & 0x03FF0000)>>16) != 0x142) &&
657 	    (((reg_e9c & 0x03FF0000)>>16) != 0x42))
658 		result |= 0x01;
659 	return result;
660 }
661 
phy_path_a_rx_iqk(struct adapter * adapt,bool configPathB)662 static u8 phy_path_a_rx_iqk(struct adapter *adapt, bool configPathB)
663 {
664 	u32 reg_eac, reg_e94, reg_e9c, reg_ea4, u4tmp;
665 	u8 result = 0x00;
666 	struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
667 	struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
668 
669 	/* 1 Get TXIMR setting */
670 	/* modify RXIQK mode table */
671 	phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000);
672 	phy_set_rf_reg(adapt, RF_PATH_A, RF_WE_LUT, bRFRegOffsetMask, 0x800a0);
673 	phy_set_rf_reg(adapt, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000);
674 	phy_set_rf_reg(adapt, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f);
675 	phy_set_rf_reg(adapt, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf117B);
676 
677 	/* PA,PAD off */
678 	phy_set_rf_reg(adapt, RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x980);
679 	phy_set_rf_reg(adapt, RF_PATH_A, 0x56, bRFRegOffsetMask, 0x51000);
680 
681 	phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
682 
683 	/* IQK setting */
684 	phy_set_bb_reg(adapt, rTx_IQK, bMaskDWord, 0x01007c00);
685 	phy_set_bb_reg(adapt, rRx_IQK, bMaskDWord, 0x81004800);
686 
687 	/* path-A IQK setting */
688 	phy_set_bb_reg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1c);
689 	phy_set_bb_reg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x30008c1c);
690 	phy_set_bb_reg(adapt, rTx_IQK_PI_A, bMaskDWord, 0x82160c1f);
691 	phy_set_bb_reg(adapt, rRx_IQK_PI_A, bMaskDWord, 0x28160000);
692 
693 	/* LO calibration setting */
694 	phy_set_bb_reg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911);
695 
696 	/* One shot, path A LOK & IQK */
697 	phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
698 	phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
699 
700 	/* delay x ms */
701 	mdelay(IQK_DELAY_TIME_88E);
702 
703 	/* Check failed */
704 	reg_eac = phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord);
705 	reg_e94 = phy_query_bb_reg(adapt, rTx_Power_Before_IQK_A, bMaskDWord);
706 	reg_e9c = phy_query_bb_reg(adapt, rTx_Power_After_IQK_A, bMaskDWord);
707 
708 	if (!(reg_eac & BIT(28)) &&
709 	    (((reg_e94 & 0x03FF0000)>>16) != 0x142) &&
710 	    (((reg_e9c & 0x03FF0000)>>16) != 0x42))
711 		result |= 0x01;
712 	else					/* if Tx not OK, ignore Rx */
713 		return result;
714 
715 	u4tmp = 0x80007C00 | (reg_e94&0x3FF0000)  | ((reg_e9c&0x3FF0000) >> 16);
716 	phy_set_bb_reg(adapt, rTx_IQK, bMaskDWord, u4tmp);
717 
718 	/* 1 RX IQK */
719 	/* modify RXIQK mode table */
720 	ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
721 		     ("Path-A Rx IQK modify RXIQK mode table 2!\n"));
722 	phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000);
723 	phy_set_rf_reg(adapt, RF_PATH_A, RF_WE_LUT, bRFRegOffsetMask, 0x800a0);
724 	phy_set_rf_reg(adapt, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000);
725 	phy_set_rf_reg(adapt, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f);
726 	phy_set_rf_reg(adapt, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf7ffa);
727 	phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
728 
729 	/* IQK setting */
730 	phy_set_bb_reg(adapt, rRx_IQK, bMaskDWord, 0x01004800);
731 
732 	/* path-A IQK setting */
733 	phy_set_bb_reg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x38008c1c);
734 	phy_set_bb_reg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x18008c1c);
735 	phy_set_bb_reg(adapt, rTx_IQK_PI_A, bMaskDWord, 0x82160c05);
736 	phy_set_bb_reg(adapt, rRx_IQK_PI_A, bMaskDWord, 0x28160c1f);
737 
738 	/* LO calibration setting */
739 	phy_set_bb_reg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911);
740 
741 	phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
742 	phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
743 
744 	mdelay(IQK_DELAY_TIME_88E);
745 
746 	/*  Check failed */
747 	reg_eac = phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord);
748 	reg_e94 = phy_query_bb_reg(adapt, rTx_Power_Before_IQK_A, bMaskDWord);
749 	reg_e9c = phy_query_bb_reg(adapt, rTx_Power_After_IQK_A, bMaskDWord);
750 	reg_ea4 = phy_query_bb_reg(adapt, rRx_Power_Before_IQK_A_2, bMaskDWord);
751 
752 	/* reload RF 0xdf */
753 	phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000);
754 	phy_set_rf_reg(adapt, RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x180);
755 
756 	if (!(reg_eac & BIT(27)) && /* if Tx is OK, check whether Rx is OK */
757 	    (((reg_ea4 & 0x03FF0000)>>16) != 0x132) &&
758 	    (((reg_eac & 0x03FF0000)>>16) != 0x36))
759 		result |= 0x02;
760 	else
761 		ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
762 			     ("Path A Rx IQK fail!!\n"));
763 
764 	return result;
765 }
766 
phy_path_b_iqk(struct adapter * adapt)767 static u8 phy_path_b_iqk(struct adapter *adapt)
768 {
769 	u32 regeac, regeb4, regebc, regec4, regecc;
770 	u8 result = 0x00;
771 	struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
772 	struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
773 
774 	/* One shot, path B LOK & IQK */
775 	phy_set_bb_reg(adapt, rIQK_AGC_Cont, bMaskDWord, 0x00000002);
776 	phy_set_bb_reg(adapt, rIQK_AGC_Cont, bMaskDWord, 0x00000000);
777 
778 	mdelay(IQK_DELAY_TIME_88E);
779 
780 	regeac = phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord);
781 	regeb4 = phy_query_bb_reg(adapt, rTx_Power_Before_IQK_B, bMaskDWord);
782 	regebc = phy_query_bb_reg(adapt, rTx_Power_After_IQK_B, bMaskDWord);
783 	regec4 = phy_query_bb_reg(adapt, rRx_Power_Before_IQK_B_2, bMaskDWord);
784 	regecc = phy_query_bb_reg(adapt, rRx_Power_After_IQK_B_2, bMaskDWord);
785 
786 	if (!(regeac & BIT(31)) &&
787 	    (((regeb4 & 0x03FF0000)>>16) != 0x142) &&
788 	    (((regebc & 0x03FF0000)>>16) != 0x42))
789 		result |= 0x01;
790 	else
791 		return result;
792 
793 	if (!(regeac & BIT(30)) &&
794 	    (((regec4 & 0x03FF0000)>>16) != 0x132) &&
795 	    (((regecc & 0x03FF0000)>>16) != 0x36))
796 		result |= 0x02;
797 	else
798 		ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION,
799 			     ODM_DBG_LOUD,  ("Path B Rx IQK fail!!\n"));
800 	return result;
801 }
802 
patha_fill_iqk(struct adapter * adapt,bool iqkok,s32 result[][8],u8 final_candidate,bool txonly)803 static void patha_fill_iqk(struct adapter *adapt, bool iqkok, s32 result[][8],
804 			   u8 final_candidate, bool txonly)
805 {
806 	u32 oldval_0, x, tx0_a, reg;
807 	s32 y, tx0_c;
808 
809 	if (final_candidate == 0xFF) {
810 		return;
811 	} else if (iqkok) {
812 		oldval_0 = (phy_query_bb_reg(adapt, rOFDM0_XATxIQImbalance, bMaskDWord) >> 22) & 0x3FF;
813 
814 		x = result[final_candidate][0];
815 		if ((x & 0x00000200) != 0)
816 			x = x | 0xFFFFFC00;
817 
818 		tx0_a = (x * oldval_0) >> 8;
819 		phy_set_bb_reg(adapt, rOFDM0_XATxIQImbalance, 0x3FF, tx0_a);
820 		phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(31),
821 			       ((x * oldval_0>>7) & 0x1));
822 
823 		y = result[final_candidate][1];
824 		if ((y & 0x00000200) != 0)
825 			y = y | 0xFFFFFC00;
826 
827 		tx0_c = (y * oldval_0) >> 8;
828 		phy_set_bb_reg(adapt, rOFDM0_XCTxAFE, 0xF0000000,
829 			       ((tx0_c&0x3C0)>>6));
830 		phy_set_bb_reg(adapt, rOFDM0_XATxIQImbalance, 0x003F0000,
831 			       (tx0_c&0x3F));
832 		phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(29),
833 			       ((y * oldval_0>>7) & 0x1));
834 
835 		if (txonly)
836 			return;
837 
838 		reg = result[final_candidate][2];
839 		phy_set_bb_reg(adapt, rOFDM0_XARxIQImbalance, 0x3FF, reg);
840 
841 		reg = result[final_candidate][3] & 0x3F;
842 		phy_set_bb_reg(adapt, rOFDM0_XARxIQImbalance, 0xFC00, reg);
843 
844 		reg = (result[final_candidate][3] >> 6) & 0xF;
845 		phy_set_bb_reg(adapt, rOFDM0_RxIQExtAnta, 0xF0000000, reg);
846 	}
847 }
848 
pathb_fill_iqk(struct adapter * adapt,bool iqkok,s32 result[][8],u8 final_candidate,bool txonly)849 static void pathb_fill_iqk(struct adapter *adapt, bool iqkok, s32 result[][8],
850 			   u8 final_candidate, bool txonly)
851 {
852 	u32 oldval_1, x, tx1_a, reg;
853 	s32 y, tx1_c;
854 
855 	if (final_candidate == 0xFF) {
856 		return;
857 	} else if (iqkok) {
858 		oldval_1 = (phy_query_bb_reg(adapt, rOFDM0_XBTxIQImbalance, bMaskDWord) >> 22) & 0x3FF;
859 
860 		x = result[final_candidate][4];
861 		if ((x & 0x00000200) != 0)
862 			x = x | 0xFFFFFC00;
863 		tx1_a = (x * oldval_1) >> 8;
864 		phy_set_bb_reg(adapt, rOFDM0_XBTxIQImbalance, 0x3FF, tx1_a);
865 
866 		phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(27),
867 			       ((x * oldval_1>>7) & 0x1));
868 
869 		y = result[final_candidate][5];
870 		if ((y & 0x00000200) != 0)
871 			y = y | 0xFFFFFC00;
872 
873 		tx1_c = (y * oldval_1) >> 8;
874 
875 		phy_set_bb_reg(adapt, rOFDM0_XDTxAFE, 0xF0000000,
876 			       ((tx1_c&0x3C0)>>6));
877 		phy_set_bb_reg(adapt, rOFDM0_XBTxIQImbalance, 0x003F0000,
878 			       (tx1_c&0x3F));
879 		phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(25),
880 			       ((y * oldval_1>>7) & 0x1));
881 
882 		if (txonly)
883 			return;
884 
885 		reg = result[final_candidate][6];
886 		phy_set_bb_reg(adapt, rOFDM0_XBRxIQImbalance, 0x3FF, reg);
887 
888 		reg = result[final_candidate][7] & 0x3F;
889 		phy_set_bb_reg(adapt, rOFDM0_XBRxIQImbalance, 0xFC00, reg);
890 
891 		reg = (result[final_candidate][7] >> 6) & 0xF;
892 		phy_set_bb_reg(adapt, rOFDM0_AGCRSSITable, 0x0000F000, reg);
893 	}
894 }
895 
save_adda_registers(struct adapter * adapt,u32 * addareg,u32 * backup,u32 register_num)896 static void save_adda_registers(struct adapter *adapt, u32 *addareg,
897 				u32 *backup, u32 register_num)
898 {
899 	u32 i;
900 
901 	for (i = 0; i < register_num; i++) {
902 		backup[i] = phy_query_bb_reg(adapt, addareg[i], bMaskDWord);
903 	}
904 }
905 
save_mac_registers(struct adapter * adapt,u32 * mac_reg,u32 * backup)906 static void save_mac_registers(struct adapter *adapt, u32 *mac_reg,
907 			       u32 *backup)
908 {
909 	u32 i;
910 
911 	for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) {
912 		backup[i] = usb_read8(adapt, mac_reg[i]);
913 	}
914 	backup[i] = usb_read32(adapt, mac_reg[i]);
915 }
916 
reload_adda_reg(struct adapter * adapt,u32 * adda_reg,u32 * backup,u32 regiester_num)917 static void reload_adda_reg(struct adapter *adapt, u32 *adda_reg,
918 			    u32 *backup, u32 regiester_num)
919 {
920 	u32 i;
921 
922 	for (i = 0; i < regiester_num; i++)
923 		phy_set_bb_reg(adapt, adda_reg[i], bMaskDWord, backup[i]);
924 }
925 
reload_mac_registers(struct adapter * adapt,u32 * mac_reg,u32 * backup)926 static void reload_mac_registers(struct adapter *adapt,
927 				 u32 *mac_reg, u32 *backup)
928 {
929 	u32 i;
930 
931 	for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) {
932 		usb_write8(adapt, mac_reg[i], (u8)backup[i]);
933 	}
934 	usb_write32(adapt, mac_reg[i], backup[i]);
935 }
936 
path_adda_on(struct adapter * adapt,u32 * adda_reg,bool is_path_a_on,bool is2t)937 static void path_adda_on(struct adapter *adapt, u32 *adda_reg,
938 			 bool is_path_a_on, bool is2t)
939 {
940 	u32 path_on;
941 	u32 i;
942 
943 	if (!is2t) {
944 		path_on = 0x0bdb25a0;
945 		phy_set_bb_reg(adapt, adda_reg[0], bMaskDWord, 0x0b1b25a0);
946 	} else {
947 		path_on = is_path_a_on ? 0x04db25a4 : 0x0b1b25a4;
948 		phy_set_bb_reg(adapt, adda_reg[0], bMaskDWord, path_on);
949 	}
950 
951 	for (i = 1; i < IQK_ADDA_REG_NUM; i++)
952 		phy_set_bb_reg(adapt, adda_reg[i], bMaskDWord, path_on);
953 }
954 
mac_setting_calibration(struct adapter * adapt,u32 * mac_reg,u32 * backup)955 static void mac_setting_calibration(struct adapter *adapt, u32 *mac_reg, u32 *backup)
956 {
957 	u32 i = 0;
958 
959 	usb_write8(adapt, mac_reg[i], 0x3F);
960 
961 	for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) {
962 		usb_write8(adapt, mac_reg[i], (u8)(backup[i]&(~BIT(3))));
963 	}
964 	usb_write8(adapt, mac_reg[i], (u8)(backup[i]&(~BIT(5))));
965 }
966 
path_a_standby(struct adapter * adapt)967 static void path_a_standby(struct adapter *adapt)
968 {
969 
970 	phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x0);
971 	phy_set_bb_reg(adapt, 0x840, bMaskDWord, 0x00010000);
972 	phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
973 }
974 
pi_mode_switch(struct adapter * adapt,bool pi_mode)975 static void pi_mode_switch(struct adapter *adapt, bool pi_mode)
976 {
977 	u32 mode;
978 
979 	mode = pi_mode ? 0x01000100 : 0x01000000;
980 	phy_set_bb_reg(adapt, rFPGA0_XA_HSSIParameter1, bMaskDWord, mode);
981 	phy_set_bb_reg(adapt, rFPGA0_XB_HSSIParameter1, bMaskDWord, mode);
982 }
983 
simularity_compare(struct adapter * adapt,s32 resulta[][8],u8 c1,u8 c2)984 static bool simularity_compare(struct adapter *adapt, s32 resulta[][8],
985 			       u8 c1, u8 c2)
986 {
987 	u32 i, j, diff, sim_bitmap = 0, bound;
988 	struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
989 	struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
990 	u8 final_candidate[2] = {0xFF, 0xFF};	/* for path A and path B */
991 	bool result = true;
992 	s32 tmp1 = 0, tmp2 = 0;
993 
994 	if ((dm_odm->RFType == ODM_2T2R) || (dm_odm->RFType == ODM_2T3R) ||
995 	    (dm_odm->RFType == ODM_2T4R))
996 		bound = 8;
997 	else
998 		bound = 4;
999 
1000 	for (i = 0; i < bound; i++) {
1001 		if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) {
1002 			if ((resulta[c1][i] & 0x00000200) != 0)
1003 				tmp1 = resulta[c1][i] | 0xFFFFFC00;
1004 			else
1005 				tmp1 = resulta[c1][i];
1006 
1007 			if ((resulta[c2][i] & 0x00000200) != 0)
1008 				tmp2 = resulta[c2][i] | 0xFFFFFC00;
1009 			else
1010 				tmp2 = resulta[c2][i];
1011 		} else {
1012 			tmp1 = resulta[c1][i];
1013 			tmp2 = resulta[c2][i];
1014 		}
1015 
1016 		diff = abs(tmp1 - tmp2);
1017 
1018 		if (diff > MAX_TOLERANCE) {
1019 			if ((i == 2 || i == 6) && !sim_bitmap) {
1020 				if (resulta[c1][i] + resulta[c1][i+1] == 0)
1021 					final_candidate[(i/4)] = c2;
1022 				else if (resulta[c2][i] + resulta[c2][i+1] == 0)
1023 					final_candidate[(i/4)] = c1;
1024 				else
1025 					sim_bitmap = sim_bitmap | (1<<i);
1026 			} else {
1027 				sim_bitmap = sim_bitmap | (1<<i);
1028 			}
1029 		}
1030 	}
1031 
1032 	if (sim_bitmap == 0) {
1033 		for (i = 0; i < (bound/4); i++) {
1034 			if (final_candidate[i] != 0xFF) {
1035 				for (j = i*4; j < (i+1)*4-2; j++)
1036 					resulta[3][j] = resulta[final_candidate[i]][j];
1037 				result = false;
1038 			}
1039 		}
1040 		return result;
1041 	} else {
1042 		if (!(sim_bitmap & 0x03)) {		   /* path A TX OK */
1043 			for (i = 0; i < 2; i++)
1044 				resulta[3][i] = resulta[c1][i];
1045 		}
1046 		if (!(sim_bitmap & 0x0c)) {		   /* path A RX OK */
1047 			for (i = 2; i < 4; i++)
1048 				resulta[3][i] = resulta[c1][i];
1049 		}
1050 
1051 		if (!(sim_bitmap & 0x30)) { /* path B TX OK */
1052 			for (i = 4; i < 6; i++)
1053 				resulta[3][i] = resulta[c1][i];
1054 		}
1055 
1056 		if (!(sim_bitmap & 0xc0)) { /* path B RX OK */
1057 			for (i = 6; i < 8; i++)
1058 				resulta[3][i] = resulta[c1][i];
1059 		}
1060 		return false;
1061 	}
1062 }
1063 
phy_iq_calibrate(struct adapter * adapt,s32 result[][8],u8 t,bool is2t)1064 static void phy_iq_calibrate(struct adapter *adapt, s32 result[][8],
1065 			     u8 t, bool is2t)
1066 {
1067 	struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
1068 	struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
1069 	u32 i;
1070 	u8 path_a_ok, path_b_ok;
1071 	u32 adda_reg[IQK_ADDA_REG_NUM] = {
1072 					  rFPGA0_XCD_SwitchControl, rBlue_Tooth,
1073 					  rRx_Wait_CCA, rTx_CCK_RFON,
1074 					  rTx_CCK_BBON, rTx_OFDM_RFON,
1075 					  rTx_OFDM_BBON, rTx_To_Rx,
1076 					  rTx_To_Tx, rRx_CCK,
1077 					  rRx_OFDM, rRx_Wait_RIFS,
1078 					  rRx_TO_Rx, rStandby,
1079 					  rSleep, rPMPD_ANAEN};
1080 
1081 	u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
1082 					    REG_TXPAUSE, REG_BCN_CTRL,
1083 					    REG_BCN_CTRL_1, REG_GPIO_MUXCFG};
1084 
1085 	/* since 92C & 92D have the different define in IQK_BB_REG */
1086 	u32 iqk_bb_reg_92c[IQK_BB_REG_NUM] = {
1087 					      rOFDM0_TRxPathEnable, rOFDM0_TRMuxPar,
1088 					      rFPGA0_XCD_RFInterfaceSW, rConfig_AntA, rConfig_AntB,
1089 					      rFPGA0_XAB_RFInterfaceSW, rFPGA0_XA_RFInterfaceOE,
1090 					      rFPGA0_XB_RFInterfaceOE, rFPGA0_RFMOD};
1091 
1092 	u32 retry_count = 9;
1093 	if (*(dm_odm->mp_mode) == 1)
1094 		retry_count = 9;
1095 	else
1096 		retry_count = 2;
1097 
1098 	if (t == 0) {
1099 
1100 		/*  Save ADDA parameters, turn Path A ADDA on */
1101 		save_adda_registers(adapt, adda_reg, dm_odm->RFCalibrateInfo.ADDA_backup,
1102 				    IQK_ADDA_REG_NUM);
1103 		save_mac_registers(adapt, iqk_mac_reg,
1104 				   dm_odm->RFCalibrateInfo.IQK_MAC_backup);
1105 		save_adda_registers(adapt, iqk_bb_reg_92c,
1106 				    dm_odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM);
1107 	}
1108 
1109 	path_adda_on(adapt, adda_reg, true, is2t);
1110 	if (t == 0)
1111 		dm_odm->RFCalibrateInfo.bRfPiEnable = (u8)phy_query_bb_reg(adapt, rFPGA0_XA_HSSIParameter1,
1112 									   BIT(8));
1113 
1114 	if (!dm_odm->RFCalibrateInfo.bRfPiEnable) {
1115 		/*  Switch BB to PI mode to do IQ Calibration. */
1116 		pi_mode_switch(adapt, true);
1117 	}
1118 
1119 	/* BB setting */
1120 	phy_set_bb_reg(adapt, rFPGA0_RFMOD, BIT(24), 0x00);
1121 	phy_set_bb_reg(adapt, rOFDM0_TRxPathEnable, bMaskDWord, 0x03a05600);
1122 	phy_set_bb_reg(adapt, rOFDM0_TRMuxPar, bMaskDWord, 0x000800e4);
1123 	phy_set_bb_reg(adapt, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, 0x22204000);
1124 
1125 	phy_set_bb_reg(adapt, rFPGA0_XAB_RFInterfaceSW, BIT(10), 0x01);
1126 	phy_set_bb_reg(adapt, rFPGA0_XAB_RFInterfaceSW, BIT(26), 0x01);
1127 	phy_set_bb_reg(adapt, rFPGA0_XA_RFInterfaceOE, BIT(10), 0x00);
1128 	phy_set_bb_reg(adapt, rFPGA0_XB_RFInterfaceOE, BIT(10), 0x00);
1129 
1130 	if (is2t) {
1131 		phy_set_bb_reg(adapt, rFPGA0_XA_LSSIParameter, bMaskDWord,
1132 			       0x00010000);
1133 		phy_set_bb_reg(adapt, rFPGA0_XB_LSSIParameter, bMaskDWord,
1134 			       0x00010000);
1135 	}
1136 
1137 	/* MAC settings */
1138 	mac_setting_calibration(adapt, iqk_mac_reg,
1139 				dm_odm->RFCalibrateInfo.IQK_MAC_backup);
1140 
1141 	/* Page B init */
1142 	/* AP or IQK */
1143 	phy_set_bb_reg(adapt, rConfig_AntA, bMaskDWord, 0x0f600000);
1144 
1145 	if (is2t)
1146 		phy_set_bb_reg(adapt, rConfig_AntB, bMaskDWord, 0x0f600000);
1147 
1148 	/*  IQ calibration setting */
1149 	phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
1150 	phy_set_bb_reg(adapt, rTx_IQK, bMaskDWord, 0x01007c00);
1151 	phy_set_bb_reg(adapt, rRx_IQK, bMaskDWord, 0x81004800);
1152 
1153 	for (i = 0; i < retry_count; i++) {
1154 		path_a_ok = phy_path_a_iqk(adapt, is2t);
1155 		if (path_a_ok == 0x01) {
1156 				result[t][0] = (phy_query_bb_reg(adapt, rTx_Power_Before_IQK_A,
1157 								 bMaskDWord)&0x3FF0000)>>16;
1158 				result[t][1] = (phy_query_bb_reg(adapt, rTx_Power_After_IQK_A,
1159 								 bMaskDWord)&0x3FF0000)>>16;
1160 			break;
1161 		}
1162 	}
1163 
1164 	for (i = 0; i < retry_count; i++) {
1165 		path_a_ok = phy_path_a_rx_iqk(adapt, is2t);
1166 		if (path_a_ok == 0x03) {
1167 				result[t][2] = (phy_query_bb_reg(adapt, rRx_Power_Before_IQK_A_2,
1168 								 bMaskDWord)&0x3FF0000)>>16;
1169 				result[t][3] = (phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2,
1170 								 bMaskDWord)&0x3FF0000)>>16;
1171 			break;
1172 		} else {
1173 			ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1174 				     ("Path A Rx IQK Fail!!\n"));
1175 		}
1176 	}
1177 
1178 	if (0x00 == path_a_ok) {
1179 		ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1180 			     ("Path A IQK failed!!\n"));
1181 	}
1182 
1183 	if (is2t) {
1184 		path_a_standby(adapt);
1185 
1186 		/*  Turn Path B ADDA on */
1187 		path_adda_on(adapt, adda_reg, false, is2t);
1188 
1189 		for (i = 0; i < retry_count; i++) {
1190 			path_b_ok = phy_path_b_iqk(adapt);
1191 			if (path_b_ok == 0x03) {
1192 				result[t][4] = (phy_query_bb_reg(adapt, rTx_Power_Before_IQK_B,
1193 								 bMaskDWord)&0x3FF0000)>>16;
1194 				result[t][5] = (phy_query_bb_reg(adapt, rTx_Power_After_IQK_B,
1195 								 bMaskDWord)&0x3FF0000)>>16;
1196 				result[t][6] = (phy_query_bb_reg(adapt, rRx_Power_Before_IQK_B_2,
1197 								 bMaskDWord)&0x3FF0000)>>16;
1198 				result[t][7] = (phy_query_bb_reg(adapt, rRx_Power_After_IQK_B_2,
1199 								 bMaskDWord)&0x3FF0000)>>16;
1200 				break;
1201 			} else if (i == (retry_count - 1) && path_b_ok == 0x01) {	/* Tx IQK OK */
1202 				result[t][4] = (phy_query_bb_reg(adapt, rTx_Power_Before_IQK_B,
1203 								 bMaskDWord)&0x3FF0000)>>16;
1204 				result[t][5] = (phy_query_bb_reg(adapt, rTx_Power_After_IQK_B,
1205 								 bMaskDWord)&0x3FF0000)>>16;
1206 			}
1207 		}
1208 
1209 		if (0x00 == path_b_ok) {
1210 			ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1211 				     ("Path B IQK failed!!\n"));
1212 		}
1213 	}
1214 
1215 	/* Back to BB mode, load original value */
1216 	phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0);
1217 
1218 	if (t != 0) {
1219 		if (!dm_odm->RFCalibrateInfo.bRfPiEnable) {
1220 			/* Switch back BB to SI mode after
1221 			 * finish IQ Calibration.
1222 			 */
1223 			pi_mode_switch(adapt, false);
1224 		}
1225 
1226 		/*  Reload ADDA power saving parameters */
1227 		reload_adda_reg(adapt, adda_reg, dm_odm->RFCalibrateInfo.ADDA_backup,
1228 				IQK_ADDA_REG_NUM);
1229 
1230 		/*  Reload MAC parameters */
1231 		reload_mac_registers(adapt, iqk_mac_reg,
1232 				     dm_odm->RFCalibrateInfo.IQK_MAC_backup);
1233 
1234 		reload_adda_reg(adapt, iqk_bb_reg_92c, dm_odm->RFCalibrateInfo.IQK_BB_backup,
1235 				IQK_BB_REG_NUM);
1236 
1237 		/*  Restore RX initial gain */
1238 		phy_set_bb_reg(adapt, rFPGA0_XA_LSSIParameter,
1239 			       bMaskDWord, 0x00032ed3);
1240 		if (is2t)
1241 			phy_set_bb_reg(adapt, rFPGA0_XB_LSSIParameter,
1242 				       bMaskDWord, 0x00032ed3);
1243 
1244 		/* load 0xe30 IQC default value */
1245 		phy_set_bb_reg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x01008c00);
1246 		phy_set_bb_reg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x01008c00);
1247 	}
1248 }
1249 
phy_lc_calibrate(struct adapter * adapt,bool is2t)1250 static void phy_lc_calibrate(struct adapter *adapt, bool is2t)
1251 {
1252 	u8 tmpreg;
1253 	u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
1254 
1255 	/* Check continuous TX and Packet TX */
1256 	tmpreg = usb_read8(adapt, 0xd03);
1257 
1258 	if ((tmpreg&0x70) != 0)
1259 		usb_write8(adapt, 0xd03, tmpreg&0x8F);
1260 	else
1261 		usb_write8(adapt, REG_TXPAUSE, 0xFF);
1262 
1263 	if ((tmpreg&0x70) != 0) {
1264 		/* 1. Read original RF mode */
1265 		/* Path-A */
1266 		rf_a_mode = phy_query_rf_reg(adapt, RF_PATH_A, RF_AC,
1267 					     bMask12Bits);
1268 
1269 		/* Path-B */
1270 		if (is2t)
1271 			rf_b_mode = phy_query_rf_reg(adapt, RF_PATH_B, RF_AC,
1272 						     bMask12Bits);
1273 
1274 		/* 2. Set RF mode = standby mode */
1275 		/* Path-A */
1276 		phy_set_rf_reg(adapt, RF_PATH_A, RF_AC, bMask12Bits,
1277 			       (rf_a_mode&0x8FFFF)|0x10000);
1278 
1279 		/* Path-B */
1280 		if (is2t)
1281 			phy_set_rf_reg(adapt, RF_PATH_B, RF_AC, bMask12Bits,
1282 				       (rf_b_mode&0x8FFFF)|0x10000);
1283 	}
1284 
1285 	/* 3. Read RF reg18 */
1286 	lc_cal = phy_query_rf_reg(adapt, RF_PATH_A, RF_CHNLBW, bMask12Bits);
1287 
1288 	/* 4. Set LC calibration begin bit15 */
1289 	phy_set_rf_reg(adapt, RF_PATH_A, RF_CHNLBW, bMask12Bits,
1290 		       lc_cal|0x08000);
1291 
1292 	msleep(100);
1293 
1294 	/* Restore original situation */
1295 	if ((tmpreg&0x70) != 0) {
1296 		/* Deal with continuous TX case */
1297 		/* Path-A */
1298 		usb_write8(adapt, 0xd03, tmpreg);
1299 		phy_set_rf_reg(adapt, RF_PATH_A, RF_AC, bMask12Bits, rf_a_mode);
1300 
1301 		/* Path-B */
1302 		if (is2t)
1303 			phy_set_rf_reg(adapt, RF_PATH_B, RF_AC, bMask12Bits,
1304 				       rf_b_mode);
1305 	} else {
1306 		/* Deal with Packet TX case */
1307 		usb_write8(adapt, REG_TXPAUSE, 0x00);
1308 	}
1309 }
1310 
rtl88eu_phy_iq_calibrate(struct adapter * adapt,bool recovery)1311 void rtl88eu_phy_iq_calibrate(struct adapter *adapt, bool recovery)
1312 {
1313 	struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
1314 	struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
1315 	s32 result[4][8];
1316 	u8 i, final, chn_index;
1317 	bool pathaok, pathbok;
1318 	s32 reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc, reg_ec4;
1319 	bool is12simular, is13simular, is23simular;
1320 	bool singletone = false, carrier_sup = false;
1321 	u32 iqk_bb_reg_92c[IQK_BB_REG_NUM] = {
1322 		rOFDM0_XARxIQImbalance, rOFDM0_XBRxIQImbalance,
1323 		rOFDM0_ECCAThreshold, rOFDM0_AGCRSSITable,
1324 		rOFDM0_XATxIQImbalance, rOFDM0_XBTxIQImbalance,
1325 		rOFDM0_XCTxAFE, rOFDM0_XDTxAFE,
1326 		rOFDM0_RxIQExtAnta};
1327 	bool is2t;
1328 
1329 	is2t = (dm_odm->RFType == ODM_2T2R) ? true : false;
1330 
1331 	if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION))
1332 		return;
1333 
1334 	if (singletone || carrier_sup)
1335 		return;
1336 
1337 	if (recovery) {
1338 		ODM_RT_TRACE(dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD,
1339 			     ("phy_iq_calibrate: Return due to recovery!\n"));
1340 		reload_adda_reg(adapt, iqk_bb_reg_92c,
1341 				dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9);
1342 		return;
1343 	}
1344 
1345 	for (i = 0; i < 8; i++) {
1346 		result[0][i] = 0;
1347 		result[1][i] = 0;
1348 		result[2][i] = 0;
1349 		if ((i == 0) || (i == 2) || (i == 4)  || (i == 6))
1350 			result[3][i] = 0x100;
1351 		else
1352 			result[3][i] = 0;
1353 	}
1354 	final = 0xff;
1355 	pathaok = false;
1356 	pathbok = false;
1357 	is12simular = false;
1358 	is23simular = false;
1359 	is13simular = false;
1360 
1361 	for (i = 0; i < 3; i++) {
1362 		phy_iq_calibrate(adapt, result, i, is2t);
1363 
1364 		if (i == 1) {
1365 			is12simular = simularity_compare(adapt, result, 0, 1);
1366 			if (is12simular) {
1367 				final = 0;
1368 				break;
1369 			}
1370 		}
1371 
1372 		if (i == 2) {
1373 			is13simular = simularity_compare(adapt, result, 0, 2);
1374 			if (is13simular) {
1375 				final = 0;
1376 				break;
1377 			}
1378 			is23simular = simularity_compare(adapt, result, 1, 2);
1379 			if (is23simular)
1380 				final = 1;
1381 			else
1382 				final = 3;
1383 		}
1384 	}
1385 
1386 	for (i = 0; i < 4; i++) {
1387 		reg_e94 = result[i][0];
1388 		reg_e9c = result[i][1];
1389 		reg_ea4 = result[i][2];
1390 		reg_eb4 = result[i][4];
1391 		reg_ebc = result[i][5];
1392 		reg_ec4 = result[i][6];
1393 	}
1394 
1395 	if (final != 0xff) {
1396 		reg_e94 = result[final][0];
1397 		reg_e9c = result[final][1];
1398 		reg_ea4 = result[final][2];
1399 		reg_eb4 = result[final][4];
1400 		reg_ebc = result[final][5];
1401 		dm_odm->RFCalibrateInfo.RegE94 = reg_e94;
1402 		dm_odm->RFCalibrateInfo.RegE9C = reg_e9c;
1403 		dm_odm->RFCalibrateInfo.RegEB4 = reg_eb4;
1404 		dm_odm->RFCalibrateInfo.RegEBC = reg_ebc;
1405 		reg_ec4 = result[final][6];
1406 		pathaok = true;
1407 		pathbok = true;
1408 	} else {
1409 		ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1410 			     ("IQK: FAIL use default value\n"));
1411 		dm_odm->RFCalibrateInfo.RegE94 = 0x100;
1412 		dm_odm->RFCalibrateInfo.RegEB4 = 0x100;
1413 		dm_odm->RFCalibrateInfo.RegE9C = 0x0;
1414 		dm_odm->RFCalibrateInfo.RegEBC = 0x0;
1415 	}
1416 	if (reg_e94 != 0)
1417 		patha_fill_iqk(adapt, pathaok, result, final,
1418 			       (reg_ea4 == 0));
1419 	if (is2t) {
1420 		if (reg_eb4 != 0)
1421 			pathb_fill_iqk(adapt, pathbok, result, final,
1422 				       (reg_ec4 == 0));
1423 	}
1424 
1425 	chn_index = get_right_chnl_for_iqk(hal_data->CurrentChannel);
1426 
1427 	if (final < 4) {
1428 		for (i = 0; i < IQK_Matrix_REG_NUM; i++)
1429 			dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[chn_index].Value[0][i] = result[final][i];
1430 		dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[chn_index].bIQKDone = true;
1431 	}
1432 
1433 	save_adda_registers(adapt, iqk_bb_reg_92c,
1434 			    dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9);
1435 }
1436 
rtl88eu_phy_lc_calibrate(struct adapter * adapt)1437 void rtl88eu_phy_lc_calibrate(struct adapter *adapt)
1438 {
1439 	bool singletone = false, carrier_sup = false;
1440 	u32 timeout = 2000, timecount = 0;
1441 	struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
1442 	struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
1443 
1444 	if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION))
1445 		return;
1446 	if (singletone || carrier_sup)
1447 		return;
1448 
1449 	while (*(dm_odm->pbScanInProcess) && timecount < timeout) {
1450 		mdelay(50);
1451 		timecount += 50;
1452 	}
1453 
1454 	dm_odm->RFCalibrateInfo.bLCKInProgress = true;
1455 
1456 	if (dm_odm->RFType == ODM_2T2R) {
1457 		phy_lc_calibrate(adapt, true);
1458 	} else {
1459 		/* For 88C 1T1R */
1460 		phy_lc_calibrate(adapt, false);
1461 	}
1462 
1463 	dm_odm->RFCalibrateInfo.bLCKInProgress = false;
1464 }
1465