can: mcp251xfd: ethtool: add support
authorMarc Kleine-Budde <mkl@pengutronix.de>
Mon, 25 Oct 2021 09:34:32 +0000 (11:34 +0200)
committerMarc Kleine-Budde <mkl@pengutronix.de>
Sun, 13 Mar 2022 08:45:35 +0000 (09:45 +0100)
This patch adds basic ethtool support (to query the current and
maximum ring parameters) to the driver.

Link: https://lore.kernel.org/20220313083640.501791-5-mkl@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
drivers/net/can/spi/mcp251xfd/Makefile
drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
drivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c [new file with mode: 0644]
drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c
drivers/net/can/spi/mcp251xfd/mcp251xfd.h

index 10c4f886d1f76fe26bc6bd720ef4822a2a4b7267..94d7de954294552de8d304cef1d9607d9da9bc76 100644 (file)
@@ -6,6 +6,7 @@ mcp251xfd-objs :=
 mcp251xfd-objs += mcp251xfd-chip-fifo.o
 mcp251xfd-objs += mcp251xfd-core.o
 mcp251xfd-objs += mcp251xfd-crc16.o
+mcp251xfd-objs += mcp251xfd-ethtool.o
 mcp251xfd-objs += mcp251xfd-ram.o
 mcp251xfd-objs += mcp251xfd-regmap.o
 mcp251xfd-objs += mcp251xfd-ring.o
index 3da17cadbd637a4ff5179954ad27ec98adc5e532..ebb4dc999bacf6d4cad9931b24f7ecdf57967136 100644 (file)
@@ -1871,6 +1871,8 @@ static int mcp251xfd_register(struct mcp251xfd_priv *priv)
        if (err)
                goto out_chip_sleep;
 
+       mcp251xfd_ethtool_init(priv);
+
        err = register_candev(ndev);
        if (err)
                goto out_chip_sleep;
diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c
new file mode 100644 (file)
index 0000000..4131185
--- /dev/null
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// mcp251xfd - Microchip MCP251xFD Family CAN controller driver
+//
+// Copyright (c) 2021, 2022 Pengutronix,
+//               Marc Kleine-Budde <kernel@pengutronix.de>
+//
+
+#include <linux/ethtool.h>
+
+#include "mcp251xfd.h"
+
+static void
+mcp251xfd_ring_get_ringparam(struct net_device *ndev,
+                            struct ethtool_ringparam *ring,
+                            struct kernel_ethtool_ringparam *kernel_ring,
+                            struct netlink_ext_ack *extack)
+{
+       const struct mcp251xfd_priv *priv = netdev_priv(ndev);
+
+       ring->rx_max_pending = MCP251XFD_RX_OBJ_NUM_MAX;
+       ring->tx_max_pending = MCP251XFD_TX_OBJ_NUM_MAX;
+
+       ring->rx_pending = priv->rx_obj_num;
+       ring->tx_pending = priv->tx->obj_num;
+}
+
+static const struct ethtool_ops mcp251xfd_ethtool_ops = {
+       .get_ringparam = mcp251xfd_ring_get_ringparam,
+};
+
+void mcp251xfd_ethtool_init(struct mcp251xfd_priv *priv)
+{
+       priv->ndev->ethtool_ops = &mcp251xfd_ethtool_ops;
+}
index b1c4d9b1934711d4fb45cbd22b3fe2de346fb2b7..e540c97b41604f5f698abb338a83c3ca17a9146c 100644 (file)
@@ -304,6 +304,8 @@ int mcp251xfd_ring_alloc(struct mcp251xfd_priv *priv)
                rx_obj_size = sizeof(struct mcp251xfd_hw_rx_obj_can);
        }
 
+       priv->rx_obj_num = 0;
+
        tx_ring = priv->tx;
        tx_ring->obj_num = tx_obj_num;
        tx_ring->obj_size = tx_obj_size;
@@ -320,6 +322,8 @@ int mcp251xfd_ring_alloc(struct mcp251xfd_priv *priv)
                rx_obj_num = min(1 << (fls(rx_obj_num) - 1),
                                 MCP251XFD_RX_OBJ_NUM_MAX);
 
+               priv->rx_obj_num += rx_obj_num;
+
                rx_ring = kzalloc(sizeof(*rx_ring) + rx_obj_size * rx_obj_num,
                                  GFP_KERNEL);
                if (!rx_ring) {
index 87cc13d455c1f05a5f8e0e0143861752dd29726a..5c7a672464b18b937dbcb610948402b3f207e358 100644 (file)
@@ -610,6 +610,7 @@ struct mcp251xfd_priv {
        struct mcp251xfd_tx_ring tx[MCP251XFD_FIFO_TX_NUM];
 
        u8 rx_ring_num;
+       u8 rx_obj_num;
 
        struct mcp251xfd_ecc ecc;
        struct mcp251xfd_regs_status regs_status;
@@ -891,6 +892,7 @@ int mcp251xfd_chip_fifo_init(const struct mcp251xfd_priv *priv);
 u16 mcp251xfd_crc16_compute2(const void *cmd, size_t cmd_size,
                             const void *data, size_t data_size);
 u16 mcp251xfd_crc16_compute(const void *data, size_t data_size);
+void mcp251xfd_ethtool_init(struct mcp251xfd_priv *priv);
 int mcp251xfd_regmap_init(struct mcp251xfd_priv *priv);
 int mcp251xfd_ring_init(struct mcp251xfd_priv *priv);
 void mcp251xfd_ring_free(struct mcp251xfd_priv *priv);