Commit 7d4a101c authored by Vincent Mailhol's avatar Vincent Mailhol Committed by Marc Kleine-Budde

can: dev: add sanity check in can_set_static_ctrlmode()

Previous patch removed can_priv::ctrlmode_static to replace it with
can_get_static_ctrlmode().

A condition sine qua non for this to work is that the controller
static modes should never be set in can_priv::ctrlmode_supported
(c.f. the comment on can_priv::ctrlmode_supported which states that it
is for "options that can be *modified* by netlink"). Also, this
condition is already correctly fulfilled by all existing drivers
which rely on the ctrlmode_static feature.

Nonetheless, we added an extra safeguard in can_set_static_ctrlmode()
to return an error value and to warn the developer who would be
adventurous enough to set to static a given feature that is already
set to supported.

The drivers which rely on the static controller mode are then updated
to check the return value of can_set_static_ctrlmode().

Link: https://lore.kernel.org/all/20211213160226.56219-3-mailhol.vincent@wanadoo.frSigned-off-by: default avatarVincent Mailhol <mailhol.vincent@wanadoo.fr>
Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parent c9e1d8ed
...@@ -1456,7 +1456,7 @@ static bool m_can_niso_supported(struct m_can_classdev *cdev) ...@@ -1456,7 +1456,7 @@ static bool m_can_niso_supported(struct m_can_classdev *cdev)
static int m_can_dev_setup(struct m_can_classdev *cdev) static int m_can_dev_setup(struct m_can_classdev *cdev)
{ {
struct net_device *dev = cdev->net; struct net_device *dev = cdev->net;
int m_can_version; int m_can_version, err;
m_can_version = m_can_check_core_release(cdev); m_can_version = m_can_check_core_release(cdev);
/* return if unsupported version */ /* return if unsupported version */
...@@ -1486,7 +1486,9 @@ static int m_can_dev_setup(struct m_can_classdev *cdev) ...@@ -1486,7 +1486,9 @@ static int m_can_dev_setup(struct m_can_classdev *cdev)
switch (cdev->version) { switch (cdev->version) {
case 30: case 30:
/* CAN_CTRLMODE_FD_NON_ISO is fixed with M_CAN IP v3.0.x */ /* CAN_CTRLMODE_FD_NON_ISO is fixed with M_CAN IP v3.0.x */
can_set_static_ctrlmode(dev, CAN_CTRLMODE_FD_NON_ISO); err = can_set_static_ctrlmode(dev, CAN_CTRLMODE_FD_NON_ISO);
if (err)
return err;
cdev->can.bittiming_const = cdev->bit_timing ? cdev->can.bittiming_const = cdev->bit_timing ?
cdev->bit_timing : &m_can_bittiming_const_30X; cdev->bit_timing : &m_can_bittiming_const_30X;
...@@ -1496,7 +1498,9 @@ static int m_can_dev_setup(struct m_can_classdev *cdev) ...@@ -1496,7 +1498,9 @@ static int m_can_dev_setup(struct m_can_classdev *cdev)
break; break;
case 31: case 31:
/* CAN_CTRLMODE_FD_NON_ISO is fixed with M_CAN IP v3.1.x */ /* CAN_CTRLMODE_FD_NON_ISO is fixed with M_CAN IP v3.1.x */
can_set_static_ctrlmode(dev, CAN_CTRLMODE_FD_NON_ISO); err = can_set_static_ctrlmode(dev, CAN_CTRLMODE_FD_NON_ISO);
if (err)
return err;
cdev->can.bittiming_const = cdev->bit_timing ? cdev->can.bittiming_const = cdev->bit_timing ?
cdev->bit_timing : &m_can_bittiming_const_31X; cdev->bit_timing : &m_can_bittiming_const_31X;
......
...@@ -1699,7 +1699,9 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch, ...@@ -1699,7 +1699,9 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
&rcar_canfd_data_bittiming_const; &rcar_canfd_data_bittiming_const;
/* Controller starts in CAN FD only mode */ /* Controller starts in CAN FD only mode */
can_set_static_ctrlmode(ndev, CAN_CTRLMODE_FD); err = can_set_static_ctrlmode(ndev, CAN_CTRLMODE_FD);
if (err)
goto fail;
priv->can.ctrlmode_supported = CAN_CTRLMODE_BERR_REPORTING; priv->can.ctrlmode_supported = CAN_CTRLMODE_BERR_REPORTING;
} else { } else {
/* Controller starts in Classical CAN only mode */ /* Controller starts in Classical CAN only mode */
......
...@@ -131,17 +131,24 @@ static inline s32 can_get_relative_tdco(const struct can_priv *priv) ...@@ -131,17 +131,24 @@ static inline s32 can_get_relative_tdco(const struct can_priv *priv)
} }
/* helper to define static CAN controller features at device creation time */ /* helper to define static CAN controller features at device creation time */
static inline void can_set_static_ctrlmode(struct net_device *dev, static inline int __must_check can_set_static_ctrlmode(struct net_device *dev,
u32 static_mode) u32 static_mode)
{ {
struct can_priv *priv = netdev_priv(dev); struct can_priv *priv = netdev_priv(dev);
/* alloc_candev() succeeded => netdev_priv() is valid at this point */ /* alloc_candev() succeeded => netdev_priv() is valid at this point */
if (priv->ctrlmode_supported & static_mode) {
netdev_warn(dev,
"Controller features can not be supported and static at the same time\n");
return -EINVAL;
}
priv->ctrlmode = static_mode; priv->ctrlmode = static_mode;
/* override MTU which was set by default in can_setup()? */ /* override MTU which was set by default in can_setup()? */
if (static_mode & CAN_CTRLMODE_FD) if (static_mode & CAN_CTRLMODE_FD)
dev->mtu = CANFD_MTU; dev->mtu = CANFD_MTU;
return 0;
} }
static inline u32 can_get_static_ctrlmode(struct can_priv *priv) static inline u32 can_get_static_ctrlmode(struct can_priv *priv)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment