These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[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, 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                 } 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, (BIT(26) | BIT(27)),
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;
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
655         if (!(reg_eac & BIT(28)) &&
656             (((reg_e94 & 0x03FF0000)>>16) != 0x142) &&
657             (((reg_e9c & 0x03FF0000)>>16) != 0x42))
658                 result |= 0x01;
659         return result;
660 }
661
662 static u8 phy_path_a_rx_iqk(struct adapter *adapt, bool configPathB)
663 {
664         u32 reg_eac, reg_e94, reg_e9c, reg_ea4, u4tmp;
665         u8 result = 0x00;
666         struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
667         struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
668
669         /* 1 Get TXIMR setting */
670         /* modify RXIQK mode table */
671         phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000);
672         phy_set_rf_reg(adapt, RF_PATH_A, RF_WE_LUT, bRFRegOffsetMask, 0x800a0);
673         phy_set_rf_reg(adapt, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000);
674         phy_set_rf_reg(adapt, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f);
675         phy_set_rf_reg(adapt, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf117B);
676
677         /* PA,PAD off */
678         phy_set_rf_reg(adapt, RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x980);
679         phy_set_rf_reg(adapt, RF_PATH_A, 0x56, bRFRegOffsetMask, 0x51000);
680
681         phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
682
683         /* IQK setting */
684         phy_set_bb_reg(adapt, rTx_IQK, bMaskDWord, 0x01007c00);
685         phy_set_bb_reg(adapt, rRx_IQK, bMaskDWord, 0x81004800);
686
687         /* path-A IQK setting */
688         phy_set_bb_reg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1c);
689         phy_set_bb_reg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x30008c1c);
690         phy_set_bb_reg(adapt, rTx_IQK_PI_A, bMaskDWord, 0x82160c1f);
691         phy_set_bb_reg(adapt, rRx_IQK_PI_A, bMaskDWord, 0x28160000);
692
693         /* LO calibration setting */
694         phy_set_bb_reg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911);
695
696         /* One shot, path A LOK & IQK */
697         phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
698         phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
699
700         /* delay x ms */
701         mdelay(IQK_DELAY_TIME_88E);
702
703         /* Check failed */
704         reg_eac = phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord);
705         reg_e94 = phy_query_bb_reg(adapt, rTx_Power_Before_IQK_A, bMaskDWord);
706         reg_e9c = phy_query_bb_reg(adapt, rTx_Power_After_IQK_A, bMaskDWord);
707
708         if (!(reg_eac & BIT(28)) &&
709             (((reg_e94 & 0x03FF0000)>>16) != 0x142) &&
710             (((reg_e9c & 0x03FF0000)>>16) != 0x42))
711                 result |= 0x01;
712         else                                    /* if Tx not OK, ignore Rx */
713                 return result;
714
715         u4tmp = 0x80007C00 | (reg_e94&0x3FF0000)  | ((reg_e9c&0x3FF0000) >> 16);
716         phy_set_bb_reg(adapt, rTx_IQK, bMaskDWord, u4tmp);
717
718         /* 1 RX IQK */
719         /* modify RXIQK mode table */
720         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
721                      ("Path-A Rx IQK modify RXIQK mode table 2!\n"));
722         phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000);
723         phy_set_rf_reg(adapt, RF_PATH_A, RF_WE_LUT, bRFRegOffsetMask, 0x800a0);
724         phy_set_rf_reg(adapt, RF_PATH_A, RF_RCK_OS, bRFRegOffsetMask, 0x30000);
725         phy_set_rf_reg(adapt, RF_PATH_A, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f);
726         phy_set_rf_reg(adapt, RF_PATH_A, RF_TXPA_G2, bRFRegOffsetMask, 0xf7ffa);
727         phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
728
729         /* IQK setting */
730         phy_set_bb_reg(adapt, rRx_IQK, bMaskDWord, 0x01004800);
731
732         /* path-A IQK setting */
733         phy_set_bb_reg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x38008c1c);
734         phy_set_bb_reg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x18008c1c);
735         phy_set_bb_reg(adapt, rTx_IQK_PI_A, bMaskDWord, 0x82160c05);
736         phy_set_bb_reg(adapt, rRx_IQK_PI_A, bMaskDWord, 0x28160c1f);
737
738         /* LO calibration setting */
739         phy_set_bb_reg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911);
740
741         phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
742         phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
743
744         mdelay(IQK_DELAY_TIME_88E);
745
746         /*  Check failed */
747         reg_eac = phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord);
748         reg_e94 = phy_query_bb_reg(adapt, rTx_Power_Before_IQK_A, bMaskDWord);
749         reg_e9c = phy_query_bb_reg(adapt, rTx_Power_After_IQK_A, bMaskDWord);
750         reg_ea4 = phy_query_bb_reg(adapt, rRx_Power_Before_IQK_A_2, bMaskDWord);
751
752         /* reload RF 0xdf */
753         phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000);
754         phy_set_rf_reg(adapt, RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x180);
755
756         if (!(reg_eac & BIT(27)) && /* if Tx is OK, check whether Rx is OK */
757             (((reg_ea4 & 0x03FF0000)>>16) != 0x132) &&
758             (((reg_eac & 0x03FF0000)>>16) != 0x36))
759                 result |= 0x02;
760         else
761                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
762                              ("Path A Rx IQK fail!!\n"));
763
764         return result;
765 }
766
767 static u8 phy_path_b_iqk(struct adapter *adapt)
768 {
769         u32 regeac, regeb4, regebc, regec4, regecc;
770         u8 result = 0x00;
771         struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
772         struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
773
774         /* One shot, path B LOK & IQK */
775         phy_set_bb_reg(adapt, rIQK_AGC_Cont, bMaskDWord, 0x00000002);
776         phy_set_bb_reg(adapt, rIQK_AGC_Cont, bMaskDWord, 0x00000000);
777
778         mdelay(IQK_DELAY_TIME_88E);
779
780         regeac = phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord);
781         regeb4 = phy_query_bb_reg(adapt, rTx_Power_Before_IQK_B, bMaskDWord);
782         regebc = phy_query_bb_reg(adapt, rTx_Power_After_IQK_B, bMaskDWord);
783         regec4 = phy_query_bb_reg(adapt, rRx_Power_Before_IQK_B_2, bMaskDWord);
784         regecc = phy_query_bb_reg(adapt, rRx_Power_After_IQK_B_2, bMaskDWord);
785
786         if (!(regeac & BIT(31)) &&
787             (((regeb4 & 0x03FF0000)>>16) != 0x142) &&
788             (((regebc & 0x03FF0000)>>16) != 0x42))
789                 result |= 0x01;
790         else
791                 return result;
792
793         if (!(regeac & BIT(30)) &&
794             (((regec4 & 0x03FF0000)>>16) != 0x132) &&
795             (((regecc & 0x03FF0000)>>16) != 0x36))
796                 result |= 0x02;
797         else
798                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION,
799                              ODM_DBG_LOUD,  ("Path B Rx IQK fail!!\n"));
800         return result;
801 }
802
803 static void patha_fill_iqk(struct adapter *adapt, bool iqkok, s32 result[][8],
804                            u8 final_candidate, bool txonly)
805 {
806         u32 oldval_0, x, tx0_a, reg;
807         s32 y, tx0_c;
808
809         if (final_candidate == 0xFF) {
810                 return;
811         } else if (iqkok) {
812                 oldval_0 = (phy_query_bb_reg(adapt, rOFDM0_XATxIQImbalance, bMaskDWord) >> 22) & 0x3FF;
813
814                 x = result[final_candidate][0];
815                 if ((x & 0x00000200) != 0)
816                         x = x | 0xFFFFFC00;
817
818                 tx0_a = (x * oldval_0) >> 8;
819                 phy_set_bb_reg(adapt, rOFDM0_XATxIQImbalance, 0x3FF, tx0_a);
820                 phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(31),
821                                ((x * oldval_0>>7) & 0x1));
822
823                 y = result[final_candidate][1];
824                 if ((y & 0x00000200) != 0)
825                         y = y | 0xFFFFFC00;
826
827                 tx0_c = (y * oldval_0) >> 8;
828                 phy_set_bb_reg(adapt, rOFDM0_XCTxAFE, 0xF0000000,
829                                ((tx0_c&0x3C0)>>6));
830                 phy_set_bb_reg(adapt, rOFDM0_XATxIQImbalance, 0x003F0000,
831                                (tx0_c&0x3F));
832                 phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(29),
833                                ((y * oldval_0>>7) & 0x1));
834
835                 if (txonly)
836                         return;
837
838                 reg = result[final_candidate][2];
839                 phy_set_bb_reg(adapt, rOFDM0_XARxIQImbalance, 0x3FF, reg);
840
841                 reg = result[final_candidate][3] & 0x3F;
842                 phy_set_bb_reg(adapt, rOFDM0_XARxIQImbalance, 0xFC00, reg);
843
844                 reg = (result[final_candidate][3] >> 6) & 0xF;
845                 phy_set_bb_reg(adapt, rOFDM0_RxIQExtAnta, 0xF0000000, reg);
846         }
847 }
848
849 static void pathb_fill_iqk(struct adapter *adapt, bool iqkok, s32 result[][8],
850                            u8 final_candidate, bool txonly)
851 {
852         u32 oldval_1, x, tx1_a, reg;
853         s32 y, tx1_c;
854
855         if (final_candidate == 0xFF) {
856                 return;
857         } else if (iqkok) {
858                 oldval_1 = (phy_query_bb_reg(adapt, rOFDM0_XBTxIQImbalance, bMaskDWord) >> 22) & 0x3FF;
859
860                 x = result[final_candidate][4];
861                 if ((x & 0x00000200) != 0)
862                         x = x | 0xFFFFFC00;
863                 tx1_a = (x * oldval_1) >> 8;
864                 phy_set_bb_reg(adapt, rOFDM0_XBTxIQImbalance, 0x3FF, tx1_a);
865
866                 phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(27),
867                                ((x * oldval_1>>7) & 0x1));
868
869                 y = result[final_candidate][5];
870                 if ((y & 0x00000200) != 0)
871                         y = y | 0xFFFFFC00;
872
873                 tx1_c = (y * oldval_1) >> 8;
874
875                 phy_set_bb_reg(adapt, rOFDM0_XDTxAFE, 0xF0000000,
876                                ((tx1_c&0x3C0)>>6));
877                 phy_set_bb_reg(adapt, rOFDM0_XBTxIQImbalance, 0x003F0000,
878                                (tx1_c&0x3F));
879                 phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(25),
880                                ((y * oldval_1>>7) & 0x1));
881
882                 if (txonly)
883                         return;
884
885                 reg = result[final_candidate][6];
886                 phy_set_bb_reg(adapt, rOFDM0_XBRxIQImbalance, 0x3FF, reg);
887
888                 reg = result[final_candidate][7] & 0x3F;
889                 phy_set_bb_reg(adapt, rOFDM0_XBRxIQImbalance, 0xFC00, reg);
890
891                 reg = (result[final_candidate][7] >> 6) & 0xF;
892                 phy_set_bb_reg(adapt, rOFDM0_AGCRSSITable, 0x0000F000, reg);
893         }
894 }
895
896 static void save_adda_registers(struct adapter *adapt, u32 *addareg,
897                                 u32 *backup, u32 register_num)
898 {
899         u32 i;
900
901         for (i = 0; i < register_num; i++) {
902                 backup[i] = phy_query_bb_reg(adapt, addareg[i], bMaskDWord);
903         }
904 }
905
906 static void save_mac_registers(struct adapter *adapt, u32 *mac_reg,
907                                u32 *backup)
908 {
909         u32 i;
910
911         for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) {
912                 backup[i] = usb_read8(adapt, mac_reg[i]);
913         }
914         backup[i] = usb_read32(adapt, mac_reg[i]);
915 }
916
917 static void reload_adda_reg(struct adapter *adapt, u32 *adda_reg,
918                             u32 *backup, u32 regiester_num)
919 {
920         u32 i;
921
922         for (i = 0; i < regiester_num; i++)
923                 phy_set_bb_reg(adapt, adda_reg[i], bMaskDWord, backup[i]);
924 }
925
926 static void reload_mac_registers(struct adapter *adapt,
927                                  u32 *mac_reg, u32 *backup)
928 {
929         u32 i;
930
931         for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) {
932                 usb_write8(adapt, mac_reg[i], (u8)backup[i]);
933         }
934         usb_write32(adapt, mac_reg[i], backup[i]);
935 }
936
937 static void path_adda_on(struct adapter *adapt, u32 *adda_reg,
938                          bool is_path_a_on, bool is2t)
939 {
940         u32 path_on;
941         u32 i;
942
943         if (!is2t) {
944                 path_on = 0x0bdb25a0;
945                 phy_set_bb_reg(adapt, adda_reg[0], bMaskDWord, 0x0b1b25a0);
946         } else {
947                 path_on = is_path_a_on ? 0x04db25a4 : 0x0b1b25a4;
948                 phy_set_bb_reg(adapt, adda_reg[0], bMaskDWord, path_on);
949         }
950
951         for (i = 1; i < IQK_ADDA_REG_NUM; i++)
952                 phy_set_bb_reg(adapt, adda_reg[i], bMaskDWord, path_on);
953 }
954
955 static void mac_setting_calibration(struct adapter *adapt, u32 *mac_reg, u32 *backup)
956 {
957         u32 i = 0;
958
959         usb_write8(adapt, mac_reg[i], 0x3F);
960
961         for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) {
962                 usb_write8(adapt, mac_reg[i], (u8)(backup[i]&(~BIT(3))));
963         }
964         usb_write8(adapt, mac_reg[i], (u8)(backup[i]&(~BIT(5))));
965 }
966
967 static void path_a_standby(struct adapter *adapt)
968 {
969
970         phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x0);
971         phy_set_bb_reg(adapt, 0x840, bMaskDWord, 0x00010000);
972         phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
973 }
974
975 static void pi_mode_switch(struct adapter *adapt, bool pi_mode)
976 {
977         u32 mode;
978
979         mode = pi_mode ? 0x01000100 : 0x01000000;
980         phy_set_bb_reg(adapt, rFPGA0_XA_HSSIParameter1, bMaskDWord, mode);
981         phy_set_bb_reg(adapt, rFPGA0_XB_HSSIParameter1, bMaskDWord, mode);
982 }
983
984 static bool simularity_compare(struct adapter *adapt, s32 resulta[][8],
985                                u8 c1, u8 c2)
986 {
987         u32 i, j, diff, sim_bitmap = 0, bound;
988         struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
989         struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
990         u8 final_candidate[2] = {0xFF, 0xFF};   /* for path A and path B */
991         bool result = true;
992         s32 tmp1 = 0, tmp2 = 0;
993
994         if ((dm_odm->RFType == ODM_2T2R) || (dm_odm->RFType == ODM_2T3R) ||
995             (dm_odm->RFType == ODM_2T4R))
996                 bound = 8;
997         else
998                 bound = 4;
999
1000         for (i = 0; i < bound; i++) {
1001                 if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) {
1002                         if ((resulta[c1][i] & 0x00000200) != 0)
1003                                 tmp1 = resulta[c1][i] | 0xFFFFFC00;
1004                         else
1005                                 tmp1 = resulta[c1][i];
1006
1007                         if ((resulta[c2][i] & 0x00000200) != 0)
1008                                 tmp2 = resulta[c2][i] | 0xFFFFFC00;
1009                         else
1010                                 tmp2 = resulta[c2][i];
1011                 } else {
1012                         tmp1 = resulta[c1][i];
1013                         tmp2 = resulta[c2][i];
1014                 }
1015
1016                 diff = abs(tmp1 - tmp2);
1017
1018                 if (diff > MAX_TOLERANCE) {
1019                         if ((i == 2 || i == 6) && !sim_bitmap) {
1020                                 if (resulta[c1][i] + resulta[c1][i+1] == 0)
1021                                         final_candidate[(i/4)] = c2;
1022                                 else if (resulta[c2][i] + resulta[c2][i+1] == 0)
1023                                         final_candidate[(i/4)] = c1;
1024                                 else
1025                                         sim_bitmap = sim_bitmap | (1<<i);
1026                         } else {
1027                                 sim_bitmap = sim_bitmap | (1<<i);
1028                         }
1029                 }
1030         }
1031
1032         if (sim_bitmap == 0) {
1033                 for (i = 0; i < (bound/4); i++) {
1034                         if (final_candidate[i] != 0xFF) {
1035                                 for (j = i*4; j < (i+1)*4-2; j++)
1036                                         resulta[3][j] = resulta[final_candidate[i]][j];
1037                                 result = false;
1038                         }
1039                 }
1040                 return result;
1041         } else {
1042                 if (!(sim_bitmap & 0x03)) {                /* path A TX OK */
1043                         for (i = 0; i < 2; i++)
1044                                 resulta[3][i] = resulta[c1][i];
1045                 }
1046                 if (!(sim_bitmap & 0x0c)) {                /* path A RX OK */
1047                         for (i = 2; i < 4; i++)
1048                                 resulta[3][i] = resulta[c1][i];
1049                 }
1050
1051                 if (!(sim_bitmap & 0x30)) { /* path B TX OK */
1052                         for (i = 4; i < 6; i++)
1053                                 resulta[3][i] = resulta[c1][i];
1054                 }
1055
1056                 if (!(sim_bitmap & 0xc0)) { /* path B RX OK */
1057                         for (i = 6; i < 8; i++)
1058                                 resulta[3][i] = resulta[c1][i];
1059                 }
1060                 return false;
1061         }
1062 }
1063
1064 static void phy_iq_calibrate(struct adapter *adapt, s32 result[][8],
1065                              u8 t, bool is2t)
1066 {
1067         struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
1068         struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
1069         u32 i;
1070         u8 path_a_ok, path_b_ok;
1071         u32 adda_reg[IQK_ADDA_REG_NUM] = {
1072                                           rFPGA0_XCD_SwitchControl, rBlue_Tooth,
1073                                           rRx_Wait_CCA, rTx_CCK_RFON,
1074                                           rTx_CCK_BBON, rTx_OFDM_RFON,
1075                                           rTx_OFDM_BBON, rTx_To_Rx,
1076                                           rTx_To_Tx, rRx_CCK,
1077                                           rRx_OFDM, rRx_Wait_RIFS,
1078                                           rRx_TO_Rx, rStandby,
1079                                           rSleep, rPMPD_ANAEN};
1080
1081         u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
1082                                             REG_TXPAUSE, REG_BCN_CTRL,
1083                                             REG_BCN_CTRL_1, REG_GPIO_MUXCFG};
1084
1085         /* since 92C & 92D have the different define in IQK_BB_REG */
1086         u32 iqk_bb_reg_92c[IQK_BB_REG_NUM] = {
1087                                               rOFDM0_TRxPathEnable, rOFDM0_TRMuxPar,
1088                                               rFPGA0_XCD_RFInterfaceSW, rConfig_AntA, rConfig_AntB,
1089                                               rFPGA0_XAB_RFInterfaceSW, rFPGA0_XA_RFInterfaceOE,
1090                                               rFPGA0_XB_RFInterfaceOE, rFPGA0_RFMOD};
1091
1092         u32 retry_count = 9;
1093         if (*(dm_odm->mp_mode) == 1)
1094                 retry_count = 9;
1095         else
1096                 retry_count = 2;
1097
1098         if (t == 0) {
1099
1100                 /*  Save ADDA parameters, turn Path A ADDA on */
1101                 save_adda_registers(adapt, adda_reg, dm_odm->RFCalibrateInfo.ADDA_backup,
1102                                     IQK_ADDA_REG_NUM);
1103                 save_mac_registers(adapt, iqk_mac_reg,
1104                                    dm_odm->RFCalibrateInfo.IQK_MAC_backup);
1105                 save_adda_registers(adapt, iqk_bb_reg_92c,
1106                                     dm_odm->RFCalibrateInfo.IQK_BB_backup, IQK_BB_REG_NUM);
1107         }
1108
1109         path_adda_on(adapt, adda_reg, true, is2t);
1110         if (t == 0)
1111                 dm_odm->RFCalibrateInfo.bRfPiEnable = (u8)phy_query_bb_reg(adapt, rFPGA0_XA_HSSIParameter1,
1112                                                                            BIT(8));
1113
1114         if (!dm_odm->RFCalibrateInfo.bRfPiEnable) {
1115                 /*  Switch BB to PI mode to do IQ Calibration. */
1116                 pi_mode_switch(adapt, true);
1117         }
1118
1119         /* BB setting */
1120         phy_set_bb_reg(adapt, rFPGA0_RFMOD, BIT(24), 0x00);
1121         phy_set_bb_reg(adapt, rOFDM0_TRxPathEnable, bMaskDWord, 0x03a05600);
1122         phy_set_bb_reg(adapt, rOFDM0_TRMuxPar, bMaskDWord, 0x000800e4);
1123         phy_set_bb_reg(adapt, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, 0x22204000);
1124
1125         phy_set_bb_reg(adapt, rFPGA0_XAB_RFInterfaceSW, BIT(10), 0x01);
1126         phy_set_bb_reg(adapt, rFPGA0_XAB_RFInterfaceSW, BIT(26), 0x01);
1127         phy_set_bb_reg(adapt, rFPGA0_XA_RFInterfaceOE, BIT(10), 0x00);
1128         phy_set_bb_reg(adapt, rFPGA0_XB_RFInterfaceOE, BIT(10), 0x00);
1129
1130         if (is2t) {
1131                 phy_set_bb_reg(adapt, rFPGA0_XA_LSSIParameter, bMaskDWord,
1132                                0x00010000);
1133                 phy_set_bb_reg(adapt, rFPGA0_XB_LSSIParameter, bMaskDWord,
1134                                0x00010000);
1135         }
1136
1137         /* MAC settings */
1138         mac_setting_calibration(adapt, iqk_mac_reg,
1139                                 dm_odm->RFCalibrateInfo.IQK_MAC_backup);
1140
1141         /* Page B init */
1142         /* AP or IQK */
1143         phy_set_bb_reg(adapt, rConfig_AntA, bMaskDWord, 0x0f600000);
1144
1145         if (is2t)
1146                 phy_set_bb_reg(adapt, rConfig_AntB, bMaskDWord, 0x0f600000);
1147
1148         /*  IQ calibration setting */
1149         phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
1150         phy_set_bb_reg(adapt, rTx_IQK, bMaskDWord, 0x01007c00);
1151         phy_set_bb_reg(adapt, rRx_IQK, bMaskDWord, 0x81004800);
1152
1153         for (i = 0; i < retry_count; i++) {
1154                 path_a_ok = phy_path_a_iqk(adapt, is2t);
1155                 if (path_a_ok == 0x01) {
1156                                 result[t][0] = (phy_query_bb_reg(adapt, rTx_Power_Before_IQK_A,
1157                                                                  bMaskDWord)&0x3FF0000)>>16;
1158                                 result[t][1] = (phy_query_bb_reg(adapt, rTx_Power_After_IQK_A,
1159                                                                  bMaskDWord)&0x3FF0000)>>16;
1160                         break;
1161                 }
1162         }
1163
1164         for (i = 0; i < retry_count; i++) {
1165                 path_a_ok = phy_path_a_rx_iqk(adapt, is2t);
1166                 if (path_a_ok == 0x03) {
1167                                 result[t][2] = (phy_query_bb_reg(adapt, rRx_Power_Before_IQK_A_2,
1168                                                                  bMaskDWord)&0x3FF0000)>>16;
1169                                 result[t][3] = (phy_query_bb_reg(adapt, rRx_Power_After_IQK_A_2,
1170                                                                  bMaskDWord)&0x3FF0000)>>16;
1171                         break;
1172                 } else {
1173                         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1174                                      ("Path A Rx IQK Fail!!\n"));
1175                 }
1176         }
1177
1178         if (0x00 == path_a_ok) {
1179                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1180                              ("Path A IQK failed!!\n"));
1181         }
1182
1183         if (is2t) {
1184                 path_a_standby(adapt);
1185
1186                 /*  Turn Path B ADDA on */
1187                 path_adda_on(adapt, adda_reg, false, is2t);
1188
1189                 for (i = 0; i < retry_count; i++) {
1190                         path_b_ok = phy_path_b_iqk(adapt);
1191                         if (path_b_ok == 0x03) {
1192                                 result[t][4] = (phy_query_bb_reg(adapt, rTx_Power_Before_IQK_B,
1193                                                                  bMaskDWord)&0x3FF0000)>>16;
1194                                 result[t][5] = (phy_query_bb_reg(adapt, rTx_Power_After_IQK_B,
1195                                                                  bMaskDWord)&0x3FF0000)>>16;
1196                                 result[t][6] = (phy_query_bb_reg(adapt, rRx_Power_Before_IQK_B_2,
1197                                                                  bMaskDWord)&0x3FF0000)>>16;
1198                                 result[t][7] = (phy_query_bb_reg(adapt, rRx_Power_After_IQK_B_2,
1199                                                                  bMaskDWord)&0x3FF0000)>>16;
1200                                 break;
1201                         } else if (i == (retry_count - 1) && path_b_ok == 0x01) {       /* Tx IQK OK */
1202                                 result[t][4] = (phy_query_bb_reg(adapt, rTx_Power_Before_IQK_B,
1203                                                                  bMaskDWord)&0x3FF0000)>>16;
1204                                 result[t][5] = (phy_query_bb_reg(adapt, rTx_Power_After_IQK_B,
1205                                                                  bMaskDWord)&0x3FF0000)>>16;
1206                         }
1207                 }
1208
1209                 if (0x00 == path_b_ok) {
1210                         ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1211                                      ("Path B IQK failed!!\n"));
1212                 }
1213         }
1214
1215         /* Back to BB mode, load original value */
1216         phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0);
1217
1218         if (t != 0) {
1219                 if (!dm_odm->RFCalibrateInfo.bRfPiEnable) {
1220                         /* Switch back BB to SI mode after
1221                          * finish IQ Calibration.
1222                          */
1223                         pi_mode_switch(adapt, false);
1224                 }
1225
1226                 /*  Reload ADDA power saving parameters */
1227                 reload_adda_reg(adapt, adda_reg, dm_odm->RFCalibrateInfo.ADDA_backup,
1228                                 IQK_ADDA_REG_NUM);
1229
1230                 /*  Reload MAC parameters */
1231                 reload_mac_registers(adapt, iqk_mac_reg,
1232                                      dm_odm->RFCalibrateInfo.IQK_MAC_backup);
1233
1234                 reload_adda_reg(adapt, iqk_bb_reg_92c, dm_odm->RFCalibrateInfo.IQK_BB_backup,
1235                                 IQK_BB_REG_NUM);
1236
1237                 /*  Restore RX initial gain */
1238                 phy_set_bb_reg(adapt, rFPGA0_XA_LSSIParameter,
1239                                bMaskDWord, 0x00032ed3);
1240                 if (is2t)
1241                         phy_set_bb_reg(adapt, rFPGA0_XB_LSSIParameter,
1242                                        bMaskDWord, 0x00032ed3);
1243
1244                 /* load 0xe30 IQC default value */
1245                 phy_set_bb_reg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x01008c00);
1246                 phy_set_bb_reg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x01008c00);
1247         }
1248 }
1249
1250 static void phy_lc_calibrate(struct adapter *adapt, bool is2t)
1251 {
1252         u8 tmpreg;
1253         u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
1254
1255         /* Check continuous TX and Packet TX */
1256         tmpreg = usb_read8(adapt, 0xd03);
1257
1258         if ((tmpreg&0x70) != 0)
1259                 usb_write8(adapt, 0xd03, tmpreg&0x8F);
1260         else
1261                 usb_write8(adapt, REG_TXPAUSE, 0xFF);
1262
1263         if ((tmpreg&0x70) != 0) {
1264                 /* 1. Read original RF mode */
1265                 /* Path-A */
1266                 rf_a_mode = phy_query_rf_reg(adapt, RF_PATH_A, RF_AC,
1267                                              bMask12Bits);
1268
1269                 /* Path-B */
1270                 if (is2t)
1271                         rf_b_mode = phy_query_rf_reg(adapt, RF_PATH_B, RF_AC,
1272                                                      bMask12Bits);
1273
1274                 /* 2. Set RF mode = standby mode */
1275                 /* Path-A */
1276                 phy_set_rf_reg(adapt, RF_PATH_A, RF_AC, bMask12Bits,
1277                                (rf_a_mode&0x8FFFF)|0x10000);
1278
1279                 /* Path-B */
1280                 if (is2t)
1281                         phy_set_rf_reg(adapt, RF_PATH_B, RF_AC, bMask12Bits,
1282                                        (rf_b_mode&0x8FFFF)|0x10000);
1283         }
1284
1285         /* 3. Read RF reg18 */
1286         lc_cal = phy_query_rf_reg(adapt, RF_PATH_A, RF_CHNLBW, bMask12Bits);
1287
1288         /* 4. Set LC calibration begin bit15 */
1289         phy_set_rf_reg(adapt, RF_PATH_A, RF_CHNLBW, bMask12Bits,
1290                        lc_cal|0x08000);
1291
1292         msleep(100);
1293
1294         /* Restore original situation */
1295         if ((tmpreg&0x70) != 0) {
1296                 /* Deal with continuous TX case */
1297                 /* Path-A */
1298                 usb_write8(adapt, 0xd03, tmpreg);
1299                 phy_set_rf_reg(adapt, RF_PATH_A, RF_AC, bMask12Bits, rf_a_mode);
1300
1301                 /* Path-B */
1302                 if (is2t)
1303                         phy_set_rf_reg(adapt, RF_PATH_B, RF_AC, bMask12Bits,
1304                                        rf_b_mode);
1305         } else {
1306                 /* Deal with Packet TX case */
1307                 usb_write8(adapt, REG_TXPAUSE, 0x00);
1308         }
1309 }
1310
1311 void rtl88eu_phy_iq_calibrate(struct adapter *adapt, bool recovery)
1312 {
1313         struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
1314         struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
1315         s32 result[4][8];
1316         u8 i, final, chn_index;
1317         bool pathaok, pathbok;
1318         s32 reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc, reg_ec4;
1319         bool is12simular, is13simular, is23simular;
1320         bool singletone = false, carrier_sup = false;
1321         u32 iqk_bb_reg_92c[IQK_BB_REG_NUM] = {
1322                 rOFDM0_XARxIQImbalance, rOFDM0_XBRxIQImbalance,
1323                 rOFDM0_ECCAThreshold, rOFDM0_AGCRSSITable,
1324                 rOFDM0_XATxIQImbalance, rOFDM0_XBTxIQImbalance,
1325                 rOFDM0_XCTxAFE, rOFDM0_XDTxAFE,
1326                 rOFDM0_RxIQExtAnta};
1327         bool is2t;
1328
1329         is2t = (dm_odm->RFType == ODM_2T2R) ? true : false;
1330
1331         if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION))
1332                 return;
1333
1334         if (singletone || carrier_sup)
1335                 return;
1336
1337         if (recovery) {
1338                 ODM_RT_TRACE(dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD,
1339                              ("phy_iq_calibrate: Return due to recovery!\n"));
1340                 reload_adda_reg(adapt, iqk_bb_reg_92c,
1341                                 dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9);
1342                 return;
1343         }
1344
1345         for (i = 0; i < 8; i++) {
1346                 result[0][i] = 0;
1347                 result[1][i] = 0;
1348                 result[2][i] = 0;
1349                 if ((i == 0) || (i == 2) || (i == 4)  || (i == 6))
1350                         result[3][i] = 0x100;
1351                 else
1352                         result[3][i] = 0;
1353         }
1354         final = 0xff;
1355         pathaok = false;
1356         pathbok = false;
1357         is12simular = false;
1358         is23simular = false;
1359         is13simular = false;
1360
1361         for (i = 0; i < 3; i++) {
1362                 phy_iq_calibrate(adapt, result, i, is2t);
1363
1364                 if (i == 1) {
1365                         is12simular = simularity_compare(adapt, result, 0, 1);
1366                         if (is12simular) {
1367                                 final = 0;
1368                                 break;
1369                         }
1370                 }
1371
1372                 if (i == 2) {
1373                         is13simular = simularity_compare(adapt, result, 0, 2);
1374                         if (is13simular) {
1375                                 final = 0;
1376                                 break;
1377                         }
1378                         is23simular = simularity_compare(adapt, result, 1, 2);
1379                         if (is23simular)
1380                                 final = 1;
1381                         else
1382                                 final = 3;
1383                 }
1384         }
1385
1386         for (i = 0; i < 4; i++) {
1387                 reg_e94 = result[i][0];
1388                 reg_e9c = result[i][1];
1389                 reg_ea4 = result[i][2];
1390                 reg_eb4 = result[i][4];
1391                 reg_ebc = result[i][5];
1392                 reg_ec4 = result[i][6];
1393         }
1394
1395         if (final != 0xff) {
1396                 reg_e94 = result[final][0];
1397                 reg_e9c = result[final][1];
1398                 reg_ea4 = result[final][2];
1399                 reg_eb4 = result[final][4];
1400                 reg_ebc = result[final][5];
1401                 dm_odm->RFCalibrateInfo.RegE94 = reg_e94;
1402                 dm_odm->RFCalibrateInfo.RegE9C = reg_e9c;
1403                 dm_odm->RFCalibrateInfo.RegEB4 = reg_eb4;
1404                 dm_odm->RFCalibrateInfo.RegEBC = reg_ebc;
1405                 reg_ec4 = result[final][6];
1406                 pathaok = true;
1407                 pathbok = true;
1408         } else {
1409                 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1410                              ("IQK: FAIL use default value\n"));
1411                 dm_odm->RFCalibrateInfo.RegE94 = 0x100;
1412                 dm_odm->RFCalibrateInfo.RegEB4 = 0x100;
1413                 dm_odm->RFCalibrateInfo.RegE9C = 0x0;
1414                 dm_odm->RFCalibrateInfo.RegEBC = 0x0;
1415         }
1416         if (reg_e94 != 0)
1417                 patha_fill_iqk(adapt, pathaok, result, final,
1418                                (reg_ea4 == 0));
1419         if (is2t) {
1420                 if (reg_eb4 != 0)
1421                         pathb_fill_iqk(adapt, pathbok, result, final,
1422                                        (reg_ec4 == 0));
1423         }
1424
1425         chn_index = get_right_chnl_for_iqk(hal_data->CurrentChannel);
1426
1427         if (final < 4) {
1428                 for (i = 0; i < IQK_Matrix_REG_NUM; i++)
1429                         dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[chn_index].Value[0][i] = result[final][i];
1430                 dm_odm->RFCalibrateInfo.IQKMatrixRegSetting[chn_index].bIQKDone = true;
1431         }
1432
1433         save_adda_registers(adapt, iqk_bb_reg_92c,
1434                             dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9);
1435 }
1436
1437 void rtl88eu_phy_lc_calibrate(struct adapter *adapt)
1438 {
1439         bool singletone = false, carrier_sup = false;
1440         u32 timeout = 2000, timecount = 0;
1441         struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
1442         struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
1443
1444         if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION))
1445                 return;
1446         if (singletone || carrier_sup)
1447                 return;
1448
1449         while (*(dm_odm->pbScanInProcess) && timecount < timeout) {
1450                 mdelay(50);
1451                 timecount += 50;
1452         }
1453
1454         dm_odm->RFCalibrateInfo.bLCKInProgress = true;
1455
1456         if (dm_odm->RFType == ODM_2T2R) {
1457                 phy_lc_calibrate(adapt, true);
1458         } else {
1459                 /* For 88C 1T1R */
1460                 phy_lc_calibrate(adapt, false);
1461         }
1462
1463         dm_odm->RFCalibrateInfo.bLCKInProgress = false;
1464 }