diff options
author | Johannes Berg <johannes.berg@intel.com> | 2012-02-27 12:18:30 +0100 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-02-29 14:14:54 -0500 |
commit | 02f2f1a951f87644166926862ec32fb13511e2f3 (patch) | |
tree | 77d5ac88a112aeb9f18887277dabf311b7ec0e8a /net/mac80211 | |
parent | 5eb02e44adc92a71bae3ff60acb1eea5ada14e93 (diff) |
mac80211: handle non-bufferable MMPDUs correctly
This renames the IEEE80211_TX_CTL_POLL_RESPONSE
TX flag to IEEE80211_TX_CTL_NO_PS_BUFFER and also
uses it for non-bufferable MMPDUs (all MMPDUs but
deauth, disassoc and action frames.)
Previously, mac80211 would let the MMPDU through
but not set the flag so drivers supporting some
hardware aids for avoiding the PS races would
then reject the frame.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/sta_info.c | 4 | ||||
-rw-r--r-- | net/mac80211/tx.c | 17 |
2 files changed, 13 insertions, 8 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 98613c8f08c..cd0f265f42e 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -1050,7 +1050,7 @@ static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata, * exchange. Also set EOSP to indicate this packet * ends the poll/service period. */ - info->flags |= IEEE80211_TX_CTL_POLL_RESPONSE | + info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER | IEEE80211_TX_STATUS_EOSP | IEEE80211_TX_CTL_REQ_TX_STATUS; @@ -1177,7 +1177,7 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta, * STA may still remain is PS mode after this frame * exchange. */ - info->flags |= IEEE80211_TX_CTL_POLL_RESPONSE; + info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER; /* * Use MoreData flag to indicate whether there are diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 7c021f25571..570737df2d2 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -448,18 +448,23 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; struct ieee80211_local *local = tx->local; - if (unlikely(!sta || - ieee80211_is_probe_resp(hdr->frame_control) || - ieee80211_is_auth(hdr->frame_control) || - ieee80211_is_assoc_resp(hdr->frame_control) || - ieee80211_is_reassoc_resp(hdr->frame_control))) + if (unlikely(!sta)) return TX_CONTINUE; if (unlikely((test_sta_flag(sta, WLAN_STA_PS_STA) || test_sta_flag(sta, WLAN_STA_PS_DRIVER)) && - !(info->flags & IEEE80211_TX_CTL_POLL_RESPONSE))) { + !(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; + } + #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG printk(KERN_DEBUG "STA %pM aid %d: PS buffer for AC %d\n", sta->sta.addr, sta->sta.aid, ac); |