From c3606d438a14faa8319eccb75b9502960a97af16 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Fri, 6 Jan 2017 11:12:41 +0100 Subject: [PATCH] can: dev: can_changelink: allow to set bitrate on devices not providing {data_,}bittiming_const Until commit 08da7da41ea4 can: provide a separate bittiming_const parameter to bittiming functions it was possible to have devices not providing bittiming_const. This can be used for hardware that only support pre-defined fixed bitrates. Although no mainline driver is using this feature so far. This patch re-introduces this feature for the bitrate and the data bitrate (of CANFD controllers). The driver can specify the {data_,}bittiming_const (if the bittiming parameters should be calculated from the bittiming_const) as before or no {data_,}bittiming_const but implement the do_set_{data,}bittiming callback. Acked-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev.c | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index fefe2cd17721..afcf487382c9 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -284,10 +284,6 @@ static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt, { int err; - /* Check if the CAN device has bit-timing parameters */ - if (!btc) - return -EOPNOTSUPP; - /* * Depending on the given can_bittiming parameter structure the CAN * timing parameters are calculated based on the provided bitrate OR @@ -872,10 +868,22 @@ static int can_changelink(struct net_device *dev, /* Do not allow changing bittiming while running */ if (dev->flags & IFF_UP) return -EBUSY; + + /* Calculate bittiming parameters based on + * bittiming_const if set, otherwise pass bitrate + * directly via do_set_bitrate(). Bail out if neither + * is given. + */ + if (!priv->bittiming_const && !priv->do_set_bittiming) + return -EOPNOTSUPP; + memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt)); - err = can_get_bittiming(dev, &bt, priv->bittiming_const); - if (err) - return err; + if (priv->bittiming_const) { + err = can_get_bittiming(dev, &bt, + priv->bittiming_const); + if (err) + return err; + } memcpy(&priv->bittiming, &bt, sizeof(bt)); if (priv->do_set_bittiming) { @@ -943,11 +951,23 @@ static int can_changelink(struct net_device *dev, /* Do not allow changing bittiming while running */ if (dev->flags & IFF_UP) return -EBUSY; + + /* Calculate bittiming parameters based on + * data_bittiming_const if set, otherwise pass bitrate + * directly via do_set_bitrate(). Bail out if neither + * is given. + */ + if (!priv->data_bittiming_const && !priv->do_set_data_bittiming) + return -EOPNOTSUPP; + memcpy(&dbt, nla_data(data[IFLA_CAN_DATA_BITTIMING]), sizeof(dbt)); - err = can_get_bittiming(dev, &dbt, priv->data_bittiming_const); - if (err) - return err; + if (priv->data_bittiming_const) { + err = can_get_bittiming(dev, &dbt, + priv->data_bittiming_const); + if (err) + return err; + } memcpy(&priv->data_bittiming, &dbt, sizeof(dbt)); if (priv->do_set_data_bittiming) { -- 2.20.1