On Tue, Aug 05, 2014 at 08:52:57AM +0200, Johannes Berg wrote:
> From: Johannes Berg <[email protected]>
>
> Upstream commit 08b9939997df30e42a228e1ecb97f99e9c8ea84e, adjusted for
> lack of ieee80211_is_bufferable_mmpdu() helper function.
>
> 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.
>
> Cc: [email protected]
> Fixes: 277d916fc2e9 ("mac80211: move "bufferable MMPDU" check to fix AP mode
> scan")
> Signed-off-by: Johannes Berg <[email protected]>
Thank you, I'll use this backport for the 3.11 kernel as well.
Cheers,
--
Luís
> ---
> net/mac80211/tx.c | 27 +++++++++++++--------------
> 1 file changed, 13 insertions(+), 14 deletions(-)
>
> diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
> index d566cdba24ec..10eea2326022 100644
> --- a/net/mac80211/tx.c
> +++ b/net/mac80211/tx.c
> @@ -398,6 +398,9 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data
> *tx)
> 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 ieee80211_tx_data
> *tx)
> {
> 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 ieee80211_tx_data
> *tx)
> !(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 ieee80211_tx_data
> *tx)
> 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
> --
> 2.0.0
>
> --
> To unsubscribe from this list: send the line "unsubscribe stable" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html