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