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 | |
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; | |||
167 | * @IEEE80211_RX_FRAGMENTED: fragmented frame | 167 | * @IEEE80211_RX_FRAGMENTED: fragmented frame |
168 | * @IEEE80211_RX_AMSDU: a-MSDU packet | 168 | * @IEEE80211_RX_AMSDU: a-MSDU packet |
169 | * @IEEE80211_RX_MALFORMED_ACTION_FRM: action frame is malformed | 169 | * @IEEE80211_RX_MALFORMED_ACTION_FRM: action frame is malformed |
170 | * @IEEE80211_RX_DEFERRED_RELEASE: frame was subjected to receive reordering | ||
170 | * | 171 | * |
171 | * These are per-frame flags that are attached to a frame in the | 172 | * These are per-frame flags that are attached to a frame in the |
172 | * @rx_flags field of &struct ieee80211_rx_status. | 173 | * @rx_flags field of &struct ieee80211_rx_status. |
@@ -177,6 +178,7 @@ enum ieee80211_packet_rx_flags { | |||
177 | IEEE80211_RX_FRAGMENTED = BIT(2), | 178 | IEEE80211_RX_FRAGMENTED = BIT(2), |
178 | IEEE80211_RX_AMSDU = BIT(3), | 179 | IEEE80211_RX_AMSDU = BIT(3), |
179 | IEEE80211_RX_MALFORMED_ACTION_FRM = BIT(4), | 180 | IEEE80211_RX_MALFORMED_ACTION_FRM = BIT(4), |
181 | IEEE80211_RX_DEFERRED_RELEASE = BIT(5), | ||
180 | }; | 182 | }; |
181 | 183 | ||
182 | /** | 184 | /** |
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)) { |