summaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorEliad Peller2012-07-27 11:33:22 +0200
committerJohannes Berg2012-07-31 16:11:04 +0200
commitab09587740fddf6b4116be7b6716ab47f34d2634 (patch)
tree18c304410c82725356a3a8d6076b2f9af173b21a /net/mac80211/mlme.c
parentwlcore: op_tx: pass sta explicitly when inferring frame hlid (diff)
downloadkernel-qcow2-linux-ab09587740fddf6b4116be7b6716ab47f34d2634.tar.gz
kernel-qcow2-linux-ab09587740fddf6b4116be7b6716ab47f34d2634.tar.xz
kernel-qcow2-linux-ab09587740fddf6b4116be7b6716ab47f34d2634.zip
mac80211: add PS flag to bss_conf
Currently, ps mode is indicated per device (rather than per interface), which doesn't make a lot of sense. Moreover, there are subtle bugs caused by the inability to indicate ps change along with other changes (e.g. when the AP deauth us, we'd like to indicate CHANGED_PS | CHANGED_ASSOC, as changing PS before notifying about disassociation will result in null-packets being sent (if IEEE80211_HW_SUPPORTS_DYNAMIC_PS) while the sta is already disconnected.) Keep the current per-device notifications, and add parallel per-vif notifications. In order to keep it simple, the per-device ps and the per-vif ps are orthogonal - the per-vif ps configuration is determined only by the user configuration (enable/disable) and the connection state, and is not affected by other vifs state and (temporary) dynamic_ps/offchannel operations (unlike per-device ps). Signed-off-by: Eliad Peller <eliad@wizery.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index f0d6fa283071..ea46c6446450 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1032,6 +1032,16 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
ieee80211_change_ps(local);
}
+void ieee80211_recalc_ps_vif(struct ieee80211_sub_if_data *sdata)
+{
+ bool ps_allowed = ieee80211_powersave_allowed(sdata);
+
+ if (sdata->vif.bss_conf.ps != ps_allowed) {
+ sdata->vif.bss_conf.ps = ps_allowed;
+ ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_PS);
+ }
+}
+
void ieee80211_dynamic_ps_disable_work(struct work_struct *work)
{
struct ieee80211_local *local =
@@ -1335,6 +1345,8 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
ieee80211_recalc_smps(local);
mutex_unlock(&local->iflist_mtx);
+ ieee80211_recalc_ps_vif(sdata);
+
netif_tx_start_all_queues(sdata->dev);
netif_carrier_on(sdata->dev);
}
@@ -1396,6 +1408,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
}
local->ps_sdata = NULL;
+ /* disable per-vif ps */
+ ieee80211_recalc_ps_vif(sdata);
+
/* flush out any pending frame (e.g. DELBA) before deauth/disassoc */
if (tx)
drv_flush(local, false);