[PATCH] net: ti: am65-cpsw-nuss: allow skipping phy_config() for speed

Jai Luthra jai.luthra at ideasonboard.com
Thu Jun 11 15:04:19 CEST 2026


Hi Siddharth,

Thank you for the patch.

Quoting Siddharth Vadapalli (2026-06-11 17:36:50)
> Currently, phy_config() is invoked every time during am65_cpsw_start()
> which guarantees robustness and also allows recovering from link
> failures by resetting the Ethernet PHY. While this is beneficial for
> system stability, for use-cases where speed is prioritized over
> robustness, the existing implementation is insufficient.
> 
> To support use-cases prioritizing speed while continuing to retain the
> existing behavior for robustness, sample the environment variable named
> "am65_cpsw_phy_config_once" to determine whether phy_config() should
> continue to be invoked once per invocation of am65_cpsw_start(), OR, it
> should only be invoked across invocations. Since the environment variable
> is not set by default, robustness is prioritized over speed. Use-cases
> which require speed can set "am65_cpsw_phy_config_once" to any of:
> '1', 'y', 'Y', 't' and 'T'
> based on the implementation of the env_get_yesno() helper function.
> 
> Signed-off-by: Siddharth Vadapalli <s-vadapalli at ti.com>
> ---
> 
> Hello,
> 
> This patch is based on commit
> 3cdce049f90 erge tag 'u-boot-rockchip-20260610' of https://source.denx.de/u-boot/custodians/u-boot-rockchip
> of the master branch of U-Boot.
> 
> Patch has been tested on J784S4 EVM which uses MCU CPSW2G for Ethernet
> functionality. The following test logs demonstrate the default behavior
> being retained in the absence of 'am65_cpsw_phy_config_once' environment
> variable being set to a logical true, followed by setting the environment
> variable to a logical true ('y') and observing the PHY Autonegotiation
> process being skipped, followed by setting the environment variable to a
> logical false ('n' but could be anything that isn't logically true based
> on the env_get_yesno() helper function) and verifying that we go back to
> the default behavior of performing PHY Autonegotiation again:
> https://gist.github.com/Siddharth-Vadapalli-at-TI/6229b5a3b7d80cd0c2037a6364406bbe
> 
> Regards,
> Siddharth.
> 
>  drivers/net/ti/am65-cpsw-nuss.c | 32 +++++++++++++++++++++++++++-----
>  1 file changed, 27 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/net/ti/am65-cpsw-nuss.c b/drivers/net/ti/am65-cpsw-nuss.c
> index 84a3e44ecbc..a5cca52f674 100644
> --- a/drivers/net/ti/am65-cpsw-nuss.c
> +++ b/drivers/net/ti/am65-cpsw-nuss.c
> @@ -18,6 +18,7 @@
>  #include <dm/pinctrl.h>
>  #include <dma-uclass.h>
>  #include <dm/of_access.h>
> +#include <env.h>
>  #include <miiphy.h>
>  #include <net.h>
>  #include <phy.h>
> @@ -104,6 +105,7 @@ struct am65_cpsw_port {
>         fdt_addr_t      macsl_base;
>         bool            disabled;
>         u32             mac_control;
> +       bool            phy_configured;
>  };
>  
>  struct am65_cpsw_common {
> @@ -313,7 +315,7 @@ static int am65_cpsw_start(struct udevice *dev)
>         struct am65_cpsw_port *port = &common->ports[priv->port_id];
>         struct am65_cpsw_port *port0 = &common->ports[0];
>         struct ti_udma_drv_chan_cfg_data *dma_rx_cfg_data;
> -       int ret, i;
> +       int ret, i, skip_phy_config_env;
>  
>         if (common->started)
>                 return 0;
> @@ -426,10 +428,30 @@ static int am65_cpsw_start(struct udevice *dev)
>                        port->port_sgmii_base + AM65_CPSW_SGMII_CONTROL_REG);
>         }
>  
> -       ret = phy_config(priv->phydev);
> -       if (ret < 0) {
> -               dev_err(dev, "phy_config failed: %d", ret);
> -               goto err_dis_rx;
> +       /*
> +        * Invoking phy_config() every time that am65_cpsw_start() is executed will
> +        * make the link robust. However, it delays every networking command such as
> +        * 'dhcp' and 'tftp'. For use-cases that prioritize speed over robustness,
> +        * phy_config() should be invoked only once. To support both use-cases,
> +        * sample the environment variable 'am65_cpsw_phy_config_once' to switch
> +        * between:
> +        * a) Invoke phy_config() every time - Default behavior for robustness
> +        * b) Invoke phy_config() once per driver probe - User configurable behavior
> +        *    for speed.
> +        */
> +       skip_phy_config_env = env_get_yesno("am65_cpsw_phy_config_once");
> +
> +       /* If environment variable is not defined, assume it to be false. */
> +       if (skip_phy_config_env == -1)
> +               skip_phy_config_env = 0;
> +
> +       if (!port->phy_configured || !skip_phy_config_env) {
> +               ret = phy_config(priv->phydev);
> +               if (ret < 0) {
> +                       dev_err(dev, "phy_config failed: %d", ret);
> +                       goto err_dis_rx;
> +               }
> +               port->phy_configured = true;
>         }

Tested-by: Jai Luthra <jai.luthra at ideasonboard.com> [on BeagleY-AI]

Although I was surprised there's no way to check the status of the phy link
through some controller bit that can maybe mark phy as unconfigured on next
attempt? Apologies if that's stupid, I don't understand networking =)

Cheers,
    Jai

>  
>         ret = phy_startup(priv->phydev);
> -- 
> 2.51.1
> 
>


More information about the U-Boot mailing list