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 */