From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CDF8BC43334 for ; Tue, 7 Jun 2022 09:49:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240056AbiFGJta (ORCPT ); Tue, 7 Jun 2022 05:49:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38470 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240070AbiFGJs0 (ORCPT ); Tue, 7 Jun 2022 05:48:26 -0400 Received: from mail-wr1-x42b.google.com (mail-wr1-x42b.google.com [IPv6:2a00:1450:4864:20::42b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4E37567D02 for ; Tue, 7 Jun 2022 02:48:25 -0700 (PDT) Received: by mail-wr1-x42b.google.com with SMTP id s1so248555wra.9 for ; Tue, 07 Jun 2022 02:48:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amarulasolutions.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=onYK8jf0XQfJNXTnZtrlaJoF/ojpUqhJIjTYy4RWPWI=; b=cRCWGgSNpt2XHDnQgz+KAWufJT5/RKaxCaOCt/Pk3UnqNXK6FJK5dHhsPcDWYOb6aK qyiDAujXzXpICWyNMxy8P6LfD6gMTuv9agCd8AA+B/zKcQ5Oal1TZqRiFhuQ0SXcGhdN LfJlg2lz03oo9CZgNa3SLw70CuWz3vNYOSJMk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=onYK8jf0XQfJNXTnZtrlaJoF/ojpUqhJIjTYy4RWPWI=; b=lDOjmkzh6IKFbwIH+zXALtWKkcu+1oaa5wWg153vB7aJL+PT0prrSwcRajdWs0cw8Z U+SpL5SMQfSuygvfWmhdwqqwzew2rWKtKmHesNJQE0sem43Likxb0RDDYzXWvwxs2P+r 4PRbitgkn9y94HxCIz087TeHc7zsU/jk81QRyWnPMI75VIBc2WayxjmltSicrRincHLf Mx5BKKqhKVRRDuMFoQB+nLAWTqBZd2keSL4UTG9J4UeUslmfcmrozPK1nZKePQj/fLkI gwojxRjq7Wz6J4Cj5xFuoHGJXars+PHb0/xxZQZs4Q3YBIB3wXAxNJYAoryRXp2bk3ZG RMNA== X-Gm-Message-State: AOAM533x83ogtX79XQt0TsF+XZWB6Q6KHpfQZ0CKthqSi1Y+5WE3IzVV +42W7EPiR/dHlOoQqraO5Bq1blooIFqwxQ== X-Google-Smtp-Source: ABdhPJxIChpp14XTvdyXsK+FVN+YIV91/EqReU6KUu7uJ5RbsKEAF1QtA6YosUz9J32Mpe0mDLOLnw== X-Received: by 2002:a5d:4649:0:b0:218:4d6c:3f3f with SMTP id j9-20020a5d4649000000b002184d6c3f3fmr3510839wrs.148.1654595303518; Tue, 07 Jun 2022 02:48:23 -0700 (PDT) Received: from dario-ThinkPad-T14s-Gen-2i.pdxnet.pdxeng.ch (mob-5-90-137-51.net.vodafone.it. [5.90.137.51]) by smtp.gmail.com with ESMTPSA id o4-20020a05600c510400b0039748be12dbsm23200547wms.47.2022.06.07.02.48.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Jun 2022 02:48:23 -0700 (PDT) From: Dario Binacchi To: linux-kernel@vger.kernel.org Cc: Amarula patchwork , michael@amarulasolutions.com, Dario Binacchi , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Marc Kleine-Budde , Paolo Abeni , Wolfgang Grandegger , linux-can@vger.kernel.org, netdev@vger.kernel.org Subject: [RFC PATCH 07/13] can: slcan: set bitrate by CAN device driver API Date: Tue, 7 Jun 2022 11:47:46 +0200 Message-Id: <20220607094752.1029295-8-dario.binacchi@amarulasolutions.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220607094752.1029295-1-dario.binacchi@amarulasolutions.com> References: <20220607094752.1029295-1-dario.binacchi@amarulasolutions.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org It allows to set the bitrate via ip tool, as it happens for the other CAN device drivers. It still remains possible to set the bitrate via slcand or slcan_attach utilities. In case the ip tool is used, the driver will send the serial command to the adapter. The struct can_bittiming_const and struct can_priv::clock.freq has been set with empirical values ​​that allow you to get a correct bit timing, so that the slc_do_set_bittiming() can be called. Signed-off-by: Dario Binacchi --- DTS properties could be used to set the can.clock.freq and the can.bittiming_const variables. This way the parameters could be changed based on the type of the adapter. drivers/net/can/slcan.c | 54 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index dbd4ebdfa024..f1bf32b70c4d 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c @@ -105,6 +105,18 @@ struct slcan { static struct net_device **slcan_devs; static DEFINE_SPINLOCK(slcan_lock); +static const struct can_bittiming_const slcan_bittiming_const = { + .name = KBUILD_MODNAME, + .tseg1_min = 2, + .tseg1_max = 256, + .tseg2_min = 1, + .tseg2_max = 128, + .sjw_max = 128, + .brp_min = 1, + .brp_max = 256, + .brp_inc = 1, +}; + /************************************************************************ * SLCAN ENCAPSULATION FORMAT * ************************************************************************/ @@ -435,6 +447,7 @@ static int slc_close(struct net_device *dev) netif_stop_queue(dev); close_candev(dev); sl->can.state = CAN_STATE_STOPPED; + sl->can.bittiming.bitrate = 0; sl->rcount = 0; sl->xleft = 0; spin_unlock_bh(&sl->lock); @@ -456,7 +469,9 @@ static int slc_open(struct net_device *dev) * can.bittiming.bitrate is 0, causing open_candev() to fail. * So let's set to a fake value. */ - sl->can.bittiming.bitrate = -1; + if (sl->can.bittiming.bitrate == 0) + sl->can.bittiming.bitrate = -1UL; + err = open_candev(dev); if (err) { netdev_err(dev, "failed to open can device\n"); @@ -554,6 +569,40 @@ static void slc_sync(void) } } +static int slc_do_set_bittiming(struct net_device *dev) +{ + struct slcan *sl = netdev_priv(dev); + unsigned char cmd[SLC_MTU]; + int i, s = -1, err; + unsigned int bitrates[] = { + 10000, 20000, 50000, 100000, + 125000, 250000, 500000, 800000, + 1000000, + }; + + for (i = 0; i < ARRAY_SIZE(bitrates); i++) { + if (sl->can.bittiming.bitrate == bitrates[i]) { + s = i; + break; + } + } + + if (s < 0) { + netdev_err(dev, "invalid bitrate\n"); + return -EINVAL; + } + + snprintf(cmd, sizeof(cmd), "C\rS%d\r", s); + err = slcan_transmit_cmd(sl, cmd); + if (err) { + sl->can.bittiming.bitrate = 0; + netdev_err(sl->dev, + "failed to send bitrate command 'C\\rS%d\\r'\n", s); + } + + return err; +} + /* Find a free SLCAN channel, and link in this `tty' line. */ static struct slcan *slc_alloc(void) { @@ -583,6 +632,9 @@ static struct slcan *slc_alloc(void) /* Initialize channel control data */ sl->magic = SLCAN_MAGIC; sl->dev = dev; + sl->can.clock.freq = 24 * 1000 * 1000; + sl->can.bittiming_const = &slcan_bittiming_const; + sl->can.do_set_bittiming = slc_do_set_bittiming; spin_lock_init(&sl->lock); INIT_WORK(&sl->tx_work, slcan_transmit); init_waitqueue_head(&sl->xcmd_wait); -- 2.32.0