diff options
author | David S. Miller <davem@davemloft.net> | 2008-12-05 22:23:34 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-12-05 22:23:34 -0800 |
commit | 098401a600b6344771900fe164c5eafb668ce99c (patch) | |
tree | c03077ee357cf6191bcd9f44ead4e6e4ce8f0495 /net/mac80211/rx.c | |
parent | cb7b48f671f9c7582993a6c0ff6e989078048561 (diff) | |
parent | c112d0c5b89037dd618083b5fdf4bb36b0c51d77 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r-- | net/mac80211/rx.c | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 648a1d0e6c82..14be095b8528 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -654,9 +654,13 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) static void ap_sta_ps_start(struct sta_info *sta) { struct ieee80211_sub_if_data *sdata = sta->sdata; + struct ieee80211_local *local = sdata->local; atomic_inc(&sdata->bss->num_sta_ps); set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL); + if (local->ops->sta_notify_ps) + local->ops->sta_notify_ps(local_to_hw(local), STA_NOTIFY_SLEEP, + &sta->sta); #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n", sdata->dev->name, sta->sta.addr, sta->sta.aid); @@ -673,6 +677,9 @@ static int ap_sta_ps_end(struct sta_info *sta) atomic_dec(&sdata->bss->num_sta_ps); clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL); + if (local->ops->sta_notify_ps) + local->ops->sta_notify_ps(local_to_hw(local), STA_NOTIFY_AWAKE, + &sta->sta); if (!skb_queue_empty(&sta->ps_tx_buf)) sta_info_clear_tim_bit(sta); @@ -741,17 +748,29 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) sta->last_qual = rx->status->qual; sta->last_noise = rx->status->noise; + /* + * Change STA power saving mode only at the end of a frame + * exchange sequence. + */ if (!ieee80211_has_morefrags(hdr->frame_control) && (rx->sdata->vif.type == NL80211_IFTYPE_AP || rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) { - /* Change STA power saving mode only in the end of a frame - * exchange sequence */ - if (test_sta_flags(sta, WLAN_STA_PS) && - !ieee80211_has_pm(hdr->frame_control)) - rx->sent_ps_buffered += ap_sta_ps_end(sta); - else if (!test_sta_flags(sta, WLAN_STA_PS) && - ieee80211_has_pm(hdr->frame_control)) - ap_sta_ps_start(sta); + if (test_sta_flags(sta, WLAN_STA_PS)) { + /* + * Ignore doze->wake transitions that are + * indicated by non-data frames, the standard + * is unclear here, but for example going to + * PS mode and then scanning would cause a + * doze->wake transition for the probe request, + * and that is clearly undesirable. + */ + if (ieee80211_is_data(hdr->frame_control) && + !ieee80211_has_pm(hdr->frame_control)) + rx->sent_ps_buffered += ap_sta_ps_end(sta); + } else { + if (ieee80211_has_pm(hdr->frame_control)) + ap_sta_ps_start(sta); + } } /* Drop data::nullfunc frames silently, since they are used only to |