xref: /openbmc/linux/net/bluetooth/hci_event.c (revision ad38e55e)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds    BlueZ - Bluetooth protocol stack for Linux
32d0a0346SRon Shaffer    Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
41da177e4SLinus Torvalds 
51da177e4SLinus Torvalds    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
61da177e4SLinus Torvalds 
71da177e4SLinus Torvalds    This program is free software; you can redistribute it and/or modify
81da177e4SLinus Torvalds    it under the terms of the GNU General Public License version 2 as
91da177e4SLinus Torvalds    published by the Free Software Foundation;
101da177e4SLinus Torvalds 
111da177e4SLinus Torvalds    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
121da177e4SLinus Torvalds    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
131da177e4SLinus Torvalds    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
141da177e4SLinus Torvalds    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
151da177e4SLinus Torvalds    CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
161da177e4SLinus Torvalds    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
171da177e4SLinus Torvalds    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
181da177e4SLinus Torvalds    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
191da177e4SLinus Torvalds 
201da177e4SLinus Torvalds    ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
211da177e4SLinus Torvalds    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
221da177e4SLinus Torvalds    SOFTWARE IS DISCLAIMED.
231da177e4SLinus Torvalds */
241da177e4SLinus Torvalds 
251da177e4SLinus Torvalds /* Bluetooth HCI event handling. */
261da177e4SLinus Torvalds 
271da177e4SLinus Torvalds #include <asm/unaligned.h>
281da177e4SLinus Torvalds 
291da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
301da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
31f0d6a0eaSMikel Astiz #include <net/bluetooth/mgmt.h>
327ef9fbf0SMarcel Holtmann 
330857dd3bSJohan Hedberg #include "hci_request.h"
3423b9ceb7SMarcel Holtmann #include "hci_debugfs.h"
357024728eSMarcel Holtmann #include "a2mp.h"
367ef9fbf0SMarcel Holtmann #include "amp.h"
372ceba539SJohan Hedberg #include "smp.h"
38145373cbSMiao-chen Chou #include "msft.h"
3901ce70b0SLuiz Augusto von Dentz #include "eir.h"
401da177e4SLinus Torvalds 
41aa5b0345SMarcel Holtmann #define ZERO_KEY "\x00\x00\x00\x00\x00\x00\x00\x00" \
42aa5b0345SMarcel Holtmann 		 "\x00\x00\x00\x00\x00\x00\x00\x00"
43aa5b0345SMarcel Holtmann 
44c45074d6SLuiz Augusto von Dentz #define secs_to_jiffies(_secs) msecs_to_jiffies((_secs) * 1000)
45c45074d6SLuiz Augusto von Dentz 
461da177e4SLinus Torvalds /* Handle HCI Event packets */
471da177e4SLinus Torvalds 
48ae61a10dSLuiz Augusto von Dentz static void *hci_ev_skb_pull(struct hci_dev *hdev, struct sk_buff *skb,
49ae61a10dSLuiz Augusto von Dentz 			     u8 ev, size_t len)
50ae61a10dSLuiz Augusto von Dentz {
51ae61a10dSLuiz Augusto von Dentz 	void *data;
52ae61a10dSLuiz Augusto von Dentz 
53ae61a10dSLuiz Augusto von Dentz 	data = skb_pull_data(skb, len);
54ae61a10dSLuiz Augusto von Dentz 	if (!data)
55ae61a10dSLuiz Augusto von Dentz 		bt_dev_err(hdev, "Malformed Event: 0x%2.2x", ev);
56ae61a10dSLuiz Augusto von Dentz 
57ae61a10dSLuiz Augusto von Dentz 	return data;
58ae61a10dSLuiz Augusto von Dentz }
59ae61a10dSLuiz Augusto von Dentz 
60e3f3a1aeSLuiz Augusto von Dentz static void *hci_cc_skb_pull(struct hci_dev *hdev, struct sk_buff *skb,
61e3f3a1aeSLuiz Augusto von Dentz 			     u16 op, size_t len)
62e3f3a1aeSLuiz Augusto von Dentz {
63e3f3a1aeSLuiz Augusto von Dentz 	void *data;
64e3f3a1aeSLuiz Augusto von Dentz 
65e3f3a1aeSLuiz Augusto von Dentz 	data = skb_pull_data(skb, len);
66e3f3a1aeSLuiz Augusto von Dentz 	if (!data)
67e3f3a1aeSLuiz Augusto von Dentz 		bt_dev_err(hdev, "Malformed Command Complete: 0x%4.4x", op);
68e3f3a1aeSLuiz Augusto von Dentz 
69e3f3a1aeSLuiz Augusto von Dentz 	return data;
70e3f3a1aeSLuiz Augusto von Dentz }
71e3f3a1aeSLuiz Augusto von Dentz 
7212cfe417SLuiz Augusto von Dentz static void *hci_le_ev_skb_pull(struct hci_dev *hdev, struct sk_buff *skb,
7312cfe417SLuiz Augusto von Dentz 				u8 ev, size_t len)
7412cfe417SLuiz Augusto von Dentz {
7512cfe417SLuiz Augusto von Dentz 	void *data;
7612cfe417SLuiz Augusto von Dentz 
7712cfe417SLuiz Augusto von Dentz 	data = skb_pull_data(skb, len);
7812cfe417SLuiz Augusto von Dentz 	if (!data)
7912cfe417SLuiz Augusto von Dentz 		bt_dev_err(hdev, "Malformed LE Event: 0x%2.2x", ev);
8012cfe417SLuiz Augusto von Dentz 
8112cfe417SLuiz Augusto von Dentz 	return data;
8212cfe417SLuiz Augusto von Dentz }
8312cfe417SLuiz Augusto von Dentz 
84c8992cffSLuiz Augusto von Dentz static u8 hci_cc_inquiry_cancel(struct hci_dev *hdev, void *data,
85c8992cffSLuiz Augusto von Dentz 				struct sk_buff *skb)
861da177e4SLinus Torvalds {
87c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
88e3f3a1aeSLuiz Augusto von Dentz 
89e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
901da177e4SLinus Torvalds 
91adf1d692SSonny Sasaka 	/* It is possible that we receive Inquiry Complete event right
92adf1d692SSonny Sasaka 	 * before we receive Inquiry Cancel Command Complete event, in
93adf1d692SSonny Sasaka 	 * which case the latter event should have status of Command
94adf1d692SSonny Sasaka 	 * Disallowed (0x0c). This should not be treated as error, since
95adf1d692SSonny Sasaka 	 * we actually achieve what Inquiry Cancel wants to achieve,
96adf1d692SSonny Sasaka 	 * which is to end the last Inquiry session.
97adf1d692SSonny Sasaka 	 */
98e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status == 0x0c && !test_bit(HCI_INQUIRY, &hdev->flags)) {
99adf1d692SSonny Sasaka 		bt_dev_warn(hdev, "Ignoring error of Inquiry Cancel command");
100e3f3a1aeSLuiz Augusto von Dentz 		rp->status = 0x00;
101adf1d692SSonny Sasaka 	}
102adf1d692SSonny Sasaka 
103e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
104c8992cffSLuiz Augusto von Dentz 		return rp->status;
1051da177e4SLinus Torvalds 
10689352e7dSAndre Guedes 	clear_bit(HCI_INQUIRY, &hdev->flags);
1074e857c58SPeter Zijlstra 	smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */
1083e13fa1eSAndre Guedes 	wake_up_bit(&hdev->flags, HCI_INQUIRY);
10989352e7dSAndre Guedes 
11050143a43SJohan Hedberg 	hci_dev_lock(hdev);
111168b8a25SJakub Pawlowski 	/* Set discovery state to stopped if we're not doing LE active
112168b8a25SJakub Pawlowski 	 * scanning.
113168b8a25SJakub Pawlowski 	 */
114168b8a25SJakub Pawlowski 	if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
115168b8a25SJakub Pawlowski 	    hdev->le_scan_type != LE_SCAN_ACTIVE)
11650143a43SJohan Hedberg 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
11750143a43SJohan Hedberg 	hci_dev_unlock(hdev);
11850143a43SJohan Hedberg 
119a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
120c8992cffSLuiz Augusto von Dentz 
121c8992cffSLuiz Augusto von Dentz 	return rp->status;
1221da177e4SLinus Torvalds }
1236bd57416SMarcel Holtmann 
124c8992cffSLuiz Augusto von Dentz static u8 hci_cc_periodic_inq(struct hci_dev *hdev, void *data,
125c8992cffSLuiz Augusto von Dentz 			      struct sk_buff *skb)
1264d93483bSAndre Guedes {
127c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
128ae854a70SAndre Guedes 
129e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
130e3f3a1aeSLuiz Augusto von Dentz 
131e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
132c8992cffSLuiz Augusto von Dentz 		return rp->status;
133ae854a70SAndre Guedes 
134a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_PERIODIC_INQ);
135c8992cffSLuiz Augusto von Dentz 
136c8992cffSLuiz Augusto von Dentz 	return rp->status;
1374d93483bSAndre Guedes }
1384d93483bSAndre Guedes 
139c8992cffSLuiz Augusto von Dentz static u8 hci_cc_exit_periodic_inq(struct hci_dev *hdev, void *data,
140c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
1411da177e4SLinus Torvalds {
142c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
143a9de9248SMarcel Holtmann 
144e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
145e3f3a1aeSLuiz Augusto von Dentz 
146e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
147c8992cffSLuiz Augusto von Dentz 		return rp->status;
148a9de9248SMarcel Holtmann 
149a358dc11SMarcel Holtmann 	hci_dev_clear_flag(hdev, HCI_PERIODIC_INQ);
150ae854a70SAndre Guedes 
151a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
152c8992cffSLuiz Augusto von Dentz 
153c8992cffSLuiz Augusto von Dentz 	return rp->status;
154a9de9248SMarcel Holtmann }
155a9de9248SMarcel Holtmann 
156c8992cffSLuiz Augusto von Dentz static u8 hci_cc_remote_name_req_cancel(struct hci_dev *hdev, void *data,
157807deac2SGustavo Padovan 					struct sk_buff *skb)
158a9de9248SMarcel Holtmann {
159c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
160e3f3a1aeSLuiz Augusto von Dentz 
161e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
162c8992cffSLuiz Augusto von Dentz 
163c8992cffSLuiz Augusto von Dentz 	return rp->status;
164a9de9248SMarcel Holtmann }
165a9de9248SMarcel Holtmann 
166c8992cffSLuiz Augusto von Dentz static u8 hci_cc_role_discovery(struct hci_dev *hdev, void *data,
167c8992cffSLuiz Augusto von Dentz 				struct sk_buff *skb)
168a9de9248SMarcel Holtmann {
169c8992cffSLuiz Augusto von Dentz 	struct hci_rp_role_discovery *rp = data;
1701da177e4SLinus Torvalds 	struct hci_conn *conn;
1711da177e4SLinus Torvalds 
172e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1731da177e4SLinus Torvalds 
174a9de9248SMarcel Holtmann 	if (rp->status)
175c8992cffSLuiz Augusto von Dentz 		return rp->status;
1761da177e4SLinus Torvalds 
1771da177e4SLinus Torvalds 	hci_dev_lock(hdev);
1781da177e4SLinus Torvalds 
179a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
18040bef302SJohan Hedberg 	if (conn)
18140bef302SJohan Hedberg 		conn->role = rp->role;
1821da177e4SLinus Torvalds 
1831da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
184c8992cffSLuiz Augusto von Dentz 
185c8992cffSLuiz Augusto von Dentz 	return rp->status;
186a9de9248SMarcel Holtmann }
1871da177e4SLinus Torvalds 
188c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_link_policy(struct hci_dev *hdev, void *data,
189c8992cffSLuiz Augusto von Dentz 				  struct sk_buff *skb)
190e4e8e37cSMarcel Holtmann {
191c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_link_policy *rp = data;
192e4e8e37cSMarcel Holtmann 	struct hci_conn *conn;
193e4e8e37cSMarcel Holtmann 
194e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
195e4e8e37cSMarcel Holtmann 
196e4e8e37cSMarcel Holtmann 	if (rp->status)
197c8992cffSLuiz Augusto von Dentz 		return rp->status;
198e4e8e37cSMarcel Holtmann 
199e4e8e37cSMarcel Holtmann 	hci_dev_lock(hdev);
200e4e8e37cSMarcel Holtmann 
201e4e8e37cSMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
202e4e8e37cSMarcel Holtmann 	if (conn)
203e4e8e37cSMarcel Holtmann 		conn->link_policy = __le16_to_cpu(rp->policy);
204e4e8e37cSMarcel Holtmann 
205e4e8e37cSMarcel Holtmann 	hci_dev_unlock(hdev);
206c8992cffSLuiz Augusto von Dentz 
207c8992cffSLuiz Augusto von Dentz 	return rp->status;
208e4e8e37cSMarcel Holtmann }
209e4e8e37cSMarcel Holtmann 
210c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_link_policy(struct hci_dev *hdev, void *data,
211c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
212a9de9248SMarcel Holtmann {
213c8992cffSLuiz Augusto von Dentz 	struct hci_rp_write_link_policy *rp = data;
214a9de9248SMarcel Holtmann 	struct hci_conn *conn;
215a9de9248SMarcel Holtmann 	void *sent;
216a9de9248SMarcel Holtmann 
217e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
218a9de9248SMarcel Holtmann 
219a9de9248SMarcel Holtmann 	if (rp->status)
220c8992cffSLuiz Augusto von Dentz 		return rp->status;
221a9de9248SMarcel Holtmann 
222a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
22304837f64SMarcel Holtmann 	if (!sent)
224c8992cffSLuiz Augusto von Dentz 		return rp->status;
22504837f64SMarcel Holtmann 
22604837f64SMarcel Holtmann 	hci_dev_lock(hdev);
22704837f64SMarcel Holtmann 
228a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
229e4e8e37cSMarcel Holtmann 	if (conn)
23083985319SHarvey Harrison 		conn->link_policy = get_unaligned_le16(sent + 2);
23104837f64SMarcel Holtmann 
23204837f64SMarcel Holtmann 	hci_dev_unlock(hdev);
233c8992cffSLuiz Augusto von Dentz 
234c8992cffSLuiz Augusto von Dentz 	return rp->status;
2351da177e4SLinus Torvalds }
2361da177e4SLinus Torvalds 
237c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_def_link_policy(struct hci_dev *hdev, void *data,
238807deac2SGustavo Padovan 				      struct sk_buff *skb)
239e4e8e37cSMarcel Holtmann {
240c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_def_link_policy *rp = data;
241e3f3a1aeSLuiz Augusto von Dentz 
242e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
243e4e8e37cSMarcel Holtmann 
244e4e8e37cSMarcel Holtmann 	if (rp->status)
245c8992cffSLuiz Augusto von Dentz 		return rp->status;
246e4e8e37cSMarcel Holtmann 
247e4e8e37cSMarcel Holtmann 	hdev->link_policy = __le16_to_cpu(rp->policy);
248c8992cffSLuiz Augusto von Dentz 
249c8992cffSLuiz Augusto von Dentz 	return rp->status;
250e4e8e37cSMarcel Holtmann }
251e4e8e37cSMarcel Holtmann 
252c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_def_link_policy(struct hci_dev *hdev, void *data,
253807deac2SGustavo Padovan 				       struct sk_buff *skb)
254e4e8e37cSMarcel Holtmann {
255c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
256e4e8e37cSMarcel Holtmann 	void *sent;
257e4e8e37cSMarcel Holtmann 
258e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
259e3f3a1aeSLuiz Augusto von Dentz 
260e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
261c8992cffSLuiz Augusto von Dentz 		return rp->status;
26245296acdSMarcel Holtmann 
263e4e8e37cSMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
264e4e8e37cSMarcel Holtmann 	if (!sent)
265c8992cffSLuiz Augusto von Dentz 		return rp->status;
266e4e8e37cSMarcel Holtmann 
267e4e8e37cSMarcel Holtmann 	hdev->link_policy = get_unaligned_le16(sent);
268c8992cffSLuiz Augusto von Dentz 
269c8992cffSLuiz Augusto von Dentz 	return rp->status;
270e4e8e37cSMarcel Holtmann }
271e4e8e37cSMarcel Holtmann 
272c8992cffSLuiz Augusto von Dentz static u8 hci_cc_reset(struct hci_dev *hdev, void *data, struct sk_buff *skb)
2731da177e4SLinus Torvalds {
274c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
275e3f3a1aeSLuiz Augusto von Dentz 
276e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
277a9de9248SMarcel Holtmann 
27810572132SGustavo F. Padovan 	clear_bit(HCI_RESET, &hdev->flags);
27910572132SGustavo F. Padovan 
280e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
281c8992cffSLuiz Augusto von Dentz 		return rp->status;
2828761f9d6SMarcel Holtmann 
283a297e97cSJohan Hedberg 	/* Reset all non-persistent flags */
284eacb44dfSMarcel Holtmann 	hci_dev_clear_volatile_flags(hdev);
28569775ff6SAndre Guedes 
28639c5d970SJohan Hedberg 	hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
28739c5d970SJohan Hedberg 
288bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
289bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
2903f0f524bSJohan Hedberg 
2913f0f524bSJohan Hedberg 	memset(hdev->adv_data, 0, sizeof(hdev->adv_data));
2923f0f524bSJohan Hedberg 	hdev->adv_data_len = 0;
293f8e808bdSMarcel Holtmann 
294f8e808bdSMarcel Holtmann 	memset(hdev->scan_rsp_data, 0, sizeof(hdev->scan_rsp_data));
295f8e808bdSMarcel Holtmann 	hdev->scan_rsp_data_len = 0;
29606f5b778SMarcel Holtmann 
297533553f8SMarcel Holtmann 	hdev->le_scan_type = LE_SCAN_PASSIVE;
298533553f8SMarcel Holtmann 
29906f5b778SMarcel Holtmann 	hdev->ssp_debug_mode = 0;
300a4d5504dSMarcel Holtmann 
3013d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->le_accept_list);
302cfdb0c2dSAnkit Navik 	hci_bdaddr_list_clear(&hdev->le_resolv_list);
303c8992cffSLuiz Augusto von Dentz 
304c8992cffSLuiz Augusto von Dentz 	return rp->status;
305a9de9248SMarcel Holtmann }
306a9de9248SMarcel Holtmann 
307c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_stored_link_key(struct hci_dev *hdev, void *data,
308c2f0f979SMarcel Holtmann 				      struct sk_buff *skb)
309c2f0f979SMarcel Holtmann {
310c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_stored_link_key *rp = data;
311c2f0f979SMarcel Holtmann 	struct hci_cp_read_stored_link_key *sent;
312c2f0f979SMarcel Holtmann 
313e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
314c2f0f979SMarcel Holtmann 
315c2f0f979SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_READ_STORED_LINK_KEY);
316c2f0f979SMarcel Holtmann 	if (!sent)
317c8992cffSLuiz Augusto von Dentz 		return rp->status;
318c2f0f979SMarcel Holtmann 
319c2f0f979SMarcel Holtmann 	if (!rp->status && sent->read_all == 0x01) {
320e88422bcSLuiz Augusto von Dentz 		hdev->stored_max_keys = le16_to_cpu(rp->max_keys);
321e88422bcSLuiz Augusto von Dentz 		hdev->stored_num_keys = le16_to_cpu(rp->num_keys);
322c2f0f979SMarcel Holtmann 	}
323c8992cffSLuiz Augusto von Dentz 
324c8992cffSLuiz Augusto von Dentz 	return rp->status;
325c2f0f979SMarcel Holtmann }
326c2f0f979SMarcel Holtmann 
327c8992cffSLuiz Augusto von Dentz static u8 hci_cc_delete_stored_link_key(struct hci_dev *hdev, void *data,
328a9366120SMarcel Holtmann 					struct sk_buff *skb)
329a9366120SMarcel Holtmann {
330c8992cffSLuiz Augusto von Dentz 	struct hci_rp_delete_stored_link_key *rp = data;
331889f0346SLuiz Augusto von Dentz 	u16 num_keys;
332e3f3a1aeSLuiz Augusto von Dentz 
333e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
334a9366120SMarcel Holtmann 
335a9366120SMarcel Holtmann 	if (rp->status)
336c8992cffSLuiz Augusto von Dentz 		return rp->status;
337a9366120SMarcel Holtmann 
338889f0346SLuiz Augusto von Dentz 	num_keys = le16_to_cpu(rp->num_keys);
339889f0346SLuiz Augusto von Dentz 
340889f0346SLuiz Augusto von Dentz 	if (num_keys <= hdev->stored_num_keys)
341889f0346SLuiz Augusto von Dentz 		hdev->stored_num_keys -= num_keys;
342a9366120SMarcel Holtmann 	else
343a9366120SMarcel Holtmann 		hdev->stored_num_keys = 0;
344c8992cffSLuiz Augusto von Dentz 
345c8992cffSLuiz Augusto von Dentz 	return rp->status;
346a9366120SMarcel Holtmann }
347a9366120SMarcel Holtmann 
348c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_local_name(struct hci_dev *hdev, void *data,
349c8992cffSLuiz Augusto von Dentz 				  struct sk_buff *skb)
350a9de9248SMarcel Holtmann {
351c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
3521da177e4SLinus Torvalds 	void *sent;
3531da177e4SLinus Torvalds 
354e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
3551da177e4SLinus Torvalds 
356a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
3571da177e4SLinus Torvalds 	if (!sent)
358c8992cffSLuiz Augusto von Dentz 		return rp->status;
3591da177e4SLinus Torvalds 
36056e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
36156e5cb86SJohan Hedberg 
362d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
363e3f3a1aeSLuiz Augusto von Dentz 		mgmt_set_local_name_complete(hdev, sent, rp->status);
364e3f3a1aeSLuiz Augusto von Dentz 	else if (!rp->status)
36528cc7bdeSJohan Hedberg 		memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
366f51d5b24SJohan Hedberg 
36756e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
368c8992cffSLuiz Augusto von Dentz 
369c8992cffSLuiz Augusto von Dentz 	return rp->status;
370a9de9248SMarcel Holtmann }
371a9de9248SMarcel Holtmann 
372c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_name(struct hci_dev *hdev, void *data,
373c8992cffSLuiz Augusto von Dentz 				 struct sk_buff *skb)
374a9de9248SMarcel Holtmann {
375c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_name *rp = data;
376e3f3a1aeSLuiz Augusto von Dentz 
377e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
378a9de9248SMarcel Holtmann 
379a9de9248SMarcel Holtmann 	if (rp->status)
380c8992cffSLuiz Augusto von Dentz 		return rp->status;
381a9de9248SMarcel Holtmann 
382d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP) ||
383d7a5a11dSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_CONFIG))
3841f6c6378SJohan Hedberg 		memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
385c8992cffSLuiz Augusto von Dentz 
386c8992cffSLuiz Augusto von Dentz 	return rp->status;
387a9de9248SMarcel Holtmann }
388a9de9248SMarcel Holtmann 
389c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_auth_enable(struct hci_dev *hdev, void *data,
390c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
391a9de9248SMarcel Holtmann {
392c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
393a9de9248SMarcel Holtmann 	void *sent;
394a9de9248SMarcel Holtmann 
395e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
396a9de9248SMarcel Holtmann 
397a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
398a9de9248SMarcel Holtmann 	if (!sent)
399c8992cffSLuiz Augusto von Dentz 		return rp->status;
4001da177e4SLinus Torvalds 
4015c1a4c8fSJaganath Kanakkassery 	hci_dev_lock(hdev);
4025c1a4c8fSJaganath Kanakkassery 
403e3f3a1aeSLuiz Augusto von Dentz 	if (!rp->status) {
404a9de9248SMarcel Holtmann 		__u8 param = *((__u8 *) sent);
405a9de9248SMarcel Holtmann 
4061da177e4SLinus Torvalds 		if (param == AUTH_ENABLED)
4071da177e4SLinus Torvalds 			set_bit(HCI_AUTH, &hdev->flags);
4081da177e4SLinus Torvalds 		else
4091da177e4SLinus Torvalds 			clear_bit(HCI_AUTH, &hdev->flags);
4101da177e4SLinus Torvalds 	}
411a9de9248SMarcel Holtmann 
412d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
413e3f3a1aeSLuiz Augusto von Dentz 		mgmt_auth_enable_complete(hdev, rp->status);
4145c1a4c8fSJaganath Kanakkassery 
4155c1a4c8fSJaganath Kanakkassery 	hci_dev_unlock(hdev);
416c8992cffSLuiz Augusto von Dentz 
417c8992cffSLuiz Augusto von Dentz 	return rp->status;
418a9de9248SMarcel Holtmann }
4191da177e4SLinus Torvalds 
420c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_encrypt_mode(struct hci_dev *hdev, void *data,
421c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
422a9de9248SMarcel Holtmann {
423c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
42445296acdSMarcel Holtmann 	__u8 param;
425a9de9248SMarcel Holtmann 	void *sent;
426a9de9248SMarcel Holtmann 
427e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
428e3f3a1aeSLuiz Augusto von Dentz 
429e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
430c8992cffSLuiz Augusto von Dentz 		return rp->status;
43145296acdSMarcel Holtmann 
432a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
4331da177e4SLinus Torvalds 	if (!sent)
434c8992cffSLuiz Augusto von Dentz 		return rp->status;
4351da177e4SLinus Torvalds 
43645296acdSMarcel Holtmann 	param = *((__u8 *) sent);
437a9de9248SMarcel Holtmann 
4381da177e4SLinus Torvalds 	if (param)
4391da177e4SLinus Torvalds 		set_bit(HCI_ENCRYPT, &hdev->flags);
4401da177e4SLinus Torvalds 	else
4411da177e4SLinus Torvalds 		clear_bit(HCI_ENCRYPT, &hdev->flags);
442c8992cffSLuiz Augusto von Dentz 
443c8992cffSLuiz Augusto von Dentz 	return rp->status;
4441da177e4SLinus Torvalds }
4451da177e4SLinus Torvalds 
446c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_scan_enable(struct hci_dev *hdev, void *data,
447c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
448a9de9248SMarcel Holtmann {
449c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
45045296acdSMarcel Holtmann 	__u8 param;
451a9de9248SMarcel Holtmann 	void *sent;
4521da177e4SLinus Torvalds 
453e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
454a9de9248SMarcel Holtmann 
455a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
4561da177e4SLinus Torvalds 	if (!sent)
457c8992cffSLuiz Augusto von Dentz 		return rp->status;
4581da177e4SLinus Torvalds 
45936f7fc7eSJohan Hedberg 	param = *((__u8 *) sent);
460a9de9248SMarcel Holtmann 
46156e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
46256e5cb86SJohan Hedberg 
463e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status) {
4642d7cee58SJohan Hedberg 		hdev->discov_timeout = 0;
4652d7cee58SJohan Hedberg 		goto done;
4662d7cee58SJohan Hedberg 	}
4672d7cee58SJohan Hedberg 
468bc6d2d04SJohan Hedberg 	if (param & SCAN_INQUIRY)
4691da177e4SLinus Torvalds 		set_bit(HCI_ISCAN, &hdev->flags);
470bc6d2d04SJohan Hedberg 	else
471bc6d2d04SJohan Hedberg 		clear_bit(HCI_ISCAN, &hdev->flags);
4721da177e4SLinus Torvalds 
473031547d8SJohan Hedberg 	if (param & SCAN_PAGE)
4741da177e4SLinus Torvalds 		set_bit(HCI_PSCAN, &hdev->flags);
475bc6d2d04SJohan Hedberg 	else
476204e3990SJohan Hedberg 		clear_bit(HCI_PSCAN, &hdev->flags);
477a9de9248SMarcel Holtmann 
47836f7fc7eSJohan Hedberg done:
47956e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
480c8992cffSLuiz Augusto von Dentz 
481c8992cffSLuiz Augusto von Dentz 	return rp->status;
4821da177e4SLinus Torvalds }
4831da177e4SLinus Torvalds 
484c8992cffSLuiz Augusto von Dentz static u8 hci_cc_set_event_filter(struct hci_dev *hdev, void *data,
485c8992cffSLuiz Augusto von Dentz 				  struct sk_buff *skb)
486e5b0ad69SAbhishek Pandit-Subedi {
487c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
488e5b0ad69SAbhishek Pandit-Subedi 	struct hci_cp_set_event_filter *cp;
489e5b0ad69SAbhishek Pandit-Subedi 	void *sent;
490e5b0ad69SAbhishek Pandit-Subedi 
491e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
492e3f3a1aeSLuiz Augusto von Dentz 
493e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
494c8992cffSLuiz Augusto von Dentz 		return rp->status;
495e5b0ad69SAbhishek Pandit-Subedi 
496e5b0ad69SAbhishek Pandit-Subedi 	sent = hci_sent_cmd_data(hdev, HCI_OP_SET_EVENT_FLT);
497e5b0ad69SAbhishek Pandit-Subedi 	if (!sent)
498c8992cffSLuiz Augusto von Dentz 		return rp->status;
499e5b0ad69SAbhishek Pandit-Subedi 
500e5b0ad69SAbhishek Pandit-Subedi 	cp = (struct hci_cp_set_event_filter *)sent;
501e5b0ad69SAbhishek Pandit-Subedi 
502e5b0ad69SAbhishek Pandit-Subedi 	if (cp->flt_type == HCI_FLT_CLEAR_ALL)
503e5b0ad69SAbhishek Pandit-Subedi 		hci_dev_clear_flag(hdev, HCI_EVENT_FILTER_CONFIGURED);
504e5b0ad69SAbhishek Pandit-Subedi 	else
505e5b0ad69SAbhishek Pandit-Subedi 		hci_dev_set_flag(hdev, HCI_EVENT_FILTER_CONFIGURED);
506c8992cffSLuiz Augusto von Dentz 
507c8992cffSLuiz Augusto von Dentz 	return rp->status;
508e5b0ad69SAbhishek Pandit-Subedi }
509e5b0ad69SAbhishek Pandit-Subedi 
510c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_class_of_dev(struct hci_dev *hdev, void *data,
511c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
512a9de9248SMarcel Holtmann {
513c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_class_of_dev *rp = data;
514e3f3a1aeSLuiz Augusto von Dentz 
515e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
516a9de9248SMarcel Holtmann 
517a9de9248SMarcel Holtmann 	if (rp->status)
518c8992cffSLuiz Augusto von Dentz 		return rp->status;
519a9de9248SMarcel Holtmann 
520a9de9248SMarcel Holtmann 	memcpy(hdev->dev_class, rp->dev_class, 3);
521a9de9248SMarcel Holtmann 
522e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "class 0x%.2x%.2x%.2x", hdev->dev_class[2],
523e3f3a1aeSLuiz Augusto von Dentz 		   hdev->dev_class[1], hdev->dev_class[0]);
524c8992cffSLuiz Augusto von Dentz 
525c8992cffSLuiz Augusto von Dentz 	return rp->status;
526a9de9248SMarcel Holtmann }
527a9de9248SMarcel Holtmann 
528c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_class_of_dev(struct hci_dev *hdev, void *data,
529c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
530a9de9248SMarcel Holtmann {
531c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
532a9de9248SMarcel Holtmann 	void *sent;
533a9de9248SMarcel Holtmann 
534e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
535a9de9248SMarcel Holtmann 
536a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
537a9de9248SMarcel Holtmann 	if (!sent)
538c8992cffSLuiz Augusto von Dentz 		return rp->status;
539a9de9248SMarcel Holtmann 
5407f9a903cSMarcel Holtmann 	hci_dev_lock(hdev);
5417f9a903cSMarcel Holtmann 
542e3f3a1aeSLuiz Augusto von Dentz 	if (!rp->status)
543a9de9248SMarcel Holtmann 		memcpy(hdev->dev_class, sent, 3);
5447f9a903cSMarcel Holtmann 
545d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
546e3f3a1aeSLuiz Augusto von Dentz 		mgmt_set_class_of_dev_complete(hdev, sent, rp->status);
5477f9a903cSMarcel Holtmann 
5487f9a903cSMarcel Holtmann 	hci_dev_unlock(hdev);
549c8992cffSLuiz Augusto von Dentz 
550c8992cffSLuiz Augusto von Dentz 	return rp->status;
551a9de9248SMarcel Holtmann }
552a9de9248SMarcel Holtmann 
553c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_voice_setting(struct hci_dev *hdev, void *data,
554c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
555a9de9248SMarcel Holtmann {
556c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_voice_setting *rp = data;
557a9de9248SMarcel Holtmann 	__u16 setting;
558a9de9248SMarcel Holtmann 
559e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
560a9de9248SMarcel Holtmann 
561a9de9248SMarcel Holtmann 	if (rp->status)
562c8992cffSLuiz Augusto von Dentz 		return rp->status;
563a9de9248SMarcel Holtmann 
564a9de9248SMarcel Holtmann 	setting = __le16_to_cpu(rp->voice_setting);
565a9de9248SMarcel Holtmann 
566a9de9248SMarcel Holtmann 	if (hdev->voice_setting == setting)
567c8992cffSLuiz Augusto von Dentz 		return rp->status;
568a9de9248SMarcel Holtmann 
569a9de9248SMarcel Holtmann 	hdev->voice_setting = setting;
570a9de9248SMarcel Holtmann 
571e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "voice setting 0x%4.4x", setting);
572a9de9248SMarcel Holtmann 
5733c54711cSGustavo F. Padovan 	if (hdev->notify)
574a9de9248SMarcel Holtmann 		hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
575c8992cffSLuiz Augusto von Dentz 
576c8992cffSLuiz Augusto von Dentz 	return rp->status;
577a9de9248SMarcel Holtmann }
578a9de9248SMarcel Holtmann 
579c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_voice_setting(struct hci_dev *hdev, void *data,
5808fc9ced3SGustavo Padovan 				     struct sk_buff *skb)
581a9de9248SMarcel Holtmann {
582c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
583f383f275SMarcel Holtmann 	__u16 setting;
584a9de9248SMarcel Holtmann 	void *sent;
585a9de9248SMarcel Holtmann 
586e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
587e3f3a1aeSLuiz Augusto von Dentz 
588e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
589c8992cffSLuiz Augusto von Dentz 		return rp->status;
590f383f275SMarcel Holtmann 
591a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
592a9de9248SMarcel Holtmann 	if (!sent)
593c8992cffSLuiz Augusto von Dentz 		return rp->status;
594a9de9248SMarcel Holtmann 
595f383f275SMarcel Holtmann 	setting = get_unaligned_le16(sent);
5961da177e4SLinus Torvalds 
597f383f275SMarcel Holtmann 	if (hdev->voice_setting == setting)
598c8992cffSLuiz Augusto von Dentz 		return rp->status;
599f383f275SMarcel Holtmann 
6001da177e4SLinus Torvalds 	hdev->voice_setting = setting;
6011da177e4SLinus Torvalds 
602e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "voice setting 0x%4.4x", setting);
6031da177e4SLinus Torvalds 
6043c54711cSGustavo F. Padovan 	if (hdev->notify)
6051da177e4SLinus Torvalds 		hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
606c8992cffSLuiz Augusto von Dentz 
607c8992cffSLuiz Augusto von Dentz 	return rp->status;
6081da177e4SLinus Torvalds }
6091da177e4SLinus Torvalds 
610c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_num_supported_iac(struct hci_dev *hdev, void *data,
611b4cb9fb2SMarcel Holtmann 					struct sk_buff *skb)
612b4cb9fb2SMarcel Holtmann {
613c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_num_supported_iac *rp = data;
614e3f3a1aeSLuiz Augusto von Dentz 
615e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
616b4cb9fb2SMarcel Holtmann 
617b4cb9fb2SMarcel Holtmann 	if (rp->status)
618c8992cffSLuiz Augusto von Dentz 		return rp->status;
619b4cb9fb2SMarcel Holtmann 
620b4cb9fb2SMarcel Holtmann 	hdev->num_iac = rp->num_iac;
621b4cb9fb2SMarcel Holtmann 
622e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "num iac %d", hdev->num_iac);
623c8992cffSLuiz Augusto von Dentz 
624c8992cffSLuiz Augusto von Dentz 	return rp->status;
625b4cb9fb2SMarcel Holtmann }
626b4cb9fb2SMarcel Holtmann 
627c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_ssp_mode(struct hci_dev *hdev, void *data,
628c8992cffSLuiz Augusto von Dentz 				struct sk_buff *skb)
629333140b5SMarcel Holtmann {
630c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
6315ed8eb2fSJohan Hedberg 	struct hci_cp_write_ssp_mode *sent;
632333140b5SMarcel Holtmann 
633e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
634333140b5SMarcel Holtmann 
635333140b5SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
636333140b5SMarcel Holtmann 	if (!sent)
637c8992cffSLuiz Augusto von Dentz 		return rp->status;
638333140b5SMarcel Holtmann 
6395c1a4c8fSJaganath Kanakkassery 	hci_dev_lock(hdev);
6405c1a4c8fSJaganath Kanakkassery 
641e3f3a1aeSLuiz Augusto von Dentz 	if (!rp->status) {
6425ed8eb2fSJohan Hedberg 		if (sent->mode)
643cad718edSJohan Hedberg 			hdev->features[1][0] |= LMP_HOST_SSP;
6445ed8eb2fSJohan Hedberg 		else
645cad718edSJohan Hedberg 			hdev->features[1][0] &= ~LMP_HOST_SSP;
6465ed8eb2fSJohan Hedberg 	}
6475ed8eb2fSJohan Hedberg 
648e3f3a1aeSLuiz Augusto von Dentz 	if (!rp->status) {
6495ed8eb2fSJohan Hedberg 		if (sent->mode)
650a1536da2SMarcel Holtmann 			hci_dev_set_flag(hdev, HCI_SSP_ENABLED);
65184bde9d6SJohan Hedberg 		else
652a358dc11SMarcel Holtmann 			hci_dev_clear_flag(hdev, HCI_SSP_ENABLED);
653c0ecddc2SJohan Hedberg 	}
6545c1a4c8fSJaganath Kanakkassery 
6555c1a4c8fSJaganath Kanakkassery 	hci_dev_unlock(hdev);
656c8992cffSLuiz Augusto von Dentz 
657c8992cffSLuiz Augusto von Dentz 	return rp->status;
658333140b5SMarcel Holtmann }
659333140b5SMarcel Holtmann 
660c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_sc_support(struct hci_dev *hdev, void *data,
661c8992cffSLuiz Augusto von Dentz 				  struct sk_buff *skb)
662eac83dc6SMarcel Holtmann {
663c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
664eac83dc6SMarcel Holtmann 	struct hci_cp_write_sc_support *sent;
665eac83dc6SMarcel Holtmann 
666e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
667eac83dc6SMarcel Holtmann 
668eac83dc6SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SC_SUPPORT);
669eac83dc6SMarcel Holtmann 	if (!sent)
670c8992cffSLuiz Augusto von Dentz 		return rp->status;
671eac83dc6SMarcel Holtmann 
6725c1a4c8fSJaganath Kanakkassery 	hci_dev_lock(hdev);
6735c1a4c8fSJaganath Kanakkassery 
674e3f3a1aeSLuiz Augusto von Dentz 	if (!rp->status) {
675eac83dc6SMarcel Holtmann 		if (sent->support)
676eac83dc6SMarcel Holtmann 			hdev->features[1][0] |= LMP_HOST_SC;
677eac83dc6SMarcel Holtmann 		else
678eac83dc6SMarcel Holtmann 			hdev->features[1][0] &= ~LMP_HOST_SC;
679eac83dc6SMarcel Holtmann 	}
680eac83dc6SMarcel Holtmann 
681e3f3a1aeSLuiz Augusto von Dentz 	if (!hci_dev_test_flag(hdev, HCI_MGMT) && !rp->status) {
682eac83dc6SMarcel Holtmann 		if (sent->support)
683a1536da2SMarcel Holtmann 			hci_dev_set_flag(hdev, HCI_SC_ENABLED);
684eac83dc6SMarcel Holtmann 		else
685a358dc11SMarcel Holtmann 			hci_dev_clear_flag(hdev, HCI_SC_ENABLED);
686eac83dc6SMarcel Holtmann 	}
6875c1a4c8fSJaganath Kanakkassery 
6885c1a4c8fSJaganath Kanakkassery 	hci_dev_unlock(hdev);
689c8992cffSLuiz Augusto von Dentz 
690c8992cffSLuiz Augusto von Dentz 	return rp->status;
691eac83dc6SMarcel Holtmann }
692eac83dc6SMarcel Holtmann 
693c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_version(struct hci_dev *hdev, void *data,
694c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
695a9de9248SMarcel Holtmann {
696c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_version *rp = data;
697e3f3a1aeSLuiz Augusto von Dentz 
698e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
6991143e5a6SMarcel Holtmann 
700a9de9248SMarcel Holtmann 	if (rp->status)
701c8992cffSLuiz Augusto von Dentz 		return rp->status;
7021143e5a6SMarcel Holtmann 
703d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP) ||
704d7a5a11dSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_CONFIG)) {
705a9de9248SMarcel Holtmann 		hdev->hci_ver = rp->hci_ver;
706e4e8e37cSMarcel Holtmann 		hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
707d5859e22SJohan Hedberg 		hdev->lmp_ver = rp->lmp_ver;
708e4e8e37cSMarcel Holtmann 		hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
709d5859e22SJohan Hedberg 		hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
7100d5551f5SMarcel Holtmann 	}
711c8992cffSLuiz Augusto von Dentz 
712c8992cffSLuiz Augusto von Dentz 	return rp->status;
713d5859e22SJohan Hedberg }
714d5859e22SJohan Hedberg 
715278d933eSBrian Gix static u8 hci_cc_read_enc_key_size(struct hci_dev *hdev, void *data,
716278d933eSBrian Gix 				   struct sk_buff *skb)
717278d933eSBrian Gix {
718278d933eSBrian Gix 	struct hci_rp_read_enc_key_size *rp = data;
719278d933eSBrian Gix 	struct hci_conn *conn;
720278d933eSBrian Gix 	u16 handle;
721278d933eSBrian Gix 	u8 status = rp->status;
722278d933eSBrian Gix 
723278d933eSBrian Gix 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
724278d933eSBrian Gix 
725278d933eSBrian Gix 	handle = le16_to_cpu(rp->handle);
726278d933eSBrian Gix 
727278d933eSBrian Gix 	hci_dev_lock(hdev);
728278d933eSBrian Gix 
729278d933eSBrian Gix 	conn = hci_conn_hash_lookup_handle(hdev, handle);
730278d933eSBrian Gix 	if (!conn) {
731278d933eSBrian Gix 		status = 0xFF;
732278d933eSBrian Gix 		goto done;
733278d933eSBrian Gix 	}
734278d933eSBrian Gix 
735278d933eSBrian Gix 	/* While unexpected, the read_enc_key_size command may fail. The most
736278d933eSBrian Gix 	 * secure approach is to then assume the key size is 0 to force a
737278d933eSBrian Gix 	 * disconnection.
738278d933eSBrian Gix 	 */
739278d933eSBrian Gix 	if (status) {
740278d933eSBrian Gix 		bt_dev_err(hdev, "failed to read key size for handle %u",
741278d933eSBrian Gix 			   handle);
742278d933eSBrian Gix 		conn->enc_key_size = 0;
743278d933eSBrian Gix 	} else {
744278d933eSBrian Gix 		conn->enc_key_size = rp->key_size;
745278d933eSBrian Gix 		status = 0;
746278d933eSBrian Gix 	}
747278d933eSBrian Gix 
748278d933eSBrian Gix 	hci_encrypt_cfm(conn, 0);
749278d933eSBrian Gix 
750278d933eSBrian Gix done:
751278d933eSBrian Gix 	hci_dev_unlock(hdev);
752278d933eSBrian Gix 
753278d933eSBrian Gix 	return status;
754278d933eSBrian Gix }
755278d933eSBrian Gix 
756c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_commands(struct hci_dev *hdev, void *data,
7578fc9ced3SGustavo Padovan 				     struct sk_buff *skb)
758a9de9248SMarcel Holtmann {
759c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_commands *rp = data;
760e3f3a1aeSLuiz Augusto von Dentz 
761e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
762a9de9248SMarcel Holtmann 
7636a070e6eSMarcel Holtmann 	if (rp->status)
764c8992cffSLuiz Augusto von Dentz 		return rp->status;
7656a070e6eSMarcel Holtmann 
766d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP) ||
767d7a5a11dSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_CONFIG))
768a9de9248SMarcel Holtmann 		memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
769c8992cffSLuiz Augusto von Dentz 
770c8992cffSLuiz Augusto von Dentz 	return rp->status;
771a9de9248SMarcel Holtmann }
772a9de9248SMarcel Holtmann 
773c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_auth_payload_timeout(struct hci_dev *hdev, void *data,
774302975cbSSpoorthi Ravishankar Koppad 					   struct sk_buff *skb)
775302975cbSSpoorthi Ravishankar Koppad {
776c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_auth_payload_to *rp = data;
777302975cbSSpoorthi Ravishankar Koppad 	struct hci_conn *conn;
778302975cbSSpoorthi Ravishankar Koppad 
779e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
780302975cbSSpoorthi Ravishankar Koppad 
781302975cbSSpoorthi Ravishankar Koppad 	if (rp->status)
782c8992cffSLuiz Augusto von Dentz 		return rp->status;
783302975cbSSpoorthi Ravishankar Koppad 
784302975cbSSpoorthi Ravishankar Koppad 	hci_dev_lock(hdev);
785302975cbSSpoorthi Ravishankar Koppad 
786302975cbSSpoorthi Ravishankar Koppad 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
787302975cbSSpoorthi Ravishankar Koppad 	if (conn)
788302975cbSSpoorthi Ravishankar Koppad 		conn->auth_payload_timeout = __le16_to_cpu(rp->timeout);
789302975cbSSpoorthi Ravishankar Koppad 
790302975cbSSpoorthi Ravishankar Koppad 	hci_dev_unlock(hdev);
791c8992cffSLuiz Augusto von Dentz 
792c8992cffSLuiz Augusto von Dentz 	return rp->status;
793302975cbSSpoorthi Ravishankar Koppad }
794302975cbSSpoorthi Ravishankar Koppad 
795c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_auth_payload_timeout(struct hci_dev *hdev, void *data,
796302975cbSSpoorthi Ravishankar Koppad 					    struct sk_buff *skb)
797302975cbSSpoorthi Ravishankar Koppad {
798c8992cffSLuiz Augusto von Dentz 	struct hci_rp_write_auth_payload_to *rp = data;
799302975cbSSpoorthi Ravishankar Koppad 	struct hci_conn *conn;
800302975cbSSpoorthi Ravishankar Koppad 	void *sent;
801302975cbSSpoorthi Ravishankar Koppad 
802e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
803302975cbSSpoorthi Ravishankar Koppad 
804302975cbSSpoorthi Ravishankar Koppad 	if (rp->status)
805c8992cffSLuiz Augusto von Dentz 		return rp->status;
806302975cbSSpoorthi Ravishankar Koppad 
807302975cbSSpoorthi Ravishankar Koppad 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_PAYLOAD_TO);
808302975cbSSpoorthi Ravishankar Koppad 	if (!sent)
809c8992cffSLuiz Augusto von Dentz 		return rp->status;
810302975cbSSpoorthi Ravishankar Koppad 
811302975cbSSpoorthi Ravishankar Koppad 	hci_dev_lock(hdev);
812302975cbSSpoorthi Ravishankar Koppad 
813302975cbSSpoorthi Ravishankar Koppad 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
814302975cbSSpoorthi Ravishankar Koppad 	if (conn)
815302975cbSSpoorthi Ravishankar Koppad 		conn->auth_payload_timeout = get_unaligned_le16(sent + 2);
816302975cbSSpoorthi Ravishankar Koppad 
817302975cbSSpoorthi Ravishankar Koppad 	hci_dev_unlock(hdev);
818c8992cffSLuiz Augusto von Dentz 
819c8992cffSLuiz Augusto von Dentz 	return rp->status;
820302975cbSSpoorthi Ravishankar Koppad }
821302975cbSSpoorthi Ravishankar Koppad 
822c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_features(struct hci_dev *hdev, void *data,
8238fc9ced3SGustavo Padovan 				     struct sk_buff *skb)
824a9de9248SMarcel Holtmann {
825c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_features *rp = data;
826e3f3a1aeSLuiz Augusto von Dentz 
827e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
828a9de9248SMarcel Holtmann 
829a9de9248SMarcel Holtmann 	if (rp->status)
830c8992cffSLuiz Augusto von Dentz 		return rp->status;
831a9de9248SMarcel Holtmann 
832a9de9248SMarcel Holtmann 	memcpy(hdev->features, rp->features, 8);
8331da177e4SLinus Torvalds 
8341da177e4SLinus Torvalds 	/* Adjust default settings according to features
8351da177e4SLinus Torvalds 	 * supported by device. */
836a9de9248SMarcel Holtmann 
837cad718edSJohan Hedberg 	if (hdev->features[0][0] & LMP_3SLOT)
8381da177e4SLinus Torvalds 		hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
8391da177e4SLinus Torvalds 
840cad718edSJohan Hedberg 	if (hdev->features[0][0] & LMP_5SLOT)
8411da177e4SLinus Torvalds 		hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
8421da177e4SLinus Torvalds 
843cad718edSJohan Hedberg 	if (hdev->features[0][1] & LMP_HV2) {
8441da177e4SLinus Torvalds 		hdev->pkt_type  |= (HCI_HV2);
8455b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_HV2);
8465b7f9909SMarcel Holtmann 	}
8471da177e4SLinus Torvalds 
848cad718edSJohan Hedberg 	if (hdev->features[0][1] & LMP_HV3) {
8491da177e4SLinus Torvalds 		hdev->pkt_type  |= (HCI_HV3);
8505b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_HV3);
8515b7f9909SMarcel Holtmann 	}
8525b7f9909SMarcel Holtmann 
85345db810fSAndre Guedes 	if (lmp_esco_capable(hdev))
8545b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_EV3);
8555b7f9909SMarcel Holtmann 
856cad718edSJohan Hedberg 	if (hdev->features[0][4] & LMP_EV4)
8575b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_EV4);
8585b7f9909SMarcel Holtmann 
859cad718edSJohan Hedberg 	if (hdev->features[0][4] & LMP_EV5)
8605b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_EV5);
8611da177e4SLinus Torvalds 
862cad718edSJohan Hedberg 	if (hdev->features[0][5] & LMP_EDR_ESCO_2M)
863efc7688bSMarcel Holtmann 		hdev->esco_type |= (ESCO_2EV3);
864efc7688bSMarcel Holtmann 
865cad718edSJohan Hedberg 	if (hdev->features[0][5] & LMP_EDR_ESCO_3M)
866efc7688bSMarcel Holtmann 		hdev->esco_type |= (ESCO_3EV3);
867efc7688bSMarcel Holtmann 
868cad718edSJohan Hedberg 	if (hdev->features[0][5] & LMP_EDR_3S_ESCO)
869efc7688bSMarcel Holtmann 		hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
870c8992cffSLuiz Augusto von Dentz 
871c8992cffSLuiz Augusto von Dentz 	return rp->status;
8721da177e4SLinus Torvalds }
8731da177e4SLinus Torvalds 
874c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_ext_features(struct hci_dev *hdev, void *data,
875971e3a4bSAndre Guedes 					 struct sk_buff *skb)
876971e3a4bSAndre Guedes {
877c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_ext_features *rp = data;
878e3f3a1aeSLuiz Augusto von Dentz 
879e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
880971e3a4bSAndre Guedes 
881971e3a4bSAndre Guedes 	if (rp->status)
882c8992cffSLuiz Augusto von Dentz 		return rp->status;
883971e3a4bSAndre Guedes 
88457af75a8SMarcel Holtmann 	if (hdev->max_page < rp->max_page)
885d2c5d77fSJohan Hedberg 		hdev->max_page = rp->max_page;
886d2c5d77fSJohan Hedberg 
887cad718edSJohan Hedberg 	if (rp->page < HCI_MAX_PAGES)
888cad718edSJohan Hedberg 		memcpy(hdev->features[rp->page], rp->features, 8);
889c8992cffSLuiz Augusto von Dentz 
890c8992cffSLuiz Augusto von Dentz 	return rp->status;
891971e3a4bSAndre Guedes }
892971e3a4bSAndre Guedes 
893c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_flow_control_mode(struct hci_dev *hdev, void *data,
8941e89cffbSAndrei Emeltchenko 					struct sk_buff *skb)
8951e89cffbSAndrei Emeltchenko {
896c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_flow_control_mode *rp = data;
897e3f3a1aeSLuiz Augusto von Dentz 
898e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
8991e89cffbSAndrei Emeltchenko 
90045296acdSMarcel Holtmann 	if (rp->status)
901c8992cffSLuiz Augusto von Dentz 		return rp->status;
90245296acdSMarcel Holtmann 
9031e89cffbSAndrei Emeltchenko 	hdev->flow_ctl_mode = rp->mode;
904c8992cffSLuiz Augusto von Dentz 
905c8992cffSLuiz Augusto von Dentz 	return rp->status;
9061e89cffbSAndrei Emeltchenko }
9071e89cffbSAndrei Emeltchenko 
908c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_buffer_size(struct hci_dev *hdev, void *data,
909c8992cffSLuiz Augusto von Dentz 				  struct sk_buff *skb)
910a9de9248SMarcel Holtmann {
911c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_buffer_size *rp = data;
912e3f3a1aeSLuiz Augusto von Dentz 
913e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
914a9de9248SMarcel Holtmann 
915a9de9248SMarcel Holtmann 	if (rp->status)
916c8992cffSLuiz Augusto von Dentz 		return rp->status;
917a9de9248SMarcel Holtmann 
918a9de9248SMarcel Holtmann 	hdev->acl_mtu  = __le16_to_cpu(rp->acl_mtu);
919a9de9248SMarcel Holtmann 	hdev->sco_mtu  = rp->sco_mtu;
920a9de9248SMarcel Holtmann 	hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
921a9de9248SMarcel Holtmann 	hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
922da1f5198SMarcel Holtmann 
923da1f5198SMarcel Holtmann 	if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
924da1f5198SMarcel Holtmann 		hdev->sco_mtu  = 64;
925da1f5198SMarcel Holtmann 		hdev->sco_pkts = 8;
926da1f5198SMarcel Holtmann 	}
927da1f5198SMarcel Holtmann 
928da1f5198SMarcel Holtmann 	hdev->acl_cnt = hdev->acl_pkts;
929da1f5198SMarcel Holtmann 	hdev->sco_cnt = hdev->sco_pkts;
9301da177e4SLinus Torvalds 
931807deac2SGustavo Padovan 	BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
932807deac2SGustavo Padovan 	       hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
933c8992cffSLuiz Augusto von Dentz 
934c8992cffSLuiz Augusto von Dentz 	return rp->status;
9351da177e4SLinus Torvalds }
9361da177e4SLinus Torvalds 
937c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_bd_addr(struct hci_dev *hdev, void *data,
938c8992cffSLuiz Augusto von Dentz 			      struct sk_buff *skb)
939a9de9248SMarcel Holtmann {
940c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_bd_addr *rp = data;
941e3f3a1aeSLuiz Augusto von Dentz 
942e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
943a9de9248SMarcel Holtmann 
944e30d3f5fSMarcel Holtmann 	if (rp->status)
945c8992cffSLuiz Augusto von Dentz 		return rp->status;
946e30d3f5fSMarcel Holtmann 
947e30d3f5fSMarcel Holtmann 	if (test_bit(HCI_INIT, &hdev->flags))
948a9de9248SMarcel Holtmann 		bacpy(&hdev->bdaddr, &rp->bdaddr);
949e30d3f5fSMarcel Holtmann 
950d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP))
951e30d3f5fSMarcel Holtmann 		bacpy(&hdev->setup_addr, &rp->bdaddr);
952c8992cffSLuiz Augusto von Dentz 
953c8992cffSLuiz Augusto von Dentz 	return rp->status;
95423bb5763SJohan Hedberg }
95523bb5763SJohan Hedberg 
956c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_pairing_opts(struct hci_dev *hdev, void *data,
957a4790360SMarcel Holtmann 					 struct sk_buff *skb)
958a4790360SMarcel Holtmann {
959c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_pairing_opts *rp = data;
960e3f3a1aeSLuiz Augusto von Dentz 
961e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
962a4790360SMarcel Holtmann 
963a4790360SMarcel Holtmann 	if (rp->status)
964c8992cffSLuiz Augusto von Dentz 		return rp->status;
965a4790360SMarcel Holtmann 
966a4790360SMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP) ||
967a4790360SMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_CONFIG)) {
968a4790360SMarcel Holtmann 		hdev->pairing_opts = rp->pairing_opts;
969a4790360SMarcel Holtmann 		hdev->max_enc_key_size = rp->max_key_size;
970a4790360SMarcel Holtmann 	}
971c8992cffSLuiz Augusto von Dentz 
972c8992cffSLuiz Augusto von Dentz 	return rp->status;
973a4790360SMarcel Holtmann }
974a4790360SMarcel Holtmann 
975c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_page_scan_activity(struct hci_dev *hdev, void *data,
976f332ec66SJohan Hedberg 					 struct sk_buff *skb)
977f332ec66SJohan Hedberg {
978c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_page_scan_activity *rp = data;
979e3f3a1aeSLuiz Augusto von Dentz 
980e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
981f332ec66SJohan Hedberg 
98245296acdSMarcel Holtmann 	if (rp->status)
983c8992cffSLuiz Augusto von Dentz 		return rp->status;
98445296acdSMarcel Holtmann 
98545296acdSMarcel Holtmann 	if (test_bit(HCI_INIT, &hdev->flags)) {
986f332ec66SJohan Hedberg 		hdev->page_scan_interval = __le16_to_cpu(rp->interval);
987f332ec66SJohan Hedberg 		hdev->page_scan_window = __le16_to_cpu(rp->window);
988f332ec66SJohan Hedberg 	}
989c8992cffSLuiz Augusto von Dentz 
990c8992cffSLuiz Augusto von Dentz 	return rp->status;
991f332ec66SJohan Hedberg }
992f332ec66SJohan Hedberg 
993c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_page_scan_activity(struct hci_dev *hdev, void *data,
9944a3ee763SJohan Hedberg 					  struct sk_buff *skb)
9954a3ee763SJohan Hedberg {
996c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
9974a3ee763SJohan Hedberg 	struct hci_cp_write_page_scan_activity *sent;
9984a3ee763SJohan Hedberg 
999e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1000e3f3a1aeSLuiz Augusto von Dentz 
1001e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1002c8992cffSLuiz Augusto von Dentz 		return rp->status;
10034a3ee763SJohan Hedberg 
10044a3ee763SJohan Hedberg 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY);
10054a3ee763SJohan Hedberg 	if (!sent)
1006c8992cffSLuiz Augusto von Dentz 		return rp->status;
10074a3ee763SJohan Hedberg 
10084a3ee763SJohan Hedberg 	hdev->page_scan_interval = __le16_to_cpu(sent->interval);
10094a3ee763SJohan Hedberg 	hdev->page_scan_window = __le16_to_cpu(sent->window);
1010c8992cffSLuiz Augusto von Dentz 
1011c8992cffSLuiz Augusto von Dentz 	return rp->status;
10124a3ee763SJohan Hedberg }
10134a3ee763SJohan Hedberg 
1014c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_page_scan_type(struct hci_dev *hdev, void *data,
1015f332ec66SJohan Hedberg 				     struct sk_buff *skb)
1016f332ec66SJohan Hedberg {
1017c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_page_scan_type *rp = data;
1018e3f3a1aeSLuiz Augusto von Dentz 
1019e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1020f332ec66SJohan Hedberg 
102145296acdSMarcel Holtmann 	if (rp->status)
1022c8992cffSLuiz Augusto von Dentz 		return rp->status;
102345296acdSMarcel Holtmann 
102445296acdSMarcel Holtmann 	if (test_bit(HCI_INIT, &hdev->flags))
1025f332ec66SJohan Hedberg 		hdev->page_scan_type = rp->type;
1026c8992cffSLuiz Augusto von Dentz 
1027c8992cffSLuiz Augusto von Dentz 	return rp->status;
1028f332ec66SJohan Hedberg }
1029f332ec66SJohan Hedberg 
1030c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_page_scan_type(struct hci_dev *hdev, void *data,
10314a3ee763SJohan Hedberg 				      struct sk_buff *skb)
10324a3ee763SJohan Hedberg {
1033c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
10344a3ee763SJohan Hedberg 	u8 *type;
10354a3ee763SJohan Hedberg 
1036e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1037e3f3a1aeSLuiz Augusto von Dentz 
1038e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1039c8992cffSLuiz Augusto von Dentz 		return rp->status;
10404a3ee763SJohan Hedberg 
10414a3ee763SJohan Hedberg 	type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE);
10424a3ee763SJohan Hedberg 	if (type)
10434a3ee763SJohan Hedberg 		hdev->page_scan_type = *type;
1044c8992cffSLuiz Augusto von Dentz 
1045c8992cffSLuiz Augusto von Dentz 	return rp->status;
10464a3ee763SJohan Hedberg }
10474a3ee763SJohan Hedberg 
1048c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_data_block_size(struct hci_dev *hdev, void *data,
1049350ee4cfSAndrei Emeltchenko 				      struct sk_buff *skb)
1050350ee4cfSAndrei Emeltchenko {
1051c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_data_block_size *rp = data;
1052e3f3a1aeSLuiz Augusto von Dentz 
1053e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1054350ee4cfSAndrei Emeltchenko 
1055350ee4cfSAndrei Emeltchenko 	if (rp->status)
1056c8992cffSLuiz Augusto von Dentz 		return rp->status;
1057350ee4cfSAndrei Emeltchenko 
1058350ee4cfSAndrei Emeltchenko 	hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
1059350ee4cfSAndrei Emeltchenko 	hdev->block_len = __le16_to_cpu(rp->block_len);
1060350ee4cfSAndrei Emeltchenko 	hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
1061350ee4cfSAndrei Emeltchenko 
1062350ee4cfSAndrei Emeltchenko 	hdev->block_cnt = hdev->num_blocks;
1063350ee4cfSAndrei Emeltchenko 
1064350ee4cfSAndrei Emeltchenko 	BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
1065350ee4cfSAndrei Emeltchenko 	       hdev->block_cnt, hdev->block_len);
1066c8992cffSLuiz Augusto von Dentz 
1067c8992cffSLuiz Augusto von Dentz 	return rp->status;
1068350ee4cfSAndrei Emeltchenko }
1069350ee4cfSAndrei Emeltchenko 
1070c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_clock(struct hci_dev *hdev, void *data,
1071c8992cffSLuiz Augusto von Dentz 			    struct sk_buff *skb)
107233f35721SJohan Hedberg {
1073c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_clock *rp = data;
107433f35721SJohan Hedberg 	struct hci_cp_read_clock *cp;
107533f35721SJohan Hedberg 	struct hci_conn *conn;
107633f35721SJohan Hedberg 
1077e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1078e3f3a1aeSLuiz Augusto von Dentz 
107933f35721SJohan Hedberg 	if (rp->status)
1080c8992cffSLuiz Augusto von Dentz 		return rp->status;
108133f35721SJohan Hedberg 
108233f35721SJohan Hedberg 	hci_dev_lock(hdev);
108333f35721SJohan Hedberg 
108433f35721SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_READ_CLOCK);
108533f35721SJohan Hedberg 	if (!cp)
108633f35721SJohan Hedberg 		goto unlock;
108733f35721SJohan Hedberg 
108833f35721SJohan Hedberg 	if (cp->which == 0x00) {
108933f35721SJohan Hedberg 		hdev->clock = le32_to_cpu(rp->clock);
109033f35721SJohan Hedberg 		goto unlock;
109133f35721SJohan Hedberg 	}
109233f35721SJohan Hedberg 
109333f35721SJohan Hedberg 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
109433f35721SJohan Hedberg 	if (conn) {
109533f35721SJohan Hedberg 		conn->clock = le32_to_cpu(rp->clock);
109633f35721SJohan Hedberg 		conn->clock_accuracy = le16_to_cpu(rp->accuracy);
109733f35721SJohan Hedberg 	}
109833f35721SJohan Hedberg 
109933f35721SJohan Hedberg unlock:
110033f35721SJohan Hedberg 	hci_dev_unlock(hdev);
1101c8992cffSLuiz Augusto von Dentz 	return rp->status;
110233f35721SJohan Hedberg }
110333f35721SJohan Hedberg 
1104c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_amp_info(struct hci_dev *hdev, void *data,
1105928abaa7SAndrei Emeltchenko 				     struct sk_buff *skb)
1106928abaa7SAndrei Emeltchenko {
1107c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_amp_info *rp = data;
1108e3f3a1aeSLuiz Augusto von Dentz 
1109e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1110928abaa7SAndrei Emeltchenko 
1111928abaa7SAndrei Emeltchenko 	if (rp->status)
1112c8992cffSLuiz Augusto von Dentz 		return rp->status;
1113928abaa7SAndrei Emeltchenko 
1114928abaa7SAndrei Emeltchenko 	hdev->amp_status = rp->amp_status;
1115928abaa7SAndrei Emeltchenko 	hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
1116928abaa7SAndrei Emeltchenko 	hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
1117928abaa7SAndrei Emeltchenko 	hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
1118928abaa7SAndrei Emeltchenko 	hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
1119928abaa7SAndrei Emeltchenko 	hdev->amp_type = rp->amp_type;
1120928abaa7SAndrei Emeltchenko 	hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
1121928abaa7SAndrei Emeltchenko 	hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
1122928abaa7SAndrei Emeltchenko 	hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
1123928abaa7SAndrei Emeltchenko 	hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
1124c8992cffSLuiz Augusto von Dentz 
1125c8992cffSLuiz Augusto von Dentz 	return rp->status;
1126928abaa7SAndrei Emeltchenko }
1127928abaa7SAndrei Emeltchenko 
1128c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev, void *data,
1129d5859e22SJohan Hedberg 				       struct sk_buff *skb)
1130d5859e22SJohan Hedberg {
1131c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_inq_rsp_tx_power *rp = data;
1132e3f3a1aeSLuiz Augusto von Dentz 
1133e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1134d5859e22SJohan Hedberg 
113545296acdSMarcel Holtmann 	if (rp->status)
1136c8992cffSLuiz Augusto von Dentz 		return rp->status;
113745296acdSMarcel Holtmann 
113891c4e9b1SMarcel Holtmann 	hdev->inq_tx_power = rp->tx_power;
1139c8992cffSLuiz Augusto von Dentz 
1140c8992cffSLuiz Augusto von Dentz 	return rp->status;
1141d5859e22SJohan Hedberg }
1142d5859e22SJohan Hedberg 
1143c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_def_err_data_reporting(struct hci_dev *hdev, void *data,
114400bce3fbSAlain Michaud 					     struct sk_buff *skb)
114500bce3fbSAlain Michaud {
1146c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_def_err_data_reporting *rp = data;
1147e3f3a1aeSLuiz Augusto von Dentz 
1148e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
114900bce3fbSAlain Michaud 
115000bce3fbSAlain Michaud 	if (rp->status)
1151c8992cffSLuiz Augusto von Dentz 		return rp->status;
115200bce3fbSAlain Michaud 
115300bce3fbSAlain Michaud 	hdev->err_data_reporting = rp->err_data_reporting;
1154c8992cffSLuiz Augusto von Dentz 
1155c8992cffSLuiz Augusto von Dentz 	return rp->status;
115600bce3fbSAlain Michaud }
115700bce3fbSAlain Michaud 
1158c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_def_err_data_reporting(struct hci_dev *hdev, void *data,
115900bce3fbSAlain Michaud 					      struct sk_buff *skb)
116000bce3fbSAlain Michaud {
1161c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
116200bce3fbSAlain Michaud 	struct hci_cp_write_def_err_data_reporting *cp;
116300bce3fbSAlain Michaud 
1164e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1165e3f3a1aeSLuiz Augusto von Dentz 
1166e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1167c8992cffSLuiz Augusto von Dentz 		return rp->status;
116800bce3fbSAlain Michaud 
116900bce3fbSAlain Michaud 	cp = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_ERR_DATA_REPORTING);
117000bce3fbSAlain Michaud 	if (!cp)
1171c8992cffSLuiz Augusto von Dentz 		return rp->status;
117200bce3fbSAlain Michaud 
117300bce3fbSAlain Michaud 	hdev->err_data_reporting = cp->err_data_reporting;
1174c8992cffSLuiz Augusto von Dentz 
1175c8992cffSLuiz Augusto von Dentz 	return rp->status;
117600bce3fbSAlain Michaud }
117700bce3fbSAlain Michaud 
1178c8992cffSLuiz Augusto von Dentz static u8 hci_cc_pin_code_reply(struct hci_dev *hdev, void *data,
1179c8992cffSLuiz Augusto von Dentz 				struct sk_buff *skb)
1180980e1a53SJohan Hedberg {
1181c8992cffSLuiz Augusto von Dentz 	struct hci_rp_pin_code_reply *rp = data;
1182980e1a53SJohan Hedberg 	struct hci_cp_pin_code_reply *cp;
1183980e1a53SJohan Hedberg 	struct hci_conn *conn;
1184980e1a53SJohan Hedberg 
1185e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1186980e1a53SJohan Hedberg 
118756e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
118856e5cb86SJohan Hedberg 
1189d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
1190744cf19eSJohan Hedberg 		mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
1191980e1a53SJohan Hedberg 
1192fa1bd918SMikel Astiz 	if (rp->status)
119356e5cb86SJohan Hedberg 		goto unlock;
1194980e1a53SJohan Hedberg 
1195980e1a53SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
1196980e1a53SJohan Hedberg 	if (!cp)
119756e5cb86SJohan Hedberg 		goto unlock;
1198980e1a53SJohan Hedberg 
1199980e1a53SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1200980e1a53SJohan Hedberg 	if (conn)
1201980e1a53SJohan Hedberg 		conn->pin_length = cp->pin_len;
120256e5cb86SJohan Hedberg 
120356e5cb86SJohan Hedberg unlock:
120456e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
1205c8992cffSLuiz Augusto von Dentz 	return rp->status;
1206980e1a53SJohan Hedberg }
1207980e1a53SJohan Hedberg 
1208c8992cffSLuiz Augusto von Dentz static u8 hci_cc_pin_code_neg_reply(struct hci_dev *hdev, void *data,
1209c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
1210980e1a53SJohan Hedberg {
1211c8992cffSLuiz Augusto von Dentz 	struct hci_rp_pin_code_neg_reply *rp = data;
1212e3f3a1aeSLuiz Augusto von Dentz 
1213e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1214980e1a53SJohan Hedberg 
121556e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
121656e5cb86SJohan Hedberg 
1217d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
1218744cf19eSJohan Hedberg 		mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
1219980e1a53SJohan Hedberg 						 rp->status);
122056e5cb86SJohan Hedberg 
122156e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
1222c8992cffSLuiz Augusto von Dentz 
1223c8992cffSLuiz Augusto von Dentz 	return rp->status;
1224980e1a53SJohan Hedberg }
122556e5cb86SJohan Hedberg 
1226c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_buffer_size(struct hci_dev *hdev, void *data,
12276ed58ec5SVille Tervo 				     struct sk_buff *skb)
12286ed58ec5SVille Tervo {
1229c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_buffer_size *rp = data;
1230e3f3a1aeSLuiz Augusto von Dentz 
1231e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
12326ed58ec5SVille Tervo 
12336ed58ec5SVille Tervo 	if (rp->status)
1234c8992cffSLuiz Augusto von Dentz 		return rp->status;
12356ed58ec5SVille Tervo 
12366ed58ec5SVille Tervo 	hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
12376ed58ec5SVille Tervo 	hdev->le_pkts = rp->le_max_pkt;
12386ed58ec5SVille Tervo 
12396ed58ec5SVille Tervo 	hdev->le_cnt = hdev->le_pkts;
12406ed58ec5SVille Tervo 
12416ed58ec5SVille Tervo 	BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
1242c8992cffSLuiz Augusto von Dentz 
1243c8992cffSLuiz Augusto von Dentz 	return rp->status;
12446ed58ec5SVille Tervo }
1245980e1a53SJohan Hedberg 
1246c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_local_features(struct hci_dev *hdev, void *data,
124760e77321SJohan Hedberg 					struct sk_buff *skb)
124860e77321SJohan Hedberg {
1249c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_local_features *rp = data;
125060e77321SJohan Hedberg 
125160e77321SJohan Hedberg 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
125260e77321SJohan Hedberg 
125345296acdSMarcel Holtmann 	if (rp->status)
1254c8992cffSLuiz Augusto von Dentz 		return rp->status;
125545296acdSMarcel Holtmann 
125660e77321SJohan Hedberg 	memcpy(hdev->le_features, rp->features, 8);
1257c8992cffSLuiz Augusto von Dentz 
1258c8992cffSLuiz Augusto von Dentz 	return rp->status;
125960e77321SJohan Hedberg }
126060e77321SJohan Hedberg 
1261c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_adv_tx_power(struct hci_dev *hdev, void *data,
12628fa19098SJohan Hedberg 				      struct sk_buff *skb)
12638fa19098SJohan Hedberg {
1264c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_adv_tx_power *rp = data;
1265e3f3a1aeSLuiz Augusto von Dentz 
1266e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
12678fa19098SJohan Hedberg 
126845296acdSMarcel Holtmann 	if (rp->status)
1269c8992cffSLuiz Augusto von Dentz 		return rp->status;
127045296acdSMarcel Holtmann 
12718fa19098SJohan Hedberg 	hdev->adv_tx_power = rp->tx_power;
1272c8992cffSLuiz Augusto von Dentz 
1273c8992cffSLuiz Augusto von Dentz 	return rp->status;
12748fa19098SJohan Hedberg }
12758fa19098SJohan Hedberg 
1276c8992cffSLuiz Augusto von Dentz static u8 hci_cc_user_confirm_reply(struct hci_dev *hdev, void *data,
1277c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
1278a5c29683SJohan Hedberg {
1279c8992cffSLuiz Augusto von Dentz 	struct hci_rp_user_confirm_reply *rp = data;
1280e3f3a1aeSLuiz Augusto von Dentz 
1281e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1282a5c29683SJohan Hedberg 
128356e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
128456e5cb86SJohan Hedberg 
1285d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
128604124681SGustavo F. Padovan 		mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
128704124681SGustavo F. Padovan 						 rp->status);
128856e5cb86SJohan Hedberg 
128956e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
1290c8992cffSLuiz Augusto von Dentz 
1291c8992cffSLuiz Augusto von Dentz 	return rp->status;
1292a5c29683SJohan Hedberg }
1293a5c29683SJohan Hedberg 
1294c8992cffSLuiz Augusto von Dentz static u8 hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, void *data,
1295a5c29683SJohan Hedberg 					struct sk_buff *skb)
1296a5c29683SJohan Hedberg {
1297c8992cffSLuiz Augusto von Dentz 	struct hci_rp_user_confirm_reply *rp = data;
1298e3f3a1aeSLuiz Augusto von Dentz 
1299e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1300a5c29683SJohan Hedberg 
130156e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
130256e5cb86SJohan Hedberg 
1303d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
1304744cf19eSJohan Hedberg 		mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
130504124681SGustavo F. Padovan 						     ACL_LINK, 0, rp->status);
130656e5cb86SJohan Hedberg 
130756e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
1308c8992cffSLuiz Augusto von Dentz 
1309c8992cffSLuiz Augusto von Dentz 	return rp->status;
1310a5c29683SJohan Hedberg }
1311a5c29683SJohan Hedberg 
1312c8992cffSLuiz Augusto von Dentz static u8 hci_cc_user_passkey_reply(struct hci_dev *hdev, void *data,
1313c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
13141143d458SBrian Gix {
1315c8992cffSLuiz Augusto von Dentz 	struct hci_rp_user_confirm_reply *rp = data;
1316e3f3a1aeSLuiz Augusto von Dentz 
1317e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
13181143d458SBrian Gix 
13191143d458SBrian Gix 	hci_dev_lock(hdev);
13201143d458SBrian Gix 
1321d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
1322272d90dfSJohan Hedberg 		mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
1323272d90dfSJohan Hedberg 						 0, rp->status);
13241143d458SBrian Gix 
13251143d458SBrian Gix 	hci_dev_unlock(hdev);
1326c8992cffSLuiz Augusto von Dentz 
1327c8992cffSLuiz Augusto von Dentz 	return rp->status;
13281143d458SBrian Gix }
13291143d458SBrian Gix 
1330c8992cffSLuiz Augusto von Dentz static u8 hci_cc_user_passkey_neg_reply(struct hci_dev *hdev, void *data,
13311143d458SBrian Gix 					struct sk_buff *skb)
13321143d458SBrian Gix {
1333c8992cffSLuiz Augusto von Dentz 	struct hci_rp_user_confirm_reply *rp = data;
1334e3f3a1aeSLuiz Augusto von Dentz 
1335e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
13361143d458SBrian Gix 
13371143d458SBrian Gix 	hci_dev_lock(hdev);
13381143d458SBrian Gix 
1339d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
13401143d458SBrian Gix 		mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
134104124681SGustavo F. Padovan 						     ACL_LINK, 0, rp->status);
13421143d458SBrian Gix 
13431143d458SBrian Gix 	hci_dev_unlock(hdev);
1344c8992cffSLuiz Augusto von Dentz 
1345c8992cffSLuiz Augusto von Dentz 	return rp->status;
13461143d458SBrian Gix }
13471143d458SBrian Gix 
1348c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_oob_data(struct hci_dev *hdev, void *data,
1349c35938b2SSzymon Janc 				     struct sk_buff *skb)
1350c35938b2SSzymon Janc {
1351c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_oob_data *rp = data;
1352e3f3a1aeSLuiz Augusto von Dentz 
1353e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1354c8992cffSLuiz Augusto von Dentz 
1355c8992cffSLuiz Augusto von Dentz 	return rp->status;
13564d2d2796SMarcel Holtmann }
13574d2d2796SMarcel Holtmann 
1358c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_oob_ext_data(struct hci_dev *hdev, void *data,
13594d2d2796SMarcel Holtmann 					 struct sk_buff *skb)
13604d2d2796SMarcel Holtmann {
1361c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_oob_ext_data *rp = data;
1362e3f3a1aeSLuiz Augusto von Dentz 
1363e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1364c8992cffSLuiz Augusto von Dentz 
1365c8992cffSLuiz Augusto von Dentz 	return rp->status;
1366c35938b2SSzymon Janc }
1367c35938b2SSzymon Janc 
1368c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_random_addr(struct hci_dev *hdev, void *data,
1369c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
13707a4cd51dSMarcel Holtmann {
1371c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
13727a4cd51dSMarcel Holtmann 	bdaddr_t *sent;
13737a4cd51dSMarcel Holtmann 
1374e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1375e3f3a1aeSLuiz Augusto von Dentz 
1376e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1377c8992cffSLuiz Augusto von Dentz 		return rp->status;
137845296acdSMarcel Holtmann 
13797a4cd51dSMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_RANDOM_ADDR);
13807a4cd51dSMarcel Holtmann 	if (!sent)
1381c8992cffSLuiz Augusto von Dentz 		return rp->status;
13827a4cd51dSMarcel Holtmann 
13837a4cd51dSMarcel Holtmann 	hci_dev_lock(hdev);
13847a4cd51dSMarcel Holtmann 
13857a4cd51dSMarcel Holtmann 	bacpy(&hdev->random_addr, sent);
13867a4cd51dSMarcel Holtmann 
1387c45074d6SLuiz Augusto von Dentz 	if (!bacmp(&hdev->rpa, sent)) {
1388c45074d6SLuiz Augusto von Dentz 		hci_dev_clear_flag(hdev, HCI_RPA_EXPIRED);
1389c45074d6SLuiz Augusto von Dentz 		queue_delayed_work(hdev->workqueue, &hdev->rpa_expired,
1390c45074d6SLuiz Augusto von Dentz 				   secs_to_jiffies(hdev->rpa_timeout));
1391c45074d6SLuiz Augusto von Dentz 	}
1392c45074d6SLuiz Augusto von Dentz 
13937a4cd51dSMarcel Holtmann 	hci_dev_unlock(hdev);
1394c8992cffSLuiz Augusto von Dentz 
1395c8992cffSLuiz Augusto von Dentz 	return rp->status;
13967a4cd51dSMarcel Holtmann }
13977a4cd51dSMarcel Holtmann 
1398c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_default_phy(struct hci_dev *hdev, void *data,
1399c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
14000314f286SJaganath Kanakkassery {
1401c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
14020314f286SJaganath Kanakkassery 	struct hci_cp_le_set_default_phy *cp;
14030314f286SJaganath Kanakkassery 
1404e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1405e3f3a1aeSLuiz Augusto von Dentz 
1406e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1407c8992cffSLuiz Augusto von Dentz 		return rp->status;
14080314f286SJaganath Kanakkassery 
14090314f286SJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_DEFAULT_PHY);
14100314f286SJaganath Kanakkassery 	if (!cp)
1411c8992cffSLuiz Augusto von Dentz 		return rp->status;
14120314f286SJaganath Kanakkassery 
14130314f286SJaganath Kanakkassery 	hci_dev_lock(hdev);
14140314f286SJaganath Kanakkassery 
14150314f286SJaganath Kanakkassery 	hdev->le_tx_def_phys = cp->tx_phys;
14160314f286SJaganath Kanakkassery 	hdev->le_rx_def_phys = cp->rx_phys;
14170314f286SJaganath Kanakkassery 
14180314f286SJaganath Kanakkassery 	hci_dev_unlock(hdev);
1419c8992cffSLuiz Augusto von Dentz 
1420c8992cffSLuiz Augusto von Dentz 	return rp->status;
14210314f286SJaganath Kanakkassery }
14220314f286SJaganath Kanakkassery 
1423c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_adv_set_random_addr(struct hci_dev *hdev, void *data,
1424a73c046aSJaganath Kanakkassery 					    struct sk_buff *skb)
1425a73c046aSJaganath Kanakkassery {
1426c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1427a73c046aSJaganath Kanakkassery 	struct hci_cp_le_set_adv_set_rand_addr *cp;
1428c45074d6SLuiz Augusto von Dentz 	struct adv_info *adv;
1429a73c046aSJaganath Kanakkassery 
1430e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1431e3f3a1aeSLuiz Augusto von Dentz 
1432e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1433c8992cffSLuiz Augusto von Dentz 		return rp->status;
1434a73c046aSJaganath Kanakkassery 
1435a73c046aSJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_SET_RAND_ADDR);
1436c45074d6SLuiz Augusto von Dentz 	/* Update only in case the adv instance since handle 0x00 shall be using
1437c45074d6SLuiz Augusto von Dentz 	 * HCI_OP_LE_SET_RANDOM_ADDR since that allows both extended and
1438c45074d6SLuiz Augusto von Dentz 	 * non-extended adverting.
1439c45074d6SLuiz Augusto von Dentz 	 */
1440c45074d6SLuiz Augusto von Dentz 	if (!cp || !cp->handle)
1441c8992cffSLuiz Augusto von Dentz 		return rp->status;
1442a73c046aSJaganath Kanakkassery 
1443a73c046aSJaganath Kanakkassery 	hci_dev_lock(hdev);
1444a73c046aSJaganath Kanakkassery 
1445c45074d6SLuiz Augusto von Dentz 	adv = hci_find_adv_instance(hdev, cp->handle);
1446c45074d6SLuiz Augusto von Dentz 	if (adv) {
1447c45074d6SLuiz Augusto von Dentz 		bacpy(&adv->random_addr, &cp->bdaddr);
1448c45074d6SLuiz Augusto von Dentz 		if (!bacmp(&hdev->rpa, &cp->bdaddr)) {
1449c45074d6SLuiz Augusto von Dentz 			adv->rpa_expired = false;
1450c45074d6SLuiz Augusto von Dentz 			queue_delayed_work(hdev->workqueue,
1451c45074d6SLuiz Augusto von Dentz 					   &adv->rpa_expired_cb,
1452c45074d6SLuiz Augusto von Dentz 					   secs_to_jiffies(hdev->rpa_timeout));
1453c45074d6SLuiz Augusto von Dentz 		}
1454a73c046aSJaganath Kanakkassery 	}
1455a73c046aSJaganath Kanakkassery 
1456a73c046aSJaganath Kanakkassery 	hci_dev_unlock(hdev);
1457c8992cffSLuiz Augusto von Dentz 
1458c8992cffSLuiz Augusto von Dentz 	return rp->status;
1459a73c046aSJaganath Kanakkassery }
1460a73c046aSJaganath Kanakkassery 
1461c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_remove_adv_set(struct hci_dev *hdev, void *data,
1462c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
1463cba6b758SLuiz Augusto von Dentz {
1464c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1465cba6b758SLuiz Augusto von Dentz 	u8 *instance;
1466cba6b758SLuiz Augusto von Dentz 	int err;
1467cba6b758SLuiz Augusto von Dentz 
1468e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1469e3f3a1aeSLuiz Augusto von Dentz 
1470e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1471c8992cffSLuiz Augusto von Dentz 		return rp->status;
1472cba6b758SLuiz Augusto von Dentz 
1473cba6b758SLuiz Augusto von Dentz 	instance = hci_sent_cmd_data(hdev, HCI_OP_LE_REMOVE_ADV_SET);
1474cba6b758SLuiz Augusto von Dentz 	if (!instance)
1475c8992cffSLuiz Augusto von Dentz 		return rp->status;
1476cba6b758SLuiz Augusto von Dentz 
1477cba6b758SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
1478cba6b758SLuiz Augusto von Dentz 
1479cba6b758SLuiz Augusto von Dentz 	err = hci_remove_adv_instance(hdev, *instance);
1480cba6b758SLuiz Augusto von Dentz 	if (!err)
1481cba6b758SLuiz Augusto von Dentz 		mgmt_advertising_removed(hci_skb_sk(hdev->sent_cmd), hdev,
1482cba6b758SLuiz Augusto von Dentz 					 *instance);
1483cba6b758SLuiz Augusto von Dentz 
1484cba6b758SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
1485c8992cffSLuiz Augusto von Dentz 
1486c8992cffSLuiz Augusto von Dentz 	return rp->status;
1487cba6b758SLuiz Augusto von Dentz }
1488cba6b758SLuiz Augusto von Dentz 
1489c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_clear_adv_sets(struct hci_dev *hdev, void *data,
1490c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
1491cba6b758SLuiz Augusto von Dentz {
1492c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1493cba6b758SLuiz Augusto von Dentz 	struct adv_info *adv, *n;
1494cba6b758SLuiz Augusto von Dentz 	int err;
1495cba6b758SLuiz Augusto von Dentz 
1496e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1497e3f3a1aeSLuiz Augusto von Dentz 
1498e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1499c8992cffSLuiz Augusto von Dentz 		return rp->status;
1500cba6b758SLuiz Augusto von Dentz 
1501cba6b758SLuiz Augusto von Dentz 	if (!hci_sent_cmd_data(hdev, HCI_OP_LE_CLEAR_ADV_SETS))
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 	list_for_each_entry_safe(adv, n, &hdev->adv_instances, list) {
1507cba6b758SLuiz Augusto von Dentz 		u8 instance = adv->instance;
1508cba6b758SLuiz Augusto von Dentz 
1509cba6b758SLuiz Augusto von Dentz 		err = hci_remove_adv_instance(hdev, instance);
1510cba6b758SLuiz Augusto von Dentz 		if (!err)
1511cba6b758SLuiz Augusto von Dentz 			mgmt_advertising_removed(hci_skb_sk(hdev->sent_cmd),
1512cba6b758SLuiz Augusto von Dentz 						 hdev, instance);
1513cba6b758SLuiz Augusto von Dentz 	}
1514cba6b758SLuiz Augusto von Dentz 
1515cba6b758SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
1516c8992cffSLuiz Augusto von Dentz 
1517c8992cffSLuiz Augusto von Dentz 	return rp->status;
1518cba6b758SLuiz Augusto von Dentz }
1519cba6b758SLuiz Augusto von Dentz 
1520c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_transmit_power(struct hci_dev *hdev, void *data,
15217c395ea5SDaniel Winkler 					struct sk_buff *skb)
15227c395ea5SDaniel Winkler {
1523c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_transmit_power *rp = data;
1524e3f3a1aeSLuiz Augusto von Dentz 
1525e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
15267c395ea5SDaniel Winkler 
15277c395ea5SDaniel Winkler 	if (rp->status)
1528c8992cffSLuiz Augusto von Dentz 		return rp->status;
15297c395ea5SDaniel Winkler 
15307c395ea5SDaniel Winkler 	hdev->min_le_tx_power = rp->min_le_tx_power;
15317c395ea5SDaniel Winkler 	hdev->max_le_tx_power = rp->max_le_tx_power;
1532c8992cffSLuiz Augusto von Dentz 
1533c8992cffSLuiz Augusto von Dentz 	return rp->status;
15347c395ea5SDaniel Winkler }
15357c395ea5SDaniel Winkler 
1536853b70b5SLuiz Augusto von Dentz static u8 hci_cc_le_set_privacy_mode(struct hci_dev *hdev, void *data,
1537853b70b5SLuiz Augusto von Dentz 				     struct sk_buff *skb)
1538853b70b5SLuiz Augusto von Dentz {
1539853b70b5SLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1540853b70b5SLuiz Augusto von Dentz 	struct hci_cp_le_set_privacy_mode *cp;
1541853b70b5SLuiz Augusto von Dentz 	struct hci_conn_params *params;
1542853b70b5SLuiz Augusto von Dentz 
1543853b70b5SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1544853b70b5SLuiz Augusto von Dentz 
1545853b70b5SLuiz Augusto von Dentz 	if (rp->status)
1546853b70b5SLuiz Augusto von Dentz 		return rp->status;
1547853b70b5SLuiz Augusto von Dentz 
1548853b70b5SLuiz Augusto von Dentz 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_PRIVACY_MODE);
1549853b70b5SLuiz Augusto von Dentz 	if (!cp)
1550853b70b5SLuiz Augusto von Dentz 		return rp->status;
1551853b70b5SLuiz Augusto von Dentz 
1552853b70b5SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
1553853b70b5SLuiz Augusto von Dentz 
1554853b70b5SLuiz Augusto von Dentz 	params = hci_conn_params_lookup(hdev, &cp->bdaddr, cp->bdaddr_type);
1555853b70b5SLuiz Augusto von Dentz 	if (params)
1556853b70b5SLuiz Augusto von Dentz 		params->privacy_mode = cp->mode;
1557853b70b5SLuiz Augusto von Dentz 
1558853b70b5SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
1559853b70b5SLuiz Augusto von Dentz 
1560853b70b5SLuiz Augusto von Dentz 	return rp->status;
1561853b70b5SLuiz Augusto von Dentz }
1562853b70b5SLuiz Augusto von Dentz 
1563c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_adv_enable(struct hci_dev *hdev, void *data,
1564c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
1565c1d5dc4aSJohan Hedberg {
1566c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1567e3f3a1aeSLuiz Augusto von Dentz 	__u8 *sent;
1568c1d5dc4aSJohan Hedberg 
1569e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1570e3f3a1aeSLuiz Augusto von Dentz 
1571e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1572c8992cffSLuiz Augusto von Dentz 		return rp->status;
1573c1d5dc4aSJohan Hedberg 
157445296acdSMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
157545296acdSMarcel Holtmann 	if (!sent)
1576c8992cffSLuiz Augusto von Dentz 		return rp->status;
15773c857757SJohan Hedberg 
1578c1d5dc4aSJohan Hedberg 	hci_dev_lock(hdev);
1579c1d5dc4aSJohan Hedberg 
158049c922bbSStephen Hemminger 	/* If we're doing connection initiation as peripheral. Set a
15813c857757SJohan Hedberg 	 * timeout in case something goes wrong.
15823c857757SJohan Hedberg 	 */
15833c857757SJohan Hedberg 	if (*sent) {
15843c857757SJohan Hedberg 		struct hci_conn *conn;
15853c857757SJohan Hedberg 
1586a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_LE_ADV);
158766c417c1SJohan Hedberg 
1588e7d9ab73SJakub Pawlowski 		conn = hci_lookup_le_connect(hdev);
15893c857757SJohan Hedberg 		if (conn)
15903c857757SJohan Hedberg 			queue_delayed_work(hdev->workqueue,
15913c857757SJohan Hedberg 					   &conn->le_conn_timeout,
159209ae260bSJohan Hedberg 					   conn->conn_timeout);
159366c417c1SJohan Hedberg 	} else {
1594a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LE_ADV);
15953c857757SJohan Hedberg 	}
15963c857757SJohan Hedberg 
159704b4edcbSJohan Hedberg 	hci_dev_unlock(hdev);
1598c8992cffSLuiz Augusto von Dentz 
1599c8992cffSLuiz Augusto von Dentz 	return rp->status;
1600c1d5dc4aSJohan Hedberg }
1601c1d5dc4aSJohan Hedberg 
1602c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_ext_adv_enable(struct hci_dev *hdev, void *data,
1603de181e88SJaganath Kanakkassery 				       struct sk_buff *skb)
1604de181e88SJaganath Kanakkassery {
1605de181e88SJaganath Kanakkassery 	struct hci_cp_le_set_ext_adv_enable *cp;
160610279313SLuiz Augusto von Dentz 	struct hci_cp_ext_adv_set *set;
160710279313SLuiz Augusto von Dentz 	struct adv_info *adv = NULL, *n;
1608c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1609de181e88SJaganath Kanakkassery 
1610e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1611e3f3a1aeSLuiz Augusto von Dentz 
1612e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1613c8992cffSLuiz Augusto von Dentz 		return rp->status;
1614de181e88SJaganath Kanakkassery 
1615de181e88SJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_ADV_ENABLE);
1616de181e88SJaganath Kanakkassery 	if (!cp)
1617c8992cffSLuiz Augusto von Dentz 		return rp->status;
1618de181e88SJaganath Kanakkassery 
161910279313SLuiz Augusto von Dentz 	set = (void *)cp->data;
162010279313SLuiz Augusto von Dentz 
1621de181e88SJaganath Kanakkassery 	hci_dev_lock(hdev);
1622de181e88SJaganath Kanakkassery 
162310279313SLuiz Augusto von Dentz 	if (cp->num_of_sets)
162410279313SLuiz Augusto von Dentz 		adv = hci_find_adv_instance(hdev, set->handle);
162510279313SLuiz Augusto von Dentz 
1626de181e88SJaganath Kanakkassery 	if (cp->enable) {
1627de181e88SJaganath Kanakkassery 		struct hci_conn *conn;
1628de181e88SJaganath Kanakkassery 
1629de181e88SJaganath Kanakkassery 		hci_dev_set_flag(hdev, HCI_LE_ADV);
1630de181e88SJaganath Kanakkassery 
163110279313SLuiz Augusto von Dentz 		if (adv)
163210279313SLuiz Augusto von Dentz 			adv->enabled = true;
163310279313SLuiz Augusto von Dentz 
1634de181e88SJaganath Kanakkassery 		conn = hci_lookup_le_connect(hdev);
1635de181e88SJaganath Kanakkassery 		if (conn)
1636de181e88SJaganath Kanakkassery 			queue_delayed_work(hdev->workqueue,
1637de181e88SJaganath Kanakkassery 					   &conn->le_conn_timeout,
1638de181e88SJaganath Kanakkassery 					   conn->conn_timeout);
163945b7749fSJaganath Kanakkassery 	} else {
16402128939fSArchie Pusaka 		if (cp->num_of_sets) {
16412128939fSArchie Pusaka 			if (adv)
164210279313SLuiz Augusto von Dentz 				adv->enabled = false;
16432128939fSArchie Pusaka 
164410279313SLuiz Augusto von Dentz 			/* If just one instance was disabled check if there are
164510279313SLuiz Augusto von Dentz 			 * any other instance enabled before clearing HCI_LE_ADV
164610279313SLuiz Augusto von Dentz 			 */
164710279313SLuiz Augusto von Dentz 			list_for_each_entry_safe(adv, n, &hdev->adv_instances,
164810279313SLuiz Augusto von Dentz 						 list) {
164910279313SLuiz Augusto von Dentz 				if (adv->enabled)
165010279313SLuiz Augusto von Dentz 					goto unlock;
165110279313SLuiz Augusto von Dentz 			}
165210279313SLuiz Augusto von Dentz 		} else {
165310279313SLuiz Augusto von Dentz 			/* All instances shall be considered disabled */
165410279313SLuiz Augusto von Dentz 			list_for_each_entry_safe(adv, n, &hdev->adv_instances,
165510279313SLuiz Augusto von Dentz 						 list)
165610279313SLuiz Augusto von Dentz 				adv->enabled = false;
165710279313SLuiz Augusto von Dentz 		}
165810279313SLuiz Augusto von Dentz 
165945b7749fSJaganath Kanakkassery 		hci_dev_clear_flag(hdev, HCI_LE_ADV);
1660de181e88SJaganath Kanakkassery 	}
1661de181e88SJaganath Kanakkassery 
166210279313SLuiz Augusto von Dentz unlock:
1663de181e88SJaganath Kanakkassery 	hci_dev_unlock(hdev);
1664c8992cffSLuiz Augusto von Dentz 	return rp->status;
1665de181e88SJaganath Kanakkassery }
1666de181e88SJaganath Kanakkassery 
1667c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_scan_param(struct hci_dev *hdev, void *data,
1668c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
1669533553f8SMarcel Holtmann {
1670533553f8SMarcel Holtmann 	struct hci_cp_le_set_scan_param *cp;
1671c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1672533553f8SMarcel Holtmann 
1673e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1674e3f3a1aeSLuiz Augusto von Dentz 
1675e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1676c8992cffSLuiz Augusto von Dentz 		return rp->status;
167745296acdSMarcel Holtmann 
1678533553f8SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_PARAM);
1679533553f8SMarcel Holtmann 	if (!cp)
1680c8992cffSLuiz Augusto von Dentz 		return rp->status;
1681533553f8SMarcel Holtmann 
1682533553f8SMarcel Holtmann 	hci_dev_lock(hdev);
1683533553f8SMarcel Holtmann 
1684533553f8SMarcel Holtmann 	hdev->le_scan_type = cp->type;
1685533553f8SMarcel Holtmann 
1686533553f8SMarcel Holtmann 	hci_dev_unlock(hdev);
1687c8992cffSLuiz Augusto von Dentz 
1688c8992cffSLuiz Augusto von Dentz 	return rp->status;
1689533553f8SMarcel Holtmann }
1690533553f8SMarcel Holtmann 
1691c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_ext_scan_param(struct hci_dev *hdev, void *data,
1692a2344b9eSJaganath Kanakkassery 				       struct sk_buff *skb)
1693a2344b9eSJaganath Kanakkassery {
1694a2344b9eSJaganath Kanakkassery 	struct hci_cp_le_set_ext_scan_params *cp;
1695c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1696a2344b9eSJaganath Kanakkassery 	struct hci_cp_le_scan_phy_params *phy_param;
1697a2344b9eSJaganath Kanakkassery 
1698e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1699e3f3a1aeSLuiz Augusto von Dentz 
1700e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1701c8992cffSLuiz Augusto von Dentz 		return rp->status;
1702a2344b9eSJaganath Kanakkassery 
1703a2344b9eSJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_SCAN_PARAMS);
1704a2344b9eSJaganath Kanakkassery 	if (!cp)
1705c8992cffSLuiz Augusto von Dentz 		return rp->status;
1706a2344b9eSJaganath Kanakkassery 
1707a2344b9eSJaganath Kanakkassery 	phy_param = (void *)cp->data;
1708a2344b9eSJaganath Kanakkassery 
1709a2344b9eSJaganath Kanakkassery 	hci_dev_lock(hdev);
1710a2344b9eSJaganath Kanakkassery 
1711a2344b9eSJaganath Kanakkassery 	hdev->le_scan_type = phy_param->type;
1712a2344b9eSJaganath Kanakkassery 
1713a2344b9eSJaganath Kanakkassery 	hci_dev_unlock(hdev);
1714c8992cffSLuiz Augusto von Dentz 
1715c8992cffSLuiz Augusto von Dentz 	return rp->status;
1716a2344b9eSJaganath Kanakkassery }
1717a2344b9eSJaganath Kanakkassery 
1718b9a6328fSJohan Hedberg static bool has_pending_adv_report(struct hci_dev *hdev)
1719b9a6328fSJohan Hedberg {
1720b9a6328fSJohan Hedberg 	struct discovery_state *d = &hdev->discovery;
1721b9a6328fSJohan Hedberg 
1722b9a6328fSJohan Hedberg 	return bacmp(&d->last_adv_addr, BDADDR_ANY);
1723b9a6328fSJohan Hedberg }
1724b9a6328fSJohan Hedberg 
1725b9a6328fSJohan Hedberg static void clear_pending_adv_report(struct hci_dev *hdev)
1726b9a6328fSJohan Hedberg {
1727b9a6328fSJohan Hedberg 	struct discovery_state *d = &hdev->discovery;
1728b9a6328fSJohan Hedberg 
1729b9a6328fSJohan Hedberg 	bacpy(&d->last_adv_addr, BDADDR_ANY);
1730b9a6328fSJohan Hedberg 	d->last_adv_data_len = 0;
1731b9a6328fSJohan Hedberg }
1732b9a6328fSJohan Hedberg 
1733b9a6328fSJohan Hedberg static void store_pending_adv_report(struct hci_dev *hdev, bdaddr_t *bdaddr,
1734c70a7e4cSMarcel Holtmann 				     u8 bdaddr_type, s8 rssi, u32 flags,
1735c70a7e4cSMarcel Holtmann 				     u8 *data, u8 len)
1736b9a6328fSJohan Hedberg {
1737b9a6328fSJohan Hedberg 	struct discovery_state *d = &hdev->discovery;
1738b9a6328fSJohan Hedberg 
1739a2ec905dSAlain Michaud 	if (len > HCI_MAX_AD_LENGTH)
1740a2ec905dSAlain Michaud 		return;
1741a2ec905dSAlain Michaud 
1742b9a6328fSJohan Hedberg 	bacpy(&d->last_adv_addr, bdaddr);
1743b9a6328fSJohan Hedberg 	d->last_adv_addr_type = bdaddr_type;
1744ff5cd29fSJohan Hedberg 	d->last_adv_rssi = rssi;
1745c70a7e4cSMarcel Holtmann 	d->last_adv_flags = flags;
1746b9a6328fSJohan Hedberg 	memcpy(d->last_adv_data, data, len);
1747b9a6328fSJohan Hedberg 	d->last_adv_data_len = len;
1748b9a6328fSJohan Hedberg }
1749b9a6328fSJohan Hedberg 
17503baef810SJaganath Kanakkassery static void le_set_scan_enable_complete(struct hci_dev *hdev, u8 enable)
1751eb9d91f5SAndre Guedes {
17525c1a4c8fSJaganath Kanakkassery 	hci_dev_lock(hdev);
17535c1a4c8fSJaganath Kanakkassery 
17543baef810SJaganath Kanakkassery 	switch (enable) {
17553fd319b8SAndre Guedes 	case LE_SCAN_ENABLE:
1756a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_LE_SCAN);
1757b9a6328fSJohan Hedberg 		if (hdev->le_scan_type == LE_SCAN_ACTIVE)
1758b9a6328fSJohan Hedberg 			clear_pending_adv_report(hdev);
1759b338d917SBrian Gix 		if (hci_dev_test_flag(hdev, HCI_MESH))
1760b338d917SBrian Gix 			hci_discovery_set_state(hdev, DISCOVERY_FINDING);
176168a8aea4SAndrei Emeltchenko 		break;
176268a8aea4SAndrei Emeltchenko 
176376a388beSAndre Guedes 	case LE_SCAN_DISABLE:
1764b9a6328fSJohan Hedberg 		/* We do this here instead of when setting DISCOVERY_STOPPED
1765b9a6328fSJohan Hedberg 		 * since the latter would potentially require waiting for
1766b9a6328fSJohan Hedberg 		 * inquiry to stop too.
1767b9a6328fSJohan Hedberg 		 */
1768b9a6328fSJohan Hedberg 		if (has_pending_adv_report(hdev)) {
1769b9a6328fSJohan Hedberg 			struct discovery_state *d = &hdev->discovery;
1770b9a6328fSJohan Hedberg 
1771b9a6328fSJohan Hedberg 			mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
1772ab0aa433SJohan Hedberg 					  d->last_adv_addr_type, NULL,
1773c70a7e4cSMarcel Holtmann 					  d->last_adv_rssi, d->last_adv_flags,
1774ab0aa433SJohan Hedberg 					  d->last_adv_data,
1775b338d917SBrian Gix 					  d->last_adv_data_len, NULL, 0, 0);
1776b9a6328fSJohan Hedberg 		}
1777b9a6328fSJohan Hedberg 
1778317ac8cbSJohan Hedberg 		/* Cancel this timer so that we don't try to disable scanning
1779317ac8cbSJohan Hedberg 		 * when it's already disabled.
1780317ac8cbSJohan Hedberg 		 */
1781317ac8cbSJohan Hedberg 		cancel_delayed_work(&hdev->le_scan_disable);
1782317ac8cbSJohan Hedberg 
1783a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LE_SCAN);
1784e8bb6b97SJohan Hedberg 
178581ad6fd9SJohan Hedberg 		/* The HCI_LE_SCAN_INTERRUPTED flag indicates that we
178681ad6fd9SJohan Hedberg 		 * interrupted scanning due to a connect request. Mark
1787abfeea47SLuiz Augusto von Dentz 		 * therefore discovery as stopped.
178881ad6fd9SJohan Hedberg 		 */
1789a69d8927SMarcel Holtmann 		if (hci_dev_test_and_clear_flag(hdev, HCI_LE_SCAN_INTERRUPTED))
179081ad6fd9SJohan Hedberg 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1791b338d917SBrian Gix 		else if (!hci_dev_test_flag(hdev, HCI_LE_ADV) &&
1792b338d917SBrian Gix 			 hdev->discovery.state == DISCOVERY_FINDING)
1793b338d917SBrian Gix 			queue_work(hdev->workqueue, &hdev->reenable_adv_work);
1794e8bb6b97SJohan Hedberg 
179568a8aea4SAndrei Emeltchenko 		break;
179668a8aea4SAndrei Emeltchenko 
179768a8aea4SAndrei Emeltchenko 	default:
17982064ee33SMarcel Holtmann 		bt_dev_err(hdev, "use of reserved LE_Scan_Enable param %d",
17993baef810SJaganath Kanakkassery 			   enable);
180068a8aea4SAndrei Emeltchenko 		break;
180135815085SAndre Guedes 	}
18025c1a4c8fSJaganath Kanakkassery 
18035c1a4c8fSJaganath Kanakkassery 	hci_dev_unlock(hdev);
1804eb9d91f5SAndre Guedes }
1805eb9d91f5SAndre Guedes 
1806c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_scan_enable(struct hci_dev *hdev, void *data,
18073baef810SJaganath Kanakkassery 				    struct sk_buff *skb)
18083baef810SJaganath Kanakkassery {
18093baef810SJaganath Kanakkassery 	struct hci_cp_le_set_scan_enable *cp;
1810c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
18113baef810SJaganath Kanakkassery 
1812e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1813e3f3a1aeSLuiz Augusto von Dentz 
1814e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1815c8992cffSLuiz Augusto von Dentz 		return rp->status;
18163baef810SJaganath Kanakkassery 
18173baef810SJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
18183baef810SJaganath Kanakkassery 	if (!cp)
1819c8992cffSLuiz Augusto von Dentz 		return rp->status;
18203baef810SJaganath Kanakkassery 
18213baef810SJaganath Kanakkassery 	le_set_scan_enable_complete(hdev, cp->enable);
1822c8992cffSLuiz Augusto von Dentz 
1823c8992cffSLuiz Augusto von Dentz 	return rp->status;
18243baef810SJaganath Kanakkassery }
18253baef810SJaganath Kanakkassery 
1826c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_ext_scan_enable(struct hci_dev *hdev, void *data,
1827a2344b9eSJaganath Kanakkassery 					struct sk_buff *skb)
1828a2344b9eSJaganath Kanakkassery {
1829a2344b9eSJaganath Kanakkassery 	struct hci_cp_le_set_ext_scan_enable *cp;
1830c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1831a2344b9eSJaganath Kanakkassery 
1832e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1833e3f3a1aeSLuiz Augusto von Dentz 
1834e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1835c8992cffSLuiz Augusto von Dentz 		return rp->status;
1836a2344b9eSJaganath Kanakkassery 
1837a2344b9eSJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_SCAN_ENABLE);
1838a2344b9eSJaganath Kanakkassery 	if (!cp)
1839c8992cffSLuiz Augusto von Dentz 		return rp->status;
1840a2344b9eSJaganath Kanakkassery 
1841a2344b9eSJaganath Kanakkassery 	le_set_scan_enable_complete(hdev, cp->enable);
1842c8992cffSLuiz Augusto von Dentz 
1843c8992cffSLuiz Augusto von Dentz 	return rp->status;
1844a2344b9eSJaganath Kanakkassery }
1845a2344b9eSJaganath Kanakkassery 
1846c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_num_adv_sets(struct hci_dev *hdev, void *data,
18476b49bcb4SJaganath Kanakkassery 				      struct sk_buff *skb)
18486b49bcb4SJaganath Kanakkassery {
1849c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_num_supported_adv_sets *rp = data;
1850e3f3a1aeSLuiz Augusto von Dentz 
1851e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x No of Adv sets %u", rp->status,
18526b49bcb4SJaganath Kanakkassery 		   rp->num_of_sets);
18536b49bcb4SJaganath Kanakkassery 
18546b49bcb4SJaganath Kanakkassery 	if (rp->status)
1855c8992cffSLuiz Augusto von Dentz 		return rp->status;
18566b49bcb4SJaganath Kanakkassery 
18576b49bcb4SJaganath Kanakkassery 	hdev->le_num_of_adv_sets = rp->num_of_sets;
1858c8992cffSLuiz Augusto von Dentz 
1859c8992cffSLuiz Augusto von Dentz 	return rp->status;
18606b49bcb4SJaganath Kanakkassery }
18616b49bcb4SJaganath Kanakkassery 
1862c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_accept_list_size(struct hci_dev *hdev, void *data,
1863cf1d081fSJohan Hedberg 					  struct sk_buff *skb)
1864cf1d081fSJohan Hedberg {
1865c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_accept_list_size *rp = data;
1866e3f3a1aeSLuiz Augusto von Dentz 
1867e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x size %u", rp->status, rp->size);
1868cf1d081fSJohan Hedberg 
186945296acdSMarcel Holtmann 	if (rp->status)
1870c8992cffSLuiz Augusto von Dentz 		return rp->status;
187145296acdSMarcel Holtmann 
18723d4f9c00SArchie Pusaka 	hdev->le_accept_list_size = rp->size;
1873c8992cffSLuiz Augusto von Dentz 
1874c8992cffSLuiz Augusto von Dentz 	return rp->status;
1875cf1d081fSJohan Hedberg }
1876cf1d081fSJohan Hedberg 
1877c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_clear_accept_list(struct hci_dev *hdev, void *data,
18780f36b589SMarcel Holtmann 				      struct sk_buff *skb)
18790f36b589SMarcel Holtmann {
1880c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
18810f36b589SMarcel Holtmann 
1882e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1883e3f3a1aeSLuiz Augusto von Dentz 
1884e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1885c8992cffSLuiz Augusto von Dentz 		return rp->status;
188645296acdSMarcel Holtmann 
18875e2b6064SNiels Dossche 	hci_dev_lock(hdev);
18883d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->le_accept_list);
18895e2b6064SNiels Dossche 	hci_dev_unlock(hdev);
1890c8992cffSLuiz Augusto von Dentz 
1891c8992cffSLuiz Augusto von Dentz 	return rp->status;
18920f36b589SMarcel Holtmann }
18930f36b589SMarcel Holtmann 
1894c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_add_to_accept_list(struct hci_dev *hdev, void *data,
18950f36b589SMarcel Holtmann 				       struct sk_buff *skb)
18960f36b589SMarcel Holtmann {
18973d4f9c00SArchie Pusaka 	struct hci_cp_le_add_to_accept_list *sent;
1898c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
18990f36b589SMarcel Holtmann 
1900e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1901e3f3a1aeSLuiz Augusto von Dentz 
1902e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1903c8992cffSLuiz Augusto von Dentz 		return rp->status;
190445296acdSMarcel Holtmann 
19053d4f9c00SArchie Pusaka 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_ACCEPT_LIST);
19060f36b589SMarcel Holtmann 	if (!sent)
1907c8992cffSLuiz Augusto von Dentz 		return rp->status;
19080f36b589SMarcel Holtmann 
19095e2b6064SNiels Dossche 	hci_dev_lock(hdev);
19103d4f9c00SArchie Pusaka 	hci_bdaddr_list_add(&hdev->le_accept_list, &sent->bdaddr,
1911dcc36c16SJohan Hedberg 			    sent->bdaddr_type);
19125e2b6064SNiels Dossche 	hci_dev_unlock(hdev);
1913c8992cffSLuiz Augusto von Dentz 
1914c8992cffSLuiz Augusto von Dentz 	return rp->status;
19150f36b589SMarcel Holtmann }
19160f36b589SMarcel Holtmann 
1917c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_del_from_accept_list(struct hci_dev *hdev, void *data,
19180f36b589SMarcel Holtmann 					 struct sk_buff *skb)
19190f36b589SMarcel Holtmann {
19203d4f9c00SArchie Pusaka 	struct hci_cp_le_del_from_accept_list *sent;
1921c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
19220f36b589SMarcel Holtmann 
1923e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1924e3f3a1aeSLuiz Augusto von Dentz 
1925e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1926c8992cffSLuiz Augusto von Dentz 		return rp->status;
192745296acdSMarcel Holtmann 
19283d4f9c00SArchie Pusaka 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_ACCEPT_LIST);
19290f36b589SMarcel Holtmann 	if (!sent)
1930c8992cffSLuiz Augusto von Dentz 		return rp->status;
19310f36b589SMarcel Holtmann 
19325e2b6064SNiels Dossche 	hci_dev_lock(hdev);
19333d4f9c00SArchie Pusaka 	hci_bdaddr_list_del(&hdev->le_accept_list, &sent->bdaddr,
1934dcc36c16SJohan Hedberg 			    sent->bdaddr_type);
19355e2b6064SNiels Dossche 	hci_dev_unlock(hdev);
1936c8992cffSLuiz Augusto von Dentz 
1937c8992cffSLuiz Augusto von Dentz 	return rp->status;
19380f36b589SMarcel Holtmann }
19390f36b589SMarcel Holtmann 
1940c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_supported_states(struct hci_dev *hdev, void *data,
19419b008c04SJohan Hedberg 					  struct sk_buff *skb)
19429b008c04SJohan Hedberg {
1943c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_supported_states *rp = data;
1944e3f3a1aeSLuiz Augusto von Dentz 
1945e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
19469b008c04SJohan Hedberg 
194745296acdSMarcel Holtmann 	if (rp->status)
1948c8992cffSLuiz Augusto von Dentz 		return rp->status;
194945296acdSMarcel Holtmann 
19509b008c04SJohan Hedberg 	memcpy(hdev->le_states, rp->le_states, 8);
1951c8992cffSLuiz Augusto von Dentz 
1952c8992cffSLuiz Augusto von Dentz 	return rp->status;
19539b008c04SJohan Hedberg }
19549b008c04SJohan Hedberg 
1955c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_def_data_len(struct hci_dev *hdev, void *data,
1956a8e1bfaaSMarcel Holtmann 				      struct sk_buff *skb)
1957a8e1bfaaSMarcel Holtmann {
1958c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_def_data_len *rp = data;
1959e3f3a1aeSLuiz Augusto von Dentz 
1960e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1961a8e1bfaaSMarcel Holtmann 
1962a8e1bfaaSMarcel Holtmann 	if (rp->status)
1963c8992cffSLuiz Augusto von Dentz 		return rp->status;
1964a8e1bfaaSMarcel Holtmann 
1965a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_len = le16_to_cpu(rp->tx_len);
1966a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_time = le16_to_cpu(rp->tx_time);
1967c8992cffSLuiz Augusto von Dentz 
1968c8992cffSLuiz Augusto von Dentz 	return rp->status;
1969a8e1bfaaSMarcel Holtmann }
1970a8e1bfaaSMarcel Holtmann 
1971c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_write_def_data_len(struct hci_dev *hdev, void *data,
1972a8e1bfaaSMarcel Holtmann 				       struct sk_buff *skb)
1973a8e1bfaaSMarcel Holtmann {
1974a8e1bfaaSMarcel Holtmann 	struct hci_cp_le_write_def_data_len *sent;
1975c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1976a8e1bfaaSMarcel Holtmann 
1977e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1978e3f3a1aeSLuiz Augusto von Dentz 
1979e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1980c8992cffSLuiz Augusto von Dentz 		return rp->status;
1981a8e1bfaaSMarcel Holtmann 
1982a8e1bfaaSMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_WRITE_DEF_DATA_LEN);
1983a8e1bfaaSMarcel Holtmann 	if (!sent)
1984c8992cffSLuiz Augusto von Dentz 		return rp->status;
1985a8e1bfaaSMarcel Holtmann 
1986a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_len = le16_to_cpu(sent->tx_len);
1987a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_time = le16_to_cpu(sent->tx_time);
1988c8992cffSLuiz Augusto von Dentz 
1989c8992cffSLuiz Augusto von Dentz 	return rp->status;
1990a8e1bfaaSMarcel Holtmann }
1991a8e1bfaaSMarcel Holtmann 
1992c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_add_to_resolv_list(struct hci_dev *hdev, void *data,
1993b950aa88SAnkit Navik 				       struct sk_buff *skb)
1994b950aa88SAnkit Navik {
1995b950aa88SAnkit Navik 	struct hci_cp_le_add_to_resolv_list *sent;
1996c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1997b950aa88SAnkit Navik 
1998e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1999e3f3a1aeSLuiz Augusto von Dentz 
2000e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
2001c8992cffSLuiz Augusto von Dentz 		return rp->status;
2002b950aa88SAnkit Navik 
2003b950aa88SAnkit Navik 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_RESOLV_LIST);
2004b950aa88SAnkit Navik 	if (!sent)
2005c8992cffSLuiz Augusto von Dentz 		return rp->status;
2006b950aa88SAnkit Navik 
20075e2b6064SNiels Dossche 	hci_dev_lock(hdev);
2008b950aa88SAnkit Navik 	hci_bdaddr_list_add_with_irk(&hdev->le_resolv_list, &sent->bdaddr,
2009b950aa88SAnkit Navik 				sent->bdaddr_type, sent->peer_irk,
2010b950aa88SAnkit Navik 				sent->local_irk);
20115e2b6064SNiels Dossche 	hci_dev_unlock(hdev);
2012c8992cffSLuiz Augusto von Dentz 
2013c8992cffSLuiz Augusto von Dentz 	return rp->status;
2014b950aa88SAnkit Navik }
2015b950aa88SAnkit Navik 
2016c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_del_from_resolv_list(struct hci_dev *hdev, void *data,
2017b950aa88SAnkit Navik 					 struct sk_buff *skb)
2018b950aa88SAnkit Navik {
2019b950aa88SAnkit Navik 	struct hci_cp_le_del_from_resolv_list *sent;
2020c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
2021b950aa88SAnkit Navik 
2022e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2023e3f3a1aeSLuiz Augusto von Dentz 
2024e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
2025c8992cffSLuiz Augusto von Dentz 		return rp->status;
2026b950aa88SAnkit Navik 
2027b950aa88SAnkit Navik 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_RESOLV_LIST);
2028b950aa88SAnkit Navik 	if (!sent)
2029c8992cffSLuiz Augusto von Dentz 		return rp->status;
2030b950aa88SAnkit Navik 
20315e2b6064SNiels Dossche 	hci_dev_lock(hdev);
2032b950aa88SAnkit Navik 	hci_bdaddr_list_del_with_irk(&hdev->le_resolv_list, &sent->bdaddr,
2033b950aa88SAnkit Navik 			    sent->bdaddr_type);
20345e2b6064SNiels Dossche 	hci_dev_unlock(hdev);
2035c8992cffSLuiz Augusto von Dentz 
2036c8992cffSLuiz Augusto von Dentz 	return rp->status;
2037b950aa88SAnkit Navik }
2038b950aa88SAnkit Navik 
2039c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_clear_resolv_list(struct hci_dev *hdev, void *data,
2040545f2596SAnkit Navik 				      struct sk_buff *skb)
2041545f2596SAnkit Navik {
2042c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
2043545f2596SAnkit Navik 
2044e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2045e3f3a1aeSLuiz Augusto von Dentz 
2046e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
2047c8992cffSLuiz Augusto von Dentz 		return rp->status;
2048545f2596SAnkit Navik 
20495e2b6064SNiels Dossche 	hci_dev_lock(hdev);
2050545f2596SAnkit Navik 	hci_bdaddr_list_clear(&hdev->le_resolv_list);
20515e2b6064SNiels Dossche 	hci_dev_unlock(hdev);
2052c8992cffSLuiz Augusto von Dentz 
2053c8992cffSLuiz Augusto von Dentz 	return rp->status;
2054545f2596SAnkit Navik }
2055545f2596SAnkit Navik 
2056c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_resolv_list_size(struct hci_dev *hdev, void *data,
2057cfdb0c2dSAnkit Navik 					  struct sk_buff *skb)
2058cfdb0c2dSAnkit Navik {
2059c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_resolv_list_size *rp = data;
2060e3f3a1aeSLuiz Augusto von Dentz 
2061e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x size %u", rp->status, rp->size);
2062cfdb0c2dSAnkit Navik 
2063cfdb0c2dSAnkit Navik 	if (rp->status)
2064c8992cffSLuiz Augusto von Dentz 		return rp->status;
2065cfdb0c2dSAnkit Navik 
2066cfdb0c2dSAnkit Navik 	hdev->le_resolv_list_size = rp->size;
2067c8992cffSLuiz Augusto von Dentz 
2068c8992cffSLuiz Augusto von Dentz 	return rp->status;
2069cfdb0c2dSAnkit Navik }
2070cfdb0c2dSAnkit Navik 
2071c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_addr_resolution_enable(struct hci_dev *hdev, void *data,
2072aa12af77SAnkit Navik 					       struct sk_buff *skb)
2073aa12af77SAnkit Navik {
2074c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
2075e3f3a1aeSLuiz Augusto von Dentz 	__u8 *sent;
2076aa12af77SAnkit Navik 
2077e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2078e3f3a1aeSLuiz Augusto von Dentz 
2079e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
2080c8992cffSLuiz Augusto von Dentz 		return rp->status;
2081aa12af77SAnkit Navik 
2082aa12af77SAnkit Navik 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADDR_RESOLV_ENABLE);
2083aa12af77SAnkit Navik 	if (!sent)
2084c8992cffSLuiz Augusto von Dentz 		return rp->status;
2085aa12af77SAnkit Navik 
2086aa12af77SAnkit Navik 	hci_dev_lock(hdev);
2087aa12af77SAnkit Navik 
2088aa12af77SAnkit Navik 	if (*sent)
2089aa12af77SAnkit Navik 		hci_dev_set_flag(hdev, HCI_LL_RPA_RESOLUTION);
2090aa12af77SAnkit Navik 	else
2091aa12af77SAnkit Navik 		hci_dev_clear_flag(hdev, HCI_LL_RPA_RESOLUTION);
2092aa12af77SAnkit Navik 
2093aa12af77SAnkit Navik 	hci_dev_unlock(hdev);
2094c8992cffSLuiz Augusto von Dentz 
2095c8992cffSLuiz Augusto von Dentz 	return rp->status;
2096aa12af77SAnkit Navik }
2097aa12af77SAnkit Navik 
2098c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_max_data_len(struct hci_dev *hdev, void *data,
2099a8e1bfaaSMarcel Holtmann 				      struct sk_buff *skb)
2100a8e1bfaaSMarcel Holtmann {
2101c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_max_data_len *rp = data;
2102e3f3a1aeSLuiz Augusto von Dentz 
2103e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2104a8e1bfaaSMarcel Holtmann 
2105a8e1bfaaSMarcel Holtmann 	if (rp->status)
2106c8992cffSLuiz Augusto von Dentz 		return rp->status;
2107a8e1bfaaSMarcel Holtmann 
2108a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_len = le16_to_cpu(rp->tx_len);
2109a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_time = le16_to_cpu(rp->tx_time);
2110a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_len = le16_to_cpu(rp->rx_len);
2111a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_time = le16_to_cpu(rp->rx_time);
2112c8992cffSLuiz Augusto von Dentz 
2113c8992cffSLuiz Augusto von Dentz 	return rp->status;
2114a8e1bfaaSMarcel Holtmann }
2115a8e1bfaaSMarcel Holtmann 
2116c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_le_host_supported(struct hci_dev *hdev, void *data,
2117f9b49306SAndre Guedes 					 struct sk_buff *skb)
2118f9b49306SAndre Guedes {
211906199cf8SJohan Hedberg 	struct hci_cp_write_le_host_supported *sent;
2120c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
2121f9b49306SAndre Guedes 
2122e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2123e3f3a1aeSLuiz Augusto von Dentz 
2124e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
2125c8992cffSLuiz Augusto von Dentz 		return rp->status;
212645296acdSMarcel Holtmann 
212706199cf8SJohan Hedberg 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
21288f984dfaSJohan Hedberg 	if (!sent)
2129c8992cffSLuiz Augusto von Dentz 		return rp->status;
2130f9b49306SAndre Guedes 
21315c1a4c8fSJaganath Kanakkassery 	hci_dev_lock(hdev);
21325c1a4c8fSJaganath Kanakkassery 
2133416a4ae5SJohan Hedberg 	if (sent->le) {
2134cad718edSJohan Hedberg 		hdev->features[1][0] |= LMP_HOST_LE;
2135a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_LE_ENABLED);
2136416a4ae5SJohan Hedberg 	} else {
2137cad718edSJohan Hedberg 		hdev->features[1][0] &= ~LMP_HOST_LE;
2138a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LE_ENABLED);
2139a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_ADVERTISING);
2140416a4ae5SJohan Hedberg 	}
214153b2caabSJohan Hedberg 
214253b2caabSJohan Hedberg 	if (sent->simul)
2143cad718edSJohan Hedberg 		hdev->features[1][0] |= LMP_HOST_LE_BREDR;
214453b2caabSJohan Hedberg 	else
2145cad718edSJohan Hedberg 		hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
21465c1a4c8fSJaganath Kanakkassery 
21475c1a4c8fSJaganath Kanakkassery 	hci_dev_unlock(hdev);
2148c8992cffSLuiz Augusto von Dentz 
2149c8992cffSLuiz Augusto von Dentz 	return rp->status;
21508f984dfaSJohan Hedberg }
2151f9b49306SAndre Guedes 
2152c8992cffSLuiz Augusto von Dentz static u8 hci_cc_set_adv_param(struct hci_dev *hdev, void *data,
2153c8992cffSLuiz Augusto von Dentz 			       struct sk_buff *skb)
215456ed2cb8SJohan Hedberg {
215556ed2cb8SJohan Hedberg 	struct hci_cp_le_set_adv_param *cp;
2156c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
215756ed2cb8SJohan Hedberg 
2158e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2159e3f3a1aeSLuiz Augusto von Dentz 
2160e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
2161c8992cffSLuiz Augusto von Dentz 		return rp->status;
216256ed2cb8SJohan Hedberg 
216356ed2cb8SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_PARAM);
216456ed2cb8SJohan Hedberg 	if (!cp)
2165c8992cffSLuiz Augusto von Dentz 		return rp->status;
216656ed2cb8SJohan Hedberg 
216756ed2cb8SJohan Hedberg 	hci_dev_lock(hdev);
216856ed2cb8SJohan Hedberg 	hdev->adv_addr_type = cp->own_address_type;
216956ed2cb8SJohan Hedberg 	hci_dev_unlock(hdev);
2170c8992cffSLuiz Augusto von Dentz 
2171c8992cffSLuiz Augusto von Dentz 	return rp->status;
217256ed2cb8SJohan Hedberg }
217356ed2cb8SJohan Hedberg 
2174c8992cffSLuiz Augusto von Dentz static u8 hci_cc_set_ext_adv_param(struct hci_dev *hdev, void *data,
2175c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
2176de181e88SJaganath Kanakkassery {
2177c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_set_ext_adv_params *rp = data;
2178de181e88SJaganath Kanakkassery 	struct hci_cp_le_set_ext_adv_params *cp;
2179de181e88SJaganath Kanakkassery 	struct adv_info *adv_instance;
2180de181e88SJaganath Kanakkassery 
2181e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2182de181e88SJaganath Kanakkassery 
2183de181e88SJaganath Kanakkassery 	if (rp->status)
2184c8992cffSLuiz Augusto von Dentz 		return rp->status;
2185de181e88SJaganath Kanakkassery 
2186de181e88SJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_ADV_PARAMS);
2187de181e88SJaganath Kanakkassery 	if (!cp)
2188c8992cffSLuiz Augusto von Dentz 		return rp->status;
2189de181e88SJaganath Kanakkassery 
2190de181e88SJaganath Kanakkassery 	hci_dev_lock(hdev);
2191de181e88SJaganath Kanakkassery 	hdev->adv_addr_type = cp->own_addr_type;
219225e70886SDaniel Winkler 	if (!cp->handle) {
2193de181e88SJaganath Kanakkassery 		/* Store in hdev for instance 0 */
2194de181e88SJaganath Kanakkassery 		hdev->adv_tx_power = rp->tx_power;
2195de181e88SJaganath Kanakkassery 	} else {
219625e70886SDaniel Winkler 		adv_instance = hci_find_adv_instance(hdev, cp->handle);
2197de181e88SJaganath Kanakkassery 		if (adv_instance)
2198de181e88SJaganath Kanakkassery 			adv_instance->tx_power = rp->tx_power;
2199de181e88SJaganath Kanakkassery 	}
2200a0fb3726SJaganath Kanakkassery 	/* Update adv data as tx power is known now */
2201651cd3d6SBrian Gix 	hci_update_adv_data(hdev, cp->handle);
220212410572SDaniel Winkler 
2203de181e88SJaganath Kanakkassery 	hci_dev_unlock(hdev);
2204c8992cffSLuiz Augusto von Dentz 
2205c8992cffSLuiz Augusto von Dentz 	return rp->status;
2206de181e88SJaganath Kanakkassery }
2207de181e88SJaganath Kanakkassery 
2208c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_rssi(struct hci_dev *hdev, void *data,
2209c8992cffSLuiz Augusto von Dentz 			   struct sk_buff *skb)
22105ae76a94SAndrzej Kaczmarek {
2211c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_rssi *rp = data;
22125ae76a94SAndrzej Kaczmarek 	struct hci_conn *conn;
22135ae76a94SAndrzej Kaczmarek 
2214e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
22155ae76a94SAndrzej Kaczmarek 
22165ae76a94SAndrzej Kaczmarek 	if (rp->status)
2217c8992cffSLuiz Augusto von Dentz 		return rp->status;
22185ae76a94SAndrzej Kaczmarek 
22195ae76a94SAndrzej Kaczmarek 	hci_dev_lock(hdev);
22205ae76a94SAndrzej Kaczmarek 
22215ae76a94SAndrzej Kaczmarek 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
22225ae76a94SAndrzej Kaczmarek 	if (conn)
22235ae76a94SAndrzej Kaczmarek 		conn->rssi = rp->rssi;
22245ae76a94SAndrzej Kaczmarek 
22255ae76a94SAndrzej Kaczmarek 	hci_dev_unlock(hdev);
2226c8992cffSLuiz Augusto von Dentz 
2227c8992cffSLuiz Augusto von Dentz 	return rp->status;
22285ae76a94SAndrzej Kaczmarek }
22295ae76a94SAndrzej Kaczmarek 
2230c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_tx_power(struct hci_dev *hdev, void *data,
2231c8992cffSLuiz Augusto von Dentz 			       struct sk_buff *skb)
22325a134faeSAndrzej Kaczmarek {
22335a134faeSAndrzej Kaczmarek 	struct hci_cp_read_tx_power *sent;
2234c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_tx_power *rp = data;
22355a134faeSAndrzej Kaczmarek 	struct hci_conn *conn;
22365a134faeSAndrzej Kaczmarek 
2237e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
22385a134faeSAndrzej Kaczmarek 
22395a134faeSAndrzej Kaczmarek 	if (rp->status)
2240c8992cffSLuiz Augusto von Dentz 		return rp->status;
22415a134faeSAndrzej Kaczmarek 
22425a134faeSAndrzej Kaczmarek 	sent = hci_sent_cmd_data(hdev, HCI_OP_READ_TX_POWER);
22435a134faeSAndrzej Kaczmarek 	if (!sent)
2244c8992cffSLuiz Augusto von Dentz 		return rp->status;
22455a134faeSAndrzej Kaczmarek 
22465a134faeSAndrzej Kaczmarek 	hci_dev_lock(hdev);
22475a134faeSAndrzej Kaczmarek 
22485a134faeSAndrzej Kaczmarek 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
2249d0455ed9SAndrzej Kaczmarek 	if (!conn)
2250d0455ed9SAndrzej Kaczmarek 		goto unlock;
22515a134faeSAndrzej Kaczmarek 
2252d0455ed9SAndrzej Kaczmarek 	switch (sent->type) {
2253d0455ed9SAndrzej Kaczmarek 	case 0x00:
2254d0455ed9SAndrzej Kaczmarek 		conn->tx_power = rp->tx_power;
2255d0455ed9SAndrzej Kaczmarek 		break;
2256d0455ed9SAndrzej Kaczmarek 	case 0x01:
2257d0455ed9SAndrzej Kaczmarek 		conn->max_tx_power = rp->tx_power;
2258d0455ed9SAndrzej Kaczmarek 		break;
2259d0455ed9SAndrzej Kaczmarek 	}
2260d0455ed9SAndrzej Kaczmarek 
2261d0455ed9SAndrzej Kaczmarek unlock:
22625a134faeSAndrzej Kaczmarek 	hci_dev_unlock(hdev);
2263c8992cffSLuiz Augusto von Dentz 	return rp->status;
22645a134faeSAndrzej Kaczmarek }
22655a134faeSAndrzej Kaczmarek 
2266c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_ssp_debug_mode(struct hci_dev *hdev, void *data,
2267c8992cffSLuiz Augusto von Dentz 				      struct sk_buff *skb)
2268c50b33c8SMarcel Holtmann {
2269c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
2270c50b33c8SMarcel Holtmann 	u8 *mode;
2271c50b33c8SMarcel Holtmann 
2272e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2273e3f3a1aeSLuiz Augusto von Dentz 
2274e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
2275c8992cffSLuiz Augusto von Dentz 		return rp->status;
2276c50b33c8SMarcel Holtmann 
2277c50b33c8SMarcel Holtmann 	mode = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE);
2278c50b33c8SMarcel Holtmann 	if (mode)
2279c50b33c8SMarcel Holtmann 		hdev->ssp_debug_mode = *mode;
2280c8992cffSLuiz Augusto von Dentz 
2281c8992cffSLuiz Augusto von Dentz 	return rp->status;
2282c50b33c8SMarcel Holtmann }
2283c50b33c8SMarcel Holtmann 
22846039aa73SGustavo Padovan static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
2285a9de9248SMarcel Holtmann {
2286147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2287a9de9248SMarcel Holtmann 
2288a9de9248SMarcel Holtmann 	if (status) {
2289a9de9248SMarcel Holtmann 		hci_conn_check_pending(hdev);
2290314b2381SJohan Hedberg 		return;
2291314b2381SJohan Hedberg 	}
2292314b2381SJohan Hedberg 
229389352e7dSAndre Guedes 	set_bit(HCI_INQUIRY, &hdev->flags);
2294a9de9248SMarcel Holtmann }
2295a9de9248SMarcel Holtmann 
22966039aa73SGustavo Padovan static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
22971da177e4SLinus Torvalds {
2298a9de9248SMarcel Holtmann 	struct hci_cp_create_conn *cp;
22991da177e4SLinus Torvalds 	struct hci_conn *conn;
23001da177e4SLinus Torvalds 
2301147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2302a9de9248SMarcel Holtmann 
2303a9de9248SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
23041da177e4SLinus Torvalds 	if (!cp)
23051da177e4SLinus Torvalds 		return;
23061da177e4SLinus Torvalds 
23071da177e4SLinus Torvalds 	hci_dev_lock(hdev);
23081da177e4SLinus Torvalds 
23091da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
23101da177e4SLinus Torvalds 
2311147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "bdaddr %pMR hcon %p", &cp->bdaddr, conn);
23121da177e4SLinus Torvalds 
23131da177e4SLinus Torvalds 	if (status) {
23141da177e4SLinus Torvalds 		if (conn && conn->state == BT_CONNECT) {
23154c67bc74SMarcel Holtmann 			if (status != 0x0c || conn->attempt > 2) {
23161da177e4SLinus Torvalds 				conn->state = BT_CLOSED;
2317539c496dSJohan Hedberg 				hci_connect_cfm(conn, status);
23181da177e4SLinus Torvalds 				hci_conn_del(conn);
23194c67bc74SMarcel Holtmann 			} else
23204c67bc74SMarcel Holtmann 				conn->state = BT_CONNECT2;
23211da177e4SLinus Torvalds 		}
23221da177e4SLinus Torvalds 	} else {
23231da177e4SLinus Torvalds 		if (!conn) {
2324a5c4e309SJohan Hedberg 			conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr,
2325a5c4e309SJohan Hedberg 					    HCI_ROLE_MASTER);
2326a5c4e309SJohan Hedberg 			if (!conn)
23272064ee33SMarcel Holtmann 				bt_dev_err(hdev, "no memory for new connection");
23281da177e4SLinus Torvalds 		}
23291da177e4SLinus Torvalds 	}
23301da177e4SLinus Torvalds 
23311da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
23321da177e4SLinus Torvalds }
23331da177e4SLinus Torvalds 
2334a9de9248SMarcel Holtmann static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
23351da177e4SLinus Torvalds {
2336a9de9248SMarcel Holtmann 	struct hci_cp_add_sco *cp;
23371da177e4SLinus Torvalds 	struct hci_conn *acl, *sco;
23381da177e4SLinus Torvalds 	__u16 handle;
23391da177e4SLinus Torvalds 
2340147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2341b6a0dc82SMarcel Holtmann 
2342a9de9248SMarcel Holtmann 	if (!status)
2343a9de9248SMarcel Holtmann 		return;
2344a9de9248SMarcel Holtmann 
2345a9de9248SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
23461da177e4SLinus Torvalds 	if (!cp)
2347a9de9248SMarcel Holtmann 		return;
23481da177e4SLinus Torvalds 
23491da177e4SLinus Torvalds 	handle = __le16_to_cpu(cp->handle);
23501da177e4SLinus Torvalds 
2351147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "handle 0x%4.4x", handle);
23521da177e4SLinus Torvalds 
23531da177e4SLinus Torvalds 	hci_dev_lock(hdev);
23541da177e4SLinus Torvalds 
23551da177e4SLinus Torvalds 	acl = hci_conn_hash_lookup_handle(hdev, handle);
23565a08ecceSAndrei Emeltchenko 	if (acl) {
23575a08ecceSAndrei Emeltchenko 		sco = acl->link;
23585a08ecceSAndrei Emeltchenko 		if (sco) {
23591da177e4SLinus Torvalds 			sco->state = BT_CLOSED;
23601da177e4SLinus Torvalds 
2361539c496dSJohan Hedberg 			hci_connect_cfm(sco, status);
23621da177e4SLinus Torvalds 			hci_conn_del(sco);
23631da177e4SLinus Torvalds 		}
23645a08ecceSAndrei Emeltchenko 	}
23651da177e4SLinus Torvalds 
23661da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
23671da177e4SLinus Torvalds }
23681da177e4SLinus Torvalds 
2369f8558555SMarcel Holtmann static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
2370f8558555SMarcel Holtmann {
2371f8558555SMarcel Holtmann 	struct hci_cp_auth_requested *cp;
2372f8558555SMarcel Holtmann 	struct hci_conn *conn;
2373f8558555SMarcel Holtmann 
2374147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2375f8558555SMarcel Holtmann 
2376f8558555SMarcel Holtmann 	if (!status)
2377f8558555SMarcel Holtmann 		return;
2378f8558555SMarcel Holtmann 
2379f8558555SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
2380f8558555SMarcel Holtmann 	if (!cp)
2381f8558555SMarcel Holtmann 		return;
2382f8558555SMarcel Holtmann 
2383f8558555SMarcel Holtmann 	hci_dev_lock(hdev);
2384f8558555SMarcel Holtmann 
2385f8558555SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2386f8558555SMarcel Holtmann 	if (conn) {
2387f8558555SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
2388539c496dSJohan Hedberg 			hci_connect_cfm(conn, status);
238976a68ba0SDavid Herrmann 			hci_conn_drop(conn);
2390f8558555SMarcel Holtmann 		}
2391f8558555SMarcel Holtmann 	}
2392f8558555SMarcel Holtmann 
2393f8558555SMarcel Holtmann 	hci_dev_unlock(hdev);
2394f8558555SMarcel Holtmann }
2395f8558555SMarcel Holtmann 
2396f8558555SMarcel Holtmann static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
2397f8558555SMarcel Holtmann {
2398f8558555SMarcel Holtmann 	struct hci_cp_set_conn_encrypt *cp;
2399f8558555SMarcel Holtmann 	struct hci_conn *conn;
2400f8558555SMarcel Holtmann 
2401147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2402f8558555SMarcel Holtmann 
2403f8558555SMarcel Holtmann 	if (!status)
2404f8558555SMarcel Holtmann 		return;
2405f8558555SMarcel Holtmann 
2406f8558555SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
2407f8558555SMarcel Holtmann 	if (!cp)
2408f8558555SMarcel Holtmann 		return;
2409f8558555SMarcel Holtmann 
2410f8558555SMarcel Holtmann 	hci_dev_lock(hdev);
2411f8558555SMarcel Holtmann 
2412f8558555SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2413f8558555SMarcel Holtmann 	if (conn) {
2414f8558555SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
2415539c496dSJohan Hedberg 			hci_connect_cfm(conn, status);
241676a68ba0SDavid Herrmann 			hci_conn_drop(conn);
2417f8558555SMarcel Holtmann 		}
2418f8558555SMarcel Holtmann 	}
2419f8558555SMarcel Holtmann 
2420f8558555SMarcel Holtmann 	hci_dev_unlock(hdev);
2421f8558555SMarcel Holtmann }
2422f8558555SMarcel Holtmann 
2423127178d2SJohan Hedberg static int hci_outgoing_auth_needed(struct hci_dev *hdev,
2424392599b9SJohan Hedberg 				    struct hci_conn *conn)
2425392599b9SJohan Hedberg {
2426392599b9SJohan Hedberg 	if (conn->state != BT_CONFIG || !conn->out)
2427392599b9SJohan Hedberg 		return 0;
2428392599b9SJohan Hedberg 
2429765c2a96SJohan Hedberg 	if (conn->pending_sec_level == BT_SECURITY_SDP)
2430392599b9SJohan Hedberg 		return 0;
2431392599b9SJohan Hedberg 
2432392599b9SJohan Hedberg 	/* Only request authentication for SSP connections or non-SSP
2433264b8b4eSJohan Hedberg 	 * devices with sec_level MEDIUM or HIGH or if MITM protection
2434264b8b4eSJohan Hedberg 	 * is requested.
2435264b8b4eSJohan Hedberg 	 */
2436807deac2SGustavo Padovan 	if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
24377e3691e1SJohan Hedberg 	    conn->pending_sec_level != BT_SECURITY_FIPS &&
2438264b8b4eSJohan Hedberg 	    conn->pending_sec_level != BT_SECURITY_HIGH &&
2439264b8b4eSJohan Hedberg 	    conn->pending_sec_level != BT_SECURITY_MEDIUM)
2440392599b9SJohan Hedberg 		return 0;
2441392599b9SJohan Hedberg 
2442392599b9SJohan Hedberg 	return 1;
2443392599b9SJohan Hedberg }
2444392599b9SJohan Hedberg 
24456039aa73SGustavo Padovan static int hci_resolve_name(struct hci_dev *hdev,
244600abfe44SGustavo F. Padovan 				   struct inquiry_entry *e)
244730dc78e1SJohan Hedberg {
244830dc78e1SJohan Hedberg 	struct hci_cp_remote_name_req cp;
244930dc78e1SJohan Hedberg 
245030dc78e1SJohan Hedberg 	memset(&cp, 0, sizeof(cp));
245130dc78e1SJohan Hedberg 
245230dc78e1SJohan Hedberg 	bacpy(&cp.bdaddr, &e->data.bdaddr);
245330dc78e1SJohan Hedberg 	cp.pscan_rep_mode = e->data.pscan_rep_mode;
245430dc78e1SJohan Hedberg 	cp.pscan_mode = e->data.pscan_mode;
245530dc78e1SJohan Hedberg 	cp.clock_offset = e->data.clock_offset;
245630dc78e1SJohan Hedberg 
245730dc78e1SJohan Hedberg 	return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
245830dc78e1SJohan Hedberg }
245930dc78e1SJohan Hedberg 
2460b644ba33SJohan Hedberg static bool hci_resolve_next_name(struct hci_dev *hdev)
246130dc78e1SJohan Hedberg {
246230dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
246330dc78e1SJohan Hedberg 	struct inquiry_entry *e;
246430dc78e1SJohan Hedberg 
2465b644ba33SJohan Hedberg 	if (list_empty(&discov->resolve))
2466b644ba33SJohan Hedberg 		return false;
2467b644ba33SJohan Hedberg 
2468dbf6811aSArchie Pusaka 	/* We should stop if we already spent too much time resolving names. */
2469dbf6811aSArchie Pusaka 	if (time_after(jiffies, discov->name_resolve_timeout)) {
2470dbf6811aSArchie Pusaka 		bt_dev_warn_ratelimited(hdev, "Name resolve takes too long.");
2471dbf6811aSArchie Pusaka 		return false;
2472dbf6811aSArchie Pusaka 	}
2473dbf6811aSArchie Pusaka 
2474b644ba33SJohan Hedberg 	e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
2475c810089cSRam Malovany 	if (!e)
2476c810089cSRam Malovany 		return false;
2477c810089cSRam Malovany 
2478b644ba33SJohan Hedberg 	if (hci_resolve_name(hdev, e) == 0) {
2479b644ba33SJohan Hedberg 		e->name_state = NAME_PENDING;
2480b644ba33SJohan Hedberg 		return true;
2481b644ba33SJohan Hedberg 	}
2482b644ba33SJohan Hedberg 
2483b644ba33SJohan Hedberg 	return false;
2484b644ba33SJohan Hedberg }
2485b644ba33SJohan Hedberg 
2486b644ba33SJohan Hedberg static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
2487b644ba33SJohan Hedberg 				   bdaddr_t *bdaddr, u8 *name, u8 name_len)
2488b644ba33SJohan Hedberg {
2489b644ba33SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
2490b644ba33SJohan Hedberg 	struct inquiry_entry *e;
2491b644ba33SJohan Hedberg 
249260cb49d2SJohan Hedberg 	/* Update the mgmt connected state if necessary. Be careful with
249360cb49d2SJohan Hedberg 	 * conn objects that exist but are not (yet) connected however.
249460cb49d2SJohan Hedberg 	 * Only those in BT_CONFIG or BT_CONNECTED states can be
249560cb49d2SJohan Hedberg 	 * considered connected.
249660cb49d2SJohan Hedberg 	 */
249760cb49d2SJohan Hedberg 	if (conn &&
249860cb49d2SJohan Hedberg 	    (conn->state == BT_CONFIG || conn->state == BT_CONNECTED) &&
2499cb77c3ecSJaganath Kanakkassery 	    !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
25001c6ed31bSYu Liu 		mgmt_device_connected(hdev, conn, name, name_len);
2501b644ba33SJohan Hedberg 
2502b644ba33SJohan Hedberg 	if (discov->state == DISCOVERY_STOPPED)
2503b644ba33SJohan Hedberg 		return;
2504b644ba33SJohan Hedberg 
250530dc78e1SJohan Hedberg 	if (discov->state == DISCOVERY_STOPPING)
250630dc78e1SJohan Hedberg 		goto discov_complete;
250730dc78e1SJohan Hedberg 
250830dc78e1SJohan Hedberg 	if (discov->state != DISCOVERY_RESOLVING)
250930dc78e1SJohan Hedberg 		return;
251030dc78e1SJohan Hedberg 
251130dc78e1SJohan Hedberg 	e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
25127cc8380eSRam Malovany 	/* If the device was not found in a list of found devices names of which
25137cc8380eSRam Malovany 	 * are pending. there is no need to continue resolving a next name as it
25147cc8380eSRam Malovany 	 * will be done upon receiving another Remote Name Request Complete
25157cc8380eSRam Malovany 	 * Event */
25167cc8380eSRam Malovany 	if (!e)
25177cc8380eSRam Malovany 		return;
25187cc8380eSRam Malovany 
251930dc78e1SJohan Hedberg 	list_del(&e->list);
2520ea13aed5SArchie Pusaka 
2521ea13aed5SArchie Pusaka 	e->name_state = name ? NAME_KNOWN : NAME_NOT_KNOWN;
2522ea13aed5SArchie Pusaka 	mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00, e->data.rssi,
2523ea13aed5SArchie Pusaka 			 name, name_len);
252430dc78e1SJohan Hedberg 
2525b644ba33SJohan Hedberg 	if (hci_resolve_next_name(hdev))
252630dc78e1SJohan Hedberg 		return;
252730dc78e1SJohan Hedberg 
252830dc78e1SJohan Hedberg discov_complete:
252930dc78e1SJohan Hedberg 	hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
253030dc78e1SJohan Hedberg }
253130dc78e1SJohan Hedberg 
2532a9de9248SMarcel Holtmann static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
25331da177e4SLinus Torvalds {
2534127178d2SJohan Hedberg 	struct hci_cp_remote_name_req *cp;
2535127178d2SJohan Hedberg 	struct hci_conn *conn;
2536127178d2SJohan Hedberg 
2537147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2538127178d2SJohan Hedberg 
2539127178d2SJohan Hedberg 	/* If successful wait for the name req complete event before
2540127178d2SJohan Hedberg 	 * checking for the need to do authentication */
2541127178d2SJohan Hedberg 	if (!status)
2542127178d2SJohan Hedberg 		return;
2543127178d2SJohan Hedberg 
2544127178d2SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
2545127178d2SJohan Hedberg 	if (!cp)
2546127178d2SJohan Hedberg 		return;
2547127178d2SJohan Hedberg 
2548127178d2SJohan Hedberg 	hci_dev_lock(hdev);
2549127178d2SJohan Hedberg 
2550127178d2SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
2551b644ba33SJohan Hedberg 
2552d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
2553b644ba33SJohan Hedberg 		hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
2554b644ba33SJohan Hedberg 
255579c6c70cSJohan Hedberg 	if (!conn)
255679c6c70cSJohan Hedberg 		goto unlock;
255779c6c70cSJohan Hedberg 
255879c6c70cSJohan Hedberg 	if (!hci_outgoing_auth_needed(hdev, conn))
255979c6c70cSJohan Hedberg 		goto unlock;
256079c6c70cSJohan Hedberg 
256151a8efd7SJohan Hedberg 	if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
2562c1f23a2bSJohannes Berg 		struct hci_cp_auth_requested auth_cp;
2563c1f23a2bSJohannes Berg 
2564977f8fceSJohan Hedberg 		set_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags);
2565977f8fceSJohan Hedberg 
2566c1f23a2bSJohannes Berg 		auth_cp.handle = __cpu_to_le16(conn->handle);
2567c1f23a2bSJohannes Berg 		hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
2568c1f23a2bSJohannes Berg 			     sizeof(auth_cp), &auth_cp);
2569127178d2SJohan Hedberg 	}
2570127178d2SJohan Hedberg 
257179c6c70cSJohan Hedberg unlock:
2572127178d2SJohan Hedberg 	hci_dev_unlock(hdev);
2573a9de9248SMarcel Holtmann }
25741da177e4SLinus Torvalds 
2575769be974SMarcel Holtmann static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
2576769be974SMarcel Holtmann {
2577769be974SMarcel Holtmann 	struct hci_cp_read_remote_features *cp;
2578769be974SMarcel Holtmann 	struct hci_conn *conn;
2579769be974SMarcel Holtmann 
2580147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2581769be974SMarcel Holtmann 
2582769be974SMarcel Holtmann 	if (!status)
2583769be974SMarcel Holtmann 		return;
2584769be974SMarcel Holtmann 
2585769be974SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
2586769be974SMarcel Holtmann 	if (!cp)
2587769be974SMarcel Holtmann 		return;
2588769be974SMarcel Holtmann 
2589769be974SMarcel Holtmann 	hci_dev_lock(hdev);
2590769be974SMarcel Holtmann 
2591769be974SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2592769be974SMarcel Holtmann 	if (conn) {
2593769be974SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
2594539c496dSJohan Hedberg 			hci_connect_cfm(conn, status);
259576a68ba0SDavid Herrmann 			hci_conn_drop(conn);
2596769be974SMarcel Holtmann 		}
2597769be974SMarcel Holtmann 	}
2598769be974SMarcel Holtmann 
2599769be974SMarcel Holtmann 	hci_dev_unlock(hdev);
2600769be974SMarcel Holtmann }
2601769be974SMarcel Holtmann 
2602769be974SMarcel Holtmann static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
2603769be974SMarcel Holtmann {
2604769be974SMarcel Holtmann 	struct hci_cp_read_remote_ext_features *cp;
2605769be974SMarcel Holtmann 	struct hci_conn *conn;
2606769be974SMarcel Holtmann 
2607147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2608769be974SMarcel Holtmann 
2609769be974SMarcel Holtmann 	if (!status)
2610769be974SMarcel Holtmann 		return;
2611769be974SMarcel Holtmann 
2612769be974SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
2613769be974SMarcel Holtmann 	if (!cp)
2614769be974SMarcel Holtmann 		return;
2615769be974SMarcel Holtmann 
2616769be974SMarcel Holtmann 	hci_dev_lock(hdev);
2617769be974SMarcel Holtmann 
2618769be974SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2619769be974SMarcel Holtmann 	if (conn) {
2620769be974SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
2621539c496dSJohan Hedberg 			hci_connect_cfm(conn, status);
262276a68ba0SDavid Herrmann 			hci_conn_drop(conn);
2623769be974SMarcel Holtmann 		}
2624769be974SMarcel Holtmann 	}
2625769be974SMarcel Holtmann 
2626769be974SMarcel Holtmann 	hci_dev_unlock(hdev);
2627769be974SMarcel Holtmann }
2628769be974SMarcel Holtmann 
2629a9de9248SMarcel Holtmann static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
2630a9de9248SMarcel Holtmann {
2631b6a0dc82SMarcel Holtmann 	struct hci_cp_setup_sync_conn *cp;
2632b6a0dc82SMarcel Holtmann 	struct hci_conn *acl, *sco;
2633b6a0dc82SMarcel Holtmann 	__u16 handle;
2634b6a0dc82SMarcel Holtmann 
2635147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2636b6a0dc82SMarcel Holtmann 
2637b6a0dc82SMarcel Holtmann 	if (!status)
2638b6a0dc82SMarcel Holtmann 		return;
2639b6a0dc82SMarcel Holtmann 
2640b6a0dc82SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
2641b6a0dc82SMarcel Holtmann 	if (!cp)
2642b6a0dc82SMarcel Holtmann 		return;
2643b6a0dc82SMarcel Holtmann 
2644b6a0dc82SMarcel Holtmann 	handle = __le16_to_cpu(cp->handle);
2645b6a0dc82SMarcel Holtmann 
2646147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "handle 0x%4.4x", handle);
2647b6a0dc82SMarcel Holtmann 
2648b6a0dc82SMarcel Holtmann 	hci_dev_lock(hdev);
2649b6a0dc82SMarcel Holtmann 
2650b6a0dc82SMarcel Holtmann 	acl = hci_conn_hash_lookup_handle(hdev, handle);
26515a08ecceSAndrei Emeltchenko 	if (acl) {
26525a08ecceSAndrei Emeltchenko 		sco = acl->link;
26535a08ecceSAndrei Emeltchenko 		if (sco) {
2654b6a0dc82SMarcel Holtmann 			sco->state = BT_CLOSED;
2655b6a0dc82SMarcel Holtmann 
2656539c496dSJohan Hedberg 			hci_connect_cfm(sco, status);
2657b6a0dc82SMarcel Holtmann 			hci_conn_del(sco);
2658b6a0dc82SMarcel Holtmann 		}
26595a08ecceSAndrei Emeltchenko 	}
2660b6a0dc82SMarcel Holtmann 
2661b6a0dc82SMarcel Holtmann 	hci_dev_unlock(hdev);
2662a9de9248SMarcel Holtmann }
2663a9de9248SMarcel Holtmann 
2664b2af264aSKiran K static void hci_cs_enhanced_setup_sync_conn(struct hci_dev *hdev, __u8 status)
2665b2af264aSKiran K {
2666b2af264aSKiran K 	struct hci_cp_enhanced_setup_sync_conn *cp;
2667b2af264aSKiran K 	struct hci_conn *acl, *sco;
2668b2af264aSKiran K 	__u16 handle;
2669b2af264aSKiran K 
2670b2af264aSKiran K 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2671b2af264aSKiran K 
2672b2af264aSKiran K 	if (!status)
2673b2af264aSKiran K 		return;
2674b2af264aSKiran K 
2675b2af264aSKiran K 	cp = hci_sent_cmd_data(hdev, HCI_OP_ENHANCED_SETUP_SYNC_CONN);
2676b2af264aSKiran K 	if (!cp)
2677b2af264aSKiran K 		return;
2678b2af264aSKiran K 
2679b2af264aSKiran K 	handle = __le16_to_cpu(cp->handle);
2680b2af264aSKiran K 
2681b2af264aSKiran K 	bt_dev_dbg(hdev, "handle 0x%4.4x", handle);
2682b2af264aSKiran K 
2683b2af264aSKiran K 	hci_dev_lock(hdev);
2684b2af264aSKiran K 
2685b2af264aSKiran K 	acl = hci_conn_hash_lookup_handle(hdev, handle);
2686b2af264aSKiran K 	if (acl) {
2687b2af264aSKiran K 		sco = acl->link;
2688b2af264aSKiran K 		if (sco) {
2689b2af264aSKiran K 			sco->state = BT_CLOSED;
2690b2af264aSKiran K 
2691b2af264aSKiran K 			hci_connect_cfm(sco, status);
2692b2af264aSKiran K 			hci_conn_del(sco);
2693b2af264aSKiran K 		}
2694b2af264aSKiran K 	}
2695b2af264aSKiran K 
2696b2af264aSKiran K 	hci_dev_unlock(hdev);
2697b2af264aSKiran K }
2698b2af264aSKiran K 
2699a9de9248SMarcel Holtmann static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
2700a9de9248SMarcel Holtmann {
2701a9de9248SMarcel Holtmann 	struct hci_cp_sniff_mode *cp;
270204837f64SMarcel Holtmann 	struct hci_conn *conn;
270304837f64SMarcel Holtmann 
2704147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2705a9de9248SMarcel Holtmann 
2706a9de9248SMarcel Holtmann 	if (!status)
2707a9de9248SMarcel Holtmann 		return;
2708a9de9248SMarcel Holtmann 
2709a9de9248SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
271004837f64SMarcel Holtmann 	if (!cp)
2711a9de9248SMarcel Holtmann 		return;
271204837f64SMarcel Holtmann 
271304837f64SMarcel Holtmann 	hci_dev_lock(hdev);
271404837f64SMarcel Holtmann 
271504837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2716e73439d8SMarcel Holtmann 	if (conn) {
271751a8efd7SJohan Hedberg 		clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
271804837f64SMarcel Holtmann 
271951a8efd7SJohan Hedberg 		if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
2720e73439d8SMarcel Holtmann 			hci_sco_setup(conn, status);
2721e73439d8SMarcel Holtmann 	}
2722e73439d8SMarcel Holtmann 
272304837f64SMarcel Holtmann 	hci_dev_unlock(hdev);
272404837f64SMarcel Holtmann }
272504837f64SMarcel Holtmann 
2726a9de9248SMarcel Holtmann static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
2727a9de9248SMarcel Holtmann {
2728a9de9248SMarcel Holtmann 	struct hci_cp_exit_sniff_mode *cp;
272904837f64SMarcel Holtmann 	struct hci_conn *conn;
273004837f64SMarcel Holtmann 
2731147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2732a9de9248SMarcel Holtmann 
2733a9de9248SMarcel Holtmann 	if (!status)
2734a9de9248SMarcel Holtmann 		return;
2735a9de9248SMarcel Holtmann 
2736a9de9248SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
273704837f64SMarcel Holtmann 	if (!cp)
2738a9de9248SMarcel Holtmann 		return;
273904837f64SMarcel Holtmann 
274004837f64SMarcel Holtmann 	hci_dev_lock(hdev);
274104837f64SMarcel Holtmann 
274204837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2743e73439d8SMarcel Holtmann 	if (conn) {
274451a8efd7SJohan Hedberg 		clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
274504837f64SMarcel Holtmann 
274651a8efd7SJohan Hedberg 		if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
2747e73439d8SMarcel Holtmann 			hci_sco_setup(conn, status);
2748e73439d8SMarcel Holtmann 	}
2749e73439d8SMarcel Holtmann 
275004837f64SMarcel Holtmann 	hci_dev_unlock(hdev);
275104837f64SMarcel Holtmann }
275204837f64SMarcel Holtmann 
275388c3df13SJohan Hedberg static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
275488c3df13SJohan Hedberg {
275588c3df13SJohan Hedberg 	struct hci_cp_disconnect *cp;
2756182ee45dSLuiz Augusto von Dentz 	struct hci_conn_params *params;
275788c3df13SJohan Hedberg 	struct hci_conn *conn;
2758182ee45dSLuiz Augusto von Dentz 	bool mgmt_conn;
275988c3df13SJohan Hedberg 
2760147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2761147306ccSLuiz Augusto von Dentz 
2762182ee45dSLuiz Augusto von Dentz 	/* Wait for HCI_EV_DISCONN_COMPLETE if status 0x00 and not suspended
2763182ee45dSLuiz Augusto von Dentz 	 * otherwise cleanup the connection immediately.
2764182ee45dSLuiz Augusto von Dentz 	 */
2765182ee45dSLuiz Augusto von Dentz 	if (!status && !hdev->suspended)
276688c3df13SJohan Hedberg 		return;
276788c3df13SJohan Hedberg 
276888c3df13SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
276988c3df13SJohan Hedberg 	if (!cp)
277088c3df13SJohan Hedberg 		return;
277188c3df13SJohan Hedberg 
277288c3df13SJohan Hedberg 	hci_dev_lock(hdev);
277388c3df13SJohan Hedberg 
277488c3df13SJohan Hedberg 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2775182ee45dSLuiz Augusto von Dentz 	if (!conn)
2776182ee45dSLuiz Augusto von Dentz 		goto unlock;
2777182ee45dSLuiz Augusto von Dentz 
2778182ee45dSLuiz Augusto von Dentz 	if (status) {
277988c3df13SJohan Hedberg 		mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
278088c3df13SJohan Hedberg 				       conn->dst_type, status);
278188c3df13SJohan Hedberg 
27821eeaa1aeSLuiz Augusto von Dentz 		if (conn->type == LE_LINK && conn->role == HCI_ROLE_SLAVE) {
27837087c4f6SLuiz Augusto von Dentz 			hdev->cur_adv_instance = conn->adv_instance;
2784abfeea47SLuiz Augusto von Dentz 			hci_enable_advertising(hdev);
27857087c4f6SLuiz Augusto von Dentz 		}
27867087c4f6SLuiz Augusto von Dentz 
2787182ee45dSLuiz Augusto von Dentz 		goto done;
2788182ee45dSLuiz Augusto von Dentz 	}
2789182ee45dSLuiz Augusto von Dentz 
2790182ee45dSLuiz Augusto von Dentz 	mgmt_conn = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
2791182ee45dSLuiz Augusto von Dentz 
2792182ee45dSLuiz Augusto von Dentz 	if (conn->type == ACL_LINK) {
2793629f66aaSAlain Michaud 		if (test_and_clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags))
2794182ee45dSLuiz Augusto von Dentz 			hci_remove_link_key(hdev, &conn->dst);
2795182ee45dSLuiz Augusto von Dentz 	}
2796182ee45dSLuiz Augusto von Dentz 
2797182ee45dSLuiz Augusto von Dentz 	params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
2798182ee45dSLuiz Augusto von Dentz 	if (params) {
2799182ee45dSLuiz Augusto von Dentz 		switch (params->auto_connect) {
2800182ee45dSLuiz Augusto von Dentz 		case HCI_AUTO_CONN_LINK_LOSS:
2801182ee45dSLuiz Augusto von Dentz 			if (cp->reason != HCI_ERROR_CONNECTION_TIMEOUT)
2802182ee45dSLuiz Augusto von Dentz 				break;
2803182ee45dSLuiz Augusto von Dentz 			fallthrough;
2804182ee45dSLuiz Augusto von Dentz 
2805182ee45dSLuiz Augusto von Dentz 		case HCI_AUTO_CONN_DIRECT:
2806182ee45dSLuiz Augusto von Dentz 		case HCI_AUTO_CONN_ALWAYS:
2807182ee45dSLuiz Augusto von Dentz 			list_del_init(&params->action);
2808182ee45dSLuiz Augusto von Dentz 			list_add(&params->action, &hdev->pend_le_conns);
2809182ee45dSLuiz Augusto von Dentz 			break;
2810182ee45dSLuiz Augusto von Dentz 
2811182ee45dSLuiz Augusto von Dentz 		default:
2812182ee45dSLuiz Augusto von Dentz 			break;
2813182ee45dSLuiz Augusto von Dentz 		}
2814182ee45dSLuiz Augusto von Dentz 	}
2815182ee45dSLuiz Augusto von Dentz 
2816182ee45dSLuiz Augusto von Dentz 	mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type,
2817182ee45dSLuiz Augusto von Dentz 				 cp->reason, mgmt_conn);
2818182ee45dSLuiz Augusto von Dentz 
2819182ee45dSLuiz Augusto von Dentz 	hci_disconn_cfm(conn, cp->reason);
2820182ee45dSLuiz Augusto von Dentz 
2821182ee45dSLuiz Augusto von Dentz done:
2822b8d29052SJoseph Hwang 	/* If the disconnection failed for any reason, the upper layer
2823b8d29052SJoseph Hwang 	 * does not retry to disconnect in current implementation.
2824b8d29052SJoseph Hwang 	 * Hence, we need to do some basic cleanup here and re-enable
2825b8d29052SJoseph Hwang 	 * advertising if necessary.
2826b8d29052SJoseph Hwang 	 */
2827b8d29052SJoseph Hwang 	hci_conn_del(conn);
2828182ee45dSLuiz Augusto von Dentz unlock:
282988c3df13SJohan Hedberg 	hci_dev_unlock(hdev);
283088c3df13SJohan Hedberg }
283188c3df13SJohan Hedberg 
2832d850bf08SLuiz Augusto von Dentz static u8 ev_bdaddr_type(struct hci_dev *hdev, u8 type, bool *resolved)
28334ec4d63bSLuiz Augusto von Dentz {
28344ec4d63bSLuiz Augusto von Dentz 	/* When using controller based address resolution, then the new
28354ec4d63bSLuiz Augusto von Dentz 	 * address types 0x02 and 0x03 are used. These types need to be
28364ec4d63bSLuiz Augusto von Dentz 	 * converted back into either public address or random address type
28374ec4d63bSLuiz Augusto von Dentz 	 */
28384ec4d63bSLuiz Augusto von Dentz 	switch (type) {
28394ec4d63bSLuiz Augusto von Dentz 	case ADDR_LE_DEV_PUBLIC_RESOLVED:
2840d850bf08SLuiz Augusto von Dentz 		if (resolved)
2841d850bf08SLuiz Augusto von Dentz 			*resolved = true;
28424ec4d63bSLuiz Augusto von Dentz 		return ADDR_LE_DEV_PUBLIC;
28434ec4d63bSLuiz Augusto von Dentz 	case ADDR_LE_DEV_RANDOM_RESOLVED:
2844d850bf08SLuiz Augusto von Dentz 		if (resolved)
2845d850bf08SLuiz Augusto von Dentz 			*resolved = true;
28464ec4d63bSLuiz Augusto von Dentz 		return ADDR_LE_DEV_RANDOM;
28474ec4d63bSLuiz Augusto von Dentz 	}
28484ec4d63bSLuiz Augusto von Dentz 
2849d850bf08SLuiz Augusto von Dentz 	if (resolved)
2850d850bf08SLuiz Augusto von Dentz 		*resolved = false;
28514ec4d63bSLuiz Augusto von Dentz 	return type;
28524ec4d63bSLuiz Augusto von Dentz }
28534ec4d63bSLuiz Augusto von Dentz 
2854d12fb056SJaganath Kanakkassery static void cs_le_create_conn(struct hci_dev *hdev, bdaddr_t *peer_addr,
2855d12fb056SJaganath Kanakkassery 			      u8 peer_addr_type, u8 own_address_type,
2856d12fb056SJaganath Kanakkassery 			      u8 filter_policy)
2857d12fb056SJaganath Kanakkassery {
2858d12fb056SJaganath Kanakkassery 	struct hci_conn *conn;
2859d12fb056SJaganath Kanakkassery 
2860d12fb056SJaganath Kanakkassery 	conn = hci_conn_hash_lookup_le(hdev, peer_addr,
2861d12fb056SJaganath Kanakkassery 				       peer_addr_type);
2862d12fb056SJaganath Kanakkassery 	if (!conn)
2863d12fb056SJaganath Kanakkassery 		return;
2864d12fb056SJaganath Kanakkassery 
2865d850bf08SLuiz Augusto von Dentz 	own_address_type = ev_bdaddr_type(hdev, own_address_type, NULL);
2866b31bc00bSSathish Narasimman 
2867d12fb056SJaganath Kanakkassery 	/* Store the initiator and responder address information which
2868d12fb056SJaganath Kanakkassery 	 * is needed for SMP. These values will not change during the
2869d12fb056SJaganath Kanakkassery 	 * lifetime of the connection.
2870d12fb056SJaganath Kanakkassery 	 */
2871d12fb056SJaganath Kanakkassery 	conn->init_addr_type = own_address_type;
2872d12fb056SJaganath Kanakkassery 	if (own_address_type == ADDR_LE_DEV_RANDOM)
2873d12fb056SJaganath Kanakkassery 		bacpy(&conn->init_addr, &hdev->random_addr);
2874d12fb056SJaganath Kanakkassery 	else
2875d12fb056SJaganath Kanakkassery 		bacpy(&conn->init_addr, &hdev->bdaddr);
2876d12fb056SJaganath Kanakkassery 
2877d12fb056SJaganath Kanakkassery 	conn->resp_addr_type = peer_addr_type;
2878d12fb056SJaganath Kanakkassery 	bacpy(&conn->resp_addr, peer_addr);
2879d12fb056SJaganath Kanakkassery 
2880d12fb056SJaganath Kanakkassery 	/* We don't want the connection attempt to stick around
2881d12fb056SJaganath Kanakkassery 	 * indefinitely since LE doesn't have a page timeout concept
2882d12fb056SJaganath Kanakkassery 	 * like BR/EDR. Set a timer for any connection that doesn't use
28833d4f9c00SArchie Pusaka 	 * the accept list for connecting.
2884d12fb056SJaganath Kanakkassery 	 */
2885d12fb056SJaganath Kanakkassery 	if (filter_policy == HCI_LE_USE_PEER_ADDR)
2886d12fb056SJaganath Kanakkassery 		queue_delayed_work(conn->hdev->workqueue,
2887d12fb056SJaganath Kanakkassery 				   &conn->le_conn_timeout,
2888d12fb056SJaganath Kanakkassery 				   conn->conn_timeout);
2889d12fb056SJaganath Kanakkassery }
2890d12fb056SJaganath Kanakkassery 
2891cb1d68f7SJohan Hedberg static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status)
2892cb1d68f7SJohan Hedberg {
2893cb1d68f7SJohan Hedberg 	struct hci_cp_le_create_conn *cp;
2894cb1d68f7SJohan Hedberg 
2895147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2896cb1d68f7SJohan Hedberg 
2897cb1d68f7SJohan Hedberg 	/* All connection failure handling is taken care of by the
28989b3628d7SLuiz Augusto von Dentz 	 * hci_conn_failed function which is triggered by the HCI
2899cb1d68f7SJohan Hedberg 	 * request completion callbacks used for connecting.
2900cb1d68f7SJohan Hedberg 	 */
2901cb1d68f7SJohan Hedberg 	if (status)
2902cb1d68f7SJohan Hedberg 		return;
2903cb1d68f7SJohan Hedberg 
2904cb1d68f7SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
2905cb1d68f7SJohan Hedberg 	if (!cp)
2906cb1d68f7SJohan Hedberg 		return;
2907cb1d68f7SJohan Hedberg 
2908cb1d68f7SJohan Hedberg 	hci_dev_lock(hdev);
2909cb1d68f7SJohan Hedberg 
2910d12fb056SJaganath Kanakkassery 	cs_le_create_conn(hdev, &cp->peer_addr, cp->peer_addr_type,
2911d12fb056SJaganath Kanakkassery 			  cp->own_address_type, cp->filter_policy);
2912cb1d68f7SJohan Hedberg 
2913cb1d68f7SJohan Hedberg 	hci_dev_unlock(hdev);
2914cb1d68f7SJohan Hedberg }
2915cb1d68f7SJohan Hedberg 
29164d94f95dSJaganath Kanakkassery static void hci_cs_le_ext_create_conn(struct hci_dev *hdev, u8 status)
29174d94f95dSJaganath Kanakkassery {
29184d94f95dSJaganath Kanakkassery 	struct hci_cp_le_ext_create_conn *cp;
29194d94f95dSJaganath Kanakkassery 
2920147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
29214d94f95dSJaganath Kanakkassery 
29224d94f95dSJaganath Kanakkassery 	/* All connection failure handling is taken care of by the
29239b3628d7SLuiz Augusto von Dentz 	 * hci_conn_failed function which is triggered by the HCI
29244d94f95dSJaganath Kanakkassery 	 * request completion callbacks used for connecting.
29254d94f95dSJaganath Kanakkassery 	 */
29264d94f95dSJaganath Kanakkassery 	if (status)
29274d94f95dSJaganath Kanakkassery 		return;
29284d94f95dSJaganath Kanakkassery 
29294d94f95dSJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_EXT_CREATE_CONN);
29304d94f95dSJaganath Kanakkassery 	if (!cp)
29314d94f95dSJaganath Kanakkassery 		return;
29324d94f95dSJaganath Kanakkassery 
29334d94f95dSJaganath Kanakkassery 	hci_dev_lock(hdev);
29344d94f95dSJaganath Kanakkassery 
29354d94f95dSJaganath Kanakkassery 	cs_le_create_conn(hdev, &cp->peer_addr, cp->peer_addr_type,
29364d94f95dSJaganath Kanakkassery 			  cp->own_addr_type, cp->filter_policy);
29374d94f95dSJaganath Kanakkassery 
29384d94f95dSJaganath Kanakkassery 	hci_dev_unlock(hdev);
29394d94f95dSJaganath Kanakkassery }
29404d94f95dSJaganath Kanakkassery 
29410fe29fd1SMarcel Holtmann static void hci_cs_le_read_remote_features(struct hci_dev *hdev, u8 status)
29420fe29fd1SMarcel Holtmann {
29430fe29fd1SMarcel Holtmann 	struct hci_cp_le_read_remote_features *cp;
29440fe29fd1SMarcel Holtmann 	struct hci_conn *conn;
29450fe29fd1SMarcel Holtmann 
2946147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
29470fe29fd1SMarcel Holtmann 
29480fe29fd1SMarcel Holtmann 	if (!status)
29490fe29fd1SMarcel Holtmann 		return;
29500fe29fd1SMarcel Holtmann 
29510fe29fd1SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_READ_REMOTE_FEATURES);
29520fe29fd1SMarcel Holtmann 	if (!cp)
29530fe29fd1SMarcel Holtmann 		return;
29540fe29fd1SMarcel Holtmann 
29550fe29fd1SMarcel Holtmann 	hci_dev_lock(hdev);
29560fe29fd1SMarcel Holtmann 
29570fe29fd1SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
29580fe29fd1SMarcel Holtmann 	if (conn) {
29590fe29fd1SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
29600fe29fd1SMarcel Holtmann 			hci_connect_cfm(conn, status);
29610fe29fd1SMarcel Holtmann 			hci_conn_drop(conn);
29620fe29fd1SMarcel Holtmann 		}
29630fe29fd1SMarcel Holtmann 	}
29640fe29fd1SMarcel Holtmann 
29650fe29fd1SMarcel Holtmann 	hci_dev_unlock(hdev);
29660fe29fd1SMarcel Holtmann }
29670fe29fd1SMarcel Holtmann 
296881d0c8adSJohan Hedberg static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
296981d0c8adSJohan Hedberg {
297081d0c8adSJohan Hedberg 	struct hci_cp_le_start_enc *cp;
297181d0c8adSJohan Hedberg 	struct hci_conn *conn;
297281d0c8adSJohan Hedberg 
2973147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
297481d0c8adSJohan Hedberg 
297581d0c8adSJohan Hedberg 	if (!status)
297681d0c8adSJohan Hedberg 		return;
297781d0c8adSJohan Hedberg 
297881d0c8adSJohan Hedberg 	hci_dev_lock(hdev);
297981d0c8adSJohan Hedberg 
298081d0c8adSJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_START_ENC);
298181d0c8adSJohan Hedberg 	if (!cp)
298281d0c8adSJohan Hedberg 		goto unlock;
298381d0c8adSJohan Hedberg 
298481d0c8adSJohan Hedberg 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
298581d0c8adSJohan Hedberg 	if (!conn)
298681d0c8adSJohan Hedberg 		goto unlock;
298781d0c8adSJohan Hedberg 
298881d0c8adSJohan Hedberg 	if (conn->state != BT_CONNECTED)
298981d0c8adSJohan Hedberg 		goto unlock;
299081d0c8adSJohan Hedberg 
299181d0c8adSJohan Hedberg 	hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
299281d0c8adSJohan Hedberg 	hci_conn_drop(conn);
299381d0c8adSJohan Hedberg 
299481d0c8adSJohan Hedberg unlock:
299581d0c8adSJohan Hedberg 	hci_dev_unlock(hdev);
299681d0c8adSJohan Hedberg }
299781d0c8adSJohan Hedberg 
299850fc85f1SKuba Pawlak static void hci_cs_switch_role(struct hci_dev *hdev, u8 status)
299950fc85f1SKuba Pawlak {
300050fc85f1SKuba Pawlak 	struct hci_cp_switch_role *cp;
300150fc85f1SKuba Pawlak 	struct hci_conn *conn;
300250fc85f1SKuba Pawlak 
300350fc85f1SKuba Pawlak 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
300450fc85f1SKuba Pawlak 
300550fc85f1SKuba Pawlak 	if (!status)
300650fc85f1SKuba Pawlak 		return;
300750fc85f1SKuba Pawlak 
300850fc85f1SKuba Pawlak 	cp = hci_sent_cmd_data(hdev, HCI_OP_SWITCH_ROLE);
300950fc85f1SKuba Pawlak 	if (!cp)
301050fc85f1SKuba Pawlak 		return;
301150fc85f1SKuba Pawlak 
301250fc85f1SKuba Pawlak 	hci_dev_lock(hdev);
301350fc85f1SKuba Pawlak 
301450fc85f1SKuba Pawlak 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
301550fc85f1SKuba Pawlak 	if (conn)
301650fc85f1SKuba Pawlak 		clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
301750fc85f1SKuba Pawlak 
301850fc85f1SKuba Pawlak 	hci_dev_unlock(hdev);
301950fc85f1SKuba Pawlak }
302050fc85f1SKuba Pawlak 
30213e54c589SLuiz Augusto von Dentz static void hci_inquiry_complete_evt(struct hci_dev *hdev, void *data,
30223e54c589SLuiz Augusto von Dentz 				     struct sk_buff *skb)
30231da177e4SLinus Torvalds {
30243e54c589SLuiz Augusto von Dentz 	struct hci_ev_status *ev = data;
302530dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
302630dc78e1SJohan Hedberg 	struct inquiry_entry *e;
30271da177e4SLinus Torvalds 
30283e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
30291da177e4SLinus Torvalds 
3030a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
303189352e7dSAndre Guedes 
303289352e7dSAndre Guedes 	if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
303389352e7dSAndre Guedes 		return;
303489352e7dSAndre Guedes 
30354e857c58SPeter Zijlstra 	smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */
30363e13fa1eSAndre Guedes 	wake_up_bit(&hdev->flags, HCI_INQUIRY);
30373e13fa1eSAndre Guedes 
3038d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
303930dc78e1SJohan Hedberg 		return;
304030dc78e1SJohan Hedberg 
304156e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
304230dc78e1SJohan Hedberg 
3043343f935bSAndre Guedes 	if (discov->state != DISCOVERY_FINDING)
304430dc78e1SJohan Hedberg 		goto unlock;
304530dc78e1SJohan Hedberg 
304630dc78e1SJohan Hedberg 	if (list_empty(&discov->resolve)) {
304707d2334aSJakub Pawlowski 		/* When BR/EDR inquiry is active and no LE scanning is in
304807d2334aSJakub Pawlowski 		 * progress, then change discovery state to indicate completion.
304907d2334aSJakub Pawlowski 		 *
305007d2334aSJakub Pawlowski 		 * When running LE scanning and BR/EDR inquiry simultaneously
305107d2334aSJakub Pawlowski 		 * and the LE scan already finished, then change the discovery
305207d2334aSJakub Pawlowski 		 * state to indicate completion.
305307d2334aSJakub Pawlowski 		 */
305407d2334aSJakub Pawlowski 		if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
305507d2334aSJakub Pawlowski 		    !test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks))
3056ff9ef578SJohan Hedberg 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
305730dc78e1SJohan Hedberg 		goto unlock;
305830dc78e1SJohan Hedberg 	}
305930dc78e1SJohan Hedberg 
306030dc78e1SJohan Hedberg 	e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
306130dc78e1SJohan Hedberg 	if (e && hci_resolve_name(hdev, e) == 0) {
306230dc78e1SJohan Hedberg 		e->name_state = NAME_PENDING;
306330dc78e1SJohan Hedberg 		hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
3064dbf6811aSArchie Pusaka 		discov->name_resolve_timeout = jiffies + NAME_RESOLVE_DURATION;
306530dc78e1SJohan Hedberg 	} else {
306607d2334aSJakub Pawlowski 		/* When BR/EDR inquiry is active and no LE scanning is in
306707d2334aSJakub Pawlowski 		 * progress, then change discovery state to indicate completion.
306807d2334aSJakub Pawlowski 		 *
306907d2334aSJakub Pawlowski 		 * When running LE scanning and BR/EDR inquiry simultaneously
307007d2334aSJakub Pawlowski 		 * and the LE scan already finished, then change the discovery
307107d2334aSJakub Pawlowski 		 * state to indicate completion.
307207d2334aSJakub Pawlowski 		 */
307307d2334aSJakub Pawlowski 		if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
307407d2334aSJakub Pawlowski 		    !test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks))
307530dc78e1SJohan Hedberg 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
307630dc78e1SJohan Hedberg 	}
307730dc78e1SJohan Hedberg 
307830dc78e1SJohan Hedberg unlock:
307956e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
30801da177e4SLinus Torvalds }
30811da177e4SLinus Torvalds 
30823e54c589SLuiz Augusto von Dentz static void hci_inquiry_result_evt(struct hci_dev *hdev, void *edata,
30833e54c589SLuiz Augusto von Dentz 				   struct sk_buff *skb)
30841da177e4SLinus Torvalds {
30853e54c589SLuiz Augusto von Dentz 	struct hci_ev_inquiry_result *ev = edata;
308645bb4bf0SMarcel Holtmann 	struct inquiry_data data;
308727d9eb4bSLuiz Augusto von Dentz 	int i;
30881da177e4SLinus Torvalds 
308927d9eb4bSLuiz Augusto von Dentz 	if (!hci_ev_skb_pull(hdev, skb, HCI_EV_INQUIRY_RESULT,
309027d9eb4bSLuiz Augusto von Dentz 			     flex_array_size(ev, info, ev->num)))
309127d9eb4bSLuiz Augusto von Dentz 		return;
309227d9eb4bSLuiz Augusto von Dentz 
30933e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "num %d", ev->num);
309427d9eb4bSLuiz Augusto von Dentz 
309527d9eb4bSLuiz Augusto von Dentz 	if (!ev->num)
309645bb4bf0SMarcel Holtmann 		return;
309745bb4bf0SMarcel Holtmann 
3098d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ))
30991519cc17SAndre Guedes 		return;
31001519cc17SAndre Guedes 
31011da177e4SLinus Torvalds 	hci_dev_lock(hdev);
310245bb4bf0SMarcel Holtmann 
310327d9eb4bSLuiz Augusto von Dentz 	for (i = 0; i < ev->num; i++) {
310427d9eb4bSLuiz Augusto von Dentz 		struct inquiry_info *info = &ev->info[i];
3105af58925cSMarcel Holtmann 		u32 flags;
31063175405bSJohan Hedberg 
31071da177e4SLinus Torvalds 		bacpy(&data.bdaddr, &info->bdaddr);
31081da177e4SLinus Torvalds 		data.pscan_rep_mode	= info->pscan_rep_mode;
31091da177e4SLinus Torvalds 		data.pscan_period_mode	= info->pscan_period_mode;
31101da177e4SLinus Torvalds 		data.pscan_mode		= info->pscan_mode;
31111da177e4SLinus Torvalds 		memcpy(data.dev_class, info->dev_class, 3);
31121da177e4SLinus Torvalds 		data.clock_offset	= info->clock_offset;
3113efb2513fSMarcel Holtmann 		data.rssi		= HCI_RSSI_INVALID;
311441a96212SMarcel Holtmann 		data.ssp_mode		= 0x00;
31153175405bSJohan Hedberg 
3116af58925cSMarcel Holtmann 		flags = hci_inquiry_cache_update(hdev, &data, false);
3117af58925cSMarcel Holtmann 
311848264f06SJohan Hedberg 		mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
3119efb2513fSMarcel Holtmann 				  info->dev_class, HCI_RSSI_INVALID,
3120b338d917SBrian Gix 				  flags, NULL, 0, NULL, 0, 0);
31211da177e4SLinus Torvalds 	}
312245bb4bf0SMarcel Holtmann 
31231da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
31241da177e4SLinus Torvalds }
31251da177e4SLinus Torvalds 
31263e54c589SLuiz Augusto von Dentz static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
31273e54c589SLuiz Augusto von Dentz 				  struct sk_buff *skb)
31281da177e4SLinus Torvalds {
31293e54c589SLuiz Augusto von Dentz 	struct hci_ev_conn_complete *ev = data;
3130a9de9248SMarcel Holtmann 	struct hci_conn *conn;
3131c86cc5a3SLuiz Augusto von Dentz 	u8 status = ev->status;
31321da177e4SLinus Torvalds 
3133c86cc5a3SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
313445bb4bf0SMarcel Holtmann 
31351da177e4SLinus Torvalds 	hci_dev_lock(hdev);
313645bb4bf0SMarcel Holtmann 
3137a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
31389499237aSMarcel Holtmann 	if (!conn) {
3139aef2aa4fSLuiz Augusto von Dentz 		/* In case of error status and there is no connection pending
3140aef2aa4fSLuiz Augusto von Dentz 		 * just unlock as there is nothing to cleanup.
3141aef2aa4fSLuiz Augusto von Dentz 		 */
3142aef2aa4fSLuiz Augusto von Dentz 		if (ev->status)
3143aef2aa4fSLuiz Augusto von Dentz 			goto unlock;
3144aef2aa4fSLuiz Augusto von Dentz 
3145a46b7ed4SSonny Sasaka 		/* Connection may not exist if auto-connected. Check the bredr
3146a46b7ed4SSonny Sasaka 		 * allowlist to see if this device is allowed to auto connect.
3147a46b7ed4SSonny Sasaka 		 * If link is an ACL type, create a connection class
31484f40afc6SAbhishek Pandit-Subedi 		 * automatically.
3149a46b7ed4SSonny Sasaka 		 *
3150a46b7ed4SSonny Sasaka 		 * Auto-connect will only occur if the event filter is
3151a46b7ed4SSonny Sasaka 		 * programmed with a given address. Right now, event filter is
3152a46b7ed4SSonny Sasaka 		 * only used during suspend.
31534f40afc6SAbhishek Pandit-Subedi 		 */
3154a46b7ed4SSonny Sasaka 		if (ev->link_type == ACL_LINK &&
31553d4f9c00SArchie Pusaka 		    hci_bdaddr_list_lookup_with_flags(&hdev->accept_list,
3156a46b7ed4SSonny Sasaka 						      &ev->bdaddr,
3157a46b7ed4SSonny Sasaka 						      BDADDR_BREDR)) {
31584f40afc6SAbhishek Pandit-Subedi 			conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr,
31594f40afc6SAbhishek Pandit-Subedi 					    HCI_ROLE_SLAVE);
31604f40afc6SAbhishek Pandit-Subedi 			if (!conn) {
31614f40afc6SAbhishek Pandit-Subedi 				bt_dev_err(hdev, "no memory for new conn");
31624f40afc6SAbhishek Pandit-Subedi 				goto unlock;
31634f40afc6SAbhishek Pandit-Subedi 			}
31642d186fcdSAbhishek Pandit-Subedi 		} else {
31659499237aSMarcel Holtmann 			if (ev->link_type != SCO_LINK)
31669499237aSMarcel Holtmann 				goto unlock;
31679499237aSMarcel Holtmann 
31682d186fcdSAbhishek Pandit-Subedi 			conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK,
31692d186fcdSAbhishek Pandit-Subedi 						       &ev->bdaddr);
3170a9de9248SMarcel Holtmann 			if (!conn)
3171a9de9248SMarcel Holtmann 				goto unlock;
317245bb4bf0SMarcel Holtmann 
31739499237aSMarcel Holtmann 			conn->type = SCO_LINK;
31749499237aSMarcel Holtmann 		}
31752d186fcdSAbhishek Pandit-Subedi 	}
31769499237aSMarcel Holtmann 
3177d5ebaa7cSSoenke Huster 	/* The HCI_Connection_Complete event is only sent once per connection.
3178d5ebaa7cSSoenke Huster 	 * Processing it more than once per connection can corrupt kernel memory.
3179d5ebaa7cSSoenke Huster 	 *
3180d5ebaa7cSSoenke Huster 	 * As the connection handle is set here for the first time, it indicates
3181d5ebaa7cSSoenke Huster 	 * whether the connection is already set up.
3182d5ebaa7cSSoenke Huster 	 */
3183d5ebaa7cSSoenke Huster 	if (conn->handle != HCI_CONN_HANDLE_UNSET) {
3184d5ebaa7cSSoenke Huster 		bt_dev_err(hdev, "Ignoring HCI_Connection_Complete for existing connection");
3185d5ebaa7cSSoenke Huster 		goto unlock;
3186d5ebaa7cSSoenke Huster 	}
3187d5ebaa7cSSoenke Huster 
3188c86cc5a3SLuiz Augusto von Dentz 	if (!status) {
3189a9de9248SMarcel Holtmann 		conn->handle = __le16_to_cpu(ev->handle);
3190c86cc5a3SLuiz Augusto von Dentz 		if (conn->handle > HCI_CONN_HANDLE_MAX) {
3191c86cc5a3SLuiz Augusto von Dentz 			bt_dev_err(hdev, "Invalid handle: 0x%4.4x > 0x%4.4x",
3192c86cc5a3SLuiz Augusto von Dentz 				   conn->handle, HCI_CONN_HANDLE_MAX);
3193c86cc5a3SLuiz Augusto von Dentz 			status = HCI_ERROR_INVALID_PARAMETERS;
3194c86cc5a3SLuiz Augusto von Dentz 			goto done;
3195c86cc5a3SLuiz Augusto von Dentz 		}
3196769be974SMarcel Holtmann 
3197769be974SMarcel Holtmann 		if (conn->type == ACL_LINK) {
3198769be974SMarcel Holtmann 			conn->state = BT_CONFIG;
3199769be974SMarcel Holtmann 			hci_conn_hold(conn);
3200a9ea3ed9SSzymon Janc 
3201a9ea3ed9SSzymon Janc 			if (!conn->out && !hci_conn_ssp_enabled(conn) &&
3202a9ea3ed9SSzymon Janc 			    !hci_find_link_key(hdev, &ev->bdaddr))
3203a9ea3ed9SSzymon Janc 				conn->disc_timeout = HCI_PAIRING_TIMEOUT;
3204a9ea3ed9SSzymon Janc 			else
3205052b30b0SMarcel Holtmann 				conn->disc_timeout = HCI_DISCONN_TIMEOUT;
3206769be974SMarcel Holtmann 		} else
3207a9de9248SMarcel Holtmann 			conn->state = BT_CONNECTED;
3208a9de9248SMarcel Holtmann 
320923b9ceb7SMarcel Holtmann 		hci_debugfs_create_conn(conn);
32107d0db0a3SMarcel Holtmann 		hci_conn_add_sysfs(conn);
32117d0db0a3SMarcel Holtmann 
3212a9de9248SMarcel Holtmann 		if (test_bit(HCI_AUTH, &hdev->flags))
32134dae2798SJohan Hedberg 			set_bit(HCI_CONN_AUTH, &conn->flags);
3214a9de9248SMarcel Holtmann 
3215a9de9248SMarcel Holtmann 		if (test_bit(HCI_ENCRYPT, &hdev->flags))
32164dae2798SJohan Hedberg 			set_bit(HCI_CONN_ENCRYPT, &conn->flags);
3217a9de9248SMarcel Holtmann 
3218a9de9248SMarcel Holtmann 		/* Get remote features */
3219a9de9248SMarcel Holtmann 		if (conn->type == ACL_LINK) {
3220a9de9248SMarcel Holtmann 			struct hci_cp_read_remote_features cp;
3221a9de9248SMarcel Holtmann 			cp.handle = ev->handle;
3222769be974SMarcel Holtmann 			hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
3223769be974SMarcel Holtmann 				     sizeof(cp), &cp);
322422f433dcSJohan Hedberg 
3225bb876725SBrian Gix 			hci_update_scan(hdev);
322645bb4bf0SMarcel Holtmann 		}
3227a9de9248SMarcel Holtmann 
3228a9de9248SMarcel Holtmann 		/* Set packet type for incoming connection */
3229d095c1ebSAndrei Emeltchenko 		if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
3230a9de9248SMarcel Holtmann 			struct hci_cp_change_conn_ptype cp;
3231a9de9248SMarcel Holtmann 			cp.handle = ev->handle;
3232a8746417SMarcel Holtmann 			cp.pkt_type = cpu_to_le16(conn->pkt_type);
323304124681SGustavo F. Padovan 			hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
323404124681SGustavo F. Padovan 				     &cp);
3235a9de9248SMarcel Holtmann 		}
323617d5c04cSJohan Hedberg 	}
323745bb4bf0SMarcel Holtmann 
3238e73439d8SMarcel Holtmann 	if (conn->type == ACL_LINK)
3239e73439d8SMarcel Holtmann 		hci_sco_setup(conn, ev->status);
324045bb4bf0SMarcel Holtmann 
3241c86cc5a3SLuiz Augusto von Dentz done:
3242c86cc5a3SLuiz Augusto von Dentz 	if (status) {
32439b3628d7SLuiz Augusto von Dentz 		hci_conn_failed(conn, status);
32441f8330eaSSathish Narsimman 	} else if (ev->link_type == SCO_LINK) {
32451f8330eaSSathish Narsimman 		switch (conn->setting & SCO_AIRMODE_MASK) {
32461f8330eaSSathish Narsimman 		case SCO_AIRMODE_CVSD:
32471f8330eaSSathish Narsimman 			if (hdev->notify)
32481f8330eaSSathish Narsimman 				hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD);
32491f8330eaSSathish Narsimman 			break;
32501f8330eaSSathish Narsimman 		}
32511f8330eaSSathish Narsimman 
3252c86cc5a3SLuiz Augusto von Dentz 		hci_connect_cfm(conn, status);
32531f8330eaSSathish Narsimman 	}
3254a9de9248SMarcel Holtmann 
3255a9de9248SMarcel Holtmann unlock:
32561da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
3257a9de9248SMarcel Holtmann 
3258a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
32591da177e4SLinus Torvalds }
32601da177e4SLinus Torvalds 
326170c46425SJohan Hedberg static void hci_reject_conn(struct hci_dev *hdev, bdaddr_t *bdaddr)
326270c46425SJohan Hedberg {
326370c46425SJohan Hedberg 	struct hci_cp_reject_conn_req cp;
326470c46425SJohan Hedberg 
326570c46425SJohan Hedberg 	bacpy(&cp.bdaddr, bdaddr);
326670c46425SJohan Hedberg 	cp.reason = HCI_ERROR_REJ_BAD_ADDR;
326770c46425SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
326870c46425SJohan Hedberg }
326970c46425SJohan Hedberg 
32703e54c589SLuiz Augusto von Dentz static void hci_conn_request_evt(struct hci_dev *hdev, void *data,
32713e54c589SLuiz Augusto von Dentz 				 struct sk_buff *skb)
32721da177e4SLinus Torvalds {
32733e54c589SLuiz Augusto von Dentz 	struct hci_ev_conn_request *ev = data;
32741da177e4SLinus Torvalds 	int mask = hdev->link_mode;
327570c46425SJohan Hedberg 	struct inquiry_entry *ie;
327670c46425SJohan Hedberg 	struct hci_conn *conn;
327720714bfeSFrédéric Dalleau 	__u8 flags = 0;
32781da177e4SLinus Torvalds 
32793e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "bdaddr %pMR type 0x%x", &ev->bdaddr, ev->link_type);
32801da177e4SLinus Torvalds 
328120714bfeSFrédéric Dalleau 	mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
328220714bfeSFrédéric Dalleau 				      &flags);
32831da177e4SLinus Torvalds 
328470c46425SJohan Hedberg 	if (!(mask & HCI_LM_ACCEPT)) {
328570c46425SJohan Hedberg 		hci_reject_conn(hdev, &ev->bdaddr);
328670c46425SJohan Hedberg 		return;
328770c46425SJohan Hedberg 	}
328870c46425SJohan Hedberg 
3289fb048caeSNiels Dossche 	hci_dev_lock(hdev);
3290fb048caeSNiels Dossche 
32913d4f9c00SArchie Pusaka 	if (hci_bdaddr_list_lookup(&hdev->reject_list, &ev->bdaddr,
3292dcc36c16SJohan Hedberg 				   BDADDR_BREDR)) {
329370c46425SJohan Hedberg 		hci_reject_conn(hdev, &ev->bdaddr);
3294fb048caeSNiels Dossche 		goto unlock;
329570c46425SJohan Hedberg 	}
329646c4c941SJohan Hedberg 
32973d4f9c00SArchie Pusaka 	/* Require HCI_CONNECTABLE or an accept list entry to accept the
32986a8fc95cSJohan Hedberg 	 * connection. These features are only touched through mgmt so
32996a8fc95cSJohan Hedberg 	 * only do the checks if HCI_MGMT is set.
33006a8fc95cSJohan Hedberg 	 */
3301d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT) &&
3302d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONNECTABLE) &&
33033d4f9c00SArchie Pusaka 	    !hci_bdaddr_list_lookup_with_flags(&hdev->accept_list, &ev->bdaddr,
3304a55bd29dSJohan Hedberg 					       BDADDR_BREDR)) {
3305a55bd29dSJohan Hedberg 		hci_reject_conn(hdev, &ev->bdaddr);
3306fb048caeSNiels Dossche 		goto unlock;
3307a55bd29dSJohan Hedberg 	}
330870c46425SJohan Hedberg 
33091da177e4SLinus Torvalds 	/* Connection accepted */
33101da177e4SLinus Torvalds 
3311cc11b9c1SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3312cc11b9c1SAndrei Emeltchenko 	if (ie)
3313c7bdd502SMarcel Holtmann 		memcpy(ie->data.dev_class, ev->dev_class, 3);
3314c7bdd502SMarcel Holtmann 
33158fc9ced3SGustavo Padovan 	conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
33168fc9ced3SGustavo Padovan 			&ev->bdaddr);
33171da177e4SLinus Torvalds 	if (!conn) {
3318a5c4e309SJohan Hedberg 		conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr,
3319a5c4e309SJohan Hedberg 				    HCI_ROLE_SLAVE);
3320cc11b9c1SAndrei Emeltchenko 		if (!conn) {
33212064ee33SMarcel Holtmann 			bt_dev_err(hdev, "no memory for new connection");
3322fb048caeSNiels Dossche 			goto unlock;
33231da177e4SLinus Torvalds 		}
33241da177e4SLinus Torvalds 	}
3325b6a0dc82SMarcel Holtmann 
33261da177e4SLinus Torvalds 	memcpy(conn->dev_class, ev->dev_class, 3);
3327b6a0dc82SMarcel Holtmann 
33281da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
33291da177e4SLinus Torvalds 
333020714bfeSFrédéric Dalleau 	if (ev->link_type == ACL_LINK ||
333120714bfeSFrédéric Dalleau 	    (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
3332b6a0dc82SMarcel Holtmann 		struct hci_cp_accept_conn_req cp;
333320714bfeSFrédéric Dalleau 		conn->state = BT_CONNECT;
3334b6a0dc82SMarcel Holtmann 
33351da177e4SLinus Torvalds 		bacpy(&cp.bdaddr, &ev->bdaddr);
33361da177e4SLinus Torvalds 
33371da177e4SLinus Torvalds 		if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
333874be523cSArchie Pusaka 			cp.role = 0x00; /* Become central */
33391da177e4SLinus Torvalds 		else
334074be523cSArchie Pusaka 			cp.role = 0x01; /* Remain peripheral */
33411da177e4SLinus Torvalds 
334270c46425SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp);
334320714bfeSFrédéric Dalleau 	} else if (!(flags & HCI_PROTO_DEFER)) {
3344b6a0dc82SMarcel Holtmann 		struct hci_cp_accept_sync_conn_req cp;
334520714bfeSFrédéric Dalleau 		conn->state = BT_CONNECT;
3346b6a0dc82SMarcel Holtmann 
3347b6a0dc82SMarcel Holtmann 		bacpy(&cp.bdaddr, &ev->bdaddr);
3348a8746417SMarcel Holtmann 		cp.pkt_type = cpu_to_le16(conn->pkt_type);
3349b6a0dc82SMarcel Holtmann 
3350dcf4adbfSJoe Perches 		cp.tx_bandwidth   = cpu_to_le32(0x00001f40);
3351dcf4adbfSJoe Perches 		cp.rx_bandwidth   = cpu_to_le32(0x00001f40);
3352dcf4adbfSJoe Perches 		cp.max_latency    = cpu_to_le16(0xffff);
3353b6a0dc82SMarcel Holtmann 		cp.content_format = cpu_to_le16(hdev->voice_setting);
3354b6a0dc82SMarcel Holtmann 		cp.retrans_effort = 0xff;
3355b6a0dc82SMarcel Holtmann 
335670c46425SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, sizeof(cp),
335770c46425SJohan Hedberg 			     &cp);
335820714bfeSFrédéric Dalleau 	} else {
335920714bfeSFrédéric Dalleau 		conn->state = BT_CONNECT2;
3360539c496dSJohan Hedberg 		hci_connect_cfm(conn, 0);
3361b6a0dc82SMarcel Holtmann 	}
3362fb048caeSNiels Dossche 
3363fb048caeSNiels Dossche 	return;
3364fb048caeSNiels Dossche unlock:
3365fb048caeSNiels Dossche 	hci_dev_unlock(hdev);
33661da177e4SLinus Torvalds }
33671da177e4SLinus Torvalds 
3368f0d6a0eaSMikel Astiz static u8 hci_to_mgmt_reason(u8 err)
3369f0d6a0eaSMikel Astiz {
3370f0d6a0eaSMikel Astiz 	switch (err) {
3371f0d6a0eaSMikel Astiz 	case HCI_ERROR_CONNECTION_TIMEOUT:
3372f0d6a0eaSMikel Astiz 		return MGMT_DEV_DISCONN_TIMEOUT;
3373f0d6a0eaSMikel Astiz 	case HCI_ERROR_REMOTE_USER_TERM:
3374f0d6a0eaSMikel Astiz 	case HCI_ERROR_REMOTE_LOW_RESOURCES:
3375f0d6a0eaSMikel Astiz 	case HCI_ERROR_REMOTE_POWER_OFF:
3376f0d6a0eaSMikel Astiz 		return MGMT_DEV_DISCONN_REMOTE;
3377f0d6a0eaSMikel Astiz 	case HCI_ERROR_LOCAL_HOST_TERM:
3378f0d6a0eaSMikel Astiz 		return MGMT_DEV_DISCONN_LOCAL_HOST;
3379f0d6a0eaSMikel Astiz 	default:
3380f0d6a0eaSMikel Astiz 		return MGMT_DEV_DISCONN_UNKNOWN;
3381f0d6a0eaSMikel Astiz 	}
3382f0d6a0eaSMikel Astiz }
3383f0d6a0eaSMikel Astiz 
33843e54c589SLuiz Augusto von Dentz static void hci_disconn_complete_evt(struct hci_dev *hdev, void *data,
33853e54c589SLuiz Augusto von Dentz 				     struct sk_buff *skb)
33861da177e4SLinus Torvalds {
33873e54c589SLuiz Augusto von Dentz 	struct hci_ev_disconn_complete *ev = data;
3388160b9251SSzymon Janc 	u8 reason;
33899fcb18efSAndre Guedes 	struct hci_conn_params *params;
339004837f64SMarcel Holtmann 	struct hci_conn *conn;
339112d4a3b2SJohan Hedberg 	bool mgmt_connected;
33921da177e4SLinus Torvalds 
33933e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
33941da177e4SLinus Torvalds 
33951da177e4SLinus Torvalds 	hci_dev_lock(hdev);
33961da177e4SLinus Torvalds 
339704837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3398f7520543SJohan Hedberg 	if (!conn)
3399f7520543SJohan Hedberg 		goto unlock;
3400f7520543SJohan Hedberg 
3401f0d6a0eaSMikel Astiz 	if (ev->status) {
340288c3df13SJohan Hedberg 		mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
340388c3df13SJohan Hedberg 				       conn->dst_type, ev->status);
3404abf54a50SAndre Guedes 		goto unlock;
3405abf54a50SAndre Guedes 	}
3406f0d6a0eaSMikel Astiz 
34073846220bSAndre Guedes 	conn->state = BT_CLOSED;
34083846220bSAndre Guedes 
340912d4a3b2SJohan Hedberg 	mgmt_connected = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
3410160b9251SSzymon Janc 
3411160b9251SSzymon Janc 	if (test_bit(HCI_CONN_AUTH_FAILURE, &conn->flags))
3412160b9251SSzymon Janc 		reason = MGMT_DEV_DISCONN_AUTH_FAILURE;
3413160b9251SSzymon Janc 	else
3414160b9251SSzymon Janc 		reason = hci_to_mgmt_reason(ev->reason);
3415160b9251SSzymon Janc 
341612d4a3b2SJohan Hedberg 	mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type,
341712d4a3b2SJohan Hedberg 				reason, mgmt_connected);
3418f7520543SJohan Hedberg 
341922f433dcSJohan Hedberg 	if (conn->type == ACL_LINK) {
3420629f66aaSAlain Michaud 		if (test_and_clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags))
34216ec5bcadSVishal Agarwal 			hci_remove_link_key(hdev, &conn->dst);
34223846220bSAndre Guedes 
3423bb876725SBrian Gix 		hci_update_scan(hdev);
342422f433dcSJohan Hedberg 	}
342522f433dcSJohan Hedberg 
34269fcb18efSAndre Guedes 	params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
34279fcb18efSAndre Guedes 	if (params) {
34289fcb18efSAndre Guedes 		switch (params->auto_connect) {
34299fcb18efSAndre Guedes 		case HCI_AUTO_CONN_LINK_LOSS:
34309fcb18efSAndre Guedes 			if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT)
34319fcb18efSAndre Guedes 				break;
343219186c7bSGustavo A. R. Silva 			fallthrough;
34339fcb18efSAndre Guedes 
34344b9e7e75SMarcel Holtmann 		case HCI_AUTO_CONN_DIRECT:
34359fcb18efSAndre Guedes 		case HCI_AUTO_CONN_ALWAYS:
3436418025d1SJohan Hedberg 			list_del_init(&params->action);
3437418025d1SJohan Hedberg 			list_add(&params->action, &hdev->pend_le_conns);
34385bee2fd6SLuiz Augusto von Dentz 			hci_update_passive_scan(hdev);
34399fcb18efSAndre Guedes 			break;
34409fcb18efSAndre Guedes 
34419fcb18efSAndre Guedes 		default:
34429fcb18efSAndre Guedes 			break;
34439fcb18efSAndre Guedes 		}
34449fcb18efSAndre Guedes 	}
34459fcb18efSAndre Guedes 
34463a6d576bSJohan Hedberg 	hci_disconn_cfm(conn, ev->reason);
34472210246cSJohan Hedberg 
34482210246cSJohan Hedberg 	/* Re-enable advertising if necessary, since it might
34492210246cSJohan Hedberg 	 * have been disabled by the connection. From the
34502210246cSJohan Hedberg 	 * HCI_LE_Set_Advertise_Enable command description in
34512210246cSJohan Hedberg 	 * the core specification (v4.0):
34522210246cSJohan Hedberg 	 * "The Controller shall continue advertising until the Host
34532210246cSJohan Hedberg 	 * issues an LE_Set_Advertise_Enable command with
34542210246cSJohan Hedberg 	 * Advertising_Enable set to 0x00 (Advertising is disabled)
34552210246cSJohan Hedberg 	 * or until a connection is created or until the Advertising
34562210246cSJohan Hedberg 	 * is timed out due to Directed Advertising."
34572210246cSJohan Hedberg 	 */
34581eeaa1aeSLuiz Augusto von Dentz 	if (conn->type == LE_LINK && conn->role == HCI_ROLE_SLAVE) {
34597087c4f6SLuiz Augusto von Dentz 		hdev->cur_adv_instance = conn->adv_instance;
3460abfeea47SLuiz Augusto von Dentz 		hci_enable_advertising(hdev);
34617087c4f6SLuiz Augusto von Dentz 	}
34627087c4f6SLuiz Augusto von Dentz 
34637087c4f6SLuiz Augusto von Dentz 	hci_conn_del(conn);
34641da177e4SLinus Torvalds 
3465f7520543SJohan Hedberg unlock:
34661da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
34671da177e4SLinus Torvalds }
34681da177e4SLinus Torvalds 
34693e54c589SLuiz Augusto von Dentz static void hci_auth_complete_evt(struct hci_dev *hdev, void *data,
34703e54c589SLuiz Augusto von Dentz 				  struct sk_buff *skb)
3471a9de9248SMarcel Holtmann {
34723e54c589SLuiz Augusto von Dentz 	struct hci_ev_auth_complete *ev = data;
3473a9de9248SMarcel Holtmann 	struct hci_conn *conn;
3474a9de9248SMarcel Holtmann 
34753e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
3476a9de9248SMarcel Holtmann 
3477a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
3478a9de9248SMarcel Holtmann 
3479a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3480d7556e20SWaldemar Rymarkiewicz 	if (!conn)
3481d7556e20SWaldemar Rymarkiewicz 		goto unlock;
3482d7556e20SWaldemar Rymarkiewicz 
3483765c2a96SJohan Hedberg 	if (!ev->status) {
3484160b9251SSzymon Janc 		clear_bit(HCI_CONN_AUTH_FAILURE, &conn->flags);
3485160b9251SSzymon Janc 
3486aa64a8b5SJohan Hedberg 		if (!hci_conn_ssp_enabled(conn) &&
348751a8efd7SJohan Hedberg 		    test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
34882064ee33SMarcel Holtmann 			bt_dev_info(hdev, "re-auth of legacy device is not possible.");
348919f8def0SWaldemar Rymarkiewicz 		} else {
34904dae2798SJohan Hedberg 			set_bit(HCI_CONN_AUTH, &conn->flags);
3491765c2a96SJohan Hedberg 			conn->sec_level = conn->pending_sec_level;
349219f8def0SWaldemar Rymarkiewicz 		}
34932a611692SJohan Hedberg 	} else {
3494160b9251SSzymon Janc 		if (ev->status == HCI_ERROR_PIN_OR_KEY_MISSING)
3495160b9251SSzymon Janc 			set_bit(HCI_CONN_AUTH_FAILURE, &conn->flags);
3496160b9251SSzymon Janc 
3497e1e930f5SJohan Hedberg 		mgmt_auth_failed(conn, ev->status);
34982a611692SJohan Hedberg 	}
3499a9de9248SMarcel Holtmann 
350051a8efd7SJohan Hedberg 	clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
350151a8efd7SJohan Hedberg 	clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
3502a9de9248SMarcel Holtmann 
3503f8558555SMarcel Holtmann 	if (conn->state == BT_CONFIG) {
3504aa64a8b5SJohan Hedberg 		if (!ev->status && hci_conn_ssp_enabled(conn)) {
3505f8558555SMarcel Holtmann 			struct hci_cp_set_conn_encrypt cp;
3506f8558555SMarcel Holtmann 			cp.handle  = ev->handle;
3507f8558555SMarcel Holtmann 			cp.encrypt = 0x01;
3508d7556e20SWaldemar Rymarkiewicz 			hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
3509d7556e20SWaldemar Rymarkiewicz 				     &cp);
3510f8558555SMarcel Holtmann 		} else {
3511f8558555SMarcel Holtmann 			conn->state = BT_CONNECTED;
3512539c496dSJohan Hedberg 			hci_connect_cfm(conn, ev->status);
351376a68ba0SDavid Herrmann 			hci_conn_drop(conn);
3514f8558555SMarcel Holtmann 		}
3515052b30b0SMarcel Holtmann 	} else {
3516a9de9248SMarcel Holtmann 		hci_auth_cfm(conn, ev->status);
3517a9de9248SMarcel Holtmann 
3518052b30b0SMarcel Holtmann 		hci_conn_hold(conn);
3519052b30b0SMarcel Holtmann 		conn->disc_timeout = HCI_DISCONN_TIMEOUT;
352076a68ba0SDavid Herrmann 		hci_conn_drop(conn);
3521052b30b0SMarcel Holtmann 	}
3522052b30b0SMarcel Holtmann 
352351a8efd7SJohan Hedberg 	if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
3524a9de9248SMarcel Holtmann 		if (!ev->status) {
3525a9de9248SMarcel Holtmann 			struct hci_cp_set_conn_encrypt cp;
3526f8558555SMarcel Holtmann 			cp.handle  = ev->handle;
3527f8558555SMarcel Holtmann 			cp.encrypt = 0x01;
3528d7556e20SWaldemar Rymarkiewicz 			hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
3529d7556e20SWaldemar Rymarkiewicz 				     &cp);
3530a9de9248SMarcel Holtmann 		} else {
353151a8efd7SJohan Hedberg 			clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
35323ca44c16SLuiz Augusto von Dentz 			hci_encrypt_cfm(conn, ev->status);
3533a9de9248SMarcel Holtmann 		}
3534a9de9248SMarcel Holtmann 	}
3535a9de9248SMarcel Holtmann 
3536d7556e20SWaldemar Rymarkiewicz unlock:
3537a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
3538a9de9248SMarcel Holtmann }
3539a9de9248SMarcel Holtmann 
35403e54c589SLuiz Augusto von Dentz static void hci_remote_name_evt(struct hci_dev *hdev, void *data,
35413e54c589SLuiz Augusto von Dentz 				struct sk_buff *skb)
3542a9de9248SMarcel Holtmann {
35433e54c589SLuiz Augusto von Dentz 	struct hci_ev_remote_name *ev = data;
3544127178d2SJohan Hedberg 	struct hci_conn *conn;
3545127178d2SJohan Hedberg 
35463e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
3547a9de9248SMarcel Holtmann 
3548a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
3549127178d2SJohan Hedberg 
3550127178d2SJohan Hedberg 	hci_dev_lock(hdev);
3551127178d2SJohan Hedberg 
3552127178d2SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3553b644ba33SJohan Hedberg 
3554d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
3555b644ba33SJohan Hedberg 		goto check_auth;
3556b644ba33SJohan Hedberg 
3557b644ba33SJohan Hedberg 	if (ev->status == 0)
3558b644ba33SJohan Hedberg 		hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
3559b644ba33SJohan Hedberg 				       strnlen(ev->name, HCI_MAX_NAME_LENGTH));
3560b644ba33SJohan Hedberg 	else
3561b644ba33SJohan Hedberg 		hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
3562b644ba33SJohan Hedberg 
3563b644ba33SJohan Hedberg check_auth:
356479c6c70cSJohan Hedberg 	if (!conn)
356579c6c70cSJohan Hedberg 		goto unlock;
356679c6c70cSJohan Hedberg 
356779c6c70cSJohan Hedberg 	if (!hci_outgoing_auth_needed(hdev, conn))
356879c6c70cSJohan Hedberg 		goto unlock;
356979c6c70cSJohan Hedberg 
357051a8efd7SJohan Hedberg 	if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
3571127178d2SJohan Hedberg 		struct hci_cp_auth_requested cp;
3572977f8fceSJohan Hedberg 
3573977f8fceSJohan Hedberg 		set_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags);
3574977f8fceSJohan Hedberg 
3575127178d2SJohan Hedberg 		cp.handle = __cpu_to_le16(conn->handle);
3576127178d2SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
3577127178d2SJohan Hedberg 	}
3578127178d2SJohan Hedberg 
357979c6c70cSJohan Hedberg unlock:
3580127178d2SJohan Hedberg 	hci_dev_unlock(hdev);
3581a9de9248SMarcel Holtmann }
3582a9de9248SMarcel Holtmann 
35833e54c589SLuiz Augusto von Dentz static void hci_encrypt_change_evt(struct hci_dev *hdev, void *data,
35843e54c589SLuiz Augusto von Dentz 				   struct sk_buff *skb)
3585a9de9248SMarcel Holtmann {
35863e54c589SLuiz Augusto von Dentz 	struct hci_ev_encrypt_change *ev = data;
3587a9de9248SMarcel Holtmann 	struct hci_conn *conn;
3588a9de9248SMarcel Holtmann 
35893e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
3590a9de9248SMarcel Holtmann 
3591a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
3592a9de9248SMarcel Holtmann 
3593a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3594dc8357ccSMarcel Holtmann 	if (!conn)
3595dc8357ccSMarcel Holtmann 		goto unlock;
3596dc8357ccSMarcel Holtmann 
3597a9de9248SMarcel Holtmann 	if (!ev->status) {
3598ae293196SMarcel Holtmann 		if (ev->encrypt) {
3599ae293196SMarcel Holtmann 			/* Encryption implies authentication */
36004dae2798SJohan Hedberg 			set_bit(HCI_CONN_AUTH, &conn->flags);
36014dae2798SJohan Hedberg 			set_bit(HCI_CONN_ENCRYPT, &conn->flags);
3602da85e5e5SVinicius Costa Gomes 			conn->sec_level = conn->pending_sec_level;
3603abf76badSMarcel Holtmann 
3604914a6ffeSMarcel Holtmann 			/* P-256 authentication key implies FIPS */
3605914a6ffeSMarcel Holtmann 			if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256)
36064dae2798SJohan Hedberg 				set_bit(HCI_CONN_FIPS, &conn->flags);
3607914a6ffeSMarcel Holtmann 
3608abf76badSMarcel Holtmann 			if ((conn->type == ACL_LINK && ev->encrypt == 0x02) ||
3609abf76badSMarcel Holtmann 			    conn->type == LE_LINK)
3610abf76badSMarcel Holtmann 				set_bit(HCI_CONN_AES_CCM, &conn->flags);
3611abf76badSMarcel Holtmann 		} else {
36124dae2798SJohan Hedberg 			clear_bit(HCI_CONN_ENCRYPT, &conn->flags);
3613abf76badSMarcel Holtmann 			clear_bit(HCI_CONN_AES_CCM, &conn->flags);
3614abf76badSMarcel Holtmann 		}
3615a9de9248SMarcel Holtmann 	}
3616a9de9248SMarcel Holtmann 
36177ed3fa20SJohan Hedberg 	/* We should disregard the current RPA and generate a new one
36187ed3fa20SJohan Hedberg 	 * whenever the encryption procedure fails.
36197ed3fa20SJohan Hedberg 	 */
3620a73c046aSJaganath Kanakkassery 	if (ev->status && conn->type == LE_LINK) {
3621a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
3622a73c046aSJaganath Kanakkassery 		hci_adv_instances_set_rpa_expired(hdev, true);
3623a73c046aSJaganath Kanakkassery 	}
36247ed3fa20SJohan Hedberg 
362551a8efd7SJohan Hedberg 	clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3626a9de9248SMarcel Holtmann 
36278746f135SLuiz Augusto von Dentz 	/* Check link security requirements are met */
36288746f135SLuiz Augusto von Dentz 	if (!hci_conn_check_link_mode(conn))
36298746f135SLuiz Augusto von Dentz 		ev->status = HCI_ERROR_AUTH_FAILURE;
36308746f135SLuiz Augusto von Dentz 
3631a7d7723aSGustavo Padovan 	if (ev->status && conn->state == BT_CONNECTED) {
3632160b9251SSzymon Janc 		if (ev->status == HCI_ERROR_PIN_OR_KEY_MISSING)
3633160b9251SSzymon Janc 			set_bit(HCI_CONN_AUTH_FAILURE, &conn->flags);
3634160b9251SSzymon Janc 
36358746f135SLuiz Augusto von Dentz 		/* Notify upper layers so they can cleanup before
36368746f135SLuiz Augusto von Dentz 		 * disconnecting.
363740b552aaSMarcel Holtmann 		 */
36388746f135SLuiz Augusto von Dentz 		hci_encrypt_cfm(conn, ev->status);
36398746f135SLuiz Augusto von Dentz 		hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
364040b552aaSMarcel Holtmann 		hci_conn_drop(conn);
364140b552aaSMarcel Holtmann 		goto unlock;
364240b552aaSMarcel Holtmann 	}
364340b552aaSMarcel Holtmann 
3644821f3766SJohan Hedberg 	/* Try reading the encryption key size for encrypted ACL links */
3645821f3766SJohan Hedberg 	if (!ev->status && ev->encrypt && conn->type == ACL_LINK) {
3646821f3766SJohan Hedberg 		struct hci_cp_read_enc_key_size cp;
3647821f3766SJohan Hedberg 
3648821f3766SJohan Hedberg 		/* Only send HCI_Read_Encryption_Key_Size if the
3649821f3766SJohan Hedberg 		 * controller really supports it. If it doesn't, assume
3650821f3766SJohan Hedberg 		 * the default size (16).
3651821f3766SJohan Hedberg 		 */
3652821f3766SJohan Hedberg 		if (!(hdev->commands[20] & 0x10)) {
3653821f3766SJohan Hedberg 			conn->enc_key_size = HCI_LINK_KEY_SIZE;
3654821f3766SJohan Hedberg 			goto notify;
3655821f3766SJohan Hedberg 		}
3656821f3766SJohan Hedberg 
3657821f3766SJohan Hedberg 		cp.handle = cpu_to_le16(conn->handle);
3658278d933eSBrian Gix 		if (hci_send_cmd(hdev, HCI_OP_READ_ENC_KEY_SIZE,
3659278d933eSBrian Gix 				 sizeof(cp), &cp)) {
36602064ee33SMarcel Holtmann 			bt_dev_err(hdev, "sending read key size failed");
3661821f3766SJohan Hedberg 			conn->enc_key_size = HCI_LINK_KEY_SIZE;
3662821f3766SJohan Hedberg 			goto notify;
3663821f3766SJohan Hedberg 		}
3664821f3766SJohan Hedberg 
3665821f3766SJohan Hedberg 		goto unlock;
3666821f3766SJohan Hedberg 	}
3667821f3766SJohan Hedberg 
3668302975cbSSpoorthi Ravishankar Koppad 	/* Set the default Authenticated Payload Timeout after
3669302975cbSSpoorthi Ravishankar Koppad 	 * an LE Link is established. As per Core Spec v5.0, Vol 2, Part B
3670302975cbSSpoorthi Ravishankar Koppad 	 * Section 3.3, the HCI command WRITE_AUTH_PAYLOAD_TIMEOUT should be
3671302975cbSSpoorthi Ravishankar Koppad 	 * sent when the link is active and Encryption is enabled, the conn
3672302975cbSSpoorthi Ravishankar Koppad 	 * type can be either LE or ACL and controller must support LMP Ping.
3673302975cbSSpoorthi Ravishankar Koppad 	 * Ensure for AES-CCM encryption as well.
3674302975cbSSpoorthi Ravishankar Koppad 	 */
3675302975cbSSpoorthi Ravishankar Koppad 	if (test_bit(HCI_CONN_ENCRYPT, &conn->flags) &&
3676302975cbSSpoorthi Ravishankar Koppad 	    test_bit(HCI_CONN_AES_CCM, &conn->flags) &&
3677302975cbSSpoorthi Ravishankar Koppad 	    ((conn->type == ACL_LINK && lmp_ping_capable(hdev)) ||
3678302975cbSSpoorthi Ravishankar Koppad 	     (conn->type == LE_LINK && (hdev->le_features[0] & HCI_LE_PING)))) {
3679302975cbSSpoorthi Ravishankar Koppad 		struct hci_cp_write_auth_payload_to cp;
3680302975cbSSpoorthi Ravishankar Koppad 
3681302975cbSSpoorthi Ravishankar Koppad 		cp.handle = cpu_to_le16(conn->handle);
3682302975cbSSpoorthi Ravishankar Koppad 		cp.timeout = cpu_to_le16(hdev->auth_payload_timeout);
3683302975cbSSpoorthi Ravishankar Koppad 		hci_send_cmd(conn->hdev, HCI_OP_WRITE_AUTH_PAYLOAD_TO,
3684302975cbSSpoorthi Ravishankar Koppad 			     sizeof(cp), &cp);
3685302975cbSSpoorthi Ravishankar Koppad 	}
3686302975cbSSpoorthi Ravishankar Koppad 
3687821f3766SJohan Hedberg notify:
36883ca44c16SLuiz Augusto von Dentz 	hci_encrypt_cfm(conn, ev->status);
3689a9de9248SMarcel Holtmann 
3690a7d7723aSGustavo Padovan unlock:
3691a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
3692a9de9248SMarcel Holtmann }
3693a9de9248SMarcel Holtmann 
36943e54c589SLuiz Augusto von Dentz static void hci_change_link_key_complete_evt(struct hci_dev *hdev, void *data,
3695807deac2SGustavo Padovan 					     struct sk_buff *skb)
3696a9de9248SMarcel Holtmann {
36973e54c589SLuiz Augusto von Dentz 	struct hci_ev_change_link_key_complete *ev = data;
3698a9de9248SMarcel Holtmann 	struct hci_conn *conn;
3699a9de9248SMarcel Holtmann 
37003e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
3701a9de9248SMarcel Holtmann 
3702a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
3703a9de9248SMarcel Holtmann 
3704a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3705a9de9248SMarcel Holtmann 	if (conn) {
3706a9de9248SMarcel Holtmann 		if (!ev->status)
37074dae2798SJohan Hedberg 			set_bit(HCI_CONN_SECURE, &conn->flags);
3708a9de9248SMarcel Holtmann 
370951a8efd7SJohan Hedberg 		clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
3710a9de9248SMarcel Holtmann 
3711a9de9248SMarcel Holtmann 		hci_key_change_cfm(conn, ev->status);
3712a9de9248SMarcel Holtmann 	}
3713a9de9248SMarcel Holtmann 
3714a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
3715a9de9248SMarcel Holtmann }
3716a9de9248SMarcel Holtmann 
37173e54c589SLuiz Augusto von Dentz static void hci_remote_features_evt(struct hci_dev *hdev, void *data,
3718807deac2SGustavo Padovan 				    struct sk_buff *skb)
3719a9de9248SMarcel Holtmann {
37203e54c589SLuiz Augusto von Dentz 	struct hci_ev_remote_features *ev = data;
3721a9de9248SMarcel Holtmann 	struct hci_conn *conn;
3722a9de9248SMarcel Holtmann 
37233e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
3724a9de9248SMarcel Holtmann 
3725a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
3726a9de9248SMarcel Holtmann 
3727a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3728ccd556feSJohan Hedberg 	if (!conn)
3729ccd556feSJohan Hedberg 		goto unlock;
3730ccd556feSJohan Hedberg 
3731769be974SMarcel Holtmann 	if (!ev->status)
3732cad718edSJohan Hedberg 		memcpy(conn->features[0], ev->features, 8);
3733a9de9248SMarcel Holtmann 
3734ccd556feSJohan Hedberg 	if (conn->state != BT_CONFIG)
3735ccd556feSJohan Hedberg 		goto unlock;
3736ccd556feSJohan Hedberg 
3737ac363cf9SSzymon Janc 	if (!ev->status && lmp_ext_feat_capable(hdev) &&
3738ac363cf9SSzymon Janc 	    lmp_ext_feat_capable(conn)) {
3739769be974SMarcel Holtmann 		struct hci_cp_read_remote_ext_features cp;
3740769be974SMarcel Holtmann 		cp.handle = ev->handle;
3741769be974SMarcel Holtmann 		cp.page = 0x01;
3742ccd556feSJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
3743769be974SMarcel Holtmann 			     sizeof(cp), &cp);
3744392599b9SJohan Hedberg 		goto unlock;
3745392599b9SJohan Hedberg 	}
3746392599b9SJohan Hedberg 
3747671267bfSJohan Hedberg 	if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
3748127178d2SJohan Hedberg 		struct hci_cp_remote_name_req cp;
3749127178d2SJohan Hedberg 		memset(&cp, 0, sizeof(cp));
3750127178d2SJohan Hedberg 		bacpy(&cp.bdaddr, &conn->dst);
3751127178d2SJohan Hedberg 		cp.pscan_rep_mode = 0x02;
3752127178d2SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
3753b644ba33SJohan Hedberg 	} else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
37541c6ed31bSYu Liu 		mgmt_device_connected(hdev, conn, NULL, 0);
3755392599b9SJohan Hedberg 
3756127178d2SJohan Hedberg 	if (!hci_outgoing_auth_needed(hdev, conn)) {
3757769be974SMarcel Holtmann 		conn->state = BT_CONNECTED;
3758539c496dSJohan Hedberg 		hci_connect_cfm(conn, ev->status);
375976a68ba0SDavid Herrmann 		hci_conn_drop(conn);
3760769be974SMarcel Holtmann 	}
3761769be974SMarcel Holtmann 
3762ccd556feSJohan Hedberg unlock:
3763a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
3764a9de9248SMarcel Holtmann }
3765a9de9248SMarcel Holtmann 
3766ecb71f25SKiran K static inline void handle_cmd_cnt_and_timer(struct hci_dev *hdev, u8 ncmd)
3767de75cd0dSManish Mandlik {
3768de75cd0dSManish Mandlik 	cancel_delayed_work(&hdev->cmd_timer);
3769de75cd0dSManish Mandlik 
3770deee93d1STetsuo Handa 	rcu_read_lock();
3771de75cd0dSManish Mandlik 	if (!test_bit(HCI_RESET, &hdev->flags)) {
3772de75cd0dSManish Mandlik 		if (ncmd) {
3773de75cd0dSManish Mandlik 			cancel_delayed_work(&hdev->ncmd_timer);
3774de75cd0dSManish Mandlik 			atomic_set(&hdev->cmd_cnt, 1);
3775de75cd0dSManish Mandlik 		} else {
3776877afadaSSchspa Shi 			if (!hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
3777deee93d1STetsuo Handa 				queue_delayed_work(hdev->workqueue, &hdev->ncmd_timer,
3778de75cd0dSManish Mandlik 						   HCI_NCMD_TIMEOUT);
3779de75cd0dSManish Mandlik 		}
3780de75cd0dSManish Mandlik 	}
3781deee93d1STetsuo Handa 	rcu_read_unlock();
3782de75cd0dSManish Mandlik }
3783de75cd0dSManish Mandlik 
378426afbd82SLuiz Augusto von Dentz static u8 hci_cc_le_read_buffer_size_v2(struct hci_dev *hdev, void *data,
378526afbd82SLuiz Augusto von Dentz 					struct sk_buff *skb)
378626afbd82SLuiz Augusto von Dentz {
378726afbd82SLuiz Augusto von Dentz 	struct hci_rp_le_read_buffer_size_v2 *rp = data;
378826afbd82SLuiz Augusto von Dentz 
378926afbd82SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
379026afbd82SLuiz Augusto von Dentz 
379126afbd82SLuiz Augusto von Dentz 	if (rp->status)
379226afbd82SLuiz Augusto von Dentz 		return rp->status;
379326afbd82SLuiz Augusto von Dentz 
379426afbd82SLuiz Augusto von Dentz 	hdev->le_mtu   = __le16_to_cpu(rp->acl_mtu);
379526afbd82SLuiz Augusto von Dentz 	hdev->le_pkts  = rp->acl_max_pkt;
379626afbd82SLuiz Augusto von Dentz 	hdev->iso_mtu  = __le16_to_cpu(rp->iso_mtu);
379726afbd82SLuiz Augusto von Dentz 	hdev->iso_pkts = rp->iso_max_pkt;
379826afbd82SLuiz Augusto von Dentz 
379926afbd82SLuiz Augusto von Dentz 	hdev->le_cnt  = hdev->le_pkts;
380026afbd82SLuiz Augusto von Dentz 	hdev->iso_cnt = hdev->iso_pkts;
380126afbd82SLuiz Augusto von Dentz 
380226afbd82SLuiz Augusto von Dentz 	BT_DBG("%s acl mtu %d:%d iso mtu %d:%d", hdev->name, hdev->acl_mtu,
380326afbd82SLuiz Augusto von Dentz 	       hdev->acl_pkts, hdev->iso_mtu, hdev->iso_pkts);
380426afbd82SLuiz Augusto von Dentz 
380526afbd82SLuiz Augusto von Dentz 	return rp->status;
380626afbd82SLuiz Augusto von Dentz }
380726afbd82SLuiz Augusto von Dentz 
380826afbd82SLuiz Augusto von Dentz static u8 hci_cc_le_set_cig_params(struct hci_dev *hdev, void *data,
380926afbd82SLuiz Augusto von Dentz 				   struct sk_buff *skb)
381026afbd82SLuiz Augusto von Dentz {
381126afbd82SLuiz Augusto von Dentz 	struct hci_rp_le_set_cig_params *rp = data;
381226afbd82SLuiz Augusto von Dentz 	struct hci_conn *conn;
381326afbd82SLuiz Augusto von Dentz 	int i = 0;
381426afbd82SLuiz Augusto von Dentz 
381526afbd82SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
381626afbd82SLuiz Augusto von Dentz 
381726afbd82SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
381826afbd82SLuiz Augusto von Dentz 
381926afbd82SLuiz Augusto von Dentz 	if (rp->status) {
382026afbd82SLuiz Augusto von Dentz 		while ((conn = hci_conn_hash_lookup_cig(hdev, rp->cig_id))) {
382126afbd82SLuiz Augusto von Dentz 			conn->state = BT_CLOSED;
382226afbd82SLuiz Augusto von Dentz 			hci_connect_cfm(conn, rp->status);
382326afbd82SLuiz Augusto von Dentz 			hci_conn_del(conn);
382426afbd82SLuiz Augusto von Dentz 		}
382526afbd82SLuiz Augusto von Dentz 		goto unlock;
382626afbd82SLuiz Augusto von Dentz 	}
382726afbd82SLuiz Augusto von Dentz 
382826afbd82SLuiz Augusto von Dentz 	rcu_read_lock();
382926afbd82SLuiz Augusto von Dentz 
383026afbd82SLuiz Augusto von Dentz 	list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) {
383126afbd82SLuiz Augusto von Dentz 		if (conn->type != ISO_LINK || conn->iso_qos.cig != rp->cig_id ||
383226afbd82SLuiz Augusto von Dentz 		    conn->state == BT_CONNECTED)
383326afbd82SLuiz Augusto von Dentz 			continue;
383426afbd82SLuiz Augusto von Dentz 
383526afbd82SLuiz Augusto von Dentz 		conn->handle = __le16_to_cpu(rp->handle[i++]);
383626afbd82SLuiz Augusto von Dentz 
383726afbd82SLuiz Augusto von Dentz 		bt_dev_dbg(hdev, "%p handle 0x%4.4x link %p", conn,
383826afbd82SLuiz Augusto von Dentz 			   conn->handle, conn->link);
383926afbd82SLuiz Augusto von Dentz 
384026afbd82SLuiz Augusto von Dentz 		/* Create CIS if LE is already connected */
384126afbd82SLuiz Augusto von Dentz 		if (conn->link && conn->link->state == BT_CONNECTED)
384226afbd82SLuiz Augusto von Dentz 			hci_le_create_cis(conn->link);
384326afbd82SLuiz Augusto von Dentz 
384426afbd82SLuiz Augusto von Dentz 		if (i == rp->num_handles)
384526afbd82SLuiz Augusto von Dentz 			break;
384626afbd82SLuiz Augusto von Dentz 	}
384726afbd82SLuiz Augusto von Dentz 
384826afbd82SLuiz Augusto von Dentz 	rcu_read_unlock();
384926afbd82SLuiz Augusto von Dentz 
385026afbd82SLuiz Augusto von Dentz unlock:
385126afbd82SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
385226afbd82SLuiz Augusto von Dentz 
385326afbd82SLuiz Augusto von Dentz 	return rp->status;
385426afbd82SLuiz Augusto von Dentz }
385526afbd82SLuiz Augusto von Dentz 
385626afbd82SLuiz Augusto von Dentz static u8 hci_cc_le_setup_iso_path(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_setup_iso_path *rp = data;
386026afbd82SLuiz Augusto von Dentz 	struct hci_cp_le_setup_iso_path *cp;
386126afbd82SLuiz Augusto von Dentz 	struct hci_conn *conn;
386226afbd82SLuiz Augusto von Dentz 
386326afbd82SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
386426afbd82SLuiz Augusto von Dentz 
386526afbd82SLuiz Augusto von Dentz 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SETUP_ISO_PATH);
386626afbd82SLuiz Augusto von Dentz 	if (!cp)
386726afbd82SLuiz Augusto von Dentz 		return rp->status;
386826afbd82SLuiz Augusto von Dentz 
386926afbd82SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
387026afbd82SLuiz Augusto von Dentz 
387126afbd82SLuiz Augusto von Dentz 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
387226afbd82SLuiz Augusto von Dentz 	if (!conn)
387326afbd82SLuiz Augusto von Dentz 		goto unlock;
387426afbd82SLuiz Augusto von Dentz 
387526afbd82SLuiz Augusto von Dentz 	if (rp->status) {
387626afbd82SLuiz Augusto von Dentz 		hci_connect_cfm(conn, rp->status);
387726afbd82SLuiz Augusto von Dentz 		hci_conn_del(conn);
387826afbd82SLuiz Augusto von Dentz 		goto unlock;
387926afbd82SLuiz Augusto von Dentz 	}
388026afbd82SLuiz Augusto von Dentz 
388126afbd82SLuiz Augusto von Dentz 	switch (cp->direction) {
388226afbd82SLuiz Augusto von Dentz 	/* Input (Host to Controller) */
388326afbd82SLuiz Augusto von Dentz 	case 0x00:
388426afbd82SLuiz Augusto von Dentz 		/* Only confirm connection if output only */
388526afbd82SLuiz Augusto von Dentz 		if (conn->iso_qos.out.sdu && !conn->iso_qos.in.sdu)
388626afbd82SLuiz Augusto von Dentz 			hci_connect_cfm(conn, rp->status);
388726afbd82SLuiz Augusto von Dentz 		break;
388826afbd82SLuiz Augusto von Dentz 	/* Output (Controller to Host) */
388926afbd82SLuiz Augusto von Dentz 	case 0x01:
389026afbd82SLuiz Augusto von Dentz 		/* Confirm connection since conn->iso_qos is always configured
389126afbd82SLuiz Augusto von Dentz 		 * last.
389226afbd82SLuiz Augusto von Dentz 		 */
389326afbd82SLuiz Augusto von Dentz 		hci_connect_cfm(conn, rp->status);
389426afbd82SLuiz Augusto von Dentz 		break;
389526afbd82SLuiz Augusto von Dentz 	}
389626afbd82SLuiz Augusto von Dentz 
389726afbd82SLuiz Augusto von Dentz unlock:
389826afbd82SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
389926afbd82SLuiz Augusto von Dentz 	return rp->status;
390026afbd82SLuiz Augusto von Dentz }
390126afbd82SLuiz Augusto von Dentz 
3902eca0ae4aSLuiz Augusto von Dentz static void hci_cs_le_create_big(struct hci_dev *hdev, u8 status)
3903eca0ae4aSLuiz Augusto von Dentz {
3904eca0ae4aSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
3905eca0ae4aSLuiz Augusto von Dentz }
3906eca0ae4aSLuiz Augusto von Dentz 
3907eca0ae4aSLuiz Augusto von Dentz static u8 hci_cc_set_per_adv_param(struct hci_dev *hdev, void *data,
3908eca0ae4aSLuiz Augusto von Dentz 				   struct sk_buff *skb)
3909eca0ae4aSLuiz Augusto von Dentz {
3910eca0ae4aSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
3911eca0ae4aSLuiz Augusto von Dentz 	struct hci_cp_le_set_per_adv_params *cp;
3912eca0ae4aSLuiz Augusto von Dentz 
3913eca0ae4aSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
3914eca0ae4aSLuiz Augusto von Dentz 
3915eca0ae4aSLuiz Augusto von Dentz 	if (rp->status)
3916eca0ae4aSLuiz Augusto von Dentz 		return rp->status;
3917eca0ae4aSLuiz Augusto von Dentz 
3918eca0ae4aSLuiz Augusto von Dentz 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_PER_ADV_PARAMS);
3919eca0ae4aSLuiz Augusto von Dentz 	if (!cp)
3920eca0ae4aSLuiz Augusto von Dentz 		return rp->status;
3921eca0ae4aSLuiz Augusto von Dentz 
3922eca0ae4aSLuiz Augusto von Dentz 	/* TODO: set the conn state */
3923eca0ae4aSLuiz Augusto von Dentz 	return rp->status;
3924eca0ae4aSLuiz Augusto von Dentz }
3925eca0ae4aSLuiz Augusto von Dentz 
3926eca0ae4aSLuiz Augusto von Dentz static u8 hci_cc_le_set_per_adv_enable(struct hci_dev *hdev, void *data,
3927eca0ae4aSLuiz Augusto von Dentz 				       struct sk_buff *skb)
3928eca0ae4aSLuiz Augusto von Dentz {
3929eca0ae4aSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
3930eca0ae4aSLuiz Augusto von Dentz 	__u8 *sent;
3931eca0ae4aSLuiz Augusto von Dentz 
3932eca0ae4aSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
3933eca0ae4aSLuiz Augusto von Dentz 
3934eca0ae4aSLuiz Augusto von Dentz 	if (rp->status)
3935eca0ae4aSLuiz Augusto von Dentz 		return rp->status;
3936eca0ae4aSLuiz Augusto von Dentz 
3937eca0ae4aSLuiz Augusto von Dentz 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_PER_ADV_ENABLE);
3938eca0ae4aSLuiz Augusto von Dentz 	if (!sent)
3939eca0ae4aSLuiz Augusto von Dentz 		return rp->status;
3940eca0ae4aSLuiz Augusto von Dentz 
3941eca0ae4aSLuiz Augusto von Dentz 	hci_dev_lock(hdev);
3942eca0ae4aSLuiz Augusto von Dentz 
3943eca0ae4aSLuiz Augusto von Dentz 	if (*sent)
3944eca0ae4aSLuiz Augusto von Dentz 		hci_dev_set_flag(hdev, HCI_LE_PER_ADV);
3945eca0ae4aSLuiz Augusto von Dentz 	else
3946eca0ae4aSLuiz Augusto von Dentz 		hci_dev_clear_flag(hdev, HCI_LE_PER_ADV);
3947eca0ae4aSLuiz Augusto von Dentz 
3948eca0ae4aSLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
3949eca0ae4aSLuiz Augusto von Dentz 
3950eca0ae4aSLuiz Augusto von Dentz 	return rp->status;
3951eca0ae4aSLuiz Augusto von Dentz }
3952eca0ae4aSLuiz Augusto von Dentz 
3953c8992cffSLuiz Augusto von Dentz #define HCI_CC_VL(_op, _func, _min, _max) \
3954c8992cffSLuiz Augusto von Dentz { \
3955c8992cffSLuiz Augusto von Dentz 	.op = _op, \
3956c8992cffSLuiz Augusto von Dentz 	.func = _func, \
3957c8992cffSLuiz Augusto von Dentz 	.min_len = _min, \
3958c8992cffSLuiz Augusto von Dentz 	.max_len = _max, \
3959c8992cffSLuiz Augusto von Dentz }
3960c8992cffSLuiz Augusto von Dentz 
3961c8992cffSLuiz Augusto von Dentz #define HCI_CC(_op, _func, _len) \
3962c8992cffSLuiz Augusto von Dentz 	HCI_CC_VL(_op, _func, _len, _len)
3963c8992cffSLuiz Augusto von Dentz 
3964c8992cffSLuiz Augusto von Dentz #define HCI_CC_STATUS(_op, _func) \
3965c8992cffSLuiz Augusto von Dentz 	HCI_CC(_op, _func, sizeof(struct hci_ev_status))
3966c8992cffSLuiz Augusto von Dentz 
3967c8992cffSLuiz Augusto von Dentz static const struct hci_cc {
3968c8992cffSLuiz Augusto von Dentz 	u16  op;
3969c8992cffSLuiz Augusto von Dentz 	u8 (*func)(struct hci_dev *hdev, void *data, struct sk_buff *skb);
3970c8992cffSLuiz Augusto von Dentz 	u16  min_len;
3971c8992cffSLuiz Augusto von Dentz 	u16  max_len;
3972c8992cffSLuiz Augusto von Dentz } hci_cc_table[] = {
3973c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_INQUIRY_CANCEL, hci_cc_inquiry_cancel),
3974c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_PERIODIC_INQ, hci_cc_periodic_inq),
3975c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_EXIT_PERIODIC_INQ, hci_cc_exit_periodic_inq),
3976c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_REMOTE_NAME_REQ_CANCEL,
3977c8992cffSLuiz Augusto von Dentz 		      hci_cc_remote_name_req_cancel),
3978c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_ROLE_DISCOVERY, hci_cc_role_discovery,
3979c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_role_discovery)),
3980c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LINK_POLICY, hci_cc_read_link_policy,
3981c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_link_policy)),
3982c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_WRITE_LINK_POLICY, hci_cc_write_link_policy,
3983c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_write_link_policy)),
3984c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_DEF_LINK_POLICY, hci_cc_read_def_link_policy,
3985c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_def_link_policy)),
3986c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_DEF_LINK_POLICY,
3987c8992cffSLuiz Augusto von Dentz 		      hci_cc_write_def_link_policy),
3988c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_RESET, hci_cc_reset),
3989c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_STORED_LINK_KEY, hci_cc_read_stored_link_key,
3990c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_stored_link_key)),
3991c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_DELETE_STORED_LINK_KEY, hci_cc_delete_stored_link_key,
3992c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_delete_stored_link_key)),
3993c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_LOCAL_NAME, hci_cc_write_local_name),
3994c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_NAME, hci_cc_read_local_name,
3995c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_name)),
3996c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_AUTH_ENABLE, hci_cc_write_auth_enable),
3997c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_ENCRYPT_MODE, hci_cc_write_encrypt_mode),
3998c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_SCAN_ENABLE, hci_cc_write_scan_enable),
3999c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_SET_EVENT_FLT, hci_cc_set_event_filter),
4000c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_CLASS_OF_DEV, hci_cc_read_class_of_dev,
4001c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_class_of_dev)),
4002c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_CLASS_OF_DEV, hci_cc_write_class_of_dev),
4003c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_VOICE_SETTING, hci_cc_read_voice_setting,
4004c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_voice_setting)),
4005c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_VOICE_SETTING, hci_cc_write_voice_setting),
4006c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_NUM_SUPPORTED_IAC, hci_cc_read_num_supported_iac,
4007c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_num_supported_iac)),
4008c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_SSP_MODE, hci_cc_write_ssp_mode),
4009c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_SC_SUPPORT, hci_cc_write_sc_support),
4010c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_AUTH_PAYLOAD_TO, hci_cc_read_auth_payload_timeout,
4011c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_auth_payload_to)),
4012c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_WRITE_AUTH_PAYLOAD_TO, hci_cc_write_auth_payload_timeout,
4013c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_write_auth_payload_to)),
4014c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_VERSION, hci_cc_read_local_version,
4015c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_version)),
4016c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_COMMANDS, hci_cc_read_local_commands,
4017c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_commands)),
4018c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_FEATURES, hci_cc_read_local_features,
4019c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_features)),
4020c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_EXT_FEATURES, hci_cc_read_local_ext_features,
4021c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_ext_features)),
4022c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_BUFFER_SIZE, hci_cc_read_buffer_size,
4023c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_buffer_size)),
4024c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_BD_ADDR, hci_cc_read_bd_addr,
4025c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_bd_addr)),
4026c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_PAIRING_OPTS, hci_cc_read_local_pairing_opts,
4027c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_pairing_opts)),
4028c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_PAGE_SCAN_ACTIVITY, hci_cc_read_page_scan_activity,
4029c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_page_scan_activity)),
4030c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_PAGE_SCAN_ACTIVITY,
4031c8992cffSLuiz Augusto von Dentz 		      hci_cc_write_page_scan_activity),
4032c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_PAGE_SCAN_TYPE, hci_cc_read_page_scan_type,
4033c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_page_scan_type)),
4034c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_PAGE_SCAN_TYPE, hci_cc_write_page_scan_type),
4035c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_DATA_BLOCK_SIZE, hci_cc_read_data_block_size,
4036c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_data_block_size)),
4037c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_FLOW_CONTROL_MODE, hci_cc_read_flow_control_mode,
4038c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_flow_control_mode)),
4039c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_AMP_INFO, hci_cc_read_local_amp_info,
4040c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_amp_info)),
4041c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_CLOCK, hci_cc_read_clock,
4042c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_clock)),
4043278d933eSBrian Gix 	HCI_CC(HCI_OP_READ_ENC_KEY_SIZE, hci_cc_read_enc_key_size,
4044278d933eSBrian Gix 	       sizeof(struct hci_rp_read_enc_key_size)),
4045c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_INQ_RSP_TX_POWER, hci_cc_read_inq_rsp_tx_power,
4046c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_inq_rsp_tx_power)),
4047c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_DEF_ERR_DATA_REPORTING,
4048c8992cffSLuiz Augusto von Dentz 	       hci_cc_read_def_err_data_reporting,
4049c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_def_err_data_reporting)),
4050c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_DEF_ERR_DATA_REPORTING,
4051c8992cffSLuiz Augusto von Dentz 		      hci_cc_write_def_err_data_reporting),
4052c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_PIN_CODE_REPLY, hci_cc_pin_code_reply,
4053c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_pin_code_reply)),
4054c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_PIN_CODE_NEG_REPLY, hci_cc_pin_code_neg_reply,
4055c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_pin_code_neg_reply)),
4056c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_OOB_DATA, hci_cc_read_local_oob_data,
4057c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_oob_data)),
4058c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_OOB_EXT_DATA, hci_cc_read_local_oob_ext_data,
4059c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_oob_ext_data)),
4060c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_BUFFER_SIZE, hci_cc_le_read_buffer_size,
4061c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_buffer_size)),
4062c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_LOCAL_FEATURES, hci_cc_le_read_local_features,
4063c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_local_features)),
4064c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_ADV_TX_POWER, hci_cc_le_read_adv_tx_power,
4065c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_adv_tx_power)),
4066c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_USER_CONFIRM_REPLY, hci_cc_user_confirm_reply,
4067c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_user_confirm_reply)),
4068c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_USER_CONFIRM_NEG_REPLY, hci_cc_user_confirm_neg_reply,
4069c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_user_confirm_reply)),
4070c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_USER_PASSKEY_REPLY, hci_cc_user_passkey_reply,
4071c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_user_confirm_reply)),
4072c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_USER_PASSKEY_NEG_REPLY, hci_cc_user_passkey_neg_reply,
4073c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_user_confirm_reply)),
4074c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_RANDOM_ADDR, hci_cc_le_set_random_addr),
4075c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_ADV_ENABLE, hci_cc_le_set_adv_enable),
4076c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_SCAN_PARAM, hci_cc_le_set_scan_param),
4077c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_SCAN_ENABLE, hci_cc_le_set_scan_enable),
4078c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_ACCEPT_LIST_SIZE,
4079c8992cffSLuiz Augusto von Dentz 	       hci_cc_le_read_accept_list_size,
4080c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_accept_list_size)),
4081c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_CLEAR_ACCEPT_LIST, hci_cc_le_clear_accept_list),
4082c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_ADD_TO_ACCEPT_LIST,
4083c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_add_to_accept_list),
4084c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_DEL_FROM_ACCEPT_LIST,
4085c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_del_from_accept_list),
4086c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_SUPPORTED_STATES, hci_cc_le_read_supported_states,
4087c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_supported_states)),
4088c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_DEF_DATA_LEN, hci_cc_le_read_def_data_len,
4089c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_def_data_len)),
4090c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_WRITE_DEF_DATA_LEN,
4091c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_write_def_data_len),
4092c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_ADD_TO_RESOLV_LIST,
4093c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_add_to_resolv_list),
4094c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_DEL_FROM_RESOLV_LIST,
4095c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_del_from_resolv_list),
4096c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_CLEAR_RESOLV_LIST,
4097c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_clear_resolv_list),
4098c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_RESOLV_LIST_SIZE, hci_cc_le_read_resolv_list_size,
4099c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_resolv_list_size)),
4100c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_ADDR_RESOLV_ENABLE,
4101c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_set_addr_resolution_enable),
4102c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_MAX_DATA_LEN, hci_cc_le_read_max_data_len,
4103c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_max_data_len)),
4104c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_LE_HOST_SUPPORTED,
4105c8992cffSLuiz Augusto von Dentz 		      hci_cc_write_le_host_supported),
4106c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_ADV_PARAM, hci_cc_set_adv_param),
4107c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_RSSI, hci_cc_read_rssi,
4108c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_rssi)),
4109c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_TX_POWER, hci_cc_read_tx_power,
4110c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_tx_power)),
4111c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_SSP_DEBUG_MODE, hci_cc_write_ssp_debug_mode),
4112c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_EXT_SCAN_PARAMS,
4113c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_set_ext_scan_param),
4114c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_EXT_SCAN_ENABLE,
4115c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_set_ext_scan_enable),
4116c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_DEFAULT_PHY, hci_cc_le_set_default_phy),
4117c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_NUM_SUPPORTED_ADV_SETS,
4118c8992cffSLuiz Augusto von Dentz 	       hci_cc_le_read_num_adv_sets,
4119c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_num_supported_adv_sets)),
4120c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_SET_EXT_ADV_PARAMS, hci_cc_set_ext_adv_param,
4121c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_set_ext_adv_params)),
4122c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_EXT_ADV_ENABLE,
4123c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_set_ext_adv_enable),
4124c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_ADV_SET_RAND_ADDR,
4125c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_set_adv_set_random_addr),
4126c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_REMOVE_ADV_SET, hci_cc_le_remove_adv_set),
4127c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_CLEAR_ADV_SETS, hci_cc_le_clear_adv_sets),
4128eca0ae4aSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_PER_ADV_PARAMS, hci_cc_set_per_adv_param),
4129eca0ae4aSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_PER_ADV_ENABLE,
4130eca0ae4aSLuiz Augusto von Dentz 		      hci_cc_le_set_per_adv_enable),
4131c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_TRANSMIT_POWER, hci_cc_le_read_transmit_power,
4132853b70b5SLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_transmit_power)),
413326afbd82SLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_PRIVACY_MODE, hci_cc_le_set_privacy_mode),
413426afbd82SLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_BUFFER_SIZE_V2, hci_cc_le_read_buffer_size_v2,
413526afbd82SLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_buffer_size_v2)),
413626afbd82SLuiz Augusto von Dentz 	HCI_CC_VL(HCI_OP_LE_SET_CIG_PARAMS, hci_cc_le_set_cig_params,
413726afbd82SLuiz Augusto von Dentz 		  sizeof(struct hci_rp_le_set_cig_params), HCI_MAX_EVENT_SIZE),
413826afbd82SLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_SETUP_ISO_PATH, hci_cc_le_setup_iso_path,
413926afbd82SLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_setup_iso_path)),
4140c8992cffSLuiz Augusto von Dentz };
4141c8992cffSLuiz Augusto von Dentz 
4142c8992cffSLuiz Augusto von Dentz static u8 hci_cc_func(struct hci_dev *hdev, const struct hci_cc *cc,
4143c8992cffSLuiz Augusto von Dentz 		      struct sk_buff *skb)
4144c8992cffSLuiz Augusto von Dentz {
4145c8992cffSLuiz Augusto von Dentz 	void *data;
4146c8992cffSLuiz Augusto von Dentz 
4147c8992cffSLuiz Augusto von Dentz 	if (skb->len < cc->min_len) {
4148c8992cffSLuiz Augusto von Dentz 		bt_dev_err(hdev, "unexpected cc 0x%4.4x length: %u < %u",
4149c8992cffSLuiz Augusto von Dentz 			   cc->op, skb->len, cc->min_len);
4150c8992cffSLuiz Augusto von Dentz 		return HCI_ERROR_UNSPECIFIED;
4151c8992cffSLuiz Augusto von Dentz 	}
4152c8992cffSLuiz Augusto von Dentz 
4153c8992cffSLuiz Augusto von Dentz 	/* Just warn if the length is over max_len size it still be possible to
4154c8992cffSLuiz Augusto von Dentz 	 * partially parse the cc so leave to callback to decide if that is
4155c8992cffSLuiz Augusto von Dentz 	 * acceptable.
4156c8992cffSLuiz Augusto von Dentz 	 */
4157c8992cffSLuiz Augusto von Dentz 	if (skb->len > cc->max_len)
4158c8992cffSLuiz Augusto von Dentz 		bt_dev_warn(hdev, "unexpected cc 0x%4.4x length: %u > %u",
4159c8992cffSLuiz Augusto von Dentz 			    cc->op, skb->len, cc->max_len);
4160c8992cffSLuiz Augusto von Dentz 
4161c8992cffSLuiz Augusto von Dentz 	data = hci_cc_skb_pull(hdev, skb, cc->op, cc->min_len);
4162c8992cffSLuiz Augusto von Dentz 	if (!data)
4163c8992cffSLuiz Augusto von Dentz 		return HCI_ERROR_UNSPECIFIED;
4164c8992cffSLuiz Augusto von Dentz 
4165c8992cffSLuiz Augusto von Dentz 	return cc->func(hdev, data, skb);
4166c8992cffSLuiz Augusto von Dentz }
4167c8992cffSLuiz Augusto von Dentz 
41683e54c589SLuiz Augusto von Dentz static void hci_cmd_complete_evt(struct hci_dev *hdev, void *data,
41693e54c589SLuiz Augusto von Dentz 				 struct sk_buff *skb, u16 *opcode, u8 *status,
4170e6214487SJohan Hedberg 				 hci_req_complete_t *req_complete,
4171e6214487SJohan Hedberg 				 hci_req_complete_skb_t *req_complete_skb)
4172a9de9248SMarcel Holtmann {
41733e54c589SLuiz Augusto von Dentz 	struct hci_ev_cmd_complete *ev = data;
4174c8992cffSLuiz Augusto von Dentz 	int i;
4175e6214487SJohan Hedberg 
4176e6214487SJohan Hedberg 	*opcode = __le16_to_cpu(ev->opcode);
4177a9de9248SMarcel Holtmann 
4178c8992cffSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "opcode 0x%4.4x", *opcode);
4179a9de9248SMarcel Holtmann 
4180c8992cffSLuiz Augusto von Dentz 	for (i = 0; i < ARRAY_SIZE(hci_cc_table); i++) {
4181c8992cffSLuiz Augusto von Dentz 		if (hci_cc_table[i].op == *opcode) {
4182c8992cffSLuiz Augusto von Dentz 			*status = hci_cc_func(hdev, &hci_cc_table[i], skb);
41834d93483bSAndre Guedes 			break;
4184c8992cffSLuiz Augusto von Dentz 		}
4185a9de9248SMarcel Holtmann 	}
4186a9de9248SMarcel Holtmann 
4187afcb3369SHans de Goede 	if (i == ARRAY_SIZE(hci_cc_table)) {
4188afcb3369SHans de Goede 		/* Unknown opcode, assume byte 0 contains the status, so
4189afcb3369SHans de Goede 		 * that e.g. __hci_cmd_sync() properly returns errors
4190afcb3369SHans de Goede 		 * for vendor specific commands send by HCI drivers.
4191afcb3369SHans de Goede 		 * If a vendor doesn't actually follow this convention we may
4192afcb3369SHans de Goede 		 * need to introduce a vendor CC table in order to properly set
4193afcb3369SHans de Goede 		 * the status.
4194afcb3369SHans de Goede 		 */
4195afcb3369SHans de Goede 		*status = skb->data[0];
4196afcb3369SHans de Goede 	}
4197afcb3369SHans de Goede 
4198ecb71f25SKiran K 	handle_cmd_cnt_and_timer(hdev, ev->ncmd);
4199600b2150SJohan Hedberg 
4200e6214487SJohan Hedberg 	hci_req_cmd_complete(hdev, *opcode, *status, req_complete,
4201e6214487SJohan Hedberg 			     req_complete_skb);
42029238f36aSJohan Hedberg 
4203f80c5dadSJoão Paulo Rechi Vita 	if (hci_dev_test_flag(hdev, HCI_CMD_PENDING)) {
4204f80c5dadSJoão Paulo Rechi Vita 		bt_dev_err(hdev,
4205f80c5dadSJoão Paulo Rechi Vita 			   "unexpected event for opcode 0x%4.4x", *opcode);
4206f80c5dadSJoão Paulo Rechi Vita 		return;
4207f80c5dadSJoão Paulo Rechi Vita 	}
4208f80c5dadSJoão Paulo Rechi Vita 
4209600b2150SJohan Hedberg 	if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q))
4210c347b765SGustavo F. Padovan 		queue_work(hdev->workqueue, &hdev->cmd_work);
4211a9de9248SMarcel Holtmann }
4212a9de9248SMarcel Holtmann 
421326afbd82SLuiz Augusto von Dentz static void hci_cs_le_create_cis(struct hci_dev *hdev, u8 status)
421426afbd82SLuiz Augusto von Dentz {
421526afbd82SLuiz Augusto von Dentz 	struct hci_cp_le_create_cis *cp;
421626afbd82SLuiz Augusto von Dentz 	int i;
421726afbd82SLuiz Augusto von Dentz 
421826afbd82SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
421926afbd82SLuiz Augusto von Dentz 
422026afbd82SLuiz Augusto von Dentz 	if (!status)
422126afbd82SLuiz Augusto von Dentz 		return;
422226afbd82SLuiz Augusto von Dentz 
422326afbd82SLuiz Augusto von Dentz 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CIS);
422426afbd82SLuiz Augusto von Dentz 	if (!cp)
422526afbd82SLuiz Augusto von Dentz 		return;
422626afbd82SLuiz Augusto von Dentz 
422726afbd82SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
422826afbd82SLuiz Augusto von Dentz 
422926afbd82SLuiz Augusto von Dentz 	/* Remove connection if command failed */
423026afbd82SLuiz Augusto von Dentz 	for (i = 0; cp->num_cis; cp->num_cis--, i++) {
423126afbd82SLuiz Augusto von Dentz 		struct hci_conn *conn;
423226afbd82SLuiz Augusto von Dentz 		u16 handle;
423326afbd82SLuiz Augusto von Dentz 
423426afbd82SLuiz Augusto von Dentz 		handle = __le16_to_cpu(cp->cis[i].cis_handle);
423526afbd82SLuiz Augusto von Dentz 
423626afbd82SLuiz Augusto von Dentz 		conn = hci_conn_hash_lookup_handle(hdev, handle);
423726afbd82SLuiz Augusto von Dentz 		if (conn) {
423826afbd82SLuiz Augusto von Dentz 			conn->state = BT_CLOSED;
423926afbd82SLuiz Augusto von Dentz 			hci_connect_cfm(conn, status);
424026afbd82SLuiz Augusto von Dentz 			hci_conn_del(conn);
424126afbd82SLuiz Augusto von Dentz 		}
424226afbd82SLuiz Augusto von Dentz 	}
424326afbd82SLuiz Augusto von Dentz 
424426afbd82SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
424526afbd82SLuiz Augusto von Dentz }
424626afbd82SLuiz Augusto von Dentz 
4247147306ccSLuiz Augusto von Dentz #define HCI_CS(_op, _func) \
4248147306ccSLuiz Augusto von Dentz { \
4249147306ccSLuiz Augusto von Dentz 	.op = _op, \
4250147306ccSLuiz Augusto von Dentz 	.func = _func, \
4251147306ccSLuiz Augusto von Dentz }
4252147306ccSLuiz Augusto von Dentz 
4253147306ccSLuiz Augusto von Dentz static const struct hci_cs {
4254147306ccSLuiz Augusto von Dentz 	u16  op;
4255147306ccSLuiz Augusto von Dentz 	void (*func)(struct hci_dev *hdev, __u8 status);
4256147306ccSLuiz Augusto von Dentz } hci_cs_table[] = {
4257147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_INQUIRY, hci_cs_inquiry),
4258147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_CREATE_CONN, hci_cs_create_conn),
4259147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_DISCONNECT, hci_cs_disconnect),
4260147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_ADD_SCO, hci_cs_add_sco),
4261147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_AUTH_REQUESTED, hci_cs_auth_requested),
4262147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_SET_CONN_ENCRYPT, hci_cs_set_conn_encrypt),
4263147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_REMOTE_NAME_REQ, hci_cs_remote_name_req),
4264147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_READ_REMOTE_FEATURES, hci_cs_read_remote_features),
4265147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_READ_REMOTE_EXT_FEATURES,
4266147306ccSLuiz Augusto von Dentz 	       hci_cs_read_remote_ext_features),
4267147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_SETUP_SYNC_CONN, hci_cs_setup_sync_conn),
4268147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_ENHANCED_SETUP_SYNC_CONN,
4269147306ccSLuiz Augusto von Dentz 	       hci_cs_enhanced_setup_sync_conn),
4270147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_SNIFF_MODE, hci_cs_sniff_mode),
4271147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_EXIT_SNIFF_MODE, hci_cs_exit_sniff_mode),
4272147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_SWITCH_ROLE, hci_cs_switch_role),
4273147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_LE_CREATE_CONN, hci_cs_le_create_conn),
4274147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_LE_READ_REMOTE_FEATURES, hci_cs_le_read_remote_features),
4275147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_LE_START_ENC, hci_cs_le_start_enc),
427626afbd82SLuiz Augusto von Dentz 	HCI_CS(HCI_OP_LE_EXT_CREATE_CONN, hci_cs_le_ext_create_conn),
427726afbd82SLuiz Augusto von Dentz 	HCI_CS(HCI_OP_LE_CREATE_CIS, hci_cs_le_create_cis),
4278eca0ae4aSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_LE_CREATE_BIG, hci_cs_le_create_big),
4279147306ccSLuiz Augusto von Dentz };
4280147306ccSLuiz Augusto von Dentz 
42813e54c589SLuiz Augusto von Dentz static void hci_cmd_status_evt(struct hci_dev *hdev, void *data,
42823e54c589SLuiz Augusto von Dentz 			       struct sk_buff *skb, u16 *opcode, u8 *status,
4283e6214487SJohan Hedberg 			       hci_req_complete_t *req_complete,
4284e6214487SJohan Hedberg 			       hci_req_complete_skb_t *req_complete_skb)
4285a9de9248SMarcel Holtmann {
42863e54c589SLuiz Augusto von Dentz 	struct hci_ev_cmd_status *ev = data;
4287147306ccSLuiz Augusto von Dentz 	int i;
4288a9de9248SMarcel Holtmann 
4289e6214487SJohan Hedberg 	*opcode = __le16_to_cpu(ev->opcode);
4290e6214487SJohan Hedberg 	*status = ev->status;
4291a9de9248SMarcel Holtmann 
4292147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "opcode 0x%4.4x", *opcode);
4293a9de9248SMarcel Holtmann 
4294147306ccSLuiz Augusto von Dentz 	for (i = 0; i < ARRAY_SIZE(hci_cs_table); i++) {
4295147306ccSLuiz Augusto von Dentz 		if (hci_cs_table[i].op == *opcode) {
4296147306ccSLuiz Augusto von Dentz 			hci_cs_table[i].func(hdev, ev->status);
4297a9de9248SMarcel Holtmann 			break;
4298147306ccSLuiz Augusto von Dentz 		}
4299a9de9248SMarcel Holtmann 	}
4300a9de9248SMarcel Holtmann 
4301ecb71f25SKiran K 	handle_cmd_cnt_and_timer(hdev, ev->ncmd);
4302600b2150SJohan Hedberg 
4303444c6dd5SJohan Hedberg 	/* Indicate request completion if the command failed. Also, if
4304444c6dd5SJohan Hedberg 	 * we're not waiting for a special event and we get a success
4305444c6dd5SJohan Hedberg 	 * command status we should try to flag the request as completed
4306444c6dd5SJohan Hedberg 	 * (since for this kind of commands there will not be a command
4307444c6dd5SJohan Hedberg 	 * complete event).
4308444c6dd5SJohan Hedberg 	 */
430985b56857SLuiz Augusto von Dentz 	if (ev->status || (hdev->sent_cmd && !hci_skb_event(hdev->sent_cmd))) {
4310e6214487SJohan Hedberg 		hci_req_cmd_complete(hdev, *opcode, ev->status, req_complete,
4311e6214487SJohan Hedberg 				     req_complete_skb);
4312f80c5dadSJoão Paulo Rechi Vita 		if (hci_dev_test_flag(hdev, HCI_CMD_PENDING)) {
431385b56857SLuiz Augusto von Dentz 			bt_dev_err(hdev, "unexpected event for opcode 0x%4.4x",
431485b56857SLuiz Augusto von Dentz 				   *opcode);
4315f80c5dadSJoão Paulo Rechi Vita 			return;
4316f80c5dadSJoão Paulo Rechi Vita 		}
431785b56857SLuiz Augusto von Dentz 	}
4318f80c5dadSJoão Paulo Rechi Vita 
4319600b2150SJohan Hedberg 	if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q))
4320c347b765SGustavo F. Padovan 		queue_work(hdev->workqueue, &hdev->cmd_work);
4321a9de9248SMarcel Holtmann }
4322a9de9248SMarcel Holtmann 
43233e54c589SLuiz Augusto von Dentz static void hci_hardware_error_evt(struct hci_dev *hdev, void *data,
43243e54c589SLuiz Augusto von Dentz 				   struct sk_buff *skb)
432524dfa343SMarcel Holtmann {
43263e54c589SLuiz Augusto von Dentz 	struct hci_ev_hardware_error *ev = data;
4327ae61a10dSLuiz Augusto von Dentz 
43283e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "code 0x%2.2x", ev->code);
432924dfa343SMarcel Holtmann 
4330c7741d16SMarcel Holtmann 	hdev->hw_error_code = ev->code;
4331c7741d16SMarcel Holtmann 
4332c7741d16SMarcel Holtmann 	queue_work(hdev->req_workqueue, &hdev->error_reset);
433324dfa343SMarcel Holtmann }
433424dfa343SMarcel Holtmann 
43353e54c589SLuiz Augusto von Dentz static void hci_role_change_evt(struct hci_dev *hdev, void *data,
43363e54c589SLuiz Augusto von Dentz 				struct sk_buff *skb)
4337a9de9248SMarcel Holtmann {
43383e54c589SLuiz Augusto von Dentz 	struct hci_ev_role_change *ev = data;
4339a9de9248SMarcel Holtmann 	struct hci_conn *conn;
4340a9de9248SMarcel Holtmann 
43413e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
4342a9de9248SMarcel Holtmann 
4343a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
4344a9de9248SMarcel Holtmann 
4345a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
4346a9de9248SMarcel Holtmann 	if (conn) {
434740bef302SJohan Hedberg 		if (!ev->status)
434840bef302SJohan Hedberg 			conn->role = ev->role;
4349a9de9248SMarcel Holtmann 
435051a8efd7SJohan Hedberg 		clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
4351a9de9248SMarcel Holtmann 
4352a9de9248SMarcel Holtmann 		hci_role_switch_cfm(conn, ev->status, ev->role);
4353a9de9248SMarcel Holtmann 	}
4354a9de9248SMarcel Holtmann 
4355a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
4356a9de9248SMarcel Holtmann }
4357a9de9248SMarcel Holtmann 
43583e54c589SLuiz Augusto von Dentz static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data,
43593e54c589SLuiz Augusto von Dentz 				  struct sk_buff *skb)
43601da177e4SLinus Torvalds {
43613e54c589SLuiz Augusto von Dentz 	struct hci_ev_num_comp_pkts *ev = data;
43621da177e4SLinus Torvalds 	int i;
43631da177e4SLinus Torvalds 
4364aadc3d2fSLuiz Augusto von Dentz 	if (!hci_ev_skb_pull(hdev, skb, HCI_EV_NUM_COMP_PKTS,
4365aadc3d2fSLuiz Augusto von Dentz 			     flex_array_size(ev, handles, ev->num)))
4366aadc3d2fSLuiz Augusto von Dentz 		return;
4367aadc3d2fSLuiz Augusto von Dentz 
436832ac5b9bSAndrei Emeltchenko 	if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
43692064ee33SMarcel Holtmann 		bt_dev_err(hdev, "wrong event for mode %d", hdev->flow_ctl_mode);
437032ac5b9bSAndrei Emeltchenko 		return;
437132ac5b9bSAndrei Emeltchenko 	}
437232ac5b9bSAndrei Emeltchenko 
43733e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "num %d", ev->num);
43741da177e4SLinus Torvalds 
4375aadc3d2fSLuiz Augusto von Dentz 	for (i = 0; i < ev->num; i++) {
4376613a1c0cSAndrei Emeltchenko 		struct hci_comp_pkts_info *info = &ev->handles[i];
43771da177e4SLinus Torvalds 		struct hci_conn *conn;
43781da177e4SLinus Torvalds 		__u16  handle, count;
43791da177e4SLinus Torvalds 
4380613a1c0cSAndrei Emeltchenko 		handle = __le16_to_cpu(info->handle);
4381613a1c0cSAndrei Emeltchenko 		count  = __le16_to_cpu(info->count);
43821da177e4SLinus Torvalds 
43831da177e4SLinus Torvalds 		conn = hci_conn_hash_lookup_handle(hdev, handle);
4384f4280918SAndrei Emeltchenko 		if (!conn)
4385f4280918SAndrei Emeltchenko 			continue;
4386f4280918SAndrei Emeltchenko 
43871da177e4SLinus Torvalds 		conn->sent -= count;
43881da177e4SLinus Torvalds 
4389f4280918SAndrei Emeltchenko 		switch (conn->type) {
4390f4280918SAndrei Emeltchenko 		case ACL_LINK:
439170f23020SAndrei Emeltchenko 			hdev->acl_cnt += count;
439270f23020SAndrei Emeltchenko 			if (hdev->acl_cnt > hdev->acl_pkts)
43931da177e4SLinus Torvalds 				hdev->acl_cnt = hdev->acl_pkts;
4394f4280918SAndrei Emeltchenko 			break;
4395f4280918SAndrei Emeltchenko 
4396f4280918SAndrei Emeltchenko 		case LE_LINK:
43976ed58ec5SVille Tervo 			if (hdev->le_pkts) {
43986ed58ec5SVille Tervo 				hdev->le_cnt += count;
43996ed58ec5SVille Tervo 				if (hdev->le_cnt > hdev->le_pkts)
44006ed58ec5SVille Tervo 					hdev->le_cnt = hdev->le_pkts;
44016ed58ec5SVille Tervo 			} else {
44026ed58ec5SVille Tervo 				hdev->acl_cnt += count;
44036ed58ec5SVille Tervo 				if (hdev->acl_cnt > hdev->acl_pkts)
44046ed58ec5SVille Tervo 					hdev->acl_cnt = hdev->acl_pkts;
44056ed58ec5SVille Tervo 			}
4406f4280918SAndrei Emeltchenko 			break;
4407f4280918SAndrei Emeltchenko 
4408f4280918SAndrei Emeltchenko 		case SCO_LINK:
440970f23020SAndrei Emeltchenko 			hdev->sco_cnt += count;
441070f23020SAndrei Emeltchenko 			if (hdev->sco_cnt > hdev->sco_pkts)
44115b7f9909SMarcel Holtmann 				hdev->sco_cnt = hdev->sco_pkts;
4412f4280918SAndrei Emeltchenko 			break;
4413f4280918SAndrei Emeltchenko 
441426afbd82SLuiz Augusto von Dentz 		case ISO_LINK:
441526afbd82SLuiz Augusto von Dentz 			if (hdev->iso_pkts) {
441626afbd82SLuiz Augusto von Dentz 				hdev->iso_cnt += count;
441726afbd82SLuiz Augusto von Dentz 				if (hdev->iso_cnt > hdev->iso_pkts)
441826afbd82SLuiz Augusto von Dentz 					hdev->iso_cnt = hdev->iso_pkts;
441926afbd82SLuiz Augusto von Dentz 			} else if (hdev->le_pkts) {
442026afbd82SLuiz Augusto von Dentz 				hdev->le_cnt += count;
442126afbd82SLuiz Augusto von Dentz 				if (hdev->le_cnt > hdev->le_pkts)
442226afbd82SLuiz Augusto von Dentz 					hdev->le_cnt = hdev->le_pkts;
442326afbd82SLuiz Augusto von Dentz 			} else {
442426afbd82SLuiz Augusto von Dentz 				hdev->acl_cnt += count;
442526afbd82SLuiz Augusto von Dentz 				if (hdev->acl_cnt > hdev->acl_pkts)
442626afbd82SLuiz Augusto von Dentz 					hdev->acl_cnt = hdev->acl_pkts;
442726afbd82SLuiz Augusto von Dentz 			}
442826afbd82SLuiz Augusto von Dentz 			break;
442926afbd82SLuiz Augusto von Dentz 
4430f4280918SAndrei Emeltchenko 		default:
44312064ee33SMarcel Holtmann 			bt_dev_err(hdev, "unknown type %d conn %p",
44322064ee33SMarcel Holtmann 				   conn->type, conn);
4433f4280918SAndrei Emeltchenko 			break;
44341da177e4SLinus Torvalds 		}
44351da177e4SLinus Torvalds 	}
4436a9de9248SMarcel Holtmann 
44373eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
44381da177e4SLinus Torvalds }
44391da177e4SLinus Torvalds 
444076ef7cf7SAndrei Emeltchenko static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
444176ef7cf7SAndrei Emeltchenko 						 __u16 handle)
444276ef7cf7SAndrei Emeltchenko {
444376ef7cf7SAndrei Emeltchenko 	struct hci_chan *chan;
444476ef7cf7SAndrei Emeltchenko 
444576ef7cf7SAndrei Emeltchenko 	switch (hdev->dev_type) {
4446ca8bee5dSMarcel Holtmann 	case HCI_PRIMARY:
444776ef7cf7SAndrei Emeltchenko 		return hci_conn_hash_lookup_handle(hdev, handle);
444876ef7cf7SAndrei Emeltchenko 	case HCI_AMP:
444976ef7cf7SAndrei Emeltchenko 		chan = hci_chan_lookup_handle(hdev, handle);
445076ef7cf7SAndrei Emeltchenko 		if (chan)
445176ef7cf7SAndrei Emeltchenko 			return chan->conn;
445276ef7cf7SAndrei Emeltchenko 		break;
445376ef7cf7SAndrei Emeltchenko 	default:
44542064ee33SMarcel Holtmann 		bt_dev_err(hdev, "unknown dev_type %d", hdev->dev_type);
445576ef7cf7SAndrei Emeltchenko 		break;
445676ef7cf7SAndrei Emeltchenko 	}
445776ef7cf7SAndrei Emeltchenko 
445876ef7cf7SAndrei Emeltchenko 	return NULL;
445976ef7cf7SAndrei Emeltchenko }
446076ef7cf7SAndrei Emeltchenko 
44613e54c589SLuiz Augusto von Dentz static void hci_num_comp_blocks_evt(struct hci_dev *hdev, void *data,
44623e54c589SLuiz Augusto von Dentz 				    struct sk_buff *skb)
446325e89e99SAndrei Emeltchenko {
44643e54c589SLuiz Augusto von Dentz 	struct hci_ev_num_comp_blocks *ev = data;
446525e89e99SAndrei Emeltchenko 	int i;
446625e89e99SAndrei Emeltchenko 
4467ae61a10dSLuiz Augusto von Dentz 	if (!hci_ev_skb_pull(hdev, skb, HCI_EV_NUM_COMP_BLOCKS,
4468ae61a10dSLuiz Augusto von Dentz 			     flex_array_size(ev, handles, ev->num_hndl)))
4469ae61a10dSLuiz Augusto von Dentz 		return;
4470ae61a10dSLuiz Augusto von Dentz 
447125e89e99SAndrei Emeltchenko 	if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
44723e54c589SLuiz Augusto von Dentz 		bt_dev_err(hdev, "wrong event for mode %d",
44733e54c589SLuiz Augusto von Dentz 			   hdev->flow_ctl_mode);
447425e89e99SAndrei Emeltchenko 		return;
447525e89e99SAndrei Emeltchenko 	}
447625e89e99SAndrei Emeltchenko 
44773e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "num_blocks %d num_hndl %d", ev->num_blocks,
447825e89e99SAndrei Emeltchenko 		   ev->num_hndl);
447925e89e99SAndrei Emeltchenko 
448025e89e99SAndrei Emeltchenko 	for (i = 0; i < ev->num_hndl; i++) {
448125e89e99SAndrei Emeltchenko 		struct hci_comp_blocks_info *info = &ev->handles[i];
448276ef7cf7SAndrei Emeltchenko 		struct hci_conn *conn = NULL;
448325e89e99SAndrei Emeltchenko 		__u16  handle, block_count;
448425e89e99SAndrei Emeltchenko 
448525e89e99SAndrei Emeltchenko 		handle = __le16_to_cpu(info->handle);
448625e89e99SAndrei Emeltchenko 		block_count = __le16_to_cpu(info->blocks);
448725e89e99SAndrei Emeltchenko 
448876ef7cf7SAndrei Emeltchenko 		conn = __hci_conn_lookup_handle(hdev, handle);
448925e89e99SAndrei Emeltchenko 		if (!conn)
449025e89e99SAndrei Emeltchenko 			continue;
449125e89e99SAndrei Emeltchenko 
449225e89e99SAndrei Emeltchenko 		conn->sent -= block_count;
449325e89e99SAndrei Emeltchenko 
449425e89e99SAndrei Emeltchenko 		switch (conn->type) {
449525e89e99SAndrei Emeltchenko 		case ACL_LINK:
4496bd1eb66bSAndrei Emeltchenko 		case AMP_LINK:
449725e89e99SAndrei Emeltchenko 			hdev->block_cnt += block_count;
449825e89e99SAndrei Emeltchenko 			if (hdev->block_cnt > hdev->num_blocks)
449925e89e99SAndrei Emeltchenko 				hdev->block_cnt = hdev->num_blocks;
450025e89e99SAndrei Emeltchenko 			break;
450125e89e99SAndrei Emeltchenko 
450225e89e99SAndrei Emeltchenko 		default:
45032064ee33SMarcel Holtmann 			bt_dev_err(hdev, "unknown type %d conn %p",
45042064ee33SMarcel Holtmann 				   conn->type, conn);
450525e89e99SAndrei Emeltchenko 			break;
450625e89e99SAndrei Emeltchenko 		}
450725e89e99SAndrei Emeltchenko 	}
450825e89e99SAndrei Emeltchenko 
450925e89e99SAndrei Emeltchenko 	queue_work(hdev->workqueue, &hdev->tx_work);
451025e89e99SAndrei Emeltchenko }
451125e89e99SAndrei Emeltchenko 
45123e54c589SLuiz Augusto von Dentz static void hci_mode_change_evt(struct hci_dev *hdev, void *data,
45133e54c589SLuiz Augusto von Dentz 				struct sk_buff *skb)
45141da177e4SLinus Torvalds {
45153e54c589SLuiz Augusto von Dentz 	struct hci_ev_mode_change *ev = data;
451604837f64SMarcel Holtmann 	struct hci_conn *conn;
45171da177e4SLinus Torvalds 
45183e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
45191da177e4SLinus Torvalds 
45201da177e4SLinus Torvalds 	hci_dev_lock(hdev);
45211da177e4SLinus Torvalds 
452204837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
452304837f64SMarcel Holtmann 	if (conn) {
452404837f64SMarcel Holtmann 		conn->mode = ev->mode;
452504837f64SMarcel Holtmann 
45268fc9ced3SGustavo Padovan 		if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
45278fc9ced3SGustavo Padovan 					&conn->flags)) {
452804837f64SMarcel Holtmann 			if (conn->mode == HCI_CM_ACTIVE)
452958a681efSJohan Hedberg 				set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
453004837f64SMarcel Holtmann 			else
453158a681efSJohan Hedberg 				clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
453204837f64SMarcel Holtmann 		}
4533e73439d8SMarcel Holtmann 
453451a8efd7SJohan Hedberg 		if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
4535e73439d8SMarcel Holtmann 			hci_sco_setup(conn, ev->status);
453604837f64SMarcel Holtmann 	}
453704837f64SMarcel Holtmann 
453804837f64SMarcel Holtmann 	hci_dev_unlock(hdev);
453904837f64SMarcel Holtmann }
454004837f64SMarcel Holtmann 
45413e54c589SLuiz Augusto von Dentz static void hci_pin_code_request_evt(struct hci_dev *hdev, void *data,
45423e54c589SLuiz Augusto von Dentz 				     struct sk_buff *skb)
45431da177e4SLinus Torvalds {
45443e54c589SLuiz Augusto von Dentz 	struct hci_ev_pin_code_req *ev = data;
4545052b30b0SMarcel Holtmann 	struct hci_conn *conn;
4546052b30b0SMarcel Holtmann 
45473e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
4548052b30b0SMarcel Holtmann 
4549052b30b0SMarcel Holtmann 	hci_dev_lock(hdev);
4550052b30b0SMarcel Holtmann 
4551052b30b0SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
4552b6f98044SWaldemar Rymarkiewicz 	if (!conn)
4553b6f98044SWaldemar Rymarkiewicz 		goto unlock;
4554b6f98044SWaldemar Rymarkiewicz 
4555b6f98044SWaldemar Rymarkiewicz 	if (conn->state == BT_CONNECTED) {
4556052b30b0SMarcel Holtmann 		hci_conn_hold(conn);
4557052b30b0SMarcel Holtmann 		conn->disc_timeout = HCI_PAIRING_TIMEOUT;
455876a68ba0SDavid Herrmann 		hci_conn_drop(conn);
4559052b30b0SMarcel Holtmann 	}
4560052b30b0SMarcel Holtmann 
4561d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BONDABLE) &&
45622f407f0aSJohan Hedberg 	    !test_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags)) {
456303b555e1SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
456403b555e1SJohan Hedberg 			     sizeof(ev->bdaddr), &ev->bdaddr);
4565d7a5a11dSMarcel Holtmann 	} else if (hci_dev_test_flag(hdev, HCI_MGMT)) {
4566a770bb5aSWaldemar Rymarkiewicz 		u8 secure;
4567a770bb5aSWaldemar Rymarkiewicz 
4568a770bb5aSWaldemar Rymarkiewicz 		if (conn->pending_sec_level == BT_SECURITY_HIGH)
4569a770bb5aSWaldemar Rymarkiewicz 			secure = 1;
4570a770bb5aSWaldemar Rymarkiewicz 		else
4571a770bb5aSWaldemar Rymarkiewicz 			secure = 0;
4572a770bb5aSWaldemar Rymarkiewicz 
4573744cf19eSJohan Hedberg 		mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
4574a770bb5aSWaldemar Rymarkiewicz 	}
4575980e1a53SJohan Hedberg 
4576b6f98044SWaldemar Rymarkiewicz unlock:
4577052b30b0SMarcel Holtmann 	hci_dev_unlock(hdev);
45781da177e4SLinus Torvalds }
45791da177e4SLinus Torvalds 
4580cb6f3f7aSJohan Hedberg static void conn_set_key(struct hci_conn *conn, u8 key_type, u8 pin_len)
4581cb6f3f7aSJohan Hedberg {
4582cb6f3f7aSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION)
4583cb6f3f7aSJohan Hedberg 		return;
4584cb6f3f7aSJohan Hedberg 
4585cb6f3f7aSJohan Hedberg 	conn->pin_length = pin_len;
4586cb6f3f7aSJohan Hedberg 	conn->key_type = key_type;
4587cb6f3f7aSJohan Hedberg 
4588cb6f3f7aSJohan Hedberg 	switch (key_type) {
4589cb6f3f7aSJohan Hedberg 	case HCI_LK_LOCAL_UNIT:
4590cb6f3f7aSJohan Hedberg 	case HCI_LK_REMOTE_UNIT:
4591cb6f3f7aSJohan Hedberg 	case HCI_LK_DEBUG_COMBINATION:
4592cb6f3f7aSJohan Hedberg 		return;
4593cb6f3f7aSJohan Hedberg 	case HCI_LK_COMBINATION:
4594cb6f3f7aSJohan Hedberg 		if (pin_len == 16)
4595cb6f3f7aSJohan Hedberg 			conn->pending_sec_level = BT_SECURITY_HIGH;
4596cb6f3f7aSJohan Hedberg 		else
4597cb6f3f7aSJohan Hedberg 			conn->pending_sec_level = BT_SECURITY_MEDIUM;
4598cb6f3f7aSJohan Hedberg 		break;
4599cb6f3f7aSJohan Hedberg 	case HCI_LK_UNAUTH_COMBINATION_P192:
4600cb6f3f7aSJohan Hedberg 	case HCI_LK_UNAUTH_COMBINATION_P256:
4601cb6f3f7aSJohan Hedberg 		conn->pending_sec_level = BT_SECURITY_MEDIUM;
4602cb6f3f7aSJohan Hedberg 		break;
4603cb6f3f7aSJohan Hedberg 	case HCI_LK_AUTH_COMBINATION_P192:
4604cb6f3f7aSJohan Hedberg 		conn->pending_sec_level = BT_SECURITY_HIGH;
4605cb6f3f7aSJohan Hedberg 		break;
4606cb6f3f7aSJohan Hedberg 	case HCI_LK_AUTH_COMBINATION_P256:
4607cb6f3f7aSJohan Hedberg 		conn->pending_sec_level = BT_SECURITY_FIPS;
4608cb6f3f7aSJohan Hedberg 		break;
4609cb6f3f7aSJohan Hedberg 	}
4610cb6f3f7aSJohan Hedberg }
4611cb6f3f7aSJohan Hedberg 
46123e54c589SLuiz Augusto von Dentz static void hci_link_key_request_evt(struct hci_dev *hdev, void *data,
46133e54c589SLuiz Augusto von Dentz 				     struct sk_buff *skb)
46141da177e4SLinus Torvalds {
46153e54c589SLuiz Augusto von Dentz 	struct hci_ev_link_key_req *ev = data;
461655ed8ca1SJohan Hedberg 	struct hci_cp_link_key_reply cp;
461755ed8ca1SJohan Hedberg 	struct hci_conn *conn;
461855ed8ca1SJohan Hedberg 	struct link_key *key;
461955ed8ca1SJohan Hedberg 
46203e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
462155ed8ca1SJohan Hedberg 
4622d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
462355ed8ca1SJohan Hedberg 		return;
462455ed8ca1SJohan Hedberg 
462555ed8ca1SJohan Hedberg 	hci_dev_lock(hdev);
462655ed8ca1SJohan Hedberg 
462755ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, &ev->bdaddr);
462855ed8ca1SJohan Hedberg 	if (!key) {
46293e54c589SLuiz Augusto von Dentz 		bt_dev_dbg(hdev, "link key not found for %pMR", &ev->bdaddr);
463055ed8ca1SJohan Hedberg 		goto not_found;
463155ed8ca1SJohan Hedberg 	}
463255ed8ca1SJohan Hedberg 
46333e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "found key type %u for %pMR", key->type, &ev->bdaddr);
463455ed8ca1SJohan Hedberg 
463555ed8ca1SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
463660b83f57SWaldemar Rymarkiewicz 	if (conn) {
4637fe8bc5acSJohan Hedberg 		clear_bit(HCI_CONN_NEW_LINK_KEY, &conn->flags);
4638fe8bc5acSJohan Hedberg 
463966138ce8SMarcel Holtmann 		if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 ||
464066138ce8SMarcel Holtmann 		     key->type == HCI_LK_UNAUTH_COMBINATION_P256) &&
4641807deac2SGustavo Padovan 		    conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
46423e54c589SLuiz Augusto von Dentz 			bt_dev_dbg(hdev, "ignoring unauthenticated key");
464355ed8ca1SJohan Hedberg 			goto not_found;
464455ed8ca1SJohan Hedberg 		}
464555ed8ca1SJohan Hedberg 
464660b83f57SWaldemar Rymarkiewicz 		if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
4647f3fb0b58SJohan Hedberg 		    (conn->pending_sec_level == BT_SECURITY_HIGH ||
4648f3fb0b58SJohan Hedberg 		     conn->pending_sec_level == BT_SECURITY_FIPS)) {
46493e54c589SLuiz Augusto von Dentz 			bt_dev_dbg(hdev, "ignoring key unauthenticated for high security");
465060b83f57SWaldemar Rymarkiewicz 			goto not_found;
465160b83f57SWaldemar Rymarkiewicz 		}
465260b83f57SWaldemar Rymarkiewicz 
4653cb6f3f7aSJohan Hedberg 		conn_set_key(conn, key->type, key->pin_len);
465460b83f57SWaldemar Rymarkiewicz 	}
465560b83f57SWaldemar Rymarkiewicz 
465655ed8ca1SJohan Hedberg 	bacpy(&cp.bdaddr, &ev->bdaddr);
46579b3b4460SAndrei Emeltchenko 	memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
465855ed8ca1SJohan Hedberg 
465955ed8ca1SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
466055ed8ca1SJohan Hedberg 
466155ed8ca1SJohan Hedberg 	hci_dev_unlock(hdev);
466255ed8ca1SJohan Hedberg 
466355ed8ca1SJohan Hedberg 	return;
466455ed8ca1SJohan Hedberg 
466555ed8ca1SJohan Hedberg not_found:
466655ed8ca1SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
466755ed8ca1SJohan Hedberg 	hci_dev_unlock(hdev);
46681da177e4SLinus Torvalds }
46691da177e4SLinus Torvalds 
46703e54c589SLuiz Augusto von Dentz static void hci_link_key_notify_evt(struct hci_dev *hdev, void *data,
46713e54c589SLuiz Augusto von Dentz 				    struct sk_buff *skb)
46721da177e4SLinus Torvalds {
46733e54c589SLuiz Augusto von Dentz 	struct hci_ev_link_key_notify *ev = data;
4674052b30b0SMarcel Holtmann 	struct hci_conn *conn;
46757652ff6aSJohan Hedberg 	struct link_key *key;
46767652ff6aSJohan Hedberg 	bool persistent;
467755ed8ca1SJohan Hedberg 	u8 pin_len = 0;
4678052b30b0SMarcel Holtmann 
46793e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
4680052b30b0SMarcel Holtmann 
4681052b30b0SMarcel Holtmann 	hci_dev_lock(hdev);
4682052b30b0SMarcel Holtmann 
4683052b30b0SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
468482c13d42SJohan Hedberg 	if (!conn)
468582c13d42SJohan Hedberg 		goto unlock;
468682c13d42SJohan Hedberg 
4687052b30b0SMarcel Holtmann 	hci_conn_hold(conn);
4688052b30b0SMarcel Holtmann 	conn->disc_timeout = HCI_DISCONN_TIMEOUT;
468976a68ba0SDavid Herrmann 	hci_conn_drop(conn);
469082c13d42SJohan Hedberg 
4691fe8bc5acSJohan Hedberg 	set_bit(HCI_CONN_NEW_LINK_KEY, &conn->flags);
4692cb6f3f7aSJohan Hedberg 	conn_set_key(conn, ev->key_type, conn->pin_length);
4693052b30b0SMarcel Holtmann 
4694d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
46957652ff6aSJohan Hedberg 		goto unlock;
469655ed8ca1SJohan Hedberg 
46977652ff6aSJohan Hedberg 	key = hci_add_link_key(hdev, conn, &ev->bdaddr, ev->link_key,
46987652ff6aSJohan Hedberg 			        ev->key_type, pin_len, &persistent);
46997652ff6aSJohan Hedberg 	if (!key)
47007652ff6aSJohan Hedberg 		goto unlock;
47017652ff6aSJohan Hedberg 
4702cb6f3f7aSJohan Hedberg 	/* Update connection information since adding the key will have
4703cb6f3f7aSJohan Hedberg 	 * fixed up the type in the case of changed combination keys.
4704cb6f3f7aSJohan Hedberg 	 */
4705cb6f3f7aSJohan Hedberg 	if (ev->key_type == HCI_LK_CHANGED_COMBINATION)
4706cb6f3f7aSJohan Hedberg 		conn_set_key(conn, key->type, key->pin_len);
4707cb6f3f7aSJohan Hedberg 
47087652ff6aSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
47097652ff6aSJohan Hedberg 
47106d5650c4SJohan Hedberg 	/* Keep debug keys around only if the HCI_KEEP_DEBUG_KEYS flag
47116d5650c4SJohan Hedberg 	 * is set. If it's not set simply remove the key from the kernel
47126d5650c4SJohan Hedberg 	 * list (we've still notified user space about it but with
47136d5650c4SJohan Hedberg 	 * store_hint being 0).
47146d5650c4SJohan Hedberg 	 */
47156d5650c4SJohan Hedberg 	if (key->type == HCI_LK_DEBUG_COMBINATION &&
4716d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_KEEP_DEBUG_KEYS)) {
47170378b597SJohan Hedberg 		list_del_rcu(&key->list);
47180378b597SJohan Hedberg 		kfree_rcu(key, rcu);
471982c13d42SJohan Hedberg 		goto unlock;
472082c13d42SJohan Hedberg 	}
472182c13d42SJohan Hedberg 
4722af6a9c32SJohan Hedberg 	if (persistent)
4723af6a9c32SJohan Hedberg 		clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags);
4724af6a9c32SJohan Hedberg 	else
4725af6a9c32SJohan Hedberg 		set_bit(HCI_CONN_FLUSH_KEY, &conn->flags);
47267652ff6aSJohan Hedberg 
47277652ff6aSJohan Hedberg unlock:
4728052b30b0SMarcel Holtmann 	hci_dev_unlock(hdev);
47291da177e4SLinus Torvalds }
47301da177e4SLinus Torvalds 
47313e54c589SLuiz Augusto von Dentz static void hci_clock_offset_evt(struct hci_dev *hdev, void *data,
47323e54c589SLuiz Augusto von Dentz 				 struct sk_buff *skb)
473304837f64SMarcel Holtmann {
47343e54c589SLuiz Augusto von Dentz 	struct hci_ev_clock_offset *ev = data;
473504837f64SMarcel Holtmann 	struct hci_conn *conn;
473604837f64SMarcel Holtmann 
47373e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
473804837f64SMarcel Holtmann 
473904837f64SMarcel Holtmann 	hci_dev_lock(hdev);
474004837f64SMarcel Holtmann 
474104837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
47421da177e4SLinus Torvalds 	if (conn && !ev->status) {
47431da177e4SLinus Torvalds 		struct inquiry_entry *ie;
47441da177e4SLinus Torvalds 
4745cc11b9c1SAndrei Emeltchenko 		ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
4746cc11b9c1SAndrei Emeltchenko 		if (ie) {
47471da177e4SLinus Torvalds 			ie->data.clock_offset = ev->clock_offset;
47481da177e4SLinus Torvalds 			ie->timestamp = jiffies;
47491da177e4SLinus Torvalds 		}
47501da177e4SLinus Torvalds 	}
47511da177e4SLinus Torvalds 
47521da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
47531da177e4SLinus Torvalds }
47541da177e4SLinus Torvalds 
47553e54c589SLuiz Augusto von Dentz static void hci_pkt_type_change_evt(struct hci_dev *hdev, void *data,
47563e54c589SLuiz Augusto von Dentz 				    struct sk_buff *skb)
4757a8746417SMarcel Holtmann {
47583e54c589SLuiz Augusto von Dentz 	struct hci_ev_pkt_type_change *ev = data;
4759a8746417SMarcel Holtmann 	struct hci_conn *conn;
4760a8746417SMarcel Holtmann 
47613e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
4762a8746417SMarcel Holtmann 
4763a8746417SMarcel Holtmann 	hci_dev_lock(hdev);
4764a8746417SMarcel Holtmann 
4765a8746417SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
4766a8746417SMarcel Holtmann 	if (conn && !ev->status)
4767a8746417SMarcel Holtmann 		conn->pkt_type = __le16_to_cpu(ev->pkt_type);
4768a8746417SMarcel Holtmann 
4769a8746417SMarcel Holtmann 	hci_dev_unlock(hdev);
4770a8746417SMarcel Holtmann }
4771a8746417SMarcel Holtmann 
47723e54c589SLuiz Augusto von Dentz static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, void *data,
47733e54c589SLuiz Augusto von Dentz 				   struct sk_buff *skb)
477485a1e930SMarcel Holtmann {
47753e54c589SLuiz Augusto von Dentz 	struct hci_ev_pscan_rep_mode *ev = data;
477685a1e930SMarcel Holtmann 	struct inquiry_entry *ie;
477785a1e930SMarcel Holtmann 
47783e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
477985a1e930SMarcel Holtmann 
478085a1e930SMarcel Holtmann 	hci_dev_lock(hdev);
478185a1e930SMarcel Holtmann 
4782cc11b9c1SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
4783cc11b9c1SAndrei Emeltchenko 	if (ie) {
478485a1e930SMarcel Holtmann 		ie->data.pscan_rep_mode = ev->pscan_rep_mode;
478585a1e930SMarcel Holtmann 		ie->timestamp = jiffies;
478685a1e930SMarcel Holtmann 	}
478785a1e930SMarcel Holtmann 
478885a1e930SMarcel Holtmann 	hci_dev_unlock(hdev);
478985a1e930SMarcel Holtmann }
479085a1e930SMarcel Holtmann 
47913e54c589SLuiz Augusto von Dentz static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, void *edata,
4792807deac2SGustavo Padovan 					     struct sk_buff *skb)
4793a9de9248SMarcel Holtmann {
479472279d17SLuiz Augusto von Dentz 	struct hci_ev_inquiry_result_rssi *ev = edata;
4795a9de9248SMarcel Holtmann 	struct inquiry_data data;
47968d08d324SLuiz Augusto von Dentz 	int i;
4797a9de9248SMarcel Holtmann 
479872279d17SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "num_rsp %d", ev->num);
47998d08d324SLuiz Augusto von Dentz 
480072279d17SLuiz Augusto von Dentz 	if (!ev->num)
4801a9de9248SMarcel Holtmann 		return;
4802a9de9248SMarcel Holtmann 
4803d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ))
48041519cc17SAndre Guedes 		return;
48051519cc17SAndre Guedes 
4806a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
4807a9de9248SMarcel Holtmann 
480872279d17SLuiz Augusto von Dentz 	if (skb->len == array_size(ev->num,
480972279d17SLuiz Augusto von Dentz 				   sizeof(struct inquiry_info_rssi_pscan))) {
48108d08d324SLuiz Augusto von Dentz 		struct inquiry_info_rssi_pscan *info;
4811a9de9248SMarcel Holtmann 
481272279d17SLuiz Augusto von Dentz 		for (i = 0; i < ev->num; i++) {
4813af58925cSMarcel Holtmann 			u32 flags;
4814af58925cSMarcel Holtmann 
4815fee64503SLuiz Augusto von Dentz 			info = hci_ev_skb_pull(hdev, skb,
4816fee64503SLuiz Augusto von Dentz 					       HCI_EV_INQUIRY_RESULT_WITH_RSSI,
4817fee64503SLuiz Augusto von Dentz 					       sizeof(*info));
4818fee64503SLuiz Augusto von Dentz 			if (!info) {
4819fee64503SLuiz Augusto von Dentz 				bt_dev_err(hdev, "Malformed HCI Event: 0x%2.2x",
4820fee64503SLuiz Augusto von Dentz 					   HCI_EV_INQUIRY_RESULT_WITH_RSSI);
4821c07ba878SDan Carpenter 				goto unlock;
4822fee64503SLuiz Augusto von Dentz 			}
4823fee64503SLuiz Augusto von Dentz 
4824a9de9248SMarcel Holtmann 			bacpy(&data.bdaddr, &info->bdaddr);
4825a9de9248SMarcel Holtmann 			data.pscan_rep_mode	= info->pscan_rep_mode;
4826a9de9248SMarcel Holtmann 			data.pscan_period_mode	= info->pscan_period_mode;
4827a9de9248SMarcel Holtmann 			data.pscan_mode		= info->pscan_mode;
4828a9de9248SMarcel Holtmann 			memcpy(data.dev_class, info->dev_class, 3);
4829a9de9248SMarcel Holtmann 			data.clock_offset	= info->clock_offset;
4830a9de9248SMarcel Holtmann 			data.rssi		= info->rssi;
483141a96212SMarcel Holtmann 			data.ssp_mode		= 0x00;
48323175405bSJohan Hedberg 
4833af58925cSMarcel Holtmann 			flags = hci_inquiry_cache_update(hdev, &data, false);
4834af58925cSMarcel Holtmann 
483548264f06SJohan Hedberg 			mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
4836e17acd40SJohan Hedberg 					  info->dev_class, info->rssi,
4837b338d917SBrian Gix 					  flags, NULL, 0, NULL, 0, 0);
4838a9de9248SMarcel Holtmann 		}
483972279d17SLuiz Augusto von Dentz 	} else if (skb->len == array_size(ev->num,
484072279d17SLuiz Augusto von Dentz 					  sizeof(struct inquiry_info_rssi))) {
48418d08d324SLuiz Augusto von Dentz 		struct inquiry_info_rssi *info;
4842a9de9248SMarcel Holtmann 
484372279d17SLuiz Augusto von Dentz 		for (i = 0; i < ev->num; i++) {
4844af58925cSMarcel Holtmann 			u32 flags;
4845af58925cSMarcel Holtmann 
4846fee64503SLuiz Augusto von Dentz 			info = hci_ev_skb_pull(hdev, skb,
4847fee64503SLuiz Augusto von Dentz 					       HCI_EV_INQUIRY_RESULT_WITH_RSSI,
4848fee64503SLuiz Augusto von Dentz 					       sizeof(*info));
4849fee64503SLuiz Augusto von Dentz 			if (!info) {
4850fee64503SLuiz Augusto von Dentz 				bt_dev_err(hdev, "Malformed HCI Event: 0x%2.2x",
4851fee64503SLuiz Augusto von Dentz 					   HCI_EV_INQUIRY_RESULT_WITH_RSSI);
4852c07ba878SDan Carpenter 				goto unlock;
4853fee64503SLuiz Augusto von Dentz 			}
4854fee64503SLuiz Augusto von Dentz 
4855a9de9248SMarcel Holtmann 			bacpy(&data.bdaddr, &info->bdaddr);
4856a9de9248SMarcel Holtmann 			data.pscan_rep_mode	= info->pscan_rep_mode;
4857a9de9248SMarcel Holtmann 			data.pscan_period_mode	= info->pscan_period_mode;
4858a9de9248SMarcel Holtmann 			data.pscan_mode		= 0x00;
4859a9de9248SMarcel Holtmann 			memcpy(data.dev_class, info->dev_class, 3);
4860a9de9248SMarcel Holtmann 			data.clock_offset	= info->clock_offset;
4861a9de9248SMarcel Holtmann 			data.rssi		= info->rssi;
486241a96212SMarcel Holtmann 			data.ssp_mode		= 0x00;
4863af58925cSMarcel Holtmann 
4864af58925cSMarcel Holtmann 			flags = hci_inquiry_cache_update(hdev, &data, false);
4865af58925cSMarcel Holtmann 
486648264f06SJohan Hedberg 			mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
4867e17acd40SJohan Hedberg 					  info->dev_class, info->rssi,
4868b338d917SBrian Gix 					  flags, NULL, 0, NULL, 0, 0);
4869a9de9248SMarcel Holtmann 		}
48708d08d324SLuiz Augusto von Dentz 	} else {
48718d08d324SLuiz Augusto von Dentz 		bt_dev_err(hdev, "Malformed HCI Event: 0x%2.2x",
48728d08d324SLuiz Augusto von Dentz 			   HCI_EV_INQUIRY_RESULT_WITH_RSSI);
4873a9de9248SMarcel Holtmann 	}
4874c07ba878SDan Carpenter unlock:
4875a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
4876a9de9248SMarcel Holtmann }
4877a9de9248SMarcel Holtmann 
48783e54c589SLuiz Augusto von Dentz static void hci_remote_ext_features_evt(struct hci_dev *hdev, void *data,
4879807deac2SGustavo Padovan 					struct sk_buff *skb)
4880a9de9248SMarcel Holtmann {
48813e54c589SLuiz Augusto von Dentz 	struct hci_ev_remote_ext_features *ev = data;
488241a96212SMarcel Holtmann 	struct hci_conn *conn;
488341a96212SMarcel Holtmann 
48843e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
488541a96212SMarcel Holtmann 
488641a96212SMarcel Holtmann 	hci_dev_lock(hdev);
488741a96212SMarcel Holtmann 
488841a96212SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
4889ccd556feSJohan Hedberg 	if (!conn)
4890ccd556feSJohan Hedberg 		goto unlock;
4891ccd556feSJohan Hedberg 
4892cad718edSJohan Hedberg 	if (ev->page < HCI_MAX_PAGES)
4893cad718edSJohan Hedberg 		memcpy(conn->features[ev->page], ev->features, 8);
4894cad718edSJohan Hedberg 
4895769be974SMarcel Holtmann 	if (!ev->status && ev->page == 0x01) {
489641a96212SMarcel Holtmann 		struct inquiry_entry *ie;
489741a96212SMarcel Holtmann 
4898cc11b9c1SAndrei Emeltchenko 		ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
4899cc11b9c1SAndrei Emeltchenko 		if (ie)
490002b7cc62SJohan Hedberg 			ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
490141a96212SMarcel Holtmann 
4902bbb0eadaSJaganath Kanakkassery 		if (ev->features[0] & LMP_HOST_SSP) {
490358a681efSJohan Hedberg 			set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
4904bbb0eadaSJaganath Kanakkassery 		} else {
4905bbb0eadaSJaganath Kanakkassery 			/* It is mandatory by the Bluetooth specification that
4906bbb0eadaSJaganath Kanakkassery 			 * Extended Inquiry Results are only used when Secure
4907bbb0eadaSJaganath Kanakkassery 			 * Simple Pairing is enabled, but some devices violate
4908bbb0eadaSJaganath Kanakkassery 			 * this.
4909bbb0eadaSJaganath Kanakkassery 			 *
4910bbb0eadaSJaganath Kanakkassery 			 * To make these devices work, the internal SSP
4911bbb0eadaSJaganath Kanakkassery 			 * enabled flag needs to be cleared if the remote host
4912bbb0eadaSJaganath Kanakkassery 			 * features do not indicate SSP support */
4913bbb0eadaSJaganath Kanakkassery 			clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
4914bbb0eadaSJaganath Kanakkassery 		}
4915eb9a8f3fSMarcel Holtmann 
4916eb9a8f3fSMarcel Holtmann 		if (ev->features[0] & LMP_HOST_SC)
4917eb9a8f3fSMarcel Holtmann 			set_bit(HCI_CONN_SC_ENABLED, &conn->flags);
491841a96212SMarcel Holtmann 	}
491941a96212SMarcel Holtmann 
4920ccd556feSJohan Hedberg 	if (conn->state != BT_CONFIG)
4921ccd556feSJohan Hedberg 		goto unlock;
4922ccd556feSJohan Hedberg 
4923671267bfSJohan Hedberg 	if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
4924127178d2SJohan Hedberg 		struct hci_cp_remote_name_req cp;
4925127178d2SJohan Hedberg 		memset(&cp, 0, sizeof(cp));
4926127178d2SJohan Hedberg 		bacpy(&cp.bdaddr, &conn->dst);
4927127178d2SJohan Hedberg 		cp.pscan_rep_mode = 0x02;
4928127178d2SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
4929b644ba33SJohan Hedberg 	} else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
49301c6ed31bSYu Liu 		mgmt_device_connected(hdev, conn, NULL, 0);
4931392599b9SJohan Hedberg 
4932127178d2SJohan Hedberg 	if (!hci_outgoing_auth_needed(hdev, conn)) {
4933769be974SMarcel Holtmann 		conn->state = BT_CONNECTED;
4934539c496dSJohan Hedberg 		hci_connect_cfm(conn, ev->status);
493576a68ba0SDavid Herrmann 		hci_conn_drop(conn);
4936769be974SMarcel Holtmann 	}
4937769be974SMarcel Holtmann 
4938ccd556feSJohan Hedberg unlock:
493941a96212SMarcel Holtmann 	hci_dev_unlock(hdev);
4940a9de9248SMarcel Holtmann }
4941a9de9248SMarcel Holtmann 
49423e54c589SLuiz Augusto von Dentz static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data,
4943807deac2SGustavo Padovan 				       struct sk_buff *skb)
4944a9de9248SMarcel Holtmann {
49453e54c589SLuiz Augusto von Dentz 	struct hci_ev_sync_conn_complete *ev = data;
4946b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
4947c86cc5a3SLuiz Augusto von Dentz 	u8 status = ev->status;
4948b6a0dc82SMarcel Holtmann 
49493afee211SSoenke Huster 	switch (ev->link_type) {
49503afee211SSoenke Huster 	case SCO_LINK:
49513afee211SSoenke Huster 	case ESCO_LINK:
49523afee211SSoenke Huster 		break;
49533afee211SSoenke Huster 	default:
49543afee211SSoenke Huster 		/* As per Core 5.3 Vol 4 Part E 7.7.35 (p.2219), Link_Type
49553afee211SSoenke Huster 		 * for HCI_Synchronous_Connection_Complete is limited to
49563afee211SSoenke Huster 		 * either SCO or eSCO
49573afee211SSoenke Huster 		 */
49583afee211SSoenke Huster 		bt_dev_err(hdev, "Ignoring connect complete event for invalid link type");
49593afee211SSoenke Huster 		return;
49603afee211SSoenke Huster 	}
49613afee211SSoenke Huster 
4962c86cc5a3SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
4963b6a0dc82SMarcel Holtmann 
4964b6a0dc82SMarcel Holtmann 	hci_dev_lock(hdev);
4965b6a0dc82SMarcel Holtmann 
4966b6a0dc82SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
49679dc0a3afSMarcel Holtmann 	if (!conn) {
49689dc0a3afSMarcel Holtmann 		if (ev->link_type == ESCO_LINK)
49699dc0a3afSMarcel Holtmann 			goto unlock;
49709dc0a3afSMarcel Holtmann 
4971618353b1SKuba Pawlak 		/* When the link type in the event indicates SCO connection
4972618353b1SKuba Pawlak 		 * and lookup of the connection object fails, then check
4973618353b1SKuba Pawlak 		 * if an eSCO connection object exists.
4974618353b1SKuba Pawlak 		 *
4975618353b1SKuba Pawlak 		 * The core limits the synchronous connections to either
4976618353b1SKuba Pawlak 		 * SCO or eSCO. The eSCO connection is preferred and tried
4977618353b1SKuba Pawlak 		 * to be setup first and until successfully established,
4978618353b1SKuba Pawlak 		 * the link type will be hinted as eSCO.
4979618353b1SKuba Pawlak 		 */
49809dc0a3afSMarcel Holtmann 		conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
4981b6a0dc82SMarcel Holtmann 		if (!conn)
4982b6a0dc82SMarcel Holtmann 			goto unlock;
49839dc0a3afSMarcel Holtmann 	}
49849dc0a3afSMarcel Holtmann 
4985d5ebaa7cSSoenke Huster 	/* The HCI_Synchronous_Connection_Complete event is only sent once per connection.
4986d5ebaa7cSSoenke Huster 	 * Processing it more than once per connection can corrupt kernel memory.
498792fe24a7SDesmond Cheong Zhi Xi 	 *
4988d5ebaa7cSSoenke Huster 	 * As the connection handle is set here for the first time, it indicates
4989d5ebaa7cSSoenke Huster 	 * whether the connection is already set up.
499092fe24a7SDesmond Cheong Zhi Xi 	 */
4991d5ebaa7cSSoenke Huster 	if (conn->handle != HCI_CONN_HANDLE_UNSET) {
4992d5ebaa7cSSoenke Huster 		bt_dev_err(hdev, "Ignoring HCI_Sync_Conn_Complete event for existing connection");
499392fe24a7SDesmond Cheong Zhi Xi 		goto unlock;
499492fe24a7SDesmond Cheong Zhi Xi 	}
499592fe24a7SDesmond Cheong Zhi Xi 
4996c86cc5a3SLuiz Augusto von Dentz 	switch (status) {
4997d5ebaa7cSSoenke Huster 	case 0x00:
4998732547f9SMarcel Holtmann 		conn->handle = __le16_to_cpu(ev->handle);
4999c86cc5a3SLuiz Augusto von Dentz 		if (conn->handle > HCI_CONN_HANDLE_MAX) {
5000c86cc5a3SLuiz Augusto von Dentz 			bt_dev_err(hdev, "Invalid handle: 0x%4.4x > 0x%4.4x",
5001c86cc5a3SLuiz Augusto von Dentz 				   conn->handle, HCI_CONN_HANDLE_MAX);
5002c86cc5a3SLuiz Augusto von Dentz 			status = HCI_ERROR_INVALID_PARAMETERS;
5003c86cc5a3SLuiz Augusto von Dentz 			conn->state = BT_CLOSED;
5004c86cc5a3SLuiz Augusto von Dentz 			break;
5005c86cc5a3SLuiz Augusto von Dentz 		}
5006c86cc5a3SLuiz Augusto von Dentz 
5007732547f9SMarcel Holtmann 		conn->state  = BT_CONNECTED;
5008618353b1SKuba Pawlak 		conn->type   = ev->link_type;
5009732547f9SMarcel Holtmann 
501023b9ceb7SMarcel Holtmann 		hci_debugfs_create_conn(conn);
5011732547f9SMarcel Holtmann 		hci_conn_add_sysfs(conn);
5012732547f9SMarcel Holtmann 		break;
5013732547f9SMarcel Holtmann 
501481218d20SNick Pelly 	case 0x10:	/* Connection Accept Timeout */
50151a4c958cSFrédéric Dalleau 	case 0x0d:	/* Connection Rejected due to Limited Resources */
5016705e5711SStephen Coe 	case 0x11:	/* Unsupported Feature or Parameter Value */
5017732547f9SMarcel Holtmann 	case 0x1c:	/* SCO interval rejected */
50181038a00bSNick Pelly 	case 0x1a:	/* Unsupported Remote Feature */
501956b5453aSHsin-Yu Chao 	case 0x1e:	/* Invalid LMP Parameters */
5020732547f9SMarcel Holtmann 	case 0x1f:	/* Unspecified error */
502127539bc4SAndrew Earl 	case 0x20:	/* Unsupported LMP Parameter value */
50222dea632fSFrédéric Dalleau 		if (conn->out) {
5023efc7688bSMarcel Holtmann 			conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
5024efc7688bSMarcel Holtmann 					(hdev->esco_type & EDR_ESCO_MASK);
50252dea632fSFrédéric Dalleau 			if (hci_setup_sync(conn, conn->link->handle))
5026efc7688bSMarcel Holtmann 				goto unlock;
5027efc7688bSMarcel Holtmann 		}
502819186c7bSGustavo A. R. Silva 		fallthrough;
5029efc7688bSMarcel Holtmann 
5030732547f9SMarcel Holtmann 	default:
5031b6a0dc82SMarcel Holtmann 		conn->state = BT_CLOSED;
5032732547f9SMarcel Holtmann 		break;
5033732547f9SMarcel Holtmann 	}
5034b6a0dc82SMarcel Holtmann 
50351f8330eaSSathish Narsimman 	bt_dev_dbg(hdev, "SCO connected with air mode: %02x", ev->air_mode);
5036f4f9fa0cSChethan T N 	/* Notify only in case of SCO over HCI transport data path which
5037f4f9fa0cSChethan T N 	 * is zero and non-zero value shall be non-HCI transport data path
5038f4f9fa0cSChethan T N 	 */
5039a27c519aSJackie Liu 	if (conn->codec.data_path == 0 && hdev->notify) {
5040a27c519aSJackie Liu 		switch (ev->air_mode) {
5041a27c519aSJackie Liu 		case 0x02:
5042a27c519aSJackie Liu 			hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD);
5043a27c519aSJackie Liu 			break;
5044a27c519aSJackie Liu 		case 0x03:
5045a27c519aSJackie Liu 			hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_TRANSP);
5046a27c519aSJackie Liu 			break;
5047a27c519aSJackie Liu 		}
5048f4f9fa0cSChethan T N 	}
5049f4f9fa0cSChethan T N 
5050c86cc5a3SLuiz Augusto von Dentz 	hci_connect_cfm(conn, status);
5051c86cc5a3SLuiz Augusto von Dentz 	if (status)
5052b6a0dc82SMarcel Holtmann 		hci_conn_del(conn);
5053b6a0dc82SMarcel Holtmann 
5054b6a0dc82SMarcel Holtmann unlock:
5055b6a0dc82SMarcel Holtmann 	hci_dev_unlock(hdev);
5056a9de9248SMarcel Holtmann }
5057a9de9248SMarcel Holtmann 
5058efdcf8e3SMarcel Holtmann static inline size_t eir_get_length(u8 *eir, size_t eir_len)
5059efdcf8e3SMarcel Holtmann {
5060efdcf8e3SMarcel Holtmann 	size_t parsed = 0;
5061efdcf8e3SMarcel Holtmann 
5062efdcf8e3SMarcel Holtmann 	while (parsed < eir_len) {
5063efdcf8e3SMarcel Holtmann 		u8 field_len = eir[0];
5064efdcf8e3SMarcel Holtmann 
5065efdcf8e3SMarcel Holtmann 		if (field_len == 0)
5066efdcf8e3SMarcel Holtmann 			return parsed;
5067efdcf8e3SMarcel Holtmann 
5068efdcf8e3SMarcel Holtmann 		parsed += field_len + 1;
5069efdcf8e3SMarcel Holtmann 		eir += field_len + 1;
5070efdcf8e3SMarcel Holtmann 	}
5071efdcf8e3SMarcel Holtmann 
5072efdcf8e3SMarcel Holtmann 	return eir_len;
5073efdcf8e3SMarcel Holtmann }
5074efdcf8e3SMarcel Holtmann 
50753e54c589SLuiz Augusto von Dentz static void hci_extended_inquiry_result_evt(struct hci_dev *hdev, void *edata,
5076807deac2SGustavo Padovan 					    struct sk_buff *skb)
5077a9de9248SMarcel Holtmann {
50783e54c589SLuiz Augusto von Dentz 	struct hci_ev_ext_inquiry_result *ev = edata;
5079a9de9248SMarcel Holtmann 	struct inquiry_data data;
50809d939d94SVishal Agarwal 	size_t eir_len;
508170a6b8deSLuiz Augusto von Dentz 	int i;
5082a9de9248SMarcel Holtmann 
508370a6b8deSLuiz Augusto von Dentz 	if (!hci_ev_skb_pull(hdev, skb, HCI_EV_EXTENDED_INQUIRY_RESULT,
508470a6b8deSLuiz Augusto von Dentz 			     flex_array_size(ev, info, ev->num)))
508570a6b8deSLuiz Augusto von Dentz 		return;
508670a6b8deSLuiz Augusto von Dentz 
50873e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "num %d", ev->num);
508870a6b8deSLuiz Augusto von Dentz 
508970a6b8deSLuiz Augusto von Dentz 	if (!ev->num)
5090a9de9248SMarcel Holtmann 		return;
5091a9de9248SMarcel Holtmann 
5092d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ))
50931519cc17SAndre Guedes 		return;
50941519cc17SAndre Guedes 
5095a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
5096a9de9248SMarcel Holtmann 
509770a6b8deSLuiz Augusto von Dentz 	for (i = 0; i < ev->num; i++) {
509870a6b8deSLuiz Augusto von Dentz 		struct extended_inquiry_info *info = &ev->info[i];
5099af58925cSMarcel Holtmann 		u32 flags;
5100af58925cSMarcel Holtmann 		bool name_known;
5101561aafbcSJohan Hedberg 
5102a9de9248SMarcel Holtmann 		bacpy(&data.bdaddr, &info->bdaddr);
5103a9de9248SMarcel Holtmann 		data.pscan_rep_mode	= info->pscan_rep_mode;
5104a9de9248SMarcel Holtmann 		data.pscan_period_mode	= info->pscan_period_mode;
5105a9de9248SMarcel Holtmann 		data.pscan_mode		= 0x00;
5106a9de9248SMarcel Holtmann 		memcpy(data.dev_class, info->dev_class, 3);
5107a9de9248SMarcel Holtmann 		data.clock_offset	= info->clock_offset;
5108a9de9248SMarcel Holtmann 		data.rssi		= info->rssi;
510941a96212SMarcel Holtmann 		data.ssp_mode		= 0x01;
5110561aafbcSJohan Hedberg 
5111d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_MGMT))
51120d3b7f64SJohan Hedberg 			name_known = eir_get_data(info->data,
51134ddb1930SJohan Hedberg 						  sizeof(info->data),
51140d3b7f64SJohan Hedberg 						  EIR_NAME_COMPLETE, NULL);
5115561aafbcSJohan Hedberg 		else
5116561aafbcSJohan Hedberg 			name_known = true;
5117561aafbcSJohan Hedberg 
5118af58925cSMarcel Holtmann 		flags = hci_inquiry_cache_update(hdev, &data, name_known);
5119af58925cSMarcel Holtmann 
51209d939d94SVishal Agarwal 		eir_len = eir_get_length(info->data, sizeof(info->data));
5121af58925cSMarcel Holtmann 
512248264f06SJohan Hedberg 		mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
5123af58925cSMarcel Holtmann 				  info->dev_class, info->rssi,
5124b338d917SBrian Gix 				  flags, info->data, eir_len, NULL, 0, 0);
5125a9de9248SMarcel Holtmann 	}
5126a9de9248SMarcel Holtmann 
5127a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
5128a9de9248SMarcel Holtmann }
5129a9de9248SMarcel Holtmann 
51303e54c589SLuiz Augusto von Dentz static void hci_key_refresh_complete_evt(struct hci_dev *hdev, void *data,
51311c2e0041SJohan Hedberg 					 struct sk_buff *skb)
51321c2e0041SJohan Hedberg {
51333e54c589SLuiz Augusto von Dentz 	struct hci_ev_key_refresh_complete *ev = data;
51341c2e0041SJohan Hedberg 	struct hci_conn *conn;
51351c2e0041SJohan Hedberg 
51363e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x handle 0x%4.4x", ev->status,
51371c2e0041SJohan Hedberg 		   __le16_to_cpu(ev->handle));
51381c2e0041SJohan Hedberg 
51391c2e0041SJohan Hedberg 	hci_dev_lock(hdev);
51401c2e0041SJohan Hedberg 
51411c2e0041SJohan Hedberg 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
51421c2e0041SJohan Hedberg 	if (!conn)
51431c2e0041SJohan Hedberg 		goto unlock;
51441c2e0041SJohan Hedberg 
51459eb1fbfaSJohan Hedberg 	/* For BR/EDR the necessary steps are taken through the
51469eb1fbfaSJohan Hedberg 	 * auth_complete event.
51479eb1fbfaSJohan Hedberg 	 */
51489eb1fbfaSJohan Hedberg 	if (conn->type != LE_LINK)
51499eb1fbfaSJohan Hedberg 		goto unlock;
51509eb1fbfaSJohan Hedberg 
51511c2e0041SJohan Hedberg 	if (!ev->status)
51521c2e0041SJohan Hedberg 		conn->sec_level = conn->pending_sec_level;
51531c2e0041SJohan Hedberg 
51541c2e0041SJohan Hedberg 	clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
51551c2e0041SJohan Hedberg 
51561c2e0041SJohan Hedberg 	if (ev->status && conn->state == BT_CONNECTED) {
5157bed71748SAndre Guedes 		hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
515876a68ba0SDavid Herrmann 		hci_conn_drop(conn);
51591c2e0041SJohan Hedberg 		goto unlock;
51601c2e0041SJohan Hedberg 	}
51611c2e0041SJohan Hedberg 
51621c2e0041SJohan Hedberg 	if (conn->state == BT_CONFIG) {
51631c2e0041SJohan Hedberg 		if (!ev->status)
51641c2e0041SJohan Hedberg 			conn->state = BT_CONNECTED;
51651c2e0041SJohan Hedberg 
5166539c496dSJohan Hedberg 		hci_connect_cfm(conn, ev->status);
516776a68ba0SDavid Herrmann 		hci_conn_drop(conn);
51681c2e0041SJohan Hedberg 	} else {
51691c2e0041SJohan Hedberg 		hci_auth_cfm(conn, ev->status);
51701c2e0041SJohan Hedberg 
51711c2e0041SJohan Hedberg 		hci_conn_hold(conn);
51721c2e0041SJohan Hedberg 		conn->disc_timeout = HCI_DISCONN_TIMEOUT;
517376a68ba0SDavid Herrmann 		hci_conn_drop(conn);
51741c2e0041SJohan Hedberg 	}
51751c2e0041SJohan Hedberg 
51761c2e0041SJohan Hedberg unlock:
51771c2e0041SJohan Hedberg 	hci_dev_unlock(hdev);
51781c2e0041SJohan Hedberg }
51791c2e0041SJohan Hedberg 
51806039aa73SGustavo Padovan static u8 hci_get_auth_req(struct hci_conn *conn)
518117fa4b9dSJohan Hedberg {
518217fa4b9dSJohan Hedberg 	/* If remote requests no-bonding follow that lead */
5183acabae96SMikel Astiz 	if (conn->remote_auth == HCI_AT_NO_BONDING ||
5184acabae96SMikel Astiz 	    conn->remote_auth == HCI_AT_NO_BONDING_MITM)
518558797bf7SWaldemar Rymarkiewicz 		return conn->remote_auth | (conn->auth_type & 0x01);
518617fa4b9dSJohan Hedberg 
5187b7f94c88SMikel Astiz 	/* If both remote and local have enough IO capabilities, require
5188b7f94c88SMikel Astiz 	 * MITM protection
5189b7f94c88SMikel Astiz 	 */
5190b7f94c88SMikel Astiz 	if (conn->remote_cap != HCI_IO_NO_INPUT_OUTPUT &&
5191b7f94c88SMikel Astiz 	    conn->io_capability != HCI_IO_NO_INPUT_OUTPUT)
5192b7f94c88SMikel Astiz 		return conn->remote_auth | 0x01;
5193b7f94c88SMikel Astiz 
51947e74170aSTimo Mueller 	/* No MITM protection possible so ignore remote requirement */
51957e74170aSTimo Mueller 	return (conn->remote_auth & ~0x01) | (conn->auth_type & 0x01);
519617fa4b9dSJohan Hedberg }
519717fa4b9dSJohan Hedberg 
5198a83ed81eSMarcel Holtmann static u8 bredr_oob_data_present(struct hci_conn *conn)
5199a83ed81eSMarcel Holtmann {
5200a83ed81eSMarcel Holtmann 	struct hci_dev *hdev = conn->hdev;
5201a83ed81eSMarcel Holtmann 	struct oob_data *data;
5202a83ed81eSMarcel Holtmann 
5203a83ed81eSMarcel Holtmann 	data = hci_find_remote_oob_data(hdev, &conn->dst, BDADDR_BREDR);
5204a83ed81eSMarcel Holtmann 	if (!data)
5205a83ed81eSMarcel Holtmann 		return 0x00;
5206a83ed81eSMarcel Holtmann 
5207bf21d793SMarcel Holtmann 	if (bredr_sc_enabled(hdev)) {
5208bf21d793SMarcel Holtmann 		/* When Secure Connections is enabled, then just
5209bf21d793SMarcel Holtmann 		 * return the present value stored with the OOB
5210bf21d793SMarcel Holtmann 		 * data. The stored value contains the right present
5211bf21d793SMarcel Holtmann 		 * information. However it can only be trusted when
5212bf21d793SMarcel Holtmann 		 * not in Secure Connection Only mode.
5213aa5b0345SMarcel Holtmann 		 */
5214d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_SC_ONLY))
5215bf21d793SMarcel Holtmann 			return data->present;
5216bf21d793SMarcel Holtmann 
5217bf21d793SMarcel Holtmann 		/* When Secure Connections Only mode is enabled, then
5218bf21d793SMarcel Holtmann 		 * the P-256 values are required. If they are not
5219bf21d793SMarcel Holtmann 		 * available, then do not declare that OOB data is
5220bf21d793SMarcel Holtmann 		 * present.
5221bf21d793SMarcel Holtmann 		 */
5222bf21d793SMarcel Holtmann 		if (!memcmp(data->rand256, ZERO_KEY, 16) ||
5223bf21d793SMarcel Holtmann 		    !memcmp(data->hash256, ZERO_KEY, 16))
5224aa5b0345SMarcel Holtmann 			return 0x00;
5225aa5b0345SMarcel Holtmann 
5226bf21d793SMarcel Holtmann 		return 0x02;
5227bf21d793SMarcel Holtmann 	}
5228659c7fb0SMarcel Holtmann 
5229659c7fb0SMarcel Holtmann 	/* When Secure Connections is not enabled or actually
5230659c7fb0SMarcel Holtmann 	 * not supported by the hardware, then check that if
5231659c7fb0SMarcel Holtmann 	 * P-192 data values are present.
5232659c7fb0SMarcel Holtmann 	 */
5233659c7fb0SMarcel Holtmann 	if (!memcmp(data->rand192, ZERO_KEY, 16) ||
5234659c7fb0SMarcel Holtmann 	    !memcmp(data->hash192, ZERO_KEY, 16))
5235659c7fb0SMarcel Holtmann 		return 0x00;
5236659c7fb0SMarcel Holtmann 
5237a83ed81eSMarcel Holtmann 	return 0x01;
5238659c7fb0SMarcel Holtmann }
5239a83ed81eSMarcel Holtmann 
52403e54c589SLuiz Augusto von Dentz static void hci_io_capa_request_evt(struct hci_dev *hdev, void *data,
52413e54c589SLuiz Augusto von Dentz 				    struct sk_buff *skb)
52420493684eSMarcel Holtmann {
52433e54c589SLuiz Augusto von Dentz 	struct hci_ev_io_capa_request *ev = data;
52440493684eSMarcel Holtmann 	struct hci_conn *conn;
52450493684eSMarcel Holtmann 
52463e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
52470493684eSMarcel Holtmann 
52480493684eSMarcel Holtmann 	hci_dev_lock(hdev);
52490493684eSMarcel Holtmann 
52500493684eSMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
525103b555e1SJohan Hedberg 	if (!conn)
525203b555e1SJohan Hedberg 		goto unlock;
525303b555e1SJohan Hedberg 
52540493684eSMarcel Holtmann 	hci_conn_hold(conn);
52550493684eSMarcel Holtmann 
5256d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
525703b555e1SJohan Hedberg 		goto unlock;
525803b555e1SJohan Hedberg 
52592f407f0aSJohan Hedberg 	/* Allow pairing if we're pairable, the initiators of the
52602f407f0aSJohan Hedberg 	 * pairing or if the remote is not requesting bonding.
52612f407f0aSJohan Hedberg 	 */
5262d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_BONDABLE) ||
52632f407f0aSJohan Hedberg 	    test_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags) ||
526403b555e1SJohan Hedberg 	    (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
526517fa4b9dSJohan Hedberg 		struct hci_cp_io_capability_reply cp;
526617fa4b9dSJohan Hedberg 
526717fa4b9dSJohan Hedberg 		bacpy(&cp.bdaddr, &ev->bdaddr);
52687a7f1e7cSHemant Gupta 		/* Change the IO capability from KeyboardDisplay
52697a7f1e7cSHemant Gupta 		 * to DisplayYesNo as it is not supported by BT spec. */
52707a7f1e7cSHemant Gupta 		cp.capability = (conn->io_capability == 0x04) ?
5271a767631aSMikel Astiz 				HCI_IO_DISPLAY_YESNO : conn->io_capability;
5272b7f94c88SMikel Astiz 
5273b7f94c88SMikel Astiz 		/* If we are initiators, there is no remote information yet */
5274b7f94c88SMikel Astiz 		if (conn->remote_auth == 0xff) {
5275b16c6604SMikel Astiz 			/* Request MITM protection if our IO caps allow it
52764ad51a75SJohan Hedberg 			 * except for the no-bonding case.
5277b16c6604SMikel Astiz 			 */
52786fd6b915SMikel Astiz 			if (conn->io_capability != HCI_IO_NO_INPUT_OUTPUT &&
52799f743d74SJohan Hedberg 			    conn->auth_type != HCI_AT_NO_BONDING)
52806c53823aSJohan Hedberg 				conn->auth_type |= 0x01;
5281b7f94c88SMikel Astiz 		} else {
52827cbc9bd9SJohan Hedberg 			conn->auth_type = hci_get_auth_req(conn);
5283b7f94c88SMikel Astiz 		}
528417fa4b9dSJohan Hedberg 
528582c295b1SJohan Hedberg 		/* If we're not bondable, force one of the non-bondable
528682c295b1SJohan Hedberg 		 * authentication requirement values.
528782c295b1SJohan Hedberg 		 */
5288d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_BONDABLE))
528982c295b1SJohan Hedberg 			conn->auth_type &= HCI_AT_NO_BONDING_MITM;
529082c295b1SJohan Hedberg 
529182c295b1SJohan Hedberg 		cp.authentication = conn->auth_type;
5292a83ed81eSMarcel Holtmann 		cp.oob_data = bredr_oob_data_present(conn);
5293ce85ee13SSzymon Janc 
529417fa4b9dSJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
529517fa4b9dSJohan Hedberg 			     sizeof(cp), &cp);
529603b555e1SJohan Hedberg 	} else {
529703b555e1SJohan Hedberg 		struct hci_cp_io_capability_neg_reply cp;
529803b555e1SJohan Hedberg 
529903b555e1SJohan Hedberg 		bacpy(&cp.bdaddr, &ev->bdaddr);
53009f5a0d7bSAndrei Emeltchenko 		cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
530103b555e1SJohan Hedberg 
530203b555e1SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
530303b555e1SJohan Hedberg 			     sizeof(cp), &cp);
530403b555e1SJohan Hedberg 	}
530503b555e1SJohan Hedberg 
530603b555e1SJohan Hedberg unlock:
530703b555e1SJohan Hedberg 	hci_dev_unlock(hdev);
530803b555e1SJohan Hedberg }
530903b555e1SJohan Hedberg 
53103e54c589SLuiz Augusto von Dentz static void hci_io_capa_reply_evt(struct hci_dev *hdev, void *data,
53113e54c589SLuiz Augusto von Dentz 				  struct sk_buff *skb)
531203b555e1SJohan Hedberg {
53133e54c589SLuiz Augusto von Dentz 	struct hci_ev_io_capa_reply *ev = data;
531403b555e1SJohan Hedberg 	struct hci_conn *conn;
531503b555e1SJohan Hedberg 
53163e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
531703b555e1SJohan Hedberg 
531803b555e1SJohan Hedberg 	hci_dev_lock(hdev);
531903b555e1SJohan Hedberg 
532003b555e1SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
532103b555e1SJohan Hedberg 	if (!conn)
532203b555e1SJohan Hedberg 		goto unlock;
532303b555e1SJohan Hedberg 
532403b555e1SJohan Hedberg 	conn->remote_cap = ev->capability;
532503b555e1SJohan Hedberg 	conn->remote_auth = ev->authentication;
532603b555e1SJohan Hedberg 
532703b555e1SJohan Hedberg unlock:
53280493684eSMarcel Holtmann 	hci_dev_unlock(hdev);
53290493684eSMarcel Holtmann }
53300493684eSMarcel Holtmann 
53313e54c589SLuiz Augusto von Dentz static void hci_user_confirm_request_evt(struct hci_dev *hdev, void *data,
5332a5c29683SJohan Hedberg 					 struct sk_buff *skb)
5333a5c29683SJohan Hedberg {
53343e54c589SLuiz Augusto von Dentz 	struct hci_ev_user_confirm_req *ev = data;
533555bc1a37SJohan Hedberg 	int loc_mitm, rem_mitm, confirm_hint = 0;
53367a828908SJohan Hedberg 	struct hci_conn *conn;
5337a5c29683SJohan Hedberg 
53383e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
5339a5c29683SJohan Hedberg 
5340a5c29683SJohan Hedberg 	hci_dev_lock(hdev);
5341a5c29683SJohan Hedberg 
5342d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
53437a828908SJohan Hedberg 		goto unlock;
53447a828908SJohan Hedberg 
53457a828908SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
53467a828908SJohan Hedberg 	if (!conn)
53477a828908SJohan Hedberg 		goto unlock;
53487a828908SJohan Hedberg 
53497a828908SJohan Hedberg 	loc_mitm = (conn->auth_type & 0x01);
53507a828908SJohan Hedberg 	rem_mitm = (conn->remote_auth & 0x01);
53517a828908SJohan Hedberg 
53527a828908SJohan Hedberg 	/* If we require MITM but the remote device can't provide that
53536c53823aSJohan Hedberg 	 * (it has NoInputNoOutput) then reject the confirmation
53546c53823aSJohan Hedberg 	 * request. We check the security level here since it doesn't
53556c53823aSJohan Hedberg 	 * necessarily match conn->auth_type.
53566fd6b915SMikel Astiz 	 */
53576c53823aSJohan Hedberg 	if (conn->pending_sec_level > BT_SECURITY_MEDIUM &&
53586c53823aSJohan Hedberg 	    conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
53593e54c589SLuiz Augusto von Dentz 		bt_dev_dbg(hdev, "Rejecting request: remote device can't provide MITM");
53607a828908SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
53617a828908SJohan Hedberg 			     sizeof(ev->bdaddr), &ev->bdaddr);
53627a828908SJohan Hedberg 		goto unlock;
53637a828908SJohan Hedberg 	}
53647a828908SJohan Hedberg 
53657a828908SJohan Hedberg 	/* If no side requires MITM protection; auto-accept */
5366a767631aSMikel Astiz 	if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
5367a767631aSMikel Astiz 	    (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
536855bc1a37SJohan Hedberg 
536955bc1a37SJohan Hedberg 		/* If we're not the initiators request authorization to
537055bc1a37SJohan Hedberg 		 * proceed from user space (mgmt_user_confirm with
5371ba15a58bSJohan Hedberg 		 * confirm_hint set to 1). The exception is if neither
537202f3e254SJohan Hedberg 		 * side had MITM or if the local IO capability is
537302f3e254SJohan Hedberg 		 * NoInputNoOutput, in which case we do auto-accept
5374ba15a58bSJohan Hedberg 		 */
5375ba15a58bSJohan Hedberg 		if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) &&
537602f3e254SJohan Hedberg 		    conn->io_capability != HCI_IO_NO_INPUT_OUTPUT &&
5377ba15a58bSJohan Hedberg 		    (loc_mitm || rem_mitm)) {
53783e54c589SLuiz Augusto von Dentz 			bt_dev_dbg(hdev, "Confirming auto-accept as acceptor");
537955bc1a37SJohan Hedberg 			confirm_hint = 1;
538055bc1a37SJohan Hedberg 			goto confirm;
538155bc1a37SJohan Hedberg 		}
538255bc1a37SJohan Hedberg 
5383cee5f20fSHoward Chung 		/* If there already exists link key in local host, leave the
5384cee5f20fSHoward Chung 		 * decision to user space since the remote device could be
5385cee5f20fSHoward Chung 		 * legitimate or malicious.
5386cee5f20fSHoward Chung 		 */
5387cee5f20fSHoward Chung 		if (hci_find_link_key(hdev, &ev->bdaddr)) {
5388cee5f20fSHoward Chung 			bt_dev_dbg(hdev, "Local host already has link key");
5389cee5f20fSHoward Chung 			confirm_hint = 1;
5390cee5f20fSHoward Chung 			goto confirm;
5391cee5f20fSHoward Chung 		}
5392cee5f20fSHoward Chung 
53939f61656aSJohan Hedberg 		BT_DBG("Auto-accept of user confirmation with %ums delay",
53949f61656aSJohan Hedberg 		       hdev->auto_accept_delay);
53959f61656aSJohan Hedberg 
53969f61656aSJohan Hedberg 		if (hdev->auto_accept_delay > 0) {
53979f61656aSJohan Hedberg 			int delay = msecs_to_jiffies(hdev->auto_accept_delay);
53987bc18d9dSJohan Hedberg 			queue_delayed_work(conn->hdev->workqueue,
53997bc18d9dSJohan Hedberg 					   &conn->auto_accept_work, delay);
54009f61656aSJohan Hedberg 			goto unlock;
54019f61656aSJohan Hedberg 		}
54029f61656aSJohan Hedberg 
54037a828908SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
54047a828908SJohan Hedberg 			     sizeof(ev->bdaddr), &ev->bdaddr);
54057a828908SJohan Hedberg 		goto unlock;
54067a828908SJohan Hedberg 	}
54077a828908SJohan Hedberg 
540855bc1a37SJohan Hedberg confirm:
540939adbffeSJohan Hedberg 	mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0,
541039adbffeSJohan Hedberg 				  le32_to_cpu(ev->passkey), confirm_hint);
5411a5c29683SJohan Hedberg 
54127a828908SJohan Hedberg unlock:
5413a5c29683SJohan Hedberg 	hci_dev_unlock(hdev);
5414a5c29683SJohan Hedberg }
5415a5c29683SJohan Hedberg 
54163e54c589SLuiz Augusto von Dentz static void hci_user_passkey_request_evt(struct hci_dev *hdev, void *data,
54171143d458SBrian Gix 					 struct sk_buff *skb)
54181143d458SBrian Gix {
54193e54c589SLuiz Augusto von Dentz 	struct hci_ev_user_passkey_req *ev = data;
5420ae61a10dSLuiz Augusto von Dentz 
54213e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
54221143d458SBrian Gix 
5423d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
5424272d90dfSJohan Hedberg 		mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
54251143d458SBrian Gix }
54261143d458SBrian Gix 
54273e54c589SLuiz Augusto von Dentz static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
542892a25256SJohan Hedberg 					struct sk_buff *skb)
542992a25256SJohan Hedberg {
54303e54c589SLuiz Augusto von Dentz 	struct hci_ev_user_passkey_notify *ev = data;
543192a25256SJohan Hedberg 	struct hci_conn *conn;
543292a25256SJohan Hedberg 
54333e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
543492a25256SJohan Hedberg 
543592a25256SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
543692a25256SJohan Hedberg 	if (!conn)
543792a25256SJohan Hedberg 		return;
543892a25256SJohan Hedberg 
543992a25256SJohan Hedberg 	conn->passkey_notify = __le32_to_cpu(ev->passkey);
544092a25256SJohan Hedberg 	conn->passkey_entered = 0;
544192a25256SJohan Hedberg 
5442d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
544392a25256SJohan Hedberg 		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
544492a25256SJohan Hedberg 					 conn->dst_type, conn->passkey_notify,
544592a25256SJohan Hedberg 					 conn->passkey_entered);
544692a25256SJohan Hedberg }
544792a25256SJohan Hedberg 
54483e54c589SLuiz Augusto von Dentz static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
54493e54c589SLuiz Augusto von Dentz 				    struct sk_buff *skb)
545092a25256SJohan Hedberg {
54513e54c589SLuiz Augusto von Dentz 	struct hci_ev_keypress_notify *ev = data;
545292a25256SJohan Hedberg 	struct hci_conn *conn;
545392a25256SJohan Hedberg 
54543e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
545592a25256SJohan Hedberg 
545692a25256SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
545792a25256SJohan Hedberg 	if (!conn)
545892a25256SJohan Hedberg 		return;
545992a25256SJohan Hedberg 
546092a25256SJohan Hedberg 	switch (ev->type) {
546192a25256SJohan Hedberg 	case HCI_KEYPRESS_STARTED:
546292a25256SJohan Hedberg 		conn->passkey_entered = 0;
546392a25256SJohan Hedberg 		return;
546492a25256SJohan Hedberg 
546592a25256SJohan Hedberg 	case HCI_KEYPRESS_ENTERED:
546692a25256SJohan Hedberg 		conn->passkey_entered++;
546792a25256SJohan Hedberg 		break;
546892a25256SJohan Hedberg 
546992a25256SJohan Hedberg 	case HCI_KEYPRESS_ERASED:
547092a25256SJohan Hedberg 		conn->passkey_entered--;
547192a25256SJohan Hedberg 		break;
547292a25256SJohan Hedberg 
547392a25256SJohan Hedberg 	case HCI_KEYPRESS_CLEARED:
547492a25256SJohan Hedberg 		conn->passkey_entered = 0;
547592a25256SJohan Hedberg 		break;
547692a25256SJohan Hedberg 
547792a25256SJohan Hedberg 	case HCI_KEYPRESS_COMPLETED:
547892a25256SJohan Hedberg 		return;
547992a25256SJohan Hedberg 	}
548092a25256SJohan Hedberg 
5481d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
548292a25256SJohan Hedberg 		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
548392a25256SJohan Hedberg 					 conn->dst_type, conn->passkey_notify,
548492a25256SJohan Hedberg 					 conn->passkey_entered);
548592a25256SJohan Hedberg }
548692a25256SJohan Hedberg 
54873e54c589SLuiz Augusto von Dentz static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,
5488807deac2SGustavo Padovan 					 struct sk_buff *skb)
54890493684eSMarcel Holtmann {
54903e54c589SLuiz Augusto von Dentz 	struct hci_ev_simple_pair_complete *ev = data;
54910493684eSMarcel Holtmann 	struct hci_conn *conn;
54920493684eSMarcel Holtmann 
54933e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
54940493684eSMarcel Holtmann 
54950493684eSMarcel Holtmann 	hci_dev_lock(hdev);
54960493684eSMarcel Holtmann 
54970493684eSMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
54982a611692SJohan Hedberg 	if (!conn)
54992a611692SJohan Hedberg 		goto unlock;
55002a611692SJohan Hedberg 
5501c1d4fa7aSJohan Hedberg 	/* Reset the authentication requirement to unknown */
5502c1d4fa7aSJohan Hedberg 	conn->remote_auth = 0xff;
5503c1d4fa7aSJohan Hedberg 
55042a611692SJohan Hedberg 	/* To avoid duplicate auth_failed events to user space we check
55052a611692SJohan Hedberg 	 * the HCI_CONN_AUTH_PEND flag which will be set if we
55062a611692SJohan Hedberg 	 * initiated the authentication. A traditional auth_complete
55072a611692SJohan Hedberg 	 * event gets always produced as initiator and is also mapped to
55082a611692SJohan Hedberg 	 * the mgmt_auth_failed event */
5509fa1bd918SMikel Astiz 	if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
5510e1e930f5SJohan Hedberg 		mgmt_auth_failed(conn, ev->status);
55112a611692SJohan Hedberg 
551276a68ba0SDavid Herrmann 	hci_conn_drop(conn);
55130493684eSMarcel Holtmann 
55142a611692SJohan Hedberg unlock:
55150493684eSMarcel Holtmann 	hci_dev_unlock(hdev);
55160493684eSMarcel Holtmann }
55170493684eSMarcel Holtmann 
55183e54c589SLuiz Augusto von Dentz static void hci_remote_host_features_evt(struct hci_dev *hdev, void *data,
5519807deac2SGustavo Padovan 					 struct sk_buff *skb)
552041a96212SMarcel Holtmann {
55213e54c589SLuiz Augusto von Dentz 	struct hci_ev_remote_host_features *ev = data;
552241a96212SMarcel Holtmann 	struct inquiry_entry *ie;
5523cad718edSJohan Hedberg 	struct hci_conn *conn;
552441a96212SMarcel Holtmann 
55253e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
552641a96212SMarcel Holtmann 
552741a96212SMarcel Holtmann 	hci_dev_lock(hdev);
552841a96212SMarcel Holtmann 
5529cad718edSJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
5530cad718edSJohan Hedberg 	if (conn)
5531cad718edSJohan Hedberg 		memcpy(conn->features[1], ev->features, 8);
5532cad718edSJohan Hedberg 
5533cc11b9c1SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
5534cc11b9c1SAndrei Emeltchenko 	if (ie)
553502b7cc62SJohan Hedberg 		ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
553641a96212SMarcel Holtmann 
553741a96212SMarcel Holtmann 	hci_dev_unlock(hdev);
553841a96212SMarcel Holtmann }
553941a96212SMarcel Holtmann 
55403e54c589SLuiz Augusto von Dentz static void hci_remote_oob_data_request_evt(struct hci_dev *hdev, void *edata,
55412763eda6SSzymon Janc 					    struct sk_buff *skb)
55422763eda6SSzymon Janc {
55433e54c589SLuiz Augusto von Dentz 	struct hci_ev_remote_oob_data_request *ev = edata;
55442763eda6SSzymon Janc 	struct oob_data *data;
55452763eda6SSzymon Janc 
55463e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
55472763eda6SSzymon Janc 
55482763eda6SSzymon Janc 	hci_dev_lock(hdev);
55492763eda6SSzymon Janc 
5550d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
5551e1ba1f15SSzymon Janc 		goto unlock;
5552e1ba1f15SSzymon Janc 
55536928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, &ev->bdaddr, BDADDR_BREDR);
55546665d057SMarcel Holtmann 	if (!data) {
55556665d057SMarcel Holtmann 		struct hci_cp_remote_oob_data_neg_reply cp;
55566665d057SMarcel Holtmann 
55576665d057SMarcel Holtmann 		bacpy(&cp.bdaddr, &ev->bdaddr);
55586665d057SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY,
55596665d057SMarcel Holtmann 			     sizeof(cp), &cp);
55606665d057SMarcel Holtmann 		goto unlock;
55616665d057SMarcel Holtmann 	}
55626665d057SMarcel Holtmann 
5563710f11c0SJohan Hedberg 	if (bredr_sc_enabled(hdev)) {
5564519ca9d0SMarcel Holtmann 		struct hci_cp_remote_oob_ext_data_reply cp;
5565519ca9d0SMarcel Holtmann 
5566519ca9d0SMarcel Holtmann 		bacpy(&cp.bdaddr, &ev->bdaddr);
5567d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_SC_ONLY)) {
55686665d057SMarcel Holtmann 			memset(cp.hash192, 0, sizeof(cp.hash192));
55696665d057SMarcel Holtmann 			memset(cp.rand192, 0, sizeof(cp.rand192));
55706665d057SMarcel Holtmann 		} else {
5571519ca9d0SMarcel Holtmann 			memcpy(cp.hash192, data->hash192, sizeof(cp.hash192));
557238da1703SJohan Hedberg 			memcpy(cp.rand192, data->rand192, sizeof(cp.rand192));
55736665d057SMarcel Holtmann 		}
5574519ca9d0SMarcel Holtmann 		memcpy(cp.hash256, data->hash256, sizeof(cp.hash256));
557538da1703SJohan Hedberg 		memcpy(cp.rand256, data->rand256, sizeof(cp.rand256));
5576519ca9d0SMarcel Holtmann 
5577519ca9d0SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY,
5578519ca9d0SMarcel Holtmann 			     sizeof(cp), &cp);
5579519ca9d0SMarcel Holtmann 	} else {
55802763eda6SSzymon Janc 		struct hci_cp_remote_oob_data_reply cp;
55812763eda6SSzymon Janc 
55822763eda6SSzymon Janc 		bacpy(&cp.bdaddr, &ev->bdaddr);
5583519ca9d0SMarcel Holtmann 		memcpy(cp.hash, data->hash192, sizeof(cp.hash));
558438da1703SJohan Hedberg 		memcpy(cp.rand, data->rand192, sizeof(cp.rand));
55852763eda6SSzymon Janc 
5586519ca9d0SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY,
5587519ca9d0SMarcel Holtmann 			     sizeof(cp), &cp);
5588519ca9d0SMarcel Holtmann 	}
55892763eda6SSzymon Janc 
5590e1ba1f15SSzymon Janc unlock:
55912763eda6SSzymon Janc 	hci_dev_unlock(hdev);
55922763eda6SSzymon Janc }
55932763eda6SSzymon Janc 
5594a77a6a14SArron Wang #if IS_ENABLED(CONFIG_BT_HS)
55953e54c589SLuiz Augusto von Dentz static void hci_chan_selected_evt(struct hci_dev *hdev, void *data,
55963e54c589SLuiz Augusto von Dentz 				  struct sk_buff *skb)
5597a77a6a14SArron Wang {
55983e54c589SLuiz Augusto von Dentz 	struct hci_ev_channel_selected *ev = data;
5599a77a6a14SArron Wang 	struct hci_conn *hcon;
5600a77a6a14SArron Wang 
56013e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "handle 0x%2.2x", ev->phy_handle);
5602a77a6a14SArron Wang 
5603a77a6a14SArron Wang 	hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
5604a77a6a14SArron Wang 	if (!hcon)
5605a77a6a14SArron Wang 		return;
5606a77a6a14SArron Wang 
5607a77a6a14SArron Wang 	amp_read_loc_assoc_final_data(hdev, hcon);
5608a77a6a14SArron Wang }
5609a77a6a14SArron Wang 
56103e54c589SLuiz Augusto von Dentz static void hci_phy_link_complete_evt(struct hci_dev *hdev, void *data,
5611d5e91192SAndrei Emeltchenko 				      struct sk_buff *skb)
5612d5e91192SAndrei Emeltchenko {
56133e54c589SLuiz Augusto von Dentz 	struct hci_ev_phy_link_complete *ev = data;
5614d5e91192SAndrei Emeltchenko 	struct hci_conn *hcon, *bredr_hcon;
5615d5e91192SAndrei Emeltchenko 
56163e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "handle 0x%2.2x status 0x%2.2x", ev->phy_handle,
5617d5e91192SAndrei Emeltchenko 		   ev->status);
5618d5e91192SAndrei Emeltchenko 
5619d5e91192SAndrei Emeltchenko 	hci_dev_lock(hdev);
5620d5e91192SAndrei Emeltchenko 
5621d5e91192SAndrei Emeltchenko 	hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
56223ae1dc75SSergey Shtylyov 	if (!hcon)
56233ae1dc75SSergey Shtylyov 		goto unlock;
5624d5e91192SAndrei Emeltchenko 
56253ae1dc75SSergey Shtylyov 	if (!hcon->amp_mgr)
56263ae1dc75SSergey Shtylyov 		goto unlock;
56276dfccd13SAnmol Karn 
5628d5e91192SAndrei Emeltchenko 	if (ev->status) {
5629d5e91192SAndrei Emeltchenko 		hci_conn_del(hcon);
56303ae1dc75SSergey Shtylyov 		goto unlock;
5631d5e91192SAndrei Emeltchenko 	}
5632d5e91192SAndrei Emeltchenko 
5633d5e91192SAndrei Emeltchenko 	bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
5634d5e91192SAndrei Emeltchenko 
5635d5e91192SAndrei Emeltchenko 	hcon->state = BT_CONNECTED;
5636d5e91192SAndrei Emeltchenko 	bacpy(&hcon->dst, &bredr_hcon->dst);
5637d5e91192SAndrei Emeltchenko 
5638d5e91192SAndrei Emeltchenko 	hci_conn_hold(hcon);
5639d5e91192SAndrei Emeltchenko 	hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
564076a68ba0SDavid Herrmann 	hci_conn_drop(hcon);
5641d5e91192SAndrei Emeltchenko 
564223b9ceb7SMarcel Holtmann 	hci_debugfs_create_conn(hcon);
5643d5e91192SAndrei Emeltchenko 	hci_conn_add_sysfs(hcon);
5644d5e91192SAndrei Emeltchenko 
5645cf70ff22SAndrei Emeltchenko 	amp_physical_cfm(bredr_hcon, hcon);
5646cf70ff22SAndrei Emeltchenko 
56473ae1dc75SSergey Shtylyov unlock:
5648d5e91192SAndrei Emeltchenko 	hci_dev_unlock(hdev);
5649d5e91192SAndrei Emeltchenko }
5650d5e91192SAndrei Emeltchenko 
56513e54c589SLuiz Augusto von Dentz static void hci_loglink_complete_evt(struct hci_dev *hdev, void *data,
56523e54c589SLuiz Augusto von Dentz 				     struct sk_buff *skb)
565327695fb4SAndrei Emeltchenko {
56543e54c589SLuiz Augusto von Dentz 	struct hci_ev_logical_link_complete *ev = data;
565527695fb4SAndrei Emeltchenko 	struct hci_conn *hcon;
565627695fb4SAndrei Emeltchenko 	struct hci_chan *hchan;
565727695fb4SAndrei Emeltchenko 	struct amp_mgr *mgr;
565827695fb4SAndrei Emeltchenko 
56593e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
56603e54c589SLuiz Augusto von Dentz 		   le16_to_cpu(ev->handle), ev->phy_handle, ev->status);
566127695fb4SAndrei Emeltchenko 
566227695fb4SAndrei Emeltchenko 	hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
566327695fb4SAndrei Emeltchenko 	if (!hcon)
566427695fb4SAndrei Emeltchenko 		return;
566527695fb4SAndrei Emeltchenko 
566627695fb4SAndrei Emeltchenko 	/* Create AMP hchan */
566727695fb4SAndrei Emeltchenko 	hchan = hci_chan_create(hcon);
566827695fb4SAndrei Emeltchenko 	if (!hchan)
566927695fb4SAndrei Emeltchenko 		return;
567027695fb4SAndrei Emeltchenko 
567127695fb4SAndrei Emeltchenko 	hchan->handle = le16_to_cpu(ev->handle);
56725c4c8c95SArchie Pusaka 	hchan->amp = true;
567327695fb4SAndrei Emeltchenko 
567427695fb4SAndrei Emeltchenko 	BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
567527695fb4SAndrei Emeltchenko 
567627695fb4SAndrei Emeltchenko 	mgr = hcon->amp_mgr;
567727695fb4SAndrei Emeltchenko 	if (mgr && mgr->bredr_chan) {
567827695fb4SAndrei Emeltchenko 		struct l2cap_chan *bredr_chan = mgr->bredr_chan;
567927695fb4SAndrei Emeltchenko 
568027695fb4SAndrei Emeltchenko 		l2cap_chan_lock(bredr_chan);
568127695fb4SAndrei Emeltchenko 
568227695fb4SAndrei Emeltchenko 		bredr_chan->conn->mtu = hdev->block_mtu;
568327695fb4SAndrei Emeltchenko 		l2cap_logical_cfm(bredr_chan, hchan, 0);
568427695fb4SAndrei Emeltchenko 		hci_conn_hold(hcon);
568527695fb4SAndrei Emeltchenko 
568627695fb4SAndrei Emeltchenko 		l2cap_chan_unlock(bredr_chan);
568727695fb4SAndrei Emeltchenko 	}
568827695fb4SAndrei Emeltchenko }
568927695fb4SAndrei Emeltchenko 
56903e54c589SLuiz Augusto von Dentz static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev, void *data,
5691606e2a10SAndrei Emeltchenko 					     struct sk_buff *skb)
5692606e2a10SAndrei Emeltchenko {
56933e54c589SLuiz Augusto von Dentz 	struct hci_ev_disconn_logical_link_complete *ev = data;
5694606e2a10SAndrei Emeltchenko 	struct hci_chan *hchan;
5695606e2a10SAndrei Emeltchenko 
56963e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "handle 0x%4.4x status 0x%2.2x",
5697606e2a10SAndrei Emeltchenko 		   le16_to_cpu(ev->handle), ev->status);
5698606e2a10SAndrei Emeltchenko 
5699606e2a10SAndrei Emeltchenko 	if (ev->status)
5700606e2a10SAndrei Emeltchenko 		return;
5701606e2a10SAndrei Emeltchenko 
5702606e2a10SAndrei Emeltchenko 	hci_dev_lock(hdev);
5703606e2a10SAndrei Emeltchenko 
5704606e2a10SAndrei Emeltchenko 	hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
57055c4c8c95SArchie Pusaka 	if (!hchan || !hchan->amp)
5706606e2a10SAndrei Emeltchenko 		goto unlock;
5707606e2a10SAndrei Emeltchenko 
5708606e2a10SAndrei Emeltchenko 	amp_destroy_logical_link(hchan, ev->reason);
5709606e2a10SAndrei Emeltchenko 
5710606e2a10SAndrei Emeltchenko unlock:
5711606e2a10SAndrei Emeltchenko 	hci_dev_unlock(hdev);
5712606e2a10SAndrei Emeltchenko }
5713606e2a10SAndrei Emeltchenko 
57143e54c589SLuiz Augusto von Dentz static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev, void *data,
57159eef6b3aSAndrei Emeltchenko 					     struct sk_buff *skb)
57169eef6b3aSAndrei Emeltchenko {
57173e54c589SLuiz Augusto von Dentz 	struct hci_ev_disconn_phy_link_complete *ev = data;
57189eef6b3aSAndrei Emeltchenko 	struct hci_conn *hcon;
57199eef6b3aSAndrei Emeltchenko 
57203e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
57219eef6b3aSAndrei Emeltchenko 
57229eef6b3aSAndrei Emeltchenko 	if (ev->status)
57239eef6b3aSAndrei Emeltchenko 		return;
57249eef6b3aSAndrei Emeltchenko 
57259eef6b3aSAndrei Emeltchenko 	hci_dev_lock(hdev);
57269eef6b3aSAndrei Emeltchenko 
57279eef6b3aSAndrei Emeltchenko 	hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
5728f63d24baSLuiz Augusto von Dentz 	if (hcon && hcon->type == AMP_LINK) {
57299eef6b3aSAndrei Emeltchenko 		hcon->state = BT_CLOSED;
5730f63d24baSLuiz Augusto von Dentz 		hci_disconn_cfm(hcon, ev->reason);
57319eef6b3aSAndrei Emeltchenko 		hci_conn_del(hcon);
57329eef6b3aSAndrei Emeltchenko 	}
57339eef6b3aSAndrei Emeltchenko 
57349eef6b3aSAndrei Emeltchenko 	hci_dev_unlock(hdev);
57359eef6b3aSAndrei Emeltchenko }
5736a77a6a14SArron Wang #endif
57379eef6b3aSAndrei Emeltchenko 
5738cafae4cdSLuiz Augusto von Dentz static void le_conn_update_addr(struct hci_conn *conn, bdaddr_t *bdaddr,
5739cafae4cdSLuiz Augusto von Dentz 				u8 bdaddr_type, bdaddr_t *local_rpa)
5740cafae4cdSLuiz Augusto von Dentz {
5741cafae4cdSLuiz Augusto von Dentz 	if (conn->out) {
5742cafae4cdSLuiz Augusto von Dentz 		conn->dst_type = bdaddr_type;
5743cafae4cdSLuiz Augusto von Dentz 		conn->resp_addr_type = bdaddr_type;
5744cafae4cdSLuiz Augusto von Dentz 		bacpy(&conn->resp_addr, bdaddr);
5745cafae4cdSLuiz Augusto von Dentz 
5746cafae4cdSLuiz Augusto von Dentz 		/* Check if the controller has set a Local RPA then it must be
5747cafae4cdSLuiz Augusto von Dentz 		 * used instead or hdev->rpa.
5748cafae4cdSLuiz Augusto von Dentz 		 */
5749cafae4cdSLuiz Augusto von Dentz 		if (local_rpa && bacmp(local_rpa, BDADDR_ANY)) {
5750cafae4cdSLuiz Augusto von Dentz 			conn->init_addr_type = ADDR_LE_DEV_RANDOM;
5751cafae4cdSLuiz Augusto von Dentz 			bacpy(&conn->init_addr, local_rpa);
5752cafae4cdSLuiz Augusto von Dentz 		} else if (hci_dev_test_flag(conn->hdev, HCI_PRIVACY)) {
5753cafae4cdSLuiz Augusto von Dentz 			conn->init_addr_type = ADDR_LE_DEV_RANDOM;
5754cafae4cdSLuiz Augusto von Dentz 			bacpy(&conn->init_addr, &conn->hdev->rpa);
5755cafae4cdSLuiz Augusto von Dentz 		} else {
5756cafae4cdSLuiz Augusto von Dentz 			hci_copy_identity_address(conn->hdev, &conn->init_addr,
5757cafae4cdSLuiz Augusto von Dentz 						  &conn->init_addr_type);
5758cafae4cdSLuiz Augusto von Dentz 		}
5759cafae4cdSLuiz Augusto von Dentz 	} else {
5760cafae4cdSLuiz Augusto von Dentz 		conn->resp_addr_type = conn->hdev->adv_addr_type;
5761cafae4cdSLuiz Augusto von Dentz 		/* Check if the controller has set a Local RPA then it must be
5762cafae4cdSLuiz Augusto von Dentz 		 * used instead or hdev->rpa.
5763cafae4cdSLuiz Augusto von Dentz 		 */
5764cafae4cdSLuiz Augusto von Dentz 		if (local_rpa && bacmp(local_rpa, BDADDR_ANY)) {
5765cafae4cdSLuiz Augusto von Dentz 			conn->resp_addr_type = ADDR_LE_DEV_RANDOM;
5766cafae4cdSLuiz Augusto von Dentz 			bacpy(&conn->resp_addr, local_rpa);
5767cafae4cdSLuiz Augusto von Dentz 		} else if (conn->hdev->adv_addr_type == ADDR_LE_DEV_RANDOM) {
5768cafae4cdSLuiz Augusto von Dentz 			/* In case of ext adv, resp_addr will be updated in
5769cafae4cdSLuiz Augusto von Dentz 			 * Adv Terminated event.
5770cafae4cdSLuiz Augusto von Dentz 			 */
5771cafae4cdSLuiz Augusto von Dentz 			if (!ext_adv_capable(conn->hdev))
5772cafae4cdSLuiz Augusto von Dentz 				bacpy(&conn->resp_addr,
5773cafae4cdSLuiz Augusto von Dentz 				      &conn->hdev->random_addr);
5774cafae4cdSLuiz Augusto von Dentz 		} else {
5775cafae4cdSLuiz Augusto von Dentz 			bacpy(&conn->resp_addr, &conn->hdev->bdaddr);
5776cafae4cdSLuiz Augusto von Dentz 		}
5777cafae4cdSLuiz Augusto von Dentz 
5778cafae4cdSLuiz Augusto von Dentz 		conn->init_addr_type = bdaddr_type;
5779cafae4cdSLuiz Augusto von Dentz 		bacpy(&conn->init_addr, bdaddr);
5780cafae4cdSLuiz Augusto von Dentz 
5781cafae4cdSLuiz Augusto von Dentz 		/* For incoming connections, set the default minimum
5782cafae4cdSLuiz Augusto von Dentz 		 * and maximum connection interval. They will be used
5783cafae4cdSLuiz Augusto von Dentz 		 * to check if the parameters are in range and if not
5784cafae4cdSLuiz Augusto von Dentz 		 * trigger the connection update procedure.
5785cafae4cdSLuiz Augusto von Dentz 		 */
5786cafae4cdSLuiz Augusto von Dentz 		conn->le_conn_min_interval = conn->hdev->le_conn_min_interval;
5787cafae4cdSLuiz Augusto von Dentz 		conn->le_conn_max_interval = conn->hdev->le_conn_max_interval;
5788cafae4cdSLuiz Augusto von Dentz 	}
5789cafae4cdSLuiz Augusto von Dentz }
5790cafae4cdSLuiz Augusto von Dentz 
5791d12fb056SJaganath Kanakkassery static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
5792cafae4cdSLuiz Augusto von Dentz 				 bdaddr_t *bdaddr, u8 bdaddr_type,
5793cafae4cdSLuiz Augusto von Dentz 				 bdaddr_t *local_rpa, u8 role, u16 handle,
5794cafae4cdSLuiz Augusto von Dentz 				 u16 interval, u16 latency,
5795cafae4cdSLuiz Augusto von Dentz 				 u16 supervision_timeout)
5796fcd89c09SVille Tervo {
5797912b42efSJohan Hedberg 	struct hci_conn_params *params;
5798fcd89c09SVille Tervo 	struct hci_conn *conn;
579968d6f6deSJohan Hedberg 	struct smp_irk *irk;
5800837d502eSJohan Hedberg 	u8 addr_type;
5801fcd89c09SVille Tervo 
5802fcd89c09SVille Tervo 	hci_dev_lock(hdev);
5803fcd89c09SVille Tervo 
5804fbd96c15SJohan Hedberg 	/* All controllers implicitly stop advertising in the event of a
5805fbd96c15SJohan Hedberg 	 * connection, so ensure that the state bit is cleared.
5806fbd96c15SJohan Hedberg 	 */
5807a358dc11SMarcel Holtmann 	hci_dev_clear_flag(hdev, HCI_LE_ADV);
5808fbd96c15SJohan Hedberg 
580953562665SArchie Pusaka 	conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, bdaddr);
5810b62f328bSVille Tervo 	if (!conn) {
5811aef2aa4fSLuiz Augusto von Dentz 		/* In case of error status and there is no connection pending
5812aef2aa4fSLuiz Augusto von Dentz 		 * just unlock as there is nothing to cleanup.
5813aef2aa4fSLuiz Augusto von Dentz 		 */
5814aef2aa4fSLuiz Augusto von Dentz 		if (status)
5815aef2aa4fSLuiz Augusto von Dentz 			goto unlock;
5816aef2aa4fSLuiz Augusto von Dentz 
5817d12fb056SJaganath Kanakkassery 		conn = hci_conn_add(hdev, LE_LINK, bdaddr, role);
5818b62f328bSVille Tervo 		if (!conn) {
58192064ee33SMarcel Holtmann 			bt_dev_err(hdev, "no memory for new connection");
5820230fd16aSAndre Guedes 			goto unlock;
5821b62f328bSVille Tervo 		}
582229b7988aSAndre Guedes 
5823d12fb056SJaganath Kanakkassery 		conn->dst_type = bdaddr_type;
5824b9b343d2SAndre Guedes 
5825cb1d68f7SJohan Hedberg 		/* If we didn't have a hci_conn object previously
582674be523cSArchie Pusaka 		 * but we're in central role this must be something
58273d4f9c00SArchie Pusaka 		 * initiated using an accept list. Since accept list based
5828cb1d68f7SJohan Hedberg 		 * connections are not "first class citizens" we don't
5829cb1d68f7SJohan Hedberg 		 * have full tracking of them. Therefore, we go ahead
5830cb1d68f7SJohan Hedberg 		 * with a "best effort" approach of determining the
5831cb1d68f7SJohan Hedberg 		 * initiator address based on the HCI_PRIVACY flag.
5832cb1d68f7SJohan Hedberg 		 */
5833cb1d68f7SJohan Hedberg 		if (conn->out) {
5834d12fb056SJaganath Kanakkassery 			conn->resp_addr_type = bdaddr_type;
5835d12fb056SJaganath Kanakkassery 			bacpy(&conn->resp_addr, bdaddr);
5836d7a5a11dSMarcel Holtmann 			if (hci_dev_test_flag(hdev, HCI_PRIVACY)) {
5837cb1d68f7SJohan Hedberg 				conn->init_addr_type = ADDR_LE_DEV_RANDOM;
5838cb1d68f7SJohan Hedberg 				bacpy(&conn->init_addr, &hdev->rpa);
5839cb1d68f7SJohan Hedberg 			} else {
5840cb1d68f7SJohan Hedberg 				hci_copy_identity_address(hdev,
5841cb1d68f7SJohan Hedberg 							  &conn->init_addr,
5842cb1d68f7SJohan Hedberg 							  &conn->init_addr_type);
5843cb1d68f7SJohan Hedberg 			}
584480c24ab8SJohan Hedberg 		}
5845cb1d68f7SJohan Hedberg 	} else {
584680c24ab8SJohan Hedberg 		cancel_delayed_work(&conn->le_conn_timeout);
584780c24ab8SJohan Hedberg 	}
584880c24ab8SJohan Hedberg 
5849d5ebaa7cSSoenke Huster 	/* The HCI_LE_Connection_Complete event is only sent once per connection.
5850d5ebaa7cSSoenke Huster 	 * Processing it more than once per connection can corrupt kernel memory.
5851d5ebaa7cSSoenke Huster 	 *
5852d5ebaa7cSSoenke Huster 	 * As the connection handle is set here for the first time, it indicates
5853d5ebaa7cSSoenke Huster 	 * whether the connection is already set up.
5854d5ebaa7cSSoenke Huster 	 */
5855d5ebaa7cSSoenke Huster 	if (conn->handle != HCI_CONN_HANDLE_UNSET) {
5856d5ebaa7cSSoenke Huster 		bt_dev_err(hdev, "Ignoring HCI_Connection_Complete for existing connection");
5857d5ebaa7cSSoenke Huster 		goto unlock;
5858d5ebaa7cSSoenke Huster 	}
5859d5ebaa7cSSoenke Huster 
5860cafae4cdSLuiz Augusto von Dentz 	le_conn_update_addr(conn, bdaddr, bdaddr_type, local_rpa);
58617be2edbbSJohan Hedberg 
5862edb4b466SMarcel Holtmann 	/* Lookup the identity address from the stored connection
5863edb4b466SMarcel Holtmann 	 * address and address type.
5864edb4b466SMarcel Holtmann 	 *
5865edb4b466SMarcel Holtmann 	 * When establishing connections to an identity address, the
5866edb4b466SMarcel Holtmann 	 * connection procedure will store the resolvable random
5867edb4b466SMarcel Holtmann 	 * address first. Now if it can be converted back into the
5868edb4b466SMarcel Holtmann 	 * identity address, start using the identity address from
5869edb4b466SMarcel Holtmann 	 * now on.
5870edb4b466SMarcel Holtmann 	 */
5871edb4b466SMarcel Holtmann 	irk = hci_get_irk(hdev, &conn->dst, conn->dst_type);
587268d6f6deSJohan Hedberg 	if (irk) {
587368d6f6deSJohan Hedberg 		bacpy(&conn->dst, &irk->bdaddr);
587468d6f6deSJohan Hedberg 		conn->dst_type = irk->addr_type;
587568d6f6deSJohan Hedberg 	}
587668d6f6deSJohan Hedberg 
5877d850bf08SLuiz Augusto von Dentz 	conn->dst_type = ev_bdaddr_type(hdev, conn->dst_type, NULL);
587879699a70SSathish Narasimman 
5879c86cc5a3SLuiz Augusto von Dentz 	if (handle > HCI_CONN_HANDLE_MAX) {
5880c86cc5a3SLuiz Augusto von Dentz 		bt_dev_err(hdev, "Invalid handle: 0x%4.4x > 0x%4.4x", handle,
5881c86cc5a3SLuiz Augusto von Dentz 			   HCI_CONN_HANDLE_MAX);
5882c86cc5a3SLuiz Augusto von Dentz 		status = HCI_ERROR_INVALID_PARAMETERS;
5883c86cc5a3SLuiz Augusto von Dentz 	}
5884c86cc5a3SLuiz Augusto von Dentz 
5885c9f73a21SLuiz Augusto von Dentz 	/* All connection failure handling is taken care of by the
5886c9f73a21SLuiz Augusto von Dentz 	 * hci_conn_failed function which is triggered by the HCI
5887c9f73a21SLuiz Augusto von Dentz 	 * request completion callbacks used for connecting.
5888c9f73a21SLuiz Augusto von Dentz 	 */
5889c9f73a21SLuiz Augusto von Dentz 	if (status)
5890837d502eSJohan Hedberg 		goto unlock;
5891837d502eSJohan Hedberg 
589208853f18SJohan Hedberg 	if (conn->dst_type == ADDR_LE_DEV_PUBLIC)
589308853f18SJohan Hedberg 		addr_type = BDADDR_LE_PUBLIC;
589408853f18SJohan Hedberg 	else
589508853f18SJohan Hedberg 		addr_type = BDADDR_LE_RANDOM;
589608853f18SJohan Hedberg 
58972d3c2260SJohan Hedberg 	/* Drop the connection if the device is blocked */
58983d4f9c00SArchie Pusaka 	if (hci_bdaddr_list_lookup(&hdev->reject_list, &conn->dst, addr_type)) {
58992d3c2260SJohan Hedberg 		hci_conn_drop(conn);
5900cd17decbSAndre Guedes 		goto unlock;
5901cd17decbSAndre Guedes 	}
5902cd17decbSAndre Guedes 
5903b644ba33SJohan Hedberg 	if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
59041c6ed31bSYu Liu 		mgmt_device_connected(hdev, conn, NULL, 0);
590583bc71b4SVinicius Costa Gomes 
59067b5c0d52SVinicius Costa Gomes 	conn->sec_level = BT_SECURITY_LOW;
5907d12fb056SJaganath Kanakkassery 	conn->handle = handle;
59080fe29fd1SMarcel Holtmann 	conn->state = BT_CONFIG;
5909fcd89c09SVille Tervo 
59107087c4f6SLuiz Augusto von Dentz 	/* Store current advertising instance as connection advertising instance
59117087c4f6SLuiz Augusto von Dentz 	 * when sotfware rotation is in use so it can be re-enabled when
59127087c4f6SLuiz Augusto von Dentz 	 * disconnected.
59137087c4f6SLuiz Augusto von Dentz 	 */
59147087c4f6SLuiz Augusto von Dentz 	if (!ext_adv_capable(hdev))
59157087c4f6SLuiz Augusto von Dentz 		conn->adv_instance = hdev->cur_adv_instance;
59167087c4f6SLuiz Augusto von Dentz 
5917d12fb056SJaganath Kanakkassery 	conn->le_conn_interval = interval;
5918d12fb056SJaganath Kanakkassery 	conn->le_conn_latency = latency;
5919d12fb056SJaganath Kanakkassery 	conn->le_supv_timeout = supervision_timeout;
5920e04fde60SMarcel Holtmann 
592123b9ceb7SMarcel Holtmann 	hci_debugfs_create_conn(conn);
5922fcd89c09SVille Tervo 	hci_conn_add_sysfs(conn);
5923fcd89c09SVille Tervo 
5924ef365da1SArchie Pusaka 	/* The remote features procedure is defined for central
59250fe29fd1SMarcel Holtmann 	 * role only. So only in case of an initiated connection
59260fe29fd1SMarcel Holtmann 	 * request the remote features.
59270fe29fd1SMarcel Holtmann 	 *
5928ef365da1SArchie Pusaka 	 * If the local controller supports peripheral-initiated features
5929ef365da1SArchie Pusaka 	 * exchange, then requesting the remote features in peripheral
59300fe29fd1SMarcel Holtmann 	 * role is possible. Otherwise just transition into the
59310fe29fd1SMarcel Holtmann 	 * connected state without requesting the remote features.
59320fe29fd1SMarcel Holtmann 	 */
59330fe29fd1SMarcel Holtmann 	if (conn->out ||
5934ef365da1SArchie Pusaka 	    (hdev->le_features[0] & HCI_LE_PERIPHERAL_FEATURES)) {
59350fe29fd1SMarcel Holtmann 		struct hci_cp_le_read_remote_features cp;
59360fe29fd1SMarcel Holtmann 
59370fe29fd1SMarcel Holtmann 		cp.handle = __cpu_to_le16(conn->handle);
59380fe29fd1SMarcel Holtmann 
59390fe29fd1SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_LE_READ_REMOTE_FEATURES,
59400fe29fd1SMarcel Holtmann 			     sizeof(cp), &cp);
59410fe29fd1SMarcel Holtmann 
59420fe29fd1SMarcel Holtmann 		hci_conn_hold(conn);
59430fe29fd1SMarcel Holtmann 	} else {
59440fe29fd1SMarcel Holtmann 		conn->state = BT_CONNECTED;
5945d12fb056SJaganath Kanakkassery 		hci_connect_cfm(conn, status);
59460fe29fd1SMarcel Holtmann 	}
5947fcd89c09SVille Tervo 
59485477610fSJohan Hedberg 	params = hci_pend_le_action_lookup(&hdev->pend_le_conns, &conn->dst,
59495477610fSJohan Hedberg 					   conn->dst_type);
5950f161dd41SJohan Hedberg 	if (params) {
595195305baaSJohan Hedberg 		list_del_init(&params->action);
5952f161dd41SJohan Hedberg 		if (params->conn) {
5953f161dd41SJohan Hedberg 			hci_conn_drop(params->conn);
5954f8aaf9b6SJohan Hedberg 			hci_conn_put(params->conn);
5955f161dd41SJohan Hedberg 			params->conn = NULL;
5956f161dd41SJohan Hedberg 		}
5957f161dd41SJohan Hedberg 	}
5958a4790dbdSAndre Guedes 
5959fcd89c09SVille Tervo unlock:
59605bee2fd6SLuiz Augusto von Dentz 	hci_update_passive_scan(hdev);
5961fcd89c09SVille Tervo 	hci_dev_unlock(hdev);
5962fcd89c09SVille Tervo }
5963fcd89c09SVille Tervo 
596495118dd4SLuiz Augusto von Dentz static void hci_le_conn_complete_evt(struct hci_dev *hdev, void *data,
596595118dd4SLuiz Augusto von Dentz 				     struct sk_buff *skb)
5966d12fb056SJaganath Kanakkassery {
596795118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_conn_complete *ev = data;
596812cfe417SLuiz Augusto von Dentz 
596995118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
5970d12fb056SJaganath Kanakkassery 
5971d12fb056SJaganath Kanakkassery 	le_conn_complete_evt(hdev, ev->status, &ev->bdaddr, ev->bdaddr_type,
5972cafae4cdSLuiz Augusto von Dentz 			     NULL, ev->role, le16_to_cpu(ev->handle),
5973d12fb056SJaganath Kanakkassery 			     le16_to_cpu(ev->interval),
5974d12fb056SJaganath Kanakkassery 			     le16_to_cpu(ev->latency),
5975d12fb056SJaganath Kanakkassery 			     le16_to_cpu(ev->supervision_timeout));
5976d12fb056SJaganath Kanakkassery }
5977d12fb056SJaganath Kanakkassery 
597895118dd4SLuiz Augusto von Dentz static void hci_le_enh_conn_complete_evt(struct hci_dev *hdev, void *data,
59794d94f95dSJaganath Kanakkassery 					 struct sk_buff *skb)
59804d94f95dSJaganath Kanakkassery {
598195118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_enh_conn_complete *ev = data;
598212cfe417SLuiz Augusto von Dentz 
598395118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
59844d94f95dSJaganath Kanakkassery 
59854d94f95dSJaganath Kanakkassery 	le_conn_complete_evt(hdev, ev->status, &ev->bdaddr, ev->bdaddr_type,
5986cafae4cdSLuiz Augusto von Dentz 			     &ev->local_rpa, ev->role, le16_to_cpu(ev->handle),
59874d94f95dSJaganath Kanakkassery 			     le16_to_cpu(ev->interval),
59884d94f95dSJaganath Kanakkassery 			     le16_to_cpu(ev->latency),
59894d94f95dSJaganath Kanakkassery 			     le16_to_cpu(ev->supervision_timeout));
59904d94f95dSJaganath Kanakkassery }
59914d94f95dSJaganath Kanakkassery 
599295118dd4SLuiz Augusto von Dentz static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, void *data,
599395118dd4SLuiz Augusto von Dentz 				    struct sk_buff *skb)
5994acf0aeaeSJaganath Kanakkassery {
599595118dd4SLuiz Augusto von Dentz 	struct hci_evt_le_ext_adv_set_term *ev = data;
5996acf0aeaeSJaganath Kanakkassery 	struct hci_conn *conn;
59971f9d5657SArchie Pusaka 	struct adv_info *adv, *n;
5998acf0aeaeSJaganath Kanakkassery 
599995118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
6000acf0aeaeSJaganath Kanakkassery 
60010f281a5eSArchie Pusaka 	/* The Bluetooth Core 5.3 specification clearly states that this event
60020f281a5eSArchie Pusaka 	 * shall not be sent when the Host disables the advertising set. So in
60030f281a5eSArchie Pusaka 	 * case of HCI_ERROR_CANCELLED_BY_HOST, just ignore the event.
60040f281a5eSArchie Pusaka 	 *
60050f281a5eSArchie Pusaka 	 * When the Host disables an advertising set, all cleanup is done via
60060f281a5eSArchie Pusaka 	 * its command callback and not needed to be duplicated here.
60070f281a5eSArchie Pusaka 	 */
60080f281a5eSArchie Pusaka 	if (ev->status == HCI_ERROR_CANCELLED_BY_HOST) {
60090f281a5eSArchie Pusaka 		bt_dev_warn_ratelimited(hdev, "Unexpected advertising set terminated event");
60100f281a5eSArchie Pusaka 		return;
60110f281a5eSArchie Pusaka 	}
60120f281a5eSArchie Pusaka 
6013728abc01SNiels Dossche 	hci_dev_lock(hdev);
6014728abc01SNiels Dossche 
6015728abc01SNiels Dossche 	adv = hci_find_adv_instance(hdev, ev->handle);
6016728abc01SNiels Dossche 
60177087c4f6SLuiz Augusto von Dentz 	if (ev->status) {
601823837a6dSLuiz Augusto von Dentz 		if (!adv)
6019728abc01SNiels Dossche 			goto unlock;
6020acf0aeaeSJaganath Kanakkassery 
602123837a6dSLuiz Augusto von Dentz 		/* Remove advertising as it has been terminated */
602223837a6dSLuiz Augusto von Dentz 		hci_remove_adv_instance(hdev, ev->handle);
602323837a6dSLuiz Augusto von Dentz 		mgmt_advertising_removed(NULL, hdev, ev->handle);
602423837a6dSLuiz Augusto von Dentz 
60251f9d5657SArchie Pusaka 		list_for_each_entry_safe(adv, n, &hdev->adv_instances, list) {
60261f9d5657SArchie Pusaka 			if (adv->enabled)
6027728abc01SNiels Dossche 				goto unlock;
60281f9d5657SArchie Pusaka 		}
60291f9d5657SArchie Pusaka 
60301f9d5657SArchie Pusaka 		/* We are no longer advertising, clear HCI_LE_ADV */
60311f9d5657SArchie Pusaka 		hci_dev_clear_flag(hdev, HCI_LE_ADV);
6032728abc01SNiels Dossche 		goto unlock;
603323837a6dSLuiz Augusto von Dentz 	}
603423837a6dSLuiz Augusto von Dentz 
60357087c4f6SLuiz Augusto von Dentz 	if (adv)
60367087c4f6SLuiz Augusto von Dentz 		adv->enabled = false;
60377087c4f6SLuiz Augusto von Dentz 
6038acf0aeaeSJaganath Kanakkassery 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->conn_handle));
6039acf0aeaeSJaganath Kanakkassery 	if (conn) {
60407087c4f6SLuiz Augusto von Dentz 		/* Store handle in the connection so the correct advertising
60417087c4f6SLuiz Augusto von Dentz 		 * instance can be re-enabled when disconnected.
60427087c4f6SLuiz Augusto von Dentz 		 */
60437087c4f6SLuiz Augusto von Dentz 		conn->adv_instance = ev->handle;
6044acf0aeaeSJaganath Kanakkassery 
6045cafae4cdSLuiz Augusto von Dentz 		if (hdev->adv_addr_type != ADDR_LE_DEV_RANDOM ||
6046cafae4cdSLuiz Augusto von Dentz 		    bacmp(&conn->resp_addr, BDADDR_ANY))
6047728abc01SNiels Dossche 			goto unlock;
6048acf0aeaeSJaganath Kanakkassery 
604925e70886SDaniel Winkler 		if (!ev->handle) {
6050acf0aeaeSJaganath Kanakkassery 			bacpy(&conn->resp_addr, &hdev->random_addr);
6051728abc01SNiels Dossche 			goto unlock;
6052acf0aeaeSJaganath Kanakkassery 		}
6053acf0aeaeSJaganath Kanakkassery 
60547087c4f6SLuiz Augusto von Dentz 		if (adv)
60557087c4f6SLuiz Augusto von Dentz 			bacpy(&conn->resp_addr, &adv->random_addr);
6056acf0aeaeSJaganath Kanakkassery 	}
6057728abc01SNiels Dossche 
6058728abc01SNiels Dossche unlock:
6059728abc01SNiels Dossche 	hci_dev_unlock(hdev);
6060acf0aeaeSJaganath Kanakkassery }
6061acf0aeaeSJaganath Kanakkassery 
606295118dd4SLuiz Augusto von Dentz static void hci_le_conn_update_complete_evt(struct hci_dev *hdev, void *data,
60631855d92dSMarcel Holtmann 					    struct sk_buff *skb)
60641855d92dSMarcel Holtmann {
606595118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_conn_update_complete *ev = data;
60661855d92dSMarcel Holtmann 	struct hci_conn *conn;
60671855d92dSMarcel Holtmann 
606895118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
60691855d92dSMarcel Holtmann 
60701855d92dSMarcel Holtmann 	if (ev->status)
60711855d92dSMarcel Holtmann 		return;
60721855d92dSMarcel Holtmann 
60731855d92dSMarcel Holtmann 	hci_dev_lock(hdev);
60741855d92dSMarcel Holtmann 
60751855d92dSMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
60761855d92dSMarcel Holtmann 	if (conn) {
60771855d92dSMarcel Holtmann 		conn->le_conn_interval = le16_to_cpu(ev->interval);
60781855d92dSMarcel Holtmann 		conn->le_conn_latency = le16_to_cpu(ev->latency);
60791855d92dSMarcel Holtmann 		conn->le_supv_timeout = le16_to_cpu(ev->supervision_timeout);
60801855d92dSMarcel Holtmann 	}
60811855d92dSMarcel Holtmann 
60821855d92dSMarcel Holtmann 	hci_dev_unlock(hdev);
60831855d92dSMarcel Holtmann }
60841855d92dSMarcel Holtmann 
6085a4790dbdSAndre Guedes /* This function requires the caller holds hdev->lock */
6086fd45ada9SAlfonso Acosta static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev,
6087fd45ada9SAlfonso Acosta 					      bdaddr_t *addr,
6088d850bf08SLuiz Augusto von Dentz 					      u8 addr_type, bool addr_resolved,
60898e8b92eeSLuiz Augusto von Dentz 					      u8 adv_type)
6090a4790dbdSAndre Guedes {
6091a4790dbdSAndre Guedes 	struct hci_conn *conn;
60924b9e7e75SMarcel Holtmann 	struct hci_conn_params *params;
6093a4790dbdSAndre Guedes 
60941c1abcabSJohan Hedberg 	/* If the event is not connectable don't proceed further */
60951c1abcabSJohan Hedberg 	if (adv_type != LE_ADV_IND && adv_type != LE_ADV_DIRECT_IND)
6096fd45ada9SAlfonso Acosta 		return NULL;
60971c1abcabSJohan Hedberg 
6098182ee45dSLuiz Augusto von Dentz 	/* Ignore if the device is blocked or hdev is suspended */
6099182ee45dSLuiz Augusto von Dentz 	if (hci_bdaddr_list_lookup(&hdev->reject_list, addr, addr_type) ||
6100182ee45dSLuiz Augusto von Dentz 	    hdev->suspended)
6101fd45ada9SAlfonso Acosta 		return NULL;
61021c1abcabSJohan Hedberg 
6103f99353cfSJohan Hedberg 	/* Most controller will fail if we try to create new connections
610439bc74caSArchie Pusaka 	 * while we have an existing one in peripheral role.
6105f99353cfSJohan Hedberg 	 */
610639bc74caSArchie Pusaka 	if (hdev->conn_hash.le_num_peripheral > 0 &&
61074364f2e9SAlain Michaud 	    (!test_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks) ||
61084364f2e9SAlain Michaud 	     !(hdev->le_states[3] & 0x10)))
6109fd45ada9SAlfonso Acosta 		return NULL;
6110f99353cfSJohan Hedberg 
61111c1abcabSJohan Hedberg 	/* If we're not connectable only connect devices that we have in
61121c1abcabSJohan Hedberg 	 * our pend_le_conns list.
61131c1abcabSJohan Hedberg 	 */
611449c50922SJohan Hedberg 	params = hci_pend_le_action_lookup(&hdev->pend_le_conns, addr,
611549c50922SJohan Hedberg 					   addr_type);
61164b9e7e75SMarcel Holtmann 	if (!params)
6117fd45ada9SAlfonso Acosta 		return NULL;
6118a4790dbdSAndre Guedes 
611928a667c9SJakub Pawlowski 	if (!params->explicit_connect) {
61204b9e7e75SMarcel Holtmann 		switch (params->auto_connect) {
61214b9e7e75SMarcel Holtmann 		case HCI_AUTO_CONN_DIRECT:
61224b9e7e75SMarcel Holtmann 			/* Only devices advertising with ADV_DIRECT_IND are
61234b9e7e75SMarcel Holtmann 			 * triggering a connection attempt. This is allowing
612467ffb185SArchie Pusaka 			 * incoming connections from peripheral devices.
61254b9e7e75SMarcel Holtmann 			 */
61264b9e7e75SMarcel Holtmann 			if (adv_type != LE_ADV_DIRECT_IND)
6127fd45ada9SAlfonso Acosta 				return NULL;
61284b9e7e75SMarcel Holtmann 			break;
61294b9e7e75SMarcel Holtmann 		case HCI_AUTO_CONN_ALWAYS:
61304b9e7e75SMarcel Holtmann 			/* Devices advertising with ADV_IND or ADV_DIRECT_IND
61314b9e7e75SMarcel Holtmann 			 * are triggering a connection attempt. This means
613267ffb185SArchie Pusaka 			 * that incoming connections from peripheral device are
613367ffb185SArchie Pusaka 			 * accepted and also outgoing connections to peripheral
61344b9e7e75SMarcel Holtmann 			 * devices are established when found.
61354b9e7e75SMarcel Holtmann 			 */
61364b9e7e75SMarcel Holtmann 			break;
61374b9e7e75SMarcel Holtmann 		default:
6138fd45ada9SAlfonso Acosta 			return NULL;
61394b9e7e75SMarcel Holtmann 		}
614028a667c9SJakub Pawlowski 	}
61414b9e7e75SMarcel Holtmann 
6142d850bf08SLuiz Augusto von Dentz 	conn = hci_connect_le(hdev, addr, addr_type, addr_resolved,
6143d850bf08SLuiz Augusto von Dentz 			      BT_SECURITY_LOW, hdev->def_le_autoconnect_timeout,
61448e8b92eeSLuiz Augusto von Dentz 			      HCI_ROLE_MASTER);
6145f161dd41SJohan Hedberg 	if (!IS_ERR(conn)) {
614628a667c9SJakub Pawlowski 		/* If HCI_AUTO_CONN_EXPLICIT is set, conn is already owned
614728a667c9SJakub Pawlowski 		 * by higher layer that tried to connect, if no then
614828a667c9SJakub Pawlowski 		 * store the pointer since we don't really have any
6149f161dd41SJohan Hedberg 		 * other owner of the object besides the params that
6150f161dd41SJohan Hedberg 		 * triggered it. This way we can abort the connection if
6151f161dd41SJohan Hedberg 		 * the parameters get removed and keep the reference
6152f161dd41SJohan Hedberg 		 * count consistent once the connection is established.
6153f161dd41SJohan Hedberg 		 */
615428a667c9SJakub Pawlowski 
615528a667c9SJakub Pawlowski 		if (!params->explicit_connect)
6156f8aaf9b6SJohan Hedberg 			params->conn = hci_conn_get(conn);
615728a667c9SJakub Pawlowski 
6158fd45ada9SAlfonso Acosta 		return conn;
6159f161dd41SJohan Hedberg 	}
6160a4790dbdSAndre Guedes 
6161a4790dbdSAndre Guedes 	switch (PTR_ERR(conn)) {
6162a4790dbdSAndre Guedes 	case -EBUSY:
6163a4790dbdSAndre Guedes 		/* If hci_connect() returns -EBUSY it means there is already
6164a4790dbdSAndre Guedes 		 * an LE connection attempt going on. Since controllers don't
6165a4790dbdSAndre Guedes 		 * support more than one connection attempt at the time, we
6166a4790dbdSAndre Guedes 		 * don't consider this an error case.
6167a4790dbdSAndre Guedes 		 */
6168a4790dbdSAndre Guedes 		break;
6169a4790dbdSAndre Guedes 	default:
6170a4790dbdSAndre Guedes 		BT_DBG("Failed to connect: err %ld", PTR_ERR(conn));
6171fd45ada9SAlfonso Acosta 		return NULL;
6172a4790dbdSAndre Guedes 	}
6173fd45ada9SAlfonso Acosta 
6174fd45ada9SAlfonso Acosta 	return NULL;
6175a4790dbdSAndre Guedes }
6176a4790dbdSAndre Guedes 
61774af605d8SJohan Hedberg static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
61782f010b55SMarcel Holtmann 			       u8 bdaddr_type, bdaddr_t *direct_addr,
6179a2ec905dSAlain Michaud 			       u8 direct_addr_type, s8 rssi, u8 *data, u8 len,
6180b338d917SBrian Gix 			       bool ext_adv, bool ctl_time, u64 instant)
61814af605d8SJohan Hedberg {
6182b9a6328fSJohan Hedberg 	struct discovery_state *d = &hdev->discovery;
61831c1abcabSJohan Hedberg 	struct smp_irk *irk;
6184fd45ada9SAlfonso Acosta 	struct hci_conn *conn;
6185d850bf08SLuiz Augusto von Dentz 	bool match, bdaddr_resolved;
6186c70a7e4cSMarcel Holtmann 	u32 flags;
61871c58e933SSzymon Janc 	u8 *ptr;
61886818375eSSzymon Janc 
618956b40fbfSJohan Hedberg 	switch (type) {
619056b40fbfSJohan Hedberg 	case LE_ADV_IND:
619156b40fbfSJohan Hedberg 	case LE_ADV_DIRECT_IND:
619256b40fbfSJohan Hedberg 	case LE_ADV_SCAN_IND:
619356b40fbfSJohan Hedberg 	case LE_ADV_NONCONN_IND:
619456b40fbfSJohan Hedberg 	case LE_ADV_SCAN_RSP:
619556b40fbfSJohan Hedberg 		break;
619656b40fbfSJohan Hedberg 	default:
61972064ee33SMarcel Holtmann 		bt_dev_err_ratelimited(hdev, "unknown advertising packet "
61982064ee33SMarcel Holtmann 				       "type: 0x%02x", type);
619956b40fbfSJohan Hedberg 		return;
620056b40fbfSJohan Hedberg 	}
620156b40fbfSJohan Hedberg 
6202a2ec905dSAlain Michaud 	if (!ext_adv && len > HCI_MAX_AD_LENGTH) {
6203a2ec905dSAlain Michaud 		bt_dev_err_ratelimited(hdev, "legacy adv larger than 31 bytes");
6204a2ec905dSAlain Michaud 		return;
6205a2ec905dSAlain Michaud 	}
6206a2ec905dSAlain Michaud 
62076818375eSSzymon Janc 	/* Find the end of the data in case the report contains padded zero
62086818375eSSzymon Janc 	 * bytes at the end causing an invalid length value.
62096818375eSSzymon Janc 	 *
62106818375eSSzymon Janc 	 * When data is NULL, len is 0 so there is no need for extra ptr
62116818375eSSzymon Janc 	 * check as 'ptr < data + 0' is already false in such case.
62126818375eSSzymon Janc 	 */
62136818375eSSzymon Janc 	for (ptr = data; ptr < data + len && *ptr; ptr += *ptr + 1) {
62146818375eSSzymon Janc 		if (ptr + 1 + *ptr > data + len)
62156818375eSSzymon Janc 			break;
62166818375eSSzymon Janc 	}
62176818375eSSzymon Janc 
62181c58e933SSzymon Janc 	/* Adjust for actual length. This handles the case when remote
62191c58e933SSzymon Janc 	 * device is advertising with incorrect data length.
62201c58e933SSzymon Janc 	 */
62211c58e933SSzymon Janc 	len = ptr - data;
6222b9a6328fSJohan Hedberg 
62232f010b55SMarcel Holtmann 	/* If the direct address is present, then this report is from
62242f010b55SMarcel Holtmann 	 * a LE Direct Advertising Report event. In that case it is
62252f010b55SMarcel Holtmann 	 * important to see if the address is matching the local
62262f010b55SMarcel Holtmann 	 * controller address.
62272f010b55SMarcel Holtmann 	 */
6228b338d917SBrian Gix 	if (!hci_dev_test_flag(hdev, HCI_MESH) && direct_addr) {
6229d850bf08SLuiz Augusto von Dentz 		direct_addr_type = ev_bdaddr_type(hdev, direct_addr_type,
6230d850bf08SLuiz Augusto von Dentz 						  &bdaddr_resolved);
62314ec4d63bSLuiz Augusto von Dentz 
62322f010b55SMarcel Holtmann 		/* Only resolvable random addresses are valid for these
62332f010b55SMarcel Holtmann 		 * kind of reports and others can be ignored.
62342f010b55SMarcel Holtmann 		 */
62352f010b55SMarcel Holtmann 		if (!hci_bdaddr_is_rpa(direct_addr, direct_addr_type))
62362f010b55SMarcel Holtmann 			return;
62372f010b55SMarcel Holtmann 
62382f010b55SMarcel Holtmann 		/* If the controller is not using resolvable random
62392f010b55SMarcel Holtmann 		 * addresses, then this report can be ignored.
62402f010b55SMarcel Holtmann 		 */
6241d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_PRIVACY))
62422f010b55SMarcel Holtmann 			return;
62432f010b55SMarcel Holtmann 
62442f010b55SMarcel Holtmann 		/* If the local IRK of the controller does not match
62452f010b55SMarcel Holtmann 		 * with the resolvable random address provided, then
62462f010b55SMarcel Holtmann 		 * this report can be ignored.
62472f010b55SMarcel Holtmann 		 */
62482f010b55SMarcel Holtmann 		if (!smp_irk_matches(hdev, hdev->irk, direct_addr))
62492f010b55SMarcel Holtmann 			return;
62502f010b55SMarcel Holtmann 	}
62512f010b55SMarcel Holtmann 
6252435a13d8SJohan Hedberg 	/* Check if we need to convert to identity address */
6253435a13d8SJohan Hedberg 	irk = hci_get_irk(hdev, bdaddr, bdaddr_type);
6254435a13d8SJohan Hedberg 	if (irk) {
6255435a13d8SJohan Hedberg 		bdaddr = &irk->bdaddr;
6256435a13d8SJohan Hedberg 		bdaddr_type = irk->addr_type;
6257435a13d8SJohan Hedberg 	}
6258435a13d8SJohan Hedberg 
6259d850bf08SLuiz Augusto von Dentz 	bdaddr_type = ev_bdaddr_type(hdev, bdaddr_type, &bdaddr_resolved);
62604ec4d63bSLuiz Augusto von Dentz 
6261082f2300SSzymon Janc 	/* Check if we have been requested to connect to this device.
6262082f2300SSzymon Janc 	 *
6263082f2300SSzymon Janc 	 * direct_addr is set only for directed advertising reports (it is NULL
6264082f2300SSzymon Janc 	 * for advertising reports) and is already verified to be RPA above.
6265082f2300SSzymon Janc 	 */
6266d850bf08SLuiz Augusto von Dentz 	conn = check_pending_le_conn(hdev, bdaddr, bdaddr_type, bdaddr_resolved,
62678e8b92eeSLuiz Augusto von Dentz 				     type);
6268a2ec905dSAlain Michaud 	if (!ext_adv && conn && type == LE_ADV_IND && len <= HCI_MAX_AD_LENGTH) {
6269fd45ada9SAlfonso Acosta 		/* Store report for later inclusion by
6270fd45ada9SAlfonso Acosta 		 * mgmt_device_connected
6271fd45ada9SAlfonso Acosta 		 */
6272fd45ada9SAlfonso Acosta 		memcpy(conn->le_adv_data, data, len);
6273fd45ada9SAlfonso Acosta 		conn->le_adv_data_len = len;
6274fd45ada9SAlfonso Acosta 	}
627599a6768eSJohan Hedberg 
6276b338d917SBrian Gix 	if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND)
6277b338d917SBrian Gix 		flags = MGMT_DEV_FOUND_NOT_CONNECTABLE;
6278b338d917SBrian Gix 	else
6279b338d917SBrian Gix 		flags = 0;
6280b338d917SBrian Gix 
6281b338d917SBrian Gix 	/* All scan results should be sent up for Mesh systems */
6282b338d917SBrian Gix 	if (hci_dev_test_flag(hdev, HCI_MESH)) {
6283b338d917SBrian Gix 		mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
6284b338d917SBrian Gix 				  rssi, flags, data, len, NULL, 0, instant);
6285b338d917SBrian Gix 		return;
6286b338d917SBrian Gix 	}
6287b338d917SBrian Gix 
62881c1abcabSJohan Hedberg 	/* Passive scanning shouldn't trigger any device found events,
62891c1abcabSJohan Hedberg 	 * except for devices marked as CONN_REPORT for which we do send
62908208f5a9SMiao-chen Chou 	 * device found events, or advertisement monitoring requested.
62911c1abcabSJohan Hedberg 	 */
62921c1abcabSJohan Hedberg 	if (hdev->le_scan_type == LE_SCAN_PASSIVE) {
62930d2bf134SJohan Hedberg 		if (type == LE_ADV_DIRECT_IND)
62940d2bf134SJohan Hedberg 			return;
62950d2bf134SJohan Hedberg 
62963a19b6feSJohan Hedberg 		if (!hci_pend_le_action_lookup(&hdev->pend_le_reports,
62978208f5a9SMiao-chen Chou 					       bdaddr, bdaddr_type) &&
62988208f5a9SMiao-chen Chou 		    idr_is_empty(&hdev->adv_monitors_idr))
62990d2bf134SJohan Hedberg 			return;
63000d2bf134SJohan Hedberg 
63010d2bf134SJohan Hedberg 		mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
6302b338d917SBrian Gix 				  rssi, flags, data, len, NULL, 0, 0);
630397bf2e99SJohan Hedberg 		return;
6304ca5c4be7SJohan Hedberg 	}
63054af605d8SJohan Hedberg 
6306c70a7e4cSMarcel Holtmann 	/* When receiving non-connectable or scannable undirected
6307c70a7e4cSMarcel Holtmann 	 * advertising reports, this means that the remote device is
6308c70a7e4cSMarcel Holtmann 	 * not connectable and then clearly indicate this in the
6309c70a7e4cSMarcel Holtmann 	 * device found event.
6310c70a7e4cSMarcel Holtmann 	 *
6311c70a7e4cSMarcel Holtmann 	 * When receiving a scan response, then there is no way to
6312c70a7e4cSMarcel Holtmann 	 * know if the remote device is connectable or not. However
6313c70a7e4cSMarcel Holtmann 	 * since scan responses are merged with a previously seen
6314c70a7e4cSMarcel Holtmann 	 * advertising report, the flags field from that report
6315c70a7e4cSMarcel Holtmann 	 * will be used.
6316c70a7e4cSMarcel Holtmann 	 *
6317c70a7e4cSMarcel Holtmann 	 * In the really unlikely case that a controller get confused
6318c70a7e4cSMarcel Holtmann 	 * and just sends a scan response event, then it is marked as
6319c70a7e4cSMarcel Holtmann 	 * not connectable as well.
6320c70a7e4cSMarcel Holtmann 	 */
6321b338d917SBrian Gix 	if (type == LE_ADV_SCAN_RSP)
6322c70a7e4cSMarcel Holtmann 		flags = MGMT_DEV_FOUND_NOT_CONNECTABLE;
6323c70a7e4cSMarcel Holtmann 
6324b9a6328fSJohan Hedberg 	/* If there's nothing pending either store the data from this
6325b9a6328fSJohan Hedberg 	 * event or send an immediate device found event if the data
6326b9a6328fSJohan Hedberg 	 * should not be stored for later.
6327b9a6328fSJohan Hedberg 	 */
6328a2ec905dSAlain Michaud 	if (!ext_adv &&	!has_pending_adv_report(hdev)) {
6329b9a6328fSJohan Hedberg 		/* If the report will trigger a SCAN_REQ store it for
6330b9a6328fSJohan Hedberg 		 * later merging.
6331b9a6328fSJohan Hedberg 		 */
6332b9a6328fSJohan Hedberg 		if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) {
6333b9a6328fSJohan Hedberg 			store_pending_adv_report(hdev, bdaddr, bdaddr_type,
6334c70a7e4cSMarcel Holtmann 						 rssi, flags, data, len);
6335b9a6328fSJohan Hedberg 			return;
6336b9a6328fSJohan Hedberg 		}
6337b9a6328fSJohan Hedberg 
6338b9a6328fSJohan Hedberg 		mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
6339b338d917SBrian Gix 				  rssi, flags, data, len, NULL, 0, 0);
6340b9a6328fSJohan Hedberg 		return;
6341b9a6328fSJohan Hedberg 	}
6342b9a6328fSJohan Hedberg 
6343474ee066SJohan Hedberg 	/* Check if the pending report is for the same device as the new one */
6344474ee066SJohan Hedberg 	match = (!bacmp(bdaddr, &d->last_adv_addr) &&
6345474ee066SJohan Hedberg 		 bdaddr_type == d->last_adv_addr_type);
6346474ee066SJohan Hedberg 
6347b9a6328fSJohan Hedberg 	/* If the pending data doesn't match this report or this isn't a
6348b9a6328fSJohan Hedberg 	 * scan response (e.g. we got a duplicate ADV_IND) then force
6349b9a6328fSJohan Hedberg 	 * sending of the pending data.
6350b9a6328fSJohan Hedberg 	 */
6351474ee066SJohan Hedberg 	if (type != LE_ADV_SCAN_RSP || !match) {
6352474ee066SJohan Hedberg 		/* Send out whatever is in the cache, but skip duplicates */
6353474ee066SJohan Hedberg 		if (!match)
6354b9a6328fSJohan Hedberg 			mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
6355ff5cd29fSJohan Hedberg 					  d->last_adv_addr_type, NULL,
6356c70a7e4cSMarcel Holtmann 					  d->last_adv_rssi, d->last_adv_flags,
6357ff5cd29fSJohan Hedberg 					  d->last_adv_data,
6358b338d917SBrian Gix 					  d->last_adv_data_len, NULL, 0, 0);
6359b9a6328fSJohan Hedberg 
6360b9a6328fSJohan Hedberg 		/* If the new report will trigger a SCAN_REQ store it for
6361b9a6328fSJohan Hedberg 		 * later merging.
6362b9a6328fSJohan Hedberg 		 */
6363a2ec905dSAlain Michaud 		if (!ext_adv && (type == LE_ADV_IND ||
6364a2ec905dSAlain Michaud 				 type == LE_ADV_SCAN_IND)) {
6365b9a6328fSJohan Hedberg 			store_pending_adv_report(hdev, bdaddr, bdaddr_type,
6366c70a7e4cSMarcel Holtmann 						 rssi, flags, data, len);
6367b9a6328fSJohan Hedberg 			return;
6368b9a6328fSJohan Hedberg 		}
6369b9a6328fSJohan Hedberg 
6370b9a6328fSJohan Hedberg 		/* The advertising reports cannot be merged, so clear
6371b9a6328fSJohan Hedberg 		 * the pending report and send out a device found event.
6372b9a6328fSJohan Hedberg 		 */
6373b9a6328fSJohan Hedberg 		clear_pending_adv_report(hdev);
63745c5b93e4SJohan Hedberg 		mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
6375b338d917SBrian Gix 				  rssi, flags, data, len, NULL, 0, 0);
6376b9a6328fSJohan Hedberg 		return;
6377b9a6328fSJohan Hedberg 	}
6378b9a6328fSJohan Hedberg 
6379b9a6328fSJohan Hedberg 	/* If we get here we've got a pending ADV_IND or ADV_SCAN_IND and
6380b9a6328fSJohan Hedberg 	 * the new event is a SCAN_RSP. We can therefore proceed with
6381b9a6328fSJohan Hedberg 	 * sending a merged device found event.
6382b9a6328fSJohan Hedberg 	 */
6383b9a6328fSJohan Hedberg 	mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
6384c70a7e4cSMarcel Holtmann 			  d->last_adv_addr_type, NULL, rssi, d->last_adv_flags,
6385b338d917SBrian Gix 			  d->last_adv_data, d->last_adv_data_len, data, len, 0);
6386b9a6328fSJohan Hedberg 	clear_pending_adv_report(hdev);
63874af605d8SJohan Hedberg }
63884af605d8SJohan Hedberg 
638995118dd4SLuiz Augusto von Dentz static void hci_le_adv_report_evt(struct hci_dev *hdev, void *data,
639095118dd4SLuiz Augusto von Dentz 				  struct sk_buff *skb)
63919aa04c91SAndre Guedes {
639295118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_advertising_report *ev = data;
6393b338d917SBrian Gix 	u64 instant = jiffies;
639447afe93cSLuiz Augusto von Dentz 
639547afe93cSLuiz Augusto von Dentz 	if (!ev->num)
639647afe93cSLuiz Augusto von Dentz 		return;
63979aa04c91SAndre Guedes 
6398a4790dbdSAndre Guedes 	hci_dev_lock(hdev);
6399a4790dbdSAndre Guedes 
640047afe93cSLuiz Augusto von Dentz 	while (ev->num--) {
640147afe93cSLuiz Augusto von Dentz 		struct hci_ev_le_advertising_info *info;
64024af605d8SJohan Hedberg 		s8 rssi;
6403a4790dbdSAndre Guedes 
640447afe93cSLuiz Augusto von Dentz 		info = hci_le_ev_skb_pull(hdev, skb,
640547afe93cSLuiz Augusto von Dentz 					  HCI_EV_LE_ADVERTISING_REPORT,
640647afe93cSLuiz Augusto von Dentz 					  sizeof(*info));
640747afe93cSLuiz Augusto von Dentz 		if (!info)
6408899663beSBrian Gix 			break;
6409899663beSBrian Gix 
641047afe93cSLuiz Augusto von Dentz 		if (!hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_ADVERTISING_REPORT,
641147afe93cSLuiz Augusto von Dentz 					info->length + 1))
641247afe93cSLuiz Augusto von Dentz 			break;
641347afe93cSLuiz Augusto von Dentz 
641447afe93cSLuiz Augusto von Dentz 		if (info->length <= HCI_MAX_AD_LENGTH) {
641547afe93cSLuiz Augusto von Dentz 			rssi = info->data[info->length];
641647afe93cSLuiz Augusto von Dentz 			process_adv_report(hdev, info->type, &info->bdaddr,
641747afe93cSLuiz Augusto von Dentz 					   info->bdaddr_type, NULL, 0, rssi,
6418b338d917SBrian Gix 					   info->data, info->length, false,
6419b338d917SBrian Gix 					   false, instant);
6420ee649346SChriz Chow 		} else {
6421ee649346SChriz Chow 			bt_dev_err(hdev, "Dropping invalid advertising data");
6422ee649346SChriz Chow 		}
64239aa04c91SAndre Guedes 	}
6424a4790dbdSAndre Guedes 
6425a4790dbdSAndre Guedes 	hci_dev_unlock(hdev);
64269aa04c91SAndre Guedes }
64279aa04c91SAndre Guedes 
6428657cc646SMarcel Holtmann static u8 ext_evt_type_to_legacy(struct hci_dev *hdev, u16 evt_type)
6429c215e939SJaganath Kanakkassery {
6430b2cc9761SJaganath Kanakkassery 	if (evt_type & LE_EXT_ADV_LEGACY_PDU) {
6431c215e939SJaganath Kanakkassery 		switch (evt_type) {
6432c215e939SJaganath Kanakkassery 		case LE_LEGACY_ADV_IND:
6433c215e939SJaganath Kanakkassery 			return LE_ADV_IND;
6434c215e939SJaganath Kanakkassery 		case LE_LEGACY_ADV_DIRECT_IND:
6435c215e939SJaganath Kanakkassery 			return LE_ADV_DIRECT_IND;
6436c215e939SJaganath Kanakkassery 		case LE_LEGACY_ADV_SCAN_IND:
6437c215e939SJaganath Kanakkassery 			return LE_ADV_SCAN_IND;
6438c215e939SJaganath Kanakkassery 		case LE_LEGACY_NONCONN_IND:
6439c215e939SJaganath Kanakkassery 			return LE_ADV_NONCONN_IND;
6440c215e939SJaganath Kanakkassery 		case LE_LEGACY_SCAN_RSP_ADV:
6441c215e939SJaganath Kanakkassery 		case LE_LEGACY_SCAN_RSP_ADV_SCAN:
6442c215e939SJaganath Kanakkassery 			return LE_ADV_SCAN_RSP;
6443c215e939SJaganath Kanakkassery 		}
6444c215e939SJaganath Kanakkassery 
6445657cc646SMarcel Holtmann 		goto invalid;
6446c215e939SJaganath Kanakkassery 	}
6447c215e939SJaganath Kanakkassery 
6448b2cc9761SJaganath Kanakkassery 	if (evt_type & LE_EXT_ADV_CONN_IND) {
6449b2cc9761SJaganath Kanakkassery 		if (evt_type & LE_EXT_ADV_DIRECT_IND)
6450b2cc9761SJaganath Kanakkassery 			return LE_ADV_DIRECT_IND;
6451b2cc9761SJaganath Kanakkassery 
6452b2cc9761SJaganath Kanakkassery 		return LE_ADV_IND;
6453b2cc9761SJaganath Kanakkassery 	}
6454b2cc9761SJaganath Kanakkassery 
6455b2cc9761SJaganath Kanakkassery 	if (evt_type & LE_EXT_ADV_SCAN_RSP)
6456b2cc9761SJaganath Kanakkassery 		return LE_ADV_SCAN_RSP;
6457b2cc9761SJaganath Kanakkassery 
6458b2cc9761SJaganath Kanakkassery 	if (evt_type & LE_EXT_ADV_SCAN_IND)
6459b2cc9761SJaganath Kanakkassery 		return LE_ADV_SCAN_IND;
6460b2cc9761SJaganath Kanakkassery 
6461b2cc9761SJaganath Kanakkassery 	if (evt_type == LE_EXT_ADV_NON_CONN_IND ||
6462b2cc9761SJaganath Kanakkassery 	    evt_type & LE_EXT_ADV_DIRECT_IND)
6463b2cc9761SJaganath Kanakkassery 		return LE_ADV_NONCONN_IND;
6464b2cc9761SJaganath Kanakkassery 
6465657cc646SMarcel Holtmann invalid:
6466657cc646SMarcel Holtmann 	bt_dev_err_ratelimited(hdev, "Unknown advertising packet type: 0x%02x",
6467b2cc9761SJaganath Kanakkassery 			       evt_type);
6468b2cc9761SJaganath Kanakkassery 
6469b2cc9761SJaganath Kanakkassery 	return LE_ADV_INVALID;
6470b2cc9761SJaganath Kanakkassery }
6471b2cc9761SJaganath Kanakkassery 
647295118dd4SLuiz Augusto von Dentz static void hci_le_ext_adv_report_evt(struct hci_dev *hdev, void *data,
647395118dd4SLuiz Augusto von Dentz 				      struct sk_buff *skb)
6474c215e939SJaganath Kanakkassery {
647595118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_ext_adv_report *ev = data;
6476b338d917SBrian Gix 	u64 instant = jiffies;
6477b48b833fSLuiz Augusto von Dentz 
6478b48b833fSLuiz Augusto von Dentz 	if (!ev->num)
6479b48b833fSLuiz Augusto von Dentz 		return;
6480c215e939SJaganath Kanakkassery 
6481c215e939SJaganath Kanakkassery 	hci_dev_lock(hdev);
6482c215e939SJaganath Kanakkassery 
6483b48b833fSLuiz Augusto von Dentz 	while (ev->num--) {
6484b48b833fSLuiz Augusto von Dentz 		struct hci_ev_le_ext_adv_info *info;
6485c215e939SJaganath Kanakkassery 		u8 legacy_evt_type;
6486c215e939SJaganath Kanakkassery 		u16 evt_type;
6487c215e939SJaganath Kanakkassery 
6488b48b833fSLuiz Augusto von Dentz 		info = hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_EXT_ADV_REPORT,
6489b48b833fSLuiz Augusto von Dentz 					  sizeof(*info));
6490b48b833fSLuiz Augusto von Dentz 		if (!info)
6491b48b833fSLuiz Augusto von Dentz 			break;
6492b48b833fSLuiz Augusto von Dentz 
6493b48b833fSLuiz Augusto von Dentz 		if (!hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_EXT_ADV_REPORT,
6494b48b833fSLuiz Augusto von Dentz 					info->length))
6495b48b833fSLuiz Augusto von Dentz 			break;
6496b48b833fSLuiz Augusto von Dentz 
6497*ad38e55eSSven Peter 		evt_type = __le16_to_cpu(info->type) & LE_EXT_ADV_EVT_TYPE_MASK;
6498657cc646SMarcel Holtmann 		legacy_evt_type = ext_evt_type_to_legacy(hdev, evt_type);
6499c215e939SJaganath Kanakkassery 		if (legacy_evt_type != LE_ADV_INVALID) {
6500b48b833fSLuiz Augusto von Dentz 			process_adv_report(hdev, legacy_evt_type, &info->bdaddr,
6501b48b833fSLuiz Augusto von Dentz 					   info->bdaddr_type, NULL, 0,
6502b48b833fSLuiz Augusto von Dentz 					   info->rssi, info->data, info->length,
6503b338d917SBrian Gix 					   !(evt_type & LE_EXT_ADV_LEGACY_PDU),
6504b338d917SBrian Gix 					   false, instant);
6505c215e939SJaganath Kanakkassery 		}
6506c215e939SJaganath Kanakkassery 	}
6507c215e939SJaganath Kanakkassery 
6508c215e939SJaganath Kanakkassery 	hci_dev_unlock(hdev);
6509c215e939SJaganath Kanakkassery }
6510c215e939SJaganath Kanakkassery 
6511eca0ae4aSLuiz Augusto von Dentz static int hci_le_pa_term_sync(struct hci_dev *hdev, __le16 handle)
6512eca0ae4aSLuiz Augusto von Dentz {
6513eca0ae4aSLuiz Augusto von Dentz 	struct hci_cp_le_pa_term_sync cp;
6514eca0ae4aSLuiz Augusto von Dentz 
6515eca0ae4aSLuiz Augusto von Dentz 	memset(&cp, 0, sizeof(cp));
6516eca0ae4aSLuiz Augusto von Dentz 	cp.handle = handle;
6517eca0ae4aSLuiz Augusto von Dentz 
6518eca0ae4aSLuiz Augusto von Dentz 	return hci_send_cmd(hdev, HCI_OP_LE_PA_TERM_SYNC, sizeof(cp), &cp);
6519eca0ae4aSLuiz Augusto von Dentz }
6520eca0ae4aSLuiz Augusto von Dentz 
6521eca0ae4aSLuiz Augusto von Dentz static void hci_le_pa_sync_estabilished_evt(struct hci_dev *hdev, void *data,
6522eca0ae4aSLuiz Augusto von Dentz 					    struct sk_buff *skb)
6523eca0ae4aSLuiz Augusto von Dentz {
6524eca0ae4aSLuiz Augusto von Dentz 	struct hci_ev_le_pa_sync_established *ev = data;
6525eca0ae4aSLuiz Augusto von Dentz 	int mask = hdev->link_mode;
6526eca0ae4aSLuiz Augusto von Dentz 	__u8 flags = 0;
6527eca0ae4aSLuiz Augusto von Dentz 
6528eca0ae4aSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
6529eca0ae4aSLuiz Augusto von Dentz 
6530eca0ae4aSLuiz Augusto von Dentz 	if (ev->status)
6531eca0ae4aSLuiz Augusto von Dentz 		return;
6532eca0ae4aSLuiz Augusto von Dentz 
6533eca0ae4aSLuiz Augusto von Dentz 	hci_dev_lock(hdev);
6534eca0ae4aSLuiz Augusto von Dentz 
6535eca0ae4aSLuiz Augusto von Dentz 	hci_dev_clear_flag(hdev, HCI_PA_SYNC);
6536eca0ae4aSLuiz Augusto von Dentz 
6537eca0ae4aSLuiz Augusto von Dentz 	mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ISO_LINK, &flags);
6538eca0ae4aSLuiz Augusto von Dentz 	if (!(mask & HCI_LM_ACCEPT))
6539eca0ae4aSLuiz Augusto von Dentz 		hci_le_pa_term_sync(hdev, ev->handle);
6540eca0ae4aSLuiz Augusto von Dentz 
6541eca0ae4aSLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
6542eca0ae4aSLuiz Augusto von Dentz }
6543eca0ae4aSLuiz Augusto von Dentz 
654495118dd4SLuiz Augusto von Dentz static void hci_le_remote_feat_complete_evt(struct hci_dev *hdev, void *data,
65450fe29fd1SMarcel Holtmann 					    struct sk_buff *skb)
65460fe29fd1SMarcel Holtmann {
654795118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_remote_feat_complete *ev = data;
65480fe29fd1SMarcel Holtmann 	struct hci_conn *conn;
65490fe29fd1SMarcel Holtmann 
655095118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
65510fe29fd1SMarcel Holtmann 
65520fe29fd1SMarcel Holtmann 	hci_dev_lock(hdev);
65530fe29fd1SMarcel Holtmann 
65540fe29fd1SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
65550fe29fd1SMarcel Holtmann 	if (conn) {
65560fe29fd1SMarcel Holtmann 		if (!ev->status)
65570fe29fd1SMarcel Holtmann 			memcpy(conn->features[0], ev->features, 8);
65580fe29fd1SMarcel Holtmann 
65590fe29fd1SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
65600fe29fd1SMarcel Holtmann 			__u8 status;
65610fe29fd1SMarcel Holtmann 
6562ef365da1SArchie Pusaka 			/* If the local controller supports peripheral-initiated
65630fe29fd1SMarcel Holtmann 			 * features exchange, but the remote controller does
65640fe29fd1SMarcel Holtmann 			 * not, then it is possible that the error code 0x1a
65650fe29fd1SMarcel Holtmann 			 * for unsupported remote feature gets returned.
65660fe29fd1SMarcel Holtmann 			 *
65670fe29fd1SMarcel Holtmann 			 * In this specific case, allow the connection to
65680fe29fd1SMarcel Holtmann 			 * transition into connected state and mark it as
65690fe29fd1SMarcel Holtmann 			 * successful.
65700fe29fd1SMarcel Holtmann 			 */
6571ef365da1SArchie Pusaka 			if (!conn->out && ev->status == 0x1a &&
6572ef365da1SArchie Pusaka 			    (hdev->le_features[0] & HCI_LE_PERIPHERAL_FEATURES))
65730fe29fd1SMarcel Holtmann 				status = 0x00;
65740fe29fd1SMarcel Holtmann 			else
65750fe29fd1SMarcel Holtmann 				status = ev->status;
65760fe29fd1SMarcel Holtmann 
65770fe29fd1SMarcel Holtmann 			conn->state = BT_CONNECTED;
65780fe29fd1SMarcel Holtmann 			hci_connect_cfm(conn, status);
65790fe29fd1SMarcel Holtmann 			hci_conn_drop(conn);
65800fe29fd1SMarcel Holtmann 		}
65810fe29fd1SMarcel Holtmann 	}
65820fe29fd1SMarcel Holtmann 
65830fe29fd1SMarcel Holtmann 	hci_dev_unlock(hdev);
65840fe29fd1SMarcel Holtmann }
65850fe29fd1SMarcel Holtmann 
658695118dd4SLuiz Augusto von Dentz static void hci_le_ltk_request_evt(struct hci_dev *hdev, void *data,
658795118dd4SLuiz Augusto von Dentz 				   struct sk_buff *skb)
6588a7a595f6SVinicius Costa Gomes {
658995118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_ltk_req *ev = data;
6590a7a595f6SVinicius Costa Gomes 	struct hci_cp_le_ltk_reply cp;
6591bea710feSVinicius Costa Gomes 	struct hci_cp_le_ltk_neg_reply neg;
6592a7a595f6SVinicius Costa Gomes 	struct hci_conn *conn;
6593c9839a11SVinicius Costa Gomes 	struct smp_ltk *ltk;
6594a7a595f6SVinicius Costa Gomes 
659595118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "handle 0x%4.4x", __le16_to_cpu(ev->handle));
6596a7a595f6SVinicius Costa Gomes 
6597a7a595f6SVinicius Costa Gomes 	hci_dev_lock(hdev);
6598a7a595f6SVinicius Costa Gomes 
6599a7a595f6SVinicius Costa Gomes 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
6600bea710feSVinicius Costa Gomes 	if (conn == NULL)
6601bea710feSVinicius Costa Gomes 		goto not_found;
6602a7a595f6SVinicius Costa Gomes 
6603f3a73d97SJohan Hedberg 	ltk = hci_find_ltk(hdev, &conn->dst, conn->dst_type, conn->role);
66045378bc56SJohan Hedberg 	if (!ltk)
6605bea710feSVinicius Costa Gomes 		goto not_found;
6606bea710feSVinicius Costa Gomes 
66075378bc56SJohan Hedberg 	if (smp_ltk_is_sc(ltk)) {
66085378bc56SJohan Hedberg 		/* With SC both EDiv and Rand are set to zero */
66095378bc56SJohan Hedberg 		if (ev->ediv || ev->rand)
66105378bc56SJohan Hedberg 			goto not_found;
66115378bc56SJohan Hedberg 	} else {
66125378bc56SJohan Hedberg 		/* For non-SC keys check that EDiv and Rand match */
66135378bc56SJohan Hedberg 		if (ev->ediv != ltk->ediv || ev->rand != ltk->rand)
66145378bc56SJohan Hedberg 			goto not_found;
66155378bc56SJohan Hedberg 	}
66165378bc56SJohan Hedberg 
66178b76ce34SJohan Hedberg 	memcpy(cp.ltk, ltk->val, ltk->enc_size);
66188b76ce34SJohan Hedberg 	memset(cp.ltk + ltk->enc_size, 0, sizeof(cp.ltk) - ltk->enc_size);
6619a7a595f6SVinicius Costa Gomes 	cp.handle = cpu_to_le16(conn->handle);
6620c9839a11SVinicius Costa Gomes 
6621a6f7833cSJohan Hedberg 	conn->pending_sec_level = smp_ltk_sec_level(ltk);
6622a7a595f6SVinicius Costa Gomes 
662389cbb4daSAndre Guedes 	conn->enc_key_size = ltk->enc_size;
6624a7a595f6SVinicius Costa Gomes 
6625a7a595f6SVinicius Costa Gomes 	hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
6626a7a595f6SVinicius Costa Gomes 
66275981a882SClaudio Takahasi 	/* Ref. Bluetooth Core SPEC pages 1975 and 2004. STK is a
66285981a882SClaudio Takahasi 	 * temporary key used to encrypt a connection following
66295981a882SClaudio Takahasi 	 * pairing. It is used during the Encrypted Session Setup to
66305981a882SClaudio Takahasi 	 * distribute the keys. Later, security can be re-established
66315981a882SClaudio Takahasi 	 * using a distributed LTK.
66325981a882SClaudio Takahasi 	 */
66332ceba539SJohan Hedberg 	if (ltk->type == SMP_STK) {
6634fe59a05fSJohan Hedberg 		set_bit(HCI_CONN_STK_ENCRYPT, &conn->flags);
6635970d0f1bSJohan Hedberg 		list_del_rcu(&ltk->list);
6636970d0f1bSJohan Hedberg 		kfree_rcu(ltk, rcu);
6637fe59a05fSJohan Hedberg 	} else {
6638fe59a05fSJohan Hedberg 		clear_bit(HCI_CONN_STK_ENCRYPT, &conn->flags);
6639c9839a11SVinicius Costa Gomes 	}
6640c9839a11SVinicius Costa Gomes 
6641a7a595f6SVinicius Costa Gomes 	hci_dev_unlock(hdev);
6642bea710feSVinicius Costa Gomes 
6643bea710feSVinicius Costa Gomes 	return;
6644bea710feSVinicius Costa Gomes 
6645bea710feSVinicius Costa Gomes not_found:
6646bea710feSVinicius Costa Gomes 	neg.handle = ev->handle;
6647bea710feSVinicius Costa Gomes 	hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
6648bea710feSVinicius Costa Gomes 	hci_dev_unlock(hdev);
6649a7a595f6SVinicius Costa Gomes }
6650a7a595f6SVinicius Costa Gomes 
66518e75b46aSAndre Guedes static void send_conn_param_neg_reply(struct hci_dev *hdev, u16 handle,
66528e75b46aSAndre Guedes 				      u8 reason)
66538e75b46aSAndre Guedes {
66548e75b46aSAndre Guedes 	struct hci_cp_le_conn_param_req_neg_reply cp;
66558e75b46aSAndre Guedes 
66568e75b46aSAndre Guedes 	cp.handle = cpu_to_le16(handle);
66578e75b46aSAndre Guedes 	cp.reason = reason;
66588e75b46aSAndre Guedes 
66598e75b46aSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY, sizeof(cp),
66608e75b46aSAndre Guedes 		     &cp);
66618e75b46aSAndre Guedes }
66628e75b46aSAndre Guedes 
666395118dd4SLuiz Augusto von Dentz static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev, void *data,
66648e75b46aSAndre Guedes 					     struct sk_buff *skb)
66658e75b46aSAndre Guedes {
666695118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_remote_conn_param_req *ev = data;
66678e75b46aSAndre Guedes 	struct hci_cp_le_conn_param_req_reply cp;
66688e75b46aSAndre Guedes 	struct hci_conn *hcon;
66698e75b46aSAndre Guedes 	u16 handle, min, max, latency, timeout;
66708e75b46aSAndre Guedes 
667195118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "handle 0x%4.4x", __le16_to_cpu(ev->handle));
667212cfe417SLuiz Augusto von Dentz 
66738e75b46aSAndre Guedes 	handle = le16_to_cpu(ev->handle);
66748e75b46aSAndre Guedes 	min = le16_to_cpu(ev->interval_min);
66758e75b46aSAndre Guedes 	max = le16_to_cpu(ev->interval_max);
66768e75b46aSAndre Guedes 	latency = le16_to_cpu(ev->latency);
66778e75b46aSAndre Guedes 	timeout = le16_to_cpu(ev->timeout);
66788e75b46aSAndre Guedes 
66798e75b46aSAndre Guedes 	hcon = hci_conn_hash_lookup_handle(hdev, handle);
66808e75b46aSAndre Guedes 	if (!hcon || hcon->state != BT_CONNECTED)
66818e75b46aSAndre Guedes 		return send_conn_param_neg_reply(hdev, handle,
66828e75b46aSAndre Guedes 						 HCI_ERROR_UNKNOWN_CONN_ID);
66838e75b46aSAndre Guedes 
66848e75b46aSAndre Guedes 	if (hci_check_conn_params(min, max, latency, timeout))
66858e75b46aSAndre Guedes 		return send_conn_param_neg_reply(hdev, handle,
66868e75b46aSAndre Guedes 						 HCI_ERROR_INVALID_LL_PARAMS);
66878e75b46aSAndre Guedes 
668840bef302SJohan Hedberg 	if (hcon->role == HCI_ROLE_MASTER) {
6689348d50b8SJohan Hedberg 		struct hci_conn_params *params;
6690f4869e2aSJohan Hedberg 		u8 store_hint;
6691348d50b8SJohan Hedberg 
6692348d50b8SJohan Hedberg 		hci_dev_lock(hdev);
6693348d50b8SJohan Hedberg 
6694348d50b8SJohan Hedberg 		params = hci_conn_params_lookup(hdev, &hcon->dst,
6695348d50b8SJohan Hedberg 						hcon->dst_type);
6696348d50b8SJohan Hedberg 		if (params) {
6697348d50b8SJohan Hedberg 			params->conn_min_interval = min;
6698348d50b8SJohan Hedberg 			params->conn_max_interval = max;
6699348d50b8SJohan Hedberg 			params->conn_latency = latency;
6700348d50b8SJohan Hedberg 			params->supervision_timeout = timeout;
6701f4869e2aSJohan Hedberg 			store_hint = 0x01;
6702f4869e2aSJohan Hedberg 		} else {
6703f4869e2aSJohan Hedberg 			store_hint = 0x00;
6704348d50b8SJohan Hedberg 		}
6705348d50b8SJohan Hedberg 
6706348d50b8SJohan Hedberg 		hci_dev_unlock(hdev);
6707348d50b8SJohan Hedberg 
6708f4869e2aSJohan Hedberg 		mgmt_new_conn_param(hdev, &hcon->dst, hcon->dst_type,
6709f4869e2aSJohan Hedberg 				    store_hint, min, max, latency, timeout);
6710348d50b8SJohan Hedberg 	}
6711ffb5a827SAndre Guedes 
67128e75b46aSAndre Guedes 	cp.handle = ev->handle;
67138e75b46aSAndre Guedes 	cp.interval_min = ev->interval_min;
67148e75b46aSAndre Guedes 	cp.interval_max = ev->interval_max;
67158e75b46aSAndre Guedes 	cp.latency = ev->latency;
67168e75b46aSAndre Guedes 	cp.timeout = ev->timeout;
67178e75b46aSAndre Guedes 	cp.min_ce_len = 0;
67188e75b46aSAndre Guedes 	cp.max_ce_len = 0;
67198e75b46aSAndre Guedes 
67208e75b46aSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_REPLY, sizeof(cp), &cp);
67218e75b46aSAndre Guedes }
67228e75b46aSAndre Guedes 
672395118dd4SLuiz Augusto von Dentz static void hci_le_direct_adv_report_evt(struct hci_dev *hdev, void *data,
67242f010b55SMarcel Holtmann 					 struct sk_buff *skb)
67252f010b55SMarcel Holtmann {
672695118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_direct_adv_report *ev = data;
6727b338d917SBrian Gix 	u64 instant = jiffies;
6728a3679649SLuiz Augusto von Dentz 	int i;
6729f7e0e8b2SPeilin Ye 
6730a3679649SLuiz Augusto von Dentz 	if (!hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_DIRECT_ADV_REPORT,
6731a3679649SLuiz Augusto von Dentz 				flex_array_size(ev, info, ev->num)))
6732a3679649SLuiz Augusto von Dentz 		return;
6733a3679649SLuiz Augusto von Dentz 
6734a3679649SLuiz Augusto von Dentz 	if (!ev->num)
6735f7e0e8b2SPeilin Ye 		return;
67362f010b55SMarcel Holtmann 
67372f010b55SMarcel Holtmann 	hci_dev_lock(hdev);
67382f010b55SMarcel Holtmann 
6739a3679649SLuiz Augusto von Dentz 	for (i = 0; i < ev->num; i++) {
6740a3679649SLuiz Augusto von Dentz 		struct hci_ev_le_direct_adv_info *info = &ev->info[i];
6741a3679649SLuiz Augusto von Dentz 
6742a3679649SLuiz Augusto von Dentz 		process_adv_report(hdev, info->type, &info->bdaddr,
6743a3679649SLuiz Augusto von Dentz 				   info->bdaddr_type, &info->direct_addr,
6744a3679649SLuiz Augusto von Dentz 				   info->direct_addr_type, info->rssi, NULL, 0,
6745b338d917SBrian Gix 				   false, false, instant);
6746a3679649SLuiz Augusto von Dentz 	}
67472f010b55SMarcel Holtmann 
67482f010b55SMarcel Holtmann 	hci_dev_unlock(hdev);
67492f010b55SMarcel Holtmann }
67502f010b55SMarcel Holtmann 
675195118dd4SLuiz Augusto von Dentz static void hci_le_phy_update_evt(struct hci_dev *hdev, void *data,
675295118dd4SLuiz Augusto von Dentz 				  struct sk_buff *skb)
67531efd927dSLuiz Augusto von Dentz {
675495118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_phy_update_complete *ev = data;
67551efd927dSLuiz Augusto von Dentz 	struct hci_conn *conn;
67561efd927dSLuiz Augusto von Dentz 
675795118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
67581efd927dSLuiz Augusto von Dentz 
675987df8bccSAyush Garg 	if (ev->status)
67601efd927dSLuiz Augusto von Dentz 		return;
67611efd927dSLuiz Augusto von Dentz 
67621efd927dSLuiz Augusto von Dentz 	hci_dev_lock(hdev);
67631efd927dSLuiz Augusto von Dentz 
67641efd927dSLuiz Augusto von Dentz 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
67651efd927dSLuiz Augusto von Dentz 	if (!conn)
67661efd927dSLuiz Augusto von Dentz 		goto unlock;
67671efd927dSLuiz Augusto von Dentz 
67681efd927dSLuiz Augusto von Dentz 	conn->le_tx_phy = ev->tx_phy;
67691efd927dSLuiz Augusto von Dentz 	conn->le_rx_phy = ev->rx_phy;
67701efd927dSLuiz Augusto von Dentz 
67711efd927dSLuiz Augusto von Dentz unlock:
67721efd927dSLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
67731efd927dSLuiz Augusto von Dentz }
67741efd927dSLuiz Augusto von Dentz 
677526afbd82SLuiz Augusto von Dentz static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data,
677626afbd82SLuiz Augusto von Dentz 					struct sk_buff *skb)
677726afbd82SLuiz Augusto von Dentz {
677826afbd82SLuiz Augusto von Dentz 	struct hci_evt_le_cis_established *ev = data;
677926afbd82SLuiz Augusto von Dentz 	struct hci_conn *conn;
678026afbd82SLuiz Augusto von Dentz 	u16 handle = __le16_to_cpu(ev->handle);
678126afbd82SLuiz Augusto von Dentz 
678226afbd82SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
678326afbd82SLuiz Augusto von Dentz 
678426afbd82SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
678526afbd82SLuiz Augusto von Dentz 
678626afbd82SLuiz Augusto von Dentz 	conn = hci_conn_hash_lookup_handle(hdev, handle);
678726afbd82SLuiz Augusto von Dentz 	if (!conn) {
678826afbd82SLuiz Augusto von Dentz 		bt_dev_err(hdev,
678926afbd82SLuiz Augusto von Dentz 			   "Unable to find connection with handle 0x%4.4x",
679026afbd82SLuiz Augusto von Dentz 			   handle);
679126afbd82SLuiz Augusto von Dentz 		goto unlock;
679226afbd82SLuiz Augusto von Dentz 	}
679326afbd82SLuiz Augusto von Dentz 
6794ed680f92SLuiz Augusto von Dentz 	if (conn->type != ISO_LINK) {
6795ed680f92SLuiz Augusto von Dentz 		bt_dev_err(hdev,
6796ed680f92SLuiz Augusto von Dentz 			   "Invalid connection link type handle 0x%4.4x",
6797ed680f92SLuiz Augusto von Dentz 			   handle);
6798ed680f92SLuiz Augusto von Dentz 		goto unlock;
6799ed680f92SLuiz Augusto von Dentz 	}
6800ed680f92SLuiz Augusto von Dentz 
680126afbd82SLuiz Augusto von Dentz 	if (conn->role == HCI_ROLE_SLAVE) {
680226afbd82SLuiz Augusto von Dentz 		__le32 interval;
680326afbd82SLuiz Augusto von Dentz 
680426afbd82SLuiz Augusto von Dentz 		memset(&interval, 0, sizeof(interval));
680526afbd82SLuiz Augusto von Dentz 
680626afbd82SLuiz Augusto von Dentz 		memcpy(&interval, ev->c_latency, sizeof(ev->c_latency));
680726afbd82SLuiz Augusto von Dentz 		conn->iso_qos.in.interval = le32_to_cpu(interval);
680826afbd82SLuiz Augusto von Dentz 		memcpy(&interval, ev->p_latency, sizeof(ev->p_latency));
680926afbd82SLuiz Augusto von Dentz 		conn->iso_qos.out.interval = le32_to_cpu(interval);
681026afbd82SLuiz Augusto von Dentz 		conn->iso_qos.in.latency = le16_to_cpu(ev->interval);
681126afbd82SLuiz Augusto von Dentz 		conn->iso_qos.out.latency = le16_to_cpu(ev->interval);
681226afbd82SLuiz Augusto von Dentz 		conn->iso_qos.in.sdu = le16_to_cpu(ev->c_mtu);
681326afbd82SLuiz Augusto von Dentz 		conn->iso_qos.out.sdu = le16_to_cpu(ev->p_mtu);
681426afbd82SLuiz Augusto von Dentz 		conn->iso_qos.in.phy = ev->c_phy;
681526afbd82SLuiz Augusto von Dentz 		conn->iso_qos.out.phy = ev->p_phy;
681626afbd82SLuiz Augusto von Dentz 	}
681726afbd82SLuiz Augusto von Dentz 
681826afbd82SLuiz Augusto von Dentz 	if (!ev->status) {
681926afbd82SLuiz Augusto von Dentz 		conn->state = BT_CONNECTED;
682026afbd82SLuiz Augusto von Dentz 		hci_debugfs_create_conn(conn);
682126afbd82SLuiz Augusto von Dentz 		hci_conn_add_sysfs(conn);
682226afbd82SLuiz Augusto von Dentz 		hci_iso_setup_path(conn);
682326afbd82SLuiz Augusto von Dentz 		goto unlock;
682426afbd82SLuiz Augusto von Dentz 	}
682526afbd82SLuiz Augusto von Dentz 
682626afbd82SLuiz Augusto von Dentz 	hci_connect_cfm(conn, ev->status);
682726afbd82SLuiz Augusto von Dentz 	hci_conn_del(conn);
682826afbd82SLuiz Augusto von Dentz 
682926afbd82SLuiz Augusto von Dentz unlock:
683026afbd82SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
683126afbd82SLuiz Augusto von Dentz }
683226afbd82SLuiz Augusto von Dentz 
683326afbd82SLuiz Augusto von Dentz static void hci_le_reject_cis(struct hci_dev *hdev, __le16 handle)
683426afbd82SLuiz Augusto von Dentz {
683526afbd82SLuiz Augusto von Dentz 	struct hci_cp_le_reject_cis cp;
683626afbd82SLuiz Augusto von Dentz 
683726afbd82SLuiz Augusto von Dentz 	memset(&cp, 0, sizeof(cp));
683826afbd82SLuiz Augusto von Dentz 	cp.handle = handle;
683926afbd82SLuiz Augusto von Dentz 	cp.reason = HCI_ERROR_REJ_BAD_ADDR;
684026afbd82SLuiz Augusto von Dentz 	hci_send_cmd(hdev, HCI_OP_LE_REJECT_CIS, sizeof(cp), &cp);
684126afbd82SLuiz Augusto von Dentz }
684226afbd82SLuiz Augusto von Dentz 
684326afbd82SLuiz Augusto von Dentz static void hci_le_accept_cis(struct hci_dev *hdev, __le16 handle)
684426afbd82SLuiz Augusto von Dentz {
684526afbd82SLuiz Augusto von Dentz 	struct hci_cp_le_accept_cis cp;
684626afbd82SLuiz Augusto von Dentz 
684726afbd82SLuiz Augusto von Dentz 	memset(&cp, 0, sizeof(cp));
684826afbd82SLuiz Augusto von Dentz 	cp.handle = handle;
684926afbd82SLuiz Augusto von Dentz 	hci_send_cmd(hdev, HCI_OP_LE_ACCEPT_CIS, sizeof(cp), &cp);
685026afbd82SLuiz Augusto von Dentz }
685126afbd82SLuiz Augusto von Dentz 
685226afbd82SLuiz Augusto von Dentz static void hci_le_cis_req_evt(struct hci_dev *hdev, void *data,
685326afbd82SLuiz Augusto von Dentz 			       struct sk_buff *skb)
685426afbd82SLuiz Augusto von Dentz {
685526afbd82SLuiz Augusto von Dentz 	struct hci_evt_le_cis_req *ev = data;
685626afbd82SLuiz Augusto von Dentz 	u16 acl_handle, cis_handle;
685726afbd82SLuiz Augusto von Dentz 	struct hci_conn *acl, *cis;
685826afbd82SLuiz Augusto von Dentz 	int mask;
685926afbd82SLuiz Augusto von Dentz 	__u8 flags = 0;
686026afbd82SLuiz Augusto von Dentz 
686126afbd82SLuiz Augusto von Dentz 	acl_handle = __le16_to_cpu(ev->acl_handle);
686226afbd82SLuiz Augusto von Dentz 	cis_handle = __le16_to_cpu(ev->cis_handle);
686326afbd82SLuiz Augusto von Dentz 
686426afbd82SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "acl 0x%4.4x handle 0x%4.4x cig 0x%2.2x cis 0x%2.2x",
686526afbd82SLuiz Augusto von Dentz 		   acl_handle, cis_handle, ev->cig_id, ev->cis_id);
686626afbd82SLuiz Augusto von Dentz 
686726afbd82SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
686826afbd82SLuiz Augusto von Dentz 
686926afbd82SLuiz Augusto von Dentz 	acl = hci_conn_hash_lookup_handle(hdev, acl_handle);
687026afbd82SLuiz Augusto von Dentz 	if (!acl)
687126afbd82SLuiz Augusto von Dentz 		goto unlock;
687226afbd82SLuiz Augusto von Dentz 
687326afbd82SLuiz Augusto von Dentz 	mask = hci_proto_connect_ind(hdev, &acl->dst, ISO_LINK, &flags);
687426afbd82SLuiz Augusto von Dentz 	if (!(mask & HCI_LM_ACCEPT)) {
687526afbd82SLuiz Augusto von Dentz 		hci_le_reject_cis(hdev, ev->cis_handle);
687626afbd82SLuiz Augusto von Dentz 		goto unlock;
687726afbd82SLuiz Augusto von Dentz 	}
687826afbd82SLuiz Augusto von Dentz 
687926afbd82SLuiz Augusto von Dentz 	cis = hci_conn_hash_lookup_handle(hdev, cis_handle);
688026afbd82SLuiz Augusto von Dentz 	if (!cis) {
688126afbd82SLuiz Augusto von Dentz 		cis = hci_conn_add(hdev, ISO_LINK, &acl->dst, HCI_ROLE_SLAVE);
688226afbd82SLuiz Augusto von Dentz 		if (!cis) {
688326afbd82SLuiz Augusto von Dentz 			hci_le_reject_cis(hdev, ev->cis_handle);
688426afbd82SLuiz Augusto von Dentz 			goto unlock;
688526afbd82SLuiz Augusto von Dentz 		}
688626afbd82SLuiz Augusto von Dentz 		cis->handle = cis_handle;
688726afbd82SLuiz Augusto von Dentz 	}
688826afbd82SLuiz Augusto von Dentz 
688926afbd82SLuiz Augusto von Dentz 	cis->iso_qos.cig = ev->cig_id;
689026afbd82SLuiz Augusto von Dentz 	cis->iso_qos.cis = ev->cis_id;
689126afbd82SLuiz Augusto von Dentz 
689226afbd82SLuiz Augusto von Dentz 	if (!(flags & HCI_PROTO_DEFER)) {
689326afbd82SLuiz Augusto von Dentz 		hci_le_accept_cis(hdev, ev->cis_handle);
689426afbd82SLuiz Augusto von Dentz 	} else {
689526afbd82SLuiz Augusto von Dentz 		cis->state = BT_CONNECT2;
689626afbd82SLuiz Augusto von Dentz 		hci_connect_cfm(cis, 0);
689726afbd82SLuiz Augusto von Dentz 	}
689826afbd82SLuiz Augusto von Dentz 
689926afbd82SLuiz Augusto von Dentz unlock:
690026afbd82SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
690126afbd82SLuiz Augusto von Dentz }
690226afbd82SLuiz Augusto von Dentz 
6903eca0ae4aSLuiz Augusto von Dentz static void hci_le_create_big_complete_evt(struct hci_dev *hdev, void *data,
6904eca0ae4aSLuiz Augusto von Dentz 					   struct sk_buff *skb)
6905eca0ae4aSLuiz Augusto von Dentz {
6906eca0ae4aSLuiz Augusto von Dentz 	struct hci_evt_le_create_big_complete *ev = data;
6907eca0ae4aSLuiz Augusto von Dentz 	struct hci_conn *conn;
6908eca0ae4aSLuiz Augusto von Dentz 
6909eca0ae4aSLuiz Augusto von Dentz 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
6910eca0ae4aSLuiz Augusto von Dentz 
6911eca0ae4aSLuiz Augusto von Dentz 	if (!hci_le_ev_skb_pull(hdev, skb, HCI_EVT_LE_CREATE_BIG_COMPLETE,
6912eca0ae4aSLuiz Augusto von Dentz 				flex_array_size(ev, bis_handle, ev->num_bis)))
6913eca0ae4aSLuiz Augusto von Dentz 		return;
6914eca0ae4aSLuiz Augusto von Dentz 
6915eca0ae4aSLuiz Augusto von Dentz 	hci_dev_lock(hdev);
6916eca0ae4aSLuiz Augusto von Dentz 
6917eca0ae4aSLuiz Augusto von Dentz 	conn = hci_conn_hash_lookup_big(hdev, ev->handle);
6918eca0ae4aSLuiz Augusto von Dentz 	if (!conn)
6919eca0ae4aSLuiz Augusto von Dentz 		goto unlock;
6920eca0ae4aSLuiz Augusto von Dentz 
6921ed680f92SLuiz Augusto von Dentz 	if (conn->type != ISO_LINK) {
6922ed680f92SLuiz Augusto von Dentz 		bt_dev_err(hdev,
6923ed680f92SLuiz Augusto von Dentz 			   "Invalid connection link type handle 0x%2.2x",
6924ed680f92SLuiz Augusto von Dentz 			   ev->handle);
6925ed680f92SLuiz Augusto von Dentz 		goto unlock;
6926ed680f92SLuiz Augusto von Dentz 	}
6927ed680f92SLuiz Augusto von Dentz 
6928eca0ae4aSLuiz Augusto von Dentz 	if (ev->num_bis)
6929eca0ae4aSLuiz Augusto von Dentz 		conn->handle = __le16_to_cpu(ev->bis_handle[0]);
6930eca0ae4aSLuiz Augusto von Dentz 
6931eca0ae4aSLuiz Augusto von Dentz 	if (!ev->status) {
6932eca0ae4aSLuiz Augusto von Dentz 		conn->state = BT_CONNECTED;
6933eca0ae4aSLuiz Augusto von Dentz 		hci_debugfs_create_conn(conn);
6934eca0ae4aSLuiz Augusto von Dentz 		hci_conn_add_sysfs(conn);
6935eca0ae4aSLuiz Augusto von Dentz 		hci_iso_setup_path(conn);
6936eca0ae4aSLuiz Augusto von Dentz 		goto unlock;
6937eca0ae4aSLuiz Augusto von Dentz 	}
6938eca0ae4aSLuiz Augusto von Dentz 
6939eca0ae4aSLuiz Augusto von Dentz 	hci_connect_cfm(conn, ev->status);
6940eca0ae4aSLuiz Augusto von Dentz 	hci_conn_del(conn);
6941eca0ae4aSLuiz Augusto von Dentz 
6942eca0ae4aSLuiz Augusto von Dentz unlock:
6943eca0ae4aSLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
6944eca0ae4aSLuiz Augusto von Dentz }
6945eca0ae4aSLuiz Augusto von Dentz 
6946eca0ae4aSLuiz Augusto von Dentz static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data,
6947eca0ae4aSLuiz Augusto von Dentz 					    struct sk_buff *skb)
6948eca0ae4aSLuiz Augusto von Dentz {
6949eca0ae4aSLuiz Augusto von Dentz 	struct hci_evt_le_big_sync_estabilished *ev = data;
6950eca0ae4aSLuiz Augusto von Dentz 	struct hci_conn *bis;
6951eca0ae4aSLuiz Augusto von Dentz 	int i;
6952eca0ae4aSLuiz Augusto von Dentz 
6953eca0ae4aSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
6954eca0ae4aSLuiz Augusto von Dentz 
6955eca0ae4aSLuiz Augusto von Dentz 	if (!hci_le_ev_skb_pull(hdev, skb, HCI_EVT_LE_BIG_SYNC_ESTABILISHED,
6956eca0ae4aSLuiz Augusto von Dentz 				flex_array_size(ev, bis, ev->num_bis)))
6957eca0ae4aSLuiz Augusto von Dentz 		return;
6958eca0ae4aSLuiz Augusto von Dentz 
6959eca0ae4aSLuiz Augusto von Dentz 	if (ev->status)
6960eca0ae4aSLuiz Augusto von Dentz 		return;
6961eca0ae4aSLuiz Augusto von Dentz 
6962eca0ae4aSLuiz Augusto von Dentz 	hci_dev_lock(hdev);
6963eca0ae4aSLuiz Augusto von Dentz 
6964eca0ae4aSLuiz Augusto von Dentz 	for (i = 0; i < ev->num_bis; i++) {
6965eca0ae4aSLuiz Augusto von Dentz 		u16 handle = le16_to_cpu(ev->bis[i]);
6966eca0ae4aSLuiz Augusto von Dentz 		__le32 interval;
6967eca0ae4aSLuiz Augusto von Dentz 
6968eca0ae4aSLuiz Augusto von Dentz 		bis = hci_conn_hash_lookup_handle(hdev, handle);
6969eca0ae4aSLuiz Augusto von Dentz 		if (!bis) {
6970eca0ae4aSLuiz Augusto von Dentz 			bis = hci_conn_add(hdev, ISO_LINK, BDADDR_ANY,
6971eca0ae4aSLuiz Augusto von Dentz 					   HCI_ROLE_SLAVE);
6972eca0ae4aSLuiz Augusto von Dentz 			if (!bis)
6973eca0ae4aSLuiz Augusto von Dentz 				continue;
6974eca0ae4aSLuiz Augusto von Dentz 			bis->handle = handle;
6975eca0ae4aSLuiz Augusto von Dentz 		}
6976eca0ae4aSLuiz Augusto von Dentz 
6977eca0ae4aSLuiz Augusto von Dentz 		bis->iso_qos.big = ev->handle;
6978eca0ae4aSLuiz Augusto von Dentz 		memset(&interval, 0, sizeof(interval));
6979eca0ae4aSLuiz Augusto von Dentz 		memcpy(&interval, ev->latency, sizeof(ev->latency));
6980eca0ae4aSLuiz Augusto von Dentz 		bis->iso_qos.in.interval = le32_to_cpu(interval);
6981eca0ae4aSLuiz Augusto von Dentz 		/* Convert ISO Interval (1.25 ms slots) to latency (ms) */
6982eca0ae4aSLuiz Augusto von Dentz 		bis->iso_qos.in.latency = le16_to_cpu(ev->interval) * 125 / 100;
6983eca0ae4aSLuiz Augusto von Dentz 		bis->iso_qos.in.sdu = le16_to_cpu(ev->max_pdu);
6984eca0ae4aSLuiz Augusto von Dentz 
6985eca0ae4aSLuiz Augusto von Dentz 		hci_connect_cfm(bis, ev->status);
6986eca0ae4aSLuiz Augusto von Dentz 	}
6987eca0ae4aSLuiz Augusto von Dentz 
6988eca0ae4aSLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
6989eca0ae4aSLuiz Augusto von Dentz }
6990eca0ae4aSLuiz Augusto von Dentz 
6991eca0ae4aSLuiz Augusto von Dentz static void hci_le_big_info_adv_report_evt(struct hci_dev *hdev, void *data,
6992eca0ae4aSLuiz Augusto von Dentz 					   struct sk_buff *skb)
6993eca0ae4aSLuiz Augusto von Dentz {
6994eca0ae4aSLuiz Augusto von Dentz 	struct hci_evt_le_big_info_adv_report *ev = data;
6995eca0ae4aSLuiz Augusto von Dentz 	int mask = hdev->link_mode;
6996eca0ae4aSLuiz Augusto von Dentz 	__u8 flags = 0;
6997eca0ae4aSLuiz Augusto von Dentz 
6998eca0ae4aSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "sync_handle 0x%4.4x", le16_to_cpu(ev->sync_handle));
6999eca0ae4aSLuiz Augusto von Dentz 
7000eca0ae4aSLuiz Augusto von Dentz 	hci_dev_lock(hdev);
7001eca0ae4aSLuiz Augusto von Dentz 
7002eca0ae4aSLuiz Augusto von Dentz 	mask |= hci_proto_connect_ind(hdev, BDADDR_ANY, ISO_LINK, &flags);
7003eca0ae4aSLuiz Augusto von Dentz 	if (!(mask & HCI_LM_ACCEPT))
7004eca0ae4aSLuiz Augusto von Dentz 		hci_le_pa_term_sync(hdev, ev->sync_handle);
7005eca0ae4aSLuiz Augusto von Dentz 
7006eca0ae4aSLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
7007eca0ae4aSLuiz Augusto von Dentz }
7008eca0ae4aSLuiz Augusto von Dentz 
700995118dd4SLuiz Augusto von Dentz #define HCI_LE_EV_VL(_op, _func, _min_len, _max_len) \
701095118dd4SLuiz Augusto von Dentz [_op] = { \
701195118dd4SLuiz Augusto von Dentz 	.func = _func, \
701295118dd4SLuiz Augusto von Dentz 	.min_len = _min_len, \
701395118dd4SLuiz Augusto von Dentz 	.max_len = _max_len, \
701495118dd4SLuiz Augusto von Dentz }
701595118dd4SLuiz Augusto von Dentz 
701695118dd4SLuiz Augusto von Dentz #define HCI_LE_EV(_op, _func, _len) \
701795118dd4SLuiz Augusto von Dentz 	HCI_LE_EV_VL(_op, _func, _len, _len)
701895118dd4SLuiz Augusto von Dentz 
701995118dd4SLuiz Augusto von Dentz #define HCI_LE_EV_STATUS(_op, _func) \
702095118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(_op, _func, sizeof(struct hci_ev_status))
702195118dd4SLuiz Augusto von Dentz 
702295118dd4SLuiz Augusto von Dentz /* Entries in this table shall have their position according to the subevent
702395118dd4SLuiz Augusto von Dentz  * opcode they handle so the use of the macros above is recommend since it does
702495118dd4SLuiz Augusto von Dentz  * attempt to initialize at its proper index using Designated Initializers that
702595118dd4SLuiz Augusto von Dentz  * way events without a callback function can be ommited.
702695118dd4SLuiz Augusto von Dentz  */
702795118dd4SLuiz Augusto von Dentz static const struct hci_le_ev {
702895118dd4SLuiz Augusto von Dentz 	void (*func)(struct hci_dev *hdev, void *data, struct sk_buff *skb);
702995118dd4SLuiz Augusto von Dentz 	u16  min_len;
703095118dd4SLuiz Augusto von Dentz 	u16  max_len;
703195118dd4SLuiz Augusto von Dentz } hci_le_ev_table[U8_MAX + 1] = {
703295118dd4SLuiz Augusto von Dentz 	/* [0x01 = HCI_EV_LE_CONN_COMPLETE] */
703395118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_CONN_COMPLETE, hci_le_conn_complete_evt,
703495118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_conn_complete)),
703595118dd4SLuiz Augusto von Dentz 	/* [0x02 = HCI_EV_LE_ADVERTISING_REPORT] */
703695118dd4SLuiz Augusto von Dentz 	HCI_LE_EV_VL(HCI_EV_LE_ADVERTISING_REPORT, hci_le_adv_report_evt,
703795118dd4SLuiz Augusto von Dentz 		     sizeof(struct hci_ev_le_advertising_report),
703895118dd4SLuiz Augusto von Dentz 		     HCI_MAX_EVENT_SIZE),
703995118dd4SLuiz Augusto von Dentz 	/* [0x03 = HCI_EV_LE_CONN_UPDATE_COMPLETE] */
704095118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_CONN_UPDATE_COMPLETE,
704195118dd4SLuiz Augusto von Dentz 		  hci_le_conn_update_complete_evt,
704295118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_conn_update_complete)),
704395118dd4SLuiz Augusto von Dentz 	/* [0x04 = HCI_EV_LE_REMOTE_FEAT_COMPLETE] */
704495118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_REMOTE_FEAT_COMPLETE,
704595118dd4SLuiz Augusto von Dentz 		  hci_le_remote_feat_complete_evt,
704695118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_remote_feat_complete)),
704795118dd4SLuiz Augusto von Dentz 	/* [0x05 = HCI_EV_LE_LTK_REQ] */
704895118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_LTK_REQ, hci_le_ltk_request_evt,
704995118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_ltk_req)),
705095118dd4SLuiz Augusto von Dentz 	/* [0x06 = HCI_EV_LE_REMOTE_CONN_PARAM_REQ] */
705195118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_REMOTE_CONN_PARAM_REQ,
705295118dd4SLuiz Augusto von Dentz 		  hci_le_remote_conn_param_req_evt,
705395118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_remote_conn_param_req)),
705495118dd4SLuiz Augusto von Dentz 	/* [0x0a = HCI_EV_LE_ENHANCED_CONN_COMPLETE] */
705595118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_ENHANCED_CONN_COMPLETE,
705695118dd4SLuiz Augusto von Dentz 		  hci_le_enh_conn_complete_evt,
705795118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_enh_conn_complete)),
705895118dd4SLuiz Augusto von Dentz 	/* [0x0b = HCI_EV_LE_DIRECT_ADV_REPORT] */
705995118dd4SLuiz Augusto von Dentz 	HCI_LE_EV_VL(HCI_EV_LE_DIRECT_ADV_REPORT, hci_le_direct_adv_report_evt,
706095118dd4SLuiz Augusto von Dentz 		     sizeof(struct hci_ev_le_direct_adv_report),
706195118dd4SLuiz Augusto von Dentz 		     HCI_MAX_EVENT_SIZE),
706295118dd4SLuiz Augusto von Dentz 	/* [0x0c = HCI_EV_LE_PHY_UPDATE_COMPLETE] */
706395118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_PHY_UPDATE_COMPLETE, hci_le_phy_update_evt,
706495118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_phy_update_complete)),
706595118dd4SLuiz Augusto von Dentz 	/* [0x0d = HCI_EV_LE_EXT_ADV_REPORT] */
706695118dd4SLuiz Augusto von Dentz 	HCI_LE_EV_VL(HCI_EV_LE_EXT_ADV_REPORT, hci_le_ext_adv_report_evt,
706795118dd4SLuiz Augusto von Dentz 		     sizeof(struct hci_ev_le_ext_adv_report),
706895118dd4SLuiz Augusto von Dentz 		     HCI_MAX_EVENT_SIZE),
7069eca0ae4aSLuiz Augusto von Dentz 	/* [0x0e = HCI_EV_LE_PA_SYNC_ESTABLISHED] */
7070eca0ae4aSLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_PA_SYNC_ESTABLISHED,
7071eca0ae4aSLuiz Augusto von Dentz 		  hci_le_pa_sync_estabilished_evt,
7072eca0ae4aSLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_pa_sync_established)),
707395118dd4SLuiz Augusto von Dentz 	/* [0x12 = HCI_EV_LE_EXT_ADV_SET_TERM] */
707495118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_EXT_ADV_SET_TERM, hci_le_ext_adv_term_evt,
707595118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_evt_le_ext_adv_set_term)),
707626afbd82SLuiz Augusto von Dentz 	/* [0x19 = HCI_EVT_LE_CIS_ESTABLISHED] */
707726afbd82SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EVT_LE_CIS_ESTABLISHED, hci_le_cis_estabilished_evt,
707826afbd82SLuiz Augusto von Dentz 		  sizeof(struct hci_evt_le_cis_established)),
707926afbd82SLuiz Augusto von Dentz 	/* [0x1a = HCI_EVT_LE_CIS_REQ] */
708026afbd82SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EVT_LE_CIS_REQ, hci_le_cis_req_evt,
708126afbd82SLuiz Augusto von Dentz 		  sizeof(struct hci_evt_le_cis_req)),
7082eca0ae4aSLuiz Augusto von Dentz 	/* [0x1b = HCI_EVT_LE_CREATE_BIG_COMPLETE] */
7083eca0ae4aSLuiz Augusto von Dentz 	HCI_LE_EV_VL(HCI_EVT_LE_CREATE_BIG_COMPLETE,
7084eca0ae4aSLuiz Augusto von Dentz 		     hci_le_create_big_complete_evt,
7085eca0ae4aSLuiz Augusto von Dentz 		     sizeof(struct hci_evt_le_create_big_complete),
7086eca0ae4aSLuiz Augusto von Dentz 		     HCI_MAX_EVENT_SIZE),
7087eca0ae4aSLuiz Augusto von Dentz 	/* [0x1d = HCI_EV_LE_BIG_SYNC_ESTABILISHED] */
7088eca0ae4aSLuiz Augusto von Dentz 	HCI_LE_EV_VL(HCI_EVT_LE_BIG_SYNC_ESTABILISHED,
7089eca0ae4aSLuiz Augusto von Dentz 		     hci_le_big_sync_established_evt,
7090eca0ae4aSLuiz Augusto von Dentz 		     sizeof(struct hci_evt_le_big_sync_estabilished),
7091eca0ae4aSLuiz Augusto von Dentz 		     HCI_MAX_EVENT_SIZE),
7092eca0ae4aSLuiz Augusto von Dentz 	/* [0x22 = HCI_EVT_LE_BIG_INFO_ADV_REPORT] */
7093eca0ae4aSLuiz Augusto von Dentz 	HCI_LE_EV_VL(HCI_EVT_LE_BIG_INFO_ADV_REPORT,
7094eca0ae4aSLuiz Augusto von Dentz 		     hci_le_big_info_adv_report_evt,
7095eca0ae4aSLuiz Augusto von Dentz 		     sizeof(struct hci_evt_le_big_info_adv_report),
7096eca0ae4aSLuiz Augusto von Dentz 		     HCI_MAX_EVENT_SIZE),
709795118dd4SLuiz Augusto von Dentz };
709895118dd4SLuiz Augusto von Dentz 
70993e54c589SLuiz Augusto von Dentz static void hci_le_meta_evt(struct hci_dev *hdev, void *data,
710085b56857SLuiz Augusto von Dentz 			    struct sk_buff *skb, u16 *opcode, u8 *status,
710185b56857SLuiz Augusto von Dentz 			    hci_req_complete_t *req_complete,
710285b56857SLuiz Augusto von Dentz 			    hci_req_complete_skb_t *req_complete_skb)
7103fcd89c09SVille Tervo {
71043e54c589SLuiz Augusto von Dentz 	struct hci_ev_le_meta *ev = data;
710595118dd4SLuiz Augusto von Dentz 	const struct hci_le_ev *subev;
7106fcd89c09SVille Tervo 
710795118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "subevent 0x%2.2x", ev->subevent);
7108fcd89c09SVille Tervo 
710985b56857SLuiz Augusto von Dentz 	/* Only match event if command OGF is for LE */
711085b56857SLuiz Augusto von Dentz 	if (hdev->sent_cmd &&
711185b56857SLuiz Augusto von Dentz 	    hci_opcode_ogf(hci_skb_opcode(hdev->sent_cmd)) == 0x08 &&
711285b56857SLuiz Augusto von Dentz 	    hci_skb_event(hdev->sent_cmd) == ev->subevent) {
711385b56857SLuiz Augusto von Dentz 		*opcode = hci_skb_opcode(hdev->sent_cmd);
711485b56857SLuiz Augusto von Dentz 		hci_req_cmd_complete(hdev, *opcode, 0x00, req_complete,
711585b56857SLuiz Augusto von Dentz 				     req_complete_skb);
711685b56857SLuiz Augusto von Dentz 	}
711785b56857SLuiz Augusto von Dentz 
711895118dd4SLuiz Augusto von Dentz 	subev = &hci_le_ev_table[ev->subevent];
711995118dd4SLuiz Augusto von Dentz 	if (!subev->func)
712095118dd4SLuiz Augusto von Dentz 		return;
71211855d92dSMarcel Holtmann 
712295118dd4SLuiz Augusto von Dentz 	if (skb->len < subev->min_len) {
712395118dd4SLuiz Augusto von Dentz 		bt_dev_err(hdev, "unexpected subevent 0x%2.2x length: %u < %u",
712495118dd4SLuiz Augusto von Dentz 			   ev->subevent, skb->len, subev->min_len);
712595118dd4SLuiz Augusto von Dentz 		return;
7126fcd89c09SVille Tervo 	}
712795118dd4SLuiz Augusto von Dentz 
712895118dd4SLuiz Augusto von Dentz 	/* Just warn if the length is over max_len size it still be
712995118dd4SLuiz Augusto von Dentz 	 * possible to partially parse the event so leave to callback to
713095118dd4SLuiz Augusto von Dentz 	 * decide if that is acceptable.
713195118dd4SLuiz Augusto von Dentz 	 */
713295118dd4SLuiz Augusto von Dentz 	if (skb->len > subev->max_len)
713395118dd4SLuiz Augusto von Dentz 		bt_dev_warn(hdev, "unexpected subevent 0x%2.2x length: %u > %u",
713495118dd4SLuiz Augusto von Dentz 			    ev->subevent, skb->len, subev->max_len);
713595118dd4SLuiz Augusto von Dentz 	data = hci_le_ev_skb_pull(hdev, skb, ev->subevent, subev->min_len);
713695118dd4SLuiz Augusto von Dentz 	if (!data)
713795118dd4SLuiz Augusto von Dentz 		return;
713895118dd4SLuiz Augusto von Dentz 
713995118dd4SLuiz Augusto von Dentz 	subev->func(hdev, data, skb);
7140fcd89c09SVille Tervo }
7141fcd89c09SVille Tervo 
7142757aa0b5SJohan Hedberg static bool hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode,
7143757aa0b5SJohan Hedberg 				 u8 event, struct sk_buff *skb)
7144757aa0b5SJohan Hedberg {
7145757aa0b5SJohan Hedberg 	struct hci_ev_cmd_complete *ev;
7146757aa0b5SJohan Hedberg 	struct hci_event_hdr *hdr;
7147757aa0b5SJohan Hedberg 
7148757aa0b5SJohan Hedberg 	if (!skb)
7149757aa0b5SJohan Hedberg 		return false;
7150757aa0b5SJohan Hedberg 
7151e3f3a1aeSLuiz Augusto von Dentz 	hdr = hci_ev_skb_pull(hdev, skb, event, sizeof(*hdr));
7152e3f3a1aeSLuiz Augusto von Dentz 	if (!hdr)
7153757aa0b5SJohan Hedberg 		return false;
7154757aa0b5SJohan Hedberg 
7155757aa0b5SJohan Hedberg 	if (event) {
7156757aa0b5SJohan Hedberg 		if (hdr->evt != event)
7157757aa0b5SJohan Hedberg 			return false;
7158757aa0b5SJohan Hedberg 		return true;
7159757aa0b5SJohan Hedberg 	}
7160757aa0b5SJohan Hedberg 
716191641b79SZheng Yongjun 	/* Check if request ended in Command Status - no way to retrieve
71621629db9cSJohan Hedberg 	 * any extra parameters in this case.
71631629db9cSJohan Hedberg 	 */
71641629db9cSJohan Hedberg 	if (hdr->evt == HCI_EV_CMD_STATUS)
71651629db9cSJohan Hedberg 		return false;
71661629db9cSJohan Hedberg 
7167757aa0b5SJohan Hedberg 	if (hdr->evt != HCI_EV_CMD_COMPLETE) {
71682064ee33SMarcel Holtmann 		bt_dev_err(hdev, "last event is not cmd complete (0x%2.2x)",
71692064ee33SMarcel Holtmann 			   hdr->evt);
7170757aa0b5SJohan Hedberg 		return false;
7171757aa0b5SJohan Hedberg 	}
7172757aa0b5SJohan Hedberg 
7173e3f3a1aeSLuiz Augusto von Dentz 	ev = hci_cc_skb_pull(hdev, skb, opcode, sizeof(*ev));
7174e3f3a1aeSLuiz Augusto von Dentz 	if (!ev)
7175757aa0b5SJohan Hedberg 		return false;
7176757aa0b5SJohan Hedberg 
7177757aa0b5SJohan Hedberg 	if (opcode != __le16_to_cpu(ev->opcode)) {
7178757aa0b5SJohan Hedberg 		BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode,
7179757aa0b5SJohan Hedberg 		       __le16_to_cpu(ev->opcode));
7180757aa0b5SJohan Hedberg 		return false;
7181757aa0b5SJohan Hedberg 	}
7182757aa0b5SJohan Hedberg 
7183757aa0b5SJohan Hedberg 	return true;
7184757aa0b5SJohan Hedberg }
7185757aa0b5SJohan Hedberg 
71862f20216cSAbhishek Pandit-Subedi static void hci_store_wake_reason(struct hci_dev *hdev, u8 event,
71872f20216cSAbhishek Pandit-Subedi 				  struct sk_buff *skb)
71882f20216cSAbhishek Pandit-Subedi {
71892f20216cSAbhishek Pandit-Subedi 	struct hci_ev_le_advertising_info *adv;
71902f20216cSAbhishek Pandit-Subedi 	struct hci_ev_le_direct_adv_info *direct_adv;
7191b48b833fSLuiz Augusto von Dentz 	struct hci_ev_le_ext_adv_info *ext_adv;
71922f20216cSAbhishek Pandit-Subedi 	const struct hci_ev_conn_complete *conn_complete = (void *)skb->data;
71932f20216cSAbhishek Pandit-Subedi 	const struct hci_ev_conn_request *conn_request = (void *)skb->data;
71942f20216cSAbhishek Pandit-Subedi 
71952f20216cSAbhishek Pandit-Subedi 	hci_dev_lock(hdev);
71962f20216cSAbhishek Pandit-Subedi 
71972f20216cSAbhishek Pandit-Subedi 	/* If we are currently suspended and this is the first BT event seen,
71982f20216cSAbhishek Pandit-Subedi 	 * save the wake reason associated with the event.
71992f20216cSAbhishek Pandit-Subedi 	 */
72002f20216cSAbhishek Pandit-Subedi 	if (!hdev->suspended || hdev->wake_reason)
72012f20216cSAbhishek Pandit-Subedi 		goto unlock;
72022f20216cSAbhishek Pandit-Subedi 
72032f20216cSAbhishek Pandit-Subedi 	/* Default to remote wake. Values for wake_reason are documented in the
72042f20216cSAbhishek Pandit-Subedi 	 * Bluez mgmt api docs.
72052f20216cSAbhishek Pandit-Subedi 	 */
72062f20216cSAbhishek Pandit-Subedi 	hdev->wake_reason = MGMT_WAKE_REASON_REMOTE_WAKE;
72072f20216cSAbhishek Pandit-Subedi 
72082f20216cSAbhishek Pandit-Subedi 	/* Once configured for remote wakeup, we should only wake up for
72092f20216cSAbhishek Pandit-Subedi 	 * reconnections. It's useful to see which device is waking us up so
72102f20216cSAbhishek Pandit-Subedi 	 * keep track of the bdaddr of the connection event that woke us up.
72112f20216cSAbhishek Pandit-Subedi 	 */
72122f20216cSAbhishek Pandit-Subedi 	if (event == HCI_EV_CONN_REQUEST) {
72132f20216cSAbhishek Pandit-Subedi 		bacpy(&hdev->wake_addr, &conn_complete->bdaddr);
72142f20216cSAbhishek Pandit-Subedi 		hdev->wake_addr_type = BDADDR_BREDR;
72152f20216cSAbhishek Pandit-Subedi 	} else if (event == HCI_EV_CONN_COMPLETE) {
72162f20216cSAbhishek Pandit-Subedi 		bacpy(&hdev->wake_addr, &conn_request->bdaddr);
72172f20216cSAbhishek Pandit-Subedi 		hdev->wake_addr_type = BDADDR_BREDR;
72182f20216cSAbhishek Pandit-Subedi 	} else if (event == HCI_EV_LE_META) {
72192f20216cSAbhishek Pandit-Subedi 		struct hci_ev_le_meta *le_ev = (void *)skb->data;
72202f20216cSAbhishek Pandit-Subedi 		u8 subevent = le_ev->subevent;
72212f20216cSAbhishek Pandit-Subedi 		u8 *ptr = &skb->data[sizeof(*le_ev)];
72222f20216cSAbhishek Pandit-Subedi 		u8 num_reports = *ptr;
72232f20216cSAbhishek Pandit-Subedi 
72242f20216cSAbhishek Pandit-Subedi 		if ((subevent == HCI_EV_LE_ADVERTISING_REPORT ||
72252f20216cSAbhishek Pandit-Subedi 		     subevent == HCI_EV_LE_DIRECT_ADV_REPORT ||
72262f20216cSAbhishek Pandit-Subedi 		     subevent == HCI_EV_LE_EXT_ADV_REPORT) &&
72272f20216cSAbhishek Pandit-Subedi 		    num_reports) {
72282f20216cSAbhishek Pandit-Subedi 			adv = (void *)(ptr + 1);
72292f20216cSAbhishek Pandit-Subedi 			direct_adv = (void *)(ptr + 1);
72302f20216cSAbhishek Pandit-Subedi 			ext_adv = (void *)(ptr + 1);
72312f20216cSAbhishek Pandit-Subedi 
72322f20216cSAbhishek Pandit-Subedi 			switch (subevent) {
72332f20216cSAbhishek Pandit-Subedi 			case HCI_EV_LE_ADVERTISING_REPORT:
72342f20216cSAbhishek Pandit-Subedi 				bacpy(&hdev->wake_addr, &adv->bdaddr);
72352f20216cSAbhishek Pandit-Subedi 				hdev->wake_addr_type = adv->bdaddr_type;
72362f20216cSAbhishek Pandit-Subedi 				break;
72372f20216cSAbhishek Pandit-Subedi 			case HCI_EV_LE_DIRECT_ADV_REPORT:
72382f20216cSAbhishek Pandit-Subedi 				bacpy(&hdev->wake_addr, &direct_adv->bdaddr);
72392f20216cSAbhishek Pandit-Subedi 				hdev->wake_addr_type = direct_adv->bdaddr_type;
72402f20216cSAbhishek Pandit-Subedi 				break;
72412f20216cSAbhishek Pandit-Subedi 			case HCI_EV_LE_EXT_ADV_REPORT:
72422f20216cSAbhishek Pandit-Subedi 				bacpy(&hdev->wake_addr, &ext_adv->bdaddr);
72432f20216cSAbhishek Pandit-Subedi 				hdev->wake_addr_type = ext_adv->bdaddr_type;
72442f20216cSAbhishek Pandit-Subedi 				break;
72452f20216cSAbhishek Pandit-Subedi 			}
72462f20216cSAbhishek Pandit-Subedi 		}
72472f20216cSAbhishek Pandit-Subedi 	} else {
72482f20216cSAbhishek Pandit-Subedi 		hdev->wake_reason = MGMT_WAKE_REASON_UNEXPECTED;
72492f20216cSAbhishek Pandit-Subedi 	}
72502f20216cSAbhishek Pandit-Subedi 
72512f20216cSAbhishek Pandit-Subedi unlock:
72522f20216cSAbhishek Pandit-Subedi 	hci_dev_unlock(hdev);
72532f20216cSAbhishek Pandit-Subedi }
72542f20216cSAbhishek Pandit-Subedi 
72553e54c589SLuiz Augusto von Dentz #define HCI_EV_VL(_op, _func, _min_len, _max_len) \
72563e54c589SLuiz Augusto von Dentz [_op] = { \
72573e54c589SLuiz Augusto von Dentz 	.req = false, \
72583e54c589SLuiz Augusto von Dentz 	.func = _func, \
72593e54c589SLuiz Augusto von Dentz 	.min_len = _min_len, \
72603e54c589SLuiz Augusto von Dentz 	.max_len = _max_len, \
72613e54c589SLuiz Augusto von Dentz }
72623e54c589SLuiz Augusto von Dentz 
72633e54c589SLuiz Augusto von Dentz #define HCI_EV(_op, _func, _len) \
72643e54c589SLuiz Augusto von Dentz 	HCI_EV_VL(_op, _func, _len, _len)
72653e54c589SLuiz Augusto von Dentz 
72663e54c589SLuiz Augusto von Dentz #define HCI_EV_STATUS(_op, _func) \
72673e54c589SLuiz Augusto von Dentz 	HCI_EV(_op, _func, sizeof(struct hci_ev_status))
72683e54c589SLuiz Augusto von Dentz 
72693e54c589SLuiz Augusto von Dentz #define HCI_EV_REQ_VL(_op, _func, _min_len, _max_len) \
72703e54c589SLuiz Augusto von Dentz [_op] = { \
72713e54c589SLuiz Augusto von Dentz 	.req = true, \
72723e54c589SLuiz Augusto von Dentz 	.func_req = _func, \
72733e54c589SLuiz Augusto von Dentz 	.min_len = _min_len, \
72743e54c589SLuiz Augusto von Dentz 	.max_len = _max_len, \
72753e54c589SLuiz Augusto von Dentz }
72763e54c589SLuiz Augusto von Dentz 
72773e54c589SLuiz Augusto von Dentz #define HCI_EV_REQ(_op, _func, _len) \
72783e54c589SLuiz Augusto von Dentz 	HCI_EV_REQ_VL(_op, _func, _len, _len)
72793e54c589SLuiz Augusto von Dentz 
72803e54c589SLuiz Augusto von Dentz /* Entries in this table shall have their position according to the event opcode
72813e54c589SLuiz Augusto von Dentz  * they handle so the use of the macros above is recommend since it does attempt
72823e54c589SLuiz Augusto von Dentz  * to initialize at its proper index using Designated Initializers that way
72833e54c589SLuiz Augusto von Dentz  * events without a callback function don't have entered.
72843e54c589SLuiz Augusto von Dentz  */
72853e54c589SLuiz Augusto von Dentz static const struct hci_ev {
72863e54c589SLuiz Augusto von Dentz 	bool req;
72873e54c589SLuiz Augusto von Dentz 	union {
72883e54c589SLuiz Augusto von Dentz 		void (*func)(struct hci_dev *hdev, void *data,
72893e54c589SLuiz Augusto von Dentz 			     struct sk_buff *skb);
72903e54c589SLuiz Augusto von Dentz 		void (*func_req)(struct hci_dev *hdev, void *data,
72913e54c589SLuiz Augusto von Dentz 				 struct sk_buff *skb, u16 *opcode, u8 *status,
72923e54c589SLuiz Augusto von Dentz 				 hci_req_complete_t *req_complete,
72933e54c589SLuiz Augusto von Dentz 				 hci_req_complete_skb_t *req_complete_skb);
72943e54c589SLuiz Augusto von Dentz 	};
72953e54c589SLuiz Augusto von Dentz 	u16  min_len;
72963e54c589SLuiz Augusto von Dentz 	u16  max_len;
72973e54c589SLuiz Augusto von Dentz } hci_ev_table[U8_MAX + 1] = {
72983e54c589SLuiz Augusto von Dentz 	/* [0x01 = HCI_EV_INQUIRY_COMPLETE] */
72993e54c589SLuiz Augusto von Dentz 	HCI_EV_STATUS(HCI_EV_INQUIRY_COMPLETE, hci_inquiry_complete_evt),
73003e54c589SLuiz Augusto von Dentz 	/* [0x02 = HCI_EV_INQUIRY_RESULT] */
73013e54c589SLuiz Augusto von Dentz 	HCI_EV_VL(HCI_EV_INQUIRY_RESULT, hci_inquiry_result_evt,
73023e54c589SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_inquiry_result), HCI_MAX_EVENT_SIZE),
73033e54c589SLuiz Augusto von Dentz 	/* [0x03 = HCI_EV_CONN_COMPLETE] */
73043e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_CONN_COMPLETE, hci_conn_complete_evt,
73053e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_conn_complete)),
73063e54c589SLuiz Augusto von Dentz 	/* [0x04 = HCI_EV_CONN_REQUEST] */
73073e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_CONN_REQUEST, hci_conn_request_evt,
73083e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_conn_request)),
73093e54c589SLuiz Augusto von Dentz 	/* [0x05 = HCI_EV_DISCONN_COMPLETE] */
73103e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_DISCONN_COMPLETE, hci_disconn_complete_evt,
73113e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_disconn_complete)),
73123e54c589SLuiz Augusto von Dentz 	/* [0x06 = HCI_EV_AUTH_COMPLETE] */
73133e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_AUTH_COMPLETE, hci_auth_complete_evt,
73143e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_auth_complete)),
73153e54c589SLuiz Augusto von Dentz 	/* [0x07 = HCI_EV_REMOTE_NAME] */
73163e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_REMOTE_NAME, hci_remote_name_evt,
73173e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_remote_name)),
73183e54c589SLuiz Augusto von Dentz 	/* [0x08 = HCI_EV_ENCRYPT_CHANGE] */
73193e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_ENCRYPT_CHANGE, hci_encrypt_change_evt,
73203e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_encrypt_change)),
73213e54c589SLuiz Augusto von Dentz 	/* [0x09 = HCI_EV_CHANGE_LINK_KEY_COMPLETE] */
73223e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_CHANGE_LINK_KEY_COMPLETE,
73233e54c589SLuiz Augusto von Dentz 	       hci_change_link_key_complete_evt,
73243e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_change_link_key_complete)),
73253e54c589SLuiz Augusto von Dentz 	/* [0x0b = HCI_EV_REMOTE_FEATURES] */
73263e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_REMOTE_FEATURES, hci_remote_features_evt,
73273e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_remote_features)),
73283e54c589SLuiz Augusto von Dentz 	/* [0x0e = HCI_EV_CMD_COMPLETE] */
73293e54c589SLuiz Augusto von Dentz 	HCI_EV_REQ_VL(HCI_EV_CMD_COMPLETE, hci_cmd_complete_evt,
73303e54c589SLuiz Augusto von Dentz 		      sizeof(struct hci_ev_cmd_complete), HCI_MAX_EVENT_SIZE),
73313e54c589SLuiz Augusto von Dentz 	/* [0x0f = HCI_EV_CMD_STATUS] */
73323e54c589SLuiz Augusto von Dentz 	HCI_EV_REQ(HCI_EV_CMD_STATUS, hci_cmd_status_evt,
73333e54c589SLuiz Augusto von Dentz 		   sizeof(struct hci_ev_cmd_status)),
73343e54c589SLuiz Augusto von Dentz 	/* [0x10 = HCI_EV_CMD_STATUS] */
73353e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_HARDWARE_ERROR, hci_hardware_error_evt,
73363e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_hardware_error)),
73373e54c589SLuiz Augusto von Dentz 	/* [0x12 = HCI_EV_ROLE_CHANGE] */
73383e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_ROLE_CHANGE, hci_role_change_evt,
73393e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_role_change)),
73403e54c589SLuiz Augusto von Dentz 	/* [0x13 = HCI_EV_NUM_COMP_PKTS] */
73413e54c589SLuiz Augusto von Dentz 	HCI_EV_VL(HCI_EV_NUM_COMP_PKTS, hci_num_comp_pkts_evt,
73423e54c589SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_num_comp_pkts), HCI_MAX_EVENT_SIZE),
73433e54c589SLuiz Augusto von Dentz 	/* [0x14 = HCI_EV_MODE_CHANGE] */
73443e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_MODE_CHANGE, hci_mode_change_evt,
73453e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_mode_change)),
73463e54c589SLuiz Augusto von Dentz 	/* [0x16 = HCI_EV_PIN_CODE_REQ] */
73473e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_PIN_CODE_REQ, hci_pin_code_request_evt,
73483e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_pin_code_req)),
73493e54c589SLuiz Augusto von Dentz 	/* [0x17 = HCI_EV_LINK_KEY_REQ] */
73503e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_LINK_KEY_REQ, hci_link_key_request_evt,
73513e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_link_key_req)),
73523e54c589SLuiz Augusto von Dentz 	/* [0x18 = HCI_EV_LINK_KEY_NOTIFY] */
73533e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_LINK_KEY_NOTIFY, hci_link_key_notify_evt,
73543e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_link_key_notify)),
73553e54c589SLuiz Augusto von Dentz 	/* [0x1c = HCI_EV_CLOCK_OFFSET] */
73563e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_CLOCK_OFFSET, hci_clock_offset_evt,
73573e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_clock_offset)),
73583e54c589SLuiz Augusto von Dentz 	/* [0x1d = HCI_EV_PKT_TYPE_CHANGE] */
73593e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_PKT_TYPE_CHANGE, hci_pkt_type_change_evt,
73603e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_pkt_type_change)),
73613e54c589SLuiz Augusto von Dentz 	/* [0x20 = HCI_EV_PSCAN_REP_MODE] */
73623e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_PSCAN_REP_MODE, hci_pscan_rep_mode_evt,
73633e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_pscan_rep_mode)),
73643e54c589SLuiz Augusto von Dentz 	/* [0x22 = HCI_EV_INQUIRY_RESULT_WITH_RSSI] */
73653e54c589SLuiz Augusto von Dentz 	HCI_EV_VL(HCI_EV_INQUIRY_RESULT_WITH_RSSI,
73663e54c589SLuiz Augusto von Dentz 		  hci_inquiry_result_with_rssi_evt,
73673e54c589SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_inquiry_result_rssi),
73683e54c589SLuiz Augusto von Dentz 		  HCI_MAX_EVENT_SIZE),
73693e54c589SLuiz Augusto von Dentz 	/* [0x23 = HCI_EV_REMOTE_EXT_FEATURES] */
73703e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_REMOTE_EXT_FEATURES, hci_remote_ext_features_evt,
73713e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_remote_ext_features)),
73723e54c589SLuiz Augusto von Dentz 	/* [0x2c = HCI_EV_SYNC_CONN_COMPLETE] */
73733e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_SYNC_CONN_COMPLETE, hci_sync_conn_complete_evt,
73743e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_sync_conn_complete)),
73753e54c589SLuiz Augusto von Dentz 	/* [0x2d = HCI_EV_EXTENDED_INQUIRY_RESULT] */
73763e54c589SLuiz Augusto von Dentz 	HCI_EV_VL(HCI_EV_EXTENDED_INQUIRY_RESULT,
73773e54c589SLuiz Augusto von Dentz 		  hci_extended_inquiry_result_evt,
73783e54c589SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_ext_inquiry_result), HCI_MAX_EVENT_SIZE),
73793e54c589SLuiz Augusto von Dentz 	/* [0x30 = HCI_EV_KEY_REFRESH_COMPLETE] */
73803e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_KEY_REFRESH_COMPLETE, hci_key_refresh_complete_evt,
73813e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_key_refresh_complete)),
73823e54c589SLuiz Augusto von Dentz 	/* [0x31 = HCI_EV_IO_CAPA_REQUEST] */
73833e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_IO_CAPA_REQUEST, hci_io_capa_request_evt,
73843e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_io_capa_request)),
73853e54c589SLuiz Augusto von Dentz 	/* [0x32 = HCI_EV_IO_CAPA_REPLY] */
73863e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_IO_CAPA_REPLY, hci_io_capa_reply_evt,
73873e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_io_capa_reply)),
73883e54c589SLuiz Augusto von Dentz 	/* [0x33 = HCI_EV_USER_CONFIRM_REQUEST] */
73893e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_USER_CONFIRM_REQUEST, hci_user_confirm_request_evt,
73903e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_user_confirm_req)),
73913e54c589SLuiz Augusto von Dentz 	/* [0x34 = HCI_EV_USER_PASSKEY_REQUEST] */
73923e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_USER_PASSKEY_REQUEST, hci_user_passkey_request_evt,
73933e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_user_passkey_req)),
73943e54c589SLuiz Augusto von Dentz 	/* [0x35 = HCI_EV_REMOTE_OOB_DATA_REQUEST] */
73953e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_REMOTE_OOB_DATA_REQUEST, hci_remote_oob_data_request_evt,
73963e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_remote_oob_data_request)),
73973e54c589SLuiz Augusto von Dentz 	/* [0x36 = HCI_EV_SIMPLE_PAIR_COMPLETE] */
73983e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_SIMPLE_PAIR_COMPLETE, hci_simple_pair_complete_evt,
73993e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_simple_pair_complete)),
74003e54c589SLuiz Augusto von Dentz 	/* [0x3b = HCI_EV_USER_PASSKEY_NOTIFY] */
74013e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_USER_PASSKEY_NOTIFY, hci_user_passkey_notify_evt,
74023e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_user_passkey_notify)),
74033e54c589SLuiz Augusto von Dentz 	/* [0x3c = HCI_EV_KEYPRESS_NOTIFY] */
74043e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_KEYPRESS_NOTIFY, hci_keypress_notify_evt,
74053e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_keypress_notify)),
74063e54c589SLuiz Augusto von Dentz 	/* [0x3d = HCI_EV_REMOTE_HOST_FEATURES] */
74073e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_REMOTE_HOST_FEATURES, hci_remote_host_features_evt,
74083e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_remote_host_features)),
74093e54c589SLuiz Augusto von Dentz 	/* [0x3e = HCI_EV_LE_META] */
741085b56857SLuiz Augusto von Dentz 	HCI_EV_REQ_VL(HCI_EV_LE_META, hci_le_meta_evt,
74113e54c589SLuiz Augusto von Dentz 		      sizeof(struct hci_ev_le_meta), HCI_MAX_EVENT_SIZE),
74123e54c589SLuiz Augusto von Dentz #if IS_ENABLED(CONFIG_BT_HS)
74133e54c589SLuiz Augusto von Dentz 	/* [0x40 = HCI_EV_PHY_LINK_COMPLETE] */
74143e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_PHY_LINK_COMPLETE, hci_phy_link_complete_evt,
74153e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_phy_link_complete)),
74163e54c589SLuiz Augusto von Dentz 	/* [0x41 = HCI_EV_CHANNEL_SELECTED] */
74173e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_CHANNEL_SELECTED, hci_chan_selected_evt,
74183e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_channel_selected)),
74193e54c589SLuiz Augusto von Dentz 	/* [0x42 = HCI_EV_DISCONN_PHY_LINK_COMPLETE] */
74203e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE,
74213e54c589SLuiz Augusto von Dentz 	       hci_disconn_loglink_complete_evt,
74223e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_disconn_logical_link_complete)),
74233e54c589SLuiz Augusto von Dentz 	/* [0x45 = HCI_EV_LOGICAL_LINK_COMPLETE] */
74243e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_LOGICAL_LINK_COMPLETE, hci_loglink_complete_evt,
74253e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_logical_link_complete)),
74263e54c589SLuiz Augusto von Dentz 	/* [0x46 = HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE] */
74273e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_DISCONN_PHY_LINK_COMPLETE,
74283e54c589SLuiz Augusto von Dentz 	       hci_disconn_phylink_complete_evt,
74293e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_disconn_phy_link_complete)),
74303e54c589SLuiz Augusto von Dentz #endif
74313e54c589SLuiz Augusto von Dentz 	/* [0x48 = HCI_EV_NUM_COMP_BLOCKS] */
74323e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_NUM_COMP_BLOCKS, hci_num_comp_blocks_evt,
74333e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_num_comp_blocks)),
74343e54c589SLuiz Augusto von Dentz 	/* [0xff = HCI_EV_VENDOR] */
7435314d8cd2SLuiz Augusto von Dentz 	HCI_EV_VL(HCI_EV_VENDOR, msft_vendor_evt, 0, HCI_MAX_EVENT_SIZE),
74363e54c589SLuiz Augusto von Dentz };
74373e54c589SLuiz Augusto von Dentz 
74383e54c589SLuiz Augusto von Dentz static void hci_event_func(struct hci_dev *hdev, u8 event, struct sk_buff *skb,
74393e54c589SLuiz Augusto von Dentz 			   u16 *opcode, u8 *status,
74403e54c589SLuiz Augusto von Dentz 			   hci_req_complete_t *req_complete,
74413e54c589SLuiz Augusto von Dentz 			   hci_req_complete_skb_t *req_complete_skb)
74423e54c589SLuiz Augusto von Dentz {
74433e54c589SLuiz Augusto von Dentz 	const struct hci_ev *ev = &hci_ev_table[event];
74443e54c589SLuiz Augusto von Dentz 	void *data;
74453e54c589SLuiz Augusto von Dentz 
74463e54c589SLuiz Augusto von Dentz 	if (!ev->func)
74473e54c589SLuiz Augusto von Dentz 		return;
74483e54c589SLuiz Augusto von Dentz 
74493e54c589SLuiz Augusto von Dentz 	if (skb->len < ev->min_len) {
74503e54c589SLuiz Augusto von Dentz 		bt_dev_err(hdev, "unexpected event 0x%2.2x length: %u < %u",
74513e54c589SLuiz Augusto von Dentz 			   event, skb->len, ev->min_len);
74523e54c589SLuiz Augusto von Dentz 		return;
74533e54c589SLuiz Augusto von Dentz 	}
74543e54c589SLuiz Augusto von Dentz 
74553e54c589SLuiz Augusto von Dentz 	/* Just warn if the length is over max_len size it still be
74563e54c589SLuiz Augusto von Dentz 	 * possible to partially parse the event so leave to callback to
74573e54c589SLuiz Augusto von Dentz 	 * decide if that is acceptable.
74583e54c589SLuiz Augusto von Dentz 	 */
74593e54c589SLuiz Augusto von Dentz 	if (skb->len > ev->max_len)
7460314d8cd2SLuiz Augusto von Dentz 		bt_dev_warn_ratelimited(hdev,
7461314d8cd2SLuiz Augusto von Dentz 					"unexpected event 0x%2.2x length: %u > %u",
74623e54c589SLuiz Augusto von Dentz 					event, skb->len, ev->max_len);
74633e54c589SLuiz Augusto von Dentz 
74643e54c589SLuiz Augusto von Dentz 	data = hci_ev_skb_pull(hdev, skb, event, ev->min_len);
74653e54c589SLuiz Augusto von Dentz 	if (!data)
74663e54c589SLuiz Augusto von Dentz 		return;
74673e54c589SLuiz Augusto von Dentz 
74683e54c589SLuiz Augusto von Dentz 	if (ev->req)
74693e54c589SLuiz Augusto von Dentz 		ev->func_req(hdev, data, skb, opcode, status, req_complete,
74703e54c589SLuiz Augusto von Dentz 			     req_complete_skb);
74713e54c589SLuiz Augusto von Dentz 	else
74723e54c589SLuiz Augusto von Dentz 		ev->func(hdev, data, skb);
74733e54c589SLuiz Augusto von Dentz }
74743e54c589SLuiz Augusto von Dentz 
74751da177e4SLinus Torvalds void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
74761da177e4SLinus Torvalds {
7477a9de9248SMarcel Holtmann 	struct hci_event_hdr *hdr = (void *) skb->data;
7478e6214487SJohan Hedberg 	hci_req_complete_t req_complete = NULL;
7479e6214487SJohan Hedberg 	hci_req_complete_skb_t req_complete_skb = NULL;
7480e6214487SJohan Hedberg 	struct sk_buff *orig_skb = NULL;
7481e3f3a1aeSLuiz Augusto von Dentz 	u8 status = 0, event, req_evt = 0;
7482e6214487SJohan Hedberg 	u16 opcode = HCI_OP_NOP;
74831da177e4SLinus Torvalds 
7484e3f3a1aeSLuiz Augusto von Dentz 	if (skb->len < sizeof(*hdr)) {
7485e3f3a1aeSLuiz Augusto von Dentz 		bt_dev_err(hdev, "Malformed HCI Event");
7486e3f3a1aeSLuiz Augusto von Dentz 		goto done;
7487e3f3a1aeSLuiz Augusto von Dentz 	}
7488e3f3a1aeSLuiz Augusto von Dentz 
7489dfe6d5c3SLuiz Augusto von Dentz 	kfree_skb(hdev->recv_event);
7490dfe6d5c3SLuiz Augusto von Dentz 	hdev->recv_event = skb_clone(skb, GFP_KERNEL);
7491dfe6d5c3SLuiz Augusto von Dentz 
7492e3f3a1aeSLuiz Augusto von Dentz 	event = hdr->evt;
749308bb4da9SAlain Michaud 	if (!event) {
74943e54c589SLuiz Augusto von Dentz 		bt_dev_warn(hdev, "Received unexpected HCI Event 0x%2.2x",
74953e54c589SLuiz Augusto von Dentz 			    event);
749608bb4da9SAlain Michaud 		goto done;
749708bb4da9SAlain Michaud 	}
749808bb4da9SAlain Michaud 
749985b56857SLuiz Augusto von Dentz 	/* Only match event if command OGF is not for LE */
750085b56857SLuiz Augusto von Dentz 	if (hdev->sent_cmd &&
750185b56857SLuiz Augusto von Dentz 	    hci_opcode_ogf(hci_skb_opcode(hdev->sent_cmd)) != 0x08 &&
750285b56857SLuiz Augusto von Dentz 	    hci_skb_event(hdev->sent_cmd) == event) {
750385b56857SLuiz Augusto von Dentz 		hci_req_cmd_complete(hdev, hci_skb_opcode(hdev->sent_cmd),
750485b56857SLuiz Augusto von Dentz 				     status, &req_complete, &req_complete_skb);
7505757aa0b5SJohan Hedberg 		req_evt = event;
750602350a72SJohan Hedberg 	}
750702350a72SJohan Hedberg 
7508e6214487SJohan Hedberg 	/* If it looks like we might end up having to call
7509e6214487SJohan Hedberg 	 * req_complete_skb, store a pristine copy of the skb since the
7510e6214487SJohan Hedberg 	 * various handlers may modify the original one through
7511e6214487SJohan Hedberg 	 * skb_pull() calls, etc.
7512e6214487SJohan Hedberg 	 */
7513e6214487SJohan Hedberg 	if (req_complete_skb || event == HCI_EV_CMD_STATUS ||
7514e6214487SJohan Hedberg 	    event == HCI_EV_CMD_COMPLETE)
7515e6214487SJohan Hedberg 		orig_skb = skb_clone(skb, GFP_KERNEL);
7516e6214487SJohan Hedberg 
7517e6214487SJohan Hedberg 	skb_pull(skb, HCI_EVENT_HDR_SIZE);
7518e6214487SJohan Hedberg 
75192f20216cSAbhishek Pandit-Subedi 	/* Store wake reason if we're suspended */
75202f20216cSAbhishek Pandit-Subedi 	hci_store_wake_reason(hdev, event, skb);
75212f20216cSAbhishek Pandit-Subedi 
75223e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "event 0x%2.2x", event);
75231da177e4SLinus Torvalds 
75243e54c589SLuiz Augusto von Dentz 	hci_event_func(hdev, event, skb, &opcode, &status, &req_complete,
7525e6214487SJohan Hedberg 		       &req_complete_skb);
75261da177e4SLinus Torvalds 
7527757aa0b5SJohan Hedberg 	if (req_complete) {
7528e6214487SJohan Hedberg 		req_complete(hdev, status, opcode);
7529757aa0b5SJohan Hedberg 	} else if (req_complete_skb) {
7530757aa0b5SJohan Hedberg 		if (!hci_get_cmd_complete(hdev, opcode, req_evt, orig_skb)) {
7531757aa0b5SJohan Hedberg 			kfree_skb(orig_skb);
7532757aa0b5SJohan Hedberg 			orig_skb = NULL;
7533757aa0b5SJohan Hedberg 		}
7534e6214487SJohan Hedberg 		req_complete_skb(hdev, status, opcode, orig_skb);
7535757aa0b5SJohan Hedberg 	}
7536e6214487SJohan Hedberg 
753708bb4da9SAlain Michaud done:
7538e6214487SJohan Hedberg 	kfree_skb(orig_skb);
75391da177e4SLinus Torvalds 	kfree_skb(skb);
75401da177e4SLinus Torvalds 	hdev->stat.evt_rx++;
75411da177e4SLinus Torvalds }
7542