Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'net-phy-eee-fixes'

Oleksij Rempel says:

====================
net: phy: EEE fixes

changes v3:
- add kernel test robot tags to commit log
- reword comment for genphy_c45_an_config_eee_aneg() function

changes v2:
- restore previous ethtool set logic for the case where advertisements
are not provided by user space.
- use ethtool_convert_legacy_u32_to_link_mode() where possible
- genphy_c45_an_config_eee_aneg(): move adv initialization in to the if
scope.

Different EEE related fixes.
====================

Link: https://lore.kernel.org/r/20230222055043.113711-1-o.rempel@pengutronix.de
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+68 -13
+42 -12
drivers/net/phy/phy-c45.c
··· 262 262 linkmode_and(phydev->advertising, phydev->advertising, 263 263 phydev->supported); 264 264 265 - ret = genphy_c45_write_eee_adv(phydev, phydev->supported_eee); 265 + ret = genphy_c45_an_config_eee_aneg(phydev); 266 266 if (ret < 0) 267 267 return ret; 268 268 else if (ret) ··· 674 674 { 675 675 int val, changed; 676 676 677 - if (linkmode_intersects(phydev->supported, PHY_EEE_CAP1_FEATURES)) { 677 + if (linkmode_intersects(phydev->supported_eee, PHY_EEE_CAP1_FEATURES)) { 678 678 val = linkmode_to_mii_eee_cap1_t(adv); 679 679 680 680 /* In eee_broken_modes are stored MDIO_AN_EEE_ADV specific raw ··· 721 721 * @phydev: target phy_device struct 722 722 * @adv: the linkmode advertisement status 723 723 */ 724 - static int genphy_c45_read_eee_adv(struct phy_device *phydev, 725 - unsigned long *adv) 724 + int genphy_c45_read_eee_adv(struct phy_device *phydev, unsigned long *adv) 726 725 { 727 726 int val; 728 727 729 - if (linkmode_intersects(phydev->supported, PHY_EEE_CAP1_FEATURES)) { 728 + if (linkmode_intersects(phydev->supported_eee, PHY_EEE_CAP1_FEATURES)) { 730 729 /* IEEE 802.3-2018 45.2.7.13 EEE advertisement 1 731 730 * (Register 7.60) 732 731 */ ··· 761 762 { 762 763 int val; 763 764 764 - if (linkmode_intersects(phydev->supported, PHY_EEE_CAP1_FEATURES)) { 765 + if (linkmode_intersects(phydev->supported_eee, PHY_EEE_CAP1_FEATURES)) { 765 766 /* IEEE 802.3-2018 45.2.7.14 EEE link partner ability 1 766 767 * (Register 7.61) 767 768 */ ··· 856 857 return 0; 857 858 } 858 859 EXPORT_SYMBOL_GPL(genphy_c45_read_eee_abilities); 860 + 861 + /** 862 + * genphy_c45_an_config_eee_aneg - configure EEE advertisement 863 + * @phydev: target phy_device struct 864 + */ 865 + int genphy_c45_an_config_eee_aneg(struct phy_device *phydev) 866 + { 867 + if (!phydev->eee_enabled) { 868 + __ETHTOOL_DECLARE_LINK_MODE_MASK(adv) = {}; 869 + 870 + return genphy_c45_write_eee_adv(phydev, adv); 871 + } 872 + 873 + return genphy_c45_write_eee_adv(phydev, phydev->advertising_eee); 874 + } 859 875 860 876 /** 861 877 * genphy_c45_pma_read_abilities - read supported link modes from PMA ··· 1435 1421 int genphy_c45_ethtool_set_eee(struct phy_device *phydev, 1436 1422 struct ethtool_eee *data) 1437 1423 { 1438 - __ETHTOOL_DECLARE_LINK_MODE_MASK(adv) = {}; 1439 1424 int ret; 1440 1425 1441 1426 if (data->eee_enabled) { 1442 - if (data->advertised) 1443 - adv[0] = data->advertised; 1444 - else 1445 - linkmode_copy(adv, phydev->supported_eee); 1427 + if (data->advertised) { 1428 + __ETHTOOL_DECLARE_LINK_MODE_MASK(adv); 1429 + 1430 + ethtool_convert_legacy_u32_to_link_mode(adv, 1431 + data->advertised); 1432 + linkmode_andnot(adv, adv, phydev->supported_eee); 1433 + if (!linkmode_empty(adv)) { 1434 + phydev_warn(phydev, "At least some EEE link modes are not supported.\n"); 1435 + return -EINVAL; 1436 + } 1437 + 1438 + ethtool_convert_legacy_u32_to_link_mode(phydev->advertising_eee, 1439 + data->advertised); 1440 + } else { 1441 + linkmode_copy(phydev->advertising_eee, 1442 + phydev->supported_eee); 1443 + } 1444 + 1445 + phydev->eee_enabled = true; 1446 + } else { 1447 + phydev->eee_enabled = false; 1446 1448 } 1447 1449 1448 - ret = genphy_c45_write_eee_adv(phydev, adv); 1450 + ret = genphy_c45_an_config_eee_aneg(phydev); 1449 1451 if (ret < 0) 1450 1452 return ret; 1451 1453 if (ret > 0)
+20 -1
drivers/net/phy/phy_device.c
··· 2231 2231 { 2232 2232 int err; 2233 2233 2234 - err = genphy_c45_write_eee_adv(phydev, phydev->supported_eee); 2234 + err = genphy_c45_an_config_eee_aneg(phydev); 2235 2235 if (err < 0) 2236 2236 return err; 2237 2237 else if (err) ··· 3140 3140 3141 3141 of_set_phy_supported(phydev); 3142 3142 phy_advertise_supported(phydev); 3143 + 3144 + /* Get PHY default EEE advertising modes and handle them as potentially 3145 + * safe initial configuration. 3146 + */ 3147 + err = genphy_c45_read_eee_adv(phydev, phydev->advertising_eee); 3148 + if (err) 3149 + return err; 3150 + 3151 + /* There is no "enabled" flag. If PHY is advertising, assume it is 3152 + * kind of enabled. 3153 + */ 3154 + phydev->eee_enabled = !linkmode_empty(phydev->advertising_eee); 3155 + 3156 + /* Some PHYs may advertise, by default, not support EEE modes. So, 3157 + * we need to clean them. 3158 + */ 3159 + if (phydev->eee_enabled) 3160 + linkmode_and(phydev->advertising_eee, phydev->supported_eee, 3161 + phydev->advertising_eee); 3143 3162 3144 3163 /* Get the EEE modes we want to prohibit. We will ask 3145 3164 * the PHY stop advertising these mode later on
+6
include/linux/phy.h
··· 575 575 * @advertising: Currently advertised linkmodes 576 576 * @adv_old: Saved advertised while power saving for WoL 577 577 * @supported_eee: supported PHY EEE linkmodes 578 + * @advertising_eee: Currently advertised EEE linkmodes 579 + * @eee_enabled: Flag indicating whether the EEE feature is enabled 578 580 * @lp_advertising: Current link partner advertised linkmodes 579 581 * @host_interfaces: PHY interface modes supported by host 580 582 * @eee_broken_modes: Energy efficient ethernet modes which should be prohibited ··· 683 681 __ETHTOOL_DECLARE_LINK_MODE_MASK(adv_old); 684 682 /* used for eee validation */ 685 683 __ETHTOOL_DECLARE_LINK_MODE_MASK(supported_eee); 684 + __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising_eee); 685 + bool eee_enabled; 686 686 687 687 /* Host supported PHY interface types. Should be ignored if empty. */ 688 688 DECLARE_PHY_INTERFACE_MASK(host_interfaces); ··· 1769 1765 int genphy_c45_ethtool_set_eee(struct phy_device *phydev, 1770 1766 struct ethtool_eee *data); 1771 1767 int genphy_c45_write_eee_adv(struct phy_device *phydev, unsigned long *adv); 1768 + int genphy_c45_an_config_eee_aneg(struct phy_device *phydev); 1769 + int genphy_c45_read_eee_adv(struct phy_device *phydev, unsigned long *adv); 1772 1770 1773 1771 /* Generic C45 PHY driver */ 1774 1772 extern struct phy_driver genphy_c45_driver;