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