diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index b73373a..7f0dd46 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -250,6 +250,7 @@ struct wpa_driver_nl80211_data {
 	unsigned int scan_for_auth:1;
 	unsigned int retry_auth:1;
 	unsigned int use_monitor:1;
+	unsigned int ignore_next_local_disconnect:1;
 
 	u64 remain_on_chan_cookie;
 	u64 send_action_cookie;
@@ -1191,6 +1192,7 @@ static void mlme_event_disconnect(struct wpa_driver_nl80211_data *drv,
 				  struct nlattr *by_ap)
 {
 	union wpa_event_data data;
+	unsigned int locally_generated = by_ap == NULL;
 
 	if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
 		/*
@@ -1201,6 +1203,18 @@ static void mlme_event_disconnect(struct wpa_driver_nl80211_data *drv,
 			   "event when using userspace SME");
 		return;
 	}
+	if (drv->ignore_next_local_disconnect) {
+		drv->ignore_next_local_disconnect = 0;
+		if (locally_generated) {
+			wpa_printf(MSG_DEBUG, "nl80211: Ignore disconnect "
+				   "event triggered during reassociation");
+			return;
+		}
+		wpa_printf(MSG_WARNING, "nl80211: Was expecting local "
+			   "disconnect but got another disconnect "
+			   "event first");
+	}
+
 
 	wpa_printf(MSG_DEBUG, "nl80211: Disconnect event");
 	drv->associated = 0;
@@ -4509,6 +4523,7 @@ static int wpa_driver_nl80211_disconnect(struct wpa_driver_nl80211_data *drv,
 {
 	wpa_printf(MSG_DEBUG, "%s(reason_code=%d)", __func__, reason_code);
 	drv->associated = 0;
+	drv->ignore_next_local_disconnect = 0;
 	/* Disconnect command doesn't need BSSID - it uses cached value */
 	return wpa_driver_nl80211_mlme(drv, NULL, NL80211_CMD_DISCONNECT,
 				       reason_code, 0);
@@ -6663,7 +6678,7 @@ nla_put_failure:
 }
 
 
-static int wpa_driver_nl80211_connect(
+static int wpa_driver_nl80211_try_connect(
 	struct wpa_driver_nl80211_data *drv,
 	struct wpa_driver_associate_params *params)
 {
@@ -6843,15 +6858,6 @@ skip_auth_type:
 	if (ret) {
 		wpa_printf(MSG_DEBUG, "nl80211: MLME connect failed: ret=%d "
 			   "(%s)", ret, strerror(-ret));
-		/*
-		 * cfg80211 does not currently accept new connection if we are
-		 * already connected. As a workaround, force disconnection and
-		 * try again once the driver indicates it completed
-		 * disconnection.
-		 */
-		if (ret == -EALREADY)
-			wpa_driver_nl80211_disconnect(
-				drv, WLAN_REASON_PREV_AUTH_NOT_VALID);
 		goto nla_put_failure;
 	}
 	ret = 0;
@@ -6864,6 +6870,31 @@ nla_put_failure:
 }
 
 
+static int wpa_driver_nl80211_connect(
+       struct wpa_driver_nl80211_data *drv,
+       struct wpa_driver_associate_params *params)
+{
+       int ret = wpa_driver_nl80211_try_connect(drv, params);
+       if (ret == -EALREADY) {
+               /*
+                * cfg80211 does not currently accept new connections if
+                * we are already connected. As a workaround, force
+                * disconnection and try again.
+                */
+               wpa_printf(MSG_DEBUG, "nl80211: Explicitly "
+                          "disconnecting before reassociation "
+                          "attempt");
+               if (wpa_driver_nl80211_disconnect(
+				drv, WLAN_REASON_PREV_AUTH_NOT_VALID))
+                       return -1;
+               /* Ignore the next local disconnect message. */
+               drv->ignore_next_local_disconnect = 1;
+               ret = wpa_driver_nl80211_try_connect(drv, params);
+       }
+       return ret;
+}
+
+
 static int wpa_driver_nl80211_associate(
 	void *priv, struct wpa_driver_associate_params *params)
 {
