aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/mlme.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/mlme.c')
-rw-r--r--net/wireless/mlme.c56
1 files changed, 43 insertions, 13 deletions
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 2610b746effa..1001db4912f7 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -243,21 +243,12 @@ void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len)
243} 243}
244EXPORT_SYMBOL(cfg80211_send_disassoc); 244EXPORT_SYMBOL(cfg80211_send_disassoc);
245 245
246void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr) 246static void __cfg80211_auth_remove(struct wireless_dev *wdev, const u8 *addr)
247{ 247{
248 struct wireless_dev *wdev = dev->ieee80211_ptr;
249 struct wiphy *wiphy = wdev->wiphy;
250 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
251 int i; 248 int i;
252 bool done = false; 249 bool done = false;
253 250
254 wdev_lock(wdev); 251 ASSERT_WDEV_LOCK(wdev);
255
256 nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL);
257 if (wdev->sme_state == CFG80211_SME_CONNECTING)
258 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
259 WLAN_STATUS_UNSPECIFIED_FAILURE,
260 false, NULL);
261 252
262 for (i = 0; addr && i < MAX_AUTH_BSSES; i++) { 253 for (i = 0; addr && i < MAX_AUTH_BSSES; i++) {
263 if (wdev->authtry_bsses[i] && 254 if (wdev->authtry_bsses[i] &&
@@ -272,6 +263,29 @@ void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
272 } 263 }
273 264
274 WARN_ON(!done); 265 WARN_ON(!done);
266}
267
268void __cfg80211_auth_canceled(struct net_device *dev, const u8 *addr)
269{
270 __cfg80211_auth_remove(dev->ieee80211_ptr, addr);
271}
272EXPORT_SYMBOL(__cfg80211_auth_canceled);
273
274void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
275{
276 struct wireless_dev *wdev = dev->ieee80211_ptr;
277 struct wiphy *wiphy = wdev->wiphy;
278 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
279
280 wdev_lock(wdev);
281
282 nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL);
283 if (wdev->sme_state == CFG80211_SME_CONNECTING)
284 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
285 WLAN_STATUS_UNSPECIFIED_FAILURE,
286 false, NULL);
287
288 __cfg80211_auth_remove(wdev, addr);
275 289
276 wdev_unlock(wdev); 290 wdev_unlock(wdev);
277} 291}
@@ -446,12 +460,23 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
446 struct cfg80211_assoc_request req; 460 struct cfg80211_assoc_request req;
447 struct cfg80211_internal_bss *bss; 461 struct cfg80211_internal_bss *bss;
448 int i, err, slot = -1; 462 int i, err, slot = -1;
463 bool was_connected = false;
449 464
450 ASSERT_WDEV_LOCK(wdev); 465 ASSERT_WDEV_LOCK(wdev);
451 466
452 memset(&req, 0, sizeof(req)); 467 memset(&req, 0, sizeof(req));
453 468
454 if (wdev->current_bss) 469 if (wdev->current_bss && prev_bssid &&
470 memcmp(wdev->current_bss->pub.bssid, prev_bssid, ETH_ALEN) == 0) {
471 /*
472 * Trying to reassociate: Allow this to proceed and let the old
473 * association to be dropped when the new one is completed.
474 */
475 if (wdev->sme_state == CFG80211_SME_CONNECTED) {
476 was_connected = true;
477 wdev->sme_state = CFG80211_SME_CONNECTING;
478 }
479 } else if (wdev->current_bss)
455 return -EALREADY; 480 return -EALREADY;
456 481
457 req.ie = ie; 482 req.ie = ie;
@@ -461,8 +486,11 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
461 req.prev_bssid = prev_bssid; 486 req.prev_bssid = prev_bssid;
462 req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, 487 req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
463 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); 488 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
464 if (!req.bss) 489 if (!req.bss) {
490 if (was_connected)
491 wdev->sme_state = CFG80211_SME_CONNECTED;
465 return -ENOENT; 492 return -ENOENT;
493 }
466 494
467 bss = bss_from_pub(req.bss); 495 bss = bss_from_pub(req.bss);
468 496
@@ -480,6 +508,8 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
480 508
481 err = rdev->ops->assoc(&rdev->wiphy, dev, &req); 509 err = rdev->ops->assoc(&rdev->wiphy, dev, &req);
482 out: 510 out:
511 if (err && was_connected)
512 wdev->sme_state = CFG80211_SME_CONNECTED;
483 /* still a reference in wdev->auth_bsses[slot] */ 513 /* still a reference in wdev->auth_bsses[slot] */
484 cfg80211_put_bss(req.bss); 514 cfg80211_put_bss(req.bss);
485 return err; 515 return err;