aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/chan.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/chan.c')
-rw-r--r--net/mac80211/chan.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 166165efd8e2..03e8d2e3270e 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -79,6 +79,7 @@ ieee80211_new_chanctx(struct ieee80211_local *local,
79 enum ieee80211_chanctx_mode mode) 79 enum ieee80211_chanctx_mode mode)
80{ 80{
81 struct ieee80211_chanctx *ctx; 81 struct ieee80211_chanctx *ctx;
82 u32 changed;
82 int err; 83 int err;
83 84
84 lockdep_assert_held(&local->chanctx_mtx); 85 lockdep_assert_held(&local->chanctx_mtx);
@@ -95,6 +96,13 @@ ieee80211_new_chanctx(struct ieee80211_local *local,
95 if (!local->use_chanctx) 96 if (!local->use_chanctx)
96 local->hw.conf.radar_enabled = ctx->conf.radar_enabled; 97 local->hw.conf.radar_enabled = ctx->conf.radar_enabled;
97 98
99 /* acquire mutex to prevent idle from changing */
100 mutex_lock(&local->mtx);
101 /* turn idle off *before* setting channel -- some drivers need that */
102 changed = ieee80211_idle_off(local);
103 if (changed)
104 ieee80211_hw_config(local, changed);
105
98 if (!local->use_chanctx) { 106 if (!local->use_chanctx) {
99 local->_oper_chandef = *chandef; 107 local->_oper_chandef = *chandef;
100 ieee80211_hw_config(local, 0); 108 ieee80211_hw_config(local, 0);
@@ -102,14 +110,17 @@ ieee80211_new_chanctx(struct ieee80211_local *local,
102 err = drv_add_chanctx(local, ctx); 110 err = drv_add_chanctx(local, ctx);
103 if (err) { 111 if (err) {
104 kfree(ctx); 112 kfree(ctx);
105 return ERR_PTR(err); 113 ctx = ERR_PTR(err);
114
115 ieee80211_recalc_idle(local);
116 goto out;
106 } 117 }
107 } 118 }
108 119
120 /* and keep the mutex held until the new chanctx is on the list */
109 list_add_rcu(&ctx->list, &local->chanctx_list); 121 list_add_rcu(&ctx->list, &local->chanctx_list);
110 122
111 mutex_lock(&local->mtx); 123 out:
112 ieee80211_recalc_idle(local);
113 mutex_unlock(&local->mtx); 124 mutex_unlock(&local->mtx);
114 125
115 return ctx; 126 return ctx;