This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit eafd01cecc66afbded0ec7ad06ef8378ada05bbe
Author: Royyan Zahir <[email protected]>
AuthorDate: Sun Oct 4 18:50:46 2026 +0400

    arch/arm/imxrt: a fixed link when no PHY answers
    
    A carrier with a switch port wired MAC to MAC has no PHY on MDIO, and
    ifup failed. With IMXRT_ENET_FIXED_LINK the configured PHY, or the
    board's PHY list, is tried first; if none answers the MAC runs at
    100 Mbps full duplex and SIOCGMIIREG reports the link up, so the
    network monitor keeps the interface up.
    
    Signed-off-by: Royyan Zahir <[email protected]>
---
 arch/arm/src/imxrt/Kconfig      |  8 ++++++
 arch/arm/src/imxrt/imxrt_enet.c | 55 ++++++++++++++++++++++++++++++++++++++---
 2 files changed, 60 insertions(+), 3 deletions(-)

diff --git a/arch/arm/src/imxrt/Kconfig b/arch/arm/src/imxrt/Kconfig
index a3138542394..ce807e39c75 100644
--- a/arch/arm/src/imxrt/Kconfig
+++ b/arch/arm/src/imxrt/Kconfig
@@ -2693,6 +2693,14 @@ config IMXRT_ENET_PHYINIT
                imxrt_phy_boardinitialize();  The i.MXRT ENET driver will call 
this
                function one time before it first uses the PHY.
 
+config IMXRT_ENET_FIXED_LINK
+       bool "Fixed link when no PHY answers"
+       default n
+       depends on IMXRT_ENET
+       ---help---
+               If no PHY answers on MDIO, run the MAC at 100 Mbps full duplex
+               instead of failing ifup, for a switch port wired MAC to MAC.
+
 config IMXRT_PHY_POLLING
        bool "Support network monitoring by polling the PHY"
        default n
diff --git a/arch/arm/src/imxrt/imxrt_enet.c b/arch/arm/src/imxrt/imxrt_enet.c
index e1dca97aaf2..2f840b08709 100644
--- a/arch/arm/src/imxrt/imxrt_enet.c
+++ b/arch/arm/src/imxrt/imxrt_enet.c
@@ -397,6 +397,9 @@ struct imxrt_driver_s
 #if defined(CONFIG_ETH0_PHY_MULTI)
   uint8_t  current_phy;         /* The index of the PHY being used */
   uint8_t  current_phy_address; /* The address of the PHY being used */
+#endif
+#ifdef CONFIG_IMXRT_ENET_FIXED_LINK
+  bool     fixed_link;          /* No PHY answered: 100 Mbps full duplex */
 #endif
   /* This holds the information visible to the NuttX network */
 
@@ -1416,16 +1419,38 @@ static int imxrt_ifup_action(struct net_driver_s *dev, 
bool resetphy)
 
   /* Configure the PHY */
 
+#ifdef CONFIG_IMXRT_ENET_FIXED_LINK
+  priv->fixed_link = false;
+#endif
+
 #if defined(CONFIG_ETH0_PHY_MULTI)
   ret = imxrt_determine_phy(priv);
   if (ret < 0)
     {
+#  ifdef CONFIG_IMXRT_ENET_FIXED_LINK
+      priv->fixed_link = true;
+#  else
       nerr("ERROR: Failed to determine the PHY: %d\n", ret);
       return ret;
+#  endif
     }
 #endif
 
   ret = imxrt_initphy(priv, resetphy);
+
+#ifdef CONFIG_IMXRT_ENET_FIXED_LINK
+  if (ret == -ENOENT && !priv->fixed_link)
+    {
+      priv->fixed_link = true;
+      ret = imxrt_initphy(priv, false);
+    }
+
+  if (priv->fixed_link)
+    {
+      nwarn("WARNING: no PHY answered, fixed 100 Mbps full duplex link\n");
+    }
+#endif
+
   if (ret < 0)
     {
       nerr("ERROR: Failed to configure the PHY: %d\n", ret);
@@ -1922,6 +1947,16 @@ static int imxrt_ioctl(struct net_driver_s *dev, int 
cmd, unsigned long arg)
         {
           struct mii_ioctl_data_s *req =
             (struct mii_ioctl_data_s *)((uintptr_t)arg);
+#ifdef CONFIG_IMXRT_ENET_FIXED_LINK
+          if (priv->fixed_link)
+            {
+              req->val_out = req->reg_num == MII_MSR ?
+                             MII_MSR_LINKSTATUS | MII_MSR_100BASETXFULL : 0;
+              ret = OK;
+              break;
+            }
+#endif
+
 #if defined(CLAUSE45)
           if (
 #  if defined(CONFIG_ETH0_PHY_MULTI)
@@ -2539,6 +2574,16 @@ static inline int imxrt_initphy(struct imxrt_driver_s 
*priv, bool renogphy)
   uint8_t phyaddr    = BOARD_PHY_ADDR;
   int retries;
   int ret;
+  bool fixed = false;
+
+#ifdef CONFIG_IMXRT_ENET_FIXED_LINK
+  fixed = priv->fixed_link;
+  phydata = 0;
+  if (fixed)
+    {
+      goto mac_setup;
+    }
+#endif
 
   if (renogphy)
     {
@@ -2866,6 +2911,10 @@ static inline int imxrt_initphy(struct imxrt_driver_s 
*priv, bool renogphy)
 #  if defined(CONFIG_ETH0_PHY_MULTI)
     }
 #  endif
+#endif
+
+#ifdef CONFIG_IMXRT_ENET_FIXED_LINK
+mac_setup:
 #endif
 
   /* Set up the transmit and receive control registers based on the
@@ -2898,7 +2947,7 @@ static inline int imxrt_initphy(struct imxrt_driver_s 
*priv, bool renogphy)
 
   /* Setup half or full duplex */
 
-  if (BOARD_PHY_ISDUPLEX(phydata))
+  if (fixed || BOARD_PHY_ISDUPLEX(phydata))
     {
       /* Full duplex */
 
@@ -2913,14 +2962,14 @@ static inline int imxrt_initphy(struct imxrt_driver_s 
*priv, bool renogphy)
       rcr |= ENET_RCR_DRT;
     }
 
-  if (BOARD_PHY_10BASET(phydata))
+  if (!fixed && BOARD_PHY_10BASET(phydata))
     {
       /* 10 Mbps */
 
       ninfo("%s: 10 Base-T\n",  BOARD_PHY_NAME);
       rcr |= ENET_RCR_RMII_10T;
     }
-  else if (BOARD_PHY_100BASET(phydata))
+  else if (fixed || BOARD_PHY_100BASET(phydata))
     {
       /* 100 Mbps */
 

Reply via email to