]> git.baikalelectronics.ru Git - kernel.git/commitdiff
can: slcan: send the open/close commands to the adapter
authorDario Binacchi <dario.binacchi@amarulasolutions.com>
Tue, 28 Jun 2022 16:31:32 +0000 (18:31 +0200)
committerMarc Kleine-Budde <mkl@pengutronix.de>
Sun, 3 Jul 2022 09:34:41 +0000 (11:34 +0200)
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>
drivers/net/can/slcan.c

index 74033e2d7097ec8583b47ac59d9d879fe5602f6d..249b5ade06fce2fcf8fffae5a207d595e2ecf7a0 100644 (file)
@@ -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)