diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/cfg.c | 2 | ||||
-rw-r--r-- | net/mac80211/debugfs_netdev.c | 34 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 41 | ||||
-rw-r--r-- | net/mac80211/iface.c | 64 | ||||
-rw-r--r-- | net/mac80211/main.c | 96 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 56 | ||||
-rw-r--r-- | net/mac80211/rc80211_pid_algo.c | 8 | ||||
-rw-r--r-- | net/mac80211/rx.c | 15 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 29 | ||||
-rw-r--r-- | net/mac80211/tx.c | 11 | ||||
-rw-r--r-- | net/mac80211/util.c | 4 | ||||
-rw-r--r-- | net/mac80211/wext.c | 10 |
12 files changed, 153 insertions, 217 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 81087281b031..3c95cd9bf8ee 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -57,7 +57,7 @@ static int ieee80211_add_iface(struct wiphy *wiphy, char *name, | |||
57 | if (itype == IEEE80211_IF_TYPE_INVALID) | 57 | if (itype == IEEE80211_IF_TYPE_INVALID) |
58 | return -EINVAL; | 58 | return -EINVAL; |
59 | 59 | ||
60 | err = ieee80211_if_add(local->mdev, name, &dev, itype, params); | 60 | err = ieee80211_if_add(local, name, &dev, itype, params); |
61 | if (err || itype != IEEE80211_IF_TYPE_MNTR || !flags) | 61 | if (err || itype != IEEE80211_IF_TYPE_MNTR || !flags) |
62 | return err; | 62 | return err; |
63 | 63 | ||
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index b2089b2da48a..4aa6621f9970 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c | |||
@@ -156,6 +156,8 @@ static const struct file_operations name##_ops = { \ | |||
156 | 156 | ||
157 | /* common attributes */ | 157 | /* common attributes */ |
158 | IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC); | 158 | IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC); |
159 | IEEE80211_IF_FILE(force_unicast_rateidx, force_unicast_rateidx, DEC); | ||
160 | IEEE80211_IF_FILE(max_ratectrl_rateidx, max_ratectrl_rateidx, DEC); | ||
159 | 161 | ||
160 | /* STA/IBSS attributes */ | 162 | /* STA/IBSS attributes */ |
161 | IEEE80211_IF_FILE(state, u.sta.state, DEC); | 163 | IEEE80211_IF_FILE(state, u.sta.state, DEC); |
@@ -191,8 +193,6 @@ __IEEE80211_IF_FILE(flags); | |||
191 | IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC); | 193 | IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC); |
192 | IEEE80211_IF_FILE(dtim_count, u.ap.dtim_count, DEC); | 194 | IEEE80211_IF_FILE(dtim_count, u.ap.dtim_count, DEC); |
193 | IEEE80211_IF_FILE(num_beacons, u.ap.num_beacons, DEC); | 195 | IEEE80211_IF_FILE(num_beacons, u.ap.num_beacons, DEC); |
194 | IEEE80211_IF_FILE(force_unicast_rateidx, u.ap.force_unicast_rateidx, DEC); | ||
195 | IEEE80211_IF_FILE(max_ratectrl_rateidx, u.ap.max_ratectrl_rateidx, DEC); | ||
196 | 196 | ||
197 | static ssize_t ieee80211_if_fmt_num_buffered_multicast( | 197 | static ssize_t ieee80211_if_fmt_num_buffered_multicast( |
198 | const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) | 198 | const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) |
@@ -248,6 +248,9 @@ IEEE80211_IF_WFILE(min_discovery_timeout, | |||
248 | static void add_sta_files(struct ieee80211_sub_if_data *sdata) | 248 | static void add_sta_files(struct ieee80211_sub_if_data *sdata) |
249 | { | 249 | { |
250 | DEBUGFS_ADD(drop_unencrypted, sta); | 250 | DEBUGFS_ADD(drop_unencrypted, sta); |
251 | DEBUGFS_ADD(force_unicast_rateidx, ap); | ||
252 | DEBUGFS_ADD(max_ratectrl_rateidx, ap); | ||
253 | |||
251 | DEBUGFS_ADD(state, sta); | 254 | DEBUGFS_ADD(state, sta); |
252 | DEBUGFS_ADD(bssid, sta); | 255 | DEBUGFS_ADD(bssid, sta); |
253 | DEBUGFS_ADD(prev_bssid, sta); | 256 | DEBUGFS_ADD(prev_bssid, sta); |
@@ -268,23 +271,29 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata) | |||
268 | static void add_ap_files(struct ieee80211_sub_if_data *sdata) | 271 | static void add_ap_files(struct ieee80211_sub_if_data *sdata) |
269 | { | 272 | { |
270 | DEBUGFS_ADD(drop_unencrypted, ap); | 273 | DEBUGFS_ADD(drop_unencrypted, ap); |
274 | DEBUGFS_ADD(force_unicast_rateidx, ap); | ||
275 | DEBUGFS_ADD(max_ratectrl_rateidx, ap); | ||
276 | |||
271 | DEBUGFS_ADD(num_sta_ps, ap); | 277 | DEBUGFS_ADD(num_sta_ps, ap); |
272 | DEBUGFS_ADD(dtim_count, ap); | 278 | DEBUGFS_ADD(dtim_count, ap); |
273 | DEBUGFS_ADD(num_beacons, ap); | 279 | DEBUGFS_ADD(num_beacons, ap); |
274 | DEBUGFS_ADD(force_unicast_rateidx, ap); | ||
275 | DEBUGFS_ADD(max_ratectrl_rateidx, ap); | ||
276 | DEBUGFS_ADD(num_buffered_multicast, ap); | 280 | DEBUGFS_ADD(num_buffered_multicast, ap); |
277 | } | 281 | } |
278 | 282 | ||
279 | static void add_wds_files(struct ieee80211_sub_if_data *sdata) | 283 | static void add_wds_files(struct ieee80211_sub_if_data *sdata) |
280 | { | 284 | { |
281 | DEBUGFS_ADD(drop_unencrypted, wds); | 285 | DEBUGFS_ADD(drop_unencrypted, wds); |
286 | DEBUGFS_ADD(force_unicast_rateidx, ap); | ||
287 | DEBUGFS_ADD(max_ratectrl_rateidx, ap); | ||
288 | |||
282 | DEBUGFS_ADD(peer, wds); | 289 | DEBUGFS_ADD(peer, wds); |
283 | } | 290 | } |
284 | 291 | ||
285 | static void add_vlan_files(struct ieee80211_sub_if_data *sdata) | 292 | static void add_vlan_files(struct ieee80211_sub_if_data *sdata) |
286 | { | 293 | { |
287 | DEBUGFS_ADD(drop_unencrypted, vlan); | 294 | DEBUGFS_ADD(drop_unencrypted, vlan); |
295 | DEBUGFS_ADD(force_unicast_rateidx, ap); | ||
296 | DEBUGFS_ADD(max_ratectrl_rateidx, ap); | ||
288 | } | 297 | } |
289 | 298 | ||
290 | static void add_monitor_files(struct ieee80211_sub_if_data *sdata) | 299 | static void add_monitor_files(struct ieee80211_sub_if_data *sdata) |
@@ -372,6 +381,9 @@ static void add_files(struct ieee80211_sub_if_data *sdata) | |||
372 | static void del_sta_files(struct ieee80211_sub_if_data *sdata) | 381 | static void del_sta_files(struct ieee80211_sub_if_data *sdata) |
373 | { | 382 | { |
374 | DEBUGFS_DEL(drop_unencrypted, sta); | 383 | DEBUGFS_DEL(drop_unencrypted, sta); |
384 | DEBUGFS_DEL(force_unicast_rateidx, ap); | ||
385 | DEBUGFS_DEL(max_ratectrl_rateidx, ap); | ||
386 | |||
375 | DEBUGFS_DEL(state, sta); | 387 | DEBUGFS_DEL(state, sta); |
376 | DEBUGFS_DEL(bssid, sta); | 388 | DEBUGFS_DEL(bssid, sta); |
377 | DEBUGFS_DEL(prev_bssid, sta); | 389 | DEBUGFS_DEL(prev_bssid, sta); |
@@ -392,23 +404,29 @@ static void del_sta_files(struct ieee80211_sub_if_data *sdata) | |||
392 | static void del_ap_files(struct ieee80211_sub_if_data *sdata) | 404 | static void del_ap_files(struct ieee80211_sub_if_data *sdata) |
393 | { | 405 | { |
394 | DEBUGFS_DEL(drop_unencrypted, ap); | 406 | DEBUGFS_DEL(drop_unencrypted, ap); |
407 | DEBUGFS_DEL(force_unicast_rateidx, ap); | ||
408 | DEBUGFS_DEL(max_ratectrl_rateidx, ap); | ||
409 | |||
395 | DEBUGFS_DEL(num_sta_ps, ap); | 410 | DEBUGFS_DEL(num_sta_ps, ap); |
396 | DEBUGFS_DEL(dtim_count, ap); | 411 | DEBUGFS_DEL(dtim_count, ap); |
397 | DEBUGFS_DEL(num_beacons, ap); | 412 | DEBUGFS_DEL(num_beacons, ap); |
398 | DEBUGFS_DEL(force_unicast_rateidx, ap); | ||
399 | DEBUGFS_DEL(max_ratectrl_rateidx, ap); | ||
400 | DEBUGFS_DEL(num_buffered_multicast, ap); | 413 | DEBUGFS_DEL(num_buffered_multicast, ap); |
401 | } | 414 | } |
402 | 415 | ||
403 | static void del_wds_files(struct ieee80211_sub_if_data *sdata) | 416 | static void del_wds_files(struct ieee80211_sub_if_data *sdata) |
404 | { | 417 | { |
405 | DEBUGFS_DEL(drop_unencrypted, wds); | 418 | DEBUGFS_DEL(drop_unencrypted, wds); |
419 | DEBUGFS_DEL(force_unicast_rateidx, ap); | ||
420 | DEBUGFS_DEL(max_ratectrl_rateidx, ap); | ||
421 | |||
406 | DEBUGFS_DEL(peer, wds); | 422 | DEBUGFS_DEL(peer, wds); |
407 | } | 423 | } |
408 | 424 | ||
409 | static void del_vlan_files(struct ieee80211_sub_if_data *sdata) | 425 | static void del_vlan_files(struct ieee80211_sub_if_data *sdata) |
410 | { | 426 | { |
411 | DEBUGFS_DEL(drop_unencrypted, vlan); | 427 | DEBUGFS_DEL(drop_unencrypted, vlan); |
428 | DEBUGFS_DEL(force_unicast_rateidx, ap); | ||
429 | DEBUGFS_DEL(max_ratectrl_rateidx, ap); | ||
412 | } | 430 | } |
413 | 431 | ||
414 | static void del_monitor_files(struct ieee80211_sub_if_data *sdata) | 432 | static void del_monitor_files(struct ieee80211_sub_if_data *sdata) |
@@ -525,7 +543,7 @@ static int netdev_notify(struct notifier_block *nb, | |||
525 | { | 543 | { |
526 | struct net_device *dev = ndev; | 544 | struct net_device *dev = ndev; |
527 | struct dentry *dir; | 545 | struct dentry *dir; |
528 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 546 | struct ieee80211_sub_if_data *sdata; |
529 | char buf[10+IFNAMSIZ]; | 547 | char buf[10+IFNAMSIZ]; |
530 | 548 | ||
531 | if (state != NETDEV_CHANGENAME) | 549 | if (state != NETDEV_CHANGENAME) |
@@ -537,6 +555,8 @@ static int netdev_notify(struct notifier_block *nb, | |||
537 | if (dev->ieee80211_ptr->wiphy->privid != mac80211_wiphy_privid) | 555 | if (dev->ieee80211_ptr->wiphy->privid != mac80211_wiphy_privid) |
538 | return 0; | 556 | return 0; |
539 | 557 | ||
558 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
559 | |||
540 | sprintf(buf, "netdev:%s", dev->name); | 560 | sprintf(buf, "netdev:%s", dev->name); |
541 | dir = sdata->debugfsdir; | 561 | dir = sdata->debugfsdir; |
542 | if (!debugfs_rename(dir->d_parent, dir, dir->d_parent, buf)) | 562 | if (!debugfs_rename(dir->d_parent, dir, dir->d_parent, buf)) |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 02a8753a4eca..1b1fc53dad36 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -237,8 +237,6 @@ struct ieee80211_if_ap { | |||
237 | struct sk_buff_head ps_bc_buf; | 237 | struct sk_buff_head ps_bc_buf; |
238 | atomic_t num_sta_ps; /* number of stations in PS mode */ | 238 | atomic_t num_sta_ps; /* number of stations in PS mode */ |
239 | int dtim_count; | 239 | int dtim_count; |
240 | int force_unicast_rateidx; /* forced TX rateidx for unicast frames */ | ||
241 | int max_ratectrl_rateidx; /* max TX rateidx for rate control */ | ||
242 | int num_beacons; /* number of TXed beacon frames for this BSS */ | 240 | int num_beacons; /* number of TXed beacon frames for this BSS */ |
243 | }; | 241 | }; |
244 | 242 | ||
@@ -248,7 +246,6 @@ struct ieee80211_if_wds { | |||
248 | }; | 246 | }; |
249 | 247 | ||
250 | struct ieee80211_if_vlan { | 248 | struct ieee80211_if_vlan { |
251 | struct ieee80211_sub_if_data *ap; | ||
252 | struct list_head list; | 249 | struct list_head list; |
253 | }; | 250 | }; |
254 | 251 | ||
@@ -432,16 +429,18 @@ struct ieee80211_sub_if_data { | |||
432 | struct ieee80211_key *keys[NUM_DEFAULT_KEYS]; | 429 | struct ieee80211_key *keys[NUM_DEFAULT_KEYS]; |
433 | struct ieee80211_key *default_key; | 430 | struct ieee80211_key *default_key; |
434 | 431 | ||
432 | /* BSS configuration for this interface. */ | ||
433 | struct ieee80211_bss_conf bss_conf; | ||
434 | |||
435 | /* | 435 | /* |
436 | * BSS configuration for this interface. | 436 | * AP this belongs to: self in AP mode and |
437 | * | 437 | * corresponding AP in VLAN mode, NULL for |
438 | * FIXME: I feel bad putting this here when we already have a | 438 | * all others (might be needed later in IBSS) |
439 | * bss pointer, but the bss pointer is just wrong when | ||
440 | * you have multiple virtual STA mode interfaces... | ||
441 | * This needs to be fixed. | ||
442 | */ | 439 | */ |
443 | struct ieee80211_bss_conf bss_conf; | 440 | struct ieee80211_if_ap *bss; |
444 | struct ieee80211_if_ap *bss; /* BSS that this device belongs to */ | 441 | |
442 | int force_unicast_rateidx; /* forced TX rateidx for unicast frames */ | ||
443 | int max_ratectrl_rateidx; /* max TX rateidx for rate control */ | ||
445 | 444 | ||
446 | union { | 445 | union { |
447 | struct ieee80211_if_ap ap; | 446 | struct ieee80211_if_ap ap; |
@@ -533,8 +532,6 @@ struct ieee80211_sub_if_data *vif_to_sdata(struct ieee80211_vif *p) | |||
533 | return container_of(p, struct ieee80211_sub_if_data, vif); | 532 | return container_of(p, struct ieee80211_sub_if_data, vif); |
534 | } | 533 | } |
535 | 534 | ||
536 | #define IEEE80211_DEV_TO_SUB_IF(dev) netdev_priv(dev) | ||
537 | |||
538 | enum { | 535 | enum { |
539 | IEEE80211_RX_MSG = 1, | 536 | IEEE80211_RX_MSG = 1, |
540 | IEEE80211_TX_STATUS_MSG = 2, | 537 | IEEE80211_TX_STATUS_MSG = 2, |
@@ -760,6 +757,16 @@ static inline int ieee80211_is_multiqueue(struct ieee80211_local *local) | |||
760 | #endif | 757 | #endif |
761 | } | 758 | } |
762 | 759 | ||
760 | static inline struct ieee80211_sub_if_data * | ||
761 | IEEE80211_DEV_TO_SUB_IF(struct net_device *dev) | ||
762 | { | ||
763 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
764 | |||
765 | BUG_ON(!local || local->mdev == dev); | ||
766 | |||
767 | return netdev_priv(dev); | ||
768 | } | ||
769 | |||
763 | /* this struct represents 802.11n's RA/TID combination */ | 770 | /* this struct represents 802.11n's RA/TID combination */ |
764 | struct ieee80211_ra_tid { | 771 | struct ieee80211_ra_tid { |
765 | u8 ra[ETH_ALEN]; | 772 | u8 ra[ETH_ALEN]; |
@@ -883,8 +890,8 @@ int ieee80211_sta_scan_results(struct net_device *dev, | |||
883 | ieee80211_rx_result ieee80211_sta_rx_scan( | 890 | ieee80211_rx_result ieee80211_sta_rx_scan( |
884 | struct net_device *dev, struct sk_buff *skb, | 891 | struct net_device *dev, struct sk_buff *skb, |
885 | struct ieee80211_rx_status *rx_status); | 892 | struct ieee80211_rx_status *rx_status); |
886 | void ieee80211_rx_bss_list_init(struct net_device *dev); | 893 | void ieee80211_rx_bss_list_init(struct ieee80211_local *local); |
887 | void ieee80211_rx_bss_list_deinit(struct net_device *dev); | 894 | void ieee80211_rx_bss_list_deinit(struct ieee80211_local *local); |
888 | int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len); | 895 | int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len); |
889 | struct sta_info *ieee80211_ibss_add_sta(struct net_device *dev, | 896 | struct sta_info *ieee80211_ibss_add_sta(struct net_device *dev, |
890 | struct sk_buff *skb, u8 *bssid, | 897 | struct sk_buff *skb, u8 *bssid, |
@@ -925,8 +932,8 @@ static inline void ieee80211_start_mesh(struct net_device *dev) | |||
925 | {} | 932 | {} |
926 | #endif | 933 | #endif |
927 | 934 | ||
928 | /* ieee80211_iface.c */ | 935 | /* interface handling */ |
929 | int ieee80211_if_add(struct net_device *dev, const char *name, | 936 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, |
930 | struct net_device **new_dev, int type, | 937 | struct net_device **new_dev, int type, |
931 | struct vif_params *params); | 938 | struct vif_params *params); |
932 | void ieee80211_if_set_type(struct net_device *dev, int type); | 939 | void ieee80211_if_set_type(struct net_device *dev, int type); |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index eeb16926aa7d..f2aefd4b8637 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -27,6 +27,9 @@ void ieee80211_if_sdata_init(struct ieee80211_sub_if_data *sdata) | |||
27 | skb_queue_head_init(&sdata->fragments[i].skb_list); | 27 | skb_queue_head_init(&sdata->fragments[i].skb_list); |
28 | 28 | ||
29 | INIT_LIST_HEAD(&sdata->key_list); | 29 | INIT_LIST_HEAD(&sdata->key_list); |
30 | |||
31 | sdata->force_unicast_rateidx = -1; | ||
32 | sdata->max_ratectrl_rateidx = -1; | ||
30 | } | 33 | } |
31 | 34 | ||
32 | static void ieee80211_if_sdata_deinit(struct ieee80211_sub_if_data *sdata) | 35 | static void ieee80211_if_sdata_deinit(struct ieee80211_sub_if_data *sdata) |
@@ -38,12 +41,11 @@ static void ieee80211_if_sdata_deinit(struct ieee80211_sub_if_data *sdata) | |||
38 | } | 41 | } |
39 | 42 | ||
40 | /* Must be called with rtnl lock held. */ | 43 | /* Must be called with rtnl lock held. */ |
41 | int ieee80211_if_add(struct net_device *dev, const char *name, | 44 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, |
42 | struct net_device **new_dev, int type, | 45 | struct net_device **new_dev, int type, |
43 | struct vif_params *params) | 46 | struct vif_params *params) |
44 | { | 47 | { |
45 | struct net_device *ndev; | 48 | struct net_device *ndev; |
46 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
47 | struct ieee80211_sub_if_data *sdata = NULL; | 49 | struct ieee80211_sub_if_data *sdata = NULL; |
48 | int ret; | 50 | int ret; |
49 | 51 | ||
@@ -67,13 +69,10 @@ int ieee80211_if_add(struct net_device *dev, const char *name, | |||
67 | goto fail; | 69 | goto fail; |
68 | 70 | ||
69 | memcpy(ndev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN); | 71 | memcpy(ndev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN); |
70 | ndev->base_addr = dev->base_addr; | ||
71 | ndev->irq = dev->irq; | ||
72 | ndev->mem_start = dev->mem_start; | ||
73 | ndev->mem_end = dev->mem_end; | ||
74 | SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); | 72 | SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); |
75 | 73 | ||
76 | sdata = IEEE80211_DEV_TO_SUB_IF(ndev); | 74 | /* don't use IEEE80211_DEV_TO_SUB_IF because it checks too much */ |
75 | sdata = netdev_priv(ndev); | ||
77 | ndev->ieee80211_ptr = &sdata->wdev; | 76 | ndev->ieee80211_ptr = &sdata->wdev; |
78 | sdata->wdev.wiphy = local->hw.wiphy; | 77 | sdata->wdev.wiphy = local->hw.wiphy; |
79 | sdata->vif.type = IEEE80211_IF_TYPE_AP; | 78 | sdata->vif.type = IEEE80211_IF_TYPE_AP; |
@@ -117,14 +116,6 @@ void ieee80211_if_set_type(struct net_device *dev, int type) | |||
117 | int oldtype = sdata->vif.type; | 116 | int oldtype = sdata->vif.type; |
118 | 117 | ||
119 | /* | 118 | /* |
120 | * We need to call this function on the master interface | ||
121 | * which already has a hard_start_xmit routine assigned | ||
122 | * which must not be changed. | ||
123 | */ | ||
124 | if (dev != sdata->local->mdev) | ||
125 | dev->hard_start_xmit = ieee80211_subif_start_xmit; | ||
126 | |||
127 | /* | ||
128 | * Called even when register_netdevice fails, it would | 119 | * Called even when register_netdevice fails, it would |
129 | * oops if assigned before initialising the rest. | 120 | * oops if assigned before initialising the rest. |
130 | */ | 121 | */ |
@@ -138,22 +129,16 @@ void ieee80211_if_set_type(struct net_device *dev, int type) | |||
138 | 129 | ||
139 | switch (type) { | 130 | switch (type) { |
140 | case IEEE80211_IF_TYPE_WDS: | 131 | case IEEE80211_IF_TYPE_WDS: |
141 | /* nothing special */ | ||
142 | break; | ||
143 | case IEEE80211_IF_TYPE_VLAN: | 132 | case IEEE80211_IF_TYPE_VLAN: |
144 | sdata->u.vlan.ap = NULL; | 133 | /* nothing special */ |
145 | break; | 134 | break; |
146 | case IEEE80211_IF_TYPE_AP: | 135 | case IEEE80211_IF_TYPE_AP: |
147 | sdata->u.ap.force_unicast_rateidx = -1; | ||
148 | sdata->u.ap.max_ratectrl_rateidx = -1; | ||
149 | skb_queue_head_init(&sdata->u.ap.ps_bc_buf); | 136 | skb_queue_head_init(&sdata->u.ap.ps_bc_buf); |
150 | sdata->bss = &sdata->u.ap; | ||
151 | INIT_LIST_HEAD(&sdata->u.ap.vlans); | 137 | INIT_LIST_HEAD(&sdata->u.ap.vlans); |
152 | break; | 138 | break; |
153 | case IEEE80211_IF_TYPE_MESH_POINT: | 139 | case IEEE80211_IF_TYPE_MESH_POINT: |
154 | case IEEE80211_IF_TYPE_STA: | 140 | case IEEE80211_IF_TYPE_STA: |
155 | case IEEE80211_IF_TYPE_IBSS: { | 141 | case IEEE80211_IF_TYPE_IBSS: { |
156 | struct ieee80211_sub_if_data *msdata; | ||
157 | struct ieee80211_if_sta *ifsta; | 142 | struct ieee80211_if_sta *ifsta; |
158 | 143 | ||
159 | ifsta = &sdata->u.sta; | 144 | ifsta = &sdata->u.sta; |
@@ -171,9 +156,6 @@ void ieee80211_if_set_type(struct net_device *dev, int type) | |||
171 | if (ieee80211_num_regular_queues(&sdata->local->hw) >= 4) | 156 | if (ieee80211_num_regular_queues(&sdata->local->hw) >= 4) |
172 | ifsta->flags |= IEEE80211_STA_WMM_ENABLED; | 157 | ifsta->flags |= IEEE80211_STA_WMM_ENABLED; |
173 | 158 | ||
174 | msdata = IEEE80211_DEV_TO_SUB_IF(sdata->local->mdev); | ||
175 | sdata->bss = &msdata->u.ap; | ||
176 | |||
177 | if (ieee80211_vif_is_mesh(&sdata->vif)) | 159 | if (ieee80211_vif_is_mesh(&sdata->vif)) |
178 | ieee80211_mesh_init_sdata(sdata); | 160 | ieee80211_mesh_init_sdata(sdata); |
179 | break; | 161 | break; |
@@ -215,27 +197,8 @@ void ieee80211_if_reinit(struct net_device *dev) | |||
215 | WARN_ON(1); | 197 | WARN_ON(1); |
216 | break; | 198 | break; |
217 | case IEEE80211_IF_TYPE_AP: { | 199 | case IEEE80211_IF_TYPE_AP: { |
218 | /* Remove all virtual interfaces that use this BSS | ||
219 | * as their sdata->bss */ | ||
220 | struct ieee80211_sub_if_data *tsdata, *n; | ||
221 | struct beacon_data *beacon; | 200 | struct beacon_data *beacon; |
222 | 201 | ||
223 | list_for_each_entry_safe(tsdata, n, &local->interfaces, list) { | ||
224 | if (tsdata != sdata && tsdata->bss == &sdata->u.ap) { | ||
225 | printk(KERN_DEBUG "%s: removing virtual " | ||
226 | "interface %s because its BSS interface" | ||
227 | " is being removed\n", | ||
228 | sdata->dev->name, tsdata->dev->name); | ||
229 | list_del_rcu(&tsdata->list); | ||
230 | /* | ||
231 | * We have lots of time and can afford | ||
232 | * to sync for each interface | ||
233 | */ | ||
234 | synchronize_rcu(); | ||
235 | __ieee80211_if_del(local, tsdata); | ||
236 | } | ||
237 | } | ||
238 | |||
239 | beacon = sdata->u.ap.beacon; | 202 | beacon = sdata->u.ap.beacon; |
240 | rcu_assign_pointer(sdata->u.ap.beacon, NULL); | 203 | rcu_assign_pointer(sdata->u.ap.beacon, NULL); |
241 | synchronize_rcu(); | 204 | synchronize_rcu(); |
@@ -249,6 +212,7 @@ void ieee80211_if_reinit(struct net_device *dev) | |||
249 | break; | 212 | break; |
250 | } | 213 | } |
251 | case IEEE80211_IF_TYPE_WDS: | 214 | case IEEE80211_IF_TYPE_WDS: |
215 | case IEEE80211_IF_TYPE_VLAN: | ||
252 | /* nothing to do */ | 216 | /* nothing to do */ |
253 | break; | 217 | break; |
254 | case IEEE80211_IF_TYPE_MESH_POINT: | 218 | case IEEE80211_IF_TYPE_MESH_POINT: |
@@ -269,9 +233,6 @@ void ieee80211_if_reinit(struct net_device *dev) | |||
269 | case IEEE80211_IF_TYPE_MNTR: | 233 | case IEEE80211_IF_TYPE_MNTR: |
270 | dev->type = ARPHRD_ETHER; | 234 | dev->type = ARPHRD_ETHER; |
271 | break; | 235 | break; |
272 | case IEEE80211_IF_TYPE_VLAN: | ||
273 | sdata->u.vlan.ap = NULL; | ||
274 | break; | ||
275 | } | 236 | } |
276 | 237 | ||
277 | flushed = sta_info_flush(local, sdata); | 238 | flushed = sta_info_flush(local, sdata); |
@@ -289,8 +250,10 @@ void __ieee80211_if_del(struct ieee80211_local *local, | |||
289 | 250 | ||
290 | ieee80211_debugfs_remove_netdev(sdata); | 251 | ieee80211_debugfs_remove_netdev(sdata); |
291 | unregister_netdevice(dev); | 252 | unregister_netdevice(dev); |
292 | /* Except master interface, the net_device will be freed by | 253 | /* |
293 | * net_device->destructor (i. e. ieee80211_if_free). */ | 254 | * The net_device will be freed by its destructor, |
255 | * i.e. ieee80211_if_free. | ||
256 | */ | ||
294 | } | 257 | } |
295 | 258 | ||
296 | /* Must be called with rtnl lock held. */ | 259 | /* Must be called with rtnl lock held. */ |
@@ -303,8 +266,7 @@ int ieee80211_if_remove(struct net_device *dev, const char *name, int id) | |||
303 | 266 | ||
304 | list_for_each_entry_safe(sdata, n, &local->interfaces, list) { | 267 | list_for_each_entry_safe(sdata, n, &local->interfaces, list) { |
305 | if ((sdata->vif.type == id || id == -1) && | 268 | if ((sdata->vif.type == id || id == -1) && |
306 | strcmp(name, sdata->dev->name) == 0 && | 269 | strcmp(name, sdata->dev->name) == 0) { |
307 | sdata->dev != local->mdev) { | ||
308 | list_del_rcu(&sdata->list); | 270 | list_del_rcu(&sdata->list); |
309 | synchronize_rcu(); | 271 | synchronize_rcu(); |
310 | __ieee80211_if_del(local, sdata); | 272 | __ieee80211_if_del(local, sdata); |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 1c4d3ba6b878..863923964d21 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -105,7 +105,7 @@ static int ieee80211_master_open(struct net_device *dev) | |||
105 | 105 | ||
106 | /* we hold the RTNL here so can safely walk the list */ | 106 | /* we hold the RTNL here so can safely walk the list */ |
107 | list_for_each_entry(sdata, &local->interfaces, list) { | 107 | list_for_each_entry(sdata, &local->interfaces, list) { |
108 | if (sdata->dev != dev && netif_running(sdata->dev)) { | 108 | if (netif_running(sdata->dev)) { |
109 | res = 0; | 109 | res = 0; |
110 | break; | 110 | break; |
111 | } | 111 | } |
@@ -126,7 +126,7 @@ static int ieee80211_master_stop(struct net_device *dev) | |||
126 | 126 | ||
127 | /* we hold the RTNL here so can safely walk the list */ | 127 | /* we hold the RTNL here so can safely walk the list */ |
128 | list_for_each_entry(sdata, &local->interfaces, list) | 128 | list_for_each_entry(sdata, &local->interfaces, list) |
129 | if (sdata->dev != dev && netif_running(sdata->dev)) | 129 | if (netif_running(sdata->dev)) |
130 | dev_close(sdata->dev); | 130 | dev_close(sdata->dev); |
131 | 131 | ||
132 | return 0; | 132 | return 0; |
@@ -194,7 +194,7 @@ static int ieee80211_open(struct net_device *dev) | |||
194 | list_for_each_entry(nsdata, &local->interfaces, list) { | 194 | list_for_each_entry(nsdata, &local->interfaces, list) { |
195 | struct net_device *ndev = nsdata->dev; | 195 | struct net_device *ndev = nsdata->dev; |
196 | 196 | ||
197 | if (ndev != dev && ndev != local->mdev && netif_running(ndev)) { | 197 | if (ndev != dev && netif_running(ndev)) { |
198 | /* | 198 | /* |
199 | * Allow only a single IBSS interface to be up at any | 199 | * Allow only a single IBSS interface to be up at any |
200 | * time. This is restricted because beacon distribution | 200 | * time. This is restricted because beacon distribution |
@@ -210,30 +210,6 @@ static int ieee80211_open(struct net_device *dev) | |||
210 | return -EBUSY; | 210 | return -EBUSY; |
211 | 211 | ||
212 | /* | 212 | /* |
213 | * Disallow multiple IBSS/STA mode interfaces. | ||
214 | * | ||
215 | * This is a technical restriction, it is possible although | ||
216 | * most likely not IEEE 802.11 compliant to have multiple | ||
217 | * STAs with just a single hardware (the TSF timer will not | ||
218 | * be adjusted properly.) | ||
219 | * | ||
220 | * However, because mac80211 uses the master device's BSS | ||
221 | * information for each STA/IBSS interface, doing this will | ||
222 | * currently corrupt that BSS information completely, unless, | ||
223 | * a not very useful case, both STAs are associated to the | ||
224 | * same BSS. | ||
225 | * | ||
226 | * To remove this restriction, the BSS information needs to | ||
227 | * be embedded in the STA/IBSS mode sdata instead of using | ||
228 | * the master device's BSS structure. | ||
229 | */ | ||
230 | if ((sdata->vif.type == IEEE80211_IF_TYPE_STA || | ||
231 | sdata->vif.type == IEEE80211_IF_TYPE_IBSS) && | ||
232 | (nsdata->vif.type == IEEE80211_IF_TYPE_STA || | ||
233 | nsdata->vif.type == IEEE80211_IF_TYPE_IBSS)) | ||
234 | return -EBUSY; | ||
235 | |||
236 | /* | ||
237 | * The remaining checks are only performed for interfaces | 213 | * The remaining checks are only performed for interfaces |
238 | * with the same MAC address. | 214 | * with the same MAC address. |
239 | */ | 215 | */ |
@@ -252,7 +228,7 @@ static int ieee80211_open(struct net_device *dev) | |||
252 | */ | 228 | */ |
253 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN && | 229 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN && |
254 | nsdata->vif.type == IEEE80211_IF_TYPE_AP) | 230 | nsdata->vif.type == IEEE80211_IF_TYPE_AP) |
255 | sdata->u.vlan.ap = nsdata; | 231 | sdata->bss = &nsdata->u.ap; |
256 | } | 232 | } |
257 | } | 233 | } |
258 | 234 | ||
@@ -262,10 +238,13 @@ static int ieee80211_open(struct net_device *dev) | |||
262 | return -ENOLINK; | 238 | return -ENOLINK; |
263 | break; | 239 | break; |
264 | case IEEE80211_IF_TYPE_VLAN: | 240 | case IEEE80211_IF_TYPE_VLAN: |
265 | if (!sdata->u.vlan.ap) | 241 | if (!sdata->bss) |
266 | return -ENOLINK; | 242 | return -ENOLINK; |
243 | list_add(&sdata->u.vlan.list, &sdata->bss->vlans); | ||
267 | break; | 244 | break; |
268 | case IEEE80211_IF_TYPE_AP: | 245 | case IEEE80211_IF_TYPE_AP: |
246 | sdata->bss = &sdata->u.ap; | ||
247 | break; | ||
269 | case IEEE80211_IF_TYPE_STA: | 248 | case IEEE80211_IF_TYPE_STA: |
270 | case IEEE80211_IF_TYPE_MNTR: | 249 | case IEEE80211_IF_TYPE_MNTR: |
271 | case IEEE80211_IF_TYPE_IBSS: | 250 | case IEEE80211_IF_TYPE_IBSS: |
@@ -283,14 +262,13 @@ static int ieee80211_open(struct net_device *dev) | |||
283 | if (local->ops->start) | 262 | if (local->ops->start) |
284 | res = local->ops->start(local_to_hw(local)); | 263 | res = local->ops->start(local_to_hw(local)); |
285 | if (res) | 264 | if (res) |
286 | return res; | 265 | goto err_del_bss; |
287 | need_hw_reconfig = 1; | 266 | need_hw_reconfig = 1; |
288 | ieee80211_led_radio(local, local->hw.conf.radio_enabled); | 267 | ieee80211_led_radio(local, local->hw.conf.radio_enabled); |
289 | } | 268 | } |
290 | 269 | ||
291 | switch (sdata->vif.type) { | 270 | switch (sdata->vif.type) { |
292 | case IEEE80211_IF_TYPE_VLAN: | 271 | case IEEE80211_IF_TYPE_VLAN: |
293 | list_add(&sdata->u.vlan.list, &sdata->u.vlan.ap->u.ap.vlans); | ||
294 | /* no need to tell driver */ | 272 | /* no need to tell driver */ |
295 | break; | 273 | break; |
296 | case IEEE80211_IF_TYPE_MNTR: | 274 | case IEEE80211_IF_TYPE_MNTR: |
@@ -404,6 +382,10 @@ static int ieee80211_open(struct net_device *dev) | |||
404 | err_stop: | 382 | err_stop: |
405 | if (!local->open_count && local->ops->stop) | 383 | if (!local->open_count && local->ops->stop) |
406 | local->ops->stop(local_to_hw(local)); | 384 | local->ops->stop(local_to_hw(local)); |
385 | err_del_bss: | ||
386 | sdata->bss = NULL; | ||
387 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) | ||
388 | list_del(&sdata->u.vlan.list); | ||
407 | return res; | 389 | return res; |
408 | } | 390 | } |
409 | 391 | ||
@@ -486,7 +468,6 @@ static int ieee80211_stop(struct net_device *dev) | |||
486 | switch (sdata->vif.type) { | 468 | switch (sdata->vif.type) { |
487 | case IEEE80211_IF_TYPE_VLAN: | 469 | case IEEE80211_IF_TYPE_VLAN: |
488 | list_del(&sdata->u.vlan.list); | 470 | list_del(&sdata->u.vlan.list); |
489 | sdata->u.vlan.ap = NULL; | ||
490 | /* no need to tell driver */ | 471 | /* no need to tell driver */ |
491 | break; | 472 | break; |
492 | case IEEE80211_IF_TYPE_MNTR: | 473 | case IEEE80211_IF_TYPE_MNTR: |
@@ -549,6 +530,8 @@ static int ieee80211_stop(struct net_device *dev) | |||
549 | local->ops->remove_interface(local_to_hw(local), &conf); | 530 | local->ops->remove_interface(local_to_hw(local), &conf); |
550 | } | 531 | } |
551 | 532 | ||
533 | sdata->bss = NULL; | ||
534 | |||
552 | if (local->open_count == 0) { | 535 | if (local->open_count == 0) { |
553 | if (netif_running(local->mdev)) | 536 | if (netif_running(local->mdev)) |
554 | dev_close(local->mdev); | 537 | dev_close(local->mdev); |
@@ -1659,7 +1642,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1659 | int result; | 1642 | int result; |
1660 | enum ieee80211_band band; | 1643 | enum ieee80211_band band; |
1661 | struct net_device *mdev; | 1644 | struct net_device *mdev; |
1662 | struct ieee80211_sub_if_data *sdata; | 1645 | struct wireless_dev *mwdev; |
1663 | 1646 | ||
1664 | /* | 1647 | /* |
1665 | * generic code guarantees at least one band, | 1648 | * generic code guarantees at least one band, |
@@ -1699,8 +1682,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1699 | hw->ampdu_queues = 0; | 1682 | hw->ampdu_queues = 0; |
1700 | #endif | 1683 | #endif |
1701 | 1684 | ||
1702 | /* for now, mdev needs sub_if_data :/ */ | 1685 | mdev = alloc_netdev_mq(sizeof(struct wireless_dev), |
1703 | mdev = alloc_netdev_mq(sizeof(struct ieee80211_sub_if_data), | ||
1704 | "wmaster%d", ether_setup, | 1686 | "wmaster%d", ether_setup, |
1705 | ieee80211_num_queues(hw)); | 1687 | ieee80211_num_queues(hw)); |
1706 | if (!mdev) | 1688 | if (!mdev) |
@@ -1709,13 +1691,13 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1709 | if (ieee80211_num_queues(hw) > 1) | 1691 | if (ieee80211_num_queues(hw) > 1) |
1710 | mdev->features |= NETIF_F_MULTI_QUEUE; | 1692 | mdev->features |= NETIF_F_MULTI_QUEUE; |
1711 | 1693 | ||
1712 | sdata = IEEE80211_DEV_TO_SUB_IF(mdev); | 1694 | mwdev = netdev_priv(mdev); |
1713 | mdev->ieee80211_ptr = &sdata->wdev; | 1695 | mdev->ieee80211_ptr = mwdev; |
1714 | sdata->wdev.wiphy = local->hw.wiphy; | 1696 | mwdev->wiphy = local->hw.wiphy; |
1715 | 1697 | ||
1716 | local->mdev = mdev; | 1698 | local->mdev = mdev; |
1717 | 1699 | ||
1718 | ieee80211_rx_bss_list_init(mdev); | 1700 | ieee80211_rx_bss_list_init(local); |
1719 | 1701 | ||
1720 | mdev->hard_start_xmit = ieee80211_master_start_xmit; | 1702 | mdev->hard_start_xmit = ieee80211_master_start_xmit; |
1721 | mdev->open = ieee80211_master_open; | 1703 | mdev->open = ieee80211_master_open; |
@@ -1724,16 +1706,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1724 | mdev->header_ops = &ieee80211_header_ops; | 1706 | mdev->header_ops = &ieee80211_header_ops; |
1725 | mdev->set_multicast_list = ieee80211_master_set_multicast_list; | 1707 | mdev->set_multicast_list = ieee80211_master_set_multicast_list; |
1726 | 1708 | ||
1727 | sdata->vif.type = IEEE80211_IF_TYPE_AP; | ||
1728 | sdata->dev = mdev; | ||
1729 | sdata->local = local; | ||
1730 | sdata->u.ap.force_unicast_rateidx = -1; | ||
1731 | sdata->u.ap.max_ratectrl_rateidx = -1; | ||
1732 | ieee80211_if_sdata_init(sdata); | ||
1733 | |||
1734 | /* no RCU needed since we're still during init phase */ | ||
1735 | list_add_tail(&sdata->list, &local->interfaces); | ||
1736 | |||
1737 | name = wiphy_dev(local->hw.wiphy)->driver->name; | 1709 | name = wiphy_dev(local->hw.wiphy)->driver->name; |
1738 | local->hw.workqueue = create_freezeable_workqueue(name); | 1710 | local->hw.workqueue = create_freezeable_workqueue(name); |
1739 | if (!local->hw.workqueue) { | 1711 | if (!local->hw.workqueue) { |
@@ -1779,9 +1751,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1779 | if (result < 0) | 1751 | if (result < 0) |
1780 | goto fail_dev; | 1752 | goto fail_dev; |
1781 | 1753 | ||
1782 | ieee80211_debugfs_add_netdev(IEEE80211_DEV_TO_SUB_IF(local->mdev)); | ||
1783 | ieee80211_if_set_type(local->mdev, IEEE80211_IF_TYPE_AP); | ||
1784 | |||
1785 | result = ieee80211_init_rate_ctrl_alg(local, | 1754 | result = ieee80211_init_rate_ctrl_alg(local, |
1786 | hw->rate_control_algorithm); | 1755 | hw->rate_control_algorithm); |
1787 | if (result < 0) { | 1756 | if (result < 0) { |
@@ -1801,7 +1770,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1801 | ieee80211_install_qdisc(local->mdev); | 1770 | ieee80211_install_qdisc(local->mdev); |
1802 | 1771 | ||
1803 | /* add one default STA interface */ | 1772 | /* add one default STA interface */ |
1804 | result = ieee80211_if_add(local->mdev, "wlan%d", NULL, | 1773 | result = ieee80211_if_add(local, "wlan%d", NULL, |
1805 | IEEE80211_IF_TYPE_STA, NULL); | 1774 | IEEE80211_IF_TYPE_STA, NULL); |
1806 | if (result) | 1775 | if (result) |
1807 | printk(KERN_WARNING "%s: Failed to add default virtual iface\n", | 1776 | printk(KERN_WARNING "%s: Failed to add default virtual iface\n", |
@@ -1817,7 +1786,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1817 | fail_wep: | 1786 | fail_wep: |
1818 | rate_control_deinitialize(local); | 1787 | rate_control_deinitialize(local); |
1819 | fail_rate: | 1788 | fail_rate: |
1820 | ieee80211_debugfs_remove_netdev(IEEE80211_DEV_TO_SUB_IF(local->mdev)); | ||
1821 | unregister_netdevice(local->mdev); | 1789 | unregister_netdevice(local->mdev); |
1822 | local->mdev = NULL; | 1790 | local->mdev = NULL; |
1823 | fail_dev: | 1791 | fail_dev: |
@@ -1827,10 +1795,8 @@ fail_sta_info: | |||
1827 | debugfs_hw_del(local); | 1795 | debugfs_hw_del(local); |
1828 | destroy_workqueue(local->hw.workqueue); | 1796 | destroy_workqueue(local->hw.workqueue); |
1829 | fail_workqueue: | 1797 | fail_workqueue: |
1830 | if (local->mdev != NULL) { | 1798 | if (local->mdev) |
1831 | ieee80211_if_free(local->mdev); | 1799 | free_netdev(local->mdev); |
1832 | local->mdev = NULL; | ||
1833 | } | ||
1834 | fail_mdev_alloc: | 1800 | fail_mdev_alloc: |
1835 | wiphy_unregister(local->hw.wiphy); | 1801 | wiphy_unregister(local->hw.wiphy); |
1836 | return result; | 1802 | return result; |
@@ -1858,24 +1824,19 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
1858 | */ | 1824 | */ |
1859 | 1825 | ||
1860 | /* | 1826 | /* |
1861 | * First, we remove all non-master interfaces. Do this because they | 1827 | * First, we remove all virtual interfaces. |
1862 | * may have bss pointer dependency on the master, and when we free | ||
1863 | * the master these would be freed as well, breaking our list | ||
1864 | * iteration completely. | ||
1865 | */ | 1828 | */ |
1866 | list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) { | 1829 | list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) { |
1867 | if (sdata->dev == local->mdev) | ||
1868 | continue; | ||
1869 | list_del(&sdata->list); | 1830 | list_del(&sdata->list); |
1870 | __ieee80211_if_del(local, sdata); | 1831 | __ieee80211_if_del(local, sdata); |
1871 | } | 1832 | } |
1872 | 1833 | ||
1873 | /* then, finally, remove the master interface */ | 1834 | /* then, finally, remove the master interface */ |
1874 | __ieee80211_if_del(local, IEEE80211_DEV_TO_SUB_IF(local->mdev)); | 1835 | unregister_netdevice(local->mdev); |
1875 | 1836 | ||
1876 | rtnl_unlock(); | 1837 | rtnl_unlock(); |
1877 | 1838 | ||
1878 | ieee80211_rx_bss_list_deinit(local->mdev); | 1839 | ieee80211_rx_bss_list_deinit(local); |
1879 | ieee80211_clear_tx_pending(local); | 1840 | ieee80211_clear_tx_pending(local); |
1880 | sta_info_stop(local); | 1841 | sta_info_stop(local); |
1881 | rate_control_deinitialize(local); | 1842 | rate_control_deinitialize(local); |
@@ -1892,8 +1853,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
1892 | wiphy_unregister(local->hw.wiphy); | 1853 | wiphy_unregister(local->hw.wiphy); |
1893 | ieee80211_wep_free(local); | 1854 | ieee80211_wep_free(local); |
1894 | ieee80211_led_exit(local); | 1855 | ieee80211_led_exit(local); |
1895 | ieee80211_if_free(local->mdev); | 1856 | free_netdev(local->mdev); |
1896 | local->mdev = NULL; | ||
1897 | } | 1857 | } |
1898 | EXPORT_SYMBOL(ieee80211_unregister_hw); | 1858 | EXPORT_SYMBOL(ieee80211_unregister_hw); |
1899 | 1859 | ||
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index dbc8cf454bc0..64d710a88b86 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -78,7 +78,7 @@ static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, | |||
78 | static struct ieee80211_sta_bss * | 78 | static struct ieee80211_sta_bss * |
79 | ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int freq, | 79 | ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int freq, |
80 | u8 *ssid, u8 ssid_len); | 80 | u8 *ssid, u8 ssid_len); |
81 | static void ieee80211_rx_bss_put(struct net_device *dev, | 81 | static void ieee80211_rx_bss_put(struct ieee80211_local *local, |
82 | struct ieee80211_sta_bss *bss); | 82 | struct ieee80211_sta_bss *bss); |
83 | static int ieee80211_sta_find_ibss(struct net_device *dev, | 83 | static int ieee80211_sta_find_ibss(struct net_device *dev, |
84 | struct ieee80211_if_sta *ifsta); | 84 | struct ieee80211_if_sta *ifsta); |
@@ -554,7 +554,7 @@ static void ieee80211_set_associated(struct net_device *dev, | |||
554 | 554 | ||
555 | changed |= ieee80211_handle_bss_capability(sdata, bss); | 555 | changed |= ieee80211_handle_bss_capability(sdata, bss); |
556 | 556 | ||
557 | ieee80211_rx_bss_put(dev, bss); | 557 | ieee80211_rx_bss_put(local, bss); |
558 | } | 558 | } |
559 | 559 | ||
560 | if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) { | 560 | if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) { |
@@ -760,7 +760,7 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
760 | (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT)) | 760 | (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT)) |
761 | capab |= WLAN_CAPABILITY_SPECTRUM_MGMT; | 761 | capab |= WLAN_CAPABILITY_SPECTRUM_MGMT; |
762 | 762 | ||
763 | ieee80211_rx_bss_put(dev, bss); | 763 | ieee80211_rx_bss_put(local, bss); |
764 | } else { | 764 | } else { |
765 | rates = ~0; | 765 | rates = ~0; |
766 | rates_len = sband->n_bitrates; | 766 | rates_len = sband->n_bitrates; |
@@ -992,7 +992,7 @@ static int ieee80211_privacy_mismatch(struct net_device *dev, | |||
992 | wep_privacy = !!ieee80211_sta_wep_configured(dev); | 992 | wep_privacy = !!ieee80211_sta_wep_configured(dev); |
993 | privacy_invoked = !!(ifsta->flags & IEEE80211_STA_PRIVACY_INVOKED); | 993 | privacy_invoked = !!(ifsta->flags & IEEE80211_STA_PRIVACY_INVOKED); |
994 | 994 | ||
995 | ieee80211_rx_bss_put(dev, bss); | 995 | ieee80211_rx_bss_put(local, bss); |
996 | 996 | ||
997 | if ((bss_privacy == wep_privacy) || (bss_privacy == privacy_invoked)) | 997 | if ((bss_privacy == wep_privacy) || (bss_privacy == privacy_invoked)) |
998 | return 0; | 998 | return 0; |
@@ -2094,7 +2094,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2094 | sta->last_signal = bss->signal; | 2094 | sta->last_signal = bss->signal; |
2095 | sta->last_qual = bss->qual; | 2095 | sta->last_qual = bss->qual; |
2096 | sta->last_noise = bss->noise; | 2096 | sta->last_noise = bss->noise; |
2097 | ieee80211_rx_bss_put(dev, bss); | 2097 | ieee80211_rx_bss_put(local, bss); |
2098 | } | 2098 | } |
2099 | 2099 | ||
2100 | err = sta_info_insert(sta); | 2100 | err = sta_info_insert(sta); |
@@ -2212,10 +2212,9 @@ static void __ieee80211_rx_bss_hash_add(struct net_device *dev, | |||
2212 | 2212 | ||
2213 | 2213 | ||
2214 | /* Caller must hold local->sta_bss_lock */ | 2214 | /* Caller must hold local->sta_bss_lock */ |
2215 | static void __ieee80211_rx_bss_hash_del(struct net_device *dev, | 2215 | static void __ieee80211_rx_bss_hash_del(struct ieee80211_local *local, |
2216 | struct ieee80211_sta_bss *bss) | 2216 | struct ieee80211_sta_bss *bss) |
2217 | { | 2217 | { |
2218 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
2219 | struct ieee80211_sta_bss *b, *prev = NULL; | 2218 | struct ieee80211_sta_bss *b, *prev = NULL; |
2220 | b = local->sta_bss_hash[STA_HASH(bss->bssid)]; | 2219 | b = local->sta_bss_hash[STA_HASH(bss->bssid)]; |
2221 | while (b) { | 2220 | while (b) { |
@@ -2367,39 +2366,35 @@ static void ieee80211_rx_bss_free(struct ieee80211_sta_bss *bss) | |||
2367 | } | 2366 | } |
2368 | 2367 | ||
2369 | 2368 | ||
2370 | static void ieee80211_rx_bss_put(struct net_device *dev, | 2369 | static void ieee80211_rx_bss_put(struct ieee80211_local *local, |
2371 | struct ieee80211_sta_bss *bss) | 2370 | struct ieee80211_sta_bss *bss) |
2372 | { | 2371 | { |
2373 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
2374 | |||
2375 | local_bh_disable(); | 2372 | local_bh_disable(); |
2376 | if (!atomic_dec_and_lock(&bss->users, &local->sta_bss_lock)) { | 2373 | if (!atomic_dec_and_lock(&bss->users, &local->sta_bss_lock)) { |
2377 | local_bh_enable(); | 2374 | local_bh_enable(); |
2378 | return; | 2375 | return; |
2379 | } | 2376 | } |
2380 | 2377 | ||
2381 | __ieee80211_rx_bss_hash_del(dev, bss); | 2378 | __ieee80211_rx_bss_hash_del(local, bss); |
2382 | list_del(&bss->list); | 2379 | list_del(&bss->list); |
2383 | spin_unlock_bh(&local->sta_bss_lock); | 2380 | spin_unlock_bh(&local->sta_bss_lock); |
2384 | ieee80211_rx_bss_free(bss); | 2381 | ieee80211_rx_bss_free(bss); |
2385 | } | 2382 | } |
2386 | 2383 | ||
2387 | 2384 | ||
2388 | void ieee80211_rx_bss_list_init(struct net_device *dev) | 2385 | void ieee80211_rx_bss_list_init(struct ieee80211_local *local) |
2389 | { | 2386 | { |
2390 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
2391 | spin_lock_init(&local->sta_bss_lock); | 2387 | spin_lock_init(&local->sta_bss_lock); |
2392 | INIT_LIST_HEAD(&local->sta_bss_list); | 2388 | INIT_LIST_HEAD(&local->sta_bss_list); |
2393 | } | 2389 | } |
2394 | 2390 | ||
2395 | 2391 | ||
2396 | void ieee80211_rx_bss_list_deinit(struct net_device *dev) | 2392 | void ieee80211_rx_bss_list_deinit(struct ieee80211_local *local) |
2397 | { | 2393 | { |
2398 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
2399 | struct ieee80211_sta_bss *bss, *tmp; | 2394 | struct ieee80211_sta_bss *bss, *tmp; |
2400 | 2395 | ||
2401 | list_for_each_entry_safe(bss, tmp, &local->sta_bss_list, list) | 2396 | list_for_each_entry_safe(bss, tmp, &local->sta_bss_list, list) |
2402 | ieee80211_rx_bss_put(dev, bss); | 2397 | ieee80211_rx_bss_put(local, bss); |
2403 | } | 2398 | } |
2404 | 2399 | ||
2405 | 2400 | ||
@@ -2775,7 +2770,7 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2775 | */ | 2770 | */ |
2776 | if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS && | 2771 | if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS && |
2777 | bss->probe_resp && beacon) { | 2772 | bss->probe_resp && beacon) { |
2778 | ieee80211_rx_bss_put(dev, bss); | 2773 | ieee80211_rx_bss_put(local, bss); |
2779 | return; | 2774 | return; |
2780 | } | 2775 | } |
2781 | 2776 | ||
@@ -2918,7 +2913,7 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2918 | } | 2913 | } |
2919 | } | 2914 | } |
2920 | 2915 | ||
2921 | ieee80211_rx_bss_put(dev, bss); | 2916 | ieee80211_rx_bss_put(local, bss); |
2922 | } | 2917 | } |
2923 | 2918 | ||
2924 | 2919 | ||
@@ -3578,7 +3573,7 @@ static int ieee80211_sta_config_auth(struct net_device *dev, | |||
3578 | selected->ssid_len); | 3573 | selected->ssid_len); |
3579 | ieee80211_sta_set_bssid(dev, selected->bssid); | 3574 | ieee80211_sta_set_bssid(dev, selected->bssid); |
3580 | ieee80211_sta_def_wmm_params(dev, selected, 0); | 3575 | ieee80211_sta_def_wmm_params(dev, selected, 0); |
3581 | ieee80211_rx_bss_put(dev, selected); | 3576 | ieee80211_rx_bss_put(local, selected); |
3582 | ifsta->state = IEEE80211_AUTHENTICATE; | 3577 | ifsta->state = IEEE80211_AUTHENTICATE; |
3583 | ieee80211_sta_reset_auth(dev, ifsta); | 3578 | ieee80211_sta_reset_auth(dev, ifsta); |
3584 | return 0; | 3579 | return 0; |
@@ -3655,7 +3650,7 @@ static int ieee80211_sta_create_ibss(struct net_device *dev, | |||
3655 | } | 3650 | } |
3656 | 3651 | ||
3657 | ret = ieee80211_sta_join_ibss(dev, ifsta, bss); | 3652 | ret = ieee80211_sta_join_ibss(dev, ifsta, bss); |
3658 | ieee80211_rx_bss_put(dev, bss); | 3653 | ieee80211_rx_bss_put(local, bss); |
3659 | return ret; | 3654 | return ret; |
3660 | } | 3655 | } |
3661 | 3656 | ||
@@ -3711,7 +3706,7 @@ static int ieee80211_sta_find_ibss(struct net_device *dev, | |||
3711 | " based on configured SSID\n", | 3706 | " based on configured SSID\n", |
3712 | dev->name, print_mac(mac, bssid)); | 3707 | dev->name, print_mac(mac, bssid)); |
3713 | ret = ieee80211_sta_join_ibss(dev, ifsta, bss); | 3708 | ret = ieee80211_sta_join_ibss(dev, ifsta, bss); |
3714 | ieee80211_rx_bss_put(dev, bss); | 3709 | ieee80211_rx_bss_put(local, bss); |
3715 | return ret; | 3710 | return ret; |
3716 | } | 3711 | } |
3717 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 3712 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
@@ -3907,11 +3902,6 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw) | |||
3907 | 3902 | ||
3908 | rcu_read_lock(); | 3903 | rcu_read_lock(); |
3909 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 3904 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
3910 | |||
3911 | /* No need to wake the master device. */ | ||
3912 | if (sdata->dev == local->mdev) | ||
3913 | continue; | ||
3914 | |||
3915 | /* Tell AP we're back */ | 3905 | /* Tell AP we're back */ |
3916 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA && | 3906 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA && |
3917 | sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED) | 3907 | sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED) |
@@ -4077,12 +4067,6 @@ static int ieee80211_sta_start_scan(struct net_device *dev, | |||
4077 | 4067 | ||
4078 | rcu_read_lock(); | 4068 | rcu_read_lock(); |
4079 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 4069 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
4080 | |||
4081 | /* Don't stop the master interface, otherwise we can't transmit | ||
4082 | * probes! */ | ||
4083 | if (sdata->dev == local->mdev) | ||
4084 | continue; | ||
4085 | |||
4086 | netif_stop_queue(sdata->dev); | 4070 | netif_stop_queue(sdata->dev); |
4087 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA && | 4071 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA && |
4088 | (sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED)) | 4072 | (sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED)) |
@@ -4473,12 +4457,10 @@ void ieee80211_notify_mac(struct ieee80211_hw *hw, | |||
4473 | case IEEE80211_NOTIFY_RE_ASSOC: | 4457 | case IEEE80211_NOTIFY_RE_ASSOC: |
4474 | rcu_read_lock(); | 4458 | rcu_read_lock(); |
4475 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 4459 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
4460 | if (sdata->vif.type != IEEE80211_IF_TYPE_STA) | ||
4461 | continue; | ||
4476 | 4462 | ||
4477 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA) { | 4463 | ieee80211_sta_req_auth(sdata->dev, &sdata->u.sta); |
4478 | ieee80211_sta_req_auth(sdata->dev, | ||
4479 | &sdata->u.sta); | ||
4480 | } | ||
4481 | |||
4482 | } | 4464 | } |
4483 | rcu_read_unlock(); | 4465 | rcu_read_unlock(); |
4484 | break; | 4466 | break; |
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c index 62388f8e9024..ca636295e628 100644 --- a/net/mac80211/rc80211_pid_algo.c +++ b/net/mac80211/rc80211_pid_algo.c | |||
@@ -259,8 +259,8 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev, | |||
259 | 259 | ||
260 | /* Don't update the state if we're not controlling the rate. */ | 260 | /* Don't update the state if we're not controlling the rate. */ |
261 | sdata = sta->sdata; | 261 | sdata = sta->sdata; |
262 | if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) { | 262 | if (sdata->force_unicast_rateidx > -1) { |
263 | sta->txrate_idx = sdata->bss->max_ratectrl_rateidx; | 263 | sta->txrate_idx = sdata->max_ratectrl_rateidx; |
264 | goto unlock; | 264 | goto unlock; |
265 | } | 265 | } |
266 | 266 | ||
@@ -337,8 +337,8 @@ static void rate_control_pid_get_rate(void *priv, struct net_device *dev, | |||
337 | 337 | ||
338 | /* If a forced rate is in effect, select it. */ | 338 | /* If a forced rate is in effect, select it. */ |
339 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 339 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
340 | if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) | 340 | if (sdata->force_unicast_rateidx > -1) |
341 | sta->txrate_idx = sdata->bss->force_unicast_rateidx; | 341 | sta->txrate_idx = sdata->force_unicast_rateidx; |
342 | 342 | ||
343 | rateidx = sta->txrate_idx; | 343 | rateidx = sta->txrate_idx; |
344 | 344 | ||
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index fab443d717eb..244ee2d50a58 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -647,8 +647,7 @@ static void ap_sta_ps_start(struct net_device *dev, struct sta_info *sta) | |||
647 | 647 | ||
648 | sdata = sta->sdata; | 648 | sdata = sta->sdata; |
649 | 649 | ||
650 | if (sdata->bss) | 650 | atomic_inc(&sdata->bss->num_sta_ps); |
651 | atomic_inc(&sdata->bss->num_sta_ps); | ||
652 | set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL); | 651 | set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL); |
653 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 652 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
654 | printk(KERN_DEBUG "%s: STA %s aid %d enters power save mode\n", | 653 | printk(KERN_DEBUG "%s: STA %s aid %d enters power save mode\n", |
@@ -667,8 +666,7 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta) | |||
667 | 666 | ||
668 | sdata = sta->sdata; | 667 | sdata = sta->sdata; |
669 | 668 | ||
670 | if (sdata->bss) | 669 | atomic_dec(&sdata->bss->num_sta_ps); |
671 | atomic_dec(&sdata->bss->num_sta_ps); | ||
672 | 670 | ||
673 | clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL); | 671 | clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL); |
674 | 672 | ||
@@ -742,7 +740,9 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
742 | sta->last_qual = rx->status->qual; | 740 | sta->last_qual = rx->status->qual; |
743 | sta->last_noise = rx->status->noise; | 741 | sta->last_noise = rx->status->noise; |
744 | 742 | ||
745 | if (!ieee80211_has_morefrags(hdr->frame_control)) { | 743 | if (!ieee80211_has_morefrags(hdr->frame_control) && |
744 | (rx->sdata->vif.type == IEEE80211_IF_TYPE_AP || | ||
745 | rx->sdata->vif.type == IEEE80211_IF_TYPE_VLAN)) { | ||
746 | /* Change STA power saving mode only in the end of a frame | 746 | /* Change STA power saving mode only in the end of a frame |
747 | * exchange sequence */ | 747 | * exchange sequence */ |
748 | if (test_sta_flags(sta, WLAN_STA_PS) && | 748 | if (test_sta_flags(sta, WLAN_STA_PS) && |
@@ -1772,11 +1772,6 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
1772 | return 0; | 1772 | return 0; |
1773 | rx->flags &= ~IEEE80211_RX_RA_MATCH; | 1773 | rx->flags &= ~IEEE80211_RX_RA_MATCH; |
1774 | } | 1774 | } |
1775 | if (sdata->dev == sdata->local->mdev && | ||
1776 | !(rx->flags & IEEE80211_RX_IN_SCAN)) | ||
1777 | /* do not receive anything via | ||
1778 | * master device when not scanning */ | ||
1779 | return 0; | ||
1780 | break; | 1775 | break; |
1781 | case IEEE80211_IF_TYPE_WDS: | 1776 | case IEEE80211_IF_TYPE_WDS: |
1782 | if (bssid || !ieee80211_is_data(hdr->frame_control)) | 1777 | if (bssid || !ieee80211_is_data(hdr->frame_control)) |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 47d2c1bbfcaa..f2ba653b9d69 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -320,7 +320,9 @@ int sta_info_insert(struct sta_info *sta) | |||
320 | /* notify driver */ | 320 | /* notify driver */ |
321 | if (local->ops->sta_notify) { | 321 | if (local->ops->sta_notify) { |
322 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) | 322 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) |
323 | sdata = sdata->u.vlan.ap; | 323 | sdata = container_of(sdata->bss, |
324 | struct ieee80211_sub_if_data, | ||
325 | u.ap); | ||
324 | 326 | ||
325 | local->ops->sta_notify(local_to_hw(local), &sdata->vif, | 327 | local->ops->sta_notify(local_to_hw(local), &sdata->vif, |
326 | STA_NOTIFY_ADD, sta->addr); | 328 | STA_NOTIFY_ADD, sta->addr); |
@@ -375,8 +377,10 @@ static inline void __bss_tim_clear(struct ieee80211_if_ap *bss, u16 aid) | |||
375 | static void __sta_info_set_tim_bit(struct ieee80211_if_ap *bss, | 377 | static void __sta_info_set_tim_bit(struct ieee80211_if_ap *bss, |
376 | struct sta_info *sta) | 378 | struct sta_info *sta) |
377 | { | 379 | { |
378 | if (bss) | 380 | BUG_ON(!bss); |
379 | __bss_tim_set(bss, sta->aid); | 381 | |
382 | __bss_tim_set(bss, sta->aid); | ||
383 | |||
380 | if (sta->local->ops->set_tim) { | 384 | if (sta->local->ops->set_tim) { |
381 | sta->local->tim_in_locked_section = true; | 385 | sta->local->tim_in_locked_section = true; |
382 | sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 1); | 386 | sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 1); |
@@ -388,6 +392,8 @@ void sta_info_set_tim_bit(struct sta_info *sta) | |||
388 | { | 392 | { |
389 | unsigned long flags; | 393 | unsigned long flags; |
390 | 394 | ||
395 | BUG_ON(!sta->sdata->bss); | ||
396 | |||
391 | spin_lock_irqsave(&sta->local->sta_lock, flags); | 397 | spin_lock_irqsave(&sta->local->sta_lock, flags); |
392 | __sta_info_set_tim_bit(sta->sdata->bss, sta); | 398 | __sta_info_set_tim_bit(sta->sdata->bss, sta); |
393 | spin_unlock_irqrestore(&sta->local->sta_lock, flags); | 399 | spin_unlock_irqrestore(&sta->local->sta_lock, flags); |
@@ -396,8 +402,10 @@ void sta_info_set_tim_bit(struct sta_info *sta) | |||
396 | static void __sta_info_clear_tim_bit(struct ieee80211_if_ap *bss, | 402 | static void __sta_info_clear_tim_bit(struct ieee80211_if_ap *bss, |
397 | struct sta_info *sta) | 403 | struct sta_info *sta) |
398 | { | 404 | { |
399 | if (bss) | 405 | BUG_ON(!bss); |
400 | __bss_tim_clear(bss, sta->aid); | 406 | |
407 | __bss_tim_clear(bss, sta->aid); | ||
408 | |||
401 | if (sta->local->ops->set_tim) { | 409 | if (sta->local->ops->set_tim) { |
402 | sta->local->tim_in_locked_section = true; | 410 | sta->local->tim_in_locked_section = true; |
403 | sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 0); | 411 | sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 0); |
@@ -409,6 +417,8 @@ void sta_info_clear_tim_bit(struct sta_info *sta) | |||
409 | { | 417 | { |
410 | unsigned long flags; | 418 | unsigned long flags; |
411 | 419 | ||
420 | BUG_ON(!sta->sdata->bss); | ||
421 | |||
412 | spin_lock_irqsave(&sta->local->sta_lock, flags); | 422 | spin_lock_irqsave(&sta->local->sta_lock, flags); |
413 | __sta_info_clear_tim_bit(sta->sdata->bss, sta); | 423 | __sta_info_clear_tim_bit(sta->sdata->bss, sta); |
414 | spin_unlock_irqrestore(&sta->local->sta_lock, flags); | 424 | spin_unlock_irqrestore(&sta->local->sta_lock, flags); |
@@ -437,8 +447,9 @@ void __sta_info_unlink(struct sta_info **sta) | |||
437 | list_del(&(*sta)->list); | 447 | list_del(&(*sta)->list); |
438 | 448 | ||
439 | if (test_and_clear_sta_flags(*sta, WLAN_STA_PS)) { | 449 | if (test_and_clear_sta_flags(*sta, WLAN_STA_PS)) { |
440 | if (sdata->bss) | 450 | BUG_ON(!sdata->bss); |
441 | atomic_dec(&sdata->bss->num_sta_ps); | 451 | |
452 | atomic_dec(&sdata->bss->num_sta_ps); | ||
442 | __sta_info_clear_tim_bit(sdata->bss, *sta); | 453 | __sta_info_clear_tim_bit(sdata->bss, *sta); |
443 | } | 454 | } |
444 | 455 | ||
@@ -446,7 +457,9 @@ void __sta_info_unlink(struct sta_info **sta) | |||
446 | 457 | ||
447 | if (local->ops->sta_notify) { | 458 | if (local->ops->sta_notify) { |
448 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) | 459 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) |
449 | sdata = sdata->u.vlan.ap; | 460 | sdata = container_of(sdata->bss, |
461 | struct ieee80211_sub_if_data, | ||
462 | u.ap); | ||
450 | 463 | ||
451 | local->ops->sta_notify(local_to_hw(local), &sdata->vif, | 464 | local->ops->sta_notify(local_to_hw(local), &sdata->vif, |
452 | STA_NOTIFY_REMOVE, (*sta)->addr); | 465 | STA_NOTIFY_REMOVE, (*sta)->addr); |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 9bd9faac3c3c..a757dcc1208d 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -303,8 +303,7 @@ static void purge_old_ps_buffers(struct ieee80211_local *local) | |||
303 | 303 | ||
304 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 304 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
305 | struct ieee80211_if_ap *ap; | 305 | struct ieee80211_if_ap *ap; |
306 | if (sdata->dev == local->mdev || | 306 | if (sdata->vif.type != IEEE80211_IF_TYPE_AP) |
307 | sdata->vif.type != IEEE80211_IF_TYPE_AP) | ||
308 | continue; | 307 | continue; |
309 | ap = &sdata->u.ap; | 308 | ap = &sdata->u.ap; |
310 | skb = skb_dequeue(&ap->ps_bc_buf); | 309 | skb = skb_dequeue(&ap->ps_bc_buf); |
@@ -346,8 +345,12 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) | |||
346 | * This is done either by the hardware or us. | 345 | * This is done either by the hardware or us. |
347 | */ | 346 | */ |
348 | 347 | ||
349 | /* not AP/IBSS or ordered frame */ | 348 | /* powersaving STAs only in AP/VLAN mode */ |
350 | if (!tx->sdata->bss || (tx->fc & IEEE80211_FCTL_ORDER)) | 349 | if (!tx->sdata->bss) |
350 | return TX_CONTINUE; | ||
351 | |||
352 | /* no buffering for ordered frames */ | ||
353 | if (tx->fc & IEEE80211_FCTL_ORDER) | ||
351 | return TX_CONTINUE; | 354 | return TX_CONTINUE; |
352 | 355 | ||
353 | /* no stations in PS mode */ | 356 | /* no stations in PS mode */ |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index ce62b163b82c..89ce4e07bd84 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -428,8 +428,6 @@ void ieee80211_iterate_active_interfaces( | |||
428 | case IEEE80211_IF_TYPE_MESH_POINT: | 428 | case IEEE80211_IF_TYPE_MESH_POINT: |
429 | break; | 429 | break; |
430 | } | 430 | } |
431 | if (sdata->dev == local->mdev) | ||
432 | continue; | ||
433 | if (netif_running(sdata->dev)) | 431 | if (netif_running(sdata->dev)) |
434 | iterator(data, sdata->dev->dev_addr, | 432 | iterator(data, sdata->dev->dev_addr, |
435 | &sdata->vif); | 433 | &sdata->vif); |
@@ -463,8 +461,6 @@ void ieee80211_iterate_active_interfaces_atomic( | |||
463 | case IEEE80211_IF_TYPE_MESH_POINT: | 461 | case IEEE80211_IF_TYPE_MESH_POINT: |
464 | break; | 462 | break; |
465 | } | 463 | } |
466 | if (sdata->dev == local->mdev) | ||
467 | continue; | ||
468 | if (netif_running(sdata->dev)) | 464 | if (netif_running(sdata->dev)) |
469 | iterator(data, sdata->dev->dev_addr, | 465 | iterator(data, sdata->dev->dev_addr, |
470 | &sdata->vif); | 466 | &sdata->vif); |
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index 207971e9ad72..e8e4a6215e89 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c | |||
@@ -627,16 +627,14 @@ static int ieee80211_ioctl_siwrate(struct net_device *dev, | |||
627 | struct ieee80211_supported_band *sband; | 627 | struct ieee80211_supported_band *sband; |
628 | 628 | ||
629 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 629 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
630 | if (!sdata->bss) | ||
631 | return -ENODEV; | ||
632 | 630 | ||
633 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | 631 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
634 | 632 | ||
635 | /* target_rate = -1, rate->fixed = 0 means auto only, so use all rates | 633 | /* target_rate = -1, rate->fixed = 0 means auto only, so use all rates |
636 | * target_rate = X, rate->fixed = 1 means only rate X | 634 | * target_rate = X, rate->fixed = 1 means only rate X |
637 | * target_rate = X, rate->fixed = 0 means all rates <= X */ | 635 | * target_rate = X, rate->fixed = 0 means all rates <= X */ |
638 | sdata->bss->max_ratectrl_rateidx = -1; | 636 | sdata->max_ratectrl_rateidx = -1; |
639 | sdata->bss->force_unicast_rateidx = -1; | 637 | sdata->force_unicast_rateidx = -1; |
640 | if (rate->value < 0) | 638 | if (rate->value < 0) |
641 | return 0; | 639 | return 0; |
642 | 640 | ||
@@ -645,9 +643,9 @@ static int ieee80211_ioctl_siwrate(struct net_device *dev, | |||
645 | int this_rate = brate->bitrate; | 643 | int this_rate = brate->bitrate; |
646 | 644 | ||
647 | if (target_rate == this_rate) { | 645 | if (target_rate == this_rate) { |
648 | sdata->bss->max_ratectrl_rateidx = i; | 646 | sdata->max_ratectrl_rateidx = i; |
649 | if (rate->fixed) | 647 | if (rate->fixed) |
650 | sdata->bss->force_unicast_rateidx = i; | 648 | sdata->force_unicast_rateidx = i; |
651 | err = 0; | 649 | err = 0; |
652 | break; | 650 | break; |
653 | } | 651 | } |