aboutsummaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorAdrian Chadd <adrian@FreeBSD.org>2018-06-08 18:21:57 +0000
committerAdrian Chadd <adrian@FreeBSD.org>2018-06-08 18:21:57 +0000
commit8a97beff9839557b5baf2817e3f201133feeb1df (patch)
treef9c363da9c595677712dcc934b62e906dca556c6 /sys/dev
parent7b1c2c4ec25d2e80ffa3417cc2dff36f66b9fa25 (diff)
downloadsrc-8a97beff9839557b5baf2817e3f201133feeb1df.tar.gz
src-8a97beff9839557b5baf2817e3f201133feeb1df.zip
[ath_hal] Return failure if noise floor calibration fails.
If we fail noise floor calibration then we may end up with a deaf NIC which we can't recover without a full chip reset. Earlier chips seem to get less stuck in this condition versus AR9280/later and AR9300/later, but whilst here just fix up the AR5212 era chips to also return NF calibration failures. This HAL routine would only return failure if the channel was not configured. This is a no-op until the driver side code for doing resets and the HAL code for being told about the reset type (and then handling it!) is implemented. Tested: * AR9280, STA mode * AR2425, STA mode * AR9380, STA mode
Notes
Notes: svn path=/head/; revision=334849
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_cal.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c b/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c
index d4e34db3e9d8..106833fe6303 100644
--- a/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c
@@ -36,7 +36,7 @@
#define NUM_NOISEFLOOR_READINGS 6 /* 3 chains * (ctl + ext) */
static void ar5416StartNFCal(struct ath_hal *ah);
-static void ar5416LoadNF(struct ath_hal *ah, const struct ieee80211_channel *);
+static HAL_BOOL ar5416LoadNF(struct ath_hal *ah, const struct ieee80211_channel *);
static int16_t ar5416GetNf(struct ath_hal *, struct ieee80211_channel *);
static uint16_t ar5416GetDefaultNF(struct ath_hal *ah, const struct ieee80211_channel *chan);
@@ -513,6 +513,7 @@ ar5416PerCalibrationN(struct ath_hal *ah, struct ieee80211_channel *chan,
HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "%s: NF calibration"
" didn't finish; delaying CCA\n", __func__);
} else {
+ int ret;
/*
* NF calibration result is valid.
*
@@ -520,10 +521,17 @@ ar5416PerCalibrationN(struct ath_hal *ah, struct ieee80211_channel *chan,
* NF is slow time-variant, so it is OK to use a
* historical value.
*/
- ar5416LoadNF(ah, AH_PRIVATE(ah)->ah_curchan);
+ ret = ar5416LoadNF(ah, AH_PRIVATE(ah)->ah_curchan);
/* start NF calibration, without updating BB NF register*/
ar5416StartNFCal(ah);
+
+ /*
+ * If we failed calibration then tell the driver
+ * we failed and it should do a full chip reset
+ */
+ if (! ret)
+ return AH_FALSE;
}
}
return AH_TRUE;
@@ -578,7 +586,7 @@ ar5416StartNFCal(struct ath_hal *ah)
OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
}
-static void
+static HAL_BOOL
ar5416LoadNF(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
static const uint32_t ar5416_cca_regs[] = {
@@ -657,7 +665,7 @@ ar5416LoadNF(struct ath_hal *ah, const struct ieee80211_channel *chan)
HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "Timeout while waiting for "
"nf to load: AR_PHY_AGC_CONTROL=0x%x\n",
OS_REG_READ(ah, AR_PHY_AGC_CONTROL));
- return;
+ return AH_FALSE;
}
/*
@@ -679,6 +687,7 @@ ar5416LoadNF(struct ath_hal *ah, const struct ieee80211_channel *chan)
OS_REG_WRITE(ah, ar5416_cca_regs[i], val);
}
}
+ return AH_TRUE;
}
/*