diff options
| author | Oliver Hartkopp <socketcan@hartkopp.net> | 2016-03-21 15:18:21 -0400 |
|---|---|---|
| committer | Marc Kleine-Budde <mkl@pengutronix.de> | 2016-05-09 05:07:28 -0400 |
| commit | bb208f144cf3f59d8f89a09a80efd04389718907 (patch) | |
| tree | dbf6d52a61a76aafa28e907d6d419464aa3fba89 /include/linux/can/dev.h | |
| parent | b6fd3aba6041922e115bd8e10539b8545f4120ac (diff) | |
can: fix handling of unmodifiable configuration options
As described in 'can: m_can: tag current CAN FD controllers as non-ISO'
(6cfda7fbebe) it is possible to define fixed configuration options by
setting the according bit in 'ctrlmode' and clear it in 'ctrlmode_supported'.
This leads to the incovenience that the fixed configuration bits can not be
passed by netlink even when they have the correct values (e.g. non-ISO, FD).
This patch fixes that issue and not only allows fixed set bit values to be set
again but now requires(!) to provide these fixed values at configuration time.
A valid CAN FD configuration consists of a nominal/arbitration bittiming, a
data bittiming and a control mode with CAN_CTRLMODE_FD set - which is now
enforced by a new can_validate() function. This fix additionally removed the
inconsistency that was prohibiting the support of 'CANFD-only' controller
drivers, like the RCar CAN FD.
For this reason a new helper can_set_static_ctrlmode() has been introduced to
provide a proper interface to handle static enabled CAN controller options.
Reported-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com>
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Reviewed-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com>
Cc: <stable@vger.kernel.org> # >= 3.18
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'include/linux/can/dev.h')
| -rw-r--r-- | include/linux/can/dev.h | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h index 735f9f8c4e43..5261751f6bd4 100644 --- a/include/linux/can/dev.h +++ b/include/linux/can/dev.h | |||
| @@ -40,8 +40,11 @@ struct can_priv { | |||
| 40 | struct can_clock clock; | 40 | struct can_clock clock; |
| 41 | 41 | ||
| 42 | enum can_state state; | 42 | enum can_state state; |
| 43 | u32 ctrlmode; | 43 | |
| 44 | u32 ctrlmode_supported; | 44 | /* CAN controller features - see include/uapi/linux/can/netlink.h */ |
| 45 | u32 ctrlmode; /* current options setting */ | ||
| 46 | u32 ctrlmode_supported; /* options that can be modified by netlink */ | ||
| 47 | u32 ctrlmode_static; /* static enabled options for driver/hardware */ | ||
| 45 | 48 | ||
| 46 | int restart_ms; | 49 | int restart_ms; |
| 47 | struct timer_list restart_timer; | 50 | struct timer_list restart_timer; |
| @@ -108,6 +111,21 @@ static inline bool can_is_canfd_skb(const struct sk_buff *skb) | |||
| 108 | return skb->len == CANFD_MTU; | 111 | return skb->len == CANFD_MTU; |
| 109 | } | 112 | } |
| 110 | 113 | ||
| 114 | /* helper to define static CAN controller features at device creation time */ | ||
| 115 | static inline void can_set_static_ctrlmode(struct net_device *dev, | ||
| 116 | u32 static_mode) | ||
| 117 | { | ||
| 118 | struct can_priv *priv = netdev_priv(dev); | ||
| 119 | |||
| 120 | /* alloc_candev() succeeded => netdev_priv() is valid at this point */ | ||
| 121 | priv->ctrlmode = static_mode; | ||
| 122 | priv->ctrlmode_static = static_mode; | ||
| 123 | |||
| 124 | /* override MTU which was set by default in can_setup()? */ | ||
| 125 | if (static_mode & CAN_CTRLMODE_FD) | ||
| 126 | dev->mtu = CANFD_MTU; | ||
| 127 | } | ||
| 128 | |||
| 111 | /* get data length from can_dlc with sanitized can_dlc */ | 129 | /* get data length from can_dlc with sanitized can_dlc */ |
| 112 | u8 can_dlc2len(u8 can_dlc); | 130 | u8 can_dlc2len(u8 can_dlc); |
| 113 | 131 | ||
