arch/[risc-v|xtensa]/espressif: reconnect Wi-Fi STA on AP-side disconnect - #19725
Merged
tmedicci merged 1 commit intoAug 7, 2026
Merged
Conversation
…nect The disconnect handler only reconnects when the reported reason is WIFI_REASON_ASSOC_LEAVE, so an AP-initiated deauth (beacon timeout, auth or assoc expire) leaves the station down forever. Restore the intent flag the driver used before 1f7c3a3 and 20ff68b, matching the ESP-IDF rule of reconnecting unless the disconnection was requested locally. Signed-off-by: Felipe Moura <moura.fmo@gmail.com>
1 task
FelipeMdeO
marked this pull request as ready for review
August 6, 2026 21:23
FelipeMdeO
requested review from
eren-terzioglu,
fdcavalcanti,
jerpelea and
tmedicci
as code owners
August 6, 2026 21:23
1 task
xiaoxiang781216
approved these changes
Aug 7, 2026
tmedicci
reviewed
Aug 7, 2026
tmedicci
left a comment
Contributor
There was a problem hiding this comment.
Thanks, @FelipeMdeO . We're running our internal CI to verify it hasn't broken anything.
(Please don't merge it yet)
fdcavalcanti
approved these changes
Aug 7, 2026
fdcavalcanti
left a comment
Contributor
There was a problem hiding this comment.
CI is ok, thanks for the change.
tmedicci
approved these changes
Aug 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
An ESP32 Wi-Fi station running NuttX never recovers from an AP-initiated
disconnection. Once the access point goes away — a reboot, a brief outage, a
deauthentication — the station drops the link and stays down forever. The
interface remains
UPwithoutRUNNINGand only a manualwapi psk+wapi essidbrings it back. Nothing is logged, so in the fieldthis looks like the board "losing the network" for no reason.
This is a regression. The disconnect handler in
esp_wifi_event_handler.creconnects only when the reported reason is
WIFI_REASON_ASSOC_LEAVE:The
reasonfield carries an 802.11 reason code, extended by ESP-IDF withvendor values above 200 for locally detected conditions
(
wifi_err_reason_tinesp_wifi_types_generic.h):WIFI_REASON_ASSOC_LEAVEis the value the stack reports for a locallyinitiated disconnect — confirmed on hardware, since running
wapi essidlogsreason: 8because the tool disconnects before associating. So the survivingbranch covers the one case where reconnecting is not needed, and every
AP-initiated reason is left unhandled.
Before the Wi-Fi driver refactors the same handler used an explicit intent
flag, which is the rule ESP-IDF documents — reconnect on any reason unless the
disconnection was requested locally:
g_sta_reconnectwas set true byesp_wifi_sta_connect()and false byesp_wifi_sta_disconnect(), so the driver always knew whether it had asked toleave. The refactors replaced that flag with the reason-code test:
1f7c3a32e520ff68bd650The intent cannot be derived from the reason code: the reason is what the
other end reports, while the intent is state this driver owns. The correct
logic is still present in tree today, in
arch/risc-v/src/esp32c3-legacy/esp32c3_wifi_adapter.c, so the same chipcurrently ships two drivers with opposite behaviour.
This PR restores the intent flag on both architectures.
esp_reconnect_work_cbre-checks the flag because the user may request
ifdownbetween the work beingqueued and the work running. Retry cadence is left to the event loop, matching
ESP-IDF: a failed attempt raises another
STA_DISCONNECTED(reason 201) whichschedules the next one, self-throttled by the radio's scan time (~2.4 s
measured).
The
failure_retry_cntwrites inesp_wifi_sta_disconnect()are leftuntouched, so this PR only adds the flag there. A comment marks them as
having no documented effect: ESP-IDF states the field applies only when
scan_methodisWIFI_ALL_CHANNEL_SCAN, and NuttX never selects it — theonly assignment of
scan_methodanywhere in the tree isWIFI_FAST_SCANin the legacy ESP32-C3 driver, and neither the common drivernor the bundled HAL ever writes the field. Removing the now-redundant writes,
and revisiting whether that field is the right mechanism at all, is better
handled as a follow-up PR so this one stays focused on the regression.
Impact
reconnects by itself instead of staying offline until rebooted or manually
re-associated.
arch/risc-vandarch/xtensa. Validated on ESP32-C3.ifdown,esp_wifi_sta_disconnect(false)from the ioctl path) still does notreconnect — that path is what the flag protects. No call sites changed:
esp_wlan_netdev.calready passesfalsefor the user disconnect and thefour internal disconnects in
esp_wifi_api.calready passtrue.Testing
Two boards on the same access point, in the same time window, so the trigger is
identical for both:
esp32c3-devkit:wifidefconfigexamples/wifi/getting_started/stationCONFIG_DEBUG_WIRELESS_INFO=y+ Wi-Fi credentialsThe NuttX side runs the unmodified board defconfig — no application on top, so
the Wi-Fi driver is the only thing under test.
Reproduction: power the access point off for 5 minutes, then back on.
NuttX, ESP32-C3 — the AP disappears:
Nothing follows. No scan, no association attempt, no further log line — the
remaining entries are the radio tearing down block-ack state at the same
millisecond. The AP came back a few minutes later; 21 minutes after that the
board was still offline:
UPwithoutRUNNING: carrier down, no recovery.ESP-IDF, ESP32-C6, same outage — note the same reason 200:
147 attempts spaced ~2.4 s apart, then an address as soon as the AP was serving
again. Both stacks received the same event; only the handling differs.
After this change the behavior is the same in NuttX side and ESP-IDF side.
Reviewers who want to reproduce either side need only two boards and a power
switch on their access point.
Related reports that may share this root cause, though neither was diagnosed:
https://github.com/apache/nuttx/issues/19137a