diff options
Diffstat (limited to 'net')
| -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; |
