Hi Marc, reply all and in plain-text, On Tue, Jan 4, 2022 at 4:41 PM Marc Kleine-Budde <mkl@xxxxxxxxxxxxxx> wrote: > > This patch adds a private flag to the flexcan driver to switch the > "rx-fifo" setting on and off. > > "rx-fifo" on - the RX FIFO with a depth of 6 CAN frames is used for RX > "rx-fifo" off - the mailboxes are used for RX, the number of mailboxes > depends on the actual flexcan IP core revision and > if CAN-FD mode is active or not. > > Signed-off-by: Dario Binacchi <dario.binacchi@xxxxxxxxxxxxxxxxxxxx> > Co-developed-by: Dario Binacchi <dario.binacchi@xxxxxxxxxxxxxxxxxxxx> > Signed-off-by: Marc Kleine-Budde <mkl@xxxxxxxxxxxxxx> > --- > drivers/net/can/flexcan/Makefile | 1 + > drivers/net/can/flexcan/flexcan-core.c | 96 +----------------- > drivers/net/can/flexcan/flexcan-ethtool.c | 81 ++++++++++++++++ > drivers/net/can/flexcan/flexcan.h | 113 ++++++++++++++++++++++ > 4 files changed, 198 insertions(+), 93 deletions(-) > create mode 100644 drivers/net/can/flexcan/flexcan-ethtool.c > create mode 100644 drivers/net/can/flexcan/flexcan.h > > diff --git a/drivers/net/can/flexcan/Makefile b/drivers/net/can/flexcan/Makefile > index 25dd1d12b866..89d5695c902e 100644 > --- a/drivers/net/can/flexcan/Makefile > +++ b/drivers/net/can/flexcan/Makefile > @@ -4,3 +4,4 @@ obj-$(CONFIG_CAN_FLEXCAN) += flexcan.o > > flexcan-objs := > flexcan-objs += flexcan-core.o > +flexcan-objs += flexcan-ethtool.o > diff --git a/drivers/net/can/flexcan/flexcan-core.c b/drivers/net/can/flexcan/flexcan-core.c > index 26bf0a0a72f1..ae7c838ff76c 100644 > --- a/drivers/net/can/flexcan/flexcan-core.c > +++ b/drivers/net/can/flexcan/flexcan-core.c > @@ -15,7 +15,6 @@ > #include <linux/can/dev.h> > #include <linux/can/error.h> > #include <linux/can/led.h> > -#include <linux/can/rx-offload.h> > #include <linux/clk.h> > #include <linux/delay.h> > #include <linux/firmware/imx/sci.h> > @@ -33,6 +32,8 @@ > #include <linux/regmap.h> > #include <linux/regulator/consumer.h> > > +#include "flexcan.h" > + > #define DRV_NAME "flexcan" > > /* 8 for RX fifo and 2 error handling */ > @@ -206,53 +207,6 @@ > > #define FLEXCAN_TIMEOUT_US (250) > > -/* FLEXCAN hardware feature flags > - * > - * Below is some version info we got: > - * SOC Version IP-Version Glitch- [TR]WRN_INT IRQ Err Memory err RTR rece- FD Mode MB > - * Filter? connected? Passive detection ption in MB Supported? > - * MCF5441X FlexCAN2 ? no yes no no yes no 16 > - * MX25 FlexCAN2 03.00.00.00 no no no no no no 64 > - * MX28 FlexCAN2 03.00.04.00 yes yes no no no no 64 > - * MX35 FlexCAN2 03.00.00.00 no no no no no no 64 > - * MX53 FlexCAN2 03.00.00.00 yes no no no no no 64 > - * MX6s FlexCAN3 10.00.12.00 yes yes no no yes no 64 > - * MX8QM FlexCAN3 03.00.23.00 yes yes no no yes yes 64 > - * MX8MP FlexCAN3 03.00.17.01 yes yes no yes yes yes 64 > - * VF610 FlexCAN3 ? no yes no yes yes? no 64 > - * LS1021A FlexCAN2 03.00.04.00 no yes no no yes no 64 > - * LX2160A FlexCAN3 03.00.23.00 no yes no yes yes yes 64 > - * > - * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected. > - */ > - > -/* [TR]WRN_INT not connected */ > -#define FLEXCAN_QUIRK_BROKEN_WERR_STATE BIT(1) > - /* Disable RX FIFO Global mask */ > -#define FLEXCAN_QUIRK_DISABLE_RXFG BIT(2) > -/* Enable EACEN and RRS bit in ctrl2 */ > -#define FLEXCAN_QUIRK_ENABLE_EACEN_RRS BIT(3) > -/* Disable non-correctable errors interrupt and freeze mode */ > -#define FLEXCAN_QUIRK_DISABLE_MECR BIT(4) > -/* Use timestamp based offloading */ > -#define FLEXCAN_QUIRK_USE_OFF_TIMESTAMP BIT(5) > -/* No interrupt for error passive */ > -#define FLEXCAN_QUIRK_BROKEN_PERR_STATE BIT(6) > -/* default to BE register access */ > -#define FLEXCAN_QUIRK_DEFAULT_BIG_ENDIAN BIT(7) > -/* Setup stop mode with GPR to support wakeup */ > -#define FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR BIT(8) > -/* Support CAN-FD mode */ > -#define FLEXCAN_QUIRK_SUPPORT_FD BIT(9) > -/* support memory detection and correction */ > -#define FLEXCAN_QUIRK_SUPPORT_ECC BIT(10) > -/* Setup stop mode with SCU firmware to support wakeup */ > -#define FLEXCAN_QUIRK_SETUP_STOP_MODE_SCFW BIT(11) > -/* Setup 3 separate interrupts, main, boff and err */ > -#define FLEXCAN_QUIRK_NR_IRQ_3 BIT(12) > -/* Setup 16 mailboxes */ > -#define FLEXCAN_QUIRK_NR_MB_16 BIT(13) > - > /* Structure of the message buffer */ > struct flexcan_mb { > u32 can_ctrl; > @@ -339,51 +293,6 @@ struct flexcan_regs { > > static_assert(sizeof(struct flexcan_regs) == 0x4 * 18 + 0xfb8); > > -struct flexcan_devtype_data { > - u32 quirks; /* quirks needed for different IP cores */ > -}; > - > -struct flexcan_stop_mode { > - struct regmap *gpr; > - u8 req_gpr; > - u8 req_bit; > -}; > - > -struct flexcan_priv { > - struct can_priv can; > - struct can_rx_offload offload; > - struct device *dev; > - > - struct flexcan_regs __iomem *regs; > - struct flexcan_mb __iomem *tx_mb; > - struct flexcan_mb __iomem *tx_mb_reserved; > - u8 tx_mb_idx; > - u8 mb_count; > - u8 mb_size; > - u8 clk_src; /* clock source of CAN Protocol Engine */ > - u8 scu_idx; > - > - u64 rx_mask; > - u64 tx_mask; > - u32 reg_ctrl_default; > - > - struct clk *clk_ipg; > - struct clk *clk_per; > - struct flexcan_devtype_data devtype_data; > - struct regulator *reg_xceiver; > - struct flexcan_stop_mode stm; > - > - int irq_boff; > - int irq_err; > - > - /* IPC handle when setup stop mode by System Controller firmware(scfw) */ > - struct imx_sc_ipc *sc_ipc_handle; > - > - /* Read and Write APIs */ > - u32 (*read)(void __iomem *addr); > - void (*write)(u32 val, void __iomem *addr); > -}; > - > static const struct flexcan_devtype_data fsl_mcf5441x_devtype_data = { > .quirks = FLEXCAN_QUIRK_BROKEN_PERR_STATE | > FLEXCAN_QUIRK_NR_IRQ_3 | FLEXCAN_QUIRK_NR_MB_16, > @@ -2177,6 +2086,7 @@ static int flexcan_probe(struct platform_device *pdev) > SET_NETDEV_DEV(dev, &pdev->dev); > > dev->netdev_ops = &flexcan_netdev_ops; > + flexcan_set_ethtool_ops(dev); > dev->irq = irq; > dev->flags |= IFF_ECHO; > > diff --git a/drivers/net/can/flexcan/flexcan-ethtool.c b/drivers/net/can/flexcan/flexcan-ethtool.c > new file mode 100644 > index 000000000000..cfa0cce1d0cf > --- /dev/null > +++ b/drivers/net/can/flexcan/flexcan-ethtool.c > @@ -0,0 +1,81 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* Copyright (c) 2022 Amarula Solutions, Dario Binacchi <dario.binacchi@xxxxxxxxxxxxxxxxxxxx> > + * Copyright (c) 2022 Pengutronix, Marc Kleine-Budde <kernel@xxxxxxxxxxxxxx> > + * > + */ > + > +#include <linux/ethtool.h> > +#include <linux/kernel.h> > +#include <linux/platform_device.h> > +#include <linux/netdevice.h> > +#include <linux/can/dev.h> > + > +#include "flexcan.h" > + > +static const char flexcan_priv_flags_strings[][ETH_GSTRING_LEN] = { > +#define FLEXCAN_PRIV_FLAGS_RX_FIFO BIT(0) > + "rx-fifo", > +}; > + > +static void > +flexcan_get_strings(struct net_device *ndev, u32 stringset, u8 *data) > +{ > + switch (stringset) { > + case ETH_SS_PRIV_FLAGS: > + memcpy(data, flexcan_priv_flags_strings, > + sizeof(flexcan_priv_flags_strings)); > + } > +} > + > +static int flexcan_get_sset_count(struct net_device *netdev, int sset) > +{ > + switch (sset) { > + case ETH_SS_PRIV_FLAGS: > + return ARRAY_SIZE(flexcan_priv_flags_strings); > + default: > + return -EOPNOTSUPP; > + } > +} > + > +static u32 flexcan_get_priv_flags(struct net_device *ndev) > +{ > + const struct flexcan_priv *priv = netdev_priv(ndev); > + const u32 quirks = priv->devtype_data.quirks; > + u32 priv_flags; u32 priv_flags = 0; regards, Dario > + > + if (!(quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP)) > + priv_flags |= FLEXCAN_PRIV_FLAGS_RX_FIFO; > + > + return priv_flags; > +} > + > +static int flexcan_set_priv_flags(struct net_device *ndev, u32 priv_flags) > +{ > + struct flexcan_priv *priv = netdev_priv(ndev); > + u32 quirks = priv->devtype_data.quirks; > + > + quirks &= ~FLEXCAN_QUIRK_USE_OFF_TIMESTAMP; > + if (!(priv_flags & FLEXCAN_PRIV_FLAGS_RX_FIFO)) > + quirks |= FLEXCAN_QUIRK_USE_OFF_TIMESTAMP; > + > + if (quirks != priv->devtype_data.quirks && > + netif_running(ndev)) { > + return -EBUSY; > + } > + > + priv->devtype_data.quirks = quirks; > + > + return 0; > +} > + > +static const struct ethtool_ops flexcan_ethtool_ops = { > + .get_sset_count = flexcan_get_sset_count, > + .get_strings = flexcan_get_strings, > + .get_priv_flags = flexcan_get_priv_flags, > + .set_priv_flags = flexcan_set_priv_flags, > +}; > + > +void flexcan_set_ethtool_ops(struct net_device *netdev) > +{ > + netdev->ethtool_ops = &flexcan_ethtool_ops; > +} > diff --git a/drivers/net/can/flexcan/flexcan.h b/drivers/net/can/flexcan/flexcan.h > new file mode 100644 > index 000000000000..e64b9f6c1041 > --- /dev/null > +++ b/drivers/net/can/flexcan/flexcan.h > @@ -0,0 +1,113 @@ > +/* SPDX-License-Identifier: GPL-2.0 > + * flexcan.c - FLEXCAN CAN controller driver > + * > + * Copyright (c) 2005-2006 Varma Electronics Oy > + * Copyright (c) 2009 Sascha Hauer, Pengutronix > + * Copyright (c) 2010-2017 Pengutronix, Marc Kleine-Budde <kernel@xxxxxxxxxxxxxx> > + * Copyright (c) 2014 David Jander, Protonic Holland > + * Copyright (C) 2022 Amarula Solutions, Dario Binacchi <dario.binacchi@xxxxxxxxxxxxxxxxxxxx> > + * > + * Based on code originally by Andrey Volkov <avolkov@xxxxxxxxxxxx> > + * > + */ > + > +#ifndef _FLEXCAN_H > +#define _FLEXCAN_H > + > +#include <linux/can/rx-offload.h> > + > +/* FLEXCAN hardware feature flags > + * > + * Below is some version info we got: > + * SOC Version IP-Version Glitch- [TR]WRN_INT IRQ Err Memory err RTR rece- FD Mode MB > + * Filter? connected? Passive detection ption in MB Supported? > + * MCF5441X FlexCAN2 ? no yes no no yes no 16 > + * MX25 FlexCAN2 03.00.00.00 no no no no no no 64 > + * MX28 FlexCAN2 03.00.04.00 yes yes no no no no 64 > + * MX35 FlexCAN2 03.00.00.00 no no no no no no 64 > + * MX53 FlexCAN2 03.00.00.00 yes no no no no no 64 > + * MX6s FlexCAN3 10.00.12.00 yes yes no no yes no 64 > + * MX8QM FlexCAN3 03.00.23.00 yes yes no no yes yes 64 > + * MX8MP FlexCAN3 03.00.17.01 yes yes no yes yes yes 64 > + * VF610 FlexCAN3 ? no yes no yes yes? no 64 > + * LS1021A FlexCAN2 03.00.04.00 no yes no no yes no 64 > + * LX2160A FlexCAN3 03.00.23.00 no yes no yes yes yes 64 > + * > + * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected. > + */ > + > +/* [TR]WRN_INT not connected */ > +#define FLEXCAN_QUIRK_BROKEN_WERR_STATE BIT(1) > + /* Disable RX FIFO Global mask */ > +#define FLEXCAN_QUIRK_DISABLE_RXFG BIT(2) > +/* Enable EACEN and RRS bit in ctrl2 */ > +#define FLEXCAN_QUIRK_ENABLE_EACEN_RRS BIT(3) > +/* Disable non-correctable errors interrupt and freeze mode */ > +#define FLEXCAN_QUIRK_DISABLE_MECR BIT(4) > +/* Use timestamp based offloading */ > +#define FLEXCAN_QUIRK_USE_OFF_TIMESTAMP BIT(5) > +/* No interrupt for error passive */ > +#define FLEXCAN_QUIRK_BROKEN_PERR_STATE BIT(6) > +/* default to BE register access */ > +#define FLEXCAN_QUIRK_DEFAULT_BIG_ENDIAN BIT(7) > +/* Setup stop mode with GPR to support wakeup */ > +#define FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR BIT(8) > +/* Support CAN-FD mode */ > +#define FLEXCAN_QUIRK_SUPPORT_FD BIT(9) > +/* support memory detection and correction */ > +#define FLEXCAN_QUIRK_SUPPORT_ECC BIT(10) > +/* Setup stop mode with SCU firmware to support wakeup */ > +#define FLEXCAN_QUIRK_SETUP_STOP_MODE_SCFW BIT(11) > +/* Setup 3 separate interrupts, main, boff and err */ > +#define FLEXCAN_QUIRK_NR_IRQ_3 BIT(12) > +/* Setup 16 mailboxes */ > +#define FLEXCAN_QUIRK_NR_MB_16 BIT(13) > + > +struct flexcan_devtype_data { > + u32 quirks; /* quirks needed for different IP cores */ > +}; > + > +struct flexcan_stop_mode { > + struct regmap *gpr; > + u8 req_gpr; > + u8 req_bit; > +}; > + > +struct flexcan_priv { > + struct can_priv can; > + struct can_rx_offload offload; > + struct device *dev; > + > + struct flexcan_regs __iomem *regs; > + struct flexcan_mb __iomem *tx_mb; > + struct flexcan_mb __iomem *tx_mb_reserved; > + u8 tx_mb_idx; > + u8 mb_count; > + u8 mb_size; > + u8 clk_src; /* clock source of CAN Protocol Engine */ > + u8 scu_idx; > + > + u64 rx_mask; > + u64 tx_mask; > + u32 reg_ctrl_default; > + > + struct clk *clk_ipg; > + struct clk *clk_per; > + struct flexcan_devtype_data devtype_data; > + struct regulator *reg_xceiver; > + struct flexcan_stop_mode stm; > + > + int irq_boff; > + int irq_err; > + > + /* IPC handle when setup stop mode by System Controller firmware(scfw) */ > + struct imx_sc_ipc *sc_ipc_handle; > + > + /* Read and Write APIs */ > + u32 (*read)(void __iomem *addr); > + void (*write)(u32 val, void __iomem *addr); > +}; > + > +void flexcan_set_ethtool_ops(struct net_device *dev); > + > +#endif /* _FLEXCAN_H */ > -- > 2.34.1 > > -- Dario Binacchi Embedded Linux Developer dario.binacchi@xxxxxxxxxxxxxxxxxxxx __________________________________ Amarula Solutions SRL Via Le Canevare 30, 31100 Treviso, Veneto, IT T. +39 042 243 5310 info@xxxxxxxxxxxxxxxxxxxx www.amarulasolutions.com