update madwifi to latest rev - works around some crashiness
[openwrt.git] / package / madwifi / patches / 300-napi_polling.patch
1 Index: madwifi-ng-r2834-20071106/ath/if_ath.c
2 ===================================================================
3 --- madwifi-ng-r2834-20071106.orig/ath/if_ath.c 2007-11-07 14:02:04.537629461 +0100
4 +++ madwifi-ng-r2834-20071106/ath/if_ath.c      2007-11-07 14:02:04.865648150 +0100
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 @@ -445,7 +445,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 @@ -696,6 +695,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 @@ -1794,6 +1795,7 @@
32                 (status & HAL_INT_RXPHY)   ? " HAL_INT_RXPHY"   : "",
33                 (status & HAL_INT_SWBA)    ? " HAL_INT_SWBA"    : "");
34  
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 @@ -1831,7 +1833,14 @@
40                 }
41                 if (status & (HAL_INT_RX | HAL_INT_RXPHY)) {
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 @@ -1857,6 +1866,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 @@ -3450,10 +3464,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 @@ -3466,7 +3480,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 @@ -5707,13 +5721,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 @@ -5726,9 +5739,11 @@
106         int type;
107         u_int phyerr;
108         u_int64_t rs_tsf;
109 -
110 +       u_int processed = 0, early_stop = 0;
111 +       u_int rx_limit = dev->quota;
112  
113         DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s\n", __func__);
114 +process_rx_again:
115         do {
116                 bf = STAILQ_FIRST(&sc->sc_rxbuf);
117                 if (bf == NULL) {               /* XXX ??? can this happen */
118 @@ -5752,6 +5767,13 @@
119                         /* NB: never process the self-linked entry at the end */
120                         break;
121                 }
122 +
123 +               processed++;
124 +               if (rx_limit-- < 0) {
125 +                       early_stop = 1;
126 +                       break;
127 +               }
128 +
129                 skb = bf->bf_skb;
130                 if (skb == NULL) {              /* XXX ??? can this happen */
131                         printk("%s: no skbuff (%s)\n", DEV_NAME(dev), __func__);
132 @@ -5796,6 +5818,7 @@
133                                 sc->sc_stats.ast_rx_phyerr++;
134                                 phyerr = rs->rs_phyerr & 0x1f;
135                                 sc->sc_stats.ast_rx_phy[phyerr]++;
136 +                               goto rx_next;
137                         }
138                         if (rs->rs_status & HAL_RXERR_DECRYPT) {
139                                 /*
140 @@ -6011,9 +6034,33 @@
141                 STAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list);
142                 ATH_RXBUF_UNLOCK_IRQ(sc);
143         } while (ath_rxbuf_init(sc, bf) == 0);
144 +       if (!early_stop) {
145 +               /* Check if more data is received while we were
146 +                * processing the descriptor chain.
147 +                */
148 +#ifndef ATH_PRECISE_TSF
149 +               ATH_DISABLE_INTR();
150 +               if (sc->sc_isr & HAL_INT_RX) {
151 +                       sc->sc_isr &= ~HAL_INT_RX;
152 +                       ATH_ENABLE_INTR();
153 +                       ath_uapsd_processtriggers(sc);
154 +                       goto process_rx_again;
155 +               }
156 +#endif
157 +               netif_rx_complete(dev);
158 +
159 +#ifndef ATH_PRECISE_TSF
160 +               sc->sc_imask |= HAL_INT_RX;
161 +               ath_hal_intrset(ah, sc->sc_imask);
162 +               ATH_ENABLE_INTR();
163 +#endif
164 +       }
165 +
166 +       *budget -= processed;
167  
168         /* rx signal state monitoring */
169         ath_hal_rxmonitor(ah, &sc->sc_halstats, &sc->sc_curchan);
170 +       return early_stop;
171  #undef PA2DESC
172  }
173  
174 @@ -7635,11 +7682,22 @@
175         struct net_device *dev = (struct net_device *)data;
176         struct ath_softc *sc = dev->priv;
177  
178 +process_tx_again:
179         if (txqactive(sc->sc_ah, 0))
180                 ath_tx_processq(sc, &sc->sc_txq[0]);
181         if (txqactive(sc->sc_ah, sc->sc_cabq->axq_qnum))
182                 ath_tx_processq(sc, sc->sc_cabq);
183  
184 +       ATH_DISABLE_INTR();
185 +       if (sc->sc_isr & HAL_INT_TX) {
186 +               sc->sc_isr &= ~HAL_INT_TX;
187 +               ATH_ENABLE_INTR();
188 +               goto process_tx_again;
189 +       }
190 +       sc->sc_imask |= HAL_INT_TX;
191 +       ath_hal_intrset(sc->sc_ah, sc->sc_imask);
192 +       ATH_ENABLE_INTR();
193 +
194         netif_wake_queue(dev);
195  
196         if (sc->sc_softled)
197 @@ -7656,6 +7714,7 @@
198         struct net_device *dev = (struct net_device *)data;
199         struct ath_softc *sc = dev->priv;
200  
201 +process_tx_again:
202         /*
203          * Process each active queue.
204          */
205 @@ -7676,6 +7735,16 @@
206         if (sc->sc_uapsdq && txqactive(sc->sc_ah, sc->sc_uapsdq->axq_qnum))
207                 ath_tx_processq(sc, sc->sc_uapsdq);
208  
209 +       ATH_DISABLE_INTR();
210 +       if (sc->sc_isr & HAL_INT_TX) {
211 +               sc->sc_isr &= ~HAL_INT_TX;
212 +               ATH_ENABLE_INTR();
213 +               goto process_tx_again;
214 +       }
215 +       sc->sc_imask |= HAL_INT_TX;
216 +       ath_hal_intrset(sc->sc_ah, sc->sc_imask);
217 +       ATH_ENABLE_INTR();
218 +
219         netif_wake_queue(dev);
220  
221         if (sc->sc_softled)
222 @@ -7693,6 +7762,7 @@
223         unsigned int i;
224  
225         /* Process each active queue. */
226 +process_tx_again:
227         for (i = 0; i < HAL_NUM_TX_QUEUES; i++)
228                 if (ATH_TXQ_SETUP(sc, i) && txqactive(sc->sc_ah, i))
229                         ath_tx_processq(sc, &sc->sc_txq[i]);
230 @@ -7701,6 +7771,16 @@
231                 ath_tx_processq(sc, sc->sc_xrtxq);
232  #endif
233  
234 +       ATH_DISABLE_INTR();
235 +       if (sc->sc_isr & HAL_INT_TX) {
236 +               sc->sc_isr &= ~HAL_INT_TX;
237 +               ATH_ENABLE_INTR();
238 +               goto process_tx_again;
239 +       }
240 +       sc->sc_imask |= HAL_INT_TX;
241 +       ath_hal_intrset(sc->sc_ah, sc->sc_imask);
242 +       ATH_ENABLE_INTR();
243 +
244         netif_wake_queue(dev);
245  
246         if (sc->sc_softled)
247 @@ -7799,6 +7879,7 @@
248  ath_draintxq(struct ath_softc *sc)
249  {
250         struct ath_hal *ah = sc->sc_ah;
251 +       int npend = 0;
252         unsigned int i;
253  
254         /* XXX return value */
255 @@ -9343,9 +9424,9 @@
256         dev->mtu = mtu;
257         if ((dev->flags & IFF_RUNNING) && !sc->sc_invalid) {
258                 /* NB: the rx buffers may need to be reallocated */
259 -               tasklet_disable(&sc->sc_rxtq);
260 +               netif_poll_disable(dev);
261                 error = ath_reset(dev);
262 -               tasklet_enable(&sc->sc_rxtq);
263 +               netif_poll_enable(dev);
264         }
265         ATH_UNLOCK(sc);
266  
267 Index: madwifi-ng-r2834-20071106/ath/if_athvar.h
268 ===================================================================
269 --- madwifi-ng-r2834-20071106.orig/ath/if_athvar.h      2007-11-07 14:02:03.557573608 +0100
270 +++ madwifi-ng-r2834-20071106/ath/if_athvar.h   2007-11-07 14:02:04.865648150 +0100
271 @@ -50,6 +50,10 @@
272  #include <asm/io.h>
273  #include <linux/list.h>
274  
275 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
276 +#define irqs_disabled()                        0
277 +#endif
278 +
279  /*
280   * Deduce if tasklets are available.  If not then
281   * fall back to using the immediate work queue.
282 @@ -642,7 +646,6 @@
283         struct ath_buf *sc_rxbufcur;            /* current rx buffer */
284         u_int32_t *sc_rxlink;                   /* link ptr in last RX desc */
285         spinlock_t sc_rxbuflock;
286 -       struct ATH_TQ_STRUCT sc_rxtq;           /* rx intr tasklet */
287         struct ATH_TQ_STRUCT sc_rxorntq;        /* rxorn intr tasklet */
288         u_int8_t sc_defant;                     /* current default antenna */
289         u_int8_t sc_rxotherant;                 /* RXs on non-default antenna */
290 @@ -655,6 +658,7 @@
291         u_int sc_txintrperiod;                  /* tx interrupt batching */
292         struct ath_txq sc_txq[HAL_NUM_TX_QUEUES];
293         struct ath_txq *sc_ac2q[WME_NUM_AC];    /* WME AC -> h/w qnum */
294 +       HAL_INT sc_isr;                         /* unmasked ISR state */
295         struct ATH_TQ_STRUCT sc_txtq;           /* tx intr tasklet */
296         u_int8_t sc_grppoll_str[GRPPOLL_RATE_STR_LEN];
297         struct ath_descdma sc_bdma;             /* beacon descriptors */
298 @@ -727,6 +731,8 @@
299  #define        ATH_TXBUF_LOCK_ASSERT(_sc) \
300         KASSERT(spin_is_locked(&(_sc)->sc_txbuflock), ("txbuf not locked!"))
301  
302 +#define ATH_DISABLE_INTR               local_irq_disable
303 +#define ATH_ENABLE_INTR                local_irq_enable
304  
305  #define        ATH_RXBUF_LOCK_INIT(_sc)        spin_lock_init(&(_sc)->sc_rxbuflock)
306  #define        ATH_RXBUF_LOCK_DESTROY(_sc)
307 Index: madwifi-ng-r2834-20071106/net80211/ieee80211_input.c
308 ===================================================================
309 --- madwifi-ng-r2834-20071106.orig/net80211/ieee80211_input.c   2007-11-07 14:02:02.873534629 +0100
310 +++ madwifi-ng-r2834-20071106/net80211/ieee80211_input.c        2007-11-07 14:02:04.873648608 +0100
311 @@ -1128,8 +1128,9 @@
312                 if (ni->ni_vlan != 0 && vap->iv_vlgrp != NULL) {
313                         /* attach vlan tag */
314                         vlan_hwaccel_receive_skb(skb, vap->iv_vlgrp, ni->ni_vlan);
315 -               } else
316 -                       netif_rx(skb);
317 +               } else {
318 +                       netif_receive_skb(skb);
319 +               }
320                 dev->last_rx = jiffies;
321         }
322  }