| 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 */ |
| 66 | |