From patchwork Wed Jun 8 16:51:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dario Binacchi X-Patchwork-Id: 2032 Return-Path: X-Original-To: linux-amarula@patchwork.amarulasolutions.com Delivered-To: linux-amarula@patchwork.amarulasolutions.com Received: from mail-ed1-f72.google.com (mail-ed1-f72.google.com [209.85.208.72]) by ganimede.amarulasolutions.com (Postfix) with ESMTPS id 0CE6D3F1F7 for ; Wed, 8 Jun 2022 18:51:31 +0200 (CEST) Received: by mail-ed1-f72.google.com with SMTP id i20-20020a50fd14000000b0042dd305d0f7sf15316356eds.18 for ; Wed, 08 Jun 2022 09:51:31 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1654707090; cv=pass; d=google.com; s=arc-20160816; b=lGqr3cCQg5ArVuchsdocFRCE7uAIwEjZofn4MXqKCXYSRvZ2NUzuTH/jOKTTLeLMUd 6DbsEkPx9AT+ezDaawxrfg8fbObrxrp6XeVCcQ8GU1XIKa1hvO9aur1kLXMMn9iQbf0K tNyG7QDiep4FTt2xjfACt1Lb+1Tyfd1R+o7sbRccf+sp1WQ3SPnvme8ghw7O9r9VDTTf CoZqLfQMW9iNktjrLqJFGtcocmXtUzKeBICn/M8kkyYiZ1E1xOThey2SpKjMUZbTyPtD U3UVfprFYITKm+slaZYbTywHiT0NJQ/ZmYTaifQNyHXM+2EZdFAzcNWLC7pjTOSMOmoM uWpg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe:list-archive:list-help:list-post:list-id :mailing-list:precedence:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=VEO1kbAD6OlbMklH5DCwJ723M4x1NPceIGRug1ouxwc=; b=U+eyeGtmqH5NTAhttl8iZJnBjBWl4N+kmrj4cvUx/jsJ9K0c9Xk5WVPGEncMKMvOw8 aJ4bl5ouES/p846RbhAo1BLrEcwwqLSHdKrseHQj6Kg1jBrYeGJpt40UlTKYqdTvMLOK AijuEryNqa0o72uD4e3C40jX3S0Y+yP1oG0KWJ4PrfX4BLA1/HEV/D1K1HXWRsZwqxwJ knLKnNTdcTEYG8mk37mkR0dBxANirzOp+64kwuCpH8817GltOBmOVbK8s4hfuJCNd3dU 2GXSo9vAMFmUPy2BHnaKP9gHRFxWrMf+LNMOonMJMNdV0hC2mWLyz/gxRydp6tf8XxZN ljIQ== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=e2zOSGbK; spf=pass (google.com: domain of dario.binacchi@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=dario.binacchi@amarulasolutions.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=amarulasolutions.com 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:x-original-sender:x-original-authentication-results :precedence:mailing-list:list-id:list-post:list-help:list-archive :list-unsubscribe; bh=VEO1kbAD6OlbMklH5DCwJ723M4x1NPceIGRug1ouxwc=; b=M+cWE7/RJIM2CGzSK8bPeGInACCP6XMzAeBEooOZ0jqVeTmOWYRPoNWKRJXMp+PA0y gBm4A8tR137zyAQl8dk8Yob03LOTH4kW+M0Mc44J9Xag5TUBnyzOUTPg8kEMheA/fAXp u0mVibHDxWueC0JsikPd85gg8ZEwlHBWyrqeg= 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:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :x-spam-checked-in-group:list-post:list-help:list-archive :list-unsubscribe; bh=VEO1kbAD6OlbMklH5DCwJ723M4x1NPceIGRug1ouxwc=; b=Krnl3qC43DBk3CEAnH511kr9IKhnkih5ifRJYEnJ0As1XzM7LdSW5jX8Vfc1ZqIIUH 8P2qeYUA7E/aV3a4pwSGHJjUFv+9CPgs9h83AdjkVK9hjNeBKddgwMFX72IC9L4olqhJ uUxSb3Es6+jc+RbqZG+zaa6NiFpF0oO1ZnRhungmYrtWmNVch1gt2iR5MN1UKKZCaRrX AXJ+nRs6bBe4Sc4gt7LE2RMy/fVxO3Cqzn6u2A1WeYsyqq1Wh+mY2j4/0njKvUdUWSyZ wBSt+QQuyiGCu9CNJCOYTbveuj1A9+WxvcYN4rBhiNqAxXIFSOzdv4WvuGk+l8uuTa1l NDUQ== X-Gm-Message-State: AOAM5314vP5+vsepE+HnIZajyopFKCpEP89yywJpF1UAEPzS+NMaq3dj EPohtT3rrZEG4/0QQX4BRf1C3+iW X-Google-Smtp-Source: ABdhPJyp6xzI8o4cKBpRvgD8RDYWvFVQlcJF10zsMfOxZ6vfsrugw60lCt212qJ2N1EUciZEbH5ELA== X-Received: by 2002:a17:907:930:b0:711:da36:62f7 with SMTP id au16-20020a170907093000b00711da3662f7mr12023738ejc.468.1654707090811; Wed, 08 Jun 2022 09:51:30 -0700 (PDT) X-BeenThere: linux-amarula@amarulasolutions.com Received: by 2002:a05:6402:5414:b0:431:6a31:654d with SMTP id ev20-20020a056402541400b004316a31654dls189605edb.0.gmail; Wed, 08 Jun 2022 09:51:29 -0700 (PDT) X-Received: by 2002:a05:6402:528f:b0:42a:c778:469e with SMTP id en15-20020a056402528f00b0042ac778469emr39799978edb.404.1654707089684; Wed, 08 Jun 2022 09:51:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1654707089; cv=none; d=google.com; s=arc-20160816; b=UP2NkACMe8Leuz5qEpRargWSHR+O/5Kgt80OBpwHEqBpy6Ek4eTUSMDKe69xsTTb/I noSqjmIHSNpmf2MaOOYV24k+aoPz8WXp3ZRxo41IYVXls16Q5Rhw6bzjfgKf6eWf0Bla Ww2N3EiCFK3K0Jnuo/AOBlsWeH4eSie2BmUHTMjsoX0srUtUXdpH7H3B3HgsaYlOCfgV 0B3zNEazg1MuKWn8rkrfFj6W5bzGS2hrHg+C1Pyi2KmDPx34wKY4rA1UmDyiWxjs6DJf 1meKIPx0j2JnXIRpzqmamZ4djyhfySy4jJF+4Pv3gGCfy4VMttWCwFsnEczP7K8mRx+R YCmA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=c+3GCirlvyznBBrVu6oPXaX+KYWRV3Xhpy2k9G10VWo=; b=Cx5BtvHO/mwR/BPzulJVTqkV/1vxDtf2wc5PEI/6ebpZdSEPoc29xMUJqZN27jVXRw BexxV6WKI+RYz/brXV6QwoX5a3bUE4Ww+kF+XU+bKIqD90A5+ukRBSIUv+yVJbGbTln9 EmgU1L04SYvcGzln0Q5rZmsb1pR6ZSnuK1JXoF+5f2IXBkAjJYUF5Ql3i7t98gh261wR 3cv7pzmLSFXtv/5cYNIIfMZdiUavMclyPltekzlgRNiAEcSjWblZzyBuqeobv18uSUvt YAfwa7E1EaGWh/wWUCetqKwDv+/CUGCL8cLDxQ8eDYTaGKAFn5Qhgt+QSkCrTFRlNZAd ztOQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=e2zOSGbK; spf=pass (google.com: domain of dario.binacchi@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=dario.binacchi@amarulasolutions.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=amarulasolutions.com Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) by mx.google.com with SMTPS id y3-20020a17090614c300b006fe220ad732sor10107832ejc.81.2022.06.08.09.51.29 for (Google Transport Security); Wed, 08 Jun 2022 09:51:29 -0700 (PDT) Received-SPF: pass (google.com: domain of dario.binacchi@amarulasolutions.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; X-Received: by 2002:a17:907:1b25:b0:6da:8206:fc56 with SMTP id mp37-20020a1709071b2500b006da8206fc56mr32386194ejc.81.1654707089355; Wed, 08 Jun 2022 09:51:29 -0700 (PDT) Received: from dario-ThinkPad-T14s-Gen-2i.homenet.telecomitalia.it (host-80-116-90-174.pool80116.interbusiness.it. [80.116.90.174]) by smtp.gmail.com with ESMTPSA id c22-20020a17090654d600b0070587f81bcfsm9569071ejp.19.2022.06.08.09.51.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 Jun 2022 09:51:28 -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: [PATCH v2 04/13] can: slcan: use CAN network device driver API Date: Wed, 8 Jun 2022 18:51:07 +0200 Message-Id: <20220608165116.1575390-5-dario.binacchi@amarulasolutions.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220608165116.1575390-1-dario.binacchi@amarulasolutions.com> References: <20220608165116.1575390-1-dario.binacchi@amarulasolutions.com> MIME-Version: 1.0 X-Original-Sender: dario.binacchi@amarulasolutions.com X-Original-Authentication-Results: mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=e2zOSGbK; spf=pass (google.com: domain of dario.binacchi@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=dario.binacchi@amarulasolutions.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=amarulasolutions.com Content-Type: text/plain; charset="UTF-8" Precedence: list Mailing-list: list linux-amarula@amarulasolutions.com; contact linux-amarula+owners@amarulasolutions.com List-ID: X-Spam-Checked-In-Group: linux-amarula@amarulasolutions.com X-Google-Group-Id: 476853432473 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , As suggested by commit [1], now the driver uses the functions and the data structures provided by the CAN network device driver interface. Currently the driver doesn't implement a way to set bitrate for SLCAN based devices via ip tool, so you'll have to do this by slcand or slcan_attach invocation through the -sX parameter: - slcan_attach -f -s6 -o /dev/ttyACM0 - slcand -f -s8 -o /dev/ttyUSB0 where -s6 in will set adapter's bitrate to 500 Kbit/s and -s8 to 1Mbit/s. See the table below for further CAN bitrates: - s0 -> 10 Kbit/s - s1 -> 20 Kbit/s - s2 -> 50 Kbit/s - s3 -> 100 Kbit/s - s4 -> 125 Kbit/s - s5 -> 250 Kbit/s - s6 -> 500 Kbit/s - s7 -> 800 Kbit/s - s8 -> 1000 Kbit/s In doing so, the struct can_priv::bittiming.bitrate of the driver is not set and since the open_candev() checks that the bitrate has been set, it must be a non-zero value, the bitrate is set to a fake value (-1) before it is called. [1] 39549eef3587f ("can: CAN Network device driver and Netlink interface") Signed-off-by: Dario Binacchi --- Changes in v2: - Move CAN_SLCAN Kconfig option inside CAN_DEV scope. - Improve the commit message. drivers/net/can/Kconfig | 40 +++++++------- drivers/net/can/slcan.c | 112 ++++++++++++++++++++-------------------- 2 files changed, 77 insertions(+), 75 deletions(-) diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index b2dcc1e5a388..45997d39621c 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig @@ -28,26 +28,6 @@ config CAN_VXCAN This driver can also be built as a module. If so, the module will be called vxcan. -config CAN_SLCAN - tristate "Serial / USB serial CAN Adaptors (slcan)" - depends on TTY - help - CAN driver for several 'low cost' CAN interfaces that are attached - via serial lines or via USB-to-serial adapters using the LAWICEL - ASCII protocol. The driver implements the tty linediscipline N_SLCAN. - - As only the sending and receiving of CAN frames is implemented, this - driver should work with the (serial/USB) CAN hardware from: - www.canusb.com / www.can232.com / www.mictronics.de / www.canhack.de - - Userspace tools to attach the SLCAN line discipline (slcan_attach, - slcand) can be found in the can-utils at the linux-can project, see - https://github.com/linux-can/can-utils for details. - - The slcan driver supports up to 10 CAN netdevices by default which - can be changed by the 'maxdev=xx' module option. This driver can - also be built as a module. If so, the module will be called slcan. - config CAN_DEV tristate "Platform CAN drivers with Netlink support" default y @@ -118,6 +98,26 @@ config CAN_KVASER_PCIEFD Kvaser Mini PCI Express HS v2 Kvaser Mini PCI Express 2xHS v2 +config CAN_SLCAN + tristate "Serial / USB serial CAN Adaptors (slcan)" + depends on TTY + help + CAN driver for several 'low cost' CAN interfaces that are attached + via serial lines or via USB-to-serial adapters using the LAWICEL + ASCII protocol. The driver implements the tty linediscipline N_SLCAN. + + As only the sending and receiving of CAN frames is implemented, this + driver should work with the (serial/USB) CAN hardware from: + www.canusb.com / www.can232.com / www.mictronics.de / www.canhack.de + + Userspace tools to attach the SLCAN line discipline (slcan_attach, + slcand) can be found in the can-utils at the linux-can project, see + https://github.com/linux-can/can-utils for details. + + The slcan driver supports up to 10 CAN netdevices by default which + can be changed by the 'maxdev=xx' module option. This driver can + also be built as a module. If so, the module will be called slcan. + config CAN_SUN4I tristate "Allwinner A10 CAN controller" depends on MACH_SUN4I || MACH_SUN7I || COMPILE_TEST diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index 5d87e25e2285..929cb55e08af 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c @@ -56,7 +56,6 @@ #include #include #include -#include MODULE_ALIAS_LDISC(N_SLCAN); MODULE_DESCRIPTION("serial line CAN interface"); @@ -79,6 +78,7 @@ MODULE_PARM_DESC(maxdev, "Maximum number of slcan interfaces"); #define SLC_EFF_ID_LEN 8 struct slcan { + struct can_priv can; int magic; /* Various fields. */ @@ -100,6 +100,7 @@ struct slcan { }; static struct net_device **slcan_devs; +static DEFINE_SPINLOCK(slcan_lock); /************************************************************************ * SLCAN ENCAPSULATION FORMAT * @@ -373,7 +374,7 @@ static netdev_tx_t slc_xmit(struct sk_buff *skb, struct net_device *dev) spin_unlock(&sl->lock); out: - kfree_skb(skb); + can_put_echo_skb(skb, dev, 0, 0); return NETDEV_TX_OK; } @@ -393,6 +394,8 @@ static int slc_close(struct net_device *dev) clear_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags); } netif_stop_queue(dev); + close_candev(dev); + sl->can.state = CAN_STATE_STOPPED; sl->rcount = 0; sl->xleft = 0; spin_unlock_bh(&sl->lock); @@ -404,21 +407,36 @@ static int slc_close(struct net_device *dev) static int slc_open(struct net_device *dev) { struct slcan *sl = netdev_priv(dev); + int err; if (sl->tty == NULL) return -ENODEV; + /* The baud rate is not set with the command + * `ip link set type can bitrate ' and therefore + * can.bittiming.bitrate is 0, causing open_candev() to fail. + * So let's set to a fake value. + */ + sl->can.bittiming.bitrate = -1; + err = open_candev(dev); + if (err) { + netdev_err(dev, "failed to open can device\n"); + return err; + } + + sl->can.state = CAN_STATE_ERROR_ACTIVE; sl->flags &= BIT(SLF_INUSE); netif_start_queue(dev); return 0; } -/* Hook the destructor so we can free slcan devs at the right point in time */ -static void slc_free_netdev(struct net_device *dev) +static void slc_dealloc(struct slcan *sl) { - int i = dev->base_addr; + int i = sl->dev->base_addr; - slcan_devs[i] = NULL; + free_candev(sl->dev); + if (slcan_devs) + slcan_devs[i] = NULL; } static int slcan_change_mtu(struct net_device *dev, int new_mtu) @@ -433,24 +451,6 @@ static const struct net_device_ops slc_netdev_ops = { .ndo_change_mtu = slcan_change_mtu, }; -static void slc_setup(struct net_device *dev) -{ - dev->netdev_ops = &slc_netdev_ops; - dev->needs_free_netdev = true; - dev->priv_destructor = slc_free_netdev; - - dev->hard_header_len = 0; - dev->addr_len = 0; - dev->tx_queue_len = 10; - - dev->mtu = CAN_MTU; - dev->type = ARPHRD_CAN; - - /* New-style flags. */ - dev->flags = IFF_NOARP; - dev->features = NETIF_F_HW_CSUM; -} - /****************************************** Routines looking at TTY side. ******************************************/ @@ -513,11 +513,8 @@ static void slc_sync(void) static struct slcan *slc_alloc(void) { int i; - char name[IFNAMSIZ]; struct net_device *dev = NULL; - struct can_ml_priv *can_ml; struct slcan *sl; - int size; for (i = 0; i < maxdev; i++) { dev = slcan_devs[i]; @@ -530,16 +527,14 @@ static struct slcan *slc_alloc(void) if (i >= maxdev) return NULL; - sprintf(name, "slcan%d", i); - size = ALIGN(sizeof(*sl), NETDEV_ALIGN) + sizeof(struct can_ml_priv); - dev = alloc_netdev(size, name, NET_NAME_UNKNOWN, slc_setup); + dev = alloc_candev(sizeof(*sl), 1); if (!dev) return NULL; + snprintf(dev->name, sizeof(dev->name), "slcan%d", i); + dev->netdev_ops = &slc_netdev_ops; dev->base_addr = i; sl = netdev_priv(dev); - can_ml = (void *)sl + ALIGN(sizeof(*sl), NETDEV_ALIGN); - can_set_ml_priv(dev, can_ml); /* Initialize channel control data */ sl->magic = SLCAN_MAGIC; @@ -572,11 +567,7 @@ static int slcan_open(struct tty_struct *tty) if (tty->ops->write == NULL) return -EOPNOTSUPP; - /* RTnetlink lock is misused here to serialize concurrent - opens of slcan channels. There are better ways, but it is - the simplest one. - */ - rtnl_lock(); + spin_lock(&slcan_lock); /* Collect hanged up channels. */ slc_sync(); @@ -604,13 +595,15 @@ static int slcan_open(struct tty_struct *tty) set_bit(SLF_INUSE, &sl->flags); - err = register_netdevice(sl->dev); - if (err) + err = register_candev(sl->dev); + if (err) { + pr_err("slcan: can't register candev\n"); goto err_free_chan; + } } /* Done. We have linked the TTY line to a channel. */ - rtnl_unlock(); + spin_unlock(&slcan_lock); tty->receive_room = 65536; /* We don't flow control */ /* TTY layer expects 0 on success */ @@ -620,14 +613,10 @@ static int slcan_open(struct tty_struct *tty) sl->tty = NULL; tty->disc_data = NULL; clear_bit(SLF_INUSE, &sl->flags); - slc_free_netdev(sl->dev); - /* do not call free_netdev before rtnl_unlock */ - rtnl_unlock(); - free_netdev(sl->dev); - return err; + slc_dealloc(sl); err_exit: - rtnl_unlock(); + spin_unlock(&slcan_lock); /* Count references from TTY module */ return err; @@ -657,9 +646,11 @@ static void slcan_close(struct tty_struct *tty) synchronize_rcu(); flush_work(&sl->tx_work); - /* Flush network side */ - unregister_netdev(sl->dev); - /* This will complete via sl_free_netdev */ + slc_close(sl->dev); + unregister_candev(sl->dev); + spin_lock(&slcan_lock); + slc_dealloc(sl); + spin_unlock(&slcan_lock); } static void slcan_hangup(struct tty_struct *tty) @@ -767,18 +758,29 @@ static void __exit slcan_exit(void) dev = slcan_devs[i]; if (!dev) continue; - slcan_devs[i] = NULL; - sl = netdev_priv(dev); - if (sl->tty) { - netdev_err(dev, "tty discipline still running\n"); - } + spin_lock(&slcan_lock); + dev = slcan_devs[i]; + if (dev) { + slcan_devs[i] = NULL; + spin_unlock(&slcan_lock); + sl = netdev_priv(dev); + if (sl->tty) { + netdev_err(dev, + "tty discipline still running\n"); + } - unregister_netdev(dev); + slc_close(dev); + unregister_candev(dev); + } else { + spin_unlock(&slcan_lock); + } } + spin_lock(&slcan_lock); kfree(slcan_devs); slcan_devs = NULL; + spin_unlock(&slcan_lock); tty_unregister_ldisc(&slc_ldisc); }