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, BIT8);
101 	else if (rfpath == RF_PATH_B)
102 		rfpi_enable = (u8)phy_query_bb_reg(adapt, rFPGA0_XB_HSSIParameter1, BIT8);
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, (BIT26 | BIT27),
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, reg_ea4;
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 	reg_ea4 = phy_query_bb_reg(adapt, rRx_Power_Before_IQK_A_2, bMaskDWord);
655 
656 	if (!(reg_eac & BIT28) &&
657 	    (((reg_e94 & 0x03FF0000)>>16) != 0x142) &&
658 	    (((reg_e9c & 0x03FF0000)>>16) != 0x42))
659 		result |= 0x01;
660 	return result;
661 }
662 
phy_path_a_rx_iqk(struct adapter * adapt,bool configPathB)663 static u8 phy_path_a_rx_iqk(struct adapter *adapt, bool configPathB)
664 {
665 	u32 reg_eac, reg_e94, reg_e9c, reg_ea4, u4tmp;
666 	u8 result = 0x00;
667 	struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
668 	struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
669 
670 	/* 1 Get TXIMR setting */
671 	/* modify RXIQK mode table */
672 	phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000);
673 	phy_set_rf_reg(adapt, RF_PATH_A, RF_WE_LUT, bRFRegOffsetMask, 0x800a0);
674 	phy_set_rf_reg(adapt, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000);
675 	phy_set_rf_reg(adapt, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f);
676 	phy_set_rf_reg(adapt, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf117B);
677 
678 	/* PA,PAD off */
679 	phy_set_rf_reg(adapt, RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x980);
680 	phy_set_rf_reg(adapt, RF_PATH_A, 0x56, bRFRegOffsetMask, 0x51000);
681 
682 	phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
683 
684 	/* IQK setting */
685 	phy_set_bb_reg(adapt, rTx_IQK, bMaskDWord, 0x01007c00);
686 	phy_set_bb_reg(adapt, rRx_IQK, bMaskDWord, 0x81004800);
687 
688 	/* path-A IQK setting */
689 	phy_set_bb_reg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1c);
690 	phy_set_bb_reg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x30008c1c);
691 	phy_set_bb_reg(adapt, rTx_IQK_PI_A, bMaskDWord, 0x82160c1f);
692 	phy_set_bb_reg(adapt, rRx_IQK_PI_A, bMaskDWord, 0x28160000);
693 
694 	/* LO calibration setting */
695 	phy_set_bb_reg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911);
696 
697 	/* One shot, path A LOK & IQK */
698 	phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
699 	phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
700 
701 	/* delay x ms */
702 	mdelay(IQK_DELAY_TIME_88E);
703 
704 	/* Check failed */
705 	reg_eac = phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord);
706 	reg_e94 = phy_query_bb_reg(adapt, rTx_Power_Before_IQK_A, bMaskDWord);
707 	reg_e9c = phy_query_bb_reg(adapt, rTx_Power_After_IQK_A, bMaskDWord);
708 
709 	if (!(reg_eac & BIT28) &&
710 	    (((reg_e94 & 0x03FF0000)>>16) != 0x142) &&
711 	    (((reg_e9c & 0x03FF0000)>>16) != 0x42))
712 		result |= 0x01;
713 	else					/* if Tx not OK, ignore Rx */
714 		return result;
715 
716 	u4tmp = 0x80007C00 | (reg_e94&0x3FF0000)  | ((reg_e9c&0x3FF0000) >> 16);
717 	phy_set_bb_reg(adapt, rTx_IQK, bMaskDWord, u4tmp);
718 
719 	/* 1 RX IQK */
720 	/* modify RXIQK mode table */
721 	ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
722 		     ("Path-A Rx IQK modify RXIQK mode table 2!\n"));
723 	phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000);
724 	phy_set_rf_reg(adapt, RF_PATH_A, RF_WE_LUT, bRFRegOffsetMask, 0x800a0);
725 	phy_set_rf_reg(adapt, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000);
726 	phy_set_rf_reg(adapt, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f);
727 	phy_set_rf_reg(adapt, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf7ffa);
728 	phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
729 
730 	/* IQK setting */
731 	phy_set_bb_reg(adapt, rRx_IQK, bMaskDWord, 0x01004800);
732 
733 	/* path-A IQK setting */
734 	phy_set_bb_reg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x38008c1c);
735 	phy_set_bb_reg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x18008c1c);
736 	phy_set_bb_reg(adapt, rTx_IQK_PI_A, bMaskDWord, 0x82160c05);
737 	phy_set_bb_reg(adapt, rRx_IQK_PI_A, bMaskDWord, 0x28160c1f);
738 
739 	/* LO calibration setting */
740 	phy_set_bb_reg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911);
741 
742 	phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
743 	phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
744 
745 	mdelay(IQK_DELAY_TIME_88E);
746 
747 	/*  Check failed */
748 	reg_eac = phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord);
749 	reg_e94 = phy_query_bb_reg(adapt, rTx_Power_Before_IQK_A, bMaskDWord);
750 	reg_e9c = phy_query_bb_reg(adapt, rTx_Power_After_IQK_A, bMaskDWord);
751 	reg_ea4 = phy_query_bb_reg(adapt, rRx_Power_Before_IQK_A_2, bMaskDWord);
752 
753 	/* reload RF 0xdf */
754 	phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000);
755 	phy_set_rf_reg(adapt, RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x180);
756 
757 	if (!(reg_eac & BIT27) && /* if Tx is OK, check whether Rx is OK */
758 	    (((reg_ea4 & 0x03FF0000)>>16) != 0x132) &&
759 	    (((reg_eac & 0x03FF0000)>>16) != 0x36))
760 		result |= 0x02;
761 	else
762 		ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
763 			     ("Path A Rx IQK fail!!\n"));
764 
765 	return result;
766 }
767 
phy_path_b_iqk(struct adapter * adapt)768 static u8 phy_path_b_iqk(struct adapter *adapt)
769 {
770 	u32 regeac, regeb4, regebc, regec4, regecc;
771 	u8 result = 0x00;
772 	struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
773 	struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
774 
775 	/* One shot, path B LOK & IQK */
776 	phy_set_bb_reg(adapt, rIQK_AGC_Cont, bMaskDWord, 0x00000002);
777 	phy_set_bb_reg(adapt, rIQK_AGC_Cont, bMaskDWord, 0x00000000);
778 
779 	mdelay(IQK_DELAY_TIME_88E);
780 
781 	regeac = phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord);
782 	regeb4 = phy_query_bb_reg(adapt, rTx_Power_Before_IQK_B, bMaskDWord);
783 	regebc = phy_query_bb_reg(adapt, rTx_Power_After_IQK_B, bMaskDWord);
784 	regec4 = phy_query_bb_reg(adapt, rRx_Power_Before_IQK_B_2, bMaskDWord);
785 	regecc = phy_query_bb_reg(adapt, rRx_Power_After_IQK_B_2, bMaskDWord);
786 
787 	if (!(regeac & BIT31) &&
788 	    (((regeb4 & 0x03FF0000)>>16) != 0x142) &&
789 	    (((regebc & 0x03FF0000)>>16) != 0x42))
790 		result |= 0x01;
791 	else
792 		return result;
793 
794 	if (!(regeac & BIT30) &&
795 	    (((regec4 & 0x03FF0000)>>16) != 0x132) &&
796 	    (((regecc & 0x03FF0000)>>16) != 0x36))
797 		result |= 0x02;
798 	else
799 		ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION,
800 			     ODM_DBG_LOUD,  ("Path B Rx IQK fail!!\n"));
801 	return result;
802 }
803 
patha_fill_iqk(struct adapter * adapt,bool iqkok,s32 result[][8],u8 final_candidate,bool txonly)804 static void patha_fill_iqk(struct adapter *adapt, bool iqkok, s32 result[][8],
805 			   u8 final_candidate, bool txonly)
806 {
807 	u32 oldval_0, x, tx0_a, reg;
808 	s32 y, tx0_c;
809 
810 	if (final_candidate == 0xFF) {
811 		return;
812 	} else if (iqkok) {
813 		oldval_0 = (phy_query_bb_reg(adapt, rOFDM0_XATxIQImbalance, bMaskDWord) >> 22) & 0x3FF;
814 
815 		x = result[final_candidate][0];
816 		if ((x & 0x00000200) != 0)
817 			x = x | 0xFFFFFC00;
818 
819 		tx0_a = (x * oldval_0) >> 8;
820 		phy_set_bb_reg(adapt, rOFDM0_XATxIQImbalance, 0x3FF, tx0_a);
821 		phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(31),
822 			       ((x * oldval_0>>7) & 0x1));
823 
824 		y = result[final_candidate][1];
825 		if ((y & 0x00000200) != 0)
826 			y = y | 0xFFFFFC00;
827 
828 		tx0_c = (y * oldval_0) >> 8;
829 		phy_set_bb_reg(adapt, rOFDM0_XCTxAFE, 0xF0000000,
830 			       ((tx0_c&0x3C0)>>6));
831 		phy_set_bb_reg(adapt, rOFDM0_XATxIQImbalance, 0x003F0000,
832 			       (tx0_c&0x3F));
833 		phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(29),
834 			       ((y * oldval_0>>7) & 0x1));
835 
836 		if (txonly)
837 			return;
838 
839 		reg = result[final_candidate][2];
840 		phy_set_bb_reg(adapt, rOFDM0_XARxIQImbalance, 0x3FF, reg);
841 
842 		reg = result[final_candidate][3] & 0x3F;
843 		phy_set_bb_reg(adapt, rOFDM0_XARxIQImbalance, 0xFC00, reg);
844 
845 		reg = (result[final_candidate][3] >> 6) & 0xF;
846 		phy_set_bb_reg(adapt, rOFDM0_RxIQExtAnta, 0xF0000000, reg);
847 	}
848 }
849 
pathb_fill_iqk(struct adapter * adapt,bool iqkok,s32 result[][8],u8 final_candidate,bool txonly)850 static void pathb_fill_iqk(struct adapter *adapt, bool iqkok, s32 result[][8],
851 			   u8 final_candidate, bool txonly)
852 {
853 	u32 oldval_1, x, tx1_a, reg;
854 	s32 y, tx1_c;
855 
856 	if (final_candidate == 0xFF) {
857 		return;
858 	} else if (iqkok) {
859 		oldval_1 = (phy_query_bb_reg(adapt, rOFDM0_XBTxIQImbalance, bMaskDWord) >> 22) & 0x3FF;
860 
861 		x = result[final_candidate][4];
862 		if ((x & 0x00000200) != 0)
863 			x = x | 0xFFFFFC00;
864 		tx1_a = (x * oldval_1) >> 8;
865 		phy_set_bb_reg(adapt, rOFDM0_XBTxIQImbalance, 0x3FF, tx1_a);
866 
867 		phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(27),
868 			       ((x * oldval_1>>7) & 0x1));
869 
870 		y = result[final_candidate][5];
871 		if ((y & 0x00000200) != 0)
872 			y = y | 0xFFFFFC00;
873 
874 		tx1_c = (y * oldval_1) >> 8;
875 
876 		phy_set_bb_reg(adapt, rOFDM0_XDTxAFE, 0xF0000000,
877 			       ((tx1_c&0x3C0)>>6));
878 		phy_set_bb_reg(adapt, rOFDM0_XBTxIQImbalance, 0x003F0000,
879 			       (tx1_c&0x3F));
880 		phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(25),
881 			       ((y * oldval_1>>7) & 0x1));
882 
883 		if (txonly)
884 			return;
885 
886 		reg = result[final_candidate][6];
887 		phy_set_bb_reg(adapt, rOFDM0_XBRxIQImbalance, 0x3FF, reg);
888 
889 		reg = result[final_candidate][7] & 0x3F;
890 		phy_set_bb_reg(adapt, rOFDM0_XBRxIQImbalance, 0xFC00, reg);
891 
892 		reg = (result[final_candidate][7] >> 6) & 0xF;
893 		phy_set_bb_reg(adapt, rOFDM0_AGCRSSITable, 0x0000F000, reg);
894 	}
895 }
896 
save_adda_registers(struct adapter * adapt,u32 * addareg,u32 * backup,u32 register_num)897 static void save_adda_registers(struct adapter *adapt, u32 *addareg,
898 				u32 *backup, u32 register_num)
899 {
900 	u32 i;
901 
902 	for (i = 0; i < register_num; i++) {
903 		backup[i] = phy_query_bb_reg(adapt, addareg[i], bMaskDWord);
904 	}
905 }
906 
save_mac_registers(struct adapter * adapt,u32 * mac_reg,u32 * backup)907 static void save_mac_registers(struct adapter *adapt, u32 *mac_reg,
908 			       u32 *backup)
909 {
910 	u32 i;
911 
912 	for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) {
913 		backup[i] = usb_read8(adapt, mac_reg[i]);
914 	}
915 	backup[i] = usb_read32(adapt, mac_reg[i]);
916 }
917 
reload_adda_reg(struct adapter * adapt,u32 * adda_reg,u32 * backup,u32 regiester_num)918 static void reload_adda_reg(struct adapter *adapt, u32 *adda_reg,
919 			    u32 *backup, u32 regiester_num)
920 {
921 	u32 i;
922 
923 	for (i = 0; i < regiester_num; i++)
924 		phy_set_bb_reg(adapt, adda_reg[i], bMaskDWord, backup[i]);
925 }
926 
reload_mac_registers(struct adapter * adapt,u32 * mac_reg,u32 * backup)927 static void reload_mac_registers(struct adapter *adapt,
928 				 u32 *mac_reg, u32 *backup)
929 {
930 	u32 i;
931 
932 	for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) {
933 		usb_write8(adapt, mac_reg[i], (u8)backup[i]);
934 	}
935 	usb_write32(adapt, mac_reg[i], backup[i]);
936 }
937 
path_adda_on(struct adapter * adapt,u32 * adda_reg,bool is_path_a_on,bool is2t)938 static void path_adda_on(struct adapter *adapt, u32 *adda_reg,
939 			 bool is_path_a_on, bool is2t)
940 {
941 	u32 path_on;
942 	u32 i;
943 
944 	if (!is2t) {
945 		path_on = 0x0bdb25a0;
946 		phy_set_bb_reg(adapt, adda_reg[0], bMaskDWord, 0x0b1b25a0);
947 	} else {
948 		path_on = is_path_a_on ? 0x04db25a4 : 0x0b1b25a4;
949 		phy_set_bb_reg(adapt, adda_reg[0], bMaskDWord, path_on);
950 	}
951 
952 	for (i = 1; i < IQK_ADDA_REG_NUM; i++)
953 		phy_set_bb_reg(adapt, adda_reg[i], bMaskDWord, path_on);
954 }
955 
mac_setting_calibration(struct adapter * adapt,u32 * mac_reg,u32 * backup)956 static void mac_setting_calibration(struct adapter *adapt, u32 *mac_reg, u32 *backup)
957 {
958 	u32 i = 0;
959 
960 	usb_write8(adapt, mac_reg[i], 0x3F);
961 
962 	for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) {
963 		usb_write8(adapt, mac_reg[i], (u8)(backup[i]&(~BIT3)));
964 	}
965 	usb_write8(adapt, mac_reg[i], (u8)(backup[i]&(~BIT5)));
966 }
967 
path_a_standby(struct adapter * adapt)968 static void path_a_standby(struct adapter *adapt)
969 {
970 
971 	phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x0);
972 	phy_set_bb_reg(adapt, 0x840, bMaskDWord, 0x00010000);
973 	phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
974 }
975 
pi_mode_switch(struct adapter * adapt,bool pi_mode)976 static void pi_mode_switch(struct adapter *adapt, bool pi_mode)
977 {
978 	u32 mode;
979 
980 	mode = pi_mode ? 0x01000100 : 0x01000000;
981 	phy_set_bb_reg(adapt, rFPGA0_XA_HSSIParameter1, bMaskDWord, mode);
982 	phy_set_bb_reg(adapt, rFPGA0_XB_HSSIParameter1, bMaskDWord, mode);
983 }
984 
simularity_compare(struct adapter * adapt,s32 resulta[][8],u8 c1,u8 c2)985 static bool simularity_compare(struct adapter *adapt, s32 resulta[][8],
986 			       u8 c1, u8 c2)
987 {
988 	u32 i, j, diff, sim_bitmap = 0, bound;
989 	struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
990 	struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
991 	u8 final_candidate[2] = {0xFF, 0xFF};	/* for path A and path B */
992 	bool result = true;
993 	s32 tmp1 = 0, tmp2 = 0;
994 
995 	if ((dm_odm->RFType == ODM_2T2R) || (dm_odm->RFType == ODM_2T3R) ||
996 	    (dm_odm->RFType == ODM_2T4R))
997 		bound = 8;
998 	else
999 		bound = 4;
1000 
1001 	for (i = 0; i < bound; i++) {
1002 		if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) {
1003 			if ((resulta[c1][i] & 0x00000200) != 0)
1004 				tmp1 = resulta[c1][i] | 0xFFFFFC00;
1005 			else
1006 				tmp1 = resulta[c1][i];
1007 
1008 			if ((resulta[c2][i] & 0x00000200) != 0)
1009 				tmp2 = resulta[c2][i] | 0xFFFFFC00;
1010 			else
1011 				tmp2 = resulta[c2][i];
1012 		} else {
1013 			tmp1 = resulta[c1][i];
1014 			tmp2 = resulta[c2][i];
1015 		}
1016 
1017 		diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1);
1018 
1019 		if (diff > MAX_TOLERANCE) {
1020 			if ((i == 2 || i == 6) && !sim_bitmap) {
1021 				if (resulta[c1][i] + resulta[c1][i+1] == 0)
1022 					final_candidate[(i/4)] = c2;
1023 				else if (resulta[c2][i] + resulta[c2][i+1] == 0)
1024 					final_candidate[(i/4)] = c1;
1025 				else
1026 					sim_bitmap = sim_bitmap | (1<<i);
1027 			} else {
1028 				sim_bitmap = sim_bitmap | (1<<i);
1029 			}
1030 		}
1031 	}
1032 
1033 	if (sim_bitmap == 0) {
1034 		for (i = 0; i < (bound/4); i++) {
1035 			if (final_candidate[i] != 0xFF) {
1036 				for (j = i*4; j < (i+1)*4-2; j++)
1037 					resulta[3][j] = resulta[final_candidate[i]][j];
1038 				result = false;
1039 			}
1040 		}
1041 		return result;
1042 	} else {
1043 		if (!(sim_bitmap & 0x03)) {		   /* path A TX OK */
1044 			for (i = 0; i < 2; i++)
1045 				resulta[3][i] = resulta[c1][i];
1046 		}
1047 		if (!(sim_bitmap & 0x0c)) {		   /* path A RX OK */
1048 			for (i = 2; i < 4; i++)
1049 				resulta[3][i] = resulta[c1][i];
1050 		}
1051 
1052 		if (!(sim_bitmap & 0x30)) { /* path B TX OK */
1053 			for (i = 4; i < 6; i++)
1054 				resulta[3][i] = resulta[c1][i];
1055 		}
1056 
1057 		if (!(sim_bitmap & 0xc0)) { /* path B RX OK */
1058 			for (i = 6; i < 8; i++)
1059 				resulta[3][i] = resulta[c1][i];
1060 		}
1061 		return false;
1062 	}
1063 }
1064 
phy_iq_calibrate(struct adapter * adapt,s32 result[][8],u8 t,bool is2t)1065 static void phy_iq_calibrate(struct adapter *adapt, s32 result[][8],
1066 			     u8 t, bool is2t)
1067 {
1068 	struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
1069 	struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
1070 	u32 i;
1071 	u8 path_a_ok, path_b_ok;
1072 	u32 adda_reg[IQK_ADDA_REG_NUM] = {
1073 					  rFPGA0_XCD_SwitchControl, rBlue_Tooth,
1074 					  rRx_Wait_CCA, rTx_CCK_RFON,
1075 					  rTx_CCK_BBON, rTx_OFDM_RFON,
1076 					  rTx_OFDM_BBON, rTx_To_Rx,
1077 					  rTx_To_Tx, rRx_CCK,
1078 					  rRx_OFDM, rRx_Wait_RIFS,
1079 					  rRx_TO_Rx, rStandby,
1080 					  rSleep, rPMPD_ANAEN};
1081 
1082 	u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
1083 					    REG_TXPAUSE, REG_BCN_CTRL,
1084 					    REG_BCN_CTRL_1, REG_GPIO_MUXCFG};
1085 
1086 	/* since 92C & 92D have the different define in IQK_BB_REG */
1087 	u32 iqk_bb_reg_92c[IQK_BB_REG_NUM] = {
1088 					      rOFDM0_TRxPathEnable, rOFDM0_TRMuxPar,
1089 					      rFPGA0_XCD_RFInterfaceSW, rConfig_AntA, rConfig_AntB,
1090 					      rFPGA0_XAB_RFInterfaceSW, rFPGA0_XA_RFInterfaceOE,
1091 					      rFPGA0_XB_RFInterfaceOE, rFPGA0_RFMOD};
1092 
1093 	u32 retry_count = 9;
1094 	if (*(dm_odm->mp_mode) == 1)
1095 		retry_count = 9;
1096 	else
1097 		retry_count = 2;
1098 
1099 	if (t == 0) {
1100 
1101 		/*  Save ADDA parameters, turn Path A ADDA on */
1102 		save_adda_registers(adapt, adda_reg, dm_odm->RFCalibrateInfo.ADDA_backup,
1103 				    IQK_ADDA_REG_NUM);
1104 		save_mac_registers(adapt, iqk_mac_reg,
1105 				   dm_odm->RFCalibrateInfo.IQK_MAC_backup);
1106 		save_adda_registers(adapt, iqk_bb_reg_92c,
1107 				    dm_odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM);
1108 	}
1109 
1110 	path_adda_on(adapt, adda_reg, true, is2t);
1111 	if (t == 0)
1112 		dm_odm->RFCalibrateInfo.bRfPiEnable = (u8)phy_query_bb_reg(adapt, rFPGA0_XA_HSSIParameter1,
1113 									   BIT(8));
1114 
1115 	if (!dm_odm->RFCalibrateInfo.bRfPiEnable) {
1116 		/*  Switch BB to PI mode to do IQ Calibration. */
1117 		pi_mode_switch(adapt, true);
1118 	}
1119 
1120 	/* BB setting */
1121 	phy_set_bb_reg(adapt, rFPGA0_RFMOD, BIT24, 0x00);
1122 	phy_set_bb_reg(adapt, rOFDM0_TRxPathEnable, bMaskDWord, 0x03a05600);
1123 	phy_set_bb_reg(adapt, rOFDM0_TRMuxPar, bMaskDWord, 0x000800e4);
1124 	phy_set_bb_reg(adapt, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, 0x22204000);
1125 
1126 	phy_set_bb_reg(adapt, rFPGA0_XAB_RFInterfaceSW, BIT10, 0x01);
1127 	phy_set_bb_reg(adapt, rFPGA0_XAB_RFInterfaceSW, BIT26, 0x01);
1128 	phy_set_bb_reg(adapt, rFPGA0_XA_RFInterfaceOE, BIT10, 0x00);
1129 	phy_set_bb_reg(adapt, rFPGA0_XB_RFInterfaceOE, BIT10, 0x00);
1130 
1131 	if (is2t) {
1132 		phy_set_bb_reg(adapt, rFPGA0_XA_LSSIParameter, bMaskDWord,
1133 			       0x00010000);
1134 		phy_set_bb_reg(adapt, rFPGA0_XB_LSSIParameter, bMaskDWord,
1135 			       0x00010000);
1136 	}
1137 
1138 	/* MAC settings */
1139 	mac_setting_calibration(adapt, iqk_mac_reg,
1140 				dm_odm->RFCalibrateInfo.IQK_MAC_backup);
1141 
1142 	/* Page B init */
1143 	/* AP or IQK */
1144 	phy_set_bb_reg(adapt, rConfig_AntA, bMaskDWord, 0x0f600000);
1145 
1146 	if (is2t)
1147 		phy_set_bb_reg(adapt, rConfig_AntB, bMaskDWord, 0x0f600000);
1148 
1149 	/*  IQ calibration setting */
1150 	phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
1151 	phy_set_bb_reg(adapt, rTx_IQK, bMaskDWord, 0x01007c00);
1152 	phy_set_bb_reg(adapt, rRx_IQK, bMaskDWord, 0x81004800);
1153 
1154 	for (i = 0; i < retry_count; i++) {
1155 		path_a_ok = phy_path_a_iqk(adapt, is2t);
1156 		if (path_a_ok == 0x01) {
1157 				result[t][0] = (phy_query_bb_reg(adapt, rTx_Power_Before_IQK_A,
1158 								 bMaskDWord)&0x3FF0000)>>16;
1159 				result[t][1] = (phy_query_bb_reg(adapt, rTx_Power_After_IQK_A,
1160 								 bMaskDWord)&0x3FF0000)>>16;
1161 			break;
1162 		}
1163 	}
1164 
1165 	for (i = 0; i < retry_count; i++) {
1166 		path_a_ok = phy_path_a_rx_iqk(adapt, is2t);
1167 		if (path_a_ok == 0x03) {
1168 				result[t][2] = (phy_query_bb_reg(adapt, rRx_Power_Before_IQK_A_2,
1169 								 bMaskDWord)&0x3FF0000)>>16;
1170 				result[t][3] = (phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2,
1171 								 bMaskDWord)&0x3FF0000)>>16;
1172 			break;
1173 		} else {
1174 			ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1175 				     ("Path A Rx IQK Fail!!\n"));
1176 		}
1177 	}
1178 
1179 	if (0x00 == path_a_ok) {
1180 		ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1181 			     ("Path A IQK failed!!\n"));
1182 	}
1183 
1184 	if (is2t) {
1185 		path_a_standby(adapt);
1186 
1187 		/*  Turn Path B ADDA on */
1188 		path_adda_on(adapt, adda_reg, false, is2t);
1189 
1190 		for (i = 0; i < retry_count; i++) {
1191 			path_b_ok = phy_path_b_iqk(adapt);
1192 			if (path_b_ok == 0x03) {
1193 				result[t][4] = (phy_query_bb_reg(adapt, rTx_Power_Before_IQK_B,
1194 								 bMaskDWord)&0x3FF0000)>>16;
1195 				result[t][5] = (phy_query_bb_reg(adapt, rTx_Power_After_IQK_B,
1196 								 bMaskDWord)&0x3FF0000)>>16;
1197 				result[t][6] = (phy_query_bb_reg(adapt, rRx_Power_Before_IQK_B_2,
1198 								 bMaskDWord)&0x3FF0000)>>16;
1199 				result[t][7] = (phy_query_bb_reg(adapt, rRx_Power_After_IQK_B_2,
1200 								 bMaskDWord)&0x3FF0000)>>16;
1201 				break;
1202 			} else if (i == (retry_count - 1) && path_b_ok == 0x01) {	/* Tx IQK OK */
1203 				result[t][4] = (phy_query_bb_reg(adapt, rTx_Power_Before_IQK_B,
1204 								 bMaskDWord)&0x3FF0000)>>16;
1205 				result[t][5] = (phy_query_bb_reg(adapt, rTx_Power_After_IQK_B,
1206 								 bMaskDWord)&0x3FF0000)>>16;
1207 			}
1208 		}
1209 
1210 		if (0x00 == path_b_ok) {
1211 			ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1212 				     ("Path B IQK failed!!\n"));
1213 		}
1214 	}
1215 
1216 	/* Back to BB mode, load original value */
1217 	phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0);
1218 
1219 	if (t != 0) {
1220 		if (!dm_odm->RFCalibrateInfo.bRfPiEnable) {
1221 			/* Switch back BB to SI mode after
1222 			 * finish IQ Calibration.
1223 			 */
1224 			pi_mode_switch(adapt, false);
1225 		}
1226 
1227 		/*  Reload ADDA power saving parameters */
1228 		reload_adda_reg(adapt, adda_reg, dm_odm->RFCalibrateInfo.ADDA_backup,
1229 				IQK_ADDA_REG_NUM);
1230 
1231 		/*  Reload MAC parameters */
1232 		reload_mac_registers(adapt, iqk_mac_reg,
1233 				     dm_odm->RFCalibrateInfo.IQK_MAC_backup);
1234 
1235 		reload_adda_reg(adapt, iqk_bb_reg_92c, dm_odm->RFCalibrateInfo.IQK_BB_backup,
1236 				IQK_BB_REG_NUM);
1237 
1238 		/*  Restore RX initial gain */
1239 		phy_set_bb_reg(adapt, rFPGA0_XA_LSSIParameter,
1240 			       bMaskDWord, 0x00032ed3);
1241 		if (is2t)
1242 			phy_set_bb_reg(adapt, rFPGA0_XB_LSSIParameter,
1243 				       bMaskDWord, 0x00032ed3);
1244 
1245 		/* load 0xe30 IQC default value */
1246 		phy_set_bb_reg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x01008c00);
1247 		phy_set_bb_reg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x01008c00);
1248 	}
1249 }
1250 
phy_lc_calibrate(struct adapter * adapt,bool is2t)1251 static void phy_lc_calibrate(struct adapter *adapt, bool is2t)
1252 {
1253 	u8 tmpreg;
1254 	u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
1255 
1256 	/* Check continuous TX and Packet TX */
1257 	tmpreg = usb_read8(adapt, 0xd03);
1258 
1259 	if ((tmpreg&0x70) != 0)
1260 		usb_write8(adapt, 0xd03, tmpreg&0x8F);
1261 	else
1262 		usb_write8(adapt, REG_TXPAUSE, 0xFF);
1263 
1264 	if ((tmpreg&0x70) != 0) {
1265 		/* 1. Read original RF mode */
1266 		/* Path-A */
1267 		rf_a_mode = phy_query_rf_reg(adapt, RF_PATH_A, RF_AC,
1268 					     bMask12Bits);
1269 
1270 		/* Path-B */
1271 		if (is2t)
1272 			rf_b_mode = phy_query_rf_reg(adapt, RF_PATH_B, RF_AC,
1273 						     bMask12Bits);
1274 
1275 		/* 2. Set RF mode = standby mode */
1276 		/* Path-A */
1277 		phy_set_rf_reg(adapt, RF_PATH_A, RF_AC, bMask12Bits,
1278 			       (rf_a_mode&0x8FFFF)|0x10000);
1279 
1280 		/* Path-B */
1281 		if (is2t)
1282 			phy_set_rf_reg(adapt, RF_PATH_B, RF_AC, bMask12Bits,
1283 				       (rf_b_mode&0x8FFFF)|0x10000);
1284 	}
1285 
1286 	/* 3. Read RF reg18 */
1287 	lc_cal = phy_query_rf_reg(adapt, RF_PATH_A, RF_CHNLBW, bMask12Bits);
1288 
1289 	/* 4. Set LC calibration begin bit15 */
1290 	phy_set_rf_reg(adapt, RF_PATH_A, RF_CHNLBW, bMask12Bits,
1291 		       lc_cal|0x08000);
1292 
1293 	msleep(100);
1294 
1295 	/* Restore original situation */
1296 	if ((tmpreg&0x70) != 0) {
1297 		/* Deal with continuous TX case */
1298 		/* Path-A */
1299 		usb_write8(adapt, 0xd03, tmpreg);
1300 		phy_set_rf_reg(adapt, RF_PATH_A, RF_AC, bMask12Bits, rf_a_mode);
1301 
1302 		/* Path-B */
1303 		if (is2t)
1304 			phy_set_rf_reg(adapt, RF_PATH_B, RF_AC, bMask12Bits,
1305 				       rf_b_mode);
1306 	} else {
1307 		/* Deal with Packet TX case */
1308 		usb_write8(adapt, REG_TXPAUSE, 0x00);
1309 	}
1310 }
1311 
rtl88eu_phy_iq_calibrate(struct adapter * adapt,bool recovery)1312 void rtl88eu_phy_iq_calibrate(struct adapter *adapt, bool recovery)
1313 {
1314 	struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
1315 	struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
1316 	s32 result[4][8];
1317 	u8 i, final, chn_index;
1318 	bool pathaok, pathbok;
1319 	s32 reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4,
1320 	    reg_ecc;
1321 	bool is12simular, is13simular, is23simular;
1322 	bool singletone = false, carrier_sup = false;
1323 	u32 iqk_bb_reg_92c[IQK_BB_REG_NUM] = {
1324 		rOFDM0_XARxIQImbalance, rOFDM0_XBRxIQImbalance,
1325 		rOFDM0_ECCAThreshold, rOFDM0_AGCRSSITable,
1326 		rOFDM0_XATxIQImbalance, rOFDM0_XBTxIQImbalance,
1327 		rOFDM0_XCTxAFE, rOFDM0_XDTxAFE,
1328 		rOFDM0_RxIQExtAnta};
1329 	bool is2t;
1330 
1331 	is2t = (dm_odm->RFType == ODM_2T2R) ? true : false;
1332 
1333 	if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION))
1334 		return;
1335 
1336 	if (singletone || carrier_sup)
1337 		return;
1338 
1339 	if (recovery) {
1340 		ODM_RT_TRACE(dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD,
1341 			     ("phy_iq_calibrate: Return due to recovery!\n"));
1342 		reload_adda_reg(adapt, iqk_bb_reg_92c,
1343 				dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9);
1344 		return;
1345 	}
1346 
1347 	for (i = 0; i < 8; i++) {
1348 		result[0][i] = 0;
1349 		result[1][i] = 0;
1350 		result[2][i] = 0;
1351 		if ((i == 0) || (i == 2) || (i == 4)  || (i == 6))
1352 			result[3][i] = 0x100;
1353 		else
1354 			result[3][i] = 0;
1355 	}
1356 	final = 0xff;
1357 	pathaok = false;
1358 	pathbok = false;
1359 	is12simular = false;
1360 	is23simular = false;
1361 	is13simular = false;
1362 
1363 	for (i = 0; i < 3; i++) {
1364 		phy_iq_calibrate(adapt, result, i, is2t);
1365 
1366 		if (i == 1) {
1367 			is12simular = simularity_compare(adapt, result, 0, 1);
1368 			if (is12simular) {
1369 				final = 0;
1370 				break;
1371 			}
1372 		}
1373 
1374 		if (i == 2) {
1375 			is13simular = simularity_compare(adapt, result, 0, 2);
1376 			if (is13simular) {
1377 				final = 0;
1378 				break;
1379 			}
1380 			is23simular = simularity_compare(adapt, result, 1, 2);
1381 			if (is23simular)
1382 				final = 1;
1383 			else
1384 				final = 3;
1385 		}
1386 	}
1387 
1388 	for (i = 0; i < 4; i++) {
1389 		reg_e94 = result[i][0];
1390 		reg_e9c = result[i][1];
1391 		reg_ea4 = result[i][2];
1392 		reg_eac = result[i][3];
1393 		reg_eb4 = result[i][4];
1394 		reg_ebc = result[i][5];
1395 		reg_ec4 = result[i][6];
1396 		reg_ecc = result[i][7];
1397 	}
1398 
1399 	if (final != 0xff) {
1400 		reg_e94 = result[final][0];
1401 		reg_e9c = result[final][1];
1402 		reg_ea4 = result[final][2];
1403 		reg_eac = result[final][3];
1404 		reg_eb4 = result[final][4];
1405 		reg_ebc = result[final][5];
1406 		dm_odm->RFCalibrateInfo.RegE94 = reg_e94;
1407 		dm_odm->RFCalibrateInfo.RegE9C = reg_e9c;
1408 		dm_odm->RFCalibrateInfo.RegEB4 = reg_eb4;
1409 		dm_odm->RFCalibrateInfo.RegEBC = reg_ebc;
1410 		reg_ec4 = result[final][6];
1411 		reg_ecc = result[final][7];
1412 		pathaok = true;
1413 		pathbok = true;
1414 	} else {
1415 		ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1416 			     ("IQK: FAIL use default value\n"));
1417 		dm_odm->RFCalibrateInfo.RegE94 = 0x100;
1418 		dm_odm->RFCalibrateInfo.RegEB4 = 0x100;
1419 		dm_odm->RFCalibrateInfo.RegE9C = 0x0;
1420 		dm_odm->RFCalibrateInfo.RegEBC = 0x0;
1421 	}
1422 	if (reg_e94 != 0)
1423 		patha_fill_iqk(adapt, pathaok, result, final,
1424 			       (reg_ea4 == 0));
1425 	if (is2t) {
1426 		if (reg_eb4 != 0)
1427 			pathb_fill_iqk(adapt, pathbok, result, final,
1428 				       (reg_ec4 == 0));
1429 	}
1430 
1431 	chn_index = get_right_chnl_for_iqk(hal_data->CurrentChannel);
1432 
1433 	if (final < 4) {
1434 		for (i = 0; i < IQK_Matrix_REG_NUM; i++)
1435 			dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[chn_index].Value[0][i] = result[final][i];
1436 		dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[chn_index].bIQKDone = true;
1437 	}
1438 
1439 	save_adda_registers(adapt, iqk_bb_reg_92c,
1440 			    dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9);
1441 }
1442 
rtl88eu_phy_lc_calibrate(struct adapter * adapt)1443 void rtl88eu_phy_lc_calibrate(struct adapter *adapt)
1444 {
1445 	bool singletone = false, carrier_sup = false;
1446 	u32 timeout = 2000, timecount = 0;
1447 	struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
1448 	struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
1449 
1450 	if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION))
1451 		return;
1452 	if (singletone || carrier_sup)
1453 		return;
1454 
1455 	while (*(dm_odm->pbScanInProcess) && timecount < timeout) {
1456 		mdelay(50);
1457 		timecount += 50;
1458 	}
1459 
1460 	dm_odm->RFCalibrateInfo.bLCKInProgress = true;
1461 
1462 	if (dm_odm->RFType == ODM_2T2R) {
1463 		phy_lc_calibrate(adapt, true);
1464 	} else {
1465 		/* For 88C 1T1R */
1466 		phy_lc_calibrate(adapt, false);
1467 	}
1468 
1469 	dm_odm->RFCalibrateInfo.bLCKInProgress = false;
1470 }
1471