[PATCH 1/2] mt76: connac: fix txpower_cur not updated in mt76_connac_mcu_set_rate_txpower()
bryam vargas
bryamestebanvargas at gmail.com
Wed Mar 11 13:58:25 PDT 2026
>From 9fabc33e722f321b4048ada6d4667ddacbb1495a Mon Sep 17 00:00:00 2001
From: bryam <bryamestebanvargas at gmail.com>
Date: Mon, 9 Mar 2026 12:25:37 -0500
Subject: [PATCH v2 2/2] mt76: mt7921u: trigger USB reset only on wfsys timeout
Instead of unconditionally scheduling a USB device reset at the start
of the reset sequence, trigger it only when mt792xu_wfsys_reset()
returns -ETIMEDOUT, which indicates the chip is in a latched state
(SEFI - Single Event Functional Interrupt) where register writes over
USB become silent no-ops.
This avoids the race condition where usb_queue_reset_device() was
scheduled asynchronously while the driver continued normal reset
operations on the same device.
Tested-on: Minisforum NAB9 (MT7921U USB adapter) at 2400m altitude,
Bogota, Colombia. Cosmic radiation causes periodic SEFI
events; USB reset restores connectivity without intervention.
Signed-off-by: Bryam Vargas <bryamestebanvargas at gmail.com>
---
.../net/wireless/mediatek/mt76/mt7921/usb.c | 32 +++++++++----------
.../net/wireless/mediatek/mt76/mt792x_usb.c | 16 ++++------
2 files changed, 23 insertions(+), 25 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/usb.c
b/drivers/net/wireless/mediatek/mt76/mt7921/usb.c
index 8c8c78f..44c7437 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/usb.c
@@ -86,33 +86,33 @@ static int mt7921u_mcu_init(struct mt792x_dev *dev)
static int mt7921u_mac_reset(struct mt792x_dev *dev)
{
- struct usb_interface *intf = to_usb_interface(dev->mt76.dev);
int err;
mt76_txq_schedule_all(&dev->mphy);
mt76_worker_disable(&dev->mt76.tx_worker);
-
set_bit(MT76_RESET, &dev->mphy.state);
set_bit(MT76_MCU_RESET, &dev->mphy.state);
-
wake_up(&dev->mt76.mcu.wait);
skb_queue_purge(&dev->mt76.mcu.res_q);
-
mt76u_stop_rx(&dev->mt76);
mt76u_stop_tx(&dev->mt76);
- /* When the chip enters a latched state (SEFI - Single Event
- * Functional Interrupt, e.g. from cosmic radiation at altitude),
- * all register writes over USB become silent no-ops.
- * usb_queue_reset_device() electrically resets the chip via the
- * USB hub regardless of internal state -- identical to probe().
- * Async variant required to avoid deadlock in workqueue context.
- */
- dev_warn(dev->mt76.dev,
- "mt7921u: scheduling USB reset for chip recovery\n");
- usb_queue_reset_device(intf);
-
- mt792xu_wfsys_reset(dev);
+ err = mt792xu_wfsys_reset(dev);
+ if (err == -ETIMEDOUT) {
+ /* Chip is in a latched state (SEFI - Single Event Functional
+ * Interrupt, e.g. from cosmic radiation at altitude).
+ * Register writes over USB become silent no-ops; schedule an
+ * electrical USB reset via the hub as last resort.
+ * usb_queue_reset_device() is async to avoid deadlock in
+ * workqueue context.
+ */
+ struct usb_interface *intf = to_usb_interface(dev->mt76.dev);
+
+ dev_warn(dev->mt76.dev,
+ "mt7921u: wfsys reset timed out, scheduling USB reset\n");
+ usb_queue_reset_device(intf);
+ goto out;
+ }
clear_bit(MT76_MCU_RESET, &dev->mphy.state);
err = mt76u_resume_rx(&dev->mt76);
diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_usb.c
b/drivers/net/wireless/mediatek/mt76/mt792x_usb.c
index cfd385e..4737384 100644
--- a/drivers/net/wireless/mediatek/mt76/mt792x_usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt792x_usb.c
@@ -269,7 +269,6 @@ EXPORT_SYMBOL_GPL(mt792xu_wfsys_reset);
int mt792xu_init_reset(struct mt792x_dev *dev)
{
- struct usb_interface *intf = to_usb_interface(dev->mt76.dev);
set_bit(MT76_RESET, &dev->mphy.state);
@@ -279,15 +278,14 @@ int mt792xu_init_reset(struct mt792x_dev *dev)
mt76u_stop_rx(&dev->mt76);
mt76u_stop_tx(&dev->mt76);
- /* Same rationale as mt7921u_mac_reset(): if the chip is in a
- * latched state (SEFI), register writes over USB are no-ops.
- * Schedule a USB port reset before software reset sequence.
- */
- dev_warn(dev->mt76.dev,
- "mt7921u: scheduling USB device reset (init_reset path)\n");
- usb_queue_reset_device(intf);
+ if (mt792xu_wfsys_reset(dev) == -ETIMEDOUT) {
+ struct usb_interface *intf = to_usb_interface(dev->mt76.dev);
+
+ dev_warn(dev->mt76.dev,
+ "mt792xu: wfsys reset timed out, scheduling USB reset\n");
+ usb_queue_reset_device(intf);
+ }
- mt792xu_wfsys_reset(dev);
clear_bit(MT76_RESET, &dev->mphy.state);
--
2.43.0
More information about the Linux-mediatek
mailing list