Commit da1b0b5c authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net-mdio-continue-separating-c22-and-c45'

Michael Walle says:

====================
net: mdio: Continue separating C22 and C45

I've picked this older series from Andrew up and rebased it onto
the latest net-next.

This is the second patch set in the series which separates the C22
and C45 MDIO bus transactions at the API level to the MDIO bus drivers.
====================

Link: https://lore.kernel.org/r/20230112-net-next-c45-seperation-part-2-v1-0-5eeaae931526@walle.cc


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 9b7fe804 80e87442
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -954,8 +954,10 @@ static int vsc9959_mdio_bus_alloc(struct ocelot *ocelot)
		return -ENOMEM;

	bus->name = "VSC9959 internal MDIO bus";
	bus->read = enetc_mdio_read;
	bus->write = enetc_mdio_write;
	bus->read = enetc_mdio_read_c22;
	bus->write = enetc_mdio_write_c22;
	bus->read_c45 = enetc_mdio_read_c45;
	bus->write_c45 = enetc_mdio_write_c45;
	bus->parent = dev;
	mdio_priv = bus->priv;
	mdio_priv->hw = hw;
+89 −30
Original line number Diff line number Diff line
@@ -55,7 +55,8 @@ static int enetc_mdio_wait_complete(struct enetc_mdio_priv *mdio_priv)
				  is_busy, !is_busy, 10, 10 * 1000);
}

int enetc_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 value)
int enetc_mdio_write_c22(struct mii_bus *bus, int phy_id, int regnum,
			 u16 value)
{
	struct enetc_mdio_priv *mdio_priv = bus->priv;
	u32 mdio_ctl, mdio_cfg;
@@ -63,14 +64,39 @@ int enetc_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 value)
	int ret;

	mdio_cfg = ENETC_EMDIO_CFG;
	if (regnum & MII_ADDR_C45) {
		dev_addr = (regnum >> 16) & 0x1f;
		mdio_cfg |= MDIO_CFG_ENC45;
	} else {
		/* clause 22 (ie 1G) */
	dev_addr = regnum & 0x1f;
	mdio_cfg &= ~MDIO_CFG_ENC45;

	enetc_mdio_wr(mdio_priv, ENETC_MDIO_CFG, mdio_cfg);

	ret = enetc_mdio_wait_complete(mdio_priv);
	if (ret)
		return ret;

	/* set port and dev addr */
	mdio_ctl = MDIO_CTL_PORT_ADDR(phy_id) | MDIO_CTL_DEV_ADDR(dev_addr);
	enetc_mdio_wr(mdio_priv, ENETC_MDIO_CTL, mdio_ctl);

	/* write the value */
	enetc_mdio_wr(mdio_priv, ENETC_MDIO_DATA, value);

	ret = enetc_mdio_wait_complete(mdio_priv);
	if (ret)
		return ret;

	return 0;
}
EXPORT_SYMBOL_GPL(enetc_mdio_write_c22);

int enetc_mdio_write_c45(struct mii_bus *bus, int phy_id, int dev_addr,
			 int regnum, u16 value)
{
	struct enetc_mdio_priv *mdio_priv = bus->priv;
	u32 mdio_ctl, mdio_cfg;
	int ret;

	mdio_cfg = ENETC_EMDIO_CFG;
	mdio_cfg |= MDIO_CFG_ENC45;

	enetc_mdio_wr(mdio_priv, ENETC_MDIO_CFG, mdio_cfg);

@@ -83,13 +109,11 @@ int enetc_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 value)
	enetc_mdio_wr(mdio_priv, ENETC_MDIO_CTL, mdio_ctl);

	/* set the register address */
	if (regnum & MII_ADDR_C45) {
	enetc_mdio_wr(mdio_priv, ENETC_MDIO_ADDR, regnum & 0xffff);

	ret = enetc_mdio_wait_complete(mdio_priv);
	if (ret)
		return ret;
	}

	/* write the value */
	enetc_mdio_wr(mdio_priv, ENETC_MDIO_DATA, value);
@@ -100,9 +124,9 @@ int enetc_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 value)

	return 0;
}
EXPORT_SYMBOL_GPL(enetc_mdio_write);
EXPORT_SYMBOL_GPL(enetc_mdio_write_c45);

int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
int enetc_mdio_read_c22(struct mii_bus *bus, int phy_id, int regnum)
{
	struct enetc_mdio_priv *mdio_priv = bus->priv;
	u32 mdio_ctl, mdio_cfg;
@@ -110,14 +134,51 @@ int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
	int ret;

	mdio_cfg = ENETC_EMDIO_CFG;
	if (regnum & MII_ADDR_C45) {
		dev_addr = (regnum >> 16) & 0x1f;
		mdio_cfg |= MDIO_CFG_ENC45;
	} else {
	dev_addr = regnum & 0x1f;
	mdio_cfg &= ~MDIO_CFG_ENC45;

	enetc_mdio_wr(mdio_priv, ENETC_MDIO_CFG, mdio_cfg);

	ret = enetc_mdio_wait_complete(mdio_priv);
	if (ret)
		return ret;

	/* set port and device addr */
	mdio_ctl = MDIO_CTL_PORT_ADDR(phy_id) | MDIO_CTL_DEV_ADDR(dev_addr);
	enetc_mdio_wr(mdio_priv, ENETC_MDIO_CTL, mdio_ctl);

	/* initiate the read */
	enetc_mdio_wr(mdio_priv, ENETC_MDIO_CTL, mdio_ctl | MDIO_CTL_READ);

	ret = enetc_mdio_wait_complete(mdio_priv);
	if (ret)
		return ret;

	/* return all Fs if nothing was there */
	if (enetc_mdio_rd(mdio_priv, ENETC_MDIO_CFG) & MDIO_CFG_RD_ER) {
		dev_dbg(&bus->dev,
			"Error while reading PHY%d reg at %d.%d\n",
			phy_id, dev_addr, regnum);
		return 0xffff;
	}

	value = enetc_mdio_rd(mdio_priv, ENETC_MDIO_DATA) & 0xffff;

	return value;
}
EXPORT_SYMBOL_GPL(enetc_mdio_read_c22);

int enetc_mdio_read_c45(struct mii_bus *bus, int phy_id, int dev_addr,
			int regnum)
{
	struct enetc_mdio_priv *mdio_priv = bus->priv;
	u32 mdio_ctl, mdio_cfg;
	u16 value;
	int ret;

	mdio_cfg = ENETC_EMDIO_CFG;
	mdio_cfg |= MDIO_CFG_ENC45;

	enetc_mdio_wr(mdio_priv, ENETC_MDIO_CFG, mdio_cfg);

	ret = enetc_mdio_wait_complete(mdio_priv);
@@ -129,13 +190,11 @@ int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
	enetc_mdio_wr(mdio_priv, ENETC_MDIO_CTL, mdio_ctl);

	/* set the register address */
	if (regnum & MII_ADDR_C45) {
	enetc_mdio_wr(mdio_priv, ENETC_MDIO_ADDR, regnum & 0xffff);

	ret = enetc_mdio_wait_complete(mdio_priv);
	if (ret)
		return ret;
	}

	/* initiate the read */
	enetc_mdio_wr(mdio_priv, ENETC_MDIO_CTL, mdio_ctl | MDIO_CTL_READ);
@@ -156,7 +215,7 @@ int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum)

	return value;
}
EXPORT_SYMBOL_GPL(enetc_mdio_read);
EXPORT_SYMBOL_GPL(enetc_mdio_read_c45);

struct enetc_hw *enetc_hw_alloc(struct device *dev, void __iomem *port_regs)
{
+4 −2
Original line number Diff line number Diff line
@@ -39,8 +39,10 @@ static int enetc_pci_mdio_probe(struct pci_dev *pdev,
	}

	bus->name = ENETC_MDIO_BUS_NAME;
	bus->read = enetc_mdio_read;
	bus->write = enetc_mdio_write;
	bus->read = enetc_mdio_read_c22;
	bus->write = enetc_mdio_write_c22;
	bus->read_c45 = enetc_mdio_read_c45;
	bus->write_c45 = enetc_mdio_write_c45;
	bus->parent = dev;
	mdio_priv = bus->priv;
	mdio_priv->hw = hw;
+8 −4
Original line number Diff line number Diff line
@@ -848,8 +848,10 @@ static int enetc_mdio_probe(struct enetc_pf *pf, struct device_node *np)
		return -ENOMEM;

	bus->name = "Freescale ENETC MDIO Bus";
	bus->read = enetc_mdio_read;
	bus->write = enetc_mdio_write;
	bus->read = enetc_mdio_read_c22;
	bus->write = enetc_mdio_write_c22;
	bus->read_c45 = enetc_mdio_read_c45;
	bus->write_c45 = enetc_mdio_write_c45;
	bus->parent = dev;
	mdio_priv = bus->priv;
	mdio_priv->hw = &pf->si->hw;
@@ -885,8 +887,10 @@ static int enetc_imdio_create(struct enetc_pf *pf)
		return -ENOMEM;

	bus->name = "Freescale ENETC internal MDIO Bus";
	bus->read = enetc_mdio_read;
	bus->write = enetc_mdio_write;
	bus->read = enetc_mdio_read_c22;
	bus->write = enetc_mdio_write_c22;
	bus->read_c45 = enetc_mdio_read_c45;
	bus->write_c45 = enetc_mdio_write_c45;
	bus->parent = dev;
	bus->phy_mask = ~0;
	mdio_priv = bus->priv;
+112 −66
Original line number Diff line number Diff line
@@ -215,7 +215,7 @@ static int mtk_mdio_busy_wait(struct mtk_eth *eth)
	return -ETIMEDOUT;
}

static int _mtk_mdio_write(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg,
static int _mtk_mdio_write_c22(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg,
			       u32 write_data)
{
	int ret;
@@ -224,13 +224,36 @@ static int _mtk_mdio_write(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg,
	if (ret < 0)
		return ret;

	if (phy_reg & MII_ADDR_C45) {
	mtk_w32(eth, PHY_IAC_ACCESS |
		PHY_IAC_START_C22 |
		PHY_IAC_CMD_WRITE |
		PHY_IAC_REG(phy_reg) |
		PHY_IAC_ADDR(phy_addr) |
		PHY_IAC_DATA(write_data),
		MTK_PHY_IAC);

	ret = mtk_mdio_busy_wait(eth);
	if (ret < 0)
		return ret;

	return 0;
}

static int _mtk_mdio_write_c45(struct mtk_eth *eth, u32 phy_addr,
			       u32 devad, u32 phy_reg, u32 write_data)
{
	int ret;

	ret = mtk_mdio_busy_wait(eth);
	if (ret < 0)
		return ret;

	mtk_w32(eth, PHY_IAC_ACCESS |
		PHY_IAC_START_C45 |
		PHY_IAC_CMD_C45_ADDR |
			     PHY_IAC_REG(mdiobus_c45_devad(phy_reg)) |
		PHY_IAC_REG(devad) |
		PHY_IAC_ADDR(phy_addr) |
			     PHY_IAC_DATA(mdiobus_c45_regad(phy_reg)),
		PHY_IAC_DATA(phy_reg),
		MTK_PHY_IAC);

	ret = mtk_mdio_busy_wait(eth);
@@ -240,28 +263,42 @@ static int _mtk_mdio_write(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg,
	mtk_w32(eth, PHY_IAC_ACCESS |
		PHY_IAC_START_C45 |
		PHY_IAC_CMD_WRITE |
			     PHY_IAC_REG(mdiobus_c45_devad(phy_reg)) |
		PHY_IAC_REG(devad) |
		PHY_IAC_ADDR(phy_addr) |
		PHY_IAC_DATA(write_data),
		MTK_PHY_IAC);
	} else {

	ret = mtk_mdio_busy_wait(eth);
	if (ret < 0)
		return ret;

	return 0;
}

static int _mtk_mdio_read_c22(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg)
{
	int ret;

	ret = mtk_mdio_busy_wait(eth);
	if (ret < 0)
		return ret;

	mtk_w32(eth, PHY_IAC_ACCESS |
		PHY_IAC_START_C22 |
			     PHY_IAC_CMD_WRITE |
		PHY_IAC_CMD_C22_READ |
		PHY_IAC_REG(phy_reg) |
			     PHY_IAC_ADDR(phy_addr) |
			     PHY_IAC_DATA(write_data),
		PHY_IAC_ADDR(phy_addr),
		MTK_PHY_IAC);
	}

	ret = mtk_mdio_busy_wait(eth);
	if (ret < 0)
		return ret;

	return 0;
	return mtk_r32(eth, MTK_PHY_IAC) & PHY_IAC_DATA_MASK;
}

static int _mtk_mdio_read(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg)
static int _mtk_mdio_read_c45(struct mtk_eth *eth, u32 phy_addr,
			      u32 devad, u32 phy_reg)
{
	int ret;

@@ -269,13 +306,12 @@ static int _mtk_mdio_read(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg)
	if (ret < 0)
		return ret;

	if (phy_reg & MII_ADDR_C45) {
	mtk_w32(eth, PHY_IAC_ACCESS |
		PHY_IAC_START_C45 |
		PHY_IAC_CMD_C45_ADDR |
			     PHY_IAC_REG(mdiobus_c45_devad(phy_reg)) |
		PHY_IAC_REG(devad) |
		PHY_IAC_ADDR(phy_addr) |
			     PHY_IAC_DATA(mdiobus_c45_regad(phy_reg)),
		PHY_IAC_DATA(phy_reg),
		MTK_PHY_IAC);

	ret = mtk_mdio_busy_wait(eth);
@@ -285,17 +321,9 @@ static int _mtk_mdio_read(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg)
	mtk_w32(eth, PHY_IAC_ACCESS |
		PHY_IAC_START_C45 |
		PHY_IAC_CMD_C45_READ |
			     PHY_IAC_REG(mdiobus_c45_devad(phy_reg)) |
			     PHY_IAC_ADDR(phy_addr),
			MTK_PHY_IAC);
	} else {
		mtk_w32(eth, PHY_IAC_ACCESS |
			     PHY_IAC_START_C22 |
			     PHY_IAC_CMD_C22_READ |
			     PHY_IAC_REG(phy_reg) |
		PHY_IAC_REG(devad) |
		PHY_IAC_ADDR(phy_addr),
		MTK_PHY_IAC);
	}

	ret = mtk_mdio_busy_wait(eth);
	if (ret < 0)
@@ -304,19 +332,35 @@ static int _mtk_mdio_read(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg)
	return mtk_r32(eth, MTK_PHY_IAC) & PHY_IAC_DATA_MASK;
}

static int mtk_mdio_write(struct mii_bus *bus, int phy_addr,
static int mtk_mdio_write_c22(struct mii_bus *bus, int phy_addr,
			      int phy_reg, u16 val)
{
	struct mtk_eth *eth = bus->priv;

	return _mtk_mdio_write(eth, phy_addr, phy_reg, val);
	return _mtk_mdio_write_c22(eth, phy_addr, phy_reg, val);
}

static int mtk_mdio_write_c45(struct mii_bus *bus, int phy_addr,
			      int devad, int phy_reg, u16 val)
{
	struct mtk_eth *eth = bus->priv;

	return _mtk_mdio_write_c45(eth, phy_addr, devad, phy_reg, val);
}

static int mtk_mdio_read_c22(struct mii_bus *bus, int phy_addr, int phy_reg)
{
	struct mtk_eth *eth = bus->priv;

	return _mtk_mdio_read_c22(eth, phy_addr, phy_reg);
}

static int mtk_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg)
static int mtk_mdio_read_c45(struct mii_bus *bus, int phy_addr, int devad,
			     int phy_reg)
{
	struct mtk_eth *eth = bus->priv;

	return _mtk_mdio_read(eth, phy_addr, phy_reg);
	return _mtk_mdio_read_c45(eth, phy_addr, devad, phy_reg);
}

static int mt7621_gmac0_rgmii_adjust(struct mtk_eth *eth,
@@ -760,8 +804,10 @@ static int mtk_mdio_init(struct mtk_eth *eth)
	}

	eth->mii_bus->name = "mdio";
	eth->mii_bus->read = mtk_mdio_read;
	eth->mii_bus->write = mtk_mdio_write;
	eth->mii_bus->read = mtk_mdio_read_c22;
	eth->mii_bus->write = mtk_mdio_write_c22;
	eth->mii_bus->read_c45 = mtk_mdio_read_c45;
	eth->mii_bus->write_c45 = mtk_mdio_write_c45;
	eth->mii_bus->probe_capabilities = MDIOBUS_C22_C45;
	eth->mii_bus->priv = eth;
	eth->mii_bus->parent = eth->dev;
Loading