diff options
author | Christian Lamparter <chunkeey@googlemail.com> | 2010-12-27 23:21:26 +0100 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-01-04 14:35:15 -0500 |
commit | 4cfda47b69d0a37e5fc0292addba6d0f5f671a14 (patch) | |
tree | 4a39ef3560c429b388e96a7479ac8fc27d4fd0c7 /net | |
parent | 5af3c1d195a6169a925a929e800dc4fce2a545ae (diff) |
mac80211: ignore PSM bit of reordered frames
This patch tackles one of the problems of my
reorder release timer patch from August.
<http://www.spinics.net/lists/linux-wireless/msg57214.html>
=>
What if the reorder release triggers and ap_sta_ps_end
(called by ieee80211_rx_h_sta_process) accidentally clears
the WLAN_STA_PS_STA flag, because 100ms ago - when the STA
was still active - frames were put into the reorder buffer.
Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/ieee80211_i.h | 2 | ||||
-rw-r--r-- | net/mac80211/rx.c | 4 |
2 files changed, 6 insertions, 0 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index eadaa243a3da..a9eb67380da6 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -167,6 +167,7 @@ typedef unsigned __bitwise__ ieee80211_rx_result; * @IEEE80211_RX_FRAGMENTED: fragmented frame * @IEEE80211_RX_AMSDU: a-MSDU packet * @IEEE80211_RX_MALFORMED_ACTION_FRM: action frame is malformed + * @IEEE80211_RX_DEFERRED_RELEASE: frame was subjected to receive reordering * * These are per-frame flags that are attached to a frame in the * @rx_flags field of &struct ieee80211_rx_status. @@ -177,6 +178,7 @@ enum ieee80211_packet_rx_flags { IEEE80211_RX_FRAGMENTED = BIT(2), IEEE80211_RX_AMSDU = BIT(3), IEEE80211_RX_MALFORMED_ACTION_FRM = BIT(4), + IEEE80211_RX_DEFERRED_RELEASE = BIT(5), }; /** diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 7c5d1b2ec453..260b48bac42e 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -537,6 +537,7 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw, struct sk_buff_head *frames) { struct sk_buff *skb = tid_agg_rx->reorder_buf[index]; + struct ieee80211_rx_status *status; lockdep_assert_held(&tid_agg_rx->reorder_lock); @@ -546,6 +547,8 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw, /* release the frame from the reorder ring buffer */ tid_agg_rx->stored_mpdu_num--; tid_agg_rx->reorder_buf[index] = NULL; + status = IEEE80211_SKB_RXCB(skb); + status->rx_flags |= IEEE80211_RX_DEFERRED_RELEASE; __skb_queue_tail(frames, skb); no_frame: @@ -1189,6 +1192,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) * exchange sequence. */ if (!ieee80211_has_morefrags(hdr->frame_control) && + !(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) && (rx->sdata->vif.type == NL80211_IFTYPE_AP || rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) { if (test_sta_flags(sta, WLAN_STA_PS_STA)) { |