diff mbox series

[3/6] ath9k: do not miss longcal on AR9002

Message ID 20200424004923.17129-4-ryazanov.s.a@gmail.com (mailing list archive)
State Accepted
Commit 41ba50fd6cac084a93e7651c528ef4bc37996ee2
Delegated to: Kalle Valo
Headers show
Series ath9k: AR9002 calibration fixes | expand

Commit Message

Sergey Ryazanov April 24, 2020, 12:49 a.m. UTC
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: Sergey Ryazanov <ryazanov.s.a@gmail.com>
---
 drivers/net/wireless/ath/ath9k/ar9002_calib.c | 10 +++++++++-
 drivers/net/wireless/ath/ath9k/hw.h           |  1 +
 2 files changed, 10 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
index 0f7c5812e5c2..ad8db7720993 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -663,8 +663,13 @@  static int ar9002_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
 	int ret;
 
 	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);
+		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 &&
 			  (currCal->calState == CAL_RUNNING ||
@@ -700,6 +705,9 @@  static int ar9002_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
 		}
 
 		if (longcal) {
+			if (ah->caldata)
+				clear_bit(LONGCAL_PENDING,
+					  &ah->caldata->cal_flags);
 			ath9k_hw_start_nfcal(ah, false);
 			/* Do periodic PAOffset Cal */
 			ar9002_hw_pa_cal(ah, false);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 2e4489700a85..c99f3c77c823 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -427,6 +427,7 @@  enum ath9k_cal_flags {
 	TXIQCAL_DONE,
 	TXCLCAL_DONE,
 	SW_PKDET_DONE,
+	LONGCAL_PENDING,
 };
 
 struct ath9k_hw_cal_data {