Commit 642af0f9 authored by Maxime Chevallier's avatar Maxime Chevallier Committed by David S. Miller

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: default avatarMaxime Chevallier <maxime.chevallier@bootlin.com>
Reviewed-by: default avatarSimon Horman <simon.horman@corigine.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f69de8aa
...@@ -12844,6 +12844,13 @@ F: Documentation/devicetree/bindings/net/ieee802154/mcr20a.txt ...@@ -12844,6 +12844,13 @@ F: Documentation/devicetree/bindings/net/ieee802154/mcr20a.txt
F: drivers/net/ieee802154/mcr20a.c F: drivers/net/ieee802154/mcr20a.c
F: drivers/net/ieee802154/mcr20a.h F: drivers/net/ieee802154/mcr20a.h
MDIO REGMAP DRIVER
M: Maxime Chevallier <maxime.chevallier@bootlin.com>
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 MEASUREMENT COMPUTING CIO-DAC IIO DRIVER
M: William Breathitt Gray <william.gray@linaro.org> M: William Breathitt Gray <william.gray@linaro.org>
L: linux-iio@vger.kernel.org L: linux-iio@vger.kernel.org
......
...@@ -185,6 +185,17 @@ config MDIO_IPQ8064 ...@@ -185,6 +185,17 @@ config MDIO_IPQ8064
This driver supports the MDIO interface found in the network This driver supports the MDIO interface found in the network
interface units of the IPQ8064 SoC interface units of the IPQ8064 SoC
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. Users willing to use this driver must explicitly select
REGMAP.
config MDIO_THUNDER config MDIO_THUNDER
tristate "ThunderX SOCs MDIO buses" tristate "ThunderX SOCs MDIO buses"
depends on 64BIT depends on 64BIT
......
...@@ -19,6 +19,7 @@ obj-$(CONFIG_MDIO_MOXART) += mdio-moxart.o ...@@ -19,6 +19,7 @@ obj-$(CONFIG_MDIO_MOXART) += mdio-moxart.o
obj-$(CONFIG_MDIO_MSCC_MIIM) += mdio-mscc-miim.o obj-$(CONFIG_MDIO_MSCC_MIIM) += mdio-mscc-miim.o
obj-$(CONFIG_MDIO_MVUSB) += mdio-mvusb.o obj-$(CONFIG_MDIO_MVUSB) += mdio-mvusb.o
obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o
obj-$(CONFIG_MDIO_REGMAP) += mdio-regmap.o
obj-$(CONFIG_MDIO_SUN4I) += mdio-sun4i.o obj-$(CONFIG_MDIO_SUN4I) += mdio-sun4i.o
obj-$(CONFIG_MDIO_THUNDER) += mdio-thunder.o obj-$(CONFIG_MDIO_THUNDER) += mdio-thunder.o
obj-$(CONFIG_MDIO_XGENE) += mdio-xgene.o obj-$(CONFIG_MDIO_XGENE) += mdio-xgene.o
......
// SPDX-License-Identifier: GPL-2.0-or-later
/* Driver for MMIO-Mapped MDIO devices. Some IPs expose internal PHYs or PCS
* within the MMIO-mapped area
*
* Copyright (C) 2023 Maxime Chevallier <maxime.chevallier@bootlin.com>
*/
#include <linux/bitfield.h>
#include <linux/delay.h>
#include <linux/mdio.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_mdio.h>
#include <linux/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/mdio/mdio-regmap.h>
#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 = bus->priv;
unsigned int val;
int ret;
if (ctx->valid_addr != addr)
return -ENODEV;
ret = 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 = bus->priv;
if (ctx->valid_addr != 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 = devm_mdiobus_alloc_size(config->parent, sizeof(*mr));
if (!mii)
return ERR_PTR(-ENOMEM);
mr = mii->priv;
mr->regmap = config->regmap;
mr->valid_addr = config->valid_addr;
mii->name = DRV_NAME;
strscpy(mii->id, config->name, MII_BUS_ID_SIZE);
mii->parent = config->parent;
mii->read = mdio_regmap_read_c22;
mii->write = mdio_regmap_write_c22;
if (config->autoscan)
mii->phy_mask = ~BIT(config->valid_addr);
else
mii->phy_mask = ~0;
rc = 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 <maxime.chevallier@bootlin.com>");
MODULE_LICENSE("GPL");
/* SPDX-License-Identifier: GPL-2.0 */
/* Driver for MMIO-Mapped MDIO devices. Some IPs expose internal PHYs or PCS
* within the MMIO-mapped area
*
* Copyright (C) 2023 Maxime Chevallier <maxime.chevallier@bootlin.com>
*/
#ifndef MDIO_REGMAP_H
#define MDIO_REGMAP_H
#include <linux/phy.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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment