All of lore.kernel.org
 help / color / mirror / Atom feed
From: George Maraveyas via B4 Relay <devnull+george.0xfff.gmail.com@kernel.org>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	 Marcel Holtmann <marcel@holtmann.org>,
	 Luiz Augusto von Dentz <luiz.dentz@gmail.com>,
	 Matthias Brugger <matthias.bgg@gmail.com>,
	 AngeloGioacchino Del Regno
	<angelogioacchino.delregno@collabora.com>
Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
	 linux-bluetooth@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	 linux-mediatek@lists.infradead.org,
	 George Maraveyas <george.0xfff@gmail.com>
Subject: [PATCH RFC 2/2] Bluetooth: mt7925: recover subsystem-reset timeout through USB re-enumeration
Date: Tue, 18 Aug 2026 04:55:21 +0200	[thread overview]
Message-ID: <20260818-mt7925-rfc-v1-2-284d856ac572@gmail.com> (raw)
In-Reply-To: <20260818-mt7925-rfc-v1-0-284d856ac572@gmail.com>

From: George Maraveyas <george.0xfff@gmail.com>

The MT7925 Bluetooth controller on an ASUS ROG Strix B850-I Gaming WiFi
can remain unusable after a warm reboot even though its USB function
initially enumerates normally.

The Bluetooth USB function on the test system is:

  idVendor=13d3, idProduct=3602
  Manufacturer: MediaTek Inc.
  Product: Wireless_Device

The problem was reproduced with ASUS motherboard BIOS versions 1644 and
1681.  Updating from BIOS 1644 to 1681 did not change the failure.

The Bluetooth firmware reported during testing was:

  HW/SW Version: 0x00000000
  Build Time: 20260605184935

A typical Windows 11-to-Linux failure is:

  1. The MT7925 USB function enumerates as 13d3:3602.
  2. Bluetooth setup begins.
  3. The WMT function-control command times out with -ETIMEDOUT (-110).
  4. The existing MediaTek reset work runs.
  5. btmtk_usb_subsys_reset() also times out.
  6. Resetting the existing usb_device does not recover the controller.

The relevant log contains:

  Bluetooth: hci0: Execution of wmt command timed out
  Bluetooth: hci0: Failed to send wmt func ctrl (-110)
  Bluetooth: hci0: MT7925 WMT func ctrl timed out (dev_id=0x7925), scheduling device reset
  Bluetooth: hci0: Failed to read uhw reg(-110)

The WMT timeout handling and scheduling of the MediaTek reset already
exist before this change.  This patch begins later, inside
btusb_mtk_reset(), after btmtk_usb_subsys_reset() has returned.

The existing path calls btmtk_usb_subsys_reset() and then queues
usb_queue_reset_device().  On the affected MT7925 the subsystem reset
returns -ETIMEDOUT, and resetting the existing usb_device does not recover
the controller.

After btmtk_usb_subsys_reset() returns, check for an MT7925 device and an
-ETIMEDOUT result.  When both conditions are present, request
re-enumeration through usb_queue_reenumerate_device(), added by Patch 1.

If the re-enumeration request is queued successfully, clear
BTMTK_HW_RESET_ACTIVE and return the original subsystem-reset error.  If
the request cannot be queued, report the error and continue into the
existing usb_queue_reset_device() path.

Other MediaTek devices and MT7925 reset results other than -ETIMEDOUT
continue to use the existing recovery path unchanged.

The re-enumeration request gives the MT7925 another chance to go through
normal USB enumeration via the helper in Patch 1, which does this.  This
patch calls that helper when the MT7925 subsystem reset has timed out.

Chia-Lin Kao's preceding _PRR patch is required for the port recovery
used on this machine.  Re-enumeration does not itself request a port
power-cycle or an ACPI _PRR reset.  If the re-enumerated device continues
to fail during enumeration, the existing hub retry path can reach its
port power-cycle, where the _PRR prerequisite supplies the ACPI reset.

The _PRR prerequisite does not fix this failure by itself because the
first USB enumeration has already succeeded before the WMT timeout and
subsequent subsystem-reset timeout occur.

A representative successful recovery was:

  Bluetooth: hci0: MT7925 subsystem reset timed out, requesting USB re-enumeration
  usb 1-11: USB disconnect, device number 4
  usb 1-11: device descriptor read/64, error -110
  usb 1-11: device descriptor read/64, error -110
  usb usb1-port11: attempt power cycle
  usb 1-11: New USB device found, idVendor=13d3, idProduct=3602

Three Windows 11-to-Linux warm restart tests recovered successfully with
this series.  The observed average interval from the initial WMT timeout
to successful Bluetooth setup was about 70.9 seconds.

Bluetooth remains unavailable during most of this interval, so recovery
should not be expected immediately after usb_queue_reenumerate_device()
is called.

Signed-off-by: George Maraveyas <george.0xfff@gmail.com>
---
 drivers/bluetooth/btmtk.c |  4 ++++
 drivers/bluetooth/btusb.c | 16 ++++++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
index 66b346761..e8f02f1e3 100644
--- a/drivers/bluetooth/btmtk.c
+++ b/drivers/bluetooth/btmtk.c
@@ -1413,6 +1413,10 @@ int btmtk_usb_setup(struct hci_dev *hdev)
 		err = btmtk_usb_hci_wmt_sync(hdev, &wmt_params);
 		if (err < 0) {
 			bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
+
+			if (dev_id == 0x7925 && err == -ETIMEDOUT)
+				btmtk_reset_sync(hdev);
+
 			return err;
 		}
 
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 2bae85b00..5b56c26de 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -2943,6 +2943,22 @@ static int btusb_mtk_reset(struct hci_dev *hdev, void *rst_data)
 
 	err = btmtk_usb_subsys_reset(hdev, btmtk_data->dev_id);
 
+	if (btmtk_data->dev_id == 0x7925 && err == -ETIMEDOUT) {
+		int reenum_err;
+
+		bt_dev_warn(hdev,
+			    "MT7925 subsystem reset timed out, requesting USB re-enumeration");
+
+		reenum_err = usb_queue_reenumerate_device(data->intf);
+		if (!reenum_err) {
+			clear_bit(BTMTK_HW_RESET_ACTIVE, &btmtk_data->flags);
+			return err;
+		}
+
+		bt_dev_err(hdev, "Failed to queue USB re-enumeration (%d)",
+			   reenum_err);
+	}
+
 	usb_queue_reset_device(data->intf);
 	clear_bit(BTMTK_HW_RESET_ACTIVE, &btmtk_data->flags);
 

-- 
2.53.0



WARNING: multiple messages have this Message-ID (diff)
From: George Maraveyas <george.0xfff@gmail.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	 Marcel Holtmann <marcel@holtmann.org>,
	 Luiz Augusto von Dentz <luiz.dentz@gmail.com>,
	 Matthias Brugger <matthias.bgg@gmail.com>,
	 AngeloGioacchino Del Regno
	<angelogioacchino.delregno@collabora.com>
Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
	 linux-bluetooth@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	 linux-mediatek@lists.infradead.org,
	 George Maraveyas <george.0xfff@gmail.com>
Subject: [PATCH RFC 2/2] Bluetooth: mt7925: recover subsystem-reset timeout through USB re-enumeration
Date: Tue, 18 Aug 2026 04:55:21 +0200	[thread overview]
Message-ID: <20260818-mt7925-rfc-v1-2-284d856ac572@gmail.com> (raw)
In-Reply-To: <20260818-mt7925-rfc-v1-0-284d856ac572@gmail.com>

The MT7925 Bluetooth controller on an ASUS ROG Strix B850-I Gaming WiFi
can remain unusable after a warm reboot even though its USB function
initially enumerates normally.

The Bluetooth USB function on the test system is:

  idVendor=13d3, idProduct=3602
  Manufacturer: MediaTek Inc.
  Product: Wireless_Device

The problem was reproduced with ASUS motherboard BIOS versions 1644 and
1681.  Updating from BIOS 1644 to 1681 did not change the failure.

The Bluetooth firmware reported during testing was:

  HW/SW Version: 0x00000000
  Build Time: 20260605184935

A typical Windows 11-to-Linux failure is:

  1. The MT7925 USB function enumerates as 13d3:3602.
  2. Bluetooth setup begins.
  3. The WMT function-control command times out with -ETIMEDOUT (-110).
  4. The existing MediaTek reset work runs.
  5. btmtk_usb_subsys_reset() also times out.
  6. Resetting the existing usb_device does not recover the controller.

The relevant log contains:

  Bluetooth: hci0: Execution of wmt command timed out
  Bluetooth: hci0: Failed to send wmt func ctrl (-110)
  Bluetooth: hci0: MT7925 WMT func ctrl timed out (dev_id=0x7925), scheduling device reset
  Bluetooth: hci0: Failed to read uhw reg(-110)

The WMT timeout handling and scheduling of the MediaTek reset already
exist before this change.  This patch begins later, inside
btusb_mtk_reset(), after btmtk_usb_subsys_reset() has returned.

The existing path calls btmtk_usb_subsys_reset() and then queues
usb_queue_reset_device().  On the affected MT7925 the subsystem reset
returns -ETIMEDOUT, and resetting the existing usb_device does not recover
the controller.

After btmtk_usb_subsys_reset() returns, check for an MT7925 device and an
-ETIMEDOUT result.  When both conditions are present, request
re-enumeration through usb_queue_reenumerate_device(), added by Patch 1.

If the re-enumeration request is queued successfully, clear
BTMTK_HW_RESET_ACTIVE and return the original subsystem-reset error.  If
the request cannot be queued, report the error and continue into the
existing usb_queue_reset_device() path.

Other MediaTek devices and MT7925 reset results other than -ETIMEDOUT
continue to use the existing recovery path unchanged.

The re-enumeration request gives the MT7925 another chance to go through
normal USB enumeration via the helper in Patch 1, which does this.  This
patch calls that helper when the MT7925 subsystem reset has timed out.

Chia-Lin Kao's preceding _PRR patch is required for the port recovery
used on this machine.  Re-enumeration does not itself request a port
power-cycle or an ACPI _PRR reset.  If the re-enumerated device continues
to fail during enumeration, the existing hub retry path can reach its
port power-cycle, where the _PRR prerequisite supplies the ACPI reset.

The _PRR prerequisite does not fix this failure by itself because the
first USB enumeration has already succeeded before the WMT timeout and
subsequent subsystem-reset timeout occur.

A representative successful recovery was:

  Bluetooth: hci0: MT7925 subsystem reset timed out, requesting USB re-enumeration
  usb 1-11: USB disconnect, device number 4
  usb 1-11: device descriptor read/64, error -110
  usb 1-11: device descriptor read/64, error -110
  usb usb1-port11: attempt power cycle
  usb 1-11: New USB device found, idVendor=13d3, idProduct=3602

Three Windows 11-to-Linux warm restart tests recovered successfully with
this series.  The observed average interval from the initial WMT timeout
to successful Bluetooth setup was about 70.9 seconds.

Bluetooth remains unavailable during most of this interval, so recovery
should not be expected immediately after usb_queue_reenumerate_device()
is called.

Signed-off-by: George Maraveyas <george.0xfff@gmail.com>
---
 drivers/bluetooth/btmtk.c |  4 ++++
 drivers/bluetooth/btusb.c | 16 ++++++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
index 66b346761..e8f02f1e3 100644
--- a/drivers/bluetooth/btmtk.c
+++ b/drivers/bluetooth/btmtk.c
@@ -1413,6 +1413,10 @@ int btmtk_usb_setup(struct hci_dev *hdev)
 		err = btmtk_usb_hci_wmt_sync(hdev, &wmt_params);
 		if (err < 0) {
 			bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
+
+			if (dev_id == 0x7925 && err == -ETIMEDOUT)
+				btmtk_reset_sync(hdev);
+
 			return err;
 		}
 
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 2bae85b00..5b56c26de 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -2943,6 +2943,22 @@ static int btusb_mtk_reset(struct hci_dev *hdev, void *rst_data)
 
 	err = btmtk_usb_subsys_reset(hdev, btmtk_data->dev_id);
 
+	if (btmtk_data->dev_id == 0x7925 && err == -ETIMEDOUT) {
+		int reenum_err;
+
+		bt_dev_warn(hdev,
+			    "MT7925 subsystem reset timed out, requesting USB re-enumeration");
+
+		reenum_err = usb_queue_reenumerate_device(data->intf);
+		if (!reenum_err) {
+			clear_bit(BTMTK_HW_RESET_ACTIVE, &btmtk_data->flags);
+			return err;
+		}
+
+		bt_dev_err(hdev, "Failed to queue USB re-enumeration (%d)",
+			   reenum_err);
+	}
+
 	usb_queue_reset_device(data->intf);
 	clear_bit(BTMTK_HW_RESET_ACTIVE, &btmtk_data->flags);
 

-- 
2.53.0


  parent reply	other threads:[~2026-08-18  3:00 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-18  2:55 [PATCH RFC 0/2] USB/Bluetooth: recover MT7925 after warm reboot George Maraveyas via B4 Relay
2026-08-18  2:55 ` George Maraveyas
2026-08-18  2:55 ` [PATCH RFC 1/2] USB: core: add helper to queue device re-enumeration George Maraveyas via B4 Relay
2026-08-18  2:55   ` George Maraveyas
2026-08-18  3:20   ` Alan Stern
2026-08-18  4:15   ` USB/Bluetooth: recover MT7925 after warm reboot bluez.test.bot
2026-08-18  2:55 ` George Maraveyas via B4 Relay [this message]
2026-08-18  2:55   ` [PATCH RFC 2/2] Bluetooth: mt7925: recover subsystem-reset timeout through USB re-enumeration George Maraveyas
2026-08-21 23:37 ` [PATCH RFC v2] Bluetooth: mt7925: trigger reset on WMT timeout George Maraveyas via B4 Relay
2026-08-21 23:37   ` George Maraveyas
2026-08-22  0:07   ` [RFC,v2] " bluez.test.bot
2026-08-24 16:50   ` [PATCH RFC v2] " patchwork-bot+bluetooth

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260818-mt7925-rfc-v1-2-284d856ac572@gmail.com \
    --to=devnull+george.0xfff.gmail.com@kernel.org \
    --cc=angelogioacchino.delregno@collabora.com \
    --cc=george.0xfff@gmail.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-bluetooth@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mediatek@lists.infradead.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=luiz.dentz@gmail.com \
    --cc=marcel@holtmann.org \
    --cc=matthias.bgg@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.