summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c
diff options
context:
space:
mode:
authorClayton Rayment <clayton.rayment@xilinx.com>2020-11-03 12:26:10 +0100
committerJakub Kicinski <kuba@kernel.org>2020-11-07 20:13:52 +0100
commit253761a0e61b7128460e26e74f57356e3eb2072e (patch)
tree94615efc7b8e8524a434bf261ec7e9c0251e6507 /drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c
parentnet: xilinx: axiethernet: Introduce helper functions for MDC enable/disable (diff)
downloadlinux-253761a0e61b7128460e26e74f57356e3eb2072e.tar.xz
linux-253761a0e61b7128460e26e74f57356e3eb2072e.zip
net: xilinx: axiethernet: Enable dynamic MDIO MDC
MDIO spec does not require an MDC at all times, only when MDIO transactions are occurring. This patch allows the xilinx_axienet driver to disable the MDC when not in use, and re-enable it when needed. It also simplifies the driver by removing MDC disable and enable in device reset sequence. Signed-off-by: Clayton Rayment <clayton.rayment@xilinx.com> Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@xilinx.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c')
-rw-r--r--drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c
index 84d06bf051ee..9c014cee34b2 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c
@@ -65,9 +65,13 @@ static int axienet_mdio_read(struct mii_bus *bus, int phy_id, int reg)
int ret;
struct axienet_local *lp = bus->priv;
+ axienet_mdio_mdc_enable(lp);
+
ret = axienet_mdio_wait_until_ready(lp);
- if (ret < 0)
+ if (ret < 0) {
+ axienet_mdio_mdc_disable(lp);
return ret;
+ }
axienet_iow(lp, XAE_MDIO_MCR_OFFSET,
(((phy_id << XAE_MDIO_MCR_PHYAD_SHIFT) &
@@ -78,14 +82,17 @@ static int axienet_mdio_read(struct mii_bus *bus, int phy_id, int reg)
XAE_MDIO_MCR_OP_READ_MASK));
ret = axienet_mdio_wait_until_ready(lp);
- if (ret < 0)
+ if (ret < 0) {
+ axienet_mdio_mdc_disable(lp);
return ret;
+ }
rc = axienet_ior(lp, XAE_MDIO_MRD_OFFSET) & 0x0000FFFF;
dev_dbg(lp->dev, "axienet_mdio_read(phy_id=%i, reg=%x) == %x\n",
phy_id, reg, rc);
+ axienet_mdio_mdc_disable(lp);
return rc;
}
@@ -111,9 +118,13 @@ static int axienet_mdio_write(struct mii_bus *bus, int phy_id, int reg,
dev_dbg(lp->dev, "axienet_mdio_write(phy_id=%i, reg=%x, val=%x)\n",
phy_id, reg, val);
+ axienet_mdio_mdc_enable(lp);
+
ret = axienet_mdio_wait_until_ready(lp);
- if (ret < 0)
+ if (ret < 0) {
+ axienet_mdio_mdc_disable(lp);
return ret;
+ }
axienet_iow(lp, XAE_MDIO_MWD_OFFSET, (u32) val);
axienet_iow(lp, XAE_MDIO_MCR_OFFSET,
@@ -125,8 +136,11 @@ static int axienet_mdio_write(struct mii_bus *bus, int phy_id, int reg,
XAE_MDIO_MCR_OP_WRITE_MASK));
ret = axienet_mdio_wait_until_ready(lp);
- if (ret < 0)
+ if (ret < 0) {
+ axienet_mdio_mdc_disable(lp);
return ret;
+ }
+ axienet_mdio_mdc_disable(lp);
return 0;
}
@@ -230,8 +244,8 @@ void axienet_mdio_disable(struct axienet_local *lp)
* Return: 0 on success, -ETIMEDOUT on a timeout, -ENOMEM when
* mdiobus_alloc (to allocate memory for mii bus structure) fails.
*
- * Sets up the MDIO interface by initializing the MDIO clock and enabling the
- * MDIO interface in hardware. Register the MDIO interface.
+ * Sets up the MDIO interface by initializing the MDIO clock.
+ * Register the MDIO interface.
**/
int axienet_mdio_setup(struct axienet_local *lp)
{
@@ -265,6 +279,7 @@ int axienet_mdio_setup(struct axienet_local *lp)
lp->mii_bus = NULL;
return ret;
}
+ axienet_mdio_mdc_disable(lp);
return 0;
}