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

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


The following commit(s) were added to refs/heads/master by this push:
     new aa114f0ec05 xtensa/espressif: resync openeth RX/TX descriptor ring on 
ifup
aa114f0ec05 is described below

commit aa114f0ec0570a4a03807a87c052779f88b92e3f
Author: Felipe Moura <[email protected]>
AuthorDate: Wed Sep 16 14:17:23 2026 -0300

    xtensa/espressif: resync openeth RX/TX descriptor ring on ifup
    
    openeth_receive() (arch/xtensa/src/common/espressif/esp_openeth.c)
    tracks the next expected RX descriptor in priv->cur_rx_desc, an int
    initialized to 0 exactly once, in esp_openeth_initialize(). QEMU's
    esp32s3 machine models the OpenCores MAC's DMA ring pointer as
    resetting to descriptor 0 every time RXEN is toggled off and back on
    (openeth_disable()/openeth_enable(), called from ifdown()/ifup()), but
    nothing rewinds the driver's own index to match. On the very first
    bring-up both start at 0, so nothing looks wrong; from the second
    ifup() onward the two permanently disagree, openeth_receive() keeps
    inspecting the wrong descriptor, finds it still marked "owned by HW"
    (e=1), and silently drops the notification. This breaks all inbound
    traffic on the interface, not just application sockets -- ARP replies
    and ICMP echo replies are RX frames too, so ping breaks identically.
    
    Re-run the same descriptor initialization esp_openeth_initialize()
    does at boot -- re-arm every RX/TX descriptor, rewind
    cur_rx_desc/cur_tx_desc to 0 -- inside openeth_ifup(), under the same
    critical section that already toggles RXEN.
    
    Board-independent code, and open_eth only exists as a QEMU peripheral,
    so there is no real-hardware regression risk.
    
    Assisted-by: Claude:claude-sonnet-5
    Signed-off-by: Felipe Moura <[email protected]>
---
 arch/xtensa/src/common/espressif/esp_openeth.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/xtensa/src/common/espressif/esp_openeth.c 
b/arch/xtensa/src/common/espressif/esp_openeth.c
index ed58e7ed357..891174dfa91 100644
--- a/arch/xtensa/src/common/espressif/esp_openeth.c
+++ b/arch/xtensa/src/common/espressif/esp_openeth.c
@@ -323,12 +323,38 @@ err:
 
 static int openeth_ifup(struct netdev_lowerhalf_s *dev)
 {
+  struct openeth_priv_s *priv = (struct openeth_priv_s *)dev;
+  int i;
   irqstate_t flags;
 
   /* Disable the Ethernet interrupt */
 
   flags = enter_critical_section();
 
+  /* Re-arm every descriptor and rewind the ring index to 0.  QEMU's
+   * OpenCores MAC model resets its DMA ring pointer to descriptor 0
+   * whenever RXEN toggles off and back on, but priv->cur_rx_desc is
+   * only ever initialized once, in esp_openeth_initialize().  After
+   * the first ifdown/ifup cycle the two disagree permanently and
+   * openeth_receive() silently drops every RX notification.
+   */
+
+  for (i = 0; i < RX_BUF_COUNT; i++)
+    {
+      openeth_init_rx_desc(openeth_rx_desc(i), priv->rx_buf[i]);
+    }
+
+  openeth_rx_desc(RX_BUF_COUNT - 1)->wr = 1;
+  priv->cur_rx_desc = 0;
+
+  for (i = 0; i < TX_BUF_COUNT; i++)
+    {
+      openeth_init_tx_desc(openeth_tx_desc(i), priv->tx_buf[i]);
+    }
+
+  openeth_tx_desc(TX_BUF_COUNT - 1)->wr = 1;
+  priv->cur_tx_desc = 0;
+
   /* Enable TX and RX */
 
   openeth_enable();

Reply via email to