summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruno Randolf <br1@einfach.org>2010-04-12 16:38:52 +0900
committerJohn W. Linville <linville@tuxdriver.com>2010-04-14 14:52:42 -0400
commit87d77c4ef132599eb3a6c49520719d39f7341efd (patch)
tree9b353e63a5fa50b6fc58b5cbf20a395166da4f5d
parent0edc9a6709d8e7d4f26c7f2a4b5ebdb641f8dfa0 (diff)
ath5k: treat RXORN as non-fatal
We get RXORN interrupts when all receive buffers are full. This is not necessarily a fatal situation. It can also happen when the bus is busy or the CPU is not fast enough to process all frames. Older chipsets apparently need a reset to come out of this situration, but on newer chips we can treat RXORN like RX, as going thru a full reset does more harm than good, there. The exact chip revisions which need a reset are unknown - this guess AR5K_SREV_AR5212 ("venice") is copied from the HAL. Inspired by openwrt 413-rxorn.patch: "treat rxorn like rx, reset after rxorn seems to do more harm than good" Signed-off-by: Bruno Randolf <br1@einfach.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c15
-rw-r--r--drivers/net/wireless/ath/ath5k/base.h1
2 files changed, 15 insertions, 1 deletions
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 3f59bc2d791..92327423325 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -2705,7 +2705,20 @@ ath5k_intr(int irq, void *dev_id)
*/
tasklet_schedule(&sc->restq);
} else if (unlikely(status & AR5K_INT_RXORN)) {
- tasklet_schedule(&sc->restq);
+ /*
+ * Receive buffers are full. Either the bus is busy or
+ * the CPU is not fast enough to process all received
+ * frames.
+ * Older chipsets need a reset to come out of this
+ * condition, but we treat it as RX for newer chips.
+ * We don't know exactly which versions need a reset -
+ * this guess is copied from the HAL.
+ */
+ sc->stats.rxorn_intr++;
+ if (ah->ah_mac_srev < AR5K_SREV_AR5212)
+ tasklet_schedule(&sc->restq);
+ else
+ tasklet_schedule(&sc->rxtq);
} else {
if (status & AR5K_INT_SWBA) {
tasklet_hi_schedule(&sc->beacontq);
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index 53a5651c57a..56221bc7c8c 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -135,6 +135,7 @@ struct ath5k_statistics {
unsigned int beacons;
unsigned int mib_intr;
+ unsigned int rxorn_intr;
};
#if CHAN_DEBUG