Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d9b5a675 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'net-phy-add-and-use-further-MMD-accessors'



Heiner Kallweit says:

====================
net: phy: add and use further MMD accessors

Add MMD accessors for modifying MMD registers and clearing / setting
bits in MMD registers. Use these accessors in PHY drivers and phylib.

v2:
- fix SoB in patch 2
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 5661f29a b52c018d
Loading
Loading
Loading
Loading
+17 −30
Original line number Diff line number Diff line
@@ -127,17 +127,13 @@ static int dp83867_config_port_mirroring(struct phy_device *phydev)
{
	struct dp83867_private *dp83867 =
		(struct dp83867_private *)phydev->priv;
	u16 val;

	val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4);

	if (dp83867->port_mirroring == DP83867_PORT_MIRROING_EN)
		val |= DP83867_CFG4_PORT_MIRROR_EN;
		phy_set_bits_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4,
				 DP83867_CFG4_PORT_MIRROR_EN);
	else
		val &= ~DP83867_CFG4_PORT_MIRROR_EN;

	phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4, val);

		phy_clear_bits_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4,
				   DP83867_CFG4_PORT_MIRROR_EN);
	return 0;
}

@@ -222,11 +218,9 @@ static int dp83867_config_init(struct phy_device *phydev)
	}

	/* RX_DV/RX_CTRL strapped in mode 1 or mode 2 workaround */
	if (dp83867->rxctrl_strap_quirk) {
		val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4);
		val &= ~BIT(7);
		phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4, val);
	}
	if (dp83867->rxctrl_strap_quirk)
		phy_clear_bits_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4,
				   BIT(7));

	if (phy_interface_is_rgmii(phydev)) {
		val = phy_read(phydev, MII_DP83867_PHYCTRL);
@@ -275,17 +269,11 @@ static int dp83867_config_init(struct phy_device *phydev)
		phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RGMIIDCTL,
			      delay);

		if (dp83867->io_impedance >= 0) {
			val = phy_read_mmd(phydev, DP83867_DEVADDR,
					   DP83867_IO_MUX_CFG);

			val &= ~DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL;
			val |= dp83867->io_impedance &
			       DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL;

			phy_write_mmd(phydev, DP83867_DEVADDR,
				      DP83867_IO_MUX_CFG, val);
		}
		if (dp83867->io_impedance >= 0)
			phy_modify_mmd(phydev, DP83867_DEVADDR, DP83867_IO_MUX_CFG,
				       DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL,
				       dp83867->io_impedance &
				       DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL);
	}

	/* Enable Interrupt output INT_OE in CFG3 register */
@@ -299,12 +287,11 @@ static int dp83867_config_init(struct phy_device *phydev)
		dp83867_config_port_mirroring(phydev);

	/* Clock output selection if muxing property is set */
	if (dp83867->clk_output_sel != DP83867_CLK_O_SEL_REF_CLK) {
		val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_IO_MUX_CFG);
		val &= ~DP83867_IO_MUX_CFG_CLK_O_SEL_MASK;
		val |= (dp83867->clk_output_sel << DP83867_IO_MUX_CFG_CLK_O_SEL_SHIFT);
		phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_IO_MUX_CFG, val);
	}
	if (dp83867->clk_output_sel != DP83867_CLK_O_SEL_REF_CLK)
		phy_modify_mmd(phydev, DP83867_DEVADDR, DP83867_IO_MUX_CFG,
			       DP83867_IO_MUX_CFG_CLK_O_SEL_MASK,
			       dp83867->clk_output_sel <<
			       DP83867_IO_MUX_CFG_CLK_O_SEL_SHIFT);

	return 0;
}
+4 −11
Original line number Diff line number Diff line
@@ -144,11 +144,8 @@ static int dp83811_set_wol(struct phy_device *phydev,
		phy_write_mmd(phydev, DP83811_DEVADDR, MII_DP83811_WOL_CFG,
			      value);
	} else {
		value = phy_read_mmd(phydev, DP83811_DEVADDR,
				     MII_DP83811_WOL_CFG);
		value &= ~DP83811_WOL_EN;
		phy_write_mmd(phydev, DP83811_DEVADDR, MII_DP83811_WOL_CFG,
			      value);
		phy_clear_bits_mmd(phydev, DP83811_DEVADDR, MII_DP83811_WOL_CFG,
				   DP83811_WOL_EN);
	}

	return 0;
@@ -328,13 +325,9 @@ static int dp83811_suspend(struct phy_device *phydev)

static int dp83811_resume(struct phy_device *phydev)
{
	int value;

	genphy_resume(phydev);

	value = phy_read_mmd(phydev, DP83811_DEVADDR, MII_DP83811_WOL_CFG);

	phy_write_mmd(phydev, DP83811_DEVADDR, MII_DP83811_WOL_CFG, value |
	phy_set_bits_mmd(phydev, DP83811_DEVADDR, MII_DP83811_WOL_CFG,
			 DP83811_WOL_CLR_INDICATION);

	return 0;
+10 −28
Original line number Diff line number Diff line
@@ -58,24 +58,6 @@ struct mv3310_priv {
	char *hwmon_name;
};

static int mv3310_modify(struct phy_device *phydev, int devad, u16 reg,
			 u16 mask, u16 bits)
{
	int old, val, ret;

	old = phy_read_mmd(phydev, devad, reg);
	if (old < 0)
		return old;

	val = (old & ~mask) | (bits & mask);
	if (val == old)
		return 0;

	ret = phy_write_mmd(phydev, devad, reg, val);

	return ret < 0 ? ret : 1;
}

#ifdef CONFIG_HWMON
static umode_t mv3310_hwmon_is_visible(const void *data,
				       enum hwmon_sensor_types type,
@@ -159,7 +141,7 @@ static int mv3310_hwmon_config(struct phy_device *phydev, bool enable)
		return ret;

	val = enable ? MV_V2_TEMP_CTRL_SAMPLE : MV_V2_TEMP_CTRL_DISABLE;
	ret = mv3310_modify(phydev, MDIO_MMD_VEND2, MV_V2_TEMP_CTRL,
	ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, MV_V2_TEMP_CTRL,
			     MV_V2_TEMP_CTRL_MASK, val);

	return ret < 0 ? ret : 0;
@@ -363,7 +345,7 @@ static int mv3310_config_aneg(struct phy_device *phydev)
	linkmode_and(phydev->advertising, phydev->advertising,
		     phydev->supported);

	ret = mv3310_modify(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE,
	ret = phy_modify_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE,
			     ADVERTISE_ALL | ADVERTISE_100BASE4 |
			     ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM,
			     linkmode_adv_to_mii_adv_t(phydev->advertising));
@@ -373,7 +355,7 @@ static int mv3310_config_aneg(struct phy_device *phydev)
		changed = true;

	reg = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising);
	ret = mv3310_modify(phydev, MDIO_MMD_AN, MV_AN_CTRL1000,
	ret = phy_modify_mmd(phydev, MDIO_MMD_AN, MV_AN_CTRL1000,
			     ADVERTISE_1000FULL | ADVERTISE_1000HALF, reg);
	if (ret < 0)
		return ret;
@@ -387,7 +369,7 @@ static int mv3310_config_aneg(struct phy_device *phydev)
	else
		reg = 0;

	ret = mv3310_modify(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
	ret = phy_modify_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
			     MDIO_AN_10GBT_CTRL_ADV10G, reg);
	if (ret < 0)
		return ret;
+4 −17
Original line number Diff line number Diff line
@@ -75,15 +75,9 @@ EXPORT_SYMBOL_GPL(genphy_c45_pma_setup_forced);
 */
int genphy_c45_an_disable_aneg(struct phy_device *phydev)
{
	int val;

	val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1);
	if (val < 0)
		return val;

	val &= ~(MDIO_AN_CTRL1_ENABLE | MDIO_AN_CTRL1_RESTART);

	return phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1, val);
	return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1,
				  MDIO_AN_CTRL1_ENABLE | MDIO_AN_CTRL1_RESTART);
}
EXPORT_SYMBOL_GPL(genphy_c45_an_disable_aneg);

@@ -97,15 +91,8 @@ EXPORT_SYMBOL_GPL(genphy_c45_an_disable_aneg);
 */
int genphy_c45_restart_aneg(struct phy_device *phydev)
{
	int val;

	val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1);
	if (val < 0)
		return val;

	val |= MDIO_AN_CTRL1_ENABLE | MDIO_AN_CTRL1_RESTART;

	return phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1, val);
	return phy_set_bits_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1,
				MDIO_AN_CTRL1_ENABLE | MDIO_AN_CTRL1_RESTART);
}
EXPORT_SYMBOL_GPL(genphy_c45_restart_aneg);

+103 −13
Original line number Diff line number Diff line
@@ -414,15 +414,15 @@ static void mmd_phy_indirect(struct mii_bus *bus, int phy_addr, int devad,
}

/**
 * phy_read_mmd - Convenience function for reading a register
 * __phy_read_mmd - Convenience function for reading a register
 * from an MMD on a given PHY.
 * @phydev: The phy_device struct
 * @devad: The MMD to read from (0..31)
 * @regnum: The register on the MMD to read (0..65535)
 *
 * Same rules as for phy_read();
 * Same rules as for __phy_read();
 */
int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
int __phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
{
	int val;

@@ -434,33 +434,52 @@ int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
	} else if (phydev->is_c45) {
		u32 addr = MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff);

		val = mdiobus_read(phydev->mdio.bus, phydev->mdio.addr, addr);
		val = __mdiobus_read(phydev->mdio.bus, phydev->mdio.addr, addr);
	} else {
		struct mii_bus *bus = phydev->mdio.bus;
		int phy_addr = phydev->mdio.addr;

		mutex_lock(&bus->mdio_lock);
		mmd_phy_indirect(bus, phy_addr, devad, regnum);

		/* Read the content of the MMD's selected register */
		val = __mdiobus_read(bus, phy_addr, MII_MMD_DATA);
		mutex_unlock(&bus->mdio_lock);
	}
	return val;
}
EXPORT_SYMBOL(__phy_read_mmd);

/**
 * phy_read_mmd - Convenience function for reading a register
 * from an MMD on a given PHY.
 * @phydev: The phy_device struct
 * @devad: The MMD to read from
 * @regnum: The register on the MMD to read
 *
 * Same rules as for phy_read();
 */
int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum)
{
	int ret;

	mutex_lock(&phydev->mdio.bus->mdio_lock);
	ret = __phy_read_mmd(phydev, devad, regnum);
	mutex_unlock(&phydev->mdio.bus->mdio_lock);

	return ret;
}
EXPORT_SYMBOL(phy_read_mmd);

/**
 * phy_write_mmd - Convenience function for writing a register
 * __phy_write_mmd - Convenience function for writing a register
 * on an MMD on a given PHY.
 * @phydev: The phy_device struct
 * @devad: The MMD to read from
 * @regnum: The register on the MMD to read
 * @val: value to write to @regnum
 *
 * Same rules as for phy_write();
 * Same rules as for __phy_write();
 */
int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
int __phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
{
	int ret;

@@ -472,23 +491,43 @@ int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
	} else if (phydev->is_c45) {
		u32 addr = MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff);

		ret = mdiobus_write(phydev->mdio.bus, phydev->mdio.addr,
		ret = __mdiobus_write(phydev->mdio.bus, phydev->mdio.addr,
				      addr, val);
	} else {
		struct mii_bus *bus = phydev->mdio.bus;
		int phy_addr = phydev->mdio.addr;

		mutex_lock(&bus->mdio_lock);
		mmd_phy_indirect(bus, phy_addr, devad, regnum);

		/* Write the data into MMD's selected register */
		__mdiobus_write(bus, phy_addr, MII_MMD_DATA, val);
		mutex_unlock(&bus->mdio_lock);

		ret = 0;
	}
	return ret;
}
EXPORT_SYMBOL(__phy_write_mmd);

/**
 * phy_write_mmd - Convenience function for writing a register
 * on an MMD on a given PHY.
 * @phydev: The phy_device struct
 * @devad: The MMD to read from
 * @regnum: The register on the MMD to read
 * @val: value to write to @regnum
 *
 * Same rules as for phy_write();
 */
int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
{
	int ret;

	mutex_lock(&phydev->mdio.bus->mdio_lock);
	ret = __phy_write_mmd(phydev, devad, regnum, val);
	mutex_unlock(&phydev->mdio.bus->mdio_lock);

	return ret;
}
EXPORT_SYMBOL(phy_write_mmd);

/**
@@ -538,6 +577,57 @@ int phy_modify(struct phy_device *phydev, u32 regnum, u16 mask, u16 set)
}
EXPORT_SYMBOL_GPL(phy_modify);

/**
 * __phy_modify_mmd - Convenience function for modifying a register on MMD
 * @phydev: the phy_device struct
 * @devad: the MMD containing register to modify
 * @regnum: register number to modify
 * @mask: bit mask of bits to clear
 * @set: new value of bits set in mask to write to @regnum
 *
 * Unlocked helper function which allows a MMD register to be modified as
 * new register value = (old register value & ~mask) | set
 */
int __phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
		     u16 mask, u16 set)
{
	int ret;

	ret = __phy_read_mmd(phydev, devad, regnum);
	if (ret < 0)
		return ret;

	ret = __phy_write_mmd(phydev, devad, regnum, (ret & ~mask) | set);

	return ret < 0 ? ret : 0;
}
EXPORT_SYMBOL_GPL(__phy_modify_mmd);

/**
 * phy_modify_mmd - Convenience function for modifying a register on MMD
 * @phydev: the phy_device struct
 * @devad: the MMD containing register to modify
 * @regnum: register number to modify
 * @mask: bit mask of bits to clear
 * @set: new value of bits set in mask to write to @regnum
 *
 * NOTE: MUST NOT be called from interrupt context,
 * because the bus read/write functions may wait for an interrupt
 * to conclude the operation.
 */
int phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
		   u16 mask, u16 set)
{
	int ret;

	mutex_lock(&phydev->mdio.bus->mdio_lock);
	ret = __phy_modify_mmd(phydev, devad, regnum, mask, set);
	mutex_unlock(&phydev->mdio.bus->mdio_lock);

	return ret;
}
EXPORT_SYMBOL_GPL(phy_modify_mmd);

static int __phy_read_page(struct phy_device *phydev)
{
	return phydev->drv->read_page(phydev);
Loading