diff options
Diffstat (limited to 'net/mac80211/scan.c')
-rw-r--r-- | net/mac80211/scan.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index d3381ba5f457..66da0ab1d8fa 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -227,7 +227,8 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) | |||
227 | static void ieee80211_scan_ps_enable(struct ieee80211_sub_if_data *sdata) | 227 | static void ieee80211_scan_ps_enable(struct ieee80211_sub_if_data *sdata) |
228 | { | 228 | { |
229 | struct ieee80211_local *local = sdata->local; | 229 | struct ieee80211_local *local = sdata->local; |
230 | bool ps = false; | 230 | |
231 | local->scan_ps_enabled = false; | ||
231 | 232 | ||
232 | /* FIXME: what to do when local->pspolling is true? */ | 233 | /* FIXME: what to do when local->pspolling is true? */ |
233 | 234 | ||
@@ -235,12 +236,13 @@ static void ieee80211_scan_ps_enable(struct ieee80211_sub_if_data *sdata) | |||
235 | cancel_work_sync(&local->dynamic_ps_enable_work); | 236 | cancel_work_sync(&local->dynamic_ps_enable_work); |
236 | 237 | ||
237 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { | 238 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { |
238 | ps = true; | 239 | local->scan_ps_enabled = true; |
239 | local->hw.conf.flags &= ~IEEE80211_CONF_PS; | 240 | local->hw.conf.flags &= ~IEEE80211_CONF_PS; |
240 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); | 241 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); |
241 | } | 242 | } |
242 | 243 | ||
243 | if (!ps || !(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)) | 244 | if (!(local->scan_ps_enabled) || |
245 | !(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)) | ||
244 | /* | 246 | /* |
245 | * If power save was enabled, no need to send a nullfunc | 247 | * If power save was enabled, no need to send a nullfunc |
246 | * frame because AP knows that we are sleeping. But if the | 248 | * frame because AP knows that we are sleeping. But if the |
@@ -261,7 +263,7 @@ static void ieee80211_scan_ps_disable(struct ieee80211_sub_if_data *sdata) | |||
261 | 263 | ||
262 | if (!local->ps_sdata) | 264 | if (!local->ps_sdata) |
263 | ieee80211_send_nullfunc(local, sdata, 0); | 265 | ieee80211_send_nullfunc(local, sdata, 0); |
264 | else { | 266 | else if (local->scan_ps_enabled) { |
265 | /* | 267 | /* |
266 | * In !IEEE80211_HW_PS_NULLFUNC_STACK case the hardware | 268 | * In !IEEE80211_HW_PS_NULLFUNC_STACK case the hardware |
267 | * will send a nullfunc frame with the powersave bit set | 269 | * will send a nullfunc frame with the powersave bit set |
@@ -277,6 +279,16 @@ static void ieee80211_scan_ps_disable(struct ieee80211_sub_if_data *sdata) | |||
277 | */ | 279 | */ |
278 | local->hw.conf.flags |= IEEE80211_CONF_PS; | 280 | local->hw.conf.flags |= IEEE80211_CONF_PS; |
279 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); | 281 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); |
282 | } else if (local->hw.conf.dynamic_ps_timeout > 0) { | ||
283 | /* | ||
284 | * If IEEE80211_CONF_PS was not set and the dynamic_ps_timer | ||
285 | * had been running before leaving the operating channel, | ||
286 | * restart the timer now and send a nullfunc frame to inform | ||
287 | * the AP that we are awake. | ||
288 | */ | ||
289 | ieee80211_send_nullfunc(local, sdata, 0); | ||
290 | mod_timer(&local->dynamic_ps_timer, jiffies + | ||
291 | msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout)); | ||
280 | } | 292 | } |
281 | } | 293 | } |
282 | 294 | ||