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