diff options
-rw-r--r-- | net/wireless/mlme.c | 20 |
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; |