From 1010a8fa96086d746251954e709f9fad751b1f0a Mon Sep 17 00:00:00 2001 From: Srinivas Neeli Date: Thu, 9 Jun 2022 16:01:57 +0530 Subject: [PATCH 01/22] can: xilinx_can: add Transmitter Delay Compensation (TDC) feature support This patch adds Transmitter Delay Compensation (TDC) feature support. In the case of higher measured loop delay with higher bit rates, bit stuff errors are observed. Enabling the TDC feature in CAN-FD controllers will compensate for the measured loop delay in the receive path. Link: https://lore.kernel.org/all/20220609103157.1425730-1-srinivas.neeli@xilinx.com Signed-off-by: Srinivas Neeli Reviewed-by: Vincent Mailhol [mkl: fix indention] Signed-off-by: Marc Kleine-Budde --- drivers/net/can/xilinx_can.c | 66 +++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c index 8a3b7b103ca4..70dcb45078bf 100644 --- a/drivers/net/can/xilinx_can.c +++ b/drivers/net/can/xilinx_can.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later /* Xilinx CAN device driver * - * Copyright (C) 2012 - 2014 Xilinx, Inc. + * Copyright (C) 2012 - 2022 Xilinx, Inc. * Copyright (C) 2009 PetaLogix. All rights reserved. * Copyright (C) 2017 - 2018 Sandvik Mining and Construction Oy * @@ -9,6 +9,7 @@ * This driver is developed for Axi CAN IP and for Zynq CANPS Controller. */ +#include #include #include #include @@ -86,6 +87,8 @@ enum xcan_reg { #define XCAN_MSR_LBACK_MASK 0x00000002 /* Loop back mode select */ #define XCAN_MSR_SLEEP_MASK 0x00000001 /* Sleep mode select */ #define XCAN_BRPR_BRP_MASK 0x000000FF /* Baud rate prescaler */ +#define XCAN_BRPR_TDCO_MASK GENMASK(12, 8) /* TDCO */ +#define XCAN_2_BRPR_TDCO_MASK GENMASK(13, 8) /* TDCO for CANFD 2.0 */ #define XCAN_BTR_SJW_MASK 0x00000180 /* Synchronous jump width */ #define XCAN_BTR_TS2_MASK 0x00000070 /* Time segment 2 */ #define XCAN_BTR_TS1_MASK 0x0000000F /* Time segment 1 */ @@ -99,6 +102,7 @@ enum xcan_reg { #define XCAN_ESR_STER_MASK 0x00000004 /* Stuff error */ #define XCAN_ESR_FMER_MASK 0x00000002 /* Form error */ #define XCAN_ESR_CRCER_MASK 0x00000001 /* CRC error */ +#define XCAN_SR_TDCV_MASK GENMASK(22, 16) /* TDCV Value */ #define XCAN_SR_TXFLL_MASK 0x00000400 /* TX FIFO is full */ #define XCAN_SR_ESTAT_MASK 0x00000180 /* Error status */ #define XCAN_SR_ERRWRN_MASK 0x00000040 /* Error warning */ @@ -132,6 +136,7 @@ enum xcan_reg { #define XCAN_DLCR_BRS_MASK 0x04000000 /* BRS Mask in DLC */ /* CAN register bit shift - XCAN___SHIFT */ +#define XCAN_BRPR_TDC_ENABLE BIT(16) /* Transmitter Delay Compensation (TDC) Enable */ #define XCAN_BTR_SJW_SHIFT 7 /* Synchronous jump width */ #define XCAN_BTR_TS2_SHIFT 4 /* Time segment 2 */ #define XCAN_BTR_SJW_SHIFT_CANFD 16 /* Synchronous jump width */ @@ -276,6 +281,26 @@ static const struct can_bittiming_const xcan_data_bittiming_const_canfd2 = { .brp_inc = 1, }; +/* Transmission Delay Compensation constants for CANFD 1.0 */ +static const struct can_tdc_const xcan_tdc_const_canfd = { + .tdcv_min = 0, + .tdcv_max = 0, /* Manual mode not supported. */ + .tdco_min = 0, + .tdco_max = 32, + .tdcf_min = 0, /* Filter window not supported */ + .tdcf_max = 0, +}; + +/* Transmission Delay Compensation constants for CANFD 2.0 */ +static const struct can_tdc_const xcan_tdc_const_canfd2 = { + .tdcv_min = 0, + .tdcv_max = 0, /* Manual mode not supported. */ + .tdco_min = 0, + .tdco_max = 64, + .tdcf_min = 0, /* Filter window not supported */ + .tdcf_max = 0, +}; + /** * xcan_write_reg_le - Write a value to the device register little endian * @priv: Driver private data structure @@ -424,6 +449,14 @@ static int xcan_set_bittiming(struct net_device *ndev) priv->devtype.cantype == XAXI_CANFD_2_0) { /* Setting Baud Rate prescalar value in F_BRPR Register */ btr0 = dbt->brp - 1; + if (can_tdc_is_enabled(&priv->can)) { + if (priv->devtype.cantype == XAXI_CANFD) + btr0 |= FIELD_PREP(XCAN_BRPR_TDCO_MASK, priv->can.tdc.tdco) | + XCAN_BRPR_TDC_ENABLE; + else + btr0 |= FIELD_PREP(XCAN_2_BRPR_TDCO_MASK, priv->can.tdc.tdco) | + XCAN_BRPR_TDC_ENABLE; + } /* Setting Time Segment 1 in BTR Register */ btr1 = dbt->prop_seg + dbt->phase_seg1 - 1; @@ -1483,6 +1516,22 @@ static int xcan_get_berr_counter(const struct net_device *ndev, return 0; } +/** + * xcan_get_auto_tdcv - Get Transmitter Delay Compensation Value + * @ndev: Pointer to net_device structure + * @tdcv: Pointer to TDCV value + * + * Return: 0 on success + */ +static int xcan_get_auto_tdcv(const struct net_device *ndev, u32 *tdcv) +{ + struct xcan_priv *priv = netdev_priv(ndev); + + *tdcv = FIELD_GET(XCAN_SR_TDCV_MASK, priv->read_reg(priv, XCAN_SR_OFFSET)); + + return 0; +} + static const struct net_device_ops xcan_netdev_ops = { .ndo_open = xcan_open, .ndo_stop = xcan_close, @@ -1735,17 +1784,24 @@ static int xcan_probe(struct platform_device *pdev) priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_BERR_REPORTING; - if (devtype->cantype == XAXI_CANFD) + if (devtype->cantype == XAXI_CANFD) { priv->can.data_bittiming_const = &xcan_data_bittiming_const_canfd; + priv->can.tdc_const = &xcan_tdc_const_canfd; + } - if (devtype->cantype == XAXI_CANFD_2_0) + if (devtype->cantype == XAXI_CANFD_2_0) { priv->can.data_bittiming_const = &xcan_data_bittiming_const_canfd2; + priv->can.tdc_const = &xcan_tdc_const_canfd2; + } if (devtype->cantype == XAXI_CANFD || - devtype->cantype == XAXI_CANFD_2_0) - priv->can.ctrlmode_supported |= CAN_CTRLMODE_FD; + devtype->cantype == XAXI_CANFD_2_0) { + priv->can.ctrlmode_supported |= CAN_CTRLMODE_FD | + CAN_CTRLMODE_TDC_AUTO; + priv->can.do_get_auto_tdcv = xcan_get_auto_tdcv; + } priv->reg_base = addr; priv->tx_max = tx_max; From b9b352e12c594bc409afb8f893d2ed3d41ab3e2d Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Thu, 9 Jun 2022 13:10:53 +0200 Subject: [PATCH 02/22] can: xilinx_can: fix typo prescalar -> prescaler This patch fixes the typo prescalar -> prescaler. Link: https://lore.kernel.org/all/20220609111424.3819039-1-mkl@pengutronix.de Reported-by: Vincent MAILHOL Cc: Srinivas Neeli Cc: Appana Durga Kedareswara rao Cc: Naga Sureshkumar Relli Signed-off-by: Marc Kleine-Budde --- drivers/net/can/xilinx_can.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c index 70dcb45078bf..393b2d9f9d2a 100644 --- a/drivers/net/can/xilinx_can.c +++ b/drivers/net/can/xilinx_can.c @@ -51,7 +51,7 @@ enum xcan_reg { /* only on CAN FD cores */ XCAN_F_BRPR_OFFSET = 0x088, /* Data Phase Baud Rate - * Prescalar + * Prescaler */ XCAN_F_BTR_OFFSET = 0x08C, /* Data Phase Bit Timing */ XCAN_TRR_OFFSET = 0x0090, /* TX Buffer Ready Request */ @@ -430,7 +430,7 @@ static int xcan_set_bittiming(struct net_device *ndev) return -EPERM; } - /* Setting Baud Rate prescalar value in BRPR Register */ + /* Setting Baud Rate prescaler value in BRPR Register */ btr0 = (bt->brp - 1); /* Setting Time Segment 1 in BTR Register */ @@ -447,7 +447,7 @@ static int xcan_set_bittiming(struct net_device *ndev) if (priv->devtype.cantype == XAXI_CANFD || priv->devtype.cantype == XAXI_CANFD_2_0) { - /* Setting Baud Rate prescalar value in F_BRPR Register */ + /* Setting Baud Rate prescaler value in F_BRPR Register */ btr0 = dbt->brp - 1; if (can_tdc_is_enabled(&priv->can)) { if (priv->devtype.cantype == XAXI_CANFD) From c38fb531675654f29f039d1b9bdd0c5b7992913e Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Thu, 9 Jun 2022 13:10:53 +0200 Subject: [PATCH 03/22] can: m_can: fix typo prescalar -> prescaler This patch fixes the typo prescalar -> prescaler. Link: https://lore.kernel.org/all/20220610112037.3857192-1-mkl@pengutronix.de Reviewed-by: Chandrasekar Ramakrishnan Signed-off-by: Marc Kleine-Budde --- drivers/net/can/m_can/m_can.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 5d0c82d8b9a9..4f90e17354f2 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -1348,8 +1348,8 @@ static void m_can_chip_config(struct net_device *dev) /* set bittiming params */ m_can_set_bittiming(dev); - /* enable internal timestamp generation, with a prescalar of 16. The - * prescalar is applied to the nominal bit timing + /* enable internal timestamp generation, with a prescaler of 16. The + * prescaler is applied to the nominal bit timing */ m_can_write(cdev, M_CAN_TSCC, FIELD_PREP(TSCC_TCP_MASK, 0xf)); From 7e193a42c37cf40eba8ac5af2d5e8eeb8b9506f9 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sat, 11 Jun 2022 16:20:58 +0200 Subject: [PATCH 04/22] can: netlink: allow configuring of fixed bit rates without need for do_set_bittiming callback Usually CAN devices support configurable bit rates. The limits are defined by struct can_priv::bittiming_const. Another way is to implement the struct can_priv::do_set_bittiming callback. If the bit rate is configured via netlink, the can_changelink() function checks that either can_priv::bittiming_const or struct can_priv::do_set_bittiming is implemented. In commit 431af779256c ("can: dev: add CAN interface API for fixed bitrates") an API for configuring bit rates on CAN interfaces that only support fixed bit rates was added. The supported bit rates are defined by struct can_priv::bitrate_const. However the above mentioned commit forgot to add the struct can_priv::bitrate_const to the check in can_changelink(). In order to avoid to implement a no-op can_priv::do_set_bittiming callback on devices with fixed bit rates, extend the check in can_changelink() accordingly. Link: https://lore.kernel.org/all/20220611144248.3924903-1-mkl@pengutronix.de Fixes: 431af779256c ("can: dev: add CAN interface API for fixed bitrates") Reported-by: Max Staudt Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev/netlink.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/dev/netlink.c b/drivers/net/can/dev/netlink.c index 7633d98e3912..667ddd28fcdc 100644 --- a/drivers/net/can/dev/netlink.c +++ b/drivers/net/can/dev/netlink.c @@ -176,7 +176,8 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[], * directly via do_set_bitrate(). Bail out if neither * is given. */ - if (!priv->bittiming_const && !priv->do_set_bittiming) + if (!priv->bittiming_const && !priv->do_set_bittiming && + !priv->bitrate_const) return -EOPNOTSUPP; memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt)); From df6ad5dd838e0fa543ca28ca6154901fa65a9443 Mon Sep 17 00:00:00 2001 From: Vincent Mailhol Date: Fri, 10 Jun 2022 23:30:03 +0900 Subject: [PATCH 05/22] can: Kconfig: rename config symbol CAN_DEV into CAN_NETLINK In the next patches, the scope of the can-dev module will grow to engloble the software/virtual drivers (slcan, v(x)can). To this extent, release CAN_DEV by renaming it into CAN_NETLINK. The config symbol CAN_DEV will be reused to cover this extended scope. The rationale for the name CAN_NETLINK is that netlink is the predominant feature added here. The current description only mentions platform drivers despite the fact that this symbol is also required by "normal" devices (e.g. USB or PCI) which do not fall under the platform devices category. The description is updated accordingly to fix this gap. Link: https://lore.kernel.org/all/20220610143009.323579-2-mailhol.vincent@wanadoo.fr Signed-off-by: Vincent Mailhol Acked-by: Max Staudt Tested-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- drivers/net/can/Kconfig | 18 +++++++++++------- drivers/net/can/dev/Makefile | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index b2dcc1e5a388..99f189ad35ad 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig @@ -48,15 +48,19 @@ config CAN_SLCAN 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" +config CAN_NETLINK + tristate "CAN device drivers with Netlink support" default y help - Enables the common framework for platform CAN drivers with Netlink - support. This is the standard library for CAN drivers. - If unsure, say Y. + Enables the common framework for CAN device drivers. This is the + standard library and provides features for the Netlink interface such + as bittiming validation, support of CAN error states, device restart + and others. -if CAN_DEV + This is required by all platform and hardware CAN drivers. If you + plan to use such devices or if unsure, say Y. + +if CAN_NETLINK config CAN_CALC_BITTIMING bool "CAN bit-timing calculation" @@ -164,7 +168,7 @@ source "drivers/net/can/softing/Kconfig" source "drivers/net/can/spi/Kconfig" source "drivers/net/can/usb/Kconfig" -endif +endif #CAN_NETLINK config CAN_DEBUG_DEVICES bool "CAN devices debugging messages" diff --git a/drivers/net/can/dev/Makefile b/drivers/net/can/dev/Makefile index af2901db473c..5b4c813c6222 100644 --- a/drivers/net/can/dev/Makefile +++ b/drivers/net/can/dev/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_CAN_DEV) += can-dev.o +obj-$(CONFIG_CAN_NETLINK) += can-dev.o can-dev-y += bittiming.o can-dev-y += dev.o can-dev-y += length.o From 6a5286442fb64a2d512e4059004441e59c786ebc Mon Sep 17 00:00:00 2001 From: Vincent Mailhol Date: Fri, 10 Jun 2022 23:30:04 +0900 Subject: [PATCH 06/22] can: Kconfig: turn menu "CAN Device Drivers" into a menuconfig using CAN_DEV In the next patches, the software/virtual drivers (slcan, v(x)can) will depend on drivers/net/can/dev/skb.o. This patch changes the scope of the can-dev module to include the above mentioned drivers. To do so, we reuse the menu "CAN Device Drivers" and turn it into a configmenu using the config symbol CAN_DEV (which we released in previous patch). Also, add a description to this new CAN_DEV menuconfig. The symbol CAN_DEV now only triggers the build of skb.o. For this reasons, all the macros from linux/module.h are deported from drivers/net/can/dev/dev.c to drivers/net/can/dev/skb.c. Finally, drivers/net/can/dev/Makefile is adjusted accordingly. Link: https://lore.kernel.org/all/20220610143009.323579-3-mailhol.vincent@wanadoo.fr Suggested-by: Oliver Hartkopp Signed-off-by: Vincent Mailhol Acked-by: Max Staudt Tested-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- drivers/net/can/Kconfig | 29 ++++++++++++++++++++++++++--- drivers/net/can/dev/Makefile | 16 +++++++++------- drivers/net/can/dev/dev.c | 9 +-------- drivers/net/can/dev/skb.c | 7 +++++++ 4 files changed, 43 insertions(+), 18 deletions(-) diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index 99f189ad35ad..3c692af16676 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig @@ -1,5 +1,25 @@ # SPDX-License-Identifier: GPL-2.0-only -menu "CAN Device Drivers" + +menuconfig CAN_DEV + tristate "CAN Device Drivers" + default y + help + Controller Area Network (CAN) is serial communications protocol up to + 1Mbit/s for its original release (now known as Classical CAN) and up + to 8Mbit/s for the more recent CAN with Flexible Data-Rate + (CAN-FD). The CAN bus was originally mainly for automotive, but is now + widely used in marine (NMEA2000), industrial, and medical + applications. More information on the CAN network protocol family + PF_CAN is contained in . + + This section contains all the CAN(-FD) device drivers including the + virtual ones. If you own such devices or plan to use the virtual CAN + interfaces to develop applications, say Y here. + + To compile as a module, choose M here: the module will be called + can-dev. + +if CAN_DEV config CAN_VCAN tristate "Virtual Local CAN Interface (vcan)" @@ -49,7 +69,7 @@ config CAN_SLCAN also be built as a module. If so, the module will be called slcan. config CAN_NETLINK - tristate "CAN device drivers with Netlink support" + bool "CAN device drivers with Netlink support" default y help Enables the common framework for CAN device drivers. This is the @@ -57,6 +77,9 @@ config CAN_NETLINK as bittiming validation, support of CAN error states, device restart and others. + The additional features selected by this option will be added to the + can-dev module. + This is required by all platform and hardware CAN drivers. If you plan to use such devices or if unsure, say Y. @@ -178,4 +201,4 @@ config CAN_DEBUG_DEVICES a problem with CAN support and want to see more of what is going on. -endmenu +endif #CAN_DEV diff --git a/drivers/net/can/dev/Makefile b/drivers/net/can/dev/Makefile index 5b4c813c6222..1baaf7020f7c 100644 --- a/drivers/net/can/dev/Makefile +++ b/drivers/net/can/dev/Makefile @@ -1,9 +1,11 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_CAN_NETLINK) += can-dev.o -can-dev-y += bittiming.o -can-dev-y += dev.o -can-dev-y += length.o -can-dev-y += netlink.o -can-dev-y += rx-offload.o -can-dev-y += skb.o +obj-$(CONFIG_CAN_DEV) += can-dev.o + +can-dev-y += skb.o + +can-dev-$(CONFIG_CAN_NETLINK) += bittiming.o +can-dev-$(CONFIG_CAN_NETLINK) += dev.o +can-dev-$(CONFIG_CAN_NETLINK) += length.o +can-dev-$(CONFIG_CAN_NETLINK) += netlink.o +can-dev-$(CONFIG_CAN_NETLINK) += rx-offload.o diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c index 96c9d9db00cf..523eaacfe29e 100644 --- a/drivers/net/can/dev/dev.c +++ b/drivers/net/can/dev/dev.c @@ -4,7 +4,6 @@ * Copyright (C) 2008-2009 Wolfgang Grandegger */ -#include #include #include #include @@ -17,12 +16,6 @@ #include #include -#define MOD_DESC "CAN device driver interface" - -MODULE_DESCRIPTION(MOD_DESC); -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Wolfgang Grandegger "); - static void can_update_state_error_stats(struct net_device *dev, enum can_state new_state) { @@ -513,7 +506,7 @@ static __init int can_dev_init(void) err = can_netlink_register(); if (!err) - pr_info(MOD_DESC "\n"); + pr_info("CAN device driver interface\n"); return err; } diff --git a/drivers/net/can/dev/skb.c b/drivers/net/can/dev/skb.c index 61660248c69e..a4208f125b76 100644 --- a/drivers/net/can/dev/skb.c +++ b/drivers/net/can/dev/skb.c @@ -5,6 +5,13 @@ */ #include +#include + +#define MOD_DESC "CAN device driver interface" + +MODULE_DESCRIPTION(MOD_DESC); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Wolfgang Grandegger "); /* Local echo of CAN messages * From 0c7e115138830af77d480ee9185bbdc23c6e73a4 Mon Sep 17 00:00:00 2001 From: Vincent Mailhol Date: Fri, 10 Jun 2022 23:30:05 +0900 Subject: [PATCH 07/22] can: bittiming: move bittiming calculation functions to calc_bittiming.c The canonical way to select or deselect an object during compilation is to use this pattern in the relevant Makefile: bar-$(CONFIG_FOO) := foo.o bittiming.c instead uses some #ifdef CONFIG_CAN_CALC_BITTIMG. Create a new file named calc_bittiming.c with all the functions which are conditionally compiled with CONFIG_CAN_CALC_BITTIMG and modify the Makefile according to above pattern. Link: https://lore.kernel.org/all/20220610143009.323579-4-mailhol.vincent@wanadoo.fr Signed-off-by: Vincent Mailhol Acked-by: Max Staudt Tested-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- drivers/net/can/Kconfig | 4 + drivers/net/can/dev/Makefile | 1 + drivers/net/can/dev/bittiming.c | 197 -------------------------- drivers/net/can/dev/calc_bittiming.c | 202 +++++++++++++++++++++++++++ 4 files changed, 207 insertions(+), 197 deletions(-) create mode 100644 drivers/net/can/dev/calc_bittiming.c diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index 3c692af16676..87470feae6b1 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig @@ -96,6 +96,10 @@ config CAN_CALC_BITTIMING source clock frequencies. Disabling saves some space, but then the bit-timing parameters must be specified directly using the Netlink arguments "tq", "prop_seg", "phase_seg1", "phase_seg2" and "sjw". + + The additional features selected by this option will be added to the + can-dev module. + If unsure, say Y. config CAN_AT91 diff --git a/drivers/net/can/dev/Makefile b/drivers/net/can/dev/Makefile index 1baaf7020f7c..791e6b297ea3 100644 --- a/drivers/net/can/dev/Makefile +++ b/drivers/net/can/dev/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_CAN_DEV) += can-dev.o can-dev-y += skb.o +can-dev-$(CONFIG_CAN_CALC_BITTIMING) += calc_bittiming.o can-dev-$(CONFIG_CAN_NETLINK) += bittiming.o can-dev-$(CONFIG_CAN_NETLINK) += dev.o can-dev-$(CONFIG_CAN_NETLINK) += length.o diff --git a/drivers/net/can/dev/bittiming.c b/drivers/net/can/dev/bittiming.c index c1e76f0a5064..7ae80763c960 100644 --- a/drivers/net/can/dev/bittiming.c +++ b/drivers/net/can/dev/bittiming.c @@ -4,205 +4,8 @@ * Copyright (C) 2008-2009 Wolfgang Grandegger */ -#include #include -#ifdef CONFIG_CAN_CALC_BITTIMING -#define CAN_CALC_MAX_ERROR 50 /* in one-tenth of a percent */ - -/* Bit-timing calculation derived from: - * - * Code based on LinCAN sources and H8S2638 project - * Copyright 2004-2006 Pavel Pisa - DCE FELK CVUT cz - * Copyright 2005 Stanislav Marek - * email: pisa@cmp.felk.cvut.cz - * - * Calculates proper bit-timing parameters for a specified bit-rate - * and sample-point, which can then be used to set the bit-timing - * registers of the CAN controller. You can find more information - * in the header file linux/can/netlink.h. - */ -static int -can_update_sample_point(const struct can_bittiming_const *btc, - const unsigned int sample_point_nominal, const unsigned int tseg, - unsigned int *tseg1_ptr, unsigned int *tseg2_ptr, - unsigned int *sample_point_error_ptr) -{ - unsigned int sample_point_error, best_sample_point_error = UINT_MAX; - unsigned int sample_point, best_sample_point = 0; - unsigned int tseg1, tseg2; - int i; - - for (i = 0; i <= 1; i++) { - tseg2 = tseg + CAN_SYNC_SEG - - (sample_point_nominal * (tseg + CAN_SYNC_SEG)) / - 1000 - i; - tseg2 = clamp(tseg2, btc->tseg2_min, btc->tseg2_max); - tseg1 = tseg - tseg2; - if (tseg1 > btc->tseg1_max) { - tseg1 = btc->tseg1_max; - tseg2 = tseg - tseg1; - } - - sample_point = 1000 * (tseg + CAN_SYNC_SEG - tseg2) / - (tseg + CAN_SYNC_SEG); - sample_point_error = abs(sample_point_nominal - sample_point); - - if (sample_point <= sample_point_nominal && - sample_point_error < best_sample_point_error) { - best_sample_point = sample_point; - best_sample_point_error = sample_point_error; - *tseg1_ptr = tseg1; - *tseg2_ptr = tseg2; - } - } - - if (sample_point_error_ptr) - *sample_point_error_ptr = best_sample_point_error; - - return best_sample_point; -} - -int can_calc_bittiming(const struct net_device *dev, struct can_bittiming *bt, - const struct can_bittiming_const *btc) -{ - struct can_priv *priv = netdev_priv(dev); - unsigned int bitrate; /* current bitrate */ - unsigned int bitrate_error; /* difference between current and nominal value */ - unsigned int best_bitrate_error = UINT_MAX; - unsigned int sample_point_error; /* difference between current and nominal value */ - unsigned int best_sample_point_error = UINT_MAX; - unsigned int sample_point_nominal; /* nominal sample point */ - unsigned int best_tseg = 0; /* current best value for tseg */ - unsigned int best_brp = 0; /* current best value for brp */ - unsigned int brp, tsegall, tseg, tseg1 = 0, tseg2 = 0; - u64 v64; - - /* Use CiA recommended sample points */ - if (bt->sample_point) { - sample_point_nominal = bt->sample_point; - } else { - if (bt->bitrate > 800 * KILO /* BPS */) - sample_point_nominal = 750; - else if (bt->bitrate > 500 * KILO /* BPS */) - sample_point_nominal = 800; - else - sample_point_nominal = 875; - } - - /* tseg even = round down, odd = round up */ - for (tseg = (btc->tseg1_max + btc->tseg2_max) * 2 + 1; - tseg >= (btc->tseg1_min + btc->tseg2_min) * 2; tseg--) { - tsegall = CAN_SYNC_SEG + tseg / 2; - - /* Compute all possible tseg choices (tseg=tseg1+tseg2) */ - brp = priv->clock.freq / (tsegall * bt->bitrate) + tseg % 2; - - /* choose brp step which is possible in system */ - brp = (brp / btc->brp_inc) * btc->brp_inc; - if (brp < btc->brp_min || brp > btc->brp_max) - continue; - - bitrate = priv->clock.freq / (brp * tsegall); - bitrate_error = abs(bt->bitrate - bitrate); - - /* tseg brp biterror */ - if (bitrate_error > best_bitrate_error) - continue; - - /* reset sample point error if we have a better bitrate */ - if (bitrate_error < best_bitrate_error) - best_sample_point_error = UINT_MAX; - - can_update_sample_point(btc, sample_point_nominal, tseg / 2, - &tseg1, &tseg2, &sample_point_error); - if (sample_point_error >= best_sample_point_error) - continue; - - best_sample_point_error = sample_point_error; - best_bitrate_error = bitrate_error; - best_tseg = tseg / 2; - best_brp = brp; - - if (bitrate_error == 0 && sample_point_error == 0) - break; - } - - if (best_bitrate_error) { - /* Error in one-tenth of a percent */ - v64 = (u64)best_bitrate_error * 1000; - do_div(v64, bt->bitrate); - bitrate_error = (u32)v64; - if (bitrate_error > CAN_CALC_MAX_ERROR) { - netdev_err(dev, - "bitrate error %d.%d%% too high\n", - bitrate_error / 10, bitrate_error % 10); - return -EDOM; - } - netdev_warn(dev, "bitrate error %d.%d%%\n", - bitrate_error / 10, bitrate_error % 10); - } - - /* real sample point */ - bt->sample_point = can_update_sample_point(btc, sample_point_nominal, - best_tseg, &tseg1, &tseg2, - NULL); - - v64 = (u64)best_brp * 1000 * 1000 * 1000; - do_div(v64, priv->clock.freq); - bt->tq = (u32)v64; - bt->prop_seg = tseg1 / 2; - bt->phase_seg1 = tseg1 - bt->prop_seg; - bt->phase_seg2 = tseg2; - - /* check for sjw user settings */ - if (!bt->sjw || !btc->sjw_max) { - bt->sjw = 1; - } else { - /* bt->sjw is at least 1 -> sanitize upper bound to sjw_max */ - if (bt->sjw > btc->sjw_max) - bt->sjw = btc->sjw_max; - /* bt->sjw must not be higher than tseg2 */ - if (tseg2 < bt->sjw) - bt->sjw = tseg2; - } - - bt->brp = best_brp; - - /* real bitrate */ - bt->bitrate = priv->clock.freq / - (bt->brp * (CAN_SYNC_SEG + tseg1 + tseg2)); - - return 0; -} - -void can_calc_tdco(struct can_tdc *tdc, const struct can_tdc_const *tdc_const, - const struct can_bittiming *dbt, - u32 *ctrlmode, u32 ctrlmode_supported) - -{ - if (!tdc_const || !(ctrlmode_supported & CAN_CTRLMODE_TDC_AUTO)) - return; - - *ctrlmode &= ~CAN_CTRLMODE_TDC_MASK; - - /* As specified in ISO 11898-1 section 11.3.3 "Transmitter - * delay compensation" (TDC) is only applicable if data BRP is - * one or two. - */ - if (dbt->brp == 1 || dbt->brp == 2) { - /* Sample point in clock periods */ - u32 sample_point_in_tc = (CAN_SYNC_SEG + dbt->prop_seg + - dbt->phase_seg1) * dbt->brp; - - if (sample_point_in_tc < tdc_const->tdco_min) - return; - tdc->tdco = min(sample_point_in_tc, tdc_const->tdco_max); - *ctrlmode |= CAN_CTRLMODE_TDC_AUTO; - } -} -#endif /* CONFIG_CAN_CALC_BITTIMING */ - /* Checks the validity of the specified bit-timing parameters prop_seg, * phase_seg1, phase_seg2 and sjw and tries to determine the bitrate * prescaler value brp. You can find more information in the header diff --git a/drivers/net/can/dev/calc_bittiming.c b/drivers/net/can/dev/calc_bittiming.c new file mode 100644 index 000000000000..d3caa040614d --- /dev/null +++ b/drivers/net/can/dev/calc_bittiming.c @@ -0,0 +1,202 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright (C) 2005 Marc Kleine-Budde, Pengutronix + * Copyright (C) 2006 Andrey Volkov, Varma Electronics + * Copyright (C) 2008-2009 Wolfgang Grandegger + */ + +#include +#include + +#define CAN_CALC_MAX_ERROR 50 /* in one-tenth of a percent */ + +/* Bit-timing calculation derived from: + * + * Code based on LinCAN sources and H8S2638 project + * Copyright 2004-2006 Pavel Pisa - DCE FELK CVUT cz + * Copyright 2005 Stanislav Marek + * email: pisa@cmp.felk.cvut.cz + * + * Calculates proper bit-timing parameters for a specified bit-rate + * and sample-point, which can then be used to set the bit-timing + * registers of the CAN controller. You can find more information + * in the header file linux/can/netlink.h. + */ +static int +can_update_sample_point(const struct can_bittiming_const *btc, + const unsigned int sample_point_nominal, const unsigned int tseg, + unsigned int *tseg1_ptr, unsigned int *tseg2_ptr, + unsigned int *sample_point_error_ptr) +{ + unsigned int sample_point_error, best_sample_point_error = UINT_MAX; + unsigned int sample_point, best_sample_point = 0; + unsigned int tseg1, tseg2; + int i; + + for (i = 0; i <= 1; i++) { + tseg2 = tseg + CAN_SYNC_SEG - + (sample_point_nominal * (tseg + CAN_SYNC_SEG)) / + 1000 - i; + tseg2 = clamp(tseg2, btc->tseg2_min, btc->tseg2_max); + tseg1 = tseg - tseg2; + if (tseg1 > btc->tseg1_max) { + tseg1 = btc->tseg1_max; + tseg2 = tseg - tseg1; + } + + sample_point = 1000 * (tseg + CAN_SYNC_SEG - tseg2) / + (tseg + CAN_SYNC_SEG); + sample_point_error = abs(sample_point_nominal - sample_point); + + if (sample_point <= sample_point_nominal && + sample_point_error < best_sample_point_error) { + best_sample_point = sample_point; + best_sample_point_error = sample_point_error; + *tseg1_ptr = tseg1; + *tseg2_ptr = tseg2; + } + } + + if (sample_point_error_ptr) + *sample_point_error_ptr = best_sample_point_error; + + return best_sample_point; +} + +int can_calc_bittiming(const struct net_device *dev, struct can_bittiming *bt, + const struct can_bittiming_const *btc) +{ + struct can_priv *priv = netdev_priv(dev); + unsigned int bitrate; /* current bitrate */ + unsigned int bitrate_error; /* difference between current and nominal value */ + unsigned int best_bitrate_error = UINT_MAX; + unsigned int sample_point_error; /* difference between current and nominal value */ + unsigned int best_sample_point_error = UINT_MAX; + unsigned int sample_point_nominal; /* nominal sample point */ + unsigned int best_tseg = 0; /* current best value for tseg */ + unsigned int best_brp = 0; /* current best value for brp */ + unsigned int brp, tsegall, tseg, tseg1 = 0, tseg2 = 0; + u64 v64; + + /* Use CiA recommended sample points */ + if (bt->sample_point) { + sample_point_nominal = bt->sample_point; + } else { + if (bt->bitrate > 800 * KILO /* BPS */) + sample_point_nominal = 750; + else if (bt->bitrate > 500 * KILO /* BPS */) + sample_point_nominal = 800; + else + sample_point_nominal = 875; + } + + /* tseg even = round down, odd = round up */ + for (tseg = (btc->tseg1_max + btc->tseg2_max) * 2 + 1; + tseg >= (btc->tseg1_min + btc->tseg2_min) * 2; tseg--) { + tsegall = CAN_SYNC_SEG + tseg / 2; + + /* Compute all possible tseg choices (tseg=tseg1+tseg2) */ + brp = priv->clock.freq / (tsegall * bt->bitrate) + tseg % 2; + + /* choose brp step which is possible in system */ + brp = (brp / btc->brp_inc) * btc->brp_inc; + if (brp < btc->brp_min || brp > btc->brp_max) + continue; + + bitrate = priv->clock.freq / (brp * tsegall); + bitrate_error = abs(bt->bitrate - bitrate); + + /* tseg brp biterror */ + if (bitrate_error > best_bitrate_error) + continue; + + /* reset sample point error if we have a better bitrate */ + if (bitrate_error < best_bitrate_error) + best_sample_point_error = UINT_MAX; + + can_update_sample_point(btc, sample_point_nominal, tseg / 2, + &tseg1, &tseg2, &sample_point_error); + if (sample_point_error >= best_sample_point_error) + continue; + + best_sample_point_error = sample_point_error; + best_bitrate_error = bitrate_error; + best_tseg = tseg / 2; + best_brp = brp; + + if (bitrate_error == 0 && sample_point_error == 0) + break; + } + + if (best_bitrate_error) { + /* Error in one-tenth of a percent */ + v64 = (u64)best_bitrate_error * 1000; + do_div(v64, bt->bitrate); + bitrate_error = (u32)v64; + if (bitrate_error > CAN_CALC_MAX_ERROR) { + netdev_err(dev, + "bitrate error %d.%d%% too high\n", + bitrate_error / 10, bitrate_error % 10); + return -EDOM; + } + netdev_warn(dev, "bitrate error %d.%d%%\n", + bitrate_error / 10, bitrate_error % 10); + } + + /* real sample point */ + bt->sample_point = can_update_sample_point(btc, sample_point_nominal, + best_tseg, &tseg1, &tseg2, + NULL); + + v64 = (u64)best_brp * 1000 * 1000 * 1000; + do_div(v64, priv->clock.freq); + bt->tq = (u32)v64; + bt->prop_seg = tseg1 / 2; + bt->phase_seg1 = tseg1 - bt->prop_seg; + bt->phase_seg2 = tseg2; + + /* check for sjw user settings */ + if (!bt->sjw || !btc->sjw_max) { + bt->sjw = 1; + } else { + /* bt->sjw is at least 1 -> sanitize upper bound to sjw_max */ + if (bt->sjw > btc->sjw_max) + bt->sjw = btc->sjw_max; + /* bt->sjw must not be higher than tseg2 */ + if (tseg2 < bt->sjw) + bt->sjw = tseg2; + } + + bt->brp = best_brp; + + /* real bitrate */ + bt->bitrate = priv->clock.freq / + (bt->brp * (CAN_SYNC_SEG + tseg1 + tseg2)); + + return 0; +} + +void can_calc_tdco(struct can_tdc *tdc, const struct can_tdc_const *tdc_const, + const struct can_bittiming *dbt, + u32 *ctrlmode, u32 ctrlmode_supported) + +{ + if (!tdc_const || !(ctrlmode_supported & CAN_CTRLMODE_TDC_AUTO)) + return; + + *ctrlmode &= ~CAN_CTRLMODE_TDC_MASK; + + /* As specified in ISO 11898-1 section 11.3.3 "Transmitter + * delay compensation" (TDC) is only applicable if data BRP is + * one or two. + */ + if (dbt->brp == 1 || dbt->brp == 2) { + /* Sample point in clock periods */ + u32 sample_point_in_tc = (CAN_SYNC_SEG + dbt->prop_seg + + dbt->phase_seg1) * dbt->brp; + + if (sample_point_in_tc < tdc_const->tdco_min) + return; + tdc->tdco = min(sample_point_in_tc, tdc_const->tdco_max); + *ctrlmode |= CAN_CTRLMODE_TDC_AUTO; + } +} From bfe0092dc237963b035d8404ecd61d60f0ef1a5d Mon Sep 17 00:00:00 2001 From: Vincent Mailhol Date: Fri, 10 Jun 2022 23:30:06 +0900 Subject: [PATCH 08/22] can: Kconfig: add CONFIG_CAN_RX_OFFLOAD Only a few drivers rely on the CAN rx offload framework (as of the writing of this patch, only four: flexcan, m_can, mcp251xfd and ti_hecc). Split it out of can-dev and add a new config symbol: CAN_RX_OFFLOAD. The drivers relying on CAN rx offload are in different sub folders. Make CAN_RX_OFFLOAD an hidden option and tag all the drivers depending on that feature with "select CAN_RX_OFFLOAD" so that the option gets automatically enabled if and only if one of those drivers is chosen. Link: https://lore.kernel.org/all/20220610143009.323579-5-mailhol.vincent@wanadoo.fr Suggested-by: Geert Uytterhoeven Suggested-by: Jakub Kicinski Signed-off-by: Vincent Mailhol Acked-by: Max Staudt Tested-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- drivers/net/can/Kconfig | 5 +++++ drivers/net/can/dev/Makefile | 2 +- drivers/net/can/m_can/Kconfig | 1 + drivers/net/can/spi/mcp251xfd/Kconfig | 1 + 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index 87470feae6b1..5335f3afc0a5 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig @@ -102,6 +102,9 @@ config CAN_CALC_BITTIMING If unsure, say Y. +config CAN_RX_OFFLOAD + bool + config CAN_AT91 tristate "Atmel AT91 onchip CAN controller" depends on (ARCH_AT91 || COMPILE_TEST) && HAS_IOMEM @@ -113,6 +116,7 @@ config CAN_FLEXCAN tristate "Support for Freescale FLEXCAN based chips" depends on OF || COLDFIRE || COMPILE_TEST depends on HAS_IOMEM + select CAN_RX_OFFLOAD help Say Y here if you want to support for Freescale FlexCAN. @@ -162,6 +166,7 @@ config CAN_SUN4I config CAN_TI_HECC depends on ARM tristate "TI High End CAN Controller" + select CAN_RX_OFFLOAD help Driver for TI HECC (High End CAN Controller) module found on many TI devices. The device specifications are available from www.ti.com diff --git a/drivers/net/can/dev/Makefile b/drivers/net/can/dev/Makefile index 791e6b297ea3..633687d6b6c0 100644 --- a/drivers/net/can/dev/Makefile +++ b/drivers/net/can/dev/Makefile @@ -9,4 +9,4 @@ can-dev-$(CONFIG_CAN_NETLINK) += bittiming.o can-dev-$(CONFIG_CAN_NETLINK) += dev.o can-dev-$(CONFIG_CAN_NETLINK) += length.o can-dev-$(CONFIG_CAN_NETLINK) += netlink.o -can-dev-$(CONFIG_CAN_NETLINK) += rx-offload.o +can-dev-$(CONFIG_CAN_RX_OFFLOAD) += rx-offload.o diff --git a/drivers/net/can/m_can/Kconfig b/drivers/net/can/m_can/Kconfig index 45ad1b3f0cd0..fc2afab36279 100644 --- a/drivers/net/can/m_can/Kconfig +++ b/drivers/net/can/m_can/Kconfig @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only menuconfig CAN_M_CAN tristate "Bosch M_CAN support" + select CAN_RX_OFFLOAD help Say Y here if you want support for Bosch M_CAN controller framework. This is common support for devices that embed the Bosch M_CAN IP. diff --git a/drivers/net/can/spi/mcp251xfd/Kconfig b/drivers/net/can/spi/mcp251xfd/Kconfig index dd0fc0a54be1..877e4356010d 100644 --- a/drivers/net/can/spi/mcp251xfd/Kconfig +++ b/drivers/net/can/spi/mcp251xfd/Kconfig @@ -2,6 +2,7 @@ config CAN_MCP251XFD tristate "Microchip MCP251xFD SPI CAN controllers" + select CAN_RX_OFFLOAD select REGMAP select WANT_DEV_COREDUMP help From d7786af59860a113d62150c4328674e896da7810 Mon Sep 17 00:00:00 2001 From: Vincent Mailhol Date: Fri, 10 Jun 2022 23:30:07 +0900 Subject: [PATCH 09/22] net: Kconfig: move the CAN device menu to the "Device Drivers" section The devices are meant to be under the "Device Drivers" category of the menuconfig. The CAN subsystem is currently one of the rare exception with all of its devices under the "Networking support" category. The CAN_DEV menuentry gets moved to fix this discrepancy. The CAN menu is added just before MCTP in order to be consistent with the current order under the "Networking support" menu. A dependency on CAN is added to CAN_DEV so that the CAN devices only show up if the CAN subsystem is enabled. Link: https://lore.kernel.org/all/20220610143009.323579-6-mailhol.vincent@wanadoo.fr Signed-off-by: Vincent Mailhol Acked-by: Max Staudt Tested-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- drivers/net/Kconfig | 2 ++ drivers/net/can/Kconfig | 1 + net/can/Kconfig | 5 ++--- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index b2a4f998c180..5de243899de8 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -499,6 +499,8 @@ config NET_SB1000 source "drivers/net/phy/Kconfig" +source "drivers/net/can/Kconfig" + source "drivers/net/mctp/Kconfig" source "drivers/net/mdio/Kconfig" diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index 5335f3afc0a5..806f15146f69 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig @@ -3,6 +3,7 @@ menuconfig CAN_DEV tristate "CAN Device Drivers" default y + depends on CAN help Controller Area Network (CAN) is serial communications protocol up to 1Mbit/s for its original release (now known as Classical CAN) and up diff --git a/net/can/Kconfig b/net/can/Kconfig index a9ac5ffab286..cb56be8e3862 100644 --- a/net/can/Kconfig +++ b/net/can/Kconfig @@ -15,7 +15,8 @@ menuconfig CAN PF_CAN is contained in . If you want CAN support you should say Y here and also to the - specific driver for your controller(s) below. + specific driver for your controller(s) under the Network device + support section. if CAN @@ -69,6 +70,4 @@ config CAN_ISOTP If you want to perform automotive vehicle diagnostic services (UDS), say 'y'. -source "drivers/net/can/Kconfig" - endif From ccd8a9351f7b44bc1c0c8e4d39c0d6593b106fc4 Mon Sep 17 00:00:00 2001 From: Vincent Mailhol Date: Fri, 10 Jun 2022 23:30:08 +0900 Subject: [PATCH 10/22] can: skb: move can_dropped_invalid_skb() and can_skb_headroom_valid() to skb.c The functions can_dropped_invalid_skb() and can_skb_headroom_valid() grew a lot over the years to a point which it does not make much sense to have them defined as static inline in header files. Move those two functions to the .c counterpart of skb.h. can_skb_headroom_valid()'s only caller being can_dropped_invalid_skb(), the declaration is removed from the header. Only can_dropped_invalid_skb() gets its symbol exported. While doing so, do a small cleanup: add brackets around the else block in can_dropped_invalid_skb(). Link: https://lore.kernel.org/all/20220610143009.323579-7-mailhol.vincent@wanadoo.fr Signed-off-by: Vincent Mailhol Reported-by: kernel test robot Acked-by: Max Staudt Tested-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev/skb.c | 58 ++++++++++++++++++++++++++++++++++++++ include/linux/can/skb.h | 59 +-------------------------------------- 2 files changed, 59 insertions(+), 58 deletions(-) diff --git a/drivers/net/can/dev/skb.c b/drivers/net/can/dev/skb.c index a4208f125b76..dc9da76c0470 100644 --- a/drivers/net/can/dev/skb.c +++ b/drivers/net/can/dev/skb.c @@ -259,3 +259,61 @@ struct sk_buff *alloc_can_err_skb(struct net_device *dev, struct can_frame **cf) return skb; } EXPORT_SYMBOL_GPL(alloc_can_err_skb); + +/* Check for outgoing skbs that have not been created by the CAN subsystem */ +static bool can_skb_headroom_valid(struct net_device *dev, struct sk_buff *skb) +{ + /* af_packet creates a headroom of HH_DATA_MOD bytes which is fine */ + if (WARN_ON_ONCE(skb_headroom(skb) < sizeof(struct can_skb_priv))) + return false; + + /* af_packet does not apply CAN skb specific settings */ + if (skb->ip_summed == CHECKSUM_NONE) { + /* init headroom */ + can_skb_prv(skb)->ifindex = dev->ifindex; + can_skb_prv(skb)->skbcnt = 0; + + skb->ip_summed = CHECKSUM_UNNECESSARY; + + /* perform proper loopback on capable devices */ + if (dev->flags & IFF_ECHO) + skb->pkt_type = PACKET_LOOPBACK; + else + skb->pkt_type = PACKET_HOST; + + skb_reset_mac_header(skb); + skb_reset_network_header(skb); + skb_reset_transport_header(skb); + } + + return true; +} + +/* Drop a given socketbuffer if it does not contain a valid CAN frame. */ +bool can_dropped_invalid_skb(struct net_device *dev, struct sk_buff *skb) +{ + const struct canfd_frame *cfd = (struct canfd_frame *)skb->data; + + if (skb->protocol == htons(ETH_P_CAN)) { + if (unlikely(skb->len != CAN_MTU || + cfd->len > CAN_MAX_DLEN)) + goto inval_skb; + } else if (skb->protocol == htons(ETH_P_CANFD)) { + if (unlikely(skb->len != CANFD_MTU || + cfd->len > CANFD_MAX_DLEN)) + goto inval_skb; + } else { + goto inval_skb; + } + + if (!can_skb_headroom_valid(dev, skb)) + goto inval_skb; + + return false; + +inval_skb: + kfree_skb(skb); + dev->stats.tx_dropped++; + return true; +} +EXPORT_SYMBOL_GPL(can_dropped_invalid_skb); diff --git a/include/linux/can/skb.h b/include/linux/can/skb.h index fdb22b00674a..182749e858b3 100644 --- a/include/linux/can/skb.h +++ b/include/linux/can/skb.h @@ -31,6 +31,7 @@ struct sk_buff *alloc_canfd_skb(struct net_device *dev, struct canfd_frame **cfd); struct sk_buff *alloc_can_err_skb(struct net_device *dev, struct can_frame **cf); +bool can_dropped_invalid_skb(struct net_device *dev, struct sk_buff *skb); /* * The struct can_skb_priv is used to transport additional information along @@ -96,64 +97,6 @@ static inline struct sk_buff *can_create_echo_skb(struct sk_buff *skb) return nskb; } -/* Check for outgoing skbs that have not been created by the CAN subsystem */ -static inline bool can_skb_headroom_valid(struct net_device *dev, - struct sk_buff *skb) -{ - /* af_packet creates a headroom of HH_DATA_MOD bytes which is fine */ - if (WARN_ON_ONCE(skb_headroom(skb) < sizeof(struct can_skb_priv))) - return false; - - /* af_packet does not apply CAN skb specific settings */ - if (skb->ip_summed == CHECKSUM_NONE) { - /* init headroom */ - can_skb_prv(skb)->ifindex = dev->ifindex; - can_skb_prv(skb)->skbcnt = 0; - - skb->ip_summed = CHECKSUM_UNNECESSARY; - - /* perform proper loopback on capable devices */ - if (dev->flags & IFF_ECHO) - skb->pkt_type = PACKET_LOOPBACK; - else - skb->pkt_type = PACKET_HOST; - - skb_reset_mac_header(skb); - skb_reset_network_header(skb); - skb_reset_transport_header(skb); - } - - return true; -} - -/* Drop a given socketbuffer if it does not contain a valid CAN frame. */ -static inline bool can_dropped_invalid_skb(struct net_device *dev, - struct sk_buff *skb) -{ - const struct canfd_frame *cfd = (struct canfd_frame *)skb->data; - - if (skb->protocol == htons(ETH_P_CAN)) { - if (unlikely(skb->len != CAN_MTU || - cfd->len > CAN_MAX_DLEN)) - goto inval_skb; - } else if (skb->protocol == htons(ETH_P_CANFD)) { - if (unlikely(skb->len != CANFD_MTU || - cfd->len > CANFD_MAX_DLEN)) - goto inval_skb; - } else - goto inval_skb; - - if (!can_skb_headroom_valid(dev, skb)) - goto inval_skb; - - return false; - -inval_skb: - kfree_skb(skb); - dev->stats.tx_dropped++; - return true; -} - static inline bool can_is_canfd_skb(const struct sk_buff *skb) { /* the CAN specific type of skb is identified by its data length */ From a6d190f8c7670068d8c154ef8477eca07b5e3574 Mon Sep 17 00:00:00 2001 From: Vincent Mailhol Date: Fri, 10 Jun 2022 23:30:09 +0900 Subject: [PATCH 11/22] can: skb: drop tx skb if in listen only mode Frames can be directly injected to a can driver via the packet socket. By doing so, it is possible to reach the net_device_ops::ndo_start_xmit function even if the driver is configured in listen only mode. Add a check in can_dropped_invalid_skb() to discard the skb if CAN_CTRLMODE_LISTENONLY is set. Link: https://lore.kernel.org/all/20220610143009.323579-8-mailhol.vincent@wanadoo.fr Signed-off-by: Vincent Mailhol Acked-by: Max Staudt Tested-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev/skb.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/dev/skb.c b/drivers/net/can/dev/skb.c index dc9da76c0470..8bb62dd864c8 100644 --- a/drivers/net/can/dev/skb.c +++ b/drivers/net/can/dev/skb.c @@ -5,6 +5,7 @@ */ #include +#include #include #define MOD_DESC "CAN device driver interface" @@ -293,6 +294,7 @@ static bool can_skb_headroom_valid(struct net_device *dev, struct sk_buff *skb) bool can_dropped_invalid_skb(struct net_device *dev, struct sk_buff *skb) { const struct canfd_frame *cfd = (struct canfd_frame *)skb->data; + struct can_priv *priv = netdev_priv(dev); if (skb->protocol == htons(ETH_P_CAN)) { if (unlikely(skb->len != CAN_MTU || @@ -306,8 +308,13 @@ bool can_dropped_invalid_skb(struct net_device *dev, struct sk_buff *skb) goto inval_skb; } - if (!can_skb_headroom_valid(dev, skb)) + if (!can_skb_headroom_valid(dev, skb)) { goto inval_skb; + } else if (priv->ctrlmode & CAN_CTRLMODE_LISTENONLY) { + netdev_info_once(dev, + "interface in listen only mode, dropping skb\n"); + goto inval_skb; + } return false; From a9cf02c6a671bc84a348cd5934627ff68d8d8d35 Mon Sep 17 00:00:00 2001 From: Max Staudt Date: Sat, 11 Jun 2022 19:11:55 +0200 Subject: [PATCH 12/22] can: Break loopback loop on loopback documentation There are two sections called "Local Loopback of Sent Frames". One was meant to link to the other, but pointed at itself instead. Link: https://lore.kernel.org/all/20220611171155.9090-1-max@enpas.org Fixes: 7d5977394515 ("can: migrate documentation to restructured text") Signed-off-by: Max Staudt Signed-off-by: Marc Kleine-Budde --- Documentation/networking/can.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/networking/can.rst b/Documentation/networking/can.rst index f34cb0e4460e..ebc822e605f5 100644 --- a/Documentation/networking/can.rst +++ b/Documentation/networking/can.rst @@ -168,7 +168,7 @@ reflect the correct [#f1]_ traffic on the node the loopback of the sent data has to be performed right after a successful transmission. If the CAN network interface is not capable of performing the loopback for some reason the SocketCAN core can do this task as a fallback solution. -See :ref:`socketcan-local-loopback1` for details (recommended). +See :ref:`socketcan-local-loopback2` for details (recommended). The loopback functionality is enabled by default to reflect standard networking behaviour for CAN applications. Due to some requests from From 173d349ba0b785305fde42a67ce66a63417e57da Mon Sep 17 00:00:00 2001 From: Vincent Mailhol Date: Sun, 12 Jun 2022 01:20:36 +0900 Subject: [PATCH 13/22] can: etas_es58x: replace es58x_device::rx_max_packet_size by usb_maxpacket() The field rx_max_packet_size of struct es58x_device in nothing else than usb_endpoint_descriptor::wMaxPacketSize and can be easily retrieved using usb_maxpacket(). Also, rx_max_packet_size being used a single time, there is no merit to cache it locally. Remove es58x_device::rx_max_packet_size and rely on usb_maxpacket() instead. Link: https://lore.kernel.org/all/20220611162037.1507-2-mailhol.vincent@wanadoo.fr Signed-off-by: Vincent Mailhol Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/etas_es58x/es58x_core.c | 5 ++--- drivers/net/can/usb/etas_es58x/es58x_core.h | 2 -- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c index 2d73ebbf3836..7353745f92d7 100644 --- a/drivers/net/can/usb/etas_es58x/es58x_core.c +++ b/drivers/net/can/usb/etas_es58x/es58x_core.c @@ -1707,7 +1707,7 @@ static int es58x_alloc_rx_urbs(struct es58x_device *es58x_dev) { const struct device *dev = es58x_dev->dev; const struct es58x_parameters *param = es58x_dev->param; - size_t rx_buf_len = es58x_dev->rx_max_packet_size; + u16 rx_buf_len = usb_maxpacket(es58x_dev->udev, es58x_dev->rx_pipe); struct urb *urb; u8 *buf; int i; @@ -1739,7 +1739,7 @@ static int es58x_alloc_rx_urbs(struct es58x_device *es58x_dev) dev_err(dev, "%s: Could not setup any rx URBs\n", __func__); return ret; } - dev_dbg(dev, "%s: Allocated %d rx URBs each of size %zu\n", + dev_dbg(dev, "%s: Allocated %d rx URBs each of size %u\n", __func__, i, rx_buf_len); return ret; @@ -2223,7 +2223,6 @@ static struct es58x_device *es58x_init_es58x_dev(struct usb_interface *intf, ep_in->bEndpointAddress); es58x_dev->tx_pipe = usb_sndbulkpipe(es58x_dev->udev, ep_out->bEndpointAddress); - es58x_dev->rx_max_packet_size = le16_to_cpu(ep_in->wMaxPacketSize); return es58x_dev; } diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.h b/drivers/net/can/usb/etas_es58x/es58x_core.h index e5033cb5e695..512c5b7a1cfa 100644 --- a/drivers/net/can/usb/etas_es58x/es58x_core.h +++ b/drivers/net/can/usb/etas_es58x/es58x_core.h @@ -380,7 +380,6 @@ struct es58x_operators { * @timestamps: a temporary buffer to store the time stamps before * feeding them to es58x_can_get_echo_skb(). Can only be used * in RX branches. - * @rx_max_packet_size: Maximum length of bulk-in URB. * @num_can_ch: Number of CAN channel (i.e. number of elements of @netdev). * @opened_channel_cnt: number of channels opened. Free of race * conditions because its two users (net_device_ops:ndo_open() @@ -414,7 +413,6 @@ struct es58x_device { u64 timestamps[ES58X_ECHO_BULK_MAX]; - u16 rx_max_packet_size; u8 num_can_ch; u8 opened_channel_cnt; From e0e0cc54000e6f36a38c70778feb9d753cfb87e2 Mon Sep 17 00:00:00 2001 From: Vincent Mailhol Date: Sun, 12 Jun 2022 01:20:37 +0900 Subject: [PATCH 14/22] can: etas_es58x: fix signedness of USB RX and TX pipes USB pipes are meant to be unsigned int (c.f. [1]). However, fields rx_pipe and tx_pipe of struct es58x_device are both signed integers. Change the type of those two fields from int to unsigned int. [1] https://elixir.bootlin.com/linux/v5.18/source/include/linux/usb.h#L1571 Link: https://lore.kernel.org/all/20220611162037.1507-3-mailhol.vincent@wanadoo.fr Signed-off-by: Vincent Mailhol Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/etas_es58x/es58x_core.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.h b/drivers/net/can/usb/etas_es58x/es58x_core.h index 512c5b7a1cfa..d769bdf740b7 100644 --- a/drivers/net/can/usb/etas_es58x/es58x_core.h +++ b/drivers/net/can/usb/etas_es58x/es58x_core.h @@ -400,8 +400,8 @@ struct es58x_device { const struct es58x_parameters *param; const struct es58x_operators *ops; - int rx_pipe; - int tx_pipe; + unsigned int rx_pipe; + unsigned int tx_pipe; struct usb_anchor rx_urbs; struct usb_anchor tx_urbs_busy; From c878d518d7b628bc40cacfc9cee4a3db91a6a9ac Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Tue, 7 Jun 2022 07:54:59 +0100 Subject: [PATCH 15/22] dt-bindings: can: mpfs: document the mpfs CAN controller Add a binding for the CAN controller on PolarFire SoC (MPFS). A data sheet and a register map can be downloaded at: | https://www.microsemi.com/document-portal/doc_download/1245725-polarfire-soc-fpga-mss-technical-reference-manual | https://www.microsemi.com/document-portal/doc_download/1244581-polarfire-soc-register-map An alternative location for the register map is: | http://web.archive.org/web/20220403030214/https://www.microsemi.com/document-portal/doc_download/1244581-polarfire-soc-register-map Link: https://lore.kernel.org/all/20220607065459.2035746-2-conor.dooley@microchip.com Signed-off-by: Conor Dooley Reviewed-by: Rob Herring [mkl: add link to data sheet and register map] Signed-off-by: Marc Kleine-Budde --- .../bindings/net/can/microchip,mpfs-can.yaml | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml diff --git a/Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml b/Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml new file mode 100644 index 000000000000..45aa3de7cf01 --- /dev/null +++ b/Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/net/can/microchip,mpfs-can.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: + Microchip PolarFire SoC (MPFS) can controller + +maintainers: + - Conor Dooley + +allOf: + - $ref: can-controller.yaml# + +properties: + compatible: + const: microchip,mpfs-can + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + - clocks + +additionalProperties: false + +examples: + - | + can@2010c000 { + compatible = "microchip,mpfs-can"; + reg = <0x2010c000 0x1000>; + clocks = <&clkcfg 17>; + interrupt-parent = <&plic>; + interrupts = <56>; + }; From 38a71fc048955c5c9d8bd14351d0f8cbcfef4f5b Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Tue, 7 Jun 2022 07:55:00 +0100 Subject: [PATCH 16/22] riscv: dts: microchip: add mpfs's CAN controllers PolarFire SoC has a pair of CAN controllers, but as they were undocumented there were omitted from the device tree. Add them. Link: https://lore.kernel.org/all/20220607065459.2035746-3-conor.dooley@microchip.com Signed-off-by: Conor Dooley Signed-off-by: Marc Kleine-Budde --- arch/riscv/boot/dts/microchip/mpfs.dtsi | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/arch/riscv/boot/dts/microchip/mpfs.dtsi b/arch/riscv/boot/dts/microchip/mpfs.dtsi index 8c3259134194..737e0e70c432 100644 --- a/arch/riscv/boot/dts/microchip/mpfs.dtsi +++ b/arch/riscv/boot/dts/microchip/mpfs.dtsi @@ -330,6 +330,24 @@ status = "disabled"; }; + can0: can@2010c000 { + compatible = "microchip,mpfs-can"; + reg = <0x0 0x2010c000 0x0 0x1000>; + clocks = <&clkcfg CLK_CAN0>; + interrupt-parent = <&plic>; + interrupts = <56>; + status = "disabled"; + }; + + can1: can@2010d000 { + compatible = "microchip,mpfs-can"; + reg = <0x0 0x2010d000 0x0 0x1000>; + clocks = <&clkcfg CLK_CAN1>; + interrupt-parent = <&plic>; + interrupts = <57>; + status = "disabled"; + }; + mac0: ethernet@20110000 { compatible = "cdns,macb"; reg = <0x0 0x20110000 0x0 0x2000>; From ec30c109391c5eac9b1d689a61e4bfed88148947 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sat, 11 Jun 2022 16:20:58 +0200 Subject: [PATCH 17/22] can: netlink: allow configuring of fixed data bit rates without need for do_set_data_bittiming callback This patch is similar to 7e193a42c37c ("can: netlink: allow configuring of fixed bit rates without need for do_set_bittiming callback") but for data bit rates instead of bit rates. Usually CAN devices support configurable data bit rates. The limits are defined by struct can_priv::data_bittiming_const. Another way is to implement the struct can_priv::do_set_data_bittiming callback. If the bit rate is configured via netlink, the can_changelink() function checks that either can_priv::data_bittiming_const or struct can_priv::do_set_data_bittiming is implemented. In commit 431af779256c ("can: dev: add CAN interface API for fixed bitrates") an API for configuring bit rates on CAN interfaces that only support fixed bit rates was added. The supported bit rates are defined by struct can_priv::bitrate_const. However the above mentioned commit forgot to add the struct can_priv::data_bitrate_const to the check in can_changelink(). In order to avoid to implement a no-op can_priv::do_set_data_bittiming callback on devices with fixed data bit rates, extend the check in can_changelink() accordingly. Link: https://lore.kernel.org/all/20220613143633.4151884-1-mkl@pengutronix.de Fixes: 431af779256c ("can: dev: add CAN interface API for fixed bitrates") Acked-by: Max Staudt Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev/netlink.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/dev/netlink.c b/drivers/net/can/dev/netlink.c index 667ddd28fcdc..037824011266 100644 --- a/drivers/net/can/dev/netlink.c +++ b/drivers/net/can/dev/netlink.c @@ -279,7 +279,8 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[], * directly via do_set_bitrate(). Bail out if neither * is given. */ - if (!priv->data_bittiming_const && !priv->do_set_data_bittiming) + if (!priv->data_bittiming_const && !priv->do_set_data_bittiming && + !priv->data_bitrate_const) return -EOPNOTSUPP; memcpy(&dbt, nla_data(data[IFLA_CAN_DATA_BITTIMING]), From 5e910bdedc84c1f196863cebdf27c1806449c27c Mon Sep 17 00:00:00 2001 From: Frank Jungclaus Date: Fri, 24 Jun 2022 21:05:15 +0200 Subject: [PATCH 18/22] can/esd_usb2: Rename esd_usb2.c to esd_usb.c As suggested by Vincent, renaming of esd_usb2.c to esd_usb.c and according to that, adaption of Kconfig and Makfile, too. Link: https://lore.kernel.org/all/20220624190517.2299701-2-frank.jungclaus@esd.eu Signed-off-by: Frank Jungclaus Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/Kconfig | 15 +++++++++++---- drivers/net/can/usb/Makefile | 2 +- drivers/net/can/usb/{esd_usb2.c => esd_usb.c} | 0 3 files changed, 12 insertions(+), 5 deletions(-) rename drivers/net/can/usb/{esd_usb2.c => esd_usb.c} (100%) diff --git a/drivers/net/can/usb/Kconfig b/drivers/net/can/usb/Kconfig index f959215c9d53..1218f9642f33 100644 --- a/drivers/net/can/usb/Kconfig +++ b/drivers/net/can/usb/Kconfig @@ -14,11 +14,18 @@ config CAN_EMS_USB This driver is for the one channel CPC-USB/ARM7 CAN/USB interface from EMS Dr. Thomas Wuensche (http://www.ems-wuensche.de). -config CAN_ESD_USB2 - tristate "ESD USB/2 CAN/USB interface" +config CAN_ESD_USB + tristate "esd electronics gmbh CAN/USB interfaces" help - This driver supports the CAN-USB/2 interface - from esd electronic system design gmbh (http://www.esd.eu). + This driver adds supports for several CAN/USB interfaces + from esd electronics gmbh (https://www.esd.eu). + + The drivers supports the following devices: + - esd CAN-USB/2 + - esd CAN-USB/Micro + + To compile this driver as a module, choose M here: the module + will be called esd_usb. config CAN_ETAS_ES58X tristate "ETAS ES58X CAN/USB interfaces" diff --git a/drivers/net/can/usb/Makefile b/drivers/net/can/usb/Makefile index 748cf31a0d53..1ea16be5743b 100644 --- a/drivers/net/can/usb/Makefile +++ b/drivers/net/can/usb/Makefile @@ -5,7 +5,7 @@ obj-$(CONFIG_CAN_8DEV_USB) += usb_8dev.o obj-$(CONFIG_CAN_EMS_USB) += ems_usb.o -obj-$(CONFIG_CAN_ESD_USB2) += esd_usb2.o +obj-$(CONFIG_CAN_ESD_USB) += esd_usb.o obj-$(CONFIG_CAN_ETAS_ES58X) += etas_es58x/ obj-$(CONFIG_CAN_GS_USB) += gs_usb.o obj-$(CONFIG_CAN_KVASER_USB) += kvaser_usb/ diff --git a/drivers/net/can/usb/esd_usb2.c b/drivers/net/can/usb/esd_usb.c similarity index 100% rename from drivers/net/can/usb/esd_usb2.c rename to drivers/net/can/usb/esd_usb.c From f4a45ef328a2e3b751f9cf0f6bb25786a4d05d15 Mon Sep 17 00:00:00 2001 From: Frank Jungclaus Date: Fri, 24 Jun 2022 21:05:16 +0200 Subject: [PATCH 19/22] can/esd_usb: Add an entry to the MAINTAINERS file As suggested by Marc, I added an entry for ESD CAN/USB Drivers to the MAINTAINERS file Link: https://lore.kernel.org/all/20220624190517.2299701-3-frank.jungclaus@esd.eu Signed-off-by: Frank Jungclaus Signed-off-by: Marc Kleine-Budde --- MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 05fcbea3e432..2d1cf1718140 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7406,6 +7406,13 @@ S: Maintained F: include/linux/errseq.h F: lib/errseq.c +ESD CAN/USB DRIVERS +M: Frank Jungclaus +R: socketcan@esd.eu +L: linux-can@vger.kernel.org +S: Maintained +F: drivers/net/can/usb/esd_usb.c + ET131X NETWORK DRIVER M: Mark Einon S: Odd Fixes From 4d54977fe3f43dde2d7a28679fc259b7a593b1bb Mon Sep 17 00:00:00 2001 From: Frank Jungclaus Date: Fri, 24 Jun 2022 21:05:17 +0200 Subject: [PATCH 20/22] can/esd_usb: Rename all terms USB2 to USB Each occurrence of the term "usb2" within variables, function names, comments, etc. is changed to "usb" where it is shared for all esd CAN/USB devices. Link: https://lore.kernel.org/all/20220624190517.2299701-4-frank.jungclaus@esd.eu Signed-off-by: Frank Jungclaus Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/esd_usb.c | 213 +++++++++++++++++----------------- 1 file changed, 109 insertions(+), 104 deletions(-) diff --git a/drivers/net/can/usb/esd_usb.c b/drivers/net/can/usb/esd_usb.c index 286daaaea0b8..befd570018d7 100644 --- a/drivers/net/can/usb/esd_usb.c +++ b/drivers/net/can/usb/esd_usb.c @@ -18,16 +18,19 @@ MODULE_AUTHOR("Matthias Fuchs "); MODULE_DESCRIPTION("CAN driver for esd CAN-USB/2 and CAN-USB/Micro interfaces"); MODULE_LICENSE("GPL v2"); -/* Define these values to match your devices */ +/* USB vendor and product ID */ #define USB_ESDGMBH_VENDOR_ID 0x0ab4 #define USB_CANUSB2_PRODUCT_ID 0x0010 #define USB_CANUSBM_PRODUCT_ID 0x0011 +/* CAN controller clock frequencies */ #define ESD_USB2_CAN_CLOCK 60000000 #define ESD_USBM_CAN_CLOCK 36000000 -#define ESD_USB2_MAX_NETS 2 -/* USB2 commands */ +/* Maximum number of CAN nets */ +#define ESD_USB_MAX_NETS 2 + +/* USB commands */ #define CMD_VERSION 1 /* also used for VERSION_REPLY */ #define CMD_CAN_RX 2 /* device to host only */ #define CMD_CAN_TX 3 /* also used for TX_DONE */ @@ -43,13 +46,15 @@ MODULE_LICENSE("GPL v2"); #define ESD_EVENT 0x40000000 #define ESD_IDMASK 0x1fffffff -/* esd CAN event ids used by this driver */ -#define ESD_EV_CAN_ERROR_EXT 2 +/* esd CAN event ids */ +#define ESD_EV_CAN_ERROR_EXT 2 /* CAN controller specific diagnostic data */ /* baudrate message flags */ -#define ESD_USB2_UBR 0x80000000 -#define ESD_USB2_LOM 0x40000000 -#define ESD_USB2_NO_BAUDRATE 0x7fffffff +#define ESD_USB_UBR 0x80000000 +#define ESD_USB_LOM 0x40000000 +#define ESD_USB_NO_BAUDRATE 0x7fffffff + +/* bit timing CAN-USB/2 */ #define ESD_USB2_TSEG1_MIN 1 #define ESD_USB2_TSEG1_MAX 16 #define ESD_USB2_TSEG1_SHIFT 16 @@ -68,7 +73,7 @@ MODULE_LICENSE("GPL v2"); #define ESD_ID_ENABLE 0x80 #define ESD_MAX_ID_SEGMENT 64 -/* SJA1000 ECC register (emulated by usb2 firmware) */ +/* SJA1000 ECC register (emulated by usb firmware) */ #define SJA1000_ECC_SEG 0x1F #define SJA1000_ECC_DIR 0x20 #define SJA1000_ECC_ERR 0x06 @@ -158,7 +163,7 @@ struct set_baudrate_msg { }; /* Main message type used between library and application */ -struct __attribute__ ((packed)) esd_usb2_msg { +struct __attribute__ ((packed)) esd_usb_msg { union { struct header_msg hdr; struct version_msg version; @@ -171,23 +176,23 @@ struct __attribute__ ((packed)) esd_usb2_msg { } msg; }; -static struct usb_device_id esd_usb2_table[] = { +static struct usb_device_id esd_usb_table[] = { {USB_DEVICE(USB_ESDGMBH_VENDOR_ID, USB_CANUSB2_PRODUCT_ID)}, {USB_DEVICE(USB_ESDGMBH_VENDOR_ID, USB_CANUSBM_PRODUCT_ID)}, {} }; -MODULE_DEVICE_TABLE(usb, esd_usb2_table); +MODULE_DEVICE_TABLE(usb, esd_usb_table); -struct esd_usb2_net_priv; +struct esd_usb_net_priv; struct esd_tx_urb_context { - struct esd_usb2_net_priv *priv; + struct esd_usb_net_priv *priv; u32 echo_index; }; -struct esd_usb2 { +struct esd_usb { struct usb_device *udev; - struct esd_usb2_net_priv *nets[ESD_USB2_MAX_NETS]; + struct esd_usb_net_priv *nets[ESD_USB_MAX_NETS]; struct usb_anchor rx_submitted; @@ -198,22 +203,22 @@ struct esd_usb2 { dma_addr_t rxbuf_dma[MAX_RX_URBS]; }; -struct esd_usb2_net_priv { +struct esd_usb_net_priv { struct can_priv can; /* must be the first member */ atomic_t active_tx_jobs; struct usb_anchor tx_submitted; struct esd_tx_urb_context tx_contexts[MAX_TX_URBS]; - struct esd_usb2 *usb2; + struct esd_usb *usb; struct net_device *netdev; int index; u8 old_state; struct can_berr_counter bec; }; -static void esd_usb2_rx_event(struct esd_usb2_net_priv *priv, - struct esd_usb2_msg *msg) +static void esd_usb_rx_event(struct esd_usb_net_priv *priv, + struct esd_usb_msg *msg) { struct net_device_stats *stats = &priv->netdev->stats; struct can_frame *cf; @@ -296,8 +301,8 @@ static void esd_usb2_rx_event(struct esd_usb2_net_priv *priv, } } -static void esd_usb2_rx_can_msg(struct esd_usb2_net_priv *priv, - struct esd_usb2_msg *msg) +static void esd_usb_rx_can_msg(struct esd_usb_net_priv *priv, + struct esd_usb_msg *msg) { struct net_device_stats *stats = &priv->netdev->stats; struct can_frame *cf; @@ -311,7 +316,7 @@ static void esd_usb2_rx_can_msg(struct esd_usb2_net_priv *priv, id = le32_to_cpu(msg->msg.rx.id); if (id & ESD_EVENT) { - esd_usb2_rx_event(priv, msg); + esd_usb_rx_event(priv, msg); } else { skb = alloc_can_skb(priv->netdev, &cf); if (skb == NULL) { @@ -342,8 +347,8 @@ static void esd_usb2_rx_can_msg(struct esd_usb2_net_priv *priv, return; } -static void esd_usb2_tx_done_msg(struct esd_usb2_net_priv *priv, - struct esd_usb2_msg *msg) +static void esd_usb_tx_done_msg(struct esd_usb_net_priv *priv, + struct esd_usb_msg *msg) { struct net_device_stats *stats = &priv->netdev->stats; struct net_device *netdev = priv->netdev; @@ -370,9 +375,9 @@ static void esd_usb2_tx_done_msg(struct esd_usb2_net_priv *priv, netif_wake_queue(netdev); } -static void esd_usb2_read_bulk_callback(struct urb *urb) +static void esd_usb_read_bulk_callback(struct urb *urb) { - struct esd_usb2 *dev = urb->context; + struct esd_usb *dev = urb->context; int retval; int pos = 0; int i; @@ -394,9 +399,9 @@ static void esd_usb2_read_bulk_callback(struct urb *urb) } while (pos < urb->actual_length) { - struct esd_usb2_msg *msg; + struct esd_usb_msg *msg; - msg = (struct esd_usb2_msg *)(urb->transfer_buffer + pos); + msg = (struct esd_usb_msg *)(urb->transfer_buffer + pos); switch (msg->msg.hdr.cmd) { case CMD_CAN_RX: @@ -405,7 +410,7 @@ static void esd_usb2_read_bulk_callback(struct urb *urb) break; } - esd_usb2_rx_can_msg(dev->nets[msg->msg.rx.net], msg); + esd_usb_rx_can_msg(dev->nets[msg->msg.rx.net], msg); break; case CMD_CAN_TX: @@ -414,8 +419,8 @@ static void esd_usb2_read_bulk_callback(struct urb *urb) break; } - esd_usb2_tx_done_msg(dev->nets[msg->msg.txdone.net], - msg); + esd_usb_tx_done_msg(dev->nets[msg->msg.txdone.net], + msg); break; } @@ -430,7 +435,7 @@ static void esd_usb2_read_bulk_callback(struct urb *urb) resubmit_urb: usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), urb->transfer_buffer, RX_BUFFER_SIZE, - esd_usb2_read_bulk_callback, dev); + esd_usb_read_bulk_callback, dev); retval = usb_submit_urb(urb, GFP_ATOMIC); if (retval == -ENODEV) { @@ -449,12 +454,12 @@ resubmit_urb: /* * callback for bulk IN urb */ -static void esd_usb2_write_bulk_callback(struct urb *urb) +static void esd_usb_write_bulk_callback(struct urb *urb) { struct esd_tx_urb_context *context = urb->context; - struct esd_usb2_net_priv *priv; + struct esd_usb_net_priv *priv; struct net_device *netdev; - size_t size = sizeof(struct esd_usb2_msg); + size_t size = sizeof(struct esd_usb_msg); WARN_ON(!context); @@ -478,7 +483,7 @@ static ssize_t firmware_show(struct device *d, struct device_attribute *attr, char *buf) { struct usb_interface *intf = to_usb_interface(d); - struct esd_usb2 *dev = usb_get_intfdata(intf); + struct esd_usb *dev = usb_get_intfdata(intf); return sprintf(buf, "%d.%d.%d\n", (dev->version >> 12) & 0xf, @@ -491,7 +496,7 @@ static ssize_t hardware_show(struct device *d, struct device_attribute *attr, char *buf) { struct usb_interface *intf = to_usb_interface(d); - struct esd_usb2 *dev = usb_get_intfdata(intf); + struct esd_usb *dev = usb_get_intfdata(intf); return sprintf(buf, "%d.%d.%d\n", (dev->version >> 28) & 0xf, @@ -504,13 +509,13 @@ static ssize_t nets_show(struct device *d, struct device_attribute *attr, char *buf) { struct usb_interface *intf = to_usb_interface(d); - struct esd_usb2 *dev = usb_get_intfdata(intf); + struct esd_usb *dev = usb_get_intfdata(intf); return sprintf(buf, "%d", dev->net_count); } static DEVICE_ATTR_RO(nets); -static int esd_usb2_send_msg(struct esd_usb2 *dev, struct esd_usb2_msg *msg) +static int esd_usb_send_msg(struct esd_usb *dev, struct esd_usb_msg *msg) { int actual_length; @@ -522,8 +527,8 @@ static int esd_usb2_send_msg(struct esd_usb2 *dev, struct esd_usb2_msg *msg) 1000); } -static int esd_usb2_wait_msg(struct esd_usb2 *dev, - struct esd_usb2_msg *msg) +static int esd_usb_wait_msg(struct esd_usb *dev, + struct esd_usb_msg *msg) { int actual_length; @@ -535,7 +540,7 @@ static int esd_usb2_wait_msg(struct esd_usb2 *dev, 1000); } -static int esd_usb2_setup_rx_urbs(struct esd_usb2 *dev) +static int esd_usb_setup_rx_urbs(struct esd_usb *dev) { int i, err = 0; @@ -568,7 +573,7 @@ static int esd_usb2_setup_rx_urbs(struct esd_usb2 *dev) usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), buf, RX_BUFFER_SIZE, - esd_usb2_read_bulk_callback, dev); + esd_usb_read_bulk_callback, dev); urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; usb_anchor_urb(urb, &dev->rx_submitted); @@ -609,11 +614,11 @@ freeurb: /* * Start interface */ -static int esd_usb2_start(struct esd_usb2_net_priv *priv) +static int esd_usb_start(struct esd_usb_net_priv *priv) { - struct esd_usb2 *dev = priv->usb2; + struct esd_usb *dev = priv->usb; struct net_device *netdev = priv->netdev; - struct esd_usb2_msg *msg; + struct esd_usb_msg *msg; int err, i; msg = kmalloc(sizeof(*msg), GFP_KERNEL); @@ -644,11 +649,11 @@ static int esd_usb2_start(struct esd_usb2_net_priv *priv) /* enable 29bit extended IDs */ msg->msg.filter.mask[ESD_MAX_ID_SEGMENT] = cpu_to_le32(0x00000001); - err = esd_usb2_send_msg(dev, msg); + err = esd_usb_send_msg(dev, msg); if (err) goto out; - err = esd_usb2_setup_rx_urbs(dev); + err = esd_usb_setup_rx_urbs(dev); if (err) goto out; @@ -664,9 +669,9 @@ out: return err; } -static void unlink_all_urbs(struct esd_usb2 *dev) +static void unlink_all_urbs(struct esd_usb *dev) { - struct esd_usb2_net_priv *priv; + struct esd_usb_net_priv *priv; int i, j; usb_kill_anchored_urbs(&dev->rx_submitted); @@ -687,9 +692,9 @@ static void unlink_all_urbs(struct esd_usb2 *dev) } } -static int esd_usb2_open(struct net_device *netdev) +static int esd_usb_open(struct net_device *netdev) { - struct esd_usb2_net_priv *priv = netdev_priv(netdev); + struct esd_usb_net_priv *priv = netdev_priv(netdev); int err; /* common open */ @@ -698,7 +703,7 @@ static int esd_usb2_open(struct net_device *netdev) return err; /* finally start device */ - err = esd_usb2_start(priv); + err = esd_usb_start(priv); if (err) { netdev_warn(netdev, "couldn't start device: %d\n", err); close_candev(netdev); @@ -710,20 +715,20 @@ static int esd_usb2_open(struct net_device *netdev) return 0; } -static netdev_tx_t esd_usb2_start_xmit(struct sk_buff *skb, +static netdev_tx_t esd_usb_start_xmit(struct sk_buff *skb, struct net_device *netdev) { - struct esd_usb2_net_priv *priv = netdev_priv(netdev); - struct esd_usb2 *dev = priv->usb2; + struct esd_usb_net_priv *priv = netdev_priv(netdev); + struct esd_usb *dev = priv->usb; struct esd_tx_urb_context *context = NULL; struct net_device_stats *stats = &netdev->stats; struct can_frame *cf = (struct can_frame *)skb->data; - struct esd_usb2_msg *msg; + struct esd_usb_msg *msg; struct urb *urb; u8 *buf; int i, err; int ret = NETDEV_TX_OK; - size_t size = sizeof(struct esd_usb2_msg); + size_t size = sizeof(struct esd_usb_msg); if (can_dropped_invalid_skb(netdev, skb)) return NETDEV_TX_OK; @@ -745,7 +750,7 @@ static netdev_tx_t esd_usb2_start_xmit(struct sk_buff *skb, goto nobufmem; } - msg = (struct esd_usb2_msg *)buf; + msg = (struct esd_usb_msg *)buf; msg->msg.hdr.len = 3; /* minimal length */ msg->msg.hdr.cmd = CMD_CAN_TX; @@ -788,7 +793,7 @@ static netdev_tx_t esd_usb2_start_xmit(struct sk_buff *skb, usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, 2), buf, msg->msg.hdr.len << 2, - esd_usb2_write_bulk_callback, context); + esd_usb_write_bulk_callback, context); urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; @@ -839,24 +844,24 @@ nourbmem: return ret; } -static int esd_usb2_close(struct net_device *netdev) +static int esd_usb_close(struct net_device *netdev) { - struct esd_usb2_net_priv *priv = netdev_priv(netdev); - struct esd_usb2_msg *msg; + struct esd_usb_net_priv *priv = netdev_priv(netdev); + struct esd_usb_msg *msg; int i; msg = kmalloc(sizeof(*msg), GFP_KERNEL); if (!msg) return -ENOMEM; - /* Disable all IDs (see esd_usb2_start()) */ + /* Disable all IDs (see esd_usb_start()) */ msg->msg.hdr.cmd = CMD_IDADD; msg->msg.hdr.len = 2 + ESD_MAX_ID_SEGMENT; msg->msg.filter.net = priv->index; msg->msg.filter.option = ESD_ID_ENABLE; /* start with segment 0 */ for (i = 0; i <= ESD_MAX_ID_SEGMENT; i++) msg->msg.filter.mask[i] = 0; - if (esd_usb2_send_msg(priv->usb2, msg) < 0) + if (esd_usb_send_msg(priv->usb, msg) < 0) netdev_err(netdev, "sending idadd message failed\n"); /* set CAN controller to reset mode */ @@ -864,8 +869,8 @@ static int esd_usb2_close(struct net_device *netdev) msg->msg.hdr.cmd = CMD_SETBAUD; msg->msg.setbaud.net = priv->index; msg->msg.setbaud.rsvd = 0; - msg->msg.setbaud.baud = cpu_to_le32(ESD_USB2_NO_BAUDRATE); - if (esd_usb2_send_msg(priv->usb2, msg) < 0) + msg->msg.setbaud.baud = cpu_to_le32(ESD_USB_NO_BAUDRATE); + if (esd_usb_send_msg(priv->usb, msg) < 0) netdev_err(netdev, "sending setbaud message failed\n"); priv->can.state = CAN_STATE_STOPPED; @@ -879,10 +884,10 @@ static int esd_usb2_close(struct net_device *netdev) return 0; } -static const struct net_device_ops esd_usb2_netdev_ops = { - .ndo_open = esd_usb2_open, - .ndo_stop = esd_usb2_close, - .ndo_start_xmit = esd_usb2_start_xmit, +static const struct net_device_ops esd_usb_netdev_ops = { + .ndo_open = esd_usb_open, + .ndo_stop = esd_usb_close, + .ndo_start_xmit = esd_usb_start_xmit, .ndo_change_mtu = can_change_mtu, }; @@ -900,20 +905,20 @@ static const struct can_bittiming_const esd_usb2_bittiming_const = { static int esd_usb2_set_bittiming(struct net_device *netdev) { - struct esd_usb2_net_priv *priv = netdev_priv(netdev); + struct esd_usb_net_priv *priv = netdev_priv(netdev); struct can_bittiming *bt = &priv->can.bittiming; - struct esd_usb2_msg *msg; + struct esd_usb_msg *msg; int err; u32 canbtr; int sjw_shift; - canbtr = ESD_USB2_UBR; + canbtr = ESD_USB_UBR; if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) - canbtr |= ESD_USB2_LOM; + canbtr |= ESD_USB_LOM; canbtr |= (bt->brp - 1) & (ESD_USB2_BRP_MAX - 1); - if (le16_to_cpu(priv->usb2->udev->descriptor.idProduct) == + if (le16_to_cpu(priv->usb->udev->descriptor.idProduct) == USB_CANUSBM_PRODUCT_ID) sjw_shift = ESD_USBM_SJW_SHIFT; else @@ -941,16 +946,16 @@ static int esd_usb2_set_bittiming(struct net_device *netdev) netdev_info(netdev, "setting BTR=%#x\n", canbtr); - err = esd_usb2_send_msg(priv->usb2, msg); + err = esd_usb_send_msg(priv->usb, msg); kfree(msg); return err; } -static int esd_usb2_get_berr_counter(const struct net_device *netdev, - struct can_berr_counter *bec) +static int esd_usb_get_berr_counter(const struct net_device *netdev, + struct can_berr_counter *bec) { - struct esd_usb2_net_priv *priv = netdev_priv(netdev); + struct esd_usb_net_priv *priv = netdev_priv(netdev); bec->txerr = priv->bec.txerr; bec->rxerr = priv->bec.rxerr; @@ -958,7 +963,7 @@ static int esd_usb2_get_berr_counter(const struct net_device *netdev, return 0; } -static int esd_usb2_set_mode(struct net_device *netdev, enum can_mode mode) +static int esd_usb_set_mode(struct net_device *netdev, enum can_mode mode) { switch (mode) { case CAN_MODE_START: @@ -972,11 +977,11 @@ static int esd_usb2_set_mode(struct net_device *netdev, enum can_mode mode) return 0; } -static int esd_usb2_probe_one_net(struct usb_interface *intf, int index) +static int esd_usb_probe_one_net(struct usb_interface *intf, int index) { - struct esd_usb2 *dev = usb_get_intfdata(intf); + struct esd_usb *dev = usb_get_intfdata(intf); struct net_device *netdev; - struct esd_usb2_net_priv *priv; + struct esd_usb_net_priv *priv; int err = 0; int i; @@ -995,7 +1000,7 @@ static int esd_usb2_probe_one_net(struct usb_interface *intf, int index) for (i = 0; i < MAX_TX_URBS; i++) priv->tx_contexts[i].echo_index = MAX_TX_URBS; - priv->usb2 = dev; + priv->usb = dev; priv->netdev = netdev; priv->index = index; @@ -1013,12 +1018,12 @@ static int esd_usb2_probe_one_net(struct usb_interface *intf, int index) priv->can.bittiming_const = &esd_usb2_bittiming_const; priv->can.do_set_bittiming = esd_usb2_set_bittiming; - priv->can.do_set_mode = esd_usb2_set_mode; - priv->can.do_get_berr_counter = esd_usb2_get_berr_counter; + priv->can.do_set_mode = esd_usb_set_mode; + priv->can.do_get_berr_counter = esd_usb_get_berr_counter; netdev->flags |= IFF_ECHO; /* we support local echo */ - netdev->netdev_ops = &esd_usb2_netdev_ops; + netdev->netdev_ops = &esd_usb_netdev_ops; SET_NETDEV_DEV(netdev, &intf->dev); netdev->dev_id = index; @@ -1039,16 +1044,16 @@ done: } /* - * probe function for new USB2 devices + * probe function for new USB devices * * check version information and number of available * CAN interfaces */ -static int esd_usb2_probe(struct usb_interface *intf, +static int esd_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { - struct esd_usb2 *dev; - struct esd_usb2_msg *msg; + struct esd_usb *dev; + struct esd_usb_msg *msg; int i, err; dev = kzalloc(sizeof(*dev), GFP_KERNEL); @@ -1076,13 +1081,13 @@ static int esd_usb2_probe(struct usb_interface *intf, msg->msg.version.flags = 0; msg->msg.version.drv_version = 0; - err = esd_usb2_send_msg(dev, msg); + err = esd_usb_send_msg(dev, msg); if (err < 0) { dev_err(&intf->dev, "sending version message failed\n"); goto free_msg; } - err = esd_usb2_wait_msg(dev, msg); + err = esd_usb_wait_msg(dev, msg); if (err < 0) { dev_err(&intf->dev, "no version message answer\n"); goto free_msg; @@ -1105,7 +1110,7 @@ static int esd_usb2_probe(struct usb_interface *intf, /* do per device probing */ for (i = 0; i < dev->net_count; i++) - esd_usb2_probe_one_net(intf, i); + esd_usb_probe_one_net(intf, i); free_msg: kfree(msg); @@ -1118,9 +1123,9 @@ done: /* * called by the usb core when the device is removed from the system */ -static void esd_usb2_disconnect(struct usb_interface *intf) +static void esd_usb_disconnect(struct usb_interface *intf) { - struct esd_usb2 *dev = usb_get_intfdata(intf); + struct esd_usb *dev = usb_get_intfdata(intf); struct net_device *netdev; int i; @@ -1144,11 +1149,11 @@ static void esd_usb2_disconnect(struct usb_interface *intf) } /* usb specific object needed to register this driver with the usb subsystem */ -static struct usb_driver esd_usb2_driver = { - .name = "esd_usb2", - .probe = esd_usb2_probe, - .disconnect = esd_usb2_disconnect, - .id_table = esd_usb2_table, +static struct usb_driver esd_usb_driver = { + .name = "esd_usb", + .probe = esd_usb_probe, + .disconnect = esd_usb_disconnect, + .id_table = esd_usb_table, }; -module_usb_driver(esd_usb2_driver); +module_usb_driver(esd_usb_driver); From 2244610050c8eaa02a696dbe2966ce584eda8a6b Mon Sep 17 00:00:00 2001 From: Frank Jungclaus Date: Fri, 24 Jun 2022 21:05:18 +0200 Subject: [PATCH 21/22] can/esd_usb: Fixed some checkpatch.pl warnings Link: https://lore.kernel.org/all/20220624190517.2299701-5-frank.jungclaus@esd.eu Signed-off-by: Frank Jungclaus Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/esd_usb.c | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/drivers/net/can/usb/esd_usb.c b/drivers/net/can/usb/esd_usb.c index befd570018d7..e23dce3db55a 100644 --- a/drivers/net/can/usb/esd_usb.c +++ b/drivers/net/can/usb/esd_usb.c @@ -163,7 +163,7 @@ struct set_baudrate_msg { }; /* Main message type used between library and application */ -struct __attribute__ ((packed)) esd_usb_msg { +struct __packed esd_usb_msg { union { struct header_msg hdr; struct version_msg version; @@ -343,8 +343,6 @@ static void esd_usb_rx_can_msg(struct esd_usb_net_priv *priv, netif_rx(skb); } - - return; } static void esd_usb_tx_done_msg(struct esd_usb_net_priv *priv, @@ -447,13 +445,9 @@ resubmit_urb: dev_err(dev->udev->dev.parent, "failed resubmitting read bulk urb: %d\n", retval); } - - return; } -/* - * callback for bulk IN urb - */ +/* callback for bulk IN urb */ static void esd_usb_write_bulk_callback(struct urb *urb) { struct esd_tx_urb_context *context = urb->context; @@ -611,9 +605,7 @@ freeurb: return 0; } -/* - * Start interface - */ +/* Start interface */ static int esd_usb_start(struct esd_usb_net_priv *priv) { struct esd_usb *dev = priv->usb; @@ -627,8 +619,7 @@ static int esd_usb_start(struct esd_usb_net_priv *priv) goto out; } - /* - * Enable all IDs + /* Enable all IDs * The IDADD message takes up to 64 32 bit bitmasks (2048 bits). * Each bit represents one 11 bit CAN identifier. A set bit * enables reception of the corresponding CAN identifier. A cleared @@ -776,9 +767,7 @@ static netdev_tx_t esd_usb_start_xmit(struct sk_buff *skb, } } - /* - * This may never happen. - */ + /* This may never happen */ if (!context) { netdev_warn(netdev, "couldn't find free context\n"); ret = NETDEV_TX_BUSY; @@ -826,8 +815,7 @@ static netdev_tx_t esd_usb_start_xmit(struct sk_buff *skb, netif_trans_update(netdev); - /* - * Release our reference to this URB, the USB core will eventually free + /* Release our reference to this URB, the USB core will eventually free * it entirely. */ usb_free_urb(urb); @@ -1043,8 +1031,7 @@ done: return err; } -/* - * probe function for new USB devices +/* probe function for new USB devices * * check version information and number of available * CAN interfaces @@ -1120,9 +1107,7 @@ done: return err; } -/* - * called by the usb core when the device is removed from the system - */ +/* called by the usb core when the device is removed from the system */ static void esd_usb_disconnect(struct usb_interface *intf) { struct esd_usb *dev = usb_get_intfdata(intf); From ce87c0f1b8592e4f934bac16c44a801b7cfa7123 Mon Sep 17 00:00:00 2001 From: Frank Jungclaus Date: Fri, 24 Jun 2022 21:05:19 +0200 Subject: [PATCH 22/22] can/esd_usb: Update to copyright, M_AUTHOR and M_DESCRIPTION - Brought the copyright notice up to date - Also regarding the changed company name from esd electronic system design gmbh to esd electronics gmbh - Using socketcan@esd.eu as a generic mail address for matthias who left esd 6 years before - Added a second MODULE_AUTHOR() for Frank Jungclaus Link: https://lore.kernel.org/all/20220624190517.2299701-6-frank.jungclaus@esd.eu Signed-off-by: Frank Jungclaus Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/esd_usb.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/net/can/usb/esd_usb.c b/drivers/net/can/usb/esd_usb.c index e23dce3db55a..8a4bf2961f3d 100644 --- a/drivers/net/can/usb/esd_usb.c +++ b/drivers/net/can/usb/esd_usb.c @@ -1,8 +1,9 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * CAN driver for esd CAN-USB/2 and CAN-USB/Micro + * CAN driver for esd electronics gmbh CAN-USB/2 and CAN-USB/Micro * - * Copyright (C) 2010-2012 Matthias Fuchs , esd gmbh + * Copyright (C) 2010-2012 esd electronic system design gmbh, Matthias Fuchs + * Copyright (C) 2022 esd electronics gmbh, Frank Jungclaus */ #include #include @@ -14,8 +15,9 @@ #include #include -MODULE_AUTHOR("Matthias Fuchs "); -MODULE_DESCRIPTION("CAN driver for esd CAN-USB/2 and CAN-USB/Micro interfaces"); +MODULE_AUTHOR("Matthias Fuchs "); +MODULE_AUTHOR("Frank Jungclaus "); +MODULE_DESCRIPTION("CAN driver for esd electronics gmbh CAN-USB/2 and CAN-USB/Micro interfaces"); MODULE_LICENSE("GPL v2"); /* USB vendor and product ID */