Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 04d19ddd authored by Sujith's avatar Sujith Committed by John W. Linville
Browse files

ath9k: Fix bug in calibration initialization



This patch fixes a bug in ath9k_hw_init_cal() where the wrong
calibration was being done for non-AR9285 chipsets.
Also add a few helpful comments.

Cc: stable@kernel.org
Signed-off-by: default avatarSujith <Sujith.Manoharan@atheros.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent cbfe9468
Loading
Loading
Loading
Loading
+22 −39
Original line number Diff line number Diff line
@@ -918,34 +918,15 @@ static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan)
	return true;
}

bool ath9k_hw_init_cal(struct ath_hw *ah,
		       struct ath9k_channel *chan)
bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
{
	if (AR_SREV_9285(ah) && AR_SREV_9285_12_OR_LATER(ah)) {
		if (!ar9285_clc(ah, chan))
			return false;
	} else if (AR_SREV_9280_10_OR_LATER(ah)) {
		REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
		REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
		REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);

		/* Kick off the cal */
		REG_WRITE(ah, AR_PHY_AGC_CONTROL,
				REG_READ(ah, AR_PHY_AGC_CONTROL) |
				AR_PHY_AGC_CONTROL_CAL);

		if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
					AR_PHY_AGC_CONTROL_CAL, 0,
					AH_WAIT_TIMEOUT)) {
			DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
				"offset calibration failed to complete in 1ms; "
				"noisy environment?\n");
			return false;
		}

	} else {
		if (AR_SREV_9280_10_OR_LATER(ah)) {
			REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
			REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
		REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
		}

		/* Calibrate the AGC */
@@ -953,6 +934,7 @@ bool ath9k_hw_init_cal(struct ath_hw *ah,
			  REG_READ(ah, AR_PHY_AGC_CONTROL) |
			  AR_PHY_AGC_CONTROL_CAL);

		/* Poll for offset calibration complete */
		if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
				   0, AH_WAIT_TIMEOUT)) {
			DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
@@ -965,18 +947,19 @@ bool ath9k_hw_init_cal(struct ath_hw *ah,
			REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
			REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
		}
	}

	/* Do PA Calibration */
	if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah))
		ath9k_hw_9285_pa_cal(ah);

	/* Do NF Calibration */
	/* Do NF Calibration after DC offset and other calibrations */
	REG_WRITE(ah, AR_PHY_AGC_CONTROL,
			REG_READ(ah, AR_PHY_AGC_CONTROL) |
			AR_PHY_AGC_CONTROL_NF);
		  REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF);

	ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;

	/* Enable IQ, ADC Gain and ADC DC offset CALs */
	if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
		if (ath9k_hw_iscal_supported(ah, ADC_GAIN_CAL)) {
			INIT_CAL(&ah->adcgain_caldata);