Skip to content
Snippets Groups Projects
0004-patches-openwrt-add-0016-ath9k-check-for-deaf-rx-pat.patch 5.17 KiB
Newer Older
From 16e48445555a8597a7d6dde41138dff4bc66d139 Mon Sep 17 00:00:00 2001
From: Jan-Tarek Butt <tarek@ring0.de>
Date: Sat, 5 Sep 2020 11:45:57 +0200
Subject: [PATCH 4/4] patches/openwrt: add
 0016-ath9k-check-for-deaf-rx-path-state.patch to fix 0% bug on meshlinks

Signed-off-by: Jan-Tarek Butt <tarek@ring0.de>
---
 ...6-ath9k-check-for-deaf-rx-path-state.patch | 126 ++++++++++++++++++
 1 file changed, 126 insertions(+)
 create mode 100644 patches/openwrt/0016-ath9k-check-for-deaf-rx-path-state.patch

diff --git a/patches/openwrt/0016-ath9k-check-for-deaf-rx-path-state.patch b/patches/openwrt/0016-ath9k-check-for-deaf-rx-path-state.patch
new file mode 100644
index 00000000..1c200536
--- /dev/null
+++ b/patches/openwrt/0016-ath9k-check-for-deaf-rx-path-state.patch
@@ -0,0 +1,126 @@
+From: Jan-Tarek Butt <tarek@ring0.de>
+Date: Sat, 5 Sep 2020 11:18:59 +0200
+Subject: 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: Jan-Tarek Butt <tarek@ring0.de>
+
+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..347d06ec888c56102523ed40b38aa4b5083d4c9c
+--- /dev/null
++++ b/package/kernel/mac80211/patches/ath/359-ath9k-check-for-deaf-rx-path-state.patch
+@@ -0,0 +1,100 @@
++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>
++---
++
++--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
++@@ -1027,6 +1027,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 = 0;
+++		return true;
+++	}
+++
+++	ath_dbg(ath9k_hw_common(sc->sc_ah), RESET,
+++		"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
++@@ -269,6 +269,7 @@ static bool ath_complete_reset(struct at
++ 	}
++ 	sc->gtt_cnt = 0;
+++	sc->rx_active = 1;
++ 	ath9k_hw_set_interrupts(ah);
++ 	ath9k_hw_enable_interrupts(ah);
++@@ -452,6 +453,7 @@ void ath9k_tasklet(unsigned long data)
++ 			ath_rx_tasklet(sc, 0, true);
++ 		ath_rx_tasklet(sc, 0, false);
+++		sc->rx_active = 1;
++ 	}
++ 	if (status & ATH9K_INT_TX) {
-- 
2.20.1