| From 08b9939997df30e42a228e1ecb97f99e9c8ea84e Mon Sep 17 00:00:00 2001 |
| From: Johannes Berg <johannes.berg@intel.com> |
| Date: Mon, 7 Jul 2014 12:01:11 +0200 |
| Subject: Revert "mac80211: move "bufferable MMPDU" check to fix AP mode scan" |
| |
| From: Johannes Berg <johannes.berg@intel.com> |
| |
| commit 08b9939997df30e42a228e1ecb97f99e9c8ea84e upstream. |
| |
| This reverts commit 277d916fc2e959c3f106904116bb4f7b1148d47a as it was |
| at least breaking iwlwifi by setting the IEEE80211_TX_CTL_NO_PS_BUFFER |
| flag in all kinds of interface modes, not only for AP mode where it is |
| appropriate. |
| |
| To avoid reintroducing the original problem, explicitly check for probe |
| request frames in the multicast buffering code. |
| |
| Fixes: 277d916fc2e9 ("mac80211: move "bufferable MMPDU" check to fix AP mode scan") |
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| |
| --- |
| net/mac80211/tx.c | 27 +++++++++++++-------------- |
| 1 file changed, 13 insertions(+), 14 deletions(-) |
| |
| --- a/net/mac80211/tx.c |
| +++ b/net/mac80211/tx.c |
| @@ -398,6 +398,9 @@ ieee80211_tx_h_multicast_ps_buf(struct i |
| if (ieee80211_has_order(hdr->frame_control)) |
| return TX_CONTINUE; |
| |
| + if (ieee80211_is_probe_req(hdr->frame_control)) |
| + return TX_CONTINUE; |
| + |
| /* no stations in PS mode */ |
| if (!atomic_read(&ps->num_sta_ps)) |
| return TX_CONTINUE; |
| @@ -447,6 +450,7 @@ ieee80211_tx_h_unicast_ps_buf(struct iee |
| { |
| struct sta_info *sta = tx->sta; |
| struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); |
| + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
| struct ieee80211_local *local = tx->local; |
| |
| if (unlikely(!sta)) |
| @@ -457,6 +461,15 @@ ieee80211_tx_h_unicast_ps_buf(struct iee |
| !(info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER))) { |
| int ac = skb_get_queue_mapping(tx->skb); |
| |
| + /* only deauth, disassoc and action are bufferable MMPDUs */ |
| + if (ieee80211_is_mgmt(hdr->frame_control) && |
| + !ieee80211_is_deauth(hdr->frame_control) && |
| + !ieee80211_is_disassoc(hdr->frame_control) && |
| + !ieee80211_is_action(hdr->frame_control)) { |
| + info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER; |
| + return TX_CONTINUE; |
| + } |
| + |
| ps_dbg(sta->sdata, "STA %pM aid %d: PS buffer for AC %d\n", |
| sta->sta.addr, sta->sta.aid, ac); |
| if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) |
| @@ -514,22 +527,8 @@ ieee80211_tx_h_unicast_ps_buf(struct iee |
| static ieee80211_tx_result debug_noinline |
| ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx) |
| { |
| - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); |
| - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
| - |
| if (unlikely(tx->flags & IEEE80211_TX_PS_BUFFERED)) |
| return TX_CONTINUE; |
| - |
| - /* only deauth, disassoc and action are bufferable MMPDUs */ |
| - if (ieee80211_is_mgmt(hdr->frame_control) && |
| - !ieee80211_is_deauth(hdr->frame_control) && |
| - !ieee80211_is_disassoc(hdr->frame_control) && |
| - !ieee80211_is_action(hdr->frame_control)) { |
| - if (tx->flags & IEEE80211_TX_UNICAST) |
| - info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER; |
| - return TX_CONTINUE; |
| - } |
| - |
| if (tx->flags & IEEE80211_TX_UNICAST) |
| return ieee80211_tx_h_unicast_ps_buf(tx); |
| else |