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