aboutsummaryrefslogtreecommitdiffstats
path: root/package
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2012-08-08 12:56:44 +0000
committerFelix Fietkau <nbd@openwrt.org>2012-08-08 12:56:44 +0000
commit59e0be352284a4dc743aad1e49fb4e9e724645e8 (patch)
treee1ae77c495b4b6aa57ffb5d76618cddff5b2b3ac /package
parent00f2d18224f8ba30588e4ee61db1cd9cb26e8438 (diff)
downloadupstream-59e0be352284a4dc743aad1e49fb4e9e724645e8.tar.gz
upstream-59e0be352284a4dc743aad1e49fb4e9e724645e8.tar.bz2
upstream-59e0be352284a4dc743aad1e49fb4e9e724645e8.zip
ath9k: fix hang issues on hw reset caused by interrupt storms
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@33055 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'package')
-rw-r--r--package/mac80211/patches/573-ath9k_fix_reset_hang.patch61
1 files changed, 61 insertions, 0 deletions
diff --git a/package/mac80211/patches/573-ath9k_fix_reset_hang.patch b/package/mac80211/patches/573-ath9k_fix_reset_hang.patch
new file mode 100644
index 0000000000..7b4d62f3bc
--- /dev/null
+++ b/package/mac80211/patches/573-ath9k_fix_reset_hang.patch
@@ -0,0 +1,61 @@
+--- a/drivers/net/wireless/ath/ath9k/mac.c
++++ b/drivers/net/wireless/ath/ath9k/mac.c
+@@ -783,15 +783,10 @@ bool ath9k_hw_intrpend(struct ath_hw *ah
+ }
+ EXPORT_SYMBOL(ath9k_hw_intrpend);
+
+-void ath9k_hw_disable_interrupts(struct ath_hw *ah)
++void ath9k_hw_kill_interrupts(struct ath_hw *ah)
+ {
+ struct ath_common *common = ath9k_hw_common(ah);
+
+- if (!(ah->imask & ATH9K_INT_GLOBAL))
+- atomic_set(&ah->intr_ref_cnt, -1);
+- else
+- atomic_dec(&ah->intr_ref_cnt);
+-
+ ath_dbg(common, INTERRUPT, "disable IER\n");
+ REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
+ (void) REG_READ(ah, AR_IER);
+@@ -803,6 +798,17 @@ void ath9k_hw_disable_interrupts(struct
+ (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
+ }
+ }
++EXPORT_SYMBOL(ath9k_hw_kill_interrupts);
++
++void ath9k_hw_disable_interrupts(struct ath_hw *ah)
++{
++ if (!(ah->imask & ATH9K_INT_GLOBAL))
++ atomic_set(&ah->intr_ref_cnt, -1);
++ else
++ atomic_dec(&ah->intr_ref_cnt);
++
++ ath9k_hw_kill_interrupts(ah);
++}
+ EXPORT_SYMBOL(ath9k_hw_disable_interrupts);
+
+ void ath9k_hw_enable_interrupts(struct ath_hw *ah)
+--- a/drivers/net/wireless/ath/ath9k/mac.h
++++ b/drivers/net/wireless/ath/ath9k/mac.h
+@@ -734,6 +734,7 @@ bool ath9k_hw_intrpend(struct ath_hw *ah
+ void ath9k_hw_set_interrupts(struct ath_hw *ah);
+ void ath9k_hw_enable_interrupts(struct ath_hw *ah);
+ void ath9k_hw_disable_interrupts(struct ath_hw *ah);
++void ath9k_hw_kill_interrupts(struct ath_hw *ah);
+
+ void ar9002_hw_attach_mac_ops(struct ath_hw *ah);
+
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -459,8 +459,10 @@ irqreturn_t ath_isr(int irq, void *dev)
+ if (!ath9k_hw_intrpend(ah))
+ return IRQ_NONE;
+
+- if(test_bit(SC_OP_HW_RESET, &sc->sc_flags))
++ if (test_bit(SC_OP_HW_RESET, &sc->sc_flags)) {
++ ath9k_hw_kill_interrupts(ah);
+ return IRQ_HANDLED;
++ }
+
+ /*
+ * Figure out the reason(s) for the interrupt. Note