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

Commit 83ea067f authored by Russell King's avatar Russell King Committed by David S. Miller
Browse files

net: phy: avoid setting unsupported EEE advertisments



We currently allow userspace to set any EEE advertisments it desires,
whether or not the PHY supports them.  For example:

 # ethtool --set-eee eth1 advertise 0xffffffff
 # ethtool --show-eee eth1
 EEE Settings for eth1:
        EEE status: disabled
        Tx LPI: disabled
        Supported EEE link modes:  100baseT/Full
                                   1000baseT/Full
                                   10000baseT/Full
        Advertised EEE link modes:  100baseT/Full
                                    1000baseT/Full
                                    1000baseKX/Full
                                    10000baseT/Full
                                    10000baseKX4/Full
                                    10000baseKR/Full

Clearly, this is not sane, we should only allow link modes that are
supported to be advertised (as we do elsewhere.)  Ensure that we mask
the MDIO_AN_EEE_ADV value with the capabilities retrieved from the
MDIO_PCS_EEE_ABLE register.

Reviewed-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Signed-off-by: default avatarRussell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent eefe06e8
Loading
Loading
Loading
Loading
+10 −5
Original line number Diff line number Diff line
@@ -1332,17 +1332,22 @@ EXPORT_SYMBOL(phy_ethtool_get_eee);
 */
int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data)
{
	int val = ethtool_adv_to_mmd_eee_adv_t(data->advertised);
	int cap, adv;

	if (!phydev->drv)
		return -EIO;

	/* Mask prohibited EEE modes */
	val &= ~phydev->eee_broken_modes;
	/* Get Supported EEE */
	cap = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE);
	if (cap < 0)
		return cap;

	phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val);
	adv = ethtool_adv_to_mmd_eee_adv_t(data->advertised) & cap;

	return 0;
	/* Mask prohibited EEE modes */
	adv &= ~phydev->eee_broken_modes;

	return phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, adv);
}
EXPORT_SYMBOL(phy_ethtool_set_eee);