diff options
author | Thomas Pedersen <thomas@cozybit.com> | 2013-02-13 12:14:19 -0800 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-02-15 09:41:09 +0100 |
commit | 39886b618aba3c39e650c191d601e26ec581ce0f (patch) | |
tree | 6a68823a37ba8e3b68293ad78d572653a5e0c72b /net/mac80211/mesh_ps.c | |
parent | de74a1d9032f4d37ea453ad2a647e1aff4cd2591 (diff) |
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 <thomas@cozybit.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/mesh_ps.c')
-rw-r--r-- | net/mac80211/mesh_ps.c | 27 |
1 files changed, 20 insertions, 7 deletions
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); } /** |