aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorChristian Lamparter <chunkeey@googlemail.com>2010-12-27 17:21:26 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-01-04 14:35:15 -0500
commit4cfda47b69d0a37e5fc0292addba6d0f5f671a14 (patch)
tree4a39ef3560c429b388e96a7479ac8fc27d4fd0c7 /net/mac80211
parent5af3c1d195a6169a925a929e800dc4fce2a545ae (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')
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/rx.c4
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
551no_frame: 554no_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)) {