diff options
author | Marc Kleine-Budde <mkl@pengutronix.de> | 2017-01-06 11:12:41 +0100 |
---|---|---|
committer | Marc Kleine-Budde <mkl@pengutronix.de> | 2017-01-24 13:52:00 +0100 |
commit | c3606d438a14faa8319eccb75b9502960a97af16 (patch) | |
tree | 04c944edb43845d96e2f66a060f2196299cd4280 /drivers/net/can | |
parent | 12a6075cabc0d9ffbc0366b44daa22f278606312 (diff) | |
download | linux-c3606d438a14faa8319eccb75b9502960a97af16.tar.bz2 |
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 <socketcan@hartkopp.net>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'drivers/net/can')
-rw-r--r-- | drivers/net/can/dev.c | 40 |
1 files 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) { |