xref: /openbmc/linux/net/bluetooth/hci_event.c (revision ca8bee5d)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds    BlueZ - Bluetooth protocol stack for Linux
32d0a0346SRon Shaffer    Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
41da177e4SLinus Torvalds 
51da177e4SLinus Torvalds    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
61da177e4SLinus Torvalds 
71da177e4SLinus Torvalds    This program is free software; you can redistribute it and/or modify
81da177e4SLinus Torvalds    it under the terms of the GNU General Public License version 2 as
91da177e4SLinus Torvalds    published by the Free Software Foundation;
101da177e4SLinus Torvalds 
111da177e4SLinus Torvalds    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
121da177e4SLinus Torvalds    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
131da177e4SLinus Torvalds    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
141da177e4SLinus Torvalds    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
151da177e4SLinus Torvalds    CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
161da177e4SLinus Torvalds    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
171da177e4SLinus Torvalds    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
181da177e4SLinus Torvalds    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
191da177e4SLinus Torvalds 
201da177e4SLinus Torvalds    ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
211da177e4SLinus Torvalds    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
221da177e4SLinus Torvalds    SOFTWARE IS DISCLAIMED.
231da177e4SLinus Torvalds */
241da177e4SLinus Torvalds 
251da177e4SLinus Torvalds /* Bluetooth HCI event handling. */
261da177e4SLinus Torvalds 
271da177e4SLinus Torvalds #include <asm/unaligned.h>
281da177e4SLinus Torvalds 
291da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
301da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
31f0d6a0eaSMikel Astiz #include <net/bluetooth/mgmt.h>
327ef9fbf0SMarcel Holtmann 
330857dd3bSJohan Hedberg #include "hci_request.h"
3423b9ceb7SMarcel Holtmann #include "hci_debugfs.h"
357024728eSMarcel Holtmann #include "a2mp.h"
367ef9fbf0SMarcel Holtmann #include "amp.h"
372ceba539SJohan Hedberg #include "smp.h"
381da177e4SLinus Torvalds 
39aa5b0345SMarcel Holtmann #define ZERO_KEY "\x00\x00\x00\x00\x00\x00\x00\x00" \
40aa5b0345SMarcel Holtmann 		 "\x00\x00\x00\x00\x00\x00\x00\x00"
41aa5b0345SMarcel Holtmann 
421da177e4SLinus Torvalds /* Handle HCI Event packets */
431da177e4SLinus Torvalds 
44a9de9248SMarcel Holtmann static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
451da177e4SLinus Torvalds {
46a9de9248SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
471da177e4SLinus Torvalds 
489f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
491da177e4SLinus Torvalds 
5082f4785cSAndre Guedes 	if (status)
51a9de9248SMarcel Holtmann 		return;
521da177e4SLinus Torvalds 
5389352e7dSAndre Guedes 	clear_bit(HCI_INQUIRY, &hdev->flags);
544e857c58SPeter Zijlstra 	smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */
553e13fa1eSAndre Guedes 	wake_up_bit(&hdev->flags, HCI_INQUIRY);
5689352e7dSAndre Guedes 
5750143a43SJohan Hedberg 	hci_dev_lock(hdev);
58168b8a25SJakub Pawlowski 	/* Set discovery state to stopped if we're not doing LE active
59168b8a25SJakub Pawlowski 	 * scanning.
60168b8a25SJakub Pawlowski 	 */
61168b8a25SJakub Pawlowski 	if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
62168b8a25SJakub Pawlowski 	    hdev->le_scan_type != LE_SCAN_ACTIVE)
6350143a43SJohan Hedberg 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
6450143a43SJohan Hedberg 	hci_dev_unlock(hdev);
6550143a43SJohan Hedberg 
66a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
671da177e4SLinus Torvalds }
686bd57416SMarcel Holtmann 
694d93483bSAndre Guedes static void hci_cc_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
704d93483bSAndre Guedes {
714d93483bSAndre Guedes 	__u8 status = *((__u8 *) skb->data);
724d93483bSAndre Guedes 
739f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
74ae854a70SAndre Guedes 
75ae854a70SAndre Guedes 	if (status)
76ae854a70SAndre Guedes 		return;
77ae854a70SAndre Guedes 
78a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_PERIODIC_INQ);
794d93483bSAndre Guedes }
804d93483bSAndre Guedes 
81a9de9248SMarcel Holtmann static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
821da177e4SLinus Torvalds {
83a9de9248SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
84a9de9248SMarcel Holtmann 
859f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
86a9de9248SMarcel Holtmann 
87a9de9248SMarcel Holtmann 	if (status)
88a9de9248SMarcel Holtmann 		return;
89a9de9248SMarcel Holtmann 
90a358dc11SMarcel Holtmann 	hci_dev_clear_flag(hdev, HCI_PERIODIC_INQ);
91ae854a70SAndre Guedes 
92a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
93a9de9248SMarcel Holtmann }
94a9de9248SMarcel Holtmann 
95807deac2SGustavo Padovan static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev,
96807deac2SGustavo Padovan 					  struct sk_buff *skb)
97a9de9248SMarcel Holtmann {
98a9de9248SMarcel Holtmann 	BT_DBG("%s", hdev->name);
99a9de9248SMarcel Holtmann }
100a9de9248SMarcel Holtmann 
101a9de9248SMarcel Holtmann static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
102a9de9248SMarcel Holtmann {
103a9de9248SMarcel Holtmann 	struct hci_rp_role_discovery *rp = (void *) skb->data;
1041da177e4SLinus Torvalds 	struct hci_conn *conn;
1051da177e4SLinus Torvalds 
1069f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1071da177e4SLinus Torvalds 
108a9de9248SMarcel Holtmann 	if (rp->status)
109a9de9248SMarcel Holtmann 		return;
1101da177e4SLinus Torvalds 
1111da177e4SLinus Torvalds 	hci_dev_lock(hdev);
1121da177e4SLinus Torvalds 
113a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
11440bef302SJohan Hedberg 	if (conn)
11540bef302SJohan Hedberg 		conn->role = rp->role;
1161da177e4SLinus Torvalds 
1171da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
118a9de9248SMarcel Holtmann }
1191da177e4SLinus Torvalds 
120e4e8e37cSMarcel Holtmann static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
121e4e8e37cSMarcel Holtmann {
122e4e8e37cSMarcel Holtmann 	struct hci_rp_read_link_policy *rp = (void *) skb->data;
123e4e8e37cSMarcel Holtmann 	struct hci_conn *conn;
124e4e8e37cSMarcel Holtmann 
1259f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
126e4e8e37cSMarcel Holtmann 
127e4e8e37cSMarcel Holtmann 	if (rp->status)
128e4e8e37cSMarcel Holtmann 		return;
129e4e8e37cSMarcel Holtmann 
130e4e8e37cSMarcel Holtmann 	hci_dev_lock(hdev);
131e4e8e37cSMarcel Holtmann 
132e4e8e37cSMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
133e4e8e37cSMarcel Holtmann 	if (conn)
134e4e8e37cSMarcel Holtmann 		conn->link_policy = __le16_to_cpu(rp->policy);
135e4e8e37cSMarcel Holtmann 
136e4e8e37cSMarcel Holtmann 	hci_dev_unlock(hdev);
137e4e8e37cSMarcel Holtmann }
138e4e8e37cSMarcel Holtmann 
139a9de9248SMarcel Holtmann static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
140a9de9248SMarcel Holtmann {
141a9de9248SMarcel Holtmann 	struct hci_rp_write_link_policy *rp = (void *) skb->data;
142a9de9248SMarcel Holtmann 	struct hci_conn *conn;
143a9de9248SMarcel Holtmann 	void *sent;
144a9de9248SMarcel Holtmann 
1459f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
146a9de9248SMarcel Holtmann 
147a9de9248SMarcel Holtmann 	if (rp->status)
148a9de9248SMarcel Holtmann 		return;
149a9de9248SMarcel Holtmann 
150a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
15104837f64SMarcel Holtmann 	if (!sent)
152a9de9248SMarcel Holtmann 		return;
15304837f64SMarcel Holtmann 
15404837f64SMarcel Holtmann 	hci_dev_lock(hdev);
15504837f64SMarcel Holtmann 
156a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
157e4e8e37cSMarcel Holtmann 	if (conn)
15883985319SHarvey Harrison 		conn->link_policy = get_unaligned_le16(sent + 2);
15904837f64SMarcel Holtmann 
16004837f64SMarcel Holtmann 	hci_dev_unlock(hdev);
1611da177e4SLinus Torvalds }
1621da177e4SLinus Torvalds 
163807deac2SGustavo Padovan static void hci_cc_read_def_link_policy(struct hci_dev *hdev,
164807deac2SGustavo Padovan 					struct sk_buff *skb)
165e4e8e37cSMarcel Holtmann {
166e4e8e37cSMarcel Holtmann 	struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
167e4e8e37cSMarcel Holtmann 
1689f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
169e4e8e37cSMarcel Holtmann 
170e4e8e37cSMarcel Holtmann 	if (rp->status)
171e4e8e37cSMarcel Holtmann 		return;
172e4e8e37cSMarcel Holtmann 
173e4e8e37cSMarcel Holtmann 	hdev->link_policy = __le16_to_cpu(rp->policy);
174e4e8e37cSMarcel Holtmann }
175e4e8e37cSMarcel Holtmann 
176807deac2SGustavo Padovan static void hci_cc_write_def_link_policy(struct hci_dev *hdev,
177807deac2SGustavo Padovan 					 struct sk_buff *skb)
178e4e8e37cSMarcel Holtmann {
179e4e8e37cSMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
180e4e8e37cSMarcel Holtmann 	void *sent;
181e4e8e37cSMarcel Holtmann 
1829f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
183e4e8e37cSMarcel Holtmann 
18445296acdSMarcel Holtmann 	if (status)
18545296acdSMarcel Holtmann 		return;
18645296acdSMarcel Holtmann 
187e4e8e37cSMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
188e4e8e37cSMarcel Holtmann 	if (!sent)
189e4e8e37cSMarcel Holtmann 		return;
190e4e8e37cSMarcel Holtmann 
191e4e8e37cSMarcel Holtmann 	hdev->link_policy = get_unaligned_le16(sent);
192e4e8e37cSMarcel Holtmann }
193e4e8e37cSMarcel Holtmann 
194a9de9248SMarcel Holtmann static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
1951da177e4SLinus Torvalds {
196a9de9248SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
197a9de9248SMarcel Holtmann 
1989f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
199a9de9248SMarcel Holtmann 
20010572132SGustavo F. Padovan 	clear_bit(HCI_RESET, &hdev->flags);
20110572132SGustavo F. Padovan 
2028761f9d6SMarcel Holtmann 	if (status)
2038761f9d6SMarcel Holtmann 		return;
2048761f9d6SMarcel Holtmann 
205a297e97cSJohan Hedberg 	/* Reset all non-persistent flags */
206eacb44dfSMarcel Holtmann 	hci_dev_clear_volatile_flags(hdev);
20769775ff6SAndre Guedes 
20839c5d970SJohan Hedberg 	hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
20939c5d970SJohan Hedberg 
210bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
211bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
2123f0f524bSJohan Hedberg 
2133f0f524bSJohan Hedberg 	memset(hdev->adv_data, 0, sizeof(hdev->adv_data));
2143f0f524bSJohan Hedberg 	hdev->adv_data_len = 0;
215f8e808bdSMarcel Holtmann 
216f8e808bdSMarcel Holtmann 	memset(hdev->scan_rsp_data, 0, sizeof(hdev->scan_rsp_data));
217f8e808bdSMarcel Holtmann 	hdev->scan_rsp_data_len = 0;
21806f5b778SMarcel Holtmann 
219533553f8SMarcel Holtmann 	hdev->le_scan_type = LE_SCAN_PASSIVE;
220533553f8SMarcel Holtmann 
22106f5b778SMarcel Holtmann 	hdev->ssp_debug_mode = 0;
222a4d5504dSMarcel Holtmann 
223a4d5504dSMarcel Holtmann 	hci_bdaddr_list_clear(&hdev->le_white_list);
224a9de9248SMarcel Holtmann }
225a9de9248SMarcel Holtmann 
226c2f0f979SMarcel Holtmann static void hci_cc_read_stored_link_key(struct hci_dev *hdev,
227c2f0f979SMarcel Holtmann 					struct sk_buff *skb)
228c2f0f979SMarcel Holtmann {
229c2f0f979SMarcel Holtmann 	struct hci_rp_read_stored_link_key *rp = (void *)skb->data;
230c2f0f979SMarcel Holtmann 	struct hci_cp_read_stored_link_key *sent;
231c2f0f979SMarcel Holtmann 
232c2f0f979SMarcel Holtmann 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
233c2f0f979SMarcel Holtmann 
234c2f0f979SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_READ_STORED_LINK_KEY);
235c2f0f979SMarcel Holtmann 	if (!sent)
236c2f0f979SMarcel Holtmann 		return;
237c2f0f979SMarcel Holtmann 
238c2f0f979SMarcel Holtmann 	if (!rp->status && sent->read_all == 0x01) {
239c2f0f979SMarcel Holtmann 		hdev->stored_max_keys = rp->max_keys;
240c2f0f979SMarcel Holtmann 		hdev->stored_num_keys = rp->num_keys;
241c2f0f979SMarcel Holtmann 	}
242c2f0f979SMarcel Holtmann }
243c2f0f979SMarcel Holtmann 
244a9366120SMarcel Holtmann static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
245a9366120SMarcel Holtmann 					  struct sk_buff *skb)
246a9366120SMarcel Holtmann {
247a9366120SMarcel Holtmann 	struct hci_rp_delete_stored_link_key *rp = (void *)skb->data;
248a9366120SMarcel Holtmann 
249a9366120SMarcel Holtmann 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
250a9366120SMarcel Holtmann 
251a9366120SMarcel Holtmann 	if (rp->status)
252a9366120SMarcel Holtmann 		return;
253a9366120SMarcel Holtmann 
254a9366120SMarcel Holtmann 	if (rp->num_keys <= hdev->stored_num_keys)
255a9366120SMarcel Holtmann 		hdev->stored_num_keys -= rp->num_keys;
256a9366120SMarcel Holtmann 	else
257a9366120SMarcel Holtmann 		hdev->stored_num_keys = 0;
258a9366120SMarcel Holtmann }
259a9366120SMarcel Holtmann 
260a9de9248SMarcel Holtmann static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
261a9de9248SMarcel Holtmann {
262a9de9248SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
2631da177e4SLinus Torvalds 	void *sent;
2641da177e4SLinus Torvalds 
2659f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
2661da177e4SLinus Torvalds 
267a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
2681da177e4SLinus Torvalds 	if (!sent)
269a9de9248SMarcel Holtmann 		return;
2701da177e4SLinus Torvalds 
27156e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
27256e5cb86SJohan Hedberg 
273d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
274f51d5b24SJohan Hedberg 		mgmt_set_local_name_complete(hdev, sent, status);
27528cc7bdeSJohan Hedberg 	else if (!status)
27628cc7bdeSJohan Hedberg 		memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
277f51d5b24SJohan Hedberg 
27856e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
279a9de9248SMarcel Holtmann }
280a9de9248SMarcel Holtmann 
281a9de9248SMarcel Holtmann static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
282a9de9248SMarcel Holtmann {
283a9de9248SMarcel Holtmann 	struct hci_rp_read_local_name *rp = (void *) skb->data;
284a9de9248SMarcel Holtmann 
2859f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
286a9de9248SMarcel Holtmann 
287a9de9248SMarcel Holtmann 	if (rp->status)
288a9de9248SMarcel Holtmann 		return;
289a9de9248SMarcel Holtmann 
290d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP) ||
291d7a5a11dSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_CONFIG))
2921f6c6378SJohan Hedberg 		memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
293a9de9248SMarcel Holtmann }
294a9de9248SMarcel Holtmann 
295a9de9248SMarcel Holtmann static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
296a9de9248SMarcel Holtmann {
297a9de9248SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
298a9de9248SMarcel Holtmann 	void *sent;
299a9de9248SMarcel Holtmann 
3009f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
301a9de9248SMarcel Holtmann 
302a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
303a9de9248SMarcel Holtmann 	if (!sent)
304a9de9248SMarcel Holtmann 		return;
3051da177e4SLinus Torvalds 
3065c1a4c8fSJaganath Kanakkassery 	hci_dev_lock(hdev);
3075c1a4c8fSJaganath Kanakkassery 
3081da177e4SLinus Torvalds 	if (!status) {
309a9de9248SMarcel Holtmann 		__u8 param = *((__u8 *) sent);
310a9de9248SMarcel Holtmann 
3111da177e4SLinus Torvalds 		if (param == AUTH_ENABLED)
3121da177e4SLinus Torvalds 			set_bit(HCI_AUTH, &hdev->flags);
3131da177e4SLinus Torvalds 		else
3141da177e4SLinus Torvalds 			clear_bit(HCI_AUTH, &hdev->flags);
3151da177e4SLinus Torvalds 	}
316a9de9248SMarcel Holtmann 
317d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
31833ef95edSJohan Hedberg 		mgmt_auth_enable_complete(hdev, status);
3195c1a4c8fSJaganath Kanakkassery 
3205c1a4c8fSJaganath Kanakkassery 	hci_dev_unlock(hdev);
321a9de9248SMarcel Holtmann }
3221da177e4SLinus Torvalds 
323a9de9248SMarcel Holtmann static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
324a9de9248SMarcel Holtmann {
325a9de9248SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
32645296acdSMarcel Holtmann 	__u8 param;
327a9de9248SMarcel Holtmann 	void *sent;
328a9de9248SMarcel Holtmann 
3299f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
330a9de9248SMarcel Holtmann 
33145296acdSMarcel Holtmann 	if (status)
33245296acdSMarcel Holtmann 		return;
33345296acdSMarcel Holtmann 
334a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
3351da177e4SLinus Torvalds 	if (!sent)
336a9de9248SMarcel Holtmann 		return;
3371da177e4SLinus Torvalds 
33845296acdSMarcel Holtmann 	param = *((__u8 *) sent);
339a9de9248SMarcel Holtmann 
3401da177e4SLinus Torvalds 	if (param)
3411da177e4SLinus Torvalds 		set_bit(HCI_ENCRYPT, &hdev->flags);
3421da177e4SLinus Torvalds 	else
3431da177e4SLinus Torvalds 		clear_bit(HCI_ENCRYPT, &hdev->flags);
3441da177e4SLinus Torvalds }
3451da177e4SLinus Torvalds 
346a9de9248SMarcel Holtmann static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
347a9de9248SMarcel Holtmann {
34845296acdSMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
34945296acdSMarcel Holtmann 	__u8 param;
350a9de9248SMarcel Holtmann 	void *sent;
3511da177e4SLinus Torvalds 
3529f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
353a9de9248SMarcel Holtmann 
354a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
3551da177e4SLinus Torvalds 	if (!sent)
356a9de9248SMarcel Holtmann 		return;
3571da177e4SLinus Torvalds 
35836f7fc7eSJohan Hedberg 	param = *((__u8 *) sent);
359a9de9248SMarcel Holtmann 
36056e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
36156e5cb86SJohan Hedberg 
362fa1bd918SMikel Astiz 	if (status) {
3632d7cee58SJohan Hedberg 		hdev->discov_timeout = 0;
3642d7cee58SJohan Hedberg 		goto done;
3652d7cee58SJohan Hedberg 	}
3662d7cee58SJohan Hedberg 
367bc6d2d04SJohan Hedberg 	if (param & SCAN_INQUIRY)
3681da177e4SLinus Torvalds 		set_bit(HCI_ISCAN, &hdev->flags);
369bc6d2d04SJohan Hedberg 	else
370bc6d2d04SJohan Hedberg 		clear_bit(HCI_ISCAN, &hdev->flags);
3711da177e4SLinus Torvalds 
372031547d8SJohan Hedberg 	if (param & SCAN_PAGE)
3731da177e4SLinus Torvalds 		set_bit(HCI_PSCAN, &hdev->flags);
374bc6d2d04SJohan Hedberg 	else
375204e3990SJohan Hedberg 		clear_bit(HCI_PSCAN, &hdev->flags);
376a9de9248SMarcel Holtmann 
37736f7fc7eSJohan Hedberg done:
37856e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
3791da177e4SLinus Torvalds }
3801da177e4SLinus Torvalds 
381a9de9248SMarcel Holtmann static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
382a9de9248SMarcel Holtmann {
383a9de9248SMarcel Holtmann 	struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
384a9de9248SMarcel Holtmann 
3859f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
386a9de9248SMarcel Holtmann 
387a9de9248SMarcel Holtmann 	if (rp->status)
388a9de9248SMarcel Holtmann 		return;
389a9de9248SMarcel Holtmann 
390a9de9248SMarcel Holtmann 	memcpy(hdev->dev_class, rp->dev_class, 3);
391a9de9248SMarcel Holtmann 
392a9de9248SMarcel Holtmann 	BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
393a9de9248SMarcel Holtmann 	       hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
394a9de9248SMarcel Holtmann }
395a9de9248SMarcel Holtmann 
396a9de9248SMarcel Holtmann static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
397a9de9248SMarcel Holtmann {
398a9de9248SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
399a9de9248SMarcel Holtmann 	void *sent;
400a9de9248SMarcel Holtmann 
4019f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
402a9de9248SMarcel Holtmann 
403a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
404a9de9248SMarcel Holtmann 	if (!sent)
405a9de9248SMarcel Holtmann 		return;
406a9de9248SMarcel Holtmann 
4077f9a903cSMarcel Holtmann 	hci_dev_lock(hdev);
4087f9a903cSMarcel Holtmann 
4097f9a903cSMarcel Holtmann 	if (status == 0)
410a9de9248SMarcel Holtmann 		memcpy(hdev->dev_class, sent, 3);
4117f9a903cSMarcel Holtmann 
412d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
4137f9a903cSMarcel Holtmann 		mgmt_set_class_of_dev_complete(hdev, sent, status);
4147f9a903cSMarcel Holtmann 
4157f9a903cSMarcel Holtmann 	hci_dev_unlock(hdev);
416a9de9248SMarcel Holtmann }
417a9de9248SMarcel Holtmann 
418a9de9248SMarcel Holtmann static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
419a9de9248SMarcel Holtmann {
420a9de9248SMarcel Holtmann 	struct hci_rp_read_voice_setting *rp = (void *) skb->data;
421a9de9248SMarcel Holtmann 	__u16 setting;
422a9de9248SMarcel Holtmann 
4239f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
424a9de9248SMarcel Holtmann 
425a9de9248SMarcel Holtmann 	if (rp->status)
426a9de9248SMarcel Holtmann 		return;
427a9de9248SMarcel Holtmann 
428a9de9248SMarcel Holtmann 	setting = __le16_to_cpu(rp->voice_setting);
429a9de9248SMarcel Holtmann 
430a9de9248SMarcel Holtmann 	if (hdev->voice_setting == setting)
431a9de9248SMarcel Holtmann 		return;
432a9de9248SMarcel Holtmann 
433a9de9248SMarcel Holtmann 	hdev->voice_setting = setting;
434a9de9248SMarcel Holtmann 
4359f1db00cSAndrei Emeltchenko 	BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
436a9de9248SMarcel Holtmann 
4373c54711cSGustavo F. Padovan 	if (hdev->notify)
438a9de9248SMarcel Holtmann 		hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
439a9de9248SMarcel Holtmann }
440a9de9248SMarcel Holtmann 
4418fc9ced3SGustavo Padovan static void hci_cc_write_voice_setting(struct hci_dev *hdev,
4428fc9ced3SGustavo Padovan 				       struct sk_buff *skb)
443a9de9248SMarcel Holtmann {
444a9de9248SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
445f383f275SMarcel Holtmann 	__u16 setting;
446a9de9248SMarcel Holtmann 	void *sent;
447a9de9248SMarcel Holtmann 
4489f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
449a9de9248SMarcel Holtmann 
450f383f275SMarcel Holtmann 	if (status)
451f383f275SMarcel Holtmann 		return;
452f383f275SMarcel Holtmann 
453a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
454a9de9248SMarcel Holtmann 	if (!sent)
455a9de9248SMarcel Holtmann 		return;
456a9de9248SMarcel Holtmann 
457f383f275SMarcel Holtmann 	setting = get_unaligned_le16(sent);
4581da177e4SLinus Torvalds 
459f383f275SMarcel Holtmann 	if (hdev->voice_setting == setting)
460f383f275SMarcel Holtmann 		return;
461f383f275SMarcel Holtmann 
4621da177e4SLinus Torvalds 	hdev->voice_setting = setting;
4631da177e4SLinus Torvalds 
4649f1db00cSAndrei Emeltchenko 	BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
4651da177e4SLinus Torvalds 
4663c54711cSGustavo F. Padovan 	if (hdev->notify)
4671da177e4SLinus Torvalds 		hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
4681da177e4SLinus Torvalds }
4691da177e4SLinus Torvalds 
470b4cb9fb2SMarcel Holtmann static void hci_cc_read_num_supported_iac(struct hci_dev *hdev,
471b4cb9fb2SMarcel Holtmann 					  struct sk_buff *skb)
472b4cb9fb2SMarcel Holtmann {
473b4cb9fb2SMarcel Holtmann 	struct hci_rp_read_num_supported_iac *rp = (void *) skb->data;
474b4cb9fb2SMarcel Holtmann 
475b4cb9fb2SMarcel Holtmann 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
476b4cb9fb2SMarcel Holtmann 
477b4cb9fb2SMarcel Holtmann 	if (rp->status)
478b4cb9fb2SMarcel Holtmann 		return;
479b4cb9fb2SMarcel Holtmann 
480b4cb9fb2SMarcel Holtmann 	hdev->num_iac = rp->num_iac;
481b4cb9fb2SMarcel Holtmann 
482b4cb9fb2SMarcel Holtmann 	BT_DBG("%s num iac %d", hdev->name, hdev->num_iac);
483b4cb9fb2SMarcel Holtmann }
484b4cb9fb2SMarcel Holtmann 
485333140b5SMarcel Holtmann static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
486333140b5SMarcel Holtmann {
487333140b5SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
4885ed8eb2fSJohan Hedberg 	struct hci_cp_write_ssp_mode *sent;
489333140b5SMarcel Holtmann 
4909f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
491333140b5SMarcel Holtmann 
492333140b5SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
493333140b5SMarcel Holtmann 	if (!sent)
494333140b5SMarcel Holtmann 		return;
495333140b5SMarcel Holtmann 
4965c1a4c8fSJaganath Kanakkassery 	hci_dev_lock(hdev);
4975c1a4c8fSJaganath Kanakkassery 
4985ed8eb2fSJohan Hedberg 	if (!status) {
4995ed8eb2fSJohan Hedberg 		if (sent->mode)
500cad718edSJohan Hedberg 			hdev->features[1][0] |= LMP_HOST_SSP;
5015ed8eb2fSJohan Hedberg 		else
502cad718edSJohan Hedberg 			hdev->features[1][0] &= ~LMP_HOST_SSP;
5035ed8eb2fSJohan Hedberg 	}
5045ed8eb2fSJohan Hedberg 
505d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
5065ed8eb2fSJohan Hedberg 		mgmt_ssp_enable_complete(hdev, sent->mode, status);
507c0ecddc2SJohan Hedberg 	else if (!status) {
5085ed8eb2fSJohan Hedberg 		if (sent->mode)
509a1536da2SMarcel Holtmann 			hci_dev_set_flag(hdev, HCI_SSP_ENABLED);
51084bde9d6SJohan Hedberg 		else
511a358dc11SMarcel Holtmann 			hci_dev_clear_flag(hdev, HCI_SSP_ENABLED);
512c0ecddc2SJohan Hedberg 	}
5135c1a4c8fSJaganath Kanakkassery 
5145c1a4c8fSJaganath Kanakkassery 	hci_dev_unlock(hdev);
515333140b5SMarcel Holtmann }
516333140b5SMarcel Holtmann 
517eac83dc6SMarcel Holtmann static void hci_cc_write_sc_support(struct hci_dev *hdev, struct sk_buff *skb)
518eac83dc6SMarcel Holtmann {
519eac83dc6SMarcel Holtmann 	u8 status = *((u8 *) skb->data);
520eac83dc6SMarcel Holtmann 	struct hci_cp_write_sc_support *sent;
521eac83dc6SMarcel Holtmann 
522eac83dc6SMarcel Holtmann 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
523eac83dc6SMarcel Holtmann 
524eac83dc6SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SC_SUPPORT);
525eac83dc6SMarcel Holtmann 	if (!sent)
526eac83dc6SMarcel Holtmann 		return;
527eac83dc6SMarcel Holtmann 
5285c1a4c8fSJaganath Kanakkassery 	hci_dev_lock(hdev);
5295c1a4c8fSJaganath Kanakkassery 
530eac83dc6SMarcel Holtmann 	if (!status) {
531eac83dc6SMarcel Holtmann 		if (sent->support)
532eac83dc6SMarcel Holtmann 			hdev->features[1][0] |= LMP_HOST_SC;
533eac83dc6SMarcel Holtmann 		else
534eac83dc6SMarcel Holtmann 			hdev->features[1][0] &= ~LMP_HOST_SC;
535eac83dc6SMarcel Holtmann 	}
536eac83dc6SMarcel Holtmann 
537d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT) && !status) {
538eac83dc6SMarcel Holtmann 		if (sent->support)
539a1536da2SMarcel Holtmann 			hci_dev_set_flag(hdev, HCI_SC_ENABLED);
540eac83dc6SMarcel Holtmann 		else
541a358dc11SMarcel Holtmann 			hci_dev_clear_flag(hdev, HCI_SC_ENABLED);
542eac83dc6SMarcel Holtmann 	}
5435c1a4c8fSJaganath Kanakkassery 
5445c1a4c8fSJaganath Kanakkassery 	hci_dev_unlock(hdev);
545eac83dc6SMarcel Holtmann }
546eac83dc6SMarcel Holtmann 
547a9de9248SMarcel Holtmann static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
548a9de9248SMarcel Holtmann {
549a9de9248SMarcel Holtmann 	struct hci_rp_read_local_version *rp = (void *) skb->data;
5501143e5a6SMarcel Holtmann 
5519f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
5521143e5a6SMarcel Holtmann 
553a9de9248SMarcel Holtmann 	if (rp->status)
55442c6b129SJohan Hedberg 		return;
5551143e5a6SMarcel Holtmann 
556d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP) ||
557d7a5a11dSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_CONFIG)) {
558a9de9248SMarcel Holtmann 		hdev->hci_ver = rp->hci_ver;
559e4e8e37cSMarcel Holtmann 		hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
560d5859e22SJohan Hedberg 		hdev->lmp_ver = rp->lmp_ver;
561e4e8e37cSMarcel Holtmann 		hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
562d5859e22SJohan Hedberg 		hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
5630d5551f5SMarcel Holtmann 	}
564d5859e22SJohan Hedberg }
565d5859e22SJohan Hedberg 
5668fc9ced3SGustavo Padovan static void hci_cc_read_local_commands(struct hci_dev *hdev,
5678fc9ced3SGustavo Padovan 				       struct sk_buff *skb)
568a9de9248SMarcel Holtmann {
569a9de9248SMarcel Holtmann 	struct hci_rp_read_local_commands *rp = (void *) skb->data;
570a9de9248SMarcel Holtmann 
5719f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
572a9de9248SMarcel Holtmann 
5736a070e6eSMarcel Holtmann 	if (rp->status)
5746a070e6eSMarcel Holtmann 		return;
5756a070e6eSMarcel Holtmann 
576d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP) ||
577d7a5a11dSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_CONFIG))
578a9de9248SMarcel Holtmann 		memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
579a9de9248SMarcel Holtmann }
580a9de9248SMarcel Holtmann 
5818fc9ced3SGustavo Padovan static void hci_cc_read_local_features(struct hci_dev *hdev,
5828fc9ced3SGustavo Padovan 				       struct sk_buff *skb)
583a9de9248SMarcel Holtmann {
584a9de9248SMarcel Holtmann 	struct hci_rp_read_local_features *rp = (void *) skb->data;
585a9de9248SMarcel Holtmann 
5869f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
587a9de9248SMarcel Holtmann 
588a9de9248SMarcel Holtmann 	if (rp->status)
589a9de9248SMarcel Holtmann 		return;
590a9de9248SMarcel Holtmann 
591a9de9248SMarcel Holtmann 	memcpy(hdev->features, rp->features, 8);
5921da177e4SLinus Torvalds 
5931da177e4SLinus Torvalds 	/* Adjust default settings according to features
5941da177e4SLinus Torvalds 	 * supported by device. */
595a9de9248SMarcel Holtmann 
596cad718edSJohan Hedberg 	if (hdev->features[0][0] & LMP_3SLOT)
5971da177e4SLinus Torvalds 		hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
5981da177e4SLinus Torvalds 
599cad718edSJohan Hedberg 	if (hdev->features[0][0] & LMP_5SLOT)
6001da177e4SLinus Torvalds 		hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
6011da177e4SLinus Torvalds 
602cad718edSJohan Hedberg 	if (hdev->features[0][1] & LMP_HV2) {
6031da177e4SLinus Torvalds 		hdev->pkt_type  |= (HCI_HV2);
6045b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_HV2);
6055b7f9909SMarcel Holtmann 	}
6061da177e4SLinus Torvalds 
607cad718edSJohan Hedberg 	if (hdev->features[0][1] & LMP_HV3) {
6081da177e4SLinus Torvalds 		hdev->pkt_type  |= (HCI_HV3);
6095b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_HV3);
6105b7f9909SMarcel Holtmann 	}
6115b7f9909SMarcel Holtmann 
61245db810fSAndre Guedes 	if (lmp_esco_capable(hdev))
6135b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_EV3);
6145b7f9909SMarcel Holtmann 
615cad718edSJohan Hedberg 	if (hdev->features[0][4] & LMP_EV4)
6165b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_EV4);
6175b7f9909SMarcel Holtmann 
618cad718edSJohan Hedberg 	if (hdev->features[0][4] & LMP_EV5)
6195b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_EV5);
6201da177e4SLinus Torvalds 
621cad718edSJohan Hedberg 	if (hdev->features[0][5] & LMP_EDR_ESCO_2M)
622efc7688bSMarcel Holtmann 		hdev->esco_type |= (ESCO_2EV3);
623efc7688bSMarcel Holtmann 
624cad718edSJohan Hedberg 	if (hdev->features[0][5] & LMP_EDR_ESCO_3M)
625efc7688bSMarcel Holtmann 		hdev->esco_type |= (ESCO_3EV3);
626efc7688bSMarcel Holtmann 
627cad718edSJohan Hedberg 	if (hdev->features[0][5] & LMP_EDR_3S_ESCO)
628efc7688bSMarcel Holtmann 		hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
6291da177e4SLinus Torvalds }
6301da177e4SLinus Torvalds 
631971e3a4bSAndre Guedes static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
632971e3a4bSAndre Guedes 					   struct sk_buff *skb)
633971e3a4bSAndre Guedes {
634971e3a4bSAndre Guedes 	struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
635971e3a4bSAndre Guedes 
6369f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
637971e3a4bSAndre Guedes 
638971e3a4bSAndre Guedes 	if (rp->status)
63942c6b129SJohan Hedberg 		return;
640971e3a4bSAndre Guedes 
64157af75a8SMarcel Holtmann 	if (hdev->max_page < rp->max_page)
642d2c5d77fSJohan Hedberg 		hdev->max_page = rp->max_page;
643d2c5d77fSJohan Hedberg 
644cad718edSJohan Hedberg 	if (rp->page < HCI_MAX_PAGES)
645cad718edSJohan Hedberg 		memcpy(hdev->features[rp->page], rp->features, 8);
646971e3a4bSAndre Guedes }
647971e3a4bSAndre Guedes 
6481e89cffbSAndrei Emeltchenko static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
6491e89cffbSAndrei Emeltchenko 					  struct sk_buff *skb)
6501e89cffbSAndrei Emeltchenko {
6511e89cffbSAndrei Emeltchenko 	struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
6521e89cffbSAndrei Emeltchenko 
6539f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
6541e89cffbSAndrei Emeltchenko 
65545296acdSMarcel Holtmann 	if (rp->status)
65645296acdSMarcel Holtmann 		return;
65745296acdSMarcel Holtmann 
6581e89cffbSAndrei Emeltchenko 	hdev->flow_ctl_mode = rp->mode;
6591e89cffbSAndrei Emeltchenko }
6601e89cffbSAndrei Emeltchenko 
661a9de9248SMarcel Holtmann static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
662a9de9248SMarcel Holtmann {
663a9de9248SMarcel Holtmann 	struct hci_rp_read_buffer_size *rp = (void *) skb->data;
664a9de9248SMarcel Holtmann 
6659f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
666a9de9248SMarcel Holtmann 
667a9de9248SMarcel Holtmann 	if (rp->status)
668a9de9248SMarcel Holtmann 		return;
669a9de9248SMarcel Holtmann 
670a9de9248SMarcel Holtmann 	hdev->acl_mtu  = __le16_to_cpu(rp->acl_mtu);
671a9de9248SMarcel Holtmann 	hdev->sco_mtu  = rp->sco_mtu;
672a9de9248SMarcel Holtmann 	hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
673a9de9248SMarcel Holtmann 	hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
674da1f5198SMarcel Holtmann 
675da1f5198SMarcel Holtmann 	if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
676da1f5198SMarcel Holtmann 		hdev->sco_mtu  = 64;
677da1f5198SMarcel Holtmann 		hdev->sco_pkts = 8;
678da1f5198SMarcel Holtmann 	}
679da1f5198SMarcel Holtmann 
680da1f5198SMarcel Holtmann 	hdev->acl_cnt = hdev->acl_pkts;
681da1f5198SMarcel Holtmann 	hdev->sco_cnt = hdev->sco_pkts;
6821da177e4SLinus Torvalds 
683807deac2SGustavo Padovan 	BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
684807deac2SGustavo Padovan 	       hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
6851da177e4SLinus Torvalds }
6861da177e4SLinus Torvalds 
687a9de9248SMarcel Holtmann static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
688a9de9248SMarcel Holtmann {
689a9de9248SMarcel Holtmann 	struct hci_rp_read_bd_addr *rp = (void *) skb->data;
6901da177e4SLinus Torvalds 
6919f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
692a9de9248SMarcel Holtmann 
693e30d3f5fSMarcel Holtmann 	if (rp->status)
694e30d3f5fSMarcel Holtmann 		return;
695e30d3f5fSMarcel Holtmann 
696e30d3f5fSMarcel Holtmann 	if (test_bit(HCI_INIT, &hdev->flags))
697a9de9248SMarcel Holtmann 		bacpy(&hdev->bdaddr, &rp->bdaddr);
698e30d3f5fSMarcel Holtmann 
699d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP))
700e30d3f5fSMarcel Holtmann 		bacpy(&hdev->setup_addr, &rp->bdaddr);
70123bb5763SJohan Hedberg }
70223bb5763SJohan Hedberg 
703f332ec66SJohan Hedberg static void hci_cc_read_page_scan_activity(struct hci_dev *hdev,
704f332ec66SJohan Hedberg 					   struct sk_buff *skb)
705f332ec66SJohan Hedberg {
706f332ec66SJohan Hedberg 	struct hci_rp_read_page_scan_activity *rp = (void *) skb->data;
707f332ec66SJohan Hedberg 
708f332ec66SJohan Hedberg 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
709f332ec66SJohan Hedberg 
71045296acdSMarcel Holtmann 	if (rp->status)
71145296acdSMarcel Holtmann 		return;
71245296acdSMarcel Holtmann 
71345296acdSMarcel Holtmann 	if (test_bit(HCI_INIT, &hdev->flags)) {
714f332ec66SJohan Hedberg 		hdev->page_scan_interval = __le16_to_cpu(rp->interval);
715f332ec66SJohan Hedberg 		hdev->page_scan_window = __le16_to_cpu(rp->window);
716f332ec66SJohan Hedberg 	}
717f332ec66SJohan Hedberg }
718f332ec66SJohan Hedberg 
7194a3ee763SJohan Hedberg static void hci_cc_write_page_scan_activity(struct hci_dev *hdev,
7204a3ee763SJohan Hedberg 					    struct sk_buff *skb)
7214a3ee763SJohan Hedberg {
7224a3ee763SJohan Hedberg 	u8 status = *((u8 *) skb->data);
7234a3ee763SJohan Hedberg 	struct hci_cp_write_page_scan_activity *sent;
7244a3ee763SJohan Hedberg 
7254a3ee763SJohan Hedberg 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
7264a3ee763SJohan Hedberg 
7274a3ee763SJohan Hedberg 	if (status)
7284a3ee763SJohan Hedberg 		return;
7294a3ee763SJohan Hedberg 
7304a3ee763SJohan Hedberg 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY);
7314a3ee763SJohan Hedberg 	if (!sent)
7324a3ee763SJohan Hedberg 		return;
7334a3ee763SJohan Hedberg 
7344a3ee763SJohan Hedberg 	hdev->page_scan_interval = __le16_to_cpu(sent->interval);
7354a3ee763SJohan Hedberg 	hdev->page_scan_window = __le16_to_cpu(sent->window);
7364a3ee763SJohan Hedberg }
7374a3ee763SJohan Hedberg 
738f332ec66SJohan Hedberg static void hci_cc_read_page_scan_type(struct hci_dev *hdev,
739f332ec66SJohan Hedberg 					   struct sk_buff *skb)
740f332ec66SJohan Hedberg {
741f332ec66SJohan Hedberg 	struct hci_rp_read_page_scan_type *rp = (void *) skb->data;
742f332ec66SJohan Hedberg 
743f332ec66SJohan Hedberg 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
744f332ec66SJohan Hedberg 
74545296acdSMarcel Holtmann 	if (rp->status)
74645296acdSMarcel Holtmann 		return;
74745296acdSMarcel Holtmann 
74845296acdSMarcel Holtmann 	if (test_bit(HCI_INIT, &hdev->flags))
749f332ec66SJohan Hedberg 		hdev->page_scan_type = rp->type;
750f332ec66SJohan Hedberg }
751f332ec66SJohan Hedberg 
7524a3ee763SJohan Hedberg static void hci_cc_write_page_scan_type(struct hci_dev *hdev,
7534a3ee763SJohan Hedberg 					struct sk_buff *skb)
7544a3ee763SJohan Hedberg {
7554a3ee763SJohan Hedberg 	u8 status = *((u8 *) skb->data);
7564a3ee763SJohan Hedberg 	u8 *type;
7574a3ee763SJohan Hedberg 
7584a3ee763SJohan Hedberg 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
7594a3ee763SJohan Hedberg 
7604a3ee763SJohan Hedberg 	if (status)
7614a3ee763SJohan Hedberg 		return;
7624a3ee763SJohan Hedberg 
7634a3ee763SJohan Hedberg 	type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE);
7644a3ee763SJohan Hedberg 	if (type)
7654a3ee763SJohan Hedberg 		hdev->page_scan_type = *type;
7664a3ee763SJohan Hedberg }
7674a3ee763SJohan Hedberg 
768350ee4cfSAndrei Emeltchenko static void hci_cc_read_data_block_size(struct hci_dev *hdev,
769350ee4cfSAndrei Emeltchenko 					struct sk_buff *skb)
770350ee4cfSAndrei Emeltchenko {
771350ee4cfSAndrei Emeltchenko 	struct hci_rp_read_data_block_size *rp = (void *) skb->data;
772350ee4cfSAndrei Emeltchenko 
7739f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
774350ee4cfSAndrei Emeltchenko 
775350ee4cfSAndrei Emeltchenko 	if (rp->status)
776350ee4cfSAndrei Emeltchenko 		return;
777350ee4cfSAndrei Emeltchenko 
778350ee4cfSAndrei Emeltchenko 	hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
779350ee4cfSAndrei Emeltchenko 	hdev->block_len = __le16_to_cpu(rp->block_len);
780350ee4cfSAndrei Emeltchenko 	hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
781350ee4cfSAndrei Emeltchenko 
782350ee4cfSAndrei Emeltchenko 	hdev->block_cnt = hdev->num_blocks;
783350ee4cfSAndrei Emeltchenko 
784350ee4cfSAndrei Emeltchenko 	BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
785350ee4cfSAndrei Emeltchenko 	       hdev->block_cnt, hdev->block_len);
786350ee4cfSAndrei Emeltchenko }
787350ee4cfSAndrei Emeltchenko 
78833f35721SJohan Hedberg static void hci_cc_read_clock(struct hci_dev *hdev, struct sk_buff *skb)
78933f35721SJohan Hedberg {
79033f35721SJohan Hedberg 	struct hci_rp_read_clock *rp = (void *) skb->data;
79133f35721SJohan Hedberg 	struct hci_cp_read_clock *cp;
79233f35721SJohan Hedberg 	struct hci_conn *conn;
79333f35721SJohan Hedberg 
79433f35721SJohan Hedberg 	BT_DBG("%s", hdev->name);
79533f35721SJohan Hedberg 
79633f35721SJohan Hedberg 	if (skb->len < sizeof(*rp))
79733f35721SJohan Hedberg 		return;
79833f35721SJohan Hedberg 
79933f35721SJohan Hedberg 	if (rp->status)
80033f35721SJohan Hedberg 		return;
80133f35721SJohan Hedberg 
80233f35721SJohan Hedberg 	hci_dev_lock(hdev);
80333f35721SJohan Hedberg 
80433f35721SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_READ_CLOCK);
80533f35721SJohan Hedberg 	if (!cp)
80633f35721SJohan Hedberg 		goto unlock;
80733f35721SJohan Hedberg 
80833f35721SJohan Hedberg 	if (cp->which == 0x00) {
80933f35721SJohan Hedberg 		hdev->clock = le32_to_cpu(rp->clock);
81033f35721SJohan Hedberg 		goto unlock;
81133f35721SJohan Hedberg 	}
81233f35721SJohan Hedberg 
81333f35721SJohan Hedberg 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
81433f35721SJohan Hedberg 	if (conn) {
81533f35721SJohan Hedberg 		conn->clock = le32_to_cpu(rp->clock);
81633f35721SJohan Hedberg 		conn->clock_accuracy = le16_to_cpu(rp->accuracy);
81733f35721SJohan Hedberg 	}
81833f35721SJohan Hedberg 
81933f35721SJohan Hedberg unlock:
82033f35721SJohan Hedberg 	hci_dev_unlock(hdev);
82133f35721SJohan Hedberg }
82233f35721SJohan Hedberg 
823928abaa7SAndrei Emeltchenko static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
824928abaa7SAndrei Emeltchenko 				       struct sk_buff *skb)
825928abaa7SAndrei Emeltchenko {
826928abaa7SAndrei Emeltchenko 	struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
827928abaa7SAndrei Emeltchenko 
8289f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
829928abaa7SAndrei Emeltchenko 
830928abaa7SAndrei Emeltchenko 	if (rp->status)
83183927882SArron Wang 		return;
832928abaa7SAndrei Emeltchenko 
833928abaa7SAndrei Emeltchenko 	hdev->amp_status = rp->amp_status;
834928abaa7SAndrei Emeltchenko 	hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
835928abaa7SAndrei Emeltchenko 	hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
836928abaa7SAndrei Emeltchenko 	hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
837928abaa7SAndrei Emeltchenko 	hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
838928abaa7SAndrei Emeltchenko 	hdev->amp_type = rp->amp_type;
839928abaa7SAndrei Emeltchenko 	hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
840928abaa7SAndrei Emeltchenko 	hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
841928abaa7SAndrei Emeltchenko 	hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
842928abaa7SAndrei Emeltchenko 	hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
843928abaa7SAndrei Emeltchenko }
844928abaa7SAndrei Emeltchenko 
845d5859e22SJohan Hedberg static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
846d5859e22SJohan Hedberg 					 struct sk_buff *skb)
847d5859e22SJohan Hedberg {
84891c4e9b1SMarcel Holtmann 	struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data;
849d5859e22SJohan Hedberg 
8509f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
851d5859e22SJohan Hedberg 
85245296acdSMarcel Holtmann 	if (rp->status)
85345296acdSMarcel Holtmann 		return;
85445296acdSMarcel Holtmann 
85591c4e9b1SMarcel Holtmann 	hdev->inq_tx_power = rp->tx_power;
856d5859e22SJohan Hedberg }
857d5859e22SJohan Hedberg 
858980e1a53SJohan Hedberg static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
859980e1a53SJohan Hedberg {
860980e1a53SJohan Hedberg 	struct hci_rp_pin_code_reply *rp = (void *) skb->data;
861980e1a53SJohan Hedberg 	struct hci_cp_pin_code_reply *cp;
862980e1a53SJohan Hedberg 	struct hci_conn *conn;
863980e1a53SJohan Hedberg 
8649f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
865980e1a53SJohan Hedberg 
86656e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
86756e5cb86SJohan Hedberg 
868d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
869744cf19eSJohan Hedberg 		mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
870980e1a53SJohan Hedberg 
871fa1bd918SMikel Astiz 	if (rp->status)
87256e5cb86SJohan Hedberg 		goto unlock;
873980e1a53SJohan Hedberg 
874980e1a53SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
875980e1a53SJohan Hedberg 	if (!cp)
87656e5cb86SJohan Hedberg 		goto unlock;
877980e1a53SJohan Hedberg 
878980e1a53SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
879980e1a53SJohan Hedberg 	if (conn)
880980e1a53SJohan Hedberg 		conn->pin_length = cp->pin_len;
88156e5cb86SJohan Hedberg 
88256e5cb86SJohan Hedberg unlock:
88356e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
884980e1a53SJohan Hedberg }
885980e1a53SJohan Hedberg 
886980e1a53SJohan Hedberg static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
887980e1a53SJohan Hedberg {
888980e1a53SJohan Hedberg 	struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
889980e1a53SJohan Hedberg 
8909f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
891980e1a53SJohan Hedberg 
89256e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
89356e5cb86SJohan Hedberg 
894d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
895744cf19eSJohan Hedberg 		mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
896980e1a53SJohan Hedberg 						 rp->status);
89756e5cb86SJohan Hedberg 
89856e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
899980e1a53SJohan Hedberg }
90056e5cb86SJohan Hedberg 
9016ed58ec5SVille Tervo static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
9026ed58ec5SVille Tervo 				       struct sk_buff *skb)
9036ed58ec5SVille Tervo {
9046ed58ec5SVille Tervo 	struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
9056ed58ec5SVille Tervo 
9069f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
9076ed58ec5SVille Tervo 
9086ed58ec5SVille Tervo 	if (rp->status)
9096ed58ec5SVille Tervo 		return;
9106ed58ec5SVille Tervo 
9116ed58ec5SVille Tervo 	hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
9126ed58ec5SVille Tervo 	hdev->le_pkts = rp->le_max_pkt;
9136ed58ec5SVille Tervo 
9146ed58ec5SVille Tervo 	hdev->le_cnt = hdev->le_pkts;
9156ed58ec5SVille Tervo 
9166ed58ec5SVille Tervo 	BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
9176ed58ec5SVille Tervo }
918980e1a53SJohan Hedberg 
91960e77321SJohan Hedberg static void hci_cc_le_read_local_features(struct hci_dev *hdev,
92060e77321SJohan Hedberg 					  struct sk_buff *skb)
92160e77321SJohan Hedberg {
92260e77321SJohan Hedberg 	struct hci_rp_le_read_local_features *rp = (void *) skb->data;
92360e77321SJohan Hedberg 
92460e77321SJohan Hedberg 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
92560e77321SJohan Hedberg 
92645296acdSMarcel Holtmann 	if (rp->status)
92745296acdSMarcel Holtmann 		return;
92845296acdSMarcel Holtmann 
92960e77321SJohan Hedberg 	memcpy(hdev->le_features, rp->features, 8);
93060e77321SJohan Hedberg }
93160e77321SJohan Hedberg 
9328fa19098SJohan Hedberg static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
9338fa19098SJohan Hedberg 					struct sk_buff *skb)
9348fa19098SJohan Hedberg {
9358fa19098SJohan Hedberg 	struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data;
9368fa19098SJohan Hedberg 
9378fa19098SJohan Hedberg 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
9388fa19098SJohan Hedberg 
93945296acdSMarcel Holtmann 	if (rp->status)
94045296acdSMarcel Holtmann 		return;
94145296acdSMarcel Holtmann 
9428fa19098SJohan Hedberg 	hdev->adv_tx_power = rp->tx_power;
9438fa19098SJohan Hedberg }
9448fa19098SJohan Hedberg 
945a5c29683SJohan Hedberg static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
946a5c29683SJohan Hedberg {
947a5c29683SJohan Hedberg 	struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
948a5c29683SJohan Hedberg 
9499f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
950a5c29683SJohan Hedberg 
95156e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
95256e5cb86SJohan Hedberg 
953d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
95404124681SGustavo F. Padovan 		mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
95504124681SGustavo F. Padovan 						 rp->status);
95656e5cb86SJohan Hedberg 
95756e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
958a5c29683SJohan Hedberg }
959a5c29683SJohan Hedberg 
960a5c29683SJohan Hedberg static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
961a5c29683SJohan Hedberg 					  struct sk_buff *skb)
962a5c29683SJohan Hedberg {
963a5c29683SJohan Hedberg 	struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
964a5c29683SJohan Hedberg 
9659f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
966a5c29683SJohan Hedberg 
96756e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
96856e5cb86SJohan Hedberg 
969d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
970744cf19eSJohan Hedberg 		mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
97104124681SGustavo F. Padovan 						     ACL_LINK, 0, rp->status);
97256e5cb86SJohan Hedberg 
97356e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
974a5c29683SJohan Hedberg }
975a5c29683SJohan Hedberg 
9761143d458SBrian Gix static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
9771143d458SBrian Gix {
9781143d458SBrian Gix 	struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
9791143d458SBrian Gix 
9809f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
9811143d458SBrian Gix 
9821143d458SBrian Gix 	hci_dev_lock(hdev);
9831143d458SBrian Gix 
984d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
985272d90dfSJohan Hedberg 		mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
986272d90dfSJohan Hedberg 						 0, rp->status);
9871143d458SBrian Gix 
9881143d458SBrian Gix 	hci_dev_unlock(hdev);
9891143d458SBrian Gix }
9901143d458SBrian Gix 
9911143d458SBrian Gix static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
9921143d458SBrian Gix 					  struct sk_buff *skb)
9931143d458SBrian Gix {
9941143d458SBrian Gix 	struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
9951143d458SBrian Gix 
9969f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
9971143d458SBrian Gix 
9981143d458SBrian Gix 	hci_dev_lock(hdev);
9991143d458SBrian Gix 
1000d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
10011143d458SBrian Gix 		mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
100204124681SGustavo F. Padovan 						     ACL_LINK, 0, rp->status);
10031143d458SBrian Gix 
10041143d458SBrian Gix 	hci_dev_unlock(hdev);
10051143d458SBrian Gix }
10061143d458SBrian Gix 
10074d2d2796SMarcel Holtmann static void hci_cc_read_local_oob_data(struct hci_dev *hdev,
1008c35938b2SSzymon Janc 				       struct sk_buff *skb)
1009c35938b2SSzymon Janc {
1010c35938b2SSzymon Janc 	struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
1011c35938b2SSzymon Janc 
10129f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
10134d2d2796SMarcel Holtmann }
10144d2d2796SMarcel Holtmann 
10154d2d2796SMarcel Holtmann static void hci_cc_read_local_oob_ext_data(struct hci_dev *hdev,
10164d2d2796SMarcel Holtmann 					   struct sk_buff *skb)
10174d2d2796SMarcel Holtmann {
10184d2d2796SMarcel Holtmann 	struct hci_rp_read_local_oob_ext_data *rp = (void *) skb->data;
10194d2d2796SMarcel Holtmann 
10204d2d2796SMarcel Holtmann 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1021c35938b2SSzymon Janc }
1022c35938b2SSzymon Janc 
10237a4cd51dSMarcel Holtmann static void hci_cc_le_set_random_addr(struct hci_dev *hdev, struct sk_buff *skb)
10247a4cd51dSMarcel Holtmann {
10257a4cd51dSMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
10267a4cd51dSMarcel Holtmann 	bdaddr_t *sent;
10277a4cd51dSMarcel Holtmann 
10287a4cd51dSMarcel Holtmann 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
10297a4cd51dSMarcel Holtmann 
103045296acdSMarcel Holtmann 	if (status)
103145296acdSMarcel Holtmann 		return;
103245296acdSMarcel Holtmann 
10337a4cd51dSMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_RANDOM_ADDR);
10347a4cd51dSMarcel Holtmann 	if (!sent)
10357a4cd51dSMarcel Holtmann 		return;
10367a4cd51dSMarcel Holtmann 
10377a4cd51dSMarcel Holtmann 	hci_dev_lock(hdev);
10387a4cd51dSMarcel Holtmann 
10397a4cd51dSMarcel Holtmann 	bacpy(&hdev->random_addr, sent);
10407a4cd51dSMarcel Holtmann 
10417a4cd51dSMarcel Holtmann 	hci_dev_unlock(hdev);
10427a4cd51dSMarcel Holtmann }
10437a4cd51dSMarcel Holtmann 
1044c1d5dc4aSJohan Hedberg static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
1045c1d5dc4aSJohan Hedberg {
1046c1d5dc4aSJohan Hedberg 	__u8 *sent, status = *((__u8 *) skb->data);
1047c1d5dc4aSJohan Hedberg 
1048c1d5dc4aSJohan Hedberg 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1049c1d5dc4aSJohan Hedberg 
105045296acdSMarcel Holtmann 	if (status)
1051c1d5dc4aSJohan Hedberg 		return;
1052c1d5dc4aSJohan Hedberg 
105345296acdSMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
105445296acdSMarcel Holtmann 	if (!sent)
10553c857757SJohan Hedberg 		return;
10563c857757SJohan Hedberg 
1057c1d5dc4aSJohan Hedberg 	hci_dev_lock(hdev);
1058c1d5dc4aSJohan Hedberg 
105949c922bbSStephen Hemminger 	/* If we're doing connection initiation as peripheral. Set a
10603c857757SJohan Hedberg 	 * timeout in case something goes wrong.
10613c857757SJohan Hedberg 	 */
10623c857757SJohan Hedberg 	if (*sent) {
10633c857757SJohan Hedberg 		struct hci_conn *conn;
10643c857757SJohan Hedberg 
1065a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_LE_ADV);
106666c417c1SJohan Hedberg 
1067e7d9ab73SJakub Pawlowski 		conn = hci_lookup_le_connect(hdev);
10683c857757SJohan Hedberg 		if (conn)
10693c857757SJohan Hedberg 			queue_delayed_work(hdev->workqueue,
10703c857757SJohan Hedberg 					   &conn->le_conn_timeout,
107109ae260bSJohan Hedberg 					   conn->conn_timeout);
107266c417c1SJohan Hedberg 	} else {
1073a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LE_ADV);
10743c857757SJohan Hedberg 	}
10753c857757SJohan Hedberg 
107604b4edcbSJohan Hedberg 	hci_dev_unlock(hdev);
1077c1d5dc4aSJohan Hedberg }
1078c1d5dc4aSJohan Hedberg 
1079533553f8SMarcel Holtmann static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1080533553f8SMarcel Holtmann {
1081533553f8SMarcel Holtmann 	struct hci_cp_le_set_scan_param *cp;
1082533553f8SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
1083533553f8SMarcel Holtmann 
1084533553f8SMarcel Holtmann 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1085533553f8SMarcel Holtmann 
108645296acdSMarcel Holtmann 	if (status)
108745296acdSMarcel Holtmann 		return;
108845296acdSMarcel Holtmann 
1089533553f8SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_PARAM);
1090533553f8SMarcel Holtmann 	if (!cp)
1091533553f8SMarcel Holtmann 		return;
1092533553f8SMarcel Holtmann 
1093533553f8SMarcel Holtmann 	hci_dev_lock(hdev);
1094533553f8SMarcel Holtmann 
1095533553f8SMarcel Holtmann 	hdev->le_scan_type = cp->type;
1096533553f8SMarcel Holtmann 
1097533553f8SMarcel Holtmann 	hci_dev_unlock(hdev);
1098533553f8SMarcel Holtmann }
1099533553f8SMarcel Holtmann 
1100b9a6328fSJohan Hedberg static bool has_pending_adv_report(struct hci_dev *hdev)
1101b9a6328fSJohan Hedberg {
1102b9a6328fSJohan Hedberg 	struct discovery_state *d = &hdev->discovery;
1103b9a6328fSJohan Hedberg 
1104b9a6328fSJohan Hedberg 	return bacmp(&d->last_adv_addr, BDADDR_ANY);
1105b9a6328fSJohan Hedberg }
1106b9a6328fSJohan Hedberg 
1107b9a6328fSJohan Hedberg static void clear_pending_adv_report(struct hci_dev *hdev)
1108b9a6328fSJohan Hedberg {
1109b9a6328fSJohan Hedberg 	struct discovery_state *d = &hdev->discovery;
1110b9a6328fSJohan Hedberg 
1111b9a6328fSJohan Hedberg 	bacpy(&d->last_adv_addr, BDADDR_ANY);
1112b9a6328fSJohan Hedberg 	d->last_adv_data_len = 0;
1113b9a6328fSJohan Hedberg }
1114b9a6328fSJohan Hedberg 
1115b9a6328fSJohan Hedberg static void store_pending_adv_report(struct hci_dev *hdev, bdaddr_t *bdaddr,
1116c70a7e4cSMarcel Holtmann 				     u8 bdaddr_type, s8 rssi, u32 flags,
1117c70a7e4cSMarcel Holtmann 				     u8 *data, u8 len)
1118b9a6328fSJohan Hedberg {
1119b9a6328fSJohan Hedberg 	struct discovery_state *d = &hdev->discovery;
1120b9a6328fSJohan Hedberg 
1121b9a6328fSJohan Hedberg 	bacpy(&d->last_adv_addr, bdaddr);
1122b9a6328fSJohan Hedberg 	d->last_adv_addr_type = bdaddr_type;
1123ff5cd29fSJohan Hedberg 	d->last_adv_rssi = rssi;
1124c70a7e4cSMarcel Holtmann 	d->last_adv_flags = flags;
1125b9a6328fSJohan Hedberg 	memcpy(d->last_adv_data, data, len);
1126b9a6328fSJohan Hedberg 	d->last_adv_data_len = len;
1127b9a6328fSJohan Hedberg }
1128b9a6328fSJohan Hedberg 
1129eb9d91f5SAndre Guedes static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
1130eb9d91f5SAndre Guedes 				      struct sk_buff *skb)
1131eb9d91f5SAndre Guedes {
1132eb9d91f5SAndre Guedes 	struct hci_cp_le_set_scan_enable *cp;
1133eb9d91f5SAndre Guedes 	__u8 status = *((__u8 *) skb->data);
1134eb9d91f5SAndre Guedes 
11359f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1136eb9d91f5SAndre Guedes 
113745296acdSMarcel Holtmann 	if (status)
1138eb9d91f5SAndre Guedes 		return;
1139eb9d91f5SAndre Guedes 
114045296acdSMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
114145296acdSMarcel Holtmann 	if (!cp)
11427ba8b4beSAndre Guedes 		return;
11437ba8b4beSAndre Guedes 
11445c1a4c8fSJaganath Kanakkassery 	hci_dev_lock(hdev);
11455c1a4c8fSJaganath Kanakkassery 
11463fd319b8SAndre Guedes 	switch (cp->enable) {
11473fd319b8SAndre Guedes 	case LE_SCAN_ENABLE:
1148a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_LE_SCAN);
1149b9a6328fSJohan Hedberg 		if (hdev->le_scan_type == LE_SCAN_ACTIVE)
1150b9a6328fSJohan Hedberg 			clear_pending_adv_report(hdev);
115168a8aea4SAndrei Emeltchenko 		break;
115268a8aea4SAndrei Emeltchenko 
115376a388beSAndre Guedes 	case LE_SCAN_DISABLE:
1154b9a6328fSJohan Hedberg 		/* We do this here instead of when setting DISCOVERY_STOPPED
1155b9a6328fSJohan Hedberg 		 * since the latter would potentially require waiting for
1156b9a6328fSJohan Hedberg 		 * inquiry to stop too.
1157b9a6328fSJohan Hedberg 		 */
1158b9a6328fSJohan Hedberg 		if (has_pending_adv_report(hdev)) {
1159b9a6328fSJohan Hedberg 			struct discovery_state *d = &hdev->discovery;
1160b9a6328fSJohan Hedberg 
1161b9a6328fSJohan Hedberg 			mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
1162ab0aa433SJohan Hedberg 					  d->last_adv_addr_type, NULL,
1163c70a7e4cSMarcel Holtmann 					  d->last_adv_rssi, d->last_adv_flags,
1164ab0aa433SJohan Hedberg 					  d->last_adv_data,
1165b9a6328fSJohan Hedberg 					  d->last_adv_data_len, NULL, 0);
1166b9a6328fSJohan Hedberg 		}
1167b9a6328fSJohan Hedberg 
1168317ac8cbSJohan Hedberg 		/* Cancel this timer so that we don't try to disable scanning
1169317ac8cbSJohan Hedberg 		 * when it's already disabled.
1170317ac8cbSJohan Hedberg 		 */
1171317ac8cbSJohan Hedberg 		cancel_delayed_work(&hdev->le_scan_disable);
1172317ac8cbSJohan Hedberg 
1173a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LE_SCAN);
1174e8bb6b97SJohan Hedberg 
117581ad6fd9SJohan Hedberg 		/* The HCI_LE_SCAN_INTERRUPTED flag indicates that we
117681ad6fd9SJohan Hedberg 		 * interrupted scanning due to a connect request. Mark
1177e8bb6b97SJohan Hedberg 		 * therefore discovery as stopped. If this was not
1178e8bb6b97SJohan Hedberg 		 * because of a connect request advertising might have
1179e8bb6b97SJohan Hedberg 		 * been disabled because of active scanning, so
1180e8bb6b97SJohan Hedberg 		 * re-enable it again if necessary.
118181ad6fd9SJohan Hedberg 		 */
1182a69d8927SMarcel Holtmann 		if (hci_dev_test_and_clear_flag(hdev, HCI_LE_SCAN_INTERRUPTED))
118381ad6fd9SJohan Hedberg 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1184d7a5a11dSMarcel Holtmann 		else if (!hci_dev_test_flag(hdev, HCI_LE_ADV) &&
118534722277SJohan Hedberg 			 hdev->discovery.state == DISCOVERY_FINDING)
1186f2252570SJohan Hedberg 			hci_req_reenable_advertising(hdev);
1187e8bb6b97SJohan Hedberg 
118868a8aea4SAndrei Emeltchenko 		break;
118968a8aea4SAndrei Emeltchenko 
119068a8aea4SAndrei Emeltchenko 	default:
119168a8aea4SAndrei Emeltchenko 		BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
119268a8aea4SAndrei Emeltchenko 		break;
119335815085SAndre Guedes 	}
11945c1a4c8fSJaganath Kanakkassery 
11955c1a4c8fSJaganath Kanakkassery 	hci_dev_unlock(hdev);
1196eb9d91f5SAndre Guedes }
1197eb9d91f5SAndre Guedes 
1198cf1d081fSJohan Hedberg static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
1199cf1d081fSJohan Hedberg 					   struct sk_buff *skb)
1200cf1d081fSJohan Hedberg {
1201cf1d081fSJohan Hedberg 	struct hci_rp_le_read_white_list_size *rp = (void *) skb->data;
1202cf1d081fSJohan Hedberg 
1203cf1d081fSJohan Hedberg 	BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
1204cf1d081fSJohan Hedberg 
120545296acdSMarcel Holtmann 	if (rp->status)
120645296acdSMarcel Holtmann 		return;
120745296acdSMarcel Holtmann 
1208cf1d081fSJohan Hedberg 	hdev->le_white_list_size = rp->size;
1209cf1d081fSJohan Hedberg }
1210cf1d081fSJohan Hedberg 
12110f36b589SMarcel Holtmann static void hci_cc_le_clear_white_list(struct hci_dev *hdev,
12120f36b589SMarcel Holtmann 				       struct sk_buff *skb)
12130f36b589SMarcel Holtmann {
12140f36b589SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
12150f36b589SMarcel Holtmann 
12160f36b589SMarcel Holtmann 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
12170f36b589SMarcel Holtmann 
121845296acdSMarcel Holtmann 	if (status)
121945296acdSMarcel Holtmann 		return;
122045296acdSMarcel Holtmann 
1221dcc36c16SJohan Hedberg 	hci_bdaddr_list_clear(&hdev->le_white_list);
12220f36b589SMarcel Holtmann }
12230f36b589SMarcel Holtmann 
12240f36b589SMarcel Holtmann static void hci_cc_le_add_to_white_list(struct hci_dev *hdev,
12250f36b589SMarcel Holtmann 					struct sk_buff *skb)
12260f36b589SMarcel Holtmann {
12270f36b589SMarcel Holtmann 	struct hci_cp_le_add_to_white_list *sent;
12280f36b589SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
12290f36b589SMarcel Holtmann 
12300f36b589SMarcel Holtmann 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
12310f36b589SMarcel Holtmann 
123245296acdSMarcel Holtmann 	if (status)
123345296acdSMarcel Holtmann 		return;
123445296acdSMarcel Holtmann 
12350f36b589SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_WHITE_LIST);
12360f36b589SMarcel Holtmann 	if (!sent)
12370f36b589SMarcel Holtmann 		return;
12380f36b589SMarcel Holtmann 
1239dcc36c16SJohan Hedberg 	hci_bdaddr_list_add(&hdev->le_white_list, &sent->bdaddr,
1240dcc36c16SJohan Hedberg 			   sent->bdaddr_type);
12410f36b589SMarcel Holtmann }
12420f36b589SMarcel Holtmann 
12430f36b589SMarcel Holtmann static void hci_cc_le_del_from_white_list(struct hci_dev *hdev,
12440f36b589SMarcel Holtmann 					  struct sk_buff *skb)
12450f36b589SMarcel Holtmann {
12460f36b589SMarcel Holtmann 	struct hci_cp_le_del_from_white_list *sent;
12470f36b589SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
12480f36b589SMarcel Holtmann 
12490f36b589SMarcel Holtmann 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
12500f36b589SMarcel Holtmann 
125145296acdSMarcel Holtmann 	if (status)
125245296acdSMarcel Holtmann 		return;
125345296acdSMarcel Holtmann 
12540f36b589SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_WHITE_LIST);
12550f36b589SMarcel Holtmann 	if (!sent)
12560f36b589SMarcel Holtmann 		return;
12570f36b589SMarcel Holtmann 
1258dcc36c16SJohan Hedberg 	hci_bdaddr_list_del(&hdev->le_white_list, &sent->bdaddr,
1259dcc36c16SJohan Hedberg 			    sent->bdaddr_type);
12600f36b589SMarcel Holtmann }
12610f36b589SMarcel Holtmann 
12629b008c04SJohan Hedberg static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
12639b008c04SJohan Hedberg 					    struct sk_buff *skb)
12649b008c04SJohan Hedberg {
12659b008c04SJohan Hedberg 	struct hci_rp_le_read_supported_states *rp = (void *) skb->data;
12669b008c04SJohan Hedberg 
12679b008c04SJohan Hedberg 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
12689b008c04SJohan Hedberg 
126945296acdSMarcel Holtmann 	if (rp->status)
127045296acdSMarcel Holtmann 		return;
127145296acdSMarcel Holtmann 
12729b008c04SJohan Hedberg 	memcpy(hdev->le_states, rp->le_states, 8);
12739b008c04SJohan Hedberg }
12749b008c04SJohan Hedberg 
1275a8e1bfaaSMarcel Holtmann static void hci_cc_le_read_def_data_len(struct hci_dev *hdev,
1276a8e1bfaaSMarcel Holtmann 					struct sk_buff *skb)
1277a8e1bfaaSMarcel Holtmann {
1278a8e1bfaaSMarcel Holtmann 	struct hci_rp_le_read_def_data_len *rp = (void *) skb->data;
1279a8e1bfaaSMarcel Holtmann 
1280a8e1bfaaSMarcel Holtmann 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1281a8e1bfaaSMarcel Holtmann 
1282a8e1bfaaSMarcel Holtmann 	if (rp->status)
1283a8e1bfaaSMarcel Holtmann 		return;
1284a8e1bfaaSMarcel Holtmann 
1285a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_len = le16_to_cpu(rp->tx_len);
1286a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_time = le16_to_cpu(rp->tx_time);
1287a8e1bfaaSMarcel Holtmann }
1288a8e1bfaaSMarcel Holtmann 
1289a8e1bfaaSMarcel Holtmann static void hci_cc_le_write_def_data_len(struct hci_dev *hdev,
1290a8e1bfaaSMarcel Holtmann 					 struct sk_buff *skb)
1291a8e1bfaaSMarcel Holtmann {
1292a8e1bfaaSMarcel Holtmann 	struct hci_cp_le_write_def_data_len *sent;
1293a8e1bfaaSMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
1294a8e1bfaaSMarcel Holtmann 
1295a8e1bfaaSMarcel Holtmann 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1296a8e1bfaaSMarcel Holtmann 
1297a8e1bfaaSMarcel Holtmann 	if (status)
1298a8e1bfaaSMarcel Holtmann 		return;
1299a8e1bfaaSMarcel Holtmann 
1300a8e1bfaaSMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_WRITE_DEF_DATA_LEN);
1301a8e1bfaaSMarcel Holtmann 	if (!sent)
1302a8e1bfaaSMarcel Holtmann 		return;
1303a8e1bfaaSMarcel Holtmann 
1304a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_len = le16_to_cpu(sent->tx_len);
1305a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_time = le16_to_cpu(sent->tx_time);
1306a8e1bfaaSMarcel Holtmann }
1307a8e1bfaaSMarcel Holtmann 
1308a8e1bfaaSMarcel Holtmann static void hci_cc_le_read_max_data_len(struct hci_dev *hdev,
1309a8e1bfaaSMarcel Holtmann 					struct sk_buff *skb)
1310a8e1bfaaSMarcel Holtmann {
1311a8e1bfaaSMarcel Holtmann 	struct hci_rp_le_read_max_data_len *rp = (void *) skb->data;
1312a8e1bfaaSMarcel Holtmann 
1313a8e1bfaaSMarcel Holtmann 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1314a8e1bfaaSMarcel Holtmann 
1315a8e1bfaaSMarcel Holtmann 	if (rp->status)
1316a8e1bfaaSMarcel Holtmann 		return;
1317a8e1bfaaSMarcel Holtmann 
1318a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_len = le16_to_cpu(rp->tx_len);
1319a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_time = le16_to_cpu(rp->tx_time);
1320a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_len = le16_to_cpu(rp->rx_len);
1321a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_time = le16_to_cpu(rp->rx_time);
1322a8e1bfaaSMarcel Holtmann }
1323a8e1bfaaSMarcel Holtmann 
13246039aa73SGustavo Padovan static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1325f9b49306SAndre Guedes 					   struct sk_buff *skb)
1326f9b49306SAndre Guedes {
132706199cf8SJohan Hedberg 	struct hci_cp_write_le_host_supported *sent;
1328f9b49306SAndre Guedes 	__u8 status = *((__u8 *) skb->data);
1329f9b49306SAndre Guedes 
13309f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1331f9b49306SAndre Guedes 
133245296acdSMarcel Holtmann 	if (status)
133345296acdSMarcel Holtmann 		return;
133445296acdSMarcel Holtmann 
133506199cf8SJohan Hedberg 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
13368f984dfaSJohan Hedberg 	if (!sent)
1337f9b49306SAndre Guedes 		return;
1338f9b49306SAndre Guedes 
13395c1a4c8fSJaganath Kanakkassery 	hci_dev_lock(hdev);
13405c1a4c8fSJaganath Kanakkassery 
1341416a4ae5SJohan Hedberg 	if (sent->le) {
1342cad718edSJohan Hedberg 		hdev->features[1][0] |= LMP_HOST_LE;
1343a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_LE_ENABLED);
1344416a4ae5SJohan Hedberg 	} else {
1345cad718edSJohan Hedberg 		hdev->features[1][0] &= ~LMP_HOST_LE;
1346a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LE_ENABLED);
1347a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_ADVERTISING);
1348416a4ae5SJohan Hedberg 	}
134953b2caabSJohan Hedberg 
135053b2caabSJohan Hedberg 	if (sent->simul)
1351cad718edSJohan Hedberg 		hdev->features[1][0] |= LMP_HOST_LE_BREDR;
135253b2caabSJohan Hedberg 	else
1353cad718edSJohan Hedberg 		hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
13545c1a4c8fSJaganath Kanakkassery 
13555c1a4c8fSJaganath Kanakkassery 	hci_dev_unlock(hdev);
13568f984dfaSJohan Hedberg }
1357f9b49306SAndre Guedes 
135856ed2cb8SJohan Hedberg static void hci_cc_set_adv_param(struct hci_dev *hdev, struct sk_buff *skb)
135956ed2cb8SJohan Hedberg {
136056ed2cb8SJohan Hedberg 	struct hci_cp_le_set_adv_param *cp;
136156ed2cb8SJohan Hedberg 	u8 status = *((u8 *) skb->data);
136256ed2cb8SJohan Hedberg 
136356ed2cb8SJohan Hedberg 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
136456ed2cb8SJohan Hedberg 
136556ed2cb8SJohan Hedberg 	if (status)
136656ed2cb8SJohan Hedberg 		return;
136756ed2cb8SJohan Hedberg 
136856ed2cb8SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_PARAM);
136956ed2cb8SJohan Hedberg 	if (!cp)
137056ed2cb8SJohan Hedberg 		return;
137156ed2cb8SJohan Hedberg 
137256ed2cb8SJohan Hedberg 	hci_dev_lock(hdev);
137356ed2cb8SJohan Hedberg 	hdev->adv_addr_type = cp->own_address_type;
137456ed2cb8SJohan Hedberg 	hci_dev_unlock(hdev);
137556ed2cb8SJohan Hedberg }
137656ed2cb8SJohan Hedberg 
13775ae76a94SAndrzej Kaczmarek static void hci_cc_read_rssi(struct hci_dev *hdev, struct sk_buff *skb)
13785ae76a94SAndrzej Kaczmarek {
13795ae76a94SAndrzej Kaczmarek 	struct hci_rp_read_rssi *rp = (void *) skb->data;
13805ae76a94SAndrzej Kaczmarek 	struct hci_conn *conn;
13815ae76a94SAndrzej Kaczmarek 
13825ae76a94SAndrzej Kaczmarek 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
13835ae76a94SAndrzej Kaczmarek 
13845ae76a94SAndrzej Kaczmarek 	if (rp->status)
13855ae76a94SAndrzej Kaczmarek 		return;
13865ae76a94SAndrzej Kaczmarek 
13875ae76a94SAndrzej Kaczmarek 	hci_dev_lock(hdev);
13885ae76a94SAndrzej Kaczmarek 
13895ae76a94SAndrzej Kaczmarek 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
13905ae76a94SAndrzej Kaczmarek 	if (conn)
13915ae76a94SAndrzej Kaczmarek 		conn->rssi = rp->rssi;
13925ae76a94SAndrzej Kaczmarek 
13935ae76a94SAndrzej Kaczmarek 	hci_dev_unlock(hdev);
13945ae76a94SAndrzej Kaczmarek }
13955ae76a94SAndrzej Kaczmarek 
13965a134faeSAndrzej Kaczmarek static void hci_cc_read_tx_power(struct hci_dev *hdev, struct sk_buff *skb)
13975a134faeSAndrzej Kaczmarek {
13985a134faeSAndrzej Kaczmarek 	struct hci_cp_read_tx_power *sent;
13995a134faeSAndrzej Kaczmarek 	struct hci_rp_read_tx_power *rp = (void *) skb->data;
14005a134faeSAndrzej Kaczmarek 	struct hci_conn *conn;
14015a134faeSAndrzej Kaczmarek 
14025a134faeSAndrzej Kaczmarek 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
14035a134faeSAndrzej Kaczmarek 
14045a134faeSAndrzej Kaczmarek 	if (rp->status)
14055a134faeSAndrzej Kaczmarek 		return;
14065a134faeSAndrzej Kaczmarek 
14075a134faeSAndrzej Kaczmarek 	sent = hci_sent_cmd_data(hdev, HCI_OP_READ_TX_POWER);
14085a134faeSAndrzej Kaczmarek 	if (!sent)
14095a134faeSAndrzej Kaczmarek 		return;
14105a134faeSAndrzej Kaczmarek 
14115a134faeSAndrzej Kaczmarek 	hci_dev_lock(hdev);
14125a134faeSAndrzej Kaczmarek 
14135a134faeSAndrzej Kaczmarek 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
1414d0455ed9SAndrzej Kaczmarek 	if (!conn)
1415d0455ed9SAndrzej Kaczmarek 		goto unlock;
14165a134faeSAndrzej Kaczmarek 
1417d0455ed9SAndrzej Kaczmarek 	switch (sent->type) {
1418d0455ed9SAndrzej Kaczmarek 	case 0x00:
1419d0455ed9SAndrzej Kaczmarek 		conn->tx_power = rp->tx_power;
1420d0455ed9SAndrzej Kaczmarek 		break;
1421d0455ed9SAndrzej Kaczmarek 	case 0x01:
1422d0455ed9SAndrzej Kaczmarek 		conn->max_tx_power = rp->tx_power;
1423d0455ed9SAndrzej Kaczmarek 		break;
1424d0455ed9SAndrzej Kaczmarek 	}
1425d0455ed9SAndrzej Kaczmarek 
1426d0455ed9SAndrzej Kaczmarek unlock:
14275a134faeSAndrzej Kaczmarek 	hci_dev_unlock(hdev);
14285a134faeSAndrzej Kaczmarek }
14295a134faeSAndrzej Kaczmarek 
1430c50b33c8SMarcel Holtmann static void hci_cc_write_ssp_debug_mode(struct hci_dev *hdev, struct sk_buff *skb)
1431c50b33c8SMarcel Holtmann {
1432c50b33c8SMarcel Holtmann 	u8 status = *((u8 *) skb->data);
1433c50b33c8SMarcel Holtmann 	u8 *mode;
1434c50b33c8SMarcel Holtmann 
1435c50b33c8SMarcel Holtmann 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1436c50b33c8SMarcel Holtmann 
1437c50b33c8SMarcel Holtmann 	if (status)
1438c50b33c8SMarcel Holtmann 		return;
1439c50b33c8SMarcel Holtmann 
1440c50b33c8SMarcel Holtmann 	mode = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE);
1441c50b33c8SMarcel Holtmann 	if (mode)
1442c50b33c8SMarcel Holtmann 		hdev->ssp_debug_mode = *mode;
1443c50b33c8SMarcel Holtmann }
1444c50b33c8SMarcel Holtmann 
14456039aa73SGustavo Padovan static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1446a9de9248SMarcel Holtmann {
14479f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1448a9de9248SMarcel Holtmann 
1449a9de9248SMarcel Holtmann 	if (status) {
1450a9de9248SMarcel Holtmann 		hci_conn_check_pending(hdev);
1451314b2381SJohan Hedberg 		return;
1452314b2381SJohan Hedberg 	}
1453314b2381SJohan Hedberg 
145489352e7dSAndre Guedes 	set_bit(HCI_INQUIRY, &hdev->flags);
1455a9de9248SMarcel Holtmann }
1456a9de9248SMarcel Holtmann 
14576039aa73SGustavo Padovan static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
14581da177e4SLinus Torvalds {
1459a9de9248SMarcel Holtmann 	struct hci_cp_create_conn *cp;
14601da177e4SLinus Torvalds 	struct hci_conn *conn;
14611da177e4SLinus Torvalds 
14629f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1463a9de9248SMarcel Holtmann 
1464a9de9248SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
14651da177e4SLinus Torvalds 	if (!cp)
14661da177e4SLinus Torvalds 		return;
14671da177e4SLinus Torvalds 
14681da177e4SLinus Torvalds 	hci_dev_lock(hdev);
14691da177e4SLinus Torvalds 
14701da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
14711da177e4SLinus Torvalds 
14726ed93dc6SAndrei Emeltchenko 	BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
14731da177e4SLinus Torvalds 
14741da177e4SLinus Torvalds 	if (status) {
14751da177e4SLinus Torvalds 		if (conn && conn->state == BT_CONNECT) {
14764c67bc74SMarcel Holtmann 			if (status != 0x0c || conn->attempt > 2) {
14771da177e4SLinus Torvalds 				conn->state = BT_CLOSED;
1478539c496dSJohan Hedberg 				hci_connect_cfm(conn, status);
14791da177e4SLinus Torvalds 				hci_conn_del(conn);
14804c67bc74SMarcel Holtmann 			} else
14814c67bc74SMarcel Holtmann 				conn->state = BT_CONNECT2;
14821da177e4SLinus Torvalds 		}
14831da177e4SLinus Torvalds 	} else {
14841da177e4SLinus Torvalds 		if (!conn) {
1485a5c4e309SJohan Hedberg 			conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr,
1486a5c4e309SJohan Hedberg 					    HCI_ROLE_MASTER);
1487a5c4e309SJohan Hedberg 			if (!conn)
1488893ef971SGustavo F. Padovan 				BT_ERR("No memory for new connection");
14891da177e4SLinus Torvalds 		}
14901da177e4SLinus Torvalds 	}
14911da177e4SLinus Torvalds 
14921da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
14931da177e4SLinus Torvalds }
14941da177e4SLinus Torvalds 
1495a9de9248SMarcel Holtmann static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
14961da177e4SLinus Torvalds {
1497a9de9248SMarcel Holtmann 	struct hci_cp_add_sco *cp;
14981da177e4SLinus Torvalds 	struct hci_conn *acl, *sco;
14991da177e4SLinus Torvalds 	__u16 handle;
15001da177e4SLinus Torvalds 
15019f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1502b6a0dc82SMarcel Holtmann 
1503a9de9248SMarcel Holtmann 	if (!status)
1504a9de9248SMarcel Holtmann 		return;
1505a9de9248SMarcel Holtmann 
1506a9de9248SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
15071da177e4SLinus Torvalds 	if (!cp)
1508a9de9248SMarcel Holtmann 		return;
15091da177e4SLinus Torvalds 
15101da177e4SLinus Torvalds 	handle = __le16_to_cpu(cp->handle);
15111da177e4SLinus Torvalds 
15129f1db00cSAndrei Emeltchenko 	BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
15131da177e4SLinus Torvalds 
15141da177e4SLinus Torvalds 	hci_dev_lock(hdev);
15151da177e4SLinus Torvalds 
15161da177e4SLinus Torvalds 	acl = hci_conn_hash_lookup_handle(hdev, handle);
15175a08ecceSAndrei Emeltchenko 	if (acl) {
15185a08ecceSAndrei Emeltchenko 		sco = acl->link;
15195a08ecceSAndrei Emeltchenko 		if (sco) {
15201da177e4SLinus Torvalds 			sco->state = BT_CLOSED;
15211da177e4SLinus Torvalds 
1522539c496dSJohan Hedberg 			hci_connect_cfm(sco, status);
15231da177e4SLinus Torvalds 			hci_conn_del(sco);
15241da177e4SLinus Torvalds 		}
15255a08ecceSAndrei Emeltchenko 	}
15261da177e4SLinus Torvalds 
15271da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
15281da177e4SLinus Torvalds }
15291da177e4SLinus Torvalds 
1530f8558555SMarcel Holtmann static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1531f8558555SMarcel Holtmann {
1532f8558555SMarcel Holtmann 	struct hci_cp_auth_requested *cp;
1533f8558555SMarcel Holtmann 	struct hci_conn *conn;
1534f8558555SMarcel Holtmann 
15359f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1536f8558555SMarcel Holtmann 
1537f8558555SMarcel Holtmann 	if (!status)
1538f8558555SMarcel Holtmann 		return;
1539f8558555SMarcel Holtmann 
1540f8558555SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1541f8558555SMarcel Holtmann 	if (!cp)
1542f8558555SMarcel Holtmann 		return;
1543f8558555SMarcel Holtmann 
1544f8558555SMarcel Holtmann 	hci_dev_lock(hdev);
1545f8558555SMarcel Holtmann 
1546f8558555SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1547f8558555SMarcel Holtmann 	if (conn) {
1548f8558555SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
1549539c496dSJohan Hedberg 			hci_connect_cfm(conn, status);
155076a68ba0SDavid Herrmann 			hci_conn_drop(conn);
1551f8558555SMarcel Holtmann 		}
1552f8558555SMarcel Holtmann 	}
1553f8558555SMarcel Holtmann 
1554f8558555SMarcel Holtmann 	hci_dev_unlock(hdev);
1555f8558555SMarcel Holtmann }
1556f8558555SMarcel Holtmann 
1557f8558555SMarcel Holtmann static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1558f8558555SMarcel Holtmann {
1559f8558555SMarcel Holtmann 	struct hci_cp_set_conn_encrypt *cp;
1560f8558555SMarcel Holtmann 	struct hci_conn *conn;
1561f8558555SMarcel Holtmann 
15629f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1563f8558555SMarcel Holtmann 
1564f8558555SMarcel Holtmann 	if (!status)
1565f8558555SMarcel Holtmann 		return;
1566f8558555SMarcel Holtmann 
1567f8558555SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1568f8558555SMarcel Holtmann 	if (!cp)
1569f8558555SMarcel Holtmann 		return;
1570f8558555SMarcel Holtmann 
1571f8558555SMarcel Holtmann 	hci_dev_lock(hdev);
1572f8558555SMarcel Holtmann 
1573f8558555SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1574f8558555SMarcel Holtmann 	if (conn) {
1575f8558555SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
1576539c496dSJohan Hedberg 			hci_connect_cfm(conn, status);
157776a68ba0SDavid Herrmann 			hci_conn_drop(conn);
1578f8558555SMarcel Holtmann 		}
1579f8558555SMarcel Holtmann 	}
1580f8558555SMarcel Holtmann 
1581f8558555SMarcel Holtmann 	hci_dev_unlock(hdev);
1582f8558555SMarcel Holtmann }
1583f8558555SMarcel Holtmann 
1584127178d2SJohan Hedberg static int hci_outgoing_auth_needed(struct hci_dev *hdev,
1585392599b9SJohan Hedberg 				    struct hci_conn *conn)
1586392599b9SJohan Hedberg {
1587392599b9SJohan Hedberg 	if (conn->state != BT_CONFIG || !conn->out)
1588392599b9SJohan Hedberg 		return 0;
1589392599b9SJohan Hedberg 
1590765c2a96SJohan Hedberg 	if (conn->pending_sec_level == BT_SECURITY_SDP)
1591392599b9SJohan Hedberg 		return 0;
1592392599b9SJohan Hedberg 
1593392599b9SJohan Hedberg 	/* Only request authentication for SSP connections or non-SSP
1594264b8b4eSJohan Hedberg 	 * devices with sec_level MEDIUM or HIGH or if MITM protection
1595264b8b4eSJohan Hedberg 	 * is requested.
1596264b8b4eSJohan Hedberg 	 */
1597807deac2SGustavo Padovan 	if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
15987e3691e1SJohan Hedberg 	    conn->pending_sec_level != BT_SECURITY_FIPS &&
1599264b8b4eSJohan Hedberg 	    conn->pending_sec_level != BT_SECURITY_HIGH &&
1600264b8b4eSJohan Hedberg 	    conn->pending_sec_level != BT_SECURITY_MEDIUM)
1601392599b9SJohan Hedberg 		return 0;
1602392599b9SJohan Hedberg 
1603392599b9SJohan Hedberg 	return 1;
1604392599b9SJohan Hedberg }
1605392599b9SJohan Hedberg 
16066039aa73SGustavo Padovan static int hci_resolve_name(struct hci_dev *hdev,
160700abfe44SGustavo F. Padovan 				   struct inquiry_entry *e)
160830dc78e1SJohan Hedberg {
160930dc78e1SJohan Hedberg 	struct hci_cp_remote_name_req cp;
161030dc78e1SJohan Hedberg 
161130dc78e1SJohan Hedberg 	memset(&cp, 0, sizeof(cp));
161230dc78e1SJohan Hedberg 
161330dc78e1SJohan Hedberg 	bacpy(&cp.bdaddr, &e->data.bdaddr);
161430dc78e1SJohan Hedberg 	cp.pscan_rep_mode = e->data.pscan_rep_mode;
161530dc78e1SJohan Hedberg 	cp.pscan_mode = e->data.pscan_mode;
161630dc78e1SJohan Hedberg 	cp.clock_offset = e->data.clock_offset;
161730dc78e1SJohan Hedberg 
161830dc78e1SJohan Hedberg 	return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
161930dc78e1SJohan Hedberg }
162030dc78e1SJohan Hedberg 
1621b644ba33SJohan Hedberg static bool hci_resolve_next_name(struct hci_dev *hdev)
162230dc78e1SJohan Hedberg {
162330dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
162430dc78e1SJohan Hedberg 	struct inquiry_entry *e;
162530dc78e1SJohan Hedberg 
1626b644ba33SJohan Hedberg 	if (list_empty(&discov->resolve))
1627b644ba33SJohan Hedberg 		return false;
1628b644ba33SJohan Hedberg 
1629b644ba33SJohan Hedberg 	e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1630c810089cSRam Malovany 	if (!e)
1631c810089cSRam Malovany 		return false;
1632c810089cSRam Malovany 
1633b644ba33SJohan Hedberg 	if (hci_resolve_name(hdev, e) == 0) {
1634b644ba33SJohan Hedberg 		e->name_state = NAME_PENDING;
1635b644ba33SJohan Hedberg 		return true;
1636b644ba33SJohan Hedberg 	}
1637b644ba33SJohan Hedberg 
1638b644ba33SJohan Hedberg 	return false;
1639b644ba33SJohan Hedberg }
1640b644ba33SJohan Hedberg 
1641b644ba33SJohan Hedberg static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
1642b644ba33SJohan Hedberg 				   bdaddr_t *bdaddr, u8 *name, u8 name_len)
1643b644ba33SJohan Hedberg {
1644b644ba33SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
1645b644ba33SJohan Hedberg 	struct inquiry_entry *e;
1646b644ba33SJohan Hedberg 
164760cb49d2SJohan Hedberg 	/* Update the mgmt connected state if necessary. Be careful with
164860cb49d2SJohan Hedberg 	 * conn objects that exist but are not (yet) connected however.
164960cb49d2SJohan Hedberg 	 * Only those in BT_CONFIG or BT_CONNECTED states can be
165060cb49d2SJohan Hedberg 	 * considered connected.
165160cb49d2SJohan Hedberg 	 */
165260cb49d2SJohan Hedberg 	if (conn &&
165360cb49d2SJohan Hedberg 	    (conn->state == BT_CONFIG || conn->state == BT_CONNECTED) &&
1654cb77c3ecSJaganath Kanakkassery 	    !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
165548ec92faSAlfonso Acosta 		mgmt_device_connected(hdev, conn, 0, name, name_len);
1656b644ba33SJohan Hedberg 
1657b644ba33SJohan Hedberg 	if (discov->state == DISCOVERY_STOPPED)
1658b644ba33SJohan Hedberg 		return;
1659b644ba33SJohan Hedberg 
166030dc78e1SJohan Hedberg 	if (discov->state == DISCOVERY_STOPPING)
166130dc78e1SJohan Hedberg 		goto discov_complete;
166230dc78e1SJohan Hedberg 
166330dc78e1SJohan Hedberg 	if (discov->state != DISCOVERY_RESOLVING)
166430dc78e1SJohan Hedberg 		return;
166530dc78e1SJohan Hedberg 
166630dc78e1SJohan Hedberg 	e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
16677cc8380eSRam Malovany 	/* If the device was not found in a list of found devices names of which
16687cc8380eSRam Malovany 	 * are pending. there is no need to continue resolving a next name as it
16697cc8380eSRam Malovany 	 * will be done upon receiving another Remote Name Request Complete
16707cc8380eSRam Malovany 	 * Event */
16717cc8380eSRam Malovany 	if (!e)
16727cc8380eSRam Malovany 		return;
16737cc8380eSRam Malovany 
167430dc78e1SJohan Hedberg 	list_del(&e->list);
16757cc8380eSRam Malovany 	if (name) {
16767cc8380eSRam Malovany 		e->name_state = NAME_KNOWN;
1677b644ba33SJohan Hedberg 		mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1678b644ba33SJohan Hedberg 				 e->data.rssi, name, name_len);
1679c3e7c0d9SRam Malovany 	} else {
1680c3e7c0d9SRam Malovany 		e->name_state = NAME_NOT_KNOWN;
168130dc78e1SJohan Hedberg 	}
168230dc78e1SJohan Hedberg 
1683b644ba33SJohan Hedberg 	if (hci_resolve_next_name(hdev))
168430dc78e1SJohan Hedberg 		return;
168530dc78e1SJohan Hedberg 
168630dc78e1SJohan Hedberg discov_complete:
168730dc78e1SJohan Hedberg 	hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
168830dc78e1SJohan Hedberg }
168930dc78e1SJohan Hedberg 
1690a9de9248SMarcel Holtmann static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
16911da177e4SLinus Torvalds {
1692127178d2SJohan Hedberg 	struct hci_cp_remote_name_req *cp;
1693127178d2SJohan Hedberg 	struct hci_conn *conn;
1694127178d2SJohan Hedberg 
16959f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1696127178d2SJohan Hedberg 
1697127178d2SJohan Hedberg 	/* If successful wait for the name req complete event before
1698127178d2SJohan Hedberg 	 * checking for the need to do authentication */
1699127178d2SJohan Hedberg 	if (!status)
1700127178d2SJohan Hedberg 		return;
1701127178d2SJohan Hedberg 
1702127178d2SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1703127178d2SJohan Hedberg 	if (!cp)
1704127178d2SJohan Hedberg 		return;
1705127178d2SJohan Hedberg 
1706127178d2SJohan Hedberg 	hci_dev_lock(hdev);
1707127178d2SJohan Hedberg 
1708127178d2SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1709b644ba33SJohan Hedberg 
1710d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
1711b644ba33SJohan Hedberg 		hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1712b644ba33SJohan Hedberg 
171379c6c70cSJohan Hedberg 	if (!conn)
171479c6c70cSJohan Hedberg 		goto unlock;
171579c6c70cSJohan Hedberg 
171679c6c70cSJohan Hedberg 	if (!hci_outgoing_auth_needed(hdev, conn))
171779c6c70cSJohan Hedberg 		goto unlock;
171879c6c70cSJohan Hedberg 
171951a8efd7SJohan Hedberg 	if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
1720c1f23a2bSJohannes Berg 		struct hci_cp_auth_requested auth_cp;
1721c1f23a2bSJohannes Berg 
1722977f8fceSJohan Hedberg 		set_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags);
1723977f8fceSJohan Hedberg 
1724c1f23a2bSJohannes Berg 		auth_cp.handle = __cpu_to_le16(conn->handle);
1725c1f23a2bSJohannes Berg 		hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
1726c1f23a2bSJohannes Berg 			     sizeof(auth_cp), &auth_cp);
1727127178d2SJohan Hedberg 	}
1728127178d2SJohan Hedberg 
172979c6c70cSJohan Hedberg unlock:
1730127178d2SJohan Hedberg 	hci_dev_unlock(hdev);
1731a9de9248SMarcel Holtmann }
17321da177e4SLinus Torvalds 
1733769be974SMarcel Holtmann static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1734769be974SMarcel Holtmann {
1735769be974SMarcel Holtmann 	struct hci_cp_read_remote_features *cp;
1736769be974SMarcel Holtmann 	struct hci_conn *conn;
1737769be974SMarcel Holtmann 
17389f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1739769be974SMarcel Holtmann 
1740769be974SMarcel Holtmann 	if (!status)
1741769be974SMarcel Holtmann 		return;
1742769be974SMarcel Holtmann 
1743769be974SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1744769be974SMarcel Holtmann 	if (!cp)
1745769be974SMarcel Holtmann 		return;
1746769be974SMarcel Holtmann 
1747769be974SMarcel Holtmann 	hci_dev_lock(hdev);
1748769be974SMarcel Holtmann 
1749769be974SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1750769be974SMarcel Holtmann 	if (conn) {
1751769be974SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
1752539c496dSJohan Hedberg 			hci_connect_cfm(conn, status);
175376a68ba0SDavid Herrmann 			hci_conn_drop(conn);
1754769be974SMarcel Holtmann 		}
1755769be974SMarcel Holtmann 	}
1756769be974SMarcel Holtmann 
1757769be974SMarcel Holtmann 	hci_dev_unlock(hdev);
1758769be974SMarcel Holtmann }
1759769be974SMarcel Holtmann 
1760769be974SMarcel Holtmann static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1761769be974SMarcel Holtmann {
1762769be974SMarcel Holtmann 	struct hci_cp_read_remote_ext_features *cp;
1763769be974SMarcel Holtmann 	struct hci_conn *conn;
1764769be974SMarcel Holtmann 
17659f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1766769be974SMarcel Holtmann 
1767769be974SMarcel Holtmann 	if (!status)
1768769be974SMarcel Holtmann 		return;
1769769be974SMarcel Holtmann 
1770769be974SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1771769be974SMarcel Holtmann 	if (!cp)
1772769be974SMarcel Holtmann 		return;
1773769be974SMarcel Holtmann 
1774769be974SMarcel Holtmann 	hci_dev_lock(hdev);
1775769be974SMarcel Holtmann 
1776769be974SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1777769be974SMarcel Holtmann 	if (conn) {
1778769be974SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
1779539c496dSJohan Hedberg 			hci_connect_cfm(conn, status);
178076a68ba0SDavid Herrmann 			hci_conn_drop(conn);
1781769be974SMarcel Holtmann 		}
1782769be974SMarcel Holtmann 	}
1783769be974SMarcel Holtmann 
1784769be974SMarcel Holtmann 	hci_dev_unlock(hdev);
1785769be974SMarcel Holtmann }
1786769be974SMarcel Holtmann 
1787a9de9248SMarcel Holtmann static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1788a9de9248SMarcel Holtmann {
1789b6a0dc82SMarcel Holtmann 	struct hci_cp_setup_sync_conn *cp;
1790b6a0dc82SMarcel Holtmann 	struct hci_conn *acl, *sco;
1791b6a0dc82SMarcel Holtmann 	__u16 handle;
1792b6a0dc82SMarcel Holtmann 
17939f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1794b6a0dc82SMarcel Holtmann 
1795b6a0dc82SMarcel Holtmann 	if (!status)
1796b6a0dc82SMarcel Holtmann 		return;
1797b6a0dc82SMarcel Holtmann 
1798b6a0dc82SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1799b6a0dc82SMarcel Holtmann 	if (!cp)
1800b6a0dc82SMarcel Holtmann 		return;
1801b6a0dc82SMarcel Holtmann 
1802b6a0dc82SMarcel Holtmann 	handle = __le16_to_cpu(cp->handle);
1803b6a0dc82SMarcel Holtmann 
18049f1db00cSAndrei Emeltchenko 	BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
1805b6a0dc82SMarcel Holtmann 
1806b6a0dc82SMarcel Holtmann 	hci_dev_lock(hdev);
1807b6a0dc82SMarcel Holtmann 
1808b6a0dc82SMarcel Holtmann 	acl = hci_conn_hash_lookup_handle(hdev, handle);
18095a08ecceSAndrei Emeltchenko 	if (acl) {
18105a08ecceSAndrei Emeltchenko 		sco = acl->link;
18115a08ecceSAndrei Emeltchenko 		if (sco) {
1812b6a0dc82SMarcel Holtmann 			sco->state = BT_CLOSED;
1813b6a0dc82SMarcel Holtmann 
1814539c496dSJohan Hedberg 			hci_connect_cfm(sco, status);
1815b6a0dc82SMarcel Holtmann 			hci_conn_del(sco);
1816b6a0dc82SMarcel Holtmann 		}
18175a08ecceSAndrei Emeltchenko 	}
1818b6a0dc82SMarcel Holtmann 
1819b6a0dc82SMarcel Holtmann 	hci_dev_unlock(hdev);
1820a9de9248SMarcel Holtmann }
1821a9de9248SMarcel Holtmann 
1822a9de9248SMarcel Holtmann static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1823a9de9248SMarcel Holtmann {
1824a9de9248SMarcel Holtmann 	struct hci_cp_sniff_mode *cp;
182504837f64SMarcel Holtmann 	struct hci_conn *conn;
182604837f64SMarcel Holtmann 
18279f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1828a9de9248SMarcel Holtmann 
1829a9de9248SMarcel Holtmann 	if (!status)
1830a9de9248SMarcel Holtmann 		return;
1831a9de9248SMarcel Holtmann 
1832a9de9248SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
183304837f64SMarcel Holtmann 	if (!cp)
1834a9de9248SMarcel Holtmann 		return;
183504837f64SMarcel Holtmann 
183604837f64SMarcel Holtmann 	hci_dev_lock(hdev);
183704837f64SMarcel Holtmann 
183804837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1839e73439d8SMarcel Holtmann 	if (conn) {
184051a8efd7SJohan Hedberg 		clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
184104837f64SMarcel Holtmann 
184251a8efd7SJohan Hedberg 		if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
1843e73439d8SMarcel Holtmann 			hci_sco_setup(conn, status);
1844e73439d8SMarcel Holtmann 	}
1845e73439d8SMarcel Holtmann 
184604837f64SMarcel Holtmann 	hci_dev_unlock(hdev);
184704837f64SMarcel Holtmann }
184804837f64SMarcel Holtmann 
1849a9de9248SMarcel Holtmann static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1850a9de9248SMarcel Holtmann {
1851a9de9248SMarcel Holtmann 	struct hci_cp_exit_sniff_mode *cp;
185204837f64SMarcel Holtmann 	struct hci_conn *conn;
185304837f64SMarcel Holtmann 
18549f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1855a9de9248SMarcel Holtmann 
1856a9de9248SMarcel Holtmann 	if (!status)
1857a9de9248SMarcel Holtmann 		return;
1858a9de9248SMarcel Holtmann 
1859a9de9248SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
186004837f64SMarcel Holtmann 	if (!cp)
1861a9de9248SMarcel Holtmann 		return;
186204837f64SMarcel Holtmann 
186304837f64SMarcel Holtmann 	hci_dev_lock(hdev);
186404837f64SMarcel Holtmann 
186504837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1866e73439d8SMarcel Holtmann 	if (conn) {
186751a8efd7SJohan Hedberg 		clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
186804837f64SMarcel Holtmann 
186951a8efd7SJohan Hedberg 		if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
1870e73439d8SMarcel Holtmann 			hci_sco_setup(conn, status);
1871e73439d8SMarcel Holtmann 	}
1872e73439d8SMarcel Holtmann 
187304837f64SMarcel Holtmann 	hci_dev_unlock(hdev);
187404837f64SMarcel Holtmann }
187504837f64SMarcel Holtmann 
187688c3df13SJohan Hedberg static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
187788c3df13SJohan Hedberg {
187888c3df13SJohan Hedberg 	struct hci_cp_disconnect *cp;
187988c3df13SJohan Hedberg 	struct hci_conn *conn;
188088c3df13SJohan Hedberg 
188188c3df13SJohan Hedberg 	if (!status)
188288c3df13SJohan Hedberg 		return;
188388c3df13SJohan Hedberg 
188488c3df13SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
188588c3df13SJohan Hedberg 	if (!cp)
188688c3df13SJohan Hedberg 		return;
188788c3df13SJohan Hedberg 
188888c3df13SJohan Hedberg 	hci_dev_lock(hdev);
188988c3df13SJohan Hedberg 
189088c3df13SJohan Hedberg 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
189188c3df13SJohan Hedberg 	if (conn)
189288c3df13SJohan Hedberg 		mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
189388c3df13SJohan Hedberg 				       conn->dst_type, status);
189488c3df13SJohan Hedberg 
189588c3df13SJohan Hedberg 	hci_dev_unlock(hdev);
189688c3df13SJohan Hedberg }
189788c3df13SJohan Hedberg 
1898cb1d68f7SJohan Hedberg static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status)
1899cb1d68f7SJohan Hedberg {
1900cb1d68f7SJohan Hedberg 	struct hci_cp_le_create_conn *cp;
1901cb1d68f7SJohan Hedberg 	struct hci_conn *conn;
1902cb1d68f7SJohan Hedberg 
1903cb1d68f7SJohan Hedberg 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1904cb1d68f7SJohan Hedberg 
1905cb1d68f7SJohan Hedberg 	/* All connection failure handling is taken care of by the
1906cb1d68f7SJohan Hedberg 	 * hci_le_conn_failed function which is triggered by the HCI
1907cb1d68f7SJohan Hedberg 	 * request completion callbacks used for connecting.
1908cb1d68f7SJohan Hedberg 	 */
1909cb1d68f7SJohan Hedberg 	if (status)
1910cb1d68f7SJohan Hedberg 		return;
1911cb1d68f7SJohan Hedberg 
1912cb1d68f7SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1913cb1d68f7SJohan Hedberg 	if (!cp)
1914cb1d68f7SJohan Hedberg 		return;
1915cb1d68f7SJohan Hedberg 
1916cb1d68f7SJohan Hedberg 	hci_dev_lock(hdev);
1917cb1d68f7SJohan Hedberg 
19189d4c1cc1SJohan Hedberg 	conn = hci_conn_hash_lookup_le(hdev, &cp->peer_addr,
19199d4c1cc1SJohan Hedberg 				       cp->peer_addr_type);
1920cb1d68f7SJohan Hedberg 	if (!conn)
1921cb1d68f7SJohan Hedberg 		goto unlock;
1922cb1d68f7SJohan Hedberg 
1923cb1d68f7SJohan Hedberg 	/* Store the initiator and responder address information which
1924cb1d68f7SJohan Hedberg 	 * is needed for SMP. These values will not change during the
1925cb1d68f7SJohan Hedberg 	 * lifetime of the connection.
1926cb1d68f7SJohan Hedberg 	 */
1927cb1d68f7SJohan Hedberg 	conn->init_addr_type = cp->own_address_type;
1928cb1d68f7SJohan Hedberg 	if (cp->own_address_type == ADDR_LE_DEV_RANDOM)
1929cb1d68f7SJohan Hedberg 		bacpy(&conn->init_addr, &hdev->random_addr);
1930cb1d68f7SJohan Hedberg 	else
1931cb1d68f7SJohan Hedberg 		bacpy(&conn->init_addr, &hdev->bdaddr);
1932cb1d68f7SJohan Hedberg 
1933cb1d68f7SJohan Hedberg 	conn->resp_addr_type = cp->peer_addr_type;
1934cb1d68f7SJohan Hedberg 	bacpy(&conn->resp_addr, &cp->peer_addr);
1935cb1d68f7SJohan Hedberg 
19369489eca4SJohan Hedberg 	/* We don't want the connection attempt to stick around
19379489eca4SJohan Hedberg 	 * indefinitely since LE doesn't have a page timeout concept
19389489eca4SJohan Hedberg 	 * like BR/EDR. Set a timer for any connection that doesn't use
19399489eca4SJohan Hedberg 	 * the white list for connecting.
19409489eca4SJohan Hedberg 	 */
19419489eca4SJohan Hedberg 	if (cp->filter_policy == HCI_LE_USE_PEER_ADDR)
19429489eca4SJohan Hedberg 		queue_delayed_work(conn->hdev->workqueue,
19439489eca4SJohan Hedberg 				   &conn->le_conn_timeout,
194409ae260bSJohan Hedberg 				   conn->conn_timeout);
19459489eca4SJohan Hedberg 
1946cb1d68f7SJohan Hedberg unlock:
1947cb1d68f7SJohan Hedberg 	hci_dev_unlock(hdev);
1948cb1d68f7SJohan Hedberg }
1949cb1d68f7SJohan Hedberg 
19500fe29fd1SMarcel Holtmann static void hci_cs_le_read_remote_features(struct hci_dev *hdev, u8 status)
19510fe29fd1SMarcel Holtmann {
19520fe29fd1SMarcel Holtmann 	struct hci_cp_le_read_remote_features *cp;
19530fe29fd1SMarcel Holtmann 	struct hci_conn *conn;
19540fe29fd1SMarcel Holtmann 
19550fe29fd1SMarcel Holtmann 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
19560fe29fd1SMarcel Holtmann 
19570fe29fd1SMarcel Holtmann 	if (!status)
19580fe29fd1SMarcel Holtmann 		return;
19590fe29fd1SMarcel Holtmann 
19600fe29fd1SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_READ_REMOTE_FEATURES);
19610fe29fd1SMarcel Holtmann 	if (!cp)
19620fe29fd1SMarcel Holtmann 		return;
19630fe29fd1SMarcel Holtmann 
19640fe29fd1SMarcel Holtmann 	hci_dev_lock(hdev);
19650fe29fd1SMarcel Holtmann 
19660fe29fd1SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
19670fe29fd1SMarcel Holtmann 	if (conn) {
19680fe29fd1SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
19690fe29fd1SMarcel Holtmann 			hci_connect_cfm(conn, status);
19700fe29fd1SMarcel Holtmann 			hci_conn_drop(conn);
19710fe29fd1SMarcel Holtmann 		}
19720fe29fd1SMarcel Holtmann 	}
19730fe29fd1SMarcel Holtmann 
19740fe29fd1SMarcel Holtmann 	hci_dev_unlock(hdev);
19750fe29fd1SMarcel Holtmann }
19760fe29fd1SMarcel Holtmann 
197781d0c8adSJohan Hedberg static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
197881d0c8adSJohan Hedberg {
197981d0c8adSJohan Hedberg 	struct hci_cp_le_start_enc *cp;
198081d0c8adSJohan Hedberg 	struct hci_conn *conn;
198181d0c8adSJohan Hedberg 
198281d0c8adSJohan Hedberg 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
198381d0c8adSJohan Hedberg 
198481d0c8adSJohan Hedberg 	if (!status)
198581d0c8adSJohan Hedberg 		return;
198681d0c8adSJohan Hedberg 
198781d0c8adSJohan Hedberg 	hci_dev_lock(hdev);
198881d0c8adSJohan Hedberg 
198981d0c8adSJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_START_ENC);
199081d0c8adSJohan Hedberg 	if (!cp)
199181d0c8adSJohan Hedberg 		goto unlock;
199281d0c8adSJohan Hedberg 
199381d0c8adSJohan Hedberg 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
199481d0c8adSJohan Hedberg 	if (!conn)
199581d0c8adSJohan Hedberg 		goto unlock;
199681d0c8adSJohan Hedberg 
199781d0c8adSJohan Hedberg 	if (conn->state != BT_CONNECTED)
199881d0c8adSJohan Hedberg 		goto unlock;
199981d0c8adSJohan Hedberg 
200081d0c8adSJohan Hedberg 	hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
200181d0c8adSJohan Hedberg 	hci_conn_drop(conn);
200281d0c8adSJohan Hedberg 
200381d0c8adSJohan Hedberg unlock:
200481d0c8adSJohan Hedberg 	hci_dev_unlock(hdev);
200581d0c8adSJohan Hedberg }
200681d0c8adSJohan Hedberg 
200750fc85f1SKuba Pawlak static void hci_cs_switch_role(struct hci_dev *hdev, u8 status)
200850fc85f1SKuba Pawlak {
200950fc85f1SKuba Pawlak 	struct hci_cp_switch_role *cp;
201050fc85f1SKuba Pawlak 	struct hci_conn *conn;
201150fc85f1SKuba Pawlak 
201250fc85f1SKuba Pawlak 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
201350fc85f1SKuba Pawlak 
201450fc85f1SKuba Pawlak 	if (!status)
201550fc85f1SKuba Pawlak 		return;
201650fc85f1SKuba Pawlak 
201750fc85f1SKuba Pawlak 	cp = hci_sent_cmd_data(hdev, HCI_OP_SWITCH_ROLE);
201850fc85f1SKuba Pawlak 	if (!cp)
201950fc85f1SKuba Pawlak 		return;
202050fc85f1SKuba Pawlak 
202150fc85f1SKuba Pawlak 	hci_dev_lock(hdev);
202250fc85f1SKuba Pawlak 
202350fc85f1SKuba Pawlak 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
202450fc85f1SKuba Pawlak 	if (conn)
202550fc85f1SKuba Pawlak 		clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
202650fc85f1SKuba Pawlak 
202750fc85f1SKuba Pawlak 	hci_dev_unlock(hdev);
202850fc85f1SKuba Pawlak }
202950fc85f1SKuba Pawlak 
20306039aa73SGustavo Padovan static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
20311da177e4SLinus Torvalds {
20321da177e4SLinus Torvalds 	__u8 status = *((__u8 *) skb->data);
203330dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
203430dc78e1SJohan Hedberg 	struct inquiry_entry *e;
20351da177e4SLinus Torvalds 
20369f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
20371da177e4SLinus Torvalds 
2038a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
203989352e7dSAndre Guedes 
204089352e7dSAndre Guedes 	if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
204189352e7dSAndre Guedes 		return;
204289352e7dSAndre Guedes 
20434e857c58SPeter Zijlstra 	smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */
20443e13fa1eSAndre Guedes 	wake_up_bit(&hdev->flags, HCI_INQUIRY);
20453e13fa1eSAndre Guedes 
2046d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
204730dc78e1SJohan Hedberg 		return;
204830dc78e1SJohan Hedberg 
204956e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
205030dc78e1SJohan Hedberg 
2051343f935bSAndre Guedes 	if (discov->state != DISCOVERY_FINDING)
205230dc78e1SJohan Hedberg 		goto unlock;
205330dc78e1SJohan Hedberg 
205430dc78e1SJohan Hedberg 	if (list_empty(&discov->resolve)) {
205507d2334aSJakub Pawlowski 		/* When BR/EDR inquiry is active and no LE scanning is in
205607d2334aSJakub Pawlowski 		 * progress, then change discovery state to indicate completion.
205707d2334aSJakub Pawlowski 		 *
205807d2334aSJakub Pawlowski 		 * When running LE scanning and BR/EDR inquiry simultaneously
205907d2334aSJakub Pawlowski 		 * and the LE scan already finished, then change the discovery
206007d2334aSJakub Pawlowski 		 * state to indicate completion.
206107d2334aSJakub Pawlowski 		 */
206207d2334aSJakub Pawlowski 		if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
206307d2334aSJakub Pawlowski 		    !test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks))
2064ff9ef578SJohan Hedberg 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
206530dc78e1SJohan Hedberg 		goto unlock;
206630dc78e1SJohan Hedberg 	}
206730dc78e1SJohan Hedberg 
206830dc78e1SJohan Hedberg 	e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
206930dc78e1SJohan Hedberg 	if (e && hci_resolve_name(hdev, e) == 0) {
207030dc78e1SJohan Hedberg 		e->name_state = NAME_PENDING;
207130dc78e1SJohan Hedberg 		hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
207230dc78e1SJohan Hedberg 	} else {
207307d2334aSJakub Pawlowski 		/* When BR/EDR inquiry is active and no LE scanning is in
207407d2334aSJakub Pawlowski 		 * progress, then change discovery state to indicate completion.
207507d2334aSJakub Pawlowski 		 *
207607d2334aSJakub Pawlowski 		 * When running LE scanning and BR/EDR inquiry simultaneously
207707d2334aSJakub Pawlowski 		 * and the LE scan already finished, then change the discovery
207807d2334aSJakub Pawlowski 		 * state to indicate completion.
207907d2334aSJakub Pawlowski 		 */
208007d2334aSJakub Pawlowski 		if (!hci_dev_test_flag(hdev, HCI_LE_SCAN) ||
208107d2334aSJakub Pawlowski 		    !test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks))
208230dc78e1SJohan Hedberg 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
208330dc78e1SJohan Hedberg 	}
208430dc78e1SJohan Hedberg 
208530dc78e1SJohan Hedberg unlock:
208656e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
20871da177e4SLinus Torvalds }
20881da177e4SLinus Torvalds 
20896039aa73SGustavo Padovan static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
20901da177e4SLinus Torvalds {
209145bb4bf0SMarcel Holtmann 	struct inquiry_data data;
2092a9de9248SMarcel Holtmann 	struct inquiry_info *info = (void *) (skb->data + 1);
20931da177e4SLinus Torvalds 	int num_rsp = *((__u8 *) skb->data);
20941da177e4SLinus Torvalds 
20951da177e4SLinus Torvalds 	BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
20961da177e4SLinus Torvalds 
209745bb4bf0SMarcel Holtmann 	if (!num_rsp)
209845bb4bf0SMarcel Holtmann 		return;
209945bb4bf0SMarcel Holtmann 
2100d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ))
21011519cc17SAndre Guedes 		return;
21021519cc17SAndre Guedes 
21031da177e4SLinus Torvalds 	hci_dev_lock(hdev);
210445bb4bf0SMarcel Holtmann 
2105e17acd40SJohan Hedberg 	for (; num_rsp; num_rsp--, info++) {
2106af58925cSMarcel Holtmann 		u32 flags;
21073175405bSJohan Hedberg 
21081da177e4SLinus Torvalds 		bacpy(&data.bdaddr, &info->bdaddr);
21091da177e4SLinus Torvalds 		data.pscan_rep_mode	= info->pscan_rep_mode;
21101da177e4SLinus Torvalds 		data.pscan_period_mode	= info->pscan_period_mode;
21111da177e4SLinus Torvalds 		data.pscan_mode		= info->pscan_mode;
21121da177e4SLinus Torvalds 		memcpy(data.dev_class, info->dev_class, 3);
21131da177e4SLinus Torvalds 		data.clock_offset	= info->clock_offset;
2114efb2513fSMarcel Holtmann 		data.rssi		= HCI_RSSI_INVALID;
211541a96212SMarcel Holtmann 		data.ssp_mode		= 0x00;
21163175405bSJohan Hedberg 
2117af58925cSMarcel Holtmann 		flags = hci_inquiry_cache_update(hdev, &data, false);
2118af58925cSMarcel Holtmann 
211948264f06SJohan Hedberg 		mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
2120efb2513fSMarcel Holtmann 				  info->dev_class, HCI_RSSI_INVALID,
2121efb2513fSMarcel Holtmann 				  flags, NULL, 0, NULL, 0);
21221da177e4SLinus Torvalds 	}
212345bb4bf0SMarcel Holtmann 
21241da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
21251da177e4SLinus Torvalds }
21261da177e4SLinus Torvalds 
21276039aa73SGustavo Padovan static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
21281da177e4SLinus Torvalds {
2129a9de9248SMarcel Holtmann 	struct hci_ev_conn_complete *ev = (void *) skb->data;
2130a9de9248SMarcel Holtmann 	struct hci_conn *conn;
21311da177e4SLinus Torvalds 
2132a9de9248SMarcel Holtmann 	BT_DBG("%s", hdev->name);
213345bb4bf0SMarcel Holtmann 
21341da177e4SLinus Torvalds 	hci_dev_lock(hdev);
213545bb4bf0SMarcel Holtmann 
2136a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
21379499237aSMarcel Holtmann 	if (!conn) {
21389499237aSMarcel Holtmann 		if (ev->link_type != SCO_LINK)
21399499237aSMarcel Holtmann 			goto unlock;
21409499237aSMarcel Holtmann 
21419499237aSMarcel Holtmann 		conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2142a9de9248SMarcel Holtmann 		if (!conn)
2143a9de9248SMarcel Holtmann 			goto unlock;
214445bb4bf0SMarcel Holtmann 
21459499237aSMarcel Holtmann 		conn->type = SCO_LINK;
21469499237aSMarcel Holtmann 	}
21479499237aSMarcel Holtmann 
2148a9de9248SMarcel Holtmann 	if (!ev->status) {
2149a9de9248SMarcel Holtmann 		conn->handle = __le16_to_cpu(ev->handle);
2150769be974SMarcel Holtmann 
2151769be974SMarcel Holtmann 		if (conn->type == ACL_LINK) {
2152769be974SMarcel Holtmann 			conn->state = BT_CONFIG;
2153769be974SMarcel Holtmann 			hci_conn_hold(conn);
2154a9ea3ed9SSzymon Janc 
2155a9ea3ed9SSzymon Janc 			if (!conn->out && !hci_conn_ssp_enabled(conn) &&
2156a9ea3ed9SSzymon Janc 			    !hci_find_link_key(hdev, &ev->bdaddr))
2157a9ea3ed9SSzymon Janc 				conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2158a9ea3ed9SSzymon Janc 			else
2159052b30b0SMarcel Holtmann 				conn->disc_timeout = HCI_DISCONN_TIMEOUT;
2160769be974SMarcel Holtmann 		} else
2161a9de9248SMarcel Holtmann 			conn->state = BT_CONNECTED;
2162a9de9248SMarcel Holtmann 
216323b9ceb7SMarcel Holtmann 		hci_debugfs_create_conn(conn);
21647d0db0a3SMarcel Holtmann 		hci_conn_add_sysfs(conn);
21657d0db0a3SMarcel Holtmann 
2166a9de9248SMarcel Holtmann 		if (test_bit(HCI_AUTH, &hdev->flags))
21674dae2798SJohan Hedberg 			set_bit(HCI_CONN_AUTH, &conn->flags);
2168a9de9248SMarcel Holtmann 
2169a9de9248SMarcel Holtmann 		if (test_bit(HCI_ENCRYPT, &hdev->flags))
21704dae2798SJohan Hedberg 			set_bit(HCI_CONN_ENCRYPT, &conn->flags);
2171a9de9248SMarcel Holtmann 
2172a9de9248SMarcel Holtmann 		/* Get remote features */
2173a9de9248SMarcel Holtmann 		if (conn->type == ACL_LINK) {
2174a9de9248SMarcel Holtmann 			struct hci_cp_read_remote_features cp;
2175a9de9248SMarcel Holtmann 			cp.handle = ev->handle;
2176769be974SMarcel Holtmann 			hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
2177769be974SMarcel Holtmann 				     sizeof(cp), &cp);
217822f433dcSJohan Hedberg 
217901b1cb87SJohan Hedberg 			hci_req_update_scan(hdev);
218045bb4bf0SMarcel Holtmann 		}
2181a9de9248SMarcel Holtmann 
2182a9de9248SMarcel Holtmann 		/* Set packet type for incoming connection */
2183d095c1ebSAndrei Emeltchenko 		if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
2184a9de9248SMarcel Holtmann 			struct hci_cp_change_conn_ptype cp;
2185a9de9248SMarcel Holtmann 			cp.handle = ev->handle;
2186a8746417SMarcel Holtmann 			cp.pkt_type = cpu_to_le16(conn->pkt_type);
218704124681SGustavo F. Padovan 			hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
218804124681SGustavo F. Padovan 				     &cp);
2189a9de9248SMarcel Holtmann 		}
219017d5c04cSJohan Hedberg 	} else {
2191a9de9248SMarcel Holtmann 		conn->state = BT_CLOSED;
219217d5c04cSJohan Hedberg 		if (conn->type == ACL_LINK)
219364c7b77cSMarcel Holtmann 			mgmt_connect_failed(hdev, &conn->dst, conn->type,
219448264f06SJohan Hedberg 					    conn->dst_type, ev->status);
219517d5c04cSJohan Hedberg 	}
219645bb4bf0SMarcel Holtmann 
2197e73439d8SMarcel Holtmann 	if (conn->type == ACL_LINK)
2198e73439d8SMarcel Holtmann 		hci_sco_setup(conn, ev->status);
219945bb4bf0SMarcel Holtmann 
2200769be974SMarcel Holtmann 	if (ev->status) {
2201539c496dSJohan Hedberg 		hci_connect_cfm(conn, ev->status);
2202a9de9248SMarcel Holtmann 		hci_conn_del(conn);
2203c89b6e6bSMarcel Holtmann 	} else if (ev->link_type != ACL_LINK)
2204539c496dSJohan Hedberg 		hci_connect_cfm(conn, ev->status);
2205a9de9248SMarcel Holtmann 
2206a9de9248SMarcel Holtmann unlock:
22071da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
2208a9de9248SMarcel Holtmann 
2209a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
22101da177e4SLinus Torvalds }
22111da177e4SLinus Torvalds 
221270c46425SJohan Hedberg static void hci_reject_conn(struct hci_dev *hdev, bdaddr_t *bdaddr)
221370c46425SJohan Hedberg {
221470c46425SJohan Hedberg 	struct hci_cp_reject_conn_req cp;
221570c46425SJohan Hedberg 
221670c46425SJohan Hedberg 	bacpy(&cp.bdaddr, bdaddr);
221770c46425SJohan Hedberg 	cp.reason = HCI_ERROR_REJ_BAD_ADDR;
221870c46425SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
221970c46425SJohan Hedberg }
222070c46425SJohan Hedberg 
22216039aa73SGustavo Padovan static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
22221da177e4SLinus Torvalds {
2223a9de9248SMarcel Holtmann 	struct hci_ev_conn_request *ev = (void *) skb->data;
22241da177e4SLinus Torvalds 	int mask = hdev->link_mode;
222570c46425SJohan Hedberg 	struct inquiry_entry *ie;
222670c46425SJohan Hedberg 	struct hci_conn *conn;
222720714bfeSFrédéric Dalleau 	__u8 flags = 0;
22281da177e4SLinus Torvalds 
22296ed93dc6SAndrei Emeltchenko 	BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
2230807deac2SGustavo Padovan 	       ev->link_type);
22311da177e4SLinus Torvalds 
223220714bfeSFrédéric Dalleau 	mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
223320714bfeSFrédéric Dalleau 				      &flags);
22341da177e4SLinus Torvalds 
223570c46425SJohan Hedberg 	if (!(mask & HCI_LM_ACCEPT)) {
223670c46425SJohan Hedberg 		hci_reject_conn(hdev, &ev->bdaddr);
223770c46425SJohan Hedberg 		return;
223870c46425SJohan Hedberg 	}
223970c46425SJohan Hedberg 
2240a55bd29dSJohan Hedberg 	if (hci_bdaddr_list_lookup(&hdev->blacklist, &ev->bdaddr,
2241dcc36c16SJohan Hedberg 				   BDADDR_BREDR)) {
224270c46425SJohan Hedberg 		hci_reject_conn(hdev, &ev->bdaddr);
224370c46425SJohan Hedberg 		return;
224470c46425SJohan Hedberg 	}
224546c4c941SJohan Hedberg 
22466a8fc95cSJohan Hedberg 	/* Require HCI_CONNECTABLE or a whitelist entry to accept the
22476a8fc95cSJohan Hedberg 	 * connection. These features are only touched through mgmt so
22486a8fc95cSJohan Hedberg 	 * only do the checks if HCI_MGMT is set.
22496a8fc95cSJohan Hedberg 	 */
2250d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT) &&
2251d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONNECTABLE) &&
225246c4c941SJohan Hedberg 	    !hci_bdaddr_list_lookup(&hdev->whitelist, &ev->bdaddr,
2253a55bd29dSJohan Hedberg 				    BDADDR_BREDR)) {
2254a55bd29dSJohan Hedberg 		    hci_reject_conn(hdev, &ev->bdaddr);
2255a55bd29dSJohan Hedberg 		    return;
2256a55bd29dSJohan Hedberg 	}
225770c46425SJohan Hedberg 
22581da177e4SLinus Torvalds 	/* Connection accepted */
22591da177e4SLinus Torvalds 
22601da177e4SLinus Torvalds 	hci_dev_lock(hdev);
2261b6a0dc82SMarcel Holtmann 
2262cc11b9c1SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2263cc11b9c1SAndrei Emeltchenko 	if (ie)
2264c7bdd502SMarcel Holtmann 		memcpy(ie->data.dev_class, ev->dev_class, 3);
2265c7bdd502SMarcel Holtmann 
22668fc9ced3SGustavo Padovan 	conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
22678fc9ced3SGustavo Padovan 			&ev->bdaddr);
22681da177e4SLinus Torvalds 	if (!conn) {
2269a5c4e309SJohan Hedberg 		conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr,
2270a5c4e309SJohan Hedberg 				    HCI_ROLE_SLAVE);
2271cc11b9c1SAndrei Emeltchenko 		if (!conn) {
2272893ef971SGustavo F. Padovan 			BT_ERR("No memory for new connection");
22731da177e4SLinus Torvalds 			hci_dev_unlock(hdev);
22741da177e4SLinus Torvalds 			return;
22751da177e4SLinus Torvalds 		}
22761da177e4SLinus Torvalds 	}
2277b6a0dc82SMarcel Holtmann 
22781da177e4SLinus Torvalds 	memcpy(conn->dev_class, ev->dev_class, 3);
2279b6a0dc82SMarcel Holtmann 
22801da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
22811da177e4SLinus Torvalds 
228220714bfeSFrédéric Dalleau 	if (ev->link_type == ACL_LINK ||
228320714bfeSFrédéric Dalleau 	    (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
2284b6a0dc82SMarcel Holtmann 		struct hci_cp_accept_conn_req cp;
228520714bfeSFrédéric Dalleau 		conn->state = BT_CONNECT;
2286b6a0dc82SMarcel Holtmann 
22871da177e4SLinus Torvalds 		bacpy(&cp.bdaddr, &ev->bdaddr);
22881da177e4SLinus Torvalds 
22891da177e4SLinus Torvalds 		if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
22901da177e4SLinus Torvalds 			cp.role = 0x00; /* Become master */
22911da177e4SLinus Torvalds 		else
22921da177e4SLinus Torvalds 			cp.role = 0x01; /* Remain slave */
22931da177e4SLinus Torvalds 
229470c46425SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp);
229520714bfeSFrédéric Dalleau 	} else if (!(flags & HCI_PROTO_DEFER)) {
2296b6a0dc82SMarcel Holtmann 		struct hci_cp_accept_sync_conn_req cp;
229720714bfeSFrédéric Dalleau 		conn->state = BT_CONNECT;
2298b6a0dc82SMarcel Holtmann 
2299b6a0dc82SMarcel Holtmann 		bacpy(&cp.bdaddr, &ev->bdaddr);
2300a8746417SMarcel Holtmann 		cp.pkt_type = cpu_to_le16(conn->pkt_type);
2301b6a0dc82SMarcel Holtmann 
2302dcf4adbfSJoe Perches 		cp.tx_bandwidth   = cpu_to_le32(0x00001f40);
2303dcf4adbfSJoe Perches 		cp.rx_bandwidth   = cpu_to_le32(0x00001f40);
2304dcf4adbfSJoe Perches 		cp.max_latency    = cpu_to_le16(0xffff);
2305b6a0dc82SMarcel Holtmann 		cp.content_format = cpu_to_le16(hdev->voice_setting);
2306b6a0dc82SMarcel Holtmann 		cp.retrans_effort = 0xff;
2307b6a0dc82SMarcel Holtmann 
230870c46425SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, sizeof(cp),
230970c46425SJohan Hedberg 			     &cp);
231020714bfeSFrédéric Dalleau 	} else {
231120714bfeSFrédéric Dalleau 		conn->state = BT_CONNECT2;
2312539c496dSJohan Hedberg 		hci_connect_cfm(conn, 0);
2313b6a0dc82SMarcel Holtmann 	}
23141da177e4SLinus Torvalds }
23151da177e4SLinus Torvalds 
2316f0d6a0eaSMikel Astiz static u8 hci_to_mgmt_reason(u8 err)
2317f0d6a0eaSMikel Astiz {
2318f0d6a0eaSMikel Astiz 	switch (err) {
2319f0d6a0eaSMikel Astiz 	case HCI_ERROR_CONNECTION_TIMEOUT:
2320f0d6a0eaSMikel Astiz 		return MGMT_DEV_DISCONN_TIMEOUT;
2321f0d6a0eaSMikel Astiz 	case HCI_ERROR_REMOTE_USER_TERM:
2322f0d6a0eaSMikel Astiz 	case HCI_ERROR_REMOTE_LOW_RESOURCES:
2323f0d6a0eaSMikel Astiz 	case HCI_ERROR_REMOTE_POWER_OFF:
2324f0d6a0eaSMikel Astiz 		return MGMT_DEV_DISCONN_REMOTE;
2325f0d6a0eaSMikel Astiz 	case HCI_ERROR_LOCAL_HOST_TERM:
2326f0d6a0eaSMikel Astiz 		return MGMT_DEV_DISCONN_LOCAL_HOST;
2327f0d6a0eaSMikel Astiz 	default:
2328f0d6a0eaSMikel Astiz 		return MGMT_DEV_DISCONN_UNKNOWN;
2329f0d6a0eaSMikel Astiz 	}
2330f0d6a0eaSMikel Astiz }
2331f0d6a0eaSMikel Astiz 
23326039aa73SGustavo Padovan static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
23331da177e4SLinus Torvalds {
2334a9de9248SMarcel Holtmann 	struct hci_ev_disconn_complete *ev = (void *) skb->data;
2335abf54a50SAndre Guedes 	u8 reason = hci_to_mgmt_reason(ev->reason);
23369fcb18efSAndre Guedes 	struct hci_conn_params *params;
233704837f64SMarcel Holtmann 	struct hci_conn *conn;
233812d4a3b2SJohan Hedberg 	bool mgmt_connected;
23393846220bSAndre Guedes 	u8 type;
23401da177e4SLinus Torvalds 
23419f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
23421da177e4SLinus Torvalds 
23431da177e4SLinus Torvalds 	hci_dev_lock(hdev);
23441da177e4SLinus Torvalds 
234504837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2346f7520543SJohan Hedberg 	if (!conn)
2347f7520543SJohan Hedberg 		goto unlock;
2348f7520543SJohan Hedberg 
2349f0d6a0eaSMikel Astiz 	if (ev->status) {
235088c3df13SJohan Hedberg 		mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
235188c3df13SJohan Hedberg 				       conn->dst_type, ev->status);
2352abf54a50SAndre Guedes 		goto unlock;
2353abf54a50SAndre Guedes 	}
2354f0d6a0eaSMikel Astiz 
23553846220bSAndre Guedes 	conn->state = BT_CLOSED;
23563846220bSAndre Guedes 
235712d4a3b2SJohan Hedberg 	mgmt_connected = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
235812d4a3b2SJohan Hedberg 	mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type,
235912d4a3b2SJohan Hedberg 				reason, mgmt_connected);
2360f7520543SJohan Hedberg 
236122f433dcSJohan Hedberg 	if (conn->type == ACL_LINK) {
236222f433dcSJohan Hedberg 		if (test_bit(HCI_CONN_FLUSH_KEY, &conn->flags))
23636ec5bcadSVishal Agarwal 			hci_remove_link_key(hdev, &conn->dst);
23643846220bSAndre Guedes 
236501b1cb87SJohan Hedberg 		hci_req_update_scan(hdev);
236622f433dcSJohan Hedberg 	}
236722f433dcSJohan Hedberg 
23689fcb18efSAndre Guedes 	params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
23699fcb18efSAndre Guedes 	if (params) {
23709fcb18efSAndre Guedes 		switch (params->auto_connect) {
23719fcb18efSAndre Guedes 		case HCI_AUTO_CONN_LINK_LOSS:
23729fcb18efSAndre Guedes 			if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT)
23739fcb18efSAndre Guedes 				break;
23749fcb18efSAndre Guedes 			/* Fall through */
23759fcb18efSAndre Guedes 
23764b9e7e75SMarcel Holtmann 		case HCI_AUTO_CONN_DIRECT:
23779fcb18efSAndre Guedes 		case HCI_AUTO_CONN_ALWAYS:
2378418025d1SJohan Hedberg 			list_del_init(&params->action);
2379418025d1SJohan Hedberg 			list_add(&params->action, &hdev->pend_le_conns);
2380418025d1SJohan Hedberg 			hci_update_background_scan(hdev);
23819fcb18efSAndre Guedes 			break;
23829fcb18efSAndre Guedes 
23839fcb18efSAndre Guedes 		default:
23849fcb18efSAndre Guedes 			break;
23859fcb18efSAndre Guedes 		}
23869fcb18efSAndre Guedes 	}
23879fcb18efSAndre Guedes 
23883846220bSAndre Guedes 	type = conn->type;
23893846220bSAndre Guedes 
23903a6d576bSJohan Hedberg 	hci_disconn_cfm(conn, ev->reason);
23911da177e4SLinus Torvalds 	hci_conn_del(conn);
23922210246cSJohan Hedberg 
23932210246cSJohan Hedberg 	/* Re-enable advertising if necessary, since it might
23942210246cSJohan Hedberg 	 * have been disabled by the connection. From the
23952210246cSJohan Hedberg 	 * HCI_LE_Set_Advertise_Enable command description in
23962210246cSJohan Hedberg 	 * the core specification (v4.0):
23972210246cSJohan Hedberg 	 * "The Controller shall continue advertising until the Host
23982210246cSJohan Hedberg 	 * issues an LE_Set_Advertise_Enable command with
23992210246cSJohan Hedberg 	 * Advertising_Enable set to 0x00 (Advertising is disabled)
24002210246cSJohan Hedberg 	 * or until a connection is created or until the Advertising
24012210246cSJohan Hedberg 	 * is timed out due to Directed Advertising."
24022210246cSJohan Hedberg 	 */
24032210246cSJohan Hedberg 	if (type == LE_LINK)
2404f2252570SJohan Hedberg 		hci_req_reenable_advertising(hdev);
24051da177e4SLinus Torvalds 
2406f7520543SJohan Hedberg unlock:
24071da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
24081da177e4SLinus Torvalds }
24091da177e4SLinus Torvalds 
24106039aa73SGustavo Padovan static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2411a9de9248SMarcel Holtmann {
2412a9de9248SMarcel Holtmann 	struct hci_ev_auth_complete *ev = (void *) skb->data;
2413a9de9248SMarcel Holtmann 	struct hci_conn *conn;
2414a9de9248SMarcel Holtmann 
24159f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
2416a9de9248SMarcel Holtmann 
2417a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
2418a9de9248SMarcel Holtmann 
2419a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2420d7556e20SWaldemar Rymarkiewicz 	if (!conn)
2421d7556e20SWaldemar Rymarkiewicz 		goto unlock;
2422d7556e20SWaldemar Rymarkiewicz 
2423765c2a96SJohan Hedberg 	if (!ev->status) {
2424aa64a8b5SJohan Hedberg 		if (!hci_conn_ssp_enabled(conn) &&
242551a8efd7SJohan Hedberg 		    test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
2426d7556e20SWaldemar Rymarkiewicz 			BT_INFO("re-auth of legacy device is not possible.");
242719f8def0SWaldemar Rymarkiewicz 		} else {
24284dae2798SJohan Hedberg 			set_bit(HCI_CONN_AUTH, &conn->flags);
2429765c2a96SJohan Hedberg 			conn->sec_level = conn->pending_sec_level;
243019f8def0SWaldemar Rymarkiewicz 		}
24312a611692SJohan Hedberg 	} else {
2432e1e930f5SJohan Hedberg 		mgmt_auth_failed(conn, ev->status);
24332a611692SJohan Hedberg 	}
2434a9de9248SMarcel Holtmann 
243551a8efd7SJohan Hedberg 	clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
243651a8efd7SJohan Hedberg 	clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
2437a9de9248SMarcel Holtmann 
2438f8558555SMarcel Holtmann 	if (conn->state == BT_CONFIG) {
2439aa64a8b5SJohan Hedberg 		if (!ev->status && hci_conn_ssp_enabled(conn)) {
2440f8558555SMarcel Holtmann 			struct hci_cp_set_conn_encrypt cp;
2441f8558555SMarcel Holtmann 			cp.handle  = ev->handle;
2442f8558555SMarcel Holtmann 			cp.encrypt = 0x01;
2443d7556e20SWaldemar Rymarkiewicz 			hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
2444d7556e20SWaldemar Rymarkiewicz 				     &cp);
2445f8558555SMarcel Holtmann 		} else {
2446f8558555SMarcel Holtmann 			conn->state = BT_CONNECTED;
2447539c496dSJohan Hedberg 			hci_connect_cfm(conn, ev->status);
244876a68ba0SDavid Herrmann 			hci_conn_drop(conn);
2449f8558555SMarcel Holtmann 		}
2450052b30b0SMarcel Holtmann 	} else {
2451a9de9248SMarcel Holtmann 		hci_auth_cfm(conn, ev->status);
2452a9de9248SMarcel Holtmann 
2453052b30b0SMarcel Holtmann 		hci_conn_hold(conn);
2454052b30b0SMarcel Holtmann 		conn->disc_timeout = HCI_DISCONN_TIMEOUT;
245576a68ba0SDavid Herrmann 		hci_conn_drop(conn);
2456052b30b0SMarcel Holtmann 	}
2457052b30b0SMarcel Holtmann 
245851a8efd7SJohan Hedberg 	if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
2459a9de9248SMarcel Holtmann 		if (!ev->status) {
2460a9de9248SMarcel Holtmann 			struct hci_cp_set_conn_encrypt cp;
2461f8558555SMarcel Holtmann 			cp.handle  = ev->handle;
2462f8558555SMarcel Holtmann 			cp.encrypt = 0x01;
2463d7556e20SWaldemar Rymarkiewicz 			hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
2464d7556e20SWaldemar Rymarkiewicz 				     &cp);
2465a9de9248SMarcel Holtmann 		} else {
246651a8efd7SJohan Hedberg 			clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
2467a9de9248SMarcel Holtmann 			hci_encrypt_cfm(conn, ev->status, 0x00);
2468a9de9248SMarcel Holtmann 		}
2469a9de9248SMarcel Holtmann 	}
2470a9de9248SMarcel Holtmann 
2471d7556e20SWaldemar Rymarkiewicz unlock:
2472a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
2473a9de9248SMarcel Holtmann }
2474a9de9248SMarcel Holtmann 
24756039aa73SGustavo Padovan static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
2476a9de9248SMarcel Holtmann {
2477127178d2SJohan Hedberg 	struct hci_ev_remote_name *ev = (void *) skb->data;
2478127178d2SJohan Hedberg 	struct hci_conn *conn;
2479127178d2SJohan Hedberg 
2480a9de9248SMarcel Holtmann 	BT_DBG("%s", hdev->name);
2481a9de9248SMarcel Holtmann 
2482a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
2483127178d2SJohan Hedberg 
2484127178d2SJohan Hedberg 	hci_dev_lock(hdev);
2485127178d2SJohan Hedberg 
2486127178d2SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2487b644ba33SJohan Hedberg 
2488d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
2489b644ba33SJohan Hedberg 		goto check_auth;
2490b644ba33SJohan Hedberg 
2491b644ba33SJohan Hedberg 	if (ev->status == 0)
2492b644ba33SJohan Hedberg 		hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
2493b644ba33SJohan Hedberg 				       strnlen(ev->name, HCI_MAX_NAME_LENGTH));
2494b644ba33SJohan Hedberg 	else
2495b644ba33SJohan Hedberg 		hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
2496b644ba33SJohan Hedberg 
2497b644ba33SJohan Hedberg check_auth:
249879c6c70cSJohan Hedberg 	if (!conn)
249979c6c70cSJohan Hedberg 		goto unlock;
250079c6c70cSJohan Hedberg 
250179c6c70cSJohan Hedberg 	if (!hci_outgoing_auth_needed(hdev, conn))
250279c6c70cSJohan Hedberg 		goto unlock;
250379c6c70cSJohan Hedberg 
250451a8efd7SJohan Hedberg 	if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
2505127178d2SJohan Hedberg 		struct hci_cp_auth_requested cp;
2506977f8fceSJohan Hedberg 
2507977f8fceSJohan Hedberg 		set_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags);
2508977f8fceSJohan Hedberg 
2509127178d2SJohan Hedberg 		cp.handle = __cpu_to_le16(conn->handle);
2510127178d2SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
2511127178d2SJohan Hedberg 	}
2512127178d2SJohan Hedberg 
251379c6c70cSJohan Hedberg unlock:
2514127178d2SJohan Hedberg 	hci_dev_unlock(hdev);
2515a9de9248SMarcel Holtmann }
2516a9de9248SMarcel Holtmann 
2517821f3766SJohan Hedberg static void read_enc_key_size_complete(struct hci_dev *hdev, u8 status,
2518821f3766SJohan Hedberg 				       u16 opcode, struct sk_buff *skb)
2519821f3766SJohan Hedberg {
2520821f3766SJohan Hedberg 	const struct hci_rp_read_enc_key_size *rp;
2521821f3766SJohan Hedberg 	struct hci_conn *conn;
2522821f3766SJohan Hedberg 	u16 handle;
2523821f3766SJohan Hedberg 
2524821f3766SJohan Hedberg 	BT_DBG("%s status 0x%02x", hdev->name, status);
2525821f3766SJohan Hedberg 
2526821f3766SJohan Hedberg 	if (!skb || skb->len < sizeof(*rp)) {
2527821f3766SJohan Hedberg 		BT_ERR("%s invalid HCI Read Encryption Key Size response",
2528821f3766SJohan Hedberg 		       hdev->name);
2529821f3766SJohan Hedberg 		return;
2530821f3766SJohan Hedberg 	}
2531821f3766SJohan Hedberg 
2532821f3766SJohan Hedberg 	rp = (void *)skb->data;
2533821f3766SJohan Hedberg 	handle = le16_to_cpu(rp->handle);
2534821f3766SJohan Hedberg 
2535821f3766SJohan Hedberg 	hci_dev_lock(hdev);
2536821f3766SJohan Hedberg 
2537821f3766SJohan Hedberg 	conn = hci_conn_hash_lookup_handle(hdev, handle);
2538821f3766SJohan Hedberg 	if (!conn)
2539821f3766SJohan Hedberg 		goto unlock;
2540821f3766SJohan Hedberg 
2541821f3766SJohan Hedberg 	/* If we fail to read the encryption key size, assume maximum
2542821f3766SJohan Hedberg 	 * (which is the same we do also when this HCI command isn't
2543821f3766SJohan Hedberg 	 * supported.
2544821f3766SJohan Hedberg 	 */
2545821f3766SJohan Hedberg 	if (rp->status) {
2546821f3766SJohan Hedberg 		BT_ERR("%s failed to read key size for handle %u", hdev->name,
2547821f3766SJohan Hedberg 		       handle);
2548821f3766SJohan Hedberg 		conn->enc_key_size = HCI_LINK_KEY_SIZE;
2549821f3766SJohan Hedberg 	} else {
2550821f3766SJohan Hedberg 		conn->enc_key_size = rp->key_size;
2551821f3766SJohan Hedberg 	}
2552821f3766SJohan Hedberg 
2553821f3766SJohan Hedberg 	if (conn->state == BT_CONFIG) {
2554821f3766SJohan Hedberg 		conn->state = BT_CONNECTED;
2555821f3766SJohan Hedberg 		hci_connect_cfm(conn, 0);
2556821f3766SJohan Hedberg 		hci_conn_drop(conn);
2557821f3766SJohan Hedberg 	} else {
2558821f3766SJohan Hedberg 		u8 encrypt;
2559821f3766SJohan Hedberg 
2560821f3766SJohan Hedberg 		if (!test_bit(HCI_CONN_ENCRYPT, &conn->flags))
2561821f3766SJohan Hedberg 			encrypt = 0x00;
25625d667ef6SJohan Hedberg 		else if (test_bit(HCI_CONN_AES_CCM, &conn->flags))
2563821f3766SJohan Hedberg 			encrypt = 0x02;
2564821f3766SJohan Hedberg 		else
2565821f3766SJohan Hedberg 			encrypt = 0x01;
2566821f3766SJohan Hedberg 
2567821f3766SJohan Hedberg 		hci_encrypt_cfm(conn, 0, encrypt);
2568821f3766SJohan Hedberg 	}
2569821f3766SJohan Hedberg 
2570821f3766SJohan Hedberg unlock:
2571821f3766SJohan Hedberg 	hci_dev_unlock(hdev);
2572821f3766SJohan Hedberg }
2573821f3766SJohan Hedberg 
25746039aa73SGustavo Padovan static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2575a9de9248SMarcel Holtmann {
2576a9de9248SMarcel Holtmann 	struct hci_ev_encrypt_change *ev = (void *) skb->data;
2577a9de9248SMarcel Holtmann 	struct hci_conn *conn;
2578a9de9248SMarcel Holtmann 
25799f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
2580a9de9248SMarcel Holtmann 
2581a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
2582a9de9248SMarcel Holtmann 
2583a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2584dc8357ccSMarcel Holtmann 	if (!conn)
2585dc8357ccSMarcel Holtmann 		goto unlock;
2586dc8357ccSMarcel Holtmann 
2587a9de9248SMarcel Holtmann 	if (!ev->status) {
2588ae293196SMarcel Holtmann 		if (ev->encrypt) {
2589ae293196SMarcel Holtmann 			/* Encryption implies authentication */
25904dae2798SJohan Hedberg 			set_bit(HCI_CONN_AUTH, &conn->flags);
25914dae2798SJohan Hedberg 			set_bit(HCI_CONN_ENCRYPT, &conn->flags);
2592da85e5e5SVinicius Costa Gomes 			conn->sec_level = conn->pending_sec_level;
2593abf76badSMarcel Holtmann 
2594914a6ffeSMarcel Holtmann 			/* P-256 authentication key implies FIPS */
2595914a6ffeSMarcel Holtmann 			if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256)
25964dae2798SJohan Hedberg 				set_bit(HCI_CONN_FIPS, &conn->flags);
2597914a6ffeSMarcel Holtmann 
2598abf76badSMarcel Holtmann 			if ((conn->type == ACL_LINK && ev->encrypt == 0x02) ||
2599abf76badSMarcel Holtmann 			    conn->type == LE_LINK)
2600abf76badSMarcel Holtmann 				set_bit(HCI_CONN_AES_CCM, &conn->flags);
2601abf76badSMarcel Holtmann 		} else {
26024dae2798SJohan Hedberg 			clear_bit(HCI_CONN_ENCRYPT, &conn->flags);
2603abf76badSMarcel Holtmann 			clear_bit(HCI_CONN_AES_CCM, &conn->flags);
2604abf76badSMarcel Holtmann 		}
2605a9de9248SMarcel Holtmann 	}
2606a9de9248SMarcel Holtmann 
26077ed3fa20SJohan Hedberg 	/* We should disregard the current RPA and generate a new one
26087ed3fa20SJohan Hedberg 	 * whenever the encryption procedure fails.
26097ed3fa20SJohan Hedberg 	 */
26107ed3fa20SJohan Hedberg 	if (ev->status && conn->type == LE_LINK)
2611a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
26127ed3fa20SJohan Hedberg 
261351a8efd7SJohan Hedberg 	clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
2614a9de9248SMarcel Holtmann 
2615a7d7723aSGustavo Padovan 	if (ev->status && conn->state == BT_CONNECTED) {
2616bed71748SAndre Guedes 		hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
261776a68ba0SDavid Herrmann 		hci_conn_drop(conn);
2618a7d7723aSGustavo Padovan 		goto unlock;
2619a7d7723aSGustavo Padovan 	}
2620a7d7723aSGustavo Padovan 
2621035ad621SJohan Hedberg 	/* In Secure Connections Only mode, do not allow any connections
2622035ad621SJohan Hedberg 	 * that are not encrypted with AES-CCM using a P-256 authenticated
2623035ad621SJohan Hedberg 	 * combination key.
262440b552aaSMarcel Holtmann 	 */
2625d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SC_ONLY) &&
262640b552aaSMarcel Holtmann 	    (!test_bit(HCI_CONN_AES_CCM, &conn->flags) ||
262740b552aaSMarcel Holtmann 	     conn->key_type != HCI_LK_AUTH_COMBINATION_P256)) {
2628539c496dSJohan Hedberg 		hci_connect_cfm(conn, HCI_ERROR_AUTH_FAILURE);
262940b552aaSMarcel Holtmann 		hci_conn_drop(conn);
263040b552aaSMarcel Holtmann 		goto unlock;
263140b552aaSMarcel Holtmann 	}
263240b552aaSMarcel Holtmann 
2633821f3766SJohan Hedberg 	/* Try reading the encryption key size for encrypted ACL links */
2634821f3766SJohan Hedberg 	if (!ev->status && ev->encrypt && conn->type == ACL_LINK) {
2635821f3766SJohan Hedberg 		struct hci_cp_read_enc_key_size cp;
2636821f3766SJohan Hedberg 		struct hci_request req;
2637821f3766SJohan Hedberg 
2638821f3766SJohan Hedberg 		/* Only send HCI_Read_Encryption_Key_Size if the
2639821f3766SJohan Hedberg 		 * controller really supports it. If it doesn't, assume
2640821f3766SJohan Hedberg 		 * the default size (16).
2641821f3766SJohan Hedberg 		 */
2642821f3766SJohan Hedberg 		if (!(hdev->commands[20] & 0x10)) {
2643821f3766SJohan Hedberg 			conn->enc_key_size = HCI_LINK_KEY_SIZE;
2644821f3766SJohan Hedberg 			goto notify;
2645821f3766SJohan Hedberg 		}
2646821f3766SJohan Hedberg 
2647821f3766SJohan Hedberg 		hci_req_init(&req, hdev);
2648821f3766SJohan Hedberg 
2649821f3766SJohan Hedberg 		cp.handle = cpu_to_le16(conn->handle);
2650821f3766SJohan Hedberg 		hci_req_add(&req, HCI_OP_READ_ENC_KEY_SIZE, sizeof(cp), &cp);
2651821f3766SJohan Hedberg 
2652821f3766SJohan Hedberg 		if (hci_req_run_skb(&req, read_enc_key_size_complete)) {
2653821f3766SJohan Hedberg 			BT_ERR("Sending HCI Read Encryption Key Size failed");
2654821f3766SJohan Hedberg 			conn->enc_key_size = HCI_LINK_KEY_SIZE;
2655821f3766SJohan Hedberg 			goto notify;
2656821f3766SJohan Hedberg 		}
2657821f3766SJohan Hedberg 
2658821f3766SJohan Hedberg 		goto unlock;
2659821f3766SJohan Hedberg 	}
2660821f3766SJohan Hedberg 
2661821f3766SJohan Hedberg notify:
2662035ad621SJohan Hedberg 	if (conn->state == BT_CONFIG) {
2663035ad621SJohan Hedberg 		if (!ev->status)
2664035ad621SJohan Hedberg 			conn->state = BT_CONNECTED;
2665035ad621SJohan Hedberg 
2666539c496dSJohan Hedberg 		hci_connect_cfm(conn, ev->status);
266776a68ba0SDavid Herrmann 		hci_conn_drop(conn);
2668f8558555SMarcel Holtmann 	} else
2669a9de9248SMarcel Holtmann 		hci_encrypt_cfm(conn, ev->status, ev->encrypt);
2670a9de9248SMarcel Holtmann 
2671a7d7723aSGustavo Padovan unlock:
2672a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
2673a9de9248SMarcel Holtmann }
2674a9de9248SMarcel Holtmann 
26756039aa73SGustavo Padovan static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
2676807deac2SGustavo Padovan 					     struct sk_buff *skb)
2677a9de9248SMarcel Holtmann {
2678a9de9248SMarcel Holtmann 	struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2679a9de9248SMarcel Holtmann 	struct hci_conn *conn;
2680a9de9248SMarcel Holtmann 
26819f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
2682a9de9248SMarcel Holtmann 
2683a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
2684a9de9248SMarcel Holtmann 
2685a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2686a9de9248SMarcel Holtmann 	if (conn) {
2687a9de9248SMarcel Holtmann 		if (!ev->status)
26884dae2798SJohan Hedberg 			set_bit(HCI_CONN_SECURE, &conn->flags);
2689a9de9248SMarcel Holtmann 
269051a8efd7SJohan Hedberg 		clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
2691a9de9248SMarcel Holtmann 
2692a9de9248SMarcel Holtmann 		hci_key_change_cfm(conn, ev->status);
2693a9de9248SMarcel Holtmann 	}
2694a9de9248SMarcel Holtmann 
2695a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
2696a9de9248SMarcel Holtmann }
2697a9de9248SMarcel Holtmann 
26986039aa73SGustavo Padovan static void hci_remote_features_evt(struct hci_dev *hdev,
2699807deac2SGustavo Padovan 				    struct sk_buff *skb)
2700a9de9248SMarcel Holtmann {
2701a9de9248SMarcel Holtmann 	struct hci_ev_remote_features *ev = (void *) skb->data;
2702a9de9248SMarcel Holtmann 	struct hci_conn *conn;
2703a9de9248SMarcel Holtmann 
27049f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
2705a9de9248SMarcel Holtmann 
2706a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
2707a9de9248SMarcel Holtmann 
2708a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2709ccd556feSJohan Hedberg 	if (!conn)
2710ccd556feSJohan Hedberg 		goto unlock;
2711ccd556feSJohan Hedberg 
2712769be974SMarcel Holtmann 	if (!ev->status)
2713cad718edSJohan Hedberg 		memcpy(conn->features[0], ev->features, 8);
2714a9de9248SMarcel Holtmann 
2715ccd556feSJohan Hedberg 	if (conn->state != BT_CONFIG)
2716ccd556feSJohan Hedberg 		goto unlock;
2717ccd556feSJohan Hedberg 
2718ac363cf9SSzymon Janc 	if (!ev->status && lmp_ext_feat_capable(hdev) &&
2719ac363cf9SSzymon Janc 	    lmp_ext_feat_capable(conn)) {
2720769be974SMarcel Holtmann 		struct hci_cp_read_remote_ext_features cp;
2721769be974SMarcel Holtmann 		cp.handle = ev->handle;
2722769be974SMarcel Holtmann 		cp.page = 0x01;
2723ccd556feSJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
2724769be974SMarcel Holtmann 			     sizeof(cp), &cp);
2725392599b9SJohan Hedberg 		goto unlock;
2726392599b9SJohan Hedberg 	}
2727392599b9SJohan Hedberg 
2728671267bfSJohan Hedberg 	if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
2729127178d2SJohan Hedberg 		struct hci_cp_remote_name_req cp;
2730127178d2SJohan Hedberg 		memset(&cp, 0, sizeof(cp));
2731127178d2SJohan Hedberg 		bacpy(&cp.bdaddr, &conn->dst);
2732127178d2SJohan Hedberg 		cp.pscan_rep_mode = 0x02;
2733127178d2SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
2734b644ba33SJohan Hedberg 	} else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
273548ec92faSAlfonso Acosta 		mgmt_device_connected(hdev, conn, 0, NULL, 0);
2736392599b9SJohan Hedberg 
2737127178d2SJohan Hedberg 	if (!hci_outgoing_auth_needed(hdev, conn)) {
2738769be974SMarcel Holtmann 		conn->state = BT_CONNECTED;
2739539c496dSJohan Hedberg 		hci_connect_cfm(conn, ev->status);
274076a68ba0SDavid Herrmann 		hci_conn_drop(conn);
2741769be974SMarcel Holtmann 	}
2742769be974SMarcel Holtmann 
2743ccd556feSJohan Hedberg unlock:
2744a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
2745a9de9248SMarcel Holtmann }
2746a9de9248SMarcel Holtmann 
2747e6214487SJohan Hedberg static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb,
2748e6214487SJohan Hedberg 				 u16 *opcode, u8 *status,
2749e6214487SJohan Hedberg 				 hci_req_complete_t *req_complete,
2750e6214487SJohan Hedberg 				 hci_req_complete_skb_t *req_complete_skb)
2751a9de9248SMarcel Holtmann {
2752a9de9248SMarcel Holtmann 	struct hci_ev_cmd_complete *ev = (void *) skb->data;
2753e6214487SJohan Hedberg 
2754e6214487SJohan Hedberg 	*opcode = __le16_to_cpu(ev->opcode);
2755e6214487SJohan Hedberg 	*status = skb->data[sizeof(*ev)];
2756a9de9248SMarcel Holtmann 
2757a9de9248SMarcel Holtmann 	skb_pull(skb, sizeof(*ev));
2758a9de9248SMarcel Holtmann 
2759e6214487SJohan Hedberg 	switch (*opcode) {
2760a9de9248SMarcel Holtmann 	case HCI_OP_INQUIRY_CANCEL:
2761a9de9248SMarcel Holtmann 		hci_cc_inquiry_cancel(hdev, skb);
2762a9de9248SMarcel Holtmann 		break;
2763a9de9248SMarcel Holtmann 
27644d93483bSAndre Guedes 	case HCI_OP_PERIODIC_INQ:
27654d93483bSAndre Guedes 		hci_cc_periodic_inq(hdev, skb);
27664d93483bSAndre Guedes 		break;
27674d93483bSAndre Guedes 
2768a9de9248SMarcel Holtmann 	case HCI_OP_EXIT_PERIODIC_INQ:
2769a9de9248SMarcel Holtmann 		hci_cc_exit_periodic_inq(hdev, skb);
2770a9de9248SMarcel Holtmann 		break;
2771a9de9248SMarcel Holtmann 
2772a9de9248SMarcel Holtmann 	case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2773a9de9248SMarcel Holtmann 		hci_cc_remote_name_req_cancel(hdev, skb);
2774a9de9248SMarcel Holtmann 		break;
2775a9de9248SMarcel Holtmann 
2776a9de9248SMarcel Holtmann 	case HCI_OP_ROLE_DISCOVERY:
2777a9de9248SMarcel Holtmann 		hci_cc_role_discovery(hdev, skb);
2778a9de9248SMarcel Holtmann 		break;
2779a9de9248SMarcel Holtmann 
2780e4e8e37cSMarcel Holtmann 	case HCI_OP_READ_LINK_POLICY:
2781e4e8e37cSMarcel Holtmann 		hci_cc_read_link_policy(hdev, skb);
2782e4e8e37cSMarcel Holtmann 		break;
2783e4e8e37cSMarcel Holtmann 
2784a9de9248SMarcel Holtmann 	case HCI_OP_WRITE_LINK_POLICY:
2785a9de9248SMarcel Holtmann 		hci_cc_write_link_policy(hdev, skb);
2786a9de9248SMarcel Holtmann 		break;
2787a9de9248SMarcel Holtmann 
2788e4e8e37cSMarcel Holtmann 	case HCI_OP_READ_DEF_LINK_POLICY:
2789e4e8e37cSMarcel Holtmann 		hci_cc_read_def_link_policy(hdev, skb);
2790e4e8e37cSMarcel Holtmann 		break;
2791e4e8e37cSMarcel Holtmann 
2792e4e8e37cSMarcel Holtmann 	case HCI_OP_WRITE_DEF_LINK_POLICY:
2793e4e8e37cSMarcel Holtmann 		hci_cc_write_def_link_policy(hdev, skb);
2794e4e8e37cSMarcel Holtmann 		break;
2795e4e8e37cSMarcel Holtmann 
2796a9de9248SMarcel Holtmann 	case HCI_OP_RESET:
2797a9de9248SMarcel Holtmann 		hci_cc_reset(hdev, skb);
2798a9de9248SMarcel Holtmann 		break;
2799a9de9248SMarcel Holtmann 
2800c2f0f979SMarcel Holtmann 	case HCI_OP_READ_STORED_LINK_KEY:
2801c2f0f979SMarcel Holtmann 		hci_cc_read_stored_link_key(hdev, skb);
2802c2f0f979SMarcel Holtmann 		break;
2803c2f0f979SMarcel Holtmann 
2804a9366120SMarcel Holtmann 	case HCI_OP_DELETE_STORED_LINK_KEY:
2805a9366120SMarcel Holtmann 		hci_cc_delete_stored_link_key(hdev, skb);
2806a9366120SMarcel Holtmann 		break;
2807a9366120SMarcel Holtmann 
2808a9de9248SMarcel Holtmann 	case HCI_OP_WRITE_LOCAL_NAME:
2809a9de9248SMarcel Holtmann 		hci_cc_write_local_name(hdev, skb);
2810a9de9248SMarcel Holtmann 		break;
2811a9de9248SMarcel Holtmann 
2812a9de9248SMarcel Holtmann 	case HCI_OP_READ_LOCAL_NAME:
2813a9de9248SMarcel Holtmann 		hci_cc_read_local_name(hdev, skb);
2814a9de9248SMarcel Holtmann 		break;
2815a9de9248SMarcel Holtmann 
2816a9de9248SMarcel Holtmann 	case HCI_OP_WRITE_AUTH_ENABLE:
2817a9de9248SMarcel Holtmann 		hci_cc_write_auth_enable(hdev, skb);
2818a9de9248SMarcel Holtmann 		break;
2819a9de9248SMarcel Holtmann 
2820a9de9248SMarcel Holtmann 	case HCI_OP_WRITE_ENCRYPT_MODE:
2821a9de9248SMarcel Holtmann 		hci_cc_write_encrypt_mode(hdev, skb);
2822a9de9248SMarcel Holtmann 		break;
2823a9de9248SMarcel Holtmann 
2824a9de9248SMarcel Holtmann 	case HCI_OP_WRITE_SCAN_ENABLE:
2825a9de9248SMarcel Holtmann 		hci_cc_write_scan_enable(hdev, skb);
2826a9de9248SMarcel Holtmann 		break;
2827a9de9248SMarcel Holtmann 
2828a9de9248SMarcel Holtmann 	case HCI_OP_READ_CLASS_OF_DEV:
2829a9de9248SMarcel Holtmann 		hci_cc_read_class_of_dev(hdev, skb);
2830a9de9248SMarcel Holtmann 		break;
2831a9de9248SMarcel Holtmann 
2832a9de9248SMarcel Holtmann 	case HCI_OP_WRITE_CLASS_OF_DEV:
2833a9de9248SMarcel Holtmann 		hci_cc_write_class_of_dev(hdev, skb);
2834a9de9248SMarcel Holtmann 		break;
2835a9de9248SMarcel Holtmann 
2836a9de9248SMarcel Holtmann 	case HCI_OP_READ_VOICE_SETTING:
2837a9de9248SMarcel Holtmann 		hci_cc_read_voice_setting(hdev, skb);
2838a9de9248SMarcel Holtmann 		break;
2839a9de9248SMarcel Holtmann 
2840a9de9248SMarcel Holtmann 	case HCI_OP_WRITE_VOICE_SETTING:
2841a9de9248SMarcel Holtmann 		hci_cc_write_voice_setting(hdev, skb);
2842a9de9248SMarcel Holtmann 		break;
2843a9de9248SMarcel Holtmann 
2844b4cb9fb2SMarcel Holtmann 	case HCI_OP_READ_NUM_SUPPORTED_IAC:
2845b4cb9fb2SMarcel Holtmann 		hci_cc_read_num_supported_iac(hdev, skb);
2846b4cb9fb2SMarcel Holtmann 		break;
2847b4cb9fb2SMarcel Holtmann 
2848333140b5SMarcel Holtmann 	case HCI_OP_WRITE_SSP_MODE:
2849333140b5SMarcel Holtmann 		hci_cc_write_ssp_mode(hdev, skb);
2850333140b5SMarcel Holtmann 		break;
2851333140b5SMarcel Holtmann 
2852eac83dc6SMarcel Holtmann 	case HCI_OP_WRITE_SC_SUPPORT:
2853eac83dc6SMarcel Holtmann 		hci_cc_write_sc_support(hdev, skb);
2854eac83dc6SMarcel Holtmann 		break;
2855eac83dc6SMarcel Holtmann 
2856a9de9248SMarcel Holtmann 	case HCI_OP_READ_LOCAL_VERSION:
2857a9de9248SMarcel Holtmann 		hci_cc_read_local_version(hdev, skb);
2858a9de9248SMarcel Holtmann 		break;
2859a9de9248SMarcel Holtmann 
2860a9de9248SMarcel Holtmann 	case HCI_OP_READ_LOCAL_COMMANDS:
2861a9de9248SMarcel Holtmann 		hci_cc_read_local_commands(hdev, skb);
2862a9de9248SMarcel Holtmann 		break;
2863a9de9248SMarcel Holtmann 
2864a9de9248SMarcel Holtmann 	case HCI_OP_READ_LOCAL_FEATURES:
2865a9de9248SMarcel Holtmann 		hci_cc_read_local_features(hdev, skb);
2866a9de9248SMarcel Holtmann 		break;
2867a9de9248SMarcel Holtmann 
2868971e3a4bSAndre Guedes 	case HCI_OP_READ_LOCAL_EXT_FEATURES:
2869971e3a4bSAndre Guedes 		hci_cc_read_local_ext_features(hdev, skb);
2870971e3a4bSAndre Guedes 		break;
2871971e3a4bSAndre Guedes 
2872a9de9248SMarcel Holtmann 	case HCI_OP_READ_BUFFER_SIZE:
2873a9de9248SMarcel Holtmann 		hci_cc_read_buffer_size(hdev, skb);
2874a9de9248SMarcel Holtmann 		break;
2875a9de9248SMarcel Holtmann 
2876a9de9248SMarcel Holtmann 	case HCI_OP_READ_BD_ADDR:
2877a9de9248SMarcel Holtmann 		hci_cc_read_bd_addr(hdev, skb);
2878a9de9248SMarcel Holtmann 		break;
2879a9de9248SMarcel Holtmann 
2880f332ec66SJohan Hedberg 	case HCI_OP_READ_PAGE_SCAN_ACTIVITY:
2881f332ec66SJohan Hedberg 		hci_cc_read_page_scan_activity(hdev, skb);
2882f332ec66SJohan Hedberg 		break;
2883f332ec66SJohan Hedberg 
28844a3ee763SJohan Hedberg 	case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY:
28854a3ee763SJohan Hedberg 		hci_cc_write_page_scan_activity(hdev, skb);
28864a3ee763SJohan Hedberg 		break;
28874a3ee763SJohan Hedberg 
2888f332ec66SJohan Hedberg 	case HCI_OP_READ_PAGE_SCAN_TYPE:
2889f332ec66SJohan Hedberg 		hci_cc_read_page_scan_type(hdev, skb);
2890f332ec66SJohan Hedberg 		break;
2891f332ec66SJohan Hedberg 
28924a3ee763SJohan Hedberg 	case HCI_OP_WRITE_PAGE_SCAN_TYPE:
28934a3ee763SJohan Hedberg 		hci_cc_write_page_scan_type(hdev, skb);
28944a3ee763SJohan Hedberg 		break;
28954a3ee763SJohan Hedberg 
2896350ee4cfSAndrei Emeltchenko 	case HCI_OP_READ_DATA_BLOCK_SIZE:
2897350ee4cfSAndrei Emeltchenko 		hci_cc_read_data_block_size(hdev, skb);
2898350ee4cfSAndrei Emeltchenko 		break;
2899350ee4cfSAndrei Emeltchenko 
29001e89cffbSAndrei Emeltchenko 	case HCI_OP_READ_FLOW_CONTROL_MODE:
29011e89cffbSAndrei Emeltchenko 		hci_cc_read_flow_control_mode(hdev, skb);
29021e89cffbSAndrei Emeltchenko 		break;
29031e89cffbSAndrei Emeltchenko 
2904928abaa7SAndrei Emeltchenko 	case HCI_OP_READ_LOCAL_AMP_INFO:
2905928abaa7SAndrei Emeltchenko 		hci_cc_read_local_amp_info(hdev, skb);
2906928abaa7SAndrei Emeltchenko 		break;
2907928abaa7SAndrei Emeltchenko 
290833f35721SJohan Hedberg 	case HCI_OP_READ_CLOCK:
290933f35721SJohan Hedberg 		hci_cc_read_clock(hdev, skb);
291033f35721SJohan Hedberg 		break;
291133f35721SJohan Hedberg 
2912d5859e22SJohan Hedberg 	case HCI_OP_READ_INQ_RSP_TX_POWER:
2913d5859e22SJohan Hedberg 		hci_cc_read_inq_rsp_tx_power(hdev, skb);
2914d5859e22SJohan Hedberg 		break;
2915d5859e22SJohan Hedberg 
2916980e1a53SJohan Hedberg 	case HCI_OP_PIN_CODE_REPLY:
2917980e1a53SJohan Hedberg 		hci_cc_pin_code_reply(hdev, skb);
2918980e1a53SJohan Hedberg 		break;
2919980e1a53SJohan Hedberg 
2920980e1a53SJohan Hedberg 	case HCI_OP_PIN_CODE_NEG_REPLY:
2921980e1a53SJohan Hedberg 		hci_cc_pin_code_neg_reply(hdev, skb);
2922980e1a53SJohan Hedberg 		break;
2923980e1a53SJohan Hedberg 
2924c35938b2SSzymon Janc 	case HCI_OP_READ_LOCAL_OOB_DATA:
29254d2d2796SMarcel Holtmann 		hci_cc_read_local_oob_data(hdev, skb);
29264d2d2796SMarcel Holtmann 		break;
29274d2d2796SMarcel Holtmann 
29284d2d2796SMarcel Holtmann 	case HCI_OP_READ_LOCAL_OOB_EXT_DATA:
29294d2d2796SMarcel Holtmann 		hci_cc_read_local_oob_ext_data(hdev, skb);
2930c35938b2SSzymon Janc 		break;
2931c35938b2SSzymon Janc 
29326ed58ec5SVille Tervo 	case HCI_OP_LE_READ_BUFFER_SIZE:
29336ed58ec5SVille Tervo 		hci_cc_le_read_buffer_size(hdev, skb);
29346ed58ec5SVille Tervo 		break;
29356ed58ec5SVille Tervo 
293660e77321SJohan Hedberg 	case HCI_OP_LE_READ_LOCAL_FEATURES:
293760e77321SJohan Hedberg 		hci_cc_le_read_local_features(hdev, skb);
293860e77321SJohan Hedberg 		break;
293960e77321SJohan Hedberg 
29408fa19098SJohan Hedberg 	case HCI_OP_LE_READ_ADV_TX_POWER:
29418fa19098SJohan Hedberg 		hci_cc_le_read_adv_tx_power(hdev, skb);
29428fa19098SJohan Hedberg 		break;
29438fa19098SJohan Hedberg 
2944a5c29683SJohan Hedberg 	case HCI_OP_USER_CONFIRM_REPLY:
2945a5c29683SJohan Hedberg 		hci_cc_user_confirm_reply(hdev, skb);
2946a5c29683SJohan Hedberg 		break;
2947a5c29683SJohan Hedberg 
2948a5c29683SJohan Hedberg 	case HCI_OP_USER_CONFIRM_NEG_REPLY:
2949a5c29683SJohan Hedberg 		hci_cc_user_confirm_neg_reply(hdev, skb);
2950a5c29683SJohan Hedberg 		break;
2951a5c29683SJohan Hedberg 
29521143d458SBrian Gix 	case HCI_OP_USER_PASSKEY_REPLY:
29531143d458SBrian Gix 		hci_cc_user_passkey_reply(hdev, skb);
29541143d458SBrian Gix 		break;
29551143d458SBrian Gix 
29561143d458SBrian Gix 	case HCI_OP_USER_PASSKEY_NEG_REPLY:
29571143d458SBrian Gix 		hci_cc_user_passkey_neg_reply(hdev, skb);
295816cde993SSzymon Janc 		break;
295907f7fa5dSAndre Guedes 
29607a4cd51dSMarcel Holtmann 	case HCI_OP_LE_SET_RANDOM_ADDR:
29617a4cd51dSMarcel Holtmann 		hci_cc_le_set_random_addr(hdev, skb);
29627a4cd51dSMarcel Holtmann 		break;
29637a4cd51dSMarcel Holtmann 
2964c1d5dc4aSJohan Hedberg 	case HCI_OP_LE_SET_ADV_ENABLE:
2965c1d5dc4aSJohan Hedberg 		hci_cc_le_set_adv_enable(hdev, skb);
2966c1d5dc4aSJohan Hedberg 		break;
2967c1d5dc4aSJohan Hedberg 
2968533553f8SMarcel Holtmann 	case HCI_OP_LE_SET_SCAN_PARAM:
2969533553f8SMarcel Holtmann 		hci_cc_le_set_scan_param(hdev, skb);
2970533553f8SMarcel Holtmann 		break;
2971533553f8SMarcel Holtmann 
2972eb9d91f5SAndre Guedes 	case HCI_OP_LE_SET_SCAN_ENABLE:
2973eb9d91f5SAndre Guedes 		hci_cc_le_set_scan_enable(hdev, skb);
2974eb9d91f5SAndre Guedes 		break;
2975eb9d91f5SAndre Guedes 
2976cf1d081fSJohan Hedberg 	case HCI_OP_LE_READ_WHITE_LIST_SIZE:
2977cf1d081fSJohan Hedberg 		hci_cc_le_read_white_list_size(hdev, skb);
2978cf1d081fSJohan Hedberg 		break;
2979cf1d081fSJohan Hedberg 
29800f36b589SMarcel Holtmann 	case HCI_OP_LE_CLEAR_WHITE_LIST:
29810f36b589SMarcel Holtmann 		hci_cc_le_clear_white_list(hdev, skb);
29820f36b589SMarcel Holtmann 		break;
29830f36b589SMarcel Holtmann 
29840f36b589SMarcel Holtmann 	case HCI_OP_LE_ADD_TO_WHITE_LIST:
29850f36b589SMarcel Holtmann 		hci_cc_le_add_to_white_list(hdev, skb);
29860f36b589SMarcel Holtmann 		break;
29870f36b589SMarcel Holtmann 
29880f36b589SMarcel Holtmann 	case HCI_OP_LE_DEL_FROM_WHITE_LIST:
29890f36b589SMarcel Holtmann 		hci_cc_le_del_from_white_list(hdev, skb);
29900f36b589SMarcel Holtmann 		break;
29910f36b589SMarcel Holtmann 
29929b008c04SJohan Hedberg 	case HCI_OP_LE_READ_SUPPORTED_STATES:
29939b008c04SJohan Hedberg 		hci_cc_le_read_supported_states(hdev, skb);
29949b008c04SJohan Hedberg 		break;
29959b008c04SJohan Hedberg 
2996a8e1bfaaSMarcel Holtmann 	case HCI_OP_LE_READ_DEF_DATA_LEN:
2997a8e1bfaaSMarcel Holtmann 		hci_cc_le_read_def_data_len(hdev, skb);
2998a8e1bfaaSMarcel Holtmann 		break;
2999a8e1bfaaSMarcel Holtmann 
3000a8e1bfaaSMarcel Holtmann 	case HCI_OP_LE_WRITE_DEF_DATA_LEN:
3001a8e1bfaaSMarcel Holtmann 		hci_cc_le_write_def_data_len(hdev, skb);
3002a8e1bfaaSMarcel Holtmann 		break;
3003a8e1bfaaSMarcel Holtmann 
3004a8e1bfaaSMarcel Holtmann 	case HCI_OP_LE_READ_MAX_DATA_LEN:
3005a8e1bfaaSMarcel Holtmann 		hci_cc_le_read_max_data_len(hdev, skb);
3006a8e1bfaaSMarcel Holtmann 		break;
3007a8e1bfaaSMarcel Holtmann 
3008f9b49306SAndre Guedes 	case HCI_OP_WRITE_LE_HOST_SUPPORTED:
3009f9b49306SAndre Guedes 		hci_cc_write_le_host_supported(hdev, skb);
3010f9b49306SAndre Guedes 		break;
3011f9b49306SAndre Guedes 
301256ed2cb8SJohan Hedberg 	case HCI_OP_LE_SET_ADV_PARAM:
301356ed2cb8SJohan Hedberg 		hci_cc_set_adv_param(hdev, skb);
301456ed2cb8SJohan Hedberg 		break;
301556ed2cb8SJohan Hedberg 
30165ae76a94SAndrzej Kaczmarek 	case HCI_OP_READ_RSSI:
30175ae76a94SAndrzej Kaczmarek 		hci_cc_read_rssi(hdev, skb);
30185ae76a94SAndrzej Kaczmarek 		break;
30195ae76a94SAndrzej Kaczmarek 
30205a134faeSAndrzej Kaczmarek 	case HCI_OP_READ_TX_POWER:
30215a134faeSAndrzej Kaczmarek 		hci_cc_read_tx_power(hdev, skb);
30225a134faeSAndrzej Kaczmarek 		break;
30235a134faeSAndrzej Kaczmarek 
3024c50b33c8SMarcel Holtmann 	case HCI_OP_WRITE_SSP_DEBUG_MODE:
3025c50b33c8SMarcel Holtmann 		hci_cc_write_ssp_debug_mode(hdev, skb);
3026c50b33c8SMarcel Holtmann 		break;
3027c50b33c8SMarcel Holtmann 
3028a9de9248SMarcel Holtmann 	default:
3029e6214487SJohan Hedberg 		BT_DBG("%s opcode 0x%4.4x", hdev->name, *opcode);
3030a9de9248SMarcel Holtmann 		break;
3031a9de9248SMarcel Holtmann 	}
3032a9de9248SMarcel Holtmann 
3033e6214487SJohan Hedberg 	if (*opcode != HCI_OP_NOP)
303465cc2b49SMarcel Holtmann 		cancel_delayed_work(&hdev->cmd_timer);
30356bd32326SVille Tervo 
3036600b2150SJohan Hedberg 	if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags))
3037600b2150SJohan Hedberg 		atomic_set(&hdev->cmd_cnt, 1);
3038600b2150SJohan Hedberg 
3039e6214487SJohan Hedberg 	hci_req_cmd_complete(hdev, *opcode, *status, req_complete,
3040e6214487SJohan Hedberg 			     req_complete_skb);
30419238f36aSJohan Hedberg 
3042600b2150SJohan Hedberg 	if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q))
3043c347b765SGustavo F. Padovan 		queue_work(hdev->workqueue, &hdev->cmd_work);
3044a9de9248SMarcel Holtmann }
3045a9de9248SMarcel Holtmann 
3046e6214487SJohan Hedberg static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb,
3047e6214487SJohan Hedberg 			       u16 *opcode, u8 *status,
3048e6214487SJohan Hedberg 			       hci_req_complete_t *req_complete,
3049e6214487SJohan Hedberg 			       hci_req_complete_skb_t *req_complete_skb)
3050a9de9248SMarcel Holtmann {
3051a9de9248SMarcel Holtmann 	struct hci_ev_cmd_status *ev = (void *) skb->data;
3052a9de9248SMarcel Holtmann 
3053a9de9248SMarcel Holtmann 	skb_pull(skb, sizeof(*ev));
3054a9de9248SMarcel Holtmann 
3055e6214487SJohan Hedberg 	*opcode = __le16_to_cpu(ev->opcode);
3056e6214487SJohan Hedberg 	*status = ev->status;
3057a9de9248SMarcel Holtmann 
3058e6214487SJohan Hedberg 	switch (*opcode) {
3059a9de9248SMarcel Holtmann 	case HCI_OP_INQUIRY:
3060a9de9248SMarcel Holtmann 		hci_cs_inquiry(hdev, ev->status);
3061a9de9248SMarcel Holtmann 		break;
3062a9de9248SMarcel Holtmann 
3063a9de9248SMarcel Holtmann 	case HCI_OP_CREATE_CONN:
3064a9de9248SMarcel Holtmann 		hci_cs_create_conn(hdev, ev->status);
3065a9de9248SMarcel Holtmann 		break;
3066a9de9248SMarcel Holtmann 
30679645c76cSKuba Pawlak 	case HCI_OP_DISCONNECT:
30689645c76cSKuba Pawlak 		hci_cs_disconnect(hdev, ev->status);
30699645c76cSKuba Pawlak 		break;
30709645c76cSKuba Pawlak 
3071a9de9248SMarcel Holtmann 	case HCI_OP_ADD_SCO:
3072a9de9248SMarcel Holtmann 		hci_cs_add_sco(hdev, ev->status);
3073a9de9248SMarcel Holtmann 		break;
3074a9de9248SMarcel Holtmann 
3075f8558555SMarcel Holtmann 	case HCI_OP_AUTH_REQUESTED:
3076f8558555SMarcel Holtmann 		hci_cs_auth_requested(hdev, ev->status);
3077f8558555SMarcel Holtmann 		break;
3078f8558555SMarcel Holtmann 
3079f8558555SMarcel Holtmann 	case HCI_OP_SET_CONN_ENCRYPT:
3080f8558555SMarcel Holtmann 		hci_cs_set_conn_encrypt(hdev, ev->status);
3081f8558555SMarcel Holtmann 		break;
3082f8558555SMarcel Holtmann 
3083a9de9248SMarcel Holtmann 	case HCI_OP_REMOTE_NAME_REQ:
3084a9de9248SMarcel Holtmann 		hci_cs_remote_name_req(hdev, ev->status);
3085a9de9248SMarcel Holtmann 		break;
3086a9de9248SMarcel Holtmann 
3087769be974SMarcel Holtmann 	case HCI_OP_READ_REMOTE_FEATURES:
3088769be974SMarcel Holtmann 		hci_cs_read_remote_features(hdev, ev->status);
3089769be974SMarcel Holtmann 		break;
3090769be974SMarcel Holtmann 
3091769be974SMarcel Holtmann 	case HCI_OP_READ_REMOTE_EXT_FEATURES:
3092769be974SMarcel Holtmann 		hci_cs_read_remote_ext_features(hdev, ev->status);
3093769be974SMarcel Holtmann 		break;
3094769be974SMarcel Holtmann 
3095a9de9248SMarcel Holtmann 	case HCI_OP_SETUP_SYNC_CONN:
3096a9de9248SMarcel Holtmann 		hci_cs_setup_sync_conn(hdev, ev->status);
3097a9de9248SMarcel Holtmann 		break;
3098a9de9248SMarcel Holtmann 
3099a9de9248SMarcel Holtmann 	case HCI_OP_SNIFF_MODE:
3100a9de9248SMarcel Holtmann 		hci_cs_sniff_mode(hdev, ev->status);
3101a9de9248SMarcel Holtmann 		break;
3102a9de9248SMarcel Holtmann 
3103a9de9248SMarcel Holtmann 	case HCI_OP_EXIT_SNIFF_MODE:
3104a9de9248SMarcel Holtmann 		hci_cs_exit_sniff_mode(hdev, ev->status);
3105a9de9248SMarcel Holtmann 		break;
3106a9de9248SMarcel Holtmann 
310750fc85f1SKuba Pawlak 	case HCI_OP_SWITCH_ROLE:
310850fc85f1SKuba Pawlak 		hci_cs_switch_role(hdev, ev->status);
310950fc85f1SKuba Pawlak 		break;
311050fc85f1SKuba Pawlak 
3111cb1d68f7SJohan Hedberg 	case HCI_OP_LE_CREATE_CONN:
3112cb1d68f7SJohan Hedberg 		hci_cs_le_create_conn(hdev, ev->status);
3113cb1d68f7SJohan Hedberg 		break;
3114cb1d68f7SJohan Hedberg 
31150fe29fd1SMarcel Holtmann 	case HCI_OP_LE_READ_REMOTE_FEATURES:
31160fe29fd1SMarcel Holtmann 		hci_cs_le_read_remote_features(hdev, ev->status);
31170fe29fd1SMarcel Holtmann 		break;
31180fe29fd1SMarcel Holtmann 
311981d0c8adSJohan Hedberg 	case HCI_OP_LE_START_ENC:
312081d0c8adSJohan Hedberg 		hci_cs_le_start_enc(hdev, ev->status);
312181d0c8adSJohan Hedberg 		break;
312281d0c8adSJohan Hedberg 
3123a9de9248SMarcel Holtmann 	default:
3124e6214487SJohan Hedberg 		BT_DBG("%s opcode 0x%4.4x", hdev->name, *opcode);
3125a9de9248SMarcel Holtmann 		break;
3126a9de9248SMarcel Holtmann 	}
3127a9de9248SMarcel Holtmann 
3128e6214487SJohan Hedberg 	if (*opcode != HCI_OP_NOP)
312965cc2b49SMarcel Holtmann 		cancel_delayed_work(&hdev->cmd_timer);
31306bd32326SVille Tervo 
3131600b2150SJohan Hedberg 	if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags))
3132600b2150SJohan Hedberg 		atomic_set(&hdev->cmd_cnt, 1);
3133600b2150SJohan Hedberg 
3134444c6dd5SJohan Hedberg 	/* Indicate request completion if the command failed. Also, if
3135444c6dd5SJohan Hedberg 	 * we're not waiting for a special event and we get a success
3136444c6dd5SJohan Hedberg 	 * command status we should try to flag the request as completed
3137444c6dd5SJohan Hedberg 	 * (since for this kind of commands there will not be a command
3138444c6dd5SJohan Hedberg 	 * complete event).
3139444c6dd5SJohan Hedberg 	 */
314002350a72SJohan Hedberg 	if (ev->status ||
3141242c0ebdSMarcel Holtmann 	    (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->hci.req_event))
3142e6214487SJohan Hedberg 		hci_req_cmd_complete(hdev, *opcode, ev->status, req_complete,
3143e6214487SJohan Hedberg 				     req_complete_skb);
31449238f36aSJohan Hedberg 
3145600b2150SJohan Hedberg 	if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q))
3146c347b765SGustavo F. Padovan 		queue_work(hdev->workqueue, &hdev->cmd_work);
3147a9de9248SMarcel Holtmann }
3148a9de9248SMarcel Holtmann 
314924dfa343SMarcel Holtmann static void hci_hardware_error_evt(struct hci_dev *hdev, struct sk_buff *skb)
315024dfa343SMarcel Holtmann {
315124dfa343SMarcel Holtmann 	struct hci_ev_hardware_error *ev = (void *) skb->data;
315224dfa343SMarcel Holtmann 
3153c7741d16SMarcel Holtmann 	hdev->hw_error_code = ev->code;
3154c7741d16SMarcel Holtmann 
3155c7741d16SMarcel Holtmann 	queue_work(hdev->req_workqueue, &hdev->error_reset);
315624dfa343SMarcel Holtmann }
315724dfa343SMarcel Holtmann 
31586039aa73SGustavo Padovan static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
3159a9de9248SMarcel Holtmann {
3160a9de9248SMarcel Holtmann 	struct hci_ev_role_change *ev = (void *) skb->data;
3161a9de9248SMarcel Holtmann 	struct hci_conn *conn;
3162a9de9248SMarcel Holtmann 
31639f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3164a9de9248SMarcel Holtmann 
3165a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
3166a9de9248SMarcel Holtmann 
3167a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3168a9de9248SMarcel Holtmann 	if (conn) {
316940bef302SJohan Hedberg 		if (!ev->status)
317040bef302SJohan Hedberg 			conn->role = ev->role;
3171a9de9248SMarcel Holtmann 
317251a8efd7SJohan Hedberg 		clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
3173a9de9248SMarcel Holtmann 
3174a9de9248SMarcel Holtmann 		hci_role_switch_cfm(conn, ev->status, ev->role);
3175a9de9248SMarcel Holtmann 	}
3176a9de9248SMarcel Holtmann 
3177a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
3178a9de9248SMarcel Holtmann }
3179a9de9248SMarcel Holtmann 
31806039aa73SGustavo Padovan static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
31811da177e4SLinus Torvalds {
3182a9de9248SMarcel Holtmann 	struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
31831da177e4SLinus Torvalds 	int i;
31841da177e4SLinus Torvalds 
318532ac5b9bSAndrei Emeltchenko 	if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
318632ac5b9bSAndrei Emeltchenko 		BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
318732ac5b9bSAndrei Emeltchenko 		return;
318832ac5b9bSAndrei Emeltchenko 	}
318932ac5b9bSAndrei Emeltchenko 
3190c5993de8SAndrei Emeltchenko 	if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
3191c5993de8SAndrei Emeltchenko 	    ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
31921da177e4SLinus Torvalds 		BT_DBG("%s bad parameters", hdev->name);
31931da177e4SLinus Torvalds 		return;
31941da177e4SLinus Torvalds 	}
31951da177e4SLinus Torvalds 
3196c5993de8SAndrei Emeltchenko 	BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
3197c5993de8SAndrei Emeltchenko 
3198613a1c0cSAndrei Emeltchenko 	for (i = 0; i < ev->num_hndl; i++) {
3199613a1c0cSAndrei Emeltchenko 		struct hci_comp_pkts_info *info = &ev->handles[i];
32001da177e4SLinus Torvalds 		struct hci_conn *conn;
32011da177e4SLinus Torvalds 		__u16  handle, count;
32021da177e4SLinus Torvalds 
3203613a1c0cSAndrei Emeltchenko 		handle = __le16_to_cpu(info->handle);
3204613a1c0cSAndrei Emeltchenko 		count  = __le16_to_cpu(info->count);
32051da177e4SLinus Torvalds 
32061da177e4SLinus Torvalds 		conn = hci_conn_hash_lookup_handle(hdev, handle);
3207f4280918SAndrei Emeltchenko 		if (!conn)
3208f4280918SAndrei Emeltchenko 			continue;
3209f4280918SAndrei Emeltchenko 
32101da177e4SLinus Torvalds 		conn->sent -= count;
32111da177e4SLinus Torvalds 
3212f4280918SAndrei Emeltchenko 		switch (conn->type) {
3213f4280918SAndrei Emeltchenko 		case ACL_LINK:
321470f23020SAndrei Emeltchenko 			hdev->acl_cnt += count;
321570f23020SAndrei Emeltchenko 			if (hdev->acl_cnt > hdev->acl_pkts)
32161da177e4SLinus Torvalds 				hdev->acl_cnt = hdev->acl_pkts;
3217f4280918SAndrei Emeltchenko 			break;
3218f4280918SAndrei Emeltchenko 
3219f4280918SAndrei Emeltchenko 		case LE_LINK:
32206ed58ec5SVille Tervo 			if (hdev->le_pkts) {
32216ed58ec5SVille Tervo 				hdev->le_cnt += count;
32226ed58ec5SVille Tervo 				if (hdev->le_cnt > hdev->le_pkts)
32236ed58ec5SVille Tervo 					hdev->le_cnt = hdev->le_pkts;
32246ed58ec5SVille Tervo 			} else {
32256ed58ec5SVille Tervo 				hdev->acl_cnt += count;
32266ed58ec5SVille Tervo 				if (hdev->acl_cnt > hdev->acl_pkts)
32276ed58ec5SVille Tervo 					hdev->acl_cnt = hdev->acl_pkts;
32286ed58ec5SVille Tervo 			}
3229f4280918SAndrei Emeltchenko 			break;
3230f4280918SAndrei Emeltchenko 
3231f4280918SAndrei Emeltchenko 		case SCO_LINK:
323270f23020SAndrei Emeltchenko 			hdev->sco_cnt += count;
323370f23020SAndrei Emeltchenko 			if (hdev->sco_cnt > hdev->sco_pkts)
32345b7f9909SMarcel Holtmann 				hdev->sco_cnt = hdev->sco_pkts;
3235f4280918SAndrei Emeltchenko 			break;
3236f4280918SAndrei Emeltchenko 
3237f4280918SAndrei Emeltchenko 		default:
3238f4280918SAndrei Emeltchenko 			BT_ERR("Unknown type %d conn %p", conn->type, conn);
3239f4280918SAndrei Emeltchenko 			break;
32401da177e4SLinus Torvalds 		}
32411da177e4SLinus Torvalds 	}
3242a9de9248SMarcel Holtmann 
32433eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
32441da177e4SLinus Torvalds }
32451da177e4SLinus Torvalds 
324676ef7cf7SAndrei Emeltchenko static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
324776ef7cf7SAndrei Emeltchenko 						 __u16 handle)
324876ef7cf7SAndrei Emeltchenko {
324976ef7cf7SAndrei Emeltchenko 	struct hci_chan *chan;
325076ef7cf7SAndrei Emeltchenko 
325176ef7cf7SAndrei Emeltchenko 	switch (hdev->dev_type) {
3252ca8bee5dSMarcel Holtmann 	case HCI_PRIMARY:
325376ef7cf7SAndrei Emeltchenko 		return hci_conn_hash_lookup_handle(hdev, handle);
325476ef7cf7SAndrei Emeltchenko 	case HCI_AMP:
325576ef7cf7SAndrei Emeltchenko 		chan = hci_chan_lookup_handle(hdev, handle);
325676ef7cf7SAndrei Emeltchenko 		if (chan)
325776ef7cf7SAndrei Emeltchenko 			return chan->conn;
325876ef7cf7SAndrei Emeltchenko 		break;
325976ef7cf7SAndrei Emeltchenko 	default:
326076ef7cf7SAndrei Emeltchenko 		BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
326176ef7cf7SAndrei Emeltchenko 		break;
326276ef7cf7SAndrei Emeltchenko 	}
326376ef7cf7SAndrei Emeltchenko 
326476ef7cf7SAndrei Emeltchenko 	return NULL;
326576ef7cf7SAndrei Emeltchenko }
326676ef7cf7SAndrei Emeltchenko 
32676039aa73SGustavo Padovan static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
326825e89e99SAndrei Emeltchenko {
326925e89e99SAndrei Emeltchenko 	struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
327025e89e99SAndrei Emeltchenko 	int i;
327125e89e99SAndrei Emeltchenko 
327225e89e99SAndrei Emeltchenko 	if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
327325e89e99SAndrei Emeltchenko 		BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
327425e89e99SAndrei Emeltchenko 		return;
327525e89e99SAndrei Emeltchenko 	}
327625e89e99SAndrei Emeltchenko 
327725e89e99SAndrei Emeltchenko 	if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
327825e89e99SAndrei Emeltchenko 	    ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
327925e89e99SAndrei Emeltchenko 		BT_DBG("%s bad parameters", hdev->name);
328025e89e99SAndrei Emeltchenko 		return;
328125e89e99SAndrei Emeltchenko 	}
328225e89e99SAndrei Emeltchenko 
328325e89e99SAndrei Emeltchenko 	BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
328425e89e99SAndrei Emeltchenko 	       ev->num_hndl);
328525e89e99SAndrei Emeltchenko 
328625e89e99SAndrei Emeltchenko 	for (i = 0; i < ev->num_hndl; i++) {
328725e89e99SAndrei Emeltchenko 		struct hci_comp_blocks_info *info = &ev->handles[i];
328876ef7cf7SAndrei Emeltchenko 		struct hci_conn *conn = NULL;
328925e89e99SAndrei Emeltchenko 		__u16  handle, block_count;
329025e89e99SAndrei Emeltchenko 
329125e89e99SAndrei Emeltchenko 		handle = __le16_to_cpu(info->handle);
329225e89e99SAndrei Emeltchenko 		block_count = __le16_to_cpu(info->blocks);
329325e89e99SAndrei Emeltchenko 
329476ef7cf7SAndrei Emeltchenko 		conn = __hci_conn_lookup_handle(hdev, handle);
329525e89e99SAndrei Emeltchenko 		if (!conn)
329625e89e99SAndrei Emeltchenko 			continue;
329725e89e99SAndrei Emeltchenko 
329825e89e99SAndrei Emeltchenko 		conn->sent -= block_count;
329925e89e99SAndrei Emeltchenko 
330025e89e99SAndrei Emeltchenko 		switch (conn->type) {
330125e89e99SAndrei Emeltchenko 		case ACL_LINK:
3302bd1eb66bSAndrei Emeltchenko 		case AMP_LINK:
330325e89e99SAndrei Emeltchenko 			hdev->block_cnt += block_count;
330425e89e99SAndrei Emeltchenko 			if (hdev->block_cnt > hdev->num_blocks)
330525e89e99SAndrei Emeltchenko 				hdev->block_cnt = hdev->num_blocks;
330625e89e99SAndrei Emeltchenko 			break;
330725e89e99SAndrei Emeltchenko 
330825e89e99SAndrei Emeltchenko 		default:
330925e89e99SAndrei Emeltchenko 			BT_ERR("Unknown type %d conn %p", conn->type, conn);
331025e89e99SAndrei Emeltchenko 			break;
331125e89e99SAndrei Emeltchenko 		}
331225e89e99SAndrei Emeltchenko 	}
331325e89e99SAndrei Emeltchenko 
331425e89e99SAndrei Emeltchenko 	queue_work(hdev->workqueue, &hdev->tx_work);
331525e89e99SAndrei Emeltchenko }
331625e89e99SAndrei Emeltchenko 
33176039aa73SGustavo Padovan static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
33181da177e4SLinus Torvalds {
3319a9de9248SMarcel Holtmann 	struct hci_ev_mode_change *ev = (void *) skb->data;
332004837f64SMarcel Holtmann 	struct hci_conn *conn;
33211da177e4SLinus Torvalds 
33229f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
33231da177e4SLinus Torvalds 
33241da177e4SLinus Torvalds 	hci_dev_lock(hdev);
33251da177e4SLinus Torvalds 
332604837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
332704837f64SMarcel Holtmann 	if (conn) {
332804837f64SMarcel Holtmann 		conn->mode = ev->mode;
332904837f64SMarcel Holtmann 
33308fc9ced3SGustavo Padovan 		if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
33318fc9ced3SGustavo Padovan 					&conn->flags)) {
333204837f64SMarcel Holtmann 			if (conn->mode == HCI_CM_ACTIVE)
333358a681efSJohan Hedberg 				set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
333404837f64SMarcel Holtmann 			else
333558a681efSJohan Hedberg 				clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
333604837f64SMarcel Holtmann 		}
3337e73439d8SMarcel Holtmann 
333851a8efd7SJohan Hedberg 		if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
3339e73439d8SMarcel Holtmann 			hci_sco_setup(conn, ev->status);
334004837f64SMarcel Holtmann 	}
334104837f64SMarcel Holtmann 
334204837f64SMarcel Holtmann 	hci_dev_unlock(hdev);
334304837f64SMarcel Holtmann }
334404837f64SMarcel Holtmann 
33456039aa73SGustavo Padovan static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
33461da177e4SLinus Torvalds {
3347052b30b0SMarcel Holtmann 	struct hci_ev_pin_code_req *ev = (void *) skb->data;
3348052b30b0SMarcel Holtmann 	struct hci_conn *conn;
3349052b30b0SMarcel Holtmann 
3350a9de9248SMarcel Holtmann 	BT_DBG("%s", hdev->name);
3351052b30b0SMarcel Holtmann 
3352052b30b0SMarcel Holtmann 	hci_dev_lock(hdev);
3353052b30b0SMarcel Holtmann 
3354052b30b0SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3355b6f98044SWaldemar Rymarkiewicz 	if (!conn)
3356b6f98044SWaldemar Rymarkiewicz 		goto unlock;
3357b6f98044SWaldemar Rymarkiewicz 
3358b6f98044SWaldemar Rymarkiewicz 	if (conn->state == BT_CONNECTED) {
3359052b30b0SMarcel Holtmann 		hci_conn_hold(conn);
3360052b30b0SMarcel Holtmann 		conn->disc_timeout = HCI_PAIRING_TIMEOUT;
336176a68ba0SDavid Herrmann 		hci_conn_drop(conn);
3362052b30b0SMarcel Holtmann 	}
3363052b30b0SMarcel Holtmann 
3364d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BONDABLE) &&
33652f407f0aSJohan Hedberg 	    !test_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags)) {
336603b555e1SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
336703b555e1SJohan Hedberg 			     sizeof(ev->bdaddr), &ev->bdaddr);
3368d7a5a11dSMarcel Holtmann 	} else if (hci_dev_test_flag(hdev, HCI_MGMT)) {
3369a770bb5aSWaldemar Rymarkiewicz 		u8 secure;
3370a770bb5aSWaldemar Rymarkiewicz 
3371a770bb5aSWaldemar Rymarkiewicz 		if (conn->pending_sec_level == BT_SECURITY_HIGH)
3372a770bb5aSWaldemar Rymarkiewicz 			secure = 1;
3373a770bb5aSWaldemar Rymarkiewicz 		else
3374a770bb5aSWaldemar Rymarkiewicz 			secure = 0;
3375a770bb5aSWaldemar Rymarkiewicz 
3376744cf19eSJohan Hedberg 		mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
3377a770bb5aSWaldemar Rymarkiewicz 	}
3378980e1a53SJohan Hedberg 
3379b6f98044SWaldemar Rymarkiewicz unlock:
3380052b30b0SMarcel Holtmann 	hci_dev_unlock(hdev);
33811da177e4SLinus Torvalds }
33821da177e4SLinus Torvalds 
3383cb6f3f7aSJohan Hedberg static void conn_set_key(struct hci_conn *conn, u8 key_type, u8 pin_len)
3384cb6f3f7aSJohan Hedberg {
3385cb6f3f7aSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION)
3386cb6f3f7aSJohan Hedberg 		return;
3387cb6f3f7aSJohan Hedberg 
3388cb6f3f7aSJohan Hedberg 	conn->pin_length = pin_len;
3389cb6f3f7aSJohan Hedberg 	conn->key_type = key_type;
3390cb6f3f7aSJohan Hedberg 
3391cb6f3f7aSJohan Hedberg 	switch (key_type) {
3392cb6f3f7aSJohan Hedberg 	case HCI_LK_LOCAL_UNIT:
3393cb6f3f7aSJohan Hedberg 	case HCI_LK_REMOTE_UNIT:
3394cb6f3f7aSJohan Hedberg 	case HCI_LK_DEBUG_COMBINATION:
3395cb6f3f7aSJohan Hedberg 		return;
3396cb6f3f7aSJohan Hedberg 	case HCI_LK_COMBINATION:
3397cb6f3f7aSJohan Hedberg 		if (pin_len == 16)
3398cb6f3f7aSJohan Hedberg 			conn->pending_sec_level = BT_SECURITY_HIGH;
3399cb6f3f7aSJohan Hedberg 		else
3400cb6f3f7aSJohan Hedberg 			conn->pending_sec_level = BT_SECURITY_MEDIUM;
3401cb6f3f7aSJohan Hedberg 		break;
3402cb6f3f7aSJohan Hedberg 	case HCI_LK_UNAUTH_COMBINATION_P192:
3403cb6f3f7aSJohan Hedberg 	case HCI_LK_UNAUTH_COMBINATION_P256:
3404cb6f3f7aSJohan Hedberg 		conn->pending_sec_level = BT_SECURITY_MEDIUM;
3405cb6f3f7aSJohan Hedberg 		break;
3406cb6f3f7aSJohan Hedberg 	case HCI_LK_AUTH_COMBINATION_P192:
3407cb6f3f7aSJohan Hedberg 		conn->pending_sec_level = BT_SECURITY_HIGH;
3408cb6f3f7aSJohan Hedberg 		break;
3409cb6f3f7aSJohan Hedberg 	case HCI_LK_AUTH_COMBINATION_P256:
3410cb6f3f7aSJohan Hedberg 		conn->pending_sec_level = BT_SECURITY_FIPS;
3411cb6f3f7aSJohan Hedberg 		break;
3412cb6f3f7aSJohan Hedberg 	}
3413cb6f3f7aSJohan Hedberg }
3414cb6f3f7aSJohan Hedberg 
34156039aa73SGustavo Padovan static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
34161da177e4SLinus Torvalds {
341755ed8ca1SJohan Hedberg 	struct hci_ev_link_key_req *ev = (void *) skb->data;
341855ed8ca1SJohan Hedberg 	struct hci_cp_link_key_reply cp;
341955ed8ca1SJohan Hedberg 	struct hci_conn *conn;
342055ed8ca1SJohan Hedberg 	struct link_key *key;
342155ed8ca1SJohan Hedberg 
3422a9de9248SMarcel Holtmann 	BT_DBG("%s", hdev->name);
342355ed8ca1SJohan Hedberg 
3424d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
342555ed8ca1SJohan Hedberg 		return;
342655ed8ca1SJohan Hedberg 
342755ed8ca1SJohan Hedberg 	hci_dev_lock(hdev);
342855ed8ca1SJohan Hedberg 
342955ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, &ev->bdaddr);
343055ed8ca1SJohan Hedberg 	if (!key) {
34316ed93dc6SAndrei Emeltchenko 		BT_DBG("%s link key not found for %pMR", hdev->name,
34326ed93dc6SAndrei Emeltchenko 		       &ev->bdaddr);
343355ed8ca1SJohan Hedberg 		goto not_found;
343455ed8ca1SJohan Hedberg 	}
343555ed8ca1SJohan Hedberg 
34366ed93dc6SAndrei Emeltchenko 	BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
34376ed93dc6SAndrei Emeltchenko 	       &ev->bdaddr);
343855ed8ca1SJohan Hedberg 
343955ed8ca1SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
344060b83f57SWaldemar Rymarkiewicz 	if (conn) {
3441fe8bc5acSJohan Hedberg 		clear_bit(HCI_CONN_NEW_LINK_KEY, &conn->flags);
3442fe8bc5acSJohan Hedberg 
344366138ce8SMarcel Holtmann 		if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 ||
344466138ce8SMarcel Holtmann 		     key->type == HCI_LK_UNAUTH_COMBINATION_P256) &&
3445807deac2SGustavo Padovan 		    conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
344655ed8ca1SJohan Hedberg 			BT_DBG("%s ignoring unauthenticated key", hdev->name);
344755ed8ca1SJohan Hedberg 			goto not_found;
344855ed8ca1SJohan Hedberg 		}
344955ed8ca1SJohan Hedberg 
345060b83f57SWaldemar Rymarkiewicz 		if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
3451f3fb0b58SJohan Hedberg 		    (conn->pending_sec_level == BT_SECURITY_HIGH ||
3452f3fb0b58SJohan Hedberg 		     conn->pending_sec_level == BT_SECURITY_FIPS)) {
34538fc9ced3SGustavo Padovan 			BT_DBG("%s ignoring key unauthenticated for high security",
34548fc9ced3SGustavo Padovan 			       hdev->name);
345560b83f57SWaldemar Rymarkiewicz 			goto not_found;
345660b83f57SWaldemar Rymarkiewicz 		}
345760b83f57SWaldemar Rymarkiewicz 
3458cb6f3f7aSJohan Hedberg 		conn_set_key(conn, key->type, key->pin_len);
345960b83f57SWaldemar Rymarkiewicz 	}
346060b83f57SWaldemar Rymarkiewicz 
346155ed8ca1SJohan Hedberg 	bacpy(&cp.bdaddr, &ev->bdaddr);
34629b3b4460SAndrei Emeltchenko 	memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
346355ed8ca1SJohan Hedberg 
346455ed8ca1SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
346555ed8ca1SJohan Hedberg 
346655ed8ca1SJohan Hedberg 	hci_dev_unlock(hdev);
346755ed8ca1SJohan Hedberg 
346855ed8ca1SJohan Hedberg 	return;
346955ed8ca1SJohan Hedberg 
347055ed8ca1SJohan Hedberg not_found:
347155ed8ca1SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
347255ed8ca1SJohan Hedberg 	hci_dev_unlock(hdev);
34731da177e4SLinus Torvalds }
34741da177e4SLinus Torvalds 
34756039aa73SGustavo Padovan static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
34761da177e4SLinus Torvalds {
3477052b30b0SMarcel Holtmann 	struct hci_ev_link_key_notify *ev = (void *) skb->data;
3478052b30b0SMarcel Holtmann 	struct hci_conn *conn;
34797652ff6aSJohan Hedberg 	struct link_key *key;
34807652ff6aSJohan Hedberg 	bool persistent;
348155ed8ca1SJohan Hedberg 	u8 pin_len = 0;
3482052b30b0SMarcel Holtmann 
3483a9de9248SMarcel Holtmann 	BT_DBG("%s", hdev->name);
3484052b30b0SMarcel Holtmann 
3485052b30b0SMarcel Holtmann 	hci_dev_lock(hdev);
3486052b30b0SMarcel Holtmann 
3487052b30b0SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
348882c13d42SJohan Hedberg 	if (!conn)
348982c13d42SJohan Hedberg 		goto unlock;
349082c13d42SJohan Hedberg 
3491052b30b0SMarcel Holtmann 	hci_conn_hold(conn);
3492052b30b0SMarcel Holtmann 	conn->disc_timeout = HCI_DISCONN_TIMEOUT;
349376a68ba0SDavid Herrmann 	hci_conn_drop(conn);
349482c13d42SJohan Hedberg 
3495fe8bc5acSJohan Hedberg 	set_bit(HCI_CONN_NEW_LINK_KEY, &conn->flags);
3496cb6f3f7aSJohan Hedberg 	conn_set_key(conn, ev->key_type, conn->pin_length);
3497052b30b0SMarcel Holtmann 
3498d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
34997652ff6aSJohan Hedberg 		goto unlock;
350055ed8ca1SJohan Hedberg 
35017652ff6aSJohan Hedberg 	key = hci_add_link_key(hdev, conn, &ev->bdaddr, ev->link_key,
35027652ff6aSJohan Hedberg 			        ev->key_type, pin_len, &persistent);
35037652ff6aSJohan Hedberg 	if (!key)
35047652ff6aSJohan Hedberg 		goto unlock;
35057652ff6aSJohan Hedberg 
3506cb6f3f7aSJohan Hedberg 	/* Update connection information since adding the key will have
3507cb6f3f7aSJohan Hedberg 	 * fixed up the type in the case of changed combination keys.
3508cb6f3f7aSJohan Hedberg 	 */
3509cb6f3f7aSJohan Hedberg 	if (ev->key_type == HCI_LK_CHANGED_COMBINATION)
3510cb6f3f7aSJohan Hedberg 		conn_set_key(conn, key->type, key->pin_len);
3511cb6f3f7aSJohan Hedberg 
35127652ff6aSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
35137652ff6aSJohan Hedberg 
35146d5650c4SJohan Hedberg 	/* Keep debug keys around only if the HCI_KEEP_DEBUG_KEYS flag
35156d5650c4SJohan Hedberg 	 * is set. If it's not set simply remove the key from the kernel
35166d5650c4SJohan Hedberg 	 * list (we've still notified user space about it but with
35176d5650c4SJohan Hedberg 	 * store_hint being 0).
35186d5650c4SJohan Hedberg 	 */
35196d5650c4SJohan Hedberg 	if (key->type == HCI_LK_DEBUG_COMBINATION &&
3520d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_KEEP_DEBUG_KEYS)) {
35210378b597SJohan Hedberg 		list_del_rcu(&key->list);
35220378b597SJohan Hedberg 		kfree_rcu(key, rcu);
352382c13d42SJohan Hedberg 		goto unlock;
352482c13d42SJohan Hedberg 	}
352582c13d42SJohan Hedberg 
3526af6a9c32SJohan Hedberg 	if (persistent)
3527af6a9c32SJohan Hedberg 		clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags);
3528af6a9c32SJohan Hedberg 	else
3529af6a9c32SJohan Hedberg 		set_bit(HCI_CONN_FLUSH_KEY, &conn->flags);
35307652ff6aSJohan Hedberg 
35317652ff6aSJohan Hedberg unlock:
3532052b30b0SMarcel Holtmann 	hci_dev_unlock(hdev);
35331da177e4SLinus Torvalds }
35341da177e4SLinus Torvalds 
35356039aa73SGustavo Padovan static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
353604837f64SMarcel Holtmann {
3537a9de9248SMarcel Holtmann 	struct hci_ev_clock_offset *ev = (void *) skb->data;
353804837f64SMarcel Holtmann 	struct hci_conn *conn;
353904837f64SMarcel Holtmann 
35409f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
354104837f64SMarcel Holtmann 
354204837f64SMarcel Holtmann 	hci_dev_lock(hdev);
354304837f64SMarcel Holtmann 
354404837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
35451da177e4SLinus Torvalds 	if (conn && !ev->status) {
35461da177e4SLinus Torvalds 		struct inquiry_entry *ie;
35471da177e4SLinus Torvalds 
3548cc11b9c1SAndrei Emeltchenko 		ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
3549cc11b9c1SAndrei Emeltchenko 		if (ie) {
35501da177e4SLinus Torvalds 			ie->data.clock_offset = ev->clock_offset;
35511da177e4SLinus Torvalds 			ie->timestamp = jiffies;
35521da177e4SLinus Torvalds 		}
35531da177e4SLinus Torvalds 	}
35541da177e4SLinus Torvalds 
35551da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
35561da177e4SLinus Torvalds }
35571da177e4SLinus Torvalds 
35586039aa73SGustavo Padovan static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
3559a8746417SMarcel Holtmann {
3560a8746417SMarcel Holtmann 	struct hci_ev_pkt_type_change *ev = (void *) skb->data;
3561a8746417SMarcel Holtmann 	struct hci_conn *conn;
3562a8746417SMarcel Holtmann 
35639f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3564a8746417SMarcel Holtmann 
3565a8746417SMarcel Holtmann 	hci_dev_lock(hdev);
3566a8746417SMarcel Holtmann 
3567a8746417SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3568a8746417SMarcel Holtmann 	if (conn && !ev->status)
3569a8746417SMarcel Holtmann 		conn->pkt_type = __le16_to_cpu(ev->pkt_type);
3570a8746417SMarcel Holtmann 
3571a8746417SMarcel Holtmann 	hci_dev_unlock(hdev);
3572a8746417SMarcel Holtmann }
3573a8746417SMarcel Holtmann 
35746039aa73SGustavo Padovan static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
357585a1e930SMarcel Holtmann {
3576a9de9248SMarcel Holtmann 	struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
357785a1e930SMarcel Holtmann 	struct inquiry_entry *ie;
357885a1e930SMarcel Holtmann 
357985a1e930SMarcel Holtmann 	BT_DBG("%s", hdev->name);
358085a1e930SMarcel Holtmann 
358185a1e930SMarcel Holtmann 	hci_dev_lock(hdev);
358285a1e930SMarcel Holtmann 
3583cc11b9c1SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3584cc11b9c1SAndrei Emeltchenko 	if (ie) {
358585a1e930SMarcel Holtmann 		ie->data.pscan_rep_mode = ev->pscan_rep_mode;
358685a1e930SMarcel Holtmann 		ie->timestamp = jiffies;
358785a1e930SMarcel Holtmann 	}
358885a1e930SMarcel Holtmann 
358985a1e930SMarcel Holtmann 	hci_dev_unlock(hdev);
359085a1e930SMarcel Holtmann }
359185a1e930SMarcel Holtmann 
35926039aa73SGustavo Padovan static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
3593807deac2SGustavo Padovan 					     struct sk_buff *skb)
3594a9de9248SMarcel Holtmann {
3595a9de9248SMarcel Holtmann 	struct inquiry_data data;
3596a9de9248SMarcel Holtmann 	int num_rsp = *((__u8 *) skb->data);
3597a9de9248SMarcel Holtmann 
3598a9de9248SMarcel Holtmann 	BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
3599a9de9248SMarcel Holtmann 
3600a9de9248SMarcel Holtmann 	if (!num_rsp)
3601a9de9248SMarcel Holtmann 		return;
3602a9de9248SMarcel Holtmann 
3603d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ))
36041519cc17SAndre Guedes 		return;
36051519cc17SAndre Guedes 
3606a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
3607a9de9248SMarcel Holtmann 
3608a9de9248SMarcel Holtmann 	if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
3609138d22efSSzymon Janc 		struct inquiry_info_with_rssi_and_pscan_mode *info;
3610138d22efSSzymon Janc 		info = (void *) (skb->data + 1);
3611a9de9248SMarcel Holtmann 
3612e17acd40SJohan Hedberg 		for (; num_rsp; num_rsp--, info++) {
3613af58925cSMarcel Holtmann 			u32 flags;
3614af58925cSMarcel Holtmann 
3615a9de9248SMarcel Holtmann 			bacpy(&data.bdaddr, &info->bdaddr);
3616a9de9248SMarcel Holtmann 			data.pscan_rep_mode	= info->pscan_rep_mode;
3617a9de9248SMarcel Holtmann 			data.pscan_period_mode	= info->pscan_period_mode;
3618a9de9248SMarcel Holtmann 			data.pscan_mode		= info->pscan_mode;
3619a9de9248SMarcel Holtmann 			memcpy(data.dev_class, info->dev_class, 3);
3620a9de9248SMarcel Holtmann 			data.clock_offset	= info->clock_offset;
3621a9de9248SMarcel Holtmann 			data.rssi		= info->rssi;
362241a96212SMarcel Holtmann 			data.ssp_mode		= 0x00;
36233175405bSJohan Hedberg 
3624af58925cSMarcel Holtmann 			flags = hci_inquiry_cache_update(hdev, &data, false);
3625af58925cSMarcel Holtmann 
362648264f06SJohan Hedberg 			mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
3627e17acd40SJohan Hedberg 					  info->dev_class, info->rssi,
3628af58925cSMarcel Holtmann 					  flags, NULL, 0, NULL, 0);
3629a9de9248SMarcel Holtmann 		}
3630a9de9248SMarcel Holtmann 	} else {
3631a9de9248SMarcel Holtmann 		struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
3632a9de9248SMarcel Holtmann 
3633e17acd40SJohan Hedberg 		for (; num_rsp; num_rsp--, info++) {
3634af58925cSMarcel Holtmann 			u32 flags;
3635af58925cSMarcel Holtmann 
3636a9de9248SMarcel Holtmann 			bacpy(&data.bdaddr, &info->bdaddr);
3637a9de9248SMarcel Holtmann 			data.pscan_rep_mode	= info->pscan_rep_mode;
3638a9de9248SMarcel Holtmann 			data.pscan_period_mode	= info->pscan_period_mode;
3639a9de9248SMarcel Holtmann 			data.pscan_mode		= 0x00;
3640a9de9248SMarcel Holtmann 			memcpy(data.dev_class, info->dev_class, 3);
3641a9de9248SMarcel Holtmann 			data.clock_offset	= info->clock_offset;
3642a9de9248SMarcel Holtmann 			data.rssi		= info->rssi;
364341a96212SMarcel Holtmann 			data.ssp_mode		= 0x00;
3644af58925cSMarcel Holtmann 
3645af58925cSMarcel Holtmann 			flags = hci_inquiry_cache_update(hdev, &data, false);
3646af58925cSMarcel Holtmann 
364748264f06SJohan Hedberg 			mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
3648e17acd40SJohan Hedberg 					  info->dev_class, info->rssi,
3649af58925cSMarcel Holtmann 					  flags, NULL, 0, NULL, 0);
3650a9de9248SMarcel Holtmann 		}
3651a9de9248SMarcel Holtmann 	}
3652a9de9248SMarcel Holtmann 
3653a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
3654a9de9248SMarcel Holtmann }
3655a9de9248SMarcel Holtmann 
36566039aa73SGustavo Padovan static void hci_remote_ext_features_evt(struct hci_dev *hdev,
3657807deac2SGustavo Padovan 					struct sk_buff *skb)
3658a9de9248SMarcel Holtmann {
365941a96212SMarcel Holtmann 	struct hci_ev_remote_ext_features *ev = (void *) skb->data;
366041a96212SMarcel Holtmann 	struct hci_conn *conn;
366141a96212SMarcel Holtmann 
3662a9de9248SMarcel Holtmann 	BT_DBG("%s", hdev->name);
366341a96212SMarcel Holtmann 
366441a96212SMarcel Holtmann 	hci_dev_lock(hdev);
366541a96212SMarcel Holtmann 
366641a96212SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3667ccd556feSJohan Hedberg 	if (!conn)
3668ccd556feSJohan Hedberg 		goto unlock;
3669ccd556feSJohan Hedberg 
3670cad718edSJohan Hedberg 	if (ev->page < HCI_MAX_PAGES)
3671cad718edSJohan Hedberg 		memcpy(conn->features[ev->page], ev->features, 8);
3672cad718edSJohan Hedberg 
3673769be974SMarcel Holtmann 	if (!ev->status && ev->page == 0x01) {
367441a96212SMarcel Holtmann 		struct inquiry_entry *ie;
367541a96212SMarcel Holtmann 
3676cc11b9c1SAndrei Emeltchenko 		ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
3677cc11b9c1SAndrei Emeltchenko 		if (ie)
367802b7cc62SJohan Hedberg 			ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
367941a96212SMarcel Holtmann 
3680bbb0eadaSJaganath Kanakkassery 		if (ev->features[0] & LMP_HOST_SSP) {
368158a681efSJohan Hedberg 			set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
3682bbb0eadaSJaganath Kanakkassery 		} else {
3683bbb0eadaSJaganath Kanakkassery 			/* It is mandatory by the Bluetooth specification that
3684bbb0eadaSJaganath Kanakkassery 			 * Extended Inquiry Results are only used when Secure
3685bbb0eadaSJaganath Kanakkassery 			 * Simple Pairing is enabled, but some devices violate
3686bbb0eadaSJaganath Kanakkassery 			 * this.
3687bbb0eadaSJaganath Kanakkassery 			 *
3688bbb0eadaSJaganath Kanakkassery 			 * To make these devices work, the internal SSP
3689bbb0eadaSJaganath Kanakkassery 			 * enabled flag needs to be cleared if the remote host
3690bbb0eadaSJaganath Kanakkassery 			 * features do not indicate SSP support */
3691bbb0eadaSJaganath Kanakkassery 			clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
3692bbb0eadaSJaganath Kanakkassery 		}
3693eb9a8f3fSMarcel Holtmann 
3694eb9a8f3fSMarcel Holtmann 		if (ev->features[0] & LMP_HOST_SC)
3695eb9a8f3fSMarcel Holtmann 			set_bit(HCI_CONN_SC_ENABLED, &conn->flags);
369641a96212SMarcel Holtmann 	}
369741a96212SMarcel Holtmann 
3698ccd556feSJohan Hedberg 	if (conn->state != BT_CONFIG)
3699ccd556feSJohan Hedberg 		goto unlock;
3700ccd556feSJohan Hedberg 
3701671267bfSJohan Hedberg 	if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
3702127178d2SJohan Hedberg 		struct hci_cp_remote_name_req cp;
3703127178d2SJohan Hedberg 		memset(&cp, 0, sizeof(cp));
3704127178d2SJohan Hedberg 		bacpy(&cp.bdaddr, &conn->dst);
3705127178d2SJohan Hedberg 		cp.pscan_rep_mode = 0x02;
3706127178d2SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
3707b644ba33SJohan Hedberg 	} else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
370848ec92faSAlfonso Acosta 		mgmt_device_connected(hdev, conn, 0, NULL, 0);
3709392599b9SJohan Hedberg 
3710127178d2SJohan Hedberg 	if (!hci_outgoing_auth_needed(hdev, conn)) {
3711769be974SMarcel Holtmann 		conn->state = BT_CONNECTED;
3712539c496dSJohan Hedberg 		hci_connect_cfm(conn, ev->status);
371376a68ba0SDavid Herrmann 		hci_conn_drop(conn);
3714769be974SMarcel Holtmann 	}
3715769be974SMarcel Holtmann 
3716ccd556feSJohan Hedberg unlock:
371741a96212SMarcel Holtmann 	hci_dev_unlock(hdev);
3718a9de9248SMarcel Holtmann }
3719a9de9248SMarcel Holtmann 
37206039aa73SGustavo Padovan static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
3721807deac2SGustavo Padovan 				       struct sk_buff *skb)
3722a9de9248SMarcel Holtmann {
3723b6a0dc82SMarcel Holtmann 	struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
3724b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
3725b6a0dc82SMarcel Holtmann 
37269f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3727b6a0dc82SMarcel Holtmann 
3728b6a0dc82SMarcel Holtmann 	hci_dev_lock(hdev);
3729b6a0dc82SMarcel Holtmann 
3730b6a0dc82SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
37319dc0a3afSMarcel Holtmann 	if (!conn) {
37329dc0a3afSMarcel Holtmann 		if (ev->link_type == ESCO_LINK)
37339dc0a3afSMarcel Holtmann 			goto unlock;
37349dc0a3afSMarcel Holtmann 
3735618353b1SKuba Pawlak 		/* When the link type in the event indicates SCO connection
3736618353b1SKuba Pawlak 		 * and lookup of the connection object fails, then check
3737618353b1SKuba Pawlak 		 * if an eSCO connection object exists.
3738618353b1SKuba Pawlak 		 *
3739618353b1SKuba Pawlak 		 * The core limits the synchronous connections to either
3740618353b1SKuba Pawlak 		 * SCO or eSCO. The eSCO connection is preferred and tried
3741618353b1SKuba Pawlak 		 * to be setup first and until successfully established,
3742618353b1SKuba Pawlak 		 * the link type will be hinted as eSCO.
3743618353b1SKuba Pawlak 		 */
37449dc0a3afSMarcel Holtmann 		conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
3745b6a0dc82SMarcel Holtmann 		if (!conn)
3746b6a0dc82SMarcel Holtmann 			goto unlock;
37479dc0a3afSMarcel Holtmann 	}
37489dc0a3afSMarcel Holtmann 
3749732547f9SMarcel Holtmann 	switch (ev->status) {
3750732547f9SMarcel Holtmann 	case 0x00:
3751732547f9SMarcel Holtmann 		conn->handle = __le16_to_cpu(ev->handle);
3752732547f9SMarcel Holtmann 		conn->state  = BT_CONNECTED;
3753618353b1SKuba Pawlak 		conn->type   = ev->link_type;
3754732547f9SMarcel Holtmann 
375523b9ceb7SMarcel Holtmann 		hci_debugfs_create_conn(conn);
3756732547f9SMarcel Holtmann 		hci_conn_add_sysfs(conn);
3757732547f9SMarcel Holtmann 		break;
3758732547f9SMarcel Holtmann 
375981218d20SNick Pelly 	case 0x10:	/* Connection Accept Timeout */
37601a4c958cSFrédéric Dalleau 	case 0x0d:	/* Connection Rejected due to Limited Resources */
3761705e5711SStephen Coe 	case 0x11:	/* Unsupported Feature or Parameter Value */
3762732547f9SMarcel Holtmann 	case 0x1c:	/* SCO interval rejected */
37631038a00bSNick Pelly 	case 0x1a:	/* Unsupported Remote Feature */
3764732547f9SMarcel Holtmann 	case 0x1f:	/* Unspecified error */
376527539bc4SAndrew Earl 	case 0x20:	/* Unsupported LMP Parameter value */
37662dea632fSFrédéric Dalleau 		if (conn->out) {
3767efc7688bSMarcel Holtmann 			conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
3768efc7688bSMarcel Holtmann 					(hdev->esco_type & EDR_ESCO_MASK);
37692dea632fSFrédéric Dalleau 			if (hci_setup_sync(conn, conn->link->handle))
3770efc7688bSMarcel Holtmann 				goto unlock;
3771efc7688bSMarcel Holtmann 		}
3772732547f9SMarcel Holtmann 		/* fall through */
3773efc7688bSMarcel Holtmann 
3774732547f9SMarcel Holtmann 	default:
3775b6a0dc82SMarcel Holtmann 		conn->state = BT_CLOSED;
3776732547f9SMarcel Holtmann 		break;
3777732547f9SMarcel Holtmann 	}
3778b6a0dc82SMarcel Holtmann 
3779539c496dSJohan Hedberg 	hci_connect_cfm(conn, ev->status);
3780b6a0dc82SMarcel Holtmann 	if (ev->status)
3781b6a0dc82SMarcel Holtmann 		hci_conn_del(conn);
3782b6a0dc82SMarcel Holtmann 
3783b6a0dc82SMarcel Holtmann unlock:
3784b6a0dc82SMarcel Holtmann 	hci_dev_unlock(hdev);
3785a9de9248SMarcel Holtmann }
3786a9de9248SMarcel Holtmann 
3787efdcf8e3SMarcel Holtmann static inline size_t eir_get_length(u8 *eir, size_t eir_len)
3788efdcf8e3SMarcel Holtmann {
3789efdcf8e3SMarcel Holtmann 	size_t parsed = 0;
3790efdcf8e3SMarcel Holtmann 
3791efdcf8e3SMarcel Holtmann 	while (parsed < eir_len) {
3792efdcf8e3SMarcel Holtmann 		u8 field_len = eir[0];
3793efdcf8e3SMarcel Holtmann 
3794efdcf8e3SMarcel Holtmann 		if (field_len == 0)
3795efdcf8e3SMarcel Holtmann 			return parsed;
3796efdcf8e3SMarcel Holtmann 
3797efdcf8e3SMarcel Holtmann 		parsed += field_len + 1;
3798efdcf8e3SMarcel Holtmann 		eir += field_len + 1;
3799efdcf8e3SMarcel Holtmann 	}
3800efdcf8e3SMarcel Holtmann 
3801efdcf8e3SMarcel Holtmann 	return eir_len;
3802efdcf8e3SMarcel Holtmann }
3803efdcf8e3SMarcel Holtmann 
38046039aa73SGustavo Padovan static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
3805807deac2SGustavo Padovan 					    struct sk_buff *skb)
3806a9de9248SMarcel Holtmann {
3807a9de9248SMarcel Holtmann 	struct inquiry_data data;
3808a9de9248SMarcel Holtmann 	struct extended_inquiry_info *info = (void *) (skb->data + 1);
3809a9de9248SMarcel Holtmann 	int num_rsp = *((__u8 *) skb->data);
38109d939d94SVishal Agarwal 	size_t eir_len;
3811a9de9248SMarcel Holtmann 
3812a9de9248SMarcel Holtmann 	BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
3813a9de9248SMarcel Holtmann 
3814a9de9248SMarcel Holtmann 	if (!num_rsp)
3815a9de9248SMarcel Holtmann 		return;
3816a9de9248SMarcel Holtmann 
3817d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_PERIODIC_INQ))
38181519cc17SAndre Guedes 		return;
38191519cc17SAndre Guedes 
3820a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
3821a9de9248SMarcel Holtmann 
3822e17acd40SJohan Hedberg 	for (; num_rsp; num_rsp--, info++) {
3823af58925cSMarcel Holtmann 		u32 flags;
3824af58925cSMarcel Holtmann 		bool name_known;
3825561aafbcSJohan Hedberg 
3826a9de9248SMarcel Holtmann 		bacpy(&data.bdaddr, &info->bdaddr);
3827a9de9248SMarcel Holtmann 		data.pscan_rep_mode	= info->pscan_rep_mode;
3828a9de9248SMarcel Holtmann 		data.pscan_period_mode	= info->pscan_period_mode;
3829a9de9248SMarcel Holtmann 		data.pscan_mode		= 0x00;
3830a9de9248SMarcel Holtmann 		memcpy(data.dev_class, info->dev_class, 3);
3831a9de9248SMarcel Holtmann 		data.clock_offset	= info->clock_offset;
3832a9de9248SMarcel Holtmann 		data.rssi		= info->rssi;
383341a96212SMarcel Holtmann 		data.ssp_mode		= 0x01;
3834561aafbcSJohan Hedberg 
3835d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_MGMT))
38360d3b7f64SJohan Hedberg 			name_known = eir_get_data(info->data,
38374ddb1930SJohan Hedberg 						  sizeof(info->data),
38380d3b7f64SJohan Hedberg 						  EIR_NAME_COMPLETE, NULL);
3839561aafbcSJohan Hedberg 		else
3840561aafbcSJohan Hedberg 			name_known = true;
3841561aafbcSJohan Hedberg 
3842af58925cSMarcel Holtmann 		flags = hci_inquiry_cache_update(hdev, &data, name_known);
3843af58925cSMarcel Holtmann 
38449d939d94SVishal Agarwal 		eir_len = eir_get_length(info->data, sizeof(info->data));
3845af58925cSMarcel Holtmann 
384648264f06SJohan Hedberg 		mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
3847af58925cSMarcel Holtmann 				  info->dev_class, info->rssi,
3848af58925cSMarcel Holtmann 				  flags, info->data, eir_len, NULL, 0);
3849a9de9248SMarcel Holtmann 	}
3850a9de9248SMarcel Holtmann 
3851a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
3852a9de9248SMarcel Holtmann }
3853a9de9248SMarcel Holtmann 
38541c2e0041SJohan Hedberg static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
38551c2e0041SJohan Hedberg 					 struct sk_buff *skb)
38561c2e0041SJohan Hedberg {
38571c2e0041SJohan Hedberg 	struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
38581c2e0041SJohan Hedberg 	struct hci_conn *conn;
38591c2e0041SJohan Hedberg 
38609f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
38611c2e0041SJohan Hedberg 	       __le16_to_cpu(ev->handle));
38621c2e0041SJohan Hedberg 
38631c2e0041SJohan Hedberg 	hci_dev_lock(hdev);
38641c2e0041SJohan Hedberg 
38651c2e0041SJohan Hedberg 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
38661c2e0041SJohan Hedberg 	if (!conn)
38671c2e0041SJohan Hedberg 		goto unlock;
38681c2e0041SJohan Hedberg 
38699eb1fbfaSJohan Hedberg 	/* For BR/EDR the necessary steps are taken through the
38709eb1fbfaSJohan Hedberg 	 * auth_complete event.
38719eb1fbfaSJohan Hedberg 	 */
38729eb1fbfaSJohan Hedberg 	if (conn->type != LE_LINK)
38739eb1fbfaSJohan Hedberg 		goto unlock;
38749eb1fbfaSJohan Hedberg 
38751c2e0041SJohan Hedberg 	if (!ev->status)
38761c2e0041SJohan Hedberg 		conn->sec_level = conn->pending_sec_level;
38771c2e0041SJohan Hedberg 
38781c2e0041SJohan Hedberg 	clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
38791c2e0041SJohan Hedberg 
38801c2e0041SJohan Hedberg 	if (ev->status && conn->state == BT_CONNECTED) {
3881bed71748SAndre Guedes 		hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
388276a68ba0SDavid Herrmann 		hci_conn_drop(conn);
38831c2e0041SJohan Hedberg 		goto unlock;
38841c2e0041SJohan Hedberg 	}
38851c2e0041SJohan Hedberg 
38861c2e0041SJohan Hedberg 	if (conn->state == BT_CONFIG) {
38871c2e0041SJohan Hedberg 		if (!ev->status)
38881c2e0041SJohan Hedberg 			conn->state = BT_CONNECTED;
38891c2e0041SJohan Hedberg 
3890539c496dSJohan Hedberg 		hci_connect_cfm(conn, ev->status);
389176a68ba0SDavid Herrmann 		hci_conn_drop(conn);
38921c2e0041SJohan Hedberg 	} else {
38931c2e0041SJohan Hedberg 		hci_auth_cfm(conn, ev->status);
38941c2e0041SJohan Hedberg 
38951c2e0041SJohan Hedberg 		hci_conn_hold(conn);
38961c2e0041SJohan Hedberg 		conn->disc_timeout = HCI_DISCONN_TIMEOUT;
389776a68ba0SDavid Herrmann 		hci_conn_drop(conn);
38981c2e0041SJohan Hedberg 	}
38991c2e0041SJohan Hedberg 
39001c2e0041SJohan Hedberg unlock:
39011c2e0041SJohan Hedberg 	hci_dev_unlock(hdev);
39021c2e0041SJohan Hedberg }
39031c2e0041SJohan Hedberg 
39046039aa73SGustavo Padovan static u8 hci_get_auth_req(struct hci_conn *conn)
390517fa4b9dSJohan Hedberg {
390617fa4b9dSJohan Hedberg 	/* If remote requests no-bonding follow that lead */
3907acabae96SMikel Astiz 	if (conn->remote_auth == HCI_AT_NO_BONDING ||
3908acabae96SMikel Astiz 	    conn->remote_auth == HCI_AT_NO_BONDING_MITM)
390958797bf7SWaldemar Rymarkiewicz 		return conn->remote_auth | (conn->auth_type & 0x01);
391017fa4b9dSJohan Hedberg 
3911b7f94c88SMikel Astiz 	/* If both remote and local have enough IO capabilities, require
3912b7f94c88SMikel Astiz 	 * MITM protection
3913b7f94c88SMikel Astiz 	 */
3914b7f94c88SMikel Astiz 	if (conn->remote_cap != HCI_IO_NO_INPUT_OUTPUT &&
3915b7f94c88SMikel Astiz 	    conn->io_capability != HCI_IO_NO_INPUT_OUTPUT)
3916b7f94c88SMikel Astiz 		return conn->remote_auth | 0x01;
3917b7f94c88SMikel Astiz 
39187e74170aSTimo Mueller 	/* No MITM protection possible so ignore remote requirement */
39197e74170aSTimo Mueller 	return (conn->remote_auth & ~0x01) | (conn->auth_type & 0x01);
392017fa4b9dSJohan Hedberg }
392117fa4b9dSJohan Hedberg 
3922a83ed81eSMarcel Holtmann static u8 bredr_oob_data_present(struct hci_conn *conn)
3923a83ed81eSMarcel Holtmann {
3924a83ed81eSMarcel Holtmann 	struct hci_dev *hdev = conn->hdev;
3925a83ed81eSMarcel Holtmann 	struct oob_data *data;
3926a83ed81eSMarcel Holtmann 
3927a83ed81eSMarcel Holtmann 	data = hci_find_remote_oob_data(hdev, &conn->dst, BDADDR_BREDR);
3928a83ed81eSMarcel Holtmann 	if (!data)
3929a83ed81eSMarcel Holtmann 		return 0x00;
3930a83ed81eSMarcel Holtmann 
3931bf21d793SMarcel Holtmann 	if (bredr_sc_enabled(hdev)) {
3932bf21d793SMarcel Holtmann 		/* When Secure Connections is enabled, then just
3933bf21d793SMarcel Holtmann 		 * return the present value stored with the OOB
3934bf21d793SMarcel Holtmann 		 * data. The stored value contains the right present
3935bf21d793SMarcel Holtmann 		 * information. However it can only be trusted when
3936bf21d793SMarcel Holtmann 		 * not in Secure Connection Only mode.
3937aa5b0345SMarcel Holtmann 		 */
3938d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_SC_ONLY))
3939bf21d793SMarcel Holtmann 			return data->present;
3940bf21d793SMarcel Holtmann 
3941bf21d793SMarcel Holtmann 		/* When Secure Connections Only mode is enabled, then
3942bf21d793SMarcel Holtmann 		 * the P-256 values are required. If they are not
3943bf21d793SMarcel Holtmann 		 * available, then do not declare that OOB data is
3944bf21d793SMarcel Holtmann 		 * present.
3945bf21d793SMarcel Holtmann 		 */
3946bf21d793SMarcel Holtmann 		if (!memcmp(data->rand256, ZERO_KEY, 16) ||
3947bf21d793SMarcel Holtmann 		    !memcmp(data->hash256, ZERO_KEY, 16))
3948aa5b0345SMarcel Holtmann 			return 0x00;
3949aa5b0345SMarcel Holtmann 
3950bf21d793SMarcel Holtmann 		return 0x02;
3951bf21d793SMarcel Holtmann 	}
3952659c7fb0SMarcel Holtmann 
3953659c7fb0SMarcel Holtmann 	/* When Secure Connections is not enabled or actually
3954659c7fb0SMarcel Holtmann 	 * not supported by the hardware, then check that if
3955659c7fb0SMarcel Holtmann 	 * P-192 data values are present.
3956659c7fb0SMarcel Holtmann 	 */
3957659c7fb0SMarcel Holtmann 	if (!memcmp(data->rand192, ZERO_KEY, 16) ||
3958659c7fb0SMarcel Holtmann 	    !memcmp(data->hash192, ZERO_KEY, 16))
3959659c7fb0SMarcel Holtmann 		return 0x00;
3960659c7fb0SMarcel Holtmann 
3961a83ed81eSMarcel Holtmann 	return 0x01;
3962659c7fb0SMarcel Holtmann }
3963a83ed81eSMarcel Holtmann 
39646039aa73SGustavo Padovan static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
39650493684eSMarcel Holtmann {
39660493684eSMarcel Holtmann 	struct hci_ev_io_capa_request *ev = (void *) skb->data;
39670493684eSMarcel Holtmann 	struct hci_conn *conn;
39680493684eSMarcel Holtmann 
39690493684eSMarcel Holtmann 	BT_DBG("%s", hdev->name);
39700493684eSMarcel Holtmann 
39710493684eSMarcel Holtmann 	hci_dev_lock(hdev);
39720493684eSMarcel Holtmann 
39730493684eSMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
397403b555e1SJohan Hedberg 	if (!conn)
397503b555e1SJohan Hedberg 		goto unlock;
397603b555e1SJohan Hedberg 
39770493684eSMarcel Holtmann 	hci_conn_hold(conn);
39780493684eSMarcel Holtmann 
3979d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
398003b555e1SJohan Hedberg 		goto unlock;
398103b555e1SJohan Hedberg 
39822f407f0aSJohan Hedberg 	/* Allow pairing if we're pairable, the initiators of the
39832f407f0aSJohan Hedberg 	 * pairing or if the remote is not requesting bonding.
39842f407f0aSJohan Hedberg 	 */
3985d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_BONDABLE) ||
39862f407f0aSJohan Hedberg 	    test_bit(HCI_CONN_AUTH_INITIATOR, &conn->flags) ||
398703b555e1SJohan Hedberg 	    (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
398817fa4b9dSJohan Hedberg 		struct hci_cp_io_capability_reply cp;
398917fa4b9dSJohan Hedberg 
399017fa4b9dSJohan Hedberg 		bacpy(&cp.bdaddr, &ev->bdaddr);
39917a7f1e7cSHemant Gupta 		/* Change the IO capability from KeyboardDisplay
39927a7f1e7cSHemant Gupta 		 * to DisplayYesNo as it is not supported by BT spec. */
39937a7f1e7cSHemant Gupta 		cp.capability = (conn->io_capability == 0x04) ?
3994a767631aSMikel Astiz 				HCI_IO_DISPLAY_YESNO : conn->io_capability;
3995b7f94c88SMikel Astiz 
3996b7f94c88SMikel Astiz 		/* If we are initiators, there is no remote information yet */
3997b7f94c88SMikel Astiz 		if (conn->remote_auth == 0xff) {
3998b16c6604SMikel Astiz 			/* Request MITM protection if our IO caps allow it
39994ad51a75SJohan Hedberg 			 * except for the no-bonding case.
4000b16c6604SMikel Astiz 			 */
40016fd6b915SMikel Astiz 			if (conn->io_capability != HCI_IO_NO_INPUT_OUTPUT &&
40029f743d74SJohan Hedberg 			    conn->auth_type != HCI_AT_NO_BONDING)
40036c53823aSJohan Hedberg 				conn->auth_type |= 0x01;
4004b7f94c88SMikel Astiz 		} else {
40057cbc9bd9SJohan Hedberg 			conn->auth_type = hci_get_auth_req(conn);
4006b7f94c88SMikel Astiz 		}
400717fa4b9dSJohan Hedberg 
400882c295b1SJohan Hedberg 		/* If we're not bondable, force one of the non-bondable
400982c295b1SJohan Hedberg 		 * authentication requirement values.
401082c295b1SJohan Hedberg 		 */
4011d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_BONDABLE))
401282c295b1SJohan Hedberg 			conn->auth_type &= HCI_AT_NO_BONDING_MITM;
401382c295b1SJohan Hedberg 
401482c295b1SJohan Hedberg 		cp.authentication = conn->auth_type;
4015a83ed81eSMarcel Holtmann 		cp.oob_data = bredr_oob_data_present(conn);
4016ce85ee13SSzymon Janc 
401717fa4b9dSJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
401817fa4b9dSJohan Hedberg 			     sizeof(cp), &cp);
401903b555e1SJohan Hedberg 	} else {
402003b555e1SJohan Hedberg 		struct hci_cp_io_capability_neg_reply cp;
402103b555e1SJohan Hedberg 
402203b555e1SJohan Hedberg 		bacpy(&cp.bdaddr, &ev->bdaddr);
40239f5a0d7bSAndrei Emeltchenko 		cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
402403b555e1SJohan Hedberg 
402503b555e1SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
402603b555e1SJohan Hedberg 			     sizeof(cp), &cp);
402703b555e1SJohan Hedberg 	}
402803b555e1SJohan Hedberg 
402903b555e1SJohan Hedberg unlock:
403003b555e1SJohan Hedberg 	hci_dev_unlock(hdev);
403103b555e1SJohan Hedberg }
403203b555e1SJohan Hedberg 
40336039aa73SGustavo Padovan static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
403403b555e1SJohan Hedberg {
403503b555e1SJohan Hedberg 	struct hci_ev_io_capa_reply *ev = (void *) skb->data;
403603b555e1SJohan Hedberg 	struct hci_conn *conn;
403703b555e1SJohan Hedberg 
403803b555e1SJohan Hedberg 	BT_DBG("%s", hdev->name);
403903b555e1SJohan Hedberg 
404003b555e1SJohan Hedberg 	hci_dev_lock(hdev);
404103b555e1SJohan Hedberg 
404203b555e1SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
404303b555e1SJohan Hedberg 	if (!conn)
404403b555e1SJohan Hedberg 		goto unlock;
404503b555e1SJohan Hedberg 
404603b555e1SJohan Hedberg 	conn->remote_cap = ev->capability;
404703b555e1SJohan Hedberg 	conn->remote_auth = ev->authentication;
404803b555e1SJohan Hedberg 
404903b555e1SJohan Hedberg unlock:
40500493684eSMarcel Holtmann 	hci_dev_unlock(hdev);
40510493684eSMarcel Holtmann }
40520493684eSMarcel Holtmann 
40536039aa73SGustavo Padovan static void hci_user_confirm_request_evt(struct hci_dev *hdev,
4054a5c29683SJohan Hedberg 					 struct sk_buff *skb)
4055a5c29683SJohan Hedberg {
4056a5c29683SJohan Hedberg 	struct hci_ev_user_confirm_req *ev = (void *) skb->data;
405755bc1a37SJohan Hedberg 	int loc_mitm, rem_mitm, confirm_hint = 0;
40587a828908SJohan Hedberg 	struct hci_conn *conn;
4059a5c29683SJohan Hedberg 
4060a5c29683SJohan Hedberg 	BT_DBG("%s", hdev->name);
4061a5c29683SJohan Hedberg 
4062a5c29683SJohan Hedberg 	hci_dev_lock(hdev);
4063a5c29683SJohan Hedberg 
4064d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
40657a828908SJohan Hedberg 		goto unlock;
40667a828908SJohan Hedberg 
40677a828908SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
40687a828908SJohan Hedberg 	if (!conn)
40697a828908SJohan Hedberg 		goto unlock;
40707a828908SJohan Hedberg 
40717a828908SJohan Hedberg 	loc_mitm = (conn->auth_type & 0x01);
40727a828908SJohan Hedberg 	rem_mitm = (conn->remote_auth & 0x01);
40737a828908SJohan Hedberg 
40747a828908SJohan Hedberg 	/* If we require MITM but the remote device can't provide that
40756c53823aSJohan Hedberg 	 * (it has NoInputNoOutput) then reject the confirmation
40766c53823aSJohan Hedberg 	 * request. We check the security level here since it doesn't
40776c53823aSJohan Hedberg 	 * necessarily match conn->auth_type.
40786fd6b915SMikel Astiz 	 */
40796c53823aSJohan Hedberg 	if (conn->pending_sec_level > BT_SECURITY_MEDIUM &&
40806c53823aSJohan Hedberg 	    conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
40817a828908SJohan Hedberg 		BT_DBG("Rejecting request: remote device can't provide MITM");
40827a828908SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
40837a828908SJohan Hedberg 			     sizeof(ev->bdaddr), &ev->bdaddr);
40847a828908SJohan Hedberg 		goto unlock;
40857a828908SJohan Hedberg 	}
40867a828908SJohan Hedberg 
40877a828908SJohan Hedberg 	/* If no side requires MITM protection; auto-accept */
4088a767631aSMikel Astiz 	if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
4089a767631aSMikel Astiz 	    (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
409055bc1a37SJohan Hedberg 
409155bc1a37SJohan Hedberg 		/* If we're not the initiators request authorization to
409255bc1a37SJohan Hedberg 		 * proceed from user space (mgmt_user_confirm with
4093ba15a58bSJohan Hedberg 		 * confirm_hint set to 1). The exception is if neither
409402f3e254SJohan Hedberg 		 * side had MITM or if the local IO capability is
409502f3e254SJohan Hedberg 		 * NoInputNoOutput, in which case we do auto-accept
4096ba15a58bSJohan Hedberg 		 */
4097ba15a58bSJohan Hedberg 		if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) &&
409802f3e254SJohan Hedberg 		    conn->io_capability != HCI_IO_NO_INPUT_OUTPUT &&
4099ba15a58bSJohan Hedberg 		    (loc_mitm || rem_mitm)) {
410055bc1a37SJohan Hedberg 			BT_DBG("Confirming auto-accept as acceptor");
410155bc1a37SJohan Hedberg 			confirm_hint = 1;
410255bc1a37SJohan Hedberg 			goto confirm;
410355bc1a37SJohan Hedberg 		}
410455bc1a37SJohan Hedberg 
41059f61656aSJohan Hedberg 		BT_DBG("Auto-accept of user confirmation with %ums delay",
41069f61656aSJohan Hedberg 		       hdev->auto_accept_delay);
41079f61656aSJohan Hedberg 
41089f61656aSJohan Hedberg 		if (hdev->auto_accept_delay > 0) {
41099f61656aSJohan Hedberg 			int delay = msecs_to_jiffies(hdev->auto_accept_delay);
41107bc18d9dSJohan Hedberg 			queue_delayed_work(conn->hdev->workqueue,
41117bc18d9dSJohan Hedberg 					   &conn->auto_accept_work, delay);
41129f61656aSJohan Hedberg 			goto unlock;
41139f61656aSJohan Hedberg 		}
41149f61656aSJohan Hedberg 
41157a828908SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
41167a828908SJohan Hedberg 			     sizeof(ev->bdaddr), &ev->bdaddr);
41177a828908SJohan Hedberg 		goto unlock;
41187a828908SJohan Hedberg 	}
41197a828908SJohan Hedberg 
412055bc1a37SJohan Hedberg confirm:
412139adbffeSJohan Hedberg 	mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0,
412239adbffeSJohan Hedberg 				  le32_to_cpu(ev->passkey), confirm_hint);
4123a5c29683SJohan Hedberg 
41247a828908SJohan Hedberg unlock:
4125a5c29683SJohan Hedberg 	hci_dev_unlock(hdev);
4126a5c29683SJohan Hedberg }
4127a5c29683SJohan Hedberg 
41286039aa73SGustavo Padovan static void hci_user_passkey_request_evt(struct hci_dev *hdev,
41291143d458SBrian Gix 					 struct sk_buff *skb)
41301143d458SBrian Gix {
41311143d458SBrian Gix 	struct hci_ev_user_passkey_req *ev = (void *) skb->data;
41321143d458SBrian Gix 
41331143d458SBrian Gix 	BT_DBG("%s", hdev->name);
41341143d458SBrian Gix 
4135d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
4136272d90dfSJohan Hedberg 		mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
41371143d458SBrian Gix }
41381143d458SBrian Gix 
413992a25256SJohan Hedberg static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
414092a25256SJohan Hedberg 					struct sk_buff *skb)
414192a25256SJohan Hedberg {
414292a25256SJohan Hedberg 	struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
414392a25256SJohan Hedberg 	struct hci_conn *conn;
414492a25256SJohan Hedberg 
414592a25256SJohan Hedberg 	BT_DBG("%s", hdev->name);
414692a25256SJohan Hedberg 
414792a25256SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
414892a25256SJohan Hedberg 	if (!conn)
414992a25256SJohan Hedberg 		return;
415092a25256SJohan Hedberg 
415192a25256SJohan Hedberg 	conn->passkey_notify = __le32_to_cpu(ev->passkey);
415292a25256SJohan Hedberg 	conn->passkey_entered = 0;
415392a25256SJohan Hedberg 
4154d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
415592a25256SJohan Hedberg 		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
415692a25256SJohan Hedberg 					 conn->dst_type, conn->passkey_notify,
415792a25256SJohan Hedberg 					 conn->passkey_entered);
415892a25256SJohan Hedberg }
415992a25256SJohan Hedberg 
416092a25256SJohan Hedberg static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
416192a25256SJohan Hedberg {
416292a25256SJohan Hedberg 	struct hci_ev_keypress_notify *ev = (void *) skb->data;
416392a25256SJohan Hedberg 	struct hci_conn *conn;
416492a25256SJohan Hedberg 
416592a25256SJohan Hedberg 	BT_DBG("%s", hdev->name);
416692a25256SJohan Hedberg 
416792a25256SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
416892a25256SJohan Hedberg 	if (!conn)
416992a25256SJohan Hedberg 		return;
417092a25256SJohan Hedberg 
417192a25256SJohan Hedberg 	switch (ev->type) {
417292a25256SJohan Hedberg 	case HCI_KEYPRESS_STARTED:
417392a25256SJohan Hedberg 		conn->passkey_entered = 0;
417492a25256SJohan Hedberg 		return;
417592a25256SJohan Hedberg 
417692a25256SJohan Hedberg 	case HCI_KEYPRESS_ENTERED:
417792a25256SJohan Hedberg 		conn->passkey_entered++;
417892a25256SJohan Hedberg 		break;
417992a25256SJohan Hedberg 
418092a25256SJohan Hedberg 	case HCI_KEYPRESS_ERASED:
418192a25256SJohan Hedberg 		conn->passkey_entered--;
418292a25256SJohan Hedberg 		break;
418392a25256SJohan Hedberg 
418492a25256SJohan Hedberg 	case HCI_KEYPRESS_CLEARED:
418592a25256SJohan Hedberg 		conn->passkey_entered = 0;
418692a25256SJohan Hedberg 		break;
418792a25256SJohan Hedberg 
418892a25256SJohan Hedberg 	case HCI_KEYPRESS_COMPLETED:
418992a25256SJohan Hedberg 		return;
419092a25256SJohan Hedberg 	}
419192a25256SJohan Hedberg 
4192d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
419392a25256SJohan Hedberg 		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
419492a25256SJohan Hedberg 					 conn->dst_type, conn->passkey_notify,
419592a25256SJohan Hedberg 					 conn->passkey_entered);
419692a25256SJohan Hedberg }
419792a25256SJohan Hedberg 
41986039aa73SGustavo Padovan static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
4199807deac2SGustavo Padovan 					 struct sk_buff *skb)
42000493684eSMarcel Holtmann {
42010493684eSMarcel Holtmann 	struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
42020493684eSMarcel Holtmann 	struct hci_conn *conn;
42030493684eSMarcel Holtmann 
42040493684eSMarcel Holtmann 	BT_DBG("%s", hdev->name);
42050493684eSMarcel Holtmann 
42060493684eSMarcel Holtmann 	hci_dev_lock(hdev);
42070493684eSMarcel Holtmann 
42080493684eSMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
42092a611692SJohan Hedberg 	if (!conn)
42102a611692SJohan Hedberg 		goto unlock;
42112a611692SJohan Hedberg 
4212c1d4fa7aSJohan Hedberg 	/* Reset the authentication requirement to unknown */
4213c1d4fa7aSJohan Hedberg 	conn->remote_auth = 0xff;
4214c1d4fa7aSJohan Hedberg 
42152a611692SJohan Hedberg 	/* To avoid duplicate auth_failed events to user space we check
42162a611692SJohan Hedberg 	 * the HCI_CONN_AUTH_PEND flag which will be set if we
42172a611692SJohan Hedberg 	 * initiated the authentication. A traditional auth_complete
42182a611692SJohan Hedberg 	 * event gets always produced as initiator and is also mapped to
42192a611692SJohan Hedberg 	 * the mgmt_auth_failed event */
4220fa1bd918SMikel Astiz 	if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
4221e1e930f5SJohan Hedberg 		mgmt_auth_failed(conn, ev->status);
42222a611692SJohan Hedberg 
422376a68ba0SDavid Herrmann 	hci_conn_drop(conn);
42240493684eSMarcel Holtmann 
42252a611692SJohan Hedberg unlock:
42260493684eSMarcel Holtmann 	hci_dev_unlock(hdev);
42270493684eSMarcel Holtmann }
42280493684eSMarcel Holtmann 
42296039aa73SGustavo Padovan static void hci_remote_host_features_evt(struct hci_dev *hdev,
4230807deac2SGustavo Padovan 					 struct sk_buff *skb)
423141a96212SMarcel Holtmann {
423241a96212SMarcel Holtmann 	struct hci_ev_remote_host_features *ev = (void *) skb->data;
423341a96212SMarcel Holtmann 	struct inquiry_entry *ie;
4234cad718edSJohan Hedberg 	struct hci_conn *conn;
423541a96212SMarcel Holtmann 
423641a96212SMarcel Holtmann 	BT_DBG("%s", hdev->name);
423741a96212SMarcel Holtmann 
423841a96212SMarcel Holtmann 	hci_dev_lock(hdev);
423941a96212SMarcel Holtmann 
4240cad718edSJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
4241cad718edSJohan Hedberg 	if (conn)
4242cad718edSJohan Hedberg 		memcpy(conn->features[1], ev->features, 8);
4243cad718edSJohan Hedberg 
4244cc11b9c1SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
4245cc11b9c1SAndrei Emeltchenko 	if (ie)
424602b7cc62SJohan Hedberg 		ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
424741a96212SMarcel Holtmann 
424841a96212SMarcel Holtmann 	hci_dev_unlock(hdev);
424941a96212SMarcel Holtmann }
425041a96212SMarcel Holtmann 
42516039aa73SGustavo Padovan static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
42522763eda6SSzymon Janc 					    struct sk_buff *skb)
42532763eda6SSzymon Janc {
42542763eda6SSzymon Janc 	struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
42552763eda6SSzymon Janc 	struct oob_data *data;
42562763eda6SSzymon Janc 
42572763eda6SSzymon Janc 	BT_DBG("%s", hdev->name);
42582763eda6SSzymon Janc 
42592763eda6SSzymon Janc 	hci_dev_lock(hdev);
42602763eda6SSzymon Janc 
4261d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
4262e1ba1f15SSzymon Janc 		goto unlock;
4263e1ba1f15SSzymon Janc 
42646928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, &ev->bdaddr, BDADDR_BREDR);
42656665d057SMarcel Holtmann 	if (!data) {
42666665d057SMarcel Holtmann 		struct hci_cp_remote_oob_data_neg_reply cp;
42676665d057SMarcel Holtmann 
42686665d057SMarcel Holtmann 		bacpy(&cp.bdaddr, &ev->bdaddr);
42696665d057SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY,
42706665d057SMarcel Holtmann 			     sizeof(cp), &cp);
42716665d057SMarcel Holtmann 		goto unlock;
42726665d057SMarcel Holtmann 	}
42736665d057SMarcel Holtmann 
4274710f11c0SJohan Hedberg 	if (bredr_sc_enabled(hdev)) {
4275519ca9d0SMarcel Holtmann 		struct hci_cp_remote_oob_ext_data_reply cp;
4276519ca9d0SMarcel Holtmann 
4277519ca9d0SMarcel Holtmann 		bacpy(&cp.bdaddr, &ev->bdaddr);
4278d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_SC_ONLY)) {
42796665d057SMarcel Holtmann 			memset(cp.hash192, 0, sizeof(cp.hash192));
42806665d057SMarcel Holtmann 			memset(cp.rand192, 0, sizeof(cp.rand192));
42816665d057SMarcel Holtmann 		} else {
4282519ca9d0SMarcel Holtmann 			memcpy(cp.hash192, data->hash192, sizeof(cp.hash192));
428338da1703SJohan Hedberg 			memcpy(cp.rand192, data->rand192, sizeof(cp.rand192));
42846665d057SMarcel Holtmann 		}
4285519ca9d0SMarcel Holtmann 		memcpy(cp.hash256, data->hash256, sizeof(cp.hash256));
428638da1703SJohan Hedberg 		memcpy(cp.rand256, data->rand256, sizeof(cp.rand256));
4287519ca9d0SMarcel Holtmann 
4288519ca9d0SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY,
4289519ca9d0SMarcel Holtmann 			     sizeof(cp), &cp);
4290519ca9d0SMarcel Holtmann 	} else {
42912763eda6SSzymon Janc 		struct hci_cp_remote_oob_data_reply cp;
42922763eda6SSzymon Janc 
42932763eda6SSzymon Janc 		bacpy(&cp.bdaddr, &ev->bdaddr);
4294519ca9d0SMarcel Holtmann 		memcpy(cp.hash, data->hash192, sizeof(cp.hash));
429538da1703SJohan Hedberg 		memcpy(cp.rand, data->rand192, sizeof(cp.rand));
42962763eda6SSzymon Janc 
4297519ca9d0SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY,
4298519ca9d0SMarcel Holtmann 			     sizeof(cp), &cp);
4299519ca9d0SMarcel Holtmann 	}
43002763eda6SSzymon Janc 
4301e1ba1f15SSzymon Janc unlock:
43022763eda6SSzymon Janc 	hci_dev_unlock(hdev);
43032763eda6SSzymon Janc }
43042763eda6SSzymon Janc 
4305a77a6a14SArron Wang #if IS_ENABLED(CONFIG_BT_HS)
4306a77a6a14SArron Wang static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
4307a77a6a14SArron Wang {
4308a77a6a14SArron Wang 	struct hci_ev_channel_selected *ev = (void *)skb->data;
4309a77a6a14SArron Wang 	struct hci_conn *hcon;
4310a77a6a14SArron Wang 
4311a77a6a14SArron Wang 	BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
4312a77a6a14SArron Wang 
4313a77a6a14SArron Wang 	skb_pull(skb, sizeof(*ev));
4314a77a6a14SArron Wang 
4315a77a6a14SArron Wang 	hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
4316a77a6a14SArron Wang 	if (!hcon)
4317a77a6a14SArron Wang 		return;
4318a77a6a14SArron Wang 
4319a77a6a14SArron Wang 	amp_read_loc_assoc_final_data(hdev, hcon);
4320a77a6a14SArron Wang }
4321a77a6a14SArron Wang 
4322d5e91192SAndrei Emeltchenko static void hci_phy_link_complete_evt(struct hci_dev *hdev,
4323d5e91192SAndrei Emeltchenko 				      struct sk_buff *skb)
4324d5e91192SAndrei Emeltchenko {
4325d5e91192SAndrei Emeltchenko 	struct hci_ev_phy_link_complete *ev = (void *) skb->data;
4326d5e91192SAndrei Emeltchenko 	struct hci_conn *hcon, *bredr_hcon;
4327d5e91192SAndrei Emeltchenko 
4328d5e91192SAndrei Emeltchenko 	BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
4329d5e91192SAndrei Emeltchenko 	       ev->status);
4330d5e91192SAndrei Emeltchenko 
4331d5e91192SAndrei Emeltchenko 	hci_dev_lock(hdev);
4332d5e91192SAndrei Emeltchenko 
4333d5e91192SAndrei Emeltchenko 	hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
4334d5e91192SAndrei Emeltchenko 	if (!hcon) {
4335d5e91192SAndrei Emeltchenko 		hci_dev_unlock(hdev);
4336d5e91192SAndrei Emeltchenko 		return;
4337d5e91192SAndrei Emeltchenko 	}
4338d5e91192SAndrei Emeltchenko 
4339d5e91192SAndrei Emeltchenko 	if (ev->status) {
4340d5e91192SAndrei Emeltchenko 		hci_conn_del(hcon);
4341d5e91192SAndrei Emeltchenko 		hci_dev_unlock(hdev);
4342d5e91192SAndrei Emeltchenko 		return;
4343d5e91192SAndrei Emeltchenko 	}
4344d5e91192SAndrei Emeltchenko 
4345d5e91192SAndrei Emeltchenko 	bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
4346d5e91192SAndrei Emeltchenko 
4347d5e91192SAndrei Emeltchenko 	hcon->state = BT_CONNECTED;
4348d5e91192SAndrei Emeltchenko 	bacpy(&hcon->dst, &bredr_hcon->dst);
4349d5e91192SAndrei Emeltchenko 
4350d5e91192SAndrei Emeltchenko 	hci_conn_hold(hcon);
4351d5e91192SAndrei Emeltchenko 	hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
435276a68ba0SDavid Herrmann 	hci_conn_drop(hcon);
4353d5e91192SAndrei Emeltchenko 
435423b9ceb7SMarcel Holtmann 	hci_debugfs_create_conn(hcon);
4355d5e91192SAndrei Emeltchenko 	hci_conn_add_sysfs(hcon);
4356d5e91192SAndrei Emeltchenko 
4357cf70ff22SAndrei Emeltchenko 	amp_physical_cfm(bredr_hcon, hcon);
4358cf70ff22SAndrei Emeltchenko 
4359d5e91192SAndrei Emeltchenko 	hci_dev_unlock(hdev);
4360d5e91192SAndrei Emeltchenko }
4361d5e91192SAndrei Emeltchenko 
436227695fb4SAndrei Emeltchenko static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
436327695fb4SAndrei Emeltchenko {
436427695fb4SAndrei Emeltchenko 	struct hci_ev_logical_link_complete *ev = (void *) skb->data;
436527695fb4SAndrei Emeltchenko 	struct hci_conn *hcon;
436627695fb4SAndrei Emeltchenko 	struct hci_chan *hchan;
436727695fb4SAndrei Emeltchenko 	struct amp_mgr *mgr;
436827695fb4SAndrei Emeltchenko 
436927695fb4SAndrei Emeltchenko 	BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
437027695fb4SAndrei Emeltchenko 	       hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
437127695fb4SAndrei Emeltchenko 	       ev->status);
437227695fb4SAndrei Emeltchenko 
437327695fb4SAndrei Emeltchenko 	hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
437427695fb4SAndrei Emeltchenko 	if (!hcon)
437527695fb4SAndrei Emeltchenko 		return;
437627695fb4SAndrei Emeltchenko 
437727695fb4SAndrei Emeltchenko 	/* Create AMP hchan */
437827695fb4SAndrei Emeltchenko 	hchan = hci_chan_create(hcon);
437927695fb4SAndrei Emeltchenko 	if (!hchan)
438027695fb4SAndrei Emeltchenko 		return;
438127695fb4SAndrei Emeltchenko 
438227695fb4SAndrei Emeltchenko 	hchan->handle = le16_to_cpu(ev->handle);
438327695fb4SAndrei Emeltchenko 
438427695fb4SAndrei Emeltchenko 	BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
438527695fb4SAndrei Emeltchenko 
438627695fb4SAndrei Emeltchenko 	mgr = hcon->amp_mgr;
438727695fb4SAndrei Emeltchenko 	if (mgr && mgr->bredr_chan) {
438827695fb4SAndrei Emeltchenko 		struct l2cap_chan *bredr_chan = mgr->bredr_chan;
438927695fb4SAndrei Emeltchenko 
439027695fb4SAndrei Emeltchenko 		l2cap_chan_lock(bredr_chan);
439127695fb4SAndrei Emeltchenko 
439227695fb4SAndrei Emeltchenko 		bredr_chan->conn->mtu = hdev->block_mtu;
439327695fb4SAndrei Emeltchenko 		l2cap_logical_cfm(bredr_chan, hchan, 0);
439427695fb4SAndrei Emeltchenko 		hci_conn_hold(hcon);
439527695fb4SAndrei Emeltchenko 
439627695fb4SAndrei Emeltchenko 		l2cap_chan_unlock(bredr_chan);
439727695fb4SAndrei Emeltchenko 	}
439827695fb4SAndrei Emeltchenko }
439927695fb4SAndrei Emeltchenko 
4400606e2a10SAndrei Emeltchenko static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
4401606e2a10SAndrei Emeltchenko 					     struct sk_buff *skb)
4402606e2a10SAndrei Emeltchenko {
4403606e2a10SAndrei Emeltchenko 	struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
4404606e2a10SAndrei Emeltchenko 	struct hci_chan *hchan;
4405606e2a10SAndrei Emeltchenko 
4406606e2a10SAndrei Emeltchenko 	BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
4407606e2a10SAndrei Emeltchenko 	       le16_to_cpu(ev->handle), ev->status);
4408606e2a10SAndrei Emeltchenko 
4409606e2a10SAndrei Emeltchenko 	if (ev->status)
4410606e2a10SAndrei Emeltchenko 		return;
4411606e2a10SAndrei Emeltchenko 
4412606e2a10SAndrei Emeltchenko 	hci_dev_lock(hdev);
4413606e2a10SAndrei Emeltchenko 
4414606e2a10SAndrei Emeltchenko 	hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
4415606e2a10SAndrei Emeltchenko 	if (!hchan)
4416606e2a10SAndrei Emeltchenko 		goto unlock;
4417606e2a10SAndrei Emeltchenko 
4418606e2a10SAndrei Emeltchenko 	amp_destroy_logical_link(hchan, ev->reason);
4419606e2a10SAndrei Emeltchenko 
4420606e2a10SAndrei Emeltchenko unlock:
4421606e2a10SAndrei Emeltchenko 	hci_dev_unlock(hdev);
4422606e2a10SAndrei Emeltchenko }
4423606e2a10SAndrei Emeltchenko 
44249eef6b3aSAndrei Emeltchenko static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
44259eef6b3aSAndrei Emeltchenko 					     struct sk_buff *skb)
44269eef6b3aSAndrei Emeltchenko {
44279eef6b3aSAndrei Emeltchenko 	struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
44289eef6b3aSAndrei Emeltchenko 	struct hci_conn *hcon;
44299eef6b3aSAndrei Emeltchenko 
44309eef6b3aSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
44319eef6b3aSAndrei Emeltchenko 
44329eef6b3aSAndrei Emeltchenko 	if (ev->status)
44339eef6b3aSAndrei Emeltchenko 		return;
44349eef6b3aSAndrei Emeltchenko 
44359eef6b3aSAndrei Emeltchenko 	hci_dev_lock(hdev);
44369eef6b3aSAndrei Emeltchenko 
44379eef6b3aSAndrei Emeltchenko 	hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
44389eef6b3aSAndrei Emeltchenko 	if (hcon) {
44399eef6b3aSAndrei Emeltchenko 		hcon->state = BT_CLOSED;
44409eef6b3aSAndrei Emeltchenko 		hci_conn_del(hcon);
44419eef6b3aSAndrei Emeltchenko 	}
44429eef6b3aSAndrei Emeltchenko 
44439eef6b3aSAndrei Emeltchenko 	hci_dev_unlock(hdev);
44449eef6b3aSAndrei Emeltchenko }
4445a77a6a14SArron Wang #endif
44469eef6b3aSAndrei Emeltchenko 
44476039aa73SGustavo Padovan static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
4448fcd89c09SVille Tervo {
4449fcd89c09SVille Tervo 	struct hci_ev_le_conn_complete *ev = (void *) skb->data;
4450912b42efSJohan Hedberg 	struct hci_conn_params *params;
4451fcd89c09SVille Tervo 	struct hci_conn *conn;
445268d6f6deSJohan Hedberg 	struct smp_irk *irk;
4453837d502eSJohan Hedberg 	u8 addr_type;
4454fcd89c09SVille Tervo 
44559f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
4456fcd89c09SVille Tervo 
4457fcd89c09SVille Tervo 	hci_dev_lock(hdev);
4458fcd89c09SVille Tervo 
4459fbd96c15SJohan Hedberg 	/* All controllers implicitly stop advertising in the event of a
4460fbd96c15SJohan Hedberg 	 * connection, so ensure that the state bit is cleared.
4461fbd96c15SJohan Hedberg 	 */
4462a358dc11SMarcel Holtmann 	hci_dev_clear_flag(hdev, HCI_LE_ADV);
4463fbd96c15SJohan Hedberg 
4464e7d9ab73SJakub Pawlowski 	conn = hci_lookup_le_connect(hdev);
4465b62f328bSVille Tervo 	if (!conn) {
4466a5c4e309SJohan Hedberg 		conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr, ev->role);
4467b62f328bSVille Tervo 		if (!conn) {
4468b62f328bSVille Tervo 			BT_ERR("No memory for new connection");
4469230fd16aSAndre Guedes 			goto unlock;
4470b62f328bSVille Tervo 		}
447129b7988aSAndre Guedes 
447229b7988aSAndre Guedes 		conn->dst_type = ev->bdaddr_type;
4473b9b343d2SAndre Guedes 
4474cb1d68f7SJohan Hedberg 		/* If we didn't have a hci_conn object previously
4475cb1d68f7SJohan Hedberg 		 * but we're in master role this must be something
4476cb1d68f7SJohan Hedberg 		 * initiated using a white list. Since white list based
4477cb1d68f7SJohan Hedberg 		 * connections are not "first class citizens" we don't
4478cb1d68f7SJohan Hedberg 		 * have full tracking of them. Therefore, we go ahead
4479cb1d68f7SJohan Hedberg 		 * with a "best effort" approach of determining the
4480cb1d68f7SJohan Hedberg 		 * initiator address based on the HCI_PRIVACY flag.
4481cb1d68f7SJohan Hedberg 		 */
4482cb1d68f7SJohan Hedberg 		if (conn->out) {
4483cb1d68f7SJohan Hedberg 			conn->resp_addr_type = ev->bdaddr_type;
4484cb1d68f7SJohan Hedberg 			bacpy(&conn->resp_addr, &ev->bdaddr);
4485d7a5a11dSMarcel Holtmann 			if (hci_dev_test_flag(hdev, HCI_PRIVACY)) {
4486cb1d68f7SJohan Hedberg 				conn->init_addr_type = ADDR_LE_DEV_RANDOM;
4487cb1d68f7SJohan Hedberg 				bacpy(&conn->init_addr, &hdev->rpa);
4488cb1d68f7SJohan Hedberg 			} else {
4489cb1d68f7SJohan Hedberg 				hci_copy_identity_address(hdev,
4490cb1d68f7SJohan Hedberg 							  &conn->init_addr,
4491cb1d68f7SJohan Hedberg 							  &conn->init_addr_type);
4492cb1d68f7SJohan Hedberg 			}
449380c24ab8SJohan Hedberg 		}
4494cb1d68f7SJohan Hedberg 	} else {
449580c24ab8SJohan Hedberg 		cancel_delayed_work(&conn->le_conn_timeout);
449680c24ab8SJohan Hedberg 	}
449780c24ab8SJohan Hedberg 
449880c24ab8SJohan Hedberg 	if (!conn->out) {
4499cb1d68f7SJohan Hedberg 		/* Set the responder (our side) address type based on
4500cb1d68f7SJohan Hedberg 		 * the advertising address type.
4501cb1d68f7SJohan Hedberg 		 */
4502cb1d68f7SJohan Hedberg 		conn->resp_addr_type = hdev->adv_addr_type;
4503cb1d68f7SJohan Hedberg 		if (hdev->adv_addr_type == ADDR_LE_DEV_RANDOM)
4504cb1d68f7SJohan Hedberg 			bacpy(&conn->resp_addr, &hdev->random_addr);
4505cb1d68f7SJohan Hedberg 		else
4506cb1d68f7SJohan Hedberg 			bacpy(&conn->resp_addr, &hdev->bdaddr);
4507cb1d68f7SJohan Hedberg 
4508cb1d68f7SJohan Hedberg 		conn->init_addr_type = ev->bdaddr_type;
4509cb1d68f7SJohan Hedberg 		bacpy(&conn->init_addr, &ev->bdaddr);
4510a720d735SMarcel Holtmann 
4511a720d735SMarcel Holtmann 		/* For incoming connections, set the default minimum
4512a720d735SMarcel Holtmann 		 * and maximum connection interval. They will be used
4513a720d735SMarcel Holtmann 		 * to check if the parameters are in range and if not
4514a720d735SMarcel Holtmann 		 * trigger the connection update procedure.
4515a720d735SMarcel Holtmann 		 */
4516a720d735SMarcel Holtmann 		conn->le_conn_min_interval = hdev->le_conn_min_interval;
4517a720d735SMarcel Holtmann 		conn->le_conn_max_interval = hdev->le_conn_max_interval;
4518cb1d68f7SJohan Hedberg 	}
45197be2edbbSJohan Hedberg 
4520edb4b466SMarcel Holtmann 	/* Lookup the identity address from the stored connection
4521edb4b466SMarcel Holtmann 	 * address and address type.
4522edb4b466SMarcel Holtmann 	 *
4523edb4b466SMarcel Holtmann 	 * When establishing connections to an identity address, the
4524edb4b466SMarcel Holtmann 	 * connection procedure will store the resolvable random
4525edb4b466SMarcel Holtmann 	 * address first. Now if it can be converted back into the
4526edb4b466SMarcel Holtmann 	 * identity address, start using the identity address from
4527edb4b466SMarcel Holtmann 	 * now on.
4528edb4b466SMarcel Holtmann 	 */
4529edb4b466SMarcel Holtmann 	irk = hci_get_irk(hdev, &conn->dst, conn->dst_type);
453068d6f6deSJohan Hedberg 	if (irk) {
453168d6f6deSJohan Hedberg 		bacpy(&conn->dst, &irk->bdaddr);
453268d6f6deSJohan Hedberg 		conn->dst_type = irk->addr_type;
453368d6f6deSJohan Hedberg 	}
453468d6f6deSJohan Hedberg 
45352d3c2260SJohan Hedberg 	if (ev->status) {
45362d3c2260SJohan Hedberg 		hci_le_conn_failed(conn, ev->status);
4537837d502eSJohan Hedberg 		goto unlock;
4538837d502eSJohan Hedberg 	}
4539837d502eSJohan Hedberg 
454008853f18SJohan Hedberg 	if (conn->dst_type == ADDR_LE_DEV_PUBLIC)
454108853f18SJohan Hedberg 		addr_type = BDADDR_LE_PUBLIC;
454208853f18SJohan Hedberg 	else
454308853f18SJohan Hedberg 		addr_type = BDADDR_LE_RANDOM;
454408853f18SJohan Hedberg 
45452d3c2260SJohan Hedberg 	/* Drop the connection if the device is blocked */
45462d3c2260SJohan Hedberg 	if (hci_bdaddr_list_lookup(&hdev->blacklist, &conn->dst, addr_type)) {
45472d3c2260SJohan Hedberg 		hci_conn_drop(conn);
4548cd17decbSAndre Guedes 		goto unlock;
4549cd17decbSAndre Guedes 	}
4550cd17decbSAndre Guedes 
4551b644ba33SJohan Hedberg 	if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
455248ec92faSAlfonso Acosta 		mgmt_device_connected(hdev, conn, 0, NULL, 0);
455383bc71b4SVinicius Costa Gomes 
45547b5c0d52SVinicius Costa Gomes 	conn->sec_level = BT_SECURITY_LOW;
4555fcd89c09SVille Tervo 	conn->handle = __le16_to_cpu(ev->handle);
45560fe29fd1SMarcel Holtmann 	conn->state = BT_CONFIG;
4557fcd89c09SVille Tervo 
4558e04fde60SMarcel Holtmann 	conn->le_conn_interval = le16_to_cpu(ev->interval);
4559e04fde60SMarcel Holtmann 	conn->le_conn_latency = le16_to_cpu(ev->latency);
4560e04fde60SMarcel Holtmann 	conn->le_supv_timeout = le16_to_cpu(ev->supervision_timeout);
4561e04fde60SMarcel Holtmann 
456223b9ceb7SMarcel Holtmann 	hci_debugfs_create_conn(conn);
4563fcd89c09SVille Tervo 	hci_conn_add_sysfs(conn);
4564fcd89c09SVille Tervo 
45650fe29fd1SMarcel Holtmann 	if (!ev->status) {
45660fe29fd1SMarcel Holtmann 		/* The remote features procedure is defined for master
45670fe29fd1SMarcel Holtmann 		 * role only. So only in case of an initiated connection
45680fe29fd1SMarcel Holtmann 		 * request the remote features.
45690fe29fd1SMarcel Holtmann 		 *
45700fe29fd1SMarcel Holtmann 		 * If the local controller supports slave-initiated features
45710fe29fd1SMarcel Holtmann 		 * exchange, then requesting the remote features in slave
45720fe29fd1SMarcel Holtmann 		 * role is possible. Otherwise just transition into the
45730fe29fd1SMarcel Holtmann 		 * connected state without requesting the remote features.
45740fe29fd1SMarcel Holtmann 		 */
45750fe29fd1SMarcel Holtmann 		if (conn->out ||
45760fe29fd1SMarcel Holtmann 		    (hdev->le_features[0] & HCI_LE_SLAVE_FEATURES)) {
45770fe29fd1SMarcel Holtmann 			struct hci_cp_le_read_remote_features cp;
45780fe29fd1SMarcel Holtmann 
45790fe29fd1SMarcel Holtmann 			cp.handle = __cpu_to_le16(conn->handle);
45800fe29fd1SMarcel Holtmann 
45810fe29fd1SMarcel Holtmann 			hci_send_cmd(hdev, HCI_OP_LE_READ_REMOTE_FEATURES,
45820fe29fd1SMarcel Holtmann 				     sizeof(cp), &cp);
45830fe29fd1SMarcel Holtmann 
45840fe29fd1SMarcel Holtmann 			hci_conn_hold(conn);
45850fe29fd1SMarcel Holtmann 		} else {
45860fe29fd1SMarcel Holtmann 			conn->state = BT_CONNECTED;
4587539c496dSJohan Hedberg 			hci_connect_cfm(conn, ev->status);
45880fe29fd1SMarcel Holtmann 		}
45890fe29fd1SMarcel Holtmann 	} else {
45900fe29fd1SMarcel Holtmann 		hci_connect_cfm(conn, ev->status);
45910fe29fd1SMarcel Holtmann 	}
4592fcd89c09SVille Tervo 
45935477610fSJohan Hedberg 	params = hci_pend_le_action_lookup(&hdev->pend_le_conns, &conn->dst,
45945477610fSJohan Hedberg 					   conn->dst_type);
4595f161dd41SJohan Hedberg 	if (params) {
459695305baaSJohan Hedberg 		list_del_init(&params->action);
4597f161dd41SJohan Hedberg 		if (params->conn) {
4598f161dd41SJohan Hedberg 			hci_conn_drop(params->conn);
4599f8aaf9b6SJohan Hedberg 			hci_conn_put(params->conn);
4600f161dd41SJohan Hedberg 			params->conn = NULL;
4601f161dd41SJohan Hedberg 		}
4602f161dd41SJohan Hedberg 	}
4603a4790dbdSAndre Guedes 
4604fcd89c09SVille Tervo unlock:
4605223683a5SJohan Hedberg 	hci_update_background_scan(hdev);
4606fcd89c09SVille Tervo 	hci_dev_unlock(hdev);
4607fcd89c09SVille Tervo }
4608fcd89c09SVille Tervo 
46091855d92dSMarcel Holtmann static void hci_le_conn_update_complete_evt(struct hci_dev *hdev,
46101855d92dSMarcel Holtmann 					    struct sk_buff *skb)
46111855d92dSMarcel Holtmann {
46121855d92dSMarcel Holtmann 	struct hci_ev_le_conn_update_complete *ev = (void *) skb->data;
46131855d92dSMarcel Holtmann 	struct hci_conn *conn;
46141855d92dSMarcel Holtmann 
46151855d92dSMarcel Holtmann 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
46161855d92dSMarcel Holtmann 
46171855d92dSMarcel Holtmann 	if (ev->status)
46181855d92dSMarcel Holtmann 		return;
46191855d92dSMarcel Holtmann 
46201855d92dSMarcel Holtmann 	hci_dev_lock(hdev);
46211855d92dSMarcel Holtmann 
46221855d92dSMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
46231855d92dSMarcel Holtmann 	if (conn) {
46241855d92dSMarcel Holtmann 		conn->le_conn_interval = le16_to_cpu(ev->interval);
46251855d92dSMarcel Holtmann 		conn->le_conn_latency = le16_to_cpu(ev->latency);
46261855d92dSMarcel Holtmann 		conn->le_supv_timeout = le16_to_cpu(ev->supervision_timeout);
46271855d92dSMarcel Holtmann 	}
46281855d92dSMarcel Holtmann 
46291855d92dSMarcel Holtmann 	hci_dev_unlock(hdev);
46301855d92dSMarcel Holtmann }
46311855d92dSMarcel Holtmann 
4632a4790dbdSAndre Guedes /* This function requires the caller holds hdev->lock */
4633fd45ada9SAlfonso Acosta static struct hci_conn *check_pending_le_conn(struct hci_dev *hdev,
4634fd45ada9SAlfonso Acosta 					      bdaddr_t *addr,
46351c1abcabSJohan Hedberg 					      u8 addr_type, u8 adv_type)
4636a4790dbdSAndre Guedes {
4637a4790dbdSAndre Guedes 	struct hci_conn *conn;
46384b9e7e75SMarcel Holtmann 	struct hci_conn_params *params;
4639a4790dbdSAndre Guedes 
46401c1abcabSJohan Hedberg 	/* If the event is not connectable don't proceed further */
46411c1abcabSJohan Hedberg 	if (adv_type != LE_ADV_IND && adv_type != LE_ADV_DIRECT_IND)
4642fd45ada9SAlfonso Acosta 		return NULL;
46431c1abcabSJohan Hedberg 
46441c1abcabSJohan Hedberg 	/* Ignore if the device is blocked */
4645dcc36c16SJohan Hedberg 	if (hci_bdaddr_list_lookup(&hdev->blacklist, addr, addr_type))
4646fd45ada9SAlfonso Acosta 		return NULL;
46471c1abcabSJohan Hedberg 
4648f99353cfSJohan Hedberg 	/* Most controller will fail if we try to create new connections
4649f99353cfSJohan Hedberg 	 * while we have an existing one in slave role.
4650f99353cfSJohan Hedberg 	 */
4651f99353cfSJohan Hedberg 	if (hdev->conn_hash.le_num_slave > 0)
4652fd45ada9SAlfonso Acosta 		return NULL;
4653f99353cfSJohan Hedberg 
46541c1abcabSJohan Hedberg 	/* If we're not connectable only connect devices that we have in
46551c1abcabSJohan Hedberg 	 * our pend_le_conns list.
46561c1abcabSJohan Hedberg 	 */
465749c50922SJohan Hedberg 	params = hci_pend_le_action_lookup(&hdev->pend_le_conns, addr,
465849c50922SJohan Hedberg 					   addr_type);
46594b9e7e75SMarcel Holtmann 	if (!params)
4660fd45ada9SAlfonso Acosta 		return NULL;
4661a4790dbdSAndre Guedes 
466228a667c9SJakub Pawlowski 	if (!params->explicit_connect) {
46634b9e7e75SMarcel Holtmann 		switch (params->auto_connect) {
46644b9e7e75SMarcel Holtmann 		case HCI_AUTO_CONN_DIRECT:
46654b9e7e75SMarcel Holtmann 			/* Only devices advertising with ADV_DIRECT_IND are
46664b9e7e75SMarcel Holtmann 			 * triggering a connection attempt. This is allowing
46674b9e7e75SMarcel Holtmann 			 * incoming connections from slave devices.
46684b9e7e75SMarcel Holtmann 			 */
46694b9e7e75SMarcel Holtmann 			if (adv_type != LE_ADV_DIRECT_IND)
4670fd45ada9SAlfonso Acosta 				return NULL;
46714b9e7e75SMarcel Holtmann 			break;
46724b9e7e75SMarcel Holtmann 		case HCI_AUTO_CONN_ALWAYS:
46734b9e7e75SMarcel Holtmann 			/* Devices advertising with ADV_IND or ADV_DIRECT_IND
46744b9e7e75SMarcel Holtmann 			 * are triggering a connection attempt. This means
46754b9e7e75SMarcel Holtmann 			 * that incoming connectioms from slave device are
46764b9e7e75SMarcel Holtmann 			 * accepted and also outgoing connections to slave
46774b9e7e75SMarcel Holtmann 			 * devices are established when found.
46784b9e7e75SMarcel Holtmann 			 */
46794b9e7e75SMarcel Holtmann 			break;
46804b9e7e75SMarcel Holtmann 		default:
4681fd45ada9SAlfonso Acosta 			return NULL;
46824b9e7e75SMarcel Holtmann 		}
468328a667c9SJakub Pawlowski 	}
46844b9e7e75SMarcel Holtmann 
4685a4790dbdSAndre Guedes 	conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW,
4686e804d25dSJohan Hedberg 			      HCI_LE_AUTOCONN_TIMEOUT, HCI_ROLE_MASTER);
4687f161dd41SJohan Hedberg 	if (!IS_ERR(conn)) {
468828a667c9SJakub Pawlowski 		/* If HCI_AUTO_CONN_EXPLICIT is set, conn is already owned
468928a667c9SJakub Pawlowski 		 * by higher layer that tried to connect, if no then
469028a667c9SJakub Pawlowski 		 * store the pointer since we don't really have any
4691f161dd41SJohan Hedberg 		 * other owner of the object besides the params that
4692f161dd41SJohan Hedberg 		 * triggered it. This way we can abort the connection if
4693f161dd41SJohan Hedberg 		 * the parameters get removed and keep the reference
4694f161dd41SJohan Hedberg 		 * count consistent once the connection is established.
4695f161dd41SJohan Hedberg 		 */
469628a667c9SJakub Pawlowski 
469728a667c9SJakub Pawlowski 		if (!params->explicit_connect)
4698f8aaf9b6SJohan Hedberg 			params->conn = hci_conn_get(conn);
469928a667c9SJakub Pawlowski 
4700fd45ada9SAlfonso Acosta 		return conn;
4701f161dd41SJohan Hedberg 	}
4702a4790dbdSAndre Guedes 
4703a4790dbdSAndre Guedes 	switch (PTR_ERR(conn)) {
4704a4790dbdSAndre Guedes 	case -EBUSY:
4705a4790dbdSAndre Guedes 		/* If hci_connect() returns -EBUSY it means there is already
4706a4790dbdSAndre Guedes 		 * an LE connection attempt going on. Since controllers don't
4707a4790dbdSAndre Guedes 		 * support more than one connection attempt at the time, we
4708a4790dbdSAndre Guedes 		 * don't consider this an error case.
4709a4790dbdSAndre Guedes 		 */
4710a4790dbdSAndre Guedes 		break;
4711a4790dbdSAndre Guedes 	default:
4712a4790dbdSAndre Guedes 		BT_DBG("Failed to connect: err %ld", PTR_ERR(conn));
4713fd45ada9SAlfonso Acosta 		return NULL;
4714a4790dbdSAndre Guedes 	}
4715fd45ada9SAlfonso Acosta 
4716fd45ada9SAlfonso Acosta 	return NULL;
4717a4790dbdSAndre Guedes }
4718a4790dbdSAndre Guedes 
47194af605d8SJohan Hedberg static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
47202f010b55SMarcel Holtmann 			       u8 bdaddr_type, bdaddr_t *direct_addr,
47212f010b55SMarcel Holtmann 			       u8 direct_addr_type, s8 rssi, u8 *data, u8 len)
47224af605d8SJohan Hedberg {
4723b9a6328fSJohan Hedberg 	struct discovery_state *d = &hdev->discovery;
47241c1abcabSJohan Hedberg 	struct smp_irk *irk;
4725fd45ada9SAlfonso Acosta 	struct hci_conn *conn;
4726474ee066SJohan Hedberg 	bool match;
4727c70a7e4cSMarcel Holtmann 	u32 flags;
47286818375eSSzymon Janc 	u8 *ptr, real_len;
47296818375eSSzymon Janc 
473056b40fbfSJohan Hedberg 	switch (type) {
473156b40fbfSJohan Hedberg 	case LE_ADV_IND:
473256b40fbfSJohan Hedberg 	case LE_ADV_DIRECT_IND:
473356b40fbfSJohan Hedberg 	case LE_ADV_SCAN_IND:
473456b40fbfSJohan Hedberg 	case LE_ADV_NONCONN_IND:
473556b40fbfSJohan Hedberg 	case LE_ADV_SCAN_RSP:
473656b40fbfSJohan Hedberg 		break;
473756b40fbfSJohan Hedberg 	default:
473856b40fbfSJohan Hedberg 		BT_ERR_RATELIMITED("Unknown advetising packet type: 0x%02x",
473956b40fbfSJohan Hedberg 				   type);
474056b40fbfSJohan Hedberg 		return;
474156b40fbfSJohan Hedberg 	}
474256b40fbfSJohan Hedberg 
47436818375eSSzymon Janc 	/* Find the end of the data in case the report contains padded zero
47446818375eSSzymon Janc 	 * bytes at the end causing an invalid length value.
47456818375eSSzymon Janc 	 *
47466818375eSSzymon Janc 	 * When data is NULL, len is 0 so there is no need for extra ptr
47476818375eSSzymon Janc 	 * check as 'ptr < data + 0' is already false in such case.
47486818375eSSzymon Janc 	 */
47496818375eSSzymon Janc 	for (ptr = data; ptr < data + len && *ptr; ptr += *ptr + 1) {
47506818375eSSzymon Janc 		if (ptr + 1 + *ptr > data + len)
47516818375eSSzymon Janc 			break;
47526818375eSSzymon Janc 	}
47536818375eSSzymon Janc 
47546818375eSSzymon Janc 	real_len = ptr - data;
47556818375eSSzymon Janc 
47566818375eSSzymon Janc 	/* Adjust for actual length */
47576818375eSSzymon Janc 	if (len != real_len) {
47586818375eSSzymon Janc 		BT_ERR_RATELIMITED("%s advertising data length corrected",
47596818375eSSzymon Janc 				   hdev->name);
47606818375eSSzymon Janc 		len = real_len;
47616818375eSSzymon Janc 	}
4762b9a6328fSJohan Hedberg 
47632f010b55SMarcel Holtmann 	/* If the direct address is present, then this report is from
47642f010b55SMarcel Holtmann 	 * a LE Direct Advertising Report event. In that case it is
47652f010b55SMarcel Holtmann 	 * important to see if the address is matching the local
47662f010b55SMarcel Holtmann 	 * controller address.
47672f010b55SMarcel Holtmann 	 */
47682f010b55SMarcel Holtmann 	if (direct_addr) {
47692f010b55SMarcel Holtmann 		/* Only resolvable random addresses are valid for these
47702f010b55SMarcel Holtmann 		 * kind of reports and others can be ignored.
47712f010b55SMarcel Holtmann 		 */
47722f010b55SMarcel Holtmann 		if (!hci_bdaddr_is_rpa(direct_addr, direct_addr_type))
47732f010b55SMarcel Holtmann 			return;
47742f010b55SMarcel Holtmann 
47752f010b55SMarcel Holtmann 		/* If the controller is not using resolvable random
47762f010b55SMarcel Holtmann 		 * addresses, then this report can be ignored.
47772f010b55SMarcel Holtmann 		 */
4778d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_PRIVACY))
47792f010b55SMarcel Holtmann 			return;
47802f010b55SMarcel Holtmann 
47812f010b55SMarcel Holtmann 		/* If the local IRK of the controller does not match
47822f010b55SMarcel Holtmann 		 * with the resolvable random address provided, then
47832f010b55SMarcel Holtmann 		 * this report can be ignored.
47842f010b55SMarcel Holtmann 		 */
47852f010b55SMarcel Holtmann 		if (!smp_irk_matches(hdev, hdev->irk, direct_addr))
47862f010b55SMarcel Holtmann 			return;
47872f010b55SMarcel Holtmann 	}
47882f010b55SMarcel Holtmann 
4789435a13d8SJohan Hedberg 	/* Check if we need to convert to identity address */
4790435a13d8SJohan Hedberg 	irk = hci_get_irk(hdev, bdaddr, bdaddr_type);
4791435a13d8SJohan Hedberg 	if (irk) {
4792435a13d8SJohan Hedberg 		bdaddr = &irk->bdaddr;
4793435a13d8SJohan Hedberg 		bdaddr_type = irk->addr_type;
4794435a13d8SJohan Hedberg 	}
4795435a13d8SJohan Hedberg 
47961c1abcabSJohan Hedberg 	/* Check if we have been requested to connect to this device */
4797fd45ada9SAlfonso Acosta 	conn = check_pending_le_conn(hdev, bdaddr, bdaddr_type, type);
4798fd45ada9SAlfonso Acosta 	if (conn && type == LE_ADV_IND) {
4799fd45ada9SAlfonso Acosta 		/* Store report for later inclusion by
4800fd45ada9SAlfonso Acosta 		 * mgmt_device_connected
4801fd45ada9SAlfonso Acosta 		 */
4802fd45ada9SAlfonso Acosta 		memcpy(conn->le_adv_data, data, len);
4803fd45ada9SAlfonso Acosta 		conn->le_adv_data_len = len;
4804fd45ada9SAlfonso Acosta 	}
480599a6768eSJohan Hedberg 
48061c1abcabSJohan Hedberg 	/* Passive scanning shouldn't trigger any device found events,
48071c1abcabSJohan Hedberg 	 * except for devices marked as CONN_REPORT for which we do send
48081c1abcabSJohan Hedberg 	 * device found events.
48091c1abcabSJohan Hedberg 	 */
48101c1abcabSJohan Hedberg 	if (hdev->le_scan_type == LE_SCAN_PASSIVE) {
48110d2bf134SJohan Hedberg 		if (type == LE_ADV_DIRECT_IND)
48120d2bf134SJohan Hedberg 			return;
48130d2bf134SJohan Hedberg 
48143a19b6feSJohan Hedberg 		if (!hci_pend_le_action_lookup(&hdev->pend_le_reports,
48153a19b6feSJohan Hedberg 					       bdaddr, bdaddr_type))
48160d2bf134SJohan Hedberg 			return;
48170d2bf134SJohan Hedberg 
48180d2bf134SJohan Hedberg 		if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND)
48190d2bf134SJohan Hedberg 			flags = MGMT_DEV_FOUND_NOT_CONNECTABLE;
48200d2bf134SJohan Hedberg 		else
48210d2bf134SJohan Hedberg 			flags = 0;
48220d2bf134SJohan Hedberg 		mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
48230d2bf134SJohan Hedberg 				  rssi, flags, data, len, NULL, 0);
482497bf2e99SJohan Hedberg 		return;
4825ca5c4be7SJohan Hedberg 	}
48264af605d8SJohan Hedberg 
4827c70a7e4cSMarcel Holtmann 	/* When receiving non-connectable or scannable undirected
4828c70a7e4cSMarcel Holtmann 	 * advertising reports, this means that the remote device is
4829c70a7e4cSMarcel Holtmann 	 * not connectable and then clearly indicate this in the
4830c70a7e4cSMarcel Holtmann 	 * device found event.
4831c70a7e4cSMarcel Holtmann 	 *
4832c70a7e4cSMarcel Holtmann 	 * When receiving a scan response, then there is no way to
4833c70a7e4cSMarcel Holtmann 	 * know if the remote device is connectable or not. However
4834c70a7e4cSMarcel Holtmann 	 * since scan responses are merged with a previously seen
4835c70a7e4cSMarcel Holtmann 	 * advertising report, the flags field from that report
4836c70a7e4cSMarcel Holtmann 	 * will be used.
4837c70a7e4cSMarcel Holtmann 	 *
4838c70a7e4cSMarcel Holtmann 	 * In the really unlikely case that a controller get confused
4839c70a7e4cSMarcel Holtmann 	 * and just sends a scan response event, then it is marked as
4840c70a7e4cSMarcel Holtmann 	 * not connectable as well.
4841c70a7e4cSMarcel Holtmann 	 */
4842c70a7e4cSMarcel Holtmann 	if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND ||
4843c70a7e4cSMarcel Holtmann 	    type == LE_ADV_SCAN_RSP)
4844c70a7e4cSMarcel Holtmann 		flags = MGMT_DEV_FOUND_NOT_CONNECTABLE;
4845c70a7e4cSMarcel Holtmann 	else
4846c70a7e4cSMarcel Holtmann 		flags = 0;
4847c70a7e4cSMarcel Holtmann 
4848b9a6328fSJohan Hedberg 	/* If there's nothing pending either store the data from this
4849b9a6328fSJohan Hedberg 	 * event or send an immediate device found event if the data
4850b9a6328fSJohan Hedberg 	 * should not be stored for later.
4851b9a6328fSJohan Hedberg 	 */
4852b9a6328fSJohan Hedberg 	if (!has_pending_adv_report(hdev)) {
4853b9a6328fSJohan Hedberg 		/* If the report will trigger a SCAN_REQ store it for
4854b9a6328fSJohan Hedberg 		 * later merging.
4855b9a6328fSJohan Hedberg 		 */
4856b9a6328fSJohan Hedberg 		if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) {
4857b9a6328fSJohan Hedberg 			store_pending_adv_report(hdev, bdaddr, bdaddr_type,
4858c70a7e4cSMarcel Holtmann 						 rssi, flags, data, len);
4859b9a6328fSJohan Hedberg 			return;
4860b9a6328fSJohan Hedberg 		}
4861b9a6328fSJohan Hedberg 
4862b9a6328fSJohan Hedberg 		mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
4863c70a7e4cSMarcel Holtmann 				  rssi, flags, data, len, NULL, 0);
4864b9a6328fSJohan Hedberg 		return;
4865b9a6328fSJohan Hedberg 	}
4866b9a6328fSJohan Hedberg 
4867474ee066SJohan Hedberg 	/* Check if the pending report is for the same device as the new one */
4868474ee066SJohan Hedberg 	match = (!bacmp(bdaddr, &d->last_adv_addr) &&
4869474ee066SJohan Hedberg 		 bdaddr_type == d->last_adv_addr_type);
4870474ee066SJohan Hedberg 
4871b9a6328fSJohan Hedberg 	/* If the pending data doesn't match this report or this isn't a
4872b9a6328fSJohan Hedberg 	 * scan response (e.g. we got a duplicate ADV_IND) then force
4873b9a6328fSJohan Hedberg 	 * sending of the pending data.
4874b9a6328fSJohan Hedberg 	 */
4875474ee066SJohan Hedberg 	if (type != LE_ADV_SCAN_RSP || !match) {
4876474ee066SJohan Hedberg 		/* Send out whatever is in the cache, but skip duplicates */
4877474ee066SJohan Hedberg 		if (!match)
4878b9a6328fSJohan Hedberg 			mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
4879ff5cd29fSJohan Hedberg 					  d->last_adv_addr_type, NULL,
4880c70a7e4cSMarcel Holtmann 					  d->last_adv_rssi, d->last_adv_flags,
4881ff5cd29fSJohan Hedberg 					  d->last_adv_data,
4882474ee066SJohan Hedberg 					  d->last_adv_data_len, NULL, 0);
4883b9a6328fSJohan Hedberg 
4884b9a6328fSJohan Hedberg 		/* If the new report will trigger a SCAN_REQ store it for
4885b9a6328fSJohan Hedberg 		 * later merging.
4886b9a6328fSJohan Hedberg 		 */
4887b9a6328fSJohan Hedberg 		if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) {
4888b9a6328fSJohan Hedberg 			store_pending_adv_report(hdev, bdaddr, bdaddr_type,
4889c70a7e4cSMarcel Holtmann 						 rssi, flags, data, len);
4890b9a6328fSJohan Hedberg 			return;
4891b9a6328fSJohan Hedberg 		}
4892b9a6328fSJohan Hedberg 
4893b9a6328fSJohan Hedberg 		/* The advertising reports cannot be merged, so clear
4894b9a6328fSJohan Hedberg 		 * the pending report and send out a device found event.
4895b9a6328fSJohan Hedberg 		 */
4896b9a6328fSJohan Hedberg 		clear_pending_adv_report(hdev);
48975c5b93e4SJohan Hedberg 		mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
4898c70a7e4cSMarcel Holtmann 				  rssi, flags, data, len, NULL, 0);
4899b9a6328fSJohan Hedberg 		return;
4900b9a6328fSJohan Hedberg 	}
4901b9a6328fSJohan Hedberg 
4902b9a6328fSJohan Hedberg 	/* If we get here we've got a pending ADV_IND or ADV_SCAN_IND and
4903b9a6328fSJohan Hedberg 	 * the new event is a SCAN_RSP. We can therefore proceed with
4904b9a6328fSJohan Hedberg 	 * sending a merged device found event.
4905b9a6328fSJohan Hedberg 	 */
4906b9a6328fSJohan Hedberg 	mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
4907c70a7e4cSMarcel Holtmann 			  d->last_adv_addr_type, NULL, rssi, d->last_adv_flags,
490842bd6a56SMarcel Holtmann 			  d->last_adv_data, d->last_adv_data_len, data, len);
4909b9a6328fSJohan Hedberg 	clear_pending_adv_report(hdev);
49104af605d8SJohan Hedberg }
49114af605d8SJohan Hedberg 
49126039aa73SGustavo Padovan static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
49139aa04c91SAndre Guedes {
4914e95beb41SAndre Guedes 	u8 num_reports = skb->data[0];
4915e95beb41SAndre Guedes 	void *ptr = &skb->data[1];
49169aa04c91SAndre Guedes 
4917a4790dbdSAndre Guedes 	hci_dev_lock(hdev);
4918a4790dbdSAndre Guedes 
4919e95beb41SAndre Guedes 	while (num_reports--) {
4920e95beb41SAndre Guedes 		struct hci_ev_le_advertising_info *ev = ptr;
49214af605d8SJohan Hedberg 		s8 rssi;
4922a4790dbdSAndre Guedes 
49233c9e9195SAndre Guedes 		rssi = ev->data[ev->length];
49244af605d8SJohan Hedberg 		process_adv_report(hdev, ev->evt_type, &ev->bdaddr,
49252f010b55SMarcel Holtmann 				   ev->bdaddr_type, NULL, 0, rssi,
49262f010b55SMarcel Holtmann 				   ev->data, ev->length);
49273c9e9195SAndre Guedes 
4928e95beb41SAndre Guedes 		ptr += sizeof(*ev) + ev->length + 1;
49299aa04c91SAndre Guedes 	}
4930a4790dbdSAndre Guedes 
4931a4790dbdSAndre Guedes 	hci_dev_unlock(hdev);
49329aa04c91SAndre Guedes }
49339aa04c91SAndre Guedes 
49340fe29fd1SMarcel Holtmann static void hci_le_remote_feat_complete_evt(struct hci_dev *hdev,
49350fe29fd1SMarcel Holtmann 					    struct sk_buff *skb)
49360fe29fd1SMarcel Holtmann {
49370fe29fd1SMarcel Holtmann 	struct hci_ev_le_remote_feat_complete *ev = (void *)skb->data;
49380fe29fd1SMarcel Holtmann 	struct hci_conn *conn;
49390fe29fd1SMarcel Holtmann 
49400fe29fd1SMarcel Holtmann 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
49410fe29fd1SMarcel Holtmann 
49420fe29fd1SMarcel Holtmann 	hci_dev_lock(hdev);
49430fe29fd1SMarcel Holtmann 
49440fe29fd1SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
49450fe29fd1SMarcel Holtmann 	if (conn) {
49460fe29fd1SMarcel Holtmann 		if (!ev->status)
49470fe29fd1SMarcel Holtmann 			memcpy(conn->features[0], ev->features, 8);
49480fe29fd1SMarcel Holtmann 
49490fe29fd1SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
49500fe29fd1SMarcel Holtmann 			__u8 status;
49510fe29fd1SMarcel Holtmann 
49520fe29fd1SMarcel Holtmann 			/* If the local controller supports slave-initiated
49530fe29fd1SMarcel Holtmann 			 * features exchange, but the remote controller does
49540fe29fd1SMarcel Holtmann 			 * not, then it is possible that the error code 0x1a
49550fe29fd1SMarcel Holtmann 			 * for unsupported remote feature gets returned.
49560fe29fd1SMarcel Holtmann 			 *
49570fe29fd1SMarcel Holtmann 			 * In this specific case, allow the connection to
49580fe29fd1SMarcel Holtmann 			 * transition into connected state and mark it as
49590fe29fd1SMarcel Holtmann 			 * successful.
49600fe29fd1SMarcel Holtmann 			 */
49610fe29fd1SMarcel Holtmann 			if ((hdev->le_features[0] & HCI_LE_SLAVE_FEATURES) &&
49620fe29fd1SMarcel Holtmann 			    !conn->out && ev->status == 0x1a)
49630fe29fd1SMarcel Holtmann 				status = 0x00;
49640fe29fd1SMarcel Holtmann 			else
49650fe29fd1SMarcel Holtmann 				status = ev->status;
49660fe29fd1SMarcel Holtmann 
49670fe29fd1SMarcel Holtmann 			conn->state = BT_CONNECTED;
49680fe29fd1SMarcel Holtmann 			hci_connect_cfm(conn, status);
49690fe29fd1SMarcel Holtmann 			hci_conn_drop(conn);
49700fe29fd1SMarcel Holtmann 		}
49710fe29fd1SMarcel Holtmann 	}
49720fe29fd1SMarcel Holtmann 
49730fe29fd1SMarcel Holtmann 	hci_dev_unlock(hdev);
49740fe29fd1SMarcel Holtmann }
49750fe29fd1SMarcel Holtmann 
49766039aa73SGustavo Padovan static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
4977a7a595f6SVinicius Costa Gomes {
4978a7a595f6SVinicius Costa Gomes 	struct hci_ev_le_ltk_req *ev = (void *) skb->data;
4979a7a595f6SVinicius Costa Gomes 	struct hci_cp_le_ltk_reply cp;
4980bea710feSVinicius Costa Gomes 	struct hci_cp_le_ltk_neg_reply neg;
4981a7a595f6SVinicius Costa Gomes 	struct hci_conn *conn;
4982c9839a11SVinicius Costa Gomes 	struct smp_ltk *ltk;
4983a7a595f6SVinicius Costa Gomes 
49849f1db00cSAndrei Emeltchenko 	BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
4985a7a595f6SVinicius Costa Gomes 
4986a7a595f6SVinicius Costa Gomes 	hci_dev_lock(hdev);
4987a7a595f6SVinicius Costa Gomes 
4988a7a595f6SVinicius Costa Gomes 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
4989bea710feSVinicius Costa Gomes 	if (conn == NULL)
4990bea710feSVinicius Costa Gomes 		goto not_found;
4991a7a595f6SVinicius Costa Gomes 
4992f3a73d97SJohan Hedberg 	ltk = hci_find_ltk(hdev, &conn->dst, conn->dst_type, conn->role);
49935378bc56SJohan Hedberg 	if (!ltk)
4994bea710feSVinicius Costa Gomes 		goto not_found;
4995bea710feSVinicius Costa Gomes 
49965378bc56SJohan Hedberg 	if (smp_ltk_is_sc(ltk)) {
49975378bc56SJohan Hedberg 		/* With SC both EDiv and Rand are set to zero */
49985378bc56SJohan Hedberg 		if (ev->ediv || ev->rand)
49995378bc56SJohan Hedberg 			goto not_found;
50005378bc56SJohan Hedberg 	} else {
50015378bc56SJohan Hedberg 		/* For non-SC keys check that EDiv and Rand match */
50025378bc56SJohan Hedberg 		if (ev->ediv != ltk->ediv || ev->rand != ltk->rand)
50035378bc56SJohan Hedberg 			goto not_found;
50045378bc56SJohan Hedberg 	}
50055378bc56SJohan Hedberg 
50068b76ce34SJohan Hedberg 	memcpy(cp.ltk, ltk->val, ltk->enc_size);
50078b76ce34SJohan Hedberg 	memset(cp.ltk + ltk->enc_size, 0, sizeof(cp.ltk) - ltk->enc_size);
5008a7a595f6SVinicius Costa Gomes 	cp.handle = cpu_to_le16(conn->handle);
5009c9839a11SVinicius Costa Gomes 
5010a6f7833cSJohan Hedberg 	conn->pending_sec_level = smp_ltk_sec_level(ltk);
5011a7a595f6SVinicius Costa Gomes 
501289cbb4daSAndre Guedes 	conn->enc_key_size = ltk->enc_size;
5013a7a595f6SVinicius Costa Gomes 
5014a7a595f6SVinicius Costa Gomes 	hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
5015a7a595f6SVinicius Costa Gomes 
50165981a882SClaudio Takahasi 	/* Ref. Bluetooth Core SPEC pages 1975 and 2004. STK is a
50175981a882SClaudio Takahasi 	 * temporary key used to encrypt a connection following
50185981a882SClaudio Takahasi 	 * pairing. It is used during the Encrypted Session Setup to
50195981a882SClaudio Takahasi 	 * distribute the keys. Later, security can be re-established
50205981a882SClaudio Takahasi 	 * using a distributed LTK.
50215981a882SClaudio Takahasi 	 */
50222ceba539SJohan Hedberg 	if (ltk->type == SMP_STK) {
5023fe59a05fSJohan Hedberg 		set_bit(HCI_CONN_STK_ENCRYPT, &conn->flags);
5024970d0f1bSJohan Hedberg 		list_del_rcu(&ltk->list);
5025970d0f1bSJohan Hedberg 		kfree_rcu(ltk, rcu);
5026fe59a05fSJohan Hedberg 	} else {
5027fe59a05fSJohan Hedberg 		clear_bit(HCI_CONN_STK_ENCRYPT, &conn->flags);
5028c9839a11SVinicius Costa Gomes 	}
5029c9839a11SVinicius Costa Gomes 
5030a7a595f6SVinicius Costa Gomes 	hci_dev_unlock(hdev);
5031bea710feSVinicius Costa Gomes 
5032bea710feSVinicius Costa Gomes 	return;
5033bea710feSVinicius Costa Gomes 
5034bea710feSVinicius Costa Gomes not_found:
5035bea710feSVinicius Costa Gomes 	neg.handle = ev->handle;
5036bea710feSVinicius Costa Gomes 	hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
5037bea710feSVinicius Costa Gomes 	hci_dev_unlock(hdev);
5038a7a595f6SVinicius Costa Gomes }
5039a7a595f6SVinicius Costa Gomes 
50408e75b46aSAndre Guedes static void send_conn_param_neg_reply(struct hci_dev *hdev, u16 handle,
50418e75b46aSAndre Guedes 				      u8 reason)
50428e75b46aSAndre Guedes {
50438e75b46aSAndre Guedes 	struct hci_cp_le_conn_param_req_neg_reply cp;
50448e75b46aSAndre Guedes 
50458e75b46aSAndre Guedes 	cp.handle = cpu_to_le16(handle);
50468e75b46aSAndre Guedes 	cp.reason = reason;
50478e75b46aSAndre Guedes 
50488e75b46aSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY, sizeof(cp),
50498e75b46aSAndre Guedes 		     &cp);
50508e75b46aSAndre Guedes }
50518e75b46aSAndre Guedes 
50528e75b46aSAndre Guedes static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev,
50538e75b46aSAndre Guedes 					     struct sk_buff *skb)
50548e75b46aSAndre Guedes {
50558e75b46aSAndre Guedes 	struct hci_ev_le_remote_conn_param_req *ev = (void *) skb->data;
50568e75b46aSAndre Guedes 	struct hci_cp_le_conn_param_req_reply cp;
50578e75b46aSAndre Guedes 	struct hci_conn *hcon;
50588e75b46aSAndre Guedes 	u16 handle, min, max, latency, timeout;
50598e75b46aSAndre Guedes 
50608e75b46aSAndre Guedes 	handle = le16_to_cpu(ev->handle);
50618e75b46aSAndre Guedes 	min = le16_to_cpu(ev->interval_min);
50628e75b46aSAndre Guedes 	max = le16_to_cpu(ev->interval_max);
50638e75b46aSAndre Guedes 	latency = le16_to_cpu(ev->latency);
50648e75b46aSAndre Guedes 	timeout = le16_to_cpu(ev->timeout);
50658e75b46aSAndre Guedes 
50668e75b46aSAndre Guedes 	hcon = hci_conn_hash_lookup_handle(hdev, handle);
50678e75b46aSAndre Guedes 	if (!hcon || hcon->state != BT_CONNECTED)
50688e75b46aSAndre Guedes 		return send_conn_param_neg_reply(hdev, handle,
50698e75b46aSAndre Guedes 						 HCI_ERROR_UNKNOWN_CONN_ID);
50708e75b46aSAndre Guedes 
50718e75b46aSAndre Guedes 	if (hci_check_conn_params(min, max, latency, timeout))
50728e75b46aSAndre Guedes 		return send_conn_param_neg_reply(hdev, handle,
50738e75b46aSAndre Guedes 						 HCI_ERROR_INVALID_LL_PARAMS);
50748e75b46aSAndre Guedes 
507540bef302SJohan Hedberg 	if (hcon->role == HCI_ROLE_MASTER) {
5076348d50b8SJohan Hedberg 		struct hci_conn_params *params;
5077f4869e2aSJohan Hedberg 		u8 store_hint;
5078348d50b8SJohan Hedberg 
5079348d50b8SJohan Hedberg 		hci_dev_lock(hdev);
5080348d50b8SJohan Hedberg 
5081348d50b8SJohan Hedberg 		params = hci_conn_params_lookup(hdev, &hcon->dst,
5082348d50b8SJohan Hedberg 						hcon->dst_type);
5083348d50b8SJohan Hedberg 		if (params) {
5084348d50b8SJohan Hedberg 			params->conn_min_interval = min;
5085348d50b8SJohan Hedberg 			params->conn_max_interval = max;
5086348d50b8SJohan Hedberg 			params->conn_latency = latency;
5087348d50b8SJohan Hedberg 			params->supervision_timeout = timeout;
5088f4869e2aSJohan Hedberg 			store_hint = 0x01;
5089f4869e2aSJohan Hedberg 		} else{
5090f4869e2aSJohan Hedberg 			store_hint = 0x00;
5091348d50b8SJohan Hedberg 		}
5092348d50b8SJohan Hedberg 
5093348d50b8SJohan Hedberg 		hci_dev_unlock(hdev);
5094348d50b8SJohan Hedberg 
5095f4869e2aSJohan Hedberg 		mgmt_new_conn_param(hdev, &hcon->dst, hcon->dst_type,
5096f4869e2aSJohan Hedberg 				    store_hint, min, max, latency, timeout);
5097348d50b8SJohan Hedberg 	}
5098ffb5a827SAndre Guedes 
50998e75b46aSAndre Guedes 	cp.handle = ev->handle;
51008e75b46aSAndre Guedes 	cp.interval_min = ev->interval_min;
51018e75b46aSAndre Guedes 	cp.interval_max = ev->interval_max;
51028e75b46aSAndre Guedes 	cp.latency = ev->latency;
51038e75b46aSAndre Guedes 	cp.timeout = ev->timeout;
51048e75b46aSAndre Guedes 	cp.min_ce_len = 0;
51058e75b46aSAndre Guedes 	cp.max_ce_len = 0;
51068e75b46aSAndre Guedes 
51078e75b46aSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_REPLY, sizeof(cp), &cp);
51088e75b46aSAndre Guedes }
51098e75b46aSAndre Guedes 
51102f010b55SMarcel Holtmann static void hci_le_direct_adv_report_evt(struct hci_dev *hdev,
51112f010b55SMarcel Holtmann 					 struct sk_buff *skb)
51122f010b55SMarcel Holtmann {
51132f010b55SMarcel Holtmann 	u8 num_reports = skb->data[0];
51142f010b55SMarcel Holtmann 	void *ptr = &skb->data[1];
51152f010b55SMarcel Holtmann 
51162f010b55SMarcel Holtmann 	hci_dev_lock(hdev);
51172f010b55SMarcel Holtmann 
51182f010b55SMarcel Holtmann 	while (num_reports--) {
51192f010b55SMarcel Holtmann 		struct hci_ev_le_direct_adv_info *ev = ptr;
51202f010b55SMarcel Holtmann 
51212f010b55SMarcel Holtmann 		process_adv_report(hdev, ev->evt_type, &ev->bdaddr,
51222f010b55SMarcel Holtmann 				   ev->bdaddr_type, &ev->direct_addr,
51232f010b55SMarcel Holtmann 				   ev->direct_addr_type, ev->rssi, NULL, 0);
51242f010b55SMarcel Holtmann 
51252f010b55SMarcel Holtmann 		ptr += sizeof(*ev);
51262f010b55SMarcel Holtmann 	}
51272f010b55SMarcel Holtmann 
51282f010b55SMarcel Holtmann 	hci_dev_unlock(hdev);
51292f010b55SMarcel Holtmann }
51302f010b55SMarcel Holtmann 
51316039aa73SGustavo Padovan static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
5132fcd89c09SVille Tervo {
5133fcd89c09SVille Tervo 	struct hci_ev_le_meta *le_ev = (void *) skb->data;
5134fcd89c09SVille Tervo 
5135fcd89c09SVille Tervo 	skb_pull(skb, sizeof(*le_ev));
5136fcd89c09SVille Tervo 
5137fcd89c09SVille Tervo 	switch (le_ev->subevent) {
5138fcd89c09SVille Tervo 	case HCI_EV_LE_CONN_COMPLETE:
5139fcd89c09SVille Tervo 		hci_le_conn_complete_evt(hdev, skb);
5140fcd89c09SVille Tervo 		break;
5141fcd89c09SVille Tervo 
51421855d92dSMarcel Holtmann 	case HCI_EV_LE_CONN_UPDATE_COMPLETE:
51431855d92dSMarcel Holtmann 		hci_le_conn_update_complete_evt(hdev, skb);
51441855d92dSMarcel Holtmann 		break;
51451855d92dSMarcel Holtmann 
51469aa04c91SAndre Guedes 	case HCI_EV_LE_ADVERTISING_REPORT:
51479aa04c91SAndre Guedes 		hci_le_adv_report_evt(hdev, skb);
51489aa04c91SAndre Guedes 		break;
51499aa04c91SAndre Guedes 
51500fe29fd1SMarcel Holtmann 	case HCI_EV_LE_REMOTE_FEAT_COMPLETE:
51510fe29fd1SMarcel Holtmann 		hci_le_remote_feat_complete_evt(hdev, skb);
51520fe29fd1SMarcel Holtmann 		break;
51530fe29fd1SMarcel Holtmann 
5154a7a595f6SVinicius Costa Gomes 	case HCI_EV_LE_LTK_REQ:
5155a7a595f6SVinicius Costa Gomes 		hci_le_ltk_request_evt(hdev, skb);
5156a7a595f6SVinicius Costa Gomes 		break;
5157a7a595f6SVinicius Costa Gomes 
51588e75b46aSAndre Guedes 	case HCI_EV_LE_REMOTE_CONN_PARAM_REQ:
51598e75b46aSAndre Guedes 		hci_le_remote_conn_param_req_evt(hdev, skb);
51608e75b46aSAndre Guedes 		break;
51618e75b46aSAndre Guedes 
51622f010b55SMarcel Holtmann 	case HCI_EV_LE_DIRECT_ADV_REPORT:
51632f010b55SMarcel Holtmann 		hci_le_direct_adv_report_evt(hdev, skb);
51642f010b55SMarcel Holtmann 		break;
51652f010b55SMarcel Holtmann 
5166fcd89c09SVille Tervo 	default:
5167fcd89c09SVille Tervo 		break;
5168fcd89c09SVille Tervo 	}
5169fcd89c09SVille Tervo }
5170fcd89c09SVille Tervo 
5171757aa0b5SJohan Hedberg static bool hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode,
5172757aa0b5SJohan Hedberg 				 u8 event, struct sk_buff *skb)
5173757aa0b5SJohan Hedberg {
5174757aa0b5SJohan Hedberg 	struct hci_ev_cmd_complete *ev;
5175757aa0b5SJohan Hedberg 	struct hci_event_hdr *hdr;
5176757aa0b5SJohan Hedberg 
5177757aa0b5SJohan Hedberg 	if (!skb)
5178757aa0b5SJohan Hedberg 		return false;
5179757aa0b5SJohan Hedberg 
5180757aa0b5SJohan Hedberg 	if (skb->len < sizeof(*hdr)) {
5181757aa0b5SJohan Hedberg 		BT_ERR("Too short HCI event");
5182757aa0b5SJohan Hedberg 		return false;
5183757aa0b5SJohan Hedberg 	}
5184757aa0b5SJohan Hedberg 
5185757aa0b5SJohan Hedberg 	hdr = (void *) skb->data;
5186757aa0b5SJohan Hedberg 	skb_pull(skb, HCI_EVENT_HDR_SIZE);
5187757aa0b5SJohan Hedberg 
5188757aa0b5SJohan Hedberg 	if (event) {
5189757aa0b5SJohan Hedberg 		if (hdr->evt != event)
5190757aa0b5SJohan Hedberg 			return false;
5191757aa0b5SJohan Hedberg 		return true;
5192757aa0b5SJohan Hedberg 	}
5193757aa0b5SJohan Hedberg 
5194757aa0b5SJohan Hedberg 	if (hdr->evt != HCI_EV_CMD_COMPLETE) {
5195757aa0b5SJohan Hedberg 		BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt);
5196757aa0b5SJohan Hedberg 		return false;
5197757aa0b5SJohan Hedberg 	}
5198757aa0b5SJohan Hedberg 
5199757aa0b5SJohan Hedberg 	if (skb->len < sizeof(*ev)) {
5200757aa0b5SJohan Hedberg 		BT_ERR("Too short cmd_complete event");
5201757aa0b5SJohan Hedberg 		return false;
5202757aa0b5SJohan Hedberg 	}
5203757aa0b5SJohan Hedberg 
5204757aa0b5SJohan Hedberg 	ev = (void *) skb->data;
5205757aa0b5SJohan Hedberg 	skb_pull(skb, sizeof(*ev));
5206757aa0b5SJohan Hedberg 
5207757aa0b5SJohan Hedberg 	if (opcode != __le16_to_cpu(ev->opcode)) {
5208757aa0b5SJohan Hedberg 		BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode,
5209757aa0b5SJohan Hedberg 		       __le16_to_cpu(ev->opcode));
5210757aa0b5SJohan Hedberg 		return false;
5211757aa0b5SJohan Hedberg 	}
5212757aa0b5SJohan Hedberg 
5213757aa0b5SJohan Hedberg 	return true;
5214757aa0b5SJohan Hedberg }
5215757aa0b5SJohan Hedberg 
52161da177e4SLinus Torvalds void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
52171da177e4SLinus Torvalds {
5218a9de9248SMarcel Holtmann 	struct hci_event_hdr *hdr = (void *) skb->data;
5219e6214487SJohan Hedberg 	hci_req_complete_t req_complete = NULL;
5220e6214487SJohan Hedberg 	hci_req_complete_skb_t req_complete_skb = NULL;
5221e6214487SJohan Hedberg 	struct sk_buff *orig_skb = NULL;
5222757aa0b5SJohan Hedberg 	u8 status = 0, event = hdr->evt, req_evt = 0;
5223e6214487SJohan Hedberg 	u16 opcode = HCI_OP_NOP;
52241da177e4SLinus Torvalds 
5225242c0ebdSMarcel Holtmann 	if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->hci.req_event == event) {
5226c1f23a2bSJohannes Berg 		struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data;
5227e6214487SJohan Hedberg 		opcode = __le16_to_cpu(cmd_hdr->opcode);
5228e6214487SJohan Hedberg 		hci_req_cmd_complete(hdev, opcode, status, &req_complete,
5229e6214487SJohan Hedberg 				     &req_complete_skb);
5230757aa0b5SJohan Hedberg 		req_evt = event;
523102350a72SJohan Hedberg 	}
523202350a72SJohan Hedberg 
5233e6214487SJohan Hedberg 	/* If it looks like we might end up having to call
5234e6214487SJohan Hedberg 	 * req_complete_skb, store a pristine copy of the skb since the
5235e6214487SJohan Hedberg 	 * various handlers may modify the original one through
5236e6214487SJohan Hedberg 	 * skb_pull() calls, etc.
5237e6214487SJohan Hedberg 	 */
5238e6214487SJohan Hedberg 	if (req_complete_skb || event == HCI_EV_CMD_STATUS ||
5239e6214487SJohan Hedberg 	    event == HCI_EV_CMD_COMPLETE)
5240e6214487SJohan Hedberg 		orig_skb = skb_clone(skb, GFP_KERNEL);
5241e6214487SJohan Hedberg 
5242e6214487SJohan Hedberg 	skb_pull(skb, HCI_EVENT_HDR_SIZE);
5243e6214487SJohan Hedberg 
5244a9de9248SMarcel Holtmann 	switch (event) {
52451da177e4SLinus Torvalds 	case HCI_EV_INQUIRY_COMPLETE:
52461da177e4SLinus Torvalds 		hci_inquiry_complete_evt(hdev, skb);
52471da177e4SLinus Torvalds 		break;
52481da177e4SLinus Torvalds 
52491da177e4SLinus Torvalds 	case HCI_EV_INQUIRY_RESULT:
52501da177e4SLinus Torvalds 		hci_inquiry_result_evt(hdev, skb);
52511da177e4SLinus Torvalds 		break;
52521da177e4SLinus Torvalds 
5253a9de9248SMarcel Holtmann 	case HCI_EV_CONN_COMPLETE:
5254a9de9248SMarcel Holtmann 		hci_conn_complete_evt(hdev, skb);
525521d9e30eSMarcel Holtmann 		break;
525621d9e30eSMarcel Holtmann 
52571da177e4SLinus Torvalds 	case HCI_EV_CONN_REQUEST:
52581da177e4SLinus Torvalds 		hci_conn_request_evt(hdev, skb);
52591da177e4SLinus Torvalds 		break;
52601da177e4SLinus Torvalds 
52611da177e4SLinus Torvalds 	case HCI_EV_DISCONN_COMPLETE:
52621da177e4SLinus Torvalds 		hci_disconn_complete_evt(hdev, skb);
52631da177e4SLinus Torvalds 		break;
52641da177e4SLinus Torvalds 
52651da177e4SLinus Torvalds 	case HCI_EV_AUTH_COMPLETE:
52661da177e4SLinus Torvalds 		hci_auth_complete_evt(hdev, skb);
52671da177e4SLinus Torvalds 		break;
52681da177e4SLinus Torvalds 
5269a9de9248SMarcel Holtmann 	case HCI_EV_REMOTE_NAME:
5270a9de9248SMarcel Holtmann 		hci_remote_name_evt(hdev, skb);
5271a9de9248SMarcel Holtmann 		break;
5272a9de9248SMarcel Holtmann 
52731da177e4SLinus Torvalds 	case HCI_EV_ENCRYPT_CHANGE:
52741da177e4SLinus Torvalds 		hci_encrypt_change_evt(hdev, skb);
52751da177e4SLinus Torvalds 		break;
52761da177e4SLinus Torvalds 
5277a9de9248SMarcel Holtmann 	case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
5278a9de9248SMarcel Holtmann 		hci_change_link_key_complete_evt(hdev, skb);
5279a9de9248SMarcel Holtmann 		break;
5280a9de9248SMarcel Holtmann 
5281a9de9248SMarcel Holtmann 	case HCI_EV_REMOTE_FEATURES:
5282a9de9248SMarcel Holtmann 		hci_remote_features_evt(hdev, skb);
5283a9de9248SMarcel Holtmann 		break;
5284a9de9248SMarcel Holtmann 
5285a9de9248SMarcel Holtmann 	case HCI_EV_CMD_COMPLETE:
5286e6214487SJohan Hedberg 		hci_cmd_complete_evt(hdev, skb, &opcode, &status,
5287e6214487SJohan Hedberg 				     &req_complete, &req_complete_skb);
5288a9de9248SMarcel Holtmann 		break;
5289a9de9248SMarcel Holtmann 
5290a9de9248SMarcel Holtmann 	case HCI_EV_CMD_STATUS:
5291e6214487SJohan Hedberg 		hci_cmd_status_evt(hdev, skb, &opcode, &status, &req_complete,
5292e6214487SJohan Hedberg 				   &req_complete_skb);
5293a9de9248SMarcel Holtmann 		break;
5294a9de9248SMarcel Holtmann 
529524dfa343SMarcel Holtmann 	case HCI_EV_HARDWARE_ERROR:
529624dfa343SMarcel Holtmann 		hci_hardware_error_evt(hdev, skb);
529724dfa343SMarcel Holtmann 		break;
529824dfa343SMarcel Holtmann 
5299a9de9248SMarcel Holtmann 	case HCI_EV_ROLE_CHANGE:
5300a9de9248SMarcel Holtmann 		hci_role_change_evt(hdev, skb);
5301a9de9248SMarcel Holtmann 		break;
5302a9de9248SMarcel Holtmann 
5303a9de9248SMarcel Holtmann 	case HCI_EV_NUM_COMP_PKTS:
5304a9de9248SMarcel Holtmann 		hci_num_comp_pkts_evt(hdev, skb);
5305a9de9248SMarcel Holtmann 		break;
5306a9de9248SMarcel Holtmann 
5307a9de9248SMarcel Holtmann 	case HCI_EV_MODE_CHANGE:
5308a9de9248SMarcel Holtmann 		hci_mode_change_evt(hdev, skb);
53091da177e4SLinus Torvalds 		break;
53101da177e4SLinus Torvalds 
53111da177e4SLinus Torvalds 	case HCI_EV_PIN_CODE_REQ:
53121da177e4SLinus Torvalds 		hci_pin_code_request_evt(hdev, skb);
53131da177e4SLinus Torvalds 		break;
53141da177e4SLinus Torvalds 
53151da177e4SLinus Torvalds 	case HCI_EV_LINK_KEY_REQ:
53161da177e4SLinus Torvalds 		hci_link_key_request_evt(hdev, skb);
53171da177e4SLinus Torvalds 		break;
53181da177e4SLinus Torvalds 
53191da177e4SLinus Torvalds 	case HCI_EV_LINK_KEY_NOTIFY:
53201da177e4SLinus Torvalds 		hci_link_key_notify_evt(hdev, skb);
53211da177e4SLinus Torvalds 		break;
53221da177e4SLinus Torvalds 
53231da177e4SLinus Torvalds 	case HCI_EV_CLOCK_OFFSET:
53241da177e4SLinus Torvalds 		hci_clock_offset_evt(hdev, skb);
53251da177e4SLinus Torvalds 		break;
53261da177e4SLinus Torvalds 
5327a8746417SMarcel Holtmann 	case HCI_EV_PKT_TYPE_CHANGE:
5328a8746417SMarcel Holtmann 		hci_pkt_type_change_evt(hdev, skb);
5329a8746417SMarcel Holtmann 		break;
5330a8746417SMarcel Holtmann 
533185a1e930SMarcel Holtmann 	case HCI_EV_PSCAN_REP_MODE:
533285a1e930SMarcel Holtmann 		hci_pscan_rep_mode_evt(hdev, skb);
533385a1e930SMarcel Holtmann 		break;
533485a1e930SMarcel Holtmann 
5335a9de9248SMarcel Holtmann 	case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
5336a9de9248SMarcel Holtmann 		hci_inquiry_result_with_rssi_evt(hdev, skb);
5337a9de9248SMarcel Holtmann 		break;
5338a9de9248SMarcel Holtmann 
5339a9de9248SMarcel Holtmann 	case HCI_EV_REMOTE_EXT_FEATURES:
5340a9de9248SMarcel Holtmann 		hci_remote_ext_features_evt(hdev, skb);
5341a9de9248SMarcel Holtmann 		break;
5342a9de9248SMarcel Holtmann 
5343a9de9248SMarcel Holtmann 	case HCI_EV_SYNC_CONN_COMPLETE:
5344a9de9248SMarcel Holtmann 		hci_sync_conn_complete_evt(hdev, skb);
5345a9de9248SMarcel Holtmann 		break;
5346a9de9248SMarcel Holtmann 
5347a9de9248SMarcel Holtmann 	case HCI_EV_EXTENDED_INQUIRY_RESULT:
5348a9de9248SMarcel Holtmann 		hci_extended_inquiry_result_evt(hdev, skb);
53491da177e4SLinus Torvalds 		break;
53501da177e4SLinus Torvalds 
53511c2e0041SJohan Hedberg 	case HCI_EV_KEY_REFRESH_COMPLETE:
53521c2e0041SJohan Hedberg 		hci_key_refresh_complete_evt(hdev, skb);
53531c2e0041SJohan Hedberg 		break;
53541c2e0041SJohan Hedberg 
53550493684eSMarcel Holtmann 	case HCI_EV_IO_CAPA_REQUEST:
53560493684eSMarcel Holtmann 		hci_io_capa_request_evt(hdev, skb);
53570493684eSMarcel Holtmann 		break;
53580493684eSMarcel Holtmann 
535903b555e1SJohan Hedberg 	case HCI_EV_IO_CAPA_REPLY:
536003b555e1SJohan Hedberg 		hci_io_capa_reply_evt(hdev, skb);
536103b555e1SJohan Hedberg 		break;
536203b555e1SJohan Hedberg 
5363a5c29683SJohan Hedberg 	case HCI_EV_USER_CONFIRM_REQUEST:
5364a5c29683SJohan Hedberg 		hci_user_confirm_request_evt(hdev, skb);
5365a5c29683SJohan Hedberg 		break;
5366a5c29683SJohan Hedberg 
53671143d458SBrian Gix 	case HCI_EV_USER_PASSKEY_REQUEST:
53681143d458SBrian Gix 		hci_user_passkey_request_evt(hdev, skb);
53691143d458SBrian Gix 		break;
53701143d458SBrian Gix 
537192a25256SJohan Hedberg 	case HCI_EV_USER_PASSKEY_NOTIFY:
537292a25256SJohan Hedberg 		hci_user_passkey_notify_evt(hdev, skb);
537392a25256SJohan Hedberg 		break;
537492a25256SJohan Hedberg 
537592a25256SJohan Hedberg 	case HCI_EV_KEYPRESS_NOTIFY:
537692a25256SJohan Hedberg 		hci_keypress_notify_evt(hdev, skb);
537792a25256SJohan Hedberg 		break;
537892a25256SJohan Hedberg 
53790493684eSMarcel Holtmann 	case HCI_EV_SIMPLE_PAIR_COMPLETE:
53800493684eSMarcel Holtmann 		hci_simple_pair_complete_evt(hdev, skb);
53810493684eSMarcel Holtmann 		break;
53820493684eSMarcel Holtmann 
538341a96212SMarcel Holtmann 	case HCI_EV_REMOTE_HOST_FEATURES:
538441a96212SMarcel Holtmann 		hci_remote_host_features_evt(hdev, skb);
538541a96212SMarcel Holtmann 		break;
538641a96212SMarcel Holtmann 
5387fcd89c09SVille Tervo 	case HCI_EV_LE_META:
5388fcd89c09SVille Tervo 		hci_le_meta_evt(hdev, skb);
5389fcd89c09SVille Tervo 		break;
5390fcd89c09SVille Tervo 
53912763eda6SSzymon Janc 	case HCI_EV_REMOTE_OOB_DATA_REQUEST:
53922763eda6SSzymon Janc 		hci_remote_oob_data_request_evt(hdev, skb);
53932763eda6SSzymon Janc 		break;
53942763eda6SSzymon Janc 
5395a77a6a14SArron Wang #if IS_ENABLED(CONFIG_BT_HS)
5396a77a6a14SArron Wang 	case HCI_EV_CHANNEL_SELECTED:
5397a77a6a14SArron Wang 		hci_chan_selected_evt(hdev, skb);
5398a77a6a14SArron Wang 		break;
5399a77a6a14SArron Wang 
5400d5e91192SAndrei Emeltchenko 	case HCI_EV_PHY_LINK_COMPLETE:
5401d5e91192SAndrei Emeltchenko 		hci_phy_link_complete_evt(hdev, skb);
5402d5e91192SAndrei Emeltchenko 		break;
5403d5e91192SAndrei Emeltchenko 
540427695fb4SAndrei Emeltchenko 	case HCI_EV_LOGICAL_LINK_COMPLETE:
540527695fb4SAndrei Emeltchenko 		hci_loglink_complete_evt(hdev, skb);
540627695fb4SAndrei Emeltchenko 		break;
540727695fb4SAndrei Emeltchenko 
5408606e2a10SAndrei Emeltchenko 	case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
5409606e2a10SAndrei Emeltchenko 		hci_disconn_loglink_complete_evt(hdev, skb);
5410606e2a10SAndrei Emeltchenko 		break;
5411606e2a10SAndrei Emeltchenko 
54129eef6b3aSAndrei Emeltchenko 	case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
54139eef6b3aSAndrei Emeltchenko 		hci_disconn_phylink_complete_evt(hdev, skb);
54149eef6b3aSAndrei Emeltchenko 		break;
5415a77a6a14SArron Wang #endif
54169eef6b3aSAndrei Emeltchenko 
541725e89e99SAndrei Emeltchenko 	case HCI_EV_NUM_COMP_BLOCKS:
541825e89e99SAndrei Emeltchenko 		hci_num_comp_blocks_evt(hdev, skb);
541925e89e99SAndrei Emeltchenko 		break;
542025e89e99SAndrei Emeltchenko 
54211da177e4SLinus Torvalds 	default:
54229f1db00cSAndrei Emeltchenko 		BT_DBG("%s event 0x%2.2x", hdev->name, event);
54231da177e4SLinus Torvalds 		break;
54241da177e4SLinus Torvalds 	}
54251da177e4SLinus Torvalds 
5426757aa0b5SJohan Hedberg 	if (req_complete) {
5427e6214487SJohan Hedberg 		req_complete(hdev, status, opcode);
5428757aa0b5SJohan Hedberg 	} else if (req_complete_skb) {
5429757aa0b5SJohan Hedberg 		if (!hci_get_cmd_complete(hdev, opcode, req_evt, orig_skb)) {
5430757aa0b5SJohan Hedberg 			kfree_skb(orig_skb);
5431757aa0b5SJohan Hedberg 			orig_skb = NULL;
5432757aa0b5SJohan Hedberg 		}
5433e6214487SJohan Hedberg 		req_complete_skb(hdev, status, opcode, orig_skb);
5434757aa0b5SJohan Hedberg 	}
5435e6214487SJohan Hedberg 
5436e6214487SJohan Hedberg 	kfree_skb(orig_skb);
54371da177e4SLinus Torvalds 	kfree_skb(skb);
54381da177e4SLinus Torvalds 	hdev->stat.evt_rx++;
54391da177e4SLinus Torvalds }
5440