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