]> www.infradead.org Git - users/griffoul/linux.git/commitdiff
net: phy: aquantia: fill supported_interfaces for all aqr_gen2_config_init() callers
authorVladimir Oltean <vladimir.oltean@nxp.com>
Thu, 21 Aug 2025 15:20:12 +0000 (18:20 +0300)
committerJakub Kicinski <kuba@kernel.org>
Mon, 25 Aug 2025 17:54:14 +0000 (10:54 -0700)
Since aqr_gen2_config_init() and aqr_gen2_fill_interface_modes() refer to
the feature set common to the same generation, it means all callers of
aqr_gen2_config_init() also support the Global System Configuration
registers at addresses 1E.31B -> 1E.31F, and these should be read by the
driver to figure out the list of supported interfaces for phylink.

This affects the following PHYs supported by this driver:
- Gen2: AQR107
- Gen3: AQR111, AQR111B0
- Gen4: AQR114C, AQR813.

AQR113C, a Gen4 PHY, has unmodified logic after this change, because
currently, the aqr_gen2_fill_interface_modes() call is chained after
aqr_gen2_config_init(), and after this patch, it is tail-called from the
latter function, leading to the same code flow.

At the same time, move aqr_gen2_fill_interface_modes() upwards of its
new caller, aqr_gen2_config_init(), to avoid a forward declaration.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Link: https://patch.msgid.link/20250821152022.1065237-6-vladimir.oltean@nxp.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/phy/aquantia/aquantia_main.c

index 8136f7843a373862588a8318fbaffa50858ec164..21fdbda2a0e001ba907789808a0338c1ae0435f7 100644 (file)
@@ -860,9 +860,93 @@ static int aqr_gen1_config_init(struct phy_device *phydev)
        return 0;
 }
 
+static const u16 aqr_global_cfg_regs[] = {
+       VEND1_GLOBAL_CFG_10M,
+       VEND1_GLOBAL_CFG_100M,
+       VEND1_GLOBAL_CFG_1G,
+       VEND1_GLOBAL_CFG_2_5G,
+       VEND1_GLOBAL_CFG_5G,
+       VEND1_GLOBAL_CFG_10G,
+};
+
+static int aqr_gen2_fill_interface_modes(struct phy_device *phydev)
+{
+       unsigned long *possible = phydev->possible_interfaces;
+       struct aqr107_priv *priv = phydev->priv;
+       unsigned int serdes_mode, rate_adapt;
+       phy_interface_t interface;
+       int i, val, ret;
+
+       /* It's been observed on some models that - when coming out of suspend
+        * - the FW signals that the PHY is ready but the GLOBAL_CFG registers
+        * continue on returning zeroes for some time. Let's poll the 100M
+        * register until it returns a real value as both 113c and 115c support
+        * this mode.
+        */
+       if (priv->wait_on_global_cfg) {
+               ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
+                                               VEND1_GLOBAL_CFG_100M, val,
+                                               val != 0, 1000, 100000, false);
+               if (ret)
+                       return ret;
+       }
+
+       /* Walk the media-speed configuration registers to determine which
+        * host-side serdes modes may be used by the PHY depending on the
+        * negotiated media speed.
+        */
+       for (i = 0; i < ARRAY_SIZE(aqr_global_cfg_regs); i++) {
+               val = phy_read_mmd(phydev, MDIO_MMD_VEND1,
+                                  aqr_global_cfg_regs[i]);
+               if (val < 0)
+                       return val;
+
+               serdes_mode = FIELD_GET(VEND1_GLOBAL_CFG_SERDES_MODE, val);
+               rate_adapt = FIELD_GET(VEND1_GLOBAL_CFG_RATE_ADAPT, val);
+
+               switch (serdes_mode) {
+               case VEND1_GLOBAL_CFG_SERDES_MODE_XFI:
+                       if (rate_adapt == VEND1_GLOBAL_CFG_RATE_ADAPT_USX)
+                               interface = PHY_INTERFACE_MODE_USXGMII;
+                       else
+                               interface = PHY_INTERFACE_MODE_10GBASER;
+                       break;
+
+               case VEND1_GLOBAL_CFG_SERDES_MODE_XFI5G:
+                       interface = PHY_INTERFACE_MODE_5GBASER;
+                       break;
+
+               case VEND1_GLOBAL_CFG_SERDES_MODE_OCSGMII:
+                       interface = PHY_INTERFACE_MODE_2500BASEX;
+                       break;
+
+               case VEND1_GLOBAL_CFG_SERDES_MODE_SGMII:
+                       interface = PHY_INTERFACE_MODE_SGMII;
+                       break;
+
+               default:
+                       phydev_warn(phydev, "unrecognised serdes mode %u\n",
+                                   serdes_mode);
+                       interface = PHY_INTERFACE_MODE_NA;
+                       break;
+               }
+
+               if (interface != PHY_INTERFACE_MODE_NA)
+                       __set_bit(interface, possible);
+       }
+
+       return 0;
+}
+
 static int aqr_gen2_config_init(struct phy_device *phydev)
 {
-       return aqr_gen1_config_init(phydev);
+       int ret;
+
+       ret = aqr_gen1_config_init(phydev);
+       if (ret)
+               return ret;
+
+       return aqr_gen2_fill_interface_modes(phydev);
 }
 
 static int aqcs109_config_init(struct phy_device *phydev)
@@ -984,84 +1068,6 @@ static int aqr_gen1_resume(struct phy_device *phydev)
        return aqr_gen1_wait_processor_intensive_op(phydev);
 }
 
-static const u16 aqr_global_cfg_regs[] = {
-       VEND1_GLOBAL_CFG_10M,
-       VEND1_GLOBAL_CFG_100M,
-       VEND1_GLOBAL_CFG_1G,
-       VEND1_GLOBAL_CFG_2_5G,
-       VEND1_GLOBAL_CFG_5G,
-       VEND1_GLOBAL_CFG_10G
-};
-
-static int aqr_gen2_fill_interface_modes(struct phy_device *phydev)
-{
-       unsigned long *possible = phydev->possible_interfaces;
-       struct aqr107_priv *priv = phydev->priv;
-       unsigned int serdes_mode, rate_adapt;
-       phy_interface_t interface;
-       int i, val, ret;
-
-       /* It's been observed on some models that - when coming out of suspend
-        * - the FW signals that the PHY is ready but the GLOBAL_CFG registers
-        * continue on returning zeroes for some time. Let's poll the 100M
-        * register until it returns a real value as both 113c and 115c support
-        * this mode.
-        */
-       if (priv->wait_on_global_cfg) {
-               ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
-                                               VEND1_GLOBAL_CFG_100M, val,
-                                               val != 0, 1000, 100000, false);
-               if (ret)
-                       return ret;
-       }
-
-       /* Walk the media-speed configuration registers to determine which
-        * host-side serdes modes may be used by the PHY depending on the
-        * negotiated media speed.
-        */
-       for (i = 0; i < ARRAY_SIZE(aqr_global_cfg_regs); i++) {
-               val = phy_read_mmd(phydev, MDIO_MMD_VEND1,
-                                  aqr_global_cfg_regs[i]);
-               if (val < 0)
-                       return val;
-
-               serdes_mode = FIELD_GET(VEND1_GLOBAL_CFG_SERDES_MODE, val);
-               rate_adapt = FIELD_GET(VEND1_GLOBAL_CFG_RATE_ADAPT, val);
-
-               switch (serdes_mode) {
-               case VEND1_GLOBAL_CFG_SERDES_MODE_XFI:
-                       if (rate_adapt == VEND1_GLOBAL_CFG_RATE_ADAPT_USX)
-                               interface = PHY_INTERFACE_MODE_USXGMII;
-                       else
-                               interface = PHY_INTERFACE_MODE_10GBASER;
-                       break;
-
-               case VEND1_GLOBAL_CFG_SERDES_MODE_XFI5G:
-                       interface = PHY_INTERFACE_MODE_5GBASER;
-                       break;
-
-               case VEND1_GLOBAL_CFG_SERDES_MODE_OCSGMII:
-                       interface = PHY_INTERFACE_MODE_2500BASEX;
-                       break;
-
-               case VEND1_GLOBAL_CFG_SERDES_MODE_SGMII:
-                       interface = PHY_INTERFACE_MODE_SGMII;
-                       break;
-
-               default:
-                       phydev_warn(phydev, "unrecognised serdes mode %u\n",
-                                   serdes_mode);
-                       interface = PHY_INTERFACE_MODE_NA;
-                       break;
-               }
-
-               if (interface != PHY_INTERFACE_MODE_NA)
-                       __set_bit(interface, possible);
-       }
-
-       return 0;
-}
-
 static int aqr115c_get_features(struct phy_device *phydev)
 {
        unsigned long *supported = phydev->supported;
@@ -1098,10 +1104,6 @@ static int aqr113c_config_init(struct phy_device *phydev)
        if (ret < 0)
                return ret;
 
-       ret = aqr_gen2_fill_interface_modes(phydev);
-       if (ret)
-               return ret;
-
        ret = phy_clear_bits_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_TXDIS,
                                 MDIO_PMD_TXDIS_GLOBAL);
        if (ret)