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