diff options
author | Thomas Pedersen <thomas@cozybit.com> | 2013-02-13 15:14:19 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-02-15 03:41:09 -0500 |
commit | 39886b618aba3c39e650c191d601e26ec581ce0f (patch) | |
tree | 6a68823a37ba8e3b68293ad78d572653a5e0c72b | |
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>
-rw-r--r-- | net/mac80211/cfg.c | 20 | ||||
-rw-r--r-- | net/mac80211/mesh.c | 2 | ||||
-rw-r--r-- | net/mac80211/mesh.h | 10 | ||||
-rw-r--r-- | net/mac80211/mesh_plink.c | 33 | ||||
-rw-r--r-- | net/mac80211/mesh_ps.c | 27 |
5 files changed, 55 insertions, 37 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 0969978c2d92..f4db30624f67 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -1262,9 +1262,8 @@ static int sta_apply_parameters(struct ieee80211_local *local, | |||
1262 | 1262 | ||
1263 | if (ieee80211_vif_is_mesh(&sdata->vif)) { | 1263 | if (ieee80211_vif_is_mesh(&sdata->vif)) { |
1264 | #ifdef CONFIG_MAC80211_MESH | 1264 | #ifdef CONFIG_MAC80211_MESH |
1265 | u32 changed = 0; | ||
1265 | if (sdata->u.mesh.security & IEEE80211_MESH_SEC_SECURED) { | 1266 | if (sdata->u.mesh.security & IEEE80211_MESH_SEC_SECURED) { |
1266 | u32 changed = 0; | ||
1267 | |||
1268 | switch (params->plink_state) { | 1267 | switch (params->plink_state) { |
1269 | case NL80211_PLINK_ESTAB: | 1268 | case NL80211_PLINK_ESTAB: |
1270 | if (sta->plink_state != NL80211_PLINK_ESTAB) | 1269 | if (sta->plink_state != NL80211_PLINK_ESTAB) |
@@ -1273,8 +1272,8 @@ static int sta_apply_parameters(struct ieee80211_local *local, | |||
1273 | sta->plink_state = params->plink_state; | 1272 | sta->plink_state = params->plink_state; |
1274 | 1273 | ||
1275 | ieee80211_mps_sta_status_update(sta); | 1274 | ieee80211_mps_sta_status_update(sta); |
1276 | ieee80211_mps_set_sta_local_pm(sta, | 1275 | changed |= ieee80211_mps_set_sta_local_pm(sta, |
1277 | sdata->u.mesh.mshcfg.power_mode); | 1276 | sdata->u.mesh.mshcfg.power_mode); |
1278 | break; | 1277 | break; |
1279 | case NL80211_PLINK_LISTEN: | 1278 | case NL80211_PLINK_LISTEN: |
1280 | case NL80211_PLINK_BLOCKED: | 1279 | case NL80211_PLINK_BLOCKED: |
@@ -1288,26 +1287,29 @@ static int sta_apply_parameters(struct ieee80211_local *local, | |||
1288 | sta->plink_state = params->plink_state; | 1287 | sta->plink_state = params->plink_state; |
1289 | 1288 | ||
1290 | ieee80211_mps_sta_status_update(sta); | 1289 | ieee80211_mps_sta_status_update(sta); |
1291 | ieee80211_mps_local_status_update(sdata); | 1290 | changed |= |
1291 | ieee80211_mps_local_status_update(sdata); | ||
1292 | break; | 1292 | break; |
1293 | default: | 1293 | default: |
1294 | /* nothing */ | 1294 | /* nothing */ |
1295 | break; | 1295 | break; |
1296 | } | 1296 | } |
1297 | ieee80211_bss_info_change_notify(sdata, changed); | ||
1298 | } else { | 1297 | } else { |
1299 | switch (params->plink_action) { | 1298 | switch (params->plink_action) { |
1300 | case PLINK_ACTION_OPEN: | 1299 | case PLINK_ACTION_OPEN: |
1301 | mesh_plink_open(sta); | 1300 | changed |= mesh_plink_open(sta); |
1302 | break; | 1301 | break; |
1303 | case PLINK_ACTION_BLOCK: | 1302 | case PLINK_ACTION_BLOCK: |
1304 | mesh_plink_block(sta); | 1303 | changed |= mesh_plink_block(sta); |
1305 | break; | 1304 | break; |
1306 | } | 1305 | } |
1307 | } | 1306 | } |
1308 | 1307 | ||
1309 | if (params->local_pm) | 1308 | if (params->local_pm) |
1310 | ieee80211_mps_set_sta_local_pm(sta, params->local_pm); | 1309 | changed |= |
1310 | ieee80211_mps_set_sta_local_pm(sta, | ||
1311 | params->local_pm); | ||
1312 | ieee80211_bss_info_change_notify(sdata, changed); | ||
1311 | #endif | 1313 | #endif |
1312 | } | 1314 | } |
1313 | 1315 | ||
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 2bf0158c3f82..0adec3d539d3 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -675,7 +675,7 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) | |||
675 | sdata->vif.bss_conf.basic_rates = | 675 | sdata->vif.bss_conf.basic_rates = |
676 | ieee80211_mandatory_rates(local, band); | 676 | ieee80211_mandatory_rates(local, band); |
677 | 677 | ||
678 | ieee80211_mps_local_status_update(sdata); | 678 | changed |= ieee80211_mps_local_status_update(sdata); |
679 | 679 | ||
680 | ieee80211_bss_info_change_notify(sdata, changed); | 680 | ieee80211_bss_info_change_notify(sdata, changed); |
681 | 681 | ||
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 3b9d862744ba..7ad035f0cacc 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h | |||
@@ -245,9 +245,9 @@ void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh); | |||
245 | const struct ieee80211_mesh_sync_ops *ieee80211_mesh_sync_ops_get(u8 method); | 245 | const struct ieee80211_mesh_sync_ops *ieee80211_mesh_sync_ops_get(u8 method); |
246 | 246 | ||
247 | /* mesh power save */ | 247 | /* mesh power save */ |
248 | void ieee80211_mps_local_status_update(struct ieee80211_sub_if_data *sdata); | 248 | u32 ieee80211_mps_local_status_update(struct ieee80211_sub_if_data *sdata); |
249 | void ieee80211_mps_set_sta_local_pm(struct sta_info *sta, | 249 | u32 ieee80211_mps_set_sta_local_pm(struct sta_info *sta, |
250 | enum nl80211_mesh_power_mode pm); | 250 | enum nl80211_mesh_power_mode pm); |
251 | void ieee80211_mps_set_frame_flags(struct ieee80211_sub_if_data *sdata, | 251 | void ieee80211_mps_set_frame_flags(struct ieee80211_sub_if_data *sdata, |
252 | struct sta_info *sta, | 252 | struct sta_info *sta, |
253 | struct ieee80211_hdr *hdr); | 253 | struct ieee80211_hdr *hdr); |
@@ -289,8 +289,8 @@ bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie); | |||
289 | u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata); | 289 | u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata); |
290 | void mesh_plink_broken(struct sta_info *sta); | 290 | void mesh_plink_broken(struct sta_info *sta); |
291 | u32 mesh_plink_deactivate(struct sta_info *sta); | 291 | u32 mesh_plink_deactivate(struct sta_info *sta); |
292 | int mesh_plink_open(struct sta_info *sta); | 292 | u32 mesh_plink_open(struct sta_info *sta); |
293 | void mesh_plink_block(struct sta_info *sta); | 293 | u32 mesh_plink_block(struct sta_info *sta); |
294 | void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, | 294 | void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, |
295 | struct ieee80211_mgmt *mgmt, size_t len, | 295 | struct ieee80211_mgmt *mgmt, size_t len, |
296 | struct ieee80211_rx_status *rx_status); | 296 | struct ieee80211_rx_status *rx_status); |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 56c9b318a97e..a4c7a7e98d14 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -202,7 +202,7 @@ static u32 __mesh_plink_deactivate(struct sta_info *sta) | |||
202 | mesh_path_flush_by_nexthop(sta); | 202 | mesh_path_flush_by_nexthop(sta); |
203 | 203 | ||
204 | ieee80211_mps_sta_status_update(sta); | 204 | ieee80211_mps_sta_status_update(sta); |
205 | ieee80211_mps_local_status_update(sdata); | 205 | changed |= ieee80211_mps_local_status_update(sdata); |
206 | 206 | ||
207 | return changed; | 207 | return changed; |
208 | } | 208 | } |
@@ -494,6 +494,7 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata, | |||
494 | struct ieee802_11_elems *elems) | 494 | struct ieee802_11_elems *elems) |
495 | { | 495 | { |
496 | struct sta_info *sta; | 496 | struct sta_info *sta; |
497 | u32 changed = 0; | ||
497 | 498 | ||
498 | sta = mesh_sta_info_get(sdata, hw_addr, elems); | 499 | sta = mesh_sta_info_get(sdata, hw_addr, elems); |
499 | if (!sta) | 500 | if (!sta) |
@@ -504,11 +505,12 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata, | |||
504 | sdata->u.mesh.accepting_plinks && | 505 | sdata->u.mesh.accepting_plinks && |
505 | sdata->u.mesh.mshcfg.auto_open_plinks && | 506 | sdata->u.mesh.mshcfg.auto_open_plinks && |
506 | rssi_threshold_check(sta, sdata)) | 507 | rssi_threshold_check(sta, sdata)) |
507 | mesh_plink_open(sta); | 508 | changed = mesh_plink_open(sta); |
508 | 509 | ||
509 | ieee80211_mps_frame_release(sta, elems); | 510 | ieee80211_mps_frame_release(sta, elems); |
510 | out: | 511 | out: |
511 | rcu_read_unlock(); | 512 | rcu_read_unlock(); |
513 | ieee80211_bss_info_change_notify(sdata, changed); | ||
512 | } | 514 | } |
513 | 515 | ||
514 | static void mesh_plink_timer(unsigned long data) | 516 | static void mesh_plink_timer(unsigned long data) |
@@ -621,13 +623,14 @@ static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout) | |||
621 | add_timer(&sta->plink_timer); | 623 | add_timer(&sta->plink_timer); |
622 | } | 624 | } |
623 | 625 | ||
624 | int mesh_plink_open(struct sta_info *sta) | 626 | u32 mesh_plink_open(struct sta_info *sta) |
625 | { | 627 | { |
626 | __le16 llid; | 628 | __le16 llid; |
627 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 629 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
630 | u32 changed; | ||
628 | 631 | ||
629 | if (!test_sta_flag(sta, WLAN_STA_AUTH)) | 632 | if (!test_sta_flag(sta, WLAN_STA_AUTH)) |
630 | return -EPERM; | 633 | return 0; |
631 | 634 | ||
632 | spin_lock_bh(&sta->lock); | 635 | spin_lock_bh(&sta->lock); |
633 | get_random_bytes(&llid, 2); | 636 | get_random_bytes(&llid, 2); |
@@ -635,7 +638,7 @@ int mesh_plink_open(struct sta_info *sta) | |||
635 | if (sta->plink_state != NL80211_PLINK_LISTEN && | 638 | if (sta->plink_state != NL80211_PLINK_LISTEN && |
636 | sta->plink_state != NL80211_PLINK_BLOCKED) { | 639 | sta->plink_state != NL80211_PLINK_BLOCKED) { |
637 | spin_unlock_bh(&sta->lock); | 640 | spin_unlock_bh(&sta->lock); |
638 | return -EBUSY; | 641 | return 0; |
639 | } | 642 | } |
640 | sta->plink_state = NL80211_PLINK_OPN_SNT; | 643 | sta->plink_state = NL80211_PLINK_OPN_SNT; |
641 | mesh_plink_timer_set(sta, sdata->u.mesh.mshcfg.dot11MeshRetryTimeout); | 644 | mesh_plink_timer_set(sta, sdata->u.mesh.mshcfg.dot11MeshRetryTimeout); |
@@ -645,15 +648,15 @@ int mesh_plink_open(struct sta_info *sta) | |||
645 | sta->sta.addr); | 648 | sta->sta.addr); |
646 | 649 | ||
647 | /* set the non-peer mode to active during peering */ | 650 | /* set the non-peer mode to active during peering */ |
648 | ieee80211_mps_local_status_update(sdata); | 651 | changed = ieee80211_mps_local_status_update(sdata); |
649 | 652 | ||
650 | return mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN, | 653 | mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN, |
651 | sta->sta.addr, llid, 0, 0); | 654 | sta->sta.addr, llid, 0, 0); |
655 | return changed; | ||
652 | } | 656 | } |
653 | 657 | ||
654 | void mesh_plink_block(struct sta_info *sta) | 658 | u32 mesh_plink_block(struct sta_info *sta) |
655 | { | 659 | { |
656 | struct ieee80211_sub_if_data *sdata = sta->sdata; | ||
657 | u32 changed; | 660 | u32 changed; |
658 | 661 | ||
659 | spin_lock_bh(&sta->lock); | 662 | spin_lock_bh(&sta->lock); |
@@ -661,7 +664,7 @@ void mesh_plink_block(struct sta_info *sta) | |||
661 | sta->plink_state = NL80211_PLINK_BLOCKED; | 664 | sta->plink_state = NL80211_PLINK_BLOCKED; |
662 | spin_unlock_bh(&sta->lock); | 665 | spin_unlock_bh(&sta->lock); |
663 | 666 | ||
664 | ieee80211_bss_info_change_notify(sdata, changed); | 667 | return changed; |
665 | } | 668 | } |
666 | 669 | ||
667 | 670 | ||
@@ -882,7 +885,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
882 | mshcfg->dot11MeshRetryTimeout); | 885 | mshcfg->dot11MeshRetryTimeout); |
883 | 886 | ||
884 | /* set the non-peer mode to active during peering */ | 887 | /* set the non-peer mode to active during peering */ |
885 | ieee80211_mps_local_status_update(sdata); | 888 | changed |= ieee80211_mps_local_status_update(sdata); |
886 | 889 | ||
887 | spin_unlock_bh(&sta->lock); | 890 | spin_unlock_bh(&sta->lock); |
888 | mesh_plink_frame_tx(sdata, | 891 | mesh_plink_frame_tx(sdata, |
@@ -978,7 +981,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
978 | mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n", | 981 | mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n", |
979 | sta->sta.addr); | 982 | sta->sta.addr); |
980 | ieee80211_mps_sta_status_update(sta); | 983 | ieee80211_mps_sta_status_update(sta); |
981 | ieee80211_mps_set_sta_local_pm(sta, | 984 | changed |= ieee80211_mps_set_sta_local_pm(sta, |
982 | mshcfg->power_mode); | 985 | mshcfg->power_mode); |
983 | break; | 986 | break; |
984 | default: | 987 | default: |
@@ -1020,8 +1023,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
1020 | WLAN_SP_MESH_PEERING_CONFIRM, | 1023 | WLAN_SP_MESH_PEERING_CONFIRM, |
1021 | sta->sta.addr, llid, plid, 0); | 1024 | sta->sta.addr, llid, plid, 0); |
1022 | ieee80211_mps_sta_status_update(sta); | 1025 | ieee80211_mps_sta_status_update(sta); |
1023 | ieee80211_mps_set_sta_local_pm(sta, | 1026 | changed |= ieee80211_mps_set_sta_local_pm(sta, |
1024 | mshcfg->power_mode); | 1027 | mshcfg->power_mode); |
1025 | break; | 1028 | break; |
1026 | default: | 1029 | default: |
1027 | spin_unlock_bh(&sta->lock); | 1030 | spin_unlock_bh(&sta->lock); |
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) | |||
74 | * @sdata: local mesh subif | 74 | * @sdata: local mesh subif |
75 | * | 75 | * |
76 | * sets the non-peer power mode and triggers the driver PS (re-)configuration | 76 | * sets the non-peer power mode and triggers the driver PS (re-)configuration |
77 | * Return BSS_CHANGED_BEACON if a beacon update is necessary. | ||
77 | */ | 78 | */ |
78 | void ieee80211_mps_local_status_update(struct ieee80211_sub_if_data *sdata) | 79 | u32 ieee80211_mps_local_status_update(struct ieee80211_sub_if_data *sdata) |
79 | { | 80 | { |
80 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 81 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
81 | struct sta_info *sta; | 82 | struct sta_info *sta; |
82 | bool peering = false; | 83 | bool peering = false; |
83 | int light_sleep_cnt = 0; | 84 | int light_sleep_cnt = 0; |
84 | int deep_sleep_cnt = 0; | 85 | int deep_sleep_cnt = 0; |
86 | u32 changed = 0; | ||
87 | enum nl80211_mesh_power_mode nonpeer_pm; | ||
85 | 88 | ||
86 | rcu_read_lock(); | 89 | rcu_read_lock(); |
87 | list_for_each_entry_rcu(sta, &sdata->local->sta_list, list) { | 90 | 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) | |||
115 | */ | 118 | */ |
116 | if (peering) { | 119 | if (peering) { |
117 | mps_dbg(sdata, "setting non-peer PM to active for peering\n"); | 120 | mps_dbg(sdata, "setting non-peer PM to active for peering\n"); |
118 | ifmsh->nonpeer_pm = NL80211_MESH_POWER_ACTIVE; | 121 | nonpeer_pm = NL80211_MESH_POWER_ACTIVE; |
119 | } else if (light_sleep_cnt || deep_sleep_cnt) { | 122 | } else if (light_sleep_cnt || deep_sleep_cnt) { |
120 | mps_dbg(sdata, "setting non-peer PM to deep sleep\n"); | 123 | mps_dbg(sdata, "setting non-peer PM to deep sleep\n"); |
121 | ifmsh->nonpeer_pm = NL80211_MESH_POWER_DEEP_SLEEP; | 124 | nonpeer_pm = NL80211_MESH_POWER_DEEP_SLEEP; |
122 | } else { | 125 | } else { |
123 | mps_dbg(sdata, "setting non-peer PM to user value\n"); | 126 | mps_dbg(sdata, "setting non-peer PM to user value\n"); |
124 | ifmsh->nonpeer_pm = ifmsh->mshcfg.power_mode; | 127 | nonpeer_pm = ifmsh->mshcfg.power_mode; |
125 | } | 128 | } |
126 | 129 | ||
130 | /* need update if sleep counts move between 0 and non-zero */ | ||
131 | if (ifmsh->nonpeer_pm != nonpeer_pm || | ||
132 | !ifmsh->ps_peers_light_sleep != !light_sleep_cnt || | ||
133 | !ifmsh->ps_peers_deep_sleep != !deep_sleep_cnt) | ||
134 | changed = BSS_CHANGED_BEACON; | ||
135 | |||
136 | ifmsh->nonpeer_pm = nonpeer_pm; | ||
127 | ifmsh->ps_peers_light_sleep = light_sleep_cnt; | 137 | ifmsh->ps_peers_light_sleep = light_sleep_cnt; |
128 | ifmsh->ps_peers_deep_sleep = deep_sleep_cnt; | 138 | ifmsh->ps_peers_deep_sleep = deep_sleep_cnt; |
139 | |||
140 | return changed; | ||
129 | } | 141 | } |
130 | 142 | ||
131 | /** | 143 | /** |
@@ -133,9 +145,10 @@ void ieee80211_mps_local_status_update(struct ieee80211_sub_if_data *sdata) | |||
133 | * | 145 | * |
134 | * @sta: mesh STA | 146 | * @sta: mesh STA |
135 | * @pm: the power mode to set | 147 | * @pm: the power mode to set |
148 | * Return BSS_CHANGED_BEACON if a beacon update is in order. | ||
136 | */ | 149 | */ |
137 | void ieee80211_mps_set_sta_local_pm(struct sta_info *sta, | 150 | u32 ieee80211_mps_set_sta_local_pm(struct sta_info *sta, |
138 | enum nl80211_mesh_power_mode pm) | 151 | enum nl80211_mesh_power_mode pm) |
139 | { | 152 | { |
140 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 153 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
141 | 154 | ||
@@ -151,7 +164,7 @@ void ieee80211_mps_set_sta_local_pm(struct sta_info *sta, | |||
151 | if (sta->plink_state == NL80211_PLINK_ESTAB) | 164 | if (sta->plink_state == NL80211_PLINK_ESTAB) |
152 | mps_qos_null_tx(sta); | 165 | mps_qos_null_tx(sta); |
153 | 166 | ||
154 | ieee80211_mps_local_status_update(sdata); | 167 | return ieee80211_mps_local_status_update(sdata); |
155 | } | 168 | } |
156 | 169 | ||
157 | /** | 170 | /** |