diff options
Diffstat (limited to 'net/wireless/sme.c')
-rw-r--r-- | net/wireless/sme.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 745c37e7992e..17fde0da1b08 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -34,6 +34,44 @@ struct cfg80211_conn { | |||
34 | bool auto_auth, prev_bssid_valid; | 34 | bool auto_auth, prev_bssid_valid; |
35 | }; | 35 | }; |
36 | 36 | ||
37 | bool cfg80211_is_all_idle(void) | ||
38 | { | ||
39 | struct cfg80211_registered_device *rdev; | ||
40 | struct wireless_dev *wdev; | ||
41 | bool is_all_idle = true; | ||
42 | |||
43 | mutex_lock(&cfg80211_mutex); | ||
44 | |||
45 | /* | ||
46 | * All devices must be idle as otherwise if you are actively | ||
47 | * scanning some new beacon hints could be learned and would | ||
48 | * count as new regulatory hints. | ||
49 | */ | ||
50 | list_for_each_entry(rdev, &cfg80211_rdev_list, list) { | ||
51 | cfg80211_lock_rdev(rdev); | ||
52 | list_for_each_entry(wdev, &rdev->netdev_list, list) { | ||
53 | wdev_lock(wdev); | ||
54 | if (wdev->sme_state != CFG80211_SME_IDLE) | ||
55 | is_all_idle = false; | ||
56 | wdev_unlock(wdev); | ||
57 | } | ||
58 | cfg80211_unlock_rdev(rdev); | ||
59 | } | ||
60 | |||
61 | mutex_unlock(&cfg80211_mutex); | ||
62 | |||
63 | return is_all_idle; | ||
64 | } | ||
65 | |||
66 | static void disconnect_work(struct work_struct *work) | ||
67 | { | ||
68 | if (!cfg80211_is_all_idle()) | ||
69 | return; | ||
70 | |||
71 | regulatory_hint_disconnect(); | ||
72 | } | ||
73 | |||
74 | static DECLARE_WORK(cfg80211_disconnect_work, disconnect_work); | ||
37 | 75 | ||
38 | static int cfg80211_conn_scan(struct wireless_dev *wdev) | 76 | static int cfg80211_conn_scan(struct wireless_dev *wdev) |
39 | { | 77 | { |
@@ -658,6 +696,8 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, | |||
658 | wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); | 696 | wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); |
659 | wdev->wext.connect.ssid_len = 0; | 697 | wdev->wext.connect.ssid_len = 0; |
660 | #endif | 698 | #endif |
699 | |||
700 | schedule_work(&cfg80211_disconnect_work); | ||
661 | } | 701 | } |
662 | 702 | ||
663 | void cfg80211_disconnected(struct net_device *dev, u16 reason, | 703 | void cfg80211_disconnected(struct net_device *dev, u16 reason, |