diff options
Diffstat (limited to 'net/mac80211/iface.c')
-rw-r--r-- | net/mac80211/iface.c | 76 |
1 files changed, 44 insertions, 32 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index e8221180b6c1..2acc416e77e1 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -236,7 +236,10 @@ static int ieee80211_open(struct net_device *dev) | |||
236 | break; | 236 | break; |
237 | case NL80211_IFTYPE_STATION: | 237 | case NL80211_IFTYPE_STATION: |
238 | case NL80211_IFTYPE_ADHOC: | 238 | case NL80211_IFTYPE_ADHOC: |
239 | sdata->u.sta.flags &= ~IEEE80211_STA_PREV_BSSID_SET; | 239 | if (sdata->vif.type == NL80211_IFTYPE_STATION) |
240 | sdata->u.mgd.flags &= ~IEEE80211_STA_PREV_BSSID_SET; | ||
241 | else | ||
242 | sdata->u.ibss.flags &= ~IEEE80211_IBSS_PREV_BSSID_SET; | ||
240 | /* fall through */ | 243 | /* fall through */ |
241 | default: | 244 | default: |
242 | conf.vif = &sdata->vif; | 245 | conf.vif = &sdata->vif; |
@@ -321,11 +324,10 @@ static int ieee80211_open(struct net_device *dev) | |||
321 | * yet be effective. Trigger execution of ieee80211_sta_work | 324 | * yet be effective. Trigger execution of ieee80211_sta_work |
322 | * to fix this. | 325 | * to fix this. |
323 | */ | 326 | */ |
324 | if (sdata->vif.type == NL80211_IFTYPE_STATION || | 327 | if (sdata->vif.type == NL80211_IFTYPE_STATION) |
325 | sdata->vif.type == NL80211_IFTYPE_ADHOC) { | 328 | queue_work(local->hw.workqueue, &sdata->u.mgd.work); |
326 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; | 329 | else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) |
327 | queue_work(local->hw.workqueue, &ifsta->work); | 330 | queue_work(local->hw.workqueue, &sdata->u.ibss.work); |
328 | } | ||
329 | 331 | ||
330 | netif_tx_start_all_queues(dev); | 332 | netif_tx_start_all_queues(dev); |
331 | 333 | ||
@@ -452,15 +454,13 @@ static int ieee80211_stop(struct net_device *dev) | |||
452 | netif_addr_unlock_bh(local->mdev); | 454 | netif_addr_unlock_bh(local->mdev); |
453 | break; | 455 | break; |
454 | case NL80211_IFTYPE_STATION: | 456 | case NL80211_IFTYPE_STATION: |
455 | case NL80211_IFTYPE_ADHOC: | ||
456 | /* Announce that we are leaving the network. */ | 457 | /* Announce that we are leaving the network. */ |
457 | if (sdata->u.sta.state != IEEE80211_STA_MLME_DISABLED) | 458 | if (sdata->u.mgd.state != IEEE80211_STA_MLME_DISABLED) |
458 | ieee80211_sta_deauthenticate(sdata, | 459 | ieee80211_sta_deauthenticate(sdata, |
459 | WLAN_REASON_DEAUTH_LEAVING); | 460 | WLAN_REASON_DEAUTH_LEAVING); |
460 | 461 | memset(sdata->u.mgd.bssid, 0, ETH_ALEN); | |
461 | memset(sdata->u.sta.bssid, 0, ETH_ALEN); | 462 | del_timer_sync(&sdata->u.mgd.chswitch_timer); |
462 | del_timer_sync(&sdata->u.sta.chswitch_timer); | 463 | del_timer_sync(&sdata->u.mgd.timer); |
463 | del_timer_sync(&sdata->u.sta.timer); | ||
464 | /* | 464 | /* |
465 | * If the timer fired while we waited for it, it will have | 465 | * If the timer fired while we waited for it, it will have |
466 | * requeued the work. Now the work will be running again | 466 | * requeued the work. Now the work will be running again |
@@ -468,8 +468,8 @@ static int ieee80211_stop(struct net_device *dev) | |||
468 | * whether the interface is running, which, at this point, | 468 | * whether the interface is running, which, at this point, |
469 | * it no longer is. | 469 | * it no longer is. |
470 | */ | 470 | */ |
471 | cancel_work_sync(&sdata->u.sta.work); | 471 | cancel_work_sync(&sdata->u.mgd.work); |
472 | cancel_work_sync(&sdata->u.sta.chswitch_work); | 472 | cancel_work_sync(&sdata->u.mgd.chswitch_work); |
473 | /* | 473 | /* |
474 | * When we get here, the interface is marked down. | 474 | * When we get here, the interface is marked down. |
475 | * Call synchronize_rcu() to wait for the RX path | 475 | * Call synchronize_rcu() to wait for the RX path |
@@ -477,13 +477,22 @@ static int ieee80211_stop(struct net_device *dev) | |||
477 | * frames at this very time on another CPU. | 477 | * frames at this very time on another CPU. |
478 | */ | 478 | */ |
479 | synchronize_rcu(); | 479 | synchronize_rcu(); |
480 | skb_queue_purge(&sdata->u.sta.skb_queue); | 480 | skb_queue_purge(&sdata->u.mgd.skb_queue); |
481 | 481 | ||
482 | sdata->u.sta.flags &= ~(IEEE80211_STA_PRIVACY_INVOKED | | 482 | sdata->u.mgd.flags &= ~(IEEE80211_STA_PRIVACY_INVOKED | |
483 | IEEE80211_STA_TKIP_WEP_USED); | 483 | IEEE80211_STA_TKIP_WEP_USED); |
484 | kfree(sdata->u.sta.extra_ie); | 484 | kfree(sdata->u.mgd.extra_ie); |
485 | sdata->u.sta.extra_ie = NULL; | 485 | sdata->u.mgd.extra_ie = NULL; |
486 | sdata->u.sta.extra_ie_len = 0; | 486 | sdata->u.mgd.extra_ie_len = 0; |
487 | /* fall through */ | ||
488 | case NL80211_IFTYPE_ADHOC: | ||
489 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { | ||
490 | memset(sdata->u.ibss.bssid, 0, ETH_ALEN); | ||
491 | del_timer_sync(&sdata->u.ibss.timer); | ||
492 | cancel_work_sync(&sdata->u.ibss.work); | ||
493 | synchronize_rcu(); | ||
494 | skb_queue_purge(&sdata->u.ibss.skb_queue); | ||
495 | } | ||
487 | /* fall through */ | 496 | /* fall through */ |
488 | case NL80211_IFTYPE_MESH_POINT: | 497 | case NL80211_IFTYPE_MESH_POINT: |
489 | if (ieee80211_vif_is_mesh(&sdata->vif)) { | 498 | if (ieee80211_vif_is_mesh(&sdata->vif)) { |
@@ -629,19 +638,20 @@ static void ieee80211_teardown_sdata(struct net_device *dev) | |||
629 | if (ieee80211_vif_is_mesh(&sdata->vif)) | 638 | if (ieee80211_vif_is_mesh(&sdata->vif)) |
630 | mesh_rmc_free(sdata); | 639 | mesh_rmc_free(sdata); |
631 | break; | 640 | break; |
632 | case NL80211_IFTYPE_STATION: | ||
633 | case NL80211_IFTYPE_ADHOC: | 641 | case NL80211_IFTYPE_ADHOC: |
634 | kfree(sdata->u.sta.extra_ie); | 642 | kfree_skb(sdata->u.ibss.probe_resp); |
635 | kfree(sdata->u.sta.assocreq_ies); | 643 | break; |
636 | kfree(sdata->u.sta.assocresp_ies); | 644 | case NL80211_IFTYPE_STATION: |
637 | kfree_skb(sdata->u.sta.probe_resp); | 645 | kfree(sdata->u.mgd.extra_ie); |
638 | kfree(sdata->u.sta.ie_probereq); | 646 | kfree(sdata->u.mgd.assocreq_ies); |
639 | kfree(sdata->u.sta.ie_proberesp); | 647 | kfree(sdata->u.mgd.assocresp_ies); |
640 | kfree(sdata->u.sta.ie_auth); | 648 | kfree(sdata->u.mgd.ie_probereq); |
641 | kfree(sdata->u.sta.ie_assocreq); | 649 | kfree(sdata->u.mgd.ie_proberesp); |
642 | kfree(sdata->u.sta.ie_reassocreq); | 650 | kfree(sdata->u.mgd.ie_auth); |
643 | kfree(sdata->u.sta.ie_deauth); | 651 | kfree(sdata->u.mgd.ie_assocreq); |
644 | kfree(sdata->u.sta.ie_disassoc); | 652 | kfree(sdata->u.mgd.ie_reassocreq); |
653 | kfree(sdata->u.mgd.ie_deauth); | ||
654 | kfree(sdata->u.mgd.ie_disassoc); | ||
645 | break; | 655 | break; |
646 | case NL80211_IFTYPE_WDS: | 656 | case NL80211_IFTYPE_WDS: |
647 | case NL80211_IFTYPE_AP_VLAN: | 657 | case NL80211_IFTYPE_AP_VLAN: |
@@ -708,9 +718,11 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, | |||
708 | INIT_LIST_HEAD(&sdata->u.ap.vlans); | 718 | INIT_LIST_HEAD(&sdata->u.ap.vlans); |
709 | break; | 719 | break; |
710 | case NL80211_IFTYPE_STATION: | 720 | case NL80211_IFTYPE_STATION: |
711 | case NL80211_IFTYPE_ADHOC: | ||
712 | ieee80211_sta_setup_sdata(sdata); | 721 | ieee80211_sta_setup_sdata(sdata); |
713 | break; | 722 | break; |
723 | case NL80211_IFTYPE_ADHOC: | ||
724 | ieee80211_ibss_setup_sdata(sdata); | ||
725 | break; | ||
714 | case NL80211_IFTYPE_MESH_POINT: | 726 | case NL80211_IFTYPE_MESH_POINT: |
715 | if (ieee80211_vif_is_mesh(&sdata->vif)) | 727 | if (ieee80211_vif_is_mesh(&sdata->vif)) |
716 | ieee80211_mesh_init_sdata(sdata); | 728 | ieee80211_mesh_init_sdata(sdata); |