[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