diff options
Diffstat (limited to 'net/mac80211/tx.c')
| -rw-r--r-- | net/mac80211/tx.c | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 1be0ca2b5936..570737df2d22 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); @@ -625,7 +630,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) tx->local->hw.wiphy->frag_threshold); /* set up the tx rate control struct we give the RC algo */ - txrc.hw = local_to_hw(tx->local); + txrc.hw = &tx->local->hw; txrc.sband = sband; txrc.bss_conf = &tx->sdata->vif.bss_conf; txrc.skb = tx->skb; @@ -2206,7 +2211,8 @@ void ieee80211_tx_pending(unsigned long data) /* functions for drivers to get certain frames */ -static void ieee80211_beacon_add_tim(struct ieee80211_if_ap *bss, +static void ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata, + struct ieee80211_if_ap *bss, struct sk_buff *skb, struct beacon_data *beacon) { @@ -2223,7 +2229,7 @@ static void ieee80211_beacon_add_tim(struct ieee80211_if_ap *bss, IEEE80211_MAX_AID+1); if (bss->dtim_count == 0) - bss->dtim_count = beacon->dtim_period - 1; + bss->dtim_count = sdata->vif.bss_conf.dtim_period - 1; else bss->dtim_count--; @@ -2231,7 +2237,7 @@ static void ieee80211_beacon_add_tim(struct ieee80211_if_ap *bss, *pos++ = WLAN_EID_TIM; *pos++ = 4; *pos++ = bss->dtim_count; - *pos++ = beacon->dtim_period; + *pos++ = sdata->vif.bss_conf.dtim_period; if (bss->dtim_count == 0 && !skb_queue_empty(&bss->ps_bc_buf)) aid0 = 1; @@ -2324,12 +2330,14 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, * of the tim bitmap in mac80211 and the driver. */ if (local->tim_in_locked_section) { - ieee80211_beacon_add_tim(ap, skb, beacon); + ieee80211_beacon_add_tim(sdata, ap, skb, + beacon); } else { unsigned long flags; spin_lock_irqsave(&local->tim_lock, flags); - ieee80211_beacon_add_tim(ap, skb, beacon); + ieee80211_beacon_add_tim(sdata, ap, skb, + beacon); spin_unlock_irqrestore(&local->tim_lock, flags); } |
