xref: /openbmc/linux/net/bluetooth/hci_event.c (revision 36db6e8484ed455bbb320d89a119378897ae991c)
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(&ltk->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