xref: /openbmc/linux/net/bluetooth/hci_event.c (revision 62e3a7cbd8e667593686399daa793218469f392f)
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 
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 
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 
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 
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
96adf1d692SSonny Sasaka 	 * Disallowed (0x0c). 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 	 */
100e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status == 0x0c && !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 
121a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
122c8992cffSLuiz Augusto von Dentz 
123c8992cffSLuiz Augusto von Dentz 	return rp->status;
1241da177e4SLinus Torvalds }
1256bd57416SMarcel Holtmann 
126c8992cffSLuiz Augusto von Dentz static u8 hci_cc_periodic_inq(struct hci_dev *hdev, void *data,
127c8992cffSLuiz Augusto von Dentz 			      struct sk_buff *skb)
1284d93483bSAndre Guedes {
129c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
130ae854a70SAndre Guedes 
131e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
132e3f3a1aeSLuiz Augusto von Dentz 
133e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
134c8992cffSLuiz Augusto von Dentz 		return rp->status;
135ae854a70SAndre Guedes 
136a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_PERIODIC_INQ);
137c8992cffSLuiz Augusto von Dentz 
138c8992cffSLuiz Augusto von Dentz 	return rp->status;
1394d93483bSAndre Guedes }
1404d93483bSAndre Guedes 
141c8992cffSLuiz Augusto von Dentz static u8 hci_cc_exit_periodic_inq(struct hci_dev *hdev, void *data,
142c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
1431da177e4SLinus Torvalds {
144c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
145a9de9248SMarcel Holtmann 
146e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
147e3f3a1aeSLuiz Augusto von Dentz 
148e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
149c8992cffSLuiz Augusto von Dentz 		return rp->status;
150a9de9248SMarcel Holtmann 
151a358dc11SMarcel Holtmann 	hci_dev_clear_flag(hdev, HCI_PERIODIC_INQ);
152ae854a70SAndre Guedes 
153a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
154c8992cffSLuiz Augusto von Dentz 
155c8992cffSLuiz Augusto von Dentz 	return rp->status;
156a9de9248SMarcel Holtmann }
157a9de9248SMarcel Holtmann 
158c8992cffSLuiz Augusto von Dentz static u8 hci_cc_remote_name_req_cancel(struct hci_dev *hdev, void *data,
159807deac2SGustavo Padovan 					struct sk_buff *skb)
160a9de9248SMarcel Holtmann {
161c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
162e3f3a1aeSLuiz Augusto von Dentz 
163e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
164c8992cffSLuiz Augusto von Dentz 
165c8992cffSLuiz Augusto von Dentz 	return rp->status;
166a9de9248SMarcel Holtmann }
167a9de9248SMarcel Holtmann 
168c8992cffSLuiz Augusto von Dentz static u8 hci_cc_role_discovery(struct hci_dev *hdev, void *data,
169c8992cffSLuiz Augusto von Dentz 				struct sk_buff *skb)
170a9de9248SMarcel Holtmann {
171c8992cffSLuiz Augusto von Dentz 	struct hci_rp_role_discovery *rp = data;
1721da177e4SLinus Torvalds 	struct hci_conn *conn;
1731da177e4SLinus Torvalds 
174e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1751da177e4SLinus Torvalds 
176a9de9248SMarcel Holtmann 	if (rp->status)
177c8992cffSLuiz Augusto von Dentz 		return rp->status;
1781da177e4SLinus Torvalds 
1791da177e4SLinus Torvalds 	hci_dev_lock(hdev);
1801da177e4SLinus Torvalds 
181a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
18240bef302SJohan Hedberg 	if (conn)
18340bef302SJohan Hedberg 		conn->role = rp->role;
1841da177e4SLinus Torvalds 
1851da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
186c8992cffSLuiz Augusto von Dentz 
187c8992cffSLuiz Augusto von Dentz 	return rp->status;
188a9de9248SMarcel Holtmann }
1891da177e4SLinus Torvalds 
190c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_link_policy(struct hci_dev *hdev, void *data,
191c8992cffSLuiz Augusto von Dentz 				  struct sk_buff *skb)
192e4e8e37cSMarcel Holtmann {
193c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_link_policy *rp = data;
194e4e8e37cSMarcel Holtmann 	struct hci_conn *conn;
195e4e8e37cSMarcel Holtmann 
196e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
197e4e8e37cSMarcel Holtmann 
198e4e8e37cSMarcel Holtmann 	if (rp->status)
199c8992cffSLuiz Augusto von Dentz 		return rp->status;
200e4e8e37cSMarcel Holtmann 
201e4e8e37cSMarcel Holtmann 	hci_dev_lock(hdev);
202e4e8e37cSMarcel Holtmann 
203e4e8e37cSMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
204e4e8e37cSMarcel Holtmann 	if (conn)
205e4e8e37cSMarcel Holtmann 		conn->link_policy = __le16_to_cpu(rp->policy);
206e4e8e37cSMarcel Holtmann 
207e4e8e37cSMarcel Holtmann 	hci_dev_unlock(hdev);
208c8992cffSLuiz Augusto von Dentz 
209c8992cffSLuiz Augusto von Dentz 	return rp->status;
210e4e8e37cSMarcel Holtmann }
211e4e8e37cSMarcel Holtmann 
212c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_link_policy(struct hci_dev *hdev, void *data,
213c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
214a9de9248SMarcel Holtmann {
215c8992cffSLuiz Augusto von Dentz 	struct hci_rp_write_link_policy *rp = data;
216a9de9248SMarcel Holtmann 	struct hci_conn *conn;
217a9de9248SMarcel Holtmann 	void *sent;
218a9de9248SMarcel Holtmann 
219e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
220a9de9248SMarcel Holtmann 
221a9de9248SMarcel Holtmann 	if (rp->status)
222c8992cffSLuiz Augusto von Dentz 		return rp->status;
223a9de9248SMarcel Holtmann 
224a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
22504837f64SMarcel Holtmann 	if (!sent)
226c8992cffSLuiz Augusto von Dentz 		return rp->status;
22704837f64SMarcel Holtmann 
22804837f64SMarcel Holtmann 	hci_dev_lock(hdev);
22904837f64SMarcel Holtmann 
230a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
231e4e8e37cSMarcel Holtmann 	if (conn)
23283985319SHarvey Harrison 		conn->link_policy = get_unaligned_le16(sent + 2);
23304837f64SMarcel Holtmann 
23404837f64SMarcel Holtmann 	hci_dev_unlock(hdev);
235c8992cffSLuiz Augusto von Dentz 
236c8992cffSLuiz Augusto von Dentz 	return rp->status;
2371da177e4SLinus Torvalds }
2381da177e4SLinus Torvalds 
239c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_def_link_policy(struct hci_dev *hdev, void *data,
240807deac2SGustavo Padovan 				      struct sk_buff *skb)
241e4e8e37cSMarcel Holtmann {
242c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_def_link_policy *rp = data;
243e3f3a1aeSLuiz Augusto von Dentz 
244e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
245e4e8e37cSMarcel Holtmann 
246e4e8e37cSMarcel Holtmann 	if (rp->status)
247c8992cffSLuiz Augusto von Dentz 		return rp->status;
248e4e8e37cSMarcel Holtmann 
249e4e8e37cSMarcel Holtmann 	hdev->link_policy = __le16_to_cpu(rp->policy);
250c8992cffSLuiz Augusto von Dentz 
251c8992cffSLuiz Augusto von Dentz 	return rp->status;
252e4e8e37cSMarcel Holtmann }
253e4e8e37cSMarcel Holtmann 
254c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_def_link_policy(struct hci_dev *hdev, void *data,
255807deac2SGustavo Padovan 				       struct sk_buff *skb)
256e4e8e37cSMarcel Holtmann {
257c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
258e4e8e37cSMarcel Holtmann 	void *sent;
259e4e8e37cSMarcel Holtmann 
260e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
261e3f3a1aeSLuiz Augusto von Dentz 
262e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
263c8992cffSLuiz Augusto von Dentz 		return rp->status;
26445296acdSMarcel Holtmann 
265e4e8e37cSMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
266e4e8e37cSMarcel Holtmann 	if (!sent)
267c8992cffSLuiz Augusto von Dentz 		return rp->status;
268e4e8e37cSMarcel Holtmann 
269e4e8e37cSMarcel Holtmann 	hdev->link_policy = get_unaligned_le16(sent);
270c8992cffSLuiz Augusto von Dentz 
271c8992cffSLuiz Augusto von Dentz 	return rp->status;
272e4e8e37cSMarcel Holtmann }
273e4e8e37cSMarcel Holtmann 
274c8992cffSLuiz Augusto von Dentz static u8 hci_cc_reset(struct hci_dev *hdev, void *data, struct sk_buff *skb)
2751da177e4SLinus Torvalds {
276c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
277e3f3a1aeSLuiz Augusto von Dentz 
278e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
279a9de9248SMarcel Holtmann 
28010572132SGustavo F. Padovan 	clear_bit(HCI_RESET, &hdev->flags);
28110572132SGustavo F. Padovan 
282e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
283c8992cffSLuiz Augusto von Dentz 		return rp->status;
2848761f9d6SMarcel Holtmann 
285a297e97cSJohan Hedberg 	/* Reset all non-persistent flags */
286eacb44dfSMarcel Holtmann 	hci_dev_clear_volatile_flags(hdev);
28769775ff6SAndre Guedes 
28839c5d970SJohan Hedberg 	hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
28939c5d970SJohan Hedberg 
290bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
291bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
2923f0f524bSJohan Hedberg 
2933f0f524bSJohan Hedberg 	memset(hdev->adv_data, 0, sizeof(hdev->adv_data));
2943f0f524bSJohan Hedberg 	hdev->adv_data_len = 0;
295f8e808bdSMarcel Holtmann 
296f8e808bdSMarcel Holtmann 	memset(hdev->scan_rsp_data, 0, sizeof(hdev->scan_rsp_data));
297f8e808bdSMarcel Holtmann 	hdev->scan_rsp_data_len = 0;
29806f5b778SMarcel Holtmann 
299533553f8SMarcel Holtmann 	hdev->le_scan_type = LE_SCAN_PASSIVE;
300533553f8SMarcel Holtmann 
30106f5b778SMarcel Holtmann 	hdev->ssp_debug_mode = 0;
302a4d5504dSMarcel Holtmann 
3033d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->le_accept_list);
304cfdb0c2dSAnkit Navik 	hci_bdaddr_list_clear(&hdev->le_resolv_list);
305c8992cffSLuiz Augusto von Dentz 
306c8992cffSLuiz Augusto von Dentz 	return rp->status;
307a9de9248SMarcel Holtmann }
308a9de9248SMarcel Holtmann 
309c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_stored_link_key(struct hci_dev *hdev, void *data,
310c2f0f979SMarcel Holtmann 				      struct sk_buff *skb)
311c2f0f979SMarcel Holtmann {
312c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_stored_link_key *rp = data;
313c2f0f979SMarcel Holtmann 	struct hci_cp_read_stored_link_key *sent;
314c2f0f979SMarcel Holtmann 
315e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
316c2f0f979SMarcel Holtmann 
317c2f0f979SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_READ_STORED_LINK_KEY);
318c2f0f979SMarcel Holtmann 	if (!sent)
319c8992cffSLuiz Augusto von Dentz 		return rp->status;
320c2f0f979SMarcel Holtmann 
321c2f0f979SMarcel Holtmann 	if (!rp->status && sent->read_all == 0x01) {
322e88422bcSLuiz Augusto von Dentz 		hdev->stored_max_keys = le16_to_cpu(rp->max_keys);
323e88422bcSLuiz Augusto von Dentz 		hdev->stored_num_keys = le16_to_cpu(rp->num_keys);
324c2f0f979SMarcel Holtmann 	}
325c8992cffSLuiz Augusto von Dentz 
326c8992cffSLuiz Augusto von Dentz 	return rp->status;
327c2f0f979SMarcel Holtmann }
328c2f0f979SMarcel Holtmann 
329c8992cffSLuiz Augusto von Dentz static u8 hci_cc_delete_stored_link_key(struct hci_dev *hdev, void *data,
330a9366120SMarcel Holtmann 					struct sk_buff *skb)
331a9366120SMarcel Holtmann {
332c8992cffSLuiz Augusto von Dentz 	struct hci_rp_delete_stored_link_key *rp = data;
333889f0346SLuiz Augusto von Dentz 	u16 num_keys;
334e3f3a1aeSLuiz Augusto von Dentz 
335e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
336a9366120SMarcel Holtmann 
337a9366120SMarcel Holtmann 	if (rp->status)
338c8992cffSLuiz Augusto von Dentz 		return rp->status;
339a9366120SMarcel Holtmann 
340889f0346SLuiz Augusto von Dentz 	num_keys = le16_to_cpu(rp->num_keys);
341889f0346SLuiz Augusto von Dentz 
342889f0346SLuiz Augusto von Dentz 	if (num_keys <= hdev->stored_num_keys)
343889f0346SLuiz Augusto von Dentz 		hdev->stored_num_keys -= num_keys;
344a9366120SMarcel Holtmann 	else
345a9366120SMarcel Holtmann 		hdev->stored_num_keys = 0;
346c8992cffSLuiz Augusto von Dentz 
347c8992cffSLuiz Augusto von Dentz 	return rp->status;
348a9366120SMarcel Holtmann }
349a9366120SMarcel Holtmann 
350c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_local_name(struct hci_dev *hdev, void *data,
351c8992cffSLuiz Augusto von Dentz 				  struct sk_buff *skb)
352a9de9248SMarcel Holtmann {
353c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
3541da177e4SLinus Torvalds 	void *sent;
3551da177e4SLinus Torvalds 
356e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
3571da177e4SLinus Torvalds 
358a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
3591da177e4SLinus Torvalds 	if (!sent)
360c8992cffSLuiz Augusto von Dentz 		return rp->status;
3611da177e4SLinus Torvalds 
36256e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
36356e5cb86SJohan Hedberg 
364d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
365e3f3a1aeSLuiz Augusto von Dentz 		mgmt_set_local_name_complete(hdev, sent, rp->status);
366e3f3a1aeSLuiz Augusto von Dentz 	else if (!rp->status)
36728cc7bdeSJohan Hedberg 		memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
368f51d5b24SJohan Hedberg 
36956e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
370c8992cffSLuiz Augusto von Dentz 
371c8992cffSLuiz Augusto von Dentz 	return rp->status;
372a9de9248SMarcel Holtmann }
373a9de9248SMarcel Holtmann 
374c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_name(struct hci_dev *hdev, void *data,
375c8992cffSLuiz Augusto von Dentz 				 struct sk_buff *skb)
376a9de9248SMarcel Holtmann {
377c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_name *rp = data;
378e3f3a1aeSLuiz Augusto von Dentz 
379e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
380a9de9248SMarcel Holtmann 
381a9de9248SMarcel Holtmann 	if (rp->status)
382c8992cffSLuiz Augusto von Dentz 		return rp->status;
383a9de9248SMarcel Holtmann 
384d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP) ||
385d7a5a11dSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_CONFIG))
3861f6c6378SJohan Hedberg 		memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
387c8992cffSLuiz Augusto von Dentz 
388c8992cffSLuiz Augusto von Dentz 	return rp->status;
389a9de9248SMarcel Holtmann }
390a9de9248SMarcel Holtmann 
391c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_auth_enable(struct hci_dev *hdev, void *data,
392c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
393a9de9248SMarcel Holtmann {
394c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
395a9de9248SMarcel Holtmann 	void *sent;
396a9de9248SMarcel Holtmann 
397e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
398a9de9248SMarcel Holtmann 
399a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
400a9de9248SMarcel Holtmann 	if (!sent)
401c8992cffSLuiz Augusto von Dentz 		return rp->status;
4021da177e4SLinus Torvalds 
4035c1a4c8fSJaganath Kanakkassery 	hci_dev_lock(hdev);
4045c1a4c8fSJaganath Kanakkassery 
405e3f3a1aeSLuiz Augusto von Dentz 	if (!rp->status) {
406a9de9248SMarcel Holtmann 		__u8 param = *((__u8 *) sent);
407a9de9248SMarcel Holtmann 
4081da177e4SLinus Torvalds 		if (param == AUTH_ENABLED)
4091da177e4SLinus Torvalds 			set_bit(HCI_AUTH, &hdev->flags);
4101da177e4SLinus Torvalds 		else
4111da177e4SLinus Torvalds 			clear_bit(HCI_AUTH, &hdev->flags);
4121da177e4SLinus Torvalds 	}
413a9de9248SMarcel Holtmann 
414d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
415e3f3a1aeSLuiz Augusto von Dentz 		mgmt_auth_enable_complete(hdev, rp->status);
4165c1a4c8fSJaganath Kanakkassery 
4175c1a4c8fSJaganath Kanakkassery 	hci_dev_unlock(hdev);
418c8992cffSLuiz Augusto von Dentz 
419c8992cffSLuiz Augusto von Dentz 	return rp->status;
420a9de9248SMarcel Holtmann }
4211da177e4SLinus Torvalds 
422c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_encrypt_mode(struct hci_dev *hdev, void *data,
423c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
424a9de9248SMarcel Holtmann {
425c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
42645296acdSMarcel Holtmann 	__u8 param;
427a9de9248SMarcel Holtmann 	void *sent;
428a9de9248SMarcel Holtmann 
429e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
430e3f3a1aeSLuiz Augusto von Dentz 
431e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
432c8992cffSLuiz Augusto von Dentz 		return rp->status;
43345296acdSMarcel Holtmann 
434a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
4351da177e4SLinus Torvalds 	if (!sent)
436c8992cffSLuiz Augusto von Dentz 		return rp->status;
4371da177e4SLinus Torvalds 
43845296acdSMarcel Holtmann 	param = *((__u8 *) sent);
439a9de9248SMarcel Holtmann 
4401da177e4SLinus Torvalds 	if (param)
4411da177e4SLinus Torvalds 		set_bit(HCI_ENCRYPT, &hdev->flags);
4421da177e4SLinus Torvalds 	else
4431da177e4SLinus Torvalds 		clear_bit(HCI_ENCRYPT, &hdev->flags);
444c8992cffSLuiz Augusto von Dentz 
445c8992cffSLuiz Augusto von Dentz 	return rp->status;
4461da177e4SLinus Torvalds }
4471da177e4SLinus Torvalds 
448c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_scan_enable(struct hci_dev *hdev, void *data,
449c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
450a9de9248SMarcel Holtmann {
451c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
45245296acdSMarcel Holtmann 	__u8 param;
453a9de9248SMarcel Holtmann 	void *sent;
4541da177e4SLinus Torvalds 
455e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
456a9de9248SMarcel Holtmann 
457a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
4581da177e4SLinus Torvalds 	if (!sent)
459c8992cffSLuiz Augusto von Dentz 		return rp->status;
4601da177e4SLinus Torvalds 
46136f7fc7eSJohan Hedberg 	param = *((__u8 *) sent);
462a9de9248SMarcel Holtmann 
46356e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
46456e5cb86SJohan Hedberg 
465e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status) {
4662d7cee58SJohan Hedberg 		hdev->discov_timeout = 0;
4672d7cee58SJohan Hedberg 		goto done;
4682d7cee58SJohan Hedberg 	}
4692d7cee58SJohan Hedberg 
470bc6d2d04SJohan Hedberg 	if (param & SCAN_INQUIRY)
4711da177e4SLinus Torvalds 		set_bit(HCI_ISCAN, &hdev->flags);
472bc6d2d04SJohan Hedberg 	else
473bc6d2d04SJohan Hedberg 		clear_bit(HCI_ISCAN, &hdev->flags);
4741da177e4SLinus Torvalds 
475031547d8SJohan Hedberg 	if (param & SCAN_PAGE)
4761da177e4SLinus Torvalds 		set_bit(HCI_PSCAN, &hdev->flags);
477bc6d2d04SJohan Hedberg 	else
478204e3990SJohan Hedberg 		clear_bit(HCI_PSCAN, &hdev->flags);
479a9de9248SMarcel Holtmann 
48036f7fc7eSJohan Hedberg done:
48156e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
482c8992cffSLuiz Augusto von Dentz 
483c8992cffSLuiz Augusto von Dentz 	return rp->status;
4841da177e4SLinus Torvalds }
4851da177e4SLinus Torvalds 
486c8992cffSLuiz Augusto von Dentz static u8 hci_cc_set_event_filter(struct hci_dev *hdev, void *data,
487c8992cffSLuiz Augusto von Dentz 				  struct sk_buff *skb)
488e5b0ad69SAbhishek Pandit-Subedi {
489c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
490e5b0ad69SAbhishek Pandit-Subedi 	struct hci_cp_set_event_filter *cp;
491e5b0ad69SAbhishek Pandit-Subedi 	void *sent;
492e5b0ad69SAbhishek Pandit-Subedi 
493e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
494e3f3a1aeSLuiz Augusto von Dentz 
495e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
496c8992cffSLuiz Augusto von Dentz 		return rp->status;
497e5b0ad69SAbhishek Pandit-Subedi 
498e5b0ad69SAbhishek Pandit-Subedi 	sent = hci_sent_cmd_data(hdev, HCI_OP_SET_EVENT_FLT);
499e5b0ad69SAbhishek Pandit-Subedi 	if (!sent)
500c8992cffSLuiz Augusto von Dentz 		return rp->status;
501e5b0ad69SAbhishek Pandit-Subedi 
502e5b0ad69SAbhishek Pandit-Subedi 	cp = (struct hci_cp_set_event_filter *)sent;
503e5b0ad69SAbhishek Pandit-Subedi 
504e5b0ad69SAbhishek Pandit-Subedi 	if (cp->flt_type == HCI_FLT_CLEAR_ALL)
505e5b0ad69SAbhishek Pandit-Subedi 		hci_dev_clear_flag(hdev, HCI_EVENT_FILTER_CONFIGURED);
506e5b0ad69SAbhishek Pandit-Subedi 	else
507e5b0ad69SAbhishek Pandit-Subedi 		hci_dev_set_flag(hdev, HCI_EVENT_FILTER_CONFIGURED);
508c8992cffSLuiz Augusto von Dentz 
509c8992cffSLuiz Augusto von Dentz 	return rp->status;
510e5b0ad69SAbhishek Pandit-Subedi }
511e5b0ad69SAbhishek Pandit-Subedi 
512c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_class_of_dev(struct hci_dev *hdev, void *data,
513c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
514a9de9248SMarcel Holtmann {
515c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_class_of_dev *rp = data;
516e3f3a1aeSLuiz Augusto von Dentz 
5177ee2ba3dSArnd Bergmann 	if (WARN_ON(!hdev))
5187ee2ba3dSArnd Bergmann 		return HCI_ERROR_UNSPECIFIED;
5197ee2ba3dSArnd Bergmann 
520e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
521a9de9248SMarcel Holtmann 
522a9de9248SMarcel Holtmann 	if (rp->status)
523c8992cffSLuiz Augusto von Dentz 		return rp->status;
524a9de9248SMarcel Holtmann 
525a9de9248SMarcel Holtmann 	memcpy(hdev->dev_class, rp->dev_class, 3);
526a9de9248SMarcel Holtmann 
527e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "class 0x%.2x%.2x%.2x", hdev->dev_class[2],
528e3f3a1aeSLuiz Augusto von Dentz 		   hdev->dev_class[1], hdev->dev_class[0]);
529c8992cffSLuiz Augusto von Dentz 
530c8992cffSLuiz Augusto von Dentz 	return rp->status;
531a9de9248SMarcel Holtmann }
532a9de9248SMarcel Holtmann 
533c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_class_of_dev(struct hci_dev *hdev, void *data,
534c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
535a9de9248SMarcel Holtmann {
536c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
537a9de9248SMarcel Holtmann 	void *sent;
538a9de9248SMarcel Holtmann 
539e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
540a9de9248SMarcel Holtmann 
541a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
542a9de9248SMarcel Holtmann 	if (!sent)
543c8992cffSLuiz Augusto von Dentz 		return rp->status;
544a9de9248SMarcel Holtmann 
5457f9a903cSMarcel Holtmann 	hci_dev_lock(hdev);
5467f9a903cSMarcel Holtmann 
547e3f3a1aeSLuiz Augusto von Dentz 	if (!rp->status)
548a9de9248SMarcel Holtmann 		memcpy(hdev->dev_class, sent, 3);
5497f9a903cSMarcel Holtmann 
550d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
551e3f3a1aeSLuiz Augusto von Dentz 		mgmt_set_class_of_dev_complete(hdev, sent, rp->status);
5527f9a903cSMarcel Holtmann 
5537f9a903cSMarcel Holtmann 	hci_dev_unlock(hdev);
554c8992cffSLuiz Augusto von Dentz 
555c8992cffSLuiz Augusto von Dentz 	return rp->status;
556a9de9248SMarcel Holtmann }
557a9de9248SMarcel Holtmann 
558c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_voice_setting(struct hci_dev *hdev, void *data,
559c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
560a9de9248SMarcel Holtmann {
561c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_voice_setting *rp = data;
562a9de9248SMarcel Holtmann 	__u16 setting;
563a9de9248SMarcel Holtmann 
564e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
565a9de9248SMarcel Holtmann 
566a9de9248SMarcel Holtmann 	if (rp->status)
567c8992cffSLuiz Augusto von Dentz 		return rp->status;
568a9de9248SMarcel Holtmann 
569a9de9248SMarcel Holtmann 	setting = __le16_to_cpu(rp->voice_setting);
570a9de9248SMarcel Holtmann 
571a9de9248SMarcel Holtmann 	if (hdev->voice_setting == setting)
572c8992cffSLuiz Augusto von Dentz 		return rp->status;
573a9de9248SMarcel Holtmann 
574a9de9248SMarcel Holtmann 	hdev->voice_setting = setting;
575a9de9248SMarcel Holtmann 
576e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "voice setting 0x%4.4x", setting);
577a9de9248SMarcel Holtmann 
5783c54711cSGustavo F. Padovan 	if (hdev->notify)
579a9de9248SMarcel Holtmann 		hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
580c8992cffSLuiz Augusto von Dentz 
581c8992cffSLuiz Augusto von Dentz 	return rp->status;
582a9de9248SMarcel Holtmann }
583a9de9248SMarcel Holtmann 
584c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_voice_setting(struct hci_dev *hdev, void *data,
5858fc9ced3SGustavo Padovan 				     struct sk_buff *skb)
586a9de9248SMarcel Holtmann {
587c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
588f383f275SMarcel Holtmann 	__u16 setting;
589a9de9248SMarcel Holtmann 	void *sent;
590a9de9248SMarcel Holtmann 
591e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
592e3f3a1aeSLuiz Augusto von Dentz 
593e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
594c8992cffSLuiz Augusto von Dentz 		return rp->status;
595f383f275SMarcel Holtmann 
596a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
597a9de9248SMarcel Holtmann 	if (!sent)
598c8992cffSLuiz Augusto von Dentz 		return rp->status;
599a9de9248SMarcel Holtmann 
600f383f275SMarcel Holtmann 	setting = get_unaligned_le16(sent);
6011da177e4SLinus Torvalds 
602f383f275SMarcel Holtmann 	if (hdev->voice_setting == setting)
603c8992cffSLuiz Augusto von Dentz 		return rp->status;
604f383f275SMarcel Holtmann 
6051da177e4SLinus Torvalds 	hdev->voice_setting = setting;
6061da177e4SLinus Torvalds 
607e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "voice setting 0x%4.4x", setting);
6081da177e4SLinus Torvalds 
6093c54711cSGustavo F. Padovan 	if (hdev->notify)
6101da177e4SLinus Torvalds 		hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
611c8992cffSLuiz Augusto von Dentz 
612c8992cffSLuiz Augusto von Dentz 	return rp->status;
6131da177e4SLinus Torvalds }
6141da177e4SLinus Torvalds 
615c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_num_supported_iac(struct hci_dev *hdev, void *data,
616b4cb9fb2SMarcel Holtmann 					struct sk_buff *skb)
617b4cb9fb2SMarcel Holtmann {
618c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_num_supported_iac *rp = data;
619e3f3a1aeSLuiz Augusto von Dentz 
620e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
621b4cb9fb2SMarcel Holtmann 
622b4cb9fb2SMarcel Holtmann 	if (rp->status)
623c8992cffSLuiz Augusto von Dentz 		return rp->status;
624b4cb9fb2SMarcel Holtmann 
625b4cb9fb2SMarcel Holtmann 	hdev->num_iac = rp->num_iac;
626b4cb9fb2SMarcel Holtmann 
627e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "num iac %d", hdev->num_iac);
628c8992cffSLuiz Augusto von Dentz 
629c8992cffSLuiz Augusto von Dentz 	return rp->status;
630b4cb9fb2SMarcel Holtmann }
631b4cb9fb2SMarcel Holtmann 
632c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_ssp_mode(struct hci_dev *hdev, void *data,
633c8992cffSLuiz Augusto von Dentz 				struct sk_buff *skb)
634333140b5SMarcel Holtmann {
635c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
6365ed8eb2fSJohan Hedberg 	struct hci_cp_write_ssp_mode *sent;
637333140b5SMarcel Holtmann 
638e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
639333140b5SMarcel Holtmann 
640333140b5SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
641333140b5SMarcel Holtmann 	if (!sent)
642c8992cffSLuiz Augusto von Dentz 		return rp->status;
643333140b5SMarcel Holtmann 
6445c1a4c8fSJaganath Kanakkassery 	hci_dev_lock(hdev);
6455c1a4c8fSJaganath Kanakkassery 
646e3f3a1aeSLuiz Augusto von Dentz 	if (!rp->status) {
6475ed8eb2fSJohan Hedberg 		if (sent->mode)
648cad718edSJohan Hedberg 			hdev->features[1][0] |= LMP_HOST_SSP;
6495ed8eb2fSJohan Hedberg 		else
650cad718edSJohan Hedberg 			hdev->features[1][0] &= ~LMP_HOST_SSP;
6515ed8eb2fSJohan Hedberg 	}
6525ed8eb2fSJohan Hedberg 
653e3f3a1aeSLuiz Augusto von Dentz 	if (!rp->status) {
6545ed8eb2fSJohan Hedberg 		if (sent->mode)
655a1536da2SMarcel Holtmann 			hci_dev_set_flag(hdev, HCI_SSP_ENABLED);
65684bde9d6SJohan Hedberg 		else
657a358dc11SMarcel Holtmann 			hci_dev_clear_flag(hdev, HCI_SSP_ENABLED);
658c0ecddc2SJohan Hedberg 	}
6595c1a4c8fSJaganath Kanakkassery 
6605c1a4c8fSJaganath Kanakkassery 	hci_dev_unlock(hdev);
661c8992cffSLuiz Augusto von Dentz 
662c8992cffSLuiz Augusto von Dentz 	return rp->status;
663333140b5SMarcel Holtmann }
664333140b5SMarcel Holtmann 
665c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_sc_support(struct hci_dev *hdev, void *data,
666c8992cffSLuiz Augusto von Dentz 				  struct sk_buff *skb)
667eac83dc6SMarcel Holtmann {
668c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
669eac83dc6SMarcel Holtmann 	struct hci_cp_write_sc_support *sent;
670eac83dc6SMarcel Holtmann 
671e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
672eac83dc6SMarcel Holtmann 
673eac83dc6SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SC_SUPPORT);
674eac83dc6SMarcel Holtmann 	if (!sent)
675c8992cffSLuiz Augusto von Dentz 		return rp->status;
676eac83dc6SMarcel Holtmann 
6775c1a4c8fSJaganath Kanakkassery 	hci_dev_lock(hdev);
6785c1a4c8fSJaganath Kanakkassery 
679e3f3a1aeSLuiz Augusto von Dentz 	if (!rp->status) {
680eac83dc6SMarcel Holtmann 		if (sent->support)
681eac83dc6SMarcel Holtmann 			hdev->features[1][0] |= LMP_HOST_SC;
682eac83dc6SMarcel Holtmann 		else
683eac83dc6SMarcel Holtmann 			hdev->features[1][0] &= ~LMP_HOST_SC;
684eac83dc6SMarcel Holtmann 	}
685eac83dc6SMarcel Holtmann 
686e3f3a1aeSLuiz Augusto von Dentz 	if (!hci_dev_test_flag(hdev, HCI_MGMT) && !rp->status) {
687eac83dc6SMarcel Holtmann 		if (sent->support)
688a1536da2SMarcel Holtmann 			hci_dev_set_flag(hdev, HCI_SC_ENABLED);
689eac83dc6SMarcel Holtmann 		else
690a358dc11SMarcel Holtmann 			hci_dev_clear_flag(hdev, HCI_SC_ENABLED);
691eac83dc6SMarcel Holtmann 	}
6925c1a4c8fSJaganath Kanakkassery 
6935c1a4c8fSJaganath Kanakkassery 	hci_dev_unlock(hdev);
694c8992cffSLuiz Augusto von Dentz 
695c8992cffSLuiz Augusto von Dentz 	return rp->status;
696eac83dc6SMarcel Holtmann }
697eac83dc6SMarcel Holtmann 
698c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_version(struct hci_dev *hdev, void *data,
699c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
700a9de9248SMarcel Holtmann {
701c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_version *rp = data;
702e3f3a1aeSLuiz Augusto von Dentz 
703e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
7041143e5a6SMarcel Holtmann 
705a9de9248SMarcel Holtmann 	if (rp->status)
706c8992cffSLuiz Augusto von Dentz 		return rp->status;
7071143e5a6SMarcel Holtmann 
708d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP) ||
709d7a5a11dSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_CONFIG)) {
710a9de9248SMarcel Holtmann 		hdev->hci_ver = rp->hci_ver;
711e4e8e37cSMarcel Holtmann 		hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
712d5859e22SJohan Hedberg 		hdev->lmp_ver = rp->lmp_ver;
713e4e8e37cSMarcel Holtmann 		hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
714d5859e22SJohan Hedberg 		hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
7150d5551f5SMarcel Holtmann 	}
716c8992cffSLuiz Augusto von Dentz 
717c8992cffSLuiz Augusto von Dentz 	return rp->status;
718d5859e22SJohan Hedberg }
719d5859e22SJohan Hedberg 
720278d933eSBrian Gix static u8 hci_cc_read_enc_key_size(struct hci_dev *hdev, void *data,
721278d933eSBrian Gix 				   struct sk_buff *skb)
722278d933eSBrian Gix {
723278d933eSBrian Gix 	struct hci_rp_read_enc_key_size *rp = data;
724278d933eSBrian Gix 	struct hci_conn *conn;
725278d933eSBrian Gix 	u16 handle;
726278d933eSBrian Gix 	u8 status = rp->status;
727278d933eSBrian Gix 
728278d933eSBrian Gix 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
729278d933eSBrian Gix 
730278d933eSBrian Gix 	handle = le16_to_cpu(rp->handle);
731278d933eSBrian Gix 
732278d933eSBrian Gix 	hci_dev_lock(hdev);
733278d933eSBrian Gix 
734278d933eSBrian Gix 	conn = hci_conn_hash_lookup_handle(hdev, handle);
735278d933eSBrian Gix 	if (!conn) {
736278d933eSBrian Gix 		status = 0xFF;
737278d933eSBrian Gix 		goto done;
738278d933eSBrian Gix 	}
739278d933eSBrian Gix 
740278d933eSBrian Gix 	/* While unexpected, the read_enc_key_size command may fail. The most
741278d933eSBrian Gix 	 * secure approach is to then assume the key size is 0 to force a
742278d933eSBrian Gix 	 * disconnection.
743278d933eSBrian Gix 	 */
744278d933eSBrian Gix 	if (status) {
745278d933eSBrian Gix 		bt_dev_err(hdev, "failed to read key size for handle %u",
746278d933eSBrian Gix 			   handle);
747278d933eSBrian Gix 		conn->enc_key_size = 0;
748278d933eSBrian Gix 	} else {
749278d933eSBrian Gix 		conn->enc_key_size = rp->key_size;
750278d933eSBrian Gix 		status = 0;
75134c032a7SAlex Lu 
75234c032a7SAlex Lu 		if (conn->enc_key_size < hdev->min_enc_key_size) {
75334c032a7SAlex Lu 			/* As slave role, the conn->state has been set to
75434c032a7SAlex Lu 			 * BT_CONNECTED and l2cap conn req might not be received
75534c032a7SAlex Lu 			 * yet, at this moment the l2cap layer almost does
75634c032a7SAlex Lu 			 * nothing with the non-zero status.
75734c032a7SAlex Lu 			 * So we also clear encrypt related bits, and then the
75834c032a7SAlex Lu 			 * handler of l2cap conn req will get the right secure
75934c032a7SAlex Lu 			 * state at a later time.
76034c032a7SAlex Lu 			 */
76134c032a7SAlex Lu 			status = HCI_ERROR_AUTH_FAILURE;
76234c032a7SAlex Lu 			clear_bit(HCI_CONN_ENCRYPT, &conn->flags);
76334c032a7SAlex Lu 			clear_bit(HCI_CONN_AES_CCM, &conn->flags);
76434c032a7SAlex Lu 		}
765278d933eSBrian Gix 	}
766278d933eSBrian Gix 
76734c032a7SAlex Lu 	hci_encrypt_cfm(conn, status);
768278d933eSBrian Gix 
769278d933eSBrian Gix done:
770278d933eSBrian Gix 	hci_dev_unlock(hdev);
771278d933eSBrian Gix 
772278d933eSBrian Gix 	return status;
773278d933eSBrian Gix }
774278d933eSBrian Gix 
775c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_commands(struct hci_dev *hdev, void *data,
7768fc9ced3SGustavo Padovan 				     struct sk_buff *skb)
777a9de9248SMarcel Holtmann {
778c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_commands *rp = data;
779e3f3a1aeSLuiz Augusto von Dentz 
780e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
781a9de9248SMarcel Holtmann 
7826a070e6eSMarcel Holtmann 	if (rp->status)
783c8992cffSLuiz Augusto von Dentz 		return rp->status;
7846a070e6eSMarcel Holtmann 
785d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP) ||
786d7a5a11dSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_CONFIG))
787a9de9248SMarcel Holtmann 		memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
788c8992cffSLuiz Augusto von Dentz 
789c8992cffSLuiz Augusto von Dentz 	return rp->status;
790a9de9248SMarcel Holtmann }
791a9de9248SMarcel Holtmann 
792c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_auth_payload_timeout(struct hci_dev *hdev, void *data,
793302975cbSSpoorthi Ravishankar Koppad 					   struct sk_buff *skb)
794302975cbSSpoorthi Ravishankar Koppad {
795c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_auth_payload_to *rp = data;
796302975cbSSpoorthi Ravishankar Koppad 	struct hci_conn *conn;
797302975cbSSpoorthi Ravishankar Koppad 
798e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
799302975cbSSpoorthi Ravishankar Koppad 
800302975cbSSpoorthi Ravishankar Koppad 	if (rp->status)
801c8992cffSLuiz Augusto von Dentz 		return rp->status;
802302975cbSSpoorthi Ravishankar Koppad 
803302975cbSSpoorthi Ravishankar Koppad 	hci_dev_lock(hdev);
804302975cbSSpoorthi Ravishankar Koppad 
805302975cbSSpoorthi Ravishankar Koppad 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
806302975cbSSpoorthi Ravishankar Koppad 	if (conn)
807302975cbSSpoorthi Ravishankar Koppad 		conn->auth_payload_timeout = __le16_to_cpu(rp->timeout);
808302975cbSSpoorthi Ravishankar Koppad 
809302975cbSSpoorthi Ravishankar Koppad 	hci_dev_unlock(hdev);
810c8992cffSLuiz Augusto von Dentz 
811c8992cffSLuiz Augusto von Dentz 	return rp->status;
812302975cbSSpoorthi Ravishankar Koppad }
813302975cbSSpoorthi Ravishankar Koppad 
814c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_auth_payload_timeout(struct hci_dev *hdev, void *data,
815302975cbSSpoorthi Ravishankar Koppad 					    struct sk_buff *skb)
816302975cbSSpoorthi Ravishankar Koppad {
817c8992cffSLuiz Augusto von Dentz 	struct hci_rp_write_auth_payload_to *rp = data;
818302975cbSSpoorthi Ravishankar Koppad 	struct hci_conn *conn;
819302975cbSSpoorthi Ravishankar Koppad 	void *sent;
820302975cbSSpoorthi Ravishankar Koppad 
821e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
822302975cbSSpoorthi Ravishankar Koppad 
823302975cbSSpoorthi Ravishankar Koppad 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_PAYLOAD_TO);
824302975cbSSpoorthi Ravishankar Koppad 	if (!sent)
825c8992cffSLuiz Augusto von Dentz 		return rp->status;
826302975cbSSpoorthi Ravishankar Koppad 
827302975cbSSpoorthi Ravishankar Koppad 	hci_dev_lock(hdev);
828302975cbSSpoorthi Ravishankar Koppad 
829302975cbSSpoorthi Ravishankar Koppad 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
8307aca0ac4SLuiz Augusto von Dentz 	if (!conn) {
8317aca0ac4SLuiz Augusto von Dentz 		rp->status = 0xff;
8327aca0ac4SLuiz Augusto von Dentz 		goto unlock;
8337aca0ac4SLuiz Augusto von Dentz 	}
8347aca0ac4SLuiz Augusto von Dentz 
8357aca0ac4SLuiz Augusto von Dentz 	if (!rp->status)
836302975cbSSpoorthi Ravishankar Koppad 		conn->auth_payload_timeout = get_unaligned_le16(sent + 2);
837302975cbSSpoorthi Ravishankar Koppad 
8387aca0ac4SLuiz Augusto von Dentz unlock:
839302975cbSSpoorthi Ravishankar Koppad 	hci_dev_unlock(hdev);
840c8992cffSLuiz Augusto von Dentz 
841c8992cffSLuiz Augusto von Dentz 	return rp->status;
842302975cbSSpoorthi Ravishankar Koppad }
843302975cbSSpoorthi Ravishankar Koppad 
844c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_features(struct hci_dev *hdev, void *data,
8458fc9ced3SGustavo Padovan 				     struct sk_buff *skb)
846a9de9248SMarcel Holtmann {
847c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_features *rp = data;
848e3f3a1aeSLuiz Augusto von Dentz 
849e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
850a9de9248SMarcel Holtmann 
851a9de9248SMarcel Holtmann 	if (rp->status)
852c8992cffSLuiz Augusto von Dentz 		return rp->status;
853a9de9248SMarcel Holtmann 
854a9de9248SMarcel Holtmann 	memcpy(hdev->features, rp->features, 8);
8551da177e4SLinus Torvalds 
8561da177e4SLinus Torvalds 	/* Adjust default settings according to features
8571da177e4SLinus Torvalds 	 * supported by device. */
858a9de9248SMarcel Holtmann 
859cad718edSJohan Hedberg 	if (hdev->features[0][0] & LMP_3SLOT)
8601da177e4SLinus Torvalds 		hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
8611da177e4SLinus Torvalds 
862cad718edSJohan Hedberg 	if (hdev->features[0][0] & LMP_5SLOT)
8631da177e4SLinus Torvalds 		hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
8641da177e4SLinus Torvalds 
865cad718edSJohan Hedberg 	if (hdev->features[0][1] & LMP_HV2) {
8661da177e4SLinus Torvalds 		hdev->pkt_type  |= (HCI_HV2);
8675b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_HV2);
8685b7f9909SMarcel Holtmann 	}
8691da177e4SLinus Torvalds 
870cad718edSJohan Hedberg 	if (hdev->features[0][1] & LMP_HV3) {
8711da177e4SLinus Torvalds 		hdev->pkt_type  |= (HCI_HV3);
8725b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_HV3);
8735b7f9909SMarcel Holtmann 	}
8745b7f9909SMarcel Holtmann 
87545db810fSAndre Guedes 	if (lmp_esco_capable(hdev))
8765b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_EV3);
8775b7f9909SMarcel Holtmann 
878cad718edSJohan Hedberg 	if (hdev->features[0][4] & LMP_EV4)
8795b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_EV4);
8805b7f9909SMarcel Holtmann 
881cad718edSJohan Hedberg 	if (hdev->features[0][4] & LMP_EV5)
8825b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_EV5);
8831da177e4SLinus Torvalds 
884cad718edSJohan Hedberg 	if (hdev->features[0][5] & LMP_EDR_ESCO_2M)
885efc7688bSMarcel Holtmann 		hdev->esco_type |= (ESCO_2EV3);
886efc7688bSMarcel Holtmann 
887cad718edSJohan Hedberg 	if (hdev->features[0][5] & LMP_EDR_ESCO_3M)
888efc7688bSMarcel Holtmann 		hdev->esco_type |= (ESCO_3EV3);
889efc7688bSMarcel Holtmann 
890cad718edSJohan Hedberg 	if (hdev->features[0][5] & LMP_EDR_3S_ESCO)
891efc7688bSMarcel Holtmann 		hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
892c8992cffSLuiz Augusto von Dentz 
893c8992cffSLuiz Augusto von Dentz 	return rp->status;
8941da177e4SLinus Torvalds }
8951da177e4SLinus Torvalds 
896c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_ext_features(struct hci_dev *hdev, void *data,
897971e3a4bSAndre Guedes 					 struct sk_buff *skb)
898971e3a4bSAndre Guedes {
899c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_ext_features *rp = data;
900e3f3a1aeSLuiz Augusto von Dentz 
901e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
902971e3a4bSAndre Guedes 
903971e3a4bSAndre Guedes 	if (rp->status)
904c8992cffSLuiz Augusto von Dentz 		return rp->status;
905971e3a4bSAndre Guedes 
9068194f1efSVasily Khoruzhick 	if (hdev->max_page < rp->max_page) {
9078194f1efSVasily Khoruzhick 		if (test_bit(HCI_QUIRK_BROKEN_LOCAL_EXT_FEATURES_PAGE_2,
9088194f1efSVasily Khoruzhick 			     &hdev->quirks))
9098194f1efSVasily Khoruzhick 			bt_dev_warn(hdev, "broken local ext features page 2");
9108194f1efSVasily Khoruzhick 		else
911d2c5d77fSJohan Hedberg 			hdev->max_page = rp->max_page;
9128194f1efSVasily Khoruzhick 	}
913d2c5d77fSJohan Hedberg 
914cad718edSJohan Hedberg 	if (rp->page < HCI_MAX_PAGES)
915cad718edSJohan Hedberg 		memcpy(hdev->features[rp->page], rp->features, 8);
916c8992cffSLuiz Augusto von Dentz 
917c8992cffSLuiz Augusto von Dentz 	return rp->status;
918971e3a4bSAndre Guedes }
919971e3a4bSAndre Guedes 
920c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_flow_control_mode(struct hci_dev *hdev, void *data,
9211e89cffbSAndrei Emeltchenko 					struct sk_buff *skb)
9221e89cffbSAndrei Emeltchenko {
923c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_flow_control_mode *rp = data;
924e3f3a1aeSLuiz Augusto von Dentz 
925e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
9261e89cffbSAndrei Emeltchenko 
92745296acdSMarcel Holtmann 	if (rp->status)
928c8992cffSLuiz Augusto von Dentz 		return rp->status;
92945296acdSMarcel Holtmann 
9301e89cffbSAndrei Emeltchenko 	hdev->flow_ctl_mode = rp->mode;
931c8992cffSLuiz Augusto von Dentz 
932c8992cffSLuiz Augusto von Dentz 	return rp->status;
9331e89cffbSAndrei Emeltchenko }
9341e89cffbSAndrei Emeltchenko 
935c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_buffer_size(struct hci_dev *hdev, void *data,
936c8992cffSLuiz Augusto von Dentz 				  struct sk_buff *skb)
937a9de9248SMarcel Holtmann {
938c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_buffer_size *rp = data;
939e3f3a1aeSLuiz Augusto von Dentz 
940e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
941a9de9248SMarcel Holtmann 
942a9de9248SMarcel Holtmann 	if (rp->status)
943c8992cffSLuiz Augusto von Dentz 		return rp->status;
944a9de9248SMarcel Holtmann 
945a9de9248SMarcel Holtmann 	hdev->acl_mtu  = __le16_to_cpu(rp->acl_mtu);
946a9de9248SMarcel Holtmann 	hdev->sco_mtu  = rp->sco_mtu;
947a9de9248SMarcel Holtmann 	hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
948a9de9248SMarcel Holtmann 	hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
949da1f5198SMarcel Holtmann 
950da1f5198SMarcel Holtmann 	if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
951da1f5198SMarcel Holtmann 		hdev->sco_mtu  = 64;
952da1f5198SMarcel Holtmann 		hdev->sco_pkts = 8;
953da1f5198SMarcel Holtmann 	}
954da1f5198SMarcel Holtmann 
955da1f5198SMarcel Holtmann 	hdev->acl_cnt = hdev->acl_pkts;
956da1f5198SMarcel Holtmann 	hdev->sco_cnt = hdev->sco_pkts;
9571da177e4SLinus Torvalds 
958807deac2SGustavo Padovan 	BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
959807deac2SGustavo Padovan 	       hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
960c8992cffSLuiz Augusto von Dentz 
961c8992cffSLuiz Augusto von Dentz 	return rp->status;
9621da177e4SLinus Torvalds }
9631da177e4SLinus Torvalds 
964c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_bd_addr(struct hci_dev *hdev, void *data,
965c8992cffSLuiz Augusto von Dentz 			      struct sk_buff *skb)
966a9de9248SMarcel Holtmann {
967c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_bd_addr *rp = data;
968e3f3a1aeSLuiz Augusto von Dentz 
969e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
970a9de9248SMarcel Holtmann 
971e30d3f5fSMarcel Holtmann 	if (rp->status)
972c8992cffSLuiz Augusto von Dentz 		return rp->status;
973e30d3f5fSMarcel Holtmann 
974e30d3f5fSMarcel Holtmann 	if (test_bit(HCI_INIT, &hdev->flags))
975a9de9248SMarcel Holtmann 		bacpy(&hdev->bdaddr, &rp->bdaddr);
976e30d3f5fSMarcel Holtmann 
977d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP))
978e30d3f5fSMarcel Holtmann 		bacpy(&hdev->setup_addr, &rp->bdaddr);
979c8992cffSLuiz Augusto von Dentz 
980c8992cffSLuiz Augusto von Dentz 	return rp->status;
98123bb5763SJohan Hedberg }
98223bb5763SJohan Hedberg 
983c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_pairing_opts(struct hci_dev *hdev, void *data,
984a4790360SMarcel Holtmann 					 struct sk_buff *skb)
985a4790360SMarcel Holtmann {
986c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_pairing_opts *rp = data;
987e3f3a1aeSLuiz Augusto von Dentz 
988e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
989a4790360SMarcel Holtmann 
990a4790360SMarcel Holtmann 	if (rp->status)
991c8992cffSLuiz Augusto von Dentz 		return rp->status;
992a4790360SMarcel Holtmann 
993a4790360SMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP) ||
994a4790360SMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_CONFIG)) {
995a4790360SMarcel Holtmann 		hdev->pairing_opts = rp->pairing_opts;
996a4790360SMarcel Holtmann 		hdev->max_enc_key_size = rp->max_key_size;
997a4790360SMarcel Holtmann 	}
998c8992cffSLuiz Augusto von Dentz 
999c8992cffSLuiz Augusto von Dentz 	return rp->status;
1000a4790360SMarcel Holtmann }
1001a4790360SMarcel Holtmann 
1002c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_page_scan_activity(struct hci_dev *hdev, void *data,
1003f332ec66SJohan Hedberg 					 struct sk_buff *skb)
1004f332ec66SJohan Hedberg {
1005c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_page_scan_activity *rp = data;
1006e3f3a1aeSLuiz Augusto von Dentz 
1007e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1008f332ec66SJohan Hedberg 
100945296acdSMarcel Holtmann 	if (rp->status)
1010c8992cffSLuiz Augusto von Dentz 		return rp->status;
101145296acdSMarcel Holtmann 
101245296acdSMarcel Holtmann 	if (test_bit(HCI_INIT, &hdev->flags)) {
1013f332ec66SJohan Hedberg 		hdev->page_scan_interval = __le16_to_cpu(rp->interval);
1014f332ec66SJohan Hedberg 		hdev->page_scan_window = __le16_to_cpu(rp->window);
1015f332ec66SJohan Hedberg 	}
1016c8992cffSLuiz Augusto von Dentz 
1017c8992cffSLuiz Augusto von Dentz 	return rp->status;
1018f332ec66SJohan Hedberg }
1019f332ec66SJohan Hedberg 
1020c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_page_scan_activity(struct hci_dev *hdev, void *data,
10214a3ee763SJohan Hedberg 					  struct sk_buff *skb)
10224a3ee763SJohan Hedberg {
1023c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
10244a3ee763SJohan Hedberg 	struct hci_cp_write_page_scan_activity *sent;
10254a3ee763SJohan Hedberg 
1026e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1027e3f3a1aeSLuiz Augusto von Dentz 
1028e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1029c8992cffSLuiz Augusto von Dentz 		return rp->status;
10304a3ee763SJohan Hedberg 
10314a3ee763SJohan Hedberg 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY);
10324a3ee763SJohan Hedberg 	if (!sent)
1033c8992cffSLuiz Augusto von Dentz 		return rp->status;
10344a3ee763SJohan Hedberg 
10354a3ee763SJohan Hedberg 	hdev->page_scan_interval = __le16_to_cpu(sent->interval);
10364a3ee763SJohan Hedberg 	hdev->page_scan_window = __le16_to_cpu(sent->window);
1037c8992cffSLuiz Augusto von Dentz 
1038c8992cffSLuiz Augusto von Dentz 	return rp->status;
10394a3ee763SJohan Hedberg }
10404a3ee763SJohan Hedberg 
1041c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_page_scan_type(struct hci_dev *hdev, void *data,
1042f332ec66SJohan Hedberg 				     struct sk_buff *skb)
1043f332ec66SJohan Hedberg {
1044c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_page_scan_type *rp = data;
1045e3f3a1aeSLuiz Augusto von Dentz 
1046e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1047f332ec66SJohan Hedberg 
104845296acdSMarcel Holtmann 	if (rp->status)
1049c8992cffSLuiz Augusto von Dentz 		return rp->status;
105045296acdSMarcel Holtmann 
105145296acdSMarcel Holtmann 	if (test_bit(HCI_INIT, &hdev->flags))
1052f332ec66SJohan Hedberg 		hdev->page_scan_type = rp->type;
1053c8992cffSLuiz Augusto von Dentz 
1054c8992cffSLuiz Augusto von Dentz 	return rp->status;
1055f332ec66SJohan Hedberg }
1056f332ec66SJohan Hedberg 
1057c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_page_scan_type(struct hci_dev *hdev, void *data,
10584a3ee763SJohan Hedberg 				      struct sk_buff *skb)
10594a3ee763SJohan Hedberg {
1060c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
10614a3ee763SJohan Hedberg 	u8 *type;
10624a3ee763SJohan Hedberg 
1063e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1064e3f3a1aeSLuiz Augusto von Dentz 
1065e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1066c8992cffSLuiz Augusto von Dentz 		return rp->status;
10674a3ee763SJohan Hedberg 
10684a3ee763SJohan Hedberg 	type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE);
10694a3ee763SJohan Hedberg 	if (type)
10704a3ee763SJohan Hedberg 		hdev->page_scan_type = *type;
1071c8992cffSLuiz Augusto von Dentz 
1072c8992cffSLuiz Augusto von Dentz 	return rp->status;
10734a3ee763SJohan Hedberg }
10744a3ee763SJohan Hedberg 
1075c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_data_block_size(struct hci_dev *hdev, void *data,
1076350ee4cfSAndrei Emeltchenko 				      struct sk_buff *skb)
1077350ee4cfSAndrei Emeltchenko {
1078c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_data_block_size *rp = data;
1079e3f3a1aeSLuiz Augusto von Dentz 
1080e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1081350ee4cfSAndrei Emeltchenko 
1082350ee4cfSAndrei Emeltchenko 	if (rp->status)
1083c8992cffSLuiz Augusto von Dentz 		return rp->status;
1084350ee4cfSAndrei Emeltchenko 
1085350ee4cfSAndrei Emeltchenko 	hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
1086350ee4cfSAndrei Emeltchenko 	hdev->block_len = __le16_to_cpu(rp->block_len);
1087350ee4cfSAndrei Emeltchenko 	hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
1088350ee4cfSAndrei Emeltchenko 
1089350ee4cfSAndrei Emeltchenko 	hdev->block_cnt = hdev->num_blocks;
1090350ee4cfSAndrei Emeltchenko 
1091350ee4cfSAndrei Emeltchenko 	BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
1092350ee4cfSAndrei Emeltchenko 	       hdev->block_cnt, hdev->block_len);
1093c8992cffSLuiz Augusto von Dentz 
1094c8992cffSLuiz Augusto von Dentz 	return rp->status;
1095350ee4cfSAndrei Emeltchenko }
1096350ee4cfSAndrei Emeltchenko 
1097c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_clock(struct hci_dev *hdev, void *data,
1098c8992cffSLuiz Augusto von Dentz 			    struct sk_buff *skb)
109933f35721SJohan Hedberg {
1100c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_clock *rp = data;
110133f35721SJohan Hedberg 	struct hci_cp_read_clock *cp;
110233f35721SJohan Hedberg 	struct hci_conn *conn;
110333f35721SJohan Hedberg 
1104e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1105e3f3a1aeSLuiz Augusto von Dentz 
110633f35721SJohan Hedberg 	if (rp->status)
1107c8992cffSLuiz Augusto von Dentz 		return rp->status;
110833f35721SJohan Hedberg 
110933f35721SJohan Hedberg 	hci_dev_lock(hdev);
111033f35721SJohan Hedberg 
111133f35721SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_READ_CLOCK);
111233f35721SJohan Hedberg 	if (!cp)
111333f35721SJohan Hedberg 		goto unlock;
111433f35721SJohan Hedberg 
111533f35721SJohan Hedberg 	if (cp->which == 0x00) {
111633f35721SJohan Hedberg 		hdev->clock = le32_to_cpu(rp->clock);
111733f35721SJohan Hedberg 		goto unlock;
111833f35721SJohan Hedberg 	}
111933f35721SJohan Hedberg 
112033f35721SJohan Hedberg 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
112133f35721SJohan Hedberg 	if (conn) {
112233f35721SJohan Hedberg 		conn->clock = le32_to_cpu(rp->clock);
112333f35721SJohan Hedberg 		conn->clock_accuracy = le16_to_cpu(rp->accuracy);
112433f35721SJohan Hedberg 	}
112533f35721SJohan Hedberg 
112633f35721SJohan Hedberg unlock:
112733f35721SJohan Hedberg 	hci_dev_unlock(hdev);
1128c8992cffSLuiz Augusto von Dentz 	return rp->status;
112933f35721SJohan Hedberg }
113033f35721SJohan Hedberg 
1131c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_amp_info(struct hci_dev *hdev, void *data,
1132928abaa7SAndrei Emeltchenko 				     struct sk_buff *skb)
1133928abaa7SAndrei Emeltchenko {
1134c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_amp_info *rp = data;
1135e3f3a1aeSLuiz Augusto von Dentz 
1136e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1137928abaa7SAndrei Emeltchenko 
1138928abaa7SAndrei Emeltchenko 	if (rp->status)
1139c8992cffSLuiz Augusto von Dentz 		return rp->status;
1140928abaa7SAndrei Emeltchenko 
1141928abaa7SAndrei Emeltchenko 	hdev->amp_status = rp->amp_status;
1142928abaa7SAndrei Emeltchenko 	hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
1143928abaa7SAndrei Emeltchenko 	hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
1144928abaa7SAndrei Emeltchenko 	hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
1145928abaa7SAndrei Emeltchenko 	hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
1146928abaa7SAndrei Emeltchenko 	hdev->amp_type = rp->amp_type;
1147928abaa7SAndrei Emeltchenko 	hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
1148928abaa7SAndrei Emeltchenko 	hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
1149928abaa7SAndrei Emeltchenko 	hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
1150928abaa7SAndrei Emeltchenko 	hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
1151c8992cffSLuiz Augusto von Dentz 
1152c8992cffSLuiz Augusto von Dentz 	return rp->status;
1153928abaa7SAndrei Emeltchenko }
1154928abaa7SAndrei Emeltchenko 
1155c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev, void *data,
1156d5859e22SJohan Hedberg 				       struct sk_buff *skb)
1157d5859e22SJohan Hedberg {
1158c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_inq_rsp_tx_power *rp = data;
1159e3f3a1aeSLuiz Augusto von Dentz 
1160e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1161d5859e22SJohan Hedberg 
116245296acdSMarcel Holtmann 	if (rp->status)
1163c8992cffSLuiz Augusto von Dentz 		return rp->status;
116445296acdSMarcel Holtmann 
116591c4e9b1SMarcel Holtmann 	hdev->inq_tx_power = rp->tx_power;
1166c8992cffSLuiz Augusto von Dentz 
1167c8992cffSLuiz Augusto von Dentz 	return rp->status;
1168d5859e22SJohan Hedberg }
1169d5859e22SJohan Hedberg 
1170c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_def_err_data_reporting(struct hci_dev *hdev, void *data,
117100bce3fbSAlain Michaud 					     struct sk_buff *skb)
117200bce3fbSAlain Michaud {
1173c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_def_err_data_reporting *rp = data;
1174e3f3a1aeSLuiz Augusto von Dentz 
1175e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
117600bce3fbSAlain Michaud 
117700bce3fbSAlain Michaud 	if (rp->status)
1178c8992cffSLuiz Augusto von Dentz 		return rp->status;
117900bce3fbSAlain Michaud 
118000bce3fbSAlain Michaud 	hdev->err_data_reporting = rp->err_data_reporting;
1181c8992cffSLuiz Augusto von Dentz 
1182c8992cffSLuiz Augusto von Dentz 	return rp->status;
118300bce3fbSAlain Michaud }
118400bce3fbSAlain Michaud 
1185c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_def_err_data_reporting(struct hci_dev *hdev, void *data,
118600bce3fbSAlain Michaud 					      struct sk_buff *skb)
118700bce3fbSAlain Michaud {
1188c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
118900bce3fbSAlain Michaud 	struct hci_cp_write_def_err_data_reporting *cp;
119000bce3fbSAlain Michaud 
1191e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1192e3f3a1aeSLuiz Augusto von Dentz 
1193e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1194c8992cffSLuiz Augusto von Dentz 		return rp->status;
119500bce3fbSAlain Michaud 
119600bce3fbSAlain Michaud 	cp = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_ERR_DATA_REPORTING);
119700bce3fbSAlain Michaud 	if (!cp)
1198c8992cffSLuiz Augusto von Dentz 		return rp->status;
119900bce3fbSAlain Michaud 
120000bce3fbSAlain Michaud 	hdev->err_data_reporting = cp->err_data_reporting;
1201c8992cffSLuiz Augusto von Dentz 
1202c8992cffSLuiz Augusto von Dentz 	return rp->status;
120300bce3fbSAlain Michaud }
120400bce3fbSAlain Michaud 
1205c8992cffSLuiz Augusto von Dentz static u8 hci_cc_pin_code_reply(struct hci_dev *hdev, void *data,
1206c8992cffSLuiz Augusto von Dentz 				struct sk_buff *skb)
1207980e1a53SJohan Hedberg {
1208c8992cffSLuiz Augusto von Dentz 	struct hci_rp_pin_code_reply *rp = data;
1209980e1a53SJohan Hedberg 	struct hci_cp_pin_code_reply *cp;
1210980e1a53SJohan Hedberg 	struct hci_conn *conn;
1211980e1a53SJohan Hedberg 
1212e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1213980e1a53SJohan Hedberg 
121456e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
121556e5cb86SJohan Hedberg 
1216d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
1217744cf19eSJohan Hedberg 		mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
1218980e1a53SJohan Hedberg 
1219fa1bd918SMikel Astiz 	if (rp->status)
122056e5cb86SJohan Hedberg 		goto unlock;
1221980e1a53SJohan Hedberg 
1222980e1a53SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
1223980e1a53SJohan Hedberg 	if (!cp)
122456e5cb86SJohan Hedberg 		goto unlock;
1225980e1a53SJohan Hedberg 
1226980e1a53SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1227980e1a53SJohan Hedberg 	if (conn)
1228980e1a53SJohan Hedberg 		conn->pin_length = cp->pin_len;
122956e5cb86SJohan Hedberg 
123056e5cb86SJohan Hedberg unlock:
123156e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
1232c8992cffSLuiz Augusto von Dentz 	return rp->status;
1233980e1a53SJohan Hedberg }
1234980e1a53SJohan Hedberg 
1235c8992cffSLuiz Augusto von Dentz static u8 hci_cc_pin_code_neg_reply(struct hci_dev *hdev, void *data,
1236c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
1237980e1a53SJohan Hedberg {
1238c8992cffSLuiz Augusto von Dentz 	struct hci_rp_pin_code_neg_reply *rp = data;
1239e3f3a1aeSLuiz Augusto von Dentz 
1240e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1241980e1a53SJohan Hedberg 
124256e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
124356e5cb86SJohan Hedberg 
1244d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
1245744cf19eSJohan Hedberg 		mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
1246980e1a53SJohan Hedberg 						 rp->status);
124756e5cb86SJohan Hedberg 
124856e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
1249c8992cffSLuiz Augusto von Dentz 
1250c8992cffSLuiz Augusto von Dentz 	return rp->status;
1251980e1a53SJohan Hedberg }
125256e5cb86SJohan Hedberg 
1253c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_buffer_size(struct hci_dev *hdev, void *data,
12546ed58ec5SVille Tervo 				     struct sk_buff *skb)
12556ed58ec5SVille Tervo {
1256c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_buffer_size *rp = data;
1257e3f3a1aeSLuiz Augusto von Dentz 
1258e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
12596ed58ec5SVille Tervo 
12606ed58ec5SVille Tervo 	if (rp->status)
1261c8992cffSLuiz Augusto von Dentz 		return rp->status;
12626ed58ec5SVille Tervo 
12636ed58ec5SVille Tervo 	hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
12646ed58ec5SVille Tervo 	hdev->le_pkts = rp->le_max_pkt;
12656ed58ec5SVille Tervo 
12666ed58ec5SVille Tervo 	hdev->le_cnt = hdev->le_pkts;
12676ed58ec5SVille Tervo 
12686ed58ec5SVille Tervo 	BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
1269c8992cffSLuiz Augusto von Dentz 
1270c8992cffSLuiz Augusto von Dentz 	return rp->status;
12716ed58ec5SVille Tervo }
1272980e1a53SJohan Hedberg 
1273c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_local_features(struct hci_dev *hdev, void *data,
127460e77321SJohan Hedberg 					struct sk_buff *skb)
127560e77321SJohan Hedberg {
1276c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_local_features *rp = data;
127760e77321SJohan Hedberg 
127860e77321SJohan Hedberg 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
127960e77321SJohan Hedberg 
128045296acdSMarcel Holtmann 	if (rp->status)
1281c8992cffSLuiz Augusto von Dentz 		return rp->status;
128245296acdSMarcel Holtmann 
128360e77321SJohan Hedberg 	memcpy(hdev->le_features, rp->features, 8);
1284c8992cffSLuiz Augusto von Dentz 
1285c8992cffSLuiz Augusto von Dentz 	return rp->status;
128660e77321SJohan Hedberg }
128760e77321SJohan Hedberg 
1288c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_adv_tx_power(struct hci_dev *hdev, void *data,
12898fa19098SJohan Hedberg 				      struct sk_buff *skb)
12908fa19098SJohan Hedberg {
1291c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_adv_tx_power *rp = data;
1292e3f3a1aeSLuiz Augusto von Dentz 
1293e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
12948fa19098SJohan Hedberg 
129545296acdSMarcel Holtmann 	if (rp->status)
1296c8992cffSLuiz Augusto von Dentz 		return rp->status;
129745296acdSMarcel Holtmann 
12988fa19098SJohan Hedberg 	hdev->adv_tx_power = rp->tx_power;
1299c8992cffSLuiz Augusto von Dentz 
1300c8992cffSLuiz Augusto von Dentz 	return rp->status;
13018fa19098SJohan Hedberg }
13028fa19098SJohan Hedberg 
1303c8992cffSLuiz Augusto von Dentz static u8 hci_cc_user_confirm_reply(struct hci_dev *hdev, void *data,
1304c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
1305a5c29683SJohan Hedberg {
1306c8992cffSLuiz Augusto von Dentz 	struct hci_rp_user_confirm_reply *rp = data;
1307e3f3a1aeSLuiz Augusto von Dentz 
1308e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1309a5c29683SJohan Hedberg 
131056e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
131156e5cb86SJohan Hedberg 
1312d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
131304124681SGustavo F. Padovan 		mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
131404124681SGustavo F. Padovan 						 rp->status);
131556e5cb86SJohan Hedberg 
131656e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
1317c8992cffSLuiz Augusto von Dentz 
1318c8992cffSLuiz Augusto von Dentz 	return rp->status;
1319a5c29683SJohan Hedberg }
1320a5c29683SJohan Hedberg 
1321c8992cffSLuiz Augusto von Dentz static u8 hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, void *data,
1322a5c29683SJohan Hedberg 					struct sk_buff *skb)
1323a5c29683SJohan Hedberg {
1324c8992cffSLuiz Augusto von Dentz 	struct hci_rp_user_confirm_reply *rp = data;
1325e3f3a1aeSLuiz Augusto von Dentz 
1326e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1327a5c29683SJohan Hedberg 
132856e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
132956e5cb86SJohan Hedberg 
1330d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
1331744cf19eSJohan Hedberg 		mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
133204124681SGustavo F. Padovan 						     ACL_LINK, 0, rp->status);
133356e5cb86SJohan Hedberg 
133456e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
1335c8992cffSLuiz Augusto von Dentz 
1336c8992cffSLuiz Augusto von Dentz 	return rp->status;
1337a5c29683SJohan Hedberg }
1338a5c29683SJohan Hedberg 
1339c8992cffSLuiz Augusto von Dentz static u8 hci_cc_user_passkey_reply(struct hci_dev *hdev, void *data,
1340c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
13411143d458SBrian Gix {
1342c8992cffSLuiz Augusto von Dentz 	struct hci_rp_user_confirm_reply *rp = data;
1343e3f3a1aeSLuiz Augusto von Dentz 
1344e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
13451143d458SBrian Gix 
13461143d458SBrian Gix 	hci_dev_lock(hdev);
13471143d458SBrian Gix 
1348d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
1349272d90dfSJohan Hedberg 		mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
1350272d90dfSJohan Hedberg 						 0, rp->status);
13511143d458SBrian Gix 
13521143d458SBrian Gix 	hci_dev_unlock(hdev);
1353c8992cffSLuiz Augusto von Dentz 
1354c8992cffSLuiz Augusto von Dentz 	return rp->status;
13551143d458SBrian Gix }
13561143d458SBrian Gix 
1357c8992cffSLuiz Augusto von Dentz static u8 hci_cc_user_passkey_neg_reply(struct hci_dev *hdev, void *data,
13581143d458SBrian Gix 					struct sk_buff *skb)
13591143d458SBrian Gix {
1360c8992cffSLuiz Augusto von Dentz 	struct hci_rp_user_confirm_reply *rp = data;
1361e3f3a1aeSLuiz Augusto von Dentz 
1362e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
13631143d458SBrian Gix 
13641143d458SBrian Gix 	hci_dev_lock(hdev);
13651143d458SBrian Gix 
1366d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
13671143d458SBrian Gix 		mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
136804124681SGustavo F. Padovan 						     ACL_LINK, 0, rp->status);
13691143d458SBrian Gix 
13701143d458SBrian Gix 	hci_dev_unlock(hdev);
1371c8992cffSLuiz Augusto von Dentz 
1372c8992cffSLuiz Augusto von Dentz 	return rp->status;
13731143d458SBrian Gix }
13741143d458SBrian Gix 
1375c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_oob_data(struct hci_dev *hdev, void *data,
1376c35938b2SSzymon Janc 				     struct sk_buff *skb)
1377c35938b2SSzymon Janc {
1378c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_oob_data *rp = data;
1379e3f3a1aeSLuiz Augusto von Dentz 
1380e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1381c8992cffSLuiz Augusto von Dentz 
1382c8992cffSLuiz Augusto von Dentz 	return rp->status;
13834d2d2796SMarcel Holtmann }
13844d2d2796SMarcel Holtmann 
1385c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_oob_ext_data(struct hci_dev *hdev, void *data,
13864d2d2796SMarcel Holtmann 					 struct sk_buff *skb)
13874d2d2796SMarcel Holtmann {
1388c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_oob_ext_data *rp = data;
1389e3f3a1aeSLuiz Augusto von Dentz 
1390e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1391c8992cffSLuiz Augusto von Dentz 
1392c8992cffSLuiz Augusto von Dentz 	return rp->status;
1393c35938b2SSzymon Janc }
1394c35938b2SSzymon Janc 
1395c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_random_addr(struct hci_dev *hdev, void *data,
1396c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
13977a4cd51dSMarcel Holtmann {
1398c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
13997a4cd51dSMarcel Holtmann 	bdaddr_t *sent;
14007a4cd51dSMarcel Holtmann 
1401e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1402e3f3a1aeSLuiz Augusto von Dentz 
1403e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1404c8992cffSLuiz Augusto von Dentz 		return rp->status;
140545296acdSMarcel Holtmann 
14067a4cd51dSMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_RANDOM_ADDR);
14077a4cd51dSMarcel Holtmann 	if (!sent)
1408c8992cffSLuiz Augusto von Dentz 		return rp->status;
14097a4cd51dSMarcel Holtmann 
14107a4cd51dSMarcel Holtmann 	hci_dev_lock(hdev);
14117a4cd51dSMarcel Holtmann 
14127a4cd51dSMarcel Holtmann 	bacpy(&hdev->random_addr, sent);
14137a4cd51dSMarcel Holtmann 
1414c45074d6SLuiz Augusto von Dentz 	if (!bacmp(&hdev->rpa, sent)) {
1415c45074d6SLuiz Augusto von Dentz 		hci_dev_clear_flag(hdev, HCI_RPA_EXPIRED);
1416c45074d6SLuiz Augusto von Dentz 		queue_delayed_work(hdev->workqueue, &hdev->rpa_expired,
1417c45074d6SLuiz Augusto von Dentz 				   secs_to_jiffies(hdev->rpa_timeout));
1418c45074d6SLuiz Augusto von Dentz 	}
1419c45074d6SLuiz Augusto von Dentz 
14207a4cd51dSMarcel Holtmann 	hci_dev_unlock(hdev);
1421c8992cffSLuiz Augusto von Dentz 
1422c8992cffSLuiz Augusto von Dentz 	return rp->status;
14237a4cd51dSMarcel Holtmann }
14247a4cd51dSMarcel Holtmann 
1425c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_default_phy(struct hci_dev *hdev, void *data,
1426c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
14270314f286SJaganath Kanakkassery {
1428c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
14290314f286SJaganath Kanakkassery 	struct hci_cp_le_set_default_phy *cp;
14300314f286SJaganath Kanakkassery 
1431e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1432e3f3a1aeSLuiz Augusto von Dentz 
1433e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1434c8992cffSLuiz Augusto von Dentz 		return rp->status;
14350314f286SJaganath Kanakkassery 
14360314f286SJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_DEFAULT_PHY);
14370314f286SJaganath Kanakkassery 	if (!cp)
1438c8992cffSLuiz Augusto von Dentz 		return rp->status;
14390314f286SJaganath Kanakkassery 
14400314f286SJaganath Kanakkassery 	hci_dev_lock(hdev);
14410314f286SJaganath Kanakkassery 
14420314f286SJaganath Kanakkassery 	hdev->le_tx_def_phys = cp->tx_phys;
14430314f286SJaganath Kanakkassery 	hdev->le_rx_def_phys = cp->rx_phys;
14440314f286SJaganath Kanakkassery 
14450314f286SJaganath Kanakkassery 	hci_dev_unlock(hdev);
1446c8992cffSLuiz Augusto von Dentz 
1447c8992cffSLuiz Augusto von Dentz 	return rp->status;
14480314f286SJaganath Kanakkassery }
14490314f286SJaganath Kanakkassery 
1450c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_adv_set_random_addr(struct hci_dev *hdev, void *data,
1451a73c046aSJaganath Kanakkassery 					    struct sk_buff *skb)
1452a73c046aSJaganath Kanakkassery {
1453c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1454a73c046aSJaganath Kanakkassery 	struct hci_cp_le_set_adv_set_rand_addr *cp;
1455c45074d6SLuiz Augusto von Dentz 	struct adv_info *adv;
1456a73c046aSJaganath Kanakkassery 
1457e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1458e3f3a1aeSLuiz Augusto von Dentz 
1459e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1460c8992cffSLuiz Augusto von Dentz 		return rp->status;
1461a73c046aSJaganath Kanakkassery 
1462a73c046aSJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_SET_RAND_ADDR);
1463c45074d6SLuiz Augusto von Dentz 	/* Update only in case the adv instance since handle 0x00 shall be using
1464c45074d6SLuiz Augusto von Dentz 	 * HCI_OP_LE_SET_RANDOM_ADDR since that allows both extended and
1465c45074d6SLuiz Augusto von Dentz 	 * non-extended adverting.
1466c45074d6SLuiz Augusto von Dentz 	 */
1467c45074d6SLuiz Augusto von Dentz 	if (!cp || !cp->handle)
1468c8992cffSLuiz Augusto von Dentz 		return rp->status;
1469a73c046aSJaganath Kanakkassery 
1470a73c046aSJaganath Kanakkassery 	hci_dev_lock(hdev);
1471a73c046aSJaganath Kanakkassery 
1472c45074d6SLuiz Augusto von Dentz 	adv = hci_find_adv_instance(hdev, cp->handle);
1473c45074d6SLuiz Augusto von Dentz 	if (adv) {
1474c45074d6SLuiz Augusto von Dentz 		bacpy(&adv->random_addr, &cp->bdaddr);
1475c45074d6SLuiz Augusto von Dentz 		if (!bacmp(&hdev->rpa, &cp->bdaddr)) {
1476c45074d6SLuiz Augusto von Dentz 			adv->rpa_expired = false;
1477c45074d6SLuiz Augusto von Dentz 			queue_delayed_work(hdev->workqueue,
1478c45074d6SLuiz Augusto von Dentz 					   &adv->rpa_expired_cb,
1479c45074d6SLuiz Augusto von Dentz 					   secs_to_jiffies(hdev->rpa_timeout));
1480c45074d6SLuiz Augusto von Dentz 		}
1481a73c046aSJaganath Kanakkassery 	}
1482a73c046aSJaganath Kanakkassery 
1483a73c046aSJaganath Kanakkassery 	hci_dev_unlock(hdev);
1484c8992cffSLuiz Augusto von Dentz 
1485c8992cffSLuiz Augusto von Dentz 	return rp->status;
1486a73c046aSJaganath Kanakkassery }
1487a73c046aSJaganath Kanakkassery 
1488c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_remove_adv_set(struct hci_dev *hdev, void *data,
1489c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
1490cba6b758SLuiz Augusto von Dentz {
1491c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1492cba6b758SLuiz Augusto von Dentz 	u8 *instance;
1493cba6b758SLuiz Augusto von Dentz 	int err;
1494cba6b758SLuiz Augusto von Dentz 
1495e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1496e3f3a1aeSLuiz Augusto von Dentz 
1497e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1498c8992cffSLuiz Augusto von Dentz 		return rp->status;
1499cba6b758SLuiz Augusto von Dentz 
1500cba6b758SLuiz Augusto von Dentz 	instance = hci_sent_cmd_data(hdev, HCI_OP_LE_REMOVE_ADV_SET);
1501cba6b758SLuiz Augusto von Dentz 	if (!instance)
1502c8992cffSLuiz Augusto von Dentz 		return rp->status;
1503cba6b758SLuiz Augusto von Dentz 
1504cba6b758SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
1505cba6b758SLuiz Augusto von Dentz 
1506cba6b758SLuiz Augusto von Dentz 	err = hci_remove_adv_instance(hdev, *instance);
1507cba6b758SLuiz Augusto von Dentz 	if (!err)
1508cba6b758SLuiz Augusto von Dentz 		mgmt_advertising_removed(hci_skb_sk(hdev->sent_cmd), hdev,
1509cba6b758SLuiz Augusto von Dentz 					 *instance);
1510cba6b758SLuiz Augusto von Dentz 
1511cba6b758SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
1512c8992cffSLuiz Augusto von Dentz 
1513c8992cffSLuiz Augusto von Dentz 	return rp->status;
1514cba6b758SLuiz Augusto von Dentz }
1515cba6b758SLuiz Augusto von Dentz 
1516c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_clear_adv_sets(struct hci_dev *hdev, void *data,
1517c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
1518cba6b758SLuiz Augusto von Dentz {
1519c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1520cba6b758SLuiz Augusto von Dentz 	struct adv_info *adv, *n;
1521cba6b758SLuiz Augusto von Dentz 	int err;
1522cba6b758SLuiz Augusto von Dentz 
1523e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1524e3f3a1aeSLuiz Augusto von Dentz 
1525e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1526c8992cffSLuiz Augusto von Dentz 		return rp->status;
1527cba6b758SLuiz Augusto von Dentz 
1528cba6b758SLuiz Augusto von Dentz 	if (!hci_sent_cmd_data(hdev, HCI_OP_LE_CLEAR_ADV_SETS))
1529c8992cffSLuiz Augusto von Dentz 		return rp->status;
1530cba6b758SLuiz Augusto von Dentz 
1531cba6b758SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
1532cba6b758SLuiz Augusto von Dentz 
1533cba6b758SLuiz Augusto von Dentz 	list_for_each_entry_safe(adv, n, &hdev->adv_instances, list) {
1534cba6b758SLuiz Augusto von Dentz 		u8 instance = adv->instance;
1535cba6b758SLuiz Augusto von Dentz 
1536cba6b758SLuiz Augusto von Dentz 		err = hci_remove_adv_instance(hdev, instance);
1537cba6b758SLuiz Augusto von Dentz 		if (!err)
1538cba6b758SLuiz Augusto von Dentz 			mgmt_advertising_removed(hci_skb_sk(hdev->sent_cmd),
1539cba6b758SLuiz Augusto von Dentz 						 hdev, instance);
1540cba6b758SLuiz Augusto von Dentz 	}
1541cba6b758SLuiz Augusto von Dentz 
1542cba6b758SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
1543c8992cffSLuiz Augusto von Dentz 
1544c8992cffSLuiz Augusto von Dentz 	return rp->status;
1545cba6b758SLuiz Augusto von Dentz }
1546cba6b758SLuiz Augusto von Dentz 
1547c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_transmit_power(struct hci_dev *hdev, void *data,
15487c395ea5SDaniel Winkler 					struct sk_buff *skb)
15497c395ea5SDaniel Winkler {
1550c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_transmit_power *rp = data;
1551e3f3a1aeSLuiz Augusto von Dentz 
1552e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
15537c395ea5SDaniel Winkler 
15547c395ea5SDaniel Winkler 	if (rp->status)
1555c8992cffSLuiz Augusto von Dentz 		return rp->status;
15567c395ea5SDaniel Winkler 
15577c395ea5SDaniel Winkler 	hdev->min_le_tx_power = rp->min_le_tx_power;
15587c395ea5SDaniel Winkler 	hdev->max_le_tx_power = rp->max_le_tx_power;
1559c8992cffSLuiz Augusto von Dentz 
1560c8992cffSLuiz Augusto von Dentz 	return rp->status;
15617c395ea5SDaniel Winkler }
15627c395ea5SDaniel Winkler 
1563853b70b5SLuiz Augusto von Dentz static u8 hci_cc_le_set_privacy_mode(struct hci_dev *hdev, void *data,
1564853b70b5SLuiz Augusto von Dentz 				     struct sk_buff *skb)
1565853b70b5SLuiz Augusto von Dentz {
1566853b70b5SLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1567853b70b5SLuiz Augusto von Dentz 	struct hci_cp_le_set_privacy_mode *cp;
1568853b70b5SLuiz Augusto von Dentz 	struct hci_conn_params *params;
1569853b70b5SLuiz Augusto von Dentz 
1570853b70b5SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1571853b70b5SLuiz Augusto von Dentz 
1572853b70b5SLuiz Augusto von Dentz 	if (rp->status)
1573853b70b5SLuiz Augusto von Dentz 		return rp->status;
1574853b70b5SLuiz Augusto von Dentz 
1575853b70b5SLuiz Augusto von Dentz 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_PRIVACY_MODE);
1576853b70b5SLuiz Augusto von Dentz 	if (!cp)
1577853b70b5SLuiz Augusto von Dentz 		return rp->status;
1578853b70b5SLuiz Augusto von Dentz 
1579853b70b5SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
1580853b70b5SLuiz Augusto von Dentz 
1581853b70b5SLuiz Augusto von Dentz 	params = hci_conn_params_lookup(hdev, &cp->bdaddr, cp->bdaddr_type);
1582853b70b5SLuiz Augusto von Dentz 	if (params)
1583195ef75eSPauli Virtanen 		WRITE_ONCE(params->privacy_mode, cp->mode);
1584853b70b5SLuiz Augusto von Dentz 
1585853b70b5SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
1586853b70b5SLuiz Augusto von Dentz 
1587853b70b5SLuiz Augusto von Dentz 	return rp->status;
1588853b70b5SLuiz Augusto von Dentz }
1589853b70b5SLuiz Augusto von Dentz 
1590c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_adv_enable(struct hci_dev *hdev, void *data,
1591c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
1592c1d5dc4aSJohan Hedberg {
1593c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1594e3f3a1aeSLuiz Augusto von Dentz 	__u8 *sent;
1595c1d5dc4aSJohan Hedberg 
1596e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1597e3f3a1aeSLuiz Augusto von Dentz 
1598e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1599c8992cffSLuiz Augusto von Dentz 		return rp->status;
1600c1d5dc4aSJohan Hedberg 
160145296acdSMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
160245296acdSMarcel Holtmann 	if (!sent)
1603c8992cffSLuiz Augusto von Dentz 		return rp->status;
16043c857757SJohan Hedberg 
1605c1d5dc4aSJohan Hedberg 	hci_dev_lock(hdev);
1606c1d5dc4aSJohan Hedberg 
160749c922bbSStephen Hemminger 	/* If we're doing connection initiation as peripheral. Set a
16083c857757SJohan Hedberg 	 * timeout in case something goes wrong.
16093c857757SJohan Hedberg 	 */
16103c857757SJohan Hedberg 	if (*sent) {
16113c857757SJohan Hedberg 		struct hci_conn *conn;
16123c857757SJohan Hedberg 
1613a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_LE_ADV);
161466c417c1SJohan Hedberg 
1615e7d9ab73SJakub Pawlowski 		conn = hci_lookup_le_connect(hdev);
16163c857757SJohan Hedberg 		if (conn)
16173c857757SJohan Hedberg 			queue_delayed_work(hdev->workqueue,
16183c857757SJohan Hedberg 					   &conn->le_conn_timeout,
161909ae260bSJohan Hedberg 					   conn->conn_timeout);
162066c417c1SJohan Hedberg 	} else {
1621a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LE_ADV);
16223c857757SJohan Hedberg 	}
16233c857757SJohan Hedberg 
162404b4edcbSJohan Hedberg 	hci_dev_unlock(hdev);
1625c8992cffSLuiz Augusto von Dentz 
1626c8992cffSLuiz Augusto von Dentz 	return rp->status;
1627c1d5dc4aSJohan Hedberg }
1628c1d5dc4aSJohan Hedberg 
1629c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_ext_adv_enable(struct hci_dev *hdev, void *data,
1630de181e88SJaganath Kanakkassery 				       struct sk_buff *skb)
1631de181e88SJaganath Kanakkassery {
1632de181e88SJaganath Kanakkassery 	struct hci_cp_le_set_ext_adv_enable *cp;
163310279313SLuiz Augusto von Dentz 	struct hci_cp_ext_adv_set *set;
163410279313SLuiz Augusto von Dentz 	struct adv_info *adv = NULL, *n;
1635c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1636de181e88SJaganath Kanakkassery 
1637e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1638e3f3a1aeSLuiz Augusto von Dentz 
1639e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1640c8992cffSLuiz Augusto von Dentz 		return rp->status;
1641de181e88SJaganath Kanakkassery 
1642de181e88SJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_ADV_ENABLE);
1643de181e88SJaganath Kanakkassery 	if (!cp)
1644c8992cffSLuiz Augusto von Dentz 		return rp->status;
1645de181e88SJaganath Kanakkassery 
164610279313SLuiz Augusto von Dentz 	set = (void *)cp->data;
164710279313SLuiz Augusto von Dentz 
1648de181e88SJaganath Kanakkassery 	hci_dev_lock(hdev);
1649de181e88SJaganath Kanakkassery 
165010279313SLuiz Augusto von Dentz 	if (cp->num_of_sets)
165110279313SLuiz Augusto von Dentz 		adv = hci_find_adv_instance(hdev, set->handle);
165210279313SLuiz Augusto von Dentz 
1653de181e88SJaganath Kanakkassery 	if (cp->enable) {
1654de181e88SJaganath Kanakkassery 		struct hci_conn *conn;
1655de181e88SJaganath Kanakkassery 
1656de181e88SJaganath Kanakkassery 		hci_dev_set_flag(hdev, HCI_LE_ADV);
1657de181e88SJaganath Kanakkassery 
16586a42e9bfSIulia Tanasescu 		if (adv && !adv->periodic)
165910279313SLuiz Augusto von Dentz 			adv->enabled = true;
166010279313SLuiz Augusto von Dentz 
1661de181e88SJaganath Kanakkassery 		conn = hci_lookup_le_connect(hdev);
1662de181e88SJaganath Kanakkassery 		if (conn)
1663de181e88SJaganath Kanakkassery 			queue_delayed_work(hdev->workqueue,
1664de181e88SJaganath Kanakkassery 					   &conn->le_conn_timeout,
1665de181e88SJaganath Kanakkassery 					   conn->conn_timeout);
166645b7749fSJaganath Kanakkassery 	} else {
16672128939fSArchie Pusaka 		if (cp->num_of_sets) {
16682128939fSArchie Pusaka 			if (adv)
166910279313SLuiz Augusto von Dentz 				adv->enabled = false;
16702128939fSArchie Pusaka 
167110279313SLuiz Augusto von Dentz 			/* If just one instance was disabled check if there are
167210279313SLuiz Augusto von Dentz 			 * any other instance enabled before clearing HCI_LE_ADV
167310279313SLuiz Augusto von Dentz 			 */
167410279313SLuiz Augusto von Dentz 			list_for_each_entry_safe(adv, n, &hdev->adv_instances,
167510279313SLuiz Augusto von Dentz 						 list) {
167610279313SLuiz Augusto von Dentz 				if (adv->enabled)
167710279313SLuiz Augusto von Dentz 					goto unlock;
167810279313SLuiz Augusto von Dentz 			}
167910279313SLuiz Augusto von Dentz 		} else {
168010279313SLuiz Augusto von Dentz 			/* All instances shall be considered disabled */
168110279313SLuiz Augusto von Dentz 			list_for_each_entry_safe(adv, n, &hdev->adv_instances,
168210279313SLuiz Augusto von Dentz 						 list)
168310279313SLuiz Augusto von Dentz 				adv->enabled = false;
168410279313SLuiz Augusto von Dentz 		}
168510279313SLuiz Augusto von Dentz 
168645b7749fSJaganath Kanakkassery 		hci_dev_clear_flag(hdev, HCI_LE_ADV);
1687de181e88SJaganath Kanakkassery 	}
1688de181e88SJaganath Kanakkassery 
168910279313SLuiz Augusto von Dentz unlock:
1690de181e88SJaganath Kanakkassery 	hci_dev_unlock(hdev);
1691c8992cffSLuiz Augusto von Dentz 	return rp->status;
1692de181e88SJaganath Kanakkassery }
1693de181e88SJaganath Kanakkassery 
1694c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_scan_param(struct hci_dev *hdev, void *data,
1695c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
1696533553f8SMarcel Holtmann {
1697533553f8SMarcel Holtmann 	struct hci_cp_le_set_scan_param *cp;
1698c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1699533553f8SMarcel Holtmann 
1700e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1701e3f3a1aeSLuiz Augusto von Dentz 
1702e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1703c8992cffSLuiz Augusto von Dentz 		return rp->status;
170445296acdSMarcel Holtmann 
1705533553f8SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_PARAM);
1706533553f8SMarcel Holtmann 	if (!cp)
1707c8992cffSLuiz Augusto von Dentz 		return rp->status;
1708533553f8SMarcel Holtmann 
1709533553f8SMarcel Holtmann 	hci_dev_lock(hdev);
1710533553f8SMarcel Holtmann 
1711533553f8SMarcel Holtmann 	hdev->le_scan_type = cp->type;
1712533553f8SMarcel Holtmann 
1713533553f8SMarcel Holtmann 	hci_dev_unlock(hdev);
1714c8992cffSLuiz Augusto von Dentz 
1715c8992cffSLuiz Augusto von Dentz 	return rp->status;
1716533553f8SMarcel Holtmann }
1717533553f8SMarcel Holtmann 
1718c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_ext_scan_param(struct hci_dev *hdev, void *data,
1719a2344b9eSJaganath Kanakkassery 				       struct sk_buff *skb)
1720a2344b9eSJaganath Kanakkassery {
1721a2344b9eSJaganath Kanakkassery 	struct hci_cp_le_set_ext_scan_params *cp;
1722c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1723a2344b9eSJaganath Kanakkassery 	struct hci_cp_le_scan_phy_params *phy_param;
1724a2344b9eSJaganath Kanakkassery 
1725e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1726e3f3a1aeSLuiz Augusto von Dentz 
1727e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1728c8992cffSLuiz Augusto von Dentz 		return rp->status;
1729a2344b9eSJaganath Kanakkassery 
1730a2344b9eSJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_SCAN_PARAMS);
1731a2344b9eSJaganath Kanakkassery 	if (!cp)
1732c8992cffSLuiz Augusto von Dentz 		return rp->status;
1733a2344b9eSJaganath Kanakkassery 
1734a2344b9eSJaganath Kanakkassery 	phy_param = (void *)cp->data;
1735a2344b9eSJaganath Kanakkassery 
1736a2344b9eSJaganath Kanakkassery 	hci_dev_lock(hdev);
1737a2344b9eSJaganath Kanakkassery 
1738a2344b9eSJaganath Kanakkassery 	hdev->le_scan_type = phy_param->type;
1739a2344b9eSJaganath Kanakkassery 
1740a2344b9eSJaganath Kanakkassery 	hci_dev_unlock(hdev);
1741c8992cffSLuiz Augusto von Dentz 
1742c8992cffSLuiz Augusto von Dentz 	return rp->status;
1743a2344b9eSJaganath Kanakkassery }
1744a2344b9eSJaganath Kanakkassery 
1745b9a6328fSJohan Hedberg static bool has_pending_adv_report(struct hci_dev *hdev)
1746b9a6328fSJohan Hedberg {
1747b9a6328fSJohan Hedberg 	struct discovery_state *d = &hdev->discovery;
1748b9a6328fSJohan Hedberg 
1749b9a6328fSJohan Hedberg 	return bacmp(&d->last_adv_addr, BDADDR_ANY);
1750b9a6328fSJohan Hedberg }
1751b9a6328fSJohan Hedberg 
1752b9a6328fSJohan Hedberg static void clear_pending_adv_report(struct hci_dev *hdev)
1753b9a6328fSJohan Hedberg {
1754b9a6328fSJohan Hedberg 	struct discovery_state *d = &hdev->discovery;
1755b9a6328fSJohan Hedberg 
1756b9a6328fSJohan Hedberg 	bacpy(&d->last_adv_addr, BDADDR_ANY);
1757b9a6328fSJohan Hedberg 	d->last_adv_data_len = 0;
1758b9a6328fSJohan Hedberg }
1759b9a6328fSJohan Hedberg 
1760b9a6328fSJohan Hedberg static void store_pending_adv_report(struct hci_dev *hdev, bdaddr_t *bdaddr,
1761c70a7e4cSMarcel Holtmann 				     u8 bdaddr_type, s8 rssi, u32 flags,
1762c70a7e4cSMarcel Holtmann 				     u8 *data, u8 len)
1763b9a6328fSJohan Hedberg {
1764b9a6328fSJohan Hedberg 	struct discovery_state *d = &hdev->discovery;
1765b9a6328fSJohan Hedberg 
1766112b5090SLuiz Augusto von Dentz 	if (len > max_adv_len(hdev))
1767a2ec905dSAlain Michaud 		return;
1768a2ec905dSAlain Michaud 
1769b9a6328fSJohan Hedberg 	bacpy(&d->last_adv_addr, bdaddr);
1770b9a6328fSJohan Hedberg 	d->last_adv_addr_type = bdaddr_type;
1771ff5cd29fSJohan Hedberg 	d->last_adv_rssi = rssi;
1772c70a7e4cSMarcel Holtmann 	d->last_adv_flags = flags;
1773b9a6328fSJohan Hedberg 	memcpy(d->last_adv_data, data, len);
1774b9a6328fSJohan Hedberg 	d->last_adv_data_len = len;
1775b9a6328fSJohan Hedberg }
1776b9a6328fSJohan Hedberg 
17773baef810SJaganath Kanakkassery static void le_set_scan_enable_complete(struct hci_dev *hdev, u8 enable)
1778eb9d91f5SAndre Guedes {
17795c1a4c8fSJaganath Kanakkassery 	hci_dev_lock(hdev);
17805c1a4c8fSJaganath Kanakkassery 
17813baef810SJaganath Kanakkassery 	switch (enable) {
17823fd319b8SAndre Guedes 	case LE_SCAN_ENABLE:
1783a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_LE_SCAN);
1784b9a6328fSJohan Hedberg 		if (hdev->le_scan_type == LE_SCAN_ACTIVE)
1785b9a6328fSJohan Hedberg 			clear_pending_adv_report(hdev);
1786b338d917SBrian Gix 		if (hci_dev_test_flag(hdev, HCI_MESH))
1787b338d917SBrian Gix 			hci_discovery_set_state(hdev, DISCOVERY_FINDING);
178868a8aea4SAndrei Emeltchenko 		break;
178968a8aea4SAndrei Emeltchenko 
179076a388beSAndre Guedes 	case LE_SCAN_DISABLE:
1791b9a6328fSJohan Hedberg 		/* We do this here instead of when setting DISCOVERY_STOPPED
1792b9a6328fSJohan Hedberg 		 * since the latter would potentially require waiting for
1793b9a6328fSJohan Hedberg 		 * inquiry to stop too.
1794b9a6328fSJohan Hedberg 		 */
1795b9a6328fSJohan Hedberg 		if (has_pending_adv_report(hdev)) {
1796b9a6328fSJohan Hedberg 			struct discovery_state *d = &hdev->discovery;
1797b9a6328fSJohan Hedberg 
1798b9a6328fSJohan Hedberg 			mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
1799ab0aa433SJohan Hedberg 					  d->last_adv_addr_type, NULL,
1800c70a7e4cSMarcel Holtmann 					  d->last_adv_rssi, d->last_adv_flags,
1801ab0aa433SJohan Hedberg 					  d->last_adv_data,
1802b338d917SBrian Gix 					  d->last_adv_data_len, NULL, 0, 0);
1803b9a6328fSJohan Hedberg 		}
1804b9a6328fSJohan Hedberg 
1805317ac8cbSJohan Hedberg 		/* Cancel this timer so that we don't try to disable scanning
1806317ac8cbSJohan Hedberg 		 * when it's already disabled.
1807317ac8cbSJohan Hedberg 		 */
1808317ac8cbSJohan Hedberg 		cancel_delayed_work(&hdev->le_scan_disable);
1809317ac8cbSJohan Hedberg 
1810a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LE_SCAN);
1811e8bb6b97SJohan Hedberg 
181281ad6fd9SJohan Hedberg 		/* The HCI_LE_SCAN_INTERRUPTED flag indicates that we
181381ad6fd9SJohan Hedberg 		 * interrupted scanning due to a connect request. Mark
1814abfeea47SLuiz Augusto von Dentz 		 * therefore discovery as stopped.
181581ad6fd9SJohan Hedberg 		 */
1816a69d8927SMarcel Holtmann 		if (hci_dev_test_and_clear_flag(hdev, HCI_LE_SCAN_INTERRUPTED))
181781ad6fd9SJohan Hedberg 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1818b338d917SBrian Gix 		else if (!hci_dev_test_flag(hdev, HCI_LE_ADV) &&
1819b338d917SBrian Gix 			 hdev->discovery.state == DISCOVERY_FINDING)
1820b338d917SBrian Gix 			queue_work(hdev->workqueue, &hdev->reenable_adv_work);
1821e8bb6b97SJohan Hedberg 
182268a8aea4SAndrei Emeltchenko 		break;
182368a8aea4SAndrei Emeltchenko 
182468a8aea4SAndrei Emeltchenko 	default:
18252064ee33SMarcel Holtmann 		bt_dev_err(hdev, "use of reserved LE_Scan_Enable param %d",
18263baef810SJaganath Kanakkassery 			   enable);
182768a8aea4SAndrei Emeltchenko 		break;
182835815085SAndre Guedes 	}
18295c1a4c8fSJaganath Kanakkassery 
18305c1a4c8fSJaganath Kanakkassery 	hci_dev_unlock(hdev);
1831eb9d91f5SAndre Guedes }
1832eb9d91f5SAndre Guedes 
1833c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_scan_enable(struct hci_dev *hdev, void *data,
18343baef810SJaganath Kanakkassery 				    struct sk_buff *skb)
18353baef810SJaganath Kanakkassery {
18363baef810SJaganath Kanakkassery 	struct hci_cp_le_set_scan_enable *cp;
1837c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
18383baef810SJaganath Kanakkassery 
1839e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1840e3f3a1aeSLuiz Augusto von Dentz 
1841e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1842c8992cffSLuiz Augusto von Dentz 		return rp->status;
18433baef810SJaganath Kanakkassery 
18443baef810SJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
18453baef810SJaganath Kanakkassery 	if (!cp)
1846c8992cffSLuiz Augusto von Dentz 		return rp->status;
18473baef810SJaganath Kanakkassery 
18483baef810SJaganath Kanakkassery 	le_set_scan_enable_complete(hdev, cp->enable);
1849c8992cffSLuiz Augusto von Dentz 
1850c8992cffSLuiz Augusto von Dentz 	return rp->status;
18513baef810SJaganath Kanakkassery }
18523baef810SJaganath Kanakkassery 
1853c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_ext_scan_enable(struct hci_dev *hdev, void *data,
1854a2344b9eSJaganath Kanakkassery 					struct sk_buff *skb)
1855a2344b9eSJaganath Kanakkassery {
1856a2344b9eSJaganath Kanakkassery 	struct hci_cp_le_set_ext_scan_enable *cp;
1857c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1858a2344b9eSJaganath Kanakkassery 
1859e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1860e3f3a1aeSLuiz Augusto von Dentz 
1861e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1862c8992cffSLuiz Augusto von Dentz 		return rp->status;
1863a2344b9eSJaganath Kanakkassery 
1864a2344b9eSJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_SCAN_ENABLE);
1865a2344b9eSJaganath Kanakkassery 	if (!cp)
1866c8992cffSLuiz Augusto von Dentz 		return rp->status;
1867a2344b9eSJaganath Kanakkassery 
1868a2344b9eSJaganath Kanakkassery 	le_set_scan_enable_complete(hdev, cp->enable);
1869c8992cffSLuiz Augusto von Dentz 
1870c8992cffSLuiz Augusto von Dentz 	return rp->status;
1871a2344b9eSJaganath Kanakkassery }
1872a2344b9eSJaganath Kanakkassery 
1873c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_num_adv_sets(struct hci_dev *hdev, void *data,
18746b49bcb4SJaganath Kanakkassery 				      struct sk_buff *skb)
18756b49bcb4SJaganath Kanakkassery {
1876c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_num_supported_adv_sets *rp = data;
1877e3f3a1aeSLuiz Augusto von Dentz 
1878e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x No of Adv sets %u", rp->status,
18796b49bcb4SJaganath Kanakkassery 		   rp->num_of_sets);
18806b49bcb4SJaganath Kanakkassery 
18816b49bcb4SJaganath Kanakkassery 	if (rp->status)
1882c8992cffSLuiz Augusto von Dentz 		return rp->status;
18836b49bcb4SJaganath Kanakkassery 
18846b49bcb4SJaganath Kanakkassery 	hdev->le_num_of_adv_sets = rp->num_of_sets;
1885c8992cffSLuiz Augusto von Dentz 
1886c8992cffSLuiz Augusto von Dentz 	return rp->status;
18876b49bcb4SJaganath Kanakkassery }
18886b49bcb4SJaganath Kanakkassery 
1889c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_accept_list_size(struct hci_dev *hdev, void *data,
1890cf1d081fSJohan Hedberg 					  struct sk_buff *skb)
1891cf1d081fSJohan Hedberg {
1892c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_accept_list_size *rp = data;
1893e3f3a1aeSLuiz Augusto von Dentz 
1894e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x size %u", rp->status, rp->size);
1895cf1d081fSJohan Hedberg 
189645296acdSMarcel Holtmann 	if (rp->status)
1897c8992cffSLuiz Augusto von Dentz 		return rp->status;
189845296acdSMarcel Holtmann 
18993d4f9c00SArchie Pusaka 	hdev->le_accept_list_size = rp->size;
1900c8992cffSLuiz Augusto von Dentz 
1901c8992cffSLuiz Augusto von Dentz 	return rp->status;
1902cf1d081fSJohan Hedberg }
1903cf1d081fSJohan Hedberg 
1904c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_clear_accept_list(struct hci_dev *hdev, void *data,
19050f36b589SMarcel Holtmann 				      struct sk_buff *skb)
19060f36b589SMarcel Holtmann {
1907c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
19080f36b589SMarcel Holtmann 
1909e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1910e3f3a1aeSLuiz Augusto von Dentz 
1911e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1912c8992cffSLuiz Augusto von Dentz 		return rp->status;
191345296acdSMarcel Holtmann 
19145e2b6064SNiels Dossche 	hci_dev_lock(hdev);
19153d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->le_accept_list);
19165e2b6064SNiels Dossche 	hci_dev_unlock(hdev);
1917c8992cffSLuiz Augusto von Dentz 
1918c8992cffSLuiz Augusto von Dentz 	return rp->status;
19190f36b589SMarcel Holtmann }
19200f36b589SMarcel Holtmann 
1921c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_add_to_accept_list(struct hci_dev *hdev, void *data,
19220f36b589SMarcel Holtmann 				       struct sk_buff *skb)
19230f36b589SMarcel Holtmann {
19243d4f9c00SArchie Pusaka 	struct hci_cp_le_add_to_accept_list *sent;
1925c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
19260f36b589SMarcel Holtmann 
1927e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1928e3f3a1aeSLuiz Augusto von Dentz 
1929e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1930c8992cffSLuiz Augusto von Dentz 		return rp->status;
193145296acdSMarcel Holtmann 
19323d4f9c00SArchie Pusaka 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_ACCEPT_LIST);
19330f36b589SMarcel Holtmann 	if (!sent)
1934c8992cffSLuiz Augusto von Dentz 		return rp->status;
19350f36b589SMarcel Holtmann 
19365e2b6064SNiels Dossche 	hci_dev_lock(hdev);
19373d4f9c00SArchie Pusaka 	hci_bdaddr_list_add(&hdev->le_accept_list, &sent->bdaddr,
1938dcc36c16SJohan Hedberg 			    sent->bdaddr_type);
19395e2b6064SNiels Dossche 	hci_dev_unlock(hdev);
1940c8992cffSLuiz Augusto von Dentz 
1941c8992cffSLuiz Augusto von Dentz 	return rp->status;
19420f36b589SMarcel Holtmann }
19430f36b589SMarcel Holtmann 
1944c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_del_from_accept_list(struct hci_dev *hdev, void *data,
19450f36b589SMarcel Holtmann 					 struct sk_buff *skb)
19460f36b589SMarcel Holtmann {
19473d4f9c00SArchie Pusaka 	struct hci_cp_le_del_from_accept_list *sent;
1948c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
19490f36b589SMarcel Holtmann 
1950e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1951e3f3a1aeSLuiz Augusto von Dentz 
1952e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1953c8992cffSLuiz Augusto von Dentz 		return rp->status;
195445296acdSMarcel Holtmann 
19553d4f9c00SArchie Pusaka 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_ACCEPT_LIST);
19560f36b589SMarcel Holtmann 	if (!sent)
1957c8992cffSLuiz Augusto von Dentz 		return rp->status;
19580f36b589SMarcel Holtmann 
19595e2b6064SNiels Dossche 	hci_dev_lock(hdev);
19603d4f9c00SArchie Pusaka 	hci_bdaddr_list_del(&hdev->le_accept_list, &sent->bdaddr,
1961dcc36c16SJohan Hedberg 			    sent->bdaddr_type);
19625e2b6064SNiels Dossche 	hci_dev_unlock(hdev);
1963c8992cffSLuiz Augusto von Dentz 
1964c8992cffSLuiz Augusto von Dentz 	return rp->status;
19650f36b589SMarcel Holtmann }
19660f36b589SMarcel Holtmann 
1967c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_supported_states(struct hci_dev *hdev, void *data,
19689b008c04SJohan Hedberg 					  struct sk_buff *skb)
19699b008c04SJohan Hedberg {
1970c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_supported_states *rp = data;
1971e3f3a1aeSLuiz Augusto von Dentz 
1972e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
19739b008c04SJohan Hedberg 
197445296acdSMarcel Holtmann 	if (rp->status)
1975c8992cffSLuiz Augusto von Dentz 		return rp->status;
197645296acdSMarcel Holtmann 
19779b008c04SJohan Hedberg 	memcpy(hdev->le_states, rp->le_states, 8);
1978c8992cffSLuiz Augusto von Dentz 
1979c8992cffSLuiz Augusto von Dentz 	return rp->status;
19809b008c04SJohan Hedberg }
19819b008c04SJohan Hedberg 
1982c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_def_data_len(struct hci_dev *hdev, void *data,
1983a8e1bfaaSMarcel Holtmann 				      struct sk_buff *skb)
1984a8e1bfaaSMarcel Holtmann {
1985c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_def_data_len *rp = data;
1986e3f3a1aeSLuiz Augusto von Dentz 
1987e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1988a8e1bfaaSMarcel Holtmann 
1989a8e1bfaaSMarcel Holtmann 	if (rp->status)
1990c8992cffSLuiz Augusto von Dentz 		return rp->status;
1991a8e1bfaaSMarcel Holtmann 
1992a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_len = le16_to_cpu(rp->tx_len);
1993a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_time = le16_to_cpu(rp->tx_time);
1994c8992cffSLuiz Augusto von Dentz 
1995c8992cffSLuiz Augusto von Dentz 	return rp->status;
1996a8e1bfaaSMarcel Holtmann }
1997a8e1bfaaSMarcel Holtmann 
1998c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_write_def_data_len(struct hci_dev *hdev, void *data,
1999a8e1bfaaSMarcel Holtmann 				       struct sk_buff *skb)
2000a8e1bfaaSMarcel Holtmann {
2001a8e1bfaaSMarcel Holtmann 	struct hci_cp_le_write_def_data_len *sent;
2002c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
2003a8e1bfaaSMarcel Holtmann 
2004e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2005e3f3a1aeSLuiz Augusto von Dentz 
2006e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
2007c8992cffSLuiz Augusto von Dentz 		return rp->status;
2008a8e1bfaaSMarcel Holtmann 
2009a8e1bfaaSMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_WRITE_DEF_DATA_LEN);
2010a8e1bfaaSMarcel Holtmann 	if (!sent)
2011c8992cffSLuiz Augusto von Dentz 		return rp->status;
2012a8e1bfaaSMarcel Holtmann 
2013a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_len = le16_to_cpu(sent->tx_len);
2014a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_time = le16_to_cpu(sent->tx_time);
2015c8992cffSLuiz Augusto von Dentz 
2016c8992cffSLuiz Augusto von Dentz 	return rp->status;
2017a8e1bfaaSMarcel Holtmann }
2018a8e1bfaaSMarcel Holtmann 
2019c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_add_to_resolv_list(struct hci_dev *hdev, void *data,
2020b950aa88SAnkit Navik 				       struct sk_buff *skb)
2021b950aa88SAnkit Navik {
2022b950aa88SAnkit Navik 	struct hci_cp_le_add_to_resolv_list *sent;
2023c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
2024b950aa88SAnkit Navik 
2025e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2026e3f3a1aeSLuiz Augusto von Dentz 
2027e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
2028c8992cffSLuiz Augusto von Dentz 		return rp->status;
2029b950aa88SAnkit Navik 
2030b950aa88SAnkit Navik 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_RESOLV_LIST);
2031b950aa88SAnkit Navik 	if (!sent)
2032c8992cffSLuiz Augusto von Dentz 		return rp->status;
2033b950aa88SAnkit Navik 
20345e2b6064SNiels Dossche 	hci_dev_lock(hdev);
2035b950aa88SAnkit Navik 	hci_bdaddr_list_add_with_irk(&hdev->le_resolv_list, &sent->bdaddr,
2036b950aa88SAnkit Navik 				sent->bdaddr_type, sent->peer_irk,
2037b950aa88SAnkit Navik 				sent->local_irk);
20385e2b6064SNiels Dossche 	hci_dev_unlock(hdev);
2039c8992cffSLuiz Augusto von Dentz 
2040c8992cffSLuiz Augusto von Dentz 	return rp->status;
2041b950aa88SAnkit Navik }
2042b950aa88SAnkit Navik 
2043c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_del_from_resolv_list(struct hci_dev *hdev, void *data,
2044b950aa88SAnkit Navik 					 struct sk_buff *skb)
2045b950aa88SAnkit Navik {
2046b950aa88SAnkit Navik 	struct hci_cp_le_del_from_resolv_list *sent;
2047c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
2048b950aa88SAnkit Navik 
2049e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2050e3f3a1aeSLuiz Augusto von Dentz 
2051e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
2052c8992cffSLuiz Augusto von Dentz 		return rp->status;
2053b950aa88SAnkit Navik 
2054b950aa88SAnkit Navik 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_RESOLV_LIST);
2055b950aa88SAnkit Navik 	if (!sent)
2056c8992cffSLuiz Augusto von Dentz 		return rp->status;
2057b950aa88SAnkit Navik 
20585e2b6064SNiels Dossche 	hci_dev_lock(hdev);
2059b950aa88SAnkit Navik 	hci_bdaddr_list_del_with_irk(&hdev->le_resolv_list, &sent->bdaddr,
2060b950aa88SAnkit Navik 			    sent->bdaddr_type);
20615e2b6064SNiels Dossche 	hci_dev_unlock(hdev);
2062c8992cffSLuiz Augusto von Dentz 
2063c8992cffSLuiz Augusto von Dentz 	return rp->status;
2064b950aa88SAnkit Navik }
2065b950aa88SAnkit Navik 
2066c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_clear_resolv_list(struct hci_dev *hdev, void *data,
2067545f2596SAnkit Navik 				      struct sk_buff *skb)
2068545f2596SAnkit Navik {
2069c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
2070545f2596SAnkit Navik 
2071e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2072e3f3a1aeSLuiz Augusto von Dentz 
2073e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
2074c8992cffSLuiz Augusto von Dentz 		return rp->status;
2075545f2596SAnkit Navik 
20765e2b6064SNiels Dossche 	hci_dev_lock(hdev);
2077545f2596SAnkit Navik 	hci_bdaddr_list_clear(&hdev->le_resolv_list);
20785e2b6064SNiels Dossche 	hci_dev_unlock(hdev);
2079c8992cffSLuiz Augusto von Dentz 
2080c8992cffSLuiz Augusto von Dentz 	return rp->status;
2081545f2596SAnkit Navik }
2082545f2596SAnkit Navik 
2083c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_resolv_list_size(struct hci_dev *hdev, void *data,
2084cfdb0c2dSAnkit Navik 					  struct sk_buff *skb)
2085cfdb0c2dSAnkit Navik {
2086c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_resolv_list_size *rp = data;
2087e3f3a1aeSLuiz Augusto von Dentz 
2088e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x size %u", rp->status, rp->size);
2089cfdb0c2dSAnkit Navik 
2090cfdb0c2dSAnkit Navik 	if (rp->status)
2091c8992cffSLuiz Augusto von Dentz 		return rp->status;
2092cfdb0c2dSAnkit Navik 
2093cfdb0c2dSAnkit Navik 	hdev->le_resolv_list_size = rp->size;
2094c8992cffSLuiz Augusto von Dentz 
2095c8992cffSLuiz Augusto von Dentz 	return rp->status;
2096cfdb0c2dSAnkit Navik }
2097cfdb0c2dSAnkit Navik 
2098c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_addr_resolution_enable(struct hci_dev *hdev, void *data,
2099aa12af77SAnkit Navik 					       struct sk_buff *skb)
2100aa12af77SAnkit Navik {
2101c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
2102e3f3a1aeSLuiz Augusto von Dentz 	__u8 *sent;
2103aa12af77SAnkit Navik 
2104e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2105e3f3a1aeSLuiz Augusto von Dentz 
2106e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
2107c8992cffSLuiz Augusto von Dentz 		return rp->status;
2108aa12af77SAnkit Navik 
2109aa12af77SAnkit Navik 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADDR_RESOLV_ENABLE);
2110aa12af77SAnkit Navik 	if (!sent)
2111c8992cffSLuiz Augusto von Dentz 		return rp->status;
2112aa12af77SAnkit Navik 
2113aa12af77SAnkit Navik 	hci_dev_lock(hdev);
2114aa12af77SAnkit Navik 
2115aa12af77SAnkit Navik 	if (*sent)
2116aa12af77SAnkit Navik 		hci_dev_set_flag(hdev, HCI_LL_RPA_RESOLUTION);
2117aa12af77SAnkit Navik 	else
2118aa12af77SAnkit Navik 		hci_dev_clear_flag(hdev, HCI_LL_RPA_RESOLUTION);
2119aa12af77SAnkit Navik 
2120aa12af77SAnkit Navik 	hci_dev_unlock(hdev);
2121c8992cffSLuiz Augusto von Dentz 
2122c8992cffSLuiz Augusto von Dentz 	return rp->status;
2123aa12af77SAnkit Navik }
2124aa12af77SAnkit Navik 
2125c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_max_data_len(struct hci_dev *hdev, void *data,
2126a8e1bfaaSMarcel Holtmann 				      struct sk_buff *skb)
2127a8e1bfaaSMarcel Holtmann {
2128c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_max_data_len *rp = data;
2129e3f3a1aeSLuiz Augusto von Dentz 
2130e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2131a8e1bfaaSMarcel Holtmann 
2132a8e1bfaaSMarcel Holtmann 	if (rp->status)
2133c8992cffSLuiz Augusto von Dentz 		return rp->status;
2134a8e1bfaaSMarcel Holtmann 
2135a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_len = le16_to_cpu(rp->tx_len);
2136a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_time = le16_to_cpu(rp->tx_time);
2137a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_len = le16_to_cpu(rp->rx_len);
2138a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_time = le16_to_cpu(rp->rx_time);
2139c8992cffSLuiz Augusto von Dentz 
2140c8992cffSLuiz Augusto von Dentz 	return rp->status;
2141a8e1bfaaSMarcel Holtmann }
2142a8e1bfaaSMarcel Holtmann 
2143c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_le_host_supported(struct hci_dev *hdev, void *data,
2144f9b49306SAndre Guedes 					 struct sk_buff *skb)
2145f9b49306SAndre Guedes {
214606199cf8SJohan Hedberg 	struct hci_cp_write_le_host_supported *sent;
2147c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
2148f9b49306SAndre Guedes 
2149e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2150e3f3a1aeSLuiz Augusto von Dentz 
2151e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
2152c8992cffSLuiz Augusto von Dentz 		return rp->status;
215345296acdSMarcel Holtmann 
215406199cf8SJohan Hedberg 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
21558f984dfaSJohan Hedberg 	if (!sent)
2156c8992cffSLuiz Augusto von Dentz 		return rp->status;
2157f9b49306SAndre Guedes 
21585c1a4c8fSJaganath Kanakkassery 	hci_dev_lock(hdev);
21595c1a4c8fSJaganath Kanakkassery 
2160416a4ae5SJohan Hedberg 	if (sent->le) {
2161cad718edSJohan Hedberg 		hdev->features[1][0] |= LMP_HOST_LE;
2162a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_LE_ENABLED);
2163416a4ae5SJohan Hedberg 	} else {
2164cad718edSJohan Hedberg 		hdev->features[1][0] &= ~LMP_HOST_LE;
2165a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LE_ENABLED);
2166a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_ADVERTISING);
2167416a4ae5SJohan Hedberg 	}
216853b2caabSJohan Hedberg 
216953b2caabSJohan Hedberg 	if (sent->simul)
2170cad718edSJohan Hedberg 		hdev->features[1][0] |= LMP_HOST_LE_BREDR;
217153b2caabSJohan Hedberg 	else
2172cad718edSJohan Hedberg 		hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
21735c1a4c8fSJaganath Kanakkassery 
21745c1a4c8fSJaganath Kanakkassery 	hci_dev_unlock(hdev);
2175c8992cffSLuiz Augusto von Dentz 
2176c8992cffSLuiz Augusto von Dentz 	return rp->status;
21778f984dfaSJohan Hedberg }
2178f9b49306SAndre Guedes 
2179c8992cffSLuiz Augusto von Dentz static u8 hci_cc_set_adv_param(struct hci_dev *hdev, void *data,
2180c8992cffSLuiz Augusto von Dentz 			       struct sk_buff *skb)
218156ed2cb8SJohan Hedberg {
218256ed2cb8SJohan Hedberg 	struct hci_cp_le_set_adv_param *cp;
2183c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
218456ed2cb8SJohan Hedberg 
2185e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2186e3f3a1aeSLuiz Augusto von Dentz 
2187e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
2188c8992cffSLuiz Augusto von Dentz 		return rp->status;
218956ed2cb8SJohan Hedberg 
219056ed2cb8SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_PARAM);
219156ed2cb8SJohan Hedberg 	if (!cp)
2192c8992cffSLuiz Augusto von Dentz 		return rp->status;
219356ed2cb8SJohan Hedberg 
219456ed2cb8SJohan Hedberg 	hci_dev_lock(hdev);
219556ed2cb8SJohan Hedberg 	hdev->adv_addr_type = cp->own_address_type;
219656ed2cb8SJohan Hedberg 	hci_dev_unlock(hdev);
2197c8992cffSLuiz Augusto von Dentz 
2198c8992cffSLuiz Augusto von Dentz 	return rp->status;
219956ed2cb8SJohan Hedberg }
220056ed2cb8SJohan Hedberg 
2201c8992cffSLuiz Augusto von Dentz static u8 hci_cc_set_ext_adv_param(struct hci_dev *hdev, void *data,
2202c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
2203de181e88SJaganath Kanakkassery {
2204c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_set_ext_adv_params *rp = data;
2205de181e88SJaganath Kanakkassery 	struct hci_cp_le_set_ext_adv_params *cp;
2206de181e88SJaganath Kanakkassery 	struct adv_info *adv_instance;
2207de181e88SJaganath Kanakkassery 
2208e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2209de181e88SJaganath Kanakkassery 
2210de181e88SJaganath Kanakkassery 	if (rp->status)
2211c8992cffSLuiz Augusto von Dentz 		return rp->status;
2212de181e88SJaganath Kanakkassery 
2213de181e88SJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_ADV_PARAMS);
2214de181e88SJaganath Kanakkassery 	if (!cp)
2215c8992cffSLuiz Augusto von Dentz 		return rp->status;
2216de181e88SJaganath Kanakkassery 
2217de181e88SJaganath Kanakkassery 	hci_dev_lock(hdev);
2218de181e88SJaganath Kanakkassery 	hdev->adv_addr_type = cp->own_addr_type;
221925e70886SDaniel Winkler 	if (!cp->handle) {
2220de181e88SJaganath Kanakkassery 		/* Store in hdev for instance 0 */
2221de181e88SJaganath Kanakkassery 		hdev->adv_tx_power = rp->tx_power;
2222de181e88SJaganath Kanakkassery 	} else {
222325e70886SDaniel Winkler 		adv_instance = hci_find_adv_instance(hdev, cp->handle);
2224de181e88SJaganath Kanakkassery 		if (adv_instance)
2225de181e88SJaganath Kanakkassery 			adv_instance->tx_power = rp->tx_power;
2226de181e88SJaganath Kanakkassery 	}
2227a0fb3726SJaganath Kanakkassery 	/* Update adv data as tx power is known now */
2228651cd3d6SBrian Gix 	hci_update_adv_data(hdev, cp->handle);
222912410572SDaniel Winkler 
2230de181e88SJaganath Kanakkassery 	hci_dev_unlock(hdev);
2231c8992cffSLuiz Augusto von Dentz 
2232c8992cffSLuiz Augusto von Dentz 	return rp->status;
2233de181e88SJaganath Kanakkassery }
2234de181e88SJaganath Kanakkassery 
2235c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_rssi(struct hci_dev *hdev, void *data,
2236c8992cffSLuiz Augusto von Dentz 			   struct sk_buff *skb)
22375ae76a94SAndrzej Kaczmarek {
2238c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_rssi *rp = data;
22395ae76a94SAndrzej Kaczmarek 	struct hci_conn *conn;
22405ae76a94SAndrzej Kaczmarek 
2241e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
22425ae76a94SAndrzej Kaczmarek 
22435ae76a94SAndrzej Kaczmarek 	if (rp->status)
2244c8992cffSLuiz Augusto von Dentz 		return rp->status;
22455ae76a94SAndrzej Kaczmarek 
22465ae76a94SAndrzej Kaczmarek 	hci_dev_lock(hdev);
22475ae76a94SAndrzej Kaczmarek 
22485ae76a94SAndrzej Kaczmarek 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
22495ae76a94SAndrzej Kaczmarek 	if (conn)
22505ae76a94SAndrzej Kaczmarek 		conn->rssi = rp->rssi;
22515ae76a94SAndrzej Kaczmarek 
22525ae76a94SAndrzej Kaczmarek 	hci_dev_unlock(hdev);
2253c8992cffSLuiz Augusto von Dentz 
2254c8992cffSLuiz Augusto von Dentz 	return rp->status;
22555ae76a94SAndrzej Kaczmarek }
22565ae76a94SAndrzej Kaczmarek 
2257c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_tx_power(struct hci_dev *hdev, void *data,
2258c8992cffSLuiz Augusto von Dentz 			       struct sk_buff *skb)
22595a134faeSAndrzej Kaczmarek {
22605a134faeSAndrzej Kaczmarek 	struct hci_cp_read_tx_power *sent;
2261c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_tx_power *rp = data;
22625a134faeSAndrzej Kaczmarek 	struct hci_conn *conn;
22635a134faeSAndrzej Kaczmarek 
2264e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
22655a134faeSAndrzej Kaczmarek 
22665a134faeSAndrzej Kaczmarek 	if (rp->status)
2267c8992cffSLuiz Augusto von Dentz 		return rp->status;
22685a134faeSAndrzej Kaczmarek 
22695a134faeSAndrzej Kaczmarek 	sent = hci_sent_cmd_data(hdev, HCI_OP_READ_TX_POWER);
22705a134faeSAndrzej Kaczmarek 	if (!sent)
2271c8992cffSLuiz Augusto von Dentz 		return rp->status;
22725a134faeSAndrzej Kaczmarek 
22735a134faeSAndrzej Kaczmarek 	hci_dev_lock(hdev);
22745a134faeSAndrzej Kaczmarek 
22755a134faeSAndrzej Kaczmarek 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
2276d0455ed9SAndrzej Kaczmarek 	if (!conn)
2277d0455ed9SAndrzej Kaczmarek 		goto unlock;
22785a134faeSAndrzej Kaczmarek 
2279d0455ed9SAndrzej Kaczmarek 	switch (sent->type) {
2280d0455ed9SAndrzej Kaczmarek 	case 0x00:
2281d0455ed9SAndrzej Kaczmarek 		conn->tx_power = rp->tx_power;
2282d0455ed9SAndrzej Kaczmarek 		break;
2283d0455ed9SAndrzej Kaczmarek 	case 0x01:
2284d0455ed9SAndrzej Kaczmarek 		conn->max_tx_power = rp->tx_power;
2285d0455ed9SAndrzej Kaczmarek 		break;
2286d0455ed9SAndrzej Kaczmarek 	}
2287d0455ed9SAndrzej Kaczmarek 
2288d0455ed9SAndrzej Kaczmarek unlock:
22895a134faeSAndrzej Kaczmarek 	hci_dev_unlock(hdev);
2290c8992cffSLuiz Augusto von Dentz 	return rp->status;
22915a134faeSAndrzej Kaczmarek }
22925a134faeSAndrzej Kaczmarek 
2293c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_ssp_debug_mode(struct hci_dev *hdev, void *data,
2294c8992cffSLuiz Augusto von Dentz 				      struct sk_buff *skb)
2295c50b33c8SMarcel Holtmann {
2296c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
2297c50b33c8SMarcel Holtmann 	u8 *mode;
2298c50b33c8SMarcel Holtmann 
2299e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2300e3f3a1aeSLuiz Augusto von Dentz 
2301e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
2302c8992cffSLuiz Augusto von Dentz 		return rp->status;
2303c50b33c8SMarcel Holtmann 
2304c50b33c8SMarcel Holtmann 	mode = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE);
2305c50b33c8SMarcel Holtmann 	if (mode)
2306c50b33c8SMarcel Holtmann 		hdev->ssp_debug_mode = *mode;
2307c8992cffSLuiz Augusto von Dentz 
2308c8992cffSLuiz Augusto von Dentz 	return rp->status;
2309c50b33c8SMarcel Holtmann }
2310c50b33c8SMarcel Holtmann 
23116039aa73SGustavo Padovan static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
2312a9de9248SMarcel Holtmann {
2313147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2314a9de9248SMarcel Holtmann 
2315a9de9248SMarcel Holtmann 	if (status) {
2316a9de9248SMarcel Holtmann 		hci_conn_check_pending(hdev);
2317314b2381SJohan Hedberg 		return;
2318314b2381SJohan Hedberg 	}
2319314b2381SJohan Hedberg 
232090d6a397SLuiz Augusto von Dentz 	if (hci_sent_cmd_data(hdev, HCI_OP_INQUIRY))
232189352e7dSAndre Guedes 		set_bit(HCI_INQUIRY, &hdev->flags);
2322a9de9248SMarcel Holtmann }
2323a9de9248SMarcel Holtmann 
23246039aa73SGustavo Padovan static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
23251da177e4SLinus Torvalds {
2326a9de9248SMarcel Holtmann 	struct hci_cp_create_conn *cp;
23271da177e4SLinus Torvalds 	struct hci_conn *conn;
23281da177e4SLinus Torvalds 
2329147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2330a9de9248SMarcel Holtmann 
2331a9de9248SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
23321da177e4SLinus Torvalds 	if (!cp)
23331da177e4SLinus Torvalds 		return;
23341da177e4SLinus Torvalds 
23351da177e4SLinus Torvalds 	hci_dev_lock(hdev);
23361da177e4SLinus Torvalds 
23371da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
23381da177e4SLinus Torvalds 
2339147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "bdaddr %pMR hcon %p", &cp->bdaddr, conn);
23401da177e4SLinus Torvalds 
23411da177e4SLinus Torvalds 	if (status) {
23421da177e4SLinus Torvalds 		if (conn && conn->state == BT_CONNECT) {
23434c67bc74SMarcel Holtmann 			if (status != 0x0c || conn->attempt > 2) {
23441da177e4SLinus Torvalds 				conn->state = BT_CLOSED;
2345539c496dSJohan Hedberg 				hci_connect_cfm(conn, status);
23461da177e4SLinus Torvalds 				hci_conn_del(conn);
23474c67bc74SMarcel Holtmann 			} else
23484c67bc74SMarcel Holtmann 				conn->state = BT_CONNECT2;
23491da177e4SLinus Torvalds 		}
23501da177e4SLinus Torvalds 	} else {
23511da177e4SLinus Torvalds 		if (!conn) {
235284cb0143SZiyang Xuan 			conn = hci_conn_add_unset(hdev, ACL_LINK, &cp->bdaddr,
2353a5c4e309SJohan Hedberg 						  HCI_ROLE_MASTER);
2354a5c4e309SJohan Hedberg 			if (!conn)
23552064ee33SMarcel Holtmann 				bt_dev_err(hdev, "no memory for new connection");
23561da177e4SLinus Torvalds 		}
23571da177e4SLinus Torvalds 	}
23581da177e4SLinus Torvalds 
23591da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
23601da177e4SLinus Torvalds }
23611da177e4SLinus Torvalds 
2362a9de9248SMarcel Holtmann static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
23631da177e4SLinus Torvalds {
2364a9de9248SMarcel Holtmann 	struct hci_cp_add_sco *cp;
236506149746SLuiz Augusto von Dentz 	struct hci_conn *acl;
236606149746SLuiz Augusto von Dentz 	struct hci_link *link;
23671da177e4SLinus Torvalds 	__u16 handle;
23681da177e4SLinus Torvalds 
2369147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2370b6a0dc82SMarcel Holtmann 
2371a9de9248SMarcel Holtmann 	if (!status)
2372a9de9248SMarcel Holtmann 		return;
2373a9de9248SMarcel Holtmann 
2374a9de9248SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
23751da177e4SLinus Torvalds 	if (!cp)
2376a9de9248SMarcel Holtmann 		return;
23771da177e4SLinus Torvalds 
23781da177e4SLinus Torvalds 	handle = __le16_to_cpu(cp->handle);
23791da177e4SLinus Torvalds 
2380147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "handle 0x%4.4x", handle);
23811da177e4SLinus Torvalds 
23821da177e4SLinus Torvalds 	hci_dev_lock(hdev);
23831da177e4SLinus Torvalds 
23841da177e4SLinus Torvalds 	acl = hci_conn_hash_lookup_handle(hdev, handle);
23855a08ecceSAndrei Emeltchenko 	if (acl) {
238606149746SLuiz Augusto von Dentz 		link = list_first_entry_or_null(&acl->link_list,
238706149746SLuiz Augusto von Dentz 						struct hci_link, list);
238806149746SLuiz Augusto von Dentz 		if (link && link->conn) {
238906149746SLuiz Augusto von Dentz 			link->conn->state = BT_CLOSED;
23901da177e4SLinus Torvalds 
239106149746SLuiz Augusto von Dentz 			hci_connect_cfm(link->conn, status);
239206149746SLuiz Augusto von Dentz 			hci_conn_del(link->conn);
23931da177e4SLinus Torvalds 		}
23945a08ecceSAndrei Emeltchenko 	}
23951da177e4SLinus Torvalds 
23961da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
23971da177e4SLinus Torvalds }
23981da177e4SLinus Torvalds 
2399f8558555SMarcel Holtmann static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
2400f8558555SMarcel Holtmann {
2401f8558555SMarcel Holtmann 	struct hci_cp_auth_requested *cp;
2402f8558555SMarcel Holtmann 	struct hci_conn *conn;
2403f8558555SMarcel Holtmann 
2404147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2405f8558555SMarcel Holtmann 
2406f8558555SMarcel Holtmann 	if (!status)
2407f8558555SMarcel Holtmann 		return;
2408f8558555SMarcel Holtmann 
2409f8558555SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
2410f8558555SMarcel Holtmann 	if (!cp)
2411f8558555SMarcel Holtmann 		return;
2412f8558555SMarcel Holtmann 
2413f8558555SMarcel Holtmann 	hci_dev_lock(hdev);
2414f8558555SMarcel Holtmann 
2415f8558555SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2416f8558555SMarcel Holtmann 	if (conn) {
2417f8558555SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
2418539c496dSJohan Hedberg 			hci_connect_cfm(conn, status);
241976a68ba0SDavid Herrmann 			hci_conn_drop(conn);
2420f8558555SMarcel Holtmann 		}
2421f8558555SMarcel Holtmann 	}
2422f8558555SMarcel Holtmann 
2423f8558555SMarcel Holtmann 	hci_dev_unlock(hdev);
2424f8558555SMarcel Holtmann }
2425f8558555SMarcel Holtmann 
2426f8558555SMarcel Holtmann static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
2427f8558555SMarcel Holtmann {
2428f8558555SMarcel Holtmann 	struct hci_cp_set_conn_encrypt *cp;
2429f8558555SMarcel Holtmann 	struct hci_conn *conn;
2430f8558555SMarcel Holtmann 
2431147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2432f8558555SMarcel Holtmann 
2433f8558555SMarcel Holtmann 	if (!status)
2434f8558555SMarcel Holtmann 		return;
2435f8558555SMarcel Holtmann 
2436f8558555SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
2437f8558555SMarcel Holtmann 	if (!cp)
2438f8558555SMarcel Holtmann 		return;
2439f8558555SMarcel Holtmann 
2440f8558555SMarcel Holtmann 	hci_dev_lock(hdev);
2441f8558555SMarcel Holtmann 
2442f8558555SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2443f8558555SMarcel Holtmann 	if (conn) {
2444f8558555SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
2445539c496dSJohan Hedberg 			hci_connect_cfm(conn, status);
244676a68ba0SDavid Herrmann 			hci_conn_drop(conn);
2447f8558555SMarcel Holtmann 		}
2448f8558555SMarcel Holtmann 	}
2449f8558555SMarcel Holtmann 
2450f8558555SMarcel Holtmann 	hci_dev_unlock(hdev);
2451f8558555SMarcel Holtmann }
2452f8558555SMarcel Holtmann 
2453127178d2SJohan Hedberg static int hci_outgoing_auth_needed(struct hci_dev *hdev,
2454392599b9SJohan Hedberg 				    struct hci_conn *conn)
2455392599b9SJohan Hedberg {
2456392599b9SJohan Hedberg 	if (conn->state != BT_CONFIG || !conn->out)
2457392599b9SJohan Hedberg 		return 0;
2458392599b9SJohan Hedberg 
2459765c2a96SJohan Hedberg 	if (conn->pending_sec_level == BT_SECURITY_SDP)
2460392599b9SJohan Hedberg 		return 0;
2461392599b9SJohan Hedberg 
2462392599b9SJohan Hedberg 	/* Only request authentication for SSP connections or non-SSP
2463264b8b4eSJohan Hedberg 	 * devices with sec_level MEDIUM or HIGH or if MITM protection
2464264b8b4eSJohan Hedberg 	 * is requested.
2465264b8b4eSJohan Hedberg 	 */
2466807deac2SGustavo Padovan 	if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
24677e3691e1SJohan Hedberg 	    conn->pending_sec_level != BT_SECURITY_FIPS &&
2468264b8b4eSJohan Hedberg 	    conn->pending_sec_level != BT_SECURITY_HIGH &&
2469264b8b4eSJohan Hedberg 	    conn->pending_sec_level != BT_SECURITY_MEDIUM)
2470392599b9SJohan Hedberg 		return 0;
2471392599b9SJohan Hedberg 
2472392599b9SJohan Hedberg 	return 1;
2473392599b9SJohan Hedberg }
2474392599b9SJohan Hedberg 
24756039aa73SGustavo Padovan static int hci_resolve_name(struct hci_dev *hdev,
247600abfe44SGustavo F. Padovan 				   struct inquiry_entry *e)
247730dc78e1SJohan Hedberg {
247830dc78e1SJohan Hedberg 	struct hci_cp_remote_name_req cp;
247930dc78e1SJohan Hedberg 
248030dc78e1SJohan Hedberg 	memset(&cp, 0, sizeof(cp));
248130dc78e1SJohan Hedberg 
248230dc78e1SJohan Hedberg 	bacpy(&cp.bdaddr, &e->data.bdaddr);
248330dc78e1SJohan Hedberg 	cp.pscan_rep_mode = e->data.pscan_rep_mode;
248430dc78e1SJohan Hedberg 	cp.pscan_mode = e->data.pscan_mode;
248530dc78e1SJohan Hedberg 	cp.clock_offset = e->data.clock_offset;
248630dc78e1SJohan Hedberg 
248730dc78e1SJohan Hedberg 	return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
248830dc78e1SJohan Hedberg }
248930dc78e1SJohan Hedberg 
2490b644ba33SJohan Hedberg static bool hci_resolve_next_name(struct hci_dev *hdev)
249130dc78e1SJohan Hedberg {
249230dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
249330dc78e1SJohan Hedberg 	struct inquiry_entry *e;
249430dc78e1SJohan Hedberg 
2495b644ba33SJohan Hedberg 	if (list_empty(&discov->resolve))
2496b644ba33SJohan Hedberg 		return false;
2497b644ba33SJohan Hedberg 
2498dbf6811aSArchie Pusaka 	/* We should stop if we already spent too much time resolving names. */
2499dbf6811aSArchie Pusaka 	if (time_after(jiffies, discov->name_resolve_timeout)) {
2500dbf6811aSArchie Pusaka 		bt_dev_warn_ratelimited(hdev, "Name resolve takes too long.");
2501dbf6811aSArchie Pusaka 		return false;
2502dbf6811aSArchie Pusaka 	}
2503dbf6811aSArchie Pusaka 
2504b644ba33SJohan Hedberg 	e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
2505c810089cSRam Malovany 	if (!e)
2506c810089cSRam Malovany 		return false;
2507c810089cSRam Malovany 
2508b644ba33SJohan Hedberg 	if (hci_resolve_name(hdev, e) == 0) {
2509b644ba33SJohan Hedberg 		e->name_state = NAME_PENDING;
2510b644ba33SJohan Hedberg 		return true;
2511b644ba33SJohan Hedberg 	}
2512b644ba33SJohan Hedberg 
2513b644ba33SJohan Hedberg 	return false;
2514b644ba33SJohan Hedberg }
2515b644ba33SJohan Hedberg 
2516b644ba33SJohan Hedberg static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
2517b644ba33SJohan Hedberg 				   bdaddr_t *bdaddr, u8 *name, u8 name_len)
2518b644ba33SJohan Hedberg {
2519b644ba33SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
2520b644ba33SJohan Hedberg 	struct inquiry_entry *e;
2521b644ba33SJohan Hedberg 
252260cb49d2SJohan Hedberg 	/* Update the mgmt connected state if necessary. Be careful with
252360cb49d2SJohan Hedberg 	 * conn objects that exist but are not (yet) connected however.
252460cb49d2SJohan Hedberg 	 * Only those in BT_CONFIG or BT_CONNECTED states can be
252560cb49d2SJohan Hedberg 	 * considered connected.
252660cb49d2SJohan Hedberg 	 */
25270b3df53cSLuiz Augusto von Dentz 	if (conn && (conn->state == BT_CONFIG || conn->state == BT_CONNECTED))
25281c6ed31bSYu Liu 		mgmt_device_connected(hdev, conn, name, name_len);
2529b644ba33SJohan Hedberg 
2530b644ba33SJohan Hedberg 	if (discov->state == DISCOVERY_STOPPED)
2531b644ba33SJohan Hedberg 		return;
2532b644ba33SJohan Hedberg 
253330dc78e1SJohan Hedberg 	if (discov->state == DISCOVERY_STOPPING)
253430dc78e1SJohan Hedberg 		goto discov_complete;
253530dc78e1SJohan Hedberg 
253630dc78e1SJohan Hedberg 	if (discov->state != DISCOVERY_RESOLVING)
253730dc78e1SJohan Hedberg 		return;
253830dc78e1SJohan Hedberg 
253930dc78e1SJohan Hedberg 	e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
25407cc8380eSRam Malovany 	/* If the device was not found in a list of found devices names of which
25417cc8380eSRam Malovany 	 * are pending. there is no need to continue resolving a next name as it
25427cc8380eSRam Malovany 	 * will be done upon receiving another Remote Name Request Complete
25437cc8380eSRam Malovany 	 * Event */
25447cc8380eSRam Malovany 	if (!e)
25457cc8380eSRam Malovany 		return;
25467cc8380eSRam Malovany 
254730dc78e1SJohan Hedberg 	list_del(&e->list);
2548ea13aed5SArchie Pusaka 
2549ea13aed5SArchie Pusaka 	e->name_state = name ? NAME_KNOWN : NAME_NOT_KNOWN;
2550ea13aed5SArchie Pusaka 	mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00, e->data.rssi,
2551ea13aed5SArchie Pusaka 			 name, name_len);
255230dc78e1SJohan Hedberg 
2553b644ba33SJohan Hedberg 	if (hci_resolve_next_name(hdev))
255430dc78e1SJohan Hedberg 		return;
255530dc78e1SJohan Hedberg 
255630dc78e1SJohan Hedberg discov_complete:
255730dc78e1SJohan Hedberg 	hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
255830dc78e1SJohan Hedberg }
255930dc78e1SJohan Hedberg 
2560a9de9248SMarcel Holtmann static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
25611da177e4SLinus Torvalds {
2562127178d2SJohan Hedberg 	struct hci_cp_remote_name_req *cp;
2563127178d2SJohan Hedberg 	struct hci_conn *conn;
2564127178d2SJohan Hedberg 
2565147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2566127178d2SJohan Hedberg 
2567127178d2SJohan Hedberg 	/* If successful wait for the name req complete event before
2568127178d2SJohan Hedberg 	 * checking for the need to do authentication */
2569127178d2SJohan Hedberg 	if (!status)
2570127178d2SJohan Hedberg 		return;
2571127178d2SJohan Hedberg 
2572127178d2SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
2573127178d2SJohan Hedberg 	if (!cp)
2574127178d2SJohan Hedberg 		return;
2575127178d2SJohan Hedberg 
2576127178d2SJohan Hedberg 	hci_dev_lock(hdev);
2577127178d2SJohan Hedberg 
2578127178d2SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
2579b644ba33SJohan Hedberg 
2580d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
2581b644ba33SJohan Hedberg 		hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
2582b644ba33SJohan Hedberg 
258379c6c70cSJohan Hedberg 	if (!conn)
258479c6c70cSJohan Hedberg 		goto unlock;
258579c6c70cSJohan Hedberg 
258679c6c70cSJohan Hedberg 	if (!hci_outgoing_auth_needed(hdev, conn))
258779c6c70cSJohan Hedberg 		goto unlock;
258879c6c70cSJohan Hedberg 
258951a8efd7SJohan Hedberg 	if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
2590c1f23a2bSJohannes Berg 		struct hci_cp_auth_requested auth_cp;
2591c1f23a2bSJohannes Berg 
2592977f8fceSJohan Hedberg 		set_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags);
2593977f8fceSJohan Hedberg 
2594c1f23a2bSJohannes Berg 		auth_cp.handle = __cpu_to_le16(conn->handle);
2595c1f23a2bSJohannes Berg 		hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
2596c1f23a2bSJohannes Berg 			     sizeof(auth_cp), &auth_cp);
2597127178d2SJohan Hedberg 	}
2598127178d2SJohan Hedberg 
259979c6c70cSJohan Hedberg unlock:
2600127178d2SJohan Hedberg 	hci_dev_unlock(hdev);
2601a9de9248SMarcel Holtmann }
26021da177e4SLinus Torvalds 
2603769be974SMarcel Holtmann static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
2604769be974SMarcel Holtmann {
2605769be974SMarcel Holtmann 	struct hci_cp_read_remote_features *cp;
2606769be974SMarcel Holtmann 	struct hci_conn *conn;
2607769be974SMarcel Holtmann 
2608147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2609769be974SMarcel Holtmann 
2610769be974SMarcel Holtmann 	if (!status)
2611769be974SMarcel Holtmann 		return;
2612769be974SMarcel Holtmann 
2613769be974SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
2614769be974SMarcel Holtmann 	if (!cp)
2615769be974SMarcel Holtmann 		return;
2616769be974SMarcel Holtmann 
2617769be974SMarcel Holtmann 	hci_dev_lock(hdev);
2618769be974SMarcel Holtmann 
2619769be974SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2620769be974SMarcel Holtmann 	if (conn) {
2621769be974SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
2622539c496dSJohan Hedberg 			hci_connect_cfm(conn, status);
262376a68ba0SDavid Herrmann 			hci_conn_drop(conn);
2624769be974SMarcel Holtmann 		}
2625769be974SMarcel Holtmann 	}
2626769be974SMarcel Holtmann 
2627769be974SMarcel Holtmann 	hci_dev_unlock(hdev);
2628769be974SMarcel Holtmann }
2629769be974SMarcel Holtmann 
2630769be974SMarcel Holtmann static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
2631769be974SMarcel Holtmann {
2632769be974SMarcel Holtmann 	struct hci_cp_read_remote_ext_features *cp;
2633769be974SMarcel Holtmann 	struct hci_conn *conn;
2634769be974SMarcel Holtmann 
2635147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2636769be974SMarcel Holtmann 
2637769be974SMarcel Holtmann 	if (!status)
2638769be974SMarcel Holtmann 		return;
2639769be974SMarcel Holtmann 
2640769be974SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
2641769be974SMarcel Holtmann 	if (!cp)
2642769be974SMarcel Holtmann 		return;
2643769be974SMarcel Holtmann 
2644769be974SMarcel Holtmann 	hci_dev_lock(hdev);
2645769be974SMarcel Holtmann 
2646769be974SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2647769be974SMarcel Holtmann 	if (conn) {
2648769be974SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
2649539c496dSJohan Hedberg 			hci_connect_cfm(conn, status);
265076a68ba0SDavid Herrmann 			hci_conn_drop(conn);
2651769be974SMarcel Holtmann 		}
2652769be974SMarcel Holtmann 	}
2653769be974SMarcel Holtmann 
2654769be974SMarcel Holtmann 	hci_dev_unlock(hdev);
2655769be974SMarcel Holtmann }
2656769be974SMarcel Holtmann 
265706149746SLuiz Augusto von Dentz static void hci_setup_sync_conn_status(struct hci_dev *hdev, __u16 handle,
265806149746SLuiz Augusto von Dentz 				       __u8 status)
265906149746SLuiz Augusto von Dentz {
266006149746SLuiz Augusto von Dentz 	struct hci_conn *acl;
266106149746SLuiz Augusto von Dentz 	struct hci_link *link;
266206149746SLuiz Augusto von Dentz 
266306149746SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "handle 0x%4.4x status 0x%2.2x", handle, status);
266406149746SLuiz Augusto von Dentz 
266506149746SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
266606149746SLuiz Augusto von Dentz 
266706149746SLuiz Augusto von Dentz 	acl = hci_conn_hash_lookup_handle(hdev, handle);
266806149746SLuiz Augusto von Dentz 	if (acl) {
266906149746SLuiz Augusto von Dentz 		link = list_first_entry_or_null(&acl->link_list,
267006149746SLuiz Augusto von Dentz 						struct hci_link, list);
267106149746SLuiz Augusto von Dentz 		if (link && link->conn) {
267206149746SLuiz Augusto von Dentz 			link->conn->state = BT_CLOSED;
267306149746SLuiz Augusto von Dentz 
267406149746SLuiz Augusto von Dentz 			hci_connect_cfm(link->conn, status);
267506149746SLuiz Augusto von Dentz 			hci_conn_del(link->conn);
267606149746SLuiz Augusto von Dentz 		}
267706149746SLuiz Augusto von Dentz 	}
267806149746SLuiz Augusto von Dentz 
267906149746SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
268006149746SLuiz Augusto von Dentz }
268106149746SLuiz Augusto von Dentz 
2682a9de9248SMarcel Holtmann static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
2683a9de9248SMarcel Holtmann {
2684b6a0dc82SMarcel Holtmann 	struct hci_cp_setup_sync_conn *cp;
2685b6a0dc82SMarcel Holtmann 
2686147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2687b6a0dc82SMarcel Holtmann 
2688b6a0dc82SMarcel Holtmann 	if (!status)
2689b6a0dc82SMarcel Holtmann 		return;
2690b6a0dc82SMarcel Holtmann 
2691b6a0dc82SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
2692b6a0dc82SMarcel Holtmann 	if (!cp)
2693b6a0dc82SMarcel Holtmann 		return;
2694b6a0dc82SMarcel Holtmann 
269506149746SLuiz Augusto von Dentz 	hci_setup_sync_conn_status(hdev, __le16_to_cpu(cp->handle), status);
2696a9de9248SMarcel Holtmann }
2697a9de9248SMarcel Holtmann 
2698b2af264aSKiran K static void hci_cs_enhanced_setup_sync_conn(struct hci_dev *hdev, __u8 status)
2699b2af264aSKiran K {
2700b2af264aSKiran K 	struct hci_cp_enhanced_setup_sync_conn *cp;
2701b2af264aSKiran K 
2702b2af264aSKiran K 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2703b2af264aSKiran K 
2704b2af264aSKiran K 	if (!status)
2705b2af264aSKiran K 		return;
2706b2af264aSKiran K 
2707b2af264aSKiran K 	cp = hci_sent_cmd_data(hdev, HCI_OP_ENHANCED_SETUP_SYNC_CONN);
2708b2af264aSKiran K 	if (!cp)
2709b2af264aSKiran K 		return;
2710b2af264aSKiran K 
271106149746SLuiz Augusto von Dentz 	hci_setup_sync_conn_status(hdev, __le16_to_cpu(cp->handle), status);
2712b2af264aSKiran K }
2713b2af264aSKiran K 
2714a9de9248SMarcel Holtmann static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
2715a9de9248SMarcel Holtmann {
2716a9de9248SMarcel Holtmann 	struct hci_cp_sniff_mode *cp;
271704837f64SMarcel Holtmann 	struct hci_conn *conn;
271804837f64SMarcel Holtmann 
2719147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2720a9de9248SMarcel Holtmann 
2721a9de9248SMarcel Holtmann 	if (!status)
2722a9de9248SMarcel Holtmann 		return;
2723a9de9248SMarcel Holtmann 
2724a9de9248SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
272504837f64SMarcel Holtmann 	if (!cp)
2726a9de9248SMarcel Holtmann 		return;
272704837f64SMarcel Holtmann 
272804837f64SMarcel Holtmann 	hci_dev_lock(hdev);
272904837f64SMarcel Holtmann 
273004837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2731e73439d8SMarcel Holtmann 	if (conn) {
273251a8efd7SJohan Hedberg 		clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
273304837f64SMarcel Holtmann 
273451a8efd7SJohan Hedberg 		if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
2735e73439d8SMarcel Holtmann 			hci_sco_setup(conn, status);
2736e73439d8SMarcel Holtmann 	}
2737e73439d8SMarcel Holtmann 
273804837f64SMarcel Holtmann 	hci_dev_unlock(hdev);
273904837f64SMarcel Holtmann }
274004837f64SMarcel Holtmann 
2741a9de9248SMarcel Holtmann static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
2742a9de9248SMarcel Holtmann {
2743a9de9248SMarcel Holtmann 	struct hci_cp_exit_sniff_mode *cp;
274404837f64SMarcel Holtmann 	struct hci_conn *conn;
274504837f64SMarcel Holtmann 
2746147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2747a9de9248SMarcel Holtmann 
2748a9de9248SMarcel Holtmann 	if (!status)
2749a9de9248SMarcel Holtmann 		return;
2750a9de9248SMarcel Holtmann 
2751a9de9248SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
275204837f64SMarcel Holtmann 	if (!cp)
2753a9de9248SMarcel Holtmann 		return;
275404837f64SMarcel Holtmann 
275504837f64SMarcel Holtmann 	hci_dev_lock(hdev);
275604837f64SMarcel Holtmann 
275704837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2758e73439d8SMarcel Holtmann 	if (conn) {
275951a8efd7SJohan Hedberg 		clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
276004837f64SMarcel Holtmann 
276151a8efd7SJohan Hedberg 		if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
2762e73439d8SMarcel Holtmann 			hci_sco_setup(conn, status);
2763e73439d8SMarcel Holtmann 	}
2764e73439d8SMarcel Holtmann 
276504837f64SMarcel Holtmann 	hci_dev_unlock(hdev);
276604837f64SMarcel Holtmann }
276704837f64SMarcel Holtmann 
276888c3df13SJohan Hedberg static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
276988c3df13SJohan Hedberg {
277088c3df13SJohan Hedberg 	struct hci_cp_disconnect *cp;
2771182ee45dSLuiz Augusto von Dentz 	struct hci_conn_params *params;
277288c3df13SJohan Hedberg 	struct hci_conn *conn;
2773182ee45dSLuiz Augusto von Dentz 	bool mgmt_conn;
277488c3df13SJohan Hedberg 
2775147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2776147306ccSLuiz Augusto von Dentz 
2777182ee45dSLuiz Augusto von Dentz 	/* Wait for HCI_EV_DISCONN_COMPLETE if status 0x00 and not suspended
2778182ee45dSLuiz Augusto von Dentz 	 * otherwise cleanup the connection immediately.
2779182ee45dSLuiz Augusto von Dentz 	 */
2780182ee45dSLuiz Augusto von Dentz 	if (!status && !hdev->suspended)
278188c3df13SJohan Hedberg 		return;
278288c3df13SJohan Hedberg 
278388c3df13SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
278488c3df13SJohan Hedberg 	if (!cp)
278588c3df13SJohan Hedberg 		return;
278688c3df13SJohan Hedberg 
278788c3df13SJohan Hedberg 	hci_dev_lock(hdev);
278888c3df13SJohan Hedberg 
278988c3df13SJohan Hedberg 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2790182ee45dSLuiz Augusto von Dentz 	if (!conn)
2791182ee45dSLuiz Augusto von Dentz 		goto unlock;
2792182ee45dSLuiz Augusto von Dentz 
2793182ee45dSLuiz Augusto von Dentz 	if (status) {
279488c3df13SJohan Hedberg 		mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
279588c3df13SJohan Hedberg 				       conn->dst_type, status);
279688c3df13SJohan Hedberg 
27971eeaa1aeSLuiz Augusto von Dentz 		if (conn->type == LE_LINK && conn->role == HCI_ROLE_SLAVE) {
27987087c4f6SLuiz Augusto von Dentz 			hdev->cur_adv_instance = conn->adv_instance;
2799abfeea47SLuiz Augusto von Dentz 			hci_enable_advertising(hdev);
28007087c4f6SLuiz Augusto von Dentz 		}
28017087c4f6SLuiz Augusto von Dentz 
28027f7cfcb6SPauli Virtanen 		/* Inform sockets conn is gone before we delete it */
28037f7cfcb6SPauli Virtanen 		hci_disconn_cfm(conn, HCI_ERROR_UNSPECIFIED);
28047f7cfcb6SPauli Virtanen 
2805182ee45dSLuiz Augusto von Dentz 		goto done;
2806182ee45dSLuiz Augusto von Dentz 	}
2807182ee45dSLuiz Augusto von Dentz 
2808182ee45dSLuiz Augusto von Dentz 	mgmt_conn = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
2809182ee45dSLuiz Augusto von Dentz 
2810182ee45dSLuiz Augusto von Dentz 	if (conn->type == ACL_LINK) {
2811629f66aaSAlain Michaud 		if (test_and_clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags))
2812182ee45dSLuiz Augusto von Dentz 			hci_remove_link_key(hdev, &conn->dst);
2813182ee45dSLuiz Augusto von Dentz 	}
2814182ee45dSLuiz Augusto von Dentz 
2815182ee45dSLuiz Augusto von Dentz 	params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
2816182ee45dSLuiz Augusto von Dentz 	if (params) {
2817182ee45dSLuiz Augusto von Dentz 		switch (params->auto_connect) {
2818182ee45dSLuiz Augusto von Dentz 		case HCI_AUTO_CONN_LINK_LOSS:
2819182ee45dSLuiz Augusto von Dentz 			if (cp->reason != HCI_ERROR_CONNECTION_TIMEOUT)
2820182ee45dSLuiz Augusto von Dentz 				break;
2821182ee45dSLuiz Augusto von Dentz 			fallthrough;
2822182ee45dSLuiz Augusto von Dentz 
2823182ee45dSLuiz Augusto von Dentz 		case HCI_AUTO_CONN_DIRECT:
2824182ee45dSLuiz Augusto von Dentz 		case HCI_AUTO_CONN_ALWAYS:
2825195ef75eSPauli Virtanen 			hci_pend_le_list_del_init(params);
2826195ef75eSPauli Virtanen 			hci_pend_le_list_add(params, &hdev->pend_le_conns);
2827182ee45dSLuiz Augusto von Dentz 			break;
2828182ee45dSLuiz Augusto von Dentz 
2829182ee45dSLuiz Augusto von Dentz 		default:
2830182ee45dSLuiz Augusto von Dentz 			break;
2831182ee45dSLuiz Augusto von Dentz 		}
2832182ee45dSLuiz Augusto von Dentz 	}
2833182ee45dSLuiz Augusto von Dentz 
2834182ee45dSLuiz Augusto von Dentz 	mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type,
2835182ee45dSLuiz Augusto von Dentz 				 cp->reason, mgmt_conn);
2836182ee45dSLuiz Augusto von Dentz 
2837182ee45dSLuiz Augusto von Dentz 	hci_disconn_cfm(conn, cp->reason);
2838182ee45dSLuiz Augusto von Dentz 
2839182ee45dSLuiz Augusto von Dentz done:
2840b8d29052SJoseph Hwang 	/* If the disconnection failed for any reason, the upper layer
2841b8d29052SJoseph Hwang 	 * does not retry to disconnect in current implementation.
2842b8d29052SJoseph Hwang 	 * Hence, we need to do some basic cleanup here and re-enable
2843b8d29052SJoseph Hwang 	 * advertising if necessary.
2844b8d29052SJoseph Hwang 	 */
2845b8d29052SJoseph Hwang 	hci_conn_del(conn);
2846182ee45dSLuiz Augusto von Dentz unlock:
284788c3df13SJohan Hedberg 	hci_dev_unlock(hdev);
284888c3df13SJohan Hedberg }
284988c3df13SJohan Hedberg 
2850d850bf08SLuiz Augusto von Dentz static u8 ev_bdaddr_type(struct hci_dev *hdev, u8 type, bool *resolved)
28514ec4d63bSLuiz Augusto von Dentz {
28524ec4d63bSLuiz Augusto von Dentz 	/* When using controller based address resolution, then the new
28534ec4d63bSLuiz Augusto von Dentz 	 * address types 0x02 and 0x03 are used. These types need to be
28544ec4d63bSLuiz Augusto von Dentz 	 * converted back into either public address or random address type
28554ec4d63bSLuiz Augusto von Dentz 	 */
28564ec4d63bSLuiz Augusto von Dentz 	switch (type) {
28574ec4d63bSLuiz Augusto von Dentz 	case ADDR_LE_DEV_PUBLIC_RESOLVED:
2858d850bf08SLuiz Augusto von Dentz 		if (resolved)
2859d850bf08SLuiz Augusto von Dentz 			*resolved = true;
28604ec4d63bSLuiz Augusto von Dentz 		return ADDR_LE_DEV_PUBLIC;
28614ec4d63bSLuiz Augusto von Dentz 	case ADDR_LE_DEV_RANDOM_RESOLVED:
2862d850bf08SLuiz Augusto von Dentz 		if (resolved)
2863d850bf08SLuiz Augusto von Dentz 			*resolved = true;
28644ec4d63bSLuiz Augusto von Dentz 		return ADDR_LE_DEV_RANDOM;
28654ec4d63bSLuiz Augusto von Dentz 	}
28664ec4d63bSLuiz Augusto von Dentz 
2867d850bf08SLuiz Augusto von Dentz 	if (resolved)
2868d850bf08SLuiz Augusto von Dentz 		*resolved = false;
28694ec4d63bSLuiz Augusto von Dentz 	return type;
28704ec4d63bSLuiz Augusto von Dentz }
28714ec4d63bSLuiz Augusto von Dentz 
2872d12fb056SJaganath Kanakkassery static void cs_le_create_conn(struct hci_dev *hdev, bdaddr_t *peer_addr,
2873d12fb056SJaganath Kanakkassery 			      u8 peer_addr_type, u8 own_address_type,
2874d12fb056SJaganath Kanakkassery 			      u8 filter_policy)
2875d12fb056SJaganath Kanakkassery {
2876d12fb056SJaganath Kanakkassery 	struct hci_conn *conn;
2877d12fb056SJaganath Kanakkassery 
2878d12fb056SJaganath Kanakkassery 	conn = hci_conn_hash_lookup_le(hdev, peer_addr,
2879d12fb056SJaganath Kanakkassery 				       peer_addr_type);
2880d12fb056SJaganath Kanakkassery 	if (!conn)
2881d12fb056SJaganath Kanakkassery 		return;
2882d12fb056SJaganath Kanakkassery 
2883d850bf08SLuiz Augusto von Dentz 	own_address_type = ev_bdaddr_type(hdev, own_address_type, NULL);
2884b31bc00bSSathish Narasimman 
2885d12fb056SJaganath Kanakkassery 	/* Store the initiator and responder address information which
2886d12fb056SJaganath Kanakkassery 	 * is needed for SMP. These values will not change during the
2887d12fb056SJaganath Kanakkassery 	 * lifetime of the connection.
2888d12fb056SJaganath Kanakkassery 	 */
2889d12fb056SJaganath Kanakkassery 	conn->init_addr_type = own_address_type;
2890d12fb056SJaganath Kanakkassery 	if (own_address_type == ADDR_LE_DEV_RANDOM)
2891d12fb056SJaganath Kanakkassery 		bacpy(&conn->init_addr, &hdev->random_addr);
2892d12fb056SJaganath Kanakkassery 	else
2893d12fb056SJaganath Kanakkassery 		bacpy(&conn->init_addr, &hdev->bdaddr);
2894d12fb056SJaganath Kanakkassery 
2895d12fb056SJaganath Kanakkassery 	conn->resp_addr_type = peer_addr_type;
2896d12fb056SJaganath Kanakkassery 	bacpy(&conn->resp_addr, peer_addr);
2897d12fb056SJaganath Kanakkassery }
2898d12fb056SJaganath Kanakkassery 
2899cb1d68f7SJohan Hedberg static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status)
2900cb1d68f7SJohan Hedberg {
2901cb1d68f7SJohan Hedberg 	struct hci_cp_le_create_conn *cp;
2902cb1d68f7SJohan Hedberg 
2903147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2904cb1d68f7SJohan Hedberg 
2905cb1d68f7SJohan Hedberg 	/* All connection failure handling is taken care of by the
29069b3628d7SLuiz Augusto von Dentz 	 * hci_conn_failed function which is triggered by the HCI
2907cb1d68f7SJohan Hedberg 	 * request completion callbacks used for connecting.
2908cb1d68f7SJohan Hedberg 	 */
2909cb1d68f7SJohan Hedberg 	if (status)
2910cb1d68f7SJohan Hedberg 		return;
2911cb1d68f7SJohan Hedberg 
2912cb1d68f7SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
2913cb1d68f7SJohan Hedberg 	if (!cp)
2914cb1d68f7SJohan Hedberg 		return;
2915cb1d68f7SJohan Hedberg 
2916cb1d68f7SJohan Hedberg 	hci_dev_lock(hdev);
2917cb1d68f7SJohan Hedberg 
2918d12fb056SJaganath Kanakkassery 	cs_le_create_conn(hdev, &cp->peer_addr, cp->peer_addr_type,
2919d12fb056SJaganath Kanakkassery 			  cp->own_address_type, cp->filter_policy);
2920cb1d68f7SJohan Hedberg 
2921cb1d68f7SJohan Hedberg 	hci_dev_unlock(hdev);
2922cb1d68f7SJohan Hedberg }
2923cb1d68f7SJohan Hedberg 
29244d94f95dSJaganath Kanakkassery static void hci_cs_le_ext_create_conn(struct hci_dev *hdev, u8 status)
29254d94f95dSJaganath Kanakkassery {
29264d94f95dSJaganath Kanakkassery 	struct hci_cp_le_ext_create_conn *cp;
29274d94f95dSJaganath Kanakkassery 
2928147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
29294d94f95dSJaganath Kanakkassery 
29304d94f95dSJaganath Kanakkassery 	/* All connection failure handling is taken care of by the
29319b3628d7SLuiz Augusto von Dentz 	 * hci_conn_failed function which is triggered by the HCI
29324d94f95dSJaganath Kanakkassery 	 * request completion callbacks used for connecting.
29334d94f95dSJaganath Kanakkassery 	 */
29344d94f95dSJaganath Kanakkassery 	if (status)
29354d94f95dSJaganath Kanakkassery 		return;
29364d94f95dSJaganath Kanakkassery 
29374d94f95dSJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_EXT_CREATE_CONN);
29384d94f95dSJaganath Kanakkassery 	if (!cp)
29394d94f95dSJaganath Kanakkassery 		return;
29404d94f95dSJaganath Kanakkassery 
29414d94f95dSJaganath Kanakkassery 	hci_dev_lock(hdev);
29424d94f95dSJaganath Kanakkassery 
29434d94f95dSJaganath Kanakkassery 	cs_le_create_conn(hdev, &cp->peer_addr, cp->peer_addr_type,
29444d94f95dSJaganath Kanakkassery 			  cp->own_addr_type, cp->filter_policy);
29454d94f95dSJaganath Kanakkassery 
29464d94f95dSJaganath Kanakkassery 	hci_dev_unlock(hdev);
29474d94f95dSJaganath Kanakkassery }
29484d94f95dSJaganath Kanakkassery 
29490fe29fd1SMarcel Holtmann static void hci_cs_le_read_remote_features(struct hci_dev *hdev, u8 status)
29500fe29fd1SMarcel Holtmann {
29510fe29fd1SMarcel Holtmann 	struct hci_cp_le_read_remote_features *cp;
29520fe29fd1SMarcel Holtmann 	struct hci_conn *conn;
29530fe29fd1SMarcel Holtmann 
2954147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
29550fe29fd1SMarcel Holtmann 
29560fe29fd1SMarcel Holtmann 	if (!status)
29570fe29fd1SMarcel Holtmann 		return;
29580fe29fd1SMarcel Holtmann 
29590fe29fd1SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_READ_REMOTE_FEATURES);
29600fe29fd1SMarcel Holtmann 	if (!cp)
29610fe29fd1SMarcel Holtmann 		return;
29620fe29fd1SMarcel Holtmann 
29630fe29fd1SMarcel Holtmann 	hci_dev_lock(hdev);
29640fe29fd1SMarcel Holtmann 
29650fe29fd1SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
29660fe29fd1SMarcel Holtmann 	if (conn) {
29670fe29fd1SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
29680fe29fd1SMarcel Holtmann 			hci_connect_cfm(conn, status);
29690fe29fd1SMarcel Holtmann 			hci_conn_drop(conn);
29700fe29fd1SMarcel Holtmann 		}
29710fe29fd1SMarcel Holtmann 	}
29720fe29fd1SMarcel Holtmann 
29730fe29fd1SMarcel Holtmann 	hci_dev_unlock(hdev);
29740fe29fd1SMarcel Holtmann }
29750fe29fd1SMarcel Holtmann 
297681d0c8adSJohan Hedberg static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
297781d0c8adSJohan Hedberg {
297881d0c8adSJohan Hedberg 	struct hci_cp_le_start_enc *cp;
297981d0c8adSJohan Hedberg 	struct hci_conn *conn;
298081d0c8adSJohan Hedberg 
2981147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
298281d0c8adSJohan Hedberg 
298381d0c8adSJohan Hedberg 	if (!status)
298481d0c8adSJohan Hedberg 		return;
298581d0c8adSJohan Hedberg 
298681d0c8adSJohan Hedberg 	hci_dev_lock(hdev);
298781d0c8adSJohan Hedberg 
298881d0c8adSJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_START_ENC);
298981d0c8adSJohan Hedberg 	if (!cp)
299081d0c8adSJohan Hedberg 		goto unlock;
299181d0c8adSJohan Hedberg 
299281d0c8adSJohan Hedberg 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
299381d0c8adSJohan Hedberg 	if (!conn)
299481d0c8adSJohan Hedberg 		goto unlock;
299581d0c8adSJohan Hedberg 
299681d0c8adSJohan Hedberg 	if (conn->state != BT_CONNECTED)
299781d0c8adSJohan Hedberg 		goto unlock;
299881d0c8adSJohan Hedberg 
299981d0c8adSJohan Hedberg 	hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
300081d0c8adSJohan Hedberg 	hci_conn_drop(conn);
300181d0c8adSJohan Hedberg 
300281d0c8adSJohan Hedberg unlock:
300381d0c8adSJohan Hedberg 	hci_dev_unlock(hdev);
300481d0c8adSJohan Hedberg }
300581d0c8adSJohan Hedberg 
300650fc85f1SKuba Pawlak static void hci_cs_switch_role(struct hci_dev *hdev, u8 status)
300750fc85f1SKuba Pawlak {
300850fc85f1SKuba Pawlak 	struct hci_cp_switch_role *cp;
300950fc85f1SKuba Pawlak 	struct hci_conn *conn;
301050fc85f1SKuba Pawlak 
301150fc85f1SKuba Pawlak 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
301250fc85f1SKuba Pawlak 
301350fc85f1SKuba Pawlak 	if (!status)
301450fc85f1SKuba Pawlak 		return;
301550fc85f1SKuba Pawlak 
301650fc85f1SKuba Pawlak 	cp = hci_sent_cmd_data(hdev, HCI_OP_SWITCH_ROLE);
301750fc85f1SKuba Pawlak 	if (!cp)
301850fc85f1SKuba Pawlak 		return;
301950fc85f1SKuba Pawlak 
302050fc85f1SKuba Pawlak 	hci_dev_lock(hdev);
302150fc85f1SKuba Pawlak 
302250fc85f1SKuba Pawlak 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
302350fc85f1SKuba Pawlak 	if (conn)
302450fc85f1SKuba Pawlak 		clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
302550fc85f1SKuba Pawlak 
302650fc85f1SKuba Pawlak 	hci_dev_unlock(hdev);
302750fc85f1SKuba Pawlak }
302850fc85f1SKuba Pawlak 
30293e54c589SLuiz Augusto von Dentz static void hci_inquiry_complete_evt(struct hci_dev *hdev, void *data,
30303e54c589SLuiz Augusto von Dentz 				     struct sk_buff *skb)
30311da177e4SLinus Torvalds {
30323e54c589SLuiz Augusto von Dentz 	struct hci_ev_status *ev = data;
303330dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
303430dc78e1SJohan Hedberg 	struct inquiry_entry *e;
30351da177e4SLinus Torvalds 
30363e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
30371da177e4SLinus Torvalds 
3038a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
303989352e7dSAndre Guedes 
304089352e7dSAndre Guedes 	if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
304189352e7dSAndre Guedes 		return;
304289352e7dSAndre Guedes 
30434e857c58SPeter Zijlstra 	smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */
30443e13fa1eSAndre Guedes 	wake_up_bit(&hdev->flags, HCI_INQUIRY);
30453e13fa1eSAndre Guedes 
3046d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
304730dc78e1SJohan Hedberg 		return;
304830dc78e1SJohan Hedberg 
304956e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
305030dc78e1SJohan Hedberg 
3051343f935bSAndre Guedes 	if (discov->state != DISCOVERY_FINDING)
305230dc78e1SJohan Hedberg 		goto unlock;
305330dc78e1SJohan Hedberg 
305430dc78e1SJohan Hedberg 	if (list_empty(&discov->resolve)) {
305507d2334aSJakub Pawlowski 		/* When BR/EDR inquiry is active and no LE scanning is in
305607d2334aSJakub Pawlowski 		 * progress, then change discovery state to indicate completion.
305707d2334aSJakub Pawlowski 		 *
305807d2334aSJakub Pawlowski 		 * When running LE scanning and BR/EDR inquiry simultaneously
305907d2334aSJakub Pawlowski 		 * and the LE scan already finished, then change the discovery
306007d2334aSJakub Pawlowski 		 * state to indicate completion.
306107d2334aSJakub Pawlowski 		 */
306207d2334aSJakub Pawlowski 		if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
306307d2334aSJakub Pawlowski 		    !test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks))
3064ff9ef578SJohan Hedberg 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
306530dc78e1SJohan Hedberg 		goto unlock;
306630dc78e1SJohan Hedberg 	}
306730dc78e1SJohan Hedberg 
306830dc78e1SJohan Hedberg 	e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
306930dc78e1SJohan Hedberg 	if (e && hci_resolve_name(hdev, e) == 0) {
307030dc78e1SJohan Hedberg 		e->name_state = NAME_PENDING;
307130dc78e1SJohan Hedberg 		hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
3072dbf6811aSArchie Pusaka 		discov->name_resolve_timeout = jiffies + NAME_RESOLVE_DURATION;
307330dc78e1SJohan Hedberg 	} else {
307407d2334aSJakub Pawlowski 		/* When BR/EDR inquiry is active and no LE scanning is in
307507d2334aSJakub Pawlowski 		 * progress, then change discovery state to indicate completion.
307607d2334aSJakub Pawlowski 		 *
307707d2334aSJakub Pawlowski 		 * When running LE scanning and BR/EDR inquiry simultaneously
307807d2334aSJakub Pawlowski 		 * and the LE scan already finished, then change the discovery
307907d2334aSJakub Pawlowski 		 * state to indicate completion.
308007d2334aSJakub Pawlowski 		 */
308107d2334aSJakub Pawlowski 		if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
308207d2334aSJakub Pawlowski 		    !test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks))
308330dc78e1SJohan Hedberg 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
308430dc78e1SJohan Hedberg 	}
308530dc78e1SJohan Hedberg 
308630dc78e1SJohan Hedberg unlock:
308756e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
30881da177e4SLinus Torvalds }
30891da177e4SLinus Torvalds 
30903e54c589SLuiz Augusto von Dentz static void hci_inquiry_result_evt(struct hci_dev *hdev, void *edata,
30913e54c589SLuiz Augusto von Dentz 				   struct sk_buff *skb)
30921da177e4SLinus Torvalds {
30933e54c589SLuiz Augusto von Dentz 	struct hci_ev_inquiry_result *ev = edata;
309445bb4bf0SMarcel Holtmann 	struct inquiry_data data;
309527d9eb4bSLuiz Augusto von Dentz 	int i;
30961da177e4SLinus Torvalds 
309727d9eb4bSLuiz Augusto von Dentz 	if (!hci_ev_skb_pull(hdev, skb, HCI_EV_INQUIRY_RESULT,
309827d9eb4bSLuiz Augusto von Dentz 			     flex_array_size(ev, info, ev->num)))
309927d9eb4bSLuiz Augusto von Dentz 		return;
310027d9eb4bSLuiz Augusto von Dentz 
31013e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "num %d", ev->num);
310227d9eb4bSLuiz Augusto von Dentz 
310327d9eb4bSLuiz Augusto von Dentz 	if (!ev->num)
310445bb4bf0SMarcel Holtmann 		return;
310545bb4bf0SMarcel Holtmann 
3106d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ))
31071519cc17SAndre Guedes 		return;
31081519cc17SAndre Guedes 
31091da177e4SLinus Torvalds 	hci_dev_lock(hdev);
311045bb4bf0SMarcel Holtmann 
311127d9eb4bSLuiz Augusto von Dentz 	for (i = 0; i < ev->num; i++) {
311227d9eb4bSLuiz Augusto von Dentz 		struct inquiry_info *info = &ev->info[i];
3113af58925cSMarcel Holtmann 		u32 flags;
31143175405bSJohan Hedberg 
31151da177e4SLinus Torvalds 		bacpy(&data.bdaddr, &info->bdaddr);
31161da177e4SLinus Torvalds 		data.pscan_rep_mode	= info->pscan_rep_mode;
31171da177e4SLinus Torvalds 		data.pscan_period_mode	= info->pscan_period_mode;
31181da177e4SLinus Torvalds 		data.pscan_mode		= info->pscan_mode;
31191da177e4SLinus Torvalds 		memcpy(data.dev_class, info->dev_class, 3);
31201da177e4SLinus Torvalds 		data.clock_offset	= info->clock_offset;
3121efb2513fSMarcel Holtmann 		data.rssi		= HCI_RSSI_INVALID;
312241a96212SMarcel Holtmann 		data.ssp_mode		= 0x00;
31233175405bSJohan Hedberg 
3124af58925cSMarcel Holtmann 		flags = hci_inquiry_cache_update(hdev, &data, false);
3125af58925cSMarcel Holtmann 
312648264f06SJohan Hedberg 		mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
3127efb2513fSMarcel Holtmann 				  info->dev_class, HCI_RSSI_INVALID,
3128b338d917SBrian Gix 				  flags, NULL, 0, NULL, 0, 0);
31291da177e4SLinus Torvalds 	}
313045bb4bf0SMarcel Holtmann 
31311da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
31321da177e4SLinus Torvalds }
31331da177e4SLinus Torvalds 
31343e54c589SLuiz Augusto von Dentz static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
31353e54c589SLuiz Augusto von Dentz 				  struct sk_buff *skb)
31361da177e4SLinus Torvalds {
31373e54c589SLuiz Augusto von Dentz 	struct hci_ev_conn_complete *ev = data;
3138a9de9248SMarcel Holtmann 	struct hci_conn *conn;
3139c86cc5a3SLuiz Augusto von Dentz 	u8 status = ev->status;
31401da177e4SLinus Torvalds 
3141c86cc5a3SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
314245bb4bf0SMarcel Holtmann 
31431da177e4SLinus Torvalds 	hci_dev_lock(hdev);
314445bb4bf0SMarcel Holtmann 
3145a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
31469499237aSMarcel Holtmann 	if (!conn) {
3147aef2aa4fSLuiz Augusto von Dentz 		/* In case of error status and there is no connection pending
3148aef2aa4fSLuiz Augusto von Dentz 		 * just unlock as there is nothing to cleanup.
3149aef2aa4fSLuiz Augusto von Dentz 		 */
3150aef2aa4fSLuiz Augusto von Dentz 		if (ev->status)
3151aef2aa4fSLuiz Augusto von Dentz 			goto unlock;
3152aef2aa4fSLuiz Augusto von Dentz 
3153a46b7ed4SSonny Sasaka 		/* Connection may not exist if auto-connected. Check the bredr
3154a46b7ed4SSonny Sasaka 		 * allowlist to see if this device is allowed to auto connect.
3155a46b7ed4SSonny Sasaka 		 * If link is an ACL type, create a connection class
31564f40afc6SAbhishek Pandit-Subedi 		 * automatically.
3157a46b7ed4SSonny Sasaka 		 *
3158a46b7ed4SSonny Sasaka 		 * Auto-connect will only occur if the event filter is
3159a46b7ed4SSonny Sasaka 		 * programmed with a given address. Right now, event filter is
3160a46b7ed4SSonny Sasaka 		 * only used during suspend.
31614f40afc6SAbhishek Pandit-Subedi 		 */
3162a46b7ed4SSonny Sasaka 		if (ev->link_type == ACL_LINK &&
31633d4f9c00SArchie Pusaka 		    hci_bdaddr_list_lookup_with_flags(&hdev->accept_list,
3164a46b7ed4SSonny Sasaka 						      &ev->bdaddr,
3165a46b7ed4SSonny Sasaka 						      BDADDR_BREDR)) {
316684cb0143SZiyang Xuan 			conn = hci_conn_add_unset(hdev, ev->link_type,
316784cb0143SZiyang Xuan 						  &ev->bdaddr, HCI_ROLE_SLAVE);
31684f40afc6SAbhishek Pandit-Subedi 			if (!conn) {
31694f40afc6SAbhishek Pandit-Subedi 				bt_dev_err(hdev, "no memory for new conn");
31704f40afc6SAbhishek Pandit-Subedi 				goto unlock;
31714f40afc6SAbhishek Pandit-Subedi 			}
31722d186fcdSAbhishek Pandit-Subedi 		} else {
31739499237aSMarcel Holtmann 			if (ev->link_type != SCO_LINK)
31749499237aSMarcel Holtmann 				goto unlock;
31759499237aSMarcel Holtmann 
31762d186fcdSAbhishek Pandit-Subedi 			conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK,
31772d186fcdSAbhishek Pandit-Subedi 						       &ev->bdaddr);
3178a9de9248SMarcel Holtmann 			if (!conn)
3179a9de9248SMarcel Holtmann 				goto unlock;
318045bb4bf0SMarcel Holtmann 
31819499237aSMarcel Holtmann 			conn->type = SCO_LINK;
31829499237aSMarcel Holtmann 		}
31832d186fcdSAbhishek Pandit-Subedi 	}
31849499237aSMarcel Holtmann 
3185d5ebaa7cSSoenke Huster 	/* The HCI_Connection_Complete event is only sent once per connection.
3186d5ebaa7cSSoenke Huster 	 * Processing it more than once per connection can corrupt kernel memory.
3187d5ebaa7cSSoenke Huster 	 *
3188d5ebaa7cSSoenke Huster 	 * As the connection handle is set here for the first time, it indicates
3189d5ebaa7cSSoenke Huster 	 * whether the connection is already set up.
3190d5ebaa7cSSoenke Huster 	 */
31919f78191cSLuiz Augusto von Dentz 	if (!HCI_CONN_HANDLE_UNSET(conn->handle)) {
3192d5ebaa7cSSoenke Huster 		bt_dev_err(hdev, "Ignoring HCI_Connection_Complete for existing connection");
3193d5ebaa7cSSoenke Huster 		goto unlock;
3194d5ebaa7cSSoenke Huster 	}
3195d5ebaa7cSSoenke Huster 
3196c86cc5a3SLuiz Augusto von Dentz 	if (!status) {
319716e3b642SLuiz Augusto von Dentz 		status = hci_conn_set_handle(conn, __le16_to_cpu(ev->handle));
319816e3b642SLuiz Augusto von Dentz 		if (status)
3199c86cc5a3SLuiz Augusto von Dentz 			goto done;
3200769be974SMarcel Holtmann 
3201769be974SMarcel Holtmann 		if (conn->type == ACL_LINK) {
3202769be974SMarcel Holtmann 			conn->state = BT_CONFIG;
3203769be974SMarcel Holtmann 			hci_conn_hold(conn);
3204a9ea3ed9SSzymon Janc 
3205a9ea3ed9SSzymon Janc 			if (!conn->out && !hci_conn_ssp_enabled(conn) &&
3206a9ea3ed9SSzymon Janc 			    !hci_find_link_key(hdev, &ev->bdaddr))
3207a9ea3ed9SSzymon Janc 				conn->disc_timeout = HCI_PAIRING_TIMEOUT;
3208a9ea3ed9SSzymon Janc 			else
3209052b30b0SMarcel Holtmann 				conn->disc_timeout = HCI_DISCONN_TIMEOUT;
3210769be974SMarcel Holtmann 		} else
3211a9de9248SMarcel Holtmann 			conn->state = BT_CONNECTED;
3212a9de9248SMarcel Holtmann 
321323b9ceb7SMarcel Holtmann 		hci_debugfs_create_conn(conn);
32147d0db0a3SMarcel Holtmann 		hci_conn_add_sysfs(conn);
32157d0db0a3SMarcel Holtmann 
3216a9de9248SMarcel Holtmann 		if (test_bit(HCI_AUTH, &hdev->flags))
32174dae2798SJohan Hedberg 			set_bit(HCI_CONN_AUTH, &conn->flags);
3218a9de9248SMarcel Holtmann 
3219a9de9248SMarcel Holtmann 		if (test_bit(HCI_ENCRYPT, &hdev->flags))
32204dae2798SJohan Hedberg 			set_bit(HCI_CONN_ENCRYPT, &conn->flags);
3221a9de9248SMarcel Holtmann 
32224a328401SHui Wang 		/* "Link key request" completed ahead of "connect request" completes */
32234a328401SHui Wang 		if (ev->encr_mode == 1 && !test_bit(HCI_CONN_ENCRYPT, &conn->flags) &&
32244a328401SHui Wang 		    ev->link_type == ACL_LINK) {
32254a328401SHui Wang 			struct link_key *key;
32264a328401SHui Wang 			struct hci_cp_read_enc_key_size cp;
32274a328401SHui Wang 
32284a328401SHui Wang 			key = hci_find_link_key(hdev, &ev->bdaddr);
32294a328401SHui Wang 			if (key) {
32304a328401SHui Wang 				set_bit(HCI_CONN_ENCRYPT, &conn->flags);
32314a328401SHui Wang 
3232*62e3a7cbSLuiz Augusto von Dentz 				if (!read_key_size_capable(hdev)) {
32334a328401SHui Wang 					conn->enc_key_size = HCI_LINK_KEY_SIZE;
32344a328401SHui Wang 				} else {
32354a328401SHui Wang 					cp.handle = cpu_to_le16(conn->handle);
32364a328401SHui Wang 					if (hci_send_cmd(hdev, HCI_OP_READ_ENC_KEY_SIZE,
32374a328401SHui Wang 							 sizeof(cp), &cp)) {
32384a328401SHui Wang 						bt_dev_err(hdev, "sending read key size failed");
32394a328401SHui Wang 						conn->enc_key_size = HCI_LINK_KEY_SIZE;
32404a328401SHui Wang 					}
32414a328401SHui Wang 				}
32424a328401SHui Wang 
32434a328401SHui Wang 				hci_encrypt_cfm(conn, ev->status);
32444a328401SHui Wang 			}
32454a328401SHui Wang 		}
32464a328401SHui Wang 
3247a9de9248SMarcel Holtmann 		/* Get remote features */
3248a9de9248SMarcel Holtmann 		if (conn->type == ACL_LINK) {
3249a9de9248SMarcel Holtmann 			struct hci_cp_read_remote_features cp;
3250a9de9248SMarcel Holtmann 			cp.handle = ev->handle;
3251769be974SMarcel Holtmann 			hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
3252769be974SMarcel Holtmann 				     sizeof(cp), &cp);
325322f433dcSJohan Hedberg 
3254bb876725SBrian Gix 			hci_update_scan(hdev);
325545bb4bf0SMarcel Holtmann 		}
3256a9de9248SMarcel Holtmann 
3257a9de9248SMarcel Holtmann 		/* Set packet type for incoming connection */
3258d095c1ebSAndrei Emeltchenko 		if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
3259a9de9248SMarcel Holtmann 			struct hci_cp_change_conn_ptype cp;
3260a9de9248SMarcel Holtmann 			cp.handle = ev->handle;
3261a8746417SMarcel Holtmann 			cp.pkt_type = cpu_to_le16(conn->pkt_type);
326204124681SGustavo F. Padovan 			hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
326304124681SGustavo F. Padovan 				     &cp);
3264a9de9248SMarcel Holtmann 		}
326517d5c04cSJohan Hedberg 	}
326645bb4bf0SMarcel Holtmann 
3267e73439d8SMarcel Holtmann 	if (conn->type == ACL_LINK)
3268e73439d8SMarcel Holtmann 		hci_sco_setup(conn, ev->status);
326945bb4bf0SMarcel Holtmann 
3270c86cc5a3SLuiz Augusto von Dentz done:
3271c86cc5a3SLuiz Augusto von Dentz 	if (status) {
32729b3628d7SLuiz Augusto von Dentz 		hci_conn_failed(conn, status);
32731f8330eaSSathish Narsimman 	} else if (ev->link_type == SCO_LINK) {
32741f8330eaSSathish Narsimman 		switch (conn->setting & SCO_AIRMODE_MASK) {
32751f8330eaSSathish Narsimman 		case SCO_AIRMODE_CVSD:
32761f8330eaSSathish Narsimman 			if (hdev->notify)
32771f8330eaSSathish Narsimman 				hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD);
32781f8330eaSSathish Narsimman 			break;
32791f8330eaSSathish Narsimman 		}
32801f8330eaSSathish Narsimman 
3281c86cc5a3SLuiz Augusto von Dentz 		hci_connect_cfm(conn, status);
32821f8330eaSSathish Narsimman 	}
3283a9de9248SMarcel Holtmann 
3284a9de9248SMarcel Holtmann unlock:
32851da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
3286a9de9248SMarcel Holtmann 
3287a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
32881da177e4SLinus Torvalds }
32891da177e4SLinus Torvalds 
329070c46425SJohan Hedberg static void hci_reject_conn(struct hci_dev *hdev, bdaddr_t *bdaddr)
329170c46425SJohan Hedberg {
329270c46425SJohan Hedberg 	struct hci_cp_reject_conn_req cp;
329370c46425SJohan Hedberg 
329470c46425SJohan Hedberg 	bacpy(&cp.bdaddr, bdaddr);
329570c46425SJohan Hedberg 	cp.reason = HCI_ERROR_REJ_BAD_ADDR;
329670c46425SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
329770c46425SJohan Hedberg }
329870c46425SJohan Hedberg 
32993e54c589SLuiz Augusto von Dentz static void hci_conn_request_evt(struct hci_dev *hdev, void *data,
33003e54c589SLuiz Augusto von Dentz 				 struct sk_buff *skb)
33011da177e4SLinus Torvalds {
33023e54c589SLuiz Augusto von Dentz 	struct hci_ev_conn_request *ev = data;
33031da177e4SLinus Torvalds 	int mask = hdev->link_mode;
330470c46425SJohan Hedberg 	struct inquiry_entry *ie;
330570c46425SJohan Hedberg 	struct hci_conn *conn;
330620714bfeSFrédéric Dalleau 	__u8 flags = 0;
33071da177e4SLinus Torvalds 
33083e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "bdaddr %pMR type 0x%x", &ev->bdaddr, ev->link_type);
33091da177e4SLinus Torvalds 
33101ffc6f8cSLee, Chun-Yi 	/* Reject incoming connection from device with same BD ADDR against
33111ffc6f8cSLee, Chun-Yi 	 * CVE-2020-26555
33121ffc6f8cSLee, Chun-Yi 	 */
33139d1a3c74SArnd Bergmann 	if (hdev && !bacmp(&hdev->bdaddr, &ev->bdaddr)) {
33141ffc6f8cSLee, Chun-Yi 		bt_dev_dbg(hdev, "Reject connection with same BD_ADDR %pMR\n",
33151ffc6f8cSLee, Chun-Yi 			   &ev->bdaddr);
33161ffc6f8cSLee, Chun-Yi 		hci_reject_conn(hdev, &ev->bdaddr);
33171ffc6f8cSLee, Chun-Yi 		return;
33181ffc6f8cSLee, Chun-Yi 	}
33191ffc6f8cSLee, Chun-Yi 
332020714bfeSFrédéric Dalleau 	mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
332120714bfeSFrédéric Dalleau 				      &flags);
33221da177e4SLinus Torvalds 
332370c46425SJohan Hedberg 	if (!(mask & HCI_LM_ACCEPT)) {
332470c46425SJohan Hedberg 		hci_reject_conn(hdev, &ev->bdaddr);
332570c46425SJohan Hedberg 		return;
332670c46425SJohan Hedberg 	}
332770c46425SJohan Hedberg 
3328fb048caeSNiels Dossche 	hci_dev_lock(hdev);
3329fb048caeSNiels Dossche 
33303d4f9c00SArchie Pusaka 	if (hci_bdaddr_list_lookup(&hdev->reject_list, &ev->bdaddr,
3331dcc36c16SJohan Hedberg 				   BDADDR_BREDR)) {
333270c46425SJohan Hedberg 		hci_reject_conn(hdev, &ev->bdaddr);
3333fb048caeSNiels Dossche 		goto unlock;
333470c46425SJohan Hedberg 	}
333546c4c941SJohan Hedberg 
33363d4f9c00SArchie Pusaka 	/* Require HCI_CONNECTABLE or an accept list entry to accept the
33376a8fc95cSJohan Hedberg 	 * connection. These features are only touched through mgmt so
33386a8fc95cSJohan Hedberg 	 * only do the checks if HCI_MGMT is set.
33396a8fc95cSJohan Hedberg 	 */
3340d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT) &&
3341d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONNECTABLE) &&
33423d4f9c00SArchie Pusaka 	    !hci_bdaddr_list_lookup_with_flags(&hdev->accept_list, &ev->bdaddr,
3343a55bd29dSJohan Hedberg 					       BDADDR_BREDR)) {
3344a55bd29dSJohan Hedberg 		hci_reject_conn(hdev, &ev->bdaddr);
3345fb048caeSNiels Dossche 		goto unlock;
3346a55bd29dSJohan Hedberg 	}
334770c46425SJohan Hedberg 
33481da177e4SLinus Torvalds 	/* Connection accepted */
33491da177e4SLinus Torvalds 
3350cc11b9c1SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3351cc11b9c1SAndrei Emeltchenko 	if (ie)
3352c7bdd502SMarcel Holtmann 		memcpy(ie->data.dev_class, ev->dev_class, 3);
3353c7bdd502SMarcel Holtmann 
33548fc9ced3SGustavo Padovan 	conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
33558fc9ced3SGustavo Padovan 			&ev->bdaddr);
33561da177e4SLinus Torvalds 	if (!conn) {
335784cb0143SZiyang Xuan 		conn = hci_conn_add_unset(hdev, ev->link_type, &ev->bdaddr,
3358a5c4e309SJohan Hedberg 					  HCI_ROLE_SLAVE);
3359cc11b9c1SAndrei Emeltchenko 		if (!conn) {
33602064ee33SMarcel Holtmann 			bt_dev_err(hdev, "no memory for new connection");
3361fb048caeSNiels Dossche 			goto unlock;
33621da177e4SLinus Torvalds 		}
33631da177e4SLinus Torvalds 	}
3364b6a0dc82SMarcel Holtmann 
33651da177e4SLinus Torvalds 	memcpy(conn->dev_class, ev->dev_class, 3);
3366b6a0dc82SMarcel Holtmann 
33671da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
33681da177e4SLinus Torvalds 
336920714bfeSFrédéric Dalleau 	if (ev->link_type == ACL_LINK ||
337020714bfeSFrédéric Dalleau 	    (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
3371b6a0dc82SMarcel Holtmann 		struct hci_cp_accept_conn_req cp;
337220714bfeSFrédéric Dalleau 		conn->state = BT_CONNECT;
3373b6a0dc82SMarcel Holtmann 
33741da177e4SLinus Torvalds 		bacpy(&cp.bdaddr, &ev->bdaddr);
33751da177e4SLinus Torvalds 
33761da177e4SLinus Torvalds 		if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
337774be523cSArchie Pusaka 			cp.role = 0x00; /* Become central */
33781da177e4SLinus Torvalds 		else
337974be523cSArchie Pusaka 			cp.role = 0x01; /* Remain peripheral */
33801da177e4SLinus Torvalds 
338170c46425SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp);
338220714bfeSFrédéric Dalleau 	} else if (!(flags & HCI_PROTO_DEFER)) {
3383b6a0dc82SMarcel Holtmann 		struct hci_cp_accept_sync_conn_req cp;
338420714bfeSFrédéric Dalleau 		conn->state = BT_CONNECT;
3385b6a0dc82SMarcel Holtmann 
3386b6a0dc82SMarcel Holtmann 		bacpy(&cp.bdaddr, &ev->bdaddr);
3387a8746417SMarcel Holtmann 		cp.pkt_type = cpu_to_le16(conn->pkt_type);
3388b6a0dc82SMarcel Holtmann 
3389dcf4adbfSJoe Perches 		cp.tx_bandwidth   = cpu_to_le32(0x00001f40);
3390dcf4adbfSJoe Perches 		cp.rx_bandwidth   = cpu_to_le32(0x00001f40);
3391dcf4adbfSJoe Perches 		cp.max_latency    = cpu_to_le16(0xffff);
3392b6a0dc82SMarcel Holtmann 		cp.content_format = cpu_to_le16(hdev->voice_setting);
3393b6a0dc82SMarcel Holtmann 		cp.retrans_effort = 0xff;
3394b6a0dc82SMarcel Holtmann 
339570c46425SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, sizeof(cp),
339670c46425SJohan Hedberg 			     &cp);
339720714bfeSFrédéric Dalleau 	} else {
339820714bfeSFrédéric Dalleau 		conn->state = BT_CONNECT2;
3399539c496dSJohan Hedberg 		hci_connect_cfm(conn, 0);
3400b6a0dc82SMarcel Holtmann 	}
3401fb048caeSNiels Dossche 
3402fb048caeSNiels Dossche 	return;
3403fb048caeSNiels Dossche unlock:
3404fb048caeSNiels Dossche 	hci_dev_unlock(hdev);
34051da177e4SLinus Torvalds }
34061da177e4SLinus Torvalds 
3407f0d6a0eaSMikel Astiz static u8 hci_to_mgmt_reason(u8 err)
3408f0d6a0eaSMikel Astiz {
3409f0d6a0eaSMikel Astiz 	switch (err) {
3410f0d6a0eaSMikel Astiz 	case HCI_ERROR_CONNECTION_TIMEOUT:
3411f0d6a0eaSMikel Astiz 		return MGMT_DEV_DISCONN_TIMEOUT;
3412f0d6a0eaSMikel Astiz 	case HCI_ERROR_REMOTE_USER_TERM:
3413f0d6a0eaSMikel Astiz 	case HCI_ERROR_REMOTE_LOW_RESOURCES:
3414f0d6a0eaSMikel Astiz 	case HCI_ERROR_REMOTE_POWER_OFF:
3415f0d6a0eaSMikel Astiz 		return MGMT_DEV_DISCONN_REMOTE;
3416f0d6a0eaSMikel Astiz 	case HCI_ERROR_LOCAL_HOST_TERM:
3417f0d6a0eaSMikel Astiz 		return MGMT_DEV_DISCONN_LOCAL_HOST;
3418f0d6a0eaSMikel Astiz 	default:
3419f0d6a0eaSMikel Astiz 		return MGMT_DEV_DISCONN_UNKNOWN;
3420f0d6a0eaSMikel Astiz 	}
3421f0d6a0eaSMikel Astiz }
3422f0d6a0eaSMikel Astiz 
34233e54c589SLuiz Augusto von Dentz static void hci_disconn_complete_evt(struct hci_dev *hdev, void *data,
34243e54c589SLuiz Augusto von Dentz 				     struct sk_buff *skb)
34251da177e4SLinus Torvalds {
34263e54c589SLuiz Augusto von Dentz 	struct hci_ev_disconn_complete *ev = data;
3427160b9251SSzymon Janc 	u8 reason;
34289fcb18efSAndre Guedes 	struct hci_conn_params *params;
342904837f64SMarcel Holtmann 	struct hci_conn *conn;
343012d4a3b2SJohan Hedberg 	bool mgmt_connected;
34311da177e4SLinus Torvalds 
34323e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
34331da177e4SLinus Torvalds 
34341da177e4SLinus Torvalds 	hci_dev_lock(hdev);
34351da177e4SLinus Torvalds 
343604837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3437f7520543SJohan Hedberg 	if (!conn)
3438f7520543SJohan Hedberg 		goto unlock;
3439f7520543SJohan Hedberg 
3440f0d6a0eaSMikel Astiz 	if (ev->status) {
344188c3df13SJohan Hedberg 		mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
344288c3df13SJohan Hedberg 				       conn->dst_type, ev->status);
3443abf54a50SAndre Guedes 		goto unlock;
3444abf54a50SAndre Guedes 	}
3445f0d6a0eaSMikel Astiz 
34463846220bSAndre Guedes 	conn->state = BT_CLOSED;
34473846220bSAndre Guedes 
344812d4a3b2SJohan Hedberg 	mgmt_connected = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
3449160b9251SSzymon Janc 
3450160b9251SSzymon Janc 	if (test_bit(HCI_CONN_AUTH_FAILURE, &conn->flags))
3451160b9251SSzymon Janc 		reason = MGMT_DEV_DISCONN_AUTH_FAILURE;
3452160b9251SSzymon Janc 	else
3453160b9251SSzymon Janc 		reason = hci_to_mgmt_reason(ev->reason);
3454160b9251SSzymon Janc 
345512d4a3b2SJohan Hedberg 	mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type,
345612d4a3b2SJohan Hedberg 				reason, mgmt_connected);
3457f7520543SJohan Hedberg 
345822f433dcSJohan Hedberg 	if (conn->type == ACL_LINK) {
3459629f66aaSAlain Michaud 		if (test_and_clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags))
34606ec5bcadSVishal Agarwal 			hci_remove_link_key(hdev, &conn->dst);
34613846220bSAndre Guedes 
3462bb876725SBrian Gix 		hci_update_scan(hdev);
346322f433dcSJohan Hedberg 	}
346422f433dcSJohan Hedberg 
34659fcb18efSAndre Guedes 	params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
34669fcb18efSAndre Guedes 	if (params) {
34679fcb18efSAndre Guedes 		switch (params->auto_connect) {
34689fcb18efSAndre Guedes 		case HCI_AUTO_CONN_LINK_LOSS:
34699fcb18efSAndre Guedes 			if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT)
34709fcb18efSAndre Guedes 				break;
347119186c7bSGustavo A. R. Silva 			fallthrough;
34729fcb18efSAndre Guedes 
34734b9e7e75SMarcel Holtmann 		case HCI_AUTO_CONN_DIRECT:
34749fcb18efSAndre Guedes 		case HCI_AUTO_CONN_ALWAYS:
3475195ef75eSPauli Virtanen 			hci_pend_le_list_del_init(params);
3476195ef75eSPauli Virtanen 			hci_pend_le_list_add(params, &hdev->pend_le_conns);
34775bee2fd6SLuiz Augusto von Dentz 			hci_update_passive_scan(hdev);
34789fcb18efSAndre Guedes 			break;
34799fcb18efSAndre Guedes 
34809fcb18efSAndre Guedes 		default:
34819fcb18efSAndre Guedes 			break;
34829fcb18efSAndre Guedes 		}
34839fcb18efSAndre Guedes 	}
34849fcb18efSAndre Guedes 
34853a6d576bSJohan Hedberg 	hci_disconn_cfm(conn, ev->reason);
34862210246cSJohan Hedberg 
34872210246cSJohan Hedberg 	/* Re-enable advertising if necessary, since it might
34882210246cSJohan Hedberg 	 * have been disabled by the connection. From the
34892210246cSJohan Hedberg 	 * HCI_LE_Set_Advertise_Enable command description in
34902210246cSJohan Hedberg 	 * the core specification (v4.0):
34912210246cSJohan Hedberg 	 * "The Controller shall continue advertising until the Host
34922210246cSJohan Hedberg 	 * issues an LE_Set_Advertise_Enable command with
34932210246cSJohan Hedberg 	 * Advertising_Enable set to 0x00 (Advertising is disabled)
34942210246cSJohan Hedberg 	 * or until a connection is created or until the Advertising
34952210246cSJohan Hedberg 	 * is timed out due to Directed Advertising."
34962210246cSJohan Hedberg 	 */
34971eeaa1aeSLuiz Augusto von Dentz 	if (conn->type == LE_LINK && conn->role == HCI_ROLE_SLAVE) {
34987087c4f6SLuiz Augusto von Dentz 		hdev->cur_adv_instance = conn->adv_instance;
3499abfeea47SLuiz Augusto von Dentz 		hci_enable_advertising(hdev);
35007087c4f6SLuiz Augusto von Dentz 	}
35017087c4f6SLuiz Augusto von Dentz 
35027087c4f6SLuiz Augusto von Dentz 	hci_conn_del(conn);
35031da177e4SLinus Torvalds 
3504f7520543SJohan Hedberg unlock:
35051da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
35061da177e4SLinus Torvalds }
35071da177e4SLinus Torvalds 
35083e54c589SLuiz Augusto von Dentz static void hci_auth_complete_evt(struct hci_dev *hdev, void *data,
35093e54c589SLuiz Augusto von Dentz 				  struct sk_buff *skb)
3510a9de9248SMarcel Holtmann {
35113e54c589SLuiz Augusto von Dentz 	struct hci_ev_auth_complete *ev = data;
3512a9de9248SMarcel Holtmann 	struct hci_conn *conn;
3513a9de9248SMarcel Holtmann 
35143e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
3515a9de9248SMarcel Holtmann 
3516a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
3517a9de9248SMarcel Holtmann 
3518a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3519d7556e20SWaldemar Rymarkiewicz 	if (!conn)
3520d7556e20SWaldemar Rymarkiewicz 		goto unlock;
3521d7556e20SWaldemar Rymarkiewicz 
3522765c2a96SJohan Hedberg 	if (!ev->status) {
3523160b9251SSzymon Janc 		clear_bit(HCI_CONN_AUTH_FAILURE, &conn->flags);
35244dae2798SJohan Hedberg 		set_bit(HCI_CONN_AUTH, &conn->flags);
3525765c2a96SJohan Hedberg 		conn->sec_level = conn->pending_sec_level;
35262a611692SJohan Hedberg 	} else {
3527160b9251SSzymon Janc 		if (ev->status == HCI_ERROR_PIN_OR_KEY_MISSING)
3528160b9251SSzymon Janc 			set_bit(HCI_CONN_AUTH_FAILURE, &conn->flags);
3529160b9251SSzymon Janc 
3530e1e930f5SJohan Hedberg 		mgmt_auth_failed(conn, ev->status);
35312a611692SJohan Hedberg 	}
3532a9de9248SMarcel Holtmann 
353351a8efd7SJohan Hedberg 	clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
3534a9de9248SMarcel Holtmann 
3535f8558555SMarcel Holtmann 	if (conn->state == BT_CONFIG) {
3536aa64a8b5SJohan Hedberg 		if (!ev->status && hci_conn_ssp_enabled(conn)) {
3537f8558555SMarcel Holtmann 			struct hci_cp_set_conn_encrypt cp;
3538f8558555SMarcel Holtmann 			cp.handle  = ev->handle;
3539f8558555SMarcel Holtmann 			cp.encrypt = 0x01;
3540d7556e20SWaldemar Rymarkiewicz 			hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
3541d7556e20SWaldemar Rymarkiewicz 				     &cp);
3542f8558555SMarcel Holtmann 		} else {
3543f8558555SMarcel Holtmann 			conn->state = BT_CONNECTED;
3544539c496dSJohan Hedberg 			hci_connect_cfm(conn, ev->status);
354576a68ba0SDavid Herrmann 			hci_conn_drop(conn);
3546f8558555SMarcel Holtmann 		}
3547052b30b0SMarcel Holtmann 	} else {
3548a9de9248SMarcel Holtmann 		hci_auth_cfm(conn, ev->status);
3549a9de9248SMarcel Holtmann 
3550052b30b0SMarcel Holtmann 		hci_conn_hold(conn);
3551052b30b0SMarcel Holtmann 		conn->disc_timeout = HCI_DISCONN_TIMEOUT;
355276a68ba0SDavid Herrmann 		hci_conn_drop(conn);
3553052b30b0SMarcel Holtmann 	}
3554052b30b0SMarcel Holtmann 
355551a8efd7SJohan Hedberg 	if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
3556a9de9248SMarcel Holtmann 		if (!ev->status) {
3557a9de9248SMarcel Holtmann 			struct hci_cp_set_conn_encrypt cp;
3558f8558555SMarcel Holtmann 			cp.handle  = ev->handle;
3559f8558555SMarcel Holtmann 			cp.encrypt = 0x01;
3560d7556e20SWaldemar Rymarkiewicz 			hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
3561d7556e20SWaldemar Rymarkiewicz 				     &cp);
3562a9de9248SMarcel Holtmann 		} else {
356351a8efd7SJohan Hedberg 			clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
35643ca44c16SLuiz Augusto von Dentz 			hci_encrypt_cfm(conn, ev->status);
3565a9de9248SMarcel Holtmann 		}
3566a9de9248SMarcel Holtmann 	}
3567a9de9248SMarcel Holtmann 
3568d7556e20SWaldemar Rymarkiewicz unlock:
3569a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
3570a9de9248SMarcel Holtmann }
3571a9de9248SMarcel Holtmann 
35723e54c589SLuiz Augusto von Dentz static void hci_remote_name_evt(struct hci_dev *hdev, void *data,
35733e54c589SLuiz Augusto von Dentz 				struct sk_buff *skb)
3574a9de9248SMarcel Holtmann {
35753e54c589SLuiz Augusto von Dentz 	struct hci_ev_remote_name *ev = data;
3576127178d2SJohan Hedberg 	struct hci_conn *conn;
3577127178d2SJohan Hedberg 
35783e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
3579a9de9248SMarcel Holtmann 
3580127178d2SJohan Hedberg 	hci_dev_lock(hdev);
3581127178d2SJohan Hedberg 
3582127178d2SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3583b644ba33SJohan Hedberg 
3584d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
3585b644ba33SJohan Hedberg 		goto check_auth;
3586b644ba33SJohan Hedberg 
3587b644ba33SJohan Hedberg 	if (ev->status == 0)
3588b644ba33SJohan Hedberg 		hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
3589b644ba33SJohan Hedberg 				       strnlen(ev->name, HCI_MAX_NAME_LENGTH));
3590b644ba33SJohan Hedberg 	else
3591b644ba33SJohan Hedberg 		hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
3592b644ba33SJohan Hedberg 
3593b644ba33SJohan Hedberg check_auth:
359479c6c70cSJohan Hedberg 	if (!conn)
359579c6c70cSJohan Hedberg 		goto unlock;
359679c6c70cSJohan Hedberg 
359779c6c70cSJohan Hedberg 	if (!hci_outgoing_auth_needed(hdev, conn))
359879c6c70cSJohan Hedberg 		goto unlock;
359979c6c70cSJohan Hedberg 
360051a8efd7SJohan Hedberg 	if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
3601127178d2SJohan Hedberg 		struct hci_cp_auth_requested cp;
3602977f8fceSJohan Hedberg 
3603977f8fceSJohan Hedberg 		set_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags);
3604977f8fceSJohan Hedberg 
3605127178d2SJohan Hedberg 		cp.handle = __cpu_to_le16(conn->handle);
3606127178d2SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
3607127178d2SJohan Hedberg 	}
3608127178d2SJohan Hedberg 
360979c6c70cSJohan Hedberg unlock:
3610127178d2SJohan Hedberg 	hci_dev_unlock(hdev);
3611a9de9248SMarcel Holtmann }
3612a9de9248SMarcel Holtmann 
36133e54c589SLuiz Augusto von Dentz static void hci_encrypt_change_evt(struct hci_dev *hdev, void *data,
36143e54c589SLuiz Augusto von Dentz 				   struct sk_buff *skb)
3615a9de9248SMarcel Holtmann {
36163e54c589SLuiz Augusto von Dentz 	struct hci_ev_encrypt_change *ev = data;
3617a9de9248SMarcel Holtmann 	struct hci_conn *conn;
3618a9de9248SMarcel Holtmann 
36193e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
3620a9de9248SMarcel Holtmann 
3621a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
3622a9de9248SMarcel Holtmann 
3623a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3624dc8357ccSMarcel Holtmann 	if (!conn)
3625dc8357ccSMarcel Holtmann 		goto unlock;
3626dc8357ccSMarcel Holtmann 
3627a9de9248SMarcel Holtmann 	if (!ev->status) {
3628ae293196SMarcel Holtmann 		if (ev->encrypt) {
3629ae293196SMarcel Holtmann 			/* Encryption implies authentication */
36304dae2798SJohan Hedberg 			set_bit(HCI_CONN_AUTH, &conn->flags);
36314dae2798SJohan Hedberg 			set_bit(HCI_CONN_ENCRYPT, &conn->flags);
3632da85e5e5SVinicius Costa Gomes 			conn->sec_level = conn->pending_sec_level;
3633abf76badSMarcel Holtmann 
3634914a6ffeSMarcel Holtmann 			/* P-256 authentication key implies FIPS */
3635914a6ffeSMarcel Holtmann 			if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256)
36364dae2798SJohan Hedberg 				set_bit(HCI_CONN_FIPS, &conn->flags);
3637914a6ffeSMarcel Holtmann 
3638abf76badSMarcel Holtmann 			if ((conn->type == ACL_LINK && ev->encrypt == 0x02) ||
3639abf76badSMarcel Holtmann 			    conn->type == LE_LINK)
3640abf76badSMarcel Holtmann 				set_bit(HCI_CONN_AES_CCM, &conn->flags);
3641abf76badSMarcel Holtmann 		} else {
36424dae2798SJohan Hedberg 			clear_bit(HCI_CONN_ENCRYPT, &conn->flags);
3643abf76badSMarcel Holtmann 			clear_bit(HCI_CONN_AES_CCM, &conn->flags);
3644abf76badSMarcel Holtmann 		}
3645a9de9248SMarcel Holtmann 	}
3646a9de9248SMarcel Holtmann 
36477ed3fa20SJohan Hedberg 	/* We should disregard the current RPA and generate a new one
36487ed3fa20SJohan Hedberg 	 * whenever the encryption procedure fails.
36497ed3fa20SJohan Hedberg 	 */
3650a73c046aSJaganath Kanakkassery 	if (ev->status && conn->type == LE_LINK) {
3651a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
3652a73c046aSJaganath Kanakkassery 		hci_adv_instances_set_rpa_expired(hdev, true);
3653a73c046aSJaganath Kanakkassery 	}
36547ed3fa20SJohan Hedberg 
365551a8efd7SJohan Hedberg 	clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3656a9de9248SMarcel Holtmann 
36578746f135SLuiz Augusto von Dentz 	/* Check link security requirements are met */
36588746f135SLuiz Augusto von Dentz 	if (!hci_conn_check_link_mode(conn))
36598746f135SLuiz Augusto von Dentz 		ev->status = HCI_ERROR_AUTH_FAILURE;
36608746f135SLuiz Augusto von Dentz 
3661a7d7723aSGustavo Padovan 	if (ev->status && conn->state == BT_CONNECTED) {
3662160b9251SSzymon Janc 		if (ev->status == HCI_ERROR_PIN_OR_KEY_MISSING)
3663160b9251SSzymon Janc 			set_bit(HCI_CONN_AUTH_FAILURE, &conn->flags);
3664160b9251SSzymon Janc 
36658746f135SLuiz Augusto von Dentz 		/* Notify upper layers so they can cleanup before
36668746f135SLuiz Augusto von Dentz 		 * disconnecting.
366740b552aaSMarcel Holtmann 		 */
36688746f135SLuiz Augusto von Dentz 		hci_encrypt_cfm(conn, ev->status);
36698746f135SLuiz Augusto von Dentz 		hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
367040b552aaSMarcel Holtmann 		hci_conn_drop(conn);
367140b552aaSMarcel Holtmann 		goto unlock;
367240b552aaSMarcel Holtmann 	}
367340b552aaSMarcel Holtmann 
3674821f3766SJohan Hedberg 	/* Try reading the encryption key size for encrypted ACL links */
3675821f3766SJohan Hedberg 	if (!ev->status && ev->encrypt && conn->type == ACL_LINK) {
3676821f3766SJohan Hedberg 		struct hci_cp_read_enc_key_size cp;
3677821f3766SJohan Hedberg 
3678821f3766SJohan Hedberg 		/* Only send HCI_Read_Encryption_Key_Size if the
3679821f3766SJohan Hedberg 		 * controller really supports it. If it doesn't, assume
3680821f3766SJohan Hedberg 		 * the default size (16).
3681821f3766SJohan Hedberg 		 */
3682*62e3a7cbSLuiz Augusto von Dentz 		if (!read_key_size_capable(hdev)) {
3683821f3766SJohan Hedberg 			conn->enc_key_size = HCI_LINK_KEY_SIZE;
3684821f3766SJohan Hedberg 			goto notify;
3685821f3766SJohan Hedberg 		}
3686821f3766SJohan Hedberg 
3687821f3766SJohan Hedberg 		cp.handle = cpu_to_le16(conn->handle);
3688278d933eSBrian Gix 		if (hci_send_cmd(hdev, HCI_OP_READ_ENC_KEY_SIZE,
3689278d933eSBrian Gix 				 sizeof(cp), &cp)) {
36902064ee33SMarcel Holtmann 			bt_dev_err(hdev, "sending read key size failed");
3691821f3766SJohan Hedberg 			conn->enc_key_size = HCI_LINK_KEY_SIZE;
3692821f3766SJohan Hedberg 			goto notify;
3693821f3766SJohan Hedberg 		}
3694821f3766SJohan Hedberg 
3695821f3766SJohan Hedberg 		goto unlock;
3696821f3766SJohan Hedberg 	}
3697821f3766SJohan Hedberg 
3698302975cbSSpoorthi Ravishankar Koppad 	/* Set the default Authenticated Payload Timeout after
3699302975cbSSpoorthi Ravishankar Koppad 	 * an LE Link is established. As per Core Spec v5.0, Vol 2, Part B
3700302975cbSSpoorthi Ravishankar Koppad 	 * Section 3.3, the HCI command WRITE_AUTH_PAYLOAD_TIMEOUT should be
3701302975cbSSpoorthi Ravishankar Koppad 	 * sent when the link is active and Encryption is enabled, the conn
3702302975cbSSpoorthi Ravishankar Koppad 	 * type can be either LE or ACL and controller must support LMP Ping.
3703302975cbSSpoorthi Ravishankar Koppad 	 * Ensure for AES-CCM encryption as well.
3704302975cbSSpoorthi Ravishankar Koppad 	 */
3705302975cbSSpoorthi Ravishankar Koppad 	if (test_bit(HCI_CONN_ENCRYPT, &conn->flags) &&
3706302975cbSSpoorthi Ravishankar Koppad 	    test_bit(HCI_CONN_AES_CCM, &conn->flags) &&
3707302975cbSSpoorthi Ravishankar Koppad 	    ((conn->type == ACL_LINK && lmp_ping_capable(hdev)) ||
3708302975cbSSpoorthi Ravishankar Koppad 	     (conn->type == LE_LINK && (hdev->le_features[0] & HCI_LE_PING)))) {
3709302975cbSSpoorthi Ravishankar Koppad 		struct hci_cp_write_auth_payload_to cp;
3710302975cbSSpoorthi Ravishankar Koppad 
3711302975cbSSpoorthi Ravishankar Koppad 		cp.handle = cpu_to_le16(conn->handle);
3712302975cbSSpoorthi Ravishankar Koppad 		cp.timeout = cpu_to_le16(hdev->auth_payload_timeout);
37137aca0ac4SLuiz Augusto von Dentz 		if (hci_send_cmd(conn->hdev, HCI_OP_WRITE_AUTH_PAYLOAD_TO,
3714399dea9dSLuiz Augusto von Dentz 				 sizeof(cp), &cp))
37157aca0ac4SLuiz Augusto von Dentz 			bt_dev_err(hdev, "write auth payload timeout failed");
3716302975cbSSpoorthi Ravishankar Koppad 	}
3717302975cbSSpoorthi Ravishankar Koppad 
3718821f3766SJohan Hedberg notify:
37193ca44c16SLuiz Augusto von Dentz 	hci_encrypt_cfm(conn, ev->status);
3720a9de9248SMarcel Holtmann 
3721a7d7723aSGustavo Padovan unlock:
3722a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
3723a9de9248SMarcel Holtmann }
3724a9de9248SMarcel Holtmann 
37253e54c589SLuiz Augusto von Dentz static void hci_change_link_key_complete_evt(struct hci_dev *hdev, void *data,
3726807deac2SGustavo Padovan 					     struct sk_buff *skb)
3727a9de9248SMarcel Holtmann {
37283e54c589SLuiz Augusto von Dentz 	struct hci_ev_change_link_key_complete *ev = data;
3729a9de9248SMarcel Holtmann 	struct hci_conn *conn;
3730a9de9248SMarcel Holtmann 
37313e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
3732a9de9248SMarcel Holtmann 
3733a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
3734a9de9248SMarcel Holtmann 
3735a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3736a9de9248SMarcel Holtmann 	if (conn) {
3737a9de9248SMarcel Holtmann 		if (!ev->status)
37384dae2798SJohan Hedberg 			set_bit(HCI_CONN_SECURE, &conn->flags);
3739a9de9248SMarcel Holtmann 
374051a8efd7SJohan Hedberg 		clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
3741a9de9248SMarcel Holtmann 
3742a9de9248SMarcel Holtmann 		hci_key_change_cfm(conn, ev->status);
3743a9de9248SMarcel Holtmann 	}
3744a9de9248SMarcel Holtmann 
3745a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
3746a9de9248SMarcel Holtmann }
3747a9de9248SMarcel Holtmann 
37483e54c589SLuiz Augusto von Dentz static void hci_remote_features_evt(struct hci_dev *hdev, void *data,
3749807deac2SGustavo Padovan 				    struct sk_buff *skb)
3750a9de9248SMarcel Holtmann {
37513e54c589SLuiz Augusto von Dentz 	struct hci_ev_remote_features *ev = data;
3752a9de9248SMarcel Holtmann 	struct hci_conn *conn;
3753a9de9248SMarcel Holtmann 
37543e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
3755a9de9248SMarcel Holtmann 
3756a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
3757a9de9248SMarcel Holtmann 
3758a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3759ccd556feSJohan Hedberg 	if (!conn)
3760ccd556feSJohan Hedberg 		goto unlock;
3761ccd556feSJohan Hedberg 
3762769be974SMarcel Holtmann 	if (!ev->status)
3763cad718edSJohan Hedberg 		memcpy(conn->features[0], ev->features, 8);
3764a9de9248SMarcel Holtmann 
3765ccd556feSJohan Hedberg 	if (conn->state != BT_CONFIG)
3766ccd556feSJohan Hedberg 		goto unlock;
3767ccd556feSJohan Hedberg 
3768ac363cf9SSzymon Janc 	if (!ev->status && lmp_ext_feat_capable(hdev) &&
3769ac363cf9SSzymon Janc 	    lmp_ext_feat_capable(conn)) {
3770769be974SMarcel Holtmann 		struct hci_cp_read_remote_ext_features cp;
3771769be974SMarcel Holtmann 		cp.handle = ev->handle;
3772769be974SMarcel Holtmann 		cp.page = 0x01;
3773ccd556feSJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
3774769be974SMarcel Holtmann 			     sizeof(cp), &cp);
3775392599b9SJohan Hedberg 		goto unlock;
3776392599b9SJohan Hedberg 	}
3777392599b9SJohan Hedberg 
3778671267bfSJohan Hedberg 	if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
3779127178d2SJohan Hedberg 		struct hci_cp_remote_name_req cp;
3780127178d2SJohan Hedberg 		memset(&cp, 0, sizeof(cp));
3781127178d2SJohan Hedberg 		bacpy(&cp.bdaddr, &conn->dst);
3782127178d2SJohan Hedberg 		cp.pscan_rep_mode = 0x02;
3783127178d2SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
37840b3df53cSLuiz Augusto von Dentz 	} else {
37851c6ed31bSYu Liu 		mgmt_device_connected(hdev, conn, NULL, 0);
37860b3df53cSLuiz Augusto von Dentz 	}
3787392599b9SJohan Hedberg 
3788127178d2SJohan Hedberg 	if (!hci_outgoing_auth_needed(hdev, conn)) {
3789769be974SMarcel Holtmann 		conn->state = BT_CONNECTED;
3790539c496dSJohan Hedberg 		hci_connect_cfm(conn, ev->status);
379176a68ba0SDavid Herrmann 		hci_conn_drop(conn);
3792769be974SMarcel Holtmann 	}
3793769be974SMarcel Holtmann 
3794ccd556feSJohan Hedberg unlock:
3795a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
3796a9de9248SMarcel Holtmann }
3797a9de9248SMarcel Holtmann 
3798ecb71f25SKiran K static inline void handle_cmd_cnt_and_timer(struct hci_dev *hdev, u8 ncmd)
3799de75cd0dSManish Mandlik {
3800de75cd0dSManish Mandlik 	cancel_delayed_work(&hdev->cmd_timer);
3801de75cd0dSManish Mandlik 
3802deee93d1STetsuo Handa 	rcu_read_lock();
3803de75cd0dSManish Mandlik 	if (!test_bit(HCI_RESET, &hdev->flags)) {
3804de75cd0dSManish Mandlik 		if (ncmd) {
3805de75cd0dSManish Mandlik 			cancel_delayed_work(&hdev->ncmd_timer);
3806de75cd0dSManish Mandlik 			atomic_set(&hdev->cmd_cnt, 1);
3807de75cd0dSManish Mandlik 		} else {
3808877afadaSSchspa Shi 			if (!hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
3809deee93d1STetsuo Handa 				queue_delayed_work(hdev->workqueue, &hdev->ncmd_timer,
3810de75cd0dSManish Mandlik 						   HCI_NCMD_TIMEOUT);
3811de75cd0dSManish Mandlik 		}
3812de75cd0dSManish Mandlik 	}
3813deee93d1STetsuo Handa 	rcu_read_unlock();
3814de75cd0dSManish Mandlik }
3815de75cd0dSManish Mandlik 
381626afbd82SLuiz Augusto von Dentz static u8 hci_cc_le_read_buffer_size_v2(struct hci_dev *hdev, void *data,
381726afbd82SLuiz Augusto von Dentz 					struct sk_buff *skb)
381826afbd82SLuiz Augusto von Dentz {
381926afbd82SLuiz Augusto von Dentz 	struct hci_rp_le_read_buffer_size_v2 *rp = data;
382026afbd82SLuiz Augusto von Dentz 
382126afbd82SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
382226afbd82SLuiz Augusto von Dentz 
382326afbd82SLuiz Augusto von Dentz 	if (rp->status)
382426afbd82SLuiz Augusto von Dentz 		return rp->status;
382526afbd82SLuiz Augusto von Dentz 
382626afbd82SLuiz Augusto von Dentz 	hdev->le_mtu   = __le16_to_cpu(rp->acl_mtu);
382726afbd82SLuiz Augusto von Dentz 	hdev->le_pkts  = rp->acl_max_pkt;
382826afbd82SLuiz Augusto von Dentz 	hdev->iso_mtu  = __le16_to_cpu(rp->iso_mtu);
382926afbd82SLuiz Augusto von Dentz 	hdev->iso_pkts = rp->iso_max_pkt;
383026afbd82SLuiz Augusto von Dentz 
383126afbd82SLuiz Augusto von Dentz 	hdev->le_cnt  = hdev->le_pkts;
383226afbd82SLuiz Augusto von Dentz 	hdev->iso_cnt = hdev->iso_pkts;
383326afbd82SLuiz Augusto von Dentz 
383426afbd82SLuiz Augusto von Dentz 	BT_DBG("%s acl mtu %d:%d iso mtu %d:%d", hdev->name, hdev->acl_mtu,
383526afbd82SLuiz Augusto von Dentz 	       hdev->acl_pkts, hdev->iso_mtu, hdev->iso_pkts);
383626afbd82SLuiz Augusto von Dentz 
383726afbd82SLuiz Augusto von Dentz 	return rp->status;
383826afbd82SLuiz Augusto von Dentz }
383926afbd82SLuiz Augusto von Dentz 
384066dee215SPauli Virtanen static void hci_unbound_cis_failed(struct hci_dev *hdev, u8 cig, u8 status)
384166dee215SPauli Virtanen {
384266dee215SPauli Virtanen 	struct hci_conn *conn, *tmp;
384366dee215SPauli Virtanen 
384466dee215SPauli Virtanen 	lockdep_assert_held(&hdev->lock);
384566dee215SPauli Virtanen 
384666dee215SPauli Virtanen 	list_for_each_entry_safe(conn, tmp, &hdev->conn_hash.list, list) {
384766dee215SPauli Virtanen 		if (conn->type != ISO_LINK || !bacmp(&conn->dst, BDADDR_ANY) ||
384866dee215SPauli Virtanen 		    conn->state == BT_OPEN || conn->iso_qos.ucast.cig != cig)
384966dee215SPauli Virtanen 			continue;
385066dee215SPauli Virtanen 
385166dee215SPauli Virtanen 		if (HCI_CONN_HANDLE_UNSET(conn->handle))
385266dee215SPauli Virtanen 			hci_conn_failed(conn, status);
385366dee215SPauli Virtanen 	}
385466dee215SPauli Virtanen }
385566dee215SPauli Virtanen 
385626afbd82SLuiz Augusto von Dentz static u8 hci_cc_le_set_cig_params(struct hci_dev *hdev, void *data,
385726afbd82SLuiz Augusto von Dentz 				   struct sk_buff *skb)
385826afbd82SLuiz Augusto von Dentz {
385926afbd82SLuiz Augusto von Dentz 	struct hci_rp_le_set_cig_params *rp = data;
386071e95884SPauli Virtanen 	struct hci_cp_le_set_cig_params *cp;
386126afbd82SLuiz Augusto von Dentz 	struct hci_conn *conn;
386271e95884SPauli Virtanen 	u8 status = rp->status;
38637f74563eSPauli Virtanen 	bool pending = false;
386471e95884SPauli Virtanen 	int i;
386526afbd82SLuiz Augusto von Dentz 
386626afbd82SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
386726afbd82SLuiz Augusto von Dentz 
386871e95884SPauli Virtanen 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_CIG_PARAMS);
3869db9cbcadSPauli Virtanen 	if (!rp->status && (!cp || rp->num_handles != cp->num_cis ||
3870db9cbcadSPauli Virtanen 			    rp->cig_id != cp->cig_id)) {
387171e95884SPauli Virtanen 		bt_dev_err(hdev, "unexpected Set CIG Parameters response data");
387271e95884SPauli Virtanen 		status = HCI_ERROR_UNSPECIFIED;
387371e95884SPauli Virtanen 	}
387471e95884SPauli Virtanen 
387526afbd82SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
387626afbd82SLuiz Augusto von Dentz 
387766dee215SPauli Virtanen 	/* BLUETOOTH CORE SPECIFICATION Version 5.4 | Vol 4, Part E page 2554
387866dee215SPauli Virtanen 	 *
387966dee215SPauli Virtanen 	 * If the Status return parameter is non-zero, then the state of the CIG
388066dee215SPauli Virtanen 	 * and its CIS configurations shall not be changed by the command. If
388166dee215SPauli Virtanen 	 * the CIG did not already exist, it shall not be created.
388266dee215SPauli Virtanen 	 */
388371e95884SPauli Virtanen 	if (status) {
388466dee215SPauli Virtanen 		/* Keep current configuration, fail only the unbound CIS */
388566dee215SPauli Virtanen 		hci_unbound_cis_failed(hdev, rp->cig_id, status);
388626afbd82SLuiz Augusto von Dentz 		goto unlock;
388726afbd82SLuiz Augusto von Dentz 	}
388826afbd82SLuiz Augusto von Dentz 
388971e95884SPauli Virtanen 	/* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E page 2553
389071e95884SPauli Virtanen 	 *
389171e95884SPauli Virtanen 	 * If the Status return parameter is zero, then the Controller shall
389271e95884SPauli Virtanen 	 * set the Connection_Handle arrayed return parameter to the connection
389371e95884SPauli Virtanen 	 * handle(s) corresponding to the CIS configurations specified in
389471e95884SPauli Virtanen 	 * the CIS_IDs command parameter, in the same order.
389571e95884SPauli Virtanen 	 */
389671e95884SPauli Virtanen 	for (i = 0; i < rp->num_handles; ++i) {
389771e95884SPauli Virtanen 		conn = hci_conn_hash_lookup_cis(hdev, NULL, 0, rp->cig_id,
389871e95884SPauli Virtanen 						cp->cis[i].cis_id);
389971e95884SPauli Virtanen 		if (!conn || !bacmp(&conn->dst, BDADDR_ANY))
390026afbd82SLuiz Augusto von Dentz 			continue;
390126afbd82SLuiz Augusto von Dentz 
390271e95884SPauli Virtanen 		if (conn->state != BT_BOUND && conn->state != BT_CONNECT)
390371e95884SPauli Virtanen 			continue;
390471e95884SPauli Virtanen 
390516e3b642SLuiz Augusto von Dentz 		if (hci_conn_set_handle(conn, __le16_to_cpu(rp->handle[i])))
390616e3b642SLuiz Augusto von Dentz 			continue;
390726afbd82SLuiz Augusto von Dentz 
39087f74563eSPauli Virtanen 		if (conn->state == BT_CONNECT)
39097f74563eSPauli Virtanen 			pending = true;
3910e9d50f76SLuiz Augusto von Dentz 	}
391126afbd82SLuiz Augusto von Dentz 
391226afbd82SLuiz Augusto von Dentz unlock:
39137f74563eSPauli Virtanen 	if (pending)
39147f74563eSPauli Virtanen 		hci_le_create_cis_pending(hdev);
39157f74563eSPauli Virtanen 
391626afbd82SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
391726afbd82SLuiz Augusto von Dentz 
391826afbd82SLuiz Augusto von Dentz 	return rp->status;
391926afbd82SLuiz Augusto von Dentz }
392026afbd82SLuiz Augusto von Dentz 
392126afbd82SLuiz Augusto von Dentz static u8 hci_cc_le_setup_iso_path(struct hci_dev *hdev, void *data,
392226afbd82SLuiz Augusto von Dentz 				   struct sk_buff *skb)
392326afbd82SLuiz Augusto von Dentz {
392426afbd82SLuiz Augusto von Dentz 	struct hci_rp_le_setup_iso_path *rp = data;
392526afbd82SLuiz Augusto von Dentz 	struct hci_cp_le_setup_iso_path *cp;
392626afbd82SLuiz Augusto von Dentz 	struct hci_conn *conn;
392726afbd82SLuiz Augusto von Dentz 
392826afbd82SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
392926afbd82SLuiz Augusto von Dentz 
393026afbd82SLuiz Augusto von Dentz 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SETUP_ISO_PATH);
393126afbd82SLuiz Augusto von Dentz 	if (!cp)
393226afbd82SLuiz Augusto von Dentz 		return rp->status;
393326afbd82SLuiz Augusto von Dentz 
393426afbd82SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
393526afbd82SLuiz Augusto von Dentz 
393626afbd82SLuiz Augusto von Dentz 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
393726afbd82SLuiz Augusto von Dentz 	if (!conn)
393826afbd82SLuiz Augusto von Dentz 		goto unlock;
393926afbd82SLuiz Augusto von Dentz 
394026afbd82SLuiz Augusto von Dentz 	if (rp->status) {
394126afbd82SLuiz Augusto von Dentz 		hci_connect_cfm(conn, rp->status);
394226afbd82SLuiz Augusto von Dentz 		hci_conn_del(conn);
394326afbd82SLuiz Augusto von Dentz 		goto unlock;
394426afbd82SLuiz Augusto von Dentz 	}
394526afbd82SLuiz Augusto von Dentz 
394626afbd82SLuiz Augusto von Dentz 	switch (cp->direction) {
394726afbd82SLuiz Augusto von Dentz 	/* Input (Host to Controller) */
394826afbd82SLuiz Augusto von Dentz 	case 0x00:
394926afbd82SLuiz Augusto von Dentz 		/* Only confirm connection if output only */
39500fe8c8d0SIulia Tanasescu 		if (conn->iso_qos.ucast.out.sdu && !conn->iso_qos.ucast.in.sdu)
395126afbd82SLuiz Augusto von Dentz 			hci_connect_cfm(conn, rp->status);
395226afbd82SLuiz Augusto von Dentz 		break;
395326afbd82SLuiz Augusto von Dentz 	/* Output (Controller to Host) */
395426afbd82SLuiz Augusto von Dentz 	case 0x01:
395526afbd82SLuiz Augusto von Dentz 		/* Confirm connection since conn->iso_qos is always configured
395626afbd82SLuiz Augusto von Dentz 		 * last.
395726afbd82SLuiz Augusto von Dentz 		 */
395826afbd82SLuiz Augusto von Dentz 		hci_connect_cfm(conn, rp->status);
39590b3df53cSLuiz Augusto von Dentz 
39600b3df53cSLuiz Augusto von Dentz 		/* Notify device connected in case it is a BIG Sync */
39610b3df53cSLuiz Augusto von Dentz 		if (!rp->status && test_bit(HCI_CONN_BIG_SYNC, &conn->flags))
39620b3df53cSLuiz Augusto von Dentz 			mgmt_device_connected(hdev, conn, NULL, 0);
39630b3df53cSLuiz Augusto von Dentz 
396426afbd82SLuiz Augusto von Dentz 		break;
396526afbd82SLuiz Augusto von Dentz 	}
396626afbd82SLuiz Augusto von Dentz 
396726afbd82SLuiz Augusto von Dentz unlock:
396826afbd82SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
396926afbd82SLuiz Augusto von Dentz 	return rp->status;
397026afbd82SLuiz Augusto von Dentz }
397126afbd82SLuiz Augusto von Dentz 
3972eca0ae4aSLuiz Augusto von Dentz static void hci_cs_le_create_big(struct hci_dev *hdev, u8 status)
3973eca0ae4aSLuiz Augusto von Dentz {
3974eca0ae4aSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
3975eca0ae4aSLuiz Augusto von Dentz }
3976eca0ae4aSLuiz Augusto von Dentz 
3977eca0ae4aSLuiz Augusto von Dentz static u8 hci_cc_set_per_adv_param(struct hci_dev *hdev, void *data,
3978eca0ae4aSLuiz Augusto von Dentz 				   struct sk_buff *skb)
3979eca0ae4aSLuiz Augusto von Dentz {
3980eca0ae4aSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
3981eca0ae4aSLuiz Augusto von Dentz 	struct hci_cp_le_set_per_adv_params *cp;
3982eca0ae4aSLuiz Augusto von Dentz 
3983eca0ae4aSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
3984eca0ae4aSLuiz Augusto von Dentz 
3985eca0ae4aSLuiz Augusto von Dentz 	if (rp->status)
3986eca0ae4aSLuiz Augusto von Dentz 		return rp->status;
3987eca0ae4aSLuiz Augusto von Dentz 
3988eca0ae4aSLuiz Augusto von Dentz 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_PER_ADV_PARAMS);
3989eca0ae4aSLuiz Augusto von Dentz 	if (!cp)
3990eca0ae4aSLuiz Augusto von Dentz 		return rp->status;
3991eca0ae4aSLuiz Augusto von Dentz 
3992eca0ae4aSLuiz Augusto von Dentz 	/* TODO: set the conn state */
3993eca0ae4aSLuiz Augusto von Dentz 	return rp->status;
3994eca0ae4aSLuiz Augusto von Dentz }
3995eca0ae4aSLuiz Augusto von Dentz 
3996eca0ae4aSLuiz Augusto von Dentz static u8 hci_cc_le_set_per_adv_enable(struct hci_dev *hdev, void *data,
3997eca0ae4aSLuiz Augusto von Dentz 				       struct sk_buff *skb)
3998eca0ae4aSLuiz Augusto von Dentz {
3999eca0ae4aSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
40006a42e9bfSIulia Tanasescu 	struct hci_cp_le_set_per_adv_enable *cp;
40016a42e9bfSIulia Tanasescu 	struct adv_info *adv = NULL, *n;
40026a42e9bfSIulia Tanasescu 	u8 per_adv_cnt = 0;
4003eca0ae4aSLuiz Augusto von Dentz 
4004eca0ae4aSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
4005eca0ae4aSLuiz Augusto von Dentz 
4006eca0ae4aSLuiz Augusto von Dentz 	if (rp->status)
4007eca0ae4aSLuiz Augusto von Dentz 		return rp->status;
4008eca0ae4aSLuiz Augusto von Dentz 
40096a42e9bfSIulia Tanasescu 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_PER_ADV_ENABLE);
40106a42e9bfSIulia Tanasescu 	if (!cp)
4011eca0ae4aSLuiz Augusto von Dentz 		return rp->status;
4012eca0ae4aSLuiz Augusto von Dentz 
4013eca0ae4aSLuiz Augusto von Dentz 	hci_dev_lock(hdev);
4014eca0ae4aSLuiz Augusto von Dentz 
40156a42e9bfSIulia Tanasescu 	adv = hci_find_adv_instance(hdev, cp->handle);
4016eca0ae4aSLuiz Augusto von Dentz 
40176a42e9bfSIulia Tanasescu 	if (cp->enable) {
40186a42e9bfSIulia Tanasescu 		hci_dev_set_flag(hdev, HCI_LE_PER_ADV);
40196a42e9bfSIulia Tanasescu 
40206a42e9bfSIulia Tanasescu 		if (adv)
40216a42e9bfSIulia Tanasescu 			adv->enabled = true;
40226a42e9bfSIulia Tanasescu 	} else {
40236a42e9bfSIulia Tanasescu 		/* If just one instance was disabled check if there are
40246a42e9bfSIulia Tanasescu 		 * any other instance enabled before clearing HCI_LE_PER_ADV.
40256a42e9bfSIulia Tanasescu 		 * The current periodic adv instance will be marked as
40266a42e9bfSIulia Tanasescu 		 * disabled once extended advertising is also disabled.
40276a42e9bfSIulia Tanasescu 		 */
40286a42e9bfSIulia Tanasescu 		list_for_each_entry_safe(adv, n, &hdev->adv_instances,
40296a42e9bfSIulia Tanasescu 					 list) {
40306a42e9bfSIulia Tanasescu 			if (adv->periodic && adv->enabled)
40316a42e9bfSIulia Tanasescu 				per_adv_cnt++;
40326a42e9bfSIulia Tanasescu 		}
40336a42e9bfSIulia Tanasescu 
40346a42e9bfSIulia Tanasescu 		if (per_adv_cnt > 1)
40356a42e9bfSIulia Tanasescu 			goto unlock;
40366a42e9bfSIulia Tanasescu 
40376a42e9bfSIulia Tanasescu 		hci_dev_clear_flag(hdev, HCI_LE_PER_ADV);
40386a42e9bfSIulia Tanasescu 	}
40396a42e9bfSIulia Tanasescu 
40406a42e9bfSIulia Tanasescu unlock:
4041eca0ae4aSLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
4042eca0ae4aSLuiz Augusto von Dentz 
4043eca0ae4aSLuiz Augusto von Dentz 	return rp->status;
4044eca0ae4aSLuiz Augusto von Dentz }
4045eca0ae4aSLuiz Augusto von Dentz 
4046c8992cffSLuiz Augusto von Dentz #define HCI_CC_VL(_op, _func, _min, _max) \
4047c8992cffSLuiz Augusto von Dentz { \
4048c8992cffSLuiz Augusto von Dentz 	.op = _op, \
4049c8992cffSLuiz Augusto von Dentz 	.func = _func, \
4050c8992cffSLuiz Augusto von Dentz 	.min_len = _min, \
4051c8992cffSLuiz Augusto von Dentz 	.max_len = _max, \
4052c8992cffSLuiz Augusto von Dentz }
4053c8992cffSLuiz Augusto von Dentz 
4054c8992cffSLuiz Augusto von Dentz #define HCI_CC(_op, _func, _len) \
4055c8992cffSLuiz Augusto von Dentz 	HCI_CC_VL(_op, _func, _len, _len)
4056c8992cffSLuiz Augusto von Dentz 
4057c8992cffSLuiz Augusto von Dentz #define HCI_CC_STATUS(_op, _func) \
4058c8992cffSLuiz Augusto von Dentz 	HCI_CC(_op, _func, sizeof(struct hci_ev_status))
4059c8992cffSLuiz Augusto von Dentz 
4060c8992cffSLuiz Augusto von Dentz static const struct hci_cc {
4061c8992cffSLuiz Augusto von Dentz 	u16  op;
4062c8992cffSLuiz Augusto von Dentz 	u8 (*func)(struct hci_dev *hdev, void *data, struct sk_buff *skb);
4063c8992cffSLuiz Augusto von Dentz 	u16  min_len;
4064c8992cffSLuiz Augusto von Dentz 	u16  max_len;
4065c8992cffSLuiz Augusto von Dentz } hci_cc_table[] = {
4066c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_INQUIRY_CANCEL, hci_cc_inquiry_cancel),
4067c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_PERIODIC_INQ, hci_cc_periodic_inq),
4068c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_EXIT_PERIODIC_INQ, hci_cc_exit_periodic_inq),
4069c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_REMOTE_NAME_REQ_CANCEL,
4070c8992cffSLuiz Augusto von Dentz 		      hci_cc_remote_name_req_cancel),
4071c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_ROLE_DISCOVERY, hci_cc_role_discovery,
4072c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_role_discovery)),
4073c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LINK_POLICY, hci_cc_read_link_policy,
4074c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_link_policy)),
4075c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_WRITE_LINK_POLICY, hci_cc_write_link_policy,
4076c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_write_link_policy)),
4077c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_DEF_LINK_POLICY, hci_cc_read_def_link_policy,
4078c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_def_link_policy)),
4079c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_DEF_LINK_POLICY,
4080c8992cffSLuiz Augusto von Dentz 		      hci_cc_write_def_link_policy),
4081c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_RESET, hci_cc_reset),
4082c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_STORED_LINK_KEY, hci_cc_read_stored_link_key,
4083c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_stored_link_key)),
4084c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_DELETE_STORED_LINK_KEY, hci_cc_delete_stored_link_key,
4085c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_delete_stored_link_key)),
4086c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_LOCAL_NAME, hci_cc_write_local_name),
4087c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_NAME, hci_cc_read_local_name,
4088c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_name)),
4089c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_AUTH_ENABLE, hci_cc_write_auth_enable),
4090c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_ENCRYPT_MODE, hci_cc_write_encrypt_mode),
4091c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_SCAN_ENABLE, hci_cc_write_scan_enable),
4092c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_SET_EVENT_FLT, hci_cc_set_event_filter),
4093c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_CLASS_OF_DEV, hci_cc_read_class_of_dev,
4094c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_class_of_dev)),
4095c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_CLASS_OF_DEV, hci_cc_write_class_of_dev),
4096c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_VOICE_SETTING, hci_cc_read_voice_setting,
4097c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_voice_setting)),
4098c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_VOICE_SETTING, hci_cc_write_voice_setting),
4099c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_NUM_SUPPORTED_IAC, hci_cc_read_num_supported_iac,
4100c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_num_supported_iac)),
4101c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_SSP_MODE, hci_cc_write_ssp_mode),
4102c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_SC_SUPPORT, hci_cc_write_sc_support),
4103c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_AUTH_PAYLOAD_TO, hci_cc_read_auth_payload_timeout,
4104c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_auth_payload_to)),
4105c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_WRITE_AUTH_PAYLOAD_TO, hci_cc_write_auth_payload_timeout,
4106c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_write_auth_payload_to)),
4107c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_VERSION, hci_cc_read_local_version,
4108c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_version)),
4109c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_COMMANDS, hci_cc_read_local_commands,
4110c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_commands)),
4111c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_FEATURES, hci_cc_read_local_features,
4112c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_features)),
4113c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_EXT_FEATURES, hci_cc_read_local_ext_features,
4114c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_ext_features)),
4115c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_BUFFER_SIZE, hci_cc_read_buffer_size,
4116c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_buffer_size)),
4117c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_BD_ADDR, hci_cc_read_bd_addr,
4118c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_bd_addr)),
4119c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_PAIRING_OPTS, hci_cc_read_local_pairing_opts,
4120c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_pairing_opts)),
4121c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_PAGE_SCAN_ACTIVITY, hci_cc_read_page_scan_activity,
4122c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_page_scan_activity)),
4123c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_PAGE_SCAN_ACTIVITY,
4124c8992cffSLuiz Augusto von Dentz 		      hci_cc_write_page_scan_activity),
4125c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_PAGE_SCAN_TYPE, hci_cc_read_page_scan_type,
4126c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_page_scan_type)),
4127c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_PAGE_SCAN_TYPE, hci_cc_write_page_scan_type),
4128c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_DATA_BLOCK_SIZE, hci_cc_read_data_block_size,
4129c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_data_block_size)),
4130c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_FLOW_CONTROL_MODE, hci_cc_read_flow_control_mode,
4131c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_flow_control_mode)),
4132c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_AMP_INFO, hci_cc_read_local_amp_info,
4133c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_amp_info)),
4134c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_CLOCK, hci_cc_read_clock,
4135c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_clock)),
4136278d933eSBrian Gix 	HCI_CC(HCI_OP_READ_ENC_KEY_SIZE, hci_cc_read_enc_key_size,
4137278d933eSBrian Gix 	       sizeof(struct hci_rp_read_enc_key_size)),
4138c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_INQ_RSP_TX_POWER, hci_cc_read_inq_rsp_tx_power,
4139c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_inq_rsp_tx_power)),
4140c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_DEF_ERR_DATA_REPORTING,
4141c8992cffSLuiz Augusto von Dentz 	       hci_cc_read_def_err_data_reporting,
4142c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_def_err_data_reporting)),
4143c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_DEF_ERR_DATA_REPORTING,
4144c8992cffSLuiz Augusto von Dentz 		      hci_cc_write_def_err_data_reporting),
4145c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_PIN_CODE_REPLY, hci_cc_pin_code_reply,
4146c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_pin_code_reply)),
4147c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_PIN_CODE_NEG_REPLY, hci_cc_pin_code_neg_reply,
4148c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_pin_code_neg_reply)),
4149c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_OOB_DATA, hci_cc_read_local_oob_data,
4150c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_oob_data)),
4151c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_OOB_EXT_DATA, hci_cc_read_local_oob_ext_data,
4152c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_oob_ext_data)),
4153c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_BUFFER_SIZE, hci_cc_le_read_buffer_size,
4154c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_buffer_size)),
4155c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_LOCAL_FEATURES, hci_cc_le_read_local_features,
4156c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_local_features)),
4157c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_ADV_TX_POWER, hci_cc_le_read_adv_tx_power,
4158c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_adv_tx_power)),
4159c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_USER_CONFIRM_REPLY, hci_cc_user_confirm_reply,
4160c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_user_confirm_reply)),
4161c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_USER_CONFIRM_NEG_REPLY, hci_cc_user_confirm_neg_reply,
4162c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_user_confirm_reply)),
4163c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_USER_PASSKEY_REPLY, hci_cc_user_passkey_reply,
4164c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_user_confirm_reply)),
4165c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_USER_PASSKEY_NEG_REPLY, hci_cc_user_passkey_neg_reply,
4166c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_user_confirm_reply)),
4167c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_RANDOM_ADDR, hci_cc_le_set_random_addr),
4168c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_ADV_ENABLE, hci_cc_le_set_adv_enable),
4169c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_SCAN_PARAM, hci_cc_le_set_scan_param),
4170c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_SCAN_ENABLE, hci_cc_le_set_scan_enable),
4171c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_ACCEPT_LIST_SIZE,
4172c8992cffSLuiz Augusto von Dentz 	       hci_cc_le_read_accept_list_size,
4173c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_accept_list_size)),
4174c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_CLEAR_ACCEPT_LIST, hci_cc_le_clear_accept_list),
4175c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_ADD_TO_ACCEPT_LIST,
4176c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_add_to_accept_list),
4177c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_DEL_FROM_ACCEPT_LIST,
4178c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_del_from_accept_list),
4179c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_SUPPORTED_STATES, hci_cc_le_read_supported_states,
4180c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_supported_states)),
4181c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_DEF_DATA_LEN, hci_cc_le_read_def_data_len,
4182c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_def_data_len)),
4183c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_WRITE_DEF_DATA_LEN,
4184c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_write_def_data_len),
4185c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_ADD_TO_RESOLV_LIST,
4186c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_add_to_resolv_list),
4187c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_DEL_FROM_RESOLV_LIST,
4188c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_del_from_resolv_list),
4189c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_CLEAR_RESOLV_LIST,
4190c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_clear_resolv_list),
4191c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_RESOLV_LIST_SIZE, hci_cc_le_read_resolv_list_size,
4192c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_resolv_list_size)),
4193c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_ADDR_RESOLV_ENABLE,
4194c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_set_addr_resolution_enable),
4195c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_MAX_DATA_LEN, hci_cc_le_read_max_data_len,
4196c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_max_data_len)),
4197c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_LE_HOST_SUPPORTED,
4198c8992cffSLuiz Augusto von Dentz 		      hci_cc_write_le_host_supported),
4199c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_ADV_PARAM, hci_cc_set_adv_param),
4200c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_RSSI, hci_cc_read_rssi,
4201c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_rssi)),
4202c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_TX_POWER, hci_cc_read_tx_power,
4203c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_tx_power)),
4204c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_SSP_DEBUG_MODE, hci_cc_write_ssp_debug_mode),
4205c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_EXT_SCAN_PARAMS,
4206c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_set_ext_scan_param),
4207c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_EXT_SCAN_ENABLE,
4208c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_set_ext_scan_enable),
4209c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_DEFAULT_PHY, hci_cc_le_set_default_phy),
4210c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_NUM_SUPPORTED_ADV_SETS,
4211c8992cffSLuiz Augusto von Dentz 	       hci_cc_le_read_num_adv_sets,
4212c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_num_supported_adv_sets)),
4213c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_SET_EXT_ADV_PARAMS, hci_cc_set_ext_adv_param,
4214c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_set_ext_adv_params)),
4215c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_EXT_ADV_ENABLE,
4216c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_set_ext_adv_enable),
4217c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_ADV_SET_RAND_ADDR,
4218c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_set_adv_set_random_addr),
4219c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_REMOVE_ADV_SET, hci_cc_le_remove_adv_set),
4220c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_CLEAR_ADV_SETS, hci_cc_le_clear_adv_sets),
4221eca0ae4aSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_PER_ADV_PARAMS, hci_cc_set_per_adv_param),
4222eca0ae4aSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_PER_ADV_ENABLE,
4223eca0ae4aSLuiz Augusto von Dentz 		      hci_cc_le_set_per_adv_enable),
4224c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_TRANSMIT_POWER, hci_cc_le_read_transmit_power,
4225853b70b5SLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_transmit_power)),
422626afbd82SLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_PRIVACY_MODE, hci_cc_le_set_privacy_mode),
422726afbd82SLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_BUFFER_SIZE_V2, hci_cc_le_read_buffer_size_v2,
422826afbd82SLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_buffer_size_v2)),
422926afbd82SLuiz Augusto von Dentz 	HCI_CC_VL(HCI_OP_LE_SET_CIG_PARAMS, hci_cc_le_set_cig_params,
423026afbd82SLuiz Augusto von Dentz 		  sizeof(struct hci_rp_le_set_cig_params), HCI_MAX_EVENT_SIZE),
423126afbd82SLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_SETUP_ISO_PATH, hci_cc_le_setup_iso_path,
423226afbd82SLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_setup_iso_path)),
4233c8992cffSLuiz Augusto von Dentz };
4234c8992cffSLuiz Augusto von Dentz 
4235c8992cffSLuiz Augusto von Dentz static u8 hci_cc_func(struct hci_dev *hdev, const struct hci_cc *cc,
4236c8992cffSLuiz Augusto von Dentz 		      struct sk_buff *skb)
4237c8992cffSLuiz Augusto von Dentz {
4238c8992cffSLuiz Augusto von Dentz 	void *data;
4239c8992cffSLuiz Augusto von Dentz 
4240c8992cffSLuiz Augusto von Dentz 	if (skb->len < cc->min_len) {
4241c8992cffSLuiz Augusto von Dentz 		bt_dev_err(hdev, "unexpected cc 0x%4.4x length: %u < %u",
4242c8992cffSLuiz Augusto von Dentz 			   cc->op, skb->len, cc->min_len);
4243c8992cffSLuiz Augusto von Dentz 		return HCI_ERROR_UNSPECIFIED;
4244c8992cffSLuiz Augusto von Dentz 	}
4245c8992cffSLuiz Augusto von Dentz 
4246c8992cffSLuiz Augusto von Dentz 	/* Just warn if the length is over max_len size it still be possible to
4247c8992cffSLuiz Augusto von Dentz 	 * partially parse the cc so leave to callback to decide if that is
4248c8992cffSLuiz Augusto von Dentz 	 * acceptable.
4249c8992cffSLuiz Augusto von Dentz 	 */
4250c8992cffSLuiz Augusto von Dentz 	if (skb->len > cc->max_len)
4251c8992cffSLuiz Augusto von Dentz 		bt_dev_warn(hdev, "unexpected cc 0x%4.4x length: %u > %u",
4252c8992cffSLuiz Augusto von Dentz 			    cc->op, skb->len, cc->max_len);
4253c8992cffSLuiz Augusto von Dentz 
4254c8992cffSLuiz Augusto von Dentz 	data = hci_cc_skb_pull(hdev, skb, cc->op, cc->min_len);
4255c8992cffSLuiz Augusto von Dentz 	if (!data)
4256c8992cffSLuiz Augusto von Dentz 		return HCI_ERROR_UNSPECIFIED;
4257c8992cffSLuiz Augusto von Dentz 
4258c8992cffSLuiz Augusto von Dentz 	return cc->func(hdev, data, skb);
4259c8992cffSLuiz Augusto von Dentz }
4260c8992cffSLuiz Augusto von Dentz 
42613e54c589SLuiz Augusto von Dentz static void hci_cmd_complete_evt(struct hci_dev *hdev, void *data,
42623e54c589SLuiz Augusto von Dentz 				 struct sk_buff *skb, u16 *opcode, u8 *status,
4263e6214487SJohan Hedberg 				 hci_req_complete_t *req_complete,
4264e6214487SJohan Hedberg 				 hci_req_complete_skb_t *req_complete_skb)
4265a9de9248SMarcel Holtmann {
42663e54c589SLuiz Augusto von Dentz 	struct hci_ev_cmd_complete *ev = data;
4267c8992cffSLuiz Augusto von Dentz 	int i;
4268e6214487SJohan Hedberg 
4269e6214487SJohan Hedberg 	*opcode = __le16_to_cpu(ev->opcode);
4270a9de9248SMarcel Holtmann 
4271c8992cffSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "opcode 0x%4.4x", *opcode);
4272a9de9248SMarcel Holtmann 
4273c8992cffSLuiz Augusto von Dentz 	for (i = 0; i < ARRAY_SIZE(hci_cc_table); i++) {
4274c8992cffSLuiz Augusto von Dentz 		if (hci_cc_table[i].op == *opcode) {
4275c8992cffSLuiz Augusto von Dentz 			*status = hci_cc_func(hdev, &hci_cc_table[i], skb);
42764d93483bSAndre Guedes 			break;
4277c8992cffSLuiz Augusto von Dentz 		}
4278a9de9248SMarcel Holtmann 	}
4279a9de9248SMarcel Holtmann 
4280afcb3369SHans de Goede 	if (i == ARRAY_SIZE(hci_cc_table)) {
4281afcb3369SHans de Goede 		/* Unknown opcode, assume byte 0 contains the status, so
4282afcb3369SHans de Goede 		 * that e.g. __hci_cmd_sync() properly returns errors
4283afcb3369SHans de Goede 		 * for vendor specific commands send by HCI drivers.
4284afcb3369SHans de Goede 		 * If a vendor doesn't actually follow this convention we may
4285afcb3369SHans de Goede 		 * need to introduce a vendor CC table in order to properly set
4286afcb3369SHans de Goede 		 * the status.
4287afcb3369SHans de Goede 		 */
4288afcb3369SHans de Goede 		*status = skb->data[0];
4289afcb3369SHans de Goede 	}
4290afcb3369SHans de Goede 
4291ecb71f25SKiran K 	handle_cmd_cnt_and_timer(hdev, ev->ncmd);
4292600b2150SJohan Hedberg 
4293e6214487SJohan Hedberg 	hci_req_cmd_complete(hdev, *opcode, *status, req_complete,
4294e6214487SJohan Hedberg 			     req_complete_skb);
42959238f36aSJohan Hedberg 
4296f80c5dadSJoão Paulo Rechi Vita 	if (hci_dev_test_flag(hdev, HCI_CMD_PENDING)) {
4297f80c5dadSJoão Paulo Rechi Vita 		bt_dev_err(hdev,
4298f80c5dadSJoão Paulo Rechi Vita 			   "unexpected event for opcode 0x%4.4x", *opcode);
4299f80c5dadSJoão Paulo Rechi Vita 		return;
4300f80c5dadSJoão Paulo Rechi Vita 	}
4301f80c5dadSJoão Paulo Rechi Vita 
4302600b2150SJohan Hedberg 	if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q))
4303c347b765SGustavo F. Padovan 		queue_work(hdev->workqueue, &hdev->cmd_work);
4304a9de9248SMarcel Holtmann }
4305a9de9248SMarcel Holtmann 
430626afbd82SLuiz Augusto von Dentz static void hci_cs_le_create_cis(struct hci_dev *hdev, u8 status)
430726afbd82SLuiz Augusto von Dentz {
430826afbd82SLuiz Augusto von Dentz 	struct hci_cp_le_create_cis *cp;
43097f74563eSPauli Virtanen 	bool pending = false;
431026afbd82SLuiz Augusto von Dentz 	int i;
431126afbd82SLuiz Augusto von Dentz 
431226afbd82SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
431326afbd82SLuiz Augusto von Dentz 
431426afbd82SLuiz Augusto von Dentz 	if (!status)
431526afbd82SLuiz Augusto von Dentz 		return;
431626afbd82SLuiz Augusto von Dentz 
431726afbd82SLuiz Augusto von Dentz 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CIS);
431826afbd82SLuiz Augusto von Dentz 	if (!cp)
431926afbd82SLuiz Augusto von Dentz 		return;
432026afbd82SLuiz Augusto von Dentz 
432126afbd82SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
432226afbd82SLuiz Augusto von Dentz 
432326afbd82SLuiz Augusto von Dentz 	/* Remove connection if command failed */
432426afbd82SLuiz Augusto von Dentz 	for (i = 0; cp->num_cis; cp->num_cis--, i++) {
432526afbd82SLuiz Augusto von Dentz 		struct hci_conn *conn;
432626afbd82SLuiz Augusto von Dentz 		u16 handle;
432726afbd82SLuiz Augusto von Dentz 
432826afbd82SLuiz Augusto von Dentz 		handle = __le16_to_cpu(cp->cis[i].cis_handle);
432926afbd82SLuiz Augusto von Dentz 
433026afbd82SLuiz Augusto von Dentz 		conn = hci_conn_hash_lookup_handle(hdev, handle);
433126afbd82SLuiz Augusto von Dentz 		if (conn) {
43327f74563eSPauli Virtanen 			if (test_and_clear_bit(HCI_CONN_CREATE_CIS,
43337f74563eSPauli Virtanen 					       &conn->flags))
43347f74563eSPauli Virtanen 				pending = true;
433526afbd82SLuiz Augusto von Dentz 			conn->state = BT_CLOSED;
433626afbd82SLuiz Augusto von Dentz 			hci_connect_cfm(conn, status);
433726afbd82SLuiz Augusto von Dentz 			hci_conn_del(conn);
433826afbd82SLuiz Augusto von Dentz 		}
433926afbd82SLuiz Augusto von Dentz 	}
434026afbd82SLuiz Augusto von Dentz 
43417f74563eSPauli Virtanen 	if (pending)
43427f74563eSPauli Virtanen 		hci_le_create_cis_pending(hdev);
43437f74563eSPauli Virtanen 
434426afbd82SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
434526afbd82SLuiz Augusto von Dentz }
434626afbd82SLuiz Augusto von Dentz 
4347147306ccSLuiz Augusto von Dentz #define HCI_CS(_op, _func) \
4348147306ccSLuiz Augusto von Dentz { \
4349147306ccSLuiz Augusto von Dentz 	.op = _op, \
4350147306ccSLuiz Augusto von Dentz 	.func = _func, \
4351147306ccSLuiz Augusto von Dentz }
4352147306ccSLuiz Augusto von Dentz 
4353147306ccSLuiz Augusto von Dentz static const struct hci_cs {
4354147306ccSLuiz Augusto von Dentz 	u16  op;
4355147306ccSLuiz Augusto von Dentz 	void (*func)(struct hci_dev *hdev, __u8 status);
4356147306ccSLuiz Augusto von Dentz } hci_cs_table[] = {
4357147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_INQUIRY, hci_cs_inquiry),
4358147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_CREATE_CONN, hci_cs_create_conn),
4359147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_DISCONNECT, hci_cs_disconnect),
4360147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_ADD_SCO, hci_cs_add_sco),
4361147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_AUTH_REQUESTED, hci_cs_auth_requested),
4362147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_SET_CONN_ENCRYPT, hci_cs_set_conn_encrypt),
4363147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_REMOTE_NAME_REQ, hci_cs_remote_name_req),
4364147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_READ_REMOTE_FEATURES, hci_cs_read_remote_features),
4365147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_READ_REMOTE_EXT_FEATURES,
4366147306ccSLuiz Augusto von Dentz 	       hci_cs_read_remote_ext_features),
4367147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_SETUP_SYNC_CONN, hci_cs_setup_sync_conn),
4368147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_ENHANCED_SETUP_SYNC_CONN,
4369147306ccSLuiz Augusto von Dentz 	       hci_cs_enhanced_setup_sync_conn),
4370147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_SNIFF_MODE, hci_cs_sniff_mode),
4371147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_EXIT_SNIFF_MODE, hci_cs_exit_sniff_mode),
4372147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_SWITCH_ROLE, hci_cs_switch_role),
4373147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_LE_CREATE_CONN, hci_cs_le_create_conn),
4374147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_LE_READ_REMOTE_FEATURES, hci_cs_le_read_remote_features),
4375147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_LE_START_ENC, hci_cs_le_start_enc),
437626afbd82SLuiz Augusto von Dentz 	HCI_CS(HCI_OP_LE_EXT_CREATE_CONN, hci_cs_le_ext_create_conn),
437726afbd82SLuiz Augusto von Dentz 	HCI_CS(HCI_OP_LE_CREATE_CIS, hci_cs_le_create_cis),
4378eca0ae4aSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_LE_CREATE_BIG, hci_cs_le_create_big),
4379147306ccSLuiz Augusto von Dentz };
4380147306ccSLuiz Augusto von Dentz 
43813e54c589SLuiz Augusto von Dentz static void hci_cmd_status_evt(struct hci_dev *hdev, void *data,
43823e54c589SLuiz Augusto von Dentz 			       struct sk_buff *skb, u16 *opcode, u8 *status,
4383e6214487SJohan Hedberg 			       hci_req_complete_t *req_complete,
4384e6214487SJohan Hedberg 			       hci_req_complete_skb_t *req_complete_skb)
4385a9de9248SMarcel Holtmann {
43863e54c589SLuiz Augusto von Dentz 	struct hci_ev_cmd_status *ev = data;
4387147306ccSLuiz Augusto von Dentz 	int i;
4388a9de9248SMarcel Holtmann 
4389e6214487SJohan Hedberg 	*opcode = __le16_to_cpu(ev->opcode);
4390e6214487SJohan Hedberg 	*status = ev->status;
4391a9de9248SMarcel Holtmann 
4392147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "opcode 0x%4.4x", *opcode);
4393a9de9248SMarcel Holtmann 
4394147306ccSLuiz Augusto von Dentz 	for (i = 0; i < ARRAY_SIZE(hci_cs_table); i++) {
4395147306ccSLuiz Augusto von Dentz 		if (hci_cs_table[i].op == *opcode) {
4396147306ccSLuiz Augusto von Dentz 			hci_cs_table[i].func(hdev, ev->status);
4397a9de9248SMarcel Holtmann 			break;
4398147306ccSLuiz Augusto von Dentz 		}
4399a9de9248SMarcel Holtmann 	}
4400a9de9248SMarcel Holtmann 
4401ecb71f25SKiran K 	handle_cmd_cnt_and_timer(hdev, ev->ncmd);
4402600b2150SJohan Hedberg 
4403444c6dd5SJohan Hedberg 	/* Indicate request completion if the command failed. Also, if
4404444c6dd5SJohan Hedberg 	 * we're not waiting for a special event and we get a success
4405444c6dd5SJohan Hedberg 	 * command status we should try to flag the request as completed
4406444c6dd5SJohan Hedberg 	 * (since for this kind of commands there will not be a command
4407444c6dd5SJohan Hedberg 	 * complete event).
4408444c6dd5SJohan Hedberg 	 */
44092af7aa66SLuiz Augusto von Dentz 	if (ev->status || (hdev->req_skb && !hci_skb_event(hdev->req_skb))) {
4410e6214487SJohan Hedberg 		hci_req_cmd_complete(hdev, *opcode, ev->status, req_complete,
4411e6214487SJohan Hedberg 				     req_complete_skb);
4412f80c5dadSJoão Paulo Rechi Vita 		if (hci_dev_test_flag(hdev, HCI_CMD_PENDING)) {
441385b56857SLuiz Augusto von Dentz 			bt_dev_err(hdev, "unexpected event for opcode 0x%4.4x",
441485b56857SLuiz Augusto von Dentz 				   *opcode);
4415f80c5dadSJoão Paulo Rechi Vita 			return;
4416f80c5dadSJoão Paulo Rechi Vita 		}
441785b56857SLuiz Augusto von Dentz 	}
4418f80c5dadSJoão Paulo Rechi Vita 
4419600b2150SJohan Hedberg 	if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q))
4420c347b765SGustavo F. Padovan 		queue_work(hdev->workqueue, &hdev->cmd_work);
4421a9de9248SMarcel Holtmann }
4422a9de9248SMarcel Holtmann 
44233e54c589SLuiz Augusto von Dentz static void hci_hardware_error_evt(struct hci_dev *hdev, void *data,
44243e54c589SLuiz Augusto von Dentz 				   struct sk_buff *skb)
442524dfa343SMarcel Holtmann {
44263e54c589SLuiz Augusto von Dentz 	struct hci_ev_hardware_error *ev = data;
4427ae61a10dSLuiz Augusto von Dentz 
44283e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "code 0x%2.2x", ev->code);
442924dfa343SMarcel Holtmann 
4430c7741d16SMarcel Holtmann 	hdev->hw_error_code = ev->code;
4431c7741d16SMarcel Holtmann 
4432c7741d16SMarcel Holtmann 	queue_work(hdev->req_workqueue, &hdev->error_reset);
443324dfa343SMarcel Holtmann }
443424dfa343SMarcel Holtmann 
44353e54c589SLuiz Augusto von Dentz static void hci_role_change_evt(struct hci_dev *hdev, void *data,
44363e54c589SLuiz Augusto von Dentz 				struct sk_buff *skb)
4437a9de9248SMarcel Holtmann {
44383e54c589SLuiz Augusto von Dentz 	struct hci_ev_role_change *ev = data;
4439a9de9248SMarcel Holtmann 	struct hci_conn *conn;
4440a9de9248SMarcel Holtmann 
44413e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
4442a9de9248SMarcel Holtmann 
4443a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
4444a9de9248SMarcel Holtmann 
4445a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
4446a9de9248SMarcel Holtmann 	if (conn) {
444740bef302SJohan Hedberg 		if (!ev->status)
444840bef302SJohan Hedberg 			conn->role = ev->role;
4449a9de9248SMarcel Holtmann 
445051a8efd7SJohan Hedberg 		clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
4451a9de9248SMarcel Holtmann 
4452a9de9248SMarcel Holtmann 		hci_role_switch_cfm(conn, ev->status, ev->role);
4453a9de9248SMarcel Holtmann 	}
4454a9de9248SMarcel Holtmann 
4455a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
4456a9de9248SMarcel Holtmann }
4457a9de9248SMarcel Holtmann 
44583e54c589SLuiz Augusto von Dentz static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data,
44593e54c589SLuiz Augusto von Dentz 				  struct sk_buff *skb)
44601da177e4SLinus Torvalds {
44613e54c589SLuiz Augusto von Dentz 	struct hci_ev_num_comp_pkts *ev = data;
44621da177e4SLinus Torvalds 	int i;
44631da177e4SLinus Torvalds 
4464aadc3d2fSLuiz Augusto von Dentz 	if (!hci_ev_skb_pull(hdev, skb, HCI_EV_NUM_COMP_PKTS,
4465aadc3d2fSLuiz Augusto von Dentz 			     flex_array_size(ev, handles, ev->num)))
4466aadc3d2fSLuiz Augusto von Dentz 		return;
4467aadc3d2fSLuiz Augusto von Dentz 
446832ac5b9bSAndrei Emeltchenko 	if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
44692064ee33SMarcel Holtmann 		bt_dev_err(hdev, "wrong event for mode %d", hdev->flow_ctl_mode);
447032ac5b9bSAndrei Emeltchenko 		return;
447132ac5b9bSAndrei Emeltchenko 	}
447232ac5b9bSAndrei Emeltchenko 
44733e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "num %d", ev->num);
44741da177e4SLinus Torvalds 
4475aadc3d2fSLuiz Augusto von Dentz 	for (i = 0; i < ev->num; i++) {
4476613a1c0cSAndrei Emeltchenko 		struct hci_comp_pkts_info *info = &ev->handles[i];
44771da177e4SLinus Torvalds 		struct hci_conn *conn;
44781da177e4SLinus Torvalds 		__u16  handle, count;
44791da177e4SLinus Torvalds 
4480613a1c0cSAndrei Emeltchenko 		handle = __le16_to_cpu(info->handle);
4481613a1c0cSAndrei Emeltchenko 		count  = __le16_to_cpu(info->count);
44821da177e4SLinus Torvalds 
44831da177e4SLinus Torvalds 		conn = hci_conn_hash_lookup_handle(hdev, handle);
4484f4280918SAndrei Emeltchenko 		if (!conn)
4485f4280918SAndrei Emeltchenko 			continue;
4486f4280918SAndrei Emeltchenko 
44871da177e4SLinus Torvalds 		conn->sent -= count;
44881da177e4SLinus Torvalds 
4489f4280918SAndrei Emeltchenko 		switch (conn->type) {
4490f4280918SAndrei Emeltchenko 		case ACL_LINK:
449170f23020SAndrei Emeltchenko 			hdev->acl_cnt += count;
449270f23020SAndrei Emeltchenko 			if (hdev->acl_cnt > hdev->acl_pkts)
44931da177e4SLinus Torvalds 				hdev->acl_cnt = hdev->acl_pkts;
4494f4280918SAndrei Emeltchenko 			break;
4495f4280918SAndrei Emeltchenko 
4496f4280918SAndrei Emeltchenko 		case LE_LINK:
44976ed58ec5SVille Tervo 			if (hdev->le_pkts) {
44986ed58ec5SVille Tervo 				hdev->le_cnt += count;
44996ed58ec5SVille Tervo 				if (hdev->le_cnt > hdev->le_pkts)
45006ed58ec5SVille Tervo 					hdev->le_cnt = hdev->le_pkts;
45016ed58ec5SVille Tervo 			} else {
45026ed58ec5SVille Tervo 				hdev->acl_cnt += count;
45036ed58ec5SVille Tervo 				if (hdev->acl_cnt > hdev->acl_pkts)
45046ed58ec5SVille Tervo 					hdev->acl_cnt = hdev->acl_pkts;
45056ed58ec5SVille Tervo 			}
4506f4280918SAndrei Emeltchenko 			break;
4507f4280918SAndrei Emeltchenko 
4508f4280918SAndrei Emeltchenko 		case SCO_LINK:
450970f23020SAndrei Emeltchenko 			hdev->sco_cnt += count;
451070f23020SAndrei Emeltchenko 			if (hdev->sco_cnt > hdev->sco_pkts)
45115b7f9909SMarcel Holtmann 				hdev->sco_cnt = hdev->sco_pkts;
4512f4280918SAndrei Emeltchenko 			break;
4513f4280918SAndrei Emeltchenko 
451426afbd82SLuiz Augusto von Dentz 		case ISO_LINK:
451526afbd82SLuiz Augusto von Dentz 			if (hdev->iso_pkts) {
451626afbd82SLuiz Augusto von Dentz 				hdev->iso_cnt += count;
451726afbd82SLuiz Augusto von Dentz 				if (hdev->iso_cnt > hdev->iso_pkts)
451826afbd82SLuiz Augusto von Dentz 					hdev->iso_cnt = hdev->iso_pkts;
451926afbd82SLuiz Augusto von Dentz 			} else if (hdev->le_pkts) {
452026afbd82SLuiz Augusto von Dentz 				hdev->le_cnt += count;
452126afbd82SLuiz Augusto von Dentz 				if (hdev->le_cnt > hdev->le_pkts)
452226afbd82SLuiz Augusto von Dentz 					hdev->le_cnt = hdev->le_pkts;
452326afbd82SLuiz Augusto von Dentz 			} else {
452426afbd82SLuiz Augusto von Dentz 				hdev->acl_cnt += count;
452526afbd82SLuiz Augusto von Dentz 				if (hdev->acl_cnt > hdev->acl_pkts)
452626afbd82SLuiz Augusto von Dentz 					hdev->acl_cnt = hdev->acl_pkts;
452726afbd82SLuiz Augusto von Dentz 			}
452826afbd82SLuiz Augusto von Dentz 			break;
452926afbd82SLuiz Augusto von Dentz 
4530f4280918SAndrei Emeltchenko 		default:
45312064ee33SMarcel Holtmann 			bt_dev_err(hdev, "unknown type %d conn %p",
45322064ee33SMarcel Holtmann 				   conn->type, conn);
4533f4280918SAndrei Emeltchenko 			break;
45341da177e4SLinus Torvalds 		}
45351da177e4SLinus Torvalds 	}
4536a9de9248SMarcel Holtmann 
45373eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
45381da177e4SLinus Torvalds }
45391da177e4SLinus Torvalds 
454076ef7cf7SAndrei Emeltchenko static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
454176ef7cf7SAndrei Emeltchenko 						 __u16 handle)
454276ef7cf7SAndrei Emeltchenko {
454376ef7cf7SAndrei Emeltchenko 	struct hci_chan *chan;
454476ef7cf7SAndrei Emeltchenko 
454576ef7cf7SAndrei Emeltchenko 	switch (hdev->dev_type) {
4546ca8bee5dSMarcel Holtmann 	case HCI_PRIMARY:
454776ef7cf7SAndrei Emeltchenko 		return hci_conn_hash_lookup_handle(hdev, handle);
454876ef7cf7SAndrei Emeltchenko 	case HCI_AMP:
454976ef7cf7SAndrei Emeltchenko 		chan = hci_chan_lookup_handle(hdev, handle);
455076ef7cf7SAndrei Emeltchenko 		if (chan)
455176ef7cf7SAndrei Emeltchenko 			return chan->conn;
455276ef7cf7SAndrei Emeltchenko 		break;
455376ef7cf7SAndrei Emeltchenko 	default:
45542064ee33SMarcel Holtmann 		bt_dev_err(hdev, "unknown dev_type %d", hdev->dev_type);
455576ef7cf7SAndrei Emeltchenko 		break;
455676ef7cf7SAndrei Emeltchenko 	}
455776ef7cf7SAndrei Emeltchenko 
455876ef7cf7SAndrei Emeltchenko 	return NULL;
455976ef7cf7SAndrei Emeltchenko }
456076ef7cf7SAndrei Emeltchenko 
45613e54c589SLuiz Augusto von Dentz static void hci_num_comp_blocks_evt(struct hci_dev *hdev, void *data,
45623e54c589SLuiz Augusto von Dentz 				    struct sk_buff *skb)
456325e89e99SAndrei Emeltchenko {
45643e54c589SLuiz Augusto von Dentz 	struct hci_ev_num_comp_blocks *ev = data;
456525e89e99SAndrei Emeltchenko 	int i;
456625e89e99SAndrei Emeltchenko 
4567ae61a10dSLuiz Augusto von Dentz 	if (!hci_ev_skb_pull(hdev, skb, HCI_EV_NUM_COMP_BLOCKS,
4568ae61a10dSLuiz Augusto von Dentz 			     flex_array_size(ev, handles, ev->num_hndl)))
4569ae61a10dSLuiz Augusto von Dentz 		return;
4570ae61a10dSLuiz Augusto von Dentz 
457125e89e99SAndrei Emeltchenko 	if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
45723e54c589SLuiz Augusto von Dentz 		bt_dev_err(hdev, "wrong event for mode %d",
45733e54c589SLuiz Augusto von Dentz 			   hdev->flow_ctl_mode);
457425e89e99SAndrei Emeltchenko 		return;
457525e89e99SAndrei Emeltchenko 	}
457625e89e99SAndrei Emeltchenko 
45773e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "num_blocks %d num_hndl %d", ev->num_blocks,
457825e89e99SAndrei Emeltchenko 		   ev->num_hndl);
457925e89e99SAndrei Emeltchenko 
458025e89e99SAndrei Emeltchenko 	for (i = 0; i < ev->num_hndl; i++) {
458125e89e99SAndrei Emeltchenko 		struct hci_comp_blocks_info *info = &ev->handles[i];
458276ef7cf7SAndrei Emeltchenko 		struct hci_conn *conn = NULL;
458325e89e99SAndrei Emeltchenko 		__u16  handle, block_count;
458425e89e99SAndrei Emeltchenko 
458525e89e99SAndrei Emeltchenko 		handle = __le16_to_cpu(info->handle);
458625e89e99SAndrei Emeltchenko 		block_count = __le16_to_cpu(info->blocks);
458725e89e99SAndrei Emeltchenko 
458876ef7cf7SAndrei Emeltchenko 		conn = __hci_conn_lookup_handle(hdev, handle);
458925e89e99SAndrei Emeltchenko 		if (!conn)
459025e89e99SAndrei Emeltchenko 			continue;
459125e89e99SAndrei Emeltchenko 
459225e89e99SAndrei Emeltchenko 		conn->sent -= block_count;
459325e89e99SAndrei Emeltchenko 
459425e89e99SAndrei Emeltchenko 		switch (conn->type) {
459525e89e99SAndrei Emeltchenko 		case ACL_LINK:
4596bd1eb66bSAndrei Emeltchenko 		case AMP_LINK:
459725e89e99SAndrei Emeltchenko 			hdev->block_cnt += block_count;
459825e89e99SAndrei Emeltchenko 			if (hdev->block_cnt > hdev->num_blocks)
459925e89e99SAndrei Emeltchenko 				hdev->block_cnt = hdev->num_blocks;
460025e89e99SAndrei Emeltchenko 			break;
460125e89e99SAndrei Emeltchenko 
460225e89e99SAndrei Emeltchenko 		default:
46032064ee33SMarcel Holtmann 			bt_dev_err(hdev, "unknown type %d conn %p",
46042064ee33SMarcel Holtmann 				   conn->type, conn);
460525e89e99SAndrei Emeltchenko 			break;
460625e89e99SAndrei Emeltchenko 		}
460725e89e99SAndrei Emeltchenko 	}
460825e89e99SAndrei Emeltchenko 
460925e89e99SAndrei Emeltchenko 	queue_work(hdev->workqueue, &hdev->tx_work);
461025e89e99SAndrei Emeltchenko }
461125e89e99SAndrei Emeltchenko 
46123e54c589SLuiz Augusto von Dentz static void hci_mode_change_evt(struct hci_dev *hdev, void *data,
46133e54c589SLuiz Augusto von Dentz 				struct sk_buff *skb)
46141da177e4SLinus Torvalds {
46153e54c589SLuiz Augusto von Dentz 	struct hci_ev_mode_change *ev = data;
461604837f64SMarcel Holtmann 	struct hci_conn *conn;
46171da177e4SLinus Torvalds 
46183e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
46191da177e4SLinus Torvalds 
46201da177e4SLinus Torvalds 	hci_dev_lock(hdev);
46211da177e4SLinus Torvalds 
462204837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
462304837f64SMarcel Holtmann 	if (conn) {
462404837f64SMarcel Holtmann 		conn->mode = ev->mode;
462504837f64SMarcel Holtmann 
46268fc9ced3SGustavo Padovan 		if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
46278fc9ced3SGustavo Padovan 					&conn->flags)) {
462804837f64SMarcel Holtmann 			if (conn->mode == HCI_CM_ACTIVE)
462958a681efSJohan Hedberg 				set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
463004837f64SMarcel Holtmann 			else
463158a681efSJohan Hedberg 				clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
463204837f64SMarcel Holtmann 		}
4633e73439d8SMarcel Holtmann 
463451a8efd7SJohan Hedberg 		if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
4635e73439d8SMarcel Holtmann 			hci_sco_setup(conn, ev->status);
463604837f64SMarcel Holtmann 	}
463704837f64SMarcel Holtmann 
463804837f64SMarcel Holtmann 	hci_dev_unlock(hdev);
463904837f64SMarcel Holtmann }
464004837f64SMarcel Holtmann 
46413e54c589SLuiz Augusto von Dentz static void hci_pin_code_request_evt(struct hci_dev *hdev, void *data,
46423e54c589SLuiz Augusto von Dentz 				     struct sk_buff *skb)
46431da177e4SLinus Torvalds {
46443e54c589SLuiz Augusto von Dentz 	struct hci_ev_pin_code_req *ev = data;
4645052b30b0SMarcel Holtmann 	struct hci_conn *conn;
4646052b30b0SMarcel Holtmann 
46473e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
4648052b30b0SMarcel Holtmann 
4649052b30b0SMarcel Holtmann 	hci_dev_lock(hdev);
4650052b30b0SMarcel Holtmann 
4651052b30b0SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
4652b6f98044SWaldemar Rymarkiewicz 	if (!conn)
4653b6f98044SWaldemar Rymarkiewicz 		goto unlock;
4654b6f98044SWaldemar Rymarkiewicz 
4655b6f98044SWaldemar Rymarkiewicz 	if (conn->state == BT_CONNECTED) {
4656052b30b0SMarcel Holtmann 		hci_conn_hold(conn);
4657052b30b0SMarcel Holtmann 		conn->disc_timeout = HCI_PAIRING_TIMEOUT;
465876a68ba0SDavid Herrmann 		hci_conn_drop(conn);
4659052b30b0SMarcel Holtmann 	}
4660052b30b0SMarcel Holtmann 
4661d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BONDABLE) &&
46622f407f0aSJohan Hedberg 	    !test_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags)) {
466303b555e1SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
466403b555e1SJohan Hedberg 			     sizeof(ev->bdaddr), &ev->bdaddr);
4665d7a5a11dSMarcel Holtmann 	} else if (hci_dev_test_flag(hdev, HCI_MGMT)) {
4666a770bb5aSWaldemar Rymarkiewicz 		u8 secure;
4667a770bb5aSWaldemar Rymarkiewicz 
4668a770bb5aSWaldemar Rymarkiewicz 		if (conn->pending_sec_level == BT_SECURITY_HIGH)
4669a770bb5aSWaldemar Rymarkiewicz 			secure = 1;
4670a770bb5aSWaldemar Rymarkiewicz 		else
4671a770bb5aSWaldemar Rymarkiewicz 			secure = 0;
4672a770bb5aSWaldemar Rymarkiewicz 
4673744cf19eSJohan Hedberg 		mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
4674a770bb5aSWaldemar Rymarkiewicz 	}
4675980e1a53SJohan Hedberg 
4676b6f98044SWaldemar Rymarkiewicz unlock:
4677052b30b0SMarcel Holtmann 	hci_dev_unlock(hdev);
46781da177e4SLinus Torvalds }
46791da177e4SLinus Torvalds 
4680cb6f3f7aSJohan Hedberg static void conn_set_key(struct hci_conn *conn, u8 key_type, u8 pin_len)
4681cb6f3f7aSJohan Hedberg {
4682cb6f3f7aSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION)
4683cb6f3f7aSJohan Hedberg 		return;
4684cb6f3f7aSJohan Hedberg 
4685cb6f3f7aSJohan Hedberg 	conn->pin_length = pin_len;
4686cb6f3f7aSJohan Hedberg 	conn->key_type = key_type;
4687cb6f3f7aSJohan Hedberg 
4688cb6f3f7aSJohan Hedberg 	switch (key_type) {
4689cb6f3f7aSJohan Hedberg 	case HCI_LK_LOCAL_UNIT:
4690cb6f3f7aSJohan Hedberg 	case HCI_LK_REMOTE_UNIT:
4691cb6f3f7aSJohan Hedberg 	case HCI_LK_DEBUG_COMBINATION:
4692cb6f3f7aSJohan Hedberg 		return;
4693cb6f3f7aSJohan Hedberg 	case HCI_LK_COMBINATION:
4694cb6f3f7aSJohan Hedberg 		if (pin_len == 16)
4695cb6f3f7aSJohan Hedberg 			conn->pending_sec_level = BT_SECURITY_HIGH;
4696cb6f3f7aSJohan Hedberg 		else
4697cb6f3f7aSJohan Hedberg 			conn->pending_sec_level = BT_SECURITY_MEDIUM;
4698cb6f3f7aSJohan Hedberg 		break;
4699cb6f3f7aSJohan Hedberg 	case HCI_LK_UNAUTH_COMBINATION_P192:
4700cb6f3f7aSJohan Hedberg 	case HCI_LK_UNAUTH_COMBINATION_P256:
4701cb6f3f7aSJohan Hedberg 		conn->pending_sec_level = BT_SECURITY_MEDIUM;
4702cb6f3f7aSJohan Hedberg 		break;
4703cb6f3f7aSJohan Hedberg 	case HCI_LK_AUTH_COMBINATION_P192:
4704cb6f3f7aSJohan Hedberg 		conn->pending_sec_level = BT_SECURITY_HIGH;
4705cb6f3f7aSJohan Hedberg 		break;
4706cb6f3f7aSJohan Hedberg 	case HCI_LK_AUTH_COMBINATION_P256:
4707cb6f3f7aSJohan Hedberg 		conn->pending_sec_level = BT_SECURITY_FIPS;
4708cb6f3f7aSJohan Hedberg 		break;
4709cb6f3f7aSJohan Hedberg 	}
4710cb6f3f7aSJohan Hedberg }
4711cb6f3f7aSJohan Hedberg 
47123e54c589SLuiz Augusto von Dentz static void hci_link_key_request_evt(struct hci_dev *hdev, void *data,
47133e54c589SLuiz Augusto von Dentz 				     struct sk_buff *skb)
47141da177e4SLinus Torvalds {
47153e54c589SLuiz Augusto von Dentz 	struct hci_ev_link_key_req *ev = data;
471655ed8ca1SJohan Hedberg 	struct hci_cp_link_key_reply cp;
471755ed8ca1SJohan Hedberg 	struct hci_conn *conn;
471855ed8ca1SJohan Hedberg 	struct link_key *key;
471955ed8ca1SJohan Hedberg 
47203e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
472155ed8ca1SJohan Hedberg 
4722d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
472355ed8ca1SJohan Hedberg 		return;
472455ed8ca1SJohan Hedberg 
472555ed8ca1SJohan Hedberg 	hci_dev_lock(hdev);
472655ed8ca1SJohan Hedberg 
472755ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, &ev->bdaddr);
472855ed8ca1SJohan Hedberg 	if (!key) {
47293e54c589SLuiz Augusto von Dentz 		bt_dev_dbg(hdev, "link key not found for %pMR", &ev->bdaddr);
473055ed8ca1SJohan Hedberg 		goto not_found;
473155ed8ca1SJohan Hedberg 	}
473255ed8ca1SJohan Hedberg 
47333e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "found key type %u for %pMR", key->type, &ev->bdaddr);
473455ed8ca1SJohan Hedberg 
473555ed8ca1SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
473660b83f57SWaldemar Rymarkiewicz 	if (conn) {
4737fe8bc5acSJohan Hedberg 		clear_bit(HCI_CONN_NEW_LINK_KEY, &conn->flags);
4738fe8bc5acSJohan Hedberg 
473966138ce8SMarcel Holtmann 		if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 ||
474066138ce8SMarcel Holtmann 		     key->type == HCI_LK_UNAUTH_COMBINATION_P256) &&
4741807deac2SGustavo Padovan 		    conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
47423e54c589SLuiz Augusto von Dentz 			bt_dev_dbg(hdev, "ignoring unauthenticated key");
474355ed8ca1SJohan Hedberg 			goto not_found;
474455ed8ca1SJohan Hedberg 		}
474555ed8ca1SJohan Hedberg 
474660b83f57SWaldemar Rymarkiewicz 		if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
4747f3fb0b58SJohan Hedberg 		    (conn->pending_sec_level == BT_SECURITY_HIGH ||
4748f3fb0b58SJohan Hedberg 		     conn->pending_sec_level == BT_SECURITY_FIPS)) {
47493e54c589SLuiz Augusto von Dentz 			bt_dev_dbg(hdev, "ignoring key unauthenticated for high security");
475060b83f57SWaldemar Rymarkiewicz 			goto not_found;
475160b83f57SWaldemar Rymarkiewicz 		}
475260b83f57SWaldemar Rymarkiewicz 
4753cb6f3f7aSJohan Hedberg 		conn_set_key(conn, key->type, key->pin_len);
475460b83f57SWaldemar Rymarkiewicz 	}
475560b83f57SWaldemar Rymarkiewicz 
475655ed8ca1SJohan Hedberg 	bacpy(&cp.bdaddr, &ev->bdaddr);
47579b3b4460SAndrei Emeltchenko 	memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
475855ed8ca1SJohan Hedberg 
475955ed8ca1SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
476055ed8ca1SJohan Hedberg 
476155ed8ca1SJohan Hedberg 	hci_dev_unlock(hdev);
476255ed8ca1SJohan Hedberg 
476355ed8ca1SJohan Hedberg 	return;
476455ed8ca1SJohan Hedberg 
476555ed8ca1SJohan Hedberg not_found:
476655ed8ca1SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
476755ed8ca1SJohan Hedberg 	hci_dev_unlock(hdev);
47681da177e4SLinus Torvalds }
47691da177e4SLinus Torvalds 
47703e54c589SLuiz Augusto von Dentz static void hci_link_key_notify_evt(struct hci_dev *hdev, void *data,
47713e54c589SLuiz Augusto von Dentz 				    struct sk_buff *skb)
47721da177e4SLinus Torvalds {
47733e54c589SLuiz Augusto von Dentz 	struct hci_ev_link_key_notify *ev = data;
4774052b30b0SMarcel Holtmann 	struct hci_conn *conn;
47757652ff6aSJohan Hedberg 	struct link_key *key;
47767652ff6aSJohan Hedberg 	bool persistent;
477755ed8ca1SJohan Hedberg 	u8 pin_len = 0;
4778052b30b0SMarcel Holtmann 
47793e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
4780052b30b0SMarcel Holtmann 
4781052b30b0SMarcel Holtmann 	hci_dev_lock(hdev);
4782052b30b0SMarcel Holtmann 
4783052b30b0SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
478482c13d42SJohan Hedberg 	if (!conn)
478582c13d42SJohan Hedberg 		goto unlock;
478682c13d42SJohan Hedberg 
478733155c4aSLee, Chun-Yi 	/* Ignore NULL link key against CVE-2020-26555 */
4788b5412606SLuiz Augusto von Dentz 	if (!crypto_memneq(ev->link_key, ZERO_KEY, HCI_LINK_KEY_SIZE)) {
478933155c4aSLee, Chun-Yi 		bt_dev_dbg(hdev, "Ignore NULL link key (ZERO KEY) for %pMR",
479033155c4aSLee, Chun-Yi 			   &ev->bdaddr);
479133155c4aSLee, Chun-Yi 		hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
479233155c4aSLee, Chun-Yi 		hci_conn_drop(conn);
479333155c4aSLee, Chun-Yi 		goto unlock;
479433155c4aSLee, Chun-Yi 	}
479533155c4aSLee, Chun-Yi 
4796052b30b0SMarcel Holtmann 	hci_conn_hold(conn);
4797052b30b0SMarcel Holtmann 	conn->disc_timeout = HCI_DISCONN_TIMEOUT;
479876a68ba0SDavid Herrmann 	hci_conn_drop(conn);
479982c13d42SJohan Hedberg 
4800fe8bc5acSJohan Hedberg 	set_bit(HCI_CONN_NEW_LINK_KEY, &conn->flags);
4801cb6f3f7aSJohan Hedberg 	conn_set_key(conn, ev->key_type, conn->pin_length);
4802052b30b0SMarcel Holtmann 
4803d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
48047652ff6aSJohan Hedberg 		goto unlock;
480555ed8ca1SJohan Hedberg 
48067652ff6aSJohan Hedberg 	key = hci_add_link_key(hdev, conn, &ev->bdaddr, ev->link_key,
48077652ff6aSJohan Hedberg 			        ev->key_type, pin_len, &persistent);
48087652ff6aSJohan Hedberg 	if (!key)
48097652ff6aSJohan Hedberg 		goto unlock;
48107652ff6aSJohan Hedberg 
4811cb6f3f7aSJohan Hedberg 	/* Update connection information since adding the key will have
4812cb6f3f7aSJohan Hedberg 	 * fixed up the type in the case of changed combination keys.
4813cb6f3f7aSJohan Hedberg 	 */
4814cb6f3f7aSJohan Hedberg 	if (ev->key_type == HCI_LK_CHANGED_COMBINATION)
4815cb6f3f7aSJohan Hedberg 		conn_set_key(conn, key->type, key->pin_len);
4816cb6f3f7aSJohan Hedberg 
48177652ff6aSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
48187652ff6aSJohan Hedberg 
48196d5650c4SJohan Hedberg 	/* Keep debug keys around only if the HCI_KEEP_DEBUG_KEYS flag
48206d5650c4SJohan Hedberg 	 * is set. If it's not set simply remove the key from the kernel
48216d5650c4SJohan Hedberg 	 * list (we've still notified user space about it but with
48226d5650c4SJohan Hedberg 	 * store_hint being 0).
48236d5650c4SJohan Hedberg 	 */
48246d5650c4SJohan Hedberg 	if (key->type == HCI_LK_DEBUG_COMBINATION &&
4825d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_KEEP_DEBUG_KEYS)) {
48260378b597SJohan Hedberg 		list_del_rcu(&key->list);
48270378b597SJohan Hedberg 		kfree_rcu(key, rcu);
482882c13d42SJohan Hedberg 		goto unlock;
482982c13d42SJohan Hedberg 	}
483082c13d42SJohan Hedberg 
4831af6a9c32SJohan Hedberg 	if (persistent)
4832af6a9c32SJohan Hedberg 		clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags);
4833af6a9c32SJohan Hedberg 	else
4834af6a9c32SJohan Hedberg 		set_bit(HCI_CONN_FLUSH_KEY, &conn->flags);
48357652ff6aSJohan Hedberg 
48367652ff6aSJohan Hedberg unlock:
4837052b30b0SMarcel Holtmann 	hci_dev_unlock(hdev);
48381da177e4SLinus Torvalds }
48391da177e4SLinus Torvalds 
48403e54c589SLuiz Augusto von Dentz static void hci_clock_offset_evt(struct hci_dev *hdev, void *data,
48413e54c589SLuiz Augusto von Dentz 				 struct sk_buff *skb)
484204837f64SMarcel Holtmann {
48433e54c589SLuiz Augusto von Dentz 	struct hci_ev_clock_offset *ev = data;
484404837f64SMarcel Holtmann 	struct hci_conn *conn;
484504837f64SMarcel Holtmann 
48463e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
484704837f64SMarcel Holtmann 
484804837f64SMarcel Holtmann 	hci_dev_lock(hdev);
484904837f64SMarcel Holtmann 
485004837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
48511da177e4SLinus Torvalds 	if (conn && !ev->status) {
48521da177e4SLinus Torvalds 		struct inquiry_entry *ie;
48531da177e4SLinus Torvalds 
4854cc11b9c1SAndrei Emeltchenko 		ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
4855cc11b9c1SAndrei Emeltchenko 		if (ie) {
48561da177e4SLinus Torvalds 			ie->data.clock_offset = ev->clock_offset;
48571da177e4SLinus Torvalds 			ie->timestamp = jiffies;
48581da177e4SLinus Torvalds 		}
48591da177e4SLinus Torvalds 	}
48601da177e4SLinus Torvalds 
48611da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
48621da177e4SLinus Torvalds }
48631da177e4SLinus Torvalds 
48643e54c589SLuiz Augusto von Dentz static void hci_pkt_type_change_evt(struct hci_dev *hdev, void *data,
48653e54c589SLuiz Augusto von Dentz 				    struct sk_buff *skb)
4866a8746417SMarcel Holtmann {
48673e54c589SLuiz Augusto von Dentz 	struct hci_ev_pkt_type_change *ev = data;
4868a8746417SMarcel Holtmann 	struct hci_conn *conn;
4869a8746417SMarcel Holtmann 
48703e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
4871a8746417SMarcel Holtmann 
4872a8746417SMarcel Holtmann 	hci_dev_lock(hdev);
4873a8746417SMarcel Holtmann 
4874a8746417SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
4875a8746417SMarcel Holtmann 	if (conn && !ev->status)
4876a8746417SMarcel Holtmann 		conn->pkt_type = __le16_to_cpu(ev->pkt_type);
4877a8746417SMarcel Holtmann 
4878a8746417SMarcel Holtmann 	hci_dev_unlock(hdev);
4879a8746417SMarcel Holtmann }
4880a8746417SMarcel Holtmann 
48813e54c589SLuiz Augusto von Dentz static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, void *data,
48823e54c589SLuiz Augusto von Dentz 				   struct sk_buff *skb)
488385a1e930SMarcel Holtmann {
48843e54c589SLuiz Augusto von Dentz 	struct hci_ev_pscan_rep_mode *ev = data;
488585a1e930SMarcel Holtmann 	struct inquiry_entry *ie;
488685a1e930SMarcel Holtmann 
48873e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
488885a1e930SMarcel Holtmann 
488985a1e930SMarcel Holtmann 	hci_dev_lock(hdev);
489085a1e930SMarcel Holtmann 
4891cc11b9c1SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
4892cc11b9c1SAndrei Emeltchenko 	if (ie) {
489385a1e930SMarcel Holtmann 		ie->data.pscan_rep_mode = ev->pscan_rep_mode;
489485a1e930SMarcel Holtmann 		ie->timestamp = jiffies;
489585a1e930SMarcel Holtmann 	}
489685a1e930SMarcel Holtmann 
489785a1e930SMarcel Holtmann 	hci_dev_unlock(hdev);
489885a1e930SMarcel Holtmann }
489985a1e930SMarcel Holtmann 
49003e54c589SLuiz Augusto von Dentz static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, void *edata,
4901807deac2SGustavo Padovan 					     struct sk_buff *skb)
4902a9de9248SMarcel Holtmann {
490372279d17SLuiz Augusto von Dentz 	struct hci_ev_inquiry_result_rssi *ev = edata;
4904a9de9248SMarcel Holtmann 	struct inquiry_data data;
49058d08d324SLuiz Augusto von Dentz 	int i;
4906a9de9248SMarcel Holtmann 
490772279d17SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "num_rsp %d", ev->num);
49088d08d324SLuiz Augusto von Dentz 
490972279d17SLuiz Augusto von Dentz 	if (!ev->num)
4910a9de9248SMarcel Holtmann 		return;
4911a9de9248SMarcel Holtmann 
4912d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ))
49131519cc17SAndre Guedes 		return;
49141519cc17SAndre Guedes 
4915a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
4916a9de9248SMarcel Holtmann 
491772279d17SLuiz Augusto von Dentz 	if (skb->len == array_size(ev->num,
491872279d17SLuiz Augusto von Dentz 				   sizeof(struct inquiry_info_rssi_pscan))) {
49198d08d324SLuiz Augusto von Dentz 		struct inquiry_info_rssi_pscan *info;
4920a9de9248SMarcel Holtmann 
492172279d17SLuiz Augusto von Dentz 		for (i = 0; i < ev->num; i++) {
4922af58925cSMarcel Holtmann 			u32 flags;
4923af58925cSMarcel Holtmann 
4924fee64503SLuiz Augusto von Dentz 			info = hci_ev_skb_pull(hdev, skb,
4925fee64503SLuiz Augusto von Dentz 					       HCI_EV_INQUIRY_RESULT_WITH_RSSI,
4926fee64503SLuiz Augusto von Dentz 					       sizeof(*info));
4927fee64503SLuiz Augusto von Dentz 			if (!info) {
4928fee64503SLuiz Augusto von Dentz 				bt_dev_err(hdev, "Malformed HCI Event: 0x%2.2x",
4929fee64503SLuiz Augusto von Dentz 					   HCI_EV_INQUIRY_RESULT_WITH_RSSI);
4930c07ba878SDan Carpenter 				goto unlock;
4931fee64503SLuiz Augusto von Dentz 			}
4932fee64503SLuiz Augusto von Dentz 
4933a9de9248SMarcel Holtmann 			bacpy(&data.bdaddr, &info->bdaddr);
4934a9de9248SMarcel Holtmann 			data.pscan_rep_mode	= info->pscan_rep_mode;
4935a9de9248SMarcel Holtmann 			data.pscan_period_mode	= info->pscan_period_mode;
4936a9de9248SMarcel Holtmann 			data.pscan_mode		= info->pscan_mode;
4937a9de9248SMarcel Holtmann 			memcpy(data.dev_class, info->dev_class, 3);
4938a9de9248SMarcel Holtmann 			data.clock_offset	= info->clock_offset;
4939a9de9248SMarcel Holtmann 			data.rssi		= info->rssi;
494041a96212SMarcel Holtmann 			data.ssp_mode		= 0x00;
49413175405bSJohan Hedberg 
4942af58925cSMarcel Holtmann 			flags = hci_inquiry_cache_update(hdev, &data, false);
4943af58925cSMarcel Holtmann 
494448264f06SJohan Hedberg 			mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
4945e17acd40SJohan Hedberg 					  info->dev_class, info->rssi,
4946b338d917SBrian Gix 					  flags, NULL, 0, NULL, 0, 0);
4947a9de9248SMarcel Holtmann 		}
494872279d17SLuiz Augusto von Dentz 	} else if (skb->len == array_size(ev->num,
494972279d17SLuiz Augusto von Dentz 					  sizeof(struct inquiry_info_rssi))) {
49508d08d324SLuiz Augusto von Dentz 		struct inquiry_info_rssi *info;
4951a9de9248SMarcel Holtmann 
495272279d17SLuiz Augusto von Dentz 		for (i = 0; i < ev->num; i++) {
4953af58925cSMarcel Holtmann 			u32 flags;
4954af58925cSMarcel Holtmann 
4955fee64503SLuiz Augusto von Dentz 			info = hci_ev_skb_pull(hdev, skb,
4956fee64503SLuiz Augusto von Dentz 					       HCI_EV_INQUIRY_RESULT_WITH_RSSI,
4957fee64503SLuiz Augusto von Dentz 					       sizeof(*info));
4958fee64503SLuiz Augusto von Dentz 			if (!info) {
4959fee64503SLuiz Augusto von Dentz 				bt_dev_err(hdev, "Malformed HCI Event: 0x%2.2x",
4960fee64503SLuiz Augusto von Dentz 					   HCI_EV_INQUIRY_RESULT_WITH_RSSI);
4961c07ba878SDan Carpenter 				goto unlock;
4962fee64503SLuiz Augusto von Dentz 			}
4963fee64503SLuiz Augusto von Dentz 
4964a9de9248SMarcel Holtmann 			bacpy(&data.bdaddr, &info->bdaddr);
4965a9de9248SMarcel Holtmann 			data.pscan_rep_mode	= info->pscan_rep_mode;
4966a9de9248SMarcel Holtmann 			data.pscan_period_mode	= info->pscan_period_mode;
4967a9de9248SMarcel Holtmann 			data.pscan_mode		= 0x00;
4968a9de9248SMarcel Holtmann 			memcpy(data.dev_class, info->dev_class, 3);
4969a9de9248SMarcel Holtmann 			data.clock_offset	= info->clock_offset;
4970a9de9248SMarcel Holtmann 			data.rssi		= info->rssi;
497141a96212SMarcel Holtmann 			data.ssp_mode		= 0x00;
4972af58925cSMarcel Holtmann 
4973af58925cSMarcel Holtmann 			flags = hci_inquiry_cache_update(hdev, &data, false);
4974af58925cSMarcel Holtmann 
497548264f06SJohan Hedberg 			mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
4976e17acd40SJohan Hedberg 					  info->dev_class, info->rssi,
4977b338d917SBrian Gix 					  flags, NULL, 0, NULL, 0, 0);
4978a9de9248SMarcel Holtmann 		}
49798d08d324SLuiz Augusto von Dentz 	} else {
49808d08d324SLuiz Augusto von Dentz 		bt_dev_err(hdev, "Malformed HCI Event: 0x%2.2x",
49818d08d324SLuiz Augusto von Dentz 			   HCI_EV_INQUIRY_RESULT_WITH_RSSI);
4982a9de9248SMarcel Holtmann 	}
4983c07ba878SDan Carpenter unlock:
4984a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
4985a9de9248SMarcel Holtmann }
4986a9de9248SMarcel Holtmann 
49873e54c589SLuiz Augusto von Dentz static void hci_remote_ext_features_evt(struct hci_dev *hdev, void *data,
4988807deac2SGustavo Padovan 					struct sk_buff *skb)
4989a9de9248SMarcel Holtmann {
49903e54c589SLuiz Augusto von Dentz 	struct hci_ev_remote_ext_features *ev = data;
499141a96212SMarcel Holtmann 	struct hci_conn *conn;
499241a96212SMarcel Holtmann 
49933e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
499441a96212SMarcel Holtmann 
499541a96212SMarcel Holtmann 	hci_dev_lock(hdev);
499641a96212SMarcel Holtmann 
499741a96212SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
4998ccd556feSJohan Hedberg 	if (!conn)
4999ccd556feSJohan Hedberg 		goto unlock;
5000ccd556feSJohan Hedberg 
5001cad718edSJohan Hedberg 	if (ev->page < HCI_MAX_PAGES)
5002cad718edSJohan Hedberg 		memcpy(conn->features[ev->page], ev->features, 8);
5003cad718edSJohan Hedberg 
5004769be974SMarcel Holtmann 	if (!ev->status && ev->page == 0x01) {
500541a96212SMarcel Holtmann 		struct inquiry_entry *ie;
500641a96212SMarcel Holtmann 
5007cc11b9c1SAndrei Emeltchenko 		ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
5008cc11b9c1SAndrei Emeltchenko 		if (ie)
500902b7cc62SJohan Hedberg 			ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
501041a96212SMarcel Holtmann 
5011bbb0eadaSJaganath Kanakkassery 		if (ev->features[0] & LMP_HOST_SSP) {
501258a681efSJohan Hedberg 			set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
5013bbb0eadaSJaganath Kanakkassery 		} else {
5014bbb0eadaSJaganath Kanakkassery 			/* It is mandatory by the Bluetooth specification that
5015bbb0eadaSJaganath Kanakkassery 			 * Extended Inquiry Results are only used when Secure
5016bbb0eadaSJaganath Kanakkassery 			 * Simple Pairing is enabled, but some devices violate
5017bbb0eadaSJaganath Kanakkassery 			 * this.
5018bbb0eadaSJaganath Kanakkassery 			 *
5019bbb0eadaSJaganath Kanakkassery 			 * To make these devices work, the internal SSP
5020bbb0eadaSJaganath Kanakkassery 			 * enabled flag needs to be cleared if the remote host
5021bbb0eadaSJaganath Kanakkassery 			 * features do not indicate SSP support */
5022bbb0eadaSJaganath Kanakkassery 			clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
5023bbb0eadaSJaganath Kanakkassery 		}
5024eb9a8f3fSMarcel Holtmann 
5025eb9a8f3fSMarcel Holtmann 		if (ev->features[0] & LMP_HOST_SC)
5026eb9a8f3fSMarcel Holtmann 			set_bit(HCI_CONN_SC_ENABLED, &conn->flags);
502741a96212SMarcel Holtmann 	}
502841a96212SMarcel Holtmann 
5029ccd556feSJohan Hedberg 	if (conn->state != BT_CONFIG)
5030ccd556feSJohan Hedberg 		goto unlock;
5031ccd556feSJohan Hedberg 
5032671267bfSJohan Hedberg 	if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
5033127178d2SJohan Hedberg 		struct hci_cp_remote_name_req cp;
5034127178d2SJohan Hedberg 		memset(&cp, 0, sizeof(cp));
5035127178d2SJohan Hedberg 		bacpy(&cp.bdaddr, &conn->dst);
5036127178d2SJohan Hedberg 		cp.pscan_rep_mode = 0x02;
5037127178d2SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
50380b3df53cSLuiz Augusto von Dentz 	} else {
50391c6ed31bSYu Liu 		mgmt_device_connected(hdev, conn, NULL, 0);
50400b3df53cSLuiz Augusto von Dentz 	}
5041392599b9SJohan Hedberg 
5042127178d2SJohan Hedberg 	if (!hci_outgoing_auth_needed(hdev, conn)) {
5043769be974SMarcel Holtmann 		conn->state = BT_CONNECTED;
5044539c496dSJohan Hedberg 		hci_connect_cfm(conn, ev->status);
504576a68ba0SDavid Herrmann 		hci_conn_drop(conn);
5046769be974SMarcel Holtmann 	}
5047769be974SMarcel Holtmann 
5048ccd556feSJohan Hedberg unlock:
504941a96212SMarcel Holtmann 	hci_dev_unlock(hdev);
5050a9de9248SMarcel Holtmann }
5051a9de9248SMarcel Holtmann 
50523e54c589SLuiz Augusto von Dentz static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data,
5053807deac2SGustavo Padovan 				       struct sk_buff *skb)
5054a9de9248SMarcel Holtmann {
50553e54c589SLuiz Augusto von Dentz 	struct hci_ev_sync_conn_complete *ev = data;
5056b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
5057c86cc5a3SLuiz Augusto von Dentz 	u8 status = ev->status;
5058b6a0dc82SMarcel Holtmann 
50593afee211SSoenke Huster 	switch (ev->link_type) {
50603afee211SSoenke Huster 	case SCO_LINK:
50613afee211SSoenke Huster 	case ESCO_LINK:
50623afee211SSoenke Huster 		break;
50633afee211SSoenke Huster 	default:
50643afee211SSoenke Huster 		/* As per Core 5.3 Vol 4 Part E 7.7.35 (p.2219), Link_Type
50653afee211SSoenke Huster 		 * for HCI_Synchronous_Connection_Complete is limited to
50663afee211SSoenke Huster 		 * either SCO or eSCO
50673afee211SSoenke Huster 		 */
50683afee211SSoenke Huster 		bt_dev_err(hdev, "Ignoring connect complete event for invalid link type");
50693afee211SSoenke Huster 		return;
50703afee211SSoenke Huster 	}
50713afee211SSoenke Huster 
5072c86cc5a3SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
5073b6a0dc82SMarcel Holtmann 
5074b6a0dc82SMarcel Holtmann 	hci_dev_lock(hdev);
5075b6a0dc82SMarcel Holtmann 
5076b6a0dc82SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
50779dc0a3afSMarcel Holtmann 	if (!conn) {
50789dc0a3afSMarcel Holtmann 		if (ev->link_type == ESCO_LINK)
50799dc0a3afSMarcel Holtmann 			goto unlock;
50809dc0a3afSMarcel Holtmann 
5081618353b1SKuba Pawlak 		/* When the link type in the event indicates SCO connection
5082618353b1SKuba Pawlak 		 * and lookup of the connection object fails, then check
5083618353b1SKuba Pawlak 		 * if an eSCO connection object exists.
5084618353b1SKuba Pawlak 		 *
5085618353b1SKuba Pawlak 		 * The core limits the synchronous connections to either
5086618353b1SKuba Pawlak 		 * SCO or eSCO. The eSCO connection is preferred and tried
5087618353b1SKuba Pawlak 		 * to be setup first and until successfully established,
5088618353b1SKuba Pawlak 		 * the link type will be hinted as eSCO.
5089618353b1SKuba Pawlak 		 */
50909dc0a3afSMarcel Holtmann 		conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
5091b6a0dc82SMarcel Holtmann 		if (!conn)
5092b6a0dc82SMarcel Holtmann 			goto unlock;
50939dc0a3afSMarcel Holtmann 	}
50949dc0a3afSMarcel Holtmann 
5095d5ebaa7cSSoenke Huster 	/* The HCI_Synchronous_Connection_Complete event is only sent once per connection.
5096d5ebaa7cSSoenke Huster 	 * Processing it more than once per connection can corrupt kernel memory.
509792fe24a7SDesmond Cheong Zhi Xi 	 *
5098d5ebaa7cSSoenke Huster 	 * As the connection handle is set here for the first time, it indicates
5099d5ebaa7cSSoenke Huster 	 * whether the connection is already set up.
510092fe24a7SDesmond Cheong Zhi Xi 	 */
51019f78191cSLuiz Augusto von Dentz 	if (!HCI_CONN_HANDLE_UNSET(conn->handle)) {
5102d5ebaa7cSSoenke Huster 		bt_dev_err(hdev, "Ignoring HCI_Sync_Conn_Complete event for existing connection");
510392fe24a7SDesmond Cheong Zhi Xi 		goto unlock;
510492fe24a7SDesmond Cheong Zhi Xi 	}
510592fe24a7SDesmond Cheong Zhi Xi 
5106c86cc5a3SLuiz Augusto von Dentz 	switch (status) {
5107d5ebaa7cSSoenke Huster 	case 0x00:
510816e3b642SLuiz Augusto von Dentz 		status = hci_conn_set_handle(conn, __le16_to_cpu(ev->handle));
510916e3b642SLuiz Augusto von Dentz 		if (status) {
5110c86cc5a3SLuiz Augusto von Dentz 			conn->state = BT_CLOSED;
5111c86cc5a3SLuiz Augusto von Dentz 			break;
5112c86cc5a3SLuiz Augusto von Dentz 		}
5113c86cc5a3SLuiz Augusto von Dentz 
5114732547f9SMarcel Holtmann 		conn->state  = BT_CONNECTED;
5115618353b1SKuba Pawlak 		conn->type   = ev->link_type;
5116732547f9SMarcel Holtmann 
511723b9ceb7SMarcel Holtmann 		hci_debugfs_create_conn(conn);
5118732547f9SMarcel Holtmann 		hci_conn_add_sysfs(conn);
5119732547f9SMarcel Holtmann 		break;
5120732547f9SMarcel Holtmann 
512181218d20SNick Pelly 	case 0x10:	/* Connection Accept Timeout */
51221a4c958cSFrédéric Dalleau 	case 0x0d:	/* Connection Rejected due to Limited Resources */
5123705e5711SStephen Coe 	case 0x11:	/* Unsupported Feature or Parameter Value */
5124732547f9SMarcel Holtmann 	case 0x1c:	/* SCO interval rejected */
51251038a00bSNick Pelly 	case 0x1a:	/* Unsupported Remote Feature */
512656b5453aSHsin-Yu Chao 	case 0x1e:	/* Invalid LMP Parameters */
5127732547f9SMarcel Holtmann 	case 0x1f:	/* Unspecified error */
512827539bc4SAndrew Earl 	case 0x20:	/* Unsupported LMP Parameter value */
51292dea632fSFrédéric Dalleau 		if (conn->out) {
5130efc7688bSMarcel Holtmann 			conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
5131efc7688bSMarcel Holtmann 					(hdev->esco_type & EDR_ESCO_MASK);
513206149746SLuiz Augusto von Dentz 			if (hci_setup_sync(conn, conn->parent->handle))
5133efc7688bSMarcel Holtmann 				goto unlock;
5134efc7688bSMarcel Holtmann 		}
513519186c7bSGustavo A. R. Silva 		fallthrough;
5136efc7688bSMarcel Holtmann 
5137732547f9SMarcel Holtmann 	default:
5138b6a0dc82SMarcel Holtmann 		conn->state = BT_CLOSED;
5139732547f9SMarcel Holtmann 		break;
5140732547f9SMarcel Holtmann 	}
5141b6a0dc82SMarcel Holtmann 
51421f8330eaSSathish Narsimman 	bt_dev_dbg(hdev, "SCO connected with air mode: %02x", ev->air_mode);
5143f4f9fa0cSChethan T N 	/* Notify only in case of SCO over HCI transport data path which
5144f4f9fa0cSChethan T N 	 * is zero and non-zero value shall be non-HCI transport data path
5145f4f9fa0cSChethan T N 	 */
5146a27c519aSJackie Liu 	if (conn->codec.data_path == 0 && hdev->notify) {
5147a27c519aSJackie Liu 		switch (ev->air_mode) {
5148a27c519aSJackie Liu 		case 0x02:
5149a27c519aSJackie Liu 			hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD);
5150a27c519aSJackie Liu 			break;
5151a27c519aSJackie Liu 		case 0x03:
5152a27c519aSJackie Liu 			hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_TRANSP);
5153a27c519aSJackie Liu 			break;
5154a27c519aSJackie Liu 		}
5155f4f9fa0cSChethan T N 	}
5156f4f9fa0cSChethan T N 
5157c86cc5a3SLuiz Augusto von Dentz 	hci_connect_cfm(conn, status);
5158c86cc5a3SLuiz Augusto von Dentz 	if (status)
5159b6a0dc82SMarcel Holtmann 		hci_conn_del(conn);
5160b6a0dc82SMarcel Holtmann 
5161b6a0dc82SMarcel Holtmann unlock:
5162b6a0dc82SMarcel Holtmann 	hci_dev_unlock(hdev);
5163a9de9248SMarcel Holtmann }
5164a9de9248SMarcel Holtmann 
5165efdcf8e3SMarcel Holtmann static inline size_t eir_get_length(u8 *eir, size_t eir_len)
5166efdcf8e3SMarcel Holtmann {
5167efdcf8e3SMarcel Holtmann 	size_t parsed = 0;
5168efdcf8e3SMarcel Holtmann 
5169efdcf8e3SMarcel Holtmann 	while (parsed < eir_len) {
5170efdcf8e3SMarcel Holtmann 		u8 field_len = eir[0];
5171efdcf8e3SMarcel Holtmann 
5172efdcf8e3SMarcel Holtmann 		if (field_len == 0)
5173efdcf8e3SMarcel Holtmann 			return parsed;
5174efdcf8e3SMarcel Holtmann 
5175efdcf8e3SMarcel Holtmann 		parsed += field_len + 1;
5176efdcf8e3SMarcel Holtmann 		eir += field_len + 1;
5177efdcf8e3SMarcel Holtmann 	}
5178efdcf8e3SMarcel Holtmann 
5179efdcf8e3SMarcel Holtmann 	return eir_len;
5180efdcf8e3SMarcel Holtmann }
5181efdcf8e3SMarcel Holtmann 
51823e54c589SLuiz Augusto von Dentz static void hci_extended_inquiry_result_evt(struct hci_dev *hdev, void *edata,
5183807deac2SGustavo Padovan 					    struct sk_buff *skb)
5184a9de9248SMarcel Holtmann {
51853e54c589SLuiz Augusto von Dentz 	struct hci_ev_ext_inquiry_result *ev = edata;
5186a9de9248SMarcel Holtmann 	struct inquiry_data data;
51879d939d94SVishal Agarwal 	size_t eir_len;
518870a6b8deSLuiz Augusto von Dentz 	int i;
5189a9de9248SMarcel Holtmann 
519070a6b8deSLuiz Augusto von Dentz 	if (!hci_ev_skb_pull(hdev, skb, HCI_EV_EXTENDED_INQUIRY_RESULT,
519170a6b8deSLuiz Augusto von Dentz 			     flex_array_size(ev, info, ev->num)))
519270a6b8deSLuiz Augusto von Dentz 		return;
519370a6b8deSLuiz Augusto von Dentz 
51943e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "num %d", ev->num);
519570a6b8deSLuiz Augusto von Dentz 
519670a6b8deSLuiz Augusto von Dentz 	if (!ev->num)
5197a9de9248SMarcel Holtmann 		return;
5198a9de9248SMarcel Holtmann 
5199d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ))
52001519cc17SAndre Guedes 		return;
52011519cc17SAndre Guedes 
5202a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
5203a9de9248SMarcel Holtmann 
520470a6b8deSLuiz Augusto von Dentz 	for (i = 0; i < ev->num; i++) {
520570a6b8deSLuiz Augusto von Dentz 		struct extended_inquiry_info *info = &ev->info[i];
5206af58925cSMarcel Holtmann 		u32 flags;
5207af58925cSMarcel Holtmann 		bool name_known;
5208561aafbcSJohan Hedberg 
5209a9de9248SMarcel Holtmann 		bacpy(&data.bdaddr, &info->bdaddr);
5210a9de9248SMarcel Holtmann 		data.pscan_rep_mode	= info->pscan_rep_mode;
5211a9de9248SMarcel Holtmann 		data.pscan_period_mode	= info->pscan_period_mode;
5212a9de9248SMarcel Holtmann 		data.pscan_mode		= 0x00;
5213a9de9248SMarcel Holtmann 		memcpy(data.dev_class, info->dev_class, 3);
5214a9de9248SMarcel Holtmann 		data.clock_offset	= info->clock_offset;
5215a9de9248SMarcel Holtmann 		data.rssi		= info->rssi;
521641a96212SMarcel Holtmann 		data.ssp_mode		= 0x01;
5217561aafbcSJohan Hedberg 
5218d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_MGMT))
52190d3b7f64SJohan Hedberg 			name_known = eir_get_data(info->data,
52204ddb1930SJohan Hedberg 						  sizeof(info->data),
52210d3b7f64SJohan Hedberg 						  EIR_NAME_COMPLETE, NULL);
5222561aafbcSJohan Hedberg 		else
5223561aafbcSJohan Hedberg 			name_known = true;
5224561aafbcSJohan Hedberg 
5225af58925cSMarcel Holtmann 		flags = hci_inquiry_cache_update(hdev, &data, name_known);
5226af58925cSMarcel Holtmann 
52279d939d94SVishal Agarwal 		eir_len = eir_get_length(info->data, sizeof(info->data));
5228af58925cSMarcel Holtmann 
522948264f06SJohan Hedberg 		mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
5230af58925cSMarcel Holtmann 				  info->dev_class, info->rssi,
5231b338d917SBrian Gix 				  flags, info->data, eir_len, NULL, 0, 0);
5232a9de9248SMarcel Holtmann 	}
5233a9de9248SMarcel Holtmann 
5234a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
5235a9de9248SMarcel Holtmann }
5236a9de9248SMarcel Holtmann 
52373e54c589SLuiz Augusto von Dentz static void hci_key_refresh_complete_evt(struct hci_dev *hdev, void *data,
52381c2e0041SJohan Hedberg 					 struct sk_buff *skb)
52391c2e0041SJohan Hedberg {
52403e54c589SLuiz Augusto von Dentz 	struct hci_ev_key_refresh_complete *ev = data;
52411c2e0041SJohan Hedberg 	struct hci_conn *conn;
52421c2e0041SJohan Hedberg 
52433e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x handle 0x%4.4x", ev->status,
52441c2e0041SJohan Hedberg 		   __le16_to_cpu(ev->handle));
52451c2e0041SJohan Hedberg 
52461c2e0041SJohan Hedberg 	hci_dev_lock(hdev);
52471c2e0041SJohan Hedberg 
52481c2e0041SJohan Hedberg 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
52491c2e0041SJohan Hedberg 	if (!conn)
52501c2e0041SJohan Hedberg 		goto unlock;
52511c2e0041SJohan Hedberg 
52529eb1fbfaSJohan Hedberg 	/* For BR/EDR the necessary steps are taken through the
52539eb1fbfaSJohan Hedberg 	 * auth_complete event.
52549eb1fbfaSJohan Hedberg 	 */
52559eb1fbfaSJohan Hedberg 	if (conn->type != LE_LINK)
52569eb1fbfaSJohan Hedberg 		goto unlock;
52579eb1fbfaSJohan Hedberg 
52581c2e0041SJohan Hedberg 	if (!ev->status)
52591c2e0041SJohan Hedberg 		conn->sec_level = conn->pending_sec_level;
52601c2e0041SJohan Hedberg 
52611c2e0041SJohan Hedberg 	clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
52621c2e0041SJohan Hedberg 
52631c2e0041SJohan Hedberg 	if (ev->status && conn->state == BT_CONNECTED) {
5264bed71748SAndre Guedes 		hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
526576a68ba0SDavid Herrmann 		hci_conn_drop(conn);
52661c2e0041SJohan Hedberg 		goto unlock;
52671c2e0041SJohan Hedberg 	}
52681c2e0041SJohan Hedberg 
52691c2e0041SJohan Hedberg 	if (conn->state == BT_CONFIG) {
52701c2e0041SJohan Hedberg 		if (!ev->status)
52711c2e0041SJohan Hedberg 			conn->state = BT_CONNECTED;
52721c2e0041SJohan Hedberg 
5273539c496dSJohan Hedberg 		hci_connect_cfm(conn, ev->status);
527476a68ba0SDavid Herrmann 		hci_conn_drop(conn);
52751c2e0041SJohan Hedberg 	} else {
52761c2e0041SJohan Hedberg 		hci_auth_cfm(conn, ev->status);
52771c2e0041SJohan Hedberg 
52781c2e0041SJohan Hedberg 		hci_conn_hold(conn);
52791c2e0041SJohan Hedberg 		conn->disc_timeout = HCI_DISCONN_TIMEOUT;
528076a68ba0SDavid Herrmann 		hci_conn_drop(conn);
52811c2e0041SJohan Hedberg 	}
52821c2e0041SJohan Hedberg 
52831c2e0041SJohan Hedberg unlock:
52841c2e0041SJohan Hedberg 	hci_dev_unlock(hdev);
52851c2e0041SJohan Hedberg }
52861c2e0041SJohan Hedberg 
52876039aa73SGustavo Padovan static u8 hci_get_auth_req(struct hci_conn *conn)
528817fa4b9dSJohan Hedberg {
528917fa4b9dSJohan Hedberg 	/* If remote requests no-bonding follow that lead */
5290acabae96SMikel Astiz 	if (conn->remote_auth == HCI_AT_NO_BONDING ||
5291acabae96SMikel Astiz 	    conn->remote_auth == HCI_AT_NO_BONDING_MITM)
529258797bf7SWaldemar Rymarkiewicz 		return conn->remote_auth | (conn->auth_type & 0x01);
529317fa4b9dSJohan Hedberg 
5294b7f94c88SMikel Astiz 	/* If both remote and local have enough IO capabilities, require
5295b7f94c88SMikel Astiz 	 * MITM protection
5296b7f94c88SMikel Astiz 	 */
5297b7f94c88SMikel Astiz 	if (conn->remote_cap != HCI_IO_NO_INPUT_OUTPUT &&
5298b7f94c88SMikel Astiz 	    conn->io_capability != HCI_IO_NO_INPUT_OUTPUT)
5299b7f94c88SMikel Astiz 		return conn->remote_auth | 0x01;
5300b7f94c88SMikel Astiz 
53017e74170aSTimo Mueller 	/* No MITM protection possible so ignore remote requirement */
53027e74170aSTimo Mueller 	return (conn->remote_auth & ~0x01) | (conn->auth_type & 0x01);
530317fa4b9dSJohan Hedberg }
530417fa4b9dSJohan Hedberg 
5305a83ed81eSMarcel Holtmann static u8 bredr_oob_data_present(struct hci_conn *conn)
5306a83ed81eSMarcel Holtmann {
5307a83ed81eSMarcel Holtmann 	struct hci_dev *hdev = conn->hdev;
5308a83ed81eSMarcel Holtmann 	struct oob_data *data;
5309a83ed81eSMarcel Holtmann 
5310a83ed81eSMarcel Holtmann 	data = hci_find_remote_oob_data(hdev, &conn->dst, BDADDR_BREDR);
5311a83ed81eSMarcel Holtmann 	if (!data)
5312a83ed81eSMarcel Holtmann 		return 0x00;
5313a83ed81eSMarcel Holtmann 
5314bf21d793SMarcel Holtmann 	if (bredr_sc_enabled(hdev)) {
5315bf21d793SMarcel Holtmann 		/* When Secure Connections is enabled, then just
5316bf21d793SMarcel Holtmann 		 * return the present value stored with the OOB
5317bf21d793SMarcel Holtmann 		 * data. The stored value contains the right present
5318bf21d793SMarcel Holtmann 		 * information. However it can only be trusted when
5319bf21d793SMarcel Holtmann 		 * not in Secure Connection Only mode.
5320aa5b0345SMarcel Holtmann 		 */
5321d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_SC_ONLY))
5322bf21d793SMarcel Holtmann 			return data->present;
5323bf21d793SMarcel Holtmann 
5324bf21d793SMarcel Holtmann 		/* When Secure Connections Only mode is enabled, then
5325bf21d793SMarcel Holtmann 		 * the P-256 values are required. If they are not
5326bf21d793SMarcel Holtmann 		 * available, then do not declare that OOB data is
5327bf21d793SMarcel Holtmann 		 * present.
5328bf21d793SMarcel Holtmann 		 */
5329b5412606SLuiz Augusto von Dentz 		if (!crypto_memneq(data->rand256, ZERO_KEY, 16) ||
5330b5412606SLuiz Augusto von Dentz 		    !crypto_memneq(data->hash256, ZERO_KEY, 16))
5331aa5b0345SMarcel Holtmann 			return 0x00;
5332aa5b0345SMarcel Holtmann 
5333bf21d793SMarcel Holtmann 		return 0x02;
5334bf21d793SMarcel Holtmann 	}
5335659c7fb0SMarcel Holtmann 
5336659c7fb0SMarcel Holtmann 	/* When Secure Connections is not enabled or actually
5337659c7fb0SMarcel Holtmann 	 * not supported by the hardware, then check that if
5338659c7fb0SMarcel Holtmann 	 * P-192 data values are present.
5339659c7fb0SMarcel Holtmann 	 */
5340b5412606SLuiz Augusto von Dentz 	if (!crypto_memneq(data->rand192, ZERO_KEY, 16) ||
5341b5412606SLuiz Augusto von Dentz 	    !crypto_memneq(data->hash192, ZERO_KEY, 16))
5342659c7fb0SMarcel Holtmann 		return 0x00;
5343659c7fb0SMarcel Holtmann 
5344a83ed81eSMarcel Holtmann 	return 0x01;
5345659c7fb0SMarcel Holtmann }
5346a83ed81eSMarcel Holtmann 
53473e54c589SLuiz Augusto von Dentz static void hci_io_capa_request_evt(struct hci_dev *hdev, void *data,
53483e54c589SLuiz Augusto von Dentz 				    struct sk_buff *skb)
53490493684eSMarcel Holtmann {
53503e54c589SLuiz Augusto von Dentz 	struct hci_ev_io_capa_request *ev = data;
53510493684eSMarcel Holtmann 	struct hci_conn *conn;
53520493684eSMarcel Holtmann 
53533e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
53540493684eSMarcel Holtmann 
53550493684eSMarcel Holtmann 	hci_dev_lock(hdev);
53560493684eSMarcel Holtmann 
53570493684eSMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
5358fba268acSLuiz Augusto von Dentz 	if (!conn || !hci_dev_test_flag(hdev, HCI_SSP_ENABLED))
535903b555e1SJohan Hedberg 		goto unlock;
536003b555e1SJohan Hedberg 
5361fba268acSLuiz Augusto von Dentz 	/* Assume remote supports SSP since it has triggered this event */
5362fba268acSLuiz Augusto von Dentz 	set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
5363fba268acSLuiz Augusto von Dentz 
53640493684eSMarcel Holtmann 	hci_conn_hold(conn);
53650493684eSMarcel Holtmann 
5366d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
536703b555e1SJohan Hedberg 		goto unlock;
536803b555e1SJohan Hedberg 
53692f407f0aSJohan Hedberg 	/* Allow pairing if we're pairable, the initiators of the
53702f407f0aSJohan Hedberg 	 * pairing or if the remote is not requesting bonding.
53712f407f0aSJohan Hedberg 	 */
5372d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_BONDABLE) ||
53732f407f0aSJohan Hedberg 	    test_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags) ||
537403b555e1SJohan Hedberg 	    (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
537517fa4b9dSJohan Hedberg 		struct hci_cp_io_capability_reply cp;
537617fa4b9dSJohan Hedberg 
537717fa4b9dSJohan Hedberg 		bacpy(&cp.bdaddr, &ev->bdaddr);
53787a7f1e7cSHemant Gupta 		/* Change the IO capability from KeyboardDisplay
53797a7f1e7cSHemant Gupta 		 * to DisplayYesNo as it is not supported by BT spec. */
53807a7f1e7cSHemant Gupta 		cp.capability = (conn->io_capability == 0x04) ?
5381a767631aSMikel Astiz 				HCI_IO_DISPLAY_YESNO : conn->io_capability;
5382b7f94c88SMikel Astiz 
5383b7f94c88SMikel Astiz 		/* If we are initiators, there is no remote information yet */
5384b7f94c88SMikel Astiz 		if (conn->remote_auth == 0xff) {
5385b16c6604SMikel Astiz 			/* Request MITM protection if our IO caps allow it
53864ad51a75SJohan Hedberg 			 * except for the no-bonding case.
5387b16c6604SMikel Astiz 			 */
53886fd6b915SMikel Astiz 			if (conn->io_capability != HCI_IO_NO_INPUT_OUTPUT &&
53899f743d74SJohan Hedberg 			    conn->auth_type != HCI_AT_NO_BONDING)
53906c53823aSJohan Hedberg 				conn->auth_type |= 0x01;
5391b7f94c88SMikel Astiz 		} else {
53927cbc9bd9SJohan Hedberg 			conn->auth_type = hci_get_auth_req(conn);
5393b7f94c88SMikel Astiz 		}
539417fa4b9dSJohan Hedberg 
539582c295b1SJohan Hedberg 		/* If we're not bondable, force one of the non-bondable
539682c295b1SJohan Hedberg 		 * authentication requirement values.
539782c295b1SJohan Hedberg 		 */
5398d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_BONDABLE))
539982c295b1SJohan Hedberg 			conn->auth_type &= HCI_AT_NO_BONDING_MITM;
540082c295b1SJohan Hedberg 
540182c295b1SJohan Hedberg 		cp.authentication = conn->auth_type;
5402a83ed81eSMarcel Holtmann 		cp.oob_data = bredr_oob_data_present(conn);
5403ce85ee13SSzymon Janc 
540417fa4b9dSJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
540517fa4b9dSJohan Hedberg 			     sizeof(cp), &cp);
540603b555e1SJohan Hedberg 	} else {
540703b555e1SJohan Hedberg 		struct hci_cp_io_capability_neg_reply cp;
540803b555e1SJohan Hedberg 
540903b555e1SJohan Hedberg 		bacpy(&cp.bdaddr, &ev->bdaddr);
54109f5a0d7bSAndrei Emeltchenko 		cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
541103b555e1SJohan Hedberg 
541203b555e1SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
541303b555e1SJohan Hedberg 			     sizeof(cp), &cp);
541403b555e1SJohan Hedberg 	}
541503b555e1SJohan Hedberg 
541603b555e1SJohan Hedberg unlock:
541703b555e1SJohan Hedberg 	hci_dev_unlock(hdev);
541803b555e1SJohan Hedberg }
541903b555e1SJohan Hedberg 
54203e54c589SLuiz Augusto von Dentz static void hci_io_capa_reply_evt(struct hci_dev *hdev, void *data,
54213e54c589SLuiz Augusto von Dentz 				  struct sk_buff *skb)
542203b555e1SJohan Hedberg {
54233e54c589SLuiz Augusto von Dentz 	struct hci_ev_io_capa_reply *ev = data;
542403b555e1SJohan Hedberg 	struct hci_conn *conn;
542503b555e1SJohan Hedberg 
54263e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
542703b555e1SJohan Hedberg 
542803b555e1SJohan Hedberg 	hci_dev_lock(hdev);
542903b555e1SJohan Hedberg 
543003b555e1SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
543103b555e1SJohan Hedberg 	if (!conn)
543203b555e1SJohan Hedberg 		goto unlock;
543303b555e1SJohan Hedberg 
543403b555e1SJohan Hedberg 	conn->remote_cap = ev->capability;
543503b555e1SJohan Hedberg 	conn->remote_auth = ev->authentication;
543603b555e1SJohan Hedberg 
543703b555e1SJohan Hedberg unlock:
54380493684eSMarcel Holtmann 	hci_dev_unlock(hdev);
54390493684eSMarcel Holtmann }
54400493684eSMarcel Holtmann 
54413e54c589SLuiz Augusto von Dentz static void hci_user_confirm_request_evt(struct hci_dev *hdev, void *data,
5442a5c29683SJohan Hedberg 					 struct sk_buff *skb)
5443a5c29683SJohan Hedberg {
54443e54c589SLuiz Augusto von Dentz 	struct hci_ev_user_confirm_req *ev = data;
544555bc1a37SJohan Hedberg 	int loc_mitm, rem_mitm, confirm_hint = 0;
54467a828908SJohan Hedberg 	struct hci_conn *conn;
5447a5c29683SJohan Hedberg 
54483e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
5449a5c29683SJohan Hedberg 
5450a5c29683SJohan Hedberg 	hci_dev_lock(hdev);
5451a5c29683SJohan Hedberg 
5452d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
54537a828908SJohan Hedberg 		goto unlock;
54547a828908SJohan Hedberg 
54557a828908SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
54567a828908SJohan Hedberg 	if (!conn)
54577a828908SJohan Hedberg 		goto unlock;
54587a828908SJohan Hedberg 
54597a828908SJohan Hedberg 	loc_mitm = (conn->auth_type & 0x01);
54607a828908SJohan Hedberg 	rem_mitm = (conn->remote_auth & 0x01);
54617a828908SJohan Hedberg 
54627a828908SJohan Hedberg 	/* If we require MITM but the remote device can't provide that
54636c53823aSJohan Hedberg 	 * (it has NoInputNoOutput) then reject the confirmation
54646c53823aSJohan Hedberg 	 * request. We check the security level here since it doesn't
54656c53823aSJohan Hedberg 	 * necessarily match conn->auth_type.
54666fd6b915SMikel Astiz 	 */
54676c53823aSJohan Hedberg 	if (conn->pending_sec_level > BT_SECURITY_MEDIUM &&
54686c53823aSJohan Hedberg 	    conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
54693e54c589SLuiz Augusto von Dentz 		bt_dev_dbg(hdev, "Rejecting request: remote device can't provide MITM");
54707a828908SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
54717a828908SJohan Hedberg 			     sizeof(ev->bdaddr), &ev->bdaddr);
54727a828908SJohan Hedberg 		goto unlock;
54737a828908SJohan Hedberg 	}
54747a828908SJohan Hedberg 
54757a828908SJohan Hedberg 	/* If no side requires MITM protection; auto-accept */
5476a767631aSMikel Astiz 	if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
5477a767631aSMikel Astiz 	    (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
547855bc1a37SJohan Hedberg 
547955bc1a37SJohan Hedberg 		/* If we're not the initiators request authorization to
548055bc1a37SJohan Hedberg 		 * proceed from user space (mgmt_user_confirm with
5481ba15a58bSJohan Hedberg 		 * confirm_hint set to 1). The exception is if neither
548202f3e254SJohan Hedberg 		 * side had MITM or if the local IO capability is
548302f3e254SJohan Hedberg 		 * NoInputNoOutput, in which case we do auto-accept
5484ba15a58bSJohan Hedberg 		 */
5485ba15a58bSJohan Hedberg 		if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) &&
548602f3e254SJohan Hedberg 		    conn->io_capability != HCI_IO_NO_INPUT_OUTPUT &&
5487ba15a58bSJohan Hedberg 		    (loc_mitm || rem_mitm)) {
54883e54c589SLuiz Augusto von Dentz 			bt_dev_dbg(hdev, "Confirming auto-accept as acceptor");
548955bc1a37SJohan Hedberg 			confirm_hint = 1;
549055bc1a37SJohan Hedberg 			goto confirm;
549155bc1a37SJohan Hedberg 		}
549255bc1a37SJohan Hedberg 
5493cee5f20fSHoward Chung 		/* If there already exists link key in local host, leave the
5494cee5f20fSHoward Chung 		 * decision to user space since the remote device could be
5495cee5f20fSHoward Chung 		 * legitimate or malicious.
5496cee5f20fSHoward Chung 		 */
5497cee5f20fSHoward Chung 		if (hci_find_link_key(hdev, &ev->bdaddr)) {
5498cee5f20fSHoward Chung 			bt_dev_dbg(hdev, "Local host already has link key");
5499cee5f20fSHoward Chung 			confirm_hint = 1;
5500cee5f20fSHoward Chung 			goto confirm;
5501cee5f20fSHoward Chung 		}
5502cee5f20fSHoward Chung 
55039f61656aSJohan Hedberg 		BT_DBG("Auto-accept of user confirmation with %ums delay",
55049f61656aSJohan Hedberg 		       hdev->auto_accept_delay);
55059f61656aSJohan Hedberg 
55069f61656aSJohan Hedberg 		if (hdev->auto_accept_delay > 0) {
55079f61656aSJohan Hedberg 			int delay = msecs_to_jiffies(hdev->auto_accept_delay);
55087bc18d9dSJohan Hedberg 			queue_delayed_work(conn->hdev->workqueue,
55097bc18d9dSJohan Hedberg 					   &conn->auto_accept_work, delay);
55109f61656aSJohan Hedberg 			goto unlock;
55119f61656aSJohan Hedberg 		}
55129f61656aSJohan Hedberg 
55137a828908SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
55147a828908SJohan Hedberg 			     sizeof(ev->bdaddr), &ev->bdaddr);
55157a828908SJohan Hedberg 		goto unlock;
55167a828908SJohan Hedberg 	}
55177a828908SJohan Hedberg 
551855bc1a37SJohan Hedberg confirm:
551939adbffeSJohan Hedberg 	mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0,
552039adbffeSJohan Hedberg 				  le32_to_cpu(ev->passkey), confirm_hint);
5521a5c29683SJohan Hedberg 
55227a828908SJohan Hedberg unlock:
5523a5c29683SJohan Hedberg 	hci_dev_unlock(hdev);
5524a5c29683SJohan Hedberg }
5525a5c29683SJohan Hedberg 
55263e54c589SLuiz Augusto von Dentz static void hci_user_passkey_request_evt(struct hci_dev *hdev, void *data,
55271143d458SBrian Gix 					 struct sk_buff *skb)
55281143d458SBrian Gix {
55293e54c589SLuiz Augusto von Dentz 	struct hci_ev_user_passkey_req *ev = data;
5530ae61a10dSLuiz Augusto von Dentz 
55313e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
55321143d458SBrian Gix 
5533d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
5534272d90dfSJohan Hedberg 		mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
55351143d458SBrian Gix }
55361143d458SBrian Gix 
55373e54c589SLuiz Augusto von Dentz static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
553892a25256SJohan Hedberg 					struct sk_buff *skb)
553992a25256SJohan Hedberg {
55403e54c589SLuiz Augusto von Dentz 	struct hci_ev_user_passkey_notify *ev = data;
554192a25256SJohan Hedberg 	struct hci_conn *conn;
554292a25256SJohan Hedberg 
55433e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
554492a25256SJohan Hedberg 
554592a25256SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
554692a25256SJohan Hedberg 	if (!conn)
554792a25256SJohan Hedberg 		return;
554892a25256SJohan Hedberg 
554992a25256SJohan Hedberg 	conn->passkey_notify = __le32_to_cpu(ev->passkey);
555092a25256SJohan Hedberg 	conn->passkey_entered = 0;
555192a25256SJohan Hedberg 
5552d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
555392a25256SJohan Hedberg 		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
555492a25256SJohan Hedberg 					 conn->dst_type, conn->passkey_notify,
555592a25256SJohan Hedberg 					 conn->passkey_entered);
555692a25256SJohan Hedberg }
555792a25256SJohan Hedberg 
55583e54c589SLuiz Augusto von Dentz static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
55593e54c589SLuiz Augusto von Dentz 				    struct sk_buff *skb)
556092a25256SJohan Hedberg {
55613e54c589SLuiz Augusto von Dentz 	struct hci_ev_keypress_notify *ev = data;
556292a25256SJohan Hedberg 	struct hci_conn *conn;
556392a25256SJohan Hedberg 
55643e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
556592a25256SJohan Hedberg 
556692a25256SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
556792a25256SJohan Hedberg 	if (!conn)
556892a25256SJohan Hedberg 		return;
556992a25256SJohan Hedberg 
557092a25256SJohan Hedberg 	switch (ev->type) {
557192a25256SJohan Hedberg 	case HCI_KEYPRESS_STARTED:
557292a25256SJohan Hedberg 		conn->passkey_entered = 0;
557392a25256SJohan Hedberg 		return;
557492a25256SJohan Hedberg 
557592a25256SJohan Hedberg 	case HCI_KEYPRESS_ENTERED:
557692a25256SJohan Hedberg 		conn->passkey_entered++;
557792a25256SJohan Hedberg 		break;
557892a25256SJohan Hedberg 
557992a25256SJohan Hedberg 	case HCI_KEYPRESS_ERASED:
558092a25256SJohan Hedberg 		conn->passkey_entered--;
558192a25256SJohan Hedberg 		break;
558292a25256SJohan Hedberg 
558392a25256SJohan Hedberg 	case HCI_KEYPRESS_CLEARED:
558492a25256SJohan Hedberg 		conn->passkey_entered = 0;
558592a25256SJohan Hedberg 		break;
558692a25256SJohan Hedberg 
558792a25256SJohan Hedberg 	case HCI_KEYPRESS_COMPLETED:
558892a25256SJohan Hedberg 		return;
558992a25256SJohan Hedberg 	}
559092a25256SJohan Hedberg 
5591d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
559292a25256SJohan Hedberg 		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
559392a25256SJohan Hedberg 					 conn->dst_type, conn->passkey_notify,
559492a25256SJohan Hedberg 					 conn->passkey_entered);
559592a25256SJohan Hedberg }
559692a25256SJohan Hedberg 
55973e54c589SLuiz Augusto von Dentz static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,
5598807deac2SGustavo Padovan 					 struct sk_buff *skb)
55990493684eSMarcel Holtmann {
56003e54c589SLuiz Augusto von Dentz 	struct hci_ev_simple_pair_complete *ev = data;
56010493684eSMarcel Holtmann 	struct hci_conn *conn;
56020493684eSMarcel Holtmann 
56033e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
56040493684eSMarcel Holtmann 
56050493684eSMarcel Holtmann 	hci_dev_lock(hdev);
56060493684eSMarcel Holtmann 
56070493684eSMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
5608c7f59461SZiyang Xuan 	if (!conn || !hci_conn_ssp_enabled(conn))
56092a611692SJohan Hedberg 		goto unlock;
56102a611692SJohan Hedberg 
5611c1d4fa7aSJohan Hedberg 	/* Reset the authentication requirement to unknown */
5612c1d4fa7aSJohan Hedberg 	conn->remote_auth = 0xff;
5613c1d4fa7aSJohan Hedberg 
56142a611692SJohan Hedberg 	/* To avoid duplicate auth_failed events to user space we check
56152a611692SJohan Hedberg 	 * the HCI_CONN_AUTH_PEND flag which will be set if we
56162a611692SJohan Hedberg 	 * initiated the authentication. A traditional auth_complete
56172a611692SJohan Hedberg 	 * event gets always produced as initiator and is also mapped to
56182a611692SJohan Hedberg 	 * the mgmt_auth_failed event */
5619fa1bd918SMikel Astiz 	if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
5620e1e930f5SJohan Hedberg 		mgmt_auth_failed(conn, ev->status);
56212a611692SJohan Hedberg 
562276a68ba0SDavid Herrmann 	hci_conn_drop(conn);
56230493684eSMarcel Holtmann 
56242a611692SJohan Hedberg unlock:
56250493684eSMarcel Holtmann 	hci_dev_unlock(hdev);
56260493684eSMarcel Holtmann }
56270493684eSMarcel Holtmann 
56283e54c589SLuiz Augusto von Dentz static void hci_remote_host_features_evt(struct hci_dev *hdev, void *data,
5629807deac2SGustavo Padovan 					 struct sk_buff *skb)
563041a96212SMarcel Holtmann {
56313e54c589SLuiz Augusto von Dentz 	struct hci_ev_remote_host_features *ev = data;
563241a96212SMarcel Holtmann 	struct inquiry_entry *ie;
5633cad718edSJohan Hedberg 	struct hci_conn *conn;
563441a96212SMarcel Holtmann 
56353e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
563641a96212SMarcel Holtmann 
563741a96212SMarcel Holtmann 	hci_dev_lock(hdev);
563841a96212SMarcel Holtmann 
5639cad718edSJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
5640cad718edSJohan Hedberg 	if (conn)
5641cad718edSJohan Hedberg 		memcpy(conn->features[1], ev->features, 8);
5642cad718edSJohan Hedberg 
5643cc11b9c1SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
5644cc11b9c1SAndrei Emeltchenko 	if (ie)
564502b7cc62SJohan Hedberg 		ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
564641a96212SMarcel Holtmann 
564741a96212SMarcel Holtmann 	hci_dev_unlock(hdev);
564841a96212SMarcel Holtmann }
564941a96212SMarcel Holtmann 
56503e54c589SLuiz Augusto von Dentz static void hci_remote_oob_data_request_evt(struct hci_dev *hdev, void *edata,
56512763eda6SSzymon Janc 					    struct sk_buff *skb)
56522763eda6SSzymon Janc {
56533e54c589SLuiz Augusto von Dentz 	struct hci_ev_remote_oob_data_request *ev = edata;
56542763eda6SSzymon Janc 	struct oob_data *data;
56552763eda6SSzymon Janc 
56563e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
56572763eda6SSzymon Janc 
56582763eda6SSzymon Janc 	hci_dev_lock(hdev);
56592763eda6SSzymon Janc 
5660d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
5661e1ba1f15SSzymon Janc 		goto unlock;
5662e1ba1f15SSzymon Janc 
56636928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, &ev->bdaddr, BDADDR_BREDR);
56646665d057SMarcel Holtmann 	if (!data) {
56656665d057SMarcel Holtmann 		struct hci_cp_remote_oob_data_neg_reply cp;
56666665d057SMarcel Holtmann 
56676665d057SMarcel Holtmann 		bacpy(&cp.bdaddr, &ev->bdaddr);
56686665d057SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY,
56696665d057SMarcel Holtmann 			     sizeof(cp), &cp);
56706665d057SMarcel Holtmann 		goto unlock;
56716665d057SMarcel Holtmann 	}
56726665d057SMarcel Holtmann 
5673710f11c0SJohan Hedberg 	if (bredr_sc_enabled(hdev)) {
5674519ca9d0SMarcel Holtmann 		struct hci_cp_remote_oob_ext_data_reply cp;
5675519ca9d0SMarcel Holtmann 
5676519ca9d0SMarcel Holtmann 		bacpy(&cp.bdaddr, &ev->bdaddr);
5677d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_SC_ONLY)) {
56786665d057SMarcel Holtmann 			memset(cp.hash192, 0, sizeof(cp.hash192));
56796665d057SMarcel Holtmann 			memset(cp.rand192, 0, sizeof(cp.rand192));
56806665d057SMarcel Holtmann 		} else {
5681519ca9d0SMarcel Holtmann 			memcpy(cp.hash192, data->hash192, sizeof(cp.hash192));
568238da1703SJohan Hedberg 			memcpy(cp.rand192, data->rand192, sizeof(cp.rand192));
56836665d057SMarcel Holtmann 		}
5684519ca9d0SMarcel Holtmann 		memcpy(cp.hash256, data->hash256, sizeof(cp.hash256));
568538da1703SJohan Hedberg 		memcpy(cp.rand256, data->rand256, sizeof(cp.rand256));
5686519ca9d0SMarcel Holtmann 
5687519ca9d0SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY,
5688519ca9d0SMarcel Holtmann 			     sizeof(cp), &cp);
5689519ca9d0SMarcel Holtmann 	} else {
56902763eda6SSzymon Janc 		struct hci_cp_remote_oob_data_reply cp;
56912763eda6SSzymon Janc 
56922763eda6SSzymon Janc 		bacpy(&cp.bdaddr, &ev->bdaddr);
5693519ca9d0SMarcel Holtmann 		memcpy(cp.hash, data->hash192, sizeof(cp.hash));
569438da1703SJohan Hedberg 		memcpy(cp.rand, data->rand192, sizeof(cp.rand));
56952763eda6SSzymon Janc 
5696519ca9d0SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY,
5697519ca9d0SMarcel Holtmann 			     sizeof(cp), &cp);
5698519ca9d0SMarcel Holtmann 	}
56992763eda6SSzymon Janc 
5700e1ba1f15SSzymon Janc unlock:
57012763eda6SSzymon Janc 	hci_dev_unlock(hdev);
57022763eda6SSzymon Janc }
57032763eda6SSzymon Janc 
5704a77a6a14SArron Wang #if IS_ENABLED(CONFIG_BT_HS)
57053e54c589SLuiz Augusto von Dentz static void hci_chan_selected_evt(struct hci_dev *hdev, void *data,
57063e54c589SLuiz Augusto von Dentz 				  struct sk_buff *skb)
5707a77a6a14SArron Wang {
57083e54c589SLuiz Augusto von Dentz 	struct hci_ev_channel_selected *ev = data;
5709a77a6a14SArron Wang 	struct hci_conn *hcon;
5710a77a6a14SArron Wang 
57113e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "handle 0x%2.2x", ev->phy_handle);
5712a77a6a14SArron Wang 
5713a77a6a14SArron Wang 	hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
5714a77a6a14SArron Wang 	if (!hcon)
5715a77a6a14SArron Wang 		return;
5716a77a6a14SArron Wang 
5717a77a6a14SArron Wang 	amp_read_loc_assoc_final_data(hdev, hcon);
5718a77a6a14SArron Wang }
5719a77a6a14SArron Wang 
57203e54c589SLuiz Augusto von Dentz static void hci_phy_link_complete_evt(struct hci_dev *hdev, void *data,
5721d5e91192SAndrei Emeltchenko 				      struct sk_buff *skb)
5722d5e91192SAndrei Emeltchenko {
57233e54c589SLuiz Augusto von Dentz 	struct hci_ev_phy_link_complete *ev = data;
5724d5e91192SAndrei Emeltchenko 	struct hci_conn *hcon, *bredr_hcon;
5725d5e91192SAndrei Emeltchenko 
57263e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "handle 0x%2.2x status 0x%2.2x", ev->phy_handle,
5727d5e91192SAndrei Emeltchenko 		   ev->status);
5728d5e91192SAndrei Emeltchenko 
5729d5e91192SAndrei Emeltchenko 	hci_dev_lock(hdev);
5730d5e91192SAndrei Emeltchenko 
5731d5e91192SAndrei Emeltchenko 	hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
57323ae1dc75SSergey Shtylyov 	if (!hcon)
57333ae1dc75SSergey Shtylyov 		goto unlock;
5734d5e91192SAndrei Emeltchenko 
57353ae1dc75SSergey Shtylyov 	if (!hcon->amp_mgr)
57363ae1dc75SSergey Shtylyov 		goto unlock;
57376dfccd13SAnmol Karn 
5738d5e91192SAndrei Emeltchenko 	if (ev->status) {
5739d5e91192SAndrei Emeltchenko 		hci_conn_del(hcon);
57403ae1dc75SSergey Shtylyov 		goto unlock;
5741d5e91192SAndrei Emeltchenko 	}
5742d5e91192SAndrei Emeltchenko 
5743d5e91192SAndrei Emeltchenko 	bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
5744d5e91192SAndrei Emeltchenko 
5745d5e91192SAndrei Emeltchenko 	hcon->state = BT_CONNECTED;
5746d5e91192SAndrei Emeltchenko 	bacpy(&hcon->dst, &bredr_hcon->dst);
5747d5e91192SAndrei Emeltchenko 
5748d5e91192SAndrei Emeltchenko 	hci_conn_hold(hcon);
5749d5e91192SAndrei Emeltchenko 	hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
575076a68ba0SDavid Herrmann 	hci_conn_drop(hcon);
5751d5e91192SAndrei Emeltchenko 
575223b9ceb7SMarcel Holtmann 	hci_debugfs_create_conn(hcon);
5753d5e91192SAndrei Emeltchenko 	hci_conn_add_sysfs(hcon);
5754d5e91192SAndrei Emeltchenko 
5755cf70ff22SAndrei Emeltchenko 	amp_physical_cfm(bredr_hcon, hcon);
5756cf70ff22SAndrei Emeltchenko 
57573ae1dc75SSergey Shtylyov unlock:
5758d5e91192SAndrei Emeltchenko 	hci_dev_unlock(hdev);
5759d5e91192SAndrei Emeltchenko }
5760d5e91192SAndrei Emeltchenko 
57613e54c589SLuiz Augusto von Dentz static void hci_loglink_complete_evt(struct hci_dev *hdev, void *data,
57623e54c589SLuiz Augusto von Dentz 				     struct sk_buff *skb)
576327695fb4SAndrei Emeltchenko {
57643e54c589SLuiz Augusto von Dentz 	struct hci_ev_logical_link_complete *ev = data;
576527695fb4SAndrei Emeltchenko 	struct hci_conn *hcon;
576627695fb4SAndrei Emeltchenko 	struct hci_chan *hchan;
576727695fb4SAndrei Emeltchenko 	struct amp_mgr *mgr;
576827695fb4SAndrei Emeltchenko 
57693e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
57703e54c589SLuiz Augusto von Dentz 		   le16_to_cpu(ev->handle), ev->phy_handle, ev->status);
577127695fb4SAndrei Emeltchenko 
577227695fb4SAndrei Emeltchenko 	hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
577327695fb4SAndrei Emeltchenko 	if (!hcon)
577427695fb4SAndrei Emeltchenko 		return;
577527695fb4SAndrei Emeltchenko 
577627695fb4SAndrei Emeltchenko 	/* Create AMP hchan */
577727695fb4SAndrei Emeltchenko 	hchan = hci_chan_create(hcon);
577827695fb4SAndrei Emeltchenko 	if (!hchan)
577927695fb4SAndrei Emeltchenko 		return;
578027695fb4SAndrei Emeltchenko 
578127695fb4SAndrei Emeltchenko 	hchan->handle = le16_to_cpu(ev->handle);
57825c4c8c95SArchie Pusaka 	hchan->amp = true;
578327695fb4SAndrei Emeltchenko 
578427695fb4SAndrei Emeltchenko 	BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
578527695fb4SAndrei Emeltchenko 
578627695fb4SAndrei Emeltchenko 	mgr = hcon->amp_mgr;
578727695fb4SAndrei Emeltchenko 	if (mgr && mgr->bredr_chan) {
578827695fb4SAndrei Emeltchenko 		struct l2cap_chan *bredr_chan = mgr->bredr_chan;
578927695fb4SAndrei Emeltchenko 
579027695fb4SAndrei Emeltchenko 		l2cap_chan_lock(bredr_chan);
579127695fb4SAndrei Emeltchenko 
579227695fb4SAndrei Emeltchenko 		bredr_chan->conn->mtu = hdev->block_mtu;
579327695fb4SAndrei Emeltchenko 		l2cap_logical_cfm(bredr_chan, hchan, 0);
579427695fb4SAndrei Emeltchenko 		hci_conn_hold(hcon);
579527695fb4SAndrei Emeltchenko 
579627695fb4SAndrei Emeltchenko 		l2cap_chan_unlock(bredr_chan);
579727695fb4SAndrei Emeltchenko 	}
579827695fb4SAndrei Emeltchenko }
579927695fb4SAndrei Emeltchenko 
58003e54c589SLuiz Augusto von Dentz static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev, void *data,
5801606e2a10SAndrei Emeltchenko 					     struct sk_buff *skb)
5802606e2a10SAndrei Emeltchenko {
58033e54c589SLuiz Augusto von Dentz 	struct hci_ev_disconn_logical_link_complete *ev = data;
5804606e2a10SAndrei Emeltchenko 	struct hci_chan *hchan;
5805606e2a10SAndrei Emeltchenko 
58063e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "handle 0x%4.4x status 0x%2.2x",
5807606e2a10SAndrei Emeltchenko 		   le16_to_cpu(ev->handle), ev->status);
5808606e2a10SAndrei Emeltchenko 
5809606e2a10SAndrei Emeltchenko 	if (ev->status)
5810606e2a10SAndrei Emeltchenko 		return;
5811606e2a10SAndrei Emeltchenko 
5812606e2a10SAndrei Emeltchenko 	hci_dev_lock(hdev);
5813606e2a10SAndrei Emeltchenko 
5814606e2a10SAndrei Emeltchenko 	hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
58155c4c8c95SArchie Pusaka 	if (!hchan || !hchan->amp)
5816606e2a10SAndrei Emeltchenko 		goto unlock;
5817606e2a10SAndrei Emeltchenko 
5818606e2a10SAndrei Emeltchenko 	amp_destroy_logical_link(hchan, ev->reason);
5819606e2a10SAndrei Emeltchenko 
5820606e2a10SAndrei Emeltchenko unlock:
5821606e2a10SAndrei Emeltchenko 	hci_dev_unlock(hdev);
5822606e2a10SAndrei Emeltchenko }
5823606e2a10SAndrei Emeltchenko 
58243e54c589SLuiz Augusto von Dentz static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev, void *data,
58259eef6b3aSAndrei Emeltchenko 					     struct sk_buff *skb)
58269eef6b3aSAndrei Emeltchenko {
58273e54c589SLuiz Augusto von Dentz 	struct hci_ev_disconn_phy_link_complete *ev = data;
58289eef6b3aSAndrei Emeltchenko 	struct hci_conn *hcon;
58299eef6b3aSAndrei Emeltchenko 
58303e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
58319eef6b3aSAndrei Emeltchenko 
58329eef6b3aSAndrei Emeltchenko 	if (ev->status)
58339eef6b3aSAndrei Emeltchenko 		return;
58349eef6b3aSAndrei Emeltchenko 
58359eef6b3aSAndrei Emeltchenko 	hci_dev_lock(hdev);
58369eef6b3aSAndrei Emeltchenko 
58379eef6b3aSAndrei Emeltchenko 	hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
5838f63d24baSLuiz Augusto von Dentz 	if (hcon && hcon->type == AMP_LINK) {
58399eef6b3aSAndrei Emeltchenko 		hcon->state = BT_CLOSED;
5840f63d24baSLuiz Augusto von Dentz 		hci_disconn_cfm(hcon, ev->reason);
58419eef6b3aSAndrei Emeltchenko 		hci_conn_del(hcon);
58429eef6b3aSAndrei Emeltchenko 	}
58439eef6b3aSAndrei Emeltchenko 
58449eef6b3aSAndrei Emeltchenko 	hci_dev_unlock(hdev);
58459eef6b3aSAndrei Emeltchenko }
5846a77a6a14SArron Wang #endif
58479eef6b3aSAndrei Emeltchenko 
5848cafae4cdSLuiz Augusto von Dentz static void le_conn_update_addr(struct hci_conn *conn, bdaddr_t *bdaddr,
5849cafae4cdSLuiz Augusto von Dentz 				u8 bdaddr_type, bdaddr_t *local_rpa)
5850cafae4cdSLuiz Augusto von Dentz {
5851cafae4cdSLuiz Augusto von Dentz 	if (conn->out) {
5852cafae4cdSLuiz Augusto von Dentz 		conn->dst_type = bdaddr_type;
5853cafae4cdSLuiz Augusto von Dentz 		conn->resp_addr_type = bdaddr_type;
5854cafae4cdSLuiz Augusto von Dentz 		bacpy(&conn->resp_addr, bdaddr);
5855cafae4cdSLuiz Augusto von Dentz 
5856cafae4cdSLuiz Augusto von Dentz 		/* Check if the controller has set a Local RPA then it must be
5857cafae4cdSLuiz Augusto von Dentz 		 * used instead or hdev->rpa.
5858cafae4cdSLuiz Augusto von Dentz 		 */
5859cafae4cdSLuiz Augusto von Dentz 		if (local_rpa && bacmp(local_rpa, BDADDR_ANY)) {
5860cafae4cdSLuiz Augusto von Dentz 			conn->init_addr_type = ADDR_LE_DEV_RANDOM;
5861cafae4cdSLuiz Augusto von Dentz 			bacpy(&conn->init_addr, local_rpa);
5862cafae4cdSLuiz Augusto von Dentz 		} else if (hci_dev_test_flag(conn->hdev, HCI_PRIVACY)) {
5863cafae4cdSLuiz Augusto von Dentz 			conn->init_addr_type = ADDR_LE_DEV_RANDOM;
5864cafae4cdSLuiz Augusto von Dentz 			bacpy(&conn->init_addr, &conn->hdev->rpa);
5865cafae4cdSLuiz Augusto von Dentz 		} else {
5866cafae4cdSLuiz Augusto von Dentz 			hci_copy_identity_address(conn->hdev, &conn->init_addr,
5867cafae4cdSLuiz Augusto von Dentz 						  &conn->init_addr_type);
5868cafae4cdSLuiz Augusto von Dentz 		}
5869cafae4cdSLuiz Augusto von Dentz 	} else {
5870cafae4cdSLuiz Augusto von Dentz 		conn->resp_addr_type = conn->hdev->adv_addr_type;
5871cafae4cdSLuiz Augusto von Dentz 		/* Check if the controller has set a Local RPA then it must be
5872cafae4cdSLuiz Augusto von Dentz 		 * used instead or hdev->rpa.
5873cafae4cdSLuiz Augusto von Dentz 		 */
5874cafae4cdSLuiz Augusto von Dentz 		if (local_rpa && bacmp(local_rpa, BDADDR_ANY)) {
5875cafae4cdSLuiz Augusto von Dentz 			conn->resp_addr_type = ADDR_LE_DEV_RANDOM;
5876cafae4cdSLuiz Augusto von Dentz 			bacpy(&conn->resp_addr, local_rpa);
5877cafae4cdSLuiz Augusto von Dentz 		} else if (conn->hdev->adv_addr_type == ADDR_LE_DEV_RANDOM) {
5878cafae4cdSLuiz Augusto von Dentz 			/* In case of ext adv, resp_addr will be updated in
5879cafae4cdSLuiz Augusto von Dentz 			 * Adv Terminated event.
5880cafae4cdSLuiz Augusto von Dentz 			 */
5881cafae4cdSLuiz Augusto von Dentz 			if (!ext_adv_capable(conn->hdev))
5882cafae4cdSLuiz Augusto von Dentz 				bacpy(&conn->resp_addr,
5883cafae4cdSLuiz Augusto von Dentz 				      &conn->hdev->random_addr);
5884cafae4cdSLuiz Augusto von Dentz 		} else {
5885cafae4cdSLuiz Augusto von Dentz 			bacpy(&conn->resp_addr, &conn->hdev->bdaddr);
5886cafae4cdSLuiz Augusto von Dentz 		}
5887cafae4cdSLuiz Augusto von Dentz 
5888cafae4cdSLuiz Augusto von Dentz 		conn->init_addr_type = bdaddr_type;
5889cafae4cdSLuiz Augusto von Dentz 		bacpy(&conn->init_addr, bdaddr);
5890cafae4cdSLuiz Augusto von Dentz 
5891cafae4cdSLuiz Augusto von Dentz 		/* For incoming connections, set the default minimum
5892cafae4cdSLuiz Augusto von Dentz 		 * and maximum connection interval. They will be used
5893cafae4cdSLuiz Augusto von Dentz 		 * to check if the parameters are in range and if not
5894cafae4cdSLuiz Augusto von Dentz 		 * trigger the connection update procedure.
5895cafae4cdSLuiz Augusto von Dentz 		 */
5896cafae4cdSLuiz Augusto von Dentz 		conn->le_conn_min_interval = conn->hdev->le_conn_min_interval;
5897cafae4cdSLuiz Augusto von Dentz 		conn->le_conn_max_interval = conn->hdev->le_conn_max_interval;
5898cafae4cdSLuiz Augusto von Dentz 	}
5899cafae4cdSLuiz Augusto von Dentz }
5900cafae4cdSLuiz Augusto von Dentz 
5901d12fb056SJaganath Kanakkassery static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
5902cafae4cdSLuiz Augusto von Dentz 				 bdaddr_t *bdaddr, u8 bdaddr_type,
5903cafae4cdSLuiz Augusto von Dentz 				 bdaddr_t *local_rpa, u8 role, u16 handle,
5904cafae4cdSLuiz Augusto von Dentz 				 u16 interval, u16 latency,
5905cafae4cdSLuiz Augusto von Dentz 				 u16 supervision_timeout)
5906fcd89c09SVille Tervo {
5907912b42efSJohan Hedberg 	struct hci_conn_params *params;
5908fcd89c09SVille Tervo 	struct hci_conn *conn;
590968d6f6deSJohan Hedberg 	struct smp_irk *irk;
5910837d502eSJohan Hedberg 	u8 addr_type;
5911fcd89c09SVille Tervo 
5912fcd89c09SVille Tervo 	hci_dev_lock(hdev);
5913fcd89c09SVille Tervo 
5914fbd96c15SJohan Hedberg 	/* All controllers implicitly stop advertising in the event of a
5915fbd96c15SJohan Hedberg 	 * connection, so ensure that the state bit is cleared.
5916fbd96c15SJohan Hedberg 	 */
5917a358dc11SMarcel Holtmann 	hci_dev_clear_flag(hdev, HCI_LE_ADV);
5918fbd96c15SJohan Hedberg 
591953562665SArchie Pusaka 	conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, bdaddr);
5920b62f328bSVille Tervo 	if (!conn) {
5921aef2aa4fSLuiz Augusto von Dentz 		/* In case of error status and there is no connection pending
5922aef2aa4fSLuiz Augusto von Dentz 		 * just unlock as there is nothing to cleanup.
5923aef2aa4fSLuiz Augusto von Dentz 		 */
5924aef2aa4fSLuiz Augusto von Dentz 		if (status)
5925aef2aa4fSLuiz Augusto von Dentz 			goto unlock;
5926aef2aa4fSLuiz Augusto von Dentz 
592784cb0143SZiyang Xuan 		conn = hci_conn_add_unset(hdev, LE_LINK, bdaddr, role);
5928b62f328bSVille Tervo 		if (!conn) {
59292064ee33SMarcel Holtmann 			bt_dev_err(hdev, "no memory for new connection");
5930230fd16aSAndre Guedes 			goto unlock;
5931b62f328bSVille Tervo 		}
593229b7988aSAndre Guedes 
5933d12fb056SJaganath Kanakkassery 		conn->dst_type = bdaddr_type;
5934b9b343d2SAndre Guedes 
5935cb1d68f7SJohan Hedberg 		/* If we didn't have a hci_conn object previously
593674be523cSArchie Pusaka 		 * but we're in central role this must be something
59373d4f9c00SArchie Pusaka 		 * initiated using an accept list. Since accept list based
5938cb1d68f7SJohan Hedberg 		 * connections are not "first class citizens" we don't
5939cb1d68f7SJohan Hedberg 		 * have full tracking of them. Therefore, we go ahead
5940cb1d68f7SJohan Hedberg 		 * with a "best effort" approach of determining the
5941cb1d68f7SJohan Hedberg 		 * initiator address based on the HCI_PRIVACY flag.
5942cb1d68f7SJohan Hedberg 		 */
5943cb1d68f7SJohan Hedberg 		if (conn->out) {
5944d12fb056SJaganath Kanakkassery 			conn->resp_addr_type = bdaddr_type;
5945d12fb056SJaganath Kanakkassery 			bacpy(&conn->resp_addr, bdaddr);
5946d7a5a11dSMarcel Holtmann 			if (hci_dev_test_flag(hdev, HCI_PRIVACY)) {
5947cb1d68f7SJohan Hedberg 				conn->init_addr_type = ADDR_LE_DEV_RANDOM;
5948cb1d68f7SJohan Hedberg 				bacpy(&conn->init_addr, &hdev->rpa);
5949cb1d68f7SJohan Hedberg 			} else {
5950cb1d68f7SJohan Hedberg 				hci_copy_identity_address(hdev,
5951cb1d68f7SJohan Hedberg 							  &conn->init_addr,
5952cb1d68f7SJohan Hedberg 							  &conn->init_addr_type);
5953cb1d68f7SJohan Hedberg 			}
595480c24ab8SJohan Hedberg 		}
5955cb1d68f7SJohan Hedberg 	} else {
595680c24ab8SJohan Hedberg 		cancel_delayed_work(&conn->le_conn_timeout);
595780c24ab8SJohan Hedberg 	}
595880c24ab8SJohan Hedberg 
5959d5ebaa7cSSoenke Huster 	/* The HCI_LE_Connection_Complete event is only sent once per connection.
5960d5ebaa7cSSoenke Huster 	 * Processing it more than once per connection can corrupt kernel memory.
5961d5ebaa7cSSoenke Huster 	 *
5962d5ebaa7cSSoenke Huster 	 * As the connection handle is set here for the first time, it indicates
5963d5ebaa7cSSoenke Huster 	 * whether the connection is already set up.
5964d5ebaa7cSSoenke Huster 	 */
59659f78191cSLuiz Augusto von Dentz 	if (!HCI_CONN_HANDLE_UNSET(conn->handle)) {
5966d5ebaa7cSSoenke Huster 		bt_dev_err(hdev, "Ignoring HCI_Connection_Complete for existing connection");
5967d5ebaa7cSSoenke Huster 		goto unlock;
5968d5ebaa7cSSoenke Huster 	}
5969d5ebaa7cSSoenke Huster 
5970cafae4cdSLuiz Augusto von Dentz 	le_conn_update_addr(conn, bdaddr, bdaddr_type, local_rpa);
59717be2edbbSJohan Hedberg 
5972edb4b466SMarcel Holtmann 	/* Lookup the identity address from the stored connection
5973edb4b466SMarcel Holtmann 	 * address and address type.
5974edb4b466SMarcel Holtmann 	 *
5975edb4b466SMarcel Holtmann 	 * When establishing connections to an identity address, the
5976edb4b466SMarcel Holtmann 	 * connection procedure will store the resolvable random
5977edb4b466SMarcel Holtmann 	 * address first. Now if it can be converted back into the
5978edb4b466SMarcel Holtmann 	 * identity address, start using the identity address from
5979edb4b466SMarcel Holtmann 	 * now on.
5980edb4b466SMarcel Holtmann 	 */
5981edb4b466SMarcel Holtmann 	irk = hci_get_irk(hdev, &conn->dst, conn->dst_type);
598268d6f6deSJohan Hedberg 	if (irk) {
598368d6f6deSJohan Hedberg 		bacpy(&conn->dst, &irk->bdaddr);
598468d6f6deSJohan Hedberg 		conn->dst_type = irk->addr_type;
598568d6f6deSJohan Hedberg 	}
598668d6f6deSJohan Hedberg 
5987d850bf08SLuiz Augusto von Dentz 	conn->dst_type = ev_bdaddr_type(hdev, conn->dst_type, NULL);
598879699a70SSathish Narasimman 
5989c9f73a21SLuiz Augusto von Dentz 	/* All connection failure handling is taken care of by the
5990c9f73a21SLuiz Augusto von Dentz 	 * hci_conn_failed function which is triggered by the HCI
5991c9f73a21SLuiz Augusto von Dentz 	 * request completion callbacks used for connecting.
5992c9f73a21SLuiz Augusto von Dentz 	 */
599384cb0143SZiyang Xuan 	if (status || hci_conn_set_handle(conn, handle))
5994837d502eSJohan Hedberg 		goto unlock;
5995837d502eSJohan Hedberg 
5996b62e7220SLuiz Augusto von Dentz 	/* Drop the connection if it has been aborted */
5997b62e7220SLuiz Augusto von Dentz 	if (test_bit(HCI_CONN_CANCEL, &conn->flags)) {
5998b62e7220SLuiz Augusto von Dentz 		hci_conn_drop(conn);
5999b62e7220SLuiz Augusto von Dentz 		goto unlock;
6000b62e7220SLuiz Augusto von Dentz 	}
6001b62e7220SLuiz Augusto von Dentz 
600208853f18SJohan Hedberg 	if (conn->dst_type == ADDR_LE_DEV_PUBLIC)
600308853f18SJohan Hedberg 		addr_type = BDADDR_LE_PUBLIC;
600408853f18SJohan Hedberg 	else
600508853f18SJohan Hedberg 		addr_type = BDADDR_LE_RANDOM;
600608853f18SJohan Hedberg 
60072d3c2260SJohan Hedberg 	/* Drop the connection if the device is blocked */
60083d4f9c00SArchie Pusaka 	if (hci_bdaddr_list_lookup(&hdev->reject_list, &conn->dst, addr_type)) {
60092d3c2260SJohan Hedberg 		hci_conn_drop(conn);
6010cd17decbSAndre Guedes 		goto unlock;
6011cd17decbSAndre Guedes 	}
6012cd17decbSAndre Guedes 
60131c6ed31bSYu Liu 	mgmt_device_connected(hdev, conn, NULL, 0);
601483bc71b4SVinicius Costa Gomes 
60157b5c0d52SVinicius Costa Gomes 	conn->sec_level = BT_SECURITY_LOW;
60160fe29fd1SMarcel Holtmann 	conn->state = BT_CONFIG;
6017fcd89c09SVille Tervo 
60187087c4f6SLuiz Augusto von Dentz 	/* Store current advertising instance as connection advertising instance
60197087c4f6SLuiz Augusto von Dentz 	 * when sotfware rotation is in use so it can be re-enabled when
60207087c4f6SLuiz Augusto von Dentz 	 * disconnected.
60217087c4f6SLuiz Augusto von Dentz 	 */
60227087c4f6SLuiz Augusto von Dentz 	if (!ext_adv_capable(hdev))
60237087c4f6SLuiz Augusto von Dentz 		conn->adv_instance = hdev->cur_adv_instance;
60247087c4f6SLuiz Augusto von Dentz 
6025d12fb056SJaganath Kanakkassery 	conn->le_conn_interval = interval;
6026d12fb056SJaganath Kanakkassery 	conn->le_conn_latency = latency;
6027d12fb056SJaganath Kanakkassery 	conn->le_supv_timeout = supervision_timeout;
6028e04fde60SMarcel Holtmann 
602923b9ceb7SMarcel Holtmann 	hci_debugfs_create_conn(conn);
6030fcd89c09SVille Tervo 	hci_conn_add_sysfs(conn);
6031fcd89c09SVille Tervo 
6032ef365da1SArchie Pusaka 	/* The remote features procedure is defined for central
60330fe29fd1SMarcel Holtmann 	 * role only. So only in case of an initiated connection
60340fe29fd1SMarcel Holtmann 	 * request the remote features.
60350fe29fd1SMarcel Holtmann 	 *
6036ef365da1SArchie Pusaka 	 * If the local controller supports peripheral-initiated features
6037ef365da1SArchie Pusaka 	 * exchange, then requesting the remote features in peripheral
60380fe29fd1SMarcel Holtmann 	 * role is possible. Otherwise just transition into the
60390fe29fd1SMarcel Holtmann 	 * connected state without requesting the remote features.
60400fe29fd1SMarcel Holtmann 	 */
60410fe29fd1SMarcel Holtmann 	if (conn->out ||
6042ef365da1SArchie Pusaka 	    (hdev->le_features[0] & HCI_LE_PERIPHERAL_FEATURES)) {
60430fe29fd1SMarcel Holtmann 		struct hci_cp_le_read_remote_features cp;
60440fe29fd1SMarcel Holtmann 
60450fe29fd1SMarcel Holtmann 		cp.handle = __cpu_to_le16(conn->handle);
60460fe29fd1SMarcel Holtmann 
60470fe29fd1SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_LE_READ_REMOTE_FEATURES,
60480fe29fd1SMarcel Holtmann 			     sizeof(cp), &cp);
60490fe29fd1SMarcel Holtmann 
60500fe29fd1SMarcel Holtmann 		hci_conn_hold(conn);
60510fe29fd1SMarcel Holtmann 	} else {
60520fe29fd1SMarcel Holtmann 		conn->state = BT_CONNECTED;
6053d12fb056SJaganath Kanakkassery 		hci_connect_cfm(conn, status);
60540fe29fd1SMarcel Holtmann 	}
6055fcd89c09SVille Tervo 
60565477610fSJohan Hedberg 	params = hci_pend_le_action_lookup(&hdev->pend_le_conns, &conn->dst,
60575477610fSJohan Hedberg 					   conn->dst_type);
6058f161dd41SJohan Hedberg 	if (params) {
6059195ef75eSPauli Virtanen 		hci_pend_le_list_del_init(params);
6060f161dd41SJohan Hedberg 		if (params->conn) {
6061f161dd41SJohan Hedberg 			hci_conn_drop(params->conn);
6062f8aaf9b6SJohan Hedberg 			hci_conn_put(params->conn);
6063f161dd41SJohan Hedberg 			params->conn = NULL;
6064f161dd41SJohan Hedberg 		}
6065f161dd41SJohan Hedberg 	}
6066a4790dbdSAndre Guedes 
6067fcd89c09SVille Tervo unlock:
60685bee2fd6SLuiz Augusto von Dentz 	hci_update_passive_scan(hdev);
6069fcd89c09SVille Tervo 	hci_dev_unlock(hdev);
6070fcd89c09SVille Tervo }
6071fcd89c09SVille Tervo 
607295118dd4SLuiz Augusto von Dentz static void hci_le_conn_complete_evt(struct hci_dev *hdev, void *data,
607395118dd4SLuiz Augusto von Dentz 				     struct sk_buff *skb)
6074d12fb056SJaganath Kanakkassery {
607595118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_conn_complete *ev = data;
607612cfe417SLuiz Augusto von Dentz 
607795118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
6078d12fb056SJaganath Kanakkassery 
6079d12fb056SJaganath Kanakkassery 	le_conn_complete_evt(hdev, ev->status, &ev->bdaddr, ev->bdaddr_type,
6080cafae4cdSLuiz Augusto von Dentz 			     NULL, ev->role, le16_to_cpu(ev->handle),
6081d12fb056SJaganath Kanakkassery 			     le16_to_cpu(ev->interval),
6082d12fb056SJaganath Kanakkassery 			     le16_to_cpu(ev->latency),
6083d12fb056SJaganath Kanakkassery 			     le16_to_cpu(ev->supervision_timeout));
6084d12fb056SJaganath Kanakkassery }
6085d12fb056SJaganath Kanakkassery 
608695118dd4SLuiz Augusto von Dentz static void hci_le_enh_conn_complete_evt(struct hci_dev *hdev, void *data,
60874d94f95dSJaganath Kanakkassery 					 struct sk_buff *skb)
60884d94f95dSJaganath Kanakkassery {
608995118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_enh_conn_complete *ev = data;
609012cfe417SLuiz Augusto von Dentz 
609195118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
60924d94f95dSJaganath Kanakkassery 
60934d94f95dSJaganath Kanakkassery 	le_conn_complete_evt(hdev, ev->status, &ev->bdaddr, ev->bdaddr_type,
6094cafae4cdSLuiz Augusto von Dentz 			     &ev->local_rpa, ev->role, le16_to_cpu(ev->handle),
60954d94f95dSJaganath Kanakkassery 			     le16_to_cpu(ev->interval),
60964d94f95dSJaganath Kanakkassery 			     le16_to_cpu(ev->latency),
60974d94f95dSJaganath Kanakkassery 			     le16_to_cpu(ev->supervision_timeout));
60984d94f95dSJaganath Kanakkassery }
60994d94f95dSJaganath Kanakkassery 
610095118dd4SLuiz Augusto von Dentz static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, void *data,
610195118dd4SLuiz Augusto von Dentz 				    struct sk_buff *skb)
6102acf0aeaeSJaganath Kanakkassery {
610395118dd4SLuiz Augusto von Dentz 	struct hci_evt_le_ext_adv_set_term *ev = data;
6104acf0aeaeSJaganath Kanakkassery 	struct hci_conn *conn;
61051f9d5657SArchie Pusaka 	struct adv_info *adv, *n;
6106acf0aeaeSJaganath Kanakkassery 
610795118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
6108acf0aeaeSJaganath Kanakkassery 
61090f281a5eSArchie Pusaka 	/* The Bluetooth Core 5.3 specification clearly states that this event
61100f281a5eSArchie Pusaka 	 * shall not be sent when the Host disables the advertising set. So in
61110f281a5eSArchie Pusaka 	 * case of HCI_ERROR_CANCELLED_BY_HOST, just ignore the event.
61120f281a5eSArchie Pusaka 	 *
61130f281a5eSArchie Pusaka 	 * When the Host disables an advertising set, all cleanup is done via
61140f281a5eSArchie Pusaka 	 * its command callback and not needed to be duplicated here.
61150f281a5eSArchie Pusaka 	 */
61160f281a5eSArchie Pusaka 	if (ev->status == HCI_ERROR_CANCELLED_BY_HOST) {
61170f281a5eSArchie Pusaka 		bt_dev_warn_ratelimited(hdev, "Unexpected advertising set terminated event");
61180f281a5eSArchie Pusaka 		return;
61190f281a5eSArchie Pusaka 	}
61200f281a5eSArchie Pusaka 
6121728abc01SNiels Dossche 	hci_dev_lock(hdev);
6122728abc01SNiels Dossche 
6123728abc01SNiels Dossche 	adv = hci_find_adv_instance(hdev, ev->handle);
6124728abc01SNiels Dossche 
61257087c4f6SLuiz Augusto von Dentz 	if (ev->status) {
612623837a6dSLuiz Augusto von Dentz 		if (!adv)
6127728abc01SNiels Dossche 			goto unlock;
6128acf0aeaeSJaganath Kanakkassery 
612923837a6dSLuiz Augusto von Dentz 		/* Remove advertising as it has been terminated */
613023837a6dSLuiz Augusto von Dentz 		hci_remove_adv_instance(hdev, ev->handle);
613123837a6dSLuiz Augusto von Dentz 		mgmt_advertising_removed(NULL, hdev, ev->handle);
613223837a6dSLuiz Augusto von Dentz 
61331f9d5657SArchie Pusaka 		list_for_each_entry_safe(adv, n, &hdev->adv_instances, list) {
61341f9d5657SArchie Pusaka 			if (adv->enabled)
6135728abc01SNiels Dossche 				goto unlock;
61361f9d5657SArchie Pusaka 		}
61371f9d5657SArchie Pusaka 
61381f9d5657SArchie Pusaka 		/* We are no longer advertising, clear HCI_LE_ADV */
61391f9d5657SArchie Pusaka 		hci_dev_clear_flag(hdev, HCI_LE_ADV);
6140728abc01SNiels Dossche 		goto unlock;
614123837a6dSLuiz Augusto von Dentz 	}
614223837a6dSLuiz Augusto von Dentz 
61437087c4f6SLuiz Augusto von Dentz 	if (adv)
61447087c4f6SLuiz Augusto von Dentz 		adv->enabled = false;
61457087c4f6SLuiz Augusto von Dentz 
6146acf0aeaeSJaganath Kanakkassery 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->conn_handle));
6147acf0aeaeSJaganath Kanakkassery 	if (conn) {
61487087c4f6SLuiz Augusto von Dentz 		/* Store handle in the connection so the correct advertising
61497087c4f6SLuiz Augusto von Dentz 		 * instance can be re-enabled when disconnected.
61507087c4f6SLuiz Augusto von Dentz 		 */
61517087c4f6SLuiz Augusto von Dentz 		conn->adv_instance = ev->handle;
6152acf0aeaeSJaganath Kanakkassery 
6153cafae4cdSLuiz Augusto von Dentz 		if (hdev->adv_addr_type != ADDR_LE_DEV_RANDOM ||
6154cafae4cdSLuiz Augusto von Dentz 		    bacmp(&conn->resp_addr, BDADDR_ANY))
6155728abc01SNiels Dossche 			goto unlock;
6156acf0aeaeSJaganath Kanakkassery 
615725e70886SDaniel Winkler 		if (!ev->handle) {
6158acf0aeaeSJaganath Kanakkassery 			bacpy(&conn->resp_addr, &hdev->random_addr);
6159728abc01SNiels Dossche 			goto unlock;
6160acf0aeaeSJaganath Kanakkassery 		}
6161acf0aeaeSJaganath Kanakkassery 
61627087c4f6SLuiz Augusto von Dentz 		if (adv)
61637087c4f6SLuiz Augusto von Dentz 			bacpy(&conn->resp_addr, &adv->random_addr);
6164acf0aeaeSJaganath Kanakkassery 	}
6165728abc01SNiels Dossche 
6166728abc01SNiels Dossche unlock:
6167728abc01SNiels Dossche 	hci_dev_unlock(hdev);
6168acf0aeaeSJaganath Kanakkassery }
6169acf0aeaeSJaganath Kanakkassery 
617095118dd4SLuiz Augusto von Dentz static void hci_le_conn_update_complete_evt(struct hci_dev *hdev, void *data,
61711855d92dSMarcel Holtmann 					    struct sk_buff *skb)
61721855d92dSMarcel Holtmann {
617395118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_conn_update_complete *ev = data;
61741855d92dSMarcel Holtmann 	struct hci_conn *conn;
61751855d92dSMarcel Holtmann 
617695118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
61771855d92dSMarcel Holtmann 
61781855d92dSMarcel Holtmann 	if (ev->status)
61791855d92dSMarcel Holtmann 		return;
61801855d92dSMarcel Holtmann 
61811855d92dSMarcel Holtmann 	hci_dev_lock(hdev);
61821855d92dSMarcel Holtmann 
61831855d92dSMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
61841855d92dSMarcel Holtmann 	if (conn) {
61851855d92dSMarcel Holtmann 		conn->le_conn_interval = le16_to_cpu(ev->interval);
61861855d92dSMarcel Holtmann 		conn->le_conn_latency = le16_to_cpu(ev->latency);
61871855d92dSMarcel Holtmann 		conn->le_supv_timeout = le16_to_cpu(ev->supervision_timeout);
61881855d92dSMarcel Holtmann 	}
61891855d92dSMarcel Holtmann 
61901855d92dSMarcel Holtmann 	hci_dev_unlock(hdev);
61911855d92dSMarcel Holtmann }
61921855d92dSMarcel Holtmann 
6193a4790dbdSAndre Guedes /* This function requires the caller holds hdev->lock */
6194fd45ada9SAlfonso Acosta static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev,
6195fd45ada9SAlfonso Acosta 					      bdaddr_t *addr,
6196d850bf08SLuiz Augusto von Dentz 					      u8 addr_type, bool addr_resolved,
61978e8b92eeSLuiz Augusto von Dentz 					      u8 adv_type)
6198a4790dbdSAndre Guedes {
6199a4790dbdSAndre Guedes 	struct hci_conn *conn;
62004b9e7e75SMarcel Holtmann 	struct hci_conn_params *params;
6201a4790dbdSAndre Guedes 
62021c1abcabSJohan Hedberg 	/* If the event is not connectable don't proceed further */
62031c1abcabSJohan Hedberg 	if (adv_type != LE_ADV_IND && adv_type != LE_ADV_DIRECT_IND)
6204fd45ada9SAlfonso Acosta 		return NULL;
62051c1abcabSJohan Hedberg 
6206182ee45dSLuiz Augusto von Dentz 	/* Ignore if the device is blocked or hdev is suspended */
6207182ee45dSLuiz Augusto von Dentz 	if (hci_bdaddr_list_lookup(&hdev->reject_list, addr, addr_type) ||
6208182ee45dSLuiz Augusto von Dentz 	    hdev->suspended)
6209fd45ada9SAlfonso Acosta 		return NULL;
62101c1abcabSJohan Hedberg 
6211f99353cfSJohan Hedberg 	/* Most controller will fail if we try to create new connections
621239bc74caSArchie Pusaka 	 * while we have an existing one in peripheral role.
6213f99353cfSJohan Hedberg 	 */
621439bc74caSArchie Pusaka 	if (hdev->conn_hash.le_num_peripheral > 0 &&
62154364f2e9SAlain Michaud 	    (!test_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks) ||
62164364f2e9SAlain Michaud 	     !(hdev->le_states[3] & 0x10)))
6217fd45ada9SAlfonso Acosta 		return NULL;
6218f99353cfSJohan Hedberg 
62191c1abcabSJohan Hedberg 	/* If we're not connectable only connect devices that we have in
62201c1abcabSJohan Hedberg 	 * our pend_le_conns list.
62211c1abcabSJohan Hedberg 	 */
622249c50922SJohan Hedberg 	params = hci_pend_le_action_lookup(&hdev->pend_le_conns, addr,
622349c50922SJohan Hedberg 					   addr_type);
62244b9e7e75SMarcel Holtmann 	if (!params)
6225fd45ada9SAlfonso Acosta 		return NULL;
6226a4790dbdSAndre Guedes 
622728a667c9SJakub Pawlowski 	if (!params->explicit_connect) {
62284b9e7e75SMarcel Holtmann 		switch (params->auto_connect) {
62294b9e7e75SMarcel Holtmann 		case HCI_AUTO_CONN_DIRECT:
62304b9e7e75SMarcel Holtmann 			/* Only devices advertising with ADV_DIRECT_IND are
62314b9e7e75SMarcel Holtmann 			 * triggering a connection attempt. This is allowing
623267ffb185SArchie Pusaka 			 * incoming connections from peripheral devices.
62334b9e7e75SMarcel Holtmann 			 */
62344b9e7e75SMarcel Holtmann 			if (adv_type != LE_ADV_DIRECT_IND)
6235fd45ada9SAlfonso Acosta 				return NULL;
62364b9e7e75SMarcel Holtmann 			break;
62374b9e7e75SMarcel Holtmann 		case HCI_AUTO_CONN_ALWAYS:
62384b9e7e75SMarcel Holtmann 			/* Devices advertising with ADV_IND or ADV_DIRECT_IND
62394b9e7e75SMarcel Holtmann 			 * are triggering a connection attempt. This means
624067ffb185SArchie Pusaka 			 * that incoming connections from peripheral device are
624167ffb185SArchie Pusaka 			 * accepted and also outgoing connections to peripheral
62424b9e7e75SMarcel Holtmann 			 * devices are established when found.
62434b9e7e75SMarcel Holtmann 			 */
62444b9e7e75SMarcel Holtmann 			break;
62454b9e7e75SMarcel Holtmann 		default:
6246fd45ada9SAlfonso Acosta 			return NULL;
62474b9e7e75SMarcel Holtmann 		}
624828a667c9SJakub Pawlowski 	}
62494b9e7e75SMarcel Holtmann 
6250d850bf08SLuiz Augusto von Dentz 	conn = hci_connect_le(hdev, addr, addr_type, addr_resolved,
6251d850bf08SLuiz Augusto von Dentz 			      BT_SECURITY_LOW, hdev->def_le_autoconnect_timeout,
62528e8b92eeSLuiz Augusto von Dentz 			      HCI_ROLE_MASTER);
6253f161dd41SJohan Hedberg 	if (!IS_ERR(conn)) {
625428a667c9SJakub Pawlowski 		/* If HCI_AUTO_CONN_EXPLICIT is set, conn is already owned
625528a667c9SJakub Pawlowski 		 * by higher layer that tried to connect, if no then
625628a667c9SJakub Pawlowski 		 * store the pointer since we don't really have any
6257f161dd41SJohan Hedberg 		 * other owner of the object besides the params that
6258f161dd41SJohan Hedberg 		 * triggered it. This way we can abort the connection if
6259f161dd41SJohan Hedberg 		 * the parameters get removed and keep the reference
6260f161dd41SJohan Hedberg 		 * count consistent once the connection is established.
6261f161dd41SJohan Hedberg 		 */
626228a667c9SJakub Pawlowski 
626328a667c9SJakub Pawlowski 		if (!params->explicit_connect)
6264f8aaf9b6SJohan Hedberg 			params->conn = hci_conn_get(conn);
626528a667c9SJakub Pawlowski 
6266fd45ada9SAlfonso Acosta 		return conn;
6267f161dd41SJohan Hedberg 	}
6268a4790dbdSAndre Guedes 
6269a4790dbdSAndre Guedes 	switch (PTR_ERR(conn)) {
6270a4790dbdSAndre Guedes 	case -EBUSY:
6271a4790dbdSAndre Guedes 		/* If hci_connect() returns -EBUSY it means there is already
6272a4790dbdSAndre Guedes 		 * an LE connection attempt going on. Since controllers don't
6273a4790dbdSAndre Guedes 		 * support more than one connection attempt at the time, we
6274a4790dbdSAndre Guedes 		 * don't consider this an error case.
6275a4790dbdSAndre Guedes 		 */
6276a4790dbdSAndre Guedes 		break;
6277a4790dbdSAndre Guedes 	default:
6278a4790dbdSAndre Guedes 		BT_DBG("Failed to connect: err %ld", PTR_ERR(conn));
6279fd45ada9SAlfonso Acosta 		return NULL;
6280a4790dbdSAndre Guedes 	}
6281fd45ada9SAlfonso Acosta 
6282fd45ada9SAlfonso Acosta 	return NULL;
6283a4790dbdSAndre Guedes }
6284a4790dbdSAndre Guedes 
62854af605d8SJohan Hedberg static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
62862f010b55SMarcel Holtmann 			       u8 bdaddr_type, bdaddr_t *direct_addr,
6287a2ec905dSAlain Michaud 			       u8 direct_addr_type, s8 rssi, u8 *data, u8 len,
6288b338d917SBrian Gix 			       bool ext_adv, bool ctl_time, u64 instant)
62894af605d8SJohan Hedberg {
6290b9a6328fSJohan Hedberg 	struct discovery_state *d = &hdev->discovery;
62911c1abcabSJohan Hedberg 	struct smp_irk *irk;
6292fd45ada9SAlfonso Acosta 	struct hci_conn *conn;
6293d850bf08SLuiz Augusto von Dentz 	bool match, bdaddr_resolved;
6294c70a7e4cSMarcel Holtmann 	u32 flags;
62951c58e933SSzymon Janc 	u8 *ptr;
62966818375eSSzymon Janc 
629756b40fbfSJohan Hedberg 	switch (type) {
629856b40fbfSJohan Hedberg 	case LE_ADV_IND:
629956b40fbfSJohan Hedberg 	case LE_ADV_DIRECT_IND:
630056b40fbfSJohan Hedberg 	case LE_ADV_SCAN_IND:
630156b40fbfSJohan Hedberg 	case LE_ADV_NONCONN_IND:
630256b40fbfSJohan Hedberg 	case LE_ADV_SCAN_RSP:
630356b40fbfSJohan Hedberg 		break;
630456b40fbfSJohan Hedberg 	default:
63052064ee33SMarcel Holtmann 		bt_dev_err_ratelimited(hdev, "unknown advertising packet "
63062064ee33SMarcel Holtmann 				       "type: 0x%02x", type);
630756b40fbfSJohan Hedberg 		return;
630856b40fbfSJohan Hedberg 	}
630956b40fbfSJohan Hedberg 
6310112b5090SLuiz Augusto von Dentz 	if (len > max_adv_len(hdev)) {
6311112b5090SLuiz Augusto von Dentz 		bt_dev_err_ratelimited(hdev,
6312112b5090SLuiz Augusto von Dentz 				       "adv larger than maximum supported");
6313a2ec905dSAlain Michaud 		return;
6314a2ec905dSAlain Michaud 	}
6315a2ec905dSAlain Michaud 
63166818375eSSzymon Janc 	/* Find the end of the data in case the report contains padded zero
63176818375eSSzymon Janc 	 * bytes at the end causing an invalid length value.
63186818375eSSzymon Janc 	 *
63196818375eSSzymon Janc 	 * When data is NULL, len is 0 so there is no need for extra ptr
63206818375eSSzymon Janc 	 * check as 'ptr < data + 0' is already false in such case.
63216818375eSSzymon Janc 	 */
63226818375eSSzymon Janc 	for (ptr = data; ptr < data + len && *ptr; ptr += *ptr + 1) {
63236818375eSSzymon Janc 		if (ptr + 1 + *ptr > data + len)
63246818375eSSzymon Janc 			break;
63256818375eSSzymon Janc 	}
63266818375eSSzymon Janc 
63271c58e933SSzymon Janc 	/* Adjust for actual length. This handles the case when remote
63281c58e933SSzymon Janc 	 * device is advertising with incorrect data length.
63291c58e933SSzymon Janc 	 */
63301c58e933SSzymon Janc 	len = ptr - data;
6331b9a6328fSJohan Hedberg 
63322f010b55SMarcel Holtmann 	/* If the direct address is present, then this report is from
63332f010b55SMarcel Holtmann 	 * a LE Direct Advertising Report event. In that case it is
63342f010b55SMarcel Holtmann 	 * important to see if the address is matching the local
63352f010b55SMarcel Holtmann 	 * controller address.
63362f010b55SMarcel Holtmann 	 */
6337b338d917SBrian Gix 	if (!hci_dev_test_flag(hdev, HCI_MESH) && direct_addr) {
6338d850bf08SLuiz Augusto von Dentz 		direct_addr_type = ev_bdaddr_type(hdev, direct_addr_type,
6339d850bf08SLuiz Augusto von Dentz 						  &bdaddr_resolved);
63404ec4d63bSLuiz Augusto von Dentz 
63412f010b55SMarcel Holtmann 		/* Only resolvable random addresses are valid for these
63422f010b55SMarcel Holtmann 		 * kind of reports and others can be ignored.
63432f010b55SMarcel Holtmann 		 */
63442f010b55SMarcel Holtmann 		if (!hci_bdaddr_is_rpa(direct_addr, direct_addr_type))
63452f010b55SMarcel Holtmann 			return;
63462f010b55SMarcel Holtmann 
63472f010b55SMarcel Holtmann 		/* If the controller is not using resolvable random
63482f010b55SMarcel Holtmann 		 * addresses, then this report can be ignored.
63492f010b55SMarcel Holtmann 		 */
6350d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_PRIVACY))
63512f010b55SMarcel Holtmann 			return;
63522f010b55SMarcel Holtmann 
63532f010b55SMarcel Holtmann 		/* If the local IRK of the controller does not match
63542f010b55SMarcel Holtmann 		 * with the resolvable random address provided, then
63552f010b55SMarcel Holtmann 		 * this report can be ignored.
63562f010b55SMarcel Holtmann 		 */
63572f010b55SMarcel Holtmann 		if (!smp_irk_matches(hdev, hdev->irk, direct_addr))
63582f010b55SMarcel Holtmann 			return;
63592f010b55SMarcel Holtmann 	}
63602f010b55SMarcel Holtmann 
6361435a13d8SJohan Hedberg 	/* Check if we need to convert to identity address */
6362435a13d8SJohan Hedberg 	irk = hci_get_irk(hdev, bdaddr, bdaddr_type);
6363435a13d8SJohan Hedberg 	if (irk) {
6364435a13d8SJohan Hedberg 		bdaddr = &irk->bdaddr;
6365435a13d8SJohan Hedberg 		bdaddr_type = irk->addr_type;
6366435a13d8SJohan Hedberg 	}
6367435a13d8SJohan Hedberg 
6368d850bf08SLuiz Augusto von Dentz 	bdaddr_type = ev_bdaddr_type(hdev, bdaddr_type, &bdaddr_resolved);
63694ec4d63bSLuiz Augusto von Dentz 
6370082f2300SSzymon Janc 	/* Check if we have been requested to connect to this device.
6371082f2300SSzymon Janc 	 *
6372082f2300SSzymon Janc 	 * direct_addr is set only for directed advertising reports (it is NULL
6373082f2300SSzymon Janc 	 * for advertising reports) and is already verified to be RPA above.
6374082f2300SSzymon Janc 	 */
6375d850bf08SLuiz Augusto von Dentz 	conn = check_pending_le_conn(hdev, bdaddr, bdaddr_type, bdaddr_resolved,
63768e8b92eeSLuiz Augusto von Dentz 				     type);
6377112b5090SLuiz Augusto von Dentz 	if (!ext_adv && conn && type == LE_ADV_IND &&
6378112b5090SLuiz Augusto von Dentz 	    len <= max_adv_len(hdev)) {
6379fd45ada9SAlfonso Acosta 		/* Store report for later inclusion by
6380fd45ada9SAlfonso Acosta 		 * mgmt_device_connected
6381fd45ada9SAlfonso Acosta 		 */
6382fd45ada9SAlfonso Acosta 		memcpy(conn->le_adv_data, data, len);
6383fd45ada9SAlfonso Acosta 		conn->le_adv_data_len = len;
6384fd45ada9SAlfonso Acosta 	}
638599a6768eSJohan Hedberg 
6386b338d917SBrian Gix 	if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND)
6387b338d917SBrian Gix 		flags = MGMT_DEV_FOUND_NOT_CONNECTABLE;
6388b338d917SBrian Gix 	else
6389b338d917SBrian Gix 		flags = 0;
6390b338d917SBrian Gix 
6391b338d917SBrian Gix 	/* All scan results should be sent up for Mesh systems */
6392b338d917SBrian Gix 	if (hci_dev_test_flag(hdev, HCI_MESH)) {
6393b338d917SBrian Gix 		mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
6394b338d917SBrian Gix 				  rssi, flags, data, len, NULL, 0, instant);
6395b338d917SBrian Gix 		return;
6396b338d917SBrian Gix 	}
6397b338d917SBrian Gix 
63981c1abcabSJohan Hedberg 	/* Passive scanning shouldn't trigger any device found events,
63991c1abcabSJohan Hedberg 	 * except for devices marked as CONN_REPORT for which we do send
64008208f5a9SMiao-chen Chou 	 * device found events, or advertisement monitoring requested.
64011c1abcabSJohan Hedberg 	 */
64021c1abcabSJohan Hedberg 	if (hdev->le_scan_type == LE_SCAN_PASSIVE) {
64030d2bf134SJohan Hedberg 		if (type == LE_ADV_DIRECT_IND)
64040d2bf134SJohan Hedberg 			return;
64050d2bf134SJohan Hedberg 
64063a19b6feSJohan Hedberg 		if (!hci_pend_le_action_lookup(&hdev->pend_le_reports,
64078208f5a9SMiao-chen Chou 					       bdaddr, bdaddr_type) &&
64088208f5a9SMiao-chen Chou 		    idr_is_empty(&hdev->adv_monitors_idr))
64090d2bf134SJohan Hedberg 			return;
64100d2bf134SJohan Hedberg 
64110d2bf134SJohan Hedberg 		mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
6412b338d917SBrian Gix 				  rssi, flags, data, len, NULL, 0, 0);
641397bf2e99SJohan Hedberg 		return;
6414ca5c4be7SJohan Hedberg 	}
64154af605d8SJohan Hedberg 
641673f55453SLuiz Augusto von Dentz 	/* When receiving a scan response, then there is no way to
6417c70a7e4cSMarcel Holtmann 	 * know if the remote device is connectable or not. However
6418c70a7e4cSMarcel Holtmann 	 * since scan responses are merged with a previously seen
6419c70a7e4cSMarcel Holtmann 	 * advertising report, the flags field from that report
6420c70a7e4cSMarcel Holtmann 	 * will be used.
6421c70a7e4cSMarcel Holtmann 	 *
642273f55453SLuiz Augusto von Dentz 	 * In the unlikely case that a controller just sends a scan
642373f55453SLuiz Augusto von Dentz 	 * response event that doesn't match the pending report, then
642473f55453SLuiz Augusto von Dentz 	 * it is marked as a standalone SCAN_RSP.
6425c70a7e4cSMarcel Holtmann 	 */
6426b338d917SBrian Gix 	if (type == LE_ADV_SCAN_RSP)
642773f55453SLuiz Augusto von Dentz 		flags = MGMT_DEV_FOUND_SCAN_RSP;
6428c70a7e4cSMarcel Holtmann 
6429b9a6328fSJohan Hedberg 	/* If there's nothing pending either store the data from this
6430b9a6328fSJohan Hedberg 	 * event or send an immediate device found event if the data
6431b9a6328fSJohan Hedberg 	 * should not be stored for later.
6432b9a6328fSJohan Hedberg 	 */
6433a2ec905dSAlain Michaud 	if (!ext_adv &&	!has_pending_adv_report(hdev)) {
6434b9a6328fSJohan Hedberg 		/* If the report will trigger a SCAN_REQ store it for
6435b9a6328fSJohan Hedberg 		 * later merging.
6436b9a6328fSJohan Hedberg 		 */
6437b9a6328fSJohan Hedberg 		if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) {
6438b9a6328fSJohan Hedberg 			store_pending_adv_report(hdev, bdaddr, bdaddr_type,
6439c70a7e4cSMarcel Holtmann 						 rssi, flags, data, len);
6440b9a6328fSJohan Hedberg 			return;
6441b9a6328fSJohan Hedberg 		}
6442b9a6328fSJohan Hedberg 
6443b9a6328fSJohan Hedberg 		mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
6444b338d917SBrian Gix 				  rssi, flags, data, len, NULL, 0, 0);
6445b9a6328fSJohan Hedberg 		return;
6446b9a6328fSJohan Hedberg 	}
6447b9a6328fSJohan Hedberg 
6448474ee066SJohan Hedberg 	/* Check if the pending report is for the same device as the new one */
6449474ee066SJohan Hedberg 	match = (!bacmp(bdaddr, &d->last_adv_addr) &&
6450474ee066SJohan Hedberg 		 bdaddr_type == d->last_adv_addr_type);
6451474ee066SJohan Hedberg 
6452b9a6328fSJohan Hedberg 	/* If the pending data doesn't match this report or this isn't a
6453b9a6328fSJohan Hedberg 	 * scan response (e.g. we got a duplicate ADV_IND) then force
6454b9a6328fSJohan Hedberg 	 * sending of the pending data.
6455b9a6328fSJohan Hedberg 	 */
6456474ee066SJohan Hedberg 	if (type != LE_ADV_SCAN_RSP || !match) {
6457474ee066SJohan Hedberg 		/* Send out whatever is in the cache, but skip duplicates */
6458474ee066SJohan Hedberg 		if (!match)
6459b9a6328fSJohan Hedberg 			mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
6460ff5cd29fSJohan Hedberg 					  d->last_adv_addr_type, NULL,
6461c70a7e4cSMarcel Holtmann 					  d->last_adv_rssi, d->last_adv_flags,
6462ff5cd29fSJohan Hedberg 					  d->last_adv_data,
6463b338d917SBrian Gix 					  d->last_adv_data_len, NULL, 0, 0);
6464b9a6328fSJohan Hedberg 
6465b9a6328fSJohan Hedberg 		/* If the new report will trigger a SCAN_REQ store it for
6466b9a6328fSJohan Hedberg 		 * later merging.
6467b9a6328fSJohan Hedberg 		 */
6468a2ec905dSAlain Michaud 		if (!ext_adv && (type == LE_ADV_IND ||
6469a2ec905dSAlain Michaud 				 type == LE_ADV_SCAN_IND)) {
6470b9a6328fSJohan Hedberg 			store_pending_adv_report(hdev, bdaddr, bdaddr_type,
6471c70a7e4cSMarcel Holtmann 						 rssi, flags, data, len);
6472b9a6328fSJohan Hedberg 			return;
6473b9a6328fSJohan Hedberg 		}
6474b9a6328fSJohan Hedberg 
6475b9a6328fSJohan Hedberg 		/* The advertising reports cannot be merged, so clear
6476b9a6328fSJohan Hedberg 		 * the pending report and send out a device found event.
6477b9a6328fSJohan Hedberg 		 */
6478b9a6328fSJohan Hedberg 		clear_pending_adv_report(hdev);
64795c5b93e4SJohan Hedberg 		mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
6480b338d917SBrian Gix 				  rssi, flags, data, len, NULL, 0, 0);
6481b9a6328fSJohan Hedberg 		return;
6482b9a6328fSJohan Hedberg 	}
6483b9a6328fSJohan Hedberg 
6484b9a6328fSJohan Hedberg 	/* If we get here we've got a pending ADV_IND or ADV_SCAN_IND and
6485b9a6328fSJohan Hedberg 	 * the new event is a SCAN_RSP. We can therefore proceed with
6486b9a6328fSJohan Hedberg 	 * sending a merged device found event.
6487b9a6328fSJohan Hedberg 	 */
6488b9a6328fSJohan Hedberg 	mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
6489c70a7e4cSMarcel Holtmann 			  d->last_adv_addr_type, NULL, rssi, d->last_adv_flags,
6490b338d917SBrian Gix 			  d->last_adv_data, d->last_adv_data_len, data, len, 0);
6491b9a6328fSJohan Hedberg 	clear_pending_adv_report(hdev);
64924af605d8SJohan Hedberg }
64934af605d8SJohan Hedberg 
649495118dd4SLuiz Augusto von Dentz static void hci_le_adv_report_evt(struct hci_dev *hdev, void *data,
649595118dd4SLuiz Augusto von Dentz 				  struct sk_buff *skb)
64969aa04c91SAndre Guedes {
649795118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_advertising_report *ev = data;
6498b338d917SBrian Gix 	u64 instant = jiffies;
649947afe93cSLuiz Augusto von Dentz 
650047afe93cSLuiz Augusto von Dentz 	if (!ev->num)
650147afe93cSLuiz Augusto von Dentz 		return;
65029aa04c91SAndre Guedes 
6503a4790dbdSAndre Guedes 	hci_dev_lock(hdev);
6504a4790dbdSAndre Guedes 
650547afe93cSLuiz Augusto von Dentz 	while (ev->num--) {
650647afe93cSLuiz Augusto von Dentz 		struct hci_ev_le_advertising_info *info;
65074af605d8SJohan Hedberg 		s8 rssi;
6508a4790dbdSAndre Guedes 
650947afe93cSLuiz Augusto von Dentz 		info = hci_le_ev_skb_pull(hdev, skb,
651047afe93cSLuiz Augusto von Dentz 					  HCI_EV_LE_ADVERTISING_REPORT,
651147afe93cSLuiz Augusto von Dentz 					  sizeof(*info));
651247afe93cSLuiz Augusto von Dentz 		if (!info)
6513899663beSBrian Gix 			break;
6514899663beSBrian Gix 
651547afe93cSLuiz Augusto von Dentz 		if (!hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_ADVERTISING_REPORT,
651647afe93cSLuiz Augusto von Dentz 					info->length + 1))
651747afe93cSLuiz Augusto von Dentz 			break;
651847afe93cSLuiz Augusto von Dentz 
6519112b5090SLuiz Augusto von Dentz 		if (info->length <= max_adv_len(hdev)) {
652047afe93cSLuiz Augusto von Dentz 			rssi = info->data[info->length];
652147afe93cSLuiz Augusto von Dentz 			process_adv_report(hdev, info->type, &info->bdaddr,
652247afe93cSLuiz Augusto von Dentz 					   info->bdaddr_type, NULL, 0, rssi,
6523b338d917SBrian Gix 					   info->data, info->length, false,
6524b338d917SBrian Gix 					   false, instant);
6525ee649346SChriz Chow 		} else {
6526ee649346SChriz Chow 			bt_dev_err(hdev, "Dropping invalid advertising data");
6527ee649346SChriz Chow 		}
65289aa04c91SAndre Guedes 	}
6529a4790dbdSAndre Guedes 
6530a4790dbdSAndre Guedes 	hci_dev_unlock(hdev);
65319aa04c91SAndre Guedes }
65329aa04c91SAndre Guedes 
6533657cc646SMarcel Holtmann static u8 ext_evt_type_to_legacy(struct hci_dev *hdev, u16 evt_type)
6534c215e939SJaganath Kanakkassery {
6535b2cc9761SJaganath Kanakkassery 	if (evt_type & LE_EXT_ADV_LEGACY_PDU) {
6536c215e939SJaganath Kanakkassery 		switch (evt_type) {
6537c215e939SJaganath Kanakkassery 		case LE_LEGACY_ADV_IND:
6538c215e939SJaganath Kanakkassery 			return LE_ADV_IND;
6539c215e939SJaganath Kanakkassery 		case LE_LEGACY_ADV_DIRECT_IND:
6540c215e939SJaganath Kanakkassery 			return LE_ADV_DIRECT_IND;
6541c215e939SJaganath Kanakkassery 		case LE_LEGACY_ADV_SCAN_IND:
6542c215e939SJaganath Kanakkassery 			return LE_ADV_SCAN_IND;
6543c215e939SJaganath Kanakkassery 		case LE_LEGACY_NONCONN_IND:
6544c215e939SJaganath Kanakkassery 			return LE_ADV_NONCONN_IND;
6545c215e939SJaganath Kanakkassery 		case LE_LEGACY_SCAN_RSP_ADV:
6546c215e939SJaganath Kanakkassery 		case LE_LEGACY_SCAN_RSP_ADV_SCAN:
6547c215e939SJaganath Kanakkassery 			return LE_ADV_SCAN_RSP;
6548c215e939SJaganath Kanakkassery 		}
6549c215e939SJaganath Kanakkassery 
6550657cc646SMarcel Holtmann 		goto invalid;
6551c215e939SJaganath Kanakkassery 	}
6552c215e939SJaganath Kanakkassery 
6553b2cc9761SJaganath Kanakkassery 	if (evt_type & LE_EXT_ADV_CONN_IND) {
6554b2cc9761SJaganath Kanakkassery 		if (evt_type & LE_EXT_ADV_DIRECT_IND)
6555b2cc9761SJaganath Kanakkassery 			return LE_ADV_DIRECT_IND;
6556b2cc9761SJaganath Kanakkassery 
6557b2cc9761SJaganath Kanakkassery 		return LE_ADV_IND;
6558b2cc9761SJaganath Kanakkassery 	}
6559b2cc9761SJaganath Kanakkassery 
6560b2cc9761SJaganath Kanakkassery 	if (evt_type & LE_EXT_ADV_SCAN_RSP)
6561b2cc9761SJaganath Kanakkassery 		return LE_ADV_SCAN_RSP;
6562b2cc9761SJaganath Kanakkassery 
6563b2cc9761SJaganath Kanakkassery 	if (evt_type & LE_EXT_ADV_SCAN_IND)
6564b2cc9761SJaganath Kanakkassery 		return LE_ADV_SCAN_IND;
6565b2cc9761SJaganath Kanakkassery 
6566b2cc9761SJaganath Kanakkassery 	if (evt_type == LE_EXT_ADV_NON_CONN_IND ||
6567b2cc9761SJaganath Kanakkassery 	    evt_type & LE_EXT_ADV_DIRECT_IND)
6568b2cc9761SJaganath Kanakkassery 		return LE_ADV_NONCONN_IND;
6569b2cc9761SJaganath Kanakkassery 
6570657cc646SMarcel Holtmann invalid:
6571657cc646SMarcel Holtmann 	bt_dev_err_ratelimited(hdev, "Unknown advertising packet type: 0x%02x",
6572b2cc9761SJaganath Kanakkassery 			       evt_type);
6573b2cc9761SJaganath Kanakkassery 
6574b2cc9761SJaganath Kanakkassery 	return LE_ADV_INVALID;
6575b2cc9761SJaganath Kanakkassery }
6576b2cc9761SJaganath Kanakkassery 
657795118dd4SLuiz Augusto von Dentz static void hci_le_ext_adv_report_evt(struct hci_dev *hdev, void *data,
657895118dd4SLuiz Augusto von Dentz 				      struct sk_buff *skb)
6579c215e939SJaganath Kanakkassery {
658095118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_ext_adv_report *ev = data;
6581b338d917SBrian Gix 	u64 instant = jiffies;
6582b48b833fSLuiz Augusto von Dentz 
6583b48b833fSLuiz Augusto von Dentz 	if (!ev->num)
6584b48b833fSLuiz Augusto von Dentz 		return;
6585c215e939SJaganath Kanakkassery 
6586c215e939SJaganath Kanakkassery 	hci_dev_lock(hdev);
6587c215e939SJaganath Kanakkassery 
6588b48b833fSLuiz Augusto von Dentz 	while (ev->num--) {
6589b48b833fSLuiz Augusto von Dentz 		struct hci_ev_le_ext_adv_info *info;
6590c215e939SJaganath Kanakkassery 		u8 legacy_evt_type;
6591c215e939SJaganath Kanakkassery 		u16 evt_type;
6592c215e939SJaganath Kanakkassery 
6593b48b833fSLuiz Augusto von Dentz 		info = hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_EXT_ADV_REPORT,
6594b48b833fSLuiz Augusto von Dentz 					  sizeof(*info));
6595b48b833fSLuiz Augusto von Dentz 		if (!info)
6596b48b833fSLuiz Augusto von Dentz 			break;
6597b48b833fSLuiz Augusto von Dentz 
6598b48b833fSLuiz Augusto von Dentz 		if (!hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_EXT_ADV_REPORT,
6599b48b833fSLuiz Augusto von Dentz 					info->length))
6600b48b833fSLuiz Augusto von Dentz 			break;
6601b48b833fSLuiz Augusto von Dentz 
6602ad38e55eSSven Peter 		evt_type = __le16_to_cpu(info->type) & LE_EXT_ADV_EVT_TYPE_MASK;
6603657cc646SMarcel Holtmann 		legacy_evt_type = ext_evt_type_to_legacy(hdev, evt_type);
6604c215e939SJaganath Kanakkassery 		if (legacy_evt_type != LE_ADV_INVALID) {
6605b48b833fSLuiz Augusto von Dentz 			process_adv_report(hdev, legacy_evt_type, &info->bdaddr,
6606b48b833fSLuiz Augusto von Dentz 					   info->bdaddr_type, NULL, 0,
6607b48b833fSLuiz Augusto von Dentz 					   info->rssi, info->data, info->length,
6608b338d917SBrian Gix 					   !(evt_type & LE_EXT_ADV_LEGACY_PDU),
6609b338d917SBrian Gix 					   false, instant);
6610c215e939SJaganath Kanakkassery 		}
6611c215e939SJaganath Kanakkassery 	}
6612c215e939SJaganath Kanakkassery 
6613c215e939SJaganath Kanakkassery 	hci_dev_unlock(hdev);
6614c215e939SJaganath Kanakkassery }
6615c215e939SJaganath Kanakkassery 
6616eca0ae4aSLuiz Augusto von Dentz static int hci_le_pa_term_sync(struct hci_dev *hdev, __le16 handle)
6617eca0ae4aSLuiz Augusto von Dentz {
6618eca0ae4aSLuiz Augusto von Dentz 	struct hci_cp_le_pa_term_sync cp;
6619eca0ae4aSLuiz Augusto von Dentz 
6620eca0ae4aSLuiz Augusto von Dentz 	memset(&cp, 0, sizeof(cp));
6621eca0ae4aSLuiz Augusto von Dentz 	cp.handle = handle;
6622eca0ae4aSLuiz Augusto von Dentz 
6623eca0ae4aSLuiz Augusto von Dentz 	return hci_send_cmd(hdev, HCI_OP_LE_PA_TERM_SYNC, sizeof(cp), &cp);
6624eca0ae4aSLuiz Augusto von Dentz }
6625eca0ae4aSLuiz Augusto von Dentz 
6626eca0ae4aSLuiz Augusto von Dentz static void hci_le_pa_sync_estabilished_evt(struct hci_dev *hdev, void *data,
6627eca0ae4aSLuiz Augusto von Dentz 					    struct sk_buff *skb)
6628eca0ae4aSLuiz Augusto von Dentz {
6629eca0ae4aSLuiz Augusto von Dentz 	struct hci_ev_le_pa_sync_established *ev = data;
6630eca0ae4aSLuiz Augusto von Dentz 	int mask = hdev->link_mode;
6631eca0ae4aSLuiz Augusto von Dentz 	__u8 flags = 0;
663223417475SIulia Tanasescu 	struct hci_conn *pa_sync;
6633eca0ae4aSLuiz Augusto von Dentz 
6634eca0ae4aSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
6635eca0ae4aSLuiz Augusto von Dentz 
6636eca0ae4aSLuiz Augusto von Dentz 	hci_dev_lock(hdev);
6637eca0ae4aSLuiz Augusto von Dentz 
6638eca0ae4aSLuiz Augusto von Dentz 	hci_dev_clear_flag(hdev, HCI_PA_SYNC);
6639eca0ae4aSLuiz Augusto von Dentz 
6640eca0ae4aSLuiz Augusto von Dentz 	mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ISO_LINK, &flags);
6641fbdc4bc4SIulia Tanasescu 	if (!(mask & HCI_LM_ACCEPT)) {
6642eca0ae4aSLuiz Augusto von Dentz 		hci_le_pa_term_sync(hdev, ev->handle);
6643fbdc4bc4SIulia Tanasescu 		goto unlock;
6644fbdc4bc4SIulia Tanasescu 	}
6645eca0ae4aSLuiz Augusto von Dentz 
6646fbdc4bc4SIulia Tanasescu 	if (!(flags & HCI_PROTO_DEFER))
6647fbdc4bc4SIulia Tanasescu 		goto unlock;
6648fbdc4bc4SIulia Tanasescu 
664923417475SIulia Tanasescu 	if (ev->status) {
665023417475SIulia Tanasescu 		/* Add connection to indicate the failed PA sync event */
665184cb0143SZiyang Xuan 		pa_sync = hci_conn_add_unset(hdev, ISO_LINK, BDADDR_ANY,
6652fbdc4bc4SIulia Tanasescu 					     HCI_ROLE_SLAVE);
6653fbdc4bc4SIulia Tanasescu 
665423417475SIulia Tanasescu 		if (!pa_sync)
6655fbdc4bc4SIulia Tanasescu 			goto unlock;
6656fbdc4bc4SIulia Tanasescu 
665723417475SIulia Tanasescu 		set_bit(HCI_CONN_PA_SYNC_FAILED, &pa_sync->flags);
6658fbdc4bc4SIulia Tanasescu 
665923417475SIulia Tanasescu 		/* Notify iso layer */
666023417475SIulia Tanasescu 		hci_connect_cfm(pa_sync, ev->status);
666123417475SIulia Tanasescu 	}
6662fbdc4bc4SIulia Tanasescu 
6663fbdc4bc4SIulia Tanasescu unlock:
6664eca0ae4aSLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
6665eca0ae4aSLuiz Augusto von Dentz }
6666eca0ae4aSLuiz Augusto von Dentz 
66679c082631SClaudia Draghicescu static void hci_le_per_adv_report_evt(struct hci_dev *hdev, void *data,
66689c082631SClaudia Draghicescu 				      struct sk_buff *skb)
66699c082631SClaudia Draghicescu {
66709c082631SClaudia Draghicescu 	struct hci_ev_le_per_adv_report *ev = data;
66719c082631SClaudia Draghicescu 	int mask = hdev->link_mode;
66729c082631SClaudia Draghicescu 	__u8 flags = 0;
66739c082631SClaudia Draghicescu 
66749c082631SClaudia Draghicescu 	bt_dev_dbg(hdev, "sync_handle 0x%4.4x", le16_to_cpu(ev->sync_handle));
66759c082631SClaudia Draghicescu 
66769c082631SClaudia Draghicescu 	hci_dev_lock(hdev);
66779c082631SClaudia Draghicescu 
66789c082631SClaudia Draghicescu 	mask |= hci_proto_connect_ind(hdev, BDADDR_ANY, ISO_LINK, &flags);
66799c082631SClaudia Draghicescu 	if (!(mask & HCI_LM_ACCEPT))
66809c082631SClaudia Draghicescu 		hci_le_pa_term_sync(hdev, ev->sync_handle);
66819c082631SClaudia Draghicescu 
66829c082631SClaudia Draghicescu 	hci_dev_unlock(hdev);
66839c082631SClaudia Draghicescu }
66849c082631SClaudia Draghicescu 
668595118dd4SLuiz Augusto von Dentz static void hci_le_remote_feat_complete_evt(struct hci_dev *hdev, void *data,
66860fe29fd1SMarcel Holtmann 					    struct sk_buff *skb)
66870fe29fd1SMarcel Holtmann {
668895118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_remote_feat_complete *ev = data;
66890fe29fd1SMarcel Holtmann 	struct hci_conn *conn;
66900fe29fd1SMarcel Holtmann 
669195118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
66920fe29fd1SMarcel Holtmann 
66930fe29fd1SMarcel Holtmann 	hci_dev_lock(hdev);
66940fe29fd1SMarcel Holtmann 
66950fe29fd1SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
66960fe29fd1SMarcel Holtmann 	if (conn) {
66970fe29fd1SMarcel Holtmann 		if (!ev->status)
66980fe29fd1SMarcel Holtmann 			memcpy(conn->features[0], ev->features, 8);
66990fe29fd1SMarcel Holtmann 
67000fe29fd1SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
67010fe29fd1SMarcel Holtmann 			__u8 status;
67020fe29fd1SMarcel Holtmann 
6703ef365da1SArchie Pusaka 			/* If the local controller supports peripheral-initiated
67040fe29fd1SMarcel Holtmann 			 * features exchange, but the remote controller does
67050fe29fd1SMarcel Holtmann 			 * not, then it is possible that the error code 0x1a
67060fe29fd1SMarcel Holtmann 			 * for unsupported remote feature gets returned.
67070fe29fd1SMarcel Holtmann 			 *
67080fe29fd1SMarcel Holtmann 			 * In this specific case, allow the connection to
67090fe29fd1SMarcel Holtmann 			 * transition into connected state and mark it as
67100fe29fd1SMarcel Holtmann 			 * successful.
67110fe29fd1SMarcel Holtmann 			 */
6712ef365da1SArchie Pusaka 			if (!conn->out && ev->status == 0x1a &&
6713ef365da1SArchie Pusaka 			    (hdev->le_features[0] & HCI_LE_PERIPHERAL_FEATURES))
67140fe29fd1SMarcel Holtmann 				status = 0x00;
67150fe29fd1SMarcel Holtmann 			else
67160fe29fd1SMarcel Holtmann 				status = ev->status;
67170fe29fd1SMarcel Holtmann 
67180fe29fd1SMarcel Holtmann 			conn->state = BT_CONNECTED;
67190fe29fd1SMarcel Holtmann 			hci_connect_cfm(conn, status);
67200fe29fd1SMarcel Holtmann 			hci_conn_drop(conn);
67210fe29fd1SMarcel Holtmann 		}
67220fe29fd1SMarcel Holtmann 	}
67230fe29fd1SMarcel Holtmann 
67240fe29fd1SMarcel Holtmann 	hci_dev_unlock(hdev);
67250fe29fd1SMarcel Holtmann }
67260fe29fd1SMarcel Holtmann 
672795118dd4SLuiz Augusto von Dentz static void hci_le_ltk_request_evt(struct hci_dev *hdev, void *data,
672895118dd4SLuiz Augusto von Dentz 				   struct sk_buff *skb)
6729a7a595f6SVinicius Costa Gomes {
673095118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_ltk_req *ev = data;
6731a7a595f6SVinicius Costa Gomes 	struct hci_cp_le_ltk_reply cp;
6732bea710feSVinicius Costa Gomes 	struct hci_cp_le_ltk_neg_reply neg;
6733a7a595f6SVinicius Costa Gomes 	struct hci_conn *conn;
6734c9839a11SVinicius Costa Gomes 	struct smp_ltk *ltk;
6735a7a595f6SVinicius Costa Gomes 
673695118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "handle 0x%4.4x", __le16_to_cpu(ev->handle));
6737a7a595f6SVinicius Costa Gomes 
6738a7a595f6SVinicius Costa Gomes 	hci_dev_lock(hdev);
6739a7a595f6SVinicius Costa Gomes 
6740a7a595f6SVinicius Costa Gomes 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
6741bea710feSVinicius Costa Gomes 	if (conn == NULL)
6742bea710feSVinicius Costa Gomes 		goto not_found;
6743a7a595f6SVinicius Costa Gomes 
6744f3a73d97SJohan Hedberg 	ltk = hci_find_ltk(hdev, &conn->dst, conn->dst_type, conn->role);
67455378bc56SJohan Hedberg 	if (!ltk)
6746bea710feSVinicius Costa Gomes 		goto not_found;
6747bea710feSVinicius Costa Gomes 
67485378bc56SJohan Hedberg 	if (smp_ltk_is_sc(ltk)) {
67495378bc56SJohan Hedberg 		/* With SC both EDiv and Rand are set to zero */
67505378bc56SJohan Hedberg 		if (ev->ediv || ev->rand)
67515378bc56SJohan Hedberg 			goto not_found;
67525378bc56SJohan Hedberg 	} else {
67535378bc56SJohan Hedberg 		/* For non-SC keys check that EDiv and Rand match */
67545378bc56SJohan Hedberg 		if (ev->ediv != ltk->ediv || ev->rand != ltk->rand)
67555378bc56SJohan Hedberg 			goto not_found;
67565378bc56SJohan Hedberg 	}
67575378bc56SJohan Hedberg 
67588b76ce34SJohan Hedberg 	memcpy(cp.ltk, ltk->val, ltk->enc_size);
67598b76ce34SJohan Hedberg 	memset(cp.ltk + ltk->enc_size, 0, sizeof(cp.ltk) - ltk->enc_size);
6760a7a595f6SVinicius Costa Gomes 	cp.handle = cpu_to_le16(conn->handle);
6761c9839a11SVinicius Costa Gomes 
6762a6f7833cSJohan Hedberg 	conn->pending_sec_level = smp_ltk_sec_level(ltk);
6763a7a595f6SVinicius Costa Gomes 
676489cbb4daSAndre Guedes 	conn->enc_key_size = ltk->enc_size;
6765a7a595f6SVinicius Costa Gomes 
6766a7a595f6SVinicius Costa Gomes 	hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
6767a7a595f6SVinicius Costa Gomes 
67685981a882SClaudio Takahasi 	/* Ref. Bluetooth Core SPEC pages 1975 and 2004. STK is a
67695981a882SClaudio Takahasi 	 * temporary key used to encrypt a connection following
67705981a882SClaudio Takahasi 	 * pairing. It is used during the Encrypted Session Setup to
67715981a882SClaudio Takahasi 	 * distribute the keys. Later, security can be re-established
67725981a882SClaudio Takahasi 	 * using a distributed LTK.
67735981a882SClaudio Takahasi 	 */
67742ceba539SJohan Hedberg 	if (ltk->type == SMP_STK) {
6775fe59a05fSJohan Hedberg 		set_bit(HCI_CONN_STK_ENCRYPT, &conn->flags);
6776970d0f1bSJohan Hedberg 		list_del_rcu(&ltk->list);
6777970d0f1bSJohan Hedberg 		kfree_rcu(ltk, rcu);
6778fe59a05fSJohan Hedberg 	} else {
6779fe59a05fSJohan Hedberg 		clear_bit(HCI_CONN_STK_ENCRYPT, &conn->flags);
6780c9839a11SVinicius Costa Gomes 	}
6781c9839a11SVinicius Costa Gomes 
6782a7a595f6SVinicius Costa Gomes 	hci_dev_unlock(hdev);
6783bea710feSVinicius Costa Gomes 
6784bea710feSVinicius Costa Gomes 	return;
6785bea710feSVinicius Costa Gomes 
6786bea710feSVinicius Costa Gomes not_found:
6787bea710feSVinicius Costa Gomes 	neg.handle = ev->handle;
6788bea710feSVinicius Costa Gomes 	hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
6789bea710feSVinicius Costa Gomes 	hci_dev_unlock(hdev);
6790a7a595f6SVinicius Costa Gomes }
6791a7a595f6SVinicius Costa Gomes 
67928e75b46aSAndre Guedes static void send_conn_param_neg_reply(struct hci_dev *hdev, u16 handle,
67938e75b46aSAndre Guedes 				      u8 reason)
67948e75b46aSAndre Guedes {
67958e75b46aSAndre Guedes 	struct hci_cp_le_conn_param_req_neg_reply cp;
67968e75b46aSAndre Guedes 
67978e75b46aSAndre Guedes 	cp.handle = cpu_to_le16(handle);
67988e75b46aSAndre Guedes 	cp.reason = reason;
67998e75b46aSAndre Guedes 
68008e75b46aSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY, sizeof(cp),
68018e75b46aSAndre Guedes 		     &cp);
68028e75b46aSAndre Guedes }
68038e75b46aSAndre Guedes 
680495118dd4SLuiz Augusto von Dentz static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev, void *data,
68058e75b46aSAndre Guedes 					     struct sk_buff *skb)
68068e75b46aSAndre Guedes {
680795118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_remote_conn_param_req *ev = data;
68088e75b46aSAndre Guedes 	struct hci_cp_le_conn_param_req_reply cp;
68098e75b46aSAndre Guedes 	struct hci_conn *hcon;
68108e75b46aSAndre Guedes 	u16 handle, min, max, latency, timeout;
68118e75b46aSAndre Guedes 
681295118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "handle 0x%4.4x", __le16_to_cpu(ev->handle));
681312cfe417SLuiz Augusto von Dentz 
68148e75b46aSAndre Guedes 	handle = le16_to_cpu(ev->handle);
68158e75b46aSAndre Guedes 	min = le16_to_cpu(ev->interval_min);
68168e75b46aSAndre Guedes 	max = le16_to_cpu(ev->interval_max);
68178e75b46aSAndre Guedes 	latency = le16_to_cpu(ev->latency);
68188e75b46aSAndre Guedes 	timeout = le16_to_cpu(ev->timeout);
68198e75b46aSAndre Guedes 
68208e75b46aSAndre Guedes 	hcon = hci_conn_hash_lookup_handle(hdev, handle);
68218e75b46aSAndre Guedes 	if (!hcon || hcon->state != BT_CONNECTED)
68228e75b46aSAndre Guedes 		return send_conn_param_neg_reply(hdev, handle,
68238e75b46aSAndre Guedes 						 HCI_ERROR_UNKNOWN_CONN_ID);
68248e75b46aSAndre Guedes 
6825dcd646f4SKai-Heng Feng 	if (max > hcon->le_conn_max_interval)
6826dcd646f4SKai-Heng Feng 		return send_conn_param_neg_reply(hdev, handle,
6827dcd646f4SKai-Heng Feng 						 HCI_ERROR_INVALID_LL_PARAMS);
6828dcd646f4SKai-Heng Feng 
68298e75b46aSAndre Guedes 	if (hci_check_conn_params(min, max, latency, timeout))
68308e75b46aSAndre Guedes 		return send_conn_param_neg_reply(hdev, handle,
68318e75b46aSAndre Guedes 						 HCI_ERROR_INVALID_LL_PARAMS);
68328e75b46aSAndre Guedes 
683340bef302SJohan Hedberg 	if (hcon->role == HCI_ROLE_MASTER) {
6834348d50b8SJohan Hedberg 		struct hci_conn_params *params;
6835f4869e2aSJohan Hedberg 		u8 store_hint;
6836348d50b8SJohan Hedberg 
6837348d50b8SJohan Hedberg 		hci_dev_lock(hdev);
6838348d50b8SJohan Hedberg 
6839348d50b8SJohan Hedberg 		params = hci_conn_params_lookup(hdev, &hcon->dst,
6840348d50b8SJohan Hedberg 						hcon->dst_type);
6841348d50b8SJohan Hedberg 		if (params) {
6842348d50b8SJohan Hedberg 			params->conn_min_interval = min;
6843348d50b8SJohan Hedberg 			params->conn_max_interval = max;
6844348d50b8SJohan Hedberg 			params->conn_latency = latency;
6845348d50b8SJohan Hedberg 			params->supervision_timeout = timeout;
6846f4869e2aSJohan Hedberg 			store_hint = 0x01;
6847f4869e2aSJohan Hedberg 		} else {
6848f4869e2aSJohan Hedberg 			store_hint = 0x00;
6849348d50b8SJohan Hedberg 		}
6850348d50b8SJohan Hedberg 
6851348d50b8SJohan Hedberg 		hci_dev_unlock(hdev);
6852348d50b8SJohan Hedberg 
6853f4869e2aSJohan Hedberg 		mgmt_new_conn_param(hdev, &hcon->dst, hcon->dst_type,
6854f4869e2aSJohan Hedberg 				    store_hint, min, max, latency, timeout);
6855348d50b8SJohan Hedberg 	}
6856ffb5a827SAndre Guedes 
68578e75b46aSAndre Guedes 	cp.handle = ev->handle;
68588e75b46aSAndre Guedes 	cp.interval_min = ev->interval_min;
68598e75b46aSAndre Guedes 	cp.interval_max = ev->interval_max;
68608e75b46aSAndre Guedes 	cp.latency = ev->latency;
68618e75b46aSAndre Guedes 	cp.timeout = ev->timeout;
68628e75b46aSAndre Guedes 	cp.min_ce_len = 0;
68638e75b46aSAndre Guedes 	cp.max_ce_len = 0;
68648e75b46aSAndre Guedes 
68658e75b46aSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_REPLY, sizeof(cp), &cp);
68668e75b46aSAndre Guedes }
68678e75b46aSAndre Guedes 
686895118dd4SLuiz Augusto von Dentz static void hci_le_direct_adv_report_evt(struct hci_dev *hdev, void *data,
68692f010b55SMarcel Holtmann 					 struct sk_buff *skb)
68702f010b55SMarcel Holtmann {
687195118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_direct_adv_report *ev = data;
6872b338d917SBrian Gix 	u64 instant = jiffies;
6873a3679649SLuiz Augusto von Dentz 	int i;
6874f7e0e8b2SPeilin Ye 
6875a3679649SLuiz Augusto von Dentz 	if (!hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_DIRECT_ADV_REPORT,
6876a3679649SLuiz Augusto von Dentz 				flex_array_size(ev, info, ev->num)))
6877a3679649SLuiz Augusto von Dentz 		return;
6878a3679649SLuiz Augusto von Dentz 
6879a3679649SLuiz Augusto von Dentz 	if (!ev->num)
6880f7e0e8b2SPeilin Ye 		return;
68812f010b55SMarcel Holtmann 
68822f010b55SMarcel Holtmann 	hci_dev_lock(hdev);
68832f010b55SMarcel Holtmann 
6884a3679649SLuiz Augusto von Dentz 	for (i = 0; i < ev->num; i++) {
6885a3679649SLuiz Augusto von Dentz 		struct hci_ev_le_direct_adv_info *info = &ev->info[i];
6886a3679649SLuiz Augusto von Dentz 
6887a3679649SLuiz Augusto von Dentz 		process_adv_report(hdev, info->type, &info->bdaddr,
6888a3679649SLuiz Augusto von Dentz 				   info->bdaddr_type, &info->direct_addr,
6889a3679649SLuiz Augusto von Dentz 				   info->direct_addr_type, info->rssi, NULL, 0,
6890b338d917SBrian Gix 				   false, false, instant);
6891a3679649SLuiz Augusto von Dentz 	}
68922f010b55SMarcel Holtmann 
68932f010b55SMarcel Holtmann 	hci_dev_unlock(hdev);
68942f010b55SMarcel Holtmann }
68952f010b55SMarcel Holtmann 
689695118dd4SLuiz Augusto von Dentz static void hci_le_phy_update_evt(struct hci_dev *hdev, void *data,
689795118dd4SLuiz Augusto von Dentz 				  struct sk_buff *skb)
68981efd927dSLuiz Augusto von Dentz {
689995118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_phy_update_complete *ev = data;
69001efd927dSLuiz Augusto von Dentz 	struct hci_conn *conn;
69011efd927dSLuiz Augusto von Dentz 
690295118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
69031efd927dSLuiz Augusto von Dentz 
690487df8bccSAyush Garg 	if (ev->status)
69051efd927dSLuiz Augusto von Dentz 		return;
69061efd927dSLuiz Augusto von Dentz 
69071efd927dSLuiz Augusto von Dentz 	hci_dev_lock(hdev);
69081efd927dSLuiz Augusto von Dentz 
69091efd927dSLuiz Augusto von Dentz 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
69101efd927dSLuiz Augusto von Dentz 	if (!conn)
69111efd927dSLuiz Augusto von Dentz 		goto unlock;
69121efd927dSLuiz Augusto von Dentz 
69131efd927dSLuiz Augusto von Dentz 	conn->le_tx_phy = ev->tx_phy;
69141efd927dSLuiz Augusto von Dentz 	conn->le_rx_phy = ev->rx_phy;
69151efd927dSLuiz Augusto von Dentz 
69161efd927dSLuiz Augusto von Dentz unlock:
69171efd927dSLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
69181efd927dSLuiz Augusto von Dentz }
69191efd927dSLuiz Augusto von Dentz 
692026afbd82SLuiz Augusto von Dentz static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data,
692126afbd82SLuiz Augusto von Dentz 					struct sk_buff *skb)
692226afbd82SLuiz Augusto von Dentz {
692326afbd82SLuiz Augusto von Dentz 	struct hci_evt_le_cis_established *ev = data;
692426afbd82SLuiz Augusto von Dentz 	struct hci_conn *conn;
69252be22f19SLuiz Augusto von Dentz 	struct bt_iso_qos *qos;
69267f74563eSPauli Virtanen 	bool pending = false;
692726afbd82SLuiz Augusto von Dentz 	u16 handle = __le16_to_cpu(ev->handle);
692826afbd82SLuiz Augusto von Dentz 
692926afbd82SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
693026afbd82SLuiz Augusto von Dentz 
693126afbd82SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
693226afbd82SLuiz Augusto von Dentz 
693326afbd82SLuiz Augusto von Dentz 	conn = hci_conn_hash_lookup_handle(hdev, handle);
693426afbd82SLuiz Augusto von Dentz 	if (!conn) {
693526afbd82SLuiz Augusto von Dentz 		bt_dev_err(hdev,
693626afbd82SLuiz Augusto von Dentz 			   "Unable to find connection with handle 0x%4.4x",
693726afbd82SLuiz Augusto von Dentz 			   handle);
693826afbd82SLuiz Augusto von Dentz 		goto unlock;
693926afbd82SLuiz Augusto von Dentz 	}
694026afbd82SLuiz Augusto von Dentz 
6941ed680f92SLuiz Augusto von Dentz 	if (conn->type != ISO_LINK) {
6942ed680f92SLuiz Augusto von Dentz 		bt_dev_err(hdev,
6943ed680f92SLuiz Augusto von Dentz 			   "Invalid connection link type handle 0x%4.4x",
6944ed680f92SLuiz Augusto von Dentz 			   handle);
6945ed680f92SLuiz Augusto von Dentz 		goto unlock;
6946ed680f92SLuiz Augusto von Dentz 	}
6947ed680f92SLuiz Augusto von Dentz 
69482be22f19SLuiz Augusto von Dentz 	qos = &conn->iso_qos;
694926afbd82SLuiz Augusto von Dentz 
69507f74563eSPauli Virtanen 	pending = test_and_clear_bit(HCI_CONN_CREATE_CIS, &conn->flags);
69517f74563eSPauli Virtanen 
69522be22f19SLuiz Augusto von Dentz 	/* Convert ISO Interval (1.25 ms slots) to SDU Interval (us) */
69532be22f19SLuiz Augusto von Dentz 	qos->ucast.in.interval = le16_to_cpu(ev->interval) * 1250;
69542be22f19SLuiz Augusto von Dentz 	qos->ucast.out.interval = qos->ucast.in.interval;
695526afbd82SLuiz Augusto von Dentz 
69562be22f19SLuiz Augusto von Dentz 	switch (conn->role) {
69572be22f19SLuiz Augusto von Dentz 	case HCI_ROLE_SLAVE:
69582be22f19SLuiz Augusto von Dentz 		/* Convert Transport Latency (us) to Latency (msec) */
69592be22f19SLuiz Augusto von Dentz 		qos->ucast.in.latency =
69602be22f19SLuiz Augusto von Dentz 			DIV_ROUND_CLOSEST(get_unaligned_le24(ev->c_latency),
69612be22f19SLuiz Augusto von Dentz 					  1000);
69622be22f19SLuiz Augusto von Dentz 		qos->ucast.out.latency =
69632be22f19SLuiz Augusto von Dentz 			DIV_ROUND_CLOSEST(get_unaligned_le24(ev->p_latency),
69642be22f19SLuiz Augusto von Dentz 					  1000);
69652be22f19SLuiz Augusto von Dentz 		qos->ucast.in.sdu = le16_to_cpu(ev->c_mtu);
69662be22f19SLuiz Augusto von Dentz 		qos->ucast.out.sdu = le16_to_cpu(ev->p_mtu);
69672be22f19SLuiz Augusto von Dentz 		qos->ucast.in.phy = ev->c_phy;
69682be22f19SLuiz Augusto von Dentz 		qos->ucast.out.phy = ev->p_phy;
69692be22f19SLuiz Augusto von Dentz 		break;
69702be22f19SLuiz Augusto von Dentz 	case HCI_ROLE_MASTER:
69712be22f19SLuiz Augusto von Dentz 		/* Convert Transport Latency (us) to Latency (msec) */
69722be22f19SLuiz Augusto von Dentz 		qos->ucast.out.latency =
69732be22f19SLuiz Augusto von Dentz 			DIV_ROUND_CLOSEST(get_unaligned_le24(ev->c_latency),
69742be22f19SLuiz Augusto von Dentz 					  1000);
69752be22f19SLuiz Augusto von Dentz 		qos->ucast.in.latency =
69762be22f19SLuiz Augusto von Dentz 			DIV_ROUND_CLOSEST(get_unaligned_le24(ev->p_latency),
69772be22f19SLuiz Augusto von Dentz 					  1000);
69782be22f19SLuiz Augusto von Dentz 		qos->ucast.out.sdu = le16_to_cpu(ev->c_mtu);
69792be22f19SLuiz Augusto von Dentz 		qos->ucast.in.sdu = le16_to_cpu(ev->p_mtu);
69802be22f19SLuiz Augusto von Dentz 		qos->ucast.out.phy = ev->c_phy;
69812be22f19SLuiz Augusto von Dentz 		qos->ucast.in.phy = ev->p_phy;
69822be22f19SLuiz Augusto von Dentz 		break;
698326afbd82SLuiz Augusto von Dentz 	}
698426afbd82SLuiz Augusto von Dentz 
698526afbd82SLuiz Augusto von Dentz 	if (!ev->status) {
698626afbd82SLuiz Augusto von Dentz 		conn->state = BT_CONNECTED;
698726afbd82SLuiz Augusto von Dentz 		hci_debugfs_create_conn(conn);
698826afbd82SLuiz Augusto von Dentz 		hci_conn_add_sysfs(conn);
698926afbd82SLuiz Augusto von Dentz 		hci_iso_setup_path(conn);
699026afbd82SLuiz Augusto von Dentz 		goto unlock;
699126afbd82SLuiz Augusto von Dentz 	}
699226afbd82SLuiz Augusto von Dentz 
69937f74563eSPauli Virtanen 	conn->state = BT_CLOSED;
699426afbd82SLuiz Augusto von Dentz 	hci_connect_cfm(conn, ev->status);
699526afbd82SLuiz Augusto von Dentz 	hci_conn_del(conn);
699626afbd82SLuiz Augusto von Dentz 
699726afbd82SLuiz Augusto von Dentz unlock:
69987f74563eSPauli Virtanen 	if (pending)
69997f74563eSPauli Virtanen 		hci_le_create_cis_pending(hdev);
70007f74563eSPauli Virtanen 
700126afbd82SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
700226afbd82SLuiz Augusto von Dentz }
700326afbd82SLuiz Augusto von Dentz 
700426afbd82SLuiz Augusto von Dentz static void hci_le_reject_cis(struct hci_dev *hdev, __le16 handle)
700526afbd82SLuiz Augusto von Dentz {
700626afbd82SLuiz Augusto von Dentz 	struct hci_cp_le_reject_cis cp;
700726afbd82SLuiz Augusto von Dentz 
700826afbd82SLuiz Augusto von Dentz 	memset(&cp, 0, sizeof(cp));
700926afbd82SLuiz Augusto von Dentz 	cp.handle = handle;
701026afbd82SLuiz Augusto von Dentz 	cp.reason = HCI_ERROR_REJ_BAD_ADDR;
701126afbd82SLuiz Augusto von Dentz 	hci_send_cmd(hdev, HCI_OP_LE_REJECT_CIS, sizeof(cp), &cp);
701226afbd82SLuiz Augusto von Dentz }
701326afbd82SLuiz Augusto von Dentz 
701426afbd82SLuiz Augusto von Dentz static void hci_le_accept_cis(struct hci_dev *hdev, __le16 handle)
701526afbd82SLuiz Augusto von Dentz {
701626afbd82SLuiz Augusto von Dentz 	struct hci_cp_le_accept_cis cp;
701726afbd82SLuiz Augusto von Dentz 
701826afbd82SLuiz Augusto von Dentz 	memset(&cp, 0, sizeof(cp));
701926afbd82SLuiz Augusto von Dentz 	cp.handle = handle;
702026afbd82SLuiz Augusto von Dentz 	hci_send_cmd(hdev, HCI_OP_LE_ACCEPT_CIS, sizeof(cp), &cp);
702126afbd82SLuiz Augusto von Dentz }
702226afbd82SLuiz Augusto von Dentz 
702326afbd82SLuiz Augusto von Dentz static void hci_le_cis_req_evt(struct hci_dev *hdev, void *data,
702426afbd82SLuiz Augusto von Dentz 			       struct sk_buff *skb)
702526afbd82SLuiz Augusto von Dentz {
702626afbd82SLuiz Augusto von Dentz 	struct hci_evt_le_cis_req *ev = data;
702726afbd82SLuiz Augusto von Dentz 	u16 acl_handle, cis_handle;
702826afbd82SLuiz Augusto von Dentz 	struct hci_conn *acl, *cis;
702926afbd82SLuiz Augusto von Dentz 	int mask;
703026afbd82SLuiz Augusto von Dentz 	__u8 flags = 0;
703126afbd82SLuiz Augusto von Dentz 
703226afbd82SLuiz Augusto von Dentz 	acl_handle = __le16_to_cpu(ev->acl_handle);
703326afbd82SLuiz Augusto von Dentz 	cis_handle = __le16_to_cpu(ev->cis_handle);
703426afbd82SLuiz Augusto von Dentz 
703526afbd82SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "acl 0x%4.4x handle 0x%4.4x cig 0x%2.2x cis 0x%2.2x",
703626afbd82SLuiz Augusto von Dentz 		   acl_handle, cis_handle, ev->cig_id, ev->cis_id);
703726afbd82SLuiz Augusto von Dentz 
703826afbd82SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
703926afbd82SLuiz Augusto von Dentz 
704026afbd82SLuiz Augusto von Dentz 	acl = hci_conn_hash_lookup_handle(hdev, acl_handle);
704126afbd82SLuiz Augusto von Dentz 	if (!acl)
704226afbd82SLuiz Augusto von Dentz 		goto unlock;
704326afbd82SLuiz Augusto von Dentz 
704426afbd82SLuiz Augusto von Dentz 	mask = hci_proto_connect_ind(hdev, &acl->dst, ISO_LINK, &flags);
704526afbd82SLuiz Augusto von Dentz 	if (!(mask & HCI_LM_ACCEPT)) {
704626afbd82SLuiz Augusto von Dentz 		hci_le_reject_cis(hdev, ev->cis_handle);
704726afbd82SLuiz Augusto von Dentz 		goto unlock;
704826afbd82SLuiz Augusto von Dentz 	}
704926afbd82SLuiz Augusto von Dentz 
705026afbd82SLuiz Augusto von Dentz 	cis = hci_conn_hash_lookup_handle(hdev, cis_handle);
705126afbd82SLuiz Augusto von Dentz 	if (!cis) {
705284cb0143SZiyang Xuan 		cis = hci_conn_add(hdev, ISO_LINK, &acl->dst, HCI_ROLE_SLAVE,
705384cb0143SZiyang Xuan 				   cis_handle);
705426afbd82SLuiz Augusto von Dentz 		if (!cis) {
705526afbd82SLuiz Augusto von Dentz 			hci_le_reject_cis(hdev, ev->cis_handle);
705626afbd82SLuiz Augusto von Dentz 			goto unlock;
705726afbd82SLuiz Augusto von Dentz 		}
705826afbd82SLuiz Augusto von Dentz 	}
705926afbd82SLuiz Augusto von Dentz 
70600fe8c8d0SIulia Tanasescu 	cis->iso_qos.ucast.cig = ev->cig_id;
70610fe8c8d0SIulia Tanasescu 	cis->iso_qos.ucast.cis = ev->cis_id;
706226afbd82SLuiz Augusto von Dentz 
706326afbd82SLuiz Augusto von Dentz 	if (!(flags & HCI_PROTO_DEFER)) {
706426afbd82SLuiz Augusto von Dentz 		hci_le_accept_cis(hdev, ev->cis_handle);
706526afbd82SLuiz Augusto von Dentz 	} else {
706626afbd82SLuiz Augusto von Dentz 		cis->state = BT_CONNECT2;
706726afbd82SLuiz Augusto von Dentz 		hci_connect_cfm(cis, 0);
706826afbd82SLuiz Augusto von Dentz 	}
706926afbd82SLuiz Augusto von Dentz 
707026afbd82SLuiz Augusto von Dentz unlock:
707126afbd82SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
707226afbd82SLuiz Augusto von Dentz }
707326afbd82SLuiz Augusto von Dentz 
7074acab8ff2SIulia Tanasescu static int hci_iso_term_big_sync(struct hci_dev *hdev, void *data)
7075acab8ff2SIulia Tanasescu {
7076acab8ff2SIulia Tanasescu 	u8 handle = PTR_UINT(data);
7077acab8ff2SIulia Tanasescu 
7078acab8ff2SIulia Tanasescu 	return hci_le_terminate_big_sync(hdev, handle,
7079acab8ff2SIulia Tanasescu 					 HCI_ERROR_LOCAL_HOST_TERM);
7080acab8ff2SIulia Tanasescu }
7081acab8ff2SIulia Tanasescu 
7082eca0ae4aSLuiz Augusto von Dentz static void hci_le_create_big_complete_evt(struct hci_dev *hdev, void *data,
7083eca0ae4aSLuiz Augusto von Dentz 					   struct sk_buff *skb)
7084eca0ae4aSLuiz Augusto von Dentz {
7085eca0ae4aSLuiz Augusto von Dentz 	struct hci_evt_le_create_big_complete *ev = data;
7086eca0ae4aSLuiz Augusto von Dentz 	struct hci_conn *conn;
708716e3b642SLuiz Augusto von Dentz 	__u8 i = 0;
7088eca0ae4aSLuiz Augusto von Dentz 
7089eca0ae4aSLuiz Augusto von Dentz 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
7090eca0ae4aSLuiz Augusto von Dentz 
7091eca0ae4aSLuiz Augusto von Dentz 	if (!hci_le_ev_skb_pull(hdev, skb, HCI_EVT_LE_CREATE_BIG_COMPLETE,
7092eca0ae4aSLuiz Augusto von Dentz 				flex_array_size(ev, bis_handle, ev->num_bis)))
7093eca0ae4aSLuiz Augusto von Dentz 		return;
7094eca0ae4aSLuiz Augusto von Dentz 
7095eca0ae4aSLuiz Augusto von Dentz 	hci_dev_lock(hdev);
7096a0bfde16SIulia Tanasescu 	rcu_read_lock();
7097eca0ae4aSLuiz Augusto von Dentz 
7098a0bfde16SIulia Tanasescu 	/* Connect all BISes that are bound to the BIG */
7099a0bfde16SIulia Tanasescu 	list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) {
7100a0bfde16SIulia Tanasescu 		if (bacmp(&conn->dst, BDADDR_ANY) ||
7101a0bfde16SIulia Tanasescu 		    conn->type != ISO_LINK ||
7102a0bfde16SIulia Tanasescu 		    conn->iso_qos.bcast.big != ev->handle)
7103a0bfde16SIulia Tanasescu 			continue;
7104eca0ae4aSLuiz Augusto von Dentz 
710516e3b642SLuiz Augusto von Dentz 		if (hci_conn_set_handle(conn,
710616e3b642SLuiz Augusto von Dentz 					__le16_to_cpu(ev->bis_handle[i++])))
710716e3b642SLuiz Augusto von Dentz 			continue;
7108eca0ae4aSLuiz Augusto von Dentz 
7109eca0ae4aSLuiz Augusto von Dentz 		if (!ev->status) {
7110eca0ae4aSLuiz Augusto von Dentz 			conn->state = BT_CONNECTED;
7111a0bfde16SIulia Tanasescu 			set_bit(HCI_CONN_BIG_CREATED, &conn->flags);
7112a0bfde16SIulia Tanasescu 			rcu_read_unlock();
7113eca0ae4aSLuiz Augusto von Dentz 			hci_debugfs_create_conn(conn);
7114eca0ae4aSLuiz Augusto von Dentz 			hci_conn_add_sysfs(conn);
7115eca0ae4aSLuiz Augusto von Dentz 			hci_iso_setup_path(conn);
7116a0bfde16SIulia Tanasescu 			rcu_read_lock();
7117a0bfde16SIulia Tanasescu 			continue;
7118eca0ae4aSLuiz Augusto von Dentz 		}
7119eca0ae4aSLuiz Augusto von Dentz 
7120eca0ae4aSLuiz Augusto von Dentz 		hci_connect_cfm(conn, ev->status);
7121a0bfde16SIulia Tanasescu 		rcu_read_unlock();
7122eca0ae4aSLuiz Augusto von Dentz 		hci_conn_del(conn);
7123a0bfde16SIulia Tanasescu 		rcu_read_lock();
7124a0bfde16SIulia Tanasescu 	}
7125eca0ae4aSLuiz Augusto von Dentz 
7126acab8ff2SIulia Tanasescu 	rcu_read_unlock();
7127acab8ff2SIulia Tanasescu 
712816e3b642SLuiz Augusto von Dentz 	if (!ev->status && !i)
7129a0bfde16SIulia Tanasescu 		/* If no BISes have been connected for the BIG,
7130a0bfde16SIulia Tanasescu 		 * terminate. This is in case all bound connections
7131a0bfde16SIulia Tanasescu 		 * have been closed before the BIG creation
7132a0bfde16SIulia Tanasescu 		 * has completed.
7133a0bfde16SIulia Tanasescu 		 */
7134acab8ff2SIulia Tanasescu 		hci_cmd_sync_queue(hdev, hci_iso_term_big_sync,
7135acab8ff2SIulia Tanasescu 				   UINT_PTR(ev->handle), NULL);
7136a0bfde16SIulia Tanasescu 
7137eca0ae4aSLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
7138eca0ae4aSLuiz Augusto von Dentz }
7139eca0ae4aSLuiz Augusto von Dentz 
7140eca0ae4aSLuiz Augusto von Dentz static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data,
7141eca0ae4aSLuiz Augusto von Dentz 					    struct sk_buff *skb)
7142eca0ae4aSLuiz Augusto von Dentz {
7143eca0ae4aSLuiz Augusto von Dentz 	struct hci_evt_le_big_sync_estabilished *ev = data;
7144eca0ae4aSLuiz Augusto von Dentz 	struct hci_conn *bis;
7145fbdc4bc4SIulia Tanasescu 	struct hci_conn *pa_sync;
7146eca0ae4aSLuiz Augusto von Dentz 	int i;
7147eca0ae4aSLuiz Augusto von Dentz 
7148eca0ae4aSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
7149eca0ae4aSLuiz Augusto von Dentz 
7150eca0ae4aSLuiz Augusto von Dentz 	if (!hci_le_ev_skb_pull(hdev, skb, HCI_EVT_LE_BIG_SYNC_ESTABILISHED,
7151eca0ae4aSLuiz Augusto von Dentz 				flex_array_size(ev, bis, ev->num_bis)))
7152eca0ae4aSLuiz Augusto von Dentz 		return;
7153eca0ae4aSLuiz Augusto von Dentz 
7154eca0ae4aSLuiz Augusto von Dentz 	hci_dev_lock(hdev);
7155eca0ae4aSLuiz Augusto von Dentz 
7156fbdc4bc4SIulia Tanasescu 	if (!ev->status) {
715723417475SIulia Tanasescu 		pa_sync = hci_conn_hash_lookup_pa_sync_big_handle(hdev, ev->handle);
7158fbdc4bc4SIulia Tanasescu 		if (pa_sync)
7159fbdc4bc4SIulia Tanasescu 			/* Also mark the BIG sync established event on the
7160fbdc4bc4SIulia Tanasescu 			 * associated PA sync hcon
7161fbdc4bc4SIulia Tanasescu 			 */
7162fbdc4bc4SIulia Tanasescu 			set_bit(HCI_CONN_BIG_SYNC, &pa_sync->flags);
7163fbdc4bc4SIulia Tanasescu 	}
7164fbdc4bc4SIulia Tanasescu 
7165eca0ae4aSLuiz Augusto von Dentz 	for (i = 0; i < ev->num_bis; i++) {
7166eca0ae4aSLuiz Augusto von Dentz 		u16 handle = le16_to_cpu(ev->bis[i]);
7167eca0ae4aSLuiz Augusto von Dentz 		__le32 interval;
7168eca0ae4aSLuiz Augusto von Dentz 
7169eca0ae4aSLuiz Augusto von Dentz 		bis = hci_conn_hash_lookup_handle(hdev, handle);
7170eca0ae4aSLuiz Augusto von Dentz 		if (!bis) {
7171eca0ae4aSLuiz Augusto von Dentz 			bis = hci_conn_add(hdev, ISO_LINK, BDADDR_ANY,
717284cb0143SZiyang Xuan 					   HCI_ROLE_SLAVE, handle);
7173eca0ae4aSLuiz Augusto von Dentz 			if (!bis)
7174eca0ae4aSLuiz Augusto von Dentz 				continue;
7175eca0ae4aSLuiz Augusto von Dentz 		}
7176eca0ae4aSLuiz Augusto von Dentz 
7177fbdc4bc4SIulia Tanasescu 		if (ev->status != 0x42)
7178fbdc4bc4SIulia Tanasescu 			/* Mark PA sync as established */
7179fbdc4bc4SIulia Tanasescu 			set_bit(HCI_CONN_PA_SYNC, &bis->flags);
7180fbdc4bc4SIulia Tanasescu 
71810fe8c8d0SIulia Tanasescu 		bis->iso_qos.bcast.big = ev->handle;
7182eca0ae4aSLuiz Augusto von Dentz 		memset(&interval, 0, sizeof(interval));
7183eca0ae4aSLuiz Augusto von Dentz 		memcpy(&interval, ev->latency, sizeof(ev->latency));
71840fe8c8d0SIulia Tanasescu 		bis->iso_qos.bcast.in.interval = le32_to_cpu(interval);
7185eca0ae4aSLuiz Augusto von Dentz 		/* Convert ISO Interval (1.25 ms slots) to latency (ms) */
71860fe8c8d0SIulia Tanasescu 		bis->iso_qos.bcast.in.latency = le16_to_cpu(ev->interval) * 125 / 100;
71870fe8c8d0SIulia Tanasescu 		bis->iso_qos.bcast.in.sdu = le16_to_cpu(ev->max_pdu);
7188eca0ae4aSLuiz Augusto von Dentz 
7189f777d882SIulia Tanasescu 		if (!ev->status) {
7190f777d882SIulia Tanasescu 			set_bit(HCI_CONN_BIG_SYNC, &bis->flags);
7191d2e4f1b1SClaudia Draghicescu 			hci_iso_setup_path(bis);
7192eca0ae4aSLuiz Augusto von Dentz 		}
7193f777d882SIulia Tanasescu 	}
7194f777d882SIulia Tanasescu 
7195f777d882SIulia Tanasescu 	/* In case BIG sync failed, notify each failed connection to
7196f777d882SIulia Tanasescu 	 * the user after all hci connections have been added
7197f777d882SIulia Tanasescu 	 */
7198f777d882SIulia Tanasescu 	if (ev->status)
7199f777d882SIulia Tanasescu 		for (i = 0; i < ev->num_bis; i++) {
7200f777d882SIulia Tanasescu 			u16 handle = le16_to_cpu(ev->bis[i]);
7201f777d882SIulia Tanasescu 
7202f777d882SIulia Tanasescu 			bis = hci_conn_hash_lookup_handle(hdev, handle);
7203f777d882SIulia Tanasescu 
7204f777d882SIulia Tanasescu 			set_bit(HCI_CONN_BIG_SYNC_FAILED, &bis->flags);
7205f777d882SIulia Tanasescu 			hci_connect_cfm(bis, ev->status);
7206f777d882SIulia Tanasescu 		}
7207eca0ae4aSLuiz Augusto von Dentz 
7208eca0ae4aSLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
7209eca0ae4aSLuiz Augusto von Dentz }
7210eca0ae4aSLuiz Augusto von Dentz 
7211eca0ae4aSLuiz Augusto von Dentz static void hci_le_big_info_adv_report_evt(struct hci_dev *hdev, void *data,
7212eca0ae4aSLuiz Augusto von Dentz 					   struct sk_buff *skb)
7213eca0ae4aSLuiz Augusto von Dentz {
7214eca0ae4aSLuiz Augusto von Dentz 	struct hci_evt_le_big_info_adv_report *ev = data;
7215eca0ae4aSLuiz Augusto von Dentz 	int mask = hdev->link_mode;
7216eca0ae4aSLuiz Augusto von Dentz 	__u8 flags = 0;
721723417475SIulia Tanasescu 	struct hci_conn *pa_sync;
7218eca0ae4aSLuiz Augusto von Dentz 
7219eca0ae4aSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "sync_handle 0x%4.4x", le16_to_cpu(ev->sync_handle));
7220eca0ae4aSLuiz Augusto von Dentz 
7221eca0ae4aSLuiz Augusto von Dentz 	hci_dev_lock(hdev);
7222eca0ae4aSLuiz Augusto von Dentz 
7223eca0ae4aSLuiz Augusto von Dentz 	mask |= hci_proto_connect_ind(hdev, BDADDR_ANY, ISO_LINK, &flags);
722423417475SIulia Tanasescu 	if (!(mask & HCI_LM_ACCEPT)) {
7225eca0ae4aSLuiz Augusto von Dentz 		hci_le_pa_term_sync(hdev, ev->sync_handle);
722623417475SIulia Tanasescu 		goto unlock;
722723417475SIulia Tanasescu 	}
7228eca0ae4aSLuiz Augusto von Dentz 
722923417475SIulia Tanasescu 	if (!(flags & HCI_PROTO_DEFER))
723023417475SIulia Tanasescu 		goto unlock;
723123417475SIulia Tanasescu 
723223417475SIulia Tanasescu 	pa_sync = hci_conn_hash_lookup_pa_sync_handle
723323417475SIulia Tanasescu 			(hdev,
723423417475SIulia Tanasescu 			le16_to_cpu(ev->sync_handle));
723523417475SIulia Tanasescu 
723623417475SIulia Tanasescu 	if (pa_sync)
723723417475SIulia Tanasescu 		goto unlock;
723823417475SIulia Tanasescu 
723923417475SIulia Tanasescu 	/* Add connection to indicate the PA sync event */
724084cb0143SZiyang Xuan 	pa_sync = hci_conn_add_unset(hdev, ISO_LINK, BDADDR_ANY,
724123417475SIulia Tanasescu 				     HCI_ROLE_SLAVE);
724223417475SIulia Tanasescu 
724323417475SIulia Tanasescu 	if (!pa_sync)
724423417475SIulia Tanasescu 		goto unlock;
724523417475SIulia Tanasescu 
724623417475SIulia Tanasescu 	pa_sync->sync_handle = le16_to_cpu(ev->sync_handle);
724723417475SIulia Tanasescu 	set_bit(HCI_CONN_PA_SYNC, &pa_sync->flags);
724823417475SIulia Tanasescu 
724923417475SIulia Tanasescu 	/* Notify iso layer */
725023417475SIulia Tanasescu 	hci_connect_cfm(pa_sync, 0x00);
725123417475SIulia Tanasescu 
72520b3df53cSLuiz Augusto von Dentz 	/* Notify MGMT layer */
72530b3df53cSLuiz Augusto von Dentz 	mgmt_device_connected(hdev, pa_sync, NULL, 0);
72540b3df53cSLuiz Augusto von Dentz 
725523417475SIulia Tanasescu unlock:
7256eca0ae4aSLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
7257eca0ae4aSLuiz Augusto von Dentz }
7258eca0ae4aSLuiz Augusto von Dentz 
725995118dd4SLuiz Augusto von Dentz #define HCI_LE_EV_VL(_op, _func, _min_len, _max_len) \
726095118dd4SLuiz Augusto von Dentz [_op] = { \
726195118dd4SLuiz Augusto von Dentz 	.func = _func, \
726295118dd4SLuiz Augusto von Dentz 	.min_len = _min_len, \
726395118dd4SLuiz Augusto von Dentz 	.max_len = _max_len, \
726495118dd4SLuiz Augusto von Dentz }
726595118dd4SLuiz Augusto von Dentz 
726695118dd4SLuiz Augusto von Dentz #define HCI_LE_EV(_op, _func, _len) \
726795118dd4SLuiz Augusto von Dentz 	HCI_LE_EV_VL(_op, _func, _len, _len)
726895118dd4SLuiz Augusto von Dentz 
726995118dd4SLuiz Augusto von Dentz #define HCI_LE_EV_STATUS(_op, _func) \
727095118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(_op, _func, sizeof(struct hci_ev_status))
727195118dd4SLuiz Augusto von Dentz 
727295118dd4SLuiz Augusto von Dentz /* Entries in this table shall have their position according to the subevent
727395118dd4SLuiz Augusto von Dentz  * opcode they handle so the use of the macros above is recommend since it does
727495118dd4SLuiz Augusto von Dentz  * attempt to initialize at its proper index using Designated Initializers that
727595118dd4SLuiz Augusto von Dentz  * way events without a callback function can be ommited.
727695118dd4SLuiz Augusto von Dentz  */
727795118dd4SLuiz Augusto von Dentz static const struct hci_le_ev {
727895118dd4SLuiz Augusto von Dentz 	void (*func)(struct hci_dev *hdev, void *data, struct sk_buff *skb);
727995118dd4SLuiz Augusto von Dentz 	u16  min_len;
728095118dd4SLuiz Augusto von Dentz 	u16  max_len;
728195118dd4SLuiz Augusto von Dentz } hci_le_ev_table[U8_MAX + 1] = {
728295118dd4SLuiz Augusto von Dentz 	/* [0x01 = HCI_EV_LE_CONN_COMPLETE] */
728395118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_CONN_COMPLETE, hci_le_conn_complete_evt,
728495118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_conn_complete)),
728595118dd4SLuiz Augusto von Dentz 	/* [0x02 = HCI_EV_LE_ADVERTISING_REPORT] */
728695118dd4SLuiz Augusto von Dentz 	HCI_LE_EV_VL(HCI_EV_LE_ADVERTISING_REPORT, hci_le_adv_report_evt,
728795118dd4SLuiz Augusto von Dentz 		     sizeof(struct hci_ev_le_advertising_report),
728895118dd4SLuiz Augusto von Dentz 		     HCI_MAX_EVENT_SIZE),
728995118dd4SLuiz Augusto von Dentz 	/* [0x03 = HCI_EV_LE_CONN_UPDATE_COMPLETE] */
729095118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_CONN_UPDATE_COMPLETE,
729195118dd4SLuiz Augusto von Dentz 		  hci_le_conn_update_complete_evt,
729295118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_conn_update_complete)),
729395118dd4SLuiz Augusto von Dentz 	/* [0x04 = HCI_EV_LE_REMOTE_FEAT_COMPLETE] */
729495118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_REMOTE_FEAT_COMPLETE,
729595118dd4SLuiz Augusto von Dentz 		  hci_le_remote_feat_complete_evt,
729695118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_remote_feat_complete)),
729795118dd4SLuiz Augusto von Dentz 	/* [0x05 = HCI_EV_LE_LTK_REQ] */
729895118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_LTK_REQ, hci_le_ltk_request_evt,
729995118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_ltk_req)),
730095118dd4SLuiz Augusto von Dentz 	/* [0x06 = HCI_EV_LE_REMOTE_CONN_PARAM_REQ] */
730195118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_REMOTE_CONN_PARAM_REQ,
730295118dd4SLuiz Augusto von Dentz 		  hci_le_remote_conn_param_req_evt,
730395118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_remote_conn_param_req)),
730495118dd4SLuiz Augusto von Dentz 	/* [0x0a = HCI_EV_LE_ENHANCED_CONN_COMPLETE] */
730595118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_ENHANCED_CONN_COMPLETE,
730695118dd4SLuiz Augusto von Dentz 		  hci_le_enh_conn_complete_evt,
730795118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_enh_conn_complete)),
730895118dd4SLuiz Augusto von Dentz 	/* [0x0b = HCI_EV_LE_DIRECT_ADV_REPORT] */
730995118dd4SLuiz Augusto von Dentz 	HCI_LE_EV_VL(HCI_EV_LE_DIRECT_ADV_REPORT, hci_le_direct_adv_report_evt,
731095118dd4SLuiz Augusto von Dentz 		     sizeof(struct hci_ev_le_direct_adv_report),
731195118dd4SLuiz Augusto von Dentz 		     HCI_MAX_EVENT_SIZE),
731295118dd4SLuiz Augusto von Dentz 	/* [0x0c = HCI_EV_LE_PHY_UPDATE_COMPLETE] */
731395118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_PHY_UPDATE_COMPLETE, hci_le_phy_update_evt,
731495118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_phy_update_complete)),
731595118dd4SLuiz Augusto von Dentz 	/* [0x0d = HCI_EV_LE_EXT_ADV_REPORT] */
731695118dd4SLuiz Augusto von Dentz 	HCI_LE_EV_VL(HCI_EV_LE_EXT_ADV_REPORT, hci_le_ext_adv_report_evt,
731795118dd4SLuiz Augusto von Dentz 		     sizeof(struct hci_ev_le_ext_adv_report),
731895118dd4SLuiz Augusto von Dentz 		     HCI_MAX_EVENT_SIZE),
7319eca0ae4aSLuiz Augusto von Dentz 	/* [0x0e = HCI_EV_LE_PA_SYNC_ESTABLISHED] */
7320eca0ae4aSLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_PA_SYNC_ESTABLISHED,
7321eca0ae4aSLuiz Augusto von Dentz 		  hci_le_pa_sync_estabilished_evt,
7322eca0ae4aSLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_pa_sync_established)),
73239c082631SClaudia Draghicescu 	/* [0x0f = HCI_EV_LE_PER_ADV_REPORT] */
73249c082631SClaudia Draghicescu 	HCI_LE_EV_VL(HCI_EV_LE_PER_ADV_REPORT,
73259c082631SClaudia Draghicescu 				 hci_le_per_adv_report_evt,
73269c082631SClaudia Draghicescu 				 sizeof(struct hci_ev_le_per_adv_report),
73279c082631SClaudia Draghicescu 				 HCI_MAX_EVENT_SIZE),
732895118dd4SLuiz Augusto von Dentz 	/* [0x12 = HCI_EV_LE_EXT_ADV_SET_TERM] */
732995118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_EXT_ADV_SET_TERM, hci_le_ext_adv_term_evt,
733095118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_evt_le_ext_adv_set_term)),
733126afbd82SLuiz Augusto von Dentz 	/* [0x19 = HCI_EVT_LE_CIS_ESTABLISHED] */
733226afbd82SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EVT_LE_CIS_ESTABLISHED, hci_le_cis_estabilished_evt,
733326afbd82SLuiz Augusto von Dentz 		  sizeof(struct hci_evt_le_cis_established)),
733426afbd82SLuiz Augusto von Dentz 	/* [0x1a = HCI_EVT_LE_CIS_REQ] */
733526afbd82SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EVT_LE_CIS_REQ, hci_le_cis_req_evt,
733626afbd82SLuiz Augusto von Dentz 		  sizeof(struct hci_evt_le_cis_req)),
7337eca0ae4aSLuiz Augusto von Dentz 	/* [0x1b = HCI_EVT_LE_CREATE_BIG_COMPLETE] */
7338eca0ae4aSLuiz Augusto von Dentz 	HCI_LE_EV_VL(HCI_EVT_LE_CREATE_BIG_COMPLETE,
7339eca0ae4aSLuiz Augusto von Dentz 		     hci_le_create_big_complete_evt,
7340eca0ae4aSLuiz Augusto von Dentz 		     sizeof(struct hci_evt_le_create_big_complete),
7341eca0ae4aSLuiz Augusto von Dentz 		     HCI_MAX_EVENT_SIZE),
7342eca0ae4aSLuiz Augusto von Dentz 	/* [0x1d = HCI_EV_LE_BIG_SYNC_ESTABILISHED] */
7343eca0ae4aSLuiz Augusto von Dentz 	HCI_LE_EV_VL(HCI_EVT_LE_BIG_SYNC_ESTABILISHED,
7344eca0ae4aSLuiz Augusto von Dentz 		     hci_le_big_sync_established_evt,
7345eca0ae4aSLuiz Augusto von Dentz 		     sizeof(struct hci_evt_le_big_sync_estabilished),
7346eca0ae4aSLuiz Augusto von Dentz 		     HCI_MAX_EVENT_SIZE),
7347eca0ae4aSLuiz Augusto von Dentz 	/* [0x22 = HCI_EVT_LE_BIG_INFO_ADV_REPORT] */
7348eca0ae4aSLuiz Augusto von Dentz 	HCI_LE_EV_VL(HCI_EVT_LE_BIG_INFO_ADV_REPORT,
7349eca0ae4aSLuiz Augusto von Dentz 		     hci_le_big_info_adv_report_evt,
7350eca0ae4aSLuiz Augusto von Dentz 		     sizeof(struct hci_evt_le_big_info_adv_report),
7351eca0ae4aSLuiz Augusto von Dentz 		     HCI_MAX_EVENT_SIZE),
735295118dd4SLuiz Augusto von Dentz };
735395118dd4SLuiz Augusto von Dentz 
73543e54c589SLuiz Augusto von Dentz static void hci_le_meta_evt(struct hci_dev *hdev, void *data,
735585b56857SLuiz Augusto von Dentz 			    struct sk_buff *skb, u16 *opcode, u8 *status,
735685b56857SLuiz Augusto von Dentz 			    hci_req_complete_t *req_complete,
735785b56857SLuiz Augusto von Dentz 			    hci_req_complete_skb_t *req_complete_skb)
7358fcd89c09SVille Tervo {
73593e54c589SLuiz Augusto von Dentz 	struct hci_ev_le_meta *ev = data;
736095118dd4SLuiz Augusto von Dentz 	const struct hci_le_ev *subev;
7361fcd89c09SVille Tervo 
736295118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "subevent 0x%2.2x", ev->subevent);
7363fcd89c09SVille Tervo 
736485b56857SLuiz Augusto von Dentz 	/* Only match event if command OGF is for LE */
73652af7aa66SLuiz Augusto von Dentz 	if (hdev->req_skb &&
73662af7aa66SLuiz Augusto von Dentz 	    hci_opcode_ogf(hci_skb_opcode(hdev->req_skb)) == 0x08 &&
73672af7aa66SLuiz Augusto von Dentz 	    hci_skb_event(hdev->req_skb) == ev->subevent) {
73682af7aa66SLuiz Augusto von Dentz 		*opcode = hci_skb_opcode(hdev->req_skb);
736985b56857SLuiz Augusto von Dentz 		hci_req_cmd_complete(hdev, *opcode, 0x00, req_complete,
737085b56857SLuiz Augusto von Dentz 				     req_complete_skb);
737185b56857SLuiz Augusto von Dentz 	}
737285b56857SLuiz Augusto von Dentz 
737395118dd4SLuiz Augusto von Dentz 	subev = &hci_le_ev_table[ev->subevent];
737495118dd4SLuiz Augusto von Dentz 	if (!subev->func)
737595118dd4SLuiz Augusto von Dentz 		return;
73761855d92dSMarcel Holtmann 
737795118dd4SLuiz Augusto von Dentz 	if (skb->len < subev->min_len) {
737895118dd4SLuiz Augusto von Dentz 		bt_dev_err(hdev, "unexpected subevent 0x%2.2x length: %u < %u",
737995118dd4SLuiz Augusto von Dentz 			   ev->subevent, skb->len, subev->min_len);
738095118dd4SLuiz Augusto von Dentz 		return;
7381fcd89c09SVille Tervo 	}
738295118dd4SLuiz Augusto von Dentz 
738395118dd4SLuiz Augusto von Dentz 	/* Just warn if the length is over max_len size it still be
738495118dd4SLuiz Augusto von Dentz 	 * possible to partially parse the event so leave to callback to
738595118dd4SLuiz Augusto von Dentz 	 * decide if that is acceptable.
738695118dd4SLuiz Augusto von Dentz 	 */
738795118dd4SLuiz Augusto von Dentz 	if (skb->len > subev->max_len)
738895118dd4SLuiz Augusto von Dentz 		bt_dev_warn(hdev, "unexpected subevent 0x%2.2x length: %u > %u",
738995118dd4SLuiz Augusto von Dentz 			    ev->subevent, skb->len, subev->max_len);
739095118dd4SLuiz Augusto von Dentz 	data = hci_le_ev_skb_pull(hdev, skb, ev->subevent, subev->min_len);
739195118dd4SLuiz Augusto von Dentz 	if (!data)
739295118dd4SLuiz Augusto von Dentz 		return;
739395118dd4SLuiz Augusto von Dentz 
739495118dd4SLuiz Augusto von Dentz 	subev->func(hdev, data, skb);
7395fcd89c09SVille Tervo }
7396fcd89c09SVille Tervo 
7397757aa0b5SJohan Hedberg static bool hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode,
7398757aa0b5SJohan Hedberg 				 u8 event, struct sk_buff *skb)
7399757aa0b5SJohan Hedberg {
7400757aa0b5SJohan Hedberg 	struct hci_ev_cmd_complete *ev;
7401757aa0b5SJohan Hedberg 	struct hci_event_hdr *hdr;
7402757aa0b5SJohan Hedberg 
7403757aa0b5SJohan Hedberg 	if (!skb)
7404757aa0b5SJohan Hedberg 		return false;
7405757aa0b5SJohan Hedberg 
7406e3f3a1aeSLuiz Augusto von Dentz 	hdr = hci_ev_skb_pull(hdev, skb, event, sizeof(*hdr));
7407e3f3a1aeSLuiz Augusto von Dentz 	if (!hdr)
7408757aa0b5SJohan Hedberg 		return false;
7409757aa0b5SJohan Hedberg 
7410757aa0b5SJohan Hedberg 	if (event) {
7411757aa0b5SJohan Hedberg 		if (hdr->evt != event)
7412757aa0b5SJohan Hedberg 			return false;
7413757aa0b5SJohan Hedberg 		return true;
7414757aa0b5SJohan Hedberg 	}
7415757aa0b5SJohan Hedberg 
741691641b79SZheng Yongjun 	/* Check if request ended in Command Status - no way to retrieve
74171629db9cSJohan Hedberg 	 * any extra parameters in this case.
74181629db9cSJohan Hedberg 	 */
74191629db9cSJohan Hedberg 	if (hdr->evt == HCI_EV_CMD_STATUS)
74201629db9cSJohan Hedberg 		return false;
74211629db9cSJohan Hedberg 
7422757aa0b5SJohan Hedberg 	if (hdr->evt != HCI_EV_CMD_COMPLETE) {
74232064ee33SMarcel Holtmann 		bt_dev_err(hdev, "last event is not cmd complete (0x%2.2x)",
74242064ee33SMarcel Holtmann 			   hdr->evt);
7425757aa0b5SJohan Hedberg 		return false;
7426757aa0b5SJohan Hedberg 	}
7427757aa0b5SJohan Hedberg 
7428e3f3a1aeSLuiz Augusto von Dentz 	ev = hci_cc_skb_pull(hdev, skb, opcode, sizeof(*ev));
7429e3f3a1aeSLuiz Augusto von Dentz 	if (!ev)
7430757aa0b5SJohan Hedberg 		return false;
7431757aa0b5SJohan Hedberg 
7432757aa0b5SJohan Hedberg 	if (opcode != __le16_to_cpu(ev->opcode)) {
7433757aa0b5SJohan Hedberg 		BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode,
7434757aa0b5SJohan Hedberg 		       __le16_to_cpu(ev->opcode));
7435757aa0b5SJohan Hedberg 		return false;
7436757aa0b5SJohan Hedberg 	}
7437757aa0b5SJohan Hedberg 
7438757aa0b5SJohan Hedberg 	return true;
7439757aa0b5SJohan Hedberg }
7440757aa0b5SJohan Hedberg 
74412f20216cSAbhishek Pandit-Subedi static void hci_store_wake_reason(struct hci_dev *hdev, u8 event,
74422f20216cSAbhishek Pandit-Subedi 				  struct sk_buff *skb)
74432f20216cSAbhishek Pandit-Subedi {
74442f20216cSAbhishek Pandit-Subedi 	struct hci_ev_le_advertising_info *adv;
74452f20216cSAbhishek Pandit-Subedi 	struct hci_ev_le_direct_adv_info *direct_adv;
7446b48b833fSLuiz Augusto von Dentz 	struct hci_ev_le_ext_adv_info *ext_adv;
74472f20216cSAbhishek Pandit-Subedi 	const struct hci_ev_conn_complete *conn_complete = (void *)skb->data;
74482f20216cSAbhishek Pandit-Subedi 	const struct hci_ev_conn_request *conn_request = (void *)skb->data;
74492f20216cSAbhishek Pandit-Subedi 
74502f20216cSAbhishek Pandit-Subedi 	hci_dev_lock(hdev);
74512f20216cSAbhishek Pandit-Subedi 
74522f20216cSAbhishek Pandit-Subedi 	/* If we are currently suspended and this is the first BT event seen,
74532f20216cSAbhishek Pandit-Subedi 	 * save the wake reason associated with the event.
74542f20216cSAbhishek Pandit-Subedi 	 */
74552f20216cSAbhishek Pandit-Subedi 	if (!hdev->suspended || hdev->wake_reason)
74562f20216cSAbhishek Pandit-Subedi 		goto unlock;
74572f20216cSAbhishek Pandit-Subedi 
74582f20216cSAbhishek Pandit-Subedi 	/* Default to remote wake. Values for wake_reason are documented in the
74592f20216cSAbhishek Pandit-Subedi 	 * Bluez mgmt api docs.
74602f20216cSAbhishek Pandit-Subedi 	 */
74612f20216cSAbhishek Pandit-Subedi 	hdev->wake_reason = MGMT_WAKE_REASON_REMOTE_WAKE;
74622f20216cSAbhishek Pandit-Subedi 
74632f20216cSAbhishek Pandit-Subedi 	/* Once configured for remote wakeup, we should only wake up for
74642f20216cSAbhishek Pandit-Subedi 	 * reconnections. It's useful to see which device is waking us up so
74652f20216cSAbhishek Pandit-Subedi 	 * keep track of the bdaddr of the connection event that woke us up.
74662f20216cSAbhishek Pandit-Subedi 	 */
74672f20216cSAbhishek Pandit-Subedi 	if (event == HCI_EV_CONN_REQUEST) {
74684a913967SZijun Hu 		bacpy(&hdev->wake_addr, &conn_request->bdaddr);
74692f20216cSAbhishek Pandit-Subedi 		hdev->wake_addr_type = BDADDR_BREDR;
74702f20216cSAbhishek Pandit-Subedi 	} else if (event == HCI_EV_CONN_COMPLETE) {
74714a913967SZijun Hu 		bacpy(&hdev->wake_addr, &conn_complete->bdaddr);
74722f20216cSAbhishek Pandit-Subedi 		hdev->wake_addr_type = BDADDR_BREDR;
74732f20216cSAbhishek Pandit-Subedi 	} else if (event == HCI_EV_LE_META) {
74742f20216cSAbhishek Pandit-Subedi 		struct hci_ev_le_meta *le_ev = (void *)skb->data;
74752f20216cSAbhishek Pandit-Subedi 		u8 subevent = le_ev->subevent;
74762f20216cSAbhishek Pandit-Subedi 		u8 *ptr = &skb->data[sizeof(*le_ev)];
74772f20216cSAbhishek Pandit-Subedi 		u8 num_reports = *ptr;
74782f20216cSAbhishek Pandit-Subedi 
74792f20216cSAbhishek Pandit-Subedi 		if ((subevent == HCI_EV_LE_ADVERTISING_REPORT ||
74802f20216cSAbhishek Pandit-Subedi 		     subevent == HCI_EV_LE_DIRECT_ADV_REPORT ||
74812f20216cSAbhishek Pandit-Subedi 		     subevent == HCI_EV_LE_EXT_ADV_REPORT) &&
74822f20216cSAbhishek Pandit-Subedi 		    num_reports) {
74832f20216cSAbhishek Pandit-Subedi 			adv = (void *)(ptr + 1);
74842f20216cSAbhishek Pandit-Subedi 			direct_adv = (void *)(ptr + 1);
74852f20216cSAbhishek Pandit-Subedi 			ext_adv = (void *)(ptr + 1);
74862f20216cSAbhishek Pandit-Subedi 
74872f20216cSAbhishek Pandit-Subedi 			switch (subevent) {
74882f20216cSAbhishek Pandit-Subedi 			case HCI_EV_LE_ADVERTISING_REPORT:
74892f20216cSAbhishek Pandit-Subedi 				bacpy(&hdev->wake_addr, &adv->bdaddr);
74902f20216cSAbhishek Pandit-Subedi 				hdev->wake_addr_type = adv->bdaddr_type;
74912f20216cSAbhishek Pandit-Subedi 				break;
74922f20216cSAbhishek Pandit-Subedi 			case HCI_EV_LE_DIRECT_ADV_REPORT:
74932f20216cSAbhishek Pandit-Subedi 				bacpy(&hdev->wake_addr, &direct_adv->bdaddr);
74942f20216cSAbhishek Pandit-Subedi 				hdev->wake_addr_type = direct_adv->bdaddr_type;
74952f20216cSAbhishek Pandit-Subedi 				break;
74962f20216cSAbhishek Pandit-Subedi 			case HCI_EV_LE_EXT_ADV_REPORT:
74972f20216cSAbhishek Pandit-Subedi 				bacpy(&hdev->wake_addr, &ext_adv->bdaddr);
74982f20216cSAbhishek Pandit-Subedi 				hdev->wake_addr_type = ext_adv->bdaddr_type;
74992f20216cSAbhishek Pandit-Subedi 				break;
75002f20216cSAbhishek Pandit-Subedi 			}
75012f20216cSAbhishek Pandit-Subedi 		}
75022f20216cSAbhishek Pandit-Subedi 	} else {
75032f20216cSAbhishek Pandit-Subedi 		hdev->wake_reason = MGMT_WAKE_REASON_UNEXPECTED;
75042f20216cSAbhishek Pandit-Subedi 	}
75052f20216cSAbhishek Pandit-Subedi 
75062f20216cSAbhishek Pandit-Subedi unlock:
75072f20216cSAbhishek Pandit-Subedi 	hci_dev_unlock(hdev);
75082f20216cSAbhishek Pandit-Subedi }
75092f20216cSAbhishek Pandit-Subedi 
75103e54c589SLuiz Augusto von Dentz #define HCI_EV_VL(_op, _func, _min_len, _max_len) \
75113e54c589SLuiz Augusto von Dentz [_op] = { \
75123e54c589SLuiz Augusto von Dentz 	.req = false, \
75133e54c589SLuiz Augusto von Dentz 	.func = _func, \
75143e54c589SLuiz Augusto von Dentz 	.min_len = _min_len, \
75153e54c589SLuiz Augusto von Dentz 	.max_len = _max_len, \
75163e54c589SLuiz Augusto von Dentz }
75173e54c589SLuiz Augusto von Dentz 
75183e54c589SLuiz Augusto von Dentz #define HCI_EV(_op, _func, _len) \
75193e54c589SLuiz Augusto von Dentz 	HCI_EV_VL(_op, _func, _len, _len)
75203e54c589SLuiz Augusto von Dentz 
75213e54c589SLuiz Augusto von Dentz #define HCI_EV_STATUS(_op, _func) \
75223e54c589SLuiz Augusto von Dentz 	HCI_EV(_op, _func, sizeof(struct hci_ev_status))
75233e54c589SLuiz Augusto von Dentz 
75243e54c589SLuiz Augusto von Dentz #define HCI_EV_REQ_VL(_op, _func, _min_len, _max_len) \
75253e54c589SLuiz Augusto von Dentz [_op] = { \
75263e54c589SLuiz Augusto von Dentz 	.req = true, \
75273e54c589SLuiz Augusto von Dentz 	.func_req = _func, \
75283e54c589SLuiz Augusto von Dentz 	.min_len = _min_len, \
75293e54c589SLuiz Augusto von Dentz 	.max_len = _max_len, \
75303e54c589SLuiz Augusto von Dentz }
75313e54c589SLuiz Augusto von Dentz 
75323e54c589SLuiz Augusto von Dentz #define HCI_EV_REQ(_op, _func, _len) \
75333e54c589SLuiz Augusto von Dentz 	HCI_EV_REQ_VL(_op, _func, _len, _len)
75343e54c589SLuiz Augusto von Dentz 
75353e54c589SLuiz Augusto von Dentz /* Entries in this table shall have their position according to the event opcode
75363e54c589SLuiz Augusto von Dentz  * they handle so the use of the macros above is recommend since it does attempt
75373e54c589SLuiz Augusto von Dentz  * to initialize at its proper index using Designated Initializers that way
75383e54c589SLuiz Augusto von Dentz  * events without a callback function don't have entered.
75393e54c589SLuiz Augusto von Dentz  */
75403e54c589SLuiz Augusto von Dentz static const struct hci_ev {
75413e54c589SLuiz Augusto von Dentz 	bool req;
75423e54c589SLuiz Augusto von Dentz 	union {
75433e54c589SLuiz Augusto von Dentz 		void (*func)(struct hci_dev *hdev, void *data,
75443e54c589SLuiz Augusto von Dentz 			     struct sk_buff *skb);
75453e54c589SLuiz Augusto von Dentz 		void (*func_req)(struct hci_dev *hdev, void *data,
75463e54c589SLuiz Augusto von Dentz 				 struct sk_buff *skb, u16 *opcode, u8 *status,
75473e54c589SLuiz Augusto von Dentz 				 hci_req_complete_t *req_complete,
75483e54c589SLuiz Augusto von Dentz 				 hci_req_complete_skb_t *req_complete_skb);
75493e54c589SLuiz Augusto von Dentz 	};
75503e54c589SLuiz Augusto von Dentz 	u16  min_len;
75513e54c589SLuiz Augusto von Dentz 	u16  max_len;
75523e54c589SLuiz Augusto von Dentz } hci_ev_table[U8_MAX + 1] = {
75533e54c589SLuiz Augusto von Dentz 	/* [0x01 = HCI_EV_INQUIRY_COMPLETE] */
75543e54c589SLuiz Augusto von Dentz 	HCI_EV_STATUS(HCI_EV_INQUIRY_COMPLETE, hci_inquiry_complete_evt),
75553e54c589SLuiz Augusto von Dentz 	/* [0x02 = HCI_EV_INQUIRY_RESULT] */
75563e54c589SLuiz Augusto von Dentz 	HCI_EV_VL(HCI_EV_INQUIRY_RESULT, hci_inquiry_result_evt,
75573e54c589SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_inquiry_result), HCI_MAX_EVENT_SIZE),
75583e54c589SLuiz Augusto von Dentz 	/* [0x03 = HCI_EV_CONN_COMPLETE] */
75593e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_CONN_COMPLETE, hci_conn_complete_evt,
75603e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_conn_complete)),
75613e54c589SLuiz Augusto von Dentz 	/* [0x04 = HCI_EV_CONN_REQUEST] */
75623e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_CONN_REQUEST, hci_conn_request_evt,
75633e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_conn_request)),
75643e54c589SLuiz Augusto von Dentz 	/* [0x05 = HCI_EV_DISCONN_COMPLETE] */
75653e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_DISCONN_COMPLETE, hci_disconn_complete_evt,
75663e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_disconn_complete)),
75673e54c589SLuiz Augusto von Dentz 	/* [0x06 = HCI_EV_AUTH_COMPLETE] */
75683e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_AUTH_COMPLETE, hci_auth_complete_evt,
75693e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_auth_complete)),
75703e54c589SLuiz Augusto von Dentz 	/* [0x07 = HCI_EV_REMOTE_NAME] */
75713e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_REMOTE_NAME, hci_remote_name_evt,
75723e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_remote_name)),
75733e54c589SLuiz Augusto von Dentz 	/* [0x08 = HCI_EV_ENCRYPT_CHANGE] */
75743e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_ENCRYPT_CHANGE, hci_encrypt_change_evt,
75753e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_encrypt_change)),
75763e54c589SLuiz Augusto von Dentz 	/* [0x09 = HCI_EV_CHANGE_LINK_KEY_COMPLETE] */
75773e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_CHANGE_LINK_KEY_COMPLETE,
75783e54c589SLuiz Augusto von Dentz 	       hci_change_link_key_complete_evt,
75793e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_change_link_key_complete)),
75803e54c589SLuiz Augusto von Dentz 	/* [0x0b = HCI_EV_REMOTE_FEATURES] */
75813e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_REMOTE_FEATURES, hci_remote_features_evt,
75823e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_remote_features)),
75833e54c589SLuiz Augusto von Dentz 	/* [0x0e = HCI_EV_CMD_COMPLETE] */
75843e54c589SLuiz Augusto von Dentz 	HCI_EV_REQ_VL(HCI_EV_CMD_COMPLETE, hci_cmd_complete_evt,
75853e54c589SLuiz Augusto von Dentz 		      sizeof(struct hci_ev_cmd_complete), HCI_MAX_EVENT_SIZE),
75863e54c589SLuiz Augusto von Dentz 	/* [0x0f = HCI_EV_CMD_STATUS] */
75873e54c589SLuiz Augusto von Dentz 	HCI_EV_REQ(HCI_EV_CMD_STATUS, hci_cmd_status_evt,
75883e54c589SLuiz Augusto von Dentz 		   sizeof(struct hci_ev_cmd_status)),
75893e54c589SLuiz Augusto von Dentz 	/* [0x10 = HCI_EV_CMD_STATUS] */
75903e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_HARDWARE_ERROR, hci_hardware_error_evt,
75913e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_hardware_error)),
75923e54c589SLuiz Augusto von Dentz 	/* [0x12 = HCI_EV_ROLE_CHANGE] */
75933e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_ROLE_CHANGE, hci_role_change_evt,
75943e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_role_change)),
75953e54c589SLuiz Augusto von Dentz 	/* [0x13 = HCI_EV_NUM_COMP_PKTS] */
75963e54c589SLuiz Augusto von Dentz 	HCI_EV_VL(HCI_EV_NUM_COMP_PKTS, hci_num_comp_pkts_evt,
75973e54c589SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_num_comp_pkts), HCI_MAX_EVENT_SIZE),
75983e54c589SLuiz Augusto von Dentz 	/* [0x14 = HCI_EV_MODE_CHANGE] */
75993e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_MODE_CHANGE, hci_mode_change_evt,
76003e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_mode_change)),
76013e54c589SLuiz Augusto von Dentz 	/* [0x16 = HCI_EV_PIN_CODE_REQ] */
76023e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_PIN_CODE_REQ, hci_pin_code_request_evt,
76033e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_pin_code_req)),
76043e54c589SLuiz Augusto von Dentz 	/* [0x17 = HCI_EV_LINK_KEY_REQ] */
76053e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_LINK_KEY_REQ, hci_link_key_request_evt,
76063e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_link_key_req)),
76073e54c589SLuiz Augusto von Dentz 	/* [0x18 = HCI_EV_LINK_KEY_NOTIFY] */
76083e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_LINK_KEY_NOTIFY, hci_link_key_notify_evt,
76093e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_link_key_notify)),
76103e54c589SLuiz Augusto von Dentz 	/* [0x1c = HCI_EV_CLOCK_OFFSET] */
76113e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_CLOCK_OFFSET, hci_clock_offset_evt,
76123e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_clock_offset)),
76133e54c589SLuiz Augusto von Dentz 	/* [0x1d = HCI_EV_PKT_TYPE_CHANGE] */
76143e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_PKT_TYPE_CHANGE, hci_pkt_type_change_evt,
76153e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_pkt_type_change)),
76163e54c589SLuiz Augusto von Dentz 	/* [0x20 = HCI_EV_PSCAN_REP_MODE] */
76173e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_PSCAN_REP_MODE, hci_pscan_rep_mode_evt,
76183e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_pscan_rep_mode)),
76193e54c589SLuiz Augusto von Dentz 	/* [0x22 = HCI_EV_INQUIRY_RESULT_WITH_RSSI] */
76203e54c589SLuiz Augusto von Dentz 	HCI_EV_VL(HCI_EV_INQUIRY_RESULT_WITH_RSSI,
76213e54c589SLuiz Augusto von Dentz 		  hci_inquiry_result_with_rssi_evt,
76223e54c589SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_inquiry_result_rssi),
76233e54c589SLuiz Augusto von Dentz 		  HCI_MAX_EVENT_SIZE),
76243e54c589SLuiz Augusto von Dentz 	/* [0x23 = HCI_EV_REMOTE_EXT_FEATURES] */
76253e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_REMOTE_EXT_FEATURES, hci_remote_ext_features_evt,
76263e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_remote_ext_features)),
76273e54c589SLuiz Augusto von Dentz 	/* [0x2c = HCI_EV_SYNC_CONN_COMPLETE] */
76283e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_SYNC_CONN_COMPLETE, hci_sync_conn_complete_evt,
76293e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_sync_conn_complete)),
76303e54c589SLuiz Augusto von Dentz 	/* [0x2d = HCI_EV_EXTENDED_INQUIRY_RESULT] */
76313e54c589SLuiz Augusto von Dentz 	HCI_EV_VL(HCI_EV_EXTENDED_INQUIRY_RESULT,
76323e54c589SLuiz Augusto von Dentz 		  hci_extended_inquiry_result_evt,
76333e54c589SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_ext_inquiry_result), HCI_MAX_EVENT_SIZE),
76343e54c589SLuiz Augusto von Dentz 	/* [0x30 = HCI_EV_KEY_REFRESH_COMPLETE] */
76353e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_KEY_REFRESH_COMPLETE, hci_key_refresh_complete_evt,
76363e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_key_refresh_complete)),
76373e54c589SLuiz Augusto von Dentz 	/* [0x31 = HCI_EV_IO_CAPA_REQUEST] */
76383e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_IO_CAPA_REQUEST, hci_io_capa_request_evt,
76393e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_io_capa_request)),
76403e54c589SLuiz Augusto von Dentz 	/* [0x32 = HCI_EV_IO_CAPA_REPLY] */
76413e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_IO_CAPA_REPLY, hci_io_capa_reply_evt,
76423e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_io_capa_reply)),
76433e54c589SLuiz Augusto von Dentz 	/* [0x33 = HCI_EV_USER_CONFIRM_REQUEST] */
76443e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_USER_CONFIRM_REQUEST, hci_user_confirm_request_evt,
76453e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_user_confirm_req)),
76463e54c589SLuiz Augusto von Dentz 	/* [0x34 = HCI_EV_USER_PASSKEY_REQUEST] */
76473e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_USER_PASSKEY_REQUEST, hci_user_passkey_request_evt,
76483e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_user_passkey_req)),
76493e54c589SLuiz Augusto von Dentz 	/* [0x35 = HCI_EV_REMOTE_OOB_DATA_REQUEST] */
76503e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_REMOTE_OOB_DATA_REQUEST, hci_remote_oob_data_request_evt,
76513e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_remote_oob_data_request)),
76523e54c589SLuiz Augusto von Dentz 	/* [0x36 = HCI_EV_SIMPLE_PAIR_COMPLETE] */
76533e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_SIMPLE_PAIR_COMPLETE, hci_simple_pair_complete_evt,
76543e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_simple_pair_complete)),
76553e54c589SLuiz Augusto von Dentz 	/* [0x3b = HCI_EV_USER_PASSKEY_NOTIFY] */
76563e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_USER_PASSKEY_NOTIFY, hci_user_passkey_notify_evt,
76573e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_user_passkey_notify)),
76583e54c589SLuiz Augusto von Dentz 	/* [0x3c = HCI_EV_KEYPRESS_NOTIFY] */
76593e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_KEYPRESS_NOTIFY, hci_keypress_notify_evt,
76603e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_keypress_notify)),
76613e54c589SLuiz Augusto von Dentz 	/* [0x3d = HCI_EV_REMOTE_HOST_FEATURES] */
76623e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_REMOTE_HOST_FEATURES, hci_remote_host_features_evt,
76633e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_remote_host_features)),
76643e54c589SLuiz Augusto von Dentz 	/* [0x3e = HCI_EV_LE_META] */
766585b56857SLuiz Augusto von Dentz 	HCI_EV_REQ_VL(HCI_EV_LE_META, hci_le_meta_evt,
76663e54c589SLuiz Augusto von Dentz 		      sizeof(struct hci_ev_le_meta), HCI_MAX_EVENT_SIZE),
76673e54c589SLuiz Augusto von Dentz #if IS_ENABLED(CONFIG_BT_HS)
76683e54c589SLuiz Augusto von Dentz 	/* [0x40 = HCI_EV_PHY_LINK_COMPLETE] */
76693e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_PHY_LINK_COMPLETE, hci_phy_link_complete_evt,
76703e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_phy_link_complete)),
76713e54c589SLuiz Augusto von Dentz 	/* [0x41 = HCI_EV_CHANNEL_SELECTED] */
76723e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_CHANNEL_SELECTED, hci_chan_selected_evt,
76733e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_channel_selected)),
76743e54c589SLuiz Augusto von Dentz 	/* [0x42 = HCI_EV_DISCONN_PHY_LINK_COMPLETE] */
76753e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE,
76763e54c589SLuiz Augusto von Dentz 	       hci_disconn_loglink_complete_evt,
76773e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_disconn_logical_link_complete)),
76783e54c589SLuiz Augusto von Dentz 	/* [0x45 = HCI_EV_LOGICAL_LINK_COMPLETE] */
76793e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_LOGICAL_LINK_COMPLETE, hci_loglink_complete_evt,
76803e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_logical_link_complete)),
76813e54c589SLuiz Augusto von Dentz 	/* [0x46 = HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE] */
76823e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_DISCONN_PHY_LINK_COMPLETE,
76833e54c589SLuiz Augusto von Dentz 	       hci_disconn_phylink_complete_evt,
76843e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_disconn_phy_link_complete)),
76853e54c589SLuiz Augusto von Dentz #endif
76863e54c589SLuiz Augusto von Dentz 	/* [0x48 = HCI_EV_NUM_COMP_BLOCKS] */
76873e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_NUM_COMP_BLOCKS, hci_num_comp_blocks_evt,
76883e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_num_comp_blocks)),
76893e54c589SLuiz Augusto von Dentz 	/* [0xff = HCI_EV_VENDOR] */
7690314d8cd2SLuiz Augusto von Dentz 	HCI_EV_VL(HCI_EV_VENDOR, msft_vendor_evt, 0, HCI_MAX_EVENT_SIZE),
76913e54c589SLuiz Augusto von Dentz };
76923e54c589SLuiz Augusto von Dentz 
76933e54c589SLuiz Augusto von Dentz static void hci_event_func(struct hci_dev *hdev, u8 event, struct sk_buff *skb,
76943e54c589SLuiz Augusto von Dentz 			   u16 *opcode, u8 *status,
76953e54c589SLuiz Augusto von Dentz 			   hci_req_complete_t *req_complete,
76963e54c589SLuiz Augusto von Dentz 			   hci_req_complete_skb_t *req_complete_skb)
76973e54c589SLuiz Augusto von Dentz {
76983e54c589SLuiz Augusto von Dentz 	const struct hci_ev *ev = &hci_ev_table[event];
76993e54c589SLuiz Augusto von Dentz 	void *data;
77003e54c589SLuiz Augusto von Dentz 
77013e54c589SLuiz Augusto von Dentz 	if (!ev->func)
77023e54c589SLuiz Augusto von Dentz 		return;
77033e54c589SLuiz Augusto von Dentz 
77043e54c589SLuiz Augusto von Dentz 	if (skb->len < ev->min_len) {
77053e54c589SLuiz Augusto von Dentz 		bt_dev_err(hdev, "unexpected event 0x%2.2x length: %u < %u",
77063e54c589SLuiz Augusto von Dentz 			   event, skb->len, ev->min_len);
77073e54c589SLuiz Augusto von Dentz 		return;
77083e54c589SLuiz Augusto von Dentz 	}
77093e54c589SLuiz Augusto von Dentz 
77103e54c589SLuiz Augusto von Dentz 	/* Just warn if the length is over max_len size it still be
77113e54c589SLuiz Augusto von Dentz 	 * possible to partially parse the event so leave to callback to
77123e54c589SLuiz Augusto von Dentz 	 * decide if that is acceptable.
77133e54c589SLuiz Augusto von Dentz 	 */
77143e54c589SLuiz Augusto von Dentz 	if (skb->len > ev->max_len)
7715314d8cd2SLuiz Augusto von Dentz 		bt_dev_warn_ratelimited(hdev,
7716314d8cd2SLuiz Augusto von Dentz 					"unexpected event 0x%2.2x length: %u > %u",
77173e54c589SLuiz Augusto von Dentz 					event, skb->len, ev->max_len);
77183e54c589SLuiz Augusto von Dentz 
77193e54c589SLuiz Augusto von Dentz 	data = hci_ev_skb_pull(hdev, skb, event, ev->min_len);
77203e54c589SLuiz Augusto von Dentz 	if (!data)
77213e54c589SLuiz Augusto von Dentz 		return;
77223e54c589SLuiz Augusto von Dentz 
77233e54c589SLuiz Augusto von Dentz 	if (ev->req)
77243e54c589SLuiz Augusto von Dentz 		ev->func_req(hdev, data, skb, opcode, status, req_complete,
77253e54c589SLuiz Augusto von Dentz 			     req_complete_skb);
77263e54c589SLuiz Augusto von Dentz 	else
77273e54c589SLuiz Augusto von Dentz 		ev->func(hdev, data, skb);
77283e54c589SLuiz Augusto von Dentz }
77293e54c589SLuiz Augusto von Dentz 
77301da177e4SLinus Torvalds void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
77311da177e4SLinus Torvalds {
7732a9de9248SMarcel Holtmann 	struct hci_event_hdr *hdr = (void *) skb->data;
7733e6214487SJohan Hedberg 	hci_req_complete_t req_complete = NULL;
7734e6214487SJohan Hedberg 	hci_req_complete_skb_t req_complete_skb = NULL;
7735e6214487SJohan Hedberg 	struct sk_buff *orig_skb = NULL;
7736e3f3a1aeSLuiz Augusto von Dentz 	u8 status = 0, event, req_evt = 0;
7737e6214487SJohan Hedberg 	u16 opcode = HCI_OP_NOP;
77381da177e4SLinus Torvalds 
7739e3f3a1aeSLuiz Augusto von Dentz 	if (skb->len < sizeof(*hdr)) {
7740e3f3a1aeSLuiz Augusto von Dentz 		bt_dev_err(hdev, "Malformed HCI Event");
7741e3f3a1aeSLuiz Augusto von Dentz 		goto done;
7742e3f3a1aeSLuiz Augusto von Dentz 	}
7743e3f3a1aeSLuiz Augusto von Dentz 
7744dfe6d5c3SLuiz Augusto von Dentz 	kfree_skb(hdev->recv_event);
7745dfe6d5c3SLuiz Augusto von Dentz 	hdev->recv_event = skb_clone(skb, GFP_KERNEL);
7746dfe6d5c3SLuiz Augusto von Dentz 
7747e3f3a1aeSLuiz Augusto von Dentz 	event = hdr->evt;
774808bb4da9SAlain Michaud 	if (!event) {
77493e54c589SLuiz Augusto von Dentz 		bt_dev_warn(hdev, "Received unexpected HCI Event 0x%2.2x",
77503e54c589SLuiz Augusto von Dentz 			    event);
775108bb4da9SAlain Michaud 		goto done;
775208bb4da9SAlain Michaud 	}
775308bb4da9SAlain Michaud 
775485b56857SLuiz Augusto von Dentz 	/* Only match event if command OGF is not for LE */
77552af7aa66SLuiz Augusto von Dentz 	if (hdev->req_skb &&
77562af7aa66SLuiz Augusto von Dentz 	    hci_opcode_ogf(hci_skb_opcode(hdev->req_skb)) != 0x08 &&
77572af7aa66SLuiz Augusto von Dentz 	    hci_skb_event(hdev->req_skb) == event) {
77582af7aa66SLuiz Augusto von Dentz 		hci_req_cmd_complete(hdev, hci_skb_opcode(hdev->req_skb),
775985b56857SLuiz Augusto von Dentz 				     status, &req_complete, &req_complete_skb);
7760757aa0b5SJohan Hedberg 		req_evt = event;
776102350a72SJohan Hedberg 	}
776202350a72SJohan Hedberg 
7763e6214487SJohan Hedberg 	/* If it looks like we might end up having to call
7764e6214487SJohan Hedberg 	 * req_complete_skb, store a pristine copy of the skb since the
7765e6214487SJohan Hedberg 	 * various handlers may modify the original one through
7766e6214487SJohan Hedberg 	 * skb_pull() calls, etc.
7767e6214487SJohan Hedberg 	 */
7768e6214487SJohan Hedberg 	if (req_complete_skb || event == HCI_EV_CMD_STATUS ||
7769e6214487SJohan Hedberg 	    event == HCI_EV_CMD_COMPLETE)
7770e6214487SJohan Hedberg 		orig_skb = skb_clone(skb, GFP_KERNEL);
7771e6214487SJohan Hedberg 
7772e6214487SJohan Hedberg 	skb_pull(skb, HCI_EVENT_HDR_SIZE);
7773e6214487SJohan Hedberg 
77742f20216cSAbhishek Pandit-Subedi 	/* Store wake reason if we're suspended */
77752f20216cSAbhishek Pandit-Subedi 	hci_store_wake_reason(hdev, event, skb);
77762f20216cSAbhishek Pandit-Subedi 
77773e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "event 0x%2.2x", event);
77781da177e4SLinus Torvalds 
77793e54c589SLuiz Augusto von Dentz 	hci_event_func(hdev, event, skb, &opcode, &status, &req_complete,
7780e6214487SJohan Hedberg 		       &req_complete_skb);
77811da177e4SLinus Torvalds 
7782757aa0b5SJohan Hedberg 	if (req_complete) {
7783e6214487SJohan Hedberg 		req_complete(hdev, status, opcode);
7784757aa0b5SJohan Hedberg 	} else if (req_complete_skb) {
7785757aa0b5SJohan Hedberg 		if (!hci_get_cmd_complete(hdev, opcode, req_evt, orig_skb)) {
7786757aa0b5SJohan Hedberg 			kfree_skb(orig_skb);
7787757aa0b5SJohan Hedberg 			orig_skb = NULL;
7788757aa0b5SJohan Hedberg 		}
7789e6214487SJohan Hedberg 		req_complete_skb(hdev, status, opcode, orig_skb);
7790757aa0b5SJohan Hedberg 	}
7791e6214487SJohan Hedberg 
779208bb4da9SAlain Michaud done:
7793e6214487SJohan Hedberg 	kfree_skb(orig_skb);
77941da177e4SLinus Torvalds 	kfree_skb(skb);
77951da177e4SLinus Torvalds 	hdev->stat.evt_rx++;
77961da177e4SLinus Torvalds }
7797