diff options
| author | Miri Korenblit <miriam.rachel.korenblit@intel.com> | 2026-05-27 22:51:43 +0300 |
|---|---|---|
| committer | Johannes Berg <johannes.berg@intel.com> | 2026-05-28 09:50:22 +0200 |
| commit | 8facc23dc26eb185146a6c0ae68ae6b9f130eee2 (patch) | |
| tree | 5ca374768090da4fc6ab8628694b99dda9067676 /net | |
| parent | 847f7ead7bdcd6ef4aef12fb1efbd4bf276d0a13 (diff) | |
| download | linux-next-history-8facc23dc26eb185146a6c0ae68ae6b9f130eee2.tar.gz | |
wifi: mac80211: add an option to filter out a channel in combinations check
Sometimes, ieee80211_check_combinations fails, but it is hard to know
why exactly. We will have to return an array of reasons, one per
combination.
In cases where we want to check if it failed because there are not
enough chanctxs (and maybe remove one if needed), we can just not fill
in that chanctx(s) in iface_combination_params::num_different_channels
in ieee80211_fill_ifcomb_params, so that chanctx(s) won't be taken into
account.
To allow that, add an option to pass a callback to
ieee80211_fill_ifcomb_params. This callback will be called for each
chanctx we consider to count in num_different_channels and will return
whether or not this chanctx should be skipped and not counted.
This mechanism will be used later.
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260527224745.0042232f996e.I5d323125e34f3b253510e85ceb7a770d59f689fb@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
| -rw-r--r-- | net/mac80211/ieee80211_i.h | 34 | ||||
| -rw-r--r-- | net/mac80211/util.c | 34 |
2 files changed, 51 insertions, 17 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 1360522649c25..20b27c8f7d4e2 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -2818,10 +2818,36 @@ int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata, struct cfg80211_csa_settings *csa_settings); void ieee80211_recalc_sb_count(struct ieee80211_sub_if_data *sdata, u64 tsf); void ieee80211_recalc_dtim(struct ieee80211_sub_if_data *sdata, u64 tsf); -int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, - const struct cfg80211_chan_def *chandef, - enum ieee80211_chanctx_mode chanmode, - u8 radar_detect, int radio_idx); + +struct ieee80211_check_combinations_data { + const struct cfg80211_chan_def *chandef; + enum ieee80211_chanctx_mode chanmode; + u8 radar_detect; + int radio_idx; + bool (*chanctx_filter)(struct ieee80211_chanctx *ctx, + void *filter_data); + void *filter_data; +}; + +int ieee80211_check_combinations_ext(struct ieee80211_sub_if_data *sdata, + struct ieee80211_check_combinations_data *data); + +static inline int +ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, + const struct cfg80211_chan_def *chandef, + enum ieee80211_chanctx_mode chanmode, + u8 radar_detect, int radio_idx) +{ + struct ieee80211_check_combinations_data data = { + .chandef = chandef, + .chanmode = chanmode, + .radar_detect = radar_detect, + .radio_idx = radio_idx, + }; + + return ieee80211_check_combinations_ext(sdata, &data); +} + int ieee80211_max_num_channels(struct ieee80211_local *local, int radio_idx); u32 ieee80211_get_radio_mask(struct wiphy *wiphy, struct net_device *dev); void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local, diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 255905f971c8a..2a7ab269687a0 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -4260,7 +4260,10 @@ static int ieee80211_fill_ifcomb_params(struct ieee80211_local *local, struct iface_combination_params *params, const struct cfg80211_chan_def *chandef, - struct ieee80211_sub_if_data *sdata) + struct ieee80211_sub_if_data *sdata, + bool (*chanctx_filter)(struct ieee80211_chanctx *ctx, + void *filter_data), + void *filter_data) { struct ieee80211_sub_if_data *sdata_iter; struct ieee80211_chanctx *ctx; @@ -4281,6 +4284,10 @@ ieee80211_fill_ifcomb_params(struct ieee80211_local *local, cfg80211_chandef_compatible(chandef, &ctx->conf.def)) continue; + if (chanctx_filter && + chanctx_filter(ctx, filter_data)) + continue; + params->num_different_channels++; } @@ -4305,26 +4312,25 @@ ieee80211_fill_ifcomb_params(struct ieee80211_local *local, return total; } -int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, - const struct cfg80211_chan_def *chandef, - enum ieee80211_chanctx_mode chanmode, - u8 radar_detect, int radio_idx) +int ieee80211_check_combinations_ext(struct ieee80211_sub_if_data *sdata, + struct ieee80211_check_combinations_data *data) { - bool shared = chanmode == IEEE80211_CHANCTX_SHARED; + const struct cfg80211_chan_def *chandef = data->chandef; + bool shared = data->chanmode == IEEE80211_CHANCTX_SHARED; struct ieee80211_local *local = sdata->local; enum nl80211_iftype iftype = sdata->wdev.iftype; struct iface_combination_params params = { - .radar_detect = radar_detect, - .radio_idx = radio_idx, + .radar_detect = data->radar_detect, + .radio_idx = data->radio_idx, }; int total; lockdep_assert_wiphy(local->hw.wiphy); - if (WARN_ON(hweight32(radar_detect) > 1)) + if (WARN_ON(hweight32(data->radar_detect) > 1)) return -EINVAL; - if (WARN_ON(chandef && chanmode == IEEE80211_CHANCTX_SHARED && + if (WARN_ON(chandef && data->chanmode == IEEE80211_CHANCTX_SHARED && !chandef->chan)) return -EINVAL; @@ -4343,7 +4349,7 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, /* Always allow software iftypes */ if (cfg80211_iftype_allowed(local->hw.wiphy, iftype, 0, 1)) { - if (radar_detect) + if (data->radar_detect) return -EINVAL; return 0; } @@ -4356,7 +4362,9 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, total = ieee80211_fill_ifcomb_params(local, ¶ms, shared ? chandef : NULL, - sdata); + sdata, + data->chanctx_filter, + data->filter_data); if (total == 1 && !params.radar_detect) return 0; @@ -4383,7 +4391,7 @@ int ieee80211_max_num_channels(struct ieee80211_local *local, int radio_idx) lockdep_assert_wiphy(local->hw.wiphy); - ieee80211_fill_ifcomb_params(local, ¶ms, NULL, NULL); + ieee80211_fill_ifcomb_params(local, ¶ms, NULL, NULL, NULL, NULL); err = cfg80211_iter_combinations(local->hw.wiphy, ¶ms, ieee80211_iter_max_chans, |
