aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/driver-ops.h
diff options
context:
space:
mode:
authorEliad Peller <eliad@wizery.com>2015-10-25 10:59:36 +0200
committerJohannes Berg <johannes.berg@intel.com>2015-11-03 10:41:12 +0100
commit968a76cef3d1bb9a3b4d135cd788056e742859f3 (patch)
treedfe73df7dae4879fe96b045cdffc0d2d64e829be /net/mac80211/driver-ops.h
parentmac80211: Remove WARN_ON_ONCE in ieee80211_recalc_smps (diff)
downloadlinux-dev-968a76cef3d1bb9a3b4d135cd788056e742859f3.tar.xz
linux-dev-968a76cef3d1bb9a3b4d135cd788056e742859f3.zip
mac80211: call drv_stop only if driver is started
If drv_start() fails during hw_restart, all the running interfaces are being closed/stopped, which results in drv_stop() being called, although the driver was never started successfully. This might cause drivers to perform operations on uninitialized memory (as they assume it was initialized on drv_start) Consider the local->started flag, and call the driver's stop() op only if drv_start() succeeded before. Move drv_start() and drv_stop() to driver-ops.c, as they are no longer simple wrappers. Signed-off-by: Eliad Peller <eliadx.peller@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/driver-ops.h')
-rw-r--r--net/mac80211/driver-ops.h32
1 files changed, 2 insertions, 30 deletions
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 30987099eb8f..f82cfab615f2 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -66,36 +66,8 @@ static inline int drv_get_et_sset_count(struct ieee80211_sub_if_data *sdata,
return rv;
}
-static inline int drv_start(struct ieee80211_local *local)
-{
- int ret;
-
- might_sleep();
-
- trace_drv_start(local);
- local->started = true;
- smp_mb();
- ret = local->ops->start(&local->hw);
- trace_drv_return_int(local, ret);
- return ret;
-}
-
-static inline void drv_stop(struct ieee80211_local *local)
-{
- might_sleep();
-
- trace_drv_stop(local);
- local->ops->stop(&local->hw);
- trace_drv_return_void(local);
-
- /* sync away all work on the tasklet before clearing started */
- tasklet_disable(&local->tasklet);
- tasklet_enable(&local->tasklet);
-
- barrier();
-
- local->started = false;
-}
+int drv_start(struct ieee80211_local *local);
+void drv_stop(struct ieee80211_local *local);
#ifdef CONFIG_PM
static inline int drv_suspend(struct ieee80211_local *local,