Commit e227300c authored by Purushottam Kushwaha's avatar Purushottam Kushwaha Committed by Johannes Berg

cfg80211: pass struct to interface combination check/iter

Move the growing parameter list to a structure for the interface
combination check and iteration functions in cfg80211 and mac80211
to make the code easier to understand.
Signed-off-by: default avatarPurushottam Kushwaha <pkushwah@qti.qualcomm.com>
[edit commit message]
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 32910bb9
...@@ -414,23 +414,24 @@ static int brcmf_vif_change_validate(struct brcmf_cfg80211_info *cfg, ...@@ -414,23 +414,24 @@ static int brcmf_vif_change_validate(struct brcmf_cfg80211_info *cfg,
struct brcmf_cfg80211_vif *vif, struct brcmf_cfg80211_vif *vif,
enum nl80211_iftype new_type) enum nl80211_iftype new_type)
{ {
int iftype_num[NUM_NL80211_IFTYPES];
struct brcmf_cfg80211_vif *pos; struct brcmf_cfg80211_vif *pos;
bool check_combos = false; bool check_combos = false;
int ret = 0; int ret = 0;
struct iface_combination_params params = {
.num_different_channels = 1,
};
memset(&iftype_num[0], 0, sizeof(iftype_num));
list_for_each_entry(pos, &cfg->vif_list, list) list_for_each_entry(pos, &cfg->vif_list, list)
if (pos == vif) { if (pos == vif) {
iftype_num[new_type]++; params.iftype_num[new_type]++;
} else { } else {
/* concurrent interfaces so need check combinations */ /* concurrent interfaces so need check combinations */
check_combos = true; check_combos = true;
iftype_num[pos->wdev.iftype]++; params.iftype_num[pos->wdev.iftype]++;
} }
if (check_combos) if (check_combos)
ret = cfg80211_check_combinations(cfg->wiphy, 1, 0, iftype_num); ret = cfg80211_check_combinations(cfg->wiphy, &params);
return ret; return ret;
} }
...@@ -438,15 +439,16 @@ static int brcmf_vif_change_validate(struct brcmf_cfg80211_info *cfg, ...@@ -438,15 +439,16 @@ static int brcmf_vif_change_validate(struct brcmf_cfg80211_info *cfg,
static int brcmf_vif_add_validate(struct brcmf_cfg80211_info *cfg, static int brcmf_vif_add_validate(struct brcmf_cfg80211_info *cfg,
enum nl80211_iftype new_type) enum nl80211_iftype new_type)
{ {
int iftype_num[NUM_NL80211_IFTYPES];
struct brcmf_cfg80211_vif *pos; struct brcmf_cfg80211_vif *pos;
struct iface_combination_params params = {
.num_different_channels = 1,
};
memset(&iftype_num[0], 0, sizeof(iftype_num));
list_for_each_entry(pos, &cfg->vif_list, list) list_for_each_entry(pos, &cfg->vif_list, list)
iftype_num[pos->wdev.iftype]++; params.iftype_num[pos->wdev.iftype]++;
iftype_num[new_type]++; params.iftype_num[new_type]++;
return cfg80211_check_combinations(cfg->wiphy, 1, 0, iftype_num); return cfg80211_check_combinations(cfg->wiphy, &params);
} }
static void convert_key_from_CPU(struct brcmf_wsec_key *key, static void convert_key_from_CPU(struct brcmf_wsec_key *key,
......
...@@ -771,6 +771,26 @@ struct cfg80211_csa_settings { ...@@ -771,6 +771,26 @@ struct cfg80211_csa_settings {
u8 count; u8 count;
}; };
/**
* struct iface_combination_params - input parameters for interface combinations
*
* Used to pass interface combination parameters
*
* @num_different_channels: the number of different channels we want
* to use for verification
* @radar_detect: a bitmap where each bit corresponds to a channel
* width where radar detection is needed, as in the definition of
* &struct ieee80211_iface_combination.@radar_detect_widths
* @iftype_num: array with the number of interfaces of each interface
* type. The index is the interface type as specified in &enum
* nl80211_iftype.
*/
struct iface_combination_params {
int num_different_channels;
u8 radar_detect;
int iftype_num[NUM_NL80211_IFTYPES];
};
/** /**
* enum station_parameters_apply_mask - station parameter values to apply * enum station_parameters_apply_mask - station parameter values to apply
* @STATION_PARAM_APPLY_UAPSD: apply new uAPSD parameters (uapsd_queues, max_sp) * @STATION_PARAM_APPLY_UAPSD: apply new uAPSD parameters (uapsd_queues, max_sp)
...@@ -5575,36 +5595,20 @@ unsigned int ieee80211_get_num_supported_channels(struct wiphy *wiphy); ...@@ -5575,36 +5595,20 @@ unsigned int ieee80211_get_num_supported_channels(struct wiphy *wiphy);
* cfg80211_check_combinations - check interface combinations * cfg80211_check_combinations - check interface combinations
* *
* @wiphy: the wiphy * @wiphy: the wiphy
* @num_different_channels: the number of different channels we want * @params: the interface combinations parameter
* to use for verification
* @radar_detect: a bitmap where each bit corresponds to a channel
* width where radar detection is needed, as in the definition of
* &struct ieee80211_iface_combination.@radar_detect_widths
* @iftype_num: array with the numbers of interfaces of each interface
* type. The index is the interface type as specified in &enum
* nl80211_iftype.
* *
* This function can be called by the driver to check whether a * This function can be called by the driver to check whether a
* combination of interfaces and their types are allowed according to * combination of interfaces and their types are allowed according to
* the interface combinations. * the interface combinations.
*/ */
int cfg80211_check_combinations(struct wiphy *wiphy, int cfg80211_check_combinations(struct wiphy *wiphy,
const int num_different_channels, struct iface_combination_params *params);
const u8 radar_detect,
const int iftype_num[NUM_NL80211_IFTYPES]);
/** /**
* cfg80211_iter_combinations - iterate over matching combinations * cfg80211_iter_combinations - iterate over matching combinations
* *
* @wiphy: the wiphy * @wiphy: the wiphy
* @num_different_channels: the number of different channels we want * @params: the interface combinations parameter
* to use for verification
* @radar_detect: a bitmap where each bit corresponds to a channel
* width where radar detection is needed, as in the definition of
* &struct ieee80211_iface_combination.@radar_detect_widths
* @iftype_num: array with the numbers of interfaces of each interface
* type. The index is the interface type as specified in &enum
* nl80211_iftype.
* @iter: function to call for each matching combination * @iter: function to call for each matching combination
* @data: pointer to pass to iter function * @data: pointer to pass to iter function
* *
...@@ -5613,9 +5617,7 @@ int cfg80211_check_combinations(struct wiphy *wiphy, ...@@ -5613,9 +5617,7 @@ int cfg80211_check_combinations(struct wiphy *wiphy,
* purposes. * purposes.
*/ */
int cfg80211_iter_combinations(struct wiphy *wiphy, int cfg80211_iter_combinations(struct wiphy *wiphy,
const int num_different_channels, struct iface_combination_params *params,
const u8 radar_detect,
const int iftype_num[NUM_NL80211_IFTYPES],
void (*iter)(const struct ieee80211_iface_combination *c, void (*iter)(const struct ieee80211_iface_combination *c,
void *data), void *data),
void *data); void *data);
......
...@@ -3308,10 +3308,11 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, ...@@ -3308,10 +3308,11 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
struct ieee80211_local *local = sdata->local; struct ieee80211_local *local = sdata->local;
struct ieee80211_sub_if_data *sdata_iter; struct ieee80211_sub_if_data *sdata_iter;
enum nl80211_iftype iftype = sdata->wdev.iftype; enum nl80211_iftype iftype = sdata->wdev.iftype;
int num[NUM_NL80211_IFTYPES];
struct ieee80211_chanctx *ctx; struct ieee80211_chanctx *ctx;
int num_different_channels = 0;
int total = 1; int total = 1;
struct iface_combination_params params = {
.radar_detect = radar_detect,
};
lockdep_assert_held(&local->chanctx_mtx); lockdep_assert_held(&local->chanctx_mtx);
...@@ -3322,9 +3323,6 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, ...@@ -3322,9 +3323,6 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
!chandef->chan)) !chandef->chan))
return -EINVAL; return -EINVAL;
if (chandef)
num_different_channels = 1;
if (WARN_ON(iftype >= NUM_NL80211_IFTYPES)) if (WARN_ON(iftype >= NUM_NL80211_IFTYPES))
return -EINVAL; return -EINVAL;
...@@ -3335,24 +3333,26 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, ...@@ -3335,24 +3333,26 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
return 0; return 0;
} }
memset(num, 0, sizeof(num)); if (chandef)
params.num_different_channels = 1;
if (iftype != NL80211_IFTYPE_UNSPECIFIED) if (iftype != NL80211_IFTYPE_UNSPECIFIED)
num[iftype] = 1; params.iftype_num[iftype] = 1;
list_for_each_entry(ctx, &local->chanctx_list, list) { list_for_each_entry(ctx, &local->chanctx_list, list) {
if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED) if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED)
continue; continue;
radar_detect |= ieee80211_chanctx_radar_detect(local, ctx); params.radar_detect |=
ieee80211_chanctx_radar_detect(local, ctx);
if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) { if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) {
num_different_channels++; params.num_different_channels++;
continue; continue;
} }
if (chandef && chanmode == IEEE80211_CHANCTX_SHARED && if (chandef && chanmode == IEEE80211_CHANCTX_SHARED &&
cfg80211_chandef_compatible(chandef, cfg80211_chandef_compatible(chandef,
&ctx->conf.def)) &ctx->conf.def))
continue; continue;
num_different_channels++; params.num_different_channels++;
} }
list_for_each_entry_rcu(sdata_iter, &local->interfaces, list) { list_for_each_entry_rcu(sdata_iter, &local->interfaces, list) {
...@@ -3365,16 +3365,14 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, ...@@ -3365,16 +3365,14 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
local->hw.wiphy->software_iftypes & BIT(wdev_iter->iftype)) local->hw.wiphy->software_iftypes & BIT(wdev_iter->iftype))
continue; continue;
num[wdev_iter->iftype]++; params.iftype_num[wdev_iter->iftype]++;
total++; total++;
} }
if (total == 1 && !radar_detect) if (total == 1 && !params.radar_detect)
return 0; return 0;
return cfg80211_check_combinations(local->hw.wiphy, return cfg80211_check_combinations(local->hw.wiphy, &params);
num_different_channels,
radar_detect, num);
} }
static void static void
...@@ -3390,12 +3388,10 @@ ieee80211_iter_max_chans(const struct ieee80211_iface_combination *c, ...@@ -3390,12 +3388,10 @@ ieee80211_iter_max_chans(const struct ieee80211_iface_combination *c,
int ieee80211_max_num_channels(struct ieee80211_local *local) int ieee80211_max_num_channels(struct ieee80211_local *local)
{ {
struct ieee80211_sub_if_data *sdata; struct ieee80211_sub_if_data *sdata;
int num[NUM_NL80211_IFTYPES] = {};
struct ieee80211_chanctx *ctx; struct ieee80211_chanctx *ctx;
int num_different_channels = 0;
u8 radar_detect = 0;
u32 max_num_different_channels = 1; u32 max_num_different_channels = 1;
int err; int err;
struct iface_combination_params params = {0};
lockdep_assert_held(&local->chanctx_mtx); lockdep_assert_held(&local->chanctx_mtx);
...@@ -3403,17 +3399,17 @@ int ieee80211_max_num_channels(struct ieee80211_local *local) ...@@ -3403,17 +3399,17 @@ int ieee80211_max_num_channels(struct ieee80211_local *local)
if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED) if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED)
continue; continue;
num_different_channels++; params.num_different_channels++;
radar_detect |= ieee80211_chanctx_radar_detect(local, ctx); params.radar_detect |=
ieee80211_chanctx_radar_detect(local, ctx);
} }
list_for_each_entry_rcu(sdata, &local->interfaces, list) list_for_each_entry_rcu(sdata, &local->interfaces, list)
num[sdata->wdev.iftype]++; params.iftype_num[sdata->wdev.iftype]++;
err = cfg80211_iter_combinations(local->hw.wiphy, err = cfg80211_iter_combinations(local->hw.wiphy, &params,
num_different_channels, radar_detect, ieee80211_iter_max_chans,
num, ieee80211_iter_max_chans,
&max_num_different_channels); &max_num_different_channels);
if (err < 0) if (err < 0)
return err; return err;
......
...@@ -1580,9 +1580,7 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, ...@@ -1580,9 +1580,7 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
} }
int cfg80211_iter_combinations(struct wiphy *wiphy, int cfg80211_iter_combinations(struct wiphy *wiphy,
const int num_different_channels, struct iface_combination_params *params,
const u8 radar_detect,
const int iftype_num[NUM_NL80211_IFTYPES],
void (*iter)(const struct ieee80211_iface_combination *c, void (*iter)(const struct ieee80211_iface_combination *c,
void *data), void *data),
void *data) void *data)
...@@ -1593,7 +1591,7 @@ int cfg80211_iter_combinations(struct wiphy *wiphy, ...@@ -1593,7 +1591,7 @@ int cfg80211_iter_combinations(struct wiphy *wiphy,
int num_interfaces = 0; int num_interfaces = 0;
u32 used_iftypes = 0; u32 used_iftypes = 0;
if (radar_detect) { if (params->radar_detect) {
rcu_read_lock(); rcu_read_lock();
regdom = rcu_dereference(cfg80211_regdomain); regdom = rcu_dereference(cfg80211_regdomain);
if (regdom) if (regdom)
...@@ -1602,8 +1600,8 @@ int cfg80211_iter_combinations(struct wiphy *wiphy, ...@@ -1602,8 +1600,8 @@ int cfg80211_iter_combinations(struct wiphy *wiphy,
} }
for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) {
num_interfaces += iftype_num[iftype]; num_interfaces += params->iftype_num[iftype];
if (iftype_num[iftype] > 0 && if (params->iftype_num[iftype] > 0 &&
!(wiphy->software_iftypes & BIT(iftype))) !(wiphy->software_iftypes & BIT(iftype)))
used_iftypes |= BIT(iftype); used_iftypes |= BIT(iftype);
} }
...@@ -1617,7 +1615,7 @@ int cfg80211_iter_combinations(struct wiphy *wiphy, ...@@ -1617,7 +1615,7 @@ int cfg80211_iter_combinations(struct wiphy *wiphy,
if (num_interfaces > c->max_interfaces) if (num_interfaces > c->max_interfaces)
continue; continue;
if (num_different_channels > c->num_different_channels) if (params->num_different_channels > c->num_different_channels)
continue; continue;
limits = kmemdup(c->limits, sizeof(limits[0]) * c->n_limits, limits = kmemdup(c->limits, sizeof(limits[0]) * c->n_limits,
...@@ -1632,16 +1630,17 @@ int cfg80211_iter_combinations(struct wiphy *wiphy, ...@@ -1632,16 +1630,17 @@ int cfg80211_iter_combinations(struct wiphy *wiphy,
all_iftypes |= limits[j].types; all_iftypes |= limits[j].types;
if (!(limits[j].types & BIT(iftype))) if (!(limits[j].types & BIT(iftype)))
continue; continue;
if (limits[j].max < iftype_num[iftype]) if (limits[j].max < params->iftype_num[iftype])
goto cont; goto cont;
limits[j].max -= iftype_num[iftype]; limits[j].max -= params->iftype_num[iftype];
} }
} }
if (radar_detect != (c->radar_detect_widths & radar_detect)) if (params->radar_detect !=
(c->radar_detect_widths & params->radar_detect))
goto cont; goto cont;
if (radar_detect && c->radar_detect_regions && if (params->radar_detect && c->radar_detect_regions &&
!(c->radar_detect_regions & BIT(region))) !(c->radar_detect_regions & BIT(region)))
goto cont; goto cont;
...@@ -1675,14 +1674,11 @@ cfg80211_iter_sum_ifcombs(const struct ieee80211_iface_combination *c, ...@@ -1675,14 +1674,11 @@ cfg80211_iter_sum_ifcombs(const struct ieee80211_iface_combination *c,
} }
int cfg80211_check_combinations(struct wiphy *wiphy, int cfg80211_check_combinations(struct wiphy *wiphy,
const int num_different_channels, struct iface_combination_params *params)
const u8 radar_detect,
const int iftype_num[NUM_NL80211_IFTYPES])
{ {
int err, num = 0; int err, num = 0;
err = cfg80211_iter_combinations(wiphy, num_different_channels, err = cfg80211_iter_combinations(wiphy, params,
radar_detect, iftype_num,
cfg80211_iter_sum_ifcombs, &num); cfg80211_iter_sum_ifcombs, &num);
if (err) if (err)
return err; return err;
......
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