FelipeMdeO opened a new pull request, #20167:
URL: https://github.com/apache/nuttx/pull/20167

   ## Summary
   
   `openeth_receive()` (`arch/xtensa/src/common/espressif/esp_openeth.c`) 
tracks the next RX descriptor to read 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` toggles off and back on 
(`openeth_disable()`/`openeth_enable()`, called from `ifdown()`/`ifup()`), but 
the driver's own index is never rewound to match.
   
   The first bring-up happens to have both at 0, so nothing looks wrong. After 
the first `ifdown()`/`ifup()` cycle they permanently disagree: 
`openeth_receive()` keeps inspecting the wrong descriptor, finds it still 
marked `e=1` ("owned by HW"), and silently drops every subsequent RX 
notification. Since ARP replies and ICMP echo replies are RX frames like any 
other, this breaks **all** inbound traffic on the interface after the first 
`ifup()`, not just application sockets — `ping` fails identically to a TCP 
`connect()`.
   
   Fix: 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. Builds on #20156 (which enabled the 
RX interrupt in the first place — this bug was unreachable via interrupts 
before that fix landed).
   
   ## Impact
   
   Fixes network RX on the `esp32s3` QEMU machine (`open_eth` NIC) for any 
workload that brings the interface down and back up more than once (a NIC 
power-cycle pattern — e.g. anything that manages a radio's on/off state between 
periodic transmissions). No impact on real hardware, since this code path is 
QEMU-only.
   
   ## Testing
   
   Reproduced with an out-of-tree NuttX application that cycles the interface 
up/down between periodic MQTT publish windows under QEMU. Before the fix: the 
first window always connects; every window after it fails with `ENETUNREACH` — 
both the app's own TCP `connect()` and a plain `ping 10.0.2.2` issued manually 
from NSH right after a failure fail identically, confirming the break is 
general RX, not specific to one socket/protocol. Inspecting the kernel's ARP 
table via GDB at the moment of failure showed a fresh, correctly-timestamped 
*negative* entry (all-zero MAC) for the broker's address — proof that a real 
ARP request was sent and genuinely got no reply, not that a stale cache entry 
was blocking a retry.
   
   Same firmware image, rebuilt only toggling this diff. Six parallel QEMU 
instances, ~480s each: 0 connect failures across dozens of completed publish 
windows (was ~0% success on window 2+ before the fix). `tools/checkpatch.sh -c 
-u -m -g` passes clean.
   
   Sample log lines before the fix (window 2, ~90s after window 1 succeeded):
   ```
   [146.880000] ... c=T3_TX op=CONNECT err=-101 | arp_prewarm sendto ret=-1
   [158.050000] ... c=T3_TX op=CONNECT err=-101 | cannot connect to 
10.0.2.2:1883
   ```
   and after (window 2, same test):
   ```
   [132.800000] ... c=T3_TX op=CONNECT err=0 | connected to 10.0.2.2:1883
   [138.820000] ... c=T3_TX op=STOP err=0 | window closed: 27 published, 27 
deleted
   ```
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to