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

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

commit b5bb6f33df2dfebdf24d9b27260fd0720a073730
Author: Darryl Ring <[email protected]>
AuthorDate: Tue Aug 25 18:59:34 2026 -0700

    arch/arm/stm32h5: Use MDIO bus
    
    Copy the MDIO bus changes from the STM32H7 port.
    
    Assisted-by: Claude:claude-sonnet-5
    Signed-off-by: Darryl Ring <[email protected]>
---
 arch/arm/src/stm32h5/CMakeLists.txt   |   4 +
 arch/arm/src/stm32h5/Make.defs        |   4 +
 arch/arm/src/stm32h5/stm32_ethernet.c | 206 ++++++-----------------------
 arch/arm/src/stm32h5/stm32_mdio.c     | 238 ++++++++++++++++++++++++++++++++++
 arch/arm/src/stm32h5/stm32_mdio.h     |  58 +++++++++
 5 files changed, 344 insertions(+), 166 deletions(-)

diff --git a/arch/arm/src/stm32h5/CMakeLists.txt 
b/arch/arm/src/stm32h5/CMakeLists.txt
index 9055fb57db2..2ab0fa7a017 100644
--- a/arch/arm/src/stm32h5/CMakeLists.txt
+++ b/arch/arm/src/stm32h5/CMakeLists.txt
@@ -108,6 +108,10 @@ if(CONFIG_STM32_ETHMAC)
   list(APPEND SRCS stm32_ethernet.c)
 endif()
 
+if(CONFIG_MDIO_BUS)
+  list(APPEND SRCS stm32_mdio.c)
+endif()
+
 if(CONFIG_STM32_DMA)
   list(APPEND SRCS stm32_dma.c)
 endif()
diff --git a/arch/arm/src/stm32h5/Make.defs b/arch/arm/src/stm32h5/Make.defs
index d401ea56d7d..3eb4b7134a8 100644
--- a/arch/arm/src/stm32h5/Make.defs
+++ b/arch/arm/src/stm32h5/Make.defs
@@ -104,6 +104,10 @@ ifeq ($(CONFIG_STM32_ETHMAC),y)
 CHIP_CSRCS += stm32_ethernet.c
 endif
 
+ifeq ($(CONFIG_MDIO_BUS),y)
+CHIP_CSRCS += stm32_mdio.c
+endif
+
 ifeq ($(CONFIG_STM32_DMA),y)
 CHIP_CSRCS += stm32_dma.c
 endif
diff --git a/arch/arm/src/stm32h5/stm32_ethernet.c 
b/arch/arm/src/stm32h5/stm32_ethernet.c
index 473b27d418f..37d84506e08 100644
--- a/arch/arm/src/stm32h5/stm32_ethernet.c
+++ b/arch/arm/src/stm32h5/stm32_ethernet.c
@@ -63,6 +63,7 @@
 #include "stm32_rcc.h"
 #include "stm32_ethernet.h"
 #include "stm32_uid.h"
+#include "stm32_mdio.h"
 
 #include <arch/board/board.h>
 
@@ -622,6 +623,8 @@ struct stm32_ethmac_s
   uint16_t             segments;    /* RX segment count */
   uint16_t             inflight;    /* Number of TX transfers "in_flight" */
   sq_queue_t           freeb;       /* The free buffer list */
+
+  struct mdio_bus_s *mdio;
 };
 
 /****************************************************************************
@@ -740,16 +743,13 @@ static void stm32_rxdescinit(struct stm32_ethmac_s *priv,
 #if defined(CONFIG_NETDEV_PHY_IOCTL) && defined(CONFIG_ARCH_PHY_INTERRUPT)
 static int  stm32_phyintenable(struct stm32_ethmac_s *priv);
 #endif
-static int  stm32_phyread(uint16_t phydevaddr, uint16_t phyregaddr,
-                          uint16_t *value);
-static int  stm32_phywrite(uint16_t phydevaddr, uint16_t phyregaddr,
-                           uint16_t value, uint16_t mask);
+
 #ifdef CONFIG_ETH0_PHY_DM9161
 static inline int stm32_dm9161(struct stm32_ethmac_s *priv);
 #endif
 static int  stm32_phyinit(struct stm32_ethmac_s *priv);
 #ifdef CONFIG_STM32_ETHMAC_REGDEBUG
-static void  stm32_phyregdump(void);
+static void  stm32_phyregdump(struct stm32_ethmac_s *priv);
 #endif
 #endif
 
@@ -2967,9 +2967,7 @@ static void stm32_rxdescinit(struct stm32_ethmac_s *priv,
 static int stm32_ioctl(struct net_driver_s *dev, int cmd, unsigned long arg)
 {
 #ifndef CONFIG_STM32_NO_PHY
-#ifdef CONFIG_ARCH_PHY_INTERRUPT
   struct stm32_ethmac_s *priv = (struct stm32_ethmac_s *)dev->d_private;
-#endif
   int ret;
 
   switch (cmd)
@@ -3007,7 +3005,8 @@ static int stm32_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);
 
-          ret = stm32_phyread(req->phy_id, req->reg_num, &req->val_out);
+          ret = mdio_read(priv->mdio,
+            req->phy_id, req->reg_num, &req->val_out);
         }
         break;
 
@@ -3016,8 +3015,8 @@ static int stm32_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);
 
-          ret = stm32_phywrite(req->phy_id, req->reg_num, req->val_in,
-                               0xffff);
+          ret = mdio_write(priv->mdio,
+            req->phy_id, req->reg_num, req->val_in);
         }
         break;
 
@@ -3061,148 +3060,6 @@ static int stm32_phyintenable(struct stm32_ethmac_s 
*priv)
 }
 #endif
 
-/****************************************************************************
- * Function: stm32_phyread
- *
- * Description:
- *  Read a PHY register.
- *
- * Parameters:
- *   phydevaddr - The PHY device address
- *   phyregaddr - The PHY register address
- *   value - The location to return the 16-bit PHY register value.
- *
- * Returned Value:
- *   OK on success; Negated errno on failure.
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static int stm32_phyread(uint16_t phydevaddr, uint16_t phyregaddr,
-                         uint16_t *value)
-{
-  volatile uint32_t timeout;
-  uint32_t regval;
-
-  /* Configure the MACMDIOAR register, preserving CSR Clock Range CR[3:0]
-   * bits
-   */
-
-  regval  = stm32_getreg(STM32_ETH_MACMDIOAR);
-  regval &= ETH_MACMDIOAR_CR_MASK;
-
-  /* Set the PHY device address, PHY register address, and set the buy bit.
-   * the ETH_MACMDIOAR_GOC == 3, indicating a read operation.
-   */
-
-  regval |= (((uint32_t)phydevaddr << ETH_MACMDIOAR_PA_SHIFT) &
-            ETH_MACMDIOAR_PA_MASK);
-  regval |= (((uint32_t)phyregaddr << ETH_MACMDIOAR_RDA_SHIFT) &
-            ETH_MACMDIOAR_RDA_MASK);
-  regval |= ETH_MACMDIOAR_MB | ETH_MACMDIOAR_GOC_READ;
-
-  stm32_putreg(regval, STM32_ETH_MACMDIOAR);
-
-  /* Wait for the transfer to complete */
-
-  for (timeout = 0; timeout < PHY_READ_TIMEOUT; timeout++)
-    {
-      if ((stm32_getreg(STM32_ETH_MACMDIOAR) & ETH_MACMDIOAR_MB) == 0)
-        {
-          *value = (uint16_t)stm32_getreg(STM32_ETH_MACMDIODR);
-          return OK;
-        }
-    }
-
-  ninfo("MII transfer timed out: phydevaddr: %04x phyregaddr: %04x\n",
-        phydevaddr, phyregaddr);
-
-  return -ETIMEDOUT;
-}
-
-/****************************************************************************
- * Function: stm32_phywrite
- *
- * Description:
- *  Write to a PHY register.
- *
- * Parameters:
- *   phydevaddr - The PHY device address
- *   phyregaddr - The PHY register address
- *   value - The 16-bit value to write to the PHY register value.
- *
- * Returned Value:
- *   OK on success; Negated errno on failure.
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static int stm32_phywrite(uint16_t phydevaddr, uint16_t phyregaddr,
-                          uint16_t set, uint16_t clear)
-{
-  volatile uint32_t timeout;
-  uint32_t regval;
-  uint16_t value;
-
-  /* Configure the MACMDIOAR register, preserving CSR Clock Range CR[3:0]
-   * bits
-   */
-
-  regval  = stm32_getreg(STM32_ETH_MACMDIOAR);
-  regval &= ETH_MACMDIOAR_CR_MASK;
-
-  /* Read the existing register value, if clear mask is given */
-
-  if (clear != 0xffff)
-    {
-      if (stm32_phyread(phydevaddr, phyregaddr, &value) != OK)
-        {
-          return -ETIMEDOUT;
-        }
-
-      value &= ~clear;
-      value |= set;
-    }
-  else
-    {
-      value = set;
-    }
-
-  /* Set the PHY device address, PHY register address, and set the busy bit.
-   * the ETH_MACMDIOAR_GOC == 1, indicating a write operation.
-   */
-
-  regval |= (((uint32_t)phydevaddr << ETH_MACMDIOAR_PA_SHIFT) &
-            ETH_MACMDIOAR_PA_MASK);
-  regval |= (((uint32_t)phyregaddr << ETH_MACMDIOAR_RDA_SHIFT) &
-            ETH_MACMDIOAR_RDA_MASK);
-  regval |= (ETH_MACMDIOAR_MB | ETH_MACMDIOAR_GOC_WRITE);
-
-  /* Write the value into the MACMDIODR register before setting the new
-   * MACMDIOAR register value.
-   */
-
-  stm32_putreg(value, STM32_ETH_MACMDIODR);
-  stm32_putreg(regval, STM32_ETH_MACMDIOAR);
-
-  /* Wait for the transfer to complete */
-
-  for (timeout = 0; timeout < PHY_WRITE_TIMEOUT; timeout++)
-    {
-      if ((stm32_getreg(STM32_ETH_MACMDIOAR) & ETH_MACMDIOAR_MB) == 0)
-        {
-          return OK;
-        }
-    }
-
-  ninfo("MII transfer timed out: phydevaddr: %04x phyregaddr: %04x value: "
-        "%04x\n", phydevaddr, phyregaddr, value);
-
-  return -ETIMEDOUT;
-}
-
 /****************************************************************************
  * Function: stm32_dm9161
  *
@@ -3231,7 +3088,8 @@ static inline int stm32_dm9161(struct stm32_ethmac_s 
*priv)
    * indication that check if the DM9161 PHY CHIP is not ready.
    */
 
-  ret = stm32_phyread(CONFIG_STM32_PHYADDR, MII_PHYID1, &phyval);
+  ret = mdio_read(priv->mdio,
+    CONFIG_STM32_PHYADDR, MII_PHYID1, &phyval);
   if (ret < 0)
     {
       nerr("ERROR: Failed to read the PHY ID1: %d\n", ret);
@@ -3253,7 +3111,8 @@ static inline int stm32_dm9161(struct stm32_ethmac_s 
*priv)
    * Register 16
    */
 
-  ret = stm32_phyread(CONFIG_STM32_PHYADDR, 16, &phyval);
+  ret = mdio_read(priv->mdio,
+    CONFIG_STM32_PHYADDR, 16, &phyval);
   if (ret < 0)
     {
       nerr("ERROR: Failed to read the PHY Register 0x10: %d\n", ret);
@@ -3288,7 +3147,7 @@ static inline int stm32_dm9161(struct stm32_ethmac_s 
*priv)
  ****************************************************************************/
 
 #ifdef CONFIG_STM32_ETHMAC_REGDEBUG
-static void stm32_phyregdump()
+static void stm32_phyregdump(struct stm32_ethmac_s *priv)
 {
   uint16_t phyval;
   int ret;
@@ -3296,7 +3155,8 @@ static void stm32_phyregdump()
 
   for (i = 0; i < 0x20; i++)
     {
-      ret = stm32_phyread(CONFIG_STM32_PHYADDR, i, &phyval);
+      ret = mdio_read(priv->mdio,
+        CONFIG_STM32_PHYADDR, i, &phyval);
       if (ret < 0)
         {
           nerr("ERROR: Failed to read reg: 0%2x\n", i);
@@ -3349,8 +3209,8 @@ static int stm32_phyinit(struct stm32_ethmac_s *priv)
 
   /* Put the PHY in reset mode */
 
-  ret = stm32_phywrite(CONFIG_STM32_PHYADDR, MII_MCR, MII_MCR_RESET,
-                       MII_MCR_RESET);
+  ret = mdio_write(priv->mdio,
+    CONFIG_STM32_PHYADDR, MII_MCR, MII_MCR_RESET);
   if (ret < 0)
     {
       nerr("ERROR: Failed to reset the PHY: %d\n", ret);
@@ -3362,7 +3222,8 @@ static int stm32_phyinit(struct stm32_ethmac_s *priv)
     {
       up_mdelay(10);
       to -= 10;
-      ret = stm32_phyread(CONFIG_STM32_PHYADDR, MII_MCR, &phyval);
+      ret = mdio_read(priv->mdio,
+        CONFIG_STM32_PHYADDR, MII_MCR, &phyval);
     }
   while (phyval & MII_MCR_RESET && to > 0);
 
@@ -3377,7 +3238,7 @@ static int stm32_phyinit(struct stm32_ethmac_s *priv)
     }
 
 #ifdef CONFIG_STM32_ETHMAC_REGDEBUG
-  stm32_phyregdump();
+  stm32_phyregdump(priv);
 #endif
 
   /* Special workaround for the Davicom DM9161 PHY is required. */
@@ -3397,7 +3258,8 @@ static int stm32_phyinit(struct stm32_ethmac_s *priv)
 
   for (timeout = 0; timeout < PHY_RETRY_TIMEOUT; timeout++)
     {
-      ret = stm32_phyread(CONFIG_STM32_PHYADDR, MII_MSR, &phyval);
+      ret = mdio_read(priv->mdio,
+        CONFIG_STM32_PHYADDR, MII_MSR, &phyval);
       if (ret < 0)
         {
           nerr("ERROR: Failed to read the PHY MSR: %d\n", ret);
@@ -3419,8 +3281,8 @@ static int stm32_phyinit(struct stm32_ethmac_s *priv)
 
   /* Enable auto-negotiation */
 
-  ret = stm32_phywrite(CONFIG_STM32_PHYADDR, MII_MCR, MII_MCR_ANENABLE,
-                       MII_MCR_ANENABLE);
+  ret = mdio_write(priv->mdio,
+    CONFIG_STM32_PHYADDR, MII_MCR, MII_MCR_ANENABLE);
   if (ret < 0)
     {
       nerr("ERROR: Failed to enable auto-negotiation: %d\n", ret);
@@ -3431,7 +3293,8 @@ static int stm32_phyinit(struct stm32_ethmac_s *priv)
 
   for (timeout = 0; timeout < PHY_RETRY_TIMEOUT; timeout++)
     {
-      ret = stm32_phyread(CONFIG_STM32_PHYADDR, MII_MSR, &phyval);
+      ret = mdio_read(priv->mdio,
+        CONFIG_STM32_PHYADDR, MII_MSR, &phyval);
       if (ret < 0)
         {
           nerr("ERROR: Failed to read the PHY MSR: %d\n", ret);
@@ -3453,7 +3316,8 @@ static int stm32_phyinit(struct stm32_ethmac_s *priv)
 
   /* Read the result of the auto-negotiation from the PHY-specific register */
 
-  ret = stm32_phyread(CONFIG_STM32_PHYADDR, CONFIG_STM32_PHYSR, &phyval);
+  ret = mdio_read(priv->mdio,
+    CONFIG_STM32_PHYADDR, CONFIG_STM32_PHYSR, &phyval);
   if (ret < 0)
     {
       nerr("ERROR: Failed to read PHY status register\n");
@@ -3528,7 +3392,8 @@ static int stm32_phyinit(struct stm32_ethmac_s *priv)
   phyval |= MII_MCR_SPEED100;
 #endif
 
-  ret = stm32_phywrite(CONFIG_STM32_PHYADDR, MII_MCR, phyval, 0xffff);
+  ret = mdio_write(priv->mdio,
+    CONFIG_STM32_PHYADDR, MII_MCR, phyval);
   if (ret < 0)
     {
       nerr("ERROR: Failed to write the PHY MCR: %d\n", ret);
@@ -4240,6 +4105,15 @@ static inline int stm32_ethinitialize(int intf)
 
   stm32_ethgpioconfig(priv);
 
+  /* Initialize the MDIO device */
+
+  priv->mdio = stm32_mdio_bus_initialize();
+  if (!priv->mdio)
+    {
+      nerr("ERROR: Failed to initialize MDIO bus\n");
+      return -ENOMEM;
+    }
+
   /* Attach the IRQ to the driver */
 
   if (irq_attach(STM32_IRQ_ETH, stm32_interrupt, NULL))
diff --git a/arch/arm/src/stm32h5/stm32_mdio.c 
b/arch/arm/src/stm32h5/stm32_mdio.c
new file mode 100644
index 00000000000..00540c47191
--- /dev/null
+++ b/arch/arm/src/stm32h5/stm32_mdio.c
@@ -0,0 +1,238 @@
+/****************************************************************************
+ * arch/arm/src/stm32h5/stm32_mdio.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <arm_internal.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_STM32_ETHMAC_REGDEBUG
+static uint32_t stm32_getreg(uint32_t addr);
+static void stm32_putreg(uint32_t val, uint32_t addr);
+static void stm32_checksetup(void);
+#else
+#  define stm32_getreg(addr)     getreg32(addr)
+#  define stm32_putreg(val,addr) putreg32(val,addr)
+#  define stm32_checksetup()
+#endif
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/mutex.h>
+#include <nuttx/config.h>
+#include <nuttx/nuttx.h>
+
+#include <nuttx/debug.h>
+#include <errno.h>
+#include <inttypes.h>
+
+#include "stm32_mdio.h"
+#include "hardware/stm32_ethernet.h"
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct stm32_mdio_lowerhalf_s
+{
+  struct mdio_lowerhalf_s base;
+
+  /* MDIO bus timeout in microseconds */
+
+  int timeout;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int stm32_c22_read(struct mdio_lowerhalf_s *dev, uint8_t phydev,
+                    uint8_t regaddr, uint16_t *value);
+
+static int stm32_c22_write(struct mdio_lowerhalf_s *dev, uint8_t phydev,
+                     uint8_t regaddr, uint16_t value);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+const struct mdio_ops_s g_stm32_mdio_ops =
+{
+  .read  = stm32_c22_read,
+  .write = stm32_c22_write,
+  .reset = NULL,
+};
+
+struct stm32_mdio_lowerhalf_s g_stm32_mdio_lowerhalf =
+{
+  .base =
+    {
+      .ops = &g_stm32_mdio_ops
+    },
+  .timeout = 10000
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int stm32_c22_read(struct mdio_lowerhalf_s *dev, uint8_t phydev,
+                          uint8_t regaddr, uint16_t *value)
+{
+  int to;
+  uint32_t regval;
+
+  int retval = -ETIMEDOUT;
+  struct stm32_mdio_lowerhalf_s *priv =
+         container_of(dev, struct stm32_mdio_lowerhalf_s, base);
+
+  /* Configure the MACMDIOAR register, preserving CSR Clock Range CR[3:0]
+   * bits
+   */
+
+  regval  = stm32_getreg(STM32_ETH_MACMDIOAR);
+  regval &= ETH_MACMDIOAR_CR_MASK;
+
+  /* Set the PHY device address, PHY register address, and set the buy bit.
+   * the ETH_MACMDIOAR_GOC == 3, indicating a read operation.
+   */
+
+  regval |= (((uint32_t)phydev << ETH_MACMDIOAR_PA_SHIFT) &
+            ETH_MACMDIOAR_PA_MASK);
+  regval |= (((uint32_t)regaddr << ETH_MACMDIOAR_RDA_SHIFT) &
+            ETH_MACMDIOAR_RDA_MASK);
+  regval |= ETH_MACMDIOAR_MB | ETH_MACMDIOAR_GOC_READ;
+
+  stm32_putreg(regval, STM32_ETH_MACMDIOAR);
+
+  /* Wait for the transfer to complete.  A Clause 22 frame is 64 MDC
+   * cycles, about 30 us at a 2.5 MHz MDC, so poll at a fraction of that.
+   * A millisecond delay here turns every PHY register access into a
+   * busy-wait far longer than the transfer, and the autonegotiation link
+   * wait in stm32_phyinit() issues thousands of them.
+   */
+
+  for (to = priv->timeout; to > 0; to -= 10)
+    {
+      if ((stm32_getreg(STM32_ETH_MACMDIOAR) & ETH_MACMDIOAR_MB) == 0)
+        {
+          *value = (uint16_t)stm32_getreg(STM32_ETH_MACMDIODR);
+          retval = OK;
+          break;
+        }
+
+      up_udelay(10);
+    }
+
+  if (retval < 0)
+    {
+      ninfo("MII transfer timed out: phydev: %04x regaddr: %04x\n",
+            phydev, regaddr);
+    }
+
+  return retval;
+}
+
+static int stm32_c22_write(struct mdio_lowerhalf_s *dev, uint8_t phydev,
+                           uint8_t regaddr, uint16_t value)
+{
+  int to;
+  uint32_t regval;
+
+  int retval = -ETIMEDOUT;
+  struct stm32_mdio_lowerhalf_s *priv =
+         container_of(dev, struct stm32_mdio_lowerhalf_s, base);
+
+  /* Configure the MACMDIOAR register, preserving CSR Clock Range CR[3:0]
+   * bits
+   */
+
+  regval  = stm32_getreg(STM32_ETH_MACMDIOAR);
+  regval &= ETH_MACMDIOAR_CR_MASK;
+
+  /* Read the existing register value, if clear mask is given */
+
+  /* Set the PHY device address, PHY register address, and set the busy bit.
+   * the ETH_MACMDIOAR_GOC == 1, indicating a write operation.
+   */
+
+  regval |= (((uint32_t)phydev << ETH_MACMDIOAR_PA_SHIFT) &
+            ETH_MACMDIOAR_PA_MASK);
+  regval |= (((uint32_t)regaddr << ETH_MACMDIOAR_RDA_SHIFT) &
+            ETH_MACMDIOAR_RDA_MASK);
+  regval |= (ETH_MACMDIOAR_MB | ETH_MACMDIOAR_GOC_WRITE);
+
+  /* Write the value into the MACMDIODR register before setting the new
+   * MACMDIOAR register value.
+   */
+
+  stm32_putreg(value, STM32_ETH_MACMDIODR);
+  stm32_putreg(regval, STM32_ETH_MACMDIOAR);
+
+  /* Wait for the transfer to complete */
+
+  for (to = priv->timeout; to > 0; to -= 10)
+    {
+      if ((stm32_getreg(STM32_ETH_MACMDIOAR) & ETH_MACMDIOAR_MB) == 0)
+        {
+          retval = OK;
+          break;
+        }
+
+      up_udelay(10);
+    }
+
+  if (retval < 0)
+    {
+      ninfo("MII transfer timed out: phydevaddr: %04x phyregaddr: %04x"
+            "value: %04x\n", phydev, regaddr, value);
+    }
+
+  return retval;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_mdio_bus_initialize
+ *
+ * Description:
+ *   Initialize the MDIO bus
+ *
+ * Returned Value:
+ *   Initialized MDIO bus structure or NULL on failure
+ *
+ ****************************************************************************/
+
+struct mdio_bus_s *stm32_mdio_bus_initialize(void)
+{
+  return mdio_register(&g_stm32_mdio_lowerhalf.base);
+}
diff --git a/arch/arm/src/stm32h5/stm32_mdio.h 
b/arch/arm/src/stm32h5/stm32_mdio.h
new file mode 100644
index 00000000000..75e14c40ef3
--- /dev/null
+++ b/arch/arm/src/stm32h5/stm32_mdio.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+ * arch/arm/src/stm32h5/stm32_mdio.h
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_STM32H5_STM32_MDIO_H
+#define __ARCH_ARM_SRC_STM32H5_STM32_MDIO_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/net/mdio.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_mdio_bus_initialize
+ *
+ * Description:
+ *   Initialize the MDIO bus
+ *
+ * Returned Value:
+ *   Initialized MDIO bus structure or NULL on failure
+ *
+ ****************************************************************************/
+
+struct mdio_bus_s *stm32_mdio_bus_initialize(void);
+
+#endif /* __ARCH_ARM_SRC_STM32H5_STM32_MDIO_H */

Reply via email to