aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Pedersen <thomas@cozybit.com>2013-02-13 15:14:19 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-02-15 03:41:09 -0500
commit39886b618aba3c39e650c191d601e26ec581ce0f (patch)
tree6a68823a37ba8e3b68293ad78d572653a5e0c72b
parentde74a1d9032f4d37ea453ad2a647e1aff4cd2591 (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.c20
-rw-r--r--net/mac80211/mesh.c2
-rw-r--r--net/mac80211/mesh.h10
-rw-r--r--net/mac80211/mesh_plink.c33
-rw-r--r--net/mac80211/mesh_ps.c27
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);
245const struct ieee80211_mesh_sync_ops *ieee80211_mesh_sync_ops_get(u8 method); 245const struct ieee80211_mesh_sync_ops *ieee80211_mesh_sync_ops_get(u8 method);
246 246
247/* mesh power save */ 247/* mesh power save */
248void ieee80211_mps_local_status_update(struct ieee80211_sub_if_data *sdata); 248u32 ieee80211_mps_local_status_update(struct ieee80211_sub_if_data *sdata);
249void ieee80211_mps_set_sta_local_pm(struct sta_info *sta, 249u32 ieee80211_mps_set_sta_local_pm(struct sta_info *sta,
250 enum nl80211_mesh_power_mode pm); 250 enum nl80211_mesh_power_mode pm);
251void ieee80211_mps_set_frame_flags(struct ieee80211_sub_if_data *sdata, 251void 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);
289u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata); 289u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata);
290void mesh_plink_broken(struct sta_info *sta); 290void mesh_plink_broken(struct sta_info *sta);
291u32 mesh_plink_deactivate(struct sta_info *sta); 291u32 mesh_plink_deactivate(struct sta_info *sta);
292int mesh_plink_open(struct sta_info *sta); 292u32 mesh_plink_open(struct sta_info *sta);
293void mesh_plink_block(struct sta_info *sta); 293u32 mesh_plink_block(struct sta_info *sta);
294void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, 294void 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);
510out: 511out:
511 rcu_read_unlock(); 512 rcu_read_unlock();
513 ieee80211_bss_info_change_notify(sdata, changed);
512} 514}
513 515
514static void mesh_plink_timer(unsigned long data) 516static 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
624int mesh_plink_open(struct sta_info *sta) 626u32 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
654void mesh_plink_block(struct sta_info *sta) 658u32 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 */
78void ieee80211_mps_local_status_update(struct ieee80211_sub_if_data *sdata) 79u32 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 */
137void ieee80211_mps_set_sta_local_pm(struct sta_info *sta, 150u32 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/**