summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-11-26 15:02:58 +0100
committerJohn W. Linville <linville@tuxdriver.com>2008-12-05 09:32:11 -0500
commit72eaa43a532b4156966444779829a986a4432f11 (patch)
treeca22c7bc823d4746a391cfa37ce31e5751b3a003
parent0d950d84d9d16f7d4edf380a238c5b534ff00d11 (diff)
mac80211: only transition STAs ps->wake on data frames
When a station goes to PS mode to scan, it will then send probe requests without the PS bit set. mac80211 will take that as indication that the station woke up, but it didn't. This patch changes mac80211 to only consider doze->wake transitions on data frames to to fix that issue. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Cc: Jouni Malinen <j@w1.fi> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--net/mac80211/rx.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 648a1d0e6c82..68a6e973c72c 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -741,17 +741,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