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>
This commit is contained in:
committed by
John W. Linville
parent
5af3c1d195
commit
4cfda47b69
@@ -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 {
|
|||||||
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,
|
|||||||
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,
|
|||||||
/* 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)
|
|||||||
* 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)) {
|
||||||
|
Reference in New Issue
Block a user