aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/mac80211.h8
-rw-r--r--net/mac80211/cfg.c32
-rw-r--r--net/mac80211/ieee80211.c9
-rw-r--r--net/mac80211/ieee80211_i.h56
-rw-r--r--net/mac80211/ieee80211_iface.c66
-rw-r--r--net/mac80211/ieee80211_sta.c72
-rw-r--r--net/mac80211/mesh.c67
-rw-r--r--net/mac80211/mesh.h13
-rw-r--r--net/mac80211/mesh_plink.c28
-rw-r--r--net/mac80211/rc80211_pid_algo.c3
-rw-r--r--net/mac80211/rx.c28
-rw-r--r--net/mac80211/sta_info.c13
-rw-r--r--net/mac80211/sta_info.h2
-rw-r--r--net/mac80211/tx.c120
-rw-r--r--net/mac80211/util.c32
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
468static 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
318static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) 312static 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
638static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, 626static 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
115static 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
123static 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
131static 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
117typedef unsigned __bitwise__ ieee80211_tx_result; 140typedef 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
237struct mesh_stats { 259struct 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
253struct mesh_config { 274struct 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
385static 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);
884u64 ieee80211_sta_get_rates(struct ieee80211_local *local, 921u64 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);
887void ieee80211_start_mesh(struct net_device *dev);
888void ieee80211_sta_tx(struct net_device *dev, struct sk_buff *skb, 924void ieee80211_sta_tx(struct net_device *dev, struct sk_buff *skb,
889 int encrypt); 925 int encrypt);
890void ieee802_11_parse_elems(u8 *start, size_t len, 926void 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
930void ieee80211_start_mesh(struct net_device *dev);
931#else
932static inline void ieee80211_start_mesh(struct net_device *dev)
933{}
934#endif
893 935
894/* ieee80211_iface.c */ 936/* ieee80211_iface.c */
895int ieee80211_if_add(struct net_device *dev, const char *name, 937int 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
22void ieee80211_if_sdata_init(struct ieee80211_sub_if_data *sdata) 20void 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 */
392int 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
411void 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
17extern 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);
211int mesh_rmc_init(struct net_device *dev); 211int mesh_rmc_init(struct net_device *dev);
212void ieee80211s_init(void); 212void ieee80211s_init(void);
213void ieee80211s_stop(void); 213void ieee80211s_stop(void);
214void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata);
215
214/* Mesh paths */ 216/* Mesh paths */
215int mesh_nexthop_lookup(u8 *next_hop, struct sk_buff *skb, 217int 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);
257void mesh_path_flush_by_nexthop(struct sta_info *sta); 259void mesh_path_flush_by_nexthop(struct sta_info *sta);
258void mesh_path_discard_frame(struct sk_buff *skb, struct net_device *dev); 260void mesh_path_discard_frame(struct sk_buff *skb, struct net_device *dev);
259 261
262#ifdef CONFIG_MAC80211_MESH
263extern int mesh_allocated;
264
260static inline int mesh_plink_free_count(struct ieee80211_sub_if_data *sdata) 265static 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 */
142void mesh_plink_deactivate(struct sta_info *sta) 142static 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 */
158void 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
151static int mesh_plink_frame_tx(struct net_device *dev, 165static 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
442static inline ieee80211_rx_result
443ieee80211_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 */
29static void sta_info_hash_add(struct ieee80211_local *local, 27static 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
318void sta_info_free(struct sta_info *sta) 314void 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
111enum plink_state { 110enum 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
1782static 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
1815struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, 1779struct 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}
150EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb); 148EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb);
151 149
152#ifdef CONFIG_MAC80211_MESH
153int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) 150int 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
172void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx) 168void 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}
420EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces); 416EXPORT_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 */
430int 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