aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/DocBook/80211.tmpl1
-rw-r--r--include/net/cfg80211.h39
-rw-r--r--net/wireless/core.h1
-rw-r--r--net/wireless/sme.c28
-rw-r--r--net/wireless/util.c2
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 */
4675void 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 */
4671void cfg80211_connect_result(struct net_device *dev, const u8 *bssid, 4697static inline void
4672 const u8 *req_ie, size_t req_ie_len, 4698cfg80211_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
756void 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, 757void 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}
790EXPORT_SYMBOL(cfg80211_connect_result); 806EXPORT_SYMBOL(cfg80211_connect_bss);
791 807
792/* Consumes bss object one way or another */ 808/* Consumes bss object one way or another */
793void __cfg80211_roamed(struct wireless_dev *wdev, 809void __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,