diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /net/wireless/sme.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (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.c | 61 |
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 | ||
38 | bool 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 | |||
67 | static void disconnect_work(struct work_struct *work) | ||
68 | { | ||
69 | if (!cfg80211_is_all_idle()) | ||
70 | return; | ||
71 | |||
72 | regulatory_hint_disconnect(); | ||
73 | } | ||
74 | |||
75 | static DECLARE_WORK(cfg80211_disconnect_work, disconnect_work); | ||
37 | 76 | ||
38 | static int cfg80211_conn_scan(struct wireless_dev *wdev) | 77 | static 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 | } |
493 | EXPORT_SYMBOL(cfg80211_connect_result); | 533 | EXPORT_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 | } |
588 | EXPORT_SYMBOL(cfg80211_roamed); | 628 | EXPORT_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 | ||
661 | void cfg80211_disconnected(struct net_device *dev, u16 reason, | 704 | void 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 | } |
686 | EXPORT_SYMBOL(cfg80211_disconnected); | 729 | EXPORT_SYMBOL(cfg80211_disconnected); |
687 | 730 | ||