Hi Ying, On Thu, May 23, 2024 at 2:09 AM Ying Hsu <yinghsu@xxxxxxxxxxxx> wrote: > > When HCI raw sockets are opened, the Bluetooth kernel module doesn't > track CIS/BIS connections. User-space applications have to identify > ISO data by maintaining connection information and look up the mapping > for each ACL data packet received. Besides, btsnoop log captured in > kernel couldn't tell ISO data from ACL data in this case. > > To avoid additional lookups, this patch introduces vendor-specific > packet classification for Intel BT controllers to distinguish > ISO data packets from ACL data packets. > > Signed-off-by: Ying Hsu <yinghsu@xxxxxxxxxxxx> > --- > Tested LE audio unicast recording on a ChromeOS device with Intel AX211 > > Changes in v2: > - Adds vendor-specific packet classificaton in hci_dev. > - Keeps reclassification in hci_recv_frame. > > drivers/bluetooth/btusb.c | 19 +++++++++++++++++++ > include/net/bluetooth/hci_core.h | 1 + > net/bluetooth/hci_core.c | 16 ++++++++++++++++ > 3 files changed, 36 insertions(+) > > diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c > index 79aefdb3324d..75561e749c50 100644 > --- a/drivers/bluetooth/btusb.c > +++ b/drivers/bluetooth/btusb.c > @@ -966,6 +966,24 @@ static void btusb_intel_cmd_timeout(struct hci_dev *hdev) > gpiod_set_value_cansleep(reset_gpio, 0); > } > > +#define BT_USB_INTEL_ISODATA_HANDLE_BASE 0x900 > + > +static u8 btusb_intel_classify_pkt_type(struct hci_dev *hdev, struct sk_buff *skb) We might as well move this to btintel.c since it should not be USB specific. > +{ > + /* > + * Distinguish ISO data packets form ACL data packets > + * based on their conneciton handle value range. > + */ > + if (hci_skb_pkt_type(skb) == HCI_ACLDATA_PKT) { > + __u16 handle = __le16_to_cpu(hci_acl_hdr(skb)->handle); > + > + if (hci_handle(handle) >= BT_USB_INTEL_ISODATA_HANDLE_BASE) > + return HCI_ISODATA_PKT; > + } > + > + return hci_skb_pkt_type(skb); > +} > + > #define RTK_DEVCOREDUMP_CODE_MEMDUMP 0x01 > #define RTK_DEVCOREDUMP_CODE_HW_ERR 0x02 > #define RTK_DEVCOREDUMP_CODE_CMD_TIMEOUT 0x03 > @@ -4451,6 +4469,7 @@ static int btusb_probe(struct usb_interface *intf, > /* Transport specific configuration */ > hdev->send = btusb_send_frame_intel; > hdev->cmd_timeout = btusb_intel_cmd_timeout; > + hdev->classify_pkt_type = btusb_intel_classify_pkt_type; > > if (id->driver_info & BTUSB_INTEL_NO_WBS_SUPPORT) > btintel_set_flag(hdev, INTEL_ROM_LEGACY_NO_WBS_SUPPORT); > diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h > index 9231396fe96f..7b7068a84ff7 100644 > --- a/include/net/bluetooth/hci_core.h > +++ b/include/net/bluetooth/hci_core.h > @@ -649,6 +649,7 @@ struct hci_dev { > int (*get_codec_config_data)(struct hci_dev *hdev, __u8 type, > struct bt_codec *codec, __u8 *vnd_len, > __u8 **vnd_data); > + u8 (*classify_pkt_type)(struct hci_dev *hdev, struct sk_buff *skb); > }; > > #define HCI_PHY_HANDLE(handle) (handle & 0xff) > diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c > index b3ee9ff17624..8b817a99cefd 100644 > --- a/net/bluetooth/hci_core.c > +++ b/net/bluetooth/hci_core.c > @@ -2941,15 +2941,31 @@ int hci_reset_dev(struct hci_dev *hdev) > } > EXPORT_SYMBOL(hci_reset_dev); > > +static u8 hci_dev_classify_pkt_type(struct hci_dev *hdev, struct sk_buff *skb) > +{ > + if (hdev->classify_pkt_type) > + return hdev->classify_pkt_type(hdev, skb); > + > + return hci_skb_pkt_type(skb); > +} > + > /* Receive frame from HCI drivers */ > int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb) > { > + u8 dev_pkt_type; > + > if (!hdev || (!test_bit(HCI_UP, &hdev->flags) > && !test_bit(HCI_INIT, &hdev->flags))) { > kfree_skb(skb); > return -ENXIO; > } > > + /* Check if the driver agree with packet type classification */ > + dev_pkt_type = hci_dev_classify_pkt_type(hdev, skb); > + if (hci_skb_pkt_type(skb) != dev_pkt_type) { > + hci_skb_pkt_type(skb) = dev_pkt_type; > + } > + > switch (hci_skb_pkt_type(skb)) { > case HCI_EVENT_PKT: > break; > -- > 2.45.1.288.g0e0cd299f1-goog > -- Luiz Augusto von Dentz