The logic that tries to reuse an existing chanctx or create a new one if such doesn't exist will be used for other types of chanctx users. Extract this logic from _ieee80211_link_use_channel. Reviewed-by: Johannes Berg Signed-off-by: Miri Korenblit --- net/mac80211/chan.c | 54 ++++++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 1bcf501cfe8e..1669ebf77346 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -2031,6 +2031,36 @@ void __ieee80211_link_release_channel(struct ieee80211_link_data *link, ieee80211_vif_use_reserved_switch(local); } +static struct ieee80211_chanctx * +ieee80211_find_or_create_chanctx(struct ieee80211_sub_if_data *sdata, + const struct ieee80211_chan_req *chanreq, + enum ieee80211_chanctx_mode mode, + bool assign_on_failure, + bool *reused_ctx) +{ + struct ieee80211_local *local = sdata->local; + struct ieee80211_chanctx *ctx; + int radio_idx; + + lockdep_assert_wiphy(local->hw.wiphy); + + ctx = ieee80211_find_chanctx(local, chanreq, mode); + if (ctx) { + *reused_ctx = true; + return ctx; + } + + *reused_ctx = false; + + if (!ieee80211_find_available_radio(local, chanreq, + sdata->wdev.radio_mask, + &radio_idx)) + return ERR_PTR(-EBUSY); + + return ieee80211_new_chanctx(local, chanreq, mode, + assign_on_failure, radio_idx); +} + int _ieee80211_link_use_channel(struct ieee80211_link_data *link, const struct ieee80211_chan_req *chanreq, enum ieee80211_chanctx_mode mode, @@ -2039,9 +2069,8 @@ int _ieee80211_link_use_channel(struct ieee80211_link_data *link, struct ieee80211_sub_if_data *sdata = link->sdata; struct ieee80211_local *local = sdata->local; struct ieee80211_chanctx *ctx; - u8 radar_detect_width = 0; - bool reserved = false; - int radio_idx; + u8 radar_detect_width = 0; + bool reused_ctx = false; int ret; lockdep_assert_wiphy(local->hw.wiphy); @@ -2069,17 +2098,8 @@ int _ieee80211_link_use_channel(struct ieee80211_link_data *link, if (!local->in_reconfig) __ieee80211_link_release_channel(link, false); - ctx = ieee80211_find_chanctx(local, chanreq, mode); - /* Note: context will_be_used flag is now set */ - if (ctx) - reserved = true; - else if (!ieee80211_find_available_radio(local, chanreq, - sdata->wdev.radio_mask, - &radio_idx)) - ctx = ERR_PTR(-EBUSY); - else - ctx = ieee80211_new_chanctx(local, chanreq, mode, - assign_on_failure, radio_idx); + ctx = ieee80211_find_or_create_chanctx(sdata, chanreq, mode, + assign_on_failure, &reused_ctx); if (IS_ERR(ctx)) { ret = PTR_ERR(ctx); goto out; @@ -2089,7 +2109,11 @@ int _ieee80211_link_use_channel(struct ieee80211_link_data *link, ret = ieee80211_assign_link_chanctx(link, ctx, assign_on_failure); - if (reserved) { + /* + * In case an existing channel context is being used, we marked it as + * will_be_used, now that it is assigned - clear this indication + */ + if (reused_ctx) { WARN_ON(!ctx->will_be_used); ctx->will_be_used = false; } -- 2.34.1