From: Johannes Berg Date: Thu, 13 Dec 2012 16:16:45 +0000 (+0100) Subject: mac80211: clean up association better in suspend X-Git-Tag: v3.12-rc1~1418^2~242^2^2~128 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=529ba6e9313dbe60dab7e72c6fdf647a012e9f5b;p=kernel%2Fkernel-generic.git mac80211: clean up association better in suspend When suspending, bss_info_changed() is called to disable beacons, but managed mode interfaces are simply removed (bss_info_changed() is called with "no change" only). This can lead to problems. To fix this and copy the BSS configuration, clear it during suspend and restore it on resume. Signed-off-by: Johannes Berg --- diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index fa6d43e..38e7883 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -783,6 +783,11 @@ struct ieee80211_sub_if_data { struct dentry *default_mgmt_key; } debugfs; #endif + +#ifdef CONFIG_PM + struct ieee80211_bss_conf suspend_bss_conf; +#endif + /* must be last, dynamically sized area in this! */ struct ieee80211_vif vif; }; diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index f321783..712c17f 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c @@ -121,6 +121,8 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) /* remove all interfaces */ list_for_each_entry(sdata, &local->interfaces, list) { + u32 changed = BSS_CHANGED_BEACON_ENABLED; + if (!ieee80211_sdata_running(sdata)) continue; @@ -129,14 +131,25 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) case NL80211_IFTYPE_MONITOR: /* skip these */ continue; + case NL80211_IFTYPE_STATION: + if (sdata->vif.bss_conf.assoc) + changed = BSS_CHANGED_ASSOC | + BSS_CHANGED_BSSID | + BSS_CHANGED_IDLE; + else + changed = 0; + /* fall through */ default: ieee80211_quiesce(sdata); break; } - /* disable beaconing */ - ieee80211_bss_info_change_notify(sdata, - BSS_CHANGED_BEACON_ENABLED); + sdata->suspend_bss_conf = sdata->vif.bss_conf; + memset(&sdata->vif.bss_conf, 0, sizeof(sdata->vif.bss_conf)); + sdata->vif.bss_conf.idle = true; + + /* disable beaconing or remove association */ + ieee80211_bss_info_change_notify(sdata, changed); if (sdata->vif.type == NL80211_IFTYPE_AP && rcu_access_pointer(sdata->u.ap.beacon)) diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 051313f..2e2e13b 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1526,6 +1526,11 @@ int ieee80211_reconfig(struct ieee80211_local *local) BSS_CHANGED_IDLE | BSS_CHANGED_TXPOWER; +#ifdef CONFIG_PM + if (local->resuming) + sdata->vif.bss_conf = sdata->suspend_bss_conf; +#endif + switch (sdata->vif.type) { case NL80211_IFTYPE_STATION: changed |= BSS_CHANGED_ASSOC |