@@ -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+
224308static 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