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