GNU Linux-libre 4.19.211-gnu1
[releases.git] / drivers / staging / rtl8188eu / hal / phy.c
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }