From nobody Wed Dec 17 19:39:44 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D369BC27C55 for ; Wed, 16 Aug 2023 21:57:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346711AbjHPV4v (ORCPT ); Wed, 16 Aug 2023 17:56:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48430 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346685AbjHPV4P (ORCPT ); Wed, 16 Aug 2023 17:56:15 -0400 Received: from mx0a-002e3701.pphosted.com (mx0a-002e3701.pphosted.com [148.163.147.86]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6EFC6271D; Wed, 16 Aug 2023 14:56:13 -0700 (PDT) Received: from pps.filterd (m0148663.ppops.net [127.0.0.1]) by mx0a-002e3701.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 37GL2Jb5006163; Wed, 16 Aug 2023 21:55:47 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hpe.com; h=from : to : subject : date : message-id : in-reply-to : references : mime-version; s=pps0720; bh=15BJWwCisxol9Y1fVdTADtWs3sLlWGzB6kh21OicCww=; b=lVa9j9VfvYQlE4Yjr6qKgHPnamNZvCSdjJBs1XrXXiZKDBo+JYzzzAhX0hEuyCMLx1y8 LRPc75oCRLO0UzZ20kyol5DkxSg+4muXb5ghr/VK919YCqC2xCrcYwbS6/tDXnHfmggv HCZiiUSRL65n910eFEzknSpeg1Kx1yC9SMCv+y5IInHMv8HbgrYSTgRvf14qrdbiE0EE XTtfG/g5h+t7/uaySgFoupKcpGVqgIgk0LudfqGdIU+cYLyXF9NbOS/z+OfojnB4v0A0 6oVVwj+LshVkQFBklcnaICRVWsr7wvVdI+cap8Br/aH6jwtoQmNsq4U2UoxgaktU3R3H Tg== Received: from p1lg14878.it.hpe.com ([16.230.97.204]) by mx0a-002e3701.pphosted.com (PPS) with ESMTPS id 3sh07b3sgr-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 16 Aug 2023 21:55:47 +0000 Received: from p1lg14886.dc01.its.hpecorp.net (unknown [10.119.18.237]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by p1lg14878.it.hpe.com (Postfix) with ESMTPS id 1CDA7D2DF; Wed, 16 Aug 2023 21:55:46 +0000 (UTC) Received: from hpe.com (unknown [16.231.227.39]) by p1lg14886.dc01.its.hpecorp.net (Postfix) with ESMTP id 61CC080C764; Wed, 16 Aug 2023 21:55:45 +0000 (UTC) From: nick.hawkins@hpe.com To: christophe.jaillet@wanadoo.fr, simon.horman@corigine.com, andrew@lunn.ch, verdun@hpe.com, nick.hawkins@hpe.com, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, conor+dt@kernel.org, netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 1/5] dt-bindings: net: Add HPE GXP UMAC MDIO Date: Wed, 16 Aug 2023 16:52:16 -0500 Message-Id: <20230816215220.114118-2-nick.hawkins@hpe.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230816215220.114118-1-nick.hawkins@hpe.com> References: <20230816215220.114118-1-nick.hawkins@hpe.com> X-Proofpoint-GUID: kCzjZKcd_xUvIl_aQtS8pE5_ViDE9c52 X-Proofpoint-ORIG-GUID: kCzjZKcd_xUvIl_aQtS8pE5_ViDE9c52 X-Proofpoint-UnRewURL: 0 URL was un-rewritten MIME-Version: 1.0 X-HPE-SCL: -1 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.267,Aquarius:18.0.957,Hydra:6.0.601,FMLib:17.11.176.26 definitions=2023-08-16_19,2023-08-15_02,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 mlxscore=0 phishscore=0 adultscore=0 spamscore=0 malwarescore=0 priorityscore=1501 lowpriorityscore=0 mlxlogscore=999 suspectscore=0 bulkscore=0 clxscore=1015 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2306200000 definitions=main-2308160195 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Nick Hawkins Provide access to the register regions and interrupt for Universal MAC(UMAC). The driver under the hpe,gxp-umac-mdio will provide an interface for managing both the internal and external PHYs. Signed-off-by: Nick Hawkins Reviewed-by: Conor Dooley Reviewed-by: Andrew Lunn --- v3: * no change v2: * remove | * remove unecessary description --- .../bindings/net/hpe,gxp-umac-mdio.yaml | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/hpe,gxp-umac-mdio= .yaml diff --git a/Documentation/devicetree/bindings/net/hpe,gxp-umac-mdio.yaml b= /Documentation/devicetree/bindings/net/hpe,gxp-umac-mdio.yaml new file mode 100644 index 000000000000..a8ab93c681bf --- /dev/null +++ b/Documentation/devicetree/bindings/net/hpe,gxp-umac-mdio.yaml @@ -0,0 +1,50 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/net/hpe,gxp-umac-mdio.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: HPE GXP UMAC MDIO Controller + +maintainers: + - Nicholas Hawkins + +description: + The HPE GXP Unversal MAC (UMAC) MDIO controller provides a configuration + path for both external PHY's and SERDES connected PHY's. + +allOf: + - $ref: mdio.yaml# + +properties: + compatible: + const: hpe,gxp-umac-mdio + + reg: + maxItems: 1 + + resets: + maxItems: 1 + +required: + - compatible + - reg + - "#address-cells" + - "#size-cells" + +unevaluatedProperties: false + +examples: + - | + mdio0: mdio@4080 { + compatible =3D "hpe,gxp-umac-mdio"; + reg =3D <0x4080 0x10>; + #address-cells =3D <1>; + #size-cells =3D <0>; + + ethphy0: ethernet-phy@0 { + compatible =3D "ethernet-phy-ieee802.3-c22"; + phy-mode =3D "sgmii"; + reg =3D <0>; + }; + }; --=20 2.17.1 From nobody Wed Dec 17 19:39:44 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 347E1C27C6F for ; Wed, 16 Aug 2023 21:57:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346748AbjHPV4z (ORCPT ); Wed, 16 Aug 2023 17:56:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33490 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346702AbjHPV4a (ORCPT ); Wed, 16 Aug 2023 17:56:30 -0400 Received: from mx0b-002e3701.pphosted.com (mx0b-002e3701.pphosted.com [148.163.143.35]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 149C32705; Wed, 16 Aug 2023 14:56:29 -0700 (PDT) Received: from pps.filterd (m0134424.ppops.net [127.0.0.1]) by mx0b-002e3701.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 37GFGICY021936; Wed, 16 Aug 2023 21:56:17 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hpe.com; h=from : to : subject : date : message-id : in-reply-to : references; s=pps0720; bh=rHqtPVdzrJfxM8TrsW0yWtuH3oVT4O+D2GL5zIPyn7c=; b=clJ8YA/KnsHT88Yob4X++RE/tjkgPIlK0tWURr1OG9cvhvgmMRGq6IyTceBE6sseQDdt Z+RlyRJus40znLImQuCUf0wE2q/cyQuofuNJozxJtMve9lHfCfFEATbFgpc5LkktyP+P tteVtMR6n1SDODW2iDcrhtf5X0r5Dq0O/qYqbBm3d4NqITE5oJplwce/YXrMx6HdiG3W lEzQuywp6CnFQGVrSBh26bJMrKS6qGXqm+ww/R62EUFOKxs21maxwMeHaOepFgafSOMp SXn7WdFg4ZhD8kRAKuzdPhxMzMPBwN+Ug5btWIUyVWY7mG5WxLtkx5nJrqDA6HD5lS8n wQ== Received: from p1lg14880.it.hpe.com ([16.230.97.201]) by mx0b-002e3701.pphosted.com (PPS) with ESMTPS id 3sh0y039d4-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 16 Aug 2023 21:56:17 +0000 Received: from p1lg14886.dc01.its.hpecorp.net (unknown [10.119.18.237]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by p1lg14880.it.hpe.com (Postfix) with ESMTPS id 06B6A800189; Wed, 16 Aug 2023 21:55:46 +0000 (UTC) Received: from hpe.com (unknown [16.231.227.39]) by p1lg14886.dc01.its.hpecorp.net (Postfix) with ESMTP id 12814800189; Wed, 16 Aug 2023 21:55:46 +0000 (UTC) From: nick.hawkins@hpe.com To: christophe.jaillet@wanadoo.fr, simon.horman@corigine.com, andrew@lunn.ch, verdun@hpe.com, nick.hawkins@hpe.com, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, conor+dt@kernel.org, netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 2/5] net: hpe: Add GXP UMAC MDIO Date: Wed, 16 Aug 2023 16:52:17 -0500 Message-Id: <20230816215220.114118-3-nick.hawkins@hpe.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230816215220.114118-1-nick.hawkins@hpe.com> References: <20230816215220.114118-1-nick.hawkins@hpe.com> X-Proofpoint-GUID: dKnKWSKLeG3hkqzXJD_JtgApmGy5mL2x X-Proofpoint-ORIG-GUID: dKnKWSKLeG3hkqzXJD_JtgApmGy5mL2x X-HPE-SCL: -1 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.267,Aquarius:18.0.957,Hydra:6.0.601,FMLib:17.11.176.26 definitions=2023-08-16_19,2023-08-15_02,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 lowpriorityscore=0 mlxlogscore=999 mlxscore=0 malwarescore=0 impostorscore=0 clxscore=1015 priorityscore=1501 adultscore=0 spamscore=0 phishscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2306200000 definitions=main-2308160196 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Nick Hawkins The GXP contains two Universal Ethernet MACs that can be connected externally to several physical devices. From an external interface perspective the BMC provides two SERDES interface connections capable of either SGMII or 1000Base-X operation. The BMC also provides a RMII interface for sideband connections to external Ethernet controllers. The primary MAC (umac0) can be mapped to either SGMII/1000-BaseX SERDES interface. The secondary MAC (umac1) can be mapped to only the second SGMII/1000-Base X Serdes interface or it can be mapped for RMII sideband. The MDIO(mdio0) interface from the primary MAC (umac0) is used for external PHY status and configuration. The MDIO(mdio1) interface from the secondary MAC (umac1) is routed to the SGMII/100Base-X IP blocks on the two SERDES interface connections. Signed-off-by: Nick Hawkins --- v3: *Remove Kconfig and Makefile changes for ethernet *Fixed Kconfig alignment and COMPILE_TEST issue *removed raw write/reads *Put consistent spacing in Kconfing help description v2: *Move from /ethernet to /mdio *Add COMPILE_TEST to Kconfig *Fix christmas tree variable declaration layout *return the error code instead of using defined where possible *Modify Kconfig to add depends on OF_MDIO && HAS_IOMEM && MDIO_DEVRES *replace , with ; *use devm_of_mdiobus_register *remove umac_mdio_remove function *remove of_ptr_match *fix size_of on alloc --- drivers/net/mdio/Kconfig | 13 +++ drivers/net/mdio/Makefile | 1 + drivers/net/mdio/mdio-gxp-umac.c | 142 +++++++++++++++++++++++++++++++ 3 files changed, 156 insertions(+) create mode 100644 drivers/net/mdio/mdio-gxp-umac.c diff --git a/drivers/net/mdio/Kconfig b/drivers/net/mdio/Kconfig index 9ff2e6f22f3f..c3bf91c86fde 100644 --- a/drivers/net/mdio/Kconfig +++ b/drivers/net/mdio/Kconfig @@ -115,6 +115,19 @@ config MDIO_GPIO To compile this driver as a module, choose M here: the module will be called mdio-gpio. =20 +config GXP_UMAC_MDIO + tristate "GXP UMAC mdio support" + depends on ARCH_HPE || COMPILE_TEST + depends on OF_MDIO && HAS_IOMEM + depends on MDIO_DEVRES + help + Say y here to support the GXP UMAC MDIO bus. The + MDIO (mdio0) interface from the primary MAC (umac0) + is used for external PHY status and configuration. + The MDIO (mdio1) interface from the secondary MAC + (umac1) is routed to the SGMII/100Base-X IP blocks + on the two SERDES interface connections. + config MDIO_HISI_FEMAC tristate "Hisilicon FEMAC MDIO bus controller" depends on HAS_IOMEM && OF_MDIO diff --git a/drivers/net/mdio/Makefile b/drivers/net/mdio/Makefile index 7d4cb4c11e4e..4d00299e327f 100644 --- a/drivers/net/mdio/Makefile +++ b/drivers/net/mdio/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_MDIO_BCM_UNIMAC) +=3D mdio-bcm-unimac.o obj-$(CONFIG_MDIO_BITBANG) +=3D mdio-bitbang.o obj-$(CONFIG_MDIO_CAVIUM) +=3D mdio-cavium.o obj-$(CONFIG_MDIO_GPIO) +=3D mdio-gpio.o +obj-$(CONFIG_GXP_UMAC_MDIO) +=3D mdio-gxp-umac.o obj-$(CONFIG_MDIO_HISI_FEMAC) +=3D mdio-hisi-femac.o obj-$(CONFIG_MDIO_I2C) +=3D mdio-i2c.o obj-$(CONFIG_MDIO_IPQ4019) +=3D mdio-ipq4019.o diff --git a/drivers/net/mdio/mdio-gxp-umac.c b/drivers/net/mdio/mdio-gxp-u= mac.c new file mode 100644 index 000000000000..bd1996e937c1 --- /dev/null +++ b/drivers/net/mdio/mdio-gxp-umac.c @@ -0,0 +1,142 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright (C) 2023 Hewlett-Packard Development Company, L.P. */ + +#include +#include +#include +#include +#include +#include + +#define UMAC_MII 0x00 /* R/W MII Register */ +#define UMAC_MII_PHY_ADDR_MASK 0x001F0000 +#define UMAC_MII_PHY_ADDR_SHIFT 16 +#define UMAC_MII_MOWNER BIT(9) +#define UMAC_MII_MRNW BIT(8) +#define UMAC_MII_REG_ADDR_MASK 0x0000001F +#define UMAC_MII_DATA 0x04 /* R/W MII Data Register */ + +struct umac_mdio_priv { + void __iomem *base; +}; + +static int umac_mdio_read(struct mii_bus *bus, int phy_id, int reg) +{ + struct umac_mdio_priv *umac_mdio =3D bus->priv; + unsigned int status; + unsigned int value; + int ret; + + status =3D readl(umac_mdio->base + UMAC_MII); + + status &=3D ~(UMAC_MII_PHY_ADDR_MASK | UMAC_MII_REG_ADDR_MASK); + status |=3D ((phy_id << UMAC_MII_PHY_ADDR_SHIFT) & + UMAC_MII_PHY_ADDR_MASK); + status |=3D (reg & UMAC_MII_REG_ADDR_MASK); + status |=3D UMAC_MII_MRNW; /* set bit for read mode */ + writel(status, umac_mdio->base + UMAC_MII); + + status |=3D UMAC_MII_MOWNER; /* set bit to activate mii transfer */ + writel(status, umac_mdio->base + UMAC_MII); + + ret =3D readl_poll_timeout(umac_mdio->base + UMAC_MII, status, + !(status & UMAC_MII_MOWNER), 1000, 100000); + if (ret) { + dev_err(bus->parent, "mdio read time out\n"); + return ret; + } + + value =3D readl(umac_mdio->base + UMAC_MII_DATA); + return value; +} + +static int umac_mdio_write(struct mii_bus *bus, int phy_id, int reg, u16 v= alue) +{ + struct umac_mdio_priv *umac_mdio =3D bus->priv; + unsigned int status; + int ret; + + writel(value, umac_mdio->base + UMAC_MII_DATA); + + status =3D readl(umac_mdio->base + UMAC_MII); + + status &=3D ~(UMAC_MII_PHY_ADDR_MASK | UMAC_MII_REG_ADDR_MASK); + status |=3D ((phy_id << UMAC_MII_PHY_ADDR_SHIFT) & + UMAC_MII_PHY_ADDR_MASK); + status |=3D (reg & UMAC_MII_REG_ADDR_MASK); + status &=3D ~UMAC_MII_MRNW; /* clear bit for write mode */ + writel(status, umac_mdio->base + UMAC_MII); + + status |=3D UMAC_MII_MOWNER; /* set bit to activate mii transfer */ + writel(status, umac_mdio->base + UMAC_MII); + + ret =3D readl_poll_timeout(umac_mdio->base + UMAC_MII, status, + !(status & UMAC_MII_MOWNER), 1000, 100000); + if (ret) + dev_err(bus->parent, "mdio read time out\n"); + + return ret; +} + +static int umac_mdio_probe(struct platform_device *pdev) +{ + struct umac_mdio_priv *umac_mdio; + struct device *dev =3D &pdev->dev; + struct resource *res; + struct mii_bus *bus; + int ret; + + res =3D platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "fail to get resource\n"); + return -ENODEV; + } + + bus =3D devm_mdiobus_alloc_size(&pdev->dev, sizeof(*umac_mdio)); + if (!bus) { + dev_err(&pdev->dev, "failed to alloc mii bus\n"); + return -ENOMEM; + } + + snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(&pdev->dev)); + + bus->name =3D dev_name(&pdev->dev); + bus->read =3D umac_mdio_read; + bus->write =3D umac_mdio_write; + bus->parent =3D &pdev->dev; + umac_mdio =3D bus->priv; + umac_mdio->base =3D devm_ioremap_resource(&pdev->dev, res); + if (!umac_mdio->base) { + dev_err(&pdev->dev, "failed to do ioremap\n"); + return -ENODEV; + } + + ret =3D devm_of_mdiobus_register(dev, bus, pdev->dev.of_node); + + if (ret < 0) { + dev_err(&pdev->dev, "Cannot register MDIO bus (%d)\n", ret); + return ret; + } + + return 0; +} + +static const struct of_device_id umac_mdio_of_matches[] =3D { + { .compatible =3D "hpe,gxp-umac-mdio", }, + {}, +}; +MODULE_DEVICE_TABLE(of, umac_mdio_of_matches); + +static struct platform_driver umac_driver =3D { + .driver =3D { + .name =3D "gxp-umac-mdio", + .of_match_table =3D umac_mdio_of_matches, + }, + .probe =3D umac_mdio_probe, +}; + +module_platform_driver(umac_driver); + +MODULE_AUTHOR("Nick Hawkins "); +MODULE_DESCRIPTION("HPE GXP UMAC MDIO driver"); +MODULE_LICENSE("GPL"); --=20 2.17.1 From nobody Wed Dec 17 19:39:44 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9361CC27C54 for ; Wed, 16 Aug 2023 21:57:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245698AbjHPV4t (ORCPT ); Wed, 16 Aug 2023 17:56:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48424 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346689AbjHPV4P (ORCPT ); Wed, 16 Aug 2023 17:56:15 -0400 Received: from mx0a-002e3701.pphosted.com (mx0a-002e3701.pphosted.com [148.163.147.86]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 52D841FC3; Wed, 16 Aug 2023 14:56:13 -0700 (PDT) Received: from pps.filterd (m0148663.ppops.net [127.0.0.1]) by mx0a-002e3701.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 37GG7AX8006141; Wed, 16 Aug 2023 21:55:48 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hpe.com; h=from : to : subject : date : message-id : in-reply-to : references : mime-version; s=pps0720; bh=YGcM0JtQz2iRHlYmQwbApVV7mHlgmm2fK96UcbfHXBE=; b=PiR2vUplJp1S/S4vmzq3MhAvTGUFtfljuMHD3FTNd4aopXitvaza9Ty9gaBThvqB+VUT S1fMdof0cjLAzn+pxPpUuGhgE7IlXGTSWr+mbt25jgCGl8RN+X2JvYzIw6TX9hfiGoqi psYyGY1g7U5Ykb9NWgF09Dbub3B7snehU/fnEusbhwEBhuC+xHpRvJ/qH3B8aJuRNL+1 sS95YF2+/7sOzaPS0F+iOjkNSrtlYg+7hpFGlIp3JMWvf8XpXLfWA8Rsaaqt/oPb9ehD fazEX10HhQBgqXRxE/az5HAqNgHRjR6D9Io0x3e9+M+TwYdFjegdLb47MfesVongHqCk qw== Received: from p1lg14878.it.hpe.com ([16.230.97.204]) by mx0a-002e3701.pphosted.com (PPS) with ESMTPS id 3sh07b3sgt-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 16 Aug 2023 21:55:48 +0000 Received: from p1lg14886.dc01.its.hpecorp.net (unknown [10.119.18.237]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by p1lg14878.it.hpe.com (Postfix) with ESMTPS id C0279D2E4; Wed, 16 Aug 2023 21:55:47 +0000 (UTC) Received: from hpe.com (unknown [16.231.227.39]) by p1lg14886.dc01.its.hpecorp.net (Postfix) with ESMTP id B5EDC80BA10; Wed, 16 Aug 2023 21:55:46 +0000 (UTC) From: nick.hawkins@hpe.com To: christophe.jaillet@wanadoo.fr, simon.horman@corigine.com, andrew@lunn.ch, verdun@hpe.com, nick.hawkins@hpe.com, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, conor+dt@kernel.org, netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 3/5] dt-bindings: net: Add HPE GXP UMAC Date: Wed, 16 Aug 2023 16:52:18 -0500 Message-Id: <20230816215220.114118-4-nick.hawkins@hpe.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230816215220.114118-1-nick.hawkins@hpe.com> References: <20230816215220.114118-1-nick.hawkins@hpe.com> X-Proofpoint-GUID: Xs2m14yHU1fIouAa3BX2ifJe2SkQDUnO X-Proofpoint-ORIG-GUID: Xs2m14yHU1fIouAa3BX2ifJe2SkQDUnO X-Proofpoint-UnRewURL: 0 URL was un-rewritten MIME-Version: 1.0 X-HPE-SCL: -1 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.267,Aquarius:18.0.957,Hydra:6.0.601,FMLib:17.11.176.26 definitions=2023-08-16_19,2023-08-15_02,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 mlxscore=0 phishscore=0 adultscore=0 spamscore=0 malwarescore=0 priorityscore=1501 lowpriorityscore=0 mlxlogscore=999 suspectscore=0 bulkscore=0 clxscore=1015 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2306200000 definitions=main-2308160195 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Nick Hawkins Provide access to the register regions and interrupt for Universal MAC(UMAC). The driver under the hpe,gxp-umac binding will provide an interface for sending and receiving networking data from both of the UMACs on the system. Signed-off-by: Nick Hawkins Reviewed-by: Conor Dooley --- v3: *Remove MDIO references *Modify description for use-ncsi v2: *Move mac-addresses into ports *Remove | where not needed --- .../devicetree/bindings/net/hpe,gxp-umac.yaml | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/hpe,gxp-umac.yaml diff --git a/Documentation/devicetree/bindings/net/hpe,gxp-umac.yaml b/Docu= mentation/devicetree/bindings/net/hpe,gxp-umac.yaml new file mode 100644 index 000000000000..d3f72694c814 --- /dev/null +++ b/Documentation/devicetree/bindings/net/hpe,gxp-umac.yaml @@ -0,0 +1,97 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/net/hpe,gxp-umac.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: HPE GXP Unified MAC Controller + +maintainers: + - Nick Hawkins + +description: + HPE GXP 802.3 10/100/1000T Ethernet Unifed MAC controller. + Device node of the controller has following properties. + +properties: + compatible: + const: hpe,gxp-umac + + use-ncsi: + type: boolean + description: + Indicates if the device should use NCSI (Network Controlled + Sideband Interface). Only one of the two MACs can support + NCSI and it requires there to be a physical connection on + the board to be present. This property indicates that + physical connection is present and should be used. + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + ethernet-ports: + type: object + additionalProperties: false + description: Ethernet ports to PHY + + properties: + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + + patternProperties: + "^port@[0-1]$": + type: object + additionalProperties: false + description: Port to PHY + + properties: + reg: + minimum: 0 + maximum: 1 + + phy-handle: + maxItems: 1 + + mac-address: true + + required: + - reg + - phy-handle + +additionalProperties: false + +required: + - compatible + - reg + - interrupts + - ethernet-ports + +examples: + - | + ethernet@4000 { + compatible =3D "hpe,gxp-umac"; + reg =3D <0x4000 0x80>; + interrupts =3D <22>; + ethernet-ports { + #address-cells =3D <1>; + #size-cells =3D <0>; + + port@0 { + reg =3D <0>; + phy-handle =3D <&int_phy0>; + mac-address =3D [00 00 00 00 00 00]; + }; + + port@1 { + reg =3D <1>; + phy-handle =3D <&ext_phy1>; + mac-address =3D [00 00 00 00 00 00]; + }; + }; + }; --=20 2.17.1 From nobody Wed Dec 17 19:39:44 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 14CD0C27C6D for ; Wed, 16 Aug 2023 21:57:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346729AbjHPV4x (ORCPT ); Wed, 16 Aug 2023 17:56:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48438 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346694AbjHPV4R (ORCPT ); Wed, 16 Aug 2023 17:56:17 -0400 Received: from mx0a-002e3701.pphosted.com (mx0a-002e3701.pphosted.com [148.163.147.86]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3CC362723; Wed, 16 Aug 2023 14:56:14 -0700 (PDT) Received: from pps.filterd (m0134420.ppops.net [127.0.0.1]) by mx0b-002e3701.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 37GH20Oi011663; Wed, 16 Aug 2023 21:55:49 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hpe.com; h=from : to : subject : date : message-id : in-reply-to : references; s=pps0720; bh=mIYrcVXlhgagGdXZFxeAiOfWQRG8/fjsfcYhggEVzv4=; b=ccQhGPqicXTpMXItiXS8pgVwSyPEhSBqlKk1WWADoDfCphJEG0ty+FgAxjIkw/LxAcbl S9YG0+nba8SV9VlBv4pvAk7B2JVg3t5VE6BSFRIGlGRS+K9dYEQtvMlOYP3GXY86WFjR ZtZa4tqHgIrCmivX5yDqe0ybMIGvAkVqX3w5Lg4Ys7LNCo/UoVBL0rcYf+F3oyCTvdHt KsFAHfTblS3lcEcmviSAYMlTvJI+ZILXA8VLVw3dujd4gS1kyLkCivSTRI3u1RQoOOnH 68Pq400wuSz1Nq/8ahGOa0f+Ro5pEV4yjYRQnbNxwbfFkblo/0wkVPbhhVtFO2BtMSOO Bw== Received: from p1lg14880.it.hpe.com ([16.230.97.201]) by mx0b-002e3701.pphosted.com (PPS) with ESMTPS id 3sgwsmd98e-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 16 Aug 2023 21:55:49 +0000 Received: from p1lg14886.dc01.its.hpecorp.net (unknown [10.119.18.237]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by p1lg14880.it.hpe.com (Postfix) with ESMTPS id 6EF78801711; Wed, 16 Aug 2023 21:55:48 +0000 (UTC) Received: from hpe.com (unknown [16.231.227.39]) by p1lg14886.dc01.its.hpecorp.net (Postfix) with ESMTP id 69E8F800237; Wed, 16 Aug 2023 21:55:47 +0000 (UTC) From: nick.hawkins@hpe.com To: christophe.jaillet@wanadoo.fr, simon.horman@corigine.com, andrew@lunn.ch, verdun@hpe.com, nick.hawkins@hpe.com, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, conor+dt@kernel.org, netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 4/5] net: hpe: Add GXP UMAC Driver Date: Wed, 16 Aug 2023 16:52:19 -0500 Message-Id: <20230816215220.114118-5-nick.hawkins@hpe.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230816215220.114118-1-nick.hawkins@hpe.com> References: <20230816215220.114118-1-nick.hawkins@hpe.com> X-Proofpoint-ORIG-GUID: 1a0MCIreA3w-Xhx9rA8CWO9FfwWILB3w X-Proofpoint-GUID: 1a0MCIreA3w-Xhx9rA8CWO9FfwWILB3w X-HPE-SCL: -1 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.267,Aquarius:18.0.957,Hydra:6.0.601,FMLib:17.11.176.26 definitions=2023-08-16_19,2023-08-15_02,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 adultscore=0 phishscore=0 priorityscore=1501 impostorscore=0 suspectscore=0 spamscore=0 mlxscore=0 bulkscore=0 malwarescore=0 mlxlogscore=999 lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2306200000 definitions=main-2308160195 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Nick Hawkins The GXP contains two Ethernet MACs that can be connected externally to several physical devices. From an external interface perspective the BMC provides two SERDES interface connections capable of either SGMII or 1000Base-X operation. The BMC also provides a RMII interface for sideband connections to external Ethernet controllers. The primary MAC (umac0) can be mapped to either SGMII/1000-BaseX SERDES interface. The secondary MAC (umac1) can be mapped to only the second SGMII/1000-Base X Serdes interface or it can be mapped for RMII sideband. Signed-off-by: Nick Hawkins --- v3: *Modify Kconfig and Makefile for ethernet directory for hpe *Remove version driver info *Removed direct writes to PHYs in MAC driver *Removed fixed-link code *Fixed code alignment *Updated commit description *Removed Direct PHY Configuration v2: *Change to reverse christmas tree format *Fix use of cpu_to_le32 *Add use of __le32 variable *use devm_alloc_etherdev *Removed remove function *Used devm_register_netdev *Removed unnecessary variable err *Removed free_netdev *Fixed compatible string *Removed of_match_ptr *Fixed return on failure to register --- drivers/net/ethernet/Kconfig | 1 + drivers/net/ethernet/Makefile | 1 + drivers/net/ethernet/hpe/Kconfig | 32 ++ drivers/net/ethernet/hpe/Makefile | 1 + drivers/net/ethernet/hpe/gxp-umac.c | 759 ++++++++++++++++++++++++++++ drivers/net/ethernet/hpe/gxp-umac.h | 89 ++++ 6 files changed, 883 insertions(+) create mode 100644 drivers/net/ethernet/hpe/Kconfig create mode 100644 drivers/net/ethernet/hpe/Makefile create mode 100644 drivers/net/ethernet/hpe/gxp-umac.c create mode 100644 drivers/net/ethernet/hpe/gxp-umac.h diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig index 5a274b99f299..b4921b84be51 100644 --- a/drivers/net/ethernet/Kconfig +++ b/drivers/net/ethernet/Kconfig @@ -80,6 +80,7 @@ source "drivers/net/ethernet/fujitsu/Kconfig" source "drivers/net/ethernet/fungible/Kconfig" source "drivers/net/ethernet/google/Kconfig" source "drivers/net/ethernet/hisilicon/Kconfig" +source "drivers/net/ethernet/hpe/Kconfig" source "drivers/net/ethernet/huawei/Kconfig" source "drivers/net/ethernet/i825xx/Kconfig" source "drivers/net/ethernet/ibm/Kconfig" diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile index 0d872d4efcd1..ce97bbae2cdc 100644 --- a/drivers/net/ethernet/Makefile +++ b/drivers/net/ethernet/Makefile @@ -45,6 +45,7 @@ obj-$(CONFIG_NET_VENDOR_FUJITSU) +=3D fujitsu/ obj-$(CONFIG_NET_VENDOR_FUNGIBLE) +=3D fungible/ obj-$(CONFIG_NET_VENDOR_GOOGLE) +=3D google/ obj-$(CONFIG_NET_VENDOR_HISILICON) +=3D hisilicon/ +obj-$(CONFIG_NET_VENDOR_HPE) +=3D hpe/ obj-$(CONFIG_NET_VENDOR_HUAWEI) +=3D huawei/ obj-$(CONFIG_NET_VENDOR_IBM) +=3D ibm/ obj-$(CONFIG_NET_VENDOR_INTEL) +=3D intel/ diff --git a/drivers/net/ethernet/hpe/Kconfig b/drivers/net/ethernet/hpe/Kc= onfig new file mode 100644 index 000000000000..6d24ef413067 --- /dev/null +++ b/drivers/net/ethernet/hpe/Kconfig @@ -0,0 +1,32 @@ +config NET_VENDOR_HPE + bool "HPE device" + default y + depends on ARCH_HPE + help + Say y here to support the HPE network devices. + The GXP contains two Ethernet MACs that can be + connected externally to several physical devices. + From an external interface perspective the BMC + provides two SERDES interface connections capable + of either SGMII or 1000Base-X operation. The BMC + also provides a RMII interface for sideband + connections to external Ethernet controllers. + +if NET_VENDOR_HPE + +config GXP_UMAC + tristate "GXP UMAC support" + depends on ARCH_HPE || COMPILE_TEST + select CRC32 + select MII + select PHYLIB + select GXP_UMAC_MDIO + help + Say y here to support the GXP UMACs interface. The + primary MAC (umac0) can be mapped to either + SGMII/1000-BaseX SERDES interface. The secondary MAC + (umac1) can be mapped to only the second + SGMII/1000-Base X Serdes interface or it can be + mapped for RMII sideband. + +endif diff --git a/drivers/net/ethernet/hpe/Makefile b/drivers/net/ethernet/hpe/M= akefile new file mode 100644 index 000000000000..e84bb86f82bc --- /dev/null +++ b/drivers/net/ethernet/hpe/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_GXP_UMAC) +=3D gxp-umac.o diff --git a/drivers/net/ethernet/hpe/gxp-umac.c b/drivers/net/ethernet/hpe= /gxp-umac.c new file mode 100644 index 000000000000..148ad36a73c6 --- /dev/null +++ b/drivers/net/ethernet/hpe/gxp-umac.c @@ -0,0 +1,759 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright (C) 2023 Hewlett-Packard Enterprise Development Company, L.P.= */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "gxp-umac.h" + +#define DRV_MODULE_NAME "gxp-umac" + +#define NUMBER_OF_PORTS 2 +#define EXTERNAL_PORT 1 +#define INTERNAL_PORT 0 + +struct umac_priv { + void __iomem *base; + int irq; + struct platform_device *pdev; + struct umac_tx_descs *tx_descs; + struct umac_rx_descs *rx_descs; + dma_addr_t tx_descs_dma_addr; + dma_addr_t rx_descs_dma_addr; + unsigned int tx_cur; + unsigned int tx_done; + unsigned int rx_cur; + struct napi_struct napi; + struct net_device *ndev; + struct phy_device *phy_dev; + struct phy_device *int_phy_dev; + struct ncsi_dev *ncsidev; + bool use_ncsi; +}; + +static void umac_get_drvinfo(struct net_device *ndev, + struct ethtool_drvinfo *info) +{ + strscpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); +} + +static struct net_device_stats *umac_get_stats(struct net_device *ndev) +{ + return &ndev->stats; +} + +static int umac_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd) +{ + if (!netif_running(ndev)) + return -EINVAL; + + if (!ndev->phydev) + return -ENODEV; + + return phy_mii_ioctl(ndev->phydev, ifr, cmd); +} + +static void umac_set_mac_address(struct net_device *ndev, void *p_addr) +{ + struct umac_priv *umac =3D netdev_priv(ndev); + char *addr =3D (char *)p_addr; + unsigned int value; + + /* update address to register */ + value =3D addr[0] << 8 | addr[1]; + writel(value, umac->base + UMAC_MAC_ADDR_HI); + value =3D addr[2] << 8 | addr[3]; + writel(value, umac->base + UMAC_MAC_ADDR_MID); + value =3D addr[4] << 8 | addr[5]; + writel(value, umac->base + UMAC_MAC_ADDR_LO); +} + +static int umac_eth_mac_addr(struct net_device *ndev, void *p) +{ + struct sockaddr *addr =3D p; + int ret; + + ret =3D eth_prepare_mac_addr_change(ndev, p); + if (ret < 0) + return ret; + + eth_commit_mac_addr_change(ndev, p); + umac_set_mac_address(ndev, addr->sa_data); + + return 0; +} + +static void umac_channel_enable(struct umac_priv *umac) +{ + unsigned int value; + + value =3D readl(umac->base + UMAC_CONFIG_STATUS); + value |=3D UMAC_CFG_TXEN | UMAC_CFG_RXEN; + writel(value, umac->base + UMAC_CONFIG_STATUS); + + /* start processing by writing the ring prompt register */ + writel(0, umac->base + UMAC_RING_PROMPT); +} + +static void umac_channel_disable(struct umac_priv *umac) +{ + writel(0, umac->base + UMAC_CONFIG_STATUS); +} + +static int umac_init_ring_discriptor(struct net_device *ndev) +{ + struct umac_priv *umac =3D netdev_priv(ndev); + struct platform_device *pdev =3D umac->pdev; + + struct umac_tx_desc_entry *ptxdesc; + struct umac_rx_desc_entry *prxdesc; + + unsigned int i; + + if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) { + netdev_err(ndev, "No suitable DMA available\n"); + return -ENOMEM; + } + + umac->tx_descs =3D dma_alloc_coherent(&pdev->dev, + sizeof(struct umac_tx_descs), + &umac->tx_descs_dma_addr, GFP_KERNEL); + if (!umac->tx_descs) + return -ENOMEM; + + umac->rx_descs =3D dma_alloc_coherent(&pdev->dev, + sizeof(struct umac_rx_descs), + &umac->rx_descs_dma_addr, GFP_KERNEL); + if (!umac->rx_descs) { + dma_free_coherent(&pdev->dev, sizeof(struct umac_tx_descs), + umac->tx_descs, + umac->tx_descs_dma_addr); + return -ENOMEM; + } + + for (i =3D 0; i < UMAC_MAX_TX_DESC_ENTRIES; i++) { + ptxdesc =3D &umac->tx_descs->entrylist[i]; + ptxdesc->dmaaddress =3D cpu_to_le32(umac->tx_descs_dma_addr + + offsetof(struct umac_tx_descs, + framelist[i][0])); + } + + for (i =3D 0; i < UMAC_MAX_RX_DESC_ENTRIES; i++) { + prxdesc =3D &umac->rx_descs->entrylist[i]; + prxdesc->dmaaddress =3D cpu_to_le32(umac->rx_descs_dma_addr + + offsetof(struct umac_rx_descs, + framelist[i][0])); + prxdesc->status =3D UMAC_RING_ENTRY_HW_OWN; + prxdesc->count =3D UMAC_MAX_RX_FRAME_SIZE; + } + + umac->tx_cur =3D 0; + umac->tx_done =3D 0; + umac->rx_cur =3D 0; + + return 0; +} + +static int umac_init_hw(struct net_device *ndev) +{ + struct umac_priv *umac =3D netdev_priv(ndev); + unsigned int value; + + /* initialize tx and rx rings to first entry */ + writel(0, umac->base + UMAC_RING_PTR); + + /* clear the missed bit */ + writel(0, umac->base + UMAC_CLEAR_STATUS); + + /* disable checksum generation */ + writel(0, umac->base + UMAC_CKSUM_CONFIG); + + /* write the ring size register */ + value =3D ((UMAC_RING_SIZE_256 << UMAC_TX_RING_SIZE_SHIFT) & + UMAC_TX_RING_SIZE_MASK) | + ((UMAC_RING_SIZE_256 << UMAC_RX_RING_SIZE_SHIFT) & + UMAC_RX_RING_SIZE_MASK); + writel(value, umac->base + UMAC_RING_SIZE); + + /* write rx ring base address */ + writel(umac->rx_descs_dma_addr, + umac->base + UMAC_RX_RING_ADDR); + + /* write tx ring base address */ + writel(umac->tx_descs_dma_addr, + umac->base + UMAC_TX_RING_ADDR); + + /* write burst size */ + writel(0x22, umac->base + UMAC_DMA_CONFIG); + + umac_channel_disable(umac); + + /* disable clocks and gigabit mode (leave channels disabled) */ + value =3D readl(umac->base + UMAC_CONFIG_STATUS); + value &=3D 0xfffff9ff; + writel(value, umac->base + UMAC_CONFIG_STATUS); + udelay(2); + + if (umac->use_ncsi) { + /* set correct tx clock */ + value &=3D UMAC_CFG_TX_CLK_EN; + value &=3D ~UMAC_CFG_GTX_CLK_EN; + value &=3D ~UMAC_CFG_GIGABIT_MODE; /* RMII mode */ + value |=3D UMAC_CFG_FULL_DUPLEX; /* full duplex */ + } else { + value |=3D UMAC_CFG_FULL_DUPLEX; + + if (ndev->phydev->speed =3D=3D SPEED_1000) { + value &=3D ~UMAC_CFG_TX_CLK_EN; + value |=3D UMAC_CFG_GTX_CLK_EN; + value |=3D UMAC_CFG_GIGABIT_MODE; + } else { + value |=3D UMAC_CFG_TX_CLK_EN; + value &=3D ~UMAC_CFG_GTX_CLK_EN; + value &=3D ~UMAC_CFG_GIGABIT_MODE; + } + } + writel(value, umac->base + UMAC_CONFIG_STATUS); + udelay(2); + + umac_channel_enable(umac); + + return 0; +} + +static int umac_start_xmit(struct sk_buff *skb, struct net_device *ndev) +{ + struct umac_priv *umac =3D netdev_priv(ndev); + struct umac_tx_desc_entry *ptxdesc; + unsigned int length; + u8 *pframe; + + ptxdesc =3D &umac->tx_descs->entrylist[umac->tx_cur]; + pframe =3D umac->tx_descs->framelist[umac->tx_cur]; + + length =3D skb->len; + if (length > 1514) { + netdev_err(ndev, "send data %d bytes > 1514, clamp it to 1514\n", + skb->len); + length =3D 1514; + } + + memset(pframe, 0, UMAC_MAX_FRAME_SIZE); + memcpy(pframe, skb->data, length); + + if (length < ETH_ZLEN) + length =3D ETH_ZLEN; /* minimum tx byte */ + + ptxdesc->count =3D length; + ptxdesc->status =3D UMAC_RING_ENTRY_HW_OWN; + ptxdesc->cksumoffset =3D 0; /* disable checksum generation */ + + umac->tx_cur++; + if (umac->tx_cur >=3D UMAC_MAX_TX_DESC_ENTRIES) + umac->tx_cur =3D 0; + + /* if current tx ring buffer is full, stop the queue */ + ptxdesc =3D &umac->tx_descs->entrylist[umac->tx_cur]; + if (ptxdesc->status & UMAC_RING_ENTRY_HW_OWN) + netif_stop_queue(ndev); + + /* start processing by writing the ring prompt register */ + writel(0, umac->base + UMAC_RING_PROMPT); + dev_kfree_skb(skb); + + return NETDEV_TX_OK; +} + +static int umac_rx(struct net_device *ndev, int budget) +{ + struct umac_priv *umac =3D netdev_priv(ndev); + + struct umac_rx_desc_entry *prxdesc; + struct sk_buff *skb; + + unsigned int rxlength; + int rxpktcount =3D 0; + u8 *pframe; + u8 *skb_buf; + + prxdesc =3D &umac->rx_descs->entrylist[umac->rx_cur]; + pframe =3D umac->rx_descs->framelist[umac->rx_cur]; + + while (!(prxdesc->status & UMAC_RING_ENTRY_HW_OWN)) { + rxlength =3D prxdesc->count; + skb =3D netdev_alloc_skb(ndev, rxlength); + if (!skb) { + /* run out of memory */ + ndev->stats.rx_dropped++; + return rxpktcount; + } + + /* make 16 bytes aligned for 14 bytes ethernet header */ + skb_buf =3D skb_put(skb, rxlength); + memcpy(skb_buf, pframe, rxlength); + + skb->protocol =3D eth_type_trans(skb, ndev); + netif_receive_skb(skb); + rxpktcount++; + + prxdesc->status =3D UMAC_RING_ENTRY_HW_OWN; + prxdesc->count =3D UMAC_MAX_FRAME_SIZE; + + ndev->stats.rx_packets++; + ndev->stats.rx_bytes +=3D rxlength; + + /* move to next buffer */ + umac->rx_cur++; + if (umac->rx_cur >=3D UMAC_MAX_RX_DESC_ENTRIES) + umac->rx_cur =3D 0; + + if (rxpktcount >=3D budget) + break; + + prxdesc =3D &umac->rx_descs->entrylist[umac->rx_cur]; + pframe =3D umac->rx_descs->framelist[umac->rx_cur]; + } + /* start processing by writing the ring prompt register */ + writel(0, umac->base + UMAC_RING_PROMPT); + + return rxpktcount; +} + +static void umac_tx_done(struct net_device *ndev) +{ + struct umac_priv *umac =3D netdev_priv(ndev); + + unsigned int txptr; + unsigned int value; + struct umac_tx_desc_entry *ptxdesc; + + value =3D readl(umac->base + UMAC_RING_PTR); + txptr =3D (value & UMAC_TX_RING_PTR_MASK) >> UMAC_TX_RING_PTR_SHIFT; + + ptxdesc =3D &umac->tx_descs->entrylist[umac->tx_done]; + + while (!(ptxdesc->status & UMAC_RING_ENTRY_HW_OWN)) { + if (umac->tx_done =3D=3D txptr) + break; + + ndev->stats.tx_packets++; + ndev->stats.tx_bytes +=3D ptxdesc->count; + + umac->tx_done++; + if (umac->tx_done >=3D UMAC_MAX_TX_DESC_ENTRIES) + umac->tx_done =3D 0; + ptxdesc =3D &umac->tx_descs->entrylist[umac->tx_done]; + } + + /* clear tx interrupt */ + value =3D readl(umac->base + UMAC_INTERRUPT); + value &=3D ~UMAC_TX_INT; + writel(value, umac->base + UMAC_INTERRUPT); + + if (netif_queue_stopped(ndev)) + netif_wake_queue(ndev); +} + +static void umac_irq_enable(struct umac_priv *umac) +{ + unsigned int value; + + /* enable interrupt */ + value =3D readl(umac->base + UMAC_INTERRUPT); + value |=3D (UMAC_RX_INTEN | UMAC_TX_INTEN); + writel(value, umac->base + UMAC_INTERRUPT); +} + +static void umac_irq_disable(struct umac_priv *umac) +{ + unsigned int value; + + /* clear and disable interrupt */ + value =3D readl(umac->base + UMAC_INTERRUPT); + value |=3D (UMAC_RX_INT | UMAC_TX_INT); + value &=3D ~(UMAC_RX_INTEN | UMAC_TX_INTEN); + writel(value, umac->base + UMAC_INTERRUPT); +} + +static irqreturn_t umac_interrupt(int irq, void *p_ndev) +{ + struct net_device *ndev =3D (struct net_device *)p_ndev; + struct umac_priv *umac =3D netdev_priv(ndev); + + if (umac->use_ncsi || netif_running(ndev)) { + umac_irq_disable(umac); + napi_schedule(&umac->napi); + } + + return IRQ_HANDLED; +} + +static int umac_poll(struct napi_struct *napi, int budget) +{ + struct umac_priv *umac =3D container_of(napi, struct umac_priv, napi); + struct net_device *ndev =3D umac->ndev; + unsigned int value; + int rx_done; + + umac_tx_done(ndev); + + rx_done =3D umac_rx(ndev, budget); + + if (rx_done < budget) { + napi_complete_done(napi, rx_done); + /* clear rx interrupt */ + value =3D readl(umac->base + UMAC_INTERRUPT); + value &=3D ~UMAC_RX_INT; + writel(value, umac->base + UMAC_INTERRUPT); + + /* enable interrupt */ + umac_irq_enable(umac); + } + + return rx_done; +} + +static int umac_open(struct net_device *ndev) +{ + struct umac_priv *umac =3D netdev_priv(ndev); + int err; + + if (request_irq(ndev->irq, umac_interrupt, 0x0, ndev->name, ndev)) { + netdev_err(ndev, "failed to register irq\n"); + return -EAGAIN; + } + + umac_init_ring_discriptor(ndev); + umac_init_hw(ndev); + + if (umac->use_ncsi) + netif_carrier_on(ndev); + else + phy_start(ndev->phydev); + + napi_enable(&umac->napi); + netif_start_queue(ndev); + umac_irq_enable(umac); + + if (umac->use_ncsi) { + err =3D ncsi_start_dev(umac->ncsidev); + if (err) { + netdev_err(ndev, "failed to start ncsi\n"); + free_irq(ndev->irq, ndev); + return err; + } + } + + return 0; +} + +static int umac_stop(struct net_device *ndev) +{ + struct umac_priv *umac =3D netdev_priv(ndev); + struct platform_device *pdev =3D umac->pdev; + + dma_free_coherent(&pdev->dev, sizeof(struct umac_tx_descs), + umac->tx_descs, umac->tx_descs_dma_addr); + dma_free_coherent(&pdev->dev, sizeof(struct umac_rx_descs), + umac->rx_descs, umac->rx_descs_dma_addr); + netif_stop_queue(ndev); + + if (umac->use_ncsi) + ncsi_stop_dev(umac->ncsidev); + else + phy_stop(ndev->phydev); + umac_irq_disable(umac); + umac_channel_disable(umac); + napi_disable(&umac->napi); + + free_irq(ndev->irq, ndev); + + return 0; +} + +static const struct ethtool_ops umac_ethtool_ops =3D { + .get_ts_info =3D ethtool_op_get_ts_info, + .get_link_ksettings =3D phy_ethtool_get_link_ksettings, + .set_link_ksettings =3D phy_ethtool_set_link_ksettings, + .get_drvinfo =3D umac_get_drvinfo, + .nway_reset =3D phy_ethtool_nway_reset, + .get_link =3D ethtool_op_get_link, +}; + +static const struct net_device_ops umac_netdev_ops =3D { + .ndo_open =3D umac_open, + .ndo_stop =3D umac_stop, + .ndo_start_xmit =3D umac_start_xmit, + .ndo_get_stats =3D umac_get_stats, + .ndo_do_ioctl =3D umac_ioctl, + .ndo_validate_addr =3D eth_validate_addr, + .ndo_set_mac_address =3D umac_eth_mac_addr, +}; + +static int umac_init_mac_address(struct net_device *ndev) +{ + struct umac_priv *umac =3D netdev_priv(ndev); + struct platform_device *pdev =3D umac->pdev; + char addr[ETH_ALEN]; + int err; + + err =3D of_get_mac_address(pdev->dev.of_node, addr); + if (err) + netdev_err(ndev, "Failed to get address from device-tree: %d\n", + err); + return -EINVAL; + + if (is_valid_ether_addr(addr)) { + dev_addr_set(ndev, addr); + netdev_dbg(ndev, + "Read MAC address %pM from DTB\n", ndev->dev_addr); + } else { + netdev_err(ndev, "Mac Address is Invalid"); + return -EINVAL; + } + + dev_addr_set(ndev, addr); + umac_set_mac_address(ndev, addr); + + return 0; +} + +static void umac_ncsi_handler(struct ncsi_dev *ncsidev) +{ + if (unlikely(ncsidev->state !=3D ncsi_dev_state_functional)) + return; +} + +static void umac_adjust_link(struct net_device *ndev) +{ + struct umac_priv *umac =3D netdev_priv(ndev); + int value; + + if (ndev->phydev->link) { + /* disable both clock */ + value =3D readl(umac->base + UMAC_CONFIG_STATUS); + value &=3D 0xfffff9ff; + writel(value, umac->base + UMAC_CONFIG_STATUS); + udelay(2); + + if (ndev->phydev->duplex) + value |=3D UMAC_CFG_FULL_DUPLEX; + else + value &=3D ~UMAC_CFG_FULL_DUPLEX; + + switch (ndev->phydev->speed) { + case SPEED_1000: + value &=3D ~UMAC_CFG_TX_CLK_EN; + value |=3D UMAC_CFG_GTX_CLK_EN; + value |=3D UMAC_CFG_GIGABIT_MODE; + break; + case SPEED_100: + case SPEED_10: + value |=3D UMAC_CFG_TX_CLK_EN; + value &=3D ~UMAC_CFG_GTX_CLK_EN; + value &=3D ~UMAC_CFG_GIGABIT_MODE; + break; + } + /* update duplex and gigabit_mode to umac */ + writel(value, umac->base + UMAC_CONFIG_STATUS); + udelay(2); + } else { + /* disable both clock */ + value =3D readl(umac->base + UMAC_CONFIG_STATUS); + value &=3D 0xfffff9ff; + writel(value, umac->base + UMAC_CONFIG_STATUS); + udelay(2); + + value &=3D ~UMAC_CFG_FULL_DUPLEX; + value &=3D ~UMAC_CFG_GTX_CLK_EN; + value &=3D ~UMAC_CFG_GIGABIT_MODE; + value |=3D UMAC_CFG_TX_CLK_EN; + writel(value, umac->base + UMAC_CONFIG_STATUS); + udelay(2); + } +} + +static struct device_node *gxp_umac_get_eth_child_node(struct device_node = *ether_np, int id) +{ + struct device_node *port_np; + int port_id; + + for_each_child_of_node(ether_np, port_np) { + /* It is not a 'port' node, continue. */ + if (strcmp(port_np->name, "port")) + continue; + if (of_property_read_u32(port_np, "reg", &port_id) < 0) + continue; + + if (port_id =3D=3D id) + return port_np; + } + + /* Not found! */ + return NULL; +} + +static int umac_setup_phy(struct net_device *ndev) +{ + struct umac_priv *umac =3D netdev_priv(ndev); + struct platform_device *pdev =3D umac->pdev; + struct device_node *phy_handle; + phy_interface_t interface; + struct device_node *eth_ports_np; + struct device_node *port_np; + int ret; + int i; + + /* Get child node ethernet-ports. */ + eth_ports_np =3D of_get_child_by_name(pdev->dev.of_node, "ethernet-ports"= ); + if (!eth_ports_np) { + dev_err(&pdev->dev, "No ethernet-ports child node found!\n"); + return -ENODEV; + } + + for (i =3D 0; i < NUMBER_OF_PORTS; i++) { + /* Get port@i of node ethernet-ports */ + port_np =3D gxp_umac_get_eth_child_node(eth_ports_np, i); + if (!port_np) + break; + + if (i =3D=3D INTERNAL_PORT) { + phy_handle =3D of_parse_phandle(port_np, "phy-handle", 0); + if (phy_handle) { + umac->int_phy_dev =3D of_phy_find_device(phy_handle); + if (!umac->int_phy_dev) + return -ENODEV; + } else { + return dev_err_probe(&pdev->dev, PTR_ERR(phy_handle), + "Failed to map phy-handle for port %d", i); + } + } + + if (i =3D=3D EXTERNAL_PORT) { + phy_handle =3D of_parse_phandle(port_np, "phy-handle", 0); + if (phy_handle) { + if (ret) + dev_err(&pdev->dev, "cannot register phy board fixup\n"); + + ret =3D of_get_phy_mode(phy_handle, &interface); + if (ret) + interface =3D PHY_INTERFACE_MODE_NA; + + umac->phy_dev =3D of_phy_connect(ndev, phy_handle, + &umac_adjust_link, + 0, interface); + + if (!umac->phy_dev) + return -ENODEV; + + phy_remove_link_mode(umac->phy_dev, + ETHTOOL_LINK_MODE_10baseT_Half_BIT); + phy_remove_link_mode(umac->phy_dev, + ETHTOOL_LINK_MODE_10baseT_Full_BIT); + } else { + return dev_err_probe(&pdev->dev, PTR_ERR(phy_handle), + "Failed to map phy-handle for port %d", i); + } + } + } + + return 0; +} + +static int umac_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct net_device *ndev; + struct umac_priv *umac; + struct resource *res; + int ret; + + ndev =3D devm_alloc_etherdev(dev, sizeof(*umac)); + if (!ndev) + return -ENOMEM; + + SET_NETDEV_DEV(ndev, &pdev->dev); + + umac =3D netdev_priv(ndev); + umac->pdev =3D pdev; + umac->ndev =3D ndev; + + res =3D platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + netdev_err(ndev, "failed to get I/O memory\n"); + return -ENXIO; + } + + umac->base =3D devm_ioremap_resource(&pdev->dev, res); + if (!umac->base) { + netdev_err(ndev, "failed to remap I/O memory\n"); + return -EBUSY; + } + + ndev->irq =3D platform_get_irq(pdev, 0); + if (ndev->irq < 0) { + netdev_err(ndev, "failed to get irq\n"); + return -ENXIO; + } + + platform_set_drvdata(pdev, ndev); + + ndev->netdev_ops =3D &umac_netdev_ops; + ndev->ethtool_ops =3D &umac_ethtool_ops; + + umac_init_mac_address(ndev); + umac_channel_disable(umac); + ret =3D umac_setup_phy(ndev); + if (ret !=3D 0) { + netdev_err(ndev, "failed to setup phy ret=3D%d\n", ret); + return -ENODEV; + } + + umac->use_ncsi =3D false; + if (of_get_property(pdev->dev.of_node, "use-ncsi", NULL)) { + if (!IS_ENABLED(CONFIG_NET_NCSI)) { + netdev_err(ndev, "NCSI stack not enabled\n"); + return 0; + } + + dev_info(&pdev->dev, "Using NCSI interface\n"); + umac->use_ncsi =3D true; + umac->ncsidev =3D ncsi_register_dev(ndev, umac_ncsi_handler); + if (!umac->ncsidev) + return -ENODEV; + } + + netif_napi_add(ndev, &umac->napi, umac_poll); + ret =3D devm_register_netdev(dev, ndev); + if (ret !=3D 0) + netdev_err(ndev, "failed to register UMAC ret=3D%d\n", ret); + + return ret; +} + +static const struct of_device_id umac_of_matches[] =3D { + { .compatible =3D "hpe,gxp-umac", }, + {}, +}; +MODULE_DEVICE_TABLE(of, umac_of_matches); + +static struct platform_driver umac_driver =3D { + .driver =3D { + .name =3D "gxp-umac", + .of_match_table =3D umac_of_matches, + }, + .probe =3D umac_probe, +}; + +module_platform_driver(umac_driver); + +MODULE_AUTHOR("Nick Hawkins X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0544BC27C5E for ; Wed, 16 Aug 2023 21:57:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346719AbjHPV4w (ORCPT ); Wed, 16 Aug 2023 17:56:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48420 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346661AbjHPV4P (ORCPT ); Wed, 16 Aug 2023 17:56:15 -0400 Received: from mx0a-002e3701.pphosted.com (mx0a-002e3701.pphosted.com [148.163.147.86]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6A4EB2713; Wed, 16 Aug 2023 14:56:13 -0700 (PDT) Received: from pps.filterd (m0150241.ppops.net [127.0.0.1]) by mx0a-002e3701.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 37GK9ce8019826; Wed, 16 Aug 2023 21:55:50 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hpe.com; h=from : to : subject : date : message-id : in-reply-to : references; s=pps0720; bh=dk5k6u/sI9iN3+yUtFn5EJMT5UPXLcBIp9iFZkAqb9E=; b=YZ0DnxWy+ZnU+0Fo1y/Q8C2sePjaKkyTGDl+JKpU6f5M2AqsEV9GzSsVbCIn+KQp7g9k sknaewy0R0uK/7Jrsl/YTPTAKDo1lzxOTImzfe6zvMVCFTannHGW1kwLAploe6AH3Fog m5HHFQuRb2hVxAf7TdLGeOUlJOY8GnoeXa9mVejSIAVSCCNoqXLIpJ1AWvEkCRNMxc9i 29lSj/DL2isZjsVsa33my/H9ddy0CqVR9osEmxprHRu3U1FHTUtGhsDnEGutlPIHN45K RW9d3re/TGbaTTl2ddmXpBk+VdOjM4aNXto0bUuem17s2r4Q5y9lTyWFoDwu6+piL9UE wg== Received: from p1lg14880.it.hpe.com ([16.230.97.201]) by mx0a-002e3701.pphosted.com (PPS) with ESMTPS id 3sh5880w89-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 16 Aug 2023 21:55:49 +0000 Received: from p1lg14886.dc01.its.hpecorp.net (unknown [10.119.18.237]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by p1lg14880.it.hpe.com (Postfix) with ESMTPS id 0276D80171B; Wed, 16 Aug 2023 21:55:49 +0000 (UTC) Received: from hpe.com (unknown [16.231.227.39]) by p1lg14886.dc01.its.hpecorp.net (Postfix) with ESMTP id 2A0CD80BA10; Wed, 16 Aug 2023 21:55:48 +0000 (UTC) From: nick.hawkins@hpe.com To: christophe.jaillet@wanadoo.fr, simon.horman@corigine.com, andrew@lunn.ch, verdun@hpe.com, nick.hawkins@hpe.com, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, conor+dt@kernel.org, netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 5/5] MAINTAINERS: HPE: Add GXP UMAC Networking Files Date: Wed, 16 Aug 2023 16:52:20 -0500 Message-Id: <20230816215220.114118-6-nick.hawkins@hpe.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230816215220.114118-1-nick.hawkins@hpe.com> References: <20230816215220.114118-1-nick.hawkins@hpe.com> X-Proofpoint-GUID: 8w6JR2cMxvQC3w6ckR4Y1JqMgnQZTf4Y X-Proofpoint-ORIG-GUID: 8w6JR2cMxvQC3w6ckR4Y1JqMgnQZTf4Y X-HPE-SCL: -1 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.267,Aquarius:18.0.957,Hydra:6.0.601,FMLib:17.11.176.26 definitions=2023-08-16_19,2023-08-15_02,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxlogscore=957 bulkscore=0 priorityscore=1501 lowpriorityscore=0 malwarescore=0 clxscore=1015 impostorscore=0 suspectscore=0 phishscore=0 mlxscore=0 adultscore=0 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2306200000 definitions=main-2308160195 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Nick Hawkins List the files added for supporting the UMAC networking on GXP. Signed-off-by: Nick Hawkins Reviewed-by: Andrew Lunn --- v3: *No change v2: *Changed dt-binding net directory files to "hpe,gxp*" --- MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 27ef11624748..c0bb534bec97 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2243,6 +2243,7 @@ S: Maintained F: Documentation/devicetree/bindings/arm/hpe,gxp.yaml F: Documentation/devicetree/bindings/hwmon/hpe,gxp-fan-ctrl.yaml F: Documentation/devicetree/bindings/i2c/hpe,gxp-i2c.yaml +F: Documentation/devicetree/bindings/net/hpe,gxp* F: Documentation/devicetree/bindings/spi/hpe,gxp-spifi.yaml F: Documentation/devicetree/bindings/timer/hpe,gxp-timer.yaml F: Documentation/hwmon/gxp-fan-ctrl.rst @@ -2252,6 +2253,7 @@ F: arch/arm/mach-hpe/ F: drivers/clocksource/timer-gxp.c F: drivers/hwmon/gxp-fan-ctrl.c F: drivers/i2c/busses/i2c-gxp.c +F: drivers/net/ethernet/hpe/ F: drivers/spi/spi-gxp.c F: drivers/watchdog/gxp-wdt.c =20 --=20 2.17.1