diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/ar9003_calib.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_calib.c | 92 |
1 files changed, 73 insertions, 19 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 6988e1d..22934d3 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -727,8 +727,12 @@ static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0, AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1); - if (caldata) - caldata->done_txiqcal_once = is_reusable; + if (caldata) { + if (is_reusable) + set_bit(TXIQCAL_DONE, &caldata->cal_flags); + else + clear_bit(TXIQCAL_DONE, &caldata->cal_flags); + } return; } @@ -961,18 +965,44 @@ static void ar9003_hw_manual_peak_cal(struct ath_hw *ah, u8 chain, bool is_2g) } static void ar9003_hw_do_manual_peak_cal(struct ath_hw *ah, - struct ath9k_channel *chan) + struct ath9k_channel *chan, + bool run_rtt_cal) { + struct ath9k_hw_cal_data *caldata = ah->caldata; int i; if (!AR_SREV_9462(ah) && !AR_SREV_9565(ah) && !AR_SREV_9485(ah)) return; + if ((ah->caps.hw_caps & ATH9K_HW_CAP_RTT) && !run_rtt_cal) + return; + for (i = 0; i < AR9300_MAX_CHAINS; i++) { if (!(ah->rxchainmask & (1 << i))) continue; ar9003_hw_manual_peak_cal(ah, i, IS_CHAN_2GHZ(chan)); } + + if (caldata) + set_bit(SW_PKDET_DONE, &caldata->cal_flags); + + if ((ah->caps.hw_caps & ATH9K_HW_CAP_RTT) && caldata) { + if (IS_CHAN_2GHZ(chan)){ + caldata->caldac[0] = REG_READ_FIELD(ah, + AR_PHY_65NM_RXRF_AGC(0), + AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR); + caldata->caldac[1] = REG_READ_FIELD(ah, + AR_PHY_65NM_RXRF_AGC(1), + AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR); + } else { + caldata->caldac[0] = REG_READ_FIELD(ah, + AR_PHY_65NM_RXRF_AGC(0), + AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR); + caldata->caldac[1] = REG_READ_FIELD(ah, + AR_PHY_65NM_RXRF_AGC(1), + AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR); + } + } } static void ar9003_hw_cl_cal_post_proc(struct ath_hw *ah, bool is_reusable) @@ -990,7 +1020,7 @@ static void ar9003_hw_cl_cal_post_proc(struct ath_hw *ah, bool is_reusable) txclcal_done = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_CLC_SUCCESS); - if (caldata->done_txclcal_once) { + if (test_bit(TXCLCAL_DONE, &caldata->cal_flags)) { for (i = 0; i < AR9300_MAX_CHAINS; i++) { if (!(ah->txchainmask & (1 << i))) continue; @@ -1006,7 +1036,7 @@ static void ar9003_hw_cl_cal_post_proc(struct ath_hw *ah, bool is_reusable) caldata->tx_clcal[i][j] = REG_READ(ah, CL_TAB_ENTRY(cl_idx[i])); } - caldata->done_txclcal_once = true; + set_bit(TXCLCAL_DONE, &caldata->cal_flags); } } @@ -1019,6 +1049,7 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, bool is_reusable = true, status = true; bool run_rtt_cal = false, run_agc_cal, sep_iq_cal = false; bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT); + u32 rx_delay = 0; u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL | AR_PHY_AGC_CONTROL_FLTR_CAL | AR_PHY_AGC_CONTROL_PKDET_CAL; @@ -1042,17 +1073,22 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, ar9003_hw_rtt_clear_hist(ah); } - if (rtt && !run_rtt_cal) { - agc_ctrl = REG_READ(ah, AR_PHY_AGC_CONTROL); - agc_supp_cals &= agc_ctrl; - agc_ctrl &= ~(AR_PHY_AGC_CONTROL_OFFSET_CAL | - AR_PHY_AGC_CONTROL_FLTR_CAL | - AR_PHY_AGC_CONTROL_PKDET_CAL); - REG_WRITE(ah, AR_PHY_AGC_CONTROL, agc_ctrl); + if (rtt) { + if (!run_rtt_cal) { + agc_ctrl = REG_READ(ah, AR_PHY_AGC_CONTROL); + agc_supp_cals &= agc_ctrl; + agc_ctrl &= ~(AR_PHY_AGC_CONTROL_OFFSET_CAL | + AR_PHY_AGC_CONTROL_FLTR_CAL | + AR_PHY_AGC_CONTROL_PKDET_CAL); + REG_WRITE(ah, AR_PHY_AGC_CONTROL, agc_ctrl); + } else { + if (ah->ah_flags & AH_FASTCC) + run_agc_cal = true; + } } if (ah->enabled_cals & TX_CL_CAL) { - if (caldata && caldata->done_txclcal_once) + if (caldata && test_bit(TXCLCAL_DONE, &caldata->cal_flags)) REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE); else { @@ -1076,14 +1112,14 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, * AGC calibration */ if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) { - if (caldata && !caldata->done_txiqcal_once) + if (caldata && !test_bit(TXIQCAL_DONE, &caldata->cal_flags)) REG_SET_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0, AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL); else REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0, AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL); txiqcal_done = run_agc_cal = true; - } else if (caldata && !caldata->done_txiqcal_once) { + } else if (caldata && !test_bit(TXIQCAL_DONE, &caldata->cal_flags)) { run_agc_cal = true; sep_iq_cal = true; } @@ -1099,6 +1135,15 @@ skip_tx_iqcal: REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); } + if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) { + rx_delay = REG_READ(ah, AR_PHY_RX_DELAY); + /* Disable BB_active */ + REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); + udelay(5); + REG_WRITE(ah, AR_PHY_RX_DELAY, AR_PHY_RX_DELAY_DELAY); + REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); + } + if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) { /* Calibrate the AGC */ REG_WRITE(ah, AR_PHY_AGC_CONTROL, @@ -1110,7 +1155,12 @@ skip_tx_iqcal: AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT); - ar9003_hw_do_manual_peak_cal(ah, chan); + ar9003_hw_do_manual_peak_cal(ah, chan, run_rtt_cal); + } + + if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) { + REG_WRITE(ah, AR_PHY_RX_DELAY, rx_delay); + udelay(5); } if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal) @@ -1133,19 +1183,23 @@ skip_tx_iqcal: if (txiqcal_done) ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable); - else if (caldata && caldata->done_txiqcal_once) + else if (caldata && test_bit(TXIQCAL_DONE, &caldata->cal_flags)) ar9003_hw_tx_iq_cal_reload(ah); ar9003_hw_cl_cal_post_proc(ah, is_reusable); if (run_rtt_cal && caldata) { if (is_reusable) { - if (!ath9k_hw_rfbus_req(ah)) + if (!ath9k_hw_rfbus_req(ah)) { ath_err(ath9k_hw_common(ah), "Could not stop baseband\n"); - else + } else { ar9003_hw_rtt_fill_hist(ah); + if (test_bit(SW_PKDET_DONE, &caldata->cal_flags)) + ar9003_hw_rtt_load_hist(ah); + } + ath9k_hw_rfbus_done(ah); } |