[PATCH v1 4/5] can: add netlink interface for CAN-FD Transmitter Delay Compensation (TDC)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add the netlink interface for TDC parameters of struct can_tdc and
can_tdc_const.

Contrary to the can_bittiming(_const) structures for which there is
just a single IFLA_CAN(_DATA)_BITTMING(_CONST) entry per structure,
here, an IFLA_CAN_TDC* entry is added for each of the TDC parameters
of the newly introduced struct can_tdc and struct can_tdc_const.

For struct can_tdc, these are:
	IFLA_CAN_TDCV
	IFLA_CAN_TDCO
	IFLA_CAN_TDCF

For struct can_tdc_const, these are:
	IFLA_CAN_TDCV_MAX_CONST
	IFLA_CAN_TDCO_MAX_CONST
	IFLA_CAN_TDCF_MAX_CONST

This is done so that changes can be applied in the future to the
structures without breaking the netlink interface.

All the new parameters are defined as u32. This arbitrary choice is
done to mimic the other bittiming values with are also all of type
u32. An u16 would have been sufficient to hold the TDC values.

Signed-off-by: Vincent Mailhol <mailhol.vincent@xxxxxxxxxx>
---
 drivers/net/can/dev/netlink.c    | 75 +++++++++++++++++++++++++++++++-
 include/uapi/linux/can/netlink.h |  6 +++
 2 files changed, 79 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/dev/netlink.c b/drivers/net/can/dev/netlink.c
index 75851fab7ff5..f63e105d3df8 100644
--- a/drivers/net/can/dev/netlink.c
+++ b/drivers/net/can/dev/netlink.c
@@ -19,7 +19,12 @@ static const struct nla_policy can_policy[IFLA_CAN_MAX + 1] = {
 	[IFLA_CAN_DATA_BITTIMING]	= { .len = sizeof(struct can_bittiming) },
 	[IFLA_CAN_DATA_BITTIMING_CONST]	= { .len = sizeof(struct can_bittiming_const) },
 	[IFLA_CAN_TERMINATION]		= { .type = NLA_U16 },
-	[IFLA_CAN_TERMINATION]		= { .type = NLA_U16 },
+	[IFLA_CAN_TDCV]			= { .type = NLA_U32 },
+	[IFLA_CAN_TDCV_MAX_CONST]	= { .type = NLA_U32 },
+	[IFLA_CAN_TDCO]			= { .type = NLA_U32 },
+	[IFLA_CAN_TDCO_MAX_CONST]	= { .type = NLA_U32 },
+	[IFLA_CAN_TDCF]			= { .type = NLA_U32 },
+	[IFLA_CAN_TDCF_MAX_CONST]	= { .type = NLA_U32 },
 };
 
 static int can_validate(struct nlattr *tb[], struct nlattr *data[],
@@ -219,6 +224,51 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[],
 		priv->termination = termval;
 	}
 
+	if (data[IFLA_CAN_TDCV]) {
+		u32 tdcv = nla_get_u32(data[IFLA_CAN_TDCV]);
+
+		if (!priv->tdc_const || !priv->tdc_const->tdcv_max)
+			return -EOPNOTSUPP;
+
+		if (tdcv > priv->tdc_const->tdcv_max)
+			return -EINVAL;
+
+		if (dev->flags & IFF_UP)
+			return -EBUSY;
+
+		priv->tdc.tdcv = tdcv;
+	}
+
+	if (data[IFLA_CAN_TDCO]) {
+		u32 tdco = nla_get_u32(data[IFLA_CAN_TDCO]);
+
+		if (!priv->tdc_const || !priv->tdc_const->tdco_max)
+			return -EOPNOTSUPP;
+
+		if (tdco > priv->tdc_const->tdco_max)
+			return -EINVAL;
+
+		if (dev->flags & IFF_UP)
+			return -EBUSY;
+
+		priv->tdc.tdco = tdco;
+	}
+
+	if (data[IFLA_CAN_TDCF]) {
+		u32 tdcf = nla_get_u32(data[IFLA_CAN_TDCF]);
+
+		if (!priv->tdc_const || !priv->tdc_const->tdcf_max)
+			return -EOPNOTSUPP;
+
+		if (tdcf > priv->tdc_const->tdcf_max)
+			return -EINVAL;
+
+		if (dev->flags & IFF_UP)
+			return -EBUSY;
+
+		priv->tdc.tdcf = tdcf;
+	}
+
 	return 0;
 }
 
@@ -253,6 +303,16 @@ static size_t can_get_size(const struct net_device *dev)
 		size += nla_total_size(sizeof(*priv->data_bitrate_const) *
 				       priv->data_bitrate_const_cnt);
 	size += sizeof(priv->bitrate_max);			/* IFLA_CAN_BITRATE_MAX */
+	if (priv->tdc.tdco) {
+		size += nla_total_size(sizeof(u32));	/* IFLA_CAN_TDCV */
+		size += nla_total_size(sizeof(u32));	/* IFLA_CAN_TDCO */
+		size += nla_total_size(sizeof(u32));	/* IFLA_CAN_TDCF */
+	}
+	if (priv->tdc_const) {
+		size += nla_total_size(sizeof(u32));	/* IFLA_CAN_TDCV_MAX_CONST */
+		size += nla_total_size(sizeof(u32));	/* IFLA_CAN_TDCO_MAX_CONST */
+		size += nla_total_size(sizeof(u32));	/* IFLA_CAN_TDCF_MAX_CONST */
+	}
 
 	return size;
 }
@@ -314,7 +374,18 @@ static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)
 
 	    (nla_put(skb, IFLA_CAN_BITRATE_MAX,
 		     sizeof(priv->bitrate_max),
-		     &priv->bitrate_max))
+		     &priv->bitrate_max)) ||
+
+	    (priv->tdc_const &&
+	     (nla_put_u32(skb, IFLA_CAN_TDCV, priv->tdc.tdcv) ||
+	      nla_put_u32(skb, IFLA_CAN_TDCO, priv->tdc.tdco) ||
+	      nla_put_u32(skb, IFLA_CAN_TDCF, priv->tdc.tdcf) ||
+	      nla_put_u32(skb, IFLA_CAN_TDCV_MAX_CONST,
+			  priv->tdc_const->tdcv_max) ||
+	      nla_put_u32(skb, IFLA_CAN_TDCO_MAX_CONST,
+			  priv->tdc_const->tdco_max) ||
+	      nla_put_u32(skb, IFLA_CAN_TDCF_MAX_CONST,
+			  priv->tdc_const->tdcf_max)))
 	    )
 
 		return -EMSGSIZE;
diff --git a/include/uapi/linux/can/netlink.h b/include/uapi/linux/can/netlink.h
index f730d443b918..e69c4b330ae6 100644
--- a/include/uapi/linux/can/netlink.h
+++ b/include/uapi/linux/can/netlink.h
@@ -134,6 +134,12 @@ enum {
 	IFLA_CAN_BITRATE_CONST,
 	IFLA_CAN_DATA_BITRATE_CONST,
 	IFLA_CAN_BITRATE_MAX,
+	IFLA_CAN_TDCV,
+	IFLA_CAN_TDCO,
+	IFLA_CAN_TDCF,
+	IFLA_CAN_TDCV_MAX_CONST,
+	IFLA_CAN_TDCO_MAX_CONST,
+	IFLA_CAN_TDCF_MAX_CONST,
 	__IFLA_CAN_MAX
 };
 
-- 
2.26.2




[Index of Archives]     [Automotive Discussions]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [CAN Bus]

  Powered by Linux