Commit b61e6b41 authored by Ilan Peer's avatar Ilan Peer Committed by Johannes Berg
Browse files

wifi: cfg80211: Add support for setting TID to link mapping



Add support for setting the TID to link mapping for a non-AP MLD
station.

This is useful in cases user space needs to restrict the possible
set of active links, e.g., since it got a BSS Transition Management
request forcing to use only a subset of the valid links etc.

Signed-off-by: default avatarIlan Peer <ilan.peer@intel.com>
Reviewed-by: default avatarGregory Greenman <gregory.greenman@intel.com>
Signed-off-by: default avatarMiri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://msgid.link/20231211085121.da4d56a5f3ff.Iacf88e943326bf9c169c49b728c4a3445fdedc97@changeid


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 9adc8b65
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -1673,6 +1673,21 @@ struct link_station_del_parameters {
	u32 link_id;
};

/**
 * struct cfg80211_ttlm_params: TID to link mapping parameters
 *
 * Used for setting a TID to link mapping.
 *
 * @dlink: Downlink TID to link mapping, as defined in section 9.4.2.314
 *     (TID-To-Link Mapping element) in Draft P802.11be_D4.0.
 * @ulink: Uplink TID to link mapping, as defined in section 9.4.2.314
 *     (TID-To-Link Mapping element) in Draft P802.11be_D4.0.
 */
struct cfg80211_ttlm_params {
	u16 dlink[8];
	u16 ulink[8];
};

/**
 * struct station_parameters - station parameters
 *
@@ -4523,6 +4538,7 @@ struct mgmt_frame_regs {
 * @del_link_station: Remove a link of a station.
 *
 * @set_hw_timestamp: Enable/disable HW timestamping of TM/FTM frames.
 * @set_ttlm: set the TID to link mapping.
 */
struct cfg80211_ops {
	int	(*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -4882,6 +4898,8 @@ struct cfg80211_ops {
				    struct link_station_del_parameters *params);
	int	(*set_hw_timestamp)(struct wiphy *wiphy, struct net_device *dev,
				    struct cfg80211_set_hw_timestamp *hwts);
	int	(*set_ttlm)(struct wiphy *wiphy, struct net_device *dev,
			    struct cfg80211_ttlm_params *params);
};

/*
+19 −0
Original line number Diff line number Diff line
@@ -1328,6 +1328,11 @@
 *	Multi-Link reconfiguration. %NL80211_ATTR_MLO_LINKS is used to provide
 *	information about the removed STA MLD setup links.
 *
 * @NL80211_CMD_SET_TID_TO_LINK_MAPPING: Set the TID to Link Mapping for a
 *      non-AP MLD station. The %NL80211_ATTR_MLO_TTLM_DLINK and
 *      %NL80211_ATTR_MLO_TTLM_ULINK attributes are used to specify the
 *      TID to Link mapping for downlink/uplink traffic.
 *
 * @NL80211_CMD_MAX: highest used command number
 * @__NL80211_CMD_AFTER_LAST: internal use
 */
@@ -1583,6 +1588,8 @@ enum nl80211_commands {

	NL80211_CMD_LINKS_REMOVED,

	NL80211_CMD_SET_TID_TO_LINK_MAPPING,

	/* add new commands above here */

	/* used to define NL80211_CMD_MAX below */
@@ -2835,6 +2842,15 @@ enum nl80211_commands {
 *	include BSSes that can only be used in restricted scenarios and/or
 *	cannot be used at all.
 *
 * @NL80211_ATTR_MLO_TTLM_DLINK: Binary attribute specifying the downlink TID to
 *      link mapping. The length is 8 * sizeof(u16). For each TID the link
 *      mapping is as defined in section 9.4.2.314 (TID-To-Link Mapping element)
 *      in Draft P802.11be_D4.0.
 * @NL80211_ATTR_MLO_TTLM_ULINK: Binary attribute specifying the uplink TID to
 *      link mapping. The length is 8 * sizeof(u16). For each TID the link
 *      mapping is as defined in section 9.4.2.314 (TID-To-Link Mapping element)
 *      in Draft P802.11be_D4.0.
 *
 * @NUM_NL80211_ATTR: total number of nl80211_attrs available
 * @NL80211_ATTR_MAX: highest attribute number currently defined
 * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3375,6 +3391,9 @@ enum nl80211_attrs {

	NL80211_ATTR_BSS_DUMP_INCLUDE_USE_DATA,

	NL80211_ATTR_MLO_TTLM_DLINK,
	NL80211_ATTR_MLO_TTLM_ULINK,

	/* add attributes here, update the policy in nl80211.c */

	__NL80211_ATTR_AFTER_LAST,
+37 −0
Original line number Diff line number Diff line
@@ -819,6 +819,8 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
	[NL80211_ATTR_EMA_RNR_ELEMS] = { .type = NLA_NESTED },
	[NL80211_ATTR_MLO_LINK_DISABLED] = { .type = NLA_FLAG },
	[NL80211_ATTR_BSS_DUMP_INCLUDE_USE_DATA] = { .type = NLA_FLAG },
	[NL80211_ATTR_MLO_TTLM_DLINK] = NLA_POLICY_EXACT_LEN(sizeof(u16) * 8),
	[NL80211_ATTR_MLO_TTLM_ULINK] = NLA_POLICY_EXACT_LEN(sizeof(u16) * 8),
};
/* policy for the key attributes */
@@ -16298,6 +16300,35 @@ static int nl80211_set_hw_timestamp(struct sk_buff *skb,
	return rdev_set_hw_timestamp(rdev, dev, &hwts);
}
static int
nl80211_set_ttlm(struct sk_buff *skb, struct genl_info *info)
{
	struct cfg80211_ttlm_params params = {};
	struct cfg80211_registered_device *rdev = info->user_ptr[0];
	struct net_device *dev = info->user_ptr[1];
	struct wireless_dev *wdev = dev->ieee80211_ptr;
	if (wdev->iftype != NL80211_IFTYPE_STATION &&
	    wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
		return -EOPNOTSUPP;
	if (!wdev->connected)
		return -ENOLINK;
	if (!info->attrs[NL80211_ATTR_MLO_TTLM_DLINK] ||
	    !info->attrs[NL80211_ATTR_MLO_TTLM_ULINK])
		return -EINVAL;
	nla_memcpy(params.dlink,
		   info->attrs[NL80211_ATTR_MLO_TTLM_DLINK],
		   sizeof(params.dlink));
	nla_memcpy(params.ulink,
		   info->attrs[NL80211_ATTR_MLO_TTLM_ULINK],
		   sizeof(params.ulink));
	return rdev_set_ttlm(rdev, dev, &params);
}
#define NL80211_FLAG_NEED_WIPHY		0x01
#define NL80211_FLAG_NEED_NETDEV	0x02
#define NL80211_FLAG_NEED_RTNL		0x04
@@ -17479,6 +17510,12 @@ static const struct genl_small_ops nl80211_small_ops[] = {
		.flags = GENL_UNS_ADMIN_PERM,
		.internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
	},
	{
		.cmd = NL80211_CMD_SET_TID_TO_LINK_MAPPING,
		.doit = nl80211_set_ttlm,
		.flags = GENL_UNS_ADMIN_PERM,
		.internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
	},
};
static struct genl_family nl80211_fam __ro_after_init = {
+18 −0
Original line number Diff line number Diff line
@@ -1524,4 +1524,22 @@ rdev_set_hw_timestamp(struct cfg80211_registered_device *rdev,

	return ret;
}

static inline int
rdev_set_ttlm(struct cfg80211_registered_device *rdev,
	      struct net_device *dev,
	      struct cfg80211_ttlm_params *params)
{
	struct wiphy *wiphy = &rdev->wiphy;
	int ret;

	if (!rdev->ops->set_ttlm)
		return -EOPNOTSUPP;

	trace_rdev_set_ttlm(wiphy, dev, params);
	ret = rdev->ops->set_ttlm(wiphy, dev, params);
	trace_rdev_return_int(wiphy, ret);

	return ret;
}
#endif /* __CFG80211_RDEV_OPS */
+20 −0
Original line number Diff line number Diff line
@@ -3979,6 +3979,26 @@ TRACE_EVENT(cfg80211_links_removed,
		  __entry->link_mask)
);

TRACE_EVENT(rdev_set_ttlm,
	TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
		 struct cfg80211_ttlm_params *params),
	TP_ARGS(wiphy, netdev, params),
	TP_STRUCT__entry(
		WIPHY_ENTRY
		NETDEV_ENTRY
		__array(u8, dlink, sizeof(u16) * 8)
		__array(u8, ulink, sizeof(u16) * 8)
	),
	TP_fast_assign(
		WIPHY_ASSIGN;
		NETDEV_ASSIGN;
		memcpy(__entry->dlink, params->dlink, sizeof(params->dlink));
		memcpy(__entry->ulink, params->ulink, sizeof(params->ulink));
	),
	TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT,
		  WIPHY_PR_ARG, NETDEV_PR_ARG)
);

#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */

#undef TRACE_INCLUDE_PATH