|
@@ -227,7 +227,8 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
|
|
|
static void ieee80211_scan_ps_enable(struct ieee80211_sub_if_data *sdata)
|
|
|
{
|
|
|
struct ieee80211_local *local = sdata->local;
|
|
|
- bool ps = false;
|
|
|
+
|
|
|
+ local->scan_ps_enabled = false;
|
|
|
|
|
|
/* FIXME: what to do when local->pspolling is true? */
|
|
|
|
|
@@ -235,12 +236,13 @@ static void ieee80211_scan_ps_enable(struct ieee80211_sub_if_data *sdata)
|
|
|
cancel_work_sync(&local->dynamic_ps_enable_work);
|
|
|
|
|
|
if (local->hw.conf.flags & IEEE80211_CONF_PS) {
|
|
|
- ps = true;
|
|
|
+ local->scan_ps_enabled = true;
|
|
|
local->hw.conf.flags &= ~IEEE80211_CONF_PS;
|
|
|
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
|
|
|
}
|
|
|
|
|
|
- if (!ps || !(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK))
|
|
|
+ if (!(local->scan_ps_enabled) ||
|
|
|
+ !(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK))
|
|
|
/*
|
|
|
* If power save was enabled, no need to send a nullfunc
|
|
|
* 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)
|
|
|
|
|
|
if (!local->ps_sdata)
|
|
|
ieee80211_send_nullfunc(local, sdata, 0);
|
|
|
- else {
|
|
|
+ else if (local->scan_ps_enabled) {
|
|
|
/*
|
|
|
* In !IEEE80211_HW_PS_NULLFUNC_STACK case the hardware
|
|
|
* 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)
|
|
|
*/
|
|
|
local->hw.conf.flags |= IEEE80211_CONF_PS;
|
|
|
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
|
|
|
+ } else if (local->hw.conf.dynamic_ps_timeout > 0) {
|
|
|
+ /*
|
|
|
+ * If IEEE80211_CONF_PS was not set and the dynamic_ps_timer
|
|
|
+ * had been running before leaving the operating channel,
|
|
|
+ * restart the timer now and send a nullfunc frame to inform
|
|
|
+ * the AP that we are awake.
|
|
|
+ */
|
|
|
+ ieee80211_send_nullfunc(local, sdata, 0);
|
|
|
+ mod_timer(&local->dynamic_ps_timer, jiffies +
|
|
|
+ msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
|
|
|
}
|
|
|
}
|
|
|
|