Merge "cfg80211: pass struct to interface combination check/iter"
This commit is contained in:
commit
bd72fb6127
3 changed files with 70 additions and 76 deletions
|
@ -783,6 +783,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)
|
||||||
|
@ -5333,36 +5353,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
|
||||||
*
|
*
|
||||||
|
@ -5371,9 +5375,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);
|
||||||
|
|
|
@ -3198,10 +3198,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);
|
||||||
|
|
||||||
|
@ -3212,9 +3213,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;
|
||||||
|
|
||||||
|
@ -3225,24 +3223,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) {
|
||||||
|
@ -3255,16 +3255,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, ¶ms);
|
||||||
num_different_channels,
|
|
||||||
radar_detect, num);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -3280,12 +3278,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);
|
||||||
|
|
||||||
|
@ -3293,17 +3289,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, ¶ms,
|
||||||
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;
|
||||||
|
|
|
@ -1504,9 +1504,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)
|
||||||
|
@ -1517,7 +1515,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)
|
||||||
|
@ -1526,8 +1524,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);
|
||||||
}
|
}
|
||||||
|
@ -1541,7 +1539,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,
|
||||||
|
@ -1556,16 +1554,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;
|
||||||
|
|
||||||
|
@ -1599,14 +1598,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;
|
||||||
|
@ -1625,14 +1621,15 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
|
||||||
u8 radar_detect)
|
u8 radar_detect)
|
||||||
{
|
{
|
||||||
struct wireless_dev *wdev_iter;
|
struct wireless_dev *wdev_iter;
|
||||||
int num[NUM_NL80211_IFTYPES];
|
|
||||||
struct ieee80211_channel
|
struct ieee80211_channel
|
||||||
*used_channels[CFG80211_MAX_NUM_DIFFERENT_CHANNELS];
|
*used_channels[CFG80211_MAX_NUM_DIFFERENT_CHANNELS];
|
||||||
struct ieee80211_channel *ch;
|
struct ieee80211_channel *ch;
|
||||||
enum cfg80211_chan_mode chmode;
|
enum cfg80211_chan_mode chmode;
|
||||||
int num_different_channels = 0;
|
|
||||||
int total = 1;
|
int total = 1;
|
||||||
int i;
|
int i;
|
||||||
|
struct iface_combination_params params = {
|
||||||
|
.radar_detect = radar_detect,
|
||||||
|
};
|
||||||
|
|
||||||
ASSERT_RTNL();
|
ASSERT_RTNL();
|
||||||
|
|
||||||
|
@ -1649,10 +1646,9 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(num, 0, sizeof(num));
|
|
||||||
memset(used_channels, 0, sizeof(used_channels));
|
memset(used_channels, 0, sizeof(used_channels));
|
||||||
|
|
||||||
num[iftype] = 1;
|
params.iftype_num[iftype] = 1;
|
||||||
|
|
||||||
/* TODO: We'll probably not need this anymore, since this
|
/* TODO: We'll probably not need this anymore, since this
|
||||||
* should only be called with CHAN_MODE_UNDEFINED. There are
|
* should only be called with CHAN_MODE_UNDEFINED. There are
|
||||||
|
@ -1665,10 +1661,10 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
|
||||||
case CHAN_MODE_SHARED:
|
case CHAN_MODE_SHARED:
|
||||||
WARN_ON(!chan);
|
WARN_ON(!chan);
|
||||||
used_channels[0] = chan;
|
used_channels[0] = chan;
|
||||||
num_different_channels++;
|
params.num_different_channels++;
|
||||||
break;
|
break;
|
||||||
case CHAN_MODE_EXCLUSIVE:
|
case CHAN_MODE_EXCLUSIVE:
|
||||||
num_different_channels++;
|
params.num_different_channels++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1696,7 +1692,8 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
|
||||||
*/
|
*/
|
||||||
mutex_lock_nested(&wdev_iter->mtx, 1);
|
mutex_lock_nested(&wdev_iter->mtx, 1);
|
||||||
__acquire(wdev_iter->mtx);
|
__acquire(wdev_iter->mtx);
|
||||||
cfg80211_get_chan_state(wdev_iter, &ch, &chmode, &radar_detect);
|
cfg80211_get_chan_state(wdev_iter, &ch, &chmode,
|
||||||
|
¶ms.radar_detect);
|
||||||
wdev_unlock(wdev_iter);
|
wdev_unlock(wdev_iter);
|
||||||
|
|
||||||
switch (chmode) {
|
switch (chmode) {
|
||||||
|
@ -1712,23 +1709,22 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
|
||||||
|
|
||||||
if (used_channels[i] == NULL) {
|
if (used_channels[i] == NULL) {
|
||||||
used_channels[i] = ch;
|
used_channels[i] = ch;
|
||||||
num_different_channels++;
|
params.num_different_channels++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CHAN_MODE_EXCLUSIVE:
|
case CHAN_MODE_EXCLUSIVE:
|
||||||
num_different_channels++;
|
params.num_different_channels++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
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(&rdev->wiphy, num_different_channels,
|
return cfg80211_check_combinations(&rdev->wiphy, ¶ms);
|
||||||
radar_detect, num);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
|
int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
|
||||||
|
|
Loading…
Add table
Reference in a new issue