]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/wireless/mlme.c
cfg80211: Allow reassociation in associated state
[karo-tx-linux.git] / net / wireless / mlme.c
index 2610b746effaefc2ca40a4d221e5e3b88ea647b3..622af5649b9a68ff15d93fa7a0c7357a3d2ffbcd 100644 (file)
@@ -446,12 +446,23 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
        struct cfg80211_assoc_request req;
        struct cfg80211_internal_bss *bss;
        int i, err, slot = -1;
+       bool was_connected = false;
 
        ASSERT_WDEV_LOCK(wdev);
 
        memset(&req, 0, sizeof(req));
 
-       if (wdev->current_bss)
+       if (wdev->current_bss && prev_bssid &&
+           memcmp(wdev->current_bss->pub.bssid, prev_bssid, ETH_ALEN) == 0) {
+               /*
+                * Trying to reassociate: Allow this to proceed and let the old
+                * association to be dropped when the new one is completed.
+                */
+               if (wdev->sme_state == CFG80211_SME_CONNECTED) {
+                       was_connected = true;
+                       wdev->sme_state = CFG80211_SME_CONNECTING;
+               }
+       } else if (wdev->current_bss)
                return -EALREADY;
 
        req.ie = ie;
@@ -461,8 +472,11 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
        req.prev_bssid = prev_bssid;
        req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
                                   WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
-       if (!req.bss)
+       if (!req.bss) {
+               if (was_connected)
+                       wdev->sme_state = CFG80211_SME_CONNECTED;
                return -ENOENT;
+       }
 
        bss = bss_from_pub(req.bss);
 
@@ -480,6 +494,8 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
 
        err = rdev->ops->assoc(&rdev->wiphy, dev, &req);
  out:
+       if (err && was_connected)
+               wdev->sme_state = CFG80211_SME_CONNECTED;
        /* still a reference in wdev->auth_bsses[slot] */
        cfg80211_put_bss(req.bss);
        return err;