diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index d4e84b22a66d8b92a082b483b3003f80bce7cf6d..090e344d5f90ccd2d5e23b1ab152382c2f6af20f 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -943,11 +943,6 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
 		}
 	}
 
-	del_timer_sync(&sdata->u.ibss.timer);
-	clear_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
-	cancel_work_sync(&sdata->work);
-	clear_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
-
 	sta_info_flush(sdata->local, sdata);
 
 	/* remove beacon */
@@ -964,6 +959,20 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
 	memset(sdata->u.ibss.bssid, 0, ETH_ALEN);
 	sdata->u.ibss.ssid_len = 0;
 
+	/*
+	 * ssid_len indicates active or not, so needs to be visible to
+	 * everybody, especially ieee80211_ibss_notify_scan_completed,
+	 * so it won't restart the timer after we remove it here.
+	 */
+	mb();
+
+	del_timer_sync(&sdata->u.ibss.timer);
+	clear_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
+	/*
+	 * Since the REQ_RUN bit is clear, the work won't do
+	 * anything if it runs after this.
+	 */
+
 	ieee80211_recalc_idle(sdata->local);
 
 	return 0;