]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ath9k: do not miss longcal on AR9002
authorSergey Ryazanov <ryazanov.s.a@gmail.com>
Fri, 24 Apr 2020 00:49:20 +0000 (03:49 +0300)
committerKalle Valo <kvalo@codeaurora.org>
Tue, 28 Apr 2020 09:07:14 +0000 (12:07 +0300)
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>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20200424004923.17129-4-ryazanov.s.a@gmail.com
drivers/net/wireless/ath/ath9k/ar9002_calib.c
drivers/net/wireless/ath/ath9k/hw.h

index 0f7c5812e5c2c60625e0c18fdb0a5bd1f29d4120..ad8db7720993e5fde4d35872dff05428963e146b 100644 (file)
@@ -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);
index 2e4489700a859722b2c54d817a91d8aea4040bcb..c99f3c77c823246597c94cf77242ec3c18514bd7 100644 (file)
@@ -427,6 +427,7 @@ enum ath9k_cal_flags {
        TXIQCAL_DONE,
        TXCLCAL_DONE,
        SW_PKDET_DONE,
+       LONGCAL_PENDING,
 };
 
 struct ath9k_hw_cal_data {