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

Commit d1420bb9 authored by Heiner Kallweit's avatar Heiner Kallweit Committed by David S. Miller
Browse files

net: phy: improve generic EEE ethtool functions



So far the two functions consider neither member eee_enabled nor
eee_active. Therefore network drivers have to do this in some kind
of glue code. I think this can be avoided.

Getting EEE parameters:
When not advertising any EEE mode, we can't consider EEE to be enabled.
Therefore interpret "EEE enabled" as "we advertise at least one EEE
mode". It's similar with "EEE active": interpret it as "EEE modes
advertised by both link partner have at least one mode in common".

Setting EEE parameters:
If eee_enabled isn't set, don't advertise any EEE mode and restart
aneg if needed to switch off EEE. If eee_enabled is set and
data->advertised is empty (e.g. because EEE was disabled), advertise
everything we support as default. This way EEE can easily switched
on/off by doing ethtool --set-eee <if> eee on/off, w/o any additional
parameters.

The changes to both functions shouldn't break any existing user.
Once the changes have been applied, at least some users can be
simplified.

Signed-off-by: default avatarHeiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 79dfab43
Loading
Loading
Loading
Loading
+10 −5
Original line number Diff line number Diff line
@@ -1144,6 +1144,7 @@ int phy_ethtool_get_eee(struct phy_device *phydev, struct ethtool_eee *data)
	if (val < 0)
		return val;
	data->advertised = mmd_eee_adv_to_ethtool_adv_t(val);
	data->eee_enabled = !!data->advertised;

	/* Get LP advertisement EEE */
	val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_LPABLE);
@@ -1151,6 +1152,8 @@ int phy_ethtool_get_eee(struct phy_device *phydev, struct ethtool_eee *data)
		return val;
	data->lp_advertised = mmd_eee_adv_to_ethtool_adv_t(val);

	data->eee_active = !!(data->advertised & data->lp_advertised);

	return 0;
}
EXPORT_SYMBOL(phy_ethtool_get_eee);
@@ -1164,7 +1167,7 @@ EXPORT_SYMBOL(phy_ethtool_get_eee);
 */
int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data)
{
	int cap, old_adv, adv, ret;
	int cap, old_adv, adv = 0, ret;

	if (!phydev->drv)
		return -EIO;
@@ -1178,10 +1181,12 @@ int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data)
	if (old_adv < 0)
		return old_adv;

	adv = ethtool_adv_to_mmd_eee_adv_t(data->advertised) & cap;

	if (data->eee_enabled) {
		adv = !data->advertised ? cap :
		      ethtool_adv_to_mmd_eee_adv_t(data->advertised) & cap;
		/* Mask prohibited EEE modes */
		adv &= ~phydev->eee_broken_modes;
	}

	if (old_adv != adv) {
		ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, adv);