refresh all package patches in the buildroot using quilt
[openwrt.git] / package / madwifi / patches / 300-napi_polling.patch
1 Index: madwifi-ng-r2420-20070602/ath/if_ath.c
2 ===================================================================
3 --- madwifi-ng-r2420-20070602.orig/ath/if_ath.c 2007-06-04 13:21:58.130139544 +0200
4 +++ madwifi-ng-r2420-20070602/ath/if_ath.c      2007-06-04 13:21:58.427094400 +0200
5 @@ -167,7 +167,7 @@
6         int, u_int32_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 @@ -442,7 +442,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 @@ -1664,6 +1665,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 @@ -1699,7 +1701,12 @@
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 +                               sc->sc_imask &= ~HAL_INT_RX;
47 +                               ath_hal_intrset(ah, sc->sc_imask);
48 +                               __netif_rx_schedule(dev);
49 +                       }
50                 }
51                 if (status & HAL_INT_TX) {
52  #ifdef ATH_SUPERG_DYNTURBO
53 @@ -1725,6 +1732,11 @@
54                                 }
55                         }
56  #endif
57 +                       /* disable transmit interrupt */
58 +                       sc->sc_isr &= ~HAL_INT_TX;
59 +                       ath_hal_intrset(ah, sc->sc_imask & ~HAL_INT_TX);
60 +                       sc->sc_imask &= ~HAL_INT_TX;
61 +
62                         ATH_SCHEDULE_TQUEUE(&sc->sc_txtq, &needmark);
63                 }
64                 if (status & HAL_INT_BMISS) {
65 @@ -3295,10 +3307,10 @@
66          *
67          * XXX Using in_softirq is not right since we might
68          * be called from other soft irq contexts than
69 -        * ath_rx_tasklet.
70 +        * ath_rx_poll
71          */
72         if (!in_softirq())
73 -               tasklet_disable(&sc->sc_rxtq);
74 +               netif_poll_disable(dev);
75         netif_stop_queue(dev);
76  }
77  
78 @@ -3311,7 +3323,7 @@
79         DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s:\n", __func__);
80         netif_start_queue(dev);
81         if (!in_softirq())              /* NB: see above */
82 -               tasklet_enable(&sc->sc_rxtq);
83 +               netif_poll_enable(dev);
84  }
85  
86  /*
87 @@ -5569,13 +5581,12 @@
88         sc->sc_rxotherant = 0;
89  }
90  
91 -static void
92 -ath_rx_tasklet(TQUEUE_ARG data)
93 +static int
94 +ath_rx_poll(struct net_device *dev, int *budget)
95  {
96  #define        PA2DESC(_sc, _pa) \
97         ((struct ath_desc *)((caddr_t)(_sc)->sc_rxdma.dd_desc + \
98                 ((_pa) - (_sc)->sc_rxdma.dd_desc_paddr)))
99 -       struct net_device *dev = (struct net_device *)data;
100         struct ath_buf *bf;
101         struct ath_softc *sc = dev->priv;
102         struct ieee80211com *ic = &sc->sc_ic;
103 @@ -5587,12 +5598,15 @@
104         unsigned int len;
105         int type;
106         u_int phyerr;
107 +       u_int processed = 0, early_stop = 0;
108 +       u_int rx_limit = dev->quota;
109  
110         /* Let the 802.11 layer know about the new noise floor */
111         sc->sc_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan));
112         ic->ic_channoise = sc->sc_channoise;
113  
114         DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s\n", __func__);
115 +process_rx_again:
116         do {
117                 bf = STAILQ_FIRST(&sc->sc_rxbuf);
118                 if (bf == NULL) {               /* XXX ??? can this happen */
119 @@ -5616,6 +5630,13 @@
120                         /* NB: never process the self-linked entry at the end */
121                         break;
122                 }
123 +
124 +               processed++;
125 +               if (rx_limit-- < 0) {
126 +                       early_stop = 1;
127 +                       break;
128 +               }
129 +
130                 skb = bf->bf_skb;
131                 if (skb == NULL) {              /* XXX ??? can this happen */
132                         printk("%s: no skbuff (%s)\n", DEV_NAME(dev), __func__);
133 @@ -5654,6 +5675,7 @@
134                                 sc->sc_stats.ast_rx_phyerr++;
135                                 phyerr = rs->rs_phyerr & 0x1f;
136                                 sc->sc_stats.ast_rx_phy[phyerr]++;
137 +                               goto rx_next;
138                         }
139                         if (rs->rs_status & HAL_RXERR_DECRYPT) {
140                                 /*
141 @@ -5865,9 +5887,29 @@
142                 STAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list);
143                 ATH_RXBUF_UNLOCK_IRQ(sc);
144         } while (ath_rxbuf_init(sc, bf) == 0);
145 +       if (!early_stop) {
146 +               /* Check if more data is received while we were
147 +                * processing the descriptor chain.
148 +                */
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 +               netif_rx_complete(dev);
157 +
158 +               sc->sc_imask |= HAL_INT_RX;
159 +               ath_hal_intrset(ah, sc->sc_imask);
160 +               ATH_ENABLE_INTR();
161 +       }
162 +
163 +       *budget -= processed;
164  
165         /* rx signal state monitoring */
166         ath_hal_rxmonitor(ah, &sc->sc_halstats, &sc->sc_curchan);
167 +       return early_stop;
168  #undef PA2DESC
169  }
170  
171 @@ -7484,11 +7526,22 @@
172         struct net_device *dev = (struct net_device *)data;
173         struct ath_softc *sc = dev->priv;
174  
175 +process_tx_again:
176         if (txqactive(sc->sc_ah, 0))
177                 ath_tx_processq(sc, &sc->sc_txq[0]);
178         if (txqactive(sc->sc_ah, sc->sc_cabq->axq_qnum))
179                 ath_tx_processq(sc, sc->sc_cabq);
180  
181 +       ATH_DISABLE_INTR();
182 +       if (sc->sc_isr & HAL_INT_TX) {
183 +               sc->sc_isr &= ~HAL_INT_TX;
184 +               ATH_ENABLE_INTR();
185 +               goto process_tx_again;
186 +       }
187 +       sc->sc_imask |= HAL_INT_TX;
188 +       ath_hal_intrset(sc->sc_ah, sc->sc_imask);
189 +       ATH_ENABLE_INTR();
190 +
191         netif_wake_queue(dev);
192  
193         if (sc->sc_softled)
194 @@ -7505,6 +7558,7 @@
195         struct net_device *dev = (struct net_device *)data;
196         struct ath_softc *sc = dev->priv;
197  
198 +process_tx_again:
199         /*
200          * Process each active queue.
201          */
202 @@ -7525,6 +7579,16 @@
203         if (sc->sc_uapsdq && txqactive(sc->sc_ah, sc->sc_uapsdq->axq_qnum))
204                 ath_tx_processq(sc, sc->sc_uapsdq);
205  
206 +       ATH_DISABLE_INTR();
207 +       if (sc->sc_isr & HAL_INT_TX) {
208 +               sc->sc_isr &= ~HAL_INT_TX;
209 +               ATH_ENABLE_INTR();
210 +               goto process_tx_again;
211 +       }
212 +       sc->sc_imask |= HAL_INT_TX;
213 +       ath_hal_intrset(sc->sc_ah, sc->sc_imask);
214 +       ATH_ENABLE_INTR();
215 +
216         netif_wake_queue(dev);
217  
218         if (sc->sc_softled)
219 @@ -7542,6 +7606,7 @@
220         unsigned int i;
221  
222         /* Process each active queue. */
223 +process_tx_again:
224         for (i = 0; i < HAL_NUM_TX_QUEUES; i++)
225                 if (ATH_TXQ_SETUP(sc, i) && txqactive(sc->sc_ah, i))
226                         ath_tx_processq(sc, &sc->sc_txq[i]);
227 @@ -7550,6 +7615,16 @@
228                 ath_tx_processq(sc, sc->sc_xrtxq);
229  #endif
230  
231 +       ATH_DISABLE_INTR();
232 +       if (sc->sc_isr & HAL_INT_TX) {
233 +               sc->sc_isr &= ~HAL_INT_TX;
234 +               ATH_ENABLE_INTR();
235 +               goto process_tx_again;
236 +       }
237 +       sc->sc_imask |= HAL_INT_TX;
238 +       ath_hal_intrset(sc->sc_ah, sc->sc_imask);
239 +       ATH_ENABLE_INTR();
240 +
241         netif_wake_queue(dev);
242  
243         if (sc->sc_softled)
244 @@ -7648,6 +7723,7 @@
245  ath_draintxq(struct ath_softc *sc)
246  {
247         struct ath_hal *ah = sc->sc_ah;
248 +       int npend = 0;
249         unsigned int i;
250  
251         /* XXX return value */
252 @@ -9167,9 +9243,9 @@
253         dev->mtu = mtu;
254         if ((dev->flags & IFF_RUNNING) && !sc->sc_invalid) {
255                 /* NB: the rx buffers may need to be reallocated */
256 -               tasklet_disable(&sc->sc_rxtq);
257 +               netif_poll_disable(dev);
258                 error = ath_reset(dev);
259 -               tasklet_enable(&sc->sc_rxtq);
260 +               netif_poll_enable(dev);
261         }
262         ATH_UNLOCK(sc);
263  
264 Index: madwifi-ng-r2420-20070602/ath/if_athvar.h
265 ===================================================================
266 --- madwifi-ng-r2420-20070602.orig/ath/if_athvar.h      2007-06-04 13:21:57.500235304 +0200
267 +++ madwifi-ng-r2420-20070602/ath/if_athvar.h   2007-06-04 13:21:58.428094248 +0200
268 @@ -48,6 +48,10 @@
269  #include "if_athioctl.h"
270  #include "net80211/ieee80211.h"                /* XXX for WME_NUM_AC */
271  
272 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
273 +#define irqs_disabled()                        0
274 +#endif
275 +
276  /*
277   * Deduce if tasklets are available.  If not then
278   * fall back to using the immediate work queue.
279 @@ -621,7 +625,6 @@
280         struct ath_buf *sc_rxbufcur;            /* current rx buffer */
281         u_int32_t *sc_rxlink;                   /* link ptr in last RX desc */
282         spinlock_t sc_rxbuflock;
283 -       struct ATH_TQ_STRUCT sc_rxtq;           /* rx intr tasklet */
284         struct ATH_TQ_STRUCT sc_rxorntq;        /* rxorn intr tasklet */
285         u_int8_t sc_defant;                     /* current default antenna */
286         u_int8_t sc_rxotherant;                 /* rx's on non-default antenna*/
287 @@ -634,6 +637,7 @@
288         u_int sc_txintrperiod;                  /* tx interrupt batching */
289         struct ath_txq sc_txq[HAL_NUM_TX_QUEUES];
290         struct ath_txq *sc_ac2q[WME_NUM_AC];    /* WME AC -> h/w qnum */
291 +       HAL_INT sc_isr;                         /* unmasked ISR state */
292         struct ATH_TQ_STRUCT sc_txtq;           /* tx intr tasklet */
293         u_int8_t sc_grppoll_str[GRPPOLL_RATE_STR_LEN];
294         struct ath_descdma sc_bdma;             /* beacon descriptors */
295 @@ -714,6 +718,8 @@
296  #define        ATH_TXBUF_LOCK_ASSERT(_sc) \
297         KASSERT(spin_is_locked(&(_sc)->sc_txbuflock), ("txbuf not locked!"))
298  
299 +#define ATH_DISABLE_INTR               local_irq_disable
300 +#define ATH_ENABLE_INTR                local_irq_enable
301  
302  #define        ATH_RXBUF_LOCK_INIT(_sc)        spin_lock_init(&(_sc)->sc_rxbuflock)
303  #define        ATH_RXBUF_LOCK_DESTROY(_sc)
304 Index: madwifi-ng-r2420-20070602/net80211/ieee80211_input.c
305 ===================================================================
306 --- madwifi-ng-r2420-20070602.orig/net80211/ieee80211_input.c   2007-06-04 13:21:57.502235000 +0200
307 +++ madwifi-ng-r2420-20070602/net80211/ieee80211_input.c        2007-06-04 13:21:58.461089232 +0200
308 @@ -1128,8 +1128,9 @@
309                 if (ni->ni_vlan != 0 && vap->iv_vlgrp != NULL) {
310                         /* attach vlan tag */
311                         vlan_hwaccel_receive_skb(skb, vap->iv_vlgrp, ni->ni_vlan);
312 -               } else
313 -                       netif_rx(skb);
314 +               } else {
315 +                       netif_receive_skb(skb);
316 +               }
317                 dev->last_rx = jiffies;
318         }
319  }