aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/scan.c')
-rw-r--r--net/mac80211/scan.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 4cf387c944bf..f1a4c7160300 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)
227static void ieee80211_scan_ps_enable(struct ieee80211_sub_if_data *sdata) 227static 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