From nobody Fri Mar 29 15:32:57 2024 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 EA76DC77B7A for ; Fri, 26 May 2023 07:43:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231691AbjEZHnL (ORCPT ); Fri, 26 May 2023 03:43:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39744 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242415AbjEZHnE (ORCPT ); Fri, 26 May 2023 03:43:04 -0400 Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::225]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 27F4313A; Fri, 26 May 2023 00:43:00 -0700 (PDT) X-GND-Sasl: maxime.chevallier@bootlin.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1685086979; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Lqllezmm8nU6jm3XMUpCZpotaT2SSvD17V9IXl44JX8=; b=hBRset2qt9hSWS5cDhmrBBG81uYN6WwOksbWLL7E1OlhtpkAtPREaVAEgD9kFdSMfNkgnW ffJj69SDBKhELxm5Ezc/56TcuHkCXxLuCFEjUPajhGx/c6uP6qzY/ZhmauY1CEoF2So5tr XOlLOuWE2CLiqS216r8tOG4gsSbUJfqvy9IYdO9eM8XzSmKKEw9vfvQhelfc6ZGtSGeq6X 3c36tVHLOx+3bzs90gqxTvD0wQ/+VyH1nZY7brlHpljmEFbQ2u6AaDVbXkpgRthKyVP094 +NJwzZ4Mr/i1bjcD5TqfRuwWzMSodGcJyUtg8sS/8LZECSYj8eGNwtsaI0gLwA== X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com Received: by mail.gandi.net (Postfix) with ESMTPSA id BB2621C000A; Fri, 26 May 2023 07:42:57 +0000 (UTC) From: Maxime Chevallier To: Mark Brown , davem@davemloft.net Cc: Maxime Chevallier , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, alexis.lothore@bootlin.com, thomas.petazzoni@bootlin.com, Andrew Lunn , Jakub Kicinski , Eric Dumazet , Paolo Abeni , Florian Fainelli , Heiner Kallweit , Russell King , Vladimir Oltean , Ioana Ciornei , linux-stm32@st-md-mailman.stormreply.com, linux-arm-kernel@lists.infradead.org, Maxime Coquelin , Jose Abreu , Alexandre Torgue , Giuseppe Cavallaro , Simon Horman Subject: [PATCH net-next v3 1/4] net: mdio: Introduce a regmap-based mdio driver Date: Fri, 26 May 2023 09:42:49 +0200 Message-Id: <20230526074252.480200-2-maxime.chevallier@bootlin.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230526074252.480200-1-maxime.chevallier@bootlin.com> References: <20230526074252.480200-1-maxime.chevallier@bootlin.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" There exists several examples today of devices that embed an ethernet PHY or PCS directly inside an SoC. In this situation, either the device is controlled through a vendor-specific register set, or sometimes exposes the standard 802.3 registers that are typically accessed over MDIO. As phylib and phylink are designed to use mdiodevices, this driver allows creating a virtual MDIO bus, that translates mdiodev register accesses to regmap accesses. The reason we use regmap is because there are at least 3 such devices known today, 2 of them are Altera TSE PCS's, memory-mapped, exposed with a 4-byte stride in stmmac's dwmac-socfpga variant, and a 2-byte stride in altera-tse. The other one (nxp,sja1110-base-tx-mdio) is exposed over SPI. Signed-off-by: Maxime Chevallier --- V2->V3 : - Introduce struct miod_regmap_priv for priv elements instead of plain reuse of the config struct - Use ~O instead of ~0UL V1->V2 : - Use phy_mask to avoid unnecessary scanning, suggested by Andrew - Allow entirely disabling scanning, suggested by Vlad MAINTAINERS | 7 +++ drivers/net/ethernet/altera/Kconfig | 2 + drivers/net/mdio/Kconfig | 10 ++++ drivers/net/mdio/Makefile | 1 + drivers/net/mdio/mdio-regmap.c | 93 +++++++++++++++++++++++++++++ include/linux/mdio/mdio-regmap.h | 24 ++++++++ 6 files changed, 137 insertions(+) create mode 100644 drivers/net/mdio/mdio-regmap.c create mode 100644 include/linux/mdio/mdio-regmap.h diff --git a/MAINTAINERS b/MAINTAINERS index c904dba1733b..f68269b39e09 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12835,6 +12835,13 @@ F: Documentation/devicetree/bindings/net/ieee80215= 4/mcr20a.txt F: drivers/net/ieee802154/mcr20a.c F: drivers/net/ieee802154/mcr20a.h =20 +MDIO REGMAP DRIVER +M: Maxime Chevallier +L: netdev@vger.kernel.org +S: Maintained +F: drivers/net/mdio/mdio-regmap.c +F: include/linux/mdio/mdio-regmap.h + MEASUREMENT COMPUTING CIO-DAC IIO DRIVER M: William Breathitt Gray L: linux-iio@vger.kernel.org diff --git a/drivers/net/ethernet/altera/Kconfig b/drivers/net/ethernet/alt= era/Kconfig index dd7fd41ccde5..0a7c0a217536 100644 --- a/drivers/net/ethernet/altera/Kconfig +++ b/drivers/net/ethernet/altera/Kconfig @@ -5,6 +5,8 @@ config ALTERA_TSE select PHYLIB select PHYLINK select PCS_ALTERA_TSE + select MDIO_REGMAP + depends on REGMAP help This driver supports the Altera Triple-Speed (TSE) Ethernet MAC. =20 diff --git a/drivers/net/mdio/Kconfig b/drivers/net/mdio/Kconfig index 9ff2e6f22f3f..aef39c89cf44 100644 --- a/drivers/net/mdio/Kconfig +++ b/drivers/net/mdio/Kconfig @@ -185,6 +185,16 @@ config MDIO_IPQ8064 This driver supports the MDIO interface found in the network interface units of the IPQ8064 SoC =20 +config MDIO_REGMAP + tristate + help + This driver allows using MDIO devices that are not sitting on a + regular MDIO bus, but still exposes the standard 802.3 register + layout. It's regmap-based so that it can be used on integrated, + memory-mapped PHYs, SPI PHYs and so on. A new virtual MDIO bus is + created, and its read/write operations are mapped to the underlying + regmap. + config MDIO_THUNDER tristate "ThunderX SOCs MDIO buses" depends on 64BIT diff --git a/drivers/net/mdio/Makefile b/drivers/net/mdio/Makefile index 7d4cb4c11e4e..1015f0db4531 100644 --- a/drivers/net/mdio/Makefile +++ b/drivers/net/mdio/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_MDIO_MOXART) +=3D mdio-moxart.o obj-$(CONFIG_MDIO_MSCC_MIIM) +=3D mdio-mscc-miim.o obj-$(CONFIG_MDIO_MVUSB) +=3D mdio-mvusb.o obj-$(CONFIG_MDIO_OCTEON) +=3D mdio-octeon.o +obj-$(CONFIG_MDIO_REGMAP) +=3D mdio-regmap.o obj-$(CONFIG_MDIO_SUN4I) +=3D mdio-sun4i.o obj-$(CONFIG_MDIO_THUNDER) +=3D mdio-thunder.o obj-$(CONFIG_MDIO_XGENE) +=3D mdio-xgene.o diff --git a/drivers/net/mdio/mdio-regmap.c b/drivers/net/mdio/mdio-regmap.c new file mode 100644 index 000000000000..8a742a8d6387 --- /dev/null +++ b/drivers/net/mdio/mdio-regmap.c @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* Driver for MMIO-Mapped MDIO devices. Some IPs expose internal PHYs or P= CS + * within the MMIO-mapped area + * + * Copyright (C) 2023 Maxime Chevallier + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "mdio-regmap" + +struct mdio_regmap_priv { + struct regmap *regmap; + u8 valid_addr; +}; + +static int mdio_regmap_read_c22(struct mii_bus *bus, int addr, int regnum) +{ + struct mdio_regmap_priv *ctx =3D bus->priv; + unsigned int val; + int ret; + + if (ctx->valid_addr !=3D addr) + return -ENODEV; + + ret =3D regmap_read(ctx->regmap, regnum, &val); + if (ret < 0) + return ret; + + return val; +} + +static int mdio_regmap_write_c22(struct mii_bus *bus, int addr, int regnum, + u16 val) +{ + struct mdio_regmap_priv *ctx =3D bus->priv; + + if (ctx->valid_addr !=3D addr) + return -ENODEV; + + return regmap_write(ctx->regmap, regnum, val); +} + +struct mii_bus *devm_mdio_regmap_register(struct device *dev, + const struct mdio_regmap_config *config) +{ + struct mdio_regmap_priv *mr; + struct mii_bus *mii; + int rc; + + if (!config->parent) + return ERR_PTR(-EINVAL); + + mii =3D devm_mdiobus_alloc_size(config->parent, sizeof(*mr)); + if (!mii) + return ERR_PTR(-ENOMEM); + + mr =3D mii->priv; + mr->regmap =3D config->regmap; + mr->valid_addr =3D config->valid_addr; + + mii->name =3D DRV_NAME; + strscpy(mii->id, config->name, MII_BUS_ID_SIZE); + mii->parent =3D config->parent; + mii->read =3D mdio_regmap_read_c22; + mii->write =3D mdio_regmap_write_c22; + + if (config->autoscan) + mii->phy_mask =3D ~BIT(config->valid_addr); + else + mii->phy_mask =3D ~0; + + rc =3D devm_mdiobus_register(dev, mii); + if (rc) { + dev_err(config->parent, "Cannot register MDIO bus![%s] (%d)\n", mii->id,= rc); + return ERR_PTR(rc); + } + + return mii; +} +EXPORT_SYMBOL_GPL(devm_mdio_regmap_register); + +MODULE_DESCRIPTION("MDIO API over regmap"); +MODULE_AUTHOR("Maxime Chevallier "); +MODULE_LICENSE("GPL"); diff --git a/include/linux/mdio/mdio-regmap.h b/include/linux/mdio/mdio-reg= map.h new file mode 100644 index 000000000000..b8508f152552 --- /dev/null +++ b/include/linux/mdio/mdio-regmap.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Driver for MMIO-Mapped MDIO devices. Some IPs expose internal PHYs or P= CS + * within the MMIO-mapped area + * + * Copyright (C) 2023 Maxime Chevallier + */ +#ifndef MDIO_REGMAP_H +#define MDIO_REGMAP_H + +struct device; +struct regmap; + +struct mdio_regmap_config { + struct device *parent; + struct regmap *regmap; + char name[MII_BUS_ID_SIZE]; + u8 valid_addr; + bool autoscan; +}; + +struct mii_bus *devm_mdio_regmap_register(struct device *dev, + const struct mdio_regmap_config *config); + +#endif --=20 2.40.1 From nobody Fri Mar 29 15:32:57 2024 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 13254C77B7A for ; Fri, 26 May 2023 07:43:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242525AbjEZHnV (ORCPT ); Fri, 26 May 2023 03:43:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39790 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242526AbjEZHnJ (ORCPT ); Fri, 26 May 2023 03:43:09 -0400 Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::225]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 42AEB13A; Fri, 26 May 2023 00:43:05 -0700 (PDT) X-GND-Sasl: maxime.chevallier@bootlin.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1685086981; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=hgk3lxLbNo2xoxXLggeXdKbVXEX79dadPfwJNxSe0cA=; b=mkOtzGgkABIjstbcWvKTxyhZaqAmZv+d8FI5wxh4Sd+sEHjrN+d2Ohj8CQGuXsOAScbdkX KrSgRa2BVGPJhqcW4uhBAGq8Bn6+qHpCNBTpoTYhQNq7gBl7vCgyTQasKXgmYdDZPr2xd2 7M52u8fCwo15gj6Nd5+15NXXzZ1J13C0MH+t/F6jUpHjcofiNuYH/0DXrcIaiAj529e5YO YnP/OBsOZPOwucoyQVeRBeHS7ygGgvXuEZvTkoz2nwKsBxjXG1CYxFa5FPed+sQQONQ8lC eVKq2RzMWR9YjoV7Rk8gtlaHGQDlCqJJPdHDMtR4dwPM7Gdk9fGjUebPKy5XFg== X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com Received: by mail.gandi.net (Postfix) with ESMTPSA id DD85E1C0006; Fri, 26 May 2023 07:42:59 +0000 (UTC) From: Maxime Chevallier To: Mark Brown , davem@davemloft.net Cc: Maxime Chevallier , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, alexis.lothore@bootlin.com, thomas.petazzoni@bootlin.com, Andrew Lunn , Jakub Kicinski , Eric Dumazet , Paolo Abeni , Florian Fainelli , Heiner Kallweit , Russell King , Vladimir Oltean , Ioana Ciornei , linux-stm32@st-md-mailman.stormreply.com, linux-arm-kernel@lists.infradead.org, Maxime Coquelin , Jose Abreu , Alexandre Torgue , Giuseppe Cavallaro , Simon Horman Subject: [PATCH net-next v3 2/4] net: ethernet: altera-tse: Convert to mdio-regmap and use PCS Lynx Date: Fri, 26 May 2023 09:42:50 +0200 Message-Id: <20230526074252.480200-3-maxime.chevallier@bootlin.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230526074252.480200-1-maxime.chevallier@bootlin.com> References: <20230526074252.480200-1-maxime.chevallier@bootlin.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The newly introduced regmap-based MDIO driver allows for an easy mapping of an mdiodevice onto the memory-mapped TSE PCS, which is actually a Lynx PCS. Convert Altera TSE to use this PCS instead of the pcs-altera-tse, which is nothing more than a memory-mapped Lynx PCS. Signed-off-by: Maxime Chevallier --- V2->V3 : No changes V1->V2 : No changes drivers/net/ethernet/altera/altera_tse.h | 1 + drivers/net/ethernet/altera/altera_tse_main.c | 57 +++++++++++++++++-- include/linux/mdio/mdio-regmap.h | 2 + 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/altera/altera_tse.h b/drivers/net/etherne= t/altera/altera_tse.h index db5eed06e92d..d50cf440d01b 100644 --- a/drivers/net/ethernet/altera/altera_tse.h +++ b/drivers/net/ethernet/altera/altera_tse.h @@ -477,6 +477,7 @@ struct altera_tse_private { struct phylink *phylink; struct phylink_config phylink_config; struct phylink_pcs *pcs; + struct mdio_device *pcs_mdiodev; }; =20 /* Function prototypes diff --git a/drivers/net/ethernet/altera/altera_tse_main.c b/drivers/net/et= hernet/altera/altera_tse_main.c index 190ff1bcd94e..66db6a7d0b22 100644 --- a/drivers/net/ethernet/altera/altera_tse_main.c +++ b/drivers/net/ethernet/altera/altera_tse_main.c @@ -27,14 +27,16 @@ #include #include #include +#include #include #include #include #include #include -#include +#include #include #include +#include #include #include =20 @@ -1134,13 +1136,21 @@ static int altera_tse_probe(struct platform_device = *pdev) const struct of_device_id *of_id =3D NULL; struct altera_tse_private *priv; struct resource *control_port; + struct regmap *pcs_regmap; struct resource *dma_res; struct resource *pcs_res; + struct mii_bus *pcs_bus; struct net_device *ndev; void __iomem *descmap; - int pcs_reg_width =3D 2; int ret =3D -ENODEV; =20 + struct regmap_config pcs_regmap_cfg; + + struct mdio_regmap_config mrc =3D { + .parent =3D &pdev->dev, + .valid_addr =3D 0x0, + }; + ndev =3D alloc_etherdev(sizeof(struct altera_tse_private)); if (!ndev) { dev_err(&pdev->dev, "Could not allocate network device\n"); @@ -1258,10 +1268,29 @@ static int altera_tse_probe(struct platform_device = *pdev) ret =3D request_and_map(pdev, "pcs", &pcs_res, &priv->pcs_base); if (ret) { + /* If we can't find a dedicated resource for the PCS, fallback + * to the internal PCS, that has a different address stride + */ priv->pcs_base =3D priv->mac_dev + tse_csroffs(mdio_phy0); - pcs_reg_width =3D 4; + pcs_regmap_cfg.reg_bits =3D 32; + /* Values are MDIO-like values, on 16 bits */ + pcs_regmap_cfg.val_bits =3D 16; + pcs_regmap_cfg.reg_shift =3D REGMAP_UPSHIFT(2); + } else { + pcs_regmap_cfg.reg_bits =3D 16; + pcs_regmap_cfg.val_bits =3D 16; + pcs_regmap_cfg.reg_shift =3D REGMAP_UPSHIFT(1); } =20 + /* Create a regmap for the PCS so that it can be used by the PCS driver */ + pcs_regmap =3D devm_regmap_init_mmio(&pdev->dev, priv->pcs_base, + &pcs_regmap_cfg); + if (IS_ERR(pcs_regmap)) { + ret =3D PTR_ERR(pcs_regmap); + goto err_free_netdev; + } + mrc.regmap =3D pcs_regmap; + /* Rx IRQ */ priv->rx_irq =3D platform_get_irq_byname(pdev, "rx_irq"); if (priv->rx_irq =3D=3D -ENXIO) { @@ -1384,7 +1413,20 @@ static int altera_tse_probe(struct platform_device *= pdev) (unsigned long) control_port->start, priv->rx_irq, priv->tx_irq); =20 - priv->pcs =3D alt_tse_pcs_create(ndev, priv->pcs_base, pcs_reg_width); + snprintf(mrc.name, MII_BUS_ID_SIZE, "%s-pcs-mii", ndev->name); + pcs_bus =3D devm_mdio_regmap_register(&pdev->dev, &mrc); + if (IS_ERR(pcs_bus)) { + ret =3D PTR_ERR(pcs_bus); + goto err_init_phy; + } + + priv->pcs_mdiodev =3D mdio_device_create(pcs_bus, 0); + + priv->pcs =3D lynx_pcs_create(priv->pcs_mdiodev); + if (!priv->pcs) { + ret =3D -ENODEV; + goto err_init_phy; + } =20 priv->phylink_config.dev =3D &ndev->dev; priv->phylink_config.type =3D PHYLINK_NETDEV; @@ -1407,11 +1449,12 @@ static int altera_tse_probe(struct platform_device = *pdev) if (IS_ERR(priv->phylink)) { dev_err(&pdev->dev, "failed to create phylink\n"); ret =3D PTR_ERR(priv->phylink); - goto err_init_phy; + goto err_pcs; } =20 return 0; - +err_pcs: + mdio_device_free(priv->pcs_mdiodev); err_init_phy: unregister_netdev(ndev); err_register_netdev: @@ -1433,6 +1476,8 @@ static int altera_tse_remove(struct platform_device *= pdev) altera_tse_mdio_destroy(ndev); unregister_netdev(ndev); phylink_destroy(priv->phylink); + mdio_device_free(priv->pcs_mdiodev); + free_netdev(ndev); =20 return 0; diff --git a/include/linux/mdio/mdio-regmap.h b/include/linux/mdio/mdio-reg= map.h index b8508f152552..679d9069846b 100644 --- a/include/linux/mdio/mdio-regmap.h +++ b/include/linux/mdio/mdio-regmap.h @@ -7,6 +7,8 @@ #ifndef MDIO_REGMAP_H #define MDIO_REGMAP_H =20 +#include + struct device; struct regmap; =20 --=20 2.40.1 From nobody Fri Mar 29 15:32:57 2024 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 2B16AC7EE23 for ; Fri, 26 May 2023 07:43:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242541AbjEZHnQ (ORCPT ); Fri, 26 May 2023 03:43:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39798 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242525AbjEZHnJ (ORCPT ); Fri, 26 May 2023 03:43:09 -0400 Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 42BBD187; Fri, 26 May 2023 00:43:05 -0700 (PDT) X-GND-Sasl: maxime.chevallier@bootlin.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1685086983; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nLTA20vRAOdhKZiSoJRVEtdsKYT69ZwQNGBlWxIzVJA=; b=abN+CFEeMvEQqeWYW+KNiqy8yZxxKlXV7MuqTfYn+AqvLcRg9GC4xvnoyiXu/tk5apFf+1 E/betvo60ea2m5MUPI4baNUAW2RNOnUdsrDWSpLk3A+0fs0aeUwXUzwDif/+76MbRdbujE yV+WhBG4g6R4OH/pMdsjA8J4VEos50cQZFgZe+2XAQEPHSqaAYLRqQTHPiHaALB5+9R5fQ msrtcNs4QdFpyV0168m01xpBI9OkjytILuCbpd+cuGqZ0cATb4/Wsw8h5w6I8SYP7ZJflh p38FkkVcDPb6igA2ce/QhbHWoAn7B59WQsyNp+CU1dugVGxxkUOyxyL7pwSpKQ== X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com Received: by mail.gandi.net (Postfix) with ESMTPSA id E1F9F1C0002; Fri, 26 May 2023 07:43:01 +0000 (UTC) From: Maxime Chevallier To: Mark Brown , davem@davemloft.net Cc: Maxime Chevallier , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, alexis.lothore@bootlin.com, thomas.petazzoni@bootlin.com, Andrew Lunn , Jakub Kicinski , Eric Dumazet , Paolo Abeni , Florian Fainelli , Heiner Kallweit , Russell King , Vladimir Oltean , Ioana Ciornei , linux-stm32@st-md-mailman.stormreply.com, linux-arm-kernel@lists.infradead.org, Maxime Coquelin , Jose Abreu , Alexandre Torgue , Giuseppe Cavallaro , Simon Horman Subject: [PATCH net-next v3 3/4] net: pcs: Drop the TSE PCS driver Date: Fri, 26 May 2023 09:42:51 +0200 Message-Id: <20230526074252.480200-4-maxime.chevallier@bootlin.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230526074252.480200-1-maxime.chevallier@bootlin.com> References: <20230526074252.480200-1-maxime.chevallier@bootlin.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Now that we can easily create a mdio-device that represents a memory-mapped device that exposes an MDIO-like register layout, we don't need the Altera TSE PCS anymore, since we can use the Lynx PCS instead. Signed-off-by: Maxime Chevallier Reviewed-by: Simon Horman --- V2->V3 : No changes V1->V2 : No changes MAINTAINERS | 7 -- drivers/net/pcs/Kconfig | 6 -- drivers/net/pcs/Makefile | 1 - drivers/net/pcs/pcs-altera-tse.c | 160 ------------------------------- include/linux/pcs-altera-tse.h | 17 ---- 5 files changed, 191 deletions(-) delete mode 100644 drivers/net/pcs/pcs-altera-tse.c delete mode 100644 include/linux/pcs-altera-tse.h diff --git a/MAINTAINERS b/MAINTAINERS index f68269b39e09..0982384e300f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -909,13 +909,6 @@ L: netdev@vger.kernel.org S: Maintained F: drivers/net/ethernet/altera/ =20 -ALTERA TSE PCS -M: Maxime Chevallier -L: netdev@vger.kernel.org -S: Supported -F: drivers/net/pcs/pcs-altera-tse.c -F: include/linux/pcs-altera-tse.h - ALTERA UART/JTAG UART SERIAL DRIVERS M: Tobias Klauser L: linux-serial@vger.kernel.org diff --git a/drivers/net/pcs/Kconfig b/drivers/net/pcs/Kconfig index 7c34fb7cbf7b..87cf308fc6d8 100644 --- a/drivers/net/pcs/Kconfig +++ b/drivers/net/pcs/Kconfig @@ -33,10 +33,4 @@ config PCS_RZN1_MIIC on RZ/N1 SoCs. This PCS converts MII to RMII/RGMII or can be set in pass-through mode for MII. =20 -config PCS_ALTERA_TSE - tristate - help - This module provides helper functions for the Altera Triple Speed - Ethernet SGMII PCS, that can be found on the Intel Socfpga family. - endmenu diff --git a/drivers/net/pcs/Makefile b/drivers/net/pcs/Makefile index 9b9afd6b1c22..ea662a7989b2 100644 --- a/drivers/net/pcs/Makefile +++ b/drivers/net/pcs/Makefile @@ -7,4 +7,3 @@ obj-$(CONFIG_PCS_XPCS) +=3D pcs_xpcs.o obj-$(CONFIG_PCS_LYNX) +=3D pcs-lynx.o obj-$(CONFIG_PCS_MTK_LYNXI) +=3D pcs-mtk-lynxi.o obj-$(CONFIG_PCS_RZN1_MIIC) +=3D pcs-rzn1-miic.o -obj-$(CONFIG_PCS_ALTERA_TSE) +=3D pcs-altera-tse.o diff --git a/drivers/net/pcs/pcs-altera-tse.c b/drivers/net/pcs/pcs-altera-= tse.c deleted file mode 100644 index d616749761f4..000000000000 --- a/drivers/net/pcs/pcs-altera-tse.c +++ /dev/null @@ -1,160 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (C) 2022 Bootlin - * - * Maxime Chevallier - */ - -#include -#include -#include -#include - -/* SGMII PCS register addresses - */ -#define SGMII_PCS_LINK_TIMER_0 0x12 -#define SGMII_PCS_LINK_TIMER_1 0x13 -#define SGMII_PCS_IF_MODE 0x14 -#define PCS_IF_MODE_SGMII_ENA BIT(0) -#define PCS_IF_MODE_USE_SGMII_AN BIT(1) -#define PCS_IF_MODE_SGMI_HALF_DUPLEX BIT(4) -#define PCS_IF_MODE_SGMI_PHY_AN BIT(5) -#define SGMII_PCS_SW_RESET_TIMEOUT 100 /* usecs */ - -struct altera_tse_pcs { - struct phylink_pcs pcs; - void __iomem *base; - int reg_width; -}; - -static struct altera_tse_pcs *phylink_pcs_to_tse_pcs(struct phylink_pcs *p= cs) -{ - return container_of(pcs, struct altera_tse_pcs, pcs); -} - -static u16 tse_pcs_read(struct altera_tse_pcs *tse_pcs, int regnum) -{ - if (tse_pcs->reg_width =3D=3D 4) - return readl(tse_pcs->base + regnum * 4); - else - return readw(tse_pcs->base + regnum * 2); -} - -static void tse_pcs_write(struct altera_tse_pcs *tse_pcs, int regnum, - u16 value) -{ - if (tse_pcs->reg_width =3D=3D 4) - writel(value, tse_pcs->base + regnum * 4); - else - writew(value, tse_pcs->base + regnum * 2); -} - -static int tse_pcs_reset(struct altera_tse_pcs *tse_pcs) -{ - u16 bmcr; - - /* Reset PCS block */ - bmcr =3D tse_pcs_read(tse_pcs, MII_BMCR); - bmcr |=3D BMCR_RESET; - tse_pcs_write(tse_pcs, MII_BMCR, bmcr); - - return read_poll_timeout(tse_pcs_read, bmcr, (bmcr & BMCR_RESET), - 10, SGMII_PCS_SW_RESET_TIMEOUT, 1, - tse_pcs, MII_BMCR); -} - -static int alt_tse_pcs_validate(struct phylink_pcs *pcs, - unsigned long *supported, - const struct phylink_link_state *state) -{ - if (state->interface =3D=3D PHY_INTERFACE_MODE_SGMII || - state->interface =3D=3D PHY_INTERFACE_MODE_1000BASEX) - return 1; - - return -EINVAL; -} - -static int alt_tse_pcs_config(struct phylink_pcs *pcs, unsigned int mode, - phy_interface_t interface, - const unsigned long *advertising, - bool permit_pause_to_mac) -{ - struct altera_tse_pcs *tse_pcs =3D phylink_pcs_to_tse_pcs(pcs); - u32 ctrl, if_mode; - - ctrl =3D tse_pcs_read(tse_pcs, MII_BMCR); - if_mode =3D tse_pcs_read(tse_pcs, SGMII_PCS_IF_MODE); - - /* Set link timer to 1.6ms, as per the MegaCore Function User Guide */ - tse_pcs_write(tse_pcs, SGMII_PCS_LINK_TIMER_0, 0x0D40); - tse_pcs_write(tse_pcs, SGMII_PCS_LINK_TIMER_1, 0x03); - - if (interface =3D=3D PHY_INTERFACE_MODE_SGMII) { - if_mode |=3D PCS_IF_MODE_USE_SGMII_AN | PCS_IF_MODE_SGMII_ENA; - } else if (interface =3D=3D PHY_INTERFACE_MODE_1000BASEX) { - if_mode &=3D ~(PCS_IF_MODE_USE_SGMII_AN | PCS_IF_MODE_SGMII_ENA); - } - - ctrl |=3D (BMCR_SPEED1000 | BMCR_FULLDPLX | BMCR_ANENABLE); - - tse_pcs_write(tse_pcs, MII_BMCR, ctrl); - tse_pcs_write(tse_pcs, SGMII_PCS_IF_MODE, if_mode); - - return tse_pcs_reset(tse_pcs); -} - -static void alt_tse_pcs_get_state(struct phylink_pcs *pcs, - struct phylink_link_state *state) -{ - struct altera_tse_pcs *tse_pcs =3D phylink_pcs_to_tse_pcs(pcs); - u16 bmsr, lpa; - - bmsr =3D tse_pcs_read(tse_pcs, MII_BMSR); - lpa =3D tse_pcs_read(tse_pcs, MII_LPA); - - phylink_mii_c22_pcs_decode_state(state, bmsr, lpa); -} - -static void alt_tse_pcs_an_restart(struct phylink_pcs *pcs) -{ - struct altera_tse_pcs *tse_pcs =3D phylink_pcs_to_tse_pcs(pcs); - u16 bmcr; - - bmcr =3D tse_pcs_read(tse_pcs, MII_BMCR); - bmcr |=3D BMCR_ANRESTART; - tse_pcs_write(tse_pcs, MII_BMCR, bmcr); - - /* This PCS seems to require a soft reset to re-sync the AN logic */ - tse_pcs_reset(tse_pcs); -} - -static const struct phylink_pcs_ops alt_tse_pcs_ops =3D { - .pcs_validate =3D alt_tse_pcs_validate, - .pcs_get_state =3D alt_tse_pcs_get_state, - .pcs_config =3D alt_tse_pcs_config, - .pcs_an_restart =3D alt_tse_pcs_an_restart, -}; - -struct phylink_pcs *alt_tse_pcs_create(struct net_device *ndev, - void __iomem *pcs_base, int reg_width) -{ - struct altera_tse_pcs *tse_pcs; - - if (reg_width !=3D 4 && reg_width !=3D 2) - return ERR_PTR(-EINVAL); - - tse_pcs =3D devm_kzalloc(&ndev->dev, sizeof(*tse_pcs), GFP_KERNEL); - if (!tse_pcs) - return ERR_PTR(-ENOMEM); - - tse_pcs->pcs.ops =3D &alt_tse_pcs_ops; - tse_pcs->base =3D pcs_base; - tse_pcs->reg_width =3D reg_width; - - return &tse_pcs->pcs; -} -EXPORT_SYMBOL_GPL(alt_tse_pcs_create); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Altera TSE PCS driver"); -MODULE_AUTHOR("Maxime Chevallier "); diff --git a/include/linux/pcs-altera-tse.h b/include/linux/pcs-altera-tse.h deleted file mode 100644 index 92ab9f08e835..000000000000 --- a/include/linux/pcs-altera-tse.h +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (C) 2022 Bootlin - * - * Maxime Chevallier - */ - -#ifndef __LINUX_PCS_ALTERA_TSE_H -#define __LINUX_PCS_ALTERA_TSE_H - -struct phylink_pcs; -struct net_device; - -struct phylink_pcs *alt_tse_pcs_create(struct net_device *ndev, - void __iomem *pcs_base, int reg_width); - -#endif /* __LINUX_PCS_ALTERA_TSE_H */ --=20 2.40.1 From nobody Fri Mar 29 15:32:57 2024 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 C869CC7EE23 for ; Fri, 26 May 2023 07:43:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242253AbjEZHn0 (ORCPT ); Fri, 26 May 2023 03:43:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39830 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242142AbjEZHnM (ORCPT ); Fri, 26 May 2023 03:43:12 -0400 Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::225]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2994812F; Fri, 26 May 2023 00:43:07 -0700 (PDT) X-GND-Sasl: maxime.chevallier@bootlin.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1685086985; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ZSHO4Na2rM8AwFuAbc7+/YEMvRiXA5r07W34WmBo0Wk=; b=pqKegkbdGW/Ts6AnYrf97VvM/dcL5vb9N5QhaZk37fkuYmCmZpVgMR0V05C81gVZZ2Mtp8 GpKuqEPTGh4JG5ag4Akcr1Hmo6UmknuY+iWmRzSksAywb9B+8ihdAPr14kEBpCUvDBbHlR xFO7wGvGYX/7p0NGHLWHjDY/ExZVFIQfbaq/tTtMz6UCsf9mSGtF7hrvSXvBfVTWZI9E9O oyIUEXWIxuB/EvhMgERAK2QVKZD78dSBrUN5t57HioK8nOXbdKlz7Ffl5FjuFu3v05EMRT 4at0/yUduzaqAaCgVy3BqTpJyg++E1mrZRkRCIcsEypBi1aAVI2sNRWmIHb4AA== X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com X-GND-Sasl: maxime.chevallier@bootlin.com Received: by mail.gandi.net (Postfix) with ESMTPSA id 18AEB1C0008; Fri, 26 May 2023 07:43:04 +0000 (UTC) From: Maxime Chevallier To: Mark Brown , davem@davemloft.net Cc: Maxime Chevallier , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, alexis.lothore@bootlin.com, thomas.petazzoni@bootlin.com, Andrew Lunn , Jakub Kicinski , Eric Dumazet , Paolo Abeni , Florian Fainelli , Heiner Kallweit , Russell King , Vladimir Oltean , Ioana Ciornei , linux-stm32@st-md-mailman.stormreply.com, linux-arm-kernel@lists.infradead.org, Maxime Coquelin , Jose Abreu , Alexandre Torgue , Giuseppe Cavallaro , Simon Horman Subject: [PATCH net-next v3 4/4] net: stmmac: dwmac-sogfpga: use the lynx pcs driver Date: Fri, 26 May 2023 09:42:52 +0200 Message-Id: <20230526074252.480200-5-maxime.chevallier@bootlin.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230526074252.480200-1-maxime.chevallier@bootlin.com> References: <20230526074252.480200-1-maxime.chevallier@bootlin.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" dwmac_socfpga re-implements support for the TSE PCS, which is identical to the already existing TSE PCS, which in turn is the same as the Lynx PCS. Drop the existing TSE re-implemenation and use the Lynx PCS instead, relying on the regmap-mdio driver to translate MDIO accesses into mmio accesses. Instead of extending xpcs, allow using a generic phylink_pcs, populated by lynx_pcs_create(), and use .mac_select_pcs() to return the relevant PCS to be used. Signed-off-by: Maxime Chevallier --- V2->V3 : No changes V1->V2 : No changes drivers/net/ethernet/stmicro/stmmac/Kconfig | 1 + drivers/net/ethernet/stmicro/stmmac/Makefile | 2 +- .../ethernet/stmicro/stmmac/altr_tse_pcs.c | 257 ------------------ .../ethernet/stmicro/stmmac/altr_tse_pcs.h | 29 -- drivers/net/ethernet/stmicro/stmmac/common.h | 1 + .../ethernet/stmicro/stmmac/dwmac-socfpga.c | 90 ++++-- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 12 +- 7 files changed, 76 insertions(+), 316 deletions(-) delete mode 100644 drivers/net/ethernet/stmicro/stmmac/altr_tse_pcs.c delete mode 100644 drivers/net/ethernet/stmicro/stmmac/altr_tse_pcs.h diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethe= rnet/stmicro/stmmac/Kconfig index 5f5a997f21f3..62b484cca1c3 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig @@ -158,6 +158,7 @@ config DWMAC_SOCFPGA default ARCH_INTEL_SOCFPGA depends on OF && (ARCH_INTEL_SOCFPGA || COMPILE_TEST) select MFD_SYSCON + select PCS_LYNX help Support for ethernet controller on Altera SOCFPGA =20 diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/eth= ernet/stmicro/stmmac/Makefile index 8738fdbb4b2d..7dd3d388068b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Makefile +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile @@ -35,7 +35,7 @@ obj-$(CONFIG_DWMAC_IMX8) +=3D dwmac-imx.o obj-$(CONFIG_DWMAC_TEGRA) +=3D dwmac-tegra.o obj-$(CONFIG_DWMAC_VISCONTI) +=3D dwmac-visconti.o stmmac-platform-objs:=3D stmmac_platform.o -dwmac-altr-socfpga-objs :=3D altr_tse_pcs.o dwmac-socfpga.o +dwmac-altr-socfpga-objs :=3D dwmac-socfpga.o =20 obj-$(CONFIG_STMMAC_PCI) +=3D stmmac-pci.o obj-$(CONFIG_DWMAC_INTEL) +=3D dwmac-intel.o diff --git a/drivers/net/ethernet/stmicro/stmmac/altr_tse_pcs.c b/drivers/n= et/ethernet/stmicro/stmmac/altr_tse_pcs.c deleted file mode 100644 index 00f6d347eaf7..000000000000 --- a/drivers/net/ethernet/stmicro/stmmac/altr_tse_pcs.c +++ /dev/null @@ -1,257 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* Copyright Altera Corporation (C) 2016. All rights reserved. - * - * Author: Tien Hock Loh - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "stmmac.h" -#include "stmmac_platform.h" -#include "altr_tse_pcs.h" - -#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII 0 -#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII BIT(1) -#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII BIT(2) -#define SYSMGR_EMACGRP_CTRL_PHYSEL_WIDTH 2 -#define SYSMGR_EMACGRP_CTRL_PHYSEL_MASK GENMASK(1, 0) - -#define TSE_PCS_CONTROL_AN_EN_MASK BIT(12) -#define TSE_PCS_CONTROL_REG 0x00 -#define TSE_PCS_CONTROL_RESTART_AN_MASK BIT(9) -#define TSE_PCS_CTRL_AUTONEG_SGMII 0x1140 -#define TSE_PCS_IF_MODE_REG 0x28 -#define TSE_PCS_LINK_TIMER_0_REG 0x24 -#define TSE_PCS_LINK_TIMER_1_REG 0x26 -#define TSE_PCS_SIZE 0x40 -#define TSE_PCS_STATUS_AN_COMPLETED_MASK BIT(5) -#define TSE_PCS_STATUS_LINK_MASK 0x0004 -#define TSE_PCS_STATUS_REG 0x02 -#define TSE_PCS_SGMII_SPEED_1000 BIT(3) -#define TSE_PCS_SGMII_SPEED_100 BIT(2) -#define TSE_PCS_SGMII_SPEED_10 0x0 -#define TSE_PCS_SW_RST_MASK 0x8000 -#define TSE_PCS_PARTNER_ABILITY_REG 0x0A -#define TSE_PCS_PARTNER_DUPLEX_FULL 0x1000 -#define TSE_PCS_PARTNER_DUPLEX_HALF 0x0000 -#define TSE_PCS_PARTNER_DUPLEX_MASK 0x1000 -#define TSE_PCS_PARTNER_SPEED_MASK GENMASK(11, 10) -#define TSE_PCS_PARTNER_SPEED_1000 BIT(11) -#define TSE_PCS_PARTNER_SPEED_100 BIT(10) -#define TSE_PCS_PARTNER_SPEED_10 0x0000 -#define TSE_PCS_PARTNER_SPEED_1000 BIT(11) -#define TSE_PCS_PARTNER_SPEED_100 BIT(10) -#define TSE_PCS_PARTNER_SPEED_10 0x0000 -#define TSE_PCS_SGMII_SPEED_MASK GENMASK(3, 2) -#define TSE_PCS_SGMII_LINK_TIMER_0 0x0D40 -#define TSE_PCS_SGMII_LINK_TIMER_1 0x0003 -#define TSE_PCS_SW_RESET_TIMEOUT 100 -#define TSE_PCS_USE_SGMII_AN_MASK BIT(1) -#define TSE_PCS_USE_SGMII_ENA BIT(0) -#define TSE_PCS_IF_USE_SGMII 0x03 - -#define AUTONEGO_LINK_TIMER 20 - -static int tse_pcs_reset(void __iomem *base, struct tse_pcs *pcs) -{ - int counter =3D 0; - u16 val; - - val =3D readw(base + TSE_PCS_CONTROL_REG); - val |=3D TSE_PCS_SW_RST_MASK; - writew(val, base + TSE_PCS_CONTROL_REG); - - while (counter < TSE_PCS_SW_RESET_TIMEOUT) { - val =3D readw(base + TSE_PCS_CONTROL_REG); - val &=3D TSE_PCS_SW_RST_MASK; - if (val =3D=3D 0) - break; - counter++; - udelay(1); - } - if (counter >=3D TSE_PCS_SW_RESET_TIMEOUT) { - dev_err(pcs->dev, "PCS could not get out of sw reset\n"); - return -ETIMEDOUT; - } - - return 0; -} - -int tse_pcs_init(void __iomem *base, struct tse_pcs *pcs) -{ - int ret =3D 0; - - writew(TSE_PCS_IF_USE_SGMII, base + TSE_PCS_IF_MODE_REG); - - writew(TSE_PCS_CTRL_AUTONEG_SGMII, base + TSE_PCS_CONTROL_REG); - - writew(TSE_PCS_SGMII_LINK_TIMER_0, base + TSE_PCS_LINK_TIMER_0_REG); - writew(TSE_PCS_SGMII_LINK_TIMER_1, base + TSE_PCS_LINK_TIMER_1_REG); - - ret =3D tse_pcs_reset(base, pcs); - if (ret =3D=3D 0) - writew(SGMII_ADAPTER_ENABLE, - pcs->sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG); - - return ret; -} - -static void pcs_link_timer_callback(struct tse_pcs *pcs) -{ - u16 val =3D 0; - void __iomem *tse_pcs_base =3D pcs->tse_pcs_base; - void __iomem *sgmii_adapter_base =3D pcs->sgmii_adapter_base; - - val =3D readw(tse_pcs_base + TSE_PCS_STATUS_REG); - val &=3D TSE_PCS_STATUS_LINK_MASK; - - if (val !=3D 0) { - dev_dbg(pcs->dev, "Adapter: Link is established\n"); - writew(SGMII_ADAPTER_ENABLE, - sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG); - } else { - mod_timer(&pcs->aneg_link_timer, jiffies + - msecs_to_jiffies(AUTONEGO_LINK_TIMER)); - } -} - -static void auto_nego_timer_callback(struct tse_pcs *pcs) -{ - u16 val =3D 0; - u16 speed =3D 0; - u16 duplex =3D 0; - void __iomem *tse_pcs_base =3D pcs->tse_pcs_base; - void __iomem *sgmii_adapter_base =3D pcs->sgmii_adapter_base; - - val =3D readw(tse_pcs_base + TSE_PCS_STATUS_REG); - val &=3D TSE_PCS_STATUS_AN_COMPLETED_MASK; - - if (val !=3D 0) { - dev_dbg(pcs->dev, "Adapter: Auto Negotiation is completed\n"); - val =3D readw(tse_pcs_base + TSE_PCS_PARTNER_ABILITY_REG); - speed =3D val & TSE_PCS_PARTNER_SPEED_MASK; - duplex =3D val & TSE_PCS_PARTNER_DUPLEX_MASK; - - if (speed =3D=3D TSE_PCS_PARTNER_SPEED_10 && - duplex =3D=3D TSE_PCS_PARTNER_DUPLEX_FULL) - dev_dbg(pcs->dev, - "Adapter: Link Partner is Up - 10/Full\n"); - else if (speed =3D=3D TSE_PCS_PARTNER_SPEED_100 && - duplex =3D=3D TSE_PCS_PARTNER_DUPLEX_FULL) - dev_dbg(pcs->dev, - "Adapter: Link Partner is Up - 100/Full\n"); - else if (speed =3D=3D TSE_PCS_PARTNER_SPEED_1000 && - duplex =3D=3D TSE_PCS_PARTNER_DUPLEX_FULL) - dev_dbg(pcs->dev, - "Adapter: Link Partner is Up - 1000/Full\n"); - else if (speed =3D=3D TSE_PCS_PARTNER_SPEED_10 && - duplex =3D=3D TSE_PCS_PARTNER_DUPLEX_HALF) - dev_err(pcs->dev, - "Adapter does not support Half Duplex\n"); - else if (speed =3D=3D TSE_PCS_PARTNER_SPEED_100 && - duplex =3D=3D TSE_PCS_PARTNER_DUPLEX_HALF) - dev_err(pcs->dev, - "Adapter does not support Half Duplex\n"); - else if (speed =3D=3D TSE_PCS_PARTNER_SPEED_1000 && - duplex =3D=3D TSE_PCS_PARTNER_DUPLEX_HALF) - dev_err(pcs->dev, - "Adapter does not support Half Duplex\n"); - else - dev_err(pcs->dev, - "Adapter: Invalid Partner Speed and Duplex\n"); - - if (duplex =3D=3D TSE_PCS_PARTNER_DUPLEX_FULL && - (speed =3D=3D TSE_PCS_PARTNER_SPEED_10 || - speed =3D=3D TSE_PCS_PARTNER_SPEED_100 || - speed =3D=3D TSE_PCS_PARTNER_SPEED_1000)) - writew(SGMII_ADAPTER_ENABLE, - sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG); - } else { - val =3D readw(tse_pcs_base + TSE_PCS_CONTROL_REG); - val |=3D TSE_PCS_CONTROL_RESTART_AN_MASK; - writew(val, tse_pcs_base + TSE_PCS_CONTROL_REG); - - tse_pcs_reset(tse_pcs_base, pcs); - mod_timer(&pcs->aneg_link_timer, jiffies + - msecs_to_jiffies(AUTONEGO_LINK_TIMER)); - } -} - -static void aneg_link_timer_callback(struct timer_list *t) -{ - struct tse_pcs *pcs =3D from_timer(pcs, t, aneg_link_timer); - - if (pcs->autoneg =3D=3D AUTONEG_ENABLE) - auto_nego_timer_callback(pcs); - else if (pcs->autoneg =3D=3D AUTONEG_DISABLE) - pcs_link_timer_callback(pcs); -} - -void tse_pcs_fix_mac_speed(struct tse_pcs *pcs, struct phy_device *phy_dev, - unsigned int speed) -{ - void __iomem *tse_pcs_base =3D pcs->tse_pcs_base; - u32 val; - - pcs->autoneg =3D phy_dev->autoneg; - - if (phy_dev->autoneg =3D=3D AUTONEG_ENABLE) { - val =3D readw(tse_pcs_base + TSE_PCS_CONTROL_REG); - val |=3D TSE_PCS_CONTROL_AN_EN_MASK; - writew(val, tse_pcs_base + TSE_PCS_CONTROL_REG); - - val =3D readw(tse_pcs_base + TSE_PCS_IF_MODE_REG); - val |=3D TSE_PCS_USE_SGMII_AN_MASK; - writew(val, tse_pcs_base + TSE_PCS_IF_MODE_REG); - - val =3D readw(tse_pcs_base + TSE_PCS_CONTROL_REG); - val |=3D TSE_PCS_CONTROL_RESTART_AN_MASK; - - tse_pcs_reset(tse_pcs_base, pcs); - - timer_setup(&pcs->aneg_link_timer, aneg_link_timer_callback, - 0); - mod_timer(&pcs->aneg_link_timer, jiffies + - msecs_to_jiffies(AUTONEGO_LINK_TIMER)); - } else if (phy_dev->autoneg =3D=3D AUTONEG_DISABLE) { - val =3D readw(tse_pcs_base + TSE_PCS_CONTROL_REG); - val &=3D ~TSE_PCS_CONTROL_AN_EN_MASK; - writew(val, tse_pcs_base + TSE_PCS_CONTROL_REG); - - val =3D readw(tse_pcs_base + TSE_PCS_IF_MODE_REG); - val &=3D ~TSE_PCS_USE_SGMII_AN_MASK; - writew(val, tse_pcs_base + TSE_PCS_IF_MODE_REG); - - val =3D readw(tse_pcs_base + TSE_PCS_IF_MODE_REG); - val &=3D ~TSE_PCS_SGMII_SPEED_MASK; - - switch (speed) { - case 1000: - val |=3D TSE_PCS_SGMII_SPEED_1000; - break; - case 100: - val |=3D TSE_PCS_SGMII_SPEED_100; - break; - case 10: - val |=3D TSE_PCS_SGMII_SPEED_10; - break; - default: - return; - } - writew(val, tse_pcs_base + TSE_PCS_IF_MODE_REG); - - tse_pcs_reset(tse_pcs_base, pcs); - - timer_setup(&pcs->aneg_link_timer, aneg_link_timer_callback, - 0); - mod_timer(&pcs->aneg_link_timer, jiffies + - msecs_to_jiffies(AUTONEGO_LINK_TIMER)); - } -} diff --git a/drivers/net/ethernet/stmicro/stmmac/altr_tse_pcs.h b/drivers/n= et/ethernet/stmicro/stmmac/altr_tse_pcs.h deleted file mode 100644 index 694ac25ef426..000000000000 --- a/drivers/net/ethernet/stmicro/stmmac/altr_tse_pcs.h +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright Altera Corporation (C) 2016. All rights reserved. - * - * Author: Tien Hock Loh - */ - -#ifndef __TSE_PCS_H__ -#define __TSE_PCS_H__ - -#include -#include - -#define SGMII_ADAPTER_CTRL_REG 0x00 -#define SGMII_ADAPTER_ENABLE 0x0000 -#define SGMII_ADAPTER_DISABLE 0x0001 - -struct tse_pcs { - struct device *dev; - void __iomem *tse_pcs_base; - void __iomem *sgmii_adapter_base; - struct timer_list aneg_link_timer; - int autoneg; -}; - -int tse_pcs_init(void __iomem *base, struct tse_pcs *pcs); -void tse_pcs_fix_mac_speed(struct tse_pcs *pcs, struct phy_device *phy_dev, - unsigned int speed); - -#endif /* __TSE_PCS_H__ */ diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/eth= ernet/stmicro/stmmac/common.h index 4ad692c4116c..34751524775a 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -519,6 +519,7 @@ struct mac_device_info { const struct stmmac_tc_ops *tc; const struct stmmac_mmc_ops *mmc; struct dw_xpcs *xpcs; + struct phylink_pcs *phylink_pcs; /* Generic external PCS */ struct mii_regs mii; /* MII register Addresses */ struct mac_link link; void __iomem *pcsr; /* vpointer to device CSRs */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/= net/ethernet/stmicro/stmmac/dwmac-socfpga.c index 6ee050300b31..5f61b33905fc 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c @@ -10,14 +10,14 @@ #include #include #include +#include #include #include +#include =20 #include "stmmac.h" #include "stmmac_platform.h" =20 -#include "altr_tse_pcs.h" - #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII 0x0 #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII 0x1 #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII 0x2 @@ -37,6 +37,10 @@ #define EMAC_SPLITTER_CTRL_SPEED_100 0x3 #define EMAC_SPLITTER_CTRL_SPEED_1000 0x0 =20 +#define SGMII_ADAPTER_CTRL_REG 0x00 +#define SGMII_ADAPTER_ENABLE 0x0000 +#define SGMII_ADAPTER_DISABLE 0x0001 + struct socfpga_dwmac; struct socfpga_dwmac_ops { int (*set_phy_mode)(struct socfpga_dwmac *dwmac_priv); @@ -50,16 +54,18 @@ struct socfpga_dwmac { struct reset_control *stmmac_rst; struct reset_control *stmmac_ocp_rst; void __iomem *splitter_base; + void __iomem *tse_pcs_base; + void __iomem *sgmii_adapter_base; bool f2h_ptp_ref_clk; - struct tse_pcs pcs; const struct socfpga_dwmac_ops *ops; + struct mdio_device *pcs_mdiodev; }; =20 static void socfpga_dwmac_fix_mac_speed(void *priv, unsigned int speed) { struct socfpga_dwmac *dwmac =3D (struct socfpga_dwmac *)priv; void __iomem *splitter_base =3D dwmac->splitter_base; - void __iomem *sgmii_adapter_base =3D dwmac->pcs.sgmii_adapter_base; + void __iomem *sgmii_adapter_base =3D dwmac->sgmii_adapter_base; struct device *dev =3D dwmac->dev; struct net_device *ndev =3D dev_get_drvdata(dev); struct phy_device *phy_dev =3D ndev->phydev; @@ -89,11 +95,9 @@ static void socfpga_dwmac_fix_mac_speed(void *priv, unsi= gned int speed) writel(val, splitter_base + EMAC_SPLITTER_CTRL_REG); } =20 - if (phy_dev && sgmii_adapter_base) { + if (phy_dev && sgmii_adapter_base) writew(SGMII_ADAPTER_ENABLE, sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG); - tse_pcs_fix_mac_speed(&dwmac->pcs, phy_dev, speed); - } } =20 static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct de= vice *dev) @@ -183,11 +187,11 @@ static int socfpga_dwmac_parse_data(struct socfpga_dw= mac *dwmac, struct device * goto err_node_put; } =20 - dwmac->pcs.sgmii_adapter_base =3D + dwmac->sgmii_adapter_base =3D devm_ioremap_resource(dev, &res_sgmii_adapter); =20 - if (IS_ERR(dwmac->pcs.sgmii_adapter_base)) { - ret =3D PTR_ERR(dwmac->pcs.sgmii_adapter_base); + if (IS_ERR(dwmac->sgmii_adapter_base)) { + ret =3D PTR_ERR(dwmac->sgmii_adapter_base); goto err_node_put; } } @@ -205,11 +209,11 @@ static int socfpga_dwmac_parse_data(struct socfpga_dw= mac *dwmac, struct device * goto err_node_put; } =20 - dwmac->pcs.tse_pcs_base =3D + dwmac->tse_pcs_base =3D devm_ioremap_resource(dev, &res_tse_pcs); =20 - if (IS_ERR(dwmac->pcs.tse_pcs_base)) { - ret =3D PTR_ERR(dwmac->pcs.tse_pcs_base); + if (IS_ERR(dwmac->tse_pcs_base)) { + ret =3D PTR_ERR(dwmac->tse_pcs_base); goto err_node_put; } } @@ -235,6 +239,13 @@ static int socfpga_get_plat_phymode(struct socfpga_dwm= ac *dwmac) return priv->plat->interface; } =20 +static void socfpga_sgmii_config(struct socfpga_dwmac *dwmac, bool enable) +{ + u16 val =3D enable ? SGMII_ADAPTER_ENABLE : SGMII_ADAPTER_DISABLE; + + writew(val, dwmac->sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG); +} + static int socfpga_set_phy_mode_common(int phymode, u32 *val) { switch (phymode) { @@ -310,12 +321,8 @@ static int socfpga_gen5_set_phy_mode(struct socfpga_dw= mac *dwmac) */ reset_control_deassert(dwmac->stmmac_ocp_rst); reset_control_deassert(dwmac->stmmac_rst); - if (phymode =3D=3D PHY_INTERFACE_MODE_SGMII) { - if (tse_pcs_init(dwmac->pcs.tse_pcs_base, &dwmac->pcs) !=3D 0) { - dev_err(dwmac->dev, "Unable to initialize TSE PCS"); - return -EINVAL; - } - } + if (phymode =3D=3D PHY_INTERFACE_MODE_SGMII) + socfpga_sgmii_config(dwmac, true); =20 return 0; } @@ -367,12 +374,8 @@ static int socfpga_gen10_set_phy_mode(struct socfpga_d= wmac *dwmac) */ reset_control_deassert(dwmac->stmmac_ocp_rst); reset_control_deassert(dwmac->stmmac_rst); - if (phymode =3D=3D PHY_INTERFACE_MODE_SGMII) { - if (tse_pcs_init(dwmac->pcs.tse_pcs_base, &dwmac->pcs) !=3D 0) { - dev_err(dwmac->dev, "Unable to initialize TSE PCS"); - return -EINVAL; - } - } + if (phymode =3D=3D PHY_INTERFACE_MODE_SGMII) + socfpga_sgmii_config(dwmac, true); return 0; } =20 @@ -386,6 +389,14 @@ static int socfpga_dwmac_probe(struct platform_device = *pdev) struct net_device *ndev; struct stmmac_priv *stpriv; const struct socfpga_dwmac_ops *ops; + struct regmap_config pcs_regmap_cfg; + struct regmap *pcs_regmap; + struct mii_bus *pcs_bus; + + struct mdio_regmap_config mrc =3D { + .parent =3D &pdev->dev, + .valid_addr =3D 0x0, + }; =20 ops =3D device_get_match_data(&pdev->dev); if (!ops) { @@ -443,6 +454,35 @@ static int socfpga_dwmac_probe(struct platform_device = *pdev) if (ret) goto err_dvr_remove; =20 + memset(&pcs_regmap_cfg, 0, sizeof(pcs_regmap_cfg)); + pcs_regmap_cfg.reg_bits =3D 16; + pcs_regmap_cfg.val_bits =3D 16; + pcs_regmap_cfg.reg_shift =3D REGMAP_UPSHIFT(1); + + /* Create a regmap for the PCS so that it can be used by the PCS driver, + * if we have such a PCS + */ + if (dwmac->tse_pcs_base) { + pcs_regmap =3D devm_regmap_init_mmio(&pdev->dev, dwmac->tse_pcs_base, + &pcs_regmap_cfg); + if (IS_ERR(pcs_regmap)) { + ret =3D PTR_ERR(pcs_regmap); + goto err_dvr_remove; + } + + mrc.regmap =3D pcs_regmap; + + snprintf(mrc.name, MII_BUS_ID_SIZE, "%s-pcs-mii", ndev->name); + pcs_bus =3D devm_mdio_regmap_register(&pdev->dev, &mrc); + if (IS_ERR(pcs_bus)) { + ret =3D PTR_ERR(pcs_bus); + goto err_dvr_remove; + } + + dwmac->pcs_mdiodev =3D mdio_device_create(pcs_bus, 0); + stpriv->hw->phylink_pcs =3D lynx_pcs_create(dwmac->pcs_mdiodev); + } + return 0; =20 err_dvr_remove: diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/ne= t/ethernet/stmicro/stmmac/stmmac_main.c index 0fca81507a77..e570a95dd8d0 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -937,10 +937,13 @@ static struct phylink_pcs *stmmac_mac_select_pcs(stru= ct phylink_config *config, { struct stmmac_priv *priv =3D netdev_priv(to_net_dev(config->dev)); =20 - if (!priv->hw->xpcs) - return NULL; + if (priv->hw->xpcs) + return &priv->hw->xpcs->pcs; + + if (priv->hw->phylink_pcs) + return priv->hw->phylink_pcs; =20 - return &priv->hw->xpcs->pcs; + return NULL; } =20 static void stmmac_mac_config(struct phylink_config *config, unsigned int = mode, @@ -3813,7 +3816,8 @@ static int __stmmac_open(struct net_device *dev, if (priv->hw->pcs !=3D STMMAC_PCS_TBI && priv->hw->pcs !=3D STMMAC_PCS_RTBI && (!priv->hw->xpcs || - xpcs_get_an_mode(priv->hw->xpcs, mode) !=3D DW_AN_C73)) { + xpcs_get_an_mode(priv->hw->xpcs, mode) !=3D DW_AN_C73) && + !priv->hw->phylink_pcs) { ret =3D stmmac_init_phy(dev); if (ret) { netdev_err(priv->dev, --=20 2.40.1