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; |
