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

Commit a5a9dcf2 authored by Ayala Beker's avatar Ayala Beker Committed by Johannes Berg
Browse files

cfg80211: allow the user space to change current NAN configuration



Some NAN configuration paramaters may change during the operation of
the NAN device. For example, a user may want to update master preference
value when the device gets plugged/unplugged to the power.
Add API that allows to do so.

Signed-off-by: default avatarAndrei Otcheretianski <andrei.otcheretianski@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent a442b761
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -2326,6 +2326,18 @@ struct cfg80211_nan_conf {
	u8 dual;
};

/**
 * enum cfg80211_nan_conf_changes - indicates changed fields in NAN
 * configuration
 *
 * @CFG80211_NAN_CONF_CHANGED_PREF: master preference
 * @CFG80211_NAN_CONF_CHANGED_DUAL: dual band operation
 */
enum cfg80211_nan_conf_changes {
	CFG80211_NAN_CONF_CHANGED_PREF = BIT(0),
	CFG80211_NAN_CONF_CHANGED_DUAL = BIT(1),
};

/**
 * struct cfg80211_nan_func_filter - a NAN function Rx / Tx filter
 *
@@ -2691,6 +2703,9 @@ struct cfg80211_nan_func {
 *	On success the driver should assign an instance_id in the
 *	provided @nan_func.
 * @del_nan_func: Delete a NAN function.
 * @nan_change_conf: changes NAN configuration. The changed parameters must
 *	be specified in @changes (using &enum cfg80211_nan_conf_changes);
 *	All other parameters must be ignored.
 */
struct cfg80211_ops {
	int	(*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -2963,6 +2978,10 @@ struct cfg80211_ops {
				struct cfg80211_nan_func *nan_func);
	void	(*del_nan_func)(struct wiphy *wiphy, struct wireless_dev *wdev,
			       u64 cookie);
	int	(*nan_change_conf)(struct wiphy *wiphy,
				   struct wireless_dev *wdev,
				   struct cfg80211_nan_conf *conf,
				   u32 changes);
};

/*
+9 −2
Original line number Diff line number Diff line
@@ -862,6 +862,10 @@
 *	the response to this command.
 *	Look at %NL80211_ATTR_SOCKET_OWNER as well.
 * @NL80211_CMD_DEL_NAN_FUNCTION: Delete a NAN function by cookie.
 * @NL80211_CMD_CHANGE_NAN_CONFIG: Change current NAN configuration. NAN
 *	must be operational (%NL80211_CMD_START_NAN was executed).
 *	It must contain at least one of the following attributes:
 *	%NL80211_ATTR_NAN_MASTER_PREF, %NL80211_ATTR_NAN_DUAL.
 *
 * @NL80211_CMD_MAX: highest used command number
 * @__NL80211_CMD_AFTER_LAST: internal use
@@ -1055,6 +1059,7 @@ enum nl80211_commands {
	NL80211_CMD_STOP_NAN,
	NL80211_CMD_ADD_NAN_FUNCTION,
	NL80211_CMD_DEL_NAN_FUNCTION,
	NL80211_CMD_CHANGE_NAN_CONFIG,

	/* add new commands above here */

@@ -1910,12 +1915,14 @@ enum nl80211_commands {
 *	used to pull the stored data for mesh peer in power save state.
 *
 * @NL80211_ATTR_NAN_MASTER_PREF: the master preference to be used by
 *	%NL80211_CMD_START_NAN. Its type is u8 and it can't be 0.
 *	%NL80211_CMD_START_NAN and optionally with
 *	%NL80211_CMD_CHANGE_NAN_CONFIG. Its type is u8 and it can't be 0.
 *	Also, values 1 and 255 are reserved for certification purposes and
 *	should not be used during a normal device operation.
 * @NL80211_ATTR_NAN_DUAL: NAN dual band operation config (see
 *	&enum nl80211_nan_dual_band_conf). This attribute is used with
 *	%NL80211_CMD_START_NAN.
 *	%NL80211_CMD_START_NAN and optionally with
 *	%NL80211_CMD_CHANGE_NAN_CONFIG.
 * @NL80211_ATTR_NAN_FUNC: a function that can be added to NAN. See
 *	&enum nl80211_nan_func_attributes for description of this nested
 *	attribute.
+42 −0
Original line number Diff line number Diff line
@@ -10919,6 +10919,40 @@ static int nl80211_nan_del_func(struct sk_buff *skb,
	return 0;
}

static int nl80211_nan_change_config(struct sk_buff *skb,
				     struct genl_info *info)
{
	struct cfg80211_registered_device *rdev = info->user_ptr[0];
	struct wireless_dev *wdev = info->user_ptr[1];
	struct cfg80211_nan_conf conf = {};
	u32 changed = 0;

	if (wdev->iftype != NL80211_IFTYPE_NAN)
		return -EOPNOTSUPP;

	if (!wdev->nan_started)
		return -ENOTCONN;

	if (info->attrs[NL80211_ATTR_NAN_MASTER_PREF]) {
		conf.master_pref =
			nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
		if (conf.master_pref <= 1 || conf.master_pref == 255)
			return -EINVAL;

		changed |= CFG80211_NAN_CONF_CHANGED_PREF;
	}

	if (info->attrs[NL80211_ATTR_NAN_DUAL]) {
		conf.dual = nla_get_u8(info->attrs[NL80211_ATTR_NAN_DUAL]);
		changed |= CFG80211_NAN_CONF_CHANGED_DUAL;
	}

	if (!changed)
		return -EINVAL;

	return rdev_nan_change_conf(rdev, wdev, &conf, changed);
}

static int nl80211_get_protocol_features(struct sk_buff *skb,
					 struct genl_info *info)
{
@@ -12292,6 +12326,14 @@ static const struct genl_ops nl80211_ops[] = {
		.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
				  NL80211_FLAG_NEED_RTNL,
	},
	{
		.cmd = NL80211_CMD_CHANGE_NAN_CONFIG,
		.doit = nl80211_nan_change_config,
		.policy = nl80211_policy,
		.flags = GENL_ADMIN_PERM,
		.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
				  NL80211_FLAG_NEED_RTNL,
	},
	{
		.cmd = NL80211_CMD_SET_MCAST_RATE,
		.doit = nl80211_set_mcast_rate,
+17 −0
Original line number Diff line number Diff line
@@ -928,6 +928,23 @@ static inline void rdev_del_nan_func(struct cfg80211_registered_device *rdev,
	trace_rdev_return_void(&rdev->wiphy);
}

static inline int
rdev_nan_change_conf(struct cfg80211_registered_device *rdev,
		     struct wireless_dev *wdev,
		     struct cfg80211_nan_conf *conf, u32 changes)
{
	int ret;

	trace_rdev_nan_change_conf(&rdev->wiphy, wdev, conf, changes);
	if (rdev->ops->nan_change_conf)
		ret = rdev->ops->nan_change_conf(&rdev->wiphy, wdev, conf,
						 changes);
	else
		ret = -ENOTSUPP;
	trace_rdev_return_int(&rdev->wiphy, ret);
	return ret;
}

static inline int rdev_set_mac_acl(struct cfg80211_registered_device *rdev,
				   struct net_device *dev,
				   struct cfg80211_acl_data *params)
+24 −0
Original line number Diff line number Diff line
@@ -1911,6 +1911,30 @@ TRACE_EVENT(rdev_start_nan,
		  __entry->dual)
);

TRACE_EVENT(rdev_nan_change_conf,
	TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
		 struct cfg80211_nan_conf *conf, u32 changes),
	TP_ARGS(wiphy, wdev, conf, changes),
	TP_STRUCT__entry(
		WIPHY_ENTRY
		WDEV_ENTRY
		__field(u8, master_pref)
		__field(u8, dual);
		__field(u32, changes);
	),
	TP_fast_assign(
		WIPHY_ASSIGN;
		WDEV_ASSIGN;
		__entry->master_pref = conf->master_pref;
		__entry->dual = conf->dual;
		__entry->changes = changes;
	),
	TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT
		  ", master preference: %u, dual: %d, changes: %x",
		  WIPHY_PR_ARG, WDEV_PR_ARG, __entry->master_pref,
		  __entry->dual, __entry->changes)
);

DEFINE_EVENT(wiphy_wdev_evt, rdev_stop_nan,
	TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev),
	TP_ARGS(wiphy, wdev)