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: Vivek Natarajan <vnatarajan@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Vivek Natarajan 2009-09-18 15:03:42 +05:30 committed by John W. Linville
parent 181af38703
commit 0b98eaaa02

View File

@ -403,7 +403,8 @@ static void ath9k_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128; iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
qCoffDenom = powerMeasQ / 64; qCoffDenom = powerMeasQ / 64;
if (powerMeasQ != 0) { if ((powerMeasQ != 0) && (iCoffDenom != 0) &&
(qCoffDenom != 0)) {
iCoff = iqCorrMeas / iCoffDenom; iCoff = iqCorrMeas / iCoffDenom;
qCoff = powerMeasI / qCoffDenom - 64; qCoff = powerMeasI / qCoffDenom - 64;
ath_print(common, ATH_DBG_CALIBRATE, 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; 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; u32 rddata;
int delta, currPDADC, regval, slope; int32_t delta, currPDADC, slope;
rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4); rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT); currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
if (OLC_FOR_AR9287_10_LATER) {
if (ah->initPDADC == 0 || currPDADC == 0) { 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; return;
} else { } else {
slope = ah->eep_ops->get_eeprom(ah, EEP_TEMPSENSE_SLOPE); slope = ah->eep_ops->get_eeprom(ah, EEP_TEMPSENSE_SLOPE);
if (slope == 0)
if (slope == 0) { /* to avoid divide by zero case */
delta = 0; delta = 0;
else } else {
delta = ((currPDADC - ah->initPDADC)*4) / slope; delta = ((currPDADC - ah->initPDADC)*4) / slope;
}
REG_RMW_FIELD(ah, AR_PHY_CH0_TX_PWRCTRL11, REG_RMW_FIELD(ah, AR_PHY_CH0_TX_PWRCTRL11,
AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta); AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
REG_RMW_FIELD(ah, AR_PHY_CH1_TX_PWRCTRL11, REG_RMW_FIELD(ah, AR_PHY_CH1_TX_PWRCTRL11,
AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta); 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 { } else {
if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G)) if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G))
delta = (currPDADC - ah->initPDADC + 4) / 8; delta = (currPDADC - ah->initPDADC + 4) / 8;
@ -782,11 +802,13 @@ static void ath9k_olc_temp_compensation(struct ath_hw *ah)
if (regval < 0) if (regval < 0)
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); AR_PHY_TX_GAIN, regval);
} }
} }
} }
}
} }
static void ath9k_hw_9271_pa_cal(struct ath_hw *ah) static void ath9k_hw_9271_pa_cal(struct ath_hw *ah)