xref: /openbmc/linux/net/bluetooth/hci_event.c (revision 5af2e235)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds    BlueZ - Bluetooth protocol stack for Linux
32d0a0346SRon Shaffer    Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
40fe8c8d0SIulia Tanasescu    Copyright 2023 NXP
51da177e4SLinus Torvalds 
61da177e4SLinus Torvalds    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
71da177e4SLinus Torvalds 
81da177e4SLinus Torvalds    This program is free software; you can redistribute it and/or modify
91da177e4SLinus Torvalds    it under the terms of the GNU General Public License version 2 as
101da177e4SLinus Torvalds    published by the Free Software Foundation;
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
131da177e4SLinus Torvalds    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
141da177e4SLinus Torvalds    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
151da177e4SLinus Torvalds    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
161da177e4SLinus Torvalds    CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
171da177e4SLinus Torvalds    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
181da177e4SLinus Torvalds    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
191da177e4SLinus Torvalds    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
201da177e4SLinus Torvalds 
211da177e4SLinus Torvalds    ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
221da177e4SLinus Torvalds    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
231da177e4SLinus Torvalds    SOFTWARE IS DISCLAIMED.
241da177e4SLinus Torvalds */
251da177e4SLinus Torvalds 
261da177e4SLinus Torvalds /* Bluetooth HCI event handling. */
271da177e4SLinus Torvalds 
281da177e4SLinus Torvalds #include <asm/unaligned.h>
29b5412606SLuiz Augusto von Dentz #include <linux/crypto.h>
30b5412606SLuiz Augusto von Dentz #include <crypto/algapi.h>
311da177e4SLinus Torvalds 
321da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
331da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
34f0d6a0eaSMikel Astiz #include <net/bluetooth/mgmt.h>
357ef9fbf0SMarcel Holtmann 
360857dd3bSJohan Hedberg #include "hci_request.h"
3723b9ceb7SMarcel Holtmann #include "hci_debugfs.h"
38b938790eSLuiz Augusto von Dentz #include "hci_codec.h"
392ceba539SJohan Hedberg #include "smp.h"
40145373cbSMiao-chen Chou #include "msft.h"
4101ce70b0SLuiz Augusto von Dentz #include "eir.h"
421da177e4SLinus Torvalds 
43aa5b0345SMarcel Holtmann #define ZERO_KEY "\x00\x00\x00\x00\x00\x00\x00\x00" \
44aa5b0345SMarcel Holtmann 		 "\x00\x00\x00\x00\x00\x00\x00\x00"
45aa5b0345SMarcel Holtmann 
46c45074d6SLuiz Augusto von Dentz #define secs_to_jiffies(_secs) msecs_to_jiffies((_secs) * 1000)
47c45074d6SLuiz Augusto von Dentz 
481da177e4SLinus Torvalds /* Handle HCI Event packets */
491da177e4SLinus Torvalds 
hci_ev_skb_pull(struct hci_dev * hdev,struct sk_buff * skb,u8 ev,size_t len)50ae61a10dSLuiz Augusto von Dentz static void *hci_ev_skb_pull(struct hci_dev *hdev, struct sk_buff *skb,
51ae61a10dSLuiz Augusto von Dentz 			     u8 ev, size_t len)
52ae61a10dSLuiz Augusto von Dentz {
53ae61a10dSLuiz Augusto von Dentz 	void *data;
54ae61a10dSLuiz Augusto von Dentz 
55ae61a10dSLuiz Augusto von Dentz 	data = skb_pull_data(skb, len);
56ae61a10dSLuiz Augusto von Dentz 	if (!data)
57ae61a10dSLuiz Augusto von Dentz 		bt_dev_err(hdev, "Malformed Event: 0x%2.2x", ev);
58ae61a10dSLuiz Augusto von Dentz 
59ae61a10dSLuiz Augusto von Dentz 	return data;
60ae61a10dSLuiz Augusto von Dentz }
61ae61a10dSLuiz Augusto von Dentz 
hci_cc_skb_pull(struct hci_dev * hdev,struct sk_buff * skb,u16 op,size_t len)62e3f3a1aeSLuiz Augusto von Dentz static void *hci_cc_skb_pull(struct hci_dev *hdev, struct sk_buff *skb,
63e3f3a1aeSLuiz Augusto von Dentz 			     u16 op, size_t len)
64e3f3a1aeSLuiz Augusto von Dentz {
65e3f3a1aeSLuiz Augusto von Dentz 	void *data;
66e3f3a1aeSLuiz Augusto von Dentz 
67e3f3a1aeSLuiz Augusto von Dentz 	data = skb_pull_data(skb, len);
68e3f3a1aeSLuiz Augusto von Dentz 	if (!data)
69e3f3a1aeSLuiz Augusto von Dentz 		bt_dev_err(hdev, "Malformed Command Complete: 0x%4.4x", op);
70e3f3a1aeSLuiz Augusto von Dentz 
71e3f3a1aeSLuiz Augusto von Dentz 	return data;
72e3f3a1aeSLuiz Augusto von Dentz }
73e3f3a1aeSLuiz Augusto von Dentz 
hci_le_ev_skb_pull(struct hci_dev * hdev,struct sk_buff * skb,u8 ev,size_t len)7412cfe417SLuiz Augusto von Dentz static void *hci_le_ev_skb_pull(struct hci_dev *hdev, struct sk_buff *skb,
7512cfe417SLuiz Augusto von Dentz 				u8 ev, size_t len)
7612cfe417SLuiz Augusto von Dentz {
7712cfe417SLuiz Augusto von Dentz 	void *data;
7812cfe417SLuiz Augusto von Dentz 
7912cfe417SLuiz Augusto von Dentz 	data = skb_pull_data(skb, len);
8012cfe417SLuiz Augusto von Dentz 	if (!data)
8112cfe417SLuiz Augusto von Dentz 		bt_dev_err(hdev, "Malformed LE Event: 0x%2.2x", ev);
8212cfe417SLuiz Augusto von Dentz 
8312cfe417SLuiz Augusto von Dentz 	return data;
8412cfe417SLuiz Augusto von Dentz }
8512cfe417SLuiz Augusto von Dentz 
hci_cc_inquiry_cancel(struct hci_dev * hdev,void * data,struct sk_buff * skb)86c8992cffSLuiz Augusto von Dentz static u8 hci_cc_inquiry_cancel(struct hci_dev *hdev, void *data,
87c8992cffSLuiz Augusto von Dentz 				struct sk_buff *skb)
881da177e4SLinus Torvalds {
89c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
90e3f3a1aeSLuiz Augusto von Dentz 
91e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
921da177e4SLinus Torvalds 
93adf1d692SSonny Sasaka 	/* It is possible that we receive Inquiry Complete event right
94adf1d692SSonny Sasaka 	 * before we receive Inquiry Cancel Command Complete event, in
95adf1d692SSonny Sasaka 	 * which case the latter event should have status of Command
96adf1d692SSonny Sasaka 	 * Disallowed (0x0c). This should not be treated as error, since
97adf1d692SSonny Sasaka 	 * we actually achieve what Inquiry Cancel wants to achieve,
98adf1d692SSonny Sasaka 	 * which is to end the last Inquiry session.
99adf1d692SSonny Sasaka 	 */
100e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status == 0x0c && !test_bit(HCI_INQUIRY, &hdev->flags)) {
101adf1d692SSonny Sasaka 		bt_dev_warn(hdev, "Ignoring error of Inquiry Cancel command");
102e3f3a1aeSLuiz Augusto von Dentz 		rp->status = 0x00;
103adf1d692SSonny Sasaka 	}
104adf1d692SSonny Sasaka 
105e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
106c8992cffSLuiz Augusto von Dentz 		return rp->status;
1071da177e4SLinus Torvalds 
10889352e7dSAndre Guedes 	clear_bit(HCI_INQUIRY, &hdev->flags);
1094e857c58SPeter Zijlstra 	smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */
1103e13fa1eSAndre Guedes 	wake_up_bit(&hdev->flags, HCI_INQUIRY);
11189352e7dSAndre Guedes 
11250143a43SJohan Hedberg 	hci_dev_lock(hdev);
113168b8a25SJakub Pawlowski 	/* Set discovery state to stopped if we're not doing LE active
114168b8a25SJakub Pawlowski 	 * scanning.
115168b8a25SJakub Pawlowski 	 */
116168b8a25SJakub Pawlowski 	if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
117168b8a25SJakub Pawlowski 	    hdev->le_scan_type != LE_SCAN_ACTIVE)
11850143a43SJohan Hedberg 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
11950143a43SJohan Hedberg 	hci_dev_unlock(hdev);
12050143a43SJohan Hedberg 
121a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
122c8992cffSLuiz Augusto von Dentz 
123c8992cffSLuiz Augusto von Dentz 	return rp->status;
1241da177e4SLinus Torvalds }
1256bd57416SMarcel Holtmann 
hci_cc_periodic_inq(struct hci_dev * hdev,void * data,struct sk_buff * skb)126c8992cffSLuiz Augusto von Dentz static u8 hci_cc_periodic_inq(struct hci_dev *hdev, void *data,
127c8992cffSLuiz Augusto von Dentz 			      struct sk_buff *skb)
1284d93483bSAndre Guedes {
129c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
130ae854a70SAndre Guedes 
131e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
132e3f3a1aeSLuiz Augusto von Dentz 
133e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
134c8992cffSLuiz Augusto von Dentz 		return rp->status;
135ae854a70SAndre Guedes 
136a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_PERIODIC_INQ);
137c8992cffSLuiz Augusto von Dentz 
138c8992cffSLuiz Augusto von Dentz 	return rp->status;
1394d93483bSAndre Guedes }
1404d93483bSAndre Guedes 
hci_cc_exit_periodic_inq(struct hci_dev * hdev,void * data,struct sk_buff * skb)141c8992cffSLuiz Augusto von Dentz static u8 hci_cc_exit_periodic_inq(struct hci_dev *hdev, void *data,
142c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
1431da177e4SLinus Torvalds {
144c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
145a9de9248SMarcel Holtmann 
146e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
147e3f3a1aeSLuiz Augusto von Dentz 
148e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
149c8992cffSLuiz Augusto von Dentz 		return rp->status;
150a9de9248SMarcel Holtmann 
151a358dc11SMarcel Holtmann 	hci_dev_clear_flag(hdev, HCI_PERIODIC_INQ);
152ae854a70SAndre Guedes 
153a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
154c8992cffSLuiz Augusto von Dentz 
155c8992cffSLuiz Augusto von Dentz 	return rp->status;
156a9de9248SMarcel Holtmann }
157a9de9248SMarcel Holtmann 
hci_cc_remote_name_req_cancel(struct hci_dev * hdev,void * data,struct sk_buff * skb)158c8992cffSLuiz Augusto von Dentz static u8 hci_cc_remote_name_req_cancel(struct hci_dev *hdev, void *data,
159807deac2SGustavo Padovan 					struct sk_buff *skb)
160a9de9248SMarcel Holtmann {
161c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
162e3f3a1aeSLuiz Augusto von Dentz 
163e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
164c8992cffSLuiz Augusto von Dentz 
165c8992cffSLuiz Augusto von Dentz 	return rp->status;
166a9de9248SMarcel Holtmann }
167a9de9248SMarcel Holtmann 
hci_cc_role_discovery(struct hci_dev * hdev,void * data,struct sk_buff * skb)168c8992cffSLuiz Augusto von Dentz static u8 hci_cc_role_discovery(struct hci_dev *hdev, void *data,
169c8992cffSLuiz Augusto von Dentz 				struct sk_buff *skb)
170a9de9248SMarcel Holtmann {
171c8992cffSLuiz Augusto von Dentz 	struct hci_rp_role_discovery *rp = data;
1721da177e4SLinus Torvalds 	struct hci_conn *conn;
1731da177e4SLinus Torvalds 
174e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1751da177e4SLinus Torvalds 
176a9de9248SMarcel Holtmann 	if (rp->status)
177c8992cffSLuiz Augusto von Dentz 		return rp->status;
1781da177e4SLinus Torvalds 
1791da177e4SLinus Torvalds 	hci_dev_lock(hdev);
1801da177e4SLinus Torvalds 
181a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
18240bef302SJohan Hedberg 	if (conn)
18340bef302SJohan Hedberg 		conn->role = rp->role;
1841da177e4SLinus Torvalds 
1851da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
186c8992cffSLuiz Augusto von Dentz 
187c8992cffSLuiz Augusto von Dentz 	return rp->status;
188a9de9248SMarcel Holtmann }
1891da177e4SLinus Torvalds 
hci_cc_read_link_policy(struct hci_dev * hdev,void * data,struct sk_buff * skb)190c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_link_policy(struct hci_dev *hdev, void *data,
191c8992cffSLuiz Augusto von Dentz 				  struct sk_buff *skb)
192e4e8e37cSMarcel Holtmann {
193c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_link_policy *rp = data;
194e4e8e37cSMarcel Holtmann 	struct hci_conn *conn;
195e4e8e37cSMarcel Holtmann 
196e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
197e4e8e37cSMarcel Holtmann 
198e4e8e37cSMarcel Holtmann 	if (rp->status)
199c8992cffSLuiz Augusto von Dentz 		return rp->status;
200e4e8e37cSMarcel Holtmann 
201e4e8e37cSMarcel Holtmann 	hci_dev_lock(hdev);
202e4e8e37cSMarcel Holtmann 
203e4e8e37cSMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
204e4e8e37cSMarcel Holtmann 	if (conn)
205e4e8e37cSMarcel Holtmann 		conn->link_policy = __le16_to_cpu(rp->policy);
206e4e8e37cSMarcel Holtmann 
207e4e8e37cSMarcel Holtmann 	hci_dev_unlock(hdev);
208c8992cffSLuiz Augusto von Dentz 
209c8992cffSLuiz Augusto von Dentz 	return rp->status;
210e4e8e37cSMarcel Holtmann }
211e4e8e37cSMarcel Holtmann 
hci_cc_write_link_policy(struct hci_dev * hdev,void * data,struct sk_buff * skb)212c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_link_policy(struct hci_dev *hdev, void *data,
213c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
214a9de9248SMarcel Holtmann {
215c8992cffSLuiz Augusto von Dentz 	struct hci_rp_write_link_policy *rp = data;
216a9de9248SMarcel Holtmann 	struct hci_conn *conn;
217a9de9248SMarcel Holtmann 	void *sent;
218a9de9248SMarcel Holtmann 
219e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
220a9de9248SMarcel Holtmann 
221a9de9248SMarcel Holtmann 	if (rp->status)
222c8992cffSLuiz Augusto von Dentz 		return rp->status;
223a9de9248SMarcel Holtmann 
224a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
22504837f64SMarcel Holtmann 	if (!sent)
226c8992cffSLuiz Augusto von Dentz 		return rp->status;
22704837f64SMarcel Holtmann 
22804837f64SMarcel Holtmann 	hci_dev_lock(hdev);
22904837f64SMarcel Holtmann 
230a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
231e4e8e37cSMarcel Holtmann 	if (conn)
23283985319SHarvey Harrison 		conn->link_policy = get_unaligned_le16(sent + 2);
23304837f64SMarcel Holtmann 
23404837f64SMarcel Holtmann 	hci_dev_unlock(hdev);
235c8992cffSLuiz Augusto von Dentz 
236c8992cffSLuiz Augusto von Dentz 	return rp->status;
2371da177e4SLinus Torvalds }
2381da177e4SLinus Torvalds 
hci_cc_read_def_link_policy(struct hci_dev * hdev,void * data,struct sk_buff * skb)239c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_def_link_policy(struct hci_dev *hdev, void *data,
240807deac2SGustavo Padovan 				      struct sk_buff *skb)
241e4e8e37cSMarcel Holtmann {
242c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_def_link_policy *rp = data;
243e3f3a1aeSLuiz Augusto von Dentz 
244e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
245e4e8e37cSMarcel Holtmann 
246e4e8e37cSMarcel Holtmann 	if (rp->status)
247c8992cffSLuiz Augusto von Dentz 		return rp->status;
248e4e8e37cSMarcel Holtmann 
249e4e8e37cSMarcel Holtmann 	hdev->link_policy = __le16_to_cpu(rp->policy);
250c8992cffSLuiz Augusto von Dentz 
251c8992cffSLuiz Augusto von Dentz 	return rp->status;
252e4e8e37cSMarcel Holtmann }
253e4e8e37cSMarcel Holtmann 
hci_cc_write_def_link_policy(struct hci_dev * hdev,void * data,struct sk_buff * skb)254c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_def_link_policy(struct hci_dev *hdev, void *data,
255807deac2SGustavo Padovan 				       struct sk_buff *skb)
256e4e8e37cSMarcel Holtmann {
257c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
258e4e8e37cSMarcel Holtmann 	void *sent;
259e4e8e37cSMarcel Holtmann 
260e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
261e3f3a1aeSLuiz Augusto von Dentz 
262e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
263c8992cffSLuiz Augusto von Dentz 		return rp->status;
26445296acdSMarcel Holtmann 
265e4e8e37cSMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
266e4e8e37cSMarcel Holtmann 	if (!sent)
267c8992cffSLuiz Augusto von Dentz 		return rp->status;
268e4e8e37cSMarcel Holtmann 
269e4e8e37cSMarcel Holtmann 	hdev->link_policy = get_unaligned_le16(sent);
270c8992cffSLuiz Augusto von Dentz 
271c8992cffSLuiz Augusto von Dentz 	return rp->status;
272e4e8e37cSMarcel Holtmann }
273e4e8e37cSMarcel Holtmann 
hci_cc_reset(struct hci_dev * hdev,void * data,struct sk_buff * skb)274c8992cffSLuiz Augusto von Dentz static u8 hci_cc_reset(struct hci_dev *hdev, void *data, struct sk_buff *skb)
2751da177e4SLinus Torvalds {
276c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
277e3f3a1aeSLuiz Augusto von Dentz 
278e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
279a9de9248SMarcel Holtmann 
28010572132SGustavo F. Padovan 	clear_bit(HCI_RESET, &hdev->flags);
28110572132SGustavo F. Padovan 
282e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
283c8992cffSLuiz Augusto von Dentz 		return rp->status;
2848761f9d6SMarcel Holtmann 
285a297e97cSJohan Hedberg 	/* Reset all non-persistent flags */
286eacb44dfSMarcel Holtmann 	hci_dev_clear_volatile_flags(hdev);
28769775ff6SAndre Guedes 
28839c5d970SJohan Hedberg 	hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
28939c5d970SJohan Hedberg 
290bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
291bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
2923f0f524bSJohan Hedberg 
2933f0f524bSJohan Hedberg 	memset(hdev->adv_data, 0, sizeof(hdev->adv_data));
2943f0f524bSJohan Hedberg 	hdev->adv_data_len = 0;
295f8e808bdSMarcel Holtmann 
296f8e808bdSMarcel Holtmann 	memset(hdev->scan_rsp_data, 0, sizeof(hdev->scan_rsp_data));
297f8e808bdSMarcel Holtmann 	hdev->scan_rsp_data_len = 0;
29806f5b778SMarcel Holtmann 
299533553f8SMarcel Holtmann 	hdev->le_scan_type = LE_SCAN_PASSIVE;
300533553f8SMarcel Holtmann 
30106f5b778SMarcel Holtmann 	hdev->ssp_debug_mode = 0;
302a4d5504dSMarcel Holtmann 
3033d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->le_accept_list);
304cfdb0c2dSAnkit Navik 	hci_bdaddr_list_clear(&hdev->le_resolv_list);
305c8992cffSLuiz Augusto von Dentz 
306c8992cffSLuiz Augusto von Dentz 	return rp->status;
307a9de9248SMarcel Holtmann }
308a9de9248SMarcel Holtmann 
hci_cc_read_stored_link_key(struct hci_dev * hdev,void * data,struct sk_buff * skb)309c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_stored_link_key(struct hci_dev *hdev, void *data,
310c2f0f979SMarcel Holtmann 				      struct sk_buff *skb)
311c2f0f979SMarcel Holtmann {
312c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_stored_link_key *rp = data;
313c2f0f979SMarcel Holtmann 	struct hci_cp_read_stored_link_key *sent;
314c2f0f979SMarcel Holtmann 
315e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
316c2f0f979SMarcel Holtmann 
317c2f0f979SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_READ_STORED_LINK_KEY);
318c2f0f979SMarcel Holtmann 	if (!sent)
319c8992cffSLuiz Augusto von Dentz 		return rp->status;
320c2f0f979SMarcel Holtmann 
321c2f0f979SMarcel Holtmann 	if (!rp->status && sent->read_all == 0x01) {
322e88422bcSLuiz Augusto von Dentz 		hdev->stored_max_keys = le16_to_cpu(rp->max_keys);
323e88422bcSLuiz Augusto von Dentz 		hdev->stored_num_keys = le16_to_cpu(rp->num_keys);
324c2f0f979SMarcel Holtmann 	}
325c8992cffSLuiz Augusto von Dentz 
326c8992cffSLuiz Augusto von Dentz 	return rp->status;
327c2f0f979SMarcel Holtmann }
328c2f0f979SMarcel Holtmann 
hci_cc_delete_stored_link_key(struct hci_dev * hdev,void * data,struct sk_buff * skb)329c8992cffSLuiz Augusto von Dentz static u8 hci_cc_delete_stored_link_key(struct hci_dev *hdev, void *data,
330a9366120SMarcel Holtmann 					struct sk_buff *skb)
331a9366120SMarcel Holtmann {
332c8992cffSLuiz Augusto von Dentz 	struct hci_rp_delete_stored_link_key *rp = data;
333889f0346SLuiz Augusto von Dentz 	u16 num_keys;
334e3f3a1aeSLuiz Augusto von Dentz 
335e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
336a9366120SMarcel Holtmann 
337a9366120SMarcel Holtmann 	if (rp->status)
338c8992cffSLuiz Augusto von Dentz 		return rp->status;
339a9366120SMarcel Holtmann 
340889f0346SLuiz Augusto von Dentz 	num_keys = le16_to_cpu(rp->num_keys);
341889f0346SLuiz Augusto von Dentz 
342889f0346SLuiz Augusto von Dentz 	if (num_keys <= hdev->stored_num_keys)
343889f0346SLuiz Augusto von Dentz 		hdev->stored_num_keys -= num_keys;
344a9366120SMarcel Holtmann 	else
345a9366120SMarcel Holtmann 		hdev->stored_num_keys = 0;
346c8992cffSLuiz Augusto von Dentz 
347c8992cffSLuiz Augusto von Dentz 	return rp->status;
348a9366120SMarcel Holtmann }
349a9366120SMarcel Holtmann 
hci_cc_write_local_name(struct hci_dev * hdev,void * data,struct sk_buff * skb)350c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_local_name(struct hci_dev *hdev, void *data,
351c8992cffSLuiz Augusto von Dentz 				  struct sk_buff *skb)
352a9de9248SMarcel Holtmann {
353c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
3541da177e4SLinus Torvalds 	void *sent;
3551da177e4SLinus Torvalds 
356e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
3571da177e4SLinus Torvalds 
358a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
3591da177e4SLinus Torvalds 	if (!sent)
360c8992cffSLuiz Augusto von Dentz 		return rp->status;
3611da177e4SLinus Torvalds 
36256e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
36356e5cb86SJohan Hedberg 
364d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
365e3f3a1aeSLuiz Augusto von Dentz 		mgmt_set_local_name_complete(hdev, sent, rp->status);
366e3f3a1aeSLuiz Augusto von Dentz 	else if (!rp->status)
36728cc7bdeSJohan Hedberg 		memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
368f51d5b24SJohan Hedberg 
36956e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
370c8992cffSLuiz Augusto von Dentz 
371c8992cffSLuiz Augusto von Dentz 	return rp->status;
372a9de9248SMarcel Holtmann }
373a9de9248SMarcel Holtmann 
hci_cc_read_local_name(struct hci_dev * hdev,void * data,struct sk_buff * skb)374c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_name(struct hci_dev *hdev, void *data,
375c8992cffSLuiz Augusto von Dentz 				 struct sk_buff *skb)
376a9de9248SMarcel Holtmann {
377c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_name *rp = data;
378e3f3a1aeSLuiz Augusto von Dentz 
379e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
380a9de9248SMarcel Holtmann 
381a9de9248SMarcel Holtmann 	if (rp->status)
382c8992cffSLuiz Augusto von Dentz 		return rp->status;
383a9de9248SMarcel Holtmann 
384d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP) ||
385d7a5a11dSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_CONFIG))
3861f6c6378SJohan Hedberg 		memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
387c8992cffSLuiz Augusto von Dentz 
388c8992cffSLuiz Augusto von Dentz 	return rp->status;
389a9de9248SMarcel Holtmann }
390a9de9248SMarcel Holtmann 
hci_cc_write_auth_enable(struct hci_dev * hdev,void * data,struct sk_buff * skb)391c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_auth_enable(struct hci_dev *hdev, void *data,
392c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
393a9de9248SMarcel Holtmann {
394c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
395a9de9248SMarcel Holtmann 	void *sent;
396a9de9248SMarcel Holtmann 
397e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
398a9de9248SMarcel Holtmann 
399a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
400a9de9248SMarcel Holtmann 	if (!sent)
401c8992cffSLuiz Augusto von Dentz 		return rp->status;
4021da177e4SLinus Torvalds 
4035c1a4c8fSJaganath Kanakkassery 	hci_dev_lock(hdev);
4045c1a4c8fSJaganath Kanakkassery 
405e3f3a1aeSLuiz Augusto von Dentz 	if (!rp->status) {
406a9de9248SMarcel Holtmann 		__u8 param = *((__u8 *) sent);
407a9de9248SMarcel Holtmann 
4081da177e4SLinus Torvalds 		if (param == AUTH_ENABLED)
4091da177e4SLinus Torvalds 			set_bit(HCI_AUTH, &hdev->flags);
4101da177e4SLinus Torvalds 		else
4111da177e4SLinus Torvalds 			clear_bit(HCI_AUTH, &hdev->flags);
4121da177e4SLinus Torvalds 	}
413a9de9248SMarcel Holtmann 
414d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
415e3f3a1aeSLuiz Augusto von Dentz 		mgmt_auth_enable_complete(hdev, rp->status);
4165c1a4c8fSJaganath Kanakkassery 
4175c1a4c8fSJaganath Kanakkassery 	hci_dev_unlock(hdev);
418c8992cffSLuiz Augusto von Dentz 
419c8992cffSLuiz Augusto von Dentz 	return rp->status;
420a9de9248SMarcel Holtmann }
4211da177e4SLinus Torvalds 
hci_cc_write_encrypt_mode(struct hci_dev * hdev,void * data,struct sk_buff * skb)422c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_encrypt_mode(struct hci_dev *hdev, void *data,
423c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
424a9de9248SMarcel Holtmann {
425c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
42645296acdSMarcel Holtmann 	__u8 param;
427a9de9248SMarcel Holtmann 	void *sent;
428a9de9248SMarcel Holtmann 
429e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
430e3f3a1aeSLuiz Augusto von Dentz 
431e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
432c8992cffSLuiz Augusto von Dentz 		return rp->status;
43345296acdSMarcel Holtmann 
434a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
4351da177e4SLinus Torvalds 	if (!sent)
436c8992cffSLuiz Augusto von Dentz 		return rp->status;
4371da177e4SLinus Torvalds 
43845296acdSMarcel Holtmann 	param = *((__u8 *) sent);
439a9de9248SMarcel Holtmann 
4401da177e4SLinus Torvalds 	if (param)
4411da177e4SLinus Torvalds 		set_bit(HCI_ENCRYPT, &hdev->flags);
4421da177e4SLinus Torvalds 	else
4431da177e4SLinus Torvalds 		clear_bit(HCI_ENCRYPT, &hdev->flags);
444c8992cffSLuiz Augusto von Dentz 
445c8992cffSLuiz Augusto von Dentz 	return rp->status;
4461da177e4SLinus Torvalds }
4471da177e4SLinus Torvalds 
hci_cc_write_scan_enable(struct hci_dev * hdev,void * data,struct sk_buff * skb)448c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_scan_enable(struct hci_dev *hdev, void *data,
449c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
450a9de9248SMarcel Holtmann {
451c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
45245296acdSMarcel Holtmann 	__u8 param;
453a9de9248SMarcel Holtmann 	void *sent;
4541da177e4SLinus Torvalds 
455e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
456a9de9248SMarcel Holtmann 
457a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
4581da177e4SLinus Torvalds 	if (!sent)
459c8992cffSLuiz Augusto von Dentz 		return rp->status;
4601da177e4SLinus Torvalds 
46136f7fc7eSJohan Hedberg 	param = *((__u8 *) sent);
462a9de9248SMarcel Holtmann 
46356e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
46456e5cb86SJohan Hedberg 
465e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status) {
4662d7cee58SJohan Hedberg 		hdev->discov_timeout = 0;
4672d7cee58SJohan Hedberg 		goto done;
4682d7cee58SJohan Hedberg 	}
4692d7cee58SJohan Hedberg 
470bc6d2d04SJohan Hedberg 	if (param & SCAN_INQUIRY)
4711da177e4SLinus Torvalds 		set_bit(HCI_ISCAN, &hdev->flags);
472bc6d2d04SJohan Hedberg 	else
473bc6d2d04SJohan Hedberg 		clear_bit(HCI_ISCAN, &hdev->flags);
4741da177e4SLinus Torvalds 
475031547d8SJohan Hedberg 	if (param & SCAN_PAGE)
4761da177e4SLinus Torvalds 		set_bit(HCI_PSCAN, &hdev->flags);
477bc6d2d04SJohan Hedberg 	else
478204e3990SJohan Hedberg 		clear_bit(HCI_PSCAN, &hdev->flags);
479a9de9248SMarcel Holtmann 
48036f7fc7eSJohan Hedberg done:
48156e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
482c8992cffSLuiz Augusto von Dentz 
483c8992cffSLuiz Augusto von Dentz 	return rp->status;
4841da177e4SLinus Torvalds }
4851da177e4SLinus Torvalds 
hci_cc_set_event_filter(struct hci_dev * hdev,void * data,struct sk_buff * skb)486c8992cffSLuiz Augusto von Dentz static u8 hci_cc_set_event_filter(struct hci_dev *hdev, void *data,
487c8992cffSLuiz Augusto von Dentz 				  struct sk_buff *skb)
488e5b0ad69SAbhishek Pandit-Subedi {
489c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
490e5b0ad69SAbhishek Pandit-Subedi 	struct hci_cp_set_event_filter *cp;
491e5b0ad69SAbhishek Pandit-Subedi 	void *sent;
492e5b0ad69SAbhishek Pandit-Subedi 
493e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
494e3f3a1aeSLuiz Augusto von Dentz 
495e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
496c8992cffSLuiz Augusto von Dentz 		return rp->status;
497e5b0ad69SAbhishek Pandit-Subedi 
498e5b0ad69SAbhishek Pandit-Subedi 	sent = hci_sent_cmd_data(hdev, HCI_OP_SET_EVENT_FLT);
499e5b0ad69SAbhishek Pandit-Subedi 	if (!sent)
500c8992cffSLuiz Augusto von Dentz 		return rp->status;
501e5b0ad69SAbhishek Pandit-Subedi 
502e5b0ad69SAbhishek Pandit-Subedi 	cp = (struct hci_cp_set_event_filter *)sent;
503e5b0ad69SAbhishek Pandit-Subedi 
504e5b0ad69SAbhishek Pandit-Subedi 	if (cp->flt_type == HCI_FLT_CLEAR_ALL)
505e5b0ad69SAbhishek Pandit-Subedi 		hci_dev_clear_flag(hdev, HCI_EVENT_FILTER_CONFIGURED);
506e5b0ad69SAbhishek Pandit-Subedi 	else
507e5b0ad69SAbhishek Pandit-Subedi 		hci_dev_set_flag(hdev, HCI_EVENT_FILTER_CONFIGURED);
508c8992cffSLuiz Augusto von Dentz 
509c8992cffSLuiz Augusto von Dentz 	return rp->status;
510e5b0ad69SAbhishek Pandit-Subedi }
511e5b0ad69SAbhishek Pandit-Subedi 
hci_cc_read_class_of_dev(struct hci_dev * hdev,void * data,struct sk_buff * skb)512c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_class_of_dev(struct hci_dev *hdev, void *data,
513c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
514a9de9248SMarcel Holtmann {
515c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_class_of_dev *rp = data;
516e3f3a1aeSLuiz Augusto von Dentz 
5177ee2ba3dSArnd Bergmann 	if (WARN_ON(!hdev))
5187ee2ba3dSArnd Bergmann 		return HCI_ERROR_UNSPECIFIED;
5197ee2ba3dSArnd Bergmann 
520e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
521a9de9248SMarcel Holtmann 
522a9de9248SMarcel Holtmann 	if (rp->status)
523c8992cffSLuiz Augusto von Dentz 		return rp->status;
524a9de9248SMarcel Holtmann 
525a9de9248SMarcel Holtmann 	memcpy(hdev->dev_class, rp->dev_class, 3);
526a9de9248SMarcel Holtmann 
527e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "class 0x%.2x%.2x%.2x", hdev->dev_class[2],
528e3f3a1aeSLuiz Augusto von Dentz 		   hdev->dev_class[1], hdev->dev_class[0]);
529c8992cffSLuiz Augusto von Dentz 
530c8992cffSLuiz Augusto von Dentz 	return rp->status;
531a9de9248SMarcel Holtmann }
532a9de9248SMarcel Holtmann 
hci_cc_write_class_of_dev(struct hci_dev * hdev,void * data,struct sk_buff * skb)533c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_class_of_dev(struct hci_dev *hdev, void *data,
534c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
535a9de9248SMarcel Holtmann {
536c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
537a9de9248SMarcel Holtmann 	void *sent;
538a9de9248SMarcel Holtmann 
539e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
540a9de9248SMarcel Holtmann 
541a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
542a9de9248SMarcel Holtmann 	if (!sent)
543c8992cffSLuiz Augusto von Dentz 		return rp->status;
544a9de9248SMarcel Holtmann 
5457f9a903cSMarcel Holtmann 	hci_dev_lock(hdev);
5467f9a903cSMarcel Holtmann 
547e3f3a1aeSLuiz Augusto von Dentz 	if (!rp->status)
548a9de9248SMarcel Holtmann 		memcpy(hdev->dev_class, sent, 3);
5497f9a903cSMarcel Holtmann 
550d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
551e3f3a1aeSLuiz Augusto von Dentz 		mgmt_set_class_of_dev_complete(hdev, sent, rp->status);
5527f9a903cSMarcel Holtmann 
5537f9a903cSMarcel Holtmann 	hci_dev_unlock(hdev);
554c8992cffSLuiz Augusto von Dentz 
555c8992cffSLuiz Augusto von Dentz 	return rp->status;
556a9de9248SMarcel Holtmann }
557a9de9248SMarcel Holtmann 
hci_cc_read_voice_setting(struct hci_dev * hdev,void * data,struct sk_buff * skb)558c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_voice_setting(struct hci_dev *hdev, void *data,
559c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
560a9de9248SMarcel Holtmann {
561c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_voice_setting *rp = data;
562a9de9248SMarcel Holtmann 	__u16 setting;
563a9de9248SMarcel Holtmann 
564e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
565a9de9248SMarcel Holtmann 
566a9de9248SMarcel Holtmann 	if (rp->status)
567c8992cffSLuiz Augusto von Dentz 		return rp->status;
568a9de9248SMarcel Holtmann 
569a9de9248SMarcel Holtmann 	setting = __le16_to_cpu(rp->voice_setting);
570a9de9248SMarcel Holtmann 
571a9de9248SMarcel Holtmann 	if (hdev->voice_setting == setting)
572c8992cffSLuiz Augusto von Dentz 		return rp->status;
573a9de9248SMarcel Holtmann 
574a9de9248SMarcel Holtmann 	hdev->voice_setting = setting;
575a9de9248SMarcel Holtmann 
576e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "voice setting 0x%4.4x", setting);
577a9de9248SMarcel Holtmann 
5783c54711cSGustavo F. Padovan 	if (hdev->notify)
579a9de9248SMarcel Holtmann 		hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
580c8992cffSLuiz Augusto von Dentz 
581c8992cffSLuiz Augusto von Dentz 	return rp->status;
582a9de9248SMarcel Holtmann }
583a9de9248SMarcel Holtmann 
hci_cc_write_voice_setting(struct hci_dev * hdev,void * data,struct sk_buff * skb)584c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_voice_setting(struct hci_dev *hdev, void *data,
5858fc9ced3SGustavo Padovan 				     struct sk_buff *skb)
586a9de9248SMarcel Holtmann {
587c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
588f383f275SMarcel Holtmann 	__u16 setting;
589a9de9248SMarcel Holtmann 	void *sent;
590a9de9248SMarcel Holtmann 
591e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
592e3f3a1aeSLuiz Augusto von Dentz 
593e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
594c8992cffSLuiz Augusto von Dentz 		return rp->status;
595f383f275SMarcel Holtmann 
596a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
597a9de9248SMarcel Holtmann 	if (!sent)
598c8992cffSLuiz Augusto von Dentz 		return rp->status;
599a9de9248SMarcel Holtmann 
600f383f275SMarcel Holtmann 	setting = get_unaligned_le16(sent);
6011da177e4SLinus Torvalds 
602f383f275SMarcel Holtmann 	if (hdev->voice_setting == setting)
603c8992cffSLuiz Augusto von Dentz 		return rp->status;
604f383f275SMarcel Holtmann 
6051da177e4SLinus Torvalds 	hdev->voice_setting = setting;
6061da177e4SLinus Torvalds 
607e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "voice setting 0x%4.4x", setting);
6081da177e4SLinus Torvalds 
6093c54711cSGustavo F. Padovan 	if (hdev->notify)
6101da177e4SLinus Torvalds 		hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
611c8992cffSLuiz Augusto von Dentz 
612c8992cffSLuiz Augusto von Dentz 	return rp->status;
6131da177e4SLinus Torvalds }
6141da177e4SLinus Torvalds 
hci_cc_read_num_supported_iac(struct hci_dev * hdev,void * data,struct sk_buff * skb)615c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_num_supported_iac(struct hci_dev *hdev, void *data,
616b4cb9fb2SMarcel Holtmann 					struct sk_buff *skb)
617b4cb9fb2SMarcel Holtmann {
618c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_num_supported_iac *rp = data;
619e3f3a1aeSLuiz Augusto von Dentz 
620e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
621b4cb9fb2SMarcel Holtmann 
622b4cb9fb2SMarcel Holtmann 	if (rp->status)
623c8992cffSLuiz Augusto von Dentz 		return rp->status;
624b4cb9fb2SMarcel Holtmann 
625b4cb9fb2SMarcel Holtmann 	hdev->num_iac = rp->num_iac;
626b4cb9fb2SMarcel Holtmann 
627e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "num iac %d", hdev->num_iac);
628c8992cffSLuiz Augusto von Dentz 
629c8992cffSLuiz Augusto von Dentz 	return rp->status;
630b4cb9fb2SMarcel Holtmann }
631b4cb9fb2SMarcel Holtmann 
hci_cc_write_ssp_mode(struct hci_dev * hdev,void * data,struct sk_buff * skb)632c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_ssp_mode(struct hci_dev *hdev, void *data,
633c8992cffSLuiz Augusto von Dentz 				struct sk_buff *skb)
634333140b5SMarcel Holtmann {
635c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
6365ed8eb2fSJohan Hedberg 	struct hci_cp_write_ssp_mode *sent;
637333140b5SMarcel Holtmann 
638e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
639333140b5SMarcel Holtmann 
640333140b5SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
641333140b5SMarcel Holtmann 	if (!sent)
642c8992cffSLuiz Augusto von Dentz 		return rp->status;
643333140b5SMarcel Holtmann 
6445c1a4c8fSJaganath Kanakkassery 	hci_dev_lock(hdev);
6455c1a4c8fSJaganath Kanakkassery 
646e3f3a1aeSLuiz Augusto von Dentz 	if (!rp->status) {
6475ed8eb2fSJohan Hedberg 		if (sent->mode)
648cad718edSJohan Hedberg 			hdev->features[1][0] |= LMP_HOST_SSP;
6495ed8eb2fSJohan Hedberg 		else
650cad718edSJohan Hedberg 			hdev->features[1][0] &= ~LMP_HOST_SSP;
6515ed8eb2fSJohan Hedberg 	}
6525ed8eb2fSJohan Hedberg 
653e3f3a1aeSLuiz Augusto von Dentz 	if (!rp->status) {
6545ed8eb2fSJohan Hedberg 		if (sent->mode)
655a1536da2SMarcel Holtmann 			hci_dev_set_flag(hdev, HCI_SSP_ENABLED);
65684bde9d6SJohan Hedberg 		else
657a358dc11SMarcel Holtmann 			hci_dev_clear_flag(hdev, HCI_SSP_ENABLED);
658c0ecddc2SJohan Hedberg 	}
6595c1a4c8fSJaganath Kanakkassery 
6605c1a4c8fSJaganath Kanakkassery 	hci_dev_unlock(hdev);
661c8992cffSLuiz Augusto von Dentz 
662c8992cffSLuiz Augusto von Dentz 	return rp->status;
663333140b5SMarcel Holtmann }
664333140b5SMarcel Holtmann 
hci_cc_write_sc_support(struct hci_dev * hdev,void * data,struct sk_buff * skb)665c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_sc_support(struct hci_dev *hdev, void *data,
666c8992cffSLuiz Augusto von Dentz 				  struct sk_buff *skb)
667eac83dc6SMarcel Holtmann {
668c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
669eac83dc6SMarcel Holtmann 	struct hci_cp_write_sc_support *sent;
670eac83dc6SMarcel Holtmann 
671e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
672eac83dc6SMarcel Holtmann 
673eac83dc6SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SC_SUPPORT);
674eac83dc6SMarcel Holtmann 	if (!sent)
675c8992cffSLuiz Augusto von Dentz 		return rp->status;
676eac83dc6SMarcel Holtmann 
6775c1a4c8fSJaganath Kanakkassery 	hci_dev_lock(hdev);
6785c1a4c8fSJaganath Kanakkassery 
679e3f3a1aeSLuiz Augusto von Dentz 	if (!rp->status) {
680eac83dc6SMarcel Holtmann 		if (sent->support)
681eac83dc6SMarcel Holtmann 			hdev->features[1][0] |= LMP_HOST_SC;
682eac83dc6SMarcel Holtmann 		else
683eac83dc6SMarcel Holtmann 			hdev->features[1][0] &= ~LMP_HOST_SC;
684eac83dc6SMarcel Holtmann 	}
685eac83dc6SMarcel Holtmann 
686e3f3a1aeSLuiz Augusto von Dentz 	if (!hci_dev_test_flag(hdev, HCI_MGMT) && !rp->status) {
687eac83dc6SMarcel Holtmann 		if (sent->support)
688a1536da2SMarcel Holtmann 			hci_dev_set_flag(hdev, HCI_SC_ENABLED);
689eac83dc6SMarcel Holtmann 		else
690a358dc11SMarcel Holtmann 			hci_dev_clear_flag(hdev, HCI_SC_ENABLED);
691eac83dc6SMarcel Holtmann 	}
6925c1a4c8fSJaganath Kanakkassery 
6935c1a4c8fSJaganath Kanakkassery 	hci_dev_unlock(hdev);
694c8992cffSLuiz Augusto von Dentz 
695c8992cffSLuiz Augusto von Dentz 	return rp->status;
696eac83dc6SMarcel Holtmann }
697eac83dc6SMarcel Holtmann 
hci_cc_read_local_version(struct hci_dev * hdev,void * data,struct sk_buff * skb)698c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_version(struct hci_dev *hdev, void *data,
699c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
700a9de9248SMarcel Holtmann {
701c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_version *rp = data;
702e3f3a1aeSLuiz Augusto von Dentz 
703e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
7041143e5a6SMarcel Holtmann 
705a9de9248SMarcel Holtmann 	if (rp->status)
706c8992cffSLuiz Augusto von Dentz 		return rp->status;
7071143e5a6SMarcel Holtmann 
708d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP) ||
709d7a5a11dSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_CONFIG)) {
710a9de9248SMarcel Holtmann 		hdev->hci_ver = rp->hci_ver;
711e4e8e37cSMarcel Holtmann 		hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
712d5859e22SJohan Hedberg 		hdev->lmp_ver = rp->lmp_ver;
713e4e8e37cSMarcel Holtmann 		hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
714d5859e22SJohan Hedberg 		hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
7150d5551f5SMarcel Holtmann 	}
716c8992cffSLuiz Augusto von Dentz 
717c8992cffSLuiz Augusto von Dentz 	return rp->status;
718d5859e22SJohan Hedberg }
719d5859e22SJohan Hedberg 
hci_cc_read_enc_key_size(struct hci_dev * hdev,void * data,struct sk_buff * skb)720278d933eSBrian Gix static u8 hci_cc_read_enc_key_size(struct hci_dev *hdev, void *data,
721278d933eSBrian Gix 				   struct sk_buff *skb)
722278d933eSBrian Gix {
723278d933eSBrian Gix 	struct hci_rp_read_enc_key_size *rp = data;
724278d933eSBrian Gix 	struct hci_conn *conn;
725278d933eSBrian Gix 	u16 handle;
726278d933eSBrian Gix 	u8 status = rp->status;
727278d933eSBrian Gix 
728278d933eSBrian Gix 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
729278d933eSBrian Gix 
730278d933eSBrian Gix 	handle = le16_to_cpu(rp->handle);
731278d933eSBrian Gix 
732278d933eSBrian Gix 	hci_dev_lock(hdev);
733278d933eSBrian Gix 
734278d933eSBrian Gix 	conn = hci_conn_hash_lookup_handle(hdev, handle);
735278d933eSBrian Gix 	if (!conn) {
736278d933eSBrian Gix 		status = 0xFF;
737278d933eSBrian Gix 		goto done;
738278d933eSBrian Gix 	}
739278d933eSBrian Gix 
740278d933eSBrian Gix 	/* While unexpected, the read_enc_key_size command may fail. The most
741278d933eSBrian Gix 	 * secure approach is to then assume the key size is 0 to force a
742278d933eSBrian Gix 	 * disconnection.
743278d933eSBrian Gix 	 */
744278d933eSBrian Gix 	if (status) {
745278d933eSBrian Gix 		bt_dev_err(hdev, "failed to read key size for handle %u",
746278d933eSBrian Gix 			   handle);
747278d933eSBrian Gix 		conn->enc_key_size = 0;
748278d933eSBrian Gix 	} else {
749278d933eSBrian Gix 		conn->enc_key_size = rp->key_size;
750278d933eSBrian Gix 		status = 0;
75134c032a7SAlex Lu 
75234c032a7SAlex Lu 		if (conn->enc_key_size < hdev->min_enc_key_size) {
75334c032a7SAlex Lu 			/* As slave role, the conn->state has been set to
75434c032a7SAlex Lu 			 * BT_CONNECTED and l2cap conn req might not be received
75534c032a7SAlex Lu 			 * yet, at this moment the l2cap layer almost does
75634c032a7SAlex Lu 			 * nothing with the non-zero status.
75734c032a7SAlex Lu 			 * So we also clear encrypt related bits, and then the
75834c032a7SAlex Lu 			 * handler of l2cap conn req will get the right secure
75934c032a7SAlex Lu 			 * state at a later time.
76034c032a7SAlex Lu 			 */
76134c032a7SAlex Lu 			status = HCI_ERROR_AUTH_FAILURE;
76234c032a7SAlex Lu 			clear_bit(HCI_CONN_ENCRYPT, &conn->flags);
76334c032a7SAlex Lu 			clear_bit(HCI_CONN_AES_CCM, &conn->flags);
76434c032a7SAlex Lu 		}
765278d933eSBrian Gix 	}
766278d933eSBrian Gix 
76734c032a7SAlex Lu 	hci_encrypt_cfm(conn, status);
768278d933eSBrian Gix 
769278d933eSBrian Gix done:
770278d933eSBrian Gix 	hci_dev_unlock(hdev);
771278d933eSBrian Gix 
772278d933eSBrian Gix 	return status;
773278d933eSBrian Gix }
774278d933eSBrian Gix 
hci_cc_read_local_commands(struct hci_dev * hdev,void * data,struct sk_buff * skb)775c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_commands(struct hci_dev *hdev, void *data,
7768fc9ced3SGustavo Padovan 				     struct sk_buff *skb)
777a9de9248SMarcel Holtmann {
778c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_commands *rp = data;
779e3f3a1aeSLuiz Augusto von Dentz 
780e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
781a9de9248SMarcel Holtmann 
7826a070e6eSMarcel Holtmann 	if (rp->status)
783c8992cffSLuiz Augusto von Dentz 		return rp->status;
7846a070e6eSMarcel Holtmann 
785d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP) ||
786d7a5a11dSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_CONFIG))
787a9de9248SMarcel Holtmann 		memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
788c8992cffSLuiz Augusto von Dentz 
789c8992cffSLuiz Augusto von Dentz 	return rp->status;
790a9de9248SMarcel Holtmann }
791a9de9248SMarcel Holtmann 
hci_cc_read_auth_payload_timeout(struct hci_dev * hdev,void * data,struct sk_buff * skb)792c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_auth_payload_timeout(struct hci_dev *hdev, void *data,
793302975cbSSpoorthi Ravishankar Koppad 					   struct sk_buff *skb)
794302975cbSSpoorthi Ravishankar Koppad {
795c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_auth_payload_to *rp = data;
796302975cbSSpoorthi Ravishankar Koppad 	struct hci_conn *conn;
797302975cbSSpoorthi Ravishankar Koppad 
798e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
799302975cbSSpoorthi Ravishankar Koppad 
800302975cbSSpoorthi Ravishankar Koppad 	if (rp->status)
801c8992cffSLuiz Augusto von Dentz 		return rp->status;
802302975cbSSpoorthi Ravishankar Koppad 
803302975cbSSpoorthi Ravishankar Koppad 	hci_dev_lock(hdev);
804302975cbSSpoorthi Ravishankar Koppad 
805302975cbSSpoorthi Ravishankar Koppad 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
806302975cbSSpoorthi Ravishankar Koppad 	if (conn)
807302975cbSSpoorthi Ravishankar Koppad 		conn->auth_payload_timeout = __le16_to_cpu(rp->timeout);
808302975cbSSpoorthi Ravishankar Koppad 
809302975cbSSpoorthi Ravishankar Koppad 	hci_dev_unlock(hdev);
810c8992cffSLuiz Augusto von Dentz 
811c8992cffSLuiz Augusto von Dentz 	return rp->status;
812302975cbSSpoorthi Ravishankar Koppad }
813302975cbSSpoorthi Ravishankar Koppad 
hci_cc_write_auth_payload_timeout(struct hci_dev * hdev,void * data,struct sk_buff * skb)814c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_auth_payload_timeout(struct hci_dev *hdev, void *data,
815302975cbSSpoorthi Ravishankar Koppad 					    struct sk_buff *skb)
816302975cbSSpoorthi Ravishankar Koppad {
817c8992cffSLuiz Augusto von Dentz 	struct hci_rp_write_auth_payload_to *rp = data;
818302975cbSSpoorthi Ravishankar Koppad 	struct hci_conn *conn;
819302975cbSSpoorthi Ravishankar Koppad 	void *sent;
820302975cbSSpoorthi Ravishankar Koppad 
821e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
822302975cbSSpoorthi Ravishankar Koppad 
823302975cbSSpoorthi Ravishankar Koppad 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_PAYLOAD_TO);
824302975cbSSpoorthi Ravishankar Koppad 	if (!sent)
825c8992cffSLuiz Augusto von Dentz 		return rp->status;
826302975cbSSpoorthi Ravishankar Koppad 
827302975cbSSpoorthi Ravishankar Koppad 	hci_dev_lock(hdev);
828302975cbSSpoorthi Ravishankar Koppad 
829302975cbSSpoorthi Ravishankar Koppad 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
8307aca0ac4SLuiz Augusto von Dentz 	if (!conn) {
8317aca0ac4SLuiz Augusto von Dentz 		rp->status = 0xff;
8327aca0ac4SLuiz Augusto von Dentz 		goto unlock;
8337aca0ac4SLuiz Augusto von Dentz 	}
8347aca0ac4SLuiz Augusto von Dentz 
8357aca0ac4SLuiz Augusto von Dentz 	if (!rp->status)
836302975cbSSpoorthi Ravishankar Koppad 		conn->auth_payload_timeout = get_unaligned_le16(sent + 2);
837302975cbSSpoorthi Ravishankar Koppad 
8387aca0ac4SLuiz Augusto von Dentz unlock:
839302975cbSSpoorthi Ravishankar Koppad 	hci_dev_unlock(hdev);
840c8992cffSLuiz Augusto von Dentz 
841c8992cffSLuiz Augusto von Dentz 	return rp->status;
842302975cbSSpoorthi Ravishankar Koppad }
843302975cbSSpoorthi Ravishankar Koppad 
hci_cc_read_local_features(struct hci_dev * hdev,void * data,struct sk_buff * skb)844c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_features(struct hci_dev *hdev, void *data,
8458fc9ced3SGustavo Padovan 				     struct sk_buff *skb)
846a9de9248SMarcel Holtmann {
847c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_features *rp = data;
848e3f3a1aeSLuiz Augusto von Dentz 
849e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
850a9de9248SMarcel Holtmann 
851a9de9248SMarcel Holtmann 	if (rp->status)
852c8992cffSLuiz Augusto von Dentz 		return rp->status;
853a9de9248SMarcel Holtmann 
854a9de9248SMarcel Holtmann 	memcpy(hdev->features, rp->features, 8);
8551da177e4SLinus Torvalds 
8561da177e4SLinus Torvalds 	/* Adjust default settings according to features
8571da177e4SLinus Torvalds 	 * supported by device. */
858a9de9248SMarcel Holtmann 
859cad718edSJohan Hedberg 	if (hdev->features[0][0] & LMP_3SLOT)
8601da177e4SLinus Torvalds 		hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
8611da177e4SLinus Torvalds 
862cad718edSJohan Hedberg 	if (hdev->features[0][0] & LMP_5SLOT)
8631da177e4SLinus Torvalds 		hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
8641da177e4SLinus Torvalds 
865cad718edSJohan Hedberg 	if (hdev->features[0][1] & LMP_HV2) {
8661da177e4SLinus Torvalds 		hdev->pkt_type  |= (HCI_HV2);
8675b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_HV2);
8685b7f9909SMarcel Holtmann 	}
8691da177e4SLinus Torvalds 
870cad718edSJohan Hedberg 	if (hdev->features[0][1] & LMP_HV3) {
8711da177e4SLinus Torvalds 		hdev->pkt_type  |= (HCI_HV3);
8725b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_HV3);
8735b7f9909SMarcel Holtmann 	}
8745b7f9909SMarcel Holtmann 
87545db810fSAndre Guedes 	if (lmp_esco_capable(hdev))
8765b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_EV3);
8775b7f9909SMarcel Holtmann 
878cad718edSJohan Hedberg 	if (hdev->features[0][4] & LMP_EV4)
8795b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_EV4);
8805b7f9909SMarcel Holtmann 
881cad718edSJohan Hedberg 	if (hdev->features[0][4] & LMP_EV5)
8825b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_EV5);
8831da177e4SLinus Torvalds 
884cad718edSJohan Hedberg 	if (hdev->features[0][5] & LMP_EDR_ESCO_2M)
885efc7688bSMarcel Holtmann 		hdev->esco_type |= (ESCO_2EV3);
886efc7688bSMarcel Holtmann 
887cad718edSJohan Hedberg 	if (hdev->features[0][5] & LMP_EDR_ESCO_3M)
888efc7688bSMarcel Holtmann 		hdev->esco_type |= (ESCO_3EV3);
889efc7688bSMarcel Holtmann 
890cad718edSJohan Hedberg 	if (hdev->features[0][5] & LMP_EDR_3S_ESCO)
891efc7688bSMarcel Holtmann 		hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
892c8992cffSLuiz Augusto von Dentz 
893c8992cffSLuiz Augusto von Dentz 	return rp->status;
8941da177e4SLinus Torvalds }
8951da177e4SLinus Torvalds 
hci_cc_read_local_ext_features(struct hci_dev * hdev,void * data,struct sk_buff * skb)896c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_ext_features(struct hci_dev *hdev, void *data,
897971e3a4bSAndre Guedes 					 struct sk_buff *skb)
898971e3a4bSAndre Guedes {
899c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_ext_features *rp = data;
900e3f3a1aeSLuiz Augusto von Dentz 
901e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
902971e3a4bSAndre Guedes 
903971e3a4bSAndre Guedes 	if (rp->status)
904c8992cffSLuiz Augusto von Dentz 		return rp->status;
905971e3a4bSAndre Guedes 
9068194f1efSVasily Khoruzhick 	if (hdev->max_page < rp->max_page) {
9078194f1efSVasily Khoruzhick 		if (test_bit(HCI_QUIRK_BROKEN_LOCAL_EXT_FEATURES_PAGE_2,
9088194f1efSVasily Khoruzhick 			     &hdev->quirks))
9098194f1efSVasily Khoruzhick 			bt_dev_warn(hdev, "broken local ext features page 2");
9108194f1efSVasily Khoruzhick 		else
911d2c5d77fSJohan Hedberg 			hdev->max_page = rp->max_page;
9128194f1efSVasily Khoruzhick 	}
913d2c5d77fSJohan Hedberg 
914cad718edSJohan Hedberg 	if (rp->page < HCI_MAX_PAGES)
915cad718edSJohan Hedberg 		memcpy(hdev->features[rp->page], rp->features, 8);
916c8992cffSLuiz Augusto von Dentz 
917c8992cffSLuiz Augusto von Dentz 	return rp->status;
918971e3a4bSAndre Guedes }
919971e3a4bSAndre Guedes 
hci_cc_read_buffer_size(struct hci_dev * hdev,void * data,struct sk_buff * skb)920c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_buffer_size(struct hci_dev *hdev, void *data,
921c8992cffSLuiz Augusto von Dentz 				  struct sk_buff *skb)
922a9de9248SMarcel Holtmann {
923c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_buffer_size *rp = data;
924e3f3a1aeSLuiz Augusto von Dentz 
925e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
926a9de9248SMarcel Holtmann 
927a9de9248SMarcel Holtmann 	if (rp->status)
928c8992cffSLuiz Augusto von Dentz 		return rp->status;
929a9de9248SMarcel Holtmann 
930a9de9248SMarcel Holtmann 	hdev->acl_mtu  = __le16_to_cpu(rp->acl_mtu);
931a9de9248SMarcel Holtmann 	hdev->sco_mtu  = rp->sco_mtu;
932a9de9248SMarcel Holtmann 	hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
933a9de9248SMarcel Holtmann 	hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
934da1f5198SMarcel Holtmann 
935da1f5198SMarcel Holtmann 	if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
936da1f5198SMarcel Holtmann 		hdev->sco_mtu  = 64;
937da1f5198SMarcel Holtmann 		hdev->sco_pkts = 8;
938da1f5198SMarcel Holtmann 	}
939da1f5198SMarcel Holtmann 
940da1f5198SMarcel Holtmann 	hdev->acl_cnt = hdev->acl_pkts;
941da1f5198SMarcel Holtmann 	hdev->sco_cnt = hdev->sco_pkts;
9421da177e4SLinus Torvalds 
943807deac2SGustavo Padovan 	BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
944807deac2SGustavo Padovan 	       hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
945c8992cffSLuiz Augusto von Dentz 
946ad3f7986SSungwoo Kim 	if (!hdev->acl_mtu || !hdev->acl_pkts)
947ad3f7986SSungwoo Kim 		return HCI_ERROR_INVALID_PARAMETERS;
948ad3f7986SSungwoo Kim 
949c8992cffSLuiz Augusto von Dentz 	return rp->status;
9501da177e4SLinus Torvalds }
9511da177e4SLinus Torvalds 
hci_cc_read_bd_addr(struct hci_dev * hdev,void * data,struct sk_buff * skb)952c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_bd_addr(struct hci_dev *hdev, void *data,
953c8992cffSLuiz Augusto von Dentz 			      struct sk_buff *skb)
954a9de9248SMarcel Holtmann {
955c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_bd_addr *rp = data;
956e3f3a1aeSLuiz Augusto von Dentz 
957e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
958a9de9248SMarcel Holtmann 
959e30d3f5fSMarcel Holtmann 	if (rp->status)
960c8992cffSLuiz Augusto von Dentz 		return rp->status;
961e30d3f5fSMarcel Holtmann 
962e30d3f5fSMarcel Holtmann 	if (test_bit(HCI_INIT, &hdev->flags))
963a9de9248SMarcel Holtmann 		bacpy(&hdev->bdaddr, &rp->bdaddr);
964e30d3f5fSMarcel Holtmann 
965d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP))
966e30d3f5fSMarcel Holtmann 		bacpy(&hdev->setup_addr, &rp->bdaddr);
967c8992cffSLuiz Augusto von Dentz 
968c8992cffSLuiz Augusto von Dentz 	return rp->status;
96923bb5763SJohan Hedberg }
97023bb5763SJohan Hedberg 
hci_cc_read_local_pairing_opts(struct hci_dev * hdev,void * data,struct sk_buff * skb)971c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_pairing_opts(struct hci_dev *hdev, void *data,
972a4790360SMarcel Holtmann 					 struct sk_buff *skb)
973a4790360SMarcel Holtmann {
974c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_pairing_opts *rp = data;
975e3f3a1aeSLuiz Augusto von Dentz 
976e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
977a4790360SMarcel Holtmann 
978a4790360SMarcel Holtmann 	if (rp->status)
979c8992cffSLuiz Augusto von Dentz 		return rp->status;
980a4790360SMarcel Holtmann 
981a4790360SMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP) ||
982a4790360SMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_CONFIG)) {
983a4790360SMarcel Holtmann 		hdev->pairing_opts = rp->pairing_opts;
984a4790360SMarcel Holtmann 		hdev->max_enc_key_size = rp->max_key_size;
985a4790360SMarcel Holtmann 	}
986c8992cffSLuiz Augusto von Dentz 
987c8992cffSLuiz Augusto von Dentz 	return rp->status;
988a4790360SMarcel Holtmann }
989a4790360SMarcel Holtmann 
hci_cc_read_page_scan_activity(struct hci_dev * hdev,void * data,struct sk_buff * skb)990c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_page_scan_activity(struct hci_dev *hdev, void *data,
991f332ec66SJohan Hedberg 					 struct sk_buff *skb)
992f332ec66SJohan Hedberg {
993c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_page_scan_activity *rp = data;
994e3f3a1aeSLuiz Augusto von Dentz 
995e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
996f332ec66SJohan Hedberg 
99745296acdSMarcel Holtmann 	if (rp->status)
998c8992cffSLuiz Augusto von Dentz 		return rp->status;
99945296acdSMarcel Holtmann 
100045296acdSMarcel Holtmann 	if (test_bit(HCI_INIT, &hdev->flags)) {
1001f332ec66SJohan Hedberg 		hdev->page_scan_interval = __le16_to_cpu(rp->interval);
1002f332ec66SJohan Hedberg 		hdev->page_scan_window = __le16_to_cpu(rp->window);
1003f332ec66SJohan Hedberg 	}
1004c8992cffSLuiz Augusto von Dentz 
1005c8992cffSLuiz Augusto von Dentz 	return rp->status;
1006f332ec66SJohan Hedberg }
1007f332ec66SJohan Hedberg 
hci_cc_write_page_scan_activity(struct hci_dev * hdev,void * data,struct sk_buff * skb)1008c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_page_scan_activity(struct hci_dev *hdev, void *data,
10094a3ee763SJohan Hedberg 					  struct sk_buff *skb)
10104a3ee763SJohan Hedberg {
1011c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
10124a3ee763SJohan Hedberg 	struct hci_cp_write_page_scan_activity *sent;
10134a3ee763SJohan Hedberg 
1014e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1015e3f3a1aeSLuiz Augusto von Dentz 
1016e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1017c8992cffSLuiz Augusto von Dentz 		return rp->status;
10184a3ee763SJohan Hedberg 
10194a3ee763SJohan Hedberg 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY);
10204a3ee763SJohan Hedberg 	if (!sent)
1021c8992cffSLuiz Augusto von Dentz 		return rp->status;
10224a3ee763SJohan Hedberg 
10234a3ee763SJohan Hedberg 	hdev->page_scan_interval = __le16_to_cpu(sent->interval);
10244a3ee763SJohan Hedberg 	hdev->page_scan_window = __le16_to_cpu(sent->window);
1025c8992cffSLuiz Augusto von Dentz 
1026c8992cffSLuiz Augusto von Dentz 	return rp->status;
10274a3ee763SJohan Hedberg }
10284a3ee763SJohan Hedberg 
hci_cc_read_page_scan_type(struct hci_dev * hdev,void * data,struct sk_buff * skb)1029c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_page_scan_type(struct hci_dev *hdev, void *data,
1030f332ec66SJohan Hedberg 				     struct sk_buff *skb)
1031f332ec66SJohan Hedberg {
1032c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_page_scan_type *rp = data;
1033e3f3a1aeSLuiz Augusto von Dentz 
1034e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1035f332ec66SJohan Hedberg 
103645296acdSMarcel Holtmann 	if (rp->status)
1037c8992cffSLuiz Augusto von Dentz 		return rp->status;
103845296acdSMarcel Holtmann 
103945296acdSMarcel Holtmann 	if (test_bit(HCI_INIT, &hdev->flags))
1040f332ec66SJohan Hedberg 		hdev->page_scan_type = rp->type;
1041c8992cffSLuiz Augusto von Dentz 
1042c8992cffSLuiz Augusto von Dentz 	return rp->status;
1043f332ec66SJohan Hedberg }
1044f332ec66SJohan Hedberg 
hci_cc_write_page_scan_type(struct hci_dev * hdev,void * data,struct sk_buff * skb)1045c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_page_scan_type(struct hci_dev *hdev, void *data,
10464a3ee763SJohan Hedberg 				      struct sk_buff *skb)
10474a3ee763SJohan Hedberg {
1048c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
10494a3ee763SJohan Hedberg 	u8 *type;
10504a3ee763SJohan Hedberg 
1051e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1052e3f3a1aeSLuiz Augusto von Dentz 
1053e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1054c8992cffSLuiz Augusto von Dentz 		return rp->status;
10554a3ee763SJohan Hedberg 
10564a3ee763SJohan Hedberg 	type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE);
10574a3ee763SJohan Hedberg 	if (type)
10584a3ee763SJohan Hedberg 		hdev->page_scan_type = *type;
1059c8992cffSLuiz Augusto von Dentz 
1060c8992cffSLuiz Augusto von Dentz 	return rp->status;
10614a3ee763SJohan Hedberg }
10624a3ee763SJohan Hedberg 
hci_cc_read_clock(struct hci_dev * hdev,void * data,struct sk_buff * skb)1063c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_clock(struct hci_dev *hdev, void *data,
1064c8992cffSLuiz Augusto von Dentz 			    struct sk_buff *skb)
106533f35721SJohan Hedberg {
1066c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_clock *rp = data;
106733f35721SJohan Hedberg 	struct hci_cp_read_clock *cp;
106833f35721SJohan Hedberg 	struct hci_conn *conn;
106933f35721SJohan Hedberg 
1070e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1071e3f3a1aeSLuiz Augusto von Dentz 
107233f35721SJohan Hedberg 	if (rp->status)
1073c8992cffSLuiz Augusto von Dentz 		return rp->status;
107433f35721SJohan Hedberg 
107533f35721SJohan Hedberg 	hci_dev_lock(hdev);
107633f35721SJohan Hedberg 
107733f35721SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_READ_CLOCK);
107833f35721SJohan Hedberg 	if (!cp)
107933f35721SJohan Hedberg 		goto unlock;
108033f35721SJohan Hedberg 
108133f35721SJohan Hedberg 	if (cp->which == 0x00) {
108233f35721SJohan Hedberg 		hdev->clock = le32_to_cpu(rp->clock);
108333f35721SJohan Hedberg 		goto unlock;
108433f35721SJohan Hedberg 	}
108533f35721SJohan Hedberg 
108633f35721SJohan Hedberg 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
108733f35721SJohan Hedberg 	if (conn) {
108833f35721SJohan Hedberg 		conn->clock = le32_to_cpu(rp->clock);
108933f35721SJohan Hedberg 		conn->clock_accuracy = le16_to_cpu(rp->accuracy);
109033f35721SJohan Hedberg 	}
109133f35721SJohan Hedberg 
109233f35721SJohan Hedberg unlock:
109333f35721SJohan Hedberg 	hci_dev_unlock(hdev);
1094c8992cffSLuiz Augusto von Dentz 	return rp->status;
109533f35721SJohan Hedberg }
109633f35721SJohan Hedberg 
hci_cc_read_inq_rsp_tx_power(struct hci_dev * hdev,void * data,struct sk_buff * skb)1097c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev, void *data,
1098d5859e22SJohan Hedberg 				       struct sk_buff *skb)
1099d5859e22SJohan Hedberg {
1100c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_inq_rsp_tx_power *rp = data;
1101e3f3a1aeSLuiz Augusto von Dentz 
1102e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1103d5859e22SJohan Hedberg 
110445296acdSMarcel Holtmann 	if (rp->status)
1105c8992cffSLuiz Augusto von Dentz 		return rp->status;
110645296acdSMarcel Holtmann 
110791c4e9b1SMarcel Holtmann 	hdev->inq_tx_power = rp->tx_power;
1108c8992cffSLuiz Augusto von Dentz 
1109c8992cffSLuiz Augusto von Dentz 	return rp->status;
1110d5859e22SJohan Hedberg }
1111d5859e22SJohan Hedberg 
hci_cc_read_def_err_data_reporting(struct hci_dev * hdev,void * data,struct sk_buff * skb)1112c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_def_err_data_reporting(struct hci_dev *hdev, void *data,
111300bce3fbSAlain Michaud 					     struct sk_buff *skb)
111400bce3fbSAlain Michaud {
1115c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_def_err_data_reporting *rp = data;
1116e3f3a1aeSLuiz Augusto von Dentz 
1117e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
111800bce3fbSAlain Michaud 
111900bce3fbSAlain Michaud 	if (rp->status)
1120c8992cffSLuiz Augusto von Dentz 		return rp->status;
112100bce3fbSAlain Michaud 
112200bce3fbSAlain Michaud 	hdev->err_data_reporting = rp->err_data_reporting;
1123c8992cffSLuiz Augusto von Dentz 
1124c8992cffSLuiz Augusto von Dentz 	return rp->status;
112500bce3fbSAlain Michaud }
112600bce3fbSAlain Michaud 
hci_cc_write_def_err_data_reporting(struct hci_dev * hdev,void * data,struct sk_buff * skb)1127c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_def_err_data_reporting(struct hci_dev *hdev, void *data,
112800bce3fbSAlain Michaud 					      struct sk_buff *skb)
112900bce3fbSAlain Michaud {
1130c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
113100bce3fbSAlain Michaud 	struct hci_cp_write_def_err_data_reporting *cp;
113200bce3fbSAlain Michaud 
1133e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1134e3f3a1aeSLuiz Augusto von Dentz 
1135e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1136c8992cffSLuiz Augusto von Dentz 		return rp->status;
113700bce3fbSAlain Michaud 
113800bce3fbSAlain Michaud 	cp = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_ERR_DATA_REPORTING);
113900bce3fbSAlain Michaud 	if (!cp)
1140c8992cffSLuiz Augusto von Dentz 		return rp->status;
114100bce3fbSAlain Michaud 
114200bce3fbSAlain Michaud 	hdev->err_data_reporting = cp->err_data_reporting;
1143c8992cffSLuiz Augusto von Dentz 
1144c8992cffSLuiz Augusto von Dentz 	return rp->status;
114500bce3fbSAlain Michaud }
114600bce3fbSAlain Michaud 
hci_cc_pin_code_reply(struct hci_dev * hdev,void * data,struct sk_buff * skb)1147c8992cffSLuiz Augusto von Dentz static u8 hci_cc_pin_code_reply(struct hci_dev *hdev, void *data,
1148c8992cffSLuiz Augusto von Dentz 				struct sk_buff *skb)
1149980e1a53SJohan Hedberg {
1150c8992cffSLuiz Augusto von Dentz 	struct hci_rp_pin_code_reply *rp = data;
1151980e1a53SJohan Hedberg 	struct hci_cp_pin_code_reply *cp;
1152980e1a53SJohan Hedberg 	struct hci_conn *conn;
1153980e1a53SJohan Hedberg 
1154e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1155980e1a53SJohan Hedberg 
115656e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
115756e5cb86SJohan Hedberg 
1158d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
1159744cf19eSJohan Hedberg 		mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
1160980e1a53SJohan Hedberg 
1161fa1bd918SMikel Astiz 	if (rp->status)
116256e5cb86SJohan Hedberg 		goto unlock;
1163980e1a53SJohan Hedberg 
1164980e1a53SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
1165980e1a53SJohan Hedberg 	if (!cp)
116656e5cb86SJohan Hedberg 		goto unlock;
1167980e1a53SJohan Hedberg 
1168980e1a53SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1169980e1a53SJohan Hedberg 	if (conn)
1170980e1a53SJohan Hedberg 		conn->pin_length = cp->pin_len;
117156e5cb86SJohan Hedberg 
117256e5cb86SJohan Hedberg unlock:
117356e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
1174c8992cffSLuiz Augusto von Dentz 	return rp->status;
1175980e1a53SJohan Hedberg }
1176980e1a53SJohan Hedberg 
hci_cc_pin_code_neg_reply(struct hci_dev * hdev,void * data,struct sk_buff * skb)1177c8992cffSLuiz Augusto von Dentz static u8 hci_cc_pin_code_neg_reply(struct hci_dev *hdev, void *data,
1178c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
1179980e1a53SJohan Hedberg {
1180c8992cffSLuiz Augusto von Dentz 	struct hci_rp_pin_code_neg_reply *rp = data;
1181e3f3a1aeSLuiz Augusto von Dentz 
1182e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1183980e1a53SJohan Hedberg 
118456e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
118556e5cb86SJohan Hedberg 
1186d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
1187744cf19eSJohan Hedberg 		mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
1188980e1a53SJohan Hedberg 						 rp->status);
118956e5cb86SJohan Hedberg 
119056e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
1191c8992cffSLuiz Augusto von Dentz 
1192c8992cffSLuiz Augusto von Dentz 	return rp->status;
1193980e1a53SJohan Hedberg }
119456e5cb86SJohan Hedberg 
hci_cc_le_read_buffer_size(struct hci_dev * hdev,void * data,struct sk_buff * skb)1195c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_buffer_size(struct hci_dev *hdev, void *data,
11966ed58ec5SVille Tervo 				     struct sk_buff *skb)
11976ed58ec5SVille Tervo {
1198c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_buffer_size *rp = data;
1199e3f3a1aeSLuiz Augusto von Dentz 
1200e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
12016ed58ec5SVille Tervo 
12026ed58ec5SVille Tervo 	if (rp->status)
1203c8992cffSLuiz Augusto von Dentz 		return rp->status;
12046ed58ec5SVille Tervo 
12056ed58ec5SVille Tervo 	hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
12066ed58ec5SVille Tervo 	hdev->le_pkts = rp->le_max_pkt;
12076ed58ec5SVille Tervo 
12086ed58ec5SVille Tervo 	hdev->le_cnt = hdev->le_pkts;
12096ed58ec5SVille Tervo 
12106ed58ec5SVille Tervo 	BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
1211c8992cffSLuiz Augusto von Dentz 
1212ad3f7986SSungwoo Kim 	if (hdev->le_mtu && hdev->le_mtu < HCI_MIN_LE_MTU)
1213ad3f7986SSungwoo Kim 		return HCI_ERROR_INVALID_PARAMETERS;
1214ad3f7986SSungwoo Kim 
1215c8992cffSLuiz Augusto von Dentz 	return rp->status;
12166ed58ec5SVille Tervo }
1217980e1a53SJohan Hedberg 
hci_cc_le_read_local_features(struct hci_dev * hdev,void * data,struct sk_buff * skb)1218c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_local_features(struct hci_dev *hdev, void *data,
121960e77321SJohan Hedberg 					struct sk_buff *skb)
122060e77321SJohan Hedberg {
1221c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_local_features *rp = data;
122260e77321SJohan Hedberg 
122360e77321SJohan Hedberg 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
122460e77321SJohan Hedberg 
122545296acdSMarcel Holtmann 	if (rp->status)
1226c8992cffSLuiz Augusto von Dentz 		return rp->status;
122745296acdSMarcel Holtmann 
122860e77321SJohan Hedberg 	memcpy(hdev->le_features, rp->features, 8);
1229c8992cffSLuiz Augusto von Dentz 
1230c8992cffSLuiz Augusto von Dentz 	return rp->status;
123160e77321SJohan Hedberg }
123260e77321SJohan Hedberg 
hci_cc_le_read_adv_tx_power(struct hci_dev * hdev,void * data,struct sk_buff * skb)1233c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_adv_tx_power(struct hci_dev *hdev, void *data,
12348fa19098SJohan Hedberg 				      struct sk_buff *skb)
12358fa19098SJohan Hedberg {
1236c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_adv_tx_power *rp = data;
1237e3f3a1aeSLuiz Augusto von Dentz 
1238e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
12398fa19098SJohan Hedberg 
124045296acdSMarcel Holtmann 	if (rp->status)
1241c8992cffSLuiz Augusto von Dentz 		return rp->status;
124245296acdSMarcel Holtmann 
12438fa19098SJohan Hedberg 	hdev->adv_tx_power = rp->tx_power;
1244c8992cffSLuiz Augusto von Dentz 
1245c8992cffSLuiz Augusto von Dentz 	return rp->status;
12468fa19098SJohan Hedberg }
12478fa19098SJohan Hedberg 
hci_cc_user_confirm_reply(struct hci_dev * hdev,void * data,struct sk_buff * skb)1248c8992cffSLuiz Augusto von Dentz static u8 hci_cc_user_confirm_reply(struct hci_dev *hdev, void *data,
1249c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
1250a5c29683SJohan Hedberg {
1251c8992cffSLuiz Augusto von Dentz 	struct hci_rp_user_confirm_reply *rp = data;
1252e3f3a1aeSLuiz Augusto von Dentz 
1253e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1254a5c29683SJohan Hedberg 
125556e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
125656e5cb86SJohan Hedberg 
1257d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
125804124681SGustavo F. Padovan 		mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
125904124681SGustavo F. Padovan 						 rp->status);
126056e5cb86SJohan Hedberg 
126156e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
1262c8992cffSLuiz Augusto von Dentz 
1263c8992cffSLuiz Augusto von Dentz 	return rp->status;
1264a5c29683SJohan Hedberg }
1265a5c29683SJohan Hedberg 
hci_cc_user_confirm_neg_reply(struct hci_dev * hdev,void * data,struct sk_buff * skb)1266c8992cffSLuiz Augusto von Dentz static u8 hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, void *data,
1267a5c29683SJohan Hedberg 					struct sk_buff *skb)
1268a5c29683SJohan Hedberg {
1269c8992cffSLuiz Augusto von Dentz 	struct hci_rp_user_confirm_reply *rp = data;
1270e3f3a1aeSLuiz Augusto von Dentz 
1271e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1272a5c29683SJohan Hedberg 
127356e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
127456e5cb86SJohan Hedberg 
1275d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
1276744cf19eSJohan Hedberg 		mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
127704124681SGustavo F. Padovan 						     ACL_LINK, 0, rp->status);
127856e5cb86SJohan Hedberg 
127956e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
1280c8992cffSLuiz Augusto von Dentz 
1281c8992cffSLuiz Augusto von Dentz 	return rp->status;
1282a5c29683SJohan Hedberg }
1283a5c29683SJohan Hedberg 
hci_cc_user_passkey_reply(struct hci_dev * hdev,void * data,struct sk_buff * skb)1284c8992cffSLuiz Augusto von Dentz static u8 hci_cc_user_passkey_reply(struct hci_dev *hdev, void *data,
1285c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
12861143d458SBrian Gix {
1287c8992cffSLuiz Augusto von Dentz 	struct hci_rp_user_confirm_reply *rp = data;
1288e3f3a1aeSLuiz Augusto von Dentz 
1289e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
12901143d458SBrian Gix 
12911143d458SBrian Gix 	hci_dev_lock(hdev);
12921143d458SBrian Gix 
1293d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
1294272d90dfSJohan Hedberg 		mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
1295272d90dfSJohan Hedberg 						 0, rp->status);
12961143d458SBrian Gix 
12971143d458SBrian Gix 	hci_dev_unlock(hdev);
1298c8992cffSLuiz Augusto von Dentz 
1299c8992cffSLuiz Augusto von Dentz 	return rp->status;
13001143d458SBrian Gix }
13011143d458SBrian Gix 
hci_cc_user_passkey_neg_reply(struct hci_dev * hdev,void * data,struct sk_buff * skb)1302c8992cffSLuiz Augusto von Dentz static u8 hci_cc_user_passkey_neg_reply(struct hci_dev *hdev, void *data,
13031143d458SBrian Gix 					struct sk_buff *skb)
13041143d458SBrian Gix {
1305c8992cffSLuiz Augusto von Dentz 	struct hci_rp_user_confirm_reply *rp = data;
1306e3f3a1aeSLuiz Augusto von Dentz 
1307e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
13081143d458SBrian Gix 
13091143d458SBrian Gix 	hci_dev_lock(hdev);
13101143d458SBrian Gix 
1311d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
13121143d458SBrian Gix 		mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
131304124681SGustavo F. Padovan 						     ACL_LINK, 0, rp->status);
13141143d458SBrian Gix 
13151143d458SBrian Gix 	hci_dev_unlock(hdev);
1316c8992cffSLuiz Augusto von Dentz 
1317c8992cffSLuiz Augusto von Dentz 	return rp->status;
13181143d458SBrian Gix }
13191143d458SBrian Gix 
hci_cc_read_local_oob_data(struct hci_dev * hdev,void * data,struct sk_buff * skb)1320c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_oob_data(struct hci_dev *hdev, void *data,
1321c35938b2SSzymon Janc 				     struct sk_buff *skb)
1322c35938b2SSzymon Janc {
1323c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_oob_data *rp = data;
1324e3f3a1aeSLuiz Augusto von Dentz 
1325e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1326c8992cffSLuiz Augusto von Dentz 
1327c8992cffSLuiz Augusto von Dentz 	return rp->status;
13284d2d2796SMarcel Holtmann }
13294d2d2796SMarcel Holtmann 
hci_cc_read_local_oob_ext_data(struct hci_dev * hdev,void * data,struct sk_buff * skb)1330c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_local_oob_ext_data(struct hci_dev *hdev, void *data,
13314d2d2796SMarcel Holtmann 					 struct sk_buff *skb)
13324d2d2796SMarcel Holtmann {
1333c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_local_oob_ext_data *rp = data;
1334e3f3a1aeSLuiz Augusto von Dentz 
1335e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1336c8992cffSLuiz Augusto von Dentz 
1337c8992cffSLuiz Augusto von Dentz 	return rp->status;
1338c35938b2SSzymon Janc }
1339c35938b2SSzymon Janc 
hci_cc_le_set_random_addr(struct hci_dev * hdev,void * data,struct sk_buff * skb)1340c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_random_addr(struct hci_dev *hdev, void *data,
1341c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
13427a4cd51dSMarcel Holtmann {
1343c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
13447a4cd51dSMarcel Holtmann 	bdaddr_t *sent;
13457a4cd51dSMarcel Holtmann 
1346e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1347e3f3a1aeSLuiz Augusto von Dentz 
1348e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1349c8992cffSLuiz Augusto von Dentz 		return rp->status;
135045296acdSMarcel Holtmann 
13517a4cd51dSMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_RANDOM_ADDR);
13527a4cd51dSMarcel Holtmann 	if (!sent)
1353c8992cffSLuiz Augusto von Dentz 		return rp->status;
13547a4cd51dSMarcel Holtmann 
13557a4cd51dSMarcel Holtmann 	hci_dev_lock(hdev);
13567a4cd51dSMarcel Holtmann 
13577a4cd51dSMarcel Holtmann 	bacpy(&hdev->random_addr, sent);
13587a4cd51dSMarcel Holtmann 
1359c45074d6SLuiz Augusto von Dentz 	if (!bacmp(&hdev->rpa, sent)) {
1360c45074d6SLuiz Augusto von Dentz 		hci_dev_clear_flag(hdev, HCI_RPA_EXPIRED);
1361c45074d6SLuiz Augusto von Dentz 		queue_delayed_work(hdev->workqueue, &hdev->rpa_expired,
1362c45074d6SLuiz Augusto von Dentz 				   secs_to_jiffies(hdev->rpa_timeout));
1363c45074d6SLuiz Augusto von Dentz 	}
1364c45074d6SLuiz Augusto von Dentz 
13657a4cd51dSMarcel Holtmann 	hci_dev_unlock(hdev);
1366c8992cffSLuiz Augusto von Dentz 
1367c8992cffSLuiz Augusto von Dentz 	return rp->status;
13687a4cd51dSMarcel Holtmann }
13697a4cd51dSMarcel Holtmann 
hci_cc_le_set_default_phy(struct hci_dev * hdev,void * data,struct sk_buff * skb)1370c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_default_phy(struct hci_dev *hdev, void *data,
1371c8992cffSLuiz Augusto von Dentz 				    struct sk_buff *skb)
13720314f286SJaganath Kanakkassery {
1373c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
13740314f286SJaganath Kanakkassery 	struct hci_cp_le_set_default_phy *cp;
13750314f286SJaganath Kanakkassery 
1376e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1377e3f3a1aeSLuiz Augusto von Dentz 
1378e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1379c8992cffSLuiz Augusto von Dentz 		return rp->status;
13800314f286SJaganath Kanakkassery 
13810314f286SJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_DEFAULT_PHY);
13820314f286SJaganath Kanakkassery 	if (!cp)
1383c8992cffSLuiz Augusto von Dentz 		return rp->status;
13840314f286SJaganath Kanakkassery 
13850314f286SJaganath Kanakkassery 	hci_dev_lock(hdev);
13860314f286SJaganath Kanakkassery 
13870314f286SJaganath Kanakkassery 	hdev->le_tx_def_phys = cp->tx_phys;
13880314f286SJaganath Kanakkassery 	hdev->le_rx_def_phys = cp->rx_phys;
13890314f286SJaganath Kanakkassery 
13900314f286SJaganath Kanakkassery 	hci_dev_unlock(hdev);
1391c8992cffSLuiz Augusto von Dentz 
1392c8992cffSLuiz Augusto von Dentz 	return rp->status;
13930314f286SJaganath Kanakkassery }
13940314f286SJaganath Kanakkassery 
hci_cc_le_set_adv_set_random_addr(struct hci_dev * hdev,void * data,struct sk_buff * skb)1395c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_adv_set_random_addr(struct hci_dev *hdev, void *data,
1396a73c046aSJaganath Kanakkassery 					    struct sk_buff *skb)
1397a73c046aSJaganath Kanakkassery {
1398c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1399a73c046aSJaganath Kanakkassery 	struct hci_cp_le_set_adv_set_rand_addr *cp;
1400c45074d6SLuiz Augusto von Dentz 	struct adv_info *adv;
1401a73c046aSJaganath Kanakkassery 
1402e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1403e3f3a1aeSLuiz Augusto von Dentz 
1404e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1405c8992cffSLuiz Augusto von Dentz 		return rp->status;
1406a73c046aSJaganath Kanakkassery 
1407a73c046aSJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_SET_RAND_ADDR);
1408c45074d6SLuiz Augusto von Dentz 	/* Update only in case the adv instance since handle 0x00 shall be using
1409c45074d6SLuiz Augusto von Dentz 	 * HCI_OP_LE_SET_RANDOM_ADDR since that allows both extended and
1410c45074d6SLuiz Augusto von Dentz 	 * non-extended adverting.
1411c45074d6SLuiz Augusto von Dentz 	 */
1412c45074d6SLuiz Augusto von Dentz 	if (!cp || !cp->handle)
1413c8992cffSLuiz Augusto von Dentz 		return rp->status;
1414a73c046aSJaganath Kanakkassery 
1415a73c046aSJaganath Kanakkassery 	hci_dev_lock(hdev);
1416a73c046aSJaganath Kanakkassery 
1417c45074d6SLuiz Augusto von Dentz 	adv = hci_find_adv_instance(hdev, cp->handle);
1418c45074d6SLuiz Augusto von Dentz 	if (adv) {
1419c45074d6SLuiz Augusto von Dentz 		bacpy(&adv->random_addr, &cp->bdaddr);
1420c45074d6SLuiz Augusto von Dentz 		if (!bacmp(&hdev->rpa, &cp->bdaddr)) {
1421c45074d6SLuiz Augusto von Dentz 			adv->rpa_expired = false;
1422c45074d6SLuiz Augusto von Dentz 			queue_delayed_work(hdev->workqueue,
1423c45074d6SLuiz Augusto von Dentz 					   &adv->rpa_expired_cb,
1424c45074d6SLuiz Augusto von Dentz 					   secs_to_jiffies(hdev->rpa_timeout));
1425c45074d6SLuiz Augusto von Dentz 		}
1426a73c046aSJaganath Kanakkassery 	}
1427a73c046aSJaganath Kanakkassery 
1428a73c046aSJaganath Kanakkassery 	hci_dev_unlock(hdev);
1429c8992cffSLuiz Augusto von Dentz 
1430c8992cffSLuiz Augusto von Dentz 	return rp->status;
1431a73c046aSJaganath Kanakkassery }
1432a73c046aSJaganath Kanakkassery 
hci_cc_le_remove_adv_set(struct hci_dev * hdev,void * data,struct sk_buff * skb)1433c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_remove_adv_set(struct hci_dev *hdev, void *data,
1434c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
1435cba6b758SLuiz Augusto von Dentz {
1436c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1437cba6b758SLuiz Augusto von Dentz 	u8 *instance;
1438cba6b758SLuiz Augusto von Dentz 	int err;
1439cba6b758SLuiz Augusto von Dentz 
1440e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1441e3f3a1aeSLuiz Augusto von Dentz 
1442e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1443c8992cffSLuiz Augusto von Dentz 		return rp->status;
1444cba6b758SLuiz Augusto von Dentz 
1445cba6b758SLuiz Augusto von Dentz 	instance = hci_sent_cmd_data(hdev, HCI_OP_LE_REMOVE_ADV_SET);
1446cba6b758SLuiz Augusto von Dentz 	if (!instance)
1447c8992cffSLuiz Augusto von Dentz 		return rp->status;
1448cba6b758SLuiz Augusto von Dentz 
1449cba6b758SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
1450cba6b758SLuiz Augusto von Dentz 
1451cba6b758SLuiz Augusto von Dentz 	err = hci_remove_adv_instance(hdev, *instance);
1452cba6b758SLuiz Augusto von Dentz 	if (!err)
1453cba6b758SLuiz Augusto von Dentz 		mgmt_advertising_removed(hci_skb_sk(hdev->sent_cmd), hdev,
1454cba6b758SLuiz Augusto von Dentz 					 *instance);
1455cba6b758SLuiz Augusto von Dentz 
1456cba6b758SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
1457c8992cffSLuiz Augusto von Dentz 
1458c8992cffSLuiz Augusto von Dentz 	return rp->status;
1459cba6b758SLuiz Augusto von Dentz }
1460cba6b758SLuiz Augusto von Dentz 
hci_cc_le_clear_adv_sets(struct hci_dev * hdev,void * data,struct sk_buff * skb)1461c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_clear_adv_sets(struct hci_dev *hdev, void *data,
1462c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
1463cba6b758SLuiz Augusto von Dentz {
1464c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1465cba6b758SLuiz Augusto von Dentz 	struct adv_info *adv, *n;
1466cba6b758SLuiz Augusto von Dentz 	int err;
1467cba6b758SLuiz Augusto von Dentz 
1468e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1469e3f3a1aeSLuiz Augusto von Dentz 
1470e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1471c8992cffSLuiz Augusto von Dentz 		return rp->status;
1472cba6b758SLuiz Augusto von Dentz 
1473cba6b758SLuiz Augusto von Dentz 	if (!hci_sent_cmd_data(hdev, HCI_OP_LE_CLEAR_ADV_SETS))
1474c8992cffSLuiz Augusto von Dentz 		return rp->status;
1475cba6b758SLuiz Augusto von Dentz 
1476cba6b758SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
1477cba6b758SLuiz Augusto von Dentz 
1478cba6b758SLuiz Augusto von Dentz 	list_for_each_entry_safe(adv, n, &hdev->adv_instances, list) {
1479cba6b758SLuiz Augusto von Dentz 		u8 instance = adv->instance;
1480cba6b758SLuiz Augusto von Dentz 
1481cba6b758SLuiz Augusto von Dentz 		err = hci_remove_adv_instance(hdev, instance);
1482cba6b758SLuiz Augusto von Dentz 		if (!err)
1483cba6b758SLuiz Augusto von Dentz 			mgmt_advertising_removed(hci_skb_sk(hdev->sent_cmd),
1484cba6b758SLuiz Augusto von Dentz 						 hdev, instance);
1485cba6b758SLuiz Augusto von Dentz 	}
1486cba6b758SLuiz Augusto von Dentz 
1487cba6b758SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
1488c8992cffSLuiz Augusto von Dentz 
1489c8992cffSLuiz Augusto von Dentz 	return rp->status;
1490cba6b758SLuiz Augusto von Dentz }
1491cba6b758SLuiz Augusto von Dentz 
hci_cc_le_read_transmit_power(struct hci_dev * hdev,void * data,struct sk_buff * skb)1492c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_transmit_power(struct hci_dev *hdev, void *data,
14937c395ea5SDaniel Winkler 					struct sk_buff *skb)
14947c395ea5SDaniel Winkler {
1495c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_transmit_power *rp = data;
1496e3f3a1aeSLuiz Augusto von Dentz 
1497e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
14987c395ea5SDaniel Winkler 
14997c395ea5SDaniel Winkler 	if (rp->status)
1500c8992cffSLuiz Augusto von Dentz 		return rp->status;
15017c395ea5SDaniel Winkler 
15027c395ea5SDaniel Winkler 	hdev->min_le_tx_power = rp->min_le_tx_power;
15037c395ea5SDaniel Winkler 	hdev->max_le_tx_power = rp->max_le_tx_power;
1504c8992cffSLuiz Augusto von Dentz 
1505c8992cffSLuiz Augusto von Dentz 	return rp->status;
15067c395ea5SDaniel Winkler }
15077c395ea5SDaniel Winkler 
hci_cc_le_set_privacy_mode(struct hci_dev * hdev,void * data,struct sk_buff * skb)1508853b70b5SLuiz Augusto von Dentz static u8 hci_cc_le_set_privacy_mode(struct hci_dev *hdev, void *data,
1509853b70b5SLuiz Augusto von Dentz 				     struct sk_buff *skb)
1510853b70b5SLuiz Augusto von Dentz {
1511853b70b5SLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1512853b70b5SLuiz Augusto von Dentz 	struct hci_cp_le_set_privacy_mode *cp;
1513853b70b5SLuiz Augusto von Dentz 	struct hci_conn_params *params;
1514853b70b5SLuiz Augusto von Dentz 
1515853b70b5SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1516853b70b5SLuiz Augusto von Dentz 
1517853b70b5SLuiz Augusto von Dentz 	if (rp->status)
1518853b70b5SLuiz Augusto von Dentz 		return rp->status;
1519853b70b5SLuiz Augusto von Dentz 
1520853b70b5SLuiz Augusto von Dentz 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_PRIVACY_MODE);
1521853b70b5SLuiz Augusto von Dentz 	if (!cp)
1522853b70b5SLuiz Augusto von Dentz 		return rp->status;
1523853b70b5SLuiz Augusto von Dentz 
1524853b70b5SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
1525853b70b5SLuiz Augusto von Dentz 
1526853b70b5SLuiz Augusto von Dentz 	params = hci_conn_params_lookup(hdev, &cp->bdaddr, cp->bdaddr_type);
1527853b70b5SLuiz Augusto von Dentz 	if (params)
1528195ef75eSPauli Virtanen 		WRITE_ONCE(params->privacy_mode, cp->mode);
1529853b70b5SLuiz Augusto von Dentz 
1530853b70b5SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
1531853b70b5SLuiz Augusto von Dentz 
1532853b70b5SLuiz Augusto von Dentz 	return rp->status;
1533853b70b5SLuiz Augusto von Dentz }
1534853b70b5SLuiz Augusto von Dentz 
hci_cc_le_set_adv_enable(struct hci_dev * hdev,void * data,struct sk_buff * skb)1535c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_adv_enable(struct hci_dev *hdev, void *data,
1536c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
1537c1d5dc4aSJohan Hedberg {
1538c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1539e3f3a1aeSLuiz Augusto von Dentz 	__u8 *sent;
1540c1d5dc4aSJohan Hedberg 
1541e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1542e3f3a1aeSLuiz Augusto von Dentz 
1543e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1544c8992cffSLuiz Augusto von Dentz 		return rp->status;
1545c1d5dc4aSJohan Hedberg 
154645296acdSMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
154745296acdSMarcel Holtmann 	if (!sent)
1548c8992cffSLuiz Augusto von Dentz 		return rp->status;
15493c857757SJohan Hedberg 
1550c1d5dc4aSJohan Hedberg 	hci_dev_lock(hdev);
1551c1d5dc4aSJohan Hedberg 
155249c922bbSStephen Hemminger 	/* If we're doing connection initiation as peripheral. Set a
15533c857757SJohan Hedberg 	 * timeout in case something goes wrong.
15543c857757SJohan Hedberg 	 */
15553c857757SJohan Hedberg 	if (*sent) {
15563c857757SJohan Hedberg 		struct hci_conn *conn;
15573c857757SJohan Hedberg 
1558a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_LE_ADV);
155966c417c1SJohan Hedberg 
1560e7d9ab73SJakub Pawlowski 		conn = hci_lookup_le_connect(hdev);
15613c857757SJohan Hedberg 		if (conn)
15623c857757SJohan Hedberg 			queue_delayed_work(hdev->workqueue,
15633c857757SJohan Hedberg 					   &conn->le_conn_timeout,
156409ae260bSJohan Hedberg 					   conn->conn_timeout);
156566c417c1SJohan Hedberg 	} else {
1566a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LE_ADV);
15673c857757SJohan Hedberg 	}
15683c857757SJohan Hedberg 
156904b4edcbSJohan Hedberg 	hci_dev_unlock(hdev);
1570c8992cffSLuiz Augusto von Dentz 
1571c8992cffSLuiz Augusto von Dentz 	return rp->status;
1572c1d5dc4aSJohan Hedberg }
1573c1d5dc4aSJohan Hedberg 
hci_cc_le_set_ext_adv_enable(struct hci_dev * hdev,void * data,struct sk_buff * skb)1574c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_ext_adv_enable(struct hci_dev *hdev, void *data,
1575de181e88SJaganath Kanakkassery 				       struct sk_buff *skb)
1576de181e88SJaganath Kanakkassery {
1577de181e88SJaganath Kanakkassery 	struct hci_cp_le_set_ext_adv_enable *cp;
157810279313SLuiz Augusto von Dentz 	struct hci_cp_ext_adv_set *set;
157910279313SLuiz Augusto von Dentz 	struct adv_info *adv = NULL, *n;
1580c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1581de181e88SJaganath Kanakkassery 
1582e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1583e3f3a1aeSLuiz Augusto von Dentz 
1584e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1585c8992cffSLuiz Augusto von Dentz 		return rp->status;
1586de181e88SJaganath Kanakkassery 
1587de181e88SJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_ADV_ENABLE);
1588de181e88SJaganath Kanakkassery 	if (!cp)
1589c8992cffSLuiz Augusto von Dentz 		return rp->status;
1590de181e88SJaganath Kanakkassery 
159110279313SLuiz Augusto von Dentz 	set = (void *)cp->data;
159210279313SLuiz Augusto von Dentz 
1593de181e88SJaganath Kanakkassery 	hci_dev_lock(hdev);
1594de181e88SJaganath Kanakkassery 
159510279313SLuiz Augusto von Dentz 	if (cp->num_of_sets)
159610279313SLuiz Augusto von Dentz 		adv = hci_find_adv_instance(hdev, set->handle);
159710279313SLuiz Augusto von Dentz 
1598de181e88SJaganath Kanakkassery 	if (cp->enable) {
1599de181e88SJaganath Kanakkassery 		struct hci_conn *conn;
1600de181e88SJaganath Kanakkassery 
1601de181e88SJaganath Kanakkassery 		hci_dev_set_flag(hdev, HCI_LE_ADV);
1602de181e88SJaganath Kanakkassery 
16036a42e9bfSIulia Tanasescu 		if (adv && !adv->periodic)
160410279313SLuiz Augusto von Dentz 			adv->enabled = true;
160510279313SLuiz Augusto von Dentz 
1606de181e88SJaganath Kanakkassery 		conn = hci_lookup_le_connect(hdev);
1607de181e88SJaganath Kanakkassery 		if (conn)
1608de181e88SJaganath Kanakkassery 			queue_delayed_work(hdev->workqueue,
1609de181e88SJaganath Kanakkassery 					   &conn->le_conn_timeout,
1610de181e88SJaganath Kanakkassery 					   conn->conn_timeout);
161145b7749fSJaganath Kanakkassery 	} else {
16122128939fSArchie Pusaka 		if (cp->num_of_sets) {
16132128939fSArchie Pusaka 			if (adv)
161410279313SLuiz Augusto von Dentz 				adv->enabled = false;
16152128939fSArchie Pusaka 
161610279313SLuiz Augusto von Dentz 			/* If just one instance was disabled check if there are
161710279313SLuiz Augusto von Dentz 			 * any other instance enabled before clearing HCI_LE_ADV
161810279313SLuiz Augusto von Dentz 			 */
161910279313SLuiz Augusto von Dentz 			list_for_each_entry_safe(adv, n, &hdev->adv_instances,
162010279313SLuiz Augusto von Dentz 						 list) {
162110279313SLuiz Augusto von Dentz 				if (adv->enabled)
162210279313SLuiz Augusto von Dentz 					goto unlock;
162310279313SLuiz Augusto von Dentz 			}
162410279313SLuiz Augusto von Dentz 		} else {
162510279313SLuiz Augusto von Dentz 			/* All instances shall be considered disabled */
162610279313SLuiz Augusto von Dentz 			list_for_each_entry_safe(adv, n, &hdev->adv_instances,
162710279313SLuiz Augusto von Dentz 						 list)
162810279313SLuiz Augusto von Dentz 				adv->enabled = false;
162910279313SLuiz Augusto von Dentz 		}
163010279313SLuiz Augusto von Dentz 
163145b7749fSJaganath Kanakkassery 		hci_dev_clear_flag(hdev, HCI_LE_ADV);
1632de181e88SJaganath Kanakkassery 	}
1633de181e88SJaganath Kanakkassery 
163410279313SLuiz Augusto von Dentz unlock:
1635de181e88SJaganath Kanakkassery 	hci_dev_unlock(hdev);
1636c8992cffSLuiz Augusto von Dentz 	return rp->status;
1637de181e88SJaganath Kanakkassery }
1638de181e88SJaganath Kanakkassery 
hci_cc_le_set_scan_param(struct hci_dev * hdev,void * data,struct sk_buff * skb)1639c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_scan_param(struct hci_dev *hdev, void *data,
1640c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
1641533553f8SMarcel Holtmann {
1642533553f8SMarcel Holtmann 	struct hci_cp_le_set_scan_param *cp;
1643c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1644533553f8SMarcel Holtmann 
1645e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1646e3f3a1aeSLuiz Augusto von Dentz 
1647e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1648c8992cffSLuiz Augusto von Dentz 		return rp->status;
164945296acdSMarcel Holtmann 
1650533553f8SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_PARAM);
1651533553f8SMarcel Holtmann 	if (!cp)
1652c8992cffSLuiz Augusto von Dentz 		return rp->status;
1653533553f8SMarcel Holtmann 
1654533553f8SMarcel Holtmann 	hci_dev_lock(hdev);
1655533553f8SMarcel Holtmann 
1656533553f8SMarcel Holtmann 	hdev->le_scan_type = cp->type;
1657533553f8SMarcel Holtmann 
1658533553f8SMarcel Holtmann 	hci_dev_unlock(hdev);
1659c8992cffSLuiz Augusto von Dentz 
1660c8992cffSLuiz Augusto von Dentz 	return rp->status;
1661533553f8SMarcel Holtmann }
1662533553f8SMarcel Holtmann 
hci_cc_le_set_ext_scan_param(struct hci_dev * hdev,void * data,struct sk_buff * skb)1663c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_ext_scan_param(struct hci_dev *hdev, void *data,
1664a2344b9eSJaganath Kanakkassery 				       struct sk_buff *skb)
1665a2344b9eSJaganath Kanakkassery {
1666a2344b9eSJaganath Kanakkassery 	struct hci_cp_le_set_ext_scan_params *cp;
1667c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1668a2344b9eSJaganath Kanakkassery 	struct hci_cp_le_scan_phy_params *phy_param;
1669a2344b9eSJaganath Kanakkassery 
1670e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1671e3f3a1aeSLuiz Augusto von Dentz 
1672e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1673c8992cffSLuiz Augusto von Dentz 		return rp->status;
1674a2344b9eSJaganath Kanakkassery 
1675a2344b9eSJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_SCAN_PARAMS);
1676a2344b9eSJaganath Kanakkassery 	if (!cp)
1677c8992cffSLuiz Augusto von Dentz 		return rp->status;
1678a2344b9eSJaganath Kanakkassery 
1679a2344b9eSJaganath Kanakkassery 	phy_param = (void *)cp->data;
1680a2344b9eSJaganath Kanakkassery 
1681a2344b9eSJaganath Kanakkassery 	hci_dev_lock(hdev);
1682a2344b9eSJaganath Kanakkassery 
1683a2344b9eSJaganath Kanakkassery 	hdev->le_scan_type = phy_param->type;
1684a2344b9eSJaganath Kanakkassery 
1685a2344b9eSJaganath Kanakkassery 	hci_dev_unlock(hdev);
1686c8992cffSLuiz Augusto von Dentz 
1687c8992cffSLuiz Augusto von Dentz 	return rp->status;
1688a2344b9eSJaganath Kanakkassery }
1689a2344b9eSJaganath Kanakkassery 
has_pending_adv_report(struct hci_dev * hdev)1690b9a6328fSJohan Hedberg static bool has_pending_adv_report(struct hci_dev *hdev)
1691b9a6328fSJohan Hedberg {
1692b9a6328fSJohan Hedberg 	struct discovery_state *d = &hdev->discovery;
1693b9a6328fSJohan Hedberg 
1694b9a6328fSJohan Hedberg 	return bacmp(&d->last_adv_addr, BDADDR_ANY);
1695b9a6328fSJohan Hedberg }
1696b9a6328fSJohan Hedberg 
clear_pending_adv_report(struct hci_dev * hdev)1697b9a6328fSJohan Hedberg static void clear_pending_adv_report(struct hci_dev *hdev)
1698b9a6328fSJohan Hedberg {
1699b9a6328fSJohan Hedberg 	struct discovery_state *d = &hdev->discovery;
1700b9a6328fSJohan Hedberg 
1701b9a6328fSJohan Hedberg 	bacpy(&d->last_adv_addr, BDADDR_ANY);
1702b9a6328fSJohan Hedberg 	d->last_adv_data_len = 0;
1703b9a6328fSJohan Hedberg }
1704b9a6328fSJohan Hedberg 
store_pending_adv_report(struct hci_dev * hdev,bdaddr_t * bdaddr,u8 bdaddr_type,s8 rssi,u32 flags,u8 * data,u8 len)1705b9a6328fSJohan Hedberg static void store_pending_adv_report(struct hci_dev *hdev, bdaddr_t *bdaddr,
1706c70a7e4cSMarcel Holtmann 				     u8 bdaddr_type, s8 rssi, u32 flags,
1707c70a7e4cSMarcel Holtmann 				     u8 *data, u8 len)
1708b9a6328fSJohan Hedberg {
1709b9a6328fSJohan Hedberg 	struct discovery_state *d = &hdev->discovery;
1710b9a6328fSJohan Hedberg 
1711112b5090SLuiz Augusto von Dentz 	if (len > max_adv_len(hdev))
1712a2ec905dSAlain Michaud 		return;
1713a2ec905dSAlain Michaud 
1714b9a6328fSJohan Hedberg 	bacpy(&d->last_adv_addr, bdaddr);
1715b9a6328fSJohan Hedberg 	d->last_adv_addr_type = bdaddr_type;
1716ff5cd29fSJohan Hedberg 	d->last_adv_rssi = rssi;
1717c70a7e4cSMarcel Holtmann 	d->last_adv_flags = flags;
1718b9a6328fSJohan Hedberg 	memcpy(d->last_adv_data, data, len);
1719b9a6328fSJohan Hedberg 	d->last_adv_data_len = len;
1720b9a6328fSJohan Hedberg }
1721b9a6328fSJohan Hedberg 
le_set_scan_enable_complete(struct hci_dev * hdev,u8 enable)17223baef810SJaganath Kanakkassery static void le_set_scan_enable_complete(struct hci_dev *hdev, u8 enable)
1723eb9d91f5SAndre Guedes {
17245c1a4c8fSJaganath Kanakkassery 	hci_dev_lock(hdev);
17255c1a4c8fSJaganath Kanakkassery 
17263baef810SJaganath Kanakkassery 	switch (enable) {
17273fd319b8SAndre Guedes 	case LE_SCAN_ENABLE:
1728a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_LE_SCAN);
1729b9a6328fSJohan Hedberg 		if (hdev->le_scan_type == LE_SCAN_ACTIVE)
1730b9a6328fSJohan Hedberg 			clear_pending_adv_report(hdev);
1731b338d917SBrian Gix 		if (hci_dev_test_flag(hdev, HCI_MESH))
1732b338d917SBrian Gix 			hci_discovery_set_state(hdev, DISCOVERY_FINDING);
173368a8aea4SAndrei Emeltchenko 		break;
173468a8aea4SAndrei Emeltchenko 
173576a388beSAndre Guedes 	case LE_SCAN_DISABLE:
1736b9a6328fSJohan Hedberg 		/* We do this here instead of when setting DISCOVERY_STOPPED
1737b9a6328fSJohan Hedberg 		 * since the latter would potentially require waiting for
1738b9a6328fSJohan Hedberg 		 * inquiry to stop too.
1739b9a6328fSJohan Hedberg 		 */
1740b9a6328fSJohan Hedberg 		if (has_pending_adv_report(hdev)) {
1741b9a6328fSJohan Hedberg 			struct discovery_state *d = &hdev->discovery;
1742b9a6328fSJohan Hedberg 
1743b9a6328fSJohan Hedberg 			mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
1744ab0aa433SJohan Hedberg 					  d->last_adv_addr_type, NULL,
1745c70a7e4cSMarcel Holtmann 					  d->last_adv_rssi, d->last_adv_flags,
1746ab0aa433SJohan Hedberg 					  d->last_adv_data,
1747b338d917SBrian Gix 					  d->last_adv_data_len, NULL, 0, 0);
1748b9a6328fSJohan Hedberg 		}
1749b9a6328fSJohan Hedberg 
1750317ac8cbSJohan Hedberg 		/* Cancel this timer so that we don't try to disable scanning
1751317ac8cbSJohan Hedberg 		 * when it's already disabled.
1752317ac8cbSJohan Hedberg 		 */
1753317ac8cbSJohan Hedberg 		cancel_delayed_work(&hdev->le_scan_disable);
1754317ac8cbSJohan Hedberg 
1755a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LE_SCAN);
1756e8bb6b97SJohan Hedberg 
175781ad6fd9SJohan Hedberg 		/* The HCI_LE_SCAN_INTERRUPTED flag indicates that we
175881ad6fd9SJohan Hedberg 		 * interrupted scanning due to a connect request. Mark
1759abfeea47SLuiz Augusto von Dentz 		 * therefore discovery as stopped.
176081ad6fd9SJohan Hedberg 		 */
1761a69d8927SMarcel Holtmann 		if (hci_dev_test_and_clear_flag(hdev, HCI_LE_SCAN_INTERRUPTED))
176281ad6fd9SJohan Hedberg 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1763b338d917SBrian Gix 		else if (!hci_dev_test_flag(hdev, HCI_LE_ADV) &&
1764b338d917SBrian Gix 			 hdev->discovery.state == DISCOVERY_FINDING)
1765b338d917SBrian Gix 			queue_work(hdev->workqueue, &hdev->reenable_adv_work);
1766e8bb6b97SJohan Hedberg 
176768a8aea4SAndrei Emeltchenko 		break;
176868a8aea4SAndrei Emeltchenko 
176968a8aea4SAndrei Emeltchenko 	default:
17702064ee33SMarcel Holtmann 		bt_dev_err(hdev, "use of reserved LE_Scan_Enable param %d",
17713baef810SJaganath Kanakkassery 			   enable);
177268a8aea4SAndrei Emeltchenko 		break;
177335815085SAndre Guedes 	}
17745c1a4c8fSJaganath Kanakkassery 
17755c1a4c8fSJaganath Kanakkassery 	hci_dev_unlock(hdev);
1776eb9d91f5SAndre Guedes }
1777eb9d91f5SAndre Guedes 
hci_cc_le_set_scan_enable(struct hci_dev * hdev,void * data,struct sk_buff * skb)1778c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_scan_enable(struct hci_dev *hdev, void *data,
17793baef810SJaganath Kanakkassery 				    struct sk_buff *skb)
17803baef810SJaganath Kanakkassery {
17813baef810SJaganath Kanakkassery 	struct hci_cp_le_set_scan_enable *cp;
1782c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
17833baef810SJaganath Kanakkassery 
1784e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1785e3f3a1aeSLuiz Augusto von Dentz 
1786e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1787c8992cffSLuiz Augusto von Dentz 		return rp->status;
17883baef810SJaganath Kanakkassery 
17893baef810SJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
17903baef810SJaganath Kanakkassery 	if (!cp)
1791c8992cffSLuiz Augusto von Dentz 		return rp->status;
17923baef810SJaganath Kanakkassery 
17933baef810SJaganath Kanakkassery 	le_set_scan_enable_complete(hdev, cp->enable);
1794c8992cffSLuiz Augusto von Dentz 
1795c8992cffSLuiz Augusto von Dentz 	return rp->status;
17963baef810SJaganath Kanakkassery }
17973baef810SJaganath Kanakkassery 
hci_cc_le_set_ext_scan_enable(struct hci_dev * hdev,void * data,struct sk_buff * skb)1798c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_ext_scan_enable(struct hci_dev *hdev, void *data,
1799a2344b9eSJaganath Kanakkassery 					struct sk_buff *skb)
1800a2344b9eSJaganath Kanakkassery {
1801a2344b9eSJaganath Kanakkassery 	struct hci_cp_le_set_ext_scan_enable *cp;
1802c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1803a2344b9eSJaganath Kanakkassery 
1804e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1805e3f3a1aeSLuiz Augusto von Dentz 
1806e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1807c8992cffSLuiz Augusto von Dentz 		return rp->status;
1808a2344b9eSJaganath Kanakkassery 
1809a2344b9eSJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_SCAN_ENABLE);
1810a2344b9eSJaganath Kanakkassery 	if (!cp)
1811c8992cffSLuiz Augusto von Dentz 		return rp->status;
1812a2344b9eSJaganath Kanakkassery 
1813a2344b9eSJaganath Kanakkassery 	le_set_scan_enable_complete(hdev, cp->enable);
1814c8992cffSLuiz Augusto von Dentz 
1815c8992cffSLuiz Augusto von Dentz 	return rp->status;
1816a2344b9eSJaganath Kanakkassery }
1817a2344b9eSJaganath Kanakkassery 
hci_cc_le_read_num_adv_sets(struct hci_dev * hdev,void * data,struct sk_buff * skb)1818c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_num_adv_sets(struct hci_dev *hdev, void *data,
18196b49bcb4SJaganath Kanakkassery 				      struct sk_buff *skb)
18206b49bcb4SJaganath Kanakkassery {
1821c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_num_supported_adv_sets *rp = data;
1822e3f3a1aeSLuiz Augusto von Dentz 
1823e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x No of Adv sets %u", rp->status,
18246b49bcb4SJaganath Kanakkassery 		   rp->num_of_sets);
18256b49bcb4SJaganath Kanakkassery 
18266b49bcb4SJaganath Kanakkassery 	if (rp->status)
1827c8992cffSLuiz Augusto von Dentz 		return rp->status;
18286b49bcb4SJaganath Kanakkassery 
18296b49bcb4SJaganath Kanakkassery 	hdev->le_num_of_adv_sets = rp->num_of_sets;
1830c8992cffSLuiz Augusto von Dentz 
1831c8992cffSLuiz Augusto von Dentz 	return rp->status;
18326b49bcb4SJaganath Kanakkassery }
18336b49bcb4SJaganath Kanakkassery 
hci_cc_le_read_accept_list_size(struct hci_dev * hdev,void * data,struct sk_buff * skb)1834c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_accept_list_size(struct hci_dev *hdev, void *data,
1835cf1d081fSJohan Hedberg 					  struct sk_buff *skb)
1836cf1d081fSJohan Hedberg {
1837c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_accept_list_size *rp = data;
1838e3f3a1aeSLuiz Augusto von Dentz 
1839e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x size %u", rp->status, rp->size);
1840cf1d081fSJohan Hedberg 
184145296acdSMarcel Holtmann 	if (rp->status)
1842c8992cffSLuiz Augusto von Dentz 		return rp->status;
184345296acdSMarcel Holtmann 
18443d4f9c00SArchie Pusaka 	hdev->le_accept_list_size = rp->size;
1845c8992cffSLuiz Augusto von Dentz 
1846c8992cffSLuiz Augusto von Dentz 	return rp->status;
1847cf1d081fSJohan Hedberg }
1848cf1d081fSJohan Hedberg 
hci_cc_le_clear_accept_list(struct hci_dev * hdev,void * data,struct sk_buff * skb)1849c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_clear_accept_list(struct hci_dev *hdev, void *data,
18500f36b589SMarcel Holtmann 				      struct sk_buff *skb)
18510f36b589SMarcel Holtmann {
1852c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
18530f36b589SMarcel Holtmann 
1854e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1855e3f3a1aeSLuiz Augusto von Dentz 
1856e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1857c8992cffSLuiz Augusto von Dentz 		return rp->status;
185845296acdSMarcel Holtmann 
18595e2b6064SNiels Dossche 	hci_dev_lock(hdev);
18603d4f9c00SArchie Pusaka 	hci_bdaddr_list_clear(&hdev->le_accept_list);
18615e2b6064SNiels Dossche 	hci_dev_unlock(hdev);
1862c8992cffSLuiz Augusto von Dentz 
1863c8992cffSLuiz Augusto von Dentz 	return rp->status;
18640f36b589SMarcel Holtmann }
18650f36b589SMarcel Holtmann 
hci_cc_le_add_to_accept_list(struct hci_dev * hdev,void * data,struct sk_buff * skb)1866c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_add_to_accept_list(struct hci_dev *hdev, void *data,
18670f36b589SMarcel Holtmann 				       struct sk_buff *skb)
18680f36b589SMarcel Holtmann {
18693d4f9c00SArchie Pusaka 	struct hci_cp_le_add_to_accept_list *sent;
1870c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
18710f36b589SMarcel Holtmann 
1872e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1873e3f3a1aeSLuiz Augusto von Dentz 
1874e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1875c8992cffSLuiz Augusto von Dentz 		return rp->status;
187645296acdSMarcel Holtmann 
18773d4f9c00SArchie Pusaka 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_ACCEPT_LIST);
18780f36b589SMarcel Holtmann 	if (!sent)
1879c8992cffSLuiz Augusto von Dentz 		return rp->status;
18800f36b589SMarcel Holtmann 
18815e2b6064SNiels Dossche 	hci_dev_lock(hdev);
18823d4f9c00SArchie Pusaka 	hci_bdaddr_list_add(&hdev->le_accept_list, &sent->bdaddr,
1883dcc36c16SJohan Hedberg 			    sent->bdaddr_type);
18845e2b6064SNiels Dossche 	hci_dev_unlock(hdev);
1885c8992cffSLuiz Augusto von Dentz 
1886c8992cffSLuiz Augusto von Dentz 	return rp->status;
18870f36b589SMarcel Holtmann }
18880f36b589SMarcel Holtmann 
hci_cc_le_del_from_accept_list(struct hci_dev * hdev,void * data,struct sk_buff * skb)1889c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_del_from_accept_list(struct hci_dev *hdev, void *data,
18900f36b589SMarcel Holtmann 					 struct sk_buff *skb)
18910f36b589SMarcel Holtmann {
18923d4f9c00SArchie Pusaka 	struct hci_cp_le_del_from_accept_list *sent;
1893c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
18940f36b589SMarcel Holtmann 
1895e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1896e3f3a1aeSLuiz Augusto von Dentz 
1897e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1898c8992cffSLuiz Augusto von Dentz 		return rp->status;
189945296acdSMarcel Holtmann 
19003d4f9c00SArchie Pusaka 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_ACCEPT_LIST);
19010f36b589SMarcel Holtmann 	if (!sent)
1902c8992cffSLuiz Augusto von Dentz 		return rp->status;
19030f36b589SMarcel Holtmann 
19045e2b6064SNiels Dossche 	hci_dev_lock(hdev);
19053d4f9c00SArchie Pusaka 	hci_bdaddr_list_del(&hdev->le_accept_list, &sent->bdaddr,
1906dcc36c16SJohan Hedberg 			    sent->bdaddr_type);
19075e2b6064SNiels Dossche 	hci_dev_unlock(hdev);
1908c8992cffSLuiz Augusto von Dentz 
1909c8992cffSLuiz Augusto von Dentz 	return rp->status;
19100f36b589SMarcel Holtmann }
19110f36b589SMarcel Holtmann 
hci_cc_le_read_supported_states(struct hci_dev * hdev,void * data,struct sk_buff * skb)1912c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_supported_states(struct hci_dev *hdev, void *data,
19139b008c04SJohan Hedberg 					  struct sk_buff *skb)
19149b008c04SJohan Hedberg {
1915c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_supported_states *rp = data;
1916e3f3a1aeSLuiz Augusto von Dentz 
1917e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
19189b008c04SJohan Hedberg 
191945296acdSMarcel Holtmann 	if (rp->status)
1920c8992cffSLuiz Augusto von Dentz 		return rp->status;
192145296acdSMarcel Holtmann 
19229b008c04SJohan Hedberg 	memcpy(hdev->le_states, rp->le_states, 8);
1923c8992cffSLuiz Augusto von Dentz 
1924c8992cffSLuiz Augusto von Dentz 	return rp->status;
19259b008c04SJohan Hedberg }
19269b008c04SJohan Hedberg 
hci_cc_le_read_def_data_len(struct hci_dev * hdev,void * data,struct sk_buff * skb)1927c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_def_data_len(struct hci_dev *hdev, void *data,
1928a8e1bfaaSMarcel Holtmann 				      struct sk_buff *skb)
1929a8e1bfaaSMarcel Holtmann {
1930c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_def_data_len *rp = data;
1931e3f3a1aeSLuiz Augusto von Dentz 
1932e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1933a8e1bfaaSMarcel Holtmann 
1934a8e1bfaaSMarcel Holtmann 	if (rp->status)
1935c8992cffSLuiz Augusto von Dentz 		return rp->status;
1936a8e1bfaaSMarcel Holtmann 
1937a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_len = le16_to_cpu(rp->tx_len);
1938a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_time = le16_to_cpu(rp->tx_time);
1939c8992cffSLuiz Augusto von Dentz 
1940c8992cffSLuiz Augusto von Dentz 	return rp->status;
1941a8e1bfaaSMarcel Holtmann }
1942a8e1bfaaSMarcel Holtmann 
hci_cc_le_write_def_data_len(struct hci_dev * hdev,void * data,struct sk_buff * skb)1943c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_write_def_data_len(struct hci_dev *hdev, void *data,
1944a8e1bfaaSMarcel Holtmann 				       struct sk_buff *skb)
1945a8e1bfaaSMarcel Holtmann {
1946a8e1bfaaSMarcel Holtmann 	struct hci_cp_le_write_def_data_len *sent;
1947c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1948a8e1bfaaSMarcel Holtmann 
1949e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1950e3f3a1aeSLuiz Augusto von Dentz 
1951e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1952c8992cffSLuiz Augusto von Dentz 		return rp->status;
1953a8e1bfaaSMarcel Holtmann 
1954a8e1bfaaSMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_WRITE_DEF_DATA_LEN);
1955a8e1bfaaSMarcel Holtmann 	if (!sent)
1956c8992cffSLuiz Augusto von Dentz 		return rp->status;
1957a8e1bfaaSMarcel Holtmann 
1958a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_len = le16_to_cpu(sent->tx_len);
1959a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_time = le16_to_cpu(sent->tx_time);
1960c8992cffSLuiz Augusto von Dentz 
1961c8992cffSLuiz Augusto von Dentz 	return rp->status;
1962a8e1bfaaSMarcel Holtmann }
1963a8e1bfaaSMarcel Holtmann 
hci_cc_le_add_to_resolv_list(struct hci_dev * hdev,void * data,struct sk_buff * skb)1964c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_add_to_resolv_list(struct hci_dev *hdev, void *data,
1965b950aa88SAnkit Navik 				       struct sk_buff *skb)
1966b950aa88SAnkit Navik {
1967b950aa88SAnkit Navik 	struct hci_cp_le_add_to_resolv_list *sent;
1968c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1969b950aa88SAnkit Navik 
1970e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1971e3f3a1aeSLuiz Augusto von Dentz 
1972e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1973c8992cffSLuiz Augusto von Dentz 		return rp->status;
1974b950aa88SAnkit Navik 
1975b950aa88SAnkit Navik 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_RESOLV_LIST);
1976b950aa88SAnkit Navik 	if (!sent)
1977c8992cffSLuiz Augusto von Dentz 		return rp->status;
1978b950aa88SAnkit Navik 
19795e2b6064SNiels Dossche 	hci_dev_lock(hdev);
1980b950aa88SAnkit Navik 	hci_bdaddr_list_add_with_irk(&hdev->le_resolv_list, &sent->bdaddr,
1981b950aa88SAnkit Navik 				sent->bdaddr_type, sent->peer_irk,
1982b950aa88SAnkit Navik 				sent->local_irk);
19835e2b6064SNiels Dossche 	hci_dev_unlock(hdev);
1984c8992cffSLuiz Augusto von Dentz 
1985c8992cffSLuiz Augusto von Dentz 	return rp->status;
1986b950aa88SAnkit Navik }
1987b950aa88SAnkit Navik 
hci_cc_le_del_from_resolv_list(struct hci_dev * hdev,void * data,struct sk_buff * skb)1988c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_del_from_resolv_list(struct hci_dev *hdev, void *data,
1989b950aa88SAnkit Navik 					 struct sk_buff *skb)
1990b950aa88SAnkit Navik {
1991b950aa88SAnkit Navik 	struct hci_cp_le_del_from_resolv_list *sent;
1992c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
1993b950aa88SAnkit Navik 
1994e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
1995e3f3a1aeSLuiz Augusto von Dentz 
1996e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
1997c8992cffSLuiz Augusto von Dentz 		return rp->status;
1998b950aa88SAnkit Navik 
1999b950aa88SAnkit Navik 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_RESOLV_LIST);
2000b950aa88SAnkit Navik 	if (!sent)
2001c8992cffSLuiz Augusto von Dentz 		return rp->status;
2002b950aa88SAnkit Navik 
20035e2b6064SNiels Dossche 	hci_dev_lock(hdev);
2004b950aa88SAnkit Navik 	hci_bdaddr_list_del_with_irk(&hdev->le_resolv_list, &sent->bdaddr,
2005b950aa88SAnkit Navik 			    sent->bdaddr_type);
20065e2b6064SNiels Dossche 	hci_dev_unlock(hdev);
2007c8992cffSLuiz Augusto von Dentz 
2008c8992cffSLuiz Augusto von Dentz 	return rp->status;
2009b950aa88SAnkit Navik }
2010b950aa88SAnkit Navik 
hci_cc_le_clear_resolv_list(struct hci_dev * hdev,void * data,struct sk_buff * skb)2011c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_clear_resolv_list(struct hci_dev *hdev, void *data,
2012545f2596SAnkit Navik 				      struct sk_buff *skb)
2013545f2596SAnkit Navik {
2014c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
2015545f2596SAnkit 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;
2020545f2596SAnkit Navik 
20215e2b6064SNiels Dossche 	hci_dev_lock(hdev);
2022545f2596SAnkit Navik 	hci_bdaddr_list_clear(&hdev->le_resolv_list);
20235e2b6064SNiels Dossche 	hci_dev_unlock(hdev);
2024c8992cffSLuiz Augusto von Dentz 
2025c8992cffSLuiz Augusto von Dentz 	return rp->status;
2026545f2596SAnkit Navik }
2027545f2596SAnkit Navik 
hci_cc_le_read_resolv_list_size(struct hci_dev * hdev,void * data,struct sk_buff * skb)2028c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_resolv_list_size(struct hci_dev *hdev, void *data,
2029cfdb0c2dSAnkit Navik 					  struct sk_buff *skb)
2030cfdb0c2dSAnkit Navik {
2031c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_resolv_list_size *rp = data;
2032e3f3a1aeSLuiz Augusto von Dentz 
2033e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x size %u", rp->status, rp->size);
2034cfdb0c2dSAnkit Navik 
2035cfdb0c2dSAnkit Navik 	if (rp->status)
2036c8992cffSLuiz Augusto von Dentz 		return rp->status;
2037cfdb0c2dSAnkit Navik 
2038cfdb0c2dSAnkit Navik 	hdev->le_resolv_list_size = rp->size;
2039c8992cffSLuiz Augusto von Dentz 
2040c8992cffSLuiz Augusto von Dentz 	return rp->status;
2041cfdb0c2dSAnkit Navik }
2042cfdb0c2dSAnkit Navik 
hci_cc_le_set_addr_resolution_enable(struct hci_dev * hdev,void * data,struct sk_buff * skb)2043c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_set_addr_resolution_enable(struct hci_dev *hdev, void *data,
2044aa12af77SAnkit Navik 					       struct sk_buff *skb)
2045aa12af77SAnkit Navik {
2046c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
2047e3f3a1aeSLuiz Augusto von Dentz 	__u8 *sent;
2048aa12af77SAnkit Navik 
2049e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2050e3f3a1aeSLuiz Augusto von Dentz 
2051e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
2052c8992cffSLuiz Augusto von Dentz 		return rp->status;
2053aa12af77SAnkit Navik 
2054aa12af77SAnkit Navik 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADDR_RESOLV_ENABLE);
2055aa12af77SAnkit Navik 	if (!sent)
2056c8992cffSLuiz Augusto von Dentz 		return rp->status;
2057aa12af77SAnkit Navik 
2058aa12af77SAnkit Navik 	hci_dev_lock(hdev);
2059aa12af77SAnkit Navik 
2060aa12af77SAnkit Navik 	if (*sent)
2061aa12af77SAnkit Navik 		hci_dev_set_flag(hdev, HCI_LL_RPA_RESOLUTION);
2062aa12af77SAnkit Navik 	else
2063aa12af77SAnkit Navik 		hci_dev_clear_flag(hdev, HCI_LL_RPA_RESOLUTION);
2064aa12af77SAnkit Navik 
2065aa12af77SAnkit Navik 	hci_dev_unlock(hdev);
2066c8992cffSLuiz Augusto von Dentz 
2067c8992cffSLuiz Augusto von Dentz 	return rp->status;
2068aa12af77SAnkit Navik }
2069aa12af77SAnkit Navik 
hci_cc_le_read_max_data_len(struct hci_dev * hdev,void * data,struct sk_buff * skb)2070c8992cffSLuiz Augusto von Dentz static u8 hci_cc_le_read_max_data_len(struct hci_dev *hdev, void *data,
2071a8e1bfaaSMarcel Holtmann 				      struct sk_buff *skb)
2072a8e1bfaaSMarcel Holtmann {
2073c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_read_max_data_len *rp = data;
2074e3f3a1aeSLuiz Augusto von Dentz 
2075e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2076a8e1bfaaSMarcel Holtmann 
2077a8e1bfaaSMarcel Holtmann 	if (rp->status)
2078c8992cffSLuiz Augusto von Dentz 		return rp->status;
2079a8e1bfaaSMarcel Holtmann 
2080a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_len = le16_to_cpu(rp->tx_len);
2081a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_time = le16_to_cpu(rp->tx_time);
2082a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_len = le16_to_cpu(rp->rx_len);
2083a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_time = le16_to_cpu(rp->rx_time);
2084c8992cffSLuiz Augusto von Dentz 
2085c8992cffSLuiz Augusto von Dentz 	return rp->status;
2086a8e1bfaaSMarcel Holtmann }
2087a8e1bfaaSMarcel Holtmann 
hci_cc_write_le_host_supported(struct hci_dev * hdev,void * data,struct sk_buff * skb)2088c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_le_host_supported(struct hci_dev *hdev, void *data,
2089f9b49306SAndre Guedes 					 struct sk_buff *skb)
2090f9b49306SAndre Guedes {
209106199cf8SJohan Hedberg 	struct hci_cp_write_le_host_supported *sent;
2092c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
2093f9b49306SAndre Guedes 
2094e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2095e3f3a1aeSLuiz Augusto von Dentz 
2096e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
2097c8992cffSLuiz Augusto von Dentz 		return rp->status;
209845296acdSMarcel Holtmann 
209906199cf8SJohan Hedberg 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
21008f984dfaSJohan Hedberg 	if (!sent)
2101c8992cffSLuiz Augusto von Dentz 		return rp->status;
2102f9b49306SAndre Guedes 
21035c1a4c8fSJaganath Kanakkassery 	hci_dev_lock(hdev);
21045c1a4c8fSJaganath Kanakkassery 
2105416a4ae5SJohan Hedberg 	if (sent->le) {
2106cad718edSJohan Hedberg 		hdev->features[1][0] |= LMP_HOST_LE;
2107a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_LE_ENABLED);
2108416a4ae5SJohan Hedberg 	} else {
2109cad718edSJohan Hedberg 		hdev->features[1][0] &= ~LMP_HOST_LE;
2110a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LE_ENABLED);
2111a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_ADVERTISING);
2112416a4ae5SJohan Hedberg 	}
211353b2caabSJohan Hedberg 
211453b2caabSJohan Hedberg 	if (sent->simul)
2115cad718edSJohan Hedberg 		hdev->features[1][0] |= LMP_HOST_LE_BREDR;
211653b2caabSJohan Hedberg 	else
2117cad718edSJohan Hedberg 		hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
21185c1a4c8fSJaganath Kanakkassery 
21195c1a4c8fSJaganath Kanakkassery 	hci_dev_unlock(hdev);
2120c8992cffSLuiz Augusto von Dentz 
2121c8992cffSLuiz Augusto von Dentz 	return rp->status;
21228f984dfaSJohan Hedberg }
2123f9b49306SAndre Guedes 
hci_cc_set_adv_param(struct hci_dev * hdev,void * data,struct sk_buff * skb)2124c8992cffSLuiz Augusto von Dentz static u8 hci_cc_set_adv_param(struct hci_dev *hdev, void *data,
2125c8992cffSLuiz Augusto von Dentz 			       struct sk_buff *skb)
212656ed2cb8SJohan Hedberg {
212756ed2cb8SJohan Hedberg 	struct hci_cp_le_set_adv_param *cp;
2128c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
212956ed2cb8SJohan Hedberg 
2130e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2131e3f3a1aeSLuiz Augusto von Dentz 
2132e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
2133c8992cffSLuiz Augusto von Dentz 		return rp->status;
213456ed2cb8SJohan Hedberg 
213556ed2cb8SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_PARAM);
213656ed2cb8SJohan Hedberg 	if (!cp)
2137c8992cffSLuiz Augusto von Dentz 		return rp->status;
213856ed2cb8SJohan Hedberg 
213956ed2cb8SJohan Hedberg 	hci_dev_lock(hdev);
214056ed2cb8SJohan Hedberg 	hdev->adv_addr_type = cp->own_address_type;
214156ed2cb8SJohan Hedberg 	hci_dev_unlock(hdev);
2142c8992cffSLuiz Augusto von Dentz 
2143c8992cffSLuiz Augusto von Dentz 	return rp->status;
214456ed2cb8SJohan Hedberg }
214556ed2cb8SJohan Hedberg 
hci_cc_set_ext_adv_param(struct hci_dev * hdev,void * data,struct sk_buff * skb)2146c8992cffSLuiz Augusto von Dentz static u8 hci_cc_set_ext_adv_param(struct hci_dev *hdev, void *data,
2147c8992cffSLuiz Augusto von Dentz 				   struct sk_buff *skb)
2148de181e88SJaganath Kanakkassery {
2149c8992cffSLuiz Augusto von Dentz 	struct hci_rp_le_set_ext_adv_params *rp = data;
2150de181e88SJaganath Kanakkassery 	struct hci_cp_le_set_ext_adv_params *cp;
2151de181e88SJaganath Kanakkassery 	struct adv_info *adv_instance;
2152de181e88SJaganath Kanakkassery 
2153e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2154de181e88SJaganath Kanakkassery 
2155de181e88SJaganath Kanakkassery 	if (rp->status)
2156c8992cffSLuiz Augusto von Dentz 		return rp->status;
2157de181e88SJaganath Kanakkassery 
2158de181e88SJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_ADV_PARAMS);
2159de181e88SJaganath Kanakkassery 	if (!cp)
2160c8992cffSLuiz Augusto von Dentz 		return rp->status;
2161de181e88SJaganath Kanakkassery 
2162de181e88SJaganath Kanakkassery 	hci_dev_lock(hdev);
2163de181e88SJaganath Kanakkassery 	hdev->adv_addr_type = cp->own_addr_type;
216425e70886SDaniel Winkler 	if (!cp->handle) {
2165de181e88SJaganath Kanakkassery 		/* Store in hdev for instance 0 */
2166de181e88SJaganath Kanakkassery 		hdev->adv_tx_power = rp->tx_power;
2167de181e88SJaganath Kanakkassery 	} else {
216825e70886SDaniel Winkler 		adv_instance = hci_find_adv_instance(hdev, cp->handle);
2169de181e88SJaganath Kanakkassery 		if (adv_instance)
2170de181e88SJaganath Kanakkassery 			adv_instance->tx_power = rp->tx_power;
2171de181e88SJaganath Kanakkassery 	}
2172a0fb3726SJaganath Kanakkassery 	/* Update adv data as tx power is known now */
2173651cd3d6SBrian Gix 	hci_update_adv_data(hdev, cp->handle);
217412410572SDaniel Winkler 
2175de181e88SJaganath Kanakkassery 	hci_dev_unlock(hdev);
2176c8992cffSLuiz Augusto von Dentz 
2177c8992cffSLuiz Augusto von Dentz 	return rp->status;
2178de181e88SJaganath Kanakkassery }
2179de181e88SJaganath Kanakkassery 
hci_cc_read_rssi(struct hci_dev * hdev,void * data,struct sk_buff * skb)2180c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_rssi(struct hci_dev *hdev, void *data,
2181c8992cffSLuiz Augusto von Dentz 			   struct sk_buff *skb)
21825ae76a94SAndrzej Kaczmarek {
2183c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_rssi *rp = data;
21845ae76a94SAndrzej Kaczmarek 	struct hci_conn *conn;
21855ae76a94SAndrzej Kaczmarek 
2186e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
21875ae76a94SAndrzej Kaczmarek 
21885ae76a94SAndrzej Kaczmarek 	if (rp->status)
2189c8992cffSLuiz Augusto von Dentz 		return rp->status;
21905ae76a94SAndrzej Kaczmarek 
21915ae76a94SAndrzej Kaczmarek 	hci_dev_lock(hdev);
21925ae76a94SAndrzej Kaczmarek 
21935ae76a94SAndrzej Kaczmarek 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
21945ae76a94SAndrzej Kaczmarek 	if (conn)
21955ae76a94SAndrzej Kaczmarek 		conn->rssi = rp->rssi;
21965ae76a94SAndrzej Kaczmarek 
21975ae76a94SAndrzej Kaczmarek 	hci_dev_unlock(hdev);
2198c8992cffSLuiz Augusto von Dentz 
2199c8992cffSLuiz Augusto von Dentz 	return rp->status;
22005ae76a94SAndrzej Kaczmarek }
22015ae76a94SAndrzej Kaczmarek 
hci_cc_read_tx_power(struct hci_dev * hdev,void * data,struct sk_buff * skb)2202c8992cffSLuiz Augusto von Dentz static u8 hci_cc_read_tx_power(struct hci_dev *hdev, void *data,
2203c8992cffSLuiz Augusto von Dentz 			       struct sk_buff *skb)
22045a134faeSAndrzej Kaczmarek {
22055a134faeSAndrzej Kaczmarek 	struct hci_cp_read_tx_power *sent;
2206c8992cffSLuiz Augusto von Dentz 	struct hci_rp_read_tx_power *rp = data;
22075a134faeSAndrzej Kaczmarek 	struct hci_conn *conn;
22085a134faeSAndrzej Kaczmarek 
2209e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
22105a134faeSAndrzej Kaczmarek 
22115a134faeSAndrzej Kaczmarek 	if (rp->status)
2212c8992cffSLuiz Augusto von Dentz 		return rp->status;
22135a134faeSAndrzej Kaczmarek 
22145a134faeSAndrzej Kaczmarek 	sent = hci_sent_cmd_data(hdev, HCI_OP_READ_TX_POWER);
22155a134faeSAndrzej Kaczmarek 	if (!sent)
2216c8992cffSLuiz Augusto von Dentz 		return rp->status;
22175a134faeSAndrzej Kaczmarek 
22185a134faeSAndrzej Kaczmarek 	hci_dev_lock(hdev);
22195a134faeSAndrzej Kaczmarek 
22205a134faeSAndrzej Kaczmarek 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
2221d0455ed9SAndrzej Kaczmarek 	if (!conn)
2222d0455ed9SAndrzej Kaczmarek 		goto unlock;
22235a134faeSAndrzej Kaczmarek 
2224d0455ed9SAndrzej Kaczmarek 	switch (sent->type) {
2225d0455ed9SAndrzej Kaczmarek 	case 0x00:
2226d0455ed9SAndrzej Kaczmarek 		conn->tx_power = rp->tx_power;
2227d0455ed9SAndrzej Kaczmarek 		break;
2228d0455ed9SAndrzej Kaczmarek 	case 0x01:
2229d0455ed9SAndrzej Kaczmarek 		conn->max_tx_power = rp->tx_power;
2230d0455ed9SAndrzej Kaczmarek 		break;
2231d0455ed9SAndrzej Kaczmarek 	}
2232d0455ed9SAndrzej Kaczmarek 
2233d0455ed9SAndrzej Kaczmarek unlock:
22345a134faeSAndrzej Kaczmarek 	hci_dev_unlock(hdev);
2235c8992cffSLuiz Augusto von Dentz 	return rp->status;
22365a134faeSAndrzej Kaczmarek }
22375a134faeSAndrzej Kaczmarek 
hci_cc_write_ssp_debug_mode(struct hci_dev * hdev,void * data,struct sk_buff * skb)2238c8992cffSLuiz Augusto von Dentz static u8 hci_cc_write_ssp_debug_mode(struct hci_dev *hdev, void *data,
2239c8992cffSLuiz Augusto von Dentz 				      struct sk_buff *skb)
2240c50b33c8SMarcel Holtmann {
2241c8992cffSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
2242c50b33c8SMarcel Holtmann 	u8 *mode;
2243c50b33c8SMarcel Holtmann 
2244e3f3a1aeSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
2245e3f3a1aeSLuiz Augusto von Dentz 
2246e3f3a1aeSLuiz Augusto von Dentz 	if (rp->status)
2247c8992cffSLuiz Augusto von Dentz 		return rp->status;
2248c50b33c8SMarcel Holtmann 
2249c50b33c8SMarcel Holtmann 	mode = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE);
2250c50b33c8SMarcel Holtmann 	if (mode)
2251c50b33c8SMarcel Holtmann 		hdev->ssp_debug_mode = *mode;
2252c8992cffSLuiz Augusto von Dentz 
2253c8992cffSLuiz Augusto von Dentz 	return rp->status;
2254c50b33c8SMarcel Holtmann }
2255c50b33c8SMarcel Holtmann 
hci_cs_inquiry(struct hci_dev * hdev,__u8 status)22566039aa73SGustavo Padovan static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
2257a9de9248SMarcel Holtmann {
2258147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2259a9de9248SMarcel Holtmann 
2260a9de9248SMarcel Holtmann 	if (status) {
2261a9de9248SMarcel Holtmann 		hci_conn_check_pending(hdev);
2262314b2381SJohan Hedberg 		return;
2263314b2381SJohan Hedberg 	}
2264314b2381SJohan Hedberg 
226590d6a397SLuiz Augusto von Dentz 	if (hci_sent_cmd_data(hdev, HCI_OP_INQUIRY))
226689352e7dSAndre Guedes 		set_bit(HCI_INQUIRY, &hdev->flags);
2267a9de9248SMarcel Holtmann }
2268a9de9248SMarcel Holtmann 
hci_cs_create_conn(struct hci_dev * hdev,__u8 status)22696039aa73SGustavo Padovan static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
22701da177e4SLinus Torvalds {
2271a9de9248SMarcel Holtmann 	struct hci_cp_create_conn *cp;
22721da177e4SLinus Torvalds 	struct hci_conn *conn;
22731da177e4SLinus Torvalds 
2274147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2275a9de9248SMarcel Holtmann 
2276a9de9248SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
22771da177e4SLinus Torvalds 	if (!cp)
22781da177e4SLinus Torvalds 		return;
22791da177e4SLinus Torvalds 
22801da177e4SLinus Torvalds 	hci_dev_lock(hdev);
22811da177e4SLinus Torvalds 
22821da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
22831da177e4SLinus Torvalds 
2284147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "bdaddr %pMR hcon %p", &cp->bdaddr, conn);
22851da177e4SLinus Torvalds 
22861da177e4SLinus Torvalds 	if (status) {
22871da177e4SLinus Torvalds 		if (conn && conn->state == BT_CONNECT) {
22884c67bc74SMarcel Holtmann 			if (status != 0x0c || conn->attempt > 2) {
22891da177e4SLinus Torvalds 				conn->state = BT_CLOSED;
2290539c496dSJohan Hedberg 				hci_connect_cfm(conn, status);
22911da177e4SLinus Torvalds 				hci_conn_del(conn);
22924c67bc74SMarcel Holtmann 			} else
22934c67bc74SMarcel Holtmann 				conn->state = BT_CONNECT2;
22941da177e4SLinus Torvalds 		}
22951da177e4SLinus Torvalds 	} else {
22961da177e4SLinus Torvalds 		if (!conn) {
229784cb0143SZiyang Xuan 			conn = hci_conn_add_unset(hdev, ACL_LINK, &cp->bdaddr,
2298a5c4e309SJohan Hedberg 						  HCI_ROLE_MASTER);
2299ad3f7986SSungwoo Kim 			if (IS_ERR(conn))
2300ad3f7986SSungwoo Kim 				bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn));
23011da177e4SLinus Torvalds 		}
23021da177e4SLinus Torvalds 	}
23031da177e4SLinus Torvalds 
23041da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
23051da177e4SLinus Torvalds }
23061da177e4SLinus Torvalds 
hci_cs_add_sco(struct hci_dev * hdev,__u8 status)2307a9de9248SMarcel Holtmann static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
23081da177e4SLinus Torvalds {
2309a9de9248SMarcel Holtmann 	struct hci_cp_add_sco *cp;
231006149746SLuiz Augusto von Dentz 	struct hci_conn *acl;
231106149746SLuiz Augusto von Dentz 	struct hci_link *link;
23121da177e4SLinus Torvalds 	__u16 handle;
23131da177e4SLinus Torvalds 
2314147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2315b6a0dc82SMarcel Holtmann 
2316a9de9248SMarcel Holtmann 	if (!status)
2317a9de9248SMarcel Holtmann 		return;
2318a9de9248SMarcel Holtmann 
2319a9de9248SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
23201da177e4SLinus Torvalds 	if (!cp)
2321a9de9248SMarcel Holtmann 		return;
23221da177e4SLinus Torvalds 
23231da177e4SLinus Torvalds 	handle = __le16_to_cpu(cp->handle);
23241da177e4SLinus Torvalds 
2325147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "handle 0x%4.4x", handle);
23261da177e4SLinus Torvalds 
23271da177e4SLinus Torvalds 	hci_dev_lock(hdev);
23281da177e4SLinus Torvalds 
23291da177e4SLinus Torvalds 	acl = hci_conn_hash_lookup_handle(hdev, handle);
23305a08ecceSAndrei Emeltchenko 	if (acl) {
233106149746SLuiz Augusto von Dentz 		link = list_first_entry_or_null(&acl->link_list,
233206149746SLuiz Augusto von Dentz 						struct hci_link, list);
233306149746SLuiz Augusto von Dentz 		if (link && link->conn) {
233406149746SLuiz Augusto von Dentz 			link->conn->state = BT_CLOSED;
23351da177e4SLinus Torvalds 
233606149746SLuiz Augusto von Dentz 			hci_connect_cfm(link->conn, status);
233706149746SLuiz Augusto von Dentz 			hci_conn_del(link->conn);
23381da177e4SLinus Torvalds 		}
23395a08ecceSAndrei Emeltchenko 	}
23401da177e4SLinus Torvalds 
23411da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
23421da177e4SLinus Torvalds }
23431da177e4SLinus Torvalds 
hci_cs_auth_requested(struct hci_dev * hdev,__u8 status)2344f8558555SMarcel Holtmann static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
2345f8558555SMarcel Holtmann {
2346f8558555SMarcel Holtmann 	struct hci_cp_auth_requested *cp;
2347f8558555SMarcel Holtmann 	struct hci_conn *conn;
2348f8558555SMarcel Holtmann 
2349147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2350f8558555SMarcel Holtmann 
2351f8558555SMarcel Holtmann 	if (!status)
2352f8558555SMarcel Holtmann 		return;
2353f8558555SMarcel Holtmann 
2354f8558555SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
2355f8558555SMarcel Holtmann 	if (!cp)
2356f8558555SMarcel Holtmann 		return;
2357f8558555SMarcel Holtmann 
2358f8558555SMarcel Holtmann 	hci_dev_lock(hdev);
2359f8558555SMarcel Holtmann 
2360f8558555SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2361f8558555SMarcel Holtmann 	if (conn) {
2362f8558555SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
2363539c496dSJohan Hedberg 			hci_connect_cfm(conn, status);
236476a68ba0SDavid Herrmann 			hci_conn_drop(conn);
2365f8558555SMarcel Holtmann 		}
2366f8558555SMarcel Holtmann 	}
2367f8558555SMarcel Holtmann 
2368f8558555SMarcel Holtmann 	hci_dev_unlock(hdev);
2369f8558555SMarcel Holtmann }
2370f8558555SMarcel Holtmann 
hci_cs_set_conn_encrypt(struct hci_dev * hdev,__u8 status)2371f8558555SMarcel Holtmann static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
2372f8558555SMarcel Holtmann {
2373f8558555SMarcel Holtmann 	struct hci_cp_set_conn_encrypt *cp;
2374f8558555SMarcel Holtmann 	struct hci_conn *conn;
2375f8558555SMarcel Holtmann 
2376147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2377f8558555SMarcel Holtmann 
2378f8558555SMarcel Holtmann 	if (!status)
2379f8558555SMarcel Holtmann 		return;
2380f8558555SMarcel Holtmann 
2381f8558555SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
2382f8558555SMarcel Holtmann 	if (!cp)
2383f8558555SMarcel Holtmann 		return;
2384f8558555SMarcel Holtmann 
2385f8558555SMarcel Holtmann 	hci_dev_lock(hdev);
2386f8558555SMarcel Holtmann 
2387f8558555SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2388f8558555SMarcel Holtmann 	if (conn) {
2389f8558555SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
2390539c496dSJohan Hedberg 			hci_connect_cfm(conn, status);
239176a68ba0SDavid Herrmann 			hci_conn_drop(conn);
2392f8558555SMarcel Holtmann 		}
2393f8558555SMarcel Holtmann 	}
2394f8558555SMarcel Holtmann 
2395f8558555SMarcel Holtmann 	hci_dev_unlock(hdev);
2396f8558555SMarcel Holtmann }
2397f8558555SMarcel Holtmann 
hci_outgoing_auth_needed(struct hci_dev * hdev,struct hci_conn * conn)2398127178d2SJohan Hedberg static int hci_outgoing_auth_needed(struct hci_dev *hdev,
2399392599b9SJohan Hedberg 				    struct hci_conn *conn)
2400392599b9SJohan Hedberg {
2401392599b9SJohan Hedberg 	if (conn->state != BT_CONFIG || !conn->out)
2402392599b9SJohan Hedberg 		return 0;
2403392599b9SJohan Hedberg 
2404765c2a96SJohan Hedberg 	if (conn->pending_sec_level == BT_SECURITY_SDP)
2405392599b9SJohan Hedberg 		return 0;
2406392599b9SJohan Hedberg 
2407392599b9SJohan Hedberg 	/* Only request authentication for SSP connections or non-SSP
2408264b8b4eSJohan Hedberg 	 * devices with sec_level MEDIUM or HIGH or if MITM protection
2409264b8b4eSJohan Hedberg 	 * is requested.
2410264b8b4eSJohan Hedberg 	 */
2411807deac2SGustavo Padovan 	if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
24127e3691e1SJohan Hedberg 	    conn->pending_sec_level != BT_SECURITY_FIPS &&
2413264b8b4eSJohan Hedberg 	    conn->pending_sec_level != BT_SECURITY_HIGH &&
2414264b8b4eSJohan Hedberg 	    conn->pending_sec_level != BT_SECURITY_MEDIUM)
2415392599b9SJohan Hedberg 		return 0;
2416392599b9SJohan Hedberg 
2417392599b9SJohan Hedberg 	return 1;
2418392599b9SJohan Hedberg }
2419392599b9SJohan Hedberg 
hci_resolve_name(struct hci_dev * hdev,struct inquiry_entry * e)24206039aa73SGustavo Padovan static int hci_resolve_name(struct hci_dev *hdev,
242100abfe44SGustavo F. Padovan 				   struct inquiry_entry *e)
242230dc78e1SJohan Hedberg {
242330dc78e1SJohan Hedberg 	struct hci_cp_remote_name_req cp;
242430dc78e1SJohan Hedberg 
242530dc78e1SJohan Hedberg 	memset(&cp, 0, sizeof(cp));
242630dc78e1SJohan Hedberg 
242730dc78e1SJohan Hedberg 	bacpy(&cp.bdaddr, &e->data.bdaddr);
242830dc78e1SJohan Hedberg 	cp.pscan_rep_mode = e->data.pscan_rep_mode;
242930dc78e1SJohan Hedberg 	cp.pscan_mode = e->data.pscan_mode;
243030dc78e1SJohan Hedberg 	cp.clock_offset = e->data.clock_offset;
243130dc78e1SJohan Hedberg 
243230dc78e1SJohan Hedberg 	return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
243330dc78e1SJohan Hedberg }
243430dc78e1SJohan Hedberg 
hci_resolve_next_name(struct hci_dev * hdev)2435b644ba33SJohan Hedberg static bool hci_resolve_next_name(struct hci_dev *hdev)
243630dc78e1SJohan Hedberg {
243730dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
243830dc78e1SJohan Hedberg 	struct inquiry_entry *e;
243930dc78e1SJohan Hedberg 
2440b644ba33SJohan Hedberg 	if (list_empty(&discov->resolve))
2441b644ba33SJohan Hedberg 		return false;
2442b644ba33SJohan Hedberg 
2443dbf6811aSArchie Pusaka 	/* We should stop if we already spent too much time resolving names. */
2444dbf6811aSArchie Pusaka 	if (time_after(jiffies, discov->name_resolve_timeout)) {
2445dbf6811aSArchie Pusaka 		bt_dev_warn_ratelimited(hdev, "Name resolve takes too long.");
2446dbf6811aSArchie Pusaka 		return false;
2447dbf6811aSArchie Pusaka 	}
2448dbf6811aSArchie Pusaka 
2449b644ba33SJohan Hedberg 	e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
2450c810089cSRam Malovany 	if (!e)
2451c810089cSRam Malovany 		return false;
2452c810089cSRam Malovany 
2453b644ba33SJohan Hedberg 	if (hci_resolve_name(hdev, e) == 0) {
2454b644ba33SJohan Hedberg 		e->name_state = NAME_PENDING;
2455b644ba33SJohan Hedberg 		return true;
2456b644ba33SJohan Hedberg 	}
2457b644ba33SJohan Hedberg 
2458b644ba33SJohan Hedberg 	return false;
2459b644ba33SJohan Hedberg }
2460b644ba33SJohan Hedberg 
hci_check_pending_name(struct hci_dev * hdev,struct hci_conn * conn,bdaddr_t * bdaddr,u8 * name,u8 name_len)2461b644ba33SJohan Hedberg static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
2462b644ba33SJohan Hedberg 				   bdaddr_t *bdaddr, u8 *name, u8 name_len)
2463b644ba33SJohan Hedberg {
2464b644ba33SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
2465b644ba33SJohan Hedberg 	struct inquiry_entry *e;
2466b644ba33SJohan Hedberg 
246760cb49d2SJohan Hedberg 	/* Update the mgmt connected state if necessary. Be careful with
246860cb49d2SJohan Hedberg 	 * conn objects that exist but are not (yet) connected however.
246960cb49d2SJohan Hedberg 	 * Only those in BT_CONFIG or BT_CONNECTED states can be
247060cb49d2SJohan Hedberg 	 * considered connected.
247160cb49d2SJohan Hedberg 	 */
24720b3df53cSLuiz Augusto von Dentz 	if (conn && (conn->state == BT_CONFIG || conn->state == BT_CONNECTED))
24731c6ed31bSYu Liu 		mgmt_device_connected(hdev, conn, name, name_len);
2474b644ba33SJohan Hedberg 
2475b644ba33SJohan Hedberg 	if (discov->state == DISCOVERY_STOPPED)
2476b644ba33SJohan Hedberg 		return;
2477b644ba33SJohan Hedberg 
247830dc78e1SJohan Hedberg 	if (discov->state == DISCOVERY_STOPPING)
247930dc78e1SJohan Hedberg 		goto discov_complete;
248030dc78e1SJohan Hedberg 
248130dc78e1SJohan Hedberg 	if (discov->state != DISCOVERY_RESOLVING)
248230dc78e1SJohan Hedberg 		return;
248330dc78e1SJohan Hedberg 
248430dc78e1SJohan Hedberg 	e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
24857cc8380eSRam Malovany 	/* If the device was not found in a list of found devices names of which
24867cc8380eSRam Malovany 	 * are pending. there is no need to continue resolving a next name as it
24877cc8380eSRam Malovany 	 * will be done upon receiving another Remote Name Request Complete
24887cc8380eSRam Malovany 	 * Event */
24897cc8380eSRam Malovany 	if (!e)
24907cc8380eSRam Malovany 		return;
24917cc8380eSRam Malovany 
249230dc78e1SJohan Hedberg 	list_del(&e->list);
2493ea13aed5SArchie Pusaka 
2494ea13aed5SArchie Pusaka 	e->name_state = name ? NAME_KNOWN : NAME_NOT_KNOWN;
2495ea13aed5SArchie Pusaka 	mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00, e->data.rssi,
2496ea13aed5SArchie Pusaka 			 name, name_len);
249730dc78e1SJohan Hedberg 
2498b644ba33SJohan Hedberg 	if (hci_resolve_next_name(hdev))
249930dc78e1SJohan Hedberg 		return;
250030dc78e1SJohan Hedberg 
250130dc78e1SJohan Hedberg discov_complete:
250230dc78e1SJohan Hedberg 	hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
250330dc78e1SJohan Hedberg }
250430dc78e1SJohan Hedberg 
hci_cs_remote_name_req(struct hci_dev * hdev,__u8 status)2505a9de9248SMarcel Holtmann static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
25061da177e4SLinus Torvalds {
2507127178d2SJohan Hedberg 	struct hci_cp_remote_name_req *cp;
2508127178d2SJohan Hedberg 	struct hci_conn *conn;
2509127178d2SJohan Hedberg 
2510147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2511127178d2SJohan Hedberg 
2512127178d2SJohan Hedberg 	/* If successful wait for the name req complete event before
2513127178d2SJohan Hedberg 	 * checking for the need to do authentication */
2514127178d2SJohan Hedberg 	if (!status)
2515127178d2SJohan Hedberg 		return;
2516127178d2SJohan Hedberg 
2517127178d2SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
2518127178d2SJohan Hedberg 	if (!cp)
2519127178d2SJohan Hedberg 		return;
2520127178d2SJohan Hedberg 
2521127178d2SJohan Hedberg 	hci_dev_lock(hdev);
2522127178d2SJohan Hedberg 
2523127178d2SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
2524b644ba33SJohan Hedberg 
2525d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
2526b644ba33SJohan Hedberg 		hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
2527b644ba33SJohan Hedberg 
252879c6c70cSJohan Hedberg 	if (!conn)
252979c6c70cSJohan Hedberg 		goto unlock;
253079c6c70cSJohan Hedberg 
253179c6c70cSJohan Hedberg 	if (!hci_outgoing_auth_needed(hdev, conn))
253279c6c70cSJohan Hedberg 		goto unlock;
253379c6c70cSJohan Hedberg 
253451a8efd7SJohan Hedberg 	if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
2535c1f23a2bSJohannes Berg 		struct hci_cp_auth_requested auth_cp;
2536c1f23a2bSJohannes Berg 
2537977f8fceSJohan Hedberg 		set_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags);
2538977f8fceSJohan Hedberg 
2539c1f23a2bSJohannes Berg 		auth_cp.handle = __cpu_to_le16(conn->handle);
2540c1f23a2bSJohannes Berg 		hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
2541c1f23a2bSJohannes Berg 			     sizeof(auth_cp), &auth_cp);
2542127178d2SJohan Hedberg 	}
2543127178d2SJohan Hedberg 
254479c6c70cSJohan Hedberg unlock:
2545127178d2SJohan Hedberg 	hci_dev_unlock(hdev);
2546a9de9248SMarcel Holtmann }
25471da177e4SLinus Torvalds 
hci_cs_read_remote_features(struct hci_dev * hdev,__u8 status)2548769be974SMarcel Holtmann static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
2549769be974SMarcel Holtmann {
2550769be974SMarcel Holtmann 	struct hci_cp_read_remote_features *cp;
2551769be974SMarcel Holtmann 	struct hci_conn *conn;
2552769be974SMarcel Holtmann 
2553147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2554769be974SMarcel Holtmann 
2555769be974SMarcel Holtmann 	if (!status)
2556769be974SMarcel Holtmann 		return;
2557769be974SMarcel Holtmann 
2558769be974SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
2559769be974SMarcel Holtmann 	if (!cp)
2560769be974SMarcel Holtmann 		return;
2561769be974SMarcel Holtmann 
2562769be974SMarcel Holtmann 	hci_dev_lock(hdev);
2563769be974SMarcel Holtmann 
2564769be974SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2565769be974SMarcel Holtmann 	if (conn) {
2566769be974SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
2567539c496dSJohan Hedberg 			hci_connect_cfm(conn, status);
256876a68ba0SDavid Herrmann 			hci_conn_drop(conn);
2569769be974SMarcel Holtmann 		}
2570769be974SMarcel Holtmann 	}
2571769be974SMarcel Holtmann 
2572769be974SMarcel Holtmann 	hci_dev_unlock(hdev);
2573769be974SMarcel Holtmann }
2574769be974SMarcel Holtmann 
hci_cs_read_remote_ext_features(struct hci_dev * hdev,__u8 status)2575769be974SMarcel Holtmann static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
2576769be974SMarcel Holtmann {
2577769be974SMarcel Holtmann 	struct hci_cp_read_remote_ext_features *cp;
2578769be974SMarcel Holtmann 	struct hci_conn *conn;
2579769be974SMarcel Holtmann 
2580147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2581769be974SMarcel Holtmann 
2582769be974SMarcel Holtmann 	if (!status)
2583769be974SMarcel Holtmann 		return;
2584769be974SMarcel Holtmann 
2585769be974SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
2586769be974SMarcel Holtmann 	if (!cp)
2587769be974SMarcel Holtmann 		return;
2588769be974SMarcel Holtmann 
2589769be974SMarcel Holtmann 	hci_dev_lock(hdev);
2590769be974SMarcel Holtmann 
2591769be974SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2592769be974SMarcel Holtmann 	if (conn) {
2593769be974SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
2594539c496dSJohan Hedberg 			hci_connect_cfm(conn, status);
259576a68ba0SDavid Herrmann 			hci_conn_drop(conn);
2596769be974SMarcel Holtmann 		}
2597769be974SMarcel Holtmann 	}
2598769be974SMarcel Holtmann 
2599769be974SMarcel Holtmann 	hci_dev_unlock(hdev);
2600769be974SMarcel Holtmann }
2601769be974SMarcel Holtmann 
hci_setup_sync_conn_status(struct hci_dev * hdev,__u16 handle,__u8 status)260206149746SLuiz Augusto von Dentz static void hci_setup_sync_conn_status(struct hci_dev *hdev, __u16 handle,
260306149746SLuiz Augusto von Dentz 				       __u8 status)
260406149746SLuiz Augusto von Dentz {
260506149746SLuiz Augusto von Dentz 	struct hci_conn *acl;
260606149746SLuiz Augusto von Dentz 	struct hci_link *link;
260706149746SLuiz Augusto von Dentz 
260806149746SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "handle 0x%4.4x status 0x%2.2x", handle, status);
260906149746SLuiz Augusto von Dentz 
261006149746SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
261106149746SLuiz Augusto von Dentz 
261206149746SLuiz Augusto von Dentz 	acl = hci_conn_hash_lookup_handle(hdev, handle);
261306149746SLuiz Augusto von Dentz 	if (acl) {
261406149746SLuiz Augusto von Dentz 		link = list_first_entry_or_null(&acl->link_list,
261506149746SLuiz Augusto von Dentz 						struct hci_link, list);
261606149746SLuiz Augusto von Dentz 		if (link && link->conn) {
261706149746SLuiz Augusto von Dentz 			link->conn->state = BT_CLOSED;
261806149746SLuiz Augusto von Dentz 
261906149746SLuiz Augusto von Dentz 			hci_connect_cfm(link->conn, status);
262006149746SLuiz Augusto von Dentz 			hci_conn_del(link->conn);
262106149746SLuiz Augusto von Dentz 		}
262206149746SLuiz Augusto von Dentz 	}
262306149746SLuiz Augusto von Dentz 
262406149746SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
262506149746SLuiz Augusto von Dentz }
262606149746SLuiz Augusto von Dentz 
hci_cs_setup_sync_conn(struct hci_dev * hdev,__u8 status)2627a9de9248SMarcel Holtmann static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
2628a9de9248SMarcel Holtmann {
2629b6a0dc82SMarcel Holtmann 	struct hci_cp_setup_sync_conn *cp;
2630b6a0dc82SMarcel Holtmann 
2631147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2632b6a0dc82SMarcel Holtmann 
2633b6a0dc82SMarcel Holtmann 	if (!status)
2634b6a0dc82SMarcel Holtmann 		return;
2635b6a0dc82SMarcel Holtmann 
2636b6a0dc82SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
2637b6a0dc82SMarcel Holtmann 	if (!cp)
2638b6a0dc82SMarcel Holtmann 		return;
2639b6a0dc82SMarcel Holtmann 
264006149746SLuiz Augusto von Dentz 	hci_setup_sync_conn_status(hdev, __le16_to_cpu(cp->handle), status);
2641a9de9248SMarcel Holtmann }
2642a9de9248SMarcel Holtmann 
hci_cs_enhanced_setup_sync_conn(struct hci_dev * hdev,__u8 status)2643b2af264aSKiran K static void hci_cs_enhanced_setup_sync_conn(struct hci_dev *hdev, __u8 status)
2644b2af264aSKiran K {
2645b2af264aSKiran K 	struct hci_cp_enhanced_setup_sync_conn *cp;
2646b2af264aSKiran K 
2647b2af264aSKiran K 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2648b2af264aSKiran K 
2649b2af264aSKiran K 	if (!status)
2650b2af264aSKiran K 		return;
2651b2af264aSKiran K 
2652b2af264aSKiran K 	cp = hci_sent_cmd_data(hdev, HCI_OP_ENHANCED_SETUP_SYNC_CONN);
2653b2af264aSKiran K 	if (!cp)
2654b2af264aSKiran K 		return;
2655b2af264aSKiran K 
265606149746SLuiz Augusto von Dentz 	hci_setup_sync_conn_status(hdev, __le16_to_cpu(cp->handle), status);
2657b2af264aSKiran K }
2658b2af264aSKiran K 
hci_cs_sniff_mode(struct hci_dev * hdev,__u8 status)2659a9de9248SMarcel Holtmann static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
2660a9de9248SMarcel Holtmann {
2661a9de9248SMarcel Holtmann 	struct hci_cp_sniff_mode *cp;
266204837f64SMarcel Holtmann 	struct hci_conn *conn;
266304837f64SMarcel Holtmann 
2664147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2665a9de9248SMarcel Holtmann 
2666a9de9248SMarcel Holtmann 	if (!status)
2667a9de9248SMarcel Holtmann 		return;
2668a9de9248SMarcel Holtmann 
2669a9de9248SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
267004837f64SMarcel Holtmann 	if (!cp)
2671a9de9248SMarcel Holtmann 		return;
267204837f64SMarcel Holtmann 
267304837f64SMarcel Holtmann 	hci_dev_lock(hdev);
267404837f64SMarcel Holtmann 
267504837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2676e73439d8SMarcel Holtmann 	if (conn) {
267751a8efd7SJohan Hedberg 		clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
267804837f64SMarcel Holtmann 
267951a8efd7SJohan Hedberg 		if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
2680e73439d8SMarcel Holtmann 			hci_sco_setup(conn, status);
2681e73439d8SMarcel Holtmann 	}
2682e73439d8SMarcel Holtmann 
268304837f64SMarcel Holtmann 	hci_dev_unlock(hdev);
268404837f64SMarcel Holtmann }
268504837f64SMarcel Holtmann 
hci_cs_exit_sniff_mode(struct hci_dev * hdev,__u8 status)2686a9de9248SMarcel Holtmann static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
2687a9de9248SMarcel Holtmann {
2688a9de9248SMarcel Holtmann 	struct hci_cp_exit_sniff_mode *cp;
268904837f64SMarcel Holtmann 	struct hci_conn *conn;
269004837f64SMarcel Holtmann 
2691147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2692a9de9248SMarcel Holtmann 
2693a9de9248SMarcel Holtmann 	if (!status)
2694a9de9248SMarcel Holtmann 		return;
2695a9de9248SMarcel Holtmann 
2696a9de9248SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
269704837f64SMarcel Holtmann 	if (!cp)
2698a9de9248SMarcel Holtmann 		return;
269904837f64SMarcel Holtmann 
270004837f64SMarcel Holtmann 	hci_dev_lock(hdev);
270104837f64SMarcel Holtmann 
270204837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2703e73439d8SMarcel Holtmann 	if (conn) {
270451a8efd7SJohan Hedberg 		clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
270504837f64SMarcel Holtmann 
270651a8efd7SJohan Hedberg 		if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
2707e73439d8SMarcel Holtmann 			hci_sco_setup(conn, status);
2708e73439d8SMarcel Holtmann 	}
2709e73439d8SMarcel Holtmann 
271004837f64SMarcel Holtmann 	hci_dev_unlock(hdev);
271104837f64SMarcel Holtmann }
271204837f64SMarcel Holtmann 
hci_cs_disconnect(struct hci_dev * hdev,u8 status)271388c3df13SJohan Hedberg static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
271488c3df13SJohan Hedberg {
271588c3df13SJohan Hedberg 	struct hci_cp_disconnect *cp;
2716182ee45dSLuiz Augusto von Dentz 	struct hci_conn_params *params;
271788c3df13SJohan Hedberg 	struct hci_conn *conn;
2718182ee45dSLuiz Augusto von Dentz 	bool mgmt_conn;
271988c3df13SJohan Hedberg 
2720147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2721147306ccSLuiz Augusto von Dentz 
2722182ee45dSLuiz Augusto von Dentz 	/* Wait for HCI_EV_DISCONN_COMPLETE if status 0x00 and not suspended
2723182ee45dSLuiz Augusto von Dentz 	 * otherwise cleanup the connection immediately.
2724182ee45dSLuiz Augusto von Dentz 	 */
2725182ee45dSLuiz Augusto von Dentz 	if (!status && !hdev->suspended)
272688c3df13SJohan Hedberg 		return;
272788c3df13SJohan Hedberg 
272888c3df13SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
272988c3df13SJohan Hedberg 	if (!cp)
273088c3df13SJohan Hedberg 		return;
273188c3df13SJohan Hedberg 
273288c3df13SJohan Hedberg 	hci_dev_lock(hdev);
273388c3df13SJohan Hedberg 
273488c3df13SJohan Hedberg 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
2735182ee45dSLuiz Augusto von Dentz 	if (!conn)
2736182ee45dSLuiz Augusto von Dentz 		goto unlock;
2737182ee45dSLuiz Augusto von Dentz 
2738182ee45dSLuiz Augusto von Dentz 	if (status) {
273988c3df13SJohan Hedberg 		mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
274088c3df13SJohan Hedberg 				       conn->dst_type, status);
274188c3df13SJohan Hedberg 
27421eeaa1aeSLuiz Augusto von Dentz 		if (conn->type == LE_LINK && conn->role == HCI_ROLE_SLAVE) {
27437087c4f6SLuiz Augusto von Dentz 			hdev->cur_adv_instance = conn->adv_instance;
2744abfeea47SLuiz Augusto von Dentz 			hci_enable_advertising(hdev);
27457087c4f6SLuiz Augusto von Dentz 		}
27467087c4f6SLuiz Augusto von Dentz 
27477f7cfcb6SPauli Virtanen 		/* Inform sockets conn is gone before we delete it */
27487f7cfcb6SPauli Virtanen 		hci_disconn_cfm(conn, HCI_ERROR_UNSPECIFIED);
27497f7cfcb6SPauli Virtanen 
2750182ee45dSLuiz Augusto von Dentz 		goto done;
2751182ee45dSLuiz Augusto von Dentz 	}
2752182ee45dSLuiz Augusto von Dentz 
2753182ee45dSLuiz Augusto von Dentz 	mgmt_conn = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
2754182ee45dSLuiz Augusto von Dentz 
2755182ee45dSLuiz Augusto von Dentz 	if (conn->type == ACL_LINK) {
2756629f66aaSAlain Michaud 		if (test_and_clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags))
2757182ee45dSLuiz Augusto von Dentz 			hci_remove_link_key(hdev, &conn->dst);
2758182ee45dSLuiz Augusto von Dentz 	}
2759182ee45dSLuiz Augusto von Dentz 
2760182ee45dSLuiz Augusto von Dentz 	params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
2761182ee45dSLuiz Augusto von Dentz 	if (params) {
2762182ee45dSLuiz Augusto von Dentz 		switch (params->auto_connect) {
2763182ee45dSLuiz Augusto von Dentz 		case HCI_AUTO_CONN_LINK_LOSS:
2764182ee45dSLuiz Augusto von Dentz 			if (cp->reason != HCI_ERROR_CONNECTION_TIMEOUT)
2765182ee45dSLuiz Augusto von Dentz 				break;
2766182ee45dSLuiz Augusto von Dentz 			fallthrough;
2767182ee45dSLuiz Augusto von Dentz 
2768182ee45dSLuiz Augusto von Dentz 		case HCI_AUTO_CONN_DIRECT:
2769182ee45dSLuiz Augusto von Dentz 		case HCI_AUTO_CONN_ALWAYS:
2770195ef75eSPauli Virtanen 			hci_pend_le_list_del_init(params);
2771195ef75eSPauli Virtanen 			hci_pend_le_list_add(params, &hdev->pend_le_conns);
2772182ee45dSLuiz Augusto von Dentz 			break;
2773182ee45dSLuiz Augusto von Dentz 
2774182ee45dSLuiz Augusto von Dentz 		default:
2775182ee45dSLuiz Augusto von Dentz 			break;
2776182ee45dSLuiz Augusto von Dentz 		}
2777182ee45dSLuiz Augusto von Dentz 	}
2778182ee45dSLuiz Augusto von Dentz 
2779182ee45dSLuiz Augusto von Dentz 	mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type,
2780182ee45dSLuiz Augusto von Dentz 				 cp->reason, mgmt_conn);
2781182ee45dSLuiz Augusto von Dentz 
2782182ee45dSLuiz Augusto von Dentz 	hci_disconn_cfm(conn, cp->reason);
2783182ee45dSLuiz Augusto von Dentz 
2784182ee45dSLuiz Augusto von Dentz done:
2785b8d29052SJoseph Hwang 	/* If the disconnection failed for any reason, the upper layer
2786b8d29052SJoseph Hwang 	 * does not retry to disconnect in current implementation.
2787b8d29052SJoseph Hwang 	 * Hence, we need to do some basic cleanup here and re-enable
2788b8d29052SJoseph Hwang 	 * advertising if necessary.
2789b8d29052SJoseph Hwang 	 */
2790b8d29052SJoseph Hwang 	hci_conn_del(conn);
2791182ee45dSLuiz Augusto von Dentz unlock:
279288c3df13SJohan Hedberg 	hci_dev_unlock(hdev);
279388c3df13SJohan Hedberg }
279488c3df13SJohan Hedberg 
ev_bdaddr_type(struct hci_dev * hdev,u8 type,bool * resolved)2795d850bf08SLuiz Augusto von Dentz static u8 ev_bdaddr_type(struct hci_dev *hdev, u8 type, bool *resolved)
27964ec4d63bSLuiz Augusto von Dentz {
27974ec4d63bSLuiz Augusto von Dentz 	/* When using controller based address resolution, then the new
27984ec4d63bSLuiz Augusto von Dentz 	 * address types 0x02 and 0x03 are used. These types need to be
27994ec4d63bSLuiz Augusto von Dentz 	 * converted back into either public address or random address type
28004ec4d63bSLuiz Augusto von Dentz 	 */
28014ec4d63bSLuiz Augusto von Dentz 	switch (type) {
28024ec4d63bSLuiz Augusto von Dentz 	case ADDR_LE_DEV_PUBLIC_RESOLVED:
2803d850bf08SLuiz Augusto von Dentz 		if (resolved)
2804d850bf08SLuiz Augusto von Dentz 			*resolved = true;
28054ec4d63bSLuiz Augusto von Dentz 		return ADDR_LE_DEV_PUBLIC;
28064ec4d63bSLuiz Augusto von Dentz 	case ADDR_LE_DEV_RANDOM_RESOLVED:
2807d850bf08SLuiz Augusto von Dentz 		if (resolved)
2808d850bf08SLuiz Augusto von Dentz 			*resolved = true;
28094ec4d63bSLuiz Augusto von Dentz 		return ADDR_LE_DEV_RANDOM;
28104ec4d63bSLuiz Augusto von Dentz 	}
28114ec4d63bSLuiz Augusto von Dentz 
2812d850bf08SLuiz Augusto von Dentz 	if (resolved)
2813d850bf08SLuiz Augusto von Dentz 		*resolved = false;
28144ec4d63bSLuiz Augusto von Dentz 	return type;
28154ec4d63bSLuiz Augusto von Dentz }
28164ec4d63bSLuiz Augusto von Dentz 
cs_le_create_conn(struct hci_dev * hdev,bdaddr_t * peer_addr,u8 peer_addr_type,u8 own_address_type,u8 filter_policy)2817d12fb056SJaganath Kanakkassery static void cs_le_create_conn(struct hci_dev *hdev, bdaddr_t *peer_addr,
2818d12fb056SJaganath Kanakkassery 			      u8 peer_addr_type, u8 own_address_type,
2819d12fb056SJaganath Kanakkassery 			      u8 filter_policy)
2820d12fb056SJaganath Kanakkassery {
2821d12fb056SJaganath Kanakkassery 	struct hci_conn *conn;
2822d12fb056SJaganath Kanakkassery 
2823d12fb056SJaganath Kanakkassery 	conn = hci_conn_hash_lookup_le(hdev, peer_addr,
2824d12fb056SJaganath Kanakkassery 				       peer_addr_type);
2825d12fb056SJaganath Kanakkassery 	if (!conn)
2826d12fb056SJaganath Kanakkassery 		return;
2827d12fb056SJaganath Kanakkassery 
2828d850bf08SLuiz Augusto von Dentz 	own_address_type = ev_bdaddr_type(hdev, own_address_type, NULL);
2829b31bc00bSSathish Narasimman 
2830d12fb056SJaganath Kanakkassery 	/* Store the initiator and responder address information which
2831d12fb056SJaganath Kanakkassery 	 * is needed for SMP. These values will not change during the
2832d12fb056SJaganath Kanakkassery 	 * lifetime of the connection.
2833d12fb056SJaganath Kanakkassery 	 */
2834d12fb056SJaganath Kanakkassery 	conn->init_addr_type = own_address_type;
2835d12fb056SJaganath Kanakkassery 	if (own_address_type == ADDR_LE_DEV_RANDOM)
2836d12fb056SJaganath Kanakkassery 		bacpy(&conn->init_addr, &hdev->random_addr);
2837d12fb056SJaganath Kanakkassery 	else
2838d12fb056SJaganath Kanakkassery 		bacpy(&conn->init_addr, &hdev->bdaddr);
2839d12fb056SJaganath Kanakkassery 
2840d12fb056SJaganath Kanakkassery 	conn->resp_addr_type = peer_addr_type;
2841d12fb056SJaganath Kanakkassery 	bacpy(&conn->resp_addr, peer_addr);
2842d12fb056SJaganath Kanakkassery }
2843d12fb056SJaganath Kanakkassery 
hci_cs_le_create_conn(struct hci_dev * hdev,u8 status)2844cb1d68f7SJohan Hedberg static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status)
2845cb1d68f7SJohan Hedberg {
2846cb1d68f7SJohan Hedberg 	struct hci_cp_le_create_conn *cp;
2847cb1d68f7SJohan Hedberg 
2848147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
2849cb1d68f7SJohan Hedberg 
2850cb1d68f7SJohan Hedberg 	/* All connection failure handling is taken care of by the
28519b3628d7SLuiz Augusto von Dentz 	 * hci_conn_failed function which is triggered by the HCI
2852cb1d68f7SJohan Hedberg 	 * request completion callbacks used for connecting.
2853cb1d68f7SJohan Hedberg 	 */
2854cb1d68f7SJohan Hedberg 	if (status)
2855cb1d68f7SJohan Hedberg 		return;
2856cb1d68f7SJohan Hedberg 
2857cb1d68f7SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
2858cb1d68f7SJohan Hedberg 	if (!cp)
2859cb1d68f7SJohan Hedberg 		return;
2860cb1d68f7SJohan Hedberg 
2861cb1d68f7SJohan Hedberg 	hci_dev_lock(hdev);
2862cb1d68f7SJohan Hedberg 
2863d12fb056SJaganath Kanakkassery 	cs_le_create_conn(hdev, &cp->peer_addr, cp->peer_addr_type,
2864d12fb056SJaganath Kanakkassery 			  cp->own_address_type, cp->filter_policy);
2865cb1d68f7SJohan Hedberg 
2866cb1d68f7SJohan Hedberg 	hci_dev_unlock(hdev);
2867cb1d68f7SJohan Hedberg }
2868cb1d68f7SJohan Hedberg 
hci_cs_le_ext_create_conn(struct hci_dev * hdev,u8 status)28694d94f95dSJaganath Kanakkassery static void hci_cs_le_ext_create_conn(struct hci_dev *hdev, u8 status)
28704d94f95dSJaganath Kanakkassery {
28714d94f95dSJaganath Kanakkassery 	struct hci_cp_le_ext_create_conn *cp;
28724d94f95dSJaganath Kanakkassery 
2873147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
28744d94f95dSJaganath Kanakkassery 
28754d94f95dSJaganath Kanakkassery 	/* All connection failure handling is taken care of by the
28769b3628d7SLuiz Augusto von Dentz 	 * hci_conn_failed function which is triggered by the HCI
28774d94f95dSJaganath Kanakkassery 	 * request completion callbacks used for connecting.
28784d94f95dSJaganath Kanakkassery 	 */
28794d94f95dSJaganath Kanakkassery 	if (status)
28804d94f95dSJaganath Kanakkassery 		return;
28814d94f95dSJaganath Kanakkassery 
28824d94f95dSJaganath Kanakkassery 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_EXT_CREATE_CONN);
28834d94f95dSJaganath Kanakkassery 	if (!cp)
28844d94f95dSJaganath Kanakkassery 		return;
28854d94f95dSJaganath Kanakkassery 
28864d94f95dSJaganath Kanakkassery 	hci_dev_lock(hdev);
28874d94f95dSJaganath Kanakkassery 
28884d94f95dSJaganath Kanakkassery 	cs_le_create_conn(hdev, &cp->peer_addr, cp->peer_addr_type,
28894d94f95dSJaganath Kanakkassery 			  cp->own_addr_type, cp->filter_policy);
28904d94f95dSJaganath Kanakkassery 
28914d94f95dSJaganath Kanakkassery 	hci_dev_unlock(hdev);
28924d94f95dSJaganath Kanakkassery }
28934d94f95dSJaganath Kanakkassery 
hci_cs_le_read_remote_features(struct hci_dev * hdev,u8 status)28940fe29fd1SMarcel Holtmann static void hci_cs_le_read_remote_features(struct hci_dev *hdev, u8 status)
28950fe29fd1SMarcel Holtmann {
28960fe29fd1SMarcel Holtmann 	struct hci_cp_le_read_remote_features *cp;
28970fe29fd1SMarcel Holtmann 	struct hci_conn *conn;
28980fe29fd1SMarcel Holtmann 
2899147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
29000fe29fd1SMarcel Holtmann 
29010fe29fd1SMarcel Holtmann 	if (!status)
29020fe29fd1SMarcel Holtmann 		return;
29030fe29fd1SMarcel Holtmann 
29040fe29fd1SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_READ_REMOTE_FEATURES);
29050fe29fd1SMarcel Holtmann 	if (!cp)
29060fe29fd1SMarcel Holtmann 		return;
29070fe29fd1SMarcel Holtmann 
29080fe29fd1SMarcel Holtmann 	hci_dev_lock(hdev);
29090fe29fd1SMarcel Holtmann 
29100fe29fd1SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
29110fe29fd1SMarcel Holtmann 	if (conn) {
29120fe29fd1SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
29130fe29fd1SMarcel Holtmann 			hci_connect_cfm(conn, status);
29140fe29fd1SMarcel Holtmann 			hci_conn_drop(conn);
29150fe29fd1SMarcel Holtmann 		}
29160fe29fd1SMarcel Holtmann 	}
29170fe29fd1SMarcel Holtmann 
29180fe29fd1SMarcel Holtmann 	hci_dev_unlock(hdev);
29190fe29fd1SMarcel Holtmann }
29200fe29fd1SMarcel Holtmann 
hci_cs_le_start_enc(struct hci_dev * hdev,u8 status)292181d0c8adSJohan Hedberg static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
292281d0c8adSJohan Hedberg {
292381d0c8adSJohan Hedberg 	struct hci_cp_le_start_enc *cp;
292481d0c8adSJohan Hedberg 	struct hci_conn *conn;
292581d0c8adSJohan Hedberg 
2926147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
292781d0c8adSJohan Hedberg 
292881d0c8adSJohan Hedberg 	if (!status)
292981d0c8adSJohan Hedberg 		return;
293081d0c8adSJohan Hedberg 
293181d0c8adSJohan Hedberg 	hci_dev_lock(hdev);
293281d0c8adSJohan Hedberg 
293381d0c8adSJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_START_ENC);
293481d0c8adSJohan Hedberg 	if (!cp)
293581d0c8adSJohan Hedberg 		goto unlock;
293681d0c8adSJohan Hedberg 
293781d0c8adSJohan Hedberg 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
293881d0c8adSJohan Hedberg 	if (!conn)
293981d0c8adSJohan Hedberg 		goto unlock;
294081d0c8adSJohan Hedberg 
294181d0c8adSJohan Hedberg 	if (conn->state != BT_CONNECTED)
294281d0c8adSJohan Hedberg 		goto unlock;
294381d0c8adSJohan Hedberg 
294481d0c8adSJohan Hedberg 	hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
294581d0c8adSJohan Hedberg 	hci_conn_drop(conn);
294681d0c8adSJohan Hedberg 
294781d0c8adSJohan Hedberg unlock:
294881d0c8adSJohan Hedberg 	hci_dev_unlock(hdev);
294981d0c8adSJohan Hedberg }
295081d0c8adSJohan Hedberg 
hci_cs_switch_role(struct hci_dev * hdev,u8 status)295150fc85f1SKuba Pawlak static void hci_cs_switch_role(struct hci_dev *hdev, u8 status)
295250fc85f1SKuba Pawlak {
295350fc85f1SKuba Pawlak 	struct hci_cp_switch_role *cp;
295450fc85f1SKuba Pawlak 	struct hci_conn *conn;
295550fc85f1SKuba Pawlak 
295650fc85f1SKuba Pawlak 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
295750fc85f1SKuba Pawlak 
295850fc85f1SKuba Pawlak 	if (!status)
295950fc85f1SKuba Pawlak 		return;
296050fc85f1SKuba Pawlak 
296150fc85f1SKuba Pawlak 	cp = hci_sent_cmd_data(hdev, HCI_OP_SWITCH_ROLE);
296250fc85f1SKuba Pawlak 	if (!cp)
296350fc85f1SKuba Pawlak 		return;
296450fc85f1SKuba Pawlak 
296550fc85f1SKuba Pawlak 	hci_dev_lock(hdev);
296650fc85f1SKuba Pawlak 
296750fc85f1SKuba Pawlak 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
296850fc85f1SKuba Pawlak 	if (conn)
296950fc85f1SKuba Pawlak 		clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
297050fc85f1SKuba Pawlak 
297150fc85f1SKuba Pawlak 	hci_dev_unlock(hdev);
297250fc85f1SKuba Pawlak }
297350fc85f1SKuba Pawlak 
hci_inquiry_complete_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)29743e54c589SLuiz Augusto von Dentz static void hci_inquiry_complete_evt(struct hci_dev *hdev, void *data,
29753e54c589SLuiz Augusto von Dentz 				     struct sk_buff *skb)
29761da177e4SLinus Torvalds {
29773e54c589SLuiz Augusto von Dentz 	struct hci_ev_status *ev = data;
297830dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
297930dc78e1SJohan Hedberg 	struct inquiry_entry *e;
29801da177e4SLinus Torvalds 
29813e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
29821da177e4SLinus Torvalds 
2983a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
298489352e7dSAndre Guedes 
298589352e7dSAndre Guedes 	if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
298689352e7dSAndre Guedes 		return;
298789352e7dSAndre Guedes 
29884e857c58SPeter Zijlstra 	smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */
29893e13fa1eSAndre Guedes 	wake_up_bit(&hdev->flags, HCI_INQUIRY);
29903e13fa1eSAndre Guedes 
2991d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
299230dc78e1SJohan Hedberg 		return;
299330dc78e1SJohan Hedberg 
299456e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
299530dc78e1SJohan Hedberg 
2996343f935bSAndre Guedes 	if (discov->state != DISCOVERY_FINDING)
299730dc78e1SJohan Hedberg 		goto unlock;
299830dc78e1SJohan Hedberg 
299930dc78e1SJohan Hedberg 	if (list_empty(&discov->resolve)) {
300007d2334aSJakub Pawlowski 		/* When BR/EDR inquiry is active and no LE scanning is in
300107d2334aSJakub Pawlowski 		 * progress, then change discovery state to indicate completion.
300207d2334aSJakub Pawlowski 		 *
300307d2334aSJakub Pawlowski 		 * When running LE scanning and BR/EDR inquiry simultaneously
300407d2334aSJakub Pawlowski 		 * and the LE scan already finished, then change the discovery
300507d2334aSJakub Pawlowski 		 * state to indicate completion.
300607d2334aSJakub Pawlowski 		 */
300707d2334aSJakub Pawlowski 		if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
300807d2334aSJakub Pawlowski 		    !test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks))
3009ff9ef578SJohan Hedberg 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
301030dc78e1SJohan Hedberg 		goto unlock;
301130dc78e1SJohan Hedberg 	}
301230dc78e1SJohan Hedberg 
301330dc78e1SJohan Hedberg 	e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
301430dc78e1SJohan Hedberg 	if (e && hci_resolve_name(hdev, e) == 0) {
301530dc78e1SJohan Hedberg 		e->name_state = NAME_PENDING;
301630dc78e1SJohan Hedberg 		hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
3017dbf6811aSArchie Pusaka 		discov->name_resolve_timeout = jiffies + NAME_RESOLVE_DURATION;
301830dc78e1SJohan Hedberg 	} else {
301907d2334aSJakub Pawlowski 		/* When BR/EDR inquiry is active and no LE scanning is in
302007d2334aSJakub Pawlowski 		 * progress, then change discovery state to indicate completion.
302107d2334aSJakub Pawlowski 		 *
302207d2334aSJakub Pawlowski 		 * When running LE scanning and BR/EDR inquiry simultaneously
302307d2334aSJakub Pawlowski 		 * and the LE scan already finished, then change the discovery
302407d2334aSJakub Pawlowski 		 * state to indicate completion.
302507d2334aSJakub Pawlowski 		 */
302607d2334aSJakub Pawlowski 		if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
302707d2334aSJakub Pawlowski 		    !test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks))
302830dc78e1SJohan Hedberg 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
302930dc78e1SJohan Hedberg 	}
303030dc78e1SJohan Hedberg 
303130dc78e1SJohan Hedberg unlock:
303256e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
30331da177e4SLinus Torvalds }
30341da177e4SLinus Torvalds 
hci_inquiry_result_evt(struct hci_dev * hdev,void * edata,struct sk_buff * skb)30353e54c589SLuiz Augusto von Dentz static void hci_inquiry_result_evt(struct hci_dev *hdev, void *edata,
30363e54c589SLuiz Augusto von Dentz 				   struct sk_buff *skb)
30371da177e4SLinus Torvalds {
30383e54c589SLuiz Augusto von Dentz 	struct hci_ev_inquiry_result *ev = edata;
303945bb4bf0SMarcel Holtmann 	struct inquiry_data data;
304027d9eb4bSLuiz Augusto von Dentz 	int i;
30411da177e4SLinus Torvalds 
304227d9eb4bSLuiz Augusto von Dentz 	if (!hci_ev_skb_pull(hdev, skb, HCI_EV_INQUIRY_RESULT,
304327d9eb4bSLuiz Augusto von Dentz 			     flex_array_size(ev, info, ev->num)))
304427d9eb4bSLuiz Augusto von Dentz 		return;
304527d9eb4bSLuiz Augusto von Dentz 
30463e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "num %d", ev->num);
304727d9eb4bSLuiz Augusto von Dentz 
304827d9eb4bSLuiz Augusto von Dentz 	if (!ev->num)
304945bb4bf0SMarcel Holtmann 		return;
305045bb4bf0SMarcel Holtmann 
3051d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ))
30521519cc17SAndre Guedes 		return;
30531519cc17SAndre Guedes 
30541da177e4SLinus Torvalds 	hci_dev_lock(hdev);
305545bb4bf0SMarcel Holtmann 
305627d9eb4bSLuiz Augusto von Dentz 	for (i = 0; i < ev->num; i++) {
305727d9eb4bSLuiz Augusto von Dentz 		struct inquiry_info *info = &ev->info[i];
3058af58925cSMarcel Holtmann 		u32 flags;
30593175405bSJohan Hedberg 
30601da177e4SLinus Torvalds 		bacpy(&data.bdaddr, &info->bdaddr);
30611da177e4SLinus Torvalds 		data.pscan_rep_mode	= info->pscan_rep_mode;
30621da177e4SLinus Torvalds 		data.pscan_period_mode	= info->pscan_period_mode;
30631da177e4SLinus Torvalds 		data.pscan_mode		= info->pscan_mode;
30641da177e4SLinus Torvalds 		memcpy(data.dev_class, info->dev_class, 3);
30651da177e4SLinus Torvalds 		data.clock_offset	= info->clock_offset;
3066efb2513fSMarcel Holtmann 		data.rssi		= HCI_RSSI_INVALID;
306741a96212SMarcel Holtmann 		data.ssp_mode		= 0x00;
30683175405bSJohan Hedberg 
3069af58925cSMarcel Holtmann 		flags = hci_inquiry_cache_update(hdev, &data, false);
3070af58925cSMarcel Holtmann 
307148264f06SJohan Hedberg 		mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
3072efb2513fSMarcel Holtmann 				  info->dev_class, HCI_RSSI_INVALID,
3073b338d917SBrian Gix 				  flags, NULL, 0, NULL, 0, 0);
30741da177e4SLinus Torvalds 	}
307545bb4bf0SMarcel Holtmann 
30761da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
30771da177e4SLinus Torvalds }
30781da177e4SLinus Torvalds 
hci_conn_complete_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)30793e54c589SLuiz Augusto von Dentz static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
30803e54c589SLuiz Augusto von Dentz 				  struct sk_buff *skb)
30811da177e4SLinus Torvalds {
30823e54c589SLuiz Augusto von Dentz 	struct hci_ev_conn_complete *ev = data;
3083a9de9248SMarcel Holtmann 	struct hci_conn *conn;
3084c86cc5a3SLuiz Augusto von Dentz 	u8 status = ev->status;
30851da177e4SLinus Torvalds 
3086c86cc5a3SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
308745bb4bf0SMarcel Holtmann 
30881da177e4SLinus Torvalds 	hci_dev_lock(hdev);
308945bb4bf0SMarcel Holtmann 
3090a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
30919499237aSMarcel Holtmann 	if (!conn) {
3092aef2aa4fSLuiz Augusto von Dentz 		/* In case of error status and there is no connection pending
3093aef2aa4fSLuiz Augusto von Dentz 		 * just unlock as there is nothing to cleanup.
3094aef2aa4fSLuiz Augusto von Dentz 		 */
3095aef2aa4fSLuiz Augusto von Dentz 		if (ev->status)
3096aef2aa4fSLuiz Augusto von Dentz 			goto unlock;
3097aef2aa4fSLuiz Augusto von Dentz 
3098a46b7ed4SSonny Sasaka 		/* Connection may not exist if auto-connected. Check the bredr
3099a46b7ed4SSonny Sasaka 		 * allowlist to see if this device is allowed to auto connect.
3100a46b7ed4SSonny Sasaka 		 * If link is an ACL type, create a connection class
31014f40afc6SAbhishek Pandit-Subedi 		 * automatically.
3102a46b7ed4SSonny Sasaka 		 *
3103a46b7ed4SSonny Sasaka 		 * Auto-connect will only occur if the event filter is
3104a46b7ed4SSonny Sasaka 		 * programmed with a given address. Right now, event filter is
3105a46b7ed4SSonny Sasaka 		 * only used during suspend.
31064f40afc6SAbhishek Pandit-Subedi 		 */
3107a46b7ed4SSonny Sasaka 		if (ev->link_type == ACL_LINK &&
31083d4f9c00SArchie Pusaka 		    hci_bdaddr_list_lookup_with_flags(&hdev->accept_list,
3109a46b7ed4SSonny Sasaka 						      &ev->bdaddr,
3110a46b7ed4SSonny Sasaka 						      BDADDR_BREDR)) {
311184cb0143SZiyang Xuan 			conn = hci_conn_add_unset(hdev, ev->link_type,
311284cb0143SZiyang Xuan 						  &ev->bdaddr, HCI_ROLE_SLAVE);
3113ad3f7986SSungwoo Kim 			if (IS_ERR(conn)) {
3114ad3f7986SSungwoo Kim 				bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn));
31154f40afc6SAbhishek Pandit-Subedi 				goto unlock;
31164f40afc6SAbhishek Pandit-Subedi 			}
31172d186fcdSAbhishek Pandit-Subedi 		} else {
31189499237aSMarcel Holtmann 			if (ev->link_type != SCO_LINK)
31199499237aSMarcel Holtmann 				goto unlock;
31209499237aSMarcel Holtmann 
31212d186fcdSAbhishek Pandit-Subedi 			conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK,
31222d186fcdSAbhishek Pandit-Subedi 						       &ev->bdaddr);
3123a9de9248SMarcel Holtmann 			if (!conn)
3124a9de9248SMarcel Holtmann 				goto unlock;
312545bb4bf0SMarcel Holtmann 
31269499237aSMarcel Holtmann 			conn->type = SCO_LINK;
31279499237aSMarcel Holtmann 		}
31282d186fcdSAbhishek Pandit-Subedi 	}
31299499237aSMarcel Holtmann 
3130d5ebaa7cSSoenke Huster 	/* The HCI_Connection_Complete event is only sent once per connection.
3131d5ebaa7cSSoenke Huster 	 * Processing it more than once per connection can corrupt kernel memory.
3132d5ebaa7cSSoenke Huster 	 *
3133d5ebaa7cSSoenke Huster 	 * As the connection handle is set here for the first time, it indicates
3134d5ebaa7cSSoenke Huster 	 * whether the connection is already set up.
3135d5ebaa7cSSoenke Huster 	 */
31369f78191cSLuiz Augusto von Dentz 	if (!HCI_CONN_HANDLE_UNSET(conn->handle)) {
3137d5ebaa7cSSoenke Huster 		bt_dev_err(hdev, "Ignoring HCI_Connection_Complete for existing connection");
3138d5ebaa7cSSoenke Huster 		goto unlock;
3139d5ebaa7cSSoenke Huster 	}
3140d5ebaa7cSSoenke Huster 
3141c86cc5a3SLuiz Augusto von Dentz 	if (!status) {
314216e3b642SLuiz Augusto von Dentz 		status = hci_conn_set_handle(conn, __le16_to_cpu(ev->handle));
314316e3b642SLuiz Augusto von Dentz 		if (status)
3144c86cc5a3SLuiz Augusto von Dentz 			goto done;
3145769be974SMarcel Holtmann 
3146769be974SMarcel Holtmann 		if (conn->type == ACL_LINK) {
3147769be974SMarcel Holtmann 			conn->state = BT_CONFIG;
3148769be974SMarcel Holtmann 			hci_conn_hold(conn);
3149a9ea3ed9SSzymon Janc 
3150a9ea3ed9SSzymon Janc 			if (!conn->out && !hci_conn_ssp_enabled(conn) &&
3151a9ea3ed9SSzymon Janc 			    !hci_find_link_key(hdev, &ev->bdaddr))
3152a9ea3ed9SSzymon Janc 				conn->disc_timeout = HCI_PAIRING_TIMEOUT;
3153a9ea3ed9SSzymon Janc 			else
3154052b30b0SMarcel Holtmann 				conn->disc_timeout = HCI_DISCONN_TIMEOUT;
3155769be974SMarcel Holtmann 		} else
3156a9de9248SMarcel Holtmann 			conn->state = BT_CONNECTED;
3157a9de9248SMarcel Holtmann 
315823b9ceb7SMarcel Holtmann 		hci_debugfs_create_conn(conn);
31597d0db0a3SMarcel Holtmann 		hci_conn_add_sysfs(conn);
31607d0db0a3SMarcel Holtmann 
3161a9de9248SMarcel Holtmann 		if (test_bit(HCI_AUTH, &hdev->flags))
31624dae2798SJohan Hedberg 			set_bit(HCI_CONN_AUTH, &conn->flags);
3163a9de9248SMarcel Holtmann 
3164a9de9248SMarcel Holtmann 		if (test_bit(HCI_ENCRYPT, &hdev->flags))
31654dae2798SJohan Hedberg 			set_bit(HCI_CONN_ENCRYPT, &conn->flags);
3166a9de9248SMarcel Holtmann 
31674a328401SHui Wang 		/* "Link key request" completed ahead of "connect request" completes */
31684a328401SHui Wang 		if (ev->encr_mode == 1 && !test_bit(HCI_CONN_ENCRYPT, &conn->flags) &&
31694a328401SHui Wang 		    ev->link_type == ACL_LINK) {
31704a328401SHui Wang 			struct link_key *key;
31714a328401SHui Wang 			struct hci_cp_read_enc_key_size cp;
31724a328401SHui Wang 
31734a328401SHui Wang 			key = hci_find_link_key(hdev, &ev->bdaddr);
31744a328401SHui Wang 			if (key) {
31754a328401SHui Wang 				set_bit(HCI_CONN_ENCRYPT, &conn->flags);
31764a328401SHui Wang 
317762e3a7cbSLuiz Augusto von Dentz 				if (!read_key_size_capable(hdev)) {
31784a328401SHui Wang 					conn->enc_key_size = HCI_LINK_KEY_SIZE;
31794a328401SHui Wang 				} else {
31804a328401SHui Wang 					cp.handle = cpu_to_le16(conn->handle);
31814a328401SHui Wang 					if (hci_send_cmd(hdev, HCI_OP_READ_ENC_KEY_SIZE,
31824a328401SHui Wang 							 sizeof(cp), &cp)) {
31834a328401SHui Wang 						bt_dev_err(hdev, "sending read key size failed");
31844a328401SHui Wang 						conn->enc_key_size = HCI_LINK_KEY_SIZE;
31854a328401SHui Wang 					}
31864a328401SHui Wang 				}
31874a328401SHui Wang 
31884a328401SHui Wang 				hci_encrypt_cfm(conn, ev->status);
31894a328401SHui Wang 			}
31904a328401SHui Wang 		}
31914a328401SHui Wang 
3192a9de9248SMarcel Holtmann 		/* Get remote features */
3193a9de9248SMarcel Holtmann 		if (conn->type == ACL_LINK) {
3194a9de9248SMarcel Holtmann 			struct hci_cp_read_remote_features cp;
3195a9de9248SMarcel Holtmann 			cp.handle = ev->handle;
3196769be974SMarcel Holtmann 			hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
3197769be974SMarcel Holtmann 				     sizeof(cp), &cp);
319822f433dcSJohan Hedberg 
3199bb876725SBrian Gix 			hci_update_scan(hdev);
320045bb4bf0SMarcel Holtmann 		}
3201a9de9248SMarcel Holtmann 
3202a9de9248SMarcel Holtmann 		/* Set packet type for incoming connection */
3203d095c1ebSAndrei Emeltchenko 		if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
3204a9de9248SMarcel Holtmann 			struct hci_cp_change_conn_ptype cp;
3205a9de9248SMarcel Holtmann 			cp.handle = ev->handle;
3206a8746417SMarcel Holtmann 			cp.pkt_type = cpu_to_le16(conn->pkt_type);
320704124681SGustavo F. Padovan 			hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
320804124681SGustavo F. Padovan 				     &cp);
3209a9de9248SMarcel Holtmann 		}
321017d5c04cSJohan Hedberg 	}
321145bb4bf0SMarcel Holtmann 
3212e73439d8SMarcel Holtmann 	if (conn->type == ACL_LINK)
3213e73439d8SMarcel Holtmann 		hci_sco_setup(conn, ev->status);
321445bb4bf0SMarcel Holtmann 
3215c86cc5a3SLuiz Augusto von Dentz done:
3216c86cc5a3SLuiz Augusto von Dentz 	if (status) {
32179b3628d7SLuiz Augusto von Dentz 		hci_conn_failed(conn, status);
32181f8330eaSSathish Narsimman 	} else if (ev->link_type == SCO_LINK) {
32191f8330eaSSathish Narsimman 		switch (conn->setting & SCO_AIRMODE_MASK) {
32201f8330eaSSathish Narsimman 		case SCO_AIRMODE_CVSD:
32211f8330eaSSathish Narsimman 			if (hdev->notify)
32221f8330eaSSathish Narsimman 				hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD);
32231f8330eaSSathish Narsimman 			break;
32241f8330eaSSathish Narsimman 		}
32251f8330eaSSathish Narsimman 
3226c86cc5a3SLuiz Augusto von Dentz 		hci_connect_cfm(conn, status);
32271f8330eaSSathish Narsimman 	}
3228a9de9248SMarcel Holtmann 
3229a9de9248SMarcel Holtmann unlock:
32301da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
3231a9de9248SMarcel Holtmann 
3232a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
32331da177e4SLinus Torvalds }
32341da177e4SLinus Torvalds 
hci_reject_conn(struct hci_dev * hdev,bdaddr_t * bdaddr)323570c46425SJohan Hedberg static void hci_reject_conn(struct hci_dev *hdev, bdaddr_t *bdaddr)
323670c46425SJohan Hedberg {
323770c46425SJohan Hedberg 	struct hci_cp_reject_conn_req cp;
323870c46425SJohan Hedberg 
323970c46425SJohan Hedberg 	bacpy(&cp.bdaddr, bdaddr);
324070c46425SJohan Hedberg 	cp.reason = HCI_ERROR_REJ_BAD_ADDR;
324170c46425SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
324270c46425SJohan Hedberg }
324370c46425SJohan Hedberg 
hci_conn_request_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)32443e54c589SLuiz Augusto von Dentz static void hci_conn_request_evt(struct hci_dev *hdev, void *data,
32453e54c589SLuiz Augusto von Dentz 				 struct sk_buff *skb)
32461da177e4SLinus Torvalds {
32473e54c589SLuiz Augusto von Dentz 	struct hci_ev_conn_request *ev = data;
32481da177e4SLinus Torvalds 	int mask = hdev->link_mode;
324970c46425SJohan Hedberg 	struct inquiry_entry *ie;
325070c46425SJohan Hedberg 	struct hci_conn *conn;
325120714bfeSFrédéric Dalleau 	__u8 flags = 0;
32521da177e4SLinus Torvalds 
32533e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "bdaddr %pMR type 0x%x", &ev->bdaddr, ev->link_type);
32541da177e4SLinus Torvalds 
32551ffc6f8cSLee, Chun-Yi 	/* Reject incoming connection from device with same BD ADDR against
32561ffc6f8cSLee, Chun-Yi 	 * CVE-2020-26555
32571ffc6f8cSLee, Chun-Yi 	 */
32589d1a3c74SArnd Bergmann 	if (hdev && !bacmp(&hdev->bdaddr, &ev->bdaddr)) {
32591ffc6f8cSLee, Chun-Yi 		bt_dev_dbg(hdev, "Reject connection with same BD_ADDR %pMR\n",
32601ffc6f8cSLee, Chun-Yi 			   &ev->bdaddr);
32611ffc6f8cSLee, Chun-Yi 		hci_reject_conn(hdev, &ev->bdaddr);
32621ffc6f8cSLee, Chun-Yi 		return;
32631ffc6f8cSLee, Chun-Yi 	}
32641ffc6f8cSLee, Chun-Yi 
326520714bfeSFrédéric Dalleau 	mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
326620714bfeSFrédéric Dalleau 				      &flags);
32671da177e4SLinus Torvalds 
326870c46425SJohan Hedberg 	if (!(mask & HCI_LM_ACCEPT)) {
326970c46425SJohan Hedberg 		hci_reject_conn(hdev, &ev->bdaddr);
327070c46425SJohan Hedberg 		return;
327170c46425SJohan Hedberg 	}
327270c46425SJohan Hedberg 
3273fb048caeSNiels Dossche 	hci_dev_lock(hdev);
3274fb048caeSNiels Dossche 
32753d4f9c00SArchie Pusaka 	if (hci_bdaddr_list_lookup(&hdev->reject_list, &ev->bdaddr,
3276dcc36c16SJohan Hedberg 				   BDADDR_BREDR)) {
327770c46425SJohan Hedberg 		hci_reject_conn(hdev, &ev->bdaddr);
3278fb048caeSNiels Dossche 		goto unlock;
327970c46425SJohan Hedberg 	}
328046c4c941SJohan Hedberg 
32813d4f9c00SArchie Pusaka 	/* Require HCI_CONNECTABLE or an accept list entry to accept the
32826a8fc95cSJohan Hedberg 	 * connection. These features are only touched through mgmt so
32836a8fc95cSJohan Hedberg 	 * only do the checks if HCI_MGMT is set.
32846a8fc95cSJohan Hedberg 	 */
3285d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT) &&
3286d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONNECTABLE) &&
32873d4f9c00SArchie Pusaka 	    !hci_bdaddr_list_lookup_with_flags(&hdev->accept_list, &ev->bdaddr,
3288a55bd29dSJohan Hedberg 					       BDADDR_BREDR)) {
3289a55bd29dSJohan Hedberg 		hci_reject_conn(hdev, &ev->bdaddr);
3290fb048caeSNiels Dossche 		goto unlock;
3291a55bd29dSJohan Hedberg 	}
329270c46425SJohan Hedberg 
32931da177e4SLinus Torvalds 	/* Connection accepted */
32941da177e4SLinus Torvalds 
3295cc11b9c1SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3296cc11b9c1SAndrei Emeltchenko 	if (ie)
3297c7bdd502SMarcel Holtmann 		memcpy(ie->data.dev_class, ev->dev_class, 3);
3298c7bdd502SMarcel Holtmann 
32998fc9ced3SGustavo Padovan 	conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
33008fc9ced3SGustavo Padovan 			&ev->bdaddr);
33011da177e4SLinus Torvalds 	if (!conn) {
330284cb0143SZiyang Xuan 		conn = hci_conn_add_unset(hdev, ev->link_type, &ev->bdaddr,
3303a5c4e309SJohan Hedberg 					  HCI_ROLE_SLAVE);
3304ad3f7986SSungwoo Kim 		if (IS_ERR(conn)) {
3305ad3f7986SSungwoo Kim 			bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn));
3306fb048caeSNiels Dossche 			goto unlock;
33071da177e4SLinus Torvalds 		}
33081da177e4SLinus Torvalds 	}
3309b6a0dc82SMarcel Holtmann 
33101da177e4SLinus Torvalds 	memcpy(conn->dev_class, ev->dev_class, 3);
3311b6a0dc82SMarcel Holtmann 
33121da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
33131da177e4SLinus Torvalds 
331420714bfeSFrédéric Dalleau 	if (ev->link_type == ACL_LINK ||
331520714bfeSFrédéric Dalleau 	    (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
3316b6a0dc82SMarcel Holtmann 		struct hci_cp_accept_conn_req cp;
331720714bfeSFrédéric Dalleau 		conn->state = BT_CONNECT;
3318b6a0dc82SMarcel Holtmann 
33191da177e4SLinus Torvalds 		bacpy(&cp.bdaddr, &ev->bdaddr);
33201da177e4SLinus Torvalds 
33211da177e4SLinus Torvalds 		if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
332274be523cSArchie Pusaka 			cp.role = 0x00; /* Become central */
33231da177e4SLinus Torvalds 		else
332474be523cSArchie Pusaka 			cp.role = 0x01; /* Remain peripheral */
33251da177e4SLinus Torvalds 
332670c46425SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp);
332720714bfeSFrédéric Dalleau 	} else if (!(flags & HCI_PROTO_DEFER)) {
3328b6a0dc82SMarcel Holtmann 		struct hci_cp_accept_sync_conn_req cp;
332920714bfeSFrédéric Dalleau 		conn->state = BT_CONNECT;
3330b6a0dc82SMarcel Holtmann 
3331b6a0dc82SMarcel Holtmann 		bacpy(&cp.bdaddr, &ev->bdaddr);
3332a8746417SMarcel Holtmann 		cp.pkt_type = cpu_to_le16(conn->pkt_type);
3333b6a0dc82SMarcel Holtmann 
3334dcf4adbfSJoe Perches 		cp.tx_bandwidth   = cpu_to_le32(0x00001f40);
3335dcf4adbfSJoe Perches 		cp.rx_bandwidth   = cpu_to_le32(0x00001f40);
3336dcf4adbfSJoe Perches 		cp.max_latency    = cpu_to_le16(0xffff);
3337b6a0dc82SMarcel Holtmann 		cp.content_format = cpu_to_le16(hdev->voice_setting);
3338b6a0dc82SMarcel Holtmann 		cp.retrans_effort = 0xff;
3339b6a0dc82SMarcel Holtmann 
334070c46425SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, sizeof(cp),
334170c46425SJohan Hedberg 			     &cp);
334220714bfeSFrédéric Dalleau 	} else {
334320714bfeSFrédéric Dalleau 		conn->state = BT_CONNECT2;
3344539c496dSJohan Hedberg 		hci_connect_cfm(conn, 0);
3345b6a0dc82SMarcel Holtmann 	}
3346fb048caeSNiels Dossche 
3347fb048caeSNiels Dossche 	return;
3348fb048caeSNiels Dossche unlock:
3349fb048caeSNiels Dossche 	hci_dev_unlock(hdev);
33501da177e4SLinus Torvalds }
33511da177e4SLinus Torvalds 
hci_to_mgmt_reason(u8 err)3352f0d6a0eaSMikel Astiz static u8 hci_to_mgmt_reason(u8 err)
3353f0d6a0eaSMikel Astiz {
3354f0d6a0eaSMikel Astiz 	switch (err) {
3355f0d6a0eaSMikel Astiz 	case HCI_ERROR_CONNECTION_TIMEOUT:
3356f0d6a0eaSMikel Astiz 		return MGMT_DEV_DISCONN_TIMEOUT;
3357f0d6a0eaSMikel Astiz 	case HCI_ERROR_REMOTE_USER_TERM:
3358f0d6a0eaSMikel Astiz 	case HCI_ERROR_REMOTE_LOW_RESOURCES:
3359f0d6a0eaSMikel Astiz 	case HCI_ERROR_REMOTE_POWER_OFF:
3360f0d6a0eaSMikel Astiz 		return MGMT_DEV_DISCONN_REMOTE;
3361f0d6a0eaSMikel Astiz 	case HCI_ERROR_LOCAL_HOST_TERM:
3362f0d6a0eaSMikel Astiz 		return MGMT_DEV_DISCONN_LOCAL_HOST;
3363f0d6a0eaSMikel Astiz 	default:
3364f0d6a0eaSMikel Astiz 		return MGMT_DEV_DISCONN_UNKNOWN;
3365f0d6a0eaSMikel Astiz 	}
3366f0d6a0eaSMikel Astiz }
3367f0d6a0eaSMikel Astiz 
hci_disconn_complete_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)33683e54c589SLuiz Augusto von Dentz static void hci_disconn_complete_evt(struct hci_dev *hdev, void *data,
33693e54c589SLuiz Augusto von Dentz 				     struct sk_buff *skb)
33701da177e4SLinus Torvalds {
33713e54c589SLuiz Augusto von Dentz 	struct hci_ev_disconn_complete *ev = data;
3372160b9251SSzymon Janc 	u8 reason;
33739fcb18efSAndre Guedes 	struct hci_conn_params *params;
337404837f64SMarcel Holtmann 	struct hci_conn *conn;
337512d4a3b2SJohan Hedberg 	bool mgmt_connected;
33761da177e4SLinus Torvalds 
33773e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
33781da177e4SLinus Torvalds 
33791da177e4SLinus Torvalds 	hci_dev_lock(hdev);
33801da177e4SLinus Torvalds 
338104837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3382f7520543SJohan Hedberg 	if (!conn)
3383f7520543SJohan Hedberg 		goto unlock;
3384f7520543SJohan Hedberg 
3385f0d6a0eaSMikel Astiz 	if (ev->status) {
338688c3df13SJohan Hedberg 		mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
338788c3df13SJohan Hedberg 				       conn->dst_type, ev->status);
3388abf54a50SAndre Guedes 		goto unlock;
3389abf54a50SAndre Guedes 	}
3390f0d6a0eaSMikel Astiz 
33913846220bSAndre Guedes 	conn->state = BT_CLOSED;
33923846220bSAndre Guedes 
339312d4a3b2SJohan Hedberg 	mgmt_connected = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
3394160b9251SSzymon Janc 
3395160b9251SSzymon Janc 	if (test_bit(HCI_CONN_AUTH_FAILURE, &conn->flags))
3396160b9251SSzymon Janc 		reason = MGMT_DEV_DISCONN_AUTH_FAILURE;
3397160b9251SSzymon Janc 	else
3398160b9251SSzymon Janc 		reason = hci_to_mgmt_reason(ev->reason);
3399160b9251SSzymon Janc 
340012d4a3b2SJohan Hedberg 	mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type,
340112d4a3b2SJohan Hedberg 				reason, mgmt_connected);
3402f7520543SJohan Hedberg 
340322f433dcSJohan Hedberg 	if (conn->type == ACL_LINK) {
3404629f66aaSAlain Michaud 		if (test_and_clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags))
34056ec5bcadSVishal Agarwal 			hci_remove_link_key(hdev, &conn->dst);
34063846220bSAndre Guedes 
3407bb876725SBrian Gix 		hci_update_scan(hdev);
340822f433dcSJohan Hedberg 	}
340922f433dcSJohan Hedberg 
34109fcb18efSAndre Guedes 	params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
34119fcb18efSAndre Guedes 	if (params) {
34129fcb18efSAndre Guedes 		switch (params->auto_connect) {
34139fcb18efSAndre Guedes 		case HCI_AUTO_CONN_LINK_LOSS:
34149fcb18efSAndre Guedes 			if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT)
34159fcb18efSAndre Guedes 				break;
341619186c7bSGustavo A. R. Silva 			fallthrough;
34179fcb18efSAndre Guedes 
34184b9e7e75SMarcel Holtmann 		case HCI_AUTO_CONN_DIRECT:
34199fcb18efSAndre Guedes 		case HCI_AUTO_CONN_ALWAYS:
3420195ef75eSPauli Virtanen 			hci_pend_le_list_del_init(params);
3421195ef75eSPauli Virtanen 			hci_pend_le_list_add(params, &hdev->pend_le_conns);
34225bee2fd6SLuiz Augusto von Dentz 			hci_update_passive_scan(hdev);
34239fcb18efSAndre Guedes 			break;
34249fcb18efSAndre Guedes 
34259fcb18efSAndre Guedes 		default:
34269fcb18efSAndre Guedes 			break;
34279fcb18efSAndre Guedes 		}
34289fcb18efSAndre Guedes 	}
34299fcb18efSAndre Guedes 
34303a6d576bSJohan Hedberg 	hci_disconn_cfm(conn, ev->reason);
34312210246cSJohan Hedberg 
34322210246cSJohan Hedberg 	/* Re-enable advertising if necessary, since it might
34332210246cSJohan Hedberg 	 * have been disabled by the connection. From the
34342210246cSJohan Hedberg 	 * HCI_LE_Set_Advertise_Enable command description in
34352210246cSJohan Hedberg 	 * the core specification (v4.0):
34362210246cSJohan Hedberg 	 * "The Controller shall continue advertising until the Host
34372210246cSJohan Hedberg 	 * issues an LE_Set_Advertise_Enable command with
34382210246cSJohan Hedberg 	 * Advertising_Enable set to 0x00 (Advertising is disabled)
34392210246cSJohan Hedberg 	 * or until a connection is created or until the Advertising
34402210246cSJohan Hedberg 	 * is timed out due to Directed Advertising."
34412210246cSJohan Hedberg 	 */
34421eeaa1aeSLuiz Augusto von Dentz 	if (conn->type == LE_LINK && conn->role == HCI_ROLE_SLAVE) {
34437087c4f6SLuiz Augusto von Dentz 		hdev->cur_adv_instance = conn->adv_instance;
3444abfeea47SLuiz Augusto von Dentz 		hci_enable_advertising(hdev);
34457087c4f6SLuiz Augusto von Dentz 	}
34467087c4f6SLuiz Augusto von Dentz 
34477087c4f6SLuiz Augusto von Dentz 	hci_conn_del(conn);
34481da177e4SLinus Torvalds 
3449f7520543SJohan Hedberg unlock:
34501da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
34511da177e4SLinus Torvalds }
34521da177e4SLinus Torvalds 
hci_auth_complete_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)34533e54c589SLuiz Augusto von Dentz static void hci_auth_complete_evt(struct hci_dev *hdev, void *data,
34543e54c589SLuiz Augusto von Dentz 				  struct sk_buff *skb)
3455a9de9248SMarcel Holtmann {
34563e54c589SLuiz Augusto von Dentz 	struct hci_ev_auth_complete *ev = data;
3457a9de9248SMarcel Holtmann 	struct hci_conn *conn;
3458a9de9248SMarcel Holtmann 
34593e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
3460a9de9248SMarcel Holtmann 
3461a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
3462a9de9248SMarcel Holtmann 
3463a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3464d7556e20SWaldemar Rymarkiewicz 	if (!conn)
3465d7556e20SWaldemar Rymarkiewicz 		goto unlock;
3466d7556e20SWaldemar Rymarkiewicz 
3467765c2a96SJohan Hedberg 	if (!ev->status) {
3468160b9251SSzymon Janc 		clear_bit(HCI_CONN_AUTH_FAILURE, &conn->flags);
34694dae2798SJohan Hedberg 		set_bit(HCI_CONN_AUTH, &conn->flags);
3470765c2a96SJohan Hedberg 		conn->sec_level = conn->pending_sec_level;
34712a611692SJohan Hedberg 	} else {
3472160b9251SSzymon Janc 		if (ev->status == HCI_ERROR_PIN_OR_KEY_MISSING)
3473160b9251SSzymon Janc 			set_bit(HCI_CONN_AUTH_FAILURE, &conn->flags);
3474160b9251SSzymon Janc 
3475e1e930f5SJohan Hedberg 		mgmt_auth_failed(conn, ev->status);
34762a611692SJohan Hedberg 	}
3477a9de9248SMarcel Holtmann 
347851a8efd7SJohan Hedberg 	clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
3479a9de9248SMarcel Holtmann 
3480f8558555SMarcel Holtmann 	if (conn->state == BT_CONFIG) {
3481aa64a8b5SJohan Hedberg 		if (!ev->status && hci_conn_ssp_enabled(conn)) {
3482f8558555SMarcel Holtmann 			struct hci_cp_set_conn_encrypt cp;
3483f8558555SMarcel Holtmann 			cp.handle  = ev->handle;
3484f8558555SMarcel Holtmann 			cp.encrypt = 0x01;
3485d7556e20SWaldemar Rymarkiewicz 			hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
3486d7556e20SWaldemar Rymarkiewicz 				     &cp);
3487f8558555SMarcel Holtmann 		} else {
3488f8558555SMarcel Holtmann 			conn->state = BT_CONNECTED;
3489539c496dSJohan Hedberg 			hci_connect_cfm(conn, ev->status);
349076a68ba0SDavid Herrmann 			hci_conn_drop(conn);
3491f8558555SMarcel Holtmann 		}
3492052b30b0SMarcel Holtmann 	} else {
3493a9de9248SMarcel Holtmann 		hci_auth_cfm(conn, ev->status);
3494a9de9248SMarcel Holtmann 
3495052b30b0SMarcel Holtmann 		hci_conn_hold(conn);
3496052b30b0SMarcel Holtmann 		conn->disc_timeout = HCI_DISCONN_TIMEOUT;
349776a68ba0SDavid Herrmann 		hci_conn_drop(conn);
3498052b30b0SMarcel Holtmann 	}
3499052b30b0SMarcel Holtmann 
350051a8efd7SJohan Hedberg 	if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
3501a9de9248SMarcel Holtmann 		if (!ev->status) {
3502a9de9248SMarcel Holtmann 			struct hci_cp_set_conn_encrypt cp;
3503f8558555SMarcel Holtmann 			cp.handle  = ev->handle;
3504f8558555SMarcel Holtmann 			cp.encrypt = 0x01;
3505d7556e20SWaldemar Rymarkiewicz 			hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
3506d7556e20SWaldemar Rymarkiewicz 				     &cp);
3507a9de9248SMarcel Holtmann 		} else {
350851a8efd7SJohan Hedberg 			clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
35093ca44c16SLuiz Augusto von Dentz 			hci_encrypt_cfm(conn, ev->status);
3510a9de9248SMarcel Holtmann 		}
3511a9de9248SMarcel Holtmann 	}
3512a9de9248SMarcel Holtmann 
3513d7556e20SWaldemar Rymarkiewicz unlock:
3514a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
3515a9de9248SMarcel Holtmann }
3516a9de9248SMarcel Holtmann 
hci_remote_name_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)35173e54c589SLuiz Augusto von Dentz static void hci_remote_name_evt(struct hci_dev *hdev, void *data,
35183e54c589SLuiz Augusto von Dentz 				struct sk_buff *skb)
3519a9de9248SMarcel Holtmann {
35203e54c589SLuiz Augusto von Dentz 	struct hci_ev_remote_name *ev = data;
3521127178d2SJohan Hedberg 	struct hci_conn *conn;
3522127178d2SJohan Hedberg 
35233e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
3524a9de9248SMarcel Holtmann 
3525127178d2SJohan Hedberg 	hci_dev_lock(hdev);
3526127178d2SJohan Hedberg 
3527127178d2SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3528b644ba33SJohan Hedberg 
3529d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
3530b644ba33SJohan Hedberg 		goto check_auth;
3531b644ba33SJohan Hedberg 
3532b644ba33SJohan Hedberg 	if (ev->status == 0)
3533b644ba33SJohan Hedberg 		hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
3534b644ba33SJohan Hedberg 				       strnlen(ev->name, HCI_MAX_NAME_LENGTH));
3535b644ba33SJohan Hedberg 	else
3536b644ba33SJohan Hedberg 		hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
3537b644ba33SJohan Hedberg 
3538b644ba33SJohan Hedberg check_auth:
353979c6c70cSJohan Hedberg 	if (!conn)
354079c6c70cSJohan Hedberg 		goto unlock;
354179c6c70cSJohan Hedberg 
354279c6c70cSJohan Hedberg 	if (!hci_outgoing_auth_needed(hdev, conn))
354379c6c70cSJohan Hedberg 		goto unlock;
354479c6c70cSJohan Hedberg 
354551a8efd7SJohan Hedberg 	if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
3546127178d2SJohan Hedberg 		struct hci_cp_auth_requested cp;
3547977f8fceSJohan Hedberg 
3548977f8fceSJohan Hedberg 		set_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags);
3549977f8fceSJohan Hedberg 
3550127178d2SJohan Hedberg 		cp.handle = __cpu_to_le16(conn->handle);
3551127178d2SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
3552127178d2SJohan Hedberg 	}
3553127178d2SJohan Hedberg 
355479c6c70cSJohan Hedberg unlock:
3555127178d2SJohan Hedberg 	hci_dev_unlock(hdev);
3556a9de9248SMarcel Holtmann }
3557a9de9248SMarcel Holtmann 
hci_encrypt_change_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)35583e54c589SLuiz Augusto von Dentz static void hci_encrypt_change_evt(struct hci_dev *hdev, void *data,
35593e54c589SLuiz Augusto von Dentz 				   struct sk_buff *skb)
3560a9de9248SMarcel Holtmann {
35613e54c589SLuiz Augusto von Dentz 	struct hci_ev_encrypt_change *ev = data;
3562a9de9248SMarcel Holtmann 	struct hci_conn *conn;
3563a9de9248SMarcel Holtmann 
35643e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
3565a9de9248SMarcel Holtmann 
3566a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
3567a9de9248SMarcel Holtmann 
3568a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3569dc8357ccSMarcel Holtmann 	if (!conn)
3570dc8357ccSMarcel Holtmann 		goto unlock;
3571dc8357ccSMarcel Holtmann 
3572a9de9248SMarcel Holtmann 	if (!ev->status) {
3573ae293196SMarcel Holtmann 		if (ev->encrypt) {
3574ae293196SMarcel Holtmann 			/* Encryption implies authentication */
35754dae2798SJohan Hedberg 			set_bit(HCI_CONN_AUTH, &conn->flags);
35764dae2798SJohan Hedberg 			set_bit(HCI_CONN_ENCRYPT, &conn->flags);
3577da85e5e5SVinicius Costa Gomes 			conn->sec_level = conn->pending_sec_level;
3578abf76badSMarcel Holtmann 
3579914a6ffeSMarcel Holtmann 			/* P-256 authentication key implies FIPS */
3580914a6ffeSMarcel Holtmann 			if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256)
35814dae2798SJohan Hedberg 				set_bit(HCI_CONN_FIPS, &conn->flags);
3582914a6ffeSMarcel Holtmann 
3583abf76badSMarcel Holtmann 			if ((conn->type == ACL_LINK && ev->encrypt == 0x02) ||
3584abf76badSMarcel Holtmann 			    conn->type == LE_LINK)
3585abf76badSMarcel Holtmann 				set_bit(HCI_CONN_AES_CCM, &conn->flags);
3586abf76badSMarcel Holtmann 		} else {
35874dae2798SJohan Hedberg 			clear_bit(HCI_CONN_ENCRYPT, &conn->flags);
3588abf76badSMarcel Holtmann 			clear_bit(HCI_CONN_AES_CCM, &conn->flags);
3589abf76badSMarcel Holtmann 		}
3590a9de9248SMarcel Holtmann 	}
3591a9de9248SMarcel Holtmann 
35927ed3fa20SJohan Hedberg 	/* We should disregard the current RPA and generate a new one
35937ed3fa20SJohan Hedberg 	 * whenever the encryption procedure fails.
35947ed3fa20SJohan Hedberg 	 */
3595a73c046aSJaganath Kanakkassery 	if (ev->status && conn->type == LE_LINK) {
3596a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
3597a73c046aSJaganath Kanakkassery 		hci_adv_instances_set_rpa_expired(hdev, true);
3598a73c046aSJaganath Kanakkassery 	}
35997ed3fa20SJohan Hedberg 
360051a8efd7SJohan Hedberg 	clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3601a9de9248SMarcel Holtmann 
36028746f135SLuiz Augusto von Dentz 	/* Check link security requirements are met */
36038746f135SLuiz Augusto von Dentz 	if (!hci_conn_check_link_mode(conn))
36048746f135SLuiz Augusto von Dentz 		ev->status = HCI_ERROR_AUTH_FAILURE;
36058746f135SLuiz Augusto von Dentz 
3606a7d7723aSGustavo Padovan 	if (ev->status && conn->state == BT_CONNECTED) {
3607160b9251SSzymon Janc 		if (ev->status == HCI_ERROR_PIN_OR_KEY_MISSING)
3608160b9251SSzymon Janc 			set_bit(HCI_CONN_AUTH_FAILURE, &conn->flags);
3609160b9251SSzymon Janc 
36108746f135SLuiz Augusto von Dentz 		/* Notify upper layers so they can cleanup before
36118746f135SLuiz Augusto von Dentz 		 * disconnecting.
361240b552aaSMarcel Holtmann 		 */
36138746f135SLuiz Augusto von Dentz 		hci_encrypt_cfm(conn, ev->status);
36148746f135SLuiz Augusto von Dentz 		hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
361540b552aaSMarcel Holtmann 		hci_conn_drop(conn);
361640b552aaSMarcel Holtmann 		goto unlock;
361740b552aaSMarcel Holtmann 	}
361840b552aaSMarcel Holtmann 
3619821f3766SJohan Hedberg 	/* Try reading the encryption key size for encrypted ACL links */
3620821f3766SJohan Hedberg 	if (!ev->status && ev->encrypt && conn->type == ACL_LINK) {
3621821f3766SJohan Hedberg 		struct hci_cp_read_enc_key_size cp;
3622821f3766SJohan Hedberg 
3623821f3766SJohan Hedberg 		/* Only send HCI_Read_Encryption_Key_Size if the
3624821f3766SJohan Hedberg 		 * controller really supports it. If it doesn't, assume
3625821f3766SJohan Hedberg 		 * the default size (16).
3626821f3766SJohan Hedberg 		 */
362762e3a7cbSLuiz Augusto von Dentz 		if (!read_key_size_capable(hdev)) {
3628821f3766SJohan Hedberg 			conn->enc_key_size = HCI_LINK_KEY_SIZE;
3629821f3766SJohan Hedberg 			goto notify;
3630821f3766SJohan Hedberg 		}
3631821f3766SJohan Hedberg 
3632821f3766SJohan Hedberg 		cp.handle = cpu_to_le16(conn->handle);
3633278d933eSBrian Gix 		if (hci_send_cmd(hdev, HCI_OP_READ_ENC_KEY_SIZE,
3634278d933eSBrian Gix 				 sizeof(cp), &cp)) {
36352064ee33SMarcel Holtmann 			bt_dev_err(hdev, "sending read key size failed");
3636821f3766SJohan Hedberg 			conn->enc_key_size = HCI_LINK_KEY_SIZE;
3637821f3766SJohan Hedberg 			goto notify;
3638821f3766SJohan Hedberg 		}
3639821f3766SJohan Hedberg 
3640821f3766SJohan Hedberg 		goto unlock;
3641821f3766SJohan Hedberg 	}
3642821f3766SJohan Hedberg 
3643302975cbSSpoorthi Ravishankar Koppad 	/* Set the default Authenticated Payload Timeout after
3644302975cbSSpoorthi Ravishankar Koppad 	 * an LE Link is established. As per Core Spec v5.0, Vol 2, Part B
3645302975cbSSpoorthi Ravishankar Koppad 	 * Section 3.3, the HCI command WRITE_AUTH_PAYLOAD_TIMEOUT should be
3646302975cbSSpoorthi Ravishankar Koppad 	 * sent when the link is active and Encryption is enabled, the conn
3647302975cbSSpoorthi Ravishankar Koppad 	 * type can be either LE or ACL and controller must support LMP Ping.
3648302975cbSSpoorthi Ravishankar Koppad 	 * Ensure for AES-CCM encryption as well.
3649302975cbSSpoorthi Ravishankar Koppad 	 */
3650302975cbSSpoorthi Ravishankar Koppad 	if (test_bit(HCI_CONN_ENCRYPT, &conn->flags) &&
3651302975cbSSpoorthi Ravishankar Koppad 	    test_bit(HCI_CONN_AES_CCM, &conn->flags) &&
3652302975cbSSpoorthi Ravishankar Koppad 	    ((conn->type == ACL_LINK && lmp_ping_capable(hdev)) ||
3653302975cbSSpoorthi Ravishankar Koppad 	     (conn->type == LE_LINK && (hdev->le_features[0] & HCI_LE_PING)))) {
3654302975cbSSpoorthi Ravishankar Koppad 		struct hci_cp_write_auth_payload_to cp;
3655302975cbSSpoorthi Ravishankar Koppad 
3656302975cbSSpoorthi Ravishankar Koppad 		cp.handle = cpu_to_le16(conn->handle);
3657302975cbSSpoorthi Ravishankar Koppad 		cp.timeout = cpu_to_le16(hdev->auth_payload_timeout);
36587aca0ac4SLuiz Augusto von Dentz 		if (hci_send_cmd(conn->hdev, HCI_OP_WRITE_AUTH_PAYLOAD_TO,
3659399dea9dSLuiz Augusto von Dentz 				 sizeof(cp), &cp))
36607aca0ac4SLuiz Augusto von Dentz 			bt_dev_err(hdev, "write auth payload timeout failed");
3661302975cbSSpoorthi Ravishankar Koppad 	}
3662302975cbSSpoorthi Ravishankar Koppad 
3663821f3766SJohan Hedberg notify:
36643ca44c16SLuiz Augusto von Dentz 	hci_encrypt_cfm(conn, ev->status);
3665a9de9248SMarcel Holtmann 
3666a7d7723aSGustavo Padovan unlock:
3667a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
3668a9de9248SMarcel Holtmann }
3669a9de9248SMarcel Holtmann 
hci_change_link_key_complete_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)36703e54c589SLuiz Augusto von Dentz static void hci_change_link_key_complete_evt(struct hci_dev *hdev, void *data,
3671807deac2SGustavo Padovan 					     struct sk_buff *skb)
3672a9de9248SMarcel Holtmann {
36733e54c589SLuiz Augusto von Dentz 	struct hci_ev_change_link_key_complete *ev = data;
3674a9de9248SMarcel Holtmann 	struct hci_conn *conn;
3675a9de9248SMarcel Holtmann 
36763e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
3677a9de9248SMarcel Holtmann 
3678a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
3679a9de9248SMarcel Holtmann 
3680a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3681a9de9248SMarcel Holtmann 	if (conn) {
3682a9de9248SMarcel Holtmann 		if (!ev->status)
36834dae2798SJohan Hedberg 			set_bit(HCI_CONN_SECURE, &conn->flags);
3684a9de9248SMarcel Holtmann 
368551a8efd7SJohan Hedberg 		clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
3686a9de9248SMarcel Holtmann 
3687a9de9248SMarcel Holtmann 		hci_key_change_cfm(conn, ev->status);
3688a9de9248SMarcel Holtmann 	}
3689a9de9248SMarcel Holtmann 
3690a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
3691a9de9248SMarcel Holtmann }
3692a9de9248SMarcel Holtmann 
hci_remote_features_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)36933e54c589SLuiz Augusto von Dentz static void hci_remote_features_evt(struct hci_dev *hdev, void *data,
3694807deac2SGustavo Padovan 				    struct sk_buff *skb)
3695a9de9248SMarcel Holtmann {
36963e54c589SLuiz Augusto von Dentz 	struct hci_ev_remote_features *ev = data;
3697a9de9248SMarcel Holtmann 	struct hci_conn *conn;
3698a9de9248SMarcel Holtmann 
36993e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
3700a9de9248SMarcel Holtmann 
3701a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
3702a9de9248SMarcel Holtmann 
3703a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3704ccd556feSJohan Hedberg 	if (!conn)
3705ccd556feSJohan Hedberg 		goto unlock;
3706ccd556feSJohan Hedberg 
3707769be974SMarcel Holtmann 	if (!ev->status)
3708cad718edSJohan Hedberg 		memcpy(conn->features[0], ev->features, 8);
3709a9de9248SMarcel Holtmann 
3710ccd556feSJohan Hedberg 	if (conn->state != BT_CONFIG)
3711ccd556feSJohan Hedberg 		goto unlock;
3712ccd556feSJohan Hedberg 
3713ac363cf9SSzymon Janc 	if (!ev->status && lmp_ext_feat_capable(hdev) &&
3714ac363cf9SSzymon Janc 	    lmp_ext_feat_capable(conn)) {
3715769be974SMarcel Holtmann 		struct hci_cp_read_remote_ext_features cp;
3716769be974SMarcel Holtmann 		cp.handle = ev->handle;
3717769be974SMarcel Holtmann 		cp.page = 0x01;
3718ccd556feSJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
3719769be974SMarcel Holtmann 			     sizeof(cp), &cp);
3720392599b9SJohan Hedberg 		goto unlock;
3721392599b9SJohan Hedberg 	}
3722392599b9SJohan Hedberg 
3723671267bfSJohan Hedberg 	if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
3724127178d2SJohan Hedberg 		struct hci_cp_remote_name_req cp;
3725127178d2SJohan Hedberg 		memset(&cp, 0, sizeof(cp));
3726127178d2SJohan Hedberg 		bacpy(&cp.bdaddr, &conn->dst);
3727127178d2SJohan Hedberg 		cp.pscan_rep_mode = 0x02;
3728127178d2SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
37290b3df53cSLuiz Augusto von Dentz 	} else {
37301c6ed31bSYu Liu 		mgmt_device_connected(hdev, conn, NULL, 0);
37310b3df53cSLuiz Augusto von Dentz 	}
3732392599b9SJohan Hedberg 
3733127178d2SJohan Hedberg 	if (!hci_outgoing_auth_needed(hdev, conn)) {
3734769be974SMarcel Holtmann 		conn->state = BT_CONNECTED;
3735539c496dSJohan Hedberg 		hci_connect_cfm(conn, ev->status);
373676a68ba0SDavid Herrmann 		hci_conn_drop(conn);
3737769be974SMarcel Holtmann 	}
3738769be974SMarcel Holtmann 
3739ccd556feSJohan Hedberg unlock:
3740a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
3741a9de9248SMarcel Holtmann }
3742a9de9248SMarcel Holtmann 
handle_cmd_cnt_and_timer(struct hci_dev * hdev,u8 ncmd)3743ecb71f25SKiran K static inline void handle_cmd_cnt_and_timer(struct hci_dev *hdev, u8 ncmd)
3744de75cd0dSManish Mandlik {
3745de75cd0dSManish Mandlik 	cancel_delayed_work(&hdev->cmd_timer);
3746de75cd0dSManish Mandlik 
3747deee93d1STetsuo Handa 	rcu_read_lock();
3748de75cd0dSManish Mandlik 	if (!test_bit(HCI_RESET, &hdev->flags)) {
3749de75cd0dSManish Mandlik 		if (ncmd) {
3750de75cd0dSManish Mandlik 			cancel_delayed_work(&hdev->ncmd_timer);
3751de75cd0dSManish Mandlik 			atomic_set(&hdev->cmd_cnt, 1);
3752de75cd0dSManish Mandlik 		} else {
3753877afadaSSchspa Shi 			if (!hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
3754deee93d1STetsuo Handa 				queue_delayed_work(hdev->workqueue, &hdev->ncmd_timer,
3755de75cd0dSManish Mandlik 						   HCI_NCMD_TIMEOUT);
3756de75cd0dSManish Mandlik 		}
3757de75cd0dSManish Mandlik 	}
3758deee93d1STetsuo Handa 	rcu_read_unlock();
3759de75cd0dSManish Mandlik }
3760de75cd0dSManish Mandlik 
hci_cc_le_read_buffer_size_v2(struct hci_dev * hdev,void * data,struct sk_buff * skb)376126afbd82SLuiz Augusto von Dentz static u8 hci_cc_le_read_buffer_size_v2(struct hci_dev *hdev, void *data,
376226afbd82SLuiz Augusto von Dentz 					struct sk_buff *skb)
376326afbd82SLuiz Augusto von Dentz {
376426afbd82SLuiz Augusto von Dentz 	struct hci_rp_le_read_buffer_size_v2 *rp = data;
376526afbd82SLuiz Augusto von Dentz 
376626afbd82SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
376726afbd82SLuiz Augusto von Dentz 
376826afbd82SLuiz Augusto von Dentz 	if (rp->status)
376926afbd82SLuiz Augusto von Dentz 		return rp->status;
377026afbd82SLuiz Augusto von Dentz 
377126afbd82SLuiz Augusto von Dentz 	hdev->le_mtu   = __le16_to_cpu(rp->acl_mtu);
377226afbd82SLuiz Augusto von Dentz 	hdev->le_pkts  = rp->acl_max_pkt;
377326afbd82SLuiz Augusto von Dentz 	hdev->iso_mtu  = __le16_to_cpu(rp->iso_mtu);
377426afbd82SLuiz Augusto von Dentz 	hdev->iso_pkts = rp->iso_max_pkt;
377526afbd82SLuiz Augusto von Dentz 
377626afbd82SLuiz Augusto von Dentz 	hdev->le_cnt  = hdev->le_pkts;
377726afbd82SLuiz Augusto von Dentz 	hdev->iso_cnt = hdev->iso_pkts;
377826afbd82SLuiz Augusto von Dentz 
377926afbd82SLuiz Augusto von Dentz 	BT_DBG("%s acl mtu %d:%d iso mtu %d:%d", hdev->name, hdev->acl_mtu,
378026afbd82SLuiz Augusto von Dentz 	       hdev->acl_pkts, hdev->iso_mtu, hdev->iso_pkts);
378126afbd82SLuiz Augusto von Dentz 
3782ad3f7986SSungwoo Kim 	if (hdev->le_mtu && hdev->le_mtu < HCI_MIN_LE_MTU)
3783ad3f7986SSungwoo Kim 		return HCI_ERROR_INVALID_PARAMETERS;
3784ad3f7986SSungwoo Kim 
378526afbd82SLuiz Augusto von Dentz 	return rp->status;
378626afbd82SLuiz Augusto von Dentz }
378726afbd82SLuiz Augusto von Dentz 
hci_unbound_cis_failed(struct hci_dev * hdev,u8 cig,u8 status)378866dee215SPauli Virtanen static void hci_unbound_cis_failed(struct hci_dev *hdev, u8 cig, u8 status)
378966dee215SPauli Virtanen {
379066dee215SPauli Virtanen 	struct hci_conn *conn, *tmp;
379166dee215SPauli Virtanen 
379266dee215SPauli Virtanen 	lockdep_assert_held(&hdev->lock);
379366dee215SPauli Virtanen 
379466dee215SPauli Virtanen 	list_for_each_entry_safe(conn, tmp, &hdev->conn_hash.list, list) {
379566dee215SPauli Virtanen 		if (conn->type != ISO_LINK || !bacmp(&conn->dst, BDADDR_ANY) ||
379666dee215SPauli Virtanen 		    conn->state == BT_OPEN || conn->iso_qos.ucast.cig != cig)
379766dee215SPauli Virtanen 			continue;
379866dee215SPauli Virtanen 
379966dee215SPauli Virtanen 		if (HCI_CONN_HANDLE_UNSET(conn->handle))
380066dee215SPauli Virtanen 			hci_conn_failed(conn, status);
380166dee215SPauli Virtanen 	}
380266dee215SPauli Virtanen }
380366dee215SPauli Virtanen 
hci_cc_le_set_cig_params(struct hci_dev * hdev,void * data,struct sk_buff * skb)380426afbd82SLuiz Augusto von Dentz static u8 hci_cc_le_set_cig_params(struct hci_dev *hdev, void *data,
380526afbd82SLuiz Augusto von Dentz 				   struct sk_buff *skb)
380626afbd82SLuiz Augusto von Dentz {
380726afbd82SLuiz Augusto von Dentz 	struct hci_rp_le_set_cig_params *rp = data;
380871e95884SPauli Virtanen 	struct hci_cp_le_set_cig_params *cp;
380926afbd82SLuiz Augusto von Dentz 	struct hci_conn *conn;
381071e95884SPauli Virtanen 	u8 status = rp->status;
38117f74563eSPauli Virtanen 	bool pending = false;
381271e95884SPauli Virtanen 	int i;
381326afbd82SLuiz Augusto von Dentz 
381426afbd82SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
381526afbd82SLuiz Augusto von Dentz 
381671e95884SPauli Virtanen 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_CIG_PARAMS);
3817db9cbcadSPauli Virtanen 	if (!rp->status && (!cp || rp->num_handles != cp->num_cis ||
3818db9cbcadSPauli Virtanen 			    rp->cig_id != cp->cig_id)) {
381971e95884SPauli Virtanen 		bt_dev_err(hdev, "unexpected Set CIG Parameters response data");
382071e95884SPauli Virtanen 		status = HCI_ERROR_UNSPECIFIED;
382171e95884SPauli Virtanen 	}
382271e95884SPauli Virtanen 
382326afbd82SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
382426afbd82SLuiz Augusto von Dentz 
382566dee215SPauli Virtanen 	/* BLUETOOTH CORE SPECIFICATION Version 5.4 | Vol 4, Part E page 2554
382666dee215SPauli Virtanen 	 *
382766dee215SPauli Virtanen 	 * If the Status return parameter is non-zero, then the state of the CIG
382866dee215SPauli Virtanen 	 * and its CIS configurations shall not be changed by the command. If
382966dee215SPauli Virtanen 	 * the CIG did not already exist, it shall not be created.
383066dee215SPauli Virtanen 	 */
383171e95884SPauli Virtanen 	if (status) {
383266dee215SPauli Virtanen 		/* Keep current configuration, fail only the unbound CIS */
383366dee215SPauli Virtanen 		hci_unbound_cis_failed(hdev, rp->cig_id, status);
383426afbd82SLuiz Augusto von Dentz 		goto unlock;
383526afbd82SLuiz Augusto von Dentz 	}
383626afbd82SLuiz Augusto von Dentz 
383771e95884SPauli Virtanen 	/* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E page 2553
383871e95884SPauli Virtanen 	 *
383971e95884SPauli Virtanen 	 * If the Status return parameter is zero, then the Controller shall
384071e95884SPauli Virtanen 	 * set the Connection_Handle arrayed return parameter to the connection
384171e95884SPauli Virtanen 	 * handle(s) corresponding to the CIS configurations specified in
384271e95884SPauli Virtanen 	 * the CIS_IDs command parameter, in the same order.
384371e95884SPauli Virtanen 	 */
384471e95884SPauli Virtanen 	for (i = 0; i < rp->num_handles; ++i) {
384571e95884SPauli Virtanen 		conn = hci_conn_hash_lookup_cis(hdev, NULL, 0, rp->cig_id,
384671e95884SPauli Virtanen 						cp->cis[i].cis_id);
384771e95884SPauli Virtanen 		if (!conn || !bacmp(&conn->dst, BDADDR_ANY))
384826afbd82SLuiz Augusto von Dentz 			continue;
384926afbd82SLuiz Augusto von Dentz 
385071e95884SPauli Virtanen 		if (conn->state != BT_BOUND && conn->state != BT_CONNECT)
385171e95884SPauli Virtanen 			continue;
385271e95884SPauli Virtanen 
385316e3b642SLuiz Augusto von Dentz 		if (hci_conn_set_handle(conn, __le16_to_cpu(rp->handle[i])))
385416e3b642SLuiz Augusto von Dentz 			continue;
385526afbd82SLuiz Augusto von Dentz 
38567f74563eSPauli Virtanen 		if (conn->state == BT_CONNECT)
38577f74563eSPauli Virtanen 			pending = true;
3858e9d50f76SLuiz Augusto von Dentz 	}
385926afbd82SLuiz Augusto von Dentz 
386026afbd82SLuiz Augusto von Dentz unlock:
38617f74563eSPauli Virtanen 	if (pending)
38627f74563eSPauli Virtanen 		hci_le_create_cis_pending(hdev);
38637f74563eSPauli Virtanen 
386426afbd82SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
386526afbd82SLuiz Augusto von Dentz 
386626afbd82SLuiz Augusto von Dentz 	return rp->status;
386726afbd82SLuiz Augusto von Dentz }
386826afbd82SLuiz Augusto von Dentz 
hci_cc_le_setup_iso_path(struct hci_dev * hdev,void * data,struct sk_buff * skb)386926afbd82SLuiz Augusto von Dentz static u8 hci_cc_le_setup_iso_path(struct hci_dev *hdev, void *data,
387026afbd82SLuiz Augusto von Dentz 				   struct sk_buff *skb)
387126afbd82SLuiz Augusto von Dentz {
387226afbd82SLuiz Augusto von Dentz 	struct hci_rp_le_setup_iso_path *rp = data;
387326afbd82SLuiz Augusto von Dentz 	struct hci_cp_le_setup_iso_path *cp;
387426afbd82SLuiz Augusto von Dentz 	struct hci_conn *conn;
387526afbd82SLuiz Augusto von Dentz 
387626afbd82SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
387726afbd82SLuiz Augusto von Dentz 
387826afbd82SLuiz Augusto von Dentz 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SETUP_ISO_PATH);
387926afbd82SLuiz Augusto von Dentz 	if (!cp)
388026afbd82SLuiz Augusto von Dentz 		return rp->status;
388126afbd82SLuiz Augusto von Dentz 
388226afbd82SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
388326afbd82SLuiz Augusto von Dentz 
388426afbd82SLuiz Augusto von Dentz 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
388526afbd82SLuiz Augusto von Dentz 	if (!conn)
388626afbd82SLuiz Augusto von Dentz 		goto unlock;
388726afbd82SLuiz Augusto von Dentz 
388826afbd82SLuiz Augusto von Dentz 	if (rp->status) {
388926afbd82SLuiz Augusto von Dentz 		hci_connect_cfm(conn, rp->status);
389026afbd82SLuiz Augusto von Dentz 		hci_conn_del(conn);
389126afbd82SLuiz Augusto von Dentz 		goto unlock;
389226afbd82SLuiz Augusto von Dentz 	}
389326afbd82SLuiz Augusto von Dentz 
389426afbd82SLuiz Augusto von Dentz 	switch (cp->direction) {
389526afbd82SLuiz Augusto von Dentz 	/* Input (Host to Controller) */
389626afbd82SLuiz Augusto von Dentz 	case 0x00:
389726afbd82SLuiz Augusto von Dentz 		/* Only confirm connection if output only */
38980fe8c8d0SIulia Tanasescu 		if (conn->iso_qos.ucast.out.sdu && !conn->iso_qos.ucast.in.sdu)
389926afbd82SLuiz Augusto von Dentz 			hci_connect_cfm(conn, rp->status);
390026afbd82SLuiz Augusto von Dentz 		break;
390126afbd82SLuiz Augusto von Dentz 	/* Output (Controller to Host) */
390226afbd82SLuiz Augusto von Dentz 	case 0x01:
390326afbd82SLuiz Augusto von Dentz 		/* Confirm connection since conn->iso_qos is always configured
390426afbd82SLuiz Augusto von Dentz 		 * last.
390526afbd82SLuiz Augusto von Dentz 		 */
390626afbd82SLuiz Augusto von Dentz 		hci_connect_cfm(conn, rp->status);
39070b3df53cSLuiz Augusto von Dentz 
39080b3df53cSLuiz Augusto von Dentz 		/* Notify device connected in case it is a BIG Sync */
39090b3df53cSLuiz Augusto von Dentz 		if (!rp->status && test_bit(HCI_CONN_BIG_SYNC, &conn->flags))
39100b3df53cSLuiz Augusto von Dentz 			mgmt_device_connected(hdev, conn, NULL, 0);
39110b3df53cSLuiz Augusto von Dentz 
391226afbd82SLuiz Augusto von Dentz 		break;
391326afbd82SLuiz Augusto von Dentz 	}
391426afbd82SLuiz Augusto von Dentz 
391526afbd82SLuiz Augusto von Dentz unlock:
391626afbd82SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
391726afbd82SLuiz Augusto von Dentz 	return rp->status;
391826afbd82SLuiz Augusto von Dentz }
391926afbd82SLuiz Augusto von Dentz 
hci_cs_le_create_big(struct hci_dev * hdev,u8 status)3920eca0ae4aSLuiz Augusto von Dentz static void hci_cs_le_create_big(struct hci_dev *hdev, u8 status)
3921eca0ae4aSLuiz Augusto von Dentz {
3922eca0ae4aSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
3923eca0ae4aSLuiz Augusto von Dentz }
3924eca0ae4aSLuiz Augusto von Dentz 
hci_cc_set_per_adv_param(struct hci_dev * hdev,void * data,struct sk_buff * skb)3925eca0ae4aSLuiz Augusto von Dentz static u8 hci_cc_set_per_adv_param(struct hci_dev *hdev, void *data,
3926eca0ae4aSLuiz Augusto von Dentz 				   struct sk_buff *skb)
3927eca0ae4aSLuiz Augusto von Dentz {
3928eca0ae4aSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
3929eca0ae4aSLuiz Augusto von Dentz 	struct hci_cp_le_set_per_adv_params *cp;
3930eca0ae4aSLuiz Augusto von Dentz 
3931eca0ae4aSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
3932eca0ae4aSLuiz Augusto von Dentz 
3933eca0ae4aSLuiz Augusto von Dentz 	if (rp->status)
3934eca0ae4aSLuiz Augusto von Dentz 		return rp->status;
3935eca0ae4aSLuiz Augusto von Dentz 
3936eca0ae4aSLuiz Augusto von Dentz 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_PER_ADV_PARAMS);
3937eca0ae4aSLuiz Augusto von Dentz 	if (!cp)
3938eca0ae4aSLuiz Augusto von Dentz 		return rp->status;
3939eca0ae4aSLuiz Augusto von Dentz 
3940eca0ae4aSLuiz Augusto von Dentz 	/* TODO: set the conn state */
3941eca0ae4aSLuiz Augusto von Dentz 	return rp->status;
3942eca0ae4aSLuiz Augusto von Dentz }
3943eca0ae4aSLuiz Augusto von Dentz 
hci_cc_le_set_per_adv_enable(struct hci_dev * hdev,void * data,struct sk_buff * skb)3944eca0ae4aSLuiz Augusto von Dentz static u8 hci_cc_le_set_per_adv_enable(struct hci_dev *hdev, void *data,
3945eca0ae4aSLuiz Augusto von Dentz 				       struct sk_buff *skb)
3946eca0ae4aSLuiz Augusto von Dentz {
3947eca0ae4aSLuiz Augusto von Dentz 	struct hci_ev_status *rp = data;
39486a42e9bfSIulia Tanasescu 	struct hci_cp_le_set_per_adv_enable *cp;
39496a42e9bfSIulia Tanasescu 	struct adv_info *adv = NULL, *n;
39506a42e9bfSIulia Tanasescu 	u8 per_adv_cnt = 0;
3951eca0ae4aSLuiz Augusto von Dentz 
3952eca0ae4aSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
3953eca0ae4aSLuiz Augusto von Dentz 
3954eca0ae4aSLuiz Augusto von Dentz 	if (rp->status)
3955eca0ae4aSLuiz Augusto von Dentz 		return rp->status;
3956eca0ae4aSLuiz Augusto von Dentz 
39576a42e9bfSIulia Tanasescu 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_PER_ADV_ENABLE);
39586a42e9bfSIulia Tanasescu 	if (!cp)
3959eca0ae4aSLuiz Augusto von Dentz 		return rp->status;
3960eca0ae4aSLuiz Augusto von Dentz 
3961eca0ae4aSLuiz Augusto von Dentz 	hci_dev_lock(hdev);
3962eca0ae4aSLuiz Augusto von Dentz 
39636a42e9bfSIulia Tanasescu 	adv = hci_find_adv_instance(hdev, cp->handle);
3964eca0ae4aSLuiz Augusto von Dentz 
39656a42e9bfSIulia Tanasescu 	if (cp->enable) {
39666a42e9bfSIulia Tanasescu 		hci_dev_set_flag(hdev, HCI_LE_PER_ADV);
39676a42e9bfSIulia Tanasescu 
39686a42e9bfSIulia Tanasescu 		if (adv)
39696a42e9bfSIulia Tanasescu 			adv->enabled = true;
39706a42e9bfSIulia Tanasescu 	} else {
39716a42e9bfSIulia Tanasescu 		/* If just one instance was disabled check if there are
39726a42e9bfSIulia Tanasescu 		 * any other instance enabled before clearing HCI_LE_PER_ADV.
39736a42e9bfSIulia Tanasescu 		 * The current periodic adv instance will be marked as
39746a42e9bfSIulia Tanasescu 		 * disabled once extended advertising is also disabled.
39756a42e9bfSIulia Tanasescu 		 */
39766a42e9bfSIulia Tanasescu 		list_for_each_entry_safe(adv, n, &hdev->adv_instances,
39776a42e9bfSIulia Tanasescu 					 list) {
39786a42e9bfSIulia Tanasescu 			if (adv->periodic && adv->enabled)
39796a42e9bfSIulia Tanasescu 				per_adv_cnt++;
39806a42e9bfSIulia Tanasescu 		}
39816a42e9bfSIulia Tanasescu 
39826a42e9bfSIulia Tanasescu 		if (per_adv_cnt > 1)
39836a42e9bfSIulia Tanasescu 			goto unlock;
39846a42e9bfSIulia Tanasescu 
39856a42e9bfSIulia Tanasescu 		hci_dev_clear_flag(hdev, HCI_LE_PER_ADV);
39866a42e9bfSIulia Tanasescu 	}
39876a42e9bfSIulia Tanasescu 
39886a42e9bfSIulia Tanasescu unlock:
3989eca0ae4aSLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
3990eca0ae4aSLuiz Augusto von Dentz 
3991eca0ae4aSLuiz Augusto von Dentz 	return rp->status;
3992eca0ae4aSLuiz Augusto von Dentz }
3993eca0ae4aSLuiz Augusto von Dentz 
3994c8992cffSLuiz Augusto von Dentz #define HCI_CC_VL(_op, _func, _min, _max) \
3995c8992cffSLuiz Augusto von Dentz { \
3996c8992cffSLuiz Augusto von Dentz 	.op = _op, \
3997c8992cffSLuiz Augusto von Dentz 	.func = _func, \
3998c8992cffSLuiz Augusto von Dentz 	.min_len = _min, \
3999c8992cffSLuiz Augusto von Dentz 	.max_len = _max, \
4000c8992cffSLuiz Augusto von Dentz }
4001c8992cffSLuiz Augusto von Dentz 
4002c8992cffSLuiz Augusto von Dentz #define HCI_CC(_op, _func, _len) \
4003c8992cffSLuiz Augusto von Dentz 	HCI_CC_VL(_op, _func, _len, _len)
4004c8992cffSLuiz Augusto von Dentz 
4005c8992cffSLuiz Augusto von Dentz #define HCI_CC_STATUS(_op, _func) \
4006c8992cffSLuiz Augusto von Dentz 	HCI_CC(_op, _func, sizeof(struct hci_ev_status))
4007c8992cffSLuiz Augusto von Dentz 
4008c8992cffSLuiz Augusto von Dentz static const struct hci_cc {
4009c8992cffSLuiz Augusto von Dentz 	u16  op;
4010c8992cffSLuiz Augusto von Dentz 	u8 (*func)(struct hci_dev *hdev, void *data, struct sk_buff *skb);
4011c8992cffSLuiz Augusto von Dentz 	u16  min_len;
4012c8992cffSLuiz Augusto von Dentz 	u16  max_len;
4013c8992cffSLuiz Augusto von Dentz } hci_cc_table[] = {
4014c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_INQUIRY_CANCEL, hci_cc_inquiry_cancel),
4015c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_PERIODIC_INQ, hci_cc_periodic_inq),
4016c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_EXIT_PERIODIC_INQ, hci_cc_exit_periodic_inq),
4017c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_REMOTE_NAME_REQ_CANCEL,
4018c8992cffSLuiz Augusto von Dentz 		      hci_cc_remote_name_req_cancel),
4019c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_ROLE_DISCOVERY, hci_cc_role_discovery,
4020c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_role_discovery)),
4021c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LINK_POLICY, hci_cc_read_link_policy,
4022c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_link_policy)),
4023c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_WRITE_LINK_POLICY, hci_cc_write_link_policy,
4024c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_write_link_policy)),
4025c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_DEF_LINK_POLICY, hci_cc_read_def_link_policy,
4026c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_def_link_policy)),
4027c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_DEF_LINK_POLICY,
4028c8992cffSLuiz Augusto von Dentz 		      hci_cc_write_def_link_policy),
4029c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_RESET, hci_cc_reset),
4030c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_STORED_LINK_KEY, hci_cc_read_stored_link_key,
4031c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_stored_link_key)),
4032c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_DELETE_STORED_LINK_KEY, hci_cc_delete_stored_link_key,
4033c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_delete_stored_link_key)),
4034c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_LOCAL_NAME, hci_cc_write_local_name),
4035c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_NAME, hci_cc_read_local_name,
4036c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_name)),
4037c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_AUTH_ENABLE, hci_cc_write_auth_enable),
4038c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_ENCRYPT_MODE, hci_cc_write_encrypt_mode),
4039c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_SCAN_ENABLE, hci_cc_write_scan_enable),
4040c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_SET_EVENT_FLT, hci_cc_set_event_filter),
4041c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_CLASS_OF_DEV, hci_cc_read_class_of_dev,
4042c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_class_of_dev)),
4043c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_CLASS_OF_DEV, hci_cc_write_class_of_dev),
4044c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_VOICE_SETTING, hci_cc_read_voice_setting,
4045c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_voice_setting)),
4046c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_VOICE_SETTING, hci_cc_write_voice_setting),
4047c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_NUM_SUPPORTED_IAC, hci_cc_read_num_supported_iac,
4048c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_num_supported_iac)),
4049c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_SSP_MODE, hci_cc_write_ssp_mode),
4050c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_SC_SUPPORT, hci_cc_write_sc_support),
4051c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_AUTH_PAYLOAD_TO, hci_cc_read_auth_payload_timeout,
4052c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_auth_payload_to)),
4053c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_WRITE_AUTH_PAYLOAD_TO, hci_cc_write_auth_payload_timeout,
4054c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_write_auth_payload_to)),
4055c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_VERSION, hci_cc_read_local_version,
4056c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_version)),
4057c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_COMMANDS, hci_cc_read_local_commands,
4058c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_commands)),
4059c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_FEATURES, hci_cc_read_local_features,
4060c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_features)),
4061c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_EXT_FEATURES, hci_cc_read_local_ext_features,
4062c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_ext_features)),
4063c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_BUFFER_SIZE, hci_cc_read_buffer_size,
4064c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_buffer_size)),
4065c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_BD_ADDR, hci_cc_read_bd_addr,
4066c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_bd_addr)),
4067c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_PAIRING_OPTS, hci_cc_read_local_pairing_opts,
4068c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_pairing_opts)),
4069c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_PAGE_SCAN_ACTIVITY, hci_cc_read_page_scan_activity,
4070c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_page_scan_activity)),
4071c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_PAGE_SCAN_ACTIVITY,
4072c8992cffSLuiz Augusto von Dentz 		      hci_cc_write_page_scan_activity),
4073c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_PAGE_SCAN_TYPE, hci_cc_read_page_scan_type,
4074c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_page_scan_type)),
4075c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_PAGE_SCAN_TYPE, hci_cc_write_page_scan_type),
4076c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_CLOCK, hci_cc_read_clock,
4077c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_clock)),
4078278d933eSBrian Gix 	HCI_CC(HCI_OP_READ_ENC_KEY_SIZE, hci_cc_read_enc_key_size,
4079278d933eSBrian Gix 	       sizeof(struct hci_rp_read_enc_key_size)),
4080c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_INQ_RSP_TX_POWER, hci_cc_read_inq_rsp_tx_power,
4081c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_inq_rsp_tx_power)),
4082c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_DEF_ERR_DATA_REPORTING,
4083c8992cffSLuiz Augusto von Dentz 	       hci_cc_read_def_err_data_reporting,
4084c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_def_err_data_reporting)),
4085c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_DEF_ERR_DATA_REPORTING,
4086c8992cffSLuiz Augusto von Dentz 		      hci_cc_write_def_err_data_reporting),
4087c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_PIN_CODE_REPLY, hci_cc_pin_code_reply,
4088c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_pin_code_reply)),
4089c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_PIN_CODE_NEG_REPLY, hci_cc_pin_code_neg_reply,
4090c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_pin_code_neg_reply)),
4091c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_OOB_DATA, hci_cc_read_local_oob_data,
4092c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_oob_data)),
4093c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_LOCAL_OOB_EXT_DATA, hci_cc_read_local_oob_ext_data,
4094c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_local_oob_ext_data)),
4095c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_BUFFER_SIZE, hci_cc_le_read_buffer_size,
4096c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_buffer_size)),
4097c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_LOCAL_FEATURES, hci_cc_le_read_local_features,
4098c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_local_features)),
4099c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_ADV_TX_POWER, hci_cc_le_read_adv_tx_power,
4100c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_adv_tx_power)),
4101c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_USER_CONFIRM_REPLY, hci_cc_user_confirm_reply,
4102c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_user_confirm_reply)),
4103c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_USER_CONFIRM_NEG_REPLY, hci_cc_user_confirm_neg_reply,
4104c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_user_confirm_reply)),
4105c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_USER_PASSKEY_REPLY, hci_cc_user_passkey_reply,
4106c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_user_confirm_reply)),
4107c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_USER_PASSKEY_NEG_REPLY, hci_cc_user_passkey_neg_reply,
4108c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_user_confirm_reply)),
4109c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_RANDOM_ADDR, hci_cc_le_set_random_addr),
4110c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_ADV_ENABLE, hci_cc_le_set_adv_enable),
4111c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_SCAN_PARAM, hci_cc_le_set_scan_param),
4112c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_SCAN_ENABLE, hci_cc_le_set_scan_enable),
4113c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_ACCEPT_LIST_SIZE,
4114c8992cffSLuiz Augusto von Dentz 	       hci_cc_le_read_accept_list_size,
4115c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_accept_list_size)),
4116c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_CLEAR_ACCEPT_LIST, hci_cc_le_clear_accept_list),
4117c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_ADD_TO_ACCEPT_LIST,
4118c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_add_to_accept_list),
4119c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_DEL_FROM_ACCEPT_LIST,
4120c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_del_from_accept_list),
4121c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_SUPPORTED_STATES, hci_cc_le_read_supported_states,
4122c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_supported_states)),
4123c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_DEF_DATA_LEN, hci_cc_le_read_def_data_len,
4124c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_def_data_len)),
4125c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_WRITE_DEF_DATA_LEN,
4126c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_write_def_data_len),
4127c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_ADD_TO_RESOLV_LIST,
4128c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_add_to_resolv_list),
4129c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_DEL_FROM_RESOLV_LIST,
4130c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_del_from_resolv_list),
4131c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_CLEAR_RESOLV_LIST,
4132c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_clear_resolv_list),
4133c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_RESOLV_LIST_SIZE, hci_cc_le_read_resolv_list_size,
4134c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_resolv_list_size)),
4135c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_ADDR_RESOLV_ENABLE,
4136c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_set_addr_resolution_enable),
4137c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_MAX_DATA_LEN, hci_cc_le_read_max_data_len,
4138c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_max_data_len)),
4139c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_LE_HOST_SUPPORTED,
4140c8992cffSLuiz Augusto von Dentz 		      hci_cc_write_le_host_supported),
4141c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_ADV_PARAM, hci_cc_set_adv_param),
4142c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_RSSI, hci_cc_read_rssi,
4143c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_rssi)),
4144c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_READ_TX_POWER, hci_cc_read_tx_power,
4145c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_read_tx_power)),
4146c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_WRITE_SSP_DEBUG_MODE, hci_cc_write_ssp_debug_mode),
4147c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_EXT_SCAN_PARAMS,
4148c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_set_ext_scan_param),
4149c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_EXT_SCAN_ENABLE,
4150c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_set_ext_scan_enable),
4151c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_DEFAULT_PHY, hci_cc_le_set_default_phy),
4152c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_NUM_SUPPORTED_ADV_SETS,
4153c8992cffSLuiz Augusto von Dentz 	       hci_cc_le_read_num_adv_sets,
4154c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_num_supported_adv_sets)),
4155c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_SET_EXT_ADV_PARAMS, hci_cc_set_ext_adv_param,
4156c8992cffSLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_set_ext_adv_params)),
4157c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_EXT_ADV_ENABLE,
4158c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_set_ext_adv_enable),
4159c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_ADV_SET_RAND_ADDR,
4160c8992cffSLuiz Augusto von Dentz 		      hci_cc_le_set_adv_set_random_addr),
4161c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_REMOVE_ADV_SET, hci_cc_le_remove_adv_set),
4162c8992cffSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_CLEAR_ADV_SETS, hci_cc_le_clear_adv_sets),
4163eca0ae4aSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_PER_ADV_PARAMS, hci_cc_set_per_adv_param),
4164eca0ae4aSLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_PER_ADV_ENABLE,
4165eca0ae4aSLuiz Augusto von Dentz 		      hci_cc_le_set_per_adv_enable),
4166c8992cffSLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_TRANSMIT_POWER, hci_cc_le_read_transmit_power,
4167853b70b5SLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_transmit_power)),
416826afbd82SLuiz Augusto von Dentz 	HCI_CC_STATUS(HCI_OP_LE_SET_PRIVACY_MODE, hci_cc_le_set_privacy_mode),
416926afbd82SLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_READ_BUFFER_SIZE_V2, hci_cc_le_read_buffer_size_v2,
417026afbd82SLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_read_buffer_size_v2)),
417126afbd82SLuiz Augusto von Dentz 	HCI_CC_VL(HCI_OP_LE_SET_CIG_PARAMS, hci_cc_le_set_cig_params,
417226afbd82SLuiz Augusto von Dentz 		  sizeof(struct hci_rp_le_set_cig_params), HCI_MAX_EVENT_SIZE),
417326afbd82SLuiz Augusto von Dentz 	HCI_CC(HCI_OP_LE_SETUP_ISO_PATH, hci_cc_le_setup_iso_path,
417426afbd82SLuiz Augusto von Dentz 	       sizeof(struct hci_rp_le_setup_iso_path)),
4175c8992cffSLuiz Augusto von Dentz };
4176c8992cffSLuiz Augusto von Dentz 
hci_cc_func(struct hci_dev * hdev,const struct hci_cc * cc,struct sk_buff * skb)4177c8992cffSLuiz Augusto von Dentz static u8 hci_cc_func(struct hci_dev *hdev, const struct hci_cc *cc,
4178c8992cffSLuiz Augusto von Dentz 		      struct sk_buff *skb)
4179c8992cffSLuiz Augusto von Dentz {
4180c8992cffSLuiz Augusto von Dentz 	void *data;
4181c8992cffSLuiz Augusto von Dentz 
4182c8992cffSLuiz Augusto von Dentz 	if (skb->len < cc->min_len) {
4183c8992cffSLuiz Augusto von Dentz 		bt_dev_err(hdev, "unexpected cc 0x%4.4x length: %u < %u",
4184c8992cffSLuiz Augusto von Dentz 			   cc->op, skb->len, cc->min_len);
4185c8992cffSLuiz Augusto von Dentz 		return HCI_ERROR_UNSPECIFIED;
4186c8992cffSLuiz Augusto von Dentz 	}
4187c8992cffSLuiz Augusto von Dentz 
4188c8992cffSLuiz Augusto von Dentz 	/* Just warn if the length is over max_len size it still be possible to
4189c8992cffSLuiz Augusto von Dentz 	 * partially parse the cc so leave to callback to decide if that is
4190c8992cffSLuiz Augusto von Dentz 	 * acceptable.
4191c8992cffSLuiz Augusto von Dentz 	 */
4192c8992cffSLuiz Augusto von Dentz 	if (skb->len > cc->max_len)
4193c8992cffSLuiz Augusto von Dentz 		bt_dev_warn(hdev, "unexpected cc 0x%4.4x length: %u > %u",
4194c8992cffSLuiz Augusto von Dentz 			    cc->op, skb->len, cc->max_len);
4195c8992cffSLuiz Augusto von Dentz 
4196c8992cffSLuiz Augusto von Dentz 	data = hci_cc_skb_pull(hdev, skb, cc->op, cc->min_len);
4197c8992cffSLuiz Augusto von Dentz 	if (!data)
4198c8992cffSLuiz Augusto von Dentz 		return HCI_ERROR_UNSPECIFIED;
4199c8992cffSLuiz Augusto von Dentz 
4200c8992cffSLuiz Augusto von Dentz 	return cc->func(hdev, data, skb);
4201c8992cffSLuiz Augusto von Dentz }
4202c8992cffSLuiz Augusto von Dentz 
hci_cmd_complete_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb,u16 * opcode,u8 * status,hci_req_complete_t * req_complete,hci_req_complete_skb_t * req_complete_skb)42033e54c589SLuiz Augusto von Dentz static void hci_cmd_complete_evt(struct hci_dev *hdev, void *data,
42043e54c589SLuiz Augusto von Dentz 				 struct sk_buff *skb, u16 *opcode, u8 *status,
4205e6214487SJohan Hedberg 				 hci_req_complete_t *req_complete,
4206e6214487SJohan Hedberg 				 hci_req_complete_skb_t *req_complete_skb)
4207a9de9248SMarcel Holtmann {
42083e54c589SLuiz Augusto von Dentz 	struct hci_ev_cmd_complete *ev = data;
4209c8992cffSLuiz Augusto von Dentz 	int i;
4210e6214487SJohan Hedberg 
4211e6214487SJohan Hedberg 	*opcode = __le16_to_cpu(ev->opcode);
4212a9de9248SMarcel Holtmann 
4213c8992cffSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "opcode 0x%4.4x", *opcode);
4214a9de9248SMarcel Holtmann 
4215c8992cffSLuiz Augusto von Dentz 	for (i = 0; i < ARRAY_SIZE(hci_cc_table); i++) {
4216c8992cffSLuiz Augusto von Dentz 		if (hci_cc_table[i].op == *opcode) {
4217c8992cffSLuiz Augusto von Dentz 			*status = hci_cc_func(hdev, &hci_cc_table[i], skb);
42184d93483bSAndre Guedes 			break;
4219c8992cffSLuiz Augusto von Dentz 		}
4220a9de9248SMarcel Holtmann 	}
4221a9de9248SMarcel Holtmann 
4222afcb3369SHans de Goede 	if (i == ARRAY_SIZE(hci_cc_table)) {
4223afcb3369SHans de Goede 		/* Unknown opcode, assume byte 0 contains the status, so
4224afcb3369SHans de Goede 		 * that e.g. __hci_cmd_sync() properly returns errors
4225afcb3369SHans de Goede 		 * for vendor specific commands send by HCI drivers.
4226afcb3369SHans de Goede 		 * If a vendor doesn't actually follow this convention we may
4227afcb3369SHans de Goede 		 * need to introduce a vendor CC table in order to properly set
4228afcb3369SHans de Goede 		 * the status.
4229afcb3369SHans de Goede 		 */
4230afcb3369SHans de Goede 		*status = skb->data[0];
4231afcb3369SHans de Goede 	}
4232afcb3369SHans de Goede 
4233ecb71f25SKiran K 	handle_cmd_cnt_and_timer(hdev, ev->ncmd);
4234600b2150SJohan Hedberg 
4235e6214487SJohan Hedberg 	hci_req_cmd_complete(hdev, *opcode, *status, req_complete,
4236e6214487SJohan Hedberg 			     req_complete_skb);
42379238f36aSJohan Hedberg 
4238f80c5dadSJoão Paulo Rechi Vita 	if (hci_dev_test_flag(hdev, HCI_CMD_PENDING)) {
4239f80c5dadSJoão Paulo Rechi Vita 		bt_dev_err(hdev,
4240f80c5dadSJoão Paulo Rechi Vita 			   "unexpected event for opcode 0x%4.4x", *opcode);
4241f80c5dadSJoão Paulo Rechi Vita 		return;
4242f80c5dadSJoão Paulo Rechi Vita 	}
4243f80c5dadSJoão Paulo Rechi Vita 
4244600b2150SJohan Hedberg 	if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q))
4245c347b765SGustavo F. Padovan 		queue_work(hdev->workqueue, &hdev->cmd_work);
4246a9de9248SMarcel Holtmann }
4247a9de9248SMarcel Holtmann 
hci_cs_le_create_cis(struct hci_dev * hdev,u8 status)424826afbd82SLuiz Augusto von Dentz static void hci_cs_le_create_cis(struct hci_dev *hdev, u8 status)
424926afbd82SLuiz Augusto von Dentz {
425026afbd82SLuiz Augusto von Dentz 	struct hci_cp_le_create_cis *cp;
42517f74563eSPauli Virtanen 	bool pending = false;
425226afbd82SLuiz Augusto von Dentz 	int i;
425326afbd82SLuiz Augusto von Dentz 
425426afbd82SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
425526afbd82SLuiz Augusto von Dentz 
425626afbd82SLuiz Augusto von Dentz 	if (!status)
425726afbd82SLuiz Augusto von Dentz 		return;
425826afbd82SLuiz Augusto von Dentz 
425926afbd82SLuiz Augusto von Dentz 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CIS);
426026afbd82SLuiz Augusto von Dentz 	if (!cp)
426126afbd82SLuiz Augusto von Dentz 		return;
426226afbd82SLuiz Augusto von Dentz 
426326afbd82SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
426426afbd82SLuiz Augusto von Dentz 
426526afbd82SLuiz Augusto von Dentz 	/* Remove connection if command failed */
426626afbd82SLuiz Augusto von Dentz 	for (i = 0; cp->num_cis; cp->num_cis--, i++) {
426726afbd82SLuiz Augusto von Dentz 		struct hci_conn *conn;
426826afbd82SLuiz Augusto von Dentz 		u16 handle;
426926afbd82SLuiz Augusto von Dentz 
427026afbd82SLuiz Augusto von Dentz 		handle = __le16_to_cpu(cp->cis[i].cis_handle);
427126afbd82SLuiz Augusto von Dentz 
427226afbd82SLuiz Augusto von Dentz 		conn = hci_conn_hash_lookup_handle(hdev, handle);
427326afbd82SLuiz Augusto von Dentz 		if (conn) {
42747f74563eSPauli Virtanen 			if (test_and_clear_bit(HCI_CONN_CREATE_CIS,
42757f74563eSPauli Virtanen 					       &conn->flags))
42767f74563eSPauli Virtanen 				pending = true;
427726afbd82SLuiz Augusto von Dentz 			conn->state = BT_CLOSED;
427826afbd82SLuiz Augusto von Dentz 			hci_connect_cfm(conn, status);
427926afbd82SLuiz Augusto von Dentz 			hci_conn_del(conn);
428026afbd82SLuiz Augusto von Dentz 		}
428126afbd82SLuiz Augusto von Dentz 	}
428226afbd82SLuiz Augusto von Dentz 
42837f74563eSPauli Virtanen 	if (pending)
42847f74563eSPauli Virtanen 		hci_le_create_cis_pending(hdev);
42857f74563eSPauli Virtanen 
428626afbd82SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
428726afbd82SLuiz Augusto von Dentz }
428826afbd82SLuiz Augusto von Dentz 
4289147306ccSLuiz Augusto von Dentz #define HCI_CS(_op, _func) \
4290147306ccSLuiz Augusto von Dentz { \
4291147306ccSLuiz Augusto von Dentz 	.op = _op, \
4292147306ccSLuiz Augusto von Dentz 	.func = _func, \
4293147306ccSLuiz Augusto von Dentz }
4294147306ccSLuiz Augusto von Dentz 
4295147306ccSLuiz Augusto von Dentz static const struct hci_cs {
4296147306ccSLuiz Augusto von Dentz 	u16  op;
4297147306ccSLuiz Augusto von Dentz 	void (*func)(struct hci_dev *hdev, __u8 status);
4298147306ccSLuiz Augusto von Dentz } hci_cs_table[] = {
4299147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_INQUIRY, hci_cs_inquiry),
4300147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_CREATE_CONN, hci_cs_create_conn),
4301147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_DISCONNECT, hci_cs_disconnect),
4302147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_ADD_SCO, hci_cs_add_sco),
4303147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_AUTH_REQUESTED, hci_cs_auth_requested),
4304147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_SET_CONN_ENCRYPT, hci_cs_set_conn_encrypt),
4305147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_REMOTE_NAME_REQ, hci_cs_remote_name_req),
4306147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_READ_REMOTE_FEATURES, hci_cs_read_remote_features),
4307147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_READ_REMOTE_EXT_FEATURES,
4308147306ccSLuiz Augusto von Dentz 	       hci_cs_read_remote_ext_features),
4309147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_SETUP_SYNC_CONN, hci_cs_setup_sync_conn),
4310147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_ENHANCED_SETUP_SYNC_CONN,
4311147306ccSLuiz Augusto von Dentz 	       hci_cs_enhanced_setup_sync_conn),
4312147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_SNIFF_MODE, hci_cs_sniff_mode),
4313147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_EXIT_SNIFF_MODE, hci_cs_exit_sniff_mode),
4314147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_SWITCH_ROLE, hci_cs_switch_role),
4315147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_LE_CREATE_CONN, hci_cs_le_create_conn),
4316147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_LE_READ_REMOTE_FEATURES, hci_cs_le_read_remote_features),
4317147306ccSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_LE_START_ENC, hci_cs_le_start_enc),
431826afbd82SLuiz Augusto von Dentz 	HCI_CS(HCI_OP_LE_EXT_CREATE_CONN, hci_cs_le_ext_create_conn),
431926afbd82SLuiz Augusto von Dentz 	HCI_CS(HCI_OP_LE_CREATE_CIS, hci_cs_le_create_cis),
4320eca0ae4aSLuiz Augusto von Dentz 	HCI_CS(HCI_OP_LE_CREATE_BIG, hci_cs_le_create_big),
4321147306ccSLuiz Augusto von Dentz };
4322147306ccSLuiz Augusto von Dentz 
hci_cmd_status_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb,u16 * opcode,u8 * status,hci_req_complete_t * req_complete,hci_req_complete_skb_t * req_complete_skb)43233e54c589SLuiz Augusto von Dentz static void hci_cmd_status_evt(struct hci_dev *hdev, void *data,
43243e54c589SLuiz Augusto von Dentz 			       struct sk_buff *skb, u16 *opcode, u8 *status,
4325e6214487SJohan Hedberg 			       hci_req_complete_t *req_complete,
4326e6214487SJohan Hedberg 			       hci_req_complete_skb_t *req_complete_skb)
4327a9de9248SMarcel Holtmann {
43283e54c589SLuiz Augusto von Dentz 	struct hci_ev_cmd_status *ev = data;
4329147306ccSLuiz Augusto von Dentz 	int i;
4330a9de9248SMarcel Holtmann 
4331e6214487SJohan Hedberg 	*opcode = __le16_to_cpu(ev->opcode);
4332e6214487SJohan Hedberg 	*status = ev->status;
4333a9de9248SMarcel Holtmann 
4334147306ccSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "opcode 0x%4.4x", *opcode);
4335a9de9248SMarcel Holtmann 
4336147306ccSLuiz Augusto von Dentz 	for (i = 0; i < ARRAY_SIZE(hci_cs_table); i++) {
4337147306ccSLuiz Augusto von Dentz 		if (hci_cs_table[i].op == *opcode) {
4338147306ccSLuiz Augusto von Dentz 			hci_cs_table[i].func(hdev, ev->status);
4339a9de9248SMarcel Holtmann 			break;
4340147306ccSLuiz Augusto von Dentz 		}
4341a9de9248SMarcel Holtmann 	}
4342a9de9248SMarcel Holtmann 
4343ecb71f25SKiran K 	handle_cmd_cnt_and_timer(hdev, ev->ncmd);
4344600b2150SJohan Hedberg 
4345444c6dd5SJohan Hedberg 	/* Indicate request completion if the command failed. Also, if
4346444c6dd5SJohan Hedberg 	 * we're not waiting for a special event and we get a success
4347444c6dd5SJohan Hedberg 	 * command status we should try to flag the request as completed
4348444c6dd5SJohan Hedberg 	 * (since for this kind of commands there will not be a command
4349444c6dd5SJohan Hedberg 	 * complete event).
4350444c6dd5SJohan Hedberg 	 */
43512af7aa66SLuiz Augusto von Dentz 	if (ev->status || (hdev->req_skb && !hci_skb_event(hdev->req_skb))) {
4352e6214487SJohan Hedberg 		hci_req_cmd_complete(hdev, *opcode, ev->status, req_complete,
4353e6214487SJohan Hedberg 				     req_complete_skb);
4354f80c5dadSJoão Paulo Rechi Vita 		if (hci_dev_test_flag(hdev, HCI_CMD_PENDING)) {
435585b56857SLuiz Augusto von Dentz 			bt_dev_err(hdev, "unexpected event for opcode 0x%4.4x",
435685b56857SLuiz Augusto von Dentz 				   *opcode);
4357f80c5dadSJoão Paulo Rechi Vita 			return;
4358f80c5dadSJoão Paulo Rechi Vita 		}
435985b56857SLuiz Augusto von Dentz 	}
4360f80c5dadSJoão Paulo Rechi Vita 
4361600b2150SJohan Hedberg 	if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q))
4362c347b765SGustavo F. Padovan 		queue_work(hdev->workqueue, &hdev->cmd_work);
4363a9de9248SMarcel Holtmann }
4364a9de9248SMarcel Holtmann 
hci_hardware_error_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)43653e54c589SLuiz Augusto von Dentz static void hci_hardware_error_evt(struct hci_dev *hdev, void *data,
43663e54c589SLuiz Augusto von Dentz 				   struct sk_buff *skb)
436724dfa343SMarcel Holtmann {
43683e54c589SLuiz Augusto von Dentz 	struct hci_ev_hardware_error *ev = data;
4369ae61a10dSLuiz Augusto von Dentz 
43703e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "code 0x%2.2x", ev->code);
437124dfa343SMarcel Holtmann 
4372c7741d16SMarcel Holtmann 	hdev->hw_error_code = ev->code;
4373c7741d16SMarcel Holtmann 
4374c7741d16SMarcel Holtmann 	queue_work(hdev->req_workqueue, &hdev->error_reset);
437524dfa343SMarcel Holtmann }
437624dfa343SMarcel Holtmann 
hci_role_change_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)43773e54c589SLuiz Augusto von Dentz static void hci_role_change_evt(struct hci_dev *hdev, void *data,
43783e54c589SLuiz Augusto von Dentz 				struct sk_buff *skb)
4379a9de9248SMarcel Holtmann {
43803e54c589SLuiz Augusto von Dentz 	struct hci_ev_role_change *ev = data;
4381a9de9248SMarcel Holtmann 	struct hci_conn *conn;
4382a9de9248SMarcel Holtmann 
43833e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
4384a9de9248SMarcel Holtmann 
4385a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
4386a9de9248SMarcel Holtmann 
4387a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
4388a9de9248SMarcel Holtmann 	if (conn) {
438940bef302SJohan Hedberg 		if (!ev->status)
439040bef302SJohan Hedberg 			conn->role = ev->role;
4391a9de9248SMarcel Holtmann 
439251a8efd7SJohan Hedberg 		clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
4393a9de9248SMarcel Holtmann 
4394a9de9248SMarcel Holtmann 		hci_role_switch_cfm(conn, ev->status, ev->role);
4395a9de9248SMarcel Holtmann 	}
4396a9de9248SMarcel Holtmann 
4397a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
4398a9de9248SMarcel Holtmann }
4399a9de9248SMarcel Holtmann 
hci_num_comp_pkts_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)44003e54c589SLuiz Augusto von Dentz static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data,
44013e54c589SLuiz Augusto von Dentz 				  struct sk_buff *skb)
44021da177e4SLinus Torvalds {
44033e54c589SLuiz Augusto von Dentz 	struct hci_ev_num_comp_pkts *ev = data;
44041da177e4SLinus Torvalds 	int i;
44051da177e4SLinus Torvalds 
4406aadc3d2fSLuiz Augusto von Dentz 	if (!hci_ev_skb_pull(hdev, skb, HCI_EV_NUM_COMP_PKTS,
4407aadc3d2fSLuiz Augusto von Dentz 			     flex_array_size(ev, handles, ev->num)))
4408aadc3d2fSLuiz Augusto von Dentz 		return;
4409aadc3d2fSLuiz Augusto von Dentz 
44103e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "num %d", ev->num);
44111da177e4SLinus Torvalds 
4412aadc3d2fSLuiz Augusto von Dentz 	for (i = 0; i < ev->num; i++) {
4413613a1c0cSAndrei Emeltchenko 		struct hci_comp_pkts_info *info = &ev->handles[i];
44141da177e4SLinus Torvalds 		struct hci_conn *conn;
44151da177e4SLinus Torvalds 		__u16  handle, count;
44161da177e4SLinus Torvalds 
4417613a1c0cSAndrei Emeltchenko 		handle = __le16_to_cpu(info->handle);
4418613a1c0cSAndrei Emeltchenko 		count  = __le16_to_cpu(info->count);
44191da177e4SLinus Torvalds 
44201da177e4SLinus Torvalds 		conn = hci_conn_hash_lookup_handle(hdev, handle);
4421f4280918SAndrei Emeltchenko 		if (!conn)
4422f4280918SAndrei Emeltchenko 			continue;
4423f4280918SAndrei Emeltchenko 
44241da177e4SLinus Torvalds 		conn->sent -= count;
44251da177e4SLinus Torvalds 
4426f4280918SAndrei Emeltchenko 		switch (conn->type) {
4427f4280918SAndrei Emeltchenko 		case ACL_LINK:
442870f23020SAndrei Emeltchenko 			hdev->acl_cnt += count;
442970f23020SAndrei Emeltchenko 			if (hdev->acl_cnt > hdev->acl_pkts)
44301da177e4SLinus Torvalds 				hdev->acl_cnt = hdev->acl_pkts;
4431f4280918SAndrei Emeltchenko 			break;
4432f4280918SAndrei Emeltchenko 
4433f4280918SAndrei Emeltchenko 		case LE_LINK:
44346ed58ec5SVille Tervo 			if (hdev->le_pkts) {
44356ed58ec5SVille Tervo 				hdev->le_cnt += count;
44366ed58ec5SVille Tervo 				if (hdev->le_cnt > hdev->le_pkts)
44376ed58ec5SVille Tervo 					hdev->le_cnt = hdev->le_pkts;
44386ed58ec5SVille Tervo 			} else {
44396ed58ec5SVille Tervo 				hdev->acl_cnt += count;
44406ed58ec5SVille Tervo 				if (hdev->acl_cnt > hdev->acl_pkts)
44416ed58ec5SVille Tervo 					hdev->acl_cnt = hdev->acl_pkts;
44426ed58ec5SVille Tervo 			}
4443f4280918SAndrei Emeltchenko 			break;
4444f4280918SAndrei Emeltchenko 
4445f4280918SAndrei Emeltchenko 		case SCO_LINK:
444670f23020SAndrei Emeltchenko 			hdev->sco_cnt += count;
444770f23020SAndrei Emeltchenko 			if (hdev->sco_cnt > hdev->sco_pkts)
44485b7f9909SMarcel Holtmann 				hdev->sco_cnt = hdev->sco_pkts;
4449f4280918SAndrei Emeltchenko 			break;
4450f4280918SAndrei Emeltchenko 
445126afbd82SLuiz Augusto von Dentz 		case ISO_LINK:
445226afbd82SLuiz Augusto von Dentz 			if (hdev->iso_pkts) {
445326afbd82SLuiz Augusto von Dentz 				hdev->iso_cnt += count;
445426afbd82SLuiz Augusto von Dentz 				if (hdev->iso_cnt > hdev->iso_pkts)
445526afbd82SLuiz Augusto von Dentz 					hdev->iso_cnt = hdev->iso_pkts;
445626afbd82SLuiz Augusto von Dentz 			} else if (hdev->le_pkts) {
445726afbd82SLuiz Augusto von Dentz 				hdev->le_cnt += count;
445826afbd82SLuiz Augusto von Dentz 				if (hdev->le_cnt > hdev->le_pkts)
445926afbd82SLuiz Augusto von Dentz 					hdev->le_cnt = hdev->le_pkts;
446026afbd82SLuiz Augusto von Dentz 			} else {
446126afbd82SLuiz Augusto von Dentz 				hdev->acl_cnt += count;
446226afbd82SLuiz Augusto von Dentz 				if (hdev->acl_cnt > hdev->acl_pkts)
446326afbd82SLuiz Augusto von Dentz 					hdev->acl_cnt = hdev->acl_pkts;
446426afbd82SLuiz Augusto von Dentz 			}
446526afbd82SLuiz Augusto von Dentz 			break;
446626afbd82SLuiz Augusto von Dentz 
4467f4280918SAndrei Emeltchenko 		default:
44682064ee33SMarcel Holtmann 			bt_dev_err(hdev, "unknown type %d conn %p",
44692064ee33SMarcel Holtmann 				   conn->type, conn);
4470f4280918SAndrei Emeltchenko 			break;
44711da177e4SLinus Torvalds 		}
44721da177e4SLinus Torvalds 	}
4473a9de9248SMarcel Holtmann 
44743eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
44751da177e4SLinus Torvalds }
44761da177e4SLinus Torvalds 
hci_mode_change_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)44773e54c589SLuiz Augusto von Dentz static void hci_mode_change_evt(struct hci_dev *hdev, void *data,
44783e54c589SLuiz Augusto von Dentz 				struct sk_buff *skb)
44791da177e4SLinus Torvalds {
44803e54c589SLuiz Augusto von Dentz 	struct hci_ev_mode_change *ev = data;
448104837f64SMarcel Holtmann 	struct hci_conn *conn;
44821da177e4SLinus Torvalds 
44833e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
44841da177e4SLinus Torvalds 
44851da177e4SLinus Torvalds 	hci_dev_lock(hdev);
44861da177e4SLinus Torvalds 
448704837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
448804837f64SMarcel Holtmann 	if (conn) {
448904837f64SMarcel Holtmann 		conn->mode = ev->mode;
449004837f64SMarcel Holtmann 
44918fc9ced3SGustavo Padovan 		if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
44928fc9ced3SGustavo Padovan 					&conn->flags)) {
449304837f64SMarcel Holtmann 			if (conn->mode == HCI_CM_ACTIVE)
449458a681efSJohan Hedberg 				set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
449504837f64SMarcel Holtmann 			else
449658a681efSJohan Hedberg 				clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
449704837f64SMarcel Holtmann 		}
4498e73439d8SMarcel Holtmann 
449951a8efd7SJohan Hedberg 		if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
4500e73439d8SMarcel Holtmann 			hci_sco_setup(conn, ev->status);
450104837f64SMarcel Holtmann 	}
450204837f64SMarcel Holtmann 
450304837f64SMarcel Holtmann 	hci_dev_unlock(hdev);
450404837f64SMarcel Holtmann }
450504837f64SMarcel Holtmann 
hci_pin_code_request_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)45063e54c589SLuiz Augusto von Dentz static void hci_pin_code_request_evt(struct hci_dev *hdev, void *data,
45073e54c589SLuiz Augusto von Dentz 				     struct sk_buff *skb)
45081da177e4SLinus Torvalds {
45093e54c589SLuiz Augusto von Dentz 	struct hci_ev_pin_code_req *ev = data;
4510052b30b0SMarcel Holtmann 	struct hci_conn *conn;
4511052b30b0SMarcel Holtmann 
45123e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
4513052b30b0SMarcel Holtmann 
4514052b30b0SMarcel Holtmann 	hci_dev_lock(hdev);
4515052b30b0SMarcel Holtmann 
4516052b30b0SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
4517b6f98044SWaldemar Rymarkiewicz 	if (!conn)
4518b6f98044SWaldemar Rymarkiewicz 		goto unlock;
4519b6f98044SWaldemar Rymarkiewicz 
4520b6f98044SWaldemar Rymarkiewicz 	if (conn->state == BT_CONNECTED) {
4521052b30b0SMarcel Holtmann 		hci_conn_hold(conn);
4522052b30b0SMarcel Holtmann 		conn->disc_timeout = HCI_PAIRING_TIMEOUT;
452376a68ba0SDavid Herrmann 		hci_conn_drop(conn);
4524052b30b0SMarcel Holtmann 	}
4525052b30b0SMarcel Holtmann 
4526d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BONDABLE) &&
45272f407f0aSJohan Hedberg 	    !test_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags)) {
452803b555e1SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
452903b555e1SJohan Hedberg 			     sizeof(ev->bdaddr), &ev->bdaddr);
4530d7a5a11dSMarcel Holtmann 	} else if (hci_dev_test_flag(hdev, HCI_MGMT)) {
4531a770bb5aSWaldemar Rymarkiewicz 		u8 secure;
4532a770bb5aSWaldemar Rymarkiewicz 
4533a770bb5aSWaldemar Rymarkiewicz 		if (conn->pending_sec_level == BT_SECURITY_HIGH)
4534a770bb5aSWaldemar Rymarkiewicz 			secure = 1;
4535a770bb5aSWaldemar Rymarkiewicz 		else
4536a770bb5aSWaldemar Rymarkiewicz 			secure = 0;
4537a770bb5aSWaldemar Rymarkiewicz 
4538744cf19eSJohan Hedberg 		mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
4539a770bb5aSWaldemar Rymarkiewicz 	}
4540980e1a53SJohan Hedberg 
4541b6f98044SWaldemar Rymarkiewicz unlock:
4542052b30b0SMarcel Holtmann 	hci_dev_unlock(hdev);
45431da177e4SLinus Torvalds }
45441da177e4SLinus Torvalds 
conn_set_key(struct hci_conn * conn,u8 key_type,u8 pin_len)4545cb6f3f7aSJohan Hedberg static void conn_set_key(struct hci_conn *conn, u8 key_type, u8 pin_len)
4546cb6f3f7aSJohan Hedberg {
4547cb6f3f7aSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION)
4548cb6f3f7aSJohan Hedberg 		return;
4549cb6f3f7aSJohan Hedberg 
4550cb6f3f7aSJohan Hedberg 	conn->pin_length = pin_len;
4551cb6f3f7aSJohan Hedberg 	conn->key_type = key_type;
4552cb6f3f7aSJohan Hedberg 
4553cb6f3f7aSJohan Hedberg 	switch (key_type) {
4554cb6f3f7aSJohan Hedberg 	case HCI_LK_LOCAL_UNIT:
4555cb6f3f7aSJohan Hedberg 	case HCI_LK_REMOTE_UNIT:
4556cb6f3f7aSJohan Hedberg 	case HCI_LK_DEBUG_COMBINATION:
4557cb6f3f7aSJohan Hedberg 		return;
4558cb6f3f7aSJohan Hedberg 	case HCI_LK_COMBINATION:
4559cb6f3f7aSJohan Hedberg 		if (pin_len == 16)
4560cb6f3f7aSJohan Hedberg 			conn->pending_sec_level = BT_SECURITY_HIGH;
4561cb6f3f7aSJohan Hedberg 		else
4562cb6f3f7aSJohan Hedberg 			conn->pending_sec_level = BT_SECURITY_MEDIUM;
4563cb6f3f7aSJohan Hedberg 		break;
4564cb6f3f7aSJohan Hedberg 	case HCI_LK_UNAUTH_COMBINATION_P192:
4565cb6f3f7aSJohan Hedberg 	case HCI_LK_UNAUTH_COMBINATION_P256:
4566cb6f3f7aSJohan Hedberg 		conn->pending_sec_level = BT_SECURITY_MEDIUM;
4567cb6f3f7aSJohan Hedberg 		break;
4568cb6f3f7aSJohan Hedberg 	case HCI_LK_AUTH_COMBINATION_P192:
4569cb6f3f7aSJohan Hedberg 		conn->pending_sec_level = BT_SECURITY_HIGH;
4570cb6f3f7aSJohan Hedberg 		break;
4571cb6f3f7aSJohan Hedberg 	case HCI_LK_AUTH_COMBINATION_P256:
4572cb6f3f7aSJohan Hedberg 		conn->pending_sec_level = BT_SECURITY_FIPS;
4573cb6f3f7aSJohan Hedberg 		break;
4574cb6f3f7aSJohan Hedberg 	}
4575cb6f3f7aSJohan Hedberg }
4576cb6f3f7aSJohan Hedberg 
hci_link_key_request_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)45773e54c589SLuiz Augusto von Dentz static void hci_link_key_request_evt(struct hci_dev *hdev, void *data,
45783e54c589SLuiz Augusto von Dentz 				     struct sk_buff *skb)
45791da177e4SLinus Torvalds {
45803e54c589SLuiz Augusto von Dentz 	struct hci_ev_link_key_req *ev = data;
458155ed8ca1SJohan Hedberg 	struct hci_cp_link_key_reply cp;
458255ed8ca1SJohan Hedberg 	struct hci_conn *conn;
458355ed8ca1SJohan Hedberg 	struct link_key *key;
458455ed8ca1SJohan Hedberg 
45853e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
458655ed8ca1SJohan Hedberg 
4587d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
458855ed8ca1SJohan Hedberg 		return;
458955ed8ca1SJohan Hedberg 
459055ed8ca1SJohan Hedberg 	hci_dev_lock(hdev);
459155ed8ca1SJohan Hedberg 
459255ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, &ev->bdaddr);
459355ed8ca1SJohan Hedberg 	if (!key) {
45943e54c589SLuiz Augusto von Dentz 		bt_dev_dbg(hdev, "link key not found for %pMR", &ev->bdaddr);
459555ed8ca1SJohan Hedberg 		goto not_found;
459655ed8ca1SJohan Hedberg 	}
459755ed8ca1SJohan Hedberg 
45983e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "found key type %u for %pMR", key->type, &ev->bdaddr);
459955ed8ca1SJohan Hedberg 
460055ed8ca1SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
460160b83f57SWaldemar Rymarkiewicz 	if (conn) {
4602fe8bc5acSJohan Hedberg 		clear_bit(HCI_CONN_NEW_LINK_KEY, &conn->flags);
4603fe8bc5acSJohan Hedberg 
460466138ce8SMarcel Holtmann 		if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 ||
460566138ce8SMarcel Holtmann 		     key->type == HCI_LK_UNAUTH_COMBINATION_P256) &&
4606807deac2SGustavo Padovan 		    conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
46073e54c589SLuiz Augusto von Dentz 			bt_dev_dbg(hdev, "ignoring unauthenticated key");
460855ed8ca1SJohan Hedberg 			goto not_found;
460955ed8ca1SJohan Hedberg 		}
461055ed8ca1SJohan Hedberg 
461160b83f57SWaldemar Rymarkiewicz 		if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
4612f3fb0b58SJohan Hedberg 		    (conn->pending_sec_level == BT_SECURITY_HIGH ||
4613f3fb0b58SJohan Hedberg 		     conn->pending_sec_level == BT_SECURITY_FIPS)) {
46143e54c589SLuiz Augusto von Dentz 			bt_dev_dbg(hdev, "ignoring key unauthenticated for high security");
461560b83f57SWaldemar Rymarkiewicz 			goto not_found;
461660b83f57SWaldemar Rymarkiewicz 		}
461760b83f57SWaldemar Rymarkiewicz 
4618cb6f3f7aSJohan Hedberg 		conn_set_key(conn, key->type, key->pin_len);
461960b83f57SWaldemar Rymarkiewicz 	}
462060b83f57SWaldemar Rymarkiewicz 
462155ed8ca1SJohan Hedberg 	bacpy(&cp.bdaddr, &ev->bdaddr);
46229b3b4460SAndrei Emeltchenko 	memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
462355ed8ca1SJohan Hedberg 
462455ed8ca1SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
462555ed8ca1SJohan Hedberg 
462655ed8ca1SJohan Hedberg 	hci_dev_unlock(hdev);
462755ed8ca1SJohan Hedberg 
462855ed8ca1SJohan Hedberg 	return;
462955ed8ca1SJohan Hedberg 
463055ed8ca1SJohan Hedberg not_found:
463155ed8ca1SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
463255ed8ca1SJohan Hedberg 	hci_dev_unlock(hdev);
46331da177e4SLinus Torvalds }
46341da177e4SLinus Torvalds 
hci_link_key_notify_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)46353e54c589SLuiz Augusto von Dentz static void hci_link_key_notify_evt(struct hci_dev *hdev, void *data,
46363e54c589SLuiz Augusto von Dentz 				    struct sk_buff *skb)
46371da177e4SLinus Torvalds {
46383e54c589SLuiz Augusto von Dentz 	struct hci_ev_link_key_notify *ev = data;
4639052b30b0SMarcel Holtmann 	struct hci_conn *conn;
46407652ff6aSJohan Hedberg 	struct link_key *key;
46417652ff6aSJohan Hedberg 	bool persistent;
464255ed8ca1SJohan Hedberg 	u8 pin_len = 0;
4643052b30b0SMarcel Holtmann 
46443e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
4645052b30b0SMarcel Holtmann 
4646052b30b0SMarcel Holtmann 	hci_dev_lock(hdev);
4647052b30b0SMarcel Holtmann 
4648052b30b0SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
464982c13d42SJohan Hedberg 	if (!conn)
465082c13d42SJohan Hedberg 		goto unlock;
465182c13d42SJohan Hedberg 
465233155c4aSLee, Chun-Yi 	/* Ignore NULL link key against CVE-2020-26555 */
4653b5412606SLuiz Augusto von Dentz 	if (!crypto_memneq(ev->link_key, ZERO_KEY, HCI_LINK_KEY_SIZE)) {
465433155c4aSLee, Chun-Yi 		bt_dev_dbg(hdev, "Ignore NULL link key (ZERO KEY) for %pMR",
465533155c4aSLee, Chun-Yi 			   &ev->bdaddr);
465633155c4aSLee, Chun-Yi 		hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
465733155c4aSLee, Chun-Yi 		hci_conn_drop(conn);
465833155c4aSLee, Chun-Yi 		goto unlock;
465933155c4aSLee, Chun-Yi 	}
466033155c4aSLee, Chun-Yi 
4661052b30b0SMarcel Holtmann 	hci_conn_hold(conn);
4662052b30b0SMarcel Holtmann 	conn->disc_timeout = HCI_DISCONN_TIMEOUT;
466376a68ba0SDavid Herrmann 	hci_conn_drop(conn);
466482c13d42SJohan Hedberg 
4665fe8bc5acSJohan Hedberg 	set_bit(HCI_CONN_NEW_LINK_KEY, &conn->flags);
4666cb6f3f7aSJohan Hedberg 	conn_set_key(conn, ev->key_type, conn->pin_length);
4667052b30b0SMarcel Holtmann 
4668d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
46697652ff6aSJohan Hedberg 		goto unlock;
467055ed8ca1SJohan Hedberg 
46717652ff6aSJohan Hedberg 	key = hci_add_link_key(hdev, conn, &ev->bdaddr, ev->link_key,
46727652ff6aSJohan Hedberg 			        ev->key_type, pin_len, &persistent);
46737652ff6aSJohan Hedberg 	if (!key)
46747652ff6aSJohan Hedberg 		goto unlock;
46757652ff6aSJohan Hedberg 
4676cb6f3f7aSJohan Hedberg 	/* Update connection information since adding the key will have
4677cb6f3f7aSJohan Hedberg 	 * fixed up the type in the case of changed combination keys.
4678cb6f3f7aSJohan Hedberg 	 */
4679cb6f3f7aSJohan Hedberg 	if (ev->key_type == HCI_LK_CHANGED_COMBINATION)
4680cb6f3f7aSJohan Hedberg 		conn_set_key(conn, key->type, key->pin_len);
4681cb6f3f7aSJohan Hedberg 
46827652ff6aSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
46837652ff6aSJohan Hedberg 
46846d5650c4SJohan Hedberg 	/* Keep debug keys around only if the HCI_KEEP_DEBUG_KEYS flag
46856d5650c4SJohan Hedberg 	 * is set. If it's not set simply remove the key from the kernel
46866d5650c4SJohan Hedberg 	 * list (we've still notified user space about it but with
46876d5650c4SJohan Hedberg 	 * store_hint being 0).
46886d5650c4SJohan Hedberg 	 */
46896d5650c4SJohan Hedberg 	if (key->type == HCI_LK_DEBUG_COMBINATION &&
4690d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_KEEP_DEBUG_KEYS)) {
46910378b597SJohan Hedberg 		list_del_rcu(&key->list);
46920378b597SJohan Hedberg 		kfree_rcu(key, rcu);
469382c13d42SJohan Hedberg 		goto unlock;
469482c13d42SJohan Hedberg 	}
469582c13d42SJohan Hedberg 
4696af6a9c32SJohan Hedberg 	if (persistent)
4697af6a9c32SJohan Hedberg 		clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags);
4698af6a9c32SJohan Hedberg 	else
4699af6a9c32SJohan Hedberg 		set_bit(HCI_CONN_FLUSH_KEY, &conn->flags);
47007652ff6aSJohan Hedberg 
47017652ff6aSJohan Hedberg unlock:
4702052b30b0SMarcel Holtmann 	hci_dev_unlock(hdev);
47031da177e4SLinus Torvalds }
47041da177e4SLinus Torvalds 
hci_clock_offset_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)47053e54c589SLuiz Augusto von Dentz static void hci_clock_offset_evt(struct hci_dev *hdev, void *data,
47063e54c589SLuiz Augusto von Dentz 				 struct sk_buff *skb)
470704837f64SMarcel Holtmann {
47083e54c589SLuiz Augusto von Dentz 	struct hci_ev_clock_offset *ev = data;
470904837f64SMarcel Holtmann 	struct hci_conn *conn;
471004837f64SMarcel Holtmann 
47113e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
471204837f64SMarcel Holtmann 
471304837f64SMarcel Holtmann 	hci_dev_lock(hdev);
471404837f64SMarcel Holtmann 
471504837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
47161da177e4SLinus Torvalds 	if (conn && !ev->status) {
47171da177e4SLinus Torvalds 		struct inquiry_entry *ie;
47181da177e4SLinus Torvalds 
4719cc11b9c1SAndrei Emeltchenko 		ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
4720cc11b9c1SAndrei Emeltchenko 		if (ie) {
47211da177e4SLinus Torvalds 			ie->data.clock_offset = ev->clock_offset;
47221da177e4SLinus Torvalds 			ie->timestamp = jiffies;
47231da177e4SLinus Torvalds 		}
47241da177e4SLinus Torvalds 	}
47251da177e4SLinus Torvalds 
47261da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
47271da177e4SLinus Torvalds }
47281da177e4SLinus Torvalds 
hci_pkt_type_change_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)47293e54c589SLuiz Augusto von Dentz static void hci_pkt_type_change_evt(struct hci_dev *hdev, void *data,
47303e54c589SLuiz Augusto von Dentz 				    struct sk_buff *skb)
4731a8746417SMarcel Holtmann {
47323e54c589SLuiz Augusto von Dentz 	struct hci_ev_pkt_type_change *ev = data;
4733a8746417SMarcel Holtmann 	struct hci_conn *conn;
4734a8746417SMarcel Holtmann 
47353e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
4736a8746417SMarcel Holtmann 
4737a8746417SMarcel Holtmann 	hci_dev_lock(hdev);
4738a8746417SMarcel Holtmann 
4739a8746417SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
4740a8746417SMarcel Holtmann 	if (conn && !ev->status)
4741a8746417SMarcel Holtmann 		conn->pkt_type = __le16_to_cpu(ev->pkt_type);
4742a8746417SMarcel Holtmann 
4743a8746417SMarcel Holtmann 	hci_dev_unlock(hdev);
4744a8746417SMarcel Holtmann }
4745a8746417SMarcel Holtmann 
hci_pscan_rep_mode_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)47463e54c589SLuiz Augusto von Dentz static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, void *data,
47473e54c589SLuiz Augusto von Dentz 				   struct sk_buff *skb)
474885a1e930SMarcel Holtmann {
47493e54c589SLuiz Augusto von Dentz 	struct hci_ev_pscan_rep_mode *ev = data;
475085a1e930SMarcel Holtmann 	struct inquiry_entry *ie;
475185a1e930SMarcel Holtmann 
47523e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
475385a1e930SMarcel Holtmann 
475485a1e930SMarcel Holtmann 	hci_dev_lock(hdev);
475585a1e930SMarcel Holtmann 
4756cc11b9c1SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
4757cc11b9c1SAndrei Emeltchenko 	if (ie) {
475885a1e930SMarcel Holtmann 		ie->data.pscan_rep_mode = ev->pscan_rep_mode;
475985a1e930SMarcel Holtmann 		ie->timestamp = jiffies;
476085a1e930SMarcel Holtmann 	}
476185a1e930SMarcel Holtmann 
476285a1e930SMarcel Holtmann 	hci_dev_unlock(hdev);
476385a1e930SMarcel Holtmann }
476485a1e930SMarcel Holtmann 
hci_inquiry_result_with_rssi_evt(struct hci_dev * hdev,void * edata,struct sk_buff * skb)47653e54c589SLuiz Augusto von Dentz static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, void *edata,
4766807deac2SGustavo Padovan 					     struct sk_buff *skb)
4767a9de9248SMarcel Holtmann {
476872279d17SLuiz Augusto von Dentz 	struct hci_ev_inquiry_result_rssi *ev = edata;
4769a9de9248SMarcel Holtmann 	struct inquiry_data data;
47708d08d324SLuiz Augusto von Dentz 	int i;
4771a9de9248SMarcel Holtmann 
477272279d17SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "num_rsp %d", ev->num);
47738d08d324SLuiz Augusto von Dentz 
477472279d17SLuiz Augusto von Dentz 	if (!ev->num)
4775a9de9248SMarcel Holtmann 		return;
4776a9de9248SMarcel Holtmann 
4777d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ))
47781519cc17SAndre Guedes 		return;
47791519cc17SAndre Guedes 
4780a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
4781a9de9248SMarcel Holtmann 
478272279d17SLuiz Augusto von Dentz 	if (skb->len == array_size(ev->num,
478372279d17SLuiz Augusto von Dentz 				   sizeof(struct inquiry_info_rssi_pscan))) {
47848d08d324SLuiz Augusto von Dentz 		struct inquiry_info_rssi_pscan *info;
4785a9de9248SMarcel Holtmann 
478672279d17SLuiz Augusto von Dentz 		for (i = 0; i < ev->num; i++) {
4787af58925cSMarcel Holtmann 			u32 flags;
4788af58925cSMarcel Holtmann 
4789fee64503SLuiz Augusto von Dentz 			info = hci_ev_skb_pull(hdev, skb,
4790fee64503SLuiz Augusto von Dentz 					       HCI_EV_INQUIRY_RESULT_WITH_RSSI,
4791fee64503SLuiz Augusto von Dentz 					       sizeof(*info));
4792fee64503SLuiz Augusto von Dentz 			if (!info) {
4793fee64503SLuiz Augusto von Dentz 				bt_dev_err(hdev, "Malformed HCI Event: 0x%2.2x",
4794fee64503SLuiz Augusto von Dentz 					   HCI_EV_INQUIRY_RESULT_WITH_RSSI);
4795c07ba878SDan Carpenter 				goto unlock;
4796fee64503SLuiz Augusto von Dentz 			}
4797fee64503SLuiz Augusto von Dentz 
4798a9de9248SMarcel Holtmann 			bacpy(&data.bdaddr, &info->bdaddr);
4799a9de9248SMarcel Holtmann 			data.pscan_rep_mode	= info->pscan_rep_mode;
4800a9de9248SMarcel Holtmann 			data.pscan_period_mode	= info->pscan_period_mode;
4801a9de9248SMarcel Holtmann 			data.pscan_mode		= info->pscan_mode;
4802a9de9248SMarcel Holtmann 			memcpy(data.dev_class, info->dev_class, 3);
4803a9de9248SMarcel Holtmann 			data.clock_offset	= info->clock_offset;
4804a9de9248SMarcel Holtmann 			data.rssi		= info->rssi;
480541a96212SMarcel Holtmann 			data.ssp_mode		= 0x00;
48063175405bSJohan Hedberg 
4807af58925cSMarcel Holtmann 			flags = hci_inquiry_cache_update(hdev, &data, false);
4808af58925cSMarcel Holtmann 
480948264f06SJohan Hedberg 			mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
4810e17acd40SJohan Hedberg 					  info->dev_class, info->rssi,
4811b338d917SBrian Gix 					  flags, NULL, 0, NULL, 0, 0);
4812a9de9248SMarcel Holtmann 		}
481372279d17SLuiz Augusto von Dentz 	} else if (skb->len == array_size(ev->num,
481472279d17SLuiz Augusto von Dentz 					  sizeof(struct inquiry_info_rssi))) {
48158d08d324SLuiz Augusto von Dentz 		struct inquiry_info_rssi *info;
4816a9de9248SMarcel Holtmann 
481772279d17SLuiz Augusto von Dentz 		for (i = 0; i < ev->num; i++) {
4818af58925cSMarcel Holtmann 			u32 flags;
4819af58925cSMarcel Holtmann 
4820fee64503SLuiz Augusto von Dentz 			info = hci_ev_skb_pull(hdev, skb,
4821fee64503SLuiz Augusto von Dentz 					       HCI_EV_INQUIRY_RESULT_WITH_RSSI,
4822fee64503SLuiz Augusto von Dentz 					       sizeof(*info));
4823fee64503SLuiz Augusto von Dentz 			if (!info) {
4824fee64503SLuiz Augusto von Dentz 				bt_dev_err(hdev, "Malformed HCI Event: 0x%2.2x",
4825fee64503SLuiz Augusto von Dentz 					   HCI_EV_INQUIRY_RESULT_WITH_RSSI);
4826c07ba878SDan Carpenter 				goto unlock;
4827fee64503SLuiz Augusto von Dentz 			}
4828fee64503SLuiz Augusto von Dentz 
4829a9de9248SMarcel Holtmann 			bacpy(&data.bdaddr, &info->bdaddr);
4830a9de9248SMarcel Holtmann 			data.pscan_rep_mode	= info->pscan_rep_mode;
4831a9de9248SMarcel Holtmann 			data.pscan_period_mode	= info->pscan_period_mode;
4832a9de9248SMarcel Holtmann 			data.pscan_mode		= 0x00;
4833a9de9248SMarcel Holtmann 			memcpy(data.dev_class, info->dev_class, 3);
4834a9de9248SMarcel Holtmann 			data.clock_offset	= info->clock_offset;
4835a9de9248SMarcel Holtmann 			data.rssi		= info->rssi;
483641a96212SMarcel Holtmann 			data.ssp_mode		= 0x00;
4837af58925cSMarcel Holtmann 
4838af58925cSMarcel Holtmann 			flags = hci_inquiry_cache_update(hdev, &data, false);
4839af58925cSMarcel Holtmann 
484048264f06SJohan Hedberg 			mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
4841e17acd40SJohan Hedberg 					  info->dev_class, info->rssi,
4842b338d917SBrian Gix 					  flags, NULL, 0, NULL, 0, 0);
4843a9de9248SMarcel Holtmann 		}
48448d08d324SLuiz Augusto von Dentz 	} else {
48458d08d324SLuiz Augusto von Dentz 		bt_dev_err(hdev, "Malformed HCI Event: 0x%2.2x",
48468d08d324SLuiz Augusto von Dentz 			   HCI_EV_INQUIRY_RESULT_WITH_RSSI);
4847a9de9248SMarcel Holtmann 	}
4848c07ba878SDan Carpenter unlock:
4849a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
4850a9de9248SMarcel Holtmann }
4851a9de9248SMarcel Holtmann 
hci_remote_ext_features_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)48523e54c589SLuiz Augusto von Dentz static void hci_remote_ext_features_evt(struct hci_dev *hdev, void *data,
4853807deac2SGustavo Padovan 					struct sk_buff *skb)
4854a9de9248SMarcel Holtmann {
48553e54c589SLuiz Augusto von Dentz 	struct hci_ev_remote_ext_features *ev = data;
485641a96212SMarcel Holtmann 	struct hci_conn *conn;
485741a96212SMarcel Holtmann 
48583e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
485941a96212SMarcel Holtmann 
486041a96212SMarcel Holtmann 	hci_dev_lock(hdev);
486141a96212SMarcel Holtmann 
486241a96212SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
4863ccd556feSJohan Hedberg 	if (!conn)
4864ccd556feSJohan Hedberg 		goto unlock;
4865ccd556feSJohan Hedberg 
4866cad718edSJohan Hedberg 	if (ev->page < HCI_MAX_PAGES)
4867cad718edSJohan Hedberg 		memcpy(conn->features[ev->page], ev->features, 8);
4868cad718edSJohan Hedberg 
4869769be974SMarcel Holtmann 	if (!ev->status && ev->page == 0x01) {
487041a96212SMarcel Holtmann 		struct inquiry_entry *ie;
487141a96212SMarcel Holtmann 
4872cc11b9c1SAndrei Emeltchenko 		ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
4873cc11b9c1SAndrei Emeltchenko 		if (ie)
487402b7cc62SJohan Hedberg 			ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
487541a96212SMarcel Holtmann 
4876bbb0eadaSJaganath Kanakkassery 		if (ev->features[0] & LMP_HOST_SSP) {
487758a681efSJohan Hedberg 			set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
4878bbb0eadaSJaganath Kanakkassery 		} else {
4879bbb0eadaSJaganath Kanakkassery 			/* It is mandatory by the Bluetooth specification that
4880bbb0eadaSJaganath Kanakkassery 			 * Extended Inquiry Results are only used when Secure
4881bbb0eadaSJaganath Kanakkassery 			 * Simple Pairing is enabled, but some devices violate
4882bbb0eadaSJaganath Kanakkassery 			 * this.
4883bbb0eadaSJaganath Kanakkassery 			 *
4884bbb0eadaSJaganath Kanakkassery 			 * To make these devices work, the internal SSP
4885bbb0eadaSJaganath Kanakkassery 			 * enabled flag needs to be cleared if the remote host
4886bbb0eadaSJaganath Kanakkassery 			 * features do not indicate SSP support */
4887bbb0eadaSJaganath Kanakkassery 			clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
4888bbb0eadaSJaganath Kanakkassery 		}
4889eb9a8f3fSMarcel Holtmann 
4890eb9a8f3fSMarcel Holtmann 		if (ev->features[0] & LMP_HOST_SC)
4891eb9a8f3fSMarcel Holtmann 			set_bit(HCI_CONN_SC_ENABLED, &conn->flags);
489241a96212SMarcel Holtmann 	}
489341a96212SMarcel Holtmann 
4894ccd556feSJohan Hedberg 	if (conn->state != BT_CONFIG)
4895ccd556feSJohan Hedberg 		goto unlock;
4896ccd556feSJohan Hedberg 
4897671267bfSJohan Hedberg 	if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
4898127178d2SJohan Hedberg 		struct hci_cp_remote_name_req cp;
4899127178d2SJohan Hedberg 		memset(&cp, 0, sizeof(cp));
4900127178d2SJohan Hedberg 		bacpy(&cp.bdaddr, &conn->dst);
4901127178d2SJohan Hedberg 		cp.pscan_rep_mode = 0x02;
4902127178d2SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
49030b3df53cSLuiz Augusto von Dentz 	} else {
49041c6ed31bSYu Liu 		mgmt_device_connected(hdev, conn, NULL, 0);
49050b3df53cSLuiz Augusto von Dentz 	}
4906392599b9SJohan Hedberg 
4907127178d2SJohan Hedberg 	if (!hci_outgoing_auth_needed(hdev, conn)) {
4908769be974SMarcel Holtmann 		conn->state = BT_CONNECTED;
4909539c496dSJohan Hedberg 		hci_connect_cfm(conn, ev->status);
491076a68ba0SDavid Herrmann 		hci_conn_drop(conn);
4911769be974SMarcel Holtmann 	}
4912769be974SMarcel Holtmann 
4913ccd556feSJohan Hedberg unlock:
491441a96212SMarcel Holtmann 	hci_dev_unlock(hdev);
4915a9de9248SMarcel Holtmann }
4916a9de9248SMarcel Holtmann 
hci_sync_conn_complete_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)49173e54c589SLuiz Augusto von Dentz static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data,
4918807deac2SGustavo Padovan 				       struct sk_buff *skb)
4919a9de9248SMarcel Holtmann {
49203e54c589SLuiz Augusto von Dentz 	struct hci_ev_sync_conn_complete *ev = data;
4921b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
4922c86cc5a3SLuiz Augusto von Dentz 	u8 status = ev->status;
4923b6a0dc82SMarcel Holtmann 
49243afee211SSoenke Huster 	switch (ev->link_type) {
49253afee211SSoenke Huster 	case SCO_LINK:
49263afee211SSoenke Huster 	case ESCO_LINK:
49273afee211SSoenke Huster 		break;
49283afee211SSoenke Huster 	default:
49293afee211SSoenke Huster 		/* As per Core 5.3 Vol 4 Part E 7.7.35 (p.2219), Link_Type
49303afee211SSoenke Huster 		 * for HCI_Synchronous_Connection_Complete is limited to
49313afee211SSoenke Huster 		 * either SCO or eSCO
49323afee211SSoenke Huster 		 */
49333afee211SSoenke Huster 		bt_dev_err(hdev, "Ignoring connect complete event for invalid link type");
49343afee211SSoenke Huster 		return;
49353afee211SSoenke Huster 	}
49363afee211SSoenke Huster 
4937c86cc5a3SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", status);
4938b6a0dc82SMarcel Holtmann 
4939b6a0dc82SMarcel Holtmann 	hci_dev_lock(hdev);
4940b6a0dc82SMarcel Holtmann 
4941b6a0dc82SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
49429dc0a3afSMarcel Holtmann 	if (!conn) {
49439dc0a3afSMarcel Holtmann 		if (ev->link_type == ESCO_LINK)
49449dc0a3afSMarcel Holtmann 			goto unlock;
49459dc0a3afSMarcel Holtmann 
4946618353b1SKuba Pawlak 		/* When the link type in the event indicates SCO connection
4947618353b1SKuba Pawlak 		 * and lookup of the connection object fails, then check
4948618353b1SKuba Pawlak 		 * if an eSCO connection object exists.
4949618353b1SKuba Pawlak 		 *
4950618353b1SKuba Pawlak 		 * The core limits the synchronous connections to either
4951618353b1SKuba Pawlak 		 * SCO or eSCO. The eSCO connection is preferred and tried
4952618353b1SKuba Pawlak 		 * to be setup first and until successfully established,
4953618353b1SKuba Pawlak 		 * the link type will be hinted as eSCO.
4954618353b1SKuba Pawlak 		 */
49559dc0a3afSMarcel Holtmann 		conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
4956b6a0dc82SMarcel Holtmann 		if (!conn)
4957b6a0dc82SMarcel Holtmann 			goto unlock;
49589dc0a3afSMarcel Holtmann 	}
49599dc0a3afSMarcel Holtmann 
4960d5ebaa7cSSoenke Huster 	/* The HCI_Synchronous_Connection_Complete event is only sent once per connection.
4961d5ebaa7cSSoenke Huster 	 * Processing it more than once per connection can corrupt kernel memory.
496292fe24a7SDesmond Cheong Zhi Xi 	 *
4963d5ebaa7cSSoenke Huster 	 * As the connection handle is set here for the first time, it indicates
4964d5ebaa7cSSoenke Huster 	 * whether the connection is already set up.
496592fe24a7SDesmond Cheong Zhi Xi 	 */
49669f78191cSLuiz Augusto von Dentz 	if (!HCI_CONN_HANDLE_UNSET(conn->handle)) {
4967d5ebaa7cSSoenke Huster 		bt_dev_err(hdev, "Ignoring HCI_Sync_Conn_Complete event for existing connection");
496892fe24a7SDesmond Cheong Zhi Xi 		goto unlock;
496992fe24a7SDesmond Cheong Zhi Xi 	}
497092fe24a7SDesmond Cheong Zhi Xi 
4971c86cc5a3SLuiz Augusto von Dentz 	switch (status) {
4972d5ebaa7cSSoenke Huster 	case 0x00:
497316e3b642SLuiz Augusto von Dentz 		status = hci_conn_set_handle(conn, __le16_to_cpu(ev->handle));
497416e3b642SLuiz Augusto von Dentz 		if (status) {
4975c86cc5a3SLuiz Augusto von Dentz 			conn->state = BT_CLOSED;
4976c86cc5a3SLuiz Augusto von Dentz 			break;
4977c86cc5a3SLuiz Augusto von Dentz 		}
4978c86cc5a3SLuiz Augusto von Dentz 
4979732547f9SMarcel Holtmann 		conn->state  = BT_CONNECTED;
4980618353b1SKuba Pawlak 		conn->type   = ev->link_type;
4981732547f9SMarcel Holtmann 
498223b9ceb7SMarcel Holtmann 		hci_debugfs_create_conn(conn);
4983732547f9SMarcel Holtmann 		hci_conn_add_sysfs(conn);
4984732547f9SMarcel Holtmann 		break;
4985732547f9SMarcel Holtmann 
498681218d20SNick Pelly 	case 0x10:	/* Connection Accept Timeout */
49871a4c958cSFrédéric Dalleau 	case 0x0d:	/* Connection Rejected due to Limited Resources */
4988705e5711SStephen Coe 	case 0x11:	/* Unsupported Feature or Parameter Value */
4989732547f9SMarcel Holtmann 	case 0x1c:	/* SCO interval rejected */
49901038a00bSNick Pelly 	case 0x1a:	/* Unsupported Remote Feature */
499156b5453aSHsin-Yu Chao 	case 0x1e:	/* Invalid LMP Parameters */
4992732547f9SMarcel Holtmann 	case 0x1f:	/* Unspecified error */
499327539bc4SAndrew Earl 	case 0x20:	/* Unsupported LMP Parameter value */
49942dea632fSFrédéric Dalleau 		if (conn->out) {
4995efc7688bSMarcel Holtmann 			conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
4996efc7688bSMarcel Holtmann 					(hdev->esco_type & EDR_ESCO_MASK);
499706149746SLuiz Augusto von Dentz 			if (hci_setup_sync(conn, conn->parent->handle))
4998efc7688bSMarcel Holtmann 				goto unlock;
4999efc7688bSMarcel Holtmann 		}
500019186c7bSGustavo A. R. Silva 		fallthrough;
5001efc7688bSMarcel Holtmann 
5002732547f9SMarcel Holtmann 	default:
5003b6a0dc82SMarcel Holtmann 		conn->state = BT_CLOSED;
5004732547f9SMarcel Holtmann 		break;
5005732547f9SMarcel Holtmann 	}
5006b6a0dc82SMarcel Holtmann 
50071f8330eaSSathish Narsimman 	bt_dev_dbg(hdev, "SCO connected with air mode: %02x", ev->air_mode);
5008f4f9fa0cSChethan T N 	/* Notify only in case of SCO over HCI transport data path which
5009f4f9fa0cSChethan T N 	 * is zero and non-zero value shall be non-HCI transport data path
5010f4f9fa0cSChethan T N 	 */
5011a27c519aSJackie Liu 	if (conn->codec.data_path == 0 && hdev->notify) {
5012a27c519aSJackie Liu 		switch (ev->air_mode) {
5013a27c519aSJackie Liu 		case 0x02:
5014a27c519aSJackie Liu 			hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD);
5015a27c519aSJackie Liu 			break;
5016a27c519aSJackie Liu 		case 0x03:
5017a27c519aSJackie Liu 			hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_TRANSP);
5018a27c519aSJackie Liu 			break;
5019a27c519aSJackie Liu 		}
5020f4f9fa0cSChethan T N 	}
5021f4f9fa0cSChethan T N 
5022c86cc5a3SLuiz Augusto von Dentz 	hci_connect_cfm(conn, status);
5023c86cc5a3SLuiz Augusto von Dentz 	if (status)
5024b6a0dc82SMarcel Holtmann 		hci_conn_del(conn);
5025b6a0dc82SMarcel Holtmann 
5026b6a0dc82SMarcel Holtmann unlock:
5027b6a0dc82SMarcel Holtmann 	hci_dev_unlock(hdev);
5028a9de9248SMarcel Holtmann }
5029a9de9248SMarcel Holtmann 
eir_get_length(u8 * eir,size_t eir_len)5030efdcf8e3SMarcel Holtmann static inline size_t eir_get_length(u8 *eir, size_t eir_len)
5031efdcf8e3SMarcel Holtmann {
5032efdcf8e3SMarcel Holtmann 	size_t parsed = 0;
5033efdcf8e3SMarcel Holtmann 
5034efdcf8e3SMarcel Holtmann 	while (parsed < eir_len) {
5035efdcf8e3SMarcel Holtmann 		u8 field_len = eir[0];
5036efdcf8e3SMarcel Holtmann 
5037efdcf8e3SMarcel Holtmann 		if (field_len == 0)
5038efdcf8e3SMarcel Holtmann 			return parsed;
5039efdcf8e3SMarcel Holtmann 
5040efdcf8e3SMarcel Holtmann 		parsed += field_len + 1;
5041efdcf8e3SMarcel Holtmann 		eir += field_len + 1;
5042efdcf8e3SMarcel Holtmann 	}
5043efdcf8e3SMarcel Holtmann 
5044efdcf8e3SMarcel Holtmann 	return eir_len;
5045efdcf8e3SMarcel Holtmann }
5046efdcf8e3SMarcel Holtmann 
hci_extended_inquiry_result_evt(struct hci_dev * hdev,void * edata,struct sk_buff * skb)50473e54c589SLuiz Augusto von Dentz static void hci_extended_inquiry_result_evt(struct hci_dev *hdev, void *edata,
5048807deac2SGustavo Padovan 					    struct sk_buff *skb)
5049a9de9248SMarcel Holtmann {
50503e54c589SLuiz Augusto von Dentz 	struct hci_ev_ext_inquiry_result *ev = edata;
5051a9de9248SMarcel Holtmann 	struct inquiry_data data;
50529d939d94SVishal Agarwal 	size_t eir_len;
505370a6b8deSLuiz Augusto von Dentz 	int i;
5054a9de9248SMarcel Holtmann 
505570a6b8deSLuiz Augusto von Dentz 	if (!hci_ev_skb_pull(hdev, skb, HCI_EV_EXTENDED_INQUIRY_RESULT,
505670a6b8deSLuiz Augusto von Dentz 			     flex_array_size(ev, info, ev->num)))
505770a6b8deSLuiz Augusto von Dentz 		return;
505870a6b8deSLuiz Augusto von Dentz 
50593e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "num %d", ev->num);
506070a6b8deSLuiz Augusto von Dentz 
506170a6b8deSLuiz Augusto von Dentz 	if (!ev->num)
5062a9de9248SMarcel Holtmann 		return;
5063a9de9248SMarcel Holtmann 
5064d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ))
50651519cc17SAndre Guedes 		return;
50661519cc17SAndre Guedes 
5067a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
5068a9de9248SMarcel Holtmann 
506970a6b8deSLuiz Augusto von Dentz 	for (i = 0; i < ev->num; i++) {
507070a6b8deSLuiz Augusto von Dentz 		struct extended_inquiry_info *info = &ev->info[i];
5071af58925cSMarcel Holtmann 		u32 flags;
5072af58925cSMarcel Holtmann 		bool name_known;
5073561aafbcSJohan Hedberg 
5074a9de9248SMarcel Holtmann 		bacpy(&data.bdaddr, &info->bdaddr);
5075a9de9248SMarcel Holtmann 		data.pscan_rep_mode	= info->pscan_rep_mode;
5076a9de9248SMarcel Holtmann 		data.pscan_period_mode	= info->pscan_period_mode;
5077a9de9248SMarcel Holtmann 		data.pscan_mode		= 0x00;
5078a9de9248SMarcel Holtmann 		memcpy(data.dev_class, info->dev_class, 3);
5079a9de9248SMarcel Holtmann 		data.clock_offset	= info->clock_offset;
5080a9de9248SMarcel Holtmann 		data.rssi		= info->rssi;
508141a96212SMarcel Holtmann 		data.ssp_mode		= 0x01;
5082561aafbcSJohan Hedberg 
5083d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_MGMT))
50840d3b7f64SJohan Hedberg 			name_known = eir_get_data(info->data,
50854ddb1930SJohan Hedberg 						  sizeof(info->data),
50860d3b7f64SJohan Hedberg 						  EIR_NAME_COMPLETE, NULL);
5087561aafbcSJohan Hedberg 		else
5088561aafbcSJohan Hedberg 			name_known = true;
5089561aafbcSJohan Hedberg 
5090af58925cSMarcel Holtmann 		flags = hci_inquiry_cache_update(hdev, &data, name_known);
5091af58925cSMarcel Holtmann 
50929d939d94SVishal Agarwal 		eir_len = eir_get_length(info->data, sizeof(info->data));
5093af58925cSMarcel Holtmann 
509448264f06SJohan Hedberg 		mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
5095af58925cSMarcel Holtmann 				  info->dev_class, info->rssi,
5096b338d917SBrian Gix 				  flags, info->data, eir_len, NULL, 0, 0);
5097a9de9248SMarcel Holtmann 	}
5098a9de9248SMarcel Holtmann 
5099a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
5100a9de9248SMarcel Holtmann }
5101a9de9248SMarcel Holtmann 
hci_key_refresh_complete_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)51023e54c589SLuiz Augusto von Dentz static void hci_key_refresh_complete_evt(struct hci_dev *hdev, void *data,
51031c2e0041SJohan Hedberg 					 struct sk_buff *skb)
51041c2e0041SJohan Hedberg {
51053e54c589SLuiz Augusto von Dentz 	struct hci_ev_key_refresh_complete *ev = data;
51061c2e0041SJohan Hedberg 	struct hci_conn *conn;
51071c2e0041SJohan Hedberg 
51083e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x handle 0x%4.4x", ev->status,
51091c2e0041SJohan Hedberg 		   __le16_to_cpu(ev->handle));
51101c2e0041SJohan Hedberg 
51111c2e0041SJohan Hedberg 	hci_dev_lock(hdev);
51121c2e0041SJohan Hedberg 
51131c2e0041SJohan Hedberg 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
51141c2e0041SJohan Hedberg 	if (!conn)
51151c2e0041SJohan Hedberg 		goto unlock;
51161c2e0041SJohan Hedberg 
51179eb1fbfaSJohan Hedberg 	/* For BR/EDR the necessary steps are taken through the
51189eb1fbfaSJohan Hedberg 	 * auth_complete event.
51199eb1fbfaSJohan Hedberg 	 */
51209eb1fbfaSJohan Hedberg 	if (conn->type != LE_LINK)
51219eb1fbfaSJohan Hedberg 		goto unlock;
51229eb1fbfaSJohan Hedberg 
51231c2e0041SJohan Hedberg 	if (!ev->status)
51241c2e0041SJohan Hedberg 		conn->sec_level = conn->pending_sec_level;
51251c2e0041SJohan Hedberg 
51261c2e0041SJohan Hedberg 	clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
51271c2e0041SJohan Hedberg 
51281c2e0041SJohan Hedberg 	if (ev->status && conn->state == BT_CONNECTED) {
5129bed71748SAndre Guedes 		hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
513076a68ba0SDavid Herrmann 		hci_conn_drop(conn);
51311c2e0041SJohan Hedberg 		goto unlock;
51321c2e0041SJohan Hedberg 	}
51331c2e0041SJohan Hedberg 
51341c2e0041SJohan Hedberg 	if (conn->state == BT_CONFIG) {
51351c2e0041SJohan Hedberg 		if (!ev->status)
51361c2e0041SJohan Hedberg 			conn->state = BT_CONNECTED;
51371c2e0041SJohan Hedberg 
5138539c496dSJohan Hedberg 		hci_connect_cfm(conn, ev->status);
513976a68ba0SDavid Herrmann 		hci_conn_drop(conn);
51401c2e0041SJohan Hedberg 	} else {
51411c2e0041SJohan Hedberg 		hci_auth_cfm(conn, ev->status);
51421c2e0041SJohan Hedberg 
51431c2e0041SJohan Hedberg 		hci_conn_hold(conn);
51441c2e0041SJohan Hedberg 		conn->disc_timeout = HCI_DISCONN_TIMEOUT;
514576a68ba0SDavid Herrmann 		hci_conn_drop(conn);
51461c2e0041SJohan Hedberg 	}
51471c2e0041SJohan Hedberg 
51481c2e0041SJohan Hedberg unlock:
51491c2e0041SJohan Hedberg 	hci_dev_unlock(hdev);
51501c2e0041SJohan Hedberg }
51511c2e0041SJohan Hedberg 
hci_get_auth_req(struct hci_conn * conn)51526039aa73SGustavo Padovan static u8 hci_get_auth_req(struct hci_conn *conn)
515317fa4b9dSJohan Hedberg {
515417fa4b9dSJohan Hedberg 	/* If remote requests no-bonding follow that lead */
5155acabae96SMikel Astiz 	if (conn->remote_auth == HCI_AT_NO_BONDING ||
5156acabae96SMikel Astiz 	    conn->remote_auth == HCI_AT_NO_BONDING_MITM)
515758797bf7SWaldemar Rymarkiewicz 		return conn->remote_auth | (conn->auth_type & 0x01);
515817fa4b9dSJohan Hedberg 
5159b7f94c88SMikel Astiz 	/* If both remote and local have enough IO capabilities, require
5160b7f94c88SMikel Astiz 	 * MITM protection
5161b7f94c88SMikel Astiz 	 */
5162b7f94c88SMikel Astiz 	if (conn->remote_cap != HCI_IO_NO_INPUT_OUTPUT &&
5163b7f94c88SMikel Astiz 	    conn->io_capability != HCI_IO_NO_INPUT_OUTPUT)
5164b7f94c88SMikel Astiz 		return conn->remote_auth | 0x01;
5165b7f94c88SMikel Astiz 
51667e74170aSTimo Mueller 	/* No MITM protection possible so ignore remote requirement */
51677e74170aSTimo Mueller 	return (conn->remote_auth & ~0x01) | (conn->auth_type & 0x01);
516817fa4b9dSJohan Hedberg }
516917fa4b9dSJohan Hedberg 
bredr_oob_data_present(struct hci_conn * conn)5170a83ed81eSMarcel Holtmann static u8 bredr_oob_data_present(struct hci_conn *conn)
5171a83ed81eSMarcel Holtmann {
5172a83ed81eSMarcel Holtmann 	struct hci_dev *hdev = conn->hdev;
5173a83ed81eSMarcel Holtmann 	struct oob_data *data;
5174a83ed81eSMarcel Holtmann 
5175a83ed81eSMarcel Holtmann 	data = hci_find_remote_oob_data(hdev, &conn->dst, BDADDR_BREDR);
5176a83ed81eSMarcel Holtmann 	if (!data)
5177a83ed81eSMarcel Holtmann 		return 0x00;
5178a83ed81eSMarcel Holtmann 
5179bf21d793SMarcel Holtmann 	if (bredr_sc_enabled(hdev)) {
5180bf21d793SMarcel Holtmann 		/* When Secure Connections is enabled, then just
5181bf21d793SMarcel Holtmann 		 * return the present value stored with the OOB
5182bf21d793SMarcel Holtmann 		 * data. The stored value contains the right present
5183bf21d793SMarcel Holtmann 		 * information. However it can only be trusted when
5184bf21d793SMarcel Holtmann 		 * not in Secure Connection Only mode.
5185aa5b0345SMarcel Holtmann 		 */
5186d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_SC_ONLY))
5187bf21d793SMarcel Holtmann 			return data->present;
5188bf21d793SMarcel Holtmann 
5189bf21d793SMarcel Holtmann 		/* When Secure Connections Only mode is enabled, then
5190bf21d793SMarcel Holtmann 		 * the P-256 values are required. If they are not
5191bf21d793SMarcel Holtmann 		 * available, then do not declare that OOB data is
5192bf21d793SMarcel Holtmann 		 * present.
5193bf21d793SMarcel Holtmann 		 */
5194b5412606SLuiz Augusto von Dentz 		if (!crypto_memneq(data->rand256, ZERO_KEY, 16) ||
5195b5412606SLuiz Augusto von Dentz 		    !crypto_memneq(data->hash256, ZERO_KEY, 16))
5196aa5b0345SMarcel Holtmann 			return 0x00;
5197aa5b0345SMarcel Holtmann 
5198bf21d793SMarcel Holtmann 		return 0x02;
5199bf21d793SMarcel Holtmann 	}
5200659c7fb0SMarcel Holtmann 
5201659c7fb0SMarcel Holtmann 	/* When Secure Connections is not enabled or actually
5202659c7fb0SMarcel Holtmann 	 * not supported by the hardware, then check that if
5203659c7fb0SMarcel Holtmann 	 * P-192 data values are present.
5204659c7fb0SMarcel Holtmann 	 */
5205b5412606SLuiz Augusto von Dentz 	if (!crypto_memneq(data->rand192, ZERO_KEY, 16) ||
5206b5412606SLuiz Augusto von Dentz 	    !crypto_memneq(data->hash192, ZERO_KEY, 16))
5207659c7fb0SMarcel Holtmann 		return 0x00;
5208659c7fb0SMarcel Holtmann 
5209a83ed81eSMarcel Holtmann 	return 0x01;
5210659c7fb0SMarcel Holtmann }
5211a83ed81eSMarcel Holtmann 
hci_io_capa_request_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)52123e54c589SLuiz Augusto von Dentz static void hci_io_capa_request_evt(struct hci_dev *hdev, void *data,
52133e54c589SLuiz Augusto von Dentz 				    struct sk_buff *skb)
52140493684eSMarcel Holtmann {
52153e54c589SLuiz Augusto von Dentz 	struct hci_ev_io_capa_request *ev = data;
52160493684eSMarcel Holtmann 	struct hci_conn *conn;
52170493684eSMarcel Holtmann 
52183e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
52190493684eSMarcel Holtmann 
52200493684eSMarcel Holtmann 	hci_dev_lock(hdev);
52210493684eSMarcel Holtmann 
52220493684eSMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
5223fba268acSLuiz Augusto von Dentz 	if (!conn || !hci_dev_test_flag(hdev, HCI_SSP_ENABLED))
522403b555e1SJohan Hedberg 		goto unlock;
522503b555e1SJohan Hedberg 
5226fba268acSLuiz Augusto von Dentz 	/* Assume remote supports SSP since it has triggered this event */
5227fba268acSLuiz Augusto von Dentz 	set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
5228fba268acSLuiz Augusto von Dentz 
52290493684eSMarcel Holtmann 	hci_conn_hold(conn);
52300493684eSMarcel Holtmann 
5231d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
523203b555e1SJohan Hedberg 		goto unlock;
523303b555e1SJohan Hedberg 
52342f407f0aSJohan Hedberg 	/* Allow pairing if we're pairable, the initiators of the
52352f407f0aSJohan Hedberg 	 * pairing or if the remote is not requesting bonding.
52362f407f0aSJohan Hedberg 	 */
5237d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_BONDABLE) ||
52382f407f0aSJohan Hedberg 	    test_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags) ||
523903b555e1SJohan Hedberg 	    (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
524017fa4b9dSJohan Hedberg 		struct hci_cp_io_capability_reply cp;
524117fa4b9dSJohan Hedberg 
524217fa4b9dSJohan Hedberg 		bacpy(&cp.bdaddr, &ev->bdaddr);
52437a7f1e7cSHemant Gupta 		/* Change the IO capability from KeyboardDisplay
52447a7f1e7cSHemant Gupta 		 * to DisplayYesNo as it is not supported by BT spec. */
52457a7f1e7cSHemant Gupta 		cp.capability = (conn->io_capability == 0x04) ?
5246a767631aSMikel Astiz 				HCI_IO_DISPLAY_YESNO : conn->io_capability;
5247b7f94c88SMikel Astiz 
5248b7f94c88SMikel Astiz 		/* If we are initiators, there is no remote information yet */
5249b7f94c88SMikel Astiz 		if (conn->remote_auth == 0xff) {
5250b16c6604SMikel Astiz 			/* Request MITM protection if our IO caps allow it
52514ad51a75SJohan Hedberg 			 * except for the no-bonding case.
5252b16c6604SMikel Astiz 			 */
52536fd6b915SMikel Astiz 			if (conn->io_capability != HCI_IO_NO_INPUT_OUTPUT &&
52549f743d74SJohan Hedberg 			    conn->auth_type != HCI_AT_NO_BONDING)
52556c53823aSJohan Hedberg 				conn->auth_type |= 0x01;
5256b7f94c88SMikel Astiz 		} else {
52577cbc9bd9SJohan Hedberg 			conn->auth_type = hci_get_auth_req(conn);
5258b7f94c88SMikel Astiz 		}
525917fa4b9dSJohan Hedberg 
526082c295b1SJohan Hedberg 		/* If we're not bondable, force one of the non-bondable
526182c295b1SJohan Hedberg 		 * authentication requirement values.
526282c295b1SJohan Hedberg 		 */
5263d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_BONDABLE))
526482c295b1SJohan Hedberg 			conn->auth_type &= HCI_AT_NO_BONDING_MITM;
526582c295b1SJohan Hedberg 
526682c295b1SJohan Hedberg 		cp.authentication = conn->auth_type;
5267a83ed81eSMarcel Holtmann 		cp.oob_data = bredr_oob_data_present(conn);
5268ce85ee13SSzymon Janc 
526917fa4b9dSJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
527017fa4b9dSJohan Hedberg 			     sizeof(cp), &cp);
527103b555e1SJohan Hedberg 	} else {
527203b555e1SJohan Hedberg 		struct hci_cp_io_capability_neg_reply cp;
527303b555e1SJohan Hedberg 
527403b555e1SJohan Hedberg 		bacpy(&cp.bdaddr, &ev->bdaddr);
52759f5a0d7bSAndrei Emeltchenko 		cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
527603b555e1SJohan Hedberg 
527703b555e1SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
527803b555e1SJohan Hedberg 			     sizeof(cp), &cp);
527903b555e1SJohan Hedberg 	}
528003b555e1SJohan Hedberg 
528103b555e1SJohan Hedberg unlock:
528203b555e1SJohan Hedberg 	hci_dev_unlock(hdev);
528303b555e1SJohan Hedberg }
528403b555e1SJohan Hedberg 
hci_io_capa_reply_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)52853e54c589SLuiz Augusto von Dentz static void hci_io_capa_reply_evt(struct hci_dev *hdev, void *data,
52863e54c589SLuiz Augusto von Dentz 				  struct sk_buff *skb)
528703b555e1SJohan Hedberg {
52883e54c589SLuiz Augusto von Dentz 	struct hci_ev_io_capa_reply *ev = data;
528903b555e1SJohan Hedberg 	struct hci_conn *conn;
529003b555e1SJohan Hedberg 
52913e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
529203b555e1SJohan Hedberg 
529303b555e1SJohan Hedberg 	hci_dev_lock(hdev);
529403b555e1SJohan Hedberg 
529503b555e1SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
529603b555e1SJohan Hedberg 	if (!conn)
529703b555e1SJohan Hedberg 		goto unlock;
529803b555e1SJohan Hedberg 
529903b555e1SJohan Hedberg 	conn->remote_cap = ev->capability;
530003b555e1SJohan Hedberg 	conn->remote_auth = ev->authentication;
530103b555e1SJohan Hedberg 
530203b555e1SJohan Hedberg unlock:
53030493684eSMarcel Holtmann 	hci_dev_unlock(hdev);
53040493684eSMarcel Holtmann }
53050493684eSMarcel Holtmann 
hci_user_confirm_request_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)53063e54c589SLuiz Augusto von Dentz static void hci_user_confirm_request_evt(struct hci_dev *hdev, void *data,
5307a5c29683SJohan Hedberg 					 struct sk_buff *skb)
5308a5c29683SJohan Hedberg {
53093e54c589SLuiz Augusto von Dentz 	struct hci_ev_user_confirm_req *ev = data;
531055bc1a37SJohan Hedberg 	int loc_mitm, rem_mitm, confirm_hint = 0;
53117a828908SJohan Hedberg 	struct hci_conn *conn;
5312a5c29683SJohan Hedberg 
53133e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
5314a5c29683SJohan Hedberg 
5315a5c29683SJohan Hedberg 	hci_dev_lock(hdev);
5316a5c29683SJohan Hedberg 
5317d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
53187a828908SJohan Hedberg 		goto unlock;
53197a828908SJohan Hedberg 
53207a828908SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
53217a828908SJohan Hedberg 	if (!conn)
53227a828908SJohan Hedberg 		goto unlock;
53237a828908SJohan Hedberg 
53247a828908SJohan Hedberg 	loc_mitm = (conn->auth_type & 0x01);
53257a828908SJohan Hedberg 	rem_mitm = (conn->remote_auth & 0x01);
53267a828908SJohan Hedberg 
53277a828908SJohan Hedberg 	/* If we require MITM but the remote device can't provide that
53286c53823aSJohan Hedberg 	 * (it has NoInputNoOutput) then reject the confirmation
53296c53823aSJohan Hedberg 	 * request. We check the security level here since it doesn't
53306c53823aSJohan Hedberg 	 * necessarily match conn->auth_type.
53316fd6b915SMikel Astiz 	 */
53326c53823aSJohan Hedberg 	if (conn->pending_sec_level > BT_SECURITY_MEDIUM &&
53336c53823aSJohan Hedberg 	    conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
53343e54c589SLuiz Augusto von Dentz 		bt_dev_dbg(hdev, "Rejecting request: remote device can't provide MITM");
53357a828908SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
53367a828908SJohan Hedberg 			     sizeof(ev->bdaddr), &ev->bdaddr);
53377a828908SJohan Hedberg 		goto unlock;
53387a828908SJohan Hedberg 	}
53397a828908SJohan Hedberg 
53407a828908SJohan Hedberg 	/* If no side requires MITM protection; auto-accept */
5341a767631aSMikel Astiz 	if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
5342a767631aSMikel Astiz 	    (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
534355bc1a37SJohan Hedberg 
534455bc1a37SJohan Hedberg 		/* If we're not the initiators request authorization to
534555bc1a37SJohan Hedberg 		 * proceed from user space (mgmt_user_confirm with
5346ba15a58bSJohan Hedberg 		 * confirm_hint set to 1). The exception is if neither
534702f3e254SJohan Hedberg 		 * side had MITM or if the local IO capability is
534802f3e254SJohan Hedberg 		 * NoInputNoOutput, in which case we do auto-accept
5349ba15a58bSJohan Hedberg 		 */
5350ba15a58bSJohan Hedberg 		if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) &&
535102f3e254SJohan Hedberg 		    conn->io_capability != HCI_IO_NO_INPUT_OUTPUT &&
5352ba15a58bSJohan Hedberg 		    (loc_mitm || rem_mitm)) {
53533e54c589SLuiz Augusto von Dentz 			bt_dev_dbg(hdev, "Confirming auto-accept as acceptor");
535455bc1a37SJohan Hedberg 			confirm_hint = 1;
535555bc1a37SJohan Hedberg 			goto confirm;
535655bc1a37SJohan Hedberg 		}
535755bc1a37SJohan Hedberg 
5358cee5f20fSHoward Chung 		/* If there already exists link key in local host, leave the
5359cee5f20fSHoward Chung 		 * decision to user space since the remote device could be
5360cee5f20fSHoward Chung 		 * legitimate or malicious.
5361cee5f20fSHoward Chung 		 */
5362cee5f20fSHoward Chung 		if (hci_find_link_key(hdev, &ev->bdaddr)) {
5363cee5f20fSHoward Chung 			bt_dev_dbg(hdev, "Local host already has link key");
5364cee5f20fSHoward Chung 			confirm_hint = 1;
5365cee5f20fSHoward Chung 			goto confirm;
5366cee5f20fSHoward Chung 		}
5367cee5f20fSHoward Chung 
53689f61656aSJohan Hedberg 		BT_DBG("Auto-accept of user confirmation with %ums delay",
53699f61656aSJohan Hedberg 		       hdev->auto_accept_delay);
53709f61656aSJohan Hedberg 
53719f61656aSJohan Hedberg 		if (hdev->auto_accept_delay > 0) {
53729f61656aSJohan Hedberg 			int delay = msecs_to_jiffies(hdev->auto_accept_delay);
53737bc18d9dSJohan Hedberg 			queue_delayed_work(conn->hdev->workqueue,
53747bc18d9dSJohan Hedberg 					   &conn->auto_accept_work, delay);
53759f61656aSJohan Hedberg 			goto unlock;
53769f61656aSJohan Hedberg 		}
53779f61656aSJohan Hedberg 
53787a828908SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
53797a828908SJohan Hedberg 			     sizeof(ev->bdaddr), &ev->bdaddr);
53807a828908SJohan Hedberg 		goto unlock;
53817a828908SJohan Hedberg 	}
53827a828908SJohan Hedberg 
538355bc1a37SJohan Hedberg confirm:
538439adbffeSJohan Hedberg 	mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0,
538539adbffeSJohan Hedberg 				  le32_to_cpu(ev->passkey), confirm_hint);
5386a5c29683SJohan Hedberg 
53877a828908SJohan Hedberg unlock:
5388a5c29683SJohan Hedberg 	hci_dev_unlock(hdev);
5389a5c29683SJohan Hedberg }
5390a5c29683SJohan Hedberg 
hci_user_passkey_request_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)53913e54c589SLuiz Augusto von Dentz static void hci_user_passkey_request_evt(struct hci_dev *hdev, void *data,
53921143d458SBrian Gix 					 struct sk_buff *skb)
53931143d458SBrian Gix {
53943e54c589SLuiz Augusto von Dentz 	struct hci_ev_user_passkey_req *ev = data;
5395ae61a10dSLuiz Augusto von Dentz 
53963e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
53971143d458SBrian Gix 
5398d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
5399272d90dfSJohan Hedberg 		mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
54001143d458SBrian Gix }
54011143d458SBrian Gix 
hci_user_passkey_notify_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)54023e54c589SLuiz Augusto von Dentz static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
540392a25256SJohan Hedberg 					struct sk_buff *skb)
540492a25256SJohan Hedberg {
54053e54c589SLuiz Augusto von Dentz 	struct hci_ev_user_passkey_notify *ev = data;
540692a25256SJohan Hedberg 	struct hci_conn *conn;
540792a25256SJohan Hedberg 
54083e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
540992a25256SJohan Hedberg 
541092a25256SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
541192a25256SJohan Hedberg 	if (!conn)
541292a25256SJohan Hedberg 		return;
541392a25256SJohan Hedberg 
541492a25256SJohan Hedberg 	conn->passkey_notify = __le32_to_cpu(ev->passkey);
541592a25256SJohan Hedberg 	conn->passkey_entered = 0;
541692a25256SJohan Hedberg 
5417d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
541892a25256SJohan Hedberg 		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
541992a25256SJohan Hedberg 					 conn->dst_type, conn->passkey_notify,
542092a25256SJohan Hedberg 					 conn->passkey_entered);
542192a25256SJohan Hedberg }
542292a25256SJohan Hedberg 
hci_keypress_notify_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)54233e54c589SLuiz Augusto von Dentz static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
54243e54c589SLuiz Augusto von Dentz 				    struct sk_buff *skb)
542592a25256SJohan Hedberg {
54263e54c589SLuiz Augusto von Dentz 	struct hci_ev_keypress_notify *ev = data;
542792a25256SJohan Hedberg 	struct hci_conn *conn;
542892a25256SJohan Hedberg 
54293e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
543092a25256SJohan Hedberg 
543192a25256SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
543292a25256SJohan Hedberg 	if (!conn)
543392a25256SJohan Hedberg 		return;
543492a25256SJohan Hedberg 
543592a25256SJohan Hedberg 	switch (ev->type) {
543692a25256SJohan Hedberg 	case HCI_KEYPRESS_STARTED:
543792a25256SJohan Hedberg 		conn->passkey_entered = 0;
543892a25256SJohan Hedberg 		return;
543992a25256SJohan Hedberg 
544092a25256SJohan Hedberg 	case HCI_KEYPRESS_ENTERED:
544192a25256SJohan Hedberg 		conn->passkey_entered++;
544292a25256SJohan Hedberg 		break;
544392a25256SJohan Hedberg 
544492a25256SJohan Hedberg 	case HCI_KEYPRESS_ERASED:
544592a25256SJohan Hedberg 		conn->passkey_entered--;
544692a25256SJohan Hedberg 		break;
544792a25256SJohan Hedberg 
544892a25256SJohan Hedberg 	case HCI_KEYPRESS_CLEARED:
544992a25256SJohan Hedberg 		conn->passkey_entered = 0;
545092a25256SJohan Hedberg 		break;
545192a25256SJohan Hedberg 
545292a25256SJohan Hedberg 	case HCI_KEYPRESS_COMPLETED:
545392a25256SJohan Hedberg 		return;
545492a25256SJohan Hedberg 	}
545592a25256SJohan Hedberg 
5456d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
545792a25256SJohan Hedberg 		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
545892a25256SJohan Hedberg 					 conn->dst_type, conn->passkey_notify,
545992a25256SJohan Hedberg 					 conn->passkey_entered);
546092a25256SJohan Hedberg }
546192a25256SJohan Hedberg 
hci_simple_pair_complete_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)54623e54c589SLuiz Augusto von Dentz static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,
5463807deac2SGustavo Padovan 					 struct sk_buff *skb)
54640493684eSMarcel Holtmann {
54653e54c589SLuiz Augusto von Dentz 	struct hci_ev_simple_pair_complete *ev = data;
54660493684eSMarcel Holtmann 	struct hci_conn *conn;
54670493684eSMarcel Holtmann 
54683e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
54690493684eSMarcel Holtmann 
54700493684eSMarcel Holtmann 	hci_dev_lock(hdev);
54710493684eSMarcel Holtmann 
54720493684eSMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
5473c7f59461SZiyang Xuan 	if (!conn || !hci_conn_ssp_enabled(conn))
54742a611692SJohan Hedberg 		goto unlock;
54752a611692SJohan Hedberg 
5476c1d4fa7aSJohan Hedberg 	/* Reset the authentication requirement to unknown */
5477c1d4fa7aSJohan Hedberg 	conn->remote_auth = 0xff;
5478c1d4fa7aSJohan Hedberg 
54792a611692SJohan Hedberg 	/* To avoid duplicate auth_failed events to user space we check
54802a611692SJohan Hedberg 	 * the HCI_CONN_AUTH_PEND flag which will be set if we
54812a611692SJohan Hedberg 	 * initiated the authentication. A traditional auth_complete
54822a611692SJohan Hedberg 	 * event gets always produced as initiator and is also mapped to
54832a611692SJohan Hedberg 	 * the mgmt_auth_failed event */
5484fa1bd918SMikel Astiz 	if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
5485e1e930f5SJohan Hedberg 		mgmt_auth_failed(conn, ev->status);
54862a611692SJohan Hedberg 
548776a68ba0SDavid Herrmann 	hci_conn_drop(conn);
54880493684eSMarcel Holtmann 
54892a611692SJohan Hedberg unlock:
54900493684eSMarcel Holtmann 	hci_dev_unlock(hdev);
54910493684eSMarcel Holtmann }
54920493684eSMarcel Holtmann 
hci_remote_host_features_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)54933e54c589SLuiz Augusto von Dentz static void hci_remote_host_features_evt(struct hci_dev *hdev, void *data,
5494807deac2SGustavo Padovan 					 struct sk_buff *skb)
549541a96212SMarcel Holtmann {
54963e54c589SLuiz Augusto von Dentz 	struct hci_ev_remote_host_features *ev = data;
549741a96212SMarcel Holtmann 	struct inquiry_entry *ie;
5498cad718edSJohan Hedberg 	struct hci_conn *conn;
549941a96212SMarcel Holtmann 
55003e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
550141a96212SMarcel Holtmann 
550241a96212SMarcel Holtmann 	hci_dev_lock(hdev);
550341a96212SMarcel Holtmann 
5504cad718edSJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
5505cad718edSJohan Hedberg 	if (conn)
5506cad718edSJohan Hedberg 		memcpy(conn->features[1], ev->features, 8);
5507cad718edSJohan Hedberg 
5508cc11b9c1SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
5509cc11b9c1SAndrei Emeltchenko 	if (ie)
551002b7cc62SJohan Hedberg 		ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
551141a96212SMarcel Holtmann 
551241a96212SMarcel Holtmann 	hci_dev_unlock(hdev);
551341a96212SMarcel Holtmann }
551441a96212SMarcel Holtmann 
hci_remote_oob_data_request_evt(struct hci_dev * hdev,void * edata,struct sk_buff * skb)55153e54c589SLuiz Augusto von Dentz static void hci_remote_oob_data_request_evt(struct hci_dev *hdev, void *edata,
55162763eda6SSzymon Janc 					    struct sk_buff *skb)
55172763eda6SSzymon Janc {
55183e54c589SLuiz Augusto von Dentz 	struct hci_ev_remote_oob_data_request *ev = edata;
55192763eda6SSzymon Janc 	struct oob_data *data;
55202763eda6SSzymon Janc 
55213e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "");
55222763eda6SSzymon Janc 
55232763eda6SSzymon Janc 	hci_dev_lock(hdev);
55242763eda6SSzymon Janc 
5525d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
5526e1ba1f15SSzymon Janc 		goto unlock;
5527e1ba1f15SSzymon Janc 
55286928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, &ev->bdaddr, BDADDR_BREDR);
55296665d057SMarcel Holtmann 	if (!data) {
55306665d057SMarcel Holtmann 		struct hci_cp_remote_oob_data_neg_reply cp;
55316665d057SMarcel Holtmann 
55326665d057SMarcel Holtmann 		bacpy(&cp.bdaddr, &ev->bdaddr);
55336665d057SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY,
55346665d057SMarcel Holtmann 			     sizeof(cp), &cp);
55356665d057SMarcel Holtmann 		goto unlock;
55366665d057SMarcel Holtmann 	}
55376665d057SMarcel Holtmann 
5538710f11c0SJohan Hedberg 	if (bredr_sc_enabled(hdev)) {
5539519ca9d0SMarcel Holtmann 		struct hci_cp_remote_oob_ext_data_reply cp;
5540519ca9d0SMarcel Holtmann 
5541519ca9d0SMarcel Holtmann 		bacpy(&cp.bdaddr, &ev->bdaddr);
5542d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_SC_ONLY)) {
55436665d057SMarcel Holtmann 			memset(cp.hash192, 0, sizeof(cp.hash192));
55446665d057SMarcel Holtmann 			memset(cp.rand192, 0, sizeof(cp.rand192));
55456665d057SMarcel Holtmann 		} else {
5546519ca9d0SMarcel Holtmann 			memcpy(cp.hash192, data->hash192, sizeof(cp.hash192));
554738da1703SJohan Hedberg 			memcpy(cp.rand192, data->rand192, sizeof(cp.rand192));
55486665d057SMarcel Holtmann 		}
5549519ca9d0SMarcel Holtmann 		memcpy(cp.hash256, data->hash256, sizeof(cp.hash256));
555038da1703SJohan Hedberg 		memcpy(cp.rand256, data->rand256, sizeof(cp.rand256));
5551519ca9d0SMarcel Holtmann 
5552519ca9d0SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY,
5553519ca9d0SMarcel Holtmann 			     sizeof(cp), &cp);
5554519ca9d0SMarcel Holtmann 	} else {
55552763eda6SSzymon Janc 		struct hci_cp_remote_oob_data_reply cp;
55562763eda6SSzymon Janc 
55572763eda6SSzymon Janc 		bacpy(&cp.bdaddr, &ev->bdaddr);
5558519ca9d0SMarcel Holtmann 		memcpy(cp.hash, data->hash192, sizeof(cp.hash));
555938da1703SJohan Hedberg 		memcpy(cp.rand, data->rand192, sizeof(cp.rand));
55602763eda6SSzymon Janc 
5561519ca9d0SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY,
5562519ca9d0SMarcel Holtmann 			     sizeof(cp), &cp);
5563519ca9d0SMarcel Holtmann 	}
55642763eda6SSzymon Janc 
5565e1ba1f15SSzymon Janc unlock:
55662763eda6SSzymon Janc 	hci_dev_unlock(hdev);
55672763eda6SSzymon Janc }
55682763eda6SSzymon Janc 
le_conn_update_addr(struct hci_conn * conn,bdaddr_t * bdaddr,u8 bdaddr_type,bdaddr_t * local_rpa)5569cafae4cdSLuiz Augusto von Dentz static void le_conn_update_addr(struct hci_conn *conn, bdaddr_t *bdaddr,
5570cafae4cdSLuiz Augusto von Dentz 				u8 bdaddr_type, bdaddr_t *local_rpa)
5571cafae4cdSLuiz Augusto von Dentz {
5572cafae4cdSLuiz Augusto von Dentz 	if (conn->out) {
5573cafae4cdSLuiz Augusto von Dentz 		conn->dst_type = bdaddr_type;
5574cafae4cdSLuiz Augusto von Dentz 		conn->resp_addr_type = bdaddr_type;
5575cafae4cdSLuiz Augusto von Dentz 		bacpy(&conn->resp_addr, bdaddr);
5576cafae4cdSLuiz Augusto von Dentz 
5577cafae4cdSLuiz Augusto von Dentz 		/* Check if the controller has set a Local RPA then it must be
5578cafae4cdSLuiz Augusto von Dentz 		 * used instead or hdev->rpa.
5579cafae4cdSLuiz Augusto von Dentz 		 */
5580cafae4cdSLuiz Augusto von Dentz 		if (local_rpa && bacmp(local_rpa, BDADDR_ANY)) {
5581cafae4cdSLuiz Augusto von Dentz 			conn->init_addr_type = ADDR_LE_DEV_RANDOM;
5582cafae4cdSLuiz Augusto von Dentz 			bacpy(&conn->init_addr, local_rpa);
5583cafae4cdSLuiz Augusto von Dentz 		} else if (hci_dev_test_flag(conn->hdev, HCI_PRIVACY)) {
5584cafae4cdSLuiz Augusto von Dentz 			conn->init_addr_type = ADDR_LE_DEV_RANDOM;
5585cafae4cdSLuiz Augusto von Dentz 			bacpy(&conn->init_addr, &conn->hdev->rpa);
5586cafae4cdSLuiz Augusto von Dentz 		} else {
5587cafae4cdSLuiz Augusto von Dentz 			hci_copy_identity_address(conn->hdev, &conn->init_addr,
5588cafae4cdSLuiz Augusto von Dentz 						  &conn->init_addr_type);
5589cafae4cdSLuiz Augusto von Dentz 		}
5590cafae4cdSLuiz Augusto von Dentz 	} else {
5591cafae4cdSLuiz Augusto von Dentz 		conn->resp_addr_type = conn->hdev->adv_addr_type;
5592cafae4cdSLuiz Augusto von Dentz 		/* Check if the controller has set a Local RPA then it must be
5593cafae4cdSLuiz Augusto von Dentz 		 * used instead or hdev->rpa.
5594cafae4cdSLuiz Augusto von Dentz 		 */
5595cafae4cdSLuiz Augusto von Dentz 		if (local_rpa && bacmp(local_rpa, BDADDR_ANY)) {
5596cafae4cdSLuiz Augusto von Dentz 			conn->resp_addr_type = ADDR_LE_DEV_RANDOM;
5597cafae4cdSLuiz Augusto von Dentz 			bacpy(&conn->resp_addr, local_rpa);
5598cafae4cdSLuiz Augusto von Dentz 		} else if (conn->hdev->adv_addr_type == ADDR_LE_DEV_RANDOM) {
5599cafae4cdSLuiz Augusto von Dentz 			/* In case of ext adv, resp_addr will be updated in
5600cafae4cdSLuiz Augusto von Dentz 			 * Adv Terminated event.
5601cafae4cdSLuiz Augusto von Dentz 			 */
5602cafae4cdSLuiz Augusto von Dentz 			if (!ext_adv_capable(conn->hdev))
5603cafae4cdSLuiz Augusto von Dentz 				bacpy(&conn->resp_addr,
5604cafae4cdSLuiz Augusto von Dentz 				      &conn->hdev->random_addr);
5605cafae4cdSLuiz Augusto von Dentz 		} else {
5606cafae4cdSLuiz Augusto von Dentz 			bacpy(&conn->resp_addr, &conn->hdev->bdaddr);
5607cafae4cdSLuiz Augusto von Dentz 		}
5608cafae4cdSLuiz Augusto von Dentz 
5609cafae4cdSLuiz Augusto von Dentz 		conn->init_addr_type = bdaddr_type;
5610cafae4cdSLuiz Augusto von Dentz 		bacpy(&conn->init_addr, bdaddr);
5611cafae4cdSLuiz Augusto von Dentz 
5612cafae4cdSLuiz Augusto von Dentz 		/* For incoming connections, set the default minimum
5613cafae4cdSLuiz Augusto von Dentz 		 * and maximum connection interval. They will be used
5614cafae4cdSLuiz Augusto von Dentz 		 * to check if the parameters are in range and if not
5615cafae4cdSLuiz Augusto von Dentz 		 * trigger the connection update procedure.
5616cafae4cdSLuiz Augusto von Dentz 		 */
5617cafae4cdSLuiz Augusto von Dentz 		conn->le_conn_min_interval = conn->hdev->le_conn_min_interval;
5618cafae4cdSLuiz Augusto von Dentz 		conn->le_conn_max_interval = conn->hdev->le_conn_max_interval;
5619cafae4cdSLuiz Augusto von Dentz 	}
5620cafae4cdSLuiz Augusto von Dentz }
5621cafae4cdSLuiz Augusto von Dentz 
le_conn_complete_evt(struct hci_dev * hdev,u8 status,bdaddr_t * bdaddr,u8 bdaddr_type,bdaddr_t * local_rpa,u8 role,u16 handle,u16 interval,u16 latency,u16 supervision_timeout)5622d12fb056SJaganath Kanakkassery static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
5623cafae4cdSLuiz Augusto von Dentz 				 bdaddr_t *bdaddr, u8 bdaddr_type,
5624cafae4cdSLuiz Augusto von Dentz 				 bdaddr_t *local_rpa, u8 role, u16 handle,
5625cafae4cdSLuiz Augusto von Dentz 				 u16 interval, u16 latency,
5626cafae4cdSLuiz Augusto von Dentz 				 u16 supervision_timeout)
5627fcd89c09SVille Tervo {
5628912b42efSJohan Hedberg 	struct hci_conn_params *params;
5629fcd89c09SVille Tervo 	struct hci_conn *conn;
563068d6f6deSJohan Hedberg 	struct smp_irk *irk;
5631837d502eSJohan Hedberg 	u8 addr_type;
5632fcd89c09SVille Tervo 
5633fcd89c09SVille Tervo 	hci_dev_lock(hdev);
5634fcd89c09SVille Tervo 
5635fbd96c15SJohan Hedberg 	/* All controllers implicitly stop advertising in the event of a
5636fbd96c15SJohan Hedberg 	 * connection, so ensure that the state bit is cleared.
5637fbd96c15SJohan Hedberg 	 */
5638a358dc11SMarcel Holtmann 	hci_dev_clear_flag(hdev, HCI_LE_ADV);
5639fbd96c15SJohan Hedberg 
564053562665SArchie Pusaka 	conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, bdaddr);
5641b62f328bSVille Tervo 	if (!conn) {
5642aef2aa4fSLuiz Augusto von Dentz 		/* In case of error status and there is no connection pending
5643aef2aa4fSLuiz Augusto von Dentz 		 * just unlock as there is nothing to cleanup.
5644aef2aa4fSLuiz Augusto von Dentz 		 */
5645aef2aa4fSLuiz Augusto von Dentz 		if (status)
5646aef2aa4fSLuiz Augusto von Dentz 			goto unlock;
5647aef2aa4fSLuiz Augusto von Dentz 
564884cb0143SZiyang Xuan 		conn = hci_conn_add_unset(hdev, LE_LINK, bdaddr, role);
5649ad3f7986SSungwoo Kim 		if (IS_ERR(conn)) {
5650ad3f7986SSungwoo Kim 			bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn));
5651230fd16aSAndre Guedes 			goto unlock;
5652b62f328bSVille Tervo 		}
565329b7988aSAndre Guedes 
5654d12fb056SJaganath Kanakkassery 		conn->dst_type = bdaddr_type;
5655b9b343d2SAndre Guedes 
5656cb1d68f7SJohan Hedberg 		/* If we didn't have a hci_conn object previously
565774be523cSArchie Pusaka 		 * but we're in central role this must be something
56583d4f9c00SArchie Pusaka 		 * initiated using an accept list. Since accept list based
5659cb1d68f7SJohan Hedberg 		 * connections are not "first class citizens" we don't
5660cb1d68f7SJohan Hedberg 		 * have full tracking of them. Therefore, we go ahead
5661cb1d68f7SJohan Hedberg 		 * with a "best effort" approach of determining the
5662cb1d68f7SJohan Hedberg 		 * initiator address based on the HCI_PRIVACY flag.
5663cb1d68f7SJohan Hedberg 		 */
5664cb1d68f7SJohan Hedberg 		if (conn->out) {
5665d12fb056SJaganath Kanakkassery 			conn->resp_addr_type = bdaddr_type;
5666d12fb056SJaganath Kanakkassery 			bacpy(&conn->resp_addr, bdaddr);
5667d7a5a11dSMarcel Holtmann 			if (hci_dev_test_flag(hdev, HCI_PRIVACY)) {
5668cb1d68f7SJohan Hedberg 				conn->init_addr_type = ADDR_LE_DEV_RANDOM;
5669cb1d68f7SJohan Hedberg 				bacpy(&conn->init_addr, &hdev->rpa);
5670cb1d68f7SJohan Hedberg 			} else {
5671cb1d68f7SJohan Hedberg 				hci_copy_identity_address(hdev,
5672cb1d68f7SJohan Hedberg 							  &conn->init_addr,
5673cb1d68f7SJohan Hedberg 							  &conn->init_addr_type);
5674cb1d68f7SJohan Hedberg 			}
567580c24ab8SJohan Hedberg 		}
5676cb1d68f7SJohan Hedberg 	} else {
567780c24ab8SJohan Hedberg 		cancel_delayed_work(&conn->le_conn_timeout);
567880c24ab8SJohan Hedberg 	}
567980c24ab8SJohan Hedberg 
5680d5ebaa7cSSoenke Huster 	/* The HCI_LE_Connection_Complete event is only sent once per connection.
5681d5ebaa7cSSoenke Huster 	 * Processing it more than once per connection can corrupt kernel memory.
5682d5ebaa7cSSoenke Huster 	 *
5683d5ebaa7cSSoenke Huster 	 * As the connection handle is set here for the first time, it indicates
5684d5ebaa7cSSoenke Huster 	 * whether the connection is already set up.
5685d5ebaa7cSSoenke Huster 	 */
56869f78191cSLuiz Augusto von Dentz 	if (!HCI_CONN_HANDLE_UNSET(conn->handle)) {
5687d5ebaa7cSSoenke Huster 		bt_dev_err(hdev, "Ignoring HCI_Connection_Complete for existing connection");
5688d5ebaa7cSSoenke Huster 		goto unlock;
5689d5ebaa7cSSoenke Huster 	}
5690d5ebaa7cSSoenke Huster 
5691cafae4cdSLuiz Augusto von Dentz 	le_conn_update_addr(conn, bdaddr, bdaddr_type, local_rpa);
56927be2edbbSJohan Hedberg 
5693edb4b466SMarcel Holtmann 	/* Lookup the identity address from the stored connection
5694edb4b466SMarcel Holtmann 	 * address and address type.
5695edb4b466SMarcel Holtmann 	 *
5696edb4b466SMarcel Holtmann 	 * When establishing connections to an identity address, the
5697edb4b466SMarcel Holtmann 	 * connection procedure will store the resolvable random
5698edb4b466SMarcel Holtmann 	 * address first. Now if it can be converted back into the
5699edb4b466SMarcel Holtmann 	 * identity address, start using the identity address from
5700edb4b466SMarcel Holtmann 	 * now on.
5701edb4b466SMarcel Holtmann 	 */
5702edb4b466SMarcel Holtmann 	irk = hci_get_irk(hdev, &conn->dst, conn->dst_type);
570368d6f6deSJohan Hedberg 	if (irk) {
570468d6f6deSJohan Hedberg 		bacpy(&conn->dst, &irk->bdaddr);
570568d6f6deSJohan Hedberg 		conn->dst_type = irk->addr_type;
570668d6f6deSJohan Hedberg 	}
570768d6f6deSJohan Hedberg 
5708d850bf08SLuiz Augusto von Dentz 	conn->dst_type = ev_bdaddr_type(hdev, conn->dst_type, NULL);
570979699a70SSathish Narasimman 
5710c9f73a21SLuiz Augusto von Dentz 	/* All connection failure handling is taken care of by the
5711c9f73a21SLuiz Augusto von Dentz 	 * hci_conn_failed function which is triggered by the HCI
5712c9f73a21SLuiz Augusto von Dentz 	 * request completion callbacks used for connecting.
5713c9f73a21SLuiz Augusto von Dentz 	 */
571484cb0143SZiyang Xuan 	if (status || hci_conn_set_handle(conn, handle))
5715837d502eSJohan Hedberg 		goto unlock;
5716837d502eSJohan Hedberg 
5717b62e7220SLuiz Augusto von Dentz 	/* Drop the connection if it has been aborted */
5718b62e7220SLuiz Augusto von Dentz 	if (test_bit(HCI_CONN_CANCEL, &conn->flags)) {
5719b62e7220SLuiz Augusto von Dentz 		hci_conn_drop(conn);
5720b62e7220SLuiz Augusto von Dentz 		goto unlock;
5721b62e7220SLuiz Augusto von Dentz 	}
5722b62e7220SLuiz Augusto von Dentz 
572308853f18SJohan Hedberg 	if (conn->dst_type == ADDR_LE_DEV_PUBLIC)
572408853f18SJohan Hedberg 		addr_type = BDADDR_LE_PUBLIC;
572508853f18SJohan Hedberg 	else
572608853f18SJohan Hedberg 		addr_type = BDADDR_LE_RANDOM;
572708853f18SJohan Hedberg 
57282d3c2260SJohan Hedberg 	/* Drop the connection if the device is blocked */
57293d4f9c00SArchie Pusaka 	if (hci_bdaddr_list_lookup(&hdev->reject_list, &conn->dst, addr_type)) {
57302d3c2260SJohan Hedberg 		hci_conn_drop(conn);
5731cd17decbSAndre Guedes 		goto unlock;
5732cd17decbSAndre Guedes 	}
5733cd17decbSAndre Guedes 
57341c6ed31bSYu Liu 	mgmt_device_connected(hdev, conn, NULL, 0);
573583bc71b4SVinicius Costa Gomes 
57367b5c0d52SVinicius Costa Gomes 	conn->sec_level = BT_SECURITY_LOW;
57370fe29fd1SMarcel Holtmann 	conn->state = BT_CONFIG;
5738fcd89c09SVille Tervo 
57397087c4f6SLuiz Augusto von Dentz 	/* Store current advertising instance as connection advertising instance
57407087c4f6SLuiz Augusto von Dentz 	 * when sotfware rotation is in use so it can be re-enabled when
57417087c4f6SLuiz Augusto von Dentz 	 * disconnected.
57427087c4f6SLuiz Augusto von Dentz 	 */
57437087c4f6SLuiz Augusto von Dentz 	if (!ext_adv_capable(hdev))
57447087c4f6SLuiz Augusto von Dentz 		conn->adv_instance = hdev->cur_adv_instance;
57457087c4f6SLuiz Augusto von Dentz 
5746d12fb056SJaganath Kanakkassery 	conn->le_conn_interval = interval;
5747d12fb056SJaganath Kanakkassery 	conn->le_conn_latency = latency;
5748d12fb056SJaganath Kanakkassery 	conn->le_supv_timeout = supervision_timeout;
5749e04fde60SMarcel Holtmann 
575023b9ceb7SMarcel Holtmann 	hci_debugfs_create_conn(conn);
5751fcd89c09SVille Tervo 	hci_conn_add_sysfs(conn);
5752fcd89c09SVille Tervo 
5753ef365da1SArchie Pusaka 	/* The remote features procedure is defined for central
57540fe29fd1SMarcel Holtmann 	 * role only. So only in case of an initiated connection
57550fe29fd1SMarcel Holtmann 	 * request the remote features.
57560fe29fd1SMarcel Holtmann 	 *
5757ef365da1SArchie Pusaka 	 * If the local controller supports peripheral-initiated features
5758ef365da1SArchie Pusaka 	 * exchange, then requesting the remote features in peripheral
57590fe29fd1SMarcel Holtmann 	 * role is possible. Otherwise just transition into the
57600fe29fd1SMarcel Holtmann 	 * connected state without requesting the remote features.
57610fe29fd1SMarcel Holtmann 	 */
57620fe29fd1SMarcel Holtmann 	if (conn->out ||
5763ef365da1SArchie Pusaka 	    (hdev->le_features[0] & HCI_LE_PERIPHERAL_FEATURES)) {
57640fe29fd1SMarcel Holtmann 		struct hci_cp_le_read_remote_features cp;
57650fe29fd1SMarcel Holtmann 
57660fe29fd1SMarcel Holtmann 		cp.handle = __cpu_to_le16(conn->handle);
57670fe29fd1SMarcel Holtmann 
57680fe29fd1SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_LE_READ_REMOTE_FEATURES,
57690fe29fd1SMarcel Holtmann 			     sizeof(cp), &cp);
57700fe29fd1SMarcel Holtmann 
57710fe29fd1SMarcel Holtmann 		hci_conn_hold(conn);
57720fe29fd1SMarcel Holtmann 	} else {
57730fe29fd1SMarcel Holtmann 		conn->state = BT_CONNECTED;
5774d12fb056SJaganath Kanakkassery 		hci_connect_cfm(conn, status);
57750fe29fd1SMarcel Holtmann 	}
5776fcd89c09SVille Tervo 
57775477610fSJohan Hedberg 	params = hci_pend_le_action_lookup(&hdev->pend_le_conns, &conn->dst,
57785477610fSJohan Hedberg 					   conn->dst_type);
5779f161dd41SJohan Hedberg 	if (params) {
5780195ef75eSPauli Virtanen 		hci_pend_le_list_del_init(params);
5781f161dd41SJohan Hedberg 		if (params->conn) {
5782f161dd41SJohan Hedberg 			hci_conn_drop(params->conn);
5783f8aaf9b6SJohan Hedberg 			hci_conn_put(params->conn);
5784f161dd41SJohan Hedberg 			params->conn = NULL;
5785f161dd41SJohan Hedberg 		}
5786f161dd41SJohan Hedberg 	}
5787a4790dbdSAndre Guedes 
5788fcd89c09SVille Tervo unlock:
57895bee2fd6SLuiz Augusto von Dentz 	hci_update_passive_scan(hdev);
5790fcd89c09SVille Tervo 	hci_dev_unlock(hdev);
5791fcd89c09SVille Tervo }
5792fcd89c09SVille Tervo 
hci_le_conn_complete_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)579395118dd4SLuiz Augusto von Dentz static void hci_le_conn_complete_evt(struct hci_dev *hdev, void *data,
579495118dd4SLuiz Augusto von Dentz 				     struct sk_buff *skb)
5795d12fb056SJaganath Kanakkassery {
579695118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_conn_complete *ev = data;
579712cfe417SLuiz Augusto von Dentz 
579895118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
5799d12fb056SJaganath Kanakkassery 
5800d12fb056SJaganath Kanakkassery 	le_conn_complete_evt(hdev, ev->status, &ev->bdaddr, ev->bdaddr_type,
5801cafae4cdSLuiz Augusto von Dentz 			     NULL, ev->role, le16_to_cpu(ev->handle),
5802d12fb056SJaganath Kanakkassery 			     le16_to_cpu(ev->interval),
5803d12fb056SJaganath Kanakkassery 			     le16_to_cpu(ev->latency),
5804d12fb056SJaganath Kanakkassery 			     le16_to_cpu(ev->supervision_timeout));
5805d12fb056SJaganath Kanakkassery }
5806d12fb056SJaganath Kanakkassery 
hci_le_enh_conn_complete_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)580795118dd4SLuiz Augusto von Dentz static void hci_le_enh_conn_complete_evt(struct hci_dev *hdev, void *data,
58084d94f95dSJaganath Kanakkassery 					 struct sk_buff *skb)
58094d94f95dSJaganath Kanakkassery {
581095118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_enh_conn_complete *ev = data;
581112cfe417SLuiz Augusto von Dentz 
581295118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
58134d94f95dSJaganath Kanakkassery 
58144d94f95dSJaganath Kanakkassery 	le_conn_complete_evt(hdev, ev->status, &ev->bdaddr, ev->bdaddr_type,
5815cafae4cdSLuiz Augusto von Dentz 			     &ev->local_rpa, ev->role, le16_to_cpu(ev->handle),
58164d94f95dSJaganath Kanakkassery 			     le16_to_cpu(ev->interval),
58174d94f95dSJaganath Kanakkassery 			     le16_to_cpu(ev->latency),
58184d94f95dSJaganath Kanakkassery 			     le16_to_cpu(ev->supervision_timeout));
58194d94f95dSJaganath Kanakkassery }
58204d94f95dSJaganath Kanakkassery 
hci_le_ext_adv_term_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)582195118dd4SLuiz Augusto von Dentz static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, void *data,
582295118dd4SLuiz Augusto von Dentz 				    struct sk_buff *skb)
5823acf0aeaeSJaganath Kanakkassery {
582495118dd4SLuiz Augusto von Dentz 	struct hci_evt_le_ext_adv_set_term *ev = data;
5825acf0aeaeSJaganath Kanakkassery 	struct hci_conn *conn;
58261f9d5657SArchie Pusaka 	struct adv_info *adv, *n;
5827acf0aeaeSJaganath Kanakkassery 
582895118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
5829acf0aeaeSJaganath Kanakkassery 
58300f281a5eSArchie Pusaka 	/* The Bluetooth Core 5.3 specification clearly states that this event
58310f281a5eSArchie Pusaka 	 * shall not be sent when the Host disables the advertising set. So in
58320f281a5eSArchie Pusaka 	 * case of HCI_ERROR_CANCELLED_BY_HOST, just ignore the event.
58330f281a5eSArchie Pusaka 	 *
58340f281a5eSArchie Pusaka 	 * When the Host disables an advertising set, all cleanup is done via
58350f281a5eSArchie Pusaka 	 * its command callback and not needed to be duplicated here.
58360f281a5eSArchie Pusaka 	 */
58370f281a5eSArchie Pusaka 	if (ev->status == HCI_ERROR_CANCELLED_BY_HOST) {
58380f281a5eSArchie Pusaka 		bt_dev_warn_ratelimited(hdev, "Unexpected advertising set terminated event");
58390f281a5eSArchie Pusaka 		return;
58400f281a5eSArchie Pusaka 	}
58410f281a5eSArchie Pusaka 
5842728abc01SNiels Dossche 	hci_dev_lock(hdev);
5843728abc01SNiels Dossche 
5844728abc01SNiels Dossche 	adv = hci_find_adv_instance(hdev, ev->handle);
5845728abc01SNiels Dossche 
58467087c4f6SLuiz Augusto von Dentz 	if (ev->status) {
584723837a6dSLuiz Augusto von Dentz 		if (!adv)
5848728abc01SNiels Dossche 			goto unlock;
5849acf0aeaeSJaganath Kanakkassery 
585023837a6dSLuiz Augusto von Dentz 		/* Remove advertising as it has been terminated */
585123837a6dSLuiz Augusto von Dentz 		hci_remove_adv_instance(hdev, ev->handle);
585223837a6dSLuiz Augusto von Dentz 		mgmt_advertising_removed(NULL, hdev, ev->handle);
585323837a6dSLuiz Augusto von Dentz 
58541f9d5657SArchie Pusaka 		list_for_each_entry_safe(adv, n, &hdev->adv_instances, list) {
58551f9d5657SArchie Pusaka 			if (adv->enabled)
5856728abc01SNiels Dossche 				goto unlock;
58571f9d5657SArchie Pusaka 		}
58581f9d5657SArchie Pusaka 
58591f9d5657SArchie Pusaka 		/* We are no longer advertising, clear HCI_LE_ADV */
58601f9d5657SArchie Pusaka 		hci_dev_clear_flag(hdev, HCI_LE_ADV);
5861728abc01SNiels Dossche 		goto unlock;
586223837a6dSLuiz Augusto von Dentz 	}
586323837a6dSLuiz Augusto von Dentz 
58647087c4f6SLuiz Augusto von Dentz 	if (adv)
58657087c4f6SLuiz Augusto von Dentz 		adv->enabled = false;
58667087c4f6SLuiz Augusto von Dentz 
5867acf0aeaeSJaganath Kanakkassery 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->conn_handle));
5868acf0aeaeSJaganath Kanakkassery 	if (conn) {
58697087c4f6SLuiz Augusto von Dentz 		/* Store handle in the connection so the correct advertising
58707087c4f6SLuiz Augusto von Dentz 		 * instance can be re-enabled when disconnected.
58717087c4f6SLuiz Augusto von Dentz 		 */
58727087c4f6SLuiz Augusto von Dentz 		conn->adv_instance = ev->handle;
5873acf0aeaeSJaganath Kanakkassery 
5874cafae4cdSLuiz Augusto von Dentz 		if (hdev->adv_addr_type != ADDR_LE_DEV_RANDOM ||
5875cafae4cdSLuiz Augusto von Dentz 		    bacmp(&conn->resp_addr, BDADDR_ANY))
5876728abc01SNiels Dossche 			goto unlock;
5877acf0aeaeSJaganath Kanakkassery 
587825e70886SDaniel Winkler 		if (!ev->handle) {
5879acf0aeaeSJaganath Kanakkassery 			bacpy(&conn->resp_addr, &hdev->random_addr);
5880728abc01SNiels Dossche 			goto unlock;
5881acf0aeaeSJaganath Kanakkassery 		}
5882acf0aeaeSJaganath Kanakkassery 
58837087c4f6SLuiz Augusto von Dentz 		if (adv)
58847087c4f6SLuiz Augusto von Dentz 			bacpy(&conn->resp_addr, &adv->random_addr);
5885acf0aeaeSJaganath Kanakkassery 	}
5886728abc01SNiels Dossche 
5887728abc01SNiels Dossche unlock:
5888728abc01SNiels Dossche 	hci_dev_unlock(hdev);
5889acf0aeaeSJaganath Kanakkassery }
5890acf0aeaeSJaganath Kanakkassery 
hci_le_conn_update_complete_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)589195118dd4SLuiz Augusto von Dentz static void hci_le_conn_update_complete_evt(struct hci_dev *hdev, void *data,
58921855d92dSMarcel Holtmann 					    struct sk_buff *skb)
58931855d92dSMarcel Holtmann {
589495118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_conn_update_complete *ev = data;
58951855d92dSMarcel Holtmann 	struct hci_conn *conn;
58961855d92dSMarcel Holtmann 
589795118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
58981855d92dSMarcel Holtmann 
58991855d92dSMarcel Holtmann 	if (ev->status)
59001855d92dSMarcel Holtmann 		return;
59011855d92dSMarcel Holtmann 
59021855d92dSMarcel Holtmann 	hci_dev_lock(hdev);
59031855d92dSMarcel Holtmann 
59041855d92dSMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
59051855d92dSMarcel Holtmann 	if (conn) {
59061855d92dSMarcel Holtmann 		conn->le_conn_interval = le16_to_cpu(ev->interval);
59071855d92dSMarcel Holtmann 		conn->le_conn_latency = le16_to_cpu(ev->latency);
59081855d92dSMarcel Holtmann 		conn->le_supv_timeout = le16_to_cpu(ev->supervision_timeout);
59091855d92dSMarcel Holtmann 	}
59101855d92dSMarcel Holtmann 
59111855d92dSMarcel Holtmann 	hci_dev_unlock(hdev);
59121855d92dSMarcel Holtmann }
59131855d92dSMarcel Holtmann 
5914a4790dbdSAndre Guedes /* This function requires the caller holds hdev->lock */
check_pending_le_conn(struct hci_dev * hdev,bdaddr_t * addr,u8 addr_type,bool addr_resolved,u8 adv_type)5915fd45ada9SAlfonso Acosta static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev,
5916fd45ada9SAlfonso Acosta 					      bdaddr_t *addr,
5917d850bf08SLuiz Augusto von Dentz 					      u8 addr_type, bool addr_resolved,
59188e8b92eeSLuiz Augusto von Dentz 					      u8 adv_type)
5919a4790dbdSAndre Guedes {
5920a4790dbdSAndre Guedes 	struct hci_conn *conn;
59214b9e7e75SMarcel Holtmann 	struct hci_conn_params *params;
5922a4790dbdSAndre Guedes 
59231c1abcabSJohan Hedberg 	/* If the event is not connectable don't proceed further */
59241c1abcabSJohan Hedberg 	if (adv_type != LE_ADV_IND && adv_type != LE_ADV_DIRECT_IND)
5925fd45ada9SAlfonso Acosta 		return NULL;
59261c1abcabSJohan Hedberg 
5927182ee45dSLuiz Augusto von Dentz 	/* Ignore if the device is blocked or hdev is suspended */
5928182ee45dSLuiz Augusto von Dentz 	if (hci_bdaddr_list_lookup(&hdev->reject_list, addr, addr_type) ||
5929182ee45dSLuiz Augusto von Dentz 	    hdev->suspended)
5930fd45ada9SAlfonso Acosta 		return NULL;
59311c1abcabSJohan Hedberg 
5932f99353cfSJohan Hedberg 	/* Most controller will fail if we try to create new connections
593339bc74caSArchie Pusaka 	 * while we have an existing one in peripheral role.
5934f99353cfSJohan Hedberg 	 */
593539bc74caSArchie Pusaka 	if (hdev->conn_hash.le_num_peripheral > 0 &&
59364364f2e9SAlain Michaud 	    (!test_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks) ||
59374364f2e9SAlain Michaud 	     !(hdev->le_states[3] & 0x10)))
5938fd45ada9SAlfonso Acosta 		return NULL;
5939f99353cfSJohan Hedberg 
59401c1abcabSJohan Hedberg 	/* If we're not connectable only connect devices that we have in
59411c1abcabSJohan Hedberg 	 * our pend_le_conns list.
59421c1abcabSJohan Hedberg 	 */
594349c50922SJohan Hedberg 	params = hci_pend_le_action_lookup(&hdev->pend_le_conns, addr,
594449c50922SJohan Hedberg 					   addr_type);
59454b9e7e75SMarcel Holtmann 	if (!params)
5946fd45ada9SAlfonso Acosta 		return NULL;
5947a4790dbdSAndre Guedes 
594828a667c9SJakub Pawlowski 	if (!params->explicit_connect) {
59494b9e7e75SMarcel Holtmann 		switch (params->auto_connect) {
59504b9e7e75SMarcel Holtmann 		case HCI_AUTO_CONN_DIRECT:
59514b9e7e75SMarcel Holtmann 			/* Only devices advertising with ADV_DIRECT_IND are
59524b9e7e75SMarcel Holtmann 			 * triggering a connection attempt. This is allowing
595367ffb185SArchie Pusaka 			 * incoming connections from peripheral devices.
59544b9e7e75SMarcel Holtmann 			 */
59554b9e7e75SMarcel Holtmann 			if (adv_type != LE_ADV_DIRECT_IND)
5956fd45ada9SAlfonso Acosta 				return NULL;
59574b9e7e75SMarcel Holtmann 			break;
59584b9e7e75SMarcel Holtmann 		case HCI_AUTO_CONN_ALWAYS:
59594b9e7e75SMarcel Holtmann 			/* Devices advertising with ADV_IND or ADV_DIRECT_IND
59604b9e7e75SMarcel Holtmann 			 * are triggering a connection attempt. This means
596167ffb185SArchie Pusaka 			 * that incoming connections from peripheral device are
596267ffb185SArchie Pusaka 			 * accepted and also outgoing connections to peripheral
59634b9e7e75SMarcel Holtmann 			 * devices are established when found.
59644b9e7e75SMarcel Holtmann 			 */
59654b9e7e75SMarcel Holtmann 			break;
59664b9e7e75SMarcel Holtmann 		default:
5967fd45ada9SAlfonso Acosta 			return NULL;
59684b9e7e75SMarcel Holtmann 		}
596928a667c9SJakub Pawlowski 	}
59704b9e7e75SMarcel Holtmann 
5971d850bf08SLuiz Augusto von Dentz 	conn = hci_connect_le(hdev, addr, addr_type, addr_resolved,
5972d850bf08SLuiz Augusto von Dentz 			      BT_SECURITY_LOW, hdev->def_le_autoconnect_timeout,
59738e8b92eeSLuiz Augusto von Dentz 			      HCI_ROLE_MASTER);
5974f161dd41SJohan Hedberg 	if (!IS_ERR(conn)) {
597528a667c9SJakub Pawlowski 		/* If HCI_AUTO_CONN_EXPLICIT is set, conn is already owned
597628a667c9SJakub Pawlowski 		 * by higher layer that tried to connect, if no then
597728a667c9SJakub Pawlowski 		 * store the pointer since we don't really have any
5978f161dd41SJohan Hedberg 		 * other owner of the object besides the params that
5979f161dd41SJohan Hedberg 		 * triggered it. This way we can abort the connection if
5980f161dd41SJohan Hedberg 		 * the parameters get removed and keep the reference
5981f161dd41SJohan Hedberg 		 * count consistent once the connection is established.
5982f161dd41SJohan Hedberg 		 */
598328a667c9SJakub Pawlowski 
598428a667c9SJakub Pawlowski 		if (!params->explicit_connect)
5985f8aaf9b6SJohan Hedberg 			params->conn = hci_conn_get(conn);
598628a667c9SJakub Pawlowski 
5987fd45ada9SAlfonso Acosta 		return conn;
5988f161dd41SJohan Hedberg 	}
5989a4790dbdSAndre Guedes 
5990a4790dbdSAndre Guedes 	switch (PTR_ERR(conn)) {
5991a4790dbdSAndre Guedes 	case -EBUSY:
5992a4790dbdSAndre Guedes 		/* If hci_connect() returns -EBUSY it means there is already
5993a4790dbdSAndre Guedes 		 * an LE connection attempt going on. Since controllers don't
5994a4790dbdSAndre Guedes 		 * support more than one connection attempt at the time, we
5995a4790dbdSAndre Guedes 		 * don't consider this an error case.
5996a4790dbdSAndre Guedes 		 */
5997a4790dbdSAndre Guedes 		break;
5998a4790dbdSAndre Guedes 	default:
5999a4790dbdSAndre Guedes 		BT_DBG("Failed to connect: err %ld", PTR_ERR(conn));
6000fd45ada9SAlfonso Acosta 		return NULL;
6001a4790dbdSAndre Guedes 	}
6002fd45ada9SAlfonso Acosta 
6003fd45ada9SAlfonso Acosta 	return NULL;
6004a4790dbdSAndre Guedes }
6005a4790dbdSAndre Guedes 
process_adv_report(struct hci_dev * hdev,u8 type,bdaddr_t * bdaddr,u8 bdaddr_type,bdaddr_t * direct_addr,u8 direct_addr_type,s8 rssi,u8 * data,u8 len,bool ext_adv,bool ctl_time,u64 instant)60064af605d8SJohan Hedberg static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
60072f010b55SMarcel Holtmann 			       u8 bdaddr_type, bdaddr_t *direct_addr,
6008a2ec905dSAlain Michaud 			       u8 direct_addr_type, s8 rssi, u8 *data, u8 len,
6009b338d917SBrian Gix 			       bool ext_adv, bool ctl_time, u64 instant)
60104af605d8SJohan Hedberg {
6011b9a6328fSJohan Hedberg 	struct discovery_state *d = &hdev->discovery;
60121c1abcabSJohan Hedberg 	struct smp_irk *irk;
6013fd45ada9SAlfonso Acosta 	struct hci_conn *conn;
6014d850bf08SLuiz Augusto von Dentz 	bool match, bdaddr_resolved;
6015c70a7e4cSMarcel Holtmann 	u32 flags;
60161c58e933SSzymon Janc 	u8 *ptr;
60176818375eSSzymon Janc 
601856b40fbfSJohan Hedberg 	switch (type) {
601956b40fbfSJohan Hedberg 	case LE_ADV_IND:
602056b40fbfSJohan Hedberg 	case LE_ADV_DIRECT_IND:
602156b40fbfSJohan Hedberg 	case LE_ADV_SCAN_IND:
602256b40fbfSJohan Hedberg 	case LE_ADV_NONCONN_IND:
602356b40fbfSJohan Hedberg 	case LE_ADV_SCAN_RSP:
602456b40fbfSJohan Hedberg 		break;
602556b40fbfSJohan Hedberg 	default:
60262064ee33SMarcel Holtmann 		bt_dev_err_ratelimited(hdev, "unknown advertising packet "
60272064ee33SMarcel Holtmann 				       "type: 0x%02x", type);
602856b40fbfSJohan Hedberg 		return;
602956b40fbfSJohan Hedberg 	}
603056b40fbfSJohan Hedberg 
6031112b5090SLuiz Augusto von Dentz 	if (len > max_adv_len(hdev)) {
6032112b5090SLuiz Augusto von Dentz 		bt_dev_err_ratelimited(hdev,
6033112b5090SLuiz Augusto von Dentz 				       "adv larger than maximum supported");
6034a2ec905dSAlain Michaud 		return;
6035a2ec905dSAlain Michaud 	}
6036a2ec905dSAlain Michaud 
60376818375eSSzymon Janc 	/* Find the end of the data in case the report contains padded zero
60386818375eSSzymon Janc 	 * bytes at the end causing an invalid length value.
60396818375eSSzymon Janc 	 *
60406818375eSSzymon Janc 	 * When data is NULL, len is 0 so there is no need for extra ptr
60416818375eSSzymon Janc 	 * check as 'ptr < data + 0' is already false in such case.
60426818375eSSzymon Janc 	 */
60436818375eSSzymon Janc 	for (ptr = data; ptr < data + len && *ptr; ptr += *ptr + 1) {
60446818375eSSzymon Janc 		if (ptr + 1 + *ptr > data + len)
60456818375eSSzymon Janc 			break;
60466818375eSSzymon Janc 	}
60476818375eSSzymon Janc 
60481c58e933SSzymon Janc 	/* Adjust for actual length. This handles the case when remote
60491c58e933SSzymon Janc 	 * device is advertising with incorrect data length.
60501c58e933SSzymon Janc 	 */
60511c58e933SSzymon Janc 	len = ptr - data;
6052b9a6328fSJohan Hedberg 
60532f010b55SMarcel Holtmann 	/* If the direct address is present, then this report is from
60542f010b55SMarcel Holtmann 	 * a LE Direct Advertising Report event. In that case it is
60552f010b55SMarcel Holtmann 	 * important to see if the address is matching the local
60562f010b55SMarcel Holtmann 	 * controller address.
60572f010b55SMarcel Holtmann 	 */
6058b338d917SBrian Gix 	if (!hci_dev_test_flag(hdev, HCI_MESH) && direct_addr) {
6059d850bf08SLuiz Augusto von Dentz 		direct_addr_type = ev_bdaddr_type(hdev, direct_addr_type,
6060d850bf08SLuiz Augusto von Dentz 						  &bdaddr_resolved);
60614ec4d63bSLuiz Augusto von Dentz 
60622f010b55SMarcel Holtmann 		/* Only resolvable random addresses are valid for these
60632f010b55SMarcel Holtmann 		 * kind of reports and others can be ignored.
60642f010b55SMarcel Holtmann 		 */
60652f010b55SMarcel Holtmann 		if (!hci_bdaddr_is_rpa(direct_addr, direct_addr_type))
60662f010b55SMarcel Holtmann 			return;
60672f010b55SMarcel Holtmann 
60682f010b55SMarcel Holtmann 		/* If the controller is not using resolvable random
60692f010b55SMarcel Holtmann 		 * addresses, then this report can be ignored.
60702f010b55SMarcel Holtmann 		 */
6071d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_PRIVACY))
60722f010b55SMarcel Holtmann 			return;
60732f010b55SMarcel Holtmann 
60742f010b55SMarcel Holtmann 		/* If the local IRK of the controller does not match
60752f010b55SMarcel Holtmann 		 * with the resolvable random address provided, then
60762f010b55SMarcel Holtmann 		 * this report can be ignored.
60772f010b55SMarcel Holtmann 		 */
60782f010b55SMarcel Holtmann 		if (!smp_irk_matches(hdev, hdev->irk, direct_addr))
60792f010b55SMarcel Holtmann 			return;
60802f010b55SMarcel Holtmann 	}
60812f010b55SMarcel Holtmann 
6082435a13d8SJohan Hedberg 	/* Check if we need to convert to identity address */
6083435a13d8SJohan Hedberg 	irk = hci_get_irk(hdev, bdaddr, bdaddr_type);
6084435a13d8SJohan Hedberg 	if (irk) {
6085435a13d8SJohan Hedberg 		bdaddr = &irk->bdaddr;
6086435a13d8SJohan Hedberg 		bdaddr_type = irk->addr_type;
6087435a13d8SJohan Hedberg 	}
6088435a13d8SJohan Hedberg 
6089d850bf08SLuiz Augusto von Dentz 	bdaddr_type = ev_bdaddr_type(hdev, bdaddr_type, &bdaddr_resolved);
60904ec4d63bSLuiz Augusto von Dentz 
6091082f2300SSzymon Janc 	/* Check if we have been requested to connect to this device.
6092082f2300SSzymon Janc 	 *
6093082f2300SSzymon Janc 	 * direct_addr is set only for directed advertising reports (it is NULL
6094082f2300SSzymon Janc 	 * for advertising reports) and is already verified to be RPA above.
6095082f2300SSzymon Janc 	 */
6096d850bf08SLuiz Augusto von Dentz 	conn = check_pending_le_conn(hdev, bdaddr, bdaddr_type, bdaddr_resolved,
60978e8b92eeSLuiz Augusto von Dentz 				     type);
6098112b5090SLuiz Augusto von Dentz 	if (!ext_adv && conn && type == LE_ADV_IND &&
6099112b5090SLuiz Augusto von Dentz 	    len <= max_adv_len(hdev)) {
6100fd45ada9SAlfonso Acosta 		/* Store report for later inclusion by
6101fd45ada9SAlfonso Acosta 		 * mgmt_device_connected
6102fd45ada9SAlfonso Acosta 		 */
6103fd45ada9SAlfonso Acosta 		memcpy(conn->le_adv_data, data, len);
6104fd45ada9SAlfonso Acosta 		conn->le_adv_data_len = len;
6105fd45ada9SAlfonso Acosta 	}
610699a6768eSJohan Hedberg 
6107b338d917SBrian Gix 	if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND)
6108b338d917SBrian Gix 		flags = MGMT_DEV_FOUND_NOT_CONNECTABLE;
6109b338d917SBrian Gix 	else
6110b338d917SBrian Gix 		flags = 0;
6111b338d917SBrian Gix 
6112b338d917SBrian Gix 	/* All scan results should be sent up for Mesh systems */
6113b338d917SBrian Gix 	if (hci_dev_test_flag(hdev, HCI_MESH)) {
6114b338d917SBrian Gix 		mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
6115b338d917SBrian Gix 				  rssi, flags, data, len, NULL, 0, instant);
6116b338d917SBrian Gix 		return;
6117b338d917SBrian Gix 	}
6118b338d917SBrian Gix 
61191c1abcabSJohan Hedberg 	/* Passive scanning shouldn't trigger any device found events,
61201c1abcabSJohan Hedberg 	 * except for devices marked as CONN_REPORT for which we do send
61218208f5a9SMiao-chen Chou 	 * device found events, or advertisement monitoring requested.
61221c1abcabSJohan Hedberg 	 */
61231c1abcabSJohan Hedberg 	if (hdev->le_scan_type == LE_SCAN_PASSIVE) {
61240d2bf134SJohan Hedberg 		if (type == LE_ADV_DIRECT_IND)
61250d2bf134SJohan Hedberg 			return;
61260d2bf134SJohan Hedberg 
61273a19b6feSJohan Hedberg 		if (!hci_pend_le_action_lookup(&hdev->pend_le_reports,
61288208f5a9SMiao-chen Chou 					       bdaddr, bdaddr_type) &&
61298208f5a9SMiao-chen Chou 		    idr_is_empty(&hdev->adv_monitors_idr))
61300d2bf134SJohan Hedberg 			return;
61310d2bf134SJohan Hedberg 
61320d2bf134SJohan Hedberg 		mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
6133b338d917SBrian Gix 				  rssi, flags, data, len, NULL, 0, 0);
613497bf2e99SJohan Hedberg 		return;
6135ca5c4be7SJohan Hedberg 	}
61364af605d8SJohan Hedberg 
613773f55453SLuiz Augusto von Dentz 	/* When receiving a scan response, then there is no way to
6138c70a7e4cSMarcel Holtmann 	 * know if the remote device is connectable or not. However
6139c70a7e4cSMarcel Holtmann 	 * since scan responses are merged with a previously seen
6140c70a7e4cSMarcel Holtmann 	 * advertising report, the flags field from that report
6141c70a7e4cSMarcel Holtmann 	 * will be used.
6142c70a7e4cSMarcel Holtmann 	 *
614373f55453SLuiz Augusto von Dentz 	 * In the unlikely case that a controller just sends a scan
614473f55453SLuiz Augusto von Dentz 	 * response event that doesn't match the pending report, then
614573f55453SLuiz Augusto von Dentz 	 * it is marked as a standalone SCAN_RSP.
6146c70a7e4cSMarcel Holtmann 	 */
6147b338d917SBrian Gix 	if (type == LE_ADV_SCAN_RSP)
614873f55453SLuiz Augusto von Dentz 		flags = MGMT_DEV_FOUND_SCAN_RSP;
6149c70a7e4cSMarcel Holtmann 
6150b9a6328fSJohan Hedberg 	/* If there's nothing pending either store the data from this
6151b9a6328fSJohan Hedberg 	 * event or send an immediate device found event if the data
6152b9a6328fSJohan Hedberg 	 * should not be stored for later.
6153b9a6328fSJohan Hedberg 	 */
6154a2ec905dSAlain Michaud 	if (!ext_adv &&	!has_pending_adv_report(hdev)) {
6155b9a6328fSJohan Hedberg 		/* If the report will trigger a SCAN_REQ store it for
6156b9a6328fSJohan Hedberg 		 * later merging.
6157b9a6328fSJohan Hedberg 		 */
6158b9a6328fSJohan Hedberg 		if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) {
6159b9a6328fSJohan Hedberg 			store_pending_adv_report(hdev, bdaddr, bdaddr_type,
6160c70a7e4cSMarcel Holtmann 						 rssi, flags, data, len);
6161b9a6328fSJohan Hedberg 			return;
6162b9a6328fSJohan Hedberg 		}
6163b9a6328fSJohan Hedberg 
6164b9a6328fSJohan Hedberg 		mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
6165b338d917SBrian Gix 				  rssi, flags, data, len, NULL, 0, 0);
6166b9a6328fSJohan Hedberg 		return;
6167b9a6328fSJohan Hedberg 	}
6168b9a6328fSJohan Hedberg 
6169474ee066SJohan Hedberg 	/* Check if the pending report is for the same device as the new one */
6170474ee066SJohan Hedberg 	match = (!bacmp(bdaddr, &d->last_adv_addr) &&
6171474ee066SJohan Hedberg 		 bdaddr_type == d->last_adv_addr_type);
6172474ee066SJohan Hedberg 
6173b9a6328fSJohan Hedberg 	/* If the pending data doesn't match this report or this isn't a
6174b9a6328fSJohan Hedberg 	 * scan response (e.g. we got a duplicate ADV_IND) then force
6175b9a6328fSJohan Hedberg 	 * sending of the pending data.
6176b9a6328fSJohan Hedberg 	 */
6177474ee066SJohan Hedberg 	if (type != LE_ADV_SCAN_RSP || !match) {
6178474ee066SJohan Hedberg 		/* Send out whatever is in the cache, but skip duplicates */
6179474ee066SJohan Hedberg 		if (!match)
6180b9a6328fSJohan Hedberg 			mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
6181ff5cd29fSJohan Hedberg 					  d->last_adv_addr_type, NULL,
6182c70a7e4cSMarcel Holtmann 					  d->last_adv_rssi, d->last_adv_flags,
6183ff5cd29fSJohan Hedberg 					  d->last_adv_data,
6184b338d917SBrian Gix 					  d->last_adv_data_len, NULL, 0, 0);
6185b9a6328fSJohan Hedberg 
6186b9a6328fSJohan Hedberg 		/* If the new report will trigger a SCAN_REQ store it for
6187b9a6328fSJohan Hedberg 		 * later merging.
6188b9a6328fSJohan Hedberg 		 */
6189a2ec905dSAlain Michaud 		if (!ext_adv && (type == LE_ADV_IND ||
6190a2ec905dSAlain Michaud 				 type == LE_ADV_SCAN_IND)) {
6191b9a6328fSJohan Hedberg 			store_pending_adv_report(hdev, bdaddr, bdaddr_type,
6192c70a7e4cSMarcel Holtmann 						 rssi, flags, data, len);
6193b9a6328fSJohan Hedberg 			return;
6194b9a6328fSJohan Hedberg 		}
6195b9a6328fSJohan Hedberg 
6196b9a6328fSJohan Hedberg 		/* The advertising reports cannot be merged, so clear
6197b9a6328fSJohan Hedberg 		 * the pending report and send out a device found event.
6198b9a6328fSJohan Hedberg 		 */
6199b9a6328fSJohan Hedberg 		clear_pending_adv_report(hdev);
62005c5b93e4SJohan Hedberg 		mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
6201b338d917SBrian Gix 				  rssi, flags, data, len, NULL, 0, 0);
6202b9a6328fSJohan Hedberg 		return;
6203b9a6328fSJohan Hedberg 	}
6204b9a6328fSJohan Hedberg 
6205b9a6328fSJohan Hedberg 	/* If we get here we've got a pending ADV_IND or ADV_SCAN_IND and
6206b9a6328fSJohan Hedberg 	 * the new event is a SCAN_RSP. We can therefore proceed with
6207b9a6328fSJohan Hedberg 	 * sending a merged device found event.
6208b9a6328fSJohan Hedberg 	 */
6209b9a6328fSJohan Hedberg 	mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
6210c70a7e4cSMarcel Holtmann 			  d->last_adv_addr_type, NULL, rssi, d->last_adv_flags,
6211b338d917SBrian Gix 			  d->last_adv_data, d->last_adv_data_len, data, len, 0);
6212b9a6328fSJohan Hedberg 	clear_pending_adv_report(hdev);
62134af605d8SJohan Hedberg }
62144af605d8SJohan Hedberg 
hci_le_adv_report_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)621595118dd4SLuiz Augusto von Dentz static void hci_le_adv_report_evt(struct hci_dev *hdev, void *data,
621695118dd4SLuiz Augusto von Dentz 				  struct sk_buff *skb)
62179aa04c91SAndre Guedes {
621895118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_advertising_report *ev = data;
6219b338d917SBrian Gix 	u64 instant = jiffies;
622047afe93cSLuiz Augusto von Dentz 
622147afe93cSLuiz Augusto von Dentz 	if (!ev->num)
622247afe93cSLuiz Augusto von Dentz 		return;
62239aa04c91SAndre Guedes 
6224a4790dbdSAndre Guedes 	hci_dev_lock(hdev);
6225a4790dbdSAndre Guedes 
622647afe93cSLuiz Augusto von Dentz 	while (ev->num--) {
622747afe93cSLuiz Augusto von Dentz 		struct hci_ev_le_advertising_info *info;
62284af605d8SJohan Hedberg 		s8 rssi;
6229a4790dbdSAndre Guedes 
623047afe93cSLuiz Augusto von Dentz 		info = hci_le_ev_skb_pull(hdev, skb,
623147afe93cSLuiz Augusto von Dentz 					  HCI_EV_LE_ADVERTISING_REPORT,
623247afe93cSLuiz Augusto von Dentz 					  sizeof(*info));
623347afe93cSLuiz Augusto von Dentz 		if (!info)
6234899663beSBrian Gix 			break;
6235899663beSBrian Gix 
623647afe93cSLuiz Augusto von Dentz 		if (!hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_ADVERTISING_REPORT,
623747afe93cSLuiz Augusto von Dentz 					info->length + 1))
623847afe93cSLuiz Augusto von Dentz 			break;
623947afe93cSLuiz Augusto von Dentz 
6240112b5090SLuiz Augusto von Dentz 		if (info->length <= max_adv_len(hdev)) {
624147afe93cSLuiz Augusto von Dentz 			rssi = info->data[info->length];
624247afe93cSLuiz Augusto von Dentz 			process_adv_report(hdev, info->type, &info->bdaddr,
624347afe93cSLuiz Augusto von Dentz 					   info->bdaddr_type, NULL, 0, rssi,
6244b338d917SBrian Gix 					   info->data, info->length, false,
6245b338d917SBrian Gix 					   false, instant);
6246ee649346SChriz Chow 		} else {
6247ee649346SChriz Chow 			bt_dev_err(hdev, "Dropping invalid advertising data");
6248ee649346SChriz Chow 		}
62499aa04c91SAndre Guedes 	}
6250a4790dbdSAndre Guedes 
6251a4790dbdSAndre Guedes 	hci_dev_unlock(hdev);
62529aa04c91SAndre Guedes }
62539aa04c91SAndre Guedes 
ext_evt_type_to_legacy(struct hci_dev * hdev,u16 evt_type)6254657cc646SMarcel Holtmann static u8 ext_evt_type_to_legacy(struct hci_dev *hdev, u16 evt_type)
6255c215e939SJaganath Kanakkassery {
6256b2cc9761SJaganath Kanakkassery 	if (evt_type & LE_EXT_ADV_LEGACY_PDU) {
6257c215e939SJaganath Kanakkassery 		switch (evt_type) {
6258c215e939SJaganath Kanakkassery 		case LE_LEGACY_ADV_IND:
6259c215e939SJaganath Kanakkassery 			return LE_ADV_IND;
6260c215e939SJaganath Kanakkassery 		case LE_LEGACY_ADV_DIRECT_IND:
6261c215e939SJaganath Kanakkassery 			return LE_ADV_DIRECT_IND;
6262c215e939SJaganath Kanakkassery 		case LE_LEGACY_ADV_SCAN_IND:
6263c215e939SJaganath Kanakkassery 			return LE_ADV_SCAN_IND;
6264c215e939SJaganath Kanakkassery 		case LE_LEGACY_NONCONN_IND:
6265c215e939SJaganath Kanakkassery 			return LE_ADV_NONCONN_IND;
6266c215e939SJaganath Kanakkassery 		case LE_LEGACY_SCAN_RSP_ADV:
6267c215e939SJaganath Kanakkassery 		case LE_LEGACY_SCAN_RSP_ADV_SCAN:
6268c215e939SJaganath Kanakkassery 			return LE_ADV_SCAN_RSP;
6269c215e939SJaganath Kanakkassery 		}
6270c215e939SJaganath Kanakkassery 
6271657cc646SMarcel Holtmann 		goto invalid;
6272c215e939SJaganath Kanakkassery 	}
6273c215e939SJaganath Kanakkassery 
6274b2cc9761SJaganath Kanakkassery 	if (evt_type & LE_EXT_ADV_CONN_IND) {
6275b2cc9761SJaganath Kanakkassery 		if (evt_type & LE_EXT_ADV_DIRECT_IND)
6276b2cc9761SJaganath Kanakkassery 			return LE_ADV_DIRECT_IND;
6277b2cc9761SJaganath Kanakkassery 
6278b2cc9761SJaganath Kanakkassery 		return LE_ADV_IND;
6279b2cc9761SJaganath Kanakkassery 	}
6280b2cc9761SJaganath Kanakkassery 
6281b2cc9761SJaganath Kanakkassery 	if (evt_type & LE_EXT_ADV_SCAN_RSP)
6282b2cc9761SJaganath Kanakkassery 		return LE_ADV_SCAN_RSP;
6283b2cc9761SJaganath Kanakkassery 
6284b2cc9761SJaganath Kanakkassery 	if (evt_type & LE_EXT_ADV_SCAN_IND)
6285b2cc9761SJaganath Kanakkassery 		return LE_ADV_SCAN_IND;
6286b2cc9761SJaganath Kanakkassery 
6287b2cc9761SJaganath Kanakkassery 	if (evt_type == LE_EXT_ADV_NON_CONN_IND ||
6288b2cc9761SJaganath Kanakkassery 	    evt_type & LE_EXT_ADV_DIRECT_IND)
6289b2cc9761SJaganath Kanakkassery 		return LE_ADV_NONCONN_IND;
6290b2cc9761SJaganath Kanakkassery 
6291657cc646SMarcel Holtmann invalid:
6292657cc646SMarcel Holtmann 	bt_dev_err_ratelimited(hdev, "Unknown advertising packet type: 0x%02x",
6293b2cc9761SJaganath Kanakkassery 			       evt_type);
6294b2cc9761SJaganath Kanakkassery 
6295b2cc9761SJaganath Kanakkassery 	return LE_ADV_INVALID;
6296b2cc9761SJaganath Kanakkassery }
6297b2cc9761SJaganath Kanakkassery 
hci_le_ext_adv_report_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)629895118dd4SLuiz Augusto von Dentz static void hci_le_ext_adv_report_evt(struct hci_dev *hdev, void *data,
629995118dd4SLuiz Augusto von Dentz 				      struct sk_buff *skb)
6300c215e939SJaganath Kanakkassery {
630195118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_ext_adv_report *ev = data;
6302b338d917SBrian Gix 	u64 instant = jiffies;
6303b48b833fSLuiz Augusto von Dentz 
6304b48b833fSLuiz Augusto von Dentz 	if (!ev->num)
6305b48b833fSLuiz Augusto von Dentz 		return;
6306c215e939SJaganath Kanakkassery 
6307c215e939SJaganath Kanakkassery 	hci_dev_lock(hdev);
6308c215e939SJaganath Kanakkassery 
6309b48b833fSLuiz Augusto von Dentz 	while (ev->num--) {
6310b48b833fSLuiz Augusto von Dentz 		struct hci_ev_le_ext_adv_info *info;
6311c215e939SJaganath Kanakkassery 		u8 legacy_evt_type;
6312c215e939SJaganath Kanakkassery 		u16 evt_type;
6313c215e939SJaganath Kanakkassery 
6314b48b833fSLuiz Augusto von Dentz 		info = hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_EXT_ADV_REPORT,
6315b48b833fSLuiz Augusto von Dentz 					  sizeof(*info));
6316b48b833fSLuiz Augusto von Dentz 		if (!info)
6317b48b833fSLuiz Augusto von Dentz 			break;
6318b48b833fSLuiz Augusto von Dentz 
6319b48b833fSLuiz Augusto von Dentz 		if (!hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_EXT_ADV_REPORT,
6320b48b833fSLuiz Augusto von Dentz 					info->length))
6321b48b833fSLuiz Augusto von Dentz 			break;
6322b48b833fSLuiz Augusto von Dentz 
6323ad38e55eSSven Peter 		evt_type = __le16_to_cpu(info->type) & LE_EXT_ADV_EVT_TYPE_MASK;
6324657cc646SMarcel Holtmann 		legacy_evt_type = ext_evt_type_to_legacy(hdev, evt_type);
6325c215e939SJaganath Kanakkassery 		if (legacy_evt_type != LE_ADV_INVALID) {
6326b48b833fSLuiz Augusto von Dentz 			process_adv_report(hdev, legacy_evt_type, &info->bdaddr,
6327b48b833fSLuiz Augusto von Dentz 					   info->bdaddr_type, NULL, 0,
6328b48b833fSLuiz Augusto von Dentz 					   info->rssi, info->data, info->length,
6329b338d917SBrian Gix 					   !(evt_type & LE_EXT_ADV_LEGACY_PDU),
6330b338d917SBrian Gix 					   false, instant);
6331c215e939SJaganath Kanakkassery 		}
6332c215e939SJaganath Kanakkassery 	}
6333c215e939SJaganath Kanakkassery 
6334c215e939SJaganath Kanakkassery 	hci_dev_unlock(hdev);
6335c215e939SJaganath Kanakkassery }
6336c215e939SJaganath Kanakkassery 
hci_le_pa_term_sync(struct hci_dev * hdev,__le16 handle)6337eca0ae4aSLuiz Augusto von Dentz static int hci_le_pa_term_sync(struct hci_dev *hdev, __le16 handle)
6338eca0ae4aSLuiz Augusto von Dentz {
6339eca0ae4aSLuiz Augusto von Dentz 	struct hci_cp_le_pa_term_sync cp;
6340eca0ae4aSLuiz Augusto von Dentz 
6341eca0ae4aSLuiz Augusto von Dentz 	memset(&cp, 0, sizeof(cp));
6342eca0ae4aSLuiz Augusto von Dentz 	cp.handle = handle;
6343eca0ae4aSLuiz Augusto von Dentz 
6344eca0ae4aSLuiz Augusto von Dentz 	return hci_send_cmd(hdev, HCI_OP_LE_PA_TERM_SYNC, sizeof(cp), &cp);
6345eca0ae4aSLuiz Augusto von Dentz }
6346eca0ae4aSLuiz Augusto von Dentz 
hci_le_pa_sync_estabilished_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)6347eca0ae4aSLuiz Augusto von Dentz static void hci_le_pa_sync_estabilished_evt(struct hci_dev *hdev, void *data,
6348eca0ae4aSLuiz Augusto von Dentz 					    struct sk_buff *skb)
6349eca0ae4aSLuiz Augusto von Dentz {
6350eca0ae4aSLuiz Augusto von Dentz 	struct hci_ev_le_pa_sync_established *ev = data;
6351eca0ae4aSLuiz Augusto von Dentz 	int mask = hdev->link_mode;
6352eca0ae4aSLuiz Augusto von Dentz 	__u8 flags = 0;
635323417475SIulia Tanasescu 	struct hci_conn *pa_sync;
6354eca0ae4aSLuiz Augusto von Dentz 
6355eca0ae4aSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
6356eca0ae4aSLuiz Augusto von Dentz 
6357eca0ae4aSLuiz Augusto von Dentz 	hci_dev_lock(hdev);
6358eca0ae4aSLuiz Augusto von Dentz 
6359eca0ae4aSLuiz Augusto von Dentz 	hci_dev_clear_flag(hdev, HCI_PA_SYNC);
6360eca0ae4aSLuiz Augusto von Dentz 
6361eca0ae4aSLuiz Augusto von Dentz 	mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ISO_LINK, &flags);
6362fbdc4bc4SIulia Tanasescu 	if (!(mask & HCI_LM_ACCEPT)) {
6363eca0ae4aSLuiz Augusto von Dentz 		hci_le_pa_term_sync(hdev, ev->handle);
6364fbdc4bc4SIulia Tanasescu 		goto unlock;
6365fbdc4bc4SIulia Tanasescu 	}
6366eca0ae4aSLuiz Augusto von Dentz 
6367fbdc4bc4SIulia Tanasescu 	if (!(flags & HCI_PROTO_DEFER))
6368fbdc4bc4SIulia Tanasescu 		goto unlock;
6369fbdc4bc4SIulia Tanasescu 
637023417475SIulia Tanasescu 	if (ev->status) {
637123417475SIulia Tanasescu 		/* Add connection to indicate the failed PA sync event */
637284cb0143SZiyang Xuan 		pa_sync = hci_conn_add_unset(hdev, ISO_LINK, BDADDR_ANY,
6373fbdc4bc4SIulia Tanasescu 					     HCI_ROLE_SLAVE);
6374fbdc4bc4SIulia Tanasescu 
637523417475SIulia Tanasescu 		if (!pa_sync)
6376fbdc4bc4SIulia Tanasescu 			goto unlock;
6377fbdc4bc4SIulia Tanasescu 
637823417475SIulia Tanasescu 		set_bit(HCI_CONN_PA_SYNC_FAILED, &pa_sync->flags);
6379fbdc4bc4SIulia Tanasescu 
638023417475SIulia Tanasescu 		/* Notify iso layer */
638123417475SIulia Tanasescu 		hci_connect_cfm(pa_sync, ev->status);
638223417475SIulia Tanasescu 	}
6383fbdc4bc4SIulia Tanasescu 
6384fbdc4bc4SIulia Tanasescu unlock:
6385eca0ae4aSLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
6386eca0ae4aSLuiz Augusto von Dentz }
6387eca0ae4aSLuiz Augusto von Dentz 
hci_le_per_adv_report_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)63889c082631SClaudia Draghicescu static void hci_le_per_adv_report_evt(struct hci_dev *hdev, void *data,
63899c082631SClaudia Draghicescu 				      struct sk_buff *skb)
63909c082631SClaudia Draghicescu {
63919c082631SClaudia Draghicescu 	struct hci_ev_le_per_adv_report *ev = data;
63929c082631SClaudia Draghicescu 	int mask = hdev->link_mode;
63939c082631SClaudia Draghicescu 	__u8 flags = 0;
63949c082631SClaudia Draghicescu 
63959c082631SClaudia Draghicescu 	bt_dev_dbg(hdev, "sync_handle 0x%4.4x", le16_to_cpu(ev->sync_handle));
63969c082631SClaudia Draghicescu 
63979c082631SClaudia Draghicescu 	hci_dev_lock(hdev);
63989c082631SClaudia Draghicescu 
63999c082631SClaudia Draghicescu 	mask |= hci_proto_connect_ind(hdev, BDADDR_ANY, ISO_LINK, &flags);
64009c082631SClaudia Draghicescu 	if (!(mask & HCI_LM_ACCEPT))
64019c082631SClaudia Draghicescu 		hci_le_pa_term_sync(hdev, ev->sync_handle);
64029c082631SClaudia Draghicescu 
64039c082631SClaudia Draghicescu 	hci_dev_unlock(hdev);
64049c082631SClaudia Draghicescu }
64059c082631SClaudia Draghicescu 
hci_le_remote_feat_complete_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)640695118dd4SLuiz Augusto von Dentz static void hci_le_remote_feat_complete_evt(struct hci_dev *hdev, void *data,
64070fe29fd1SMarcel Holtmann 					    struct sk_buff *skb)
64080fe29fd1SMarcel Holtmann {
640995118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_remote_feat_complete *ev = data;
64100fe29fd1SMarcel Holtmann 	struct hci_conn *conn;
64110fe29fd1SMarcel Holtmann 
641295118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
64130fe29fd1SMarcel Holtmann 
64140fe29fd1SMarcel Holtmann 	hci_dev_lock(hdev);
64150fe29fd1SMarcel Holtmann 
64160fe29fd1SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
64170fe29fd1SMarcel Holtmann 	if (conn) {
64180fe29fd1SMarcel Holtmann 		if (!ev->status)
64190fe29fd1SMarcel Holtmann 			memcpy(conn->features[0], ev->features, 8);
64200fe29fd1SMarcel Holtmann 
64210fe29fd1SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
64220fe29fd1SMarcel Holtmann 			__u8 status;
64230fe29fd1SMarcel Holtmann 
6424ef365da1SArchie Pusaka 			/* If the local controller supports peripheral-initiated
64250fe29fd1SMarcel Holtmann 			 * features exchange, but the remote controller does
64260fe29fd1SMarcel Holtmann 			 * not, then it is possible that the error code 0x1a
64270fe29fd1SMarcel Holtmann 			 * for unsupported remote feature gets returned.
64280fe29fd1SMarcel Holtmann 			 *
64290fe29fd1SMarcel Holtmann 			 * In this specific case, allow the connection to
64300fe29fd1SMarcel Holtmann 			 * transition into connected state and mark it as
64310fe29fd1SMarcel Holtmann 			 * successful.
64320fe29fd1SMarcel Holtmann 			 */
6433ef365da1SArchie Pusaka 			if (!conn->out && ev->status == 0x1a &&
6434ef365da1SArchie Pusaka 			    (hdev->le_features[0] & HCI_LE_PERIPHERAL_FEATURES))
64350fe29fd1SMarcel Holtmann 				status = 0x00;
64360fe29fd1SMarcel Holtmann 			else
64370fe29fd1SMarcel Holtmann 				status = ev->status;
64380fe29fd1SMarcel Holtmann 
64390fe29fd1SMarcel Holtmann 			conn->state = BT_CONNECTED;
64400fe29fd1SMarcel Holtmann 			hci_connect_cfm(conn, status);
64410fe29fd1SMarcel Holtmann 			hci_conn_drop(conn);
64420fe29fd1SMarcel Holtmann 		}
64430fe29fd1SMarcel Holtmann 	}
64440fe29fd1SMarcel Holtmann 
64450fe29fd1SMarcel Holtmann 	hci_dev_unlock(hdev);
64460fe29fd1SMarcel Holtmann }
64470fe29fd1SMarcel Holtmann 
hci_le_ltk_request_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)644895118dd4SLuiz Augusto von Dentz static void hci_le_ltk_request_evt(struct hci_dev *hdev, void *data,
644995118dd4SLuiz Augusto von Dentz 				   struct sk_buff *skb)
6450a7a595f6SVinicius Costa Gomes {
645195118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_ltk_req *ev = data;
6452a7a595f6SVinicius Costa Gomes 	struct hci_cp_le_ltk_reply cp;
6453bea710feSVinicius Costa Gomes 	struct hci_cp_le_ltk_neg_reply neg;
6454a7a595f6SVinicius Costa Gomes 	struct hci_conn *conn;
6455c9839a11SVinicius Costa Gomes 	struct smp_ltk *ltk;
6456a7a595f6SVinicius Costa Gomes 
645795118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "handle 0x%4.4x", __le16_to_cpu(ev->handle));
6458a7a595f6SVinicius Costa Gomes 
6459a7a595f6SVinicius Costa Gomes 	hci_dev_lock(hdev);
6460a7a595f6SVinicius Costa Gomes 
6461a7a595f6SVinicius Costa Gomes 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
6462bea710feSVinicius Costa Gomes 	if (conn == NULL)
6463bea710feSVinicius Costa Gomes 		goto not_found;
6464a7a595f6SVinicius Costa Gomes 
6465f3a73d97SJohan Hedberg 	ltk = hci_find_ltk(hdev, &conn->dst, conn->dst_type, conn->role);
64665378bc56SJohan Hedberg 	if (!ltk)
6467bea710feSVinicius Costa Gomes 		goto not_found;
6468bea710feSVinicius Costa Gomes 
64695378bc56SJohan Hedberg 	if (smp_ltk_is_sc(ltk)) {
64705378bc56SJohan Hedberg 		/* With SC both EDiv and Rand are set to zero */
64715378bc56SJohan Hedberg 		if (ev->ediv || ev->rand)
64725378bc56SJohan Hedberg 			goto not_found;
64735378bc56SJohan Hedberg 	} else {
64745378bc56SJohan Hedberg 		/* For non-SC keys check that EDiv and Rand match */
64755378bc56SJohan Hedberg 		if (ev->ediv != ltk->ediv || ev->rand != ltk->rand)
64765378bc56SJohan Hedberg 			goto not_found;
64775378bc56SJohan Hedberg 	}
64785378bc56SJohan Hedberg 
64798b76ce34SJohan Hedberg 	memcpy(cp.ltk, ltk->val, ltk->enc_size);
64808b76ce34SJohan Hedberg 	memset(cp.ltk + ltk->enc_size, 0, sizeof(cp.ltk) - ltk->enc_size);
6481a7a595f6SVinicius Costa Gomes 	cp.handle = cpu_to_le16(conn->handle);
6482c9839a11SVinicius Costa Gomes 
6483a6f7833cSJohan Hedberg 	conn->pending_sec_level = smp_ltk_sec_level(ltk);
6484a7a595f6SVinicius Costa Gomes 
648589cbb4daSAndre Guedes 	conn->enc_key_size = ltk->enc_size;
6486a7a595f6SVinicius Costa Gomes 
6487a7a595f6SVinicius Costa Gomes 	hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
6488a7a595f6SVinicius Costa Gomes 
64895981a882SClaudio Takahasi 	/* Ref. Bluetooth Core SPEC pages 1975 and 2004. STK is a
64905981a882SClaudio Takahasi 	 * temporary key used to encrypt a connection following
64915981a882SClaudio Takahasi 	 * pairing. It is used during the Encrypted Session Setup to
64925981a882SClaudio Takahasi 	 * distribute the keys. Later, security can be re-established
64935981a882SClaudio Takahasi 	 * using a distributed LTK.
64945981a882SClaudio Takahasi 	 */
64952ceba539SJohan Hedberg 	if (ltk->type == SMP_STK) {
6496fe59a05fSJohan Hedberg 		set_bit(HCI_CONN_STK_ENCRYPT, &conn->flags);
6497970d0f1bSJohan Hedberg 		list_del_rcu(&ltk->list);
6498970d0f1bSJohan Hedberg 		kfree_rcu(ltk, rcu);
6499fe59a05fSJohan Hedberg 	} else {
6500fe59a05fSJohan Hedberg 		clear_bit(HCI_CONN_STK_ENCRYPT, &conn->flags);
6501c9839a11SVinicius Costa Gomes 	}
6502c9839a11SVinicius Costa Gomes 
6503a7a595f6SVinicius Costa Gomes 	hci_dev_unlock(hdev);
6504bea710feSVinicius Costa Gomes 
6505bea710feSVinicius Costa Gomes 	return;
6506bea710feSVinicius Costa Gomes 
6507bea710feSVinicius Costa Gomes not_found:
6508bea710feSVinicius Costa Gomes 	neg.handle = ev->handle;
6509bea710feSVinicius Costa Gomes 	hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
6510bea710feSVinicius Costa Gomes 	hci_dev_unlock(hdev);
6511a7a595f6SVinicius Costa Gomes }
6512a7a595f6SVinicius Costa Gomes 
send_conn_param_neg_reply(struct hci_dev * hdev,u16 handle,u8 reason)65138e75b46aSAndre Guedes static void send_conn_param_neg_reply(struct hci_dev *hdev, u16 handle,
65148e75b46aSAndre Guedes 				      u8 reason)
65158e75b46aSAndre Guedes {
65168e75b46aSAndre Guedes 	struct hci_cp_le_conn_param_req_neg_reply cp;
65178e75b46aSAndre Guedes 
65188e75b46aSAndre Guedes 	cp.handle = cpu_to_le16(handle);
65198e75b46aSAndre Guedes 	cp.reason = reason;
65208e75b46aSAndre Guedes 
65218e75b46aSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY, sizeof(cp),
65228e75b46aSAndre Guedes 		     &cp);
65238e75b46aSAndre Guedes }
65248e75b46aSAndre Guedes 
hci_le_remote_conn_param_req_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)652595118dd4SLuiz Augusto von Dentz static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev, void *data,
65268e75b46aSAndre Guedes 					     struct sk_buff *skb)
65278e75b46aSAndre Guedes {
652895118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_remote_conn_param_req *ev = data;
65298e75b46aSAndre Guedes 	struct hci_cp_le_conn_param_req_reply cp;
65308e75b46aSAndre Guedes 	struct hci_conn *hcon;
65318e75b46aSAndre Guedes 	u16 handle, min, max, latency, timeout;
65328e75b46aSAndre Guedes 
653395118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "handle 0x%4.4x", __le16_to_cpu(ev->handle));
653412cfe417SLuiz Augusto von Dentz 
65358e75b46aSAndre Guedes 	handle = le16_to_cpu(ev->handle);
65368e75b46aSAndre Guedes 	min = le16_to_cpu(ev->interval_min);
65378e75b46aSAndre Guedes 	max = le16_to_cpu(ev->interval_max);
65388e75b46aSAndre Guedes 	latency = le16_to_cpu(ev->latency);
65398e75b46aSAndre Guedes 	timeout = le16_to_cpu(ev->timeout);
65408e75b46aSAndre Guedes 
65418e75b46aSAndre Guedes 	hcon = hci_conn_hash_lookup_handle(hdev, handle);
65428e75b46aSAndre Guedes 	if (!hcon || hcon->state != BT_CONNECTED)
65438e75b46aSAndre Guedes 		return send_conn_param_neg_reply(hdev, handle,
65448e75b46aSAndre Guedes 						 HCI_ERROR_UNKNOWN_CONN_ID);
65458e75b46aSAndre Guedes 
6546dcd646f4SKai-Heng Feng 	if (max > hcon->le_conn_max_interval)
6547dcd646f4SKai-Heng Feng 		return send_conn_param_neg_reply(hdev, handle,
6548dcd646f4SKai-Heng Feng 						 HCI_ERROR_INVALID_LL_PARAMS);
6549dcd646f4SKai-Heng Feng 
65508e75b46aSAndre Guedes 	if (hci_check_conn_params(min, max, latency, timeout))
65518e75b46aSAndre Guedes 		return send_conn_param_neg_reply(hdev, handle,
65528e75b46aSAndre Guedes 						 HCI_ERROR_INVALID_LL_PARAMS);
65538e75b46aSAndre Guedes 
655440bef302SJohan Hedberg 	if (hcon->role == HCI_ROLE_MASTER) {
6555348d50b8SJohan Hedberg 		struct hci_conn_params *params;
6556f4869e2aSJohan Hedberg 		u8 store_hint;
6557348d50b8SJohan Hedberg 
6558348d50b8SJohan Hedberg 		hci_dev_lock(hdev);
6559348d50b8SJohan Hedberg 
6560348d50b8SJohan Hedberg 		params = hci_conn_params_lookup(hdev, &hcon->dst,
6561348d50b8SJohan Hedberg 						hcon->dst_type);
6562348d50b8SJohan Hedberg 		if (params) {
6563348d50b8SJohan Hedberg 			params->conn_min_interval = min;
6564348d50b8SJohan Hedberg 			params->conn_max_interval = max;
6565348d50b8SJohan Hedberg 			params->conn_latency = latency;
6566348d50b8SJohan Hedberg 			params->supervision_timeout = timeout;
6567f4869e2aSJohan Hedberg 			store_hint = 0x01;
6568f4869e2aSJohan Hedberg 		} else {
6569f4869e2aSJohan Hedberg 			store_hint = 0x00;
6570348d50b8SJohan Hedberg 		}
6571348d50b8SJohan Hedberg 
6572348d50b8SJohan Hedberg 		hci_dev_unlock(hdev);
6573348d50b8SJohan Hedberg 
6574f4869e2aSJohan Hedberg 		mgmt_new_conn_param(hdev, &hcon->dst, hcon->dst_type,
6575f4869e2aSJohan Hedberg 				    store_hint, min, max, latency, timeout);
6576348d50b8SJohan Hedberg 	}
6577ffb5a827SAndre Guedes 
65788e75b46aSAndre Guedes 	cp.handle = ev->handle;
65798e75b46aSAndre Guedes 	cp.interval_min = ev->interval_min;
65808e75b46aSAndre Guedes 	cp.interval_max = ev->interval_max;
65818e75b46aSAndre Guedes 	cp.latency = ev->latency;
65828e75b46aSAndre Guedes 	cp.timeout = ev->timeout;
65838e75b46aSAndre Guedes 	cp.min_ce_len = 0;
65848e75b46aSAndre Guedes 	cp.max_ce_len = 0;
65858e75b46aSAndre Guedes 
65868e75b46aSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_REPLY, sizeof(cp), &cp);
65878e75b46aSAndre Guedes }
65888e75b46aSAndre Guedes 
hci_le_direct_adv_report_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)658995118dd4SLuiz Augusto von Dentz static void hci_le_direct_adv_report_evt(struct hci_dev *hdev, void *data,
65902f010b55SMarcel Holtmann 					 struct sk_buff *skb)
65912f010b55SMarcel Holtmann {
659295118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_direct_adv_report *ev = data;
6593b338d917SBrian Gix 	u64 instant = jiffies;
6594a3679649SLuiz Augusto von Dentz 	int i;
6595f7e0e8b2SPeilin Ye 
6596a3679649SLuiz Augusto von Dentz 	if (!hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_DIRECT_ADV_REPORT,
6597a3679649SLuiz Augusto von Dentz 				flex_array_size(ev, info, ev->num)))
6598a3679649SLuiz Augusto von Dentz 		return;
6599a3679649SLuiz Augusto von Dentz 
6600a3679649SLuiz Augusto von Dentz 	if (!ev->num)
6601f7e0e8b2SPeilin Ye 		return;
66022f010b55SMarcel Holtmann 
66032f010b55SMarcel Holtmann 	hci_dev_lock(hdev);
66042f010b55SMarcel Holtmann 
6605a3679649SLuiz Augusto von Dentz 	for (i = 0; i < ev->num; i++) {
6606a3679649SLuiz Augusto von Dentz 		struct hci_ev_le_direct_adv_info *info = &ev->info[i];
6607a3679649SLuiz Augusto von Dentz 
6608a3679649SLuiz Augusto von Dentz 		process_adv_report(hdev, info->type, &info->bdaddr,
6609a3679649SLuiz Augusto von Dentz 				   info->bdaddr_type, &info->direct_addr,
6610a3679649SLuiz Augusto von Dentz 				   info->direct_addr_type, info->rssi, NULL, 0,
6611b338d917SBrian Gix 				   false, false, instant);
6612a3679649SLuiz Augusto von Dentz 	}
66132f010b55SMarcel Holtmann 
66142f010b55SMarcel Holtmann 	hci_dev_unlock(hdev);
66152f010b55SMarcel Holtmann }
66162f010b55SMarcel Holtmann 
hci_le_phy_update_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)661795118dd4SLuiz Augusto von Dentz static void hci_le_phy_update_evt(struct hci_dev *hdev, void *data,
661895118dd4SLuiz Augusto von Dentz 				  struct sk_buff *skb)
66191efd927dSLuiz Augusto von Dentz {
662095118dd4SLuiz Augusto von Dentz 	struct hci_ev_le_phy_update_complete *ev = data;
66211efd927dSLuiz Augusto von Dentz 	struct hci_conn *conn;
66221efd927dSLuiz Augusto von Dentz 
662395118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
66241efd927dSLuiz Augusto von Dentz 
662587df8bccSAyush Garg 	if (ev->status)
66261efd927dSLuiz Augusto von Dentz 		return;
66271efd927dSLuiz Augusto von Dentz 
66281efd927dSLuiz Augusto von Dentz 	hci_dev_lock(hdev);
66291efd927dSLuiz Augusto von Dentz 
66301efd927dSLuiz Augusto von Dentz 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
66311efd927dSLuiz Augusto von Dentz 	if (!conn)
66321efd927dSLuiz Augusto von Dentz 		goto unlock;
66331efd927dSLuiz Augusto von Dentz 
66341efd927dSLuiz Augusto von Dentz 	conn->le_tx_phy = ev->tx_phy;
66351efd927dSLuiz Augusto von Dentz 	conn->le_rx_phy = ev->rx_phy;
66361efd927dSLuiz Augusto von Dentz 
66371efd927dSLuiz Augusto von Dentz unlock:
66381efd927dSLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
66391efd927dSLuiz Augusto von Dentz }
66401efd927dSLuiz Augusto von Dentz 
hci_le_cis_estabilished_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)664126afbd82SLuiz Augusto von Dentz static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data,
664226afbd82SLuiz Augusto von Dentz 					struct sk_buff *skb)
664326afbd82SLuiz Augusto von Dentz {
664426afbd82SLuiz Augusto von Dentz 	struct hci_evt_le_cis_established *ev = data;
664526afbd82SLuiz Augusto von Dentz 	struct hci_conn *conn;
66462be22f19SLuiz Augusto von Dentz 	struct bt_iso_qos *qos;
66477f74563eSPauli Virtanen 	bool pending = false;
664826afbd82SLuiz Augusto von Dentz 	u16 handle = __le16_to_cpu(ev->handle);
664926afbd82SLuiz Augusto von Dentz 
665026afbd82SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
665126afbd82SLuiz Augusto von Dentz 
665226afbd82SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
665326afbd82SLuiz Augusto von Dentz 
665426afbd82SLuiz Augusto von Dentz 	conn = hci_conn_hash_lookup_handle(hdev, handle);
665526afbd82SLuiz Augusto von Dentz 	if (!conn) {
665626afbd82SLuiz Augusto von Dentz 		bt_dev_err(hdev,
665726afbd82SLuiz Augusto von Dentz 			   "Unable to find connection with handle 0x%4.4x",
665826afbd82SLuiz Augusto von Dentz 			   handle);
665926afbd82SLuiz Augusto von Dentz 		goto unlock;
666026afbd82SLuiz Augusto von Dentz 	}
666126afbd82SLuiz Augusto von Dentz 
6662ed680f92SLuiz Augusto von Dentz 	if (conn->type != ISO_LINK) {
6663ed680f92SLuiz Augusto von Dentz 		bt_dev_err(hdev,
6664ed680f92SLuiz Augusto von Dentz 			   "Invalid connection link type handle 0x%4.4x",
6665ed680f92SLuiz Augusto von Dentz 			   handle);
6666ed680f92SLuiz Augusto von Dentz 		goto unlock;
6667ed680f92SLuiz Augusto von Dentz 	}
6668ed680f92SLuiz Augusto von Dentz 
66692be22f19SLuiz Augusto von Dentz 	qos = &conn->iso_qos;
667026afbd82SLuiz Augusto von Dentz 
66717f74563eSPauli Virtanen 	pending = test_and_clear_bit(HCI_CONN_CREATE_CIS, &conn->flags);
66727f74563eSPauli Virtanen 
66732be22f19SLuiz Augusto von Dentz 	/* Convert ISO Interval (1.25 ms slots) to SDU Interval (us) */
66742be22f19SLuiz Augusto von Dentz 	qos->ucast.in.interval = le16_to_cpu(ev->interval) * 1250;
66752be22f19SLuiz Augusto von Dentz 	qos->ucast.out.interval = qos->ucast.in.interval;
667626afbd82SLuiz Augusto von Dentz 
66772be22f19SLuiz Augusto von Dentz 	switch (conn->role) {
66782be22f19SLuiz Augusto von Dentz 	case HCI_ROLE_SLAVE:
66792be22f19SLuiz Augusto von Dentz 		/* Convert Transport Latency (us) to Latency (msec) */
66802be22f19SLuiz Augusto von Dentz 		qos->ucast.in.latency =
66812be22f19SLuiz Augusto von Dentz 			DIV_ROUND_CLOSEST(get_unaligned_le24(ev->c_latency),
66822be22f19SLuiz Augusto von Dentz 					  1000);
66832be22f19SLuiz Augusto von Dentz 		qos->ucast.out.latency =
66842be22f19SLuiz Augusto von Dentz 			DIV_ROUND_CLOSEST(get_unaligned_le24(ev->p_latency),
66852be22f19SLuiz Augusto von Dentz 					  1000);
66862be22f19SLuiz Augusto von Dentz 		qos->ucast.in.sdu = le16_to_cpu(ev->c_mtu);
66872be22f19SLuiz Augusto von Dentz 		qos->ucast.out.sdu = le16_to_cpu(ev->p_mtu);
66882be22f19SLuiz Augusto von Dentz 		qos->ucast.in.phy = ev->c_phy;
66892be22f19SLuiz Augusto von Dentz 		qos->ucast.out.phy = ev->p_phy;
66902be22f19SLuiz Augusto von Dentz 		break;
66912be22f19SLuiz Augusto von Dentz 	case HCI_ROLE_MASTER:
66922be22f19SLuiz Augusto von Dentz 		/* Convert Transport Latency (us) to Latency (msec) */
66932be22f19SLuiz Augusto von Dentz 		qos->ucast.out.latency =
66942be22f19SLuiz Augusto von Dentz 			DIV_ROUND_CLOSEST(get_unaligned_le24(ev->c_latency),
66952be22f19SLuiz Augusto von Dentz 					  1000);
66962be22f19SLuiz Augusto von Dentz 		qos->ucast.in.latency =
66972be22f19SLuiz Augusto von Dentz 			DIV_ROUND_CLOSEST(get_unaligned_le24(ev->p_latency),
66982be22f19SLuiz Augusto von Dentz 					  1000);
66992be22f19SLuiz Augusto von Dentz 		qos->ucast.out.sdu = le16_to_cpu(ev->c_mtu);
67002be22f19SLuiz Augusto von Dentz 		qos->ucast.in.sdu = le16_to_cpu(ev->p_mtu);
67012be22f19SLuiz Augusto von Dentz 		qos->ucast.out.phy = ev->c_phy;
67022be22f19SLuiz Augusto von Dentz 		qos->ucast.in.phy = ev->p_phy;
67032be22f19SLuiz Augusto von Dentz 		break;
670426afbd82SLuiz Augusto von Dentz 	}
670526afbd82SLuiz Augusto von Dentz 
670626afbd82SLuiz Augusto von Dentz 	if (!ev->status) {
670726afbd82SLuiz Augusto von Dentz 		conn->state = BT_CONNECTED;
670826afbd82SLuiz Augusto von Dentz 		hci_debugfs_create_conn(conn);
670926afbd82SLuiz Augusto von Dentz 		hci_conn_add_sysfs(conn);
671026afbd82SLuiz Augusto von Dentz 		hci_iso_setup_path(conn);
671126afbd82SLuiz Augusto von Dentz 		goto unlock;
671226afbd82SLuiz Augusto von Dentz 	}
671326afbd82SLuiz Augusto von Dentz 
67147f74563eSPauli Virtanen 	conn->state = BT_CLOSED;
671526afbd82SLuiz Augusto von Dentz 	hci_connect_cfm(conn, ev->status);
671626afbd82SLuiz Augusto von Dentz 	hci_conn_del(conn);
671726afbd82SLuiz Augusto von Dentz 
671826afbd82SLuiz Augusto von Dentz unlock:
67197f74563eSPauli Virtanen 	if (pending)
67207f74563eSPauli Virtanen 		hci_le_create_cis_pending(hdev);
67217f74563eSPauli Virtanen 
672226afbd82SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
672326afbd82SLuiz Augusto von Dentz }
672426afbd82SLuiz Augusto von Dentz 
hci_le_reject_cis(struct hci_dev * hdev,__le16 handle)672526afbd82SLuiz Augusto von Dentz static void hci_le_reject_cis(struct hci_dev *hdev, __le16 handle)
672626afbd82SLuiz Augusto von Dentz {
672726afbd82SLuiz Augusto von Dentz 	struct hci_cp_le_reject_cis cp;
672826afbd82SLuiz Augusto von Dentz 
672926afbd82SLuiz Augusto von Dentz 	memset(&cp, 0, sizeof(cp));
673026afbd82SLuiz Augusto von Dentz 	cp.handle = handle;
673126afbd82SLuiz Augusto von Dentz 	cp.reason = HCI_ERROR_REJ_BAD_ADDR;
673226afbd82SLuiz Augusto von Dentz 	hci_send_cmd(hdev, HCI_OP_LE_REJECT_CIS, sizeof(cp), &cp);
673326afbd82SLuiz Augusto von Dentz }
673426afbd82SLuiz Augusto von Dentz 
hci_le_accept_cis(struct hci_dev * hdev,__le16 handle)673526afbd82SLuiz Augusto von Dentz static void hci_le_accept_cis(struct hci_dev *hdev, __le16 handle)
673626afbd82SLuiz Augusto von Dentz {
673726afbd82SLuiz Augusto von Dentz 	struct hci_cp_le_accept_cis cp;
673826afbd82SLuiz Augusto von Dentz 
673926afbd82SLuiz Augusto von Dentz 	memset(&cp, 0, sizeof(cp));
674026afbd82SLuiz Augusto von Dentz 	cp.handle = handle;
674126afbd82SLuiz Augusto von Dentz 	hci_send_cmd(hdev, HCI_OP_LE_ACCEPT_CIS, sizeof(cp), &cp);
674226afbd82SLuiz Augusto von Dentz }
674326afbd82SLuiz Augusto von Dentz 
hci_le_cis_req_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)674426afbd82SLuiz Augusto von Dentz static void hci_le_cis_req_evt(struct hci_dev *hdev, void *data,
674526afbd82SLuiz Augusto von Dentz 			       struct sk_buff *skb)
674626afbd82SLuiz Augusto von Dentz {
674726afbd82SLuiz Augusto von Dentz 	struct hci_evt_le_cis_req *ev = data;
674826afbd82SLuiz Augusto von Dentz 	u16 acl_handle, cis_handle;
674926afbd82SLuiz Augusto von Dentz 	struct hci_conn *acl, *cis;
675026afbd82SLuiz Augusto von Dentz 	int mask;
675126afbd82SLuiz Augusto von Dentz 	__u8 flags = 0;
675226afbd82SLuiz Augusto von Dentz 
675326afbd82SLuiz Augusto von Dentz 	acl_handle = __le16_to_cpu(ev->acl_handle);
675426afbd82SLuiz Augusto von Dentz 	cis_handle = __le16_to_cpu(ev->cis_handle);
675526afbd82SLuiz Augusto von Dentz 
675626afbd82SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "acl 0x%4.4x handle 0x%4.4x cig 0x%2.2x cis 0x%2.2x",
675726afbd82SLuiz Augusto von Dentz 		   acl_handle, cis_handle, ev->cig_id, ev->cis_id);
675826afbd82SLuiz Augusto von Dentz 
675926afbd82SLuiz Augusto von Dentz 	hci_dev_lock(hdev);
676026afbd82SLuiz Augusto von Dentz 
676126afbd82SLuiz Augusto von Dentz 	acl = hci_conn_hash_lookup_handle(hdev, acl_handle);
676226afbd82SLuiz Augusto von Dentz 	if (!acl)
676326afbd82SLuiz Augusto von Dentz 		goto unlock;
676426afbd82SLuiz Augusto von Dentz 
676526afbd82SLuiz Augusto von Dentz 	mask = hci_proto_connect_ind(hdev, &acl->dst, ISO_LINK, &flags);
676626afbd82SLuiz Augusto von Dentz 	if (!(mask & HCI_LM_ACCEPT)) {
676726afbd82SLuiz Augusto von Dentz 		hci_le_reject_cis(hdev, ev->cis_handle);
676826afbd82SLuiz Augusto von Dentz 		goto unlock;
676926afbd82SLuiz Augusto von Dentz 	}
677026afbd82SLuiz Augusto von Dentz 
677126afbd82SLuiz Augusto von Dentz 	cis = hci_conn_hash_lookup_handle(hdev, cis_handle);
677226afbd82SLuiz Augusto von Dentz 	if (!cis) {
677384cb0143SZiyang Xuan 		cis = hci_conn_add(hdev, ISO_LINK, &acl->dst, HCI_ROLE_SLAVE,
677484cb0143SZiyang Xuan 				   cis_handle);
6775ad3f7986SSungwoo Kim 		if (IS_ERR(cis)) {
677626afbd82SLuiz Augusto von Dentz 			hci_le_reject_cis(hdev, ev->cis_handle);
677726afbd82SLuiz Augusto von Dentz 			goto unlock;
677826afbd82SLuiz Augusto von Dentz 		}
677926afbd82SLuiz Augusto von Dentz 	}
678026afbd82SLuiz Augusto von Dentz 
67810fe8c8d0SIulia Tanasescu 	cis->iso_qos.ucast.cig = ev->cig_id;
67820fe8c8d0SIulia Tanasescu 	cis->iso_qos.ucast.cis = ev->cis_id;
678326afbd82SLuiz Augusto von Dentz 
678426afbd82SLuiz Augusto von Dentz 	if (!(flags & HCI_PROTO_DEFER)) {
678526afbd82SLuiz Augusto von Dentz 		hci_le_accept_cis(hdev, ev->cis_handle);
678626afbd82SLuiz Augusto von Dentz 	} else {
678726afbd82SLuiz Augusto von Dentz 		cis->state = BT_CONNECT2;
678826afbd82SLuiz Augusto von Dentz 		hci_connect_cfm(cis, 0);
678926afbd82SLuiz Augusto von Dentz 	}
679026afbd82SLuiz Augusto von Dentz 
679126afbd82SLuiz Augusto von Dentz unlock:
679226afbd82SLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
679326afbd82SLuiz Augusto von Dentz }
679426afbd82SLuiz Augusto von Dentz 
hci_iso_term_big_sync(struct hci_dev * hdev,void * data)6795acab8ff2SIulia Tanasescu static int hci_iso_term_big_sync(struct hci_dev *hdev, void *data)
6796acab8ff2SIulia Tanasescu {
6797acab8ff2SIulia Tanasescu 	u8 handle = PTR_UINT(data);
6798acab8ff2SIulia Tanasescu 
6799acab8ff2SIulia Tanasescu 	return hci_le_terminate_big_sync(hdev, handle,
6800acab8ff2SIulia Tanasescu 					 HCI_ERROR_LOCAL_HOST_TERM);
6801acab8ff2SIulia Tanasescu }
6802acab8ff2SIulia Tanasescu 
hci_le_create_big_complete_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)6803eca0ae4aSLuiz Augusto von Dentz static void hci_le_create_big_complete_evt(struct hci_dev *hdev, void *data,
6804eca0ae4aSLuiz Augusto von Dentz 					   struct sk_buff *skb)
6805eca0ae4aSLuiz Augusto von Dentz {
6806eca0ae4aSLuiz Augusto von Dentz 	struct hci_evt_le_create_big_complete *ev = data;
6807eca0ae4aSLuiz Augusto von Dentz 	struct hci_conn *conn;
680816e3b642SLuiz Augusto von Dentz 	__u8 i = 0;
6809eca0ae4aSLuiz Augusto von Dentz 
6810eca0ae4aSLuiz Augusto von Dentz 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
6811eca0ae4aSLuiz Augusto von Dentz 
6812eca0ae4aSLuiz Augusto von Dentz 	if (!hci_le_ev_skb_pull(hdev, skb, HCI_EVT_LE_CREATE_BIG_COMPLETE,
6813eca0ae4aSLuiz Augusto von Dentz 				flex_array_size(ev, bis_handle, ev->num_bis)))
6814eca0ae4aSLuiz Augusto von Dentz 		return;
6815eca0ae4aSLuiz Augusto von Dentz 
6816eca0ae4aSLuiz Augusto von Dentz 	hci_dev_lock(hdev);
6817a0bfde16SIulia Tanasescu 	rcu_read_lock();
6818eca0ae4aSLuiz Augusto von Dentz 
6819a0bfde16SIulia Tanasescu 	/* Connect all BISes that are bound to the BIG */
6820a0bfde16SIulia Tanasescu 	list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) {
6821a0bfde16SIulia Tanasescu 		if (bacmp(&conn->dst, BDADDR_ANY) ||
6822a0bfde16SIulia Tanasescu 		    conn->type != ISO_LINK ||
6823a0bfde16SIulia Tanasescu 		    conn->iso_qos.bcast.big != ev->handle)
6824a0bfde16SIulia Tanasescu 			continue;
6825eca0ae4aSLuiz Augusto von Dentz 
682616e3b642SLuiz Augusto von Dentz 		if (hci_conn_set_handle(conn,
682716e3b642SLuiz Augusto von Dentz 					__le16_to_cpu(ev->bis_handle[i++])))
682816e3b642SLuiz Augusto von Dentz 			continue;
6829eca0ae4aSLuiz Augusto von Dentz 
6830eca0ae4aSLuiz Augusto von Dentz 		if (!ev->status) {
6831eca0ae4aSLuiz Augusto von Dentz 			conn->state = BT_CONNECTED;
6832a0bfde16SIulia Tanasescu 			set_bit(HCI_CONN_BIG_CREATED, &conn->flags);
6833a0bfde16SIulia Tanasescu 			rcu_read_unlock();
6834eca0ae4aSLuiz Augusto von Dentz 			hci_debugfs_create_conn(conn);
6835eca0ae4aSLuiz Augusto von Dentz 			hci_conn_add_sysfs(conn);
6836eca0ae4aSLuiz Augusto von Dentz 			hci_iso_setup_path(conn);
6837a0bfde16SIulia Tanasescu 			rcu_read_lock();
6838a0bfde16SIulia Tanasescu 			continue;
6839eca0ae4aSLuiz Augusto von Dentz 		}
6840eca0ae4aSLuiz Augusto von Dentz 
6841eca0ae4aSLuiz Augusto von Dentz 		hci_connect_cfm(conn, ev->status);
6842a0bfde16SIulia Tanasescu 		rcu_read_unlock();
6843eca0ae4aSLuiz Augusto von Dentz 		hci_conn_del(conn);
6844a0bfde16SIulia Tanasescu 		rcu_read_lock();
6845a0bfde16SIulia Tanasescu 	}
6846eca0ae4aSLuiz Augusto von Dentz 
6847acab8ff2SIulia Tanasescu 	rcu_read_unlock();
6848acab8ff2SIulia Tanasescu 
684916e3b642SLuiz Augusto von Dentz 	if (!ev->status && !i)
6850a0bfde16SIulia Tanasescu 		/* If no BISes have been connected for the BIG,
6851a0bfde16SIulia Tanasescu 		 * terminate. This is in case all bound connections
6852a0bfde16SIulia Tanasescu 		 * have been closed before the BIG creation
6853a0bfde16SIulia Tanasescu 		 * has completed.
6854a0bfde16SIulia Tanasescu 		 */
6855acab8ff2SIulia Tanasescu 		hci_cmd_sync_queue(hdev, hci_iso_term_big_sync,
6856acab8ff2SIulia Tanasescu 				   UINT_PTR(ev->handle), NULL);
6857a0bfde16SIulia Tanasescu 
6858eca0ae4aSLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
6859eca0ae4aSLuiz Augusto von Dentz }
6860eca0ae4aSLuiz Augusto von Dentz 
hci_le_big_sync_established_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)6861eca0ae4aSLuiz Augusto von Dentz static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data,
6862eca0ae4aSLuiz Augusto von Dentz 					    struct sk_buff *skb)
6863eca0ae4aSLuiz Augusto von Dentz {
6864eca0ae4aSLuiz Augusto von Dentz 	struct hci_evt_le_big_sync_estabilished *ev = data;
6865eca0ae4aSLuiz Augusto von Dentz 	struct hci_conn *bis;
6866fbdc4bc4SIulia Tanasescu 	struct hci_conn *pa_sync;
6867eca0ae4aSLuiz Augusto von Dentz 	int i;
6868eca0ae4aSLuiz Augusto von Dentz 
6869eca0ae4aSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
6870eca0ae4aSLuiz Augusto von Dentz 
6871eca0ae4aSLuiz Augusto von Dentz 	if (!hci_le_ev_skb_pull(hdev, skb, HCI_EVT_LE_BIG_SYNC_ESTABILISHED,
6872eca0ae4aSLuiz Augusto von Dentz 				flex_array_size(ev, bis, ev->num_bis)))
6873eca0ae4aSLuiz Augusto von Dentz 		return;
6874eca0ae4aSLuiz Augusto von Dentz 
6875eca0ae4aSLuiz Augusto von Dentz 	hci_dev_lock(hdev);
6876eca0ae4aSLuiz Augusto von Dentz 
6877fbdc4bc4SIulia Tanasescu 	if (!ev->status) {
687823417475SIulia Tanasescu 		pa_sync = hci_conn_hash_lookup_pa_sync_big_handle(hdev, ev->handle);
6879fbdc4bc4SIulia Tanasescu 		if (pa_sync)
6880fbdc4bc4SIulia Tanasescu 			/* Also mark the BIG sync established event on the
6881fbdc4bc4SIulia Tanasescu 			 * associated PA sync hcon
6882fbdc4bc4SIulia Tanasescu 			 */
6883fbdc4bc4SIulia Tanasescu 			set_bit(HCI_CONN_BIG_SYNC, &pa_sync->flags);
6884fbdc4bc4SIulia Tanasescu 	}
6885fbdc4bc4SIulia Tanasescu 
6886eca0ae4aSLuiz Augusto von Dentz 	for (i = 0; i < ev->num_bis; i++) {
6887eca0ae4aSLuiz Augusto von Dentz 		u16 handle = le16_to_cpu(ev->bis[i]);
6888eca0ae4aSLuiz Augusto von Dentz 		__le32 interval;
6889eca0ae4aSLuiz Augusto von Dentz 
6890eca0ae4aSLuiz Augusto von Dentz 		bis = hci_conn_hash_lookup_handle(hdev, handle);
6891eca0ae4aSLuiz Augusto von Dentz 		if (!bis) {
6892eca0ae4aSLuiz Augusto von Dentz 			bis = hci_conn_add(hdev, ISO_LINK, BDADDR_ANY,
689384cb0143SZiyang Xuan 					   HCI_ROLE_SLAVE, handle);
6894ad3f7986SSungwoo Kim 			if (IS_ERR(bis))
6895eca0ae4aSLuiz Augusto von Dentz 				continue;
6896eca0ae4aSLuiz Augusto von Dentz 		}
6897eca0ae4aSLuiz Augusto von Dentz 
6898fbdc4bc4SIulia Tanasescu 		if (ev->status != 0x42)
6899fbdc4bc4SIulia Tanasescu 			/* Mark PA sync as established */
6900fbdc4bc4SIulia Tanasescu 			set_bit(HCI_CONN_PA_SYNC, &bis->flags);
6901fbdc4bc4SIulia Tanasescu 
69020fe8c8d0SIulia Tanasescu 		bis->iso_qos.bcast.big = ev->handle;
6903eca0ae4aSLuiz Augusto von Dentz 		memset(&interval, 0, sizeof(interval));
6904eca0ae4aSLuiz Augusto von Dentz 		memcpy(&interval, ev->latency, sizeof(ev->latency));
69050fe8c8d0SIulia Tanasescu 		bis->iso_qos.bcast.in.interval = le32_to_cpu(interval);
6906eca0ae4aSLuiz Augusto von Dentz 		/* Convert ISO Interval (1.25 ms slots) to latency (ms) */
69070fe8c8d0SIulia Tanasescu 		bis->iso_qos.bcast.in.latency = le16_to_cpu(ev->interval) * 125 / 100;
69080fe8c8d0SIulia Tanasescu 		bis->iso_qos.bcast.in.sdu = le16_to_cpu(ev->max_pdu);
6909eca0ae4aSLuiz Augusto von Dentz 
6910f777d882SIulia Tanasescu 		if (!ev->status) {
6911f777d882SIulia Tanasescu 			set_bit(HCI_CONN_BIG_SYNC, &bis->flags);
6912d2e4f1b1SClaudia Draghicescu 			hci_iso_setup_path(bis);
6913eca0ae4aSLuiz Augusto von Dentz 		}
6914f777d882SIulia Tanasescu 	}
6915f777d882SIulia Tanasescu 
6916f777d882SIulia Tanasescu 	/* In case BIG sync failed, notify each failed connection to
6917f777d882SIulia Tanasescu 	 * the user after all hci connections have been added
6918f777d882SIulia Tanasescu 	 */
6919f777d882SIulia Tanasescu 	if (ev->status)
6920f777d882SIulia Tanasescu 		for (i = 0; i < ev->num_bis; i++) {
6921f777d882SIulia Tanasescu 			u16 handle = le16_to_cpu(ev->bis[i]);
6922f777d882SIulia Tanasescu 
6923f777d882SIulia Tanasescu 			bis = hci_conn_hash_lookup_handle(hdev, handle);
69241f7ebb69SSungwoo Kim 			if (!bis)
69251f7ebb69SSungwoo Kim 				continue;
6926f777d882SIulia Tanasescu 
6927f777d882SIulia Tanasescu 			set_bit(HCI_CONN_BIG_SYNC_FAILED, &bis->flags);
6928f777d882SIulia Tanasescu 			hci_connect_cfm(bis, ev->status);
6929f777d882SIulia Tanasescu 		}
6930eca0ae4aSLuiz Augusto von Dentz 
6931eca0ae4aSLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
6932eca0ae4aSLuiz Augusto von Dentz }
6933eca0ae4aSLuiz Augusto von Dentz 
hci_le_big_info_adv_report_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb)6934eca0ae4aSLuiz Augusto von Dentz static void hci_le_big_info_adv_report_evt(struct hci_dev *hdev, void *data,
6935eca0ae4aSLuiz Augusto von Dentz 					   struct sk_buff *skb)
6936eca0ae4aSLuiz Augusto von Dentz {
6937eca0ae4aSLuiz Augusto von Dentz 	struct hci_evt_le_big_info_adv_report *ev = data;
6938eca0ae4aSLuiz Augusto von Dentz 	int mask = hdev->link_mode;
6939eca0ae4aSLuiz Augusto von Dentz 	__u8 flags = 0;
694023417475SIulia Tanasescu 	struct hci_conn *pa_sync;
6941eca0ae4aSLuiz Augusto von Dentz 
6942eca0ae4aSLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "sync_handle 0x%4.4x", le16_to_cpu(ev->sync_handle));
6943eca0ae4aSLuiz Augusto von Dentz 
6944eca0ae4aSLuiz Augusto von Dentz 	hci_dev_lock(hdev);
6945eca0ae4aSLuiz Augusto von Dentz 
6946eca0ae4aSLuiz Augusto von Dentz 	mask |= hci_proto_connect_ind(hdev, BDADDR_ANY, ISO_LINK, &flags);
694723417475SIulia Tanasescu 	if (!(mask & HCI_LM_ACCEPT)) {
6948eca0ae4aSLuiz Augusto von Dentz 		hci_le_pa_term_sync(hdev, ev->sync_handle);
694923417475SIulia Tanasescu 		goto unlock;
695023417475SIulia Tanasescu 	}
6951eca0ae4aSLuiz Augusto von Dentz 
695223417475SIulia Tanasescu 	if (!(flags & HCI_PROTO_DEFER))
695323417475SIulia Tanasescu 		goto unlock;
695423417475SIulia Tanasescu 
695523417475SIulia Tanasescu 	pa_sync = hci_conn_hash_lookup_pa_sync_handle
695623417475SIulia Tanasescu 			(hdev,
695723417475SIulia Tanasescu 			le16_to_cpu(ev->sync_handle));
695823417475SIulia Tanasescu 
695923417475SIulia Tanasescu 	if (pa_sync)
696023417475SIulia Tanasescu 		goto unlock;
696123417475SIulia Tanasescu 
696223417475SIulia Tanasescu 	/* Add connection to indicate the PA sync event */
696384cb0143SZiyang Xuan 	pa_sync = hci_conn_add_unset(hdev, ISO_LINK, BDADDR_ANY,
696423417475SIulia Tanasescu 				     HCI_ROLE_SLAVE);
696523417475SIulia Tanasescu 
6966ad3f7986SSungwoo Kim 	if (IS_ERR(pa_sync))
696723417475SIulia Tanasescu 		goto unlock;
696823417475SIulia Tanasescu 
696923417475SIulia Tanasescu 	pa_sync->sync_handle = le16_to_cpu(ev->sync_handle);
697023417475SIulia Tanasescu 	set_bit(HCI_CONN_PA_SYNC, &pa_sync->flags);
697123417475SIulia Tanasescu 
697223417475SIulia Tanasescu 	/* Notify iso layer */
697323417475SIulia Tanasescu 	hci_connect_cfm(pa_sync, 0x00);
697423417475SIulia Tanasescu 
69750b3df53cSLuiz Augusto von Dentz 	/* Notify MGMT layer */
69760b3df53cSLuiz Augusto von Dentz 	mgmt_device_connected(hdev, pa_sync, NULL, 0);
69770b3df53cSLuiz Augusto von Dentz 
697823417475SIulia Tanasescu unlock:
6979eca0ae4aSLuiz Augusto von Dentz 	hci_dev_unlock(hdev);
6980eca0ae4aSLuiz Augusto von Dentz }
6981eca0ae4aSLuiz Augusto von Dentz 
698295118dd4SLuiz Augusto von Dentz #define HCI_LE_EV_VL(_op, _func, _min_len, _max_len) \
698395118dd4SLuiz Augusto von Dentz [_op] = { \
698495118dd4SLuiz Augusto von Dentz 	.func = _func, \
698595118dd4SLuiz Augusto von Dentz 	.min_len = _min_len, \
698695118dd4SLuiz Augusto von Dentz 	.max_len = _max_len, \
698795118dd4SLuiz Augusto von Dentz }
698895118dd4SLuiz Augusto von Dentz 
698995118dd4SLuiz Augusto von Dentz #define HCI_LE_EV(_op, _func, _len) \
699095118dd4SLuiz Augusto von Dentz 	HCI_LE_EV_VL(_op, _func, _len, _len)
699195118dd4SLuiz Augusto von Dentz 
699295118dd4SLuiz Augusto von Dentz #define HCI_LE_EV_STATUS(_op, _func) \
699395118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(_op, _func, sizeof(struct hci_ev_status))
699495118dd4SLuiz Augusto von Dentz 
699595118dd4SLuiz Augusto von Dentz /* Entries in this table shall have their position according to the subevent
699695118dd4SLuiz Augusto von Dentz  * opcode they handle so the use of the macros above is recommend since it does
699795118dd4SLuiz Augusto von Dentz  * attempt to initialize at its proper index using Designated Initializers that
699895118dd4SLuiz Augusto von Dentz  * way events without a callback function can be ommited.
699995118dd4SLuiz Augusto von Dentz  */
700095118dd4SLuiz Augusto von Dentz static const struct hci_le_ev {
700195118dd4SLuiz Augusto von Dentz 	void (*func)(struct hci_dev *hdev, void *data, struct sk_buff *skb);
700295118dd4SLuiz Augusto von Dentz 	u16  min_len;
700395118dd4SLuiz Augusto von Dentz 	u16  max_len;
700495118dd4SLuiz Augusto von Dentz } hci_le_ev_table[U8_MAX + 1] = {
700595118dd4SLuiz Augusto von Dentz 	/* [0x01 = HCI_EV_LE_CONN_COMPLETE] */
700695118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_CONN_COMPLETE, hci_le_conn_complete_evt,
700795118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_conn_complete)),
700895118dd4SLuiz Augusto von Dentz 	/* [0x02 = HCI_EV_LE_ADVERTISING_REPORT] */
700995118dd4SLuiz Augusto von Dentz 	HCI_LE_EV_VL(HCI_EV_LE_ADVERTISING_REPORT, hci_le_adv_report_evt,
701095118dd4SLuiz Augusto von Dentz 		     sizeof(struct hci_ev_le_advertising_report),
701195118dd4SLuiz Augusto von Dentz 		     HCI_MAX_EVENT_SIZE),
701295118dd4SLuiz Augusto von Dentz 	/* [0x03 = HCI_EV_LE_CONN_UPDATE_COMPLETE] */
701395118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_CONN_UPDATE_COMPLETE,
701495118dd4SLuiz Augusto von Dentz 		  hci_le_conn_update_complete_evt,
701595118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_conn_update_complete)),
701695118dd4SLuiz Augusto von Dentz 	/* [0x04 = HCI_EV_LE_REMOTE_FEAT_COMPLETE] */
701795118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_REMOTE_FEAT_COMPLETE,
701895118dd4SLuiz Augusto von Dentz 		  hci_le_remote_feat_complete_evt,
701995118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_remote_feat_complete)),
702095118dd4SLuiz Augusto von Dentz 	/* [0x05 = HCI_EV_LE_LTK_REQ] */
702195118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_LTK_REQ, hci_le_ltk_request_evt,
702295118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_ltk_req)),
702395118dd4SLuiz Augusto von Dentz 	/* [0x06 = HCI_EV_LE_REMOTE_CONN_PARAM_REQ] */
702495118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_REMOTE_CONN_PARAM_REQ,
702595118dd4SLuiz Augusto von Dentz 		  hci_le_remote_conn_param_req_evt,
702695118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_remote_conn_param_req)),
702795118dd4SLuiz Augusto von Dentz 	/* [0x0a = HCI_EV_LE_ENHANCED_CONN_COMPLETE] */
702895118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_ENHANCED_CONN_COMPLETE,
702995118dd4SLuiz Augusto von Dentz 		  hci_le_enh_conn_complete_evt,
703095118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_enh_conn_complete)),
703195118dd4SLuiz Augusto von Dentz 	/* [0x0b = HCI_EV_LE_DIRECT_ADV_REPORT] */
703295118dd4SLuiz Augusto von Dentz 	HCI_LE_EV_VL(HCI_EV_LE_DIRECT_ADV_REPORT, hci_le_direct_adv_report_evt,
703395118dd4SLuiz Augusto von Dentz 		     sizeof(struct hci_ev_le_direct_adv_report),
703495118dd4SLuiz Augusto von Dentz 		     HCI_MAX_EVENT_SIZE),
703595118dd4SLuiz Augusto von Dentz 	/* [0x0c = HCI_EV_LE_PHY_UPDATE_COMPLETE] */
703695118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_PHY_UPDATE_COMPLETE, hci_le_phy_update_evt,
703795118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_phy_update_complete)),
703895118dd4SLuiz Augusto von Dentz 	/* [0x0d = HCI_EV_LE_EXT_ADV_REPORT] */
703995118dd4SLuiz Augusto von Dentz 	HCI_LE_EV_VL(HCI_EV_LE_EXT_ADV_REPORT, hci_le_ext_adv_report_evt,
704095118dd4SLuiz Augusto von Dentz 		     sizeof(struct hci_ev_le_ext_adv_report),
704195118dd4SLuiz Augusto von Dentz 		     HCI_MAX_EVENT_SIZE),
7042eca0ae4aSLuiz Augusto von Dentz 	/* [0x0e = HCI_EV_LE_PA_SYNC_ESTABLISHED] */
7043eca0ae4aSLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_PA_SYNC_ESTABLISHED,
7044eca0ae4aSLuiz Augusto von Dentz 		  hci_le_pa_sync_estabilished_evt,
7045eca0ae4aSLuiz Augusto von Dentz 		  sizeof(struct hci_ev_le_pa_sync_established)),
70469c082631SClaudia Draghicescu 	/* [0x0f = HCI_EV_LE_PER_ADV_REPORT] */
70479c082631SClaudia Draghicescu 	HCI_LE_EV_VL(HCI_EV_LE_PER_ADV_REPORT,
70489c082631SClaudia Draghicescu 				 hci_le_per_adv_report_evt,
70499c082631SClaudia Draghicescu 				 sizeof(struct hci_ev_le_per_adv_report),
70509c082631SClaudia Draghicescu 				 HCI_MAX_EVENT_SIZE),
705195118dd4SLuiz Augusto von Dentz 	/* [0x12 = HCI_EV_LE_EXT_ADV_SET_TERM] */
705295118dd4SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EV_LE_EXT_ADV_SET_TERM, hci_le_ext_adv_term_evt,
705395118dd4SLuiz Augusto von Dentz 		  sizeof(struct hci_evt_le_ext_adv_set_term)),
705426afbd82SLuiz Augusto von Dentz 	/* [0x19 = HCI_EVT_LE_CIS_ESTABLISHED] */
705526afbd82SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EVT_LE_CIS_ESTABLISHED, hci_le_cis_estabilished_evt,
705626afbd82SLuiz Augusto von Dentz 		  sizeof(struct hci_evt_le_cis_established)),
705726afbd82SLuiz Augusto von Dentz 	/* [0x1a = HCI_EVT_LE_CIS_REQ] */
705826afbd82SLuiz Augusto von Dentz 	HCI_LE_EV(HCI_EVT_LE_CIS_REQ, hci_le_cis_req_evt,
705926afbd82SLuiz Augusto von Dentz 		  sizeof(struct hci_evt_le_cis_req)),
7060eca0ae4aSLuiz Augusto von Dentz 	/* [0x1b = HCI_EVT_LE_CREATE_BIG_COMPLETE] */
7061eca0ae4aSLuiz Augusto von Dentz 	HCI_LE_EV_VL(HCI_EVT_LE_CREATE_BIG_COMPLETE,
7062eca0ae4aSLuiz Augusto von Dentz 		     hci_le_create_big_complete_evt,
7063eca0ae4aSLuiz Augusto von Dentz 		     sizeof(struct hci_evt_le_create_big_complete),
7064eca0ae4aSLuiz Augusto von Dentz 		     HCI_MAX_EVENT_SIZE),
7065eca0ae4aSLuiz Augusto von Dentz 	/* [0x1d = HCI_EV_LE_BIG_SYNC_ESTABILISHED] */
7066eca0ae4aSLuiz Augusto von Dentz 	HCI_LE_EV_VL(HCI_EVT_LE_BIG_SYNC_ESTABILISHED,
7067eca0ae4aSLuiz Augusto von Dentz 		     hci_le_big_sync_established_evt,
7068eca0ae4aSLuiz Augusto von Dentz 		     sizeof(struct hci_evt_le_big_sync_estabilished),
7069eca0ae4aSLuiz Augusto von Dentz 		     HCI_MAX_EVENT_SIZE),
7070eca0ae4aSLuiz Augusto von Dentz 	/* [0x22 = HCI_EVT_LE_BIG_INFO_ADV_REPORT] */
7071eca0ae4aSLuiz Augusto von Dentz 	HCI_LE_EV_VL(HCI_EVT_LE_BIG_INFO_ADV_REPORT,
7072eca0ae4aSLuiz Augusto von Dentz 		     hci_le_big_info_adv_report_evt,
7073eca0ae4aSLuiz Augusto von Dentz 		     sizeof(struct hci_evt_le_big_info_adv_report),
7074eca0ae4aSLuiz Augusto von Dentz 		     HCI_MAX_EVENT_SIZE),
707595118dd4SLuiz Augusto von Dentz };
707695118dd4SLuiz Augusto von Dentz 
hci_le_meta_evt(struct hci_dev * hdev,void * data,struct sk_buff * skb,u16 * opcode,u8 * status,hci_req_complete_t * req_complete,hci_req_complete_skb_t * req_complete_skb)70773e54c589SLuiz Augusto von Dentz static void hci_le_meta_evt(struct hci_dev *hdev, void *data,
707885b56857SLuiz Augusto von Dentz 			    struct sk_buff *skb, u16 *opcode, u8 *status,
707985b56857SLuiz Augusto von Dentz 			    hci_req_complete_t *req_complete,
708085b56857SLuiz Augusto von Dentz 			    hci_req_complete_skb_t *req_complete_skb)
7081fcd89c09SVille Tervo {
70823e54c589SLuiz Augusto von Dentz 	struct hci_ev_le_meta *ev = data;
708395118dd4SLuiz Augusto von Dentz 	const struct hci_le_ev *subev;
7084fcd89c09SVille Tervo 
708595118dd4SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "subevent 0x%2.2x", ev->subevent);
7086fcd89c09SVille Tervo 
708785b56857SLuiz Augusto von Dentz 	/* Only match event if command OGF is for LE */
70882af7aa66SLuiz Augusto von Dentz 	if (hdev->req_skb &&
70892af7aa66SLuiz Augusto von Dentz 	    hci_opcode_ogf(hci_skb_opcode(hdev->req_skb)) == 0x08 &&
70902af7aa66SLuiz Augusto von Dentz 	    hci_skb_event(hdev->req_skb) == ev->subevent) {
70912af7aa66SLuiz Augusto von Dentz 		*opcode = hci_skb_opcode(hdev->req_skb);
709285b56857SLuiz Augusto von Dentz 		hci_req_cmd_complete(hdev, *opcode, 0x00, req_complete,
709385b56857SLuiz Augusto von Dentz 				     req_complete_skb);
709485b56857SLuiz Augusto von Dentz 	}
709585b56857SLuiz Augusto von Dentz 
709695118dd4SLuiz Augusto von Dentz 	subev = &hci_le_ev_table[ev->subevent];
709795118dd4SLuiz Augusto von Dentz 	if (!subev->func)
709895118dd4SLuiz Augusto von Dentz 		return;
70991855d92dSMarcel Holtmann 
710095118dd4SLuiz Augusto von Dentz 	if (skb->len < subev->min_len) {
710195118dd4SLuiz Augusto von Dentz 		bt_dev_err(hdev, "unexpected subevent 0x%2.2x length: %u < %u",
710295118dd4SLuiz Augusto von Dentz 			   ev->subevent, skb->len, subev->min_len);
710395118dd4SLuiz Augusto von Dentz 		return;
7104fcd89c09SVille Tervo 	}
710595118dd4SLuiz Augusto von Dentz 
710695118dd4SLuiz Augusto von Dentz 	/* Just warn if the length is over max_len size it still be
710795118dd4SLuiz Augusto von Dentz 	 * possible to partially parse the event so leave to callback to
710895118dd4SLuiz Augusto von Dentz 	 * decide if that is acceptable.
710995118dd4SLuiz Augusto von Dentz 	 */
711095118dd4SLuiz Augusto von Dentz 	if (skb->len > subev->max_len)
711195118dd4SLuiz Augusto von Dentz 		bt_dev_warn(hdev, "unexpected subevent 0x%2.2x length: %u > %u",
711295118dd4SLuiz Augusto von Dentz 			    ev->subevent, skb->len, subev->max_len);
711395118dd4SLuiz Augusto von Dentz 	data = hci_le_ev_skb_pull(hdev, skb, ev->subevent, subev->min_len);
711495118dd4SLuiz Augusto von Dentz 	if (!data)
711595118dd4SLuiz Augusto von Dentz 		return;
711695118dd4SLuiz Augusto von Dentz 
711795118dd4SLuiz Augusto von Dentz 	subev->func(hdev, data, skb);
7118fcd89c09SVille Tervo }
7119fcd89c09SVille Tervo 
hci_get_cmd_complete(struct hci_dev * hdev,u16 opcode,u8 event,struct sk_buff * skb)7120757aa0b5SJohan Hedberg static bool hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode,
7121757aa0b5SJohan Hedberg 				 u8 event, struct sk_buff *skb)
7122757aa0b5SJohan Hedberg {
7123757aa0b5SJohan Hedberg 	struct hci_ev_cmd_complete *ev;
7124757aa0b5SJohan Hedberg 	struct hci_event_hdr *hdr;
7125757aa0b5SJohan Hedberg 
7126757aa0b5SJohan Hedberg 	if (!skb)
7127757aa0b5SJohan Hedberg 		return false;
7128757aa0b5SJohan Hedberg 
7129e3f3a1aeSLuiz Augusto von Dentz 	hdr = hci_ev_skb_pull(hdev, skb, event, sizeof(*hdr));
7130e3f3a1aeSLuiz Augusto von Dentz 	if (!hdr)
7131757aa0b5SJohan Hedberg 		return false;
7132757aa0b5SJohan Hedberg 
7133757aa0b5SJohan Hedberg 	if (event) {
7134757aa0b5SJohan Hedberg 		if (hdr->evt != event)
7135757aa0b5SJohan Hedberg 			return false;
7136757aa0b5SJohan Hedberg 		return true;
7137757aa0b5SJohan Hedberg 	}
7138757aa0b5SJohan Hedberg 
713991641b79SZheng Yongjun 	/* Check if request ended in Command Status - no way to retrieve
71401629db9cSJohan Hedberg 	 * any extra parameters in this case.
71411629db9cSJohan Hedberg 	 */
71421629db9cSJohan Hedberg 	if (hdr->evt == HCI_EV_CMD_STATUS)
71431629db9cSJohan Hedberg 		return false;
71441629db9cSJohan Hedberg 
7145757aa0b5SJohan Hedberg 	if (hdr->evt != HCI_EV_CMD_COMPLETE) {
71462064ee33SMarcel Holtmann 		bt_dev_err(hdev, "last event is not cmd complete (0x%2.2x)",
71472064ee33SMarcel Holtmann 			   hdr->evt);
7148757aa0b5SJohan Hedberg 		return false;
7149757aa0b5SJohan Hedberg 	}
7150757aa0b5SJohan Hedberg 
7151e3f3a1aeSLuiz Augusto von Dentz 	ev = hci_cc_skb_pull(hdev, skb, opcode, sizeof(*ev));
7152e3f3a1aeSLuiz Augusto von Dentz 	if (!ev)
7153757aa0b5SJohan Hedberg 		return false;
7154757aa0b5SJohan Hedberg 
7155757aa0b5SJohan Hedberg 	if (opcode != __le16_to_cpu(ev->opcode)) {
7156757aa0b5SJohan Hedberg 		BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode,
7157757aa0b5SJohan Hedberg 		       __le16_to_cpu(ev->opcode));
7158757aa0b5SJohan Hedberg 		return false;
7159757aa0b5SJohan Hedberg 	}
7160757aa0b5SJohan Hedberg 
7161757aa0b5SJohan Hedberg 	return true;
7162757aa0b5SJohan Hedberg }
7163757aa0b5SJohan Hedberg 
hci_store_wake_reason(struct hci_dev * hdev,u8 event,struct sk_buff * skb)71642f20216cSAbhishek Pandit-Subedi static void hci_store_wake_reason(struct hci_dev *hdev, u8 event,
71652f20216cSAbhishek Pandit-Subedi 				  struct sk_buff *skb)
71662f20216cSAbhishek Pandit-Subedi {
71672f20216cSAbhishek Pandit-Subedi 	struct hci_ev_le_advertising_info *adv;
71682f20216cSAbhishek Pandit-Subedi 	struct hci_ev_le_direct_adv_info *direct_adv;
7169b48b833fSLuiz Augusto von Dentz 	struct hci_ev_le_ext_adv_info *ext_adv;
71702f20216cSAbhishek Pandit-Subedi 	const struct hci_ev_conn_complete *conn_complete = (void *)skb->data;
71712f20216cSAbhishek Pandit-Subedi 	const struct hci_ev_conn_request *conn_request = (void *)skb->data;
71722f20216cSAbhishek Pandit-Subedi 
71732f20216cSAbhishek Pandit-Subedi 	hci_dev_lock(hdev);
71742f20216cSAbhishek Pandit-Subedi 
71752f20216cSAbhishek Pandit-Subedi 	/* If we are currently suspended and this is the first BT event seen,
71762f20216cSAbhishek Pandit-Subedi 	 * save the wake reason associated with the event.
71772f20216cSAbhishek Pandit-Subedi 	 */
71782f20216cSAbhishek Pandit-Subedi 	if (!hdev->suspended || hdev->wake_reason)
71792f20216cSAbhishek Pandit-Subedi 		goto unlock;
71802f20216cSAbhishek Pandit-Subedi 
71812f20216cSAbhishek Pandit-Subedi 	/* Default to remote wake. Values for wake_reason are documented in the
71822f20216cSAbhishek Pandit-Subedi 	 * Bluez mgmt api docs.
71832f20216cSAbhishek Pandit-Subedi 	 */
71842f20216cSAbhishek Pandit-Subedi 	hdev->wake_reason = MGMT_WAKE_REASON_REMOTE_WAKE;
71852f20216cSAbhishek Pandit-Subedi 
71862f20216cSAbhishek Pandit-Subedi 	/* Once configured for remote wakeup, we should only wake up for
71872f20216cSAbhishek Pandit-Subedi 	 * reconnections. It's useful to see which device is waking us up so
71882f20216cSAbhishek Pandit-Subedi 	 * keep track of the bdaddr of the connection event that woke us up.
71892f20216cSAbhishek Pandit-Subedi 	 */
71902f20216cSAbhishek Pandit-Subedi 	if (event == HCI_EV_CONN_REQUEST) {
71914a913967SZijun Hu 		bacpy(&hdev->wake_addr, &conn_request->bdaddr);
71922f20216cSAbhishek Pandit-Subedi 		hdev->wake_addr_type = BDADDR_BREDR;
71932f20216cSAbhishek Pandit-Subedi 	} else if (event == HCI_EV_CONN_COMPLETE) {
71944a913967SZijun Hu 		bacpy(&hdev->wake_addr, &conn_complete->bdaddr);
71952f20216cSAbhishek Pandit-Subedi 		hdev->wake_addr_type = BDADDR_BREDR;
71962f20216cSAbhishek Pandit-Subedi 	} else if (event == HCI_EV_LE_META) {
71972f20216cSAbhishek Pandit-Subedi 		struct hci_ev_le_meta *le_ev = (void *)skb->data;
71982f20216cSAbhishek Pandit-Subedi 		u8 subevent = le_ev->subevent;
71992f20216cSAbhishek Pandit-Subedi 		u8 *ptr = &skb->data[sizeof(*le_ev)];
72002f20216cSAbhishek Pandit-Subedi 		u8 num_reports = *ptr;
72012f20216cSAbhishek Pandit-Subedi 
72022f20216cSAbhishek Pandit-Subedi 		if ((subevent == HCI_EV_LE_ADVERTISING_REPORT ||
72032f20216cSAbhishek Pandit-Subedi 		     subevent == HCI_EV_LE_DIRECT_ADV_REPORT ||
72042f20216cSAbhishek Pandit-Subedi 		     subevent == HCI_EV_LE_EXT_ADV_REPORT) &&
72052f20216cSAbhishek Pandit-Subedi 		    num_reports) {
72062f20216cSAbhishek Pandit-Subedi 			adv = (void *)(ptr + 1);
72072f20216cSAbhishek Pandit-Subedi 			direct_adv = (void *)(ptr + 1);
72082f20216cSAbhishek Pandit-Subedi 			ext_adv = (void *)(ptr + 1);
72092f20216cSAbhishek Pandit-Subedi 
72102f20216cSAbhishek Pandit-Subedi 			switch (subevent) {
72112f20216cSAbhishek Pandit-Subedi 			case HCI_EV_LE_ADVERTISING_REPORT:
72122f20216cSAbhishek Pandit-Subedi 				bacpy(&hdev->wake_addr, &adv->bdaddr);
72132f20216cSAbhishek Pandit-Subedi 				hdev->wake_addr_type = adv->bdaddr_type;
72142f20216cSAbhishek Pandit-Subedi 				break;
72152f20216cSAbhishek Pandit-Subedi 			case HCI_EV_LE_DIRECT_ADV_REPORT:
72162f20216cSAbhishek Pandit-Subedi 				bacpy(&hdev->wake_addr, &direct_adv->bdaddr);
72172f20216cSAbhishek Pandit-Subedi 				hdev->wake_addr_type = direct_adv->bdaddr_type;
72182f20216cSAbhishek Pandit-Subedi 				break;
72192f20216cSAbhishek Pandit-Subedi 			case HCI_EV_LE_EXT_ADV_REPORT:
72202f20216cSAbhishek Pandit-Subedi 				bacpy(&hdev->wake_addr, &ext_adv->bdaddr);
72212f20216cSAbhishek Pandit-Subedi 				hdev->wake_addr_type = ext_adv->bdaddr_type;
72222f20216cSAbhishek Pandit-Subedi 				break;
72232f20216cSAbhishek Pandit-Subedi 			}
72242f20216cSAbhishek Pandit-Subedi 		}
72252f20216cSAbhishek Pandit-Subedi 	} else {
72262f20216cSAbhishek Pandit-Subedi 		hdev->wake_reason = MGMT_WAKE_REASON_UNEXPECTED;
72272f20216cSAbhishek Pandit-Subedi 	}
72282f20216cSAbhishek Pandit-Subedi 
72292f20216cSAbhishek Pandit-Subedi unlock:
72302f20216cSAbhishek Pandit-Subedi 	hci_dev_unlock(hdev);
72312f20216cSAbhishek Pandit-Subedi }
72322f20216cSAbhishek Pandit-Subedi 
72333e54c589SLuiz Augusto von Dentz #define HCI_EV_VL(_op, _func, _min_len, _max_len) \
72343e54c589SLuiz Augusto von Dentz [_op] = { \
72353e54c589SLuiz Augusto von Dentz 	.req = false, \
72363e54c589SLuiz Augusto von Dentz 	.func = _func, \
72373e54c589SLuiz Augusto von Dentz 	.min_len = _min_len, \
72383e54c589SLuiz Augusto von Dentz 	.max_len = _max_len, \
72393e54c589SLuiz Augusto von Dentz }
72403e54c589SLuiz Augusto von Dentz 
72413e54c589SLuiz Augusto von Dentz #define HCI_EV(_op, _func, _len) \
72423e54c589SLuiz Augusto von Dentz 	HCI_EV_VL(_op, _func, _len, _len)
72433e54c589SLuiz Augusto von Dentz 
72443e54c589SLuiz Augusto von Dentz #define HCI_EV_STATUS(_op, _func) \
72453e54c589SLuiz Augusto von Dentz 	HCI_EV(_op, _func, sizeof(struct hci_ev_status))
72463e54c589SLuiz Augusto von Dentz 
72473e54c589SLuiz Augusto von Dentz #define HCI_EV_REQ_VL(_op, _func, _min_len, _max_len) \
72483e54c589SLuiz Augusto von Dentz [_op] = { \
72493e54c589SLuiz Augusto von Dentz 	.req = true, \
72503e54c589SLuiz Augusto von Dentz 	.func_req = _func, \
72513e54c589SLuiz Augusto von Dentz 	.min_len = _min_len, \
72523e54c589SLuiz Augusto von Dentz 	.max_len = _max_len, \
72533e54c589SLuiz Augusto von Dentz }
72543e54c589SLuiz Augusto von Dentz 
72553e54c589SLuiz Augusto von Dentz #define HCI_EV_REQ(_op, _func, _len) \
72563e54c589SLuiz Augusto von Dentz 	HCI_EV_REQ_VL(_op, _func, _len, _len)
72573e54c589SLuiz Augusto von Dentz 
72583e54c589SLuiz Augusto von Dentz /* Entries in this table shall have their position according to the event opcode
72593e54c589SLuiz Augusto von Dentz  * they handle so the use of the macros above is recommend since it does attempt
72603e54c589SLuiz Augusto von Dentz  * to initialize at its proper index using Designated Initializers that way
72613e54c589SLuiz Augusto von Dentz  * events without a callback function don't have entered.
72623e54c589SLuiz Augusto von Dentz  */
72633e54c589SLuiz Augusto von Dentz static const struct hci_ev {
72643e54c589SLuiz Augusto von Dentz 	bool req;
72653e54c589SLuiz Augusto von Dentz 	union {
72663e54c589SLuiz Augusto von Dentz 		void (*func)(struct hci_dev *hdev, void *data,
72673e54c589SLuiz Augusto von Dentz 			     struct sk_buff *skb);
72683e54c589SLuiz Augusto von Dentz 		void (*func_req)(struct hci_dev *hdev, void *data,
72693e54c589SLuiz Augusto von Dentz 				 struct sk_buff *skb, u16 *opcode, u8 *status,
72703e54c589SLuiz Augusto von Dentz 				 hci_req_complete_t *req_complete,
72713e54c589SLuiz Augusto von Dentz 				 hci_req_complete_skb_t *req_complete_skb);
72723e54c589SLuiz Augusto von Dentz 	};
72733e54c589SLuiz Augusto von Dentz 	u16  min_len;
72743e54c589SLuiz Augusto von Dentz 	u16  max_len;
72753e54c589SLuiz Augusto von Dentz } hci_ev_table[U8_MAX + 1] = {
72763e54c589SLuiz Augusto von Dentz 	/* [0x01 = HCI_EV_INQUIRY_COMPLETE] */
72773e54c589SLuiz Augusto von Dentz 	HCI_EV_STATUS(HCI_EV_INQUIRY_COMPLETE, hci_inquiry_complete_evt),
72783e54c589SLuiz Augusto von Dentz 	/* [0x02 = HCI_EV_INQUIRY_RESULT] */
72793e54c589SLuiz Augusto von Dentz 	HCI_EV_VL(HCI_EV_INQUIRY_RESULT, hci_inquiry_result_evt,
72803e54c589SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_inquiry_result), HCI_MAX_EVENT_SIZE),
72813e54c589SLuiz Augusto von Dentz 	/* [0x03 = HCI_EV_CONN_COMPLETE] */
72823e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_CONN_COMPLETE, hci_conn_complete_evt,
72833e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_conn_complete)),
72843e54c589SLuiz Augusto von Dentz 	/* [0x04 = HCI_EV_CONN_REQUEST] */
72853e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_CONN_REQUEST, hci_conn_request_evt,
72863e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_conn_request)),
72873e54c589SLuiz Augusto von Dentz 	/* [0x05 = HCI_EV_DISCONN_COMPLETE] */
72883e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_DISCONN_COMPLETE, hci_disconn_complete_evt,
72893e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_disconn_complete)),
72903e54c589SLuiz Augusto von Dentz 	/* [0x06 = HCI_EV_AUTH_COMPLETE] */
72913e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_AUTH_COMPLETE, hci_auth_complete_evt,
72923e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_auth_complete)),
72933e54c589SLuiz Augusto von Dentz 	/* [0x07 = HCI_EV_REMOTE_NAME] */
72943e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_REMOTE_NAME, hci_remote_name_evt,
72953e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_remote_name)),
72963e54c589SLuiz Augusto von Dentz 	/* [0x08 = HCI_EV_ENCRYPT_CHANGE] */
72973e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_ENCRYPT_CHANGE, hci_encrypt_change_evt,
72983e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_encrypt_change)),
72993e54c589SLuiz Augusto von Dentz 	/* [0x09 = HCI_EV_CHANGE_LINK_KEY_COMPLETE] */
73003e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_CHANGE_LINK_KEY_COMPLETE,
73013e54c589SLuiz Augusto von Dentz 	       hci_change_link_key_complete_evt,
73023e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_change_link_key_complete)),
73033e54c589SLuiz Augusto von Dentz 	/* [0x0b = HCI_EV_REMOTE_FEATURES] */
73043e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_REMOTE_FEATURES, hci_remote_features_evt,
73053e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_remote_features)),
73063e54c589SLuiz Augusto von Dentz 	/* [0x0e = HCI_EV_CMD_COMPLETE] */
73073e54c589SLuiz Augusto von Dentz 	HCI_EV_REQ_VL(HCI_EV_CMD_COMPLETE, hci_cmd_complete_evt,
73083e54c589SLuiz Augusto von Dentz 		      sizeof(struct hci_ev_cmd_complete), HCI_MAX_EVENT_SIZE),
73093e54c589SLuiz Augusto von Dentz 	/* [0x0f = HCI_EV_CMD_STATUS] */
73103e54c589SLuiz Augusto von Dentz 	HCI_EV_REQ(HCI_EV_CMD_STATUS, hci_cmd_status_evt,
73113e54c589SLuiz Augusto von Dentz 		   sizeof(struct hci_ev_cmd_status)),
73123e54c589SLuiz Augusto von Dentz 	/* [0x10 = HCI_EV_CMD_STATUS] */
73133e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_HARDWARE_ERROR, hci_hardware_error_evt,
73143e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_hardware_error)),
73153e54c589SLuiz Augusto von Dentz 	/* [0x12 = HCI_EV_ROLE_CHANGE] */
73163e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_ROLE_CHANGE, hci_role_change_evt,
73173e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_role_change)),
73183e54c589SLuiz Augusto von Dentz 	/* [0x13 = HCI_EV_NUM_COMP_PKTS] */
73193e54c589SLuiz Augusto von Dentz 	HCI_EV_VL(HCI_EV_NUM_COMP_PKTS, hci_num_comp_pkts_evt,
73203e54c589SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_num_comp_pkts), HCI_MAX_EVENT_SIZE),
73213e54c589SLuiz Augusto von Dentz 	/* [0x14 = HCI_EV_MODE_CHANGE] */
73223e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_MODE_CHANGE, hci_mode_change_evt,
73233e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_mode_change)),
73243e54c589SLuiz Augusto von Dentz 	/* [0x16 = HCI_EV_PIN_CODE_REQ] */
73253e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_PIN_CODE_REQ, hci_pin_code_request_evt,
73263e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_pin_code_req)),
73273e54c589SLuiz Augusto von Dentz 	/* [0x17 = HCI_EV_LINK_KEY_REQ] */
73283e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_LINK_KEY_REQ, hci_link_key_request_evt,
73293e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_link_key_req)),
73303e54c589SLuiz Augusto von Dentz 	/* [0x18 = HCI_EV_LINK_KEY_NOTIFY] */
73313e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_LINK_KEY_NOTIFY, hci_link_key_notify_evt,
73323e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_link_key_notify)),
73333e54c589SLuiz Augusto von Dentz 	/* [0x1c = HCI_EV_CLOCK_OFFSET] */
73343e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_CLOCK_OFFSET, hci_clock_offset_evt,
73353e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_clock_offset)),
73363e54c589SLuiz Augusto von Dentz 	/* [0x1d = HCI_EV_PKT_TYPE_CHANGE] */
73373e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_PKT_TYPE_CHANGE, hci_pkt_type_change_evt,
73383e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_pkt_type_change)),
73393e54c589SLuiz Augusto von Dentz 	/* [0x20 = HCI_EV_PSCAN_REP_MODE] */
73403e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_PSCAN_REP_MODE, hci_pscan_rep_mode_evt,
73413e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_pscan_rep_mode)),
73423e54c589SLuiz Augusto von Dentz 	/* [0x22 = HCI_EV_INQUIRY_RESULT_WITH_RSSI] */
73433e54c589SLuiz Augusto von Dentz 	HCI_EV_VL(HCI_EV_INQUIRY_RESULT_WITH_RSSI,
73443e54c589SLuiz Augusto von Dentz 		  hci_inquiry_result_with_rssi_evt,
73453e54c589SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_inquiry_result_rssi),
73463e54c589SLuiz Augusto von Dentz 		  HCI_MAX_EVENT_SIZE),
73473e54c589SLuiz Augusto von Dentz 	/* [0x23 = HCI_EV_REMOTE_EXT_FEATURES] */
73483e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_REMOTE_EXT_FEATURES, hci_remote_ext_features_evt,
73493e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_remote_ext_features)),
73503e54c589SLuiz Augusto von Dentz 	/* [0x2c = HCI_EV_SYNC_CONN_COMPLETE] */
73513e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_SYNC_CONN_COMPLETE, hci_sync_conn_complete_evt,
73523e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_sync_conn_complete)),
73533e54c589SLuiz Augusto von Dentz 	/* [0x2d = HCI_EV_EXTENDED_INQUIRY_RESULT] */
73543e54c589SLuiz Augusto von Dentz 	HCI_EV_VL(HCI_EV_EXTENDED_INQUIRY_RESULT,
73553e54c589SLuiz Augusto von Dentz 		  hci_extended_inquiry_result_evt,
73563e54c589SLuiz Augusto von Dentz 		  sizeof(struct hci_ev_ext_inquiry_result), HCI_MAX_EVENT_SIZE),
73573e54c589SLuiz Augusto von Dentz 	/* [0x30 = HCI_EV_KEY_REFRESH_COMPLETE] */
73583e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_KEY_REFRESH_COMPLETE, hci_key_refresh_complete_evt,
73593e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_key_refresh_complete)),
73603e54c589SLuiz Augusto von Dentz 	/* [0x31 = HCI_EV_IO_CAPA_REQUEST] */
73613e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_IO_CAPA_REQUEST, hci_io_capa_request_evt,
73623e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_io_capa_request)),
73633e54c589SLuiz Augusto von Dentz 	/* [0x32 = HCI_EV_IO_CAPA_REPLY] */
73643e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_IO_CAPA_REPLY, hci_io_capa_reply_evt,
73653e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_io_capa_reply)),
73663e54c589SLuiz Augusto von Dentz 	/* [0x33 = HCI_EV_USER_CONFIRM_REQUEST] */
73673e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_USER_CONFIRM_REQUEST, hci_user_confirm_request_evt,
73683e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_user_confirm_req)),
73693e54c589SLuiz Augusto von Dentz 	/* [0x34 = HCI_EV_USER_PASSKEY_REQUEST] */
73703e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_USER_PASSKEY_REQUEST, hci_user_passkey_request_evt,
73713e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_user_passkey_req)),
73723e54c589SLuiz Augusto von Dentz 	/* [0x35 = HCI_EV_REMOTE_OOB_DATA_REQUEST] */
73733e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_REMOTE_OOB_DATA_REQUEST, hci_remote_oob_data_request_evt,
73743e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_remote_oob_data_request)),
73753e54c589SLuiz Augusto von Dentz 	/* [0x36 = HCI_EV_SIMPLE_PAIR_COMPLETE] */
73763e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_SIMPLE_PAIR_COMPLETE, hci_simple_pair_complete_evt,
73773e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_simple_pair_complete)),
73783e54c589SLuiz Augusto von Dentz 	/* [0x3b = HCI_EV_USER_PASSKEY_NOTIFY] */
73793e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_USER_PASSKEY_NOTIFY, hci_user_passkey_notify_evt,
73803e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_user_passkey_notify)),
73813e54c589SLuiz Augusto von Dentz 	/* [0x3c = HCI_EV_KEYPRESS_NOTIFY] */
73823e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_KEYPRESS_NOTIFY, hci_keypress_notify_evt,
73833e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_keypress_notify)),
73843e54c589SLuiz Augusto von Dentz 	/* [0x3d = HCI_EV_REMOTE_HOST_FEATURES] */
73853e54c589SLuiz Augusto von Dentz 	HCI_EV(HCI_EV_REMOTE_HOST_FEATURES, hci_remote_host_features_evt,
73863e54c589SLuiz Augusto von Dentz 	       sizeof(struct hci_ev_remote_host_features)),
73873e54c589SLuiz Augusto von Dentz 	/* [0x3e = HCI_EV_LE_META] */
738885b56857SLuiz Augusto von Dentz 	HCI_EV_REQ_VL(HCI_EV_LE_META, hci_le_meta_evt,
73893e54c589SLuiz Augusto von Dentz 		      sizeof(struct hci_ev_le_meta), HCI_MAX_EVENT_SIZE),
73903e54c589SLuiz Augusto von Dentz 	/* [0xff = HCI_EV_VENDOR] */
7391314d8cd2SLuiz Augusto von Dentz 	HCI_EV_VL(HCI_EV_VENDOR, msft_vendor_evt, 0, HCI_MAX_EVENT_SIZE),
73923e54c589SLuiz Augusto von Dentz };
73933e54c589SLuiz Augusto von Dentz 
hci_event_func(struct hci_dev * hdev,u8 event,struct sk_buff * skb,u16 * opcode,u8 * status,hci_req_complete_t * req_complete,hci_req_complete_skb_t * req_complete_skb)73943e54c589SLuiz Augusto von Dentz static void hci_event_func(struct hci_dev *hdev, u8 event, struct sk_buff *skb,
73953e54c589SLuiz Augusto von Dentz 			   u16 *opcode, u8 *status,
73963e54c589SLuiz Augusto von Dentz 			   hci_req_complete_t *req_complete,
73973e54c589SLuiz Augusto von Dentz 			   hci_req_complete_skb_t *req_complete_skb)
73983e54c589SLuiz Augusto von Dentz {
73993e54c589SLuiz Augusto von Dentz 	const struct hci_ev *ev = &hci_ev_table[event];
74003e54c589SLuiz Augusto von Dentz 	void *data;
74013e54c589SLuiz Augusto von Dentz 
74023e54c589SLuiz Augusto von Dentz 	if (!ev->func)
74033e54c589SLuiz Augusto von Dentz 		return;
74043e54c589SLuiz Augusto von Dentz 
74053e54c589SLuiz Augusto von Dentz 	if (skb->len < ev->min_len) {
74063e54c589SLuiz Augusto von Dentz 		bt_dev_err(hdev, "unexpected event 0x%2.2x length: %u < %u",
74073e54c589SLuiz Augusto von Dentz 			   event, skb->len, ev->min_len);
74083e54c589SLuiz Augusto von Dentz 		return;
74093e54c589SLuiz Augusto von Dentz 	}
74103e54c589SLuiz Augusto von Dentz 
74113e54c589SLuiz Augusto von Dentz 	/* Just warn if the length is over max_len size it still be
74123e54c589SLuiz Augusto von Dentz 	 * possible to partially parse the event so leave to callback to
74133e54c589SLuiz Augusto von Dentz 	 * decide if that is acceptable.
74143e54c589SLuiz Augusto von Dentz 	 */
74153e54c589SLuiz Augusto von Dentz 	if (skb->len > ev->max_len)
7416314d8cd2SLuiz Augusto von Dentz 		bt_dev_warn_ratelimited(hdev,
7417314d8cd2SLuiz Augusto von Dentz 					"unexpected event 0x%2.2x length: %u > %u",
74183e54c589SLuiz Augusto von Dentz 					event, skb->len, ev->max_len);
74193e54c589SLuiz Augusto von Dentz 
74203e54c589SLuiz Augusto von Dentz 	data = hci_ev_skb_pull(hdev, skb, event, ev->min_len);
74213e54c589SLuiz Augusto von Dentz 	if (!data)
74223e54c589SLuiz Augusto von Dentz 		return;
74233e54c589SLuiz Augusto von Dentz 
74243e54c589SLuiz Augusto von Dentz 	if (ev->req)
74253e54c589SLuiz Augusto von Dentz 		ev->func_req(hdev, data, skb, opcode, status, req_complete,
74263e54c589SLuiz Augusto von Dentz 			     req_complete_skb);
74273e54c589SLuiz Augusto von Dentz 	else
74283e54c589SLuiz Augusto von Dentz 		ev->func(hdev, data, skb);
74293e54c589SLuiz Augusto von Dentz }
74303e54c589SLuiz Augusto von Dentz 
hci_event_packet(struct hci_dev * hdev,struct sk_buff * skb)74311da177e4SLinus Torvalds void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
74321da177e4SLinus Torvalds {
7433a9de9248SMarcel Holtmann 	struct hci_event_hdr *hdr = (void *) skb->data;
7434e6214487SJohan Hedberg 	hci_req_complete_t req_complete = NULL;
7435e6214487SJohan Hedberg 	hci_req_complete_skb_t req_complete_skb = NULL;
7436e6214487SJohan Hedberg 	struct sk_buff *orig_skb = NULL;
7437e3f3a1aeSLuiz Augusto von Dentz 	u8 status = 0, event, req_evt = 0;
7438e6214487SJohan Hedberg 	u16 opcode = HCI_OP_NOP;
74391da177e4SLinus Torvalds 
7440e3f3a1aeSLuiz Augusto von Dentz 	if (skb->len < sizeof(*hdr)) {
7441e3f3a1aeSLuiz Augusto von Dentz 		bt_dev_err(hdev, "Malformed HCI Event");
7442e3f3a1aeSLuiz Augusto von Dentz 		goto done;
7443e3f3a1aeSLuiz Augusto von Dentz 	}
7444e3f3a1aeSLuiz Augusto von Dentz 
7445dfe6d5c3SLuiz Augusto von Dentz 	kfree_skb(hdev->recv_event);
7446dfe6d5c3SLuiz Augusto von Dentz 	hdev->recv_event = skb_clone(skb, GFP_KERNEL);
7447dfe6d5c3SLuiz Augusto von Dentz 
7448e3f3a1aeSLuiz Augusto von Dentz 	event = hdr->evt;
744908bb4da9SAlain Michaud 	if (!event) {
74503e54c589SLuiz Augusto von Dentz 		bt_dev_warn(hdev, "Received unexpected HCI Event 0x%2.2x",
74513e54c589SLuiz Augusto von Dentz 			    event);
745208bb4da9SAlain Michaud 		goto done;
745308bb4da9SAlain Michaud 	}
745408bb4da9SAlain Michaud 
745585b56857SLuiz Augusto von Dentz 	/* Only match event if command OGF is not for LE */
74562af7aa66SLuiz Augusto von Dentz 	if (hdev->req_skb &&
74572af7aa66SLuiz Augusto von Dentz 	    hci_opcode_ogf(hci_skb_opcode(hdev->req_skb)) != 0x08 &&
74582af7aa66SLuiz Augusto von Dentz 	    hci_skb_event(hdev->req_skb) == event) {
74592af7aa66SLuiz Augusto von Dentz 		hci_req_cmd_complete(hdev, hci_skb_opcode(hdev->req_skb),
746085b56857SLuiz Augusto von Dentz 				     status, &req_complete, &req_complete_skb);
7461757aa0b5SJohan Hedberg 		req_evt = event;
746202350a72SJohan Hedberg 	}
746302350a72SJohan Hedberg 
7464e6214487SJohan Hedberg 	/* If it looks like we might end up having to call
7465e6214487SJohan Hedberg 	 * req_complete_skb, store a pristine copy of the skb since the
7466e6214487SJohan Hedberg 	 * various handlers may modify the original one through
7467e6214487SJohan Hedberg 	 * skb_pull() calls, etc.
7468e6214487SJohan Hedberg 	 */
7469e6214487SJohan Hedberg 	if (req_complete_skb || event == HCI_EV_CMD_STATUS ||
7470e6214487SJohan Hedberg 	    event == HCI_EV_CMD_COMPLETE)
7471e6214487SJohan Hedberg 		orig_skb = skb_clone(skb, GFP_KERNEL);
7472e6214487SJohan Hedberg 
7473e6214487SJohan Hedberg 	skb_pull(skb, HCI_EVENT_HDR_SIZE);
7474e6214487SJohan Hedberg 
74752f20216cSAbhishek Pandit-Subedi 	/* Store wake reason if we're suspended */
74762f20216cSAbhishek Pandit-Subedi 	hci_store_wake_reason(hdev, event, skb);
74772f20216cSAbhishek Pandit-Subedi 
74783e54c589SLuiz Augusto von Dentz 	bt_dev_dbg(hdev, "event 0x%2.2x", event);
74791da177e4SLinus Torvalds 
74803e54c589SLuiz Augusto von Dentz 	hci_event_func(hdev, event, skb, &opcode, &status, &req_complete,
7481e6214487SJohan Hedberg 		       &req_complete_skb);
74821da177e4SLinus Torvalds 
7483757aa0b5SJohan Hedberg 	if (req_complete) {
7484e6214487SJohan Hedberg 		req_complete(hdev, status, opcode);
7485757aa0b5SJohan Hedberg 	} else if (req_complete_skb) {
7486757aa0b5SJohan Hedberg 		if (!hci_get_cmd_complete(hdev, opcode, req_evt, orig_skb)) {
7487757aa0b5SJohan Hedberg 			kfree_skb(orig_skb);
7488757aa0b5SJohan Hedberg 			orig_skb = NULL;
7489757aa0b5SJohan Hedberg 		}
7490e6214487SJohan Hedberg 		req_complete_skb(hdev, status, opcode, orig_skb);
7491757aa0b5SJohan Hedberg 	}
7492e6214487SJohan Hedberg 
749308bb4da9SAlain Michaud done:
7494e6214487SJohan Hedberg 	kfree_skb(orig_skb);
74951da177e4SLinus Torvalds 	kfree_skb(skb);
74961da177e4SLinus Torvalds 	hdev->stat.evt_rx++;
74971da177e4SLinus Torvalds }
7498