[PATCH] netdev: Fix premature ECSA channel switch timeout for mt7925
arpan <[email protected]> Thu, 30 Jul 2026 01:43:16 +0530
| Newsgroups | dev.linux.lists.iwd |
|---|---|
| Message-ID | <[email protected]> |
The mt7925 cards get stuck and disconnect during Extended Channel Switch Announcement (ECSA) events because the kernel considers them stuck. This occurs because the kernel sends an imminent channel switch notification (NL80211_CMD_CH_SWITCH_NOTIFY with the NL80211_ATTR_CH_SWITCH_COUNT attribute present) prior to the physical switch. iwd was previously ignoring the countdown attribute and immediately initiating an active scan to re-query the AP. Sending a scan command while the firmware is trying to tune the radio causes the mt7925 firmware to time out. This patch adds a check to see if the countdown attribute is present for mt7925 interfaces. If it is, we wait for the second notification (which omits the count) that confirms the switch is physically completed before proceeding with the internal state updates. Signed-off-by: Arpan <[email protected]> --- src/netdev.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/netdev.c b/src/netdev.c index e639a1f8..96b48ac3 100644 --- a/src/netdev.c +++ b/src/netdev.c @@ -5428,12 +5428,32 @@ static void netdev_channel_switch_event(struct l_genl_msg *msg, { _auto_(l_free) struct band_chandef *chandef = NULL; + uint32_t count; + const char *driver; + if (netdev->type != NL80211_IFTYPE_STATION) return; if (L_WARN_ON(!netdev->connected)) return; + driver = wiphy_get_driver(netdev_get_wiphy(netdev)); + + /* + * If the channel switch countdown is present, the switch is imminent + * but has not happened yet. Wait for the second CH_SWITCH_NOTIFY + * event (which omits the count) to avoid interrupting the firmware + * by prematurely starting a scan. + * + * Restrict this workaround to mt7925 cards as requested. + */ + if (driver && !strncmp(driver, "mt7925", 6) && + nl80211_parse_attrs(msg, NL80211_ATTR_CH_SWITCH_COUNT, &count, + NL80211_ATTR_UNSPEC) == 0) { + l_debug("Channel switch imminent in %u TBTTs, waiting...", count); + return; + } + chandef = l_new(struct band_chandef, 1); if (nl80211_parse_chandef(msg, chandef) < 0) { -- 2.55.0