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