Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH v2] Bluetooth: btmtk: Add MT7928 support
From: Chris Lu @ 2026-06-17  6:17 UTC (permalink / raw)
  To: Marcel Holtmann, Johan Hedberg, Luiz Von Dentz
  Cc: Sean Wang, Will Lee, SS Wu, Steve Lee, linux-bluetooth,
	linux-kernel, linux-mediatek, Chris Lu

Add support for MT7928 (device ID 0x7935) which requires additional
firmware (CBMCU firmware) loading before Bluetooth firmware.

Implement two-phase CBMCU firmware download: Phase 1 loads
section with type 0x5 containing global descriptor,
section maps and signature data; Phase 2 loads remaining
firmware sections. Add retry mechanism for concurrent download
protection.

After CBMCU firmware loads successfully, the driver continues
to load corresponding BT firmware based on device ID through
fallthrough to case 0x7922/0x7925.

MT7928 bringup kernel log:
[90.081868] usb 1-3: new high-speed USB device number 28 using xhci_hcd
[90.209995] usb 1-3: New USB device found, idVendor=0e8d, idProduct=7935, bcdDevice= 1.00
[90.210027] usb 1-3: New USB device strings: Mfr=5, Product=6, SerialNumber=7
[90.210046] usb 1-3: Product: Wireless_Device
[90.210060] usb 1-3: Manufacturer: MediaTek Inc.
[90.210075] usb 1-3: SerialNumber: 000000000
[90.223089] Bluetooth: hci1: CBMCU Version: 0x00000000, Build Time: 20260601T161751+0800
[90.664706] Bluetooth: hci1: CBMCU firmware download completed
[90.685424] Bluetooth: hci1: HW/SW Version: 0x00000000, Build Time: 20260527000816
[93.771612] Bluetooth: hci1: Device setup in 3467323 usecs
[93.771657] Bluetooth: hci1: HCI Enhanced Setup Synchronous
            Connection command is advertised, but not supported.
[93.890840] Bluetooth: hci1: AOSP extensions version v2.00
[93.890887] Bluetooth: hci1: AOSP quality report is supported
[93.893444] Bluetooth: MGMT ver 1.23

Signed-off-by: Chris Lu <chris.lu@mediatek.com>
---
v1->v2: Update error message; Use macro instead of magic number.
---
 drivers/bluetooth/btmtk.c | 348 +++++++++++++++++++++++++++++++++++++-
 drivers/bluetooth/btmtk.h |   3 +
 2 files changed, 350 insertions(+), 1 deletion(-)

diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
index 02a96342e964..6bae0b0794dd 100644
--- a/drivers/bluetooth/btmtk.c
+++ b/drivers/bluetooth/btmtk.c
@@ -21,6 +21,8 @@
 #define MTK_FW_ROM_PATCH_SEC_MAP_SIZE	64
 #define MTK_SEC_MAP_COMMON_SIZE	12
 #define MTK_SEC_MAP_NEED_SEND_SIZE	52
+#define MTK_SEC_MAP_LENGTH_SIZE	4
+#define MTK_SEC_CBMCU_DESC	0x5
 
 /* It is for mt79xx iso data transmission setting */
 #define MTK_ISO_THRESHOLD	264
@@ -120,6 +122,10 @@ void btmtk_fw_get_filename(char *buf, size_t size, u32 dev_id, u32 fw_ver,
 		snprintf(buf, size,
 			 "mediatek/mt%04x/BT_RAM_CODE_MT%04x_1_%x_hdr.bin",
 			 dev_id & 0xffff, dev_id & 0xffff, (fw_ver & 0xff) + 1);
+	else if (dev_id == 0x7935)
+		snprintf(buf, size,
+			 "mediatek/mt7928/BT_RAM_CODE_MT%04x_1_1_hdr.bin",
+			 dev_id & 0xffff);
 	else if (dev_id == 0x7961 && fw_flavor)
 		snprintf(buf, size,
 			 "mediatek/BT_RAM_CODE_MT%04x_1a_%x_hdr.bin",
@@ -734,6 +740,7 @@ static int btmtk_usb_hci_wmt_sync(struct hci_dev *hdev,
 			status = BTMTK_WMT_ON_UNDONE;
 		break;
 	case BTMTK_WMT_PATCH_DWNLD:
+	case BTMTK_WMT_CBMCU_DWNLD:
 		if (wmt_evt->whdr.flag == 2)
 			status = BTMTK_WMT_PATCH_DONE;
 		else if (wmt_evt->whdr.flag == 1)
@@ -870,6 +877,334 @@ static u32 btmtk_usb_reset_done(struct hci_dev *hdev)
 	return val & MTK_BT_RST_DONE;
 }
 
+static int btmtk_cbmcu_patch_status(struct hci_dev *hdev,
+				    wmt_cmd_sync_func_t wmt_cmd_sync,
+				    u8 *patch_status)
+{
+	struct btmtk_hci_wmt_params wmt_params;
+	int status, err, retry = 20;
+
+	do {
+		wmt_params.op = BTMTK_WMT_CBMCU_DWNLD;
+		wmt_params.flag = 0xF0;
+		wmt_params.dlen = 0;
+		wmt_params.data = NULL;
+		wmt_params.status = &status;
+
+		err = wmt_cmd_sync(hdev, &wmt_params);
+		if (err < 0) {
+			bt_dev_err(hdev, "Failed to query CBMCU patch status (%d)", err);
+			return err;
+		}
+
+		*patch_status = (u8)status;
+
+		if (*patch_status == BTMTK_WMT_PATCH_PROGRESS) {
+			msleep(100);
+			retry--;
+		} else {
+			break;
+		}
+	} while (retry > 0);
+
+	return 0;
+}
+
+static int btmtk_query_cbmcu_section(struct hci_dev *hdev,
+				     wmt_cmd_sync_func_t wmt_cmd_sync,
+				     u8 cbmcu_type,
+				     const u8 *section_map,
+				     u32 cert_len)
+{
+	struct btmtk_hci_wmt_params wmt_params;
+	u8 cmd[64];
+	int status, err;
+
+	cmd[0] = 0;
+	cmd[1] = cbmcu_type;
+
+	if (cbmcu_type == 0)
+		put_unaligned_le32(cert_len, &cmd[2]);
+	else
+		memcpy(&cmd[2], section_map, MTK_SEC_MAP_NEED_SEND_SIZE);
+
+	wmt_params.op = BTMTK_WMT_CBMCU_DWNLD;
+	wmt_params.flag = 0;
+	wmt_params.dlen = cbmcu_type ?
+		MTK_SEC_MAP_NEED_SEND_SIZE + 2 :
+		MTK_SEC_MAP_LENGTH_SIZE + 2;
+	wmt_params.data = cmd;
+	wmt_params.status = &status;
+
+	err = wmt_cmd_sync(hdev, &wmt_params);
+	if (err < 0) {
+		bt_dev_err(hdev, "Failed to query CBMCU section (%d)", err);
+		return err;
+	}
+
+	/* Query should return UNDONE status for successful section query */
+	if (status != BTMTK_WMT_PATCH_UNDONE) {
+		bt_dev_err(hdev, "CBMCU section query status error (%d)", status);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int btmtk_download_cbmcu_section(struct hci_dev *hdev,
+					wmt_cmd_sync_func_t wmt_cmd_sync,
+					const u8 *fw_data,
+					u32 dl_size)
+{
+	struct btmtk_hci_wmt_params wmt_params;
+	u32 sent_len, total_size = dl_size;
+	int err;
+
+	wmt_params.op = BTMTK_WMT_CBMCU_DWNLD;
+	wmt_params.status = NULL;
+
+	while (dl_size > 0) {
+		sent_len = min_t(u32, 250, dl_size);
+
+		if (dl_size == total_size)
+			wmt_params.flag = 1;
+		else if (dl_size == sent_len)
+			wmt_params.flag = 3;
+		else
+			wmt_params.flag = 2;
+
+		wmt_params.dlen = sent_len;
+		wmt_params.data = fw_data;
+
+		err = wmt_cmd_sync(hdev, &wmt_params);
+		if (err < 0) {
+			bt_dev_err(hdev, "Failed to send CBMCU section data (%d)", err);
+			return err;
+		}
+
+		dl_size -= sent_len;
+		fw_data += sent_len;
+	}
+
+	return 0;
+}
+
+static int btmtk_enable_cbmcu_patch(struct hci_dev *hdev,
+				    wmt_cmd_sync_func_t wmt_cmd_sync)
+{
+	struct btmtk_hci_wmt_params wmt_params;
+	int err;
+
+	wmt_params.op = BTMTK_WMT_CBMCU_DWNLD;
+	wmt_params.flag = 0xF1;
+	wmt_params.dlen = 0;
+	wmt_params.data = NULL;
+	wmt_params.status = NULL;
+
+	err = wmt_cmd_sync(hdev, &wmt_params);
+	if (err < 0) {
+		bt_dev_err(hdev, "Failed to enable CBMCU patch (%d)", err);
+		return err;
+	}
+
+	return 0;
+}
+
+static int btmtk_load_cbmcu_firmware(struct hci_dev *hdev,
+				     const char *fwname,
+				     wmt_cmd_sync_func_t wmt_cmd_sync)
+{
+	struct btmtk_patch_header *hdr;
+	struct btmtk_global_desc *globaldesc;
+	struct btmtk_section_map *sectionmap;
+	const struct firmware *fw;
+	const u8 *fw_ptr;
+	u8 *cert_buf = NULL;
+	u32 section_num, section_offset, dl_size, cert_len;
+	int i, err;
+
+	err = request_firmware(&fw, fwname, &hdev->dev);
+	if (err < 0) {
+		bt_dev_err(hdev, "Failed to load CBMCU firmware file %s (%d)",
+			   fwname, err);
+		return err;
+	}
+
+	if (fw->size < MTK_FW_ROM_PATCH_HEADER_SIZE + MTK_FW_ROM_PATCH_GD_SIZE) {
+		bt_dev_err(hdev, "CBMCU firmware too small (%zu bytes)", fw->size);
+		err = -EINVAL;
+		goto err_release_fw;
+	}
+
+	fw_ptr = fw->data;
+	hdr = (struct btmtk_patch_header *)fw_ptr;
+	globaldesc = (struct btmtk_global_desc *)(fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE);
+	section_num = le32_to_cpu(globaldesc->section_num);
+
+	if (fw->size < MTK_FW_ROM_PATCH_HEADER_SIZE + MTK_FW_ROM_PATCH_GD_SIZE +
+		       (size_t)MTK_FW_ROM_PATCH_SEC_MAP_SIZE * section_num) {
+		bt_dev_err(hdev, "CBMCU firmware truncated: size=%zu, expected=%zu (section_num=%u)",
+			   fw->size,
+			   MTK_FW_ROM_PATCH_HEADER_SIZE + MTK_FW_ROM_PATCH_GD_SIZE +
+			   (size_t)MTK_FW_ROM_PATCH_SEC_MAP_SIZE * section_num,
+			   section_num);
+		err = -EINVAL;
+		goto err_release_fw;
+	}
+
+	bt_dev_info(hdev, "CBMCU Version: 0x%04x%04x, Build Time: %s",
+		    le16_to_cpu(hdr->hwver), le16_to_cpu(hdr->swver), hdr->datetime);
+
+	/* Phase 1: Download section type MTK_SEC_CBMCU_DESC */
+	for (i = 0; i < section_num; i++) {
+		sectionmap = (struct btmtk_section_map *)
+			(fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE +
+			 MTK_FW_ROM_PATCH_GD_SIZE +
+			 MTK_FW_ROM_PATCH_SEC_MAP_SIZE * i);
+
+		/* Only process MTK_SEC_CBMCU_DESC section in Phase 1 */
+		if ((le32_to_cpu(sectionmap->sectype) & 0xFFFF) != MTK_SEC_CBMCU_DESC)
+			continue;
+
+		section_offset = le32_to_cpu(sectionmap->secoffset);
+		dl_size = le32_to_cpu(sectionmap->secsize);
+
+		if (dl_size == 0)
+			continue;
+
+		if (section_offset > fw->size ||
+		    dl_size > fw->size - section_offset) {
+			bt_dev_err(hdev, "CBMCU Phase 1 section out of bounds");
+			err = -EINVAL;
+			goto err_release_fw;
+		}
+
+		cert_len = MTK_FW_ROM_PATCH_GD_SIZE +
+			   MTK_FW_ROM_PATCH_SEC_MAP_SIZE * section_num +
+			   dl_size;
+
+		/* Query cbmcu section */
+		err = btmtk_query_cbmcu_section(hdev, wmt_cmd_sync, 0, NULL,
+						cert_len);
+		if (err < 0)
+			goto err_release_fw;
+
+		cert_buf = kmalloc(cert_len, GFP_KERNEL);
+		if (!cert_buf) {
+			err = -ENOMEM;
+			goto err_release_fw;
+		}
+
+		/* Copy Global Descriptor + All Section Maps */
+		memcpy(cert_buf,
+		       fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE,
+		       MTK_FW_ROM_PATCH_GD_SIZE + MTK_FW_ROM_PATCH_SEC_MAP_SIZE * section_num);
+
+		/* Copy Phase 1 section data */
+		memcpy(cert_buf + MTK_FW_ROM_PATCH_GD_SIZE +
+		       MTK_FW_ROM_PATCH_SEC_MAP_SIZE * section_num,
+		       fw_ptr + section_offset,
+		       dl_size);
+
+		/* Download Phase 1 section */
+		err = btmtk_download_cbmcu_section(hdev, wmt_cmd_sync,
+						   cert_buf, cert_len);
+		kfree(cert_buf);
+		cert_buf = NULL;
+
+		if (err < 0) {
+			bt_dev_err(hdev, "Failed to download CBMCU Phase 1 section (%d)", err);
+			goto err_release_fw;
+		}
+
+		break;
+	}
+
+	/* Phase 2: Download other sections (type != MTK_SEC_CBMCU_DESC) */
+	for (i = 0; i < section_num; i++) {
+		sectionmap = (struct btmtk_section_map *)
+			(fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE +
+			 MTK_FW_ROM_PATCH_GD_SIZE +
+			 MTK_FW_ROM_PATCH_SEC_MAP_SIZE * i);
+
+		/* Skip MTK_SEC_CBMCU_DESC section in Phase 2 */
+		if ((le32_to_cpu(sectionmap->sectype) & 0xFFFF) == MTK_SEC_CBMCU_DESC)
+			continue;
+
+		section_offset = le32_to_cpu(sectionmap->secoffset);
+		dl_size = le32_to_cpu(sectionmap->bin_info_spec.dlsize);
+
+		if (dl_size == 0)
+			continue;
+
+		if (section_offset > fw->size ||
+		    dl_size > fw->size - section_offset) {
+			bt_dev_err(hdev, "CBMCU Phase 2 section %d out of bounds", i);
+			err = -EINVAL;
+			goto err_release_fw;
+		}
+
+		/* Query cbmcu section */
+		err = btmtk_query_cbmcu_section(hdev, wmt_cmd_sync, 1,
+						(u8 *)&sectionmap->bin_info_spec,
+						0);
+		if (err < 0)
+			goto err_release_fw;
+
+		/* Download section data */
+		err = btmtk_download_cbmcu_section(hdev, wmt_cmd_sync,
+						   fw_ptr + section_offset,
+						   dl_size);
+		if (err < 0) {
+			bt_dev_err(hdev, "Failed to download CBMCU section %d (%d)", i, err);
+			goto err_release_fw;
+		}
+	}
+
+	/* Wait for firmware activation */
+	usleep_range(100000, 120000);
+
+	bt_dev_info(hdev, "CBMCU firmware download completed");
+
+err_release_fw:
+	release_firmware(fw);
+	return err;
+}
+
+static int btmtk_setup_cbmcu_firmware(struct hci_dev *hdev,
+				      wmt_cmd_sync_func_t wmt_cmd_sync,
+				      u32 dev_id)
+{
+	char cbmcu_fwname[64];
+	u8 patch_status;
+	int err;
+
+	err = btmtk_cbmcu_patch_status(hdev, wmt_cmd_sync, &patch_status);
+	if (err < 0)
+		return err;
+
+	bt_dev_dbg(hdev, "CBMCU patch status: 0x%02x", patch_status);
+
+	if (patch_status != BTMTK_WMT_PATCH_UNDONE)
+		return 0;
+
+	snprintf(cbmcu_fwname, sizeof(cbmcu_fwname),
+		 "mediatek/mt7928/CBMCU_CODE_MT%04x_1_1.bin",
+		 dev_id & 0xffff);
+
+	err = btmtk_load_cbmcu_firmware(hdev, cbmcu_fwname, wmt_cmd_sync);
+	if (err < 0) {
+		bt_dev_err(hdev, "Failed to download CBMCU firmware (%d)", err);
+		return err;
+	}
+
+	err = btmtk_enable_cbmcu_patch(hdev, wmt_cmd_sync);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
 int btmtk_usb_subsys_reset(struct hci_dev *hdev, u32 dev_id)
 {
 	u32 val;
@@ -894,7 +1229,7 @@ int btmtk_usb_subsys_reset(struct hci_dev *hdev, u32 dev_id)
 		if (err < 0)
 			return err;
 		msleep(100);
-	} else if (dev_id == 0x7925 || dev_id == 0x6639) {
+	} else if (dev_id == 0x7925 || dev_id == 0x6639 || dev_id == 0x7935) {
 		err = btmtk_usb_uhw_reg_read(hdev, MTK_BT_RESET_REG_CONNV3, &val);
 		if (err < 0)
 			return err;
@@ -1379,6 +1714,15 @@ int btmtk_usb_setup(struct hci_dev *hdev)
 	case 0x7668:
 		fwname = FIRMWARE_MT7668;
 		break;
+	case 0x7935:
+		/* Requires CBMCU firmware before BT firmware */
+		err = btmtk_setup_cbmcu_firmware(hdev, btmtk_usb_hci_wmt_sync,
+						 dev_id);
+		if (err < 0) {
+			bt_dev_err(hdev, "Failed to set up CBMCU firmware (%d)", err);
+			return err;
+		}
+		fallthrough;
 	case 0x7922:
 	case 0x7925:
 		/*
@@ -1596,3 +1940,5 @@ MODULE_FIRMWARE(FIRMWARE_MT7922);
 MODULE_FIRMWARE(FIRMWARE_MT7961);
 MODULE_FIRMWARE(FIRMWARE_MT7925);
 MODULE_FIRMWARE(FIRMWARE_MT7927);
+MODULE_FIRMWARE(FIRMWARE_MT7928);
+MODULE_FIRMWARE(FIRMWARE_MT7928_CBMCU);
diff --git a/drivers/bluetooth/btmtk.h b/drivers/bluetooth/btmtk.h
index c83c24897c95..6d3bf6b74a1d 100644
--- a/drivers/bluetooth/btmtk.h
+++ b/drivers/bluetooth/btmtk.h
@@ -9,6 +9,8 @@
 #define FIRMWARE_MT7961		"mediatek/BT_RAM_CODE_MT7961_1_2_hdr.bin"
 #define FIRMWARE_MT7925		"mediatek/mt7925/BT_RAM_CODE_MT7925_1_1_hdr.bin"
 #define FIRMWARE_MT7927		"mediatek/mt7927/BT_RAM_CODE_MT6639_2_1_hdr.bin"
+#define FIRMWARE_MT7928		"mediatek/mt7928/BT_RAM_CODE_MT7935_1_1_hdr.bin"
+#define FIRMWARE_MT7928_CBMCU	"mediatek/mt7928/CBMCU_CODE_MT7935_1_1.bin"
 
 #define HCI_EV_WMT 0xe4
 #define HCI_WMT_MAX_EVENT_SIZE		64
@@ -54,6 +56,7 @@ enum {
 	BTMTK_WMT_RST = 0x7,
 	BTMTK_WMT_REGISTER = 0x8,
 	BTMTK_WMT_SEMAPHORE = 0x17,
+	BTMTK_WMT_CBMCU_DWNLD = 0x58,
 };
 
 enum {
-- 
2.45.2


^ permalink raw reply related

* [PATCH RFC] bluetooth: hci: Fix null-ptr-deref in hci_conn_timeout
From: Sungwoo Kim @ 2026-06-17  3:54 UTC (permalink / raw)
  To: Marcel Holtmann, Luiz Augusto von Dentz
  Cc: Sungwoo Kim, Dave Tian, Luiz Augusto von Dentz, linux-bluetooth,
	linux-kernel

RFC only.

The hci_conn_timeout() function dereferences hdev->sent_cmd when handling
connection timeouts. However, an HCI_EV_HARDWARE_ERROR can trigger an
asynchronous reset sequence that sets hdev->sent_cmd to NULL via
hci_dev_close_sync().

hdev->sent_cmd is dereferenced when conn->disc_work timeout:

hci_conn_timeout()
  hci_abort_conn()
    switch (hci_skb_event(hdev->sent_cmd)) {
      ...

However, an HCI hardware error event (HCI_EV_HARDWARE_ERROR) resets the
hci device, setting hdev->sent_cmd = NULL asynchornously:

hci_hardware_error_evt()
  hci_error_reset() (async)
    hci_dev_do_close()
      hci_dev_close_sync()
        hdev->sent_cmd = NULL;

As a result, a race condition exists between conn->disc_work execution
and the reset path, which can lead to a NULL pointer dereference when
hci_abort_conn() accesses hdev->sent_cmd.

To fix this, this patch ensures that all pending conn->disc_work
instances are canceled and completed before hdev->sent_cmd is cleared
during the reset path.
This is a provisional fix. Better design suggestions are welcome.

Oops:

Bluetooth: hci4: hardware error 0x00
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000007: 0000 [#1] SMP KASAN NOPTI
KASAN: null-ptr-deref in range [0x0000000000000038-0x000000000000003f]
CPU: 2 UID: 0 PID: 408 Comm: kworker/u17:4 Not tainted 7.1.0-dirty #96 PREEMPT(lazy)
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org 04/01/2014
Workqueue: hci1 hci_conn_timeout
RIP: 0010:hci_abort_conn+0x291/0x350 net/bluetooth/hci_conn.c:3196

Fixes: d0b137062b2d ("Bluetooth: hci_sync: Rework init stages")
Acked-by: Dave Tian <daveti@purdue.edu>
Signed-off-by: Sungwoo Kim <iam@sung-woo.kim>
---
 net/bluetooth/hci_sync.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index df23245d6ccd..dab709448a02 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -5419,6 +5419,14 @@ int hci_dev_close_sync(struct hci_dev *hdev)
 
 	/* Drop last sent command */
 	if (hdev->sent_cmd) {
+		struct hci_conn *c;
+
+		rcu_read_lock();
+		list_for_each_entry_rcu(c, &hdev->conn_hash.list, list) {
+			cancel_delayed_work_sync(&c->disc_work);
+		}
+		rcu_read_unlock();
+
 		cancel_delayed_work_sync(&hdev->cmd_timer);
 		kfree_skb(hdev->sent_cmd);
 		hdev->sent_cmd = NULL;
-- 
2.47.3


^ permalink raw reply related

* Re: [PATCH v2 1/3] Bluetooth: btmtksdio: correct btmtksdio_txrx_work() loop timeout check
From: Sergey Senozhatsky @ 2026-06-17  3:43 UTC (permalink / raw)
  To: Sean Wang
  Cc: Sergey Senozhatsky, Marcel Holtmann, Luiz Augusto von Dentz,
	Mark-yw Chen, Sean Wang, Tomasz Figa, linux-bluetooth,
	linux-kernel, linux-arm-kernel, linux-mediatek, stable
In-Reply-To: <CAGp9LzpCMGr2hyVJRMehs_BD4Rk6mS2jAifWuCgBaANdqgtvqA@mail.gmail.com>

On (26/06/16 19:40), Sean Wang wrote:
> > The btmtksdio_txrx_work() loop is expected to be terminated if running
> > for longer than 5*HZ.  However the timeout check is reversed:
> > time_is_before_jiffies(old_jiffies + 5*HZ) evaluates to true when
> > old_jiffies + 5*HZ is in the past i.e. when a timeout has occurred.
> > Using OR with time_is_before_jiffies(txrx_timeout) means that:
> > - before the 5-second timeout: the condition is `int_status || false`,
> >   so it loops as long as there are pending interrupts.
> > - after the 5-second timeout: the condition becomes `int_status || true`,
> >   which is always true.
> >
> > Fix loop termination condition to actually enforce a 5*HZ timeout.
> >
> > Fixes: 26270bc189ea4 ("Bluetooth: btmtksdio: move interrupt service to work")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
> > ---
> >  drivers/bluetooth/btmtksdio.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c
> > index 5b0fab7b89b5..c6f80c419e90 100644
> > --- a/drivers/bluetooth/btmtksdio.c
> > +++ b/drivers/bluetooth/btmtksdio.c
> > @@ -620,7 +620,7 @@ static void btmtksdio_txrx_work(struct work_struct *work)
> >                         if (btmtksdio_rx_packet(bdev, rx_size) < 0)
> >                                 bdev->hdev->stat.err_rx++;
> >                 }
> > -       } while (int_status || time_is_before_jiffies(txrx_timeout));
> > +       } while (int_status && time_is_after_jiffies(txrx_timeout));
> >
> 
> This patch has already been merged, so I think the series should be
> respun based on the latest code.

Oh, I see.  Any chance it can be dropped from the tree or updated?
The patch is identical it's the commit message that has changed.
Otherwise, I can drop it from a v3 re-spin.

^ permalink raw reply

* Re: [PATCH v2 3/3] Bluetooth: btmtksdio: call cancel_work_sync() outside of host lock scope
From: Sergey Senozhatsky @ 2026-06-17  3:41 UTC (permalink / raw)
  To: Sean Wang
  Cc: Sergey Senozhatsky, Marcel Holtmann, Luiz Augusto von Dentz,
	Mark-yw Chen, Sean Wang, Tomasz Figa, linux-bluetooth,
	linux-kernel, linux-arm-kernel, linux-mediatek, stable
In-Reply-To: <CAGp9LzqT4knwk9hONu43cGDr005Phs3xw6T+YexXa3X6JEBOpA@mail.gmail.com>

On (26/06/16 19:56), Sean Wang wrote:
> The patch looks good to me. Inspired by your patch,
> do you think should we add another patch to keep txrx_work out of the
> reset window by rejecting TX during reset,
> ignoring reset-time interrupts, and making queued workers exit early?

I honestly don't know, it's hard for to me judge as I'm not all that
familiar with the code.  To make things more complex, I don't think we
see any crashes on reset path.  My personal preference maybe would be
to keep things the way they are?

> Some code like:
> 
> --- a/drivers/bluetooth/btmtksdio.c
> +++ b/drivers/bluetooth/btmtksdio.c
> @@ -567,6 +567,8 @@ static void btmtksdio_txrx_work(struct work_struct *work)
>         pm_runtime_get_sync(bdev->dev);
> 
>         sdio_claim_host(bdev->func);
> +       if (test_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state))
> +               goto out;

A nit: I think you can test_bit() outside of host lock scope.
Other than that I'm afraid I cannot be of much help here.

>         /* Disable interrupt */
>         sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, NULL);
> @@ -628,6 +630,7 @@ static void btmtksdio_txrx_work(struct work_struct *work)
>             !test_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state))
>                 sdio_writel(bdev->func, C_INT_EN_SET, MTK_REG_CHLPCR, NULL);
> 
> +out:
>         sdio_release_host(bdev->func);
> 
>         pm_runtime_put_autosuspend(bdev->dev);
> @@ -646,6 +649,9 @@ static void btmtksdio_interrupt(struct sdio_func *func)
>         /* Disable interrupt */
>         sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, NULL);
> 
> +       if (test_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state))
> +               return;
> +
>         schedule_work(&bdev->txrx_work);
>  }
> 
> @@ -1250,6 +1256,9 @@ static int btmtksdio_send_frame(struct hci_dev
> *hdev, struct sk_buff *skb)
>  {
>         struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
> 
> +       if (test_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state))
> +               return -EBUSY;
> +
>         switch (hci_skb_pkt_type(skb)) {
>         case HCI_COMMAND_PKT:
>                 hdev->stat.cmd_tx++;

^ permalink raw reply

* Re: [PATCH v1] Bluetooth: btmtk: Add MT7928 support
From: Chris Lu (陸稚泓) @ 2026-06-17  2:16 UTC (permalink / raw)
  To: pmenzel@molgen.mpg.de
  Cc: Will-CY Lee (李政穎),
	Steve Lee (李視誠), luiz.dentz@gmail.com,
	marcel@holtmann.org, SS Wu (巫憲欣),
	linux-kernel@vger.kernel.org, johan.hedberg@gmail.com, Sean Wang,
	linux-bluetooth@vger.kernel.org,
	linux-mediatek@lists.infradead.org
In-Reply-To: <6b29b553-d703-448d-9275-62912a62e356@molgen.mpg.de>

Hi Paul,

On Tue, 2026-06-16 at 12:24 +0200, Paul Menzel wrote:
> 
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
> 
> 
> Dear Chris,
> 
> 
> Thank you for your patch.
> 
> Am 16.06.26 um 05:01 schrieb Chris Lu:
> > Add support for MT7928 (device ID 0x7935) which requires additional
> > firmware (CBMCU firmware) loading before Bluetooth firmware.
> 
> Please detail what CBMCU firmware is.

CBMCU is a new component on MT7928 to handle common part shared across
the combo chip (Wi-Fi/Bluetooth's subsystem), providing a better user
experience through improved coordination between subsystems.

> 
> > Implement two-phase CBMCU firmware download: Phase 1 loads
> > section with type 0x5 containing global descriptor,
> > section maps and signature data; Phase 2 loads remaining
> > firmware sections. Add retry mechanism for concurrent download
> > protection.
> 
> What is type 0x5? How big is the firmware, and how long does it take?
> 
> > After CBMCU firmware loads successfully, the driver continues
> > to load corresponding BT firmware based on device ID through
> > fallthrough to case 0x7922/0x7925.
> 
> Please add the new log message to the commit message.
> 
> > Signed-off-by: Chris Lu <chris.lu@mediatek.com>
> > ---
> >   drivers/bluetooth/btmtk.c | 342
> > +++++++++++++++++++++++++++++++++++++-
> >   drivers/bluetooth/btmtk.h |   3 +
> >   2 files changed, 344 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
> > index 02a96342e964..a68c67d1df4b 100644
> > --- a/drivers/bluetooth/btmtk.c
> > +++ b/drivers/bluetooth/btmtk.c
> > @@ -21,6 +21,7 @@
> >   #define MTK_FW_ROM_PATCH_SEC_MAP_SIZE       64
> >   #define MTK_SEC_MAP_COMMON_SIZE     12
> >   #define MTK_SEC_MAP_NEED_SEND_SIZE  52
> > +#define MTK_SEC_MAP_LENGTH_SIZE      4
> > 
> >   /* It is for mt79xx iso data transmission setting */
> >   #define MTK_ISO_THRESHOLD   264
> > @@ -120,6 +121,10 @@ void btmtk_fw_get_filename(char *buf, size_t
> > size, u32 dev_id, u32 fw_ver,
> >               snprintf(buf, size,
> >                       
> > "mediatek/mt%04x/BT_RAM_CODE_MT%04x_1_%x_hdr.bin",
> >                        dev_id & 0xffff, dev_id & 0xffff, (fw_ver &
> > 0xff) + 1);
> > +     else if (dev_id == 0x7935)
> > +             snprintf(buf, size,
> > +                     
> > "mediatek/mt7928/BT_RAM_CODE_MT%04x_1_1_hdr.bin",
> > +                      dev_id & 0xffff);
> >       else if (dev_id == 0x7961 && fw_flavor)
> >               snprintf(buf, size,
> >                        "mediatek/BT_RAM_CODE_MT%04x_1a_%x_hdr.bin",
> > @@ -734,6 +739,7 @@ static int btmtk_usb_hci_wmt_sync(struct
> > hci_dev *hdev,
> >                       status = BTMTK_WMT_ON_UNDONE;
> >               break;
> >       case BTMTK_WMT_PATCH_DWNLD:
> > +     case BTMTK_WMT_CBMCU_DWNLD:
> >               if (wmt_evt->whdr.flag == 2)
> >                       status = BTMTK_WMT_PATCH_DONE;
> >               else if (wmt_evt->whdr.flag == 1)
> > @@ -870,6 +876,329 @@ static u32 btmtk_usb_reset_done(struct
> > hci_dev *hdev)
> >       return val & MTK_BT_RST_DONE;
> >   }
> > 
> > +static int btmtk_cbmcu_patch_status(struct hci_dev *hdev,
> > +                                 wmt_cmd_sync_func_t wmt_cmd_sync,
> > +                                 u8 *patch_status)
> > +{
> > +     struct btmtk_hci_wmt_params wmt_params;
> > +     int status, err, retry = 20;
> > +
> > +     do {
> > +             wmt_params.op = BTMTK_WMT_CBMCU_DWNLD;
> > +             wmt_params.flag = 0xF0;
> > +             wmt_params.dlen = 0;
> > +             wmt_params.data = NULL;
> > +             wmt_params.status = &status;
> > +
> > +             err = wmt_cmd_sync(hdev, &wmt_params);
> > +             if (err < 0) {
> > +                     bt_dev_err(hdev, "Failed to query CBMCU patch
> > status (%d)", err);
> > +                     return err;
> > +             }
> > +
> > +             *patch_status = (u8)status;
> > +
> > +             if (*patch_status == BTMTK_WMT_PATCH_PROGRESS) {
> > +                     msleep(100);
> > +                     retry--;
> > +             } else {
> > +                     break;
> > +             }
> > +     } while (retry > 0);
> > +
> > +     return 0;
> > +}
> > +
> > +static int btmtk_query_cbmcu_section(struct hci_dev *hdev,
> > +                                  wmt_cmd_sync_func_t
> > wmt_cmd_sync,
> > +                                  u8 cbmcu_type,
> > +                                  const u8 *section_map,
> > +                                  u32 cert_len)
> > +{
> > +     struct btmtk_hci_wmt_params wmt_params;
> > +     u8 cmd[64];
> > +     int status, err;
> > +
> > +     cmd[0] = 0;
> > +     cmd[1] = cbmcu_type;
> > +
> > +     if (cbmcu_type == 0)
> > +             put_unaligned_le32(cert_len, &cmd[2]);
> > +     else
> > +             memcpy(&cmd[2], section_map,
> > MTK_SEC_MAP_NEED_SEND_SIZE);
> > +
> > +     wmt_params.op = BTMTK_WMT_CBMCU_DWNLD;
> > +     wmt_params.flag = 0;
> > +     wmt_params.dlen = cbmcu_type ?
> > +             MTK_SEC_MAP_NEED_SEND_SIZE + 2 :
> > +             MTK_SEC_MAP_LENGTH_SIZE + 2;
> > +     wmt_params.data = cmd;
> > +     wmt_params.status = &status;
> > +
> > +     err = wmt_cmd_sync(hdev, &wmt_params);
> > +     if (err < 0) {
> > +             bt_dev_err(hdev, "Failed to query CBMCU section
> > (%d)", err);
> > +             return err;
> > +     }
> > +
> > +     /* Query should return UNDONE status for successful section
> > query */
> > +     if (status != BTMTK_WMT_PATCH_UNDONE) {
> > +             bt_dev_err(hdev, "CBMCU section query status error
> > (%d)", status);
> > +             return -EIO;
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static int btmtk_download_cbmcu_section(struct hci_dev *hdev,
> > +                                     wmt_cmd_sync_func_t
> > wmt_cmd_sync,
> > +                                     const u8 *fw_data,
> > +                                     u32 dl_size)
> > +{
> > +     struct btmtk_hci_wmt_params wmt_params;
> > +     u32 sent_len, total_size = dl_size;
> > +     int err;
> > +
> > +     wmt_params.op = BTMTK_WMT_CBMCU_DWNLD;
> > +     wmt_params.status = NULL;
> > +
> > +     while (dl_size > 0) {
> > +             sent_len = min_t(u32, 250, dl_size);
> > +
> > +             if (dl_size == total_size)
> > +                     wmt_params.flag = 1;
> > +             else if (dl_size == sent_len)
> > +                     wmt_params.flag = 3;
> > +             else
> > +                     wmt_params.flag = 2;
> > +
> > +             wmt_params.dlen = sent_len;
> > +             wmt_params.data = fw_data;
> > +
> > +             err = wmt_cmd_sync(hdev, &wmt_params);
> > +             if (err < 0) {
> > +                     bt_dev_err(hdev, "Failed to send CBMCU
> > section data (%d)", err);
> > +                     return err;
> > +             }
> > +
> > +             dl_size -= sent_len;
> > +             fw_data += sent_len;
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static int btmtk_enable_cbmcu_patch(struct hci_dev *hdev,
> > +                                 wmt_cmd_sync_func_t wmt_cmd_sync)
> > +{
> > +     struct btmtk_hci_wmt_params wmt_params;
> > +     int err;
> > +
> > +     wmt_params.op = BTMTK_WMT_CBMCU_DWNLD;
> > +     wmt_params.flag = 0xF1;
> > +     wmt_params.dlen = 0;
> > +     wmt_params.data = NULL;
> > +     wmt_params.status = NULL;
> > +
> > +     err = wmt_cmd_sync(hdev, &wmt_params);
> > +     if (err < 0) {
> > +             bt_dev_err(hdev, "Failed to enable CBMCU patch (%d)",
> > err);
> > +             return err;
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static int btmtk_load_cbmcu_firmware(struct hci_dev *hdev,
> > +                                  const char *fwname,
> > +                                  wmt_cmd_sync_func_t
> > wmt_cmd_sync)
> > +{
> > +     struct btmtk_patch_header *hdr;
> > +     struct btmtk_global_desc *globaldesc;
> > +     struct btmtk_section_map *sectionmap;
> > +     const struct firmware *fw;
> > +     const u8 *fw_ptr;
> > +     u8 *cert_buf = NULL;
> > +     u32 section_num, section_offset, dl_size, cert_len;
> > +     int i, err;
> > +
> > +     err = request_firmware(&fw, fwname, &hdev->dev);
> > +     if (err < 0) {
> > +             bt_dev_err(hdev, "Failed to load CBMCU firmware file
> > (%d)", err);
> 
> Please add fwname to the error message.
> 
> > +             return err;
> > +     }
> > +
> > +     if (fw->size < MTK_FW_ROM_PATCH_HEADER_SIZE +
> > MTK_FW_ROM_PATCH_GD_SIZE) {
> > +             bt_dev_err(hdev, "CBMCU firmware too small (%zu
> > bytes)", fw->size);
> 
> Please add the limit to the error message.
> 
> > +             err = -EINVAL;
> > +             goto err_release_fw;
> > +     }
> > +
> > +     fw_ptr = fw->data;
> > +     hdr = (struct btmtk_patch_header *)fw_ptr;
> > +     globaldesc = (struct btmtk_global_desc *)(fw_ptr +
> > MTK_FW_ROM_PATCH_HEADER_SIZE);
> > +     section_num = le32_to_cpu(globaldesc->section_num);
> > +
> > +     if (fw->size < MTK_FW_ROM_PATCH_HEADER_SIZE +
> > MTK_FW_ROM_PATCH_GD_SIZE +
> > +                    (size_t)MTK_FW_ROM_PATCH_SEC_MAP_SIZE *
> > section_num) {
> > +             bt_dev_err(hdev, "CBMCU firmware truncated
> > (section_num=%u)", section_num);
> 
> Please log the values from the if condition.
> 
> > +             err = -EINVAL;
> > +             goto err_release_fw;
> > +     }
> > +
> > +     bt_dev_info(hdev, "CBMCU Version: 0x%04x%04x, Build Time:
> > %s",
> > +                 le16_to_cpu(hdr->hwver), le16_to_cpu(hdr->swver),
> > hdr->datetime);
> > +
> > +     /* Phase 1: Download section type 0x5 */
> 
> Please define a macro or enum for 0x5.
> 
> > +     for (i = 0; i < section_num; i++) {
> > +             sectionmap = (struct btmtk_section_map *)
> > +                     (fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE +
> > +                      MTK_FW_ROM_PATCH_GD_SIZE +
> > +                      MTK_FW_ROM_PATCH_SEC_MAP_SIZE * i);
> > +
> > +             /* Only process type 0x5 section in Phase 1 */
> > +             if ((le32_to_cpu(sectionmap->sectype) & 0xFFFF) !=
> > 0x5)
> > +                     continue;
> > +
> > +             section_offset = le32_to_cpu(sectionmap->secoffset);
> > +             dl_size = le32_to_cpu(sectionmap->secsize);
> > +
> > +             if (dl_size == 0)
> > +                     continue;
> > +
> > +             if (section_offset > fw->size ||
> > +                 dl_size > fw->size - section_offset) {
> > +                     bt_dev_err(hdev, "CBMCU Phase 1 section out
> > of bounds");
> > +                     err = -EINVAL;
> > +                     goto err_release_fw;
> > +             }
> > +
> > +             cert_len = MTK_FW_ROM_PATCH_GD_SIZE +
> > +                        MTK_FW_ROM_PATCH_SEC_MAP_SIZE *
> > section_num +
> > +                        dl_size;
> > +
> > +             /* Query cbmcu section */
> > +             err = btmtk_query_cbmcu_section(hdev, wmt_cmd_sync,
> > 0, NULL,
> > +                                             cert_len);
> > +             if (err < 0)
> > +                     goto err_release_fw;
> > +
> > +             cert_buf = kmalloc(cert_len, GFP_KERNEL);
> > +             if (!cert_buf) {
> > +                     err = -ENOMEM;
> > +                     goto err_release_fw;
> > +             }
> > +
> > +             /* Copy Global Descriptor + All Section Maps */
> > +             memcpy(cert_buf,
> > +                    fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE,
> > +                    MTK_FW_ROM_PATCH_GD_SIZE +
> > MTK_FW_ROM_PATCH_SEC_MAP_SIZE * section_num);
> > +
> > +             /* Copy Phase 1 section data */
> > +             memcpy(cert_buf + MTK_FW_ROM_PATCH_GD_SIZE +
> > +                    MTK_FW_ROM_PATCH_SEC_MAP_SIZE * section_num,
> > +                    fw_ptr + section_offset,
> > +                    dl_size);
> > +
> > +             /* Download Phase 1 section */
> > +             err = btmtk_download_cbmcu_section(hdev,
> > wmt_cmd_sync,
> > +                                                cert_buf,
> > cert_len);
> > +             kfree(cert_buf);
> > +             cert_buf = NULL;
> > +
> > +             if (err < 0) {
> > +                     bt_dev_err(hdev, "Failed to download CBMCU
> > Phase 1 section (%d)", err);
> > +                     goto err_release_fw;
> > +             }
> > +
> > +             break;
> > +     }
> > +
> > +     /* Phase 2: Download other sections (type != 0x5) */
> > +     for (i = 0; i < section_num; i++) {
> > +             sectionmap = (struct btmtk_section_map *)
> > +                     (fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE +
> > +                      MTK_FW_ROM_PATCH_GD_SIZE +
> > +                      MTK_FW_ROM_PATCH_SEC_MAP_SIZE * i);
> > +
> > +             /* Skip type 0x5 section in Phase 2 */
> > +             if ((le32_to_cpu(sectionmap->sectype) & 0xFFFF) ==
> > 0x5)
> > +                     continue;
> > +
> > +             section_offset = le32_to_cpu(sectionmap->secoffset);
> > +             dl_size = le32_to_cpu(sectionmap-
> > >bin_info_spec.dlsize);
> > +
> > +             if (dl_size == 0)
> > +                     continue;
> > +
> > +             if (section_offset > fw->size ||
> > +                 dl_size > fw->size - section_offset) {
> > +                     bt_dev_err(hdev, "CBMCU Phase 2 section %d
> > out of bounds", i);
> > +                     err = -EINVAL;
> > +                     goto err_release_fw;
> > +             }
> > +
> > +             /* Query cbmcu section */
> > +             err = btmtk_query_cbmcu_section(hdev, wmt_cmd_sync,
> > 1,
> > +                                             (u8 *)&sectionmap-
> > >bin_info_spec,
> > +                                             0);
> > +             if (err < 0)
> > +                     goto err_release_fw;
> > +
> > +             /* Download section data */
> > +             err = btmtk_download_cbmcu_section(hdev,
> > wmt_cmd_sync,
> > +                                                fw_ptr +
> > section_offset,
> > +                                                dl_size);
> > +             if (err < 0) {
> > +                     bt_dev_err(hdev, "Failed to download CBMCU
> > section %d (%d)", i, err);
> > +                     goto err_release_fw;
> > +             }
> > +     }
> > +
> > +     /* Wait for firmware activation */
> > +     usleep_range(100000, 120000);
> > +
> > +     bt_dev_info(hdev, "CBMCU firmware download completed");
> > +
> > +err_release_fw:
> > +     release_firmware(fw);
> > +     return err;
> > +}
> > +
> > +static int btmtk_setup_cbmcu_firmware(struct hci_dev *hdev,
> > +                                   wmt_cmd_sync_func_t
> > wmt_cmd_sync,
> > +                                   u32 dev_id)
> > +{
> > +     char cbmcu_fwname[64];
> > +     u8 patch_status;
> > +     int err;
> > +
> > +     err = btmtk_cbmcu_patch_status(hdev, wmt_cmd_sync,
> > &patch_status);
> > +     if (err < 0)
> > +             return err;
> > +
> > +     bt_dev_dbg(hdev, "CBMCU patch status: 0x%02x", patch_status);
> > +
> > +     if (patch_status != BTMTK_WMT_PATCH_UNDONE)
> > +             return 0;
> > +
> > +     snprintf(cbmcu_fwname, sizeof(cbmcu_fwname),
> > +              "mediatek/mt7928/CBMCU_CODE_MT%04x_1_1.bin",
> > +              dev_id & 0xffff);
> > +
> > +     err = btmtk_load_cbmcu_firmware(hdev, cbmcu_fwname,
> > wmt_cmd_sync);
> > +     if (err < 0) {
> > +             bt_dev_err(hdev, "Failed to download CBMCU firmware
> > (%d)", err);
> > +             return err;
> > +     }
> > +
> > +     err = btmtk_enable_cbmcu_patch(hdev, wmt_cmd_sync);
> > +     if (err < 0)
> > +             return err;
> > +
> > +     return 0;
> > +}
> > +
> >   int btmtk_usb_subsys_reset(struct hci_dev *hdev, u32 dev_id)
> >   {
> >       u32 val;
> > @@ -894,7 +1223,7 @@ int btmtk_usb_subsys_reset(struct hci_dev
> > *hdev, u32 dev_id)
> >               if (err < 0)
> >                       return err;
> >               msleep(100);
> > -     } else if (dev_id == 0x7925 || dev_id == 0x6639) {
> > +     } else if (dev_id == 0x7925 || dev_id == 0x6639 || dev_id ==
> > 0x7935) {
> >               err = btmtk_usb_uhw_reg_read(hdev,
> > MTK_BT_RESET_REG_CONNV3, &val);
> >               if (err < 0)
> >                       return err;
> > @@ -1379,6 +1708,15 @@ int btmtk_usb_setup(struct hci_dev *hdev)
> >       case 0x7668:
> >               fwname = FIRMWARE_MT7668;
> >               break;
> > +     case 0x7935:
> > +             /* Requires CBMCU firmware before BT firmware */
> > +             err = btmtk_setup_cbmcu_firmware(hdev,
> > btmtk_usb_hci_wmt_sync,
> > +                                              dev_id);
> > +             if (err < 0) {
> > +                     bt_dev_err(hdev, "Failed to set up CBMCU
> > firmware (%d)", err);
> > +                     return err;
> > +             }
> > +             fallthrough;
> >       case 0x7922:
> >       case 0x7925:
> >               /*
> > @@ -1596,3 +1934,5 @@ MODULE_FIRMWARE(FIRMWARE_MT7922);
> >   MODULE_FIRMWARE(FIRMWARE_MT7961);
> >   MODULE_FIRMWARE(FIRMWARE_MT7925);
> >   MODULE_FIRMWARE(FIRMWARE_MT7927);
> > +MODULE_FIRMWARE(FIRMWARE_MT7928);
> > +MODULE_FIRMWARE(FIRMWARE_MT7928_CBMCU);
> > diff --git a/drivers/bluetooth/btmtk.h b/drivers/bluetooth/btmtk.h
> > index c83c24897c95..6d3bf6b74a1d 100644
> > --- a/drivers/bluetooth/btmtk.h
> > +++ b/drivers/bluetooth/btmtk.h
> > @@ -9,6 +9,8 @@
> >   #define FIRMWARE_MT7961            
> > "mediatek/BT_RAM_CODE_MT7961_1_2_hdr.bin"
> >   #define FIRMWARE_MT7925            
> > "mediatek/mt7925/BT_RAM_CODE_MT7925_1_1_hdr.bin"
> >   #define FIRMWARE_MT7927            
> > "mediatek/mt7927/BT_RAM_CODE_MT6639_2_1_hdr.bin"
> > +#define FIRMWARE_MT7928             
> > "mediatek/mt7928/BT_RAM_CODE_MT7935_1_1_hdr.bin"
> > +#define FIRMWARE_MT7928_CBMCU       
> > "mediatek/mt7928/CBMCU_CODE_MT7935_1_1.bin"
> > 
> >   #define HCI_EV_WMT 0xe4
> >   #define HCI_WMT_MAX_EVENT_SIZE              64
> > @@ -54,6 +56,7 @@ enum {
> >       BTMTK_WMT_RST = 0x7,
> >       BTMTK_WMT_REGISTER = 0x8,
> >       BTMTK_WMT_SEMAPHORE = 0x17,
> > +     BTMTK_WMT_CBMCU_DWNLD = 0x58,
> >   };
> > 
> >   enum {
> 
> 
> Kind regards,
> 
> Paul

Thanks for the review, I'll revise the error message to be more
informative and replace the magic number with proper macro. A v2 will
be sent out shortly.

Chris Lu


^ permalink raw reply

* Re: [PATCH v1] Bluetooth: btmtk: Add MT7928 support
From: Chris Lu (陸稚泓) @ 2026-06-17  1:53 UTC (permalink / raw)
  To: luiz.dentz@gmail.com, johan.hedberg@gmail.com,
	marcel@holtmann.org, pav@iki.fi
  Cc: Sean Wang, linux-mediatek@lists.infradead.org,
	SS Wu (巫憲欣),
	Steve Lee (李視誠),
	Will-CY Lee (李政穎),
	linux-bluetooth@vger.kernel.org
In-Reply-To: <cb14eaa1c566ed30119ca66bff0484192f852e91.camel@iki.fi>

Hi Pauli,

On Tue, 2026-06-16 at 17:38 +0300, Pauli Virtanen wrote:
> 
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
> 
> 
> Hi,
> 
> ti, 2026-06-16 kello 11:01 +0800, Chris Lu kirjoitti:
> > Add support for MT7928 (device ID 0x7935) which requires additional
> > firmware (CBMCU firmware) loading before Bluetooth firmware.
> > 
> > Implement two-phase CBMCU firmware download: Phase 1 loads
> > section with type 0x5 containing global descriptor,
> > section maps and signature data; Phase 2 loads remaining
> > firmware sections. Add retry mechanism for concurrent download
> > protection.
> > 
> > After CBMCU firmware loads successfully, the driver continues
> > to load corresponding BT firmware based on device ID through
> > fallthrough to case 0x7922/0x7925.
> > 
> > Signed-off-by: Chris Lu <chris.lu@mediatek.com>
> > ---
> [clip]
> > diff --git a/drivers/bluetooth/btmtk.h b/drivers/bluetooth/btmtk.h
> > index c83c24897c95..6d3bf6b74a1d 100644
> > --- a/drivers/bluetooth/btmtk.h
> > +++ b/drivers/bluetooth/btmtk.h
> > @@ -9,6 +9,8 @@
> >  #define FIRMWARE_MT7961             
> > "mediatek/BT_RAM_CODE_MT7961_1_2_hdr.bin"
> >  #define FIRMWARE_MT7925             
> > "mediatek/mt7925/BT_RAM_CODE_MT7925_1_1_hdr.bin"
> >  #define FIRMWARE_MT7927             
> > "mediatek/mt7927/BT_RAM_CODE_MT6639_2_1_hdr.bin"
> > +#define FIRMWARE_MT7928             
> > "mediatek/mt7928/BT_RAM_CODE_MT7935_1_1_hdr.bin"
> > +#define FIRMWARE_MT7928_CBMCU       
> > "mediatek/mt7928/CBMCU_CODE_MT7935_1_1.bin"
> 
> Are these firmware names correct?
> 
> The above names for MT7928 say MT79**35** not MT7928?

The naming is intentional,
MT7928 is the external/marketing name, while MT7935 is MediaTek's
internal codename for same chip. The firmware filename follows and
generate with internal codename. Windows PC paired with MT7928 also
follows this rule.

> 
> > 
> >  #define HCI_EV_WMT 0xe4
> >  #define HCI_WMT_MAX_EVENT_SIZE               64
> > @@ -54,6 +56,7 @@ enum {
> >       BTMTK_WMT_RST = 0x7,
> >       BTMTK_WMT_REGISTER = 0x8,
> >       BTMTK_WMT_SEMAPHORE = 0x17,
> > +     BTMTK_WMT_CBMCU_DWNLD = 0x58,
> >  };
> > 
> >  enum {
> 
> --
> Pauli Virtanen

Chris Lu


^ permalink raw reply

* Re: [PATCH v2 3/3] Bluetooth: btmtksdio: call cancel_work_sync() outside of host lock scope
From: Sean Wang @ 2026-06-17  0:56 UTC (permalink / raw)
  To: Sergey Senozhatsky
  Cc: Marcel Holtmann, Luiz Augusto von Dentz, Mark-yw Chen, Sean Wang,
	Tomasz Figa, linux-bluetooth, linux-kernel, linux-arm-kernel,
	linux-mediatek, stable
In-Reply-To: <20260616111224.152140-4-senozhatsky@chromium.org>

Hi,

On Tue, Jun 16, 2026 at 6:15 AM Sergey Senozhatsky
<senozhatsky@chromium.org> wrote:
>
> cancel_work_sync() should be called outside of host lock scope
> in order to avoid circular locking scenario:
>
> CPU0                                    CPU1
>                                         close()/reset()
>                                         sdio_claim_host()
> txrx_work
>   sdio_claim_host() // sleeps
>                                         cancel_work_sync() // sleeps
>
> In addition, when txrx_work() runs concurrently with close()/reset()
> it better not to re-enable interrupts by testing for BTMTKSDIO_FUNC_ENABLED
> and not BTMTKSDIO_HW_RESET_ACTIVE before C_INT_EN_SET write.  However,
> btmtksdio_close() clears the BTMTKSDIO_FUNC_ENABLED too late (after
> cancel_work_sync() call).  Move BTMTKSDIO_FUNC_ENABLED bit-clear earlier
> so that txrx_work can see concurrent close().
>
> Fixes: 26270bc189ea4 ("Bluetooth: btmtksdio: move interrupt service to work")
> Cc: stable@vger.kernel.org
> Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
> ---
>  drivers/bluetooth/btmtksdio.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c
> index d8c8d2857527..207d04cc2282 100644
> --- a/drivers/bluetooth/btmtksdio.c
> +++ b/drivers/bluetooth/btmtksdio.c
> @@ -625,7 +625,9 @@ static void btmtksdio_txrx_work(struct work_struct *work)
>         } while (int_status && time_is_after_jiffies(txrx_timeout));
>
>         /* Enable interrupt */
> -       if (bdev->func->irq_handler)
> +       if (bdev->func->irq_handler &&
> +           test_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state) &&
> +           !test_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state))
>                 sdio_writel(bdev->func, C_INT_EN_SET, MTK_REG_CHLPCR, NULL);
>
>         sdio_release_host(bdev->func);
> @@ -741,6 +743,8 @@ static int btmtksdio_close(struct hci_dev *hdev)
>         if (!test_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state))
>                 return 0;
>
> +       clear_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state);
> +
>         sdio_claim_host(bdev->func);
>
>         /* Disable interrupt */
> @@ -748,11 +752,12 @@ static int btmtksdio_close(struct hci_dev *hdev)
>
>         sdio_release_irq(bdev->func);
>
> +       sdio_release_host(bdev->func);
>         cancel_work_sync(&bdev->txrx_work);
> +       sdio_claim_host(bdev->func);
>
>         btmtksdio_fw_pmctrl(bdev);
>
> -       clear_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state);
>         sdio_disable_func(bdev->func);
>
>         sdio_release_host(bdev->func);
> @@ -1295,7 +1300,10 @@ static void btmtksdio_reset(struct hci_dev *hdev)
>
>         sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, NULL);
>         skb_queue_purge(&bdev->txq);
> +
> +       sdio_release_host(bdev->func);
>         cancel_work_sync(&bdev->txrx_work);
> +       sdio_claim_host(bdev->func);
>
>         gpiod_set_value_cansleep(bdev->reset, 1);
>         msleep(100);

The patch looks good to me. Inspired by your patch,
do you think should we add another patch to keep txrx_work out of the
reset window by rejecting TX during reset,
ignoring reset-time interrupts, and making queued workers exit early?

Some code like:

--- a/drivers/bluetooth/btmtksdio.c
+++ b/drivers/bluetooth/btmtksdio.c
@@ -567,6 +567,8 @@ static void btmtksdio_txrx_work(struct work_struct *work)
        pm_runtime_get_sync(bdev->dev);

        sdio_claim_host(bdev->func);
+       if (test_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state))
+               goto out;

        /* Disable interrupt */
        sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, NULL);
@@ -628,6 +630,7 @@ static void btmtksdio_txrx_work(struct work_struct *work)
            !test_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state))
                sdio_writel(bdev->func, C_INT_EN_SET, MTK_REG_CHLPCR, NULL);

+out:
        sdio_release_host(bdev->func);

        pm_runtime_put_autosuspend(bdev->dev);
@@ -646,6 +649,9 @@ static void btmtksdio_interrupt(struct sdio_func *func)
        /* Disable interrupt */
        sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, NULL);

+       if (test_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state))
+               return;
+
        schedule_work(&bdev->txrx_work);
 }

@@ -1250,6 +1256,9 @@ static int btmtksdio_send_frame(struct hci_dev
*hdev, struct sk_buff *skb)
 {
        struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);

+       if (test_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state))
+               return -EBUSY;
+
        switch (hci_skb_pkt_type(skb)) {
        case HCI_COMMAND_PKT:
                hdev->stat.cmd_tx++;

> --
> 2.54.0.1136.gdb2ca164c4-goog
>
>

^ permalink raw reply

* Re: [PATCH v2 1/3] Bluetooth: btmtksdio: correct btmtksdio_txrx_work() loop timeout check
From: Sean Wang @ 2026-06-17  0:40 UTC (permalink / raw)
  To: Sergey Senozhatsky
  Cc: Marcel Holtmann, Luiz Augusto von Dentz, Mark-yw Chen, Sean Wang,
	Tomasz Figa, linux-bluetooth, linux-kernel, linux-arm-kernel,
	linux-mediatek, stable
In-Reply-To: <20260616111224.152140-2-senozhatsky@chromium.org>

Hi,

On Tue, Jun 16, 2026 at 6:15 AM Sergey Senozhatsky
<senozhatsky@chromium.org> wrote:
>
> The btmtksdio_txrx_work() loop is expected to be terminated if running
> for longer than 5*HZ.  However the timeout check is reversed:
> time_is_before_jiffies(old_jiffies + 5*HZ) evaluates to true when
> old_jiffies + 5*HZ is in the past i.e. when a timeout has occurred.
> Using OR with time_is_before_jiffies(txrx_timeout) means that:
> - before the 5-second timeout: the condition is `int_status || false`,
>   so it loops as long as there are pending interrupts.
> - after the 5-second timeout: the condition becomes `int_status || true`,
>   which is always true.
>
> Fix loop termination condition to actually enforce a 5*HZ timeout.
>
> Fixes: 26270bc189ea4 ("Bluetooth: btmtksdio: move interrupt service to work")
> Cc: stable@vger.kernel.org
> Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
> ---
>  drivers/bluetooth/btmtksdio.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c
> index 5b0fab7b89b5..c6f80c419e90 100644
> --- a/drivers/bluetooth/btmtksdio.c
> +++ b/drivers/bluetooth/btmtksdio.c
> @@ -620,7 +620,7 @@ static void btmtksdio_txrx_work(struct work_struct *work)
>                         if (btmtksdio_rx_packet(bdev, rx_size) < 0)
>                                 bdev->hdev->stat.err_rx++;
>                 }
> -       } while (int_status || time_is_before_jiffies(txrx_timeout));
> +       } while (int_status && time_is_after_jiffies(txrx_timeout));
>

This patch has already been merged, so I think the series should be
respun based on the latest code.

>         /* Enable interrupt */
>         if (bdev->func->irq_handler)
> --
> 2.54.0.1136.gdb2ca164c4-goog
>
>

^ permalink raw reply

* [bluetooth-next:master] BUILD SUCCESS cb20f6afc25b2b54c0fec61b45ac0ec9eb875d59
From: kernel test robot @ 2026-06-17  0:30 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git master
branch HEAD: cb20f6afc25b2b54c0fec61b45ac0ec9eb875d59  Bluetooth: MGMT: Fix UAF of hci_conn_params in add_device_complete

elapsed time: 986m

configs tested: 289
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

tested configs:
alpha                             allnoconfig    gcc-16.1.0
alpha                            allyesconfig    gcc-16.1.0
alpha                               defconfig    gcc-16.1.0
arc                              allmodconfig    clang-23
arc                              allmodconfig    gcc-16.1.0
arc                               allnoconfig    gcc-16.1.0
arc                              allyesconfig    clang-23
arc                                 defconfig    gcc-16.1.0
arc                   randconfig-001-20260616    gcc-9.5.0
arc                   randconfig-001-20260617    gcc-16.1.0
arc                   randconfig-002-20260616    gcc-9.5.0
arc                   randconfig-002-20260617    gcc-16.1.0
arm                               allnoconfig    clang-23
arm                               allnoconfig    gcc-16.1.0
arm                              allyesconfig    clang-23
arm                              allyesconfig    gcc-16.1.0
arm                                 defconfig    gcc-16.1.0
arm                         lpc18xx_defconfig    clang-23
arm                   randconfig-001-20260616    gcc-9.5.0
arm                   randconfig-001-20260617    gcc-16.1.0
arm                   randconfig-002-20260616    gcc-9.5.0
arm                   randconfig-002-20260617    gcc-16.1.0
arm                   randconfig-003-20260616    gcc-9.5.0
arm                   randconfig-003-20260617    gcc-16.1.0
arm                   randconfig-004-20260616    gcc-9.5.0
arm                   randconfig-004-20260617    gcc-16.1.0
arm64                            allmodconfig    clang-23
arm64                             allnoconfig    gcc-16.1.0
arm64                               defconfig    gcc-16.1.0
arm64                 randconfig-001-20260617    gcc-12.5.0
arm64                 randconfig-002-20260617    gcc-12.5.0
arm64                 randconfig-003-20260617    gcc-12.5.0
arm64                 randconfig-004-20260617    gcc-12.5.0
csky                             allmodconfig    gcc-16.1.0
csky                              allnoconfig    gcc-16.1.0
csky                                defconfig    gcc-16.1.0
csky                  randconfig-001-20260617    gcc-12.5.0
csky                  randconfig-002-20260617    gcc-12.5.0
hexagon                          allmodconfig    clang-23
hexagon                          allmodconfig    gcc-16.1.0
hexagon                           allnoconfig    clang-23
hexagon                           allnoconfig    gcc-16.1.0
hexagon                             defconfig    gcc-16.1.0
hexagon               randconfig-001-20260616    clang-23
hexagon               randconfig-001-20260617    clang-17
hexagon               randconfig-002-20260616    clang-23
hexagon               randconfig-002-20260617    clang-17
i386                             allmodconfig    clang-22
i386                             allmodconfig    gcc-14
i386                              allnoconfig    gcc-14
i386                              allnoconfig    gcc-16.1.0
i386                             allyesconfig    clang-22
i386        buildonly-randconfig-001-20260616    gcc-14
i386        buildonly-randconfig-001-20260617    gcc-14
i386        buildonly-randconfig-002-20260616    clang-22
i386        buildonly-randconfig-002-20260617    gcc-14
i386        buildonly-randconfig-003-20260616    gcc-14
i386        buildonly-randconfig-003-20260617    gcc-14
i386        buildonly-randconfig-004-20260616    gcc-14
i386        buildonly-randconfig-004-20260617    gcc-14
i386        buildonly-randconfig-005-20260616    gcc-14
i386        buildonly-randconfig-005-20260617    gcc-14
i386        buildonly-randconfig-006-20260616    gcc-14
i386        buildonly-randconfig-006-20260617    gcc-14
i386                                defconfig    gcc-16.1.0
i386                  randconfig-001-20260616    gcc-14
i386                  randconfig-001-20260617    gcc-13
i386                  randconfig-002-20260616    gcc-14
i386                  randconfig-002-20260617    gcc-13
i386                  randconfig-003-20260616    gcc-14
i386                  randconfig-003-20260617    gcc-13
i386                  randconfig-004-20260616    gcc-14
i386                  randconfig-004-20260617    gcc-13
i386                  randconfig-005-20260616    gcc-14
i386                  randconfig-005-20260617    gcc-13
i386                  randconfig-006-20260616    gcc-14
i386                  randconfig-006-20260617    gcc-13
i386                  randconfig-007-20260616    gcc-14
i386                  randconfig-007-20260617    gcc-13
i386                  randconfig-011-20260616    gcc-14
i386                  randconfig-011-20260617    clang-22
i386                  randconfig-012-20260616    gcc-14
i386                  randconfig-012-20260617    clang-22
i386                  randconfig-013-20260616    gcc-14
i386                  randconfig-013-20260617    clang-22
i386                  randconfig-014-20260616    gcc-14
i386                  randconfig-014-20260617    clang-22
i386                  randconfig-015-20260616    gcc-14
i386                  randconfig-015-20260617    clang-22
i386                  randconfig-016-20260616    clang-22
i386                  randconfig-016-20260617    clang-22
i386                  randconfig-017-20260616    clang-22
i386                  randconfig-017-20260617    clang-22
loongarch                        allmodconfig    clang-23
loongarch                         allnoconfig    clang-20
loongarch                         allnoconfig    gcc-16.1.0
loongarch                           defconfig    clang-23
loongarch             randconfig-001-20260616    clang-23
loongarch             randconfig-001-20260617    clang-17
loongarch             randconfig-002-20260616    clang-23
loongarch             randconfig-002-20260617    clang-17
m68k                             allmodconfig    gcc-16.1.0
m68k                              allnoconfig    gcc-16.1.0
m68k                             allyesconfig    clang-23
m68k                             allyesconfig    gcc-16.1.0
m68k                                defconfig    clang-23
m68k                                defconfig    gcc-16.1.0
m68k                          hp300_defconfig    gcc-16.1.0
microblaze                        allnoconfig    gcc-16.1.0
microblaze                       allyesconfig    gcc-16.1.0
microblaze                          defconfig    clang-23
microblaze                          defconfig    gcc-16.1.0
mips                             allmodconfig    gcc-16.1.0
mips                              allnoconfig    gcc-16.1.0
mips                             allyesconfig    gcc-16.1.0
mips                      malta_kvm_defconfig    gcc-16.1.0
nios2                            allmodconfig    clang-20
nios2                            allmodconfig    gcc-11.5.0
nios2                             allnoconfig    clang-23
nios2                               defconfig    clang-23
nios2                               defconfig    gcc-11.5.0
nios2                 randconfig-001-20260616    clang-23
nios2                 randconfig-001-20260617    clang-17
nios2                 randconfig-002-20260616    clang-23
nios2                 randconfig-002-20260617    clang-17
openrisc                         allmodconfig    clang-20
openrisc                         allmodconfig    gcc-16.1.0
openrisc                          allnoconfig    clang-23
openrisc                            defconfig    gcc-16.1.0
parisc                           allmodconfig    gcc-16.1.0
parisc                            allnoconfig    clang-23
parisc                           allyesconfig    clang-17
parisc                           allyesconfig    gcc-16.1.0
parisc                              defconfig    gcc-16.1.0
parisc                randconfig-001-20260617    gcc-15.2.0
parisc                randconfig-002-20260617    gcc-15.2.0
parisc64                            defconfig    clang-23
parisc64                            defconfig    gcc-16.1.0
powerpc                          allmodconfig    gcc-16.1.0
powerpc                           allnoconfig    clang-23
powerpc               randconfig-001-20260617    gcc-15.2.0
powerpc               randconfig-002-20260617    gcc-15.2.0
powerpc64             randconfig-001-20260617    gcc-15.2.0
powerpc64             randconfig-002-20260617    gcc-15.2.0
riscv                            allmodconfig    clang-23
riscv                             allnoconfig    clang-23
riscv                            allyesconfig    clang-23
riscv                               defconfig    gcc-16.1.0
riscv                          randconfig-001    gcc-13.4.0
riscv                 randconfig-001-20260616    gcc-9.5.0
riscv                 randconfig-001-20260617    gcc-16.1.0
riscv                          randconfig-002    clang-23
riscv                 randconfig-002-20260616    clang-23
riscv                 randconfig-002-20260617    gcc-16.1.0
s390                             allmodconfig    clang-17
s390                              allnoconfig    clang-23
s390                             allyesconfig    gcc-16.1.0
s390                                defconfig    gcc-16.1.0
s390                           randconfig-001    gcc-15.2.0
s390                  randconfig-001-20260616    clang-23
s390                  randconfig-001-20260617    gcc-16.1.0
s390                           randconfig-002    clang-18
s390                  randconfig-002-20260616    clang-18
s390                  randconfig-002-20260617    gcc-16.1.0
sh                               allmodconfig    gcc-16.1.0
sh                                allnoconfig    clang-23
sh                               allyesconfig    clang-17
sh                               allyesconfig    gcc-16.1.0
sh                                  defconfig    gcc-14
sh                             randconfig-001    gcc-14.3.0
sh                    randconfig-001-20260616    gcc-16.1.0
sh                    randconfig-001-20260617    gcc-16.1.0
sh                             randconfig-002    gcc-9.5.0
sh                    randconfig-002-20260616    gcc-13.4.0
sh                    randconfig-002-20260617    gcc-16.1.0
sparc                             allnoconfig    clang-23
sparc                               defconfig    gcc-16.1.0
sparc                 randconfig-001-20260616    gcc-8.5.0
sparc                 randconfig-001-20260617    gcc-16.1.0
sparc                 randconfig-002-20260616    gcc-8.5.0
sparc                 randconfig-002-20260617    gcc-16.1.0
sparc64                          allmodconfig    clang-20
sparc64                             defconfig    gcc-14
sparc64               randconfig-001-20260616    gcc-8.5.0
sparc64               randconfig-001-20260617    gcc-16.1.0
sparc64               randconfig-002-20260616    gcc-8.5.0
sparc64               randconfig-002-20260617    gcc-16.1.0
um                               allmodconfig    clang-17
um                                allnoconfig    clang-23
um                               allyesconfig    gcc-14
um                               allyesconfig    gcc-16.1.0
um                                  defconfig    gcc-14
um                             i386_defconfig    gcc-14
um                    randconfig-001-20260616    gcc-8.5.0
um                    randconfig-001-20260617    gcc-16.1.0
um                    randconfig-002-20260616    gcc-8.5.0
um                    randconfig-002-20260617    gcc-16.1.0
um                           x86_64_defconfig    gcc-14
x86_64                           allmodconfig    clang-22
x86_64                            allnoconfig    clang-23
x86_64                           allyesconfig    clang-22
x86_64      buildonly-randconfig-001-20260616    gcc-14
x86_64      buildonly-randconfig-001-20260617    clang-22
x86_64      buildonly-randconfig-002-20260616    gcc-14
x86_64      buildonly-randconfig-002-20260617    clang-22
x86_64      buildonly-randconfig-003-20260616    gcc-12
x86_64      buildonly-randconfig-003-20260617    clang-22
x86_64      buildonly-randconfig-004-20260616    gcc-12
x86_64      buildonly-randconfig-004-20260617    clang-22
x86_64      buildonly-randconfig-005-20260616    gcc-14
x86_64      buildonly-randconfig-005-20260617    clang-22
x86_64      buildonly-randconfig-006-20260616    gcc-14
x86_64      buildonly-randconfig-006-20260617    clang-22
x86_64                              defconfig    gcc-14
x86_64                                  kexec    clang-22
x86_64                randconfig-001-20260617    clang-22
x86_64                randconfig-002-20260617    clang-22
x86_64                randconfig-003-20260617    clang-22
x86_64                randconfig-004-20260617    clang-22
x86_64                randconfig-005-20260617    clang-22
x86_64                randconfig-006-20260617    clang-22
x86_64                         randconfig-011    clang-22
x86_64                         randconfig-011    gcc-14
x86_64                randconfig-011-20260616    clang-22
x86_64                randconfig-011-20260616    gcc-14
x86_64                randconfig-011-20260617    clang-22
x86_64                         randconfig-012    clang-22
x86_64                         randconfig-012    gcc-14
x86_64                randconfig-012-20260616    clang-22
x86_64                randconfig-012-20260616    gcc-14
x86_64                randconfig-012-20260617    clang-22
x86_64                         randconfig-013    clang-22
x86_64                randconfig-013-20260616    clang-22
x86_64                randconfig-013-20260617    clang-22
x86_64                         randconfig-014    clang-22
x86_64                         randconfig-014    gcc-14
x86_64                randconfig-014-20260616    clang-22
x86_64                randconfig-014-20260617    clang-22
x86_64                         randconfig-015    clang-22
x86_64                         randconfig-015    gcc-14
x86_64                randconfig-015-20260616    clang-22
x86_64                randconfig-015-20260617    clang-22
x86_64                         randconfig-016    clang-22
x86_64                randconfig-016-20260616    clang-22
x86_64                randconfig-016-20260616    gcc-14
x86_64                randconfig-016-20260617    clang-22
x86_64                         randconfig-071    gcc-13
x86_64                         randconfig-071    gcc-14
x86_64                randconfig-071-20260616    gcc-13
x86_64                randconfig-071-20260616    gcc-14
x86_64                randconfig-071-20260617    clang-22
x86_64                         randconfig-072    gcc-13
x86_64                         randconfig-072    gcc-14
x86_64                randconfig-072-20260616    clang-22
x86_64                randconfig-072-20260616    gcc-13
x86_64                randconfig-072-20260617    clang-22
x86_64                         randconfig-073    clang-22
x86_64                         randconfig-073    gcc-13
x86_64                randconfig-073-20260616    gcc-13
x86_64                randconfig-073-20260616    gcc-14
x86_64                randconfig-073-20260617    clang-22
x86_64                         randconfig-074    gcc-13
x86_64                         randconfig-074    gcc-14
x86_64                randconfig-074-20260616    gcc-13
x86_64                randconfig-074-20260616    gcc-14
x86_64                randconfig-074-20260617    clang-22
x86_64                         randconfig-075    gcc-13
x86_64                randconfig-075-20260616    gcc-12
x86_64                randconfig-075-20260616    gcc-13
x86_64                randconfig-075-20260617    clang-22
x86_64                         randconfig-076    clang-22
x86_64                         randconfig-076    gcc-13
x86_64                randconfig-076-20260616    gcc-13
x86_64                randconfig-076-20260616    gcc-14
x86_64                randconfig-076-20260617    clang-22
x86_64                               rhel-9.4    clang-22
x86_64                           rhel-9.4-bpf    gcc-14
x86_64                          rhel-9.4-func    clang-22
x86_64                    rhel-9.4-kselftests    clang-22
x86_64                         rhel-9.4-kunit    gcc-14
x86_64                           rhel-9.4-ltp    gcc-14
x86_64                          rhel-9.4-rust    clang-22
xtensa                            allnoconfig    clang-23
xtensa                           allyesconfig    clang-20
xtensa                           allyesconfig    gcc-16.1.0
xtensa                randconfig-001-20260616    gcc-8.5.0
xtensa                randconfig-001-20260617    gcc-16.1.0
xtensa                randconfig-002-20260616    gcc-8.5.0
xtensa                randconfig-002-20260617    gcc-16.1.0

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* [Bug 221660] New: btmtk (MT7921K / RZ608): BR/EDR outgoing connection always fails with Page Timeout (0x04); scan/receive works, same device pairs fine on Windows
From: bugzilla-daemon @ 2026-06-16 22:39 UTC (permalink / raw)
  To: linux-bluetooth

https://bugzilla.kernel.org/show_bug.cgi?id=221660

            Bug ID: 221660
           Summary: btmtk (MT7921K / RZ608): BR/EDR outgoing connection
                    always fails with Page Timeout (0x04); scan/receive
                    works, same device pairs fine on Windows
           Product: Drivers
           Version: 2.5
    Kernel Version: 7.0.12-arch1-1
          Hardware: AMD
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P3
         Component: Bluetooth
          Assignee: linux-bluetooth@vger.kernel.org
          Reporter: bynxmusic@gmail.com
        Regression: No

Created attachment 310333
  --> https://bugzilla.kernel.org/attachment.cgi?id=310333&action=edit
btmon HCI trace (binary + decoded) of the Page Timeout + system info

btmtk (MT7921K / RZ608): every BR/EDR outgoing connection fails with Page
Timeout (0x04). Scan/receive works, and the same device pairs fine on Windows.

HARDWARE
  WiFi+BT combo: MediaTek MT7921K (RZ608) Wi-Fi 6E, PCI 14c3:0608, driver
mt7921e
  Bluetooth function: USB 0e8d:0608 (MediaTek Inc. Wireless_Device), btusb +
btmtk
  Motherboard onboard radio, AMD desktop platform

SOFTWARE
  Kernel: 7.0.12-arch1-1 (x86_64), Arch Linux (rolling)
  linux-firmware: 20260519-1 ; linux-firmware-mediatek: 20260519-1
  BlueZ: 5.86
  BT controller firmware: HW/SW Version 0x008a008a, Build Time 20260224111243
  BT firmware blob loads OK: mediatek/BT_RAM_CODE_MT7961_1_2_hdr.bin

WHAT WORKS
  Controller initializes cleanly every boot ("hci0: Device setup in ~160000
  usecs", AOSP extensions v1.00). Inquiry/scan works: remote devices (a
  Skullcandy Crusher Evo headset and a Samsung TV) are reliably discovered with
  RSSI, so the RX path is fine.

THE BUG
  Every outgoing connection (page) to any BR/EDR device times out. HCI Create
  Connection is issued and accepted (Command Status: Success), but roughly 7.7
s
  later the controller returns Connect Complete with Status: Page Timeout
(0x04).
  BlueZ reports org.bluez.Error.ConnectionAttemptFailed. The remote device
never
  registers a connection. The same headset on the same PC pairs and works
  perfectly under Windows, so this is not dead hardware or a peripheral issue;
  it is the btmtk/MT7921K outgoing-connection path on Linux.

KEY HCI TRACE (btmon), captured with the WiFi driver (mt7921e) UNLOADED, i.e.
WiFi/BT coexistence ruled out:

  < HCI Command: Create Connection (0x01|0x0005) plen 13   #9  [hci0] 14.208614
          Address: 88:08:94:13:8F:94 (Skullcandy)
          Packet type: 0xcc18 (DM1/DH1/DM3/DH3 ...)
  > HCI Event: Command Status (0x0f) plen 4               #10 [hci0] 14.209664
        Create Connection (0x01|0x0005) ncmd 1
          Status: Success (0x00)
  > HCI Event: Connect Complete (0x03) plen 11            #11 [hci0] 21.899975
          Status: Page Timeout (0x04)
          Handle: 0
          Address: 88:08:94:13:8F:94 (Skullcandy)
          Link type: ACL (0x01)

  Also seen intermittently in dmesg during attempts:
  Bluetooth: hci0: ACL packet for unknown connection handle 3837

STEPS TO REPRODUCE
  1. Boot with MT7921K onboard Bluetooth.
  2. Put any BR/EDR device (e.g. a freshly factory-reset BT headset) in pairing
     mode.
  3. In bluetoothctl: scan on (device IS discovered), then pair <MAC>.
  4. Pairing fails with org.bluez.Error.ConnectionAttemptFailed; btmon shows
     Connect Complete: Page Timeout (0x04).

EXPECTED vs ACTUAL
  Expected: Create Connection succeeds and pairing/bonding proceeds (as on
  Windows).
  Actual: every Create Connection ends in Page Timeout; no outgoing connection
  ever completes.

ALREADY RULED OUT
  - USB autosuspend: disabled via options btusb enable_autosuspend=0 (confirmed
    power/control=on). No change.
  - WiFi/BT coexistence: Page Timeout persists even with mt7921e fully unloaded
    (modprobe -r mt7921e); the trace above is from that state. Also tested with
    rfkill block wifi. No change.
  - LE vs BR/EDR bearer: tested with and without Experimental, and with
    ControllerMode = bredr. No change.
  - Stale/half state: reproduced after a fresh cold boot (controller not
wedged).
  - Remote device: Crusher Evo factory-reset; nothing else paired to it
    (phone/TV BT off); works on Windows.

ATTACHMENTS
  - bt-hci-trace.btsnoop: full binary btmon capture of one failed pairing.
  - bt-bugreport.txt: full system diagnostic bundle (versions, lspci/lsusb,
dmesg).

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are the assignee for the bug.

^ permalink raw reply

* RE: Bluetooth: btnxpuart: Fix out-of-bounds firmware read in nxp_recv_fw_req_v3()
From: bluez.test.bot @ 2026-06-16 19:25 UTC (permalink / raw)
  To: linux-bluetooth, maoyixie.tju
In-Reply-To: <178162441367.2434858.9590661629618538235@maoyixie.com>

[-- Attachment #1: Type: text/plain, Size: 2563 bytes --]

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1112441

---Test result---

Test Summary:
CheckPatch                    FAIL      0.44 seconds
VerifyFixes                   PASS      0.08 seconds
VerifySignedoff               PASS      0.08 seconds
GitLint                       FAIL      0.21 seconds
SubjectPrefix                 PASS      0.07 seconds
BuildKernel                   PASS      16.91 seconds
CheckAllWarning               PASS      20.08 seconds
CheckSparse                   PASS      18.00 seconds
BuildKernel32                 PASS      16.75 seconds
CheckKernelLLVM               SKIP      0.00 seconds
TestRunnerSetup               PASS      329.06 seconds
IncrementalBuild              PASS      16.02 seconds

Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script
Output:
Bluetooth: btnxpuart: Fix out-of-bounds firmware read in nxp_recv_fw_req_v3()
WARNING: Prefer a maximum 75 chars per line (possible unwrapped commit description?)
#108: 
Nothing checks that fw_dnld_v3_offset + len stays within nxpdev->fw->size, so a

total: 0 errors, 1 warnings, 12 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
      mechanically convert to the typical style using --fix or --fix-inplace.

/github/workspace/src/patch/14631861.patch has style problems, please review.

NOTE: Ignored message types: UNKNOWN_COMMIT_ID

NOTE: If any of the errors are false positives, please report
      them to the maintainer, see CHECKPATCH in MAINTAINERS.


##############################
Test: GitLint - FAIL
Desc: Run gitlint
Output:
Bluetooth: btnxpuart: Fix out-of-bounds firmware read in nxp_recv_fw_req_v3()

7: B3 Line contains hard tab characters (\t): "	nxpdev->fw_dnld_v3_offset = offset - nxpdev->fw_v3_offset_correction;"
8: B3 Line contains hard tab characters (\t): "	serdev_device_write_buf(nxpdev->serdev, nxpdev->fw->data +"
9: B3 Line contains hard tab characters (\t): "				nxpdev->fw_dnld_v3_offset, len);"
26: B1 Line exceeds max length (81>80): "confirmed the bug and asked me to send it. The Suggested-by is for his suggestion"
##############################
Test: CheckKernelLLVM - SKIP
Desc: Build kernel with LLVM + context analysis
Output:
Clang not found


https://github.com/bluez/bluetooth-next/pull/321

---
Regards,
Linux Bluetooth


^ permalink raw reply

* [bluez/bluez] 4f34c4: shared/gatt: Fix gatt-db buffer overflow for clone...
From: fdanis-oss @ 2026-06-16 17:23 UTC (permalink / raw)
  To: linux-bluetooth

  Branch: refs/heads/1112321
  Home:   https://github.com/bluez/bluez
  Commit: 4f34c4155f8ff852ab543ba8e4ca85fcc600530b
      https://github.com/bluez/bluez/commit/4f34c4155f8ff852ab543ba8e4ca85fcc600530b
  Author: Frédéric Danis <frederic.danis@collabora.com>
  Date:   2026-06-16 (Tue, 16 Jun 2026)

  Changed paths:
    M src/shared/gatt-db.c

  Log Message:
  -----------
  shared/gatt: Fix gatt-db buffer overflow for cloned db

On notify_service_changed() timeout, db_hash_update() is called but
for cloned db the last-handle has not been copied and only one slot is
allocated, ending in buffer overflow:

==288975==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x5020000ac220 at pc 0x55f8b7e551bf bp 0x7ffcd6e9ddf0 sp 0x7ffcd6e9dde0
WRITE of size 8 at 0x5020000ac220 thread T0
    #0 0x55f8b7e551be in gen_hash_m src/shared/gatt-db.c:415
    #1 0x55f8b7e5d817 in gatt_db_service_foreach src/shared/gatt-db.c:1744
    #2 0x55f8b7e5d817 in gatt_db_service_foreach src/shared/gatt-db.c:1722
    #3 0x55f8b7e60c6c in foreach_service_in_range src/shared/gatt-db.c:1633
    #4 0x55f8b7e60c6c in foreach_in_range src/shared/gatt-db.c:1656
    #5 0x55f8b7dde002 in queue_foreach src/shared/queue.c:207
    #6 0x55f8b7e5c435 in gatt_db_foreach_service_in_range src/shared/gatt-db.c:1698
    #7 0x55f8b7e5c87c in db_hash_update src/shared/gatt-db.c:442
    #8 0x55f8b7f15283 in timeout_callback src/shared/timeout-glib.c:25
    #9 0x7fc1845154f1  (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x5e4f1) (BuildId: 116e142b9b52c8a4dfd403e759e71ab8f95d8bb3)
    #10 0x7fc18451445d  (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x5d45d) (BuildId: 116e142b9b52c8a4dfd403e759e71ab8f95d8bb3)
    #11 0x7fc184573976  (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0xbc976) (BuildId: 116e142b9b52c8a4dfd403e759e71ab8f95d8bb3)
    #12 0x7fc184514f46 in g_main_loop_run (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x5df46) (BuildId: 116e142b9b52c8a4dfd403e759e71ab8f95d8bb3)
    #13 0x55f8b7f157e8 in mainloop_run src/shared/mainloop-glib.c:65
    #14 0x55f8b7f16116 in mainloop_run_with_signal src/shared/mainloop-notify.c:196
    #15 0x55f8b7af46df in main src/main.c:1709
    #16 0x7fc18382a1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #17 0x7fc18382a28a in __libc_start_main_impl ../csu/libc-start.c:360
    #18 0x55f8b7af68b4 in _start (/home/fdanis/src/bluez/src/bluetoothd+0x6588b4) (BuildId: 89dc89ac5800f58cc305bae57a965b1185601a3e)

0x5020000ac220 is located 0 bytes after 16-byte region [0x5020000ac210,0x5020000ac220)
allocated by thread T0 here:
    #0 0x7fc1846fd9c7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x55f8b7ddf2b6 in util_malloc src/shared/util.c:46



To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications

^ permalink raw reply

* RE: [v2] Bluetooth: MGMT: Add management security level changed event
From: bluez.test.bot @ 2026-06-16 16:06 UTC (permalink / raw)
  To: linux-bluetooth, frederic.danis
In-Reply-To: <20260616145855.342740-1-frederic.danis@collabora.com>

[-- Attachment #1: Type: text/plain, Size: 2469 bytes --]

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1112403

---Test result---

Test Summary:
CheckPatch                    PASS      1.45 seconds
VerifyFixes                   PASS      0.07 seconds
VerifySignedoff               PASS      0.07 seconds
GitLint                       PASS      0.20 seconds
SubjectPrefix                 PASS      0.06 seconds
BuildKernel                   PASS      26.77 seconds
CheckAllWarning               PASS      29.14 seconds
CheckSparse                   PASS      27.75 seconds
BuildKernel32                 PASS      25.71 seconds
CheckKernelLLVM               SKIP      0.00 seconds
TestRunnerSetup               PASS      576.60 seconds
TestRunner_l2cap-tester       PASS      58.98 seconds
TestRunner_iso-tester         PASS      78.50 seconds
TestRunner_bnep-tester        PASS      18.77 seconds
TestRunner_mgmt-tester        FAIL      208.08 seconds
TestRunner_rfcomm-tester      PASS      25.39 seconds
TestRunner_sco-tester         PASS      32.28 seconds
TestRunner_ioctl-tester       PASS      25.58 seconds
TestRunner_mesh-tester        FAIL      24.95 seconds
TestRunner_smp-tester         PASS      23.13 seconds
TestRunner_userchan-tester    PASS      19.70 seconds
TestRunner_6lowpan-tester     PASS      22.49 seconds
IncrementalBuild              PASS      24.70 seconds

Details
##############################
Test: CheckKernelLLVM - SKIP
Desc: Build kernel with LLVM + context analysis
Output:
Clang not found
##############################
Test: TestRunner_mgmt-tester - FAIL
Desc: Run mgmt-tester with test-runner
Output:
Total: 494, Passed: 488 (98.8%), Failed: 2, Not Run: 4

Failed Test Cases
Read Exp Feature - Success                           Failed       0.245 seconds
LL Privacy - Unpair 1                                Timed out    1.853 seconds
##############################
Test: TestRunner_mesh-tester - FAIL
Desc: Run mesh-tester with test-runner
Output:
Total: 10, Passed: 8 (80.0%), Failed: 2, Not Run: 0

Failed Test Cases
Mesh - Send cancel - 1                               Timed out    1.826 seconds
Mesh - Send cancel - 2                               Timed out    1.992 seconds


https://github.com/bluez/bluetooth-next/pull/320

---
Regards,
Linux Bluetooth


^ permalink raw reply

* [PATCH] Bluetooth: btnxpuart: Fix out-of-bounds firmware read in nxp_recv_fw_req_v3()
From: Maoyi Xie @ 2026-06-16 15:40 UTC (permalink / raw)
  To: Amitkumar Karwar, Neeraj Kale, Marcel Holtmann,
	Luiz Augusto von Dentz
  Cc: Ilpo Järvinen, linux-bluetooth, linux-kernel

During the v3 firmware download the controller sends a v3_data_req with a
32 bit offset and a 16 bit len. nxp_recv_fw_req_v3() checks only the lower
bound of the offset and then sends firmware from that offset.

	nxpdev->fw_dnld_v3_offset = offset - nxpdev->fw_v3_offset_correction;
	serdev_device_write_buf(nxpdev->serdev, nxpdev->fw->data +
				nxpdev->fw_dnld_v3_offset, len);

Nothing checks that fw_dnld_v3_offset + len stays within nxpdev->fw->size, so a
controller that asks for an offset or length past the firmware image makes the
driver read past the end of nxpdev->fw->data and send that memory back over
UART.

nxp_recv_fw_req_v1() already bounds the same write. Add the equivalent check to
the v3 path, reject the request when it falls outside the firmware image, and
zero len on the error path so the fw_v3_prev_sent bookkeeping at free_skb stays
consistent.

Fixes: 689ca16e5232 ("Bluetooth: NXP: Add protocol support for NXP Bluetooth chipsets")
Suggested-by: Neeraj Kale <neeraj.sanjaykale@nxp.com>
Cc: stable@vger.kernel.org
Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com>
---
This is the fix for the out of bounds read I reported on linux-bluetooth. Neeraj
confirmed the bug and asked me to send it. The Suggested-by is for his suggestion
to zero len on the reject path, which keeps the fw_v3_prev_sent bookkeeping at
free_skb consistent.

 drivers/bluetooth/btnxpuart.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c
index e7036a48ce48..6a1cffe08d5f 100644
--- a/drivers/bluetooth/btnxpuart.c
+++ b/drivers/bluetooth/btnxpuart.c
@@ -1267,6 +1267,12 @@ static int nxp_recv_fw_req_v3(struct hci_dev *hdev, struct sk_buff *skb)
 	}
 
 	nxpdev->fw_dnld_v3_offset = offset - nxpdev->fw_v3_offset_correction;
+	if (nxpdev->fw_dnld_v3_offset >= nxpdev->fw->size ||
+	    len > nxpdev->fw->size - nxpdev->fw_dnld_v3_offset) {
+		bt_dev_err(hdev, "FW download out of bounds, ignoring request");
+		len = 0;
+		goto free_skb;
+	}
 	serdev_device_write_buf(nxpdev->serdev, nxpdev->fw->data +
 				nxpdev->fw_dnld_v3_offset, len);
 
-- 
2.34.1


^ permalink raw reply related

* Re: [v6,1/2] Bluetooth: hci_conn: Fix null ptr deref in hci_abort_conn()
From: Siwei Zhang @ 2026-06-16 15:33 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <6a3030a7.f732ad81.18cf48.63cc@mx.google.com>

Hi Luiz,

On Mon, Jun 15, 2026, at 1:04 PM, bluez.test.bot@gmail.com wrote:
> This is automated email and please do not reply to this email!
>
> Dear submitter,
>
> Thank you for submitting the patches to the linux bluetooth mailing list.
> This is a CI test results with your patch series:
> PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1111791
>
> ---Test result---
>
> Test Summary:
> CheckPatch                    PASS      1.82 seconds
> VerifyFixes                   PASS      0.09 seconds
> VerifySignedoff               PASS      0.09 seconds
> GitLint                       PASS      0.47 seconds
> SubjectPrefix                 PASS      0.16 seconds
> BuildKernel                   PASS      26.58 seconds
> CheckAllWarning               PASS      28.89 seconds
> CheckSparse                   PASS      27.60 seconds
> BuildKernel32                 PASS      25.49 seconds
> TestRunnerSetup               PASS      571.42 seconds
> TestRunner_l2cap-tester       PASS      58.94 seconds
> TestRunner_iso-tester         PASS      96.66 seconds
> TestRunner_bnep-tester        PASS      30.75 seconds
> TestRunner_mgmt-tester        FAIL      207.20 seconds
> TestRunner_rfcomm-tester      PASS      30.92 seconds
> TestRunner_sco-tester         PASS      31.50 seconds
> TestRunner_ioctl-tester       PASS      26.69 seconds
> TestRunner_mesh-tester        FAIL      25.83 seconds
> TestRunner_smp-tester         PASS      22.80 seconds
> TestRunner_userchan-tester    PASS      19.22 seconds
> TestRunner_6lowpan-tester     FAIL      45.81 seconds
> IncrementalBuild              PASS      43.45 seconds
>
> Details
> ##############################
> Test: TestRunner_mgmt-tester - FAIL
> Desc: Run mgmt-tester with test-runner
> Output:
> Total: 494, Passed: 489 (99.0%), Failed: 1, Not Run: 4
>
> Failed Test Cases
> Read Exp Feature - Success                           Failed       0.234 seconds

The mgmt.c is not modified in this patch.

> ##############################
> Test: TestRunner_mesh-tester - FAIL
> Desc: Run mesh-tester with test-runner
> Output:
> Total: 10, Passed: 8 (80.0%), Failed: 2, Not Run: 0
>
> Failed Test Cases
> Mesh - Send cancel - 1                               Timed out    2.808 seconds
> Mesh - Send cancel - 2                               Timed out    1.989 seconds

Also, the mesh path does not allocate hci_conn nor related to the code path changed.

> ##############################
> Test: TestRunner_6lowpan-tester - FAIL
> Desc: Run 6lowpan-tester with test-runner
> Output:
> Total: 8, Passed: 3 (37.5%), Failed: 5, Not Run: 0
>
> Failed Test Cases
> Client Connect - Disconnect                          Timed out    5.480 seconds
> Client Recv Dgram - Success                          Timed out    4.991 seconds
> Client Recv Raw - Success                            Timed out    4.993 seconds
> Client Recv IPHC Dgram - Success                     Timed out    4.999 seconds
> Client Recv IPHC Raw - Success                       Timed out    4.993 seconds
>
>

Fixed by the recent commit d35e2950daaf8cd362beb4ecd42af2b0d9459136.

> https://github.com/bluez/bluetooth-next/pull/318
>
> ---
> Regards,
> Linux Bluetooth

Could you please review on this patch?

And also this patch I sent on Monday.
https://lore.kernel.org/linux-bluetooth/20260612143449.3045055-1-oss@fourdim.xyz/T/#t

Thanks.

Best,
Siwei

^ permalink raw reply

* RE: Bluetooth: btmtksdio: teardown fixes
From: bluez.test.bot @ 2026-06-16 15:30 UTC (permalink / raw)
  To: linux-bluetooth, senozhatsky
In-Reply-To: <20260616111224.152140-2-senozhatsky@chromium.org>

[-- Attachment #1: Type: text/plain, Size: 560 bytes --]

This is an automated email and please do not reply to this email.

Dear Submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
While preparing the CI tests, the patches you submitted couldn't be applied to the current HEAD of the repository.

----- Output -----

error: patch failed: drivers/bluetooth/btmtksdio.c:620
error: drivers/bluetooth/btmtksdio.c: patch does not apply
hint: Use 'git am --show-current-patch' to see the failed patch

Please resolve the issue and submit the patches again.


---
Regards,
Linux Bluetooth


^ permalink raw reply

* [PATCH v2] Bluetooth: MGMT: Add management security level changed event
From: Frédéric Danis @ 2026-06-16 14:58 UTC (permalink / raw)
  To: linux-bluetooth

Add an event on device security level or encryption type change to
let user space know which level is currently in use.
Reset security level to 0 on disconnection so further connections
will correctly report security level changes.

This will be used for BlueZ qualification automation.

Signed-off-by: Frédéric Danis <frederic.danis@collabora.com>
---
v1->v2:
 - Add encryption type to the mgmt event
 - Send event on security level or encryption type change

 include/net/bluetooth/hci_core.h | 15 +++++++++++++--
 include/net/bluetooth/mgmt.h     | 11 +++++++++++
 net/bluetooth/hci_conn.c         |  8 ++++++++
 net/bluetooth/hci_event.c        | 20 ++++++++++++++++++--
 net/bluetooth/mgmt.c             | 20 ++++++++++++++++++++
 5 files changed, 70 insertions(+), 4 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 7e15da47fe3a..2920229c7f0b 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -2177,6 +2177,8 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
 		conn->security_cfm_cb(conn, status);
 }
 
+void mgmt_security_level_changed(struct hci_conn *conn);
+
 static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status)
 {
 	struct hci_cb *cb;
@@ -2199,11 +2201,20 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status)
 		encrypt = 0x01;
 
 	if (!status) {
-		if (conn->sec_level == BT_SECURITY_SDP)
+		bool sec_level_changed  = false;
+
+		if (conn->sec_level == BT_SECURITY_SDP) {
 			conn->sec_level = BT_SECURITY_LOW;
+			sec_level_changed = true;
+		}
 
-		if (conn->pending_sec_level > conn->sec_level)
+		if (conn->pending_sec_level > conn->sec_level) {
 			conn->sec_level = conn->pending_sec_level;
+			sec_level_changed = true;
+		}
+
+		if (sec_level_changed)
+			mgmt_security_level_changed(conn);
 	}
 
 	mutex_lock(&hci_cb_list_lock);
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 08daed7a96d5..69e0f3503e79 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -1192,3 +1192,14 @@ struct mgmt_ev_mesh_device_found {
 struct mgmt_ev_mesh_pkt_cmplt {
 	__u8	handle;
 } __packed;
+
+#define MGMT_CONN_SEC_ENCRYPT_NONE		0x00
+#define MGMT_CONN_SEC_ENCRYPT_E0		0x01
+#define MGMT_CONN_SEC_ENCRYPT_AES_CCM		0x02
+
+#define MGMT_EV_SECURITY_LEVEL_CHANGED		0x0033
+struct mgmt_ev_security_level_changed {
+	struct mgmt_addr_info addr;
+	__u8   level;
+	__u8   enc_type;
+} __packed;
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index c335372e4062..c9fb134c8891 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -1200,6 +1200,11 @@ static void hci_conn_unlink(struct hci_conn *conn)
 	if (!conn->parent) {
 		struct hci_link *link, *t;
 
+		conn->sec_level = BT_SECURITY_SDP;
+		clear_bit(HCI_CONN_ENCRYPT, &conn->flags);
+		clear_bit(HCI_CONN_AES_CCM, &conn->flags);
+		mgmt_security_level_changed(conn);
+
 		list_for_each_entry_safe(link, t, &conn->link_list, list) {
 			struct hci_conn *child = link->conn;
 
@@ -1502,6 +1507,7 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
 	}
 
 	conn->sec_level = BT_SECURITY_LOW;
+	mgmt_security_level_changed(conn);
 	conn->conn_timeout = conn_timeout;
 	conn->le_adv_phy = phy;
 	conn->le_adv_sec_phy = sec_phy;
@@ -1729,6 +1735,7 @@ struct hci_conn *hci_connect_le_scan(struct hci_dev *hdev, bdaddr_t *dst,
 	conn->state = BT_CONNECT;
 	set_bit(HCI_CONN_SCANNING, &conn->flags);
 	conn->sec_level = BT_SECURITY_LOW;
+	mgmt_security_level_changed(conn);
 	conn->pending_sec_level = sec_level;
 	conn->conn_timeout = conn_timeout;
 	conn->conn_reason = conn_reason;
@@ -1777,6 +1784,7 @@ struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
 		int err;
 
 		acl->sec_level = BT_SECURITY_LOW;
+		mgmt_security_level_changed(acl);
 		acl->pending_sec_level = sec_level;
 		acl->auth_type = auth_type;
 		acl->conn_timeout = timeout;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index b6d963ce26d0..15086780b766 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -762,6 +762,7 @@ static u8 hci_cc_read_enc_key_size(struct hci_dev *hdev, void *data,
 			status = HCI_ERROR_AUTH_FAILURE;
 			clear_bit(HCI_CONN_ENCRYPT, &conn->flags);
 			clear_bit(HCI_CONN_AES_CCM, &conn->flags);
+			mgmt_security_level_changed(conn);
 		}
 
 		/* Update the key encryption size with the connection one */
@@ -3184,6 +3185,8 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
 	}
 
 	if (!status) {
+		bool encrypt_change = false;
+
 		status = hci_conn_set_handle(conn, __le16_to_cpu(ev->handle));
 		if (status)
 			goto done;
@@ -3206,8 +3209,10 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
 		if (test_bit(HCI_AUTH, &hdev->flags))
 			set_bit(HCI_CONN_AUTH, &conn->flags);
 
-		if (test_bit(HCI_ENCRYPT, &hdev->flags))
+		if (test_bit(HCI_ENCRYPT, &hdev->flags)) {
 			set_bit(HCI_CONN_ENCRYPT, &conn->flags);
+			encrypt_change = true;
+		}
 
 		/* "Link key request" completed ahead of "connect request" completes */
 		if (ev->encr_mode == 1 && !test_bit(HCI_CONN_ENCRYPT, &conn->flags) &&
@@ -3217,11 +3222,15 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
 			key = hci_find_link_key(hdev, &ev->bdaddr);
 			if (key) {
 				set_bit(HCI_CONN_ENCRYPT, &conn->flags);
+				encrypt_change = true;
 				hci_read_enc_key_size(hdev, conn);
 				hci_encrypt_cfm(conn, ev->status);
 			}
 		}
 
+		if (encrypt_change)
+			mgmt_security_level_changed(conn);
+
 		/* Get remote features */
 		if (conn->type == ACL_LINK) {
 			struct hci_cp_read_remote_features cp;
@@ -3507,6 +3516,7 @@ static void hci_auth_complete_evt(struct hci_dev *hdev, void *data,
 		clear_bit(HCI_CONN_AUTH_FAILURE, &conn->flags);
 		set_bit(HCI_CONN_AUTH, &conn->flags);
 		conn->sec_level = conn->pending_sec_level;
+		mgmt_security_level_changed(conn);
 	} else {
 		if (ev->status == HCI_ERROR_PIN_OR_KEY_MISSING)
 			set_bit(HCI_CONN_AUTH_FAILURE, &conn->flags);
@@ -3622,9 +3632,12 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, void *data,
 			if ((conn->type == ACL_LINK && ev->encrypt == 0x02) ||
 			    conn->type == LE_LINK)
 				set_bit(HCI_CONN_AES_CCM, &conn->flags);
+
+			mgmt_security_level_changed(conn);
 		} else {
 			clear_bit(HCI_CONN_ENCRYPT, &conn->flags);
 			clear_bit(HCI_CONN_AES_CCM, &conn->flags);
+			mgmt_security_level_changed(conn);
 		}
 	}
 
@@ -5215,8 +5228,10 @@ static void hci_key_refresh_complete_evt(struct hci_dev *hdev, void *data,
 	if (conn->type != LE_LINK)
 		goto unlock;
 
-	if (!ev->status)
+	if (!ev->status) {
 		conn->sec_level = conn->pending_sec_level;
+		mgmt_security_level_changed(conn);
+	}
 
 	clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
 
@@ -5847,6 +5862,7 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
 	mgmt_device_connected(hdev, conn, NULL, 0);
 
 	conn->sec_level = BT_SECURITY_LOW;
+	mgmt_security_level_changed(conn);
 	conn->state = BT_CONFIG;
 
 	/* Store current advertising instance as connection advertising instance
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index dc55763f9e58..b02181f945d8 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -177,6 +177,7 @@ static const u16 mgmt_events[] = {
 	MGMT_EV_CONTROLLER_RESUME,
 	MGMT_EV_ADV_MONITOR_DEVICE_FOUND,
 	MGMT_EV_ADV_MONITOR_DEVICE_LOST,
+	MGMT_EV_SECURITY_LEVEL_CHANGED,
 };
 
 static const u16 mgmt_untrusted_commands[] = {
@@ -10534,6 +10535,25 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
 	mgmt_adv_monitor_device_found(hdev, bdaddr, report_device, skb, NULL);
 }
 
+void mgmt_security_level_changed(struct hci_conn *conn)
+{
+	struct mgmt_ev_security_level_changed ev;
+
+	bacpy(&ev.addr.bdaddr, &conn->dst);
+	ev.addr.type = link_to_bdaddr(conn->type, conn->dst_type);
+	ev.level = conn->sec_level;
+
+	if (!test_bit(HCI_CONN_ENCRYPT, &conn->flags))
+		ev.enc_type = MGMT_CONN_SEC_ENCRYPT_NONE;
+	else if (test_bit(HCI_CONN_AES_CCM, &conn->flags))
+		ev.enc_type = MGMT_CONN_SEC_ENCRYPT_AES_CCM;
+	else
+		ev.enc_type = MGMT_CONN_SEC_ENCRYPT_E0;
+
+	mgmt_event(MGMT_EV_SECURITY_LEVEL_CHANGED, conn->hdev, &ev, sizeof(ev),
+		   NULL);
+}
+
 void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
 		      u8 addr_type, s8 rssi, u8 *name, u8 name_len)
 {
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH v1] Bluetooth: btmtk: Add MT7928 support
From: Pauli Virtanen @ 2026-06-16 14:38 UTC (permalink / raw)
  To: Chris Lu, Marcel Holtmann, Johan Hedberg, Luiz Von Dentz
  Cc: Sean Wang, Will Lee, SS Wu, Steve Lee, linux-bluetooth,
	linux-mediatek
In-Reply-To: <20260616030132.532184-1-chris.lu@mediatek.com>

Hi,

ti, 2026-06-16 kello 11:01 +0800, Chris Lu kirjoitti:
> Add support for MT7928 (device ID 0x7935) which requires additional
> firmware (CBMCU firmware) loading before Bluetooth firmware.
> 
> Implement two-phase CBMCU firmware download: Phase 1 loads
> section with type 0x5 containing global descriptor,
> section maps and signature data; Phase 2 loads remaining
> firmware sections. Add retry mechanism for concurrent download
> protection.
> 
> After CBMCU firmware loads successfully, the driver continues
> to load corresponding BT firmware based on device ID through
> fallthrough to case 0x7922/0x7925.
> 
> Signed-off-by: Chris Lu <chris.lu@mediatek.com>
> ---
[clip]
> diff --git a/drivers/bluetooth/btmtk.h b/drivers/bluetooth/btmtk.h
> index c83c24897c95..6d3bf6b74a1d 100644
> --- a/drivers/bluetooth/btmtk.h
> +++ b/drivers/bluetooth/btmtk.h
> @@ -9,6 +9,8 @@
>  #define FIRMWARE_MT7961		"mediatek/BT_RAM_CODE_MT7961_1_2_hdr.bin"
>  #define FIRMWARE_MT7925		"mediatek/mt7925/BT_RAM_CODE_MT7925_1_1_hdr.bin"
>  #define FIRMWARE_MT7927		"mediatek/mt7927/BT_RAM_CODE_MT6639_2_1_hdr.bin"
> +#define FIRMWARE_MT7928		"mediatek/mt7928/BT_RAM_CODE_MT7935_1_1_hdr.bin"
> +#define FIRMWARE_MT7928_CBMCU	"mediatek/mt7928/CBMCU_CODE_MT7935_1_1.bin"

Are these firmware names correct? 

The above names for MT7928 say MT79**35** not MT7928?

>  
>  #define HCI_EV_WMT 0xe4
>  #define HCI_WMT_MAX_EVENT_SIZE		64
> @@ -54,6 +56,7 @@ enum {
>  	BTMTK_WMT_RST = 0x7,
>  	BTMTK_WMT_REGISTER = 0x8,
>  	BTMTK_WMT_SEMAPHORE = 0x17,
> +	BTMTK_WMT_CBMCU_DWNLD = 0x58,
>  };
>  
>  enum {

-- 
Pauli Virtanen

^ permalink raw reply

* RE: [BlueZ] hci-tester: Work-around possible string overflow
From: bluez.test.bot @ 2026-06-16 13:05 UTC (permalink / raw)
  To: linux-bluetooth, hadess
In-Reply-To: <20260616085538.3568474-1-hadess@hadess.net>

[-- Attachment #1: Type: text/plain, Size: 1172 bytes --]

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1112149

---Test result---

Test Summary:
CheckPatch                    PASS      0.45 seconds
GitLint                       FAIL      0.32 seconds
BuildEll                      PASS      20.10 seconds
BluezMake                     PASS      620.61 seconds
CheckSmatch                   PASS      330.69 seconds
bluezmakeextell               PASS      169.87 seconds
IncrementalBuild              PASS      628.29 seconds
ScanBuild                     PASS      945.21 seconds

Details
##############################
Test: GitLint - FAIL
Desc: Run gitlint
Output:
[BlueZ] hci-tester: Work-around possible string overflow

7: B1 Line exceeds max length (160>80): "/usr/include/bits/string_fortified.h:29:10: warning: '__builtin_memcpy' writing 6 bytes into a region of size 0 overflows the destination [-Wstringop-overflow=]"


https://github.com/bluez/bluez/pull/2236

---
Regards,
Linux Bluetooth


^ permalink raw reply

* RE: Initial Channel Sounding Support for
From: bluez.test.bot @ 2026-06-16 12:55 UTC (permalink / raw)
  To: linux-bluetooth, naga.akella
In-Reply-To: <20260616072245.3700010-2-naga.akella@oss.qualcomm.com>

[-- Attachment #1: Type: text/plain, Size: 2090 bytes --]

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1112111

---Test result---

Test Summary:
CheckPatch                    PASS      1.07 seconds
GitLint                       PASS      0.54 seconds
BuildEll                      FAIL      13.99 seconds
BluezMake                     PASS      508.08 seconds
CheckSmatch                   PASS      258.70 seconds
bluezmakeextell               FAIL      5.21 seconds
IncrementalBuild              PASS      549.34 seconds
ScanBuild                     PASS      746.61 seconds

Details
##############################
Test: BuildEll - FAIL
Desc: Build and Install ELL
Output:

writing RSA key
writing RSA key
writing RSA key
writing RSA key
writing RSA key
make[1]: *** [Makefile:3293: unit/ec-cert-server.pem] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:1309: all] Error 2
##############################
Test: bluezmakeextell - FAIL
Desc: Build Bluez with External ELL
Output:

configure.ac:21: installing './compile'
configure.ac:36: installing './config.guess'
configure.ac:36: installing './config.sub'
configure.ac:5: installing './install-sh'
configure.ac:5: installing './missing'
Makefile.am: installing './depcomp'
parallel-tests: installing './test-driver'
Package cups was not found in the pkg-config search path.
Perhaps you should add the directory containing `cups.pc'
to the PKG_CONFIG_PATH environment variable
No package 'cups' found
configure: error: Package requirements (ell >= 0.39) were not met:

No package 'ell' found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables ELL_CFLAGS
and ELL_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.


https://github.com/bluez/bluez/pull/2235

---
Regards,
Linux Bluetooth


^ permalink raw reply

* [PATCH BlueZ] shared/gatt: Fix gatt-db buffer overflow for cloned db
From: Frédéric Danis @ 2026-06-16 12:30 UTC (permalink / raw)
  To: linux-bluetooth

On notify_service_changed() timeout, db_hash_update() is called but
for cloned db the last-handle has not been copied and only one slot is
allocated, ending in buffer overflow:

==288975==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x5020000ac220 at pc 0x55f8b7e551bf bp 0x7ffcd6e9ddf0 sp 0x7ffcd6e9dde0
WRITE of size 8 at 0x5020000ac220 thread T0
    #0 0x55f8b7e551be in gen_hash_m src/shared/gatt-db.c:415
    #1 0x55f8b7e5d817 in gatt_db_service_foreach src/shared/gatt-db.c:1744
    #2 0x55f8b7e5d817 in gatt_db_service_foreach src/shared/gatt-db.c:1722
    #3 0x55f8b7e60c6c in foreach_service_in_range src/shared/gatt-db.c:1633
    #4 0x55f8b7e60c6c in foreach_in_range src/shared/gatt-db.c:1656
    #5 0x55f8b7dde002 in queue_foreach src/shared/queue.c:207
    #6 0x55f8b7e5c435 in gatt_db_foreach_service_in_range src/shared/gatt-db.c:1698
    #7 0x55f8b7e5c87c in db_hash_update src/shared/gatt-db.c:442
    #8 0x55f8b7f15283 in timeout_callback src/shared/timeout-glib.c:25
    #9 0x7fc1845154f1  (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x5e4f1) (BuildId: 116e142b9b52c8a4dfd403e759e71ab8f95d8bb3)
    #10 0x7fc18451445d  (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x5d45d) (BuildId: 116e142b9b52c8a4dfd403e759e71ab8f95d8bb3)
    #11 0x7fc184573976  (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0xbc976) (BuildId: 116e142b9b52c8a4dfd403e759e71ab8f95d8bb3)
    #12 0x7fc184514f46 in g_main_loop_run (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x5df46) (BuildId: 116e142b9b52c8a4dfd403e759e71ab8f95d8bb3)
    #13 0x55f8b7f157e8 in mainloop_run src/shared/mainloop-glib.c:65
    #14 0x55f8b7f16116 in mainloop_run_with_signal src/shared/mainloop-notify.c:196
    #15 0x55f8b7af46df in main src/main.c:1709
    #16 0x7fc18382a1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #17 0x7fc18382a28a in __libc_start_main_impl ../csu/libc-start.c:360
    #18 0x55f8b7af68b4 in _start (/home/fdanis/src/bluez/src/bluetoothd+0x6588b4) (BuildId: 89dc89ac5800f58cc305bae57a965b1185601a3e)

0x5020000ac220 is located 0 bytes after 16-byte region [0x5020000ac210,0x5020000ac220)
allocated by thread T0 here:
    #0 0x7fc1846fd9c7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x55f8b7ddf2b6 in util_malloc src/shared/util.c:46
---
 src/shared/gatt-db.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/shared/gatt-db.c b/src/shared/gatt-db.c
index 87cc61cf3..751d4c3da 100644
--- a/src/shared/gatt-db.c
+++ b/src/shared/gatt-db.c
@@ -330,6 +330,7 @@ struct gatt_db *gatt_db_clone(struct gatt_db *db)
 		return NULL;
 
 	queue_foreach(db->services, service_clone, clone);
+	clone->last_handle = db->last_handle;
 
 	return clone;
 }
@@ -433,7 +434,7 @@ static bool db_hash_update(void *user_data)
 
 	db->hash_id = 0;
 
-	if (gatt_db_isempty(db))
+	if (gatt_db_isempty(db) || !db->last_handle)
 		return false;
 
 	hash.iov = new0(struct iovec, db->last_handle + 1);
-- 
2.43.0


^ permalink raw reply related

* [bluez/bluez]
From: BluezTestBot @ 2026-06-16 12:19 UTC (permalink / raw)
  To: linux-bluetooth

  Branch: refs/heads/1109997
  Home:   https://github.com/bluez/bluez

To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications

^ permalink raw reply

* [bluez/bluez] fd0161: hci-tester: Work-around possible string overflow
From: hadess @ 2026-06-16 12:19 UTC (permalink / raw)
  To: linux-bluetooth

  Branch: refs/heads/1112149
  Home:   https://github.com/bluez/bluez
  Commit: fd0161f8f6af60019a11b003772a5655ae05c632
      https://github.com/bluez/bluez/commit/fd0161f8f6af60019a11b003772a5655ae05c632
  Author: Bastien Nocera <hadess@hadess.net>
  Date:   2026-06-16 (Tue, 16 Jun 2026)

  Changed paths:
    M tools/hci-tester.c

  Log Message:
  -----------
  hci-tester: Work-around possible string overflow

Quiet overflow warning by checking for a non-NULL destination.

In function 'memcpy',
    inlined from 'test_pre_setup_lt_address' at tools/hci-tester.c:67:2:
/usr/include/bits/string_fortified.h:29:10: warning: '__builtin_memcpy' writing 6 bytes into a region of size 0 overflows the destination [-Wstringop-overflow=]
   29 |   return __builtin___memcpy_chk (__dest, __src, __len,
      |          ^



To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications

^ permalink raw reply

* [bluez/bluez] 654362: shared: rap: Check role before sending CS Sec Enab...
From: Bhavani @ 2026-06-16 12:19 UTC (permalink / raw)
  To: linux-bluetooth

  Branch: refs/heads/1112111
  Home:   https://github.com/bluez/bluez
  Commit: 654362f5880156fdf3467baf04bbab7407477be4
      https://github.com/bluez/bluez/commit/654362f5880156fdf3467baf04bbab7407477be4
  Author: Naga Bhavani Akella <naga.akella@oss.qualcomm.com>
  Date:   2026-06-16 (Tue, 16 Jun 2026)

  Changed paths:
    M src/shared/rap.h

  Log Message:
  -----------
  shared: rap: Check role before sending CS Sec Enable cmd

Add the is_central parameter to verify whether
the local role is central before sending
the HCI CS Security Enable command.


  Commit: e98e534dcc27c8861a626cb5968da391c29246aa
      https://github.com/bluez/bluez/commit/e98e534dcc27c8861a626cb5968da391c29246aa
  Author: Naga Bhavani Akella <naga.akella@oss.qualcomm.com>
  Date:   2026-06-16 (Tue, 16 Jun 2026)

  Changed paths:
    M profiles/ranging/rap.c
    M profiles/ranging/rap_hci.c

  Log Message:
  -----------
  profiles: ranging: Add CS Initiator cmd and evt handling

Introduce support for LE Channel Sounding (CS)
ranging procedures in the Initiator role by enabling
required HCI command sequencing and event handling.

Add handling of core HCI LE CS commands and events
This enables cs capability discovery, cs configuration
management and execution of CS ranging procedures
in the Initiator role.


  Commit: d8e60b357ae7e770262746b47809bb8ac6a21368
      https://github.com/bluez/bluez/commit/d8e60b357ae7e770262746b47809bb8ac6a21368
  Author: Naga Bhavani Akella <naga.akella@oss.qualcomm.com>
  Date:   2026-06-16 (Tue, 16 Jun 2026)

  Changed paths:
    M src/shared/rap.h

  Log Message:
  -----------
  shared: rap: remove the old wrapper API

Replace API bt_rap_set_conn_handle with
bt_rap_set_conn_hndl which has extra parameter
to avoid compilation error for individual patches


Compare: https://github.com/bluez/bluez/compare/654362f58801%5E...d8e60b357ae7

To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications

^ permalink raw reply

* [PATCH v2 3/3] Bluetooth: btmtksdio: call cancel_work_sync() outside of host lock scope
From: Sergey Senozhatsky @ 2026-06-16 11:12 UTC (permalink / raw)
  To: Marcel Holtmann, Luiz Augusto von Dentz, Mark-yw Chen, Sean Wang
  Cc: Tomasz Figa, linux-bluetooth, linux-kernel, linux-arm-kernel,
	linux-mediatek, Sergey Senozhatsky, stable
In-Reply-To: <20260616111224.152140-1-senozhatsky@chromium.org>

cancel_work_sync() should be called outside of host lock scope
in order to avoid circular locking scenario:

CPU0					CPU1
					close()/reset()
					sdio_claim_host()
txrx_work
  sdio_claim_host() // sleeps
					cancel_work_sync() // sleeps

In addition, when txrx_work() runs concurrently with close()/reset()
it better not to re-enable interrupts by testing for BTMTKSDIO_FUNC_ENABLED
and not BTMTKSDIO_HW_RESET_ACTIVE before C_INT_EN_SET write.  However,
btmtksdio_close() clears the BTMTKSDIO_FUNC_ENABLED too late (after
cancel_work_sync() call).  Move BTMTKSDIO_FUNC_ENABLED bit-clear earlier
so that txrx_work can see concurrent close().

Fixes: 26270bc189ea4 ("Bluetooth: btmtksdio: move interrupt service to work")
Cc: stable@vger.kernel.org
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
 drivers/bluetooth/btmtksdio.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c
index d8c8d2857527..207d04cc2282 100644
--- a/drivers/bluetooth/btmtksdio.c
+++ b/drivers/bluetooth/btmtksdio.c
@@ -625,7 +625,9 @@ static void btmtksdio_txrx_work(struct work_struct *work)
 	} while (int_status && time_is_after_jiffies(txrx_timeout));
 
 	/* Enable interrupt */
-	if (bdev->func->irq_handler)
+	if (bdev->func->irq_handler &&
+	    test_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state) &&
+	    !test_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state))
 		sdio_writel(bdev->func, C_INT_EN_SET, MTK_REG_CHLPCR, NULL);
 
 	sdio_release_host(bdev->func);
@@ -741,6 +743,8 @@ static int btmtksdio_close(struct hci_dev *hdev)
 	if (!test_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state))
 		return 0;
 
+	clear_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state);
+
 	sdio_claim_host(bdev->func);
 
 	/* Disable interrupt */
@@ -748,11 +752,12 @@ static int btmtksdio_close(struct hci_dev *hdev)
 
 	sdio_release_irq(bdev->func);
 
+	sdio_release_host(bdev->func);
 	cancel_work_sync(&bdev->txrx_work);
+	sdio_claim_host(bdev->func);
 
 	btmtksdio_fw_pmctrl(bdev);
 
-	clear_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state);
 	sdio_disable_func(bdev->func);
 
 	sdio_release_host(bdev->func);
@@ -1295,7 +1300,10 @@ static void btmtksdio_reset(struct hci_dev *hdev)
 
 	sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, NULL);
 	skb_queue_purge(&bdev->txq);
+
+	sdio_release_host(bdev->func);
 	cancel_work_sync(&bdev->txrx_work);
+	sdio_claim_host(bdev->func);
 
 	gpiod_set_value_cansleep(bdev->reset, 1);
 	msleep(100);
-- 
2.54.0.1136.gdb2ca164c4-goog


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox