Re: [PATCH] Bluetooth: btusb: Add support for Qualcomm QCC2072

From: Zijun Hu

Date: Tue Jul 14 2026 - 23:11:22 EST


On 7/14/2026 10:29 PM, Luiz Augusto von Dentz wrote:
>> A. Why pre-host processing?
>>
>> QCC2072's endpoints carry non-BT frames (PERI event and PERI ACL) alongside BT frames. btusb_qcom.c must first reassemble the raw byte stream into
>> complete frames — of either kind. Once assembled, non-BT frames are intercepted and handled locally; BT frames are passed up to the stack untouched.
> Well they are still HCI commands/events aren't they? If they properly
> use the vendor command/event range I don't see a problem here. Also,
> if you pre-process, it will skip sending to the monitor, making
> debugging much harder.
>
1) Yes — they do belong to HCI we call PERI-HCI, which differs from BT-HCI frame format in wire. We
mainly use the packet indicator to distinguish it from BT-HCI.

To describe the *wire* protocol more clearly, let us use future 'USB BULK SERIALIZATION MODE' instead of current
'use EP to mark packet indicator' as an example:
PERI packet on the wire: [Packet Indicator] + [Host ID] + [...] (Host ID is a single byte; 0 =
BT host)
BT packet on the wire: [Packet Indicator] + [...]

┌───────────────────────────┬──────────────────┬────────────────────┐
│ Packet type │ BT-HCI indicator │ PERI-HCI indicator │
├───────────────────────────┼──────────────────┼────────────────────┤
│ CMD (Host → Controller) │ 0x01 │ 0x31 │
├───────────────────────────┼──────────────────┼────────────────────┤
│ ACL Data (bidirectional) │ 0x02 │ 0x32 │
├───────────────────────────┼──────────────────┼────────────────────┤
│ EVENT (Controller → Host) │ 0x04 │ 0x34 │
└───────────────────────────┴──────────────────┴────────────────────┘

2) Why not use the stack's cmd-sync infrastructure for PERI-HCI frames?

A. PERI-HCI frames are not BT traffic, and handling them through the stack's own command-sync
path risks messing up the stack.
B. hci_recv_frame() will simply drop these frames due to unknown packet types.
C. Disguising them as BT frames (stripping the PERI indicator and substituting a BT one) has two
problems: they risk colliding with real BT frames, and they'd become indistinguishable from
real BT traffic in btmon logs.

>> B. What to do with non-BT frames
>>
>> There are two options:
>> 1. Don't let them reach the host stack at all, or
>> 2. Route them through the stack by an opaque channel such as HCI_VENDOR_PKT — defined by the stack but with no implementation yet.
> We have vendor diagostic packets already in the form of HCI_DIAG_PKT.
>
For PERI (cmd/event/ACL), we can use HCI_DIAG_PKT for debugging purposes. Beyond debugging, it
would be great if userspace could also access it via socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)

>> C. Why not skb_pull_data() for non-BT frames
>>
>> We want to preserve and log the complete frame for diagnostics, so we deliberately avoid skb_pull_data().
> Yeah, that is price tag of pre-processing, but even for vendor packets
> if they don't reach hci_send_to_monitor you won't be able to see on
> the likes of btmon.

Exactly right — that's precisely the issue we're facing today.

We really want btmon to show these PERI frames in readable format, but I guess btmon can't
currently.

1)What btusb_qcom.c does today for debugging

After a PERI frame is intercepted, we don't touch it while handling it by not calling
skb_pull_data(), then drop it into diag via the function below. The driver's RX path runs in
IRQ/softirq context, so we avoid skb_clone() here to keep performance.

static inline void btqcom_recv_diag(struct hci_dev *hdev, struct sk_buff *skb)
{
*(u8 *)skb_push(skb, 1) = hci_skb_pkt_type(skb);
hci_recv_diag(hdev, skb);
}