1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-27 11:55:06 +00:00

Bring over some NF calibration changes from ath9k.

Each different radio chipset has a different "good" range of CCA
(clear channel access) parameters where, if you write something
out of range, it's possible the radio will go deaf.

Also, since apparently occasionally reading the NF calibration
returns "wrong" values, so enforce those limits on what is being
written into the CCA register.

Write a default value if there's no history available.

This isn't the case right now but it may be later on when "off-channel"
scanning occurs without init'ing or changing the NF history buffer.
(As each channel may have a different noise floor; so scanning or
other off-channel activity shouldn't affect the NF history of
the current channel.)
This commit is contained in:
Adrian Chadd 2011-01-29 14:27:20 +00:00
parent 7c913dea08
commit c6c9d8c8ed
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=218068
9 changed files with 128 additions and 2 deletions

View File

@ -49,6 +49,12 @@ typedef struct {
#define AR5416_SPUR_RSSI_THRESH 40
struct ar5416NfLimits {
int16_t max;
int16_t min;
int16_t nominal;
};
struct ath_hal_5416 {
struct ath_hal_5212 ah_5212;
@ -82,6 +88,9 @@ struct ath_hal_5416 {
uint32_t ah_tx_chainmask;
struct ar5416PerCal ah_cal; /* periodic calibration state */
struct ar5416NfLimits nf_2g;
struct ar5416NfLimits nf_5g;
};
#define AH5416(_ah) ((struct ath_hal_5416 *)(_ah))

View File

@ -356,6 +356,14 @@ ar5416Attach(uint16_t devid, HAL_SOFTC sc,
}
ar5416AniSetup(ah); /* Anti Noise Immunity */
AH5416(ah)->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_5416_2GHZ;
AH5416(ah)->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_5416_2GHZ;
AH5416(ah)->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_5416_2GHZ;
AH5416(ah)->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_5416_5GHZ;
AH5416(ah)->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_5416_5GHZ;
AH5416(ah)->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_5416_5GHZ;
ar5416InitNfHistBuff(AH5416(ah)->ah_cal.nfCalHist);
HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__);

View File

@ -37,6 +37,9 @@ static void ar5416StartNFCal(struct ath_hal *ah);
static void 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);
static void ar5416SanitizeNF(struct ath_hal *ah, int16_t *nf);
/*
* Determine if calibration is supported by device and channel flags
*/
@ -548,6 +551,7 @@ ar5416LoadNF(struct ath_hal *ah, const struct ieee80211_channel *chan)
int i;
int32_t val;
uint8_t chainmask;
int16_t default_nf = ar5416GetDefaultNF(ah, chan);
/*
* Force NF calibration for all chains.
@ -567,13 +571,24 @@ ar5416LoadNF(struct ath_hal *ah, const struct ieee80211_channel *chan)
* so we can load below.
*/
h = AH5416(ah)->ah_cal.nfCalHist;
for (i = 0; i < AR5416_NUM_NF_READINGS; i ++)
HALDEBUG(ah, HAL_DEBUG_NFCAL, "CCA: ");
for (i = 0; i < AR5416_NUM_NF_READINGS; i ++) {
if (chainmask & (1 << i)) {
int16_t nf_val;
if (h)
nf_val = h[i].privNF;
else
nf_val = default_nf;
val = OS_REG_READ(ah, ar5416_cca_regs[i]);
val &= 0xFFFFFE00;
val |= (((uint32_t)(h[i].privNF) << 1) & 0x1ff);
val |= (((uint32_t) nf_val << 1) & 0x1ff);
HALDEBUG(ah, HAL_DEBUG_NFCAL, "[%d: %d]", i, nf_val);
OS_REG_WRITE(ah, ar5416_cca_regs[i], val);
}
}
HALDEBUG(ah, HAL_DEBUG_NFCAL, "\n");
/* Load software filtered NF value into baseband internal minCCApwr variable. */
OS_REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF);
@ -611,6 +626,11 @@ ar5416LoadNF(struct ath_hal *ah, const struct ieee80211_channel *chan)
}
}
/*
* This just initialises the "good" values for AR5416 which
* may not be right; it'lll be overridden by ar5416SanitizeNF()
* to nominal values.
*/
void
ar5416InitNfHistBuff(struct ar5212NfCalHist *h)
{
@ -652,6 +672,50 @@ ar5416UpdateNFHistBuff(struct ar5212NfCalHist *h, int16_t *nfarray)
}
}
static uint16_t
ar5416GetDefaultNF(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
struct ar5416NfLimits *limit;
if (!chan || IEEE80211_IS_CHAN_2GHZ(chan))
limit = &AH5416(ah)->nf_2g;
else
limit = &AH5416(ah)->nf_5g;
return limit->nominal;
}
static void
ar5416SanitizeNF(struct ath_hal *ah, int16_t *nf)
{
struct ar5416NfLimits *limit;
int i;
if (IEEE80211_IS_CHAN_2GHZ(AH_PRIVATE(ah)->ah_curchan))
limit = &AH5416(ah)->nf_2g;
else
limit = &AH5416(ah)->nf_5g;
for (i = 0; i < AR5416_NUM_NF_READINGS; i++) {
if (!nf[i])
continue;
if (nf[i] > limit->max) {
HALDEBUG(ah, HAL_DEBUG_NFCAL,
"NF[%d] (%d) > MAX (%d), correcting to MAX\n",
i, nf[i], limit->max);
nf[i] = limit->max;
} else if (nf[i] < limit->min) {
HALDEBUG(ah, HAL_DEBUG_NFCAL,
"NF[%d] (%d) < MIN (%d), correcting to NOM\n",
i, nf[i], limit->min);
nf[i] = limit->nominal;
}
}
}
/*
* Read the NF and check it against the noise floor threshhold
*/
@ -672,6 +736,7 @@ ar5416GetNf(struct ath_hal *ah, struct ieee80211_channel *chan)
/* TODO - enhance for multiple chains and ext ch */
ath_hal_getNoiseFloor(ah, nfarray);
nf = nfarray[0];
ar5416SanitizeNF(ah, nfarray);
if (ar5416GetEepromNoiseFloorThresh(ah, chan, &nfThresh)) {
if (nf > nfThresh) {
HALDEBUG(ah, HAL_DEBUG_ANY,

View File

@ -269,4 +269,13 @@
#define AR_PHY_CL_CAL_CTL 0xA358 /* carrier leak cal control */
#define AR_PHY_CL_CAL_ENABLE 0x00000002
#define AR_PHY_PARALLEL_CAL_ENABLE 0x00000001
/* empirically determined "good" CCA value ranges from atheros */
#define AR_PHY_CCA_NOM_VAL_5416_2GHZ -90
#define AR_PHY_CCA_NOM_VAL_5416_5GHZ -100
#define AR_PHY_CCA_MIN_GOOD_VAL_5416_2GHZ -100
#define AR_PHY_CCA_MIN_GOOD_VAL_5416_5GHZ -110
#define AR_PHY_CCA_MAX_GOOD_VAL_5416_2GHZ -80
#define AR_PHY_CCA_MAX_GOOD_VAL_5416_5GHZ -90
#endif /* _DEV_ATH_AR5416PHY_H_ */

View File

@ -250,6 +250,15 @@ ar9160Attach(uint16_t devid, HAL_SOFTC sc,
OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode);
ar9160AniSetup(ah); /* Anti Noise Immunity */
/* This just uses the AR5416 NF values */
AH5416(ah)->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_5416_2GHZ;
AH5416(ah)->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_5416_2GHZ;
AH5416(ah)->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_5416_2GHZ;
AH5416(ah)->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_5416_5GHZ;
AH5416(ah)->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_5416_5GHZ;
AH5416(ah)->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_5416_5GHZ;
ar5416InitNfHistBuff(AH5416(ah)->ah_cal.nfCalHist);
HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__);

View File

@ -34,6 +34,13 @@ struct ath_hal_9280 {
#define AR9280_DEFAULT_TXCHAINMASK 1
#define AR9285_DEFAULT_TXCHAINMASK 1
#define AR_PHY_CCA_NOM_VAL_9280_2GHZ -112
#define AR_PHY_CCA_NOM_VAL_9280_5GHZ -112
#define AR_PHY_CCA_MIN_GOOD_VAL_9280_2GHZ -127
#define AR_PHY_CCA_MIN_GOOD_VAL_9280_5GHZ -122
#define AR_PHY_CCA_MAX_GOOD_VAL_9280_2GHZ -97
#define AR_PHY_CCA_MAX_GOOD_VAL_9280_5GHZ -102
HAL_BOOL ar9280RfAttach(struct ath_hal *, HAL_STATUS *);
struct ath_hal;

View File

@ -280,6 +280,15 @@ ar9280Attach(uint16_t devid, HAL_SOFTC sc,
OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode);
ar9280AniSetup(ah); /* Anti Noise Immunity */
/* Setup noise floor min/max/nominal values */
AH5416(ah)->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9280_2GHZ;
AH5416(ah)->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9280_2GHZ;
AH5416(ah)->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9280_2GHZ;
AH5416(ah)->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9280_5GHZ;
AH5416(ah)->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9280_5GHZ;
AH5416(ah)->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9280_5GHZ;
ar5416InitNfHistBuff(AH5416(ah)->ah_cal.nfCalHist);
HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__);

View File

@ -31,6 +31,9 @@ struct ath_hal_9285 {
#define AR9285_DEFAULT_RXCHAINMASK 1
#define AR9285_DEFAULT_TXCHAINMASK 1
#define AR_PHY_CCA_NOM_VAL_9285_2GHZ -118
#define AR_PHY_CCA_MIN_GOOD_VAL_9285_2GHZ -127
#define AR_PHY_CCA_MAX_GOOD_VAL_9285_2GHZ -108
HAL_BOOL ar9285SetAntennaSwitch(struct ath_hal *, HAL_ANT_SETTING);
HAL_BOOL ar9285RfAttach(struct ath_hal *, HAL_STATUS *);

View File

@ -281,6 +281,13 @@ ar9285Attach(uint16_t devid, HAL_SOFTC sc,
OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode);
ar9285AniSetup(ah); /* Anti Noise Immunity */
/* Setup noise floor min/max/nominal values */
AH5416(ah)->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9285_2GHZ;
AH5416(ah)->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9285_2GHZ;
AH5416(ah)->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9285_2GHZ;
/* XXX no 5ghz values? */
ar5416InitNfHistBuff(AH5416(ah)->ah_cal.nfCalHist);
HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__);