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/scan.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/scan.c')
-rw-r--r-- | net/mac80211/scan.c | 15 |
1 files changed, 5 insertions, 10 deletions
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index d59fc6818b1c..bf82e69d0601 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -292,7 +292,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted, | |||
292 | if (!was_hw_scan) { | 292 | if (!was_hw_scan) { |
293 | ieee80211_configure_filter(local); | 293 | ieee80211_configure_filter(local); |
294 | drv_sw_scan_complete(local); | 294 | drv_sw_scan_complete(local); |
295 | ieee80211_offchannel_return(local, true); | 295 | ieee80211_offchannel_return(local); |
296 | } | 296 | } |
297 | 297 | ||
298 | ieee80211_recalc_idle(local); | 298 | ieee80211_recalc_idle(local); |
@@ -341,7 +341,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local) | |||
341 | local->next_scan_state = SCAN_DECISION; | 341 | local->next_scan_state = SCAN_DECISION; |
342 | local->scan_channel_idx = 0; | 342 | local->scan_channel_idx = 0; |
343 | 343 | ||
344 | ieee80211_offchannel_stop_vifs(local, true); | 344 | ieee80211_offchannel_stop_vifs(local); |
345 | 345 | ||
346 | ieee80211_configure_filter(local); | 346 | ieee80211_configure_filter(local); |
347 | 347 | ||
@@ -678,12 +678,8 @@ static void ieee80211_scan_state_suspend(struct ieee80211_local *local, | |||
678 | local->scan_channel = NULL; | 678 | local->scan_channel = NULL; |
679 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | 679 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); |
680 | 680 | ||
681 | /* | 681 | /* disable PS */ |
682 | * Re-enable vifs and beaconing. Leave PS | 682 | ieee80211_offchannel_return(local); |
683 | * in off-channel state..will put that back | ||
684 | * on-channel at the end of scanning. | ||
685 | */ | ||
686 | ieee80211_offchannel_return(local, false); | ||
687 | 683 | ||
688 | *next_delay = HZ / 5; | 684 | *next_delay = HZ / 5; |
689 | /* afterwards, resume scan & go to next channel */ | 685 | /* afterwards, resume scan & go to next channel */ |
@@ -693,8 +689,7 @@ static void ieee80211_scan_state_suspend(struct ieee80211_local *local, | |||
693 | static void ieee80211_scan_state_resume(struct ieee80211_local *local, | 689 | static void ieee80211_scan_state_resume(struct ieee80211_local *local, |
694 | unsigned long *next_delay) | 690 | unsigned long *next_delay) |
695 | { | 691 | { |
696 | /* PS already is in off-channel mode */ | 692 | ieee80211_offchannel_stop_vifs(local); |
697 | ieee80211_offchannel_stop_vifs(local, false); | ||
698 | 693 | ||
699 | if (local->ops->flush) { | 694 | if (local->ops->flush) { |
700 | drv_flush(local, false); | 695 | drv_flush(local, false); |