diff options
author | Christian Lamparter <chunkeey@googlemail.com> | 2010-12-27 17:21:26 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-01-04 14:35:15 -0500 |
commit | 4cfda47b69d0a37e5fc0292addba6d0f5f671a14 (patch) | |
tree | 4a39ef3560c429b388e96a7479ac8fc27d4fd0c7 /net/mac80211/rx.c | |
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/mac80211/rx.c')
-rw-r--r-- | net/mac80211/rx.c | 4 |
1 files changed, 4 insertions, 0 deletions
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, | |||
537 | struct sk_buff_head *frames) | 537 | struct sk_buff_head *frames) |
538 | { | 538 | { |
539 | struct sk_buff *skb = tid_agg_rx->reorder_buf[index]; | 539 | struct sk_buff *skb = tid_agg_rx->reorder_buf[index]; |
540 | struct ieee80211_rx_status *status; | ||
540 | 541 | ||
541 | lockdep_assert_held(&tid_agg_rx->reorder_lock); | 542 | lockdep_assert_held(&tid_agg_rx->reorder_lock); |
542 | 543 | ||
@@ -546,6 +547,8 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw, | |||
546 | /* release the frame from the reorder ring buffer */ | 547 | /* release the frame from the reorder ring buffer */ |
547 | tid_agg_rx->stored_mpdu_num--; | 548 | tid_agg_rx->stored_mpdu_num--; |
548 | tid_agg_rx->reorder_buf[index] = NULL; | 549 | tid_agg_rx->reorder_buf[index] = NULL; |
550 | status = IEEE80211_SKB_RXCB(skb); | ||
551 | status->rx_flags |= IEEE80211_RX_DEFERRED_RELEASE; | ||
549 | __skb_queue_tail(frames, skb); | 552 | __skb_queue_tail(frames, skb); |
550 | 553 | ||
551 | no_frame: | 554 | no_frame: |
@@ -1189,6 +1192,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
1189 | * exchange sequence. | 1192 | * exchange sequence. |
1190 | */ | 1193 | */ |
1191 | if (!ieee80211_has_morefrags(hdr->frame_control) && | 1194 | if (!ieee80211_has_morefrags(hdr->frame_control) && |
1195 | !(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) && | ||
1192 | (rx->sdata->vif.type == NL80211_IFTYPE_AP || | 1196 | (rx->sdata->vif.type == NL80211_IFTYPE_AP || |
1193 | rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) { | 1197 | rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) { |
1194 | if (test_sta_flags(sta, WLAN_STA_PS_STA)) { | 1198 | if (test_sta_flags(sta, WLAN_STA_PS_STA)) { |