diff options
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r-- | net/mac80211/main.c | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index ebdec7106d63..4bfac4b41c51 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -564,14 +564,6 @@ static int ieee80211_stop(struct net_device *dev) | |||
564 | synchronize_rcu(); | 564 | synchronize_rcu(); |
565 | skb_queue_purge(&sdata->u.sta.skb_queue); | 565 | skb_queue_purge(&sdata->u.sta.skb_queue); |
566 | 566 | ||
567 | if (local->scan_sdata == sdata) { | ||
568 | if (!local->ops->hw_scan) { | ||
569 | local->sta_sw_scanning = 0; | ||
570 | cancel_delayed_work(&local->scan_work); | ||
571 | } else | ||
572 | local->sta_hw_scanning = 0; | ||
573 | } | ||
574 | |||
575 | sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED; | 567 | sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED; |
576 | kfree(sdata->u.sta.extra_ie); | 568 | kfree(sdata->u.sta.extra_ie); |
577 | sdata->u.sta.extra_ie = NULL; | 569 | sdata->u.sta.extra_ie = NULL; |
@@ -585,6 +577,31 @@ static int ieee80211_stop(struct net_device *dev) | |||
585 | } | 577 | } |
586 | /* fall through */ | 578 | /* fall through */ |
587 | default: | 579 | default: |
580 | if (local->scan_sdata == sdata) { | ||
581 | if (!local->ops->hw_scan) | ||
582 | cancel_delayed_work_sync(&local->scan_work); | ||
583 | /* | ||
584 | * The software scan can no longer run now, so we can | ||
585 | * clear out the scan_sdata reference. However, the | ||
586 | * hardware scan may still be running. The complete | ||
587 | * function must be prepared to handle a NULL value. | ||
588 | */ | ||
589 | local->scan_sdata = NULL; | ||
590 | /* | ||
591 | * The memory barrier guarantees that another CPU | ||
592 | * that is hardware-scanning will now see the fact | ||
593 | * that this interface is gone. | ||
594 | */ | ||
595 | smp_mb(); | ||
596 | /* | ||
597 | * If software scanning, complete the scan but since | ||
598 | * the scan_sdata is NULL already don't send out a | ||
599 | * scan event to userspace -- the scan is incomplete. | ||
600 | */ | ||
601 | if (local->sta_sw_scanning) | ||
602 | ieee80211_scan_completed(&local->hw); | ||
603 | } | ||
604 | |||
588 | conf.vif = &sdata->vif; | 605 | conf.vif = &sdata->vif; |
589 | conf.type = sdata->vif.type; | 606 | conf.type = sdata->vif.type; |
590 | conf.mac_addr = dev->dev_addr; | 607 | conf.mac_addr = dev->dev_addr; |