ath9k_hw: Fix throughput drops in HT40 mode for AR9287 chips
authorRajkumar Manoharan <rmanoharan@atheros.com>
Tue, 15 Mar 2011 14:25:36 +0000 (19:55 +0530)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 30 Mar 2011 18:15:11 +0000 (14:15 -0400)
Doing adc gain calibration for AR9287 chips is causing
throughput drops in HT40 mode. Remove ADC Gain from supported
calibration list.

Signed-off-by: Rajkumar Manoharan <rmanoharan@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/ath/ath9k/ar9002_calib.c

index 76388c6d66923a0f6e455e1d7c597ebe5087ae5f..cb611b287b35a4459bdce1fa4c179b72b64aef94 100644 (file)
@@ -26,6 +26,27 @@ enum ar9002_cal_types {
        IQ_MISMATCH_CAL = BIT(2),
 };
 
+static bool ar9002_hw_is_cal_supported(struct ath_hw *ah,
+                               struct ath9k_channel *chan,
+                               enum ar9002_cal_types cal_type)
+{
+       bool supported = false;
+       switch (ah->supp_cals & cal_type) {
+       case IQ_MISMATCH_CAL:
+               /* Run IQ Mismatch for non-CCK only */
+               if (!IS_CHAN_B(chan))
+                       supported = true;
+               break;
+       case ADC_GAIN_CAL:
+       case ADC_DC_CAL:
+               /* Run ADC Gain Cal for non-CCK & non 2GHz-HT20 only */
+               if (!IS_CHAN_B(chan) &&
+                   !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan)))
+                       supported = true;
+               break;
+       }
+       return supported;
+}
 
 static void ar9002_hw_setup_calibration(struct ath_hw *ah,
                                        struct ath9k_cal_list *currCal)
@@ -858,26 +879,32 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
        if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
                ah->supp_cals = IQ_MISMATCH_CAL;
 
-               if (AR_SREV_9160_10_OR_LATER(ah) &&
-                   !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan))) {
+               if (AR_SREV_9160_10_OR_LATER(ah))
                        ah->supp_cals |= ADC_GAIN_CAL | ADC_DC_CAL;
 
+               if (AR_SREV_9287(ah))
+                       ah->supp_cals &= ~ADC_GAIN_CAL;
 
+               if (ar9002_hw_is_cal_supported(ah, chan, ADC_GAIN_CAL)) {
                        INIT_CAL(&ah->adcgain_caldata);
                        INSERT_CAL(ah, &ah->adcgain_caldata);
                        ath_dbg(common, ATH_DBG_CALIBRATE,
-                               "enabling ADC Gain Calibration.\n");
+                                       "enabling ADC Gain Calibration.\n");
+               }
 
+               if (ar9002_hw_is_cal_supported(ah, chan, ADC_DC_CAL)) {
                        INIT_CAL(&ah->adcdc_caldata);
                        INSERT_CAL(ah, &ah->adcdc_caldata);
                        ath_dbg(common, ATH_DBG_CALIBRATE,
-                               "enabling ADC DC Calibration.\n");
+                                       "enabling ADC DC Calibration.\n");
                }
 
-               INIT_CAL(&ah->iq_caldata);
-               INSERT_CAL(ah, &ah->iq_caldata);
-               ath_dbg(common, ATH_DBG_CALIBRATE,
-                       "enabling IQ Calibration.\n");
+               if (ar9002_hw_is_cal_supported(ah, chan, IQ_MISMATCH_CAL)) {
+                       INIT_CAL(&ah->iq_caldata);
+                       INSERT_CAL(ah, &ah->iq_caldata);
+                       ath_dbg(common, ATH_DBG_CALIBRATE,
+                                       "enabling IQ Calibration.\n");
+               }
 
                ah->cal_list_curr = ah->cal_list;