Skip to content

Commit 2e543af

Browse files
vincent-mailholmarckleinebudde
authored andcommitted
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>
1 parent 530c918 commit 2e543af

File tree

1 file changed

+88
-64
lines changed

1 file changed

+88
-64
lines changed

drivers/net/can/dev/netlink.c

Lines changed: 88 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -221,12 +221,95 @@ static int can_tdc_changelink(struct data_bittiming_params *dbt_params,
221221
return 0;
222222
}
223223

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+
224308
static int can_changelink(struct net_device *dev, struct nlattr *tb[],
225309
struct nlattr *data[],
226310
struct netlink_ext_ack *extack)
227311
{
228312
struct can_priv *priv = netdev_priv(dev);
229-
bool fd_tdc_flag_provided = false;
230313
int err;
231314

232315
/* We need synchronization with dev->stop() */
@@ -273,8 +356,6 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[],
273356
}
274357

275358
can_set_default_mtu(dev);
276-
277-
fd_tdc_flag_provided = cm->mask & CAN_CTRLMODE_FD_TDC_MASK;
278359
}
279360

280361
if (data[IFLA_CAN_BITTIMING]) {
@@ -347,67 +428,10 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[],
347428
return err;
348429
}
349430

350-
if (data[IFLA_CAN_DATA_BITTIMING]) {
351-
struct can_bittiming dbt;
352-
353-
/* Do not allow changing bittiming while running */
354-
if (dev->flags & IFF_UP)
355-
return -EBUSY;
356-
357-
/* Calculate bittiming parameters based on
358-
* data_bittiming_const if set, otherwise pass bitrate
359-
* directly via do_set_bitrate(). Bail out if neither
360-
* is given.
361-
*/
362-
if (!priv->fd.data_bittiming_const && !priv->fd.do_set_data_bittiming &&
363-
!priv->fd.data_bitrate_const)
364-
return -EOPNOTSUPP;
365-
366-
memcpy(&dbt, nla_data(data[IFLA_CAN_DATA_BITTIMING]),
367-
sizeof(dbt));
368-
err = can_get_bittiming(dev, &dbt,
369-
priv->fd.data_bittiming_const,
370-
priv->fd.data_bitrate_const,
371-
priv->fd.data_bitrate_const_cnt,
372-
extack);
373-
if (err)
374-
return err;
375-
376-
if (priv->bitrate_max && dbt.bitrate > priv->bitrate_max) {
377-
NL_SET_ERR_MSG_FMT(extack,
378-
"CANFD data bitrate %u bps surpasses transceiver capabilities of %u bps",
379-
dbt.bitrate, priv->bitrate_max);
380-
return -EINVAL;
381-
}
382-
383-
memset(&priv->fd.tdc, 0, sizeof(priv->fd.tdc));
384-
if (data[IFLA_CAN_TDC]) {
385-
/* TDC parameters are provided: use them */
386-
err = can_tdc_changelink(&priv->fd,
387-
data[IFLA_CAN_TDC], extack);
388-
if (err) {
389-
priv->ctrlmode &= ~CAN_CTRLMODE_FD_TDC_MASK;
390-
return err;
391-
}
392-
} else if (!fd_tdc_flag_provided) {
393-
/* Neither of TDC parameters nor TDC flags are
394-
* provided: do calculation
395-
*/
396-
can_calc_tdco(&priv->fd.tdc, priv->fd.tdc_const, &dbt,
397-
&priv->ctrlmode, priv->ctrlmode_supported);
398-
} /* else: both CAN_CTRLMODE_TDC_{AUTO,MANUAL} are explicitly
399-
* turned off. TDC is disabled: do nothing
400-
*/
401-
402-
memcpy(&priv->fd.data_bittiming, &dbt, sizeof(dbt));
403-
404-
if (priv->fd.do_set_data_bittiming) {
405-
/* Finally, set the bit-timing registers */
406-
err = priv->fd.do_set_data_bittiming(dev);
407-
if (err)
408-
return err;
409-
}
410-
}
431+
/* CAN FD */
432+
err = can_dbt_changelink(dev, data, true, extack);
433+
if (err)
434+
return err;
411435

412436
if (data[IFLA_CAN_TERMINATION]) {
413437
const u16 termval = nla_get_u16(data[IFLA_CAN_TERMINATION]);

0 commit comments

Comments
 (0)