Commit 4cfda47b authored by Christian Lamparter's avatar Christian Lamparter Committed by John W. Linville

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: default avatarChristian Lamparter <chunkeey@googlemail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 5af3c1d1
...@@ -167,6 +167,7 @@ typedef unsigned __bitwise__ ieee80211_rx_result; ...@@ -167,6 +167,7 @@ typedef unsigned __bitwise__ ieee80211_rx_result;
* @IEEE80211_RX_FRAGMENTED: fragmented frame * @IEEE80211_RX_FRAGMENTED: fragmented frame
* @IEEE80211_RX_AMSDU: a-MSDU packet * @IEEE80211_RX_AMSDU: a-MSDU packet
* @IEEE80211_RX_MALFORMED_ACTION_FRM: action frame is malformed * @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 * These are per-frame flags that are attached to a frame in the
* @rx_flags field of &struct ieee80211_rx_status. * @rx_flags field of &struct ieee80211_rx_status.
...@@ -177,6 +178,7 @@ enum ieee80211_packet_rx_flags { ...@@ -177,6 +178,7 @@ enum ieee80211_packet_rx_flags {
IEEE80211_RX_FRAGMENTED = BIT(2), IEEE80211_RX_FRAGMENTED = BIT(2),
IEEE80211_RX_AMSDU = BIT(3), IEEE80211_RX_AMSDU = BIT(3),
IEEE80211_RX_MALFORMED_ACTION_FRM = BIT(4), IEEE80211_RX_MALFORMED_ACTION_FRM = BIT(4),
IEEE80211_RX_DEFERRED_RELEASE = BIT(5),
}; };
/** /**
......
...@@ -537,6 +537,7 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw, ...@@ -537,6 +537,7 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw,
struct sk_buff_head *frames) struct sk_buff_head *frames)
{ {
struct sk_buff *skb = tid_agg_rx->reorder_buf[index]; struct sk_buff *skb = tid_agg_rx->reorder_buf[index];
struct ieee80211_rx_status *status;
lockdep_assert_held(&tid_agg_rx->reorder_lock); lockdep_assert_held(&tid_agg_rx->reorder_lock);
...@@ -546,6 +547,8 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw, ...@@ -546,6 +547,8 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw,
/* release the frame from the reorder ring buffer */ /* release the frame from the reorder ring buffer */
tid_agg_rx->stored_mpdu_num--; tid_agg_rx->stored_mpdu_num--;
tid_agg_rx->reorder_buf[index] = NULL; tid_agg_rx->reorder_buf[index] = NULL;
status = IEEE80211_SKB_RXCB(skb);
status->rx_flags |= IEEE80211_RX_DEFERRED_RELEASE;
__skb_queue_tail(frames, skb); __skb_queue_tail(frames, skb);
no_frame: no_frame:
...@@ -1189,6 +1192,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) ...@@ -1189,6 +1192,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
* exchange sequence. * exchange sequence.
*/ */
if (!ieee80211_has_morefrags(hdr->frame_control) && 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 ||
rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) { rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) {
if (test_sta_flags(sta, WLAN_STA_PS_STA)) { if (test_sta_flags(sta, WLAN_STA_PS_STA)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment