xref: /openbmc/linux/net/bluetooth/hci_event.c (revision 853b70b5)
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;
331e3f3a1aeSLuiz Augusto von Dentz 
332e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
333a9366120SMarcel Holtmann 
334a9366120SMarcel Holtmann 	if (rp->status)
335c8992cffSLuiz Augusto von Dentz 		return rp->status;
336a9366120SMarcel Holtmann 
337a9366120SMarcel Holtmann 	if (rp->num_keys <= hdev->stored_num_keys)
3387978656cSLuiz Augusto von Dentz 		hdev->stored_num_keys -= le16_to_cpu(rp->num_keys);
339a9366120SMarcel Holtmann 	else
340a9366120SMarcel Holtmann 		hdev->stored_num_keys = 0;
341c8992cffSLuiz Augusto von Dentz 
342c8992cffSLuiz Augusto von Dentz 	return rp->status;
343a9366120SMarcel Holtmann }
344a9366120SMarcel Holtmann 
345c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_local_name(struct hci_dev *hdev, void *data,
346c8992cffSLuiz Augusto von Dentz 				  struct sk_buff *skb)
347a9de9248SMarcel Holtmann {
348c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
3491da177e4SLinus Torvalds 	void *sent;
3501da177e4SLinus Torvalds 
351e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
3521da177e4SLinus Torvalds 
353a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
3541da177e4SLinus Torvalds 	if (!sent)
355c8992cffSLuiz Augusto von Dentz 		return rp->status;
3561da177e4SLinus Torvalds 
35756e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
35856e5cb86SJohan Hedberg 
359d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
360e3f3a1aeSLuiz Augusto von Dentz 		mgmt_set_local_name_complete(hdev, sent, rp->status);
361e3f3a1aeSLuiz Augusto von Dentz 	else if (!rp->status)
36228cc7bdeSJohan Hedberg 		memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
363f51d5b24SJohan Hedberg 
36456e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
365c8992cffSLuiz Augusto von Dentz 
366c8992cffSLuiz Augusto von Dentz 	return rp->status;
367a9de9248SMarcel Holtmann }
368a9de9248SMarcel Holtmann 
369c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_name(struct hci_dev *hdev, void *data,
370c8992cffSLuiz Augusto von Dentz 				 struct sk_buff *skb)
371a9de9248SMarcel Holtmann {
372c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_name *rp = data;
373e3f3a1aeSLuiz Augusto von Dentz 
374e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
375a9de9248SMarcel Holtmann 
376a9de9248SMarcel Holtmann 	if (rp->status)
377c8992cffSLuiz Augusto von Dentz 		return rp->status;
378a9de9248SMarcel Holtmann 
379d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP) ||
380d7a5a11dSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_CONFIG))
3811f6c6378SJohan Hedberg 		memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
382c8992cffSLuiz Augusto von Dentz 
383c8992cffSLuiz Augusto von Dentz 	return rp->status;
384a9de9248SMarcel Holtmann }
385a9de9248SMarcel Holtmann 
386c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_auth_enable(struct hci_dev *hdev, void *data,
387c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
388a9de9248SMarcel Holtmann {
389c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
390a9de9248SMarcel Holtmann 	void *sent;
391a9de9248SMarcel Holtmann 
392e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
393a9de9248SMarcel Holtmann 
394a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
395a9de9248SMarcel Holtmann 	if (!sent)
396c8992cffSLuiz Augusto von Dentz 		return rp->status;
3971da177e4SLinus Torvalds 
3985c1a4c8fSJaganath Kanakkassery 	hci_dev_lock(hdev);
3995c1a4c8fSJaganath Kanakkassery 
400e3f3a1aeSLuiz Augusto von Dentz 	if (!rp->status) {
401a9de9248SMarcel Holtmann 		__u8 param = *((__u8 *) sent);
402a9de9248SMarcel Holtmann 
4031da177e4SLinus Torvalds 		if (param == AUTH_ENABLED)
4041da177e4SLinus Torvalds 			set_bit(HCI_AUTH, &hdev->flags);
4051da177e4SLinus Torvalds 		else
4061da177e4SLinus Torvalds 			clear_bit(HCI_AUTH, &hdev->flags);
4071da177e4SLinus Torvalds 	}
408a9de9248SMarcel Holtmann 
409d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
410e3f3a1aeSLuiz Augusto von Dentz 		mgmt_auth_enable_complete(hdev, rp->status);
4115c1a4c8fSJaganath Kanakkassery 
4125c1a4c8fSJaganath Kanakkassery 	hci_dev_unlock(hdev);
413c8992cffSLuiz Augusto von Dentz 
414c8992cffSLuiz Augusto von Dentz 	return rp->status;
415a9de9248SMarcel Holtmann }
4161da177e4SLinus Torvalds 
417c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_encrypt_mode(struct hci_dev *hdev, void *data,
418c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
419a9de9248SMarcel Holtmann {
420c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
42145296acdSMarcel Holtmann 	__u8 param;
422a9de9248SMarcel Holtmann 	void *sent;
423a9de9248SMarcel Holtmann 
424e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
425e3f3a1aeSLuiz Augusto von Dentz 
426e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
427c8992cffSLuiz Augusto von Dentz 		return rp->status;
42845296acdSMarcel Holtmann 
429a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
4301da177e4SLinus Torvalds 	if (!sent)
431c8992cffSLuiz Augusto von Dentz 		return rp->status;
4321da177e4SLinus Torvalds 
43345296acdSMarcel Holtmann 	param = *((__u8 *) sent);
434a9de9248SMarcel Holtmann 
4351da177e4SLinus Torvalds 	if (param)
4361da177e4SLinus Torvalds 		set_bit(HCI_ENCRYPT, &hdev->flags);
4371da177e4SLinus Torvalds 	else
4381da177e4SLinus Torvalds 		clear_bit(HCI_ENCRYPT, &hdev->flags);
439c8992cffSLuiz Augusto von Dentz 
440c8992cffSLuiz Augusto von Dentz 	return rp->status;
4411da177e4SLinus Torvalds }
4421da177e4SLinus Torvalds 
443c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_scan_enable(struct hci_dev *hdev, void *data,
444c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
445a9de9248SMarcel Holtmann {
446c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
44745296acdSMarcel Holtmann 	__u8 param;
448a9de9248SMarcel Holtmann 	void *sent;
4491da177e4SLinus Torvalds 
450e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
451a9de9248SMarcel Holtmann 
452a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
4531da177e4SLinus Torvalds 	if (!sent)
454c8992cffSLuiz Augusto von Dentz 		return rp->status;
4551da177e4SLinus Torvalds 
45636f7fc7eSJohan Hedberg 	param = *((__u8 *) sent);
457a9de9248SMarcel Holtmann 
45856e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
45956e5cb86SJohan Hedberg 
460e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status) {
4612d7cee58SJohan Hedberg 		hdev->discov_timeout = 0;
4622d7cee58SJohan Hedberg 		goto done;
4632d7cee58SJohan Hedberg 	}
4642d7cee58SJohan Hedberg 
465bc6d2d04SJohan Hedberg 	if (param & SCAN_INQUIRY)
4661da177e4SLinus Torvalds 		set_bit(HCI_ISCAN, &hdev->flags);
467bc6d2d04SJohan Hedberg 	else
468bc6d2d04SJohan Hedberg 		clear_bit(HCI_ISCAN, &hdev->flags);
4691da177e4SLinus Torvalds 
470031547d8SJohan Hedberg 	if (param & SCAN_PAGE)
4711da177e4SLinus Torvalds 		set_bit(HCI_PSCAN, &hdev->flags);
472bc6d2d04SJohan Hedberg 	else
473204e3990SJohan Hedberg 		clear_bit(HCI_PSCAN, &hdev->flags);
474a9de9248SMarcel Holtmann 
47536f7fc7eSJohan Hedberg done:
47656e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
477c8992cffSLuiz Augusto von Dentz 
478c8992cffSLuiz Augusto von Dentz 	return rp->status;
4791da177e4SLinus Torvalds }
4801da177e4SLinus Torvalds 
481c8992cffSLuiz Augusto von Dentz static u8 hci_cc_set_event_filter(struct hci_dev *hdev, void *data,
482c8992cffSLuiz Augusto von Dentz 				  struct sk_buff *skb)
483e5b0ad69SAbhishek Pandit-Subedi {
484c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
485e5b0ad69SAbhishek Pandit-Subedi 	struct hci_cp_set_event_filter *cp;
486e5b0ad69SAbhishek Pandit-Subedi 	void *sent;
487e5b0ad69SAbhishek Pandit-Subedi 
488e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
489e3f3a1aeSLuiz Augusto von Dentz 
490e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
491c8992cffSLuiz Augusto von Dentz 		return rp->status;
492e5b0ad69SAbhishek Pandit-Subedi 
493e5b0ad69SAbhishek Pandit-Subedi 	sent = hci_sent_cmd_data(hdev, HCI_OP_SET_EVENT_FLT);
494e5b0ad69SAbhishek Pandit-Subedi 	if (!sent)
495c8992cffSLuiz Augusto von Dentz 		return rp->status;
496e5b0ad69SAbhishek Pandit-Subedi 
497e5b0ad69SAbhishek Pandit-Subedi 	cp = (struct hci_cp_set_event_filter *)sent;
498e5b0ad69SAbhishek Pandit-Subedi 
499e5b0ad69SAbhishek Pandit-Subedi 	if (cp->flt_type == HCI_FLT_CLEAR_ALL)
500e5b0ad69SAbhishek Pandit-Subedi 		hci_dev_clear_flag(hdev, HCI_EVENT_FILTER_CONFIGURED);
501e5b0ad69SAbhishek Pandit-Subedi 	else
502e5b0ad69SAbhishek Pandit-Subedi 		hci_dev_set_flag(hdev, HCI_EVENT_FILTER_CONFIGURED);
503c8992cffSLuiz Augusto von Dentz 
504c8992cffSLuiz Augusto von Dentz 	return rp->status;
505e5b0ad69SAbhishek Pandit-Subedi }
506e5b0ad69SAbhishek Pandit-Subedi 
507c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_class_of_dev(struct hci_dev *hdev, void *data,
508c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
509a9de9248SMarcel Holtmann {
510c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_class_of_dev *rp = data;
511e3f3a1aeSLuiz Augusto von Dentz 
512e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
513a9de9248SMarcel Holtmann 
514a9de9248SMarcel Holtmann 	if (rp->status)
515c8992cffSLuiz Augusto von Dentz 		return rp->status;
516a9de9248SMarcel Holtmann 
517a9de9248SMarcel Holtmann 	memcpy(hdev->dev_class, rp->dev_class, 3);
518a9de9248SMarcel Holtmann 
519e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "class 0x%.2x%.2x%.2x", hdev->dev_class[2],
520e3f3a1aeSLuiz Augusto von Dentz 		   hdev->dev_class[1], hdev->dev_class[0]);
521c8992cffSLuiz Augusto von Dentz 
522c8992cffSLuiz Augusto von Dentz 	return rp->status;
523a9de9248SMarcel Holtmann }
524a9de9248SMarcel Holtmann 
525c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_class_of_dev(struct hci_dev *hdev, void *data,
526c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
527a9de9248SMarcel Holtmann {
528c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
529a9de9248SMarcel Holtmann 	void *sent;
530a9de9248SMarcel Holtmann 
531e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
532a9de9248SMarcel Holtmann 
533a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
534a9de9248SMarcel Holtmann 	if (!sent)
535c8992cffSLuiz Augusto von Dentz 		return rp->status;
536a9de9248SMarcel Holtmann 
5377f9a903cSMarcel Holtmann 	hci_dev_lock(hdev);
5387f9a903cSMarcel Holtmann 
539e3f3a1aeSLuiz Augusto von Dentz 	if (!rp->status)
540a9de9248SMarcel Holtmann 		memcpy(hdev->dev_class, sent, 3);
5417f9a903cSMarcel Holtmann 
542d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
543e3f3a1aeSLuiz Augusto von Dentz 		mgmt_set_class_of_dev_complete(hdev, sent, rp->status);
5447f9a903cSMarcel Holtmann 
5457f9a903cSMarcel Holtmann 	hci_dev_unlock(hdev);
546c8992cffSLuiz Augusto von Dentz 
547c8992cffSLuiz Augusto von Dentz 	return rp->status;
548a9de9248SMarcel Holtmann }
549a9de9248SMarcel Holtmann 
550c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_voice_setting(struct hci_dev *hdev, void *data,
551c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
552a9de9248SMarcel Holtmann {
553c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_voice_setting *rp = data;
554a9de9248SMarcel Holtmann 	__u16 setting;
555a9de9248SMarcel Holtmann 
556e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
557a9de9248SMarcel Holtmann 
558a9de9248SMarcel Holtmann 	if (rp->status)
559c8992cffSLuiz Augusto von Dentz 		return rp->status;
560a9de9248SMarcel Holtmann 
561a9de9248SMarcel Holtmann 	setting = __le16_to_cpu(rp->voice_setting);
562a9de9248SMarcel Holtmann 
563a9de9248SMarcel Holtmann 	if (hdev->voice_setting == setting)
564c8992cffSLuiz Augusto von Dentz 		return rp->status;
565a9de9248SMarcel Holtmann 
566a9de9248SMarcel Holtmann 	hdev->voice_setting = setting;
567a9de9248SMarcel Holtmann 
568e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "voice setting 0x%4.4x", setting);
569a9de9248SMarcel Holtmann 
5703c54711cSGustavo F. Padovan 	if (hdev->notify)
571a9de9248SMarcel Holtmann 		hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
572c8992cffSLuiz Augusto von Dentz 
573c8992cffSLuiz Augusto von Dentz 	return rp->status;
574a9de9248SMarcel Holtmann }
575a9de9248SMarcel Holtmann 
576c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_voice_setting(struct hci_dev *hdev, void *data,
5778fc9ced3SGustavo Padovan 				     struct sk_buff *skb)
578a9de9248SMarcel Holtmann {
579c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
580f383f275SMarcel Holtmann 	__u16 setting;
581a9de9248SMarcel Holtmann 	void *sent;
582a9de9248SMarcel Holtmann 
583e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
584e3f3a1aeSLuiz Augusto von Dentz 
585e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
586c8992cffSLuiz Augusto von Dentz 		return rp->status;
587f383f275SMarcel Holtmann 
588a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
589a9de9248SMarcel Holtmann 	if (!sent)
590c8992cffSLuiz Augusto von Dentz 		return rp->status;
591a9de9248SMarcel Holtmann 
592f383f275SMarcel Holtmann 	setting = get_unaligned_le16(sent);
5931da177e4SLinus Torvalds 
594f383f275SMarcel Holtmann 	if (hdev->voice_setting == setting)
595c8992cffSLuiz Augusto von Dentz 		return rp->status;
596f383f275SMarcel Holtmann 
5971da177e4SLinus Torvalds 	hdev->voice_setting = setting;
5981da177e4SLinus Torvalds 
599e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "voice setting 0x%4.4x", setting);
6001da177e4SLinus Torvalds 
6013c54711cSGustavo F. Padovan 	if (hdev->notify)
6021da177e4SLinus Torvalds 		hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
603c8992cffSLuiz Augusto von Dentz 
604c8992cffSLuiz Augusto von Dentz 	return rp->status;
6051da177e4SLinus Torvalds }
6061da177e4SLinus Torvalds 
607c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_num_supported_iac(struct hci_dev *hdev, void *data,
608b4cb9fb2SMarcel Holtmann 					struct sk_buff *skb)
609b4cb9fb2SMarcel Holtmann {
610c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_num_supported_iac *rp = data;
611e3f3a1aeSLuiz Augusto von Dentz 
612e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
613b4cb9fb2SMarcel Holtmann 
614b4cb9fb2SMarcel Holtmann 	if (rp->status)
615c8992cffSLuiz Augusto von Dentz 		return rp->status;
616b4cb9fb2SMarcel Holtmann 
617b4cb9fb2SMarcel Holtmann 	hdev->num_iac = rp->num_iac;
618b4cb9fb2SMarcel Holtmann 
619e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "num iac %d", hdev->num_iac);
620c8992cffSLuiz Augusto von Dentz 
621c8992cffSLuiz Augusto von Dentz 	return rp->status;
622b4cb9fb2SMarcel Holtmann }
623b4cb9fb2SMarcel Holtmann 
624c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_ssp_mode(struct hci_dev *hdev, void *data,
625c8992cffSLuiz Augusto von Dentz 				struct sk_buff *skb)
626333140b5SMarcel Holtmann {
627c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
6285ed8eb2fSJohan Hedberg 	struct hci_cp_write_ssp_mode *sent;
629333140b5SMarcel Holtmann 
630e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
631333140b5SMarcel Holtmann 
632333140b5SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
633333140b5SMarcel Holtmann 	if (!sent)
634c8992cffSLuiz Augusto von Dentz 		return rp->status;
635333140b5SMarcel Holtmann 
6365c1a4c8fSJaganath Kanakkassery 	hci_dev_lock(hdev);
6375c1a4c8fSJaganath Kanakkassery 
638e3f3a1aeSLuiz Augusto von Dentz 	if (!rp->status) {
6395ed8eb2fSJohan Hedberg 		if (sent->mode)
640cad718edSJohan Hedberg 			hdev->features[1][0] |= LMP_HOST_SSP;
6415ed8eb2fSJohan Hedberg 		else
642cad718edSJohan Hedberg 			hdev->features[1][0] &= ~LMP_HOST_SSP;
6435ed8eb2fSJohan Hedberg 	}
6445ed8eb2fSJohan Hedberg 
645e3f3a1aeSLuiz Augusto von Dentz 	if (!rp->status) {
6465ed8eb2fSJohan Hedberg 		if (sent->mode)
647a1536da2SMarcel Holtmann 			hci_dev_set_flag(hdev, HCI_SSP_ENABLED);
64884bde9d6SJohan Hedberg 		else
649a358dc11SMarcel Holtmann 			hci_dev_clear_flag(hdev, HCI_SSP_ENABLED);
650c0ecddc2SJohan Hedberg 	}
6515c1a4c8fSJaganath Kanakkassery 
6525c1a4c8fSJaganath Kanakkassery 	hci_dev_unlock(hdev);
653c8992cffSLuiz Augusto von Dentz 
654c8992cffSLuiz Augusto von Dentz 	return rp->status;
655333140b5SMarcel Holtmann }
656333140b5SMarcel Holtmann 
657c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_sc_support(struct hci_dev *hdev, void *data,
658c8992cffSLuiz Augusto von Dentz 				  struct sk_buff *skb)
659eac83dc6SMarcel Holtmann {
660c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
661eac83dc6SMarcel Holtmann 	struct hci_cp_write_sc_support *sent;
662eac83dc6SMarcel Holtmann 
663e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
664eac83dc6SMarcel Holtmann 
665eac83dc6SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SC_SUPPORT);
666eac83dc6SMarcel Holtmann 	if (!sent)
667c8992cffSLuiz Augusto von Dentz 		return rp->status;
668eac83dc6SMarcel Holtmann 
6695c1a4c8fSJaganath Kanakkassery 	hci_dev_lock(hdev);
6705c1a4c8fSJaganath Kanakkassery 
671e3f3a1aeSLuiz Augusto von Dentz 	if (!rp->status) {
672eac83dc6SMarcel Holtmann 		if (sent->support)
673eac83dc6SMarcel Holtmann 			hdev->features[1][0] |= LMP_HOST_SC;
674eac83dc6SMarcel Holtmann 		else
675eac83dc6SMarcel Holtmann 			hdev->features[1][0] &= ~LMP_HOST_SC;
676eac83dc6SMarcel Holtmann 	}
677eac83dc6SMarcel Holtmann 
678e3f3a1aeSLuiz Augusto von Dentz 	if (!hci_dev_test_flag(hdev, HCI_MGMT) && !rp->status) {
679eac83dc6SMarcel Holtmann 		if (sent->support)
680a1536da2SMarcel Holtmann 			hci_dev_set_flag(hdev, HCI_SC_ENABLED);
681eac83dc6SMarcel Holtmann 		else
682a358dc11SMarcel Holtmann 			hci_dev_clear_flag(hdev, HCI_SC_ENABLED);
683eac83dc6SMarcel Holtmann 	}
6845c1a4c8fSJaganath Kanakkassery 
6855c1a4c8fSJaganath Kanakkassery 	hci_dev_unlock(hdev);
686c8992cffSLuiz Augusto von Dentz 
687c8992cffSLuiz Augusto von Dentz 	return rp->status;
688eac83dc6SMarcel Holtmann }
689eac83dc6SMarcel Holtmann 
690c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_version(struct hci_dev *hdev, void *data,
691c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
692a9de9248SMarcel Holtmann {
693c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_version *rp = data;
694e3f3a1aeSLuiz Augusto von Dentz 
695e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
6961143e5a6SMarcel Holtmann 
697a9de9248SMarcel Holtmann 	if (rp->status)
698c8992cffSLuiz Augusto von Dentz 		return rp->status;
6991143e5a6SMarcel Holtmann 
700d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP) ||
701d7a5a11dSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_CONFIG)) {
702a9de9248SMarcel Holtmann 		hdev->hci_ver = rp->hci_ver;
703e4e8e37cSMarcel Holtmann 		hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
704d5859e22SJohan Hedberg 		hdev->lmp_ver = rp->lmp_ver;
705e4e8e37cSMarcel Holtmann 		hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
706d5859e22SJohan Hedberg 		hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
7070d5551f5SMarcel Holtmann 	}
708c8992cffSLuiz Augusto von Dentz 
709c8992cffSLuiz Augusto von Dentz 	return rp->status;
710d5859e22SJohan Hedberg }
711d5859e22SJohan Hedberg 
712c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_commands(struct hci_dev *hdev, void *data,
7138fc9ced3SGustavo Padovan 				     struct sk_buff *skb)
714a9de9248SMarcel Holtmann {
715c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_commands *rp = data;
716e3f3a1aeSLuiz Augusto von Dentz 
717e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
718a9de9248SMarcel Holtmann 
7196a070e6eSMarcel Holtmann 	if (rp->status)
720c8992cffSLuiz Augusto von Dentz 		return rp->status;
7216a070e6eSMarcel Holtmann 
722d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP) ||
723d7a5a11dSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_CONFIG))
724a9de9248SMarcel Holtmann 		memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
725c8992cffSLuiz Augusto von Dentz 
726c8992cffSLuiz Augusto von Dentz 	return rp->status;
727a9de9248SMarcel Holtmann }
728a9de9248SMarcel Holtmann 
729c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_auth_payload_timeout(struct hci_dev *hdev, void *data,
730302975cbSSpoorthi Ravishankar Koppad 					   struct sk_buff *skb)
731302975cbSSpoorthi Ravishankar Koppad {
732c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_auth_payload_to *rp = data;
733302975cbSSpoorthi Ravishankar Koppad 	struct hci_conn *conn;
734302975cbSSpoorthi Ravishankar Koppad 
735e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
736302975cbSSpoorthi Ravishankar Koppad 
737302975cbSSpoorthi Ravishankar Koppad 	if (rp->status)
738c8992cffSLuiz Augusto von Dentz 		return rp->status;
739302975cbSSpoorthi Ravishankar Koppad 
740302975cbSSpoorthi Ravishankar Koppad 	hci_dev_lock(hdev);
741302975cbSSpoorthi Ravishankar Koppad 
742302975cbSSpoorthi Ravishankar Koppad 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
743302975cbSSpoorthi Ravishankar Koppad 	if (conn)
744302975cbSSpoorthi Ravishankar Koppad 		conn->auth_payload_timeout = __le16_to_cpu(rp->timeout);
745302975cbSSpoorthi Ravishankar Koppad 
746302975cbSSpoorthi Ravishankar Koppad 	hci_dev_unlock(hdev);
747c8992cffSLuiz Augusto von Dentz 
748c8992cffSLuiz Augusto von Dentz 	return rp->status;
749302975cbSSpoorthi Ravishankar Koppad }
750302975cbSSpoorthi Ravishankar Koppad 
751c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_auth_payload_timeout(struct hci_dev *hdev, void *data,
752302975cbSSpoorthi Ravishankar Koppad 					    struct sk_buff *skb)
753302975cbSSpoorthi Ravishankar Koppad {
754c8992cffSLuiz Augusto von Dentz 	struct hci_rp_write_auth_payload_to *rp = data;
755302975cbSSpoorthi Ravishankar Koppad 	struct hci_conn *conn;
756302975cbSSpoorthi Ravishankar Koppad 	void *sent;
757302975cbSSpoorthi Ravishankar Koppad 
758e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
759302975cbSSpoorthi Ravishankar Koppad 
760302975cbSSpoorthi Ravishankar Koppad 	if (rp->status)
761c8992cffSLuiz Augusto von Dentz 		return rp->status;
762302975cbSSpoorthi Ravishankar Koppad 
763302975cbSSpoorthi Ravishankar Koppad 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_PAYLOAD_TO);
764302975cbSSpoorthi Ravishankar Koppad 	if (!sent)
765c8992cffSLuiz Augusto von Dentz 		return rp->status;
766302975cbSSpoorthi Ravishankar Koppad 
767302975cbSSpoorthi Ravishankar Koppad 	hci_dev_lock(hdev);
768302975cbSSpoorthi Ravishankar Koppad 
769302975cbSSpoorthi Ravishankar Koppad 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
770302975cbSSpoorthi Ravishankar Koppad 	if (conn)
771302975cbSSpoorthi Ravishankar Koppad 		conn->auth_payload_timeout = get_unaligned_le16(sent + 2);
772302975cbSSpoorthi Ravishankar Koppad 
773302975cbSSpoorthi Ravishankar Koppad 	hci_dev_unlock(hdev);
774c8992cffSLuiz Augusto von Dentz 
775c8992cffSLuiz Augusto von Dentz 	return rp->status;
776302975cbSSpoorthi Ravishankar Koppad }
777302975cbSSpoorthi Ravishankar Koppad 
778c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_features(struct hci_dev *hdev, void *data,
7798fc9ced3SGustavo Padovan 				     struct sk_buff *skb)
780a9de9248SMarcel Holtmann {
781c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_features *rp = data;
782e3f3a1aeSLuiz Augusto von Dentz 
783e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
784a9de9248SMarcel Holtmann 
785a9de9248SMarcel Holtmann 	if (rp->status)
786c8992cffSLuiz Augusto von Dentz 		return rp->status;
787a9de9248SMarcel Holtmann 
788a9de9248SMarcel Holtmann 	memcpy(hdev->features, rp->features, 8);
7891da177e4SLinus Torvalds 
7901da177e4SLinus Torvalds 	/* Adjust default settings according to features
7911da177e4SLinus Torvalds 	 * supported by device. */
792a9de9248SMarcel Holtmann 
793cad718edSJohan Hedberg 	if (hdev->features[0][0] & LMP_3SLOT)
7941da177e4SLinus Torvalds 		hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
7951da177e4SLinus Torvalds 
796cad718edSJohan Hedberg 	if (hdev->features[0][0] & LMP_5SLOT)
7971da177e4SLinus Torvalds 		hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
7981da177e4SLinus Torvalds 
799cad718edSJohan Hedberg 	if (hdev->features[0][1] & LMP_HV2) {
8001da177e4SLinus Torvalds 		hdev->pkt_type  |= (HCI_HV2);
8015b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_HV2);
8025b7f9909SMarcel Holtmann 	}
8031da177e4SLinus Torvalds 
804cad718edSJohan Hedberg 	if (hdev->features[0][1] & LMP_HV3) {
8051da177e4SLinus Torvalds 		hdev->pkt_type  |= (HCI_HV3);
8065b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_HV3);
8075b7f9909SMarcel Holtmann 	}
8085b7f9909SMarcel Holtmann 
80945db810fSAndre Guedes 	if (lmp_esco_capable(hdev))
8105b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_EV3);
8115b7f9909SMarcel Holtmann 
812cad718edSJohan Hedberg 	if (hdev->features[0][4] & LMP_EV4)
8135b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_EV4);
8145b7f9909SMarcel Holtmann 
815cad718edSJohan Hedberg 	if (hdev->features[0][4] & LMP_EV5)
8165b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_EV5);
8171da177e4SLinus Torvalds 
818cad718edSJohan Hedberg 	if (hdev->features[0][5] & LMP_EDR_ESCO_2M)
819efc7688bSMarcel Holtmann 		hdev->esco_type |= (ESCO_2EV3);
820efc7688bSMarcel Holtmann 
821cad718edSJohan Hedberg 	if (hdev->features[0][5] & LMP_EDR_ESCO_3M)
822efc7688bSMarcel Holtmann 		hdev->esco_type |= (ESCO_3EV3);
823efc7688bSMarcel Holtmann 
824cad718edSJohan Hedberg 	if (hdev->features[0][5] & LMP_EDR_3S_ESCO)
825efc7688bSMarcel Holtmann 		hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
826c8992cffSLuiz Augusto von Dentz 
827c8992cffSLuiz Augusto von Dentz 	return rp->status;
8281da177e4SLinus Torvalds }
8291da177e4SLinus Torvalds 
830c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_ext_features(struct hci_dev *hdev, void *data,
831971e3a4bSAndre Guedes 					 struct sk_buff *skb)
832971e3a4bSAndre Guedes {
833c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_ext_features *rp = data;
834e3f3a1aeSLuiz Augusto von Dentz 
835e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
836971e3a4bSAndre Guedes 
837971e3a4bSAndre Guedes 	if (rp->status)
838c8992cffSLuiz Augusto von Dentz 		return rp->status;
839971e3a4bSAndre Guedes 
84057af75a8SMarcel Holtmann 	if (hdev->max_page < rp->max_page)
841d2c5d77fSJohan Hedberg 		hdev->max_page = rp->max_page;
842d2c5d77fSJohan Hedberg 
843cad718edSJohan Hedberg 	if (rp->page < HCI_MAX_PAGES)
844cad718edSJohan Hedberg 		memcpy(hdev->features[rp->page], rp->features, 8);
845c8992cffSLuiz Augusto von Dentz 
846c8992cffSLuiz Augusto von Dentz 	return rp->status;
847971e3a4bSAndre Guedes }
848971e3a4bSAndre Guedes 
849c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_flow_control_mode(struct hci_dev *hdev, void *data,
8501e89cffbSAndrei Emeltchenko 					struct sk_buff *skb)
8511e89cffbSAndrei Emeltchenko {
852c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_flow_control_mode *rp = data;
853e3f3a1aeSLuiz Augusto von Dentz 
854e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
8551e89cffbSAndrei Emeltchenko 
85645296acdSMarcel Holtmann 	if (rp->status)
857c8992cffSLuiz Augusto von Dentz 		return rp->status;
85845296acdSMarcel Holtmann 
8591e89cffbSAndrei Emeltchenko 	hdev->flow_ctl_mode = rp->mode;
860c8992cffSLuiz Augusto von Dentz 
861c8992cffSLuiz Augusto von Dentz 	return rp->status;
8621e89cffbSAndrei Emeltchenko }
8631e89cffbSAndrei Emeltchenko 
864c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_buffer_size(struct hci_dev *hdev, void *data,
865c8992cffSLuiz Augusto von Dentz 				  struct sk_buff *skb)
866a9de9248SMarcel Holtmann {
867c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_buffer_size *rp = data;
868e3f3a1aeSLuiz Augusto von Dentz 
869e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
870a9de9248SMarcel Holtmann 
871a9de9248SMarcel Holtmann 	if (rp->status)
872c8992cffSLuiz Augusto von Dentz 		return rp->status;
873a9de9248SMarcel Holtmann 
874a9de9248SMarcel Holtmann 	hdev->acl_mtu  = __le16_to_cpu(rp->acl_mtu);
875a9de9248SMarcel Holtmann 	hdev->sco_mtu  = rp->sco_mtu;
876a9de9248SMarcel Holtmann 	hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
877a9de9248SMarcel Holtmann 	hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
878da1f5198SMarcel Holtmann 
879da1f5198SMarcel Holtmann 	if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
880da1f5198SMarcel Holtmann 		hdev->sco_mtu  = 64;
881da1f5198SMarcel Holtmann 		hdev->sco_pkts = 8;
882da1f5198SMarcel Holtmann 	}
883da1f5198SMarcel Holtmann 
884da1f5198SMarcel Holtmann 	hdev->acl_cnt = hdev->acl_pkts;
885da1f5198SMarcel Holtmann 	hdev->sco_cnt = hdev->sco_pkts;
8861da177e4SLinus Torvalds 
887807deac2SGustavo Padovan 	BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
888807deac2SGustavo Padovan 	       hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
889c8992cffSLuiz Augusto von Dentz 
890c8992cffSLuiz Augusto von Dentz 	return rp->status;
8911da177e4SLinus Torvalds }
8921da177e4SLinus Torvalds 
893c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_bd_addr(struct hci_dev *hdev, void *data,
894c8992cffSLuiz Augusto von Dentz 			      struct sk_buff *skb)
895a9de9248SMarcel Holtmann {
896c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_bd_addr *rp = data;
897e3f3a1aeSLuiz Augusto von Dentz 
898e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
899a9de9248SMarcel Holtmann 
900e30d3f5fSMarcel Holtmann 	if (rp->status)
901c8992cffSLuiz Augusto von Dentz 		return rp->status;
902e30d3f5fSMarcel Holtmann 
903e30d3f5fSMarcel Holtmann 	if (test_bit(HCI_INIT, &hdev->flags))
904a9de9248SMarcel Holtmann 		bacpy(&hdev->bdaddr, &rp->bdaddr);
905e30d3f5fSMarcel Holtmann 
906d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP))
907e30d3f5fSMarcel Holtmann 		bacpy(&hdev->setup_addr, &rp->bdaddr);
908c8992cffSLuiz Augusto von Dentz 
909c8992cffSLuiz Augusto von Dentz 	return rp->status;
91023bb5763SJohan Hedberg }
91123bb5763SJohan Hedberg 
912c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_pairing_opts(struct hci_dev *hdev, void *data,
913a4790360SMarcel Holtmann 					 struct sk_buff *skb)
914a4790360SMarcel Holtmann {
915c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_pairing_opts *rp = data;
916e3f3a1aeSLuiz Augusto von Dentz 
917e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
918a4790360SMarcel Holtmann 
919a4790360SMarcel Holtmann 	if (rp->status)
920c8992cffSLuiz Augusto von Dentz 		return rp->status;
921a4790360SMarcel Holtmann 
922a4790360SMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP) ||
923a4790360SMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_CONFIG)) {
924a4790360SMarcel Holtmann 		hdev->pairing_opts = rp->pairing_opts;
925a4790360SMarcel Holtmann 		hdev->max_enc_key_size = rp->max_key_size;
926a4790360SMarcel Holtmann 	}
927c8992cffSLuiz Augusto von Dentz 
928c8992cffSLuiz Augusto von Dentz 	return rp->status;
929a4790360SMarcel Holtmann }
930a4790360SMarcel Holtmann 
931c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_page_scan_activity(struct hci_dev *hdev, void *data,
932f332ec66SJohan Hedberg 					 struct sk_buff *skb)
933f332ec66SJohan Hedberg {
934c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_page_scan_activity *rp = data;
935e3f3a1aeSLuiz Augusto von Dentz 
936e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
937f332ec66SJohan Hedberg 
93845296acdSMarcel Holtmann 	if (rp->status)
939c8992cffSLuiz Augusto von Dentz 		return rp->status;
94045296acdSMarcel Holtmann 
94145296acdSMarcel Holtmann 	if (test_bit(HCI_INIT, &hdev->flags)) {
942f332ec66SJohan Hedberg 		hdev->page_scan_interval = __le16_to_cpu(rp->interval);
943f332ec66SJohan Hedberg 		hdev->page_scan_window = __le16_to_cpu(rp->window);
944f332ec66SJohan Hedberg 	}
945c8992cffSLuiz Augusto von Dentz 
946c8992cffSLuiz Augusto von Dentz 	return rp->status;
947f332ec66SJohan Hedberg }
948f332ec66SJohan Hedberg 
949c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_page_scan_activity(struct hci_dev *hdev, void *data,
9504a3ee763SJohan Hedberg 					  struct sk_buff *skb)
9514a3ee763SJohan Hedberg {
952c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
9534a3ee763SJohan Hedberg 	struct hci_cp_write_page_scan_activity *sent;
9544a3ee763SJohan Hedberg 
955e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
956e3f3a1aeSLuiz Augusto von Dentz 
957e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
958c8992cffSLuiz Augusto von Dentz 		return rp->status;
9594a3ee763SJohan Hedberg 
9604a3ee763SJohan Hedberg 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY);
9614a3ee763SJohan Hedberg 	if (!sent)
962c8992cffSLuiz Augusto von Dentz 		return rp->status;
9634a3ee763SJohan Hedberg 
9644a3ee763SJohan Hedberg 	hdev->page_scan_interval = __le16_to_cpu(sent->interval);
9654a3ee763SJohan Hedberg 	hdev->page_scan_window = __le16_to_cpu(sent->window);
966c8992cffSLuiz Augusto von Dentz 
967c8992cffSLuiz Augusto von Dentz 	return rp->status;
9684a3ee763SJohan Hedberg }
9694a3ee763SJohan Hedberg 
970c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_page_scan_type(struct hci_dev *hdev, void *data,
971f332ec66SJohan Hedberg 				     struct sk_buff *skb)
972f332ec66SJohan Hedberg {
973c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_page_scan_type *rp = data;
974e3f3a1aeSLuiz Augusto von Dentz 
975e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
976f332ec66SJohan Hedberg 
97745296acdSMarcel Holtmann 	if (rp->status)
978c8992cffSLuiz Augusto von Dentz 		return rp->status;
97945296acdSMarcel Holtmann 
98045296acdSMarcel Holtmann 	if (test_bit(HCI_INIT, &hdev->flags))
981f332ec66SJohan Hedberg 		hdev->page_scan_type = rp->type;
982c8992cffSLuiz Augusto von Dentz 
983c8992cffSLuiz Augusto von Dentz 	return rp->status;
984f332ec66SJohan Hedberg }
985f332ec66SJohan Hedberg 
986c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_page_scan_type(struct hci_dev *hdev, void *data,
9874a3ee763SJohan Hedberg 				      struct sk_buff *skb)
9884a3ee763SJohan Hedberg {
989c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
9904a3ee763SJohan Hedberg 	u8 *type;
9914a3ee763SJohan Hedberg 
992e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
993e3f3a1aeSLuiz Augusto von Dentz 
994e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
995c8992cffSLuiz Augusto von Dentz 		return rp->status;
9964a3ee763SJohan Hedberg 
9974a3ee763SJohan Hedberg 	type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE);
9984a3ee763SJohan Hedberg 	if (type)
9994a3ee763SJohan Hedberg 		hdev->page_scan_type = *type;
1000c8992cffSLuiz Augusto von Dentz 
1001c8992cffSLuiz Augusto von Dentz 	return rp->status;
10024a3ee763SJohan Hedberg }
10034a3ee763SJohan Hedberg 
1004c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_data_block_size(struct hci_dev *hdev, void *data,
1005350ee4cfSAndrei Emeltchenko 				      struct sk_buff *skb)
1006350ee4cfSAndrei Emeltchenko {
1007c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_data_block_size *rp = data;
1008e3f3a1aeSLuiz Augusto von Dentz 
1009e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1010350ee4cfSAndrei Emeltchenko 
1011350ee4cfSAndrei Emeltchenko 	if (rp->status)
1012c8992cffSLuiz Augusto von Dentz 		return rp->status;
1013350ee4cfSAndrei Emeltchenko 
1014350ee4cfSAndrei Emeltchenko 	hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
1015350ee4cfSAndrei Emeltchenko 	hdev->block_len = __le16_to_cpu(rp->block_len);
1016350ee4cfSAndrei Emeltchenko 	hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
1017350ee4cfSAndrei Emeltchenko 
1018350ee4cfSAndrei Emeltchenko 	hdev->block_cnt = hdev->num_blocks;
1019350ee4cfSAndrei Emeltchenko 
1020350ee4cfSAndrei Emeltchenko 	BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
1021350ee4cfSAndrei Emeltchenko 	       hdev->block_cnt, hdev->block_len);
1022c8992cffSLuiz Augusto von Dentz 
1023c8992cffSLuiz Augusto von Dentz 	return rp->status;
1024350ee4cfSAndrei Emeltchenko }
1025350ee4cfSAndrei Emeltchenko 
1026c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_clock(struct hci_dev *hdev, void *data,
1027c8992cffSLuiz Augusto von Dentz 			    struct sk_buff *skb)
102833f35721SJohan Hedberg {
1029c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_clock *rp = data;
103033f35721SJohan Hedberg 	struct hci_cp_read_clock *cp;
103133f35721SJohan Hedberg 	struct hci_conn *conn;
103233f35721SJohan Hedberg 
1033e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1034e3f3a1aeSLuiz Augusto von Dentz 
103533f35721SJohan Hedberg 	if (rp->status)
1036c8992cffSLuiz Augusto von Dentz 		return rp->status;
103733f35721SJohan Hedberg 
103833f35721SJohan Hedberg 	hci_dev_lock(hdev);
103933f35721SJohan Hedberg 
104033f35721SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_READ_CLOCK);
104133f35721SJohan Hedberg 	if (!cp)
104233f35721SJohan Hedberg 		goto unlock;
104333f35721SJohan Hedberg 
104433f35721SJohan Hedberg 	if (cp->which == 0x00) {
104533f35721SJohan Hedberg 		hdev->clock = le32_to_cpu(rp->clock);
104633f35721SJohan Hedberg 		goto unlock;
104733f35721SJohan Hedberg 	}
104833f35721SJohan Hedberg 
104933f35721SJohan Hedberg 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
105033f35721SJohan Hedberg 	if (conn) {
105133f35721SJohan Hedberg 		conn->clock = le32_to_cpu(rp->clock);
105233f35721SJohan Hedberg 		conn->clock_accuracy = le16_to_cpu(rp->accuracy);
105333f35721SJohan Hedberg 	}
105433f35721SJohan Hedberg 
105533f35721SJohan Hedberg unlock:
105633f35721SJohan Hedberg 	hci_dev_unlock(hdev);
1057c8992cffSLuiz Augusto von Dentz 	return rp->status;
105833f35721SJohan Hedberg }
105933f35721SJohan Hedberg 
1060c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_amp_info(struct hci_dev *hdev, void *data,
1061928abaa7SAndrei Emeltchenko 				     struct sk_buff *skb)
1062928abaa7SAndrei Emeltchenko {
1063c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_amp_info *rp = data;
1064e3f3a1aeSLuiz Augusto von Dentz 
1065e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1066928abaa7SAndrei Emeltchenko 
1067928abaa7SAndrei Emeltchenko 	if (rp->status)
1068c8992cffSLuiz Augusto von Dentz 		return rp->status;
1069928abaa7SAndrei Emeltchenko 
1070928abaa7SAndrei Emeltchenko 	hdev->amp_status = rp->amp_status;
1071928abaa7SAndrei Emeltchenko 	hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
1072928abaa7SAndrei Emeltchenko 	hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
1073928abaa7SAndrei Emeltchenko 	hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
1074928abaa7SAndrei Emeltchenko 	hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
1075928abaa7SAndrei Emeltchenko 	hdev->amp_type = rp->amp_type;
1076928abaa7SAndrei Emeltchenko 	hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
1077928abaa7SAndrei Emeltchenko 	hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
1078928abaa7SAndrei Emeltchenko 	hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
1079928abaa7SAndrei Emeltchenko 	hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
1080c8992cffSLuiz Augusto von Dentz 
1081c8992cffSLuiz Augusto von Dentz 	return rp->status;
1082928abaa7SAndrei Emeltchenko }
1083928abaa7SAndrei Emeltchenko 
1084c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev, void *data,
1085d5859e22SJohan Hedberg 				       struct sk_buff *skb)
1086d5859e22SJohan Hedberg {
1087c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_inq_rsp_tx_power *rp = data;
1088e3f3a1aeSLuiz Augusto von Dentz 
1089e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1090d5859e22SJohan Hedberg 
109145296acdSMarcel Holtmann 	if (rp->status)
1092c8992cffSLuiz Augusto von Dentz 		return rp->status;
109345296acdSMarcel Holtmann 
109491c4e9b1SMarcel Holtmann 	hdev->inq_tx_power = rp->tx_power;
1095c8992cffSLuiz Augusto von Dentz 
1096c8992cffSLuiz Augusto von Dentz 	return rp->status;
1097d5859e22SJohan Hedberg }
1098d5859e22SJohan Hedberg 
1099c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_def_err_data_reporting(struct hci_dev *hdev, void *data,
110000bce3fbSAlain Michaud 					     struct sk_buff *skb)
110100bce3fbSAlain Michaud {
1102c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_def_err_data_reporting *rp = data;
1103e3f3a1aeSLuiz Augusto von Dentz 
1104e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
110500bce3fbSAlain Michaud 
110600bce3fbSAlain Michaud 	if (rp->status)
1107c8992cffSLuiz Augusto von Dentz 		return rp->status;
110800bce3fbSAlain Michaud 
110900bce3fbSAlain Michaud 	hdev->err_data_reporting = rp->err_data_reporting;
1110c8992cffSLuiz Augusto von Dentz 
1111c8992cffSLuiz Augusto von Dentz 	return rp->status;
111200bce3fbSAlain Michaud }
111300bce3fbSAlain Michaud 
1114c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_def_err_data_reporting(struct hci_dev *hdev, void *data,
111500bce3fbSAlain Michaud 					      struct sk_buff *skb)
111600bce3fbSAlain Michaud {
1117c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
111800bce3fbSAlain Michaud 	struct hci_cp_write_def_err_data_reporting *cp;
111900bce3fbSAlain Michaud 
1120e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1121e3f3a1aeSLuiz Augusto von Dentz 
1122e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1123c8992cffSLuiz Augusto von Dentz 		return rp->status;
112400bce3fbSAlain Michaud 
112500bce3fbSAlain Michaud 	cp = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_ERR_DATA_REPORTING);
112600bce3fbSAlain Michaud 	if (!cp)
1127c8992cffSLuiz Augusto von Dentz 		return rp->status;
112800bce3fbSAlain Michaud 
112900bce3fbSAlain Michaud 	hdev->err_data_reporting = cp->err_data_reporting;
1130c8992cffSLuiz Augusto von Dentz 
1131c8992cffSLuiz Augusto von Dentz 	return rp->status;
113200bce3fbSAlain Michaud }
113300bce3fbSAlain Michaud 
1134c8992cffSLuiz Augusto von Dentz static u8 hci_cc_pin_code_reply(struct hci_dev *hdev, void *data,
1135c8992cffSLuiz Augusto von Dentz 				struct sk_buff *skb)
1136980e1a53SJohan Hedberg {
1137c8992cffSLuiz Augusto von Dentz 	struct hci_rp_pin_code_reply *rp = data;
1138980e1a53SJohan Hedberg 	struct hci_cp_pin_code_reply *cp;
1139980e1a53SJohan Hedberg 	struct hci_conn *conn;
1140980e1a53SJohan Hedberg 
1141e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1142980e1a53SJohan Hedberg 
114356e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
114456e5cb86SJohan Hedberg 
1145d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
1146744cf19eSJohan Hedberg 		mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
1147980e1a53SJohan Hedberg 
1148fa1bd918SMikel Astiz 	if (rp->status)
114956e5cb86SJohan Hedberg 		goto unlock;
1150980e1a53SJohan Hedberg 
1151980e1a53SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
1152980e1a53SJohan Hedberg 	if (!cp)
115356e5cb86SJohan Hedberg 		goto unlock;
1154980e1a53SJohan Hedberg 
1155980e1a53SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1156980e1a53SJohan Hedberg 	if (conn)
1157980e1a53SJohan Hedberg 		conn->pin_length = cp->pin_len;
115856e5cb86SJohan Hedberg 
115956e5cb86SJohan Hedberg unlock:
116056e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
1161c8992cffSLuiz Augusto von Dentz 	return rp->status;
1162980e1a53SJohan Hedberg }
1163980e1a53SJohan Hedberg 
1164c8992cffSLuiz Augusto von Dentz static u8 hci_cc_pin_code_neg_reply(struct hci_dev *hdev, void *data,
1165c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
1166980e1a53SJohan Hedberg {
1167c8992cffSLuiz Augusto von Dentz 	struct hci_rp_pin_code_neg_reply *rp = data;
1168e3f3a1aeSLuiz Augusto von Dentz 
1169e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1170980e1a53SJohan Hedberg 
117156e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
117256e5cb86SJohan Hedberg 
1173d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
1174744cf19eSJohan Hedberg 		mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
1175980e1a53SJohan Hedberg 						 rp->status);
117656e5cb86SJohan Hedberg 
117756e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
1178c8992cffSLuiz Augusto von Dentz 
1179c8992cffSLuiz Augusto von Dentz 	return rp->status;
1180980e1a53SJohan Hedberg }
118156e5cb86SJohan Hedberg 
1182c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_buffer_size(struct hci_dev *hdev, void *data,
11836ed58ec5SVille Tervo 				     struct sk_buff *skb)
11846ed58ec5SVille Tervo {
1185c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_buffer_size *rp = data;
1186e3f3a1aeSLuiz Augusto von Dentz 
1187e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
11886ed58ec5SVille Tervo 
11896ed58ec5SVille Tervo 	if (rp->status)
1190c8992cffSLuiz Augusto von Dentz 		return rp->status;
11916ed58ec5SVille Tervo 
11926ed58ec5SVille Tervo 	hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
11936ed58ec5SVille Tervo 	hdev->le_pkts = rp->le_max_pkt;
11946ed58ec5SVille Tervo 
11956ed58ec5SVille Tervo 	hdev->le_cnt = hdev->le_pkts;
11966ed58ec5SVille Tervo 
11976ed58ec5SVille Tervo 	BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
1198c8992cffSLuiz Augusto von Dentz 
1199c8992cffSLuiz Augusto von Dentz 	return rp->status;
12006ed58ec5SVille Tervo }
1201980e1a53SJohan Hedberg 
1202c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_local_features(struct hci_dev *hdev, void *data,
120360e77321SJohan Hedberg 					struct sk_buff *skb)
120460e77321SJohan Hedberg {
1205c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_local_features *rp = data;
120660e77321SJohan Hedberg 
120760e77321SJohan Hedberg 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
120860e77321SJohan Hedberg 
120945296acdSMarcel Holtmann 	if (rp->status)
1210c8992cffSLuiz Augusto von Dentz 		return rp->status;
121145296acdSMarcel Holtmann 
121260e77321SJohan Hedberg 	memcpy(hdev->le_features, rp->features, 8);
1213c8992cffSLuiz Augusto von Dentz 
1214c8992cffSLuiz Augusto von Dentz 	return rp->status;
121560e77321SJohan Hedberg }
121660e77321SJohan Hedberg 
1217c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_adv_tx_power(struct hci_dev *hdev, void *data,
12188fa19098SJohan Hedberg 				      struct sk_buff *skb)
12198fa19098SJohan Hedberg {
1220c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_adv_tx_power *rp = data;
1221e3f3a1aeSLuiz Augusto von Dentz 
1222e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
12238fa19098SJohan Hedberg 
122445296acdSMarcel Holtmann 	if (rp->status)
1225c8992cffSLuiz Augusto von Dentz 		return rp->status;
122645296acdSMarcel Holtmann 
12278fa19098SJohan Hedberg 	hdev->adv_tx_power = rp->tx_power;
1228c8992cffSLuiz Augusto von Dentz 
1229c8992cffSLuiz Augusto von Dentz 	return rp->status;
12308fa19098SJohan Hedberg }
12318fa19098SJohan Hedberg 
1232c8992cffSLuiz Augusto von Dentz static u8 hci_cc_user_confirm_reply(struct hci_dev *hdev, void *data,
1233c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
1234a5c29683SJohan Hedberg {
1235c8992cffSLuiz Augusto von Dentz 	struct hci_rp_user_confirm_reply *rp = data;
1236e3f3a1aeSLuiz Augusto von Dentz 
1237e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1238a5c29683SJohan Hedberg 
123956e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
124056e5cb86SJohan Hedberg 
1241d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
124204124681SGustavo F. Padovan 		mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
124304124681SGustavo F. Padovan 						 rp->status);
124456e5cb86SJohan Hedberg 
124556e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
1246c8992cffSLuiz Augusto von Dentz 
1247c8992cffSLuiz Augusto von Dentz 	return rp->status;
1248a5c29683SJohan Hedberg }
1249a5c29683SJohan Hedberg 
1250c8992cffSLuiz Augusto von Dentz static u8 hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, void *data,
1251a5c29683SJohan Hedberg 					struct sk_buff *skb)
1252a5c29683SJohan Hedberg {
1253c8992cffSLuiz Augusto von Dentz 	struct hci_rp_user_confirm_reply *rp = data;
1254e3f3a1aeSLuiz Augusto von Dentz 
1255e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1256a5c29683SJohan Hedberg 
125756e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
125856e5cb86SJohan Hedberg 
1259d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
1260744cf19eSJohan Hedberg 		mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
126104124681SGustavo F. Padovan 						     ACL_LINK, 0, rp->status);
126256e5cb86SJohan Hedberg 
126356e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
1264c8992cffSLuiz Augusto von Dentz 
1265c8992cffSLuiz Augusto von Dentz 	return rp->status;
1266a5c29683SJohan Hedberg }
1267a5c29683SJohan Hedberg 
1268c8992cffSLuiz Augusto von Dentz static u8 hci_cc_user_passkey_reply(struct hci_dev *hdev, void *data,
1269c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
12701143d458SBrian Gix {
1271c8992cffSLuiz Augusto von Dentz 	struct hci_rp_user_confirm_reply *rp = data;
1272e3f3a1aeSLuiz Augusto von Dentz 
1273e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
12741143d458SBrian Gix 
12751143d458SBrian Gix 	hci_dev_lock(hdev);
12761143d458SBrian Gix 
1277d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
1278272d90dfSJohan Hedberg 		mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
1279272d90dfSJohan Hedberg 						 0, rp->status);
12801143d458SBrian Gix 
12811143d458SBrian Gix 	hci_dev_unlock(hdev);
1282c8992cffSLuiz Augusto von Dentz 
1283c8992cffSLuiz Augusto von Dentz 	return rp->status;
12841143d458SBrian Gix }
12851143d458SBrian Gix 
1286c8992cffSLuiz Augusto von Dentz static u8 hci_cc_user_passkey_neg_reply(struct hci_dev *hdev, void *data,
12871143d458SBrian Gix 					struct sk_buff *skb)
12881143d458SBrian Gix {
1289c8992cffSLuiz Augusto von Dentz 	struct hci_rp_user_confirm_reply *rp = data;
1290e3f3a1aeSLuiz Augusto von Dentz 
1291e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
12921143d458SBrian Gix 
12931143d458SBrian Gix 	hci_dev_lock(hdev);
12941143d458SBrian Gix 
1295d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
12961143d458SBrian Gix 		mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
129704124681SGustavo F. Padovan 						     ACL_LINK, 0, rp->status);
12981143d458SBrian Gix 
12991143d458SBrian Gix 	hci_dev_unlock(hdev);
1300c8992cffSLuiz Augusto von Dentz 
1301c8992cffSLuiz Augusto von Dentz 	return rp->status;
13021143d458SBrian Gix }
13031143d458SBrian Gix 
1304c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_oob_data(struct hci_dev *hdev, void *data,
1305c35938b2SSzymon Janc 				     struct sk_buff *skb)
1306c35938b2SSzymon Janc {
1307c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_oob_data *rp = data;
1308e3f3a1aeSLuiz Augusto von Dentz 
1309e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1310c8992cffSLuiz Augusto von Dentz 
1311c8992cffSLuiz Augusto von Dentz 	return rp->status;
13124d2d2796SMarcel Holtmann }
13134d2d2796SMarcel Holtmann 
1314c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_oob_ext_data(struct hci_dev *hdev, void *data,
13154d2d2796SMarcel Holtmann 					 struct sk_buff *skb)
13164d2d2796SMarcel Holtmann {
1317c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_oob_ext_data *rp = data;
1318e3f3a1aeSLuiz Augusto von Dentz 
1319e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1320c8992cffSLuiz Augusto von Dentz 
1321c8992cffSLuiz Augusto von Dentz 	return rp->status;
1322c35938b2SSzymon Janc }
1323c35938b2SSzymon Janc 
1324c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_random_addr(struct hci_dev *hdev, void *data,
1325c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
13267a4cd51dSMarcel Holtmann {
1327c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
13287a4cd51dSMarcel Holtmann 	bdaddr_t *sent;
13297a4cd51dSMarcel Holtmann 
1330e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1331e3f3a1aeSLuiz Augusto von Dentz 
1332e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1333c8992cffSLuiz Augusto von Dentz 		return rp->status;
133445296acdSMarcel Holtmann 
13357a4cd51dSMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_RANDOM_ADDR);
13367a4cd51dSMarcel Holtmann 	if (!sent)
1337c8992cffSLuiz Augusto von Dentz 		return rp->status;
13387a4cd51dSMarcel Holtmann 
13397a4cd51dSMarcel Holtmann 	hci_dev_lock(hdev);
13407a4cd51dSMarcel Holtmann 
13417a4cd51dSMarcel Holtmann 	bacpy(&hdev->random_addr, sent);
13427a4cd51dSMarcel Holtmann 
1343c45074d6SLuiz Augusto von Dentz 	if (!bacmp(&hdev->rpa, sent)) {
1344c45074d6SLuiz Augusto von Dentz 		hci_dev_clear_flag(hdev, HCI_RPA_EXPIRED);
1345c45074d6SLuiz Augusto von Dentz 		queue_delayed_work(hdev->workqueue, &hdev->rpa_expired,
1346c45074d6SLuiz Augusto von Dentz 				   secs_to_jiffies(hdev->rpa_timeout));
1347c45074d6SLuiz Augusto von Dentz 	}
1348c45074d6SLuiz Augusto von Dentz 
13497a4cd51dSMarcel Holtmann 	hci_dev_unlock(hdev);
1350c8992cffSLuiz Augusto von Dentz 
1351c8992cffSLuiz Augusto von Dentz 	return rp->status;
13527a4cd51dSMarcel Holtmann }
13537a4cd51dSMarcel Holtmann 
1354c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_default_phy(struct hci_dev *hdev, void *data,
1355c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
13560314f286SJaganath Kanakkassery {
1357c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
13580314f286SJaganath Kanakkassery 	struct hci_cp_le_set_default_phy *cp;
13590314f286SJaganath Kanakkassery 
1360e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1361e3f3a1aeSLuiz Augusto von Dentz 
1362e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1363c8992cffSLuiz Augusto von Dentz 		return rp->status;
13640314f286SJaganath Kanakkassery 
13650314f286SJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_DEFAULT_PHY);
13660314f286SJaganath Kanakkassery 	if (!cp)
1367c8992cffSLuiz Augusto von Dentz 		return rp->status;
13680314f286SJaganath Kanakkassery 
13690314f286SJaganath Kanakkassery 	hci_dev_lock(hdev);
13700314f286SJaganath Kanakkassery 
13710314f286SJaganath Kanakkassery 	hdev->le_tx_def_phys = cp->tx_phys;
13720314f286SJaganath Kanakkassery 	hdev->le_rx_def_phys = cp->rx_phys;
13730314f286SJaganath Kanakkassery 
13740314f286SJaganath Kanakkassery 	hci_dev_unlock(hdev);
1375c8992cffSLuiz Augusto von Dentz 
1376c8992cffSLuiz Augusto von Dentz 	return rp->status;
13770314f286SJaganath Kanakkassery }
13780314f286SJaganath Kanakkassery 
1379c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_adv_set_random_addr(struct hci_dev *hdev, void *data,
1380a73c046aSJaganath Kanakkassery 					    struct sk_buff *skb)
1381a73c046aSJaganath Kanakkassery {
1382c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1383a73c046aSJaganath Kanakkassery 	struct hci_cp_le_set_adv_set_rand_addr *cp;
1384c45074d6SLuiz Augusto von Dentz 	struct adv_info *adv;
1385a73c046aSJaganath Kanakkassery 
1386e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1387e3f3a1aeSLuiz Augusto von Dentz 
1388e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1389c8992cffSLuiz Augusto von Dentz 		return rp->status;
1390a73c046aSJaganath Kanakkassery 
1391a73c046aSJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_SET_RAND_ADDR);
1392c45074d6SLuiz Augusto von Dentz 	/* Update only in case the adv instance since handle 0x00 shall be using
1393c45074d6SLuiz Augusto von Dentz 	 * HCI_OP_LE_SET_RANDOM_ADDR since that allows both extended and
1394c45074d6SLuiz Augusto von Dentz 	 * non-extended adverting.
1395c45074d6SLuiz Augusto von Dentz 	 */
1396c45074d6SLuiz Augusto von Dentz 	if (!cp || !cp->handle)
1397c8992cffSLuiz Augusto von Dentz 		return rp->status;
1398a73c046aSJaganath Kanakkassery 
1399a73c046aSJaganath Kanakkassery 	hci_dev_lock(hdev);
1400a73c046aSJaganath Kanakkassery 
1401c45074d6SLuiz Augusto von Dentz 	adv = hci_find_adv_instance(hdev, cp->handle);
1402c45074d6SLuiz Augusto von Dentz 	if (adv) {
1403c45074d6SLuiz Augusto von Dentz 		bacpy(&adv->random_addr, &cp->bdaddr);
1404c45074d6SLuiz Augusto von Dentz 		if (!bacmp(&hdev->rpa, &cp->bdaddr)) {
1405c45074d6SLuiz Augusto von Dentz 			adv->rpa_expired = false;
1406c45074d6SLuiz Augusto von Dentz 			queue_delayed_work(hdev->workqueue,
1407c45074d6SLuiz Augusto von Dentz 					   &adv->rpa_expired_cb,
1408c45074d6SLuiz Augusto von Dentz 					   secs_to_jiffies(hdev->rpa_timeout));
1409c45074d6SLuiz Augusto von Dentz 		}
1410a73c046aSJaganath Kanakkassery 	}
1411a73c046aSJaganath Kanakkassery 
1412a73c046aSJaganath Kanakkassery 	hci_dev_unlock(hdev);
1413c8992cffSLuiz Augusto von Dentz 
1414c8992cffSLuiz Augusto von Dentz 	return rp->status;
1415a73c046aSJaganath Kanakkassery }
1416a73c046aSJaganath Kanakkassery 
1417c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_remove_adv_set(struct hci_dev *hdev, void *data,
1418c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
1419cba6b758SLuiz Augusto von Dentz {
1420c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1421cba6b758SLuiz Augusto von Dentz 	u8 *instance;
1422cba6b758SLuiz Augusto von Dentz 	int err;
1423cba6b758SLuiz Augusto von Dentz 
1424e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1425e3f3a1aeSLuiz Augusto von Dentz 
1426e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1427c8992cffSLuiz Augusto von Dentz 		return rp->status;
1428cba6b758SLuiz Augusto von Dentz 
1429cba6b758SLuiz Augusto von Dentz 	instance = hci_sent_cmd_data(hdev, HCI_OP_LE_REMOVE_ADV_SET);
1430cba6b758SLuiz Augusto von Dentz 	if (!instance)
1431c8992cffSLuiz Augusto von Dentz 		return rp->status;
1432cba6b758SLuiz Augusto von Dentz 
1433cba6b758SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
1434cba6b758SLuiz Augusto von Dentz 
1435cba6b758SLuiz Augusto von Dentz 	err = hci_remove_adv_instance(hdev, *instance);
1436cba6b758SLuiz Augusto von Dentz 	if (!err)
1437cba6b758SLuiz Augusto von Dentz 		mgmt_advertising_removed(hci_skb_sk(hdev->sent_cmd), hdev,
1438cba6b758SLuiz Augusto von Dentz 					 *instance);
1439cba6b758SLuiz Augusto von Dentz 
1440cba6b758SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
1441c8992cffSLuiz Augusto von Dentz 
1442c8992cffSLuiz Augusto von Dentz 	return rp->status;
1443cba6b758SLuiz Augusto von Dentz }
1444cba6b758SLuiz Augusto von Dentz 
1445c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_clear_adv_sets(struct hci_dev *hdev, void *data,
1446c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
1447cba6b758SLuiz Augusto von Dentz {
1448c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1449cba6b758SLuiz Augusto von Dentz 	struct adv_info *adv, *n;
1450cba6b758SLuiz Augusto von Dentz 	int err;
1451cba6b758SLuiz Augusto von Dentz 
1452e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1453e3f3a1aeSLuiz Augusto von Dentz 
1454e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1455c8992cffSLuiz Augusto von Dentz 		return rp->status;
1456cba6b758SLuiz Augusto von Dentz 
1457cba6b758SLuiz Augusto von Dentz 	if (!hci_sent_cmd_data(hdev, HCI_OP_LE_CLEAR_ADV_SETS))
1458c8992cffSLuiz Augusto von Dentz 		return rp->status;
1459cba6b758SLuiz Augusto von Dentz 
1460cba6b758SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
1461cba6b758SLuiz Augusto von Dentz 
1462cba6b758SLuiz Augusto von Dentz 	list_for_each_entry_safe(adv, n, &hdev->adv_instances, list) {
1463cba6b758SLuiz Augusto von Dentz 		u8 instance = adv->instance;
1464cba6b758SLuiz Augusto von Dentz 
1465cba6b758SLuiz Augusto von Dentz 		err = hci_remove_adv_instance(hdev, instance);
1466cba6b758SLuiz Augusto von Dentz 		if (!err)
1467cba6b758SLuiz Augusto von Dentz 			mgmt_advertising_removed(hci_skb_sk(hdev->sent_cmd),
1468cba6b758SLuiz Augusto von Dentz 						 hdev, instance);
1469cba6b758SLuiz Augusto von Dentz 	}
1470cba6b758SLuiz Augusto von Dentz 
1471cba6b758SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
1472c8992cffSLuiz Augusto von Dentz 
1473c8992cffSLuiz Augusto von Dentz 	return rp->status;
1474cba6b758SLuiz Augusto von Dentz }
1475cba6b758SLuiz Augusto von Dentz 
1476c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_transmit_power(struct hci_dev *hdev, void *data,
14777c395ea5SDaniel Winkler 					struct sk_buff *skb)
14787c395ea5SDaniel Winkler {
1479c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_transmit_power *rp = data;
1480e3f3a1aeSLuiz Augusto von Dentz 
1481e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
14827c395ea5SDaniel Winkler 
14837c395ea5SDaniel Winkler 	if (rp->status)
1484c8992cffSLuiz Augusto von Dentz 		return rp->status;
14857c395ea5SDaniel Winkler 
14867c395ea5SDaniel Winkler 	hdev->min_le_tx_power = rp->min_le_tx_power;
14877c395ea5SDaniel Winkler 	hdev->max_le_tx_power = rp->max_le_tx_power;
1488c8992cffSLuiz Augusto von Dentz 
1489c8992cffSLuiz Augusto von Dentz 	return rp->status;
14907c395ea5SDaniel Winkler }
14917c395ea5SDaniel Winkler 
1492*853b70b5SLuiz Augusto von Dentz static u8 hci_cc_le_set_privacy_mode(struct hci_dev *hdev, void *data,
1493*853b70b5SLuiz Augusto von Dentz 				     struct sk_buff *skb)
1494*853b70b5SLuiz Augusto von Dentz {
1495*853b70b5SLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1496*853b70b5SLuiz Augusto von Dentz 	struct hci_cp_le_set_privacy_mode *cp;
1497*853b70b5SLuiz Augusto von Dentz 	struct hci_conn_params *params;
1498*853b70b5SLuiz Augusto von Dentz 
1499*853b70b5SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1500*853b70b5SLuiz Augusto von Dentz 
1501*853b70b5SLuiz Augusto von Dentz 	if (rp->status)
1502*853b70b5SLuiz Augusto von Dentz 		return rp->status;
1503*853b70b5SLuiz Augusto von Dentz 
1504*853b70b5SLuiz Augusto von Dentz 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_PRIVACY_MODE);
1505*853b70b5SLuiz Augusto von Dentz 	if (!cp)
1506*853b70b5SLuiz Augusto von Dentz 		return rp->status;
1507*853b70b5SLuiz Augusto von Dentz 
1508*853b70b5SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
1509*853b70b5SLuiz Augusto von Dentz 
1510*853b70b5SLuiz Augusto von Dentz 	params = hci_conn_params_lookup(hdev, &cp->bdaddr, cp->bdaddr_type);
1511*853b70b5SLuiz Augusto von Dentz 	if (params)
1512*853b70b5SLuiz Augusto von Dentz 		params->privacy_mode = cp->mode;
1513*853b70b5SLuiz Augusto von Dentz 
1514*853b70b5SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
1515*853b70b5SLuiz Augusto von Dentz 
1516*853b70b5SLuiz Augusto von Dentz 	return rp->status;
1517*853b70b5SLuiz Augusto von Dentz }
1518*853b70b5SLuiz Augusto von Dentz 
1519c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_adv_enable(struct hci_dev *hdev, void *data,
1520c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
1521c1d5dc4aSJohan Hedberg {
1522c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1523e3f3a1aeSLuiz Augusto von Dentz 	__u8 *sent;
1524c1d5dc4aSJohan Hedberg 
1525e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1526e3f3a1aeSLuiz Augusto von Dentz 
1527e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1528c8992cffSLuiz Augusto von Dentz 		return rp->status;
1529c1d5dc4aSJohan Hedberg 
153045296acdSMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
153145296acdSMarcel Holtmann 	if (!sent)
1532c8992cffSLuiz Augusto von Dentz 		return rp->status;
15333c857757SJohan Hedberg 
1534c1d5dc4aSJohan Hedberg 	hci_dev_lock(hdev);
1535c1d5dc4aSJohan Hedberg 
153649c922bbSStephen Hemminger 	/* If we're doing connection initiation as peripheral. Set a
15373c857757SJohan Hedberg 	 * timeout in case something goes wrong.
15383c857757SJohan Hedberg 	 */
15393c857757SJohan Hedberg 	if (*sent) {
15403c857757SJohan Hedberg 		struct hci_conn *conn;
15413c857757SJohan Hedberg 
1542a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_LE_ADV);
154366c417c1SJohan Hedberg 
1544e7d9ab73SJakub Pawlowski 		conn = hci_lookup_le_connect(hdev);
15453c857757SJohan Hedberg 		if (conn)
15463c857757SJohan Hedberg 			queue_delayed_work(hdev->workqueue,
15473c857757SJohan Hedberg 					   &conn->le_conn_timeout,
154809ae260bSJohan Hedberg 					   conn->conn_timeout);
154966c417c1SJohan Hedberg 	} else {
1550a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LE_ADV);
15513c857757SJohan Hedberg 	}
15523c857757SJohan Hedberg 
155304b4edcbSJohan Hedberg 	hci_dev_unlock(hdev);
1554c8992cffSLuiz Augusto von Dentz 
1555c8992cffSLuiz Augusto von Dentz 	return rp->status;
1556c1d5dc4aSJohan Hedberg }
1557c1d5dc4aSJohan Hedberg 
1558c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_ext_adv_enable(struct hci_dev *hdev, void *data,
1559de181e88SJaganath Kanakkassery 				       struct sk_buff *skb)
1560de181e88SJaganath Kanakkassery {
1561de181e88SJaganath Kanakkassery 	struct hci_cp_le_set_ext_adv_enable *cp;
156210279313SLuiz Augusto von Dentz 	struct hci_cp_ext_adv_set *set;
156310279313SLuiz Augusto von Dentz 	struct adv_info *adv = NULL, *n;
1564c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1565de181e88SJaganath Kanakkassery 
1566e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1567e3f3a1aeSLuiz Augusto von Dentz 
1568e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1569c8992cffSLuiz Augusto von Dentz 		return rp->status;
1570de181e88SJaganath Kanakkassery 
1571de181e88SJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_ADV_ENABLE);
1572de181e88SJaganath Kanakkassery 	if (!cp)
1573c8992cffSLuiz Augusto von Dentz 		return rp->status;
1574de181e88SJaganath Kanakkassery 
157510279313SLuiz Augusto von Dentz 	set = (void *)cp->data;
157610279313SLuiz Augusto von Dentz 
1577de181e88SJaganath Kanakkassery 	hci_dev_lock(hdev);
1578de181e88SJaganath Kanakkassery 
157910279313SLuiz Augusto von Dentz 	if (cp->num_of_sets)
158010279313SLuiz Augusto von Dentz 		adv = hci_find_adv_instance(hdev, set->handle);
158110279313SLuiz Augusto von Dentz 
1582de181e88SJaganath Kanakkassery 	if (cp->enable) {
1583de181e88SJaganath Kanakkassery 		struct hci_conn *conn;
1584de181e88SJaganath Kanakkassery 
1585de181e88SJaganath Kanakkassery 		hci_dev_set_flag(hdev, HCI_LE_ADV);
1586de181e88SJaganath Kanakkassery 
158710279313SLuiz Augusto von Dentz 		if (adv)
158810279313SLuiz Augusto von Dentz 			adv->enabled = true;
158910279313SLuiz Augusto von Dentz 
1590de181e88SJaganath Kanakkassery 		conn = hci_lookup_le_connect(hdev);
1591de181e88SJaganath Kanakkassery 		if (conn)
1592de181e88SJaganath Kanakkassery 			queue_delayed_work(hdev->workqueue,
1593de181e88SJaganath Kanakkassery 					   &conn->le_conn_timeout,
1594de181e88SJaganath Kanakkassery 					   conn->conn_timeout);
159545b7749fSJaganath Kanakkassery 	} else {
15962128939fSArchie Pusaka 		if (cp->num_of_sets) {
15972128939fSArchie Pusaka 			if (adv)
159810279313SLuiz Augusto von Dentz 				adv->enabled = false;
15992128939fSArchie Pusaka 
160010279313SLuiz Augusto von Dentz 			/* If just one instance was disabled check if there are
160110279313SLuiz Augusto von Dentz 			 * any other instance enabled before clearing HCI_LE_ADV
160210279313SLuiz Augusto von Dentz 			 */
160310279313SLuiz Augusto von Dentz 			list_for_each_entry_safe(adv, n, &hdev->adv_instances,
160410279313SLuiz Augusto von Dentz 						 list) {
160510279313SLuiz Augusto von Dentz 				if (adv->enabled)
160610279313SLuiz Augusto von Dentz 					goto unlock;
160710279313SLuiz Augusto von Dentz 			}
160810279313SLuiz Augusto von Dentz 		} else {
160910279313SLuiz Augusto von Dentz 			/* All instances shall be considered disabled */
161010279313SLuiz Augusto von Dentz 			list_for_each_entry_safe(adv, n, &hdev->adv_instances,
161110279313SLuiz Augusto von Dentz 						 list)
161210279313SLuiz Augusto von Dentz 				adv->enabled = false;
161310279313SLuiz Augusto von Dentz 		}
161410279313SLuiz Augusto von Dentz 
161545b7749fSJaganath Kanakkassery 		hci_dev_clear_flag(hdev, HCI_LE_ADV);
1616de181e88SJaganath Kanakkassery 	}
1617de181e88SJaganath Kanakkassery 
161810279313SLuiz Augusto von Dentz unlock:
1619de181e88SJaganath Kanakkassery 	hci_dev_unlock(hdev);
1620c8992cffSLuiz Augusto von Dentz 	return rp->status;
1621de181e88SJaganath Kanakkassery }
1622de181e88SJaganath Kanakkassery 
1623c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_scan_param(struct hci_dev *hdev, void *data,
1624c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
1625533553f8SMarcel Holtmann {
1626533553f8SMarcel Holtmann 	struct hci_cp_le_set_scan_param *cp;
1627c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1628533553f8SMarcel Holtmann 
1629e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1630e3f3a1aeSLuiz Augusto von Dentz 
1631e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1632c8992cffSLuiz Augusto von Dentz 		return rp->status;
163345296acdSMarcel Holtmann 
1634533553f8SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_PARAM);
1635533553f8SMarcel Holtmann 	if (!cp)
1636c8992cffSLuiz Augusto von Dentz 		return rp->status;
1637533553f8SMarcel Holtmann 
1638533553f8SMarcel Holtmann 	hci_dev_lock(hdev);
1639533553f8SMarcel Holtmann 
1640533553f8SMarcel Holtmann 	hdev->le_scan_type = cp->type;
1641533553f8SMarcel Holtmann 
1642533553f8SMarcel Holtmann 	hci_dev_unlock(hdev);
1643c8992cffSLuiz Augusto von Dentz 
1644c8992cffSLuiz Augusto von Dentz 	return rp->status;
1645533553f8SMarcel Holtmann }
1646533553f8SMarcel Holtmann 
1647c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_ext_scan_param(struct hci_dev *hdev, void *data,
1648a2344b9eSJaganath Kanakkassery 				       struct sk_buff *skb)
1649a2344b9eSJaganath Kanakkassery {
1650a2344b9eSJaganath Kanakkassery 	struct hci_cp_le_set_ext_scan_params *cp;
1651c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1652a2344b9eSJaganath Kanakkassery 	struct hci_cp_le_scan_phy_params *phy_param;
1653a2344b9eSJaganath Kanakkassery 
1654e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1655e3f3a1aeSLuiz Augusto von Dentz 
1656e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1657c8992cffSLuiz Augusto von Dentz 		return rp->status;
1658a2344b9eSJaganath Kanakkassery 
1659a2344b9eSJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_SCAN_PARAMS);
1660a2344b9eSJaganath Kanakkassery 	if (!cp)
1661c8992cffSLuiz Augusto von Dentz 		return rp->status;
1662a2344b9eSJaganath Kanakkassery 
1663a2344b9eSJaganath Kanakkassery 	phy_param = (void *)cp->data;
1664a2344b9eSJaganath Kanakkassery 
1665a2344b9eSJaganath Kanakkassery 	hci_dev_lock(hdev);
1666a2344b9eSJaganath Kanakkassery 
1667a2344b9eSJaganath Kanakkassery 	hdev->le_scan_type = phy_param->type;
1668a2344b9eSJaganath Kanakkassery 
1669a2344b9eSJaganath Kanakkassery 	hci_dev_unlock(hdev);
1670c8992cffSLuiz Augusto von Dentz 
1671c8992cffSLuiz Augusto von Dentz 	return rp->status;
1672a2344b9eSJaganath Kanakkassery }
1673a2344b9eSJaganath Kanakkassery 
1674b9a6328fSJohan Hedberg static bool has_pending_adv_report(struct hci_dev *hdev)
1675b9a6328fSJohan Hedberg {
1676b9a6328fSJohan Hedberg 	struct discovery_state *d = &hdev->discovery;
1677b9a6328fSJohan Hedberg 
1678b9a6328fSJohan Hedberg 	return bacmp(&d->last_adv_addr, BDADDR_ANY);
1679b9a6328fSJohan Hedberg }
1680b9a6328fSJohan Hedberg 
1681b9a6328fSJohan Hedberg static void clear_pending_adv_report(struct hci_dev *hdev)
1682b9a6328fSJohan Hedberg {
1683b9a6328fSJohan Hedberg 	struct discovery_state *d = &hdev->discovery;
1684b9a6328fSJohan Hedberg 
1685b9a6328fSJohan Hedberg 	bacpy(&d->last_adv_addr, BDADDR_ANY);
1686b9a6328fSJohan Hedberg 	d->last_adv_data_len = 0;
1687b9a6328fSJohan Hedberg }
1688b9a6328fSJohan Hedberg 
1689b9a6328fSJohan Hedberg static void store_pending_adv_report(struct hci_dev *hdev, bdaddr_t *bdaddr,
1690c70a7e4cSMarcel Holtmann 				     u8 bdaddr_type, s8 rssi, u32 flags,
1691c70a7e4cSMarcel Holtmann 				     u8 *data, u8 len)
1692b9a6328fSJohan Hedberg {
1693b9a6328fSJohan Hedberg 	struct discovery_state *d = &hdev->discovery;
1694b9a6328fSJohan Hedberg 
1695a2ec905dSAlain Michaud 	if (len > HCI_MAX_AD_LENGTH)
1696a2ec905dSAlain Michaud 		return;
1697a2ec905dSAlain Michaud 
1698b9a6328fSJohan Hedberg 	bacpy(&d->last_adv_addr, bdaddr);
1699b9a6328fSJohan Hedberg 	d->last_adv_addr_type = bdaddr_type;
1700ff5cd29fSJohan Hedberg 	d->last_adv_rssi = rssi;
1701c70a7e4cSMarcel Holtmann 	d->last_adv_flags = flags;
1702b9a6328fSJohan Hedberg 	memcpy(d->last_adv_data, data, len);
1703b9a6328fSJohan Hedberg 	d->last_adv_data_len = len;
1704b9a6328fSJohan Hedberg }
1705b9a6328fSJohan Hedberg 
17063baef810SJaganath Kanakkassery static void le_set_scan_enable_complete(struct hci_dev *hdev, u8 enable)
1707eb9d91f5SAndre Guedes {
17085c1a4c8fSJaganath Kanakkassery 	hci_dev_lock(hdev);
17095c1a4c8fSJaganath Kanakkassery 
17103baef810SJaganath Kanakkassery 	switch (enable) {
17113fd319b8SAndre Guedes 	case LE_SCAN_ENABLE:
1712a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_LE_SCAN);
1713b9a6328fSJohan Hedberg 		if (hdev->le_scan_type == LE_SCAN_ACTIVE)
1714b9a6328fSJohan Hedberg 			clear_pending_adv_report(hdev);
171568a8aea4SAndrei Emeltchenko 		break;
171668a8aea4SAndrei Emeltchenko 
171776a388beSAndre Guedes 	case LE_SCAN_DISABLE:
1718b9a6328fSJohan Hedberg 		/* We do this here instead of when setting DISCOVERY_STOPPED
1719b9a6328fSJohan Hedberg 		 * since the latter would potentially require waiting for
1720b9a6328fSJohan Hedberg 		 * inquiry to stop too.
1721b9a6328fSJohan Hedberg 		 */
1722b9a6328fSJohan Hedberg 		if (has_pending_adv_report(hdev)) {
1723b9a6328fSJohan Hedberg 			struct discovery_state *d = &hdev->discovery;
1724b9a6328fSJohan Hedberg 
1725b9a6328fSJohan Hedberg 			mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
1726ab0aa433SJohan Hedberg 					  d->last_adv_addr_type, NULL,
1727c70a7e4cSMarcel Holtmann 					  d->last_adv_rssi, d->last_adv_flags,
1728ab0aa433SJohan Hedberg 					  d->last_adv_data,
1729b9a6328fSJohan Hedberg 					  d->last_adv_data_len, NULL, 0);
1730b9a6328fSJohan Hedberg 		}
1731b9a6328fSJohan Hedberg 
1732317ac8cbSJohan Hedberg 		/* Cancel this timer so that we don't try to disable scanning
1733317ac8cbSJohan Hedberg 		 * when it's already disabled.
1734317ac8cbSJohan Hedberg 		 */
1735317ac8cbSJohan Hedberg 		cancel_delayed_work(&hdev->le_scan_disable);
1736317ac8cbSJohan Hedberg 
1737a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LE_SCAN);
1738e8bb6b97SJohan Hedberg 
173981ad6fd9SJohan Hedberg 		/* The HCI_LE_SCAN_INTERRUPTED flag indicates that we
174081ad6fd9SJohan Hedberg 		 * interrupted scanning due to a connect request. Mark
1741abfeea47SLuiz Augusto von Dentz 		 * therefore discovery as stopped.
174281ad6fd9SJohan Hedberg 		 */
1743a69d8927SMarcel Holtmann 		if (hci_dev_test_and_clear_flag(hdev, HCI_LE_SCAN_INTERRUPTED))
174481ad6fd9SJohan Hedberg 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1745e8bb6b97SJohan Hedberg 
174668a8aea4SAndrei Emeltchenko 		break;
174768a8aea4SAndrei Emeltchenko 
174868a8aea4SAndrei Emeltchenko 	default:
17492064ee33SMarcel Holtmann 		bt_dev_err(hdev, "use of reserved LE_Scan_Enable param %d",
17503baef810SJaganath Kanakkassery 			   enable);
175168a8aea4SAndrei Emeltchenko 		break;
175235815085SAndre Guedes 	}
17535c1a4c8fSJaganath Kanakkassery 
17545c1a4c8fSJaganath Kanakkassery 	hci_dev_unlock(hdev);
1755eb9d91f5SAndre Guedes }
1756eb9d91f5SAndre Guedes 
1757c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_scan_enable(struct hci_dev *hdev, void *data,
17583baef810SJaganath Kanakkassery 				    struct sk_buff *skb)
17593baef810SJaganath Kanakkassery {
17603baef810SJaganath Kanakkassery 	struct hci_cp_le_set_scan_enable *cp;
1761c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
17623baef810SJaganath Kanakkassery 
1763e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1764e3f3a1aeSLuiz Augusto von Dentz 
1765e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1766c8992cffSLuiz Augusto von Dentz 		return rp->status;
17673baef810SJaganath Kanakkassery 
17683baef810SJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
17693baef810SJaganath Kanakkassery 	if (!cp)
1770c8992cffSLuiz Augusto von Dentz 		return rp->status;
17713baef810SJaganath Kanakkassery 
17723baef810SJaganath Kanakkassery 	le_set_scan_enable_complete(hdev, cp->enable);
1773c8992cffSLuiz Augusto von Dentz 
1774c8992cffSLuiz Augusto von Dentz 	return rp->status;
17753baef810SJaganath Kanakkassery }
17763baef810SJaganath Kanakkassery 
1777c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_ext_scan_enable(struct hci_dev *hdev, void *data,
1778a2344b9eSJaganath Kanakkassery 					struct sk_buff *skb)
1779a2344b9eSJaganath Kanakkassery {
1780a2344b9eSJaganath Kanakkassery 	struct hci_cp_le_set_ext_scan_enable *cp;
1781c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1782a2344b9eSJaganath Kanakkassery 
1783e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1784e3f3a1aeSLuiz Augusto von Dentz 
1785e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1786c8992cffSLuiz Augusto von Dentz 		return rp->status;
1787a2344b9eSJaganath Kanakkassery 
1788a2344b9eSJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_SCAN_ENABLE);
1789a2344b9eSJaganath Kanakkassery 	if (!cp)
1790c8992cffSLuiz Augusto von Dentz 		return rp->status;
1791a2344b9eSJaganath Kanakkassery 
1792a2344b9eSJaganath Kanakkassery 	le_set_scan_enable_complete(hdev, cp->enable);
1793c8992cffSLuiz Augusto von Dentz 
1794c8992cffSLuiz Augusto von Dentz 	return rp->status;
1795a2344b9eSJaganath Kanakkassery }
1796a2344b9eSJaganath Kanakkassery 
1797c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_num_adv_sets(struct hci_dev *hdev, void *data,
17986b49bcb4SJaganath Kanakkassery 				      struct sk_buff *skb)
17996b49bcb4SJaganath Kanakkassery {
1800c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_num_supported_adv_sets *rp = data;
1801e3f3a1aeSLuiz Augusto von Dentz 
1802e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x No of Adv sets %u", rp->status,
18036b49bcb4SJaganath Kanakkassery 		   rp->num_of_sets);
18046b49bcb4SJaganath Kanakkassery 
18056b49bcb4SJaganath Kanakkassery 	if (rp->status)
1806c8992cffSLuiz Augusto von Dentz 		return rp->status;
18076b49bcb4SJaganath Kanakkassery 
18086b49bcb4SJaganath Kanakkassery 	hdev->le_num_of_adv_sets = rp->num_of_sets;
1809c8992cffSLuiz Augusto von Dentz 
1810c8992cffSLuiz Augusto von Dentz 	return rp->status;
18116b49bcb4SJaganath Kanakkassery }
18126b49bcb4SJaganath Kanakkassery 
1813c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_accept_list_size(struct hci_dev *hdev, void *data,
1814cf1d081fSJohan Hedberg 					  struct sk_buff *skb)
1815cf1d081fSJohan Hedberg {
1816c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_accept_list_size *rp = data;
1817e3f3a1aeSLuiz Augusto von Dentz 
1818e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x size %u", rp->status, rp->size);
1819cf1d081fSJohan Hedberg 
182045296acdSMarcel Holtmann 	if (rp->status)
1821c8992cffSLuiz Augusto von Dentz 		return rp->status;
182245296acdSMarcel Holtmann 
18233d4f9c00SArchie Pusaka 	hdev->le_accept_list_size = rp->size;
1824c8992cffSLuiz Augusto von Dentz 
1825c8992cffSLuiz Augusto von Dentz 	return rp->status;
1826cf1d081fSJohan Hedberg }
1827cf1d081fSJohan Hedberg 
1828c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_clear_accept_list(struct hci_dev *hdev, void *data,
18290f36b589SMarcel Holtmann 				      struct sk_buff *skb)
18300f36b589SMarcel Holtmann {
1831c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
18320f36b589SMarcel Holtmann 
1833e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1834e3f3a1aeSLuiz Augusto von Dentz 
1835e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1836c8992cffSLuiz Augusto von Dentz 		return rp->status;
183745296acdSMarcel Holtmann 
18383d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->le_accept_list);
1839c8992cffSLuiz Augusto von Dentz 
1840c8992cffSLuiz Augusto von Dentz 	return rp->status;
18410f36b589SMarcel Holtmann }
18420f36b589SMarcel Holtmann 
1843c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_add_to_accept_list(struct hci_dev *hdev, void *data,
18440f36b589SMarcel Holtmann 				       struct sk_buff *skb)
18450f36b589SMarcel Holtmann {
18463d4f9c00SArchie Pusaka 	struct hci_cp_le_add_to_accept_list *sent;
1847c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
18480f36b589SMarcel Holtmann 
1849e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1850e3f3a1aeSLuiz Augusto von Dentz 
1851e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1852c8992cffSLuiz Augusto von Dentz 		return rp->status;
185345296acdSMarcel Holtmann 
18543d4f9c00SArchie Pusaka 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_ACCEPT_LIST);
18550f36b589SMarcel Holtmann 	if (!sent)
1856c8992cffSLuiz Augusto von Dentz 		return rp->status;
18570f36b589SMarcel Holtmann 
18583d4f9c00SArchie Pusaka 	hci_bdaddr_list_add(&hdev->le_accept_list, &sent->bdaddr,
1859dcc36c16SJohan Hedberg 			    sent->bdaddr_type);
1860c8992cffSLuiz Augusto von Dentz 
1861c8992cffSLuiz Augusto von Dentz 	return rp->status;
18620f36b589SMarcel Holtmann }
18630f36b589SMarcel Holtmann 
1864c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_del_from_accept_list(struct hci_dev *hdev, void *data,
18650f36b589SMarcel Holtmann 					 struct sk_buff *skb)
18660f36b589SMarcel Holtmann {
18673d4f9c00SArchie Pusaka 	struct hci_cp_le_del_from_accept_list *sent;
1868c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
18690f36b589SMarcel Holtmann 
1870e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1871e3f3a1aeSLuiz Augusto von Dentz 
1872e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1873c8992cffSLuiz Augusto von Dentz 		return rp->status;
187445296acdSMarcel Holtmann 
18753d4f9c00SArchie Pusaka 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_ACCEPT_LIST);
18760f36b589SMarcel Holtmann 	if (!sent)
1877c8992cffSLuiz Augusto von Dentz 		return rp->status;
18780f36b589SMarcel Holtmann 
18793d4f9c00SArchie Pusaka 	hci_bdaddr_list_del(&hdev->le_accept_list, &sent->bdaddr,
1880dcc36c16SJohan Hedberg 			    sent->bdaddr_type);
1881c8992cffSLuiz Augusto von Dentz 
1882c8992cffSLuiz Augusto von Dentz 	return rp->status;
18830f36b589SMarcel Holtmann }
18840f36b589SMarcel Holtmann 
1885c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_supported_states(struct hci_dev *hdev, void *data,
18869b008c04SJohan Hedberg 					  struct sk_buff *skb)
18879b008c04SJohan Hedberg {
1888c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_supported_states *rp = data;
1889e3f3a1aeSLuiz Augusto von Dentz 
1890e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
18919b008c04SJohan Hedberg 
189245296acdSMarcel Holtmann 	if (rp->status)
1893c8992cffSLuiz Augusto von Dentz 		return rp->status;
189445296acdSMarcel Holtmann 
18959b008c04SJohan Hedberg 	memcpy(hdev->le_states, rp->le_states, 8);
1896c8992cffSLuiz Augusto von Dentz 
1897c8992cffSLuiz Augusto von Dentz 	return rp->status;
18989b008c04SJohan Hedberg }
18999b008c04SJohan Hedberg 
1900c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_def_data_len(struct hci_dev *hdev, void *data,
1901a8e1bfaaSMarcel Holtmann 				      struct sk_buff *skb)
1902a8e1bfaaSMarcel Holtmann {
1903c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_def_data_len *rp = data;
1904e3f3a1aeSLuiz Augusto von Dentz 
1905e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1906a8e1bfaaSMarcel Holtmann 
1907a8e1bfaaSMarcel Holtmann 	if (rp->status)
1908c8992cffSLuiz Augusto von Dentz 		return rp->status;
1909a8e1bfaaSMarcel Holtmann 
1910a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_len = le16_to_cpu(rp->tx_len);
1911a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_time = le16_to_cpu(rp->tx_time);
1912c8992cffSLuiz Augusto von Dentz 
1913c8992cffSLuiz Augusto von Dentz 	return rp->status;
1914a8e1bfaaSMarcel Holtmann }
1915a8e1bfaaSMarcel Holtmann 
1916c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_write_def_data_len(struct hci_dev *hdev, void *data,
1917a8e1bfaaSMarcel Holtmann 				       struct sk_buff *skb)
1918a8e1bfaaSMarcel Holtmann {
1919a8e1bfaaSMarcel Holtmann 	struct hci_cp_le_write_def_data_len *sent;
1920c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1921a8e1bfaaSMarcel Holtmann 
1922e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1923e3f3a1aeSLuiz Augusto von Dentz 
1924e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1925c8992cffSLuiz Augusto von Dentz 		return rp->status;
1926a8e1bfaaSMarcel Holtmann 
1927a8e1bfaaSMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_WRITE_DEF_DATA_LEN);
1928a8e1bfaaSMarcel Holtmann 	if (!sent)
1929c8992cffSLuiz Augusto von Dentz 		return rp->status;
1930a8e1bfaaSMarcel Holtmann 
1931a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_len = le16_to_cpu(sent->tx_len);
1932a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_time = le16_to_cpu(sent->tx_time);
1933c8992cffSLuiz Augusto von Dentz 
1934c8992cffSLuiz Augusto von Dentz 	return rp->status;
1935a8e1bfaaSMarcel Holtmann }
1936a8e1bfaaSMarcel Holtmann 
1937c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_add_to_resolv_list(struct hci_dev *hdev, void *data,
1938b950aa88SAnkit Navik 				       struct sk_buff *skb)
1939b950aa88SAnkit Navik {
1940b950aa88SAnkit Navik 	struct hci_cp_le_add_to_resolv_list *sent;
1941c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1942b950aa88SAnkit Navik 
1943e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1944e3f3a1aeSLuiz Augusto von Dentz 
1945e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1946c8992cffSLuiz Augusto von Dentz 		return rp->status;
1947b950aa88SAnkit Navik 
1948b950aa88SAnkit Navik 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_RESOLV_LIST);
1949b950aa88SAnkit Navik 	if (!sent)
1950c8992cffSLuiz Augusto von Dentz 		return rp->status;
1951b950aa88SAnkit Navik 
1952b950aa88SAnkit Navik 	hci_bdaddr_list_add_with_irk(&hdev->le_resolv_list, &sent->bdaddr,
1953b950aa88SAnkit Navik 				sent->bdaddr_type, sent->peer_irk,
1954b950aa88SAnkit Navik 				sent->local_irk);
1955c8992cffSLuiz Augusto von Dentz 
1956c8992cffSLuiz Augusto von Dentz 	return rp->status;
1957b950aa88SAnkit Navik }
1958b950aa88SAnkit Navik 
1959c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_del_from_resolv_list(struct hci_dev *hdev, void *data,
1960b950aa88SAnkit Navik 					 struct sk_buff *skb)
1961b950aa88SAnkit Navik {
1962b950aa88SAnkit Navik 	struct hci_cp_le_del_from_resolv_list *sent;
1963c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1964b950aa88SAnkit Navik 
1965e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1966e3f3a1aeSLuiz Augusto von Dentz 
1967e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1968c8992cffSLuiz Augusto von Dentz 		return rp->status;
1969b950aa88SAnkit Navik 
1970b950aa88SAnkit Navik 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_RESOLV_LIST);
1971b950aa88SAnkit Navik 	if (!sent)
1972c8992cffSLuiz Augusto von Dentz 		return rp->status;
1973b950aa88SAnkit Navik 
1974b950aa88SAnkit Navik 	hci_bdaddr_list_del_with_irk(&hdev->le_resolv_list, &sent->bdaddr,
1975b950aa88SAnkit Navik 			    sent->bdaddr_type);
1976c8992cffSLuiz Augusto von Dentz 
1977c8992cffSLuiz Augusto von Dentz 	return rp->status;
1978b950aa88SAnkit Navik }
1979b950aa88SAnkit Navik 
1980c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_clear_resolv_list(struct hci_dev *hdev, void *data,
1981545f2596SAnkit Navik 				      struct sk_buff *skb)
1982545f2596SAnkit Navik {
1983c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1984545f2596SAnkit Navik 
1985e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1986e3f3a1aeSLuiz Augusto von Dentz 
1987e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1988c8992cffSLuiz Augusto von Dentz 		return rp->status;
1989545f2596SAnkit Navik 
1990545f2596SAnkit Navik 	hci_bdaddr_list_clear(&hdev->le_resolv_list);
1991c8992cffSLuiz Augusto von Dentz 
1992c8992cffSLuiz Augusto von Dentz 	return rp->status;
1993545f2596SAnkit Navik }
1994545f2596SAnkit Navik 
1995c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_resolv_list_size(struct hci_dev *hdev, void *data,
1996cfdb0c2dSAnkit Navik 					  struct sk_buff *skb)
1997cfdb0c2dSAnkit Navik {
1998c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_resolv_list_size *rp = data;
1999e3f3a1aeSLuiz Augusto von Dentz 
2000e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x size %u", rp->status, rp->size);
2001cfdb0c2dSAnkit Navik 
2002cfdb0c2dSAnkit Navik 	if (rp->status)
2003c8992cffSLuiz Augusto von Dentz 		return rp->status;
2004cfdb0c2dSAnkit Navik 
2005cfdb0c2dSAnkit Navik 	hdev->le_resolv_list_size = rp->size;
2006c8992cffSLuiz Augusto von Dentz 
2007c8992cffSLuiz Augusto von Dentz 	return rp->status;
2008cfdb0c2dSAnkit Navik }
2009cfdb0c2dSAnkit Navik 
2010c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_addr_resolution_enable(struct hci_dev *hdev, void *data,
2011aa12af77SAnkit Navik 					       struct sk_buff *skb)
2012aa12af77SAnkit Navik {
2013c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
2014e3f3a1aeSLuiz Augusto von Dentz 	__u8 *sent;
2015aa12af77SAnkit Navik 
2016e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2017e3f3a1aeSLuiz Augusto von Dentz 
2018e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
2019c8992cffSLuiz Augusto von Dentz 		return rp->status;
2020aa12af77SAnkit Navik 
2021aa12af77SAnkit Navik 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADDR_RESOLV_ENABLE);
2022aa12af77SAnkit Navik 	if (!sent)
2023c8992cffSLuiz Augusto von Dentz 		return rp->status;
2024aa12af77SAnkit Navik 
2025aa12af77SAnkit Navik 	hci_dev_lock(hdev);
2026aa12af77SAnkit Navik 
2027aa12af77SAnkit Navik 	if (*sent)
2028aa12af77SAnkit Navik 		hci_dev_set_flag(hdev, HCI_LL_RPA_RESOLUTION);
2029aa12af77SAnkit Navik 	else
2030aa12af77SAnkit Navik 		hci_dev_clear_flag(hdev, HCI_LL_RPA_RESOLUTION);
2031aa12af77SAnkit Navik 
2032aa12af77SAnkit Navik 	hci_dev_unlock(hdev);
2033c8992cffSLuiz Augusto von Dentz 
2034c8992cffSLuiz Augusto von Dentz 	return rp->status;
2035aa12af77SAnkit Navik }
2036aa12af77SAnkit Navik 
2037c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_max_data_len(struct hci_dev *hdev, void *data,
2038a8e1bfaaSMarcel Holtmann 				      struct sk_buff *skb)
2039a8e1bfaaSMarcel Holtmann {
2040c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_max_data_len *rp = data;
2041e3f3a1aeSLuiz Augusto von Dentz 
2042e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2043a8e1bfaaSMarcel Holtmann 
2044a8e1bfaaSMarcel Holtmann 	if (rp->status)
2045c8992cffSLuiz Augusto von Dentz 		return rp->status;
2046a8e1bfaaSMarcel Holtmann 
2047a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_len = le16_to_cpu(rp->tx_len);
2048a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_time = le16_to_cpu(rp->tx_time);
2049a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_len = le16_to_cpu(rp->rx_len);
2050a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_time = le16_to_cpu(rp->rx_time);
2051c8992cffSLuiz Augusto von Dentz 
2052c8992cffSLuiz Augusto von Dentz 	return rp->status;
2053a8e1bfaaSMarcel Holtmann }
2054a8e1bfaaSMarcel Holtmann 
2055c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_le_host_supported(struct hci_dev *hdev, void *data,
2056f9b49306SAndre Guedes 					 struct sk_buff *skb)
2057f9b49306SAndre Guedes {
205806199cf8SJohan Hedberg 	struct hci_cp_write_le_host_supported *sent;
2059c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
2060f9b49306SAndre Guedes 
2061e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2062e3f3a1aeSLuiz Augusto von Dentz 
2063e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
2064c8992cffSLuiz Augusto von Dentz 		return rp->status;
206545296acdSMarcel Holtmann 
206606199cf8SJohan Hedberg 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
20678f984dfaSJohan Hedberg 	if (!sent)
2068c8992cffSLuiz Augusto von Dentz 		return rp->status;
2069f9b49306SAndre Guedes 
20705c1a4c8fSJaganath Kanakkassery 	hci_dev_lock(hdev);
20715c1a4c8fSJaganath Kanakkassery 
2072416a4ae5SJohan Hedberg 	if (sent->le) {
2073cad718edSJohan Hedberg 		hdev->features[1][0] |= LMP_HOST_LE;
2074a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_LE_ENABLED);
2075416a4ae5SJohan Hedberg 	} else {
2076cad718edSJohan Hedberg 		hdev->features[1][0] &= ~LMP_HOST_LE;
2077a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LE_ENABLED);
2078a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_ADVERTISING);
2079416a4ae5SJohan Hedberg 	}
208053b2caabSJohan Hedberg 
208153b2caabSJohan Hedberg 	if (sent->simul)
2082cad718edSJohan Hedberg 		hdev->features[1][0] |= LMP_HOST_LE_BREDR;
208353b2caabSJohan Hedberg 	else
2084cad718edSJohan Hedberg 		hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
20855c1a4c8fSJaganath Kanakkassery 
20865c1a4c8fSJaganath Kanakkassery 	hci_dev_unlock(hdev);
2087c8992cffSLuiz Augusto von Dentz 
2088c8992cffSLuiz Augusto von Dentz 	return rp->status;
20898f984dfaSJohan Hedberg }
2090f9b49306SAndre Guedes 
2091c8992cffSLuiz Augusto von Dentz static u8 hci_cc_set_adv_param(struct hci_dev *hdev, void *data,
2092c8992cffSLuiz Augusto von Dentz 			       struct sk_buff *skb)
209356ed2cb8SJohan Hedberg {
209456ed2cb8SJohan Hedberg 	struct hci_cp_le_set_adv_param *cp;
2095c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
209656ed2cb8SJohan Hedberg 
2097e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2098e3f3a1aeSLuiz Augusto von Dentz 
2099e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
2100c8992cffSLuiz Augusto von Dentz 		return rp->status;
210156ed2cb8SJohan Hedberg 
210256ed2cb8SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_PARAM);
210356ed2cb8SJohan Hedberg 	if (!cp)
2104c8992cffSLuiz Augusto von Dentz 		return rp->status;
210556ed2cb8SJohan Hedberg 
210656ed2cb8SJohan Hedberg 	hci_dev_lock(hdev);
210756ed2cb8SJohan Hedberg 	hdev->adv_addr_type = cp->own_address_type;
210856ed2cb8SJohan Hedberg 	hci_dev_unlock(hdev);
2109c8992cffSLuiz Augusto von Dentz 
2110c8992cffSLuiz Augusto von Dentz 	return rp->status;
211156ed2cb8SJohan Hedberg }
211256ed2cb8SJohan Hedberg 
2113c8992cffSLuiz Augusto von Dentz static u8 hci_cc_set_ext_adv_param(struct hci_dev *hdev, void *data,
2114c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
2115de181e88SJaganath Kanakkassery {
2116c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_set_ext_adv_params *rp = data;
2117de181e88SJaganath Kanakkassery 	struct hci_cp_le_set_ext_adv_params *cp;
2118de181e88SJaganath Kanakkassery 	struct adv_info *adv_instance;
2119de181e88SJaganath Kanakkassery 
2120e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2121de181e88SJaganath Kanakkassery 
2122de181e88SJaganath Kanakkassery 	if (rp->status)
2123c8992cffSLuiz Augusto von Dentz 		return rp->status;
2124de181e88SJaganath Kanakkassery 
2125de181e88SJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_ADV_PARAMS);
2126de181e88SJaganath Kanakkassery 	if (!cp)
2127c8992cffSLuiz Augusto von Dentz 		return rp->status;
2128de181e88SJaganath Kanakkassery 
2129de181e88SJaganath Kanakkassery 	hci_dev_lock(hdev);
2130de181e88SJaganath Kanakkassery 	hdev->adv_addr_type = cp->own_addr_type;
213125e70886SDaniel Winkler 	if (!cp->handle) {
2132de181e88SJaganath Kanakkassery 		/* Store in hdev for instance 0 */
2133de181e88SJaganath Kanakkassery 		hdev->adv_tx_power = rp->tx_power;
2134de181e88SJaganath Kanakkassery 	} else {
213525e70886SDaniel Winkler 		adv_instance = hci_find_adv_instance(hdev, cp->handle);
2136de181e88SJaganath Kanakkassery 		if (adv_instance)
2137de181e88SJaganath Kanakkassery 			adv_instance->tx_power = rp->tx_power;
2138de181e88SJaganath Kanakkassery 	}
2139a0fb3726SJaganath Kanakkassery 	/* Update adv data as tx power is known now */
214025e70886SDaniel Winkler 	hci_req_update_adv_data(hdev, cp->handle);
214112410572SDaniel Winkler 
2142de181e88SJaganath Kanakkassery 	hci_dev_unlock(hdev);
2143c8992cffSLuiz Augusto von Dentz 
2144c8992cffSLuiz Augusto von Dentz 	return rp->status;
2145de181e88SJaganath Kanakkassery }
2146de181e88SJaganath Kanakkassery 
2147c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_rssi(struct hci_dev *hdev, void *data,
2148c8992cffSLuiz Augusto von Dentz 			   struct sk_buff *skb)
21495ae76a94SAndrzej Kaczmarek {
2150c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_rssi *rp = data;
21515ae76a94SAndrzej Kaczmarek 	struct hci_conn *conn;
21525ae76a94SAndrzej Kaczmarek 
2153e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
21545ae76a94SAndrzej Kaczmarek 
21555ae76a94SAndrzej Kaczmarek 	if (rp->status)
2156c8992cffSLuiz Augusto von Dentz 		return rp->status;
21575ae76a94SAndrzej Kaczmarek 
21585ae76a94SAndrzej Kaczmarek 	hci_dev_lock(hdev);
21595ae76a94SAndrzej Kaczmarek 
21605ae76a94SAndrzej Kaczmarek 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
21615ae76a94SAndrzej Kaczmarek 	if (conn)
21625ae76a94SAndrzej Kaczmarek 		conn->rssi = rp->rssi;
21635ae76a94SAndrzej Kaczmarek 
21645ae76a94SAndrzej Kaczmarek 	hci_dev_unlock(hdev);
2165c8992cffSLuiz Augusto von Dentz 
2166c8992cffSLuiz Augusto von Dentz 	return rp->status;
21675ae76a94SAndrzej Kaczmarek }
21685ae76a94SAndrzej Kaczmarek 
2169c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_tx_power(struct hci_dev *hdev, void *data,
2170c8992cffSLuiz Augusto von Dentz 			       struct sk_buff *skb)
21715a134faeSAndrzej Kaczmarek {
21725a134faeSAndrzej Kaczmarek 	struct hci_cp_read_tx_power *sent;
2173c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_tx_power *rp = data;
21745a134faeSAndrzej Kaczmarek 	struct hci_conn *conn;
21755a134faeSAndrzej Kaczmarek 
2176e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
21775a134faeSAndrzej Kaczmarek 
21785a134faeSAndrzej Kaczmarek 	if (rp->status)
2179c8992cffSLuiz Augusto von Dentz 		return rp->status;
21805a134faeSAndrzej Kaczmarek 
21815a134faeSAndrzej Kaczmarek 	sent = hci_sent_cmd_data(hdev, HCI_OP_READ_TX_POWER);
21825a134faeSAndrzej Kaczmarek 	if (!sent)
2183c8992cffSLuiz Augusto von Dentz 		return rp->status;
21845a134faeSAndrzej Kaczmarek 
21855a134faeSAndrzej Kaczmarek 	hci_dev_lock(hdev);
21865a134faeSAndrzej Kaczmarek 
21875a134faeSAndrzej Kaczmarek 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
2188d0455ed9SAndrzej Kaczmarek 	if (!conn)
2189d0455ed9SAndrzej Kaczmarek 		goto unlock;
21905a134faeSAndrzej Kaczmarek 
2191d0455ed9SAndrzej Kaczmarek 	switch (sent->type) {
2192d0455ed9SAndrzej Kaczmarek 	case 0x00:
2193d0455ed9SAndrzej Kaczmarek 		conn->tx_power = rp->tx_power;
2194d0455ed9SAndrzej Kaczmarek 		break;
2195d0455ed9SAndrzej Kaczmarek 	case 0x01:
2196d0455ed9SAndrzej Kaczmarek 		conn->max_tx_power = rp->tx_power;
2197d0455ed9SAndrzej Kaczmarek 		break;
2198d0455ed9SAndrzej Kaczmarek 	}
2199d0455ed9SAndrzej Kaczmarek 
2200d0455ed9SAndrzej Kaczmarek unlock:
22015a134faeSAndrzej Kaczmarek 	hci_dev_unlock(hdev);
2202c8992cffSLuiz Augusto von Dentz 	return rp->status;
22035a134faeSAndrzej Kaczmarek }
22045a134faeSAndrzej Kaczmarek 
2205c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_ssp_debug_mode(struct hci_dev *hdev, void *data,
2206c8992cffSLuiz Augusto von Dentz 				      struct sk_buff *skb)
2207c50b33c8SMarcel Holtmann {
2208c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
2209c50b33c8SMarcel Holtmann 	u8 *mode;
2210c50b33c8SMarcel Holtmann 
2211e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2212e3f3a1aeSLuiz Augusto von Dentz 
2213e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
2214c8992cffSLuiz Augusto von Dentz 		return rp->status;
2215c50b33c8SMarcel Holtmann 
2216c50b33c8SMarcel Holtmann 	mode = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE);
2217c50b33c8SMarcel Holtmann 	if (mode)
2218c50b33c8SMarcel Holtmann 		hdev->ssp_debug_mode = *mode;
2219c8992cffSLuiz Augusto von Dentz 
2220c8992cffSLuiz Augusto von Dentz 	return rp->status;
2221c50b33c8SMarcel Holtmann }
2222c50b33c8SMarcel Holtmann 
22236039aa73SGustavo Padovan static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
2224a9de9248SMarcel Holtmann {
2225147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2226a9de9248SMarcel Holtmann 
2227a9de9248SMarcel Holtmann 	if (status) {
2228a9de9248SMarcel Holtmann 		hci_conn_check_pending(hdev);
2229314b2381SJohan Hedberg 		return;
2230314b2381SJohan Hedberg 	}
2231314b2381SJohan Hedberg 
223289352e7dSAndre Guedes 	set_bit(HCI_INQUIRY, &hdev->flags);
2233a9de9248SMarcel Holtmann }
2234a9de9248SMarcel Holtmann 
22356039aa73SGustavo Padovan static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
22361da177e4SLinus Torvalds {
2237a9de9248SMarcel Holtmann 	struct hci_cp_create_conn *cp;
22381da177e4SLinus Torvalds 	struct hci_conn *conn;
22391da177e4SLinus Torvalds 
2240147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2241a9de9248SMarcel Holtmann 
2242a9de9248SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
22431da177e4SLinus Torvalds 	if (!cp)
22441da177e4SLinus Torvalds 		return;
22451da177e4SLinus Torvalds 
22461da177e4SLinus Torvalds 	hci_dev_lock(hdev);
22471da177e4SLinus Torvalds 
22481da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
22491da177e4SLinus Torvalds 
2250147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "bdaddr %pMR hcon %p", &cp->bdaddr, conn);
22511da177e4SLinus Torvalds 
22521da177e4SLinus Torvalds 	if (status) {
22531da177e4SLinus Torvalds 		if (conn && conn->state == BT_CONNECT) {
22544c67bc74SMarcel Holtmann 			if (status != 0x0c || conn->attempt > 2) {
22551da177e4SLinus Torvalds 				conn->state = BT_CLOSED;
2256539c496dSJohan Hedberg 				hci_connect_cfm(conn, status);
22571da177e4SLinus Torvalds 				hci_conn_del(conn);
22584c67bc74SMarcel Holtmann 			} else
22594c67bc74SMarcel Holtmann 				conn->state = BT_CONNECT2;
22601da177e4SLinus Torvalds 		}
22611da177e4SLinus Torvalds 	} else {
22621da177e4SLinus Torvalds 		if (!conn) {
2263a5c4e309SJohan Hedberg 			conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr,
2264a5c4e309SJohan Hedberg 					    HCI_ROLE_MASTER);
2265a5c4e309SJohan Hedberg 			if (!conn)
22662064ee33SMarcel Holtmann 				bt_dev_err(hdev, "no memory for new connection");
22671da177e4SLinus Torvalds 		}
22681da177e4SLinus Torvalds 	}
22691da177e4SLinus Torvalds 
22701da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
22711da177e4SLinus Torvalds }
22721da177e4SLinus Torvalds 
2273a9de9248SMarcel Holtmann static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
22741da177e4SLinus Torvalds {
2275a9de9248SMarcel Holtmann 	struct hci_cp_add_sco *cp;
22761da177e4SLinus Torvalds 	struct hci_conn *acl, *sco;
22771da177e4SLinus Torvalds 	__u16 handle;
22781da177e4SLinus Torvalds 
2279147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2280b6a0dc82SMarcel Holtmann 
2281a9de9248SMarcel Holtmann 	if (!status)
2282a9de9248SMarcel Holtmann 		return;
2283a9de9248SMarcel Holtmann 
2284a9de9248SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
22851da177e4SLinus Torvalds 	if (!cp)
2286a9de9248SMarcel Holtmann 		return;
22871da177e4SLinus Torvalds 
22881da177e4SLinus Torvalds 	handle = __le16_to_cpu(cp->handle);
22891da177e4SLinus Torvalds 
2290147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "handle 0x%4.4x", handle);
22911da177e4SLinus Torvalds 
22921da177e4SLinus Torvalds 	hci_dev_lock(hdev);
22931da177e4SLinus Torvalds 
22941da177e4SLinus Torvalds 	acl = hci_conn_hash_lookup_handle(hdev, handle);
22955a08ecceSAndrei Emeltchenko 	if (acl) {
22965a08ecceSAndrei Emeltchenko 		sco = acl->link;
22975a08ecceSAndrei Emeltchenko 		if (sco) {
22981da177e4SLinus Torvalds 			sco->state = BT_CLOSED;
22991da177e4SLinus Torvalds 
2300539c496dSJohan Hedberg 			hci_connect_cfm(sco, status);
23011da177e4SLinus Torvalds 			hci_conn_del(sco);
23021da177e4SLinus Torvalds 		}
23035a08ecceSAndrei Emeltchenko 	}
23041da177e4SLinus Torvalds 
23051da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
23061da177e4SLinus Torvalds }
23071da177e4SLinus Torvalds 
2308f8558555SMarcel Holtmann static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
2309f8558555SMarcel Holtmann {
2310f8558555SMarcel Holtmann 	struct hci_cp_auth_requested *cp;
2311f8558555SMarcel Holtmann 	struct hci_conn *conn;
2312f8558555SMarcel Holtmann 
2313147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2314f8558555SMarcel Holtmann 
2315f8558555SMarcel Holtmann 	if (!status)
2316f8558555SMarcel Holtmann 		return;
2317f8558555SMarcel Holtmann 
2318f8558555SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
2319f8558555SMarcel Holtmann 	if (!cp)
2320f8558555SMarcel Holtmann 		return;
2321f8558555SMarcel Holtmann 
2322f8558555SMarcel Holtmann 	hci_dev_lock(hdev);
2323f8558555SMarcel Holtmann 
2324f8558555SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2325f8558555SMarcel Holtmann 	if (conn) {
2326f8558555SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
2327539c496dSJohan Hedberg 			hci_connect_cfm(conn, status);
232876a68ba0SDavid Herrmann 			hci_conn_drop(conn);
2329f8558555SMarcel Holtmann 		}
2330f8558555SMarcel Holtmann 	}
2331f8558555SMarcel Holtmann 
2332f8558555SMarcel Holtmann 	hci_dev_unlock(hdev);
2333f8558555SMarcel Holtmann }
2334f8558555SMarcel Holtmann 
2335f8558555SMarcel Holtmann static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
2336f8558555SMarcel Holtmann {
2337f8558555SMarcel Holtmann 	struct hci_cp_set_conn_encrypt *cp;
2338f8558555SMarcel Holtmann 	struct hci_conn *conn;
2339f8558555SMarcel Holtmann 
2340147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2341f8558555SMarcel Holtmann 
2342f8558555SMarcel Holtmann 	if (!status)
2343f8558555SMarcel Holtmann 		return;
2344f8558555SMarcel Holtmann 
2345f8558555SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
2346f8558555SMarcel Holtmann 	if (!cp)
2347f8558555SMarcel Holtmann 		return;
2348f8558555SMarcel Holtmann 
2349f8558555SMarcel Holtmann 	hci_dev_lock(hdev);
2350f8558555SMarcel Holtmann 
2351f8558555SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2352f8558555SMarcel Holtmann 	if (conn) {
2353f8558555SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
2354539c496dSJohan Hedberg 			hci_connect_cfm(conn, status);
235576a68ba0SDavid Herrmann 			hci_conn_drop(conn);
2356f8558555SMarcel Holtmann 		}
2357f8558555SMarcel Holtmann 	}
2358f8558555SMarcel Holtmann 
2359f8558555SMarcel Holtmann 	hci_dev_unlock(hdev);
2360f8558555SMarcel Holtmann }
2361f8558555SMarcel Holtmann 
2362127178d2SJohan Hedberg static int hci_outgoing_auth_needed(struct hci_dev *hdev,
2363392599b9SJohan Hedberg 				    struct hci_conn *conn)
2364392599b9SJohan Hedberg {
2365392599b9SJohan Hedberg 	if (conn->state != BT_CONFIG || !conn->out)
2366392599b9SJohan Hedberg 		return 0;
2367392599b9SJohan Hedberg 
2368765c2a96SJohan Hedberg 	if (conn->pending_sec_level == BT_SECURITY_SDP)
2369392599b9SJohan Hedberg 		return 0;
2370392599b9SJohan Hedberg 
2371392599b9SJohan Hedberg 	/* Only request authentication for SSP connections or non-SSP
2372264b8b4eSJohan Hedberg 	 * devices with sec_level MEDIUM or HIGH or if MITM protection
2373264b8b4eSJohan Hedberg 	 * is requested.
2374264b8b4eSJohan Hedberg 	 */
2375807deac2SGustavo Padovan 	if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
23767e3691e1SJohan Hedberg 	    conn->pending_sec_level != BT_SECURITY_FIPS &&
2377264b8b4eSJohan Hedberg 	    conn->pending_sec_level != BT_SECURITY_HIGH &&
2378264b8b4eSJohan Hedberg 	    conn->pending_sec_level != BT_SECURITY_MEDIUM)
2379392599b9SJohan Hedberg 		return 0;
2380392599b9SJohan Hedberg 
2381392599b9SJohan Hedberg 	return 1;
2382392599b9SJohan Hedberg }
2383392599b9SJohan Hedberg 
23846039aa73SGustavo Padovan static int hci_resolve_name(struct hci_dev *hdev,
238500abfe44SGustavo F. Padovan 				   struct inquiry_entry *e)
238630dc78e1SJohan Hedberg {
238730dc78e1SJohan Hedberg 	struct hci_cp_remote_name_req cp;
238830dc78e1SJohan Hedberg 
238930dc78e1SJohan Hedberg 	memset(&cp, 0, sizeof(cp));
239030dc78e1SJohan Hedberg 
239130dc78e1SJohan Hedberg 	bacpy(&cp.bdaddr, &e->data.bdaddr);
239230dc78e1SJohan Hedberg 	cp.pscan_rep_mode = e->data.pscan_rep_mode;
239330dc78e1SJohan Hedberg 	cp.pscan_mode = e->data.pscan_mode;
239430dc78e1SJohan Hedberg 	cp.clock_offset = e->data.clock_offset;
239530dc78e1SJohan Hedberg 
239630dc78e1SJohan Hedberg 	return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
239730dc78e1SJohan Hedberg }
239830dc78e1SJohan Hedberg 
2399b644ba33SJohan Hedberg static bool hci_resolve_next_name(struct hci_dev *hdev)
240030dc78e1SJohan Hedberg {
240130dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
240230dc78e1SJohan Hedberg 	struct inquiry_entry *e;
240330dc78e1SJohan Hedberg 
2404b644ba33SJohan Hedberg 	if (list_empty(&discov->resolve))
2405b644ba33SJohan Hedberg 		return false;
2406b644ba33SJohan Hedberg 
2407dbf6811aSArchie Pusaka 	/* We should stop if we already spent too much time resolving names. */
2408dbf6811aSArchie Pusaka 	if (time_after(jiffies, discov->name_resolve_timeout)) {
2409dbf6811aSArchie Pusaka 		bt_dev_warn_ratelimited(hdev, "Name resolve takes too long.");
2410dbf6811aSArchie Pusaka 		return false;
2411dbf6811aSArchie Pusaka 	}
2412dbf6811aSArchie Pusaka 
2413b644ba33SJohan Hedberg 	e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
2414c810089cSRam Malovany 	if (!e)
2415c810089cSRam Malovany 		return false;
2416c810089cSRam Malovany 
2417b644ba33SJohan Hedberg 	if (hci_resolve_name(hdev, e) == 0) {
2418b644ba33SJohan Hedberg 		e->name_state = NAME_PENDING;
2419b644ba33SJohan Hedberg 		return true;
2420b644ba33SJohan Hedberg 	}
2421b644ba33SJohan Hedberg 
2422b644ba33SJohan Hedberg 	return false;
2423b644ba33SJohan Hedberg }
2424b644ba33SJohan Hedberg 
2425b644ba33SJohan Hedberg static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
2426b644ba33SJohan Hedberg 				   bdaddr_t *bdaddr, u8 *name, u8 name_len)
2427b644ba33SJohan Hedberg {
2428b644ba33SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
2429b644ba33SJohan Hedberg 	struct inquiry_entry *e;
2430b644ba33SJohan Hedberg 
243160cb49d2SJohan Hedberg 	/* Update the mgmt connected state if necessary. Be careful with
243260cb49d2SJohan Hedberg 	 * conn objects that exist but are not (yet) connected however.
243360cb49d2SJohan Hedberg 	 * Only those in BT_CONFIG or BT_CONNECTED states can be
243460cb49d2SJohan Hedberg 	 * considered connected.
243560cb49d2SJohan Hedberg 	 */
243660cb49d2SJohan Hedberg 	if (conn &&
243760cb49d2SJohan Hedberg 	    (conn->state == BT_CONFIG || conn->state == BT_CONNECTED) &&
2438cb77c3ecSJaganath Kanakkassery 	    !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
24391c6ed31bSYu Liu 		mgmt_device_connected(hdev, conn, name, name_len);
2440b644ba33SJohan Hedberg 
2441b644ba33SJohan Hedberg 	if (discov->state == DISCOVERY_STOPPED)
2442b644ba33SJohan Hedberg 		return;
2443b644ba33SJohan Hedberg 
244430dc78e1SJohan Hedberg 	if (discov->state == DISCOVERY_STOPPING)
244530dc78e1SJohan Hedberg 		goto discov_complete;
244630dc78e1SJohan Hedberg 
244730dc78e1SJohan Hedberg 	if (discov->state != DISCOVERY_RESOLVING)
244830dc78e1SJohan Hedberg 		return;
244930dc78e1SJohan Hedberg 
245030dc78e1SJohan Hedberg 	e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
24517cc8380eSRam Malovany 	/* If the device was not found in a list of found devices names of which
24527cc8380eSRam Malovany 	 * are pending. there is no need to continue resolving a next name as it
24537cc8380eSRam Malovany 	 * will be done upon receiving another Remote Name Request Complete
24547cc8380eSRam Malovany 	 * Event */
24557cc8380eSRam Malovany 	if (!e)
24567cc8380eSRam Malovany 		return;
24577cc8380eSRam Malovany 
245830dc78e1SJohan Hedberg 	list_del(&e->list);
2459ea13aed5SArchie Pusaka 
2460ea13aed5SArchie Pusaka 	e->name_state = name ? NAME_KNOWN : NAME_NOT_KNOWN;
2461ea13aed5SArchie Pusaka 	mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00, e->data.rssi,
2462ea13aed5SArchie Pusaka 			 name, name_len);
246330dc78e1SJohan Hedberg 
2464b644ba33SJohan Hedberg 	if (hci_resolve_next_name(hdev))
246530dc78e1SJohan Hedberg 		return;
246630dc78e1SJohan Hedberg 
246730dc78e1SJohan Hedberg discov_complete:
246830dc78e1SJohan Hedberg 	hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
246930dc78e1SJohan Hedberg }
247030dc78e1SJohan Hedberg 
2471a9de9248SMarcel Holtmann static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
24721da177e4SLinus Torvalds {
2473127178d2SJohan Hedberg 	struct hci_cp_remote_name_req *cp;
2474127178d2SJohan Hedberg 	struct hci_conn *conn;
2475127178d2SJohan Hedberg 
2476147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2477127178d2SJohan Hedberg 
2478127178d2SJohan Hedberg 	/* If successful wait for the name req complete event before
2479127178d2SJohan Hedberg 	 * checking for the need to do authentication */
2480127178d2SJohan Hedberg 	if (!status)
2481127178d2SJohan Hedberg 		return;
2482127178d2SJohan Hedberg 
2483127178d2SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
2484127178d2SJohan Hedberg 	if (!cp)
2485127178d2SJohan Hedberg 		return;
2486127178d2SJohan Hedberg 
2487127178d2SJohan Hedberg 	hci_dev_lock(hdev);
2488127178d2SJohan Hedberg 
2489127178d2SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
2490b644ba33SJohan Hedberg 
2491d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
2492b644ba33SJohan Hedberg 		hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
2493b644ba33SJohan Hedberg 
249479c6c70cSJohan Hedberg 	if (!conn)
249579c6c70cSJohan Hedberg 		goto unlock;
249679c6c70cSJohan Hedberg 
249779c6c70cSJohan Hedberg 	if (!hci_outgoing_auth_needed(hdev, conn))
249879c6c70cSJohan Hedberg 		goto unlock;
249979c6c70cSJohan Hedberg 
250051a8efd7SJohan Hedberg 	if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
2501c1f23a2bSJohannes Berg 		struct hci_cp_auth_requested auth_cp;
2502c1f23a2bSJohannes Berg 
2503977f8fceSJohan Hedberg 		set_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags);
2504977f8fceSJohan Hedberg 
2505c1f23a2bSJohannes Berg 		auth_cp.handle = __cpu_to_le16(conn->handle);
2506c1f23a2bSJohannes Berg 		hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
2507c1f23a2bSJohannes Berg 			     sizeof(auth_cp), &auth_cp);
2508127178d2SJohan Hedberg 	}
2509127178d2SJohan Hedberg 
251079c6c70cSJohan Hedberg unlock:
2511127178d2SJohan Hedberg 	hci_dev_unlock(hdev);
2512a9de9248SMarcel Holtmann }
25131da177e4SLinus Torvalds 
2514769be974SMarcel Holtmann static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
2515769be974SMarcel Holtmann {
2516769be974SMarcel Holtmann 	struct hci_cp_read_remote_features *cp;
2517769be974SMarcel Holtmann 	struct hci_conn *conn;
2518769be974SMarcel Holtmann 
2519147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2520769be974SMarcel Holtmann 
2521769be974SMarcel Holtmann 	if (!status)
2522769be974SMarcel Holtmann 		return;
2523769be974SMarcel Holtmann 
2524769be974SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
2525769be974SMarcel Holtmann 	if (!cp)
2526769be974SMarcel Holtmann 		return;
2527769be974SMarcel Holtmann 
2528769be974SMarcel Holtmann 	hci_dev_lock(hdev);
2529769be974SMarcel Holtmann 
2530769be974SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2531769be974SMarcel Holtmann 	if (conn) {
2532769be974SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
2533539c496dSJohan Hedberg 			hci_connect_cfm(conn, status);
253476a68ba0SDavid Herrmann 			hci_conn_drop(conn);
2535769be974SMarcel Holtmann 		}
2536769be974SMarcel Holtmann 	}
2537769be974SMarcel Holtmann 
2538769be974SMarcel Holtmann 	hci_dev_unlock(hdev);
2539769be974SMarcel Holtmann }
2540769be974SMarcel Holtmann 
2541769be974SMarcel Holtmann static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
2542769be974SMarcel Holtmann {
2543769be974SMarcel Holtmann 	struct hci_cp_read_remote_ext_features *cp;
2544769be974SMarcel Holtmann 	struct hci_conn *conn;
2545769be974SMarcel Holtmann 
2546147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2547769be974SMarcel Holtmann 
2548769be974SMarcel Holtmann 	if (!status)
2549769be974SMarcel Holtmann 		return;
2550769be974SMarcel Holtmann 
2551769be974SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
2552769be974SMarcel Holtmann 	if (!cp)
2553769be974SMarcel Holtmann 		return;
2554769be974SMarcel Holtmann 
2555769be974SMarcel Holtmann 	hci_dev_lock(hdev);
2556769be974SMarcel Holtmann 
2557769be974SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2558769be974SMarcel Holtmann 	if (conn) {
2559769be974SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
2560539c496dSJohan Hedberg 			hci_connect_cfm(conn, status);
256176a68ba0SDavid Herrmann 			hci_conn_drop(conn);
2562769be974SMarcel Holtmann 		}
2563769be974SMarcel Holtmann 	}
2564769be974SMarcel Holtmann 
2565769be974SMarcel Holtmann 	hci_dev_unlock(hdev);
2566769be974SMarcel Holtmann }
2567769be974SMarcel Holtmann 
2568a9de9248SMarcel Holtmann static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
2569a9de9248SMarcel Holtmann {
2570b6a0dc82SMarcel Holtmann 	struct hci_cp_setup_sync_conn *cp;
2571b6a0dc82SMarcel Holtmann 	struct hci_conn *acl, *sco;
2572b6a0dc82SMarcel Holtmann 	__u16 handle;
2573b6a0dc82SMarcel Holtmann 
2574147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2575b6a0dc82SMarcel Holtmann 
2576b6a0dc82SMarcel Holtmann 	if (!status)
2577b6a0dc82SMarcel Holtmann 		return;
2578b6a0dc82SMarcel Holtmann 
2579b6a0dc82SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
2580b6a0dc82SMarcel Holtmann 	if (!cp)
2581b6a0dc82SMarcel Holtmann 		return;
2582b6a0dc82SMarcel Holtmann 
2583b6a0dc82SMarcel Holtmann 	handle = __le16_to_cpu(cp->handle);
2584b6a0dc82SMarcel Holtmann 
2585147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "handle 0x%4.4x", handle);
2586b6a0dc82SMarcel Holtmann 
2587b6a0dc82SMarcel Holtmann 	hci_dev_lock(hdev);
2588b6a0dc82SMarcel Holtmann 
2589b6a0dc82SMarcel Holtmann 	acl = hci_conn_hash_lookup_handle(hdev, handle);
25905a08ecceSAndrei Emeltchenko 	if (acl) {
25915a08ecceSAndrei Emeltchenko 		sco = acl->link;
25925a08ecceSAndrei Emeltchenko 		if (sco) {
2593b6a0dc82SMarcel Holtmann 			sco->state = BT_CLOSED;
2594b6a0dc82SMarcel Holtmann 
2595539c496dSJohan Hedberg 			hci_connect_cfm(sco, status);
2596b6a0dc82SMarcel Holtmann 			hci_conn_del(sco);
2597b6a0dc82SMarcel Holtmann 		}
25985a08ecceSAndrei Emeltchenko 	}
2599b6a0dc82SMarcel Holtmann 
2600b6a0dc82SMarcel Holtmann 	hci_dev_unlock(hdev);
2601a9de9248SMarcel Holtmann }
2602a9de9248SMarcel Holtmann 
2603b2af264aSKiran K static void hci_cs_enhanced_setup_sync_conn(struct hci_dev *hdev, __u8 status)
2604b2af264aSKiran K {
2605b2af264aSKiran K 	struct hci_cp_enhanced_setup_sync_conn *cp;
2606b2af264aSKiran K 	struct hci_conn *acl, *sco;
2607b2af264aSKiran K 	__u16 handle;
2608b2af264aSKiran K 
2609b2af264aSKiran K 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2610b2af264aSKiran K 
2611b2af264aSKiran K 	if (!status)
2612b2af264aSKiran K 		return;
2613b2af264aSKiran K 
2614b2af264aSKiran K 	cp = hci_sent_cmd_data(hdev, HCI_OP_ENHANCED_SETUP_SYNC_CONN);
2615b2af264aSKiran K 	if (!cp)
2616b2af264aSKiran K 		return;
2617b2af264aSKiran K 
2618b2af264aSKiran K 	handle = __le16_to_cpu(cp->handle);
2619b2af264aSKiran K 
2620b2af264aSKiran K 	bt_dev_dbg(hdev, "handle 0x%4.4x", handle);
2621b2af264aSKiran K 
2622b2af264aSKiran K 	hci_dev_lock(hdev);
2623b2af264aSKiran K 
2624b2af264aSKiran K 	acl = hci_conn_hash_lookup_handle(hdev, handle);
2625b2af264aSKiran K 	if (acl) {
2626b2af264aSKiran K 		sco = acl->link;
2627b2af264aSKiran K 		if (sco) {
2628b2af264aSKiran K 			sco->state = BT_CLOSED;
2629b2af264aSKiran K 
2630b2af264aSKiran K 			hci_connect_cfm(sco, status);
2631b2af264aSKiran K 			hci_conn_del(sco);
2632b2af264aSKiran K 		}
2633b2af264aSKiran K 	}
2634b2af264aSKiran K 
2635b2af264aSKiran K 	hci_dev_unlock(hdev);
2636b2af264aSKiran K }
2637b2af264aSKiran K 
2638a9de9248SMarcel Holtmann static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
2639a9de9248SMarcel Holtmann {
2640a9de9248SMarcel Holtmann 	struct hci_cp_sniff_mode *cp;
264104837f64SMarcel Holtmann 	struct hci_conn *conn;
264204837f64SMarcel Holtmann 
2643147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2644a9de9248SMarcel Holtmann 
2645a9de9248SMarcel Holtmann 	if (!status)
2646a9de9248SMarcel Holtmann 		return;
2647a9de9248SMarcel Holtmann 
2648a9de9248SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
264904837f64SMarcel Holtmann 	if (!cp)
2650a9de9248SMarcel Holtmann 		return;
265104837f64SMarcel Holtmann 
265204837f64SMarcel Holtmann 	hci_dev_lock(hdev);
265304837f64SMarcel Holtmann 
265404837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2655e73439d8SMarcel Holtmann 	if (conn) {
265651a8efd7SJohan Hedberg 		clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
265704837f64SMarcel Holtmann 
265851a8efd7SJohan Hedberg 		if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
2659e73439d8SMarcel Holtmann 			hci_sco_setup(conn, status);
2660e73439d8SMarcel Holtmann 	}
2661e73439d8SMarcel Holtmann 
266204837f64SMarcel Holtmann 	hci_dev_unlock(hdev);
266304837f64SMarcel Holtmann }
266404837f64SMarcel Holtmann 
2665a9de9248SMarcel Holtmann static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
2666a9de9248SMarcel Holtmann {
2667a9de9248SMarcel Holtmann 	struct hci_cp_exit_sniff_mode *cp;
266804837f64SMarcel Holtmann 	struct hci_conn *conn;
266904837f64SMarcel Holtmann 
2670147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2671a9de9248SMarcel Holtmann 
2672a9de9248SMarcel Holtmann 	if (!status)
2673a9de9248SMarcel Holtmann 		return;
2674a9de9248SMarcel Holtmann 
2675a9de9248SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
267604837f64SMarcel Holtmann 	if (!cp)
2677a9de9248SMarcel Holtmann 		return;
267804837f64SMarcel Holtmann 
267904837f64SMarcel Holtmann 	hci_dev_lock(hdev);
268004837f64SMarcel Holtmann 
268104837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2682e73439d8SMarcel Holtmann 	if (conn) {
268351a8efd7SJohan Hedberg 		clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
268404837f64SMarcel Holtmann 
268551a8efd7SJohan Hedberg 		if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
2686e73439d8SMarcel Holtmann 			hci_sco_setup(conn, status);
2687e73439d8SMarcel Holtmann 	}
2688e73439d8SMarcel Holtmann 
268904837f64SMarcel Holtmann 	hci_dev_unlock(hdev);
269004837f64SMarcel Holtmann }
269104837f64SMarcel Holtmann 
269288c3df13SJohan Hedberg static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
269388c3df13SJohan Hedberg {
269488c3df13SJohan Hedberg 	struct hci_cp_disconnect *cp;
2695182ee45dSLuiz Augusto von Dentz 	struct hci_conn_params *params;
269688c3df13SJohan Hedberg 	struct hci_conn *conn;
2697182ee45dSLuiz Augusto von Dentz 	bool mgmt_conn;
269888c3df13SJohan Hedberg 
2699147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2700147306ccSLuiz Augusto von Dentz 
2701182ee45dSLuiz Augusto von Dentz 	/* Wait for HCI_EV_DISCONN_COMPLETE if status 0x00 and not suspended
2702182ee45dSLuiz Augusto von Dentz 	 * otherwise cleanup the connection immediately.
2703182ee45dSLuiz Augusto von Dentz 	 */
2704182ee45dSLuiz Augusto von Dentz 	if (!status && !hdev->suspended)
270588c3df13SJohan Hedberg 		return;
270688c3df13SJohan Hedberg 
270788c3df13SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
270888c3df13SJohan Hedberg 	if (!cp)
270988c3df13SJohan Hedberg 		return;
271088c3df13SJohan Hedberg 
271188c3df13SJohan Hedberg 	hci_dev_lock(hdev);
271288c3df13SJohan Hedberg 
271388c3df13SJohan Hedberg 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2714182ee45dSLuiz Augusto von Dentz 	if (!conn)
2715182ee45dSLuiz Augusto von Dentz 		goto unlock;
2716182ee45dSLuiz Augusto von Dentz 
2717182ee45dSLuiz Augusto von Dentz 	if (status) {
271888c3df13SJohan Hedberg 		mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
271988c3df13SJohan Hedberg 				       conn->dst_type, status);
272088c3df13SJohan Hedberg 
27211eeaa1aeSLuiz Augusto von Dentz 		if (conn->type == LE_LINK && conn->role == HCI_ROLE_SLAVE) {
27227087c4f6SLuiz Augusto von Dentz 			hdev->cur_adv_instance = conn->adv_instance;
2723abfeea47SLuiz Augusto von Dentz 			hci_enable_advertising(hdev);
27247087c4f6SLuiz Augusto von Dentz 		}
27257087c4f6SLuiz Augusto von Dentz 
2726182ee45dSLuiz Augusto von Dentz 		goto done;
2727182ee45dSLuiz Augusto von Dentz 	}
2728182ee45dSLuiz Augusto von Dentz 
2729182ee45dSLuiz Augusto von Dentz 	mgmt_conn = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
2730182ee45dSLuiz Augusto von Dentz 
2731182ee45dSLuiz Augusto von Dentz 	if (conn->type == ACL_LINK) {
2732182ee45dSLuiz Augusto von Dentz 		if (test_bit(HCI_CONN_FLUSH_KEY, &conn->flags))
2733182ee45dSLuiz Augusto von Dentz 			hci_remove_link_key(hdev, &conn->dst);
2734182ee45dSLuiz Augusto von Dentz 	}
2735182ee45dSLuiz Augusto von Dentz 
2736182ee45dSLuiz Augusto von Dentz 	params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
2737182ee45dSLuiz Augusto von Dentz 	if (params) {
2738182ee45dSLuiz Augusto von Dentz 		switch (params->auto_connect) {
2739182ee45dSLuiz Augusto von Dentz 		case HCI_AUTO_CONN_LINK_LOSS:
2740182ee45dSLuiz Augusto von Dentz 			if (cp->reason != HCI_ERROR_CONNECTION_TIMEOUT)
2741182ee45dSLuiz Augusto von Dentz 				break;
2742182ee45dSLuiz Augusto von Dentz 			fallthrough;
2743182ee45dSLuiz Augusto von Dentz 
2744182ee45dSLuiz Augusto von Dentz 		case HCI_AUTO_CONN_DIRECT:
2745182ee45dSLuiz Augusto von Dentz 		case HCI_AUTO_CONN_ALWAYS:
2746182ee45dSLuiz Augusto von Dentz 			list_del_init(&params->action);
2747182ee45dSLuiz Augusto von Dentz 			list_add(&params->action, &hdev->pend_le_conns);
2748182ee45dSLuiz Augusto von Dentz 			break;
2749182ee45dSLuiz Augusto von Dentz 
2750182ee45dSLuiz Augusto von Dentz 		default:
2751182ee45dSLuiz Augusto von Dentz 			break;
2752182ee45dSLuiz Augusto von Dentz 		}
2753182ee45dSLuiz Augusto von Dentz 	}
2754182ee45dSLuiz Augusto von Dentz 
2755182ee45dSLuiz Augusto von Dentz 	mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type,
2756182ee45dSLuiz Augusto von Dentz 				 cp->reason, mgmt_conn);
2757182ee45dSLuiz Augusto von Dentz 
2758182ee45dSLuiz Augusto von Dentz 	hci_disconn_cfm(conn, cp->reason);
2759182ee45dSLuiz Augusto von Dentz 
2760182ee45dSLuiz Augusto von Dentz done:
2761b8d29052SJoseph Hwang 	/* If the disconnection failed for any reason, the upper layer
2762b8d29052SJoseph Hwang 	 * does not retry to disconnect in current implementation.
2763b8d29052SJoseph Hwang 	 * Hence, we need to do some basic cleanup here and re-enable
2764b8d29052SJoseph Hwang 	 * advertising if necessary.
2765b8d29052SJoseph Hwang 	 */
2766b8d29052SJoseph Hwang 	hci_conn_del(conn);
2767182ee45dSLuiz Augusto von Dentz unlock:
276888c3df13SJohan Hedberg 	hci_dev_unlock(hdev);
276988c3df13SJohan Hedberg }
277088c3df13SJohan Hedberg 
2771d850bf08SLuiz Augusto von Dentz static u8 ev_bdaddr_type(struct hci_dev *hdev, u8 type, bool *resolved)
27724ec4d63bSLuiz Augusto von Dentz {
27734ec4d63bSLuiz Augusto von Dentz 	/* When using controller based address resolution, then the new
27744ec4d63bSLuiz Augusto von Dentz 	 * address types 0x02 and 0x03 are used. These types need to be
27754ec4d63bSLuiz Augusto von Dentz 	 * converted back into either public address or random address type
27764ec4d63bSLuiz Augusto von Dentz 	 */
27774ec4d63bSLuiz Augusto von Dentz 	switch (type) {
27784ec4d63bSLuiz Augusto von Dentz 	case ADDR_LE_DEV_PUBLIC_RESOLVED:
2779d850bf08SLuiz Augusto von Dentz 		if (resolved)
2780d850bf08SLuiz Augusto von Dentz 			*resolved = true;
27814ec4d63bSLuiz Augusto von Dentz 		return ADDR_LE_DEV_PUBLIC;
27824ec4d63bSLuiz Augusto von Dentz 	case ADDR_LE_DEV_RANDOM_RESOLVED:
2783d850bf08SLuiz Augusto von Dentz 		if (resolved)
2784d850bf08SLuiz Augusto von Dentz 			*resolved = true;
27854ec4d63bSLuiz Augusto von Dentz 		return ADDR_LE_DEV_RANDOM;
27864ec4d63bSLuiz Augusto von Dentz 	}
27874ec4d63bSLuiz Augusto von Dentz 
2788d850bf08SLuiz Augusto von Dentz 	if (resolved)
2789d850bf08SLuiz Augusto von Dentz 		*resolved = false;
27904ec4d63bSLuiz Augusto von Dentz 	return type;
27914ec4d63bSLuiz Augusto von Dentz }
27924ec4d63bSLuiz Augusto von Dentz 
2793d12fb056SJaganath Kanakkassery static void cs_le_create_conn(struct hci_dev *hdev, bdaddr_t *peer_addr,
2794d12fb056SJaganath Kanakkassery 			      u8 peer_addr_type, u8 own_address_type,
2795d12fb056SJaganath Kanakkassery 			      u8 filter_policy)
2796d12fb056SJaganath Kanakkassery {
2797d12fb056SJaganath Kanakkassery 	struct hci_conn *conn;
2798d12fb056SJaganath Kanakkassery 
2799d12fb056SJaganath Kanakkassery 	conn = hci_conn_hash_lookup_le(hdev, peer_addr,
2800d12fb056SJaganath Kanakkassery 				       peer_addr_type);
2801d12fb056SJaganath Kanakkassery 	if (!conn)
2802d12fb056SJaganath Kanakkassery 		return;
2803d12fb056SJaganath Kanakkassery 
2804d850bf08SLuiz Augusto von Dentz 	own_address_type = ev_bdaddr_type(hdev, own_address_type, NULL);
2805b31bc00bSSathish Narasimman 
2806d12fb056SJaganath Kanakkassery 	/* Store the initiator and responder address information which
2807d12fb056SJaganath Kanakkassery 	 * is needed for SMP. These values will not change during the
2808d12fb056SJaganath Kanakkassery 	 * lifetime of the connection.
2809d12fb056SJaganath Kanakkassery 	 */
2810d12fb056SJaganath Kanakkassery 	conn->init_addr_type = own_address_type;
2811d12fb056SJaganath Kanakkassery 	if (own_address_type == ADDR_LE_DEV_RANDOM)
2812d12fb056SJaganath Kanakkassery 		bacpy(&conn->init_addr, &hdev->random_addr);
2813d12fb056SJaganath Kanakkassery 	else
2814d12fb056SJaganath Kanakkassery 		bacpy(&conn->init_addr, &hdev->bdaddr);
2815d12fb056SJaganath Kanakkassery 
2816d12fb056SJaganath Kanakkassery 	conn->resp_addr_type = peer_addr_type;
2817d12fb056SJaganath Kanakkassery 	bacpy(&conn->resp_addr, peer_addr);
2818d12fb056SJaganath Kanakkassery 
2819d12fb056SJaganath Kanakkassery 	/* We don't want the connection attempt to stick around
2820d12fb056SJaganath Kanakkassery 	 * indefinitely since LE doesn't have a page timeout concept
2821d12fb056SJaganath Kanakkassery 	 * like BR/EDR. Set a timer for any connection that doesn't use
28223d4f9c00SArchie Pusaka 	 * the accept list for connecting.
2823d12fb056SJaganath Kanakkassery 	 */
2824d12fb056SJaganath Kanakkassery 	if (filter_policy == HCI_LE_USE_PEER_ADDR)
2825d12fb056SJaganath Kanakkassery 		queue_delayed_work(conn->hdev->workqueue,
2826d12fb056SJaganath Kanakkassery 				   &conn->le_conn_timeout,
2827d12fb056SJaganath Kanakkassery 				   conn->conn_timeout);
2828d12fb056SJaganath Kanakkassery }
2829d12fb056SJaganath Kanakkassery 
2830cb1d68f7SJohan Hedberg static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status)
2831cb1d68f7SJohan Hedberg {
2832cb1d68f7SJohan Hedberg 	struct hci_cp_le_create_conn *cp;
2833cb1d68f7SJohan Hedberg 
2834147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2835cb1d68f7SJohan Hedberg 
2836cb1d68f7SJohan Hedberg 	/* All connection failure handling is taken care of by the
2837cb1d68f7SJohan Hedberg 	 * hci_le_conn_failed function which is triggered by the HCI
2838cb1d68f7SJohan Hedberg 	 * request completion callbacks used for connecting.
2839cb1d68f7SJohan Hedberg 	 */
2840cb1d68f7SJohan Hedberg 	if (status)
2841cb1d68f7SJohan Hedberg 		return;
2842cb1d68f7SJohan Hedberg 
2843cb1d68f7SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
2844cb1d68f7SJohan Hedberg 	if (!cp)
2845cb1d68f7SJohan Hedberg 		return;
2846cb1d68f7SJohan Hedberg 
2847cb1d68f7SJohan Hedberg 	hci_dev_lock(hdev);
2848cb1d68f7SJohan Hedberg 
2849d12fb056SJaganath Kanakkassery 	cs_le_create_conn(hdev, &cp->peer_addr, cp->peer_addr_type,
2850d12fb056SJaganath Kanakkassery 			  cp->own_address_type, cp->filter_policy);
2851cb1d68f7SJohan Hedberg 
2852cb1d68f7SJohan Hedberg 	hci_dev_unlock(hdev);
2853cb1d68f7SJohan Hedberg }
2854cb1d68f7SJohan Hedberg 
28554d94f95dSJaganath Kanakkassery static void hci_cs_le_ext_create_conn(struct hci_dev *hdev, u8 status)
28564d94f95dSJaganath Kanakkassery {
28574d94f95dSJaganath Kanakkassery 	struct hci_cp_le_ext_create_conn *cp;
28584d94f95dSJaganath Kanakkassery 
2859147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
28604d94f95dSJaganath Kanakkassery 
28614d94f95dSJaganath Kanakkassery 	/* All connection failure handling is taken care of by the
28624d94f95dSJaganath Kanakkassery 	 * hci_le_conn_failed function which is triggered by the HCI
28634d94f95dSJaganath Kanakkassery 	 * request completion callbacks used for connecting.
28644d94f95dSJaganath Kanakkassery 	 */
28654d94f95dSJaganath Kanakkassery 	if (status)
28664d94f95dSJaganath Kanakkassery 		return;
28674d94f95dSJaganath Kanakkassery 
28684d94f95dSJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_EXT_CREATE_CONN);
28694d94f95dSJaganath Kanakkassery 	if (!cp)
28704d94f95dSJaganath Kanakkassery 		return;
28714d94f95dSJaganath Kanakkassery 
28724d94f95dSJaganath Kanakkassery 	hci_dev_lock(hdev);
28734d94f95dSJaganath Kanakkassery 
28744d94f95dSJaganath Kanakkassery 	cs_le_create_conn(hdev, &cp->peer_addr, cp->peer_addr_type,
28754d94f95dSJaganath Kanakkassery 			  cp->own_addr_type, cp->filter_policy);
28764d94f95dSJaganath Kanakkassery 
28774d94f95dSJaganath Kanakkassery 	hci_dev_unlock(hdev);
28784d94f95dSJaganath Kanakkassery }
28794d94f95dSJaganath Kanakkassery 
28800fe29fd1SMarcel Holtmann static void hci_cs_le_read_remote_features(struct hci_dev *hdev, u8 status)
28810fe29fd1SMarcel Holtmann {
28820fe29fd1SMarcel Holtmann 	struct hci_cp_le_read_remote_features *cp;
28830fe29fd1SMarcel Holtmann 	struct hci_conn *conn;
28840fe29fd1SMarcel Holtmann 
2885147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
28860fe29fd1SMarcel Holtmann 
28870fe29fd1SMarcel Holtmann 	if (!status)
28880fe29fd1SMarcel Holtmann 		return;
28890fe29fd1SMarcel Holtmann 
28900fe29fd1SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_READ_REMOTE_FEATURES);
28910fe29fd1SMarcel Holtmann 	if (!cp)
28920fe29fd1SMarcel Holtmann 		return;
28930fe29fd1SMarcel Holtmann 
28940fe29fd1SMarcel Holtmann 	hci_dev_lock(hdev);
28950fe29fd1SMarcel Holtmann 
28960fe29fd1SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
28970fe29fd1SMarcel Holtmann 	if (conn) {
28980fe29fd1SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
28990fe29fd1SMarcel Holtmann 			hci_connect_cfm(conn, status);
29000fe29fd1SMarcel Holtmann 			hci_conn_drop(conn);
29010fe29fd1SMarcel Holtmann 		}
29020fe29fd1SMarcel Holtmann 	}
29030fe29fd1SMarcel Holtmann 
29040fe29fd1SMarcel Holtmann 	hci_dev_unlock(hdev);
29050fe29fd1SMarcel Holtmann }
29060fe29fd1SMarcel Holtmann 
290781d0c8adSJohan Hedberg static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
290881d0c8adSJohan Hedberg {
290981d0c8adSJohan Hedberg 	struct hci_cp_le_start_enc *cp;
291081d0c8adSJohan Hedberg 	struct hci_conn *conn;
291181d0c8adSJohan Hedberg 
2912147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
291381d0c8adSJohan Hedberg 
291481d0c8adSJohan Hedberg 	if (!status)
291581d0c8adSJohan Hedberg 		return;
291681d0c8adSJohan Hedberg 
291781d0c8adSJohan Hedberg 	hci_dev_lock(hdev);
291881d0c8adSJohan Hedberg 
291981d0c8adSJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_START_ENC);
292081d0c8adSJohan Hedberg 	if (!cp)
292181d0c8adSJohan Hedberg 		goto unlock;
292281d0c8adSJohan Hedberg 
292381d0c8adSJohan Hedberg 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
292481d0c8adSJohan Hedberg 	if (!conn)
292581d0c8adSJohan Hedberg 		goto unlock;
292681d0c8adSJohan Hedberg 
292781d0c8adSJohan Hedberg 	if (conn->state != BT_CONNECTED)
292881d0c8adSJohan Hedberg 		goto unlock;
292981d0c8adSJohan Hedberg 
293081d0c8adSJohan Hedberg 	hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
293181d0c8adSJohan Hedberg 	hci_conn_drop(conn);
293281d0c8adSJohan Hedberg 
293381d0c8adSJohan Hedberg unlock:
293481d0c8adSJohan Hedberg 	hci_dev_unlock(hdev);
293581d0c8adSJohan Hedberg }
293681d0c8adSJohan Hedberg 
293750fc85f1SKuba Pawlak static void hci_cs_switch_role(struct hci_dev *hdev, u8 status)
293850fc85f1SKuba Pawlak {
293950fc85f1SKuba Pawlak 	struct hci_cp_switch_role *cp;
294050fc85f1SKuba Pawlak 	struct hci_conn *conn;
294150fc85f1SKuba Pawlak 
294250fc85f1SKuba Pawlak 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
294350fc85f1SKuba Pawlak 
294450fc85f1SKuba Pawlak 	if (!status)
294550fc85f1SKuba Pawlak 		return;
294650fc85f1SKuba Pawlak 
294750fc85f1SKuba Pawlak 	cp = hci_sent_cmd_data(hdev, HCI_OP_SWITCH_ROLE);
294850fc85f1SKuba Pawlak 	if (!cp)
294950fc85f1SKuba Pawlak 		return;
295050fc85f1SKuba Pawlak 
295150fc85f1SKuba Pawlak 	hci_dev_lock(hdev);
295250fc85f1SKuba Pawlak 
295350fc85f1SKuba Pawlak 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
295450fc85f1SKuba Pawlak 	if (conn)
295550fc85f1SKuba Pawlak 		clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
295650fc85f1SKuba Pawlak 
295750fc85f1SKuba Pawlak 	hci_dev_unlock(hdev);
295850fc85f1SKuba Pawlak }
295950fc85f1SKuba Pawlak 
29603e54c589SLuiz Augusto von Dentz static void hci_inquiry_complete_evt(struct hci_dev *hdev, void *data,
29613e54c589SLuiz Augusto von Dentz 				     struct sk_buff *skb)
29621da177e4SLinus Torvalds {
29633e54c589SLuiz Augusto von Dentz 	struct hci_ev_status *ev = data;
296430dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
296530dc78e1SJohan Hedberg 	struct inquiry_entry *e;
29661da177e4SLinus Torvalds 
29673e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
29681da177e4SLinus Torvalds 
2969a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
297089352e7dSAndre Guedes 
297189352e7dSAndre Guedes 	if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
297289352e7dSAndre Guedes 		return;
297389352e7dSAndre Guedes 
29744e857c58SPeter Zijlstra 	smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */
29753e13fa1eSAndre Guedes 	wake_up_bit(&hdev->flags, HCI_INQUIRY);
29763e13fa1eSAndre Guedes 
2977d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
297830dc78e1SJohan Hedberg 		return;
297930dc78e1SJohan Hedberg 
298056e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
298130dc78e1SJohan Hedberg 
2982343f935bSAndre Guedes 	if (discov->state != DISCOVERY_FINDING)
298330dc78e1SJohan Hedberg 		goto unlock;
298430dc78e1SJohan Hedberg 
298530dc78e1SJohan Hedberg 	if (list_empty(&discov->resolve)) {
298607d2334aSJakub Pawlowski 		/* When BR/EDR inquiry is active and no LE scanning is in
298707d2334aSJakub Pawlowski 		 * progress, then change discovery state to indicate completion.
298807d2334aSJakub Pawlowski 		 *
298907d2334aSJakub Pawlowski 		 * When running LE scanning and BR/EDR inquiry simultaneously
299007d2334aSJakub Pawlowski 		 * and the LE scan already finished, then change the discovery
299107d2334aSJakub Pawlowski 		 * state to indicate completion.
299207d2334aSJakub Pawlowski 		 */
299307d2334aSJakub Pawlowski 		if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
299407d2334aSJakub Pawlowski 		    !test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks))
2995ff9ef578SJohan Hedberg 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
299630dc78e1SJohan Hedberg 		goto unlock;
299730dc78e1SJohan Hedberg 	}
299830dc78e1SJohan Hedberg 
299930dc78e1SJohan Hedberg 	e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
300030dc78e1SJohan Hedberg 	if (e && hci_resolve_name(hdev, e) == 0) {
300130dc78e1SJohan Hedberg 		e->name_state = NAME_PENDING;
300230dc78e1SJohan Hedberg 		hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
3003dbf6811aSArchie Pusaka 		discov->name_resolve_timeout = jiffies + NAME_RESOLVE_DURATION;
300430dc78e1SJohan Hedberg 	} else {
300507d2334aSJakub Pawlowski 		/* When BR/EDR inquiry is active and no LE scanning is in
300607d2334aSJakub Pawlowski 		 * progress, then change discovery state to indicate completion.
300707d2334aSJakub Pawlowski 		 *
300807d2334aSJakub Pawlowski 		 * When running LE scanning and BR/EDR inquiry simultaneously
300907d2334aSJakub Pawlowski 		 * and the LE scan already finished, then change the discovery
301007d2334aSJakub Pawlowski 		 * state to indicate completion.
301107d2334aSJakub Pawlowski 		 */
301207d2334aSJakub Pawlowski 		if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
301307d2334aSJakub Pawlowski 		    !test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks))
301430dc78e1SJohan Hedberg 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
301530dc78e1SJohan Hedberg 	}
301630dc78e1SJohan Hedberg 
301730dc78e1SJohan Hedberg unlock:
301856e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
30191da177e4SLinus Torvalds }
30201da177e4SLinus Torvalds 
30213e54c589SLuiz Augusto von Dentz static void hci_inquiry_result_evt(struct hci_dev *hdev, void *edata,
30223e54c589SLuiz Augusto von Dentz 				   struct sk_buff *skb)
30231da177e4SLinus Torvalds {
30243e54c589SLuiz Augusto von Dentz 	struct hci_ev_inquiry_result *ev = edata;
302545bb4bf0SMarcel Holtmann 	struct inquiry_data data;
302627d9eb4bSLuiz Augusto von Dentz 	int i;
30271da177e4SLinus Torvalds 
302827d9eb4bSLuiz Augusto von Dentz 	if (!hci_ev_skb_pull(hdev, skb, HCI_EV_INQUIRY_RESULT,
302927d9eb4bSLuiz Augusto von Dentz 			     flex_array_size(ev, info, ev->num)))
303027d9eb4bSLuiz Augusto von Dentz 		return;
303127d9eb4bSLuiz Augusto von Dentz 
30323e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "num %d", ev->num);
303327d9eb4bSLuiz Augusto von Dentz 
303427d9eb4bSLuiz Augusto von Dentz 	if (!ev->num)
303545bb4bf0SMarcel Holtmann 		return;
303645bb4bf0SMarcel Holtmann 
3037d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ))
30381519cc17SAndre Guedes 		return;
30391519cc17SAndre Guedes 
30401da177e4SLinus Torvalds 	hci_dev_lock(hdev);
304145bb4bf0SMarcel Holtmann 
304227d9eb4bSLuiz Augusto von Dentz 	for (i = 0; i < ev->num; i++) {
304327d9eb4bSLuiz Augusto von Dentz 		struct inquiry_info *info = &ev->info[i];
3044af58925cSMarcel Holtmann 		u32 flags;
30453175405bSJohan Hedberg 
30461da177e4SLinus Torvalds 		bacpy(&data.bdaddr, &info->bdaddr);
30471da177e4SLinus Torvalds 		data.pscan_rep_mode	= info->pscan_rep_mode;
30481da177e4SLinus Torvalds 		data.pscan_period_mode	= info->pscan_period_mode;
30491da177e4SLinus Torvalds 		data.pscan_mode		= info->pscan_mode;
30501da177e4SLinus Torvalds 		memcpy(data.dev_class, info->dev_class, 3);
30511da177e4SLinus Torvalds 		data.clock_offset	= info->clock_offset;
3052efb2513fSMarcel Holtmann 		data.rssi		= HCI_RSSI_INVALID;
305341a96212SMarcel Holtmann 		data.ssp_mode		= 0x00;
30543175405bSJohan Hedberg 
3055af58925cSMarcel Holtmann 		flags = hci_inquiry_cache_update(hdev, &data, false);
3056af58925cSMarcel Holtmann 
305748264f06SJohan Hedberg 		mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
3058efb2513fSMarcel Holtmann 				  info->dev_class, HCI_RSSI_INVALID,
3059efb2513fSMarcel Holtmann 				  flags, NULL, 0, NULL, 0);
30601da177e4SLinus Torvalds 	}
306145bb4bf0SMarcel Holtmann 
30621da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
30631da177e4SLinus Torvalds }
30641da177e4SLinus Torvalds 
30653e54c589SLuiz Augusto von Dentz static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
30663e54c589SLuiz Augusto von Dentz 				  struct sk_buff *skb)
30671da177e4SLinus Torvalds {
30683e54c589SLuiz Augusto von Dentz 	struct hci_ev_conn_complete *ev = data;
3069a9de9248SMarcel Holtmann 	struct hci_conn *conn;
30701da177e4SLinus Torvalds 
30713e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
307245bb4bf0SMarcel Holtmann 
30731da177e4SLinus Torvalds 	hci_dev_lock(hdev);
307445bb4bf0SMarcel Holtmann 
3075a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
30769499237aSMarcel Holtmann 	if (!conn) {
3077a46b7ed4SSonny Sasaka 		/* Connection may not exist if auto-connected. Check the bredr
3078a46b7ed4SSonny Sasaka 		 * allowlist to see if this device is allowed to auto connect.
3079a46b7ed4SSonny Sasaka 		 * If link is an ACL type, create a connection class
30804f40afc6SAbhishek Pandit-Subedi 		 * automatically.
3081a46b7ed4SSonny Sasaka 		 *
3082a46b7ed4SSonny Sasaka 		 * Auto-connect will only occur if the event filter is
3083a46b7ed4SSonny Sasaka 		 * programmed with a given address. Right now, event filter is
3084a46b7ed4SSonny Sasaka 		 * only used during suspend.
30854f40afc6SAbhishek Pandit-Subedi 		 */
3086a46b7ed4SSonny Sasaka 		if (ev->link_type == ACL_LINK &&
30873d4f9c00SArchie Pusaka 		    hci_bdaddr_list_lookup_with_flags(&hdev->accept_list,
3088a46b7ed4SSonny Sasaka 						      &ev->bdaddr,
3089a46b7ed4SSonny Sasaka 						      BDADDR_BREDR)) {
30904f40afc6SAbhishek Pandit-Subedi 			conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr,
30914f40afc6SAbhishek Pandit-Subedi 					    HCI_ROLE_SLAVE);
30924f40afc6SAbhishek Pandit-Subedi 			if (!conn) {
30934f40afc6SAbhishek Pandit-Subedi 				bt_dev_err(hdev, "no memory for new conn");
30944f40afc6SAbhishek Pandit-Subedi 				goto unlock;
30954f40afc6SAbhishek Pandit-Subedi 			}
30962d186fcdSAbhishek Pandit-Subedi 		} else {
30979499237aSMarcel Holtmann 			if (ev->link_type != SCO_LINK)
30989499237aSMarcel Holtmann 				goto unlock;
30999499237aSMarcel Holtmann 
31002d186fcdSAbhishek Pandit-Subedi 			conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK,
31012d186fcdSAbhishek Pandit-Subedi 						       &ev->bdaddr);
3102a9de9248SMarcel Holtmann 			if (!conn)
3103a9de9248SMarcel Holtmann 				goto unlock;
310445bb4bf0SMarcel Holtmann 
31059499237aSMarcel Holtmann 			conn->type = SCO_LINK;
31069499237aSMarcel Holtmann 		}
31072d186fcdSAbhishek Pandit-Subedi 	}
31089499237aSMarcel Holtmann 
3109a9de9248SMarcel Holtmann 	if (!ev->status) {
3110a9de9248SMarcel Holtmann 		conn->handle = __le16_to_cpu(ev->handle);
3111769be974SMarcel Holtmann 
3112769be974SMarcel Holtmann 		if (conn->type == ACL_LINK) {
3113769be974SMarcel Holtmann 			conn->state = BT_CONFIG;
3114769be974SMarcel Holtmann 			hci_conn_hold(conn);
3115a9ea3ed9SSzymon Janc 
3116a9ea3ed9SSzymon Janc 			if (!conn->out && !hci_conn_ssp_enabled(conn) &&
3117a9ea3ed9SSzymon Janc 			    !hci_find_link_key(hdev, &ev->bdaddr))
3118a9ea3ed9SSzymon Janc 				conn->disc_timeout = HCI_PAIRING_TIMEOUT;
3119a9ea3ed9SSzymon Janc 			else
3120052b30b0SMarcel Holtmann 				conn->disc_timeout = HCI_DISCONN_TIMEOUT;
3121769be974SMarcel Holtmann 		} else
3122a9de9248SMarcel Holtmann 			conn->state = BT_CONNECTED;
3123a9de9248SMarcel Holtmann 
312423b9ceb7SMarcel Holtmann 		hci_debugfs_create_conn(conn);
31257d0db0a3SMarcel Holtmann 		hci_conn_add_sysfs(conn);
31267d0db0a3SMarcel Holtmann 
3127a9de9248SMarcel Holtmann 		if (test_bit(HCI_AUTH, &hdev->flags))
31284dae2798SJohan Hedberg 			set_bit(HCI_CONN_AUTH, &conn->flags);
3129a9de9248SMarcel Holtmann 
3130a9de9248SMarcel Holtmann 		if (test_bit(HCI_ENCRYPT, &hdev->flags))
31314dae2798SJohan Hedberg 			set_bit(HCI_CONN_ENCRYPT, &conn->flags);
3132a9de9248SMarcel Holtmann 
3133a9de9248SMarcel Holtmann 		/* Get remote features */
3134a9de9248SMarcel Holtmann 		if (conn->type == ACL_LINK) {
3135a9de9248SMarcel Holtmann 			struct hci_cp_read_remote_features cp;
3136a9de9248SMarcel Holtmann 			cp.handle = ev->handle;
3137769be974SMarcel Holtmann 			hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
3138769be974SMarcel Holtmann 				     sizeof(cp), &cp);
313922f433dcSJohan Hedberg 
314001b1cb87SJohan Hedberg 			hci_req_update_scan(hdev);
314145bb4bf0SMarcel Holtmann 		}
3142a9de9248SMarcel Holtmann 
3143a9de9248SMarcel Holtmann 		/* Set packet type for incoming connection */
3144d095c1ebSAndrei Emeltchenko 		if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
3145a9de9248SMarcel Holtmann 			struct hci_cp_change_conn_ptype cp;
3146a9de9248SMarcel Holtmann 			cp.handle = ev->handle;
3147a8746417SMarcel Holtmann 			cp.pkt_type = cpu_to_le16(conn->pkt_type);
314804124681SGustavo F. Padovan 			hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
314904124681SGustavo F. Padovan 				     &cp);
3150a9de9248SMarcel Holtmann 		}
315117d5c04cSJohan Hedberg 	} else {
3152a9de9248SMarcel Holtmann 		conn->state = BT_CLOSED;
315317d5c04cSJohan Hedberg 		if (conn->type == ACL_LINK)
315464c7b77cSMarcel Holtmann 			mgmt_connect_failed(hdev, &conn->dst, conn->type,
315548264f06SJohan Hedberg 					    conn->dst_type, ev->status);
315617d5c04cSJohan Hedberg 	}
315745bb4bf0SMarcel Holtmann 
3158e73439d8SMarcel Holtmann 	if (conn->type == ACL_LINK)
3159e73439d8SMarcel Holtmann 		hci_sco_setup(conn, ev->status);
316045bb4bf0SMarcel Holtmann 
3161769be974SMarcel Holtmann 	if (ev->status) {
3162539c496dSJohan Hedberg 		hci_connect_cfm(conn, ev->status);
3163a9de9248SMarcel Holtmann 		hci_conn_del(conn);
31641f8330eaSSathish Narsimman 	} else if (ev->link_type == SCO_LINK) {
31651f8330eaSSathish Narsimman 		switch (conn->setting & SCO_AIRMODE_MASK) {
31661f8330eaSSathish Narsimman 		case SCO_AIRMODE_CVSD:
31671f8330eaSSathish Narsimman 			if (hdev->notify)
31681f8330eaSSathish Narsimman 				hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD);
31691f8330eaSSathish Narsimman 			break;
31701f8330eaSSathish Narsimman 		}
31711f8330eaSSathish Narsimman 
3172539c496dSJohan Hedberg 		hci_connect_cfm(conn, ev->status);
31731f8330eaSSathish Narsimman 	}
3174a9de9248SMarcel Holtmann 
3175a9de9248SMarcel Holtmann unlock:
31761da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
3177a9de9248SMarcel Holtmann 
3178a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
31791da177e4SLinus Torvalds }
31801da177e4SLinus Torvalds 
318170c46425SJohan Hedberg static void hci_reject_conn(struct hci_dev *hdev, bdaddr_t *bdaddr)
318270c46425SJohan Hedberg {
318370c46425SJohan Hedberg 	struct hci_cp_reject_conn_req cp;
318470c46425SJohan Hedberg 
318570c46425SJohan Hedberg 	bacpy(&cp.bdaddr, bdaddr);
318670c46425SJohan Hedberg 	cp.reason = HCI_ERROR_REJ_BAD_ADDR;
318770c46425SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
318870c46425SJohan Hedberg }
318970c46425SJohan Hedberg 
31903e54c589SLuiz Augusto von Dentz static void hci_conn_request_evt(struct hci_dev *hdev, void *data,
31913e54c589SLuiz Augusto von Dentz 				 struct sk_buff *skb)
31921da177e4SLinus Torvalds {
31933e54c589SLuiz Augusto von Dentz 	struct hci_ev_conn_request *ev = data;
31941da177e4SLinus Torvalds 	int mask = hdev->link_mode;
319570c46425SJohan Hedberg 	struct inquiry_entry *ie;
319670c46425SJohan Hedberg 	struct hci_conn *conn;
319720714bfeSFrédéric Dalleau 	__u8 flags = 0;
31981da177e4SLinus Torvalds 
31993e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "bdaddr %pMR type 0x%x", &ev->bdaddr, ev->link_type);
32001da177e4SLinus Torvalds 
320120714bfeSFrédéric Dalleau 	mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
320220714bfeSFrédéric Dalleau 				      &flags);
32031da177e4SLinus Torvalds 
320470c46425SJohan Hedberg 	if (!(mask & HCI_LM_ACCEPT)) {
320570c46425SJohan Hedberg 		hci_reject_conn(hdev, &ev->bdaddr);
320670c46425SJohan Hedberg 		return;
320770c46425SJohan Hedberg 	}
320870c46425SJohan Hedberg 
32093d4f9c00SArchie Pusaka 	if (hci_bdaddr_list_lookup(&hdev->reject_list, &ev->bdaddr,
3210dcc36c16SJohan Hedberg 				   BDADDR_BREDR)) {
321170c46425SJohan Hedberg 		hci_reject_conn(hdev, &ev->bdaddr);
321270c46425SJohan Hedberg 		return;
321370c46425SJohan Hedberg 	}
321446c4c941SJohan Hedberg 
32153d4f9c00SArchie Pusaka 	/* Require HCI_CONNECTABLE or an accept list entry to accept the
32166a8fc95cSJohan Hedberg 	 * connection. These features are only touched through mgmt so
32176a8fc95cSJohan Hedberg 	 * only do the checks if HCI_MGMT is set.
32186a8fc95cSJohan Hedberg 	 */
3219d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT) &&
3220d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONNECTABLE) &&
32213d4f9c00SArchie Pusaka 	    !hci_bdaddr_list_lookup_with_flags(&hdev->accept_list, &ev->bdaddr,
3222a55bd29dSJohan Hedberg 					       BDADDR_BREDR)) {
3223a55bd29dSJohan Hedberg 		hci_reject_conn(hdev, &ev->bdaddr);
3224a55bd29dSJohan Hedberg 		return;
3225a55bd29dSJohan Hedberg 	}
322670c46425SJohan Hedberg 
32271da177e4SLinus Torvalds 	/* Connection accepted */
32281da177e4SLinus Torvalds 
32291da177e4SLinus Torvalds 	hci_dev_lock(hdev);
3230b6a0dc82SMarcel Holtmann 
3231cc11b9c1SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3232cc11b9c1SAndrei Emeltchenko 	if (ie)
3233c7bdd502SMarcel Holtmann 		memcpy(ie->data.dev_class, ev->dev_class, 3);
3234c7bdd502SMarcel Holtmann 
32358fc9ced3SGustavo Padovan 	conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
32368fc9ced3SGustavo Padovan 			&ev->bdaddr);
32371da177e4SLinus Torvalds 	if (!conn) {
3238a5c4e309SJohan Hedberg 		conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr,
3239a5c4e309SJohan Hedberg 				    HCI_ROLE_SLAVE);
3240cc11b9c1SAndrei Emeltchenko 		if (!conn) {
32412064ee33SMarcel Holtmann 			bt_dev_err(hdev, "no memory for new connection");
32421da177e4SLinus Torvalds 			hci_dev_unlock(hdev);
32431da177e4SLinus Torvalds 			return;
32441da177e4SLinus Torvalds 		}
32451da177e4SLinus Torvalds 	}
3246b6a0dc82SMarcel Holtmann 
32471da177e4SLinus Torvalds 	memcpy(conn->dev_class, ev->dev_class, 3);
3248b6a0dc82SMarcel Holtmann 
32491da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
32501da177e4SLinus Torvalds 
325120714bfeSFrédéric Dalleau 	if (ev->link_type == ACL_LINK ||
325220714bfeSFrédéric Dalleau 	    (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
3253b6a0dc82SMarcel Holtmann 		struct hci_cp_accept_conn_req cp;
325420714bfeSFrédéric Dalleau 		conn->state = BT_CONNECT;
3255b6a0dc82SMarcel Holtmann 
32561da177e4SLinus Torvalds 		bacpy(&cp.bdaddr, &ev->bdaddr);
32571da177e4SLinus Torvalds 
32581da177e4SLinus Torvalds 		if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
325974be523cSArchie Pusaka 			cp.role = 0x00; /* Become central */
32601da177e4SLinus Torvalds 		else
326174be523cSArchie Pusaka 			cp.role = 0x01; /* Remain peripheral */
32621da177e4SLinus Torvalds 
326370c46425SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp);
326420714bfeSFrédéric Dalleau 	} else if (!(flags & HCI_PROTO_DEFER)) {
3265b6a0dc82SMarcel Holtmann 		struct hci_cp_accept_sync_conn_req cp;
326620714bfeSFrédéric Dalleau 		conn->state = BT_CONNECT;
3267b6a0dc82SMarcel Holtmann 
3268b6a0dc82SMarcel Holtmann 		bacpy(&cp.bdaddr, &ev->bdaddr);
3269a8746417SMarcel Holtmann 		cp.pkt_type = cpu_to_le16(conn->pkt_type);
3270b6a0dc82SMarcel Holtmann 
3271dcf4adbfSJoe Perches 		cp.tx_bandwidth   = cpu_to_le32(0x00001f40);
3272dcf4adbfSJoe Perches 		cp.rx_bandwidth   = cpu_to_le32(0x00001f40);
3273dcf4adbfSJoe Perches 		cp.max_latency    = cpu_to_le16(0xffff);
3274b6a0dc82SMarcel Holtmann 		cp.content_format = cpu_to_le16(hdev->voice_setting);
3275b6a0dc82SMarcel Holtmann 		cp.retrans_effort = 0xff;
3276b6a0dc82SMarcel Holtmann 
327770c46425SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, sizeof(cp),
327870c46425SJohan Hedberg 			     &cp);
327920714bfeSFrédéric Dalleau 	} else {
328020714bfeSFrédéric Dalleau 		conn->state = BT_CONNECT2;
3281539c496dSJohan Hedberg 		hci_connect_cfm(conn, 0);
3282b6a0dc82SMarcel Holtmann 	}
32831da177e4SLinus Torvalds }
32841da177e4SLinus Torvalds 
3285f0d6a0eaSMikel Astiz static u8 hci_to_mgmt_reason(u8 err)
3286f0d6a0eaSMikel Astiz {
3287f0d6a0eaSMikel Astiz 	switch (err) {
3288f0d6a0eaSMikel Astiz 	case HCI_ERROR_CONNECTION_TIMEOUT:
3289f0d6a0eaSMikel Astiz 		return MGMT_DEV_DISCONN_TIMEOUT;
3290f0d6a0eaSMikel Astiz 	case HCI_ERROR_REMOTE_USER_TERM:
3291f0d6a0eaSMikel Astiz 	case HCI_ERROR_REMOTE_LOW_RESOURCES:
3292f0d6a0eaSMikel Astiz 	case HCI_ERROR_REMOTE_POWER_OFF:
3293f0d6a0eaSMikel Astiz 		return MGMT_DEV_DISCONN_REMOTE;
3294f0d6a0eaSMikel Astiz 	case HCI_ERROR_LOCAL_HOST_TERM:
3295f0d6a0eaSMikel Astiz 		return MGMT_DEV_DISCONN_LOCAL_HOST;
3296f0d6a0eaSMikel Astiz 	default:
3297f0d6a0eaSMikel Astiz 		return MGMT_DEV_DISCONN_UNKNOWN;
3298f0d6a0eaSMikel Astiz 	}
3299f0d6a0eaSMikel Astiz }
3300f0d6a0eaSMikel Astiz 
33013e54c589SLuiz Augusto von Dentz static void hci_disconn_complete_evt(struct hci_dev *hdev, void *data,
33023e54c589SLuiz Augusto von Dentz 				     struct sk_buff *skb)
33031da177e4SLinus Torvalds {
33043e54c589SLuiz Augusto von Dentz 	struct hci_ev_disconn_complete *ev = data;
3305160b9251SSzymon Janc 	u8 reason;
33069fcb18efSAndre Guedes 	struct hci_conn_params *params;
330704837f64SMarcel Holtmann 	struct hci_conn *conn;
330812d4a3b2SJohan Hedberg 	bool mgmt_connected;
33091da177e4SLinus Torvalds 
33103e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
33111da177e4SLinus Torvalds 
33121da177e4SLinus Torvalds 	hci_dev_lock(hdev);
33131da177e4SLinus Torvalds 
331404837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3315f7520543SJohan Hedberg 	if (!conn)
3316f7520543SJohan Hedberg 		goto unlock;
3317f7520543SJohan Hedberg 
3318f0d6a0eaSMikel Astiz 	if (ev->status) {
331988c3df13SJohan Hedberg 		mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
332088c3df13SJohan Hedberg 				       conn->dst_type, ev->status);
3321abf54a50SAndre Guedes 		goto unlock;
3322abf54a50SAndre Guedes 	}
3323f0d6a0eaSMikel Astiz 
33243846220bSAndre Guedes 	conn->state = BT_CLOSED;
33253846220bSAndre Guedes 
332612d4a3b2SJohan Hedberg 	mgmt_connected = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
3327160b9251SSzymon Janc 
3328160b9251SSzymon Janc 	if (test_bit(HCI_CONN_AUTH_FAILURE, &conn->flags))
3329160b9251SSzymon Janc 		reason = MGMT_DEV_DISCONN_AUTH_FAILURE;
3330160b9251SSzymon Janc 	else
3331160b9251SSzymon Janc 		reason = hci_to_mgmt_reason(ev->reason);
3332160b9251SSzymon Janc 
333312d4a3b2SJohan Hedberg 	mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type,
333412d4a3b2SJohan Hedberg 				reason, mgmt_connected);
3335f7520543SJohan Hedberg 
333622f433dcSJohan Hedberg 	if (conn->type == ACL_LINK) {
333722f433dcSJohan Hedberg 		if (test_bit(HCI_CONN_FLUSH_KEY, &conn->flags))
33386ec5bcadSVishal Agarwal 			hci_remove_link_key(hdev, &conn->dst);
33393846220bSAndre Guedes 
334001b1cb87SJohan Hedberg 		hci_req_update_scan(hdev);
334122f433dcSJohan Hedberg 	}
334222f433dcSJohan Hedberg 
33439fcb18efSAndre Guedes 	params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
33449fcb18efSAndre Guedes 	if (params) {
33459fcb18efSAndre Guedes 		switch (params->auto_connect) {
33469fcb18efSAndre Guedes 		case HCI_AUTO_CONN_LINK_LOSS:
33479fcb18efSAndre Guedes 			if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT)
33489fcb18efSAndre Guedes 				break;
334919186c7bSGustavo A. R. Silva 			fallthrough;
33509fcb18efSAndre Guedes 
33514b9e7e75SMarcel Holtmann 		case HCI_AUTO_CONN_DIRECT:
33529fcb18efSAndre Guedes 		case HCI_AUTO_CONN_ALWAYS:
3353418025d1SJohan Hedberg 			list_del_init(&params->action);
3354418025d1SJohan Hedberg 			list_add(&params->action, &hdev->pend_le_conns);
33555bee2fd6SLuiz Augusto von Dentz 			hci_update_passive_scan(hdev);
33569fcb18efSAndre Guedes 			break;
33579fcb18efSAndre Guedes 
33589fcb18efSAndre Guedes 		default:
33599fcb18efSAndre Guedes 			break;
33609fcb18efSAndre Guedes 		}
33619fcb18efSAndre Guedes 	}
33629fcb18efSAndre Guedes 
33633a6d576bSJohan Hedberg 	hci_disconn_cfm(conn, ev->reason);
33642210246cSJohan Hedberg 
33652210246cSJohan Hedberg 	/* Re-enable advertising if necessary, since it might
33662210246cSJohan Hedberg 	 * have been disabled by the connection. From the
33672210246cSJohan Hedberg 	 * HCI_LE_Set_Advertise_Enable command description in
33682210246cSJohan Hedberg 	 * the core specification (v4.0):
33692210246cSJohan Hedberg 	 * "The Controller shall continue advertising until the Host
33702210246cSJohan Hedberg 	 * issues an LE_Set_Advertise_Enable command with
33712210246cSJohan Hedberg 	 * Advertising_Enable set to 0x00 (Advertising is disabled)
33722210246cSJohan Hedberg 	 * or until a connection is created or until the Advertising
33732210246cSJohan Hedberg 	 * is timed out due to Directed Advertising."
33742210246cSJohan Hedberg 	 */
33751eeaa1aeSLuiz Augusto von Dentz 	if (conn->type == LE_LINK && conn->role == HCI_ROLE_SLAVE) {
33767087c4f6SLuiz Augusto von Dentz 		hdev->cur_adv_instance = conn->adv_instance;
3377abfeea47SLuiz Augusto von Dentz 		hci_enable_advertising(hdev);
33787087c4f6SLuiz Augusto von Dentz 	}
33797087c4f6SLuiz Augusto von Dentz 
33807087c4f6SLuiz Augusto von Dentz 	hci_conn_del(conn);
33811da177e4SLinus Torvalds 
3382f7520543SJohan Hedberg unlock:
33831da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
33841da177e4SLinus Torvalds }
33851da177e4SLinus Torvalds 
33863e54c589SLuiz Augusto von Dentz static void hci_auth_complete_evt(struct hci_dev *hdev, void *data,
33873e54c589SLuiz Augusto von Dentz 				  struct sk_buff *skb)
3388a9de9248SMarcel Holtmann {
33893e54c589SLuiz Augusto von Dentz 	struct hci_ev_auth_complete *ev = data;
3390a9de9248SMarcel Holtmann 	struct hci_conn *conn;
3391a9de9248SMarcel Holtmann 
33923e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
3393a9de9248SMarcel Holtmann 
3394a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
3395a9de9248SMarcel Holtmann 
3396a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3397d7556e20SWaldemar Rymarkiewicz 	if (!conn)
3398d7556e20SWaldemar Rymarkiewicz 		goto unlock;
3399d7556e20SWaldemar Rymarkiewicz 
3400765c2a96SJohan Hedberg 	if (!ev->status) {
3401160b9251SSzymon Janc 		clear_bit(HCI_CONN_AUTH_FAILURE, &conn->flags);
3402160b9251SSzymon Janc 
3403aa64a8b5SJohan Hedberg 		if (!hci_conn_ssp_enabled(conn) &&
340451a8efd7SJohan Hedberg 		    test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
34052064ee33SMarcel Holtmann 			bt_dev_info(hdev, "re-auth of legacy device is not possible.");
340619f8def0SWaldemar Rymarkiewicz 		} else {
34074dae2798SJohan Hedberg 			set_bit(HCI_CONN_AUTH, &conn->flags);
3408765c2a96SJohan Hedberg 			conn->sec_level = conn->pending_sec_level;
340919f8def0SWaldemar Rymarkiewicz 		}
34102a611692SJohan Hedberg 	} else {
3411160b9251SSzymon Janc 		if (ev->status == HCI_ERROR_PIN_OR_KEY_MISSING)
3412160b9251SSzymon Janc 			set_bit(HCI_CONN_AUTH_FAILURE, &conn->flags);
3413160b9251SSzymon Janc 
3414e1e930f5SJohan Hedberg 		mgmt_auth_failed(conn, ev->status);
34152a611692SJohan Hedberg 	}
3416a9de9248SMarcel Holtmann 
341751a8efd7SJohan Hedberg 	clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
341851a8efd7SJohan Hedberg 	clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
3419a9de9248SMarcel Holtmann 
3420f8558555SMarcel Holtmann 	if (conn->state == BT_CONFIG) {
3421aa64a8b5SJohan Hedberg 		if (!ev->status && hci_conn_ssp_enabled(conn)) {
3422f8558555SMarcel Holtmann 			struct hci_cp_set_conn_encrypt cp;
3423f8558555SMarcel Holtmann 			cp.handle  = ev->handle;
3424f8558555SMarcel Holtmann 			cp.encrypt = 0x01;
3425d7556e20SWaldemar Rymarkiewicz 			hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
3426d7556e20SWaldemar Rymarkiewicz 				     &cp);
3427f8558555SMarcel Holtmann 		} else {
3428f8558555SMarcel Holtmann 			conn->state = BT_CONNECTED;
3429539c496dSJohan Hedberg 			hci_connect_cfm(conn, ev->status);
343076a68ba0SDavid Herrmann 			hci_conn_drop(conn);
3431f8558555SMarcel Holtmann 		}
3432052b30b0SMarcel Holtmann 	} else {
3433a9de9248SMarcel Holtmann 		hci_auth_cfm(conn, ev->status);
3434a9de9248SMarcel Holtmann 
3435052b30b0SMarcel Holtmann 		hci_conn_hold(conn);
3436052b30b0SMarcel Holtmann 		conn->disc_timeout = HCI_DISCONN_TIMEOUT;
343776a68ba0SDavid Herrmann 		hci_conn_drop(conn);
3438052b30b0SMarcel Holtmann 	}
3439052b30b0SMarcel Holtmann 
344051a8efd7SJohan Hedberg 	if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
3441a9de9248SMarcel Holtmann 		if (!ev->status) {
3442a9de9248SMarcel Holtmann 			struct hci_cp_set_conn_encrypt cp;
3443f8558555SMarcel Holtmann 			cp.handle  = ev->handle;
3444f8558555SMarcel Holtmann 			cp.encrypt = 0x01;
3445d7556e20SWaldemar Rymarkiewicz 			hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
3446d7556e20SWaldemar Rymarkiewicz 				     &cp);
3447a9de9248SMarcel Holtmann 		} else {
344851a8efd7SJohan Hedberg 			clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
34493ca44c16SLuiz Augusto von Dentz 			hci_encrypt_cfm(conn, ev->status);
3450a9de9248SMarcel Holtmann 		}
3451a9de9248SMarcel Holtmann 	}
3452a9de9248SMarcel Holtmann 
3453d7556e20SWaldemar Rymarkiewicz unlock:
3454a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
3455a9de9248SMarcel Holtmann }
3456a9de9248SMarcel Holtmann 
34573e54c589SLuiz Augusto von Dentz static void hci_remote_name_evt(struct hci_dev *hdev, void *data,
34583e54c589SLuiz Augusto von Dentz 				struct sk_buff *skb)
3459a9de9248SMarcel Holtmann {
34603e54c589SLuiz Augusto von Dentz 	struct hci_ev_remote_name *ev = data;
3461127178d2SJohan Hedberg 	struct hci_conn *conn;
3462127178d2SJohan Hedberg 
34633e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
3464a9de9248SMarcel Holtmann 
3465a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
3466127178d2SJohan Hedberg 
3467127178d2SJohan Hedberg 	hci_dev_lock(hdev);
3468127178d2SJohan Hedberg 
3469127178d2SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3470b644ba33SJohan Hedberg 
3471d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
3472b644ba33SJohan Hedberg 		goto check_auth;
3473b644ba33SJohan Hedberg 
3474b644ba33SJohan Hedberg 	if (ev->status == 0)
3475b644ba33SJohan Hedberg 		hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
3476b644ba33SJohan Hedberg 				       strnlen(ev->name, HCI_MAX_NAME_LENGTH));
3477b644ba33SJohan Hedberg 	else
3478b644ba33SJohan Hedberg 		hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
3479b644ba33SJohan Hedberg 
3480b644ba33SJohan Hedberg check_auth:
348179c6c70cSJohan Hedberg 	if (!conn)
348279c6c70cSJohan Hedberg 		goto unlock;
348379c6c70cSJohan Hedberg 
348479c6c70cSJohan Hedberg 	if (!hci_outgoing_auth_needed(hdev, conn))
348579c6c70cSJohan Hedberg 		goto unlock;
348679c6c70cSJohan Hedberg 
348751a8efd7SJohan Hedberg 	if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
3488127178d2SJohan Hedberg 		struct hci_cp_auth_requested cp;
3489977f8fceSJohan Hedberg 
3490977f8fceSJohan Hedberg 		set_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags);
3491977f8fceSJohan Hedberg 
3492127178d2SJohan Hedberg 		cp.handle = __cpu_to_le16(conn->handle);
3493127178d2SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
3494127178d2SJohan Hedberg 	}
3495127178d2SJohan Hedberg 
349679c6c70cSJohan Hedberg unlock:
3497127178d2SJohan Hedberg 	hci_dev_unlock(hdev);
3498a9de9248SMarcel Holtmann }
3499a9de9248SMarcel Holtmann 
3500821f3766SJohan Hedberg static void read_enc_key_size_complete(struct hci_dev *hdev, u8 status,
3501821f3766SJohan Hedberg 				       u16 opcode, struct sk_buff *skb)
3502821f3766SJohan Hedberg {
3503821f3766SJohan Hedberg 	const struct hci_rp_read_enc_key_size *rp;
3504821f3766SJohan Hedberg 	struct hci_conn *conn;
3505821f3766SJohan Hedberg 	u16 handle;
3506821f3766SJohan Hedberg 
3507821f3766SJohan Hedberg 	BT_DBG("%s status 0x%02x", hdev->name, status);
3508821f3766SJohan Hedberg 
3509821f3766SJohan Hedberg 	if (!skb || skb->len < sizeof(*rp)) {
35102064ee33SMarcel Holtmann 		bt_dev_err(hdev, "invalid read key size response");
3511821f3766SJohan Hedberg 		return;
3512821f3766SJohan Hedberg 	}
3513821f3766SJohan Hedberg 
3514821f3766SJohan Hedberg 	rp = (void *)skb->data;
3515821f3766SJohan Hedberg 	handle = le16_to_cpu(rp->handle);
3516821f3766SJohan Hedberg 
3517821f3766SJohan Hedberg 	hci_dev_lock(hdev);
3518821f3766SJohan Hedberg 
3519821f3766SJohan Hedberg 	conn = hci_conn_hash_lookup_handle(hdev, handle);
3520821f3766SJohan Hedberg 	if (!conn)
3521821f3766SJohan Hedberg 		goto unlock;
3522821f3766SJohan Hedberg 
352332b50729SAlain Michaud 	/* While unexpected, the read_enc_key_size command may fail. The most
352432b50729SAlain Michaud 	 * secure approach is to then assume the key size is 0 to force a
352532b50729SAlain Michaud 	 * disconnection.
3526821f3766SJohan Hedberg 	 */
3527821f3766SJohan Hedberg 	if (rp->status) {
35282064ee33SMarcel Holtmann 		bt_dev_err(hdev, "failed to read key size for handle %u",
3529821f3766SJohan Hedberg 			   handle);
353032b50729SAlain Michaud 		conn->enc_key_size = 0;
3531821f3766SJohan Hedberg 	} else {
3532821f3766SJohan Hedberg 		conn->enc_key_size = rp->key_size;
3533821f3766SJohan Hedberg 	}
3534821f3766SJohan Hedberg 
35353ca44c16SLuiz Augusto von Dentz 	hci_encrypt_cfm(conn, 0);
3536821f3766SJohan Hedberg 
3537821f3766SJohan Hedberg unlock:
3538821f3766SJohan Hedberg 	hci_dev_unlock(hdev);
3539821f3766SJohan Hedberg }
3540821f3766SJohan Hedberg 
35413e54c589SLuiz Augusto von Dentz static void hci_encrypt_change_evt(struct hci_dev *hdev, void *data,
35423e54c589SLuiz Augusto von Dentz 				   struct sk_buff *skb)
3543a9de9248SMarcel Holtmann {
35443e54c589SLuiz Augusto von Dentz 	struct hci_ev_encrypt_change *ev = data;
3545a9de9248SMarcel Holtmann 	struct hci_conn *conn;
3546a9de9248SMarcel Holtmann 
35473e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
3548a9de9248SMarcel Holtmann 
3549a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
3550a9de9248SMarcel Holtmann 
3551a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3552dc8357ccSMarcel Holtmann 	if (!conn)
3553dc8357ccSMarcel Holtmann 		goto unlock;
3554dc8357ccSMarcel Holtmann 
3555a9de9248SMarcel Holtmann 	if (!ev->status) {
3556ae293196SMarcel Holtmann 		if (ev->encrypt) {
3557ae293196SMarcel Holtmann 			/* Encryption implies authentication */
35584dae2798SJohan Hedberg 			set_bit(HCI_CONN_AUTH, &conn->flags);
35594dae2798SJohan Hedberg 			set_bit(HCI_CONN_ENCRYPT, &conn->flags);
3560da85e5e5SVinicius Costa Gomes 			conn->sec_level = conn->pending_sec_level;
3561abf76badSMarcel Holtmann 
3562914a6ffeSMarcel Holtmann 			/* P-256 authentication key implies FIPS */
3563914a6ffeSMarcel Holtmann 			if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256)
35644dae2798SJohan Hedberg 				set_bit(HCI_CONN_FIPS, &conn->flags);
3565914a6ffeSMarcel Holtmann 
3566abf76badSMarcel Holtmann 			if ((conn->type == ACL_LINK && ev->encrypt == 0x02) ||
3567abf76badSMarcel Holtmann 			    conn->type == LE_LINK)
3568abf76badSMarcel Holtmann 				set_bit(HCI_CONN_AES_CCM, &conn->flags);
3569abf76badSMarcel Holtmann 		} else {
35704dae2798SJohan Hedberg 			clear_bit(HCI_CONN_ENCRYPT, &conn->flags);
3571abf76badSMarcel Holtmann 			clear_bit(HCI_CONN_AES_CCM, &conn->flags);
3572abf76badSMarcel Holtmann 		}
3573a9de9248SMarcel Holtmann 	}
3574a9de9248SMarcel Holtmann 
35757ed3fa20SJohan Hedberg 	/* We should disregard the current RPA and generate a new one
35767ed3fa20SJohan Hedberg 	 * whenever the encryption procedure fails.
35777ed3fa20SJohan Hedberg 	 */
3578a73c046aSJaganath Kanakkassery 	if (ev->status && conn->type == LE_LINK) {
3579a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
3580a73c046aSJaganath Kanakkassery 		hci_adv_instances_set_rpa_expired(hdev, true);
3581a73c046aSJaganath Kanakkassery 	}
35827ed3fa20SJohan Hedberg 
358351a8efd7SJohan Hedberg 	clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3584a9de9248SMarcel Holtmann 
35858746f135SLuiz Augusto von Dentz 	/* Check link security requirements are met */
35868746f135SLuiz Augusto von Dentz 	if (!hci_conn_check_link_mode(conn))
35878746f135SLuiz Augusto von Dentz 		ev->status = HCI_ERROR_AUTH_FAILURE;
35888746f135SLuiz Augusto von Dentz 
3589a7d7723aSGustavo Padovan 	if (ev->status && conn->state == BT_CONNECTED) {
3590160b9251SSzymon Janc 		if (ev->status == HCI_ERROR_PIN_OR_KEY_MISSING)
3591160b9251SSzymon Janc 			set_bit(HCI_CONN_AUTH_FAILURE, &conn->flags);
3592160b9251SSzymon Janc 
35938746f135SLuiz Augusto von Dentz 		/* Notify upper layers so they can cleanup before
35948746f135SLuiz Augusto von Dentz 		 * disconnecting.
359540b552aaSMarcel Holtmann 		 */
35968746f135SLuiz Augusto von Dentz 		hci_encrypt_cfm(conn, ev->status);
35978746f135SLuiz Augusto von Dentz 		hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
359840b552aaSMarcel Holtmann 		hci_conn_drop(conn);
359940b552aaSMarcel Holtmann 		goto unlock;
360040b552aaSMarcel Holtmann 	}
360140b552aaSMarcel Holtmann 
3602821f3766SJohan Hedberg 	/* Try reading the encryption key size for encrypted ACL links */
3603821f3766SJohan Hedberg 	if (!ev->status && ev->encrypt && conn->type == ACL_LINK) {
3604821f3766SJohan Hedberg 		struct hci_cp_read_enc_key_size cp;
3605821f3766SJohan Hedberg 		struct hci_request req;
3606821f3766SJohan Hedberg 
3607821f3766SJohan Hedberg 		/* Only send HCI_Read_Encryption_Key_Size if the
3608821f3766SJohan Hedberg 		 * controller really supports it. If it doesn't, assume
3609821f3766SJohan Hedberg 		 * the default size (16).
3610821f3766SJohan Hedberg 		 */
3611821f3766SJohan Hedberg 		if (!(hdev->commands[20] & 0x10)) {
3612821f3766SJohan Hedberg 			conn->enc_key_size = HCI_LINK_KEY_SIZE;
3613821f3766SJohan Hedberg 			goto notify;
3614821f3766SJohan Hedberg 		}
3615821f3766SJohan Hedberg 
3616821f3766SJohan Hedberg 		hci_req_init(&req, hdev);
3617821f3766SJohan Hedberg 
3618821f3766SJohan Hedberg 		cp.handle = cpu_to_le16(conn->handle);
3619821f3766SJohan Hedberg 		hci_req_add(&req, HCI_OP_READ_ENC_KEY_SIZE, sizeof(cp), &cp);
3620821f3766SJohan Hedberg 
3621821f3766SJohan Hedberg 		if (hci_req_run_skb(&req, read_enc_key_size_complete)) {
36222064ee33SMarcel Holtmann 			bt_dev_err(hdev, "sending read key size failed");
3623821f3766SJohan Hedberg 			conn->enc_key_size = HCI_LINK_KEY_SIZE;
3624821f3766SJohan Hedberg 			goto notify;
3625821f3766SJohan Hedberg 		}
3626821f3766SJohan Hedberg 
3627821f3766SJohan Hedberg 		goto unlock;
3628821f3766SJohan Hedberg 	}
3629821f3766SJohan Hedberg 
3630302975cbSSpoorthi Ravishankar Koppad 	/* Set the default Authenticated Payload Timeout after
3631302975cbSSpoorthi Ravishankar Koppad 	 * an LE Link is established. As per Core Spec v5.0, Vol 2, Part B
3632302975cbSSpoorthi Ravishankar Koppad 	 * Section 3.3, the HCI command WRITE_AUTH_PAYLOAD_TIMEOUT should be
3633302975cbSSpoorthi Ravishankar Koppad 	 * sent when the link is active and Encryption is enabled, the conn
3634302975cbSSpoorthi Ravishankar Koppad 	 * type can be either LE or ACL and controller must support LMP Ping.
3635302975cbSSpoorthi Ravishankar Koppad 	 * Ensure for AES-CCM encryption as well.
3636302975cbSSpoorthi Ravishankar Koppad 	 */
3637302975cbSSpoorthi Ravishankar Koppad 	if (test_bit(HCI_CONN_ENCRYPT, &conn->flags) &&
3638302975cbSSpoorthi Ravishankar Koppad 	    test_bit(HCI_CONN_AES_CCM, &conn->flags) &&
3639302975cbSSpoorthi Ravishankar Koppad 	    ((conn->type == ACL_LINK && lmp_ping_capable(hdev)) ||
3640302975cbSSpoorthi Ravishankar Koppad 	     (conn->type == LE_LINK && (hdev->le_features[0] & HCI_LE_PING)))) {
3641302975cbSSpoorthi Ravishankar Koppad 		struct hci_cp_write_auth_payload_to cp;
3642302975cbSSpoorthi Ravishankar Koppad 
3643302975cbSSpoorthi Ravishankar Koppad 		cp.handle = cpu_to_le16(conn->handle);
3644302975cbSSpoorthi Ravishankar Koppad 		cp.timeout = cpu_to_le16(hdev->auth_payload_timeout);
3645302975cbSSpoorthi Ravishankar Koppad 		hci_send_cmd(conn->hdev, HCI_OP_WRITE_AUTH_PAYLOAD_TO,
3646302975cbSSpoorthi Ravishankar Koppad 			     sizeof(cp), &cp);
3647302975cbSSpoorthi Ravishankar Koppad 	}
3648302975cbSSpoorthi Ravishankar Koppad 
3649821f3766SJohan Hedberg notify:
36503ca44c16SLuiz Augusto von Dentz 	hci_encrypt_cfm(conn, ev->status);
3651a9de9248SMarcel Holtmann 
3652a7d7723aSGustavo Padovan unlock:
3653a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
3654a9de9248SMarcel Holtmann }
3655a9de9248SMarcel Holtmann 
36563e54c589SLuiz Augusto von Dentz static void hci_change_link_key_complete_evt(struct hci_dev *hdev, void *data,
3657807deac2SGustavo Padovan 					     struct sk_buff *skb)
3658a9de9248SMarcel Holtmann {
36593e54c589SLuiz Augusto von Dentz 	struct hci_ev_change_link_key_complete *ev = data;
3660a9de9248SMarcel Holtmann 	struct hci_conn *conn;
3661a9de9248SMarcel Holtmann 
36623e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
3663a9de9248SMarcel Holtmann 
3664a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
3665a9de9248SMarcel Holtmann 
3666a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3667a9de9248SMarcel Holtmann 	if (conn) {
3668a9de9248SMarcel Holtmann 		if (!ev->status)
36694dae2798SJohan Hedberg 			set_bit(HCI_CONN_SECURE, &conn->flags);
3670a9de9248SMarcel Holtmann 
367151a8efd7SJohan Hedberg 		clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
3672a9de9248SMarcel Holtmann 
3673a9de9248SMarcel Holtmann 		hci_key_change_cfm(conn, ev->status);
3674a9de9248SMarcel Holtmann 	}
3675a9de9248SMarcel Holtmann 
3676a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
3677a9de9248SMarcel Holtmann }
3678a9de9248SMarcel Holtmann 
36793e54c589SLuiz Augusto von Dentz static void hci_remote_features_evt(struct hci_dev *hdev, void *data,
3680807deac2SGustavo Padovan 				    struct sk_buff *skb)
3681a9de9248SMarcel Holtmann {
36823e54c589SLuiz Augusto von Dentz 	struct hci_ev_remote_features *ev = data;
3683a9de9248SMarcel Holtmann 	struct hci_conn *conn;
3684a9de9248SMarcel Holtmann 
36853e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
3686a9de9248SMarcel Holtmann 
3687a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
3688a9de9248SMarcel Holtmann 
3689a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3690ccd556feSJohan Hedberg 	if (!conn)
3691ccd556feSJohan Hedberg 		goto unlock;
3692ccd556feSJohan Hedberg 
3693769be974SMarcel Holtmann 	if (!ev->status)
3694cad718edSJohan Hedberg 		memcpy(conn->features[0], ev->features, 8);
3695a9de9248SMarcel Holtmann 
3696ccd556feSJohan Hedberg 	if (conn->state != BT_CONFIG)
3697ccd556feSJohan Hedberg 		goto unlock;
3698ccd556feSJohan Hedberg 
3699ac363cf9SSzymon Janc 	if (!ev->status && lmp_ext_feat_capable(hdev) &&
3700ac363cf9SSzymon Janc 	    lmp_ext_feat_capable(conn)) {
3701769be974SMarcel Holtmann 		struct hci_cp_read_remote_ext_features cp;
3702769be974SMarcel Holtmann 		cp.handle = ev->handle;
3703769be974SMarcel Holtmann 		cp.page = 0x01;
3704ccd556feSJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
3705769be974SMarcel Holtmann 			     sizeof(cp), &cp);
3706392599b9SJohan Hedberg 		goto unlock;
3707392599b9SJohan Hedberg 	}
3708392599b9SJohan Hedberg 
3709671267bfSJohan Hedberg 	if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
3710127178d2SJohan Hedberg 		struct hci_cp_remote_name_req cp;
3711127178d2SJohan Hedberg 		memset(&cp, 0, sizeof(cp));
3712127178d2SJohan Hedberg 		bacpy(&cp.bdaddr, &conn->dst);
3713127178d2SJohan Hedberg 		cp.pscan_rep_mode = 0x02;
3714127178d2SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
3715b644ba33SJohan Hedberg 	} else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
37161c6ed31bSYu Liu 		mgmt_device_connected(hdev, conn, NULL, 0);
3717392599b9SJohan Hedberg 
3718127178d2SJohan Hedberg 	if (!hci_outgoing_auth_needed(hdev, conn)) {
3719769be974SMarcel Holtmann 		conn->state = BT_CONNECTED;
3720539c496dSJohan Hedberg 		hci_connect_cfm(conn, ev->status);
372176a68ba0SDavid Herrmann 		hci_conn_drop(conn);
3722769be974SMarcel Holtmann 	}
3723769be974SMarcel Holtmann 
3724ccd556feSJohan Hedberg unlock:
3725a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
3726a9de9248SMarcel Holtmann }
3727a9de9248SMarcel Holtmann 
3728ecb71f25SKiran K static inline void handle_cmd_cnt_and_timer(struct hci_dev *hdev, u8 ncmd)
3729de75cd0dSManish Mandlik {
3730de75cd0dSManish Mandlik 	cancel_delayed_work(&hdev->cmd_timer);
3731de75cd0dSManish Mandlik 
3732de75cd0dSManish Mandlik 	if (!test_bit(HCI_RESET, &hdev->flags)) {
3733de75cd0dSManish Mandlik 		if (ncmd) {
3734de75cd0dSManish Mandlik 			cancel_delayed_work(&hdev->ncmd_timer);
3735de75cd0dSManish Mandlik 			atomic_set(&hdev->cmd_cnt, 1);
3736de75cd0dSManish Mandlik 		} else {
3737de75cd0dSManish Mandlik 			schedule_delayed_work(&hdev->ncmd_timer,
3738de75cd0dSManish Mandlik 					      HCI_NCMD_TIMEOUT);
3739de75cd0dSManish Mandlik 		}
3740de75cd0dSManish Mandlik 	}
3741de75cd0dSManish Mandlik }
3742de75cd0dSManish Mandlik 
3743c8992cffSLuiz Augusto von Dentz #define HCI_CC_VL(_op, _func, _min, _max) \
3744c8992cffSLuiz Augusto von Dentz { \
3745c8992cffSLuiz Augusto von Dentz 	.op = _op, \
3746c8992cffSLuiz Augusto von Dentz 	.func = _func, \
3747c8992cffSLuiz Augusto von Dentz 	.min_len = _min, \
3748c8992cffSLuiz Augusto von Dentz 	.max_len = _max, \
3749c8992cffSLuiz Augusto von Dentz }
3750c8992cffSLuiz Augusto von Dentz 
3751c8992cffSLuiz Augusto von Dentz #define HCI_CC(_op, _func, _len) \
3752c8992cffSLuiz Augusto von Dentz 	HCI_CC_VL(_op, _func, _len, _len)
3753c8992cffSLuiz Augusto von Dentz 
3754c8992cffSLuiz Augusto von Dentz #define HCI_CC_STATUS(_op, _func) \
3755c8992cffSLuiz Augusto von Dentz 	HCI_CC(_op, _func, sizeof(struct hci_ev_status))
3756c8992cffSLuiz Augusto von Dentz 
3757c8992cffSLuiz Augusto von Dentz static const struct hci_cc {
3758c8992cffSLuiz Augusto von Dentz 	u16  op;
3759c8992cffSLuiz Augusto von Dentz 	u8 (*func)(struct hci_dev *hdev, void *data, struct sk_buff *skb);
3760c8992cffSLuiz Augusto von Dentz 	u16  min_len;
3761c8992cffSLuiz Augusto von Dentz 	u16  max_len;
3762c8992cffSLuiz Augusto von Dentz } hci_cc_table[] = {
3763c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_INQUIRY_CANCEL, hci_cc_inquiry_cancel),
3764c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_PERIODIC_INQ, hci_cc_periodic_inq),
3765c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_EXIT_PERIODIC_INQ, hci_cc_exit_periodic_inq),
3766c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_REMOTE_NAME_REQ_CANCEL,
3767c8992cffSLuiz Augusto von Dentz 		      hci_cc_remote_name_req_cancel),
3768c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_ROLE_DISCOVERY, hci_cc_role_discovery,
3769c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_role_discovery)),
3770c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LINK_POLICY, hci_cc_read_link_policy,
3771c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_link_policy)),
3772c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_WRITE_LINK_POLICY, hci_cc_write_link_policy,
3773c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_write_link_policy)),
3774c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_DEF_LINK_POLICY, hci_cc_read_def_link_policy,
3775c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_def_link_policy)),
3776c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_DEF_LINK_POLICY,
3777c8992cffSLuiz Augusto von Dentz 		      hci_cc_write_def_link_policy),
3778c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_RESET, hci_cc_reset),
3779c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_STORED_LINK_KEY, hci_cc_read_stored_link_key,
3780c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_stored_link_key)),
3781c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_DELETE_STORED_LINK_KEY, hci_cc_delete_stored_link_key,
3782c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_delete_stored_link_key)),
3783c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_LOCAL_NAME, hci_cc_write_local_name),
3784c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_NAME, hci_cc_read_local_name,
3785c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_name)),
3786c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_AUTH_ENABLE, hci_cc_write_auth_enable),
3787c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_ENCRYPT_MODE, hci_cc_write_encrypt_mode),
3788c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_SCAN_ENABLE, hci_cc_write_scan_enable),
3789c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_SET_EVENT_FLT, hci_cc_set_event_filter),
3790c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_CLASS_OF_DEV, hci_cc_read_class_of_dev,
3791c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_class_of_dev)),
3792c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_CLASS_OF_DEV, hci_cc_write_class_of_dev),
3793c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_VOICE_SETTING, hci_cc_read_voice_setting,
3794c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_voice_setting)),
3795c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_VOICE_SETTING, hci_cc_write_voice_setting),
3796c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_NUM_SUPPORTED_IAC, hci_cc_read_num_supported_iac,
3797c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_num_supported_iac)),
3798c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_SSP_MODE, hci_cc_write_ssp_mode),
3799c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_SC_SUPPORT, hci_cc_write_sc_support),
3800c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_AUTH_PAYLOAD_TO, hci_cc_read_auth_payload_timeout,
3801c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_auth_payload_to)),
3802c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_WRITE_AUTH_PAYLOAD_TO, hci_cc_write_auth_payload_timeout,
3803c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_write_auth_payload_to)),
3804c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_VERSION, hci_cc_read_local_version,
3805c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_version)),
3806c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_COMMANDS, hci_cc_read_local_commands,
3807c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_commands)),
3808c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_FEATURES, hci_cc_read_local_features,
3809c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_features)),
3810c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_EXT_FEATURES, hci_cc_read_local_ext_features,
3811c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_ext_features)),
3812c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_BUFFER_SIZE, hci_cc_read_buffer_size,
3813c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_buffer_size)),
3814c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_BD_ADDR, hci_cc_read_bd_addr,
3815c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_bd_addr)),
3816c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_PAIRING_OPTS, hci_cc_read_local_pairing_opts,
3817c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_pairing_opts)),
3818c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_PAGE_SCAN_ACTIVITY, hci_cc_read_page_scan_activity,
3819c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_page_scan_activity)),
3820c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_PAGE_SCAN_ACTIVITY,
3821c8992cffSLuiz Augusto von Dentz 		      hci_cc_write_page_scan_activity),
3822c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_PAGE_SCAN_TYPE, hci_cc_read_page_scan_type,
3823c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_page_scan_type)),
3824c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_PAGE_SCAN_TYPE, hci_cc_write_page_scan_type),
3825c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_DATA_BLOCK_SIZE, hci_cc_read_data_block_size,
3826c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_data_block_size)),
3827c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_FLOW_CONTROL_MODE, hci_cc_read_flow_control_mode,
3828c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_flow_control_mode)),
3829c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_AMP_INFO, hci_cc_read_local_amp_info,
3830c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_amp_info)),
3831c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_CLOCK, hci_cc_read_clock,
3832c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_clock)),
3833c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_INQ_RSP_TX_POWER, hci_cc_read_inq_rsp_tx_power,
3834c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_inq_rsp_tx_power)),
3835c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_DEF_ERR_DATA_REPORTING,
3836c8992cffSLuiz Augusto von Dentz 	       hci_cc_read_def_err_data_reporting,
3837c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_def_err_data_reporting)),
3838c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_DEF_ERR_DATA_REPORTING,
3839c8992cffSLuiz Augusto von Dentz 		      hci_cc_write_def_err_data_reporting),
3840c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_PIN_CODE_REPLY, hci_cc_pin_code_reply,
3841c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_pin_code_reply)),
3842c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_PIN_CODE_NEG_REPLY, hci_cc_pin_code_neg_reply,
3843c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_pin_code_neg_reply)),
3844c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_OOB_DATA, hci_cc_read_local_oob_data,
3845c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_oob_data)),
3846c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_OOB_EXT_DATA, hci_cc_read_local_oob_ext_data,
3847c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_oob_ext_data)),
3848c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_BUFFER_SIZE, hci_cc_le_read_buffer_size,
3849c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_buffer_size)),
3850c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_LOCAL_FEATURES, hci_cc_le_read_local_features,
3851c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_local_features)),
3852c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_ADV_TX_POWER, hci_cc_le_read_adv_tx_power,
3853c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_adv_tx_power)),
3854c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_USER_CONFIRM_REPLY, hci_cc_user_confirm_reply,
3855c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_user_confirm_reply)),
3856c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_USER_CONFIRM_NEG_REPLY, hci_cc_user_confirm_neg_reply,
3857c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_user_confirm_reply)),
3858c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_USER_PASSKEY_REPLY, hci_cc_user_passkey_reply,
3859c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_user_confirm_reply)),
3860c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_USER_PASSKEY_NEG_REPLY, hci_cc_user_passkey_neg_reply,
3861c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_user_confirm_reply)),
3862c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_RANDOM_ADDR, hci_cc_le_set_random_addr),
3863c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_ADV_ENABLE, hci_cc_le_set_adv_enable),
3864c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_SCAN_PARAM, hci_cc_le_set_scan_param),
3865c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_SCAN_ENABLE, hci_cc_le_set_scan_enable),
3866c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_ACCEPT_LIST_SIZE,
3867c8992cffSLuiz Augusto von Dentz 	       hci_cc_le_read_accept_list_size,
3868c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_accept_list_size)),
3869c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_CLEAR_ACCEPT_LIST, hci_cc_le_clear_accept_list),
3870c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_ADD_TO_ACCEPT_LIST,
3871c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_add_to_accept_list),
3872c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_DEL_FROM_ACCEPT_LIST,
3873c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_del_from_accept_list),
3874c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_SUPPORTED_STATES, hci_cc_le_read_supported_states,
3875c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_supported_states)),
3876c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_DEF_DATA_LEN, hci_cc_le_read_def_data_len,
3877c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_def_data_len)),
3878c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_WRITE_DEF_DATA_LEN,
3879c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_write_def_data_len),
3880c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_ADD_TO_RESOLV_LIST,
3881c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_add_to_resolv_list),
3882c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_DEL_FROM_RESOLV_LIST,
3883c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_del_from_resolv_list),
3884c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_CLEAR_RESOLV_LIST,
3885c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_clear_resolv_list),
3886c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_RESOLV_LIST_SIZE, hci_cc_le_read_resolv_list_size,
3887c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_resolv_list_size)),
3888c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_ADDR_RESOLV_ENABLE,
3889c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_set_addr_resolution_enable),
3890c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_MAX_DATA_LEN, hci_cc_le_read_max_data_len,
3891c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_max_data_len)),
3892c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_LE_HOST_SUPPORTED,
3893c8992cffSLuiz Augusto von Dentz 		      hci_cc_write_le_host_supported),
3894c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_ADV_PARAM, hci_cc_set_adv_param),
3895c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_RSSI, hci_cc_read_rssi,
3896c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_rssi)),
3897c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_TX_POWER, hci_cc_read_tx_power,
3898c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_tx_power)),
3899c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_SSP_DEBUG_MODE, hci_cc_write_ssp_debug_mode),
3900c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_EXT_SCAN_PARAMS,
3901c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_set_ext_scan_param),
3902c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_EXT_SCAN_ENABLE,
3903c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_set_ext_scan_enable),
3904c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_DEFAULT_PHY, hci_cc_le_set_default_phy),
3905c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_NUM_SUPPORTED_ADV_SETS,
3906c8992cffSLuiz Augusto von Dentz 	       hci_cc_le_read_num_adv_sets,
3907c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_num_supported_adv_sets)),
3908c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_SET_EXT_ADV_PARAMS, hci_cc_set_ext_adv_param,
3909c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_set_ext_adv_params)),
3910c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_EXT_ADV_ENABLE,
3911c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_set_ext_adv_enable),
3912c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_ADV_SET_RAND_ADDR,
3913c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_set_adv_set_random_addr),
3914c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_REMOVE_ADV_SET, hci_cc_le_remove_adv_set),
3915c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_CLEAR_ADV_SETS, hci_cc_le_clear_adv_sets),
3916c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_TRANSMIT_POWER, hci_cc_le_read_transmit_power,
3917*853b70b5SLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_transmit_power)),
3918*853b70b5SLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_PRIVACY_MODE, hci_cc_le_set_privacy_mode)
3919c8992cffSLuiz Augusto von Dentz };
3920c8992cffSLuiz Augusto von Dentz 
3921c8992cffSLuiz Augusto von Dentz static u8 hci_cc_func(struct hci_dev *hdev, const struct hci_cc *cc,
3922c8992cffSLuiz Augusto von Dentz 		      struct sk_buff *skb)
3923c8992cffSLuiz Augusto von Dentz {
3924c8992cffSLuiz Augusto von Dentz 	void *data;
3925c8992cffSLuiz Augusto von Dentz 
3926c8992cffSLuiz Augusto von Dentz 	if (skb->len < cc->min_len) {
3927c8992cffSLuiz Augusto von Dentz 		bt_dev_err(hdev, "unexpected cc 0x%4.4x length: %u < %u",
3928c8992cffSLuiz Augusto von Dentz 			   cc->op, skb->len, cc->min_len);
3929c8992cffSLuiz Augusto von Dentz 		return HCI_ERROR_UNSPECIFIED;
3930c8992cffSLuiz Augusto von Dentz 	}
3931c8992cffSLuiz Augusto von Dentz 
3932c8992cffSLuiz Augusto von Dentz 	/* Just warn if the length is over max_len size it still be possible to
3933c8992cffSLuiz Augusto von Dentz 	 * partially parse the cc so leave to callback to decide if that is
3934c8992cffSLuiz Augusto von Dentz 	 * acceptable.
3935c8992cffSLuiz Augusto von Dentz 	 */
3936c8992cffSLuiz Augusto von Dentz 	if (skb->len > cc->max_len)
3937c8992cffSLuiz Augusto von Dentz 		bt_dev_warn(hdev, "unexpected cc 0x%4.4x length: %u > %u",
3938c8992cffSLuiz Augusto von Dentz 			    cc->op, skb->len, cc->max_len);
3939c8992cffSLuiz Augusto von Dentz 
3940c8992cffSLuiz Augusto von Dentz 	data = hci_cc_skb_pull(hdev, skb, cc->op, cc->min_len);
3941c8992cffSLuiz Augusto von Dentz 	if (!data)
3942c8992cffSLuiz Augusto von Dentz 		return HCI_ERROR_UNSPECIFIED;
3943c8992cffSLuiz Augusto von Dentz 
3944c8992cffSLuiz Augusto von Dentz 	return cc->func(hdev, data, skb);
3945c8992cffSLuiz Augusto von Dentz }
3946c8992cffSLuiz Augusto von Dentz 
39473e54c589SLuiz Augusto von Dentz static void hci_cmd_complete_evt(struct hci_dev *hdev, void *data,
39483e54c589SLuiz Augusto von Dentz 				 struct sk_buff *skb, u16 *opcode, u8 *status,
3949e6214487SJohan Hedberg 				 hci_req_complete_t *req_complete,
3950e6214487SJohan Hedberg 				 hci_req_complete_skb_t *req_complete_skb)
3951a9de9248SMarcel Holtmann {
39523e54c589SLuiz Augusto von Dentz 	struct hci_ev_cmd_complete *ev = data;
3953c8992cffSLuiz Augusto von Dentz 	int i;
3954e6214487SJohan Hedberg 
3955e6214487SJohan Hedberg 	*opcode = __le16_to_cpu(ev->opcode);
3956a9de9248SMarcel Holtmann 
3957c8992cffSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "opcode 0x%4.4x", *opcode);
3958a9de9248SMarcel Holtmann 
3959c8992cffSLuiz Augusto von Dentz 	for (i = 0; i < ARRAY_SIZE(hci_cc_table); i++) {
3960c8992cffSLuiz Augusto von Dentz 		if (hci_cc_table[i].op == *opcode) {
3961c8992cffSLuiz Augusto von Dentz 			*status = hci_cc_func(hdev, &hci_cc_table[i], skb);
39624d93483bSAndre Guedes 			break;
3963c8992cffSLuiz Augusto von Dentz 		}
3964a9de9248SMarcel Holtmann 	}
3965a9de9248SMarcel Holtmann 
3966ecb71f25SKiran K 	handle_cmd_cnt_and_timer(hdev, ev->ncmd);
3967600b2150SJohan Hedberg 
3968e6214487SJohan Hedberg 	hci_req_cmd_complete(hdev, *opcode, *status, req_complete,
3969e6214487SJohan Hedberg 			     req_complete_skb);
39709238f36aSJohan Hedberg 
3971f80c5dadSJoão Paulo Rechi Vita 	if (hci_dev_test_flag(hdev, HCI_CMD_PENDING)) {
3972f80c5dadSJoão Paulo Rechi Vita 		bt_dev_err(hdev,
3973f80c5dadSJoão Paulo Rechi Vita 			   "unexpected event for opcode 0x%4.4x", *opcode);
3974f80c5dadSJoão Paulo Rechi Vita 		return;
3975f80c5dadSJoão Paulo Rechi Vita 	}
3976f80c5dadSJoão Paulo Rechi Vita 
3977600b2150SJohan Hedberg 	if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q))
3978c347b765SGustavo F. Padovan 		queue_work(hdev->workqueue, &hdev->cmd_work);
3979a9de9248SMarcel Holtmann }
3980a9de9248SMarcel Holtmann 
3981147306ccSLuiz Augusto von Dentz #define HCI_CS(_op, _func) \
3982147306ccSLuiz Augusto von Dentz { \
3983147306ccSLuiz Augusto von Dentz 	.op = _op, \
3984147306ccSLuiz Augusto von Dentz 	.func = _func, \
3985147306ccSLuiz Augusto von Dentz }
3986147306ccSLuiz Augusto von Dentz 
3987147306ccSLuiz Augusto von Dentz static const struct hci_cs {
3988147306ccSLuiz Augusto von Dentz 	u16  op;
3989147306ccSLuiz Augusto von Dentz 	void (*func)(struct hci_dev *hdev, __u8 status);
3990147306ccSLuiz Augusto von Dentz } hci_cs_table[] = {
3991147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_INQUIRY, hci_cs_inquiry),
3992147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_CREATE_CONN, hci_cs_create_conn),
3993147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_DISCONNECT, hci_cs_disconnect),
3994147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_ADD_SCO, hci_cs_add_sco),
3995147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_AUTH_REQUESTED, hci_cs_auth_requested),
3996147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_SET_CONN_ENCRYPT, hci_cs_set_conn_encrypt),
3997147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_REMOTE_NAME_REQ, hci_cs_remote_name_req),
3998147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_READ_REMOTE_FEATURES, hci_cs_read_remote_features),
3999147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_READ_REMOTE_EXT_FEATURES,
4000147306ccSLuiz Augusto von Dentz 	       hci_cs_read_remote_ext_features),
4001147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_SETUP_SYNC_CONN, hci_cs_setup_sync_conn),
4002147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_ENHANCED_SETUP_SYNC_CONN,
4003147306ccSLuiz Augusto von Dentz 	       hci_cs_enhanced_setup_sync_conn),
4004147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_SNIFF_MODE, hci_cs_sniff_mode),
4005147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_EXIT_SNIFF_MODE, hci_cs_exit_sniff_mode),
4006147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_SWITCH_ROLE, hci_cs_switch_role),
4007147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_LE_CREATE_CONN, hci_cs_le_create_conn),
4008147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_LE_READ_REMOTE_FEATURES, hci_cs_le_read_remote_features),
4009147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_LE_START_ENC, hci_cs_le_start_enc),
4010147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_LE_EXT_CREATE_CONN, hci_cs_le_ext_create_conn)
4011147306ccSLuiz Augusto von Dentz };
4012147306ccSLuiz Augusto von Dentz 
40133e54c589SLuiz Augusto von Dentz static void hci_cmd_status_evt(struct hci_dev *hdev, void *data,
40143e54c589SLuiz Augusto von Dentz 			       struct sk_buff *skb, u16 *opcode, u8 *status,
4015e6214487SJohan Hedberg 			       hci_req_complete_t *req_complete,
4016e6214487SJohan Hedberg 			       hci_req_complete_skb_t *req_complete_skb)
4017a9de9248SMarcel Holtmann {
40183e54c589SLuiz Augusto von Dentz 	struct hci_ev_cmd_status *ev = data;
4019147306ccSLuiz Augusto von Dentz 	int i;
4020a9de9248SMarcel Holtmann 
4021e6214487SJohan Hedberg 	*opcode = __le16_to_cpu(ev->opcode);
4022e6214487SJohan Hedberg 	*status = ev->status;
4023a9de9248SMarcel Holtmann 
4024147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "opcode 0x%4.4x", *opcode);
4025a9de9248SMarcel Holtmann 
4026147306ccSLuiz Augusto von Dentz 	for (i = 0; i < ARRAY_SIZE(hci_cs_table); i++) {
4027147306ccSLuiz Augusto von Dentz 		if (hci_cs_table[i].op == *opcode) {
4028147306ccSLuiz Augusto von Dentz 			hci_cs_table[i].func(hdev, ev->status);
4029a9de9248SMarcel Holtmann 			break;
4030147306ccSLuiz Augusto von Dentz 		}
4031a9de9248SMarcel Holtmann 	}
4032a9de9248SMarcel Holtmann 
4033ecb71f25SKiran K 	handle_cmd_cnt_and_timer(hdev, ev->ncmd);
4034600b2150SJohan Hedberg 
4035444c6dd5SJohan Hedberg 	/* Indicate request completion if the command failed. Also, if
4036444c6dd5SJohan Hedberg 	 * we're not waiting for a special event and we get a success
4037444c6dd5SJohan Hedberg 	 * command status we should try to flag the request as completed
4038444c6dd5SJohan Hedberg 	 * (since for this kind of commands there will not be a command
4039444c6dd5SJohan Hedberg 	 * complete event).
4040444c6dd5SJohan Hedberg 	 */
404102350a72SJohan Hedberg 	if (ev->status ||
4042242c0ebdSMarcel Holtmann 	    (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->hci.req_event))
4043e6214487SJohan Hedberg 		hci_req_cmd_complete(hdev, *opcode, ev->status, req_complete,
4044e6214487SJohan Hedberg 				     req_complete_skb);
40459238f36aSJohan Hedberg 
4046f80c5dadSJoão Paulo Rechi Vita 	if (hci_dev_test_flag(hdev, HCI_CMD_PENDING)) {
4047f80c5dadSJoão Paulo Rechi Vita 		bt_dev_err(hdev,
4048f80c5dadSJoão Paulo Rechi Vita 			   "unexpected event for opcode 0x%4.4x", *opcode);
4049f80c5dadSJoão Paulo Rechi Vita 		return;
4050f80c5dadSJoão Paulo Rechi Vita 	}
4051f80c5dadSJoão Paulo Rechi Vita 
4052600b2150SJohan Hedberg 	if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q))
4053c347b765SGustavo F. Padovan 		queue_work(hdev->workqueue, &hdev->cmd_work);
4054a9de9248SMarcel Holtmann }
4055a9de9248SMarcel Holtmann 
40563e54c589SLuiz Augusto von Dentz static void hci_hardware_error_evt(struct hci_dev *hdev, void *data,
40573e54c589SLuiz Augusto von Dentz 				   struct sk_buff *skb)
405824dfa343SMarcel Holtmann {
40593e54c589SLuiz Augusto von Dentz 	struct hci_ev_hardware_error *ev = data;
4060ae61a10dSLuiz Augusto von Dentz 
40613e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "code 0x%2.2x", ev->code);
406224dfa343SMarcel Holtmann 
4063c7741d16SMarcel Holtmann 	hdev->hw_error_code = ev->code;
4064c7741d16SMarcel Holtmann 
4065c7741d16SMarcel Holtmann 	queue_work(hdev->req_workqueue, &hdev->error_reset);
406624dfa343SMarcel Holtmann }
406724dfa343SMarcel Holtmann 
40683e54c589SLuiz Augusto von Dentz static void hci_role_change_evt(struct hci_dev *hdev, void *data,
40693e54c589SLuiz Augusto von Dentz 				struct sk_buff *skb)
4070a9de9248SMarcel Holtmann {
40713e54c589SLuiz Augusto von Dentz 	struct hci_ev_role_change *ev = data;
4072a9de9248SMarcel Holtmann 	struct hci_conn *conn;
4073a9de9248SMarcel Holtmann 
40743e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
4075a9de9248SMarcel Holtmann 
4076a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
4077a9de9248SMarcel Holtmann 
4078a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
4079a9de9248SMarcel Holtmann 	if (conn) {
408040bef302SJohan Hedberg 		if (!ev->status)
408140bef302SJohan Hedberg 			conn->role = ev->role;
4082a9de9248SMarcel Holtmann 
408351a8efd7SJohan Hedberg 		clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
4084a9de9248SMarcel Holtmann 
4085a9de9248SMarcel Holtmann 		hci_role_switch_cfm(conn, ev->status, ev->role);
4086a9de9248SMarcel Holtmann 	}
4087a9de9248SMarcel Holtmann 
4088a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
4089a9de9248SMarcel Holtmann }
4090a9de9248SMarcel Holtmann 
40913e54c589SLuiz Augusto von Dentz static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data,
40923e54c589SLuiz Augusto von Dentz 				  struct sk_buff *skb)
40931da177e4SLinus Torvalds {
40943e54c589SLuiz Augusto von Dentz 	struct hci_ev_num_comp_pkts *ev = data;
40951da177e4SLinus Torvalds 	int i;
40961da177e4SLinus Torvalds 
4097aadc3d2fSLuiz Augusto von Dentz 	if (!hci_ev_skb_pull(hdev, skb, HCI_EV_NUM_COMP_PKTS,
4098aadc3d2fSLuiz Augusto von Dentz 			     flex_array_size(ev, handles, ev->num)))
4099aadc3d2fSLuiz Augusto von Dentz 		return;
4100aadc3d2fSLuiz Augusto von Dentz 
410132ac5b9bSAndrei Emeltchenko 	if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
41022064ee33SMarcel Holtmann 		bt_dev_err(hdev, "wrong event for mode %d", hdev->flow_ctl_mode);
410332ac5b9bSAndrei Emeltchenko 		return;
410432ac5b9bSAndrei Emeltchenko 	}
410532ac5b9bSAndrei Emeltchenko 
41063e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "num %d", ev->num);
41071da177e4SLinus Torvalds 
4108aadc3d2fSLuiz Augusto von Dentz 	for (i = 0; i < ev->num; i++) {
4109613a1c0cSAndrei Emeltchenko 		struct hci_comp_pkts_info *info = &ev->handles[i];
41101da177e4SLinus Torvalds 		struct hci_conn *conn;
41111da177e4SLinus Torvalds 		__u16  handle, count;
41121da177e4SLinus Torvalds 
4113613a1c0cSAndrei Emeltchenko 		handle = __le16_to_cpu(info->handle);
4114613a1c0cSAndrei Emeltchenko 		count  = __le16_to_cpu(info->count);
41151da177e4SLinus Torvalds 
41161da177e4SLinus Torvalds 		conn = hci_conn_hash_lookup_handle(hdev, handle);
4117f4280918SAndrei Emeltchenko 		if (!conn)
4118f4280918SAndrei Emeltchenko 			continue;
4119f4280918SAndrei Emeltchenko 
41201da177e4SLinus Torvalds 		conn->sent -= count;
41211da177e4SLinus Torvalds 
4122f4280918SAndrei Emeltchenko 		switch (conn->type) {
4123f4280918SAndrei Emeltchenko 		case ACL_LINK:
412470f23020SAndrei Emeltchenko 			hdev->acl_cnt += count;
412570f23020SAndrei Emeltchenko 			if (hdev->acl_cnt > hdev->acl_pkts)
41261da177e4SLinus Torvalds 				hdev->acl_cnt = hdev->acl_pkts;
4127f4280918SAndrei Emeltchenko 			break;
4128f4280918SAndrei Emeltchenko 
4129f4280918SAndrei Emeltchenko 		case LE_LINK:
41306ed58ec5SVille Tervo 			if (hdev->le_pkts) {
41316ed58ec5SVille Tervo 				hdev->le_cnt += count;
41326ed58ec5SVille Tervo 				if (hdev->le_cnt > hdev->le_pkts)
41336ed58ec5SVille Tervo 					hdev->le_cnt = hdev->le_pkts;
41346ed58ec5SVille Tervo 			} else {
41356ed58ec5SVille Tervo 				hdev->acl_cnt += count;
41366ed58ec5SVille Tervo 				if (hdev->acl_cnt > hdev->acl_pkts)
41376ed58ec5SVille Tervo 					hdev->acl_cnt = hdev->acl_pkts;
41386ed58ec5SVille Tervo 			}
4139f4280918SAndrei Emeltchenko 			break;
4140f4280918SAndrei Emeltchenko 
4141f4280918SAndrei Emeltchenko 		case SCO_LINK:
414270f23020SAndrei Emeltchenko 			hdev->sco_cnt += count;
414370f23020SAndrei Emeltchenko 			if (hdev->sco_cnt > hdev->sco_pkts)
41445b7f9909SMarcel Holtmann 				hdev->sco_cnt = hdev->sco_pkts;
4145f4280918SAndrei Emeltchenko 			break;
4146f4280918SAndrei Emeltchenko 
4147f4280918SAndrei Emeltchenko 		default:
41482064ee33SMarcel Holtmann 			bt_dev_err(hdev, "unknown type %d conn %p",
41492064ee33SMarcel Holtmann 				   conn->type, conn);
4150f4280918SAndrei Emeltchenko 			break;
41511da177e4SLinus Torvalds 		}
41521da177e4SLinus Torvalds 	}
4153a9de9248SMarcel Holtmann 
41543eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
41551da177e4SLinus Torvalds }
41561da177e4SLinus Torvalds 
415776ef7cf7SAndrei Emeltchenko static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
415876ef7cf7SAndrei Emeltchenko 						 __u16 handle)
415976ef7cf7SAndrei Emeltchenko {
416076ef7cf7SAndrei Emeltchenko 	struct hci_chan *chan;
416176ef7cf7SAndrei Emeltchenko 
416276ef7cf7SAndrei Emeltchenko 	switch (hdev->dev_type) {
4163ca8bee5dSMarcel Holtmann 	case HCI_PRIMARY:
416476ef7cf7SAndrei Emeltchenko 		return hci_conn_hash_lookup_handle(hdev, handle);
416576ef7cf7SAndrei Emeltchenko 	case HCI_AMP:
416676ef7cf7SAndrei Emeltchenko 		chan = hci_chan_lookup_handle(hdev, handle);
416776ef7cf7SAndrei Emeltchenko 		if (chan)
416876ef7cf7SAndrei Emeltchenko 			return chan->conn;
416976ef7cf7SAndrei Emeltchenko 		break;
417076ef7cf7SAndrei Emeltchenko 	default:
41712064ee33SMarcel Holtmann 		bt_dev_err(hdev, "unknown dev_type %d", hdev->dev_type);
417276ef7cf7SAndrei Emeltchenko 		break;
417376ef7cf7SAndrei Emeltchenko 	}
417476ef7cf7SAndrei Emeltchenko 
417576ef7cf7SAndrei Emeltchenko 	return NULL;
417676ef7cf7SAndrei Emeltchenko }
417776ef7cf7SAndrei Emeltchenko 
41783e54c589SLuiz Augusto von Dentz static void hci_num_comp_blocks_evt(struct hci_dev *hdev, void *data,
41793e54c589SLuiz Augusto von Dentz 				    struct sk_buff *skb)
418025e89e99SAndrei Emeltchenko {
41813e54c589SLuiz Augusto von Dentz 	struct hci_ev_num_comp_blocks *ev = data;
418225e89e99SAndrei Emeltchenko 	int i;
418325e89e99SAndrei Emeltchenko 
4184ae61a10dSLuiz Augusto von Dentz 	if (!hci_ev_skb_pull(hdev, skb, HCI_EV_NUM_COMP_BLOCKS,
4185ae61a10dSLuiz Augusto von Dentz 			     flex_array_size(ev, handles, ev->num_hndl)))
4186ae61a10dSLuiz Augusto von Dentz 		return;
4187ae61a10dSLuiz Augusto von Dentz 
418825e89e99SAndrei Emeltchenko 	if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
41893e54c589SLuiz Augusto von Dentz 		bt_dev_err(hdev, "wrong event for mode %d",
41903e54c589SLuiz Augusto von Dentz 			   hdev->flow_ctl_mode);
419125e89e99SAndrei Emeltchenko 		return;
419225e89e99SAndrei Emeltchenko 	}
419325e89e99SAndrei Emeltchenko 
41943e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "num_blocks %d num_hndl %d", ev->num_blocks,
419525e89e99SAndrei Emeltchenko 		   ev->num_hndl);
419625e89e99SAndrei Emeltchenko 
419725e89e99SAndrei Emeltchenko 	for (i = 0; i < ev->num_hndl; i++) {
419825e89e99SAndrei Emeltchenko 		struct hci_comp_blocks_info *info = &ev->handles[i];
419976ef7cf7SAndrei Emeltchenko 		struct hci_conn *conn = NULL;
420025e89e99SAndrei Emeltchenko 		__u16  handle, block_count;
420125e89e99SAndrei Emeltchenko 
420225e89e99SAndrei Emeltchenko 		handle = __le16_to_cpu(info->handle);
420325e89e99SAndrei Emeltchenko 		block_count = __le16_to_cpu(info->blocks);
420425e89e99SAndrei Emeltchenko 
420576ef7cf7SAndrei Emeltchenko 		conn = __hci_conn_lookup_handle(hdev, handle);
420625e89e99SAndrei Emeltchenko 		if (!conn)
420725e89e99SAndrei Emeltchenko 			continue;
420825e89e99SAndrei Emeltchenko 
420925e89e99SAndrei Emeltchenko 		conn->sent -= block_count;
421025e89e99SAndrei Emeltchenko 
421125e89e99SAndrei Emeltchenko 		switch (conn->type) {
421225e89e99SAndrei Emeltchenko 		case ACL_LINK:
4213bd1eb66bSAndrei Emeltchenko 		case AMP_LINK:
421425e89e99SAndrei Emeltchenko 			hdev->block_cnt += block_count;
421525e89e99SAndrei Emeltchenko 			if (hdev->block_cnt > hdev->num_blocks)
421625e89e99SAndrei Emeltchenko 				hdev->block_cnt = hdev->num_blocks;
421725e89e99SAndrei Emeltchenko 			break;
421825e89e99SAndrei Emeltchenko 
421925e89e99SAndrei Emeltchenko 		default:
42202064ee33SMarcel Holtmann 			bt_dev_err(hdev, "unknown type %d conn %p",
42212064ee33SMarcel Holtmann 				   conn->type, conn);
422225e89e99SAndrei Emeltchenko 			break;
422325e89e99SAndrei Emeltchenko 		}
422425e89e99SAndrei Emeltchenko 	}
422525e89e99SAndrei Emeltchenko 
422625e89e99SAndrei Emeltchenko 	queue_work(hdev->workqueue, &hdev->tx_work);
422725e89e99SAndrei Emeltchenko }
422825e89e99SAndrei Emeltchenko 
42293e54c589SLuiz Augusto von Dentz static void hci_mode_change_evt(struct hci_dev *hdev, void *data,
42303e54c589SLuiz Augusto von Dentz 				struct sk_buff *skb)
42311da177e4SLinus Torvalds {
42323e54c589SLuiz Augusto von Dentz 	struct hci_ev_mode_change *ev = data;
423304837f64SMarcel Holtmann 	struct hci_conn *conn;
42341da177e4SLinus Torvalds 
42353e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
42361da177e4SLinus Torvalds 
42371da177e4SLinus Torvalds 	hci_dev_lock(hdev);
42381da177e4SLinus Torvalds 
423904837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
424004837f64SMarcel Holtmann 	if (conn) {
424104837f64SMarcel Holtmann 		conn->mode = ev->mode;
424204837f64SMarcel Holtmann 
42438fc9ced3SGustavo Padovan 		if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
42448fc9ced3SGustavo Padovan 					&conn->flags)) {
424504837f64SMarcel Holtmann 			if (conn->mode == HCI_CM_ACTIVE)
424658a681efSJohan Hedberg 				set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
424704837f64SMarcel Holtmann 			else
424858a681efSJohan Hedberg 				clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
424904837f64SMarcel Holtmann 		}
4250e73439d8SMarcel Holtmann 
425151a8efd7SJohan Hedberg 		if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
4252e73439d8SMarcel Holtmann 			hci_sco_setup(conn, ev->status);
425304837f64SMarcel Holtmann 	}
425404837f64SMarcel Holtmann 
425504837f64SMarcel Holtmann 	hci_dev_unlock(hdev);
425604837f64SMarcel Holtmann }
425704837f64SMarcel Holtmann 
42583e54c589SLuiz Augusto von Dentz static void hci_pin_code_request_evt(struct hci_dev *hdev, void *data,
42593e54c589SLuiz Augusto von Dentz 				     struct sk_buff *skb)
42601da177e4SLinus Torvalds {
42613e54c589SLuiz Augusto von Dentz 	struct hci_ev_pin_code_req *ev = data;
4262052b30b0SMarcel Holtmann 	struct hci_conn *conn;
4263052b30b0SMarcel Holtmann 
42643e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
4265052b30b0SMarcel Holtmann 
4266052b30b0SMarcel Holtmann 	hci_dev_lock(hdev);
4267052b30b0SMarcel Holtmann 
4268052b30b0SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
4269b6f98044SWaldemar Rymarkiewicz 	if (!conn)
4270b6f98044SWaldemar Rymarkiewicz 		goto unlock;
4271b6f98044SWaldemar Rymarkiewicz 
4272b6f98044SWaldemar Rymarkiewicz 	if (conn->state == BT_CONNECTED) {
4273052b30b0SMarcel Holtmann 		hci_conn_hold(conn);
4274052b30b0SMarcel Holtmann 		conn->disc_timeout = HCI_PAIRING_TIMEOUT;
427576a68ba0SDavid Herrmann 		hci_conn_drop(conn);
4276052b30b0SMarcel Holtmann 	}
4277052b30b0SMarcel Holtmann 
4278d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BONDABLE) &&
42792f407f0aSJohan Hedberg 	    !test_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags)) {
428003b555e1SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
428103b555e1SJohan Hedberg 			     sizeof(ev->bdaddr), &ev->bdaddr);
4282d7a5a11dSMarcel Holtmann 	} else if (hci_dev_test_flag(hdev, HCI_MGMT)) {
4283a770bb5aSWaldemar Rymarkiewicz 		u8 secure;
4284a770bb5aSWaldemar Rymarkiewicz 
4285a770bb5aSWaldemar Rymarkiewicz 		if (conn->pending_sec_level == BT_SECURITY_HIGH)
4286a770bb5aSWaldemar Rymarkiewicz 			secure = 1;
4287a770bb5aSWaldemar Rymarkiewicz 		else
4288a770bb5aSWaldemar Rymarkiewicz 			secure = 0;
4289a770bb5aSWaldemar Rymarkiewicz 
4290744cf19eSJohan Hedberg 		mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
4291a770bb5aSWaldemar Rymarkiewicz 	}
4292980e1a53SJohan Hedberg 
4293b6f98044SWaldemar Rymarkiewicz unlock:
4294052b30b0SMarcel Holtmann 	hci_dev_unlock(hdev);
42951da177e4SLinus Torvalds }
42961da177e4SLinus Torvalds 
4297cb6f3f7aSJohan Hedberg static void conn_set_key(struct hci_conn *conn, u8 key_type, u8 pin_len)
4298cb6f3f7aSJohan Hedberg {
4299cb6f3f7aSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION)
4300cb6f3f7aSJohan Hedberg 		return;
4301cb6f3f7aSJohan Hedberg 
4302cb6f3f7aSJohan Hedberg 	conn->pin_length = pin_len;
4303cb6f3f7aSJohan Hedberg 	conn->key_type = key_type;
4304cb6f3f7aSJohan Hedberg 
4305cb6f3f7aSJohan Hedberg 	switch (key_type) {
4306cb6f3f7aSJohan Hedberg 	case HCI_LK_LOCAL_UNIT:
4307cb6f3f7aSJohan Hedberg 	case HCI_LK_REMOTE_UNIT:
4308cb6f3f7aSJohan Hedberg 	case HCI_LK_DEBUG_COMBINATION:
4309cb6f3f7aSJohan Hedberg 		return;
4310cb6f3f7aSJohan Hedberg 	case HCI_LK_COMBINATION:
4311cb6f3f7aSJohan Hedberg 		if (pin_len == 16)
4312cb6f3f7aSJohan Hedberg 			conn->pending_sec_level = BT_SECURITY_HIGH;
4313cb6f3f7aSJohan Hedberg 		else
4314cb6f3f7aSJohan Hedberg 			conn->pending_sec_level = BT_SECURITY_MEDIUM;
4315cb6f3f7aSJohan Hedberg 		break;
4316cb6f3f7aSJohan Hedberg 	case HCI_LK_UNAUTH_COMBINATION_P192:
4317cb6f3f7aSJohan Hedberg 	case HCI_LK_UNAUTH_COMBINATION_P256:
4318cb6f3f7aSJohan Hedberg 		conn->pending_sec_level = BT_SECURITY_MEDIUM;
4319cb6f3f7aSJohan Hedberg 		break;
4320cb6f3f7aSJohan Hedberg 	case HCI_LK_AUTH_COMBINATION_P192:
4321cb6f3f7aSJohan Hedberg 		conn->pending_sec_level = BT_SECURITY_HIGH;
4322cb6f3f7aSJohan Hedberg 		break;
4323cb6f3f7aSJohan Hedberg 	case HCI_LK_AUTH_COMBINATION_P256:
4324cb6f3f7aSJohan Hedberg 		conn->pending_sec_level = BT_SECURITY_FIPS;
4325cb6f3f7aSJohan Hedberg 		break;
4326cb6f3f7aSJohan Hedberg 	}
4327cb6f3f7aSJohan Hedberg }
4328cb6f3f7aSJohan Hedberg 
43293e54c589SLuiz Augusto von Dentz static void hci_link_key_request_evt(struct hci_dev *hdev, void *data,
43303e54c589SLuiz Augusto von Dentz 				     struct sk_buff *skb)
43311da177e4SLinus Torvalds {
43323e54c589SLuiz Augusto von Dentz 	struct hci_ev_link_key_req *ev = data;
433355ed8ca1SJohan Hedberg 	struct hci_cp_link_key_reply cp;
433455ed8ca1SJohan Hedberg 	struct hci_conn *conn;
433555ed8ca1SJohan Hedberg 	struct link_key *key;
433655ed8ca1SJohan Hedberg 
43373e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
433855ed8ca1SJohan Hedberg 
4339d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
434055ed8ca1SJohan Hedberg 		return;
434155ed8ca1SJohan Hedberg 
434255ed8ca1SJohan Hedberg 	hci_dev_lock(hdev);
434355ed8ca1SJohan Hedberg 
434455ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, &ev->bdaddr);
434555ed8ca1SJohan Hedberg 	if (!key) {
43463e54c589SLuiz Augusto von Dentz 		bt_dev_dbg(hdev, "link key not found for %pMR", &ev->bdaddr);
434755ed8ca1SJohan Hedberg 		goto not_found;
434855ed8ca1SJohan Hedberg 	}
434955ed8ca1SJohan Hedberg 
43503e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "found key type %u for %pMR", key->type, &ev->bdaddr);
435155ed8ca1SJohan Hedberg 
435255ed8ca1SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
435360b83f57SWaldemar Rymarkiewicz 	if (conn) {
4354fe8bc5acSJohan Hedberg 		clear_bit(HCI_CONN_NEW_LINK_KEY, &conn->flags);
4355fe8bc5acSJohan Hedberg 
435666138ce8SMarcel Holtmann 		if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 ||
435766138ce8SMarcel Holtmann 		     key->type == HCI_LK_UNAUTH_COMBINATION_P256) &&
4358807deac2SGustavo Padovan 		    conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
43593e54c589SLuiz Augusto von Dentz 			bt_dev_dbg(hdev, "ignoring unauthenticated key");
436055ed8ca1SJohan Hedberg 			goto not_found;
436155ed8ca1SJohan Hedberg 		}
436255ed8ca1SJohan Hedberg 
436360b83f57SWaldemar Rymarkiewicz 		if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
4364f3fb0b58SJohan Hedberg 		    (conn->pending_sec_level == BT_SECURITY_HIGH ||
4365f3fb0b58SJohan Hedberg 		     conn->pending_sec_level == BT_SECURITY_FIPS)) {
43663e54c589SLuiz Augusto von Dentz 			bt_dev_dbg(hdev, "ignoring key unauthenticated for high security");
436760b83f57SWaldemar Rymarkiewicz 			goto not_found;
436860b83f57SWaldemar Rymarkiewicz 		}
436960b83f57SWaldemar Rymarkiewicz 
4370cb6f3f7aSJohan Hedberg 		conn_set_key(conn, key->type, key->pin_len);
437160b83f57SWaldemar Rymarkiewicz 	}
437260b83f57SWaldemar Rymarkiewicz 
437355ed8ca1SJohan Hedberg 	bacpy(&cp.bdaddr, &ev->bdaddr);
43749b3b4460SAndrei Emeltchenko 	memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
437555ed8ca1SJohan Hedberg 
437655ed8ca1SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
437755ed8ca1SJohan Hedberg 
437855ed8ca1SJohan Hedberg 	hci_dev_unlock(hdev);
437955ed8ca1SJohan Hedberg 
438055ed8ca1SJohan Hedberg 	return;
438155ed8ca1SJohan Hedberg 
438255ed8ca1SJohan Hedberg not_found:
438355ed8ca1SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
438455ed8ca1SJohan Hedberg 	hci_dev_unlock(hdev);
43851da177e4SLinus Torvalds }
43861da177e4SLinus Torvalds 
43873e54c589SLuiz Augusto von Dentz static void hci_link_key_notify_evt(struct hci_dev *hdev, void *data,
43883e54c589SLuiz Augusto von Dentz 				    struct sk_buff *skb)
43891da177e4SLinus Torvalds {
43903e54c589SLuiz Augusto von Dentz 	struct hci_ev_link_key_notify *ev = data;
4391052b30b0SMarcel Holtmann 	struct hci_conn *conn;
43927652ff6aSJohan Hedberg 	struct link_key *key;
43937652ff6aSJohan Hedberg 	bool persistent;
439455ed8ca1SJohan Hedberg 	u8 pin_len = 0;
4395052b30b0SMarcel Holtmann 
43963e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
4397052b30b0SMarcel Holtmann 
4398052b30b0SMarcel Holtmann 	hci_dev_lock(hdev);
4399052b30b0SMarcel Holtmann 
4400052b30b0SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
440182c13d42SJohan Hedberg 	if (!conn)
440282c13d42SJohan Hedberg 		goto unlock;
440382c13d42SJohan Hedberg 
4404052b30b0SMarcel Holtmann 	hci_conn_hold(conn);
4405052b30b0SMarcel Holtmann 	conn->disc_timeout = HCI_DISCONN_TIMEOUT;
440676a68ba0SDavid Herrmann 	hci_conn_drop(conn);
440782c13d42SJohan Hedberg 
4408fe8bc5acSJohan Hedberg 	set_bit(HCI_CONN_NEW_LINK_KEY, &conn->flags);
4409cb6f3f7aSJohan Hedberg 	conn_set_key(conn, ev->key_type, conn->pin_length);
4410052b30b0SMarcel Holtmann 
4411d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
44127652ff6aSJohan Hedberg 		goto unlock;
441355ed8ca1SJohan Hedberg 
44147652ff6aSJohan Hedberg 	key = hci_add_link_key(hdev, conn, &ev->bdaddr, ev->link_key,
44157652ff6aSJohan Hedberg 			        ev->key_type, pin_len, &persistent);
44167652ff6aSJohan Hedberg 	if (!key)
44177652ff6aSJohan Hedberg 		goto unlock;
44187652ff6aSJohan Hedberg 
4419cb6f3f7aSJohan Hedberg 	/* Update connection information since adding the key will have
4420cb6f3f7aSJohan Hedberg 	 * fixed up the type in the case of changed combination keys.
4421cb6f3f7aSJohan Hedberg 	 */
4422cb6f3f7aSJohan Hedberg 	if (ev->key_type == HCI_LK_CHANGED_COMBINATION)
4423cb6f3f7aSJohan Hedberg 		conn_set_key(conn, key->type, key->pin_len);
4424cb6f3f7aSJohan Hedberg 
44257652ff6aSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
44267652ff6aSJohan Hedberg 
44276d5650c4SJohan Hedberg 	/* Keep debug keys around only if the HCI_KEEP_DEBUG_KEYS flag
44286d5650c4SJohan Hedberg 	 * is set. If it's not set simply remove the key from the kernel
44296d5650c4SJohan Hedberg 	 * list (we've still notified user space about it but with
44306d5650c4SJohan Hedberg 	 * store_hint being 0).
44316d5650c4SJohan Hedberg 	 */
44326d5650c4SJohan Hedberg 	if (key->type == HCI_LK_DEBUG_COMBINATION &&
4433d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_KEEP_DEBUG_KEYS)) {
44340378b597SJohan Hedberg 		list_del_rcu(&key->list);
44350378b597SJohan Hedberg 		kfree_rcu(key, rcu);
443682c13d42SJohan Hedberg 		goto unlock;
443782c13d42SJohan Hedberg 	}
443882c13d42SJohan Hedberg 
4439af6a9c32SJohan Hedberg 	if (persistent)
4440af6a9c32SJohan Hedberg 		clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags);
4441af6a9c32SJohan Hedberg 	else
4442af6a9c32SJohan Hedberg 		set_bit(HCI_CONN_FLUSH_KEY, &conn->flags);
44437652ff6aSJohan Hedberg 
44447652ff6aSJohan Hedberg unlock:
4445052b30b0SMarcel Holtmann 	hci_dev_unlock(hdev);
44461da177e4SLinus Torvalds }
44471da177e4SLinus Torvalds 
44483e54c589SLuiz Augusto von Dentz static void hci_clock_offset_evt(struct hci_dev *hdev, void *data,
44493e54c589SLuiz Augusto von Dentz 				 struct sk_buff *skb)
445004837f64SMarcel Holtmann {
44513e54c589SLuiz Augusto von Dentz 	struct hci_ev_clock_offset *ev = data;
445204837f64SMarcel Holtmann 	struct hci_conn *conn;
445304837f64SMarcel Holtmann 
44543e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
445504837f64SMarcel Holtmann 
445604837f64SMarcel Holtmann 	hci_dev_lock(hdev);
445704837f64SMarcel Holtmann 
445804837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
44591da177e4SLinus Torvalds 	if (conn && !ev->status) {
44601da177e4SLinus Torvalds 		struct inquiry_entry *ie;
44611da177e4SLinus Torvalds 
4462cc11b9c1SAndrei Emeltchenko 		ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
4463cc11b9c1SAndrei Emeltchenko 		if (ie) {
44641da177e4SLinus Torvalds 			ie->data.clock_offset = ev->clock_offset;
44651da177e4SLinus Torvalds 			ie->timestamp = jiffies;
44661da177e4SLinus Torvalds 		}
44671da177e4SLinus Torvalds 	}
44681da177e4SLinus Torvalds 
44691da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
44701da177e4SLinus Torvalds }
44711da177e4SLinus Torvalds 
44723e54c589SLuiz Augusto von Dentz static void hci_pkt_type_change_evt(struct hci_dev *hdev, void *data,
44733e54c589SLuiz Augusto von Dentz 				    struct sk_buff *skb)
4474a8746417SMarcel Holtmann {
44753e54c589SLuiz Augusto von Dentz 	struct hci_ev_pkt_type_change *ev = data;
4476a8746417SMarcel Holtmann 	struct hci_conn *conn;
4477a8746417SMarcel Holtmann 
44783e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
4479a8746417SMarcel Holtmann 
4480a8746417SMarcel Holtmann 	hci_dev_lock(hdev);
4481a8746417SMarcel Holtmann 
4482a8746417SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
4483a8746417SMarcel Holtmann 	if (conn && !ev->status)
4484a8746417SMarcel Holtmann 		conn->pkt_type = __le16_to_cpu(ev->pkt_type);
4485a8746417SMarcel Holtmann 
4486a8746417SMarcel Holtmann 	hci_dev_unlock(hdev);
4487a8746417SMarcel Holtmann }
4488a8746417SMarcel Holtmann 
44893e54c589SLuiz Augusto von Dentz static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, void *data,
44903e54c589SLuiz Augusto von Dentz 				   struct sk_buff *skb)
449185a1e930SMarcel Holtmann {
44923e54c589SLuiz Augusto von Dentz 	struct hci_ev_pscan_rep_mode *ev = data;
449385a1e930SMarcel Holtmann 	struct inquiry_entry *ie;
449485a1e930SMarcel Holtmann 
44953e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
449685a1e930SMarcel Holtmann 
449785a1e930SMarcel Holtmann 	hci_dev_lock(hdev);
449885a1e930SMarcel Holtmann 
4499cc11b9c1SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
4500cc11b9c1SAndrei Emeltchenko 	if (ie) {
450185a1e930SMarcel Holtmann 		ie->data.pscan_rep_mode = ev->pscan_rep_mode;
450285a1e930SMarcel Holtmann 		ie->timestamp = jiffies;
450385a1e930SMarcel Holtmann 	}
450485a1e930SMarcel Holtmann 
450585a1e930SMarcel Holtmann 	hci_dev_unlock(hdev);
450685a1e930SMarcel Holtmann }
450785a1e930SMarcel Holtmann 
45083e54c589SLuiz Augusto von Dentz static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, void *edata,
4509807deac2SGustavo Padovan 					     struct sk_buff *skb)
4510a9de9248SMarcel Holtmann {
45118d08d324SLuiz Augusto von Dentz 	union {
45128d08d324SLuiz Augusto von Dentz 		struct hci_ev_inquiry_result_rssi *res1;
45138d08d324SLuiz Augusto von Dentz 		struct hci_ev_inquiry_result_rssi_pscan *res2;
45143e54c589SLuiz Augusto von Dentz 	} *ev = edata;
4515a9de9248SMarcel Holtmann 	struct inquiry_data data;
45168d08d324SLuiz Augusto von Dentz 	int i;
4517a9de9248SMarcel Holtmann 
45183e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "num_rsp %d", ev->res1->num);
45198d08d324SLuiz Augusto von Dentz 
45208d08d324SLuiz Augusto von Dentz 	if (!ev->res1->num)
4521a9de9248SMarcel Holtmann 		return;
4522a9de9248SMarcel Holtmann 
4523d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ))
45241519cc17SAndre Guedes 		return;
45251519cc17SAndre Guedes 
4526a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
4527a9de9248SMarcel Holtmann 
45288d08d324SLuiz Augusto von Dentz 	if (skb->len == flex_array_size(ev, res2->info, ev->res2->num)) {
45298d08d324SLuiz Augusto von Dentz 		struct inquiry_info_rssi_pscan *info;
4530a9de9248SMarcel Holtmann 
45318d08d324SLuiz Augusto von Dentz 		for (i = 0; i < ev->res2->num; i++) {
4532af58925cSMarcel Holtmann 			u32 flags;
4533af58925cSMarcel Holtmann 
45348d08d324SLuiz Augusto von Dentz 			info = &ev->res2->info[i];
4535a9de9248SMarcel Holtmann 			bacpy(&data.bdaddr, &info->bdaddr);
4536a9de9248SMarcel Holtmann 			data.pscan_rep_mode	= info->pscan_rep_mode;
4537a9de9248SMarcel Holtmann 			data.pscan_period_mode	= info->pscan_period_mode;
4538a9de9248SMarcel Holtmann 			data.pscan_mode		= info->pscan_mode;
4539a9de9248SMarcel Holtmann 			memcpy(data.dev_class, info->dev_class, 3);
4540a9de9248SMarcel Holtmann 			data.clock_offset	= info->clock_offset;
4541a9de9248SMarcel Holtmann 			data.rssi		= info->rssi;
454241a96212SMarcel Holtmann 			data.ssp_mode		= 0x00;
45433175405bSJohan Hedberg 
4544af58925cSMarcel Holtmann 			flags = hci_inquiry_cache_update(hdev, &data, false);
4545af58925cSMarcel Holtmann 
454648264f06SJohan Hedberg 			mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
4547e17acd40SJohan Hedberg 					  info->dev_class, info->rssi,
4548af58925cSMarcel Holtmann 					  flags, NULL, 0, NULL, 0);
4549a9de9248SMarcel Holtmann 		}
45508d08d324SLuiz Augusto von Dentz 	} else if (skb->len == flex_array_size(ev, res1->info, ev->res1->num)) {
45518d08d324SLuiz Augusto von Dentz 		struct inquiry_info_rssi *info;
4552a9de9248SMarcel Holtmann 
45538d08d324SLuiz Augusto von Dentz 		for (i = 0; i < ev->res1->num; i++) {
4554af58925cSMarcel Holtmann 			u32 flags;
4555af58925cSMarcel Holtmann 
45568d08d324SLuiz Augusto von Dentz 			info = &ev->res1->info[i];
4557a9de9248SMarcel Holtmann 			bacpy(&data.bdaddr, &info->bdaddr);
4558a9de9248SMarcel Holtmann 			data.pscan_rep_mode	= info->pscan_rep_mode;
4559a9de9248SMarcel Holtmann 			data.pscan_period_mode	= info->pscan_period_mode;
4560a9de9248SMarcel Holtmann 			data.pscan_mode		= 0x00;
4561a9de9248SMarcel Holtmann 			memcpy(data.dev_class, info->dev_class, 3);
4562a9de9248SMarcel Holtmann 			data.clock_offset	= info->clock_offset;
4563a9de9248SMarcel Holtmann 			data.rssi		= info->rssi;
456441a96212SMarcel Holtmann 			data.ssp_mode		= 0x00;
4565af58925cSMarcel Holtmann 
4566af58925cSMarcel Holtmann 			flags = hci_inquiry_cache_update(hdev, &data, false);
4567af58925cSMarcel Holtmann 
456848264f06SJohan Hedberg 			mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
4569e17acd40SJohan Hedberg 					  info->dev_class, info->rssi,
4570af58925cSMarcel Holtmann 					  flags, NULL, 0, NULL, 0);
4571a9de9248SMarcel Holtmann 		}
45728d08d324SLuiz Augusto von Dentz 	} else {
45738d08d324SLuiz Augusto von Dentz 		bt_dev_err(hdev, "Malformed HCI Event: 0x%2.2x",
45748d08d324SLuiz Augusto von Dentz 			   HCI_EV_INQUIRY_RESULT_WITH_RSSI);
4575a9de9248SMarcel Holtmann 	}
4576a9de9248SMarcel Holtmann 
4577a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
4578a9de9248SMarcel Holtmann }
4579a9de9248SMarcel Holtmann 
45803e54c589SLuiz Augusto von Dentz static void hci_remote_ext_features_evt(struct hci_dev *hdev, void *data,
4581807deac2SGustavo Padovan 					struct sk_buff *skb)
4582a9de9248SMarcel Holtmann {
45833e54c589SLuiz Augusto von Dentz 	struct hci_ev_remote_ext_features *ev = data;
458441a96212SMarcel Holtmann 	struct hci_conn *conn;
458541a96212SMarcel Holtmann 
45863e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
458741a96212SMarcel Holtmann 
458841a96212SMarcel Holtmann 	hci_dev_lock(hdev);
458941a96212SMarcel Holtmann 
459041a96212SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
4591ccd556feSJohan Hedberg 	if (!conn)
4592ccd556feSJohan Hedberg 		goto unlock;
4593ccd556feSJohan Hedberg 
4594cad718edSJohan Hedberg 	if (ev->page < HCI_MAX_PAGES)
4595cad718edSJohan Hedberg 		memcpy(conn->features[ev->page], ev->features, 8);
4596cad718edSJohan Hedberg 
4597769be974SMarcel Holtmann 	if (!ev->status && ev->page == 0x01) {
459841a96212SMarcel Holtmann 		struct inquiry_entry *ie;
459941a96212SMarcel Holtmann 
4600cc11b9c1SAndrei Emeltchenko 		ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
4601cc11b9c1SAndrei Emeltchenko 		if (ie)
460202b7cc62SJohan Hedberg 			ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
460341a96212SMarcel Holtmann 
4604bbb0eadaSJaganath Kanakkassery 		if (ev->features[0] & LMP_HOST_SSP) {
460558a681efSJohan Hedberg 			set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
4606bbb0eadaSJaganath Kanakkassery 		} else {
4607bbb0eadaSJaganath Kanakkassery 			/* It is mandatory by the Bluetooth specification that
4608bbb0eadaSJaganath Kanakkassery 			 * Extended Inquiry Results are only used when Secure
4609bbb0eadaSJaganath Kanakkassery 			 * Simple Pairing is enabled, but some devices violate
4610bbb0eadaSJaganath Kanakkassery 			 * this.
4611bbb0eadaSJaganath Kanakkassery 			 *
4612bbb0eadaSJaganath Kanakkassery 			 * To make these devices work, the internal SSP
4613bbb0eadaSJaganath Kanakkassery 			 * enabled flag needs to be cleared if the remote host
4614bbb0eadaSJaganath Kanakkassery 			 * features do not indicate SSP support */
4615bbb0eadaSJaganath Kanakkassery 			clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
4616bbb0eadaSJaganath Kanakkassery 		}
4617eb9a8f3fSMarcel Holtmann 
4618eb9a8f3fSMarcel Holtmann 		if (ev->features[0] & LMP_HOST_SC)
4619eb9a8f3fSMarcel Holtmann 			set_bit(HCI_CONN_SC_ENABLED, &conn->flags);
462041a96212SMarcel Holtmann 	}
462141a96212SMarcel Holtmann 
4622ccd556feSJohan Hedberg 	if (conn->state != BT_CONFIG)
4623ccd556feSJohan Hedberg 		goto unlock;
4624ccd556feSJohan Hedberg 
4625671267bfSJohan Hedberg 	if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
4626127178d2SJohan Hedberg 		struct hci_cp_remote_name_req cp;
4627127178d2SJohan Hedberg 		memset(&cp, 0, sizeof(cp));
4628127178d2SJohan Hedberg 		bacpy(&cp.bdaddr, &conn->dst);
4629127178d2SJohan Hedberg 		cp.pscan_rep_mode = 0x02;
4630127178d2SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
4631b644ba33SJohan Hedberg 	} else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
46321c6ed31bSYu Liu 		mgmt_device_connected(hdev, conn, NULL, 0);
4633392599b9SJohan Hedberg 
4634127178d2SJohan Hedberg 	if (!hci_outgoing_auth_needed(hdev, conn)) {
4635769be974SMarcel Holtmann 		conn->state = BT_CONNECTED;
4636539c496dSJohan Hedberg 		hci_connect_cfm(conn, ev->status);
463776a68ba0SDavid Herrmann 		hci_conn_drop(conn);
4638769be974SMarcel Holtmann 	}
4639769be974SMarcel Holtmann 
4640ccd556feSJohan Hedberg unlock:
464141a96212SMarcel Holtmann 	hci_dev_unlock(hdev);
4642a9de9248SMarcel Holtmann }
4643a9de9248SMarcel Holtmann 
46443e54c589SLuiz Augusto von Dentz static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data,
4645807deac2SGustavo Padovan 				       struct sk_buff *skb)
4646a9de9248SMarcel Holtmann {
46473e54c589SLuiz Augusto von Dentz 	struct hci_ev_sync_conn_complete *ev = data;
4648b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
4649b6a0dc82SMarcel Holtmann 
46503e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
4651b6a0dc82SMarcel Holtmann 
4652b6a0dc82SMarcel Holtmann 	hci_dev_lock(hdev);
4653b6a0dc82SMarcel Holtmann 
4654b6a0dc82SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
46559dc0a3afSMarcel Holtmann 	if (!conn) {
46569dc0a3afSMarcel Holtmann 		if (ev->link_type == ESCO_LINK)
46579dc0a3afSMarcel Holtmann 			goto unlock;
46589dc0a3afSMarcel Holtmann 
4659618353b1SKuba Pawlak 		/* When the link type in the event indicates SCO connection
4660618353b1SKuba Pawlak 		 * and lookup of the connection object fails, then check
4661618353b1SKuba Pawlak 		 * if an eSCO connection object exists.
4662618353b1SKuba Pawlak 		 *
4663618353b1SKuba Pawlak 		 * The core limits the synchronous connections to either
4664618353b1SKuba Pawlak 		 * SCO or eSCO. The eSCO connection is preferred and tried
4665618353b1SKuba Pawlak 		 * to be setup first and until successfully established,
4666618353b1SKuba Pawlak 		 * the link type will be hinted as eSCO.
4667618353b1SKuba Pawlak 		 */
46689dc0a3afSMarcel Holtmann 		conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
4669b6a0dc82SMarcel Holtmann 		if (!conn)
4670b6a0dc82SMarcel Holtmann 			goto unlock;
46719dc0a3afSMarcel Holtmann 	}
46729dc0a3afSMarcel Holtmann 
4673732547f9SMarcel Holtmann 	switch (ev->status) {
4674732547f9SMarcel Holtmann 	case 0x00:
467592fe24a7SDesmond Cheong Zhi Xi 		/* The synchronous connection complete event should only be
467692fe24a7SDesmond Cheong Zhi Xi 		 * sent once per new connection. Receiving a successful
467792fe24a7SDesmond Cheong Zhi Xi 		 * complete event when the connection status is already
467892fe24a7SDesmond Cheong Zhi Xi 		 * BT_CONNECTED means that the device is misbehaving and sent
467992fe24a7SDesmond Cheong Zhi Xi 		 * multiple complete event packets for the same new connection.
468092fe24a7SDesmond Cheong Zhi Xi 		 *
468192fe24a7SDesmond Cheong Zhi Xi 		 * Registering the device more than once can corrupt kernel
468292fe24a7SDesmond Cheong Zhi Xi 		 * memory, hence upon detecting this invalid event, we report
468392fe24a7SDesmond Cheong Zhi Xi 		 * an error and ignore the packet.
468492fe24a7SDesmond Cheong Zhi Xi 		 */
468592fe24a7SDesmond Cheong Zhi Xi 		if (conn->state == BT_CONNECTED) {
468692fe24a7SDesmond Cheong Zhi Xi 			bt_dev_err(hdev, "Ignoring connect complete event for existing connection");
468792fe24a7SDesmond Cheong Zhi Xi 			goto unlock;
468892fe24a7SDesmond Cheong Zhi Xi 		}
468992fe24a7SDesmond Cheong Zhi Xi 
4690732547f9SMarcel Holtmann 		conn->handle = __le16_to_cpu(ev->handle);
4691732547f9SMarcel Holtmann 		conn->state  = BT_CONNECTED;
4692618353b1SKuba Pawlak 		conn->type   = ev->link_type;
4693732547f9SMarcel Holtmann 
469423b9ceb7SMarcel Holtmann 		hci_debugfs_create_conn(conn);
4695732547f9SMarcel Holtmann 		hci_conn_add_sysfs(conn);
4696732547f9SMarcel Holtmann 		break;
4697732547f9SMarcel Holtmann 
469881218d20SNick Pelly 	case 0x10:	/* Connection Accept Timeout */
46991a4c958cSFrédéric Dalleau 	case 0x0d:	/* Connection Rejected due to Limited Resources */
4700705e5711SStephen Coe 	case 0x11:	/* Unsupported Feature or Parameter Value */
4701732547f9SMarcel Holtmann 	case 0x1c:	/* SCO interval rejected */
47021038a00bSNick Pelly 	case 0x1a:	/* Unsupported Remote Feature */
470356b5453aSHsin-Yu Chao 	case 0x1e:	/* Invalid LMP Parameters */
4704732547f9SMarcel Holtmann 	case 0x1f:	/* Unspecified error */
470527539bc4SAndrew Earl 	case 0x20:	/* Unsupported LMP Parameter value */
47062dea632fSFrédéric Dalleau 		if (conn->out) {
4707efc7688bSMarcel Holtmann 			conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
4708efc7688bSMarcel Holtmann 					(hdev->esco_type & EDR_ESCO_MASK);
47092dea632fSFrédéric Dalleau 			if (hci_setup_sync(conn, conn->link->handle))
4710efc7688bSMarcel Holtmann 				goto unlock;
4711efc7688bSMarcel Holtmann 		}
471219186c7bSGustavo A. R. Silva 		fallthrough;
4713efc7688bSMarcel Holtmann 
4714732547f9SMarcel Holtmann 	default:
4715b6a0dc82SMarcel Holtmann 		conn->state = BT_CLOSED;
4716732547f9SMarcel Holtmann 		break;
4717732547f9SMarcel Holtmann 	}
4718b6a0dc82SMarcel Holtmann 
47191f8330eaSSathish Narsimman 	bt_dev_dbg(hdev, "SCO connected with air mode: %02x", ev->air_mode);
4720f4f9fa0cSChethan T N 	/* Notify only in case of SCO over HCI transport data path which
4721f4f9fa0cSChethan T N 	 * is zero and non-zero value shall be non-HCI transport data path
4722f4f9fa0cSChethan T N 	 */
4723a27c519aSJackie Liu 	if (conn->codec.data_path == 0 && hdev->notify) {
4724a27c519aSJackie Liu 		switch (ev->air_mode) {
4725a27c519aSJackie Liu 		case 0x02:
4726a27c519aSJackie Liu 			hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD);
4727a27c519aSJackie Liu 			break;
4728a27c519aSJackie Liu 		case 0x03:
4729a27c519aSJackie Liu 			hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_TRANSP);
4730a27c519aSJackie Liu 			break;
4731a27c519aSJackie Liu 		}
4732f4f9fa0cSChethan T N 	}
4733f4f9fa0cSChethan T N 
4734539c496dSJohan Hedberg 	hci_connect_cfm(conn, ev->status);
4735b6a0dc82SMarcel Holtmann 	if (ev->status)
4736b6a0dc82SMarcel Holtmann 		hci_conn_del(conn);
4737b6a0dc82SMarcel Holtmann 
4738b6a0dc82SMarcel Holtmann unlock:
4739b6a0dc82SMarcel Holtmann 	hci_dev_unlock(hdev);
4740a9de9248SMarcel Holtmann }
4741a9de9248SMarcel Holtmann 
4742efdcf8e3SMarcel Holtmann static inline size_t eir_get_length(u8 *eir, size_t eir_len)
4743efdcf8e3SMarcel Holtmann {
4744efdcf8e3SMarcel Holtmann 	size_t parsed = 0;
4745efdcf8e3SMarcel Holtmann 
4746efdcf8e3SMarcel Holtmann 	while (parsed < eir_len) {
4747efdcf8e3SMarcel Holtmann 		u8 field_len = eir[0];
4748efdcf8e3SMarcel Holtmann 
4749efdcf8e3SMarcel Holtmann 		if (field_len == 0)
4750efdcf8e3SMarcel Holtmann 			return parsed;
4751efdcf8e3SMarcel Holtmann 
4752efdcf8e3SMarcel Holtmann 		parsed += field_len + 1;
4753efdcf8e3SMarcel Holtmann 		eir += field_len + 1;
4754efdcf8e3SMarcel Holtmann 	}
4755efdcf8e3SMarcel Holtmann 
4756efdcf8e3SMarcel Holtmann 	return eir_len;
4757efdcf8e3SMarcel Holtmann }
4758efdcf8e3SMarcel Holtmann 
47593e54c589SLuiz Augusto von Dentz static void hci_extended_inquiry_result_evt(struct hci_dev *hdev, void *edata,
4760807deac2SGustavo Padovan 					    struct sk_buff *skb)
4761a9de9248SMarcel Holtmann {
47623e54c589SLuiz Augusto von Dentz 	struct hci_ev_ext_inquiry_result *ev = edata;
4763a9de9248SMarcel Holtmann 	struct inquiry_data data;
47649d939d94SVishal Agarwal 	size_t eir_len;
476570a6b8deSLuiz Augusto von Dentz 	int i;
4766a9de9248SMarcel Holtmann 
476770a6b8deSLuiz Augusto von Dentz 	if (!hci_ev_skb_pull(hdev, skb, HCI_EV_EXTENDED_INQUIRY_RESULT,
476870a6b8deSLuiz Augusto von Dentz 			     flex_array_size(ev, info, ev->num)))
476970a6b8deSLuiz Augusto von Dentz 		return;
477070a6b8deSLuiz Augusto von Dentz 
47713e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "num %d", ev->num);
477270a6b8deSLuiz Augusto von Dentz 
477370a6b8deSLuiz Augusto von Dentz 	if (!ev->num)
4774a9de9248SMarcel Holtmann 		return;
4775a9de9248SMarcel Holtmann 
4776d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ))
47771519cc17SAndre Guedes 		return;
47781519cc17SAndre Guedes 
4779a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
4780a9de9248SMarcel Holtmann 
478170a6b8deSLuiz Augusto von Dentz 	for (i = 0; i < ev->num; i++) {
478270a6b8deSLuiz Augusto von Dentz 		struct extended_inquiry_info *info = &ev->info[i];
4783af58925cSMarcel Holtmann 		u32 flags;
4784af58925cSMarcel Holtmann 		bool name_known;
4785561aafbcSJohan Hedberg 
4786a9de9248SMarcel Holtmann 		bacpy(&data.bdaddr, &info->bdaddr);
4787a9de9248SMarcel Holtmann 		data.pscan_rep_mode	= info->pscan_rep_mode;
4788a9de9248SMarcel Holtmann 		data.pscan_period_mode	= info->pscan_period_mode;
4789a9de9248SMarcel Holtmann 		data.pscan_mode		= 0x00;
4790a9de9248SMarcel Holtmann 		memcpy(data.dev_class, info->dev_class, 3);
4791a9de9248SMarcel Holtmann 		data.clock_offset	= info->clock_offset;
4792a9de9248SMarcel Holtmann 		data.rssi		= info->rssi;
479341a96212SMarcel Holtmann 		data.ssp_mode		= 0x01;
4794561aafbcSJohan Hedberg 
4795d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_MGMT))
47960d3b7f64SJohan Hedberg 			name_known = eir_get_data(info->data,
47974ddb1930SJohan Hedberg 						  sizeof(info->data),
47980d3b7f64SJohan Hedberg 						  EIR_NAME_COMPLETE, NULL);
4799561aafbcSJohan Hedberg 		else
4800561aafbcSJohan Hedberg 			name_known = true;
4801561aafbcSJohan Hedberg 
4802af58925cSMarcel Holtmann 		flags = hci_inquiry_cache_update(hdev, &data, name_known);
4803af58925cSMarcel Holtmann 
48049d939d94SVishal Agarwal 		eir_len = eir_get_length(info->data, sizeof(info->data));
4805af58925cSMarcel Holtmann 
480648264f06SJohan Hedberg 		mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
4807af58925cSMarcel Holtmann 				  info->dev_class, info->rssi,
4808af58925cSMarcel Holtmann 				  flags, info->data, eir_len, NULL, 0);
4809a9de9248SMarcel Holtmann 	}
4810a9de9248SMarcel Holtmann 
4811a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
4812a9de9248SMarcel Holtmann }
4813a9de9248SMarcel Holtmann 
48143e54c589SLuiz Augusto von Dentz static void hci_key_refresh_complete_evt(struct hci_dev *hdev, void *data,
48151c2e0041SJohan Hedberg 					 struct sk_buff *skb)
48161c2e0041SJohan Hedberg {
48173e54c589SLuiz Augusto von Dentz 	struct hci_ev_key_refresh_complete *ev = data;
48181c2e0041SJohan Hedberg 	struct hci_conn *conn;
48191c2e0041SJohan Hedberg 
48203e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x handle 0x%4.4x", ev->status,
48211c2e0041SJohan Hedberg 		   __le16_to_cpu(ev->handle));
48221c2e0041SJohan Hedberg 
48231c2e0041SJohan Hedberg 	hci_dev_lock(hdev);
48241c2e0041SJohan Hedberg 
48251c2e0041SJohan Hedberg 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
48261c2e0041SJohan Hedberg 	if (!conn)
48271c2e0041SJohan Hedberg 		goto unlock;
48281c2e0041SJohan Hedberg 
48299eb1fbfaSJohan Hedberg 	/* For BR/EDR the necessary steps are taken through the
48309eb1fbfaSJohan Hedberg 	 * auth_complete event.
48319eb1fbfaSJohan Hedberg 	 */
48329eb1fbfaSJohan Hedberg 	if (conn->type != LE_LINK)
48339eb1fbfaSJohan Hedberg 		goto unlock;
48349eb1fbfaSJohan Hedberg 
48351c2e0041SJohan Hedberg 	if (!ev->status)
48361c2e0041SJohan Hedberg 		conn->sec_level = conn->pending_sec_level;
48371c2e0041SJohan Hedberg 
48381c2e0041SJohan Hedberg 	clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
48391c2e0041SJohan Hedberg 
48401c2e0041SJohan Hedberg 	if (ev->status && conn->state == BT_CONNECTED) {
4841bed71748SAndre Guedes 		hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
484276a68ba0SDavid Herrmann 		hci_conn_drop(conn);
48431c2e0041SJohan Hedberg 		goto unlock;
48441c2e0041SJohan Hedberg 	}
48451c2e0041SJohan Hedberg 
48461c2e0041SJohan Hedberg 	if (conn->state == BT_CONFIG) {
48471c2e0041SJohan Hedberg 		if (!ev->status)
48481c2e0041SJohan Hedberg 			conn->state = BT_CONNECTED;
48491c2e0041SJohan Hedberg 
4850539c496dSJohan Hedberg 		hci_connect_cfm(conn, ev->status);
485176a68ba0SDavid Herrmann 		hci_conn_drop(conn);
48521c2e0041SJohan Hedberg 	} else {
48531c2e0041SJohan Hedberg 		hci_auth_cfm(conn, ev->status);
48541c2e0041SJohan Hedberg 
48551c2e0041SJohan Hedberg 		hci_conn_hold(conn);
48561c2e0041SJohan Hedberg 		conn->disc_timeout = HCI_DISCONN_TIMEOUT;
485776a68ba0SDavid Herrmann 		hci_conn_drop(conn);
48581c2e0041SJohan Hedberg 	}
48591c2e0041SJohan Hedberg 
48601c2e0041SJohan Hedberg unlock:
48611c2e0041SJohan Hedberg 	hci_dev_unlock(hdev);
48621c2e0041SJohan Hedberg }
48631c2e0041SJohan Hedberg 
48646039aa73SGustavo Padovan static u8 hci_get_auth_req(struct hci_conn *conn)
486517fa4b9dSJohan Hedberg {
486617fa4b9dSJohan Hedberg 	/* If remote requests no-bonding follow that lead */
4867acabae96SMikel Astiz 	if (conn->remote_auth == HCI_AT_NO_BONDING ||
4868acabae96SMikel Astiz 	    conn->remote_auth == HCI_AT_NO_BONDING_MITM)
486958797bf7SWaldemar Rymarkiewicz 		return conn->remote_auth | (conn->auth_type & 0x01);
487017fa4b9dSJohan Hedberg 
4871b7f94c88SMikel Astiz 	/* If both remote and local have enough IO capabilities, require
4872b7f94c88SMikel Astiz 	 * MITM protection
4873b7f94c88SMikel Astiz 	 */
4874b7f94c88SMikel Astiz 	if (conn->remote_cap != HCI_IO_NO_INPUT_OUTPUT &&
4875b7f94c88SMikel Astiz 	    conn->io_capability != HCI_IO_NO_INPUT_OUTPUT)
4876b7f94c88SMikel Astiz 		return conn->remote_auth | 0x01;
4877b7f94c88SMikel Astiz 
48787e74170aSTimo Mueller 	/* No MITM protection possible so ignore remote requirement */
48797e74170aSTimo Mueller 	return (conn->remote_auth & ~0x01) | (conn->auth_type & 0x01);
488017fa4b9dSJohan Hedberg }
488117fa4b9dSJohan Hedberg 
4882a83ed81eSMarcel Holtmann static u8 bredr_oob_data_present(struct hci_conn *conn)
4883a83ed81eSMarcel Holtmann {
4884a83ed81eSMarcel Holtmann 	struct hci_dev *hdev = conn->hdev;
4885a83ed81eSMarcel Holtmann 	struct oob_data *data;
4886a83ed81eSMarcel Holtmann 
4887a83ed81eSMarcel Holtmann 	data = hci_find_remote_oob_data(hdev, &conn->dst, BDADDR_BREDR);
4888a83ed81eSMarcel Holtmann 	if (!data)
4889a83ed81eSMarcel Holtmann 		return 0x00;
4890a83ed81eSMarcel Holtmann 
4891bf21d793SMarcel Holtmann 	if (bredr_sc_enabled(hdev)) {
4892bf21d793SMarcel Holtmann 		/* When Secure Connections is enabled, then just
4893bf21d793SMarcel Holtmann 		 * return the present value stored with the OOB
4894bf21d793SMarcel Holtmann 		 * data. The stored value contains the right present
4895bf21d793SMarcel Holtmann 		 * information. However it can only be trusted when
4896bf21d793SMarcel Holtmann 		 * not in Secure Connection Only mode.
4897aa5b0345SMarcel Holtmann 		 */
4898d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_SC_ONLY))
4899bf21d793SMarcel Holtmann 			return data->present;
4900bf21d793SMarcel Holtmann 
4901bf21d793SMarcel Holtmann 		/* When Secure Connections Only mode is enabled, then
4902bf21d793SMarcel Holtmann 		 * the P-256 values are required. If they are not
4903bf21d793SMarcel Holtmann 		 * available, then do not declare that OOB data is
4904bf21d793SMarcel Holtmann 		 * present.
4905bf21d793SMarcel Holtmann 		 */
4906bf21d793SMarcel Holtmann 		if (!memcmp(data->rand256, ZERO_KEY, 16) ||
4907bf21d793SMarcel Holtmann 		    !memcmp(data->hash256, ZERO_KEY, 16))
4908aa5b0345SMarcel Holtmann 			return 0x00;
4909aa5b0345SMarcel Holtmann 
4910bf21d793SMarcel Holtmann 		return 0x02;
4911bf21d793SMarcel Holtmann 	}
4912659c7fb0SMarcel Holtmann 
4913659c7fb0SMarcel Holtmann 	/* When Secure Connections is not enabled or actually
4914659c7fb0SMarcel Holtmann 	 * not supported by the hardware, then check that if
4915659c7fb0SMarcel Holtmann 	 * P-192 data values are present.
4916659c7fb0SMarcel Holtmann 	 */
4917659c7fb0SMarcel Holtmann 	if (!memcmp(data->rand192, ZERO_KEY, 16) ||
4918659c7fb0SMarcel Holtmann 	    !memcmp(data->hash192, ZERO_KEY, 16))
4919659c7fb0SMarcel Holtmann 		return 0x00;
4920659c7fb0SMarcel Holtmann 
4921a83ed81eSMarcel Holtmann 	return 0x01;
4922659c7fb0SMarcel Holtmann }
4923a83ed81eSMarcel Holtmann 
49243e54c589SLuiz Augusto von Dentz static void hci_io_capa_request_evt(struct hci_dev *hdev, void *data,
49253e54c589SLuiz Augusto von Dentz 				    struct sk_buff *skb)
49260493684eSMarcel Holtmann {
49273e54c589SLuiz Augusto von Dentz 	struct hci_ev_io_capa_request *ev = data;
49280493684eSMarcel Holtmann 	struct hci_conn *conn;
49290493684eSMarcel Holtmann 
49303e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
49310493684eSMarcel Holtmann 
49320493684eSMarcel Holtmann 	hci_dev_lock(hdev);
49330493684eSMarcel Holtmann 
49340493684eSMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
493503b555e1SJohan Hedberg 	if (!conn)
493603b555e1SJohan Hedberg 		goto unlock;
493703b555e1SJohan Hedberg 
49380493684eSMarcel Holtmann 	hci_conn_hold(conn);
49390493684eSMarcel Holtmann 
4940d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
494103b555e1SJohan Hedberg 		goto unlock;
494203b555e1SJohan Hedberg 
49432f407f0aSJohan Hedberg 	/* Allow pairing if we're pairable, the initiators of the
49442f407f0aSJohan Hedberg 	 * pairing or if the remote is not requesting bonding.
49452f407f0aSJohan Hedberg 	 */
4946d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_BONDABLE) ||
49472f407f0aSJohan Hedberg 	    test_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags) ||
494803b555e1SJohan Hedberg 	    (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
494917fa4b9dSJohan Hedberg 		struct hci_cp_io_capability_reply cp;
495017fa4b9dSJohan Hedberg 
495117fa4b9dSJohan Hedberg 		bacpy(&cp.bdaddr, &ev->bdaddr);
49527a7f1e7cSHemant Gupta 		/* Change the IO capability from KeyboardDisplay
49537a7f1e7cSHemant Gupta 		 * to DisplayYesNo as it is not supported by BT spec. */
49547a7f1e7cSHemant Gupta 		cp.capability = (conn->io_capability == 0x04) ?
4955a767631aSMikel Astiz 				HCI_IO_DISPLAY_YESNO : conn->io_capability;
4956b7f94c88SMikel Astiz 
4957b7f94c88SMikel Astiz 		/* If we are initiators, there is no remote information yet */
4958b7f94c88SMikel Astiz 		if (conn->remote_auth == 0xff) {
4959b16c6604SMikel Astiz 			/* Request MITM protection if our IO caps allow it
49604ad51a75SJohan Hedberg 			 * except for the no-bonding case.
4961b16c6604SMikel Astiz 			 */
49626fd6b915SMikel Astiz 			if (conn->io_capability != HCI_IO_NO_INPUT_OUTPUT &&
49639f743d74SJohan Hedberg 			    conn->auth_type != HCI_AT_NO_BONDING)
49646c53823aSJohan Hedberg 				conn->auth_type |= 0x01;
4965b7f94c88SMikel Astiz 		} else {
49667cbc9bd9SJohan Hedberg 			conn->auth_type = hci_get_auth_req(conn);
4967b7f94c88SMikel Astiz 		}
496817fa4b9dSJohan Hedberg 
496982c295b1SJohan Hedberg 		/* If we're not bondable, force one of the non-bondable
497082c295b1SJohan Hedberg 		 * authentication requirement values.
497182c295b1SJohan Hedberg 		 */
4972d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_BONDABLE))
497382c295b1SJohan Hedberg 			conn->auth_type &= HCI_AT_NO_BONDING_MITM;
497482c295b1SJohan Hedberg 
497582c295b1SJohan Hedberg 		cp.authentication = conn->auth_type;
4976a83ed81eSMarcel Holtmann 		cp.oob_data = bredr_oob_data_present(conn);
4977ce85ee13SSzymon Janc 
497817fa4b9dSJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
497917fa4b9dSJohan Hedberg 			     sizeof(cp), &cp);
498003b555e1SJohan Hedberg 	} else {
498103b555e1SJohan Hedberg 		struct hci_cp_io_capability_neg_reply cp;
498203b555e1SJohan Hedberg 
498303b555e1SJohan Hedberg 		bacpy(&cp.bdaddr, &ev->bdaddr);
49849f5a0d7bSAndrei Emeltchenko 		cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
498503b555e1SJohan Hedberg 
498603b555e1SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
498703b555e1SJohan Hedberg 			     sizeof(cp), &cp);
498803b555e1SJohan Hedberg 	}
498903b555e1SJohan Hedberg 
499003b555e1SJohan Hedberg unlock:
499103b555e1SJohan Hedberg 	hci_dev_unlock(hdev);
499203b555e1SJohan Hedberg }
499303b555e1SJohan Hedberg 
49943e54c589SLuiz Augusto von Dentz static void hci_io_capa_reply_evt(struct hci_dev *hdev, void *data,
49953e54c589SLuiz Augusto von Dentz 				  struct sk_buff *skb)
499603b555e1SJohan Hedberg {
49973e54c589SLuiz Augusto von Dentz 	struct hci_ev_io_capa_reply *ev = data;
499803b555e1SJohan Hedberg 	struct hci_conn *conn;
499903b555e1SJohan Hedberg 
50003e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
500103b555e1SJohan Hedberg 
500203b555e1SJohan Hedberg 	hci_dev_lock(hdev);
500303b555e1SJohan Hedberg 
500403b555e1SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
500503b555e1SJohan Hedberg 	if (!conn)
500603b555e1SJohan Hedberg 		goto unlock;
500703b555e1SJohan Hedberg 
500803b555e1SJohan Hedberg 	conn->remote_cap = ev->capability;
500903b555e1SJohan Hedberg 	conn->remote_auth = ev->authentication;
501003b555e1SJohan Hedberg 
501103b555e1SJohan Hedberg unlock:
50120493684eSMarcel Holtmann 	hci_dev_unlock(hdev);
50130493684eSMarcel Holtmann }
50140493684eSMarcel Holtmann 
50153e54c589SLuiz Augusto von Dentz static void hci_user_confirm_request_evt(struct hci_dev *hdev, void *data,
5016a5c29683SJohan Hedberg 					 struct sk_buff *skb)
5017a5c29683SJohan Hedberg {
50183e54c589SLuiz Augusto von Dentz 	struct hci_ev_user_confirm_req *ev = data;
501955bc1a37SJohan Hedberg 	int loc_mitm, rem_mitm, confirm_hint = 0;
50207a828908SJohan Hedberg 	struct hci_conn *conn;
5021a5c29683SJohan Hedberg 
50223e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
5023a5c29683SJohan Hedberg 
5024a5c29683SJohan Hedberg 	hci_dev_lock(hdev);
5025a5c29683SJohan Hedberg 
5026d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
50277a828908SJohan Hedberg 		goto unlock;
50287a828908SJohan Hedberg 
50297a828908SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
50307a828908SJohan Hedberg 	if (!conn)
50317a828908SJohan Hedberg 		goto unlock;
50327a828908SJohan Hedberg 
50337a828908SJohan Hedberg 	loc_mitm = (conn->auth_type & 0x01);
50347a828908SJohan Hedberg 	rem_mitm = (conn->remote_auth & 0x01);
50357a828908SJohan Hedberg 
50367a828908SJohan Hedberg 	/* If we require MITM but the remote device can't provide that
50376c53823aSJohan Hedberg 	 * (it has NoInputNoOutput) then reject the confirmation
50386c53823aSJohan Hedberg 	 * request. We check the security level here since it doesn't
50396c53823aSJohan Hedberg 	 * necessarily match conn->auth_type.
50406fd6b915SMikel Astiz 	 */
50416c53823aSJohan Hedberg 	if (conn->pending_sec_level > BT_SECURITY_MEDIUM &&
50426c53823aSJohan Hedberg 	    conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
50433e54c589SLuiz Augusto von Dentz 		bt_dev_dbg(hdev, "Rejecting request: remote device can't provide MITM");
50447a828908SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
50457a828908SJohan Hedberg 			     sizeof(ev->bdaddr), &ev->bdaddr);
50467a828908SJohan Hedberg 		goto unlock;
50477a828908SJohan Hedberg 	}
50487a828908SJohan Hedberg 
50497a828908SJohan Hedberg 	/* If no side requires MITM protection; auto-accept */
5050a767631aSMikel Astiz 	if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
5051a767631aSMikel Astiz 	    (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
505255bc1a37SJohan Hedberg 
505355bc1a37SJohan Hedberg 		/* If we're not the initiators request authorization to
505455bc1a37SJohan Hedberg 		 * proceed from user space (mgmt_user_confirm with
5055ba15a58bSJohan Hedberg 		 * confirm_hint set to 1). The exception is if neither
505602f3e254SJohan Hedberg 		 * side had MITM or if the local IO capability is
505702f3e254SJohan Hedberg 		 * NoInputNoOutput, in which case we do auto-accept
5058ba15a58bSJohan Hedberg 		 */
5059ba15a58bSJohan Hedberg 		if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) &&
506002f3e254SJohan Hedberg 		    conn->io_capability != HCI_IO_NO_INPUT_OUTPUT &&
5061ba15a58bSJohan Hedberg 		    (loc_mitm || rem_mitm)) {
50623e54c589SLuiz Augusto von Dentz 			bt_dev_dbg(hdev, "Confirming auto-accept as acceptor");
506355bc1a37SJohan Hedberg 			confirm_hint = 1;
506455bc1a37SJohan Hedberg 			goto confirm;
506555bc1a37SJohan Hedberg 		}
506655bc1a37SJohan Hedberg 
5067cee5f20fSHoward Chung 		/* If there already exists link key in local host, leave the
5068cee5f20fSHoward Chung 		 * decision to user space since the remote device could be
5069cee5f20fSHoward Chung 		 * legitimate or malicious.
5070cee5f20fSHoward Chung 		 */
5071cee5f20fSHoward Chung 		if (hci_find_link_key(hdev, &ev->bdaddr)) {
5072cee5f20fSHoward Chung 			bt_dev_dbg(hdev, "Local host already has link key");
5073cee5f20fSHoward Chung 			confirm_hint = 1;
5074cee5f20fSHoward Chung 			goto confirm;
5075cee5f20fSHoward Chung 		}
5076cee5f20fSHoward Chung 
50779f61656aSJohan Hedberg 		BT_DBG("Auto-accept of user confirmation with %ums delay",
50789f61656aSJohan Hedberg 		       hdev->auto_accept_delay);
50799f61656aSJohan Hedberg 
50809f61656aSJohan Hedberg 		if (hdev->auto_accept_delay > 0) {
50819f61656aSJohan Hedberg 			int delay = msecs_to_jiffies(hdev->auto_accept_delay);
50827bc18d9dSJohan Hedberg 			queue_delayed_work(conn->hdev->workqueue,
50837bc18d9dSJohan Hedberg 					   &conn->auto_accept_work, delay);
50849f61656aSJohan Hedberg 			goto unlock;
50859f61656aSJohan Hedberg 		}
50869f61656aSJohan Hedberg 
50877a828908SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
50887a828908SJohan Hedberg 			     sizeof(ev->bdaddr), &ev->bdaddr);
50897a828908SJohan Hedberg 		goto unlock;
50907a828908SJohan Hedberg 	}
50917a828908SJohan Hedberg 
509255bc1a37SJohan Hedberg confirm:
509339adbffeSJohan Hedberg 	mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0,
509439adbffeSJohan Hedberg 				  le32_to_cpu(ev->passkey), confirm_hint);
5095a5c29683SJohan Hedberg 
50967a828908SJohan Hedberg unlock:
5097a5c29683SJohan Hedberg 	hci_dev_unlock(hdev);
5098a5c29683SJohan Hedberg }
5099a5c29683SJohan Hedberg 
51003e54c589SLuiz Augusto von Dentz static void hci_user_passkey_request_evt(struct hci_dev *hdev, void *data,
51011143d458SBrian Gix 					 struct sk_buff *skb)
51021143d458SBrian Gix {
51033e54c589SLuiz Augusto von Dentz 	struct hci_ev_user_passkey_req *ev = data;
5104ae61a10dSLuiz Augusto von Dentz 
51053e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
51061143d458SBrian Gix 
5107d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
5108272d90dfSJohan Hedberg 		mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
51091143d458SBrian Gix }
51101143d458SBrian Gix 
51113e54c589SLuiz Augusto von Dentz static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
511292a25256SJohan Hedberg 					struct sk_buff *skb)
511392a25256SJohan Hedberg {
51143e54c589SLuiz Augusto von Dentz 	struct hci_ev_user_passkey_notify *ev = data;
511592a25256SJohan Hedberg 	struct hci_conn *conn;
511692a25256SJohan Hedberg 
51173e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
511892a25256SJohan Hedberg 
511992a25256SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
512092a25256SJohan Hedberg 	if (!conn)
512192a25256SJohan Hedberg 		return;
512292a25256SJohan Hedberg 
512392a25256SJohan Hedberg 	conn->passkey_notify = __le32_to_cpu(ev->passkey);
512492a25256SJohan Hedberg 	conn->passkey_entered = 0;
512592a25256SJohan Hedberg 
5126d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
512792a25256SJohan Hedberg 		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
512892a25256SJohan Hedberg 					 conn->dst_type, conn->passkey_notify,
512992a25256SJohan Hedberg 					 conn->passkey_entered);
513092a25256SJohan Hedberg }
513192a25256SJohan Hedberg 
51323e54c589SLuiz Augusto von Dentz static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
51333e54c589SLuiz Augusto von Dentz 				    struct sk_buff *skb)
513492a25256SJohan Hedberg {
51353e54c589SLuiz Augusto von Dentz 	struct hci_ev_keypress_notify *ev = data;
513692a25256SJohan Hedberg 	struct hci_conn *conn;
513792a25256SJohan Hedberg 
51383e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
513992a25256SJohan Hedberg 
514092a25256SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
514192a25256SJohan Hedberg 	if (!conn)
514292a25256SJohan Hedberg 		return;
514392a25256SJohan Hedberg 
514492a25256SJohan Hedberg 	switch (ev->type) {
514592a25256SJohan Hedberg 	case HCI_KEYPRESS_STARTED:
514692a25256SJohan Hedberg 		conn->passkey_entered = 0;
514792a25256SJohan Hedberg 		return;
514892a25256SJohan Hedberg 
514992a25256SJohan Hedberg 	case HCI_KEYPRESS_ENTERED:
515092a25256SJohan Hedberg 		conn->passkey_entered++;
515192a25256SJohan Hedberg 		break;
515292a25256SJohan Hedberg 
515392a25256SJohan Hedberg 	case HCI_KEYPRESS_ERASED:
515492a25256SJohan Hedberg 		conn->passkey_entered--;
515592a25256SJohan Hedberg 		break;
515692a25256SJohan Hedberg 
515792a25256SJohan Hedberg 	case HCI_KEYPRESS_CLEARED:
515892a25256SJohan Hedberg 		conn->passkey_entered = 0;
515992a25256SJohan Hedberg 		break;
516092a25256SJohan Hedberg 
516192a25256SJohan Hedberg 	case HCI_KEYPRESS_COMPLETED:
516292a25256SJohan Hedberg 		return;
516392a25256SJohan Hedberg 	}
516492a25256SJohan Hedberg 
5165d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
516692a25256SJohan Hedberg 		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
516792a25256SJohan Hedberg 					 conn->dst_type, conn->passkey_notify,
516892a25256SJohan Hedberg 					 conn->passkey_entered);
516992a25256SJohan Hedberg }
517092a25256SJohan Hedberg 
51713e54c589SLuiz Augusto von Dentz static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,
5172807deac2SGustavo Padovan 					 struct sk_buff *skb)
51730493684eSMarcel Holtmann {
51743e54c589SLuiz Augusto von Dentz 	struct hci_ev_simple_pair_complete *ev = data;
51750493684eSMarcel Holtmann 	struct hci_conn *conn;
51760493684eSMarcel Holtmann 
51773e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
51780493684eSMarcel Holtmann 
51790493684eSMarcel Holtmann 	hci_dev_lock(hdev);
51800493684eSMarcel Holtmann 
51810493684eSMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
51822a611692SJohan Hedberg 	if (!conn)
51832a611692SJohan Hedberg 		goto unlock;
51842a611692SJohan Hedberg 
5185c1d4fa7aSJohan Hedberg 	/* Reset the authentication requirement to unknown */
5186c1d4fa7aSJohan Hedberg 	conn->remote_auth = 0xff;
5187c1d4fa7aSJohan Hedberg 
51882a611692SJohan Hedberg 	/* To avoid duplicate auth_failed events to user space we check
51892a611692SJohan Hedberg 	 * the HCI_CONN_AUTH_PEND flag which will be set if we
51902a611692SJohan Hedberg 	 * initiated the authentication. A traditional auth_complete
51912a611692SJohan Hedberg 	 * event gets always produced as initiator and is also mapped to
51922a611692SJohan Hedberg 	 * the mgmt_auth_failed event */
5193fa1bd918SMikel Astiz 	if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
5194e1e930f5SJohan Hedberg 		mgmt_auth_failed(conn, ev->status);
51952a611692SJohan Hedberg 
519676a68ba0SDavid Herrmann 	hci_conn_drop(conn);
51970493684eSMarcel Holtmann 
51982a611692SJohan Hedberg unlock:
51990493684eSMarcel Holtmann 	hci_dev_unlock(hdev);
52000493684eSMarcel Holtmann }
52010493684eSMarcel Holtmann 
52023e54c589SLuiz Augusto von Dentz static void hci_remote_host_features_evt(struct hci_dev *hdev, void *data,
5203807deac2SGustavo Padovan 					 struct sk_buff *skb)
520441a96212SMarcel Holtmann {
52053e54c589SLuiz Augusto von Dentz 	struct hci_ev_remote_host_features *ev = data;
520641a96212SMarcel Holtmann 	struct inquiry_entry *ie;
5207cad718edSJohan Hedberg 	struct hci_conn *conn;
520841a96212SMarcel Holtmann 
52093e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
521041a96212SMarcel Holtmann 
521141a96212SMarcel Holtmann 	hci_dev_lock(hdev);
521241a96212SMarcel Holtmann 
5213cad718edSJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
5214cad718edSJohan Hedberg 	if (conn)
5215cad718edSJohan Hedberg 		memcpy(conn->features[1], ev->features, 8);
5216cad718edSJohan Hedberg 
5217cc11b9c1SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
5218cc11b9c1SAndrei Emeltchenko 	if (ie)
521902b7cc62SJohan Hedberg 		ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
522041a96212SMarcel Holtmann 
522141a96212SMarcel Holtmann 	hci_dev_unlock(hdev);
522241a96212SMarcel Holtmann }
522341a96212SMarcel Holtmann 
52243e54c589SLuiz Augusto von Dentz static void hci_remote_oob_data_request_evt(struct hci_dev *hdev, void *edata,
52252763eda6SSzymon Janc 					    struct sk_buff *skb)
52262763eda6SSzymon Janc {
52273e54c589SLuiz Augusto von Dentz 	struct hci_ev_remote_oob_data_request *ev = edata;
52282763eda6SSzymon Janc 	struct oob_data *data;
52292763eda6SSzymon Janc 
52303e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
52312763eda6SSzymon Janc 
52322763eda6SSzymon Janc 	hci_dev_lock(hdev);
52332763eda6SSzymon Janc 
5234d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
5235e1ba1f15SSzymon Janc 		goto unlock;
5236e1ba1f15SSzymon Janc 
52376928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, &ev->bdaddr, BDADDR_BREDR);
52386665d057SMarcel Holtmann 	if (!data) {
52396665d057SMarcel Holtmann 		struct hci_cp_remote_oob_data_neg_reply cp;
52406665d057SMarcel Holtmann 
52416665d057SMarcel Holtmann 		bacpy(&cp.bdaddr, &ev->bdaddr);
52426665d057SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY,
52436665d057SMarcel Holtmann 			     sizeof(cp), &cp);
52446665d057SMarcel Holtmann 		goto unlock;
52456665d057SMarcel Holtmann 	}
52466665d057SMarcel Holtmann 
5247710f11c0SJohan Hedberg 	if (bredr_sc_enabled(hdev)) {
5248519ca9d0SMarcel Holtmann 		struct hci_cp_remote_oob_ext_data_reply cp;
5249519ca9d0SMarcel Holtmann 
5250519ca9d0SMarcel Holtmann 		bacpy(&cp.bdaddr, &ev->bdaddr);
5251d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_SC_ONLY)) {
52526665d057SMarcel Holtmann 			memset(cp.hash192, 0, sizeof(cp.hash192));
52536665d057SMarcel Holtmann 			memset(cp.rand192, 0, sizeof(cp.rand192));
52546665d057SMarcel Holtmann 		} else {
5255519ca9d0SMarcel Holtmann 			memcpy(cp.hash192, data->hash192, sizeof(cp.hash192));
525638da1703SJohan Hedberg 			memcpy(cp.rand192, data->rand192, sizeof(cp.rand192));
52576665d057SMarcel Holtmann 		}
5258519ca9d0SMarcel Holtmann 		memcpy(cp.hash256, data->hash256, sizeof(cp.hash256));
525938da1703SJohan Hedberg 		memcpy(cp.rand256, data->rand256, sizeof(cp.rand256));
5260519ca9d0SMarcel Holtmann 
5261519ca9d0SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY,
5262519ca9d0SMarcel Holtmann 			     sizeof(cp), &cp);
5263519ca9d0SMarcel Holtmann 	} else {
52642763eda6SSzymon Janc 		struct hci_cp_remote_oob_data_reply cp;
52652763eda6SSzymon Janc 
52662763eda6SSzymon Janc 		bacpy(&cp.bdaddr, &ev->bdaddr);
5267519ca9d0SMarcel Holtmann 		memcpy(cp.hash, data->hash192, sizeof(cp.hash));
526838da1703SJohan Hedberg 		memcpy(cp.rand, data->rand192, sizeof(cp.rand));
52692763eda6SSzymon Janc 
5270519ca9d0SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY,
5271519ca9d0SMarcel Holtmann 			     sizeof(cp), &cp);
5272519ca9d0SMarcel Holtmann 	}
52732763eda6SSzymon Janc 
5274e1ba1f15SSzymon Janc unlock:
52752763eda6SSzymon Janc 	hci_dev_unlock(hdev);
52762763eda6SSzymon Janc }
52772763eda6SSzymon Janc 
5278a77a6a14SArron Wang #if IS_ENABLED(CONFIG_BT_HS)
52793e54c589SLuiz Augusto von Dentz static void hci_chan_selected_evt(struct hci_dev *hdev, void *data,
52803e54c589SLuiz Augusto von Dentz 				  struct sk_buff *skb)
5281a77a6a14SArron Wang {
52823e54c589SLuiz Augusto von Dentz 	struct hci_ev_channel_selected *ev = data;
5283a77a6a14SArron Wang 	struct hci_conn *hcon;
5284a77a6a14SArron Wang 
52853e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "handle 0x%2.2x", ev->phy_handle);
5286a77a6a14SArron Wang 
5287a77a6a14SArron Wang 	hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
5288a77a6a14SArron Wang 	if (!hcon)
5289a77a6a14SArron Wang 		return;
5290a77a6a14SArron Wang 
5291a77a6a14SArron Wang 	amp_read_loc_assoc_final_data(hdev, hcon);
5292a77a6a14SArron Wang }
5293a77a6a14SArron Wang 
52943e54c589SLuiz Augusto von Dentz static void hci_phy_link_complete_evt(struct hci_dev *hdev, void *data,
5295d5e91192SAndrei Emeltchenko 				      struct sk_buff *skb)
5296d5e91192SAndrei Emeltchenko {
52973e54c589SLuiz Augusto von Dentz 	struct hci_ev_phy_link_complete *ev = data;
5298d5e91192SAndrei Emeltchenko 	struct hci_conn *hcon, *bredr_hcon;
5299d5e91192SAndrei Emeltchenko 
53003e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "handle 0x%2.2x status 0x%2.2x", ev->phy_handle,
5301d5e91192SAndrei Emeltchenko 		   ev->status);
5302d5e91192SAndrei Emeltchenko 
5303d5e91192SAndrei Emeltchenko 	hci_dev_lock(hdev);
5304d5e91192SAndrei Emeltchenko 
5305d5e91192SAndrei Emeltchenko 	hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
53063ae1dc75SSergey Shtylyov 	if (!hcon)
53073ae1dc75SSergey Shtylyov 		goto unlock;
5308d5e91192SAndrei Emeltchenko 
53093ae1dc75SSergey Shtylyov 	if (!hcon->amp_mgr)
53103ae1dc75SSergey Shtylyov 		goto unlock;
53116dfccd13SAnmol Karn 
5312d5e91192SAndrei Emeltchenko 	if (ev->status) {
5313d5e91192SAndrei Emeltchenko 		hci_conn_del(hcon);
53143ae1dc75SSergey Shtylyov 		goto unlock;
5315d5e91192SAndrei Emeltchenko 	}
5316d5e91192SAndrei Emeltchenko 
5317d5e91192SAndrei Emeltchenko 	bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
5318d5e91192SAndrei Emeltchenko 
5319d5e91192SAndrei Emeltchenko 	hcon->state = BT_CONNECTED;
5320d5e91192SAndrei Emeltchenko 	bacpy(&hcon->dst, &bredr_hcon->dst);
5321d5e91192SAndrei Emeltchenko 
5322d5e91192SAndrei Emeltchenko 	hci_conn_hold(hcon);
5323d5e91192SAndrei Emeltchenko 	hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
532476a68ba0SDavid Herrmann 	hci_conn_drop(hcon);
5325d5e91192SAndrei Emeltchenko 
532623b9ceb7SMarcel Holtmann 	hci_debugfs_create_conn(hcon);
5327d5e91192SAndrei Emeltchenko 	hci_conn_add_sysfs(hcon);
5328d5e91192SAndrei Emeltchenko 
5329cf70ff22SAndrei Emeltchenko 	amp_physical_cfm(bredr_hcon, hcon);
5330cf70ff22SAndrei Emeltchenko 
53313ae1dc75SSergey Shtylyov unlock:
5332d5e91192SAndrei Emeltchenko 	hci_dev_unlock(hdev);
5333d5e91192SAndrei Emeltchenko }
5334d5e91192SAndrei Emeltchenko 
53353e54c589SLuiz Augusto von Dentz static void hci_loglink_complete_evt(struct hci_dev *hdev, void *data,
53363e54c589SLuiz Augusto von Dentz 				     struct sk_buff *skb)
533727695fb4SAndrei Emeltchenko {
53383e54c589SLuiz Augusto von Dentz 	struct hci_ev_logical_link_complete *ev = data;
533927695fb4SAndrei Emeltchenko 	struct hci_conn *hcon;
534027695fb4SAndrei Emeltchenko 	struct hci_chan *hchan;
534127695fb4SAndrei Emeltchenko 	struct amp_mgr *mgr;
534227695fb4SAndrei Emeltchenko 
53433e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
53443e54c589SLuiz Augusto von Dentz 		   le16_to_cpu(ev->handle), ev->phy_handle, ev->status);
534527695fb4SAndrei Emeltchenko 
534627695fb4SAndrei Emeltchenko 	hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
534727695fb4SAndrei Emeltchenko 	if (!hcon)
534827695fb4SAndrei Emeltchenko 		return;
534927695fb4SAndrei Emeltchenko 
535027695fb4SAndrei Emeltchenko 	/* Create AMP hchan */
535127695fb4SAndrei Emeltchenko 	hchan = hci_chan_create(hcon);
535227695fb4SAndrei Emeltchenko 	if (!hchan)
535327695fb4SAndrei Emeltchenko 		return;
535427695fb4SAndrei Emeltchenko 
535527695fb4SAndrei Emeltchenko 	hchan->handle = le16_to_cpu(ev->handle);
53565c4c8c95SArchie Pusaka 	hchan->amp = true;
535727695fb4SAndrei Emeltchenko 
535827695fb4SAndrei Emeltchenko 	BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
535927695fb4SAndrei Emeltchenko 
536027695fb4SAndrei Emeltchenko 	mgr = hcon->amp_mgr;
536127695fb4SAndrei Emeltchenko 	if (mgr && mgr->bredr_chan) {
536227695fb4SAndrei Emeltchenko 		struct l2cap_chan *bredr_chan = mgr->bredr_chan;
536327695fb4SAndrei Emeltchenko 
536427695fb4SAndrei Emeltchenko 		l2cap_chan_lock(bredr_chan);
536527695fb4SAndrei Emeltchenko 
536627695fb4SAndrei Emeltchenko 		bredr_chan->conn->mtu = hdev->block_mtu;
536727695fb4SAndrei Emeltchenko 		l2cap_logical_cfm(bredr_chan, hchan, 0);
536827695fb4SAndrei Emeltchenko 		hci_conn_hold(hcon);
536927695fb4SAndrei Emeltchenko 
537027695fb4SAndrei Emeltchenko 		l2cap_chan_unlock(bredr_chan);
537127695fb4SAndrei Emeltchenko 	}
537227695fb4SAndrei Emeltchenko }
537327695fb4SAndrei Emeltchenko 
53743e54c589SLuiz Augusto von Dentz static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev, void *data,
5375606e2a10SAndrei Emeltchenko 					     struct sk_buff *skb)
5376606e2a10SAndrei Emeltchenko {
53773e54c589SLuiz Augusto von Dentz 	struct hci_ev_disconn_logical_link_complete *ev = data;
5378606e2a10SAndrei Emeltchenko 	struct hci_chan *hchan;
5379606e2a10SAndrei Emeltchenko 
53803e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "handle 0x%4.4x status 0x%2.2x",
5381606e2a10SAndrei Emeltchenko 		   le16_to_cpu(ev->handle), ev->status);
5382606e2a10SAndrei Emeltchenko 
5383606e2a10SAndrei Emeltchenko 	if (ev->status)
5384606e2a10SAndrei Emeltchenko 		return;
5385606e2a10SAndrei Emeltchenko 
5386606e2a10SAndrei Emeltchenko 	hci_dev_lock(hdev);
5387606e2a10SAndrei Emeltchenko 
5388606e2a10SAndrei Emeltchenko 	hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
53895c4c8c95SArchie Pusaka 	if (!hchan || !hchan->amp)
5390606e2a10SAndrei Emeltchenko 		goto unlock;
5391606e2a10SAndrei Emeltchenko 
5392606e2a10SAndrei Emeltchenko 	amp_destroy_logical_link(hchan, ev->reason);
5393606e2a10SAndrei Emeltchenko 
5394606e2a10SAndrei Emeltchenko unlock:
5395606e2a10SAndrei Emeltchenko 	hci_dev_unlock(hdev);
5396606e2a10SAndrei Emeltchenko }
5397606e2a10SAndrei Emeltchenko 
53983e54c589SLuiz Augusto von Dentz static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev, void *data,
53999eef6b3aSAndrei Emeltchenko 					     struct sk_buff *skb)
54009eef6b3aSAndrei Emeltchenko {
54013e54c589SLuiz Augusto von Dentz 	struct hci_ev_disconn_phy_link_complete *ev = data;
54029eef6b3aSAndrei Emeltchenko 	struct hci_conn *hcon;
54039eef6b3aSAndrei Emeltchenko 
54043e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
54059eef6b3aSAndrei Emeltchenko 
54069eef6b3aSAndrei Emeltchenko 	if (ev->status)
54079eef6b3aSAndrei Emeltchenko 		return;
54089eef6b3aSAndrei Emeltchenko 
54099eef6b3aSAndrei Emeltchenko 	hci_dev_lock(hdev);
54109eef6b3aSAndrei Emeltchenko 
54119eef6b3aSAndrei Emeltchenko 	hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
54129eef6b3aSAndrei Emeltchenko 	if (hcon) {
54139eef6b3aSAndrei Emeltchenko 		hcon->state = BT_CLOSED;
54149eef6b3aSAndrei Emeltchenko 		hci_conn_del(hcon);
54159eef6b3aSAndrei Emeltchenko 	}
54169eef6b3aSAndrei Emeltchenko 
54179eef6b3aSAndrei Emeltchenko 	hci_dev_unlock(hdev);
54189eef6b3aSAndrei Emeltchenko }
5419a77a6a14SArron Wang #endif
54209eef6b3aSAndrei Emeltchenko 
5421cafae4cdSLuiz Augusto von Dentz static void le_conn_update_addr(struct hci_conn *conn, bdaddr_t *bdaddr,
5422cafae4cdSLuiz Augusto von Dentz 				u8 bdaddr_type, bdaddr_t *local_rpa)
5423cafae4cdSLuiz Augusto von Dentz {
5424cafae4cdSLuiz Augusto von Dentz 	if (conn->out) {
5425cafae4cdSLuiz Augusto von Dentz 		conn->dst_type = bdaddr_type;
5426cafae4cdSLuiz Augusto von Dentz 		conn->resp_addr_type = bdaddr_type;
5427cafae4cdSLuiz Augusto von Dentz 		bacpy(&conn->resp_addr, bdaddr);
5428cafae4cdSLuiz Augusto von Dentz 
5429cafae4cdSLuiz Augusto von Dentz 		/* Check if the controller has set a Local RPA then it must be
5430cafae4cdSLuiz Augusto von Dentz 		 * used instead or hdev->rpa.
5431cafae4cdSLuiz Augusto von Dentz 		 */
5432cafae4cdSLuiz Augusto von Dentz 		if (local_rpa && bacmp(local_rpa, BDADDR_ANY)) {
5433cafae4cdSLuiz Augusto von Dentz 			conn->init_addr_type = ADDR_LE_DEV_RANDOM;
5434cafae4cdSLuiz Augusto von Dentz 			bacpy(&conn->init_addr, local_rpa);
5435cafae4cdSLuiz Augusto von Dentz 		} else if (hci_dev_test_flag(conn->hdev, HCI_PRIVACY)) {
5436cafae4cdSLuiz Augusto von Dentz 			conn->init_addr_type = ADDR_LE_DEV_RANDOM;
5437cafae4cdSLuiz Augusto von Dentz 			bacpy(&conn->init_addr, &conn->hdev->rpa);
5438cafae4cdSLuiz Augusto von Dentz 		} else {
5439cafae4cdSLuiz Augusto von Dentz 			hci_copy_identity_address(conn->hdev, &conn->init_addr,
5440cafae4cdSLuiz Augusto von Dentz 						  &conn->init_addr_type);
5441cafae4cdSLuiz Augusto von Dentz 		}
5442cafae4cdSLuiz Augusto von Dentz 	} else {
5443cafae4cdSLuiz Augusto von Dentz 		conn->resp_addr_type = conn->hdev->adv_addr_type;
5444cafae4cdSLuiz Augusto von Dentz 		/* Check if the controller has set a Local RPA then it must be
5445cafae4cdSLuiz Augusto von Dentz 		 * used instead or hdev->rpa.
5446cafae4cdSLuiz Augusto von Dentz 		 */
5447cafae4cdSLuiz Augusto von Dentz 		if (local_rpa && bacmp(local_rpa, BDADDR_ANY)) {
5448cafae4cdSLuiz Augusto von Dentz 			conn->resp_addr_type = ADDR_LE_DEV_RANDOM;
5449cafae4cdSLuiz Augusto von Dentz 			bacpy(&conn->resp_addr, local_rpa);
5450cafae4cdSLuiz Augusto von Dentz 		} else if (conn->hdev->adv_addr_type == ADDR_LE_DEV_RANDOM) {
5451cafae4cdSLuiz Augusto von Dentz 			/* In case of ext adv, resp_addr will be updated in
5452cafae4cdSLuiz Augusto von Dentz 			 * Adv Terminated event.
5453cafae4cdSLuiz Augusto von Dentz 			 */
5454cafae4cdSLuiz Augusto von Dentz 			if (!ext_adv_capable(conn->hdev))
5455cafae4cdSLuiz Augusto von Dentz 				bacpy(&conn->resp_addr,
5456cafae4cdSLuiz Augusto von Dentz 				      &conn->hdev->random_addr);
5457cafae4cdSLuiz Augusto von Dentz 		} else {
5458cafae4cdSLuiz Augusto von Dentz 			bacpy(&conn->resp_addr, &conn->hdev->bdaddr);
5459cafae4cdSLuiz Augusto von Dentz 		}
5460cafae4cdSLuiz Augusto von Dentz 
5461cafae4cdSLuiz Augusto von Dentz 		conn->init_addr_type = bdaddr_type;
5462cafae4cdSLuiz Augusto von Dentz 		bacpy(&conn->init_addr, bdaddr);
5463cafae4cdSLuiz Augusto von Dentz 
5464cafae4cdSLuiz Augusto von Dentz 		/* For incoming connections, set the default minimum
5465cafae4cdSLuiz Augusto von Dentz 		 * and maximum connection interval. They will be used
5466cafae4cdSLuiz Augusto von Dentz 		 * to check if the parameters are in range and if not
5467cafae4cdSLuiz Augusto von Dentz 		 * trigger the connection update procedure.
5468cafae4cdSLuiz Augusto von Dentz 		 */
5469cafae4cdSLuiz Augusto von Dentz 		conn->le_conn_min_interval = conn->hdev->le_conn_min_interval;
5470cafae4cdSLuiz Augusto von Dentz 		conn->le_conn_max_interval = conn->hdev->le_conn_max_interval;
5471cafae4cdSLuiz Augusto von Dentz 	}
5472cafae4cdSLuiz Augusto von Dentz }
5473cafae4cdSLuiz Augusto von Dentz 
5474d12fb056SJaganath Kanakkassery static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
5475cafae4cdSLuiz Augusto von Dentz 				 bdaddr_t *bdaddr, u8 bdaddr_type,
5476cafae4cdSLuiz Augusto von Dentz 				 bdaddr_t *local_rpa, u8 role, u16 handle,
5477cafae4cdSLuiz Augusto von Dentz 				 u16 interval, u16 latency,
5478cafae4cdSLuiz Augusto von Dentz 				 u16 supervision_timeout)
5479fcd89c09SVille Tervo {
5480912b42efSJohan Hedberg 	struct hci_conn_params *params;
5481fcd89c09SVille Tervo 	struct hci_conn *conn;
548268d6f6deSJohan Hedberg 	struct smp_irk *irk;
5483837d502eSJohan Hedberg 	u8 addr_type;
5484fcd89c09SVille Tervo 
5485fcd89c09SVille Tervo 	hci_dev_lock(hdev);
5486fcd89c09SVille Tervo 
5487fbd96c15SJohan Hedberg 	/* All controllers implicitly stop advertising in the event of a
5488fbd96c15SJohan Hedberg 	 * connection, so ensure that the state bit is cleared.
5489fbd96c15SJohan Hedberg 	 */
5490a358dc11SMarcel Holtmann 	hci_dev_clear_flag(hdev, HCI_LE_ADV);
5491fbd96c15SJohan Hedberg 
5492e7d9ab73SJakub Pawlowski 	conn = hci_lookup_le_connect(hdev);
5493b62f328bSVille Tervo 	if (!conn) {
5494d12fb056SJaganath Kanakkassery 		conn = hci_conn_add(hdev, LE_LINK, bdaddr, role);
5495b62f328bSVille Tervo 		if (!conn) {
54962064ee33SMarcel Holtmann 			bt_dev_err(hdev, "no memory for new connection");
5497230fd16aSAndre Guedes 			goto unlock;
5498b62f328bSVille Tervo 		}
549929b7988aSAndre Guedes 
5500d12fb056SJaganath Kanakkassery 		conn->dst_type = bdaddr_type;
5501b9b343d2SAndre Guedes 
5502cb1d68f7SJohan Hedberg 		/* If we didn't have a hci_conn object previously
550374be523cSArchie Pusaka 		 * but we're in central role this must be something
55043d4f9c00SArchie Pusaka 		 * initiated using an accept list. Since accept list based
5505cb1d68f7SJohan Hedberg 		 * connections are not "first class citizens" we don't
5506cb1d68f7SJohan Hedberg 		 * have full tracking of them. Therefore, we go ahead
5507cb1d68f7SJohan Hedberg 		 * with a "best effort" approach of determining the
5508cb1d68f7SJohan Hedberg 		 * initiator address based on the HCI_PRIVACY flag.
5509cb1d68f7SJohan Hedberg 		 */
5510cb1d68f7SJohan Hedberg 		if (conn->out) {
5511d12fb056SJaganath Kanakkassery 			conn->resp_addr_type = bdaddr_type;
5512d12fb056SJaganath Kanakkassery 			bacpy(&conn->resp_addr, bdaddr);
5513d7a5a11dSMarcel Holtmann 			if (hci_dev_test_flag(hdev, HCI_PRIVACY)) {
5514cb1d68f7SJohan Hedberg 				conn->init_addr_type = ADDR_LE_DEV_RANDOM;
5515cb1d68f7SJohan Hedberg 				bacpy(&conn->init_addr, &hdev->rpa);
5516cb1d68f7SJohan Hedberg 			} else {
5517cb1d68f7SJohan Hedberg 				hci_copy_identity_address(hdev,
5518cb1d68f7SJohan Hedberg 							  &conn->init_addr,
5519cb1d68f7SJohan Hedberg 							  &conn->init_addr_type);
5520cb1d68f7SJohan Hedberg 			}
552180c24ab8SJohan Hedberg 		}
5522cb1d68f7SJohan Hedberg 	} else {
552380c24ab8SJohan Hedberg 		cancel_delayed_work(&conn->le_conn_timeout);
552480c24ab8SJohan Hedberg 	}
552580c24ab8SJohan Hedberg 
5526cafae4cdSLuiz Augusto von Dentz 	le_conn_update_addr(conn, bdaddr, bdaddr_type, local_rpa);
55277be2edbbSJohan Hedberg 
5528edb4b466SMarcel Holtmann 	/* Lookup the identity address from the stored connection
5529edb4b466SMarcel Holtmann 	 * address and address type.
5530edb4b466SMarcel Holtmann 	 *
5531edb4b466SMarcel Holtmann 	 * When establishing connections to an identity address, the
5532edb4b466SMarcel Holtmann 	 * connection procedure will store the resolvable random
5533edb4b466SMarcel Holtmann 	 * address first. Now if it can be converted back into the
5534edb4b466SMarcel Holtmann 	 * identity address, start using the identity address from
5535edb4b466SMarcel Holtmann 	 * now on.
5536edb4b466SMarcel Holtmann 	 */
5537edb4b466SMarcel Holtmann 	irk = hci_get_irk(hdev, &conn->dst, conn->dst_type);
553868d6f6deSJohan Hedberg 	if (irk) {
553968d6f6deSJohan Hedberg 		bacpy(&conn->dst, &irk->bdaddr);
554068d6f6deSJohan Hedberg 		conn->dst_type = irk->addr_type;
554168d6f6deSJohan Hedberg 	}
554268d6f6deSJohan Hedberg 
5543d850bf08SLuiz Augusto von Dentz 	conn->dst_type = ev_bdaddr_type(hdev, conn->dst_type, NULL);
554479699a70SSathish Narasimman 
5545d12fb056SJaganath Kanakkassery 	if (status) {
5546d12fb056SJaganath Kanakkassery 		hci_le_conn_failed(conn, status);
5547837d502eSJohan Hedberg 		goto unlock;
5548837d502eSJohan Hedberg 	}
5549837d502eSJohan Hedberg 
555008853f18SJohan Hedberg 	if (conn->dst_type == ADDR_LE_DEV_PUBLIC)
555108853f18SJohan Hedberg 		addr_type = BDADDR_LE_PUBLIC;
555208853f18SJohan Hedberg 	else
555308853f18SJohan Hedberg 		addr_type = BDADDR_LE_RANDOM;
555408853f18SJohan Hedberg 
55552d3c2260SJohan Hedberg 	/* Drop the connection if the device is blocked */
55563d4f9c00SArchie Pusaka 	if (hci_bdaddr_list_lookup(&hdev->reject_list, &conn->dst, addr_type)) {
55572d3c2260SJohan Hedberg 		hci_conn_drop(conn);
5558cd17decbSAndre Guedes 		goto unlock;
5559cd17decbSAndre Guedes 	}
5560cd17decbSAndre Guedes 
5561b644ba33SJohan Hedberg 	if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
55621c6ed31bSYu Liu 		mgmt_device_connected(hdev, conn, NULL, 0);
556383bc71b4SVinicius Costa Gomes 
55647b5c0d52SVinicius Costa Gomes 	conn->sec_level = BT_SECURITY_LOW;
5565d12fb056SJaganath Kanakkassery 	conn->handle = handle;
55660fe29fd1SMarcel Holtmann 	conn->state = BT_CONFIG;
5567fcd89c09SVille Tervo 
55687087c4f6SLuiz Augusto von Dentz 	/* Store current advertising instance as connection advertising instance
55697087c4f6SLuiz Augusto von Dentz 	 * when sotfware rotation is in use so it can be re-enabled when
55707087c4f6SLuiz Augusto von Dentz 	 * disconnected.
55717087c4f6SLuiz Augusto von Dentz 	 */
55727087c4f6SLuiz Augusto von Dentz 	if (!ext_adv_capable(hdev))
55737087c4f6SLuiz Augusto von Dentz 		conn->adv_instance = hdev->cur_adv_instance;
55747087c4f6SLuiz Augusto von Dentz 
5575d12fb056SJaganath Kanakkassery 	conn->le_conn_interval = interval;
5576d12fb056SJaganath Kanakkassery 	conn->le_conn_latency = latency;
5577d12fb056SJaganath Kanakkassery 	conn->le_supv_timeout = supervision_timeout;
5578e04fde60SMarcel Holtmann 
557923b9ceb7SMarcel Holtmann 	hci_debugfs_create_conn(conn);
5580fcd89c09SVille Tervo 	hci_conn_add_sysfs(conn);
5581fcd89c09SVille Tervo 
5582ef365da1SArchie Pusaka 	/* The remote features procedure is defined for central
55830fe29fd1SMarcel Holtmann 	 * role only. So only in case of an initiated connection
55840fe29fd1SMarcel Holtmann 	 * request the remote features.
55850fe29fd1SMarcel Holtmann 	 *
5586ef365da1SArchie Pusaka 	 * If the local controller supports peripheral-initiated features
5587ef365da1SArchie Pusaka 	 * exchange, then requesting the remote features in peripheral
55880fe29fd1SMarcel Holtmann 	 * role is possible. Otherwise just transition into the
55890fe29fd1SMarcel Holtmann 	 * connected state without requesting the remote features.
55900fe29fd1SMarcel Holtmann 	 */
55910fe29fd1SMarcel Holtmann 	if (conn->out ||
5592ef365da1SArchie Pusaka 	    (hdev->le_features[0] & HCI_LE_PERIPHERAL_FEATURES)) {
55930fe29fd1SMarcel Holtmann 		struct hci_cp_le_read_remote_features cp;
55940fe29fd1SMarcel Holtmann 
55950fe29fd1SMarcel Holtmann 		cp.handle = __cpu_to_le16(conn->handle);
55960fe29fd1SMarcel Holtmann 
55970fe29fd1SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_LE_READ_REMOTE_FEATURES,
55980fe29fd1SMarcel Holtmann 			     sizeof(cp), &cp);
55990fe29fd1SMarcel Holtmann 
56000fe29fd1SMarcel Holtmann 		hci_conn_hold(conn);
56010fe29fd1SMarcel Holtmann 	} else {
56020fe29fd1SMarcel Holtmann 		conn->state = BT_CONNECTED;
5603d12fb056SJaganath Kanakkassery 		hci_connect_cfm(conn, status);
56040fe29fd1SMarcel Holtmann 	}
5605fcd89c09SVille Tervo 
56065477610fSJohan Hedberg 	params = hci_pend_le_action_lookup(&hdev->pend_le_conns, &conn->dst,
56075477610fSJohan Hedberg 					   conn->dst_type);
5608f161dd41SJohan Hedberg 	if (params) {
560995305baaSJohan Hedberg 		list_del_init(&params->action);
5610f161dd41SJohan Hedberg 		if (params->conn) {
5611f161dd41SJohan Hedberg 			hci_conn_drop(params->conn);
5612f8aaf9b6SJohan Hedberg 			hci_conn_put(params->conn);
5613f161dd41SJohan Hedberg 			params->conn = NULL;
5614f161dd41SJohan Hedberg 		}
5615f161dd41SJohan Hedberg 	}
5616a4790dbdSAndre Guedes 
5617fcd89c09SVille Tervo unlock:
56185bee2fd6SLuiz Augusto von Dentz 	hci_update_passive_scan(hdev);
5619fcd89c09SVille Tervo 	hci_dev_unlock(hdev);
5620fcd89c09SVille Tervo }
5621fcd89c09SVille Tervo 
562295118dd4SLuiz Augusto von Dentz static void hci_le_conn_complete_evt(struct hci_dev *hdev, void *data,
562395118dd4SLuiz Augusto von Dentz 				     struct sk_buff *skb)
5624d12fb056SJaganath Kanakkassery {
562595118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_conn_complete *ev = data;
562612cfe417SLuiz Augusto von Dentz 
562795118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
5628d12fb056SJaganath Kanakkassery 
5629d12fb056SJaganath Kanakkassery 	le_conn_complete_evt(hdev, ev->status, &ev->bdaddr, ev->bdaddr_type,
5630cafae4cdSLuiz Augusto von Dentz 			     NULL, ev->role, le16_to_cpu(ev->handle),
5631d12fb056SJaganath Kanakkassery 			     le16_to_cpu(ev->interval),
5632d12fb056SJaganath Kanakkassery 			     le16_to_cpu(ev->latency),
5633d12fb056SJaganath Kanakkassery 			     le16_to_cpu(ev->supervision_timeout));
5634d12fb056SJaganath Kanakkassery }
5635d12fb056SJaganath Kanakkassery 
563695118dd4SLuiz Augusto von Dentz static void hci_le_enh_conn_complete_evt(struct hci_dev *hdev, void *data,
56374d94f95dSJaganath Kanakkassery 					 struct sk_buff *skb)
56384d94f95dSJaganath Kanakkassery {
563995118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_enh_conn_complete *ev = data;
564012cfe417SLuiz Augusto von Dentz 
564195118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
56424d94f95dSJaganath Kanakkassery 
56434d94f95dSJaganath Kanakkassery 	le_conn_complete_evt(hdev, ev->status, &ev->bdaddr, ev->bdaddr_type,
5644cafae4cdSLuiz Augusto von Dentz 			     &ev->local_rpa, ev->role, le16_to_cpu(ev->handle),
56454d94f95dSJaganath Kanakkassery 			     le16_to_cpu(ev->interval),
56464d94f95dSJaganath Kanakkassery 			     le16_to_cpu(ev->latency),
56474d94f95dSJaganath Kanakkassery 			     le16_to_cpu(ev->supervision_timeout));
56484d94f95dSJaganath Kanakkassery }
56494d94f95dSJaganath Kanakkassery 
565095118dd4SLuiz Augusto von Dentz static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, void *data,
565195118dd4SLuiz Augusto von Dentz 				    struct sk_buff *skb)
5652acf0aeaeSJaganath Kanakkassery {
565395118dd4SLuiz Augusto von Dentz 	struct hci_evt_le_ext_adv_set_term *ev = data;
5654acf0aeaeSJaganath Kanakkassery 	struct hci_conn *conn;
56551f9d5657SArchie Pusaka 	struct adv_info *adv, *n;
5656acf0aeaeSJaganath Kanakkassery 
565795118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
5658acf0aeaeSJaganath Kanakkassery 
565923837a6dSLuiz Augusto von Dentz 	adv = hci_find_adv_instance(hdev, ev->handle);
56607087c4f6SLuiz Augusto von Dentz 
56610f281a5eSArchie Pusaka 	/* The Bluetooth Core 5.3 specification clearly states that this event
56620f281a5eSArchie Pusaka 	 * shall not be sent when the Host disables the advertising set. So in
56630f281a5eSArchie Pusaka 	 * case of HCI_ERROR_CANCELLED_BY_HOST, just ignore the event.
56640f281a5eSArchie Pusaka 	 *
56650f281a5eSArchie Pusaka 	 * When the Host disables an advertising set, all cleanup is done via
56660f281a5eSArchie Pusaka 	 * its command callback and not needed to be duplicated here.
56670f281a5eSArchie Pusaka 	 */
56680f281a5eSArchie Pusaka 	if (ev->status == HCI_ERROR_CANCELLED_BY_HOST) {
56690f281a5eSArchie Pusaka 		bt_dev_warn_ratelimited(hdev, "Unexpected advertising set terminated event");
56700f281a5eSArchie Pusaka 		return;
56710f281a5eSArchie Pusaka 	}
56720f281a5eSArchie Pusaka 
56737087c4f6SLuiz Augusto von Dentz 	if (ev->status) {
567423837a6dSLuiz Augusto von Dentz 		if (!adv)
5675acf0aeaeSJaganath Kanakkassery 			return;
5676acf0aeaeSJaganath Kanakkassery 
567723837a6dSLuiz Augusto von Dentz 		/* Remove advertising as it has been terminated */
567823837a6dSLuiz Augusto von Dentz 		hci_remove_adv_instance(hdev, ev->handle);
567923837a6dSLuiz Augusto von Dentz 		mgmt_advertising_removed(NULL, hdev, ev->handle);
568023837a6dSLuiz Augusto von Dentz 
56811f9d5657SArchie Pusaka 		list_for_each_entry_safe(adv, n, &hdev->adv_instances, list) {
56821f9d5657SArchie Pusaka 			if (adv->enabled)
56831f9d5657SArchie Pusaka 				return;
56841f9d5657SArchie Pusaka 		}
56851f9d5657SArchie Pusaka 
56861f9d5657SArchie Pusaka 		/* We are no longer advertising, clear HCI_LE_ADV */
56871f9d5657SArchie Pusaka 		hci_dev_clear_flag(hdev, HCI_LE_ADV);
568823837a6dSLuiz Augusto von Dentz 		return;
568923837a6dSLuiz Augusto von Dentz 	}
569023837a6dSLuiz Augusto von Dentz 
56917087c4f6SLuiz Augusto von Dentz 	if (adv)
56927087c4f6SLuiz Augusto von Dentz 		adv->enabled = false;
56937087c4f6SLuiz Augusto von Dentz 
5694acf0aeaeSJaganath Kanakkassery 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->conn_handle));
5695acf0aeaeSJaganath Kanakkassery 	if (conn) {
56967087c4f6SLuiz Augusto von Dentz 		/* Store handle in the connection so the correct advertising
56977087c4f6SLuiz Augusto von Dentz 		 * instance can be re-enabled when disconnected.
56987087c4f6SLuiz Augusto von Dentz 		 */
56997087c4f6SLuiz Augusto von Dentz 		conn->adv_instance = ev->handle;
5700acf0aeaeSJaganath Kanakkassery 
5701cafae4cdSLuiz Augusto von Dentz 		if (hdev->adv_addr_type != ADDR_LE_DEV_RANDOM ||
5702cafae4cdSLuiz Augusto von Dentz 		    bacmp(&conn->resp_addr, BDADDR_ANY))
5703acf0aeaeSJaganath Kanakkassery 			return;
5704acf0aeaeSJaganath Kanakkassery 
570525e70886SDaniel Winkler 		if (!ev->handle) {
5706acf0aeaeSJaganath Kanakkassery 			bacpy(&conn->resp_addr, &hdev->random_addr);
5707acf0aeaeSJaganath Kanakkassery 			return;
5708acf0aeaeSJaganath Kanakkassery 		}
5709acf0aeaeSJaganath Kanakkassery 
57107087c4f6SLuiz Augusto von Dentz 		if (adv)
57117087c4f6SLuiz Augusto von Dentz 			bacpy(&conn->resp_addr, &adv->random_addr);
5712acf0aeaeSJaganath Kanakkassery 	}
5713acf0aeaeSJaganath Kanakkassery }
5714acf0aeaeSJaganath Kanakkassery 
571595118dd4SLuiz Augusto von Dentz static void hci_le_conn_update_complete_evt(struct hci_dev *hdev, void *data,
57161855d92dSMarcel Holtmann 					    struct sk_buff *skb)
57171855d92dSMarcel Holtmann {
571895118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_conn_update_complete *ev = data;
57191855d92dSMarcel Holtmann 	struct hci_conn *conn;
57201855d92dSMarcel Holtmann 
572195118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
57221855d92dSMarcel Holtmann 
57231855d92dSMarcel Holtmann 	if (ev->status)
57241855d92dSMarcel Holtmann 		return;
57251855d92dSMarcel Holtmann 
57261855d92dSMarcel Holtmann 	hci_dev_lock(hdev);
57271855d92dSMarcel Holtmann 
57281855d92dSMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
57291855d92dSMarcel Holtmann 	if (conn) {
57301855d92dSMarcel Holtmann 		conn->le_conn_interval = le16_to_cpu(ev->interval);
57311855d92dSMarcel Holtmann 		conn->le_conn_latency = le16_to_cpu(ev->latency);
57321855d92dSMarcel Holtmann 		conn->le_supv_timeout = le16_to_cpu(ev->supervision_timeout);
57331855d92dSMarcel Holtmann 	}
57341855d92dSMarcel Holtmann 
57351855d92dSMarcel Holtmann 	hci_dev_unlock(hdev);
57361855d92dSMarcel Holtmann }
57371855d92dSMarcel Holtmann 
5738a4790dbdSAndre Guedes /* This function requires the caller holds hdev->lock */
5739fd45ada9SAlfonso Acosta static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev,
5740fd45ada9SAlfonso Acosta 					      bdaddr_t *addr,
5741d850bf08SLuiz Augusto von Dentz 					      u8 addr_type, bool addr_resolved,
5742d850bf08SLuiz Augusto von Dentz 					      u8 adv_type, bdaddr_t *direct_rpa)
5743a4790dbdSAndre Guedes {
5744a4790dbdSAndre Guedes 	struct hci_conn *conn;
57454b9e7e75SMarcel Holtmann 	struct hci_conn_params *params;
5746a4790dbdSAndre Guedes 
57471c1abcabSJohan Hedberg 	/* If the event is not connectable don't proceed further */
57481c1abcabSJohan Hedberg 	if (adv_type != LE_ADV_IND && adv_type != LE_ADV_DIRECT_IND)
5749fd45ada9SAlfonso Acosta 		return NULL;
57501c1abcabSJohan Hedberg 
5751182ee45dSLuiz Augusto von Dentz 	/* Ignore if the device is blocked or hdev is suspended */
5752182ee45dSLuiz Augusto von Dentz 	if (hci_bdaddr_list_lookup(&hdev->reject_list, addr, addr_type) ||
5753182ee45dSLuiz Augusto von Dentz 	    hdev->suspended)
5754fd45ada9SAlfonso Acosta 		return NULL;
57551c1abcabSJohan Hedberg 
5756f99353cfSJohan Hedberg 	/* Most controller will fail if we try to create new connections
575739bc74caSArchie Pusaka 	 * while we have an existing one in peripheral role.
5758f99353cfSJohan Hedberg 	 */
575939bc74caSArchie Pusaka 	if (hdev->conn_hash.le_num_peripheral > 0 &&
57604364f2e9SAlain Michaud 	    (!test_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks) ||
57614364f2e9SAlain Michaud 	     !(hdev->le_states[3] & 0x10)))
5762fd45ada9SAlfonso Acosta 		return NULL;
5763f99353cfSJohan Hedberg 
57641c1abcabSJohan Hedberg 	/* If we're not connectable only connect devices that we have in
57651c1abcabSJohan Hedberg 	 * our pend_le_conns list.
57661c1abcabSJohan Hedberg 	 */
576749c50922SJohan Hedberg 	params = hci_pend_le_action_lookup(&hdev->pend_le_conns, addr,
576849c50922SJohan Hedberg 					   addr_type);
57694b9e7e75SMarcel Holtmann 	if (!params)
5770fd45ada9SAlfonso Acosta 		return NULL;
5771a4790dbdSAndre Guedes 
577228a667c9SJakub Pawlowski 	if (!params->explicit_connect) {
57734b9e7e75SMarcel Holtmann 		switch (params->auto_connect) {
57744b9e7e75SMarcel Holtmann 		case HCI_AUTO_CONN_DIRECT:
57754b9e7e75SMarcel Holtmann 			/* Only devices advertising with ADV_DIRECT_IND are
57764b9e7e75SMarcel Holtmann 			 * triggering a connection attempt. This is allowing
577767ffb185SArchie Pusaka 			 * incoming connections from peripheral devices.
57784b9e7e75SMarcel Holtmann 			 */
57794b9e7e75SMarcel Holtmann 			if (adv_type != LE_ADV_DIRECT_IND)
5780fd45ada9SAlfonso Acosta 				return NULL;
57814b9e7e75SMarcel Holtmann 			break;
57824b9e7e75SMarcel Holtmann 		case HCI_AUTO_CONN_ALWAYS:
57834b9e7e75SMarcel Holtmann 			/* Devices advertising with ADV_IND or ADV_DIRECT_IND
57844b9e7e75SMarcel Holtmann 			 * are triggering a connection attempt. This means
578567ffb185SArchie Pusaka 			 * that incoming connections from peripheral device are
578667ffb185SArchie Pusaka 			 * accepted and also outgoing connections to peripheral
57874b9e7e75SMarcel Holtmann 			 * devices are established when found.
57884b9e7e75SMarcel Holtmann 			 */
57894b9e7e75SMarcel Holtmann 			break;
57904b9e7e75SMarcel Holtmann 		default:
5791fd45ada9SAlfonso Acosta 			return NULL;
57924b9e7e75SMarcel Holtmann 		}
579328a667c9SJakub Pawlowski 	}
57944b9e7e75SMarcel Holtmann 
5795d850bf08SLuiz Augusto von Dentz 	conn = hci_connect_le(hdev, addr, addr_type, addr_resolved,
5796d850bf08SLuiz Augusto von Dentz 			      BT_SECURITY_LOW, hdev->def_le_autoconnect_timeout,
5797d850bf08SLuiz Augusto von Dentz 			      HCI_ROLE_MASTER, direct_rpa);
5798f161dd41SJohan Hedberg 	if (!IS_ERR(conn)) {
579928a667c9SJakub Pawlowski 		/* If HCI_AUTO_CONN_EXPLICIT is set, conn is already owned
580028a667c9SJakub Pawlowski 		 * by higher layer that tried to connect, if no then
580128a667c9SJakub Pawlowski 		 * store the pointer since we don't really have any
5802f161dd41SJohan Hedberg 		 * other owner of the object besides the params that
5803f161dd41SJohan Hedberg 		 * triggered it. This way we can abort the connection if
5804f161dd41SJohan Hedberg 		 * the parameters get removed and keep the reference
5805f161dd41SJohan Hedberg 		 * count consistent once the connection is established.
5806f161dd41SJohan Hedberg 		 */
580728a667c9SJakub Pawlowski 
580828a667c9SJakub Pawlowski 		if (!params->explicit_connect)
5809f8aaf9b6SJohan Hedberg 			params->conn = hci_conn_get(conn);
581028a667c9SJakub Pawlowski 
5811fd45ada9SAlfonso Acosta 		return conn;
5812f161dd41SJohan Hedberg 	}
5813a4790dbdSAndre Guedes 
5814a4790dbdSAndre Guedes 	switch (PTR_ERR(conn)) {
5815a4790dbdSAndre Guedes 	case -EBUSY:
5816a4790dbdSAndre Guedes 		/* If hci_connect() returns -EBUSY it means there is already
5817a4790dbdSAndre Guedes 		 * an LE connection attempt going on. Since controllers don't
5818a4790dbdSAndre Guedes 		 * support more than one connection attempt at the time, we
5819a4790dbdSAndre Guedes 		 * don't consider this an error case.
5820a4790dbdSAndre Guedes 		 */
5821a4790dbdSAndre Guedes 		break;
5822a4790dbdSAndre Guedes 	default:
5823a4790dbdSAndre Guedes 		BT_DBG("Failed to connect: err %ld", PTR_ERR(conn));
5824fd45ada9SAlfonso Acosta 		return NULL;
5825a4790dbdSAndre Guedes 	}
5826fd45ada9SAlfonso Acosta 
5827fd45ada9SAlfonso Acosta 	return NULL;
5828a4790dbdSAndre Guedes }
5829a4790dbdSAndre Guedes 
58304af605d8SJohan Hedberg static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
58312f010b55SMarcel Holtmann 			       u8 bdaddr_type, bdaddr_t *direct_addr,
5832a2ec905dSAlain Michaud 			       u8 direct_addr_type, s8 rssi, u8 *data, u8 len,
5833a2ec905dSAlain Michaud 			       bool ext_adv)
58344af605d8SJohan Hedberg {
5835b9a6328fSJohan Hedberg 	struct discovery_state *d = &hdev->discovery;
58361c1abcabSJohan Hedberg 	struct smp_irk *irk;
5837fd45ada9SAlfonso Acosta 	struct hci_conn *conn;
5838d850bf08SLuiz Augusto von Dentz 	bool match, bdaddr_resolved;
5839c70a7e4cSMarcel Holtmann 	u32 flags;
58401c58e933SSzymon Janc 	u8 *ptr;
58416818375eSSzymon Janc 
584256b40fbfSJohan Hedberg 	switch (type) {
584356b40fbfSJohan Hedberg 	case LE_ADV_IND:
584456b40fbfSJohan Hedberg 	case LE_ADV_DIRECT_IND:
584556b40fbfSJohan Hedberg 	case LE_ADV_SCAN_IND:
584656b40fbfSJohan Hedberg 	case LE_ADV_NONCONN_IND:
584756b40fbfSJohan Hedberg 	case LE_ADV_SCAN_RSP:
584856b40fbfSJohan Hedberg 		break;
584956b40fbfSJohan Hedberg 	default:
58502064ee33SMarcel Holtmann 		bt_dev_err_ratelimited(hdev, "unknown advertising packet "
58512064ee33SMarcel Holtmann 				       "type: 0x%02x", type);
585256b40fbfSJohan Hedberg 		return;
585356b40fbfSJohan Hedberg 	}
585456b40fbfSJohan Hedberg 
5855a2ec905dSAlain Michaud 	if (!ext_adv && len > HCI_MAX_AD_LENGTH) {
5856a2ec905dSAlain Michaud 		bt_dev_err_ratelimited(hdev, "legacy adv larger than 31 bytes");
5857a2ec905dSAlain Michaud 		return;
5858a2ec905dSAlain Michaud 	}
5859a2ec905dSAlain Michaud 
58606818375eSSzymon Janc 	/* Find the end of the data in case the report contains padded zero
58616818375eSSzymon Janc 	 * bytes at the end causing an invalid length value.
58626818375eSSzymon Janc 	 *
58636818375eSSzymon Janc 	 * When data is NULL, len is 0 so there is no need for extra ptr
58646818375eSSzymon Janc 	 * check as 'ptr < data + 0' is already false in such case.
58656818375eSSzymon Janc 	 */
58666818375eSSzymon Janc 	for (ptr = data; ptr < data + len && *ptr; ptr += *ptr + 1) {
58676818375eSSzymon Janc 		if (ptr + 1 + *ptr > data + len)
58686818375eSSzymon Janc 			break;
58696818375eSSzymon Janc 	}
58706818375eSSzymon Janc 
58711c58e933SSzymon Janc 	/* Adjust for actual length. This handles the case when remote
58721c58e933SSzymon Janc 	 * device is advertising with incorrect data length.
58731c58e933SSzymon Janc 	 */
58741c58e933SSzymon Janc 	len = ptr - data;
5875b9a6328fSJohan Hedberg 
58762f010b55SMarcel Holtmann 	/* If the direct address is present, then this report is from
58772f010b55SMarcel Holtmann 	 * a LE Direct Advertising Report event. In that case it is
58782f010b55SMarcel Holtmann 	 * important to see if the address is matching the local
58792f010b55SMarcel Holtmann 	 * controller address.
58802f010b55SMarcel Holtmann 	 */
58812f010b55SMarcel Holtmann 	if (direct_addr) {
5882d850bf08SLuiz Augusto von Dentz 		direct_addr_type = ev_bdaddr_type(hdev, direct_addr_type,
5883d850bf08SLuiz Augusto von Dentz 						  &bdaddr_resolved);
58844ec4d63bSLuiz Augusto von Dentz 
58852f010b55SMarcel Holtmann 		/* Only resolvable random addresses are valid for these
58862f010b55SMarcel Holtmann 		 * kind of reports and others can be ignored.
58872f010b55SMarcel Holtmann 		 */
58882f010b55SMarcel Holtmann 		if (!hci_bdaddr_is_rpa(direct_addr, direct_addr_type))
58892f010b55SMarcel Holtmann 			return;
58902f010b55SMarcel Holtmann 
58912f010b55SMarcel Holtmann 		/* If the controller is not using resolvable random
58922f010b55SMarcel Holtmann 		 * addresses, then this report can be ignored.
58932f010b55SMarcel Holtmann 		 */
5894d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_PRIVACY))
58952f010b55SMarcel Holtmann 			return;
58962f010b55SMarcel Holtmann 
58972f010b55SMarcel Holtmann 		/* If the local IRK of the controller does not match
58982f010b55SMarcel Holtmann 		 * with the resolvable random address provided, then
58992f010b55SMarcel Holtmann 		 * this report can be ignored.
59002f010b55SMarcel Holtmann 		 */
59012f010b55SMarcel Holtmann 		if (!smp_irk_matches(hdev, hdev->irk, direct_addr))
59022f010b55SMarcel Holtmann 			return;
59032f010b55SMarcel Holtmann 	}
59042f010b55SMarcel Holtmann 
5905435a13d8SJohan Hedberg 	/* Check if we need to convert to identity address */
5906435a13d8SJohan Hedberg 	irk = hci_get_irk(hdev, bdaddr, bdaddr_type);
5907435a13d8SJohan Hedberg 	if (irk) {
5908435a13d8SJohan Hedberg 		bdaddr = &irk->bdaddr;
5909435a13d8SJohan Hedberg 		bdaddr_type = irk->addr_type;
5910435a13d8SJohan Hedberg 	}
5911435a13d8SJohan Hedberg 
5912d850bf08SLuiz Augusto von Dentz 	bdaddr_type = ev_bdaddr_type(hdev, bdaddr_type, &bdaddr_resolved);
59134ec4d63bSLuiz Augusto von Dentz 
5914082f2300SSzymon Janc 	/* Check if we have been requested to connect to this device.
5915082f2300SSzymon Janc 	 *
5916082f2300SSzymon Janc 	 * direct_addr is set only for directed advertising reports (it is NULL
5917082f2300SSzymon Janc 	 * for advertising reports) and is already verified to be RPA above.
5918082f2300SSzymon Janc 	 */
5919d850bf08SLuiz Augusto von Dentz 	conn = check_pending_le_conn(hdev, bdaddr, bdaddr_type, bdaddr_resolved,
5920d850bf08SLuiz Augusto von Dentz 				     type, direct_addr);
5921a2ec905dSAlain Michaud 	if (!ext_adv && conn && type == LE_ADV_IND && len <= HCI_MAX_AD_LENGTH) {
5922fd45ada9SAlfonso Acosta 		/* Store report for later inclusion by
5923fd45ada9SAlfonso Acosta 		 * mgmt_device_connected
5924fd45ada9SAlfonso Acosta 		 */
5925fd45ada9SAlfonso Acosta 		memcpy(conn->le_adv_data, data, len);
5926fd45ada9SAlfonso Acosta 		conn->le_adv_data_len = len;
5927fd45ada9SAlfonso Acosta 	}
592899a6768eSJohan Hedberg 
59291c1abcabSJohan Hedberg 	/* Passive scanning shouldn't trigger any device found events,
59301c1abcabSJohan Hedberg 	 * except for devices marked as CONN_REPORT for which we do send
59318208f5a9SMiao-chen Chou 	 * device found events, or advertisement monitoring requested.
59321c1abcabSJohan Hedberg 	 */
59331c1abcabSJohan Hedberg 	if (hdev->le_scan_type == LE_SCAN_PASSIVE) {
59340d2bf134SJohan Hedberg 		if (type == LE_ADV_DIRECT_IND)
59350d2bf134SJohan Hedberg 			return;
59360d2bf134SJohan Hedberg 
59373a19b6feSJohan Hedberg 		if (!hci_pend_le_action_lookup(&hdev->pend_le_reports,
59388208f5a9SMiao-chen Chou 					       bdaddr, bdaddr_type) &&
59398208f5a9SMiao-chen Chou 		    idr_is_empty(&hdev->adv_monitors_idr))
59400d2bf134SJohan Hedberg 			return;
59410d2bf134SJohan Hedberg 
59420d2bf134SJohan Hedberg 		if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND)
59430d2bf134SJohan Hedberg 			flags = MGMT_DEV_FOUND_NOT_CONNECTABLE;
59440d2bf134SJohan Hedberg 		else
59450d2bf134SJohan Hedberg 			flags = 0;
59460d2bf134SJohan Hedberg 		mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
59470d2bf134SJohan Hedberg 				  rssi, flags, data, len, NULL, 0);
594897bf2e99SJohan Hedberg 		return;
5949ca5c4be7SJohan Hedberg 	}
59504af605d8SJohan Hedberg 
5951c70a7e4cSMarcel Holtmann 	/* When receiving non-connectable or scannable undirected
5952c70a7e4cSMarcel Holtmann 	 * advertising reports, this means that the remote device is
5953c70a7e4cSMarcel Holtmann 	 * not connectable and then clearly indicate this in the
5954c70a7e4cSMarcel Holtmann 	 * device found event.
5955c70a7e4cSMarcel Holtmann 	 *
5956c70a7e4cSMarcel Holtmann 	 * When receiving a scan response, then there is no way to
5957c70a7e4cSMarcel Holtmann 	 * know if the remote device is connectable or not. However
5958c70a7e4cSMarcel Holtmann 	 * since scan responses are merged with a previously seen
5959c70a7e4cSMarcel Holtmann 	 * advertising report, the flags field from that report
5960c70a7e4cSMarcel Holtmann 	 * will be used.
5961c70a7e4cSMarcel Holtmann 	 *
5962c70a7e4cSMarcel Holtmann 	 * In the really unlikely case that a controller get confused
5963c70a7e4cSMarcel Holtmann 	 * and just sends a scan response event, then it is marked as
5964c70a7e4cSMarcel Holtmann 	 * not connectable as well.
5965c70a7e4cSMarcel Holtmann 	 */
5966c70a7e4cSMarcel Holtmann 	if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND ||
5967c70a7e4cSMarcel Holtmann 	    type == LE_ADV_SCAN_RSP)
5968c70a7e4cSMarcel Holtmann 		flags = MGMT_DEV_FOUND_NOT_CONNECTABLE;
5969c70a7e4cSMarcel Holtmann 	else
5970c70a7e4cSMarcel Holtmann 		flags = 0;
5971c70a7e4cSMarcel Holtmann 
5972b9a6328fSJohan Hedberg 	/* If there's nothing pending either store the data from this
5973b9a6328fSJohan Hedberg 	 * event or send an immediate device found event if the data
5974b9a6328fSJohan Hedberg 	 * should not be stored for later.
5975b9a6328fSJohan Hedberg 	 */
5976a2ec905dSAlain Michaud 	if (!ext_adv &&	!has_pending_adv_report(hdev)) {
5977b9a6328fSJohan Hedberg 		/* If the report will trigger a SCAN_REQ store it for
5978b9a6328fSJohan Hedberg 		 * later merging.
5979b9a6328fSJohan Hedberg 		 */
5980b9a6328fSJohan Hedberg 		if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) {
5981b9a6328fSJohan Hedberg 			store_pending_adv_report(hdev, bdaddr, bdaddr_type,
5982c70a7e4cSMarcel Holtmann 						 rssi, flags, data, len);
5983b9a6328fSJohan Hedberg 			return;
5984b9a6328fSJohan Hedberg 		}
5985b9a6328fSJohan Hedberg 
5986b9a6328fSJohan Hedberg 		mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
5987c70a7e4cSMarcel Holtmann 				  rssi, flags, data, len, NULL, 0);
5988b9a6328fSJohan Hedberg 		return;
5989b9a6328fSJohan Hedberg 	}
5990b9a6328fSJohan Hedberg 
5991474ee066SJohan Hedberg 	/* Check if the pending report is for the same device as the new one */
5992474ee066SJohan Hedberg 	match = (!bacmp(bdaddr, &d->last_adv_addr) &&
5993474ee066SJohan Hedberg 		 bdaddr_type == d->last_adv_addr_type);
5994474ee066SJohan Hedberg 
5995b9a6328fSJohan Hedberg 	/* If the pending data doesn't match this report or this isn't a
5996b9a6328fSJohan Hedberg 	 * scan response (e.g. we got a duplicate ADV_IND) then force
5997b9a6328fSJohan Hedberg 	 * sending of the pending data.
5998b9a6328fSJohan Hedberg 	 */
5999474ee066SJohan Hedberg 	if (type != LE_ADV_SCAN_RSP || !match) {
6000474ee066SJohan Hedberg 		/* Send out whatever is in the cache, but skip duplicates */
6001474ee066SJohan Hedberg 		if (!match)
6002b9a6328fSJohan Hedberg 			mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
6003ff5cd29fSJohan Hedberg 					  d->last_adv_addr_type, NULL,
6004c70a7e4cSMarcel Holtmann 					  d->last_adv_rssi, d->last_adv_flags,
6005ff5cd29fSJohan Hedberg 					  d->last_adv_data,
6006474ee066SJohan Hedberg 					  d->last_adv_data_len, NULL, 0);
6007b9a6328fSJohan Hedberg 
6008b9a6328fSJohan Hedberg 		/* If the new report will trigger a SCAN_REQ store it for
6009b9a6328fSJohan Hedberg 		 * later merging.
6010b9a6328fSJohan Hedberg 		 */
6011a2ec905dSAlain Michaud 		if (!ext_adv && (type == LE_ADV_IND ||
6012a2ec905dSAlain Michaud 				 type == LE_ADV_SCAN_IND)) {
6013b9a6328fSJohan Hedberg 			store_pending_adv_report(hdev, bdaddr, bdaddr_type,
6014c70a7e4cSMarcel Holtmann 						 rssi, flags, data, len);
6015b9a6328fSJohan Hedberg 			return;
6016b9a6328fSJohan Hedberg 		}
6017b9a6328fSJohan Hedberg 
6018b9a6328fSJohan Hedberg 		/* The advertising reports cannot be merged, so clear
6019b9a6328fSJohan Hedberg 		 * the pending report and send out a device found event.
6020b9a6328fSJohan Hedberg 		 */
6021b9a6328fSJohan Hedberg 		clear_pending_adv_report(hdev);
60225c5b93e4SJohan Hedberg 		mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
6023c70a7e4cSMarcel Holtmann 				  rssi, flags, data, len, NULL, 0);
6024b9a6328fSJohan Hedberg 		return;
6025b9a6328fSJohan Hedberg 	}
6026b9a6328fSJohan Hedberg 
6027b9a6328fSJohan Hedberg 	/* If we get here we've got a pending ADV_IND or ADV_SCAN_IND and
6028b9a6328fSJohan Hedberg 	 * the new event is a SCAN_RSP. We can therefore proceed with
6029b9a6328fSJohan Hedberg 	 * sending a merged device found event.
6030b9a6328fSJohan Hedberg 	 */
6031b9a6328fSJohan Hedberg 	mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
6032c70a7e4cSMarcel Holtmann 			  d->last_adv_addr_type, NULL, rssi, d->last_adv_flags,
603342bd6a56SMarcel Holtmann 			  d->last_adv_data, d->last_adv_data_len, data, len);
6034b9a6328fSJohan Hedberg 	clear_pending_adv_report(hdev);
60354af605d8SJohan Hedberg }
60364af605d8SJohan Hedberg 
603795118dd4SLuiz Augusto von Dentz static void hci_le_adv_report_evt(struct hci_dev *hdev, void *data,
603895118dd4SLuiz Augusto von Dentz 				  struct sk_buff *skb)
60399aa04c91SAndre Guedes {
604095118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_advertising_report *ev = data;
604147afe93cSLuiz Augusto von Dentz 
604247afe93cSLuiz Augusto von Dentz 	if (!ev->num)
604347afe93cSLuiz Augusto von Dentz 		return;
60449aa04c91SAndre Guedes 
6045a4790dbdSAndre Guedes 	hci_dev_lock(hdev);
6046a4790dbdSAndre Guedes 
604747afe93cSLuiz Augusto von Dentz 	while (ev->num--) {
604847afe93cSLuiz Augusto von Dentz 		struct hci_ev_le_advertising_info *info;
60494af605d8SJohan Hedberg 		s8 rssi;
6050a4790dbdSAndre Guedes 
605147afe93cSLuiz Augusto von Dentz 		info = hci_le_ev_skb_pull(hdev, skb,
605247afe93cSLuiz Augusto von Dentz 					  HCI_EV_LE_ADVERTISING_REPORT,
605347afe93cSLuiz Augusto von Dentz 					  sizeof(*info));
605447afe93cSLuiz Augusto von Dentz 		if (!info)
6055899663beSBrian Gix 			break;
6056899663beSBrian Gix 
605747afe93cSLuiz Augusto von Dentz 		if (!hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_ADVERTISING_REPORT,
605847afe93cSLuiz Augusto von Dentz 					info->length + 1))
605947afe93cSLuiz Augusto von Dentz 			break;
606047afe93cSLuiz Augusto von Dentz 
606147afe93cSLuiz Augusto von Dentz 		if (info->length <= HCI_MAX_AD_LENGTH) {
606247afe93cSLuiz Augusto von Dentz 			rssi = info->data[info->length];
606347afe93cSLuiz Augusto von Dentz 			process_adv_report(hdev, info->type, &info->bdaddr,
606447afe93cSLuiz Augusto von Dentz 					   info->bdaddr_type, NULL, 0, rssi,
606547afe93cSLuiz Augusto von Dentz 					   info->data, info->length, false);
6066ee649346SChriz Chow 		} else {
6067ee649346SChriz Chow 			bt_dev_err(hdev, "Dropping invalid advertising data");
6068ee649346SChriz Chow 		}
60699aa04c91SAndre Guedes 	}
6070a4790dbdSAndre Guedes 
6071a4790dbdSAndre Guedes 	hci_dev_unlock(hdev);
60729aa04c91SAndre Guedes }
60739aa04c91SAndre Guedes 
6074657cc646SMarcel Holtmann static u8 ext_evt_type_to_legacy(struct hci_dev *hdev, u16 evt_type)
6075c215e939SJaganath Kanakkassery {
6076b2cc9761SJaganath Kanakkassery 	if (evt_type & LE_EXT_ADV_LEGACY_PDU) {
6077c215e939SJaganath Kanakkassery 		switch (evt_type) {
6078c215e939SJaganath Kanakkassery 		case LE_LEGACY_ADV_IND:
6079c215e939SJaganath Kanakkassery 			return LE_ADV_IND;
6080c215e939SJaganath Kanakkassery 		case LE_LEGACY_ADV_DIRECT_IND:
6081c215e939SJaganath Kanakkassery 			return LE_ADV_DIRECT_IND;
6082c215e939SJaganath Kanakkassery 		case LE_LEGACY_ADV_SCAN_IND:
6083c215e939SJaganath Kanakkassery 			return LE_ADV_SCAN_IND;
6084c215e939SJaganath Kanakkassery 		case LE_LEGACY_NONCONN_IND:
6085c215e939SJaganath Kanakkassery 			return LE_ADV_NONCONN_IND;
6086c215e939SJaganath Kanakkassery 		case LE_LEGACY_SCAN_RSP_ADV:
6087c215e939SJaganath Kanakkassery 		case LE_LEGACY_SCAN_RSP_ADV_SCAN:
6088c215e939SJaganath Kanakkassery 			return LE_ADV_SCAN_RSP;
6089c215e939SJaganath Kanakkassery 		}
6090c215e939SJaganath Kanakkassery 
6091657cc646SMarcel Holtmann 		goto invalid;
6092c215e939SJaganath Kanakkassery 	}
6093c215e939SJaganath Kanakkassery 
6094b2cc9761SJaganath Kanakkassery 	if (evt_type & LE_EXT_ADV_CONN_IND) {
6095b2cc9761SJaganath Kanakkassery 		if (evt_type & LE_EXT_ADV_DIRECT_IND)
6096b2cc9761SJaganath Kanakkassery 			return LE_ADV_DIRECT_IND;
6097b2cc9761SJaganath Kanakkassery 
6098b2cc9761SJaganath Kanakkassery 		return LE_ADV_IND;
6099b2cc9761SJaganath Kanakkassery 	}
6100b2cc9761SJaganath Kanakkassery 
6101b2cc9761SJaganath Kanakkassery 	if (evt_type & LE_EXT_ADV_SCAN_RSP)
6102b2cc9761SJaganath Kanakkassery 		return LE_ADV_SCAN_RSP;
6103b2cc9761SJaganath Kanakkassery 
6104b2cc9761SJaganath Kanakkassery 	if (evt_type & LE_EXT_ADV_SCAN_IND)
6105b2cc9761SJaganath Kanakkassery 		return LE_ADV_SCAN_IND;
6106b2cc9761SJaganath Kanakkassery 
6107b2cc9761SJaganath Kanakkassery 	if (evt_type == LE_EXT_ADV_NON_CONN_IND ||
6108b2cc9761SJaganath Kanakkassery 	    evt_type & LE_EXT_ADV_DIRECT_IND)
6109b2cc9761SJaganath Kanakkassery 		return LE_ADV_NONCONN_IND;
6110b2cc9761SJaganath Kanakkassery 
6111657cc646SMarcel Holtmann invalid:
6112657cc646SMarcel Holtmann 	bt_dev_err_ratelimited(hdev, "Unknown advertising packet type: 0x%02x",
6113b2cc9761SJaganath Kanakkassery 			       evt_type);
6114b2cc9761SJaganath Kanakkassery 
6115b2cc9761SJaganath Kanakkassery 	return LE_ADV_INVALID;
6116b2cc9761SJaganath Kanakkassery }
6117b2cc9761SJaganath Kanakkassery 
611895118dd4SLuiz Augusto von Dentz static void hci_le_ext_adv_report_evt(struct hci_dev *hdev, void *data,
611995118dd4SLuiz Augusto von Dentz 				      struct sk_buff *skb)
6120c215e939SJaganath Kanakkassery {
612195118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_ext_adv_report *ev = data;
6122b48b833fSLuiz Augusto von Dentz 
6123b48b833fSLuiz Augusto von Dentz 	if (!ev->num)
6124b48b833fSLuiz Augusto von Dentz 		return;
6125c215e939SJaganath Kanakkassery 
6126c215e939SJaganath Kanakkassery 	hci_dev_lock(hdev);
6127c215e939SJaganath Kanakkassery 
6128b48b833fSLuiz Augusto von Dentz 	while (ev->num--) {
6129b48b833fSLuiz Augusto von Dentz 		struct hci_ev_le_ext_adv_info *info;
6130c215e939SJaganath Kanakkassery 		u8 legacy_evt_type;
6131c215e939SJaganath Kanakkassery 		u16 evt_type;
6132c215e939SJaganath Kanakkassery 
6133b48b833fSLuiz Augusto von Dentz 		info = hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_EXT_ADV_REPORT,
6134b48b833fSLuiz Augusto von Dentz 					  sizeof(*info));
6135b48b833fSLuiz Augusto von Dentz 		if (!info)
6136b48b833fSLuiz Augusto von Dentz 			break;
6137b48b833fSLuiz Augusto von Dentz 
6138b48b833fSLuiz Augusto von Dentz 		if (!hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_EXT_ADV_REPORT,
6139b48b833fSLuiz Augusto von Dentz 					info->length))
6140b48b833fSLuiz Augusto von Dentz 			break;
6141b48b833fSLuiz Augusto von Dentz 
6142b48b833fSLuiz Augusto von Dentz 		evt_type = __le16_to_cpu(info->type);
6143657cc646SMarcel Holtmann 		legacy_evt_type = ext_evt_type_to_legacy(hdev, evt_type);
6144c215e939SJaganath Kanakkassery 		if (legacy_evt_type != LE_ADV_INVALID) {
6145b48b833fSLuiz Augusto von Dentz 			process_adv_report(hdev, legacy_evt_type, &info->bdaddr,
6146b48b833fSLuiz Augusto von Dentz 					   info->bdaddr_type, NULL, 0,
6147b48b833fSLuiz Augusto von Dentz 					   info->rssi, info->data, info->length,
6148a2ec905dSAlain Michaud 					   !(evt_type & LE_EXT_ADV_LEGACY_PDU));
6149c215e939SJaganath Kanakkassery 		}
6150c215e939SJaganath Kanakkassery 	}
6151c215e939SJaganath Kanakkassery 
6152c215e939SJaganath Kanakkassery 	hci_dev_unlock(hdev);
6153c215e939SJaganath Kanakkassery }
6154c215e939SJaganath Kanakkassery 
615595118dd4SLuiz Augusto von Dentz static void hci_le_remote_feat_complete_evt(struct hci_dev *hdev, void *data,
61560fe29fd1SMarcel Holtmann 					    struct sk_buff *skb)
61570fe29fd1SMarcel Holtmann {
615895118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_remote_feat_complete *ev = data;
61590fe29fd1SMarcel Holtmann 	struct hci_conn *conn;
61600fe29fd1SMarcel Holtmann 
616195118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
61620fe29fd1SMarcel Holtmann 
61630fe29fd1SMarcel Holtmann 	hci_dev_lock(hdev);
61640fe29fd1SMarcel Holtmann 
61650fe29fd1SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
61660fe29fd1SMarcel Holtmann 	if (conn) {
61670fe29fd1SMarcel Holtmann 		if (!ev->status)
61680fe29fd1SMarcel Holtmann 			memcpy(conn->features[0], ev->features, 8);
61690fe29fd1SMarcel Holtmann 
61700fe29fd1SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
61710fe29fd1SMarcel Holtmann 			__u8 status;
61720fe29fd1SMarcel Holtmann 
6173ef365da1SArchie Pusaka 			/* If the local controller supports peripheral-initiated
61740fe29fd1SMarcel Holtmann 			 * features exchange, but the remote controller does
61750fe29fd1SMarcel Holtmann 			 * not, then it is possible that the error code 0x1a
61760fe29fd1SMarcel Holtmann 			 * for unsupported remote feature gets returned.
61770fe29fd1SMarcel Holtmann 			 *
61780fe29fd1SMarcel Holtmann 			 * In this specific case, allow the connection to
61790fe29fd1SMarcel Holtmann 			 * transition into connected state and mark it as
61800fe29fd1SMarcel Holtmann 			 * successful.
61810fe29fd1SMarcel Holtmann 			 */
6182ef365da1SArchie Pusaka 			if (!conn->out && ev->status == 0x1a &&
6183ef365da1SArchie Pusaka 			    (hdev->le_features[0] & HCI_LE_PERIPHERAL_FEATURES))
61840fe29fd1SMarcel Holtmann 				status = 0x00;
61850fe29fd1SMarcel Holtmann 			else
61860fe29fd1SMarcel Holtmann 				status = ev->status;
61870fe29fd1SMarcel Holtmann 
61880fe29fd1SMarcel Holtmann 			conn->state = BT_CONNECTED;
61890fe29fd1SMarcel Holtmann 			hci_connect_cfm(conn, status);
61900fe29fd1SMarcel Holtmann 			hci_conn_drop(conn);
61910fe29fd1SMarcel Holtmann 		}
61920fe29fd1SMarcel Holtmann 	}
61930fe29fd1SMarcel Holtmann 
61940fe29fd1SMarcel Holtmann 	hci_dev_unlock(hdev);
61950fe29fd1SMarcel Holtmann }
61960fe29fd1SMarcel Holtmann 
619795118dd4SLuiz Augusto von Dentz static void hci_le_ltk_request_evt(struct hci_dev *hdev, void *data,
619895118dd4SLuiz Augusto von Dentz 				   struct sk_buff *skb)
6199a7a595f6SVinicius Costa Gomes {
620095118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_ltk_req *ev = data;
6201a7a595f6SVinicius Costa Gomes 	struct hci_cp_le_ltk_reply cp;
6202bea710feSVinicius Costa Gomes 	struct hci_cp_le_ltk_neg_reply neg;
6203a7a595f6SVinicius Costa Gomes 	struct hci_conn *conn;
6204c9839a11SVinicius Costa Gomes 	struct smp_ltk *ltk;
6205a7a595f6SVinicius Costa Gomes 
620695118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "handle 0x%4.4x", __le16_to_cpu(ev->handle));
6207a7a595f6SVinicius Costa Gomes 
6208a7a595f6SVinicius Costa Gomes 	hci_dev_lock(hdev);
6209a7a595f6SVinicius Costa Gomes 
6210a7a595f6SVinicius Costa Gomes 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
6211bea710feSVinicius Costa Gomes 	if (conn == NULL)
6212bea710feSVinicius Costa Gomes 		goto not_found;
6213a7a595f6SVinicius Costa Gomes 
6214f3a73d97SJohan Hedberg 	ltk = hci_find_ltk(hdev, &conn->dst, conn->dst_type, conn->role);
62155378bc56SJohan Hedberg 	if (!ltk)
6216bea710feSVinicius Costa Gomes 		goto not_found;
6217bea710feSVinicius Costa Gomes 
62185378bc56SJohan Hedberg 	if (smp_ltk_is_sc(ltk)) {
62195378bc56SJohan Hedberg 		/* With SC both EDiv and Rand are set to zero */
62205378bc56SJohan Hedberg 		if (ev->ediv || ev->rand)
62215378bc56SJohan Hedberg 			goto not_found;
62225378bc56SJohan Hedberg 	} else {
62235378bc56SJohan Hedberg 		/* For non-SC keys check that EDiv and Rand match */
62245378bc56SJohan Hedberg 		if (ev->ediv != ltk->ediv || ev->rand != ltk->rand)
62255378bc56SJohan Hedberg 			goto not_found;
62265378bc56SJohan Hedberg 	}
62275378bc56SJohan Hedberg 
62288b76ce34SJohan Hedberg 	memcpy(cp.ltk, ltk->val, ltk->enc_size);
62298b76ce34SJohan Hedberg 	memset(cp.ltk + ltk->enc_size, 0, sizeof(cp.ltk) - ltk->enc_size);
6230a7a595f6SVinicius Costa Gomes 	cp.handle = cpu_to_le16(conn->handle);
6231c9839a11SVinicius Costa Gomes 
6232a6f7833cSJohan Hedberg 	conn->pending_sec_level = smp_ltk_sec_level(ltk);
6233a7a595f6SVinicius Costa Gomes 
623489cbb4daSAndre Guedes 	conn->enc_key_size = ltk->enc_size;
6235a7a595f6SVinicius Costa Gomes 
6236a7a595f6SVinicius Costa Gomes 	hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
6237a7a595f6SVinicius Costa Gomes 
62385981a882SClaudio Takahasi 	/* Ref. Bluetooth Core SPEC pages 1975 and 2004. STK is a
62395981a882SClaudio Takahasi 	 * temporary key used to encrypt a connection following
62405981a882SClaudio Takahasi 	 * pairing. It is used during the Encrypted Session Setup to
62415981a882SClaudio Takahasi 	 * distribute the keys. Later, security can be re-established
62425981a882SClaudio Takahasi 	 * using a distributed LTK.
62435981a882SClaudio Takahasi 	 */
62442ceba539SJohan Hedberg 	if (ltk->type == SMP_STK) {
6245fe59a05fSJohan Hedberg 		set_bit(HCI_CONN_STK_ENCRYPT, &conn->flags);
6246970d0f1bSJohan Hedberg 		list_del_rcu(&ltk->list);
6247970d0f1bSJohan Hedberg 		kfree_rcu(ltk, rcu);
6248fe59a05fSJohan Hedberg 	} else {
6249fe59a05fSJohan Hedberg 		clear_bit(HCI_CONN_STK_ENCRYPT, &conn->flags);
6250c9839a11SVinicius Costa Gomes 	}
6251c9839a11SVinicius Costa Gomes 
6252a7a595f6SVinicius Costa Gomes 	hci_dev_unlock(hdev);
6253bea710feSVinicius Costa Gomes 
6254bea710feSVinicius Costa Gomes 	return;
6255bea710feSVinicius Costa Gomes 
6256bea710feSVinicius Costa Gomes not_found:
6257bea710feSVinicius Costa Gomes 	neg.handle = ev->handle;
6258bea710feSVinicius Costa Gomes 	hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
6259bea710feSVinicius Costa Gomes 	hci_dev_unlock(hdev);
6260a7a595f6SVinicius Costa Gomes }
6261a7a595f6SVinicius Costa Gomes 
62628e75b46aSAndre Guedes static void send_conn_param_neg_reply(struct hci_dev *hdev, u16 handle,
62638e75b46aSAndre Guedes 				      u8 reason)
62648e75b46aSAndre Guedes {
62658e75b46aSAndre Guedes 	struct hci_cp_le_conn_param_req_neg_reply cp;
62668e75b46aSAndre Guedes 
62678e75b46aSAndre Guedes 	cp.handle = cpu_to_le16(handle);
62688e75b46aSAndre Guedes 	cp.reason = reason;
62698e75b46aSAndre Guedes 
62708e75b46aSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY, sizeof(cp),
62718e75b46aSAndre Guedes 		     &cp);
62728e75b46aSAndre Guedes }
62738e75b46aSAndre Guedes 
627495118dd4SLuiz Augusto von Dentz static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev, void *data,
62758e75b46aSAndre Guedes 					     struct sk_buff *skb)
62768e75b46aSAndre Guedes {
627795118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_remote_conn_param_req *ev = data;
62788e75b46aSAndre Guedes 	struct hci_cp_le_conn_param_req_reply cp;
62798e75b46aSAndre Guedes 	struct hci_conn *hcon;
62808e75b46aSAndre Guedes 	u16 handle, min, max, latency, timeout;
62818e75b46aSAndre Guedes 
628295118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "handle 0x%4.4x", __le16_to_cpu(ev->handle));
628312cfe417SLuiz Augusto von Dentz 
62848e75b46aSAndre Guedes 	handle = le16_to_cpu(ev->handle);
62858e75b46aSAndre Guedes 	min = le16_to_cpu(ev->interval_min);
62868e75b46aSAndre Guedes 	max = le16_to_cpu(ev->interval_max);
62878e75b46aSAndre Guedes 	latency = le16_to_cpu(ev->latency);
62888e75b46aSAndre Guedes 	timeout = le16_to_cpu(ev->timeout);
62898e75b46aSAndre Guedes 
62908e75b46aSAndre Guedes 	hcon = hci_conn_hash_lookup_handle(hdev, handle);
62918e75b46aSAndre Guedes 	if (!hcon || hcon->state != BT_CONNECTED)
62928e75b46aSAndre Guedes 		return send_conn_param_neg_reply(hdev, handle,
62938e75b46aSAndre Guedes 						 HCI_ERROR_UNKNOWN_CONN_ID);
62948e75b46aSAndre Guedes 
62958e75b46aSAndre Guedes 	if (hci_check_conn_params(min, max, latency, timeout))
62968e75b46aSAndre Guedes 		return send_conn_param_neg_reply(hdev, handle,
62978e75b46aSAndre Guedes 						 HCI_ERROR_INVALID_LL_PARAMS);
62988e75b46aSAndre Guedes 
629940bef302SJohan Hedberg 	if (hcon->role == HCI_ROLE_MASTER) {
6300348d50b8SJohan Hedberg 		struct hci_conn_params *params;
6301f4869e2aSJohan Hedberg 		u8 store_hint;
6302348d50b8SJohan Hedberg 
6303348d50b8SJohan Hedberg 		hci_dev_lock(hdev);
6304348d50b8SJohan Hedberg 
6305348d50b8SJohan Hedberg 		params = hci_conn_params_lookup(hdev, &hcon->dst,
6306348d50b8SJohan Hedberg 						hcon->dst_type);
6307348d50b8SJohan Hedberg 		if (params) {
6308348d50b8SJohan Hedberg 			params->conn_min_interval = min;
6309348d50b8SJohan Hedberg 			params->conn_max_interval = max;
6310348d50b8SJohan Hedberg 			params->conn_latency = latency;
6311348d50b8SJohan Hedberg 			params->supervision_timeout = timeout;
6312f4869e2aSJohan Hedberg 			store_hint = 0x01;
6313f4869e2aSJohan Hedberg 		} else {
6314f4869e2aSJohan Hedberg 			store_hint = 0x00;
6315348d50b8SJohan Hedberg 		}
6316348d50b8SJohan Hedberg 
6317348d50b8SJohan Hedberg 		hci_dev_unlock(hdev);
6318348d50b8SJohan Hedberg 
6319f4869e2aSJohan Hedberg 		mgmt_new_conn_param(hdev, &hcon->dst, hcon->dst_type,
6320f4869e2aSJohan Hedberg 				    store_hint, min, max, latency, timeout);
6321348d50b8SJohan Hedberg 	}
6322ffb5a827SAndre Guedes 
63238e75b46aSAndre Guedes 	cp.handle = ev->handle;
63248e75b46aSAndre Guedes 	cp.interval_min = ev->interval_min;
63258e75b46aSAndre Guedes 	cp.interval_max = ev->interval_max;
63268e75b46aSAndre Guedes 	cp.latency = ev->latency;
63278e75b46aSAndre Guedes 	cp.timeout = ev->timeout;
63288e75b46aSAndre Guedes 	cp.min_ce_len = 0;
63298e75b46aSAndre Guedes 	cp.max_ce_len = 0;
63308e75b46aSAndre Guedes 
63318e75b46aSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_REPLY, sizeof(cp), &cp);
63328e75b46aSAndre Guedes }
63338e75b46aSAndre Guedes 
633495118dd4SLuiz Augusto von Dentz static void hci_le_direct_adv_report_evt(struct hci_dev *hdev, void *data,
63352f010b55SMarcel Holtmann 					 struct sk_buff *skb)
63362f010b55SMarcel Holtmann {
633795118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_direct_adv_report *ev = data;
6338a3679649SLuiz Augusto von Dentz 	int i;
6339f7e0e8b2SPeilin Ye 
6340a3679649SLuiz Augusto von Dentz 	if (!hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_DIRECT_ADV_REPORT,
6341a3679649SLuiz Augusto von Dentz 				flex_array_size(ev, info, ev->num)))
6342a3679649SLuiz Augusto von Dentz 		return;
6343a3679649SLuiz Augusto von Dentz 
6344a3679649SLuiz Augusto von Dentz 	if (!ev->num)
6345f7e0e8b2SPeilin Ye 		return;
63462f010b55SMarcel Holtmann 
63472f010b55SMarcel Holtmann 	hci_dev_lock(hdev);
63482f010b55SMarcel Holtmann 
6349a3679649SLuiz Augusto von Dentz 	for (i = 0; i < ev->num; i++) {
6350a3679649SLuiz Augusto von Dentz 		struct hci_ev_le_direct_adv_info *info = &ev->info[i];
6351a3679649SLuiz Augusto von Dentz 
6352a3679649SLuiz Augusto von Dentz 		process_adv_report(hdev, info->type, &info->bdaddr,
6353a3679649SLuiz Augusto von Dentz 				   info->bdaddr_type, &info->direct_addr,
6354a3679649SLuiz Augusto von Dentz 				   info->direct_addr_type, info->rssi, NULL, 0,
6355a2ec905dSAlain Michaud 				   false);
6356a3679649SLuiz Augusto von Dentz 	}
63572f010b55SMarcel Holtmann 
63582f010b55SMarcel Holtmann 	hci_dev_unlock(hdev);
63592f010b55SMarcel Holtmann }
63602f010b55SMarcel Holtmann 
636195118dd4SLuiz Augusto von Dentz static void hci_le_phy_update_evt(struct hci_dev *hdev, void *data,
636295118dd4SLuiz Augusto von Dentz 				  struct sk_buff *skb)
63631efd927dSLuiz Augusto von Dentz {
636495118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_phy_update_complete *ev = data;
63651efd927dSLuiz Augusto von Dentz 	struct hci_conn *conn;
63661efd927dSLuiz Augusto von Dentz 
636795118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
63681efd927dSLuiz Augusto von Dentz 
636987df8bccSAyush Garg 	if (ev->status)
63701efd927dSLuiz Augusto von Dentz 		return;
63711efd927dSLuiz Augusto von Dentz 
63721efd927dSLuiz Augusto von Dentz 	hci_dev_lock(hdev);
63731efd927dSLuiz Augusto von Dentz 
63741efd927dSLuiz Augusto von Dentz 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
63751efd927dSLuiz Augusto von Dentz 	if (!conn)
63761efd927dSLuiz Augusto von Dentz 		goto unlock;
63771efd927dSLuiz Augusto von Dentz 
63781efd927dSLuiz Augusto von Dentz 	conn->le_tx_phy = ev->tx_phy;
63791efd927dSLuiz Augusto von Dentz 	conn->le_rx_phy = ev->rx_phy;
63801efd927dSLuiz Augusto von Dentz 
63811efd927dSLuiz Augusto von Dentz unlock:
63821efd927dSLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
63831efd927dSLuiz Augusto von Dentz }
63841efd927dSLuiz Augusto von Dentz 
638595118dd4SLuiz Augusto von Dentz #define HCI_LE_EV_VL(_op, _func, _min_len, _max_len) \
638695118dd4SLuiz Augusto von Dentz [_op] = { \
638795118dd4SLuiz Augusto von Dentz 	.func = _func, \
638895118dd4SLuiz Augusto von Dentz 	.min_len = _min_len, \
638995118dd4SLuiz Augusto von Dentz 	.max_len = _max_len, \
639095118dd4SLuiz Augusto von Dentz }
639195118dd4SLuiz Augusto von Dentz 
639295118dd4SLuiz Augusto von Dentz #define HCI_LE_EV(_op, _func, _len) \
639395118dd4SLuiz Augusto von Dentz 	HCI_LE_EV_VL(_op, _func, _len, _len)
639495118dd4SLuiz Augusto von Dentz 
639595118dd4SLuiz Augusto von Dentz #define HCI_LE_EV_STATUS(_op, _func) \
639695118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(_op, _func, sizeof(struct hci_ev_status))
639795118dd4SLuiz Augusto von Dentz 
639895118dd4SLuiz Augusto von Dentz /* Entries in this table shall have their position according to the subevent
639995118dd4SLuiz Augusto von Dentz  * opcode they handle so the use of the macros above is recommend since it does
640095118dd4SLuiz Augusto von Dentz  * attempt to initialize at its proper index using Designated Initializers that
640195118dd4SLuiz Augusto von Dentz  * way events without a callback function can be ommited.
640295118dd4SLuiz Augusto von Dentz  */
640395118dd4SLuiz Augusto von Dentz static const struct hci_le_ev {
640495118dd4SLuiz Augusto von Dentz 	void (*func)(struct hci_dev *hdev, void *data, struct sk_buff *skb);
640595118dd4SLuiz Augusto von Dentz 	u16  min_len;
640695118dd4SLuiz Augusto von Dentz 	u16  max_len;
640795118dd4SLuiz Augusto von Dentz } hci_le_ev_table[U8_MAX + 1] = {
640895118dd4SLuiz Augusto von Dentz 	/* [0x01 = HCI_EV_LE_CONN_COMPLETE] */
640995118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_CONN_COMPLETE, hci_le_conn_complete_evt,
641095118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_conn_complete)),
641195118dd4SLuiz Augusto von Dentz 	/* [0x02 = HCI_EV_LE_ADVERTISING_REPORT] */
641295118dd4SLuiz Augusto von Dentz 	HCI_LE_EV_VL(HCI_EV_LE_ADVERTISING_REPORT, hci_le_adv_report_evt,
641395118dd4SLuiz Augusto von Dentz 		     sizeof(struct hci_ev_le_advertising_report),
641495118dd4SLuiz Augusto von Dentz 		     HCI_MAX_EVENT_SIZE),
641595118dd4SLuiz Augusto von Dentz 	/* [0x03 = HCI_EV_LE_CONN_UPDATE_COMPLETE] */
641695118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_CONN_UPDATE_COMPLETE,
641795118dd4SLuiz Augusto von Dentz 		  hci_le_conn_update_complete_evt,
641895118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_conn_update_complete)),
641995118dd4SLuiz Augusto von Dentz 	/* [0x04 = HCI_EV_LE_REMOTE_FEAT_COMPLETE] */
642095118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_REMOTE_FEAT_COMPLETE,
642195118dd4SLuiz Augusto von Dentz 		  hci_le_remote_feat_complete_evt,
642295118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_remote_feat_complete)),
642395118dd4SLuiz Augusto von Dentz 	/* [0x05 = HCI_EV_LE_LTK_REQ] */
642495118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_LTK_REQ, hci_le_ltk_request_evt,
642595118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_ltk_req)),
642695118dd4SLuiz Augusto von Dentz 	/* [0x06 = HCI_EV_LE_REMOTE_CONN_PARAM_REQ] */
642795118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_REMOTE_CONN_PARAM_REQ,
642895118dd4SLuiz Augusto von Dentz 		  hci_le_remote_conn_param_req_evt,
642995118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_remote_conn_param_req)),
643095118dd4SLuiz Augusto von Dentz 	/* [0x0a = HCI_EV_LE_ENHANCED_CONN_COMPLETE] */
643195118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_ENHANCED_CONN_COMPLETE,
643295118dd4SLuiz Augusto von Dentz 		  hci_le_enh_conn_complete_evt,
643395118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_enh_conn_complete)),
643495118dd4SLuiz Augusto von Dentz 	/* [0x0b = HCI_EV_LE_DIRECT_ADV_REPORT] */
643595118dd4SLuiz Augusto von Dentz 	HCI_LE_EV_VL(HCI_EV_LE_DIRECT_ADV_REPORT, hci_le_direct_adv_report_evt,
643695118dd4SLuiz Augusto von Dentz 		     sizeof(struct hci_ev_le_direct_adv_report),
643795118dd4SLuiz Augusto von Dentz 		     HCI_MAX_EVENT_SIZE),
643895118dd4SLuiz Augusto von Dentz 	/* [0x0c = HCI_EV_LE_PHY_UPDATE_COMPLETE] */
643995118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_PHY_UPDATE_COMPLETE, hci_le_phy_update_evt,
644095118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_phy_update_complete)),
644195118dd4SLuiz Augusto von Dentz 	/* [0x0d = HCI_EV_LE_EXT_ADV_REPORT] */
644295118dd4SLuiz Augusto von Dentz 	HCI_LE_EV_VL(HCI_EV_LE_EXT_ADV_REPORT, hci_le_ext_adv_report_evt,
644395118dd4SLuiz Augusto von Dentz 		     sizeof(struct hci_ev_le_ext_adv_report),
644495118dd4SLuiz Augusto von Dentz 		     HCI_MAX_EVENT_SIZE),
644595118dd4SLuiz Augusto von Dentz 	/* [0x12 = HCI_EV_LE_EXT_ADV_SET_TERM] */
644695118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_EXT_ADV_SET_TERM, hci_le_ext_adv_term_evt,
644795118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_evt_le_ext_adv_set_term)),
644895118dd4SLuiz Augusto von Dentz };
644995118dd4SLuiz Augusto von Dentz 
64503e54c589SLuiz Augusto von Dentz static void hci_le_meta_evt(struct hci_dev *hdev, void *data,
64513e54c589SLuiz Augusto von Dentz 			    struct sk_buff *skb)
6452fcd89c09SVille Tervo {
64533e54c589SLuiz Augusto von Dentz 	struct hci_ev_le_meta *ev = data;
645495118dd4SLuiz Augusto von Dentz 	const struct hci_le_ev *subev;
6455fcd89c09SVille Tervo 
645695118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "subevent 0x%2.2x", ev->subevent);
6457fcd89c09SVille Tervo 
645895118dd4SLuiz Augusto von Dentz 	subev = &hci_le_ev_table[ev->subevent];
645995118dd4SLuiz Augusto von Dentz 	if (!subev->func)
646095118dd4SLuiz Augusto von Dentz 		return;
64611855d92dSMarcel Holtmann 
646295118dd4SLuiz Augusto von Dentz 	if (skb->len < subev->min_len) {
646395118dd4SLuiz Augusto von Dentz 		bt_dev_err(hdev, "unexpected subevent 0x%2.2x length: %u < %u",
646495118dd4SLuiz Augusto von Dentz 			   ev->subevent, skb->len, subev->min_len);
646595118dd4SLuiz Augusto von Dentz 		return;
6466fcd89c09SVille Tervo 	}
646795118dd4SLuiz Augusto von Dentz 
646895118dd4SLuiz Augusto von Dentz 	/* Just warn if the length is over max_len size it still be
646995118dd4SLuiz Augusto von Dentz 	 * possible to partially parse the event so leave to callback to
647095118dd4SLuiz Augusto von Dentz 	 * decide if that is acceptable.
647195118dd4SLuiz Augusto von Dentz 	 */
647295118dd4SLuiz Augusto von Dentz 	if (skb->len > subev->max_len)
647395118dd4SLuiz Augusto von Dentz 		bt_dev_warn(hdev, "unexpected subevent 0x%2.2x length: %u > %u",
647495118dd4SLuiz Augusto von Dentz 			    ev->subevent, skb->len, subev->max_len);
647595118dd4SLuiz Augusto von Dentz 
647695118dd4SLuiz Augusto von Dentz 	data = hci_le_ev_skb_pull(hdev, skb, ev->subevent, subev->min_len);
647795118dd4SLuiz Augusto von Dentz 	if (!data)
647895118dd4SLuiz Augusto von Dentz 		return;
647995118dd4SLuiz Augusto von Dentz 
648095118dd4SLuiz Augusto von Dentz 	subev->func(hdev, data, skb);
6481fcd89c09SVille Tervo }
6482fcd89c09SVille Tervo 
6483757aa0b5SJohan Hedberg static bool hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode,
6484757aa0b5SJohan Hedberg 				 u8 event, struct sk_buff *skb)
6485757aa0b5SJohan Hedberg {
6486757aa0b5SJohan Hedberg 	struct hci_ev_cmd_complete *ev;
6487757aa0b5SJohan Hedberg 	struct hci_event_hdr *hdr;
6488757aa0b5SJohan Hedberg 
6489757aa0b5SJohan Hedberg 	if (!skb)
6490757aa0b5SJohan Hedberg 		return false;
6491757aa0b5SJohan Hedberg 
6492e3f3a1aeSLuiz Augusto von Dentz 	hdr = hci_ev_skb_pull(hdev, skb, event, sizeof(*hdr));
6493e3f3a1aeSLuiz Augusto von Dentz 	if (!hdr)
6494757aa0b5SJohan Hedberg 		return false;
6495757aa0b5SJohan Hedberg 
6496757aa0b5SJohan Hedberg 	if (event) {
6497757aa0b5SJohan Hedberg 		if (hdr->evt != event)
6498757aa0b5SJohan Hedberg 			return false;
6499757aa0b5SJohan Hedberg 		return true;
6500757aa0b5SJohan Hedberg 	}
6501757aa0b5SJohan Hedberg 
650291641b79SZheng Yongjun 	/* Check if request ended in Command Status - no way to retrieve
65031629db9cSJohan Hedberg 	 * any extra parameters in this case.
65041629db9cSJohan Hedberg 	 */
65051629db9cSJohan Hedberg 	if (hdr->evt == HCI_EV_CMD_STATUS)
65061629db9cSJohan Hedberg 		return false;
65071629db9cSJohan Hedberg 
6508757aa0b5SJohan Hedberg 	if (hdr->evt != HCI_EV_CMD_COMPLETE) {
65092064ee33SMarcel Holtmann 		bt_dev_err(hdev, "last event is not cmd complete (0x%2.2x)",
65102064ee33SMarcel Holtmann 			   hdr->evt);
6511757aa0b5SJohan Hedberg 		return false;
6512757aa0b5SJohan Hedberg 	}
6513757aa0b5SJohan Hedberg 
6514e3f3a1aeSLuiz Augusto von Dentz 	ev = hci_cc_skb_pull(hdev, skb, opcode, sizeof(*ev));
6515e3f3a1aeSLuiz Augusto von Dentz 	if (!ev)
6516757aa0b5SJohan Hedberg 		return false;
6517757aa0b5SJohan Hedberg 
6518757aa0b5SJohan Hedberg 	if (opcode != __le16_to_cpu(ev->opcode)) {
6519757aa0b5SJohan Hedberg 		BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode,
6520757aa0b5SJohan Hedberg 		       __le16_to_cpu(ev->opcode));
6521757aa0b5SJohan Hedberg 		return false;
6522757aa0b5SJohan Hedberg 	}
6523757aa0b5SJohan Hedberg 
6524757aa0b5SJohan Hedberg 	return true;
6525757aa0b5SJohan Hedberg }
6526757aa0b5SJohan Hedberg 
65272f20216cSAbhishek Pandit-Subedi static void hci_store_wake_reason(struct hci_dev *hdev, u8 event,
65282f20216cSAbhishek Pandit-Subedi 				  struct sk_buff *skb)
65292f20216cSAbhishek Pandit-Subedi {
65302f20216cSAbhishek Pandit-Subedi 	struct hci_ev_le_advertising_info *adv;
65312f20216cSAbhishek Pandit-Subedi 	struct hci_ev_le_direct_adv_info *direct_adv;
6532b48b833fSLuiz Augusto von Dentz 	struct hci_ev_le_ext_adv_info *ext_adv;
65332f20216cSAbhishek Pandit-Subedi 	const struct hci_ev_conn_complete *conn_complete = (void *)skb->data;
65342f20216cSAbhishek Pandit-Subedi 	const struct hci_ev_conn_request *conn_request = (void *)skb->data;
65352f20216cSAbhishek Pandit-Subedi 
65362f20216cSAbhishek Pandit-Subedi 	hci_dev_lock(hdev);
65372f20216cSAbhishek Pandit-Subedi 
65382f20216cSAbhishek Pandit-Subedi 	/* If we are currently suspended and this is the first BT event seen,
65392f20216cSAbhishek Pandit-Subedi 	 * save the wake reason associated with the event.
65402f20216cSAbhishek Pandit-Subedi 	 */
65412f20216cSAbhishek Pandit-Subedi 	if (!hdev->suspended || hdev->wake_reason)
65422f20216cSAbhishek Pandit-Subedi 		goto unlock;
65432f20216cSAbhishek Pandit-Subedi 
65442f20216cSAbhishek Pandit-Subedi 	/* Default to remote wake. Values for wake_reason are documented in the
65452f20216cSAbhishek Pandit-Subedi 	 * Bluez mgmt api docs.
65462f20216cSAbhishek Pandit-Subedi 	 */
65472f20216cSAbhishek Pandit-Subedi 	hdev->wake_reason = MGMT_WAKE_REASON_REMOTE_WAKE;
65482f20216cSAbhishek Pandit-Subedi 
65492f20216cSAbhishek Pandit-Subedi 	/* Once configured for remote wakeup, we should only wake up for
65502f20216cSAbhishek Pandit-Subedi 	 * reconnections. It's useful to see which device is waking us up so
65512f20216cSAbhishek Pandit-Subedi 	 * keep track of the bdaddr of the connection event that woke us up.
65522f20216cSAbhishek Pandit-Subedi 	 */
65532f20216cSAbhishek Pandit-Subedi 	if (event == HCI_EV_CONN_REQUEST) {
65542f20216cSAbhishek Pandit-Subedi 		bacpy(&hdev->wake_addr, &conn_complete->bdaddr);
65552f20216cSAbhishek Pandit-Subedi 		hdev->wake_addr_type = BDADDR_BREDR;
65562f20216cSAbhishek Pandit-Subedi 	} else if (event == HCI_EV_CONN_COMPLETE) {
65572f20216cSAbhishek Pandit-Subedi 		bacpy(&hdev->wake_addr, &conn_request->bdaddr);
65582f20216cSAbhishek Pandit-Subedi 		hdev->wake_addr_type = BDADDR_BREDR;
65592f20216cSAbhishek Pandit-Subedi 	} else if (event == HCI_EV_LE_META) {
65602f20216cSAbhishek Pandit-Subedi 		struct hci_ev_le_meta *le_ev = (void *)skb->data;
65612f20216cSAbhishek Pandit-Subedi 		u8 subevent = le_ev->subevent;
65622f20216cSAbhishek Pandit-Subedi 		u8 *ptr = &skb->data[sizeof(*le_ev)];
65632f20216cSAbhishek Pandit-Subedi 		u8 num_reports = *ptr;
65642f20216cSAbhishek Pandit-Subedi 
65652f20216cSAbhishek Pandit-Subedi 		if ((subevent == HCI_EV_LE_ADVERTISING_REPORT ||
65662f20216cSAbhishek Pandit-Subedi 		     subevent == HCI_EV_LE_DIRECT_ADV_REPORT ||
65672f20216cSAbhishek Pandit-Subedi 		     subevent == HCI_EV_LE_EXT_ADV_REPORT) &&
65682f20216cSAbhishek Pandit-Subedi 		    num_reports) {
65692f20216cSAbhishek Pandit-Subedi 			adv = (void *)(ptr + 1);
65702f20216cSAbhishek Pandit-Subedi 			direct_adv = (void *)(ptr + 1);
65712f20216cSAbhishek Pandit-Subedi 			ext_adv = (void *)(ptr + 1);
65722f20216cSAbhishek Pandit-Subedi 
65732f20216cSAbhishek Pandit-Subedi 			switch (subevent) {
65742f20216cSAbhishek Pandit-Subedi 			case HCI_EV_LE_ADVERTISING_REPORT:
65752f20216cSAbhishek Pandit-Subedi 				bacpy(&hdev->wake_addr, &adv->bdaddr);
65762f20216cSAbhishek Pandit-Subedi 				hdev->wake_addr_type = adv->bdaddr_type;
65772f20216cSAbhishek Pandit-Subedi 				break;
65782f20216cSAbhishek Pandit-Subedi 			case HCI_EV_LE_DIRECT_ADV_REPORT:
65792f20216cSAbhishek Pandit-Subedi 				bacpy(&hdev->wake_addr, &direct_adv->bdaddr);
65802f20216cSAbhishek Pandit-Subedi 				hdev->wake_addr_type = direct_adv->bdaddr_type;
65812f20216cSAbhishek Pandit-Subedi 				break;
65822f20216cSAbhishek Pandit-Subedi 			case HCI_EV_LE_EXT_ADV_REPORT:
65832f20216cSAbhishek Pandit-Subedi 				bacpy(&hdev->wake_addr, &ext_adv->bdaddr);
65842f20216cSAbhishek Pandit-Subedi 				hdev->wake_addr_type = ext_adv->bdaddr_type;
65852f20216cSAbhishek Pandit-Subedi 				break;
65862f20216cSAbhishek Pandit-Subedi 			}
65872f20216cSAbhishek Pandit-Subedi 		}
65882f20216cSAbhishek Pandit-Subedi 	} else {
65892f20216cSAbhishek Pandit-Subedi 		hdev->wake_reason = MGMT_WAKE_REASON_UNEXPECTED;
65902f20216cSAbhishek Pandit-Subedi 	}
65912f20216cSAbhishek Pandit-Subedi 
65922f20216cSAbhishek Pandit-Subedi unlock:
65932f20216cSAbhishek Pandit-Subedi 	hci_dev_unlock(hdev);
65942f20216cSAbhishek Pandit-Subedi }
65952f20216cSAbhishek Pandit-Subedi 
65963e54c589SLuiz Augusto von Dentz #define HCI_EV_VL(_op, _func, _min_len, _max_len) \
65973e54c589SLuiz Augusto von Dentz [_op] = { \
65983e54c589SLuiz Augusto von Dentz 	.req = false, \
65993e54c589SLuiz Augusto von Dentz 	.func = _func, \
66003e54c589SLuiz Augusto von Dentz 	.min_len = _min_len, \
66013e54c589SLuiz Augusto von Dentz 	.max_len = _max_len, \
66023e54c589SLuiz Augusto von Dentz }
66033e54c589SLuiz Augusto von Dentz 
66043e54c589SLuiz Augusto von Dentz #define HCI_EV(_op, _func, _len) \
66053e54c589SLuiz Augusto von Dentz 	HCI_EV_VL(_op, _func, _len, _len)
66063e54c589SLuiz Augusto von Dentz 
66073e54c589SLuiz Augusto von Dentz #define HCI_EV_STATUS(_op, _func) \
66083e54c589SLuiz Augusto von Dentz 	HCI_EV(_op, _func, sizeof(struct hci_ev_status))
66093e54c589SLuiz Augusto von Dentz 
66103e54c589SLuiz Augusto von Dentz #define HCI_EV_REQ_VL(_op, _func, _min_len, _max_len) \
66113e54c589SLuiz Augusto von Dentz [_op] = { \
66123e54c589SLuiz Augusto von Dentz 	.req = true, \
66133e54c589SLuiz Augusto von Dentz 	.func_req = _func, \
66143e54c589SLuiz Augusto von Dentz 	.min_len = _min_len, \
66153e54c589SLuiz Augusto von Dentz 	.max_len = _max_len, \
66163e54c589SLuiz Augusto von Dentz }
66173e54c589SLuiz Augusto von Dentz 
66183e54c589SLuiz Augusto von Dentz #define HCI_EV_REQ(_op, _func, _len) \
66193e54c589SLuiz Augusto von Dentz 	HCI_EV_REQ_VL(_op, _func, _len, _len)
66203e54c589SLuiz Augusto von Dentz 
66213e54c589SLuiz Augusto von Dentz /* Entries in this table shall have their position according to the event opcode
66223e54c589SLuiz Augusto von Dentz  * they handle so the use of the macros above is recommend since it does attempt
66233e54c589SLuiz Augusto von Dentz  * to initialize at its proper index using Designated Initializers that way
66243e54c589SLuiz Augusto von Dentz  * events without a callback function don't have entered.
66253e54c589SLuiz Augusto von Dentz  */
66263e54c589SLuiz Augusto von Dentz static const struct hci_ev {
66273e54c589SLuiz Augusto von Dentz 	bool req;
66283e54c589SLuiz Augusto von Dentz 	union {
66293e54c589SLuiz Augusto von Dentz 		void (*func)(struct hci_dev *hdev, void *data,
66303e54c589SLuiz Augusto von Dentz 			     struct sk_buff *skb);
66313e54c589SLuiz Augusto von Dentz 		void (*func_req)(struct hci_dev *hdev, void *data,
66323e54c589SLuiz Augusto von Dentz 				 struct sk_buff *skb, u16 *opcode, u8 *status,
66333e54c589SLuiz Augusto von Dentz 				 hci_req_complete_t *req_complete,
66343e54c589SLuiz Augusto von Dentz 				 hci_req_complete_skb_t *req_complete_skb);
66353e54c589SLuiz Augusto von Dentz 	};
66363e54c589SLuiz Augusto von Dentz 	u16  min_len;
66373e54c589SLuiz Augusto von Dentz 	u16  max_len;
66383e54c589SLuiz Augusto von Dentz } hci_ev_table[U8_MAX + 1] = {
66393e54c589SLuiz Augusto von Dentz 	/* [0x01 = HCI_EV_INQUIRY_COMPLETE] */
66403e54c589SLuiz Augusto von Dentz 	HCI_EV_STATUS(HCI_EV_INQUIRY_COMPLETE, hci_inquiry_complete_evt),
66413e54c589SLuiz Augusto von Dentz 	/* [0x02 = HCI_EV_INQUIRY_RESULT] */
66423e54c589SLuiz Augusto von Dentz 	HCI_EV_VL(HCI_EV_INQUIRY_RESULT, hci_inquiry_result_evt,
66433e54c589SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_inquiry_result), HCI_MAX_EVENT_SIZE),
66443e54c589SLuiz Augusto von Dentz 	/* [0x03 = HCI_EV_CONN_COMPLETE] */
66453e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_CONN_COMPLETE, hci_conn_complete_evt,
66463e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_conn_complete)),
66473e54c589SLuiz Augusto von Dentz 	/* [0x04 = HCI_EV_CONN_REQUEST] */
66483e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_CONN_REQUEST, hci_conn_request_evt,
66493e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_conn_request)),
66503e54c589SLuiz Augusto von Dentz 	/* [0x05 = HCI_EV_DISCONN_COMPLETE] */
66513e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_DISCONN_COMPLETE, hci_disconn_complete_evt,
66523e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_disconn_complete)),
66533e54c589SLuiz Augusto von Dentz 	/* [0x06 = HCI_EV_AUTH_COMPLETE] */
66543e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_AUTH_COMPLETE, hci_auth_complete_evt,
66553e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_auth_complete)),
66563e54c589SLuiz Augusto von Dentz 	/* [0x07 = HCI_EV_REMOTE_NAME] */
66573e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_REMOTE_NAME, hci_remote_name_evt,
66583e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_remote_name)),
66593e54c589SLuiz Augusto von Dentz 	/* [0x08 = HCI_EV_ENCRYPT_CHANGE] */
66603e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_ENCRYPT_CHANGE, hci_encrypt_change_evt,
66613e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_encrypt_change)),
66623e54c589SLuiz Augusto von Dentz 	/* [0x09 = HCI_EV_CHANGE_LINK_KEY_COMPLETE] */
66633e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_CHANGE_LINK_KEY_COMPLETE,
66643e54c589SLuiz Augusto von Dentz 	       hci_change_link_key_complete_evt,
66653e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_change_link_key_complete)),
66663e54c589SLuiz Augusto von Dentz 	/* [0x0b = HCI_EV_REMOTE_FEATURES] */
66673e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_REMOTE_FEATURES, hci_remote_features_evt,
66683e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_remote_features)),
66693e54c589SLuiz Augusto von Dentz 	/* [0x0e = HCI_EV_CMD_COMPLETE] */
66703e54c589SLuiz Augusto von Dentz 	HCI_EV_REQ_VL(HCI_EV_CMD_COMPLETE, hci_cmd_complete_evt,
66713e54c589SLuiz Augusto von Dentz 		      sizeof(struct hci_ev_cmd_complete), HCI_MAX_EVENT_SIZE),
66723e54c589SLuiz Augusto von Dentz 	/* [0x0f = HCI_EV_CMD_STATUS] */
66733e54c589SLuiz Augusto von Dentz 	HCI_EV_REQ(HCI_EV_CMD_STATUS, hci_cmd_status_evt,
66743e54c589SLuiz Augusto von Dentz 		   sizeof(struct hci_ev_cmd_status)),
66753e54c589SLuiz Augusto von Dentz 	/* [0x10 = HCI_EV_CMD_STATUS] */
66763e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_HARDWARE_ERROR, hci_hardware_error_evt,
66773e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_hardware_error)),
66783e54c589SLuiz Augusto von Dentz 	/* [0x12 = HCI_EV_ROLE_CHANGE] */
66793e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_ROLE_CHANGE, hci_role_change_evt,
66803e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_role_change)),
66813e54c589SLuiz Augusto von Dentz 	/* [0x13 = HCI_EV_NUM_COMP_PKTS] */
66823e54c589SLuiz Augusto von Dentz 	HCI_EV_VL(HCI_EV_NUM_COMP_PKTS, hci_num_comp_pkts_evt,
66833e54c589SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_num_comp_pkts), HCI_MAX_EVENT_SIZE),
66843e54c589SLuiz Augusto von Dentz 	/* [0x14 = HCI_EV_MODE_CHANGE] */
66853e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_MODE_CHANGE, hci_mode_change_evt,
66863e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_mode_change)),
66873e54c589SLuiz Augusto von Dentz 	/* [0x16 = HCI_EV_PIN_CODE_REQ] */
66883e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_PIN_CODE_REQ, hci_pin_code_request_evt,
66893e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_pin_code_req)),
66903e54c589SLuiz Augusto von Dentz 	/* [0x17 = HCI_EV_LINK_KEY_REQ] */
66913e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_LINK_KEY_REQ, hci_link_key_request_evt,
66923e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_link_key_req)),
66933e54c589SLuiz Augusto von Dentz 	/* [0x18 = HCI_EV_LINK_KEY_NOTIFY] */
66943e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_LINK_KEY_NOTIFY, hci_link_key_notify_evt,
66953e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_link_key_notify)),
66963e54c589SLuiz Augusto von Dentz 	/* [0x1c = HCI_EV_CLOCK_OFFSET] */
66973e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_CLOCK_OFFSET, hci_clock_offset_evt,
66983e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_clock_offset)),
66993e54c589SLuiz Augusto von Dentz 	/* [0x1d = HCI_EV_PKT_TYPE_CHANGE] */
67003e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_PKT_TYPE_CHANGE, hci_pkt_type_change_evt,
67013e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_pkt_type_change)),
67023e54c589SLuiz Augusto von Dentz 	/* [0x20 = HCI_EV_PSCAN_REP_MODE] */
67033e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_PSCAN_REP_MODE, hci_pscan_rep_mode_evt,
67043e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_pscan_rep_mode)),
67053e54c589SLuiz Augusto von Dentz 	/* [0x22 = HCI_EV_INQUIRY_RESULT_WITH_RSSI] */
67063e54c589SLuiz Augusto von Dentz 	HCI_EV_VL(HCI_EV_INQUIRY_RESULT_WITH_RSSI,
67073e54c589SLuiz Augusto von Dentz 		  hci_inquiry_result_with_rssi_evt,
67083e54c589SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_inquiry_result_rssi),
67093e54c589SLuiz Augusto von Dentz 		  HCI_MAX_EVENT_SIZE),
67103e54c589SLuiz Augusto von Dentz 	/* [0x23 = HCI_EV_REMOTE_EXT_FEATURES] */
67113e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_REMOTE_EXT_FEATURES, hci_remote_ext_features_evt,
67123e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_remote_ext_features)),
67133e54c589SLuiz Augusto von Dentz 	/* [0x2c = HCI_EV_SYNC_CONN_COMPLETE] */
67143e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_SYNC_CONN_COMPLETE, hci_sync_conn_complete_evt,
67153e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_sync_conn_complete)),
67163e54c589SLuiz Augusto von Dentz 	/* [0x2d = HCI_EV_EXTENDED_INQUIRY_RESULT] */
67173e54c589SLuiz Augusto von Dentz 	HCI_EV_VL(HCI_EV_EXTENDED_INQUIRY_RESULT,
67183e54c589SLuiz Augusto von Dentz 		  hci_extended_inquiry_result_evt,
67193e54c589SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_ext_inquiry_result), HCI_MAX_EVENT_SIZE),
67203e54c589SLuiz Augusto von Dentz 	/* [0x30 = HCI_EV_KEY_REFRESH_COMPLETE] */
67213e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_KEY_REFRESH_COMPLETE, hci_key_refresh_complete_evt,
67223e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_key_refresh_complete)),
67233e54c589SLuiz Augusto von Dentz 	/* [0x31 = HCI_EV_IO_CAPA_REQUEST] */
67243e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_IO_CAPA_REQUEST, hci_io_capa_request_evt,
67253e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_io_capa_request)),
67263e54c589SLuiz Augusto von Dentz 	/* [0x32 = HCI_EV_IO_CAPA_REPLY] */
67273e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_IO_CAPA_REPLY, hci_io_capa_reply_evt,
67283e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_io_capa_reply)),
67293e54c589SLuiz Augusto von Dentz 	/* [0x33 = HCI_EV_USER_CONFIRM_REQUEST] */
67303e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_USER_CONFIRM_REQUEST, hci_user_confirm_request_evt,
67313e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_user_confirm_req)),
67323e54c589SLuiz Augusto von Dentz 	/* [0x34 = HCI_EV_USER_PASSKEY_REQUEST] */
67333e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_USER_PASSKEY_REQUEST, hci_user_passkey_request_evt,
67343e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_user_passkey_req)),
67353e54c589SLuiz Augusto von Dentz 	/* [0x35 = HCI_EV_REMOTE_OOB_DATA_REQUEST] */
67363e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_REMOTE_OOB_DATA_REQUEST, hci_remote_oob_data_request_evt,
67373e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_remote_oob_data_request)),
67383e54c589SLuiz Augusto von Dentz 	/* [0x36 = HCI_EV_SIMPLE_PAIR_COMPLETE] */
67393e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_SIMPLE_PAIR_COMPLETE, hci_simple_pair_complete_evt,
67403e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_simple_pair_complete)),
67413e54c589SLuiz Augusto von Dentz 	/* [0x3b = HCI_EV_USER_PASSKEY_NOTIFY] */
67423e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_USER_PASSKEY_NOTIFY, hci_user_passkey_notify_evt,
67433e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_user_passkey_notify)),
67443e54c589SLuiz Augusto von Dentz 	/* [0x3c = HCI_EV_KEYPRESS_NOTIFY] */
67453e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_KEYPRESS_NOTIFY, hci_keypress_notify_evt,
67463e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_keypress_notify)),
67473e54c589SLuiz Augusto von Dentz 	/* [0x3d = HCI_EV_REMOTE_HOST_FEATURES] */
67483e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_REMOTE_HOST_FEATURES, hci_remote_host_features_evt,
67493e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_remote_host_features)),
67503e54c589SLuiz Augusto von Dentz 	/* [0x3e = HCI_EV_LE_META] */
67513e54c589SLuiz Augusto von Dentz 	HCI_EV_VL(HCI_EV_LE_META, hci_le_meta_evt,
67523e54c589SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_meta), HCI_MAX_EVENT_SIZE),
67533e54c589SLuiz Augusto von Dentz #if IS_ENABLED(CONFIG_BT_HS)
67543e54c589SLuiz Augusto von Dentz 	/* [0x40 = HCI_EV_PHY_LINK_COMPLETE] */
67553e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_PHY_LINK_COMPLETE, hci_phy_link_complete_evt,
67563e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_phy_link_complete)),
67573e54c589SLuiz Augusto von Dentz 	/* [0x41 = HCI_EV_CHANNEL_SELECTED] */
67583e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_CHANNEL_SELECTED, hci_chan_selected_evt,
67593e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_channel_selected)),
67603e54c589SLuiz Augusto von Dentz 	/* [0x42 = HCI_EV_DISCONN_PHY_LINK_COMPLETE] */
67613e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE,
67623e54c589SLuiz Augusto von Dentz 	       hci_disconn_loglink_complete_evt,
67633e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_disconn_logical_link_complete)),
67643e54c589SLuiz Augusto von Dentz 	/* [0x45 = HCI_EV_LOGICAL_LINK_COMPLETE] */
67653e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_LOGICAL_LINK_COMPLETE, hci_loglink_complete_evt,
67663e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_logical_link_complete)),
67673e54c589SLuiz Augusto von Dentz 	/* [0x46 = HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE] */
67683e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_DISCONN_PHY_LINK_COMPLETE,
67693e54c589SLuiz Augusto von Dentz 	       hci_disconn_phylink_complete_evt,
67703e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_disconn_phy_link_complete)),
67713e54c589SLuiz Augusto von Dentz #endif
67723e54c589SLuiz Augusto von Dentz 	/* [0x48 = HCI_EV_NUM_COMP_BLOCKS] */
67733e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_NUM_COMP_BLOCKS, hci_num_comp_blocks_evt,
67743e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_num_comp_blocks)),
67753e54c589SLuiz Augusto von Dentz 	/* [0xff = HCI_EV_VENDOR] */
67763e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_VENDOR, msft_vendor_evt, 0),
67773e54c589SLuiz Augusto von Dentz };
67783e54c589SLuiz Augusto von Dentz 
67793e54c589SLuiz Augusto von Dentz static void hci_event_func(struct hci_dev *hdev, u8 event, struct sk_buff *skb,
67803e54c589SLuiz Augusto von Dentz 			   u16 *opcode, u8 *status,
67813e54c589SLuiz Augusto von Dentz 			   hci_req_complete_t *req_complete,
67823e54c589SLuiz Augusto von Dentz 			   hci_req_complete_skb_t *req_complete_skb)
67833e54c589SLuiz Augusto von Dentz {
67843e54c589SLuiz Augusto von Dentz 	const struct hci_ev *ev = &hci_ev_table[event];
67853e54c589SLuiz Augusto von Dentz 	void *data;
67863e54c589SLuiz Augusto von Dentz 
67873e54c589SLuiz Augusto von Dentz 	if (!ev->func)
67883e54c589SLuiz Augusto von Dentz 		return;
67893e54c589SLuiz Augusto von Dentz 
67903e54c589SLuiz Augusto von Dentz 	if (skb->len < ev->min_len) {
67913e54c589SLuiz Augusto von Dentz 		bt_dev_err(hdev, "unexpected event 0x%2.2x length: %u < %u",
67923e54c589SLuiz Augusto von Dentz 			   event, skb->len, ev->min_len);
67933e54c589SLuiz Augusto von Dentz 		return;
67943e54c589SLuiz Augusto von Dentz 	}
67953e54c589SLuiz Augusto von Dentz 
67963e54c589SLuiz Augusto von Dentz 	/* Just warn if the length is over max_len size it still be
67973e54c589SLuiz Augusto von Dentz 	 * possible to partially parse the event so leave to callback to
67983e54c589SLuiz Augusto von Dentz 	 * decide if that is acceptable.
67993e54c589SLuiz Augusto von Dentz 	 */
68003e54c589SLuiz Augusto von Dentz 	if (skb->len > ev->max_len)
68013e54c589SLuiz Augusto von Dentz 		bt_dev_warn(hdev, "unexpected event 0x%2.2x length: %u > %u",
68023e54c589SLuiz Augusto von Dentz 			    event, skb->len, ev->max_len);
68033e54c589SLuiz Augusto von Dentz 
68043e54c589SLuiz Augusto von Dentz 	data = hci_ev_skb_pull(hdev, skb, event, ev->min_len);
68053e54c589SLuiz Augusto von Dentz 	if (!data)
68063e54c589SLuiz Augusto von Dentz 		return;
68073e54c589SLuiz Augusto von Dentz 
68083e54c589SLuiz Augusto von Dentz 	if (ev->req)
68093e54c589SLuiz Augusto von Dentz 		ev->func_req(hdev, data, skb, opcode, status, req_complete,
68103e54c589SLuiz Augusto von Dentz 			     req_complete_skb);
68113e54c589SLuiz Augusto von Dentz 	else
68123e54c589SLuiz Augusto von Dentz 		ev->func(hdev, data, skb);
68133e54c589SLuiz Augusto von Dentz }
68143e54c589SLuiz Augusto von Dentz 
68151da177e4SLinus Torvalds void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
68161da177e4SLinus Torvalds {
6817a9de9248SMarcel Holtmann 	struct hci_event_hdr *hdr = (void *) skb->data;
6818e6214487SJohan Hedberg 	hci_req_complete_t req_complete = NULL;
6819e6214487SJohan Hedberg 	hci_req_complete_skb_t req_complete_skb = NULL;
6820e6214487SJohan Hedberg 	struct sk_buff *orig_skb = NULL;
6821e3f3a1aeSLuiz Augusto von Dentz 	u8 status = 0, event, req_evt = 0;
6822e6214487SJohan Hedberg 	u16 opcode = HCI_OP_NOP;
68231da177e4SLinus Torvalds 
6824e3f3a1aeSLuiz Augusto von Dentz 	if (skb->len < sizeof(*hdr)) {
6825e3f3a1aeSLuiz Augusto von Dentz 		bt_dev_err(hdev, "Malformed HCI Event");
6826e3f3a1aeSLuiz Augusto von Dentz 		goto done;
6827e3f3a1aeSLuiz Augusto von Dentz 	}
6828e3f3a1aeSLuiz Augusto von Dentz 
6829e3f3a1aeSLuiz Augusto von Dentz 	event = hdr->evt;
683008bb4da9SAlain Michaud 	if (!event) {
68313e54c589SLuiz Augusto von Dentz 		bt_dev_warn(hdev, "Received unexpected HCI Event 0x%2.2x",
68323e54c589SLuiz Augusto von Dentz 			    event);
683308bb4da9SAlain Michaud 		goto done;
683408bb4da9SAlain Michaud 	}
683508bb4da9SAlain Michaud 
6836242c0ebdSMarcel Holtmann 	if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->hci.req_event == event) {
6837c1f23a2bSJohannes Berg 		struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data;
6838e6214487SJohan Hedberg 		opcode = __le16_to_cpu(cmd_hdr->opcode);
6839e6214487SJohan Hedberg 		hci_req_cmd_complete(hdev, opcode, status, &req_complete,
6840e6214487SJohan Hedberg 				     &req_complete_skb);
6841757aa0b5SJohan Hedberg 		req_evt = event;
684202350a72SJohan Hedberg 	}
684302350a72SJohan Hedberg 
6844e6214487SJohan Hedberg 	/* If it looks like we might end up having to call
6845e6214487SJohan Hedberg 	 * req_complete_skb, store a pristine copy of the skb since the
6846e6214487SJohan Hedberg 	 * various handlers may modify the original one through
6847e6214487SJohan Hedberg 	 * skb_pull() calls, etc.
6848e6214487SJohan Hedberg 	 */
6849e6214487SJohan Hedberg 	if (req_complete_skb || event == HCI_EV_CMD_STATUS ||
6850e6214487SJohan Hedberg 	    event == HCI_EV_CMD_COMPLETE)
6851e6214487SJohan Hedberg 		orig_skb = skb_clone(skb, GFP_KERNEL);
6852e6214487SJohan Hedberg 
6853e6214487SJohan Hedberg 	skb_pull(skb, HCI_EVENT_HDR_SIZE);
6854e6214487SJohan Hedberg 
68552f20216cSAbhishek Pandit-Subedi 	/* Store wake reason if we're suspended */
68562f20216cSAbhishek Pandit-Subedi 	hci_store_wake_reason(hdev, event, skb);
68572f20216cSAbhishek Pandit-Subedi 
68583e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "event 0x%2.2x", event);
68591da177e4SLinus Torvalds 
68603e54c589SLuiz Augusto von Dentz 	hci_event_func(hdev, event, skb, &opcode, &status, &req_complete,
6861e6214487SJohan Hedberg 		       &req_complete_skb);
68621da177e4SLinus Torvalds 
6863757aa0b5SJohan Hedberg 	if (req_complete) {
6864e6214487SJohan Hedberg 		req_complete(hdev, status, opcode);
6865757aa0b5SJohan Hedberg 	} else if (req_complete_skb) {
6866757aa0b5SJohan Hedberg 		if (!hci_get_cmd_complete(hdev, opcode, req_evt, orig_skb)) {
6867757aa0b5SJohan Hedberg 			kfree_skb(orig_skb);
6868757aa0b5SJohan Hedberg 			orig_skb = NULL;
6869757aa0b5SJohan Hedberg 		}
6870e6214487SJohan Hedberg 		req_complete_skb(hdev, status, opcode, orig_skb);
6871757aa0b5SJohan Hedberg 	}
6872e6214487SJohan Hedberg 
687308bb4da9SAlain Michaud done:
6874e6214487SJohan Hedberg 	kfree_skb(orig_skb);
68751da177e4SLinus Torvalds 	kfree_skb(skb);
68761da177e4SLinus Torvalds 	hdev->stat.evt_rx++;
68771da177e4SLinus Torvalds }
6878