diff options
author | Oliver Hartkopp <socketcan@hartkopp.net> | 2014-02-28 16:36:24 +0100 |
---|---|---|
committer | Marc Kleine-Budde <mkl@pengutronix.de> | 2014-03-07 09:18:23 +0100 |
commit | bc05a8944a344acdb81a65de055ca6febbf9657c (patch) | |
tree | bf3e474f5bac669b5a9d4b3d07aa7119875334fc | |
parent | 9859ccd2c8be63ce939522e63e265f2b0caa1109 (diff) |
can: allow to change the device mtu for CAN FD capable devices
The configuration for CAN FD depends on CAN_CTRLMODE_FD enabled in the driver
specific ctrlmode_supported capabilities.
The configuration can be done either with the 'fd { on | off }' option in the
'ip' tool from iproute2 or by setting the CAN netdevice MTU to CAN_MTU (16) or
to CANFD_MTU (72).
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Acked-by: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
-rw-r--r-- | drivers/net/can/dev.c | 39 | ||||
-rw-r--r-- | include/linux/can/dev.h | 1 | ||||
-rw-r--r-- | include/uapi/linux/can/netlink.h | 1 |
3 files changed, 41 insertions, 0 deletions
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 8ebe112458c4..4e20d82b799e 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -595,6 +595,39 @@ void free_candev(struct net_device *dev) EXPORT_SYMBOL_GPL(free_candev); /* + * changing MTU and control mode for CAN/CANFD devices + */ +int can_change_mtu(struct net_device *dev, int new_mtu) +{ + struct can_priv *priv = netdev_priv(dev); + + /* Do not allow changing the MTU while running */ + if (dev->flags & IFF_UP) + return -EBUSY; + + /* allow change of MTU according to the CANFD ability of the device */ + switch (new_mtu) { + case CAN_MTU: + priv->ctrlmode &= ~CAN_CTRLMODE_FD; + break; + + case CANFD_MTU: + if (!(priv->ctrlmode_supported & CAN_CTRLMODE_FD)) + return -EINVAL; + + priv->ctrlmode |= CAN_CTRLMODE_FD; + break; + + default: + return -EINVAL; + } + + dev->mtu = new_mtu; + return 0; +} +EXPORT_SYMBOL_GPL(can_change_mtu); + +/* * Common open function when the device gets opened. * * This function should be called in the open function of the device @@ -693,6 +726,12 @@ static int can_changelink(struct net_device *dev, return -EOPNOTSUPP; priv->ctrlmode &= ~cm->mask; priv->ctrlmode |= cm->flags; + + /* CAN_CTRLMODE_FD can only be set when driver supports FD */ + if (priv->ctrlmode & CAN_CTRLMODE_FD) + dev->mtu = CANFD_MTU; + else + dev->mtu = CAN_MTU; } if (data[IFLA_CAN_RESTART_MS]) { diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h index 8adaee96f292..3ce5e526525f 100644 --- a/include/linux/can/dev.h +++ b/include/linux/can/dev.h @@ -113,6 +113,7 @@ struct can_priv *safe_candev_priv(struct net_device *dev); int open_candev(struct net_device *dev); void close_candev(struct net_device *dev); +int can_change_mtu(struct net_device *dev, int new_mtu); int register_candev(struct net_device *dev); void unregister_candev(struct net_device *dev); diff --git a/include/uapi/linux/can/netlink.h b/include/uapi/linux/can/netlink.h index b41933d6bdcd..7e2e1863db16 100644 --- a/include/uapi/linux/can/netlink.h +++ b/include/uapi/linux/can/netlink.h @@ -96,6 +96,7 @@ struct can_ctrlmode { #define CAN_CTRLMODE_3_SAMPLES 0x04 /* Triple sampling mode */ #define CAN_CTRLMODE_ONE_SHOT 0x08 /* One-Shot mode */ #define CAN_CTRLMODE_BERR_REPORTING 0x10 /* Bus-error reporting */ +#define CAN_CTRLMODE_FD 0x20 /* CAN FD mode */ /* * CAN device statistics |