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 <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
This commit is contained in:
Johannes Berg 2012-02-27 12:18:30 +01:00 • committed by John W. Linville
commit 02f2f1a951
6 changed files with 30 additions and 18 deletions

View file

@ -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

View file

@ -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);