Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

can: netlink: add initial CAN XL support

CAN XL uses bittiming parameters different from Classical CAN and CAN
FD. Thus, all the data bittiming parameters, including TDC, need to be
duplicated for CAN XL.

Add the CAN XL netlink interface for all the features which are common
with CAN FD. Any new CAN XL specific features are added later on.

The first time CAN XL is activated, the MTU is set by default to
CANXL_MAX_MTU. The user may then configure a custom MTU within the
CANXL_MIN_MTU to CANXL_MAX_MTU range, in which case, the custom MTU
value will be kept as long as CAN XL remains active.

Signed-off-by: Vincent Mailhol <mailhol@kernel.org>
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Link: https://patch.msgid.link/20251126-canxl-v8-5-e7e3eb74f889@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>

authored by

Vincent Mailhol and committed by
Marc Kleine-Budde
e6328161 60f511f4

+90 -20
+13 -1
drivers/net/can/dev/dev.c
··· 117 117 return "TDC-MANUAL"; 118 118 case CAN_CTRLMODE_RESTRICTED: 119 119 return "RESTRICTED"; 120 + case CAN_CTRLMODE_XL: 121 + return "XL"; 122 + case CAN_CTRLMODE_XL_TDC_AUTO: 123 + return "XL-TDC-AUTO"; 124 + case CAN_CTRLMODE_XL_TDC_MANUAL: 125 + return "XL-TDC-MANUAL"; 120 126 default: 121 127 return "<unknown>"; 122 128 } ··· 356 350 { 357 351 struct can_priv *priv = netdev_priv(dev); 358 352 359 - if (priv->ctrlmode & CAN_CTRLMODE_FD) { 353 + if (priv->ctrlmode & CAN_CTRLMODE_XL) { 354 + if (can_is_canxl_dev_mtu(dev->mtu)) 355 + return; 356 + dev->mtu = CANXL_MTU; 357 + dev->min_mtu = CANXL_MIN_MTU; 358 + dev->max_mtu = CANXL_MAX_MTU; 359 + } else if (priv->ctrlmode & CAN_CTRLMODE_FD) { 360 360 dev->mtu = CANFD_MTU; 361 361 dev->min_mtu = CANFD_MTU; 362 362 dev->max_mtu = CANFD_MTU;
+60 -16
drivers/net/can/dev/netlink.c
··· 2 2 /* Copyright (C) 2005 Marc Kleine-Budde, Pengutronix 3 3 * Copyright (C) 2006 Andrey Volkov, Varma Electronics 4 4 * Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com> 5 - * Copyright (C) 2021 Vincent Mailhol <mailhol.vincent@wanadoo.fr> 5 + * Copyright (C) 2021-2025 Vincent Mailhol <mailhol@kernel.org> 6 6 */ 7 7 8 8 #include <linux/can/dev.h> ··· 22 22 [IFLA_CAN_TERMINATION] = { .type = NLA_U16 }, 23 23 [IFLA_CAN_TDC] = { .type = NLA_NESTED }, 24 24 [IFLA_CAN_CTRLMODE_EXT] = { .type = NLA_NESTED }, 25 + [IFLA_CAN_XL_DATA_BITTIMING] = { .len = sizeof(struct can_bittiming) }, 26 + [IFLA_CAN_XL_DATA_BITTIMING_CONST] = { .len = sizeof(struct can_bittiming_const) }, 27 + [IFLA_CAN_XL_TDC] = { .type = NLA_NESTED }, 25 28 }; 26 29 27 30 static const struct nla_policy can_tdc_policy[IFLA_CAN_TDC_MAX + 1] = { ··· 73 70 return -EOPNOTSUPP; 74 71 } 75 72 76 - /* If one of the CAN_CTRLMODE_TDC_* flag is set then TDC 73 + /* If one of the CAN_CTRLMODE_{,XL}_TDC_* flags is set then TDC 77 74 * must be set and vice-versa 78 75 */ 79 76 if ((tdc_auto || tdc_manual) && !data_tdc) { ··· 85 82 return -EOPNOTSUPP; 86 83 } 87 84 88 - /* If providing TDC parameters, at least TDCO is needed. TDCV 89 - * is needed if and only if CAN_CTRLMODE_TDC_MANUAL is set 85 + /* If providing TDC parameters, at least TDCO is needed. TDCV is 86 + * needed if and only if CAN_CTRLMODE_{,XL}_TDC_MANUAL is set 90 87 */ 91 88 if (data_tdc) { 92 89 struct nlattr *tb_tdc[IFLA_CAN_TDC_MAX + 1]; ··· 129 126 bool is_on; 130 127 int err; 131 128 132 - /* Make sure that valid CAN FD configurations always consist of 129 + /* Make sure that valid CAN FD/XL configurations always consist of 133 130 * - nominal/arbitration bittiming 134 131 * - data bittiming 135 - * - control mode with CAN_CTRLMODE_FD set 132 + * - control mode with CAN_CTRLMODE_{FD,XL} set 136 133 * - TDC parameters are coherent (details in can_validate_tdc()) 137 134 */ 138 135 ··· 142 139 is_on = flags & CAN_CTRLMODE_FD; 143 140 type = "FD"; 144 141 } else { 145 - return -EOPNOTSUPP; /* Place holder for CAN XL */ 142 + data_tdc = data[IFLA_CAN_XL_TDC]; 143 + tdc_flags = flags & CAN_CTRLMODE_XL_TDC_MASK; 144 + is_on = flags & CAN_CTRLMODE_XL; 145 + type = "XL"; 146 146 } 147 147 148 148 if (is_on) { ··· 212 206 if (err) 213 207 return err; 214 208 209 + err = can_validate_databittiming(data, extack, 210 + IFLA_CAN_XL_DATA_BITTIMING, flags); 211 + if (err) 212 + return err; 213 + 215 214 return 0; 216 215 } 217 216 ··· 262 251 /* If a top dependency flag is provided, reset all its dependencies */ 263 252 if (cm->mask & CAN_CTRLMODE_FD) 264 253 priv->ctrlmode &= ~CAN_CTRLMODE_FD_TDC_MASK; 254 + if (cm->mask & CAN_CTRLMODE_XL) 255 + priv->ctrlmode &= ~(CAN_CTRLMODE_XL_TDC_MASK); 265 256 266 257 /* clear bits to be modified and copy the flag values */ 267 258 priv->ctrlmode &= ~cm->mask; 268 259 priv->ctrlmode |= maskedflags; 269 260 270 - /* Wipe potential leftovers from previous CAN FD config */ 261 + /* Wipe potential leftovers from previous CAN FD/XL config */ 271 262 if (!(priv->ctrlmode & CAN_CTRLMODE_FD)) { 272 263 memset(&priv->fd.data_bittiming, 0, 273 264 sizeof(priv->fd.data_bittiming)); 274 265 priv->ctrlmode &= ~CAN_CTRLMODE_FD_TDC_MASK; 275 266 memset(&priv->fd.tdc, 0, sizeof(priv->fd.tdc)); 267 + } 268 + if (!(priv->ctrlmode & CAN_CTRLMODE_XL)) { 269 + memset(&priv->xl.data_bittiming, 0, 270 + sizeof(priv->fd.data_bittiming)); 271 + priv->ctrlmode &= ~CAN_CTRLMODE_XL_TDC_MASK; 272 + memset(&priv->xl.tdc, 0, sizeof(priv->xl.tdc)); 276 273 } 277 274 278 275 can_set_default_mtu(dev); ··· 356 337 dbt_params = &priv->fd; 357 338 tdc_mask = CAN_CTRLMODE_FD_TDC_MASK; 358 339 } else { 359 - return -EOPNOTSUPP; /* Place holder for CAN XL */ 340 + data_bittiming = data[IFLA_CAN_XL_DATA_BITTIMING]; 341 + data_tdc = data[IFLA_CAN_XL_TDC]; 342 + dbt_params = &priv->xl; 343 + tdc_mask = CAN_CTRLMODE_XL_TDC_MASK; 360 344 } 361 345 362 346 if (!data_bittiming) ··· 410 388 */ 411 389 can_calc_tdco(&dbt_params->tdc, dbt_params->tdc_const, &dbt, 412 390 tdc_mask, &priv->ctrlmode, priv->ctrlmode_supported); 413 - } /* else: both CAN_CTRLMODE_TDC_{AUTO,MANUAL} are explicitly 391 + } /* else: both CAN_CTRLMODE_{,XL}_TDC_{AUTO,MANUAL} are explicitly 414 392 * turned off. TDC is disabled: do nothing 415 393 */ 416 394 ··· 515 493 if (err) 516 494 return err; 517 495 496 + /* CAN XL */ 497 + err = can_dbt_changelink(dev, data, false, extack); 498 + if (err) 499 + return err; 500 + 518 501 if (data[IFLA_CAN_TERMINATION]) { 519 502 const u16 termval = nla_get_u16(data[IFLA_CAN_TERMINATION]); 520 503 const unsigned int num_term = priv->termination_const_cnt; ··· 587 560 { 588 561 size_t size = 0; 589 562 590 - if (dbt_params->data_bittiming.bitrate) /* IFLA_CAN_DATA_BITTIMING */ 563 + if (dbt_params->data_bittiming.bitrate) /* IFLA_CAN_{,XL}_DATA_BITTIMING */ 591 564 size += nla_total_size(sizeof(dbt_params->data_bittiming)); 592 - if (dbt_params->data_bittiming_const) /* IFLA_CAN_DATA_BITTIMING_CONST */ 565 + if (dbt_params->data_bittiming_const) /* IFLA_CAN_{,XL}_DATA_BITTIMING_CONST */ 593 566 size += nla_total_size(sizeof(*dbt_params->data_bittiming_const)); 594 - if (dbt_params->data_bitrate_const) /* IFLA_CAN_DATA_BITRATE_CONST */ 567 + if (dbt_params->data_bitrate_const) /* IFLA_CAN_{,XL}_DATA_BITRATE_CONST */ 595 568 size += nla_total_size(sizeof(*dbt_params->data_bitrate_const) * 596 569 dbt_params->data_bitrate_const_cnt); 597 - size += can_tdc_get_size(dbt_params, tdc_flags);/* IFLA_CAN_TDC */ 570 + size += can_tdc_get_size(dbt_params, tdc_flags);/* IFLA_CAN_{,XL}_TDC */ 598 571 599 572 return size; 600 573 } ··· 633 606 634 607 size += can_data_bittiming_get_size(&priv->fd, 635 608 priv->ctrlmode & CAN_CTRLMODE_FD_TDC_MASK); 609 + 610 + size += can_data_bittiming_get_size(&priv->xl, 611 + priv->ctrlmode & CAN_CTRLMODE_XL_TDC_MASK); 636 612 637 613 return size; 638 614 } ··· 681 651 tdc_is_enabled = can_fd_tdc_is_enabled(priv); 682 652 tdc_manual = priv->ctrlmode & CAN_CTRLMODE_TDC_MANUAL; 683 653 } else { 684 - return -EOPNOTSUPP; /* Place holder for CAN XL */ 654 + dbt_params = &priv->xl; 655 + tdc_is_enabled = can_xl_tdc_is_enabled(priv); 656 + tdc_manual = priv->ctrlmode & CAN_CTRLMODE_XL_TDC_MANUAL; 685 657 } 686 658 tdc_const = dbt_params->tdc_const; 687 659 tdc = &dbt_params->tdc; ··· 805 773 806 774 can_tdc_fill_info(skb, dev, IFLA_CAN_TDC) || 807 775 808 - can_ctrlmode_ext_fill_info(skb, priv) 776 + can_ctrlmode_ext_fill_info(skb, priv) || 777 + 778 + can_bittiming_fill_info(skb, IFLA_CAN_XL_DATA_BITTIMING, 779 + &priv->xl.data_bittiming) || 780 + 781 + can_bittiming_const_fill_info(skb, IFLA_CAN_XL_DATA_BITTIMING_CONST, 782 + priv->xl.data_bittiming_const) || 783 + 784 + can_bitrate_const_fill_info(skb, IFLA_CAN_XL_DATA_BITRATE_CONST, 785 + priv->xl.data_bitrate_const, 786 + priv->xl.data_bitrate_const_cnt) || 787 + 788 + can_tdc_fill_info(skb, dev, IFLA_CAN_XL_TDC) 809 789 ) 810 790 811 791 return -EMSGSIZE;
+4 -2
include/linux/can/bittiming.h
··· 16 16 17 17 #define CAN_CTRLMODE_FD_TDC_MASK \ 18 18 (CAN_CTRLMODE_TDC_AUTO | CAN_CTRLMODE_TDC_MANUAL) 19 + #define CAN_CTRLMODE_XL_TDC_MASK \ 20 + (CAN_CTRLMODE_XL_TDC_AUTO | CAN_CTRLMODE_XL_TDC_MANUAL) 19 21 #define CAN_CTRLMODE_TDC_AUTO_MASK \ 20 - (CAN_CTRLMODE_TDC_AUTO) 22 + (CAN_CTRLMODE_TDC_AUTO | CAN_CTRLMODE_XL_TDC_AUTO) 21 23 #define CAN_CTRLMODE_TDC_MANUAL_MASK \ 22 - (CAN_CTRLMODE_TDC_MANUAL) 24 + (CAN_CTRLMODE_TDC_MANUAL | CAN_CTRLMODE_XL_TDC_MANUAL) 23 25 24 26 /* 25 27 * struct can_tdc - CAN FD Transmission Delay Compensation parameters
+6 -1
include/linux/can/dev.h
··· 47 47 48 48 const struct can_bittiming_const *bittiming_const; 49 49 struct can_bittiming bittiming; 50 - struct data_bittiming_params fd; 50 + struct data_bittiming_params fd, xl; 51 51 unsigned int bitrate_const_cnt; 52 52 const u32 *bitrate_const; 53 53 u32 bitrate_max; ··· 83 83 static inline bool can_fd_tdc_is_enabled(const struct can_priv *priv) 84 84 { 85 85 return !!(priv->ctrlmode & CAN_CTRLMODE_FD_TDC_MASK); 86 + } 87 + 88 + static inline bool can_xl_tdc_is_enabled(const struct can_priv *priv) 89 + { 90 + return !!(priv->ctrlmode & CAN_CTRLMODE_XL_TDC_MASK); 86 91 } 87 92 88 93 static inline u32 can_get_static_ctrlmode(struct can_priv *priv)
+7
include/uapi/linux/can/netlink.h
··· 104 104 #define CAN_CTRLMODE_TDC_AUTO 0x200 /* FD transceiver automatically calculates TDCV */ 105 105 #define CAN_CTRLMODE_TDC_MANUAL 0x400 /* FD TDCV is manually set up by user */ 106 106 #define CAN_CTRLMODE_RESTRICTED 0x800 /* Restricted operation mode */ 107 + #define CAN_CTRLMODE_XL 0x1000 /* CAN XL mode */ 108 + #define CAN_CTRLMODE_XL_TDC_AUTO 0x2000 /* XL transceiver automatically calculates TDCV */ 109 + #define CAN_CTRLMODE_XL_TDC_MANUAL 0x4000 /* XL TDCV is manually set up by user */ 107 110 108 111 /* 109 112 * CAN device statistics ··· 142 139 IFLA_CAN_BITRATE_MAX, 143 140 IFLA_CAN_TDC, /* FD */ 144 141 IFLA_CAN_CTRLMODE_EXT, 142 + IFLA_CAN_XL_DATA_BITTIMING, 143 + IFLA_CAN_XL_DATA_BITTIMING_CONST, 144 + IFLA_CAN_XL_DATA_BITRATE_CONST, 145 + IFLA_CAN_XL_TDC, 145 146 146 147 /* add new constants above here */ 147 148 __IFLA_CAN_MAX,