提交 a4d65b1d 编写于 作者: A Andrew Lunn 提交者: Jakub Kicinski

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: NAndrew Lunn <andrew@lunn.ch>
Signed-off-by: NMichael Walle <michael@walle.cc>
Signed-off-by: NJakub Kicinski <kuba@kernel.org>
上级 064a6a88
...@@ -334,7 +334,7 @@ static int macb_mdio_wait_for_idle(struct macb *bp) ...@@ -334,7 +334,7 @@ static int macb_mdio_wait_for_idle(struct macb *bp)
1, MACB_MDIO_TIMEOUT); 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; struct macb *bp = bus->priv;
int status; int status;
...@@ -347,31 +347,58 @@ static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum) ...@@ -347,31 +347,58 @@ static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
if (status < 0) if (status < 0)
goto mdio_read_exit; goto mdio_read_exit;
if (regnum & MII_ADDR_C45) { macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_C22_SOF)
macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_C45_SOF) | MACB_BF(RW, MACB_MAN_C22_READ)
| MACB_BF(RW, MACB_MAN_C45_ADDR) | MACB_BF(PHYA, mii_id)
| MACB_BF(PHYA, mii_id) | MACB_BF(REGA, regnum)
| MACB_BF(REGA, (regnum >> 16) & 0x1F) | MACB_BF(CODE, MACB_MAN_C22_CODE)));
| MACB_BF(DATA, regnum & 0xFFFF)
| MACB_BF(CODE, MACB_MAN_C45_CODE))); status = macb_mdio_wait_for_idle(bp);
if (status < 0)
status = macb_mdio_wait_for_idle(bp); goto mdio_read_exit;
if (status < 0)
goto mdio_read_exit; status = MACB_BFEXT(DATA, macb_readl(bp, MAN));
macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_C45_SOF) mdio_read_exit:
| MACB_BF(RW, MACB_MAN_C45_READ) pm_runtime_mark_last_busy(&bp->pdev->dev);
| MACB_BF(PHYA, mii_id) pm_runtime_put_autosuspend(&bp->pdev->dev);
| MACB_BF(REGA, (regnum >> 16) & 0x1F) mdio_pm_exit:
| MACB_BF(CODE, MACB_MAN_C45_CODE))); return status;
} else { }
macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_C22_SOF)
| MACB_BF(RW, MACB_MAN_C22_READ) static int macb_mdio_read_c45(struct mii_bus *bus, int mii_id, int devad,
| MACB_BF(PHYA, mii_id) int regnum)
| MACB_BF(REGA, regnum) {
| MACB_BF(CODE, MACB_MAN_C22_CODE))); 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); status = macb_mdio_wait_for_idle(bp);
if (status < 0) if (status < 0)
goto mdio_read_exit; goto mdio_read_exit;
...@@ -385,8 +412,8 @@ static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum) ...@@ -385,8 +412,8 @@ static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
return status; return status;
} }
static int macb_mdio_write(struct mii_bus *bus, int mii_id, int regnum, static int macb_mdio_write_c22(struct mii_bus *bus, int mii_id, int regnum,
u16 value) u16 value)
{ {
struct macb *bp = bus->priv; struct macb *bp = bus->priv;
int status; int status;
...@@ -399,37 +426,63 @@ static int macb_mdio_write(struct mii_bus *bus, int mii_id, int regnum, ...@@ -399,37 +426,63 @@ static int macb_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
if (status < 0) if (status < 0)
goto mdio_write_exit; goto mdio_write_exit;
if (regnum & MII_ADDR_C45) { macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_C22_SOF)
macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_C45_SOF) | MACB_BF(RW, MACB_MAN_C22_WRITE)
| MACB_BF(RW, MACB_MAN_C45_ADDR) | MACB_BF(PHYA, mii_id)
| MACB_BF(PHYA, mii_id) | MACB_BF(REGA, regnum)
| MACB_BF(REGA, (regnum >> 16) & 0x1F) | MACB_BF(CODE, MACB_MAN_C22_CODE)
| MACB_BF(DATA, regnum & 0xFFFF) | MACB_BF(DATA, value)));
| MACB_BF(CODE, MACB_MAN_C45_CODE)));
status = macb_mdio_wait_for_idle(bp);
status = macb_mdio_wait_for_idle(bp); if (status < 0)
if (status < 0) goto mdio_write_exit;
goto mdio_write_exit;
mdio_write_exit:
macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_C45_SOF) pm_runtime_mark_last_busy(&bp->pdev->dev);
| MACB_BF(RW, MACB_MAN_C45_WRITE) pm_runtime_put_autosuspend(&bp->pdev->dev);
| MACB_BF(PHYA, mii_id) mdio_pm_exit:
| MACB_BF(REGA, (regnum >> 16) & 0x1F) return status;
| MACB_BF(CODE, MACB_MAN_C45_CODE) }
| MACB_BF(DATA, value)));
} else { static int macb_mdio_write_c45(struct mii_bus *bus, int mii_id,
macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_C22_SOF) int devad, int regnum,
| MACB_BF(RW, MACB_MAN_C22_WRITE) u16 value)
| MACB_BF(PHYA, mii_id) {
| MACB_BF(REGA, regnum) struct macb *bp = bus->priv;
| MACB_BF(CODE, MACB_MAN_C22_CODE) int status;
| MACB_BF(DATA, value)));
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); status = macb_mdio_wait_for_idle(bp);
if (status < 0) if (status < 0)
goto mdio_write_exit; 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: mdio_write_exit:
pm_runtime_mark_last_busy(&bp->pdev->dev); pm_runtime_mark_last_busy(&bp->pdev->dev);
pm_runtime_put_autosuspend(&bp->pdev->dev); pm_runtime_put_autosuspend(&bp->pdev->dev);
...@@ -902,8 +955,10 @@ static int macb_mii_init(struct macb *bp) ...@@ -902,8 +955,10 @@ static int macb_mii_init(struct macb *bp)
} }
bp->mii_bus->name = "MACB_mii_bus"; bp->mii_bus->name = "MACB_mii_bus";
bp->mii_bus->read = &macb_mdio_read; bp->mii_bus->read = &macb_mdio_read_c22;
bp->mii_bus->write = &macb_mdio_write; 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", snprintf(bp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
bp->pdev->name, bp->pdev->id); bp->pdev->name, bp->pdev->id);
bp->mii_bus->priv = bp; bp->mii_bus->priv = bp;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册