From: Oliver Hartkopp <socketcan@hartkopp.net>
To: linux-can@vger.kernel.org
Cc: Vincent Mailhol <mailhol@kernel.org>,
Oliver Hartkopp <socketcan@hartkopp.net>
Subject: [canxl v5 06/17] can: netlink: add CAN_CTRLMODE_XL_TMS flag
Date: Fri, 21 Nov 2025 20:35:02 +0100 [thread overview]
Message-ID: <20251121193513.2097-7-socketcan@hartkopp.net> (raw)
In-Reply-To: <20251121193513.2097-1-socketcan@hartkopp.net>
From: Vincent Mailhol <mailhol@kernel.org>
The Transceiver Mode Switching (TMS) indicates whether the CAN XL
controller shall use the PWM or NRZ encoding during the data phase.
The term "transceiver mode switching" is used in both ISO 11898-1 and
CiA 612-2 (although only the latter one uses the abbreviation TMS). We
adopt the same naming convention here for consistency.
Add the CAN_CTRLMODE_XL_TMS flag to the list of the CAN control modes.
Add can_validate_xl_flags() to check the coherency of the TMS flag.
That function will be reused in upcoming changes to validate the other
CAN XL flags.
Signed-off-by: Vincent Mailhol <mailhol@kernel.org>
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
---
drivers/net/can/dev/dev.c | 2 ++
drivers/net/can/dev/netlink.c | 48 ++++++++++++++++++++++++++++++--
include/uapi/linux/can/netlink.h | 1 +
3 files changed, 48 insertions(+), 3 deletions(-)
diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
index dbc9b099b3f9..32db9f69844d 100644
--- a/drivers/net/can/dev/dev.c
+++ b/drivers/net/can/dev/dev.c
@@ -121,10 +121,12 @@ const char *can_get_ctrlmode_str(u32 ctrlmode)
return "XL";
case CAN_CTRLMODE_XL_TDC_AUTO:
return "XL-TDC-AUTO";
case CAN_CTRLMODE_XL_TDC_MANUAL:
return "XL-TDC-MANUAL";
+ case CAN_CTRLMODE_XL_TMS:
+ return "TMS";
default:
return "<unknown>";
}
}
EXPORT_SYMBOL_GPL(can_get_ctrlmode_str);
diff --git a/drivers/net/can/dev/netlink.c b/drivers/net/can/dev/netlink.c
index fdd1fa7cf93a..b2c24439abba 100644
--- a/drivers/net/can/dev/netlink.c
+++ b/drivers/net/can/dev/netlink.c
@@ -179,10 +179,36 @@ static int can_validate_databittiming(struct nlattr *data[],
return err;
return 0;
}
+static int can_validate_xl_flags(struct netlink_ext_ack *extack,
+ u32 masked_flags, u32 mask)
+{
+ if (masked_flags & CAN_CTRLMODE_XL) {
+ if (masked_flags & CAN_CTRLMODE_XL_TMS) {
+ const u32 tms_conflicts_mask = CAN_CTRLMODE_FD |
+ CAN_CTRLMODE_XL_TDC_MASK;
+ u32 tms_conflicts = masked_flags & tms_conflicts_mask;
+
+ if (tms_conflicts) {
+ NL_SET_ERR_MSG_FMT(extack,
+ "TMS and %s are mutually exclusive",
+ can_get_ctrlmode_str(tms_conflicts));
+ return -EOPNOTSUPP;
+ }
+ }
+ } else {
+ if (mask & CAN_CTRLMODE_XL_TMS) {
+ NL_SET_ERR_MSG(extack, "TMS requires CAN XL");
+ return -EOPNOTSUPP;
+ }
+ }
+
+ return 0;
+}
+
static int can_validate(struct nlattr *tb[], struct nlattr *data[],
struct netlink_ext_ack *extack)
{
u32 flags = 0;
int err;
@@ -199,10 +225,14 @@ static int can_validate(struct nlattr *tb[], struct nlattr *data[],
(flags & CAN_CTRLMODE_RESTRICTED)) {
NL_SET_ERR_MSG(extack,
"LISTEN-ONLY and RESTRICTED modes are mutually exclusive");
return -EOPNOTSUPP;
}
+
+ err = can_validate_xl_flags(extack, flags, cm->mask);
+ if (err)
+ return err;
}
err = can_validate_bittiming(data, extack, IFLA_CAN_BITTIMING);
if (err)
return err;
@@ -224,11 +254,11 @@ static int can_ctrlmode_changelink(struct net_device *dev,
struct nlattr *data[],
struct netlink_ext_ack *extack)
{
struct can_priv *priv = netdev_priv(dev);
struct can_ctrlmode *cm;
- u32 ctrlstatic, maskedflags, notsupp, ctrlstatic_missing;
+ u32 ctrlstatic, maskedflags, deactivated, notsupp, ctrlstatic_missing;
if (!data[IFLA_CAN_CTRLMODE])
return 0;
/* Do not allow changing controller mode while running */
@@ -236,10 +266,11 @@ static int can_ctrlmode_changelink(struct net_device *dev,
return -EBUSY;
cm = nla_data(data[IFLA_CAN_CTRLMODE]);
ctrlstatic = can_get_static_ctrlmode(priv);
maskedflags = cm->flags & cm->mask;
+ deactivated = ~cm->flags & cm->mask;
notsupp = maskedflags & ~(priv->ctrlmode_supported | ctrlstatic);
ctrlstatic_missing = (maskedflags & ctrlstatic) ^ ctrlstatic;
if (notsupp) {
NL_SET_ERR_MSG_FMT(extack,
@@ -257,15 +288,25 @@ static int can_ctrlmode_changelink(struct net_device *dev,
"missing required %s static control mode",
can_get_ctrlmode_str(ctrlstatic_missing));
return -EOPNOTSUPP;
}
+ /* If FD was active and is not turned off, check for XL conflicts */
+ if (priv->ctrlmode & CAN_CTRLMODE_FD & ~deactivated) {
+ if (maskedflags & CAN_CTRLMODE_XL_TMS) {
+ NL_SET_ERR_MSG(extack,
+ "TMS can not be activated while CAN FD is on");
+ return -EOPNOTSUPP;
+ }
+ }
+
/* If a top dependency flag is provided, reset all its dependencies */
if (cm->mask & CAN_CTRLMODE_FD)
priv->ctrlmode &= ~CAN_CTRLMODE_FD_TDC_MASK;
if (cm->mask & CAN_CTRLMODE_XL)
- priv->ctrlmode &= ~(CAN_CTRLMODE_XL_TDC_MASK);
+ priv->ctrlmode &= ~(CAN_CTRLMODE_XL_TDC_MASK |
+ CAN_CTRLMODE_XL_TMS);
/* clear bits to be modified and copy the flag values */
priv->ctrlmode &= ~cm->mask;
priv->ctrlmode |= maskedflags;
@@ -393,11 +434,12 @@ static int can_dbt_changelink(struct net_device *dev, struct nlattr *data[],
memset(&dbt_params->tdc, 0, sizeof(dbt_params->tdc));
if (data[IFLA_CAN_CTRLMODE]) {
struct can_ctrlmode *cm = nla_data(data[IFLA_CAN_CTRLMODE]);
- need_tdc_calc = !(cm->mask & tdc_mask);
+ if (fd || !(priv->ctrlmode & CAN_CTRLMODE_XL_TMS))
+ need_tdc_calc = !(cm->mask & tdc_mask);
}
if (data_tdc) {
/* TDC parameters are provided: use them */
err = can_tdc_changelink(dbt_params, data_tdc, extack);
if (err) {
diff --git a/include/uapi/linux/can/netlink.h b/include/uapi/linux/can/netlink.h
index c2c96c5978a8..ebafb091d80f 100644
--- a/include/uapi/linux/can/netlink.h
+++ b/include/uapi/linux/can/netlink.h
@@ -105,10 +105,11 @@ struct can_ctrlmode {
#define CAN_CTRLMODE_TDC_MANUAL 0x400 /* FD TDCV is manually set up by user */
#define CAN_CTRLMODE_RESTRICTED 0x800 /* Restricted operation mode */
#define CAN_CTRLMODE_XL 0x1000 /* CAN XL mode */
#define CAN_CTRLMODE_XL_TDC_AUTO 0x2000 /* XL transceiver automatically calculates TDCV */
#define CAN_CTRLMODE_XL_TDC_MANUAL 0x4000 /* XL TDCV is manually set up by user */
+#define CAN_CTRLMODE_XL_TMS 0x8000 /* Transceiver Mode Switching */
/*
* CAN device statistics
*/
struct can_device_stats {
--
2.47.3
next prev parent reply other threads:[~2025-11-21 19:35 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-21 19:34 [canxl v5 00/17] CAN XL support for review (full series) Oliver Hartkopp
2025-11-21 19:34 ` [canxl v5 01/17] can: dev: can_get_ctrlmode_str: use capitalized ctrlmode strings Oliver Hartkopp
2025-11-21 19:34 ` [canxl v5 02/17] can: bittiming: apply NL_SET_ERR_MSG() to can_calc_bittiming() Oliver Hartkopp
2025-11-21 19:34 ` [canxl v5 03/17] can: dev: can_dev_dropped_skb: drop CAN FD skbs if FD is off Oliver Hartkopp
2025-11-21 19:35 ` [canxl v5 04/17] can: netlink: add CAN_CTRLMODE_RESTRICTED Oliver Hartkopp
2025-11-21 19:35 ` [canxl v5 05/17] can: netlink: add initial CAN XL support Oliver Hartkopp
2025-11-21 19:35 ` Oliver Hartkopp [this message]
2025-11-21 19:35 ` [canxl v5 07/17] can: dev: can_dev_dropped_skb: drop CC/FD frames in CANXL-only mode Oliver Hartkopp
2025-11-21 19:35 ` [canxl v5 08/17] can: bittiming: add PWM parameters Oliver Hartkopp
2025-11-21 19:35 ` [canxl v5 09/17] can: bittiming: add PWM validation Oliver Hartkopp
2025-11-21 19:35 ` [canxl v5 10/17] can: calc_bittiming: add PWM calculation Oliver Hartkopp
2025-11-21 19:35 ` [canxl v5 11/17] can: netlink: add PWM netlink interface Oliver Hartkopp
2025-11-21 19:35 ` [canxl v5 12/17] can: calc_bittiming: get rid of the incorrect "nominal" word Oliver Hartkopp
2025-11-21 19:35 ` [canxl v5 13/17] can: calc_bittiming: add can_calc_sample_point_nrz() Oliver Hartkopp
2025-11-21 19:35 ` [canxl v5 14/17] can: calc_bittiming: add can_calc_sample_point_pwm() Oliver Hartkopp
2025-11-21 19:35 ` [canxl v5 15/17] can: add dummy_can driver Oliver Hartkopp
2025-11-21 19:35 ` [canxl v5 16/17] can: raw: instantly reject unsupported CAN frames Oliver Hartkopp
2025-11-21 19:35 ` [canxl v5 17/17] can: dev: print bitrate error with two decimal digits Oliver Hartkopp
2025-11-21 19:57 ` Marc Kleine-Budde
2025-11-21 21:01 ` Oliver Hartkopp
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251121193513.2097-7-socketcan@hartkopp.net \
--to=socketcan@hartkopp.net \
--cc=linux-can@vger.kernel.org \
--cc=mailhol@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.