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.
In the netlink interface, each boolean option is in reality a tristate
in disguise: on, off or omitted. For the moment, TMS is implemented as
below:
- CAN_CTRLMODE_XL_TMS is set to false: TMS is disabled.
- CAN_CTRLMODE_XL_TMS is set to true: TMS is enabled.
- CAN_CTRLMODE_XL_TMS is omitted: return -EOPNOTSUPP.
For most of the other control modes, omitting a flag default to the
option turned off. It could also be possible to provide a default
behaviour if the TMS flag is omitted (i.e. either default to TMS off
or on). However, it is not clear for the moment which default
behaviour is preferable. If the usage shows a clear trend (for example
if the vast majority of the users want TMS on by default), it is still
possible to revisit that choice in the future. Whereas once a default
option is provided, we can not change it back without breaking the
interface.
As a corollary, for the moment, the users will be forced to specify
the TMS in the ip tool when using CAN XL.
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>
---
Question:
Is it still possible to send Classical CAN frames when TMS is on? If
not, we need to also add this filter in can_dev_dropped_skb():
if ((priv->ctrlmode & CAN_CTRLMODE_XL_TMS) && !can_is_canxl_skb(skb)) {
netdev_info_once(dev,
"Classical CAN frames are not allowed under CAN XL's TMS mode\n");
goto invalid_skb;
}
My current assumption is that this is possible. But the standard being
not crystal clear on that point, I want to double check this with you!
---
drivers/net/can/dev/dev.c | 2 ++
drivers/net/can/dev/netlink.c | 52 +++++++++++++++++++++++++++++++++++++---
include/uapi/linux/can/netlink.h | 1 +
3 files changed, 52 insertions(+), 3 deletions(-)
diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
index 32f11db88295..1de5babcc4f3 100644
--- a/drivers/net/can/dev/dev.c
+++ b/drivers/net/can/dev/dev.c
@@ -123,6 +123,8 @@ const char *can_get_ctrlmode_str(u32 ctrlmode)
return "xl-tdc-auto";
case CAN_CTRLMODE_XL_TDC_MANUAL:
return "xl-tdc-manual";
+ case CAN_CTRLMODE_XL_TMS:
+ return "xl-tms";
default:
return "<unknown>";
}
diff --git a/drivers/net/can/dev/netlink.c b/drivers/net/can/dev/netlink.c
index 2405f1265488..8afd2baa03cf 100644
--- a/drivers/net/can/dev/netlink.c
+++ b/drivers/net/can/dev/netlink.c
@@ -181,6 +181,36 @@ static int can_validate_databittiming(struct nlattr *data[],
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 (!(mask & CAN_CTRLMODE_XL_TMS)) {
+ NL_SET_ERR_MSG(extack, "Specify whether TMS is on or off");
+ return -EOPNOTSUPP;
+ }
+ 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)
{
@@ -201,6 +231,10 @@ static int can_validate(struct nlattr *tb[], struct nlattr *data[],
"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);
@@ -227,7 +261,7 @@ static int can_ctrlmode_changelink(struct net_device *dev,
struct can_priv *priv = netdev_priv(dev);
struct can_ctrlmode *cm;
const u32 xl_mandatory = CAN_CTRLMODE_RESTRICTED;
- u32 ctrlstatic, maskedflags, notsupp, ctrlstatic_missing, xl_missing;
+ u32 ctrlstatic, maskedflags, deactivated, notsupp, ctrlstatic_missing, xl_missing;
if (!data[IFLA_CAN_CTRLMODE])
return 0;
@@ -239,6 +273,7 @@ static int can_ctrlmode_changelink(struct net_device *dev,
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;
xl_missing = (priv->ctrlmode_supported & xl_mandatory) ^ xl_mandatory;
@@ -268,11 +303,21 @@ static int can_ctrlmode_changelink(struct net_device *dev,
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;
@@ -404,7 +449,8 @@ static int can_dbt_changelink(struct net_device *dev, struct nlattr *data[],
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 */
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
@@ -107,6 +107,7 @@ struct can_ctrlmode {
#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
--
2.51.0
Hello Vincent,
On 21.10.25 17:47, Vincent Mailhol wrote:
> 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.
>
> In the netlink interface, each boolean option is in reality a tristate
> in disguise: on, off or omitted. For the moment, TMS is implemented as
> below:
>
> - CAN_CTRLMODE_XL_TMS is set to false: TMS is disabled.
> - CAN_CTRLMODE_XL_TMS is set to true: TMS is enabled.
> - CAN_CTRLMODE_XL_TMS is omitted: return -EOPNOTSUPP.
I would propose to follow the usual pattern:
- TMS off (default)
- TMS on (when selected on the command line)
> For most of the other control modes, omitting a flag default to the
> option turned off. It could also be possible to provide a default
> behaviour if the TMS flag is omitted (i.e. either default to TMS off
> or on). However, it is not clear for the moment which default
> behaviour is preferable. If the usage shows a clear trend (for example
> if the vast majority of the users want TMS on by default), it is still
> possible to revisit that choice in the future. Whereas once a default
> option is provided, we can not change it back without breaking the
> interface.
>
> As a corollary, for the moment, the users will be forced to specify
> the TMS in the ip tool when using CAN XL.
>
> 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>
> ---
> Question:
>
> Is it still possible to send Classical CAN frames when TMS is on? If
> not, we need to also add this filter in can_dev_dropped_skb():
No.
I've now learned there are two "CANXL-only" modes:
1. TMS on -> no CC/FD traffic
2. TMS off and ERR_SIG off -> no CC/FD traffic, because CC/FD require
ERR_SIG on for a compliant transmission
And there is a "mixed-mode" with CC/FD/XL with TMS off ('ERR_SIG on' is
default anyway).
This "mixed-mode" requires all bitrates for CC/FD/XL to be set and all
these CAN protocols can be sent.
Currently the "mixed mode" consistency check does not insist on having
FD on.
> if ((priv->ctrlmode & CAN_CTRLMODE_XL_TMS) && !can_is_canxl_skb(skb)) {
> netdev_info_once(dev,
> "Classical CAN frames are not allowed under CAN XL's TMS mode\n");
> goto invalid_skb;
> }
Disabling CC & FD traffic with TMS on resp. ERR_SIG off is addressed in
my patch:
[PATCH b4/canxl-netlink v2] can: drop unsupported CAN frames on socket
and netdev level
https://lore.kernel.org/linux-can/20251103185336.32772-1-socketcan@hartkopp.net/T/#u
TMS on resp. ERR_SIG off urges FD to be off. And with this condition CC
traffic is also disabled by that patch.
> My current assumption is that this is possible.
No.
> But the standard being
> not crystal clear on that point, I want to double check this with you!
Done ;-)
Best regards,
Oliver
> ---
> drivers/net/can/dev/dev.c | 2 ++
> drivers/net/can/dev/netlink.c | 52 +++++++++++++++++++++++++++++++++++++---
> include/uapi/linux/can/netlink.h | 1 +
> 3 files changed, 52 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
> index 32f11db88295..1de5babcc4f3 100644
> --- a/drivers/net/can/dev/dev.c
> +++ b/drivers/net/can/dev/dev.c
> @@ -123,6 +123,8 @@ const char *can_get_ctrlmode_str(u32 ctrlmode)
> return "xl-tdc-auto";
> case CAN_CTRLMODE_XL_TDC_MANUAL:
> return "xl-tdc-manual";
> + case CAN_CTRLMODE_XL_TMS:
> + return "xl-tms";
> default:
> return "<unknown>";
> }
> diff --git a/drivers/net/can/dev/netlink.c b/drivers/net/can/dev/netlink.c
> index 2405f1265488..8afd2baa03cf 100644
> --- a/drivers/net/can/dev/netlink.c
> +++ b/drivers/net/can/dev/netlink.c
> @@ -181,6 +181,36 @@ static int can_validate_databittiming(struct nlattr *data[],
> 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 (!(mask & CAN_CTRLMODE_XL_TMS)) {
> + NL_SET_ERR_MSG(extack, "Specify whether TMS is on or off");
> + return -EOPNOTSUPP;
> + }
> + 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)
> {
> @@ -201,6 +231,10 @@ static int can_validate(struct nlattr *tb[], struct nlattr *data[],
> "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);
> @@ -227,7 +261,7 @@ static int can_ctrlmode_changelink(struct net_device *dev,
> struct can_priv *priv = netdev_priv(dev);
> struct can_ctrlmode *cm;
> const u32 xl_mandatory = CAN_CTRLMODE_RESTRICTED;
> - u32 ctrlstatic, maskedflags, notsupp, ctrlstatic_missing, xl_missing;
> + u32 ctrlstatic, maskedflags, deactivated, notsupp, ctrlstatic_missing, xl_missing;
>
> if (!data[IFLA_CAN_CTRLMODE])
> return 0;
> @@ -239,6 +273,7 @@ static int can_ctrlmode_changelink(struct net_device *dev,
> 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;
> xl_missing = (priv->ctrlmode_supported & xl_mandatory) ^ xl_mandatory;
> @@ -268,11 +303,21 @@ static int can_ctrlmode_changelink(struct net_device *dev,
> 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;
> @@ -404,7 +449,8 @@ static int can_dbt_changelink(struct net_device *dev, struct nlattr *data[],
> 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 */
> 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
> @@ -107,6 +107,7 @@ struct can_ctrlmode {
> #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
>
Hello Oliver,
On 06/11/2025 at 09:42, Oliver Hartkopp wrote:
> Hello Vincent,
>
> On 21.10.25 17:47, Vincent Mailhol wrote:
>> 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.
>>
>> In the netlink interface, each boolean option is in reality a tristate
>> in disguise: on, off or omitted. For the moment, TMS is implemented as
>> below:
>>
>> - CAN_CTRLMODE_XL_TMS is set to false: TMS is disabled.
>> - CAN_CTRLMODE_XL_TMS is set to true: TMS is enabled.
>> - CAN_CTRLMODE_XL_TMS is omitted: return -EOPNOTSUPP.
>
> I would propose to follow the usual pattern:
>
> - TMS off (default)
> - TMS on (when selected on the command line)
OK. "TMS omitted" will be interpreted as "TMS off" in v2.
>> For most of the other control modes, omitting a flag default to the
>> option turned off. It could also be possible to provide a default
>> behaviour if the TMS flag is omitted (i.e. either default to TMS off
>> or on). However, it is not clear for the moment which default
>> behaviour is preferable. If the usage shows a clear trend (for example
>> if the vast majority of the users want TMS on by default), it is still
>> possible to revisit that choice in the future. Whereas once a default
>> option is provided, we can not change it back without breaking the
>> interface.
>>
>> As a corollary, for the moment, the users will be forced to specify
>> the TMS in the ip tool when using CAN XL.
>>
>> 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>
>> ---
>> Question:
>>
>> Is it still possible to send Classical CAN frames when TMS is on? If
>> not, we need to also add this filter in can_dev_dropped_skb():
>
> No.
>
> I've now learned there are two "CANXL-only" modes:
>
> 1. TMS on -> no CC/FD traffic
> 2. TMS off and ERR_SIG off -> no CC/FD traffic, because CC/FD require ERR_SIG on
> for a compliant transmission
I see. I was under the assumption that CC and FD could be used with error
signalling off in mixed mode. Thanks!
> And there is a "mixed-mode" with CC/FD/XL with TMS off ('ERR_SIG on' is default
> anyway).
>
> This "mixed-mode" requires all bitrates for CC/FD/XL to be set and all these CAN
> protocols can be sent.
Why? Will your device reject the configuration if you omit the FD bitrate? I did
not see anything in this direction in the ISO standard.
Did you have any source for this? Maybe the CiA provided some clarification
which I am not aware of?
Yours sincerely,
Vincent Mailhol
Hi Vincent,
On 09.11.25 15:28, Vincent Mailhol wrote:
> Hello Oliver,
>
> On 06/11/2025 at 09:42, Oliver Hartkopp wrote:
>> Hello Vincent,
>>
>> On 21.10.25 17:47, Vincent Mailhol wrote:
>>> 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.
>>>
>>> In the netlink interface, each boolean option is in reality a tristate
>>> in disguise: on, off or omitted. For the moment, TMS is implemented as
>>> below:
>>>
>>> - CAN_CTRLMODE_XL_TMS is set to false: TMS is disabled.
>>> - CAN_CTRLMODE_XL_TMS is set to true: TMS is enabled.
>>> - CAN_CTRLMODE_XL_TMS is omitted: return -EOPNOTSUPP.
>>
>> I would propose to follow the usual pattern:
>>
>> - TMS off (default)
>> - TMS on (when selected on the command line)
>
> OK. "TMS omitted" will be interpreted as "TMS off" in v2.
>
Thx!
>>> For most of the other control modes, omitting a flag default to the
>>> option turned off. It could also be possible to provide a default
>>> behaviour if the TMS flag is omitted (i.e. either default to TMS off
>>> or on). However, it is not clear for the moment which default
>>> behaviour is preferable. If the usage shows a clear trend (for example
>>> if the vast majority of the users want TMS on by default), it is still
>>> possible to revisit that choice in the future. Whereas once a default
>>> option is provided, we can not change it back without breaking the
>>> interface.
>>>
>>> As a corollary, for the moment, the users will be forced to specify
>>> the TMS in the ip tool when using CAN XL.
>>>
>>> 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>
>>> ---
>>> Question:
>>>
>>> Is it still possible to send Classical CAN frames when TMS is on? If
>>> not, we need to also add this filter in can_dev_dropped_skb():
>>
>> No.
>>
>> I've now learned there are two "CANXL-only" modes:
>>
>> 1. TMS on -> no CC/FD traffic
>> 2. TMS off and ERR_SIG off -> no CC/FD traffic, because CC/FD require ERR_SIG on
>> for a compliant transmission
>
> I see. I was under the assumption that CC and FD could be used with error
> signalling off in mixed mode. Thanks!
>
>> And there is a "mixed-mode" with CC/FD/XL with TMS off ('ERR_SIG on' is default
>> anyway).
>>
>> This "mixed-mode" requires all bitrates for CC/FD/XL to be set and all these CAN
>> protocols can be sent.
>
> Why? Will your device reject the configuration if you omit the FD bitrate? I did
> not see anything in this direction in the ISO standard.
>
> Did you have any source for this? Maybe the CiA provided some clarification
> which I am not aware of?
It wasn't clear to me either.
Please take a look into the X_CAN user manual here:
https://github.com/linux-can/can-doc/blob/master/x_can/xcan_user_manual_v350.pdf
1.5.5.3 Operating Mode
There you can see the valid (and invalid) modes & combinations.
When XL is on, FD also has to be on. Of course this is Bosch specific in
the first place. But there are two modes (ERR_SIGNAL off either with TMS
on or off) that are "CANXL-Only" which means no CC and no FD traffic as
those need error-signalling. CAN XL is using the (CC) arbitration
bitrate in this XL-only mode but CAN CC frames can not be sent.
I would recommend this CAN CiA Webinar from Dr. Arthur Mutter:
https://www.youtube.com/watch?v=OSEj6ISJKAM
As (only!) the CAN FD controllers are CAN XL tolerant (see video
timestamp 18:53) the "mixed-mode" basically means "a mix of XL and FD
controllers and protocols".
The fact that FD&XL controllers then can also send CC frames in this
mixed-mode is just a side-effect IMO. The idea is FD & XL.
Therefore the two XL modes "XL-Only" and "mixed-mode" leads to FD on in
the mixed-mode IMO. And this finally can be used in my "[PATCH
b4/canxl-netlink v2] can: drop unsupported CAN frames on socket
and netdev level" patch.
Best regards,
Oliver
© 2016 - 2026 Red Hat, Inc.