On Tue, Aug 05, 2014 at 08:52:57AM +0200, Johannes Berg wrote: > From: Johannes Berg <johannes.berg@xxxxxxxxx> > > 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: stable@xxxxxxxxxxxxxxx > Fixes: 277d916fc2e9 ("mac80211: move "bufferable MMPDU" check to fix AP mode scan") > Signed-off-by: Johannes Berg <johannes.berg@xxxxxxxxx> 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 majordomo@xxxxxxxxxxxxxxx > 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 majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html