* [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 *)§ionmap->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 *)§ionmap-
> > >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
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox