aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/wireless/mlme.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 2610b746effa..622af5649b9a 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -446,12 +446,23 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
446 struct cfg80211_assoc_request req; 446 struct cfg80211_assoc_request req;
447 struct cfg80211_internal_bss *bss; 447 struct cfg80211_internal_bss *bss;
448 int i, err, slot = -1; 448 int i, err, slot = -1;
449 bool was_connected = false;
449 450
450 ASSERT_WDEV_LOCK(wdev); 451 ASSERT_WDEV_LOCK(wdev);
451 452
452 memset(&req, 0, sizeof(req)); 453 memset(&req, 0, sizeof(req));
453 454
454 if (wdev->current_bss) 455 if (wdev->current_bss && prev_bssid &&
456 memcmp(wdev->current_bss->pub.bssid, prev_bssid, ETH_ALEN) == 0) {
457 /*
458 * Trying to reassociate: Allow this to proceed and let the old
459 * association to be dropped when the new one is completed.
460 */
461 if (wdev->sme_state == CFG80211_SME_CONNECTED) {
462 was_connected = true;
463 wdev->sme_state = CFG80211_SME_CONNECTING;
464 }
465 } else if (wdev->current_bss)
455 return -EALREADY; 466 return -EALREADY;
456 467
457 req.ie = ie; 468 req.ie = ie;
@@ -461,8 +472,11 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
461 req.prev_bssid = prev_bssid; 472 req.prev_bssid = prev_bssid;
462 req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, 473 req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
463 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); 474 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
464 if (!req.bss) 475 if (!req.bss) {
476 if (was_connected)
477 wdev->sme_state = CFG80211_SME_CONNECTED;
465 return -ENOENT; 478 return -ENOENT;
479 }
466 480
467 bss = bss_from_pub(req.bss); 481 bss = bss_from_pub(req.bss);
468 482
@@ -480,6 +494,8 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
480 494
481 err = rdev->ops->assoc(&rdev->wiphy, dev, &req); 495 err = rdev->ops->assoc(&rdev->wiphy, dev, &req);
482 out: 496 out:
497 if (err && was_connected)
498 wdev->sme_state = CFG80211_SME_CONNECTED;
483 /* still a reference in wdev->auth_bsses[slot] */ 499 /* still a reference in wdev->auth_bsses[slot] */
484 cfg80211_put_bss(req.bss); 500 cfg80211_put_bss(req.bss);
485 return err; 501 return err;