aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mesh.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/mesh.c')
-rw-r--r--net/mac80211/mesh.c49
1 files changed, 32 insertions, 17 deletions
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 85572353a7e3..ff0296c7bab8 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -109,11 +109,11 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
109 109
110 /* Disallow HT40+/- mismatch */ 110 /* Disallow HT40+/- mismatch */
111 if (ie->ht_operation && 111 if (ie->ht_operation &&
112 (local->_oper_channel_type == NL80211_CHAN_HT40MINUS || 112 (sdata->vif.bss_conf.channel_type == NL80211_CHAN_HT40MINUS ||
113 local->_oper_channel_type == NL80211_CHAN_HT40PLUS) && 113 sdata->vif.bss_conf.channel_type == NL80211_CHAN_HT40PLUS) &&
114 (sta_channel_type == NL80211_CHAN_HT40MINUS || 114 (sta_channel_type == NL80211_CHAN_HT40MINUS ||
115 sta_channel_type == NL80211_CHAN_HT40PLUS) && 115 sta_channel_type == NL80211_CHAN_HT40PLUS) &&
116 local->_oper_channel_type != sta_channel_type) 116 sdata->vif.bss_conf.channel_type != sta_channel_type)
117 goto mismatch; 117 goto mismatch;
118 118
119 return true; 119 return true;
@@ -136,10 +136,13 @@ bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie)
136 * mesh_accept_plinks_update - update accepting_plink in local mesh beacons 136 * mesh_accept_plinks_update - update accepting_plink in local mesh beacons
137 * 137 *
138 * @sdata: mesh interface in which mesh beacons are going to be updated 138 * @sdata: mesh interface in which mesh beacons are going to be updated
139 *
140 * Returns: beacon changed flag if the beacon content changed.
139 */ 141 */
140void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata) 142u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata)
141{ 143{
142 bool free_plinks; 144 bool free_plinks;
145 u32 changed = 0;
143 146
144 /* In case mesh_plink_free_count > 0 and mesh_plinktbl_capacity == 0, 147 /* In case mesh_plink_free_count > 0 and mesh_plinktbl_capacity == 0,
145 * the mesh interface might be able to establish plinks with peers that 148 * the mesh interface might be able to establish plinks with peers that
@@ -149,8 +152,12 @@ void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata)
149 */ 152 */
150 free_plinks = mesh_plink_availables(sdata); 153 free_plinks = mesh_plink_availables(sdata);
151 154
152 if (free_plinks != sdata->u.mesh.accepting_plinks) 155 if (free_plinks != sdata->u.mesh.accepting_plinks) {
153 ieee80211_mesh_housekeeping_timer((unsigned long) sdata); 156 sdata->u.mesh.accepting_plinks = free_plinks;
157 changed = BSS_CHANGED_BEACON;
158 }
159
160 return changed;
154} 161}
155 162
156int mesh_rmc_init(struct ieee80211_sub_if_data *sdata) 163int mesh_rmc_init(struct ieee80211_sub_if_data *sdata)
@@ -262,7 +269,6 @@ mesh_add_meshconf_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
262 neighbors = (neighbors > 15) ? 15 : neighbors; 269 neighbors = (neighbors > 15) ? 15 : neighbors;
263 *pos++ = neighbors << 1; 270 *pos++ = neighbors << 1;
264 /* Mesh capability */ 271 /* Mesh capability */
265 ifmsh->accepting_plinks = mesh_plink_availables(sdata);
266 *pos = MESHCONF_CAPAB_FORWARDING; 272 *pos = MESHCONF_CAPAB_FORWARDING;
267 *pos |= ifmsh->accepting_plinks ? 273 *pos |= ifmsh->accepting_plinks ?
268 MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00; 274 MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00;
@@ -349,17 +355,18 @@ int mesh_add_ds_params_ie(struct sk_buff *skb,
349{ 355{
350 struct ieee80211_local *local = sdata->local; 356 struct ieee80211_local *local = sdata->local;
351 struct ieee80211_supported_band *sband; 357 struct ieee80211_supported_band *sband;
358 struct ieee80211_channel *chan = local->oper_channel;
352 u8 *pos; 359 u8 *pos;
353 360
354 if (skb_tailroom(skb) < 3) 361 if (skb_tailroom(skb) < 3)
355 return -ENOMEM; 362 return -ENOMEM;
356 363
357 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 364 sband = local->hw.wiphy->bands[chan->band];
358 if (sband->band == IEEE80211_BAND_2GHZ) { 365 if (sband->band == IEEE80211_BAND_2GHZ) {
359 pos = skb_put(skb, 2 + 1); 366 pos = skb_put(skb, 2 + 1);
360 *pos++ = WLAN_EID_DS_PARAMS; 367 *pos++ = WLAN_EID_DS_PARAMS;
361 *pos++ = 1; 368 *pos++ = 1;
362 *pos++ = ieee80211_frequency_to_channel(local->hw.conf.channel->center_freq); 369 *pos++ = ieee80211_frequency_to_channel(chan->center_freq);
363 } 370 }
364 371
365 return 0; 372 return 0;
@@ -374,7 +381,7 @@ int mesh_add_ht_cap_ie(struct sk_buff *skb,
374 381
375 sband = local->hw.wiphy->bands[local->oper_channel->band]; 382 sband = local->hw.wiphy->bands[local->oper_channel->band];
376 if (!sband->ht_cap.ht_supported || 383 if (!sband->ht_cap.ht_supported ||
377 local->_oper_channel_type == NL80211_CHAN_NO_HT) 384 sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT)
378 return 0; 385 return 0;
379 386
380 if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_ht_cap)) 387 if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_ht_cap))
@@ -391,7 +398,8 @@ int mesh_add_ht_oper_ie(struct sk_buff *skb,
391{ 398{
392 struct ieee80211_local *local = sdata->local; 399 struct ieee80211_local *local = sdata->local;
393 struct ieee80211_channel *channel = local->oper_channel; 400 struct ieee80211_channel *channel = local->oper_channel;
394 enum nl80211_channel_type channel_type = local->_oper_channel_type; 401 enum nl80211_channel_type channel_type =
402 sdata->vif.bss_conf.channel_type;
395 struct ieee80211_supported_band *sband = 403 struct ieee80211_supported_band *sband =
396 local->hw.wiphy->bands[channel->band]; 404 local->hw.wiphy->bands[channel->band];
397 struct ieee80211_sta_ht_cap *ht_cap = &sband->ht_cap; 405 struct ieee80211_sta_ht_cap *ht_cap = &sband->ht_cap;
@@ -521,14 +529,13 @@ int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
521static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata, 529static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
522 struct ieee80211_if_mesh *ifmsh) 530 struct ieee80211_if_mesh *ifmsh)
523{ 531{
524 bool free_plinks; 532 u32 changed;
525 533
526 ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT); 534 ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT);
527 mesh_path_expire(sdata); 535 mesh_path_expire(sdata);
528 536
529 free_plinks = mesh_plink_availables(sdata); 537 changed = mesh_accept_plinks_update(sdata);
530 if (free_plinks != sdata->u.mesh.accepting_plinks) 538 ieee80211_bss_info_change_notify(sdata, changed);
531 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
532 539
533 mod_timer(&ifmsh->housekeeping_timer, 540 mod_timer(&ifmsh->housekeeping_timer,
534 round_jiffies(jiffies + IEEE80211_MESH_HOUSEKEEPING_INTERVAL)); 541 round_jiffies(jiffies + IEEE80211_MESH_HOUSEKEEPING_INTERVAL));
@@ -603,12 +610,14 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
603 sdata->vif.bss_conf.beacon_int = MESH_DEFAULT_BEACON_INTERVAL; 610 sdata->vif.bss_conf.beacon_int = MESH_DEFAULT_BEACON_INTERVAL;
604 sdata->vif.bss_conf.basic_rates = 611 sdata->vif.bss_conf.basic_rates =
605 ieee80211_mandatory_rates(sdata->local, 612 ieee80211_mandatory_rates(sdata->local,
606 sdata->local->hw.conf.channel->band); 613 sdata->local->oper_channel->band);
607 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON | 614 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON |
608 BSS_CHANGED_BEACON_ENABLED | 615 BSS_CHANGED_BEACON_ENABLED |
609 BSS_CHANGED_HT | 616 BSS_CHANGED_HT |
610 BSS_CHANGED_BASIC_RATES | 617 BSS_CHANGED_BASIC_RATES |
611 BSS_CHANGED_BEACON_INT); 618 BSS_CHANGED_BEACON_INT);
619
620 netif_carrier_on(sdata->dev);
612} 621}
613 622
614void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) 623void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
@@ -616,9 +625,15 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
616 struct ieee80211_local *local = sdata->local; 625 struct ieee80211_local *local = sdata->local;
617 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 626 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
618 627
628 netif_carrier_off(sdata->dev);
629
630 /* stop the beacon */
619 ifmsh->mesh_id_len = 0; 631 ifmsh->mesh_id_len = 0;
620 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); 632 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
621 sta_info_flush(local, NULL); 633
634 /* flush STAs and mpaths on this iface */
635 sta_info_flush(sdata->local, sdata);
636 mesh_path_flush_by_iface(sdata);
622 637
623 del_timer_sync(&sdata->u.mesh.housekeeping_timer); 638 del_timer_sync(&sdata->u.mesh.housekeeping_timer);
624 del_timer_sync(&sdata->u.mesh.mesh_path_root_timer); 639 del_timer_sync(&sdata->u.mesh.mesh_path_root_timer);