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