diff options
Diffstat (limited to 'net/mac80211/iface.c')
-rw-r--r-- | net/mac80211/iface.c | 37 |
1 files changed, 19 insertions, 18 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index a6e6da3cab70..00a1f4ccdaf1 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -65,7 +65,7 @@ static int ieee80211_change_mac(struct net_device *dev, void *addr) | |||
65 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 65 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
66 | int ret; | 66 | int ret; |
67 | 67 | ||
68 | if (netif_running(dev)) | 68 | if (ieee80211_sdata_running(sdata)) |
69 | return -EBUSY; | 69 | return -EBUSY; |
70 | 70 | ||
71 | ret = eth_mac_addr(dev, addr); | 71 | ret = eth_mac_addr(dev, addr); |
@@ -96,7 +96,6 @@ static int ieee80211_open(struct net_device *dev) | |||
96 | struct ieee80211_sub_if_data *nsdata; | 96 | struct ieee80211_sub_if_data *nsdata; |
97 | struct ieee80211_local *local = sdata->local; | 97 | struct ieee80211_local *local = sdata->local; |
98 | struct sta_info *sta; | 98 | struct sta_info *sta; |
99 | struct ieee80211_if_init_conf conf; | ||
100 | u32 changed = 0; | 99 | u32 changed = 0; |
101 | int res; | 100 | int res; |
102 | u32 hw_reconf_flags = 0; | 101 | u32 hw_reconf_flags = 0; |
@@ -111,7 +110,7 @@ static int ieee80211_open(struct net_device *dev) | |||
111 | list_for_each_entry(nsdata, &local->interfaces, list) { | 110 | list_for_each_entry(nsdata, &local->interfaces, list) { |
112 | struct net_device *ndev = nsdata->dev; | 111 | struct net_device *ndev = nsdata->dev; |
113 | 112 | ||
114 | if (ndev != dev && netif_running(ndev)) { | 113 | if (ndev != dev && ieee80211_sdata_running(nsdata)) { |
115 | /* | 114 | /* |
116 | * Allow only a single IBSS interface to be up at any | 115 | * Allow only a single IBSS interface to be up at any |
117 | * time. This is restricted because beacon distribution | 116 | * time. This is restricted because beacon distribution |
@@ -197,7 +196,7 @@ static int ieee80211_open(struct net_device *dev) | |||
197 | struct net_device *ndev = nsdata->dev; | 196 | struct net_device *ndev = nsdata->dev; |
198 | 197 | ||
199 | /* | 198 | /* |
200 | * No need to check netif_running since we do not allow | 199 | * No need to check running since we do not allow |
201 | * it to start up with this invalid address. | 200 | * it to start up with this invalid address. |
202 | */ | 201 | */ |
203 | if (compare_ether_addr(null_addr, ndev->dev_addr) == 0) { | 202 | if (compare_ether_addr(null_addr, ndev->dev_addr) == 0) { |
@@ -248,10 +247,7 @@ static int ieee80211_open(struct net_device *dev) | |||
248 | ieee80211_configure_filter(local); | 247 | ieee80211_configure_filter(local); |
249 | break; | 248 | break; |
250 | default: | 249 | default: |
251 | conf.vif = &sdata->vif; | 250 | res = drv_add_interface(local, &sdata->vif); |
252 | conf.type = sdata->vif.type; | ||
253 | conf.mac_addr = sdata->vif.addr; | ||
254 | res = drv_add_interface(local, &conf); | ||
255 | if (res) | 251 | if (res) |
256 | goto err_stop; | 252 | goto err_stop; |
257 | 253 | ||
@@ -334,7 +330,7 @@ static int ieee80211_open(struct net_device *dev) | |||
334 | 330 | ||
335 | return 0; | 331 | return 0; |
336 | err_del_interface: | 332 | err_del_interface: |
337 | drv_remove_interface(local, &conf); | 333 | drv_remove_interface(local, &sdata->vif); |
338 | err_stop: | 334 | err_stop: |
339 | if (!local->open_count) | 335 | if (!local->open_count) |
340 | drv_stop(local); | 336 | drv_stop(local); |
@@ -349,7 +345,6 @@ static int ieee80211_stop(struct net_device *dev) | |||
349 | { | 345 | { |
350 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 346 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
351 | struct ieee80211_local *local = sdata->local; | 347 | struct ieee80211_local *local = sdata->local; |
352 | struct ieee80211_if_init_conf conf; | ||
353 | struct sta_info *sta; | 348 | struct sta_info *sta; |
354 | unsigned long flags; | 349 | unsigned long flags; |
355 | struct sk_buff *skb, *tmp; | 350 | struct sk_buff *skb, *tmp; |
@@ -362,6 +357,11 @@ static int ieee80211_stop(struct net_device *dev) | |||
362 | netif_stop_queue(dev); | 357 | netif_stop_queue(dev); |
363 | 358 | ||
364 | /* | 359 | /* |
360 | * Purge work for this interface. | ||
361 | */ | ||
362 | ieee80211_work_purge(sdata); | ||
363 | |||
364 | /* | ||
365 | * Now delete all active aggregation sessions. | 365 | * Now delete all active aggregation sessions. |
366 | */ | 366 | */ |
367 | rcu_read_lock(); | 367 | rcu_read_lock(); |
@@ -528,12 +528,9 @@ static int ieee80211_stop(struct net_device *dev) | |||
528 | BSS_CHANGED_BEACON_ENABLED); | 528 | BSS_CHANGED_BEACON_ENABLED); |
529 | } | 529 | } |
530 | 530 | ||
531 | conf.vif = &sdata->vif; | ||
532 | conf.type = sdata->vif.type; | ||
533 | conf.mac_addr = sdata->vif.addr; | ||
534 | /* disable all keys for as long as this netdev is down */ | 531 | /* disable all keys for as long as this netdev is down */ |
535 | ieee80211_disable_keys(sdata); | 532 | ieee80211_disable_keys(sdata); |
536 | drv_remove_interface(local, &conf); | 533 | drv_remove_interface(local, &sdata->vif); |
537 | } | 534 | } |
538 | 535 | ||
539 | sdata->bss = NULL; | 536 | sdata->bss = NULL; |
@@ -756,7 +753,7 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | |||
756 | * and goes into the requested mode. | 753 | * and goes into the requested mode. |
757 | */ | 754 | */ |
758 | 755 | ||
759 | if (netif_running(sdata->dev)) | 756 | if (ieee80211_sdata_running(sdata)) |
760 | return -EBUSY; | 757 | return -EBUSY; |
761 | 758 | ||
762 | /* Purge and reset type-dependent state. */ | 759 | /* Purge and reset type-dependent state. */ |
@@ -917,6 +914,8 @@ static u32 ieee80211_idle_on(struct ieee80211_local *local) | |||
917 | wiphy_name(local->hw.wiphy)); | 914 | wiphy_name(local->hw.wiphy)); |
918 | #endif | 915 | #endif |
919 | 916 | ||
917 | drv_flush(local, false); | ||
918 | |||
920 | local->hw.conf.flags |= IEEE80211_CONF_IDLE; | 919 | local->hw.conf.flags |= IEEE80211_CONF_IDLE; |
921 | return IEEE80211_CONF_CHANGE_IDLE; | 920 | return IEEE80211_CONF_CHANGE_IDLE; |
922 | } | 921 | } |
@@ -926,16 +925,18 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local) | |||
926 | struct ieee80211_sub_if_data *sdata; | 925 | struct ieee80211_sub_if_data *sdata; |
927 | int count = 0; | 926 | int count = 0; |
928 | 927 | ||
928 | if (!list_empty(&local->work_list)) | ||
929 | return ieee80211_idle_off(local, "working"); | ||
930 | |||
929 | if (local->scanning) | 931 | if (local->scanning) |
930 | return ieee80211_idle_off(local, "scanning"); | 932 | return ieee80211_idle_off(local, "scanning"); |
931 | 933 | ||
932 | list_for_each_entry(sdata, &local->interfaces, list) { | 934 | list_for_each_entry(sdata, &local->interfaces, list) { |
933 | if (!netif_running(sdata->dev)) | 935 | if (!ieee80211_sdata_running(sdata)) |
934 | continue; | 936 | continue; |
935 | /* do not count disabled managed interfaces */ | 937 | /* do not count disabled managed interfaces */ |
936 | if (sdata->vif.type == NL80211_IFTYPE_STATION && | 938 | if (sdata->vif.type == NL80211_IFTYPE_STATION && |
937 | !sdata->u.mgd.associated && | 939 | !sdata->u.mgd.associated) |
938 | list_empty(&sdata->u.mgd.work_list)) | ||
939 | continue; | 940 | continue; |
940 | /* do not count unused IBSS interfaces */ | 941 | /* do not count unused IBSS interfaces */ |
941 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && | 942 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && |