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>
This commit is contained in:
commit
1e30373ea5
|
@ -262,7 +262,7 @@ int genphy_c45_an_config_aneg(struct phy_device *phydev)
|
|||
linkmode_and(phydev->advertising, phydev->advertising,
|
||||
phydev->supported);
|
||||
|
||||
ret = genphy_c45_write_eee_adv(phydev, phydev->supported_eee);
|
||||
ret = genphy_c45_an_config_eee_aneg(phydev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
else if (ret)
|
||||
|
@ -674,7 +674,7 @@ int genphy_c45_write_eee_adv(struct phy_device *phydev, unsigned long *adv)
|
|||
{
|
||||
int val, changed;
|
||||
|
||||
if (linkmode_intersects(phydev->supported, PHY_EEE_CAP1_FEATURES)) {
|
||||
if (linkmode_intersects(phydev->supported_eee, PHY_EEE_CAP1_FEATURES)) {
|
||||
val = linkmode_to_mii_eee_cap1_t(adv);
|
||||
|
||||
/* In eee_broken_modes are stored MDIO_AN_EEE_ADV specific raw
|
||||
|
@ -721,12 +721,11 @@ int genphy_c45_write_eee_adv(struct phy_device *phydev, unsigned long *adv)
|
|||
* @phydev: target phy_device struct
|
||||
* @adv: the linkmode advertisement status
|
||||
*/
|
||||
static int genphy_c45_read_eee_adv(struct phy_device *phydev,
|
||||
unsigned long *adv)
|
||||
int genphy_c45_read_eee_adv(struct phy_device *phydev, unsigned long *adv)
|
||||
{
|
||||
int val;
|
||||
|
||||
if (linkmode_intersects(phydev->supported, PHY_EEE_CAP1_FEATURES)) {
|
||||
if (linkmode_intersects(phydev->supported_eee, PHY_EEE_CAP1_FEATURES)) {
|
||||
/* IEEE 802.3-2018 45.2.7.13 EEE advertisement 1
|
||||
* (Register 7.60)
|
||||
*/
|
||||
|
@ -762,7 +761,7 @@ static int genphy_c45_read_eee_lpa(struct phy_device *phydev,
|
|||
{
|
||||
int val;
|
||||
|
||||
if (linkmode_intersects(phydev->supported, PHY_EEE_CAP1_FEATURES)) {
|
||||
if (linkmode_intersects(phydev->supported_eee, PHY_EEE_CAP1_FEATURES)) {
|
||||
/* IEEE 802.3-2018 45.2.7.14 EEE link partner ability 1
|
||||
* (Register 7.61)
|
||||
*/
|
||||
|
@ -858,6 +857,21 @@ int genphy_c45_read_eee_abilities(struct phy_device *phydev)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(genphy_c45_read_eee_abilities);
|
||||
|
||||
/**
|
||||
* genphy_c45_an_config_eee_aneg - configure EEE advertisement
|
||||
* @phydev: target phy_device struct
|
||||
*/
|
||||
int genphy_c45_an_config_eee_aneg(struct phy_device *phydev)
|
||||
{
|
||||
if (!phydev->eee_enabled) {
|
||||
__ETHTOOL_DECLARE_LINK_MODE_MASK(adv) = {};
|
||||
|
||||
return genphy_c45_write_eee_adv(phydev, adv);
|
||||
}
|
||||
|
||||
return genphy_c45_write_eee_adv(phydev, phydev->advertising_eee);
|
||||
}
|
||||
|
||||
/**
|
||||
* genphy_c45_pma_read_abilities - read supported link modes from PMA
|
||||
* @phydev: target phy_device struct
|
||||
|
@ -1421,17 +1435,33 @@ EXPORT_SYMBOL(genphy_c45_ethtool_get_eee);
|
|||
int genphy_c45_ethtool_set_eee(struct phy_device *phydev,
|
||||
struct ethtool_eee *data)
|
||||
{
|
||||
__ETHTOOL_DECLARE_LINK_MODE_MASK(adv) = {};
|
||||
int ret;
|
||||
|
||||
if (data->eee_enabled) {
|
||||
if (data->advertised)
|
||||
adv[0] = data->advertised;
|
||||
else
|
||||
linkmode_copy(adv, phydev->supported_eee);
|
||||
if (data->advertised) {
|
||||
__ETHTOOL_DECLARE_LINK_MODE_MASK(adv);
|
||||
|
||||
ethtool_convert_legacy_u32_to_link_mode(adv,
|
||||
data->advertised);
|
||||
linkmode_andnot(adv, adv, phydev->supported_eee);
|
||||
if (!linkmode_empty(adv)) {
|
||||
phydev_warn(phydev, "At least some EEE link modes are not supported.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ethtool_convert_legacy_u32_to_link_mode(phydev->advertising_eee,
|
||||
data->advertised);
|
||||
} else {
|
||||
linkmode_copy(phydev->advertising_eee,
|
||||
phydev->supported_eee);
|
||||
}
|
||||
|
||||
phydev->eee_enabled = true;
|
||||
} else {
|
||||
phydev->eee_enabled = false;
|
||||
}
|
||||
|
||||
ret = genphy_c45_write_eee_adv(phydev, adv);
|
||||
ret = genphy_c45_an_config_eee_aneg(phydev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret > 0)
|
||||
|
|
|
@ -2231,7 +2231,7 @@ int __genphy_config_aneg(struct phy_device *phydev, bool changed)
|
|||
{
|
||||
int err;
|
||||
|
||||
err = genphy_c45_write_eee_adv(phydev, phydev->supported_eee);
|
||||
err = genphy_c45_an_config_eee_aneg(phydev);
|
||||
if (err < 0)
|
||||
return err;
|
||||
else if (err)
|
||||
|
@ -3141,6 +3141,25 @@ static int phy_probe(struct device *dev)
|
|||
of_set_phy_supported(phydev);
|
||||
phy_advertise_supported(phydev);
|
||||
|
||||
/* Get PHY default EEE advertising modes and handle them as potentially
|
||||
* safe initial configuration.
|
||||
*/
|
||||
err = genphy_c45_read_eee_adv(phydev, phydev->advertising_eee);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* There is no "enabled" flag. If PHY is advertising, assume it is
|
||||
* kind of enabled.
|
||||
*/
|
||||
phydev->eee_enabled = !linkmode_empty(phydev->advertising_eee);
|
||||
|
||||
/* Some PHYs may advertise, by default, not support EEE modes. So,
|
||||
* we need to clean them.
|
||||
*/
|
||||
if (phydev->eee_enabled)
|
||||
linkmode_and(phydev->advertising_eee, phydev->supported_eee,
|
||||
phydev->advertising_eee);
|
||||
|
||||
/* Get the EEE modes we want to prohibit. We will ask
|
||||
* the PHY stop advertising these mode later on
|
||||
*/
|
||||
|
|
|
@ -575,6 +575,8 @@ struct macsec_ops;
|
|||
* @advertising: Currently advertised linkmodes
|
||||
* @adv_old: Saved advertised while power saving for WoL
|
||||
* @supported_eee: supported PHY EEE linkmodes
|
||||
* @advertising_eee: Currently advertised EEE linkmodes
|
||||
* @eee_enabled: Flag indicating whether the EEE feature is enabled
|
||||
* @lp_advertising: Current link partner advertised linkmodes
|
||||
* @host_interfaces: PHY interface modes supported by host
|
||||
* @eee_broken_modes: Energy efficient ethernet modes which should be prohibited
|
||||
|
@ -681,6 +683,8 @@ struct phy_device {
|
|||
__ETHTOOL_DECLARE_LINK_MODE_MASK(adv_old);
|
||||
/* used for eee validation */
|
||||
__ETHTOOL_DECLARE_LINK_MODE_MASK(supported_eee);
|
||||
__ETHTOOL_DECLARE_LINK_MODE_MASK(advertising_eee);
|
||||
bool eee_enabled;
|
||||
|
||||
/* Host supported PHY interface types. Should be ignored if empty. */
|
||||
DECLARE_PHY_INTERFACE_MASK(host_interfaces);
|
||||
|
@ -1765,6 +1769,8 @@ int genphy_c45_ethtool_get_eee(struct phy_device *phydev,
|
|||
int genphy_c45_ethtool_set_eee(struct phy_device *phydev,
|
||||
struct ethtool_eee *data);
|
||||
int genphy_c45_write_eee_adv(struct phy_device *phydev, unsigned long *adv);
|
||||
int genphy_c45_an_config_eee_aneg(struct phy_device *phydev);
|
||||
int genphy_c45_read_eee_adv(struct phy_device *phydev, unsigned long *adv);
|
||||
|
||||
/* Generic C45 PHY driver */
|
||||
extern struct phy_driver genphy_c45_driver;
|
||||
|
|
Loading…
Reference in New Issue