mac80211: update to wireless-testing 2010-10-15, add a few ath9k fixes and performanc...
[openwrt.git] / package / mac80211 / patches / 550-ath9k_interrupt_mask_optimization.patch
1 --- a/drivers/net/wireless/ath/ath9k/mac.c
2 +++ b/drivers/net/wireless/ath/ath9k/mac.c
3 @@ -117,12 +117,11 @@ EXPORT_SYMBOL(ath9k_hw_numtxpending);
4  bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
5  {
6         u32 txcfg, curLevel, newLevel;
7 -       enum ath9k_int omask;
8  
9         if (ah->tx_trig_level >= ah->config.max_txtrig_level)
10                 return false;
11  
12 -       omask = ath9k_hw_set_interrupts(ah, ah->imask & ~ATH9K_INT_GLOBAL);
13 +       ath9k_hw_disable_interrupts(ah);
14  
15         txcfg = REG_READ(ah, AR_TXCFG);
16         curLevel = MS(txcfg, AR_FTRIG);
17 @@ -136,7 +135,7 @@ bool ath9k_hw_updatetxtriglevel(struct a
18                 REG_WRITE(ah, AR_TXCFG,
19                           (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG));
20  
21 -       ath9k_hw_set_interrupts(ah, omask);
22 +       ath9k_hw_enable_interrupts(ah);
23  
24         ah->tx_trig_level = newLevel;
25  
26 @@ -849,28 +848,59 @@ bool ath9k_hw_intrpend(struct ath_hw *ah
27  }
28  EXPORT_SYMBOL(ath9k_hw_intrpend);
29  
30 -enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah,
31 -                                             enum ath9k_int ints)
32 +void ath9k_hw_disable_interrupts(struct ath_hw *ah)
33 +{
34 +       struct ath_common *common = ath9k_hw_common(ah);
35 +
36 +       ath_print(common, ATH_DBG_INTERRUPT, "disable IER\n");
37 +       REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
38 +       (void) REG_READ(ah, AR_IER);
39 +       if (!AR_SREV_9100(ah)) {
40 +               REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
41 +               (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
42 +
43 +               REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
44 +               (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
45 +       }
46 +}
47 +EXPORT_SYMBOL(ath9k_hw_disable_interrupts);
48 +
49 +void ath9k_hw_enable_interrupts(struct ath_hw *ah)
50 +{
51 +       struct ath_common *common = ath9k_hw_common(ah);
52 +
53 +       if (!(ah->imask & ATH9K_INT_GLOBAL))
54 +               return;
55 +
56 +       ath_print(common, ATH_DBG_INTERRUPT, "enable IER\n");
57 +       REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
58 +       if (!AR_SREV_9100(ah)) {
59 +               REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
60 +                         AR_INTR_MAC_IRQ);
61 +               REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
62 +
63 +
64 +               REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
65 +                         AR_INTR_SYNC_DEFAULT);
66 +               REG_WRITE(ah, AR_INTR_SYNC_MASK,
67 +                         AR_INTR_SYNC_DEFAULT);
68 +       }
69 +       ath_print(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
70 +                 REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
71 +}
72 +EXPORT_SYMBOL(ath9k_hw_enable_interrupts);
73 +
74 +void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
75  {
76         enum ath9k_int omask = ah->imask;
77         u32 mask, mask2;
78         struct ath9k_hw_capabilities *pCap = &ah->caps;
79         struct ath_common *common = ath9k_hw_common(ah);
80  
81 -       ath_print(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
82 -
83 -       if (omask & ATH9K_INT_GLOBAL) {
84 -               ath_print(common, ATH_DBG_INTERRUPT, "disable IER\n");
85 -               REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
86 -               (void) REG_READ(ah, AR_IER);
87 -               if (!AR_SREV_9100(ah)) {
88 -                       REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
89 -                       (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
90 +       if (!(ints & ATH9K_INT_GLOBAL))
91 +               ath9k_hw_enable_interrupts(ah);
92  
93 -                       REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
94 -                       (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
95 -               }
96 -       }
97 +       ath_print(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
98  
99         /* TODO: global int Ref count */
100         mask = ints & ATH9K_INT_COMMON;
101 @@ -946,24 +976,8 @@ enum ath9k_int ath9k_hw_set_interrupts(s
102                         REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
103         }
104  
105 -       if (ints & ATH9K_INT_GLOBAL) {
106 -               ath_print(common, ATH_DBG_INTERRUPT, "enable IER\n");
107 -               REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
108 -               if (!AR_SREV_9100(ah)) {
109 -                       REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
110 -                                 AR_INTR_MAC_IRQ);
111 -                       REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
112 -
113 -
114 -                       REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
115 -                                 AR_INTR_SYNC_DEFAULT);
116 -                       REG_WRITE(ah, AR_INTR_SYNC_MASK,
117 -                                 AR_INTR_SYNC_DEFAULT);
118 -               }
119 -               ath_print(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
120 -                         REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
121 -       }
122 +       ath9k_hw_enable_interrupts(ah);
123  
124 -       return omask;
125 +       return;
126  }
127  EXPORT_SYMBOL(ath9k_hw_set_interrupts);
128 --- a/drivers/net/wireless/ath/ath9k/mac.h
129 +++ b/drivers/net/wireless/ath/ath9k/mac.h
130 @@ -669,6 +669,7 @@ enum ath9k_key_type {
131  
132  struct ath_hw;
133  struct ath9k_channel;
134 +enum ath9k_int;
135  
136  u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q);
137  void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp);
138 @@ -700,8 +701,9 @@ int ath9k_hw_beaconq_setup(struct ath_hw
139  
140  /* Interrupt Handling */
141  bool ath9k_hw_intrpend(struct ath_hw *ah);
142 -enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah,
143 -                                      enum ath9k_int ints);
144 +void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints);
145 +void ath9k_hw_enable_interrupts(struct ath_hw *ah);
146 +void ath9k_hw_disable_interrupts(struct ath_hw *ah);
147  
148  void ar9002_hw_attach_mac_ops(struct ath_hw *ah);
149  
150 --- a/drivers/net/wireless/ath/ath9k/main.c
151 +++ b/drivers/net/wireless/ath/ath9k/main.c
152 @@ -237,7 +237,7 @@ int ath_set_channel(struct ath_softc *sc
153          * hardware at the new frequency, and then re-enable
154          * the relevant bits of the h/w.
155          */
156 -       ath9k_hw_set_interrupts(ah, 0);
157 +       ath9k_hw_disable_interrupts(ah);
158         ath_drain_all_txq(sc, false);
159         stopped = ath_stoprecv(sc);
160  
161 @@ -644,7 +644,7 @@ void ath9k_tasklet(unsigned long data)
162                         ath_gen_timer_isr(sc->sc_ah);
163  
164         /* re-enable hardware interrupt */
165 -       ath9k_hw_set_interrupts(ah, ah->imask);
166 +       ath9k_hw_enable_interrupts(ah);
167         ath9k_ps_restore(sc);
168  }
169  
170 @@ -743,7 +743,7 @@ irqreturn_t ath_isr(int irq, void *dev)
171                  * interrupt; otherwise it will continue to
172                  * fire.
173                  */
174 -               ath9k_hw_set_interrupts(ah, 0);
175 +               ath9k_hw_disable_interrupts(ah);
176                 /*
177                  * Let the hal handle the event. We assume
178                  * it will clear whatever condition caused
179 @@ -752,7 +752,7 @@ irqreturn_t ath_isr(int irq, void *dev)
180                 spin_lock(&common->cc_lock);
181                 ath9k_hw_proc_mib_event(ah);
182                 spin_unlock(&common->cc_lock);
183 -               ath9k_hw_set_interrupts(ah, ah->imask);
184 +               ath9k_hw_enable_interrupts(ah);
185         }
186  
187         if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
188 @@ -769,8 +769,8 @@ chip_reset:
189         ath_debug_stat_interrupt(sc, status);
190  
191         if (sched) {
192 -               /* turn off every interrupt except SWBA */
193 -               ath9k_hw_set_interrupts(ah, (ah->imask & ATH9K_INT_SWBA));
194 +               /* turn off every interrupt */
195 +               ath9k_hw_disable_interrupts(ah);
196                 tasklet_schedule(&sc->intr_tq);
197         }
198  
199 @@ -925,7 +925,7 @@ void ath_radio_disable(struct ath_softc 
200         }
201  
202         /* Disable interrupts */
203 -       ath9k_hw_set_interrupts(ah, 0);
204 +       ath9k_hw_disable_interrupts(ah);
205  
206         ath_drain_all_txq(sc, false);   /* clear pending tx frames */
207         ath_stoprecv(sc);               /* turn off frame recv */
208 @@ -962,7 +962,7 @@ int ath_reset(struct ath_softc *sc, bool
209  
210         ieee80211_stop_queues(hw);
211  
212 -       ath9k_hw_set_interrupts(ah, 0);
213 +       ath9k_hw_disable_interrupts(ah);
214         ath_drain_all_txq(sc, retry_tx);
215         ath_stoprecv(sc);
216         ath_flushrecv(sc);
217 @@ -1367,7 +1367,7 @@ static void ath9k_stop(struct ieee80211_
218  
219         /* make sure h/w will not generate any interrupt
220          * before setting the invalid flag. */
221 -       ath9k_hw_set_interrupts(ah, 0);
222 +       ath9k_hw_disable_interrupts(ah);
223  
224         if (!(sc->sc_flags & SC_OP_INVALID)) {
225                 ath_drain_all_txq(sc, false);
226 --- a/drivers/net/wireless/ath/ath9k/beacon.c
227 +++ b/drivers/net/wireless/ath/ath9k/beacon.c
228 @@ -500,10 +500,10 @@ static void ath_beacon_config_ap(struct 
229  
230         /* Set the computed AP beacon timers */
231  
232 -       ath9k_hw_set_interrupts(ah, 0);
233 +       ath9k_hw_disable_interrupts(ah);
234         ath9k_beacon_init(sc, nexttbtt, intval);
235         sc->beacon.bmisscnt = 0;
236 -       ath9k_hw_set_interrupts(ah, ah->imask);
237 +       ath9k_hw_enable_interrupts(ah);
238  
239         /* Clear the reset TSF flag, so that subsequent beacon updation
240            will not reset the HW TSF. */
241 @@ -635,7 +635,7 @@ static void ath_beacon_config_sta(struct
242  
243         /* Set the computed STA beacon timers */
244  
245 -       ath9k_hw_set_interrupts(ah, 0);
246 +       ath9k_hw_disable_interrupts(ah);
247         ath9k_hw_set_sta_beacon_timers(ah, &bs);
248         ah->imask |= ATH9K_INT_BMISS;
249         ath9k_hw_set_interrupts(ah, ah->imask);
250 @@ -683,10 +683,10 @@ static void ath_beacon_config_adhoc(stru
251  
252         /* Set the computed ADHOC beacon timers */
253  
254 -       ath9k_hw_set_interrupts(ah, 0);
255 +       ath9k_hw_disable_interrupts(ah);
256         ath9k_beacon_init(sc, nexttbtt, intval);
257         sc->beacon.bmisscnt = 0;
258 -       ath9k_hw_set_interrupts(ah, ah->imask);
259 +       ath9k_hw_enable_interrupts(ah);
260  }
261  
262  void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
263 --- a/drivers/net/wireless/ath/ath9k/gpio.c
264 +++ b/drivers/net/wireless/ath/ath9k/gpio.c
265 @@ -275,7 +275,7 @@ static void ath9k_gen_timer_start(struct
266         ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period);
267  
268         if ((ah->imask & ATH9K_INT_GENTIMER) == 0) {
269 -               ath9k_hw_set_interrupts(ah, 0);
270 +               ath9k_hw_disable_interrupts(ah);
271                 ah->imask |= ATH9K_INT_GENTIMER;
272                 ath9k_hw_set_interrupts(ah, ah->imask);
273         }
274 @@ -289,7 +289,7 @@ static void ath9k_gen_timer_stop(struct 
275  
276         /* if no timer is enabled, turn off interrupt mask */
277         if (timer_table->timer_mask.val == 0) {
278 -               ath9k_hw_set_interrupts(ah, 0);
279 +               ath9k_hw_disable_interrupts(ah);
280                 ah->imask &= ~ATH9K_INT_GENTIMER;
281                 ath9k_hw_set_interrupts(ah, ah->imask);
282         }