Commit cfbd6de5 authored by Christian Marangi's avatar Christian Marangi Committed by David S. Miller
Browse files

net: dsa: qca8k: introduce single mii read/write lo/hi



It may be useful to read/write just the lo or hi half of a reg.

This is especially useful for phy poll with the use of mdio master.
The mdio master reg is composed by the first 16 bit related to setup and
the other half with the returned data or data to write.

Refactor the mii function to permit single mii read/write of lo or hi
half of the reg.

Tested-by: default avatarRonald Wahl <ronald.wahl@raritan.com>
Signed-off-by: default avatarChristian Marangi <ansuelsmth@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 03cb9e6d
Loading
Loading
Loading
Loading
+84 −22
Original line number Original line Diff line number Diff line
@@ -37,42 +37,104 @@ qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page)
}
}


static int
static int
qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
qca8k_mii_write_lo(struct mii_bus *bus, int phy_id, u32 regnum, u32 val)
{
{
	int ret;
	int ret;
	u16 lo;


	ret = bus->read(bus, phy_id, regnum);
	lo = val & 0xffff;
	if (ret >= 0) {
	ret = bus->write(bus, phy_id, regnum, lo);
		*val = ret;
	if (ret < 0)
		ret = bus->read(bus, phy_id, regnum + 1);
		dev_err_ratelimited(&bus->dev,
		*val |= ret << 16;
				    "failed to write qca8k 32bit lo register\n");

	return ret;
}
}


	if (ret < 0) {
static int
qca8k_mii_write_hi(struct mii_bus *bus, int phy_id, u32 regnum, u32 val)
{
	int ret;
	u16 hi;

	hi = (u16)(val >> 16);
	ret = bus->write(bus, phy_id, regnum, hi);
	if (ret < 0)
		dev_err_ratelimited(&bus->dev,
				    "failed to write qca8k 32bit hi register\n");

	return ret;
}

static int
qca8k_mii_read_lo(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
{
	int ret;

	ret = bus->read(bus, phy_id, regnum);
	if (ret < 0)
		goto err;

	*val = ret & 0xffff;
	return 0;

err:
	dev_err_ratelimited(&bus->dev,
	dev_err_ratelimited(&bus->dev,
				    "failed to read qca8k 32bit register\n");
			    "failed to read qca8k 32bit lo register\n");
	*val = 0;
	*val = 0;

	return ret;
	return ret;
}
}


static int
qca8k_mii_read_hi(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
{
	int ret;

	ret = bus->read(bus, phy_id, regnum);
	if (ret < 0)
		goto err;

	*val = ret << 16;
	return 0;
	return 0;

err:
	dev_err_ratelimited(&bus->dev,
			    "failed to read qca8k 32bit hi register\n");
	*val = 0;

	return ret;
}
}


static void
static int
qca8k_mii_write32(struct mii_bus *bus, int phy_id, u32 regnum, u32 val)
qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
{
{
	u16 lo, hi;
	u32 hi, lo;
	int ret;
	int ret;


	lo = val & 0xffff;
	*val = 0;
	hi = (u16)(val >> 16);


	ret = bus->write(bus, phy_id, regnum, lo);
	ret = qca8k_mii_read_lo(bus, phy_id, regnum, &lo);
	if (ret >= 0)
		ret = bus->write(bus, phy_id, regnum + 1, hi);
	if (ret < 0)
	if (ret < 0)
		dev_err_ratelimited(&bus->dev,
		goto err;
				    "failed to write qca8k 32bit register\n");

	ret = qca8k_mii_read_hi(bus, phy_id, regnum + 1, &hi);
	if (ret < 0)
		goto err;

	*val = lo | hi;

err:
	return ret;
}

static void
qca8k_mii_write32(struct mii_bus *bus, int phy_id, u32 regnum, u32 val)
{
	if (qca8k_mii_write_lo(bus, phy_id, regnum, val) < 0)
		return;

	qca8k_mii_write_hi(bus, phy_id, regnum + 1, val);
}
}


static int
static int