Commit 41ba50fd authored by Sergey Ryazanov's avatar Sergey Ryazanov Committed by Kalle Valo

ath9k: do not miss longcal on AR9002

Each of AGC & I/Q calibrations can take a long time. Long calibration
and NF calibration in particular are forbiden for parallel run with
ADC & I/Q calibrations. So, the chip could not be ready to perform the
long calibration at the time of request. And a request to perform the
long calibration may be lost.

In order to fix this, preserve the long calibration request as a
calibration state flag and restore the long calibration request each
time the calibration function is called again (i.e. on each subsequent
ivocation of the short calibration).

This feature will be twice useful after the next change, which will
make it possible to start the long calibration before all ADCs & I/Q
calibrations are completed.

Run tested with AR9220.
Signed-off-by: default avatarSergey Ryazanov <ryazanov.s.a@gmail.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20200424004923.17129-4-ryazanov.s.a@gmail.com
parent 93f8d422
...@@ -663,8 +663,13 @@ static int ar9002_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, ...@@ -663,8 +663,13 @@ static int ar9002_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
int ret; int ret;
nfcal = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF); nfcal = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF);
if (ah->caldata) if (ah->caldata) {
nfcal_pending = test_bit(NFCAL_PENDING, &ah->caldata->cal_flags); nfcal_pending = test_bit(NFCAL_PENDING, &ah->caldata->cal_flags);
if (longcal) /* Remember to not miss */
set_bit(LONGCAL_PENDING, &ah->caldata->cal_flags);
else if (test_bit(LONGCAL_PENDING, &ah->caldata->cal_flags))
longcal = true; /* Respin a previous one */
}
percal_pending = (currCal && percal_pending = (currCal &&
(currCal->calState == CAL_RUNNING || (currCal->calState == CAL_RUNNING ||
...@@ -700,6 +705,9 @@ static int ar9002_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, ...@@ -700,6 +705,9 @@ static int ar9002_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
} }
if (longcal) { if (longcal) {
if (ah->caldata)
clear_bit(LONGCAL_PENDING,
&ah->caldata->cal_flags);
ath9k_hw_start_nfcal(ah, false); ath9k_hw_start_nfcal(ah, false);
/* Do periodic PAOffset Cal */ /* Do periodic PAOffset Cal */
ar9002_hw_pa_cal(ah, false); ar9002_hw_pa_cal(ah, false);
......
...@@ -427,6 +427,7 @@ enum ath9k_cal_flags { ...@@ -427,6 +427,7 @@ enum ath9k_cal_flags {
TXIQCAL_DONE, TXIQCAL_DONE,
TXCLCAL_DONE, TXCLCAL_DONE,
SW_PKDET_DONE, SW_PKDET_DONE,
LONGCAL_PENDING,
}; };
struct ath9k_hw_cal_data { struct ath9k_hw_cal_data {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment