diff options
-rw-r--r-- | include/net/mac80211.h | 8 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 32 | ||||
-rw-r--r-- | net/mac80211/ieee80211.c | 9 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 56 | ||||
-rw-r--r-- | net/mac80211/ieee80211_iface.c | 66 | ||||
-rw-r--r-- | net/mac80211/ieee80211_sta.c | 72 | ||||
-rw-r--r-- | net/mac80211/mesh.c | 67 | ||||
-rw-r--r-- | net/mac80211/mesh.h | 13 | ||||
-rw-r--r-- | net/mac80211/mesh_plink.c | 28 | ||||
-rw-r--r-- | net/mac80211/rc80211_pid_algo.c | 3 | ||||
-rw-r--r-- | net/mac80211/rx.c | 28 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 13 | ||||
-rw-r--r-- | net/mac80211/sta_info.h | 2 | ||||
-rw-r--r-- | net/mac80211/tx.c | 120 | ||||
-rw-r--r-- | net/mac80211/util.c | 32 |
15 files changed, 277 insertions, 272 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 934cc25f757..6aca472d7a0 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -465,6 +465,14 @@ struct ieee80211_vif { | |||
465 | u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *)))); | 465 | u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *)))); |
466 | }; | 466 | }; |
467 | 467 | ||
468 | static inline bool ieee80211_vif_is_mesh(struct ieee80211_vif *vif) | ||
469 | { | ||
470 | #ifdef CONFIG_MAC80211_MESH | ||
471 | return vif->type == IEEE80211_IF_TYPE_MESH_POINT; | ||
472 | #endif | ||
473 | return false; | ||
474 | } | ||
475 | |||
468 | /** | 476 | /** |
469 | * struct ieee80211_if_init_conf - initial configuration of an interface | 477 | * struct ieee80211_if_init_conf - initial configuration of an interface |
470 | * | 478 | * |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index b1befac1736..6ac49231efa 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -15,9 +15,7 @@ | |||
15 | #include "ieee80211_i.h" | 15 | #include "ieee80211_i.h" |
16 | #include "cfg.h" | 16 | #include "cfg.h" |
17 | #include "ieee80211_rate.h" | 17 | #include "ieee80211_rate.h" |
18 | #ifdef CONFIG_MAC80211_MESH | ||
19 | #include "mesh.h" | 18 | #include "mesh.h" |
20 | #endif | ||
21 | 19 | ||
22 | #define DEFAULT_RATES 0 | 20 | #define DEFAULT_RATES 0 |
23 | 21 | ||
@@ -119,14 +117,10 @@ static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex, | |||
119 | ieee80211_if_reinit(dev); | 117 | ieee80211_if_reinit(dev); |
120 | ieee80211_if_set_type(dev, itype); | 118 | ieee80211_if_set_type(dev, itype); |
121 | 119 | ||
122 | #ifdef CONFIG_MAC80211_MESH | 120 | if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len) |
123 | if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT && | 121 | ieee80211_if_sta_set_mesh_id(&sdata->u.sta, |
124 | params->mesh_id_len) { | 122 | params->mesh_id_len, |
125 | sdata->u.sta.mesh_id_len = params->mesh_id_len; | 123 | params->mesh_id); |
126 | memcpy(sdata->u.sta.mesh_id, params->mesh_id, | ||
127 | params->mesh_id_len); | ||
128 | } | ||
129 | #endif | ||
130 | 124 | ||
131 | if (sdata->vif.type != IEEE80211_IF_TYPE_MNTR || !flags) | 125 | if (sdata->vif.type != IEEE80211_IF_TYPE_MNTR || !flags) |
132 | return 0; | 126 | return 0; |
@@ -317,9 +311,7 @@ static int ieee80211_config_default_key(struct wiphy *wiphy, | |||
317 | 311 | ||
318 | static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | 312 | static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) |
319 | { | 313 | { |
320 | #ifdef CONFIG_MAC80211_MESH | ||
321 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); | 314 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); |
322 | #endif | ||
323 | 315 | ||
324 | sinfo->filled = STATION_INFO_INACTIVE_TIME | | 316 | sinfo->filled = STATION_INFO_INACTIVE_TIME | |
325 | STATION_INFO_RX_BYTES | | 317 | STATION_INFO_RX_BYTES | |
@@ -329,8 +321,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
329 | sinfo->rx_bytes = sta->rx_bytes; | 321 | sinfo->rx_bytes = sta->rx_bytes; |
330 | sinfo->tx_bytes = sta->tx_bytes; | 322 | sinfo->tx_bytes = sta->tx_bytes; |
331 | 323 | ||
324 | if (ieee80211_vif_is_mesh(&sdata->vif)) { | ||
332 | #ifdef CONFIG_MAC80211_MESH | 325 | #ifdef CONFIG_MAC80211_MESH |
333 | if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT) { | ||
334 | sinfo->filled |= STATION_INFO_LLID | | 326 | sinfo->filled |= STATION_INFO_LLID | |
335 | STATION_INFO_PLID | | 327 | STATION_INFO_PLID | |
336 | STATION_INFO_PLINK_STATE; | 328 | STATION_INFO_PLINK_STATE; |
@@ -338,8 +330,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
338 | sinfo->llid = le16_to_cpu(sta->llid); | 330 | sinfo->llid = le16_to_cpu(sta->llid); |
339 | sinfo->plid = le16_to_cpu(sta->plid); | 331 | sinfo->plid = le16_to_cpu(sta->plid); |
340 | sinfo->plink_state = sta->plink_state; | 332 | sinfo->plink_state = sta->plink_state; |
341 | } | ||
342 | #endif | 333 | #endif |
334 | } | ||
343 | } | 335 | } |
344 | 336 | ||
345 | 337 | ||
@@ -580,9 +572,7 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
580 | u32 rates; | 572 | u32 rates; |
581 | int i, j; | 573 | int i, j; |
582 | struct ieee80211_supported_band *sband; | 574 | struct ieee80211_supported_band *sband; |
583 | #ifdef CONFIG_MAC80211_MESH | ||
584 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); | 575 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); |
585 | #endif | ||
586 | 576 | ||
587 | if (params->station_flags & STATION_FLAG_CHANGED) { | 577 | if (params->station_flags & STATION_FLAG_CHANGED) { |
588 | sta->flags &= ~WLAN_STA_AUTHORIZED; | 578 | sta->flags &= ~WLAN_STA_AUTHORIZED; |
@@ -621,9 +611,7 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
621 | sta->supp_rates[local->oper_channel->band] = rates; | 611 | sta->supp_rates[local->oper_channel->band] = rates; |
622 | } | 612 | } |
623 | 613 | ||
624 | #ifdef CONFIG_MAC80211_MESH | 614 | if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) { |
625 | if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT && | ||
626 | params->plink_action) | ||
627 | switch (params->plink_action) { | 615 | switch (params->plink_action) { |
628 | case PLINK_ACTION_OPEN: | 616 | case PLINK_ACTION_OPEN: |
629 | mesh_plink_open(sta); | 617 | mesh_plink_open(sta); |
@@ -632,7 +620,7 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
632 | mesh_plink_block(sta); | 620 | mesh_plink_block(sta); |
633 | break; | 621 | break; |
634 | } | 622 | } |
635 | #endif | 623 | } |
636 | } | 624 | } |
637 | 625 | ||
638 | static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, | 626 | static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, |
@@ -655,11 +643,9 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, | |||
655 | } else | 643 | } else |
656 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 644 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
657 | 645 | ||
658 | #ifdef CONFIG_MAC80211_MESH | 646 | if (ieee80211_vif_is_mesh(&sdata->vif)) |
659 | if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT) | ||
660 | sta = mesh_plink_add(mac, DEFAULT_RATES, dev); | 647 | sta = mesh_plink_add(mac, DEFAULT_RATES, dev); |
661 | else | 648 | else |
662 | #endif | ||
663 | sta = sta_info_add(local, dev, mac, GFP_KERNEL); | 649 | sta = sta_info_add(local, dev, mac, GFP_KERNEL); |
664 | 650 | ||
665 | if (IS_ERR(sta)) | 651 | if (IS_ERR(sta)) |
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c index 7106d651f4f..727af295c96 100644 --- a/net/mac80211/ieee80211.c +++ b/net/mac80211/ieee80211.c | |||
@@ -26,9 +26,7 @@ | |||
26 | 26 | ||
27 | #include "ieee80211_i.h" | 27 | #include "ieee80211_i.h" |
28 | #include "ieee80211_rate.h" | 28 | #include "ieee80211_rate.h" |
29 | #ifdef CONFIG_MAC80211_MESH | ||
30 | #include "mesh.h" | 29 | #include "mesh.h" |
31 | #endif | ||
32 | #include "wep.h" | 30 | #include "wep.h" |
33 | #include "wme.h" | 31 | #include "wme.h" |
34 | #include "aes_ccm.h" | 32 | #include "aes_ccm.h" |
@@ -938,11 +936,9 @@ static int __ieee80211_if_config(struct net_device *dev, | |||
938 | conf.bssid = sdata->u.sta.bssid; | 936 | conf.bssid = sdata->u.sta.bssid; |
939 | conf.ssid = sdata->u.sta.ssid; | 937 | conf.ssid = sdata->u.sta.ssid; |
940 | conf.ssid_len = sdata->u.sta.ssid_len; | 938 | conf.ssid_len = sdata->u.sta.ssid_len; |
941 | #ifdef CONFIG_MAC80211_MESH | 939 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) { |
942 | } else if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT) { | ||
943 | conf.beacon = beacon; | 940 | conf.beacon = beacon; |
944 | ieee80211_start_mesh(dev); | 941 | ieee80211_start_mesh(dev); |
945 | #endif | ||
946 | } else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { | 942 | } else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { |
947 | conf.ssid = sdata->u.ap.ssid; | 943 | conf.ssid = sdata->u.ap.ssid; |
948 | conf.ssid_len = sdata->u.ap.ssid_len; | 944 | conf.ssid_len = sdata->u.ap.ssid_len; |
@@ -1824,10 +1820,9 @@ static void __exit ieee80211_exit(void) | |||
1824 | rc80211_simple_exit(); | 1820 | rc80211_simple_exit(); |
1825 | rc80211_pid_exit(); | 1821 | rc80211_pid_exit(); |
1826 | 1822 | ||
1827 | #ifdef CONFIG_MAC80211_MESH | ||
1828 | if (mesh_allocated) | 1823 | if (mesh_allocated) |
1829 | ieee80211s_stop(); | 1824 | ieee80211s_stop(); |
1830 | #endif | 1825 | |
1831 | ieee80211_wme_unregister(); | 1826 | ieee80211_wme_unregister(); |
1832 | ieee80211_debugfs_netdev_exit(); | 1827 | ieee80211_debugfs_netdev_exit(); |
1833 | } | 1828 | } |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 49466b6996d..7394c9b783b 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -93,9 +93,8 @@ struct ieee80211_sta_bss { | |||
93 | #ifdef CONFIG_MAC80211_MESH | 93 | #ifdef CONFIG_MAC80211_MESH |
94 | u8 *mesh_id; | 94 | u8 *mesh_id; |
95 | size_t mesh_id_len; | 95 | size_t mesh_id_len; |
96 | #endif | ||
97 | /* mesh_cfg left out the ifdef to reduce clutter on bss handling */ | ||
98 | u8 *mesh_cfg; | 96 | u8 *mesh_cfg; |
97 | #endif | ||
99 | #define IEEE80211_MAX_SUPP_RATES 32 | 98 | #define IEEE80211_MAX_SUPP_RATES 32 |
100 | u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; | 99 | u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; |
101 | size_t supp_rates_len; | 100 | size_t supp_rates_len; |
@@ -113,6 +112,30 @@ struct ieee80211_sta_bss { | |||
113 | u8 erp_value; | 112 | u8 erp_value; |
114 | }; | 113 | }; |
115 | 114 | ||
115 | static inline u8 *bss_mesh_cfg(struct ieee80211_sta_bss *bss) | ||
116 | { | ||
117 | #ifdef CONFIG_MAC80211_MESH | ||
118 | return bss->mesh_cfg; | ||
119 | #endif | ||
120 | return NULL; | ||
121 | } | ||
122 | |||
123 | static inline u8 *bss_mesh_id(struct ieee80211_sta_bss *bss) | ||
124 | { | ||
125 | #ifdef CONFIG_MAC80211_MESH | ||
126 | return bss->mesh_id; | ||
127 | #endif | ||
128 | return NULL; | ||
129 | } | ||
130 | |||
131 | static inline u8 bss_mesh_id_len(struct ieee80211_sta_bss *bss) | ||
132 | { | ||
133 | #ifdef CONFIG_MAC80211_MESH | ||
134 | return bss->mesh_id_len; | ||
135 | #endif | ||
136 | return 0; | ||
137 | } | ||
138 | |||
116 | 139 | ||
117 | typedef unsigned __bitwise__ ieee80211_tx_result; | 140 | typedef unsigned __bitwise__ ieee80211_tx_result; |
118 | #define TX_CONTINUE ((__force ieee80211_tx_result) 0u) | 141 | #define TX_CONTINUE ((__force ieee80211_tx_result) 0u) |
@@ -233,7 +256,6 @@ struct ieee80211_if_vlan { | |||
233 | struct list_head list; | 256 | struct list_head list; |
234 | }; | 257 | }; |
235 | 258 | ||
236 | #ifdef CONFIG_MAC80211_MESH | ||
237 | struct mesh_stats { | 259 | struct mesh_stats { |
238 | __u32 fwded_frames; /* Mesh forwarded frames */ | 260 | __u32 fwded_frames; /* Mesh forwarded frames */ |
239 | __u32 dropped_frames_ttl; /* Not transmitted since mesh_ttl == 0*/ | 261 | __u32 dropped_frames_ttl; /* Not transmitted since mesh_ttl == 0*/ |
@@ -249,7 +271,6 @@ struct mesh_preq_queue { | |||
249 | u8 flags; | 271 | u8 flags; |
250 | }; | 272 | }; |
251 | 273 | ||
252 | |||
253 | struct mesh_config { | 274 | struct mesh_config { |
254 | /* Timeouts in ms */ | 275 | /* Timeouts in ms */ |
255 | /* Mesh plink management parameters */ | 276 | /* Mesh plink management parameters */ |
@@ -268,7 +289,7 @@ struct mesh_config { | |||
268 | u32 path_refresh_time; | 289 | u32 path_refresh_time; |
269 | u16 min_discovery_timeout; | 290 | u16 min_discovery_timeout; |
270 | }; | 291 | }; |
271 | #endif | 292 | |
272 | 293 | ||
273 | /* flags used in struct ieee80211_if_sta.flags */ | 294 | /* flags used in struct ieee80211_if_sta.flags */ |
274 | #define IEEE80211_STA_SSID_SET BIT(0) | 295 | #define IEEE80211_STA_SSID_SET BIT(0) |
@@ -361,6 +382,22 @@ struct ieee80211_if_sta { | |||
361 | int num_beacons; /* number of TXed beacon frames by this STA */ | 382 | int num_beacons; /* number of TXed beacon frames by this STA */ |
362 | }; | 383 | }; |
363 | 384 | ||
385 | static inline void ieee80211_if_sta_set_mesh_id(struct ieee80211_if_sta *ifsta, | ||
386 | u8 mesh_id_len, u8 *mesh_id) | ||
387 | { | ||
388 | #ifdef CONFIG_MAC80211_MESH | ||
389 | ifsta->mesh_id_len = mesh_id_len; | ||
390 | memcpy(ifsta->mesh_id, mesh_id, mesh_id_len); | ||
391 | #endif | ||
392 | } | ||
393 | |||
394 | #ifdef CONFIG_MAC80211_MESH | ||
395 | #define IEEE80211_IFSTA_MESH_CTR_INC(sta, name) \ | ||
396 | do { (sta)->mshstats.name++; } while (0) | ||
397 | #else | ||
398 | #define IEEE80211_IFSTA_MESH_CTR_INC(sta, name) \ | ||
399 | do { } while (0) | ||
400 | #endif | ||
364 | 401 | ||
365 | /* flags used in struct ieee80211_sub_if_data.flags */ | 402 | /* flags used in struct ieee80211_sub_if_data.flags */ |
366 | #define IEEE80211_SDATA_ALLMULTI BIT(0) | 403 | #define IEEE80211_SDATA_ALLMULTI BIT(0) |
@@ -472,7 +509,7 @@ struct ieee80211_sub_if_data { | |||
472 | struct dentry *dropped_frames_ttl; | 509 | struct dentry *dropped_frames_ttl; |
473 | struct dentry *dropped_frames_no_route; | 510 | struct dentry *dropped_frames_no_route; |
474 | struct dentry *estab_plinks; | 511 | struct dentry *estab_plinks; |
475 | struct timer_list mesh_path_timer; | 512 | struct timer_list mesh_path_timer; |
476 | } mesh_stats; | 513 | } mesh_stats; |
477 | 514 | ||
478 | struct dentry *mesh_config_dir; | 515 | struct dentry *mesh_config_dir; |
@@ -884,12 +921,17 @@ void sta_addba_resp_timer_expired(unsigned long data); | |||
884 | u64 ieee80211_sta_get_rates(struct ieee80211_local *local, | 921 | u64 ieee80211_sta_get_rates(struct ieee80211_local *local, |
885 | struct ieee802_11_elems *elems, | 922 | struct ieee802_11_elems *elems, |
886 | enum ieee80211_band band); | 923 | enum ieee80211_band band); |
887 | void ieee80211_start_mesh(struct net_device *dev); | ||
888 | void ieee80211_sta_tx(struct net_device *dev, struct sk_buff *skb, | 924 | void ieee80211_sta_tx(struct net_device *dev, struct sk_buff *skb, |
889 | int encrypt); | 925 | int encrypt); |
890 | void ieee802_11_parse_elems(u8 *start, size_t len, | 926 | void ieee802_11_parse_elems(u8 *start, size_t len, |
891 | struct ieee802_11_elems *elems); | 927 | struct ieee802_11_elems *elems); |
892 | 928 | ||
929 | #ifdef CONFIG_MAC80211_MESH | ||
930 | void ieee80211_start_mesh(struct net_device *dev); | ||
931 | #else | ||
932 | static inline void ieee80211_start_mesh(struct net_device *dev) | ||
933 | {} | ||
934 | #endif | ||
893 | 935 | ||
894 | /* ieee80211_iface.c */ | 936 | /* ieee80211_iface.c */ |
895 | int ieee80211_if_add(struct net_device *dev, const char *name, | 937 | int ieee80211_if_add(struct net_device *dev, const char *name, |
diff --git a/net/mac80211/ieee80211_iface.c b/net/mac80211/ieee80211_iface.c index c2f92b78bfc..b0f17a2b1a4 100644 --- a/net/mac80211/ieee80211_iface.c +++ b/net/mac80211/ieee80211_iface.c | |||
@@ -15,9 +15,7 @@ | |||
15 | #include "ieee80211_i.h" | 15 | #include "ieee80211_i.h" |
16 | #include "sta_info.h" | 16 | #include "sta_info.h" |
17 | #include "debugfs_netdev.h" | 17 | #include "debugfs_netdev.h" |
18 | #ifdef CONFIG_MAC80211_MESH | ||
19 | #include "mesh.h" | 18 | #include "mesh.h" |
20 | #endif | ||
21 | 19 | ||
22 | void ieee80211_if_sdata_init(struct ieee80211_sub_if_data *sdata) | 20 | void ieee80211_if_sdata_init(struct ieee80211_sub_if_data *sdata) |
23 | { | 21 | { |
@@ -82,14 +80,11 @@ int ieee80211_if_add(struct net_device *dev, const char *name, | |||
82 | ieee80211_debugfs_add_netdev(sdata); | 80 | ieee80211_debugfs_add_netdev(sdata); |
83 | ieee80211_if_set_type(ndev, type); | 81 | ieee80211_if_set_type(ndev, type); |
84 | 82 | ||
85 | #ifdef CONFIG_MAC80211_MESH | 83 | if (ieee80211_vif_is_mesh(&sdata->vif) && |
86 | if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT && | 84 | params && params->mesh_id_len) |
87 | params && params->mesh_id_len) { | 85 | ieee80211_if_sta_set_mesh_id(&sdata->u.sta, |
88 | sdata->u.sta.mesh_id_len = params->mesh_id_len; | 86 | params->mesh_id_len, |
89 | memcpy(sdata->u.sta.mesh_id, params->mesh_id, | 87 | params->mesh_id); |
90 | params->mesh_id_len); | ||
91 | } | ||
92 | #endif | ||
93 | 88 | ||
94 | /* we're under RTNL so all this is fine */ | 89 | /* we're under RTNL so all this is fine */ |
95 | if (unlikely(local->reg_state == IEEE80211_DEV_UNREGISTERED)) { | 90 | if (unlikely(local->reg_state == IEEE80211_DEV_UNREGISTERED)) { |
@@ -170,47 +165,8 @@ void ieee80211_if_set_type(struct net_device *dev, int type) | |||
170 | msdata = IEEE80211_DEV_TO_SUB_IF(sdata->local->mdev); | 165 | msdata = IEEE80211_DEV_TO_SUB_IF(sdata->local->mdev); |
171 | sdata->bss = &msdata->u.ap; | 166 | sdata->bss = &msdata->u.ap; |
172 | 167 | ||
173 | #ifdef CONFIG_MAC80211_MESH | 168 | if (ieee80211_vif_is_mesh(&sdata->vif)) |
174 | if (type == IEEE80211_IF_TYPE_MESH_POINT) { | 169 | ieee80211_mesh_init_sdata(sdata); |
175 | ifsta->mshcfg.dot11MeshRetryTimeout = MESH_RET_T; | ||
176 | ifsta->mshcfg.dot11MeshConfirmTimeout = MESH_CONF_T; | ||
177 | ifsta->mshcfg.dot11MeshHoldingTimeout = MESH_HOLD_T; | ||
178 | ifsta->mshcfg.dot11MeshMaxRetries = MESH_MAX_RETR; | ||
179 | ifsta->mshcfg.dot11MeshTTL = MESH_TTL; | ||
180 | ifsta->mshcfg.auto_open_plinks = true; | ||
181 | ifsta->mshcfg.dot11MeshMaxPeerLinks = | ||
182 | MESH_MAX_ESTAB_PLINKS; | ||
183 | ifsta->mshcfg.dot11MeshHWMPactivePathTimeout = | ||
184 | MESH_PATH_TIMEOUT; | ||
185 | ifsta->mshcfg.dot11MeshHWMPpreqMinInterval = | ||
186 | MESH_PREQ_MIN_INT; | ||
187 | ifsta->mshcfg.dot11MeshHWMPnetDiameterTraversalTime = | ||
188 | MESH_DIAM_TRAVERSAL_TIME; | ||
189 | ifsta->mshcfg.dot11MeshHWMPmaxPREQretries = | ||
190 | MESH_MAX_PREQ_RETRIES; | ||
191 | ifsta->mshcfg.path_refresh_time = | ||
192 | MESH_PATH_REFRESH_TIME; | ||
193 | ifsta->mshcfg.min_discovery_timeout = | ||
194 | MESH_MIN_DISCOVERY_TIMEOUT; | ||
195 | ifsta->accepting_plinks = true; | ||
196 | ifsta->preq_id = 0; | ||
197 | ifsta->dsn = 0; | ||
198 | atomic_set(&ifsta->mpaths, 0); | ||
199 | mesh_rmc_init(dev); | ||
200 | ifsta->last_preq = jiffies; | ||
201 | /* Allocate all mesh structures when creating the first | ||
202 | * mesh interface. | ||
203 | */ | ||
204 | if (!mesh_allocated) | ||
205 | ieee80211s_init(); | ||
206 | mesh_ids_set_default(ifsta); | ||
207 | setup_timer(&ifsta->mesh_path_timer, | ||
208 | ieee80211_mesh_path_timer, | ||
209 | (unsigned long) sdata); | ||
210 | INIT_LIST_HEAD(&ifsta->preq_queue.list); | ||
211 | spin_lock_init(&ifsta->mesh_preq_queue_lock); | ||
212 | } | ||
213 | #endif | ||
214 | break; | 170 | break; |
215 | } | 171 | } |
216 | case IEEE80211_IF_TYPE_MNTR: | 172 | case IEEE80211_IF_TYPE_MNTR: |
@@ -240,6 +196,10 @@ void ieee80211_if_reinit(struct net_device *dev) | |||
240 | 196 | ||
241 | ieee80211_if_sdata_deinit(sdata); | 197 | ieee80211_if_sdata_deinit(sdata); |
242 | 198 | ||
199 | /* Need to handle mesh specially to allow eliding the function call */ | ||
200 | if (ieee80211_vif_is_mesh(&sdata->vif)) | ||
201 | mesh_rmc_free(dev); | ||
202 | |||
243 | switch (sdata->vif.type) { | 203 | switch (sdata->vif.type) { |
244 | case IEEE80211_IF_TYPE_INVALID: | 204 | case IEEE80211_IF_TYPE_INVALID: |
245 | /* cannot happen */ | 205 | /* cannot happen */ |
@@ -292,10 +252,6 @@ void ieee80211_if_reinit(struct net_device *dev) | |||
292 | } | 252 | } |
293 | break; | 253 | break; |
294 | case IEEE80211_IF_TYPE_MESH_POINT: | 254 | case IEEE80211_IF_TYPE_MESH_POINT: |
295 | #ifdef CONFIG_MAC80211_MESH | ||
296 | mesh_rmc_free(dev); | ||
297 | #endif | ||
298 | /* fall through */ | ||
299 | case IEEE80211_IF_TYPE_STA: | 255 | case IEEE80211_IF_TYPE_STA: |
300 | case IEEE80211_IF_TYPE_IBSS: | 256 | case IEEE80211_IF_TYPE_IBSS: |
301 | kfree(sdata->u.sta.extra_ie); | 257 | kfree(sdata->u.sta.extra_ie); |
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c index d2dedcb5a95..9f933aeca71 100644 --- a/net/mac80211/ieee80211_sta.c +++ b/net/mac80211/ieee80211_sta.c | |||
@@ -31,9 +31,7 @@ | |||
31 | #include "ieee80211_i.h" | 31 | #include "ieee80211_i.h" |
32 | #include "ieee80211_rate.h" | 32 | #include "ieee80211_rate.h" |
33 | #include "ieee80211_led.h" | 33 | #include "ieee80211_led.h" |
34 | #ifdef CONFIG_MAC80211_MESH | ||
35 | #include "mesh.h" | 34 | #include "mesh.h" |
36 | #endif | ||
37 | 35 | ||
38 | #define IEEE80211_AUTH_TIMEOUT (HZ / 5) | 36 | #define IEEE80211_AUTH_TIMEOUT (HZ / 5) |
39 | #define IEEE80211_AUTH_MAX_TRIES 3 | 37 | #define IEEE80211_AUTH_MAX_TRIES 3 |
@@ -1897,12 +1895,13 @@ static void __ieee80211_rx_bss_hash_add(struct net_device *dev, | |||
1897 | { | 1895 | { |
1898 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 1896 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
1899 | u8 hash_idx; | 1897 | u8 hash_idx; |
1900 | #ifdef CONFIG_MAC80211_MESH | 1898 | |
1901 | if (bss->mesh_cfg) | 1899 | if (bss_mesh_cfg(bss)) |
1902 | hash_idx = mesh_id_hash(bss->mesh_id, bss->mesh_id_len); | 1900 | hash_idx = mesh_id_hash(bss_mesh_id(bss), |
1901 | bss_mesh_id_len(bss)); | ||
1903 | else | 1902 | else |
1904 | #endif | ||
1905 | hash_idx = STA_HASH(bss->bssid); | 1903 | hash_idx = STA_HASH(bss->bssid); |
1904 | |||
1906 | bss->hnext = local->sta_bss_hash[hash_idx]; | 1905 | bss->hnext = local->sta_bss_hash[hash_idx]; |
1907 | local->sta_bss_hash[hash_idx] = bss; | 1906 | local->sta_bss_hash[hash_idx] = bss; |
1908 | } | 1907 | } |
@@ -1967,7 +1966,8 @@ ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int freq, | |||
1967 | spin_lock_bh(&local->sta_bss_lock); | 1966 | spin_lock_bh(&local->sta_bss_lock); |
1968 | bss = local->sta_bss_hash[STA_HASH(bssid)]; | 1967 | bss = local->sta_bss_hash[STA_HASH(bssid)]; |
1969 | while (bss) { | 1968 | while (bss) { |
1970 | if (!bss->mesh_cfg && !memcmp(bss->bssid, bssid, ETH_ALEN) && | 1969 | if (!bss_mesh_cfg(bss) && |
1970 | !memcmp(bss->bssid, bssid, ETH_ALEN) && | ||
1971 | bss->freq == freq && | 1971 | bss->freq == freq && |
1972 | bss->ssid_len == ssid_len && | 1972 | bss->ssid_len == ssid_len && |
1973 | (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) { | 1973 | (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) { |
@@ -1991,8 +1991,8 @@ ieee80211_rx_mesh_bss_get(struct net_device *dev, u8 *mesh_id, int mesh_id_len, | |||
1991 | spin_lock_bh(&local->sta_bss_lock); | 1991 | spin_lock_bh(&local->sta_bss_lock); |
1992 | bss = local->sta_bss_hash[mesh_id_hash(mesh_id, mesh_id_len)]; | 1992 | bss = local->sta_bss_hash[mesh_id_hash(mesh_id, mesh_id_len)]; |
1993 | while (bss) { | 1993 | while (bss) { |
1994 | if (bss->mesh_cfg && | 1994 | if (bss_mesh_cfg(bss) && |
1995 | !memcmp(bss->mesh_cfg, mesh_cfg, MESH_CFG_CMP_LEN) && | 1995 | !memcmp(bss_mesh_cfg(bss), mesh_cfg, MESH_CFG_CMP_LEN) && |
1996 | bss->freq == freq && | 1996 | bss->freq == freq && |
1997 | mesh_id_len == bss->mesh_id_len && | 1997 | mesh_id_len == bss->mesh_id_len && |
1998 | (mesh_id_len == 0 || !memcmp(bss->mesh_id, mesh_id, | 1998 | (mesh_id_len == 0 || !memcmp(bss->mesh_id, mesh_id, |
@@ -2053,10 +2053,8 @@ static void ieee80211_rx_bss_free(struct ieee80211_sta_bss *bss) | |||
2053 | kfree(bss->rsn_ie); | 2053 | kfree(bss->rsn_ie); |
2054 | kfree(bss->wmm_ie); | 2054 | kfree(bss->wmm_ie); |
2055 | kfree(bss->ht_ie); | 2055 | kfree(bss->ht_ie); |
2056 | #ifdef CONFIG_MAC80211_MESH | 2056 | kfree(bss_mesh_id(bss)); |
2057 | kfree(bss->mesh_id); | 2057 | kfree(bss_mesh_cfg(bss)); |
2058 | kfree(bss->mesh_cfg); | ||
2059 | #endif | ||
2060 | kfree(bss); | 2058 | kfree(bss); |
2061 | } | 2059 | } |
2062 | 2060 | ||
@@ -2322,16 +2320,14 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2322 | beacon_timestamp = le64_to_cpu(mgmt->u.beacon.timestamp); | 2320 | beacon_timestamp = le64_to_cpu(mgmt->u.beacon.timestamp); |
2323 | ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); | 2321 | ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); |
2324 | 2322 | ||
2325 | #ifdef CONFIG_MAC80211_MESH | 2323 | if (ieee80211_vif_is_mesh(&sdata->vif) && elems.mesh_id && |
2326 | if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT && elems.mesh_id | 2324 | elems.mesh_config && mesh_matches_local(&elems, dev)) { |
2327 | && elems.mesh_config) | 2325 | u64 rates = ieee80211_sta_get_rates(local, &elems, |
2328 | if (mesh_matches_local(&elems, dev)) { | 2326 | rx_status->band); |
2329 | u64 rates = ieee80211_sta_get_rates(local, &elems, | 2327 | |
2330 | rx_status->band); | 2328 | mesh_neighbour_update(mgmt->sa, rates, dev, |
2331 | mesh_neighbour_update(mgmt->sa, rates, dev, | 2329 | mesh_peer_accepts_plinks(&elems, dev)); |
2332 | mesh_peer_accepts_plinks(&elems, dev)); | 2330 | } |
2333 | } | ||
2334 | #endif | ||
2335 | 2331 | ||
2336 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates && | 2332 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates && |
2337 | memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 && | 2333 | memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 && |
@@ -2712,9 +2708,7 @@ static void ieee80211_rx_mgmt_action(struct net_device *dev, | |||
2712 | size_t len, | 2708 | size_t len, |
2713 | struct ieee80211_rx_status *rx_status) | 2709 | struct ieee80211_rx_status *rx_status) |
2714 | { | 2710 | { |
2715 | #ifdef CONFIG_MAC80211_MESH | ||
2716 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 2711 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
2717 | #endif | ||
2718 | 2712 | ||
2719 | if (len < IEEE80211_MIN_ACTION_SIZE) | 2713 | if (len < IEEE80211_MIN_ACTION_SIZE) |
2720 | return; | 2714 | return; |
@@ -2747,17 +2741,14 @@ static void ieee80211_rx_mgmt_action(struct net_device *dev, | |||
2747 | break; | 2741 | break; |
2748 | } | 2742 | } |
2749 | break; | 2743 | break; |
2750 | #ifdef CONFIG_MAC80211_MESH | ||
2751 | case PLINK_CATEGORY: | 2744 | case PLINK_CATEGORY: |
2752 | if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT) | 2745 | if (ieee80211_vif_is_mesh(&sdata->vif)) |
2753 | mesh_rx_plink_frame(dev, mgmt, len, rx_status); | 2746 | mesh_rx_plink_frame(dev, mgmt, len, rx_status); |
2754 | break; | 2747 | break; |
2755 | |||
2756 | case MESH_PATH_SEL_CATEGORY: | 2748 | case MESH_PATH_SEL_CATEGORY: |
2757 | if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT) | 2749 | if (ieee80211_vif_is_mesh(&sdata->vif)) |
2758 | mesh_rx_path_sel_frame(dev, mgmt, len); | 2750 | mesh_rx_path_sel_frame(dev, mgmt, len); |
2759 | break; | 2751 | break; |
2760 | #endif | ||
2761 | default: | 2752 | default: |
2762 | if (net_ratelimit()) | 2753 | if (net_ratelimit()) |
2763 | printk(KERN_DEBUG "%s: Rx unknown action frame - " | 2754 | printk(KERN_DEBUG "%s: Rx unknown action frame - " |
@@ -3027,8 +3018,9 @@ void ieee80211_sta_work(struct work_struct *work) | |||
3027 | ieee80211_sta_rx_queued_mgmt(dev, skb); | 3018 | ieee80211_sta_rx_queued_mgmt(dev, skb); |
3028 | 3019 | ||
3029 | #ifdef CONFIG_MAC80211_MESH | 3020 | #ifdef CONFIG_MAC80211_MESH |
3030 | if (ifsta->preq_queue_len && time_after(jiffies, ifsta->last_preq + | 3021 | if (ifsta->preq_queue_len && |
3031 | msecs_to_jiffies(ifsta->mshcfg.dot11MeshHWMPpreqMinInterval))) | 3022 | time_after(jiffies, |
3023 | ifsta->last_preq + msecs_to_jiffies(ifsta->mshcfg.dot11MeshHWMPpreqMinInterval))) | ||
3032 | mesh_path_start_discovery(dev); | 3024 | mesh_path_start_discovery(dev); |
3033 | #endif | 3025 | #endif |
3034 | 3026 | ||
@@ -3810,13 +3802,11 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
3810 | 3802 | ||
3811 | memset(&iwe, 0, sizeof(iwe)); | 3803 | memset(&iwe, 0, sizeof(iwe)); |
3812 | iwe.cmd = SIOCGIWESSID; | 3804 | iwe.cmd = SIOCGIWESSID; |
3813 | if (bss->mesh_cfg) { | 3805 | if (bss_mesh_cfg(bss)) { |
3814 | #ifdef CONFIG_MAC80211_MESH | 3806 | iwe.u.data.length = bss_mesh_id_len(bss); |
3815 | iwe.u.data.length = bss->mesh_id_len; | ||
3816 | iwe.u.data.flags = 1; | 3807 | iwe.u.data.flags = 1; |
3817 | current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, | 3808 | current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, |
3818 | bss->mesh_id); | 3809 | bss_mesh_id(bss)); |
3819 | #endif | ||
3820 | } else { | 3810 | } else { |
3821 | iwe.u.data.length = bss->ssid_len; | 3811 | iwe.u.data.length = bss->ssid_len; |
3822 | iwe.u.data.flags = 1; | 3812 | iwe.u.data.flags = 1; |
@@ -3825,10 +3815,10 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
3825 | } | 3815 | } |
3826 | 3816 | ||
3827 | if (bss->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS | 3817 | if (bss->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS |
3828 | || bss->mesh_cfg)) { | 3818 | || bss_mesh_cfg(bss))) { |
3829 | memset(&iwe, 0, sizeof(iwe)); | 3819 | memset(&iwe, 0, sizeof(iwe)); |
3830 | iwe.cmd = SIOCGIWMODE; | 3820 | iwe.cmd = SIOCGIWMODE; |
3831 | if (bss->mesh_cfg) | 3821 | if (bss_mesh_cfg(bss)) |
3832 | iwe.u.mode = IW_MODE_MESH; | 3822 | iwe.u.mode = IW_MODE_MESH; |
3833 | else if (bss->capability & WLAN_CAPABILITY_ESS) | 3823 | else if (bss->capability & WLAN_CAPABILITY_ESS) |
3834 | iwe.u.mode = IW_MODE_MASTER; | 3824 | iwe.u.mode = IW_MODE_MASTER; |
@@ -3919,9 +3909,9 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
3919 | } | 3909 | } |
3920 | } | 3910 | } |
3921 | 3911 | ||
3922 | if (bss->mesh_cfg) { | 3912 | if (bss_mesh_cfg(bss)) { |
3923 | char *buf; | 3913 | char *buf; |
3924 | u8 *cfg = bss->mesh_cfg; | 3914 | u8 *cfg = bss_mesh_cfg(bss); |
3925 | buf = kmalloc(200, GFP_ATOMIC); | 3915 | buf = kmalloc(200, GFP_ATOMIC); |
3926 | if (buf) { | 3916 | if (buf) { |
3927 | memset(&iwe, 0, sizeof(iwe)); | 3917 | memset(&iwe, 0, sizeof(iwe)); |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 8ff533005d9..ebe1a7a80ba 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -381,3 +381,70 @@ endgrow: | |||
381 | else | 381 | else |
382 | return newtbl; | 382 | return newtbl; |
383 | } | 383 | } |
384 | |||
385 | /** | ||
386 | * ieee80211_new_mesh_header - create a new mesh header | ||
387 | * @meshhdr: uninitialized mesh header | ||
388 | * @sdata: mesh interface to be used | ||
389 | * | ||
390 | * Return the header length. | ||
391 | */ | ||
392 | int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, | ||
393 | struct ieee80211_sub_if_data *sdata) | ||
394 | { | ||
395 | meshhdr->flags = 0; | ||
396 | meshhdr->ttl = sdata->u.sta.mshcfg.dot11MeshTTL; | ||
397 | |||
398 | meshhdr->seqnum[0] = sdata->u.sta.mesh_seqnum[0]++; | ||
399 | meshhdr->seqnum[1] = sdata->u.sta.mesh_seqnum[1]; | ||
400 | meshhdr->seqnum[2] = sdata->u.sta.mesh_seqnum[2]; | ||
401 | |||
402 | if (sdata->u.sta.mesh_seqnum[0] == 0) { | ||
403 | sdata->u.sta.mesh_seqnum[1]++; | ||
404 | if (sdata->u.sta.mesh_seqnum[1] == 0) | ||
405 | sdata->u.sta.mesh_seqnum[2]++; | ||
406 | } | ||
407 | |||
408 | return 5; | ||
409 | } | ||
410 | |||
411 | void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata) | ||
412 | { | ||
413 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; | ||
414 | |||
415 | ifsta->mshcfg.dot11MeshRetryTimeout = MESH_RET_T; | ||
416 | ifsta->mshcfg.dot11MeshConfirmTimeout = MESH_CONF_T; | ||
417 | ifsta->mshcfg.dot11MeshHoldingTimeout = MESH_HOLD_T; | ||
418 | ifsta->mshcfg.dot11MeshMaxRetries = MESH_MAX_RETR; | ||
419 | ifsta->mshcfg.dot11MeshTTL = MESH_TTL; | ||
420 | ifsta->mshcfg.auto_open_plinks = true; | ||
421 | ifsta->mshcfg.dot11MeshMaxPeerLinks = | ||
422 | MESH_MAX_ESTAB_PLINKS; | ||
423 | ifsta->mshcfg.dot11MeshHWMPactivePathTimeout = | ||
424 | MESH_PATH_TIMEOUT; | ||
425 | ifsta->mshcfg.dot11MeshHWMPpreqMinInterval = | ||
426 | MESH_PREQ_MIN_INT; | ||
427 | ifsta->mshcfg.dot11MeshHWMPnetDiameterTraversalTime = | ||
428 | MESH_DIAM_TRAVERSAL_TIME; | ||
429 | ifsta->mshcfg.dot11MeshHWMPmaxPREQretries = | ||
430 | MESH_MAX_PREQ_RETRIES; | ||
431 | ifsta->mshcfg.path_refresh_time = | ||
432 | MESH_PATH_REFRESH_TIME; | ||
433 | ifsta->mshcfg.min_discovery_timeout = | ||
434 | MESH_MIN_DISCOVERY_TIMEOUT; | ||
435 | ifsta->accepting_plinks = true; | ||
436 | ifsta->preq_id = 0; | ||
437 | ifsta->dsn = 0; | ||
438 | atomic_set(&ifsta->mpaths, 0); | ||
439 | mesh_rmc_init(sdata->dev); | ||
440 | ifsta->last_preq = jiffies; | ||
441 | /* Allocate all mesh structures when creating the first mesh interface. */ | ||
442 | if (!mesh_allocated) | ||
443 | ieee80211s_init(); | ||
444 | mesh_ids_set_default(ifsta); | ||
445 | setup_timer(&ifsta->mesh_path_timer, | ||
446 | ieee80211_mesh_path_timer, | ||
447 | (unsigned long) sdata); | ||
448 | INIT_LIST_HEAD(&ifsta->preq_queue.list); | ||
449 | spin_lock_init(&ifsta->mesh_preq_queue_lock); | ||
450 | } | ||
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index ac892379390..d565b3fb9e6 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h | |||
@@ -11,10 +11,10 @@ | |||
11 | #ifndef IEEE80211S_H | 11 | #ifndef IEEE80211S_H |
12 | #define IEEE80211S_H | 12 | #define IEEE80211S_H |
13 | 13 | ||
14 | #include "ieee80211_i.h" | 14 | #include <linux/types.h> |
15 | #include <linux/jhash.h> | 15 | #include <linux/jhash.h> |
16 | #include "ieee80211_i.h" | ||
16 | 17 | ||
17 | extern int mesh_allocated; | ||
18 | 18 | ||
19 | /* Data structures */ | 19 | /* Data structures */ |
20 | 20 | ||
@@ -211,6 +211,8 @@ void mesh_rmc_free(struct net_device *dev); | |||
211 | int mesh_rmc_init(struct net_device *dev); | 211 | int mesh_rmc_init(struct net_device *dev); |
212 | void ieee80211s_init(void); | 212 | void ieee80211s_init(void); |
213 | void ieee80211s_stop(void); | 213 | void ieee80211s_stop(void); |
214 | void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata); | ||
215 | |||
214 | /* Mesh paths */ | 216 | /* Mesh paths */ |
215 | int mesh_nexthop_lookup(u8 *next_hop, struct sk_buff *skb, | 217 | int mesh_nexthop_lookup(u8 *next_hop, struct sk_buff *skb, |
216 | struct net_device *dev); | 218 | struct net_device *dev); |
@@ -257,6 +259,9 @@ void mesh_path_timer(unsigned long data); | |||
257 | void mesh_path_flush_by_nexthop(struct sta_info *sta); | 259 | void mesh_path_flush_by_nexthop(struct sta_info *sta); |
258 | void mesh_path_discard_frame(struct sk_buff *skb, struct net_device *dev); | 260 | void mesh_path_discard_frame(struct sk_buff *skb, struct net_device *dev); |
259 | 261 | ||
262 | #ifdef CONFIG_MAC80211_MESH | ||
263 | extern int mesh_allocated; | ||
264 | |||
260 | static inline int mesh_plink_free_count(struct ieee80211_sub_if_data *sdata) | 265 | static inline int mesh_plink_free_count(struct ieee80211_sub_if_data *sdata) |
261 | { | 266 | { |
262 | return sdata->u.sta.mshcfg.dot11MeshMaxPeerLinks - | 267 | return sdata->u.sta.mshcfg.dot11MeshMaxPeerLinks - |
@@ -278,6 +283,10 @@ static inline void mesh_path_activate(struct mesh_path *mpath) | |||
278 | for (i = 0; i <= x->hash_mask; i++) \ | 283 | for (i = 0; i <= x->hash_mask; i++) \ |
279 | hlist_for_each_entry_rcu(node, p, &x->hash_buckets[i], list) | 284 | hlist_for_each_entry_rcu(node, p, &x->hash_buckets[i], list) |
280 | 285 | ||
286 | #else | ||
287 | #define mesh_allocated 0 | ||
288 | #endif | ||
289 | |||
281 | #define MESH_PREQ(skb) (skb->cb + 30) | 290 | #define MESH_PREQ(skb) (skb->cb + 30) |
282 | 291 | ||
283 | #endif /* IEEE80211S_H */ | 292 | #endif /* IEEE80211S_H */ |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 5cd97e99be6..0b0e8d7eb9c 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -6,11 +6,11 @@ | |||
6 | * it under the terms of the GNU General Public License version 2 as | 6 | * it under the terms of the GNU General Public License version 2 as |
7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
8 | */ | 8 | */ |
9 | 9 | #include <linux/kernel.h> | |
10 | #include <linux/random.h> | ||
10 | #include "ieee80211_i.h" | 11 | #include "ieee80211_i.h" |
11 | #include "ieee80211_rate.h" | 12 | #include "ieee80211_rate.h" |
12 | #include "mesh.h" | 13 | #include "mesh.h" |
13 | #include <linux/random.h> | ||
14 | 14 | ||
15 | #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG | 15 | #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG |
16 | #define mpl_dbg(fmt, args...) printk(KERN_DEBUG fmt, ##args) | 16 | #define mpl_dbg(fmt, args...) printk(KERN_DEBUG fmt, ##args) |
@@ -131,7 +131,7 @@ struct sta_info *mesh_plink_add(u8 *hw_addr, u64 rates, struct net_device *dev) | |||
131 | } | 131 | } |
132 | 132 | ||
133 | /** | 133 | /** |
134 | * mesh_plink_deactivate - deactivate mesh peer link | 134 | * __mesh_plink_deactivate - deactivate mesh peer link |
135 | * | 135 | * |
136 | * @sta: mesh peer link to deactivate | 136 | * @sta: mesh peer link to deactivate |
137 | * | 137 | * |
@@ -139,7 +139,7 @@ struct sta_info *mesh_plink_add(u8 *hw_addr, u64 rates, struct net_device *dev) | |||
139 | * | 139 | * |
140 | * Locking: the caller must hold sta->plink_lock | 140 | * Locking: the caller must hold sta->plink_lock |
141 | */ | 141 | */ |
142 | void mesh_plink_deactivate(struct sta_info *sta) | 142 | static void __mesh_plink_deactivate(struct sta_info *sta) |
143 | { | 143 | { |
144 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); | 144 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); |
145 | if (sta->plink_state == ESTAB) | 145 | if (sta->plink_state == ESTAB) |
@@ -148,6 +148,20 @@ void mesh_plink_deactivate(struct sta_info *sta) | |||
148 | mesh_path_flush_by_nexthop(sta); | 148 | mesh_path_flush_by_nexthop(sta); |
149 | } | 149 | } |
150 | 150 | ||
151 | /** | ||
152 | * __mesh_plink_deactivate - deactivate mesh peer link | ||
153 | * | ||
154 | * @sta: mesh peer link to deactivate | ||
155 | * | ||
156 | * All mesh paths with this peer as next hop will be flushed | ||
157 | */ | ||
158 | void mesh_plink_deactivate(struct sta_info *sta) | ||
159 | { | ||
160 | spin_lock_bh(&sta->plink_lock); | ||
161 | __mesh_plink_deactivate(sta); | ||
162 | spin_unlock_bh(&sta->plink_lock); | ||
163 | } | ||
164 | |||
151 | static int mesh_plink_frame_tx(struct net_device *dev, | 165 | static int mesh_plink_frame_tx(struct net_device *dev, |
152 | enum plink_frame_type action, u8 *da, __le16 llid, __le16 plid, | 166 | enum plink_frame_type action, u8 *da, __le16 llid, __le16 plid, |
153 | __le16 reason) { | 167 | __le16 reason) { |
@@ -365,7 +379,7 @@ void mesh_plink_block(struct sta_info *sta) | |||
365 | #endif | 379 | #endif |
366 | 380 | ||
367 | spin_lock_bh(&sta->plink_lock); | 381 | spin_lock_bh(&sta->plink_lock); |
368 | mesh_plink_deactivate(sta); | 382 | __mesh_plink_deactivate(sta); |
369 | sta->plink_state = BLOCKED; | 383 | sta->plink_state = BLOCKED; |
370 | spin_unlock_bh(&sta->plink_lock); | 384 | spin_unlock_bh(&sta->plink_lock); |
371 | } | 385 | } |
@@ -390,7 +404,7 @@ int mesh_plink_close(struct sta_info *sta) | |||
390 | sta_info_put(sta); | 404 | sta_info_put(sta); |
391 | return 0; | 405 | return 0; |
392 | } else if (sta->plink_state == ESTAB) { | 406 | } else if (sta->plink_state == ESTAB) { |
393 | mesh_plink_deactivate(sta); | 407 | __mesh_plink_deactivate(sta); |
394 | /* The timer should not be running */ | 408 | /* The timer should not be running */ |
395 | if (!mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata))) | 409 | if (!mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata))) |
396 | __sta_info_get(sta); | 410 | __sta_info_get(sta); |
@@ -699,7 +713,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
699 | case CLS_ACPT: | 713 | case CLS_ACPT: |
700 | reason = cpu_to_le16(MESH_CLOSE_RCVD); | 714 | reason = cpu_to_le16(MESH_CLOSE_RCVD); |
701 | sta->reason = reason; | 715 | sta->reason = reason; |
702 | mesh_plink_deactivate(sta); | 716 | __mesh_plink_deactivate(sta); |
703 | sta->plink_state = HOLDING; | 717 | sta->plink_state = HOLDING; |
704 | llid = sta->llid; | 718 | llid = sta->llid; |
705 | if (!mod_plink_timer(sta, | 719 | if (!mod_plink_timer(sta, |
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c index 4a51647a41a..217c0f487bb 100644 --- a/net/mac80211/rc80211_pid_algo.c +++ b/net/mac80211/rc80211_pid_algo.c | |||
@@ -15,10 +15,7 @@ | |||
15 | #include <linux/debugfs.h> | 15 | #include <linux/debugfs.h> |
16 | #include <net/mac80211.h> | 16 | #include <net/mac80211.h> |
17 | #include "ieee80211_rate.h" | 17 | #include "ieee80211_rate.h" |
18 | #ifdef CONFIG_MAC80211_MESH | ||
19 | #include "mesh.h" | 18 | #include "mesh.h" |
20 | #endif | ||
21 | |||
22 | #include "rc80211_pid.h" | 19 | #include "rc80211_pid.h" |
23 | 20 | ||
24 | 21 | ||
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index cc4a896c617..d0018fc40b0 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -20,9 +20,7 @@ | |||
20 | 20 | ||
21 | #include "ieee80211_i.h" | 21 | #include "ieee80211_i.h" |
22 | #include "ieee80211_led.h" | 22 | #include "ieee80211_led.h" |
23 | #ifdef CONFIG_MAC80211_MESH | ||
24 | #include "mesh.h" | 23 | #include "mesh.h" |
25 | #endif | ||
26 | #include "wep.h" | 24 | #include "wep.h" |
27 | #include "wpa.h" | 25 | #include "wpa.h" |
28 | #include "tkip.h" | 26 | #include "tkip.h" |
@@ -439,6 +437,13 @@ ieee80211_rx_mesh_check(struct ieee80211_txrx_data *rx) | |||
439 | else | 437 | else |
440 | return RX_CONTINUE; | 438 | return RX_CONTINUE; |
441 | } | 439 | } |
440 | #undef msh_h_get | ||
441 | #else | ||
442 | static inline ieee80211_rx_result | ||
443 | ieee80211_rx_mesh_check(struct ieee80211_txrx_data *rx) | ||
444 | { | ||
445 | return RX_CONTINUE; | ||
446 | } | ||
442 | #endif | 447 | #endif |
443 | 448 | ||
444 | 449 | ||
@@ -477,10 +482,8 @@ ieee80211_rx_h_check(struct ieee80211_txrx_data *rx) | |||
477 | * responsible for filtering on both auth and assoc states. | 482 | * responsible for filtering on both auth and assoc states. |
478 | */ | 483 | */ |
479 | 484 | ||
480 | #ifdef CONFIG_MAC80211_MESH | 485 | if (ieee80211_vif_is_mesh(&rx->sdata->vif)) |
481 | if (rx->sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT) | ||
482 | return ieee80211_rx_mesh_check(rx); | 486 | return ieee80211_rx_mesh_check(rx); |
483 | #endif | ||
484 | 487 | ||
485 | if (unlikely(((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA || | 488 | if (unlikely(((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA || |
486 | ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL && | 489 | ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL && |
@@ -1111,8 +1114,7 @@ ieee80211_data_to_8023(struct ieee80211_txrx_data *rx) | |||
1111 | 1114 | ||
1112 | hdrlen = ieee80211_get_hdrlen(fc); | 1115 | hdrlen = ieee80211_get_hdrlen(fc); |
1113 | 1116 | ||
1114 | #ifdef CONFIG_MAC80211_MESH | 1117 | if (ieee80211_vif_is_mesh(&sdata->vif)) { |
1115 | if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT) { | ||
1116 | int meshhdrlen = ieee80211_get_mesh_hdrlen( | 1118 | int meshhdrlen = ieee80211_get_mesh_hdrlen( |
1117 | (struct ieee80211s_hdr *) (skb->data + hdrlen)); | 1119 | (struct ieee80211s_hdr *) (skb->data + hdrlen)); |
1118 | /* Copy on cb: | 1120 | /* Copy on cb: |
@@ -1126,7 +1128,6 @@ ieee80211_data_to_8023(struct ieee80211_txrx_data *rx) | |||
1126 | memcpy(MESH_PREQ(skb), hdr->addr2, ETH_ALEN); | 1128 | memcpy(MESH_PREQ(skb), hdr->addr2, ETH_ALEN); |
1127 | hdrlen += meshhdrlen; | 1129 | hdrlen += meshhdrlen; |
1128 | } | 1130 | } |
1129 | #endif | ||
1130 | 1131 | ||
1131 | /* convert IEEE 802.11 header + possible LLC headers into Ethernet | 1132 | /* convert IEEE 802.11 header + possible LLC headers into Ethernet |
1132 | * header | 1133 | * header |
@@ -1306,9 +1307,8 @@ ieee80211_deliver_skb(struct ieee80211_txrx_data *rx) | |||
1306 | } | 1307 | } |
1307 | } | 1308 | } |
1308 | 1309 | ||
1309 | #ifdef CONFIG_MAC80211_MESH | ||
1310 | /* Mesh forwarding */ | 1310 | /* Mesh forwarding */ |
1311 | if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT) { | 1311 | if (ieee80211_vif_is_mesh(&sdata->vif)) { |
1312 | u8 *mesh_ttl = &((struct ieee80211s_hdr *)skb->cb)->ttl; | 1312 | u8 *mesh_ttl = &((struct ieee80211s_hdr *)skb->cb)->ttl; |
1313 | (*mesh_ttl)--; | 1313 | (*mesh_ttl)--; |
1314 | 1314 | ||
@@ -1321,12 +1321,13 @@ ieee80211_deliver_skb(struct ieee80211_txrx_data *rx) | |||
1321 | else | 1321 | else |
1322 | xmit_skb->pkt_type = PACKET_OTHERHOST; | 1322 | xmit_skb->pkt_type = PACKET_OTHERHOST; |
1323 | } else | 1323 | } else |
1324 | sdata->u.sta.mshstats.dropped_frames_ttl++; | 1324 | IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.sta, |
1325 | 1325 | dropped_frames_ttl); | |
1326 | } else if (skb->pkt_type != PACKET_OTHERHOST && | 1326 | } else if (skb->pkt_type != PACKET_OTHERHOST && |
1327 | compare_ether_addr(dev->dev_addr, skb->data) != 0) { | 1327 | compare_ether_addr(dev->dev_addr, skb->data) != 0) { |
1328 | if (*mesh_ttl == 0) { | 1328 | if (*mesh_ttl == 0) { |
1329 | sdata->u.sta.mshstats.dropped_frames_ttl++; | 1329 | IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.sta, |
1330 | dropped_frames_ttl); | ||
1330 | dev_kfree_skb(skb); | 1331 | dev_kfree_skb(skb); |
1331 | skb = NULL; | 1332 | skb = NULL; |
1332 | } else { | 1333 | } else { |
@@ -1337,7 +1338,6 @@ ieee80211_deliver_skb(struct ieee80211_txrx_data *rx) | |||
1337 | } | 1338 | } |
1338 | } | 1339 | } |
1339 | } | 1340 | } |
1340 | #endif | ||
1341 | 1341 | ||
1342 | if (skb) { | 1342 | if (skb) { |
1343 | /* deliver to local stack */ | 1343 | /* deliver to local stack */ |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 1f3c9eb9850..81c4e3392f4 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -21,9 +21,7 @@ | |||
21 | #include "ieee80211_rate.h" | 21 | #include "ieee80211_rate.h" |
22 | #include "sta_info.h" | 22 | #include "sta_info.h" |
23 | #include "debugfs_sta.h" | 23 | #include "debugfs_sta.h" |
24 | #ifdef CONFIG_MAC80211_MESH | ||
25 | #include "mesh.h" | 24 | #include "mesh.h" |
26 | #endif | ||
27 | 25 | ||
28 | /* Caller must hold local->sta_lock */ | 26 | /* Caller must hold local->sta_lock */ |
29 | static void sta_info_hash_add(struct ieee80211_local *local, | 27 | static void sta_info_hash_add(struct ieee80211_local *local, |
@@ -309,10 +307,8 @@ void sta_info_remove(struct sta_info *sta) | |||
309 | } | 307 | } |
310 | local->num_sta--; | 308 | local->num_sta--; |
311 | 309 | ||
312 | #ifdef CONFIG_MAC80211_MESH | 310 | if (ieee80211_vif_is_mesh(&sdata->vif)) |
313 | if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT) | ||
314 | mesh_accept_plinks_update(sdata->dev); | 311 | mesh_accept_plinks_update(sdata->dev); |
315 | #endif | ||
316 | } | 312 | } |
317 | 313 | ||
318 | void sta_info_free(struct sta_info *sta) | 314 | void sta_info_free(struct sta_info *sta) |
@@ -329,13 +325,8 @@ void sta_info_free(struct sta_info *sta) | |||
329 | sta_info_remove(sta); | 325 | sta_info_remove(sta); |
330 | write_unlock_bh(&local->sta_lock); | 326 | write_unlock_bh(&local->sta_lock); |
331 | 327 | ||
332 | #ifdef CONFIG_MAC80211_MESH | 328 | if (ieee80211_vif_is_mesh(&sdata->vif)) |
333 | if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT) { | ||
334 | spin_lock_bh(&sta->plink_lock); | ||
335 | mesh_plink_deactivate(sta); | 329 | mesh_plink_deactivate(sta); |
336 | spin_unlock_bh(&sta->plink_lock); | ||
337 | } | ||
338 | #endif | ||
339 | 330 | ||
340 | while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) { | 331 | while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) { |
341 | local->total_ps_buffered--; | 332 | local->total_ps_buffered--; |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 9d1d7a0e311..4ad500373d5 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -107,7 +107,6 @@ struct tid_ampdu_rx { | |||
107 | struct timer_list session_timer; | 107 | struct timer_list session_timer; |
108 | }; | 108 | }; |
109 | 109 | ||
110 | #ifdef CONFIG_MAC80211_MESH | ||
111 | enum plink_state { | 110 | enum plink_state { |
112 | LISTEN, | 111 | LISTEN, |
113 | OPN_SNT, | 112 | OPN_SNT, |
@@ -117,7 +116,6 @@ enum plink_state { | |||
117 | HOLDING, | 116 | HOLDING, |
118 | BLOCKED | 117 | BLOCKED |
119 | }; | 118 | }; |
120 | #endif | ||
121 | 119 | ||
122 | /** | 120 | /** |
123 | * struct sta_ampdu_mlme - STA aggregation information. | 121 | * struct sta_ampdu_mlme - STA aggregation information. |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index fc1ffb55ed5..3b06e0d8f35 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -26,9 +26,7 @@ | |||
26 | 26 | ||
27 | #include "ieee80211_i.h" | 27 | #include "ieee80211_i.h" |
28 | #include "ieee80211_led.h" | 28 | #include "ieee80211_led.h" |
29 | #ifdef CONFIG_MAC80211_MESH | ||
30 | #include "mesh.h" | 29 | #include "mesh.h" |
31 | #endif | ||
32 | #include "wep.h" | 30 | #include "wep.h" |
33 | #include "wpa.h" | 31 | #include "wpa.h" |
34 | #include "wme.h" | 32 | #include "wme.h" |
@@ -1460,7 +1458,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1460 | goto fail; | 1458 | goto fail; |
1461 | } | 1459 | } |
1462 | meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, | 1460 | meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, |
1463 | sdata); | 1461 | sdata); |
1464 | } | 1462 | } |
1465 | hdrlen = 30; | 1463 | hdrlen = 30; |
1466 | break; | 1464 | break; |
@@ -1778,40 +1776,6 @@ static void ieee80211_beacon_add_tim(struct ieee80211_local *local, | |||
1778 | read_unlock_bh(&local->sta_lock); | 1776 | read_unlock_bh(&local->sta_lock); |
1779 | } | 1777 | } |
1780 | 1778 | ||
1781 | #ifdef CONFIG_MAC80211_MESH | ||
1782 | static struct sk_buff *ieee80211_mesh_beacon_get(struct net_device *dev) | ||
1783 | { | ||
1784 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
1785 | struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); | ||
1786 | struct ieee80211_mgmt *mgmt; | ||
1787 | u8 *pos; | ||
1788 | |||
1789 | if (!skb) | ||
1790 | return NULL; | ||
1791 | skb_reserve(skb, local->hw.extra_tx_headroom); | ||
1792 | mgmt = (struct ieee80211_mgmt *) | ||
1793 | skb_put(skb, 24 + sizeof(mgmt->u.beacon)); | ||
1794 | memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); | ||
1795 | mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, | ||
1796 | IEEE80211_STYPE_BEACON); | ||
1797 | memset(mgmt->da, 0xff, ETH_ALEN); | ||
1798 | memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); | ||
1799 | /* BSSID is left zeroed, wildcard value */ | ||
1800 | mgmt->u.beacon.beacon_int = | ||
1801 | cpu_to_le16(local->hw.conf.beacon_int); | ||
1802 | mgmt->u.beacon.capab_info = 0x0; /* 0x0 for MPs */ | ||
1803 | |||
1804 | pos = skb_put(skb, 2); | ||
1805 | *pos++ = WLAN_EID_SSID; | ||
1806 | *pos++ = 0x0; | ||
1807 | |||
1808 | mesh_mgmt_ies_add(skb, dev); | ||
1809 | |||
1810 | return skb; | ||
1811 | } | ||
1812 | #endif | ||
1813 | |||
1814 | |||
1815 | struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | 1779 | struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, |
1816 | struct ieee80211_vif *vif, | 1780 | struct ieee80211_vif *vif, |
1817 | struct ieee80211_tx_control *control) | 1781 | struct ieee80211_tx_control *control) |
@@ -1824,8 +1788,10 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1824 | struct rate_selection rsel; | 1788 | struct rate_selection rsel; |
1825 | struct beacon_data *beacon; | 1789 | struct beacon_data *beacon; |
1826 | struct ieee80211_supported_band *sband; | 1790 | struct ieee80211_supported_band *sband; |
1791 | struct ieee80211_mgmt *mgmt; | ||
1827 | int *num_beacons; | 1792 | int *num_beacons; |
1828 | int err = 0; | 1793 | bool err = true; |
1794 | u8 *pos; | ||
1829 | 1795 | ||
1830 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | 1796 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
1831 | 1797 | ||
@@ -1834,47 +1800,65 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1834 | sdata = vif_to_sdata(vif); | 1800 | sdata = vif_to_sdata(vif); |
1835 | bdev = sdata->dev; | 1801 | bdev = sdata->dev; |
1836 | 1802 | ||
1837 | switch (sdata->vif.type) { | 1803 | if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { |
1838 | case IEEE80211_IF_TYPE_AP: | ||
1839 | ap = &sdata->u.ap; | 1804 | ap = &sdata->u.ap; |
1840 | beacon = rcu_dereference(ap->beacon); | 1805 | beacon = rcu_dereference(ap->beacon); |
1841 | if (!ap || !beacon) { | 1806 | if (ap && beacon) { |
1842 | err = -1; | 1807 | /* |
1843 | break; | 1808 | * headroom, head length, |
1844 | } | 1809 | * tail length and maximum TIM length |
1810 | */ | ||
1811 | skb = dev_alloc_skb(local->tx_headroom + | ||
1812 | beacon->head_len + | ||
1813 | beacon->tail_len + 256); | ||
1814 | if (!skb) | ||
1815 | goto out; | ||
1845 | 1816 | ||
1846 | /* headroom, head length, tail length and maximum TIM length */ | 1817 | skb_reserve(skb, local->tx_headroom); |
1847 | skb = dev_alloc_skb(local->tx_headroom + beacon->head_len + | 1818 | memcpy(skb_put(skb, beacon->head_len), beacon->head, |
1848 | beacon->tail_len + 256); | 1819 | beacon->head_len); |
1849 | if (!skb) | ||
1850 | goto out; | ||
1851 | 1820 | ||
1852 | skb_reserve(skb, local->tx_headroom); | 1821 | ieee80211_include_sequence(sdata, |
1853 | memcpy(skb_put(skb, beacon->head_len), beacon->head, | 1822 | (struct ieee80211_hdr *)skb->data); |
1854 | beacon->head_len); | ||
1855 | 1823 | ||
1856 | ieee80211_include_sequence(sdata, | 1824 | ieee80211_beacon_add_tim(local, ap, skb, beacon); |
1857 | (struct ieee80211_hdr *)skb->data); | ||
1858 | 1825 | ||
1859 | ieee80211_beacon_add_tim(local, ap, skb, beacon); | 1826 | if (beacon->tail) |
1827 | memcpy(skb_put(skb, beacon->tail_len), | ||
1828 | beacon->tail, beacon->tail_len); | ||
1860 | 1829 | ||
1861 | if (beacon->tail) | 1830 | num_beacons = &ap->num_beacons; |
1862 | memcpy(skb_put(skb, beacon->tail_len), beacon->tail, | ||
1863 | beacon->tail_len); | ||
1864 | 1831 | ||
1865 | num_beacons = &ap->num_beacons; | 1832 | err = false; |
1866 | break; | 1833 | } |
1834 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) { | ||
1835 | /* headroom, head length, tail length and maximum TIM length */ | ||
1836 | skb = dev_alloc_skb(local->tx_headroom + 400); | ||
1837 | if (!skb) | ||
1838 | goto out; | ||
1839 | |||
1840 | skb_reserve(skb, local->hw.extra_tx_headroom); | ||
1841 | mgmt = (struct ieee80211_mgmt *) | ||
1842 | skb_put(skb, 24 + sizeof(mgmt->u.beacon)); | ||
1843 | memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); | ||
1844 | mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, | ||
1845 | IEEE80211_STYPE_BEACON); | ||
1846 | memset(mgmt->da, 0xff, ETH_ALEN); | ||
1847 | memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); | ||
1848 | /* BSSID is left zeroed, wildcard value */ | ||
1849 | mgmt->u.beacon.beacon_int = | ||
1850 | cpu_to_le16(local->hw.conf.beacon_int); | ||
1851 | mgmt->u.beacon.capab_info = 0x0; /* 0x0 for MPs */ | ||
1852 | |||
1853 | pos = skb_put(skb, 2); | ||
1854 | *pos++ = WLAN_EID_SSID; | ||
1855 | *pos++ = 0x0; | ||
1856 | |||
1857 | mesh_mgmt_ies_add(skb, sdata->dev); | ||
1867 | 1858 | ||
1868 | #ifdef CONFIG_MAC80211_MESH | ||
1869 | case IEEE80211_IF_TYPE_MESH_POINT: | ||
1870 | skb = ieee80211_mesh_beacon_get(bdev); | ||
1871 | num_beacons = &sdata->u.sta.num_beacons; | 1859 | num_beacons = &sdata->u.sta.num_beacons; |
1872 | break; | ||
1873 | #endif | ||
1874 | 1860 | ||
1875 | default: | 1861 | err = false; |
1876 | err = -1; | ||
1877 | break; | ||
1878 | } | 1862 | } |
1879 | 1863 | ||
1880 | if (err) { | 1864 | if (err) { |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 6b50b6c12da..b46496fa2e1 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -26,9 +26,7 @@ | |||
26 | 26 | ||
27 | #include "ieee80211_i.h" | 27 | #include "ieee80211_i.h" |
28 | #include "ieee80211_rate.h" | 28 | #include "ieee80211_rate.h" |
29 | #ifdef CONFIG_MAC80211_MESH | ||
30 | #include "mesh.h" | 29 | #include "mesh.h" |
31 | #endif | ||
32 | #include "wme.h" | 30 | #include "wme.h" |
33 | 31 | ||
34 | /* privid for wiphys to determine whether they belong to us or not */ | 32 | /* privid for wiphys to determine whether they belong to us or not */ |
@@ -149,7 +147,6 @@ int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb) | |||
149 | } | 147 | } |
150 | EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb); | 148 | EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb); |
151 | 149 | ||
152 | #ifdef CONFIG_MAC80211_MESH | ||
153 | int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) | 150 | int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) |
154 | { | 151 | { |
155 | int ae = meshhdr->flags & IEEE80211S_FLAGS_AE; | 152 | int ae = meshhdr->flags & IEEE80211S_FLAGS_AE; |
@@ -167,7 +164,6 @@ int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) | |||
167 | return 5; | 164 | return 5; |
168 | } | 165 | } |
169 | } | 166 | } |
170 | #endif | ||
171 | 167 | ||
172 | void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx) | 168 | void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx) |
173 | { | 169 | { |
@@ -418,31 +414,3 @@ void ieee80211_iterate_active_interfaces( | |||
418 | rcu_read_unlock(); | 414 | rcu_read_unlock(); |
419 | } | 415 | } |
420 | EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces); | 416 | EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces); |
421 | |||
422 | #ifdef CONFIG_MAC80211_MESH | ||
423 | /** | ||
424 | * ieee80211_new_mesh_header - create a new mesh header | ||
425 | * @meshhdr: uninitialized mesh header | ||
426 | * @sdata: mesh interface to be used | ||
427 | * | ||
428 | * Return the header length. | ||
429 | */ | ||
430 | int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, | ||
431 | struct ieee80211_sub_if_data *sdata) | ||
432 | { | ||
433 | meshhdr->flags = 0; | ||
434 | meshhdr->ttl = sdata->u.sta.mshcfg.dot11MeshTTL; | ||
435 | |||
436 | meshhdr->seqnum[0] = sdata->u.sta.mesh_seqnum[0]++; | ||
437 | meshhdr->seqnum[1] = sdata->u.sta.mesh_seqnum[1]; | ||
438 | meshhdr->seqnum[2] = sdata->u.sta.mesh_seqnum[2]; | ||
439 | |||
440 | if (sdata->u.sta.mesh_seqnum[0] == 0) { | ||
441 | sdata->u.sta.mesh_seqnum[1]++; | ||
442 | if (sdata->u.sta.mesh_seqnum[1] == 0) | ||
443 | sdata->u.sta.mesh_seqnum[2]++; | ||
444 | } | ||
445 | |||
446 | return 5; | ||
447 | } | ||
448 | #endif | ||