aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/sme.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /net/wireless/sme.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'net/wireless/sme.c')
-rw-r--r--net/wireless/sme.c61
1 files changed, 52 insertions, 9 deletions
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 9f0b2800a9d7..f4dfd5f5f2ea 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -7,6 +7,7 @@
7 7
8#include <linux/etherdevice.h> 8#include <linux/etherdevice.h>
9#include <linux/if_arp.h> 9#include <linux/if_arp.h>
10#include <linux/slab.h>
10#include <linux/workqueue.h> 11#include <linux/workqueue.h>
11#include <linux/wireless.h> 12#include <linux/wireless.h>
12#include <net/iw_handler.h> 13#include <net/iw_handler.h>
@@ -34,6 +35,44 @@ struct cfg80211_conn {
34 bool auto_auth, prev_bssid_valid; 35 bool auto_auth, prev_bssid_valid;
35}; 36};
36 37
38bool cfg80211_is_all_idle(void)
39{
40 struct cfg80211_registered_device *rdev;
41 struct wireless_dev *wdev;
42 bool is_all_idle = true;
43
44 mutex_lock(&cfg80211_mutex);
45
46 /*
47 * All devices must be idle as otherwise if you are actively
48 * scanning some new beacon hints could be learned and would
49 * count as new regulatory hints.
50 */
51 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
52 cfg80211_lock_rdev(rdev);
53 list_for_each_entry(wdev, &rdev->netdev_list, list) {
54 wdev_lock(wdev);
55 if (wdev->sme_state != CFG80211_SME_IDLE)
56 is_all_idle = false;
57 wdev_unlock(wdev);
58 }
59 cfg80211_unlock_rdev(rdev);
60 }
61
62 mutex_unlock(&cfg80211_mutex);
63
64 return is_all_idle;
65}
66
67static void disconnect_work(struct work_struct *work)
68{
69 if (!cfg80211_is_all_idle())
70 return;
71
72 regulatory_hint_disconnect();
73}
74
75static DECLARE_WORK(cfg80211_disconnect_work, disconnect_work);
37 76
38static int cfg80211_conn_scan(struct wireless_dev *wdev) 77static int cfg80211_conn_scan(struct wireless_dev *wdev)
39{ 78{
@@ -365,7 +404,7 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
365{ 404{
366 struct wireless_dev *wdev = dev->ieee80211_ptr; 405 struct wireless_dev *wdev = dev->ieee80211_ptr;
367 u8 *country_ie; 406 u8 *country_ie;
368#ifdef CONFIG_WIRELESS_EXT 407#ifdef CONFIG_CFG80211_WEXT
369 union iwreq_data wrqu; 408 union iwreq_data wrqu;
370#endif 409#endif
371 410
@@ -382,7 +421,7 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
382 resp_ie, resp_ie_len, 421 resp_ie, resp_ie_len,
383 status, GFP_KERNEL); 422 status, GFP_KERNEL);
384 423
385#ifdef CONFIG_WIRELESS_EXT 424#ifdef CONFIG_CFG80211_WEXT
386 if (wextev) { 425 if (wextev) {
387 if (req_ie && status == WLAN_STATUS_SUCCESS) { 426 if (req_ie && status == WLAN_STATUS_SUCCESS) {
388 memset(&wrqu, 0, sizeof(wrqu)); 427 memset(&wrqu, 0, sizeof(wrqu));
@@ -454,6 +493,7 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
454 * - and country_ie[1] which is the IE length 493 * - and country_ie[1] which is the IE length
455 */ 494 */
456 regulatory_hint_11d(wdev->wiphy, 495 regulatory_hint_11d(wdev->wiphy,
496 bss->channel->band,
457 country_ie + 2, 497 country_ie + 2,
458 country_ie[1]); 498 country_ie[1]);
459} 499}
@@ -488,7 +528,7 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
488 spin_lock_irqsave(&wdev->event_lock, flags); 528 spin_lock_irqsave(&wdev->event_lock, flags);
489 list_add_tail(&ev->list, &wdev->event_list); 529 list_add_tail(&ev->list, &wdev->event_list);
490 spin_unlock_irqrestore(&wdev->event_lock, flags); 530 spin_unlock_irqrestore(&wdev->event_lock, flags);
491 schedule_work(&rdev->event_work); 531 queue_work(cfg80211_wq, &rdev->event_work);
492} 532}
493EXPORT_SYMBOL(cfg80211_connect_result); 533EXPORT_SYMBOL(cfg80211_connect_result);
494 534
@@ -497,7 +537,7 @@ void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid,
497 const u8 *resp_ie, size_t resp_ie_len) 537 const u8 *resp_ie, size_t resp_ie_len)
498{ 538{
499 struct cfg80211_bss *bss; 539 struct cfg80211_bss *bss;
500#ifdef CONFIG_WIRELESS_EXT 540#ifdef CONFIG_CFG80211_WEXT
501 union iwreq_data wrqu; 541 union iwreq_data wrqu;
502#endif 542#endif
503 543
@@ -532,7 +572,7 @@ void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid,
532 req_ie, req_ie_len, resp_ie, resp_ie_len, 572 req_ie, req_ie_len, resp_ie, resp_ie_len,
533 GFP_KERNEL); 573 GFP_KERNEL);
534 574
535#ifdef CONFIG_WIRELESS_EXT 575#ifdef CONFIG_CFG80211_WEXT
536 if (req_ie) { 576 if (req_ie) {
537 memset(&wrqu, 0, sizeof(wrqu)); 577 memset(&wrqu, 0, sizeof(wrqu));
538 wrqu.data.length = req_ie_len; 578 wrqu.data.length = req_ie_len;
@@ -583,7 +623,7 @@ void cfg80211_roamed(struct net_device *dev, const u8 *bssid,
583 spin_lock_irqsave(&wdev->event_lock, flags); 623 spin_lock_irqsave(&wdev->event_lock, flags);
584 list_add_tail(&ev->list, &wdev->event_list); 624 list_add_tail(&ev->list, &wdev->event_list);
585 spin_unlock_irqrestore(&wdev->event_lock, flags); 625 spin_unlock_irqrestore(&wdev->event_lock, flags);
586 schedule_work(&rdev->event_work); 626 queue_work(cfg80211_wq, &rdev->event_work);
587} 627}
588EXPORT_SYMBOL(cfg80211_roamed); 628EXPORT_SYMBOL(cfg80211_roamed);
589 629
@@ -593,7 +633,7 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
593 struct wireless_dev *wdev = dev->ieee80211_ptr; 633 struct wireless_dev *wdev = dev->ieee80211_ptr;
594 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 634 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
595 int i; 635 int i;
596#ifdef CONFIG_WIRELESS_EXT 636#ifdef CONFIG_CFG80211_WEXT
597 union iwreq_data wrqu; 637 union iwreq_data wrqu;
598#endif 638#endif
599 639
@@ -651,11 +691,14 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
651 for (i = 0; i < 6; i++) 691 for (i = 0; i < 6; i++)
652 rdev->ops->del_key(wdev->wiphy, dev, i, NULL); 692 rdev->ops->del_key(wdev->wiphy, dev, i, NULL);
653 693
654#ifdef CONFIG_WIRELESS_EXT 694#ifdef CONFIG_CFG80211_WEXT
655 memset(&wrqu, 0, sizeof(wrqu)); 695 memset(&wrqu, 0, sizeof(wrqu));
656 wrqu.ap_addr.sa_family = ARPHRD_ETHER; 696 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
657 wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); 697 wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
698 wdev->wext.connect.ssid_len = 0;
658#endif 699#endif
700
701 schedule_work(&cfg80211_disconnect_work);
659} 702}
660 703
661void cfg80211_disconnected(struct net_device *dev, u16 reason, 704void cfg80211_disconnected(struct net_device *dev, u16 reason,
@@ -681,7 +724,7 @@ void cfg80211_disconnected(struct net_device *dev, u16 reason,
681 spin_lock_irqsave(&wdev->event_lock, flags); 724 spin_lock_irqsave(&wdev->event_lock, flags);
682 list_add_tail(&ev->list, &wdev->event_list); 725 list_add_tail(&ev->list, &wdev->event_list);
683 spin_unlock_irqrestore(&wdev->event_lock, flags); 726 spin_unlock_irqrestore(&wdev->event_lock, flags);
684 schedule_work(&rdev->event_work); 727 queue_work(cfg80211_wq, &rdev->event_work);
685} 728}
686EXPORT_SYMBOL(cfg80211_disconnected); 729EXPORT_SYMBOL(cfg80211_disconnected);
687 730