ath9k: fix hang issues on hw reset caused by interrupt storms
[openwrt.git] / package / mac80211 / patches / 573-ath9k_fix_reset_hang.patch
1 --- a/drivers/net/wireless/ath/ath9k/mac.c
2 +++ b/drivers/net/wireless/ath/ath9k/mac.c
3 @@ -783,15 +783,10 @@ bool ath9k_hw_intrpend(struct ath_hw *ah
4  }
5  EXPORT_SYMBOL(ath9k_hw_intrpend);
6  
7 -void ath9k_hw_disable_interrupts(struct ath_hw *ah)
8 +void ath9k_hw_kill_interrupts(struct ath_hw *ah)
9  {
10         struct ath_common *common = ath9k_hw_common(ah);
11  
12 -       if (!(ah->imask & ATH9K_INT_GLOBAL))
13 -               atomic_set(&ah->intr_ref_cnt, -1);
14 -       else
15 -               atomic_dec(&ah->intr_ref_cnt);
16 -
17         ath_dbg(common, INTERRUPT, "disable IER\n");
18         REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
19         (void) REG_READ(ah, AR_IER);
20 @@ -803,6 +798,17 @@ void ath9k_hw_disable_interrupts(struct 
21                 (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
22         }
23  }
24 +EXPORT_SYMBOL(ath9k_hw_kill_interrupts);
25 +
26 +void ath9k_hw_disable_interrupts(struct ath_hw *ah)
27 +{
28 +       if (!(ah->imask & ATH9K_INT_GLOBAL))
29 +               atomic_set(&ah->intr_ref_cnt, -1);
30 +       else
31 +               atomic_dec(&ah->intr_ref_cnt);
32 +
33 +       ath9k_hw_kill_interrupts(ah);
34 +}
35  EXPORT_SYMBOL(ath9k_hw_disable_interrupts);
36  
37  void ath9k_hw_enable_interrupts(struct ath_hw *ah)
38 --- a/drivers/net/wireless/ath/ath9k/mac.h
39 +++ b/drivers/net/wireless/ath/ath9k/mac.h
40 @@ -734,6 +734,7 @@ bool ath9k_hw_intrpend(struct ath_hw *ah
41  void ath9k_hw_set_interrupts(struct ath_hw *ah);
42  void ath9k_hw_enable_interrupts(struct ath_hw *ah);
43  void ath9k_hw_disable_interrupts(struct ath_hw *ah);
44 +void ath9k_hw_kill_interrupts(struct ath_hw *ah);
45  
46  void ar9002_hw_attach_mac_ops(struct ath_hw *ah);
47  
48 --- a/drivers/net/wireless/ath/ath9k/main.c
49 +++ b/drivers/net/wireless/ath/ath9k/main.c
50 @@ -459,8 +459,10 @@ irqreturn_t ath_isr(int irq, void *dev)
51         if (!ath9k_hw_intrpend(ah))
52                 return IRQ_NONE;
53  
54 -       if(test_bit(SC_OP_HW_RESET, &sc->sc_flags))
55 +       if (test_bit(SC_OP_HW_RESET, &sc->sc_flags)) {
56 +               ath9k_hw_kill_interrupts(ah);
57                 return IRQ_HANDLED;
58 +       }
59  
60         /*
61          * Figure out the reason(s) for the interrupt.  Note