diff options
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r-- | net/mac80211/rx.c | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 944bdc04e913..2cd02278d4d4 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -873,9 +873,10 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata, set_release_timer: - mod_timer(&tid_agg_rx->reorder_timer, - tid_agg_rx->reorder_time[j] + 1 + - HT_RX_REORDER_BUF_TIMEOUT); + if (!tid_agg_rx->removed) + mod_timer(&tid_agg_rx->reorder_timer, + tid_agg_rx->reorder_time[j] + 1 + + HT_RX_REORDER_BUF_TIMEOUT); } else { del_timer(&tid_agg_rx->reorder_timer); } @@ -1912,8 +1913,7 @@ static int ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc) /* Drop unencrypted frames if key is set. */ if (unlikely(!ieee80211_has_protected(fc) && !ieee80211_is_nullfunc(fc) && - ieee80211_is_data(fc) && - (rx->key || rx->sdata->drop_unencrypted))) + ieee80211_is_data(fc) && rx->key)) return -EACCES; return 0; @@ -2043,6 +2043,9 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) struct sta_info *dsta; struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); + dev->stats.rx_packets++; + dev->stats.rx_bytes += rx->skb->len; + skb = rx->skb; xmit_skb = NULL; @@ -2173,8 +2176,6 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) dev_kfree_skb(rx->skb); continue; } - dev->stats.rx_packets++; - dev->stats.rx_bytes += rx->skb->len; ieee80211_deliver_skb(rx); } @@ -2400,9 +2401,6 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) rx->skb->dev = dev; - dev->stats.rx_packets++; - dev->stats.rx_bytes += rx->skb->len; - if (local->ps_sdata && local->hw.conf.dynamic_ps_timeout > 0 && !is_multicast_ether_addr( ((struct ethhdr *)rx->skb->data)->h_dest) && @@ -3128,6 +3126,12 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx, goto rxh_next; \ } while (0); + /* Lock here to avoid hitting all of the data used in the RX + * path (e.g. key data, station data, ...) concurrently when + * a frame is released from the reorder buffer due to timeout + * from the timer, potentially concurrently with RX from the + * driver. + */ spin_lock_bh(&rx->local->rx_path_lock); while ((skb = __skb_dequeue(frames))) { |