Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Bluetooth: Introduce HCI Driver protocol

Although commit 75ddcd5ad40e ("Bluetooth: btusb: Configure altsetting
for HCI_USER_CHANNEL") has enabled the HCI_USER_CHANNEL user to send out
SCO data through USB Bluetooth chips, it's observed that with the patch
HFP is flaky on most of the existing USB Bluetooth controllers: Intel
chips sometimes send out no packet for Transparent codec; MTK chips may
generate SCO data with a wrong handle for CVSD codec; RTK could split
the data with a wrong packet size for Transparent codec; ... etc.

To address the issue above one needs to reset the altsetting back to
zero when there is no active SCO connection, which is the same as the
BlueZ behavior, and another benefit is the bus doesn't need to reserve
bandwidth when no SCO connection.

This patch adds the infrastructure that allow the user space program to
talk to Bluetooth drivers directly:
- Define the new packet type HCI_DRV_PKT which is specifically used for
communication between the user space program and the Bluetooth drviers
- hci_send_frame intercepts the packets and invokes drivers' HCI Drv
callbacks (so far only defined for btusb)
- 2 kinds of events to user space: Command Status and Command Complete,
the former simply returns the status while the later may contain
additional response data.

Cc: chromeos-bluetooth-upstreaming@chromium.org
Fixes: b16b327edb4d ("Bluetooth: btusb: add sysfs attribute to control USB alt setting")
Signed-off-by: Hsin-chen Chuang <chharry@chromium.org>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

authored by

Hsin-chen Chuang and committed by
Luiz Augusto von Dentz
04425292 c50b5666

+273 -9
+63 -6
drivers/bluetooth/btusb.c
··· 21 21 22 22 #include <net/bluetooth/bluetooth.h> 23 23 #include <net/bluetooth/hci_core.h> 24 + #include <net/bluetooth/hci_drv.h> 24 25 25 26 #include "btintel.h" 26 27 #include "btbcm.h" ··· 3801 3800 3802 3801 static DEVICE_ATTR_RW(isoc_alt); 3803 3802 3803 + static const struct { 3804 + u16 opcode; 3805 + const char *desc; 3806 + } btusb_hci_drv_supported_commands[] = { 3807 + /* Common commands */ 3808 + { HCI_DRV_OP_READ_INFO, "Read Info" }, 3809 + }; 3810 + static int btusb_hci_drv_read_info(struct hci_dev *hdev, void *data, 3811 + u16 data_len) 3812 + { 3813 + struct hci_drv_rp_read_info *rp; 3814 + size_t rp_size; 3815 + int err, i; 3816 + u16 opcode, num_supported_commands = 3817 + ARRAY_SIZE(btusb_hci_drv_supported_commands); 3818 + 3819 + rp_size = sizeof(*rp) + num_supported_commands * 2; 3820 + 3821 + rp = kmalloc(rp_size, GFP_KERNEL); 3822 + if (!rp) 3823 + return -ENOMEM; 3824 + 3825 + strscpy_pad(rp->driver_name, btusb_driver.name); 3826 + 3827 + rp->num_supported_commands = cpu_to_le16(num_supported_commands); 3828 + for (i = 0; i < num_supported_commands; i++) { 3829 + opcode = btusb_hci_drv_supported_commands[i].opcode; 3830 + bt_dev_info(hdev, 3831 + "Supported HCI Drv command (0x%02x|0x%04x): %s", 3832 + hci_opcode_ogf(opcode), 3833 + hci_opcode_ocf(opcode), 3834 + btusb_hci_drv_supported_commands[i].desc); 3835 + rp->supported_commands[i] = cpu_to_le16(opcode); 3836 + } 3837 + 3838 + err = hci_drv_cmd_complete(hdev, HCI_DRV_OP_READ_INFO, 3839 + HCI_DRV_STATUS_SUCCESS, rp, rp_size); 3840 + 3841 + kfree(rp); 3842 + return err; 3843 + } 3844 + 3845 + static const struct hci_drv_handler btusb_hci_drv_common_handlers[] = { 3846 + { btusb_hci_drv_read_info, HCI_DRV_READ_INFO_SIZE }, 3847 + }; 3848 + 3849 + static const struct hci_drv_handler btusb_hci_drv_specific_handlers[] = {}; 3850 + 3851 + static struct hci_drv btusb_hci_drv = { 3852 + .common_handler_count = ARRAY_SIZE(btusb_hci_drv_common_handlers), 3853 + .common_handlers = btusb_hci_drv_common_handlers, 3854 + .specific_handler_count = ARRAY_SIZE(btusb_hci_drv_specific_handlers), 3855 + .specific_handlers = btusb_hci_drv_specific_handlers, 3856 + }; 3857 + 3804 3858 static int btusb_probe(struct usb_interface *intf, 3805 3859 const struct usb_device_id *id) 3806 3860 { ··· 3995 3939 data->reset_gpio = reset_gpio; 3996 3940 } 3997 3941 3998 - hdev->open = btusb_open; 3999 - hdev->close = btusb_close; 4000 - hdev->flush = btusb_flush; 4001 - hdev->send = btusb_send_frame; 4002 - hdev->notify = btusb_notify; 4003 - hdev->wakeup = btusb_wakeup; 3942 + hdev->open = btusb_open; 3943 + hdev->close = btusb_close; 3944 + hdev->flush = btusb_flush; 3945 + hdev->send = btusb_send_frame; 3946 + hdev->notify = btusb_notify; 3947 + hdev->wakeup = btusb_wakeup; 3948 + hdev->hci_drv = &btusb_hci_drv; 4004 3949 4005 3950 #ifdef CONFIG_PM 4006 3951 err = btusb_config_oob_wake(hdev);
+1
include/net/bluetooth/hci.h
··· 494 494 #define HCI_EVENT_PKT 0x04 495 495 #define HCI_ISODATA_PKT 0x05 496 496 #define HCI_DIAG_PKT 0xf0 497 + #define HCI_DRV_PKT 0xf1 497 498 #define HCI_VENDOR_PKT 0xff 498 499 499 500 /* HCI packet types */
+3
include/net/bluetooth/hci_core.h
··· 31 31 #include <linux/rculist.h> 32 32 33 33 #include <net/bluetooth/hci.h> 34 + #include <net/bluetooth/hci_drv.h> 34 35 #include <net/bluetooth/hci_sync.h> 35 36 #include <net/bluetooth/hci_sock.h> 36 37 #include <net/bluetooth/coredump.h> ··· 613 612 614 613 struct list_head monitored_devices; 615 614 bool advmon_pend_notify; 615 + 616 + struct hci_drv *hci_drv; 616 617 617 618 #if IS_ENABLED(CONFIG_BT_LEDS) 618 619 struct led_trigger *power_led;
+76
include/net/bluetooth/hci_drv.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Copyright (C) 2025 Google Corporation 4 + */ 5 + 6 + #ifndef __HCI_DRV_H 7 + #define __HCI_DRV_H 8 + 9 + #include <linux/types.h> 10 + 11 + #include <net/bluetooth/bluetooth.h> 12 + #include <net/bluetooth/hci.h> 13 + 14 + struct hci_drv_cmd_hdr { 15 + __le16 opcode; 16 + __le16 len; 17 + } __packed; 18 + 19 + struct hci_drv_ev_hdr { 20 + __le16 opcode; 21 + __le16 len; 22 + } __packed; 23 + 24 + #define HCI_DRV_EV_CMD_STATUS 0x0000 25 + struct hci_drv_ev_cmd_status { 26 + __le16 opcode; 27 + __u8 status; 28 + } __packed; 29 + 30 + #define HCI_DRV_EV_CMD_COMPLETE 0x0001 31 + struct hci_drv_ev_cmd_complete { 32 + __le16 opcode; 33 + __u8 status; 34 + __u8 data[]; 35 + } __packed; 36 + 37 + #define HCI_DRV_STATUS_SUCCESS 0x00 38 + #define HCI_DRV_STATUS_UNSPECIFIED_ERROR 0x01 39 + #define HCI_DRV_STATUS_UNKNOWN_COMMAND 0x02 40 + #define HCI_DRV_STATUS_INVALID_PARAMETERS 0x03 41 + 42 + #define HCI_DRV_MAX_DRIVER_NAME_LENGTH 32 43 + 44 + /* Common commands that make sense on all drivers start from 0x0000 */ 45 + #define HCI_DRV_OP_READ_INFO 0x0000 46 + #define HCI_DRV_READ_INFO_SIZE 0 47 + struct hci_drv_rp_read_info { 48 + __u8 driver_name[HCI_DRV_MAX_DRIVER_NAME_LENGTH]; 49 + __le16 num_supported_commands; 50 + __le16 supported_commands[]; 51 + } __packed; 52 + 53 + /* Driver specific OGF (Opcode Group Field) 54 + * Commands in this group may have different meanings across different drivers. 55 + */ 56 + #define HCI_DRV_OGF_DRIVER_SPECIFIC 0x01 57 + 58 + int hci_drv_cmd_status(struct hci_dev *hdev, u16 cmd, u8 status); 59 + int hci_drv_cmd_complete(struct hci_dev *hdev, u16 cmd, u8 status, void *rp, 60 + size_t rp_len); 61 + int hci_drv_process_cmd(struct hci_dev *hdev, struct sk_buff *cmd_skb); 62 + 63 + struct hci_drv_handler { 64 + int (*func)(struct hci_dev *hdev, void *data, u16 data_len); 65 + size_t data_len; 66 + }; 67 + 68 + struct hci_drv { 69 + size_t common_handler_count; 70 + const struct hci_drv_handler *common_handlers; 71 + 72 + size_t specific_handler_count; 73 + const struct hci_drv_handler *specific_handlers; 74 + }; 75 + 76 + #endif /* __HCI_DRV_H */
+2
include/net/bluetooth/hci_mon.h
··· 51 51 #define HCI_MON_CTRL_EVENT 17 52 52 #define HCI_MON_ISO_TX_PKT 18 53 53 #define HCI_MON_ISO_RX_PKT 19 54 + #define HCI_MON_DRV_TX_PKT 20 55 + #define HCI_MON_DRV_RX_PKT 21 54 56 55 57 struct hci_mon_new_index { 56 58 __u8 type;
+2 -1
net/bluetooth/Makefile
··· 14 14 15 15 bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o \ 16 16 hci_sock.o hci_sysfs.o l2cap_core.o l2cap_sock.o smp.o lib.o \ 17 - ecdh_helper.o mgmt_util.o mgmt_config.o hci_codec.o eir.o hci_sync.o 17 + ecdh_helper.o mgmt_util.o mgmt_config.o hci_codec.o eir.o hci_sync.o \ 18 + hci_drv.o 18 19 19 20 bluetooth-$(CONFIG_DEV_COREDUMP) += coredump.o 20 21
+11
net/bluetooth/hci_core.c
··· 2911 2911 break; 2912 2912 case HCI_ISODATA_PKT: 2913 2913 break; 2914 + case HCI_DRV_PKT: 2915 + break; 2914 2916 default: 2915 2917 kfree_skb(skb); 2916 2918 return -EINVAL; ··· 3019 3017 if (!test_bit(HCI_RUNNING, &hdev->flags)) { 3020 3018 kfree_skb(skb); 3021 3019 return -EINVAL; 3020 + } 3021 + 3022 + if (hci_skb_pkt_type(skb) == HCI_DRV_PKT) { 3023 + /* Intercept HCI Drv packet here and don't go with hdev->send 3024 + * callback. 3025 + */ 3026 + err = hci_drv_process_cmd(hdev, skb); 3027 + kfree_skb(skb); 3028 + return err; 3022 3029 } 3023 3030 3024 3031 err = hdev->send(hdev, skb);
+105
net/bluetooth/hci_drv.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (C) 2025 Google Corporation 4 + */ 5 + 6 + #include <linux/skbuff.h> 7 + #include <linux/types.h> 8 + 9 + #include <net/bluetooth/bluetooth.h> 10 + #include <net/bluetooth/hci.h> 11 + #include <net/bluetooth/hci_core.h> 12 + #include <net/bluetooth/hci_drv.h> 13 + 14 + int hci_drv_cmd_status(struct hci_dev *hdev, u16 cmd, u8 status) 15 + { 16 + struct hci_drv_ev_hdr *hdr; 17 + struct hci_drv_ev_cmd_status *ev; 18 + struct sk_buff *skb; 19 + 20 + skb = bt_skb_alloc(sizeof(*hdr) + sizeof(*ev), GFP_KERNEL); 21 + if (!skb) 22 + return -ENOMEM; 23 + 24 + hdr = skb_put(skb, sizeof(*hdr)); 25 + hdr->opcode = __cpu_to_le16(HCI_DRV_EV_CMD_STATUS); 26 + hdr->len = __cpu_to_le16(sizeof(*ev)); 27 + 28 + ev = skb_put(skb, sizeof(*ev)); 29 + ev->opcode = __cpu_to_le16(cmd); 30 + ev->status = status; 31 + 32 + hci_skb_pkt_type(skb) = HCI_DRV_PKT; 33 + 34 + return hci_recv_frame(hdev, skb); 35 + } 36 + EXPORT_SYMBOL(hci_drv_cmd_status); 37 + 38 + int hci_drv_cmd_complete(struct hci_dev *hdev, u16 cmd, u8 status, void *rp, 39 + size_t rp_len) 40 + { 41 + struct hci_drv_ev_hdr *hdr; 42 + struct hci_drv_ev_cmd_complete *ev; 43 + struct sk_buff *skb; 44 + 45 + skb = bt_skb_alloc(sizeof(*hdr) + sizeof(*ev) + rp_len, GFP_KERNEL); 46 + if (!skb) 47 + return -ENOMEM; 48 + 49 + hdr = skb_put(skb, sizeof(*hdr)); 50 + hdr->opcode = __cpu_to_le16(HCI_DRV_EV_CMD_COMPLETE); 51 + hdr->len = __cpu_to_le16(sizeof(*ev) + rp_len); 52 + 53 + ev = skb_put(skb, sizeof(*ev)); 54 + ev->opcode = __cpu_to_le16(cmd); 55 + ev->status = status; 56 + 57 + skb_put_data(skb, rp, rp_len); 58 + 59 + hci_skb_pkt_type(skb) = HCI_DRV_PKT; 60 + 61 + return hci_recv_frame(hdev, skb); 62 + } 63 + EXPORT_SYMBOL(hci_drv_cmd_complete); 64 + 65 + int hci_drv_process_cmd(struct hci_dev *hdev, struct sk_buff *skb) 66 + { 67 + struct hci_drv_cmd_hdr *hdr; 68 + const struct hci_drv_handler *handler = NULL; 69 + u16 opcode, len, ogf, ocf; 70 + 71 + hdr = skb_pull_data(skb, sizeof(*hdr)); 72 + if (!hdr) 73 + return -EILSEQ; 74 + 75 + opcode = __le16_to_cpu(hdr->opcode); 76 + len = __le16_to_cpu(hdr->len); 77 + if (len != skb->len) 78 + return -EILSEQ; 79 + 80 + ogf = hci_opcode_ogf(opcode); 81 + ocf = hci_opcode_ocf(opcode); 82 + 83 + if (!hdev->hci_drv) 84 + return hci_drv_cmd_status(hdev, opcode, 85 + HCI_DRV_STATUS_UNKNOWN_COMMAND); 86 + 87 + if (ogf != HCI_DRV_OGF_DRIVER_SPECIFIC) { 88 + if (opcode < hdev->hci_drv->common_handler_count) 89 + handler = &hdev->hci_drv->common_handlers[opcode]; 90 + } else { 91 + if (ocf < hdev->hci_drv->specific_handler_count) 92 + handler = &hdev->hci_drv->specific_handlers[ocf]; 93 + } 94 + 95 + if (!handler || !handler->func) 96 + return hci_drv_cmd_status(hdev, opcode, 97 + HCI_DRV_STATUS_UNKNOWN_COMMAND); 98 + 99 + if (len != handler->data_len) 100 + return hci_drv_cmd_status(hdev, opcode, 101 + HCI_DRV_STATUS_INVALID_PARAMETERS); 102 + 103 + return handler->func(hdev, skb->data, len); 104 + } 105 + EXPORT_SYMBOL(hci_drv_process_cmd);
+10 -2
net/bluetooth/hci_sock.c
··· 234 234 if (hci_skb_pkt_type(skb) != HCI_EVENT_PKT && 235 235 hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT && 236 236 hci_skb_pkt_type(skb) != HCI_SCODATA_PKT && 237 - hci_skb_pkt_type(skb) != HCI_ISODATA_PKT) 237 + hci_skb_pkt_type(skb) != HCI_ISODATA_PKT && 238 + hci_skb_pkt_type(skb) != HCI_DRV_PKT) 238 239 continue; 239 240 } else { 240 241 /* Don't send frame to other channel types */ ··· 391 390 opcode = cpu_to_le16(HCI_MON_ISO_RX_PKT); 392 391 else 393 392 opcode = cpu_to_le16(HCI_MON_ISO_TX_PKT); 393 + break; 394 + case HCI_DRV_PKT: 395 + if (bt_cb(skb)->incoming) 396 + opcode = cpu_to_le16(HCI_MON_DRV_RX_PKT); 397 + else 398 + opcode = cpu_to_le16(HCI_MON_DRV_TX_PKT); 394 399 break; 395 400 case HCI_DIAG_PKT: 396 401 opcode = cpu_to_le16(HCI_MON_VENDOR_DIAG); ··· 1867 1860 if (hci_skb_pkt_type(skb) != HCI_COMMAND_PKT && 1868 1861 hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT && 1869 1862 hci_skb_pkt_type(skb) != HCI_SCODATA_PKT && 1870 - hci_skb_pkt_type(skb) != HCI_ISODATA_PKT) { 1863 + hci_skb_pkt_type(skb) != HCI_ISODATA_PKT && 1864 + hci_skb_pkt_type(skb) != HCI_DRV_PKT) { 1871 1865 err = -EINVAL; 1872 1866 goto drop; 1873 1867 }