summaryrefslogtreecommitdiff
path: root/drivers/bluetooth
AgeCommit message (Collapse)AuthorFilesLines
4 daysBluetooth: btusb: validate Realtek vendor event lengthPengpeng Hou1-1/+3
[ Upstream commit df541cd485ff80a5ddc579d99687bc7506df9851 ] btusb_recv_event_realtek() reads the event code at data[0] and the Realtek subevent code at data[2] before deciding whether to consume a vendor event as a coredump. For example, the two-byte event ff 00 contains a complete vendor-event header declaring zero parameters. The old classifier still reads a nonexistent third byte and can misclassify the event as a coredump if the adjacent byte is 0x34. Require the HCI event header and first parameter to be present before inspecting the Realtek subevent code. Short events continue through the normal HCI receive path, which owns their protocol validation. Fixes: 044014ce85a1 ("Bluetooth: btrtl: Add Realtek devcoredump support") Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
4 daysBluetooth: hci_qca: Clear memdump state on invalid dump sizeRuoyu Wang1-0/+4
[ Upstream commit bf587a10c33e5571a299742e45bc18960b9912e7 ] qca_controller_memdump() allocates qca->qca_memdump before processing the first dump packet. For a sequence-zero packet it then disables IBS, marks memdump collection active, and reads the advertised dump size. If the controller reports a zero dump size, the error path frees the local qca_memdump object and returns without clearing qca->qca_memdump or undoing the collection state. A later memdump work item initializes its local pointer from qca->qca_memdump and skips allocation when that pointer is non-NULL, so it can operate on freed memory. The stale collection and IBS-disabled flags can also leave waiters or later transmit handling blocked behind an aborted dump. Clear the saved pointer and memdump state before returning from the invalid-size path, matching the cleanup used when hci_devcd_init() fails. A static analysis checker reported the stale memdump state, and manual source review confirmed the invalid-size failure path. Fixes: 06d3fdfcdf5c ("Bluetooth: hci_qca: Add qcom devcoredump support") Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com> Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de> Reviewed-by: Zijun Hu <zijun.hu@oss.qualcomm.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
4 daysBluetooth: qca: fix NVM tag length underflow in TLV parserXiang Mei1-1/+1
[ Upstream commit c90164ca0f7036942ba088eb7ea8d3f6c2352020 ] In the TLV_TYPE_NVM branch of qca_tlv_check_data() the tag loop bound is "while (idx < length - sizeof(struct tlv_type_nvm))". "length" is a signed int from the firmware TLV header and sizeof(struct tlv_type_nvm) is a size_t (12), so "length" is converted to size_t and any firmware-supplied "length" < 12 makes the subtraction wrap to a huge value. The loop body then reads a 12-byte struct tlv_type_nvm past the end of the short vmalloc'd firmware buffer (and the EDL_TAG_ID_* handlers can write past it). Rewrite the bound as "idx + sizeof(struct tlv_type_nvm) <= length"; both operands are non-negative, so it no longer underflows and a "length" too small for one record correctly skips the loop. BUG: KASAN: vmalloc-out-of-bounds in qca_download_firmware.isra.0 (drivers/bluetooth/btqca.c:421) Read of size 2 at addr ffffc900000e5004 by task kworker/u9:0/52 Workqueue: hci0 hci_power_on Call Trace: ... kasan_report (mm/kasan/report.c:595) qca_download_firmware.isra.0 (drivers/bluetooth/btqca.c:421 drivers/bluetooth/btqca.c:617) qca_uart_setup (drivers/bluetooth/btqca.c:948) qca_setup (drivers/bluetooth/hci_qca.c:2029) hci_uart_setup (drivers/bluetooth/hci_ldisc.c:438) hci_dev_open_sync (net/bluetooth/hci_sync.c:5227) hci_power_on (net/bluetooth/hci_core.c:920) process_one_work (kernel/workqueue.c:3322) worker_thread (kernel/workqueue.c:3486) kthread (kernel/kthread.c:436) ret_from_fork (arch/x86/kernel/process.c:158) ret_from_fork_asm (arch/x86/entry/entry_64.S:245) Fixes: 2e4edfa1e2bd ("Bluetooth: qca: add missing firmware sanity checks") Reported-by: Weiming Shi <bestswngs@gmail.com> Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Xiang Mei <xmei5@asu.edu> Reported-by: Weiming Shi <bestswngs@gmail.com> Reviewed-by: Johan Hovold <johan@kernel.org> Acked-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
14 daysBluetooth: btrtl: validate firmware patch boundsLaxman Acharya Padhya1-2/+3
commit 609c5b04a28dc1b0f3af6a7bc93055135b2d2059 upstream. rtlbt_parse_firmware() copies patch_length - 4 bytes before appending the firmware version. A malformed firmware patch shorter than the version field can make this subtraction underflow and turn the copy into an oversized read and write during Bluetooth setup. The existing patch_offset + patch_length check can also wrap on 32-bit architectures. Validate the patch length and range without arithmetic overflow before allocating or copying the patch. Fixes: db33c77dddc2 ("Bluetooth: btrtl: Create separate module for Realtek BT driver") Cc: stable@vger.kernel.org Signed-off-by: Laxman Acharya Padhya <acharyalaxman8848@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
14 daysBluetooth: bpa10x: avoid OOB read of revision string in bpa10x_setup()Weiming Shi1-2/+6
[ Upstream commit dd068ef044128db655f48323a4acfd5907e04903 ] bpa10x_setup() sends the vendor command 0xfc0e and passes the response to bt_dev_info() and hci_set_fw_info() as a "%s" string starting at skb->data + 1, without checking the length: bt_dev_info(hdev, "%s", (char *)(skb->data + 1)); hci_set_fw_info(hdev, "%s", skb->data + 1); A device that returns a one-byte response (status only) leaves skb->data + 1 past the end of the data, and the %s walk reads adjacent slab memory until it meets a NUL. The same happens when the payload is not NUL-terminated within skb->len. The out-of-bounds bytes end up in the kernel log and the firmware-info debugfs file. Print the revision string with a bounded "%.*s" limited to skb->len - 1 instead. This keeps the string readable for well-behaved devices while never reading past the received data, and does not fail setup, so a device returning a short or unterminated response keeps working. Fixes: ddd68ec8f484 ("Bluetooth: bpa10x: Read revision information in setup stage") Reported-by: Xiang Mei <xmei5@asu.edu> Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Weiming Shi <bestswngs@gmail.com> Reported-by: Xiang Mei <xmei5@asu.edu> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
14 daysBluetooth: btintel_pcie: Refactor FLR to use device_reprobe()Kiran K1-50/+52
[ Upstream commit 9c36951474d8e1127f4946f39cb874a200f34e9f ] The FLR branch in btintel_pcie_reset_work() open-coded the entire re-init sequence: btintel_pcie_release_hdev() (hci_unregister_dev + hci_free_dev), pci_try_reset_function(), enable_interrupts / config_msix / enable_bt / reset_ia / start_rx, then btintel_pcie_setup_hdev() (hci_alloc_dev_priv + hci_register_dev). Every probe() init step had to be kept in sync with this second copy in the reset path, and any failure mid-sequence left state to unwind by hand. The PLDR path already delegates teardown and re-init to the PCI core via device_reprobe(): .remove() destroys data through devres and unregisters hdev, then .probe() rebuilds everything from scratch. Apply the same model to FLR. Introduce btintel_pcie_perform_flr() mirroring perform_pldr(). It runs pci_try_reset_function() (required to avoid the device_lock ABBA against btintel_pcie_remove(), which calls disable_work_sync(&reset_work) while holding device_lock) followed by device_reprobe(). On success, data is destroyed and a fresh probe re-INIT_WORKs coredump_work with disable count 0, so enable_work() must not be called; on failure, data is still alive and the caller balances the earlier disable_work_sync(). The contract is documented on the helper and reiterated at the reset_work() call site. reset_work() shrinks to interrupt/worker drain, dispatch on reset_type, and the single asymmetry between the two paths. The out_enable label, the manual unregister/register pair, and the forward declaration of btintel_pcie_setup_hdev() are dropped. No intended functional change; FLR and PLDR now share one teardown contract. Fixes: 256ab9520d15 ("Bluetooth: btintel_pcie: Support Function level reset") Assisted-by: GitHub-Copilot:claude-4.7-opus Signed-off-by: Kiran K <kiran.k@intel.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
14 daysBluetooth: btintel_pcie: Separate coredump work from RX workRavindra2-20/+87
[ Upstream commit f70f7f2512c6b9113dc78f6a25361166afd1412e ] Sharing a single workqueue between coredump processing and RX delays evacuation of RX events while a coredump is in progress. The firmware's RX buffers can overflow during that window, leading to dropped events. The issue was observed in HID use cases where HID reports arrive in bursts and quickly fill the RX path while a coredump is being collected. Move coredump processing to a dedicated ordered coredump_workqueue with its own coredump_work, so coredumps run independently of RX. All four coredump trigger sources (FW assert, HW exception, user sysfs trigger, and resume-error detection) are switched to this new workqueue. Ordering serialises concurrent triggers without blocking RX. Signed-off-by: Ravindra <ravindra@intel.com> Signed-off-by: Kiran K <kiran.k@intel.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Stable-dep-of: 9c36951474d8 ("Bluetooth: btintel_pcie: Refactor FLR to use device_reprobe()") Signed-off-by: Sasha Levin <sashal@kernel.org>
14 daysBluetooth: btintel_pcie: Add support for smart trigger dumpKiran K3-1/+174
[ Upstream commit 975a70ff0aec8a2be0d633113f781b301db4a816 ] Based on the debug configuration, firmware can raise MSI-X interrupt with firmware trigger cause bit set on specific events like Disconnection, Connection Timeout, Page Timeout etc. Upon receiving an MSI-X interrupt with the firmware trigger cause bit set, the driver performs the following actions: 1. Reads Device Memory: Retrieves data from the device memory, constructs an HCI diagnostic event, and sends it to the monitor. This event includes details about the trigger, such as connection timeout or page timeout. 2. Dumps Device Coredump: Generates a coredump containing firmware traces for further analysis. The coredump can be retrieved using: $ cat /sys/class/devcoredump/devcd*/data > /tmp/btintel_coredump.bin HCI traces: = Vendor Diagnostic (len 12) a5 a5 a5 a5 01 03 00 23 00 01 00 00 Signed-off-by: Kiran K <kiran.k@intel.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Stable-dep-of: 9c36951474d8 ("Bluetooth: btintel_pcie: Refactor FLR to use device_reprobe()") Signed-off-by: Sasha Levin <sashal@kernel.org>
14 daysBluetooth: btintel_pcie: Support Product level resetChandrashekar Devegowda5-36/+195
[ Upstream commit 2d00975c841fa2e52921353392ce9780843bfee7 ] When driver encounters a TOP exception, ACPI methods will be called for Product level reset since Wifi and BT share the same TOP. BT driver will first reprobe the wifi driver and then reprobe BT. Signed-off-by: Chandrashekar Devegowda <chandrashekar.devegowda@intel.com> Signed-off-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Stable-dep-of: 9c36951474d8 ("Bluetooth: btintel_pcie: Refactor FLR to use device_reprobe()") Signed-off-by: Sasha Levin <sashal@kernel.org>
14 daysBluetooth: vhci: validate devcoredump state before side effectsSamuel Moelius1-0/+10
[ Upstream commit 88c2404a3c59c3126453919388dbd5ed98ed01bd ] The VHCI force_devcoredump debugfs hook accepts a small test record from userspace. It validates the requested terminal state only after registering, initializing and appending a Bluetooth devcoredump. As a result, an invalid state returns -EINVAL but still leaves queued devcoredump work behind. With a non-zero timeout field, the rejected write can still emit a devcoredump after the timeout expires. Reject unsupported states before allocating the skb or changing the HCI devcoredump state machine. Fixes: ab4e4380d4e1 ("Bluetooth: Add vhci devcoredump support") Assisted-by: Codex:gpt-5.5-cyber-preview Signed-off-by: Samuel Moelius <sam.moelius@trailofbits.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
14 daysBluetooth: btintel_pcie: Load IOSF debug regs by controller variantSai Teja Aluvala3-6/+29
[ Upstream commit e43b33bf8d671c50a45fe5f487819927595bbd50 ] Load the IOSF DBGC base address based on the controller hardware variant when reading DRAM buffers during a trace dump. Scorpius Peak family controllers (SCP/SCP2/SCP2F) use a different DBGC base address (0xf0d5d500) than Blazar family controllers (BZRI/BZRIW, 0xf3800300). Fixes: 07e6bddb54b4 ("Bluetooth: btintel_pcie: Add support for device coredump") Signed-off-by: Sai Teja Aluvala <aluvala.sai.teja@intel.com> Signed-off-by: Kiran K <kiran.k@intel.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
14 daysBluetooth: btmtk: fix URB leak in alloc_mtk_intr_urb error pathZhao Dongdong1-1/+3
[ Upstream commit f396f4005180928cd9e15e352a6512865d3bc908 ] When btmtk_isopkt_pad() fails, the previously allocated URB is not freed, leaking the urb structure. Add usb_free_urb() before returning the error. Fixes: ceac1cb0259d ("Bluetooth: btusb: mediatek: add ISO data transmission functions") Signed-off-by: Zhao Dongdong <zhaodongdong@kylinos.cn> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
14 daysBluetooth: hci_qca: fix NULL pointer dereference in qca_dmp_hdr() for ↵Zijun Hu1-1/+1
non-serdev device [ Upstream commit 6b8cbcf08de0db62254d1981f83db0f94681ccd9 ] hu->serdev is NULL for hci_uart attached via non-serdev paths, but qca_dmp_hdr() unconditionally dereferences hu->serdev->dev.driver->name, causing a NULL pointer dereference. Fix by guarding the dereference with a NULL check and falling back to "hci_ldisc_qca" for the non-serdev case. Fixes: 06d3fdfcdf5c ("Bluetooth: hci_qca: Add qcom devcoredump support") Signed-off-by: Zijun Hu <zijun.hu@oss.qualcomm.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
14 daysBluetooth: hci_qca: fix NULL pointer dereference in qca_setup() for ↵Zijun Hu1-3/+6
non-serdev device [ Upstream commit 3ec629fee178d429f01ae843e4ea888de93012bf ] hu->serdev is NULL for hci_uart attached via non-serdev paths, but qca_setup() unconditionally calls serdev_device_get_drvdata(hu->serdev) and dereferences the result, causing a NULL pointer dereference. Fix by guarding the dereference with a NULL check, consistent with the rest of qca_setup(). Fixes: 22d893eec0d5 ("Bluetooth: hci_qca: Refactor HFP hardware offload capability handling") Signed-off-by: Zijun Hu <zijun.hu@oss.qualcomm.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
2026-07-18Bluetooth: hci_uart: clear HCI_UART_SENDING when write_work is canceledPauli Virtanen1-4/+10
commit 1b0d946d6f08bd39211385bc703a440911b41e46 upstream. HCI_UART_SENDING bit in tx_state means write_work is pending and blocks queueing it again. Currently this bit is not cleared when canceling the work in hci_uart_close(), which blocks future writes when device is reopened later if write_work was pending. Fix by clearing HCI_UART_SENDING when canceling the work. Also make clearing of tx_skb safe by using disable_work_sync + enable_work instead of just cancel_work_sync. hci_uart_flush() purges the proto tx queue so we can cancel the pending write_work there, instead of doing it just in hci_uart_close(). Re-enable and possibly requeue the work after queue flush. Fixes: c1bb9336ae6b ("Bluetooth: hci_uart: fix UAFs and race conditions in close and init paths") Link: https://lore.kernel.org/linux-bluetooth/07e0a28650773abec711ee492fdb1bf5d21a6c98.camel@iki.fi/ Cc: stable@vger.kernel.org Signed-off-by: Pauli Virtanen <pav@iki.fi> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-07-18Bluetooth: btnxpuart: Fix out-of-bounds firmware read in nxp_recv_fw_req_v3()Maoyi Xie1-0/+6
commit badff6c3bed8923a1257a853f137d447976eec30 upstream. 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 Sanjay Kale <neeraj.sanjaykale@nxp.com> Reviewed-by: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com> Cc: stable@vger.kernel.org Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-07-18Bluetooth: btmtksdio: fix infinite loop in btmtksdio_txrx_work()Sergey Senozhatsky1-1/+1
commit a257407e2bbbb099ed427719a50563f67fa366d8 upstream. Every once in a while we see a hung btmtksdio_flush() task: INFO: task kworker/u17:0:189 blocked for more than 122 seconds. __cancel_work_timer+0x3f4/0x460 cancel_work_sync+0x1c/0x2c btmtksdio_flush+0x2c/0x40 hci_dev_open_sync+0x10c4/0x2190 [..] It all boils down to incorrect time_is_before_jiffies() usage in btmtksdio_txrx_work(). The btmtksdio_txrx_work() loop is expected to be terminated if running for longer than 5*HZ. However the timeout check is twisted: 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. When the loop becomes infinite btmtksdio_txrx_work() loop never terminates and never releases the SDIO host. 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> Reviewed-by: Sean Wang <sean.wang@mediatek.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-07-18Bluetooth: btusb: fix wakeup source leak on probe failureJohan Hovold1-3/+15
commit 3d93e1bb0fb881fe3ef961d1120556658e9cac4d upstream. Make sure to disable wakeup on probe failure to avoid leaking the wakeup source. Fixes: fd913ef7ce61 ("Bluetooth: btusb: Add out-of-band wakeup support") Cc: stable@vger.kernel.org # 4.11 Cc: Rajat Jain <rajatja@google.com> Signed-off-by: Johan Hovold <johan@kernel.org> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-07-18Bluetooth: btusb: fix use-after-free on marvell probe failureJohan Hovold1-3/+5
commit c5b600a3c05b1a7a110d558df935a8fc8a471c79 upstream. Make sure to stop any TX URBs submitted during Marvell OOB wakeup configuration on later probe failures to avoid use-after-free in the completion callback. This issue was reported by Sashiko while reviewing a fix for a wakeup source leak in the btusb probe errors paths. Link: https://sashiko.dev/#/patchset/20260402092704.2346710-1-johan%40kernel.org Fixes: a4ccc9e33d2f ("Bluetooth: btusb: Configure Marvell to use one of the pins for oob wakeup") Cc: stable@vger.kernel.org # 4.11 Cc: Rajat Jain <rajatja@google.com> Signed-off-by: Johan Hovold <johan@kernel.org> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-07-18Bluetooth: btusb: fix use-after-free on registration failureJohan Hovold1-1/+10
commit eedc6867ebad73edbfaf9a0a65fbef7115cc4753 upstream. Make sure to release the sibling interfaces in case controller registration fails to avoid use-after-free and double-free when they are eventually disconnected. This issue was reported by Sashiko while reviewing a fix for a wakeup source leak in the btusb probe errors paths. Link: https://sashiko.dev/#/patchset/20260402092704.2346710-1-johan%40kernel.org Fixes: 9bfa35fe422c ("[Bluetooth] Add SCO support to btusb driver") Fixes: 9d08f50401ac ("Bluetooth: btusb: Add support for Broadcom LM_DIAG interface") Cc: stable@vger.kernel.org # 2.6.27 Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de> Signed-off-by: Johan Hovold <johan@kernel.org> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-07-18Bluetooth: btusb: Add USB ID 2c4e:0128 for Mercusys MA60XNBZenm Chen1-0/+2
commit 88b4d528eda4ac71c2952b3458f2abbc80a91cd2 upstream. Add USB ID 2c4e:0128 for Mercusys MA60XNB, an RTL8851BU-based Wi-Fi + Bluetooth adapter. The information in /sys/kernel/debug/usb/devices about the Bluetooth device is listed as the below: T: Bus=03 Lev=01 Prnt=01 Port=04 Cnt=01 Dev#= 3 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=2c4e ProdID=0128 Rev= 0.00 S: Manufacturer=Realtek S: Product=802.11ax WLAN Adapter S: SerialNumber=00e04c000001 C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=500mA A: FirstIf#= 0 IfCount= 2 Cls=e0(wlcon) Sub=01 Prot=01 I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms I: If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 63 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 63 Ivl=1ms I:* If#= 2 Alt= 0 #EPs= 8 Cls=ff(vend.) Sub=ff Prot=ff Driver=rtw89_8851bu E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=09(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=0a(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=0b(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=0c(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms Cc: stable@vger.kernel.org # 6.6.x Signed-off-by: Zenm Chen <zenmchen@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-05-27Bluetooth: hci_qca: Use 100 ms SSR delay for rampatch and NVM loadingShuai Zhang1-2/+2
When bt_en is pulled high by hardware, the host does not re-download the firmware after SSR. The controller loads the rampatch and NVM internally. On HMT chip, the rampatch is ~264 KB and the NVM is ~9.4 KB. The loading process takes approximately 70 ms. The previous 50 ms delay is too short, causing the controller to not respond to the reset command sent by the host, which leads to BT initialization failure: Bluetooth: hci0: QCA memdump Done, received 458752, total 458752 Bluetooth: hci0: mem_dump_status: 2 Bluetooth: hci0: Opcode 0x0c03 failed: -110 Increase the delay to 100 ms, which was confirmed as a safe value by the controller, to ensure the controller has finished loading the firmware before the host sends commands. Steps to reproduce: 1. Trigger SSR and wait for SSR to complete: hcitool cmd 0x3f 0c 26 2. Run "bluetoothctl power on" and observe that BT fails to start. Fixes: fce1a9244a0f ("Bluetooth: hci_qca: Fix SSR (SubSystem Restart) fail when BT_EN is pulled up by hw") Cc: stable@vger.kernel.org Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Signed-off-by: Shuai Zhang <shuai.zhang@oss.qualcomm.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-05-27Bluetooth: btusb: Allow firmware re-download when version matchesShuai Zhang1-1/+7
The Bluetooth host decides whether to download firmware by reading the controller firmware download completion flag and firmware version information. If a USB error occurs during the firmware download process (for example due to a USB disconnect), the download is aborted immediately. An incomplete firmware transfer does not cause the controller to set the download completion flag, but the firmware version information may be updated at an early stage of the download process. In this case, after USB reconnection, the host attempts to re-download the firmware because the download completion flag is not set. However, since the controller reports the same firmware version as the target firmware, the download is skipped. This ultimately results in the firmware not being properly updated on the controller. This change removes the restriction that skips firmware download when the versions are equal. It covers scenarios where the USB connection can be disconnected at any time and ensures that firmware download can be retriggered after USB reconnection, allowing the Bluetooth firmware to be correctly and completely updated. Fixes: 3267c884cefa ("Bluetooth: btusb: Add support for QCA ROME chipset family") Cc: stable@vger.kernel.org Signed-off-by: Shuai Zhang <shuai.zhang@oss.qualcomm.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-05-20Bluetooth: hci_uart: fix UAFs and race conditions in close and init pathsMingyu Wang1-8/+40
Vulnerabilities leading to Use-After-Free (UAF) and Null Pointer Dereference (NPD) conditions were observed in the lifecycle management of hci_uart. The primary issue arises because the workqueues (init_ready and write_work) are only flushed/cancelled if the HCI_UART_PROTO_READY flag is set during TTY close. If a hangup occurs before setup completes, hci_uart_tty_close() skips the teardown of these workqueues and proceeds to free the `hu` struct. When the scheduled work executes later, it blindly dereferences the freed `hu` struct. Furthermore, several data races and UAFs were identified in the teardown sequence: 1. Calling hci_uart_flush() from hci_uart_close() without effectively disabling write_work causes a race condition where both can concurrently double-free hu->tx_skb. This happens because protocol timers can concurrently invoke hci_uart_tx_wakeup() and requeue write_work. 2. Calling hci_free_dev(hdev) before hu->proto->close(hu) causes a UAF when vendor specific protocol close callbacks dereference hu->hdev. 3. In the initialization error paths, failing to take the proto_lock write lock before clearing PROTO_READY leads to races with active readers. Additionally, hci_uart_tty_receive() accesses hu->hdev outside the read lock, leading to UAFs if the initialization error path frees hdev concurrently. Fix these synchronization and lifecycle issues by: 1. Re-ordering hci_uart_tty_close() to clear HCI_UART_PROTO_READY first, followed immediately by a cancel_work_sync(&hu->write_work). Clearing the flag locks out concurrent protocol timers from successfully invoking hci_uart_tx_wakeup(), effectively rendering the cancellation permanent and preventing the tx_skb double-free. 2. Note: Clearing PROTO_READY early causes hci_uart_close() to skip hu->proto->flush(). This is perfectly safe in the tty_close path because hu->proto->close() executes shortly after, which intrinsically purges all protocol SKB queues and tears down the state. 3. Relocating hu->proto->close(hu) strictly prior to hci_free_dev(hdev) across all close and error paths to prevent vendor-level UAFs. 4. Moving the hdev->stat.byte_rx increment in hci_uart_tty_receive() inside the proto_lock read-side critical section to safely synchronize with device unregistration. 5. Adding cancel_work_sync(&hu->write_work) to hci_uart_close() to safely flush the workqueue before hci_uart_flush() is invoked via the HCI core. 6. Utilizing cancel_work_sync() instead of disable_work_sync() across all paths to prevent permanently breaking user-space retry capabilities. Fixes: 3b799254cf6f ("Bluetooth: hci_uart: Cancel init work before unregistering") Cc: stable@vger.kernel.org Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-05-20Bluetooth: btmtk: fix urb->setup_packet leak in error pathsJiajia Liu1-0/+2
The setup_packet of control urb is not freed if usb_submit_urb fails or the submitted urb is killed. Add free in these two paths. Fixes: a1c49c434e150 ("Bluetooth: btusb: Add protocol support for MediaTek MT7668U USB devices") Signed-off-by: Jiajia Liu <liujiajia@kylinos.cn> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-05-20Bluetooth: btintel_pcie: Fix incorrect MAC access programmingKiran K2-17/+6
btintel_pcie_get_mac_access() and btintel_pcie_release_mac_access() were programming STOP_MAC_ACCESS_DIS and XTAL_CLK_REQ in addition to the MAC_ACCESS_REQ handshake. These bits are not part of the host MAC-access handshake on the supported parts; the driver was programming them incorrectly. Drop the writes so the register update contains only the bits the controller actually consumes. Fixes: b9465e6670a2 ("Bluetooth: btintel_pcie: Read hardware exception data") Signed-off-by: Kiran K <kiran.k@intel.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-05-14Bluetooth: hci_qca: Convert timeout from jiffies to msShuai Zhang1-17/+16
Since the timer uses jiffies as its unit rather than ms, the timeout value must be converted from ms to jiffies when configuring the timer. Otherwise, the intended 8s timeout is incorrectly set to approximately 33s. To improve readability, embed msecs_to_jiffies() directly in the macro definitions and drop the _MS suffix from macros that now yield jiffies values: MEMDUMP_TIMEOUT, FW_DOWNLOAD_TIMEOUT, IBS_DISABLE_SSR_TIMEOUT, CMD_TRANS_TIMEOUT, and IBS_BTSOC_TX_IDLE_TIMEOUT. IBS_WAKE_RETRANS_TIMEOUT_MS and IBS_HOST_TX_IDLE_TIMEOUT_MS are intentionally left unchanged. Their values are stored in the struct fields wake_retrans and tx_idle_delay, which hold ms values at runtime and can be modified via debugfs. The msecs_to_jiffies() conversion happens at each call site against the field value, so it cannot be embedded in the macro. Wake timer depends on commit c347ca17d62a Cc: stable@vger.kernel.org Fixes: d841502c79e3 ("Bluetooth: hci_qca: Collect controller memory dump during SSR") Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de> Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> Signed-off-by: Shuai Zhang <shuai.zhang@oss.qualcomm.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-05-14Bluetooth: btmtk: accept too short WMT FUNC_CTRL eventsPauli Virtanen1-2/+2
MT7925 (USB ID 0e8d:e025) on fw version 20260106153314 sends WMT FUNC_CTRL events that are missing the status field. Prior to commit 006b9943b982 ("Bluetooth: btmtk: validate WMT event SKB length before struct access") the status was read from out-of-bounds of SKB data, which usually would result to success with BTMTK_WMT_ON_UNDONE, although I don't know the intent here. The bounds check added in that commit returns with error instead, producing "Bluetooth: hci0: Failed to send wmt func ctrl (-22)" and makes the device unusable. Fix the regression by interpreting too short packet as status BTMTK_WMT_ON_UNDONE, which makes the device work normally again. Fixes: 634a4408c061 ("Bluetooth: btmtk: validate WMT event SKB length before struct access") Signed-off-by: Pauli Virtanen <pav@iki.fi> Tested-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com> # MT7922 (0489:e0e2) Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-05-06Bluetooth: virtio_bt: validate rx pkt_type header lengthMichael Bommarito1-3/+20
virtbt_rx_handle() reads the leading pkt_type byte from the RX skb and forwards the remainder to hci_recv_frame() for every event/ACL/SCO/ISO type, without checking that the remaining payload is at least the fixed HCI header for that type. After the preceding patch bounds the backend-supplied used.len to [1, VIRTBT_RX_BUF_SIZE], a one-byte completion still reaches hci_recv_frame() with skb->len already pulled to 0. If the byte happened to be HCI_ACLDATA_PKT, the ACL-vs-ISO classification fast-path in hci_dev_classify_pkt_type() dereferences hci_acl_hdr(skb)->handle whenever the HCI device has an active CIS_LINK, BIS_LINK, or PA_LINK connection, reading two bytes of uninitialized RX-buffer data. The same hazard exists for every packet type the driver accepts because none of the switch cases in virtbt_rx_handle() check skb->len against the per-type minimum HCI header size before handing the frame to the core. After stripping pkt_type, require skb->len to cover the fixed header size for the selected type (event 2, ACL 4, SCO 3, ISO 4) before calling hci_recv_frame(); drop ratelimited otherwise. Unknown pkt_type values still take the original kfree_skb() default path. Use bt_dev_err_ratelimited() because both the length and pkt_type values come from an untrusted backend that can otherwise flood the kernel log. Fixes: 160fbcf3bfb9 ("Bluetooth: virtio_bt: Use skb_put to set length") Cc: stable@vger.kernel.org Cc: Soenke Huster <soenke.huster@eknoes.de> Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com> Assisted-by: Claude:claude-opus-4-7 Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-05-06Bluetooth: virtio_bt: clamp rx length before skb_putMichael Bommarito1-4/+12
virtbt_rx_work() calls skb_put(skb, len) where len comes directly from virtqueue_get_buf() with no validation against the buffer we posted to the device. The RX skb is allocated in virtbt_add_inbuf() and exposed to virtio as exactly 1000 bytes via sg_init_one(). Checking len against skb_tailroom(skb) is not sufficient because alloc_skb() can leave more tailroom than the 1000 bytes actually handed to the device. A malicious or buggy backend can therefore report used.len between 1001 and skb_tailroom(skb), causing skb_put() to include uninitialized kernel heap bytes that were never written by the device. The same path also accepts len == 0, in which case skb_put(skb, 0) leaves the skb empty but virtbt_rx_handle() still reads the pkt_type byte from skb->data, consuming uninitialized memory. Define VIRTBT_RX_BUF_SIZE once and reuse it in alloc_skb() and sg_init_one(), and gate virtbt_rx_work() on that same constant so the bound checked matches the buffer actually exposed to the device. Reject used.len == 0 in the same gate so an empty completion can no longer reach virtbt_rx_handle(). Use bt_dev_err_ratelimited() because the length value comes from an untrusted backend that can otherwise flood the kernel log. Same class of bug as commit c04db81cd028 ("net/9p: Fix buffer overflow in USB transport layer"), which hardened the USB 9p transport against unchecked device-reported length. Fixes: 160fbcf3bfb9 ("Bluetooth: virtio_bt: Use skb_put to set length") Cc: stable@vger.kernel.org Cc: Soenke Huster <soenke.huster@eknoes.de> Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com> Assisted-by: Claude:claude-opus-4-7 Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-05-06Bluetooth: btmtk: validate WMT event SKB length before struct accessTristan Madani1-2/+13
btmtk_usb_hci_wmt_sync() casts the WMT event response SKB data to struct btmtk_hci_wmt_evt (7 bytes) and struct btmtk_hci_wmt_evt_funcc (9 bytes) without first checking that the SKB contains enough data. A short firmware response causes out-of-bounds reads from SKB tailroom. Use skb_pull_data() to validate and advance past the base WMT event header. For the FUNC_CTRL case, pull the additional status field bytes before accessing them. Fixes: d019930b0049 ("Bluetooth: btmtk: move btusb_mtk_hci_wmt_sync to btmtk.c") Cc: stable@vger.kernel.org Signed-off-by: Tristan Madani <tristan@talencesecurity.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-05-06Bluetooth: hci_uart: Fix NULL deref in recv callbacks when priv is uninitializedAurelien DESBRIERES4-0/+12
When a fault is injected during hci_uart line discipline setup, the proto open() callback may fail leaving hu->priv as NULL. A subsequent TIOCSTI ioctl can trigger the recv() callback before priv is initialized, causing a NULL pointer dereference. Fix all four affected HCI UART protocol drivers by adding a NULL check on hu->priv at the start of their recv() callbacks: h4, h5, ath and bcsp. Reported-by: syzbot+ff30eeab8e07b37d524e@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=ff30eeab8e07b37d524e Signed-off-by: Aurelien DESBRIERES <aurelien@hackers.camp> Assisted-by: Claude:claude-sonnet-4-6 Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-05-06Bluetooth: btintel_pcie: treat boot stage bit 12 as warningSai Teja Aluvala2-4/+11
CSR boot stage register bit 12 is documented as a device warning, not a fatal error. Rename the bit definition accordingly and stop including it in btintel_pcie_in_error(). This keeps warning-only boot stage values from being classified as errors while preserving abort-handler state as the actual error condition. Fixes: 190377500fde ("Bluetooth: btintel_pcie: Dump debug registers on error") Signed-off-by: Kiran K <kiran.k@intel.com> Signed-off-by: Sai Teja Aluvala <aluvala.sai.teja@intel.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-04-13Bluetooth: hci_qca: Fix missing wakeup during SSR memdump handlingShuai Zhang1-2/+2
When a Bluetooth controller encounters a coredump, it triggers the Subsystem Restart (SSR) mechanism. The controller first reports the coredump data and, once the upload is complete, sends a hw_error event. The host relies on this event to proceed with subsequent recovery actions. If the host has not finished processing the coredump data when the hw_error event is received, it waits until either the processing is complete or the 8-second timeout expires before handling the event. The current implementation clears QCA_MEMDUMP_COLLECTION using clear_bit(), which does not wake up waiters sleeping in wait_on_bit_timeout(). As a result, the waiting thread may remain blocked until the timeout expires even if the coredump collection has already completed. Fix this by clearing QCA_MEMDUMP_COLLECTION with clear_and_wake_up_bit(), which also wakes up the waiting thread and allows the hw_error handling to proceed immediately. Test case: - Trigger a controller coredump using: hcitool cmd 0x3f 0c 26 - Tested on QCA6390. - Capture HCI logs using btmon. - Verify that the delay between receiving the hw_error event and initiating the power-off sequence is reduced compared to the timeout-based behavior. Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com> Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de> Signed-off-by: Shuai Zhang <shuai.zhang@oss.qualcomm.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-04-13Bluetooth: btintel_pcie: use strscpy to copy plain stringsThorsten Blum1-2/+2
Use strscpy() instead of snprintf() to copy plain strings with no format specifiers. Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-04-13Bluetooth: btintel_pcie: Align shared DMA memory to 128 bytesKiran K2-44/+53
Align each descriptor/index/context region to 128 bytes before calculating the total DMA pool size. This ensures the memory layout shared with firmware meets the 128-byte alignment requirement. The DMA pool alignment is also set to 128 bytes to match the firmware expectation for all shared structures. Signed-off-by: Kiran K <kiran.k@intel.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-04-13Bluetooth: hci_ll: Enable BROKEN_ENHANCED_SETUP_SYNC_CONN for WL183xStefano Radaelli1-0/+10
TI WL183x controllers advertise support for the HCI Enhanced Setup Synchronous Connection command, but SCO setup fails when the enhanced path is used. The only working configuration is to fall back to the legacy HCI Setup Synchronous Connection (0x0028). This matches the scenario described in commit 05abad857277 ("Bluetooth: HCI: Add HCI_QUIRK_BROKEN_ENHANCED_SETUP_SYNC_CONN quirk"). Enable HCI_QUIRK_BROKEN_ENHANCED_SETUP_SYNC_CONN automatically for devices compatible with: - ti,wl1831-st - ti,wl1835-st - ti,wl1837-st Signed-off-by: Stefano Radaelli <stefano.r@variscite.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-04-13Bluetooth: btusb: MediaTek MT7922: Add VID 0489 & PID e11dKamiyama Chiaki1-0/+2
Add VID 0489 & PID e11d for MediaTek MT7922 USB Bluetooth chip. Found in Dynabook GA/ZY (W6GAZY5RCL). The information in /sys/kernel/debug/usb/devices about the Bluetooth device is listed as the below. T: Bus=03 Lev=01 Prnt=01 Port=03 Cnt=02 Dev#= 3 Spd=480 MxCh= 0 D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0489 ProdID=e11d Rev= 1.00 S: Manufacturer=MediaTek Inc. S: Product=Wireless_Device S: SerialNumber=000000000 Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de> Signed-off-by: Kamiyama Chiaki <nercone@nercone.dev> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-04-13Bluetooth: btmtk: hide unused btmtk_mt6639_devs[] arrayArnd Bergmann1-16/+16
When USB support is disabled, the array is not referenced anywhere, causing a warning: drivers/bluetooth/btmtk.c:35:3: error: 'btmtk_mt6639_devs' defined but not used [-Werror=unused-const-variable=] 35 | } btmtk_mt6639_devs[] = { | ^~~~~~~~~~~~~~~~~ Move it into the #ifdef block. Fixes: 28b7c5a6db74 ("Bluetooth: btmtk: Add MT6639 (MT7927) Bluetooth support") Signed-off-by: Arnd Bergmann <arnd@arndb.de> Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-04-13Bluetooth: btusb: Add MT7927 ID for ASUS X870E / ProArt X870E-CreatorJavier Tia1-0/+2
Add USB device ID 13d3:3588 (IMC Networks/Azurewave) for the MediaTek MT7927 (Filogic 380) Bluetooth interface found on the ASUS ROG STRIX X870E-E GAMING WIFI and ASUS ProArt X870E-Creator WiFi motherboards. The information in /sys/kernel/debug/usb/devices about the Bluetooth device is listed as the below. T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 5 Spd=480 MxCh= 0 D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=13d3 ProdID=3588 Rev= 1.00 S: Manufacturer=MediaTek Inc. S: Product=Wireless_Device S: SerialNumber=000000000 C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA A: FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01 I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=125us E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=8a(I) Atr=03(Int.) MxPS= 512 Ivl=125us E: Ad=0a(O) Atr=03(Int.) MxPS= 512 Ivl=125us Link: https://bugzilla.kernel.org/show_bug.cgi?id=221096 Link: https://github.com/openwrt/mt76/issues/927 Signed-off-by: Javier Tia <floss@jetm.me> Tested-by: Jose Tiburcio Ribeiro Netto <jnetto@mineiro.io> Tested-by: Ivan Lubnin <lubnin.ivan@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-04-13Bluetooth: btusb: Add MT7927 ID for TP-Link Archer TBE550EJavier Tia1-0/+2
Add USB device ID 0489:e116 (Foxconn/Hon Hai) for the MediaTek MT7927 (Filogic 380) Bluetooth interface found on the TP-Link Archer TBE550E PCIe adapter. The information in /sys/kernel/debug/usb/devices about the Bluetooth device is listed as the below. T: Bus=01 Lev=01 Prnt=01 Port=05 Cnt=04 Dev#= 5 Spd=480 MxCh= 0 D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0489 ProdID=e116 Rev= 1.00 S: Manufacturer=MediaTek Inc. S: Product=Wireless_Device S: SerialNumber=000000000 C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA A: FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01 I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=125us E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb ... I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=8a(I) Atr=03(Int.) MxPS= 512 Ivl=125us E: Ad=0a(O) Atr=03(Int.) MxPS= 512 Ivl=125us Link: https://bugzilla.kernel.org/show_bug.cgi?id=221096 Link: https://github.com/openwrt/mt76/issues/927 Signed-off-by: Javier Tia <floss@jetm.me> Tested-by: Thibaut FRANCOIS <tibo@humeurlibre.fr> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-04-13Bluetooth: btusb: Add MT7927 ID for MSI X870E Ace MaxJavier Tia1-0/+2
Add USB device ID 0489:e110 (Foxconn/Hon Hai) for the MediaTek MT7927 (Filogic 380) Bluetooth interface found on the MSI X870E Ace Max motherboard. The information in /sys/kernel/debug/usb/devices about the Bluetooth device is listed as the below. T: Bus=01 Lev=01 Prnt=01 Port=05 Cnt=04 Dev#= 5 Spd=480 MxCh= 0 D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0489 ProdID=e110 Rev= 1.00 S: Manufacturer=MediaTek Inc. S: Product=Wireless_Device S: SerialNumber=000000000 C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA A: FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01 I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=125us E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb ... I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=8a(I) Atr=03(Int.) MxPS= 512 Ivl=125us E: Ad=0a(O) Atr=03(Int.) MxPS= 512 Ivl=125us Link: https://bugzilla.kernel.org/show_bug.cgi?id=221096 Link: https://github.com/openwrt/mt76/issues/927 Signed-off-by: Javier Tia <floss@jetm.me> Tested-by: Nitin Gurram <nitin.reddy88@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-04-13Bluetooth: btusb: Add MT7927 ID for Gigabyte Z790 AORUS MASTER XJavier Tia1-0/+2
Add USB device ID 0489:e10f (Foxconn/Hon Hai) for the MediaTek MT7927 (Filogic 380) Bluetooth interface found on the Gigabyte Z790 AORUS MASTER X motherboard. The information in /sys/kernel/debug/usb/devices about the Bluetooth device is listed as the below. T: Bus=01 Lev=01 Prnt=01 Port=05 Cnt=04 Dev#= 5 Spd=480 MxCh= 0 D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0489 ProdID=e10f Rev= 1.00 S: Manufacturer=MediaTek Inc. S: Product=Wireless_Device S: SerialNumber=000000000 C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA A: FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01 I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=125us E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb ... I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=8a(I) Atr=03(Int.) MxPS= 512 Ivl=125us E: Ad=0a(O) Atr=03(Int.) MxPS= 512 Ivl=125us Link: https://bugzilla.kernel.org/show_bug.cgi?id=221096 Link: https://github.com/openwrt/mt76/issues/927 Signed-off-by: Javier Tia <floss@jetm.me> Tested-by: Chapuis Dario <chapuisdario4@gmail.com> Tested-by: Evgeny Kapusta <3193631@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-04-13Bluetooth: btusb: Add MT7927 ID for Lenovo Legion Pro 7 16ARX9Javier Tia1-0/+2
Add USB device ID 0489:e0fa (Foxconn/Hon Hai) for the MediaTek MT7927 (Filogic 380) Bluetooth interface found on the Lenovo Legion Pro 7 16ARX9 laptop. The information in /sys/kernel/debug/usb/devices about the Bluetooth device is listed as the below. T: Bus=01 Lev=01 Prnt=01 Port=05 Cnt=04 Dev#= 5 Spd=480 MxCh= 0 D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0489 ProdID=e0fa Rev= 1.00 S: Manufacturer=MediaTek Inc. S: Product=Wireless_Device S: SerialNumber=000000000 C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA A: FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01 I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=125us E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb ... I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=8a(I) Atr=03(Int.) MxPS= 512 Ivl=125us E: Ad=0a(O) Atr=03(Int.) MxPS= 512 Ivl=125us Link: https://bugzilla.kernel.org/show_bug.cgi?id=221096 Link: https://github.com/openwrt/mt76/issues/927 Signed-off-by: Javier Tia <floss@jetm.me> Tested-by: Llewellyn Curran <melinko2003@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-04-13Bluetooth: btusb: Add MT7927 ID for ASUS ROG Crosshair X870E HeroJavier Tia1-0/+2
Add USB device ID 0489:e13a (Foxconn/Hon Hai) for the MediaTek MT7927 (Filogic 380) Bluetooth interface found on the ASUS ROG Crosshair X870E Hero WiFi motherboard. The information in /sys/kernel/debug/usb/devices about the Bluetooth device is listed as the below. T: Bus=01 Lev=01 Prnt=01 Port=05 Cnt=04 Dev#= 5 Spd=480 MxCh= 0 D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0489 ProdID=e13a Rev= 1.00 S: Manufacturer=MediaTek Inc. S: Product=Wireless_Device S: SerialNumber=000000000 C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA A: FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01 I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=125us E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb ... I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=8a(I) Atr=03(Int.) MxPS= 512 Ivl=125us E: Ad=0a(O) Atr=03(Int.) MxPS= 512 Ivl=125us Link: https://bugzilla.kernel.org/show_bug.cgi?id=221096 Link: https://github.com/openwrt/mt76/issues/927 Signed-off-by: Javier Tia <floss@jetm.me> Tested-by: Jose Tiburcio Ribeiro Netto <jnetto@mineiro.io> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-04-13Bluetooth: btmtk: fix ISO interface setup for single alt settingJavier Tia1-1/+2
Some MT6639 Bluetooth USB interfaces (e.g. IMC Networks 13d3:3588 on ASUS ROG STRIX X870E-E and ProArt X870E-Creator boards) expose only a single alternate setting (alt 0) on the ISO interface. The driver unconditionally requests alt setting 1, which fails with EINVAL on these devices, causing a ~20 second initialization delay and no LE audio support. Check the number of available alternate settings before selecting one. If only alt 0 exists, use it; otherwise request alt 1 as before. Closes: https://github.com/jetm/mediatek-mt7927-dkms/pull/39 Signed-off-by: Javier Tia <floss@jetm.me> Reported-by: Ryan Gilbert <xelnaga@gmail.com> Tested-by: Ryan Gilbert <xelnaga@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-04-13Bluetooth: btmtk: Add MT6639 (MT7927) Bluetooth supportJavier Tia3-8/+61
The MediaTek MT7927 (Filogic 380) combo WiFi 7 + BT 5.4 module uses hardware variant 0x6639 for its Bluetooth subsystem. Without this patch, the chip fails with "Unsupported hardware variant (00006639)" or hangs during firmware download. Three changes are needed to support MT6639: 1. CHIPID workaround: On some boards the BT USB MMIO register reads 0x0000 for dev_id, causing the driver to skip the 0x6639 init path. Force dev_id to 0x6639 only when the USB VID/PID matches a known MT6639 device, avoiding misdetection if a future chip also reads zero. This follows the WiFi-side pattern that uses PCI device IDs to scope the same workaround. 2. Firmware naming: MT6639 uses firmware version prefix "2_1" instead of "1_1" used by MT7925 and other variants. The firmware path is mediatek/mt7927/BT_RAM_CODE_MT6639_2_1_hdr.bin, using the mt7927 directory to match the WiFi firmware convention. The filename will likely change to use MT7927 once MediaTek submits a dedicated Linux firmware binary. 3. Section filtering: The MT6639 firmware binary contains 9 sections, but only sections with (dlmodecrctype & 0xff) == 0x01 are Bluetooth-related. Sending the remaining WiFi/other sections causes an irreversible BT subsystem hang requiring a full power cycle. This matches the Windows driver behavior observed via USB captures. Also add 0x6639 to the reset register (CONNV3) and firmware setup switch cases alongside the existing 0x7925 handling. Link: https://bugzilla.kernel.org/show_bug.cgi?id=221096 Link: https://github.com/openwrt/mt76/issues/927 Reported-by: Ryan Gilbert <xelnaga@gmail.com> Signed-off-by: Javier Tia <floss@jetm.me> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-04-13Bluetooth: btmtk: refactor endpoint lookupJohan Hovold1-24/+5
Use the common USB helper for looking up bulk and interrupt endpoints instead of open coding. Signed-off-by: Johan Hovold <johan@kernel.org> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-04-13Bluetooth: btusb: refactor endpoint lookupJohan Hovold1-43/+8
Use the common USB helper for looking up bulk and interrupt endpoints instead of open coding. Signed-off-by: Johan Hovold <johan@kernel.org> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-04-13Bluetooth: hci_ldisc: Clear HCI_UART_PROTO_INIT on errorJonathan Rissanen1-0/+3
When hci_register_dev() fails in hci_uart_register_dev() HCI_UART_PROTO_INIT is not cleared before calling hu->proto->close(hu) and setting hu->hdev to NULL. This means incoming UART data will reach the protocol-specific recv handler in hci_uart_tty_receive() after resources are freed. Clear HCI_UART_PROTO_INIT with a write lock before calling hu->proto->close() and setting hu->hdev to NULL. The write lock ensures all active readers have completed and no new reader can enter the protocol recv path before resources are freed. This allows the protocol-specific recv functions to remove the "HCI_UART_REGISTERED" guard without risking a null pointer dereference if hci_register_dev() fails. Fixes: 5df5dafc171b ("Bluetooth: hci_uart: Fix another race during initialization") Signed-off-by: Jonathan Rissanen <jonathan.rissanen@axis.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>