summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--net/mac80211/ibss.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index d4e84b22a66d..090e344d5f90 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;