11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds BlueZ - Bluetooth protocol stack for Linux
32d0a0346SRon Shaffer Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
40fe8c8d0SIulia Tanasescu Copyright 2023 NXP
51da177e4SLinus Torvalds
61da177e4SLinus Torvalds Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
71da177e4SLinus Torvalds
81da177e4SLinus Torvalds This program is free software; you can redistribute it and/or modify
91da177e4SLinus Torvalds it under the terms of the GNU General Public License version 2 as
101da177e4SLinus Torvalds published by the Free Software Foundation;
111da177e4SLinus Torvalds
121da177e4SLinus Torvalds THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
131da177e4SLinus Torvalds OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
141da177e4SLinus Torvalds FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
151da177e4SLinus Torvalds IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
161da177e4SLinus Torvalds CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
171da177e4SLinus Torvalds WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
181da177e4SLinus Torvalds ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
191da177e4SLinus Torvalds OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
201da177e4SLinus Torvalds
211da177e4SLinus Torvalds ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
221da177e4SLinus Torvalds COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
231da177e4SLinus Torvalds SOFTWARE IS DISCLAIMED.
241da177e4SLinus Torvalds */
251da177e4SLinus Torvalds
261da177e4SLinus Torvalds /* Bluetooth HCI event handling. */
271da177e4SLinus Torvalds
281da177e4SLinus Torvalds #include <asm/unaligned.h>
29b5412606SLuiz Augusto von Dentz #include <linux/crypto.h>
30b5412606SLuiz Augusto von Dentz #include <crypto/algapi.h>
311da177e4SLinus Torvalds
321da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
331da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
34f0d6a0eaSMikel Astiz #include <net/bluetooth/mgmt.h>
357ef9fbf0SMarcel Holtmann
360857dd3bSJohan Hedberg #include "hci_request.h"
3723b9ceb7SMarcel Holtmann #include "hci_debugfs.h"
38b938790eSLuiz Augusto von Dentz #include "hci_codec.h"
392ceba539SJohan Hedberg #include "smp.h"
40145373cbSMiao-chen Chou #include "msft.h"
4101ce70b0SLuiz Augusto von Dentz #include "eir.h"
421da177e4SLinus Torvalds
43aa5b0345SMarcel Holtmann #define ZERO_KEY "\x00\x00\x00\x00\x00\x00\x00\x00" \
44aa5b0345SMarcel Holtmann "\x00\x00\x00\x00\x00\x00\x00\x00"
45aa5b0345SMarcel Holtmann
46c45074d6SLuiz Augusto von Dentz #define secs_to_jiffies(_secs) msecs_to_jiffies((_secs) * 1000)
47c45074d6SLuiz Augusto von Dentz
481da177e4SLinus Torvalds /* Handle HCI Event packets */
491da177e4SLinus Torvalds
hci_ev_skb_pull(struct hci_dev * hdev,struct sk_buff * skb,u8 ev,size_t len)50ae61a10dSLuiz Augusto von Dentz static void *hci_ev_skb_pull(struct hci_dev *hdev, struct sk_buff *skb,
51ae61a10dSLuiz Augusto von Dentz u8 ev, size_t len)
52ae61a10dSLuiz Augusto von Dentz {
53ae61a10dSLuiz Augusto von Dentz void *data;
54ae61a10dSLuiz Augusto von Dentz
55ae61a10dSLuiz Augusto von Dentz data = skb_pull_data(skb, len);
56ae61a10dSLuiz Augusto von Dentz if (!data)
57ae61a10dSLuiz Augusto von Dentz bt_dev_err(hdev, "Malformed Event: 0x%2.2x", ev);
58ae61a10dSLuiz Augusto von Dentz
59ae61a10dSLuiz Augusto von Dentz return data;
60ae61a10dSLuiz Augusto von Dentz }
61ae61a10dSLuiz Augusto von Dentz
hci_cc_skb_pull(struct hci_dev * hdev,struct sk_buff * skb,u16 op,size_t len)62e3f3a1aeSLuiz Augusto von Dentz static void *hci_cc_skb_pull(struct hci_dev *hdev, struct sk_buff *skb,
63e3f3a1aeSLuiz Augusto von Dentz u16 op, size_t len)
64e3f3a1aeSLuiz Augusto von Dentz {
65e3f3a1aeSLuiz Augusto von Dentz void *data;
66e3f3a1aeSLuiz Augusto von Dentz
67e3f3a1aeSLuiz Augusto von Dentz data = skb_pull_data(skb, len);
68e3f3a1aeSLuiz Augusto von Dentz if (!data)
69e3f3a1aeSLuiz Augusto von Dentz bt_dev_err(hdev, "Malformed Command Complete: 0x%4.4x", op);
70e3f3a1aeSLuiz Augusto von Dentz
71e3f3a1aeSLuiz Augusto von Dentz return data;
72e3f3a1aeSLuiz Augusto von Dentz }
73e3f3a1aeSLuiz Augusto von Dentz
hci_le_ev_skb_pull(struct hci_dev * hdev,struct sk_buff * skb,u8 ev,size_t len)7412cfe417SLuiz Augusto von Dentz static void *hci_le_ev_skb_pull(struct hci_dev *hdev, struct sk_buff *skb,
7512cfe417SLuiz Augusto von Dentz u8 ev, size_t len)
7612cfe417SLuiz Augusto von Dentz {
7712cfe417SLuiz Augusto von Dentz void *data;
7812cfe417SLuiz Augusto von Dentz
7912cfe417SLuiz Augusto von Dentz data = skb_pull_data(skb, len);
8012cfe417SLuiz Augusto von Dentz if (!data)
8112cfe417SLuiz Augusto von Dentz bt_dev_err(hdev, "Malformed LE Event: 0x%2.2x", ev);
8212cfe417SLuiz Augusto von Dentz
8312cfe417SLuiz Augusto von Dentz return data;
8412cfe417SLuiz Augusto von Dentz }
8512cfe417SLuiz Augusto von Dentz
hci_cc_inquiry_cancel(struct hci_dev * hdev,void * data,struct sk_buff * skb)86c8992cffSLuiz Augusto von Dentz static u8 hci_cc_inquiry_cancel(struct hci_dev *hdev, void *data,
87c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
881da177e4SLinus Torvalds {
89c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
90e3f3a1aeSLuiz Augusto von Dentz
91e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
921da177e4SLinus Torvalds
93adf1d692SSonny Sasaka /* It is possible that we receive Inquiry Complete event right
94adf1d692SSonny Sasaka * before we receive Inquiry Cancel Command Complete event, in
95adf1d692SSonny Sasaka * which case the latter event should have status of Command
969cd7289bSJonas Dreßler * Disallowed. This should not be treated as error, since
97adf1d692SSonny Sasaka * we actually achieve what Inquiry Cancel wants to achieve,
98adf1d692SSonny Sasaka * which is to end the last Inquiry session.
99adf1d692SSonny Sasaka */
1009cd7289bSJonas Dreßler if (rp->status == HCI_ERROR_COMMAND_DISALLOWED && !test_bit(HCI_INQUIRY, &hdev->flags)) {
101adf1d692SSonny Sasaka bt_dev_warn(hdev, "Ignoring error of Inquiry Cancel command");
102e3f3a1aeSLuiz Augusto von Dentz rp->status = 0x00;
103adf1d692SSonny Sasaka }
104adf1d692SSonny Sasaka
105e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
106c8992cffSLuiz Augusto von Dentz return rp->status;
1071da177e4SLinus Torvalds
10889352e7dSAndre Guedes clear_bit(HCI_INQUIRY, &hdev->flags);
1094e857c58SPeter Zijlstra smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */
1103e13fa1eSAndre Guedes wake_up_bit(&hdev->flags, HCI_INQUIRY);
11189352e7dSAndre Guedes
11250143a43SJohan Hedberg hci_dev_lock(hdev);
113168b8a25SJakub Pawlowski /* Set discovery state to stopped if we're not doing LE active
114168b8a25SJakub Pawlowski * scanning.
115168b8a25SJakub Pawlowski */
116168b8a25SJakub Pawlowski if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
117168b8a25SJakub Pawlowski hdev->le_scan_type != LE_SCAN_ACTIVE)
11850143a43SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
11950143a43SJohan Hedberg hci_dev_unlock(hdev);
12050143a43SJohan Hedberg
121c8992cffSLuiz Augusto von Dentz return rp->status;
1221da177e4SLinus Torvalds }
1236bd57416SMarcel Holtmann
hci_cc_periodic_inq(struct hci_dev * hdev,void * data,struct sk_buff * skb)124c8992cffSLuiz Augusto von Dentz static u8 hci_cc_periodic_inq(struct hci_dev *hdev, void *data,
125c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
1264d93483bSAndre Guedes {
127c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
128ae854a70SAndre Guedes
129e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
130e3f3a1aeSLuiz Augusto von Dentz
131e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
132c8992cffSLuiz Augusto von Dentz return rp->status;
133ae854a70SAndre Guedes
134a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_PERIODIC_INQ);
135c8992cffSLuiz Augusto von Dentz
136c8992cffSLuiz Augusto von Dentz return rp->status;
1374d93483bSAndre Guedes }
1384d93483bSAndre Guedes
hci_cc_exit_periodic_inq(struct hci_dev * hdev,void * data,struct sk_buff * skb)139c8992cffSLuiz Augusto von Dentz static u8 hci_cc_exit_periodic_inq(struct hci_dev *hdev, void *data,
140c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
1411da177e4SLinus Torvalds {
142c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
143a9de9248SMarcel Holtmann
144e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
145e3f3a1aeSLuiz Augusto von Dentz
146e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
147c8992cffSLuiz Augusto von Dentz return rp->status;
148a9de9248SMarcel Holtmann
149a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_PERIODIC_INQ);
150ae854a70SAndre Guedes
151c8992cffSLuiz Augusto von Dentz return rp->status;
152a9de9248SMarcel Holtmann }
153a9de9248SMarcel Holtmann
hci_cc_remote_name_req_cancel(struct hci_dev * hdev,void * data,struct sk_buff * skb)154c8992cffSLuiz Augusto von Dentz static u8 hci_cc_remote_name_req_cancel(struct hci_dev *hdev, void *data,
155807deac2SGustavo Padovan struct sk_buff *skb)
156a9de9248SMarcel Holtmann {
157c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
158e3f3a1aeSLuiz Augusto von Dentz
159e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
160c8992cffSLuiz Augusto von Dentz
161c8992cffSLuiz Augusto von Dentz return rp->status;
162a9de9248SMarcel Holtmann }
163a9de9248SMarcel Holtmann
hci_cc_role_discovery(struct hci_dev * hdev,void * data,struct sk_buff * skb)164c8992cffSLuiz Augusto von Dentz static u8 hci_cc_role_discovery(struct hci_dev *hdev, void *data,
165c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
166a9de9248SMarcel Holtmann {
167c8992cffSLuiz Augusto von Dentz struct hci_rp_role_discovery *rp = data;
1681da177e4SLinus Torvalds struct hci_conn *conn;
1691da177e4SLinus Torvalds
170e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1711da177e4SLinus Torvalds
172a9de9248SMarcel Holtmann if (rp->status)
173c8992cffSLuiz Augusto von Dentz return rp->status;
1741da177e4SLinus Torvalds
1751da177e4SLinus Torvalds hci_dev_lock(hdev);
1761da177e4SLinus Torvalds
177a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
17840bef302SJohan Hedberg if (conn)
17940bef302SJohan Hedberg conn->role = rp->role;
1801da177e4SLinus Torvalds
1811da177e4SLinus Torvalds hci_dev_unlock(hdev);
182c8992cffSLuiz Augusto von Dentz
183c8992cffSLuiz Augusto von Dentz return rp->status;
184a9de9248SMarcel Holtmann }
1851da177e4SLinus Torvalds
hci_cc_read_link_policy(struct hci_dev * hdev,void * data,struct sk_buff * skb)186c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_link_policy(struct hci_dev *hdev, void *data,
187c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
188e4e8e37cSMarcel Holtmann {
189c8992cffSLuiz Augusto von Dentz struct hci_rp_read_link_policy *rp = data;
190e4e8e37cSMarcel Holtmann struct hci_conn *conn;
191e4e8e37cSMarcel Holtmann
192e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
193e4e8e37cSMarcel Holtmann
194e4e8e37cSMarcel Holtmann if (rp->status)
195c8992cffSLuiz Augusto von Dentz return rp->status;
196e4e8e37cSMarcel Holtmann
197e4e8e37cSMarcel Holtmann hci_dev_lock(hdev);
198e4e8e37cSMarcel Holtmann
199e4e8e37cSMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
200e4e8e37cSMarcel Holtmann if (conn)
201e4e8e37cSMarcel Holtmann conn->link_policy = __le16_to_cpu(rp->policy);
202e4e8e37cSMarcel Holtmann
203e4e8e37cSMarcel Holtmann hci_dev_unlock(hdev);
204c8992cffSLuiz Augusto von Dentz
205c8992cffSLuiz Augusto von Dentz return rp->status;
206e4e8e37cSMarcel Holtmann }
207e4e8e37cSMarcel Holtmann
hci_cc_write_link_policy(struct hci_dev * hdev,void * data,struct sk_buff * skb)208c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_link_policy(struct hci_dev *hdev, void *data,
209c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
210a9de9248SMarcel Holtmann {
211c8992cffSLuiz Augusto von Dentz struct hci_rp_write_link_policy *rp = data;
212a9de9248SMarcel Holtmann struct hci_conn *conn;
213a9de9248SMarcel Holtmann void *sent;
214a9de9248SMarcel Holtmann
215e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
216a9de9248SMarcel Holtmann
217a9de9248SMarcel Holtmann if (rp->status)
218c8992cffSLuiz Augusto von Dentz return rp->status;
219a9de9248SMarcel Holtmann
220a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
22104837f64SMarcel Holtmann if (!sent)
222c8992cffSLuiz Augusto von Dentz return rp->status;
22304837f64SMarcel Holtmann
22404837f64SMarcel Holtmann hci_dev_lock(hdev);
22504837f64SMarcel Holtmann
226a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
227e4e8e37cSMarcel Holtmann if (conn)
22883985319SHarvey Harrison conn->link_policy = get_unaligned_le16(sent + 2);
22904837f64SMarcel Holtmann
23004837f64SMarcel Holtmann hci_dev_unlock(hdev);
231c8992cffSLuiz Augusto von Dentz
232c8992cffSLuiz Augusto von Dentz return rp->status;
2331da177e4SLinus Torvalds }
2341da177e4SLinus Torvalds
hci_cc_read_def_link_policy(struct hci_dev * hdev,void * data,struct sk_buff * skb)235c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_def_link_policy(struct hci_dev *hdev, void *data,
236807deac2SGustavo Padovan struct sk_buff *skb)
237e4e8e37cSMarcel Holtmann {
238c8992cffSLuiz Augusto von Dentz struct hci_rp_read_def_link_policy *rp = data;
239e3f3a1aeSLuiz Augusto von Dentz
240e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
241e4e8e37cSMarcel Holtmann
242e4e8e37cSMarcel Holtmann if (rp->status)
243c8992cffSLuiz Augusto von Dentz return rp->status;
244e4e8e37cSMarcel Holtmann
245e4e8e37cSMarcel Holtmann hdev->link_policy = __le16_to_cpu(rp->policy);
246c8992cffSLuiz Augusto von Dentz
247c8992cffSLuiz Augusto von Dentz return rp->status;
248e4e8e37cSMarcel Holtmann }
249e4e8e37cSMarcel Holtmann
hci_cc_write_def_link_policy(struct hci_dev * hdev,void * data,struct sk_buff * skb)250c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_def_link_policy(struct hci_dev *hdev, void *data,
251807deac2SGustavo Padovan struct sk_buff *skb)
252e4e8e37cSMarcel Holtmann {
253c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
254e4e8e37cSMarcel Holtmann void *sent;
255e4e8e37cSMarcel Holtmann
256e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
257e3f3a1aeSLuiz Augusto von Dentz
258e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
259c8992cffSLuiz Augusto von Dentz return rp->status;
26045296acdSMarcel Holtmann
261e4e8e37cSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
262e4e8e37cSMarcel Holtmann if (!sent)
263c8992cffSLuiz Augusto von Dentz return rp->status;
264e4e8e37cSMarcel Holtmann
265e4e8e37cSMarcel Holtmann hdev->link_policy = get_unaligned_le16(sent);
266c8992cffSLuiz Augusto von Dentz
267c8992cffSLuiz Augusto von Dentz return rp->status;
268e4e8e37cSMarcel Holtmann }
269e4e8e37cSMarcel Holtmann
hci_cc_reset(struct hci_dev * hdev,void * data,struct sk_buff * skb)270c8992cffSLuiz Augusto von Dentz static u8 hci_cc_reset(struct hci_dev *hdev, void *data, struct sk_buff *skb)
2711da177e4SLinus Torvalds {
272c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
273e3f3a1aeSLuiz Augusto von Dentz
274e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
275a9de9248SMarcel Holtmann
27610572132SGustavo F. Padovan clear_bit(HCI_RESET, &hdev->flags);
27710572132SGustavo F. Padovan
278e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
279c8992cffSLuiz Augusto von Dentz return rp->status;
2808761f9d6SMarcel Holtmann
281a297e97cSJohan Hedberg /* Reset all non-persistent flags */
282eacb44dfSMarcel Holtmann hci_dev_clear_volatile_flags(hdev);
28369775ff6SAndre Guedes
28439c5d970SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
28539c5d970SJohan Hedberg
286bbaf444aSJohan Hedberg hdev->inq_tx_power = HCI_TX_POWER_INVALID;
287bbaf444aSJohan Hedberg hdev->adv_tx_power = HCI_TX_POWER_INVALID;
2883f0f524bSJohan Hedberg
2893f0f524bSJohan Hedberg memset(hdev->adv_data, 0, sizeof(hdev->adv_data));
2903f0f524bSJohan Hedberg hdev->adv_data_len = 0;
291f8e808bdSMarcel Holtmann
292f8e808bdSMarcel Holtmann memset(hdev->scan_rsp_data, 0, sizeof(hdev->scan_rsp_data));
293f8e808bdSMarcel Holtmann hdev->scan_rsp_data_len = 0;
29406f5b778SMarcel Holtmann
295533553f8SMarcel Holtmann hdev->le_scan_type = LE_SCAN_PASSIVE;
296533553f8SMarcel Holtmann
29706f5b778SMarcel Holtmann hdev->ssp_debug_mode = 0;
298a4d5504dSMarcel Holtmann
2993d4f9c00SArchie Pusaka hci_bdaddr_list_clear(&hdev->le_accept_list);
300cfdb0c2dSAnkit Navik hci_bdaddr_list_clear(&hdev->le_resolv_list);
301c8992cffSLuiz Augusto von Dentz
302c8992cffSLuiz Augusto von Dentz return rp->status;
303a9de9248SMarcel Holtmann }
304a9de9248SMarcel Holtmann
hci_cc_read_stored_link_key(struct hci_dev * hdev,void * data,struct sk_buff * skb)305c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_stored_link_key(struct hci_dev *hdev, void *data,
306c2f0f979SMarcel Holtmann struct sk_buff *skb)
307c2f0f979SMarcel Holtmann {
308c8992cffSLuiz Augusto von Dentz struct hci_rp_read_stored_link_key *rp = data;
309c2f0f979SMarcel Holtmann struct hci_cp_read_stored_link_key *sent;
310c2f0f979SMarcel Holtmann
311e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
312c2f0f979SMarcel Holtmann
313c2f0f979SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_READ_STORED_LINK_KEY);
314c2f0f979SMarcel Holtmann if (!sent)
315c8992cffSLuiz Augusto von Dentz return rp->status;
316c2f0f979SMarcel Holtmann
317c2f0f979SMarcel Holtmann if (!rp->status && sent->read_all == 0x01) {
318e88422bcSLuiz Augusto von Dentz hdev->stored_max_keys = le16_to_cpu(rp->max_keys);
319e88422bcSLuiz Augusto von Dentz hdev->stored_num_keys = le16_to_cpu(rp->num_keys);
320c2f0f979SMarcel Holtmann }
321c8992cffSLuiz Augusto von Dentz
322c8992cffSLuiz Augusto von Dentz return rp->status;
323c2f0f979SMarcel Holtmann }
324c2f0f979SMarcel Holtmann
hci_cc_delete_stored_link_key(struct hci_dev * hdev,void * data,struct sk_buff * skb)325c8992cffSLuiz Augusto von Dentz static u8 hci_cc_delete_stored_link_key(struct hci_dev *hdev, void *data,
326a9366120SMarcel Holtmann struct sk_buff *skb)
327a9366120SMarcel Holtmann {
328c8992cffSLuiz Augusto von Dentz struct hci_rp_delete_stored_link_key *rp = data;
329889f0346SLuiz Augusto von Dentz u16 num_keys;
330e3f3a1aeSLuiz Augusto von Dentz
331e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
332a9366120SMarcel Holtmann
333a9366120SMarcel Holtmann if (rp->status)
334c8992cffSLuiz Augusto von Dentz return rp->status;
335a9366120SMarcel Holtmann
336889f0346SLuiz Augusto von Dentz num_keys = le16_to_cpu(rp->num_keys);
337889f0346SLuiz Augusto von Dentz
338889f0346SLuiz Augusto von Dentz if (num_keys <= hdev->stored_num_keys)
339889f0346SLuiz Augusto von Dentz hdev->stored_num_keys -= num_keys;
340a9366120SMarcel Holtmann else
341a9366120SMarcel Holtmann hdev->stored_num_keys = 0;
342c8992cffSLuiz Augusto von Dentz
343c8992cffSLuiz Augusto von Dentz return rp->status;
344a9366120SMarcel Holtmann }
345a9366120SMarcel Holtmann
hci_cc_write_local_name(struct hci_dev * hdev,void * data,struct sk_buff * skb)346c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_local_name(struct hci_dev *hdev, void *data,
347c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
348a9de9248SMarcel Holtmann {
349c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
3501da177e4SLinus Torvalds void *sent;
3511da177e4SLinus Torvalds
352e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
3531da177e4SLinus Torvalds
354a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
3551da177e4SLinus Torvalds if (!sent)
356c8992cffSLuiz Augusto von Dentz return rp->status;
3571da177e4SLinus Torvalds
35856e5cb86SJohan Hedberg hci_dev_lock(hdev);
35956e5cb86SJohan Hedberg
360d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT))
361e3f3a1aeSLuiz Augusto von Dentz mgmt_set_local_name_complete(hdev, sent, rp->status);
362e3f3a1aeSLuiz Augusto von Dentz else if (!rp->status)
36328cc7bdeSJohan Hedberg memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
364f51d5b24SJohan Hedberg
36556e5cb86SJohan Hedberg hci_dev_unlock(hdev);
366c8992cffSLuiz Augusto von Dentz
367c8992cffSLuiz Augusto von Dentz return rp->status;
368a9de9248SMarcel Holtmann }
369a9de9248SMarcel Holtmann
hci_cc_read_local_name(struct hci_dev * hdev,void * data,struct sk_buff * skb)370c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_name(struct hci_dev *hdev, void *data,
371c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
372a9de9248SMarcel Holtmann {
373c8992cffSLuiz Augusto von Dentz struct hci_rp_read_local_name *rp = data;
374e3f3a1aeSLuiz Augusto von Dentz
375e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
376a9de9248SMarcel Holtmann
377a9de9248SMarcel Holtmann if (rp->status)
378c8992cffSLuiz Augusto von Dentz return rp->status;
379a9de9248SMarcel Holtmann
380d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP) ||
381d7a5a11dSMarcel Holtmann hci_dev_test_flag(hdev, HCI_CONFIG))
3821f6c6378SJohan Hedberg memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
383c8992cffSLuiz Augusto von Dentz
384c8992cffSLuiz Augusto von Dentz return rp->status;
385a9de9248SMarcel Holtmann }
386a9de9248SMarcel Holtmann
hci_cc_write_auth_enable(struct hci_dev * hdev,void * data,struct sk_buff * skb)387c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_auth_enable(struct hci_dev *hdev, void *data,
388c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
389a9de9248SMarcel Holtmann {
390c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
391a9de9248SMarcel Holtmann void *sent;
392a9de9248SMarcel Holtmann
393e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
394a9de9248SMarcel Holtmann
395a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
396a9de9248SMarcel Holtmann if (!sent)
397c8992cffSLuiz Augusto von Dentz return rp->status;
3981da177e4SLinus Torvalds
3995c1a4c8fSJaganath Kanakkassery hci_dev_lock(hdev);
4005c1a4c8fSJaganath Kanakkassery
401e3f3a1aeSLuiz Augusto von Dentz if (!rp->status) {
402a9de9248SMarcel Holtmann __u8 param = *((__u8 *) sent);
403a9de9248SMarcel Holtmann
4041da177e4SLinus Torvalds if (param == AUTH_ENABLED)
4051da177e4SLinus Torvalds set_bit(HCI_AUTH, &hdev->flags);
4061da177e4SLinus Torvalds else
4071da177e4SLinus Torvalds clear_bit(HCI_AUTH, &hdev->flags);
4081da177e4SLinus Torvalds }
409a9de9248SMarcel Holtmann
410d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT))
411e3f3a1aeSLuiz Augusto von Dentz mgmt_auth_enable_complete(hdev, rp->status);
4125c1a4c8fSJaganath Kanakkassery
4135c1a4c8fSJaganath Kanakkassery hci_dev_unlock(hdev);
414c8992cffSLuiz Augusto von Dentz
415c8992cffSLuiz Augusto von Dentz return rp->status;
416a9de9248SMarcel Holtmann }
4171da177e4SLinus Torvalds
hci_cc_write_encrypt_mode(struct hci_dev * hdev,void * data,struct sk_buff * skb)418c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_encrypt_mode(struct hci_dev *hdev, void *data,
419c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
420a9de9248SMarcel Holtmann {
421c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
42245296acdSMarcel Holtmann __u8 param;
423a9de9248SMarcel Holtmann void *sent;
424a9de9248SMarcel Holtmann
425e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
426e3f3a1aeSLuiz Augusto von Dentz
427e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
428c8992cffSLuiz Augusto von Dentz return rp->status;
42945296acdSMarcel Holtmann
430a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
4311da177e4SLinus Torvalds if (!sent)
432c8992cffSLuiz Augusto von Dentz return rp->status;
4331da177e4SLinus Torvalds
43445296acdSMarcel Holtmann param = *((__u8 *) sent);
435a9de9248SMarcel Holtmann
4361da177e4SLinus Torvalds if (param)
4371da177e4SLinus Torvalds set_bit(HCI_ENCRYPT, &hdev->flags);
4381da177e4SLinus Torvalds else
4391da177e4SLinus Torvalds clear_bit(HCI_ENCRYPT, &hdev->flags);
440c8992cffSLuiz Augusto von Dentz
441c8992cffSLuiz Augusto von Dentz return rp->status;
4421da177e4SLinus Torvalds }
4431da177e4SLinus Torvalds
hci_cc_write_scan_enable(struct hci_dev * hdev,void * data,struct sk_buff * skb)444c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_scan_enable(struct hci_dev *hdev, void *data,
445c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
446a9de9248SMarcel Holtmann {
447c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
44845296acdSMarcel Holtmann __u8 param;
449a9de9248SMarcel Holtmann void *sent;
4501da177e4SLinus Torvalds
451e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
452a9de9248SMarcel Holtmann
453a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
4541da177e4SLinus Torvalds if (!sent)
455c8992cffSLuiz Augusto von Dentz return rp->status;
4561da177e4SLinus Torvalds
45736f7fc7eSJohan Hedberg param = *((__u8 *) sent);
458a9de9248SMarcel Holtmann
45956e5cb86SJohan Hedberg hci_dev_lock(hdev);
46056e5cb86SJohan Hedberg
461e3f3a1aeSLuiz Augusto von Dentz if (rp->status) {
4622d7cee58SJohan Hedberg hdev->discov_timeout = 0;
4632d7cee58SJohan Hedberg goto done;
4642d7cee58SJohan Hedberg }
4652d7cee58SJohan Hedberg
466bc6d2d04SJohan Hedberg if (param & SCAN_INQUIRY)
4671da177e4SLinus Torvalds set_bit(HCI_ISCAN, &hdev->flags);
468bc6d2d04SJohan Hedberg else
469bc6d2d04SJohan Hedberg clear_bit(HCI_ISCAN, &hdev->flags);
4701da177e4SLinus Torvalds
471031547d8SJohan Hedberg if (param & SCAN_PAGE)
4721da177e4SLinus Torvalds set_bit(HCI_PSCAN, &hdev->flags);
473bc6d2d04SJohan Hedberg else
474204e3990SJohan Hedberg clear_bit(HCI_PSCAN, &hdev->flags);
475a9de9248SMarcel Holtmann
47636f7fc7eSJohan Hedberg done:
47756e5cb86SJohan Hedberg hci_dev_unlock(hdev);
478c8992cffSLuiz Augusto von Dentz
479c8992cffSLuiz Augusto von Dentz return rp->status;
4801da177e4SLinus Torvalds }
4811da177e4SLinus Torvalds
hci_cc_set_event_filter(struct hci_dev * hdev,void * data,struct sk_buff * skb)482c8992cffSLuiz Augusto von Dentz static u8 hci_cc_set_event_filter(struct hci_dev *hdev, void *data,
483c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
484e5b0ad69SAbhishek Pandit-Subedi {
485c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
486e5b0ad69SAbhishek Pandit-Subedi struct hci_cp_set_event_filter *cp;
487e5b0ad69SAbhishek Pandit-Subedi void *sent;
488e5b0ad69SAbhishek Pandit-Subedi
489e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
490e3f3a1aeSLuiz Augusto von Dentz
491e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
492c8992cffSLuiz Augusto von Dentz return rp->status;
493e5b0ad69SAbhishek Pandit-Subedi
494e5b0ad69SAbhishek Pandit-Subedi sent = hci_sent_cmd_data(hdev, HCI_OP_SET_EVENT_FLT);
495e5b0ad69SAbhishek Pandit-Subedi if (!sent)
496c8992cffSLuiz Augusto von Dentz return rp->status;
497e5b0ad69SAbhishek Pandit-Subedi
498e5b0ad69SAbhishek Pandit-Subedi cp = (struct hci_cp_set_event_filter *)sent;
499e5b0ad69SAbhishek Pandit-Subedi
500e5b0ad69SAbhishek Pandit-Subedi if (cp->flt_type == HCI_FLT_CLEAR_ALL)
501e5b0ad69SAbhishek Pandit-Subedi hci_dev_clear_flag(hdev, HCI_EVENT_FILTER_CONFIGURED);
502e5b0ad69SAbhishek Pandit-Subedi else
503e5b0ad69SAbhishek Pandit-Subedi hci_dev_set_flag(hdev, HCI_EVENT_FILTER_CONFIGURED);
504c8992cffSLuiz Augusto von Dentz
505c8992cffSLuiz Augusto von Dentz return rp->status;
506e5b0ad69SAbhishek Pandit-Subedi }
507e5b0ad69SAbhishek Pandit-Subedi
hci_cc_read_class_of_dev(struct hci_dev * hdev,void * data,struct sk_buff * skb)508c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_class_of_dev(struct hci_dev *hdev, void *data,
509c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
510a9de9248SMarcel Holtmann {
511c8992cffSLuiz Augusto von Dentz struct hci_rp_read_class_of_dev *rp = data;
512e3f3a1aeSLuiz Augusto von Dentz
5137ee2ba3dSArnd Bergmann if (WARN_ON(!hdev))
5147ee2ba3dSArnd Bergmann return HCI_ERROR_UNSPECIFIED;
5157ee2ba3dSArnd Bergmann
516e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
517a9de9248SMarcel Holtmann
518a9de9248SMarcel Holtmann if (rp->status)
519c8992cffSLuiz Augusto von Dentz return rp->status;
520a9de9248SMarcel Holtmann
521a9de9248SMarcel Holtmann memcpy(hdev->dev_class, rp->dev_class, 3);
522a9de9248SMarcel Holtmann
523e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "class 0x%.2x%.2x%.2x", hdev->dev_class[2],
524e3f3a1aeSLuiz Augusto von Dentz hdev->dev_class[1], hdev->dev_class[0]);
525c8992cffSLuiz Augusto von Dentz
526c8992cffSLuiz Augusto von Dentz return rp->status;
527a9de9248SMarcel Holtmann }
528a9de9248SMarcel Holtmann
hci_cc_write_class_of_dev(struct hci_dev * hdev,void * data,struct sk_buff * skb)529c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_class_of_dev(struct hci_dev *hdev, void *data,
530c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
531a9de9248SMarcel Holtmann {
532c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
533a9de9248SMarcel Holtmann void *sent;
534a9de9248SMarcel Holtmann
535e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
536a9de9248SMarcel Holtmann
537a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
538a9de9248SMarcel Holtmann if (!sent)
539c8992cffSLuiz Augusto von Dentz return rp->status;
540a9de9248SMarcel Holtmann
5417f9a903cSMarcel Holtmann hci_dev_lock(hdev);
5427f9a903cSMarcel Holtmann
543e3f3a1aeSLuiz Augusto von Dentz if (!rp->status)
544a9de9248SMarcel Holtmann memcpy(hdev->dev_class, sent, 3);
5457f9a903cSMarcel Holtmann
546d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT))
547e3f3a1aeSLuiz Augusto von Dentz mgmt_set_class_of_dev_complete(hdev, sent, rp->status);
5487f9a903cSMarcel Holtmann
5497f9a903cSMarcel Holtmann hci_dev_unlock(hdev);
550c8992cffSLuiz Augusto von Dentz
551c8992cffSLuiz Augusto von Dentz return rp->status;
552a9de9248SMarcel Holtmann }
553a9de9248SMarcel Holtmann
hci_cc_read_voice_setting(struct hci_dev * hdev,void * data,struct sk_buff * skb)554c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_voice_setting(struct hci_dev *hdev, void *data,
555c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
556a9de9248SMarcel Holtmann {
557c8992cffSLuiz Augusto von Dentz struct hci_rp_read_voice_setting *rp = data;
558a9de9248SMarcel Holtmann __u16 setting;
559a9de9248SMarcel Holtmann
560e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
561a9de9248SMarcel Holtmann
562a9de9248SMarcel Holtmann if (rp->status)
563c8992cffSLuiz Augusto von Dentz return rp->status;
564a9de9248SMarcel Holtmann
565a9de9248SMarcel Holtmann setting = __le16_to_cpu(rp->voice_setting);
566a9de9248SMarcel Holtmann
567a9de9248SMarcel Holtmann if (hdev->voice_setting == setting)
568c8992cffSLuiz Augusto von Dentz return rp->status;
569a9de9248SMarcel Holtmann
570a9de9248SMarcel Holtmann hdev->voice_setting = setting;
571a9de9248SMarcel Holtmann
572e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "voice setting 0x%4.4x", setting);
573a9de9248SMarcel Holtmann
5743c54711cSGustavo F. Padovan if (hdev->notify)
575a9de9248SMarcel Holtmann hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
576c8992cffSLuiz Augusto von Dentz
577c8992cffSLuiz Augusto von Dentz return rp->status;
578a9de9248SMarcel Holtmann }
579a9de9248SMarcel Holtmann
hci_cc_write_voice_setting(struct hci_dev * hdev,void * data,struct sk_buff * skb)580c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_voice_setting(struct hci_dev *hdev, void *data,
5818fc9ced3SGustavo Padovan struct sk_buff *skb)
582a9de9248SMarcel Holtmann {
583c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
584f383f275SMarcel Holtmann __u16 setting;
585a9de9248SMarcel Holtmann void *sent;
586a9de9248SMarcel Holtmann
587e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
588e3f3a1aeSLuiz Augusto von Dentz
589e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
590c8992cffSLuiz Augusto von Dentz return rp->status;
591f383f275SMarcel Holtmann
592a9de9248SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
593a9de9248SMarcel Holtmann if (!sent)
594c8992cffSLuiz Augusto von Dentz return rp->status;
595a9de9248SMarcel Holtmann
596f383f275SMarcel Holtmann setting = get_unaligned_le16(sent);
5971da177e4SLinus Torvalds
598f383f275SMarcel Holtmann if (hdev->voice_setting == setting)
599c8992cffSLuiz Augusto von Dentz return rp->status;
600f383f275SMarcel Holtmann
6011da177e4SLinus Torvalds hdev->voice_setting = setting;
6021da177e4SLinus Torvalds
603e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "voice setting 0x%4.4x", setting);
6041da177e4SLinus Torvalds
6053c54711cSGustavo F. Padovan if (hdev->notify)
6061da177e4SLinus Torvalds hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
607c8992cffSLuiz Augusto von Dentz
608c8992cffSLuiz Augusto von Dentz return rp->status;
6091da177e4SLinus Torvalds }
6101da177e4SLinus Torvalds
hci_cc_read_num_supported_iac(struct hci_dev * hdev,void * data,struct sk_buff * skb)611c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_num_supported_iac(struct hci_dev *hdev, void *data,
612b4cb9fb2SMarcel Holtmann struct sk_buff *skb)
613b4cb9fb2SMarcel Holtmann {
614c8992cffSLuiz Augusto von Dentz struct hci_rp_read_num_supported_iac *rp = data;
615e3f3a1aeSLuiz Augusto von Dentz
616e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
617b4cb9fb2SMarcel Holtmann
618b4cb9fb2SMarcel Holtmann if (rp->status)
619c8992cffSLuiz Augusto von Dentz return rp->status;
620b4cb9fb2SMarcel Holtmann
621b4cb9fb2SMarcel Holtmann hdev->num_iac = rp->num_iac;
622b4cb9fb2SMarcel Holtmann
623e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "num iac %d", hdev->num_iac);
624c8992cffSLuiz Augusto von Dentz
625c8992cffSLuiz Augusto von Dentz return rp->status;
626b4cb9fb2SMarcel Holtmann }
627b4cb9fb2SMarcel Holtmann
hci_cc_write_ssp_mode(struct hci_dev * hdev,void * data,struct sk_buff * skb)628c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_ssp_mode(struct hci_dev *hdev, void *data,
629c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
630333140b5SMarcel Holtmann {
631c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
6325ed8eb2fSJohan Hedberg struct hci_cp_write_ssp_mode *sent;
633333140b5SMarcel Holtmann
634e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
635333140b5SMarcel Holtmann
636333140b5SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
637333140b5SMarcel Holtmann if (!sent)
638c8992cffSLuiz Augusto von Dentz return rp->status;
639333140b5SMarcel Holtmann
6405c1a4c8fSJaganath Kanakkassery hci_dev_lock(hdev);
6415c1a4c8fSJaganath Kanakkassery
642e3f3a1aeSLuiz Augusto von Dentz if (!rp->status) {
6435ed8eb2fSJohan Hedberg if (sent->mode)
644cad718edSJohan Hedberg hdev->features[1][0] |= LMP_HOST_SSP;
6455ed8eb2fSJohan Hedberg else
646cad718edSJohan Hedberg hdev->features[1][0] &= ~LMP_HOST_SSP;
6475ed8eb2fSJohan Hedberg }
6485ed8eb2fSJohan Hedberg
649e3f3a1aeSLuiz Augusto von Dentz if (!rp->status) {
6505ed8eb2fSJohan Hedberg if (sent->mode)
651a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_SSP_ENABLED);
65284bde9d6SJohan Hedberg else
653a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_SSP_ENABLED);
654c0ecddc2SJohan Hedberg }
6555c1a4c8fSJaganath Kanakkassery
6565c1a4c8fSJaganath Kanakkassery hci_dev_unlock(hdev);
657c8992cffSLuiz Augusto von Dentz
658c8992cffSLuiz Augusto von Dentz return rp->status;
659333140b5SMarcel Holtmann }
660333140b5SMarcel Holtmann
hci_cc_write_sc_support(struct hci_dev * hdev,void * data,struct sk_buff * skb)661c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_sc_support(struct hci_dev *hdev, void *data,
662c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
663eac83dc6SMarcel Holtmann {
664c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
665eac83dc6SMarcel Holtmann struct hci_cp_write_sc_support *sent;
666eac83dc6SMarcel Holtmann
667e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
668eac83dc6SMarcel Holtmann
669eac83dc6SMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SC_SUPPORT);
670eac83dc6SMarcel Holtmann if (!sent)
671c8992cffSLuiz Augusto von Dentz return rp->status;
672eac83dc6SMarcel Holtmann
6735c1a4c8fSJaganath Kanakkassery hci_dev_lock(hdev);
6745c1a4c8fSJaganath Kanakkassery
675e3f3a1aeSLuiz Augusto von Dentz if (!rp->status) {
676eac83dc6SMarcel Holtmann if (sent->support)
677eac83dc6SMarcel Holtmann hdev->features[1][0] |= LMP_HOST_SC;
678eac83dc6SMarcel Holtmann else
679eac83dc6SMarcel Holtmann hdev->features[1][0] &= ~LMP_HOST_SC;
680eac83dc6SMarcel Holtmann }
681eac83dc6SMarcel Holtmann
682e3f3a1aeSLuiz Augusto von Dentz if (!hci_dev_test_flag(hdev, HCI_MGMT) && !rp->status) {
683eac83dc6SMarcel Holtmann if (sent->support)
684a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_SC_ENABLED);
685eac83dc6SMarcel Holtmann else
686a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_SC_ENABLED);
687eac83dc6SMarcel Holtmann }
6885c1a4c8fSJaganath Kanakkassery
6895c1a4c8fSJaganath Kanakkassery hci_dev_unlock(hdev);
690c8992cffSLuiz Augusto von Dentz
691c8992cffSLuiz Augusto von Dentz return rp->status;
692eac83dc6SMarcel Holtmann }
693eac83dc6SMarcel Holtmann
hci_cc_read_local_version(struct hci_dev * hdev,void * data,struct sk_buff * skb)694c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_version(struct hci_dev *hdev, void *data,
695c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
696a9de9248SMarcel Holtmann {
697c8992cffSLuiz Augusto von Dentz struct hci_rp_read_local_version *rp = data;
698e3f3a1aeSLuiz Augusto von Dentz
699e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
7001143e5a6SMarcel Holtmann
701a9de9248SMarcel Holtmann if (rp->status)
702c8992cffSLuiz Augusto von Dentz return rp->status;
7031143e5a6SMarcel Holtmann
704d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP) ||
705d7a5a11dSMarcel Holtmann hci_dev_test_flag(hdev, HCI_CONFIG)) {
706a9de9248SMarcel Holtmann hdev->hci_ver = rp->hci_ver;
707e4e8e37cSMarcel Holtmann hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
708d5859e22SJohan Hedberg hdev->lmp_ver = rp->lmp_ver;
709e4e8e37cSMarcel Holtmann hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
710d5859e22SJohan Hedberg hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
7110d5551f5SMarcel Holtmann }
712c8992cffSLuiz Augusto von Dentz
713c8992cffSLuiz Augusto von Dentz return rp->status;
714d5859e22SJohan Hedberg }
715d5859e22SJohan Hedberg
hci_cc_read_enc_key_size(struct hci_dev * hdev,void * data,struct sk_buff * skb)716278d933eSBrian Gix static u8 hci_cc_read_enc_key_size(struct hci_dev *hdev, void *data,
717278d933eSBrian Gix struct sk_buff *skb)
718278d933eSBrian Gix {
719278d933eSBrian Gix struct hci_rp_read_enc_key_size *rp = data;
720278d933eSBrian Gix struct hci_conn *conn;
721278d933eSBrian Gix u16 handle;
722278d933eSBrian Gix u8 status = rp->status;
723278d933eSBrian Gix
724278d933eSBrian Gix bt_dev_dbg(hdev, "status 0x%2.2x", status);
725278d933eSBrian Gix
726278d933eSBrian Gix handle = le16_to_cpu(rp->handle);
727278d933eSBrian Gix
728278d933eSBrian Gix hci_dev_lock(hdev);
729278d933eSBrian Gix
730278d933eSBrian Gix conn = hci_conn_hash_lookup_handle(hdev, handle);
731278d933eSBrian Gix if (!conn) {
732278d933eSBrian Gix status = 0xFF;
733278d933eSBrian Gix goto done;
734278d933eSBrian Gix }
735278d933eSBrian Gix
736278d933eSBrian Gix /* While unexpected, the read_enc_key_size command may fail. The most
737278d933eSBrian Gix * secure approach is to then assume the key size is 0 to force a
738278d933eSBrian Gix * disconnection.
739278d933eSBrian Gix */
740278d933eSBrian Gix if (status) {
741278d933eSBrian Gix bt_dev_err(hdev, "failed to read key size for handle %u",
742278d933eSBrian Gix handle);
743278d933eSBrian Gix conn->enc_key_size = 0;
744278d933eSBrian Gix } else {
745278d933eSBrian Gix conn->enc_key_size = rp->key_size;
746278d933eSBrian Gix status = 0;
74734c032a7SAlex Lu
74834c032a7SAlex Lu if (conn->enc_key_size < hdev->min_enc_key_size) {
74934c032a7SAlex Lu /* As slave role, the conn->state has been set to
75034c032a7SAlex Lu * BT_CONNECTED and l2cap conn req might not be received
75134c032a7SAlex Lu * yet, at this moment the l2cap layer almost does
75234c032a7SAlex Lu * nothing with the non-zero status.
75334c032a7SAlex Lu * So we also clear encrypt related bits, and then the
75434c032a7SAlex Lu * handler of l2cap conn req will get the right secure
75534c032a7SAlex Lu * state at a later time.
75634c032a7SAlex Lu */
75734c032a7SAlex Lu status = HCI_ERROR_AUTH_FAILURE;
75834c032a7SAlex Lu clear_bit(HCI_CONN_ENCRYPT, &conn->flags);
75934c032a7SAlex Lu clear_bit(HCI_CONN_AES_CCM, &conn->flags);
76034c032a7SAlex Lu }
761278d933eSBrian Gix }
762278d933eSBrian Gix
76334c032a7SAlex Lu hci_encrypt_cfm(conn, status);
764278d933eSBrian Gix
765278d933eSBrian Gix done:
766278d933eSBrian Gix hci_dev_unlock(hdev);
767278d933eSBrian Gix
768278d933eSBrian Gix return status;
769278d933eSBrian Gix }
770278d933eSBrian Gix
hci_cc_read_local_commands(struct hci_dev * hdev,void * data,struct sk_buff * skb)771c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_commands(struct hci_dev *hdev, void *data,
7728fc9ced3SGustavo Padovan struct sk_buff *skb)
773a9de9248SMarcel Holtmann {
774c8992cffSLuiz Augusto von Dentz struct hci_rp_read_local_commands *rp = data;
775e3f3a1aeSLuiz Augusto von Dentz
776e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
777a9de9248SMarcel Holtmann
7786a070e6eSMarcel Holtmann if (rp->status)
779c8992cffSLuiz Augusto von Dentz return rp->status;
7806a070e6eSMarcel Holtmann
781d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP) ||
782d7a5a11dSMarcel Holtmann hci_dev_test_flag(hdev, HCI_CONFIG))
783a9de9248SMarcel Holtmann memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
784c8992cffSLuiz Augusto von Dentz
785c8992cffSLuiz Augusto von Dentz return rp->status;
786a9de9248SMarcel Holtmann }
787a9de9248SMarcel Holtmann
hci_cc_read_auth_payload_timeout(struct hci_dev * hdev,void * data,struct sk_buff * skb)788c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_auth_payload_timeout(struct hci_dev *hdev, void *data,
789302975cbSSpoorthi Ravishankar Koppad struct sk_buff *skb)
790302975cbSSpoorthi Ravishankar Koppad {
791c8992cffSLuiz Augusto von Dentz struct hci_rp_read_auth_payload_to *rp = data;
792302975cbSSpoorthi Ravishankar Koppad struct hci_conn *conn;
793302975cbSSpoorthi Ravishankar Koppad
794e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
795302975cbSSpoorthi Ravishankar Koppad
796302975cbSSpoorthi Ravishankar Koppad if (rp->status)
797c8992cffSLuiz Augusto von Dentz return rp->status;
798302975cbSSpoorthi Ravishankar Koppad
799302975cbSSpoorthi Ravishankar Koppad hci_dev_lock(hdev);
800302975cbSSpoorthi Ravishankar Koppad
801302975cbSSpoorthi Ravishankar Koppad conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
802302975cbSSpoorthi Ravishankar Koppad if (conn)
803302975cbSSpoorthi Ravishankar Koppad conn->auth_payload_timeout = __le16_to_cpu(rp->timeout);
804302975cbSSpoorthi Ravishankar Koppad
805302975cbSSpoorthi Ravishankar Koppad hci_dev_unlock(hdev);
806c8992cffSLuiz Augusto von Dentz
807c8992cffSLuiz Augusto von Dentz return rp->status;
808302975cbSSpoorthi Ravishankar Koppad }
809302975cbSSpoorthi Ravishankar Koppad
hci_cc_write_auth_payload_timeout(struct hci_dev * hdev,void * data,struct sk_buff * skb)810c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_auth_payload_timeout(struct hci_dev *hdev, void *data,
811302975cbSSpoorthi Ravishankar Koppad struct sk_buff *skb)
812302975cbSSpoorthi Ravishankar Koppad {
813c8992cffSLuiz Augusto von Dentz struct hci_rp_write_auth_payload_to *rp = data;
814302975cbSSpoorthi Ravishankar Koppad struct hci_conn *conn;
815302975cbSSpoorthi Ravishankar Koppad void *sent;
816302975cbSSpoorthi Ravishankar Koppad
817e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
818302975cbSSpoorthi Ravishankar Koppad
819302975cbSSpoorthi Ravishankar Koppad sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_PAYLOAD_TO);
820302975cbSSpoorthi Ravishankar Koppad if (!sent)
821c8992cffSLuiz Augusto von Dentz return rp->status;
822302975cbSSpoorthi Ravishankar Koppad
823302975cbSSpoorthi Ravishankar Koppad hci_dev_lock(hdev);
824302975cbSSpoorthi Ravishankar Koppad
825302975cbSSpoorthi Ravishankar Koppad conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
8267aca0ac4SLuiz Augusto von Dentz if (!conn) {
8277aca0ac4SLuiz Augusto von Dentz rp->status = 0xff;
8287aca0ac4SLuiz Augusto von Dentz goto unlock;
8297aca0ac4SLuiz Augusto von Dentz }
8307aca0ac4SLuiz Augusto von Dentz
8317aca0ac4SLuiz Augusto von Dentz if (!rp->status)
832302975cbSSpoorthi Ravishankar Koppad conn->auth_payload_timeout = get_unaligned_le16(sent + 2);
833302975cbSSpoorthi Ravishankar Koppad
8347aca0ac4SLuiz Augusto von Dentz unlock:
835302975cbSSpoorthi Ravishankar Koppad hci_dev_unlock(hdev);
836c8992cffSLuiz Augusto von Dentz
837c8992cffSLuiz Augusto von Dentz return rp->status;
838302975cbSSpoorthi Ravishankar Koppad }
839302975cbSSpoorthi Ravishankar Koppad
hci_cc_read_local_features(struct hci_dev * hdev,void * data,struct sk_buff * skb)840c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_features(struct hci_dev *hdev, void *data,
8418fc9ced3SGustavo Padovan struct sk_buff *skb)
842a9de9248SMarcel Holtmann {
843c8992cffSLuiz Augusto von Dentz struct hci_rp_read_local_features *rp = data;
844e3f3a1aeSLuiz Augusto von Dentz
845e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
846a9de9248SMarcel Holtmann
847a9de9248SMarcel Holtmann if (rp->status)
848c8992cffSLuiz Augusto von Dentz return rp->status;
849a9de9248SMarcel Holtmann
850a9de9248SMarcel Holtmann memcpy(hdev->features, rp->features, 8);
8511da177e4SLinus Torvalds
8521da177e4SLinus Torvalds /* Adjust default settings according to features
8531da177e4SLinus Torvalds * supported by device. */
854a9de9248SMarcel Holtmann
855cad718edSJohan Hedberg if (hdev->features[0][0] & LMP_3SLOT)
8561da177e4SLinus Torvalds hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
8571da177e4SLinus Torvalds
858cad718edSJohan Hedberg if (hdev->features[0][0] & LMP_5SLOT)
8591da177e4SLinus Torvalds hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
8601da177e4SLinus Torvalds
861cad718edSJohan Hedberg if (hdev->features[0][1] & LMP_HV2) {
8621da177e4SLinus Torvalds hdev->pkt_type |= (HCI_HV2);
8635b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_HV2);
8645b7f9909SMarcel Holtmann }
8651da177e4SLinus Torvalds
866cad718edSJohan Hedberg if (hdev->features[0][1] & LMP_HV3) {
8671da177e4SLinus Torvalds hdev->pkt_type |= (HCI_HV3);
8685b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_HV3);
8695b7f9909SMarcel Holtmann }
8705b7f9909SMarcel Holtmann
87145db810fSAndre Guedes if (lmp_esco_capable(hdev))
8725b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV3);
8735b7f9909SMarcel Holtmann
874cad718edSJohan Hedberg if (hdev->features[0][4] & LMP_EV4)
8755b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV4);
8765b7f9909SMarcel Holtmann
877cad718edSJohan Hedberg if (hdev->features[0][4] & LMP_EV5)
8785b7f9909SMarcel Holtmann hdev->esco_type |= (ESCO_EV5);
8791da177e4SLinus Torvalds
880cad718edSJohan Hedberg if (hdev->features[0][5] & LMP_EDR_ESCO_2M)
881efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_2EV3);
882efc7688bSMarcel Holtmann
883cad718edSJohan Hedberg if (hdev->features[0][5] & LMP_EDR_ESCO_3M)
884efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_3EV3);
885efc7688bSMarcel Holtmann
886cad718edSJohan Hedberg if (hdev->features[0][5] & LMP_EDR_3S_ESCO)
887efc7688bSMarcel Holtmann hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
888c8992cffSLuiz Augusto von Dentz
889c8992cffSLuiz Augusto von Dentz return rp->status;
8901da177e4SLinus Torvalds }
8911da177e4SLinus Torvalds
hci_cc_read_local_ext_features(struct hci_dev * hdev,void * data,struct sk_buff * skb)892c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_ext_features(struct hci_dev *hdev, void *data,
893971e3a4bSAndre Guedes struct sk_buff *skb)
894971e3a4bSAndre Guedes {
895c8992cffSLuiz Augusto von Dentz struct hci_rp_read_local_ext_features *rp = data;
896e3f3a1aeSLuiz Augusto von Dentz
897e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
898971e3a4bSAndre Guedes
899971e3a4bSAndre Guedes if (rp->status)
900c8992cffSLuiz Augusto von Dentz return rp->status;
901971e3a4bSAndre Guedes
9028194f1efSVasily Khoruzhick if (hdev->max_page < rp->max_page) {
9038194f1efSVasily Khoruzhick if (test_bit(HCI_QUIRK_BROKEN_LOCAL_EXT_FEATURES_PAGE_2,
9048194f1efSVasily Khoruzhick &hdev->quirks))
9058194f1efSVasily Khoruzhick bt_dev_warn(hdev, "broken local ext features page 2");
9068194f1efSVasily Khoruzhick else
907d2c5d77fSJohan Hedberg hdev->max_page = rp->max_page;
9088194f1efSVasily Khoruzhick }
909d2c5d77fSJohan Hedberg
910cad718edSJohan Hedberg if (rp->page < HCI_MAX_PAGES)
911cad718edSJohan Hedberg memcpy(hdev->features[rp->page], rp->features, 8);
912c8992cffSLuiz Augusto von Dentz
913c8992cffSLuiz Augusto von Dentz return rp->status;
914971e3a4bSAndre Guedes }
915971e3a4bSAndre Guedes
hci_cc_read_buffer_size(struct hci_dev * hdev,void * data,struct sk_buff * skb)916c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_buffer_size(struct hci_dev *hdev, void *data,
917c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
918a9de9248SMarcel Holtmann {
919c8992cffSLuiz Augusto von Dentz struct hci_rp_read_buffer_size *rp = data;
920e3f3a1aeSLuiz Augusto von Dentz
921e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
922a9de9248SMarcel Holtmann
923a9de9248SMarcel Holtmann if (rp->status)
924c8992cffSLuiz Augusto von Dentz return rp->status;
925a9de9248SMarcel Holtmann
926a9de9248SMarcel Holtmann hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
927a9de9248SMarcel Holtmann hdev->sco_mtu = rp->sco_mtu;
928a9de9248SMarcel Holtmann hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
929a9de9248SMarcel Holtmann hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
930da1f5198SMarcel Holtmann
931da1f5198SMarcel Holtmann if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
932da1f5198SMarcel Holtmann hdev->sco_mtu = 64;
933da1f5198SMarcel Holtmann hdev->sco_pkts = 8;
934da1f5198SMarcel Holtmann }
935da1f5198SMarcel Holtmann
936da1f5198SMarcel Holtmann hdev->acl_cnt = hdev->acl_pkts;
937da1f5198SMarcel Holtmann hdev->sco_cnt = hdev->sco_pkts;
9381da177e4SLinus Torvalds
939807deac2SGustavo Padovan BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
940807deac2SGustavo Padovan hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
941c8992cffSLuiz Augusto von Dentz
942ad3f7986SSungwoo Kim if (!hdev->acl_mtu || !hdev->acl_pkts)
943ad3f7986SSungwoo Kim return HCI_ERROR_INVALID_PARAMETERS;
944ad3f7986SSungwoo Kim
945c8992cffSLuiz Augusto von Dentz return rp->status;
9461da177e4SLinus Torvalds }
9471da177e4SLinus Torvalds
hci_cc_read_bd_addr(struct hci_dev * hdev,void * data,struct sk_buff * skb)948c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_bd_addr(struct hci_dev *hdev, void *data,
949c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
950a9de9248SMarcel Holtmann {
951c8992cffSLuiz Augusto von Dentz struct hci_rp_read_bd_addr *rp = data;
952e3f3a1aeSLuiz Augusto von Dentz
953e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
954a9de9248SMarcel Holtmann
955e30d3f5fSMarcel Holtmann if (rp->status)
956c8992cffSLuiz Augusto von Dentz return rp->status;
957e30d3f5fSMarcel Holtmann
958e30d3f5fSMarcel Holtmann if (test_bit(HCI_INIT, &hdev->flags))
959a9de9248SMarcel Holtmann bacpy(&hdev->bdaddr, &rp->bdaddr);
960e30d3f5fSMarcel Holtmann
961d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP))
962e30d3f5fSMarcel Holtmann bacpy(&hdev->setup_addr, &rp->bdaddr);
963c8992cffSLuiz Augusto von Dentz
964c8992cffSLuiz Augusto von Dentz return rp->status;
96523bb5763SJohan Hedberg }
96623bb5763SJohan Hedberg
hci_cc_read_local_pairing_opts(struct hci_dev * hdev,void * data,struct sk_buff * skb)967c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_pairing_opts(struct hci_dev *hdev, void *data,
968a4790360SMarcel Holtmann struct sk_buff *skb)
969a4790360SMarcel Holtmann {
970c8992cffSLuiz Augusto von Dentz struct hci_rp_read_local_pairing_opts *rp = data;
971e3f3a1aeSLuiz Augusto von Dentz
972e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
973a4790360SMarcel Holtmann
974a4790360SMarcel Holtmann if (rp->status)
975c8992cffSLuiz Augusto von Dentz return rp->status;
976a4790360SMarcel Holtmann
977a4790360SMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SETUP) ||
978a4790360SMarcel Holtmann hci_dev_test_flag(hdev, HCI_CONFIG)) {
979a4790360SMarcel Holtmann hdev->pairing_opts = rp->pairing_opts;
980a4790360SMarcel Holtmann hdev->max_enc_key_size = rp->max_key_size;
981a4790360SMarcel Holtmann }
982c8992cffSLuiz Augusto von Dentz
983c8992cffSLuiz Augusto von Dentz return rp->status;
984a4790360SMarcel Holtmann }
985a4790360SMarcel Holtmann
hci_cc_read_page_scan_activity(struct hci_dev * hdev,void * data,struct sk_buff * skb)986c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_page_scan_activity(struct hci_dev *hdev, void *data,
987f332ec66SJohan Hedberg struct sk_buff *skb)
988f332ec66SJohan Hedberg {
989c8992cffSLuiz Augusto von Dentz struct hci_rp_read_page_scan_activity *rp = data;
990e3f3a1aeSLuiz Augusto von Dentz
991e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
992f332ec66SJohan Hedberg
99345296acdSMarcel Holtmann if (rp->status)
994c8992cffSLuiz Augusto von Dentz return rp->status;
99545296acdSMarcel Holtmann
99645296acdSMarcel Holtmann if (test_bit(HCI_INIT, &hdev->flags)) {
997f332ec66SJohan Hedberg hdev->page_scan_interval = __le16_to_cpu(rp->interval);
998f332ec66SJohan Hedberg hdev->page_scan_window = __le16_to_cpu(rp->window);
999f332ec66SJohan Hedberg }
1000c8992cffSLuiz Augusto von Dentz
1001c8992cffSLuiz Augusto von Dentz return rp->status;
1002f332ec66SJohan Hedberg }
1003f332ec66SJohan Hedberg
hci_cc_write_page_scan_activity(struct hci_dev * hdev,void * data,struct sk_buff * skb)1004c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_page_scan_activity(struct hci_dev *hdev, void *data,
10054a3ee763SJohan Hedberg struct sk_buff *skb)
10064a3ee763SJohan Hedberg {
1007c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
10084a3ee763SJohan Hedberg struct hci_cp_write_page_scan_activity *sent;
10094a3ee763SJohan Hedberg
1010e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1011e3f3a1aeSLuiz Augusto von Dentz
1012e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
1013c8992cffSLuiz Augusto von Dentz return rp->status;
10144a3ee763SJohan Hedberg
10154a3ee763SJohan Hedberg sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY);
10164a3ee763SJohan Hedberg if (!sent)
1017c8992cffSLuiz Augusto von Dentz return rp->status;
10184a3ee763SJohan Hedberg
10194a3ee763SJohan Hedberg hdev->page_scan_interval = __le16_to_cpu(sent->interval);
10204a3ee763SJohan Hedberg hdev->page_scan_window = __le16_to_cpu(sent->window);
1021c8992cffSLuiz Augusto von Dentz
1022c8992cffSLuiz Augusto von Dentz return rp->status;
10234a3ee763SJohan Hedberg }
10244a3ee763SJohan Hedberg
hci_cc_read_page_scan_type(struct hci_dev * hdev,void * data,struct sk_buff * skb)1025c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_page_scan_type(struct hci_dev *hdev, void *data,
1026f332ec66SJohan Hedberg struct sk_buff *skb)
1027f332ec66SJohan Hedberg {
1028c8992cffSLuiz Augusto von Dentz struct hci_rp_read_page_scan_type *rp = data;
1029e3f3a1aeSLuiz Augusto von Dentz
1030e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1031f332ec66SJohan Hedberg
103245296acdSMarcel Holtmann if (rp->status)
1033c8992cffSLuiz Augusto von Dentz return rp->status;
103445296acdSMarcel Holtmann
103545296acdSMarcel Holtmann if (test_bit(HCI_INIT, &hdev->flags))
1036f332ec66SJohan Hedberg hdev->page_scan_type = rp->type;
1037c8992cffSLuiz Augusto von Dentz
1038c8992cffSLuiz Augusto von Dentz return rp->status;
1039f332ec66SJohan Hedberg }
1040f332ec66SJohan Hedberg
hci_cc_write_page_scan_type(struct hci_dev * hdev,void * data,struct sk_buff * skb)1041c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_page_scan_type(struct hci_dev *hdev, void *data,
10424a3ee763SJohan Hedberg struct sk_buff *skb)
10434a3ee763SJohan Hedberg {
1044c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
10454a3ee763SJohan Hedberg u8 *type;
10464a3ee763SJohan Hedberg
1047e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1048e3f3a1aeSLuiz Augusto von Dentz
1049e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
1050c8992cffSLuiz Augusto von Dentz return rp->status;
10514a3ee763SJohan Hedberg
10524a3ee763SJohan Hedberg type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE);
10534a3ee763SJohan Hedberg if (type)
10544a3ee763SJohan Hedberg hdev->page_scan_type = *type;
1055c8992cffSLuiz Augusto von Dentz
1056c8992cffSLuiz Augusto von Dentz return rp->status;
10574a3ee763SJohan Hedberg }
10584a3ee763SJohan Hedberg
hci_cc_read_clock(struct hci_dev * hdev,void * data,struct sk_buff * skb)1059c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_clock(struct hci_dev *hdev, void *data,
1060c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
106133f35721SJohan Hedberg {
1062c8992cffSLuiz Augusto von Dentz struct hci_rp_read_clock *rp = data;
106333f35721SJohan Hedberg struct hci_cp_read_clock *cp;
106433f35721SJohan Hedberg struct hci_conn *conn;
106533f35721SJohan Hedberg
1066e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1067e3f3a1aeSLuiz Augusto von Dentz
106833f35721SJohan Hedberg if (rp->status)
1069c8992cffSLuiz Augusto von Dentz return rp->status;
107033f35721SJohan Hedberg
107133f35721SJohan Hedberg hci_dev_lock(hdev);
107233f35721SJohan Hedberg
107333f35721SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_READ_CLOCK);
107433f35721SJohan Hedberg if (!cp)
107533f35721SJohan Hedberg goto unlock;
107633f35721SJohan Hedberg
107733f35721SJohan Hedberg if (cp->which == 0x00) {
107833f35721SJohan Hedberg hdev->clock = le32_to_cpu(rp->clock);
107933f35721SJohan Hedberg goto unlock;
108033f35721SJohan Hedberg }
108133f35721SJohan Hedberg
108233f35721SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
108333f35721SJohan Hedberg if (conn) {
108433f35721SJohan Hedberg conn->clock = le32_to_cpu(rp->clock);
108533f35721SJohan Hedberg conn->clock_accuracy = le16_to_cpu(rp->accuracy);
108633f35721SJohan Hedberg }
108733f35721SJohan Hedberg
108833f35721SJohan Hedberg unlock:
108933f35721SJohan Hedberg hci_dev_unlock(hdev);
1090c8992cffSLuiz Augusto von Dentz return rp->status;
109133f35721SJohan Hedberg }
109233f35721SJohan Hedberg
hci_cc_read_inq_rsp_tx_power(struct hci_dev * hdev,void * data,struct sk_buff * skb)1093c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev, void *data,
1094d5859e22SJohan Hedberg struct sk_buff *skb)
1095d5859e22SJohan Hedberg {
1096c8992cffSLuiz Augusto von Dentz struct hci_rp_read_inq_rsp_tx_power *rp = data;
1097e3f3a1aeSLuiz Augusto von Dentz
1098e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1099d5859e22SJohan Hedberg
110045296acdSMarcel Holtmann if (rp->status)
1101c8992cffSLuiz Augusto von Dentz return rp->status;
110245296acdSMarcel Holtmann
110391c4e9b1SMarcel Holtmann hdev->inq_tx_power = rp->tx_power;
1104c8992cffSLuiz Augusto von Dentz
1105c8992cffSLuiz Augusto von Dentz return rp->status;
1106d5859e22SJohan Hedberg }
1107d5859e22SJohan Hedberg
hci_cc_read_def_err_data_reporting(struct hci_dev * hdev,void * data,struct sk_buff * skb)1108c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_def_err_data_reporting(struct hci_dev *hdev, void *data,
110900bce3fbSAlain Michaud struct sk_buff *skb)
111000bce3fbSAlain Michaud {
1111c8992cffSLuiz Augusto von Dentz struct hci_rp_read_def_err_data_reporting *rp = data;
1112e3f3a1aeSLuiz Augusto von Dentz
1113e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
111400bce3fbSAlain Michaud
111500bce3fbSAlain Michaud if (rp->status)
1116c8992cffSLuiz Augusto von Dentz return rp->status;
111700bce3fbSAlain Michaud
111800bce3fbSAlain Michaud hdev->err_data_reporting = rp->err_data_reporting;
1119c8992cffSLuiz Augusto von Dentz
1120c8992cffSLuiz Augusto von Dentz return rp->status;
112100bce3fbSAlain Michaud }
112200bce3fbSAlain Michaud
hci_cc_write_def_err_data_reporting(struct hci_dev * hdev,void * data,struct sk_buff * skb)1123c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_def_err_data_reporting(struct hci_dev *hdev, void *data,
112400bce3fbSAlain Michaud struct sk_buff *skb)
112500bce3fbSAlain Michaud {
1126c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
112700bce3fbSAlain Michaud struct hci_cp_write_def_err_data_reporting *cp;
112800bce3fbSAlain Michaud
1129e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1130e3f3a1aeSLuiz Augusto von Dentz
1131e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
1132c8992cffSLuiz Augusto von Dentz return rp->status;
113300bce3fbSAlain Michaud
113400bce3fbSAlain Michaud cp = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_ERR_DATA_REPORTING);
113500bce3fbSAlain Michaud if (!cp)
1136c8992cffSLuiz Augusto von Dentz return rp->status;
113700bce3fbSAlain Michaud
113800bce3fbSAlain Michaud hdev->err_data_reporting = cp->err_data_reporting;
1139c8992cffSLuiz Augusto von Dentz
1140c8992cffSLuiz Augusto von Dentz return rp->status;
114100bce3fbSAlain Michaud }
114200bce3fbSAlain Michaud
hci_cc_pin_code_reply(struct hci_dev * hdev,void * data,struct sk_buff * skb)1143c8992cffSLuiz Augusto von Dentz static u8 hci_cc_pin_code_reply(struct hci_dev *hdev, void *data,
1144c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
1145980e1a53SJohan Hedberg {
1146c8992cffSLuiz Augusto von Dentz struct hci_rp_pin_code_reply *rp = data;
1147980e1a53SJohan Hedberg struct hci_cp_pin_code_reply *cp;
1148980e1a53SJohan Hedberg struct hci_conn *conn;
1149980e1a53SJohan Hedberg
1150e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1151980e1a53SJohan Hedberg
115256e5cb86SJohan Hedberg hci_dev_lock(hdev);
115356e5cb86SJohan Hedberg
1154d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT))
1155744cf19eSJohan Hedberg mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
1156980e1a53SJohan Hedberg
1157fa1bd918SMikel Astiz if (rp->status)
115856e5cb86SJohan Hedberg goto unlock;
1159980e1a53SJohan Hedberg
1160980e1a53SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
1161980e1a53SJohan Hedberg if (!cp)
116256e5cb86SJohan Hedberg goto unlock;
1163980e1a53SJohan Hedberg
1164980e1a53SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1165980e1a53SJohan Hedberg if (conn)
1166980e1a53SJohan Hedberg conn->pin_length = cp->pin_len;
116756e5cb86SJohan Hedberg
116856e5cb86SJohan Hedberg unlock:
116956e5cb86SJohan Hedberg hci_dev_unlock(hdev);
1170c8992cffSLuiz Augusto von Dentz return rp->status;
1171980e1a53SJohan Hedberg }
1172980e1a53SJohan Hedberg
hci_cc_pin_code_neg_reply(struct hci_dev * hdev,void * data,struct sk_buff * skb)1173c8992cffSLuiz Augusto von Dentz static u8 hci_cc_pin_code_neg_reply(struct hci_dev *hdev, void *data,
1174c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
1175980e1a53SJohan Hedberg {
1176c8992cffSLuiz Augusto von Dentz struct hci_rp_pin_code_neg_reply *rp = data;
1177e3f3a1aeSLuiz Augusto von Dentz
1178e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1179980e1a53SJohan Hedberg
118056e5cb86SJohan Hedberg hci_dev_lock(hdev);
118156e5cb86SJohan Hedberg
1182d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT))
1183744cf19eSJohan Hedberg mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
1184980e1a53SJohan Hedberg rp->status);
118556e5cb86SJohan Hedberg
118656e5cb86SJohan Hedberg hci_dev_unlock(hdev);
1187c8992cffSLuiz Augusto von Dentz
1188c8992cffSLuiz Augusto von Dentz return rp->status;
1189980e1a53SJohan Hedberg }
119056e5cb86SJohan Hedberg
hci_cc_le_read_buffer_size(struct hci_dev * hdev,void * data,struct sk_buff * skb)1191c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_buffer_size(struct hci_dev *hdev, void *data,
11926ed58ec5SVille Tervo struct sk_buff *skb)
11936ed58ec5SVille Tervo {
1194c8992cffSLuiz Augusto von Dentz struct hci_rp_le_read_buffer_size *rp = data;
1195e3f3a1aeSLuiz Augusto von Dentz
1196e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
11976ed58ec5SVille Tervo
11986ed58ec5SVille Tervo if (rp->status)
1199c8992cffSLuiz Augusto von Dentz return rp->status;
12006ed58ec5SVille Tervo
12016ed58ec5SVille Tervo hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
12026ed58ec5SVille Tervo hdev->le_pkts = rp->le_max_pkt;
12036ed58ec5SVille Tervo
12046ed58ec5SVille Tervo hdev->le_cnt = hdev->le_pkts;
12056ed58ec5SVille Tervo
12066ed58ec5SVille Tervo BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
1207c8992cffSLuiz Augusto von Dentz
1208ad3f7986SSungwoo Kim if (hdev->le_mtu && hdev->le_mtu < HCI_MIN_LE_MTU)
1209ad3f7986SSungwoo Kim return HCI_ERROR_INVALID_PARAMETERS;
1210ad3f7986SSungwoo Kim
1211c8992cffSLuiz Augusto von Dentz return rp->status;
12126ed58ec5SVille Tervo }
1213980e1a53SJohan Hedberg
hci_cc_le_read_local_features(struct hci_dev * hdev,void * data,struct sk_buff * skb)1214c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_local_features(struct hci_dev *hdev, void *data,
121560e77321SJohan Hedberg struct sk_buff *skb)
121660e77321SJohan Hedberg {
1217c8992cffSLuiz Augusto von Dentz struct hci_rp_le_read_local_features *rp = data;
121860e77321SJohan Hedberg
121960e77321SJohan Hedberg BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
122060e77321SJohan Hedberg
122145296acdSMarcel Holtmann if (rp->status)
1222c8992cffSLuiz Augusto von Dentz return rp->status;
122345296acdSMarcel Holtmann
122460e77321SJohan Hedberg memcpy(hdev->le_features, rp->features, 8);
1225c8992cffSLuiz Augusto von Dentz
1226c8992cffSLuiz Augusto von Dentz return rp->status;
122760e77321SJohan Hedberg }
122860e77321SJohan Hedberg
hci_cc_le_read_adv_tx_power(struct hci_dev * hdev,void * data,struct sk_buff * skb)1229c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_adv_tx_power(struct hci_dev *hdev, void *data,
12308fa19098SJohan Hedberg struct sk_buff *skb)
12318fa19098SJohan Hedberg {
1232c8992cffSLuiz Augusto von Dentz struct hci_rp_le_read_adv_tx_power *rp = data;
1233e3f3a1aeSLuiz Augusto von Dentz
1234e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
12358fa19098SJohan Hedberg
123645296acdSMarcel Holtmann if (rp->status)
1237c8992cffSLuiz Augusto von Dentz return rp->status;
123845296acdSMarcel Holtmann
12398fa19098SJohan Hedberg hdev->adv_tx_power = rp->tx_power;
1240c8992cffSLuiz Augusto von Dentz
1241c8992cffSLuiz Augusto von Dentz return rp->status;
12428fa19098SJohan Hedberg }
12438fa19098SJohan Hedberg
hci_cc_user_confirm_reply(struct hci_dev * hdev,void * data,struct sk_buff * skb)1244c8992cffSLuiz Augusto von Dentz static u8 hci_cc_user_confirm_reply(struct hci_dev *hdev, void *data,
1245c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
1246a5c29683SJohan Hedberg {
1247c8992cffSLuiz Augusto von Dentz struct hci_rp_user_confirm_reply *rp = data;
1248e3f3a1aeSLuiz Augusto von Dentz
1249e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1250a5c29683SJohan Hedberg
125156e5cb86SJohan Hedberg hci_dev_lock(hdev);
125256e5cb86SJohan Hedberg
1253d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT))
125404124681SGustavo F. Padovan mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
125504124681SGustavo F. Padovan rp->status);
125656e5cb86SJohan Hedberg
125756e5cb86SJohan Hedberg hci_dev_unlock(hdev);
1258c8992cffSLuiz Augusto von Dentz
1259c8992cffSLuiz Augusto von Dentz return rp->status;
1260a5c29683SJohan Hedberg }
1261a5c29683SJohan Hedberg
hci_cc_user_confirm_neg_reply(struct hci_dev * hdev,void * data,struct sk_buff * skb)1262c8992cffSLuiz Augusto von Dentz static u8 hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, void *data,
1263a5c29683SJohan Hedberg struct sk_buff *skb)
1264a5c29683SJohan Hedberg {
1265c8992cffSLuiz Augusto von Dentz struct hci_rp_user_confirm_reply *rp = data;
1266e3f3a1aeSLuiz Augusto von Dentz
1267e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1268a5c29683SJohan Hedberg
126956e5cb86SJohan Hedberg hci_dev_lock(hdev);
127056e5cb86SJohan Hedberg
1271d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT))
1272744cf19eSJohan Hedberg mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
127304124681SGustavo F. Padovan ACL_LINK, 0, rp->status);
127456e5cb86SJohan Hedberg
127556e5cb86SJohan Hedberg hci_dev_unlock(hdev);
1276c8992cffSLuiz Augusto von Dentz
1277c8992cffSLuiz Augusto von Dentz return rp->status;
1278a5c29683SJohan Hedberg }
1279a5c29683SJohan Hedberg
hci_cc_user_passkey_reply(struct hci_dev * hdev,void * data,struct sk_buff * skb)1280c8992cffSLuiz Augusto von Dentz static u8 hci_cc_user_passkey_reply(struct hci_dev *hdev, void *data,
1281c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
12821143d458SBrian Gix {
1283c8992cffSLuiz Augusto von Dentz struct hci_rp_user_confirm_reply *rp = data;
1284e3f3a1aeSLuiz Augusto von Dentz
1285e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
12861143d458SBrian Gix
12871143d458SBrian Gix hci_dev_lock(hdev);
12881143d458SBrian Gix
1289d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT))
1290272d90dfSJohan Hedberg mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
1291272d90dfSJohan Hedberg 0, rp->status);
12921143d458SBrian Gix
12931143d458SBrian Gix hci_dev_unlock(hdev);
1294c8992cffSLuiz Augusto von Dentz
1295c8992cffSLuiz Augusto von Dentz return rp->status;
12961143d458SBrian Gix }
12971143d458SBrian Gix
hci_cc_user_passkey_neg_reply(struct hci_dev * hdev,void * data,struct sk_buff * skb)1298c8992cffSLuiz Augusto von Dentz static u8 hci_cc_user_passkey_neg_reply(struct hci_dev *hdev, void *data,
12991143d458SBrian Gix struct sk_buff *skb)
13001143d458SBrian Gix {
1301c8992cffSLuiz Augusto von Dentz struct hci_rp_user_confirm_reply *rp = data;
1302e3f3a1aeSLuiz Augusto von Dentz
1303e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
13041143d458SBrian Gix
13051143d458SBrian Gix hci_dev_lock(hdev);
13061143d458SBrian Gix
1307d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT))
13081143d458SBrian Gix mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
130904124681SGustavo F. Padovan ACL_LINK, 0, rp->status);
13101143d458SBrian Gix
13111143d458SBrian Gix hci_dev_unlock(hdev);
1312c8992cffSLuiz Augusto von Dentz
1313c8992cffSLuiz Augusto von Dentz return rp->status;
13141143d458SBrian Gix }
13151143d458SBrian Gix
hci_cc_read_local_oob_data(struct hci_dev * hdev,void * data,struct sk_buff * skb)1316c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_oob_data(struct hci_dev *hdev, void *data,
1317c35938b2SSzymon Janc struct sk_buff *skb)
1318c35938b2SSzymon Janc {
1319c8992cffSLuiz Augusto von Dentz struct hci_rp_read_local_oob_data *rp = data;
1320e3f3a1aeSLuiz Augusto von Dentz
1321e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1322c8992cffSLuiz Augusto von Dentz
1323c8992cffSLuiz Augusto von Dentz return rp->status;
13244d2d2796SMarcel Holtmann }
13254d2d2796SMarcel Holtmann
hci_cc_read_local_oob_ext_data(struct hci_dev * hdev,void * data,struct sk_buff * skb)1326c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_oob_ext_data(struct hci_dev *hdev, void *data,
13274d2d2796SMarcel Holtmann struct sk_buff *skb)
13284d2d2796SMarcel Holtmann {
1329c8992cffSLuiz Augusto von Dentz struct hci_rp_read_local_oob_ext_data *rp = data;
1330e3f3a1aeSLuiz Augusto von Dentz
1331e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1332c8992cffSLuiz Augusto von Dentz
1333c8992cffSLuiz Augusto von Dentz return rp->status;
1334c35938b2SSzymon Janc }
1335c35938b2SSzymon Janc
hci_cc_le_set_random_addr(struct hci_dev * hdev,void * data,struct sk_buff * skb)1336c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_random_addr(struct hci_dev *hdev, void *data,
1337c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
13387a4cd51dSMarcel Holtmann {
1339c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
13407a4cd51dSMarcel Holtmann bdaddr_t *sent;
13417a4cd51dSMarcel Holtmann
1342e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1343e3f3a1aeSLuiz Augusto von Dentz
1344e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
1345c8992cffSLuiz Augusto von Dentz return rp->status;
134645296acdSMarcel Holtmann
13477a4cd51dSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_RANDOM_ADDR);
13487a4cd51dSMarcel Holtmann if (!sent)
1349c8992cffSLuiz Augusto von Dentz return rp->status;
13507a4cd51dSMarcel Holtmann
13517a4cd51dSMarcel Holtmann hci_dev_lock(hdev);
13527a4cd51dSMarcel Holtmann
13537a4cd51dSMarcel Holtmann bacpy(&hdev->random_addr, sent);
13547a4cd51dSMarcel Holtmann
1355c45074d6SLuiz Augusto von Dentz if (!bacmp(&hdev->rpa, sent)) {
1356c45074d6SLuiz Augusto von Dentz hci_dev_clear_flag(hdev, HCI_RPA_EXPIRED);
1357c45074d6SLuiz Augusto von Dentz queue_delayed_work(hdev->workqueue, &hdev->rpa_expired,
1358c45074d6SLuiz Augusto von Dentz secs_to_jiffies(hdev->rpa_timeout));
1359c45074d6SLuiz Augusto von Dentz }
1360c45074d6SLuiz Augusto von Dentz
13617a4cd51dSMarcel Holtmann hci_dev_unlock(hdev);
1362c8992cffSLuiz Augusto von Dentz
1363c8992cffSLuiz Augusto von Dentz return rp->status;
13647a4cd51dSMarcel Holtmann }
13657a4cd51dSMarcel Holtmann
hci_cc_le_set_default_phy(struct hci_dev * hdev,void * data,struct sk_buff * skb)1366c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_default_phy(struct hci_dev *hdev, void *data,
1367c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
13680314f286SJaganath Kanakkassery {
1369c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
13700314f286SJaganath Kanakkassery struct hci_cp_le_set_default_phy *cp;
13710314f286SJaganath Kanakkassery
1372e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1373e3f3a1aeSLuiz Augusto von Dentz
1374e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
1375c8992cffSLuiz Augusto von Dentz return rp->status;
13760314f286SJaganath Kanakkassery
13770314f286SJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_DEFAULT_PHY);
13780314f286SJaganath Kanakkassery if (!cp)
1379c8992cffSLuiz Augusto von Dentz return rp->status;
13800314f286SJaganath Kanakkassery
13810314f286SJaganath Kanakkassery hci_dev_lock(hdev);
13820314f286SJaganath Kanakkassery
13830314f286SJaganath Kanakkassery hdev->le_tx_def_phys = cp->tx_phys;
13840314f286SJaganath Kanakkassery hdev->le_rx_def_phys = cp->rx_phys;
13850314f286SJaganath Kanakkassery
13860314f286SJaganath Kanakkassery hci_dev_unlock(hdev);
1387c8992cffSLuiz Augusto von Dentz
1388c8992cffSLuiz Augusto von Dentz return rp->status;
13890314f286SJaganath Kanakkassery }
13900314f286SJaganath Kanakkassery
hci_cc_le_set_adv_set_random_addr(struct hci_dev * hdev,void * data,struct sk_buff * skb)1391c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_adv_set_random_addr(struct hci_dev *hdev, void *data,
1392a73c046aSJaganath Kanakkassery struct sk_buff *skb)
1393a73c046aSJaganath Kanakkassery {
1394c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
1395a73c046aSJaganath Kanakkassery struct hci_cp_le_set_adv_set_rand_addr *cp;
1396c45074d6SLuiz Augusto von Dentz struct adv_info *adv;
1397a73c046aSJaganath Kanakkassery
1398e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1399e3f3a1aeSLuiz Augusto von Dentz
1400e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
1401c8992cffSLuiz Augusto von Dentz return rp->status;
1402a73c046aSJaganath Kanakkassery
1403a73c046aSJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_SET_RAND_ADDR);
1404c45074d6SLuiz Augusto von Dentz /* Update only in case the adv instance since handle 0x00 shall be using
1405c45074d6SLuiz Augusto von Dentz * HCI_OP_LE_SET_RANDOM_ADDR since that allows both extended and
1406c45074d6SLuiz Augusto von Dentz * non-extended adverting.
1407c45074d6SLuiz Augusto von Dentz */
1408c45074d6SLuiz Augusto von Dentz if (!cp || !cp->handle)
1409c8992cffSLuiz Augusto von Dentz return rp->status;
1410a73c046aSJaganath Kanakkassery
1411a73c046aSJaganath Kanakkassery hci_dev_lock(hdev);
1412a73c046aSJaganath Kanakkassery
1413c45074d6SLuiz Augusto von Dentz adv = hci_find_adv_instance(hdev, cp->handle);
1414c45074d6SLuiz Augusto von Dentz if (adv) {
1415c45074d6SLuiz Augusto von Dentz bacpy(&adv->random_addr, &cp->bdaddr);
1416c45074d6SLuiz Augusto von Dentz if (!bacmp(&hdev->rpa, &cp->bdaddr)) {
1417c45074d6SLuiz Augusto von Dentz adv->rpa_expired = false;
1418c45074d6SLuiz Augusto von Dentz queue_delayed_work(hdev->workqueue,
1419c45074d6SLuiz Augusto von Dentz &adv->rpa_expired_cb,
1420c45074d6SLuiz Augusto von Dentz secs_to_jiffies(hdev->rpa_timeout));
1421c45074d6SLuiz Augusto von Dentz }
1422a73c046aSJaganath Kanakkassery }
1423a73c046aSJaganath Kanakkassery
1424a73c046aSJaganath Kanakkassery hci_dev_unlock(hdev);
1425c8992cffSLuiz Augusto von Dentz
1426c8992cffSLuiz Augusto von Dentz return rp->status;
1427a73c046aSJaganath Kanakkassery }
1428a73c046aSJaganath Kanakkassery
hci_cc_le_remove_adv_set(struct hci_dev * hdev,void * data,struct sk_buff * skb)1429c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_remove_adv_set(struct hci_dev *hdev, void *data,
1430c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
1431cba6b758SLuiz Augusto von Dentz {
1432c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
1433cba6b758SLuiz Augusto von Dentz u8 *instance;
1434cba6b758SLuiz Augusto von Dentz int err;
1435cba6b758SLuiz Augusto von Dentz
1436e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1437e3f3a1aeSLuiz Augusto von Dentz
1438e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
1439c8992cffSLuiz Augusto von Dentz return rp->status;
1440cba6b758SLuiz Augusto von Dentz
1441cba6b758SLuiz Augusto von Dentz instance = hci_sent_cmd_data(hdev, HCI_OP_LE_REMOVE_ADV_SET);
1442cba6b758SLuiz Augusto von Dentz if (!instance)
1443c8992cffSLuiz Augusto von Dentz return rp->status;
1444cba6b758SLuiz Augusto von Dentz
1445cba6b758SLuiz Augusto von Dentz hci_dev_lock(hdev);
1446cba6b758SLuiz Augusto von Dentz
1447cba6b758SLuiz Augusto von Dentz err = hci_remove_adv_instance(hdev, *instance);
1448cba6b758SLuiz Augusto von Dentz if (!err)
1449cba6b758SLuiz Augusto von Dentz mgmt_advertising_removed(hci_skb_sk(hdev->sent_cmd), hdev,
1450cba6b758SLuiz Augusto von Dentz *instance);
1451cba6b758SLuiz Augusto von Dentz
1452cba6b758SLuiz Augusto von Dentz hci_dev_unlock(hdev);
1453c8992cffSLuiz Augusto von Dentz
1454c8992cffSLuiz Augusto von Dentz return rp->status;
1455cba6b758SLuiz Augusto von Dentz }
1456cba6b758SLuiz Augusto von Dentz
hci_cc_le_clear_adv_sets(struct hci_dev * hdev,void * data,struct sk_buff * skb)1457c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_clear_adv_sets(struct hci_dev *hdev, void *data,
1458c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
1459cba6b758SLuiz Augusto von Dentz {
1460c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
1461cba6b758SLuiz Augusto von Dentz struct adv_info *adv, *n;
1462cba6b758SLuiz Augusto von Dentz int err;
1463cba6b758SLuiz Augusto von Dentz
1464e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1465e3f3a1aeSLuiz Augusto von Dentz
1466e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
1467c8992cffSLuiz Augusto von Dentz return rp->status;
1468cba6b758SLuiz Augusto von Dentz
1469cba6b758SLuiz Augusto von Dentz if (!hci_sent_cmd_data(hdev, HCI_OP_LE_CLEAR_ADV_SETS))
1470c8992cffSLuiz Augusto von Dentz return rp->status;
1471cba6b758SLuiz Augusto von Dentz
1472cba6b758SLuiz Augusto von Dentz hci_dev_lock(hdev);
1473cba6b758SLuiz Augusto von Dentz
1474cba6b758SLuiz Augusto von Dentz list_for_each_entry_safe(adv, n, &hdev->adv_instances, list) {
1475cba6b758SLuiz Augusto von Dentz u8 instance = adv->instance;
1476cba6b758SLuiz Augusto von Dentz
1477cba6b758SLuiz Augusto von Dentz err = hci_remove_adv_instance(hdev, instance);
1478cba6b758SLuiz Augusto von Dentz if (!err)
1479cba6b758SLuiz Augusto von Dentz mgmt_advertising_removed(hci_skb_sk(hdev->sent_cmd),
1480cba6b758SLuiz Augusto von Dentz hdev, instance);
1481cba6b758SLuiz Augusto von Dentz }
1482cba6b758SLuiz Augusto von Dentz
1483cba6b758SLuiz Augusto von Dentz hci_dev_unlock(hdev);
1484c8992cffSLuiz Augusto von Dentz
1485c8992cffSLuiz Augusto von Dentz return rp->status;
1486cba6b758SLuiz Augusto von Dentz }
1487cba6b758SLuiz Augusto von Dentz
hci_cc_le_read_transmit_power(struct hci_dev * hdev,void * data,struct sk_buff * skb)1488c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_transmit_power(struct hci_dev *hdev, void *data,
14897c395ea5SDaniel Winkler struct sk_buff *skb)
14907c395ea5SDaniel Winkler {
1491c8992cffSLuiz Augusto von Dentz struct hci_rp_le_read_transmit_power *rp = data;
1492e3f3a1aeSLuiz Augusto von Dentz
1493e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
14947c395ea5SDaniel Winkler
14957c395ea5SDaniel Winkler if (rp->status)
1496c8992cffSLuiz Augusto von Dentz return rp->status;
14977c395ea5SDaniel Winkler
14987c395ea5SDaniel Winkler hdev->min_le_tx_power = rp->min_le_tx_power;
14997c395ea5SDaniel Winkler hdev->max_le_tx_power = rp->max_le_tx_power;
1500c8992cffSLuiz Augusto von Dentz
1501c8992cffSLuiz Augusto von Dentz return rp->status;
15027c395ea5SDaniel Winkler }
15037c395ea5SDaniel Winkler
hci_cc_le_set_privacy_mode(struct hci_dev * hdev,void * data,struct sk_buff * skb)1504853b70b5SLuiz Augusto von Dentz static u8 hci_cc_le_set_privacy_mode(struct hci_dev *hdev, void *data,
1505853b70b5SLuiz Augusto von Dentz struct sk_buff *skb)
1506853b70b5SLuiz Augusto von Dentz {
1507853b70b5SLuiz Augusto von Dentz struct hci_ev_status *rp = data;
1508853b70b5SLuiz Augusto von Dentz struct hci_cp_le_set_privacy_mode *cp;
1509853b70b5SLuiz Augusto von Dentz struct hci_conn_params *params;
1510853b70b5SLuiz Augusto von Dentz
1511853b70b5SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1512853b70b5SLuiz Augusto von Dentz
1513853b70b5SLuiz Augusto von Dentz if (rp->status)
1514853b70b5SLuiz Augusto von Dentz return rp->status;
1515853b70b5SLuiz Augusto von Dentz
1516853b70b5SLuiz Augusto von Dentz cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_PRIVACY_MODE);
1517853b70b5SLuiz Augusto von Dentz if (!cp)
1518853b70b5SLuiz Augusto von Dentz return rp->status;
1519853b70b5SLuiz Augusto von Dentz
1520853b70b5SLuiz Augusto von Dentz hci_dev_lock(hdev);
1521853b70b5SLuiz Augusto von Dentz
1522853b70b5SLuiz Augusto von Dentz params = hci_conn_params_lookup(hdev, &cp->bdaddr, cp->bdaddr_type);
1523853b70b5SLuiz Augusto von Dentz if (params)
1524195ef75eSPauli Virtanen WRITE_ONCE(params->privacy_mode, cp->mode);
1525853b70b5SLuiz Augusto von Dentz
1526853b70b5SLuiz Augusto von Dentz hci_dev_unlock(hdev);
1527853b70b5SLuiz Augusto von Dentz
1528853b70b5SLuiz Augusto von Dentz return rp->status;
1529853b70b5SLuiz Augusto von Dentz }
1530853b70b5SLuiz Augusto von Dentz
hci_cc_le_set_adv_enable(struct hci_dev * hdev,void * data,struct sk_buff * skb)1531c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_adv_enable(struct hci_dev *hdev, void *data,
1532c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
1533c1d5dc4aSJohan Hedberg {
1534c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
1535e3f3a1aeSLuiz Augusto von Dentz __u8 *sent;
1536c1d5dc4aSJohan Hedberg
1537e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1538e3f3a1aeSLuiz Augusto von Dentz
1539e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
1540c8992cffSLuiz Augusto von Dentz return rp->status;
1541c1d5dc4aSJohan Hedberg
154245296acdSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
154345296acdSMarcel Holtmann if (!sent)
1544c8992cffSLuiz Augusto von Dentz return rp->status;
15453c857757SJohan Hedberg
1546c1d5dc4aSJohan Hedberg hci_dev_lock(hdev);
1547c1d5dc4aSJohan Hedberg
154849c922bbSStephen Hemminger /* If we're doing connection initiation as peripheral. Set a
15493c857757SJohan Hedberg * timeout in case something goes wrong.
15503c857757SJohan Hedberg */
15513c857757SJohan Hedberg if (*sent) {
15523c857757SJohan Hedberg struct hci_conn *conn;
15533c857757SJohan Hedberg
1554a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_LE_ADV);
155566c417c1SJohan Hedberg
1556e7d9ab73SJakub Pawlowski conn = hci_lookup_le_connect(hdev);
15573c857757SJohan Hedberg if (conn)
15583c857757SJohan Hedberg queue_delayed_work(hdev->workqueue,
15593c857757SJohan Hedberg &conn->le_conn_timeout,
156009ae260bSJohan Hedberg conn->conn_timeout);
156166c417c1SJohan Hedberg } else {
1562a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LE_ADV);
15633c857757SJohan Hedberg }
15643c857757SJohan Hedberg
156504b4edcbSJohan Hedberg hci_dev_unlock(hdev);
1566c8992cffSLuiz Augusto von Dentz
1567c8992cffSLuiz Augusto von Dentz return rp->status;
1568c1d5dc4aSJohan Hedberg }
1569c1d5dc4aSJohan Hedberg
hci_cc_le_set_ext_adv_enable(struct hci_dev * hdev,void * data,struct sk_buff * skb)1570c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_ext_adv_enable(struct hci_dev *hdev, void *data,
1571de181e88SJaganath Kanakkassery struct sk_buff *skb)
1572de181e88SJaganath Kanakkassery {
1573de181e88SJaganath Kanakkassery struct hci_cp_le_set_ext_adv_enable *cp;
157410279313SLuiz Augusto von Dentz struct hci_cp_ext_adv_set *set;
157510279313SLuiz Augusto von Dentz struct adv_info *adv = NULL, *n;
1576c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
1577de181e88SJaganath Kanakkassery
1578e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1579e3f3a1aeSLuiz Augusto von Dentz
1580e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
1581c8992cffSLuiz Augusto von Dentz return rp->status;
1582de181e88SJaganath Kanakkassery
1583de181e88SJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_ADV_ENABLE);
1584de181e88SJaganath Kanakkassery if (!cp)
1585c8992cffSLuiz Augusto von Dentz return rp->status;
1586de181e88SJaganath Kanakkassery
158710279313SLuiz Augusto von Dentz set = (void *)cp->data;
158810279313SLuiz Augusto von Dentz
1589de181e88SJaganath Kanakkassery hci_dev_lock(hdev);
1590de181e88SJaganath Kanakkassery
159110279313SLuiz Augusto von Dentz if (cp->num_of_sets)
159210279313SLuiz Augusto von Dentz adv = hci_find_adv_instance(hdev, set->handle);
159310279313SLuiz Augusto von Dentz
1594de181e88SJaganath Kanakkassery if (cp->enable) {
1595de181e88SJaganath Kanakkassery struct hci_conn *conn;
1596de181e88SJaganath Kanakkassery
1597de181e88SJaganath Kanakkassery hci_dev_set_flag(hdev, HCI_LE_ADV);
1598de181e88SJaganath Kanakkassery
15996a42e9bfSIulia Tanasescu if (adv && !adv->periodic)
160010279313SLuiz Augusto von Dentz adv->enabled = true;
160110279313SLuiz Augusto von Dentz
1602de181e88SJaganath Kanakkassery conn = hci_lookup_le_connect(hdev);
1603de181e88SJaganath Kanakkassery if (conn)
1604de181e88SJaganath Kanakkassery queue_delayed_work(hdev->workqueue,
1605de181e88SJaganath Kanakkassery &conn->le_conn_timeout,
1606de181e88SJaganath Kanakkassery conn->conn_timeout);
160745b7749fSJaganath Kanakkassery } else {
16082128939fSArchie Pusaka if (cp->num_of_sets) {
16092128939fSArchie Pusaka if (adv)
161010279313SLuiz Augusto von Dentz adv->enabled = false;
16112128939fSArchie Pusaka
161210279313SLuiz Augusto von Dentz /* If just one instance was disabled check if there are
161310279313SLuiz Augusto von Dentz * any other instance enabled before clearing HCI_LE_ADV
161410279313SLuiz Augusto von Dentz */
161510279313SLuiz Augusto von Dentz list_for_each_entry_safe(adv, n, &hdev->adv_instances,
161610279313SLuiz Augusto von Dentz list) {
161710279313SLuiz Augusto von Dentz if (adv->enabled)
161810279313SLuiz Augusto von Dentz goto unlock;
161910279313SLuiz Augusto von Dentz }
162010279313SLuiz Augusto von Dentz } else {
162110279313SLuiz Augusto von Dentz /* All instances shall be considered disabled */
162210279313SLuiz Augusto von Dentz list_for_each_entry_safe(adv, n, &hdev->adv_instances,
162310279313SLuiz Augusto von Dentz list)
162410279313SLuiz Augusto von Dentz adv->enabled = false;
162510279313SLuiz Augusto von Dentz }
162610279313SLuiz Augusto von Dentz
162745b7749fSJaganath Kanakkassery hci_dev_clear_flag(hdev, HCI_LE_ADV);
1628de181e88SJaganath Kanakkassery }
1629de181e88SJaganath Kanakkassery
163010279313SLuiz Augusto von Dentz unlock:
1631de181e88SJaganath Kanakkassery hci_dev_unlock(hdev);
1632c8992cffSLuiz Augusto von Dentz return rp->status;
1633de181e88SJaganath Kanakkassery }
1634de181e88SJaganath Kanakkassery
hci_cc_le_set_scan_param(struct hci_dev * hdev,void * data,struct sk_buff * skb)1635c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_scan_param(struct hci_dev *hdev, void *data,
1636c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
1637533553f8SMarcel Holtmann {
1638533553f8SMarcel Holtmann struct hci_cp_le_set_scan_param *cp;
1639c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
1640533553f8SMarcel Holtmann
1641e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1642e3f3a1aeSLuiz Augusto von Dentz
1643e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
1644c8992cffSLuiz Augusto von Dentz return rp->status;
164545296acdSMarcel Holtmann
1646533553f8SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_PARAM);
1647533553f8SMarcel Holtmann if (!cp)
1648c8992cffSLuiz Augusto von Dentz return rp->status;
1649533553f8SMarcel Holtmann
1650533553f8SMarcel Holtmann hci_dev_lock(hdev);
1651533553f8SMarcel Holtmann
1652533553f8SMarcel Holtmann hdev->le_scan_type = cp->type;
1653533553f8SMarcel Holtmann
1654533553f8SMarcel Holtmann hci_dev_unlock(hdev);
1655c8992cffSLuiz Augusto von Dentz
1656c8992cffSLuiz Augusto von Dentz return rp->status;
1657533553f8SMarcel Holtmann }
1658533553f8SMarcel Holtmann
hci_cc_le_set_ext_scan_param(struct hci_dev * hdev,void * data,struct sk_buff * skb)1659c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_ext_scan_param(struct hci_dev *hdev, void *data,
1660a2344b9eSJaganath Kanakkassery struct sk_buff *skb)
1661a2344b9eSJaganath Kanakkassery {
1662a2344b9eSJaganath Kanakkassery struct hci_cp_le_set_ext_scan_params *cp;
1663c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
1664a2344b9eSJaganath Kanakkassery struct hci_cp_le_scan_phy_params *phy_param;
1665a2344b9eSJaganath Kanakkassery
1666e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1667e3f3a1aeSLuiz Augusto von Dentz
1668e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
1669c8992cffSLuiz Augusto von Dentz return rp->status;
1670a2344b9eSJaganath Kanakkassery
1671a2344b9eSJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_SCAN_PARAMS);
1672a2344b9eSJaganath Kanakkassery if (!cp)
1673c8992cffSLuiz Augusto von Dentz return rp->status;
1674a2344b9eSJaganath Kanakkassery
1675a2344b9eSJaganath Kanakkassery phy_param = (void *)cp->data;
1676a2344b9eSJaganath Kanakkassery
1677a2344b9eSJaganath Kanakkassery hci_dev_lock(hdev);
1678a2344b9eSJaganath Kanakkassery
1679a2344b9eSJaganath Kanakkassery hdev->le_scan_type = phy_param->type;
1680a2344b9eSJaganath Kanakkassery
1681a2344b9eSJaganath Kanakkassery hci_dev_unlock(hdev);
1682c8992cffSLuiz Augusto von Dentz
1683c8992cffSLuiz Augusto von Dentz return rp->status;
1684a2344b9eSJaganath Kanakkassery }
1685a2344b9eSJaganath Kanakkassery
has_pending_adv_report(struct hci_dev * hdev)1686b9a6328fSJohan Hedberg static bool has_pending_adv_report(struct hci_dev *hdev)
1687b9a6328fSJohan Hedberg {
1688b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery;
1689b9a6328fSJohan Hedberg
1690b9a6328fSJohan Hedberg return bacmp(&d->last_adv_addr, BDADDR_ANY);
1691b9a6328fSJohan Hedberg }
1692b9a6328fSJohan Hedberg
clear_pending_adv_report(struct hci_dev * hdev)1693b9a6328fSJohan Hedberg static void clear_pending_adv_report(struct hci_dev *hdev)
1694b9a6328fSJohan Hedberg {
1695b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery;
1696b9a6328fSJohan Hedberg
1697b9a6328fSJohan Hedberg bacpy(&d->last_adv_addr, BDADDR_ANY);
1698b9a6328fSJohan Hedberg d->last_adv_data_len = 0;
1699b9a6328fSJohan Hedberg }
1700b9a6328fSJohan Hedberg
store_pending_adv_report(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 bdaddr_type,s8 rssi,u32 flags,u8 * data,u8 len)1701b9a6328fSJohan Hedberg static void store_pending_adv_report(struct hci_dev *hdev, bdaddr_t *bdaddr,
1702c70a7e4cSMarcel Holtmann u8 bdaddr_type, s8 rssi, u32 flags,
1703c70a7e4cSMarcel Holtmann u8 *data, u8 len)
1704b9a6328fSJohan Hedberg {
1705b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery;
1706b9a6328fSJohan Hedberg
1707112b5090SLuiz Augusto von Dentz if (len > max_adv_len(hdev))
1708a2ec905dSAlain Michaud return;
1709a2ec905dSAlain Michaud
1710b9a6328fSJohan Hedberg bacpy(&d->last_adv_addr, bdaddr);
1711b9a6328fSJohan Hedberg d->last_adv_addr_type = bdaddr_type;
1712ff5cd29fSJohan Hedberg d->last_adv_rssi = rssi;
1713c70a7e4cSMarcel Holtmann d->last_adv_flags = flags;
1714b9a6328fSJohan Hedberg memcpy(d->last_adv_data, data, len);
1715b9a6328fSJohan Hedberg d->last_adv_data_len = len;
1716b9a6328fSJohan Hedberg }
1717b9a6328fSJohan Hedberg
le_set_scan_enable_complete(struct hci_dev * hdev,u8 enable)17183baef810SJaganath Kanakkassery static void le_set_scan_enable_complete(struct hci_dev *hdev, u8 enable)
1719eb9d91f5SAndre Guedes {
17205c1a4c8fSJaganath Kanakkassery hci_dev_lock(hdev);
17215c1a4c8fSJaganath Kanakkassery
17223baef810SJaganath Kanakkassery switch (enable) {
17233fd319b8SAndre Guedes case LE_SCAN_ENABLE:
1724a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_LE_SCAN);
1725b9a6328fSJohan Hedberg if (hdev->le_scan_type == LE_SCAN_ACTIVE)
1726b9a6328fSJohan Hedberg clear_pending_adv_report(hdev);
1727b338d917SBrian Gix if (hci_dev_test_flag(hdev, HCI_MESH))
1728b338d917SBrian Gix hci_discovery_set_state(hdev, DISCOVERY_FINDING);
172968a8aea4SAndrei Emeltchenko break;
173068a8aea4SAndrei Emeltchenko
173176a388beSAndre Guedes case LE_SCAN_DISABLE:
1732b9a6328fSJohan Hedberg /* We do this here instead of when setting DISCOVERY_STOPPED
1733b9a6328fSJohan Hedberg * since the latter would potentially require waiting for
1734b9a6328fSJohan Hedberg * inquiry to stop too.
1735b9a6328fSJohan Hedberg */
1736b9a6328fSJohan Hedberg if (has_pending_adv_report(hdev)) {
1737b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery;
1738b9a6328fSJohan Hedberg
1739b9a6328fSJohan Hedberg mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
1740ab0aa433SJohan Hedberg d->last_adv_addr_type, NULL,
1741c70a7e4cSMarcel Holtmann d->last_adv_rssi, d->last_adv_flags,
1742ab0aa433SJohan Hedberg d->last_adv_data,
1743b338d917SBrian Gix d->last_adv_data_len, NULL, 0, 0);
1744b9a6328fSJohan Hedberg }
1745b9a6328fSJohan Hedberg
1746317ac8cbSJohan Hedberg /* Cancel this timer so that we don't try to disable scanning
1747317ac8cbSJohan Hedberg * when it's already disabled.
1748317ac8cbSJohan Hedberg */
1749317ac8cbSJohan Hedberg cancel_delayed_work(&hdev->le_scan_disable);
1750317ac8cbSJohan Hedberg
1751a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LE_SCAN);
1752e8bb6b97SJohan Hedberg
175381ad6fd9SJohan Hedberg /* The HCI_LE_SCAN_INTERRUPTED flag indicates that we
175481ad6fd9SJohan Hedberg * interrupted scanning due to a connect request. Mark
1755abfeea47SLuiz Augusto von Dentz * therefore discovery as stopped.
175681ad6fd9SJohan Hedberg */
1757a69d8927SMarcel Holtmann if (hci_dev_test_and_clear_flag(hdev, HCI_LE_SCAN_INTERRUPTED))
175881ad6fd9SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1759b338d917SBrian Gix else if (!hci_dev_test_flag(hdev, HCI_LE_ADV) &&
1760b338d917SBrian Gix hdev->discovery.state == DISCOVERY_FINDING)
1761b338d917SBrian Gix queue_work(hdev->workqueue, &hdev->reenable_adv_work);
1762e8bb6b97SJohan Hedberg
176368a8aea4SAndrei Emeltchenko break;
176468a8aea4SAndrei Emeltchenko
176568a8aea4SAndrei Emeltchenko default:
17662064ee33SMarcel Holtmann bt_dev_err(hdev, "use of reserved LE_Scan_Enable param %d",
17673baef810SJaganath Kanakkassery enable);
176868a8aea4SAndrei Emeltchenko break;
176935815085SAndre Guedes }
17705c1a4c8fSJaganath Kanakkassery
17715c1a4c8fSJaganath Kanakkassery hci_dev_unlock(hdev);
1772eb9d91f5SAndre Guedes }
1773eb9d91f5SAndre Guedes
hci_cc_le_set_scan_enable(struct hci_dev * hdev,void * data,struct sk_buff * skb)1774c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_scan_enable(struct hci_dev *hdev, void *data,
17753baef810SJaganath Kanakkassery struct sk_buff *skb)
17763baef810SJaganath Kanakkassery {
17773baef810SJaganath Kanakkassery struct hci_cp_le_set_scan_enable *cp;
1778c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
17793baef810SJaganath Kanakkassery
1780e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1781e3f3a1aeSLuiz Augusto von Dentz
1782e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
1783c8992cffSLuiz Augusto von Dentz return rp->status;
17843baef810SJaganath Kanakkassery
17853baef810SJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
17863baef810SJaganath Kanakkassery if (!cp)
1787c8992cffSLuiz Augusto von Dentz return rp->status;
17883baef810SJaganath Kanakkassery
17893baef810SJaganath Kanakkassery le_set_scan_enable_complete(hdev, cp->enable);
1790c8992cffSLuiz Augusto von Dentz
1791c8992cffSLuiz Augusto von Dentz return rp->status;
17923baef810SJaganath Kanakkassery }
17933baef810SJaganath Kanakkassery
hci_cc_le_set_ext_scan_enable(struct hci_dev * hdev,void * data,struct sk_buff * skb)1794c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_ext_scan_enable(struct hci_dev *hdev, void *data,
1795a2344b9eSJaganath Kanakkassery struct sk_buff *skb)
1796a2344b9eSJaganath Kanakkassery {
1797a2344b9eSJaganath Kanakkassery struct hci_cp_le_set_ext_scan_enable *cp;
1798c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
1799a2344b9eSJaganath Kanakkassery
1800e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1801e3f3a1aeSLuiz Augusto von Dentz
1802e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
1803c8992cffSLuiz Augusto von Dentz return rp->status;
1804a2344b9eSJaganath Kanakkassery
1805a2344b9eSJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_SCAN_ENABLE);
1806a2344b9eSJaganath Kanakkassery if (!cp)
1807c8992cffSLuiz Augusto von Dentz return rp->status;
1808a2344b9eSJaganath Kanakkassery
1809a2344b9eSJaganath Kanakkassery le_set_scan_enable_complete(hdev, cp->enable);
1810c8992cffSLuiz Augusto von Dentz
1811c8992cffSLuiz Augusto von Dentz return rp->status;
1812a2344b9eSJaganath Kanakkassery }
1813a2344b9eSJaganath Kanakkassery
hci_cc_le_read_num_adv_sets(struct hci_dev * hdev,void * data,struct sk_buff * skb)1814c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_num_adv_sets(struct hci_dev *hdev, void *data,
18156b49bcb4SJaganath Kanakkassery struct sk_buff *skb)
18166b49bcb4SJaganath Kanakkassery {
1817c8992cffSLuiz Augusto von Dentz struct hci_rp_le_read_num_supported_adv_sets *rp = data;
1818e3f3a1aeSLuiz Augusto von Dentz
1819e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x No of Adv sets %u", rp->status,
18206b49bcb4SJaganath Kanakkassery rp->num_of_sets);
18216b49bcb4SJaganath Kanakkassery
18226b49bcb4SJaganath Kanakkassery if (rp->status)
1823c8992cffSLuiz Augusto von Dentz return rp->status;
18246b49bcb4SJaganath Kanakkassery
18256b49bcb4SJaganath Kanakkassery hdev->le_num_of_adv_sets = rp->num_of_sets;
1826c8992cffSLuiz Augusto von Dentz
1827c8992cffSLuiz Augusto von Dentz return rp->status;
18286b49bcb4SJaganath Kanakkassery }
18296b49bcb4SJaganath Kanakkassery
hci_cc_le_read_accept_list_size(struct hci_dev * hdev,void * data,struct sk_buff * skb)1830c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_accept_list_size(struct hci_dev *hdev, void *data,
1831cf1d081fSJohan Hedberg struct sk_buff *skb)
1832cf1d081fSJohan Hedberg {
1833c8992cffSLuiz Augusto von Dentz struct hci_rp_le_read_accept_list_size *rp = data;
1834e3f3a1aeSLuiz Augusto von Dentz
1835e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x size %u", rp->status, rp->size);
1836cf1d081fSJohan Hedberg
183745296acdSMarcel Holtmann if (rp->status)
1838c8992cffSLuiz Augusto von Dentz return rp->status;
183945296acdSMarcel Holtmann
18403d4f9c00SArchie Pusaka hdev->le_accept_list_size = rp->size;
1841c8992cffSLuiz Augusto von Dentz
1842c8992cffSLuiz Augusto von Dentz return rp->status;
1843cf1d081fSJohan Hedberg }
1844cf1d081fSJohan Hedberg
hci_cc_le_clear_accept_list(struct hci_dev * hdev,void * data,struct sk_buff * skb)1845c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_clear_accept_list(struct hci_dev *hdev, void *data,
18460f36b589SMarcel Holtmann struct sk_buff *skb)
18470f36b589SMarcel Holtmann {
1848c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
18490f36b589SMarcel Holtmann
1850e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1851e3f3a1aeSLuiz Augusto von Dentz
1852e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
1853c8992cffSLuiz Augusto von Dentz return rp->status;
185445296acdSMarcel Holtmann
18555e2b6064SNiels Dossche hci_dev_lock(hdev);
18563d4f9c00SArchie Pusaka hci_bdaddr_list_clear(&hdev->le_accept_list);
18575e2b6064SNiels Dossche hci_dev_unlock(hdev);
1858c8992cffSLuiz Augusto von Dentz
1859c8992cffSLuiz Augusto von Dentz return rp->status;
18600f36b589SMarcel Holtmann }
18610f36b589SMarcel Holtmann
hci_cc_le_add_to_accept_list(struct hci_dev * hdev,void * data,struct sk_buff * skb)1862c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_add_to_accept_list(struct hci_dev *hdev, void *data,
18630f36b589SMarcel Holtmann struct sk_buff *skb)
18640f36b589SMarcel Holtmann {
18653d4f9c00SArchie Pusaka struct hci_cp_le_add_to_accept_list *sent;
1866c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
18670f36b589SMarcel Holtmann
1868e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1869e3f3a1aeSLuiz Augusto von Dentz
1870e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
1871c8992cffSLuiz Augusto von Dentz return rp->status;
187245296acdSMarcel Holtmann
18733d4f9c00SArchie Pusaka sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_ACCEPT_LIST);
18740f36b589SMarcel Holtmann if (!sent)
1875c8992cffSLuiz Augusto von Dentz return rp->status;
18760f36b589SMarcel Holtmann
18775e2b6064SNiels Dossche hci_dev_lock(hdev);
18783d4f9c00SArchie Pusaka hci_bdaddr_list_add(&hdev->le_accept_list, &sent->bdaddr,
1879dcc36c16SJohan Hedberg sent->bdaddr_type);
18805e2b6064SNiels Dossche hci_dev_unlock(hdev);
1881c8992cffSLuiz Augusto von Dentz
1882c8992cffSLuiz Augusto von Dentz return rp->status;
18830f36b589SMarcel Holtmann }
18840f36b589SMarcel Holtmann
hci_cc_le_del_from_accept_list(struct hci_dev * hdev,void * data,struct sk_buff * skb)1885c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_del_from_accept_list(struct hci_dev *hdev, void *data,
18860f36b589SMarcel Holtmann struct sk_buff *skb)
18870f36b589SMarcel Holtmann {
18883d4f9c00SArchie Pusaka struct hci_cp_le_del_from_accept_list *sent;
1889c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
18900f36b589SMarcel Holtmann
1891e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1892e3f3a1aeSLuiz Augusto von Dentz
1893e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
1894c8992cffSLuiz Augusto von Dentz return rp->status;
189545296acdSMarcel Holtmann
18963d4f9c00SArchie Pusaka sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_ACCEPT_LIST);
18970f36b589SMarcel Holtmann if (!sent)
1898c8992cffSLuiz Augusto von Dentz return rp->status;
18990f36b589SMarcel Holtmann
19005e2b6064SNiels Dossche hci_dev_lock(hdev);
19013d4f9c00SArchie Pusaka hci_bdaddr_list_del(&hdev->le_accept_list, &sent->bdaddr,
1902dcc36c16SJohan Hedberg sent->bdaddr_type);
19035e2b6064SNiels Dossche hci_dev_unlock(hdev);
1904c8992cffSLuiz Augusto von Dentz
1905c8992cffSLuiz Augusto von Dentz return rp->status;
19060f36b589SMarcel Holtmann }
19070f36b589SMarcel Holtmann
hci_cc_le_read_supported_states(struct hci_dev * hdev,void * data,struct sk_buff * skb)1908c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_supported_states(struct hci_dev *hdev, void *data,
19099b008c04SJohan Hedberg struct sk_buff *skb)
19109b008c04SJohan Hedberg {
1911c8992cffSLuiz Augusto von Dentz struct hci_rp_le_read_supported_states *rp = data;
1912e3f3a1aeSLuiz Augusto von Dentz
1913e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
19149b008c04SJohan Hedberg
191545296acdSMarcel Holtmann if (rp->status)
1916c8992cffSLuiz Augusto von Dentz return rp->status;
191745296acdSMarcel Holtmann
19189b008c04SJohan Hedberg memcpy(hdev->le_states, rp->le_states, 8);
1919c8992cffSLuiz Augusto von Dentz
1920c8992cffSLuiz Augusto von Dentz return rp->status;
19219b008c04SJohan Hedberg }
19229b008c04SJohan Hedberg
hci_cc_le_read_def_data_len(struct hci_dev * hdev,void * data,struct sk_buff * skb)1923c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_def_data_len(struct hci_dev *hdev, void *data,
1924a8e1bfaaSMarcel Holtmann struct sk_buff *skb)
1925a8e1bfaaSMarcel Holtmann {
1926c8992cffSLuiz Augusto von Dentz struct hci_rp_le_read_def_data_len *rp = data;
1927e3f3a1aeSLuiz Augusto von Dentz
1928e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1929a8e1bfaaSMarcel Holtmann
1930a8e1bfaaSMarcel Holtmann if (rp->status)
1931c8992cffSLuiz Augusto von Dentz return rp->status;
1932a8e1bfaaSMarcel Holtmann
1933a8e1bfaaSMarcel Holtmann hdev->le_def_tx_len = le16_to_cpu(rp->tx_len);
1934a8e1bfaaSMarcel Holtmann hdev->le_def_tx_time = le16_to_cpu(rp->tx_time);
1935c8992cffSLuiz Augusto von Dentz
1936c8992cffSLuiz Augusto von Dentz return rp->status;
1937a8e1bfaaSMarcel Holtmann }
1938a8e1bfaaSMarcel Holtmann
hci_cc_le_write_def_data_len(struct hci_dev * hdev,void * data,struct sk_buff * skb)1939c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_write_def_data_len(struct hci_dev *hdev, void *data,
1940a8e1bfaaSMarcel Holtmann struct sk_buff *skb)
1941a8e1bfaaSMarcel Holtmann {
1942a8e1bfaaSMarcel Holtmann struct hci_cp_le_write_def_data_len *sent;
1943c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
1944a8e1bfaaSMarcel Holtmann
1945e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1946e3f3a1aeSLuiz Augusto von Dentz
1947e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
1948c8992cffSLuiz Augusto von Dentz return rp->status;
1949a8e1bfaaSMarcel Holtmann
1950a8e1bfaaSMarcel Holtmann sent = hci_sent_cmd_data(hdev, HCI_OP_LE_WRITE_DEF_DATA_LEN);
1951a8e1bfaaSMarcel Holtmann if (!sent)
1952c8992cffSLuiz Augusto von Dentz return rp->status;
1953a8e1bfaaSMarcel Holtmann
1954a8e1bfaaSMarcel Holtmann hdev->le_def_tx_len = le16_to_cpu(sent->tx_len);
1955a8e1bfaaSMarcel Holtmann hdev->le_def_tx_time = le16_to_cpu(sent->tx_time);
1956c8992cffSLuiz Augusto von Dentz
1957c8992cffSLuiz Augusto von Dentz return rp->status;
1958a8e1bfaaSMarcel Holtmann }
1959a8e1bfaaSMarcel Holtmann
hci_cc_le_add_to_resolv_list(struct hci_dev * hdev,void * data,struct sk_buff * skb)1960c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_add_to_resolv_list(struct hci_dev *hdev, void *data,
1961b950aa88SAnkit Navik struct sk_buff *skb)
1962b950aa88SAnkit Navik {
1963b950aa88SAnkit Navik struct hci_cp_le_add_to_resolv_list *sent;
1964c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
1965b950aa88SAnkit Navik
1966e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1967e3f3a1aeSLuiz Augusto von Dentz
1968e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
1969c8992cffSLuiz Augusto von Dentz return rp->status;
1970b950aa88SAnkit Navik
1971b950aa88SAnkit Navik sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_RESOLV_LIST);
1972b950aa88SAnkit Navik if (!sent)
1973c8992cffSLuiz Augusto von Dentz return rp->status;
1974b950aa88SAnkit Navik
19755e2b6064SNiels Dossche hci_dev_lock(hdev);
1976b950aa88SAnkit Navik hci_bdaddr_list_add_with_irk(&hdev->le_resolv_list, &sent->bdaddr,
1977b950aa88SAnkit Navik sent->bdaddr_type, sent->peer_irk,
1978b950aa88SAnkit Navik sent->local_irk);
19795e2b6064SNiels Dossche hci_dev_unlock(hdev);
1980c8992cffSLuiz Augusto von Dentz
1981c8992cffSLuiz Augusto von Dentz return rp->status;
1982b950aa88SAnkit Navik }
1983b950aa88SAnkit Navik
hci_cc_le_del_from_resolv_list(struct hci_dev * hdev,void * data,struct sk_buff * skb)1984c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_del_from_resolv_list(struct hci_dev *hdev, void *data,
1985b950aa88SAnkit Navik struct sk_buff *skb)
1986b950aa88SAnkit Navik {
1987b950aa88SAnkit Navik struct hci_cp_le_del_from_resolv_list *sent;
1988c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
1989b950aa88SAnkit Navik
1990e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1991e3f3a1aeSLuiz Augusto von Dentz
1992e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
1993c8992cffSLuiz Augusto von Dentz return rp->status;
1994b950aa88SAnkit Navik
1995b950aa88SAnkit Navik sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_RESOLV_LIST);
1996b950aa88SAnkit Navik if (!sent)
1997c8992cffSLuiz Augusto von Dentz return rp->status;
1998b950aa88SAnkit Navik
19995e2b6064SNiels Dossche hci_dev_lock(hdev);
2000b950aa88SAnkit Navik hci_bdaddr_list_del_with_irk(&hdev->le_resolv_list, &sent->bdaddr,
2001b950aa88SAnkit Navik sent->bdaddr_type);
20025e2b6064SNiels Dossche hci_dev_unlock(hdev);
2003c8992cffSLuiz Augusto von Dentz
2004c8992cffSLuiz Augusto von Dentz return rp->status;
2005b950aa88SAnkit Navik }
2006b950aa88SAnkit Navik
hci_cc_le_clear_resolv_list(struct hci_dev * hdev,void * data,struct sk_buff * skb)2007c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_clear_resolv_list(struct hci_dev *hdev, void *data,
2008545f2596SAnkit Navik struct sk_buff *skb)
2009545f2596SAnkit Navik {
2010c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
2011545f2596SAnkit Navik
2012e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2013e3f3a1aeSLuiz Augusto von Dentz
2014e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
2015c8992cffSLuiz Augusto von Dentz return rp->status;
2016545f2596SAnkit Navik
20175e2b6064SNiels Dossche hci_dev_lock(hdev);
2018545f2596SAnkit Navik hci_bdaddr_list_clear(&hdev->le_resolv_list);
20195e2b6064SNiels Dossche hci_dev_unlock(hdev);
2020c8992cffSLuiz Augusto von Dentz
2021c8992cffSLuiz Augusto von Dentz return rp->status;
2022545f2596SAnkit Navik }
2023545f2596SAnkit Navik
hci_cc_le_read_resolv_list_size(struct hci_dev * hdev,void * data,struct sk_buff * skb)2024c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_resolv_list_size(struct hci_dev *hdev, void *data,
2025cfdb0c2dSAnkit Navik struct sk_buff *skb)
2026cfdb0c2dSAnkit Navik {
2027c8992cffSLuiz Augusto von Dentz struct hci_rp_le_read_resolv_list_size *rp = data;
2028e3f3a1aeSLuiz Augusto von Dentz
2029e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x size %u", rp->status, rp->size);
2030cfdb0c2dSAnkit Navik
2031cfdb0c2dSAnkit Navik if (rp->status)
2032c8992cffSLuiz Augusto von Dentz return rp->status;
2033cfdb0c2dSAnkit Navik
2034cfdb0c2dSAnkit Navik hdev->le_resolv_list_size = rp->size;
2035c8992cffSLuiz Augusto von Dentz
2036c8992cffSLuiz Augusto von Dentz return rp->status;
2037cfdb0c2dSAnkit Navik }
2038cfdb0c2dSAnkit Navik
hci_cc_le_set_addr_resolution_enable(struct hci_dev * hdev,void * data,struct sk_buff * skb)2039c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_addr_resolution_enable(struct hci_dev *hdev, void *data,
2040aa12af77SAnkit Navik struct sk_buff *skb)
2041aa12af77SAnkit Navik {
2042c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
2043e3f3a1aeSLuiz Augusto von Dentz __u8 *sent;
2044aa12af77SAnkit Navik
2045e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2046e3f3a1aeSLuiz Augusto von Dentz
2047e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
2048c8992cffSLuiz Augusto von Dentz return rp->status;
2049aa12af77SAnkit Navik
2050aa12af77SAnkit Navik sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADDR_RESOLV_ENABLE);
2051aa12af77SAnkit Navik if (!sent)
2052c8992cffSLuiz Augusto von Dentz return rp->status;
2053aa12af77SAnkit Navik
2054aa12af77SAnkit Navik hci_dev_lock(hdev);
2055aa12af77SAnkit Navik
2056aa12af77SAnkit Navik if (*sent)
2057aa12af77SAnkit Navik hci_dev_set_flag(hdev, HCI_LL_RPA_RESOLUTION);
2058aa12af77SAnkit Navik else
2059aa12af77SAnkit Navik hci_dev_clear_flag(hdev, HCI_LL_RPA_RESOLUTION);
2060aa12af77SAnkit Navik
2061aa12af77SAnkit Navik hci_dev_unlock(hdev);
2062c8992cffSLuiz Augusto von Dentz
2063c8992cffSLuiz Augusto von Dentz return rp->status;
2064aa12af77SAnkit Navik }
2065aa12af77SAnkit Navik
hci_cc_le_read_max_data_len(struct hci_dev * hdev,void * data,struct sk_buff * skb)2066c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_max_data_len(struct hci_dev *hdev, void *data,
2067a8e1bfaaSMarcel Holtmann struct sk_buff *skb)
2068a8e1bfaaSMarcel Holtmann {
2069c8992cffSLuiz Augusto von Dentz struct hci_rp_le_read_max_data_len *rp = data;
2070e3f3a1aeSLuiz Augusto von Dentz
2071e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2072a8e1bfaaSMarcel Holtmann
2073a8e1bfaaSMarcel Holtmann if (rp->status)
2074c8992cffSLuiz Augusto von Dentz return rp->status;
2075a8e1bfaaSMarcel Holtmann
2076a8e1bfaaSMarcel Holtmann hdev->le_max_tx_len = le16_to_cpu(rp->tx_len);
2077a8e1bfaaSMarcel Holtmann hdev->le_max_tx_time = le16_to_cpu(rp->tx_time);
2078a8e1bfaaSMarcel Holtmann hdev->le_max_rx_len = le16_to_cpu(rp->rx_len);
2079a8e1bfaaSMarcel Holtmann hdev->le_max_rx_time = le16_to_cpu(rp->rx_time);
2080c8992cffSLuiz Augusto von Dentz
2081c8992cffSLuiz Augusto von Dentz return rp->status;
2082a8e1bfaaSMarcel Holtmann }
2083a8e1bfaaSMarcel Holtmann
hci_cc_write_le_host_supported(struct hci_dev * hdev,void * data,struct sk_buff * skb)2084c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_le_host_supported(struct hci_dev *hdev, void *data,
2085f9b49306SAndre Guedes struct sk_buff *skb)
2086f9b49306SAndre Guedes {
208706199cf8SJohan Hedberg struct hci_cp_write_le_host_supported *sent;
2088c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
2089f9b49306SAndre Guedes
2090e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2091e3f3a1aeSLuiz Augusto von Dentz
2092e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
2093c8992cffSLuiz Augusto von Dentz return rp->status;
209445296acdSMarcel Holtmann
209506199cf8SJohan Hedberg sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
20968f984dfaSJohan Hedberg if (!sent)
2097c8992cffSLuiz Augusto von Dentz return rp->status;
2098f9b49306SAndre Guedes
20995c1a4c8fSJaganath Kanakkassery hci_dev_lock(hdev);
21005c1a4c8fSJaganath Kanakkassery
2101416a4ae5SJohan Hedberg if (sent->le) {
2102cad718edSJohan Hedberg hdev->features[1][0] |= LMP_HOST_LE;
2103a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_LE_ENABLED);
2104416a4ae5SJohan Hedberg } else {
2105cad718edSJohan Hedberg hdev->features[1][0] &= ~LMP_HOST_LE;
2106a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LE_ENABLED);
2107a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_ADVERTISING);
2108416a4ae5SJohan Hedberg }
210953b2caabSJohan Hedberg
211053b2caabSJohan Hedberg if (sent->simul)
2111cad718edSJohan Hedberg hdev->features[1][0] |= LMP_HOST_LE_BREDR;
211253b2caabSJohan Hedberg else
2113cad718edSJohan Hedberg hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
21145c1a4c8fSJaganath Kanakkassery
21155c1a4c8fSJaganath Kanakkassery hci_dev_unlock(hdev);
2116c8992cffSLuiz Augusto von Dentz
2117c8992cffSLuiz Augusto von Dentz return rp->status;
21188f984dfaSJohan Hedberg }
2119f9b49306SAndre Guedes
hci_cc_set_adv_param(struct hci_dev * hdev,void * data,struct sk_buff * skb)2120c8992cffSLuiz Augusto von Dentz static u8 hci_cc_set_adv_param(struct hci_dev *hdev, void *data,
2121c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
212256ed2cb8SJohan Hedberg {
212356ed2cb8SJohan Hedberg struct hci_cp_le_set_adv_param *cp;
2124c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
212556ed2cb8SJohan Hedberg
2126e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2127e3f3a1aeSLuiz Augusto von Dentz
2128e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
2129c8992cffSLuiz Augusto von Dentz return rp->status;
213056ed2cb8SJohan Hedberg
213156ed2cb8SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_PARAM);
213256ed2cb8SJohan Hedberg if (!cp)
2133c8992cffSLuiz Augusto von Dentz return rp->status;
213456ed2cb8SJohan Hedberg
213556ed2cb8SJohan Hedberg hci_dev_lock(hdev);
213656ed2cb8SJohan Hedberg hdev->adv_addr_type = cp->own_address_type;
213756ed2cb8SJohan Hedberg hci_dev_unlock(hdev);
2138c8992cffSLuiz Augusto von Dentz
2139c8992cffSLuiz Augusto von Dentz return rp->status;
214056ed2cb8SJohan Hedberg }
214156ed2cb8SJohan Hedberg
hci_cc_set_ext_adv_param(struct hci_dev * hdev,void * data,struct sk_buff * skb)2142c8992cffSLuiz Augusto von Dentz static u8 hci_cc_set_ext_adv_param(struct hci_dev *hdev, void *data,
2143c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
2144de181e88SJaganath Kanakkassery {
2145c8992cffSLuiz Augusto von Dentz struct hci_rp_le_set_ext_adv_params *rp = data;
2146de181e88SJaganath Kanakkassery struct hci_cp_le_set_ext_adv_params *cp;
2147de181e88SJaganath Kanakkassery struct adv_info *adv_instance;
2148de181e88SJaganath Kanakkassery
2149e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2150de181e88SJaganath Kanakkassery
2151de181e88SJaganath Kanakkassery if (rp->status)
2152c8992cffSLuiz Augusto von Dentz return rp->status;
2153de181e88SJaganath Kanakkassery
2154de181e88SJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_ADV_PARAMS);
2155de181e88SJaganath Kanakkassery if (!cp)
2156c8992cffSLuiz Augusto von Dentz return rp->status;
2157de181e88SJaganath Kanakkassery
2158de181e88SJaganath Kanakkassery hci_dev_lock(hdev);
2159de181e88SJaganath Kanakkassery hdev->adv_addr_type = cp->own_addr_type;
216025e70886SDaniel Winkler if (!cp->handle) {
2161de181e88SJaganath Kanakkassery /* Store in hdev for instance 0 */
2162de181e88SJaganath Kanakkassery hdev->adv_tx_power = rp->tx_power;
2163de181e88SJaganath Kanakkassery } else {
216425e70886SDaniel Winkler adv_instance = hci_find_adv_instance(hdev, cp->handle);
2165de181e88SJaganath Kanakkassery if (adv_instance)
2166de181e88SJaganath Kanakkassery adv_instance->tx_power = rp->tx_power;
2167de181e88SJaganath Kanakkassery }
2168a0fb3726SJaganath Kanakkassery /* Update adv data as tx power is known now */
2169651cd3d6SBrian Gix hci_update_adv_data(hdev, cp->handle);
217012410572SDaniel Winkler
2171de181e88SJaganath Kanakkassery hci_dev_unlock(hdev);
2172c8992cffSLuiz Augusto von Dentz
2173c8992cffSLuiz Augusto von Dentz return rp->status;
2174de181e88SJaganath Kanakkassery }
2175de181e88SJaganath Kanakkassery
hci_cc_read_rssi(struct hci_dev * hdev,void * data,struct sk_buff * skb)2176c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_rssi(struct hci_dev *hdev, void *data,
2177c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
21785ae76a94SAndrzej Kaczmarek {
2179c8992cffSLuiz Augusto von Dentz struct hci_rp_read_rssi *rp = data;
21805ae76a94SAndrzej Kaczmarek struct hci_conn *conn;
21815ae76a94SAndrzej Kaczmarek
2182e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
21835ae76a94SAndrzej Kaczmarek
21845ae76a94SAndrzej Kaczmarek if (rp->status)
2185c8992cffSLuiz Augusto von Dentz return rp->status;
21865ae76a94SAndrzej Kaczmarek
21875ae76a94SAndrzej Kaczmarek hci_dev_lock(hdev);
21885ae76a94SAndrzej Kaczmarek
21895ae76a94SAndrzej Kaczmarek conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
21905ae76a94SAndrzej Kaczmarek if (conn)
21915ae76a94SAndrzej Kaczmarek conn->rssi = rp->rssi;
21925ae76a94SAndrzej Kaczmarek
21935ae76a94SAndrzej Kaczmarek hci_dev_unlock(hdev);
2194c8992cffSLuiz Augusto von Dentz
2195c8992cffSLuiz Augusto von Dentz return rp->status;
21965ae76a94SAndrzej Kaczmarek }
21975ae76a94SAndrzej Kaczmarek
hci_cc_read_tx_power(struct hci_dev * hdev,void * data,struct sk_buff * skb)2198c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_tx_power(struct hci_dev *hdev, void *data,
2199c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
22005a134faeSAndrzej Kaczmarek {
22015a134faeSAndrzej Kaczmarek struct hci_cp_read_tx_power *sent;
2202c8992cffSLuiz Augusto von Dentz struct hci_rp_read_tx_power *rp = data;
22035a134faeSAndrzej Kaczmarek struct hci_conn *conn;
22045a134faeSAndrzej Kaczmarek
2205e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
22065a134faeSAndrzej Kaczmarek
22075a134faeSAndrzej Kaczmarek if (rp->status)
2208c8992cffSLuiz Augusto von Dentz return rp->status;
22095a134faeSAndrzej Kaczmarek
22105a134faeSAndrzej Kaczmarek sent = hci_sent_cmd_data(hdev, HCI_OP_READ_TX_POWER);
22115a134faeSAndrzej Kaczmarek if (!sent)
2212c8992cffSLuiz Augusto von Dentz return rp->status;
22135a134faeSAndrzej Kaczmarek
22145a134faeSAndrzej Kaczmarek hci_dev_lock(hdev);
22155a134faeSAndrzej Kaczmarek
22165a134faeSAndrzej Kaczmarek conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
2217d0455ed9SAndrzej Kaczmarek if (!conn)
2218d0455ed9SAndrzej Kaczmarek goto unlock;
22195a134faeSAndrzej Kaczmarek
2220d0455ed9SAndrzej Kaczmarek switch (sent->type) {
2221d0455ed9SAndrzej Kaczmarek case 0x00:
2222d0455ed9SAndrzej Kaczmarek conn->tx_power = rp->tx_power;
2223d0455ed9SAndrzej Kaczmarek break;
2224d0455ed9SAndrzej Kaczmarek case 0x01:
2225d0455ed9SAndrzej Kaczmarek conn->max_tx_power = rp->tx_power;
2226d0455ed9SAndrzej Kaczmarek break;
2227d0455ed9SAndrzej Kaczmarek }
2228d0455ed9SAndrzej Kaczmarek
2229d0455ed9SAndrzej Kaczmarek unlock:
22305a134faeSAndrzej Kaczmarek hci_dev_unlock(hdev);
2231c8992cffSLuiz Augusto von Dentz return rp->status;
22325a134faeSAndrzej Kaczmarek }
22335a134faeSAndrzej Kaczmarek
hci_cc_write_ssp_debug_mode(struct hci_dev * hdev,void * data,struct sk_buff * skb)2234c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_ssp_debug_mode(struct hci_dev *hdev, void *data,
2235c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
2236c50b33c8SMarcel Holtmann {
2237c8992cffSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
2238c50b33c8SMarcel Holtmann u8 *mode;
2239c50b33c8SMarcel Holtmann
2240e3f3a1aeSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2241e3f3a1aeSLuiz Augusto von Dentz
2242e3f3a1aeSLuiz Augusto von Dentz if (rp->status)
2243c8992cffSLuiz Augusto von Dentz return rp->status;
2244c50b33c8SMarcel Holtmann
2245c50b33c8SMarcel Holtmann mode = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE);
2246c50b33c8SMarcel Holtmann if (mode)
2247c50b33c8SMarcel Holtmann hdev->ssp_debug_mode = *mode;
2248c8992cffSLuiz Augusto von Dentz
2249c8992cffSLuiz Augusto von Dentz return rp->status;
2250c50b33c8SMarcel Holtmann }
2251c50b33c8SMarcel Holtmann
hci_cs_inquiry(struct hci_dev * hdev,__u8 status)22526039aa73SGustavo Padovan static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
2253a9de9248SMarcel Holtmann {
2254147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status);
2255a9de9248SMarcel Holtmann
2256e78bd85aSJonas Dreßler if (status)
2257314b2381SJohan Hedberg return;
2258314b2381SJohan Hedberg
225990d6a397SLuiz Augusto von Dentz if (hci_sent_cmd_data(hdev, HCI_OP_INQUIRY))
226089352e7dSAndre Guedes set_bit(HCI_INQUIRY, &hdev->flags);
2261a9de9248SMarcel Holtmann }
2262a9de9248SMarcel Holtmann
hci_cs_create_conn(struct hci_dev * hdev,__u8 status)22636039aa73SGustavo Padovan static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
22641da177e4SLinus Torvalds {
2265a9de9248SMarcel Holtmann struct hci_cp_create_conn *cp;
22661da177e4SLinus Torvalds struct hci_conn *conn;
22671da177e4SLinus Torvalds
2268147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status);
2269a9de9248SMarcel Holtmann
2270a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
22711da177e4SLinus Torvalds if (!cp)
22721da177e4SLinus Torvalds return;
22731da177e4SLinus Torvalds
22741da177e4SLinus Torvalds hci_dev_lock(hdev);
22751da177e4SLinus Torvalds
22761da177e4SLinus Torvalds conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
22771da177e4SLinus Torvalds
2278147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "bdaddr %pMR hcon %p", &cp->bdaddr, conn);
22791da177e4SLinus Torvalds
22801da177e4SLinus Torvalds if (status) {
22811da177e4SLinus Torvalds if (conn && conn->state == BT_CONNECT) {
22821da177e4SLinus Torvalds conn->state = BT_CLOSED;
2283539c496dSJohan Hedberg hci_connect_cfm(conn, status);
22841da177e4SLinus Torvalds hci_conn_del(conn);
22851da177e4SLinus Torvalds }
22861da177e4SLinus Torvalds } else {
22871da177e4SLinus Torvalds if (!conn) {
228884cb0143SZiyang Xuan conn = hci_conn_add_unset(hdev, ACL_LINK, &cp->bdaddr,
2289a5c4e309SJohan Hedberg HCI_ROLE_MASTER);
2290ad3f7986SSungwoo Kim if (IS_ERR(conn))
2291ad3f7986SSungwoo Kim bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn));
22921da177e4SLinus Torvalds }
22931da177e4SLinus Torvalds }
22941da177e4SLinus Torvalds
22951da177e4SLinus Torvalds hci_dev_unlock(hdev);
22961da177e4SLinus Torvalds }
22971da177e4SLinus Torvalds
hci_cs_add_sco(struct hci_dev * hdev,__u8 status)2298a9de9248SMarcel Holtmann static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
22991da177e4SLinus Torvalds {
2300a9de9248SMarcel Holtmann struct hci_cp_add_sco *cp;
230106149746SLuiz Augusto von Dentz struct hci_conn *acl;
230206149746SLuiz Augusto von Dentz struct hci_link *link;
23031da177e4SLinus Torvalds __u16 handle;
23041da177e4SLinus Torvalds
2305147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status);
2306b6a0dc82SMarcel Holtmann
2307a9de9248SMarcel Holtmann if (!status)
2308a9de9248SMarcel Holtmann return;
2309a9de9248SMarcel Holtmann
2310a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
23111da177e4SLinus Torvalds if (!cp)
2312a9de9248SMarcel Holtmann return;
23131da177e4SLinus Torvalds
23141da177e4SLinus Torvalds handle = __le16_to_cpu(cp->handle);
23151da177e4SLinus Torvalds
2316147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "handle 0x%4.4x", handle);
23171da177e4SLinus Torvalds
23181da177e4SLinus Torvalds hci_dev_lock(hdev);
23191da177e4SLinus Torvalds
23201da177e4SLinus Torvalds acl = hci_conn_hash_lookup_handle(hdev, handle);
23215a08ecceSAndrei Emeltchenko if (acl) {
232206149746SLuiz Augusto von Dentz link = list_first_entry_or_null(&acl->link_list,
232306149746SLuiz Augusto von Dentz struct hci_link, list);
232406149746SLuiz Augusto von Dentz if (link && link->conn) {
232506149746SLuiz Augusto von Dentz link->conn->state = BT_CLOSED;
23261da177e4SLinus Torvalds
232706149746SLuiz Augusto von Dentz hci_connect_cfm(link->conn, status);
232806149746SLuiz Augusto von Dentz hci_conn_del(link->conn);
23291da177e4SLinus Torvalds }
23305a08ecceSAndrei Emeltchenko }
23311da177e4SLinus Torvalds
23321da177e4SLinus Torvalds hci_dev_unlock(hdev);
23331da177e4SLinus Torvalds }
23341da177e4SLinus Torvalds
hci_cs_auth_requested(struct hci_dev * hdev,__u8 status)2335f8558555SMarcel Holtmann static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
2336f8558555SMarcel Holtmann {
2337f8558555SMarcel Holtmann struct hci_cp_auth_requested *cp;
2338f8558555SMarcel Holtmann struct hci_conn *conn;
2339f8558555SMarcel Holtmann
2340147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status);
2341f8558555SMarcel Holtmann
2342f8558555SMarcel Holtmann if (!status)
2343f8558555SMarcel Holtmann return;
2344f8558555SMarcel Holtmann
2345f8558555SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
2346f8558555SMarcel Holtmann if (!cp)
2347f8558555SMarcel Holtmann return;
2348f8558555SMarcel Holtmann
2349f8558555SMarcel Holtmann hci_dev_lock(hdev);
2350f8558555SMarcel Holtmann
2351f8558555SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2352f8558555SMarcel Holtmann if (conn) {
2353f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) {
2354539c496dSJohan Hedberg hci_connect_cfm(conn, status);
235576a68ba0SDavid Herrmann hci_conn_drop(conn);
2356f8558555SMarcel Holtmann }
2357f8558555SMarcel Holtmann }
2358f8558555SMarcel Holtmann
2359f8558555SMarcel Holtmann hci_dev_unlock(hdev);
2360f8558555SMarcel Holtmann }
2361f8558555SMarcel Holtmann
hci_cs_set_conn_encrypt(struct hci_dev * hdev,__u8 status)2362f8558555SMarcel Holtmann static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
2363f8558555SMarcel Holtmann {
2364f8558555SMarcel Holtmann struct hci_cp_set_conn_encrypt *cp;
2365f8558555SMarcel Holtmann struct hci_conn *conn;
2366f8558555SMarcel Holtmann
2367147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status);
2368f8558555SMarcel Holtmann
2369f8558555SMarcel Holtmann if (!status)
2370f8558555SMarcel Holtmann return;
2371f8558555SMarcel Holtmann
2372f8558555SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
2373f8558555SMarcel Holtmann if (!cp)
2374f8558555SMarcel Holtmann return;
2375f8558555SMarcel Holtmann
2376f8558555SMarcel Holtmann hci_dev_lock(hdev);
2377f8558555SMarcel Holtmann
2378f8558555SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2379f8558555SMarcel Holtmann if (conn) {
2380f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) {
2381539c496dSJohan Hedberg hci_connect_cfm(conn, status);
238276a68ba0SDavid Herrmann hci_conn_drop(conn);
2383f8558555SMarcel Holtmann }
2384f8558555SMarcel Holtmann }
2385f8558555SMarcel Holtmann
2386f8558555SMarcel Holtmann hci_dev_unlock(hdev);
2387f8558555SMarcel Holtmann }
2388f8558555SMarcel Holtmann
hci_outgoing_auth_needed(struct hci_dev * hdev,struct hci_conn * conn)2389127178d2SJohan Hedberg static int hci_outgoing_auth_needed(struct hci_dev *hdev,
2390392599b9SJohan Hedberg struct hci_conn *conn)
2391392599b9SJohan Hedberg {
2392392599b9SJohan Hedberg if (conn->state != BT_CONFIG || !conn->out)
2393392599b9SJohan Hedberg return 0;
2394392599b9SJohan Hedberg
2395765c2a96SJohan Hedberg if (conn->pending_sec_level == BT_SECURITY_SDP)
2396392599b9SJohan Hedberg return 0;
2397392599b9SJohan Hedberg
2398392599b9SJohan Hedberg /* Only request authentication for SSP connections or non-SSP
2399264b8b4eSJohan Hedberg * devices with sec_level MEDIUM or HIGH or if MITM protection
2400264b8b4eSJohan Hedberg * is requested.
2401264b8b4eSJohan Hedberg */
2402807deac2SGustavo Padovan if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
24037e3691e1SJohan Hedberg conn->pending_sec_level != BT_SECURITY_FIPS &&
2404264b8b4eSJohan Hedberg conn->pending_sec_level != BT_SECURITY_HIGH &&
2405264b8b4eSJohan Hedberg conn->pending_sec_level != BT_SECURITY_MEDIUM)
2406392599b9SJohan Hedberg return 0;
2407392599b9SJohan Hedberg
2408392599b9SJohan Hedberg return 1;
2409392599b9SJohan Hedberg }
2410392599b9SJohan Hedberg
hci_resolve_name(struct hci_dev * hdev,struct inquiry_entry * e)24116039aa73SGustavo Padovan static int hci_resolve_name(struct hci_dev *hdev,
241200abfe44SGustavo F. Padovan struct inquiry_entry *e)
241330dc78e1SJohan Hedberg {
241430dc78e1SJohan Hedberg struct hci_cp_remote_name_req cp;
241530dc78e1SJohan Hedberg
241630dc78e1SJohan Hedberg memset(&cp, 0, sizeof(cp));
241730dc78e1SJohan Hedberg
241830dc78e1SJohan Hedberg bacpy(&cp.bdaddr, &e->data.bdaddr);
241930dc78e1SJohan Hedberg cp.pscan_rep_mode = e->data.pscan_rep_mode;
242030dc78e1SJohan Hedberg cp.pscan_mode = e->data.pscan_mode;
242130dc78e1SJohan Hedberg cp.clock_offset = e->data.clock_offset;
242230dc78e1SJohan Hedberg
242330dc78e1SJohan Hedberg return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
242430dc78e1SJohan Hedberg }
242530dc78e1SJohan Hedberg
hci_resolve_next_name(struct hci_dev * hdev)2426b644ba33SJohan Hedberg static bool hci_resolve_next_name(struct hci_dev *hdev)
242730dc78e1SJohan Hedberg {
242830dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery;
242930dc78e1SJohan Hedberg struct inquiry_entry *e;
243030dc78e1SJohan Hedberg
2431b644ba33SJohan Hedberg if (list_empty(&discov->resolve))
2432b644ba33SJohan Hedberg return false;
2433b644ba33SJohan Hedberg
2434dbf6811aSArchie Pusaka /* We should stop if we already spent too much time resolving names. */
2435dbf6811aSArchie Pusaka if (time_after(jiffies, discov->name_resolve_timeout)) {
2436dbf6811aSArchie Pusaka bt_dev_warn_ratelimited(hdev, "Name resolve takes too long.");
2437dbf6811aSArchie Pusaka return false;
2438dbf6811aSArchie Pusaka }
2439dbf6811aSArchie Pusaka
2440b644ba33SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
2441c810089cSRam Malovany if (!e)
2442c810089cSRam Malovany return false;
2443c810089cSRam Malovany
2444b644ba33SJohan Hedberg if (hci_resolve_name(hdev, e) == 0) {
2445b644ba33SJohan Hedberg e->name_state = NAME_PENDING;
2446b644ba33SJohan Hedberg return true;
2447b644ba33SJohan Hedberg }
2448b644ba33SJohan Hedberg
2449b644ba33SJohan Hedberg return false;
2450b644ba33SJohan Hedberg }
2451b644ba33SJohan Hedberg
hci_check_pending_name(struct hci_dev * hdev,struct hci_conn * conn,bdaddr_t * bdaddr,u8 * name,u8 name_len)2452b644ba33SJohan Hedberg static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
2453b644ba33SJohan Hedberg bdaddr_t *bdaddr, u8 *name, u8 name_len)
2454b644ba33SJohan Hedberg {
2455b644ba33SJohan Hedberg struct discovery_state *discov = &hdev->discovery;
2456b644ba33SJohan Hedberg struct inquiry_entry *e;
2457b644ba33SJohan Hedberg
245860cb49d2SJohan Hedberg /* Update the mgmt connected state if necessary. Be careful with
245960cb49d2SJohan Hedberg * conn objects that exist but are not (yet) connected however.
246060cb49d2SJohan Hedberg * Only those in BT_CONFIG or BT_CONNECTED states can be
246160cb49d2SJohan Hedberg * considered connected.
246260cb49d2SJohan Hedberg */
24630b3df53cSLuiz Augusto von Dentz if (conn && (conn->state == BT_CONFIG || conn->state == BT_CONNECTED))
24641c6ed31bSYu Liu mgmt_device_connected(hdev, conn, name, name_len);
2465b644ba33SJohan Hedberg
2466b644ba33SJohan Hedberg if (discov->state == DISCOVERY_STOPPED)
2467b644ba33SJohan Hedberg return;
2468b644ba33SJohan Hedberg
246930dc78e1SJohan Hedberg if (discov->state == DISCOVERY_STOPPING)
247030dc78e1SJohan Hedberg goto discov_complete;
247130dc78e1SJohan Hedberg
247230dc78e1SJohan Hedberg if (discov->state != DISCOVERY_RESOLVING)
247330dc78e1SJohan Hedberg return;
247430dc78e1SJohan Hedberg
247530dc78e1SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
24767cc8380eSRam Malovany /* If the device was not found in a list of found devices names of which
24777cc8380eSRam Malovany * are pending. there is no need to continue resolving a next name as it
24787cc8380eSRam Malovany * will be done upon receiving another Remote Name Request Complete
24797cc8380eSRam Malovany * Event */
24807cc8380eSRam Malovany if (!e)
24817cc8380eSRam Malovany return;
24827cc8380eSRam Malovany
248330dc78e1SJohan Hedberg list_del(&e->list);
2484ea13aed5SArchie Pusaka
2485ea13aed5SArchie Pusaka e->name_state = name ? NAME_KNOWN : NAME_NOT_KNOWN;
2486ea13aed5SArchie Pusaka mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00, e->data.rssi,
2487ea13aed5SArchie Pusaka name, name_len);
248830dc78e1SJohan Hedberg
2489b644ba33SJohan Hedberg if (hci_resolve_next_name(hdev))
249030dc78e1SJohan Hedberg return;
249130dc78e1SJohan Hedberg
249230dc78e1SJohan Hedberg discov_complete:
249330dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
249430dc78e1SJohan Hedberg }
249530dc78e1SJohan Hedberg
hci_cs_remote_name_req(struct hci_dev * hdev,__u8 status)2496a9de9248SMarcel Holtmann static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
24971da177e4SLinus Torvalds {
2498127178d2SJohan Hedberg struct hci_cp_remote_name_req *cp;
2499127178d2SJohan Hedberg struct hci_conn *conn;
2500127178d2SJohan Hedberg
2501147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status);
2502127178d2SJohan Hedberg
2503127178d2SJohan Hedberg /* If successful wait for the name req complete event before
2504127178d2SJohan Hedberg * checking for the need to do authentication */
2505127178d2SJohan Hedberg if (!status)
2506127178d2SJohan Hedberg return;
2507127178d2SJohan Hedberg
2508127178d2SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
2509127178d2SJohan Hedberg if (!cp)
2510127178d2SJohan Hedberg return;
2511127178d2SJohan Hedberg
2512127178d2SJohan Hedberg hci_dev_lock(hdev);
2513127178d2SJohan Hedberg
2514127178d2SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
2515b644ba33SJohan Hedberg
2516d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT))
2517b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
2518b644ba33SJohan Hedberg
251979c6c70cSJohan Hedberg if (!conn)
252079c6c70cSJohan Hedberg goto unlock;
252179c6c70cSJohan Hedberg
252279c6c70cSJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn))
252379c6c70cSJohan Hedberg goto unlock;
252479c6c70cSJohan Hedberg
252551a8efd7SJohan Hedberg if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
2526c1f23a2bSJohannes Berg struct hci_cp_auth_requested auth_cp;
2527c1f23a2bSJohannes Berg
2528977f8fceSJohan Hedberg set_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags);
2529977f8fceSJohan Hedberg
2530c1f23a2bSJohannes Berg auth_cp.handle = __cpu_to_le16(conn->handle);
2531c1f23a2bSJohannes Berg hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
2532c1f23a2bSJohannes Berg sizeof(auth_cp), &auth_cp);
2533127178d2SJohan Hedberg }
2534127178d2SJohan Hedberg
253579c6c70cSJohan Hedberg unlock:
2536127178d2SJohan Hedberg hci_dev_unlock(hdev);
2537a9de9248SMarcel Holtmann }
25381da177e4SLinus Torvalds
hci_cs_read_remote_features(struct hci_dev * hdev,__u8 status)2539769be974SMarcel Holtmann static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
2540769be974SMarcel Holtmann {
2541769be974SMarcel Holtmann struct hci_cp_read_remote_features *cp;
2542769be974SMarcel Holtmann struct hci_conn *conn;
2543769be974SMarcel Holtmann
2544147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status);
2545769be974SMarcel Holtmann
2546769be974SMarcel Holtmann if (!status)
2547769be974SMarcel Holtmann return;
2548769be974SMarcel Holtmann
2549769be974SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
2550769be974SMarcel Holtmann if (!cp)
2551769be974SMarcel Holtmann return;
2552769be974SMarcel Holtmann
2553769be974SMarcel Holtmann hci_dev_lock(hdev);
2554769be974SMarcel Holtmann
2555769be974SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2556769be974SMarcel Holtmann if (conn) {
2557769be974SMarcel Holtmann if (conn->state == BT_CONFIG) {
2558539c496dSJohan Hedberg hci_connect_cfm(conn, status);
255976a68ba0SDavid Herrmann hci_conn_drop(conn);
2560769be974SMarcel Holtmann }
2561769be974SMarcel Holtmann }
2562769be974SMarcel Holtmann
2563769be974SMarcel Holtmann hci_dev_unlock(hdev);
2564769be974SMarcel Holtmann }
2565769be974SMarcel Holtmann
hci_cs_read_remote_ext_features(struct hci_dev * hdev,__u8 status)2566769be974SMarcel Holtmann static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
2567769be974SMarcel Holtmann {
2568769be974SMarcel Holtmann struct hci_cp_read_remote_ext_features *cp;
2569769be974SMarcel Holtmann struct hci_conn *conn;
2570769be974SMarcel Holtmann
2571147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status);
2572769be974SMarcel Holtmann
2573769be974SMarcel Holtmann if (!status)
2574769be974SMarcel Holtmann return;
2575769be974SMarcel Holtmann
2576769be974SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
2577769be974SMarcel Holtmann if (!cp)
2578769be974SMarcel Holtmann return;
2579769be974SMarcel Holtmann
2580769be974SMarcel Holtmann hci_dev_lock(hdev);
2581769be974SMarcel Holtmann
2582769be974SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2583769be974SMarcel Holtmann if (conn) {
2584769be974SMarcel Holtmann if (conn->state == BT_CONFIG) {
2585539c496dSJohan Hedberg hci_connect_cfm(conn, status);
258676a68ba0SDavid Herrmann hci_conn_drop(conn);
2587769be974SMarcel Holtmann }
2588769be974SMarcel Holtmann }
2589769be974SMarcel Holtmann
2590769be974SMarcel Holtmann hci_dev_unlock(hdev);
2591769be974SMarcel Holtmann }
2592769be974SMarcel Holtmann
hci_setup_sync_conn_status(struct hci_dev * hdev,__u16 handle,__u8 status)259306149746SLuiz Augusto von Dentz static void hci_setup_sync_conn_status(struct hci_dev *hdev, __u16 handle,
259406149746SLuiz Augusto von Dentz __u8 status)
259506149746SLuiz Augusto von Dentz {
259606149746SLuiz Augusto von Dentz struct hci_conn *acl;
259706149746SLuiz Augusto von Dentz struct hci_link *link;
259806149746SLuiz Augusto von Dentz
259906149746SLuiz Augusto von Dentz bt_dev_dbg(hdev, "handle 0x%4.4x status 0x%2.2x", handle, status);
260006149746SLuiz Augusto von Dentz
260106149746SLuiz Augusto von Dentz hci_dev_lock(hdev);
260206149746SLuiz Augusto von Dentz
260306149746SLuiz Augusto von Dentz acl = hci_conn_hash_lookup_handle(hdev, handle);
260406149746SLuiz Augusto von Dentz if (acl) {
260506149746SLuiz Augusto von Dentz link = list_first_entry_or_null(&acl->link_list,
260606149746SLuiz Augusto von Dentz struct hci_link, list);
260706149746SLuiz Augusto von Dentz if (link && link->conn) {
260806149746SLuiz Augusto von Dentz link->conn->state = BT_CLOSED;
260906149746SLuiz Augusto von Dentz
261006149746SLuiz Augusto von Dentz hci_connect_cfm(link->conn, status);
261106149746SLuiz Augusto von Dentz hci_conn_del(link->conn);
261206149746SLuiz Augusto von Dentz }
261306149746SLuiz Augusto von Dentz }
261406149746SLuiz Augusto von Dentz
261506149746SLuiz Augusto von Dentz hci_dev_unlock(hdev);
261606149746SLuiz Augusto von Dentz }
261706149746SLuiz Augusto von Dentz
hci_cs_setup_sync_conn(struct hci_dev * hdev,__u8 status)2618a9de9248SMarcel Holtmann static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
2619a9de9248SMarcel Holtmann {
2620b6a0dc82SMarcel Holtmann struct hci_cp_setup_sync_conn *cp;
2621b6a0dc82SMarcel Holtmann
2622147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status);
2623b6a0dc82SMarcel Holtmann
2624b6a0dc82SMarcel Holtmann if (!status)
2625b6a0dc82SMarcel Holtmann return;
2626b6a0dc82SMarcel Holtmann
2627b6a0dc82SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
2628b6a0dc82SMarcel Holtmann if (!cp)
2629b6a0dc82SMarcel Holtmann return;
2630b6a0dc82SMarcel Holtmann
263106149746SLuiz Augusto von Dentz hci_setup_sync_conn_status(hdev, __le16_to_cpu(cp->handle), status);
2632a9de9248SMarcel Holtmann }
2633a9de9248SMarcel Holtmann
hci_cs_enhanced_setup_sync_conn(struct hci_dev * hdev,__u8 status)2634b2af264aSKiran K static void hci_cs_enhanced_setup_sync_conn(struct hci_dev *hdev, __u8 status)
2635b2af264aSKiran K {
2636b2af264aSKiran K struct hci_cp_enhanced_setup_sync_conn *cp;
2637b2af264aSKiran K
2638b2af264aSKiran K bt_dev_dbg(hdev, "status 0x%2.2x", status);
2639b2af264aSKiran K
2640b2af264aSKiran K if (!status)
2641b2af264aSKiran K return;
2642b2af264aSKiran K
2643b2af264aSKiran K cp = hci_sent_cmd_data(hdev, HCI_OP_ENHANCED_SETUP_SYNC_CONN);
2644b2af264aSKiran K if (!cp)
2645b2af264aSKiran K return;
2646b2af264aSKiran K
264706149746SLuiz Augusto von Dentz hci_setup_sync_conn_status(hdev, __le16_to_cpu(cp->handle), status);
2648b2af264aSKiran K }
2649b2af264aSKiran K
hci_cs_sniff_mode(struct hci_dev * hdev,__u8 status)2650a9de9248SMarcel Holtmann static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
2651a9de9248SMarcel Holtmann {
2652a9de9248SMarcel Holtmann struct hci_cp_sniff_mode *cp;
265304837f64SMarcel Holtmann struct hci_conn *conn;
265404837f64SMarcel Holtmann
2655147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status);
2656a9de9248SMarcel Holtmann
2657a9de9248SMarcel Holtmann if (!status)
2658a9de9248SMarcel Holtmann return;
2659a9de9248SMarcel Holtmann
2660a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
266104837f64SMarcel Holtmann if (!cp)
2662a9de9248SMarcel Holtmann return;
266304837f64SMarcel Holtmann
266404837f64SMarcel Holtmann hci_dev_lock(hdev);
266504837f64SMarcel Holtmann
266604837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2667e73439d8SMarcel Holtmann if (conn) {
266851a8efd7SJohan Hedberg clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
266904837f64SMarcel Holtmann
267051a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
2671e73439d8SMarcel Holtmann hci_sco_setup(conn, status);
2672e73439d8SMarcel Holtmann }
2673e73439d8SMarcel Holtmann
267404837f64SMarcel Holtmann hci_dev_unlock(hdev);
267504837f64SMarcel Holtmann }
267604837f64SMarcel Holtmann
hci_cs_exit_sniff_mode(struct hci_dev * hdev,__u8 status)2677a9de9248SMarcel Holtmann static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
2678a9de9248SMarcel Holtmann {
2679a9de9248SMarcel Holtmann struct hci_cp_exit_sniff_mode *cp;
268004837f64SMarcel Holtmann struct hci_conn *conn;
268104837f64SMarcel Holtmann
2682147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status);
2683a9de9248SMarcel Holtmann
2684a9de9248SMarcel Holtmann if (!status)
2685a9de9248SMarcel Holtmann return;
2686a9de9248SMarcel Holtmann
2687a9de9248SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
268804837f64SMarcel Holtmann if (!cp)
2689a9de9248SMarcel Holtmann return;
269004837f64SMarcel Holtmann
269104837f64SMarcel Holtmann hci_dev_lock(hdev);
269204837f64SMarcel Holtmann
269304837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2694e73439d8SMarcel Holtmann if (conn) {
269551a8efd7SJohan Hedberg clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
269604837f64SMarcel Holtmann
269751a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
2698e73439d8SMarcel Holtmann hci_sco_setup(conn, status);
2699e73439d8SMarcel Holtmann }
2700e73439d8SMarcel Holtmann
270104837f64SMarcel Holtmann hci_dev_unlock(hdev);
270204837f64SMarcel Holtmann }
270304837f64SMarcel Holtmann
hci_cs_disconnect(struct hci_dev * hdev,u8 status)270488c3df13SJohan Hedberg static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
270588c3df13SJohan Hedberg {
270688c3df13SJohan Hedberg struct hci_cp_disconnect *cp;
2707182ee45dSLuiz Augusto von Dentz struct hci_conn_params *params;
270888c3df13SJohan Hedberg struct hci_conn *conn;
2709182ee45dSLuiz Augusto von Dentz bool mgmt_conn;
271088c3df13SJohan Hedberg
2711147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status);
2712147306ccSLuiz Augusto von Dentz
2713182ee45dSLuiz Augusto von Dentz /* Wait for HCI_EV_DISCONN_COMPLETE if status 0x00 and not suspended
2714182ee45dSLuiz Augusto von Dentz * otherwise cleanup the connection immediately.
2715182ee45dSLuiz Augusto von Dentz */
2716182ee45dSLuiz Augusto von Dentz if (!status && !hdev->suspended)
271788c3df13SJohan Hedberg return;
271888c3df13SJohan Hedberg
271988c3df13SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
272088c3df13SJohan Hedberg if (!cp)
272188c3df13SJohan Hedberg return;
272288c3df13SJohan Hedberg
272388c3df13SJohan Hedberg hci_dev_lock(hdev);
272488c3df13SJohan Hedberg
272588c3df13SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2726182ee45dSLuiz Augusto von Dentz if (!conn)
2727182ee45dSLuiz Augusto von Dentz goto unlock;
2728182ee45dSLuiz Augusto von Dentz
2729182ee45dSLuiz Augusto von Dentz if (status) {
273088c3df13SJohan Hedberg mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
273188c3df13SJohan Hedberg conn->dst_type, status);
273288c3df13SJohan Hedberg
27331eeaa1aeSLuiz Augusto von Dentz if (conn->type == LE_LINK && conn->role == HCI_ROLE_SLAVE) {
27347087c4f6SLuiz Augusto von Dentz hdev->cur_adv_instance = conn->adv_instance;
2735abfeea47SLuiz Augusto von Dentz hci_enable_advertising(hdev);
27367087c4f6SLuiz Augusto von Dentz }
27377087c4f6SLuiz Augusto von Dentz
27387f7cfcb6SPauli Virtanen /* Inform sockets conn is gone before we delete it */
27397f7cfcb6SPauli Virtanen hci_disconn_cfm(conn, HCI_ERROR_UNSPECIFIED);
27407f7cfcb6SPauli Virtanen
2741182ee45dSLuiz Augusto von Dentz goto done;
2742182ee45dSLuiz Augusto von Dentz }
2743182ee45dSLuiz Augusto von Dentz
2744182ee45dSLuiz Augusto von Dentz mgmt_conn = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
2745182ee45dSLuiz Augusto von Dentz
2746182ee45dSLuiz Augusto von Dentz if (conn->type == ACL_LINK) {
2747629f66aaSAlain Michaud if (test_and_clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags))
2748182ee45dSLuiz Augusto von Dentz hci_remove_link_key(hdev, &conn->dst);
2749182ee45dSLuiz Augusto von Dentz }
2750182ee45dSLuiz Augusto von Dentz
2751182ee45dSLuiz Augusto von Dentz params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
2752182ee45dSLuiz Augusto von Dentz if (params) {
2753182ee45dSLuiz Augusto von Dentz switch (params->auto_connect) {
2754182ee45dSLuiz Augusto von Dentz case HCI_AUTO_CONN_LINK_LOSS:
2755182ee45dSLuiz Augusto von Dentz if (cp->reason != HCI_ERROR_CONNECTION_TIMEOUT)
2756182ee45dSLuiz Augusto von Dentz break;
2757182ee45dSLuiz Augusto von Dentz fallthrough;
2758182ee45dSLuiz Augusto von Dentz
2759182ee45dSLuiz Augusto von Dentz case HCI_AUTO_CONN_DIRECT:
2760182ee45dSLuiz Augusto von Dentz case HCI_AUTO_CONN_ALWAYS:
2761195ef75eSPauli Virtanen hci_pend_le_list_del_init(params);
2762195ef75eSPauli Virtanen hci_pend_le_list_add(params, &hdev->pend_le_conns);
2763182ee45dSLuiz Augusto von Dentz break;
2764182ee45dSLuiz Augusto von Dentz
2765182ee45dSLuiz Augusto von Dentz default:
2766182ee45dSLuiz Augusto von Dentz break;
2767182ee45dSLuiz Augusto von Dentz }
2768182ee45dSLuiz Augusto von Dentz }
2769182ee45dSLuiz Augusto von Dentz
2770182ee45dSLuiz Augusto von Dentz mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type,
2771182ee45dSLuiz Augusto von Dentz cp->reason, mgmt_conn);
2772182ee45dSLuiz Augusto von Dentz
2773182ee45dSLuiz Augusto von Dentz hci_disconn_cfm(conn, cp->reason);
2774182ee45dSLuiz Augusto von Dentz
2775182ee45dSLuiz Augusto von Dentz done:
2776b8d29052SJoseph Hwang /* If the disconnection failed for any reason, the upper layer
2777b8d29052SJoseph Hwang * does not retry to disconnect in current implementation.
2778b8d29052SJoseph Hwang * Hence, we need to do some basic cleanup here and re-enable
2779b8d29052SJoseph Hwang * advertising if necessary.
2780b8d29052SJoseph Hwang */
2781b8d29052SJoseph Hwang hci_conn_del(conn);
2782182ee45dSLuiz Augusto von Dentz unlock:
278388c3df13SJohan Hedberg hci_dev_unlock(hdev);
278488c3df13SJohan Hedberg }
278588c3df13SJohan Hedberg
ev_bdaddr_type(struct hci_dev * hdev,u8 type,bool * resolved)2786d850bf08SLuiz Augusto von Dentz static u8 ev_bdaddr_type(struct hci_dev *hdev, u8 type, bool *resolved)
27874ec4d63bSLuiz Augusto von Dentz {
27884ec4d63bSLuiz Augusto von Dentz /* When using controller based address resolution, then the new
27894ec4d63bSLuiz Augusto von Dentz * address types 0x02 and 0x03 are used. These types need to be
27904ec4d63bSLuiz Augusto von Dentz * converted back into either public address or random address type
27914ec4d63bSLuiz Augusto von Dentz */
27924ec4d63bSLuiz Augusto von Dentz switch (type) {
27934ec4d63bSLuiz Augusto von Dentz case ADDR_LE_DEV_PUBLIC_RESOLVED:
2794d850bf08SLuiz Augusto von Dentz if (resolved)
2795d850bf08SLuiz Augusto von Dentz *resolved = true;
27964ec4d63bSLuiz Augusto von Dentz return ADDR_LE_DEV_PUBLIC;
27974ec4d63bSLuiz Augusto von Dentz case ADDR_LE_DEV_RANDOM_RESOLVED:
2798d850bf08SLuiz Augusto von Dentz if (resolved)
2799d850bf08SLuiz Augusto von Dentz *resolved = true;
28004ec4d63bSLuiz Augusto von Dentz return ADDR_LE_DEV_RANDOM;
28014ec4d63bSLuiz Augusto von Dentz }
28024ec4d63bSLuiz Augusto von Dentz
2803d850bf08SLuiz Augusto von Dentz if (resolved)
2804d850bf08SLuiz Augusto von Dentz *resolved = false;
28054ec4d63bSLuiz Augusto von Dentz return type;
28064ec4d63bSLuiz Augusto von Dentz }
28074ec4d63bSLuiz Augusto von Dentz
cs_le_create_conn(struct hci_dev * hdev,bdaddr_t * peer_addr,u8 peer_addr_type,u8 own_address_type,u8 filter_policy)2808d12fb056SJaganath Kanakkassery static void cs_le_create_conn(struct hci_dev *hdev, bdaddr_t *peer_addr,
2809d12fb056SJaganath Kanakkassery u8 peer_addr_type, u8 own_address_type,
2810d12fb056SJaganath Kanakkassery u8 filter_policy)
2811d12fb056SJaganath Kanakkassery {
2812d12fb056SJaganath Kanakkassery struct hci_conn *conn;
2813d12fb056SJaganath Kanakkassery
2814d12fb056SJaganath Kanakkassery conn = hci_conn_hash_lookup_le(hdev, peer_addr,
2815d12fb056SJaganath Kanakkassery peer_addr_type);
2816d12fb056SJaganath Kanakkassery if (!conn)
2817d12fb056SJaganath Kanakkassery return;
2818d12fb056SJaganath Kanakkassery
2819d850bf08SLuiz Augusto von Dentz own_address_type = ev_bdaddr_type(hdev, own_address_type, NULL);
2820b31bc00bSSathish Narasimman
2821d12fb056SJaganath Kanakkassery /* Store the initiator and responder address information which
2822d12fb056SJaganath Kanakkassery * is needed for SMP. These values will not change during the
2823d12fb056SJaganath Kanakkassery * lifetime of the connection.
2824d12fb056SJaganath Kanakkassery */
2825d12fb056SJaganath Kanakkassery conn->init_addr_type = own_address_type;
2826d12fb056SJaganath Kanakkassery if (own_address_type == ADDR_LE_DEV_RANDOM)
2827d12fb056SJaganath Kanakkassery bacpy(&conn->init_addr, &hdev->random_addr);
2828d12fb056SJaganath Kanakkassery else
2829d12fb056SJaganath Kanakkassery bacpy(&conn->init_addr, &hdev->bdaddr);
2830d12fb056SJaganath Kanakkassery
2831d12fb056SJaganath Kanakkassery conn->resp_addr_type = peer_addr_type;
2832d12fb056SJaganath Kanakkassery bacpy(&conn->resp_addr, peer_addr);
2833d12fb056SJaganath Kanakkassery }
2834d12fb056SJaganath Kanakkassery
hci_cs_le_create_conn(struct hci_dev * hdev,u8 status)2835cb1d68f7SJohan Hedberg static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status)
2836cb1d68f7SJohan Hedberg {
2837cb1d68f7SJohan Hedberg struct hci_cp_le_create_conn *cp;
2838cb1d68f7SJohan Hedberg
2839147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status);
2840cb1d68f7SJohan Hedberg
2841cb1d68f7SJohan Hedberg /* All connection failure handling is taken care of by the
28429b3628d7SLuiz Augusto von Dentz * hci_conn_failed function which is triggered by the HCI
2843cb1d68f7SJohan Hedberg * request completion callbacks used for connecting.
2844cb1d68f7SJohan Hedberg */
2845cb1d68f7SJohan Hedberg if (status)
2846cb1d68f7SJohan Hedberg return;
2847cb1d68f7SJohan Hedberg
2848cb1d68f7SJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
2849cb1d68f7SJohan Hedberg if (!cp)
2850cb1d68f7SJohan Hedberg return;
2851cb1d68f7SJohan Hedberg
2852cb1d68f7SJohan Hedberg hci_dev_lock(hdev);
2853cb1d68f7SJohan Hedberg
2854d12fb056SJaganath Kanakkassery cs_le_create_conn(hdev, &cp->peer_addr, cp->peer_addr_type,
2855d12fb056SJaganath Kanakkassery cp->own_address_type, cp->filter_policy);
2856cb1d68f7SJohan Hedberg
2857cb1d68f7SJohan Hedberg hci_dev_unlock(hdev);
2858cb1d68f7SJohan Hedberg }
2859cb1d68f7SJohan Hedberg
hci_cs_le_ext_create_conn(struct hci_dev * hdev,u8 status)28604d94f95dSJaganath Kanakkassery static void hci_cs_le_ext_create_conn(struct hci_dev *hdev, u8 status)
28614d94f95dSJaganath Kanakkassery {
28624d94f95dSJaganath Kanakkassery struct hci_cp_le_ext_create_conn *cp;
28634d94f95dSJaganath Kanakkassery
2864147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status);
28654d94f95dSJaganath Kanakkassery
28664d94f95dSJaganath Kanakkassery /* All connection failure handling is taken care of by the
28679b3628d7SLuiz Augusto von Dentz * hci_conn_failed function which is triggered by the HCI
28684d94f95dSJaganath Kanakkassery * request completion callbacks used for connecting.
28694d94f95dSJaganath Kanakkassery */
28704d94f95dSJaganath Kanakkassery if (status)
28714d94f95dSJaganath Kanakkassery return;
28724d94f95dSJaganath Kanakkassery
28734d94f95dSJaganath Kanakkassery cp = hci_sent_cmd_data(hdev, HCI_OP_LE_EXT_CREATE_CONN);
28744d94f95dSJaganath Kanakkassery if (!cp)
28754d94f95dSJaganath Kanakkassery return;
28764d94f95dSJaganath Kanakkassery
28774d94f95dSJaganath Kanakkassery hci_dev_lock(hdev);
28784d94f95dSJaganath Kanakkassery
28794d94f95dSJaganath Kanakkassery cs_le_create_conn(hdev, &cp->peer_addr, cp->peer_addr_type,
28804d94f95dSJaganath Kanakkassery cp->own_addr_type, cp->filter_policy);
28814d94f95dSJaganath Kanakkassery
28824d94f95dSJaganath Kanakkassery hci_dev_unlock(hdev);
28834d94f95dSJaganath Kanakkassery }
28844d94f95dSJaganath Kanakkassery
hci_cs_le_read_remote_features(struct hci_dev * hdev,u8 status)28850fe29fd1SMarcel Holtmann static void hci_cs_le_read_remote_features(struct hci_dev *hdev, u8 status)
28860fe29fd1SMarcel Holtmann {
28870fe29fd1SMarcel Holtmann struct hci_cp_le_read_remote_features *cp;
28880fe29fd1SMarcel Holtmann struct hci_conn *conn;
28890fe29fd1SMarcel Holtmann
2890147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status);
28910fe29fd1SMarcel Holtmann
28920fe29fd1SMarcel Holtmann if (!status)
28930fe29fd1SMarcel Holtmann return;
28940fe29fd1SMarcel Holtmann
28950fe29fd1SMarcel Holtmann cp = hci_sent_cmd_data(hdev, HCI_OP_LE_READ_REMOTE_FEATURES);
28960fe29fd1SMarcel Holtmann if (!cp)
28970fe29fd1SMarcel Holtmann return;
28980fe29fd1SMarcel Holtmann
28990fe29fd1SMarcel Holtmann hci_dev_lock(hdev);
29000fe29fd1SMarcel Holtmann
29010fe29fd1SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
29020fe29fd1SMarcel Holtmann if (conn) {
29030fe29fd1SMarcel Holtmann if (conn->state == BT_CONFIG) {
29040fe29fd1SMarcel Holtmann hci_connect_cfm(conn, status);
29050fe29fd1SMarcel Holtmann hci_conn_drop(conn);
29060fe29fd1SMarcel Holtmann }
29070fe29fd1SMarcel Holtmann }
29080fe29fd1SMarcel Holtmann
29090fe29fd1SMarcel Holtmann hci_dev_unlock(hdev);
29100fe29fd1SMarcel Holtmann }
29110fe29fd1SMarcel Holtmann
hci_cs_le_start_enc(struct hci_dev * hdev,u8 status)291281d0c8adSJohan Hedberg static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
291381d0c8adSJohan Hedberg {
291481d0c8adSJohan Hedberg struct hci_cp_le_start_enc *cp;
291581d0c8adSJohan Hedberg struct hci_conn *conn;
291681d0c8adSJohan Hedberg
2917147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status);
291881d0c8adSJohan Hedberg
291981d0c8adSJohan Hedberg if (!status)
292081d0c8adSJohan Hedberg return;
292181d0c8adSJohan Hedberg
292281d0c8adSJohan Hedberg hci_dev_lock(hdev);
292381d0c8adSJohan Hedberg
292481d0c8adSJohan Hedberg cp = hci_sent_cmd_data(hdev, HCI_OP_LE_START_ENC);
292581d0c8adSJohan Hedberg if (!cp)
292681d0c8adSJohan Hedberg goto unlock;
292781d0c8adSJohan Hedberg
292881d0c8adSJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
292981d0c8adSJohan Hedberg if (!conn)
293081d0c8adSJohan Hedberg goto unlock;
293181d0c8adSJohan Hedberg
293281d0c8adSJohan Hedberg if (conn->state != BT_CONNECTED)
293381d0c8adSJohan Hedberg goto unlock;
293481d0c8adSJohan Hedberg
293581d0c8adSJohan Hedberg hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
293681d0c8adSJohan Hedberg hci_conn_drop(conn);
293781d0c8adSJohan Hedberg
293881d0c8adSJohan Hedberg unlock:
293981d0c8adSJohan Hedberg hci_dev_unlock(hdev);
294081d0c8adSJohan Hedberg }
294181d0c8adSJohan Hedberg
hci_cs_switch_role(struct hci_dev * hdev,u8 status)294250fc85f1SKuba Pawlak static void hci_cs_switch_role(struct hci_dev *hdev, u8 status)
294350fc85f1SKuba Pawlak {
294450fc85f1SKuba Pawlak struct hci_cp_switch_role *cp;
294550fc85f1SKuba Pawlak struct hci_conn *conn;
294650fc85f1SKuba Pawlak
294750fc85f1SKuba Pawlak BT_DBG("%s status 0x%2.2x", hdev->name, status);
294850fc85f1SKuba Pawlak
294950fc85f1SKuba Pawlak if (!status)
295050fc85f1SKuba Pawlak return;
295150fc85f1SKuba Pawlak
295250fc85f1SKuba Pawlak cp = hci_sent_cmd_data(hdev, HCI_OP_SWITCH_ROLE);
295350fc85f1SKuba Pawlak if (!cp)
295450fc85f1SKuba Pawlak return;
295550fc85f1SKuba Pawlak
295650fc85f1SKuba Pawlak hci_dev_lock(hdev);
295750fc85f1SKuba Pawlak
295850fc85f1SKuba Pawlak conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
295950fc85f1SKuba Pawlak if (conn)
296050fc85f1SKuba Pawlak clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
296150fc85f1SKuba Pawlak
296250fc85f1SKuba Pawlak hci_dev_unlock(hdev);
296350fc85f1SKuba Pawlak }
296450fc85f1SKuba Pawlak
hci_inquiry_complete_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)29653e54c589SLuiz Augusto von Dentz static void hci_inquiry_complete_evt(struct hci_dev *hdev, void *data,
29663e54c589SLuiz Augusto von Dentz struct sk_buff *skb)
29671da177e4SLinus Torvalds {
29683e54c589SLuiz Augusto von Dentz struct hci_ev_status *ev = data;
296930dc78e1SJohan Hedberg struct discovery_state *discov = &hdev->discovery;
297030dc78e1SJohan Hedberg struct inquiry_entry *e;
29711da177e4SLinus Torvalds
29723e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
29731da177e4SLinus Torvalds
297489352e7dSAndre Guedes if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
297589352e7dSAndre Guedes return;
297689352e7dSAndre Guedes
29774e857c58SPeter Zijlstra smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */
29783e13fa1eSAndre Guedes wake_up_bit(&hdev->flags, HCI_INQUIRY);
29793e13fa1eSAndre Guedes
2980d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT))
298130dc78e1SJohan Hedberg return;
298230dc78e1SJohan Hedberg
298356e5cb86SJohan Hedberg hci_dev_lock(hdev);
298430dc78e1SJohan Hedberg
2985343f935bSAndre Guedes if (discov->state != DISCOVERY_FINDING)
298630dc78e1SJohan Hedberg goto unlock;
298730dc78e1SJohan Hedberg
298830dc78e1SJohan Hedberg if (list_empty(&discov->resolve)) {
298907d2334aSJakub Pawlowski /* When BR/EDR inquiry is active and no LE scanning is in
299007d2334aSJakub Pawlowski * progress, then change discovery state to indicate completion.
299107d2334aSJakub Pawlowski *
299207d2334aSJakub Pawlowski * When running LE scanning and BR/EDR inquiry simultaneously
299307d2334aSJakub Pawlowski * and the LE scan already finished, then change the discovery
299407d2334aSJakub Pawlowski * state to indicate completion.
299507d2334aSJakub Pawlowski */
299607d2334aSJakub Pawlowski if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
299707d2334aSJakub Pawlowski !test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks))
2998ff9ef578SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
299930dc78e1SJohan Hedberg goto unlock;
300030dc78e1SJohan Hedberg }
300130dc78e1SJohan Hedberg
300230dc78e1SJohan Hedberg e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
300330dc78e1SJohan Hedberg if (e && hci_resolve_name(hdev, e) == 0) {
300430dc78e1SJohan Hedberg e->name_state = NAME_PENDING;
300530dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
3006dbf6811aSArchie Pusaka discov->name_resolve_timeout = jiffies + NAME_RESOLVE_DURATION;
300730dc78e1SJohan Hedberg } else {
300807d2334aSJakub Pawlowski /* When BR/EDR inquiry is active and no LE scanning is in
300907d2334aSJakub Pawlowski * progress, then change discovery state to indicate completion.
301007d2334aSJakub Pawlowski *
301107d2334aSJakub Pawlowski * When running LE scanning and BR/EDR inquiry simultaneously
301207d2334aSJakub Pawlowski * and the LE scan already finished, then change the discovery
301307d2334aSJakub Pawlowski * state to indicate completion.
301407d2334aSJakub Pawlowski */
301507d2334aSJakub Pawlowski if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
301607d2334aSJakub Pawlowski !test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks))
301730dc78e1SJohan Hedberg hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
301830dc78e1SJohan Hedberg }
301930dc78e1SJohan Hedberg
302030dc78e1SJohan Hedberg unlock:
302156e5cb86SJohan Hedberg hci_dev_unlock(hdev);
30221da177e4SLinus Torvalds }
30231da177e4SLinus Torvalds
hci_inquiry_result_evt(struct hci_dev * hdev,void * edata,struct sk_buff * skb)30243e54c589SLuiz Augusto von Dentz static void hci_inquiry_result_evt(struct hci_dev *hdev, void *edata,
30253e54c589SLuiz Augusto von Dentz struct sk_buff *skb)
30261da177e4SLinus Torvalds {
30273e54c589SLuiz Augusto von Dentz struct hci_ev_inquiry_result *ev = edata;
302845bb4bf0SMarcel Holtmann struct inquiry_data data;
302927d9eb4bSLuiz Augusto von Dentz int i;
30301da177e4SLinus Torvalds
303127d9eb4bSLuiz Augusto von Dentz if (!hci_ev_skb_pull(hdev, skb, HCI_EV_INQUIRY_RESULT,
303227d9eb4bSLuiz Augusto von Dentz flex_array_size(ev, info, ev->num)))
303327d9eb4bSLuiz Augusto von Dentz return;
303427d9eb4bSLuiz Augusto von Dentz
30353e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "num %d", ev->num);
303627d9eb4bSLuiz Augusto von Dentz
303727d9eb4bSLuiz Augusto von Dentz if (!ev->num)
303845bb4bf0SMarcel Holtmann return;
303945bb4bf0SMarcel Holtmann
3040d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ))
30411519cc17SAndre Guedes return;
30421519cc17SAndre Guedes
30431da177e4SLinus Torvalds hci_dev_lock(hdev);
304445bb4bf0SMarcel Holtmann
304527d9eb4bSLuiz Augusto von Dentz for (i = 0; i < ev->num; i++) {
304627d9eb4bSLuiz Augusto von Dentz struct inquiry_info *info = &ev->info[i];
3047af58925cSMarcel Holtmann u32 flags;
30483175405bSJohan Hedberg
30491da177e4SLinus Torvalds bacpy(&data.bdaddr, &info->bdaddr);
30501da177e4SLinus Torvalds data.pscan_rep_mode = info->pscan_rep_mode;
30511da177e4SLinus Torvalds data.pscan_period_mode = info->pscan_period_mode;
30521da177e4SLinus Torvalds data.pscan_mode = info->pscan_mode;
30531da177e4SLinus Torvalds memcpy(data.dev_class, info->dev_class, 3);
30541da177e4SLinus Torvalds data.clock_offset = info->clock_offset;
3055efb2513fSMarcel Holtmann data.rssi = HCI_RSSI_INVALID;
305641a96212SMarcel Holtmann data.ssp_mode = 0x00;
30573175405bSJohan Hedberg
3058af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, false);
3059af58925cSMarcel Holtmann
306048264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
3061efb2513fSMarcel Holtmann info->dev_class, HCI_RSSI_INVALID,
3062b338d917SBrian Gix flags, NULL, 0, NULL, 0, 0);
30631da177e4SLinus Torvalds }
306445bb4bf0SMarcel Holtmann
30651da177e4SLinus Torvalds hci_dev_unlock(hdev);
30661da177e4SLinus Torvalds }
30671da177e4SLinus Torvalds
hci_conn_complete_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)30683e54c589SLuiz Augusto von Dentz static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
30693e54c589SLuiz Augusto von Dentz struct sk_buff *skb)
30701da177e4SLinus Torvalds {
30713e54c589SLuiz Augusto von Dentz struct hci_ev_conn_complete *ev = data;
3072a9de9248SMarcel Holtmann struct hci_conn *conn;
3073c86cc5a3SLuiz Augusto von Dentz u8 status = ev->status;
30741da177e4SLinus Torvalds
3075c86cc5a3SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status);
307645bb4bf0SMarcel Holtmann
30771da177e4SLinus Torvalds hci_dev_lock(hdev);
307845bb4bf0SMarcel Holtmann
3079a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
30809499237aSMarcel Holtmann if (!conn) {
3081aef2aa4fSLuiz Augusto von Dentz /* In case of error status and there is no connection pending
3082aef2aa4fSLuiz Augusto von Dentz * just unlock as there is nothing to cleanup.
3083aef2aa4fSLuiz Augusto von Dentz */
3084aef2aa4fSLuiz Augusto von Dentz if (ev->status)
3085aef2aa4fSLuiz Augusto von Dentz goto unlock;
3086aef2aa4fSLuiz Augusto von Dentz
3087a46b7ed4SSonny Sasaka /* Connection may not exist if auto-connected. Check the bredr
3088a46b7ed4SSonny Sasaka * allowlist to see if this device is allowed to auto connect.
3089a46b7ed4SSonny Sasaka * If link is an ACL type, create a connection class
30904f40afc6SAbhishek Pandit-Subedi * automatically.
3091a46b7ed4SSonny Sasaka *
3092a46b7ed4SSonny Sasaka * Auto-connect will only occur if the event filter is
3093a46b7ed4SSonny Sasaka * programmed with a given address. Right now, event filter is
3094a46b7ed4SSonny Sasaka * only used during suspend.
30954f40afc6SAbhishek Pandit-Subedi */
3096a46b7ed4SSonny Sasaka if (ev->link_type == ACL_LINK &&
30973d4f9c00SArchie Pusaka hci_bdaddr_list_lookup_with_flags(&hdev->accept_list,
3098a46b7ed4SSonny Sasaka &ev->bdaddr,
3099a46b7ed4SSonny Sasaka BDADDR_BREDR)) {
310084cb0143SZiyang Xuan conn = hci_conn_add_unset(hdev, ev->link_type,
310184cb0143SZiyang Xuan &ev->bdaddr, HCI_ROLE_SLAVE);
3102ad3f7986SSungwoo Kim if (IS_ERR(conn)) {
3103ad3f7986SSungwoo Kim bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn));
31044f40afc6SAbhishek Pandit-Subedi goto unlock;
31054f40afc6SAbhishek Pandit-Subedi }
31062d186fcdSAbhishek Pandit-Subedi } else {
31079499237aSMarcel Holtmann if (ev->link_type != SCO_LINK)
31089499237aSMarcel Holtmann goto unlock;
31099499237aSMarcel Holtmann
31102d186fcdSAbhishek Pandit-Subedi conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK,
31112d186fcdSAbhishek Pandit-Subedi &ev->bdaddr);
3112a9de9248SMarcel Holtmann if (!conn)
3113a9de9248SMarcel Holtmann goto unlock;
311445bb4bf0SMarcel Holtmann
31159499237aSMarcel Holtmann conn->type = SCO_LINK;
31169499237aSMarcel Holtmann }
31172d186fcdSAbhishek Pandit-Subedi }
31189499237aSMarcel Holtmann
3119d5ebaa7cSSoenke Huster /* The HCI_Connection_Complete event is only sent once per connection.
3120d5ebaa7cSSoenke Huster * Processing it more than once per connection can corrupt kernel memory.
3121d5ebaa7cSSoenke Huster *
3122d5ebaa7cSSoenke Huster * As the connection handle is set here for the first time, it indicates
3123d5ebaa7cSSoenke Huster * whether the connection is already set up.
3124d5ebaa7cSSoenke Huster */
31259f78191cSLuiz Augusto von Dentz if (!HCI_CONN_HANDLE_UNSET(conn->handle)) {
3126d5ebaa7cSSoenke Huster bt_dev_err(hdev, "Ignoring HCI_Connection_Complete for existing connection");
3127d5ebaa7cSSoenke Huster goto unlock;
3128d5ebaa7cSSoenke Huster }
3129d5ebaa7cSSoenke Huster
3130c86cc5a3SLuiz Augusto von Dentz if (!status) {
313116e3b642SLuiz Augusto von Dentz status = hci_conn_set_handle(conn, __le16_to_cpu(ev->handle));
313216e3b642SLuiz Augusto von Dentz if (status)
3133c86cc5a3SLuiz Augusto von Dentz goto done;
3134769be974SMarcel Holtmann
3135769be974SMarcel Holtmann if (conn->type == ACL_LINK) {
3136769be974SMarcel Holtmann conn->state = BT_CONFIG;
3137769be974SMarcel Holtmann hci_conn_hold(conn);
3138a9ea3ed9SSzymon Janc
3139a9ea3ed9SSzymon Janc if (!conn->out && !hci_conn_ssp_enabled(conn) &&
3140a9ea3ed9SSzymon Janc !hci_find_link_key(hdev, &ev->bdaddr))
3141a9ea3ed9SSzymon Janc conn->disc_timeout = HCI_PAIRING_TIMEOUT;
3142a9ea3ed9SSzymon Janc else
3143052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT;
3144769be974SMarcel Holtmann } else
3145a9de9248SMarcel Holtmann conn->state = BT_CONNECTED;
3146a9de9248SMarcel Holtmann
314723b9ceb7SMarcel Holtmann hci_debugfs_create_conn(conn);
31487d0db0a3SMarcel Holtmann hci_conn_add_sysfs(conn);
31497d0db0a3SMarcel Holtmann
3150a9de9248SMarcel Holtmann if (test_bit(HCI_AUTH, &hdev->flags))
31514dae2798SJohan Hedberg set_bit(HCI_CONN_AUTH, &conn->flags);
3152a9de9248SMarcel Holtmann
3153a9de9248SMarcel Holtmann if (test_bit(HCI_ENCRYPT, &hdev->flags))
31544dae2798SJohan Hedberg set_bit(HCI_CONN_ENCRYPT, &conn->flags);
3155a9de9248SMarcel Holtmann
31564a328401SHui Wang /* "Link key request" completed ahead of "connect request" completes */
31574a328401SHui Wang if (ev->encr_mode == 1 && !test_bit(HCI_CONN_ENCRYPT, &conn->flags) &&
31584a328401SHui Wang ev->link_type == ACL_LINK) {
31594a328401SHui Wang struct link_key *key;
31604a328401SHui Wang struct hci_cp_read_enc_key_size cp;
31614a328401SHui Wang
31624a328401SHui Wang key = hci_find_link_key(hdev, &ev->bdaddr);
31634a328401SHui Wang if (key) {
31644a328401SHui Wang set_bit(HCI_CONN_ENCRYPT, &conn->flags);
31654a328401SHui Wang
316662e3a7cbSLuiz Augusto von Dentz if (!read_key_size_capable(hdev)) {
31674a328401SHui Wang conn->enc_key_size = HCI_LINK_KEY_SIZE;
31684a328401SHui Wang } else {
31694a328401SHui Wang cp.handle = cpu_to_le16(conn->handle);
31704a328401SHui Wang if (hci_send_cmd(hdev, HCI_OP_READ_ENC_KEY_SIZE,
31714a328401SHui Wang sizeof(cp), &cp)) {
31724a328401SHui Wang bt_dev_err(hdev, "sending read key size failed");
31734a328401SHui Wang conn->enc_key_size = HCI_LINK_KEY_SIZE;
31744a328401SHui Wang }
31754a328401SHui Wang }
31764a328401SHui Wang
31774a328401SHui Wang hci_encrypt_cfm(conn, ev->status);
31784a328401SHui Wang }
31794a328401SHui Wang }
31804a328401SHui Wang
3181a9de9248SMarcel Holtmann /* Get remote features */
3182a9de9248SMarcel Holtmann if (conn->type == ACL_LINK) {
3183a9de9248SMarcel Holtmann struct hci_cp_read_remote_features cp;
3184a9de9248SMarcel Holtmann cp.handle = ev->handle;
3185769be974SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
3186769be974SMarcel Holtmann sizeof(cp), &cp);
318722f433dcSJohan Hedberg
3188bb876725SBrian Gix hci_update_scan(hdev);
318945bb4bf0SMarcel Holtmann }
3190a9de9248SMarcel Holtmann
3191a9de9248SMarcel Holtmann /* Set packet type for incoming connection */
3192d095c1ebSAndrei Emeltchenko if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
3193a9de9248SMarcel Holtmann struct hci_cp_change_conn_ptype cp;
3194a9de9248SMarcel Holtmann cp.handle = ev->handle;
3195a8746417SMarcel Holtmann cp.pkt_type = cpu_to_le16(conn->pkt_type);
319604124681SGustavo F. Padovan hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
319704124681SGustavo F. Padovan &cp);
3198a9de9248SMarcel Holtmann }
319917d5c04cSJohan Hedberg }
320045bb4bf0SMarcel Holtmann
3201e73439d8SMarcel Holtmann if (conn->type == ACL_LINK)
3202e73439d8SMarcel Holtmann hci_sco_setup(conn, ev->status);
320345bb4bf0SMarcel Holtmann
3204c86cc5a3SLuiz Augusto von Dentz done:
3205c86cc5a3SLuiz Augusto von Dentz if (status) {
32069b3628d7SLuiz Augusto von Dentz hci_conn_failed(conn, status);
32071f8330eaSSathish Narsimman } else if (ev->link_type == SCO_LINK) {
32081f8330eaSSathish Narsimman switch (conn->setting & SCO_AIRMODE_MASK) {
32091f8330eaSSathish Narsimman case SCO_AIRMODE_CVSD:
32101f8330eaSSathish Narsimman if (hdev->notify)
32111f8330eaSSathish Narsimman hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD);
32121f8330eaSSathish Narsimman break;
32131f8330eaSSathish Narsimman }
32141f8330eaSSathish Narsimman
3215c86cc5a3SLuiz Augusto von Dentz hci_connect_cfm(conn, status);
32161f8330eaSSathish Narsimman }
3217a9de9248SMarcel Holtmann
3218a9de9248SMarcel Holtmann unlock:
32191da177e4SLinus Torvalds hci_dev_unlock(hdev);
32201da177e4SLinus Torvalds }
32211da177e4SLinus Torvalds
hci_reject_conn(struct hci_dev * hdev,bdaddr_t * bdaddr)322270c46425SJohan Hedberg static void hci_reject_conn(struct hci_dev *hdev, bdaddr_t *bdaddr)
322370c46425SJohan Hedberg {
322470c46425SJohan Hedberg struct hci_cp_reject_conn_req cp;
322570c46425SJohan Hedberg
322670c46425SJohan Hedberg bacpy(&cp.bdaddr, bdaddr);
322770c46425SJohan Hedberg cp.reason = HCI_ERROR_REJ_BAD_ADDR;
322870c46425SJohan Hedberg hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
322970c46425SJohan Hedberg }
323070c46425SJohan Hedberg
hci_conn_request_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)32313e54c589SLuiz Augusto von Dentz static void hci_conn_request_evt(struct hci_dev *hdev, void *data,
32323e54c589SLuiz Augusto von Dentz struct sk_buff *skb)
32331da177e4SLinus Torvalds {
32343e54c589SLuiz Augusto von Dentz struct hci_ev_conn_request *ev = data;
32351da177e4SLinus Torvalds int mask = hdev->link_mode;
323670c46425SJohan Hedberg struct inquiry_entry *ie;
323770c46425SJohan Hedberg struct hci_conn *conn;
323820714bfeSFrédéric Dalleau __u8 flags = 0;
32391da177e4SLinus Torvalds
32403e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "bdaddr %pMR type 0x%x", &ev->bdaddr, ev->link_type);
32411da177e4SLinus Torvalds
32421ffc6f8cSLee, Chun-Yi /* Reject incoming connection from device with same BD ADDR against
32431ffc6f8cSLee, Chun-Yi * CVE-2020-26555
32441ffc6f8cSLee, Chun-Yi */
32459d1a3c74SArnd Bergmann if (hdev && !bacmp(&hdev->bdaddr, &ev->bdaddr)) {
32461ffc6f8cSLee, Chun-Yi bt_dev_dbg(hdev, "Reject connection with same BD_ADDR %pMR\n",
32471ffc6f8cSLee, Chun-Yi &ev->bdaddr);
32481ffc6f8cSLee, Chun-Yi hci_reject_conn(hdev, &ev->bdaddr);
32491ffc6f8cSLee, Chun-Yi return;
32501ffc6f8cSLee, Chun-Yi }
32511ffc6f8cSLee, Chun-Yi
325220714bfeSFrédéric Dalleau mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
325320714bfeSFrédéric Dalleau &flags);
32541da177e4SLinus Torvalds
325570c46425SJohan Hedberg if (!(mask & HCI_LM_ACCEPT)) {
325670c46425SJohan Hedberg hci_reject_conn(hdev, &ev->bdaddr);
325770c46425SJohan Hedberg return;
325870c46425SJohan Hedberg }
325970c46425SJohan Hedberg
3260fb048caeSNiels Dossche hci_dev_lock(hdev);
3261fb048caeSNiels Dossche
32623d4f9c00SArchie Pusaka if (hci_bdaddr_list_lookup(&hdev->reject_list, &ev->bdaddr,
3263dcc36c16SJohan Hedberg BDADDR_BREDR)) {
326470c46425SJohan Hedberg hci_reject_conn(hdev, &ev->bdaddr);
3265fb048caeSNiels Dossche goto unlock;
326670c46425SJohan Hedberg }
326746c4c941SJohan Hedberg
32683d4f9c00SArchie Pusaka /* Require HCI_CONNECTABLE or an accept list entry to accept the
32696a8fc95cSJohan Hedberg * connection. These features are only touched through mgmt so
32706a8fc95cSJohan Hedberg * only do the checks if HCI_MGMT is set.
32716a8fc95cSJohan Hedberg */
3272d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT) &&
3273d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_CONNECTABLE) &&
32743d4f9c00SArchie Pusaka !hci_bdaddr_list_lookup_with_flags(&hdev->accept_list, &ev->bdaddr,
3275a55bd29dSJohan Hedberg BDADDR_BREDR)) {
3276a55bd29dSJohan Hedberg hci_reject_conn(hdev, &ev->bdaddr);
3277fb048caeSNiels Dossche goto unlock;
3278a55bd29dSJohan Hedberg }
327970c46425SJohan Hedberg
32801da177e4SLinus Torvalds /* Connection accepted */
32811da177e4SLinus Torvalds
3282cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3283cc11b9c1SAndrei Emeltchenko if (ie)
3284c7bdd502SMarcel Holtmann memcpy(ie->data.dev_class, ev->dev_class, 3);
3285c7bdd502SMarcel Holtmann
32868fc9ced3SGustavo Padovan conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
32878fc9ced3SGustavo Padovan &ev->bdaddr);
32881da177e4SLinus Torvalds if (!conn) {
328984cb0143SZiyang Xuan conn = hci_conn_add_unset(hdev, ev->link_type, &ev->bdaddr,
3290a5c4e309SJohan Hedberg HCI_ROLE_SLAVE);
3291ad3f7986SSungwoo Kim if (IS_ERR(conn)) {
3292ad3f7986SSungwoo Kim bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn));
3293fb048caeSNiels Dossche goto unlock;
32941da177e4SLinus Torvalds }
32951da177e4SLinus Torvalds }
3296b6a0dc82SMarcel Holtmann
32971da177e4SLinus Torvalds memcpy(conn->dev_class, ev->dev_class, 3);
3298b6a0dc82SMarcel Holtmann
32991da177e4SLinus Torvalds hci_dev_unlock(hdev);
33001da177e4SLinus Torvalds
330120714bfeSFrédéric Dalleau if (ev->link_type == ACL_LINK ||
330220714bfeSFrédéric Dalleau (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
3303b6a0dc82SMarcel Holtmann struct hci_cp_accept_conn_req cp;
330420714bfeSFrédéric Dalleau conn->state = BT_CONNECT;
3305b6a0dc82SMarcel Holtmann
33061da177e4SLinus Torvalds bacpy(&cp.bdaddr, &ev->bdaddr);
33071da177e4SLinus Torvalds
33081da177e4SLinus Torvalds if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
330974be523cSArchie Pusaka cp.role = 0x00; /* Become central */
33101da177e4SLinus Torvalds else
331174be523cSArchie Pusaka cp.role = 0x01; /* Remain peripheral */
33121da177e4SLinus Torvalds
331370c46425SJohan Hedberg hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp);
331420714bfeSFrédéric Dalleau } else if (!(flags & HCI_PROTO_DEFER)) {
3315b6a0dc82SMarcel Holtmann struct hci_cp_accept_sync_conn_req cp;
331620714bfeSFrédéric Dalleau conn->state = BT_CONNECT;
3317b6a0dc82SMarcel Holtmann
3318b6a0dc82SMarcel Holtmann bacpy(&cp.bdaddr, &ev->bdaddr);
3319a8746417SMarcel Holtmann cp.pkt_type = cpu_to_le16(conn->pkt_type);
3320b6a0dc82SMarcel Holtmann
3321dcf4adbfSJoe Perches cp.tx_bandwidth = cpu_to_le32(0x00001f40);
3322dcf4adbfSJoe Perches cp.rx_bandwidth = cpu_to_le32(0x00001f40);
3323dcf4adbfSJoe Perches cp.max_latency = cpu_to_le16(0xffff);
3324b6a0dc82SMarcel Holtmann cp.content_format = cpu_to_le16(hdev->voice_setting);
3325b6a0dc82SMarcel Holtmann cp.retrans_effort = 0xff;
3326b6a0dc82SMarcel Holtmann
332770c46425SJohan Hedberg hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, sizeof(cp),
332870c46425SJohan Hedberg &cp);
332920714bfeSFrédéric Dalleau } else {
333020714bfeSFrédéric Dalleau conn->state = BT_CONNECT2;
3331539c496dSJohan Hedberg hci_connect_cfm(conn, 0);
3332b6a0dc82SMarcel Holtmann }
3333fb048caeSNiels Dossche
3334fb048caeSNiels Dossche return;
3335fb048caeSNiels Dossche unlock:
3336fb048caeSNiels Dossche hci_dev_unlock(hdev);
33371da177e4SLinus Torvalds }
33381da177e4SLinus Torvalds
hci_to_mgmt_reason(u8 err)3339f0d6a0eaSMikel Astiz static u8 hci_to_mgmt_reason(u8 err)
3340f0d6a0eaSMikel Astiz {
3341f0d6a0eaSMikel Astiz switch (err) {
3342f0d6a0eaSMikel Astiz case HCI_ERROR_CONNECTION_TIMEOUT:
3343f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_TIMEOUT;
3344f0d6a0eaSMikel Astiz case HCI_ERROR_REMOTE_USER_TERM:
3345f0d6a0eaSMikel Astiz case HCI_ERROR_REMOTE_LOW_RESOURCES:
3346f0d6a0eaSMikel Astiz case HCI_ERROR_REMOTE_POWER_OFF:
3347f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_REMOTE;
3348f0d6a0eaSMikel Astiz case HCI_ERROR_LOCAL_HOST_TERM:
3349f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_LOCAL_HOST;
3350f0d6a0eaSMikel Astiz default:
3351f0d6a0eaSMikel Astiz return MGMT_DEV_DISCONN_UNKNOWN;
3352f0d6a0eaSMikel Astiz }
3353f0d6a0eaSMikel Astiz }
3354f0d6a0eaSMikel Astiz
hci_disconn_complete_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)33553e54c589SLuiz Augusto von Dentz static void hci_disconn_complete_evt(struct hci_dev *hdev, void *data,
33563e54c589SLuiz Augusto von Dentz struct sk_buff *skb)
33571da177e4SLinus Torvalds {
33583e54c589SLuiz Augusto von Dentz struct hci_ev_disconn_complete *ev = data;
3359160b9251SSzymon Janc u8 reason;
33609fcb18efSAndre Guedes struct hci_conn_params *params;
336104837f64SMarcel Holtmann struct hci_conn *conn;
336212d4a3b2SJohan Hedberg bool mgmt_connected;
33631da177e4SLinus Torvalds
33643e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
33651da177e4SLinus Torvalds
33661da177e4SLinus Torvalds hci_dev_lock(hdev);
33671da177e4SLinus Torvalds
336804837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3369f7520543SJohan Hedberg if (!conn)
3370f7520543SJohan Hedberg goto unlock;
3371f7520543SJohan Hedberg
3372f0d6a0eaSMikel Astiz if (ev->status) {
337388c3df13SJohan Hedberg mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
337488c3df13SJohan Hedberg conn->dst_type, ev->status);
3375abf54a50SAndre Guedes goto unlock;
3376abf54a50SAndre Guedes }
3377f0d6a0eaSMikel Astiz
33783846220bSAndre Guedes conn->state = BT_CLOSED;
33793846220bSAndre Guedes
338012d4a3b2SJohan Hedberg mgmt_connected = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
3381160b9251SSzymon Janc
3382160b9251SSzymon Janc if (test_bit(HCI_CONN_AUTH_FAILURE, &conn->flags))
3383160b9251SSzymon Janc reason = MGMT_DEV_DISCONN_AUTH_FAILURE;
3384160b9251SSzymon Janc else
3385160b9251SSzymon Janc reason = hci_to_mgmt_reason(ev->reason);
3386160b9251SSzymon Janc
338712d4a3b2SJohan Hedberg mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type,
338812d4a3b2SJohan Hedberg reason, mgmt_connected);
3389f7520543SJohan Hedberg
339022f433dcSJohan Hedberg if (conn->type == ACL_LINK) {
3391629f66aaSAlain Michaud if (test_and_clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags))
33926ec5bcadSVishal Agarwal hci_remove_link_key(hdev, &conn->dst);
33933846220bSAndre Guedes
3394bb876725SBrian Gix hci_update_scan(hdev);
339522f433dcSJohan Hedberg }
339622f433dcSJohan Hedberg
3397*7e8cd2bcSLuiz Augusto von Dentz /* Re-enable passive scanning if disconnected device is marked
3398*7e8cd2bcSLuiz Augusto von Dentz * as auto-connectable.
3399*7e8cd2bcSLuiz Augusto von Dentz */
3400*7e8cd2bcSLuiz Augusto von Dentz if (conn->type == LE_LINK) {
3401*7e8cd2bcSLuiz Augusto von Dentz params = hci_conn_params_lookup(hdev, &conn->dst,
3402*7e8cd2bcSLuiz Augusto von Dentz conn->dst_type);
34039fcb18efSAndre Guedes if (params) {
34049fcb18efSAndre Guedes switch (params->auto_connect) {
34059fcb18efSAndre Guedes case HCI_AUTO_CONN_LINK_LOSS:
34069fcb18efSAndre Guedes if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT)
34079fcb18efSAndre Guedes break;
340819186c7bSGustavo A. R. Silva fallthrough;
34099fcb18efSAndre Guedes
34104b9e7e75SMarcel Holtmann case HCI_AUTO_CONN_DIRECT:
34119fcb18efSAndre Guedes case HCI_AUTO_CONN_ALWAYS:
3412195ef75eSPauli Virtanen hci_pend_le_list_del_init(params);
3413*7e8cd2bcSLuiz Augusto von Dentz hci_pend_le_list_add(params,
3414*7e8cd2bcSLuiz Augusto von Dentz &hdev->pend_le_conns);
34155bee2fd6SLuiz Augusto von Dentz hci_update_passive_scan(hdev);
34169fcb18efSAndre Guedes break;
34179fcb18efSAndre Guedes
34189fcb18efSAndre Guedes default:
34199fcb18efSAndre Guedes break;
34209fcb18efSAndre Guedes }
34219fcb18efSAndre Guedes }
3422*7e8cd2bcSLuiz Augusto von Dentz }
34239fcb18efSAndre Guedes
34243a6d576bSJohan Hedberg hci_disconn_cfm(conn, ev->reason);
34252210246cSJohan Hedberg
34262210246cSJohan Hedberg /* Re-enable advertising if necessary, since it might
34272210246cSJohan Hedberg * have been disabled by the connection. From the
34282210246cSJohan Hedberg * HCI_LE_Set_Advertise_Enable command description in
34292210246cSJohan Hedberg * the core specification (v4.0):
34302210246cSJohan Hedberg * "The Controller shall continue advertising until the Host
34312210246cSJohan Hedberg * issues an LE_Set_Advertise_Enable command with
34322210246cSJohan Hedberg * Advertising_Enable set to 0x00 (Advertising is disabled)
34332210246cSJohan Hedberg * or until a connection is created or until the Advertising
34342210246cSJohan Hedberg * is timed out due to Directed Advertising."
34352210246cSJohan Hedberg */
34361eeaa1aeSLuiz Augusto von Dentz if (conn->type == LE_LINK && conn->role == HCI_ROLE_SLAVE) {
34377087c4f6SLuiz Augusto von Dentz hdev->cur_adv_instance = conn->adv_instance;
3438abfeea47SLuiz Augusto von Dentz hci_enable_advertising(hdev);
34397087c4f6SLuiz Augusto von Dentz }
34407087c4f6SLuiz Augusto von Dentz
34417087c4f6SLuiz Augusto von Dentz hci_conn_del(conn);
34421da177e4SLinus Torvalds
3443f7520543SJohan Hedberg unlock:
34441da177e4SLinus Torvalds hci_dev_unlock(hdev);
34451da177e4SLinus Torvalds }
34461da177e4SLinus Torvalds
34473e54c589SLuiz Augusto von Dentz static void hci_auth_complete_evt(struct hci_dev *hdev, void *data,
34483e54c589SLuiz Augusto von Dentz struct sk_buff *skb)
3449a9de9248SMarcel Holtmann {
34503e54c589SLuiz Augusto von Dentz struct hci_ev_auth_complete *ev = data;
3451a9de9248SMarcel Holtmann struct hci_conn *conn;
3452a9de9248SMarcel Holtmann
34533e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
3454a9de9248SMarcel Holtmann
3455a9de9248SMarcel Holtmann hci_dev_lock(hdev);
3456a9de9248SMarcel Holtmann
3457a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3458d7556e20SWaldemar Rymarkiewicz if (!conn)
3459d7556e20SWaldemar Rymarkiewicz goto unlock;
3460d7556e20SWaldemar Rymarkiewicz
3461765c2a96SJohan Hedberg if (!ev->status) {
3462160b9251SSzymon Janc clear_bit(HCI_CONN_AUTH_FAILURE, &conn->flags);
34634dae2798SJohan Hedberg set_bit(HCI_CONN_AUTH, &conn->flags);
3464765c2a96SJohan Hedberg conn->sec_level = conn->pending_sec_level;
34652a611692SJohan Hedberg } else {
3466160b9251SSzymon Janc if (ev->status == HCI_ERROR_PIN_OR_KEY_MISSING)
3467160b9251SSzymon Janc set_bit(HCI_CONN_AUTH_FAILURE, &conn->flags);
3468160b9251SSzymon Janc
3469e1e930f5SJohan Hedberg mgmt_auth_failed(conn, ev->status);
34702a611692SJohan Hedberg }
3471a9de9248SMarcel Holtmann
347251a8efd7SJohan Hedberg clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
3473a9de9248SMarcel Holtmann
3474f8558555SMarcel Holtmann if (conn->state == BT_CONFIG) {
3475aa64a8b5SJohan Hedberg if (!ev->status && hci_conn_ssp_enabled(conn)) {
3476f8558555SMarcel Holtmann struct hci_cp_set_conn_encrypt cp;
3477f8558555SMarcel Holtmann cp.handle = ev->handle;
3478f8558555SMarcel Holtmann cp.encrypt = 0x01;
3479d7556e20SWaldemar Rymarkiewicz hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
3480d7556e20SWaldemar Rymarkiewicz &cp);
3481f8558555SMarcel Holtmann } else {
3482f8558555SMarcel Holtmann conn->state = BT_CONNECTED;
3483539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status);
348476a68ba0SDavid Herrmann hci_conn_drop(conn);
3485f8558555SMarcel Holtmann }
3486052b30b0SMarcel Holtmann } else {
3487a9de9248SMarcel Holtmann hci_auth_cfm(conn, ev->status);
3488a9de9248SMarcel Holtmann
3489052b30b0SMarcel Holtmann hci_conn_hold(conn);
3490052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT;
349176a68ba0SDavid Herrmann hci_conn_drop(conn);
3492052b30b0SMarcel Holtmann }
3493052b30b0SMarcel Holtmann
349451a8efd7SJohan Hedberg if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
3495a9de9248SMarcel Holtmann if (!ev->status) {
3496a9de9248SMarcel Holtmann struct hci_cp_set_conn_encrypt cp;
3497f8558555SMarcel Holtmann cp.handle = ev->handle;
3498f8558555SMarcel Holtmann cp.encrypt = 0x01;
3499d7556e20SWaldemar Rymarkiewicz hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
3500d7556e20SWaldemar Rymarkiewicz &cp);
3501a9de9248SMarcel Holtmann } else {
350251a8efd7SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
35033ca44c16SLuiz Augusto von Dentz hci_encrypt_cfm(conn, ev->status);
hci_remote_name_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)3504a9de9248SMarcel Holtmann }
3505a9de9248SMarcel Holtmann }
3506a9de9248SMarcel Holtmann
3507d7556e20SWaldemar Rymarkiewicz unlock:
3508a9de9248SMarcel Holtmann hci_dev_unlock(hdev);
3509a9de9248SMarcel Holtmann }
3510a9de9248SMarcel Holtmann
35113e54c589SLuiz Augusto von Dentz static void hci_remote_name_evt(struct hci_dev *hdev, void *data,
35123e54c589SLuiz Augusto von Dentz struct sk_buff *skb)
3513a9de9248SMarcel Holtmann {
35143e54c589SLuiz Augusto von Dentz struct hci_ev_remote_name *ev = data;
3515127178d2SJohan Hedberg struct hci_conn *conn;
3516127178d2SJohan Hedberg
35173e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
3518a9de9248SMarcel Holtmann
3519127178d2SJohan Hedberg hci_dev_lock(hdev);
3520127178d2SJohan Hedberg
3521127178d2SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3522b644ba33SJohan Hedberg
3523d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT))
3524b644ba33SJohan Hedberg goto check_auth;
3525b644ba33SJohan Hedberg
3526b644ba33SJohan Hedberg if (ev->status == 0)
3527b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
3528b644ba33SJohan Hedberg strnlen(ev->name, HCI_MAX_NAME_LENGTH));
3529b644ba33SJohan Hedberg else
3530b644ba33SJohan Hedberg hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
3531b644ba33SJohan Hedberg
3532b644ba33SJohan Hedberg check_auth:
353379c6c70cSJohan Hedberg if (!conn)
353479c6c70cSJohan Hedberg goto unlock;
353579c6c70cSJohan Hedberg
353679c6c70cSJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn))
353779c6c70cSJohan Hedberg goto unlock;
353879c6c70cSJohan Hedberg
353951a8efd7SJohan Hedberg if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
3540127178d2SJohan Hedberg struct hci_cp_auth_requested cp;
3541977f8fceSJohan Hedberg
3542977f8fceSJohan Hedberg set_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags);
3543977f8fceSJohan Hedberg
3544127178d2SJohan Hedberg cp.handle = __cpu_to_le16(conn->handle);
hci_encrypt_change_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)3545127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
3546127178d2SJohan Hedberg }
3547127178d2SJohan Hedberg
354879c6c70cSJohan Hedberg unlock:
3549127178d2SJohan Hedberg hci_dev_unlock(hdev);
3550a9de9248SMarcel Holtmann }
3551a9de9248SMarcel Holtmann
35523e54c589SLuiz Augusto von Dentz static void hci_encrypt_change_evt(struct hci_dev *hdev, void *data,
35533e54c589SLuiz Augusto von Dentz struct sk_buff *skb)
3554a9de9248SMarcel Holtmann {
35553e54c589SLuiz Augusto von Dentz struct hci_ev_encrypt_change *ev = data;
3556a9de9248SMarcel Holtmann struct hci_conn *conn;
3557a9de9248SMarcel Holtmann
35583e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
3559a9de9248SMarcel Holtmann
3560a9de9248SMarcel Holtmann hci_dev_lock(hdev);
3561a9de9248SMarcel Holtmann
3562a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3563dc8357ccSMarcel Holtmann if (!conn)
3564dc8357ccSMarcel Holtmann goto unlock;
3565dc8357ccSMarcel Holtmann
3566a9de9248SMarcel Holtmann if (!ev->status) {
3567ae293196SMarcel Holtmann if (ev->encrypt) {
3568ae293196SMarcel Holtmann /* Encryption implies authentication */
35694dae2798SJohan Hedberg set_bit(HCI_CONN_AUTH, &conn->flags);
35704dae2798SJohan Hedberg set_bit(HCI_CONN_ENCRYPT, &conn->flags);
3571da85e5e5SVinicius Costa Gomes conn->sec_level = conn->pending_sec_level;
3572abf76badSMarcel Holtmann
3573914a6ffeSMarcel Holtmann /* P-256 authentication key implies FIPS */
3574914a6ffeSMarcel Holtmann if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256)
35754dae2798SJohan Hedberg set_bit(HCI_CONN_FIPS, &conn->flags);
3576914a6ffeSMarcel Holtmann
3577abf76badSMarcel Holtmann if ((conn->type == ACL_LINK && ev->encrypt == 0x02) ||
3578abf76badSMarcel Holtmann conn->type == LE_LINK)
3579abf76badSMarcel Holtmann set_bit(HCI_CONN_AES_CCM, &conn->flags);
3580abf76badSMarcel Holtmann } else {
35814dae2798SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT, &conn->flags);
3582abf76badSMarcel Holtmann clear_bit(HCI_CONN_AES_CCM, &conn->flags);
3583abf76badSMarcel Holtmann }
3584a9de9248SMarcel Holtmann }
3585a9de9248SMarcel Holtmann
35867ed3fa20SJohan Hedberg /* We should disregard the current RPA and generate a new one
35877ed3fa20SJohan Hedberg * whenever the encryption procedure fails.
35887ed3fa20SJohan Hedberg */
3589a73c046aSJaganath Kanakkassery if (ev->status && conn->type == LE_LINK) {
3590a1536da2SMarcel Holtmann hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
3591a73c046aSJaganath Kanakkassery hci_adv_instances_set_rpa_expired(hdev, true);
3592a73c046aSJaganath Kanakkassery }
35937ed3fa20SJohan Hedberg
359451a8efd7SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3595a9de9248SMarcel Holtmann
35968746f135SLuiz Augusto von Dentz /* Check link security requirements are met */
35978746f135SLuiz Augusto von Dentz if (!hci_conn_check_link_mode(conn))
35988746f135SLuiz Augusto von Dentz ev->status = HCI_ERROR_AUTH_FAILURE;
35998746f135SLuiz Augusto von Dentz
3600a7d7723aSGustavo Padovan if (ev->status && conn->state == BT_CONNECTED) {
3601160b9251SSzymon Janc if (ev->status == HCI_ERROR_PIN_OR_KEY_MISSING)
3602160b9251SSzymon Janc set_bit(HCI_CONN_AUTH_FAILURE, &conn->flags);
3603160b9251SSzymon Janc
36048746f135SLuiz Augusto von Dentz /* Notify upper layers so they can cleanup before
36058746f135SLuiz Augusto von Dentz * disconnecting.
360640b552aaSMarcel Holtmann */
36078746f135SLuiz Augusto von Dentz hci_encrypt_cfm(conn, ev->status);
36088746f135SLuiz Augusto von Dentz hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
360940b552aaSMarcel Holtmann hci_conn_drop(conn);
361040b552aaSMarcel Holtmann goto unlock;
361140b552aaSMarcel Holtmann }
361240b552aaSMarcel Holtmann
3613821f3766SJohan Hedberg /* Try reading the encryption key size for encrypted ACL links */
3614821f3766SJohan Hedberg if (!ev->status && ev->encrypt && conn->type == ACL_LINK) {
3615821f3766SJohan Hedberg struct hci_cp_read_enc_key_size cp;
3616821f3766SJohan Hedberg
3617821f3766SJohan Hedberg /* Only send HCI_Read_Encryption_Key_Size if the
3618821f3766SJohan Hedberg * controller really supports it. If it doesn't, assume
3619821f3766SJohan Hedberg * the default size (16).
3620821f3766SJohan Hedberg */
362162e3a7cbSLuiz Augusto von Dentz if (!read_key_size_capable(hdev)) {
3622821f3766SJohan Hedberg conn->enc_key_size = HCI_LINK_KEY_SIZE;
3623821f3766SJohan Hedberg goto notify;
3624821f3766SJohan Hedberg }
3625821f3766SJohan Hedberg
3626821f3766SJohan Hedberg cp.handle = cpu_to_le16(conn->handle);
3627278d933eSBrian Gix if (hci_send_cmd(hdev, HCI_OP_READ_ENC_KEY_SIZE,
3628278d933eSBrian Gix sizeof(cp), &cp)) {
36292064ee33SMarcel Holtmann bt_dev_err(hdev, "sending read key size failed");
3630821f3766SJohan Hedberg conn->enc_key_size = HCI_LINK_KEY_SIZE;
3631821f3766SJohan Hedberg goto notify;
3632821f3766SJohan Hedberg }
3633821f3766SJohan Hedberg
3634821f3766SJohan Hedberg goto unlock;
3635821f3766SJohan Hedberg }
3636821f3766SJohan Hedberg
3637ac22911fSDanil Pylaev /* We skip the WRITE_AUTH_PAYLOAD_TIMEOUT for ATS2851 based controllers
3638ac22911fSDanil Pylaev * to avoid unexpected SMP command errors when pairing.
3639ac22911fSDanil Pylaev */
3640ac22911fSDanil Pylaev if (test_bit(HCI_QUIRK_BROKEN_WRITE_AUTH_PAYLOAD_TIMEOUT,
3641ac22911fSDanil Pylaev &hdev->quirks))
3642ac22911fSDanil Pylaev goto notify;
3643ac22911fSDanil Pylaev
3644302975cbSSpoorthi Ravishankar Koppad /* Set the default Authenticated Payload Timeout after
3645302975cbSSpoorthi Ravishankar Koppad * an LE Link is established. As per Core Spec v5.0, Vol 2, Part B
3646302975cbSSpoorthi Ravishankar Koppad * Section 3.3, the HCI command WRITE_AUTH_PAYLOAD_TIMEOUT should be
3647302975cbSSpoorthi Ravishankar Koppad * sent when the link is active and Encryption is enabled, the conn
3648302975cbSSpoorthi Ravishankar Koppad * type can be either LE or ACL and controller must support LMP Ping.
3649302975cbSSpoorthi Ravishankar Koppad * Ensure for AES-CCM encryption as well.
3650302975cbSSpoorthi Ravishankar Koppad */
3651302975cbSSpoorthi Ravishankar Koppad if (test_bit(HCI_CONN_ENCRYPT, &conn->flags) &&
3652302975cbSSpoorthi Ravishankar Koppad test_bit(HCI_CONN_AES_CCM, &conn->flags) &&
3653302975cbSSpoorthi Ravishankar Koppad ((conn->type == ACL_LINK && lmp_ping_capable(hdev)) ||
3654302975cbSSpoorthi Ravishankar Koppad (conn->type == LE_LINK && (hdev->le_features[0] & HCI_LE_PING)))) {
3655302975cbSSpoorthi Ravishankar Koppad struct hci_cp_write_auth_payload_to cp;
3656302975cbSSpoorthi Ravishankar Koppad
3657302975cbSSpoorthi Ravishankar Koppad cp.handle = cpu_to_le16(conn->handle);
3658302975cbSSpoorthi Ravishankar Koppad cp.timeout = cpu_to_le16(hdev->auth_payload_timeout);
36597aca0ac4SLuiz Augusto von Dentz if (hci_send_cmd(conn->hdev, HCI_OP_WRITE_AUTH_PAYLOAD_TO,
3660399dea9dSLuiz Augusto von Dentz sizeof(cp), &cp))
36617aca0ac4SLuiz Augusto von Dentz bt_dev_err(hdev, "write auth payload timeout failed");
3662302975cbSSpoorthi Ravishankar Koppad }
3663302975cbSSpoorthi Ravishankar Koppad
hci_change_link_key_complete_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)3664821f3766SJohan Hedberg notify:
36653ca44c16SLuiz Augusto von Dentz hci_encrypt_cfm(conn, ev->status);
3666a9de9248SMarcel Holtmann
3667a7d7723aSGustavo Padovan unlock:
3668a9de9248SMarcel Holtmann hci_dev_unlock(hdev);
3669a9de9248SMarcel Holtmann }
3670a9de9248SMarcel Holtmann
36713e54c589SLuiz Augusto von Dentz static void hci_change_link_key_complete_evt(struct hci_dev *hdev, void *data,
3672807deac2SGustavo Padovan struct sk_buff *skb)
3673a9de9248SMarcel Holtmann {
36743e54c589SLuiz Augusto von Dentz struct hci_ev_change_link_key_complete *ev = data;
3675a9de9248SMarcel Holtmann struct hci_conn *conn;
3676a9de9248SMarcel Holtmann
36773e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
3678a9de9248SMarcel Holtmann
3679a9de9248SMarcel Holtmann hci_dev_lock(hdev);
3680a9de9248SMarcel Holtmann
3681a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3682a9de9248SMarcel Holtmann if (conn) {
3683a9de9248SMarcel Holtmann if (!ev->status)
36844dae2798SJohan Hedberg set_bit(HCI_CONN_SECURE, &conn->flags);
3685a9de9248SMarcel Holtmann
368651a8efd7SJohan Hedberg clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
hci_remote_features_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)3687a9de9248SMarcel Holtmann
3688a9de9248SMarcel Holtmann hci_key_change_cfm(conn, ev->status);
3689a9de9248SMarcel Holtmann }
3690a9de9248SMarcel Holtmann
3691a9de9248SMarcel Holtmann hci_dev_unlock(hdev);
3692a9de9248SMarcel Holtmann }
3693a9de9248SMarcel Holtmann
36943e54c589SLuiz Augusto von Dentz static void hci_remote_features_evt(struct hci_dev *hdev, void *data,
3695807deac2SGustavo Padovan struct sk_buff *skb)
3696a9de9248SMarcel Holtmann {
36973e54c589SLuiz Augusto von Dentz struct hci_ev_remote_features *ev = data;
3698a9de9248SMarcel Holtmann struct hci_conn *conn;
3699a9de9248SMarcel Holtmann
37003e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
3701a9de9248SMarcel Holtmann
3702a9de9248SMarcel Holtmann hci_dev_lock(hdev);
3703a9de9248SMarcel Holtmann
3704a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3705ccd556feSJohan Hedberg if (!conn)
3706ccd556feSJohan Hedberg goto unlock;
3707ccd556feSJohan Hedberg
3708769be974SMarcel Holtmann if (!ev->status)
3709cad718edSJohan Hedberg memcpy(conn->features[0], ev->features, 8);
3710a9de9248SMarcel Holtmann
3711ccd556feSJohan Hedberg if (conn->state != BT_CONFIG)
3712ccd556feSJohan Hedberg goto unlock;
3713ccd556feSJohan Hedberg
3714ac363cf9SSzymon Janc if (!ev->status && lmp_ext_feat_capable(hdev) &&
3715ac363cf9SSzymon Janc lmp_ext_feat_capable(conn)) {
3716769be974SMarcel Holtmann struct hci_cp_read_remote_ext_features cp;
3717769be974SMarcel Holtmann cp.handle = ev->handle;
3718769be974SMarcel Holtmann cp.page = 0x01;
3719ccd556feSJohan Hedberg hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
3720769be974SMarcel Holtmann sizeof(cp), &cp);
3721392599b9SJohan Hedberg goto unlock;
3722392599b9SJohan Hedberg }
3723392599b9SJohan Hedberg
3724b9090769SLuiz Augusto von Dentz if (!ev->status) {
3725127178d2SJohan Hedberg struct hci_cp_remote_name_req cp;
3726127178d2SJohan Hedberg memset(&cp, 0, sizeof(cp));
3727127178d2SJohan Hedberg bacpy(&cp.bdaddr, &conn->dst);
3728127178d2SJohan Hedberg cp.pscan_rep_mode = 0x02;
3729127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
37300b3df53cSLuiz Augusto von Dentz } else {
37311c6ed31bSYu Liu mgmt_device_connected(hdev, conn, NULL, 0);
37320b3df53cSLuiz Augusto von Dentz }
3733392599b9SJohan Hedberg
3734127178d2SJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) {
3735769be974SMarcel Holtmann conn->state = BT_CONNECTED;
3736539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status);
handle_cmd_cnt_and_timer(struct hci_dev * hdev,u8 ncmd)373776a68ba0SDavid Herrmann hci_conn_drop(conn);
3738769be974SMarcel Holtmann }
3739769be974SMarcel Holtmann
3740ccd556feSJohan Hedberg unlock:
3741a9de9248SMarcel Holtmann hci_dev_unlock(hdev);
3742a9de9248SMarcel Holtmann }
3743a9de9248SMarcel Holtmann
3744ecb71f25SKiran K static inline void handle_cmd_cnt_and_timer(struct hci_dev *hdev, u8 ncmd)
3745de75cd0dSManish Mandlik {
3746de75cd0dSManish Mandlik cancel_delayed_work(&hdev->cmd_timer);
3747de75cd0dSManish Mandlik
3748deee93d1STetsuo Handa rcu_read_lock();
3749de75cd0dSManish Mandlik if (!test_bit(HCI_RESET, &hdev->flags)) {
3750de75cd0dSManish Mandlik if (ncmd) {
3751de75cd0dSManish Mandlik cancel_delayed_work(&hdev->ncmd_timer);
3752de75cd0dSManish Mandlik atomic_set(&hdev->cmd_cnt, 1);
3753de75cd0dSManish Mandlik } else {
3754877afadaSSchspa Shi if (!hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
hci_cc_le_read_buffer_size_v2(struct hci_dev * hdev,void * data,struct sk_buff * skb)3755deee93d1STetsuo Handa queue_delayed_work(hdev->workqueue, &hdev->ncmd_timer,
3756de75cd0dSManish Mandlik HCI_NCMD_TIMEOUT);
3757de75cd0dSManish Mandlik }
3758de75cd0dSManish Mandlik }
3759deee93d1STetsuo Handa rcu_read_unlock();
3760de75cd0dSManish Mandlik }
3761de75cd0dSManish Mandlik
376226afbd82SLuiz Augusto von Dentz static u8 hci_cc_le_read_buffer_size_v2(struct hci_dev *hdev, void *data,
376326afbd82SLuiz Augusto von Dentz struct sk_buff *skb)
376426afbd82SLuiz Augusto von Dentz {
376526afbd82SLuiz Augusto von Dentz struct hci_rp_le_read_buffer_size_v2 *rp = data;
376626afbd82SLuiz Augusto von Dentz
376726afbd82SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
376826afbd82SLuiz Augusto von Dentz
376926afbd82SLuiz Augusto von Dentz if (rp->status)
377026afbd82SLuiz Augusto von Dentz return rp->status;
377126afbd82SLuiz Augusto von Dentz
377226afbd82SLuiz Augusto von Dentz hdev->le_mtu = __le16_to_cpu(rp->acl_mtu);
377326afbd82SLuiz Augusto von Dentz hdev->le_pkts = rp->acl_max_pkt;
377426afbd82SLuiz Augusto von Dentz hdev->iso_mtu = __le16_to_cpu(rp->iso_mtu);
377526afbd82SLuiz Augusto von Dentz hdev->iso_pkts = rp->iso_max_pkt;
377626afbd82SLuiz Augusto von Dentz
377726afbd82SLuiz Augusto von Dentz hdev->le_cnt = hdev->le_pkts;
377826afbd82SLuiz Augusto von Dentz hdev->iso_cnt = hdev->iso_pkts;
377926afbd82SLuiz Augusto von Dentz
378026afbd82SLuiz Augusto von Dentz BT_DBG("%s acl mtu %d:%d iso mtu %d:%d", hdev->name, hdev->acl_mtu,
378126afbd82SLuiz Augusto von Dentz hdev->acl_pkts, hdev->iso_mtu, hdev->iso_pkts);
hci_unbound_cis_failed(struct hci_dev * hdev,u8 cig,u8 status)378226afbd82SLuiz Augusto von Dentz
3783ad3f7986SSungwoo Kim if (hdev->le_mtu && hdev->le_mtu < HCI_MIN_LE_MTU)
3784ad3f7986SSungwoo Kim return HCI_ERROR_INVALID_PARAMETERS;
3785ad3f7986SSungwoo Kim
378626afbd82SLuiz Augusto von Dentz return rp->status;
378726afbd82SLuiz Augusto von Dentz }
378826afbd82SLuiz Augusto von Dentz
378966dee215SPauli Virtanen static void hci_unbound_cis_failed(struct hci_dev *hdev, u8 cig, u8 status)
379066dee215SPauli Virtanen {
379166dee215SPauli Virtanen struct hci_conn *conn, *tmp;
379266dee215SPauli Virtanen
379366dee215SPauli Virtanen lockdep_assert_held(&hdev->lock);
379466dee215SPauli Virtanen
379566dee215SPauli Virtanen list_for_each_entry_safe(conn, tmp, &hdev->conn_hash.list, list) {
379666dee215SPauli Virtanen if (conn->type != ISO_LINK || !bacmp(&conn->dst, BDADDR_ANY) ||
379766dee215SPauli Virtanen conn->state == BT_OPEN || conn->iso_qos.ucast.cig != cig)
hci_cc_le_set_cig_params(struct hci_dev * hdev,void * data,struct sk_buff * skb)379866dee215SPauli Virtanen continue;
379966dee215SPauli Virtanen
380066dee215SPauli Virtanen if (HCI_CONN_HANDLE_UNSET(conn->handle))
380166dee215SPauli Virtanen hci_conn_failed(conn, status);
380266dee215SPauli Virtanen }
380366dee215SPauli Virtanen }
380466dee215SPauli Virtanen
380526afbd82SLuiz Augusto von Dentz static u8 hci_cc_le_set_cig_params(struct hci_dev *hdev, void *data,
380626afbd82SLuiz Augusto von Dentz struct sk_buff *skb)
380726afbd82SLuiz Augusto von Dentz {
380826afbd82SLuiz Augusto von Dentz struct hci_rp_le_set_cig_params *rp = data;
380971e95884SPauli Virtanen struct hci_cp_le_set_cig_params *cp;
381026afbd82SLuiz Augusto von Dentz struct hci_conn *conn;
381171e95884SPauli Virtanen u8 status = rp->status;
38127f74563eSPauli Virtanen bool pending = false;
381371e95884SPauli Virtanen int i;
381426afbd82SLuiz Augusto von Dentz
381526afbd82SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
381626afbd82SLuiz Augusto von Dentz
381771e95884SPauli Virtanen cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_CIG_PARAMS);
3818db9cbcadSPauli Virtanen if (!rp->status && (!cp || rp->num_handles != cp->num_cis ||
3819db9cbcadSPauli Virtanen rp->cig_id != cp->cig_id)) {
382071e95884SPauli Virtanen bt_dev_err(hdev, "unexpected Set CIG Parameters response data");
382171e95884SPauli Virtanen status = HCI_ERROR_UNSPECIFIED;
382271e95884SPauli Virtanen }
382371e95884SPauli Virtanen
382426afbd82SLuiz Augusto von Dentz hci_dev_lock(hdev);
382526afbd82SLuiz Augusto von Dentz
382666dee215SPauli Virtanen /* BLUETOOTH CORE SPECIFICATION Version 5.4 | Vol 4, Part E page 2554
382766dee215SPauli Virtanen *
382866dee215SPauli Virtanen * If the Status return parameter is non-zero, then the state of the CIG
382966dee215SPauli Virtanen * and its CIS configurations shall not be changed by the command. If
383066dee215SPauli Virtanen * the CIG did not already exist, it shall not be created.
383166dee215SPauli Virtanen */
383271e95884SPauli Virtanen if (status) {
383366dee215SPauli Virtanen /* Keep current configuration, fail only the unbound CIS */
383466dee215SPauli Virtanen hci_unbound_cis_failed(hdev, rp->cig_id, status);
383526afbd82SLuiz Augusto von Dentz goto unlock;
383626afbd82SLuiz Augusto von Dentz }
383726afbd82SLuiz Augusto von Dentz
383871e95884SPauli Virtanen /* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E page 2553
383971e95884SPauli Virtanen *
384071e95884SPauli Virtanen * If the Status return parameter is zero, then the Controller shall
384171e95884SPauli Virtanen * set the Connection_Handle arrayed return parameter to the connection
384271e95884SPauli Virtanen * handle(s) corresponding to the CIS configurations specified in
384371e95884SPauli Virtanen * the CIS_IDs command parameter, in the same order.
384471e95884SPauli Virtanen */
384571e95884SPauli Virtanen for (i = 0; i < rp->num_handles; ++i) {
384671e95884SPauli Virtanen conn = hci_conn_hash_lookup_cis(hdev, NULL, 0, rp->cig_id,
384771e95884SPauli Virtanen cp->cis[i].cis_id);
384871e95884SPauli Virtanen if (!conn || !bacmp(&conn->dst, BDADDR_ANY))
384926afbd82SLuiz Augusto von Dentz continue;
385026afbd82SLuiz Augusto von Dentz
385171e95884SPauli Virtanen if (conn->state != BT_BOUND && conn->state != BT_CONNECT)
385271e95884SPauli Virtanen continue;
385371e95884SPauli Virtanen
385416e3b642SLuiz Augusto von Dentz if (hci_conn_set_handle(conn, __le16_to_cpu(rp->handle[i])))
385516e3b642SLuiz Augusto von Dentz continue;
385626afbd82SLuiz Augusto von Dentz
38577f74563eSPauli Virtanen if (conn->state == BT_CONNECT)
38587f74563eSPauli Virtanen pending = true;
3859e9d50f76SLuiz Augusto von Dentz }
386026afbd82SLuiz Augusto von Dentz
386126afbd82SLuiz Augusto von Dentz unlock:
38627f74563eSPauli Virtanen if (pending)
hci_cc_le_setup_iso_path(struct hci_dev * hdev,void * data,struct sk_buff * skb)38637f74563eSPauli Virtanen hci_le_create_cis_pending(hdev);
38647f74563eSPauli Virtanen
386526afbd82SLuiz Augusto von Dentz hci_dev_unlock(hdev);
386626afbd82SLuiz Augusto von Dentz
386726afbd82SLuiz Augusto von Dentz return rp->status;
386826afbd82SLuiz Augusto von Dentz }
386926afbd82SLuiz Augusto von Dentz
387026afbd82SLuiz Augusto von Dentz static u8 hci_cc_le_setup_iso_path(struct hci_dev *hdev, void *data,
387126afbd82SLuiz Augusto von Dentz struct sk_buff *skb)
387226afbd82SLuiz Augusto von Dentz {
387326afbd82SLuiz Augusto von Dentz struct hci_rp_le_setup_iso_path *rp = data;
387426afbd82SLuiz Augusto von Dentz struct hci_cp_le_setup_iso_path *cp;
387526afbd82SLuiz Augusto von Dentz struct hci_conn *conn;
387626afbd82SLuiz Augusto von Dentz
387726afbd82SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
387826afbd82SLuiz Augusto von Dentz
387926afbd82SLuiz Augusto von Dentz cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SETUP_ISO_PATH);
388026afbd82SLuiz Augusto von Dentz if (!cp)
388126afbd82SLuiz Augusto von Dentz return rp->status;
388226afbd82SLuiz Augusto von Dentz
388326afbd82SLuiz Augusto von Dentz hci_dev_lock(hdev);
388426afbd82SLuiz Augusto von Dentz
388526afbd82SLuiz Augusto von Dentz conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
388626afbd82SLuiz Augusto von Dentz if (!conn)
388726afbd82SLuiz Augusto von Dentz goto unlock;
388826afbd82SLuiz Augusto von Dentz
388926afbd82SLuiz Augusto von Dentz if (rp->status) {
389026afbd82SLuiz Augusto von Dentz hci_connect_cfm(conn, rp->status);
389126afbd82SLuiz Augusto von Dentz hci_conn_del(conn);
389226afbd82SLuiz Augusto von Dentz goto unlock;
389326afbd82SLuiz Augusto von Dentz }
389426afbd82SLuiz Augusto von Dentz
389526afbd82SLuiz Augusto von Dentz switch (cp->direction) {
389626afbd82SLuiz Augusto von Dentz /* Input (Host to Controller) */
389726afbd82SLuiz Augusto von Dentz case 0x00:
389826afbd82SLuiz Augusto von Dentz /* Only confirm connection if output only */
38990fe8c8d0SIulia Tanasescu if (conn->iso_qos.ucast.out.sdu && !conn->iso_qos.ucast.in.sdu)
390026afbd82SLuiz Augusto von Dentz hci_connect_cfm(conn, rp->status);
390126afbd82SLuiz Augusto von Dentz break;
390226afbd82SLuiz Augusto von Dentz /* Output (Controller to Host) */
390326afbd82SLuiz Augusto von Dentz case 0x01:
390426afbd82SLuiz Augusto von Dentz /* Confirm connection since conn->iso_qos is always configured
390526afbd82SLuiz Augusto von Dentz * last.
390626afbd82SLuiz Augusto von Dentz */
390726afbd82SLuiz Augusto von Dentz hci_connect_cfm(conn, rp->status);
39080b3df53cSLuiz Augusto von Dentz
39090b3df53cSLuiz Augusto von Dentz /* Notify device connected in case it is a BIG Sync */
39100b3df53cSLuiz Augusto von Dentz if (!rp->status && test_bit(HCI_CONN_BIG_SYNC, &conn->flags))
39110b3df53cSLuiz Augusto von Dentz mgmt_device_connected(hdev, conn, NULL, 0);
39120b3df53cSLuiz Augusto von Dentz
391326afbd82SLuiz Augusto von Dentz break;
hci_cs_le_create_big(struct hci_dev * hdev,u8 status)391426afbd82SLuiz Augusto von Dentz }
391526afbd82SLuiz Augusto von Dentz
391626afbd82SLuiz Augusto von Dentz unlock:
391726afbd82SLuiz Augusto von Dentz hci_dev_unlock(hdev);
391826afbd82SLuiz Augusto von Dentz return rp->status;
hci_cc_set_per_adv_param(struct hci_dev * hdev,void * data,struct sk_buff * skb)391926afbd82SLuiz Augusto von Dentz }
392026afbd82SLuiz Augusto von Dentz
3921eca0ae4aSLuiz Augusto von Dentz static void hci_cs_le_create_big(struct hci_dev *hdev, u8 status)
3922eca0ae4aSLuiz Augusto von Dentz {
3923eca0ae4aSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status);
3924eca0ae4aSLuiz Augusto von Dentz }
3925eca0ae4aSLuiz Augusto von Dentz
3926eca0ae4aSLuiz Augusto von Dentz static u8 hci_cc_set_per_adv_param(struct hci_dev *hdev, void *data,
3927eca0ae4aSLuiz Augusto von Dentz struct sk_buff *skb)
3928eca0ae4aSLuiz Augusto von Dentz {
3929eca0ae4aSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
3930eca0ae4aSLuiz Augusto von Dentz struct hci_cp_le_set_per_adv_params *cp;
3931eca0ae4aSLuiz Augusto von Dentz
3932eca0ae4aSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
3933eca0ae4aSLuiz Augusto von Dentz
3934eca0ae4aSLuiz Augusto von Dentz if (rp->status)
3935eca0ae4aSLuiz Augusto von Dentz return rp->status;
3936eca0ae4aSLuiz Augusto von Dentz
3937eca0ae4aSLuiz Augusto von Dentz cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_PER_ADV_PARAMS);
hci_cc_le_set_per_adv_enable(struct hci_dev * hdev,void * data,struct sk_buff * skb)3938eca0ae4aSLuiz Augusto von Dentz if (!cp)
3939eca0ae4aSLuiz Augusto von Dentz return rp->status;
3940eca0ae4aSLuiz Augusto von Dentz
3941eca0ae4aSLuiz Augusto von Dentz /* TODO: set the conn state */
3942eca0ae4aSLuiz Augusto von Dentz return rp->status;
3943eca0ae4aSLuiz Augusto von Dentz }
3944eca0ae4aSLuiz Augusto von Dentz
3945eca0ae4aSLuiz Augusto von Dentz static u8 hci_cc_le_set_per_adv_enable(struct hci_dev *hdev, void *data,
3946eca0ae4aSLuiz Augusto von Dentz struct sk_buff *skb)
3947eca0ae4aSLuiz Augusto von Dentz {
3948eca0ae4aSLuiz Augusto von Dentz struct hci_ev_status *rp = data;
39496a42e9bfSIulia Tanasescu struct hci_cp_le_set_per_adv_enable *cp;
39506a42e9bfSIulia Tanasescu struct adv_info *adv = NULL, *n;
39516a42e9bfSIulia Tanasescu u8 per_adv_cnt = 0;
3952eca0ae4aSLuiz Augusto von Dentz
3953eca0ae4aSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
3954eca0ae4aSLuiz Augusto von Dentz
3955eca0ae4aSLuiz Augusto von Dentz if (rp->status)
3956eca0ae4aSLuiz Augusto von Dentz return rp->status;
3957eca0ae4aSLuiz Augusto von Dentz
39586a42e9bfSIulia Tanasescu cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_PER_ADV_ENABLE);
39596a42e9bfSIulia Tanasescu if (!cp)
3960eca0ae4aSLuiz Augusto von Dentz return rp->status;
3961eca0ae4aSLuiz Augusto von Dentz
3962eca0ae4aSLuiz Augusto von Dentz hci_dev_lock(hdev);
3963eca0ae4aSLuiz Augusto von Dentz
39646a42e9bfSIulia Tanasescu adv = hci_find_adv_instance(hdev, cp->handle);
3965eca0ae4aSLuiz Augusto von Dentz
39666a42e9bfSIulia Tanasescu if (cp->enable) {
39676a42e9bfSIulia Tanasescu hci_dev_set_flag(hdev, HCI_LE_PER_ADV);
39686a42e9bfSIulia Tanasescu
39696a42e9bfSIulia Tanasescu if (adv)
39706a42e9bfSIulia Tanasescu adv->enabled = true;
39716a42e9bfSIulia Tanasescu } else {
39726a42e9bfSIulia Tanasescu /* If just one instance was disabled check if there are
39736a42e9bfSIulia Tanasescu * any other instance enabled before clearing HCI_LE_PER_ADV.
39746a42e9bfSIulia Tanasescu * The current periodic adv instance will be marked as
39756a42e9bfSIulia Tanasescu * disabled once extended advertising is also disabled.
39766a42e9bfSIulia Tanasescu */
39776a42e9bfSIulia Tanasescu list_for_each_entry_safe(adv, n, &hdev->adv_instances,
39786a42e9bfSIulia Tanasescu list) {
39796a42e9bfSIulia Tanasescu if (adv->periodic && adv->enabled)
39806a42e9bfSIulia Tanasescu per_adv_cnt++;
39816a42e9bfSIulia Tanasescu }
39826a42e9bfSIulia Tanasescu
39836a42e9bfSIulia Tanasescu if (per_adv_cnt > 1)
39846a42e9bfSIulia Tanasescu goto unlock;
39856a42e9bfSIulia Tanasescu
39866a42e9bfSIulia Tanasescu hci_dev_clear_flag(hdev, HCI_LE_PER_ADV);
39876a42e9bfSIulia Tanasescu }
39886a42e9bfSIulia Tanasescu
39896a42e9bfSIulia Tanasescu unlock:
3990eca0ae4aSLuiz Augusto von Dentz hci_dev_unlock(hdev);
3991eca0ae4aSLuiz Augusto von Dentz
3992eca0ae4aSLuiz Augusto von Dentz return rp->status;
3993eca0ae4aSLuiz Augusto von Dentz }
3994eca0ae4aSLuiz Augusto von Dentz
3995c8992cffSLuiz Augusto von Dentz #define HCI_CC_VL(_op, _func, _min, _max) \
3996c8992cffSLuiz Augusto von Dentz { \
3997c8992cffSLuiz Augusto von Dentz .op = _op, \
3998c8992cffSLuiz Augusto von Dentz .func = _func, \
3999c8992cffSLuiz Augusto von Dentz .min_len = _min, \
4000c8992cffSLuiz Augusto von Dentz .max_len = _max, \
4001c8992cffSLuiz Augusto von Dentz }
4002c8992cffSLuiz Augusto von Dentz
4003c8992cffSLuiz Augusto von Dentz #define HCI_CC(_op, _func, _len) \
4004c8992cffSLuiz Augusto von Dentz HCI_CC_VL(_op, _func, _len, _len)
4005c8992cffSLuiz Augusto von Dentz
4006c8992cffSLuiz Augusto von Dentz #define HCI_CC_STATUS(_op, _func) \
4007c8992cffSLuiz Augusto von Dentz HCI_CC(_op, _func, sizeof(struct hci_ev_status))
4008c8992cffSLuiz Augusto von Dentz
4009c8992cffSLuiz Augusto von Dentz static const struct hci_cc {
4010c8992cffSLuiz Augusto von Dentz u16 op;
4011c8992cffSLuiz Augusto von Dentz u8 (*func)(struct hci_dev *hdev, void *data, struct sk_buff *skb);
4012c8992cffSLuiz Augusto von Dentz u16 min_len;
4013c8992cffSLuiz Augusto von Dentz u16 max_len;
4014c8992cffSLuiz Augusto von Dentz } hci_cc_table[] = {
4015c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_INQUIRY_CANCEL, hci_cc_inquiry_cancel),
4016c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_PERIODIC_INQ, hci_cc_periodic_inq),
4017c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_EXIT_PERIODIC_INQ, hci_cc_exit_periodic_inq),
4018c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_REMOTE_NAME_REQ_CANCEL,
4019c8992cffSLuiz Augusto von Dentz hci_cc_remote_name_req_cancel),
4020c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_ROLE_DISCOVERY, hci_cc_role_discovery,
4021c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_role_discovery)),
4022c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_LINK_POLICY, hci_cc_read_link_policy,
4023c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_link_policy)),
4024c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_WRITE_LINK_POLICY, hci_cc_write_link_policy,
4025c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_write_link_policy)),
4026c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_DEF_LINK_POLICY, hci_cc_read_def_link_policy,
4027c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_def_link_policy)),
4028c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_DEF_LINK_POLICY,
4029c8992cffSLuiz Augusto von Dentz hci_cc_write_def_link_policy),
4030c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_RESET, hci_cc_reset),
4031c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_STORED_LINK_KEY, hci_cc_read_stored_link_key,
4032c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_stored_link_key)),
4033c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_DELETE_STORED_LINK_KEY, hci_cc_delete_stored_link_key,
4034c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_delete_stored_link_key)),
4035c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_LOCAL_NAME, hci_cc_write_local_name),
4036c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_LOCAL_NAME, hci_cc_read_local_name,
4037c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_local_name)),
4038c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_AUTH_ENABLE, hci_cc_write_auth_enable),
4039c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_ENCRYPT_MODE, hci_cc_write_encrypt_mode),
4040c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_SCAN_ENABLE, hci_cc_write_scan_enable),
4041c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_SET_EVENT_FLT, hci_cc_set_event_filter),
4042c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_CLASS_OF_DEV, hci_cc_read_class_of_dev,
4043c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_class_of_dev)),
4044c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_CLASS_OF_DEV, hci_cc_write_class_of_dev),
4045c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_VOICE_SETTING, hci_cc_read_voice_setting,
4046c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_voice_setting)),
4047c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_VOICE_SETTING, hci_cc_write_voice_setting),
4048c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_NUM_SUPPORTED_IAC, hci_cc_read_num_supported_iac,
4049c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_num_supported_iac)),
4050c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_SSP_MODE, hci_cc_write_ssp_mode),
4051c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_SC_SUPPORT, hci_cc_write_sc_support),
4052c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_AUTH_PAYLOAD_TO, hci_cc_read_auth_payload_timeout,
4053c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_auth_payload_to)),
4054c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_WRITE_AUTH_PAYLOAD_TO, hci_cc_write_auth_payload_timeout,
4055c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_write_auth_payload_to)),
4056c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_LOCAL_VERSION, hci_cc_read_local_version,
4057c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_local_version)),
4058c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_LOCAL_COMMANDS, hci_cc_read_local_commands,
4059c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_local_commands)),
4060c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_LOCAL_FEATURES, hci_cc_read_local_features,
4061c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_local_features)),
4062c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_LOCAL_EXT_FEATURES, hci_cc_read_local_ext_features,
4063c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_local_ext_features)),
4064c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_BUFFER_SIZE, hci_cc_read_buffer_size,
4065c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_buffer_size)),
4066c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_BD_ADDR, hci_cc_read_bd_addr,
4067c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_bd_addr)),
4068c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_LOCAL_PAIRING_OPTS, hci_cc_read_local_pairing_opts,
4069c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_local_pairing_opts)),
4070c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_PAGE_SCAN_ACTIVITY, hci_cc_read_page_scan_activity,
4071c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_page_scan_activity)),
4072c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_PAGE_SCAN_ACTIVITY,
4073c8992cffSLuiz Augusto von Dentz hci_cc_write_page_scan_activity),
4074c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_PAGE_SCAN_TYPE, hci_cc_read_page_scan_type,
4075c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_page_scan_type)),
4076c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_PAGE_SCAN_TYPE, hci_cc_write_page_scan_type),
4077c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_CLOCK, hci_cc_read_clock,
4078c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_clock)),
4079278d933eSBrian Gix HCI_CC(HCI_OP_READ_ENC_KEY_SIZE, hci_cc_read_enc_key_size,
4080278d933eSBrian Gix sizeof(struct hci_rp_read_enc_key_size)),
4081c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_INQ_RSP_TX_POWER, hci_cc_read_inq_rsp_tx_power,
4082c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_inq_rsp_tx_power)),
4083c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_DEF_ERR_DATA_REPORTING,
4084c8992cffSLuiz Augusto von Dentz hci_cc_read_def_err_data_reporting,
4085c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_def_err_data_reporting)),
4086c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_DEF_ERR_DATA_REPORTING,
4087c8992cffSLuiz Augusto von Dentz hci_cc_write_def_err_data_reporting),
4088c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_PIN_CODE_REPLY, hci_cc_pin_code_reply,
4089c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_pin_code_reply)),
4090c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_PIN_CODE_NEG_REPLY, hci_cc_pin_code_neg_reply,
4091c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_pin_code_neg_reply)),
4092c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_LOCAL_OOB_DATA, hci_cc_read_local_oob_data,
4093c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_local_oob_data)),
4094c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_LOCAL_OOB_EXT_DATA, hci_cc_read_local_oob_ext_data,
4095c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_local_oob_ext_data)),
4096c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_BUFFER_SIZE, hci_cc_le_read_buffer_size,
4097c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_buffer_size)),
4098c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_LOCAL_FEATURES, hci_cc_le_read_local_features,
4099c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_local_features)),
4100c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_ADV_TX_POWER, hci_cc_le_read_adv_tx_power,
4101c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_adv_tx_power)),
4102c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_USER_CONFIRM_REPLY, hci_cc_user_confirm_reply,
4103c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_user_confirm_reply)),
4104c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_USER_CONFIRM_NEG_REPLY, hci_cc_user_confirm_neg_reply,
4105c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_user_confirm_reply)),
4106c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_USER_PASSKEY_REPLY, hci_cc_user_passkey_reply,
4107c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_user_confirm_reply)),
4108c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_USER_PASSKEY_NEG_REPLY, hci_cc_user_passkey_neg_reply,
4109c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_user_confirm_reply)),
4110c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_RANDOM_ADDR, hci_cc_le_set_random_addr),
4111c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_ADV_ENABLE, hci_cc_le_set_adv_enable),
4112c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_SCAN_PARAM, hci_cc_le_set_scan_param),
4113c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_SCAN_ENABLE, hci_cc_le_set_scan_enable),
4114c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_ACCEPT_LIST_SIZE,
4115c8992cffSLuiz Augusto von Dentz hci_cc_le_read_accept_list_size,
4116c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_accept_list_size)),
4117c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_CLEAR_ACCEPT_LIST, hci_cc_le_clear_accept_list),
4118c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_ADD_TO_ACCEPT_LIST,
4119c8992cffSLuiz Augusto von Dentz hci_cc_le_add_to_accept_list),
4120c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_DEL_FROM_ACCEPT_LIST,
4121c8992cffSLuiz Augusto von Dentz hci_cc_le_del_from_accept_list),
4122c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_SUPPORTED_STATES, hci_cc_le_read_supported_states,
4123c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_supported_states)),
4124c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_DEF_DATA_LEN, hci_cc_le_read_def_data_len,
4125c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_def_data_len)),
4126c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_WRITE_DEF_DATA_LEN,
4127c8992cffSLuiz Augusto von Dentz hci_cc_le_write_def_data_len),
4128c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_ADD_TO_RESOLV_LIST,
4129c8992cffSLuiz Augusto von Dentz hci_cc_le_add_to_resolv_list),
4130c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_DEL_FROM_RESOLV_LIST,
4131c8992cffSLuiz Augusto von Dentz hci_cc_le_del_from_resolv_list),
4132c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_CLEAR_RESOLV_LIST,
4133c8992cffSLuiz Augusto von Dentz hci_cc_le_clear_resolv_list),
4134c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_RESOLV_LIST_SIZE, hci_cc_le_read_resolv_list_size,
4135c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_resolv_list_size)),
4136c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_ADDR_RESOLV_ENABLE,
4137c8992cffSLuiz Augusto von Dentz hci_cc_le_set_addr_resolution_enable),
4138c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_MAX_DATA_LEN, hci_cc_le_read_max_data_len,
4139c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_max_data_len)),
4140c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_LE_HOST_SUPPORTED,
4141c8992cffSLuiz Augusto von Dentz hci_cc_write_le_host_supported),
4142c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_ADV_PARAM, hci_cc_set_adv_param),
4143c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_RSSI, hci_cc_read_rssi,
4144c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_rssi)),
4145c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_READ_TX_POWER, hci_cc_read_tx_power,
4146c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_read_tx_power)),
4147c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_WRITE_SSP_DEBUG_MODE, hci_cc_write_ssp_debug_mode),
4148c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_EXT_SCAN_PARAMS,
4149c8992cffSLuiz Augusto von Dentz hci_cc_le_set_ext_scan_param),
4150c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_EXT_SCAN_ENABLE,
4151c8992cffSLuiz Augusto von Dentz hci_cc_le_set_ext_scan_enable),
4152c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_DEFAULT_PHY, hci_cc_le_set_default_phy),
4153c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_NUM_SUPPORTED_ADV_SETS,
4154c8992cffSLuiz Augusto von Dentz hci_cc_le_read_num_adv_sets,
4155c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_num_supported_adv_sets)),
4156c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_SET_EXT_ADV_PARAMS, hci_cc_set_ext_adv_param,
4157c8992cffSLuiz Augusto von Dentz sizeof(struct hci_rp_le_set_ext_adv_params)),
4158c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_EXT_ADV_ENABLE,
4159c8992cffSLuiz Augusto von Dentz hci_cc_le_set_ext_adv_enable),
4160c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_ADV_SET_RAND_ADDR,
4161c8992cffSLuiz Augusto von Dentz hci_cc_le_set_adv_set_random_addr),
4162c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_REMOVE_ADV_SET, hci_cc_le_remove_adv_set),
4163c8992cffSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_CLEAR_ADV_SETS, hci_cc_le_clear_adv_sets),
4164eca0ae4aSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_PER_ADV_PARAMS, hci_cc_set_per_adv_param),
4165eca0ae4aSLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_PER_ADV_ENABLE,
4166eca0ae4aSLuiz Augusto von Dentz hci_cc_le_set_per_adv_enable),
4167c8992cffSLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_TRANSMIT_POWER, hci_cc_le_read_transmit_power,
4168853b70b5SLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_transmit_power)),
416926afbd82SLuiz Augusto von Dentz HCI_CC_STATUS(HCI_OP_LE_SET_PRIVACY_MODE, hci_cc_le_set_privacy_mode),
417026afbd82SLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_READ_BUFFER_SIZE_V2, hci_cc_le_read_buffer_size_v2,
hci_cc_func(struct hci_dev * hdev,const struct hci_cc * cc,struct sk_buff * skb)417126afbd82SLuiz Augusto von Dentz sizeof(struct hci_rp_le_read_buffer_size_v2)),
417226afbd82SLuiz Augusto von Dentz HCI_CC_VL(HCI_OP_LE_SET_CIG_PARAMS, hci_cc_le_set_cig_params,
417326afbd82SLuiz Augusto von Dentz sizeof(struct hci_rp_le_set_cig_params), HCI_MAX_EVENT_SIZE),
417426afbd82SLuiz Augusto von Dentz HCI_CC(HCI_OP_LE_SETUP_ISO_PATH, hci_cc_le_setup_iso_path,
417526afbd82SLuiz Augusto von Dentz sizeof(struct hci_rp_le_setup_iso_path)),
4176c8992cffSLuiz Augusto von Dentz };
4177c8992cffSLuiz Augusto von Dentz
4178c8992cffSLuiz Augusto von Dentz static u8 hci_cc_func(struct hci_dev *hdev, const struct hci_cc *cc,
4179c8992cffSLuiz Augusto von Dentz struct sk_buff *skb)
4180c8992cffSLuiz Augusto von Dentz {
4181c8992cffSLuiz Augusto von Dentz void *data;
4182c8992cffSLuiz Augusto von Dentz
4183c8992cffSLuiz Augusto von Dentz if (skb->len < cc->min_len) {
4184c8992cffSLuiz Augusto von Dentz bt_dev_err(hdev, "unexpected cc 0x%4.4x length: %u < %u",
4185c8992cffSLuiz Augusto von Dentz cc->op, skb->len, cc->min_len);
4186c8992cffSLuiz Augusto von Dentz return HCI_ERROR_UNSPECIFIED;
4187c8992cffSLuiz Augusto von Dentz }
4188c8992cffSLuiz Augusto von Dentz
4189c8992cffSLuiz Augusto von Dentz /* Just warn if the length is over max_len size it still be possible to
4190c8992cffSLuiz Augusto von Dentz * partially parse the cc so leave to callback to decide if that is
4191c8992cffSLuiz Augusto von Dentz * acceptable.
4192c8992cffSLuiz Augusto von Dentz */
4193c8992cffSLuiz Augusto von Dentz if (skb->len > cc->max_len)
4194c8992cffSLuiz Augusto von Dentz bt_dev_warn(hdev, "unexpected cc 0x%4.4x length: %u > %u",
4195c8992cffSLuiz Augusto von Dentz cc->op, skb->len, cc->max_len);
4196c8992cffSLuiz Augusto von Dentz
hci_cmd_complete_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb,u16 * opcode,u8 * status,hci_req_complete_t * req_complete,hci_req_complete_skb_t * req_complete_skb)4197c8992cffSLuiz Augusto von Dentz data = hci_cc_skb_pull(hdev, skb, cc->op, cc->min_len);
4198c8992cffSLuiz Augusto von Dentz if (!data)
4199c8992cffSLuiz Augusto von Dentz return HCI_ERROR_UNSPECIFIED;
4200c8992cffSLuiz Augusto von Dentz
4201c8992cffSLuiz Augusto von Dentz return cc->func(hdev, data, skb);
4202c8992cffSLuiz Augusto von Dentz }
4203c8992cffSLuiz Augusto von Dentz
42043e54c589SLuiz Augusto von Dentz static void hci_cmd_complete_evt(struct hci_dev *hdev, void *data,
42053e54c589SLuiz Augusto von Dentz struct sk_buff *skb, u16 *opcode, u8 *status,
4206e6214487SJohan Hedberg hci_req_complete_t *req_complete,
4207e6214487SJohan Hedberg hci_req_complete_skb_t *req_complete_skb)
4208a9de9248SMarcel Holtmann {
42093e54c589SLuiz Augusto von Dentz struct hci_ev_cmd_complete *ev = data;
4210c8992cffSLuiz Augusto von Dentz int i;
4211e6214487SJohan Hedberg
4212e6214487SJohan Hedberg *opcode = __le16_to_cpu(ev->opcode);
4213a9de9248SMarcel Holtmann
4214c8992cffSLuiz Augusto von Dentz bt_dev_dbg(hdev, "opcode 0x%4.4x", *opcode);
4215a9de9248SMarcel Holtmann
4216c8992cffSLuiz Augusto von Dentz for (i = 0; i < ARRAY_SIZE(hci_cc_table); i++) {
4217c8992cffSLuiz Augusto von Dentz if (hci_cc_table[i].op == *opcode) {
4218c8992cffSLuiz Augusto von Dentz *status = hci_cc_func(hdev, &hci_cc_table[i], skb);
42194d93483bSAndre Guedes break;
4220c8992cffSLuiz Augusto von Dentz }
4221a9de9248SMarcel Holtmann }
4222a9de9248SMarcel Holtmann
4223afcb3369SHans de Goede if (i == ARRAY_SIZE(hci_cc_table)) {
4224afcb3369SHans de Goede /* Unknown opcode, assume byte 0 contains the status, so
4225afcb3369SHans de Goede * that e.g. __hci_cmd_sync() properly returns errors
4226afcb3369SHans de Goede * for vendor specific commands send by HCI drivers.
4227afcb3369SHans de Goede * If a vendor doesn't actually follow this convention we may
4228afcb3369SHans de Goede * need to introduce a vendor CC table in order to properly set
4229afcb3369SHans de Goede * the status.
4230afcb3369SHans de Goede */
4231afcb3369SHans de Goede *status = skb->data[0];
4232afcb3369SHans de Goede }
4233afcb3369SHans de Goede
4234ecb71f25SKiran K handle_cmd_cnt_and_timer(hdev, ev->ncmd);
4235600b2150SJohan Hedberg
4236e6214487SJohan Hedberg hci_req_cmd_complete(hdev, *opcode, *status, req_complete,
4237e6214487SJohan Hedberg req_complete_skb);
42389238f36aSJohan Hedberg
4239f80c5dadSJoão Paulo Rechi Vita if (hci_dev_test_flag(hdev, HCI_CMD_PENDING)) {
4240f80c5dadSJoão Paulo Rechi Vita bt_dev_err(hdev,
4241f80c5dadSJoão Paulo Rechi Vita "unexpected event for opcode 0x%4.4x", *opcode);
hci_cs_le_create_cis(struct hci_dev * hdev,u8 status)4242f80c5dadSJoão Paulo Rechi Vita return;
4243f80c5dadSJoão Paulo Rechi Vita }
4244f80c5dadSJoão Paulo Rechi Vita
4245600b2150SJohan Hedberg if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q))
4246c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work);
4247a9de9248SMarcel Holtmann }
4248a9de9248SMarcel Holtmann
424926afbd82SLuiz Augusto von Dentz static void hci_cs_le_create_cis(struct hci_dev *hdev, u8 status)
425026afbd82SLuiz Augusto von Dentz {
425126afbd82SLuiz Augusto von Dentz struct hci_cp_le_create_cis *cp;
42527f74563eSPauli Virtanen bool pending = false;
425326afbd82SLuiz Augusto von Dentz int i;
425426afbd82SLuiz Augusto von Dentz
425526afbd82SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status);
425626afbd82SLuiz Augusto von Dentz
425726afbd82SLuiz Augusto von Dentz if (!status)
425826afbd82SLuiz Augusto von Dentz return;
425926afbd82SLuiz Augusto von Dentz
426026afbd82SLuiz Augusto von Dentz cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CIS);
426126afbd82SLuiz Augusto von Dentz if (!cp)
426226afbd82SLuiz Augusto von Dentz return;
426326afbd82SLuiz Augusto von Dentz
426426afbd82SLuiz Augusto von Dentz hci_dev_lock(hdev);
426526afbd82SLuiz Augusto von Dentz
426626afbd82SLuiz Augusto von Dentz /* Remove connection if command failed */
426726afbd82SLuiz Augusto von Dentz for (i = 0; cp->num_cis; cp->num_cis--, i++) {
426826afbd82SLuiz Augusto von Dentz struct hci_conn *conn;
426926afbd82SLuiz Augusto von Dentz u16 handle;
427026afbd82SLuiz Augusto von Dentz
427126afbd82SLuiz Augusto von Dentz handle = __le16_to_cpu(cp->cis[i].cis_handle);
427226afbd82SLuiz Augusto von Dentz
427326afbd82SLuiz Augusto von Dentz conn = hci_conn_hash_lookup_handle(hdev, handle);
427426afbd82SLuiz Augusto von Dentz if (conn) {
42757f74563eSPauli Virtanen if (test_and_clear_bit(HCI_CONN_CREATE_CIS,
42767f74563eSPauli Virtanen &conn->flags))
42777f74563eSPauli Virtanen pending = true;
427826afbd82SLuiz Augusto von Dentz conn->state = BT_CLOSED;
427926afbd82SLuiz Augusto von Dentz hci_connect_cfm(conn, status);
428026afbd82SLuiz Augusto von Dentz hci_conn_del(conn);
428126afbd82SLuiz Augusto von Dentz }
428226afbd82SLuiz Augusto von Dentz }
428326afbd82SLuiz Augusto von Dentz
42847f74563eSPauli Virtanen if (pending)
42857f74563eSPauli Virtanen hci_le_create_cis_pending(hdev);
42867f74563eSPauli Virtanen
428726afbd82SLuiz Augusto von Dentz hci_dev_unlock(hdev);
428826afbd82SLuiz Augusto von Dentz }
428926afbd82SLuiz Augusto von Dentz
4290147306ccSLuiz Augusto von Dentz #define HCI_CS(_op, _func) \
4291147306ccSLuiz Augusto von Dentz { \
4292147306ccSLuiz Augusto von Dentz .op = _op, \
4293147306ccSLuiz Augusto von Dentz .func = _func, \
4294147306ccSLuiz Augusto von Dentz }
4295147306ccSLuiz Augusto von Dentz
4296147306ccSLuiz Augusto von Dentz static const struct hci_cs {
4297147306ccSLuiz Augusto von Dentz u16 op;
4298147306ccSLuiz Augusto von Dentz void (*func)(struct hci_dev *hdev, __u8 status);
4299147306ccSLuiz Augusto von Dentz } hci_cs_table[] = {
4300147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_INQUIRY, hci_cs_inquiry),
4301147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_CREATE_CONN, hci_cs_create_conn),
4302147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_DISCONNECT, hci_cs_disconnect),
4303147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_ADD_SCO, hci_cs_add_sco),
4304147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_AUTH_REQUESTED, hci_cs_auth_requested),
4305147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_SET_CONN_ENCRYPT, hci_cs_set_conn_encrypt),
4306147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_REMOTE_NAME_REQ, hci_cs_remote_name_req),
4307147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_READ_REMOTE_FEATURES, hci_cs_read_remote_features),
4308147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_READ_REMOTE_EXT_FEATURES,
4309147306ccSLuiz Augusto von Dentz hci_cs_read_remote_ext_features),
4310147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_SETUP_SYNC_CONN, hci_cs_setup_sync_conn),
4311147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_ENHANCED_SETUP_SYNC_CONN,
4312147306ccSLuiz Augusto von Dentz hci_cs_enhanced_setup_sync_conn),
4313147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_SNIFF_MODE, hci_cs_sniff_mode),
4314147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_EXIT_SNIFF_MODE, hci_cs_exit_sniff_mode),
4315147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_SWITCH_ROLE, hci_cs_switch_role),
4316147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_LE_CREATE_CONN, hci_cs_le_create_conn),
hci_cmd_status_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb,u16 * opcode,u8 * status,hci_req_complete_t * req_complete,hci_req_complete_skb_t * req_complete_skb)4317147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_LE_READ_REMOTE_FEATURES, hci_cs_le_read_remote_features),
4318147306ccSLuiz Augusto von Dentz HCI_CS(HCI_OP_LE_START_ENC, hci_cs_le_start_enc),
431926afbd82SLuiz Augusto von Dentz HCI_CS(HCI_OP_LE_EXT_CREATE_CONN, hci_cs_le_ext_create_conn),
432026afbd82SLuiz Augusto von Dentz HCI_CS(HCI_OP_LE_CREATE_CIS, hci_cs_le_create_cis),
4321eca0ae4aSLuiz Augusto von Dentz HCI_CS(HCI_OP_LE_CREATE_BIG, hci_cs_le_create_big),
4322147306ccSLuiz Augusto von Dentz };
4323147306ccSLuiz Augusto von Dentz
43243e54c589SLuiz Augusto von Dentz static void hci_cmd_status_evt(struct hci_dev *hdev, void *data,
43253e54c589SLuiz Augusto von Dentz struct sk_buff *skb, u16 *opcode, u8 *status,
4326e6214487SJohan Hedberg hci_req_complete_t *req_complete,
4327e6214487SJohan Hedberg hci_req_complete_skb_t *req_complete_skb)
4328a9de9248SMarcel Holtmann {
43293e54c589SLuiz Augusto von Dentz struct hci_ev_cmd_status *ev = data;
4330147306ccSLuiz Augusto von Dentz int i;
4331a9de9248SMarcel Holtmann
4332e6214487SJohan Hedberg *opcode = __le16_to_cpu(ev->opcode);
4333e6214487SJohan Hedberg *status = ev->status;
4334a9de9248SMarcel Holtmann
4335147306ccSLuiz Augusto von Dentz bt_dev_dbg(hdev, "opcode 0x%4.4x", *opcode);
4336a9de9248SMarcel Holtmann
4337147306ccSLuiz Augusto von Dentz for (i = 0; i < ARRAY_SIZE(hci_cs_table); i++) {
4338147306ccSLuiz Augusto von Dentz if (hci_cs_table[i].op == *opcode) {
4339147306ccSLuiz Augusto von Dentz hci_cs_table[i].func(hdev, ev->status);
4340a9de9248SMarcel Holtmann break;
4341147306ccSLuiz Augusto von Dentz }
4342a9de9248SMarcel Holtmann }
4343a9de9248SMarcel Holtmann
4344ecb71f25SKiran K handle_cmd_cnt_and_timer(hdev, ev->ncmd);
4345600b2150SJohan Hedberg
4346444c6dd5SJohan Hedberg /* Indicate request completion if the command failed. Also, if
4347444c6dd5SJohan Hedberg * we're not waiting for a special event and we get a success
4348444c6dd5SJohan Hedberg * command status we should try to flag the request as completed
4349444c6dd5SJohan Hedberg * (since for this kind of commands there will not be a command
4350444c6dd5SJohan Hedberg * complete event).
4351444c6dd5SJohan Hedberg */
43522af7aa66SLuiz Augusto von Dentz if (ev->status || (hdev->req_skb && !hci_skb_event(hdev->req_skb))) {
4353e6214487SJohan Hedberg hci_req_cmd_complete(hdev, *opcode, ev->status, req_complete,
4354e6214487SJohan Hedberg req_complete_skb);
4355f80c5dadSJoão Paulo Rechi Vita if (hci_dev_test_flag(hdev, HCI_CMD_PENDING)) {
435685b56857SLuiz Augusto von Dentz bt_dev_err(hdev, "unexpected event for opcode 0x%4.4x",
435785b56857SLuiz Augusto von Dentz *opcode);
4358f80c5dadSJoão Paulo Rechi Vita return;
hci_hardware_error_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)4359f80c5dadSJoão Paulo Rechi Vita }
436085b56857SLuiz Augusto von Dentz }
4361f80c5dadSJoão Paulo Rechi Vita
4362600b2150SJohan Hedberg if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q))
4363c347b765SGustavo F. Padovan queue_work(hdev->workqueue, &hdev->cmd_work);
4364a9de9248SMarcel Holtmann }
4365a9de9248SMarcel Holtmann
43663e54c589SLuiz Augusto von Dentz static void hci_hardware_error_evt(struct hci_dev *hdev, void *data,
43673e54c589SLuiz Augusto von Dentz struct sk_buff *skb)
436824dfa343SMarcel Holtmann {
43693e54c589SLuiz Augusto von Dentz struct hci_ev_hardware_error *ev = data;
4370ae61a10dSLuiz Augusto von Dentz
hci_role_change_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)43713e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "code 0x%2.2x", ev->code);
437224dfa343SMarcel Holtmann
4373c7741d16SMarcel Holtmann hdev->hw_error_code = ev->code;
4374c7741d16SMarcel Holtmann
4375c7741d16SMarcel Holtmann queue_work(hdev->req_workqueue, &hdev->error_reset);
437624dfa343SMarcel Holtmann }
437724dfa343SMarcel Holtmann
43783e54c589SLuiz Augusto von Dentz static void hci_role_change_evt(struct hci_dev *hdev, void *data,
43793e54c589SLuiz Augusto von Dentz struct sk_buff *skb)
4380a9de9248SMarcel Holtmann {
43813e54c589SLuiz Augusto von Dentz struct hci_ev_role_change *ev = data;
4382a9de9248SMarcel Holtmann struct hci_conn *conn;
4383a9de9248SMarcel Holtmann
43843e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
4385a9de9248SMarcel Holtmann
4386a9de9248SMarcel Holtmann hci_dev_lock(hdev);
4387a9de9248SMarcel Holtmann
4388a9de9248SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
4389a9de9248SMarcel Holtmann if (conn) {
439040bef302SJohan Hedberg if (!ev->status)
439140bef302SJohan Hedberg conn->role = ev->role;
4392a9de9248SMarcel Holtmann
439351a8efd7SJohan Hedberg clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
hci_num_comp_pkts_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)4394a9de9248SMarcel Holtmann
4395a9de9248SMarcel Holtmann hci_role_switch_cfm(conn, ev->status, ev->role);
4396a9de9248SMarcel Holtmann }
4397a9de9248SMarcel Holtmann
4398a9de9248SMarcel Holtmann hci_dev_unlock(hdev);
4399a9de9248SMarcel Holtmann }
4400a9de9248SMarcel Holtmann
44013e54c589SLuiz Augusto von Dentz static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data,
44023e54c589SLuiz Augusto von Dentz struct sk_buff *skb)
44031da177e4SLinus Torvalds {
44043e54c589SLuiz Augusto von Dentz struct hci_ev_num_comp_pkts *ev = data;
44051da177e4SLinus Torvalds int i;
44061da177e4SLinus Torvalds
4407aadc3d2fSLuiz Augusto von Dentz if (!hci_ev_skb_pull(hdev, skb, HCI_EV_NUM_COMP_PKTS,
4408aadc3d2fSLuiz Augusto von Dentz flex_array_size(ev, handles, ev->num)))
4409aadc3d2fSLuiz Augusto von Dentz return;
4410aadc3d2fSLuiz Augusto von Dentz
44113e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "num %d", ev->num);
44121da177e4SLinus Torvalds
4413aadc3d2fSLuiz Augusto von Dentz for (i = 0; i < ev->num; i++) {
4414613a1c0cSAndrei Emeltchenko struct hci_comp_pkts_info *info = &ev->handles[i];
44151da177e4SLinus Torvalds struct hci_conn *conn;
44161da177e4SLinus Torvalds __u16 handle, count;
44171da177e4SLinus Torvalds
4418613a1c0cSAndrei Emeltchenko handle = __le16_to_cpu(info->handle);
4419613a1c0cSAndrei Emeltchenko count = __le16_to_cpu(info->count);
44201da177e4SLinus Torvalds
44211da177e4SLinus Torvalds conn = hci_conn_hash_lookup_handle(hdev, handle);
4422f4280918SAndrei Emeltchenko if (!conn)
4423f4280918SAndrei Emeltchenko continue;
4424f4280918SAndrei Emeltchenko
44251da177e4SLinus Torvalds conn->sent -= count;
44261da177e4SLinus Torvalds
4427f4280918SAndrei Emeltchenko switch (conn->type) {
4428f4280918SAndrei Emeltchenko case ACL_LINK:
442970f23020SAndrei Emeltchenko hdev->acl_cnt += count;
443070f23020SAndrei Emeltchenko if (hdev->acl_cnt > hdev->acl_pkts)
44311da177e4SLinus Torvalds hdev->acl_cnt = hdev->acl_pkts;
4432f4280918SAndrei Emeltchenko break;
4433f4280918SAndrei Emeltchenko
4434f4280918SAndrei Emeltchenko case LE_LINK:
44356ed58ec5SVille Tervo if (hdev->le_pkts) {
44366ed58ec5SVille Tervo hdev->le_cnt += count;
44376ed58ec5SVille Tervo if (hdev->le_cnt > hdev->le_pkts)
44386ed58ec5SVille Tervo hdev->le_cnt = hdev->le_pkts;
44396ed58ec5SVille Tervo } else {
44406ed58ec5SVille Tervo hdev->acl_cnt += count;
44416ed58ec5SVille Tervo if (hdev->acl_cnt > hdev->acl_pkts)
44426ed58ec5SVille Tervo hdev->acl_cnt = hdev->acl_pkts;
44436ed58ec5SVille Tervo }
4444f4280918SAndrei Emeltchenko break;
4445f4280918SAndrei Emeltchenko
4446f4280918SAndrei Emeltchenko case SCO_LINK:
444770f23020SAndrei Emeltchenko hdev->sco_cnt += count;
444870f23020SAndrei Emeltchenko if (hdev->sco_cnt > hdev->sco_pkts)
44495b7f9909SMarcel Holtmann hdev->sco_cnt = hdev->sco_pkts;
4450f4280918SAndrei Emeltchenko break;
4451f4280918SAndrei Emeltchenko
445226afbd82SLuiz Augusto von Dentz case ISO_LINK:
445326afbd82SLuiz Augusto von Dentz if (hdev->iso_pkts) {
445426afbd82SLuiz Augusto von Dentz hdev->iso_cnt += count;
445526afbd82SLuiz Augusto von Dentz if (hdev->iso_cnt > hdev->iso_pkts)
445626afbd82SLuiz Augusto von Dentz hdev->iso_cnt = hdev->iso_pkts;
445726afbd82SLuiz Augusto von Dentz } else if (hdev->le_pkts) {
445826afbd82SLuiz Augusto von Dentz hdev->le_cnt += count;
445926afbd82SLuiz Augusto von Dentz if (hdev->le_cnt > hdev->le_pkts)
446026afbd82SLuiz Augusto von Dentz hdev->le_cnt = hdev->le_pkts;
446126afbd82SLuiz Augusto von Dentz } else {
446226afbd82SLuiz Augusto von Dentz hdev->acl_cnt += count;
446326afbd82SLuiz Augusto von Dentz if (hdev->acl_cnt > hdev->acl_pkts)
446426afbd82SLuiz Augusto von Dentz hdev->acl_cnt = hdev->acl_pkts;
446526afbd82SLuiz Augusto von Dentz }
446626afbd82SLuiz Augusto von Dentz break;
446726afbd82SLuiz Augusto von Dentz
4468f4280918SAndrei Emeltchenko default:
44692064ee33SMarcel Holtmann bt_dev_err(hdev, "unknown type %d conn %p",
44702064ee33SMarcel Holtmann conn->type, conn);
hci_mode_change_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)4471f4280918SAndrei Emeltchenko break;
44721da177e4SLinus Torvalds }
44731da177e4SLinus Torvalds }
4474a9de9248SMarcel Holtmann
44753eff45eaSGustavo F. Padovan queue_work(hdev->workqueue, &hdev->tx_work);
44761da177e4SLinus Torvalds }
44771da177e4SLinus Torvalds
44783e54c589SLuiz Augusto von Dentz static void hci_mode_change_evt(struct hci_dev *hdev, void *data,
44793e54c589SLuiz Augusto von Dentz struct sk_buff *skb)
44801da177e4SLinus Torvalds {
44813e54c589SLuiz Augusto von Dentz struct hci_ev_mode_change *ev = data;
448204837f64SMarcel Holtmann struct hci_conn *conn;
44831da177e4SLinus Torvalds
44843e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
44851da177e4SLinus Torvalds
44861da177e4SLinus Torvalds hci_dev_lock(hdev);
44871da177e4SLinus Torvalds
448804837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
448904837f64SMarcel Holtmann if (conn) {
449004837f64SMarcel Holtmann conn->mode = ev->mode;
449104837f64SMarcel Holtmann
44928fc9ced3SGustavo Padovan if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
44938fc9ced3SGustavo Padovan &conn->flags)) {
449404837f64SMarcel Holtmann if (conn->mode == HCI_CM_ACTIVE)
449558a681efSJohan Hedberg set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
449604837f64SMarcel Holtmann else
449758a681efSJohan Hedberg clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
449804837f64SMarcel Holtmann }
4499e73439d8SMarcel Holtmann
hci_pin_code_request_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)450051a8efd7SJohan Hedberg if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
4501e73439d8SMarcel Holtmann hci_sco_setup(conn, ev->status);
450204837f64SMarcel Holtmann }
450304837f64SMarcel Holtmann
450404837f64SMarcel Holtmann hci_dev_unlock(hdev);
450504837f64SMarcel Holtmann }
450604837f64SMarcel Holtmann
45073e54c589SLuiz Augusto von Dentz static void hci_pin_code_request_evt(struct hci_dev *hdev, void *data,
45083e54c589SLuiz Augusto von Dentz struct sk_buff *skb)
45091da177e4SLinus Torvalds {
45103e54c589SLuiz Augusto von Dentz struct hci_ev_pin_code_req *ev = data;
4511052b30b0SMarcel Holtmann struct hci_conn *conn;
4512052b30b0SMarcel Holtmann
45133e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "");
4514052b30b0SMarcel Holtmann
4515052b30b0SMarcel Holtmann hci_dev_lock(hdev);
4516052b30b0SMarcel Holtmann
4517052b30b0SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
4518b6f98044SWaldemar Rymarkiewicz if (!conn)
4519b6f98044SWaldemar Rymarkiewicz goto unlock;
4520b6f98044SWaldemar Rymarkiewicz
4521b6f98044SWaldemar Rymarkiewicz if (conn->state == BT_CONNECTED) {
4522052b30b0SMarcel Holtmann hci_conn_hold(conn);
4523052b30b0SMarcel Holtmann conn->disc_timeout = HCI_PAIRING_TIMEOUT;
452476a68ba0SDavid Herrmann hci_conn_drop(conn);
4525052b30b0SMarcel Holtmann }
4526052b30b0SMarcel Holtmann
4527d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BONDABLE) &&
45282f407f0aSJohan Hedberg !test_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags)) {
452903b555e1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
453003b555e1SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr);
4531d7a5a11dSMarcel Holtmann } else if (hci_dev_test_flag(hdev, HCI_MGMT)) {
4532a770bb5aSWaldemar Rymarkiewicz u8 secure;
4533a770bb5aSWaldemar Rymarkiewicz
4534a770bb5aSWaldemar Rymarkiewicz if (conn->pending_sec_level == BT_SECURITY_HIGH)
4535a770bb5aSWaldemar Rymarkiewicz secure = 1;
4536a770bb5aSWaldemar Rymarkiewicz else
4537a770bb5aSWaldemar Rymarkiewicz secure = 0;
4538a770bb5aSWaldemar Rymarkiewicz
conn_set_key(struct hci_conn * conn,u8 key_type,u8 pin_len)4539744cf19eSJohan Hedberg mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
4540a770bb5aSWaldemar Rymarkiewicz }
4541980e1a53SJohan Hedberg
4542b6f98044SWaldemar Rymarkiewicz unlock:
4543052b30b0SMarcel Holtmann hci_dev_unlock(hdev);
45441da177e4SLinus Torvalds }
45451da177e4SLinus Torvalds
4546cb6f3f7aSJohan Hedberg static void conn_set_key(struct hci_conn *conn, u8 key_type, u8 pin_len)
4547cb6f3f7aSJohan Hedberg {
4548cb6f3f7aSJohan Hedberg if (key_type == HCI_LK_CHANGED_COMBINATION)
4549cb6f3f7aSJohan Hedberg return;
4550cb6f3f7aSJohan Hedberg
4551cb6f3f7aSJohan Hedberg conn->pin_length = pin_len;
4552cb6f3f7aSJohan Hedberg conn->key_type = key_type;
4553cb6f3f7aSJohan Hedberg
4554cb6f3f7aSJohan Hedberg switch (key_type) {
4555cb6f3f7aSJohan Hedberg case HCI_LK_LOCAL_UNIT:
4556cb6f3f7aSJohan Hedberg case HCI_LK_REMOTE_UNIT:
4557cb6f3f7aSJohan Hedberg case HCI_LK_DEBUG_COMBINATION:
4558cb6f3f7aSJohan Hedberg return;
4559cb6f3f7aSJohan Hedberg case HCI_LK_COMBINATION:
4560cb6f3f7aSJohan Hedberg if (pin_len == 16)
4561cb6f3f7aSJohan Hedberg conn->pending_sec_level = BT_SECURITY_HIGH;
4562cb6f3f7aSJohan Hedberg else
4563cb6f3f7aSJohan Hedberg conn->pending_sec_level = BT_SECURITY_MEDIUM;
4564cb6f3f7aSJohan Hedberg break;
4565cb6f3f7aSJohan Hedberg case HCI_LK_UNAUTH_COMBINATION_P192:
4566cb6f3f7aSJohan Hedberg case HCI_LK_UNAUTH_COMBINATION_P256:
4567cb6f3f7aSJohan Hedberg conn->pending_sec_level = BT_SECURITY_MEDIUM;
4568cb6f3f7aSJohan Hedberg break;
4569cb6f3f7aSJohan Hedberg case HCI_LK_AUTH_COMBINATION_P192:
4570cb6f3f7aSJohan Hedberg conn->pending_sec_level = BT_SECURITY_HIGH;
hci_link_key_request_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)4571cb6f3f7aSJohan Hedberg break;
4572cb6f3f7aSJohan Hedberg case HCI_LK_AUTH_COMBINATION_P256:
4573cb6f3f7aSJohan Hedberg conn->pending_sec_level = BT_SECURITY_FIPS;
4574cb6f3f7aSJohan Hedberg break;
4575cb6f3f7aSJohan Hedberg }
4576cb6f3f7aSJohan Hedberg }
4577cb6f3f7aSJohan Hedberg
45783e54c589SLuiz Augusto von Dentz static void hci_link_key_request_evt(struct hci_dev *hdev, void *data,
45793e54c589SLuiz Augusto von Dentz struct sk_buff *skb)
45801da177e4SLinus Torvalds {
45813e54c589SLuiz Augusto von Dentz struct hci_ev_link_key_req *ev = data;
458255ed8ca1SJohan Hedberg struct hci_cp_link_key_reply cp;
458355ed8ca1SJohan Hedberg struct hci_conn *conn;
458455ed8ca1SJohan Hedberg struct link_key *key;
458555ed8ca1SJohan Hedberg
45863e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "");
458755ed8ca1SJohan Hedberg
4588d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT))
458955ed8ca1SJohan Hedberg return;
459055ed8ca1SJohan Hedberg
459155ed8ca1SJohan Hedberg hci_dev_lock(hdev);
459255ed8ca1SJohan Hedberg
459355ed8ca1SJohan Hedberg key = hci_find_link_key(hdev, &ev->bdaddr);
459455ed8ca1SJohan Hedberg if (!key) {
45953e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "link key not found for %pMR", &ev->bdaddr);
459655ed8ca1SJohan Hedberg goto not_found;
459755ed8ca1SJohan Hedberg }
459855ed8ca1SJohan Hedberg
45993e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "found key type %u for %pMR", key->type, &ev->bdaddr);
460055ed8ca1SJohan Hedberg
460155ed8ca1SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
460260b83f57SWaldemar Rymarkiewicz if (conn) {
4603fe8bc5acSJohan Hedberg clear_bit(HCI_CONN_NEW_LINK_KEY, &conn->flags);
4604fe8bc5acSJohan Hedberg
460566138ce8SMarcel Holtmann if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 ||
460666138ce8SMarcel Holtmann key->type == HCI_LK_UNAUTH_COMBINATION_P256) &&
4607807deac2SGustavo Padovan conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
46083e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "ignoring unauthenticated key");
460955ed8ca1SJohan Hedberg goto not_found;
461055ed8ca1SJohan Hedberg }
461155ed8ca1SJohan Hedberg
461260b83f57SWaldemar Rymarkiewicz if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
4613f3fb0b58SJohan Hedberg (conn->pending_sec_level == BT_SECURITY_HIGH ||
4614f3fb0b58SJohan Hedberg conn->pending_sec_level == BT_SECURITY_FIPS)) {
46153e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "ignoring key unauthenticated for high security");
461660b83f57SWaldemar Rymarkiewicz goto not_found;
461760b83f57SWaldemar Rymarkiewicz }
461860b83f57SWaldemar Rymarkiewicz
4619cb6f3f7aSJohan Hedberg conn_set_key(conn, key->type, key->pin_len);
462060b83f57SWaldemar Rymarkiewicz }
462160b83f57SWaldemar Rymarkiewicz
462255ed8ca1SJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr);
46239b3b4460SAndrei Emeltchenko memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
462455ed8ca1SJohan Hedberg
462555ed8ca1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
462655ed8ca1SJohan Hedberg
462755ed8ca1SJohan Hedberg hci_dev_unlock(hdev);
462855ed8ca1SJohan Hedberg
hci_link_key_notify_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)462955ed8ca1SJohan Hedberg return;
463055ed8ca1SJohan Hedberg
463155ed8ca1SJohan Hedberg not_found:
463255ed8ca1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
463355ed8ca1SJohan Hedberg hci_dev_unlock(hdev);
46341da177e4SLinus Torvalds }
46351da177e4SLinus Torvalds
46363e54c589SLuiz Augusto von Dentz static void hci_link_key_notify_evt(struct hci_dev *hdev, void *data,
46373e54c589SLuiz Augusto von Dentz struct sk_buff *skb)
46381da177e4SLinus Torvalds {
46393e54c589SLuiz Augusto von Dentz struct hci_ev_link_key_notify *ev = data;
4640052b30b0SMarcel Holtmann struct hci_conn *conn;
46417652ff6aSJohan Hedberg struct link_key *key;
46427652ff6aSJohan Hedberg bool persistent;
464355ed8ca1SJohan Hedberg u8 pin_len = 0;
4644052b30b0SMarcel Holtmann
46453e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "");
4646052b30b0SMarcel Holtmann
4647052b30b0SMarcel Holtmann hci_dev_lock(hdev);
4648052b30b0SMarcel Holtmann
4649052b30b0SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
465082c13d42SJohan Hedberg if (!conn)
465182c13d42SJohan Hedberg goto unlock;
465282c13d42SJohan Hedberg
465333155c4aSLee, Chun-Yi /* Ignore NULL link key against CVE-2020-26555 */
4654b5412606SLuiz Augusto von Dentz if (!crypto_memneq(ev->link_key, ZERO_KEY, HCI_LINK_KEY_SIZE)) {
465533155c4aSLee, Chun-Yi bt_dev_dbg(hdev, "Ignore NULL link key (ZERO KEY) for %pMR",
465633155c4aSLee, Chun-Yi &ev->bdaddr);
465733155c4aSLee, Chun-Yi hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
465833155c4aSLee, Chun-Yi hci_conn_drop(conn);
465933155c4aSLee, Chun-Yi goto unlock;
466033155c4aSLee, Chun-Yi }
466133155c4aSLee, Chun-Yi
4662052b30b0SMarcel Holtmann hci_conn_hold(conn);
4663052b30b0SMarcel Holtmann conn->disc_timeout = HCI_DISCONN_TIMEOUT;
466476a68ba0SDavid Herrmann hci_conn_drop(conn);
466582c13d42SJohan Hedberg
4666fe8bc5acSJohan Hedberg set_bit(HCI_CONN_NEW_LINK_KEY, &conn->flags);
4667cb6f3f7aSJohan Hedberg conn_set_key(conn, ev->key_type, conn->pin_length);
4668052b30b0SMarcel Holtmann
4669d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT))
46707652ff6aSJohan Hedberg goto unlock;
467155ed8ca1SJohan Hedberg
46727652ff6aSJohan Hedberg key = hci_add_link_key(hdev, conn, &ev->bdaddr, ev->link_key,
46737652ff6aSJohan Hedberg ev->key_type, pin_len, &persistent);
46747652ff6aSJohan Hedberg if (!key)
46757652ff6aSJohan Hedberg goto unlock;
46767652ff6aSJohan Hedberg
4677cb6f3f7aSJohan Hedberg /* Update connection information since adding the key will have
4678cb6f3f7aSJohan Hedberg * fixed up the type in the case of changed combination keys.
4679cb6f3f7aSJohan Hedberg */
4680cb6f3f7aSJohan Hedberg if (ev->key_type == HCI_LK_CHANGED_COMBINATION)
4681cb6f3f7aSJohan Hedberg conn_set_key(conn, key->type, key->pin_len);
4682cb6f3f7aSJohan Hedberg
46837652ff6aSJohan Hedberg mgmt_new_link_key(hdev, key, persistent);
46847652ff6aSJohan Hedberg
46856d5650c4SJohan Hedberg /* Keep debug keys around only if the HCI_KEEP_DEBUG_KEYS flag
46866d5650c4SJohan Hedberg * is set. If it's not set simply remove the key from the kernel
46876d5650c4SJohan Hedberg * list (we've still notified user space about it but with
46886d5650c4SJohan Hedberg * store_hint being 0).
46896d5650c4SJohan Hedberg */
46906d5650c4SJohan Hedberg if (key->type == HCI_LK_DEBUG_COMBINATION &&
4691d7a5a11dSMarcel Holtmann !hci_dev_test_flag(hdev, HCI_KEEP_DEBUG_KEYS)) {
46920378b597SJohan Hedberg list_del_rcu(&key->list);
46930378b597SJohan Hedberg kfree_rcu(key, rcu);
469482c13d42SJohan Hedberg goto unlock;
469582c13d42SJohan Hedberg }
469682c13d42SJohan Hedberg
4697af6a9c32SJohan Hedberg if (persistent)
4698af6a9c32SJohan Hedberg clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags);
hci_clock_offset_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)4699af6a9c32SJohan Hedberg else
4700af6a9c32SJohan Hedberg set_bit(HCI_CONN_FLUSH_KEY, &conn->flags);
47017652ff6aSJohan Hedberg
47027652ff6aSJohan Hedberg unlock:
4703052b30b0SMarcel Holtmann hci_dev_unlock(hdev);
47041da177e4SLinus Torvalds }
47051da177e4SLinus Torvalds
47063e54c589SLuiz Augusto von Dentz static void hci_clock_offset_evt(struct hci_dev *hdev, void *data,
47073e54c589SLuiz Augusto von Dentz struct sk_buff *skb)
470804837f64SMarcel Holtmann {
47093e54c589SLuiz Augusto von Dentz struct hci_ev_clock_offset *ev = data;
471004837f64SMarcel Holtmann struct hci_conn *conn;
471104837f64SMarcel Holtmann
47123e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
471304837f64SMarcel Holtmann
471404837f64SMarcel Holtmann hci_dev_lock(hdev);
471504837f64SMarcel Holtmann
471604837f64SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
47171da177e4SLinus Torvalds if (conn && !ev->status) {
47181da177e4SLinus Torvalds struct inquiry_entry *ie;
47191da177e4SLinus Torvalds
4720cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
4721cc11b9c1SAndrei Emeltchenko if (ie) {
47221da177e4SLinus Torvalds ie->data.clock_offset = ev->clock_offset;
hci_pkt_type_change_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)47231da177e4SLinus Torvalds ie->timestamp = jiffies;
47241da177e4SLinus Torvalds }
47251da177e4SLinus Torvalds }
47261da177e4SLinus Torvalds
47271da177e4SLinus Torvalds hci_dev_unlock(hdev);
47281da177e4SLinus Torvalds }
47291da177e4SLinus Torvalds
47303e54c589SLuiz Augusto von Dentz static void hci_pkt_type_change_evt(struct hci_dev *hdev, void *data,
47313e54c589SLuiz Augusto von Dentz struct sk_buff *skb)
4732a8746417SMarcel Holtmann {
47333e54c589SLuiz Augusto von Dentz struct hci_ev_pkt_type_change *ev = data;
4734a8746417SMarcel Holtmann struct hci_conn *conn;
4735a8746417SMarcel Holtmann
47363e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
4737a8746417SMarcel Holtmann
4738a8746417SMarcel Holtmann hci_dev_lock(hdev);
4739a8746417SMarcel Holtmann
hci_pscan_rep_mode_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)4740a8746417SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
4741a8746417SMarcel Holtmann if (conn && !ev->status)
4742a8746417SMarcel Holtmann conn->pkt_type = __le16_to_cpu(ev->pkt_type);
4743a8746417SMarcel Holtmann
4744a8746417SMarcel Holtmann hci_dev_unlock(hdev);
4745a8746417SMarcel Holtmann }
4746a8746417SMarcel Holtmann
47473e54c589SLuiz Augusto von Dentz static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, void *data,
47483e54c589SLuiz Augusto von Dentz struct sk_buff *skb)
474985a1e930SMarcel Holtmann {
47503e54c589SLuiz Augusto von Dentz struct hci_ev_pscan_rep_mode *ev = data;
475185a1e930SMarcel Holtmann struct inquiry_entry *ie;
475285a1e930SMarcel Holtmann
47533e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "");
475485a1e930SMarcel Holtmann
475585a1e930SMarcel Holtmann hci_dev_lock(hdev);
475685a1e930SMarcel Holtmann
4757cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
4758cc11b9c1SAndrei Emeltchenko if (ie) {
hci_inquiry_result_with_rssi_evt(struct hci_dev * hdev,void * edata,struct sk_buff * skb)475985a1e930SMarcel Holtmann ie->data.pscan_rep_mode = ev->pscan_rep_mode;
476085a1e930SMarcel Holtmann ie->timestamp = jiffies;
476185a1e930SMarcel Holtmann }
476285a1e930SMarcel Holtmann
476385a1e930SMarcel Holtmann hci_dev_unlock(hdev);
476485a1e930SMarcel Holtmann }
476585a1e930SMarcel Holtmann
47663e54c589SLuiz Augusto von Dentz static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, void *edata,
4767807deac2SGustavo Padovan struct sk_buff *skb)
4768a9de9248SMarcel Holtmann {
476972279d17SLuiz Augusto von Dentz struct hci_ev_inquiry_result_rssi *ev = edata;
4770a9de9248SMarcel Holtmann struct inquiry_data data;
47718d08d324SLuiz Augusto von Dentz int i;
4772a9de9248SMarcel Holtmann
477372279d17SLuiz Augusto von Dentz bt_dev_dbg(hdev, "num_rsp %d", ev->num);
47748d08d324SLuiz Augusto von Dentz
477572279d17SLuiz Augusto von Dentz if (!ev->num)
4776a9de9248SMarcel Holtmann return;
4777a9de9248SMarcel Holtmann
4778d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ))
47791519cc17SAndre Guedes return;
47801519cc17SAndre Guedes
4781a9de9248SMarcel Holtmann hci_dev_lock(hdev);
4782a9de9248SMarcel Holtmann
478372279d17SLuiz Augusto von Dentz if (skb->len == array_size(ev->num,
478472279d17SLuiz Augusto von Dentz sizeof(struct inquiry_info_rssi_pscan))) {
47858d08d324SLuiz Augusto von Dentz struct inquiry_info_rssi_pscan *info;
4786a9de9248SMarcel Holtmann
478772279d17SLuiz Augusto von Dentz for (i = 0; i < ev->num; i++) {
4788af58925cSMarcel Holtmann u32 flags;
4789af58925cSMarcel Holtmann
4790fee64503SLuiz Augusto von Dentz info = hci_ev_skb_pull(hdev, skb,
4791fee64503SLuiz Augusto von Dentz HCI_EV_INQUIRY_RESULT_WITH_RSSI,
4792fee64503SLuiz Augusto von Dentz sizeof(*info));
4793fee64503SLuiz Augusto von Dentz if (!info) {
4794fee64503SLuiz Augusto von Dentz bt_dev_err(hdev, "Malformed HCI Event: 0x%2.2x",
4795fee64503SLuiz Augusto von Dentz HCI_EV_INQUIRY_RESULT_WITH_RSSI);
4796c07ba878SDan Carpenter goto unlock;
4797fee64503SLuiz Augusto von Dentz }
4798fee64503SLuiz Augusto von Dentz
4799a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr);
4800a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode;
4801a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode;
4802a9de9248SMarcel Holtmann data.pscan_mode = info->pscan_mode;
4803a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3);
4804a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset;
4805a9de9248SMarcel Holtmann data.rssi = info->rssi;
480641a96212SMarcel Holtmann data.ssp_mode = 0x00;
48073175405bSJohan Hedberg
4808af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, false);
4809af58925cSMarcel Holtmann
481048264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
4811e17acd40SJohan Hedberg info->dev_class, info->rssi,
4812b338d917SBrian Gix flags, NULL, 0, NULL, 0, 0);
4813a9de9248SMarcel Holtmann }
481472279d17SLuiz Augusto von Dentz } else if (skb->len == array_size(ev->num,
481572279d17SLuiz Augusto von Dentz sizeof(struct inquiry_info_rssi))) {
48168d08d324SLuiz Augusto von Dentz struct inquiry_info_rssi *info;
4817a9de9248SMarcel Holtmann
481872279d17SLuiz Augusto von Dentz for (i = 0; i < ev->num; i++) {
4819af58925cSMarcel Holtmann u32 flags;
4820af58925cSMarcel Holtmann
4821fee64503SLuiz Augusto von Dentz info = hci_ev_skb_pull(hdev, skb,
4822fee64503SLuiz Augusto von Dentz HCI_EV_INQUIRY_RESULT_WITH_RSSI,
4823fee64503SLuiz Augusto von Dentz sizeof(*info));
4824fee64503SLuiz Augusto von Dentz if (!info) {
4825fee64503SLuiz Augusto von Dentz bt_dev_err(hdev, "Malformed HCI Event: 0x%2.2x",
4826fee64503SLuiz Augusto von Dentz HCI_EV_INQUIRY_RESULT_WITH_RSSI);
4827c07ba878SDan Carpenter goto unlock;
4828fee64503SLuiz Augusto von Dentz }
4829fee64503SLuiz Augusto von Dentz
4830a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr);
4831a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode;
4832a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode;
4833a9de9248SMarcel Holtmann data.pscan_mode = 0x00;
4834a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3);
4835a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset;
4836a9de9248SMarcel Holtmann data.rssi = info->rssi;
483741a96212SMarcel Holtmann data.ssp_mode = 0x00;
4838af58925cSMarcel Holtmann
4839af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, false);
4840af58925cSMarcel Holtmann
484148264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
4842e17acd40SJohan Hedberg info->dev_class, info->rssi,
4843b338d917SBrian Gix flags, NULL, 0, NULL, 0, 0);
4844a9de9248SMarcel Holtmann }
48458d08d324SLuiz Augusto von Dentz } else {
hci_remote_ext_features_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)48468d08d324SLuiz Augusto von Dentz bt_dev_err(hdev, "Malformed HCI Event: 0x%2.2x",
48478d08d324SLuiz Augusto von Dentz HCI_EV_INQUIRY_RESULT_WITH_RSSI);
4848a9de9248SMarcel Holtmann }
4849c07ba878SDan Carpenter unlock:
4850a9de9248SMarcel Holtmann hci_dev_unlock(hdev);
4851a9de9248SMarcel Holtmann }
4852a9de9248SMarcel Holtmann
48533e54c589SLuiz Augusto von Dentz static void hci_remote_ext_features_evt(struct hci_dev *hdev, void *data,
4854807deac2SGustavo Padovan struct sk_buff *skb)
4855a9de9248SMarcel Holtmann {
48563e54c589SLuiz Augusto von Dentz struct hci_ev_remote_ext_features *ev = data;
485741a96212SMarcel Holtmann struct hci_conn *conn;
485841a96212SMarcel Holtmann
48593e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
486041a96212SMarcel Holtmann
486141a96212SMarcel Holtmann hci_dev_lock(hdev);
486241a96212SMarcel Holtmann
486341a96212SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
4864ccd556feSJohan Hedberg if (!conn)
4865ccd556feSJohan Hedberg goto unlock;
4866ccd556feSJohan Hedberg
4867cad718edSJohan Hedberg if (ev->page < HCI_MAX_PAGES)
4868cad718edSJohan Hedberg memcpy(conn->features[ev->page], ev->features, 8);
4869cad718edSJohan Hedberg
4870769be974SMarcel Holtmann if (!ev->status && ev->page == 0x01) {
487141a96212SMarcel Holtmann struct inquiry_entry *ie;
487241a96212SMarcel Holtmann
4873cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
4874cc11b9c1SAndrei Emeltchenko if (ie)
487502b7cc62SJohan Hedberg ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
487641a96212SMarcel Holtmann
4877bbb0eadaSJaganath Kanakkassery if (ev->features[0] & LMP_HOST_SSP) {
487858a681efSJohan Hedberg set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
4879bbb0eadaSJaganath Kanakkassery } else {
4880bbb0eadaSJaganath Kanakkassery /* It is mandatory by the Bluetooth specification that
4881bbb0eadaSJaganath Kanakkassery * Extended Inquiry Results are only used when Secure
4882bbb0eadaSJaganath Kanakkassery * Simple Pairing is enabled, but some devices violate
4883bbb0eadaSJaganath Kanakkassery * this.
4884bbb0eadaSJaganath Kanakkassery *
4885bbb0eadaSJaganath Kanakkassery * To make these devices work, the internal SSP
4886bbb0eadaSJaganath Kanakkassery * enabled flag needs to be cleared if the remote host
4887bbb0eadaSJaganath Kanakkassery * features do not indicate SSP support */
4888bbb0eadaSJaganath Kanakkassery clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
4889bbb0eadaSJaganath Kanakkassery }
4890eb9a8f3fSMarcel Holtmann
4891eb9a8f3fSMarcel Holtmann if (ev->features[0] & LMP_HOST_SC)
4892eb9a8f3fSMarcel Holtmann set_bit(HCI_CONN_SC_ENABLED, &conn->flags);
489341a96212SMarcel Holtmann }
489441a96212SMarcel Holtmann
4895ccd556feSJohan Hedberg if (conn->state != BT_CONFIG)
4896ccd556feSJohan Hedberg goto unlock;
4897ccd556feSJohan Hedberg
4898671267bfSJohan Hedberg if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
4899127178d2SJohan Hedberg struct hci_cp_remote_name_req cp;
4900127178d2SJohan Hedberg memset(&cp, 0, sizeof(cp));
4901127178d2SJohan Hedberg bacpy(&cp.bdaddr, &conn->dst);
4902127178d2SJohan Hedberg cp.pscan_rep_mode = 0x02;
4903127178d2SJohan Hedberg hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
49040b3df53cSLuiz Augusto von Dentz } else {
49051c6ed31bSYu Liu mgmt_device_connected(hdev, conn, NULL, 0);
49060b3df53cSLuiz Augusto von Dentz }
4907392599b9SJohan Hedberg
4908127178d2SJohan Hedberg if (!hci_outgoing_auth_needed(hdev, conn)) {
4909769be974SMarcel Holtmann conn->state = BT_CONNECTED;
4910539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status);
hci_sync_conn_complete_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)491176a68ba0SDavid Herrmann hci_conn_drop(conn);
4912769be974SMarcel Holtmann }
4913769be974SMarcel Holtmann
4914ccd556feSJohan Hedberg unlock:
491541a96212SMarcel Holtmann hci_dev_unlock(hdev);
4916a9de9248SMarcel Holtmann }
4917a9de9248SMarcel Holtmann
49183e54c589SLuiz Augusto von Dentz static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data,
4919807deac2SGustavo Padovan struct sk_buff *skb)
4920a9de9248SMarcel Holtmann {
49213e54c589SLuiz Augusto von Dentz struct hci_ev_sync_conn_complete *ev = data;
4922b6a0dc82SMarcel Holtmann struct hci_conn *conn;
4923c86cc5a3SLuiz Augusto von Dentz u8 status = ev->status;
4924b6a0dc82SMarcel Holtmann
49253afee211SSoenke Huster switch (ev->link_type) {
49263afee211SSoenke Huster case SCO_LINK:
49273afee211SSoenke Huster case ESCO_LINK:
49283afee211SSoenke Huster break;
49293afee211SSoenke Huster default:
49303afee211SSoenke Huster /* As per Core 5.3 Vol 4 Part E 7.7.35 (p.2219), Link_Type
49313afee211SSoenke Huster * for HCI_Synchronous_Connection_Complete is limited to
49323afee211SSoenke Huster * either SCO or eSCO
49333afee211SSoenke Huster */
49343afee211SSoenke Huster bt_dev_err(hdev, "Ignoring connect complete event for invalid link type");
49353afee211SSoenke Huster return;
49363afee211SSoenke Huster }
49373afee211SSoenke Huster
4938c86cc5a3SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", status);
4939b6a0dc82SMarcel Holtmann
4940b6a0dc82SMarcel Holtmann hci_dev_lock(hdev);
4941b6a0dc82SMarcel Holtmann
4942b6a0dc82SMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
49439dc0a3afSMarcel Holtmann if (!conn) {
49449dc0a3afSMarcel Holtmann if (ev->link_type == ESCO_LINK)
49459dc0a3afSMarcel Holtmann goto unlock;
49469dc0a3afSMarcel Holtmann
4947618353b1SKuba Pawlak /* When the link type in the event indicates SCO connection
4948618353b1SKuba Pawlak * and lookup of the connection object fails, then check
4949618353b1SKuba Pawlak * if an eSCO connection object exists.
4950618353b1SKuba Pawlak *
4951618353b1SKuba Pawlak * The core limits the synchronous connections to either
4952618353b1SKuba Pawlak * SCO or eSCO. The eSCO connection is preferred and tried
4953618353b1SKuba Pawlak * to be setup first and until successfully established,
4954618353b1SKuba Pawlak * the link type will be hinted as eSCO.
4955618353b1SKuba Pawlak */
49569dc0a3afSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
4957b6a0dc82SMarcel Holtmann if (!conn)
4958b6a0dc82SMarcel Holtmann goto unlock;
49599dc0a3afSMarcel Holtmann }
49609dc0a3afSMarcel Holtmann
4961d5ebaa7cSSoenke Huster /* The HCI_Synchronous_Connection_Complete event is only sent once per connection.
4962d5ebaa7cSSoenke Huster * Processing it more than once per connection can corrupt kernel memory.
496392fe24a7SDesmond Cheong Zhi Xi *
4964d5ebaa7cSSoenke Huster * As the connection handle is set here for the first time, it indicates
4965d5ebaa7cSSoenke Huster * whether the connection is already set up.
496692fe24a7SDesmond Cheong Zhi Xi */
49679f78191cSLuiz Augusto von Dentz if (!HCI_CONN_HANDLE_UNSET(conn->handle)) {
4968d5ebaa7cSSoenke Huster bt_dev_err(hdev, "Ignoring HCI_Sync_Conn_Complete event for existing connection");
496992fe24a7SDesmond Cheong Zhi Xi goto unlock;
497092fe24a7SDesmond Cheong Zhi Xi }
497192fe24a7SDesmond Cheong Zhi Xi
4972c86cc5a3SLuiz Augusto von Dentz switch (status) {
4973d5ebaa7cSSoenke Huster case 0x00:
497416e3b642SLuiz Augusto von Dentz status = hci_conn_set_handle(conn, __le16_to_cpu(ev->handle));
497516e3b642SLuiz Augusto von Dentz if (status) {
4976c86cc5a3SLuiz Augusto von Dentz conn->state = BT_CLOSED;
4977c86cc5a3SLuiz Augusto von Dentz break;
4978c86cc5a3SLuiz Augusto von Dentz }
4979c86cc5a3SLuiz Augusto von Dentz
4980732547f9SMarcel Holtmann conn->state = BT_CONNECTED;
4981618353b1SKuba Pawlak conn->type = ev->link_type;
4982732547f9SMarcel Holtmann
498323b9ceb7SMarcel Holtmann hci_debugfs_create_conn(conn);
4984732547f9SMarcel Holtmann hci_conn_add_sysfs(conn);
4985732547f9SMarcel Holtmann break;
4986732547f9SMarcel Holtmann
498781218d20SNick Pelly case 0x10: /* Connection Accept Timeout */
49881a4c958cSFrédéric Dalleau case 0x0d: /* Connection Rejected due to Limited Resources */
4989705e5711SStephen Coe case 0x11: /* Unsupported Feature or Parameter Value */
4990732547f9SMarcel Holtmann case 0x1c: /* SCO interval rejected */
49911038a00bSNick Pelly case 0x1a: /* Unsupported Remote Feature */
499256b5453aSHsin-Yu Chao case 0x1e: /* Invalid LMP Parameters */
4993732547f9SMarcel Holtmann case 0x1f: /* Unspecified error */
499427539bc4SAndrew Earl case 0x20: /* Unsupported LMP Parameter value */
49952dea632fSFrédéric Dalleau if (conn->out) {
4996efc7688bSMarcel Holtmann conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
4997efc7688bSMarcel Holtmann (hdev->esco_type & EDR_ESCO_MASK);
499806149746SLuiz Augusto von Dentz if (hci_setup_sync(conn, conn->parent->handle))
4999efc7688bSMarcel Holtmann goto unlock;
5000efc7688bSMarcel Holtmann }
500119186c7bSGustavo A. R. Silva fallthrough;
5002efc7688bSMarcel Holtmann
5003732547f9SMarcel Holtmann default:
5004b6a0dc82SMarcel Holtmann conn->state = BT_CLOSED;
5005732547f9SMarcel Holtmann break;
5006732547f9SMarcel Holtmann }
5007b6a0dc82SMarcel Holtmann
50081f8330eaSSathish Narsimman bt_dev_dbg(hdev, "SCO connected with air mode: %02x", ev->air_mode);
5009f4f9fa0cSChethan T N /* Notify only in case of SCO over HCI transport data path which
5010f4f9fa0cSChethan T N * is zero and non-zero value shall be non-HCI transport data path
5011f4f9fa0cSChethan T N */
5012a27c519aSJackie Liu if (conn->codec.data_path == 0 && hdev->notify) {
5013a27c519aSJackie Liu switch (ev->air_mode) {
5014a27c519aSJackie Liu case 0x02:
5015a27c519aSJackie Liu hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD);
5016a27c519aSJackie Liu break;
5017a27c519aSJackie Liu case 0x03:
5018a27c519aSJackie Liu hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_TRANSP);
5019a27c519aSJackie Liu break;
5020a27c519aSJackie Liu }
5021f4f9fa0cSChethan T N }
5022f4f9fa0cSChethan T N
5023c86cc5a3SLuiz Augusto von Dentz hci_connect_cfm(conn, status);
eir_get_length(u8 * eir,size_t eir_len)5024c86cc5a3SLuiz Augusto von Dentz if (status)
5025b6a0dc82SMarcel Holtmann hci_conn_del(conn);
5026b6a0dc82SMarcel Holtmann
5027b6a0dc82SMarcel Holtmann unlock:
5028b6a0dc82SMarcel Holtmann hci_dev_unlock(hdev);
5029a9de9248SMarcel Holtmann }
5030a9de9248SMarcel Holtmann
5031efdcf8e3SMarcel Holtmann static inline size_t eir_get_length(u8 *eir, size_t eir_len)
5032efdcf8e3SMarcel Holtmann {
5033efdcf8e3SMarcel Holtmann size_t parsed = 0;
5034efdcf8e3SMarcel Holtmann
5035efdcf8e3SMarcel Holtmann while (parsed < eir_len) {
5036efdcf8e3SMarcel Holtmann u8 field_len = eir[0];
5037efdcf8e3SMarcel Holtmann
5038efdcf8e3SMarcel Holtmann if (field_len == 0)
5039efdcf8e3SMarcel Holtmann return parsed;
5040efdcf8e3SMarcel Holtmann
hci_extended_inquiry_result_evt(struct hci_dev * hdev,void * edata,struct sk_buff * skb)5041efdcf8e3SMarcel Holtmann parsed += field_len + 1;
5042efdcf8e3SMarcel Holtmann eir += field_len + 1;
5043efdcf8e3SMarcel Holtmann }
5044efdcf8e3SMarcel Holtmann
5045efdcf8e3SMarcel Holtmann return eir_len;
5046efdcf8e3SMarcel Holtmann }
5047efdcf8e3SMarcel Holtmann
50483e54c589SLuiz Augusto von Dentz static void hci_extended_inquiry_result_evt(struct hci_dev *hdev, void *edata,
5049807deac2SGustavo Padovan struct sk_buff *skb)
5050a9de9248SMarcel Holtmann {
50513e54c589SLuiz Augusto von Dentz struct hci_ev_ext_inquiry_result *ev = edata;
5052a9de9248SMarcel Holtmann struct inquiry_data data;
50539d939d94SVishal Agarwal size_t eir_len;
505470a6b8deSLuiz Augusto von Dentz int i;
5055a9de9248SMarcel Holtmann
505670a6b8deSLuiz Augusto von Dentz if (!hci_ev_skb_pull(hdev, skb, HCI_EV_EXTENDED_INQUIRY_RESULT,
505770a6b8deSLuiz Augusto von Dentz flex_array_size(ev, info, ev->num)))
505870a6b8deSLuiz Augusto von Dentz return;
505970a6b8deSLuiz Augusto von Dentz
50603e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "num %d", ev->num);
506170a6b8deSLuiz Augusto von Dentz
506270a6b8deSLuiz Augusto von Dentz if (!ev->num)
5063a9de9248SMarcel Holtmann return;
5064a9de9248SMarcel Holtmann
5065d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ))
50661519cc17SAndre Guedes return;
50671519cc17SAndre Guedes
5068a9de9248SMarcel Holtmann hci_dev_lock(hdev);
5069a9de9248SMarcel Holtmann
507070a6b8deSLuiz Augusto von Dentz for (i = 0; i < ev->num; i++) {
507170a6b8deSLuiz Augusto von Dentz struct extended_inquiry_info *info = &ev->info[i];
5072af58925cSMarcel Holtmann u32 flags;
5073af58925cSMarcel Holtmann bool name_known;
5074561aafbcSJohan Hedberg
5075a9de9248SMarcel Holtmann bacpy(&data.bdaddr, &info->bdaddr);
5076a9de9248SMarcel Holtmann data.pscan_rep_mode = info->pscan_rep_mode;
5077a9de9248SMarcel Holtmann data.pscan_period_mode = info->pscan_period_mode;
5078a9de9248SMarcel Holtmann data.pscan_mode = 0x00;
5079a9de9248SMarcel Holtmann memcpy(data.dev_class, info->dev_class, 3);
5080a9de9248SMarcel Holtmann data.clock_offset = info->clock_offset;
5081a9de9248SMarcel Holtmann data.rssi = info->rssi;
508241a96212SMarcel Holtmann data.ssp_mode = 0x01;
5083561aafbcSJohan Hedberg
5084d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT))
50850d3b7f64SJohan Hedberg name_known = eir_get_data(info->data,
50864ddb1930SJohan Hedberg sizeof(info->data),
50870d3b7f64SJohan Hedberg EIR_NAME_COMPLETE, NULL);
5088561aafbcSJohan Hedberg else
5089561aafbcSJohan Hedberg name_known = true;
5090561aafbcSJohan Hedberg
5091af58925cSMarcel Holtmann flags = hci_inquiry_cache_update(hdev, &data, name_known);
5092af58925cSMarcel Holtmann
50939d939d94SVishal Agarwal eir_len = eir_get_length(info->data, sizeof(info->data));
5094af58925cSMarcel Holtmann
509548264f06SJohan Hedberg mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
hci_key_refresh_complete_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)5096af58925cSMarcel Holtmann info->dev_class, info->rssi,
5097b338d917SBrian Gix flags, info->data, eir_len, NULL, 0, 0);
5098a9de9248SMarcel Holtmann }
5099a9de9248SMarcel Holtmann
5100a9de9248SMarcel Holtmann hci_dev_unlock(hdev);
5101a9de9248SMarcel Holtmann }
5102a9de9248SMarcel Holtmann
51033e54c589SLuiz Augusto von Dentz static void hci_key_refresh_complete_evt(struct hci_dev *hdev, void *data,
51041c2e0041SJohan Hedberg struct sk_buff *skb)
51051c2e0041SJohan Hedberg {
51063e54c589SLuiz Augusto von Dentz struct hci_ev_key_refresh_complete *ev = data;
51071c2e0041SJohan Hedberg struct hci_conn *conn;
51081c2e0041SJohan Hedberg
51093e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x handle 0x%4.4x", ev->status,
51101c2e0041SJohan Hedberg __le16_to_cpu(ev->handle));
51111c2e0041SJohan Hedberg
51121c2e0041SJohan Hedberg hci_dev_lock(hdev);
51131c2e0041SJohan Hedberg
51141c2e0041SJohan Hedberg conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
51151c2e0041SJohan Hedberg if (!conn)
51161c2e0041SJohan Hedberg goto unlock;
51171c2e0041SJohan Hedberg
51189eb1fbfaSJohan Hedberg /* For BR/EDR the necessary steps are taken through the
51199eb1fbfaSJohan Hedberg * auth_complete event.
51209eb1fbfaSJohan Hedberg */
51219eb1fbfaSJohan Hedberg if (conn->type != LE_LINK)
51229eb1fbfaSJohan Hedberg goto unlock;
51239eb1fbfaSJohan Hedberg
51241c2e0041SJohan Hedberg if (!ev->status)
51251c2e0041SJohan Hedberg conn->sec_level = conn->pending_sec_level;
51261c2e0041SJohan Hedberg
51271c2e0041SJohan Hedberg clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
51281c2e0041SJohan Hedberg
51291c2e0041SJohan Hedberg if (ev->status && conn->state == BT_CONNECTED) {
5130bed71748SAndre Guedes hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
513176a68ba0SDavid Herrmann hci_conn_drop(conn);
51321c2e0041SJohan Hedberg goto unlock;
51331c2e0041SJohan Hedberg }
51341c2e0041SJohan Hedberg
51351c2e0041SJohan Hedberg if (conn->state == BT_CONFIG) {
51361c2e0041SJohan Hedberg if (!ev->status)
51371c2e0041SJohan Hedberg conn->state = BT_CONNECTED;
51381c2e0041SJohan Hedberg
5139539c496dSJohan Hedberg hci_connect_cfm(conn, ev->status);
514076a68ba0SDavid Herrmann hci_conn_drop(conn);
51411c2e0041SJohan Hedberg } else {
51421c2e0041SJohan Hedberg hci_auth_cfm(conn, ev->status);
51431c2e0041SJohan Hedberg
51441c2e0041SJohan Hedberg hci_conn_hold(conn);
51451c2e0041SJohan Hedberg conn->disc_timeout = HCI_DISCONN_TIMEOUT;
hci_get_auth_req(struct hci_conn * conn)514676a68ba0SDavid Herrmann hci_conn_drop(conn);
51471c2e0041SJohan Hedberg }
51481c2e0041SJohan Hedberg
51491c2e0041SJohan Hedberg unlock:
51501c2e0041SJohan Hedberg hci_dev_unlock(hdev);
51511c2e0041SJohan Hedberg }
51521c2e0041SJohan Hedberg
51536039aa73SGustavo Padovan static u8 hci_get_auth_req(struct hci_conn *conn)
515417fa4b9dSJohan Hedberg {
515517fa4b9dSJohan Hedberg /* If remote requests no-bonding follow that lead */
5156acabae96SMikel Astiz if (conn->remote_auth == HCI_AT_NO_BONDING ||
5157acabae96SMikel Astiz conn->remote_auth == HCI_AT_NO_BONDING_MITM)
515858797bf7SWaldemar Rymarkiewicz return conn->remote_auth | (conn->auth_type & 0x01);
515917fa4b9dSJohan Hedberg
5160b7f94c88SMikel Astiz /* If both remote and local have enough IO capabilities, require
5161b7f94c88SMikel Astiz * MITM protection
5162b7f94c88SMikel Astiz */
5163b7f94c88SMikel Astiz if (conn->remote_cap != HCI_IO_NO_INPUT_OUTPUT &&
bredr_oob_data_present(struct hci_conn * conn)5164b7f94c88SMikel Astiz conn->io_capability != HCI_IO_NO_INPUT_OUTPUT)
5165b7f94c88SMikel Astiz return conn->remote_auth | 0x01;
5166b7f94c88SMikel Astiz
51677e74170aSTimo Mueller /* No MITM protection possible so ignore remote requirement */
51687e74170aSTimo Mueller return (conn->remote_auth & ~0x01) | (conn->auth_type & 0x01);
516917fa4b9dSJohan Hedberg }
517017fa4b9dSJohan Hedberg
5171a83ed81eSMarcel Holtmann static u8 bredr_oob_data_present(struct hci_conn *conn)
5172a83ed81eSMarcel Holtmann {
5173a83ed81eSMarcel Holtmann struct hci_dev *hdev = conn->hdev;
5174a83ed81eSMarcel Holtmann struct oob_data *data;
5175a83ed81eSMarcel Holtmann
5176a83ed81eSMarcel Holtmann data = hci_find_remote_oob_data(hdev, &conn->dst, BDADDR_BREDR);
5177a83ed81eSMarcel Holtmann if (!data)
5178a83ed81eSMarcel Holtmann return 0x00;
5179a83ed81eSMarcel Holtmann
5180bf21d793SMarcel Holtmann if (bredr_sc_enabled(hdev)) {
5181bf21d793SMarcel Holtmann /* When Secure Connections is enabled, then just
5182bf21d793SMarcel Holtmann * return the present value stored with the OOB
5183bf21d793SMarcel Holtmann * data. The stored value contains the right present
5184bf21d793SMarcel Holtmann * information. However it can only be trusted when
5185bf21d793SMarcel Holtmann * not in Secure Connection Only mode.
5186aa5b0345SMarcel Holtmann */
5187d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_SC_ONLY))
5188bf21d793SMarcel Holtmann return data->present;
5189bf21d793SMarcel Holtmann
5190bf21d793SMarcel Holtmann /* When Secure Connections Only mode is enabled, then
5191bf21d793SMarcel Holtmann * the P-256 values are required. If they are not
5192bf21d793SMarcel Holtmann * available, then do not declare that OOB data is
5193bf21d793SMarcel Holtmann * present.
5194bf21d793SMarcel Holtmann */
5195b5412606SLuiz Augusto von Dentz if (!crypto_memneq(data->rand256, ZERO_KEY, 16) ||
5196b5412606SLuiz Augusto von Dentz !crypto_memneq(data->hash256, ZERO_KEY, 16))
5197aa5b0345SMarcel Holtmann return 0x00;
5198aa5b0345SMarcel Holtmann
5199bf21d793SMarcel Holtmann return 0x02;
5200bf21d793SMarcel Holtmann }
5201659c7fb0SMarcel Holtmann
5202659c7fb0SMarcel Holtmann /* When Secure Connections is not enabled or actually
5203659c7fb0SMarcel Holtmann * not supported by the hardware, then check that if
5204659c7fb0SMarcel Holtmann * P-192 data values are present.
5205659c7fb0SMarcel Holtmann */
hci_io_capa_request_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)5206b5412606SLuiz Augusto von Dentz if (!crypto_memneq(data->rand192, ZERO_KEY, 16) ||
5207b5412606SLuiz Augusto von Dentz !crypto_memneq(data->hash192, ZERO_KEY, 16))
5208659c7fb0SMarcel Holtmann return 0x00;
5209659c7fb0SMarcel Holtmann
5210a83ed81eSMarcel Holtmann return 0x01;
5211659c7fb0SMarcel Holtmann }
5212a83ed81eSMarcel Holtmann
52133e54c589SLuiz Augusto von Dentz static void hci_io_capa_request_evt(struct hci_dev *hdev, void *data,
52143e54c589SLuiz Augusto von Dentz struct sk_buff *skb)
52150493684eSMarcel Holtmann {
52163e54c589SLuiz Augusto von Dentz struct hci_ev_io_capa_request *ev = data;
52170493684eSMarcel Holtmann struct hci_conn *conn;
52180493684eSMarcel Holtmann
52193e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "");
52200493684eSMarcel Holtmann
52210493684eSMarcel Holtmann hci_dev_lock(hdev);
52220493684eSMarcel Holtmann
52230493684eSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
5224fba268acSLuiz Augusto von Dentz if (!conn || !hci_dev_test_flag(hdev, HCI_SSP_ENABLED))
522503b555e1SJohan Hedberg goto unlock;
522603b555e1SJohan Hedberg
5227fba268acSLuiz Augusto von Dentz /* Assume remote supports SSP since it has triggered this event */
5228fba268acSLuiz Augusto von Dentz set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
5229fba268acSLuiz Augusto von Dentz
52300493684eSMarcel Holtmann hci_conn_hold(conn);
52310493684eSMarcel Holtmann
5232d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT))
523303b555e1SJohan Hedberg goto unlock;
523403b555e1SJohan Hedberg
52352f407f0aSJohan Hedberg /* Allow pairing if we're pairable, the initiators of the
52362f407f0aSJohan Hedberg * pairing or if the remote is not requesting bonding.
52372f407f0aSJohan Hedberg */
5238d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_BONDABLE) ||
52392f407f0aSJohan Hedberg test_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags) ||
524003b555e1SJohan Hedberg (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
524117fa4b9dSJohan Hedberg struct hci_cp_io_capability_reply cp;
524217fa4b9dSJohan Hedberg
524317fa4b9dSJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr);
52447a7f1e7cSHemant Gupta /* Change the IO capability from KeyboardDisplay
52457a7f1e7cSHemant Gupta * to DisplayYesNo as it is not supported by BT spec. */
52467a7f1e7cSHemant Gupta cp.capability = (conn->io_capability == 0x04) ?
5247a767631aSMikel Astiz HCI_IO_DISPLAY_YESNO : conn->io_capability;
5248b7f94c88SMikel Astiz
5249b7f94c88SMikel Astiz /* If we are initiators, there is no remote information yet */
5250b7f94c88SMikel Astiz if (conn->remote_auth == 0xff) {
5251b16c6604SMikel Astiz /* Request MITM protection if our IO caps allow it
52524ad51a75SJohan Hedberg * except for the no-bonding case.
5253b16c6604SMikel Astiz */
52546fd6b915SMikel Astiz if (conn->io_capability != HCI_IO_NO_INPUT_OUTPUT &&
52559f743d74SJohan Hedberg conn->auth_type != HCI_AT_NO_BONDING)
52566c53823aSJohan Hedberg conn->auth_type |= 0x01;
5257b7f94c88SMikel Astiz } else {
52587cbc9bd9SJohan Hedberg conn->auth_type = hci_get_auth_req(conn);
5259b7f94c88SMikel Astiz }
526017fa4b9dSJohan Hedberg
526182c295b1SJohan Hedberg /* If we're not bondable, force one of the non-bondable
526282c295b1SJohan Hedberg * authentication requirement values.
526382c295b1SJohan Hedberg */
5264d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_BONDABLE))
526582c295b1SJohan Hedberg conn->auth_type &= HCI_AT_NO_BONDING_MITM;
526682c295b1SJohan Hedberg
526782c295b1SJohan Hedberg cp.authentication = conn->auth_type;
5268a83ed81eSMarcel Holtmann cp.oob_data = bredr_oob_data_present(conn);
5269ce85ee13SSzymon Janc
527017fa4b9dSJohan Hedberg hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
527117fa4b9dSJohan Hedberg sizeof(cp), &cp);
527203b555e1SJohan Hedberg } else {
527303b555e1SJohan Hedberg struct hci_cp_io_capability_neg_reply cp;
527403b555e1SJohan Hedberg
527503b555e1SJohan Hedberg bacpy(&cp.bdaddr, &ev->bdaddr);
52769f5a0d7bSAndrei Emeltchenko cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
527703b555e1SJohan Hedberg
527803b555e1SJohan Hedberg hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
hci_io_capa_reply_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)527903b555e1SJohan Hedberg sizeof(cp), &cp);
528003b555e1SJohan Hedberg }
528103b555e1SJohan Hedberg
528203b555e1SJohan Hedberg unlock:
528303b555e1SJohan Hedberg hci_dev_unlock(hdev);
528403b555e1SJohan Hedberg }
528503b555e1SJohan Hedberg
52863e54c589SLuiz Augusto von Dentz static void hci_io_capa_reply_evt(struct hci_dev *hdev, void *data,
52873e54c589SLuiz Augusto von Dentz struct sk_buff *skb)
528803b555e1SJohan Hedberg {
52893e54c589SLuiz Augusto von Dentz struct hci_ev_io_capa_reply *ev = data;
529003b555e1SJohan Hedberg struct hci_conn *conn;
529103b555e1SJohan Hedberg
52923e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "");
529303b555e1SJohan Hedberg
529403b555e1SJohan Hedberg hci_dev_lock(hdev);
529503b555e1SJohan Hedberg
529603b555e1SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
529703b555e1SJohan Hedberg if (!conn)
529803b555e1SJohan Hedberg goto unlock;
529903b555e1SJohan Hedberg
hci_user_confirm_request_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)530003b555e1SJohan Hedberg conn->remote_cap = ev->capability;
530103b555e1SJohan Hedberg conn->remote_auth = ev->authentication;
530203b555e1SJohan Hedberg
530303b555e1SJohan Hedberg unlock:
53040493684eSMarcel Holtmann hci_dev_unlock(hdev);
53050493684eSMarcel Holtmann }
53060493684eSMarcel Holtmann
53073e54c589SLuiz Augusto von Dentz static void hci_user_confirm_request_evt(struct hci_dev *hdev, void *data,
5308a5c29683SJohan Hedberg struct sk_buff *skb)
5309a5c29683SJohan Hedberg {
53103e54c589SLuiz Augusto von Dentz struct hci_ev_user_confirm_req *ev = data;
531155bc1a37SJohan Hedberg int loc_mitm, rem_mitm, confirm_hint = 0;
53127a828908SJohan Hedberg struct hci_conn *conn;
5313a5c29683SJohan Hedberg
53143e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "");
5315a5c29683SJohan Hedberg
5316a5c29683SJohan Hedberg hci_dev_lock(hdev);
5317a5c29683SJohan Hedberg
5318d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT))
53197a828908SJohan Hedberg goto unlock;
53207a828908SJohan Hedberg
53217a828908SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
53227a828908SJohan Hedberg if (!conn)
53237a828908SJohan Hedberg goto unlock;
53247a828908SJohan Hedberg
53257a828908SJohan Hedberg loc_mitm = (conn->auth_type & 0x01);
53267a828908SJohan Hedberg rem_mitm = (conn->remote_auth & 0x01);
53277a828908SJohan Hedberg
53287a828908SJohan Hedberg /* If we require MITM but the remote device can't provide that
53296c53823aSJohan Hedberg * (it has NoInputNoOutput) then reject the confirmation
53306c53823aSJohan Hedberg * request. We check the security level here since it doesn't
53316c53823aSJohan Hedberg * necessarily match conn->auth_type.
53326fd6b915SMikel Astiz */
53336c53823aSJohan Hedberg if (conn->pending_sec_level > BT_SECURITY_MEDIUM &&
53346c53823aSJohan Hedberg conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
53353e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "Rejecting request: remote device can't provide MITM");
53367a828908SJohan Hedberg hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
53377a828908SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr);
53387a828908SJohan Hedberg goto unlock;
53397a828908SJohan Hedberg }
53407a828908SJohan Hedberg
5341830c03e5SLuiz Augusto von Dentz /* If no side requires MITM protection; use JUST_CFM method */
5342a767631aSMikel Astiz if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
5343a767631aSMikel Astiz (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
534455bc1a37SJohan Hedberg
5345830c03e5SLuiz Augusto von Dentz /* If we're not the initiator of request authorization and the
5346830c03e5SLuiz Augusto von Dentz * local IO capability is not NoInputNoOutput, use JUST_WORKS
5347830c03e5SLuiz Augusto von Dentz * method (mgmt_user_confirm with confirm_hint set to 1).
5348ba15a58bSJohan Hedberg */
5349ba15a58bSJohan Hedberg if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) &&
5350830c03e5SLuiz Augusto von Dentz conn->io_capability != HCI_IO_NO_INPUT_OUTPUT) {
53513e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "Confirming auto-accept as acceptor");
535255bc1a37SJohan Hedberg confirm_hint = 1;
535355bc1a37SJohan Hedberg goto confirm;
535455bc1a37SJohan Hedberg }
535555bc1a37SJohan Hedberg
5356cee5f20fSHoward Chung /* If there already exists link key in local host, leave the
5357cee5f20fSHoward Chung * decision to user space since the remote device could be
5358cee5f20fSHoward Chung * legitimate or malicious.
5359cee5f20fSHoward Chung */
5360cee5f20fSHoward Chung if (hci_find_link_key(hdev, &ev->bdaddr)) {
5361cee5f20fSHoward Chung bt_dev_dbg(hdev, "Local host already has link key");
5362cee5f20fSHoward Chung confirm_hint = 1;
5363cee5f20fSHoward Chung goto confirm;
5364cee5f20fSHoward Chung }
5365cee5f20fSHoward Chung
53669f61656aSJohan Hedberg BT_DBG("Auto-accept of user confirmation with %ums delay",
53679f61656aSJohan Hedberg hdev->auto_accept_delay);
53689f61656aSJohan Hedberg
53699f61656aSJohan Hedberg if (hdev->auto_accept_delay > 0) {
53709f61656aSJohan Hedberg int delay = msecs_to_jiffies(hdev->auto_accept_delay);
53717bc18d9dSJohan Hedberg queue_delayed_work(conn->hdev->workqueue,
53727bc18d9dSJohan Hedberg &conn->auto_accept_work, delay);
53739f61656aSJohan Hedberg goto unlock;
53749f61656aSJohan Hedberg }
53759f61656aSJohan Hedberg
53767a828908SJohan Hedberg hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
53777a828908SJohan Hedberg sizeof(ev->bdaddr), &ev->bdaddr);
53787a828908SJohan Hedberg goto unlock;
53797a828908SJohan Hedberg }
53807a828908SJohan Hedberg
538155bc1a37SJohan Hedberg confirm:
hci_user_passkey_request_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)538239adbffeSJohan Hedberg mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0,
538339adbffeSJohan Hedberg le32_to_cpu(ev->passkey), confirm_hint);
5384a5c29683SJohan Hedberg
53857a828908SJohan Hedberg unlock:
5386a5c29683SJohan Hedberg hci_dev_unlock(hdev);
5387a5c29683SJohan Hedberg }
5388a5c29683SJohan Hedberg
53893e54c589SLuiz Augusto von Dentz static void hci_user_passkey_request_evt(struct hci_dev *hdev, void *data,
53901143d458SBrian Gix struct sk_buff *skb)
53911143d458SBrian Gix {
53923e54c589SLuiz Augusto von Dentz struct hci_ev_user_passkey_req *ev = data;
hci_user_passkey_notify_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)5393ae61a10dSLuiz Augusto von Dentz
53943e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "");
53951143d458SBrian Gix
5396d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT))
5397272d90dfSJohan Hedberg mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
53981143d458SBrian Gix }
53991143d458SBrian Gix
54003e54c589SLuiz Augusto von Dentz static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
540192a25256SJohan Hedberg struct sk_buff *skb)
540292a25256SJohan Hedberg {
54033e54c589SLuiz Augusto von Dentz struct hci_ev_user_passkey_notify *ev = data;
540492a25256SJohan Hedberg struct hci_conn *conn;
540592a25256SJohan Hedberg
54063e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "");
540792a25256SJohan Hedberg
540892a25256SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
540992a25256SJohan Hedberg if (!conn)
541092a25256SJohan Hedberg return;
541192a25256SJohan Hedberg
541292a25256SJohan Hedberg conn->passkey_notify = __le32_to_cpu(ev->passkey);
541392a25256SJohan Hedberg conn->passkey_entered = 0;
hci_keypress_notify_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)541492a25256SJohan Hedberg
5415d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT))
541692a25256SJohan Hedberg mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
541792a25256SJohan Hedberg conn->dst_type, conn->passkey_notify,
541892a25256SJohan Hedberg conn->passkey_entered);
541992a25256SJohan Hedberg }
542092a25256SJohan Hedberg
54213e54c589SLuiz Augusto von Dentz static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
54223e54c589SLuiz Augusto von Dentz struct sk_buff *skb)
542392a25256SJohan Hedberg {
54243e54c589SLuiz Augusto von Dentz struct hci_ev_keypress_notify *ev = data;
542592a25256SJohan Hedberg struct hci_conn *conn;
542692a25256SJohan Hedberg
54273e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "");
542892a25256SJohan Hedberg
542992a25256SJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
543092a25256SJohan Hedberg if (!conn)
543192a25256SJohan Hedberg return;
543292a25256SJohan Hedberg
543392a25256SJohan Hedberg switch (ev->type) {
543492a25256SJohan Hedberg case HCI_KEYPRESS_STARTED:
543592a25256SJohan Hedberg conn->passkey_entered = 0;
543692a25256SJohan Hedberg return;
543792a25256SJohan Hedberg
543892a25256SJohan Hedberg case HCI_KEYPRESS_ENTERED:
543992a25256SJohan Hedberg conn->passkey_entered++;
544092a25256SJohan Hedberg break;
544192a25256SJohan Hedberg
544292a25256SJohan Hedberg case HCI_KEYPRESS_ERASED:
544392a25256SJohan Hedberg conn->passkey_entered--;
544492a25256SJohan Hedberg break;
544592a25256SJohan Hedberg
544692a25256SJohan Hedberg case HCI_KEYPRESS_CLEARED:
544792a25256SJohan Hedberg conn->passkey_entered = 0;
544892a25256SJohan Hedberg break;
544992a25256SJohan Hedberg
545092a25256SJohan Hedberg case HCI_KEYPRESS_COMPLETED:
545192a25256SJohan Hedberg return;
545292a25256SJohan Hedberg }
hci_simple_pair_complete_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)545392a25256SJohan Hedberg
5454d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_MGMT))
545592a25256SJohan Hedberg mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
545692a25256SJohan Hedberg conn->dst_type, conn->passkey_notify,
545792a25256SJohan Hedberg conn->passkey_entered);
545892a25256SJohan Hedberg }
545992a25256SJohan Hedberg
54603e54c589SLuiz Augusto von Dentz static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,
5461807deac2SGustavo Padovan struct sk_buff *skb)
54620493684eSMarcel Holtmann {
54633e54c589SLuiz Augusto von Dentz struct hci_ev_simple_pair_complete *ev = data;
54640493684eSMarcel Holtmann struct hci_conn *conn;
54650493684eSMarcel Holtmann
54663e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "");
54670493684eSMarcel Holtmann
54680493684eSMarcel Holtmann hci_dev_lock(hdev);
54690493684eSMarcel Holtmann
54700493684eSMarcel Holtmann conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
5471c7f59461SZiyang Xuan if (!conn || !hci_conn_ssp_enabled(conn))
54722a611692SJohan Hedberg goto unlock;
54732a611692SJohan Hedberg
5474c1d4fa7aSJohan Hedberg /* Reset the authentication requirement to unknown */
5475c1d4fa7aSJohan Hedberg conn->remote_auth = 0xff;
5476c1d4fa7aSJohan Hedberg
54772a611692SJohan Hedberg /* To avoid duplicate auth_failed events to user space we check
54782a611692SJohan Hedberg * the HCI_CONN_AUTH_PEND flag which will be set if we
54792a611692SJohan Hedberg * initiated the authentication. A traditional auth_complete
54802a611692SJohan Hedberg * event gets always produced as initiator and is also mapped to
54812a611692SJohan Hedberg * the mgmt_auth_failed event */
5482fa1bd918SMikel Astiz if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
5483e1e930f5SJohan Hedberg mgmt_auth_failed(conn, ev->status);
hci_remote_host_features_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)54842a611692SJohan Hedberg
548576a68ba0SDavid Herrmann hci_conn_drop(conn);
54860493684eSMarcel Holtmann
54872a611692SJohan Hedberg unlock:
54880493684eSMarcel Holtmann hci_dev_unlock(hdev);
54890493684eSMarcel Holtmann }
54900493684eSMarcel Holtmann
54913e54c589SLuiz Augusto von Dentz static void hci_remote_host_features_evt(struct hci_dev *hdev, void *data,
5492807deac2SGustavo Padovan struct sk_buff *skb)
549341a96212SMarcel Holtmann {
54943e54c589SLuiz Augusto von Dentz struct hci_ev_remote_host_features *ev = data;
549541a96212SMarcel Holtmann struct inquiry_entry *ie;
5496cad718edSJohan Hedberg struct hci_conn *conn;
549741a96212SMarcel Holtmann
54983e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "");
549941a96212SMarcel Holtmann
550041a96212SMarcel Holtmann hci_dev_lock(hdev);
550141a96212SMarcel Holtmann
5502cad718edSJohan Hedberg conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
5503cad718edSJohan Hedberg if (conn)
5504cad718edSJohan Hedberg memcpy(conn->features[1], ev->features, 8);
5505cad718edSJohan Hedberg
hci_remote_oob_data_request_evt(struct hci_dev * hdev,void * edata,struct sk_buff * skb)5506cc11b9c1SAndrei Emeltchenko ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
5507cc11b9c1SAndrei Emeltchenko if (ie)
550802b7cc62SJohan Hedberg ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
550941a96212SMarcel Holtmann
551041a96212SMarcel Holtmann hci_dev_unlock(hdev);
551141a96212SMarcel Holtmann }
551241a96212SMarcel Holtmann
55133e54c589SLuiz Augusto von Dentz static void hci_remote_oob_data_request_evt(struct hci_dev *hdev, void *edata,
55142763eda6SSzymon Janc struct sk_buff *skb)
55152763eda6SSzymon Janc {
55163e54c589SLuiz Augusto von Dentz struct hci_ev_remote_oob_data_request *ev = edata;
55172763eda6SSzymon Janc struct oob_data *data;
55182763eda6SSzymon Janc
55193e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "");
55202763eda6SSzymon Janc
55212763eda6SSzymon Janc hci_dev_lock(hdev);
55222763eda6SSzymon Janc
5523d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_MGMT))
5524e1ba1f15SSzymon Janc goto unlock;
5525e1ba1f15SSzymon Janc
55266928a924SJohan Hedberg data = hci_find_remote_oob_data(hdev, &ev->bdaddr, BDADDR_BREDR);
55276665d057SMarcel Holtmann if (!data) {
55286665d057SMarcel Holtmann struct hci_cp_remote_oob_data_neg_reply cp;
55296665d057SMarcel Holtmann
55306665d057SMarcel Holtmann bacpy(&cp.bdaddr, &ev->bdaddr);
55316665d057SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY,
55326665d057SMarcel Holtmann sizeof(cp), &cp);
55336665d057SMarcel Holtmann goto unlock;
55346665d057SMarcel Holtmann }
55356665d057SMarcel Holtmann
5536710f11c0SJohan Hedberg if (bredr_sc_enabled(hdev)) {
5537519ca9d0SMarcel Holtmann struct hci_cp_remote_oob_ext_data_reply cp;
5538519ca9d0SMarcel Holtmann
5539519ca9d0SMarcel Holtmann bacpy(&cp.bdaddr, &ev->bdaddr);
5540d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_SC_ONLY)) {
55416665d057SMarcel Holtmann memset(cp.hash192, 0, sizeof(cp.hash192));
55426665d057SMarcel Holtmann memset(cp.rand192, 0, sizeof(cp.rand192));
55436665d057SMarcel Holtmann } else {
5544519ca9d0SMarcel Holtmann memcpy(cp.hash192, data->hash192, sizeof(cp.hash192));
554538da1703SJohan Hedberg memcpy(cp.rand192, data->rand192, sizeof(cp.rand192));
55466665d057SMarcel Holtmann }
5547519ca9d0SMarcel Holtmann memcpy(cp.hash256, data->hash256, sizeof(cp.hash256));
554838da1703SJohan Hedberg memcpy(cp.rand256, data->rand256, sizeof(cp.rand256));
5549519ca9d0SMarcel Holtmann
5550519ca9d0SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY,
5551519ca9d0SMarcel Holtmann sizeof(cp), &cp);
5552519ca9d0SMarcel Holtmann } else {
55532763eda6SSzymon Janc struct hci_cp_remote_oob_data_reply cp;
55542763eda6SSzymon Janc
55552763eda6SSzymon Janc bacpy(&cp.bdaddr, &ev->bdaddr);
5556519ca9d0SMarcel Holtmann memcpy(cp.hash, data->hash192, sizeof(cp.hash));
555738da1703SJohan Hedberg memcpy(cp.rand, data->rand192, sizeof(cp.rand));
55582763eda6SSzymon Janc
5559519ca9d0SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY,
le_conn_update_addr(struct hci_conn * conn,bdaddr_t * bdaddr,u8 bdaddr_type,bdaddr_t * local_rpa)5560519ca9d0SMarcel Holtmann sizeof(cp), &cp);
5561519ca9d0SMarcel Holtmann }
55622763eda6SSzymon Janc
5563e1ba1f15SSzymon Janc unlock:
55642763eda6SSzymon Janc hci_dev_unlock(hdev);
55652763eda6SSzymon Janc }
55662763eda6SSzymon Janc
5567cafae4cdSLuiz Augusto von Dentz static void le_conn_update_addr(struct hci_conn *conn, bdaddr_t *bdaddr,
5568cafae4cdSLuiz Augusto von Dentz u8 bdaddr_type, bdaddr_t *local_rpa)
5569cafae4cdSLuiz Augusto von Dentz {
5570cafae4cdSLuiz Augusto von Dentz if (conn->out) {
5571cafae4cdSLuiz Augusto von Dentz conn->dst_type = bdaddr_type;
5572cafae4cdSLuiz Augusto von Dentz conn->resp_addr_type = bdaddr_type;
5573cafae4cdSLuiz Augusto von Dentz bacpy(&conn->resp_addr, bdaddr);
5574cafae4cdSLuiz Augusto von Dentz
5575cafae4cdSLuiz Augusto von Dentz /* Check if the controller has set a Local RPA then it must be
5576cafae4cdSLuiz Augusto von Dentz * used instead or hdev->rpa.
5577cafae4cdSLuiz Augusto von Dentz */
5578cafae4cdSLuiz Augusto von Dentz if (local_rpa && bacmp(local_rpa, BDADDR_ANY)) {
5579cafae4cdSLuiz Augusto von Dentz conn->init_addr_type = ADDR_LE_DEV_RANDOM;
5580cafae4cdSLuiz Augusto von Dentz bacpy(&conn->init_addr, local_rpa);
5581cafae4cdSLuiz Augusto von Dentz } else if (hci_dev_test_flag(conn->hdev, HCI_PRIVACY)) {
5582cafae4cdSLuiz Augusto von Dentz conn->init_addr_type = ADDR_LE_DEV_RANDOM;
5583cafae4cdSLuiz Augusto von Dentz bacpy(&conn->init_addr, &conn->hdev->rpa);
5584cafae4cdSLuiz Augusto von Dentz } else {
5585cafae4cdSLuiz Augusto von Dentz hci_copy_identity_address(conn->hdev, &conn->init_addr,
5586cafae4cdSLuiz Augusto von Dentz &conn->init_addr_type);
5587cafae4cdSLuiz Augusto von Dentz }
5588cafae4cdSLuiz Augusto von Dentz } else {
5589cafae4cdSLuiz Augusto von Dentz conn->resp_addr_type = conn->hdev->adv_addr_type;
5590cafae4cdSLuiz Augusto von Dentz /* Check if the controller has set a Local RPA then it must be
5591cafae4cdSLuiz Augusto von Dentz * used instead or hdev->rpa.
5592cafae4cdSLuiz Augusto von Dentz */
5593cafae4cdSLuiz Augusto von Dentz if (local_rpa && bacmp(local_rpa, BDADDR_ANY)) {
5594cafae4cdSLuiz Augusto von Dentz conn->resp_addr_type = ADDR_LE_DEV_RANDOM;
5595cafae4cdSLuiz Augusto von Dentz bacpy(&conn->resp_addr, local_rpa);
5596cafae4cdSLuiz Augusto von Dentz } else if (conn->hdev->adv_addr_type == ADDR_LE_DEV_RANDOM) {
5597cafae4cdSLuiz Augusto von Dentz /* In case of ext adv, resp_addr will be updated in
5598cafae4cdSLuiz Augusto von Dentz * Adv Terminated event.
5599cafae4cdSLuiz Augusto von Dentz */
5600cafae4cdSLuiz Augusto von Dentz if (!ext_adv_capable(conn->hdev))
5601cafae4cdSLuiz Augusto von Dentz bacpy(&conn->resp_addr,
5602cafae4cdSLuiz Augusto von Dentz &conn->hdev->random_addr);
5603cafae4cdSLuiz Augusto von Dentz } else {
5604cafae4cdSLuiz Augusto von Dentz bacpy(&conn->resp_addr, &conn->hdev->bdaddr);
5605cafae4cdSLuiz Augusto von Dentz }
5606cafae4cdSLuiz Augusto von Dentz
5607cafae4cdSLuiz Augusto von Dentz conn->init_addr_type = bdaddr_type;
5608cafae4cdSLuiz Augusto von Dentz bacpy(&conn->init_addr, bdaddr);
5609cafae4cdSLuiz Augusto von Dentz
5610cafae4cdSLuiz Augusto von Dentz /* For incoming connections, set the default minimum
5611cafae4cdSLuiz Augusto von Dentz * and maximum connection interval. They will be used
5612cafae4cdSLuiz Augusto von Dentz * to check if the parameters are in range and if not
le_conn_complete_evt(struct hci_dev * hdev,u8 status,bdaddr_t * bdaddr,u8 bdaddr_type,bdaddr_t * local_rpa,u8 role,u16 handle,u16 interval,u16 latency,u16 supervision_timeout)5613cafae4cdSLuiz Augusto von Dentz * trigger the connection update procedure.
5614cafae4cdSLuiz Augusto von Dentz */
5615cafae4cdSLuiz Augusto von Dentz conn->le_conn_min_interval = conn->hdev->le_conn_min_interval;
5616cafae4cdSLuiz Augusto von Dentz conn->le_conn_max_interval = conn->hdev->le_conn_max_interval;
5617cafae4cdSLuiz Augusto von Dentz }
5618cafae4cdSLuiz Augusto von Dentz }
5619cafae4cdSLuiz Augusto von Dentz
5620d12fb056SJaganath Kanakkassery static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
5621cafae4cdSLuiz Augusto von Dentz bdaddr_t *bdaddr, u8 bdaddr_type,
5622cafae4cdSLuiz Augusto von Dentz bdaddr_t *local_rpa, u8 role, u16 handle,
5623cafae4cdSLuiz Augusto von Dentz u16 interval, u16 latency,
5624cafae4cdSLuiz Augusto von Dentz u16 supervision_timeout)
5625fcd89c09SVille Tervo {
5626912b42efSJohan Hedberg struct hci_conn_params *params;
5627fcd89c09SVille Tervo struct hci_conn *conn;
562868d6f6deSJohan Hedberg struct smp_irk *irk;
5629837d502eSJohan Hedberg u8 addr_type;
5630fcd89c09SVille Tervo
5631fcd89c09SVille Tervo hci_dev_lock(hdev);
5632fcd89c09SVille Tervo
5633fbd96c15SJohan Hedberg /* All controllers implicitly stop advertising in the event of a
5634fbd96c15SJohan Hedberg * connection, so ensure that the state bit is cleared.
5635fbd96c15SJohan Hedberg */
5636a358dc11SMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LE_ADV);
5637fbd96c15SJohan Hedberg
563853562665SArchie Pusaka conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, bdaddr);
5639b62f328bSVille Tervo if (!conn) {
5640aef2aa4fSLuiz Augusto von Dentz /* In case of error status and there is no connection pending
5641aef2aa4fSLuiz Augusto von Dentz * just unlock as there is nothing to cleanup.
5642aef2aa4fSLuiz Augusto von Dentz */
5643aef2aa4fSLuiz Augusto von Dentz if (status)
5644aef2aa4fSLuiz Augusto von Dentz goto unlock;
5645aef2aa4fSLuiz Augusto von Dentz
564684cb0143SZiyang Xuan conn = hci_conn_add_unset(hdev, LE_LINK, bdaddr, role);
5647ad3f7986SSungwoo Kim if (IS_ERR(conn)) {
5648ad3f7986SSungwoo Kim bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn));
5649230fd16aSAndre Guedes goto unlock;
5650b62f328bSVille Tervo }
565129b7988aSAndre Guedes
5652d12fb056SJaganath Kanakkassery conn->dst_type = bdaddr_type;
5653b9b343d2SAndre Guedes
5654cb1d68f7SJohan Hedberg /* If we didn't have a hci_conn object previously
565574be523cSArchie Pusaka * but we're in central role this must be something
56563d4f9c00SArchie Pusaka * initiated using an accept list. Since accept list based
5657cb1d68f7SJohan Hedberg * connections are not "first class citizens" we don't
5658cb1d68f7SJohan Hedberg * have full tracking of them. Therefore, we go ahead
5659cb1d68f7SJohan Hedberg * with a "best effort" approach of determining the
5660cb1d68f7SJohan Hedberg * initiator address based on the HCI_PRIVACY flag.
5661cb1d68f7SJohan Hedberg */
5662cb1d68f7SJohan Hedberg if (conn->out) {
5663d12fb056SJaganath Kanakkassery conn->resp_addr_type = bdaddr_type;
5664d12fb056SJaganath Kanakkassery bacpy(&conn->resp_addr, bdaddr);
5665d7a5a11dSMarcel Holtmann if (hci_dev_test_flag(hdev, HCI_PRIVACY)) {
5666cb1d68f7SJohan Hedberg conn->init_addr_type = ADDR_LE_DEV_RANDOM;
5667cb1d68f7SJohan Hedberg bacpy(&conn->init_addr, &hdev->rpa);
5668cb1d68f7SJohan Hedberg } else {
5669cb1d68f7SJohan Hedberg hci_copy_identity_address(hdev,
5670cb1d68f7SJohan Hedberg &conn->init_addr,
5671cb1d68f7SJohan Hedberg &conn->init_addr_type);
5672cb1d68f7SJohan Hedberg }
567380c24ab8SJohan Hedberg }
5674cb1d68f7SJohan Hedberg } else {
567580c24ab8SJohan Hedberg cancel_delayed_work(&conn->le_conn_timeout);
567680c24ab8SJohan Hedberg }
567780c24ab8SJohan Hedberg
5678d5ebaa7cSSoenke Huster /* The HCI_LE_Connection_Complete event is only sent once per connection.
5679d5ebaa7cSSoenke Huster * Processing it more than once per connection can corrupt kernel memory.
5680d5ebaa7cSSoenke Huster *
5681d5ebaa7cSSoenke Huster * As the connection handle is set here for the first time, it indicates
5682d5ebaa7cSSoenke Huster * whether the connection is already set up.
5683d5ebaa7cSSoenke Huster */
56849f78191cSLuiz Augusto von Dentz if (!HCI_CONN_HANDLE_UNSET(conn->handle)) {
5685d5ebaa7cSSoenke Huster bt_dev_err(hdev, "Ignoring HCI_Connection_Complete for existing connection");
5686d5ebaa7cSSoenke Huster goto unlock;
5687d5ebaa7cSSoenke Huster }
5688d5ebaa7cSSoenke Huster
5689cafae4cdSLuiz Augusto von Dentz le_conn_update_addr(conn, bdaddr, bdaddr_type, local_rpa);
56907be2edbbSJohan Hedberg
5691edb4b466SMarcel Holtmann /* Lookup the identity address from the stored connection
5692edb4b466SMarcel Holtmann * address and address type.
5693edb4b466SMarcel Holtmann *
5694edb4b466SMarcel Holtmann * When establishing connections to an identity address, the
5695edb4b466SMarcel Holtmann * connection procedure will store the resolvable random
5696edb4b466SMarcel Holtmann * address first. Now if it can be converted back into the
5697edb4b466SMarcel Holtmann * identity address, start using the identity address from
5698edb4b466SMarcel Holtmann * now on.
5699edb4b466SMarcel Holtmann */
5700edb4b466SMarcel Holtmann irk = hci_get_irk(hdev, &conn->dst, conn->dst_type);
570168d6f6deSJohan Hedberg if (irk) {
570268d6f6deSJohan Hedberg bacpy(&conn->dst, &irk->bdaddr);
570368d6f6deSJohan Hedberg conn->dst_type = irk->addr_type;
570468d6f6deSJohan Hedberg }
570568d6f6deSJohan Hedberg
5706d850bf08SLuiz Augusto von Dentz conn->dst_type = ev_bdaddr_type(hdev, conn->dst_type, NULL);
570779699a70SSathish Narasimman
5708c9f73a21SLuiz Augusto von Dentz /* All connection failure handling is taken care of by the
5709c9f73a21SLuiz Augusto von Dentz * hci_conn_failed function which is triggered by the HCI
5710c9f73a21SLuiz Augusto von Dentz * request completion callbacks used for connecting.
5711c9f73a21SLuiz Augusto von Dentz */
571284cb0143SZiyang Xuan if (status || hci_conn_set_handle(conn, handle))
5713837d502eSJohan Hedberg goto unlock;
5714837d502eSJohan Hedberg
5715b62e7220SLuiz Augusto von Dentz /* Drop the connection if it has been aborted */
5716b62e7220SLuiz Augusto von Dentz if (test_bit(HCI_CONN_CANCEL, &conn->flags)) {
5717b62e7220SLuiz Augusto von Dentz hci_conn_drop(conn);
5718b62e7220SLuiz Augusto von Dentz goto unlock;
5719b62e7220SLuiz Augusto von Dentz }
5720b62e7220SLuiz Augusto von Dentz
572108853f18SJohan Hedberg if (conn->dst_type == ADDR_LE_DEV_PUBLIC)
572208853f18SJohan Hedberg addr_type = BDADDR_LE_PUBLIC;
572308853f18SJohan Hedberg else
572408853f18SJohan Hedberg addr_type = BDADDR_LE_RANDOM;
572508853f18SJohan Hedberg
57262d3c2260SJohan Hedberg /* Drop the connection if the device is blocked */
57273d4f9c00SArchie Pusaka if (hci_bdaddr_list_lookup(&hdev->reject_list, &conn->dst, addr_type)) {
57282d3c2260SJohan Hedberg hci_conn_drop(conn);
5729cd17decbSAndre Guedes goto unlock;
5730cd17decbSAndre Guedes }
5731cd17decbSAndre Guedes
57321c6ed31bSYu Liu mgmt_device_connected(hdev, conn, NULL, 0);
573383bc71b4SVinicius Costa Gomes
57347b5c0d52SVinicius Costa Gomes conn->sec_level = BT_SECURITY_LOW;
57350fe29fd1SMarcel Holtmann conn->state = BT_CONFIG;
5736fcd89c09SVille Tervo
57377087c4f6SLuiz Augusto von Dentz /* Store current advertising instance as connection advertising instance
57387087c4f6SLuiz Augusto von Dentz * when sotfware rotation is in use so it can be re-enabled when
57397087c4f6SLuiz Augusto von Dentz * disconnected.
57407087c4f6SLuiz Augusto von Dentz */
57417087c4f6SLuiz Augusto von Dentz if (!ext_adv_capable(hdev))
57427087c4f6SLuiz Augusto von Dentz conn->adv_instance = hdev->cur_adv_instance;
57437087c4f6SLuiz Augusto von Dentz
5744d12fb056SJaganath Kanakkassery conn->le_conn_interval = interval;
5745d12fb056SJaganath Kanakkassery conn->le_conn_latency = latency;
5746d12fb056SJaganath Kanakkassery conn->le_supv_timeout = supervision_timeout;
5747e04fde60SMarcel Holtmann
574823b9ceb7SMarcel Holtmann hci_debugfs_create_conn(conn);
5749fcd89c09SVille Tervo hci_conn_add_sysfs(conn);
5750fcd89c09SVille Tervo
5751ef365da1SArchie Pusaka /* The remote features procedure is defined for central
57520fe29fd1SMarcel Holtmann * role only. So only in case of an initiated connection
57530fe29fd1SMarcel Holtmann * request the remote features.
57540fe29fd1SMarcel Holtmann *
5755ef365da1SArchie Pusaka * If the local controller supports peripheral-initiated features
5756ef365da1SArchie Pusaka * exchange, then requesting the remote features in peripheral
57570fe29fd1SMarcel Holtmann * role is possible. Otherwise just transition into the
57580fe29fd1SMarcel Holtmann * connected state without requesting the remote features.
57590fe29fd1SMarcel Holtmann */
57600fe29fd1SMarcel Holtmann if (conn->out ||
5761ef365da1SArchie Pusaka (hdev->le_features[0] & HCI_LE_PERIPHERAL_FEATURES)) {
57620fe29fd1SMarcel Holtmann struct hci_cp_le_read_remote_features cp;
57630fe29fd1SMarcel Holtmann
57640fe29fd1SMarcel Holtmann cp.handle = __cpu_to_le16(conn->handle);
57650fe29fd1SMarcel Holtmann
57660fe29fd1SMarcel Holtmann hci_send_cmd(hdev, HCI_OP_LE_READ_REMOTE_FEATURES,
57670fe29fd1SMarcel Holtmann sizeof(cp), &cp);
57680fe29fd1SMarcel Holtmann
57690fe29fd1SMarcel Holtmann hci_conn_hold(conn);
57700fe29fd1SMarcel Holtmann } else {
57710fe29fd1SMarcel Holtmann conn->state = BT_CONNECTED;
5772d12fb056SJaganath Kanakkassery hci_connect_cfm(conn, status);
57730fe29fd1SMarcel Holtmann }
5774fcd89c09SVille Tervo
57755477610fSJohan Hedberg params = hci_pend_le_action_lookup(&hdev->pend_le_conns, &conn->dst,
57765477610fSJohan Hedberg conn->dst_type);
5777f161dd41SJohan Hedberg if (params) {
5778195ef75eSPauli Virtanen hci_pend_le_list_del_init(params);
5779f161dd41SJohan Hedberg if (params->conn) {
5780f161dd41SJohan Hedberg hci_conn_drop(params->conn);
5781f8aaf9b6SJohan Hedberg hci_conn_put(params->conn);
5782f161dd41SJohan Hedberg params->conn = NULL;
5783f161dd41SJohan Hedberg }
hci_le_conn_complete_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)5784f161dd41SJohan Hedberg }
5785a4790dbdSAndre Guedes
5786fcd89c09SVille Tervo unlock:
57875bee2fd6SLuiz Augusto von Dentz hci_update_passive_scan(hdev);
5788fcd89c09SVille Tervo hci_dev_unlock(hdev);
5789fcd89c09SVille Tervo }
5790fcd89c09SVille Tervo
579195118dd4SLuiz Augusto von Dentz static void hci_le_conn_complete_evt(struct hci_dev *hdev, void *data,
579295118dd4SLuiz Augusto von Dentz struct sk_buff *skb)
5793d12fb056SJaganath Kanakkassery {
579495118dd4SLuiz Augusto von Dentz struct hci_ev_le_conn_complete *ev = data;
579512cfe417SLuiz Augusto von Dentz
579695118dd4SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
5797d12fb056SJaganath Kanakkassery
hci_le_enh_conn_complete_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)5798d12fb056SJaganath Kanakkassery le_conn_complete_evt(hdev, ev->status, &ev->bdaddr, ev->bdaddr_type,
5799cafae4cdSLuiz Augusto von Dentz NULL, ev->role, le16_to_cpu(ev->handle),
5800d12fb056SJaganath Kanakkassery le16_to_cpu(ev->interval),
5801d12fb056SJaganath Kanakkassery le16_to_cpu(ev->latency),
5802d12fb056SJaganath Kanakkassery le16_to_cpu(ev->supervision_timeout));
5803d12fb056SJaganath Kanakkassery }
5804d12fb056SJaganath Kanakkassery
580595118dd4SLuiz Augusto von Dentz static void hci_le_enh_conn_complete_evt(struct hci_dev *hdev, void *data,
58064d94f95dSJaganath Kanakkassery struct sk_buff *skb)
58074d94f95dSJaganath Kanakkassery {
580895118dd4SLuiz Augusto von Dentz struct hci_ev_le_enh_conn_complete *ev = data;
580912cfe417SLuiz Augusto von Dentz
581095118dd4SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
58114d94f95dSJaganath Kanakkassery
hci_le_ext_adv_term_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)58124d94f95dSJaganath Kanakkassery le_conn_complete_evt(hdev, ev->status, &ev->bdaddr, ev->bdaddr_type,
5813cafae4cdSLuiz Augusto von Dentz &ev->local_rpa, ev->role, le16_to_cpu(ev->handle),
58144d94f95dSJaganath Kanakkassery le16_to_cpu(ev->interval),
58154d94f95dSJaganath Kanakkassery le16_to_cpu(ev->latency),
58164d94f95dSJaganath Kanakkassery le16_to_cpu(ev->supervision_timeout));
58174d94f95dSJaganath Kanakkassery }
58184d94f95dSJaganath Kanakkassery
581995118dd4SLuiz Augusto von Dentz static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, void *data,
582095118dd4SLuiz Augusto von Dentz struct sk_buff *skb)
5821acf0aeaeSJaganath Kanakkassery {
582295118dd4SLuiz Augusto von Dentz struct hci_evt_le_ext_adv_set_term *ev = data;
5823acf0aeaeSJaganath Kanakkassery struct hci_conn *conn;
58241f9d5657SArchie Pusaka struct adv_info *adv, *n;
5825acf0aeaeSJaganath Kanakkassery
582695118dd4SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
5827acf0aeaeSJaganath Kanakkassery
58280f281a5eSArchie Pusaka /* The Bluetooth Core 5.3 specification clearly states that this event
58290f281a5eSArchie Pusaka * shall not be sent when the Host disables the advertising set. So in
58300f281a5eSArchie Pusaka * case of HCI_ERROR_CANCELLED_BY_HOST, just ignore the event.
58310f281a5eSArchie Pusaka *
58320f281a5eSArchie Pusaka * When the Host disables an advertising set, all cleanup is done via
58330f281a5eSArchie Pusaka * its command callback and not needed to be duplicated here.
58340f281a5eSArchie Pusaka */
58350f281a5eSArchie Pusaka if (ev->status == HCI_ERROR_CANCELLED_BY_HOST) {
58360f281a5eSArchie Pusaka bt_dev_warn_ratelimited(hdev, "Unexpected advertising set terminated event");
58370f281a5eSArchie Pusaka return;
58380f281a5eSArchie Pusaka }
58390f281a5eSArchie Pusaka
5840728abc01SNiels Dossche hci_dev_lock(hdev);
5841728abc01SNiels Dossche
5842728abc01SNiels Dossche adv = hci_find_adv_instance(hdev, ev->handle);
5843728abc01SNiels Dossche
58447087c4f6SLuiz Augusto von Dentz if (ev->status) {
584523837a6dSLuiz Augusto von Dentz if (!adv)
5846728abc01SNiels Dossche goto unlock;
5847acf0aeaeSJaganath Kanakkassery
584823837a6dSLuiz Augusto von Dentz /* Remove advertising as it has been terminated */
584923837a6dSLuiz Augusto von Dentz hci_remove_adv_instance(hdev, ev->handle);
585023837a6dSLuiz Augusto von Dentz mgmt_advertising_removed(NULL, hdev, ev->handle);
585123837a6dSLuiz Augusto von Dentz
58521f9d5657SArchie Pusaka list_for_each_entry_safe(adv, n, &hdev->adv_instances, list) {
58531f9d5657SArchie Pusaka if (adv->enabled)
5854728abc01SNiels Dossche goto unlock;
58551f9d5657SArchie Pusaka }
58561f9d5657SArchie Pusaka
58571f9d5657SArchie Pusaka /* We are no longer advertising, clear HCI_LE_ADV */
58581f9d5657SArchie Pusaka hci_dev_clear_flag(hdev, HCI_LE_ADV);
5859728abc01SNiels Dossche goto unlock;
586023837a6dSLuiz Augusto von Dentz }
586123837a6dSLuiz Augusto von Dentz
58627087c4f6SLuiz Augusto von Dentz if (adv)
58637087c4f6SLuiz Augusto von Dentz adv->enabled = false;
58647087c4f6SLuiz Augusto von Dentz
5865acf0aeaeSJaganath Kanakkassery conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->conn_handle));
5866acf0aeaeSJaganath Kanakkassery if (conn) {
58677087c4f6SLuiz Augusto von Dentz /* Store handle in the connection so the correct advertising
58687087c4f6SLuiz Augusto von Dentz * instance can be re-enabled when disconnected.
58697087c4f6SLuiz Augusto von Dentz */
58707087c4f6SLuiz Augusto von Dentz conn->adv_instance = ev->handle;
5871acf0aeaeSJaganath Kanakkassery
5872cafae4cdSLuiz Augusto von Dentz if (hdev->adv_addr_type != ADDR_LE_DEV_RANDOM ||
5873cafae4cdSLuiz Augusto von Dentz bacmp(&conn->resp_addr, BDADDR_ANY))
5874728abc01SNiels Dossche goto unlock;
5875acf0aeaeSJaganath Kanakkassery
587625e70886SDaniel Winkler if (!ev->handle) {
5877acf0aeaeSJaganath Kanakkassery bacpy(&conn->resp_addr, &hdev->random_addr);
5878728abc01SNiels Dossche goto unlock;
5879acf0aeaeSJaganath Kanakkassery }
5880acf0aeaeSJaganath Kanakkassery
58817087c4f6SLuiz Augusto von Dentz if (adv)
hci_le_conn_update_complete_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)58827087c4f6SLuiz Augusto von Dentz bacpy(&conn->resp_addr, &adv->random_addr);
5883acf0aeaeSJaganath Kanakkassery }
5884728abc01SNiels Dossche
5885728abc01SNiels Dossche unlock:
5886728abc01SNiels Dossche hci_dev_unlock(hdev);
5887acf0aeaeSJaganath Kanakkassery }
5888acf0aeaeSJaganath Kanakkassery
588995118dd4SLuiz Augusto von Dentz static void hci_le_conn_update_complete_evt(struct hci_dev *hdev, void *data,
58901855d92dSMarcel Holtmann struct sk_buff *skb)
58911855d92dSMarcel Holtmann {
589295118dd4SLuiz Augusto von Dentz struct hci_ev_le_conn_update_complete *ev = data;
58931855d92dSMarcel Holtmann struct hci_conn *conn;
58941855d92dSMarcel Holtmann
589595118dd4SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
58961855d92dSMarcel Holtmann
58971855d92dSMarcel Holtmann if (ev->status)
58981855d92dSMarcel Holtmann return;
58991855d92dSMarcel Holtmann
59001855d92dSMarcel Holtmann hci_dev_lock(hdev);
59011855d92dSMarcel Holtmann
59021855d92dSMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
59031855d92dSMarcel Holtmann if (conn) {
59041855d92dSMarcel Holtmann conn->le_conn_interval = le16_to_cpu(ev->interval);
59051855d92dSMarcel Holtmann conn->le_conn_latency = le16_to_cpu(ev->latency);
check_pending_le_conn(struct hci_dev * hdev,bdaddr_t * addr,u8 addr_type,bool addr_resolved,u8 adv_type)59061855d92dSMarcel Holtmann conn->le_supv_timeout = le16_to_cpu(ev->supervision_timeout);
59071855d92dSMarcel Holtmann }
59081855d92dSMarcel Holtmann
59091855d92dSMarcel Holtmann hci_dev_unlock(hdev);
59101855d92dSMarcel Holtmann }
59111855d92dSMarcel Holtmann
5912a4790dbdSAndre Guedes /* This function requires the caller holds hdev->lock */
5913fd45ada9SAlfonso Acosta static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev,
5914fd45ada9SAlfonso Acosta bdaddr_t *addr,
5915d850bf08SLuiz Augusto von Dentz u8 addr_type, bool addr_resolved,
59168e8b92eeSLuiz Augusto von Dentz u8 adv_type)
5917a4790dbdSAndre Guedes {
5918a4790dbdSAndre Guedes struct hci_conn *conn;
59194b9e7e75SMarcel Holtmann struct hci_conn_params *params;
5920a4790dbdSAndre Guedes
59211c1abcabSJohan Hedberg /* If the event is not connectable don't proceed further */
59221c1abcabSJohan Hedberg if (adv_type != LE_ADV_IND && adv_type != LE_ADV_DIRECT_IND)
5923fd45ada9SAlfonso Acosta return NULL;
59241c1abcabSJohan Hedberg
5925182ee45dSLuiz Augusto von Dentz /* Ignore if the device is blocked or hdev is suspended */
5926182ee45dSLuiz Augusto von Dentz if (hci_bdaddr_list_lookup(&hdev->reject_list, addr, addr_type) ||
5927182ee45dSLuiz Augusto von Dentz hdev->suspended)
5928fd45ada9SAlfonso Acosta return NULL;
59291c1abcabSJohan Hedberg
5930f99353cfSJohan Hedberg /* Most controller will fail if we try to create new connections
593139bc74caSArchie Pusaka * while we have an existing one in peripheral role.
5932f99353cfSJohan Hedberg */
593339bc74caSArchie Pusaka if (hdev->conn_hash.le_num_peripheral > 0 &&
59344364f2e9SAlain Michaud (!test_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks) ||
59354364f2e9SAlain Michaud !(hdev->le_states[3] & 0x10)))
5936fd45ada9SAlfonso Acosta return NULL;
5937f99353cfSJohan Hedberg
59381c1abcabSJohan Hedberg /* If we're not connectable only connect devices that we have in
59391c1abcabSJohan Hedberg * our pend_le_conns list.
59401c1abcabSJohan Hedberg */
594149c50922SJohan Hedberg params = hci_pend_le_action_lookup(&hdev->pend_le_conns, addr,
594249c50922SJohan Hedberg addr_type);
59434b9e7e75SMarcel Holtmann if (!params)
5944fd45ada9SAlfonso Acosta return NULL;
5945a4790dbdSAndre Guedes
594628a667c9SJakub Pawlowski if (!params->explicit_connect) {
59474b9e7e75SMarcel Holtmann switch (params->auto_connect) {
59484b9e7e75SMarcel Holtmann case HCI_AUTO_CONN_DIRECT:
59494b9e7e75SMarcel Holtmann /* Only devices advertising with ADV_DIRECT_IND are
59504b9e7e75SMarcel Holtmann * triggering a connection attempt. This is allowing
595167ffb185SArchie Pusaka * incoming connections from peripheral devices.
59524b9e7e75SMarcel Holtmann */
59534b9e7e75SMarcel Holtmann if (adv_type != LE_ADV_DIRECT_IND)
5954fd45ada9SAlfonso Acosta return NULL;
59554b9e7e75SMarcel Holtmann break;
59564b9e7e75SMarcel Holtmann case HCI_AUTO_CONN_ALWAYS:
59574b9e7e75SMarcel Holtmann /* Devices advertising with ADV_IND or ADV_DIRECT_IND
59584b9e7e75SMarcel Holtmann * are triggering a connection attempt. This means
595967ffb185SArchie Pusaka * that incoming connections from peripheral device are
596067ffb185SArchie Pusaka * accepted and also outgoing connections to peripheral
59614b9e7e75SMarcel Holtmann * devices are established when found.
59624b9e7e75SMarcel Holtmann */
59634b9e7e75SMarcel Holtmann break;
59644b9e7e75SMarcel Holtmann default:
5965fd45ada9SAlfonso Acosta return NULL;
59664b9e7e75SMarcel Holtmann }
596728a667c9SJakub Pawlowski }
59684b9e7e75SMarcel Holtmann
5969d850bf08SLuiz Augusto von Dentz conn = hci_connect_le(hdev, addr, addr_type, addr_resolved,
5970d850bf08SLuiz Augusto von Dentz BT_SECURITY_LOW, hdev->def_le_autoconnect_timeout,
59718e8b92eeSLuiz Augusto von Dentz HCI_ROLE_MASTER);
5972f161dd41SJohan Hedberg if (!IS_ERR(conn)) {
597328a667c9SJakub Pawlowski /* If HCI_AUTO_CONN_EXPLICIT is set, conn is already owned
597428a667c9SJakub Pawlowski * by higher layer that tried to connect, if no then
597528a667c9SJakub Pawlowski * store the pointer since we don't really have any
5976f161dd41SJohan Hedberg * other owner of the object besides the params that
5977f161dd41SJohan Hedberg * triggered it. This way we can abort the connection if
5978f161dd41SJohan Hedberg * the parameters get removed and keep the reference
5979f161dd41SJohan Hedberg * count consistent once the connection is established.
5980f161dd41SJohan Hedberg */
598128a667c9SJakub Pawlowski
598228a667c9SJakub Pawlowski if (!params->explicit_connect)
5983f8aaf9b6SJohan Hedberg params->conn = hci_conn_get(conn);
598428a667c9SJakub Pawlowski
5985fd45ada9SAlfonso Acosta return conn;
5986f161dd41SJohan Hedberg }
5987a4790dbdSAndre Guedes
5988a4790dbdSAndre Guedes switch (PTR_ERR(conn)) {
5989a4790dbdSAndre Guedes case -EBUSY:
5990a4790dbdSAndre Guedes /* If hci_connect() returns -EBUSY it means there is already
5991a4790dbdSAndre Guedes * an LE connection attempt going on. Since controllers don't
5992a4790dbdSAndre Guedes * support more than one connection attempt at the time, we
5993a4790dbdSAndre Guedes * don't consider this an error case.
5994a4790dbdSAndre Guedes */
5995a4790dbdSAndre Guedes break;
5996a4790dbdSAndre Guedes default:
process_adv_report(struct hci_dev * hdev,u8 type,bdaddr_t * bdaddr,u8 bdaddr_type,bdaddr_t * direct_addr,u8 direct_addr_type,s8 rssi,u8 * data,u8 len,bool ext_adv,bool ctl_time,u64 instant)5997a4790dbdSAndre Guedes BT_DBG("Failed to connect: err %ld", PTR_ERR(conn));
5998fd45ada9SAlfonso Acosta return NULL;
5999a4790dbdSAndre Guedes }
6000fd45ada9SAlfonso Acosta
6001fd45ada9SAlfonso Acosta return NULL;
6002a4790dbdSAndre Guedes }
6003a4790dbdSAndre Guedes
60044af605d8SJohan Hedberg static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
60052f010b55SMarcel Holtmann u8 bdaddr_type, bdaddr_t *direct_addr,
6006a2ec905dSAlain Michaud u8 direct_addr_type, s8 rssi, u8 *data, u8 len,
6007b338d917SBrian Gix bool ext_adv, bool ctl_time, u64 instant)
60084af605d8SJohan Hedberg {
6009b9a6328fSJohan Hedberg struct discovery_state *d = &hdev->discovery;
60101c1abcabSJohan Hedberg struct smp_irk *irk;
6011fd45ada9SAlfonso Acosta struct hci_conn *conn;
6012d850bf08SLuiz Augusto von Dentz bool match, bdaddr_resolved;
6013c70a7e4cSMarcel Holtmann u32 flags;
60141c58e933SSzymon Janc u8 *ptr;
60156818375eSSzymon Janc
601656b40fbfSJohan Hedberg switch (type) {
601756b40fbfSJohan Hedberg case LE_ADV_IND:
601856b40fbfSJohan Hedberg case LE_ADV_DIRECT_IND:
601956b40fbfSJohan Hedberg case LE_ADV_SCAN_IND:
602056b40fbfSJohan Hedberg case LE_ADV_NONCONN_IND:
602156b40fbfSJohan Hedberg case LE_ADV_SCAN_RSP:
602256b40fbfSJohan Hedberg break;
602356b40fbfSJohan Hedberg default:
60242064ee33SMarcel Holtmann bt_dev_err_ratelimited(hdev, "unknown advertising packet "
60252064ee33SMarcel Holtmann "type: 0x%02x", type);
602656b40fbfSJohan Hedberg return;
602756b40fbfSJohan Hedberg }
602856b40fbfSJohan Hedberg
6029112b5090SLuiz Augusto von Dentz if (len > max_adv_len(hdev)) {
6030112b5090SLuiz Augusto von Dentz bt_dev_err_ratelimited(hdev,
6031112b5090SLuiz Augusto von Dentz "adv larger than maximum supported");
6032a2ec905dSAlain Michaud return;
6033a2ec905dSAlain Michaud }
6034a2ec905dSAlain Michaud
60356818375eSSzymon Janc /* Find the end of the data in case the report contains padded zero
60366818375eSSzymon Janc * bytes at the end causing an invalid length value.
60376818375eSSzymon Janc *
60386818375eSSzymon Janc * When data is NULL, len is 0 so there is no need for extra ptr
60396818375eSSzymon Janc * check as 'ptr < data + 0' is already false in such case.
60406818375eSSzymon Janc */
60416818375eSSzymon Janc for (ptr = data; ptr < data + len && *ptr; ptr += *ptr + 1) {
60426818375eSSzymon Janc if (ptr + 1 + *ptr > data + len)
60436818375eSSzymon Janc break;
60446818375eSSzymon Janc }
60456818375eSSzymon Janc
60461c58e933SSzymon Janc /* Adjust for actual length. This handles the case when remote
60471c58e933SSzymon Janc * device is advertising with incorrect data length.
60481c58e933SSzymon Janc */
60491c58e933SSzymon Janc len = ptr - data;
6050b9a6328fSJohan Hedberg
60512f010b55SMarcel Holtmann /* If the direct address is present, then this report is from
60522f010b55SMarcel Holtmann * a LE Direct Advertising Report event. In that case it is
60532f010b55SMarcel Holtmann * important to see if the address is matching the local
60542f010b55SMarcel Holtmann * controller address.
60552f010b55SMarcel Holtmann */
6056b338d917SBrian Gix if (!hci_dev_test_flag(hdev, HCI_MESH) && direct_addr) {
6057d850bf08SLuiz Augusto von Dentz direct_addr_type = ev_bdaddr_type(hdev, direct_addr_type,
6058d850bf08SLuiz Augusto von Dentz &bdaddr_resolved);
60594ec4d63bSLuiz Augusto von Dentz
60602f010b55SMarcel Holtmann /* Only resolvable random addresses are valid for these
60612f010b55SMarcel Holtmann * kind of reports and others can be ignored.
60622f010b55SMarcel Holtmann */
60632f010b55SMarcel Holtmann if (!hci_bdaddr_is_rpa(direct_addr, direct_addr_type))
60642f010b55SMarcel Holtmann return;
60652f010b55SMarcel Holtmann
60662f010b55SMarcel Holtmann /* If the controller is not using resolvable random
60672f010b55SMarcel Holtmann * addresses, then this report can be ignored.
60682f010b55SMarcel Holtmann */
6069d7a5a11dSMarcel Holtmann if (!hci_dev_test_flag(hdev, HCI_PRIVACY))
60702f010b55SMarcel Holtmann return;
60712f010b55SMarcel Holtmann
60722f010b55SMarcel Holtmann /* If the local IRK of the controller does not match
60732f010b55SMarcel Holtmann * with the resolvable random address provided, then
60742f010b55SMarcel Holtmann * this report can be ignored.
60752f010b55SMarcel Holtmann */
60762f010b55SMarcel Holtmann if (!smp_irk_matches(hdev, hdev->irk, direct_addr))
60772f010b55SMarcel Holtmann return;
60782f010b55SMarcel Holtmann }
60792f010b55SMarcel Holtmann
6080435a13d8SJohan Hedberg /* Check if we need to convert to identity address */
6081435a13d8SJohan Hedberg irk = hci_get_irk(hdev, bdaddr, bdaddr_type);
6082435a13d8SJohan Hedberg if (irk) {
6083435a13d8SJohan Hedberg bdaddr = &irk->bdaddr;
6084435a13d8SJohan Hedberg bdaddr_type = irk->addr_type;
6085435a13d8SJohan Hedberg }
6086435a13d8SJohan Hedberg
6087d850bf08SLuiz Augusto von Dentz bdaddr_type = ev_bdaddr_type(hdev, bdaddr_type, &bdaddr_resolved);
60884ec4d63bSLuiz Augusto von Dentz
6089082f2300SSzymon Janc /* Check if we have been requested to connect to this device.
6090082f2300SSzymon Janc *
6091082f2300SSzymon Janc * direct_addr is set only for directed advertising reports (it is NULL
6092082f2300SSzymon Janc * for advertising reports) and is already verified to be RPA above.
6093082f2300SSzymon Janc */
6094d850bf08SLuiz Augusto von Dentz conn = check_pending_le_conn(hdev, bdaddr, bdaddr_type, bdaddr_resolved,
60958e8b92eeSLuiz Augusto von Dentz type);
6096112b5090SLuiz Augusto von Dentz if (!ext_adv && conn && type == LE_ADV_IND &&
6097112b5090SLuiz Augusto von Dentz len <= max_adv_len(hdev)) {
6098fd45ada9SAlfonso Acosta /* Store report for later inclusion by
6099fd45ada9SAlfonso Acosta * mgmt_device_connected
6100fd45ada9SAlfonso Acosta */
6101fd45ada9SAlfonso Acosta memcpy(conn->le_adv_data, data, len);
6102fd45ada9SAlfonso Acosta conn->le_adv_data_len = len;
6103fd45ada9SAlfonso Acosta }
610499a6768eSJohan Hedberg
6105b338d917SBrian Gix if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND)
6106b338d917SBrian Gix flags = MGMT_DEV_FOUND_NOT_CONNECTABLE;
6107b338d917SBrian Gix else
6108b338d917SBrian Gix flags = 0;
6109b338d917SBrian Gix
6110b338d917SBrian Gix /* All scan results should be sent up for Mesh systems */
6111b338d917SBrian Gix if (hci_dev_test_flag(hdev, HCI_MESH)) {
6112b338d917SBrian Gix mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
6113b338d917SBrian Gix rssi, flags, data, len, NULL, 0, instant);
6114b338d917SBrian Gix return;
6115b338d917SBrian Gix }
6116b338d917SBrian Gix
61171c1abcabSJohan Hedberg /* Passive scanning shouldn't trigger any device found events,
61181c1abcabSJohan Hedberg * except for devices marked as CONN_REPORT for which we do send
61198208f5a9SMiao-chen Chou * device found events, or advertisement monitoring requested.
61201c1abcabSJohan Hedberg */
61211c1abcabSJohan Hedberg if (hdev->le_scan_type == LE_SCAN_PASSIVE) {
61220d2bf134SJohan Hedberg if (type == LE_ADV_DIRECT_IND)
61230d2bf134SJohan Hedberg return;
61240d2bf134SJohan Hedberg
61253a19b6feSJohan Hedberg if (!hci_pend_le_action_lookup(&hdev->pend_le_reports,
61268208f5a9SMiao-chen Chou bdaddr, bdaddr_type) &&
61278208f5a9SMiao-chen Chou idr_is_empty(&hdev->adv_monitors_idr))
61280d2bf134SJohan Hedberg return;
61290d2bf134SJohan Hedberg
61300d2bf134SJohan Hedberg mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
6131b338d917SBrian Gix rssi, flags, data, len, NULL, 0, 0);
613297bf2e99SJohan Hedberg return;
6133ca5c4be7SJohan Hedberg }
61344af605d8SJohan Hedberg
613573f55453SLuiz Augusto von Dentz /* When receiving a scan response, then there is no way to
6136c70a7e4cSMarcel Holtmann * know if the remote device is connectable or not. However
6137c70a7e4cSMarcel Holtmann * since scan responses are merged with a previously seen
6138c70a7e4cSMarcel Holtmann * advertising report, the flags field from that report
6139c70a7e4cSMarcel Holtmann * will be used.
6140c70a7e4cSMarcel Holtmann *
614173f55453SLuiz Augusto von Dentz * In the unlikely case that a controller just sends a scan
614273f55453SLuiz Augusto von Dentz * response event that doesn't match the pending report, then
614373f55453SLuiz Augusto von Dentz * it is marked as a standalone SCAN_RSP.
6144c70a7e4cSMarcel Holtmann */
6145b338d917SBrian Gix if (type == LE_ADV_SCAN_RSP)
614673f55453SLuiz Augusto von Dentz flags = MGMT_DEV_FOUND_SCAN_RSP;
6147c70a7e4cSMarcel Holtmann
6148b9a6328fSJohan Hedberg /* If there's nothing pending either store the data from this
6149b9a6328fSJohan Hedberg * event or send an immediate device found event if the data
6150b9a6328fSJohan Hedberg * should not be stored for later.
6151b9a6328fSJohan Hedberg */
6152a2ec905dSAlain Michaud if (!ext_adv && !has_pending_adv_report(hdev)) {
6153b9a6328fSJohan Hedberg /* If the report will trigger a SCAN_REQ store it for
6154b9a6328fSJohan Hedberg * later merging.
6155b9a6328fSJohan Hedberg */
6156b9a6328fSJohan Hedberg if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) {
6157b9a6328fSJohan Hedberg store_pending_adv_report(hdev, bdaddr, bdaddr_type,
6158c70a7e4cSMarcel Holtmann rssi, flags, data, len);
6159b9a6328fSJohan Hedberg return;
6160b9a6328fSJohan Hedberg }
6161b9a6328fSJohan Hedberg
6162b9a6328fSJohan Hedberg mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
6163b338d917SBrian Gix rssi, flags, data, len, NULL, 0, 0);
6164b9a6328fSJohan Hedberg return;
6165b9a6328fSJohan Hedberg }
6166b9a6328fSJohan Hedberg
6167474ee066SJohan Hedberg /* Check if the pending report is for the same device as the new one */
6168474ee066SJohan Hedberg match = (!bacmp(bdaddr, &d->last_adv_addr) &&
6169474ee066SJohan Hedberg bdaddr_type == d->last_adv_addr_type);
6170474ee066SJohan Hedberg
6171b9a6328fSJohan Hedberg /* If the pending data doesn't match this report or this isn't a
6172b9a6328fSJohan Hedberg * scan response (e.g. we got a duplicate ADV_IND) then force
6173b9a6328fSJohan Hedberg * sending of the pending data.
6174b9a6328fSJohan Hedberg */
6175474ee066SJohan Hedberg if (type != LE_ADV_SCAN_RSP || !match) {
6176474ee066SJohan Hedberg /* Send out whatever is in the cache, but skip duplicates */
6177474ee066SJohan Hedberg if (!match)
6178b9a6328fSJohan Hedberg mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
6179ff5cd29fSJohan Hedberg d->last_adv_addr_type, NULL,
6180c70a7e4cSMarcel Holtmann d->last_adv_rssi, d->last_adv_flags,
6181ff5cd29fSJohan Hedberg d->last_adv_data,
6182b338d917SBrian Gix d->last_adv_data_len, NULL, 0, 0);
6183b9a6328fSJohan Hedberg
6184b9a6328fSJohan Hedberg /* If the new report will trigger a SCAN_REQ store it for
6185b9a6328fSJohan Hedberg * later merging.
6186b9a6328fSJohan Hedberg */
6187a2ec905dSAlain Michaud if (!ext_adv && (type == LE_ADV_IND ||
6188a2ec905dSAlain Michaud type == LE_ADV_SCAN_IND)) {
6189b9a6328fSJohan Hedberg store_pending_adv_report(hdev, bdaddr, bdaddr_type,
6190c70a7e4cSMarcel Holtmann rssi, flags, data, len);
6191b9a6328fSJohan Hedberg return;
6192b9a6328fSJohan Hedberg }
6193b9a6328fSJohan Hedberg
6194b9a6328fSJohan Hedberg /* The advertising reports cannot be merged, so clear
6195b9a6328fSJohan Hedberg * the pending report and send out a device found event.
6196b9a6328fSJohan Hedberg */
6197b9a6328fSJohan Hedberg clear_pending_adv_report(hdev);
61985c5b93e4SJohan Hedberg mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
6199b338d917SBrian Gix rssi, flags, data, len, NULL, 0, 0);
6200b9a6328fSJohan Hedberg return;
6201b9a6328fSJohan Hedberg }
6202b9a6328fSJohan Hedberg
6203b9a6328fSJohan Hedberg /* If we get here we've got a pending ADV_IND or ADV_SCAN_IND and
6204b9a6328fSJohan Hedberg * the new event is a SCAN_RSP. We can therefore proceed with
6205b9a6328fSJohan Hedberg * sending a merged device found event.
hci_le_adv_report_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)6206b9a6328fSJohan Hedberg */
6207b9a6328fSJohan Hedberg mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
6208c70a7e4cSMarcel Holtmann d->last_adv_addr_type, NULL, rssi, d->last_adv_flags,
6209b338d917SBrian Gix d->last_adv_data, d->last_adv_data_len, data, len, 0);
6210b9a6328fSJohan Hedberg clear_pending_adv_report(hdev);
62114af605d8SJohan Hedberg }
62124af605d8SJohan Hedberg
621395118dd4SLuiz Augusto von Dentz static void hci_le_adv_report_evt(struct hci_dev *hdev, void *data,
621495118dd4SLuiz Augusto von Dentz struct sk_buff *skb)
62159aa04c91SAndre Guedes {
621695118dd4SLuiz Augusto von Dentz struct hci_ev_le_advertising_report *ev = data;
6217b338d917SBrian Gix u64 instant = jiffies;
621847afe93cSLuiz Augusto von Dentz
621947afe93cSLuiz Augusto von Dentz if (!ev->num)
622047afe93cSLuiz Augusto von Dentz return;
62219aa04c91SAndre Guedes
6222a4790dbdSAndre Guedes hci_dev_lock(hdev);
6223a4790dbdSAndre Guedes
622447afe93cSLuiz Augusto von Dentz while (ev->num--) {
622547afe93cSLuiz Augusto von Dentz struct hci_ev_le_advertising_info *info;
62264af605d8SJohan Hedberg s8 rssi;
6227a4790dbdSAndre Guedes
622847afe93cSLuiz Augusto von Dentz info = hci_le_ev_skb_pull(hdev, skb,
622947afe93cSLuiz Augusto von Dentz HCI_EV_LE_ADVERTISING_REPORT,
623047afe93cSLuiz Augusto von Dentz sizeof(*info));
623147afe93cSLuiz Augusto von Dentz if (!info)
6232899663beSBrian Gix break;
6233899663beSBrian Gix
623447afe93cSLuiz Augusto von Dentz if (!hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_ADVERTISING_REPORT,
623547afe93cSLuiz Augusto von Dentz info->length + 1))
623647afe93cSLuiz Augusto von Dentz break;
623747afe93cSLuiz Augusto von Dentz
6238112b5090SLuiz Augusto von Dentz if (info->length <= max_adv_len(hdev)) {
623947afe93cSLuiz Augusto von Dentz rssi = info->data[info->length];
624047afe93cSLuiz Augusto von Dentz process_adv_report(hdev, info->type, &info->bdaddr,
624147afe93cSLuiz Augusto von Dentz info->bdaddr_type, NULL, 0, rssi,
6242b338d917SBrian Gix info->data, info->length, false,
6243b338d917SBrian Gix false, instant);
6244ee649346SChriz Chow } else {
ext_evt_type_to_legacy(struct hci_dev * hdev,u16 evt_type)6245ee649346SChriz Chow bt_dev_err(hdev, "Dropping invalid advertising data");
6246ee649346SChriz Chow }
62479aa04c91SAndre Guedes }
6248a4790dbdSAndre Guedes
6249a4790dbdSAndre Guedes hci_dev_unlock(hdev);
62509aa04c91SAndre Guedes }
62519aa04c91SAndre Guedes
6252657cc646SMarcel Holtmann static u8 ext_evt_type_to_legacy(struct hci_dev *hdev, u16 evt_type)
6253c215e939SJaganath Kanakkassery {
6254b2cc9761SJaganath Kanakkassery if (evt_type & LE_EXT_ADV_LEGACY_PDU) {
6255c215e939SJaganath Kanakkassery switch (evt_type) {
6256c215e939SJaganath Kanakkassery case LE_LEGACY_ADV_IND:
6257c215e939SJaganath Kanakkassery return LE_ADV_IND;
6258c215e939SJaganath Kanakkassery case LE_LEGACY_ADV_DIRECT_IND:
6259c215e939SJaganath Kanakkassery return LE_ADV_DIRECT_IND;
6260c215e939SJaganath Kanakkassery case LE_LEGACY_ADV_SCAN_IND:
6261c215e939SJaganath Kanakkassery return LE_ADV_SCAN_IND;
6262c215e939SJaganath Kanakkassery case LE_LEGACY_NONCONN_IND:
6263c215e939SJaganath Kanakkassery return LE_ADV_NONCONN_IND;
6264c215e939SJaganath Kanakkassery case LE_LEGACY_SCAN_RSP_ADV:
6265c215e939SJaganath Kanakkassery case LE_LEGACY_SCAN_RSP_ADV_SCAN:
6266c215e939SJaganath Kanakkassery return LE_ADV_SCAN_RSP;
6267c215e939SJaganath Kanakkassery }
6268c215e939SJaganath Kanakkassery
6269657cc646SMarcel Holtmann goto invalid;
6270c215e939SJaganath Kanakkassery }
6271c215e939SJaganath Kanakkassery
6272b2cc9761SJaganath Kanakkassery if (evt_type & LE_EXT_ADV_CONN_IND) {
6273b2cc9761SJaganath Kanakkassery if (evt_type & LE_EXT_ADV_DIRECT_IND)
6274b2cc9761SJaganath Kanakkassery return LE_ADV_DIRECT_IND;
6275b2cc9761SJaganath Kanakkassery
6276b2cc9761SJaganath Kanakkassery return LE_ADV_IND;
6277b2cc9761SJaganath Kanakkassery }
6278b2cc9761SJaganath Kanakkassery
6279b2cc9761SJaganath Kanakkassery if (evt_type & LE_EXT_ADV_SCAN_RSP)
6280b2cc9761SJaganath Kanakkassery return LE_ADV_SCAN_RSP;
6281b2cc9761SJaganath Kanakkassery
6282b2cc9761SJaganath Kanakkassery if (evt_type & LE_EXT_ADV_SCAN_IND)
6283b2cc9761SJaganath Kanakkassery return LE_ADV_SCAN_IND;
6284b2cc9761SJaganath Kanakkassery
6285b2cc9761SJaganath Kanakkassery if (evt_type == LE_EXT_ADV_NON_CONN_IND ||
6286b2cc9761SJaganath Kanakkassery evt_type & LE_EXT_ADV_DIRECT_IND)
6287b2cc9761SJaganath Kanakkassery return LE_ADV_NONCONN_IND;
6288b2cc9761SJaganath Kanakkassery
hci_le_ext_adv_report_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)6289657cc646SMarcel Holtmann invalid:
6290657cc646SMarcel Holtmann bt_dev_err_ratelimited(hdev, "Unknown advertising packet type: 0x%02x",
6291b2cc9761SJaganath Kanakkassery evt_type);
6292b2cc9761SJaganath Kanakkassery
6293b2cc9761SJaganath Kanakkassery return LE_ADV_INVALID;
6294b2cc9761SJaganath Kanakkassery }
6295b2cc9761SJaganath Kanakkassery
629695118dd4SLuiz Augusto von Dentz static void hci_le_ext_adv_report_evt(struct hci_dev *hdev, void *data,
629795118dd4SLuiz Augusto von Dentz struct sk_buff *skb)
6298c215e939SJaganath Kanakkassery {
629995118dd4SLuiz Augusto von Dentz struct hci_ev_le_ext_adv_report *ev = data;
6300b338d917SBrian Gix u64 instant = jiffies;
6301b48b833fSLuiz Augusto von Dentz
6302b48b833fSLuiz Augusto von Dentz if (!ev->num)
6303b48b833fSLuiz Augusto von Dentz return;
6304c215e939SJaganath Kanakkassery
6305c215e939SJaganath Kanakkassery hci_dev_lock(hdev);
6306c215e939SJaganath Kanakkassery
6307b48b833fSLuiz Augusto von Dentz while (ev->num--) {
6308b48b833fSLuiz Augusto von Dentz struct hci_ev_le_ext_adv_info *info;
6309c215e939SJaganath Kanakkassery u8 legacy_evt_type;
6310c215e939SJaganath Kanakkassery u16 evt_type;
6311c215e939SJaganath Kanakkassery
6312b48b833fSLuiz Augusto von Dentz info = hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_EXT_ADV_REPORT,
6313b48b833fSLuiz Augusto von Dentz sizeof(*info));
6314b48b833fSLuiz Augusto von Dentz if (!info)
6315b48b833fSLuiz Augusto von Dentz break;
6316b48b833fSLuiz Augusto von Dentz
6317b48b833fSLuiz Augusto von Dentz if (!hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_EXT_ADV_REPORT,
6318b48b833fSLuiz Augusto von Dentz info->length))
6319b48b833fSLuiz Augusto von Dentz break;
6320b48b833fSLuiz Augusto von Dentz
6321ad38e55eSSven Peter evt_type = __le16_to_cpu(info->type) & LE_EXT_ADV_EVT_TYPE_MASK;
6322657cc646SMarcel Holtmann legacy_evt_type = ext_evt_type_to_legacy(hdev, evt_type);
6323c215e939SJaganath Kanakkassery if (legacy_evt_type != LE_ADV_INVALID) {
6324b48b833fSLuiz Augusto von Dentz process_adv_report(hdev, legacy_evt_type, &info->bdaddr,
6325b48b833fSLuiz Augusto von Dentz info->bdaddr_type, NULL, 0,
6326b48b833fSLuiz Augusto von Dentz info->rssi, info->data, info->length,
6327b338d917SBrian Gix !(evt_type & LE_EXT_ADV_LEGACY_PDU),
hci_le_pa_term_sync(struct hci_dev * hdev,__le16 handle)6328b338d917SBrian Gix false, instant);
6329c215e939SJaganath Kanakkassery }
6330c215e939SJaganath Kanakkassery }
6331c215e939SJaganath Kanakkassery
6332c215e939SJaganath Kanakkassery hci_dev_unlock(hdev);
6333c215e939SJaganath Kanakkassery }
6334c215e939SJaganath Kanakkassery
6335eca0ae4aSLuiz Augusto von Dentz static int hci_le_pa_term_sync(struct hci_dev *hdev, __le16 handle)
6336eca0ae4aSLuiz Augusto von Dentz {
6337eca0ae4aSLuiz Augusto von Dentz struct hci_cp_le_pa_term_sync cp;
hci_le_pa_sync_estabilished_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)6338eca0ae4aSLuiz Augusto von Dentz
6339eca0ae4aSLuiz Augusto von Dentz memset(&cp, 0, sizeof(cp));
6340eca0ae4aSLuiz Augusto von Dentz cp.handle = handle;
6341eca0ae4aSLuiz Augusto von Dentz
6342eca0ae4aSLuiz Augusto von Dentz return hci_send_cmd(hdev, HCI_OP_LE_PA_TERM_SYNC, sizeof(cp), &cp);
6343eca0ae4aSLuiz Augusto von Dentz }
6344eca0ae4aSLuiz Augusto von Dentz
6345eca0ae4aSLuiz Augusto von Dentz static void hci_le_pa_sync_estabilished_evt(struct hci_dev *hdev, void *data,
6346eca0ae4aSLuiz Augusto von Dentz struct sk_buff *skb)
6347eca0ae4aSLuiz Augusto von Dentz {
6348eca0ae4aSLuiz Augusto von Dentz struct hci_ev_le_pa_sync_established *ev = data;
6349eca0ae4aSLuiz Augusto von Dentz int mask = hdev->link_mode;
6350eca0ae4aSLuiz Augusto von Dentz __u8 flags = 0;
635123417475SIulia Tanasescu struct hci_conn *pa_sync;
6352eca0ae4aSLuiz Augusto von Dentz
6353eca0ae4aSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
6354eca0ae4aSLuiz Augusto von Dentz
6355eca0ae4aSLuiz Augusto von Dentz hci_dev_lock(hdev);
6356eca0ae4aSLuiz Augusto von Dentz
6357eca0ae4aSLuiz Augusto von Dentz hci_dev_clear_flag(hdev, HCI_PA_SYNC);
6358eca0ae4aSLuiz Augusto von Dentz
6359eca0ae4aSLuiz Augusto von Dentz mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ISO_LINK, &flags);
6360fbdc4bc4SIulia Tanasescu if (!(mask & HCI_LM_ACCEPT)) {
6361eca0ae4aSLuiz Augusto von Dentz hci_le_pa_term_sync(hdev, ev->handle);
6362fbdc4bc4SIulia Tanasescu goto unlock;
6363fbdc4bc4SIulia Tanasescu }
6364eca0ae4aSLuiz Augusto von Dentz
6365fbdc4bc4SIulia Tanasescu if (!(flags & HCI_PROTO_DEFER))
6366fbdc4bc4SIulia Tanasescu goto unlock;
6367fbdc4bc4SIulia Tanasescu
636823417475SIulia Tanasescu if (ev->status) {
636923417475SIulia Tanasescu /* Add connection to indicate the failed PA sync event */
637084cb0143SZiyang Xuan pa_sync = hci_conn_add_unset(hdev, ISO_LINK, BDADDR_ANY,
6371fbdc4bc4SIulia Tanasescu HCI_ROLE_SLAVE);
6372fbdc4bc4SIulia Tanasescu
637323417475SIulia Tanasescu if (!pa_sync)
6374fbdc4bc4SIulia Tanasescu goto unlock;
6375fbdc4bc4SIulia Tanasescu
637623417475SIulia Tanasescu set_bit(HCI_CONN_PA_SYNC_FAILED, &pa_sync->flags);
6377fbdc4bc4SIulia Tanasescu
637823417475SIulia Tanasescu /* Notify iso layer */
hci_le_per_adv_report_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)637923417475SIulia Tanasescu hci_connect_cfm(pa_sync, ev->status);
638023417475SIulia Tanasescu }
6381fbdc4bc4SIulia Tanasescu
6382fbdc4bc4SIulia Tanasescu unlock:
6383eca0ae4aSLuiz Augusto von Dentz hci_dev_unlock(hdev);
6384eca0ae4aSLuiz Augusto von Dentz }
6385eca0ae4aSLuiz Augusto von Dentz
63869c082631SClaudia Draghicescu static void hci_le_per_adv_report_evt(struct hci_dev *hdev, void *data,
63879c082631SClaudia Draghicescu struct sk_buff *skb)
63889c082631SClaudia Draghicescu {
63899c082631SClaudia Draghicescu struct hci_ev_le_per_adv_report *ev = data;
63909c082631SClaudia Draghicescu int mask = hdev->link_mode;
63919c082631SClaudia Draghicescu __u8 flags = 0;
63929c082631SClaudia Draghicescu
63939c082631SClaudia Draghicescu bt_dev_dbg(hdev, "sync_handle 0x%4.4x", le16_to_cpu(ev->sync_handle));
63949c082631SClaudia Draghicescu
63959c082631SClaudia Draghicescu hci_dev_lock(hdev);
63969c082631SClaudia Draghicescu
hci_le_remote_feat_complete_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)63979c082631SClaudia Draghicescu mask |= hci_proto_connect_ind(hdev, BDADDR_ANY, ISO_LINK, &flags);
63989c082631SClaudia Draghicescu if (!(mask & HCI_LM_ACCEPT))
63999c082631SClaudia Draghicescu hci_le_pa_term_sync(hdev, ev->sync_handle);
64009c082631SClaudia Draghicescu
64019c082631SClaudia Draghicescu hci_dev_unlock(hdev);
64029c082631SClaudia Draghicescu }
64039c082631SClaudia Draghicescu
640495118dd4SLuiz Augusto von Dentz static void hci_le_remote_feat_complete_evt(struct hci_dev *hdev, void *data,
64050fe29fd1SMarcel Holtmann struct sk_buff *skb)
64060fe29fd1SMarcel Holtmann {
640795118dd4SLuiz Augusto von Dentz struct hci_ev_le_remote_feat_complete *ev = data;
64080fe29fd1SMarcel Holtmann struct hci_conn *conn;
64090fe29fd1SMarcel Holtmann
641095118dd4SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
64110fe29fd1SMarcel Holtmann
64120fe29fd1SMarcel Holtmann hci_dev_lock(hdev);
64130fe29fd1SMarcel Holtmann
64140fe29fd1SMarcel Holtmann conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
64150fe29fd1SMarcel Holtmann if (conn) {
64160fe29fd1SMarcel Holtmann if (!ev->status)
64170fe29fd1SMarcel Holtmann memcpy(conn->features[0], ev->features, 8);
64180fe29fd1SMarcel Holtmann
64190fe29fd1SMarcel Holtmann if (conn->state == BT_CONFIG) {
64200fe29fd1SMarcel Holtmann __u8 status;
64210fe29fd1SMarcel Holtmann
6422ef365da1SArchie Pusaka /* If the local controller supports peripheral-initiated
64230fe29fd1SMarcel Holtmann * features exchange, but the remote controller does
64240fe29fd1SMarcel Holtmann * not, then it is possible that the error code 0x1a
64250fe29fd1SMarcel Holtmann * for unsupported remote feature gets returned.
64260fe29fd1SMarcel Holtmann *
64270fe29fd1SMarcel Holtmann * In this specific case, allow the connection to
64280fe29fd1SMarcel Holtmann * transition into connected state and mark it as
64290fe29fd1SMarcel Holtmann * successful.
64300fe29fd1SMarcel Holtmann */
64319cd7289bSJonas Dreßler if (!conn->out && ev->status == HCI_ERROR_UNSUPPORTED_REMOTE_FEATURE &&
6432ef365da1SArchie Pusaka (hdev->le_features[0] & HCI_LE_PERIPHERAL_FEATURES))
64330fe29fd1SMarcel Holtmann status = 0x00;
64340fe29fd1SMarcel Holtmann else
64350fe29fd1SMarcel Holtmann status = ev->status;
64360fe29fd1SMarcel Holtmann
64370fe29fd1SMarcel Holtmann conn->state = BT_CONNECTED;
64380fe29fd1SMarcel Holtmann hci_connect_cfm(conn, status);
hci_le_ltk_request_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)64390fe29fd1SMarcel Holtmann hci_conn_drop(conn);
64400fe29fd1SMarcel Holtmann }
64410fe29fd1SMarcel Holtmann }
64420fe29fd1SMarcel Holtmann
64430fe29fd1SMarcel Holtmann hci_dev_unlock(hdev);
64440fe29fd1SMarcel Holtmann }
64450fe29fd1SMarcel Holtmann
644695118dd4SLuiz Augusto von Dentz static void hci_le_ltk_request_evt(struct hci_dev *hdev, void *data,
644795118dd4SLuiz Augusto von Dentz struct sk_buff *skb)
6448a7a595f6SVinicius Costa Gomes {
644995118dd4SLuiz Augusto von Dentz struct hci_ev_le_ltk_req *ev = data;
6450a7a595f6SVinicius Costa Gomes struct hci_cp_le_ltk_reply cp;
6451bea710feSVinicius Costa Gomes struct hci_cp_le_ltk_neg_reply neg;
6452a7a595f6SVinicius Costa Gomes struct hci_conn *conn;
6453c9839a11SVinicius Costa Gomes struct smp_ltk *ltk;
6454a7a595f6SVinicius Costa Gomes
645595118dd4SLuiz Augusto von Dentz bt_dev_dbg(hdev, "handle 0x%4.4x", __le16_to_cpu(ev->handle));
6456a7a595f6SVinicius Costa Gomes
6457a7a595f6SVinicius Costa Gomes hci_dev_lock(hdev);
6458a7a595f6SVinicius Costa Gomes
6459a7a595f6SVinicius Costa Gomes conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
6460bea710feSVinicius Costa Gomes if (conn == NULL)
6461bea710feSVinicius Costa Gomes goto not_found;
6462a7a595f6SVinicius Costa Gomes
6463f3a73d97SJohan Hedberg ltk = hci_find_ltk(hdev, &conn->dst, conn->dst_type, conn->role);
64645378bc56SJohan Hedberg if (!ltk)
6465bea710feSVinicius Costa Gomes goto not_found;
6466bea710feSVinicius Costa Gomes
64675378bc56SJohan Hedberg if (smp_ltk_is_sc(ltk)) {
64685378bc56SJohan Hedberg /* With SC both EDiv and Rand are set to zero */
64695378bc56SJohan Hedberg if (ev->ediv || ev->rand)
64705378bc56SJohan Hedberg goto not_found;
64715378bc56SJohan Hedberg } else {
64725378bc56SJohan Hedberg /* For non-SC keys check that EDiv and Rand match */
64735378bc56SJohan Hedberg if (ev->ediv != ltk->ediv || ev->rand != ltk->rand)
64745378bc56SJohan Hedberg goto not_found;
64755378bc56SJohan Hedberg }
64765378bc56SJohan Hedberg
64778b76ce34SJohan Hedberg memcpy(cp.ltk, ltk->val, ltk->enc_size);
64788b76ce34SJohan Hedberg memset(cp.ltk + ltk->enc_size, 0, sizeof(cp.ltk) - ltk->enc_size);
6479a7a595f6SVinicius Costa Gomes cp.handle = cpu_to_le16(conn->handle);
6480c9839a11SVinicius Costa Gomes
6481a6f7833cSJohan Hedberg conn->pending_sec_level = smp_ltk_sec_level(ltk);
6482a7a595f6SVinicius Costa Gomes
648389cbb4daSAndre Guedes conn->enc_key_size = ltk->enc_size;
6484a7a595f6SVinicius Costa Gomes
6485a7a595f6SVinicius Costa Gomes hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
6486a7a595f6SVinicius Costa Gomes
64875981a882SClaudio Takahasi /* Ref. Bluetooth Core SPEC pages 1975 and 2004. STK is a
64885981a882SClaudio Takahasi * temporary key used to encrypt a connection following
64895981a882SClaudio Takahasi * pairing. It is used during the Encrypted Session Setup to
64905981a882SClaudio Takahasi * distribute the keys. Later, security can be re-established
64915981a882SClaudio Takahasi * using a distributed LTK.
64925981a882SClaudio Takahasi */
64932ceba539SJohan Hedberg if (ltk->type == SMP_STK) {
6494fe59a05fSJohan Hedberg set_bit(HCI_CONN_STK_ENCRYPT, &conn->flags);
6495970d0f1bSJohan Hedberg list_del_rcu(<k->list);
6496970d0f1bSJohan Hedberg kfree_rcu(ltk, rcu);
6497fe59a05fSJohan Hedberg } else {
6498fe59a05fSJohan Hedberg clear_bit(HCI_CONN_STK_ENCRYPT, &conn->flags);
6499c9839a11SVinicius Costa Gomes }
6500c9839a11SVinicius Costa Gomes
6501a7a595f6SVinicius Costa Gomes hci_dev_unlock(hdev);
6502bea710feSVinicius Costa Gomes
6503bea710feSVinicius Costa Gomes return;
send_conn_param_neg_reply(struct hci_dev * hdev,u16 handle,u8 reason)6504bea710feSVinicius Costa Gomes
6505bea710feSVinicius Costa Gomes not_found:
6506bea710feSVinicius Costa Gomes neg.handle = ev->handle;
6507bea710feSVinicius Costa Gomes hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
6508bea710feSVinicius Costa Gomes hci_dev_unlock(hdev);
6509a7a595f6SVinicius Costa Gomes }
6510a7a595f6SVinicius Costa Gomes
65118e75b46aSAndre Guedes static void send_conn_param_neg_reply(struct hci_dev *hdev, u16 handle,
65128e75b46aSAndre Guedes u8 reason)
65138e75b46aSAndre Guedes {
65148e75b46aSAndre Guedes struct hci_cp_le_conn_param_req_neg_reply cp;
65158e75b46aSAndre Guedes
hci_le_remote_conn_param_req_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)65168e75b46aSAndre Guedes cp.handle = cpu_to_le16(handle);
65178e75b46aSAndre Guedes cp.reason = reason;
65188e75b46aSAndre Guedes
65198e75b46aSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY, sizeof(cp),
65208e75b46aSAndre Guedes &cp);
65218e75b46aSAndre Guedes }
65228e75b46aSAndre Guedes
652395118dd4SLuiz Augusto von Dentz static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev, void *data,
65248e75b46aSAndre Guedes struct sk_buff *skb)
65258e75b46aSAndre Guedes {
652695118dd4SLuiz Augusto von Dentz struct hci_ev_le_remote_conn_param_req *ev = data;
65278e75b46aSAndre Guedes struct hci_cp_le_conn_param_req_reply cp;
65288e75b46aSAndre Guedes struct hci_conn *hcon;
65298e75b46aSAndre Guedes u16 handle, min, max, latency, timeout;
65308e75b46aSAndre Guedes
653195118dd4SLuiz Augusto von Dentz bt_dev_dbg(hdev, "handle 0x%4.4x", __le16_to_cpu(ev->handle));
653212cfe417SLuiz Augusto von Dentz
65338e75b46aSAndre Guedes handle = le16_to_cpu(ev->handle);
65348e75b46aSAndre Guedes min = le16_to_cpu(ev->interval_min);
65358e75b46aSAndre Guedes max = le16_to_cpu(ev->interval_max);
65368e75b46aSAndre Guedes latency = le16_to_cpu(ev->latency);
65378e75b46aSAndre Guedes timeout = le16_to_cpu(ev->timeout);
65388e75b46aSAndre Guedes
65398e75b46aSAndre Guedes hcon = hci_conn_hash_lookup_handle(hdev, handle);
65408e75b46aSAndre Guedes if (!hcon || hcon->state != BT_CONNECTED)
65418e75b46aSAndre Guedes return send_conn_param_neg_reply(hdev, handle,
65428e75b46aSAndre Guedes HCI_ERROR_UNKNOWN_CONN_ID);
65438e75b46aSAndre Guedes
6544dcd646f4SKai-Heng Feng if (max > hcon->le_conn_max_interval)
6545dcd646f4SKai-Heng Feng return send_conn_param_neg_reply(hdev, handle,
6546dcd646f4SKai-Heng Feng HCI_ERROR_INVALID_LL_PARAMS);
6547dcd646f4SKai-Heng Feng
65488e75b46aSAndre Guedes if (hci_check_conn_params(min, max, latency, timeout))
65498e75b46aSAndre Guedes return send_conn_param_neg_reply(hdev, handle,
65508e75b46aSAndre Guedes HCI_ERROR_INVALID_LL_PARAMS);
65518e75b46aSAndre Guedes
655240bef302SJohan Hedberg if (hcon->role == HCI_ROLE_MASTER) {
6553348d50b8SJohan Hedberg struct hci_conn_params *params;
6554f4869e2aSJohan Hedberg u8 store_hint;
6555348d50b8SJohan Hedberg
6556348d50b8SJohan Hedberg hci_dev_lock(hdev);
6557348d50b8SJohan Hedberg
6558348d50b8SJohan Hedberg params = hci_conn_params_lookup(hdev, &hcon->dst,
6559348d50b8SJohan Hedberg hcon->dst_type);
6560348d50b8SJohan Hedberg if (params) {
6561348d50b8SJohan Hedberg params->conn_min_interval = min;
6562348d50b8SJohan Hedberg params->conn_max_interval = max;
6563348d50b8SJohan Hedberg params->conn_latency = latency;
6564348d50b8SJohan Hedberg params->supervision_timeout = timeout;
6565f4869e2aSJohan Hedberg store_hint = 0x01;
6566f4869e2aSJohan Hedberg } else {
6567f4869e2aSJohan Hedberg store_hint = 0x00;
6568348d50b8SJohan Hedberg }
6569348d50b8SJohan Hedberg
6570348d50b8SJohan Hedberg hci_dev_unlock(hdev);
6571348d50b8SJohan Hedberg
6572f4869e2aSJohan Hedberg mgmt_new_conn_param(hdev, &hcon->dst, hcon->dst_type,
6573f4869e2aSJohan Hedberg store_hint, min, max, latency, timeout);
6574348d50b8SJohan Hedberg }
6575ffb5a827SAndre Guedes
65768e75b46aSAndre Guedes cp.handle = ev->handle;
65778e75b46aSAndre Guedes cp.interval_min = ev->interval_min;
65788e75b46aSAndre Guedes cp.interval_max = ev->interval_max;
65798e75b46aSAndre Guedes cp.latency = ev->latency;
hci_le_direct_adv_report_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)65808e75b46aSAndre Guedes cp.timeout = ev->timeout;
65818e75b46aSAndre Guedes cp.min_ce_len = 0;
65828e75b46aSAndre Guedes cp.max_ce_len = 0;
65838e75b46aSAndre Guedes
65848e75b46aSAndre Guedes hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_REPLY, sizeof(cp), &cp);
65858e75b46aSAndre Guedes }
65868e75b46aSAndre Guedes
658795118dd4SLuiz Augusto von Dentz static void hci_le_direct_adv_report_evt(struct hci_dev *hdev, void *data,
65882f010b55SMarcel Holtmann struct sk_buff *skb)
65892f010b55SMarcel Holtmann {
659095118dd4SLuiz Augusto von Dentz struct hci_ev_le_direct_adv_report *ev = data;
6591b338d917SBrian Gix u64 instant = jiffies;
6592a3679649SLuiz Augusto von Dentz int i;
6593f7e0e8b2SPeilin Ye
6594a3679649SLuiz Augusto von Dentz if (!hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_DIRECT_ADV_REPORT,
6595a3679649SLuiz Augusto von Dentz flex_array_size(ev, info, ev->num)))
6596a3679649SLuiz Augusto von Dentz return;
6597a3679649SLuiz Augusto von Dentz
6598a3679649SLuiz Augusto von Dentz if (!ev->num)
6599f7e0e8b2SPeilin Ye return;
66002f010b55SMarcel Holtmann
66012f010b55SMarcel Holtmann hci_dev_lock(hdev);
66022f010b55SMarcel Holtmann
6603a3679649SLuiz Augusto von Dentz for (i = 0; i < ev->num; i++) {
6604a3679649SLuiz Augusto von Dentz struct hci_ev_le_direct_adv_info *info = &ev->info[i];
6605a3679649SLuiz Augusto von Dentz
6606a3679649SLuiz Augusto von Dentz process_adv_report(hdev, info->type, &info->bdaddr,
6607a3679649SLuiz Augusto von Dentz info->bdaddr_type, &info->direct_addr,
hci_le_phy_update_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)6608a3679649SLuiz Augusto von Dentz info->direct_addr_type, info->rssi, NULL, 0,
6609b338d917SBrian Gix false, false, instant);
6610a3679649SLuiz Augusto von Dentz }
66112f010b55SMarcel Holtmann
66122f010b55SMarcel Holtmann hci_dev_unlock(hdev);
66132f010b55SMarcel Holtmann }
66142f010b55SMarcel Holtmann
661595118dd4SLuiz Augusto von Dentz static void hci_le_phy_update_evt(struct hci_dev *hdev, void *data,
661695118dd4SLuiz Augusto von Dentz struct sk_buff *skb)
66171efd927dSLuiz Augusto von Dentz {
661895118dd4SLuiz Augusto von Dentz struct hci_ev_le_phy_update_complete *ev = data;
66191efd927dSLuiz Augusto von Dentz struct hci_conn *conn;
66201efd927dSLuiz Augusto von Dentz
662195118dd4SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
66221efd927dSLuiz Augusto von Dentz
662387df8bccSAyush Garg if (ev->status)
66241efd927dSLuiz Augusto von Dentz return;
66251efd927dSLuiz Augusto von Dentz
66261efd927dSLuiz Augusto von Dentz hci_dev_lock(hdev);
66271efd927dSLuiz Augusto von Dentz
66281efd927dSLuiz Augusto von Dentz conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
66291efd927dSLuiz Augusto von Dentz if (!conn)
66301efd927dSLuiz Augusto von Dentz goto unlock;
66311efd927dSLuiz Augusto von Dentz
hci_le_cis_estabilished_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)66321efd927dSLuiz Augusto von Dentz conn->le_tx_phy = ev->tx_phy;
66331efd927dSLuiz Augusto von Dentz conn->le_rx_phy = ev->rx_phy;
66341efd927dSLuiz Augusto von Dentz
66351efd927dSLuiz Augusto von Dentz unlock:
66361efd927dSLuiz Augusto von Dentz hci_dev_unlock(hdev);
66371efd927dSLuiz Augusto von Dentz }
66381efd927dSLuiz Augusto von Dentz
663926afbd82SLuiz Augusto von Dentz static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data,
664026afbd82SLuiz Augusto von Dentz struct sk_buff *skb)
664126afbd82SLuiz Augusto von Dentz {
664226afbd82SLuiz Augusto von Dentz struct hci_evt_le_cis_established *ev = data;
664326afbd82SLuiz Augusto von Dentz struct hci_conn *conn;
66442be22f19SLuiz Augusto von Dentz struct bt_iso_qos *qos;
66457f74563eSPauli Virtanen bool pending = false;
664626afbd82SLuiz Augusto von Dentz u16 handle = __le16_to_cpu(ev->handle);
66471ae31b35SLuiz Augusto von Dentz u32 c_sdu_interval, p_sdu_interval;
664826afbd82SLuiz Augusto von Dentz
664926afbd82SLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
665026afbd82SLuiz Augusto von Dentz
665126afbd82SLuiz Augusto von Dentz hci_dev_lock(hdev);
665226afbd82SLuiz Augusto von Dentz
665326afbd82SLuiz Augusto von Dentz conn = hci_conn_hash_lookup_handle(hdev, handle);
665426afbd82SLuiz Augusto von Dentz if (!conn) {
665526afbd82SLuiz Augusto von Dentz bt_dev_err(hdev,
665626afbd82SLuiz Augusto von Dentz "Unable to find connection with handle 0x%4.4x",
665726afbd82SLuiz Augusto von Dentz handle);
665826afbd82SLuiz Augusto von Dentz goto unlock;
665926afbd82SLuiz Augusto von Dentz }
666026afbd82SLuiz Augusto von Dentz
6661ed680f92SLuiz Augusto von Dentz if (conn->type != ISO_LINK) {
6662ed680f92SLuiz Augusto von Dentz bt_dev_err(hdev,
6663ed680f92SLuiz Augusto von Dentz "Invalid connection link type handle 0x%4.4x",
6664ed680f92SLuiz Augusto von Dentz handle);
6665ed680f92SLuiz Augusto von Dentz goto unlock;
6666ed680f92SLuiz Augusto von Dentz }
6667ed680f92SLuiz Augusto von Dentz
66682be22f19SLuiz Augusto von Dentz qos = &conn->iso_qos;
666926afbd82SLuiz Augusto von Dentz
66707f74563eSPauli Virtanen pending = test_and_clear_bit(HCI_CONN_CREATE_CIS, &conn->flags);
66717f74563eSPauli Virtanen
66721ae31b35SLuiz Augusto von Dentz /* BLUETOOTH CORE SPECIFICATION Version 5.4 | Vol 6, Part G
66731ae31b35SLuiz Augusto von Dentz * page 3075:
66741ae31b35SLuiz Augusto von Dentz * Transport_Latency_C_To_P = CIG_Sync_Delay + (FT_C_To_P) ×
66751ae31b35SLuiz Augusto von Dentz * ISO_Interval + SDU_Interval_C_To_P
66761ae31b35SLuiz Augusto von Dentz * ...
66771ae31b35SLuiz Augusto von Dentz * SDU_Interval = (CIG_Sync_Delay + (FT) x ISO_Interval) -
66781ae31b35SLuiz Augusto von Dentz * Transport_Latency
66791ae31b35SLuiz Augusto von Dentz */
66801ae31b35SLuiz Augusto von Dentz c_sdu_interval = (get_unaligned_le24(ev->cig_sync_delay) +
66811ae31b35SLuiz Augusto von Dentz (ev->c_ft * le16_to_cpu(ev->interval) * 1250)) -
66821ae31b35SLuiz Augusto von Dentz get_unaligned_le24(ev->c_latency);
66831ae31b35SLuiz Augusto von Dentz p_sdu_interval = (get_unaligned_le24(ev->cig_sync_delay) +
66841ae31b35SLuiz Augusto von Dentz (ev->p_ft * le16_to_cpu(ev->interval) * 1250)) -
66851ae31b35SLuiz Augusto von Dentz get_unaligned_le24(ev->p_latency);
668626afbd82SLuiz Augusto von Dentz
66872be22f19SLuiz Augusto von Dentz switch (conn->role) {
66882be22f19SLuiz Augusto von Dentz case HCI_ROLE_SLAVE:
66891ae31b35SLuiz Augusto von Dentz qos->ucast.in.interval = c_sdu_interval;
66901ae31b35SLuiz Augusto von Dentz qos->ucast.out.interval = p_sdu_interval;
66912be22f19SLuiz Augusto von Dentz /* Convert Transport Latency (us) to Latency (msec) */
66922be22f19SLuiz Augusto von Dentz qos->ucast.in.latency =
66932be22f19SLuiz Augusto von Dentz DIV_ROUND_CLOSEST(get_unaligned_le24(ev->c_latency),
66942be22f19SLuiz Augusto von Dentz 1000);
66952be22f19SLuiz Augusto von Dentz qos->ucast.out.latency =
66962be22f19SLuiz Augusto von Dentz DIV_ROUND_CLOSEST(get_unaligned_le24(ev->p_latency),
66972be22f19SLuiz Augusto von Dentz 1000);
66982be22f19SLuiz Augusto von Dentz qos->ucast.in.sdu = le16_to_cpu(ev->c_mtu);
66992be22f19SLuiz Augusto von Dentz qos->ucast.out.sdu = le16_to_cpu(ev->p_mtu);
67002be22f19SLuiz Augusto von Dentz qos->ucast.in.phy = ev->c_phy;
67012be22f19SLuiz Augusto von Dentz qos->ucast.out.phy = ev->p_phy;
67022be22f19SLuiz Augusto von Dentz break;
67032be22f19SLuiz Augusto von Dentz case HCI_ROLE_MASTER:
67041ae31b35SLuiz Augusto von Dentz qos->ucast.in.interval = p_sdu_interval;
67051ae31b35SLuiz Augusto von Dentz qos->ucast.out.interval = c_sdu_interval;
67062be22f19SLuiz Augusto von Dentz /* Convert Transport Latency (us) to Latency (msec) */
67072be22f19SLuiz Augusto von Dentz qos->ucast.out.latency =
67082be22f19SLuiz Augusto von Dentz DIV_ROUND_CLOSEST(get_unaligned_le24(ev->c_latency),
67092be22f19SLuiz Augusto von Dentz 1000);
67102be22f19SLuiz Augusto von Dentz qos->ucast.in.latency =
67112be22f19SLuiz Augusto von Dentz DIV_ROUND_CLOSEST(get_unaligned_le24(ev->p_latency),
67122be22f19SLuiz Augusto von Dentz 1000);
67132be22f19SLuiz Augusto von Dentz qos->ucast.out.sdu = le16_to_cpu(ev->c_mtu);
67142be22f19SLuiz Augusto von Dentz qos->ucast.in.sdu = le16_to_cpu(ev->p_mtu);
67152be22f19SLuiz Augusto von Dentz qos->ucast.out.phy = ev->c_phy;
67162be22f19SLuiz Augusto von Dentz qos->ucast.in.phy = ev->p_phy;
67172be22f19SLuiz Augusto von Dentz break;
671826afbd82SLuiz Augusto von Dentz }
671926afbd82SLuiz Augusto von Dentz
672026afbd82SLuiz Augusto von Dentz if (!ev->status) {
672126afbd82SLuiz Augusto von Dentz conn->state = BT_CONNECTED;
672226afbd82SLuiz Augusto von Dentz hci_debugfs_create_conn(conn);
672326afbd82SLuiz Augusto von Dentz hci_conn_add_sysfs(conn);
672426afbd82SLuiz Augusto von Dentz hci_iso_setup_path(conn);
672526afbd82SLuiz Augusto von Dentz goto unlock;
672626afbd82SLuiz Augusto von Dentz }
672726afbd82SLuiz Augusto von Dentz
67287f74563eSPauli Virtanen conn->state = BT_CLOSED;
672926afbd82SLuiz Augusto von Dentz hci_connect_cfm(conn, ev->status);
673026afbd82SLuiz Augusto von Dentz hci_conn_del(conn);
673126afbd82SLuiz Augusto von Dentz
hci_le_reject_cis(struct hci_dev * hdev,__le16 handle)673226afbd82SLuiz Augusto von Dentz unlock:
67337f74563eSPauli Virtanen if (pending)
67347f74563eSPauli Virtanen hci_le_create_cis_pending(hdev);
67357f74563eSPauli Virtanen
673626afbd82SLuiz Augusto von Dentz hci_dev_unlock(hdev);
673726afbd82SLuiz Augusto von Dentz }
673826afbd82SLuiz Augusto von Dentz
673926afbd82SLuiz Augusto von Dentz static void hci_le_reject_cis(struct hci_dev *hdev, __le16 handle)
674026afbd82SLuiz Augusto von Dentz {
674126afbd82SLuiz Augusto von Dentz struct hci_cp_le_reject_cis cp;
hci_le_accept_cis(struct hci_dev * hdev,__le16 handle)674226afbd82SLuiz Augusto von Dentz
674326afbd82SLuiz Augusto von Dentz memset(&cp, 0, sizeof(cp));
674426afbd82SLuiz Augusto von Dentz cp.handle = handle;
674526afbd82SLuiz Augusto von Dentz cp.reason = HCI_ERROR_REJ_BAD_ADDR;
674626afbd82SLuiz Augusto von Dentz hci_send_cmd(hdev, HCI_OP_LE_REJECT_CIS, sizeof(cp), &cp);
674726afbd82SLuiz Augusto von Dentz }
674826afbd82SLuiz Augusto von Dentz
674926afbd82SLuiz Augusto von Dentz static void hci_le_accept_cis(struct hci_dev *hdev, __le16 handle)
675026afbd82SLuiz Augusto von Dentz {
hci_le_cis_req_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)675126afbd82SLuiz Augusto von Dentz struct hci_cp_le_accept_cis cp;
675226afbd82SLuiz Augusto von Dentz
675326afbd82SLuiz Augusto von Dentz memset(&cp, 0, sizeof(cp));
675426afbd82SLuiz Augusto von Dentz cp.handle = handle;
675526afbd82SLuiz Augusto von Dentz hci_send_cmd(hdev, HCI_OP_LE_ACCEPT_CIS, sizeof(cp), &cp);
675626afbd82SLuiz Augusto von Dentz }
675726afbd82SLuiz Augusto von Dentz
675826afbd82SLuiz Augusto von Dentz static void hci_le_cis_req_evt(struct hci_dev *hdev, void *data,
675926afbd82SLuiz Augusto von Dentz struct sk_buff *skb)
676026afbd82SLuiz Augusto von Dentz {
676126afbd82SLuiz Augusto von Dentz struct hci_evt_le_cis_req *ev = data;
676226afbd82SLuiz Augusto von Dentz u16 acl_handle, cis_handle;
676326afbd82SLuiz Augusto von Dentz struct hci_conn *acl, *cis;
676426afbd82SLuiz Augusto von Dentz int mask;
676526afbd82SLuiz Augusto von Dentz __u8 flags = 0;
676626afbd82SLuiz Augusto von Dentz
676726afbd82SLuiz Augusto von Dentz acl_handle = __le16_to_cpu(ev->acl_handle);
676826afbd82SLuiz Augusto von Dentz cis_handle = __le16_to_cpu(ev->cis_handle);
676926afbd82SLuiz Augusto von Dentz
677026afbd82SLuiz Augusto von Dentz bt_dev_dbg(hdev, "acl 0x%4.4x handle 0x%4.4x cig 0x%2.2x cis 0x%2.2x",
677126afbd82SLuiz Augusto von Dentz acl_handle, cis_handle, ev->cig_id, ev->cis_id);
677226afbd82SLuiz Augusto von Dentz
677326afbd82SLuiz Augusto von Dentz hci_dev_lock(hdev);
677426afbd82SLuiz Augusto von Dentz
677526afbd82SLuiz Augusto von Dentz acl = hci_conn_hash_lookup_handle(hdev, acl_handle);
677626afbd82SLuiz Augusto von Dentz if (!acl)
677726afbd82SLuiz Augusto von Dentz goto unlock;
677826afbd82SLuiz Augusto von Dentz
677926afbd82SLuiz Augusto von Dentz mask = hci_proto_connect_ind(hdev, &acl->dst, ISO_LINK, &flags);
678026afbd82SLuiz Augusto von Dentz if (!(mask & HCI_LM_ACCEPT)) {
678126afbd82SLuiz Augusto von Dentz hci_le_reject_cis(hdev, ev->cis_handle);
678226afbd82SLuiz Augusto von Dentz goto unlock;
678326afbd82SLuiz Augusto von Dentz }
678426afbd82SLuiz Augusto von Dentz
678526afbd82SLuiz Augusto von Dentz cis = hci_conn_hash_lookup_handle(hdev, cis_handle);
678626afbd82SLuiz Augusto von Dentz if (!cis) {
678784cb0143SZiyang Xuan cis = hci_conn_add(hdev, ISO_LINK, &acl->dst, HCI_ROLE_SLAVE,
678884cb0143SZiyang Xuan cis_handle);
6789ad3f7986SSungwoo Kim if (IS_ERR(cis)) {
679026afbd82SLuiz Augusto von Dentz hci_le_reject_cis(hdev, ev->cis_handle);
679126afbd82SLuiz Augusto von Dentz goto unlock;
679226afbd82SLuiz Augusto von Dentz }
679326afbd82SLuiz Augusto von Dentz }
679426afbd82SLuiz Augusto von Dentz
67950fe8c8d0SIulia Tanasescu cis->iso_qos.ucast.cig = ev->cig_id;
67960fe8c8d0SIulia Tanasescu cis->iso_qos.ucast.cis = ev->cis_id;
679726afbd82SLuiz Augusto von Dentz
679826afbd82SLuiz Augusto von Dentz if (!(flags & HCI_PROTO_DEFER)) {
679926afbd82SLuiz Augusto von Dentz hci_le_accept_cis(hdev, ev->cis_handle);
680026afbd82SLuiz Augusto von Dentz } else {
680126afbd82SLuiz Augusto von Dentz cis->state = BT_CONNECT2;
hci_iso_term_big_sync(struct hci_dev * hdev,void * data)680226afbd82SLuiz Augusto von Dentz hci_connect_cfm(cis, 0);
680326afbd82SLuiz Augusto von Dentz }
680426afbd82SLuiz Augusto von Dentz
680526afbd82SLuiz Augusto von Dentz unlock:
680626afbd82SLuiz Augusto von Dentz hci_dev_unlock(hdev);
680726afbd82SLuiz Augusto von Dentz }
680826afbd82SLuiz Augusto von Dentz
6809acab8ff2SIulia Tanasescu static int hci_iso_term_big_sync(struct hci_dev *hdev, void *data)
hci_le_create_big_complete_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)6810acab8ff2SIulia Tanasescu {
6811acab8ff2SIulia Tanasescu u8 handle = PTR_UINT(data);
6812acab8ff2SIulia Tanasescu
6813acab8ff2SIulia Tanasescu return hci_le_terminate_big_sync(hdev, handle,
6814acab8ff2SIulia Tanasescu HCI_ERROR_LOCAL_HOST_TERM);
6815acab8ff2SIulia Tanasescu }
6816acab8ff2SIulia Tanasescu
6817eca0ae4aSLuiz Augusto von Dentz static void hci_le_create_big_complete_evt(struct hci_dev *hdev, void *data,
6818eca0ae4aSLuiz Augusto von Dentz struct sk_buff *skb)
6819eca0ae4aSLuiz Augusto von Dentz {
6820eca0ae4aSLuiz Augusto von Dentz struct hci_evt_le_create_big_complete *ev = data;
6821eca0ae4aSLuiz Augusto von Dentz struct hci_conn *conn;
682216e3b642SLuiz Augusto von Dentz __u8 i = 0;
6823eca0ae4aSLuiz Augusto von Dentz
6824eca0ae4aSLuiz Augusto von Dentz BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
6825eca0ae4aSLuiz Augusto von Dentz
6826eca0ae4aSLuiz Augusto von Dentz if (!hci_le_ev_skb_pull(hdev, skb, HCI_EVT_LE_CREATE_BIG_COMPLETE,
6827eca0ae4aSLuiz Augusto von Dentz flex_array_size(ev, bis_handle, ev->num_bis)))
6828eca0ae4aSLuiz Augusto von Dentz return;
6829eca0ae4aSLuiz Augusto von Dentz
6830eca0ae4aSLuiz Augusto von Dentz hci_dev_lock(hdev);
6831eca0ae4aSLuiz Augusto von Dentz
6832a0bfde16SIulia Tanasescu /* Connect all BISes that are bound to the BIG */
68330108132dSLuiz Augusto von Dentz while ((conn = hci_conn_hash_lookup_big_state(hdev, ev->handle,
68340108132dSLuiz Augusto von Dentz BT_BOUND))) {
68350108132dSLuiz Augusto von Dentz if (ev->status) {
68360108132dSLuiz Augusto von Dentz hci_connect_cfm(conn, ev->status);
68370108132dSLuiz Augusto von Dentz hci_conn_del(conn);
6838a0bfde16SIulia Tanasescu continue;
68390108132dSLuiz Augusto von Dentz }
6840eca0ae4aSLuiz Augusto von Dentz
684116e3b642SLuiz Augusto von Dentz if (hci_conn_set_handle(conn,
684216e3b642SLuiz Augusto von Dentz __le16_to_cpu(ev->bis_handle[i++])))
684316e3b642SLuiz Augusto von Dentz continue;
6844eca0ae4aSLuiz Augusto von Dentz
6845eca0ae4aSLuiz Augusto von Dentz conn->state = BT_CONNECTED;
6846a0bfde16SIulia Tanasescu set_bit(HCI_CONN_BIG_CREATED, &conn->flags);
6847eca0ae4aSLuiz Augusto von Dentz hci_debugfs_create_conn(conn);
6848eca0ae4aSLuiz Augusto von Dentz hci_conn_add_sysfs(conn);
6849eca0ae4aSLuiz Augusto von Dentz hci_iso_setup_path(conn);
6850eca0ae4aSLuiz Augusto von Dentz }
6851eca0ae4aSLuiz Augusto von Dentz
685216e3b642SLuiz Augusto von Dentz if (!ev->status && !i)
6853a0bfde16SIulia Tanasescu /* If no BISes have been connected for the BIG,
6854a0bfde16SIulia Tanasescu * terminate. This is in case all bound connections
6855a0bfde16SIulia Tanasescu * have been closed before the BIG creation
6856a0bfde16SIulia Tanasescu * has completed.
hci_le_big_sync_established_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)6857a0bfde16SIulia Tanasescu */
6858acab8ff2SIulia Tanasescu hci_cmd_sync_queue(hdev, hci_iso_term_big_sync,
6859acab8ff2SIulia Tanasescu UINT_PTR(ev->handle), NULL);
6860a0bfde16SIulia Tanasescu
6861eca0ae4aSLuiz Augusto von Dentz hci_dev_unlock(hdev);
6862eca0ae4aSLuiz Augusto von Dentz }
6863eca0ae4aSLuiz Augusto von Dentz
6864eca0ae4aSLuiz Augusto von Dentz static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data,
6865eca0ae4aSLuiz Augusto von Dentz struct sk_buff *skb)
6866eca0ae4aSLuiz Augusto von Dentz {
6867eca0ae4aSLuiz Augusto von Dentz struct hci_evt_le_big_sync_estabilished *ev = data;
6868eca0ae4aSLuiz Augusto von Dentz struct hci_conn *bis;
6869fbdc4bc4SIulia Tanasescu struct hci_conn *pa_sync;
6870eca0ae4aSLuiz Augusto von Dentz int i;
6871eca0ae4aSLuiz Augusto von Dentz
6872eca0ae4aSLuiz Augusto von Dentz bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
6873eca0ae4aSLuiz Augusto von Dentz
6874eca0ae4aSLuiz Augusto von Dentz if (!hci_le_ev_skb_pull(hdev, skb, HCI_EVT_LE_BIG_SYNC_ESTABILISHED,
6875eca0ae4aSLuiz Augusto von Dentz flex_array_size(ev, bis, ev->num_bis)))
6876eca0ae4aSLuiz Augusto von Dentz return;
6877eca0ae4aSLuiz Augusto von Dentz
6878eca0ae4aSLuiz Augusto von Dentz hci_dev_lock(hdev);
6879eca0ae4aSLuiz Augusto von Dentz
6880fbdc4bc4SIulia Tanasescu if (!ev->status) {
688123417475SIulia Tanasescu pa_sync = hci_conn_hash_lookup_pa_sync_big_handle(hdev, ev->handle);
6882fbdc4bc4SIulia Tanasescu if (pa_sync)
6883fbdc4bc4SIulia Tanasescu /* Also mark the BIG sync established event on the
6884fbdc4bc4SIulia Tanasescu * associated PA sync hcon
6885fbdc4bc4SIulia Tanasescu */
6886fbdc4bc4SIulia Tanasescu set_bit(HCI_CONN_BIG_SYNC, &pa_sync->flags);
6887fbdc4bc4SIulia Tanasescu }
6888fbdc4bc4SIulia Tanasescu
6889eca0ae4aSLuiz Augusto von Dentz for (i = 0; i < ev->num_bis; i++) {
6890eca0ae4aSLuiz Augusto von Dentz u16 handle = le16_to_cpu(ev->bis[i]);
6891eca0ae4aSLuiz Augusto von Dentz __le32 interval;
6892eca0ae4aSLuiz Augusto von Dentz
6893eca0ae4aSLuiz Augusto von Dentz bis = hci_conn_hash_lookup_handle(hdev, handle);
6894eca0ae4aSLuiz Augusto von Dentz if (!bis) {
689538263088SEdward Adam Davis if (handle > HCI_CONN_HANDLE_MAX) {
689638263088SEdward Adam Davis bt_dev_dbg(hdev, "ignore too large handle %u", handle);
689738263088SEdward Adam Davis continue;
689838263088SEdward Adam Davis }
6899eca0ae4aSLuiz Augusto von Dentz bis = hci_conn_add(hdev, ISO_LINK, BDADDR_ANY,
690084cb0143SZiyang Xuan HCI_ROLE_SLAVE, handle);
6901ad3f7986SSungwoo Kim if (IS_ERR(bis))
6902eca0ae4aSLuiz Augusto von Dentz continue;
6903eca0ae4aSLuiz Augusto von Dentz }
6904eca0ae4aSLuiz Augusto von Dentz
6905fbdc4bc4SIulia Tanasescu if (ev->status != 0x42)
6906fbdc4bc4SIulia Tanasescu /* Mark PA sync as established */
6907fbdc4bc4SIulia Tanasescu set_bit(HCI_CONN_PA_SYNC, &bis->flags);
6908fbdc4bc4SIulia Tanasescu
69090fe8c8d0SIulia Tanasescu bis->iso_qos.bcast.big = ev->handle;
6910eca0ae4aSLuiz Augusto von Dentz memset(&interval, 0, sizeof(interval));
6911eca0ae4aSLuiz Augusto von Dentz memcpy(&interval, ev->latency, sizeof(ev->latency));
69120fe8c8d0SIulia Tanasescu bis->iso_qos.bcast.in.interval = le32_to_cpu(interval);
6913eca0ae4aSLuiz Augusto von Dentz /* Convert ISO Interval (1.25 ms slots) to latency (ms) */
69140fe8c8d0SIulia Tanasescu bis->iso_qos.bcast.in.latency = le16_to_cpu(ev->interval) * 125 / 100;
69150fe8c8d0SIulia Tanasescu bis->iso_qos.bcast.in.sdu = le16_to_cpu(ev->max_pdu);
6916eca0ae4aSLuiz Augusto von Dentz
6917f777d882SIulia Tanasescu if (!ev->status) {
6918f777d882SIulia Tanasescu set_bit(HCI_CONN_BIG_SYNC, &bis->flags);
6919d2e4f1b1SClaudia Draghicescu hci_iso_setup_path(bis);
6920eca0ae4aSLuiz Augusto von Dentz }
6921f777d882SIulia Tanasescu }
6922f777d882SIulia Tanasescu
6923f777d882SIulia Tanasescu /* In case BIG sync failed, notify each failed connection to
6924f777d882SIulia Tanasescu * the user after all hci connections have been added
6925f777d882SIulia Tanasescu */
6926f777d882SIulia Tanasescu if (ev->status)
6927f777d882SIulia Tanasescu for (i = 0; i < ev->num_bis; i++) {
6928f777d882SIulia Tanasescu u16 handle = le16_to_cpu(ev->bis[i]);
6929f777d882SIulia Tanasescu
6930f777d882SIulia Tanasescu bis = hci_conn_hash_lookup_handle(hdev, handle);
69311f7ebb69SSungwoo Kim if (!bis)
69321f7ebb69SSungwoo Kim continue;
6933f777d882SIulia Tanasescu
hci_le_big_info_adv_report_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)6934f777d882SIulia Tanasescu set_bit(HCI_CONN_BIG_SYNC_FAILED, &bis->flags);
6935f777d882SIulia Tanasescu hci_connect_cfm(bis, ev->status);
6936f777d882SIulia Tanasescu }
6937eca0ae4aSLuiz Augusto von Dentz
6938eca0ae4aSLuiz Augusto von Dentz hci_dev_unlock(hdev);
6939eca0ae4aSLuiz Augusto von Dentz }
6940eca0ae4aSLuiz Augusto von Dentz
6941eca0ae4aSLuiz Augusto von Dentz static void hci_le_big_info_adv_report_evt(struct hci_dev *hdev, void *data,
6942eca0ae4aSLuiz Augusto von Dentz struct sk_buff *skb)
6943eca0ae4aSLuiz Augusto von Dentz {
6944eca0ae4aSLuiz Augusto von Dentz struct hci_evt_le_big_info_adv_report *ev = data;
6945eca0ae4aSLuiz Augusto von Dentz int mask = hdev->link_mode;
6946eca0ae4aSLuiz Augusto von Dentz __u8 flags = 0;
694723417475SIulia Tanasescu struct hci_conn *pa_sync;
6948eca0ae4aSLuiz Augusto von Dentz
6949eca0ae4aSLuiz Augusto von Dentz bt_dev_dbg(hdev, "sync_handle 0x%4.4x", le16_to_cpu(ev->sync_handle));
6950eca0ae4aSLuiz Augusto von Dentz
6951eca0ae4aSLuiz Augusto von Dentz hci_dev_lock(hdev);
6952eca0ae4aSLuiz Augusto von Dentz
6953eca0ae4aSLuiz Augusto von Dentz mask |= hci_proto_connect_ind(hdev, BDADDR_ANY, ISO_LINK, &flags);
695423417475SIulia Tanasescu if (!(mask & HCI_LM_ACCEPT)) {
6955eca0ae4aSLuiz Augusto von Dentz hci_le_pa_term_sync(hdev, ev->sync_handle);
695623417475SIulia Tanasescu goto unlock;
695723417475SIulia Tanasescu }
6958eca0ae4aSLuiz Augusto von Dentz
695923417475SIulia Tanasescu if (!(flags & HCI_PROTO_DEFER))
696023417475SIulia Tanasescu goto unlock;
696123417475SIulia Tanasescu
696223417475SIulia Tanasescu pa_sync = hci_conn_hash_lookup_pa_sync_handle
696323417475SIulia Tanasescu (hdev,
696423417475SIulia Tanasescu le16_to_cpu(ev->sync_handle));
696523417475SIulia Tanasescu
696623417475SIulia Tanasescu if (pa_sync)
696723417475SIulia Tanasescu goto unlock;
696823417475SIulia Tanasescu
696923417475SIulia Tanasescu /* Add connection to indicate the PA sync event */
697084cb0143SZiyang Xuan pa_sync = hci_conn_add_unset(hdev, ISO_LINK, BDADDR_ANY,
697123417475SIulia Tanasescu HCI_ROLE_SLAVE);
697223417475SIulia Tanasescu
6973ad3f7986SSungwoo Kim if (IS_ERR(pa_sync))
697423417475SIulia Tanasescu goto unlock;
697523417475SIulia Tanasescu
697623417475SIulia Tanasescu pa_sync->sync_handle = le16_to_cpu(ev->sync_handle);
697723417475SIulia Tanasescu set_bit(HCI_CONN_PA_SYNC, &pa_sync->flags);
697823417475SIulia Tanasescu
697923417475SIulia Tanasescu /* Notify iso layer */
698023417475SIulia Tanasescu hci_connect_cfm(pa_sync, 0x00);
698123417475SIulia Tanasescu
69820b3df53cSLuiz Augusto von Dentz /* Notify MGMT layer */
69830b3df53cSLuiz Augusto von Dentz mgmt_device_connected(hdev, pa_sync, NULL, 0);
69840b3df53cSLuiz Augusto von Dentz
698523417475SIulia Tanasescu unlock:
6986eca0ae4aSLuiz Augusto von Dentz hci_dev_unlock(hdev);
6987eca0ae4aSLuiz Augusto von Dentz }
6988eca0ae4aSLuiz Augusto von Dentz
698995118dd4SLuiz Augusto von Dentz #define HCI_LE_EV_VL(_op, _func, _min_len, _max_len) \
699095118dd4SLuiz Augusto von Dentz [_op] = { \
699195118dd4SLuiz Augusto von Dentz .func = _func, \
699295118dd4SLuiz Augusto von Dentz .min_len = _min_len, \
699395118dd4SLuiz Augusto von Dentz .max_len = _max_len, \
699495118dd4SLuiz Augusto von Dentz }
699595118dd4SLuiz Augusto von Dentz
699695118dd4SLuiz Augusto von Dentz #define HCI_LE_EV(_op, _func, _len) \
699795118dd4SLuiz Augusto von Dentz HCI_LE_EV_VL(_op, _func, _len, _len)
699895118dd4SLuiz Augusto von Dentz
699995118dd4SLuiz Augusto von Dentz #define HCI_LE_EV_STATUS(_op, _func) \
700095118dd4SLuiz Augusto von Dentz HCI_LE_EV(_op, _func, sizeof(struct hci_ev_status))
700195118dd4SLuiz Augusto von Dentz
700295118dd4SLuiz Augusto von Dentz /* Entries in this table shall have their position according to the subevent
700395118dd4SLuiz Augusto von Dentz * opcode they handle so the use of the macros above is recommend since it does
700495118dd4SLuiz Augusto von Dentz * attempt to initialize at its proper index using Designated Initializers that
700595118dd4SLuiz Augusto von Dentz * way events without a callback function can be ommited.
700695118dd4SLuiz Augusto von Dentz */
700795118dd4SLuiz Augusto von Dentz static const struct hci_le_ev {
700895118dd4SLuiz Augusto von Dentz void (*func)(struct hci_dev *hdev, void *data, struct sk_buff *skb);
700995118dd4SLuiz Augusto von Dentz u16 min_len;
701095118dd4SLuiz Augusto von Dentz u16 max_len;
701195118dd4SLuiz Augusto von Dentz } hci_le_ev_table[U8_MAX + 1] = {
701295118dd4SLuiz Augusto von Dentz /* [0x01 = HCI_EV_LE_CONN_COMPLETE] */
701395118dd4SLuiz Augusto von Dentz HCI_LE_EV(HCI_EV_LE_CONN_COMPLETE, hci_le_conn_complete_evt,
701495118dd4SLuiz Augusto von Dentz sizeof(struct hci_ev_le_conn_complete)),
701595118dd4SLuiz Augusto von Dentz /* [0x02 = HCI_EV_LE_ADVERTISING_REPORT] */
701695118dd4SLuiz Augusto von Dentz HCI_LE_EV_VL(HCI_EV_LE_ADVERTISING_REPORT, hci_le_adv_report_evt,
701795118dd4SLuiz Augusto von Dentz sizeof(struct hci_ev_le_advertising_report),
701895118dd4SLuiz Augusto von Dentz HCI_MAX_EVENT_SIZE),
701995118dd4SLuiz Augusto von Dentz /* [0x03 = HCI_EV_LE_CONN_UPDATE_COMPLETE] */
702095118dd4SLuiz Augusto von Dentz HCI_LE_EV(HCI_EV_LE_CONN_UPDATE_COMPLETE,
702195118dd4SLuiz Augusto von Dentz hci_le_conn_update_complete_evt,
702295118dd4SLuiz Augusto von Dentz sizeof(struct hci_ev_le_conn_update_complete)),
702395118dd4SLuiz Augusto von Dentz /* [0x04 = HCI_EV_LE_REMOTE_FEAT_COMPLETE] */
702495118dd4SLuiz Augusto von Dentz HCI_LE_EV(HCI_EV_LE_REMOTE_FEAT_COMPLETE,
702595118dd4SLuiz Augusto von Dentz hci_le_remote_feat_complete_evt,
702695118dd4SLuiz Augusto von Dentz sizeof(struct hci_ev_le_remote_feat_complete)),
702795118dd4SLuiz Augusto von Dentz /* [0x05 = HCI_EV_LE_LTK_REQ] */
702895118dd4SLuiz Augusto von Dentz HCI_LE_EV(HCI_EV_LE_LTK_REQ, hci_le_ltk_request_evt,
702995118dd4SLuiz Augusto von Dentz sizeof(struct hci_ev_le_ltk_req)),
703095118dd4SLuiz Augusto von Dentz /* [0x06 = HCI_EV_LE_REMOTE_CONN_PARAM_REQ] */
703195118dd4SLuiz Augusto von Dentz HCI_LE_EV(HCI_EV_LE_REMOTE_CONN_PARAM_REQ,
703295118dd4SLuiz Augusto von Dentz hci_le_remote_conn_param_req_evt,
703395118dd4SLuiz Augusto von Dentz sizeof(struct hci_ev_le_remote_conn_param_req)),
703495118dd4SLuiz Augusto von Dentz /* [0x0a = HCI_EV_LE_ENHANCED_CONN_COMPLETE] */
703595118dd4SLuiz Augusto von Dentz HCI_LE_EV(HCI_EV_LE_ENHANCED_CONN_COMPLETE,
703695118dd4SLuiz Augusto von Dentz hci_le_enh_conn_complete_evt,
703795118dd4SLuiz Augusto von Dentz sizeof(struct hci_ev_le_enh_conn_complete)),
703895118dd4SLuiz Augusto von Dentz /* [0x0b = HCI_EV_LE_DIRECT_ADV_REPORT] */
703995118dd4SLuiz Augusto von Dentz HCI_LE_EV_VL(HCI_EV_LE_DIRECT_ADV_REPORT, hci_le_direct_adv_report_evt,
704095118dd4SLuiz Augusto von Dentz sizeof(struct hci_ev_le_direct_adv_report),
704195118dd4SLuiz Augusto von Dentz HCI_MAX_EVENT_SIZE),
704295118dd4SLuiz Augusto von Dentz /* [0x0c = HCI_EV_LE_PHY_UPDATE_COMPLETE] */
704395118dd4SLuiz Augusto von Dentz HCI_LE_EV(HCI_EV_LE_PHY_UPDATE_COMPLETE, hci_le_phy_update_evt,
704495118dd4SLuiz Augusto von Dentz sizeof(struct hci_ev_le_phy_update_complete)),
704595118dd4SLuiz Augusto von Dentz /* [0x0d = HCI_EV_LE_EXT_ADV_REPORT] */
704695118dd4SLuiz Augusto von Dentz HCI_LE_EV_VL(HCI_EV_LE_EXT_ADV_REPORT, hci_le_ext_adv_report_evt,
704795118dd4SLuiz Augusto von Dentz sizeof(struct hci_ev_le_ext_adv_report),
704895118dd4SLuiz Augusto von Dentz HCI_MAX_EVENT_SIZE),
7049eca0ae4aSLuiz Augusto von Dentz /* [0x0e = HCI_EV_LE_PA_SYNC_ESTABLISHED] */
7050eca0ae4aSLuiz Augusto von Dentz HCI_LE_EV(HCI_EV_LE_PA_SYNC_ESTABLISHED,
7051eca0ae4aSLuiz Augusto von Dentz hci_le_pa_sync_estabilished_evt,
7052eca0ae4aSLuiz Augusto von Dentz sizeof(struct hci_ev_le_pa_sync_established)),
70539c082631SClaudia Draghicescu /* [0x0f = HCI_EV_LE_PER_ADV_REPORT] */
70549c082631SClaudia Draghicescu HCI_LE_EV_VL(HCI_EV_LE_PER_ADV_REPORT,
70559c082631SClaudia Draghicescu hci_le_per_adv_report_evt,
70569c082631SClaudia Draghicescu sizeof(struct hci_ev_le_per_adv_report),
70579c082631SClaudia Draghicescu HCI_MAX_EVENT_SIZE),
705895118dd4SLuiz Augusto von Dentz /* [0x12 = HCI_EV_LE_EXT_ADV_SET_TERM] */
705995118dd4SLuiz Augusto von Dentz HCI_LE_EV(HCI_EV_LE_EXT_ADV_SET_TERM, hci_le_ext_adv_term_evt,
706095118dd4SLuiz Augusto von Dentz sizeof(struct hci_evt_le_ext_adv_set_term)),
706126afbd82SLuiz Augusto von Dentz /* [0x19 = HCI_EVT_LE_CIS_ESTABLISHED] */
706226afbd82SLuiz Augusto von Dentz HCI_LE_EV(HCI_EVT_LE_CIS_ESTABLISHED, hci_le_cis_estabilished_evt,
706326afbd82SLuiz Augusto von Dentz sizeof(struct hci_evt_le_cis_established)),
706426afbd82SLuiz Augusto von Dentz /* [0x1a = HCI_EVT_LE_CIS_REQ] */
706526afbd82SLuiz Augusto von Dentz HCI_LE_EV(HCI_EVT_LE_CIS_REQ, hci_le_cis_req_evt,
706626afbd82SLuiz Augusto von Dentz sizeof(struct hci_evt_le_cis_req)),
7067eca0ae4aSLuiz Augusto von Dentz /* [0x1b = HCI_EVT_LE_CREATE_BIG_COMPLETE] */
7068eca0ae4aSLuiz Augusto von Dentz HCI_LE_EV_VL(HCI_EVT_LE_CREATE_BIG_COMPLETE,
7069eca0ae4aSLuiz Augusto von Dentz hci_le_create_big_complete_evt,
7070eca0ae4aSLuiz Augusto von Dentz sizeof(struct hci_evt_le_create_big_complete),
7071eca0ae4aSLuiz Augusto von Dentz HCI_MAX_EVENT_SIZE),
7072eca0ae4aSLuiz Augusto von Dentz /* [0x1d = HCI_EV_LE_BIG_SYNC_ESTABILISHED] */
7073eca0ae4aSLuiz Augusto von Dentz HCI_LE_EV_VL(HCI_EVT_LE_BIG_SYNC_ESTABILISHED,
7074eca0ae4aSLuiz Augusto von Dentz hci_le_big_sync_established_evt,
7075eca0ae4aSLuiz Augusto von Dentz sizeof(struct hci_evt_le_big_sync_estabilished),
7076eca0ae4aSLuiz Augusto von Dentz HCI_MAX_EVENT_SIZE),
hci_le_meta_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb,u16 * opcode,u8 * status,hci_req_complete_t * req_complete,hci_req_complete_skb_t * req_complete_skb)7077eca0ae4aSLuiz Augusto von Dentz /* [0x22 = HCI_EVT_LE_BIG_INFO_ADV_REPORT] */
7078eca0ae4aSLuiz Augusto von Dentz HCI_LE_EV_VL(HCI_EVT_LE_BIG_INFO_ADV_REPORT,
7079eca0ae4aSLuiz Augusto von Dentz hci_le_big_info_adv_report_evt,
7080eca0ae4aSLuiz Augusto von Dentz sizeof(struct hci_evt_le_big_info_adv_report),
7081eca0ae4aSLuiz Augusto von Dentz HCI_MAX_EVENT_SIZE),
708295118dd4SLuiz Augusto von Dentz };
708395118dd4SLuiz Augusto von Dentz
70843e54c589SLuiz Augusto von Dentz static void hci_le_meta_evt(struct hci_dev *hdev, void *data,
708585b56857SLuiz Augusto von Dentz struct sk_buff *skb, u16 *opcode, u8 *status,
708685b56857SLuiz Augusto von Dentz hci_req_complete_t *req_complete,
708785b56857SLuiz Augusto von Dentz hci_req_complete_skb_t *req_complete_skb)
7088fcd89c09SVille Tervo {
70893e54c589SLuiz Augusto von Dentz struct hci_ev_le_meta *ev = data;
709095118dd4SLuiz Augusto von Dentz const struct hci_le_ev *subev;
7091fcd89c09SVille Tervo
709295118dd4SLuiz Augusto von Dentz bt_dev_dbg(hdev, "subevent 0x%2.2x", ev->subevent);
7093fcd89c09SVille Tervo
709485b56857SLuiz Augusto von Dentz /* Only match event if command OGF is for LE */
70952af7aa66SLuiz Augusto von Dentz if (hdev->req_skb &&
70962af7aa66SLuiz Augusto von Dentz hci_opcode_ogf(hci_skb_opcode(hdev->req_skb)) == 0x08 &&
70972af7aa66SLuiz Augusto von Dentz hci_skb_event(hdev->req_skb) == ev->subevent) {
70982af7aa66SLuiz Augusto von Dentz *opcode = hci_skb_opcode(hdev->req_skb);
709985b56857SLuiz Augusto von Dentz hci_req_cmd_complete(hdev, *opcode, 0x00, req_complete,
710085b56857SLuiz Augusto von Dentz req_complete_skb);
710185b56857SLuiz Augusto von Dentz }
710285b56857SLuiz Augusto von Dentz
710395118dd4SLuiz Augusto von Dentz subev = &hci_le_ev_table[ev->subevent];
710495118dd4SLuiz Augusto von Dentz if (!subev->func)
710595118dd4SLuiz Augusto von Dentz return;
71061855d92dSMarcel Holtmann
710795118dd4SLuiz Augusto von Dentz if (skb->len < subev->min_len) {
710895118dd4SLuiz Augusto von Dentz bt_dev_err(hdev, "unexpected subevent 0x%2.2x length: %u < %u",
710995118dd4SLuiz Augusto von Dentz ev->subevent, skb->len, subev->min_len);
711095118dd4SLuiz Augusto von Dentz return;
7111fcd89c09SVille Tervo }
711295118dd4SLuiz Augusto von Dentz
711395118dd4SLuiz Augusto von Dentz /* Just warn if the length is over max_len size it still be
711495118dd4SLuiz Augusto von Dentz * possible to partially parse the event so leave to callback to
711595118dd4SLuiz Augusto von Dentz * decide if that is acceptable.
711695118dd4SLuiz Augusto von Dentz */
711795118dd4SLuiz Augusto von Dentz if (skb->len > subev->max_len)
711895118dd4SLuiz Augusto von Dentz bt_dev_warn(hdev, "unexpected subevent 0x%2.2x length: %u > %u",
711995118dd4SLuiz Augusto von Dentz ev->subevent, skb->len, subev->max_len);
hci_get_cmd_complete(struct hci_dev * hdev,u16 opcode,u8 event,struct sk_buff * skb)712095118dd4SLuiz Augusto von Dentz data = hci_le_ev_skb_pull(hdev, skb, ev->subevent, subev->min_len);
712195118dd4SLuiz Augusto von Dentz if (!data)
712295118dd4SLuiz Augusto von Dentz return;
712395118dd4SLuiz Augusto von Dentz
712495118dd4SLuiz Augusto von Dentz subev->func(hdev, data, skb);
7125fcd89c09SVille Tervo }
7126fcd89c09SVille Tervo
7127757aa0b5SJohan Hedberg static bool hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode,
7128757aa0b5SJohan Hedberg u8 event, struct sk_buff *skb)
7129757aa0b5SJohan Hedberg {
7130757aa0b5SJohan Hedberg struct hci_ev_cmd_complete *ev;
7131757aa0b5SJohan Hedberg struct hci_event_hdr *hdr;
7132757aa0b5SJohan Hedberg
7133757aa0b5SJohan Hedberg if (!skb)
7134757aa0b5SJohan Hedberg return false;
7135757aa0b5SJohan Hedberg
7136e3f3a1aeSLuiz Augusto von Dentz hdr = hci_ev_skb_pull(hdev, skb, event, sizeof(*hdr));
7137e3f3a1aeSLuiz Augusto von Dentz if (!hdr)
7138757aa0b5SJohan Hedberg return false;
7139757aa0b5SJohan Hedberg
7140757aa0b5SJohan Hedberg if (event) {
7141757aa0b5SJohan Hedberg if (hdr->evt != event)
7142757aa0b5SJohan Hedberg return false;
7143757aa0b5SJohan Hedberg return true;
7144757aa0b5SJohan Hedberg }
7145757aa0b5SJohan Hedberg
714691641b79SZheng Yongjun /* Check if request ended in Command Status - no way to retrieve
71471629db9cSJohan Hedberg * any extra parameters in this case.
71481629db9cSJohan Hedberg */
71491629db9cSJohan Hedberg if (hdr->evt == HCI_EV_CMD_STATUS)
71501629db9cSJohan Hedberg return false;
71511629db9cSJohan Hedberg
7152757aa0b5SJohan Hedberg if (hdr->evt != HCI_EV_CMD_COMPLETE) {
71532064ee33SMarcel Holtmann bt_dev_err(hdev, "last event is not cmd complete (0x%2.2x)",
71542064ee33SMarcel Holtmann hdr->evt);
7155757aa0b5SJohan Hedberg return false;
7156757aa0b5SJohan Hedberg }
7157757aa0b5SJohan Hedberg
7158e3f3a1aeSLuiz Augusto von Dentz ev = hci_cc_skb_pull(hdev, skb, opcode, sizeof(*ev));
7159e3f3a1aeSLuiz Augusto von Dentz if (!ev)
7160757aa0b5SJohan Hedberg return false;
7161757aa0b5SJohan Hedberg
7162757aa0b5SJohan Hedberg if (opcode != __le16_to_cpu(ev->opcode)) {
7163757aa0b5SJohan Hedberg BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode,
hci_store_wake_reason(struct hci_dev * hdev,u8 event,struct sk_buff * skb)7164757aa0b5SJohan Hedberg __le16_to_cpu(ev->opcode));
7165757aa0b5SJohan Hedberg return false;
7166757aa0b5SJohan Hedberg }
7167757aa0b5SJohan Hedberg
7168757aa0b5SJohan Hedberg return true;
7169757aa0b5SJohan Hedberg }
7170757aa0b5SJohan Hedberg
71712f20216cSAbhishek Pandit-Subedi static void hci_store_wake_reason(struct hci_dev *hdev, u8 event,
71722f20216cSAbhishek Pandit-Subedi struct sk_buff *skb)
71732f20216cSAbhishek Pandit-Subedi {
71742f20216cSAbhishek Pandit-Subedi struct hci_ev_le_advertising_info *adv;
71752f20216cSAbhishek Pandit-Subedi struct hci_ev_le_direct_adv_info *direct_adv;
7176b48b833fSLuiz Augusto von Dentz struct hci_ev_le_ext_adv_info *ext_adv;
71772f20216cSAbhishek Pandit-Subedi const struct hci_ev_conn_complete *conn_complete = (void *)skb->data;
71782f20216cSAbhishek Pandit-Subedi const struct hci_ev_conn_request *conn_request = (void *)skb->data;
71792f20216cSAbhishek Pandit-Subedi
71802f20216cSAbhishek Pandit-Subedi hci_dev_lock(hdev);
71812f20216cSAbhishek Pandit-Subedi
71822f20216cSAbhishek Pandit-Subedi /* If we are currently suspended and this is the first BT event seen,
71832f20216cSAbhishek Pandit-Subedi * save the wake reason associated with the event.
71842f20216cSAbhishek Pandit-Subedi */
71852f20216cSAbhishek Pandit-Subedi if (!hdev->suspended || hdev->wake_reason)
71862f20216cSAbhishek Pandit-Subedi goto unlock;
71872f20216cSAbhishek Pandit-Subedi
71882f20216cSAbhishek Pandit-Subedi /* Default to remote wake. Values for wake_reason are documented in the
71892f20216cSAbhishek Pandit-Subedi * Bluez mgmt api docs.
71902f20216cSAbhishek Pandit-Subedi */
71912f20216cSAbhishek Pandit-Subedi hdev->wake_reason = MGMT_WAKE_REASON_REMOTE_WAKE;
71922f20216cSAbhishek Pandit-Subedi
71932f20216cSAbhishek Pandit-Subedi /* Once configured for remote wakeup, we should only wake up for
71942f20216cSAbhishek Pandit-Subedi * reconnections. It's useful to see which device is waking us up so
71952f20216cSAbhishek Pandit-Subedi * keep track of the bdaddr of the connection event that woke us up.
71962f20216cSAbhishek Pandit-Subedi */
71972f20216cSAbhishek Pandit-Subedi if (event == HCI_EV_CONN_REQUEST) {
71984a913967SZijun Hu bacpy(&hdev->wake_addr, &conn_request->bdaddr);
71992f20216cSAbhishek Pandit-Subedi hdev->wake_addr_type = BDADDR_BREDR;
72002f20216cSAbhishek Pandit-Subedi } else if (event == HCI_EV_CONN_COMPLETE) {
72014a913967SZijun Hu bacpy(&hdev->wake_addr, &conn_complete->bdaddr);
72022f20216cSAbhishek Pandit-Subedi hdev->wake_addr_type = BDADDR_BREDR;
72032f20216cSAbhishek Pandit-Subedi } else if (event == HCI_EV_LE_META) {
72042f20216cSAbhishek Pandit-Subedi struct hci_ev_le_meta *le_ev = (void *)skb->data;
72052f20216cSAbhishek Pandit-Subedi u8 subevent = le_ev->subevent;
72062f20216cSAbhishek Pandit-Subedi u8 *ptr = &skb->data[sizeof(*le_ev)];
72072f20216cSAbhishek Pandit-Subedi u8 num_reports = *ptr;
72082f20216cSAbhishek Pandit-Subedi
72092f20216cSAbhishek Pandit-Subedi if ((subevent == HCI_EV_LE_ADVERTISING_REPORT ||
72102f20216cSAbhishek Pandit-Subedi subevent == HCI_EV_LE_DIRECT_ADV_REPORT ||
72112f20216cSAbhishek Pandit-Subedi subevent == HCI_EV_LE_EXT_ADV_REPORT) &&
72122f20216cSAbhishek Pandit-Subedi num_reports) {
72132f20216cSAbhishek Pandit-Subedi adv = (void *)(ptr + 1);
72142f20216cSAbhishek Pandit-Subedi direct_adv = (void *)(ptr + 1);
72152f20216cSAbhishek Pandit-Subedi ext_adv = (void *)(ptr + 1);
72162f20216cSAbhishek Pandit-Subedi
72172f20216cSAbhishek Pandit-Subedi switch (subevent) {
72182f20216cSAbhishek Pandit-Subedi case HCI_EV_LE_ADVERTISING_REPORT:
72192f20216cSAbhishek Pandit-Subedi bacpy(&hdev->wake_addr, &adv->bdaddr);
72202f20216cSAbhishek Pandit-Subedi hdev->wake_addr_type = adv->bdaddr_type;
72212f20216cSAbhishek Pandit-Subedi break;
72222f20216cSAbhishek Pandit-Subedi case HCI_EV_LE_DIRECT_ADV_REPORT:
72232f20216cSAbhishek Pandit-Subedi bacpy(&hdev->wake_addr, &direct_adv->bdaddr);
72242f20216cSAbhishek Pandit-Subedi hdev->wake_addr_type = direct_adv->bdaddr_type;
72252f20216cSAbhishek Pandit-Subedi break;
72262f20216cSAbhishek Pandit-Subedi case HCI_EV_LE_EXT_ADV_REPORT:
72272f20216cSAbhishek Pandit-Subedi bacpy(&hdev->wake_addr, &ext_adv->bdaddr);
72282f20216cSAbhishek Pandit-Subedi hdev->wake_addr_type = ext_adv->bdaddr_type;
72292f20216cSAbhishek Pandit-Subedi break;
72302f20216cSAbhishek Pandit-Subedi }
72312f20216cSAbhishek Pandit-Subedi }
72322f20216cSAbhishek Pandit-Subedi } else {
72332f20216cSAbhishek Pandit-Subedi hdev->wake_reason = MGMT_WAKE_REASON_UNEXPECTED;
72342f20216cSAbhishek Pandit-Subedi }
72352f20216cSAbhishek Pandit-Subedi
72362f20216cSAbhishek Pandit-Subedi unlock:
72372f20216cSAbhishek Pandit-Subedi hci_dev_unlock(hdev);
72382f20216cSAbhishek Pandit-Subedi }
72392f20216cSAbhishek Pandit-Subedi
72403e54c589SLuiz Augusto von Dentz #define HCI_EV_VL(_op, _func, _min_len, _max_len) \
72413e54c589SLuiz Augusto von Dentz [_op] = { \
72423e54c589SLuiz Augusto von Dentz .req = false, \
72433e54c589SLuiz Augusto von Dentz .func = _func, \
72443e54c589SLuiz Augusto von Dentz .min_len = _min_len, \
72453e54c589SLuiz Augusto von Dentz .max_len = _max_len, \
72463e54c589SLuiz Augusto von Dentz }
72473e54c589SLuiz Augusto von Dentz
72483e54c589SLuiz Augusto von Dentz #define HCI_EV(_op, _func, _len) \
72493e54c589SLuiz Augusto von Dentz HCI_EV_VL(_op, _func, _len, _len)
72503e54c589SLuiz Augusto von Dentz
72513e54c589SLuiz Augusto von Dentz #define HCI_EV_STATUS(_op, _func) \
72523e54c589SLuiz Augusto von Dentz HCI_EV(_op, _func, sizeof(struct hci_ev_status))
72533e54c589SLuiz Augusto von Dentz
72543e54c589SLuiz Augusto von Dentz #define HCI_EV_REQ_VL(_op, _func, _min_len, _max_len) \
72553e54c589SLuiz Augusto von Dentz [_op] = { \
72563e54c589SLuiz Augusto von Dentz .req = true, \
72573e54c589SLuiz Augusto von Dentz .func_req = _func, \
72583e54c589SLuiz Augusto von Dentz .min_len = _min_len, \
72593e54c589SLuiz Augusto von Dentz .max_len = _max_len, \
72603e54c589SLuiz Augusto von Dentz }
72613e54c589SLuiz Augusto von Dentz
72623e54c589SLuiz Augusto von Dentz #define HCI_EV_REQ(_op, _func, _len) \
72633e54c589SLuiz Augusto von Dentz HCI_EV_REQ_VL(_op, _func, _len, _len)
72643e54c589SLuiz Augusto von Dentz
72653e54c589SLuiz Augusto von Dentz /* Entries in this table shall have their position according to the event opcode
72663e54c589SLuiz Augusto von Dentz * they handle so the use of the macros above is recommend since it does attempt
72673e54c589SLuiz Augusto von Dentz * to initialize at its proper index using Designated Initializers that way
72683e54c589SLuiz Augusto von Dentz * events without a callback function don't have entered.
72693e54c589SLuiz Augusto von Dentz */
72703e54c589SLuiz Augusto von Dentz static const struct hci_ev {
72713e54c589SLuiz Augusto von Dentz bool req;
72723e54c589SLuiz Augusto von Dentz union {
72733e54c589SLuiz Augusto von Dentz void (*func)(struct hci_dev *hdev, void *data,
72743e54c589SLuiz Augusto von Dentz struct sk_buff *skb);
72753e54c589SLuiz Augusto von Dentz void (*func_req)(struct hci_dev *hdev, void *data,
72763e54c589SLuiz Augusto von Dentz struct sk_buff *skb, u16 *opcode, u8 *status,
72773e54c589SLuiz Augusto von Dentz hci_req_complete_t *req_complete,
72783e54c589SLuiz Augusto von Dentz hci_req_complete_skb_t *req_complete_skb);
72793e54c589SLuiz Augusto von Dentz };
72803e54c589SLuiz Augusto von Dentz u16 min_len;
72813e54c589SLuiz Augusto von Dentz u16 max_len;
72823e54c589SLuiz Augusto von Dentz } hci_ev_table[U8_MAX + 1] = {
72833e54c589SLuiz Augusto von Dentz /* [0x01 = HCI_EV_INQUIRY_COMPLETE] */
72843e54c589SLuiz Augusto von Dentz HCI_EV_STATUS(HCI_EV_INQUIRY_COMPLETE, hci_inquiry_complete_evt),
72853e54c589SLuiz Augusto von Dentz /* [0x02 = HCI_EV_INQUIRY_RESULT] */
72863e54c589SLuiz Augusto von Dentz HCI_EV_VL(HCI_EV_INQUIRY_RESULT, hci_inquiry_result_evt,
72873e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_inquiry_result), HCI_MAX_EVENT_SIZE),
72883e54c589SLuiz Augusto von Dentz /* [0x03 = HCI_EV_CONN_COMPLETE] */
72893e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_CONN_COMPLETE, hci_conn_complete_evt,
72903e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_conn_complete)),
72913e54c589SLuiz Augusto von Dentz /* [0x04 = HCI_EV_CONN_REQUEST] */
72923e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_CONN_REQUEST, hci_conn_request_evt,
72933e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_conn_request)),
72943e54c589SLuiz Augusto von Dentz /* [0x05 = HCI_EV_DISCONN_COMPLETE] */
72953e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_DISCONN_COMPLETE, hci_disconn_complete_evt,
72963e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_disconn_complete)),
72973e54c589SLuiz Augusto von Dentz /* [0x06 = HCI_EV_AUTH_COMPLETE] */
72983e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_AUTH_COMPLETE, hci_auth_complete_evt,
72993e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_auth_complete)),
73003e54c589SLuiz Augusto von Dentz /* [0x07 = HCI_EV_REMOTE_NAME] */
73013e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_REMOTE_NAME, hci_remote_name_evt,
73023e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_remote_name)),
73033e54c589SLuiz Augusto von Dentz /* [0x08 = HCI_EV_ENCRYPT_CHANGE] */
73043e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_ENCRYPT_CHANGE, hci_encrypt_change_evt,
73053e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_encrypt_change)),
73063e54c589SLuiz Augusto von Dentz /* [0x09 = HCI_EV_CHANGE_LINK_KEY_COMPLETE] */
73073e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_CHANGE_LINK_KEY_COMPLETE,
73083e54c589SLuiz Augusto von Dentz hci_change_link_key_complete_evt,
73093e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_change_link_key_complete)),
73103e54c589SLuiz Augusto von Dentz /* [0x0b = HCI_EV_REMOTE_FEATURES] */
73113e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_REMOTE_FEATURES, hci_remote_features_evt,
73123e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_remote_features)),
73133e54c589SLuiz Augusto von Dentz /* [0x0e = HCI_EV_CMD_COMPLETE] */
73143e54c589SLuiz Augusto von Dentz HCI_EV_REQ_VL(HCI_EV_CMD_COMPLETE, hci_cmd_complete_evt,
73153e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_cmd_complete), HCI_MAX_EVENT_SIZE),
73163e54c589SLuiz Augusto von Dentz /* [0x0f = HCI_EV_CMD_STATUS] */
73173e54c589SLuiz Augusto von Dentz HCI_EV_REQ(HCI_EV_CMD_STATUS, hci_cmd_status_evt,
73183e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_cmd_status)),
73193e54c589SLuiz Augusto von Dentz /* [0x10 = HCI_EV_CMD_STATUS] */
73203e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_HARDWARE_ERROR, hci_hardware_error_evt,
73213e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_hardware_error)),
73223e54c589SLuiz Augusto von Dentz /* [0x12 = HCI_EV_ROLE_CHANGE] */
73233e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_ROLE_CHANGE, hci_role_change_evt,
73243e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_role_change)),
73253e54c589SLuiz Augusto von Dentz /* [0x13 = HCI_EV_NUM_COMP_PKTS] */
73263e54c589SLuiz Augusto von Dentz HCI_EV_VL(HCI_EV_NUM_COMP_PKTS, hci_num_comp_pkts_evt,
73273e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_num_comp_pkts), HCI_MAX_EVENT_SIZE),
73283e54c589SLuiz Augusto von Dentz /* [0x14 = HCI_EV_MODE_CHANGE] */
73293e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_MODE_CHANGE, hci_mode_change_evt,
73303e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_mode_change)),
73313e54c589SLuiz Augusto von Dentz /* [0x16 = HCI_EV_PIN_CODE_REQ] */
73323e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_PIN_CODE_REQ, hci_pin_code_request_evt,
73333e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_pin_code_req)),
73343e54c589SLuiz Augusto von Dentz /* [0x17 = HCI_EV_LINK_KEY_REQ] */
73353e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_LINK_KEY_REQ, hci_link_key_request_evt,
73363e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_link_key_req)),
73373e54c589SLuiz Augusto von Dentz /* [0x18 = HCI_EV_LINK_KEY_NOTIFY] */
73383e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_LINK_KEY_NOTIFY, hci_link_key_notify_evt,
73393e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_link_key_notify)),
73403e54c589SLuiz Augusto von Dentz /* [0x1c = HCI_EV_CLOCK_OFFSET] */
73413e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_CLOCK_OFFSET, hci_clock_offset_evt,
73423e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_clock_offset)),
73433e54c589SLuiz Augusto von Dentz /* [0x1d = HCI_EV_PKT_TYPE_CHANGE] */
73443e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_PKT_TYPE_CHANGE, hci_pkt_type_change_evt,
73453e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_pkt_type_change)),
73463e54c589SLuiz Augusto von Dentz /* [0x20 = HCI_EV_PSCAN_REP_MODE] */
73473e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_PSCAN_REP_MODE, hci_pscan_rep_mode_evt,
73483e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_pscan_rep_mode)),
73493e54c589SLuiz Augusto von Dentz /* [0x22 = HCI_EV_INQUIRY_RESULT_WITH_RSSI] */
73503e54c589SLuiz Augusto von Dentz HCI_EV_VL(HCI_EV_INQUIRY_RESULT_WITH_RSSI,
73513e54c589SLuiz Augusto von Dentz hci_inquiry_result_with_rssi_evt,
73523e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_inquiry_result_rssi),
73533e54c589SLuiz Augusto von Dentz HCI_MAX_EVENT_SIZE),
73543e54c589SLuiz Augusto von Dentz /* [0x23 = HCI_EV_REMOTE_EXT_FEATURES] */
73553e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_REMOTE_EXT_FEATURES, hci_remote_ext_features_evt,
73563e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_remote_ext_features)),
73573e54c589SLuiz Augusto von Dentz /* [0x2c = HCI_EV_SYNC_CONN_COMPLETE] */
73583e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_SYNC_CONN_COMPLETE, hci_sync_conn_complete_evt,
73593e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_sync_conn_complete)),
73603e54c589SLuiz Augusto von Dentz /* [0x2d = HCI_EV_EXTENDED_INQUIRY_RESULT] */
73613e54c589SLuiz Augusto von Dentz HCI_EV_VL(HCI_EV_EXTENDED_INQUIRY_RESULT,
73623e54c589SLuiz Augusto von Dentz hci_extended_inquiry_result_evt,
73633e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_ext_inquiry_result), HCI_MAX_EVENT_SIZE),
73643e54c589SLuiz Augusto von Dentz /* [0x30 = HCI_EV_KEY_REFRESH_COMPLETE] */
73653e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_KEY_REFRESH_COMPLETE, hci_key_refresh_complete_evt,
73663e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_key_refresh_complete)),
73673e54c589SLuiz Augusto von Dentz /* [0x31 = HCI_EV_IO_CAPA_REQUEST] */
73683e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_IO_CAPA_REQUEST, hci_io_capa_request_evt,
73693e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_io_capa_request)),
73703e54c589SLuiz Augusto von Dentz /* [0x32 = HCI_EV_IO_CAPA_REPLY] */
73713e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_IO_CAPA_REPLY, hci_io_capa_reply_evt,
73723e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_io_capa_reply)),
73733e54c589SLuiz Augusto von Dentz /* [0x33 = HCI_EV_USER_CONFIRM_REQUEST] */
73743e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_USER_CONFIRM_REQUEST, hci_user_confirm_request_evt,
73753e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_user_confirm_req)),
73763e54c589SLuiz Augusto von Dentz /* [0x34 = HCI_EV_USER_PASSKEY_REQUEST] */
73773e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_USER_PASSKEY_REQUEST, hci_user_passkey_request_evt,
73783e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_user_passkey_req)),
73793e54c589SLuiz Augusto von Dentz /* [0x35 = HCI_EV_REMOTE_OOB_DATA_REQUEST] */
73803e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_REMOTE_OOB_DATA_REQUEST, hci_remote_oob_data_request_evt,
73813e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_remote_oob_data_request)),
73823e54c589SLuiz Augusto von Dentz /* [0x36 = HCI_EV_SIMPLE_PAIR_COMPLETE] */
73833e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_SIMPLE_PAIR_COMPLETE, hci_simple_pair_complete_evt,
73843e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_simple_pair_complete)),
73853e54c589SLuiz Augusto von Dentz /* [0x3b = HCI_EV_USER_PASSKEY_NOTIFY] */
73863e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_USER_PASSKEY_NOTIFY, hci_user_passkey_notify_evt,
73873e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_user_passkey_notify)),
73883e54c589SLuiz Augusto von Dentz /* [0x3c = HCI_EV_KEYPRESS_NOTIFY] */
73893e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_KEYPRESS_NOTIFY, hci_keypress_notify_evt,
73903e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_keypress_notify)),
73913e54c589SLuiz Augusto von Dentz /* [0x3d = HCI_EV_REMOTE_HOST_FEATURES] */
73923e54c589SLuiz Augusto von Dentz HCI_EV(HCI_EV_REMOTE_HOST_FEATURES, hci_remote_host_features_evt,
73933e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_remote_host_features)),
hci_event_func(struct hci_dev * hdev,u8 event,struct sk_buff * skb,u16 * opcode,u8 * status,hci_req_complete_t * req_complete,hci_req_complete_skb_t * req_complete_skb)73943e54c589SLuiz Augusto von Dentz /* [0x3e = HCI_EV_LE_META] */
739585b56857SLuiz Augusto von Dentz HCI_EV_REQ_VL(HCI_EV_LE_META, hci_le_meta_evt,
73963e54c589SLuiz Augusto von Dentz sizeof(struct hci_ev_le_meta), HCI_MAX_EVENT_SIZE),
73973e54c589SLuiz Augusto von Dentz /* [0xff = HCI_EV_VENDOR] */
7398314d8cd2SLuiz Augusto von Dentz HCI_EV_VL(HCI_EV_VENDOR, msft_vendor_evt, 0, HCI_MAX_EVENT_SIZE),
73993e54c589SLuiz Augusto von Dentz };
74003e54c589SLuiz Augusto von Dentz
74013e54c589SLuiz Augusto von Dentz static void hci_event_func(struct hci_dev *hdev, u8 event, struct sk_buff *skb,
74023e54c589SLuiz Augusto von Dentz u16 *opcode, u8 *status,
74033e54c589SLuiz Augusto von Dentz hci_req_complete_t *req_complete,
74043e54c589SLuiz Augusto von Dentz hci_req_complete_skb_t *req_complete_skb)
74053e54c589SLuiz Augusto von Dentz {
74063e54c589SLuiz Augusto von Dentz const struct hci_ev *ev = &hci_ev_table[event];
74073e54c589SLuiz Augusto von Dentz void *data;
74083e54c589SLuiz Augusto von Dentz
74093e54c589SLuiz Augusto von Dentz if (!ev->func)
74103e54c589SLuiz Augusto von Dentz return;
74113e54c589SLuiz Augusto von Dentz
74123e54c589SLuiz Augusto von Dentz if (skb->len < ev->min_len) {
74133e54c589SLuiz Augusto von Dentz bt_dev_err(hdev, "unexpected event 0x%2.2x length: %u < %u",
74143e54c589SLuiz Augusto von Dentz event, skb->len, ev->min_len);
74153e54c589SLuiz Augusto von Dentz return;
74163e54c589SLuiz Augusto von Dentz }
74173e54c589SLuiz Augusto von Dentz
74183e54c589SLuiz Augusto von Dentz /* Just warn if the length is over max_len size it still be
74193e54c589SLuiz Augusto von Dentz * possible to partially parse the event so leave to callback to
74203e54c589SLuiz Augusto von Dentz * decide if that is acceptable.
74213e54c589SLuiz Augusto von Dentz */
74223e54c589SLuiz Augusto von Dentz if (skb->len > ev->max_len)
7423314d8cd2SLuiz Augusto von Dentz bt_dev_warn_ratelimited(hdev,
7424314d8cd2SLuiz Augusto von Dentz "unexpected event 0x%2.2x length: %u > %u",
74253e54c589SLuiz Augusto von Dentz event, skb->len, ev->max_len);
74263e54c589SLuiz Augusto von Dentz
74273e54c589SLuiz Augusto von Dentz data = hci_ev_skb_pull(hdev, skb, event, ev->min_len);
74283e54c589SLuiz Augusto von Dentz if (!data)
74293e54c589SLuiz Augusto von Dentz return;
74303e54c589SLuiz Augusto von Dentz
hci_event_packet(struct hci_dev * hdev,struct sk_buff * skb)74313e54c589SLuiz Augusto von Dentz if (ev->req)
74323e54c589SLuiz Augusto von Dentz ev->func_req(hdev, data, skb, opcode, status, req_complete,
74333e54c589SLuiz Augusto von Dentz req_complete_skb);
74343e54c589SLuiz Augusto von Dentz else
74353e54c589SLuiz Augusto von Dentz ev->func(hdev, data, skb);
74363e54c589SLuiz Augusto von Dentz }
74373e54c589SLuiz Augusto von Dentz
74381da177e4SLinus Torvalds void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
74391da177e4SLinus Torvalds {
7440a9de9248SMarcel Holtmann struct hci_event_hdr *hdr = (void *) skb->data;
7441e6214487SJohan Hedberg hci_req_complete_t req_complete = NULL;
7442e6214487SJohan Hedberg hci_req_complete_skb_t req_complete_skb = NULL;
7443e6214487SJohan Hedberg struct sk_buff *orig_skb = NULL;
7444e3f3a1aeSLuiz Augusto von Dentz u8 status = 0, event, req_evt = 0;
7445e6214487SJohan Hedberg u16 opcode = HCI_OP_NOP;
74461da177e4SLinus Torvalds
7447e3f3a1aeSLuiz Augusto von Dentz if (skb->len < sizeof(*hdr)) {
7448e3f3a1aeSLuiz Augusto von Dentz bt_dev_err(hdev, "Malformed HCI Event");
7449e3f3a1aeSLuiz Augusto von Dentz goto done;
7450e3f3a1aeSLuiz Augusto von Dentz }
7451e3f3a1aeSLuiz Augusto von Dentz
7452dfe6d5c3SLuiz Augusto von Dentz kfree_skb(hdev->recv_event);
7453dfe6d5c3SLuiz Augusto von Dentz hdev->recv_event = skb_clone(skb, GFP_KERNEL);
7454dfe6d5c3SLuiz Augusto von Dentz
7455e3f3a1aeSLuiz Augusto von Dentz event = hdr->evt;
745608bb4da9SAlain Michaud if (!event) {
74573e54c589SLuiz Augusto von Dentz bt_dev_warn(hdev, "Received unexpected HCI Event 0x%2.2x",
74583e54c589SLuiz Augusto von Dentz event);
745908bb4da9SAlain Michaud goto done;
746008bb4da9SAlain Michaud }
746108bb4da9SAlain Michaud
746285b56857SLuiz Augusto von Dentz /* Only match event if command OGF is not for LE */
74632af7aa66SLuiz Augusto von Dentz if (hdev->req_skb &&
74642af7aa66SLuiz Augusto von Dentz hci_opcode_ogf(hci_skb_opcode(hdev->req_skb)) != 0x08 &&
74652af7aa66SLuiz Augusto von Dentz hci_skb_event(hdev->req_skb) == event) {
74662af7aa66SLuiz Augusto von Dentz hci_req_cmd_complete(hdev, hci_skb_opcode(hdev->req_skb),
746785b56857SLuiz Augusto von Dentz status, &req_complete, &req_complete_skb);
7468757aa0b5SJohan Hedberg req_evt = event;
746902350a72SJohan Hedberg }
747002350a72SJohan Hedberg
7471e6214487SJohan Hedberg /* If it looks like we might end up having to call
7472e6214487SJohan Hedberg * req_complete_skb, store a pristine copy of the skb since the
7473e6214487SJohan Hedberg * various handlers may modify the original one through
7474e6214487SJohan Hedberg * skb_pull() calls, etc.
7475e6214487SJohan Hedberg */
7476e6214487SJohan Hedberg if (req_complete_skb || event == HCI_EV_CMD_STATUS ||
7477e6214487SJohan Hedberg event == HCI_EV_CMD_COMPLETE)
7478e6214487SJohan Hedberg orig_skb = skb_clone(skb, GFP_KERNEL);
7479e6214487SJohan Hedberg
7480e6214487SJohan Hedberg skb_pull(skb, HCI_EVENT_HDR_SIZE);
7481e6214487SJohan Hedberg
74822f20216cSAbhishek Pandit-Subedi /* Store wake reason if we're suspended */
74832f20216cSAbhishek Pandit-Subedi hci_store_wake_reason(hdev, event, skb);
74842f20216cSAbhishek Pandit-Subedi
74853e54c589SLuiz Augusto von Dentz bt_dev_dbg(hdev, "event 0x%2.2x", event);
74861da177e4SLinus Torvalds
74873e54c589SLuiz Augusto von Dentz hci_event_func(hdev, event, skb, &opcode, &status, &req_complete,
7488e6214487SJohan Hedberg &req_complete_skb);
74891da177e4SLinus Torvalds
7490757aa0b5SJohan Hedberg if (req_complete) {
7491e6214487SJohan Hedberg req_complete(hdev, status, opcode);
7492757aa0b5SJohan Hedberg } else if (req_complete_skb) {
7493757aa0b5SJohan Hedberg if (!hci_get_cmd_complete(hdev, opcode, req_evt, orig_skb)) {
7494757aa0b5SJohan Hedberg kfree_skb(orig_skb);
7495757aa0b5SJohan Hedberg orig_skb = NULL;
7496757aa0b5SJohan Hedberg }
7497e6214487SJohan Hedberg req_complete_skb(hdev, status, opcode, orig_skb);
7498757aa0b5SJohan Hedberg }
7499e6214487SJohan Hedberg
750008bb4da9SAlain Michaud done:
7501e6214487SJohan Hedberg kfree_skb(orig_skb);
75021da177e4SLinus Torvalds kfree_skb(skb);
75031da177e4SLinus Torvalds hdev->stat.evt_rx++;
75041da177e4SLinus Torvalds }
7505