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