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

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

Merge "cfg80211: pass struct to interface combination check/iter"

parents 035c4cda db9dd48f
Loading
Loading
Loading
Loading
+25 −23
Original line number Diff line number Diff line
@@ -778,6 +778,26 @@ 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.
 */
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
 * @STATION_PARAM_APPLY_UAPSD: apply new uAPSD parameters (uapsd_queues, max_sp)
@@ -5006,36 +5026,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
 *
@@ -5044,9 +5048,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);
+20 −24
Original line number Diff line number Diff line
@@ -2997,10 +2997,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);

@@ -3011,9 +3012,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;

@@ -3024,24 +3022,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) {
@@ -3054,16 +3054,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
@@ -3079,12 +3077,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);

@@ -3092,17 +3088,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;
+25 −29
Original line number Diff line number Diff line
@@ -1272,9 +1272,7 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
}

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)
@@ -1285,7 +1283,7 @@ int cfg80211_iter_combinations(struct wiphy *wiphy,
	int num_interfaces = 0;
	u32 used_iftypes = 0;

	if (radar_detect) {
	if (params->radar_detect) {
		rcu_read_lock();
		regdom = rcu_dereference(cfg80211_regdomain);
		if (regdom)
@@ -1294,8 +1292,8 @@ int cfg80211_iter_combinations(struct wiphy *wiphy,
	}

	for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) {
		num_interfaces += iftype_num[iftype];
		if (iftype_num[iftype] > 0 &&
		num_interfaces += params->iftype_num[iftype];
		if (params->iftype_num[iftype] > 0 &&
		    !(wiphy->software_iftypes & BIT(iftype)))
			used_iftypes |= BIT(iftype);
	}
@@ -1309,7 +1307,7 @@ int cfg80211_iter_combinations(struct wiphy *wiphy,

		if (num_interfaces > c->max_interfaces)
			continue;
		if (num_different_channels > c->num_different_channels)
		if (params->num_different_channels > c->num_different_channels)
			continue;

		limits = kmemdup(c->limits, sizeof(limits[0]) * c->n_limits,
@@ -1324,16 +1322,17 @@ int cfg80211_iter_combinations(struct wiphy *wiphy,
				all_iftypes |= limits[j].types;
				if (!(limits[j].types & BIT(iftype)))
					continue;
				if (limits[j].max < iftype_num[iftype])
				if (limits[j].max < params->iftype_num[iftype])
					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;

		if (radar_detect && c->radar_detect_regions &&
		if (params->radar_detect && c->radar_detect_regions &&
		    !(c->radar_detect_regions & BIT(region)))
			goto cont;

@@ -1367,14 +1366,11 @@ cfg80211_iter_sum_ifcombs(const struct ieee80211_iface_combination *c,
}

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)
{
	int err, num = 0;

	err = cfg80211_iter_combinations(wiphy, num_different_channels,
					 radar_detect, iftype_num,
	err = cfg80211_iter_combinations(wiphy, params,
					 cfg80211_iter_sum_ifcombs, &num);
	if (err)
		return err;
@@ -1393,14 +1389,15 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
				 u8 radar_detect)
{
	struct wireless_dev *wdev_iter;
	int num[NUM_NL80211_IFTYPES];
	struct ieee80211_channel
			*used_channels[CFG80211_MAX_NUM_DIFFERENT_CHANNELS];
	struct ieee80211_channel *ch;
	enum cfg80211_chan_mode chmode;
	int num_different_channels = 0;
	int total = 1;
	int i;
	struct iface_combination_params params = {
		.radar_detect = radar_detect,
	};

	ASSERT_RTNL();

@@ -1417,10 +1414,9 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
		return 0;
	}

	memset(num, 0, sizeof(num));
	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
	 * should only be called with CHAN_MODE_UNDEFINED. There are
@@ -1433,10 +1429,10 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
	case CHAN_MODE_SHARED:
		WARN_ON(!chan);
		used_channels[0] = chan;
		num_different_channels++;
		params.num_different_channels++;
		break;
	case CHAN_MODE_EXCLUSIVE:
		num_different_channels++;
		params.num_different_channels++;
		break;
	}

@@ -1464,7 +1460,8 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
		 */
		mutex_lock_nested(&wdev_iter->mtx, 1);
		__acquire(wdev_iter->mtx);
		cfg80211_get_chan_state(wdev_iter, &ch, &chmode, &radar_detect);
		cfg80211_get_chan_state(wdev_iter, &ch, &chmode,
					&params.radar_detect);
		wdev_unlock(wdev_iter);

		switch (chmode) {
@@ -1480,23 +1477,22 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,

			if (used_channels[i] == NULL) {
				used_channels[i] = ch;
				num_different_channels++;
				params.num_different_channels++;
			}
			break;
		case CHAN_MODE_EXCLUSIVE:
			num_different_channels++;
			params.num_different_channels++;
			break;
		}

		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(&rdev->wiphy, num_different_channels,
					   radar_detect, num);
	return cfg80211_check_combinations(&rdev->wiphy, &params);
}

int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,