Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net: mdio: Introduce a regmap-based mdio driver

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 <maxime.chevallier@bootlin.com>
Reviewed-by: Simon Horman <simon.horman@corigine.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Maxime Chevallier and committed by
David S. Miller
642af0f9 f69de8aa

+138
+7
MAINTAINERS
··· 12844 12844 F: drivers/net/ieee802154/mcr20a.c 12845 12845 F: drivers/net/ieee802154/mcr20a.h 12846 12846 12847 + MDIO REGMAP DRIVER 12848 + M: Maxime Chevallier <maxime.chevallier@bootlin.com> 12849 + L: netdev@vger.kernel.org 12850 + S: Maintained 12851 + F: drivers/net/mdio/mdio-regmap.c 12852 + F: include/linux/mdio/mdio-regmap.h 12853 + 12847 12854 MEASUREMENT COMPUTING CIO-DAC IIO DRIVER 12848 12855 M: William Breathitt Gray <william.gray@linaro.org> 12849 12856 L: linux-iio@vger.kernel.org
+11
drivers/net/mdio/Kconfig
··· 185 185 This driver supports the MDIO interface found in the network 186 186 interface units of the IPQ8064 SoC 187 187 188 + config MDIO_REGMAP 189 + tristate 190 + help 191 + This driver allows using MDIO devices that are not sitting on a 192 + regular MDIO bus, but still exposes the standard 802.3 register 193 + layout. It's regmap-based so that it can be used on integrated, 194 + memory-mapped PHYs, SPI PHYs and so on. A new virtual MDIO bus is 195 + created, and its read/write operations are mapped to the underlying 196 + regmap. Users willing to use this driver must explicitly select 197 + REGMAP. 198 + 188 199 config MDIO_THUNDER 189 200 tristate "ThunderX SOCs MDIO buses" 190 201 depends on 64BIT
+1
drivers/net/mdio/Makefile
··· 19 19 obj-$(CONFIG_MDIO_MSCC_MIIM) += mdio-mscc-miim.o 20 20 obj-$(CONFIG_MDIO_MVUSB) += mdio-mvusb.o 21 21 obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o 22 + obj-$(CONFIG_MDIO_REGMAP) += mdio-regmap.o 22 23 obj-$(CONFIG_MDIO_SUN4I) += mdio-sun4i.o 23 24 obj-$(CONFIG_MDIO_THUNDER) += mdio-thunder.o 24 25 obj-$(CONFIG_MDIO_XGENE) += mdio-xgene.o
+93
drivers/net/mdio/mdio-regmap.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* Driver for MMIO-Mapped MDIO devices. Some IPs expose internal PHYs or PCS 3 + * within the MMIO-mapped area 4 + * 5 + * Copyright (C) 2023 Maxime Chevallier <maxime.chevallier@bootlin.com> 6 + */ 7 + #include <linux/bitfield.h> 8 + #include <linux/delay.h> 9 + #include <linux/mdio.h> 10 + #include <linux/module.h> 11 + #include <linux/of.h> 12 + #include <linux/of_mdio.h> 13 + #include <linux/phy.h> 14 + #include <linux/platform_device.h> 15 + #include <linux/regmap.h> 16 + #include <linux/mdio/mdio-regmap.h> 17 + 18 + #define DRV_NAME "mdio-regmap" 19 + 20 + struct mdio_regmap_priv { 21 + struct regmap *regmap; 22 + u8 valid_addr; 23 + }; 24 + 25 + static int mdio_regmap_read_c22(struct mii_bus *bus, int addr, int regnum) 26 + { 27 + struct mdio_regmap_priv *ctx = bus->priv; 28 + unsigned int val; 29 + int ret; 30 + 31 + if (ctx->valid_addr != addr) 32 + return -ENODEV; 33 + 34 + ret = regmap_read(ctx->regmap, regnum, &val); 35 + if (ret < 0) 36 + return ret; 37 + 38 + return val; 39 + } 40 + 41 + static int mdio_regmap_write_c22(struct mii_bus *bus, int addr, int regnum, 42 + u16 val) 43 + { 44 + struct mdio_regmap_priv *ctx = bus->priv; 45 + 46 + if (ctx->valid_addr != addr) 47 + return -ENODEV; 48 + 49 + return regmap_write(ctx->regmap, regnum, val); 50 + } 51 + 52 + struct mii_bus *devm_mdio_regmap_register(struct device *dev, 53 + const struct mdio_regmap_config *config) 54 + { 55 + struct mdio_regmap_priv *mr; 56 + struct mii_bus *mii; 57 + int rc; 58 + 59 + if (!config->parent) 60 + return ERR_PTR(-EINVAL); 61 + 62 + mii = devm_mdiobus_alloc_size(config->parent, sizeof(*mr)); 63 + if (!mii) 64 + return ERR_PTR(-ENOMEM); 65 + 66 + mr = mii->priv; 67 + mr->regmap = config->regmap; 68 + mr->valid_addr = config->valid_addr; 69 + 70 + mii->name = DRV_NAME; 71 + strscpy(mii->id, config->name, MII_BUS_ID_SIZE); 72 + mii->parent = config->parent; 73 + mii->read = mdio_regmap_read_c22; 74 + mii->write = mdio_regmap_write_c22; 75 + 76 + if (config->autoscan) 77 + mii->phy_mask = ~BIT(config->valid_addr); 78 + else 79 + mii->phy_mask = ~0; 80 + 81 + rc = devm_mdiobus_register(dev, mii); 82 + if (rc) { 83 + dev_err(config->parent, "Cannot register MDIO bus![%s] (%d)\n", mii->id, rc); 84 + return ERR_PTR(rc); 85 + } 86 + 87 + return mii; 88 + } 89 + EXPORT_SYMBOL_GPL(devm_mdio_regmap_register); 90 + 91 + MODULE_DESCRIPTION("MDIO API over regmap"); 92 + MODULE_AUTHOR("Maxime Chevallier <maxime.chevallier@bootlin.com>"); 93 + MODULE_LICENSE("GPL");
+26
include/linux/mdio/mdio-regmap.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* Driver for MMIO-Mapped MDIO devices. Some IPs expose internal PHYs or PCS 3 + * within the MMIO-mapped area 4 + * 5 + * Copyright (C) 2023 Maxime Chevallier <maxime.chevallier@bootlin.com> 6 + */ 7 + #ifndef MDIO_REGMAP_H 8 + #define MDIO_REGMAP_H 9 + 10 + #include <linux/phy.h> 11 + 12 + struct device; 13 + struct regmap; 14 + 15 + struct mdio_regmap_config { 16 + struct device *parent; 17 + struct regmap *regmap; 18 + char name[MII_BUS_ID_SIZE]; 19 + u8 valid_addr; 20 + bool autoscan; 21 + }; 22 + 23 + struct mii_bus *devm_mdio_regmap_register(struct device *dev, 24 + const struct mdio_regmap_config *config); 25 + 26 + #endif