Commit a4d65b1d authored by Andrew Lunn's avatar Andrew Lunn Committed by Jakub Kicinski
Browse files

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: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarMichael Walle <michael@walle.cc>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 064a6a88
Loading
Loading
Loading
Loading
+108 −53
Original line number Diff line number Diff line
@@ -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,11 +347,45 @@ 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_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, (regnum >> 16) & 0x1F)
			      | MACB_BF(REGA, devad & 0x1F)
			      | MACB_BF(DATA, regnum & 0xFFFF)
			      | MACB_BF(CODE, MACB_MAN_C45_CODE)));

@@ -362,15 +396,8 @@ static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
	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(REGA, devad & 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)));
	}

	status = macb_mdio_wait_for_idle(bp);
	if (status < 0)
@@ -385,7 +412,7 @@ 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,
static int macb_mdio_write_c22(struct mii_bus *bus, int mii_id, int regnum,
			       u16 value)
{
	struct macb *bp = bus->priv;
@@ -399,11 +426,45 @@ 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_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, (regnum >> 16) & 0x1F)
			      | MACB_BF(REGA, devad & 0x1F)
			      | MACB_BF(DATA, regnum & 0xFFFF)
			      | MACB_BF(CODE, MACB_MAN_C45_CODE)));

@@ -414,17 +475,9 @@ static int macb_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
	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(REGA, devad & 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)));
	}

	status = macb_mdio_wait_for_idle(bp);
	if (status < 0)
@@ -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;