diff options
-rw-r--r-- | Documentation/DocBook/80211.tmpl | 1 | ||||
-rw-r--r-- | include/net/cfg80211.h | 39 | ||||
-rw-r--r-- | net/wireless/core.h | 1 | ||||
-rw-r--r-- | net/wireless/sme.c | 28 | ||||
-rw-r--r-- | net/wireless/util.c | 2 |
5 files changed, 60 insertions, 11 deletions
diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl index f2a312b35875..5f7c55999c77 100644 --- a/Documentation/DocBook/80211.tmpl +++ b/Documentation/DocBook/80211.tmpl | |||
@@ -135,6 +135,7 @@ | |||
135 | !Finclude/net/cfg80211.h cfg80211_tx_mlme_mgmt | 135 | !Finclude/net/cfg80211.h cfg80211_tx_mlme_mgmt |
136 | !Finclude/net/cfg80211.h cfg80211_ibss_joined | 136 | !Finclude/net/cfg80211.h cfg80211_ibss_joined |
137 | !Finclude/net/cfg80211.h cfg80211_connect_result | 137 | !Finclude/net/cfg80211.h cfg80211_connect_result |
138 | !Finclude/net/cfg80211.h cfg80211_connect_bss | ||
138 | !Finclude/net/cfg80211.h cfg80211_roamed | 139 | !Finclude/net/cfg80211.h cfg80211_roamed |
139 | !Finclude/net/cfg80211.h cfg80211_disconnected | 140 | !Finclude/net/cfg80211.h cfg80211_disconnected |
140 | !Finclude/net/cfg80211.h cfg80211_ready_on_channel | 141 | !Finclude/net/cfg80211.h cfg80211_ready_on_channel |
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index c8414962683d..1e008cddd41d 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -4652,6 +4652,32 @@ static inline void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp) | |||
4652 | #endif | 4652 | #endif |
4653 | 4653 | ||
4654 | /** | 4654 | /** |
4655 | * cfg80211_connect_bss - notify cfg80211 of connection result | ||
4656 | * | ||
4657 | * @dev: network device | ||
4658 | * @bssid: the BSSID of the AP | ||
4659 | * @bss: entry of bss to which STA got connected to, can be obtained | ||
4660 | * through cfg80211_get_bss (may be %NULL) | ||
4661 | * @req_ie: association request IEs (maybe be %NULL) | ||
4662 | * @req_ie_len: association request IEs length | ||
4663 | * @resp_ie: association response IEs (may be %NULL) | ||
4664 | * @resp_ie_len: assoc response IEs length | ||
4665 | * @status: status code, 0 for successful connection, use | ||
4666 | * %WLAN_STATUS_UNSPECIFIED_FAILURE if your device cannot give you | ||
4667 | * the real status code for failures. | ||
4668 | * @gfp: allocation flags | ||
4669 | * | ||
4670 | * It should be called by the underlying driver whenever connect() has | ||
4671 | * succeeded. This is similar to cfg80211_connect_result(), but with the | ||
4672 | * option of identifying the exact bss entry for the connection. Only one of | ||
4673 | * these functions should be called. | ||
4674 | */ | ||
4675 | void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid, | ||
4676 | struct cfg80211_bss *bss, const u8 *req_ie, | ||
4677 | size_t req_ie_len, const u8 *resp_ie, | ||
4678 | size_t resp_ie_len, u16 status, gfp_t gfp); | ||
4679 | |||
4680 | /** | ||
4655 | * cfg80211_connect_result - notify cfg80211 of connection result | 4681 | * cfg80211_connect_result - notify cfg80211 of connection result |
4656 | * | 4682 | * |
4657 | * @dev: network device | 4683 | * @dev: network device |
@@ -4668,10 +4694,15 @@ static inline void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp) | |||
4668 | * It should be called by the underlying driver whenever connect() has | 4694 | * It should be called by the underlying driver whenever connect() has |
4669 | * succeeded. | 4695 | * succeeded. |
4670 | */ | 4696 | */ |
4671 | void cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | 4697 | static inline void |
4672 | const u8 *req_ie, size_t req_ie_len, | 4698 | cfg80211_connect_result(struct net_device *dev, const u8 *bssid, |
4673 | const u8 *resp_ie, size_t resp_ie_len, | 4699 | const u8 *req_ie, size_t req_ie_len, |
4674 | u16 status, gfp_t gfp); | 4700 | const u8 *resp_ie, size_t resp_ie_len, |
4701 | u16 status, gfp_t gfp) | ||
4702 | { | ||
4703 | cfg80211_connect_bss(dev, bssid, NULL, req_ie, req_ie_len, resp_ie, | ||
4704 | resp_ie_len, status, gfp); | ||
4705 | } | ||
4675 | 4706 | ||
4676 | /** | 4707 | /** |
4677 | * cfg80211_roamed - notify cfg80211 of roaming | 4708 | * cfg80211_roamed - notify cfg80211 of roaming |
diff --git a/net/wireless/core.h b/net/wireless/core.h index 022ccad06cbe..ac44e77ac2f2 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -214,6 +214,7 @@ struct cfg80211_event { | |||
214 | const u8 *resp_ie; | 214 | const u8 *resp_ie; |
215 | size_t req_ie_len; | 215 | size_t req_ie_len; |
216 | size_t resp_ie_len; | 216 | size_t resp_ie_len; |
217 | struct cfg80211_bss *bss; | ||
217 | u16 status; | 218 | u16 status; |
218 | } cr; | 219 | } cr; |
219 | struct { | 220 | struct { |
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index e22e5b83cfa9..d814279fb556 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -753,19 +753,32 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | |||
753 | kfree(country_ie); | 753 | kfree(country_ie); |
754 | } | 754 | } |
755 | 755 | ||
756 | void cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | 756 | /* Consumes bss object one way or another */ |
757 | const u8 *req_ie, size_t req_ie_len, | 757 | void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid, |
758 | const u8 *resp_ie, size_t resp_ie_len, | 758 | struct cfg80211_bss *bss, const u8 *req_ie, |
759 | u16 status, gfp_t gfp) | 759 | size_t req_ie_len, const u8 *resp_ie, |
760 | size_t resp_ie_len, u16 status, gfp_t gfp) | ||
760 | { | 761 | { |
761 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 762 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
762 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); | 763 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
763 | struct cfg80211_event *ev; | 764 | struct cfg80211_event *ev; |
764 | unsigned long flags; | 765 | unsigned long flags; |
765 | 766 | ||
767 | if (bss) { | ||
768 | /* Make sure the bss entry provided by the driver is valid. */ | ||
769 | struct cfg80211_internal_bss *ibss = bss_from_pub(bss); | ||
770 | |||
771 | if (WARN_ON(list_empty(&ibss->list))) { | ||
772 | cfg80211_put_bss(wdev->wiphy, bss); | ||
773 | return; | ||
774 | } | ||
775 | } | ||
776 | |||
766 | ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp); | 777 | ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp); |
767 | if (!ev) | 778 | if (!ev) { |
779 | cfg80211_put_bss(wdev->wiphy, bss); | ||
768 | return; | 780 | return; |
781 | } | ||
769 | 782 | ||
770 | ev->type = EVENT_CONNECT_RESULT; | 783 | ev->type = EVENT_CONNECT_RESULT; |
771 | if (bssid) | 784 | if (bssid) |
@@ -780,6 +793,9 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | |||
780 | ev->cr.resp_ie_len = resp_ie_len; | 793 | ev->cr.resp_ie_len = resp_ie_len; |
781 | memcpy((void *)ev->cr.resp_ie, resp_ie, resp_ie_len); | 794 | memcpy((void *)ev->cr.resp_ie, resp_ie, resp_ie_len); |
782 | } | 795 | } |
796 | if (bss) | ||
797 | cfg80211_hold_bss(bss_from_pub(bss)); | ||
798 | ev->cr.bss = bss; | ||
783 | ev->cr.status = status; | 799 | ev->cr.status = status; |
784 | 800 | ||
785 | spin_lock_irqsave(&wdev->event_lock, flags); | 801 | spin_lock_irqsave(&wdev->event_lock, flags); |
@@ -787,7 +803,7 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | |||
787 | spin_unlock_irqrestore(&wdev->event_lock, flags); | 803 | spin_unlock_irqrestore(&wdev->event_lock, flags); |
788 | queue_work(cfg80211_wq, &rdev->event_work); | 804 | queue_work(cfg80211_wq, &rdev->event_work); |
789 | } | 805 | } |
790 | EXPORT_SYMBOL(cfg80211_connect_result); | 806 | EXPORT_SYMBOL(cfg80211_connect_bss); |
791 | 807 | ||
792 | /* Consumes bss object one way or another */ | 808 | /* Consumes bss object one way or another */ |
793 | void __cfg80211_roamed(struct wireless_dev *wdev, | 809 | void __cfg80211_roamed(struct wireless_dev *wdev, |
diff --git a/net/wireless/util.c b/net/wireless/util.c index f36039888eb5..7cfabd6e83c6 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
@@ -950,7 +950,7 @@ void cfg80211_process_wdev_events(struct wireless_dev *wdev) | |||
950 | ev->cr.resp_ie, ev->cr.resp_ie_len, | 950 | ev->cr.resp_ie, ev->cr.resp_ie_len, |
951 | ev->cr.status, | 951 | ev->cr.status, |
952 | ev->cr.status == WLAN_STATUS_SUCCESS, | 952 | ev->cr.status == WLAN_STATUS_SUCCESS, |
953 | NULL); | 953 | ev->cr.bss); |
954 | break; | 954 | break; |
955 | case EVENT_ROAMED: | 955 | case EVENT_ROAMED: |
956 | __cfg80211_roamed(wdev, ev->rm.bss, ev->rm.req_ie, | 956 | __cfg80211_roamed(wdev, ev->rm.bss, ev->rm.req_ie, |