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

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

Merge branch 'net-phy-register-modifying-helpers'



Heiner Kallweit says:

====================
net: phy: add and use register modifying helpers returning 1 on change

Add and use register modifying helpers returning 1 on change.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 193dad2a 4f9744ed
Loading
Loading
Loading
Loading
+6 −7
Original line number Diff line number Diff line
@@ -141,10 +141,9 @@ 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 = phy_modify_mmd(phydev, MDIO_MMD_VEND2, MV_V2_TEMP_CTRL,
			     MV_V2_TEMP_CTRL_MASK, val);

	return ret < 0 ? ret : 0;
	return phy_modify_mmd(phydev, MDIO_MMD_VEND2, MV_V2_TEMP_CTRL,
			      MV_V2_TEMP_CTRL_MASK, val);
}

static void mv3310_hwmon_disable(void *data)
@@ -345,7 +344,7 @@ static int mv3310_config_aneg(struct phy_device *phydev)
	linkmode_and(phydev->advertising, phydev->advertising,
		     phydev->supported);

	ret = phy_modify_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE,
	ret = phy_modify_mmd_changed(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));
@@ -355,7 +354,7 @@ static int mv3310_config_aneg(struct phy_device *phydev)
		changed = true;

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

	ret = phy_modify_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
	ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
				     MDIO_AN_10GBT_CTRL_ADV10G, reg);
	if (ret < 0)
		return ret;
+118 −9
Original line number Diff line number Diff line
@@ -531,7 +531,7 @@ int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
EXPORT_SYMBOL(phy_write_mmd);

/**
 * __phy_modify() - Convenience function for modifying a PHY register
 * __phy_modify_changed() - Convenience function for modifying a PHY register
 * @phydev: a pointer to a &struct phy_device
 * @regnum: register number
 * @mask: bit mask of bits to clear
@@ -539,16 +539,69 @@ EXPORT_SYMBOL(phy_write_mmd);
 *
 * Unlocked helper function which allows a PHY register to be modified as
 * new register value = (old register value & ~mask) | set
 *
 * Returns negative errno, 0 if there was no change, and 1 in case of change
 */
int __phy_modify(struct phy_device *phydev, u32 regnum, u16 mask, u16 set)
int __phy_modify_changed(struct phy_device *phydev, u32 regnum, u16 mask,
			 u16 set)
{
	int ret;
	int new, ret;

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

	ret = __phy_write(phydev, regnum, (ret & ~mask) | set);
	new = (ret & ~mask) | set;
	if (new == ret)
		return 0;

	ret = __phy_write(phydev, regnum, new);

	return ret < 0 ? ret : 1;
}
EXPORT_SYMBOL_GPL(__phy_modify_changed);

/**
 * phy_modify_changed - Function for modifying a PHY register
 * @phydev: the phy_device struct
 * @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.
 *
 * Returns negative errno, 0 if there was no change, and 1 in case of change
 */
int phy_modify_changed(struct phy_device *phydev, u32 regnum, u16 mask, u16 set)
{
	int ret;

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

	return ret;
}
EXPORT_SYMBOL_GPL(phy_modify_changed);

/**
 * __phy_modify - Convenience function for modifying a PHY register
 * @phydev: the phy_device struct
 * @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(struct phy_device *phydev, u32 regnum, u16 mask, u16 set)
{
	int ret;

	ret = __phy_modify_changed(phydev, regnum, mask, set);

	return ret < 0 ? ret : 0;
}
@@ -578,7 +631,7 @@ 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
 * __phy_modify_mmd_changed - Function for modifying a register on MMD
 * @phydev: the phy_device struct
 * @devad: the MMD containing register to modify
 * @regnum: register number to modify
@@ -587,17 +640,73 @@ EXPORT_SYMBOL_GPL(phy_modify);
 *
 * Unlocked helper function which allows a MMD register to be modified as
 * new register value = (old register value & ~mask) | set
 *
 * Returns negative errno, 0 if there was no change, and 1 in case of change
 */
int __phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
int __phy_modify_mmd_changed(struct phy_device *phydev, int devad, u32 regnum,
			     u16 mask, u16 set)
{
	int ret;
	int new, ret;

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

	ret = __phy_write_mmd(phydev, devad, regnum, (ret & ~mask) | set);
	new = (ret & ~mask) | set;
	if (new == ret)
		return 0;

	ret = __phy_write_mmd(phydev, devad, regnum, new);

	return ret < 0 ? ret : 1;
}
EXPORT_SYMBOL_GPL(__phy_modify_mmd_changed);

/**
 * phy_modify_mmd_changed - 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.
 *
 * Returns negative errno, 0 if there was no change, and 1 in case of change
 */
int phy_modify_mmd_changed(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_changed(phydev, devad, regnum, mask, set);
	mutex_unlock(&phydev->mdio.bus->mdio_lock);

	return ret;
}
EXPORT_SYMBOL_GPL(phy_modify_mmd_changed);

/**
 * __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;

	ret = __phy_modify_mmd_changed(phydev, devad, regnum, mask, set);

	return ret < 0 ? ret : 0;
}
+15 −28
Original line number Diff line number Diff line
@@ -1516,7 +1516,7 @@ EXPORT_SYMBOL(phy_reset_after_clk_enable);
static int genphy_config_advert(struct phy_device *phydev)
{
	u32 advertise;
	int oldadv, adv, bmsr;
	int bmsr, adv;
	int err, changed = 0;

	/* Only allow advertising what this PHY supports */
@@ -1529,22 +1529,14 @@ static int genphy_config_advert(struct phy_device *phydev)
			    phydev->advertising);

	/* Setup standard advertisement */
	adv = phy_read(phydev, MII_ADVERTISE);
	if (adv < 0)
		return adv;

	oldadv = adv;
	adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP |
		 ADVERTISE_PAUSE_ASYM);
	adv |= ethtool_adv_to_mii_adv_t(advertise);

	if (adv != oldadv) {
		err = phy_write(phydev, MII_ADVERTISE, adv);

	err = phy_modify_changed(phydev, MII_ADVERTISE,
				 ADVERTISE_ALL | ADVERTISE_100BASE4 |
				 ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM,
				 ethtool_adv_to_mii_adv_t(advertise));
	if (err < 0)
		return err;
	if (err > 0)
		changed = 1;
	}

	bmsr = phy_read(phydev, MII_BMSR);
	if (bmsr < 0)
@@ -1558,25 +1550,20 @@ static int genphy_config_advert(struct phy_device *phydev)
		return changed;

	/* Configure gigabit if it's supported */
	adv = phy_read(phydev, MII_CTRL1000);
	if (adv < 0)
		return adv;

	oldadv = adv;
	adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);

	adv = 0;
	if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
			      phydev->supported) ||
	    linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
			      phydev->supported))
		adv |= ethtool_adv_to_mii_ctrl1000_t(advertise);
		adv = ethtool_adv_to_mii_ctrl1000_t(advertise);

	if (adv != oldadv)
		changed = 1;

	err = phy_write(phydev, MII_CTRL1000, adv);
	err = phy_modify_changed(phydev, MII_CTRL1000,
				 ADVERTISE_1000FULL | ADVERTISE_1000HALF,
				 adv);
	if (err < 0)
		return err;
	if (err > 0)
		changed = 1;

	return changed;
}
+10 −2
Original line number Diff line number Diff line
@@ -799,9 +799,17 @@ 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 __phy_modify_changed(struct phy_device *phydev, u32 regnum, u16 mask,
			 u16 set);
int phy_modify_changed(struct phy_device *phydev, u32 regnum, u16 mask,
		       u16 set);
int __phy_modify(struct phy_device *phydev, u32 regnum, u16 mask, u16 set);
int phy_modify(struct phy_device *phydev, u32 regnum, u16 mask, u16 set);

int __phy_modify_mmd_changed(struct phy_device *phydev, int devad, u32 regnum,
			     u16 mask, u16 set);
int phy_modify_mmd_changed(struct phy_device *phydev, int devad, u32 regnum,
			   u16 mask, u16 set);
int __phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,
		     u16 mask, u16 set);
int phy_modify_mmd(struct phy_device *phydev, int devad, u32 regnum,