Introduce the build system integration and initial implementation for the MaxLinear LGM SoC Ethernet driver. This patch adds Kconfig and Makefile entries, the main driver source file, and documentation. Signed-off-by: Jack Ping CHNG --- .../device_drivers/ethernet/index.rst | 1 + .../device_drivers/ethernet/maxlinear/mxl.rst | 61 ++++++ MAINTAINERS | 8 + drivers/net/ethernet/Kconfig | 1 + drivers/net/ethernet/Makefile | 1 + drivers/net/ethernet/maxlinear/Kconfig | 15 ++ drivers/net/ethernet/maxlinear/Makefile | 6 + drivers/net/ethernet/maxlinear/mxl_eth.c | 189 ++++++++++++++++++ 8 files changed, 282 insertions(+) create mode 100644 Documentation/networking/device_drivers/ethernet/maxlinear/mxl.rst create mode 100644 drivers/net/ethernet/maxlinear/Kconfig create mode 100644 drivers/net/ethernet/maxlinear/Makefile create mode 100644 drivers/net/ethernet/maxlinear/mxl_eth.c diff --git a/Documentation/networking/device_drivers/ethernet/index.rst b/Documentation/networking/device_drivers/ethernet/index.rst index 40ac552641a3..13d3cbc96e87 100644 --- a/Documentation/networking/device_drivers/ethernet/index.rst +++ b/Documentation/networking/device_drivers/ethernet/index.rst @@ -44,6 +44,7 @@ Contents: marvell/octeontx2 marvell/octeon_ep marvell/octeon_ep_vf + maxlinear/mxl mellanox/mlx5/index meta/fbnic microsoft/netvsc diff --git a/Documentation/networking/device_drivers/ethernet/maxlinear/mxl.rst b/Documentation/networking/device_drivers/ethernet/maxlinear/mxl.rst new file mode 100644 index 000000000000..7954c47347e7 --- /dev/null +++ b/Documentation/networking/device_drivers/ethernet/maxlinear/mxl.rst @@ -0,0 +1,61 @@ +.. SPDX-License-Identifier: GPL-2.0 + +=============================================== +MaxLinear Multi-MAC Network Processor (NP) +=============================================== + +Copyright(c) 2025 MaxLinear, Inc. + +Overview +======== + +This document describes the Linux driver for the MaxLinear Network Processor +(NP), a high-performance controller supporting multiple MACs and +advanced packet processing capabilities. + +The MaxLinear Network processor integrates programmable hardware accelerators +for tasks such as Layer 2, 3, 4 forwarding, flow steering, and traffic shaping. +It is designed to operate in high-throughput applications, including data +center switching, virtualized environments, and telco infrastructure. + +Key Features +============ + +- Support for up to 4 independent 10 Gbit/s MAC interfaces +- Full-duplex 10G operation +- Multiqueue support for parallel RX/TX paths (per MAC) + +Supported Devices +================= + +The driver supports the following MaxLinear NPU family devices: +- MaxLinear LGM + +Each device supports multiple MACs and high-performance data pipelines managed +through internal firmware and programmable engines. + +Kernel Configuration +==================== + +The driver is located in the menu structure at: + + -> Device Drivers + -> Network device support + -> Ethernet driver support + -> MaxLinear NPU Ethernet driver + +Or set in your kernel config: + CONFIG_NET_VENDOR_MAXLINEAR=y + CONFIG_MAXLINEAR_ETH=y + +Maintainers +=========== + +See the MAINTAINERS file: + + MAXLINEAR ETHERNET DRIVER + M: Jack Ping Chng + L: netdev@vger.kernel.org + S: Supported + F: drivers/net/ethernet/maxlinear/ + diff --git a/MAINTAINERS b/MAINTAINERS index fe168477caa4..e4765bd73615 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15102,6 +15102,14 @@ W: https://linuxtv.org T: git git://linuxtv.org/media.git F: drivers/media/radio/radio-maxiradio* +MAXLINEAR ETHERNET DRIVER +M: Jack Ping Chng +L: netdev@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/net/mxl,lgm-eth.yaml +F: Documentation/networking/device_drivers/ethernet/maxlinear/mxl.rst +F: drivers/net/ethernet/maxlinear/mxl_eth.c + MAXLINEAR ETHERNET PHY DRIVER M: Xu Liang L: netdev@vger.kernel.org diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig index f86d4557d8d7..3e94ff7922c8 100644 --- a/drivers/net/ethernet/Kconfig +++ b/drivers/net/ethernet/Kconfig @@ -121,6 +121,7 @@ config LANTIQ_XRX200 source "drivers/net/ethernet/adi/Kconfig" source "drivers/net/ethernet/litex/Kconfig" source "drivers/net/ethernet/marvell/Kconfig" +source "drivers/net/ethernet/maxlinear/Kconfig" source "drivers/net/ethernet/mediatek/Kconfig" source "drivers/net/ethernet/mellanox/Kconfig" source "drivers/net/ethernet/meta/Kconfig" diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile index 67182339469a..760d598df197 100644 --- a/drivers/net/ethernet/Makefile +++ b/drivers/net/ethernet/Makefile @@ -58,6 +58,7 @@ obj-$(CONFIG_LANTIQ_ETOP) += lantiq_etop.o obj-$(CONFIG_LANTIQ_XRX200) += lantiq_xrx200.o obj-$(CONFIG_NET_VENDOR_LITEX) += litex/ obj-$(CONFIG_NET_VENDOR_MARVELL) += marvell/ +obj-$(CONFIG_NET_VENDOR_MAXLINEAR) += maxlinear/ obj-$(CONFIG_NET_VENDOR_MEDIATEK) += mediatek/ obj-$(CONFIG_NET_VENDOR_MELLANOX) += mellanox/ obj-$(CONFIG_NET_VENDOR_META) += meta/ diff --git a/drivers/net/ethernet/maxlinear/Kconfig b/drivers/net/ethernet/maxlinear/Kconfig new file mode 100644 index 000000000000..b88cdd9675fb --- /dev/null +++ b/drivers/net/ethernet/maxlinear/Kconfig @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0-only +config NET_VENDOR_MAXLINEAR + bool "MaxLinear devices" + help + If you have a MaxLinear SoC with ethernet, say Y. + +if NET_VENDOR_MAXLINEAR + +config MXL_NPU + tristate "MaxLinear NPU Ethernet driver" + help + This driver supports the MaxLinear NPU Ethernet. + +endif #NET_VENDOR_MAXLINEAR + diff --git a/drivers/net/ethernet/maxlinear/Makefile b/drivers/net/ethernet/maxlinear/Makefile new file mode 100644 index 000000000000..0577b325494c --- /dev/null +++ b/drivers/net/ethernet/maxlinear/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Makefile for the MaxLinear network device drivers. +# + +obj-$(CONFIG_MXL_NPU) += mxl_eth.o diff --git a/drivers/net/ethernet/maxlinear/mxl_eth.c b/drivers/net/ethernet/maxlinear/mxl_eth.c new file mode 100644 index 000000000000..093ad9b27a81 --- /dev/null +++ b/drivers/net/ethernet/maxlinear/mxl_eth.c @@ -0,0 +1,189 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2025 MaxLinear, Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ETH_TX_TIMEOUT (10 * HZ) +#define MXL_NUM_TX_RING 8 +#define MXL_NUM_RX_RING 8 +#define MXL_NUM_PORT 2 + +struct mxl_eth_drvdata { + struct net_device *ndevs[MXL_NUM_PORT]; + struct clk *clks; +}; + +struct eth_priv { + struct platform_device *pdev; + struct device_node *np; +}; + +static int mxl_eth_open(struct net_device *ndev) +{ + netif_carrier_on(ndev); + netif_start_queue(ndev); + return 0; +} + +static int mxl_eth_stop(struct net_device *ndev) +{ + netif_stop_queue(ndev); + netif_carrier_off(ndev); + return 0; +} + +static int mxl_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) +{ + dev_kfree_skb(skb); + return NETDEV_TX_OK; +} + +static const struct net_device_ops mxl_eth_netdev_ops = { + .ndo_open = mxl_eth_open, + .ndo_stop = mxl_eth_stop, + .ndo_start_xmit = mxl_eth_start_xmit, +}; + +static int mxl_eth_create_ndev(struct platform_device *pdev, + struct device_node *np, + struct net_device **ndev_out) +{ + struct net_device *ndev; + struct eth_priv *priv; + int ret; + + ndev = devm_alloc_etherdev_mqs(&pdev->dev, sizeof(struct eth_priv), + MXL_NUM_TX_RING, MXL_NUM_RX_RING); + if (!ndev) { + dev_err(&pdev->dev, "alloc_etherdev_mq failed\n"); + return -ENOMEM; + } + + ndev->netdev_ops = &mxl_eth_netdev_ops; + ndev->watchdog_timeo = ETH_TX_TIMEOUT; + ndev->max_mtu = ETH_FRAME_LEN; + ndev->min_mtu = ETH_MIN_MTU; + SET_NETDEV_DEV(ndev, &pdev->dev); + + priv = netdev_priv(ndev); + priv->pdev = pdev; + priv->np = np; + + ret = register_netdev(ndev); + if (ret) { + dev_err(&pdev->dev, "failed to register net device\n"); + return ret; + } + + *ndev_out = ndev; + return 0; +} + +static void mxl_eth_cleanup(struct mxl_eth_drvdata *drvdata) +{ + int i; + + for (i = 0; i < MXL_NUM_PORT && drvdata->ndevs[i]; i++) { + unregister_netdev(drvdata->ndevs[i]); + drvdata->ndevs[i] = NULL; + } +} + +static int mxl_eth_probe(struct platform_device *pdev) +{ + struct mxl_eth_drvdata *drvdata; + struct reset_control *rst; + struct net_device *ndev; + struct device_node *np; + int ret, i; + + drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); + if (!drvdata) + return -ENOMEM; + + drvdata->clks = devm_clk_get_enabled(&pdev->dev, "ethif"); + if (IS_ERR(drvdata->clks)) + return dev_err_probe(&pdev->dev, PTR_ERR(drvdata->clks), + "failed to get/enable clock\n"); + + rst = devm_reset_control_get_optional(&pdev->dev, NULL); + if (IS_ERR(rst)) { + dev_err(&pdev->dev, + "failed to get optional reset control: %ld\n", + PTR_ERR(rst)); + ret = PTR_ERR(rst); + goto err_cleanup; + } + + if (rst) { + ret = reset_control_assert(rst); + if (ret) + goto err_cleanup; + + udelay(1); + + ret = reset_control_deassert(rst); + if (ret) + goto err_cleanup; + } + + platform_set_drvdata(pdev, drvdata); + + i = 0; + for_each_available_child_of_node(pdev->dev.of_node, np) { + if (!of_device_is_compatible(np, "mxl,eth-mac")) + continue; + + ret = mxl_eth_create_ndev(pdev, np, &ndev); + if (ret) + goto err_cleanup; + + drvdata->ndevs[i++] = ndev; + if (i >= MXL_NUM_PORT) + break; + } + + return 0; + +err_cleanup: + mxl_eth_cleanup(drvdata); + return ret; +} + +static void mxl_eth_remove(struct platform_device *pdev) +{ + struct mxl_eth_drvdata *drvdata = platform_get_drvdata(pdev); + + mxl_eth_cleanup(drvdata); +} + +/* Device Tree match table */ +static const struct of_device_id mxl_eth_of_match[] = { + { .compatible = "mxl,lgm-eth" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, mxl_eth_of_match); + +/* Platform driver struct */ +static struct platform_driver mxl_eth_drv = { + .probe = mxl_eth_probe, + .remove = mxl_eth_remove, + .driver = { + .name = KBUILD_MODNAME, + .of_match_table = mxl_eth_of_match, + }, +}; + +module_platform_driver(mxl_eth_drv); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Ethernet driver for MxL SoC"); -- 2.34.1