From 80e4021c25d8c1ddae0dd655ed5f6b1e938dd79b Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Wed, 14 Feb 2024 21:16:19 +0100 Subject: [PATCH 1/5] net: mdio: add helpers for accessing the EEE CAP2 registers This adds helpers for accessing the EEE CAP2 registers. For now only 2500baseT and 5000baseT modes are supported. Signed-off-by: Heiner Kallweit Signed-off-by: David S. Miller --- include/linux/mdio.h | 55 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/include/linux/mdio.h b/include/linux/mdio.h index 79ceee3c8673..fd8ff310f9eb 100644 --- a/include/linux/mdio.h +++ b/include/linux/mdio.h @@ -439,6 +439,42 @@ static inline void mii_eee_cap1_mod_linkmode_t(unsigned long *adv, u32 val) adv, val & MDIO_EEE_10GKR); } +/** + * mii_eee_cap2_mod_linkmode_sup_t() + * @adv: target the linkmode settings + * @val: register value + * + * A function that translates value of following registers to the linkmode: + * IEEE 802.3-2022 45.2.3.11 "EEE control and capability 2" register (3.21) + */ +static inline void mii_eee_cap2_mod_linkmode_sup_t(unsigned long *adv, u32 val) +{ + linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, + adv, val & MDIO_EEE_2_5GT); + linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, + adv, val & MDIO_EEE_5GT); +} + +/** + * mii_eee_cap2_mod_linkmode_adv_t() + * @adv: target the linkmode advertisement settings + * @val: register value + * + * A function that translates value of following registers to the linkmode: + * IEEE 802.3-2022 45.2.7.16 "EEE advertisement 2" register (7.62) + * IEEE 802.3-2022 45.2.7.17 "EEE link partner ability 2" register (7.63) + * Note: Currently this function is the same as mii_eee_cap2_mod_linkmode_sup_t. + * For certain, not yet supported, modes however the bits differ. + * Therefore create separate functions already. + */ +static inline void mii_eee_cap2_mod_linkmode_adv_t(unsigned long *adv, u32 val) +{ + linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, + adv, val & MDIO_EEE_2_5GT); + linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, + adv, val & MDIO_EEE_5GT); +} + /** * linkmode_to_mii_eee_cap1_t() * @adv: the linkmode advertisement settings @@ -466,6 +502,25 @@ static inline u32 linkmode_to_mii_eee_cap1_t(unsigned long *adv) return result; } +/** + * linkmode_to_mii_eee_cap2_t() + * @adv: the linkmode advertisement settings + * + * A function that translates linkmode to value for IEEE 802.3-2022 45.2.7.16 + * "EEE advertisement 2" register (7.62) + */ +static inline u32 linkmode_to_mii_eee_cap2_t(unsigned long *adv) +{ + u32 result = 0; + + if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, adv)) + result |= MDIO_EEE_2_5GT; + if (linkmode_test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, adv)) + result |= MDIO_EEE_5GT; + + return result; +} + /** * mii_10base_t1_adv_mod_linkmode_t() * @adv: linkmode advertisement settings From ef6ee3a31bdc699391f2db4eff407fdb06895809 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Wed, 14 Feb 2024 21:17:11 +0100 Subject: [PATCH 2/5] net: phy: add PHY_EEE_CAP2_FEATURES As a prerequisite for adding EEE CAP2 register support, complement PHY_EEE_CAP1_FEATURES with PHY_EEE_CAP2_FEATURES. For now only 2500baseT and 5000baseT modes are supported. Signed-off-by: Heiner Kallweit Signed-off-by: David S. Miller --- drivers/net/phy/phy_device.c | 11 +++++++++++ include/linux/phy.h | 2 ++ 2 files changed, 13 insertions(+) diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index d63dca535746..2eefee970851 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -148,6 +148,14 @@ static const int phy_eee_cap1_features_array[] = { __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_eee_cap1_features) __ro_after_init; EXPORT_SYMBOL_GPL(phy_eee_cap1_features); +static const int phy_eee_cap2_features_array[] = { + ETHTOOL_LINK_MODE_2500baseT_Full_BIT, + ETHTOOL_LINK_MODE_5000baseT_Full_BIT, +}; + +__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_eee_cap2_features) __ro_after_init; +EXPORT_SYMBOL_GPL(phy_eee_cap2_features); + static void features_init(void) { /* 10/100 half/full*/ @@ -232,6 +240,9 @@ static void features_init(void) linkmode_set_bit_array(phy_eee_cap1_features_array, ARRAY_SIZE(phy_eee_cap1_features_array), phy_eee_cap1_features); + linkmode_set_bit_array(phy_eee_cap2_features_array, + ARRAY_SIZE(phy_eee_cap2_features_array), + phy_eee_cap2_features); } diff --git a/include/linux/phy.h b/include/linux/phy.h index c2dda21b39e1..e3ab2c347a59 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -54,6 +54,7 @@ extern __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_features) __ro_after_init; extern __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_fec_features) __ro_after_init; extern __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_full_features) __ro_after_init; extern __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_eee_cap1_features) __ro_after_init; +extern __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_eee_cap2_features) __ro_after_init; #define PHY_BASIC_FEATURES ((unsigned long *)&phy_basic_features) #define PHY_BASIC_T1_FEATURES ((unsigned long *)&phy_basic_t1_features) @@ -65,6 +66,7 @@ extern __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_eee_cap1_features) __ro_after_init; #define PHY_10GBIT_FEC_FEATURES ((unsigned long *)&phy_10gbit_fec_features) #define PHY_10GBIT_FULL_FEATURES ((unsigned long *)&phy_10gbit_full_features) #define PHY_EEE_CAP1_FEATURES ((unsigned long *)&phy_eee_cap1_features) +#define PHY_EEE_CAP2_FEATURES ((unsigned long *)&phy_eee_cap2_features) extern const int phy_basic_ports_array[3]; extern const int phy_fibre_port_array[1]; From b63584c86edbaf7477c3569cec331672bb7714d5 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Wed, 14 Feb 2024 21:18:02 +0100 Subject: [PATCH 3/5] net: phy: c45: add and use genphy_c45_read_eee_cap2 Add and use genphy_c45_read_eee_cap2(), complementing genphy_c45_read_eee_cap1(). Signed-off-by: Heiner Kallweit Signed-off-by: David S. Miller --- drivers/net/phy/phy-c45.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/drivers/net/phy/phy-c45.c b/drivers/net/phy/phy-c45.c index 46c87a903efd..5a245f0cc8b1 100644 --- a/drivers/net/phy/phy-c45.c +++ b/drivers/net/phy/phy-c45.c @@ -830,6 +830,30 @@ static int genphy_c45_read_eee_cap1(struct phy_device *phydev) return 0; } +/** + * genphy_c45_read_eee_cap2 - read supported EEE link modes from register 3.21 + * @phydev: target phy_device struct + */ +static int genphy_c45_read_eee_cap2(struct phy_device *phydev) +{ + int val; + + /* IEEE 802.3-2022 45.2.3.11 EEE control and capability 2 + * (Register 3.21) + */ + val = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE2); + if (val < 0) + return val; + + /* IEEE 802.3-2022 45.2.3.11 says 9 bits are reserved. */ + if (val == 0xffff) + return 0; + + mii_eee_cap2_mod_linkmode_sup_t(phydev->supported_eee, val); + + return 0; +} + /** * genphy_c45_read_eee_abilities - read supported EEE link modes * @phydev: target phy_device struct @@ -848,6 +872,13 @@ int genphy_c45_read_eee_abilities(struct phy_device *phydev) return val; } + /* Same for cap2 (3.21) */ + if (linkmode_intersects(phydev->supported, PHY_EEE_CAP2_FEATURES)) { + val = genphy_c45_read_eee_cap2(phydev); + if (val) + return val; + } + if (linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT1L_Full_BIT, phydev->supported)) { /* IEEE 802.3cg-2019 45.2.1.186b 10BASE-T1L PMA status register From 1bbe04e305fb2b5127650e6f2c0dbd611e8ebb14 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Wed, 14 Feb 2024 21:18:50 +0100 Subject: [PATCH 4/5] net: phy: c45: add support for EEE link partner ability 2 to genphy_c45_read_eee_lpa Add support for reading EEE link partner ability 2 register. Signed-off-by: Heiner Kallweit Signed-off-by: David S. Miller --- drivers/net/phy/phy-c45.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/net/phy/phy-c45.c b/drivers/net/phy/phy-c45.c index 5a245f0cc8b1..b09c6baf0c08 100644 --- a/drivers/net/phy/phy-c45.c +++ b/drivers/net/phy/phy-c45.c @@ -781,6 +781,17 @@ static int genphy_c45_read_eee_lpa(struct phy_device *phydev, mii_eee_cap1_mod_linkmode_t(lpa, val); } + if (linkmode_intersects(phydev->supported_eee, PHY_EEE_CAP2_FEATURES)) { + /* IEEE 802.3-2022 45.2.7.17 EEE link partner ability 2 + * (Register 7.63) + */ + val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_LPABLE2); + if (val < 0) + return val; + + mii_eee_cap2_mod_linkmode_adv_t(lpa, val); + } + if (linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT1L_Full_BIT, phydev->supported_eee)) { /* IEEE 802.3cg-2019 45.2.7.26 10BASE-T1 AN status register From 9a1e31299decfb4fc134933dbb6c34236187173f Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Wed, 14 Feb 2024 21:19:47 +0100 Subject: [PATCH 5/5] net: phy: c45: add support for MDIO_AN_EEE_ADV2 Add support for handling the EEE advertisement 2 register. For now only 2500baseT and 5000baseT modes are supported. Signed-off-by: Heiner Kallweit Signed-off-by: David S. Miller --- drivers/net/phy/phy-c45.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/net/phy/phy-c45.c b/drivers/net/phy/phy-c45.c index b09c6baf0c08..c69568e7695e 100644 --- a/drivers/net/phy/phy-c45.c +++ b/drivers/net/phy/phy-c45.c @@ -706,6 +706,22 @@ int genphy_c45_write_eee_adv(struct phy_device *phydev, unsigned long *adv) changed = 1; } + if (linkmode_intersects(phydev->supported_eee, PHY_EEE_CAP2_FEATURES)) { + val = linkmode_to_mii_eee_cap2_t(adv); + + /* IEEE 802.3-2022 45.2.7.16 EEE advertisement 2 + * (Register 7.62) + */ + val = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, + MDIO_AN_EEE_ADV2, + MDIO_EEE_2_5GT | MDIO_EEE_5GT, + val); + if (val < 0) + return val; + if (val > 0) + changed = 1; + } + if (linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT1L_Full_BIT, phydev->supported_eee)) { val = linkmode_adv_to_mii_10base_t1_t(adv); @@ -745,6 +761,17 @@ int genphy_c45_read_eee_adv(struct phy_device *phydev, unsigned long *adv) mii_eee_cap1_mod_linkmode_t(adv, val); } + if (linkmode_intersects(phydev->supported_eee, PHY_EEE_CAP2_FEATURES)) { + /* IEEE 802.3-2022 45.2.7.16 EEE advertisement 2 + * (Register 7.62) + */ + val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV2); + if (val < 0) + return val; + + mii_eee_cap2_mod_linkmode_adv_t(adv, val); + } + if (linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT1L_Full_BIT, phydev->supported_eee)) { /* IEEE 802.3cg-2019 45.2.7.25 10BASE-T1 AN control register