Skip to content

Commit 872b5d8

Browse files
Felix Fietkaulinvjw
authored andcommitted
ath9k: do not access hardware on IRQs during reset
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. Signed-off-by: Felix Fietkau <[email protected]> Signed-off-by: John W. Linville <[email protected]>
1 parent ef739ab commit 872b5d8

File tree

1 file changed

+8
-6
lines changed
  • drivers/net/wireless/ath/ath9k

1 file changed

+8
-6
lines changed

drivers/net/wireless/ath/ath9k/main.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -512,16 +512,13 @@ irqreturn_t ath_isr(int irq, void *dev)
512512
if (!ah || test_bit(ATH_OP_INVALID, &common->op_flags))
513513
return IRQ_NONE;
514514

515-
/* shared irq, not for us */
515+
if (!AR_SREV_9100(ah) && test_bit(ATH_OP_HW_RESET, &common->op_flags))
516+
return IRQ_NONE;
516517

518+
/* shared irq, not for us */
517519
if (!ath9k_hw_intrpend(ah))
518520
return IRQ_NONE;
519521

520-
if (test_bit(ATH_OP_HW_RESET, &common->op_flags)) {
521-
ath9k_hw_kill_interrupts(ah);
522-
return IRQ_HANDLED;
523-
}
524-
525522
/*
526523
* Figure out the reason(s) for the interrupt. Note
527524
* that the hal returns a pseudo-ISR that may include
@@ -532,6 +529,9 @@ irqreturn_t ath_isr(int irq, void *dev)
532529
ath9k_debug_sync_cause(sc, sync_cause);
533530
status &= ah->imask; /* discard unasked-for bits */
534531

532+
if (AR_SREV_9100(ah) && test_bit(ATH_OP_HW_RESET, &common->op_flags))
533+
return IRQ_HANDLED;
534+
535535
/*
536536
* If there are no status bits set, then this interrupt was not
537537
* for me (should have been caught above).
@@ -613,6 +613,7 @@ int ath_reset(struct ath_softc *sc, struct ath9k_channel *hchan)
613613
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
614614
int r;
615615

616+
ath9k_hw_kill_interrupts(sc->sc_ah);
616617
set_bit(ATH_OP_HW_RESET, &common->op_flags);
617618

618619
ath9k_ps_wakeup(sc);
@@ -633,6 +634,7 @@ void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type)
633634
#ifdef CONFIG_ATH9K_DEBUGFS
634635
RESET_STAT_INC(sc, type);
635636
#endif
637+
ath9k_hw_kill_interrupts(sc->sc_ah);
636638
set_bit(ATH_OP_HW_RESET, &common->op_flags);
637639
ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
638640
}

0 commit comments

Comments
 (0)