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 CAN_CTRLMODE_XL_TMS flag

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>
Link: https://patch.msgid.link/20251126-canxl-v8-6-e7e3eb74f889@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>

authored by

Vincent Mailhol and committed by
Marc Kleine-Budde
233134af e6328161

+48 -3
+2
drivers/net/can/dev/dev.c
··· 123 123 return "XL-TDC-AUTO"; 124 124 case CAN_CTRLMODE_XL_TDC_MANUAL: 125 125 return "XL-TDC-MANUAL"; 126 + case CAN_CTRLMODE_XL_TMS: 127 + return "TMS"; 126 128 default: 127 129 return "<unknown>"; 128 130 }
+45 -3
drivers/net/can/dev/netlink.c
··· 181 181 return 0; 182 182 } 183 183 184 + static int can_validate_xl_flags(struct netlink_ext_ack *extack, 185 + u32 masked_flags, u32 mask) 186 + { 187 + if (masked_flags & CAN_CTRLMODE_XL) { 188 + if (masked_flags & CAN_CTRLMODE_XL_TMS) { 189 + const u32 tms_conflicts_mask = CAN_CTRLMODE_FD | 190 + CAN_CTRLMODE_XL_TDC_MASK; 191 + u32 tms_conflicts = masked_flags & tms_conflicts_mask; 192 + 193 + if (tms_conflicts) { 194 + NL_SET_ERR_MSG_FMT(extack, 195 + "TMS and %s are mutually exclusive", 196 + can_get_ctrlmode_str(tms_conflicts)); 197 + return -EOPNOTSUPP; 198 + } 199 + } 200 + } else { 201 + if (mask & CAN_CTRLMODE_XL_TMS) { 202 + NL_SET_ERR_MSG(extack, "TMS requires CAN XL"); 203 + return -EOPNOTSUPP; 204 + } 205 + } 206 + 207 + return 0; 208 + } 209 + 184 210 static int can_validate(struct nlattr *tb[], struct nlattr *data[], 185 211 struct netlink_ext_ack *extack) 186 212 { ··· 227 201 "LISTEN-ONLY and RESTRICTED modes are mutually exclusive"); 228 202 return -EOPNOTSUPP; 229 203 } 204 + 205 + err = can_validate_xl_flags(extack, flags, cm->mask); 206 + if (err) 207 + return err; 230 208 } 231 209 232 210 err = can_validate_bittiming(data, extack, IFLA_CAN_BITTIMING); ··· 256 226 { 257 227 struct can_priv *priv = netdev_priv(dev); 258 228 struct can_ctrlmode *cm; 259 - u32 ctrlstatic, maskedflags, notsupp, ctrlstatic_missing; 229 + u32 ctrlstatic, maskedflags, deactivated, notsupp, ctrlstatic_missing; 260 230 261 231 if (!data[IFLA_CAN_CTRLMODE]) 262 232 return 0; ··· 268 238 cm = nla_data(data[IFLA_CAN_CTRLMODE]); 269 239 ctrlstatic = can_get_static_ctrlmode(priv); 270 240 maskedflags = cm->flags & cm->mask; 241 + deactivated = ~cm->flags & cm->mask; 271 242 notsupp = maskedflags & ~(priv->ctrlmode_supported | ctrlstatic); 272 243 ctrlstatic_missing = (maskedflags & ctrlstatic) ^ ctrlstatic; 273 244 ··· 290 259 return -EOPNOTSUPP; 291 260 } 292 261 262 + /* If FD was active and is not turned off, check for XL conflicts */ 263 + if (priv->ctrlmode & CAN_CTRLMODE_FD & ~deactivated) { 264 + if (maskedflags & CAN_CTRLMODE_XL_TMS) { 265 + NL_SET_ERR_MSG(extack, 266 + "TMS can not be activated while CAN FD is on"); 267 + return -EOPNOTSUPP; 268 + } 269 + } 270 + 293 271 /* If a top dependency flag is provided, reset all its dependencies */ 294 272 if (cm->mask & CAN_CTRLMODE_FD) 295 273 priv->ctrlmode &= ~CAN_CTRLMODE_FD_TDC_MASK; 296 274 if (cm->mask & CAN_CTRLMODE_XL) 297 - priv->ctrlmode &= ~(CAN_CTRLMODE_XL_TDC_MASK); 275 + priv->ctrlmode &= ~(CAN_CTRLMODE_XL_TDC_MASK | 276 + CAN_CTRLMODE_XL_TMS); 298 277 299 278 /* clear bits to be modified and copy the flag values */ 300 279 priv->ctrlmode &= ~cm->mask; ··· 436 395 if (data[IFLA_CAN_CTRLMODE]) { 437 396 struct can_ctrlmode *cm = nla_data(data[IFLA_CAN_CTRLMODE]); 438 397 439 - need_tdc_calc = !(cm->mask & tdc_mask); 398 + if (fd || !(priv->ctrlmode & CAN_CTRLMODE_XL_TMS)) 399 + need_tdc_calc = !(cm->mask & tdc_mask); 440 400 } 441 401 if (data_tdc) { 442 402 /* TDC parameters are provided: use them */
+1
include/uapi/linux/can/netlink.h
··· 107 107 #define CAN_CTRLMODE_XL 0x1000 /* CAN XL mode */ 108 108 #define CAN_CTRLMODE_XL_TDC_AUTO 0x2000 /* XL transceiver automatically calculates TDCV */ 109 109 #define CAN_CTRLMODE_XL_TDC_MANUAL 0x4000 /* XL TDCV is manually set up by user */ 110 + #define CAN_CTRLMODE_XL_TMS 0x8000 /* Transceiver Mode Switching */ 110 111 111 112 /* 112 113 * CAN device statistics