diff options
author | Stanislaw Gruszka <sgruszka@redhat.com> | 2012-12-20 08:41:18 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-01-16 09:06:18 -0500 |
commit | aacde9ee45225f7e0b90960f479aef83c66bfdc0 (patch) | |
tree | 50a7b363fde4cbc30aa0ba22bef4bbe27701c4ea /net/mac80211/offchannel.c | |
parent | 1626e0fa740dec8665a973cf2349405cdfeb46dc (diff) |
mac80211: synchronize scan off/on-channel and PS states
Since:
commit b23b025fe246f3acc2988eb6d400df34c27cb8ae
Author: Ben Greear <greearb@candelatech.com>
Date: Fri Feb 4 11:54:17 2011 -0800
mac80211: Optimize scans on current operating channel.
we do not disable PS while going back to operational channel (on
ieee80211_scan_state_suspend) and deffer that until scan finish.
But since we are allowed to send frames, we can send a frame to AP
without PM bit set, so disable PS on AP side. Then when we switch
to off-channel (in ieee80211_scan_state_resume) we do not enable PS.
Hence we are off-channel with PS disabled, frames are not buffered
by AP.
To fix remove offchannel_ps_disable argument and always enable PS when
going off-channel and disable it when going on-channel, like it was
before.
Cc: stable@vger.kernel.org # 2.6.39+
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Tested-by: Seth Forshee <seth.forshee@canonical.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/offchannel.c')
-rw-r--r-- | net/mac80211/offchannel.c | 19 |
1 files changed, 7 insertions, 12 deletions
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index a5379aea7d09..a3ad4c3c80a3 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c | |||
@@ -102,8 +102,7 @@ static void ieee80211_offchannel_ps_disable(struct ieee80211_sub_if_data *sdata) | |||
102 | ieee80211_sta_reset_conn_monitor(sdata); | 102 | ieee80211_sta_reset_conn_monitor(sdata); |
103 | } | 103 | } |
104 | 104 | ||
105 | void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, | 105 | void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local) |
106 | bool offchannel_ps_enable) | ||
107 | { | 106 | { |
108 | struct ieee80211_sub_if_data *sdata; | 107 | struct ieee80211_sub_if_data *sdata; |
109 | 108 | ||
@@ -134,8 +133,7 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, | |||
134 | 133 | ||
135 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { | 134 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { |
136 | netif_tx_stop_all_queues(sdata->dev); | 135 | netif_tx_stop_all_queues(sdata->dev); |
137 | if (offchannel_ps_enable && | 136 | if (sdata->vif.type == NL80211_IFTYPE_STATION && |
138 | (sdata->vif.type == NL80211_IFTYPE_STATION) && | ||
139 | sdata->u.mgd.associated) | 137 | sdata->u.mgd.associated) |
140 | ieee80211_offchannel_ps_enable(sdata); | 138 | ieee80211_offchannel_ps_enable(sdata); |
141 | } | 139 | } |
@@ -143,8 +141,7 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, | |||
143 | mutex_unlock(&local->iflist_mtx); | 141 | mutex_unlock(&local->iflist_mtx); |
144 | } | 142 | } |
145 | 143 | ||
146 | void ieee80211_offchannel_return(struct ieee80211_local *local, | 144 | void ieee80211_offchannel_return(struct ieee80211_local *local) |
147 | bool offchannel_ps_disable) | ||
148 | { | 145 | { |
149 | struct ieee80211_sub_if_data *sdata; | 146 | struct ieee80211_sub_if_data *sdata; |
150 | 147 | ||
@@ -163,11 +160,9 @@ void ieee80211_offchannel_return(struct ieee80211_local *local, | |||
163 | continue; | 160 | continue; |
164 | 161 | ||
165 | /* Tell AP we're back */ | 162 | /* Tell AP we're back */ |
166 | if (offchannel_ps_disable && | 163 | if (sdata->vif.type == NL80211_IFTYPE_STATION && |
167 | sdata->vif.type == NL80211_IFTYPE_STATION) { | 164 | sdata->u.mgd.associated) |
168 | if (sdata->u.mgd.associated) | 165 | ieee80211_offchannel_ps_disable(sdata); |
169 | ieee80211_offchannel_ps_disable(sdata); | ||
170 | } | ||
171 | 166 | ||
172 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { | 167 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { |
173 | /* | 168 | /* |
@@ -385,7 +380,7 @@ void ieee80211_sw_roc_work(struct work_struct *work) | |||
385 | local->tmp_channel = NULL; | 380 | local->tmp_channel = NULL; |
386 | ieee80211_hw_config(local, 0); | 381 | ieee80211_hw_config(local, 0); |
387 | 382 | ||
388 | ieee80211_offchannel_return(local, true); | 383 | ieee80211_offchannel_return(local); |
389 | } | 384 | } |
390 | 385 | ||
391 | ieee80211_recalc_idle(local); | 386 | ieee80211_recalc_idle(local); |