]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
net: phy: Support overriding Auto Negotiation timeout with env variable
authorSiddharth Vadapalli <s-vadapalli@ti.com>
Thu, 24 Jul 2025 14:15:36 +0000 (19:45 +0530)
committerJerome Forissier <jerome.forissier@linaro.org>
Fri, 1 Aug 2025 08:42:22 +0000 (10:42 +0200)
The Auto Negotiation procedure between two Ethernet PHYs consists of
determining the best commonly supported parameters among Speed,
Duplex Mode and Flow Control.

The time taken for this procedure is not only dependent on the local
PHY used, but also on the link-partner PHY.

While a timeout can be specified in the form of a "CONFIG" on the basis
of the local PHY present on the device, since the timeout also depends
on the link-partner PHY, it might be necessary to modify the timeout.

To avoid rebuilding the bootloader for a given device, just because it
may be connected to various link-partner PHYs, each with a different
timeout, introduce an environment variable named "phy_aneg_timeout" and
override "CONFIG_PHY_ANEG_TIMEOUT" with "phy_aneg_timeout".

Signed-off-by: Siddharth Vadapalli <s-vadapalli@ti.com>
Acked-by: Jerome Forissier <jerome.forissier@linaro.org>
[jf: add missing #include <env.h>]
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
doc/usage/environment.rst
drivers/net/phy/Kconfig
drivers/net/phy/aquantia.c
drivers/net/phy/phy.c
drivers/net/xilinx_axi_emac.c

index bb6c351b441ea25afe25071e64d340cbbb546333..77197d79380f4c456a78236f1eeee3937dd3cc76 100644 (file)
@@ -335,6 +335,15 @@ netretry
     Useful on scripts which control the retry operation
     themselves.
 
+phy_aneg_timeout
+    If set, the specified value will override CONFIG_PHY_ANEG_TIMEOUT.
+    This variable has the same base and unit as CONFIG_PHY_ANEG_TIMEOUT
+    which is "decimal" and "millisecond" respectively. The default value
+    of CONFIG_PHY_ANEG_TIMEOUT may be sufficient for most use-cases, but
+    certain link-partners may require a larger timeout due to the Ethernet
+    PHY they use. Alternatively, the timeout can be reduced as well if the
+    use-case demands it.
+
 rng_seed_size
     Size of random value added to device-tree node /chosen/rng-seed.
     This variable is given as a decimal number.
index 8d88c14290033e36312c32479d19fa4dbde85ac1..21bf983056af1974986b9a00314a960165dd63ed 100644 (file)
@@ -23,7 +23,10 @@ config PHY_ANEG_TIMEOUT
        int "PHY auto-negotiation timeout"
        default 4000
        help
-         Default PHY auto-negotiation timeout.
+         Value of PHY auto-negotiation timeout with the base being
+         "decimal" and the unit being "millisecond". This can be
+         overridden by the "phy_aneg_timeout" environment variable
+         that has the same base (decimal) and unit (millisecond).
 
 if PHY_ADDR_ENABLE
 config PHY_ADDR
index d2db8d9f79213961c9f4045d43c8498293e1254f..f63a13824ca68c52f138d98ae70f290286e1ebb7 100644 (file)
@@ -7,6 +7,7 @@
  */
 #include <config.h>
 #include <dm.h>
+#include <env.h>
 #include <log.h>
 #include <net.h>
 #include <phy.h>
@@ -551,14 +552,15 @@ int aquantia_config(struct phy_device *phydev)
 
 int aquantia_startup(struct phy_device *phydev)
 {
-       u32 speed;
-       int i = 0;
+       u32 speed, i = 0;
        int reg;
 
        phydev->duplex = DUPLEX_FULL;
 
        /* if the AN is still in progress, wait till timeout. */
        if (!aquantia_link_is_up(phydev)) {
+               u32 aneg_timeout = env_get_ulong("phy_aneg_timeout", 10,
+                                                CONFIG_PHY_ANEG_TIMEOUT);
                printf("%s Waiting for PHY auto negotiation to complete",
                       phydev->dev->name);
                do {
@@ -566,9 +568,9 @@ int aquantia_startup(struct phy_device *phydev)
                        if ((i++ % 500) == 0)
                                printf(".");
                } while (!aquantia_link_is_up(phydev) &&
-                        i < (4 * CONFIG_PHY_ANEG_TIMEOUT));
+                        i < (4 * aneg_timeout));
 
-               if (i > CONFIG_PHY_ANEG_TIMEOUT)
+               if (i > aneg_timeout)
                        printf(" TIMEOUT !\n");
        }
 
index e6fed8c41d77e12d51efe0aad1894e7c1d84d29b..9702d0422962db706d777c7949b17dc9426089e1 100644 (file)
@@ -9,6 +9,7 @@
  */
 #include <console.h>
 #include <dm.h>
+#include <env.h>
 #include <log.h>
 #include <malloc.h>
 #include <net.h>
@@ -242,7 +243,9 @@ int genphy_update_link(struct phy_device *phydev)
 
        if ((phydev->autoneg == AUTONEG_ENABLE) &&
            !(mii_reg & BMSR_ANEGCOMPLETE)) {
-               int i = 0;
+               u32 i = 0;
+               u32 aneg_timeout = env_get_ulong("phy_aneg_timeout", 10,
+                                                CONFIG_PHY_ANEG_TIMEOUT);
 
                printf("%s Waiting for PHY auto negotiation to complete",
                       phydev->dev->name);
@@ -250,7 +253,7 @@ int genphy_update_link(struct phy_device *phydev)
                        /*
                         * Timeout reached ?
                         */
-                       if (i > (CONFIG_PHY_ANEG_TIMEOUT / 50)) {
+                       if (i > (aneg_timeout / 50)) {
                                printf(" TIMEOUT !\n");
                                phydev->link = 0;
                                return -ETIMEDOUT;
index 4d87e2d1f36fffe75e22c584ae291cd5dc85baca..c8038ddef1b8e4d77d09e6cea5671df6a51c9ae3 100644 (file)
@@ -11,6 +11,7 @@
 #include <display_options.h>
 #include <dm.h>
 #include <dm/device_compat.h>
+#include <env.h>
 #include <log.h>
 #include <net.h>
 #include <malloc.h>
@@ -343,6 +344,8 @@ static int axiemac_phy_init(struct udevice *dev)
 
 static int pcs_pma_startup(struct axidma_priv *priv)
 {
+       u32 aneg_timeout = env_get_ulong("phy_aneg_timeout", 10,
+                                        CONFIG_PHY_ANEG_TIMEOUT);
        u32 rc, retry_cnt = 0;
        u16 mii_reg;
 
@@ -361,7 +364,7 @@ static int pcs_pma_startup(struct axidma_priv *priv)
         * and the external PHY is not obtained.
         */
        debug("axiemac: waiting for link status of the PCS/PMA PHY");
-       while (retry_cnt * 10 < CONFIG_PHY_ANEG_TIMEOUT) {
+       while (retry_cnt * 10 < aneg_timeout) {
                rc = phyread(priv, priv->pcsaddr, MII_BMSR, &mii_reg);
                if ((mii_reg & BMSR_LSTATUS) && mii_reg != 0xffff && !rc) {
                        debug(".Done\n");