25d02653a764ac70ef57cf54d90bb69be954b17e
[openwrt/staging/florian.git] / package / madwifi / patches-r3776 / 300-napi_polling.patch
1 Index: madwifi-trunk-r3776/ath/if_ath.c
2 ===================================================================
3 --- madwifi-trunk-r3776.orig/ath/if_ath.c 2008-07-18 20:35:03.000000000 +0200
4 +++ madwifi-trunk-r3776/ath/if_ath.c 2008-07-18 20:37:47.000000000 +0200
5 @@ -182,7 +182,11 @@
6 struct sk_buff *, int, 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 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
11 +static int ath_rx_poll(struct napi_struct *napi, int budget);
12 +#else
13 +static int ath_rx_poll(struct net_device *dev, int *budget);
14 +#endif
15 static int ath_hardstart(struct sk_buff *, struct net_device *);
16 static int ath_mgtstart(struct ieee80211com *, struct sk_buff *);
17 #ifdef ATH_SUPERG_COMP
18 @@ -331,6 +335,9 @@
19 static u_int32_t ath_set_clamped_maxtxpower(struct ath_softc *sc,
20 u_int32_t new_clamped_maxtxpower);
21
22 +static void ath_poll_disable(struct net_device *dev);
23 +static void ath_poll_enable(struct net_device *dev);
24 +
25 static void ath_scanbufs(struct ath_softc *sc);
26 static int ath_debug_iwpriv(struct ieee80211com *ic,
27 unsigned int param, unsigned int value);
28 @@ -518,7 +525,6 @@
29
30 atomic_set(&sc->sc_txbuf_counter, 0);
31
32 - ATH_INIT_TQUEUE(&sc->sc_rxtq, ath_rx_tasklet, dev);
33 ATH_INIT_TQUEUE(&sc->sc_txtq, ath_tx_tasklet, dev);
34 ATH_INIT_TQUEUE(&sc->sc_bmisstq, ath_bmiss_tasklet, dev);
35 ATH_INIT_TQUEUE(&sc->sc_bstucktq, ath_bstuck_tasklet, dev);
36 @@ -833,6 +839,12 @@
37 dev->set_mac_address = ath_set_mac_address;
38 dev->change_mtu = ath_change_mtu;
39 dev->tx_queue_len = ATH_TXBUF - ATH_TXBUF_MGT_RESERVED;
40 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
41 + netif_napi_add(dev, &sc->sc_napi, ath_rx_poll, 64);
42 +#else
43 + dev->poll = ath_rx_poll;
44 + dev->weight = 64;
45 +#endif
46 #ifdef USE_HEADERLEN_RESV
47 dev->hard_header_len += sizeof(struct ieee80211_qosframe) +
48 sizeof(struct llc) +
49 @@ -1770,7 +1782,7 @@
50 }
51
52 static void
53 -ath_intr_process_rx_descriptors(struct ath_softc *sc, int *pneedmark, u_int64_t hw_tsf)
54 +ath_intr_process_rx_descriptors(struct ath_softc *sc, int *pneedmark, u_int64_t hw_tsf, int schedule)
55 {
56 struct ath_hal *ah = sc->sc_ah;
57 struct ath_desc *ds;
58 @@ -2252,8 +2264,25 @@
59 }
60
61 /* If we got something to process, schedule rx queue to handle it */
62 - if (count)
63 - ATH_SCHEDULE_TQUEUE(&sc->sc_rxtq, pneedmark);
64 + if (count) {
65 + sc->sc_isr &= ~HAL_INT_RX;
66 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
67 + if (netif_rx_schedule_prep(sc->sc_dev, &sc->sc_napi))
68 +#else
69 + if (netif_rx_schedule_prep(sc->sc_dev))
70 +#endif
71 + {
72 +#ifndef ATH_PRECISE_TSF
73 + sc->sc_imask &= ~HAL_INT_RX;
74 + ath_hal_intrset(ah, sc->sc_imask);
75 +#endif
76 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
77 + __netif_rx_schedule(sc->sc_dev, &sc->sc_napi);
78 +#else
79 + __netif_rx_schedule(sc->sc_dev);
80 +#endif
81 + }
82 + }
83 ATH_RXBUF_UNLOCK_IRQ(sc);
84 #undef PA2DESC
85 }
86 @@ -2343,6 +2372,7 @@
87 (status & HAL_INT_GLOBAL) ? " HAL_INT_GLOBAL" : ""
88 );
89
90 + sc->sc_isr = status;
91 status &= sc->sc_imask; /* discard unasked for bits */
92 /* As soon as we know we have a real interrupt we intend to service,
93 * we will check to see if we need an initial hardware TSF reading.
94 @@ -2400,7 +2430,7 @@
95 }
96 if (status & (HAL_INT_RX | HAL_INT_RXPHY)) {
97 /* NB: Will schedule rx tasklet if necessary. */
98 - ath_intr_process_rx_descriptors(sc, &needmark, hw_tsf);
99 + ath_intr_process_rx_descriptors(sc, &needmark, hw_tsf, 1);
100 }
101 if (status & HAL_INT_TX) {
102 #ifdef ATH_SUPERG_DYNTURBO
103 @@ -2426,6 +2456,11 @@
104 }
105 }
106 #endif
107 + /* disable transmit interrupt */
108 + sc->sc_isr &= ~HAL_INT_TX;
109 + ath_hal_intrset(ah, sc->sc_imask & ~HAL_INT_TX);
110 + sc->sc_imask &= ~HAL_INT_TX;
111 +
112 ATH_SCHEDULE_TQUEUE(&sc->sc_txtq, &needmark);
113 }
114 if (status & HAL_INT_BMISS) {
115 @@ -2617,6 +2652,7 @@
116 if (sc->sc_tx99 != NULL)
117 sc->sc_tx99->start(sc->sc_tx99);
118 #endif
119 + ath_poll_enable(dev);
120
121 done:
122 ATH_UNLOCK(sc);
123 @@ -2657,6 +2693,9 @@
124 if (sc->sc_tx99 != NULL)
125 sc->sc_tx99->stop(sc->sc_tx99);
126 #endif
127 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
128 + ath_poll_disable(dev);
129 +#endif
130 netif_stop_queue(dev); /* XXX re-enabled by ath_newstate */
131 dev->flags &= ~IFF_RUNNING; /* NB: avoid recursion */
132 ieee80211_stop_running(ic); /* stop all VAPs */
133 @@ -4109,6 +4148,43 @@
134 return ath_keyset(sc, k, mac, vap->iv_bss);
135 }
136
137 +static void ath_poll_disable(struct net_device *dev)
138 +{
139 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
140 + struct ath_softc *sc = dev->priv;
141 +#endif
142 +
143 + /*
144 + * XXX Using in_softirq is not right since we might
145 + * be called from other soft irq contexts than
146 + * ath_rx_poll
147 + */
148 + if (!in_softirq()) {
149 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
150 + napi_disable(&sc->sc_napi);
151 +#else
152 + netif_poll_disable(dev);
153 +#endif
154 + }
155 +}
156 +
157 +static void ath_poll_enable(struct net_device *dev)
158 +{
159 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
160 + struct ath_softc *sc = dev->priv;
161 +#endif
162 +
163 + /* NB: see above */
164 + if (!in_softirq()) {
165 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
166 + napi_enable(&sc->sc_napi);
167 +#else
168 + netif_poll_enable(dev);
169 +#endif
170 + }
171 +}
172 +
173 +
174 /*
175 * Block/unblock tx+rx processing while a key change is done.
176 * We assume the caller serializes key management operations
177 @@ -4119,33 +4195,26 @@
178 ath_key_update_begin(struct ieee80211vap *vap)
179 {
180 struct net_device *dev = vap->iv_ic->ic_dev;
181 - struct ath_softc *sc = dev->priv;
182
183 DPRINTF(sc, ATH_DEBUG_KEYCACHE, "Begin\n");
184 /*
185 * When called from the rx tasklet we cannot use
186 * tasklet_disable because it will block waiting
187 * for us to complete execution.
188 - *
189 - * XXX Using in_softirq is not right since we might
190 - * be called from other soft irq contexts than
191 - * ath_rx_tasklet.
192 */
193 - if (!in_softirq())
194 - tasklet_disable(&sc->sc_rxtq);
195 - netif_stop_queue(dev);
196 + if ((dev->flags & (IFF_UP|IFF_RUNNING)) == (IFF_UP|IFF_RUNNING))
197 + netif_stop_queue(dev);
198 }
199
200 static void
201 ath_key_update_end(struct ieee80211vap *vap)
202 {
203 struct net_device *dev = vap->iv_ic->ic_dev;
204 - struct ath_softc *sc = dev->priv;
205
206 DPRINTF(sc, ATH_DEBUG_KEYCACHE, "End\n");
207 - netif_wake_queue(dev);
208 - if (!in_softirq()) /* NB: see above */
209 - tasklet_enable(&sc->sc_rxtq);
210 +
211 + if ((dev->flags & (IFF_UP|IFF_RUNNING)) == (IFF_UP|IFF_RUNNING))
212 + netif_wake_queue(dev);
213 }
214
215 /*
216 @@ -6405,15 +6474,25 @@
217 sc->sc_numrxotherant = 0;
218 }
219
220 -static void
221 -ath_rx_tasklet(TQUEUE_ARG data)
222 +static int
223 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
224 +ath_rx_poll(struct napi_struct *napi, int budget)
225 +#else
226 +ath_rx_poll(struct net_device *dev, int *budget)
227 +#endif
228 {
229 #define PA2DESC(_sc, _pa) \
230 ((struct ath_desc *)((caddr_t)(_sc)->sc_rxdma.dd_desc + \
231 ((_pa) - (_sc)->sc_rxdma.dd_desc_paddr)))
232 - struct net_device *dev = (struct net_device *)data;
233 - struct ath_buf *bf;
234 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
235 + struct ath_softc *sc = container_of(napi, struct ath_softc, sc_napi);
236 + struct net_device *dev = sc->sc_dev;
237 + u_int rx_limit = budget;
238 +#else
239 struct ath_softc *sc = dev->priv;
240 + u_int rx_limit = min(dev->quota, *budget);
241 +#endif
242 + struct ath_buf *bf;
243 struct ieee80211com *ic = &sc->sc_ic;
244 struct ath_hal *ah = sc ? sc->sc_ah : NULL;
245 struct ath_desc *ds;
246 @@ -6421,6 +6500,7 @@
247 struct ieee80211_node *ni;
248 struct sk_buff *skb = NULL;
249 unsigned int len, phyerr, mic_fail = 0;
250 + unsigned int early_stop = 0;
251 int type = -1; /* undefined */
252 int init_ret = 0;
253 int bf_processed = 0;
254 @@ -6428,6 +6508,7 @@
255 int errors = 0;
256
257 DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s started...\n", __func__);
258 +process_rx_again:
259 do {
260 /* Get next RX buffer pending processing by RX tasklet...
261 *
262 @@ -6457,6 +6538,10 @@
263 break;
264
265 bf_processed++;
266 + if (rx_limit-- < 0) {
267 + early_stop = 1;
268 + break;
269 + }
270 ds = bf->bf_desc;
271
272 #ifdef AR_DEBUG
273 @@ -6491,6 +6576,7 @@
274 sc->sc_stats.ast_rx_phyerr++;
275 phyerr = rs->rs_phyerr & 0x1f;
276 sc->sc_stats.ast_rx_phy[phyerr]++;
277 + goto rx_next;
278 }
279 if (rs->rs_status & HAL_RXERR_DECRYPT) {
280 /* Decrypt error. If the error occurred
281 @@ -6689,6 +6775,33 @@
282 STAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list);
283 ATH_RXBUF_UNLOCK_IRQ(sc);
284 } while (1);
285 + if (!early_stop) {
286 + unsigned long flags;
287 + /* Check if more data is received while we were
288 + * processing the descriptor chain.
289 + */
290 +#ifndef ATH_PRECISE_TSF
291 + local_irq_save(flags);
292 + if (sc->sc_isr & HAL_INT_RX) {
293 + u_int64_t hw_tsf = ath_hal_gettsf64(ah);
294 + sc->sc_isr &= ~HAL_INT_RX;
295 + local_irq_restore(flags);
296 + ath_intr_process_rx_descriptors(sc, NULL, hw_tsf, 0);
297 + goto process_rx_again;
298 + }
299 + sc->sc_imask |= HAL_INT_RX;
300 + ath_hal_intrset(ah, sc->sc_imask);
301 + local_irq_restore(flags);
302 +#endif
303 + }
304 +
305 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
306 + netif_rx_complete(dev, napi);
307 +#else
308 + netif_rx_complete(dev);
309 + *budget -= bf_processed;
310 + dev->quota -= bf_processed;
311 +#endif
312
313 if (sc->sc_useintmit)
314 ath_hal_rxmonitor(ah, &sc->sc_halstats, &sc->sc_curchan);
315 @@ -6701,6 +6814,12 @@
316 " %d rx buf processed. %d were errors. %d skb accepted.\n",
317 __func__, bf_processed, errors, skb_accepted);
318 #undef PA2DESC
319 +
320 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
321 + return bf_processed;
322 +#else
323 + return early_stop;
324 +#endif
325 }
326
327 #ifdef ATH_SUPERG_XR
328 @@ -8306,12 +8425,24 @@
329 {
330 struct net_device *dev = (struct net_device *)data;
331 struct ath_softc *sc = dev->priv;
332 + unsigned long flags;
333
334 +process_tx_again:
335 if (txqactive(sc->sc_ah, 0))
336 ath_tx_processq(sc, &sc->sc_txq[0]);
337 if (txqactive(sc->sc_ah, sc->sc_cabq->axq_qnum))
338 ath_tx_processq(sc, sc->sc_cabq);
339
340 + local_irq_save(flags);
341 + if (sc->sc_isr & HAL_INT_TX) {
342 + sc->sc_isr &= ~HAL_INT_TX;
343 + local_irq_restore(flags);
344 + goto process_tx_again;
345 + }
346 + sc->sc_imask |= HAL_INT_TX;
347 + ath_hal_intrset(sc->sc_ah, sc->sc_imask);
348 + local_irq_restore(flags);
349 +
350 netif_wake_queue(dev);
351
352 if (sc->sc_softled)
353 @@ -8327,7 +8458,9 @@
354 {
355 struct net_device *dev = (struct net_device *)data;
356 struct ath_softc *sc = dev->priv;
357 + unsigned long flags;
358
359 +process_tx_again:
360 /*
361 * Process each active queue.
362 */
363 @@ -8357,6 +8490,16 @@
364 if (sc->sc_uapsdq && txqactive(sc->sc_ah, sc->sc_uapsdq->axq_qnum))
365 ath_tx_processq(sc, sc->sc_uapsdq);
366
367 + local_irq_save(flags);
368 + if (sc->sc_isr & HAL_INT_TX) {
369 + sc->sc_isr &= ~HAL_INT_TX;
370 + local_irq_restore(flags);
371 + goto process_tx_again;
372 + }
373 + sc->sc_imask |= HAL_INT_TX;
374 + ath_hal_intrset(sc->sc_ah, sc->sc_imask);
375 + local_irq_restore(flags);
376 +
377 netif_wake_queue(dev);
378
379 if (sc->sc_softled)
380 @@ -10322,9 +10465,9 @@
381 dev->mtu = mtu;
382 if ((dev->flags & IFF_RUNNING) && !sc->sc_invalid) {
383 /* NB: the rx buffers may need to be reallocated */
384 - tasklet_disable(&sc->sc_rxtq);
385 + ath_poll_disable(dev);
386 error = ath_reset(dev);
387 - tasklet_enable(&sc->sc_rxtq);
388 + ath_poll_enable(dev);
389 }
390 ATH_UNLOCK(sc);
391
392 Index: madwifi-trunk-r3776/ath/if_athvar.h
393 ===================================================================
394 --- madwifi-trunk-r3776.orig/ath/if_athvar.h 2008-07-18 20:35:03.000000000 +0200
395 +++ madwifi-trunk-r3776/ath/if_athvar.h 2008-07-18 20:37:09.000000000 +0200
396 @@ -56,6 +56,10 @@
397 # include <asm/bitops.h>
398 #endif
399
400 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
401 +#define irqs_disabled() 0
402 +#endif
403 +
404 /*
405 * Deduce if tasklets are available. If not then
406 * fall back to using the immediate work queue.
407 @@ -644,6 +648,9 @@
408 struct ath_softc {
409 struct ieee80211com sc_ic; /* NB: must be first */
410 struct net_device *sc_dev;
411 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
412 + struct napi_struct sc_napi;
413 +#endif
414 void __iomem *sc_iobase; /* address of the device */
415 struct semaphore sc_lock; /* dev-level lock */
416 struct net_device_stats sc_devstats; /* device statistics */
417 @@ -756,7 +763,6 @@
418 struct ath_buf *sc_rxbufcur; /* current rx buffer */
419 u_int32_t *sc_rxlink; /* link ptr in last RX desc */
420 spinlock_t sc_rxbuflock;
421 - struct ATH_TQ_STRUCT sc_rxtq; /* rx intr tasklet */
422 struct ATH_TQ_STRUCT sc_rxorntq; /* rxorn intr tasklet */
423 u_int16_t sc_cachelsz; /* cache line size */
424
425 @@ -769,6 +775,7 @@
426 u_int sc_txintrperiod; /* tx interrupt batching */
427 struct ath_txq sc_txq[HAL_NUM_TX_QUEUES];
428 struct ath_txq *sc_ac2q[WME_NUM_AC]; /* WME AC -> h/w qnum */
429 + HAL_INT sc_isr; /* unmasked ISR state */
430 struct ATH_TQ_STRUCT sc_txtq; /* tx intr tasklet */
431 u_int8_t sc_grppoll_str[GRPPOLL_RATE_STR_LEN];
432 struct ath_descdma sc_bdma; /* beacon descriptors */
433 @@ -888,6 +895,8 @@
434 #define ATH_TXBUF_LOCK_CHECK(_sc)
435 #endif
436
437 +#define ATH_DISABLE_INTR local_irq_disable
438 +#define ATH_ENABLE_INTR local_irq_enable
439
440 #define ATH_RXBUF_LOCK_INIT(_sc) spin_lock_init(&(_sc)->sc_rxbuflock)
441 #define ATH_RXBUF_LOCK_DESTROY(_sc)
442 Index: madwifi-trunk-r3776/net80211/ieee80211_skb.c
443 ===================================================================
444 --- madwifi-trunk-r3776.orig/net80211/ieee80211_skb.c 2008-07-18 20:32:42.000000000 +0200
445 +++ madwifi-trunk-r3776/net80211/ieee80211_skb.c 2008-07-18 20:35:03.000000000 +0200
446 @@ -73,7 +73,7 @@
447 #undef dev_queue_xmit
448 #undef kfree_skb
449 #undef kfree_skb_fast
450 -#undef netif_rx
451 +#undef netif_receive_skb
452 #undef pskb_copy
453 #undef skb_clone
454 #undef skb_copy
455 @@ -581,8 +581,8 @@
456 grp, vlan_tag);
457 }
458
459 -int netif_rx_debug(struct sk_buff *skb, const char *func, int line) {
460 - return netif_rx(untrack_skb(skb, 0, __func__, __LINE__));
461 +int netif_receive_skb_debug(struct sk_buff *skb, const char *func, int line) {
462 + return netif_receive_skb(untrack_skb(skb, 0, __func__, __LINE__));
463 }
464
465 struct sk_buff *alloc_skb_debug(unsigned int length, gfp_t gfp_mask,
466 @@ -707,7 +707,7 @@
467 }
468
469 EXPORT_SYMBOL(vlan_hwaccel_rx_debug);
470 -EXPORT_SYMBOL(netif_rx_debug);
471 +EXPORT_SYMBOL(netif_receive_skb_debug);
472 EXPORT_SYMBOL(alloc_skb_debug);
473 EXPORT_SYMBOL(dev_alloc_skb_debug);
474 EXPORT_SYMBOL(skb_clone_debug);
475 Index: madwifi-trunk-r3776/net80211/ieee80211_skb.h
476 ===================================================================
477 --- madwifi-trunk-r3776.orig/net80211/ieee80211_skb.h 2008-07-18 20:32:42.000000000 +0200
478 +++ madwifi-trunk-r3776/net80211/ieee80211_skb.h 2008-07-18 20:35:03.000000000 +0200
479 @@ -115,7 +115,7 @@
480
481 int vlan_hwaccel_rx_debug(struct sk_buff *skb, struct vlan_group *grp,
482 unsigned short vlan_tag, const char *func, int line);
483 -int netif_rx_debug(struct sk_buff *skb, const char *func, int line);
484 +int netif_receive_skb_debug(struct sk_buff *skb, const char *func, int line);
485 struct sk_buff *alloc_skb_debug(unsigned int length, gfp_t gfp_mask,
486 const char *func, int line);
487 struct sk_buff *dev_alloc_skb_debug(unsigned int length,
488 @@ -150,7 +150,7 @@
489 #undef dev_queue_xmit
490 #undef kfree_skb
491 #undef kfree_skb_fast
492 -#undef netif_rx
493 +#undef netif_receive_skb
494 #undef pskb_copy
495 #undef skb_clone
496 #undef skb_copy
497 @@ -167,8 +167,8 @@
498 skb_copy_expand_debug(_skb, _newheadroom, _newtailroom, _gfp_mask, __func__, __LINE__)
499 #define vlan_hwaccel_rx(_skb, _grp, _tag) \
500 vlan_hwaccel_rx_debug(_skb, _grp, _tag, __func__, __LINE__)
501 -#define netif_rx(_skb) \
502 - netif_rx_debug(_skb, __func__, __LINE__)
503 +#define netif_receive_skb(_skb) \
504 + netif_receive_skb_debug(_skb, __func__, __LINE__)
505 #define alloc_skb(_length, _gfp_mask) \
506 alloc_skb_debug(_length, _gfp_mask, __func__, __LINE__)
507 #define dev_alloc_skb(_length) \
508 Index: madwifi-trunk-r3776/net80211/ieee80211_input.c
509 ===================================================================
510 --- madwifi-trunk-r3776.orig/net80211/ieee80211_input.c 2008-07-18 20:32:42.000000000 +0200
511 +++ madwifi-trunk-r3776/net80211/ieee80211_input.c 2008-07-18 20:37:09.000000000 +0200
512 @@ -1185,7 +1185,7 @@
513 ret = vlan_hwaccel_rx(skb,
514 vap->iv_vlgrp, ni->ni_vlan);
515 else
516 - ret = netif_rx(skb);
517 + ret = netif_receive_skb(skb);
518 if (ret == NET_RX_DROP)
519 vap->iv_devstats.rx_dropped++;
520 if (tni != NULL)
521 @@ -2285,7 +2285,7 @@
522
523 if (SKB_NI(skb1) != NULL)
524 ieee80211_unref_node(&SKB_NI(skb1));
525 - if (netif_rx(skb1) == NET_RX_DROP)
526 + if (netif_receive_skb(skb1) == NET_RX_DROP)
527 vap->iv_devstats.rx_dropped++;
528 }
529 }
530 Index: madwifi-trunk-r3776/net80211/ieee80211_monitor.c
531 ===================================================================
532 --- madwifi-trunk-r3776.orig/net80211/ieee80211_monitor.c 2008-07-18 20:32:42.000000000 +0200
533 +++ madwifi-trunk-r3776/net80211/ieee80211_monitor.c 2008-07-18 20:35:03.000000000 +0200
534 @@ -580,7 +580,7 @@
535
536 if (SKB_NI(skb1) != NULL)
537 ieee80211_unref_node(&SKB_NI(skb1));
538 - if (netif_rx(skb1) == NET_RX_DROP)
539 + if (netif_receive_skb(skb1) == NET_RX_DROP)
540 vap->iv_devstats.rx_dropped++;
541 skb1 = NULL;
542 }