Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2577b830 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "cfg80211: support virtual interfaces with different beacon intervals"

parents d6a02ba9 c6800ff6
Loading
Loading
Loading
Loading
+12 −10
Original line number Diff line number Diff line
@@ -414,23 +414,24 @@ static int brcmf_vif_change_validate(struct brcmf_cfg80211_info *cfg,
				     struct brcmf_cfg80211_vif *vif,
				     enum nl80211_iftype new_type)
{
	int iftype_num[NUM_NL80211_IFTYPES];
	struct brcmf_cfg80211_vif *pos;
	bool check_combos = false;
	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)
		if (pos == vif) {
			iftype_num[new_type]++;
			params.iftype_num[new_type]++;
		} else {
			/* concurrent interfaces so need check combinations */
			check_combos = true;
			iftype_num[pos->wdev.iftype]++;
			params.iftype_num[pos->wdev.iftype]++;
		}

	if (check_combos)
		ret = cfg80211_check_combinations(cfg->wiphy, 1, 0, iftype_num);
		ret = cfg80211_check_combinations(cfg->wiphy, &params);

	return ret;
}
@@ -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,
				  enum nl80211_iftype new_type)
{
	int iftype_num[NUM_NL80211_IFTYPES];
	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)
		iftype_num[pos->wdev.iftype]++;
		params.iftype_num[pos->wdev.iftype]++;

	iftype_num[new_type]++;
	return cfg80211_check_combinations(cfg->wiphy, 1, 0, iftype_num);
	params.iftype_num[new_type]++;
	return cfg80211_check_combinations(cfg->wiphy, &params);
}

static void convert_key_from_CPU(struct brcmf_wsec_key *key,
+39 −22
Original line number Diff line number Diff line
@@ -771,6 +771,34 @@ struct cfg80211_csa_settings {
	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.
 * @beacon_int_gcd: a value specifying GCD of all beaconing interfaces,
 *	the GCD of a single value is considered the value itself, so for
 *	a single interface this should be set to that interface's beacon
 *	interval
 * @beacon_int_different: a flag indicating whether or not all beacon
 *	intervals (of beaconing interfaces) are different or not.
 */
struct iface_combination_params {
	int num_different_channels;
	u8 radar_detect;
	int iftype_num[NUM_NL80211_IFTYPES];
	u32 beacon_int_gcd;
	bool beacon_int_different;
};

/**
 * enum station_parameters_apply_mask - station parameter values to apply
 * @STATION_PARAM_APPLY_UAPSD: apply new uAPSD parameters (uapsd_queues, max_sp)
@@ -3082,6 +3110,12 @@ struct ieee80211_iface_limit {
 *	only in special cases.
 * @radar_detect_widths: bitmap of channel widths supported for radar detection
 * @radar_detect_regions: bitmap of regions supported for radar detection
 * @beacon_int_min_gcd: This interface combination supports different
 *	beacon intervals.
 *	= 0 - all beacon intervals for different interface must be same.
 *	> 0 - any beacon interval for the interface part of this combination AND
 *	      *GCD* of all beacon intervals from beaconing interfaces of this
 *	      combination must be greater or equal to this value.
 *
 * With this structure the driver can describe which interface
 * combinations it supports concurrently.
@@ -3147,6 +3181,7 @@ struct ieee80211_iface_combination {
	bool beacon_int_infra_match;
	u8 radar_detect_widths;
	u8 radar_detect_regions;
	u32 beacon_int_min_gcd;
};

struct ieee80211_txrx_stypes {
@@ -5644,36 +5679,20 @@ unsigned int ieee80211_get_num_supported_channels(struct wiphy *wiphy);
 * cfg80211_check_combinations - check interface combinations
 *
 * @wiphy: the wiphy
 * @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 numbers of interfaces of each interface
 *	type.  The index is the interface type as specified in &enum
 *	nl80211_iftype.
 * @params: the interface combinations parameter
 *
 * This function can be called by the driver to check whether a
 * combination of interfaces and their types are allowed according to
 * the interface combinations.
 */
int cfg80211_check_combinations(struct wiphy *wiphy,
				const int num_different_channels,
				const u8 radar_detect,
				const int iftype_num[NUM_NL80211_IFTYPES]);
				struct iface_combination_params *params);

/**
 * cfg80211_iter_combinations - iterate over matching combinations
 *
 * @wiphy: the wiphy
 * @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 numbers of interfaces of each interface
 *	type.  The index is the interface type as specified in &enum
 *	nl80211_iftype.
 * @params: the interface combinations parameter
 * @iter: function to call for each matching combination
 * @data: pointer to pass to iter function
 *
@@ -5682,9 +5701,7 @@ int cfg80211_check_combinations(struct wiphy *wiphy,
 * purposes.
 */
int cfg80211_iter_combinations(struct wiphy *wiphy,
			       const int num_different_channels,
			       const u8 radar_detect,
			       const int iftype_num[NUM_NL80211_IFTYPES],
			       struct iface_combination_params *params,
			       void (*iter)(const struct ieee80211_iface_combination *c,
					    void *data),
			       void *data);
+6 −2
Original line number Diff line number Diff line
@@ -4285,6 +4285,9 @@ enum nl80211_iface_limit_attrs {
 *	of supported channel widths for radar detection.
 * @NL80211_IFACE_COMB_RADAR_DETECT_REGIONS: u32 attribute containing the bitmap
 *	of supported regulatory regions for radar detection.
 * @NL80211_IFACE_COMB_BI_MIN_GCD: u32 attribute specifying the minimum GCD of
 *	different beacon intervals supported by all the interface combinations
 *	in this group (if not present, all beacon intervals be identical).
 * @NUM_NL80211_IFACE_COMB: number of attributes
 * @MAX_NL80211_IFACE_COMB: highest attribute number
 *
@@ -4292,8 +4295,8 @@ enum nl80211_iface_limit_attrs {
 *	limits = [ #{STA} <= 1, #{AP} <= 1 ], matching BI, channels = 1, max = 2
 *	=> allows an AP and a STA that must match BIs
 *
 *	numbers = [ #{AP, P2P-GO} <= 8 ], channels = 1, max = 8
 *	=> allows 8 of AP/GO
 *	numbers = [ #{AP, P2P-GO} <= 8 ], BI min gcd, channels = 1, max = 8,
 *	=> allows 8 of AP/GO that can have BI gcd >= min gcd
 *
 *	numbers = [ #{STA} <= 2 ], channels = 2, max = 2
 *	=> allows two STAs on different channels
@@ -4319,6 +4322,7 @@ enum nl80211_if_combination_attrs {
	NL80211_IFACE_COMB_NUM_CHANNELS,
	NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
	NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
	NL80211_IFACE_COMB_BI_MIN_GCD,

	/* keep last */
	NUM_NL80211_IFACE_COMB,
+20 −24
Original line number Diff line number Diff line
@@ -3308,10 +3308,11 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_sub_if_data *sdata_iter;
	enum nl80211_iftype iftype = sdata->wdev.iftype;
	int num[NUM_NL80211_IFTYPES];
	struct ieee80211_chanctx *ctx;
	int num_different_channels = 0;
	int total = 1;
	struct iface_combination_params params = {
		.radar_detect = radar_detect,
	};

	lockdep_assert_held(&local->chanctx_mtx);

@@ -3322,9 +3323,6 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
		    !chandef->chan))
		return -EINVAL;

	if (chandef)
		num_different_channels = 1;

	if (WARN_ON(iftype >= NUM_NL80211_IFTYPES))
		return -EINVAL;

@@ -3335,24 +3333,26 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
		return 0;
	}

	memset(num, 0, sizeof(num));
	if (chandef)
		params.num_different_channels = 1;

	if (iftype != NL80211_IFTYPE_UNSPECIFIED)
		num[iftype] = 1;
		params.iftype_num[iftype] = 1;

	list_for_each_entry(ctx, &local->chanctx_list, list) {
		if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED)
			continue;
		radar_detect |= ieee80211_chanctx_radar_detect(local, ctx);
		params.radar_detect |=
			ieee80211_chanctx_radar_detect(local, ctx);
		if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) {
			num_different_channels++;
			params.num_different_channels++;
			continue;
		}
		if (chandef && chanmode == IEEE80211_CHANCTX_SHARED &&
		    cfg80211_chandef_compatible(chandef,
						&ctx->conf.def))
			continue;
		num_different_channels++;
		params.num_different_channels++;
	}

	list_for_each_entry_rcu(sdata_iter, &local->interfaces, list) {
@@ -3365,16 +3365,14 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
		    local->hw.wiphy->software_iftypes & BIT(wdev_iter->iftype))
			continue;

		num[wdev_iter->iftype]++;
		params.iftype_num[wdev_iter->iftype]++;
		total++;
	}

	if (total == 1 && !radar_detect)
	if (total == 1 && !params.radar_detect)
		return 0;

	return cfg80211_check_combinations(local->hw.wiphy,
					   num_different_channels,
					   radar_detect, num);
	return cfg80211_check_combinations(local->hw.wiphy, &params);
}

static void
@@ -3390,12 +3388,10 @@ ieee80211_iter_max_chans(const struct ieee80211_iface_combination *c,
int ieee80211_max_num_channels(struct ieee80211_local *local)
{
	struct ieee80211_sub_if_data *sdata;
	int num[NUM_NL80211_IFTYPES] = {};
	struct ieee80211_chanctx *ctx;
	int num_different_channels = 0;
	u8 radar_detect = 0;
	u32 max_num_different_channels = 1;
	int err;
	struct iface_combination_params params = {0};

	lockdep_assert_held(&local->chanctx_mtx);

@@ -3403,17 +3399,17 @@ int ieee80211_max_num_channels(struct ieee80211_local *local)
		if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED)
			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)
		num[sdata->wdev.iftype]++;
		params.iftype_num[sdata->wdev.iftype]++;

	err = cfg80211_iter_combinations(local->hw.wiphy,
					 num_different_channels, radar_detect,
					 num, ieee80211_iter_max_chans,
	err = cfg80211_iter_combinations(local->hw.wiphy, &params,
					 ieee80211_iter_max_chans,
					 &max_num_different_channels);
	if (err < 0)
		return err;
+1 −1
Original line number Diff line number Diff line
@@ -477,7 +477,7 @@ int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
			   u32 *mask);

int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
				 u32 beacon_int);
				 enum nl80211_iftype iftype, u32 beacon_int);

void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev,
			       enum nl80211_iftype iftype, int num);
Loading