From: Andrew Lunn Date: Mon, 16 Jan 2023 23:52:19 +0000 (+0100) Subject: net: macb: Separate C22 and C45 transactions X-Git-Tag: v6.6.7~3490^2~270^2~8 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a4d65b1de2a2034358027d272c878f46076929bb;p=platform%2Fkernel%2Flinux-starfive.git net: macb: Separate C22 and C45 transactions The macb MDIO bus driver can perform both C22 and C45 transfers. Create separate functions for each and register the C45 versions using the new API calls where appropriate. Signed-off-by: Andrew Lunn Signed-off-by: Michael Walle Signed-off-by: Jakub Kicinski --- diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 95667b979fab..f2d08a2dadf9 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -334,7 +334,7 @@ static int macb_mdio_wait_for_idle(struct macb *bp) 1, MACB_MDIO_TIMEOUT); } -static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum) +static int macb_mdio_read_c22(struct mii_bus *bus, int mii_id, int regnum) { struct macb *bp = bus->priv; int status; @@ -347,31 +347,58 @@ static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum) if (status < 0) goto mdio_read_exit; - if (regnum & MII_ADDR_C45) { - macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_C45_SOF) - | MACB_BF(RW, MACB_MAN_C45_ADDR) - | MACB_BF(PHYA, mii_id) - | MACB_BF(REGA, (regnum >> 16) & 0x1F) - | MACB_BF(DATA, regnum & 0xFFFF) - | MACB_BF(CODE, MACB_MAN_C45_CODE))); - - status = macb_mdio_wait_for_idle(bp); - if (status < 0) - goto mdio_read_exit; - - macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_C45_SOF) - | MACB_BF(RW, MACB_MAN_C45_READ) - | MACB_BF(PHYA, mii_id) - | MACB_BF(REGA, (regnum >> 16) & 0x1F) - | MACB_BF(CODE, MACB_MAN_C45_CODE))); - } else { - macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_C22_SOF) - | MACB_BF(RW, MACB_MAN_C22_READ) - | MACB_BF(PHYA, mii_id) - | MACB_BF(REGA, regnum) - | MACB_BF(CODE, MACB_MAN_C22_CODE))); + macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_C22_SOF) + | MACB_BF(RW, MACB_MAN_C22_READ) + | MACB_BF(PHYA, mii_id) + | MACB_BF(REGA, regnum) + | MACB_BF(CODE, MACB_MAN_C22_CODE))); + + status = macb_mdio_wait_for_idle(bp); + if (status < 0) + goto mdio_read_exit; + + status = MACB_BFEXT(DATA, macb_readl(bp, MAN)); + +mdio_read_exit: + pm_runtime_mark_last_busy(&bp->pdev->dev); + pm_runtime_put_autosuspend(&bp->pdev->dev); +mdio_pm_exit: + return status; +} + +static int macb_mdio_read_c45(struct mii_bus *bus, int mii_id, int devad, + int regnum) +{ + struct macb *bp = bus->priv; + int status; + + status = pm_runtime_get_sync(&bp->pdev->dev); + if (status < 0) { + pm_runtime_put_noidle(&bp->pdev->dev); + goto mdio_pm_exit; } + status = macb_mdio_wait_for_idle(bp); + if (status < 0) + goto mdio_read_exit; + + macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_C45_SOF) + | MACB_BF(RW, MACB_MAN_C45_ADDR) + | MACB_BF(PHYA, mii_id) + | MACB_BF(REGA, devad & 0x1F) + | MACB_BF(DATA, regnum & 0xFFFF) + | MACB_BF(CODE, MACB_MAN_C45_CODE))); + + status = macb_mdio_wait_for_idle(bp); + if (status < 0) + goto mdio_read_exit; + + macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_C45_SOF) + | MACB_BF(RW, MACB_MAN_C45_READ) + | MACB_BF(PHYA, mii_id) + | MACB_BF(REGA, devad & 0x1F) + | MACB_BF(CODE, MACB_MAN_C45_CODE))); + status = macb_mdio_wait_for_idle(bp); if (status < 0) goto mdio_read_exit; @@ -385,8 +412,8 @@ mdio_pm_exit: return status; } -static int macb_mdio_write(struct mii_bus *bus, int mii_id, int regnum, - u16 value) +static int macb_mdio_write_c22(struct mii_bus *bus, int mii_id, int regnum, + u16 value) { struct macb *bp = bus->priv; int status; @@ -399,37 +426,63 @@ static int macb_mdio_write(struct mii_bus *bus, int mii_id, int regnum, if (status < 0) goto mdio_write_exit; - if (regnum & MII_ADDR_C45) { - macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_C45_SOF) - | MACB_BF(RW, MACB_MAN_C45_ADDR) - | MACB_BF(PHYA, mii_id) - | MACB_BF(REGA, (regnum >> 16) & 0x1F) - | MACB_BF(DATA, regnum & 0xFFFF) - | MACB_BF(CODE, MACB_MAN_C45_CODE))); - - status = macb_mdio_wait_for_idle(bp); - if (status < 0) - goto mdio_write_exit; - - macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_C45_SOF) - | MACB_BF(RW, MACB_MAN_C45_WRITE) - | MACB_BF(PHYA, mii_id) - | MACB_BF(REGA, (regnum >> 16) & 0x1F) - | MACB_BF(CODE, MACB_MAN_C45_CODE) - | MACB_BF(DATA, value))); - } else { - macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_C22_SOF) - | MACB_BF(RW, MACB_MAN_C22_WRITE) - | MACB_BF(PHYA, mii_id) - | MACB_BF(REGA, regnum) - | MACB_BF(CODE, MACB_MAN_C22_CODE) - | MACB_BF(DATA, value))); + macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_C22_SOF) + | MACB_BF(RW, MACB_MAN_C22_WRITE) + | MACB_BF(PHYA, mii_id) + | MACB_BF(REGA, regnum) + | MACB_BF(CODE, MACB_MAN_C22_CODE) + | MACB_BF(DATA, value))); + + status = macb_mdio_wait_for_idle(bp); + if (status < 0) + goto mdio_write_exit; + +mdio_write_exit: + pm_runtime_mark_last_busy(&bp->pdev->dev); + pm_runtime_put_autosuspend(&bp->pdev->dev); +mdio_pm_exit: + return status; +} + +static int macb_mdio_write_c45(struct mii_bus *bus, int mii_id, + int devad, int regnum, + u16 value) +{ + struct macb *bp = bus->priv; + int status; + + status = pm_runtime_get_sync(&bp->pdev->dev); + if (status < 0) { + pm_runtime_put_noidle(&bp->pdev->dev); + goto mdio_pm_exit; } status = macb_mdio_wait_for_idle(bp); if (status < 0) goto mdio_write_exit; + macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_C45_SOF) + | MACB_BF(RW, MACB_MAN_C45_ADDR) + | MACB_BF(PHYA, mii_id) + | MACB_BF(REGA, devad & 0x1F) + | MACB_BF(DATA, regnum & 0xFFFF) + | MACB_BF(CODE, MACB_MAN_C45_CODE))); + + status = macb_mdio_wait_for_idle(bp); + if (status < 0) + goto mdio_write_exit; + + macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_C45_SOF) + | MACB_BF(RW, MACB_MAN_C45_WRITE) + | MACB_BF(PHYA, mii_id) + | MACB_BF(REGA, devad & 0x1F) + | MACB_BF(CODE, MACB_MAN_C45_CODE) + | MACB_BF(DATA, value))); + + status = macb_mdio_wait_for_idle(bp); + if (status < 0) + goto mdio_write_exit; + mdio_write_exit: pm_runtime_mark_last_busy(&bp->pdev->dev); pm_runtime_put_autosuspend(&bp->pdev->dev); @@ -902,8 +955,10 @@ static int macb_mii_init(struct macb *bp) } bp->mii_bus->name = "MACB_mii_bus"; - bp->mii_bus->read = &macb_mdio_read; - bp->mii_bus->write = &macb_mdio_write; + bp->mii_bus->read = &macb_mdio_read_c22; + bp->mii_bus->write = &macb_mdio_write_c22; + bp->mii_bus->read_c45 = &macb_mdio_read_c45; + bp->mii_bus->write_c45 = &macb_mdio_write_c45; snprintf(bp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x", bp->pdev->name, bp->pdev->id); bp->mii_bus->priv = bp;