1 /******************************************************************************
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
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.
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
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
19 ******************************************************************************/
20 #define _RTL8188E_PHYCFG_C_
22 #include <osdep_service.h>
23 #include <drv_types.h>
25 #include <rtl8188e_hal.h>
29 #define MAX_PRECMD_CNT 16
30 #define MAX_RFDEPENDCMD_CNT 16
31 #define MAX_POSTCMD_CNT 16
33 #define MAX_DOZE_WAITING_TIMES_9x 64
35 static u32 cal_bit_shift(u32 bitmask)
39 for (i = 0; i <= 31; i++) {
40 if (((bitmask >> i) & 0x1) == 1)
46 u32 phy_query_bb_reg(struct adapter *adapt, u32 regaddr, u32 bitmask)
48 u32 return_value = 0, original_value, bit_shift;
50 original_value = usb_read32(adapt, regaddr);
51 bit_shift = cal_bit_shift(bitmask);
52 return_value = (original_value & bitmask) >> bit_shift;
56 void phy_set_bb_reg(struct adapter *adapt, u32 regaddr, u32 bitmask, u32 data)
58 u32 original_value, bit_shift;
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);
66 usb_write32(adapt, regaddr, data);
69 static u32 rf_serial_read(struct adapter *adapt,
70 enum rf_radio_path rfpath, u32 offset)
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;
80 tmplong = phy_query_bb_reg(adapt, rFPGA0_XA_HSSIParameter2, bMaskDWord);
81 if (rfpath == RF_PATH_A)
84 tmplong2 = phy_query_bb_reg(adapt, phyreg->rfHSSIPara2,
87 tmplong2 = (tmplong2 & (~bLSSIReadAddress)) |
88 (offset<<23) | bLSSIReadEdge;
90 phy_set_bb_reg(adapt, rFPGA0_XA_HSSIParameter2, bMaskDWord,
91 tmplong&(~bLSSIReadEdge));
94 phy_set_bb_reg(adapt, phyreg->rfHSSIPara2, bMaskDWord, tmplong2);
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);
105 ret = phy_query_bb_reg(adapt, phyreg->rfLSSIReadBackPi,
108 ret = phy_query_bb_reg(adapt, phyreg->rfLSSIReadBack,
113 static void rf_serial_write(struct adapter *adapt,
114 enum rf_radio_path rfpath, u32 offset,
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];
122 data_and_addr = ((offset<<20) | (data&0x000fffff)) & 0x0fffffff;
123 phy_set_bb_reg(adapt, phyreg->rf3wireOffset, bMaskDWord, data_and_addr);
126 u32 phy_query_rf_reg(struct adapter *adapt, enum rf_radio_path rf_path,
127 u32 reg_addr, u32 bit_mask)
129 u32 original_value, readback_value, bit_shift;
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;
137 void phy_set_rf_reg(struct adapter *adapt, enum rf_radio_path rf_path,
138 u32 reg_addr, u32 bit_mask, u32 data)
140 u32 original_value, bit_shift;
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);
149 rf_serial_write(adapt, rf_path, reg_addr, data);
152 static void get_tx_power_index(struct adapter *adapt, u8 channel, u8 *cck_pwr,
153 u8 *ofdm_pwr, u8 *bw20_pwr, u8 *bw40_pwr)
155 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
156 u8 index = (channel - 1);
157 u8 TxCount = 0, path_nums;
159 if ((RF_1T2R == hal_data->rf_type) || (RF_1T1R == hal_data->rf_type))
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];
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];
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];
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];
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];
213 static void phy_power_index_check(struct adapter *adapt, u8 channel,
214 u8 *cck_pwr, u8 *ofdm_pwr, u8 *bw20_pwr,
217 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
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];
225 void phy_set_tx_power_level(struct adapter *adapt, u8 channel)
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};
232 get_tx_power_index(adapt, channel, &cck_pwr[0], &ofdm_pwr[0],
233 &bw20_pwr[0], &bw40_pwr[0]);
235 phy_power_index_check(adapt, channel, &cck_pwr[0], &ofdm_pwr[0],
236 &bw20_pwr[0], &bw40_pwr[0]);
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);
243 static void phy_set_bw_mode_callback(struct adapter *adapt)
245 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
249 if (hal_data->rf_chip == RF_PSEUDO_11N)
252 /* There is no 40MHz mode in RF_8225. */
253 if (hal_data->rf_chip == RF_8225)
256 if (adapt->bDriverStopped)
259 /* Set MAC register */
261 reg_bw_opmode = usb_read8(adapt, REG_BWOPMODE);
262 reg_prsr_rsc = usb_read8(adapt, REG_RRSR+2);
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);
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);
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);
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
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);
303 /* Set RF related register */
304 if (hal_data->rf_chip == RF_6052)
305 rtl88eu_phy_rf6052_set_bandwidth(adapt, hal_data->CurrentChannelBW);
308 void phy_set_bw_mode(struct adapter *adapt, enum ht_channel_width bandwidth,
309 unsigned char offset)
311 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
312 enum ht_channel_width tmp_bw = hal_data->CurrentChannelBW;
314 hal_data->CurrentChannelBW = bandwidth;
315 hal_data->nCur40MhzPrimeSC = offset;
317 if ((!adapt->bDriverStopped) && (!adapt->bSurpriseRemoved))
318 phy_set_bw_mode_callback(adapt);
320 hal_data->CurrentChannelBW = tmp_bw;
323 static void phy_sw_chnl_callback(struct adapter *adapt, u8 channel)
327 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
329 if (adapt->bNotifyChannelChange)
330 DBG_88E("[%s] ch = %d\n", __func__, channel);
332 phy_set_tx_power_level(adapt, 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]);
344 void phy_sw_chnl(struct adapter *adapt, u8 channel)
346 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
347 u8 tmpchannel = hal_data->CurrentChannel;
349 if (hal_data->rf_chip == RF_PSEUDO_11N)
355 hal_data->CurrentChannel = channel;
357 if ((!adapt->bDriverStopped) && (!adapt->bSurpriseRemoved))
358 phy_sw_chnl_callback(adapt, channel);
360 hal_data->CurrentChannel = tmpchannel;
363 #define ODM_TXPWRTRACK_MAX_IDX_88E 6
365 static u8 get_right_chnl_for_iqk(u8 chnl)
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
376 for (place = 0; place < sizeof(channel_all); place++) {
377 if (channel_all[place] == chnl)
384 void rtl88eu_dm_txpower_track_adjust(struct odm_dm_struct *dm_odm, u8 type,
385 u8 *direction, u32 *out_write_val)
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));
394 if (dm_odm->BbSwingIdxOfdm <= dm_odm->BbSwingIdxOfdmBase) {
396 pwr_value = dm_odm->BbSwingIdxOfdmBase -
397 dm_odm->BbSwingIdxOfdm;
400 pwr_value = dm_odm->BbSwingIdxOfdm -
401 dm_odm->BbSwingIdxOfdmBase;
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));
409 if (dm_odm->BbSwingIdxCck <= dm_odm->BbSwingIdxCckBase) {
411 pwr_value = dm_odm->BbSwingIdxCckBase -
412 dm_odm->BbSwingIdxCck;
415 pwr_value = dm_odm->BbSwingIdxCck -
416 dm_odm->BbSwingIdxCckBase;
421 if (pwr_value >= ODM_TXPWRTRACK_MAX_IDX_88E && *direction == 1)
422 pwr_value = ODM_TXPWRTRACK_MAX_IDX_88E;
424 *out_write_val = pwr_value | (pwr_value<<8) | (pwr_value<<16) |
428 static void dm_txpwr_track_setpwr(struct odm_dm_struct *dm_odm)
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;
439 void rtl88eu_dm_txpower_tracking_callback_thermalmeter(struct adapter *adapt)
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;
446 s8 ofdm_index[2], cck_index = 0;
447 s8 ofdm_index_old[2] = {0, 0}, cck_index_old = 0;
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},
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},
464 struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
466 dm_txpwr_track_setpwr(dm_odm);
468 dm_odm->RFCalibrateInfo.TXPowerTrackingCallbackCnt++;
469 dm_odm->RFCalibrateInfo.bTXPowerTrackingInit = true;
471 dm_odm->RFCalibrateInfo.RegA24 = 0x090e1317;
473 thermal_val = (u8)phy_query_rf_reg(adapt, RF_PATH_A,
474 RF_T_METER_88E, 0xfc00);
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;
492 /* Query OFDM path B default setting */
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;
503 /* Query CCK default setting From 0xa24 */
504 temp_cck = dm_odm->RFCalibrateInfo.RegA24;
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;
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;
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;
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;
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];
539 if (thermal_avg_count)
540 thermal_val = (u8)(thermal_avg / thermal_avg_count);
542 if (dm_odm->RFCalibrateInfo.bDoneTxpower &&
543 !dm_odm->RFCalibrateInfo.bReloadtxpowerindex)
544 delta = abs(thermal_val - dm_odm->RFCalibrateInfo.ThermalValue);
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;
553 delta_lck = abs(dm_odm->RFCalibrateInfo.ThermalValue_LCK - thermal_val);
554 delta_iqk = abs(dm_odm->RFCalibrateInfo.ThermalValue_IQK - thermal_val);
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);
562 if (delta > 0 && dm_odm->RFCalibrateInfo.TxPowerTrackControl) {
563 delta = abs(hal_data->EEPROMThermalMeter - thermal_val);
565 /* calculate new OFDM / CCK offset */
566 if (thermal_val > hal_data->EEPROMThermalMeter)
570 for (offset = 0; offset < index_mapping_NUM_88E; offset++) {
571 if (delta < thermal_mapping[j][offset]) {
577 if (offset >= index_mapping_NUM_88E)
578 offset = index_mapping_NUM_88E-1;
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;
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)
595 /* 2 temporarily remove bNOPG */
596 /* Config by SwingTable */
597 if (dm_odm->RFCalibrateInfo.TxPowerTrackControl) {
598 dm_odm->RFCalibrateInfo.bDoneTxpower = true;
600 /* Revse TX power table. */
601 dm_odm->BbSwingIdxOfdm = (u8)ofdm_index[0];
602 dm_odm->BbSwingIdxCck = (u8)cck_index;
604 if (dm_odm->BbSwingIdxOfdmCurrent != dm_odm->BbSwingIdxOfdm) {
605 dm_odm->BbSwingIdxOfdmCurrent = dm_odm->BbSwingIdxOfdm;
606 dm_odm->BbSwingFlagOfdm = true;
609 if (dm_odm->BbSwingIdxCckCurrent != dm_odm->BbSwingIdxCck) {
610 dm_odm->BbSwingIdxCckCurrent = dm_odm->BbSwingIdxCck;
611 dm_odm->BbSwingFlagCck = true;
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);
621 /* update thermal meter value */
622 if (dm_odm->RFCalibrateInfo.TxPowerTrackControl)
623 dm_odm->RFCalibrateInfo.ThermalValue = thermal_val;
625 dm_odm->RFCalibrateInfo.TXPowercount = 0;
628 #define MAX_TOLERANCE 5
630 static u8 phy_path_a_iqk(struct adapter *adapt, bool config_pathb)
632 u32 reg_eac, reg_e94, reg_e9c, reg_ea4;
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);
642 /* LO calibration setting */
643 phy_set_bb_reg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x00462911);
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);
649 mdelay(IQK_DELAY_TIME_88E);
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);
656 if (!(reg_eac & BIT28) &&
657 (((reg_e94 & 0x03FF0000)>>16) != 0x142) &&
658 (((reg_e9c & 0x03FF0000)>>16) != 0x42))
663 static u8 phy_path_a_rx_iqk(struct adapter *adapt, bool configPathB)
665 u32 reg_eac, reg_e94, reg_e9c, reg_ea4, u4tmp;
667 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
668 struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
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);
679 phy_set_rf_reg(adapt, RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x980);
680 phy_set_rf_reg(adapt, RF_PATH_A, 0x56, bRFRegOffsetMask, 0x51000);
682 phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000);
685 phy_set_bb_reg(adapt, rTx_IQK, bMaskDWord, 0x01007c00);
686 phy_set_bb_reg(adapt, rRx_IQK, bMaskDWord, 0x81004800);
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);
694 /* LO calibration setting */
695 phy_set_bb_reg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911);
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);
702 mdelay(IQK_DELAY_TIME_88E);
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);
709 if (!(reg_eac & BIT28) &&
710 (((reg_e94 & 0x03FF0000)>>16) != 0x142) &&
711 (((reg_e9c & 0x03FF0000)>>16) != 0x42))
713 else /* if Tx not OK, ignore Rx */
716 u4tmp = 0x80007C00 | (reg_e94&0x3FF0000) | ((reg_e9c&0x3FF0000) >> 16);
717 phy_set_bb_reg(adapt, rTx_IQK, bMaskDWord, u4tmp);
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);
731 phy_set_bb_reg(adapt, rRx_IQK, bMaskDWord, 0x01004800);
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);
739 /* LO calibration setting */
740 phy_set_bb_reg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911);
742 phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf9000000);
743 phy_set_bb_reg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf8000000);
745 mdelay(IQK_DELAY_TIME_88E);
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);
754 phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000);
755 phy_set_rf_reg(adapt, RF_PATH_A, 0xdf, bRFRegOffsetMask, 0x180);
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))
762 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
763 ("Path A Rx IQK fail!!\n"));
768 static u8 phy_path_b_iqk(struct adapter *adapt)
770 u32 regeac, regeb4, regebc, regec4, regecc;
772 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
773 struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
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);
779 mdelay(IQK_DELAY_TIME_88E);
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);
787 if (!(regeac & BIT31) &&
788 (((regeb4 & 0x03FF0000)>>16) != 0x142) &&
789 (((regebc & 0x03FF0000)>>16) != 0x42))
794 if (!(regeac & BIT30) &&
795 (((regec4 & 0x03FF0000)>>16) != 0x132) &&
796 (((regecc & 0x03FF0000)>>16) != 0x36))
799 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION,
800 ODM_DBG_LOUD, ("Path B Rx IQK fail!!\n"));
804 static void patha_fill_iqk(struct adapter *adapt, bool iqkok, s32 result[][8],
805 u8 final_candidate, bool txonly)
807 u32 oldval_0, x, tx0_a, reg;
810 if (final_candidate == 0xFF) {
813 oldval_0 = (phy_query_bb_reg(adapt, rOFDM0_XATxIQImbalance, bMaskDWord) >> 22) & 0x3FF;
815 x = result[final_candidate][0];
816 if ((x & 0x00000200) != 0)
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));
824 y = result[final_candidate][1];
825 if ((y & 0x00000200) != 0)
828 tx0_c = (y * oldval_0) >> 8;
829 phy_set_bb_reg(adapt, rOFDM0_XCTxAFE, 0xF0000000,
831 phy_set_bb_reg(adapt, rOFDM0_XATxIQImbalance, 0x003F0000,
833 phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(29),
834 ((y * oldval_0>>7) & 0x1));
839 reg = result[final_candidate][2];
840 phy_set_bb_reg(adapt, rOFDM0_XARxIQImbalance, 0x3FF, reg);
842 reg = result[final_candidate][3] & 0x3F;
843 phy_set_bb_reg(adapt, rOFDM0_XARxIQImbalance, 0xFC00, reg);
845 reg = (result[final_candidate][3] >> 6) & 0xF;
846 phy_set_bb_reg(adapt, rOFDM0_RxIQExtAnta, 0xF0000000, reg);
850 static void pathb_fill_iqk(struct adapter *adapt, bool iqkok, s32 result[][8],
851 u8 final_candidate, bool txonly)
853 u32 oldval_1, x, tx1_a, reg;
856 if (final_candidate == 0xFF) {
859 oldval_1 = (phy_query_bb_reg(adapt, rOFDM0_XBTxIQImbalance, bMaskDWord) >> 22) & 0x3FF;
861 x = result[final_candidate][4];
862 if ((x & 0x00000200) != 0)
864 tx1_a = (x * oldval_1) >> 8;
865 phy_set_bb_reg(adapt, rOFDM0_XBTxIQImbalance, 0x3FF, tx1_a);
867 phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(27),
868 ((x * oldval_1>>7) & 0x1));
870 y = result[final_candidate][5];
871 if ((y & 0x00000200) != 0)
874 tx1_c = (y * oldval_1) >> 8;
876 phy_set_bb_reg(adapt, rOFDM0_XDTxAFE, 0xF0000000,
878 phy_set_bb_reg(adapt, rOFDM0_XBTxIQImbalance, 0x003F0000,
880 phy_set_bb_reg(adapt, rOFDM0_ECCAThreshold, BIT(25),
881 ((y * oldval_1>>7) & 0x1));
886 reg = result[final_candidate][6];
887 phy_set_bb_reg(adapt, rOFDM0_XBRxIQImbalance, 0x3FF, reg);
889 reg = result[final_candidate][7] & 0x3F;
890 phy_set_bb_reg(adapt, rOFDM0_XBRxIQImbalance, 0xFC00, reg);
892 reg = (result[final_candidate][7] >> 6) & 0xF;
893 phy_set_bb_reg(adapt, rOFDM0_AGCRSSITable, 0x0000F000, reg);
897 static void save_adda_registers(struct adapter *adapt, u32 *addareg,
898 u32 *backup, u32 register_num)
902 for (i = 0; i < register_num; i++) {
903 backup[i] = phy_query_bb_reg(adapt, addareg[i], bMaskDWord);
907 static void save_mac_registers(struct adapter *adapt, u32 *mac_reg,
912 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) {
913 backup[i] = usb_read8(adapt, mac_reg[i]);
915 backup[i] = usb_read32(adapt, mac_reg[i]);
918 static void reload_adda_reg(struct adapter *adapt, u32 *adda_reg,
919 u32 *backup, u32 regiester_num)
923 for (i = 0; i < regiester_num; i++)
924 phy_set_bb_reg(adapt, adda_reg[i], bMaskDWord, backup[i]);
927 static void reload_mac_registers(struct adapter *adapt,
928 u32 *mac_reg, u32 *backup)
932 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) {
933 usb_write8(adapt, mac_reg[i], (u8)backup[i]);
935 usb_write32(adapt, mac_reg[i], backup[i]);
938 static void path_adda_on(struct adapter *adapt, u32 *adda_reg,
939 bool is_path_a_on, bool is2t)
945 path_on = 0x0bdb25a0;
946 phy_set_bb_reg(adapt, adda_reg[0], bMaskDWord, 0x0b1b25a0);
948 path_on = is_path_a_on ? 0x04db25a4 : 0x0b1b25a4;
949 phy_set_bb_reg(adapt, adda_reg[0], bMaskDWord, path_on);
952 for (i = 1; i < IQK_ADDA_REG_NUM; i++)
953 phy_set_bb_reg(adapt, adda_reg[i], bMaskDWord, path_on);
956 static void mac_setting_calibration(struct adapter *adapt, u32 *mac_reg, u32 *backup)
960 usb_write8(adapt, mac_reg[i], 0x3F);
962 for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) {
963 usb_write8(adapt, mac_reg[i], (u8)(backup[i]&(~BIT3)));
965 usb_write8(adapt, mac_reg[i], (u8)(backup[i]&(~BIT5)));
968 static void path_a_standby(struct adapter *adapt)
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);
976 static void pi_mode_switch(struct adapter *adapt, bool pi_mode)
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);
985 static bool simularity_compare(struct adapter *adapt, s32 resulta[][8],
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 */
993 s32 tmp1 = 0, tmp2 = 0;
995 if ((dm_odm->RFType == ODM_2T2R) || (dm_odm->RFType == ODM_2T3R) ||
996 (dm_odm->RFType == ODM_2T4R))
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;
1006 tmp1 = resulta[c1][i];
1008 if ((resulta[c2][i] & 0x00000200) != 0)
1009 tmp2 = resulta[c2][i] | 0xFFFFFC00;
1011 tmp2 = resulta[c2][i];
1013 tmp1 = resulta[c1][i];
1014 tmp2 = resulta[c2][i];
1017 diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1);
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;
1026 sim_bitmap = sim_bitmap | (1<<i);
1028 sim_bitmap = sim_bitmap | (1<<i);
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];
1043 if (!(sim_bitmap & 0x03)) { /* path A TX OK */
1044 for (i = 0; i < 2; i++)
1045 resulta[3][i] = resulta[c1][i];
1047 if (!(sim_bitmap & 0x0c)) { /* path A RX OK */
1048 for (i = 2; i < 4; i++)
1049 resulta[3][i] = resulta[c1][i];
1052 if (!(sim_bitmap & 0x30)) { /* path B TX OK */
1053 for (i = 4; i < 6; i++)
1054 resulta[3][i] = resulta[c1][i];
1057 if (!(sim_bitmap & 0xc0)) { /* path B RX OK */
1058 for (i = 6; i < 8; i++)
1059 resulta[3][i] = resulta[c1][i];
1065 static void phy_iq_calibrate(struct adapter *adapt, s32 result[][8],
1068 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
1069 struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
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,
1078 rRx_OFDM, rRx_Wait_RIFS,
1079 rRx_TO_Rx, rStandby,
1080 rSleep, rPMPD_ANAEN};
1082 u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
1083 REG_TXPAUSE, REG_BCN_CTRL,
1084 REG_BCN_CTRL_1, REG_GPIO_MUXCFG};
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};
1093 u32 retry_count = 9;
1094 if (*(dm_odm->mp_mode) == 1)
1101 /* Save ADDA parameters, turn Path A ADDA on */
1102 save_adda_registers(adapt, adda_reg, dm_odm->RFCalibrateInfo.ADDA_backup,
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);
1110 path_adda_on(adapt, adda_reg, true, is2t);
1112 dm_odm->RFCalibrateInfo.bRfPiEnable = (u8)phy_query_bb_reg(adapt, rFPGA0_XA_HSSIParameter1,
1115 if (!dm_odm->RFCalibrateInfo.bRfPiEnable) {
1116 /* Switch BB to PI mode to do IQ Calibration. */
1117 pi_mode_switch(adapt, true);
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);
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);
1132 phy_set_bb_reg(adapt, rFPGA0_XA_LSSIParameter, bMaskDWord,
1134 phy_set_bb_reg(adapt, rFPGA0_XB_LSSIParameter, bMaskDWord,
1139 mac_setting_calibration(adapt, iqk_mac_reg,
1140 dm_odm->RFCalibrateInfo.IQK_MAC_backup);
1144 phy_set_bb_reg(adapt, rConfig_AntA, bMaskDWord, 0x0f600000);
1147 phy_set_bb_reg(adapt, rConfig_AntB, bMaskDWord, 0x0f600000);
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);
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;
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;
1174 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1175 ("Path A Rx IQK Fail!!\n"));
1179 if (0x00 == path_a_ok) {
1180 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1181 ("Path A IQK failed!!\n"));
1185 path_a_standby(adapt);
1187 /* Turn Path B ADDA on */
1188 path_adda_on(adapt, adda_reg, false, is2t);
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;
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;
1210 if (0x00 == path_b_ok) {
1211 ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
1212 ("Path B IQK failed!!\n"));
1216 /* Back to BB mode, load original value */
1217 phy_set_bb_reg(adapt, rFPGA0_IQK, bMaskDWord, 0);
1220 if (!dm_odm->RFCalibrateInfo.bRfPiEnable) {
1221 /* Switch back BB to SI mode after
1222 * finish IQ Calibration.
1224 pi_mode_switch(adapt, false);
1227 /* Reload ADDA power saving parameters */
1228 reload_adda_reg(adapt, adda_reg, dm_odm->RFCalibrateInfo.ADDA_backup,
1231 /* Reload MAC parameters */
1232 reload_mac_registers(adapt, iqk_mac_reg,
1233 dm_odm->RFCalibrateInfo.IQK_MAC_backup);
1235 reload_adda_reg(adapt, iqk_bb_reg_92c, dm_odm->RFCalibrateInfo.IQK_BB_backup,
1238 /* Restore RX initial gain */
1239 phy_set_bb_reg(adapt, rFPGA0_XA_LSSIParameter,
1240 bMaskDWord, 0x00032ed3);
1242 phy_set_bb_reg(adapt, rFPGA0_XB_LSSIParameter,
1243 bMaskDWord, 0x00032ed3);
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);
1251 static void phy_lc_calibrate(struct adapter *adapt, bool is2t)
1254 u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
1256 /* Check continuous TX and Packet TX */
1257 tmpreg = usb_read8(adapt, 0xd03);
1259 if ((tmpreg&0x70) != 0)
1260 usb_write8(adapt, 0xd03, tmpreg&0x8F);
1262 usb_write8(adapt, REG_TXPAUSE, 0xFF);
1264 if ((tmpreg&0x70) != 0) {
1265 /* 1. Read original RF mode */
1267 rf_a_mode = phy_query_rf_reg(adapt, RF_PATH_A, RF_AC,
1272 rf_b_mode = phy_query_rf_reg(adapt, RF_PATH_B, RF_AC,
1275 /* 2. Set RF mode = standby mode */
1277 phy_set_rf_reg(adapt, RF_PATH_A, RF_AC, bMask12Bits,
1278 (rf_a_mode&0x8FFFF)|0x10000);
1282 phy_set_rf_reg(adapt, RF_PATH_B, RF_AC, bMask12Bits,
1283 (rf_b_mode&0x8FFFF)|0x10000);
1286 /* 3. Read RF reg18 */
1287 lc_cal = phy_query_rf_reg(adapt, RF_PATH_A, RF_CHNLBW, bMask12Bits);
1289 /* 4. Set LC calibration begin bit15 */
1290 phy_set_rf_reg(adapt, RF_PATH_A, RF_CHNLBW, bMask12Bits,
1295 /* Restore original situation */
1296 if ((tmpreg&0x70) != 0) {
1297 /* Deal with continuous TX case */
1299 usb_write8(adapt, 0xd03, tmpreg);
1300 phy_set_rf_reg(adapt, RF_PATH_A, RF_AC, bMask12Bits, rf_a_mode);
1304 phy_set_rf_reg(adapt, RF_PATH_B, RF_AC, bMask12Bits,
1307 /* Deal with Packet TX case */
1308 usb_write8(adapt, REG_TXPAUSE, 0x00);
1312 void rtl88eu_phy_iq_calibrate(struct adapter *adapt, bool recovery)
1314 struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
1315 struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
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,
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};
1331 is2t = (dm_odm->RFType == ODM_2T2R) ? true : false;
1333 if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION))
1336 if (singletone || carrier_sup)
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);
1347 for (i = 0; i < 8; i++) {
1351 if ((i == 0) || (i == 2) || (i == 4) || (i == 6))
1352 result[3][i] = 0x100;
1359 is12simular = false;
1360 is23simular = false;
1361 is13simular = false;
1363 for (i = 0; i < 3; i++) {
1364 phy_iq_calibrate(adapt, result, i, is2t);
1367 is12simular = simularity_compare(adapt, result, 0, 1);
1375 is13simular = simularity_compare(adapt, result, 0, 2);
1380 is23simular = simularity_compare(adapt, result, 1, 2);
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];
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];
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;
1423 patha_fill_iqk(adapt, pathaok, result, final,
1427 pathb_fill_iqk(adapt, pathbok, result, final,
1431 chn_index = get_right_chnl_for_iqk(hal_data->CurrentChannel);
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;
1439 save_adda_registers(adapt, iqk_bb_reg_92c,
1440 dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9);
1443 void rtl88eu_phy_lc_calibrate(struct adapter *adapt)
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;
1450 if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION))
1452 if (singletone || carrier_sup)
1455 while (*(dm_odm->pbScanInProcess) && timecount < timeout) {
1460 dm_odm->RFCalibrateInfo.bLCKInProgress = true;
1462 if (dm_odm->RFType == ODM_2T2R) {
1463 phy_lc_calibrate(adapt, true);
1466 phy_lc_calibrate(adapt, false);
1469 dm_odm->RFCalibrateInfo.bLCKInProgress = false;