[PATCH net-next v3 2/4] net: dsa: mxl862xx: add SMDIO clause-22 register access
From: Daniel Golle <daniel@makrotopia.org>
Date: 2026-07-20 03:14:59
Also in:
lkml
Subsystem:
maxlinear mxl862xx switch driver, networking drivers, networking [dsa], the rest · Maintainers:
Daniel Golle, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Vladimir Oltean, Linus Torvalds
Add mxl862xx_smdio_read() and mxl862xx_smdio_write() for clause-22
SMDIO register access. MCUboot rescue mode only exposes clause-22
registers; the existing clause-45 MMD interface is unavailable during
firmware transfer. The MDIO bus lock is held per-transaction (not
across polls) so that SB PDI polling during flash erase does not
starve other non-switch users of the same MDIO bus, such as separate
PHYs providing WAN or management interfaces.
Unlike mxl862xx_api_wrap(), which takes the bus lock with
MDIO_MUTEX_NESTED because it can be entered from the accessors of
the switch-internal MDIO bus while that bus's lock of the same lock
class is already held, the SMDIO helpers take it with a plain
mutex_lock(). They are only called from probe and devlink flash
contexts where no other MDIO bus lock can be held.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
v3: explain the plain mutex_lock() vs MDIO_MUTEX_NESTED choice in
the commit message
v2: clarify in the commit message that the per-transaction bus
locking is about unrelated non-switch devices on the same MDIO
bus (Andrew Lunn)
drivers/net/dsa/mxl862xx/mxl862xx-host.c | 35 ++++++++++++++++++++++++
drivers/net/dsa/mxl862xx/mxl862xx-host.h | 2 ++
2 files changed, 37 insertions(+)
diff --git a/drivers/net/dsa/mxl862xx/mxl862xx-host.c b/drivers/net/dsa/mxl862xx/mxl862xx-host.c
index 4acd216f7cc0..6e582caea1fa 100644
--- a/drivers/net/dsa/mxl862xx/mxl862xx-host.c
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-host.c@@ -495,6 +495,41 @@ int mxl862xx_reset(struct mxl862xx_priv *priv) return ret; } +#define MXL862XX_SMDIO_ADDR_REG 0x1f +#define MXL862XX_SMDIO_PAGE_MASK 0xfff0 +#define MXL862XX_SMDIO_OFF_MASK 0x000f + +int mxl862xx_smdio_read(struct mxl862xx_priv *priv, u32 addr) +{ + struct mii_bus *bus = priv->mdiodev->bus; + int phy = priv->mdiodev->addr; + int ret; + + mutex_lock(&bus->mdio_lock); + ret = __mdiobus_write(bus, phy, MXL862XX_SMDIO_ADDR_REG, + addr & MXL862XX_SMDIO_PAGE_MASK); + if (ret >= 0) + ret = __mdiobus_read(bus, phy, addr & MXL862XX_SMDIO_OFF_MASK); + mutex_unlock(&bus->mdio_lock); + return ret; +} + +int mxl862xx_smdio_write(struct mxl862xx_priv *priv, u32 addr, u16 val) +{ + struct mii_bus *bus = priv->mdiodev->bus; + int phy = priv->mdiodev->addr; + int ret; + + mutex_lock(&bus->mdio_lock); + ret = __mdiobus_write(bus, phy, MXL862XX_SMDIO_ADDR_REG, + addr & MXL862XX_SMDIO_PAGE_MASK); + if (ret >= 0) + ret = __mdiobus_write(bus, phy, addr & MXL862XX_SMDIO_OFF_MASK, + val); + mutex_unlock(&bus->mdio_lock); + return ret; +} + void mxl862xx_host_init(struct mxl862xx_priv *priv) { INIT_WORK(&priv->crc_err_work, mxl862xx_crc_err_work_fn);
diff --git a/drivers/net/dsa/mxl862xx/mxl862xx-host.h b/drivers/net/dsa/mxl862xx/mxl862xx-host.h
index 66d6ae198aff..4e054c6e4c0e 100644
--- a/drivers/net/dsa/mxl862xx/mxl862xx-host.h
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-host.h@@ -18,5 +18,7 @@ int mxl862xx_api_wrap(struct mxl862xx_priv *priv, u16 cmd, void *data, u16 size, mxl862xx_api_wrap(dev, cmd, &(data), sizeof((data)), true, true) int mxl862xx_reset(struct mxl862xx_priv *priv); +int mxl862xx_smdio_read(struct mxl862xx_priv *priv, u32 addr); +int mxl862xx_smdio_write(struct mxl862xx_priv *priv, u32 addr, u16 val); #endif /* __MXL862XX_HOST_H */
--
2.55.0