diff options
author | Felix Fietkau <nbd@openwrt.org> | 2012-08-08 12:56:44 +0000 |
---|---|---|
committer | Felix Fietkau <nbd@openwrt.org> | 2012-08-08 12:56:44 +0000 |
commit | 59e0be352284a4dc743aad1e49fb4e9e724645e8 (patch) | |
tree | e1ae77c495b4b6aa57ffb5d76618cddff5b2b3ac /package/mac80211 | |
parent | 00f2d18224f8ba30588e4ee61db1cd9cb26e8438 (diff) | |
download | master-187ad058-59e0be352284a4dc743aad1e49fb4e9e724645e8.tar.gz master-187ad058-59e0be352284a4dc743aad1e49fb4e9e724645e8.tar.bz2 master-187ad058-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/mac80211')
-rw-r--r-- | package/mac80211/patches/573-ath9k_fix_reset_hang.patch | 61 |
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 |