]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
Bluetooth: btmtk: add event filter to filter specific event
authorChris Lu <chris.lu@mediatek.com>
Thu, 16 Apr 2026 11:16:07 +0000 (19:16 +0800)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Thu, 11 Jun 2026 18:24:37 +0000 (14:24 -0400)
Add an event filter to filter event with specific opcode to prevent BT
stack from receiving unexpected event.

Event with opcode 0xfc5d is generated when MediaTek's Bluetooth enable
firmware logs and is not expected to be sent to userspace.

Signed-off-by: Chris Lu <chris.lu@mediatek.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
drivers/bluetooth/btmtk.c
drivers/bluetooth/btmtk.h
drivers/bluetooth/btusb.c

index 8ff66b276af03e024b04c00de9580799aa4bef8e..ea7a031000cd8f7fb8acfe31d7c7019b10654d63 100644 (file)
@@ -1547,6 +1547,29 @@ int btmtk_usb_shutdown(struct hci_dev *hdev)
        return 0;
 }
 EXPORT_SYMBOL_GPL(btmtk_usb_shutdown);
+
+int btmtk_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       struct hci_event_hdr *hdr = (void *)skb->data;
+       struct hci_ev_cmd_complete *ec;
+
+       if (hdr->evt == HCI_EV_CMD_COMPLETE &&
+           skb->len >= HCI_EVENT_HDR_SIZE + sizeof(*ec)) {
+               u16 opcode;
+
+               ec = (void *)(skb->data + HCI_EVENT_HDR_SIZE);
+               opcode = __le16_to_cpu(ec->opcode);
+
+               /* Filter vendor opcode */
+               if (opcode == 0xfc5d) {
+                       kfree_skb(skb);
+                       return 0;
+               }
+       }
+
+       return hci_recv_frame(hdev, skb);
+}
+EXPORT_SYMBOL_GPL(btmtk_recv_event);
 #endif
 
 MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
index c564aedc0ce0f8360facb7847c5575149442a8d0..c83c24897c95414d396409dfcc7ebb1fa2662c4c 100644 (file)
@@ -220,6 +220,8 @@ int btmtk_usb_suspend(struct hci_dev *hdev);
 int btmtk_usb_setup(struct hci_dev *hdev);
 
 int btmtk_usb_shutdown(struct hci_dev *hdev);
+
+int btmtk_recv_event(struct hci_dev *hdev, struct sk_buff *skb);
 #else
 
 static inline int btmtk_set_bdaddr(struct hci_dev *hdev,
@@ -299,4 +301,9 @@ static inline int btmtk_usb_shutdown(struct hci_dev *hdev)
 {
        return -EOPNOTSUPP;
 }
+
+static inline int btmtk_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       return hci_recv_frame(hdev, skb);
+}
 #endif
index 7a59ed4fc42c66bac4ceefb3f7edf2e3304c3438..525d70d9cf340a2c4e6e7e9ea36430fb3b1ee0ca 100644 (file)
@@ -4252,6 +4252,7 @@ static int btusb_probe(struct usb_interface *intf,
                hci_set_quirk(hdev, HCI_QUIRK_BROKEN_ENHANCED_SETUP_SYNC_CONN);
                hci_set_quirk(hdev, HCI_QUIRK_NON_PERSISTENT_SETUP);
                data->recv_acl = btmtk_usb_recv_acl;
+               data->recv_event = btmtk_recv_event;
                data->suspend = btmtk_usb_suspend;
                data->resume = btmtk_usb_resume;
                data->disconnect = btusb_mtk_disconnect;