* [PATCH 3.18 1/3] ath9k: prevent early IRQs from accessing hardware
@ 2014-11-13 17:34 Felix Fietkau
2014-11-13 17:34 ` [PATCH 3.18 2/3] ath9k: set ATH_OP_INVALID before disabling hardware Felix Fietkau
2014-11-13 17:34 ` [PATCH 3.18 3/3] ath9k: do not access hardware on IRQs during reset Felix Fietkau
0 siblings, 2 replies; 4+ messages in thread
From: Felix Fietkau @ 2014-11-13 17:34 UTC (permalink / raw)
To: linux-wireless; +Cc: linville
IRQs are suppressed if ah == NULL and ATH_OP_INVALID being set in
common->op_flags. Close a short time window between those two.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
drivers/net/wireless/ath/ath9k/init.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index c5bcddd..3c6ded9 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -529,10 +529,14 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
ah->reg_ops.read = ath9k_ioread32;
ah->reg_ops.write = ath9k_iowrite32;
ah->reg_ops.rmw = ath9k_reg_rmw;
- sc->sc_ah = ah;
pCap = &ah->caps;
common = ath9k_hw_common(ah);
+
+ /* Will be cleared in ath9k_start() */
+ set_bit(ATH_OP_INVALID, &common->op_flags);
+
+ sc->sc_ah = ah;
sc->dfs_detector = dfs_pattern_detector_init(common, NL80211_DFS_UNSET);
sc->tx99_power = MAX_RATE_POWER + 1;
init_waitqueue_head(&sc->tx_wait);
@@ -893,9 +897,6 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc,
common = ath9k_hw_common(ah);
ath9k_set_hw_capab(sc, hw);
- /* Will be cleared in ath9k_start() */
- set_bit(ATH_OP_INVALID, &common->op_flags);
-
/* Initialize regulatory */
error = ath_regd_init(&common->regulatory, sc->hw->wiphy,
ath9k_reg_notifier);
--
2.1.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 3.18 2/3] ath9k: set ATH_OP_INVALID before disabling hardware
2014-11-13 17:34 [PATCH 3.18 1/3] ath9k: prevent early IRQs from accessing hardware Felix Fietkau
@ 2014-11-13 17:34 ` Felix Fietkau
2014-11-13 17:34 ` [PATCH 3.18 3/3] ath9k: do not access hardware on IRQs during reset Felix Fietkau
1 sibling, 0 replies; 4+ messages in thread
From: Felix Fietkau @ 2014-11-13 17:34 UTC (permalink / raw)
To: linux-wireless; +Cc: linville
Closes another small IRQ handler race
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
drivers/net/wireless/ath/ath9k/main.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 644552c..ee67956 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -885,6 +885,9 @@ static void ath9k_stop(struct ieee80211_hw *hw)
&sc->cur_chan->chandef);
ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
+
+ set_bit(ATH_OP_INVALID, &common->op_flags);
+
ath9k_hw_phy_disable(ah);
ath9k_hw_configpcipowersave(ah, true);
@@ -893,7 +896,6 @@ static void ath9k_stop(struct ieee80211_hw *hw)
ath9k_ps_restore(sc);
- set_bit(ATH_OP_INVALID, &common->op_flags);
sc->ps_idle = prev_idle;
mutex_unlock(&sc->mutex);
--
2.1.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 3.18 3/3] ath9k: do not access hardware on IRQs during reset
2014-11-13 17:34 [PATCH 3.18 1/3] ath9k: prevent early IRQs from accessing hardware Felix Fietkau
2014-11-13 17:34 ` [PATCH 3.18 2/3] ath9k: set ATH_OP_INVALID before disabling hardware Felix Fietkau
@ 2014-11-13 17:34 ` Felix Fietkau
2014-11-15 22:46 ` Felix Fietkau
1 sibling, 1 reply; 4+ messages in thread
From: Felix Fietkau @ 2014-11-13 17:34 UTC (permalink / raw)
To: linux-wireless; +Cc: linville
Instead of killing interrupts during reset when the first one happens,
kill them before issuing the reset.
This fixes an easy to reproduce crash with multiple cards sharing the
same IRQ.
Cc: stable@vger.kernel.org
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
drivers/net/wireless/ath/ath9k/main.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index ee67956..19cab65 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -512,16 +512,13 @@ irqreturn_t ath_isr(int irq, void *dev)
if (!ah || test_bit(ATH_OP_INVALID, &common->op_flags))
return IRQ_NONE;
- /* shared irq, not for us */
+ if (test_bit(ATH_OP_HW_RESET, &common->op_flags))
+ return IRQ_NONE;
+ /* shared irq, not for us */
if (!ath9k_hw_intrpend(ah))
return IRQ_NONE;
- if (test_bit(ATH_OP_HW_RESET, &common->op_flags)) {
- ath9k_hw_kill_interrupts(ah);
- return IRQ_HANDLED;
- }
-
/*
* Figure out the reason(s) for the interrupt. Note
* that the hal returns a pseudo-ISR that may include
@@ -613,6 +610,7 @@ int ath_reset(struct ath_softc *sc, struct ath9k_channel *hchan)
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
int r;
+ ath9k_hw_kill_interrupts(sc->sc_ah);
set_bit(ATH_OP_HW_RESET, &common->op_flags);
ath9k_ps_wakeup(sc);
@@ -633,6 +631,7 @@ void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type)
#ifdef CONFIG_ATH9K_DEBUGFS
RESET_STAT_INC(sc, type);
#endif
+ ath9k_hw_kill_interrupts(sc->sc_ah);
set_bit(ATH_OP_HW_RESET, &common->op_flags);
ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
}
--
2.1.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2014-11-15 22:46 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-11-13 17:34 [PATCH 3.18 1/3] ath9k: prevent early IRQs from accessing hardware Felix Fietkau
2014-11-13 17:34 ` [PATCH 3.18 2/3] ath9k: set ATH_OP_INVALID before disabling hardware Felix Fietkau
2014-11-13 17:34 ` [PATCH 3.18 3/3] ath9k: do not access hardware on IRQs during reset Felix Fietkau
2014-11-15 22:46 ` Felix Fietkau
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).