Commit 0b98eaaa authored by Vivek Natarajan's avatar Vivek Natarajan Committed by John W. Linville
Browse files

ath9k: Add Calibration checks



* Prevent divide-by-zero errors in IQ Calibration.
* Do not run temperature compensation if initPDADC or currPDADC is zero.
* Also, introduce a separate function for handling OLC for AR9287.

Signed-off-by: default avatarVivek Natarajan <vnatarajan@atheros.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 181af387
Loading
Loading
Loading
Loading
+50 −28
Original line number Diff line number Diff line
@@ -403,7 +403,8 @@ static void ath9k_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
		iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
		qCoffDenom = powerMeasQ / 64;

		if (powerMeasQ != 0) {
		if ((powerMeasQ != 0) && (iCoffDenom != 0) &&
		    (qCoffDenom != 0)) {
			iCoff = iqCorrMeas / iCoffDenom;
			qCoff = powerMeasI / qCoffDenom - 64;
			ath_print(common, ATH_DBG_CALIBRATE,
@@ -746,29 +747,48 @@ s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
	return nf;
}

static void ath9k_olc_temp_compensation(struct ath_hw *ah)
static void ath9k_olc_temp_compensation_9287(struct ath_hw *ah)
{
	u32 rddata, i;
	int delta, currPDADC, regval, slope;
	u32 rddata;
	int32_t delta, currPDADC, slope;

	rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
	currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);


	if (OLC_FOR_AR9287_10_LATER) {
	if (ah->initPDADC == 0 || currPDADC == 0) {
		/*
		 * Zero value indicates that no frames have been transmitted yet,
		 * can't do temperature compensation until frames are transmitted.
		 */
		return;
	} else {
		slope = ah->eep_ops->get_eeprom(ah, EEP_TEMPSENSE_SLOPE);
			if (slope == 0)

		if (slope == 0) { /* to avoid divide by zero case */
			delta = 0;
			else
		} else {
			delta = ((currPDADC - ah->initPDADC)*4) / slope;
		}
		REG_RMW_FIELD(ah, AR_PHY_CH0_TX_PWRCTRL11,
			      AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
		REG_RMW_FIELD(ah, AR_PHY_CH1_TX_PWRCTRL11,
			      AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
	}
}

static void ath9k_olc_temp_compensation(struct ath_hw *ah)
{
	u32 rddata, i;
	int delta, currPDADC, regval;

	if (OLC_FOR_AR9287_10_LATER) {
		ath9k_olc_temp_compensation_9287(ah);
	} else {
		rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
		currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);

		if (ah->initPDADC == 0 || currPDADC == 0) {
			return;
		} else {
			if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G))
				delta = (currPDADC - ah->initPDADC + 4) / 8;
@@ -782,12 +802,14 @@ static void ath9k_olc_temp_compensation(struct ath_hw *ah)
					if (regval < 0)
						regval = 0;

				REG_RMW_FIELD(ah, AR_PHY_TX_GAIN_TBL1 + i * 4,
					REG_RMW_FIELD(ah,
						      AR_PHY_TX_GAIN_TBL1 + i * 4,
						      AR_PHY_TX_GAIN, regval);
				}
			}
		}
	}
}

static void ath9k_hw_9271_pa_cal(struct ath_hw *ah)
{