Commit 28ef6450 authored by Rajkumar Manoharan's avatar Rajkumar Manoharan Committed by John W. Linville

ath9k_hw: do noise floor calibration only on required chains

At present the noise floor calibration is processed in supported
control and extension chains rather than required chains.
Unnccesarily doing nfcal in all supported chains leads to
invalid nf readings on extn chains and these invalid values
got updated into history buffer. While loading those values
from history buffer is moving the chip to deaf state.

This issue was observed in AR9002/AR9003 chips while doing
associate/dissociate in HT40 mode and interface up/down
in iterative manner. After some iterations, the chip was moved
to deaf state. Somehow the pci devices are recovered by poll work
after chip reset. Raading the nf values in all supported extension chains
when the hw is not yet configured in HT40 mode results invalid values.

Cc: stable@kernel.org
Signed-off-by: default avatarRajkumar Manoharan <rmanoharan@atheros.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent eecc4800
...@@ -69,15 +69,21 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah, ...@@ -69,15 +69,21 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah,
int16_t *nfarray) int16_t *nfarray)
{ {
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
struct ieee80211_conf *conf = &common->hw->conf;
struct ath_nf_limits *limit; struct ath_nf_limits *limit;
struct ath9k_nfcal_hist *h; struct ath9k_nfcal_hist *h;
bool high_nf_mid = false; bool high_nf_mid = false;
u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
int i; int i;
h = cal->nfCalHist; h = cal->nfCalHist;
limit = ath9k_hw_get_nf_limits(ah, ah->curchan); limit = ath9k_hw_get_nf_limits(ah, ah->curchan);
for (i = 0; i < NUM_NF_READINGS; i++) { for (i = 0; i < NUM_NF_READINGS; i++) {
if (!(chainmask & (1 << i)) ||
((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf)))
continue;
h[i].nfCalBuffer[h[i].currIndex] = nfarray[i]; h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];
if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX) if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX)
...@@ -225,6 +231,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) ...@@ -225,6 +231,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
int32_t val; int32_t val;
u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask; u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
struct ieee80211_conf *conf = &common->hw->conf;
s16 default_nf = ath9k_hw_get_default_nf(ah, chan); s16 default_nf = ath9k_hw_get_default_nf(ah, chan);
if (ah->caldata) if (ah->caldata)
...@@ -234,6 +241,9 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) ...@@ -234,6 +241,9 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
if (chainmask & (1 << i)) { if (chainmask & (1 << i)) {
s16 nfval; s16 nfval;
if ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf))
continue;
if (h) if (h)
nfval = h[i].privNF; nfval = h[i].privNF;
else else
...@@ -293,6 +303,9 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) ...@@ -293,6 +303,9 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
ENABLE_REGWRITE_BUFFER(ah); ENABLE_REGWRITE_BUFFER(ah);
for (i = 0; i < NUM_NF_READINGS; i++) { for (i = 0; i < NUM_NF_READINGS; i++) {
if (chainmask & (1 << i)) { if (chainmask & (1 << i)) {
if ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf))
continue;
val = REG_READ(ah, ah->nf_regs[i]); val = REG_READ(ah, ah->nf_regs[i]);
val &= 0xFFFFFE00; val &= 0xFFFFFE00;
val |= (((u32) (-50) << 1) & 0x1ff); val |= (((u32) (-50) << 1) & 0x1ff);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment