Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bc86863d authored by Stanislaw Gruszka's avatar Stanislaw Gruszka Committed by John W. Linville
Browse files

mac80211: perform scan cancel in hw reset work

Move ieee80211_scan_cancel() and all other related code to
ieee80211_restart_work() as ieee80211_restart_hw() is intended to be
callable from any context.

Fix a bug that RTNL lock is not taken during ieee80211_cancel_scan().

Take local->mtx before WARN(test_bit(SCAN_HW_SCANNING, &local->scanning)
to prevent the race condition with __ieee80211_start_scan() described
here: http://marc.info/?l=linux-wireless&m=128516716810537&w=2



Signed-off-by: default avatarStanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 8e0167a4
Loading
Loading
Loading
Loading
+10 −9
Original line number Diff line number Diff line
@@ -295,7 +295,17 @@ static void ieee80211_restart_work(struct work_struct *work)
	struct ieee80211_local *local =
		container_of(work, struct ieee80211_local, restart_work);

	/* wait for scan work complete */
	flush_workqueue(local->workqueue);

	mutex_lock(&local->mtx);
	WARN(test_bit(SCAN_HW_SCANNING, &local->scanning),
		"%s called with hardware scan in progress\n", __func__);
	mutex_unlock(&local->mtx);

	rtnl_lock();
	if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning)))
		ieee80211_scan_cancel(local);
	ieee80211_reconfig(local);
	rtnl_unlock();
}
@@ -306,15 +316,6 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw)

	trace_api_restart_hw(local);

	/* wait for scan work complete */
	flush_workqueue(local->workqueue);

	WARN(test_bit(SCAN_HW_SCANNING, &local->scanning),
		"%s called with hardware scan in progress\n", __func__);

	if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning)))
		ieee80211_scan_cancel(local);

	/* use this reason, ieee80211_reconfig will unblock it */
	ieee80211_stop_queues_by_reason(hw,
		IEEE80211_QUEUE_STOP_REASON_SUSPEND);