madwifi: fix a wds related race condition
[openwrt.git] / package / madwifi / patches / 396-napi_ff_fix.patch
1 --- a/ath/if_ath.c
2 +++ b/ath/if_ath.c
3 @@ -6734,10 +6734,10 @@ ath_rx_poll(struct net_device *dev, int 
4  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
5         struct ath_softc *sc = container_of(napi, struct ath_softc, sc_napi);
6         struct net_device *dev = sc->sc_dev;
7 -       u_int rx_limit = budget;
8 +       int rx_limit = budget;
9  #else
10         struct ath_softc *sc = dev->priv;
11 -       u_int rx_limit = min(dev->quota, *budget);
12 +       int rx_limit = min(dev->quota, *budget);
13  #endif
14         struct ath_buf *bf;
15         struct ieee80211com *ic = &sc->sc_ic;
16 @@ -6780,13 +6780,15 @@ process_rx_again:
17                         break;
18                 }
19  
20 -               if (rx_limit-- < 2) {
21 +               processed += ic->ic_recv;
22 +               rx_limit -= ic->ic_recv;
23 +               ic->ic_recv = 0;
24 +
25 +               /* keep a reserve for napi */
26 +               if (rx_limit < 4) {
27                         early_stop = 1;
28                         break;
29                 }
30 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
31 -               processed++;
32 -#endif
33  
34                 skb = bf->bf_skb;
35                 if (skb == NULL) {
36 @@ -7074,8 +7076,8 @@ rx_next:
37                 if (sc->sc_isr & HAL_INT_RX) {
38                         u_int64_t hw_tsf = ath_hal_gettsf64(ah);
39                         sc->sc_isr &= ~HAL_INT_RX;
40 -                       local_irq_restore(flags);
41                         ath_uapsd_processtriggers(sc, hw_tsf);
42 +                       local_irq_restore(flags);
43                         goto process_rx_again;
44                 }
45                 local_irq_restore(flags);
46 --- a/net80211/ieee80211_input.c
47 +++ b/net80211/ieee80211_input.c
48 @@ -1206,6 +1206,7 @@ ieee80211_deliver_data(struct ieee80211_
49                 }
50         }
51  
52 +       vap->iv_ic->ic_recv++;
53         if (skb != NULL) {
54                 skb->dev = dev;
55  
56 --- a/net80211/ieee80211_var.h
57 +++ b/net80211/ieee80211_var.h
58 @@ -323,6 +323,7 @@ struct ieee80211com {
59         struct ifmedia ic_media;                /* interface media config */
60         u_int8_t ic_myaddr[IEEE80211_ADDR_LEN];
61         struct timer_list ic_inact;             /* mgmt/inactivity timer */
62 +       u_int ic_recv;                                  /* frame received counter */
63  
64         unsigned int ic_subifs;
65         u_int32_t ic_flags;                     /* state flags */