diff options
Diffstat (limited to 'net/mac80211/mesh.c')
-rw-r--r-- | net/mac80211/mesh.c | 49 |
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 | */ |
140 | void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata) | 142 | u32 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 | ||
156 | int mesh_rmc_init(struct ieee80211_sub_if_data *sdata) | 163 | int 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, | |||
521 | static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata, | 529 | static 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 | ||
614 | void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) | 623 | void 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); |