diff options
Diffstat (limited to 'net/mac80211/chan.c')
-rw-r--r-- | net/mac80211/chan.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 78c0d90dd641..931be419ab5a 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c | |||
@@ -63,6 +63,7 @@ ieee80211_new_chanctx(struct ieee80211_local *local, | |||
63 | enum ieee80211_chanctx_mode mode) | 63 | enum ieee80211_chanctx_mode mode) |
64 | { | 64 | { |
65 | struct ieee80211_chanctx *ctx; | 65 | struct ieee80211_chanctx *ctx; |
66 | u32 changed; | ||
66 | int err; | 67 | int err; |
67 | 68 | ||
68 | lockdep_assert_held(&local->chanctx_mtx); | 69 | lockdep_assert_held(&local->chanctx_mtx); |
@@ -76,6 +77,13 @@ ieee80211_new_chanctx(struct ieee80211_local *local, | |||
76 | ctx->conf.rx_chains_dynamic = 1; | 77 | ctx->conf.rx_chains_dynamic = 1; |
77 | ctx->mode = mode; | 78 | ctx->mode = mode; |
78 | 79 | ||
80 | /* acquire mutex to prevent idle from changing */ | ||
81 | mutex_lock(&local->mtx); | ||
82 | /* turn idle off *before* setting channel -- some drivers need that */ | ||
83 | changed = ieee80211_idle_off(local); | ||
84 | if (changed) | ||
85 | ieee80211_hw_config(local, changed); | ||
86 | |||
79 | if (!local->use_chanctx) { | 87 | if (!local->use_chanctx) { |
80 | local->_oper_channel_type = | 88 | local->_oper_channel_type = |
81 | cfg80211_get_chandef_type(chandef); | 89 | cfg80211_get_chandef_type(chandef); |
@@ -85,14 +93,17 @@ ieee80211_new_chanctx(struct ieee80211_local *local, | |||
85 | err = drv_add_chanctx(local, ctx); | 93 | err = drv_add_chanctx(local, ctx); |
86 | if (err) { | 94 | if (err) { |
87 | kfree(ctx); | 95 | kfree(ctx); |
88 | return ERR_PTR(err); | 96 | ctx = ERR_PTR(err); |
97 | |||
98 | ieee80211_recalc_idle(local); | ||
99 | goto out; | ||
89 | } | 100 | } |
90 | } | 101 | } |
91 | 102 | ||
103 | /* and keep the mutex held until the new chanctx is on the list */ | ||
92 | list_add_rcu(&ctx->list, &local->chanctx_list); | 104 | list_add_rcu(&ctx->list, &local->chanctx_list); |
93 | 105 | ||
94 | mutex_lock(&local->mtx); | 106 | out: |
95 | ieee80211_recalc_idle(local); | ||
96 | mutex_unlock(&local->mtx); | 107 | mutex_unlock(&local->mtx); |
97 | 108 | ||
98 | return ctx; | 109 | return ctx; |