From 39886b618aba3c39e650c191d601e26ec581ce0f Mon Sep 17 00:00:00 2001 From: Thomas Pedersen Date: Wed, 13 Feb 2013 12:14:19 -0800 Subject: mac80211: consolidate MBSS change notification A few mesh utility functions will call ieee80211_bss_info_change_notify(), and then the caller might notify the driver of the same change again. Avoid this redundancy by propagating the BSS changes and generally calling bss_info_change_notify() once per change. Signed-off-by: Thomas Pedersen Signed-off-by: Johannes Berg --- net/mac80211/mesh_ps.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'net/mac80211/mesh_ps.c') diff --git a/net/mac80211/mesh_ps.c b/net/mac80211/mesh_ps.c index b677962525ed..3b7bfc01ee36 100644 --- a/net/mac80211/mesh_ps.c +++ b/net/mac80211/mesh_ps.c @@ -74,14 +74,17 @@ static void mps_qos_null_tx(struct sta_info *sta) * @sdata: local mesh subif * * sets the non-peer power mode and triggers the driver PS (re-)configuration + * Return BSS_CHANGED_BEACON if a beacon update is necessary. */ -void ieee80211_mps_local_status_update(struct ieee80211_sub_if_data *sdata) +u32 ieee80211_mps_local_status_update(struct ieee80211_sub_if_data *sdata) { struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; struct sta_info *sta; bool peering = false; int light_sleep_cnt = 0; int deep_sleep_cnt = 0; + u32 changed = 0; + enum nl80211_mesh_power_mode nonpeer_pm; rcu_read_lock(); list_for_each_entry_rcu(sta, &sdata->local->sta_list, list) { @@ -115,17 +118,26 @@ void ieee80211_mps_local_status_update(struct ieee80211_sub_if_data *sdata) */ if (peering) { mps_dbg(sdata, "setting non-peer PM to active for peering\n"); - ifmsh->nonpeer_pm = NL80211_MESH_POWER_ACTIVE; + nonpeer_pm = NL80211_MESH_POWER_ACTIVE; } else if (light_sleep_cnt || deep_sleep_cnt) { mps_dbg(sdata, "setting non-peer PM to deep sleep\n"); - ifmsh->nonpeer_pm = NL80211_MESH_POWER_DEEP_SLEEP; + nonpeer_pm = NL80211_MESH_POWER_DEEP_SLEEP; } else { mps_dbg(sdata, "setting non-peer PM to user value\n"); - ifmsh->nonpeer_pm = ifmsh->mshcfg.power_mode; + nonpeer_pm = ifmsh->mshcfg.power_mode; } + /* need update if sleep counts move between 0 and non-zero */ + if (ifmsh->nonpeer_pm != nonpeer_pm || + !ifmsh->ps_peers_light_sleep != !light_sleep_cnt || + !ifmsh->ps_peers_deep_sleep != !deep_sleep_cnt) + changed = BSS_CHANGED_BEACON; + + ifmsh->nonpeer_pm = nonpeer_pm; ifmsh->ps_peers_light_sleep = light_sleep_cnt; ifmsh->ps_peers_deep_sleep = deep_sleep_cnt; + + return changed; } /** @@ -133,9 +145,10 @@ void ieee80211_mps_local_status_update(struct ieee80211_sub_if_data *sdata) * * @sta: mesh STA * @pm: the power mode to set + * Return BSS_CHANGED_BEACON if a beacon update is in order. */ -void ieee80211_mps_set_sta_local_pm(struct sta_info *sta, - enum nl80211_mesh_power_mode pm) +u32 ieee80211_mps_set_sta_local_pm(struct sta_info *sta, + enum nl80211_mesh_power_mode pm) { struct ieee80211_sub_if_data *sdata = sta->sdata; @@ -151,7 +164,7 @@ void ieee80211_mps_set_sta_local_pm(struct sta_info *sta, if (sta->plink_state == NL80211_PLINK_ESTAB) mps_qos_null_tx(sta); - ieee80211_mps_local_status_update(sdata); + return ieee80211_mps_local_status_update(sdata); } /** -- cgit v1.2.3