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();