summaryrefslogtreecommitdiff
path: root/net/wireless/sme.c
diff options
context:
space:
mode:
authorKanchanapally, Vidyullatha <vkanchan@qti.qualcomm.com>2016-04-11 15:16:01 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2016-08-29 01:45:00 -0700
commit9f28983d4e1b093e5daa0f4a59d6faeff8520da4 (patch)
treec4f1a2d174dd7e04398d53c7ab593981d5fb1fbc /net/wireless/sme.c
parentbc2630b4c908d45b24398acb45d7f912de3bf338 (diff)
cfg80211: Add option to report the bss entry in connect result
Since cfg80211 maintains separate BSS table entries for APs if the same BSSID, SSID pair is seen on multiple channels, it is possible that it can map the current_bss to a BSS entry on the wrong channel. This current_bss will not get flushed unless disconnected and cfg80211 reports a wrong channel as the associated channel. Fix this by introducing a new cfg80211_connect_bss() function which is similar to cfg80211_connect_result(), but it includes an additional parameter: the bss the STA is connected to. This allows drivers to provide the exact bss entry that matches the BSS to which the connection was completed. Reviewed-by: Jouni Malinen <jouni@qca.qualcomm.com> Signed-off-by: Vidyullatha Kanchanapally <vkanchan@qti.qualcomm.com> Signed-off-by: Sunil Dutt <usdutt@qti.qualcomm.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com> Git-commit: 81948527fce52c73c9a0742b8ec8d26b97f6c3c0 Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git Change-Id: I5dc58b360b2bbce53493466a0bcd5363276c302a CRs-fixed: 1008791 Signed-off-by: Vidyullatha Kanchanapally <vidyullatha@codeaurora.org>
Diffstat (limited to 'net/wireless/sme.c')
-rw-r--r--net/wireless/sme.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 44f420dfa8e3..37d8ab3a71be 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -767,19 +767,32 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
kfree(country_ie);
}
-void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
- const u8 *req_ie, size_t req_ie_len,
- const u8 *resp_ie, size_t resp_ie_len,
- u16 status, gfp_t gfp)
+/* Consumes bss object one way or another */
+void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,
+ struct cfg80211_bss *bss, const u8 *req_ie,
+ size_t req_ie_len, const u8 *resp_ie,
+ size_t resp_ie_len, u16 status, gfp_t gfp)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
struct cfg80211_event *ev;
unsigned long flags;
+ if (bss) {
+ /* Make sure the bss entry provided by the driver is valid. */
+ struct cfg80211_internal_bss *ibss = bss_from_pub(bss);
+
+ if (WARN_ON(list_empty(&ibss->list))) {
+ cfg80211_put_bss(wdev->wiphy, bss);
+ return;
+ }
+ }
+
ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp);
- if (!ev)
+ if (!ev) {
+ cfg80211_put_bss(wdev->wiphy, bss);
return;
+ }
ev->type = EVENT_CONNECT_RESULT;
if (bssid)
@@ -794,6 +807,9 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
ev->cr.resp_ie_len = resp_ie_len;
memcpy((void *)ev->cr.resp_ie, resp_ie, resp_ie_len);
}
+ if (bss)
+ cfg80211_hold_bss(bss_from_pub(bss));
+ ev->cr.bss = bss;
ev->cr.status = status;
spin_lock_irqsave(&wdev->event_lock, flags);
@@ -801,7 +817,7 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
spin_unlock_irqrestore(&wdev->event_lock, flags);
queue_work(cfg80211_wq, &rdev->event_work);
}
-EXPORT_SYMBOL(cfg80211_connect_result);
+EXPORT_SYMBOL(cfg80211_connect_bss);
/* Consumes bss object one way or another */
void __cfg80211_roamed(struct wireless_dev *wdev,