1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2020 Google Corporation
6 #include <net/bluetooth/bluetooth.h>
7 #include <net/bluetooth/hci_core.h>
11 #define MSFT_OP_READ_SUPPORTED_FEATURES 0x00
12 struct msft_cp_read_supported_features
{
16 struct msft_rp_read_supported_features
{
30 static bool read_supported_features(struct hci_dev
*hdev
,
31 struct msft_data
*msft
)
33 struct msft_cp_read_supported_features cp
;
34 struct msft_rp_read_supported_features
*rp
;
37 cp
.sub_opcode
= MSFT_OP_READ_SUPPORTED_FEATURES
;
39 skb
= __hci_cmd_sync(hdev
, hdev
->msft_opcode
, sizeof(cp
), &cp
,
42 bt_dev_err(hdev
, "Failed to read MSFT supported features (%ld)",
47 if (skb
->len
< sizeof(*rp
)) {
48 bt_dev_err(hdev
, "MSFT supported features length mismatch");
52 rp
= (struct msft_rp_read_supported_features
*)skb
->data
;
54 if (rp
->sub_opcode
!= MSFT_OP_READ_SUPPORTED_FEATURES
)
57 if (rp
->evt_prefix_len
> 0) {
58 msft
->evt_prefix
= kmemdup(rp
->evt_prefix
, rp
->evt_prefix_len
,
60 if (!msft
->evt_prefix
)
64 msft
->evt_prefix_len
= rp
->evt_prefix_len
;
65 msft
->features
= __le64_to_cpu(rp
->features
);
75 void msft_do_open(struct hci_dev
*hdev
)
77 struct msft_data
*msft
;
79 if (hdev
->msft_opcode
== HCI_OP_NOP
)
82 bt_dev_dbg(hdev
, "Initialize MSFT extension");
84 msft
= kzalloc(sizeof(*msft
), GFP_KERNEL
);
88 if (!read_supported_features(hdev
, msft
)) {
93 hdev
->msft_data
= msft
;
96 void msft_do_close(struct hci_dev
*hdev
)
98 struct msft_data
*msft
= hdev
->msft_data
;
103 bt_dev_dbg(hdev
, "Cleanup of MSFT extension");
105 hdev
->msft_data
= NULL
;
107 kfree(msft
->evt_prefix
);
111 void msft_vendor_evt(struct hci_dev
*hdev
, struct sk_buff
*skb
)
113 struct msft_data
*msft
= hdev
->msft_data
;
119 /* When the extension has defined an event prefix, check that it
120 * matches, and otherwise just return.
122 if (msft
->evt_prefix_len
> 0) {
123 if (skb
->len
< msft
->evt_prefix_len
)
126 if (memcmp(skb
->data
, msft
->evt_prefix
, msft
->evt_prefix_len
))
129 skb_pull(skb
, msft
->evt_prefix_len
);
132 /* Every event starts at least with an event code and the rest of
133 * the data is variable and depends on the event code.
141 bt_dev_dbg(hdev
, "MSFT vendor event %u", event
);
144 __u64
msft_get_features(struct hci_dev
*hdev
)
146 struct msft_data
*msft
= hdev
->msft_data
;
148 return msft
? msft
->features
: 0;