aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/can/slcan.c
diff options
context:
space:
mode:
authorDario Binacchi <dario.binacchi@amarulasolutions.com>2022-06-28 18:31:32 +0200
committerMarc Kleine-Budde <mkl@pengutronix.de>2022-07-03 11:34:41 +0200
commit5bac315be7eb6a7442d390c6b99e7ff5cb61f848 (patch)
treeed00fe909e311748d0e209874c4e3d8017e1c0e0 /drivers/net/can/slcan.c
parentcan: slcan: set bitrate by CAN device driver API (diff)
downloadlinux-dev-5bac315be7eb6a7442d390c6b99e7ff5cb61f848.tar.xz
linux-dev-5bac315be7eb6a7442d390c6b99e7ff5cb61f848.zip
can: slcan: send the open/close commands to the adapter
In case the bitrate has been set via ip tool, this patch changes the driver to send the open ("O\r") and close ("C\r) commands to the adapter. Link: https://lore.kernel.org/all/20220628163137.413025-9-dario.binacchi@amarulasolutions.com Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com> Tested-by: Jeroen Hofstee <jhofstee@victronenergy.com> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to '')
-rw-r--r--drivers/net/can/slcan.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c
index 74033e2d7097..249b5ade06fc 100644
--- a/drivers/net/can/slcan.c
+++ b/drivers/net/can/slcan.c
@@ -435,9 +435,20 @@ static int slcan_transmit_cmd(struct slcan *sl, const unsigned char *cmd)
static int slc_close(struct net_device *dev)
{
struct slcan *sl = netdev_priv(dev);
+ int err;
spin_lock_bh(&sl->lock);
if (sl->tty) {
+ if (sl->can.bittiming.bitrate &&
+ sl->can.bittiming.bitrate != CAN_BITRATE_UNKNOWN) {
+ spin_unlock_bh(&sl->lock);
+ err = slcan_transmit_cmd(sl, "C\r");
+ spin_lock_bh(&sl->lock);
+ if (err)
+ netdev_warn(dev,
+ "failed to send close command 'C\\r'\n");
+ }
+
/* TTY discipline is running. */
clear_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
}
@@ -496,14 +507,23 @@ static int slc_open(struct net_device *dev)
netdev_err(dev,
"failed to send bitrate command 'C\\rS%d\\r'\n",
s);
- close_candev(dev);
- return err;
+ goto cmd_transmit_failed;
+ }
+
+ err = slcan_transmit_cmd(sl, "O\r");
+ if (err) {
+ netdev_err(dev, "failed to send open command 'O\\r'\n");
+ goto cmd_transmit_failed;
}
}
sl->can.state = CAN_STATE_ERROR_ACTIVE;
netif_start_queue(dev);
return 0;
+
+cmd_transmit_failed:
+ close_candev(dev);
+ return err;
}
static void slc_dealloc(struct slcan *sl)