update to the latest madwifi snapshot
[openwrt.git] / package / madwifi / patches / 300-napi_polling.patch
1 Index: madwifi-ng-r2525-20070630/ath/if_ath.c
2 ===================================================================
3 --- madwifi-ng-r2525-20070630.orig/ath/if_ath.c 2007-07-03 23:02:32.178054750 +0200
4 +++ madwifi-ng-r2525-20070630/ath/if_ath.c      2007-07-03 23:02:32.998106000 +0200
5 @@ -170,7 +170,7 @@
6         int, u_int64_t);
7  static void ath_setdefantenna(struct ath_softc *, u_int);
8  static struct ath_txq *ath_txq_setup(struct ath_softc *, int, int);
9 -static void ath_rx_tasklet(TQUEUE_ARG);
10 +static int ath_rx_poll(struct net_device *dev, int *budget);
11  static int ath_hardstart(struct sk_buff *, struct net_device *);
12  static int ath_mgtstart(struct ieee80211com *, struct sk_buff *);
13  #ifdef ATH_SUPERG_COMP
14 @@ -446,7 +446,6 @@
15         ATH_TXBUF_LOCK_INIT(sc);
16         ATH_RXBUF_LOCK_INIT(sc);
17  
18 -       ATH_INIT_TQUEUE(&sc->sc_rxtq,     ath_rx_tasklet,       dev);
19         ATH_INIT_TQUEUE(&sc->sc_txtq,     ath_tx_tasklet,       dev);
20         ATH_INIT_TQUEUE(&sc->sc_bmisstq,  ath_bmiss_tasklet,    dev);
21         ATH_INIT_TQUEUE(&sc->sc_bstucktq, ath_bstuck_tasklet,   dev);
22 @@ -699,6 +698,8 @@
23         dev->set_mac_address = ath_set_mac_address;
24         dev->change_mtu = ath_change_mtu;
25         dev->tx_queue_len = ATH_TXBUF - 1;              /* 1 for mgmt frame */
26 +       dev->poll = ath_rx_poll;
27 +       dev->weight = 64;
28  #ifdef USE_HEADERLEN_RESV
29         dev->hard_header_len += sizeof(struct ieee80211_qosframe) +
30                                 sizeof(struct llc) +
31 @@ -1668,6 +1669,7 @@
32          */
33         ath_hal_getisr(ah, &status);            /* NB: clears ISR too */
34         DPRINTF(sc, ATH_DEBUG_INTR, "%s: status 0x%x\n", __func__, status);
35 +       sc->sc_isr = status;
36         status &= sc->sc_imask;                 /* discard unasked for bits */
37         if (status & HAL_INT_FATAL) {
38                 sc->sc_stats.ast_hardware++;
39 @@ -1703,7 +1705,14 @@
40                 if (status & HAL_INT_RX) {
41                         sc->sc_tsf = ath_hal_gettsf64(ah);
42                         ath_uapsd_processtriggers(sc);
43 -                       ATH_SCHEDULE_TQUEUE(&sc->sc_rxtq, &needmark);
44 +                       sc->sc_isr &= ~HAL_INT_RX;
45 +                       if (netif_rx_schedule_prep(dev)) {
46 +#ifndef ATH_PRECISE_TSF
47 +                               sc->sc_imask &= ~HAL_INT_RX;
48 +                               ath_hal_intrset(ah, sc->sc_imask);
49 +#endif
50 +                               __netif_rx_schedule(dev);
51 +                       }
52                 }
53                 if (status & HAL_INT_TX) {
54  #ifdef ATH_SUPERG_DYNTURBO
55 @@ -1729,6 +1738,11 @@
56                                 }
57                         }
58  #endif
59 +                       /* disable transmit interrupt */
60 +                       sc->sc_isr &= ~HAL_INT_TX;
61 +                       ath_hal_intrset(ah, sc->sc_imask & ~HAL_INT_TX);
62 +                       sc->sc_imask &= ~HAL_INT_TX;
63 +
64                         ATH_SCHEDULE_TQUEUE(&sc->sc_txtq, &needmark);
65                 }
66                 if (status & HAL_INT_BMISS) {
67 @@ -3323,10 +3337,10 @@
68          *
69          * XXX Using in_softirq is not right since we might
70          * be called from other soft irq contexts than
71 -        * ath_rx_tasklet.
72 +        * ath_rx_poll
73          */
74         if (!in_softirq())
75 -               tasklet_disable(&sc->sc_rxtq);
76 +               netif_poll_disable(dev);
77         netif_stop_queue(dev);
78  }
79  
80 @@ -3339,7 +3353,7 @@
81         DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s:\n", __func__);
82         netif_start_queue(dev);
83         if (!in_softirq())              /* NB: see above */
84 -               tasklet_enable(&sc->sc_rxtq);
85 +               netif_poll_enable(dev);
86  }
87  
88  /*
89 @@ -5590,13 +5604,12 @@
90         sc->sc_rxotherant = 0;
91  }
92  
93 -static void
94 -ath_rx_tasklet(TQUEUE_ARG data)
95 +static int
96 +ath_rx_poll(struct net_device *dev, int *budget)
97  {
98  #define        PA2DESC(_sc, _pa) \
99         ((struct ath_desc *)((caddr_t)(_sc)->sc_rxdma.dd_desc + \
100                 ((_pa) - (_sc)->sc_rxdma.dd_desc_paddr)))
101 -       struct net_device *dev = (struct net_device *)data;
102         struct ath_buf *bf;
103         struct ath_softc *sc = dev->priv;
104         struct ieee80211com *ic = &sc->sc_ic;
105 @@ -5609,12 +5622,15 @@
106         int type;
107         u_int phyerr;
108         u_int64_t rs_tsf;
109 +       u_int processed = 0, early_stop = 0;
110 +       u_int rx_limit = dev->quota;
111  
112         /* Let the 802.11 layer know about the new noise floor */
113         sc->sc_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan));
114         ic->ic_channoise = sc->sc_channoise;
115  
116         DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s\n", __func__);
117 +process_rx_again:
118         do {
119                 bf = STAILQ_FIRST(&sc->sc_rxbuf);
120                 if (bf == NULL) {               /* XXX ??? can this happen */
121 @@ -5638,6 +5654,13 @@
122                         /* NB: never process the self-linked entry at the end */
123                         break;
124                 }
125 +
126 +               processed++;
127 +               if (rx_limit-- < 0) {
128 +                       early_stop = 1;
129 +                       break;
130 +               }
131 +
132                 skb = bf->bf_skb;
133                 if (skb == NULL) {              /* XXX ??? can this happen */
134                         printk("%s: no skbuff (%s)\n", DEV_NAME(dev), __func__);
135 @@ -5676,6 +5699,7 @@
136                                 sc->sc_stats.ast_rx_phyerr++;
137                                 phyerr = rs->rs_phyerr & 0x1f;
138                                 sc->sc_stats.ast_rx_phy[phyerr]++;
139 +                               goto rx_next;
140                         }
141                         if (rs->rs_status & HAL_RXERR_DECRYPT) {
142                                 /*
143 @@ -5892,9 +5916,33 @@
144                 STAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list);
145                 ATH_RXBUF_UNLOCK_IRQ(sc);
146         } while (ath_rxbuf_init(sc, bf) == 0);
147 +       if (!early_stop) {
148 +               /* Check if more data is received while we were
149 +                * processing the descriptor chain.
150 +                */
151 +#ifndef ATH_PRECISE_TSF
152 +               ATH_DISABLE_INTR();
153 +               if (sc->sc_isr & HAL_INT_RX) {
154 +                       sc->sc_isr &= ~HAL_INT_RX;
155 +                       ATH_ENABLE_INTR();
156 +                       ath_uapsd_processtriggers(sc);
157 +                       goto process_rx_again;
158 +               }
159 +#endif
160 +               netif_rx_complete(dev);
161 +
162 +#ifndef ATH_PRECISE_TSF
163 +               sc->sc_imask |= HAL_INT_RX;
164 +               ath_hal_intrset(ah, sc->sc_imask);
165 +               ATH_ENABLE_INTR();
166 +#endif
167 +       }
168 +
169 +       *budget -= processed;
170  
171         /* rx signal state monitoring */
172         ath_hal_rxmonitor(ah, &sc->sc_halstats, &sc->sc_curchan);
173 +       return early_stop;
174  #undef PA2DESC
175  }
176  
177 @@ -7513,11 +7561,22 @@
178         struct net_device *dev = (struct net_device *)data;
179         struct ath_softc *sc = dev->priv;
180  
181 +process_tx_again:
182         if (txqactive(sc->sc_ah, 0))
183                 ath_tx_processq(sc, &sc->sc_txq[0]);
184         if (txqactive(sc->sc_ah, sc->sc_cabq->axq_qnum))
185                 ath_tx_processq(sc, sc->sc_cabq);
186  
187 +       ATH_DISABLE_INTR();
188 +       if (sc->sc_isr & HAL_INT_TX) {
189 +               sc->sc_isr &= ~HAL_INT_TX;
190 +               ATH_ENABLE_INTR();
191 +               goto process_tx_again;
192 +       }
193 +       sc->sc_imask |= HAL_INT_TX;
194 +       ath_hal_intrset(sc->sc_ah, sc->sc_imask);
195 +       ATH_ENABLE_INTR();
196 +
197         netif_wake_queue(dev);
198  
199         if (sc->sc_softled)
200 @@ -7534,6 +7593,7 @@
201         struct net_device *dev = (struct net_device *)data;
202         struct ath_softc *sc = dev->priv;
203  
204 +process_tx_again:
205         /*
206          * Process each active queue.
207          */
208 @@ -7554,6 +7614,16 @@
209         if (sc->sc_uapsdq && txqactive(sc->sc_ah, sc->sc_uapsdq->axq_qnum))
210                 ath_tx_processq(sc, sc->sc_uapsdq);
211  
212 +       ATH_DISABLE_INTR();
213 +       if (sc->sc_isr & HAL_INT_TX) {
214 +               sc->sc_isr &= ~HAL_INT_TX;
215 +               ATH_ENABLE_INTR();
216 +               goto process_tx_again;
217 +       }
218 +       sc->sc_imask |= HAL_INT_TX;
219 +       ath_hal_intrset(sc->sc_ah, sc->sc_imask);
220 +       ATH_ENABLE_INTR();
221 +
222         netif_wake_queue(dev);
223  
224         if (sc->sc_softled)
225 @@ -7571,6 +7641,7 @@
226         unsigned int i;
227  
228         /* Process each active queue. */
229 +process_tx_again:
230         for (i = 0; i < HAL_NUM_TX_QUEUES; i++)
231                 if (ATH_TXQ_SETUP(sc, i) && txqactive(sc->sc_ah, i))
232                         ath_tx_processq(sc, &sc->sc_txq[i]);
233 @@ -7579,6 +7650,16 @@
234                 ath_tx_processq(sc, sc->sc_xrtxq);
235  #endif
236  
237 +       ATH_DISABLE_INTR();
238 +       if (sc->sc_isr & HAL_INT_TX) {
239 +               sc->sc_isr &= ~HAL_INT_TX;
240 +               ATH_ENABLE_INTR();
241 +               goto process_tx_again;
242 +       }
243 +       sc->sc_imask |= HAL_INT_TX;
244 +       ath_hal_intrset(sc->sc_ah, sc->sc_imask);
245 +       ATH_ENABLE_INTR();
246 +
247         netif_wake_queue(dev);
248  
249         if (sc->sc_softled)
250 @@ -7677,6 +7758,7 @@
251  ath_draintxq(struct ath_softc *sc)
252  {
253         struct ath_hal *ah = sc->sc_ah;
254 +       int npend = 0;
255         unsigned int i;
256  
257         /* XXX return value */
258 @@ -9195,9 +9277,9 @@
259         dev->mtu = mtu;
260         if ((dev->flags & IFF_RUNNING) && !sc->sc_invalid) {
261                 /* NB: the rx buffers may need to be reallocated */
262 -               tasklet_disable(&sc->sc_rxtq);
263 +               netif_poll_disable(dev);
264                 error = ath_reset(dev);
265 -               tasklet_enable(&sc->sc_rxtq);
266 +               netif_poll_enable(dev);
267         }
268         ATH_UNLOCK(sc);
269  
270 Index: madwifi-ng-r2525-20070630/ath/if_athvar.h
271 ===================================================================
272 --- madwifi-ng-r2525-20070630.orig/ath/if_athvar.h      2007-07-03 23:02:30.957978500 +0200
273 +++ madwifi-ng-r2525-20070630/ath/if_athvar.h   2007-07-03 23:02:33.002106250 +0200
274 @@ -49,6 +49,10 @@
275  #include "net80211/ieee80211.h"                /* XXX for WME_NUM_AC */
276  #include <asm/io.h>
277  
278 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
279 +#define irqs_disabled()                        0
280 +#endif
281 +
282  /*
283   * Deduce if tasklets are available.  If not then
284   * fall back to using the immediate work queue.
285 @@ -625,7 +629,6 @@
286         struct ath_buf *sc_rxbufcur;            /* current rx buffer */
287         u_int32_t *sc_rxlink;                   /* link ptr in last RX desc */
288         spinlock_t sc_rxbuflock;
289 -       struct ATH_TQ_STRUCT sc_rxtq;           /* rx intr tasklet */
290         struct ATH_TQ_STRUCT sc_rxorntq;        /* rxorn intr tasklet */
291         u_int8_t sc_defant;                     /* current default antenna */
292         u_int8_t sc_rxotherant;                 /* RXs on non-default antenna */
293 @@ -638,6 +641,7 @@
294         u_int sc_txintrperiod;                  /* tx interrupt batching */
295         struct ath_txq sc_txq[HAL_NUM_TX_QUEUES];
296         struct ath_txq *sc_ac2q[WME_NUM_AC];    /* WME AC -> h/w qnum */
297 +       HAL_INT sc_isr;                         /* unmasked ISR state */
298         struct ATH_TQ_STRUCT sc_txtq;           /* tx intr tasklet */
299         u_int8_t sc_grppoll_str[GRPPOLL_RATE_STR_LEN];
300         struct ath_descdma sc_bdma;             /* beacon descriptors */
301 @@ -718,6 +722,8 @@
302  #define        ATH_TXBUF_LOCK_ASSERT(_sc) \
303         KASSERT(spin_is_locked(&(_sc)->sc_txbuflock), ("txbuf not locked!"))
304  
305 +#define ATH_DISABLE_INTR               local_irq_disable
306 +#define ATH_ENABLE_INTR                local_irq_enable
307  
308  #define        ATH_RXBUF_LOCK_INIT(_sc)        spin_lock_init(&(_sc)->sc_rxbuflock)
309  #define        ATH_RXBUF_LOCK_DESTROY(_sc)
310 Index: madwifi-ng-r2525-20070630/net80211/ieee80211_input.c
311 ===================================================================
312 --- madwifi-ng-r2525-20070630.orig/net80211/ieee80211_input.c   2007-07-03 23:02:31.926039000 +0200
313 +++ madwifi-ng-r2525-20070630/net80211/ieee80211_input.c        2007-07-03 23:02:33.002106250 +0200
314 @@ -1128,8 +1128,9 @@
315                 if (ni->ni_vlan != 0 && vap->iv_vlgrp != NULL) {
316                         /* attach vlan tag */
317                         vlan_hwaccel_receive_skb(skb, vap->iv_vlgrp, ni->ni_vlan);
318 -               } else
319 -                       netif_rx(skb);
320 +               } else {
321 +                       netif_receive_skb(skb);
322 +               }
323                 dev->last_rx = jiffies;
324         }
325  }