Commit 6265c67f authored by Felix Fietkau's avatar Felix Fietkau Committed by Johannes Berg

wifi: mac80211: move code in ieee80211_link_reserve_chanctx to a helper

Reduces indentation in preparation for further changes
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
Link: https://patch.msgid.link/cce95007092336254d51570f4a27e05a6f150a53.1720514221.git-series.nbd@nbd.nameSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 0874bcd0
......@@ -1089,6 +1089,71 @@ int ieee80211_link_unreserve_chanctx(struct ieee80211_link_data *link)
return 0;
}
static struct ieee80211_chanctx *
ieee80211_replace_chanctx(struct ieee80211_local *local,
const struct ieee80211_chan_req *chanreq,
enum ieee80211_chanctx_mode mode,
struct ieee80211_chanctx *curr_ctx)
{
struct ieee80211_chanctx *new_ctx, *ctx;
if (!curr_ctx || (curr_ctx->replace_state ==
IEEE80211_CHANCTX_WILL_BE_REPLACED) ||
!list_empty(&curr_ctx->reserved_links)) {
/*
* Another link already requested this context for a
* reservation. Find another one hoping all links assigned
* to it will also switch soon enough.
*
* TODO: This needs a little more work as some cases
* (more than 2 chanctx capable devices) may fail which could
* otherwise succeed provided some channel context juggling was
* performed.
*
* Consider ctx1..3, link1..6, each ctx has 2 links. link1 and
* link2 from ctx1 request new different chandefs starting 2
* in-place reserations with ctx4 and ctx5 replacing ctx1 and
* ctx2 respectively. Next link5 and link6 from ctx3 reserve
* ctx4. If link3 and link4 remain on ctx2 as they are then this
* fails unless `replace_ctx` from ctx5 is replaced with ctx3.
*/
list_for_each_entry(ctx, &local->chanctx_list, list) {
if (ctx->replace_state !=
IEEE80211_CHANCTX_REPLACE_NONE)
continue;
if (!list_empty(&ctx->reserved_links))
continue;
curr_ctx = ctx;
break;
}
}
/*
* If that's true then all available contexts already have reservations
* and cannot be used.
*/
if (!curr_ctx || (curr_ctx->replace_state ==
IEEE80211_CHANCTX_WILL_BE_REPLACED) ||
!list_empty(&curr_ctx->reserved_links))
return ERR_PTR(-EBUSY);
new_ctx = ieee80211_alloc_chanctx(local, chanreq, mode, -1);
if (!new_ctx)
return ERR_PTR(-ENOMEM);
new_ctx->replace_ctx = curr_ctx;
new_ctx->replace_state = IEEE80211_CHANCTX_REPLACES_OTHER;
curr_ctx->replace_ctx = new_ctx;
curr_ctx->replace_state = IEEE80211_CHANCTX_WILL_BE_REPLACED;
list_add_rcu(&new_ctx->list, &local->chanctx_list);
return new_ctx;
}
int ieee80211_link_reserve_chanctx(struct ieee80211_link_data *link,
const struct ieee80211_chan_req *chanreq,
enum ieee80211_chanctx_mode mode,
......@@ -1096,7 +1161,7 @@ int ieee80211_link_reserve_chanctx(struct ieee80211_link_data *link,
{
struct ieee80211_sub_if_data *sdata = link->sdata;
struct ieee80211_local *local = sdata->local;
struct ieee80211_chanctx *new_ctx, *curr_ctx, *ctx;
struct ieee80211_chanctx *new_ctx, *curr_ctx;
lockdep_assert_wiphy(local->hw.wiphy);
......@@ -1106,76 +1171,14 @@ int ieee80211_link_reserve_chanctx(struct ieee80211_link_data *link,
new_ctx = ieee80211_find_reservation_chanctx(local, chanreq, mode);
if (!new_ctx) {
if (ieee80211_can_create_new_chanctx(local, -1)) {
if (ieee80211_can_create_new_chanctx(local, -1))
new_ctx = ieee80211_new_chanctx(local, chanreq, mode,
false);
if (IS_ERR(new_ctx))
return PTR_ERR(new_ctx);
} else {
if (!curr_ctx ||
(curr_ctx->replace_state ==
IEEE80211_CHANCTX_WILL_BE_REPLACED) ||
!list_empty(&curr_ctx->reserved_links)) {
/*
* Another link already requested this context
* for a reservation. Find another one hoping
* all links assigned to it will also switch
* soon enough.
*
* TODO: This needs a little more work as some
* cases (more than 2 chanctx capable devices)
* may fail which could otherwise succeed
* provided some channel context juggling was
* performed.
*
* Consider ctx1..3, link1..6, each ctx has 2
* links. link1 and link2 from ctx1 request new
* different chandefs starting 2 in-place
* reserations with ctx4 and ctx5 replacing
* ctx1 and ctx2 respectively. Next link5 and
* link6 from ctx3 reserve ctx4. If link3 and
* link4 remain on ctx2 as they are then this
* fails unless `replace_ctx` from ctx5 is
* replaced with ctx3.
*/
list_for_each_entry(ctx, &local->chanctx_list,
list) {
if (ctx->replace_state !=
IEEE80211_CHANCTX_REPLACE_NONE)
continue;
if (!list_empty(&ctx->reserved_links))
continue;
curr_ctx = ctx;
break;
}
}
/*
* If that's true then all available contexts already
* have reservations and cannot be used.
*/
if (!curr_ctx ||
(curr_ctx->replace_state ==
IEEE80211_CHANCTX_WILL_BE_REPLACED) ||
!list_empty(&curr_ctx->reserved_links))
return -EBUSY;
new_ctx = ieee80211_alloc_chanctx(local, chanreq, mode, -1);
if (!new_ctx)
return -ENOMEM;
new_ctx->replace_ctx = curr_ctx;
new_ctx->replace_state =
IEEE80211_CHANCTX_REPLACES_OTHER;
curr_ctx->replace_ctx = new_ctx;
curr_ctx->replace_state =
IEEE80211_CHANCTX_WILL_BE_REPLACED;
list_add_rcu(&new_ctx->list, &local->chanctx_list);
}
else
new_ctx = ieee80211_replace_chanctx(local, chanreq,
mode, curr_ctx);
if (IS_ERR(new_ctx))
return PTR_ERR(new_ctx);
}
list_add(&link->reserved_chanctx_list, &new_ctx->reserved_links);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment