Compare commits
1 Commits
master
...
pr-ath9k-m
Author | SHA1 | Date | |
---|---|---|---|
|
fa0740cca4 |
@ -0,0 +1,126 @@
|
||||
From: David Bauer <mail@david-bauer.net>
|
||||
Date: Fri, 25 Jun 2021 21:19:02 +0200
|
||||
Subject: mac80211: ath9k: add WAR for deaf RX state
|
||||
|
||||
Add a WAR dropped from OpenWrt tree with OpenWrt 18.06. It triggers a
|
||||
chip reset when there is no RX activity for more than 15 seconds.
|
||||
|
||||
Suggested-by: Jan-Tarek Butt <tarek@ring0.de>
|
||||
Signed-off-by: David Bauer <mail@david-bauer.net>
|
||||
|
||||
diff --git a/package/kernel/mac80211/patches/ath/359-ath9k-check-for-deaf-rx-path-state.patch b/package/kernel/mac80211/patches/ath/359-ath9k-check-for-deaf-rx-path-state.patch
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..bb36f513530caebe5745def86c0b73467c82366e
|
||||
--- /dev/null
|
||||
+++ b/package/kernel/mac80211/patches/ath/359-ath9k-check-for-deaf-rx-path-state.patch
|
||||
@@ -0,0 +1,110 @@
|
||||
+From: Felix Fietkau <nbd@nbd.name>
|
||||
+Date: Wed, 25 Jan 2017 13:00:58 +0100
|
||||
+Subject: [PATCH] ath9k: check for deaf rx path state
|
||||
+
|
||||
+Various chips occasionally run into a state where the tx path still
|
||||
+appears to be working normally, but the rx path is deaf.
|
||||
+
|
||||
+There is no known register signature to check for this state explicitly,
|
||||
+so use the lack of rx interrupts as an indicator.
|
||||
+
|
||||
+This detection is prone to false positives, since a device could also
|
||||
+simply be in an environment where there are no frames on the air.
|
||||
+However, in this case doing a reset should be harmless since it's
|
||||
+obviously not interrupting any real activity. To avoid confusion, call
|
||||
+the reset counters in this case "Rx path inactive" instead of something
|
||||
+like "Rx path deaf", since it may not be an indication of a real
|
||||
+hardware failure.
|
||||
+
|
||||
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
+[increase timeout for deaf RX state]
|
||||
+Signed-off-by: David Bauer <mail@david-bauer.net>
|
||||
+---
|
||||
+
|
||||
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||
+@@ -111,6 +111,7 @@ int ath_descdma_setup(struct ath_softc *
|
||||
+ #define ATH_HW_CHECK_POLL_INT 1000
|
||||
+ #define ATH_TXFIFO_DEPTH 8
|
||||
+ #define ATH_TX_ERROR 0x01
|
||||
++#define ATH_RX_STUCK_WAR_TIMEOUT 15000
|
||||
+
|
||||
+ #define ATH_AIRTIME_QUANTUM 300 /* usec */
|
||||
+
|
||||
+@@ -1029,6 +1030,7 @@ struct ath_softc {
|
||||
+
|
||||
+ u8 gtt_cnt;
|
||||
+ u32 intrstatus;
|
||||
++ u32 rx_active;
|
||||
+ u16 ps_flags; /* PS_* */
|
||||
+ bool ps_enabled;
|
||||
+ bool ps_idle;
|
||||
+--- a/drivers/net/wireless/ath/ath9k/debug.c
|
||||
++++ b/drivers/net/wireless/ath/ath9k/debug.c
|
||||
+@@ -763,6 +763,7 @@ static int read_file_reset(struct seq_fi
|
||||
+ [RESET_TYPE_BEACON_STUCK] = "Stuck Beacon",
|
||||
+ [RESET_TYPE_MCI] = "MCI Reset",
|
||||
+ [RESET_TYPE_CALIBRATION] = "Calibration error",
|
||||
++ [RESET_TYPE_RX_INACTIVE] = "Rx path inactive",
|
||||
+ [RESET_TX_DMA_ERROR] = "Tx DMA stop error",
|
||||
+ [RESET_RX_DMA_ERROR] = "Rx DMA stop error",
|
||||
+ };
|
||||
+--- a/drivers/net/wireless/ath/ath9k/debug.h
|
||||
++++ b/drivers/net/wireless/ath/ath9k/debug.h
|
||||
+@@ -50,6 +50,7 @@ enum ath_reset_type {
|
||||
+ RESET_TYPE_BEACON_STUCK,
|
||||
+ RESET_TYPE_MCI,
|
||||
+ RESET_TYPE_CALIBRATION,
|
||||
++ RESET_TYPE_RX_INACTIVE,
|
||||
+ RESET_TX_DMA_ERROR,
|
||||
+ RESET_RX_DMA_ERROR,
|
||||
+ __RESET_TYPE_MAX
|
||||
+--- a/drivers/net/wireless/ath/ath9k/link.c
|
||||
++++ b/drivers/net/wireless/ath/ath9k/link.c
|
||||
+@@ -53,13 +53,27 @@ reset:
|
||||
+
|
||||
+ }
|
||||
+
|
||||
++static bool ath_rx_active_check(struct ath_softc *sc)
|
||||
++{
|
||||
++ if (sc->rx_active) {
|
||||
++ sc->rx_active--;
|
||||
++ return true;
|
||||
++ }
|
||||
++
|
||||
++ ath_err(ath9k_hw_common(sc->sc_ah),
|
||||
++ "rx path inactive, resetting the chip\n");
|
||||
++ ath9k_queue_reset(sc, RESET_TYPE_RX_INACTIVE);
|
||||
++ return false;
|
||||
++}
|
||||
++
|
||||
+ void ath_hw_check_work(struct work_struct *work)
|
||||
+ {
|
||||
+ struct ath_softc *sc = container_of(work, struct ath_softc,
|
||||
+ hw_check_work.work);
|
||||
+
|
||||
+ if (!ath_hw_check(sc) ||
|
||||
+- !ath_tx_complete_check(sc))
|
||||
++ !ath_tx_complete_check(sc) ||
|
||||
++ !ath_rx_active_check(sc))
|
||||
+ return;
|
||||
+
|
||||
+ ieee80211_queue_delayed_work(sc->hw, &sc->hw_check_work,
|
||||
+--- a/drivers/net/wireless/ath/ath9k/main.c
|
||||
++++ b/drivers/net/wireless/ath/ath9k/main.c
|
||||
+@@ -270,6 +270,7 @@ static bool ath_complete_reset(struct at
|
||||
+ }
|
||||
+
|
||||
+ sc->gtt_cnt = 0;
|
||||
++ sc->rx_active = ATH_RX_STUCK_WAR_TIMEOUT;
|
||||
+
|
||||
+ ath9k_hw_set_interrupts(ah);
|
||||
+ ath9k_hw_enable_interrupts(ah);
|
||||
+@@ -446,6 +447,7 @@ void ath9k_tasklet(unsigned long data)
|
||||
+ ath_rx_tasklet(sc, 0, true);
|
||||
+
|
||||
+ ath_rx_tasklet(sc, 0, false);
|
||||
++ sc->rx_active = ATH_RX_STUCK_WAR_TIMEOUT;
|
||||
+ }
|
||||
+
|
||||
+ if (status & ATH9K_INT_TX) {
|
Loading…
Reference in New Issue
Block a user