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_dtb_changelink()

Factorise the databittiming parsing out of can_changelink() and move
it in the new can_dtb_changelink() function. This is a preparation
patch for the introduction of CAN XL because the databittiming
changelink logic will be reused later on.

Signed-off-by: Vincent Mailhol <mailhol@kernel.org>
Link: https://patch.msgid.link/20250923-canxl-netlink-prep-v4-10-e720d28f66fe@kernel.org
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>

authored by

Vincent Mailhol and committed by
Marc Kleine-Budde
2e543af4 530c918f

+88 -64
+88 -64
drivers/net/can/dev/netlink.c
··· 221 221 return 0; 222 222 } 223 223 224 + static int can_dbt_changelink(struct net_device *dev, struct nlattr *data[], 225 + bool fd, struct netlink_ext_ack *extack) 226 + { 227 + struct nlattr *data_bittiming, *data_tdc; 228 + struct can_priv *priv = netdev_priv(dev); 229 + struct data_bittiming_params *dbt_params; 230 + struct can_bittiming dbt; 231 + bool need_tdc_calc = false; 232 + u32 tdc_mask; 233 + int err; 234 + 235 + if (fd) { 236 + data_bittiming = data[IFLA_CAN_DATA_BITTIMING]; 237 + data_tdc = data[IFLA_CAN_TDC]; 238 + dbt_params = &priv->fd; 239 + tdc_mask = CAN_CTRLMODE_FD_TDC_MASK; 240 + } else { 241 + return -EOPNOTSUPP; /* Place holder for CAN XL */ 242 + } 243 + 244 + if (!data_bittiming) 245 + return 0; 246 + 247 + /* Do not allow changing bittiming while running */ 248 + if (dev->flags & IFF_UP) 249 + return -EBUSY; 250 + 251 + /* Calculate bittiming parameters based on data_bittiming_const 252 + * if set, otherwise pass bitrate directly via do_set_bitrate(). 253 + * Bail out if neither is given. 254 + */ 255 + if (!dbt_params->data_bittiming_const && !dbt_params->do_set_data_bittiming && 256 + !dbt_params->data_bitrate_const) 257 + return -EOPNOTSUPP; 258 + 259 + memcpy(&dbt, nla_data(data_bittiming), sizeof(dbt)); 260 + err = can_get_bittiming(dev, &dbt, dbt_params->data_bittiming_const, 261 + dbt_params->data_bitrate_const, 262 + dbt_params->data_bitrate_const_cnt, extack); 263 + if (err) 264 + return err; 265 + 266 + if (priv->bitrate_max && dbt.bitrate > priv->bitrate_max) { 267 + NL_SET_ERR_MSG_FMT(extack, 268 + "CAN data bitrate %u bps surpasses transceiver capabilities of %u bps", 269 + dbt.bitrate, priv->bitrate_max); 270 + return -EINVAL; 271 + } 272 + 273 + memset(&dbt_params->tdc, 0, sizeof(dbt_params->tdc)); 274 + if (data[IFLA_CAN_CTRLMODE]) { 275 + struct can_ctrlmode *cm = nla_data(data[IFLA_CAN_CTRLMODE]); 276 + 277 + need_tdc_calc = !(cm->mask & tdc_mask); 278 + } 279 + if (data_tdc) { 280 + /* TDC parameters are provided: use them */ 281 + err = can_tdc_changelink(dbt_params, data_tdc, extack); 282 + if (err) { 283 + priv->ctrlmode &= ~tdc_mask; 284 + return err; 285 + } 286 + } else if (need_tdc_calc) { 287 + /* Neither of TDC parameters nor TDC flags are provided: 288 + * do calculation 289 + */ 290 + can_calc_tdco(&dbt_params->tdc, dbt_params->tdc_const, &dbt, 291 + &priv->ctrlmode, priv->ctrlmode_supported); 292 + } /* else: both CAN_CTRLMODE_TDC_{AUTO,MANUAL} are explicitly 293 + * turned off. TDC is disabled: do nothing 294 + */ 295 + 296 + memcpy(&dbt_params->data_bittiming, &dbt, sizeof(dbt)); 297 + 298 + if (dbt_params->do_set_data_bittiming) { 299 + /* Finally, set the bit-timing registers */ 300 + err = dbt_params->do_set_data_bittiming(dev); 301 + if (err) 302 + return err; 303 + } 304 + 305 + return 0; 306 + } 307 + 224 308 static int can_changelink(struct net_device *dev, struct nlattr *tb[], 225 309 struct nlattr *data[], 226 310 struct netlink_ext_ack *extack) 227 311 { 228 312 struct can_priv *priv = netdev_priv(dev); 229 - bool fd_tdc_flag_provided = false; 230 313 int err; 231 314 232 315 /* We need synchronization with dev->stop() */ ··· 356 273 } 357 274 358 275 can_set_default_mtu(dev); 359 - 360 - fd_tdc_flag_provided = cm->mask & CAN_CTRLMODE_FD_TDC_MASK; 361 276 } 362 277 363 278 if (data[IFLA_CAN_BITTIMING]) { ··· 428 347 return err; 429 348 } 430 349 431 - if (data[IFLA_CAN_DATA_BITTIMING]) { 432 - struct can_bittiming dbt; 433 - 434 - /* Do not allow changing bittiming while running */ 435 - if (dev->flags & IFF_UP) 436 - return -EBUSY; 437 - 438 - /* Calculate bittiming parameters based on 439 - * data_bittiming_const if set, otherwise pass bitrate 440 - * directly via do_set_bitrate(). Bail out if neither 441 - * is given. 442 - */ 443 - if (!priv->fd.data_bittiming_const && !priv->fd.do_set_data_bittiming && 444 - !priv->fd.data_bitrate_const) 445 - return -EOPNOTSUPP; 446 - 447 - memcpy(&dbt, nla_data(data[IFLA_CAN_DATA_BITTIMING]), 448 - sizeof(dbt)); 449 - err = can_get_bittiming(dev, &dbt, 450 - priv->fd.data_bittiming_const, 451 - priv->fd.data_bitrate_const, 452 - priv->fd.data_bitrate_const_cnt, 453 - extack); 454 - if (err) 455 - return err; 456 - 457 - if (priv->bitrate_max && dbt.bitrate > priv->bitrate_max) { 458 - NL_SET_ERR_MSG_FMT(extack, 459 - "CANFD data bitrate %u bps surpasses transceiver capabilities of %u bps", 460 - dbt.bitrate, priv->bitrate_max); 461 - return -EINVAL; 462 - } 463 - 464 - memset(&priv->fd.tdc, 0, sizeof(priv->fd.tdc)); 465 - if (data[IFLA_CAN_TDC]) { 466 - /* TDC parameters are provided: use them */ 467 - err = can_tdc_changelink(&priv->fd, 468 - data[IFLA_CAN_TDC], extack); 469 - if (err) { 470 - priv->ctrlmode &= ~CAN_CTRLMODE_FD_TDC_MASK; 471 - return err; 472 - } 473 - } else if (!fd_tdc_flag_provided) { 474 - /* Neither of TDC parameters nor TDC flags are 475 - * provided: do calculation 476 - */ 477 - can_calc_tdco(&priv->fd.tdc, priv->fd.tdc_const, &dbt, 478 - &priv->ctrlmode, priv->ctrlmode_supported); 479 - } /* else: both CAN_CTRLMODE_TDC_{AUTO,MANUAL} are explicitly 480 - * turned off. TDC is disabled: do nothing 481 - */ 482 - 483 - memcpy(&priv->fd.data_bittiming, &dbt, sizeof(dbt)); 484 - 485 - if (priv->fd.do_set_data_bittiming) { 486 - /* Finally, set the bit-timing registers */ 487 - err = priv->fd.do_set_data_bittiming(dev); 488 - if (err) 489 - return err; 490 - } 491 - } 350 + /* CAN FD */ 351 + err = can_dbt_changelink(dev, data, true, extack); 352 + if (err) 353 + return err; 492 354 493 355 if (data[IFLA_CAN_TERMINATION]) { 494 356 const u16 termval = nla_get_u16(data[IFLA_CAN_TERMINATION]);