aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/iface.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/iface.c')
-rw-r--r--net/mac80211/iface.c76
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);