Skip to content

Commit

Permalink
net: macb: Separate C22 and C45 transactions
Browse files Browse the repository at this point in the history
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 <andrew@lunn.ch>
Signed-off-by: Michael Walle <michael@walle.cc>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Andrew Lunn authored and Jakub Kicinski committed Jan 18, 2023
1 parent 064a6a8 commit a4d65b1
Showing 1 changed file with 108 additions and 53 deletions.
161 changes: 108 additions & 53 deletions drivers/net/ethernet/cadence/macb_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -385,8 +412,8 @@ static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
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;
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit a4d65b1

Please sign in to comment.