]> git.baikalelectronics.ru Git - kernel.git/commitdiff
phy: aquantia: Fix AN when higher speeds than 1G are not advertised
authorClaudiu Manoil <claudiu.manoil@nxp.com>
Fri, 10 Jun 2022 08:40:37 +0000 (11:40 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 29 Jun 2022 06:58:45 +0000 (08:58 +0200)
[ Upstream commit 3d5e65d39d6c6fdbc9ad14cd8ec67dd8795b64ed ]

Even when the eth port is resticted to work with speeds not higher than 1G,
and so the eth driver is requesting the phy (via phylink) to advertise up
to 1000BASET support, the aquantia phy device is still advertising for 2.5G
and 5G speeds.
Clear these advertising defaults when requested.

Cc: Ondrej Spacek <ondrej.spacek@nxp.com>
Fixes: a9894f007b7e1 ("net: phy: aquantia: add support for auto-negotiation configuration")
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Link: https://lore.kernel.org/r/20220610084037.7625-1-claudiu.manoil@nxp.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/phy/aquantia_main.c

index 975789d9349dc5f72184af47e5c132e2a19c265b..75d8351ee2506fd98d53da310f14750c715a52ee 100644 (file)
@@ -34,6 +34,8 @@
 #define MDIO_AN_VEND_PROV                      0xc400
 #define MDIO_AN_VEND_PROV_1000BASET_FULL       BIT(15)
 #define MDIO_AN_VEND_PROV_1000BASET_HALF       BIT(14)
+#define MDIO_AN_VEND_PROV_5000BASET_FULL       BIT(11)
+#define MDIO_AN_VEND_PROV_2500BASET_FULL       BIT(10)
 #define MDIO_AN_VEND_PROV_DOWNSHIFT_EN         BIT(4)
 #define MDIO_AN_VEND_PROV_DOWNSHIFT_MASK       GENMASK(3, 0)
 #define MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT       4
@@ -230,9 +232,20 @@ static int aqr_config_aneg(struct phy_device *phydev)
                              phydev->advertising))
                reg |= MDIO_AN_VEND_PROV_1000BASET_HALF;
 
+       /* Handle the case when the 2.5G and 5G speeds are not advertised */
+       if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+                             phydev->advertising))
+               reg |= MDIO_AN_VEND_PROV_2500BASET_FULL;
+
+       if (linkmode_test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
+                             phydev->advertising))
+               reg |= MDIO_AN_VEND_PROV_5000BASET_FULL;
+
        ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV,
                                     MDIO_AN_VEND_PROV_1000BASET_HALF |
-                                    MDIO_AN_VEND_PROV_1000BASET_FULL, reg);
+                                    MDIO_AN_VEND_PROV_1000BASET_FULL |
+                                    MDIO_AN_VEND_PROV_2500BASET_FULL |
+                                    MDIO_AN_VEND_PROV_5000BASET_FULL, reg);
        if (ret < 0)
                return ret;
        if (ret > 0)