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

Commit b6a55015 authored by Luciano Coelho's avatar Luciano Coelho Committed by Johannes Berg
Browse files

cfg80211/mac80211: move more combination checks to mac80211



Get rid of the cfg80211_can_add_interface() and
cfg80211_can_change_interface() functions by moving that functionality
to mac80211.  With this patch all interface combination checks are now
out of cfg80211 (except for the channel switch case which will be
addressed in a future commit).

Additionally, modify the ieee80211_check_combinations() function so
that an undefined chandef can be passed, in order to use it before a
channel is defined.

Signed-off-by: default avatarLuciano Coelho <luciano.coelho@intel.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 71965c1d
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -109,6 +109,15 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
static int ieee80211_start_p2p_device(struct wiphy *wiphy,
				      struct wireless_dev *wdev)
{
	struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
	int ret;

	mutex_lock(&sdata->local->chanctx_mtx);
	ret = ieee80211_check_combinations(sdata, NULL, 0, 0);
	mutex_unlock(&sdata->local->chanctx_mtx);
	if (ret < 0)
		return ret;

	return ieee80211_do_open(wdev, true);
}

+5 −1
Original line number Diff line number Diff line
@@ -250,6 +250,7 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata,
{
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_sub_if_data *nsdata;
	int ret;

	ASSERT_RTNL();

@@ -300,7 +301,10 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata,
		}
	}

	return 0;
	mutex_lock(&local->chanctx_mtx);
	ret = ieee80211_check_combinations(sdata, NULL, 0, 0);
	mutex_unlock(&local->chanctx_mtx);
	return ret;
}

static int ieee80211_check_queues(struct ieee80211_sub_if_data *sdata,
+7 −3
Original line number Diff line number Diff line
@@ -2808,7 +2808,7 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
	enum nl80211_iftype iftype = sdata->wdev.iftype;
	int num[NUM_NL80211_IFTYPES];
	struct ieee80211_chanctx *ctx;
	int num_different_channels = 1;
	int num_different_channels = 0;
	int total = 1;

	lockdep_assert_held(&local->chanctx_mtx);
@@ -2816,9 +2816,13 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
	if (WARN_ON(hweight32(radar_detect) > 1))
		return -EINVAL;

	if (WARN_ON(chanmode == IEEE80211_CHANCTX_SHARED && !chandef->chan))
	if (WARN_ON(chandef && chanmode == IEEE80211_CHANCTX_SHARED &&
		    !chandef->chan))
		return -EINVAL;

	if (chandef)
		num_different_channels = 1;

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

@@ -2841,7 +2845,7 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
			num_different_channels++;
			continue;
		}
		if ((chanmode == IEEE80211_CHANCTX_SHARED) &&
		if (chandef && chanmode == IEEE80211_CHANCTX_SHARED &&
		    cfg80211_chandef_compatible(chandef,
						&ctx->conf.def))
			continue;
+3 −8
Original line number Diff line number Diff line
@@ -439,10 +439,7 @@ static int wiphy_verify_combinations(struct wiphy *wiphy)
		for (j = 0; j < c->n_limits; j++) {
			u16 types = c->limits[j].types;

			/*
			 * interface types shouldn't overlap, this is
			 * used in cfg80211_can_change_interface()
			 */
			/* interface types shouldn't overlap */
			if (WARN_ON(types & all_iftypes))
				return -EINVAL;
			all_iftypes |= types;
@@ -840,7 +837,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
	struct wireless_dev *wdev = dev->ieee80211_ptr;
	struct cfg80211_registered_device *rdev;
	int ret;

	if (!wdev)
		return NOTIFY_DONE;
@@ -1003,9 +999,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
	case NETDEV_PRE_UP:
		if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype)))
			return notifier_from_errno(-EOPNOTSUPP);
		ret = cfg80211_can_add_interface(rdev, wdev->iftype);
		if (ret)
			return notifier_from_errno(ret);
		if (rfkill_blocked(rdev->rfkill))
			return notifier_from_errno(-ERFKILL);
		break;
	}

+0 −22
Original line number Diff line number Diff line
@@ -412,28 +412,6 @@ unsigned int
cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
			      const struct cfg80211_chan_def *chandef);

static inline int
cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
			      struct wireless_dev *wdev,
			      enum nl80211_iftype iftype)
{
	/* TODO: For this function, we'll probably need to keep some
	 * kind of interface combination check in cfg80211...
	 */
	return cfg80211_can_use_iftype_chan(rdev, wdev, iftype, NULL,
					    CHAN_MODE_UNDEFINED, 0);
}

static inline int
cfg80211_can_add_interface(struct cfg80211_registered_device *rdev,
			   enum nl80211_iftype iftype)
{
	if (rfkill_blocked(rdev->rfkill))
		return -ERFKILL;

	return cfg80211_can_change_interface(rdev, NULL, iftype);
}

static inline unsigned int elapsed_jiffies_msecs(unsigned long start)
{
	unsigned long end = jiffies;
Loading