xref: /openbmc/linux/net/bluetooth/hci_event.c (revision 8e75b46a)
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 
337024728eSMarcel Holtmann #include "a2mp.h"
347ef9fbf0SMarcel Holtmann #include "amp.h"
352ceba539SJohan Hedberg #include "smp.h"
361da177e4SLinus Torvalds 
371da177e4SLinus Torvalds /* Handle HCI Event packets */
381da177e4SLinus Torvalds 
39a9de9248SMarcel Holtmann static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
401da177e4SLinus Torvalds {
41a9de9248SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
421da177e4SLinus Torvalds 
439f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
441da177e4SLinus Torvalds 
4582f4785cSAndre Guedes 	if (status)
46a9de9248SMarcel Holtmann 		return;
471da177e4SLinus Torvalds 
4889352e7dSAndre Guedes 	clear_bit(HCI_INQUIRY, &hdev->flags);
494e857c58SPeter Zijlstra 	smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */
503e13fa1eSAndre Guedes 	wake_up_bit(&hdev->flags, HCI_INQUIRY);
5189352e7dSAndre Guedes 
5250143a43SJohan Hedberg 	hci_dev_lock(hdev);
5350143a43SJohan Hedberg 	hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
5450143a43SJohan Hedberg 	hci_dev_unlock(hdev);
5550143a43SJohan Hedberg 
56a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
571da177e4SLinus Torvalds }
586bd57416SMarcel Holtmann 
594d93483bSAndre Guedes static void hci_cc_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
604d93483bSAndre Guedes {
614d93483bSAndre Guedes 	__u8 status = *((__u8 *) skb->data);
624d93483bSAndre Guedes 
639f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
64ae854a70SAndre Guedes 
65ae854a70SAndre Guedes 	if (status)
66ae854a70SAndre Guedes 		return;
67ae854a70SAndre Guedes 
68ae854a70SAndre Guedes 	set_bit(HCI_PERIODIC_INQ, &hdev->dev_flags);
694d93483bSAndre Guedes }
704d93483bSAndre Guedes 
71a9de9248SMarcel Holtmann static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
721da177e4SLinus Torvalds {
73a9de9248SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
74a9de9248SMarcel Holtmann 
759f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
76a9de9248SMarcel Holtmann 
77a9de9248SMarcel Holtmann 	if (status)
78a9de9248SMarcel Holtmann 		return;
79a9de9248SMarcel Holtmann 
80ae854a70SAndre Guedes 	clear_bit(HCI_PERIODIC_INQ, &hdev->dev_flags);
81ae854a70SAndre Guedes 
82a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
83a9de9248SMarcel Holtmann }
84a9de9248SMarcel Holtmann 
85807deac2SGustavo Padovan static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev,
86807deac2SGustavo Padovan 					  struct sk_buff *skb)
87a9de9248SMarcel Holtmann {
88a9de9248SMarcel Holtmann 	BT_DBG("%s", hdev->name);
89a9de9248SMarcel Holtmann }
90a9de9248SMarcel Holtmann 
91a9de9248SMarcel Holtmann static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
92a9de9248SMarcel Holtmann {
93a9de9248SMarcel Holtmann 	struct hci_rp_role_discovery *rp = (void *) skb->data;
941da177e4SLinus Torvalds 	struct hci_conn *conn;
951da177e4SLinus Torvalds 
969f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
971da177e4SLinus Torvalds 
98a9de9248SMarcel Holtmann 	if (rp->status)
99a9de9248SMarcel Holtmann 		return;
1001da177e4SLinus Torvalds 
1011da177e4SLinus Torvalds 	hci_dev_lock(hdev);
1021da177e4SLinus Torvalds 
103a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
1041da177e4SLinus Torvalds 	if (conn) {
105a9de9248SMarcel Holtmann 		if (rp->role)
1064dae2798SJohan Hedberg 			clear_bit(HCI_CONN_MASTER, &conn->flags);
1071da177e4SLinus Torvalds 		else
1084dae2798SJohan Hedberg 			set_bit(HCI_CONN_MASTER, &conn->flags);
1091da177e4SLinus Torvalds 	}
1101da177e4SLinus Torvalds 
1111da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
112a9de9248SMarcel Holtmann }
1131da177e4SLinus Torvalds 
114e4e8e37cSMarcel Holtmann static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
115e4e8e37cSMarcel Holtmann {
116e4e8e37cSMarcel Holtmann 	struct hci_rp_read_link_policy *rp = (void *) skb->data;
117e4e8e37cSMarcel Holtmann 	struct hci_conn *conn;
118e4e8e37cSMarcel Holtmann 
1199f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
120e4e8e37cSMarcel Holtmann 
121e4e8e37cSMarcel Holtmann 	if (rp->status)
122e4e8e37cSMarcel Holtmann 		return;
123e4e8e37cSMarcel Holtmann 
124e4e8e37cSMarcel Holtmann 	hci_dev_lock(hdev);
125e4e8e37cSMarcel Holtmann 
126e4e8e37cSMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
127e4e8e37cSMarcel Holtmann 	if (conn)
128e4e8e37cSMarcel Holtmann 		conn->link_policy = __le16_to_cpu(rp->policy);
129e4e8e37cSMarcel Holtmann 
130e4e8e37cSMarcel Holtmann 	hci_dev_unlock(hdev);
131e4e8e37cSMarcel Holtmann }
132e4e8e37cSMarcel Holtmann 
133a9de9248SMarcel Holtmann static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
134a9de9248SMarcel Holtmann {
135a9de9248SMarcel Holtmann 	struct hci_rp_write_link_policy *rp = (void *) skb->data;
136a9de9248SMarcel Holtmann 	struct hci_conn *conn;
137a9de9248SMarcel Holtmann 	void *sent;
138a9de9248SMarcel Holtmann 
1399f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
140a9de9248SMarcel Holtmann 
141a9de9248SMarcel Holtmann 	if (rp->status)
142a9de9248SMarcel Holtmann 		return;
143a9de9248SMarcel Holtmann 
144a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
14504837f64SMarcel Holtmann 	if (!sent)
146a9de9248SMarcel Holtmann 		return;
14704837f64SMarcel Holtmann 
14804837f64SMarcel Holtmann 	hci_dev_lock(hdev);
14904837f64SMarcel Holtmann 
150a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
151e4e8e37cSMarcel Holtmann 	if (conn)
15283985319SHarvey Harrison 		conn->link_policy = get_unaligned_le16(sent + 2);
15304837f64SMarcel Holtmann 
15404837f64SMarcel Holtmann 	hci_dev_unlock(hdev);
1551da177e4SLinus Torvalds }
1561da177e4SLinus Torvalds 
157807deac2SGustavo Padovan static void hci_cc_read_def_link_policy(struct hci_dev *hdev,
158807deac2SGustavo Padovan 					struct sk_buff *skb)
159e4e8e37cSMarcel Holtmann {
160e4e8e37cSMarcel Holtmann 	struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
161e4e8e37cSMarcel Holtmann 
1629f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
163e4e8e37cSMarcel Holtmann 
164e4e8e37cSMarcel Holtmann 	if (rp->status)
165e4e8e37cSMarcel Holtmann 		return;
166e4e8e37cSMarcel Holtmann 
167e4e8e37cSMarcel Holtmann 	hdev->link_policy = __le16_to_cpu(rp->policy);
168e4e8e37cSMarcel Holtmann }
169e4e8e37cSMarcel Holtmann 
170807deac2SGustavo Padovan static void hci_cc_write_def_link_policy(struct hci_dev *hdev,
171807deac2SGustavo Padovan 					 struct sk_buff *skb)
172e4e8e37cSMarcel Holtmann {
173e4e8e37cSMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
174e4e8e37cSMarcel Holtmann 	void *sent;
175e4e8e37cSMarcel Holtmann 
1769f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
177e4e8e37cSMarcel Holtmann 
178e4e8e37cSMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
179e4e8e37cSMarcel Holtmann 	if (!sent)
180e4e8e37cSMarcel Holtmann 		return;
181e4e8e37cSMarcel Holtmann 
182e4e8e37cSMarcel Holtmann 	if (!status)
183e4e8e37cSMarcel Holtmann 		hdev->link_policy = get_unaligned_le16(sent);
184e4e8e37cSMarcel Holtmann }
185e4e8e37cSMarcel Holtmann 
186a9de9248SMarcel Holtmann static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
1871da177e4SLinus Torvalds {
188a9de9248SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
189a9de9248SMarcel Holtmann 
1909f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
191a9de9248SMarcel Holtmann 
19210572132SGustavo F. Padovan 	clear_bit(HCI_RESET, &hdev->flags);
19310572132SGustavo F. Padovan 
194a297e97cSJohan Hedberg 	/* Reset all non-persistent flags */
1952cc6fb00SJohan Hedberg 	hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
19669775ff6SAndre Guedes 
19769775ff6SAndre Guedes 	hdev->discovery.state = DISCOVERY_STOPPED;
198bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
199bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
2003f0f524bSJohan Hedberg 
2013f0f524bSJohan Hedberg 	memset(hdev->adv_data, 0, sizeof(hdev->adv_data));
2023f0f524bSJohan Hedberg 	hdev->adv_data_len = 0;
203f8e808bdSMarcel Holtmann 
204f8e808bdSMarcel Holtmann 	memset(hdev->scan_rsp_data, 0, sizeof(hdev->scan_rsp_data));
205f8e808bdSMarcel Holtmann 	hdev->scan_rsp_data_len = 0;
20606f5b778SMarcel Holtmann 
207533553f8SMarcel Holtmann 	hdev->le_scan_type = LE_SCAN_PASSIVE;
208533553f8SMarcel Holtmann 
20906f5b778SMarcel Holtmann 	hdev->ssp_debug_mode = 0;
210a9de9248SMarcel Holtmann }
211a9de9248SMarcel Holtmann 
212a9de9248SMarcel Holtmann static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
213a9de9248SMarcel Holtmann {
214a9de9248SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
2151da177e4SLinus Torvalds 	void *sent;
2161da177e4SLinus Torvalds 
2179f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
2181da177e4SLinus Torvalds 
219a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
2201da177e4SLinus Torvalds 	if (!sent)
221a9de9248SMarcel Holtmann 		return;
2221da177e4SLinus Torvalds 
22356e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
22456e5cb86SJohan Hedberg 
225f51d5b24SJohan Hedberg 	if (test_bit(HCI_MGMT, &hdev->dev_flags))
226f51d5b24SJohan Hedberg 		mgmt_set_local_name_complete(hdev, sent, status);
22728cc7bdeSJohan Hedberg 	else if (!status)
22828cc7bdeSJohan Hedberg 		memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
229f51d5b24SJohan Hedberg 
23056e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
231a9de9248SMarcel Holtmann }
232a9de9248SMarcel Holtmann 
233a9de9248SMarcel Holtmann static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
234a9de9248SMarcel Holtmann {
235a9de9248SMarcel Holtmann 	struct hci_rp_read_local_name *rp = (void *) skb->data;
236a9de9248SMarcel Holtmann 
2379f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
238a9de9248SMarcel Holtmann 
239a9de9248SMarcel Holtmann 	if (rp->status)
240a9de9248SMarcel Holtmann 		return;
241a9de9248SMarcel Holtmann 
242db99b5fcSJohan Hedberg 	if (test_bit(HCI_SETUP, &hdev->dev_flags))
2431f6c6378SJohan Hedberg 		memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
244a9de9248SMarcel Holtmann }
245a9de9248SMarcel Holtmann 
246a9de9248SMarcel Holtmann static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
247a9de9248SMarcel Holtmann {
248a9de9248SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
249a9de9248SMarcel Holtmann 	void *sent;
250a9de9248SMarcel Holtmann 
2519f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
252a9de9248SMarcel Holtmann 
253a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
254a9de9248SMarcel Holtmann 	if (!sent)
255a9de9248SMarcel Holtmann 		return;
2561da177e4SLinus Torvalds 
2571da177e4SLinus Torvalds 	if (!status) {
258a9de9248SMarcel Holtmann 		__u8 param = *((__u8 *) sent);
259a9de9248SMarcel Holtmann 
2601da177e4SLinus Torvalds 		if (param == AUTH_ENABLED)
2611da177e4SLinus Torvalds 			set_bit(HCI_AUTH, &hdev->flags);
2621da177e4SLinus Torvalds 		else
2631da177e4SLinus Torvalds 			clear_bit(HCI_AUTH, &hdev->flags);
2641da177e4SLinus Torvalds 	}
265a9de9248SMarcel Holtmann 
26633ef95edSJohan Hedberg 	if (test_bit(HCI_MGMT, &hdev->dev_flags))
26733ef95edSJohan Hedberg 		mgmt_auth_enable_complete(hdev, status);
268a9de9248SMarcel Holtmann }
2691da177e4SLinus Torvalds 
270a9de9248SMarcel Holtmann static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
271a9de9248SMarcel Holtmann {
272a9de9248SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
273a9de9248SMarcel Holtmann 	void *sent;
274a9de9248SMarcel Holtmann 
2759f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
276a9de9248SMarcel Holtmann 
277a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
2781da177e4SLinus Torvalds 	if (!sent)
279a9de9248SMarcel Holtmann 		return;
2801da177e4SLinus Torvalds 
2811da177e4SLinus Torvalds 	if (!status) {
282a9de9248SMarcel Holtmann 		__u8 param = *((__u8 *) sent);
283a9de9248SMarcel Holtmann 
2841da177e4SLinus Torvalds 		if (param)
2851da177e4SLinus Torvalds 			set_bit(HCI_ENCRYPT, &hdev->flags);
2861da177e4SLinus Torvalds 		else
2871da177e4SLinus Torvalds 			clear_bit(HCI_ENCRYPT, &hdev->flags);
2881da177e4SLinus Torvalds 	}
2891da177e4SLinus Torvalds }
2901da177e4SLinus Torvalds 
291a9de9248SMarcel Holtmann static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
292a9de9248SMarcel Holtmann {
29336f7fc7eSJohan Hedberg 	__u8 param, status = *((__u8 *) skb->data);
29436f7fc7eSJohan Hedberg 	int old_pscan, old_iscan;
295a9de9248SMarcel Holtmann 	void *sent;
2961da177e4SLinus Torvalds 
2979f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
298a9de9248SMarcel Holtmann 
299a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
3001da177e4SLinus Torvalds 	if (!sent)
301a9de9248SMarcel Holtmann 		return;
3021da177e4SLinus Torvalds 
30336f7fc7eSJohan Hedberg 	param = *((__u8 *) sent);
304a9de9248SMarcel Holtmann 
30556e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
30656e5cb86SJohan Hedberg 
307fa1bd918SMikel Astiz 	if (status) {
308744cf19eSJohan Hedberg 		mgmt_write_scan_failed(hdev, param, status);
3092d7cee58SJohan Hedberg 		hdev->discov_timeout = 0;
3102d7cee58SJohan Hedberg 		goto done;
3112d7cee58SJohan Hedberg 	}
3122d7cee58SJohan Hedberg 
3130663ca2aSJohan Hedberg 	/* We need to ensure that we set this back on if someone changed
3140663ca2aSJohan Hedberg 	 * the scan mode through a raw HCI socket.
3150663ca2aSJohan Hedberg 	 */
3160663ca2aSJohan Hedberg 	set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
3170663ca2aSJohan Hedberg 
3189fbcbb45SJohan Hedberg 	old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
3199fbcbb45SJohan Hedberg 	old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
320a9de9248SMarcel Holtmann 
32173f22f62SJohan Hedberg 	if (param & SCAN_INQUIRY) {
3221da177e4SLinus Torvalds 		set_bit(HCI_ISCAN, &hdev->flags);
3239fbcbb45SJohan Hedberg 		if (!old_iscan)
324744cf19eSJohan Hedberg 			mgmt_discoverable(hdev, 1);
3259fbcbb45SJohan Hedberg 	} else if (old_iscan)
326744cf19eSJohan Hedberg 		mgmt_discoverable(hdev, 0);
3271da177e4SLinus Torvalds 
3289fbcbb45SJohan Hedberg 	if (param & SCAN_PAGE) {
3291da177e4SLinus Torvalds 		set_bit(HCI_PSCAN, &hdev->flags);
3309fbcbb45SJohan Hedberg 		if (!old_pscan)
331744cf19eSJohan Hedberg 			mgmt_connectable(hdev, 1);
3329fbcbb45SJohan Hedberg 	} else if (old_pscan)
333744cf19eSJohan Hedberg 		mgmt_connectable(hdev, 0);
334a9de9248SMarcel Holtmann 
33536f7fc7eSJohan Hedberg done:
33656e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
3371da177e4SLinus Torvalds }
3381da177e4SLinus Torvalds 
339a9de9248SMarcel Holtmann static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
340a9de9248SMarcel Holtmann {
341a9de9248SMarcel Holtmann 	struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
342a9de9248SMarcel Holtmann 
3439f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
344a9de9248SMarcel Holtmann 
345a9de9248SMarcel Holtmann 	if (rp->status)
346a9de9248SMarcel Holtmann 		return;
347a9de9248SMarcel Holtmann 
348a9de9248SMarcel Holtmann 	memcpy(hdev->dev_class, rp->dev_class, 3);
349a9de9248SMarcel Holtmann 
350a9de9248SMarcel Holtmann 	BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
351a9de9248SMarcel Holtmann 	       hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
352a9de9248SMarcel Holtmann }
353a9de9248SMarcel Holtmann 
354a9de9248SMarcel Holtmann static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
355a9de9248SMarcel Holtmann {
356a9de9248SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
357a9de9248SMarcel Holtmann 	void *sent;
358a9de9248SMarcel Holtmann 
3599f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
360a9de9248SMarcel Holtmann 
361a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
362a9de9248SMarcel Holtmann 	if (!sent)
363a9de9248SMarcel Holtmann 		return;
364a9de9248SMarcel Holtmann 
3657f9a903cSMarcel Holtmann 	hci_dev_lock(hdev);
3667f9a903cSMarcel Holtmann 
3677f9a903cSMarcel Holtmann 	if (status == 0)
368a9de9248SMarcel Holtmann 		memcpy(hdev->dev_class, sent, 3);
3697f9a903cSMarcel Holtmann 
3707f9a903cSMarcel Holtmann 	if (test_bit(HCI_MGMT, &hdev->dev_flags))
3717f9a903cSMarcel Holtmann 		mgmt_set_class_of_dev_complete(hdev, sent, status);
3727f9a903cSMarcel Holtmann 
3737f9a903cSMarcel Holtmann 	hci_dev_unlock(hdev);
374a9de9248SMarcel Holtmann }
375a9de9248SMarcel Holtmann 
376a9de9248SMarcel Holtmann static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
377a9de9248SMarcel Holtmann {
378a9de9248SMarcel Holtmann 	struct hci_rp_read_voice_setting *rp = (void *) skb->data;
379a9de9248SMarcel Holtmann 	__u16 setting;
380a9de9248SMarcel Holtmann 
3819f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
382a9de9248SMarcel Holtmann 
383a9de9248SMarcel Holtmann 	if (rp->status)
384a9de9248SMarcel Holtmann 		return;
385a9de9248SMarcel Holtmann 
386a9de9248SMarcel Holtmann 	setting = __le16_to_cpu(rp->voice_setting);
387a9de9248SMarcel Holtmann 
388a9de9248SMarcel Holtmann 	if (hdev->voice_setting == setting)
389a9de9248SMarcel Holtmann 		return;
390a9de9248SMarcel Holtmann 
391a9de9248SMarcel Holtmann 	hdev->voice_setting = setting;
392a9de9248SMarcel Holtmann 
3939f1db00cSAndrei Emeltchenko 	BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
394a9de9248SMarcel Holtmann 
3953c54711cSGustavo F. Padovan 	if (hdev->notify)
396a9de9248SMarcel Holtmann 		hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
397a9de9248SMarcel Holtmann }
398a9de9248SMarcel Holtmann 
3998fc9ced3SGustavo Padovan static void hci_cc_write_voice_setting(struct hci_dev *hdev,
4008fc9ced3SGustavo Padovan 				       struct sk_buff *skb)
401a9de9248SMarcel Holtmann {
402a9de9248SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
403f383f275SMarcel Holtmann 	__u16 setting;
404a9de9248SMarcel Holtmann 	void *sent;
405a9de9248SMarcel Holtmann 
4069f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
407a9de9248SMarcel Holtmann 
408f383f275SMarcel Holtmann 	if (status)
409f383f275SMarcel Holtmann 		return;
410f383f275SMarcel Holtmann 
411a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
412a9de9248SMarcel Holtmann 	if (!sent)
413a9de9248SMarcel Holtmann 		return;
414a9de9248SMarcel Holtmann 
415f383f275SMarcel Holtmann 	setting = get_unaligned_le16(sent);
4161da177e4SLinus Torvalds 
417f383f275SMarcel Holtmann 	if (hdev->voice_setting == setting)
418f383f275SMarcel Holtmann 		return;
419f383f275SMarcel Holtmann 
4201da177e4SLinus Torvalds 	hdev->voice_setting = setting;
4211da177e4SLinus Torvalds 
4229f1db00cSAndrei Emeltchenko 	BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
4231da177e4SLinus Torvalds 
4243c54711cSGustavo F. Padovan 	if (hdev->notify)
4251da177e4SLinus Torvalds 		hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
4261da177e4SLinus Torvalds }
4271da177e4SLinus Torvalds 
428b4cb9fb2SMarcel Holtmann static void hci_cc_read_num_supported_iac(struct hci_dev *hdev,
429b4cb9fb2SMarcel Holtmann 					  struct sk_buff *skb)
430b4cb9fb2SMarcel Holtmann {
431b4cb9fb2SMarcel Holtmann 	struct hci_rp_read_num_supported_iac *rp = (void *) skb->data;
432b4cb9fb2SMarcel Holtmann 
433b4cb9fb2SMarcel Holtmann 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
434b4cb9fb2SMarcel Holtmann 
435b4cb9fb2SMarcel Holtmann 	if (rp->status)
436b4cb9fb2SMarcel Holtmann 		return;
437b4cb9fb2SMarcel Holtmann 
438b4cb9fb2SMarcel Holtmann 	hdev->num_iac = rp->num_iac;
439b4cb9fb2SMarcel Holtmann 
440b4cb9fb2SMarcel Holtmann 	BT_DBG("%s num iac %d", hdev->name, hdev->num_iac);
441b4cb9fb2SMarcel Holtmann }
442b4cb9fb2SMarcel Holtmann 
443333140b5SMarcel Holtmann static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
444333140b5SMarcel Holtmann {
445333140b5SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
4465ed8eb2fSJohan Hedberg 	struct hci_cp_write_ssp_mode *sent;
447333140b5SMarcel Holtmann 
4489f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
449333140b5SMarcel Holtmann 
450333140b5SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
451333140b5SMarcel Holtmann 	if (!sent)
452333140b5SMarcel Holtmann 		return;
453333140b5SMarcel Holtmann 
4545ed8eb2fSJohan Hedberg 	if (!status) {
4555ed8eb2fSJohan Hedberg 		if (sent->mode)
456cad718edSJohan Hedberg 			hdev->features[1][0] |= LMP_HOST_SSP;
4575ed8eb2fSJohan Hedberg 		else
458cad718edSJohan Hedberg 			hdev->features[1][0] &= ~LMP_HOST_SSP;
4595ed8eb2fSJohan Hedberg 	}
4605ed8eb2fSJohan Hedberg 
461c0ecddc2SJohan Hedberg 	if (test_bit(HCI_MGMT, &hdev->dev_flags))
4625ed8eb2fSJohan Hedberg 		mgmt_ssp_enable_complete(hdev, sent->mode, status);
463c0ecddc2SJohan Hedberg 	else if (!status) {
4645ed8eb2fSJohan Hedberg 		if (sent->mode)
46584bde9d6SJohan Hedberg 			set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
46684bde9d6SJohan Hedberg 		else
46784bde9d6SJohan Hedberg 			clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
468c0ecddc2SJohan Hedberg 	}
469333140b5SMarcel Holtmann }
470333140b5SMarcel Holtmann 
471eac83dc6SMarcel Holtmann static void hci_cc_write_sc_support(struct hci_dev *hdev, struct sk_buff *skb)
472eac83dc6SMarcel Holtmann {
473eac83dc6SMarcel Holtmann 	u8 status = *((u8 *) skb->data);
474eac83dc6SMarcel Holtmann 	struct hci_cp_write_sc_support *sent;
475eac83dc6SMarcel Holtmann 
476eac83dc6SMarcel Holtmann 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
477eac83dc6SMarcel Holtmann 
478eac83dc6SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SC_SUPPORT);
479eac83dc6SMarcel Holtmann 	if (!sent)
480eac83dc6SMarcel Holtmann 		return;
481eac83dc6SMarcel Holtmann 
482eac83dc6SMarcel Holtmann 	if (!status) {
483eac83dc6SMarcel Holtmann 		if (sent->support)
484eac83dc6SMarcel Holtmann 			hdev->features[1][0] |= LMP_HOST_SC;
485eac83dc6SMarcel Holtmann 		else
486eac83dc6SMarcel Holtmann 			hdev->features[1][0] &= ~LMP_HOST_SC;
487eac83dc6SMarcel Holtmann 	}
488eac83dc6SMarcel Holtmann 
489eac83dc6SMarcel Holtmann 	if (test_bit(HCI_MGMT, &hdev->dev_flags))
490eac83dc6SMarcel Holtmann 		mgmt_sc_enable_complete(hdev, sent->support, status);
491eac83dc6SMarcel Holtmann 	else if (!status) {
492eac83dc6SMarcel Holtmann 		if (sent->support)
493eac83dc6SMarcel Holtmann 			set_bit(HCI_SC_ENABLED, &hdev->dev_flags);
494eac83dc6SMarcel Holtmann 		else
495eac83dc6SMarcel Holtmann 			clear_bit(HCI_SC_ENABLED, &hdev->dev_flags);
496eac83dc6SMarcel Holtmann 	}
497eac83dc6SMarcel Holtmann }
498eac83dc6SMarcel Holtmann 
499a9de9248SMarcel Holtmann static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
500a9de9248SMarcel Holtmann {
501a9de9248SMarcel Holtmann 	struct hci_rp_read_local_version *rp = (void *) skb->data;
5021143e5a6SMarcel Holtmann 
5039f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
5041143e5a6SMarcel Holtmann 
505a9de9248SMarcel Holtmann 	if (rp->status)
50642c6b129SJohan Hedberg 		return;
5071143e5a6SMarcel Holtmann 
5080d5551f5SMarcel Holtmann 	if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
509a9de9248SMarcel Holtmann 		hdev->hci_ver = rp->hci_ver;
510e4e8e37cSMarcel Holtmann 		hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
511d5859e22SJohan Hedberg 		hdev->lmp_ver = rp->lmp_ver;
512e4e8e37cSMarcel Holtmann 		hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
513d5859e22SJohan Hedberg 		hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
5140d5551f5SMarcel Holtmann 	}
515d5859e22SJohan Hedberg }
516d5859e22SJohan Hedberg 
5178fc9ced3SGustavo Padovan static void hci_cc_read_local_commands(struct hci_dev *hdev,
5188fc9ced3SGustavo Padovan 				       struct sk_buff *skb)
519a9de9248SMarcel Holtmann {
520a9de9248SMarcel Holtmann 	struct hci_rp_read_local_commands *rp = (void *) skb->data;
521a9de9248SMarcel Holtmann 
5229f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
523a9de9248SMarcel Holtmann 
5246a070e6eSMarcel Holtmann 	if (rp->status)
5256a070e6eSMarcel Holtmann 		return;
5266a070e6eSMarcel Holtmann 
5276a070e6eSMarcel Holtmann 	if (test_bit(HCI_SETUP, &hdev->dev_flags))
528a9de9248SMarcel Holtmann 		memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
529a9de9248SMarcel Holtmann }
530a9de9248SMarcel Holtmann 
5318fc9ced3SGustavo Padovan static void hci_cc_read_local_features(struct hci_dev *hdev,
5328fc9ced3SGustavo Padovan 				       struct sk_buff *skb)
533a9de9248SMarcel Holtmann {
534a9de9248SMarcel Holtmann 	struct hci_rp_read_local_features *rp = (void *) skb->data;
535a9de9248SMarcel Holtmann 
5369f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
537a9de9248SMarcel Holtmann 
538a9de9248SMarcel Holtmann 	if (rp->status)
539a9de9248SMarcel Holtmann 		return;
540a9de9248SMarcel Holtmann 
541a9de9248SMarcel Holtmann 	memcpy(hdev->features, rp->features, 8);
5421da177e4SLinus Torvalds 
5431da177e4SLinus Torvalds 	/* Adjust default settings according to features
5441da177e4SLinus Torvalds 	 * supported by device. */
545a9de9248SMarcel Holtmann 
546cad718edSJohan Hedberg 	if (hdev->features[0][0] & LMP_3SLOT)
5471da177e4SLinus Torvalds 		hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
5481da177e4SLinus Torvalds 
549cad718edSJohan Hedberg 	if (hdev->features[0][0] & LMP_5SLOT)
5501da177e4SLinus Torvalds 		hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
5511da177e4SLinus Torvalds 
552cad718edSJohan Hedberg 	if (hdev->features[0][1] & LMP_HV2) {
5531da177e4SLinus Torvalds 		hdev->pkt_type  |= (HCI_HV2);
5545b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_HV2);
5555b7f9909SMarcel Holtmann 	}
5561da177e4SLinus Torvalds 
557cad718edSJohan Hedberg 	if (hdev->features[0][1] & LMP_HV3) {
5581da177e4SLinus Torvalds 		hdev->pkt_type  |= (HCI_HV3);
5595b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_HV3);
5605b7f9909SMarcel Holtmann 	}
5615b7f9909SMarcel Holtmann 
56245db810fSAndre Guedes 	if (lmp_esco_capable(hdev))
5635b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_EV3);
5645b7f9909SMarcel Holtmann 
565cad718edSJohan Hedberg 	if (hdev->features[0][4] & LMP_EV4)
5665b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_EV4);
5675b7f9909SMarcel Holtmann 
568cad718edSJohan Hedberg 	if (hdev->features[0][4] & LMP_EV5)
5695b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_EV5);
5701da177e4SLinus Torvalds 
571cad718edSJohan Hedberg 	if (hdev->features[0][5] & LMP_EDR_ESCO_2M)
572efc7688bSMarcel Holtmann 		hdev->esco_type |= (ESCO_2EV3);
573efc7688bSMarcel Holtmann 
574cad718edSJohan Hedberg 	if (hdev->features[0][5] & LMP_EDR_ESCO_3M)
575efc7688bSMarcel Holtmann 		hdev->esco_type |= (ESCO_3EV3);
576efc7688bSMarcel Holtmann 
577cad718edSJohan Hedberg 	if (hdev->features[0][5] & LMP_EDR_3S_ESCO)
578efc7688bSMarcel Holtmann 		hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
5791da177e4SLinus Torvalds }
5801da177e4SLinus Torvalds 
581971e3a4bSAndre Guedes static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
582971e3a4bSAndre Guedes 					   struct sk_buff *skb)
583971e3a4bSAndre Guedes {
584971e3a4bSAndre Guedes 	struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
585971e3a4bSAndre Guedes 
5869f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
587971e3a4bSAndre Guedes 
588971e3a4bSAndre Guedes 	if (rp->status)
58942c6b129SJohan Hedberg 		return;
590971e3a4bSAndre Guedes 
59157af75a8SMarcel Holtmann 	if (hdev->max_page < rp->max_page)
592d2c5d77fSJohan Hedberg 		hdev->max_page = rp->max_page;
593d2c5d77fSJohan Hedberg 
594cad718edSJohan Hedberg 	if (rp->page < HCI_MAX_PAGES)
595cad718edSJohan Hedberg 		memcpy(hdev->features[rp->page], rp->features, 8);
596971e3a4bSAndre Guedes }
597971e3a4bSAndre Guedes 
5981e89cffbSAndrei Emeltchenko static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
5991e89cffbSAndrei Emeltchenko 					  struct sk_buff *skb)
6001e89cffbSAndrei Emeltchenko {
6011e89cffbSAndrei Emeltchenko 	struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
6021e89cffbSAndrei Emeltchenko 
6039f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
6041e89cffbSAndrei Emeltchenko 
60542c6b129SJohan Hedberg 	if (!rp->status)
6061e89cffbSAndrei Emeltchenko 		hdev->flow_ctl_mode = rp->mode;
6071e89cffbSAndrei Emeltchenko }
6081e89cffbSAndrei Emeltchenko 
609a9de9248SMarcel Holtmann static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
610a9de9248SMarcel Holtmann {
611a9de9248SMarcel Holtmann 	struct hci_rp_read_buffer_size *rp = (void *) skb->data;
612a9de9248SMarcel Holtmann 
6139f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
614a9de9248SMarcel Holtmann 
615a9de9248SMarcel Holtmann 	if (rp->status)
616a9de9248SMarcel Holtmann 		return;
617a9de9248SMarcel Holtmann 
618a9de9248SMarcel Holtmann 	hdev->acl_mtu  = __le16_to_cpu(rp->acl_mtu);
619a9de9248SMarcel Holtmann 	hdev->sco_mtu  = rp->sco_mtu;
620a9de9248SMarcel Holtmann 	hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
621a9de9248SMarcel Holtmann 	hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
622da1f5198SMarcel Holtmann 
623da1f5198SMarcel Holtmann 	if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
624da1f5198SMarcel Holtmann 		hdev->sco_mtu  = 64;
625da1f5198SMarcel Holtmann 		hdev->sco_pkts = 8;
626da1f5198SMarcel Holtmann 	}
627da1f5198SMarcel Holtmann 
628da1f5198SMarcel Holtmann 	hdev->acl_cnt = hdev->acl_pkts;
629da1f5198SMarcel Holtmann 	hdev->sco_cnt = hdev->sco_pkts;
6301da177e4SLinus Torvalds 
631807deac2SGustavo Padovan 	BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
632807deac2SGustavo Padovan 	       hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
6331da177e4SLinus Torvalds }
6341da177e4SLinus Torvalds 
635a9de9248SMarcel Holtmann static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
636a9de9248SMarcel Holtmann {
637a9de9248SMarcel Holtmann 	struct hci_rp_read_bd_addr *rp = (void *) skb->data;
6381da177e4SLinus Torvalds 
6399f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
640a9de9248SMarcel Holtmann 
641a9de9248SMarcel Holtmann 	if (!rp->status)
642a9de9248SMarcel Holtmann 		bacpy(&hdev->bdaddr, &rp->bdaddr);
64323bb5763SJohan Hedberg }
64423bb5763SJohan Hedberg 
645f332ec66SJohan Hedberg static void hci_cc_read_page_scan_activity(struct hci_dev *hdev,
646f332ec66SJohan Hedberg 					   struct sk_buff *skb)
647f332ec66SJohan Hedberg {
648f332ec66SJohan Hedberg 	struct hci_rp_read_page_scan_activity *rp = (void *) skb->data;
649f332ec66SJohan Hedberg 
650f332ec66SJohan Hedberg 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
651f332ec66SJohan Hedberg 
652f332ec66SJohan Hedberg 	if (test_bit(HCI_INIT, &hdev->flags) && !rp->status) {
653f332ec66SJohan Hedberg 		hdev->page_scan_interval = __le16_to_cpu(rp->interval);
654f332ec66SJohan Hedberg 		hdev->page_scan_window = __le16_to_cpu(rp->window);
655f332ec66SJohan Hedberg 	}
656f332ec66SJohan Hedberg }
657f332ec66SJohan Hedberg 
6584a3ee763SJohan Hedberg static void hci_cc_write_page_scan_activity(struct hci_dev *hdev,
6594a3ee763SJohan Hedberg 					    struct sk_buff *skb)
6604a3ee763SJohan Hedberg {
6614a3ee763SJohan Hedberg 	u8 status = *((u8 *) skb->data);
6624a3ee763SJohan Hedberg 	struct hci_cp_write_page_scan_activity *sent;
6634a3ee763SJohan Hedberg 
6644a3ee763SJohan Hedberg 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
6654a3ee763SJohan Hedberg 
6664a3ee763SJohan Hedberg 	if (status)
6674a3ee763SJohan Hedberg 		return;
6684a3ee763SJohan Hedberg 
6694a3ee763SJohan Hedberg 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY);
6704a3ee763SJohan Hedberg 	if (!sent)
6714a3ee763SJohan Hedberg 		return;
6724a3ee763SJohan Hedberg 
6734a3ee763SJohan Hedberg 	hdev->page_scan_interval = __le16_to_cpu(sent->interval);
6744a3ee763SJohan Hedberg 	hdev->page_scan_window = __le16_to_cpu(sent->window);
6754a3ee763SJohan Hedberg }
6764a3ee763SJohan Hedberg 
677f332ec66SJohan Hedberg static void hci_cc_read_page_scan_type(struct hci_dev *hdev,
678f332ec66SJohan Hedberg 					   struct sk_buff *skb)
679f332ec66SJohan Hedberg {
680f332ec66SJohan Hedberg 	struct hci_rp_read_page_scan_type *rp = (void *) skb->data;
681f332ec66SJohan Hedberg 
682f332ec66SJohan Hedberg 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
683f332ec66SJohan Hedberg 
684f332ec66SJohan Hedberg 	if (test_bit(HCI_INIT, &hdev->flags) && !rp->status)
685f332ec66SJohan Hedberg 		hdev->page_scan_type = rp->type;
686f332ec66SJohan Hedberg }
687f332ec66SJohan Hedberg 
6884a3ee763SJohan Hedberg static void hci_cc_write_page_scan_type(struct hci_dev *hdev,
6894a3ee763SJohan Hedberg 					struct sk_buff *skb)
6904a3ee763SJohan Hedberg {
6914a3ee763SJohan Hedberg 	u8 status = *((u8 *) skb->data);
6924a3ee763SJohan Hedberg 	u8 *type;
6934a3ee763SJohan Hedberg 
6944a3ee763SJohan Hedberg 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
6954a3ee763SJohan Hedberg 
6964a3ee763SJohan Hedberg 	if (status)
6974a3ee763SJohan Hedberg 		return;
6984a3ee763SJohan Hedberg 
6994a3ee763SJohan Hedberg 	type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE);
7004a3ee763SJohan Hedberg 	if (type)
7014a3ee763SJohan Hedberg 		hdev->page_scan_type = *type;
7024a3ee763SJohan Hedberg }
7034a3ee763SJohan Hedberg 
704350ee4cfSAndrei Emeltchenko static void hci_cc_read_data_block_size(struct hci_dev *hdev,
705350ee4cfSAndrei Emeltchenko 					struct sk_buff *skb)
706350ee4cfSAndrei Emeltchenko {
707350ee4cfSAndrei Emeltchenko 	struct hci_rp_read_data_block_size *rp = (void *) skb->data;
708350ee4cfSAndrei Emeltchenko 
7099f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
710350ee4cfSAndrei Emeltchenko 
711350ee4cfSAndrei Emeltchenko 	if (rp->status)
712350ee4cfSAndrei Emeltchenko 		return;
713350ee4cfSAndrei Emeltchenko 
714350ee4cfSAndrei Emeltchenko 	hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
715350ee4cfSAndrei Emeltchenko 	hdev->block_len = __le16_to_cpu(rp->block_len);
716350ee4cfSAndrei Emeltchenko 	hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
717350ee4cfSAndrei Emeltchenko 
718350ee4cfSAndrei Emeltchenko 	hdev->block_cnt = hdev->num_blocks;
719350ee4cfSAndrei Emeltchenko 
720350ee4cfSAndrei Emeltchenko 	BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
721350ee4cfSAndrei Emeltchenko 	       hdev->block_cnt, hdev->block_len);
722350ee4cfSAndrei Emeltchenko }
723350ee4cfSAndrei Emeltchenko 
72433f35721SJohan Hedberg static void hci_cc_read_clock(struct hci_dev *hdev, struct sk_buff *skb)
72533f35721SJohan Hedberg {
72633f35721SJohan Hedberg 	struct hci_rp_read_clock *rp = (void *) skb->data;
72733f35721SJohan Hedberg 	struct hci_cp_read_clock *cp;
72833f35721SJohan Hedberg 	struct hci_conn *conn;
72933f35721SJohan Hedberg 
73033f35721SJohan Hedberg 	BT_DBG("%s", hdev->name);
73133f35721SJohan Hedberg 
73233f35721SJohan Hedberg 	if (skb->len < sizeof(*rp))
73333f35721SJohan Hedberg 		return;
73433f35721SJohan Hedberg 
73533f35721SJohan Hedberg 	if (rp->status)
73633f35721SJohan Hedberg 		return;
73733f35721SJohan Hedberg 
73833f35721SJohan Hedberg 	hci_dev_lock(hdev);
73933f35721SJohan Hedberg 
74033f35721SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_READ_CLOCK);
74133f35721SJohan Hedberg 	if (!cp)
74233f35721SJohan Hedberg 		goto unlock;
74333f35721SJohan Hedberg 
74433f35721SJohan Hedberg 	if (cp->which == 0x00) {
74533f35721SJohan Hedberg 		hdev->clock = le32_to_cpu(rp->clock);
74633f35721SJohan Hedberg 		goto unlock;
74733f35721SJohan Hedberg 	}
74833f35721SJohan Hedberg 
74933f35721SJohan Hedberg 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
75033f35721SJohan Hedberg 	if (conn) {
75133f35721SJohan Hedberg 		conn->clock = le32_to_cpu(rp->clock);
75233f35721SJohan Hedberg 		conn->clock_accuracy = le16_to_cpu(rp->accuracy);
75333f35721SJohan Hedberg 	}
75433f35721SJohan Hedberg 
75533f35721SJohan Hedberg unlock:
75633f35721SJohan Hedberg 	hci_dev_unlock(hdev);
75733f35721SJohan Hedberg }
75833f35721SJohan Hedberg 
759928abaa7SAndrei Emeltchenko static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
760928abaa7SAndrei Emeltchenko 				       struct sk_buff *skb)
761928abaa7SAndrei Emeltchenko {
762928abaa7SAndrei Emeltchenko 	struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
763928abaa7SAndrei Emeltchenko 
7649f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
765928abaa7SAndrei Emeltchenko 
766928abaa7SAndrei Emeltchenko 	if (rp->status)
7678e2a0d92SAndrei Emeltchenko 		goto a2mp_rsp;
768928abaa7SAndrei Emeltchenko 
769928abaa7SAndrei Emeltchenko 	hdev->amp_status = rp->amp_status;
770928abaa7SAndrei Emeltchenko 	hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
771928abaa7SAndrei Emeltchenko 	hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
772928abaa7SAndrei Emeltchenko 	hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
773928abaa7SAndrei Emeltchenko 	hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
774928abaa7SAndrei Emeltchenko 	hdev->amp_type = rp->amp_type;
775928abaa7SAndrei Emeltchenko 	hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
776928abaa7SAndrei Emeltchenko 	hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
777928abaa7SAndrei Emeltchenko 	hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
778928abaa7SAndrei Emeltchenko 	hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
779928abaa7SAndrei Emeltchenko 
7808e2a0d92SAndrei Emeltchenko a2mp_rsp:
7818e2a0d92SAndrei Emeltchenko 	a2mp_send_getinfo_rsp(hdev);
782928abaa7SAndrei Emeltchenko }
783928abaa7SAndrei Emeltchenko 
784903e4541SAndrei Emeltchenko static void hci_cc_read_local_amp_assoc(struct hci_dev *hdev,
785903e4541SAndrei Emeltchenko 					struct sk_buff *skb)
786903e4541SAndrei Emeltchenko {
787903e4541SAndrei Emeltchenko 	struct hci_rp_read_local_amp_assoc *rp = (void *) skb->data;
788903e4541SAndrei Emeltchenko 	struct amp_assoc *assoc = &hdev->loc_assoc;
789903e4541SAndrei Emeltchenko 	size_t rem_len, frag_len;
790903e4541SAndrei Emeltchenko 
791903e4541SAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
792903e4541SAndrei Emeltchenko 
793903e4541SAndrei Emeltchenko 	if (rp->status)
794903e4541SAndrei Emeltchenko 		goto a2mp_rsp;
795903e4541SAndrei Emeltchenko 
796903e4541SAndrei Emeltchenko 	frag_len = skb->len - sizeof(*rp);
797903e4541SAndrei Emeltchenko 	rem_len = __le16_to_cpu(rp->rem_len);
798903e4541SAndrei Emeltchenko 
799903e4541SAndrei Emeltchenko 	if (rem_len > frag_len) {
8002e430be3SAndrei Emeltchenko 		BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len);
801903e4541SAndrei Emeltchenko 
802903e4541SAndrei Emeltchenko 		memcpy(assoc->data + assoc->offset, rp->frag, frag_len);
803903e4541SAndrei Emeltchenko 		assoc->offset += frag_len;
804903e4541SAndrei Emeltchenko 
805903e4541SAndrei Emeltchenko 		/* Read other fragments */
806903e4541SAndrei Emeltchenko 		amp_read_loc_assoc_frag(hdev, rp->phy_handle);
807903e4541SAndrei Emeltchenko 
808903e4541SAndrei Emeltchenko 		return;
809903e4541SAndrei Emeltchenko 	}
810903e4541SAndrei Emeltchenko 
811903e4541SAndrei Emeltchenko 	memcpy(assoc->data + assoc->offset, rp->frag, rem_len);
812903e4541SAndrei Emeltchenko 	assoc->len = assoc->offset + rem_len;
813903e4541SAndrei Emeltchenko 	assoc->offset = 0;
814903e4541SAndrei Emeltchenko 
815903e4541SAndrei Emeltchenko a2mp_rsp:
816903e4541SAndrei Emeltchenko 	/* Send A2MP Rsp when all fragments are received */
817903e4541SAndrei Emeltchenko 	a2mp_send_getampassoc_rsp(hdev, rp->status);
8189495b2eeSAndrei Emeltchenko 	a2mp_send_create_phy_link_req(hdev, rp->status);
819903e4541SAndrei Emeltchenko }
820903e4541SAndrei Emeltchenko 
821d5859e22SJohan Hedberg static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
822d5859e22SJohan Hedberg 					 struct sk_buff *skb)
823d5859e22SJohan Hedberg {
82491c4e9b1SMarcel Holtmann 	struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data;
825d5859e22SJohan Hedberg 
8269f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
827d5859e22SJohan Hedberg 
82891c4e9b1SMarcel Holtmann 	if (!rp->status)
82991c4e9b1SMarcel Holtmann 		hdev->inq_tx_power = rp->tx_power;
830d5859e22SJohan Hedberg }
831d5859e22SJohan Hedberg 
832980e1a53SJohan Hedberg static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
833980e1a53SJohan Hedberg {
834980e1a53SJohan Hedberg 	struct hci_rp_pin_code_reply *rp = (void *) skb->data;
835980e1a53SJohan Hedberg 	struct hci_cp_pin_code_reply *cp;
836980e1a53SJohan Hedberg 	struct hci_conn *conn;
837980e1a53SJohan Hedberg 
8389f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
839980e1a53SJohan Hedberg 
84056e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
84156e5cb86SJohan Hedberg 
842a8b2d5c2SJohan Hedberg 	if (test_bit(HCI_MGMT, &hdev->dev_flags))
843744cf19eSJohan Hedberg 		mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
844980e1a53SJohan Hedberg 
845fa1bd918SMikel Astiz 	if (rp->status)
84656e5cb86SJohan Hedberg 		goto unlock;
847980e1a53SJohan Hedberg 
848980e1a53SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
849980e1a53SJohan Hedberg 	if (!cp)
85056e5cb86SJohan Hedberg 		goto unlock;
851980e1a53SJohan Hedberg 
852980e1a53SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
853980e1a53SJohan Hedberg 	if (conn)
854980e1a53SJohan Hedberg 		conn->pin_length = cp->pin_len;
85556e5cb86SJohan Hedberg 
85656e5cb86SJohan Hedberg unlock:
85756e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
858980e1a53SJohan Hedberg }
859980e1a53SJohan Hedberg 
860980e1a53SJohan Hedberg static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
861980e1a53SJohan Hedberg {
862980e1a53SJohan Hedberg 	struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
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 
868a8b2d5c2SJohan Hedberg 	if (test_bit(HCI_MGMT, &hdev->dev_flags))
869744cf19eSJohan Hedberg 		mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
870980e1a53SJohan Hedberg 						 rp->status);
87156e5cb86SJohan Hedberg 
87256e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
873980e1a53SJohan Hedberg }
87456e5cb86SJohan Hedberg 
8756ed58ec5SVille Tervo static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
8766ed58ec5SVille Tervo 				       struct sk_buff *skb)
8776ed58ec5SVille Tervo {
8786ed58ec5SVille Tervo 	struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
8796ed58ec5SVille Tervo 
8809f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
8816ed58ec5SVille Tervo 
8826ed58ec5SVille Tervo 	if (rp->status)
8836ed58ec5SVille Tervo 		return;
8846ed58ec5SVille Tervo 
8856ed58ec5SVille Tervo 	hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
8866ed58ec5SVille Tervo 	hdev->le_pkts = rp->le_max_pkt;
8876ed58ec5SVille Tervo 
8886ed58ec5SVille Tervo 	hdev->le_cnt = hdev->le_pkts;
8896ed58ec5SVille Tervo 
8906ed58ec5SVille Tervo 	BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
8916ed58ec5SVille Tervo }
892980e1a53SJohan Hedberg 
89360e77321SJohan Hedberg static void hci_cc_le_read_local_features(struct hci_dev *hdev,
89460e77321SJohan Hedberg 					  struct sk_buff *skb)
89560e77321SJohan Hedberg {
89660e77321SJohan Hedberg 	struct hci_rp_le_read_local_features *rp = (void *) skb->data;
89760e77321SJohan Hedberg 
89860e77321SJohan Hedberg 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
89960e77321SJohan Hedberg 
90060e77321SJohan Hedberg 	if (!rp->status)
90160e77321SJohan Hedberg 		memcpy(hdev->le_features, rp->features, 8);
90260e77321SJohan Hedberg }
90360e77321SJohan Hedberg 
9048fa19098SJohan Hedberg static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
9058fa19098SJohan Hedberg 					struct sk_buff *skb)
9068fa19098SJohan Hedberg {
9078fa19098SJohan Hedberg 	struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data;
9088fa19098SJohan Hedberg 
9098fa19098SJohan Hedberg 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
9108fa19098SJohan Hedberg 
91104b4edcbSJohan Hedberg 	if (!rp->status)
9128fa19098SJohan Hedberg 		hdev->adv_tx_power = rp->tx_power;
9138fa19098SJohan Hedberg }
9148fa19098SJohan Hedberg 
915a5c29683SJohan Hedberg static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
916a5c29683SJohan Hedberg {
917a5c29683SJohan Hedberg 	struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
918a5c29683SJohan Hedberg 
9199f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
920a5c29683SJohan Hedberg 
92156e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
92256e5cb86SJohan Hedberg 
923a8b2d5c2SJohan Hedberg 	if (test_bit(HCI_MGMT, &hdev->dev_flags))
92404124681SGustavo F. Padovan 		mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
92504124681SGustavo F. Padovan 						 rp->status);
92656e5cb86SJohan Hedberg 
92756e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
928a5c29683SJohan Hedberg }
929a5c29683SJohan Hedberg 
930a5c29683SJohan Hedberg static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
931a5c29683SJohan Hedberg 					  struct sk_buff *skb)
932a5c29683SJohan Hedberg {
933a5c29683SJohan Hedberg 	struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
934a5c29683SJohan Hedberg 
9359f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
936a5c29683SJohan Hedberg 
93756e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
93856e5cb86SJohan Hedberg 
939a8b2d5c2SJohan Hedberg 	if (test_bit(HCI_MGMT, &hdev->dev_flags))
940744cf19eSJohan Hedberg 		mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
94104124681SGustavo F. Padovan 						     ACL_LINK, 0, rp->status);
94256e5cb86SJohan Hedberg 
94356e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
944a5c29683SJohan Hedberg }
945a5c29683SJohan Hedberg 
9461143d458SBrian Gix static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
9471143d458SBrian Gix {
9481143d458SBrian Gix 	struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
9491143d458SBrian Gix 
9509f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
9511143d458SBrian Gix 
9521143d458SBrian Gix 	hci_dev_lock(hdev);
9531143d458SBrian Gix 
954a8b2d5c2SJohan Hedberg 	if (test_bit(HCI_MGMT, &hdev->dev_flags))
955272d90dfSJohan Hedberg 		mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
956272d90dfSJohan Hedberg 						 0, rp->status);
9571143d458SBrian Gix 
9581143d458SBrian Gix 	hci_dev_unlock(hdev);
9591143d458SBrian Gix }
9601143d458SBrian Gix 
9611143d458SBrian Gix static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
9621143d458SBrian Gix 					  struct sk_buff *skb)
9631143d458SBrian Gix {
9641143d458SBrian Gix 	struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
9651143d458SBrian Gix 
9669f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
9671143d458SBrian Gix 
9681143d458SBrian Gix 	hci_dev_lock(hdev);
9691143d458SBrian Gix 
970a8b2d5c2SJohan Hedberg 	if (test_bit(HCI_MGMT, &hdev->dev_flags))
9711143d458SBrian Gix 		mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
97204124681SGustavo F. Padovan 						     ACL_LINK, 0, rp->status);
9731143d458SBrian Gix 
9741143d458SBrian Gix 	hci_dev_unlock(hdev);
9751143d458SBrian Gix }
9761143d458SBrian Gix 
9774d2d2796SMarcel Holtmann static void hci_cc_read_local_oob_data(struct hci_dev *hdev,
978c35938b2SSzymon Janc 				       struct sk_buff *skb)
979c35938b2SSzymon Janc {
980c35938b2SSzymon Janc 	struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
981c35938b2SSzymon Janc 
9829f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
983c35938b2SSzymon Janc 
98456e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
9854d2d2796SMarcel Holtmann 	mgmt_read_local_oob_data_complete(hdev, rp->hash, rp->randomizer,
9864d2d2796SMarcel Holtmann 					  NULL, NULL, rp->status);
9874d2d2796SMarcel Holtmann 	hci_dev_unlock(hdev);
9884d2d2796SMarcel Holtmann }
9894d2d2796SMarcel Holtmann 
9904d2d2796SMarcel Holtmann static void hci_cc_read_local_oob_ext_data(struct hci_dev *hdev,
9914d2d2796SMarcel Holtmann 					   struct sk_buff *skb)
9924d2d2796SMarcel Holtmann {
9934d2d2796SMarcel Holtmann 	struct hci_rp_read_local_oob_ext_data *rp = (void *) skb->data;
9944d2d2796SMarcel Holtmann 
9954d2d2796SMarcel Holtmann 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
9964d2d2796SMarcel Holtmann 
9974d2d2796SMarcel Holtmann 	hci_dev_lock(hdev);
9984d2d2796SMarcel Holtmann 	mgmt_read_local_oob_data_complete(hdev, rp->hash192, rp->randomizer192,
9994d2d2796SMarcel Holtmann 					  rp->hash256, rp->randomizer256,
10004d2d2796SMarcel Holtmann 					  rp->status);
100156e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
1002c35938b2SSzymon Janc }
1003c35938b2SSzymon Janc 
10047a4cd51dSMarcel Holtmann 
10057a4cd51dSMarcel Holtmann static void hci_cc_le_set_random_addr(struct hci_dev *hdev, struct sk_buff *skb)
10067a4cd51dSMarcel Holtmann {
10077a4cd51dSMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
10087a4cd51dSMarcel Holtmann 	bdaddr_t *sent;
10097a4cd51dSMarcel Holtmann 
10107a4cd51dSMarcel Holtmann 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
10117a4cd51dSMarcel Holtmann 
10127a4cd51dSMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_RANDOM_ADDR);
10137a4cd51dSMarcel Holtmann 	if (!sent)
10147a4cd51dSMarcel Holtmann 		return;
10157a4cd51dSMarcel Holtmann 
10167a4cd51dSMarcel Holtmann 	hci_dev_lock(hdev);
10177a4cd51dSMarcel Holtmann 
10187a4cd51dSMarcel Holtmann 	if (!status)
10197a4cd51dSMarcel Holtmann 		bacpy(&hdev->random_addr, sent);
10207a4cd51dSMarcel Holtmann 
10217a4cd51dSMarcel Holtmann 	hci_dev_unlock(hdev);
10227a4cd51dSMarcel Holtmann }
10237a4cd51dSMarcel Holtmann 
1024c1d5dc4aSJohan Hedberg static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
1025c1d5dc4aSJohan Hedberg {
1026c1d5dc4aSJohan Hedberg 	__u8 *sent, status = *((__u8 *) skb->data);
1027c1d5dc4aSJohan Hedberg 
1028c1d5dc4aSJohan Hedberg 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1029c1d5dc4aSJohan Hedberg 
1030c1d5dc4aSJohan Hedberg 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
1031c1d5dc4aSJohan Hedberg 	if (!sent)
1032c1d5dc4aSJohan Hedberg 		return;
1033c1d5dc4aSJohan Hedberg 
10343c857757SJohan Hedberg 	if (status)
10353c857757SJohan Hedberg 		return;
10363c857757SJohan Hedberg 
1037c1d5dc4aSJohan Hedberg 	hci_dev_lock(hdev);
1038c1d5dc4aSJohan Hedberg 
10393c857757SJohan Hedberg 	/* If we're doing connection initation as peripheral. Set a
10403c857757SJohan Hedberg 	 * timeout in case something goes wrong.
10413c857757SJohan Hedberg 	 */
10423c857757SJohan Hedberg 	if (*sent) {
10433c857757SJohan Hedberg 		struct hci_conn *conn;
10443c857757SJohan Hedberg 
10453c857757SJohan Hedberg 		conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
10463c857757SJohan Hedberg 		if (conn)
10473c857757SJohan Hedberg 			queue_delayed_work(hdev->workqueue,
10483c857757SJohan Hedberg 					   &conn->le_conn_timeout,
10493c857757SJohan Hedberg 					   HCI_LE_CONN_TIMEOUT);
10503c857757SJohan Hedberg 	}
10513c857757SJohan Hedberg 
1052778b235aSJohan Hedberg 	mgmt_advertising(hdev, *sent);
1053c1d5dc4aSJohan Hedberg 
105404b4edcbSJohan Hedberg 	hci_dev_unlock(hdev);
1055c1d5dc4aSJohan Hedberg }
1056c1d5dc4aSJohan Hedberg 
1057533553f8SMarcel Holtmann static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1058533553f8SMarcel Holtmann {
1059533553f8SMarcel Holtmann 	struct hci_cp_le_set_scan_param *cp;
1060533553f8SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
1061533553f8SMarcel Holtmann 
1062533553f8SMarcel Holtmann 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1063533553f8SMarcel Holtmann 
1064533553f8SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_PARAM);
1065533553f8SMarcel Holtmann 	if (!cp)
1066533553f8SMarcel Holtmann 		return;
1067533553f8SMarcel Holtmann 
1068533553f8SMarcel Holtmann 	hci_dev_lock(hdev);
1069533553f8SMarcel Holtmann 
1070533553f8SMarcel Holtmann 	if (!status)
1071533553f8SMarcel Holtmann 		hdev->le_scan_type = cp->type;
1072533553f8SMarcel Holtmann 
1073533553f8SMarcel Holtmann 	hci_dev_unlock(hdev);
1074533553f8SMarcel Holtmann }
1075533553f8SMarcel Holtmann 
1076b9a6328fSJohan Hedberg static bool has_pending_adv_report(struct hci_dev *hdev)
1077b9a6328fSJohan Hedberg {
1078b9a6328fSJohan Hedberg 	struct discovery_state *d = &hdev->discovery;
1079b9a6328fSJohan Hedberg 
1080b9a6328fSJohan Hedberg 	return bacmp(&d->last_adv_addr, BDADDR_ANY);
1081b9a6328fSJohan Hedberg }
1082b9a6328fSJohan Hedberg 
1083b9a6328fSJohan Hedberg static void clear_pending_adv_report(struct hci_dev *hdev)
1084b9a6328fSJohan Hedberg {
1085b9a6328fSJohan Hedberg 	struct discovery_state *d = &hdev->discovery;
1086b9a6328fSJohan Hedberg 
1087b9a6328fSJohan Hedberg 	bacpy(&d->last_adv_addr, BDADDR_ANY);
1088b9a6328fSJohan Hedberg 	d->last_adv_data_len = 0;
1089b9a6328fSJohan Hedberg }
1090b9a6328fSJohan Hedberg 
1091b9a6328fSJohan Hedberg static void store_pending_adv_report(struct hci_dev *hdev, bdaddr_t *bdaddr,
1092c70a7e4cSMarcel Holtmann 				     u8 bdaddr_type, s8 rssi, u32 flags,
1093c70a7e4cSMarcel Holtmann 				     u8 *data, u8 len)
1094b9a6328fSJohan Hedberg {
1095b9a6328fSJohan Hedberg 	struct discovery_state *d = &hdev->discovery;
1096b9a6328fSJohan Hedberg 
1097b9a6328fSJohan Hedberg 	bacpy(&d->last_adv_addr, bdaddr);
1098b9a6328fSJohan Hedberg 	d->last_adv_addr_type = bdaddr_type;
1099ff5cd29fSJohan Hedberg 	d->last_adv_rssi = rssi;
1100c70a7e4cSMarcel Holtmann 	d->last_adv_flags = flags;
1101b9a6328fSJohan Hedberg 	memcpy(d->last_adv_data, data, len);
1102b9a6328fSJohan Hedberg 	d->last_adv_data_len = len;
1103b9a6328fSJohan Hedberg }
1104b9a6328fSJohan Hedberg 
1105eb9d91f5SAndre Guedes static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
1106eb9d91f5SAndre Guedes 				      struct sk_buff *skb)
1107eb9d91f5SAndre Guedes {
1108eb9d91f5SAndre Guedes 	struct hci_cp_le_set_scan_enable *cp;
1109eb9d91f5SAndre Guedes 	__u8 status = *((__u8 *) skb->data);
1110eb9d91f5SAndre Guedes 
11119f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1112eb9d91f5SAndre Guedes 
1113eb9d91f5SAndre Guedes 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1114eb9d91f5SAndre Guedes 	if (!cp)
1115eb9d91f5SAndre Guedes 		return;
1116eb9d91f5SAndre Guedes 
1117fef5234aSAndre Guedes 	if (status)
11187ba8b4beSAndre Guedes 		return;
11197ba8b4beSAndre Guedes 
11203fd319b8SAndre Guedes 	switch (cp->enable) {
11213fd319b8SAndre Guedes 	case LE_SCAN_ENABLE:
1122d23264a8SAndre Guedes 		set_bit(HCI_LE_SCAN, &hdev->dev_flags);
1123b9a6328fSJohan Hedberg 		if (hdev->le_scan_type == LE_SCAN_ACTIVE)
1124b9a6328fSJohan Hedberg 			clear_pending_adv_report(hdev);
112568a8aea4SAndrei Emeltchenko 		break;
112668a8aea4SAndrei Emeltchenko 
112776a388beSAndre Guedes 	case LE_SCAN_DISABLE:
1128b9a6328fSJohan Hedberg 		/* We do this here instead of when setting DISCOVERY_STOPPED
1129b9a6328fSJohan Hedberg 		 * since the latter would potentially require waiting for
1130b9a6328fSJohan Hedberg 		 * inquiry to stop too.
1131b9a6328fSJohan Hedberg 		 */
1132b9a6328fSJohan Hedberg 		if (has_pending_adv_report(hdev)) {
1133b9a6328fSJohan Hedberg 			struct discovery_state *d = &hdev->discovery;
1134b9a6328fSJohan Hedberg 
1135b9a6328fSJohan Hedberg 			mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
1136ab0aa433SJohan Hedberg 					  d->last_adv_addr_type, NULL,
1137c70a7e4cSMarcel Holtmann 					  d->last_adv_rssi, d->last_adv_flags,
1138ab0aa433SJohan Hedberg 					  d->last_adv_data,
1139b9a6328fSJohan Hedberg 					  d->last_adv_data_len, NULL, 0);
1140b9a6328fSJohan Hedberg 		}
1141b9a6328fSJohan Hedberg 
1142317ac8cbSJohan Hedberg 		/* Cancel this timer so that we don't try to disable scanning
1143317ac8cbSJohan Hedberg 		 * when it's already disabled.
1144317ac8cbSJohan Hedberg 		 */
1145317ac8cbSJohan Hedberg 		cancel_delayed_work(&hdev->le_scan_disable);
1146317ac8cbSJohan Hedberg 
1147d23264a8SAndre Guedes 		clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
114881ad6fd9SJohan Hedberg 		/* The HCI_LE_SCAN_INTERRUPTED flag indicates that we
114981ad6fd9SJohan Hedberg 		 * interrupted scanning due to a connect request. Mark
115081ad6fd9SJohan Hedberg 		 * therefore discovery as stopped.
115181ad6fd9SJohan Hedberg 		 */
115281ad6fd9SJohan Hedberg 		if (test_and_clear_bit(HCI_LE_SCAN_INTERRUPTED,
115381ad6fd9SJohan Hedberg 				       &hdev->dev_flags))
115481ad6fd9SJohan Hedberg 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
115568a8aea4SAndrei Emeltchenko 		break;
115668a8aea4SAndrei Emeltchenko 
115768a8aea4SAndrei Emeltchenko 	default:
115868a8aea4SAndrei Emeltchenko 		BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
115968a8aea4SAndrei Emeltchenko 		break;
116035815085SAndre Guedes 	}
1161eb9d91f5SAndre Guedes }
1162eb9d91f5SAndre Guedes 
1163cf1d081fSJohan Hedberg static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
1164cf1d081fSJohan Hedberg 					   struct sk_buff *skb)
1165cf1d081fSJohan Hedberg {
1166cf1d081fSJohan Hedberg 	struct hci_rp_le_read_white_list_size *rp = (void *) skb->data;
1167cf1d081fSJohan Hedberg 
1168cf1d081fSJohan Hedberg 	BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
1169cf1d081fSJohan Hedberg 
1170cf1d081fSJohan Hedberg 	if (!rp->status)
1171cf1d081fSJohan Hedberg 		hdev->le_white_list_size = rp->size;
1172cf1d081fSJohan Hedberg }
1173cf1d081fSJohan Hedberg 
11740f36b589SMarcel Holtmann static void hci_cc_le_clear_white_list(struct hci_dev *hdev,
11750f36b589SMarcel Holtmann 				       struct sk_buff *skb)
11760f36b589SMarcel Holtmann {
11770f36b589SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
11780f36b589SMarcel Holtmann 
11790f36b589SMarcel Holtmann 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
11800f36b589SMarcel Holtmann 
11810f36b589SMarcel Holtmann 	if (!status)
11820f36b589SMarcel Holtmann 		hci_white_list_clear(hdev);
11830f36b589SMarcel Holtmann }
11840f36b589SMarcel Holtmann 
11850f36b589SMarcel Holtmann static void hci_cc_le_add_to_white_list(struct hci_dev *hdev,
11860f36b589SMarcel Holtmann 					struct sk_buff *skb)
11870f36b589SMarcel Holtmann {
11880f36b589SMarcel Holtmann 	struct hci_cp_le_add_to_white_list *sent;
11890f36b589SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
11900f36b589SMarcel Holtmann 
11910f36b589SMarcel Holtmann 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
11920f36b589SMarcel Holtmann 
11930f36b589SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_WHITE_LIST);
11940f36b589SMarcel Holtmann 	if (!sent)
11950f36b589SMarcel Holtmann 		return;
11960f36b589SMarcel Holtmann 
11970f36b589SMarcel Holtmann 	if (!status)
11980f36b589SMarcel Holtmann 		hci_white_list_add(hdev, &sent->bdaddr, sent->bdaddr_type);
11990f36b589SMarcel Holtmann }
12000f36b589SMarcel Holtmann 
12010f36b589SMarcel Holtmann static void hci_cc_le_del_from_white_list(struct hci_dev *hdev,
12020f36b589SMarcel Holtmann 					  struct sk_buff *skb)
12030f36b589SMarcel Holtmann {
12040f36b589SMarcel Holtmann 	struct hci_cp_le_del_from_white_list *sent;
12050f36b589SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
12060f36b589SMarcel Holtmann 
12070f36b589SMarcel Holtmann 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
12080f36b589SMarcel Holtmann 
12090f36b589SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_WHITE_LIST);
12100f36b589SMarcel Holtmann 	if (!sent)
12110f36b589SMarcel Holtmann 		return;
12120f36b589SMarcel Holtmann 
12130f36b589SMarcel Holtmann 	if (!status)
12140f36b589SMarcel Holtmann 		hci_white_list_del(hdev, &sent->bdaddr, sent->bdaddr_type);
12150f36b589SMarcel Holtmann }
12160f36b589SMarcel Holtmann 
12179b008c04SJohan Hedberg static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
12189b008c04SJohan Hedberg 					    struct sk_buff *skb)
12199b008c04SJohan Hedberg {
12209b008c04SJohan Hedberg 	struct hci_rp_le_read_supported_states *rp = (void *) skb->data;
12219b008c04SJohan Hedberg 
12229b008c04SJohan Hedberg 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
12239b008c04SJohan Hedberg 
12249b008c04SJohan Hedberg 	if (!rp->status)
12259b008c04SJohan Hedberg 		memcpy(hdev->le_states, rp->le_states, 8);
12269b008c04SJohan Hedberg }
12279b008c04SJohan Hedberg 
12286039aa73SGustavo Padovan static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1229f9b49306SAndre Guedes 					   struct sk_buff *skb)
1230f9b49306SAndre Guedes {
123106199cf8SJohan Hedberg 	struct hci_cp_write_le_host_supported *sent;
1232f9b49306SAndre Guedes 	__u8 status = *((__u8 *) skb->data);
1233f9b49306SAndre Guedes 
12349f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1235f9b49306SAndre Guedes 
123606199cf8SJohan Hedberg 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
12378f984dfaSJohan Hedberg 	if (!sent)
1238f9b49306SAndre Guedes 		return;
1239f9b49306SAndre Guedes 
12408f984dfaSJohan Hedberg 	if (!status) {
1241416a4ae5SJohan Hedberg 		if (sent->le) {
1242cad718edSJohan Hedberg 			hdev->features[1][0] |= LMP_HOST_LE;
1243416a4ae5SJohan Hedberg 			set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
1244416a4ae5SJohan Hedberg 		} else {
1245cad718edSJohan Hedberg 			hdev->features[1][0] &= ~LMP_HOST_LE;
1246416a4ae5SJohan Hedberg 			clear_bit(HCI_LE_ENABLED, &hdev->dev_flags);
1247f3d3444aSJohan Hedberg 			clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
1248416a4ae5SJohan Hedberg 		}
124953b2caabSJohan Hedberg 
125053b2caabSJohan Hedberg 		if (sent->simul)
1251cad718edSJohan Hedberg 			hdev->features[1][0] |= LMP_HOST_LE_BREDR;
125253b2caabSJohan Hedberg 		else
1253cad718edSJohan Hedberg 			hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
12548f984dfaSJohan Hedberg 	}
1255f9b49306SAndre Guedes }
1256f9b49306SAndre Guedes 
125756ed2cb8SJohan Hedberg static void hci_cc_set_adv_param(struct hci_dev *hdev, struct sk_buff *skb)
125856ed2cb8SJohan Hedberg {
125956ed2cb8SJohan Hedberg 	struct hci_cp_le_set_adv_param *cp;
126056ed2cb8SJohan Hedberg 	u8 status = *((u8 *) skb->data);
126156ed2cb8SJohan Hedberg 
126256ed2cb8SJohan Hedberg 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
126356ed2cb8SJohan Hedberg 
126456ed2cb8SJohan Hedberg 	if (status)
126556ed2cb8SJohan Hedberg 		return;
126656ed2cb8SJohan Hedberg 
126756ed2cb8SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_PARAM);
126856ed2cb8SJohan Hedberg 	if (!cp)
126956ed2cb8SJohan Hedberg 		return;
127056ed2cb8SJohan Hedberg 
127156ed2cb8SJohan Hedberg 	hci_dev_lock(hdev);
127256ed2cb8SJohan Hedberg 	hdev->adv_addr_type = cp->own_address_type;
127356ed2cb8SJohan Hedberg 	hci_dev_unlock(hdev);
127456ed2cb8SJohan Hedberg }
127556ed2cb8SJohan Hedberg 
127693c284eeSAndrei Emeltchenko static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
127793c284eeSAndrei Emeltchenko 					  struct sk_buff *skb)
127893c284eeSAndrei Emeltchenko {
127993c284eeSAndrei Emeltchenko 	struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data;
128093c284eeSAndrei Emeltchenko 
128193c284eeSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x",
128293c284eeSAndrei Emeltchenko 	       hdev->name, rp->status, rp->phy_handle);
128393c284eeSAndrei Emeltchenko 
128493c284eeSAndrei Emeltchenko 	if (rp->status)
128593c284eeSAndrei Emeltchenko 		return;
128693c284eeSAndrei Emeltchenko 
128793c284eeSAndrei Emeltchenko 	amp_write_rem_assoc_continue(hdev, rp->phy_handle);
128893c284eeSAndrei Emeltchenko }
128993c284eeSAndrei Emeltchenko 
12905ae76a94SAndrzej Kaczmarek static void hci_cc_read_rssi(struct hci_dev *hdev, struct sk_buff *skb)
12915ae76a94SAndrzej Kaczmarek {
12925ae76a94SAndrzej Kaczmarek 	struct hci_rp_read_rssi *rp = (void *) skb->data;
12935ae76a94SAndrzej Kaczmarek 	struct hci_conn *conn;
12945ae76a94SAndrzej Kaczmarek 
12955ae76a94SAndrzej Kaczmarek 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
12965ae76a94SAndrzej Kaczmarek 
12975ae76a94SAndrzej Kaczmarek 	if (rp->status)
12985ae76a94SAndrzej Kaczmarek 		return;
12995ae76a94SAndrzej Kaczmarek 
13005ae76a94SAndrzej Kaczmarek 	hci_dev_lock(hdev);
13015ae76a94SAndrzej Kaczmarek 
13025ae76a94SAndrzej Kaczmarek 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
13035ae76a94SAndrzej Kaczmarek 	if (conn)
13045ae76a94SAndrzej Kaczmarek 		conn->rssi = rp->rssi;
13055ae76a94SAndrzej Kaczmarek 
13065ae76a94SAndrzej Kaczmarek 	hci_dev_unlock(hdev);
13075ae76a94SAndrzej Kaczmarek }
13085ae76a94SAndrzej Kaczmarek 
13095a134faeSAndrzej Kaczmarek static void hci_cc_read_tx_power(struct hci_dev *hdev, struct sk_buff *skb)
13105a134faeSAndrzej Kaczmarek {
13115a134faeSAndrzej Kaczmarek 	struct hci_cp_read_tx_power *sent;
13125a134faeSAndrzej Kaczmarek 	struct hci_rp_read_tx_power *rp = (void *) skb->data;
13135a134faeSAndrzej Kaczmarek 	struct hci_conn *conn;
13145a134faeSAndrzej Kaczmarek 
13155a134faeSAndrzej Kaczmarek 	BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
13165a134faeSAndrzej Kaczmarek 
13175a134faeSAndrzej Kaczmarek 	if (rp->status)
13185a134faeSAndrzej Kaczmarek 		return;
13195a134faeSAndrzej Kaczmarek 
13205a134faeSAndrzej Kaczmarek 	sent = hci_sent_cmd_data(hdev, HCI_OP_READ_TX_POWER);
13215a134faeSAndrzej Kaczmarek 	if (!sent)
13225a134faeSAndrzej Kaczmarek 		return;
13235a134faeSAndrzej Kaczmarek 
13245a134faeSAndrzej Kaczmarek 	hci_dev_lock(hdev);
13255a134faeSAndrzej Kaczmarek 
13265a134faeSAndrzej Kaczmarek 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
1327d0455ed9SAndrzej Kaczmarek 	if (!conn)
1328d0455ed9SAndrzej Kaczmarek 		goto unlock;
13295a134faeSAndrzej Kaczmarek 
1330d0455ed9SAndrzej Kaczmarek 	switch (sent->type) {
1331d0455ed9SAndrzej Kaczmarek 	case 0x00:
1332d0455ed9SAndrzej Kaczmarek 		conn->tx_power = rp->tx_power;
1333d0455ed9SAndrzej Kaczmarek 		break;
1334d0455ed9SAndrzej Kaczmarek 	case 0x01:
1335d0455ed9SAndrzej Kaczmarek 		conn->max_tx_power = rp->tx_power;
1336d0455ed9SAndrzej Kaczmarek 		break;
1337d0455ed9SAndrzej Kaczmarek 	}
1338d0455ed9SAndrzej Kaczmarek 
1339d0455ed9SAndrzej Kaczmarek unlock:
13405a134faeSAndrzej Kaczmarek 	hci_dev_unlock(hdev);
13415a134faeSAndrzej Kaczmarek }
13425a134faeSAndrzej Kaczmarek 
13436039aa73SGustavo Padovan static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1344a9de9248SMarcel Holtmann {
13459f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1346a9de9248SMarcel Holtmann 
1347a9de9248SMarcel Holtmann 	if (status) {
1348a9de9248SMarcel Holtmann 		hci_conn_check_pending(hdev);
1349314b2381SJohan Hedberg 		return;
1350314b2381SJohan Hedberg 	}
1351314b2381SJohan Hedberg 
135289352e7dSAndre Guedes 	set_bit(HCI_INQUIRY, &hdev->flags);
1353a9de9248SMarcel Holtmann }
1354a9de9248SMarcel Holtmann 
13556039aa73SGustavo Padovan static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
13561da177e4SLinus Torvalds {
1357a9de9248SMarcel Holtmann 	struct hci_cp_create_conn *cp;
13581da177e4SLinus Torvalds 	struct hci_conn *conn;
13591da177e4SLinus Torvalds 
13609f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1361a9de9248SMarcel Holtmann 
1362a9de9248SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
13631da177e4SLinus Torvalds 	if (!cp)
13641da177e4SLinus Torvalds 		return;
13651da177e4SLinus Torvalds 
13661da177e4SLinus Torvalds 	hci_dev_lock(hdev);
13671da177e4SLinus Torvalds 
13681da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
13691da177e4SLinus Torvalds 
13706ed93dc6SAndrei Emeltchenko 	BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
13711da177e4SLinus Torvalds 
13721da177e4SLinus Torvalds 	if (status) {
13731da177e4SLinus Torvalds 		if (conn && conn->state == BT_CONNECT) {
13744c67bc74SMarcel Holtmann 			if (status != 0x0c || conn->attempt > 2) {
13751da177e4SLinus Torvalds 				conn->state = BT_CLOSED;
13761da177e4SLinus Torvalds 				hci_proto_connect_cfm(conn, status);
13771da177e4SLinus Torvalds 				hci_conn_del(conn);
13784c67bc74SMarcel Holtmann 			} else
13794c67bc74SMarcel Holtmann 				conn->state = BT_CONNECT2;
13801da177e4SLinus Torvalds 		}
13811da177e4SLinus Torvalds 	} else {
13821da177e4SLinus Torvalds 		if (!conn) {
13831da177e4SLinus Torvalds 			conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
13841da177e4SLinus Torvalds 			if (conn) {
1385a0c808b3SJohan Hedberg 				conn->out = true;
13864dae2798SJohan Hedberg 				set_bit(HCI_CONN_MASTER, &conn->flags);
13871da177e4SLinus Torvalds 			} else
1388893ef971SGustavo F. Padovan 				BT_ERR("No memory for new connection");
13891da177e4SLinus Torvalds 		}
13901da177e4SLinus Torvalds 	}
13911da177e4SLinus Torvalds 
13921da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
13931da177e4SLinus Torvalds }
13941da177e4SLinus Torvalds 
1395a9de9248SMarcel Holtmann static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
13961da177e4SLinus Torvalds {
1397a9de9248SMarcel Holtmann 	struct hci_cp_add_sco *cp;
13981da177e4SLinus Torvalds 	struct hci_conn *acl, *sco;
13991da177e4SLinus Torvalds 	__u16 handle;
14001da177e4SLinus Torvalds 
14019f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1402b6a0dc82SMarcel Holtmann 
1403a9de9248SMarcel Holtmann 	if (!status)
1404a9de9248SMarcel Holtmann 		return;
1405a9de9248SMarcel Holtmann 
1406a9de9248SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
14071da177e4SLinus Torvalds 	if (!cp)
1408a9de9248SMarcel Holtmann 		return;
14091da177e4SLinus Torvalds 
14101da177e4SLinus Torvalds 	handle = __le16_to_cpu(cp->handle);
14111da177e4SLinus Torvalds 
14129f1db00cSAndrei Emeltchenko 	BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
14131da177e4SLinus Torvalds 
14141da177e4SLinus Torvalds 	hci_dev_lock(hdev);
14151da177e4SLinus Torvalds 
14161da177e4SLinus Torvalds 	acl = hci_conn_hash_lookup_handle(hdev, handle);
14175a08ecceSAndrei Emeltchenko 	if (acl) {
14185a08ecceSAndrei Emeltchenko 		sco = acl->link;
14195a08ecceSAndrei Emeltchenko 		if (sco) {
14201da177e4SLinus Torvalds 			sco->state = BT_CLOSED;
14211da177e4SLinus Torvalds 
14221da177e4SLinus Torvalds 			hci_proto_connect_cfm(sco, status);
14231da177e4SLinus Torvalds 			hci_conn_del(sco);
14241da177e4SLinus Torvalds 		}
14255a08ecceSAndrei Emeltchenko 	}
14261da177e4SLinus Torvalds 
14271da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
14281da177e4SLinus Torvalds }
14291da177e4SLinus Torvalds 
1430f8558555SMarcel Holtmann static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1431f8558555SMarcel Holtmann {
1432f8558555SMarcel Holtmann 	struct hci_cp_auth_requested *cp;
1433f8558555SMarcel Holtmann 	struct hci_conn *conn;
1434f8558555SMarcel Holtmann 
14359f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1436f8558555SMarcel Holtmann 
1437f8558555SMarcel Holtmann 	if (!status)
1438f8558555SMarcel Holtmann 		return;
1439f8558555SMarcel Holtmann 
1440f8558555SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1441f8558555SMarcel Holtmann 	if (!cp)
1442f8558555SMarcel Holtmann 		return;
1443f8558555SMarcel Holtmann 
1444f8558555SMarcel Holtmann 	hci_dev_lock(hdev);
1445f8558555SMarcel Holtmann 
1446f8558555SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1447f8558555SMarcel Holtmann 	if (conn) {
1448f8558555SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
1449f8558555SMarcel Holtmann 			hci_proto_connect_cfm(conn, status);
145076a68ba0SDavid Herrmann 			hci_conn_drop(conn);
1451f8558555SMarcel Holtmann 		}
1452f8558555SMarcel Holtmann 	}
1453f8558555SMarcel Holtmann 
1454f8558555SMarcel Holtmann 	hci_dev_unlock(hdev);
1455f8558555SMarcel Holtmann }
1456f8558555SMarcel Holtmann 
1457f8558555SMarcel Holtmann static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1458f8558555SMarcel Holtmann {
1459f8558555SMarcel Holtmann 	struct hci_cp_set_conn_encrypt *cp;
1460f8558555SMarcel Holtmann 	struct hci_conn *conn;
1461f8558555SMarcel Holtmann 
14629f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1463f8558555SMarcel Holtmann 
1464f8558555SMarcel Holtmann 	if (!status)
1465f8558555SMarcel Holtmann 		return;
1466f8558555SMarcel Holtmann 
1467f8558555SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1468f8558555SMarcel Holtmann 	if (!cp)
1469f8558555SMarcel Holtmann 		return;
1470f8558555SMarcel Holtmann 
1471f8558555SMarcel Holtmann 	hci_dev_lock(hdev);
1472f8558555SMarcel Holtmann 
1473f8558555SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1474f8558555SMarcel Holtmann 	if (conn) {
1475f8558555SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
1476f8558555SMarcel Holtmann 			hci_proto_connect_cfm(conn, status);
147776a68ba0SDavid Herrmann 			hci_conn_drop(conn);
1478f8558555SMarcel Holtmann 		}
1479f8558555SMarcel Holtmann 	}
1480f8558555SMarcel Holtmann 
1481f8558555SMarcel Holtmann 	hci_dev_unlock(hdev);
1482f8558555SMarcel Holtmann }
1483f8558555SMarcel Holtmann 
1484127178d2SJohan Hedberg static int hci_outgoing_auth_needed(struct hci_dev *hdev,
1485392599b9SJohan Hedberg 				    struct hci_conn *conn)
1486392599b9SJohan Hedberg {
1487392599b9SJohan Hedberg 	if (conn->state != BT_CONFIG || !conn->out)
1488392599b9SJohan Hedberg 		return 0;
1489392599b9SJohan Hedberg 
1490765c2a96SJohan Hedberg 	if (conn->pending_sec_level == BT_SECURITY_SDP)
1491392599b9SJohan Hedberg 		return 0;
1492392599b9SJohan Hedberg 
1493392599b9SJohan Hedberg 	/* Only request authentication for SSP connections or non-SSP
1494264b8b4eSJohan Hedberg 	 * devices with sec_level MEDIUM or HIGH or if MITM protection
1495264b8b4eSJohan Hedberg 	 * is requested.
1496264b8b4eSJohan Hedberg 	 */
1497807deac2SGustavo Padovan 	if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
14987e3691e1SJohan Hedberg 	    conn->pending_sec_level != BT_SECURITY_FIPS &&
1499264b8b4eSJohan Hedberg 	    conn->pending_sec_level != BT_SECURITY_HIGH &&
1500264b8b4eSJohan Hedberg 	    conn->pending_sec_level != BT_SECURITY_MEDIUM)
1501392599b9SJohan Hedberg 		return 0;
1502392599b9SJohan Hedberg 
1503392599b9SJohan Hedberg 	return 1;
1504392599b9SJohan Hedberg }
1505392599b9SJohan Hedberg 
15066039aa73SGustavo Padovan static int hci_resolve_name(struct hci_dev *hdev,
150700abfe44SGustavo F. Padovan 				   struct inquiry_entry *e)
150830dc78e1SJohan Hedberg {
150930dc78e1SJohan Hedberg 	struct hci_cp_remote_name_req cp;
151030dc78e1SJohan Hedberg 
151130dc78e1SJohan Hedberg 	memset(&cp, 0, sizeof(cp));
151230dc78e1SJohan Hedberg 
151330dc78e1SJohan Hedberg 	bacpy(&cp.bdaddr, &e->data.bdaddr);
151430dc78e1SJohan Hedberg 	cp.pscan_rep_mode = e->data.pscan_rep_mode;
151530dc78e1SJohan Hedberg 	cp.pscan_mode = e->data.pscan_mode;
151630dc78e1SJohan Hedberg 	cp.clock_offset = e->data.clock_offset;
151730dc78e1SJohan Hedberg 
151830dc78e1SJohan Hedberg 	return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
151930dc78e1SJohan Hedberg }
152030dc78e1SJohan Hedberg 
1521b644ba33SJohan Hedberg static bool hci_resolve_next_name(struct hci_dev *hdev)
152230dc78e1SJohan Hedberg {
152330dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
152430dc78e1SJohan Hedberg 	struct inquiry_entry *e;
152530dc78e1SJohan Hedberg 
1526b644ba33SJohan Hedberg 	if (list_empty(&discov->resolve))
1527b644ba33SJohan Hedberg 		return false;
1528b644ba33SJohan Hedberg 
1529b644ba33SJohan Hedberg 	e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1530c810089cSRam Malovany 	if (!e)
1531c810089cSRam Malovany 		return false;
1532c810089cSRam Malovany 
1533b644ba33SJohan Hedberg 	if (hci_resolve_name(hdev, e) == 0) {
1534b644ba33SJohan Hedberg 		e->name_state = NAME_PENDING;
1535b644ba33SJohan Hedberg 		return true;
1536b644ba33SJohan Hedberg 	}
1537b644ba33SJohan Hedberg 
1538b644ba33SJohan Hedberg 	return false;
1539b644ba33SJohan Hedberg }
1540b644ba33SJohan Hedberg 
1541b644ba33SJohan Hedberg static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
1542b644ba33SJohan Hedberg 				   bdaddr_t *bdaddr, u8 *name, u8 name_len)
1543b644ba33SJohan Hedberg {
1544b644ba33SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
1545b644ba33SJohan Hedberg 	struct inquiry_entry *e;
1546b644ba33SJohan Hedberg 
1547b644ba33SJohan Hedberg 	if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
154804124681SGustavo F. Padovan 		mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
154904124681SGustavo F. Padovan 				      name_len, conn->dev_class);
1550b644ba33SJohan Hedberg 
1551b644ba33SJohan Hedberg 	if (discov->state == DISCOVERY_STOPPED)
1552b644ba33SJohan Hedberg 		return;
1553b644ba33SJohan Hedberg 
155430dc78e1SJohan Hedberg 	if (discov->state == DISCOVERY_STOPPING)
155530dc78e1SJohan Hedberg 		goto discov_complete;
155630dc78e1SJohan Hedberg 
155730dc78e1SJohan Hedberg 	if (discov->state != DISCOVERY_RESOLVING)
155830dc78e1SJohan Hedberg 		return;
155930dc78e1SJohan Hedberg 
156030dc78e1SJohan Hedberg 	e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
15617cc8380eSRam Malovany 	/* If the device was not found in a list of found devices names of which
15627cc8380eSRam Malovany 	 * are pending. there is no need to continue resolving a next name as it
15637cc8380eSRam Malovany 	 * will be done upon receiving another Remote Name Request Complete
15647cc8380eSRam Malovany 	 * Event */
15657cc8380eSRam Malovany 	if (!e)
15667cc8380eSRam Malovany 		return;
15677cc8380eSRam Malovany 
156830dc78e1SJohan Hedberg 	list_del(&e->list);
15697cc8380eSRam Malovany 	if (name) {
15707cc8380eSRam Malovany 		e->name_state = NAME_KNOWN;
1571b644ba33SJohan Hedberg 		mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1572b644ba33SJohan Hedberg 				 e->data.rssi, name, name_len);
1573c3e7c0d9SRam Malovany 	} else {
1574c3e7c0d9SRam Malovany 		e->name_state = NAME_NOT_KNOWN;
157530dc78e1SJohan Hedberg 	}
157630dc78e1SJohan Hedberg 
1577b644ba33SJohan Hedberg 	if (hci_resolve_next_name(hdev))
157830dc78e1SJohan Hedberg 		return;
157930dc78e1SJohan Hedberg 
158030dc78e1SJohan Hedberg discov_complete:
158130dc78e1SJohan Hedberg 	hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
158230dc78e1SJohan Hedberg }
158330dc78e1SJohan Hedberg 
1584a9de9248SMarcel Holtmann static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
15851da177e4SLinus Torvalds {
1586127178d2SJohan Hedberg 	struct hci_cp_remote_name_req *cp;
1587127178d2SJohan Hedberg 	struct hci_conn *conn;
1588127178d2SJohan Hedberg 
15899f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1590127178d2SJohan Hedberg 
1591127178d2SJohan Hedberg 	/* If successful wait for the name req complete event before
1592127178d2SJohan Hedberg 	 * checking for the need to do authentication */
1593127178d2SJohan Hedberg 	if (!status)
1594127178d2SJohan Hedberg 		return;
1595127178d2SJohan Hedberg 
1596127178d2SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1597127178d2SJohan Hedberg 	if (!cp)
1598127178d2SJohan Hedberg 		return;
1599127178d2SJohan Hedberg 
1600127178d2SJohan Hedberg 	hci_dev_lock(hdev);
1601127178d2SJohan Hedberg 
1602127178d2SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1603b644ba33SJohan Hedberg 
1604b644ba33SJohan Hedberg 	if (test_bit(HCI_MGMT, &hdev->dev_flags))
1605b644ba33SJohan Hedberg 		hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1606b644ba33SJohan Hedberg 
160779c6c70cSJohan Hedberg 	if (!conn)
160879c6c70cSJohan Hedberg 		goto unlock;
160979c6c70cSJohan Hedberg 
161079c6c70cSJohan Hedberg 	if (!hci_outgoing_auth_needed(hdev, conn))
161179c6c70cSJohan Hedberg 		goto unlock;
161279c6c70cSJohan Hedberg 
161351a8efd7SJohan Hedberg 	if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
1614c1f23a2bSJohannes Berg 		struct hci_cp_auth_requested auth_cp;
1615c1f23a2bSJohannes Berg 
1616c1f23a2bSJohannes Berg 		auth_cp.handle = __cpu_to_le16(conn->handle);
1617c1f23a2bSJohannes Berg 		hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
1618c1f23a2bSJohannes Berg 			     sizeof(auth_cp), &auth_cp);
1619127178d2SJohan Hedberg 	}
1620127178d2SJohan Hedberg 
162179c6c70cSJohan Hedberg unlock:
1622127178d2SJohan Hedberg 	hci_dev_unlock(hdev);
1623a9de9248SMarcel Holtmann }
16241da177e4SLinus Torvalds 
1625769be974SMarcel Holtmann static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1626769be974SMarcel Holtmann {
1627769be974SMarcel Holtmann 	struct hci_cp_read_remote_features *cp;
1628769be974SMarcel Holtmann 	struct hci_conn *conn;
1629769be974SMarcel Holtmann 
16309f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1631769be974SMarcel Holtmann 
1632769be974SMarcel Holtmann 	if (!status)
1633769be974SMarcel Holtmann 		return;
1634769be974SMarcel Holtmann 
1635769be974SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1636769be974SMarcel Holtmann 	if (!cp)
1637769be974SMarcel Holtmann 		return;
1638769be974SMarcel Holtmann 
1639769be974SMarcel Holtmann 	hci_dev_lock(hdev);
1640769be974SMarcel Holtmann 
1641769be974SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1642769be974SMarcel Holtmann 	if (conn) {
1643769be974SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
1644769be974SMarcel Holtmann 			hci_proto_connect_cfm(conn, status);
164576a68ba0SDavid Herrmann 			hci_conn_drop(conn);
1646769be974SMarcel Holtmann 		}
1647769be974SMarcel Holtmann 	}
1648769be974SMarcel Holtmann 
1649769be974SMarcel Holtmann 	hci_dev_unlock(hdev);
1650769be974SMarcel Holtmann }
1651769be974SMarcel Holtmann 
1652769be974SMarcel Holtmann static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1653769be974SMarcel Holtmann {
1654769be974SMarcel Holtmann 	struct hci_cp_read_remote_ext_features *cp;
1655769be974SMarcel Holtmann 	struct hci_conn *conn;
1656769be974SMarcel Holtmann 
16579f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1658769be974SMarcel Holtmann 
1659769be974SMarcel Holtmann 	if (!status)
1660769be974SMarcel Holtmann 		return;
1661769be974SMarcel Holtmann 
1662769be974SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1663769be974SMarcel Holtmann 	if (!cp)
1664769be974SMarcel Holtmann 		return;
1665769be974SMarcel Holtmann 
1666769be974SMarcel Holtmann 	hci_dev_lock(hdev);
1667769be974SMarcel Holtmann 
1668769be974SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1669769be974SMarcel Holtmann 	if (conn) {
1670769be974SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
1671769be974SMarcel Holtmann 			hci_proto_connect_cfm(conn, status);
167276a68ba0SDavid Herrmann 			hci_conn_drop(conn);
1673769be974SMarcel Holtmann 		}
1674769be974SMarcel Holtmann 	}
1675769be974SMarcel Holtmann 
1676769be974SMarcel Holtmann 	hci_dev_unlock(hdev);
1677769be974SMarcel Holtmann }
1678769be974SMarcel Holtmann 
1679a9de9248SMarcel Holtmann static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1680a9de9248SMarcel Holtmann {
1681b6a0dc82SMarcel Holtmann 	struct hci_cp_setup_sync_conn *cp;
1682b6a0dc82SMarcel Holtmann 	struct hci_conn *acl, *sco;
1683b6a0dc82SMarcel Holtmann 	__u16 handle;
1684b6a0dc82SMarcel Holtmann 
16859f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1686b6a0dc82SMarcel Holtmann 
1687b6a0dc82SMarcel Holtmann 	if (!status)
1688b6a0dc82SMarcel Holtmann 		return;
1689b6a0dc82SMarcel Holtmann 
1690b6a0dc82SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1691b6a0dc82SMarcel Holtmann 	if (!cp)
1692b6a0dc82SMarcel Holtmann 		return;
1693b6a0dc82SMarcel Holtmann 
1694b6a0dc82SMarcel Holtmann 	handle = __le16_to_cpu(cp->handle);
1695b6a0dc82SMarcel Holtmann 
16969f1db00cSAndrei Emeltchenko 	BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
1697b6a0dc82SMarcel Holtmann 
1698b6a0dc82SMarcel Holtmann 	hci_dev_lock(hdev);
1699b6a0dc82SMarcel Holtmann 
1700b6a0dc82SMarcel Holtmann 	acl = hci_conn_hash_lookup_handle(hdev, handle);
17015a08ecceSAndrei Emeltchenko 	if (acl) {
17025a08ecceSAndrei Emeltchenko 		sco = acl->link;
17035a08ecceSAndrei Emeltchenko 		if (sco) {
1704b6a0dc82SMarcel Holtmann 			sco->state = BT_CLOSED;
1705b6a0dc82SMarcel Holtmann 
1706b6a0dc82SMarcel Holtmann 			hci_proto_connect_cfm(sco, status);
1707b6a0dc82SMarcel Holtmann 			hci_conn_del(sco);
1708b6a0dc82SMarcel Holtmann 		}
17095a08ecceSAndrei Emeltchenko 	}
1710b6a0dc82SMarcel Holtmann 
1711b6a0dc82SMarcel Holtmann 	hci_dev_unlock(hdev);
1712a9de9248SMarcel Holtmann }
1713a9de9248SMarcel Holtmann 
1714a9de9248SMarcel Holtmann static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1715a9de9248SMarcel Holtmann {
1716a9de9248SMarcel Holtmann 	struct hci_cp_sniff_mode *cp;
171704837f64SMarcel Holtmann 	struct hci_conn *conn;
171804837f64SMarcel Holtmann 
17199f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1720a9de9248SMarcel Holtmann 
1721a9de9248SMarcel Holtmann 	if (!status)
1722a9de9248SMarcel Holtmann 		return;
1723a9de9248SMarcel Holtmann 
1724a9de9248SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
172504837f64SMarcel Holtmann 	if (!cp)
1726a9de9248SMarcel Holtmann 		return;
172704837f64SMarcel Holtmann 
172804837f64SMarcel Holtmann 	hci_dev_lock(hdev);
172904837f64SMarcel Holtmann 
173004837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1731e73439d8SMarcel Holtmann 	if (conn) {
173251a8efd7SJohan Hedberg 		clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
173304837f64SMarcel Holtmann 
173451a8efd7SJohan Hedberg 		if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
1735e73439d8SMarcel Holtmann 			hci_sco_setup(conn, status);
1736e73439d8SMarcel Holtmann 	}
1737e73439d8SMarcel Holtmann 
173804837f64SMarcel Holtmann 	hci_dev_unlock(hdev);
173904837f64SMarcel Holtmann }
174004837f64SMarcel Holtmann 
1741a9de9248SMarcel Holtmann static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1742a9de9248SMarcel Holtmann {
1743a9de9248SMarcel Holtmann 	struct hci_cp_exit_sniff_mode *cp;
174404837f64SMarcel Holtmann 	struct hci_conn *conn;
174504837f64SMarcel Holtmann 
17469f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1747a9de9248SMarcel Holtmann 
1748a9de9248SMarcel Holtmann 	if (!status)
1749a9de9248SMarcel Holtmann 		return;
1750a9de9248SMarcel Holtmann 
1751a9de9248SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
175204837f64SMarcel Holtmann 	if (!cp)
1753a9de9248SMarcel Holtmann 		return;
175404837f64SMarcel Holtmann 
175504837f64SMarcel Holtmann 	hci_dev_lock(hdev);
175604837f64SMarcel Holtmann 
175704837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1758e73439d8SMarcel Holtmann 	if (conn) {
175951a8efd7SJohan Hedberg 		clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
176004837f64SMarcel Holtmann 
176151a8efd7SJohan Hedberg 		if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
1762e73439d8SMarcel Holtmann 			hci_sco_setup(conn, status);
1763e73439d8SMarcel Holtmann 	}
1764e73439d8SMarcel Holtmann 
176504837f64SMarcel Holtmann 	hci_dev_unlock(hdev);
176604837f64SMarcel Holtmann }
176704837f64SMarcel Holtmann 
176888c3df13SJohan Hedberg static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
176988c3df13SJohan Hedberg {
177088c3df13SJohan Hedberg 	struct hci_cp_disconnect *cp;
177188c3df13SJohan Hedberg 	struct hci_conn *conn;
177288c3df13SJohan Hedberg 
177388c3df13SJohan Hedberg 	if (!status)
177488c3df13SJohan Hedberg 		return;
177588c3df13SJohan Hedberg 
177688c3df13SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
177788c3df13SJohan Hedberg 	if (!cp)
177888c3df13SJohan Hedberg 		return;
177988c3df13SJohan Hedberg 
178088c3df13SJohan Hedberg 	hci_dev_lock(hdev);
178188c3df13SJohan Hedberg 
178288c3df13SJohan Hedberg 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
178388c3df13SJohan Hedberg 	if (conn)
178488c3df13SJohan Hedberg 		mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
178588c3df13SJohan Hedberg 				       conn->dst_type, status);
178688c3df13SJohan Hedberg 
178788c3df13SJohan Hedberg 	hci_dev_unlock(hdev);
178888c3df13SJohan Hedberg }
178988c3df13SJohan Hedberg 
1790a02226d6SAndrei Emeltchenko static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1791a02226d6SAndrei Emeltchenko {
179293c284eeSAndrei Emeltchenko 	struct hci_cp_create_phy_link *cp;
179393c284eeSAndrei Emeltchenko 
1794a02226d6SAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
179593c284eeSAndrei Emeltchenko 
179693c284eeSAndrei Emeltchenko 	cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
179793c284eeSAndrei Emeltchenko 	if (!cp)
179893c284eeSAndrei Emeltchenko 		return;
179993c284eeSAndrei Emeltchenko 
1800e58917b9SAndrei Emeltchenko 	hci_dev_lock(hdev);
1801e58917b9SAndrei Emeltchenko 
1802e58917b9SAndrei Emeltchenko 	if (status) {
1803e58917b9SAndrei Emeltchenko 		struct hci_conn *hcon;
1804e58917b9SAndrei Emeltchenko 
1805e58917b9SAndrei Emeltchenko 		hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1806e58917b9SAndrei Emeltchenko 		if (hcon)
1807e58917b9SAndrei Emeltchenko 			hci_conn_del(hcon);
1808e58917b9SAndrei Emeltchenko 	} else {
180993c284eeSAndrei Emeltchenko 		amp_write_remote_assoc(hdev, cp->phy_handle);
1810a02226d6SAndrei Emeltchenko 	}
1811a02226d6SAndrei Emeltchenko 
1812e58917b9SAndrei Emeltchenko 	hci_dev_unlock(hdev);
1813e58917b9SAndrei Emeltchenko }
1814e58917b9SAndrei Emeltchenko 
18150b26ab9dSAndrei Emeltchenko static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
18160b26ab9dSAndrei Emeltchenko {
18170b26ab9dSAndrei Emeltchenko 	struct hci_cp_accept_phy_link *cp;
18180b26ab9dSAndrei Emeltchenko 
18190b26ab9dSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
18200b26ab9dSAndrei Emeltchenko 
18210b26ab9dSAndrei Emeltchenko 	if (status)
18220b26ab9dSAndrei Emeltchenko 		return;
18230b26ab9dSAndrei Emeltchenko 
18240b26ab9dSAndrei Emeltchenko 	cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
18250b26ab9dSAndrei Emeltchenko 	if (!cp)
18260b26ab9dSAndrei Emeltchenko 		return;
18270b26ab9dSAndrei Emeltchenko 
18280b26ab9dSAndrei Emeltchenko 	amp_write_remote_assoc(hdev, cp->phy_handle);
18290b26ab9dSAndrei Emeltchenko }
18300b26ab9dSAndrei Emeltchenko 
1831cb1d68f7SJohan Hedberg static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status)
1832cb1d68f7SJohan Hedberg {
1833cb1d68f7SJohan Hedberg 	struct hci_cp_le_create_conn *cp;
1834cb1d68f7SJohan Hedberg 	struct hci_conn *conn;
1835cb1d68f7SJohan Hedberg 
1836cb1d68f7SJohan Hedberg 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
1837cb1d68f7SJohan Hedberg 
1838cb1d68f7SJohan Hedberg 	/* All connection failure handling is taken care of by the
1839cb1d68f7SJohan Hedberg 	 * hci_le_conn_failed function which is triggered by the HCI
1840cb1d68f7SJohan Hedberg 	 * request completion callbacks used for connecting.
1841cb1d68f7SJohan Hedberg 	 */
1842cb1d68f7SJohan Hedberg 	if (status)
1843cb1d68f7SJohan Hedberg 		return;
1844cb1d68f7SJohan Hedberg 
1845cb1d68f7SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1846cb1d68f7SJohan Hedberg 	if (!cp)
1847cb1d68f7SJohan Hedberg 		return;
1848cb1d68f7SJohan Hedberg 
1849cb1d68f7SJohan Hedberg 	hci_dev_lock(hdev);
1850cb1d68f7SJohan Hedberg 
1851cb1d68f7SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1852cb1d68f7SJohan Hedberg 	if (!conn)
1853cb1d68f7SJohan Hedberg 		goto unlock;
1854cb1d68f7SJohan Hedberg 
1855cb1d68f7SJohan Hedberg 	/* Store the initiator and responder address information which
1856cb1d68f7SJohan Hedberg 	 * is needed for SMP. These values will not change during the
1857cb1d68f7SJohan Hedberg 	 * lifetime of the connection.
1858cb1d68f7SJohan Hedberg 	 */
1859cb1d68f7SJohan Hedberg 	conn->init_addr_type = cp->own_address_type;
1860cb1d68f7SJohan Hedberg 	if (cp->own_address_type == ADDR_LE_DEV_RANDOM)
1861cb1d68f7SJohan Hedberg 		bacpy(&conn->init_addr, &hdev->random_addr);
1862cb1d68f7SJohan Hedberg 	else
1863cb1d68f7SJohan Hedberg 		bacpy(&conn->init_addr, &hdev->bdaddr);
1864cb1d68f7SJohan Hedberg 
1865cb1d68f7SJohan Hedberg 	conn->resp_addr_type = cp->peer_addr_type;
1866cb1d68f7SJohan Hedberg 	bacpy(&conn->resp_addr, &cp->peer_addr);
1867cb1d68f7SJohan Hedberg 
18689489eca4SJohan Hedberg 	/* We don't want the connection attempt to stick around
18699489eca4SJohan Hedberg 	 * indefinitely since LE doesn't have a page timeout concept
18709489eca4SJohan Hedberg 	 * like BR/EDR. Set a timer for any connection that doesn't use
18719489eca4SJohan Hedberg 	 * the white list for connecting.
18729489eca4SJohan Hedberg 	 */
18739489eca4SJohan Hedberg 	if (cp->filter_policy == HCI_LE_USE_PEER_ADDR)
18749489eca4SJohan Hedberg 		queue_delayed_work(conn->hdev->workqueue,
18759489eca4SJohan Hedberg 				   &conn->le_conn_timeout,
18769489eca4SJohan Hedberg 				   HCI_LE_CONN_TIMEOUT);
18779489eca4SJohan Hedberg 
1878cb1d68f7SJohan Hedberg unlock:
1879cb1d68f7SJohan Hedberg 	hci_dev_unlock(hdev);
1880cb1d68f7SJohan Hedberg }
1881cb1d68f7SJohan Hedberg 
188281d0c8adSJohan Hedberg static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
188381d0c8adSJohan Hedberg {
188481d0c8adSJohan Hedberg 	struct hci_cp_le_start_enc *cp;
188581d0c8adSJohan Hedberg 	struct hci_conn *conn;
188681d0c8adSJohan Hedberg 
188781d0c8adSJohan Hedberg 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
188881d0c8adSJohan Hedberg 
188981d0c8adSJohan Hedberg 	if (!status)
189081d0c8adSJohan Hedberg 		return;
189181d0c8adSJohan Hedberg 
189281d0c8adSJohan Hedberg 	hci_dev_lock(hdev);
189381d0c8adSJohan Hedberg 
189481d0c8adSJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_START_ENC);
189581d0c8adSJohan Hedberg 	if (!cp)
189681d0c8adSJohan Hedberg 		goto unlock;
189781d0c8adSJohan Hedberg 
189881d0c8adSJohan Hedberg 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
189981d0c8adSJohan Hedberg 	if (!conn)
190081d0c8adSJohan Hedberg 		goto unlock;
190181d0c8adSJohan Hedberg 
190281d0c8adSJohan Hedberg 	if (conn->state != BT_CONNECTED)
190381d0c8adSJohan Hedberg 		goto unlock;
190481d0c8adSJohan Hedberg 
190581d0c8adSJohan Hedberg 	hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
190681d0c8adSJohan Hedberg 	hci_conn_drop(conn);
190781d0c8adSJohan Hedberg 
190881d0c8adSJohan Hedberg unlock:
190981d0c8adSJohan Hedberg 	hci_dev_unlock(hdev);
191081d0c8adSJohan Hedberg }
191181d0c8adSJohan Hedberg 
19126039aa73SGustavo Padovan static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
19131da177e4SLinus Torvalds {
19141da177e4SLinus Torvalds 	__u8 status = *((__u8 *) skb->data);
191530dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
191630dc78e1SJohan Hedberg 	struct inquiry_entry *e;
19171da177e4SLinus Torvalds 
19189f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, status);
19191da177e4SLinus Torvalds 
1920a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
192189352e7dSAndre Guedes 
192289352e7dSAndre Guedes 	if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
192389352e7dSAndre Guedes 		return;
192489352e7dSAndre Guedes 
19254e857c58SPeter Zijlstra 	smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */
19263e13fa1eSAndre Guedes 	wake_up_bit(&hdev->flags, HCI_INQUIRY);
19273e13fa1eSAndre Guedes 
1928a8b2d5c2SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
192930dc78e1SJohan Hedberg 		return;
193030dc78e1SJohan Hedberg 
193156e5cb86SJohan Hedberg 	hci_dev_lock(hdev);
193230dc78e1SJohan Hedberg 
1933343f935bSAndre Guedes 	if (discov->state != DISCOVERY_FINDING)
193430dc78e1SJohan Hedberg 		goto unlock;
193530dc78e1SJohan Hedberg 
193630dc78e1SJohan Hedberg 	if (list_empty(&discov->resolve)) {
1937ff9ef578SJohan Hedberg 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
193830dc78e1SJohan Hedberg 		goto unlock;
193930dc78e1SJohan Hedberg 	}
194030dc78e1SJohan Hedberg 
194130dc78e1SJohan Hedberg 	e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
194230dc78e1SJohan Hedberg 	if (e && hci_resolve_name(hdev, e) == 0) {
194330dc78e1SJohan Hedberg 		e->name_state = NAME_PENDING;
194430dc78e1SJohan Hedberg 		hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
194530dc78e1SJohan Hedberg 	} else {
194630dc78e1SJohan Hedberg 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
194730dc78e1SJohan Hedberg 	}
194830dc78e1SJohan Hedberg 
194930dc78e1SJohan Hedberg unlock:
195056e5cb86SJohan Hedberg 	hci_dev_unlock(hdev);
19511da177e4SLinus Torvalds }
19521da177e4SLinus Torvalds 
19536039aa73SGustavo Padovan static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
19541da177e4SLinus Torvalds {
195545bb4bf0SMarcel Holtmann 	struct inquiry_data data;
1956a9de9248SMarcel Holtmann 	struct inquiry_info *info = (void *) (skb->data + 1);
19571da177e4SLinus Torvalds 	int num_rsp = *((__u8 *) skb->data);
19581da177e4SLinus Torvalds 
19591da177e4SLinus Torvalds 	BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
19601da177e4SLinus Torvalds 
196145bb4bf0SMarcel Holtmann 	if (!num_rsp)
196245bb4bf0SMarcel Holtmann 		return;
196345bb4bf0SMarcel Holtmann 
19641519cc17SAndre Guedes 	if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
19651519cc17SAndre Guedes 		return;
19661519cc17SAndre Guedes 
19671da177e4SLinus Torvalds 	hci_dev_lock(hdev);
196845bb4bf0SMarcel Holtmann 
1969e17acd40SJohan Hedberg 	for (; num_rsp; num_rsp--, info++) {
1970af58925cSMarcel Holtmann 		u32 flags;
19713175405bSJohan Hedberg 
19721da177e4SLinus Torvalds 		bacpy(&data.bdaddr, &info->bdaddr);
19731da177e4SLinus Torvalds 		data.pscan_rep_mode	= info->pscan_rep_mode;
19741da177e4SLinus Torvalds 		data.pscan_period_mode	= info->pscan_period_mode;
19751da177e4SLinus Torvalds 		data.pscan_mode		= info->pscan_mode;
19761da177e4SLinus Torvalds 		memcpy(data.dev_class, info->dev_class, 3);
19771da177e4SLinus Torvalds 		data.clock_offset	= info->clock_offset;
19781da177e4SLinus Torvalds 		data.rssi		= 0x00;
197941a96212SMarcel Holtmann 		data.ssp_mode		= 0x00;
19803175405bSJohan Hedberg 
1981af58925cSMarcel Holtmann 		flags = hci_inquiry_cache_update(hdev, &data, false);
1982af58925cSMarcel Holtmann 
198348264f06SJohan Hedberg 		mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
1984af58925cSMarcel Holtmann 				  info->dev_class, 0, flags, NULL, 0, NULL, 0);
19851da177e4SLinus Torvalds 	}
198645bb4bf0SMarcel Holtmann 
19871da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
19881da177e4SLinus Torvalds }
19891da177e4SLinus Torvalds 
19906039aa73SGustavo Padovan static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
19911da177e4SLinus Torvalds {
1992a9de9248SMarcel Holtmann 	struct hci_ev_conn_complete *ev = (void *) skb->data;
1993a9de9248SMarcel Holtmann 	struct hci_conn *conn;
19941da177e4SLinus Torvalds 
1995a9de9248SMarcel Holtmann 	BT_DBG("%s", hdev->name);
199645bb4bf0SMarcel Holtmann 
19971da177e4SLinus Torvalds 	hci_dev_lock(hdev);
199845bb4bf0SMarcel Holtmann 
1999a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
20009499237aSMarcel Holtmann 	if (!conn) {
20019499237aSMarcel Holtmann 		if (ev->link_type != SCO_LINK)
20029499237aSMarcel Holtmann 			goto unlock;
20039499237aSMarcel Holtmann 
20049499237aSMarcel Holtmann 		conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2005a9de9248SMarcel Holtmann 		if (!conn)
2006a9de9248SMarcel Holtmann 			goto unlock;
200745bb4bf0SMarcel Holtmann 
20089499237aSMarcel Holtmann 		conn->type = SCO_LINK;
20099499237aSMarcel Holtmann 	}
20109499237aSMarcel Holtmann 
2011a9de9248SMarcel Holtmann 	if (!ev->status) {
2012a9de9248SMarcel Holtmann 		conn->handle = __le16_to_cpu(ev->handle);
2013769be974SMarcel Holtmann 
2014769be974SMarcel Holtmann 		if (conn->type == ACL_LINK) {
2015769be974SMarcel Holtmann 			conn->state = BT_CONFIG;
2016769be974SMarcel Holtmann 			hci_conn_hold(conn);
2017a9ea3ed9SSzymon Janc 
2018a9ea3ed9SSzymon Janc 			if (!conn->out && !hci_conn_ssp_enabled(conn) &&
2019a9ea3ed9SSzymon Janc 			    !hci_find_link_key(hdev, &ev->bdaddr))
2020a9ea3ed9SSzymon Janc 				conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2021a9ea3ed9SSzymon Janc 			else
2022052b30b0SMarcel Holtmann 				conn->disc_timeout = HCI_DISCONN_TIMEOUT;
2023769be974SMarcel Holtmann 		} else
2024a9de9248SMarcel Holtmann 			conn->state = BT_CONNECTED;
2025a9de9248SMarcel Holtmann 
20267d0db0a3SMarcel Holtmann 		hci_conn_add_sysfs(conn);
20277d0db0a3SMarcel Holtmann 
2028a9de9248SMarcel Holtmann 		if (test_bit(HCI_AUTH, &hdev->flags))
20294dae2798SJohan Hedberg 			set_bit(HCI_CONN_AUTH, &conn->flags);
2030a9de9248SMarcel Holtmann 
2031a9de9248SMarcel Holtmann 		if (test_bit(HCI_ENCRYPT, &hdev->flags))
20324dae2798SJohan Hedberg 			set_bit(HCI_CONN_ENCRYPT, &conn->flags);
2033a9de9248SMarcel Holtmann 
2034a9de9248SMarcel Holtmann 		/* Get remote features */
2035a9de9248SMarcel Holtmann 		if (conn->type == ACL_LINK) {
2036a9de9248SMarcel Holtmann 			struct hci_cp_read_remote_features cp;
2037a9de9248SMarcel Holtmann 			cp.handle = ev->handle;
2038769be974SMarcel Holtmann 			hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
2039769be974SMarcel Holtmann 				     sizeof(cp), &cp);
204045bb4bf0SMarcel Holtmann 		}
2041a9de9248SMarcel Holtmann 
2042a9de9248SMarcel Holtmann 		/* Set packet type for incoming connection */
2043d095c1ebSAndrei Emeltchenko 		if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
2044a9de9248SMarcel Holtmann 			struct hci_cp_change_conn_ptype cp;
2045a9de9248SMarcel Holtmann 			cp.handle = ev->handle;
2046a8746417SMarcel Holtmann 			cp.pkt_type = cpu_to_le16(conn->pkt_type);
204704124681SGustavo F. Padovan 			hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
204804124681SGustavo F. Padovan 				     &cp);
2049a9de9248SMarcel Holtmann 		}
205017d5c04cSJohan Hedberg 	} else {
2051a9de9248SMarcel Holtmann 		conn->state = BT_CLOSED;
205217d5c04cSJohan Hedberg 		if (conn->type == ACL_LINK)
205364c7b77cSMarcel Holtmann 			mgmt_connect_failed(hdev, &conn->dst, conn->type,
205448264f06SJohan Hedberg 					    conn->dst_type, ev->status);
205517d5c04cSJohan Hedberg 	}
205645bb4bf0SMarcel Holtmann 
2057e73439d8SMarcel Holtmann 	if (conn->type == ACL_LINK)
2058e73439d8SMarcel Holtmann 		hci_sco_setup(conn, ev->status);
205945bb4bf0SMarcel Holtmann 
2060769be974SMarcel Holtmann 	if (ev->status) {
2061a9de9248SMarcel Holtmann 		hci_proto_connect_cfm(conn, ev->status);
2062a9de9248SMarcel Holtmann 		hci_conn_del(conn);
2063c89b6e6bSMarcel Holtmann 	} else if (ev->link_type != ACL_LINK)
2064c89b6e6bSMarcel Holtmann 		hci_proto_connect_cfm(conn, ev->status);
2065a9de9248SMarcel Holtmann 
2066a9de9248SMarcel Holtmann unlock:
20671da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
2068a9de9248SMarcel Holtmann 
2069a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
20701da177e4SLinus Torvalds }
20711da177e4SLinus Torvalds 
20726039aa73SGustavo Padovan static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
20731da177e4SLinus Torvalds {
2074a9de9248SMarcel Holtmann 	struct hci_ev_conn_request *ev = (void *) skb->data;
20751da177e4SLinus Torvalds 	int mask = hdev->link_mode;
207620714bfeSFrédéric Dalleau 	__u8 flags = 0;
20771da177e4SLinus Torvalds 
20786ed93dc6SAndrei Emeltchenko 	BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
2079807deac2SGustavo Padovan 	       ev->link_type);
20801da177e4SLinus Torvalds 
208120714bfeSFrédéric Dalleau 	mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
208220714bfeSFrédéric Dalleau 				      &flags);
20831da177e4SLinus Torvalds 
2084138d22efSSzymon Janc 	if ((mask & HCI_LM_ACCEPT) &&
2085b9ee0a78SMarcel Holtmann 	    !hci_blacklist_lookup(hdev, &ev->bdaddr, BDADDR_BREDR)) {
20861da177e4SLinus Torvalds 		/* Connection accepted */
2087c7bdd502SMarcel Holtmann 		struct inquiry_entry *ie;
20881da177e4SLinus Torvalds 		struct hci_conn *conn;
20891da177e4SLinus Torvalds 
20901da177e4SLinus Torvalds 		hci_dev_lock(hdev);
2091b6a0dc82SMarcel Holtmann 
2092cc11b9c1SAndrei Emeltchenko 		ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2093cc11b9c1SAndrei Emeltchenko 		if (ie)
2094c7bdd502SMarcel Holtmann 			memcpy(ie->data.dev_class, ev->dev_class, 3);
2095c7bdd502SMarcel Holtmann 
20968fc9ced3SGustavo Padovan 		conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
20978fc9ced3SGustavo Padovan 					       &ev->bdaddr);
20981da177e4SLinus Torvalds 		if (!conn) {
2099cc11b9c1SAndrei Emeltchenko 			conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
2100cc11b9c1SAndrei Emeltchenko 			if (!conn) {
2101893ef971SGustavo F. Padovan 				BT_ERR("No memory for new connection");
21021da177e4SLinus Torvalds 				hci_dev_unlock(hdev);
21031da177e4SLinus Torvalds 				return;
21041da177e4SLinus Torvalds 			}
21051da177e4SLinus Torvalds 		}
2106b6a0dc82SMarcel Holtmann 
21071da177e4SLinus Torvalds 		memcpy(conn->dev_class, ev->dev_class, 3);
2108b6a0dc82SMarcel Holtmann 
21091da177e4SLinus Torvalds 		hci_dev_unlock(hdev);
21101da177e4SLinus Torvalds 
211120714bfeSFrédéric Dalleau 		if (ev->link_type == ACL_LINK ||
211220714bfeSFrédéric Dalleau 		    (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
2113b6a0dc82SMarcel Holtmann 			struct hci_cp_accept_conn_req cp;
211420714bfeSFrédéric Dalleau 			conn->state = BT_CONNECT;
2115b6a0dc82SMarcel Holtmann 
21161da177e4SLinus Torvalds 			bacpy(&cp.bdaddr, &ev->bdaddr);
21171da177e4SLinus Torvalds 
21181da177e4SLinus Torvalds 			if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
21191da177e4SLinus Torvalds 				cp.role = 0x00; /* Become master */
21201da177e4SLinus Torvalds 			else
21211da177e4SLinus Torvalds 				cp.role = 0x01; /* Remain slave */
21221da177e4SLinus Torvalds 
212304124681SGustavo F. Padovan 			hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
212404124681SGustavo F. Padovan 				     &cp);
212520714bfeSFrédéric Dalleau 		} else if (!(flags & HCI_PROTO_DEFER)) {
2126b6a0dc82SMarcel Holtmann 			struct hci_cp_accept_sync_conn_req cp;
212720714bfeSFrédéric Dalleau 			conn->state = BT_CONNECT;
2128b6a0dc82SMarcel Holtmann 
2129b6a0dc82SMarcel Holtmann 			bacpy(&cp.bdaddr, &ev->bdaddr);
2130a8746417SMarcel Holtmann 			cp.pkt_type = cpu_to_le16(conn->pkt_type);
2131b6a0dc82SMarcel Holtmann 
2132dcf4adbfSJoe Perches 			cp.tx_bandwidth   = cpu_to_le32(0x00001f40);
2133dcf4adbfSJoe Perches 			cp.rx_bandwidth   = cpu_to_le32(0x00001f40);
2134dcf4adbfSJoe Perches 			cp.max_latency    = cpu_to_le16(0xffff);
2135b6a0dc82SMarcel Holtmann 			cp.content_format = cpu_to_le16(hdev->voice_setting);
2136b6a0dc82SMarcel Holtmann 			cp.retrans_effort = 0xff;
2137b6a0dc82SMarcel Holtmann 
2138b6a0dc82SMarcel Holtmann 			hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
2139b6a0dc82SMarcel Holtmann 				     sizeof(cp), &cp);
214020714bfeSFrédéric Dalleau 		} else {
214120714bfeSFrédéric Dalleau 			conn->state = BT_CONNECT2;
214220714bfeSFrédéric Dalleau 			hci_proto_connect_cfm(conn, 0);
2143b6a0dc82SMarcel Holtmann 		}
21441da177e4SLinus Torvalds 	} else {
21451da177e4SLinus Torvalds 		/* Connection rejected */
21461da177e4SLinus Torvalds 		struct hci_cp_reject_conn_req cp;
21471da177e4SLinus Torvalds 
21481da177e4SLinus Torvalds 		bacpy(&cp.bdaddr, &ev->bdaddr);
21499f5a0d7bSAndrei Emeltchenko 		cp.reason = HCI_ERROR_REJ_BAD_ADDR;
2150a9de9248SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
21511da177e4SLinus Torvalds 	}
21521da177e4SLinus Torvalds }
21531da177e4SLinus Torvalds 
2154f0d6a0eaSMikel Astiz static u8 hci_to_mgmt_reason(u8 err)
2155f0d6a0eaSMikel Astiz {
2156f0d6a0eaSMikel Astiz 	switch (err) {
2157f0d6a0eaSMikel Astiz 	case HCI_ERROR_CONNECTION_TIMEOUT:
2158f0d6a0eaSMikel Astiz 		return MGMT_DEV_DISCONN_TIMEOUT;
2159f0d6a0eaSMikel Astiz 	case HCI_ERROR_REMOTE_USER_TERM:
2160f0d6a0eaSMikel Astiz 	case HCI_ERROR_REMOTE_LOW_RESOURCES:
2161f0d6a0eaSMikel Astiz 	case HCI_ERROR_REMOTE_POWER_OFF:
2162f0d6a0eaSMikel Astiz 		return MGMT_DEV_DISCONN_REMOTE;
2163f0d6a0eaSMikel Astiz 	case HCI_ERROR_LOCAL_HOST_TERM:
2164f0d6a0eaSMikel Astiz 		return MGMT_DEV_DISCONN_LOCAL_HOST;
2165f0d6a0eaSMikel Astiz 	default:
2166f0d6a0eaSMikel Astiz 		return MGMT_DEV_DISCONN_UNKNOWN;
2167f0d6a0eaSMikel Astiz 	}
2168f0d6a0eaSMikel Astiz }
2169f0d6a0eaSMikel Astiz 
21706039aa73SGustavo Padovan static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
21711da177e4SLinus Torvalds {
2172a9de9248SMarcel Holtmann 	struct hci_ev_disconn_complete *ev = (void *) skb->data;
2173abf54a50SAndre Guedes 	u8 reason = hci_to_mgmt_reason(ev->reason);
21749fcb18efSAndre Guedes 	struct hci_conn_params *params;
217504837f64SMarcel Holtmann 	struct hci_conn *conn;
217612d4a3b2SJohan Hedberg 	bool mgmt_connected;
21773846220bSAndre Guedes 	u8 type;
21781da177e4SLinus Torvalds 
21799f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
21801da177e4SLinus Torvalds 
21811da177e4SLinus Torvalds 	hci_dev_lock(hdev);
21821da177e4SLinus Torvalds 
218304837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2184f7520543SJohan Hedberg 	if (!conn)
2185f7520543SJohan Hedberg 		goto unlock;
2186f7520543SJohan Hedberg 
2187f0d6a0eaSMikel Astiz 	if (ev->status) {
218888c3df13SJohan Hedberg 		mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
218988c3df13SJohan Hedberg 				       conn->dst_type, ev->status);
2190abf54a50SAndre Guedes 		goto unlock;
2191abf54a50SAndre Guedes 	}
2192f0d6a0eaSMikel Astiz 
21933846220bSAndre Guedes 	conn->state = BT_CLOSED;
21943846220bSAndre Guedes 
219512d4a3b2SJohan Hedberg 	mgmt_connected = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
219612d4a3b2SJohan Hedberg 	mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type,
219712d4a3b2SJohan Hedberg 				reason, mgmt_connected);
2198f7520543SJohan Hedberg 
2199af6a9c32SJohan Hedberg 	if (conn->type == ACL_LINK &&
2200af6a9c32SJohan Hedberg 	    test_bit(HCI_CONN_FLUSH_KEY, &conn->flags))
22016ec5bcadSVishal Agarwal 		hci_remove_link_key(hdev, &conn->dst);
22023846220bSAndre Guedes 
22039fcb18efSAndre Guedes 	params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
22049fcb18efSAndre Guedes 	if (params) {
22059fcb18efSAndre Guedes 		switch (params->auto_connect) {
22069fcb18efSAndre Guedes 		case HCI_AUTO_CONN_LINK_LOSS:
22079fcb18efSAndre Guedes 			if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT)
22089fcb18efSAndre Guedes 				break;
22099fcb18efSAndre Guedes 			/* Fall through */
22109fcb18efSAndre Guedes 
22119fcb18efSAndre Guedes 		case HCI_AUTO_CONN_ALWAYS:
22129fcb18efSAndre Guedes 			hci_pend_le_conn_add(hdev, &conn->dst, conn->dst_type);
22139fcb18efSAndre Guedes 			break;
22149fcb18efSAndre Guedes 
22159fcb18efSAndre Guedes 		default:
22169fcb18efSAndre Guedes 			break;
22179fcb18efSAndre Guedes 		}
22189fcb18efSAndre Guedes 	}
22199fcb18efSAndre Guedes 
22203846220bSAndre Guedes 	type = conn->type;
22213846220bSAndre Guedes 
22222950f21aSMarcel Holtmann 	hci_proto_disconn_cfm(conn, ev->reason);
22231da177e4SLinus Torvalds 	hci_conn_del(conn);
22242210246cSJohan Hedberg 
22252210246cSJohan Hedberg 	/* Re-enable advertising if necessary, since it might
22262210246cSJohan Hedberg 	 * have been disabled by the connection. From the
22272210246cSJohan Hedberg 	 * HCI_LE_Set_Advertise_Enable command description in
22282210246cSJohan Hedberg 	 * the core specification (v4.0):
22292210246cSJohan Hedberg 	 * "The Controller shall continue advertising until the Host
22302210246cSJohan Hedberg 	 * issues an LE_Set_Advertise_Enable command with
22312210246cSJohan Hedberg 	 * Advertising_Enable set to 0x00 (Advertising is disabled)
22322210246cSJohan Hedberg 	 * or until a connection is created or until the Advertising
22332210246cSJohan Hedberg 	 * is timed out due to Directed Advertising."
22342210246cSJohan Hedberg 	 */
22352210246cSJohan Hedberg 	if (type == LE_LINK)
22365976e608SMarcel Holtmann 		mgmt_reenable_advertising(hdev);
22371da177e4SLinus Torvalds 
2238f7520543SJohan Hedberg unlock:
22391da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
22401da177e4SLinus Torvalds }
22411da177e4SLinus Torvalds 
22426039aa73SGustavo Padovan static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2243a9de9248SMarcel Holtmann {
2244a9de9248SMarcel Holtmann 	struct hci_ev_auth_complete *ev = (void *) skb->data;
2245a9de9248SMarcel Holtmann 	struct hci_conn *conn;
2246a9de9248SMarcel Holtmann 
22479f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
2248a9de9248SMarcel Holtmann 
2249a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
2250a9de9248SMarcel Holtmann 
2251a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2252d7556e20SWaldemar Rymarkiewicz 	if (!conn)
2253d7556e20SWaldemar Rymarkiewicz 		goto unlock;
2254d7556e20SWaldemar Rymarkiewicz 
2255765c2a96SJohan Hedberg 	if (!ev->status) {
2256aa64a8b5SJohan Hedberg 		if (!hci_conn_ssp_enabled(conn) &&
225751a8efd7SJohan Hedberg 		    test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
2258d7556e20SWaldemar Rymarkiewicz 			BT_INFO("re-auth of legacy device is not possible.");
225919f8def0SWaldemar Rymarkiewicz 		} else {
22604dae2798SJohan Hedberg 			set_bit(HCI_CONN_AUTH, &conn->flags);
2261765c2a96SJohan Hedberg 			conn->sec_level = conn->pending_sec_level;
226219f8def0SWaldemar Rymarkiewicz 		}
22632a611692SJohan Hedberg 	} else {
2264bab73cb6SJohan Hedberg 		mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
2265bab73cb6SJohan Hedberg 				 ev->status);
22662a611692SJohan Hedberg 	}
2267a9de9248SMarcel Holtmann 
226851a8efd7SJohan Hedberg 	clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
226951a8efd7SJohan Hedberg 	clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
2270a9de9248SMarcel Holtmann 
2271f8558555SMarcel Holtmann 	if (conn->state == BT_CONFIG) {
2272aa64a8b5SJohan Hedberg 		if (!ev->status && hci_conn_ssp_enabled(conn)) {
2273f8558555SMarcel Holtmann 			struct hci_cp_set_conn_encrypt cp;
2274f8558555SMarcel Holtmann 			cp.handle  = ev->handle;
2275f8558555SMarcel Holtmann 			cp.encrypt = 0x01;
2276d7556e20SWaldemar Rymarkiewicz 			hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
2277d7556e20SWaldemar Rymarkiewicz 				     &cp);
2278f8558555SMarcel Holtmann 		} else {
2279f8558555SMarcel Holtmann 			conn->state = BT_CONNECTED;
2280f8558555SMarcel Holtmann 			hci_proto_connect_cfm(conn, ev->status);
228176a68ba0SDavid Herrmann 			hci_conn_drop(conn);
2282f8558555SMarcel Holtmann 		}
2283052b30b0SMarcel Holtmann 	} else {
2284a9de9248SMarcel Holtmann 		hci_auth_cfm(conn, ev->status);
2285a9de9248SMarcel Holtmann 
2286052b30b0SMarcel Holtmann 		hci_conn_hold(conn);
2287052b30b0SMarcel Holtmann 		conn->disc_timeout = HCI_DISCONN_TIMEOUT;
228876a68ba0SDavid Herrmann 		hci_conn_drop(conn);
2289052b30b0SMarcel Holtmann 	}
2290052b30b0SMarcel Holtmann 
229151a8efd7SJohan Hedberg 	if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
2292a9de9248SMarcel Holtmann 		if (!ev->status) {
2293a9de9248SMarcel Holtmann 			struct hci_cp_set_conn_encrypt cp;
2294f8558555SMarcel Holtmann 			cp.handle  = ev->handle;
2295f8558555SMarcel Holtmann 			cp.encrypt = 0x01;
2296d7556e20SWaldemar Rymarkiewicz 			hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
2297d7556e20SWaldemar Rymarkiewicz 				     &cp);
2298a9de9248SMarcel Holtmann 		} else {
229951a8efd7SJohan Hedberg 			clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
2300a9de9248SMarcel Holtmann 			hci_encrypt_cfm(conn, ev->status, 0x00);
2301a9de9248SMarcel Holtmann 		}
2302a9de9248SMarcel Holtmann 	}
2303a9de9248SMarcel Holtmann 
2304d7556e20SWaldemar Rymarkiewicz unlock:
2305a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
2306a9de9248SMarcel Holtmann }
2307a9de9248SMarcel Holtmann 
23086039aa73SGustavo Padovan static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
2309a9de9248SMarcel Holtmann {
2310127178d2SJohan Hedberg 	struct hci_ev_remote_name *ev = (void *) skb->data;
2311127178d2SJohan Hedberg 	struct hci_conn *conn;
2312127178d2SJohan Hedberg 
2313a9de9248SMarcel Holtmann 	BT_DBG("%s", hdev->name);
2314a9de9248SMarcel Holtmann 
2315a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
2316127178d2SJohan Hedberg 
2317127178d2SJohan Hedberg 	hci_dev_lock(hdev);
2318127178d2SJohan Hedberg 
2319127178d2SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2320b644ba33SJohan Hedberg 
2321b644ba33SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2322b644ba33SJohan Hedberg 		goto check_auth;
2323b644ba33SJohan Hedberg 
2324b644ba33SJohan Hedberg 	if (ev->status == 0)
2325b644ba33SJohan Hedberg 		hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
2326b644ba33SJohan Hedberg 				       strnlen(ev->name, HCI_MAX_NAME_LENGTH));
2327b644ba33SJohan Hedberg 	else
2328b644ba33SJohan Hedberg 		hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
2329b644ba33SJohan Hedberg 
2330b644ba33SJohan Hedberg check_auth:
233179c6c70cSJohan Hedberg 	if (!conn)
233279c6c70cSJohan Hedberg 		goto unlock;
233379c6c70cSJohan Hedberg 
233479c6c70cSJohan Hedberg 	if (!hci_outgoing_auth_needed(hdev, conn))
233579c6c70cSJohan Hedberg 		goto unlock;
233679c6c70cSJohan Hedberg 
233751a8efd7SJohan Hedberg 	if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
2338127178d2SJohan Hedberg 		struct hci_cp_auth_requested cp;
2339127178d2SJohan Hedberg 		cp.handle = __cpu_to_le16(conn->handle);
2340127178d2SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
2341127178d2SJohan Hedberg 	}
2342127178d2SJohan Hedberg 
234379c6c70cSJohan Hedberg unlock:
2344127178d2SJohan Hedberg 	hci_dev_unlock(hdev);
2345a9de9248SMarcel Holtmann }
2346a9de9248SMarcel Holtmann 
23476039aa73SGustavo Padovan static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2348a9de9248SMarcel Holtmann {
2349a9de9248SMarcel Holtmann 	struct hci_ev_encrypt_change *ev = (void *) skb->data;
2350a9de9248SMarcel Holtmann 	struct hci_conn *conn;
2351a9de9248SMarcel Holtmann 
23529f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
2353a9de9248SMarcel Holtmann 
2354a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
2355a9de9248SMarcel Holtmann 
2356a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2357dc8357ccSMarcel Holtmann 	if (!conn)
2358dc8357ccSMarcel Holtmann 		goto unlock;
2359dc8357ccSMarcel Holtmann 
2360a9de9248SMarcel Holtmann 	if (!ev->status) {
2361ae293196SMarcel Holtmann 		if (ev->encrypt) {
2362ae293196SMarcel Holtmann 			/* Encryption implies authentication */
23634dae2798SJohan Hedberg 			set_bit(HCI_CONN_AUTH, &conn->flags);
23644dae2798SJohan Hedberg 			set_bit(HCI_CONN_ENCRYPT, &conn->flags);
2365da85e5e5SVinicius Costa Gomes 			conn->sec_level = conn->pending_sec_level;
2366abf76badSMarcel Holtmann 
2367914a6ffeSMarcel Holtmann 			/* P-256 authentication key implies FIPS */
2368914a6ffeSMarcel Holtmann 			if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256)
23694dae2798SJohan Hedberg 				set_bit(HCI_CONN_FIPS, &conn->flags);
2370914a6ffeSMarcel Holtmann 
2371abf76badSMarcel Holtmann 			if ((conn->type == ACL_LINK && ev->encrypt == 0x02) ||
2372abf76badSMarcel Holtmann 			    conn->type == LE_LINK)
2373abf76badSMarcel Holtmann 				set_bit(HCI_CONN_AES_CCM, &conn->flags);
2374abf76badSMarcel Holtmann 		} else {
23754dae2798SJohan Hedberg 			clear_bit(HCI_CONN_ENCRYPT, &conn->flags);
2376abf76badSMarcel Holtmann 			clear_bit(HCI_CONN_AES_CCM, &conn->flags);
2377abf76badSMarcel Holtmann 		}
2378a9de9248SMarcel Holtmann 	}
2379a9de9248SMarcel Holtmann 
238051a8efd7SJohan Hedberg 	clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
2381a9de9248SMarcel Holtmann 
2382a7d7723aSGustavo Padovan 	if (ev->status && conn->state == BT_CONNECTED) {
2383bed71748SAndre Guedes 		hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
238476a68ba0SDavid Herrmann 		hci_conn_drop(conn);
2385a7d7723aSGustavo Padovan 		goto unlock;
2386a7d7723aSGustavo Padovan 	}
2387a7d7723aSGustavo Padovan 
2388f8558555SMarcel Holtmann 	if (conn->state == BT_CONFIG) {
2389f8558555SMarcel Holtmann 		if (!ev->status)
2390f8558555SMarcel Holtmann 			conn->state = BT_CONNECTED;
2391f8558555SMarcel Holtmann 
239240b552aaSMarcel Holtmann 		/* In Secure Connections Only mode, do not allow any
239340b552aaSMarcel Holtmann 		 * connections that are not encrypted with AES-CCM
239440b552aaSMarcel Holtmann 		 * using a P-256 authenticated combination key.
239540b552aaSMarcel Holtmann 		 */
239640b552aaSMarcel Holtmann 		if (test_bit(HCI_SC_ONLY, &hdev->dev_flags) &&
239740b552aaSMarcel Holtmann 		    (!test_bit(HCI_CONN_AES_CCM, &conn->flags) ||
239840b552aaSMarcel Holtmann 		     conn->key_type != HCI_LK_AUTH_COMBINATION_P256)) {
239940b552aaSMarcel Holtmann 			hci_proto_connect_cfm(conn, HCI_ERROR_AUTH_FAILURE);
240040b552aaSMarcel Holtmann 			hci_conn_drop(conn);
240140b552aaSMarcel Holtmann 			goto unlock;
240240b552aaSMarcel Holtmann 		}
240340b552aaSMarcel Holtmann 
2404f8558555SMarcel Holtmann 		hci_proto_connect_cfm(conn, ev->status);
240576a68ba0SDavid Herrmann 		hci_conn_drop(conn);
2406f8558555SMarcel Holtmann 	} else
2407a9de9248SMarcel Holtmann 		hci_encrypt_cfm(conn, ev->status, ev->encrypt);
2408a9de9248SMarcel Holtmann 
2409a7d7723aSGustavo Padovan unlock:
2410a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
2411a9de9248SMarcel Holtmann }
2412a9de9248SMarcel Holtmann 
24136039aa73SGustavo Padovan static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
2414807deac2SGustavo Padovan 					     struct sk_buff *skb)
2415a9de9248SMarcel Holtmann {
2416a9de9248SMarcel Holtmann 	struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2417a9de9248SMarcel Holtmann 	struct hci_conn *conn;
2418a9de9248SMarcel Holtmann 
24199f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
2420a9de9248SMarcel Holtmann 
2421a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
2422a9de9248SMarcel Holtmann 
2423a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2424a9de9248SMarcel Holtmann 	if (conn) {
2425a9de9248SMarcel Holtmann 		if (!ev->status)
24264dae2798SJohan Hedberg 			set_bit(HCI_CONN_SECURE, &conn->flags);
2427a9de9248SMarcel Holtmann 
242851a8efd7SJohan Hedberg 		clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
2429a9de9248SMarcel Holtmann 
2430a9de9248SMarcel Holtmann 		hci_key_change_cfm(conn, ev->status);
2431a9de9248SMarcel Holtmann 	}
2432a9de9248SMarcel Holtmann 
2433a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
2434a9de9248SMarcel Holtmann }
2435a9de9248SMarcel Holtmann 
24366039aa73SGustavo Padovan static void hci_remote_features_evt(struct hci_dev *hdev,
2437807deac2SGustavo Padovan 				    struct sk_buff *skb)
2438a9de9248SMarcel Holtmann {
2439a9de9248SMarcel Holtmann 	struct hci_ev_remote_features *ev = (void *) skb->data;
2440a9de9248SMarcel Holtmann 	struct hci_conn *conn;
2441a9de9248SMarcel Holtmann 
24429f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
2443a9de9248SMarcel Holtmann 
2444a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
2445a9de9248SMarcel Holtmann 
2446a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2447ccd556feSJohan Hedberg 	if (!conn)
2448ccd556feSJohan Hedberg 		goto unlock;
2449ccd556feSJohan Hedberg 
2450769be974SMarcel Holtmann 	if (!ev->status)
2451cad718edSJohan Hedberg 		memcpy(conn->features[0], ev->features, 8);
2452a9de9248SMarcel Holtmann 
2453ccd556feSJohan Hedberg 	if (conn->state != BT_CONFIG)
2454ccd556feSJohan Hedberg 		goto unlock;
2455ccd556feSJohan Hedberg 
2456ccd556feSJohan Hedberg 	if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2457769be974SMarcel Holtmann 		struct hci_cp_read_remote_ext_features cp;
2458769be974SMarcel Holtmann 		cp.handle = ev->handle;
2459769be974SMarcel Holtmann 		cp.page = 0x01;
2460ccd556feSJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
2461769be974SMarcel Holtmann 			     sizeof(cp), &cp);
2462392599b9SJohan Hedberg 		goto unlock;
2463392599b9SJohan Hedberg 	}
2464392599b9SJohan Hedberg 
2465671267bfSJohan Hedberg 	if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
2466127178d2SJohan Hedberg 		struct hci_cp_remote_name_req cp;
2467127178d2SJohan Hedberg 		memset(&cp, 0, sizeof(cp));
2468127178d2SJohan Hedberg 		bacpy(&cp.bdaddr, &conn->dst);
2469127178d2SJohan Hedberg 		cp.pscan_rep_mode = 0x02;
2470127178d2SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
2471b644ba33SJohan Hedberg 	} else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2472b644ba33SJohan Hedberg 		mgmt_device_connected(hdev, &conn->dst, conn->type,
247308c79b61SJohan Hedberg 				      conn->dst_type, 0, NULL, 0,
2474b644ba33SJohan Hedberg 				      conn->dev_class);
2475392599b9SJohan Hedberg 
2476127178d2SJohan Hedberg 	if (!hci_outgoing_auth_needed(hdev, conn)) {
2477769be974SMarcel Holtmann 		conn->state = BT_CONNECTED;
2478769be974SMarcel Holtmann 		hci_proto_connect_cfm(conn, ev->status);
247976a68ba0SDavid Herrmann 		hci_conn_drop(conn);
2480769be974SMarcel Holtmann 	}
2481769be974SMarcel Holtmann 
2482ccd556feSJohan Hedberg unlock:
2483a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
2484a9de9248SMarcel Holtmann }
2485a9de9248SMarcel Holtmann 
24866039aa73SGustavo Padovan static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2487a9de9248SMarcel Holtmann {
2488a9de9248SMarcel Holtmann 	struct hci_ev_cmd_complete *ev = (void *) skb->data;
24899238f36aSJohan Hedberg 	u8 status = skb->data[sizeof(*ev)];
2490a9de9248SMarcel Holtmann 	__u16 opcode;
2491a9de9248SMarcel Holtmann 
2492a9de9248SMarcel Holtmann 	skb_pull(skb, sizeof(*ev));
2493a9de9248SMarcel Holtmann 
2494a9de9248SMarcel Holtmann 	opcode = __le16_to_cpu(ev->opcode);
2495a9de9248SMarcel Holtmann 
2496a9de9248SMarcel Holtmann 	switch (opcode) {
2497a9de9248SMarcel Holtmann 	case HCI_OP_INQUIRY_CANCEL:
2498a9de9248SMarcel Holtmann 		hci_cc_inquiry_cancel(hdev, skb);
2499a9de9248SMarcel Holtmann 		break;
2500a9de9248SMarcel Holtmann 
25014d93483bSAndre Guedes 	case HCI_OP_PERIODIC_INQ:
25024d93483bSAndre Guedes 		hci_cc_periodic_inq(hdev, skb);
25034d93483bSAndre Guedes 		break;
25044d93483bSAndre Guedes 
2505a9de9248SMarcel Holtmann 	case HCI_OP_EXIT_PERIODIC_INQ:
2506a9de9248SMarcel Holtmann 		hci_cc_exit_periodic_inq(hdev, skb);
2507a9de9248SMarcel Holtmann 		break;
2508a9de9248SMarcel Holtmann 
2509a9de9248SMarcel Holtmann 	case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2510a9de9248SMarcel Holtmann 		hci_cc_remote_name_req_cancel(hdev, skb);
2511a9de9248SMarcel Holtmann 		break;
2512a9de9248SMarcel Holtmann 
2513a9de9248SMarcel Holtmann 	case HCI_OP_ROLE_DISCOVERY:
2514a9de9248SMarcel Holtmann 		hci_cc_role_discovery(hdev, skb);
2515a9de9248SMarcel Holtmann 		break;
2516a9de9248SMarcel Holtmann 
2517e4e8e37cSMarcel Holtmann 	case HCI_OP_READ_LINK_POLICY:
2518e4e8e37cSMarcel Holtmann 		hci_cc_read_link_policy(hdev, skb);
2519e4e8e37cSMarcel Holtmann 		break;
2520e4e8e37cSMarcel Holtmann 
2521a9de9248SMarcel Holtmann 	case HCI_OP_WRITE_LINK_POLICY:
2522a9de9248SMarcel Holtmann 		hci_cc_write_link_policy(hdev, skb);
2523a9de9248SMarcel Holtmann 		break;
2524a9de9248SMarcel Holtmann 
2525e4e8e37cSMarcel Holtmann 	case HCI_OP_READ_DEF_LINK_POLICY:
2526e4e8e37cSMarcel Holtmann 		hci_cc_read_def_link_policy(hdev, skb);
2527e4e8e37cSMarcel Holtmann 		break;
2528e4e8e37cSMarcel Holtmann 
2529e4e8e37cSMarcel Holtmann 	case HCI_OP_WRITE_DEF_LINK_POLICY:
2530e4e8e37cSMarcel Holtmann 		hci_cc_write_def_link_policy(hdev, skb);
2531e4e8e37cSMarcel Holtmann 		break;
2532e4e8e37cSMarcel Holtmann 
2533a9de9248SMarcel Holtmann 	case HCI_OP_RESET:
2534a9de9248SMarcel Holtmann 		hci_cc_reset(hdev, skb);
2535a9de9248SMarcel Holtmann 		break;
2536a9de9248SMarcel Holtmann 
2537a9de9248SMarcel Holtmann 	case HCI_OP_WRITE_LOCAL_NAME:
2538a9de9248SMarcel Holtmann 		hci_cc_write_local_name(hdev, skb);
2539a9de9248SMarcel Holtmann 		break;
2540a9de9248SMarcel Holtmann 
2541a9de9248SMarcel Holtmann 	case HCI_OP_READ_LOCAL_NAME:
2542a9de9248SMarcel Holtmann 		hci_cc_read_local_name(hdev, skb);
2543a9de9248SMarcel Holtmann 		break;
2544a9de9248SMarcel Holtmann 
2545a9de9248SMarcel Holtmann 	case HCI_OP_WRITE_AUTH_ENABLE:
2546a9de9248SMarcel Holtmann 		hci_cc_write_auth_enable(hdev, skb);
2547a9de9248SMarcel Holtmann 		break;
2548a9de9248SMarcel Holtmann 
2549a9de9248SMarcel Holtmann 	case HCI_OP_WRITE_ENCRYPT_MODE:
2550a9de9248SMarcel Holtmann 		hci_cc_write_encrypt_mode(hdev, skb);
2551a9de9248SMarcel Holtmann 		break;
2552a9de9248SMarcel Holtmann 
2553a9de9248SMarcel Holtmann 	case HCI_OP_WRITE_SCAN_ENABLE:
2554a9de9248SMarcel Holtmann 		hci_cc_write_scan_enable(hdev, skb);
2555a9de9248SMarcel Holtmann 		break;
2556a9de9248SMarcel Holtmann 
2557a9de9248SMarcel Holtmann 	case HCI_OP_READ_CLASS_OF_DEV:
2558a9de9248SMarcel Holtmann 		hci_cc_read_class_of_dev(hdev, skb);
2559a9de9248SMarcel Holtmann 		break;
2560a9de9248SMarcel Holtmann 
2561a9de9248SMarcel Holtmann 	case HCI_OP_WRITE_CLASS_OF_DEV:
2562a9de9248SMarcel Holtmann 		hci_cc_write_class_of_dev(hdev, skb);
2563a9de9248SMarcel Holtmann 		break;
2564a9de9248SMarcel Holtmann 
2565a9de9248SMarcel Holtmann 	case HCI_OP_READ_VOICE_SETTING:
2566a9de9248SMarcel Holtmann 		hci_cc_read_voice_setting(hdev, skb);
2567a9de9248SMarcel Holtmann 		break;
2568a9de9248SMarcel Holtmann 
2569a9de9248SMarcel Holtmann 	case HCI_OP_WRITE_VOICE_SETTING:
2570a9de9248SMarcel Holtmann 		hci_cc_write_voice_setting(hdev, skb);
2571a9de9248SMarcel Holtmann 		break;
2572a9de9248SMarcel Holtmann 
2573b4cb9fb2SMarcel Holtmann 	case HCI_OP_READ_NUM_SUPPORTED_IAC:
2574b4cb9fb2SMarcel Holtmann 		hci_cc_read_num_supported_iac(hdev, skb);
2575b4cb9fb2SMarcel Holtmann 		break;
2576b4cb9fb2SMarcel Holtmann 
2577333140b5SMarcel Holtmann 	case HCI_OP_WRITE_SSP_MODE:
2578333140b5SMarcel Holtmann 		hci_cc_write_ssp_mode(hdev, skb);
2579333140b5SMarcel Holtmann 		break;
2580333140b5SMarcel Holtmann 
2581eac83dc6SMarcel Holtmann 	case HCI_OP_WRITE_SC_SUPPORT:
2582eac83dc6SMarcel Holtmann 		hci_cc_write_sc_support(hdev, skb);
2583eac83dc6SMarcel Holtmann 		break;
2584eac83dc6SMarcel Holtmann 
2585a9de9248SMarcel Holtmann 	case HCI_OP_READ_LOCAL_VERSION:
2586a9de9248SMarcel Holtmann 		hci_cc_read_local_version(hdev, skb);
2587a9de9248SMarcel Holtmann 		break;
2588a9de9248SMarcel Holtmann 
2589a9de9248SMarcel Holtmann 	case HCI_OP_READ_LOCAL_COMMANDS:
2590a9de9248SMarcel Holtmann 		hci_cc_read_local_commands(hdev, skb);
2591a9de9248SMarcel Holtmann 		break;
2592a9de9248SMarcel Holtmann 
2593a9de9248SMarcel Holtmann 	case HCI_OP_READ_LOCAL_FEATURES:
2594a9de9248SMarcel Holtmann 		hci_cc_read_local_features(hdev, skb);
2595a9de9248SMarcel Holtmann 		break;
2596a9de9248SMarcel Holtmann 
2597971e3a4bSAndre Guedes 	case HCI_OP_READ_LOCAL_EXT_FEATURES:
2598971e3a4bSAndre Guedes 		hci_cc_read_local_ext_features(hdev, skb);
2599971e3a4bSAndre Guedes 		break;
2600971e3a4bSAndre Guedes 
2601a9de9248SMarcel Holtmann 	case HCI_OP_READ_BUFFER_SIZE:
2602a9de9248SMarcel Holtmann 		hci_cc_read_buffer_size(hdev, skb);
2603a9de9248SMarcel Holtmann 		break;
2604a9de9248SMarcel Holtmann 
2605a9de9248SMarcel Holtmann 	case HCI_OP_READ_BD_ADDR:
2606a9de9248SMarcel Holtmann 		hci_cc_read_bd_addr(hdev, skb);
2607a9de9248SMarcel Holtmann 		break;
2608a9de9248SMarcel Holtmann 
2609f332ec66SJohan Hedberg 	case HCI_OP_READ_PAGE_SCAN_ACTIVITY:
2610f332ec66SJohan Hedberg 		hci_cc_read_page_scan_activity(hdev, skb);
2611f332ec66SJohan Hedberg 		break;
2612f332ec66SJohan Hedberg 
26134a3ee763SJohan Hedberg 	case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY:
26144a3ee763SJohan Hedberg 		hci_cc_write_page_scan_activity(hdev, skb);
26154a3ee763SJohan Hedberg 		break;
26164a3ee763SJohan Hedberg 
2617f332ec66SJohan Hedberg 	case HCI_OP_READ_PAGE_SCAN_TYPE:
2618f332ec66SJohan Hedberg 		hci_cc_read_page_scan_type(hdev, skb);
2619f332ec66SJohan Hedberg 		break;
2620f332ec66SJohan Hedberg 
26214a3ee763SJohan Hedberg 	case HCI_OP_WRITE_PAGE_SCAN_TYPE:
26224a3ee763SJohan Hedberg 		hci_cc_write_page_scan_type(hdev, skb);
26234a3ee763SJohan Hedberg 		break;
26244a3ee763SJohan Hedberg 
2625350ee4cfSAndrei Emeltchenko 	case HCI_OP_READ_DATA_BLOCK_SIZE:
2626350ee4cfSAndrei Emeltchenko 		hci_cc_read_data_block_size(hdev, skb);
2627350ee4cfSAndrei Emeltchenko 		break;
2628350ee4cfSAndrei Emeltchenko 
26291e89cffbSAndrei Emeltchenko 	case HCI_OP_READ_FLOW_CONTROL_MODE:
26301e89cffbSAndrei Emeltchenko 		hci_cc_read_flow_control_mode(hdev, skb);
26311e89cffbSAndrei Emeltchenko 		break;
26321e89cffbSAndrei Emeltchenko 
2633928abaa7SAndrei Emeltchenko 	case HCI_OP_READ_LOCAL_AMP_INFO:
2634928abaa7SAndrei Emeltchenko 		hci_cc_read_local_amp_info(hdev, skb);
2635928abaa7SAndrei Emeltchenko 		break;
2636928abaa7SAndrei Emeltchenko 
263733f35721SJohan Hedberg 	case HCI_OP_READ_CLOCK:
263833f35721SJohan Hedberg 		hci_cc_read_clock(hdev, skb);
263933f35721SJohan Hedberg 		break;
264033f35721SJohan Hedberg 
2641903e4541SAndrei Emeltchenko 	case HCI_OP_READ_LOCAL_AMP_ASSOC:
2642903e4541SAndrei Emeltchenko 		hci_cc_read_local_amp_assoc(hdev, skb);
2643903e4541SAndrei Emeltchenko 		break;
2644903e4541SAndrei Emeltchenko 
2645d5859e22SJohan Hedberg 	case HCI_OP_READ_INQ_RSP_TX_POWER:
2646d5859e22SJohan Hedberg 		hci_cc_read_inq_rsp_tx_power(hdev, skb);
2647d5859e22SJohan Hedberg 		break;
2648d5859e22SJohan Hedberg 
2649980e1a53SJohan Hedberg 	case HCI_OP_PIN_CODE_REPLY:
2650980e1a53SJohan Hedberg 		hci_cc_pin_code_reply(hdev, skb);
2651980e1a53SJohan Hedberg 		break;
2652980e1a53SJohan Hedberg 
2653980e1a53SJohan Hedberg 	case HCI_OP_PIN_CODE_NEG_REPLY:
2654980e1a53SJohan Hedberg 		hci_cc_pin_code_neg_reply(hdev, skb);
2655980e1a53SJohan Hedberg 		break;
2656980e1a53SJohan Hedberg 
2657c35938b2SSzymon Janc 	case HCI_OP_READ_LOCAL_OOB_DATA:
26584d2d2796SMarcel Holtmann 		hci_cc_read_local_oob_data(hdev, skb);
26594d2d2796SMarcel Holtmann 		break;
26604d2d2796SMarcel Holtmann 
26614d2d2796SMarcel Holtmann 	case HCI_OP_READ_LOCAL_OOB_EXT_DATA:
26624d2d2796SMarcel Holtmann 		hci_cc_read_local_oob_ext_data(hdev, skb);
2663c35938b2SSzymon Janc 		break;
2664c35938b2SSzymon Janc 
26656ed58ec5SVille Tervo 	case HCI_OP_LE_READ_BUFFER_SIZE:
26666ed58ec5SVille Tervo 		hci_cc_le_read_buffer_size(hdev, skb);
26676ed58ec5SVille Tervo 		break;
26686ed58ec5SVille Tervo 
266960e77321SJohan Hedberg 	case HCI_OP_LE_READ_LOCAL_FEATURES:
267060e77321SJohan Hedberg 		hci_cc_le_read_local_features(hdev, skb);
267160e77321SJohan Hedberg 		break;
267260e77321SJohan Hedberg 
26738fa19098SJohan Hedberg 	case HCI_OP_LE_READ_ADV_TX_POWER:
26748fa19098SJohan Hedberg 		hci_cc_le_read_adv_tx_power(hdev, skb);
26758fa19098SJohan Hedberg 		break;
26768fa19098SJohan Hedberg 
2677a5c29683SJohan Hedberg 	case HCI_OP_USER_CONFIRM_REPLY:
2678a5c29683SJohan Hedberg 		hci_cc_user_confirm_reply(hdev, skb);
2679a5c29683SJohan Hedberg 		break;
2680a5c29683SJohan Hedberg 
2681a5c29683SJohan Hedberg 	case HCI_OP_USER_CONFIRM_NEG_REPLY:
2682a5c29683SJohan Hedberg 		hci_cc_user_confirm_neg_reply(hdev, skb);
2683a5c29683SJohan Hedberg 		break;
2684a5c29683SJohan Hedberg 
26851143d458SBrian Gix 	case HCI_OP_USER_PASSKEY_REPLY:
26861143d458SBrian Gix 		hci_cc_user_passkey_reply(hdev, skb);
26871143d458SBrian Gix 		break;
26881143d458SBrian Gix 
26891143d458SBrian Gix 	case HCI_OP_USER_PASSKEY_NEG_REPLY:
26901143d458SBrian Gix 		hci_cc_user_passkey_neg_reply(hdev, skb);
269116cde993SSzymon Janc 		break;
269207f7fa5dSAndre Guedes 
26937a4cd51dSMarcel Holtmann 	case HCI_OP_LE_SET_RANDOM_ADDR:
26947a4cd51dSMarcel Holtmann 		hci_cc_le_set_random_addr(hdev, skb);
26957a4cd51dSMarcel Holtmann 		break;
26967a4cd51dSMarcel Holtmann 
2697c1d5dc4aSJohan Hedberg 	case HCI_OP_LE_SET_ADV_ENABLE:
2698c1d5dc4aSJohan Hedberg 		hci_cc_le_set_adv_enable(hdev, skb);
2699c1d5dc4aSJohan Hedberg 		break;
2700c1d5dc4aSJohan Hedberg 
2701533553f8SMarcel Holtmann 	case HCI_OP_LE_SET_SCAN_PARAM:
2702533553f8SMarcel Holtmann 		hci_cc_le_set_scan_param(hdev, skb);
2703533553f8SMarcel Holtmann 		break;
2704533553f8SMarcel Holtmann 
2705eb9d91f5SAndre Guedes 	case HCI_OP_LE_SET_SCAN_ENABLE:
2706eb9d91f5SAndre Guedes 		hci_cc_le_set_scan_enable(hdev, skb);
2707eb9d91f5SAndre Guedes 		break;
2708eb9d91f5SAndre Guedes 
2709cf1d081fSJohan Hedberg 	case HCI_OP_LE_READ_WHITE_LIST_SIZE:
2710cf1d081fSJohan Hedberg 		hci_cc_le_read_white_list_size(hdev, skb);
2711cf1d081fSJohan Hedberg 		break;
2712cf1d081fSJohan Hedberg 
27130f36b589SMarcel Holtmann 	case HCI_OP_LE_CLEAR_WHITE_LIST:
27140f36b589SMarcel Holtmann 		hci_cc_le_clear_white_list(hdev, skb);
27150f36b589SMarcel Holtmann 		break;
27160f36b589SMarcel Holtmann 
27170f36b589SMarcel Holtmann 	case HCI_OP_LE_ADD_TO_WHITE_LIST:
27180f36b589SMarcel Holtmann 		hci_cc_le_add_to_white_list(hdev, skb);
27190f36b589SMarcel Holtmann 		break;
27200f36b589SMarcel Holtmann 
27210f36b589SMarcel Holtmann 	case HCI_OP_LE_DEL_FROM_WHITE_LIST:
27220f36b589SMarcel Holtmann 		hci_cc_le_del_from_white_list(hdev, skb);
27230f36b589SMarcel Holtmann 		break;
27240f36b589SMarcel Holtmann 
27259b008c04SJohan Hedberg 	case HCI_OP_LE_READ_SUPPORTED_STATES:
27269b008c04SJohan Hedberg 		hci_cc_le_read_supported_states(hdev, skb);
27279b008c04SJohan Hedberg 		break;
27289b008c04SJohan Hedberg 
2729f9b49306SAndre Guedes 	case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2730f9b49306SAndre Guedes 		hci_cc_write_le_host_supported(hdev, skb);
2731f9b49306SAndre Guedes 		break;
2732f9b49306SAndre Guedes 
273356ed2cb8SJohan Hedberg 	case HCI_OP_LE_SET_ADV_PARAM:
273456ed2cb8SJohan Hedberg 		hci_cc_set_adv_param(hdev, skb);
273556ed2cb8SJohan Hedberg 		break;
273656ed2cb8SJohan Hedberg 
273793c284eeSAndrei Emeltchenko 	case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
273893c284eeSAndrei Emeltchenko 		hci_cc_write_remote_amp_assoc(hdev, skb);
273993c284eeSAndrei Emeltchenko 		break;
274093c284eeSAndrei Emeltchenko 
27415ae76a94SAndrzej Kaczmarek 	case HCI_OP_READ_RSSI:
27425ae76a94SAndrzej Kaczmarek 		hci_cc_read_rssi(hdev, skb);
27435ae76a94SAndrzej Kaczmarek 		break;
27445ae76a94SAndrzej Kaczmarek 
27455a134faeSAndrzej Kaczmarek 	case HCI_OP_READ_TX_POWER:
27465a134faeSAndrzej Kaczmarek 		hci_cc_read_tx_power(hdev, skb);
27475a134faeSAndrzej Kaczmarek 		break;
27485a134faeSAndrzej Kaczmarek 
2749a9de9248SMarcel Holtmann 	default:
27509f1db00cSAndrei Emeltchenko 		BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
2751a9de9248SMarcel Holtmann 		break;
2752a9de9248SMarcel Holtmann 	}
2753a9de9248SMarcel Holtmann 
2754ad82cdd1SJohan Hedberg 	if (opcode != HCI_OP_NOP)
275565cc2b49SMarcel Holtmann 		cancel_delayed_work(&hdev->cmd_timer);
27566bd32326SVille Tervo 
2757ad82cdd1SJohan Hedberg 	hci_req_cmd_complete(hdev, opcode, status);
27589238f36aSJohan Hedberg 
2759dbccd791SSzymon Janc 	if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
2760a9de9248SMarcel Holtmann 		atomic_set(&hdev->cmd_cnt, 1);
2761a9de9248SMarcel Holtmann 		if (!skb_queue_empty(&hdev->cmd_q))
2762c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
2763a9de9248SMarcel Holtmann 	}
2764a9de9248SMarcel Holtmann }
2765a9de9248SMarcel Holtmann 
27666039aa73SGustavo Padovan static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2767a9de9248SMarcel Holtmann {
2768a9de9248SMarcel Holtmann 	struct hci_ev_cmd_status *ev = (void *) skb->data;
2769a9de9248SMarcel Holtmann 	__u16 opcode;
2770a9de9248SMarcel Holtmann 
2771a9de9248SMarcel Holtmann 	skb_pull(skb, sizeof(*ev));
2772a9de9248SMarcel Holtmann 
2773a9de9248SMarcel Holtmann 	opcode = __le16_to_cpu(ev->opcode);
2774a9de9248SMarcel Holtmann 
2775a9de9248SMarcel Holtmann 	switch (opcode) {
2776a9de9248SMarcel Holtmann 	case HCI_OP_INQUIRY:
2777a9de9248SMarcel Holtmann 		hci_cs_inquiry(hdev, ev->status);
2778a9de9248SMarcel Holtmann 		break;
2779a9de9248SMarcel Holtmann 
2780a9de9248SMarcel Holtmann 	case HCI_OP_CREATE_CONN:
2781a9de9248SMarcel Holtmann 		hci_cs_create_conn(hdev, ev->status);
2782a9de9248SMarcel Holtmann 		break;
2783a9de9248SMarcel Holtmann 
2784a9de9248SMarcel Holtmann 	case HCI_OP_ADD_SCO:
2785a9de9248SMarcel Holtmann 		hci_cs_add_sco(hdev, ev->status);
2786a9de9248SMarcel Holtmann 		break;
2787a9de9248SMarcel Holtmann 
2788f8558555SMarcel Holtmann 	case HCI_OP_AUTH_REQUESTED:
2789f8558555SMarcel Holtmann 		hci_cs_auth_requested(hdev, ev->status);
2790f8558555SMarcel Holtmann 		break;
2791f8558555SMarcel Holtmann 
2792f8558555SMarcel Holtmann 	case HCI_OP_SET_CONN_ENCRYPT:
2793f8558555SMarcel Holtmann 		hci_cs_set_conn_encrypt(hdev, ev->status);
2794f8558555SMarcel Holtmann 		break;
2795f8558555SMarcel Holtmann 
2796a9de9248SMarcel Holtmann 	case HCI_OP_REMOTE_NAME_REQ:
2797a9de9248SMarcel Holtmann 		hci_cs_remote_name_req(hdev, ev->status);
2798a9de9248SMarcel Holtmann 		break;
2799a9de9248SMarcel Holtmann 
2800769be974SMarcel Holtmann 	case HCI_OP_READ_REMOTE_FEATURES:
2801769be974SMarcel Holtmann 		hci_cs_read_remote_features(hdev, ev->status);
2802769be974SMarcel Holtmann 		break;
2803769be974SMarcel Holtmann 
2804769be974SMarcel Holtmann 	case HCI_OP_READ_REMOTE_EXT_FEATURES:
2805769be974SMarcel Holtmann 		hci_cs_read_remote_ext_features(hdev, ev->status);
2806769be974SMarcel Holtmann 		break;
2807769be974SMarcel Holtmann 
2808a9de9248SMarcel Holtmann 	case HCI_OP_SETUP_SYNC_CONN:
2809a9de9248SMarcel Holtmann 		hci_cs_setup_sync_conn(hdev, ev->status);
2810a9de9248SMarcel Holtmann 		break;
2811a9de9248SMarcel Holtmann 
2812a9de9248SMarcel Holtmann 	case HCI_OP_SNIFF_MODE:
2813a9de9248SMarcel Holtmann 		hci_cs_sniff_mode(hdev, ev->status);
2814a9de9248SMarcel Holtmann 		break;
2815a9de9248SMarcel Holtmann 
2816a9de9248SMarcel Holtmann 	case HCI_OP_EXIT_SNIFF_MODE:
2817a9de9248SMarcel Holtmann 		hci_cs_exit_sniff_mode(hdev, ev->status);
2818a9de9248SMarcel Holtmann 		break;
2819a9de9248SMarcel Holtmann 
28208962ee74SJohan Hedberg 	case HCI_OP_DISCONNECT:
282188c3df13SJohan Hedberg 		hci_cs_disconnect(hdev, ev->status);
28228962ee74SJohan Hedberg 		break;
28238962ee74SJohan Hedberg 
2824a02226d6SAndrei Emeltchenko 	case HCI_OP_CREATE_PHY_LINK:
2825a02226d6SAndrei Emeltchenko 		hci_cs_create_phylink(hdev, ev->status);
2826a02226d6SAndrei Emeltchenko 		break;
2827a02226d6SAndrei Emeltchenko 
28280b26ab9dSAndrei Emeltchenko 	case HCI_OP_ACCEPT_PHY_LINK:
28290b26ab9dSAndrei Emeltchenko 		hci_cs_accept_phylink(hdev, ev->status);
28300b26ab9dSAndrei Emeltchenko 		break;
28310b26ab9dSAndrei Emeltchenko 
2832cb1d68f7SJohan Hedberg 	case HCI_OP_LE_CREATE_CONN:
2833cb1d68f7SJohan Hedberg 		hci_cs_le_create_conn(hdev, ev->status);
2834cb1d68f7SJohan Hedberg 		break;
2835cb1d68f7SJohan Hedberg 
283681d0c8adSJohan Hedberg 	case HCI_OP_LE_START_ENC:
283781d0c8adSJohan Hedberg 		hci_cs_le_start_enc(hdev, ev->status);
283881d0c8adSJohan Hedberg 		break;
283981d0c8adSJohan Hedberg 
2840a9de9248SMarcel Holtmann 	default:
28419f1db00cSAndrei Emeltchenko 		BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
2842a9de9248SMarcel Holtmann 		break;
2843a9de9248SMarcel Holtmann 	}
2844a9de9248SMarcel Holtmann 
2845ad82cdd1SJohan Hedberg 	if (opcode != HCI_OP_NOP)
284665cc2b49SMarcel Holtmann 		cancel_delayed_work(&hdev->cmd_timer);
28476bd32326SVille Tervo 
284802350a72SJohan Hedberg 	if (ev->status ||
284902350a72SJohan Hedberg 	    (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
285033720450SAndre Guedes 		hci_req_cmd_complete(hdev, opcode, ev->status);
28519238f36aSJohan Hedberg 
285210572132SGustavo F. Padovan 	if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
2853a9de9248SMarcel Holtmann 		atomic_set(&hdev->cmd_cnt, 1);
2854a9de9248SMarcel Holtmann 		if (!skb_queue_empty(&hdev->cmd_q))
2855c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
2856a9de9248SMarcel Holtmann 	}
2857a9de9248SMarcel Holtmann }
2858a9de9248SMarcel Holtmann 
28596039aa73SGustavo Padovan static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2860a9de9248SMarcel Holtmann {
2861a9de9248SMarcel Holtmann 	struct hci_ev_role_change *ev = (void *) skb->data;
2862a9de9248SMarcel Holtmann 	struct hci_conn *conn;
2863a9de9248SMarcel Holtmann 
28649f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
2865a9de9248SMarcel Holtmann 
2866a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
2867a9de9248SMarcel Holtmann 
2868a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2869a9de9248SMarcel Holtmann 	if (conn) {
2870a9de9248SMarcel Holtmann 		if (!ev->status) {
2871a9de9248SMarcel Holtmann 			if (ev->role)
28724dae2798SJohan Hedberg 				clear_bit(HCI_CONN_MASTER, &conn->flags);
2873a9de9248SMarcel Holtmann 			else
28744dae2798SJohan Hedberg 				set_bit(HCI_CONN_MASTER, &conn->flags);
2875a9de9248SMarcel Holtmann 		}
2876a9de9248SMarcel Holtmann 
287751a8efd7SJohan Hedberg 		clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
2878a9de9248SMarcel Holtmann 
2879a9de9248SMarcel Holtmann 		hci_role_switch_cfm(conn, ev->status, ev->role);
2880a9de9248SMarcel Holtmann 	}
2881a9de9248SMarcel Holtmann 
2882a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
2883a9de9248SMarcel Holtmann }
2884a9de9248SMarcel Holtmann 
28856039aa73SGustavo Padovan static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
28861da177e4SLinus Torvalds {
2887a9de9248SMarcel Holtmann 	struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
28881da177e4SLinus Torvalds 	int i;
28891da177e4SLinus Torvalds 
289032ac5b9bSAndrei Emeltchenko 	if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
289132ac5b9bSAndrei Emeltchenko 		BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
289232ac5b9bSAndrei Emeltchenko 		return;
289332ac5b9bSAndrei Emeltchenko 	}
289432ac5b9bSAndrei Emeltchenko 
2895c5993de8SAndrei Emeltchenko 	if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2896c5993de8SAndrei Emeltchenko 	    ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
28971da177e4SLinus Torvalds 		BT_DBG("%s bad parameters", hdev->name);
28981da177e4SLinus Torvalds 		return;
28991da177e4SLinus Torvalds 	}
29001da177e4SLinus Torvalds 
2901c5993de8SAndrei Emeltchenko 	BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2902c5993de8SAndrei Emeltchenko 
2903613a1c0cSAndrei Emeltchenko 	for (i = 0; i < ev->num_hndl; i++) {
2904613a1c0cSAndrei Emeltchenko 		struct hci_comp_pkts_info *info = &ev->handles[i];
29051da177e4SLinus Torvalds 		struct hci_conn *conn;
29061da177e4SLinus Torvalds 		__u16  handle, count;
29071da177e4SLinus Torvalds 
2908613a1c0cSAndrei Emeltchenko 		handle = __le16_to_cpu(info->handle);
2909613a1c0cSAndrei Emeltchenko 		count  = __le16_to_cpu(info->count);
29101da177e4SLinus Torvalds 
29111da177e4SLinus Torvalds 		conn = hci_conn_hash_lookup_handle(hdev, handle);
2912f4280918SAndrei Emeltchenko 		if (!conn)
2913f4280918SAndrei Emeltchenko 			continue;
2914f4280918SAndrei Emeltchenko 
29151da177e4SLinus Torvalds 		conn->sent -= count;
29161da177e4SLinus Torvalds 
2917f4280918SAndrei Emeltchenko 		switch (conn->type) {
2918f4280918SAndrei Emeltchenko 		case ACL_LINK:
291970f23020SAndrei Emeltchenko 			hdev->acl_cnt += count;
292070f23020SAndrei Emeltchenko 			if (hdev->acl_cnt > hdev->acl_pkts)
29211da177e4SLinus Torvalds 				hdev->acl_cnt = hdev->acl_pkts;
2922f4280918SAndrei Emeltchenko 			break;
2923f4280918SAndrei Emeltchenko 
2924f4280918SAndrei Emeltchenko 		case LE_LINK:
29256ed58ec5SVille Tervo 			if (hdev->le_pkts) {
29266ed58ec5SVille Tervo 				hdev->le_cnt += count;
29276ed58ec5SVille Tervo 				if (hdev->le_cnt > hdev->le_pkts)
29286ed58ec5SVille Tervo 					hdev->le_cnt = hdev->le_pkts;
29296ed58ec5SVille Tervo 			} else {
29306ed58ec5SVille Tervo 				hdev->acl_cnt += count;
29316ed58ec5SVille Tervo 				if (hdev->acl_cnt > hdev->acl_pkts)
29326ed58ec5SVille Tervo 					hdev->acl_cnt = hdev->acl_pkts;
29336ed58ec5SVille Tervo 			}
2934f4280918SAndrei Emeltchenko 			break;
2935f4280918SAndrei Emeltchenko 
2936f4280918SAndrei Emeltchenko 		case SCO_LINK:
293770f23020SAndrei Emeltchenko 			hdev->sco_cnt += count;
293870f23020SAndrei Emeltchenko 			if (hdev->sco_cnt > hdev->sco_pkts)
29395b7f9909SMarcel Holtmann 				hdev->sco_cnt = hdev->sco_pkts;
2940f4280918SAndrei Emeltchenko 			break;
2941f4280918SAndrei Emeltchenko 
2942f4280918SAndrei Emeltchenko 		default:
2943f4280918SAndrei Emeltchenko 			BT_ERR("Unknown type %d conn %p", conn->type, conn);
2944f4280918SAndrei Emeltchenko 			break;
29451da177e4SLinus Torvalds 		}
29461da177e4SLinus Torvalds 	}
2947a9de9248SMarcel Holtmann 
29483eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
29491da177e4SLinus Torvalds }
29501da177e4SLinus Torvalds 
295176ef7cf7SAndrei Emeltchenko static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
295276ef7cf7SAndrei Emeltchenko 						 __u16 handle)
295376ef7cf7SAndrei Emeltchenko {
295476ef7cf7SAndrei Emeltchenko 	struct hci_chan *chan;
295576ef7cf7SAndrei Emeltchenko 
295676ef7cf7SAndrei Emeltchenko 	switch (hdev->dev_type) {
295776ef7cf7SAndrei Emeltchenko 	case HCI_BREDR:
295876ef7cf7SAndrei Emeltchenko 		return hci_conn_hash_lookup_handle(hdev, handle);
295976ef7cf7SAndrei Emeltchenko 	case HCI_AMP:
296076ef7cf7SAndrei Emeltchenko 		chan = hci_chan_lookup_handle(hdev, handle);
296176ef7cf7SAndrei Emeltchenko 		if (chan)
296276ef7cf7SAndrei Emeltchenko 			return chan->conn;
296376ef7cf7SAndrei Emeltchenko 		break;
296476ef7cf7SAndrei Emeltchenko 	default:
296576ef7cf7SAndrei Emeltchenko 		BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
296676ef7cf7SAndrei Emeltchenko 		break;
296776ef7cf7SAndrei Emeltchenko 	}
296876ef7cf7SAndrei Emeltchenko 
296976ef7cf7SAndrei Emeltchenko 	return NULL;
297076ef7cf7SAndrei Emeltchenko }
297176ef7cf7SAndrei Emeltchenko 
29726039aa73SGustavo Padovan static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
297325e89e99SAndrei Emeltchenko {
297425e89e99SAndrei Emeltchenko 	struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
297525e89e99SAndrei Emeltchenko 	int i;
297625e89e99SAndrei Emeltchenko 
297725e89e99SAndrei Emeltchenko 	if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
297825e89e99SAndrei Emeltchenko 		BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
297925e89e99SAndrei Emeltchenko 		return;
298025e89e99SAndrei Emeltchenko 	}
298125e89e99SAndrei Emeltchenko 
298225e89e99SAndrei Emeltchenko 	if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
298325e89e99SAndrei Emeltchenko 	    ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
298425e89e99SAndrei Emeltchenko 		BT_DBG("%s bad parameters", hdev->name);
298525e89e99SAndrei Emeltchenko 		return;
298625e89e99SAndrei Emeltchenko 	}
298725e89e99SAndrei Emeltchenko 
298825e89e99SAndrei Emeltchenko 	BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
298925e89e99SAndrei Emeltchenko 	       ev->num_hndl);
299025e89e99SAndrei Emeltchenko 
299125e89e99SAndrei Emeltchenko 	for (i = 0; i < ev->num_hndl; i++) {
299225e89e99SAndrei Emeltchenko 		struct hci_comp_blocks_info *info = &ev->handles[i];
299376ef7cf7SAndrei Emeltchenko 		struct hci_conn *conn = NULL;
299425e89e99SAndrei Emeltchenko 		__u16  handle, block_count;
299525e89e99SAndrei Emeltchenko 
299625e89e99SAndrei Emeltchenko 		handle = __le16_to_cpu(info->handle);
299725e89e99SAndrei Emeltchenko 		block_count = __le16_to_cpu(info->blocks);
299825e89e99SAndrei Emeltchenko 
299976ef7cf7SAndrei Emeltchenko 		conn = __hci_conn_lookup_handle(hdev, handle);
300025e89e99SAndrei Emeltchenko 		if (!conn)
300125e89e99SAndrei Emeltchenko 			continue;
300225e89e99SAndrei Emeltchenko 
300325e89e99SAndrei Emeltchenko 		conn->sent -= block_count;
300425e89e99SAndrei Emeltchenko 
300525e89e99SAndrei Emeltchenko 		switch (conn->type) {
300625e89e99SAndrei Emeltchenko 		case ACL_LINK:
3007bd1eb66bSAndrei Emeltchenko 		case AMP_LINK:
300825e89e99SAndrei Emeltchenko 			hdev->block_cnt += block_count;
300925e89e99SAndrei Emeltchenko 			if (hdev->block_cnt > hdev->num_blocks)
301025e89e99SAndrei Emeltchenko 				hdev->block_cnt = hdev->num_blocks;
301125e89e99SAndrei Emeltchenko 			break;
301225e89e99SAndrei Emeltchenko 
301325e89e99SAndrei Emeltchenko 		default:
301425e89e99SAndrei Emeltchenko 			BT_ERR("Unknown type %d conn %p", conn->type, conn);
301525e89e99SAndrei Emeltchenko 			break;
301625e89e99SAndrei Emeltchenko 		}
301725e89e99SAndrei Emeltchenko 	}
301825e89e99SAndrei Emeltchenko 
301925e89e99SAndrei Emeltchenko 	queue_work(hdev->workqueue, &hdev->tx_work);
302025e89e99SAndrei Emeltchenko }
302125e89e99SAndrei Emeltchenko 
30226039aa73SGustavo Padovan static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
30231da177e4SLinus Torvalds {
3024a9de9248SMarcel Holtmann 	struct hci_ev_mode_change *ev = (void *) skb->data;
302504837f64SMarcel Holtmann 	struct hci_conn *conn;
30261da177e4SLinus Torvalds 
30279f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
30281da177e4SLinus Torvalds 
30291da177e4SLinus Torvalds 	hci_dev_lock(hdev);
30301da177e4SLinus Torvalds 
303104837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
303204837f64SMarcel Holtmann 	if (conn) {
303304837f64SMarcel Holtmann 		conn->mode = ev->mode;
303404837f64SMarcel Holtmann 
30358fc9ced3SGustavo Padovan 		if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
30368fc9ced3SGustavo Padovan 					&conn->flags)) {
303704837f64SMarcel Holtmann 			if (conn->mode == HCI_CM_ACTIVE)
303858a681efSJohan Hedberg 				set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
303904837f64SMarcel Holtmann 			else
304058a681efSJohan Hedberg 				clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
304104837f64SMarcel Holtmann 		}
3042e73439d8SMarcel Holtmann 
304351a8efd7SJohan Hedberg 		if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
3044e73439d8SMarcel Holtmann 			hci_sco_setup(conn, ev->status);
304504837f64SMarcel Holtmann 	}
304604837f64SMarcel Holtmann 
304704837f64SMarcel Holtmann 	hci_dev_unlock(hdev);
304804837f64SMarcel Holtmann }
304904837f64SMarcel Holtmann 
30506039aa73SGustavo Padovan static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
30511da177e4SLinus Torvalds {
3052052b30b0SMarcel Holtmann 	struct hci_ev_pin_code_req *ev = (void *) skb->data;
3053052b30b0SMarcel Holtmann 	struct hci_conn *conn;
3054052b30b0SMarcel Holtmann 
3055a9de9248SMarcel Holtmann 	BT_DBG("%s", hdev->name);
3056052b30b0SMarcel Holtmann 
3057052b30b0SMarcel Holtmann 	hci_dev_lock(hdev);
3058052b30b0SMarcel Holtmann 
3059052b30b0SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3060b6f98044SWaldemar Rymarkiewicz 	if (!conn)
3061b6f98044SWaldemar Rymarkiewicz 		goto unlock;
3062b6f98044SWaldemar Rymarkiewicz 
3063b6f98044SWaldemar Rymarkiewicz 	if (conn->state == BT_CONNECTED) {
3064052b30b0SMarcel Holtmann 		hci_conn_hold(conn);
3065052b30b0SMarcel Holtmann 		conn->disc_timeout = HCI_PAIRING_TIMEOUT;
306676a68ba0SDavid Herrmann 		hci_conn_drop(conn);
3067052b30b0SMarcel Holtmann 	}
3068052b30b0SMarcel Holtmann 
3069a8b2d5c2SJohan Hedberg 	if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
307003b555e1SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
307103b555e1SJohan Hedberg 			     sizeof(ev->bdaddr), &ev->bdaddr);
3072a8b2d5c2SJohan Hedberg 	else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
3073a770bb5aSWaldemar Rymarkiewicz 		u8 secure;
3074a770bb5aSWaldemar Rymarkiewicz 
3075a770bb5aSWaldemar Rymarkiewicz 		if (conn->pending_sec_level == BT_SECURITY_HIGH)
3076a770bb5aSWaldemar Rymarkiewicz 			secure = 1;
3077a770bb5aSWaldemar Rymarkiewicz 		else
3078a770bb5aSWaldemar Rymarkiewicz 			secure = 0;
3079a770bb5aSWaldemar Rymarkiewicz 
3080744cf19eSJohan Hedberg 		mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
3081a770bb5aSWaldemar Rymarkiewicz 	}
3082980e1a53SJohan Hedberg 
3083b6f98044SWaldemar Rymarkiewicz unlock:
3084052b30b0SMarcel Holtmann 	hci_dev_unlock(hdev);
30851da177e4SLinus Torvalds }
30861da177e4SLinus Torvalds 
30876039aa73SGustavo Padovan static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
30881da177e4SLinus Torvalds {
308955ed8ca1SJohan Hedberg 	struct hci_ev_link_key_req *ev = (void *) skb->data;
309055ed8ca1SJohan Hedberg 	struct hci_cp_link_key_reply cp;
309155ed8ca1SJohan Hedberg 	struct hci_conn *conn;
309255ed8ca1SJohan Hedberg 	struct link_key *key;
309355ed8ca1SJohan Hedberg 
3094a9de9248SMarcel Holtmann 	BT_DBG("%s", hdev->name);
309555ed8ca1SJohan Hedberg 
3096034cbea0SAndrei Emeltchenko 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
309755ed8ca1SJohan Hedberg 		return;
309855ed8ca1SJohan Hedberg 
309955ed8ca1SJohan Hedberg 	hci_dev_lock(hdev);
310055ed8ca1SJohan Hedberg 
310155ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, &ev->bdaddr);
310255ed8ca1SJohan Hedberg 	if (!key) {
31036ed93dc6SAndrei Emeltchenko 		BT_DBG("%s link key not found for %pMR", hdev->name,
31046ed93dc6SAndrei Emeltchenko 		       &ev->bdaddr);
310555ed8ca1SJohan Hedberg 		goto not_found;
310655ed8ca1SJohan Hedberg 	}
310755ed8ca1SJohan Hedberg 
31086ed93dc6SAndrei Emeltchenko 	BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
31096ed93dc6SAndrei Emeltchenko 	       &ev->bdaddr);
311055ed8ca1SJohan Hedberg 
311155ed8ca1SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
311260b83f57SWaldemar Rymarkiewicz 	if (conn) {
311366138ce8SMarcel Holtmann 		if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 ||
311466138ce8SMarcel Holtmann 		     key->type == HCI_LK_UNAUTH_COMBINATION_P256) &&
3115807deac2SGustavo Padovan 		    conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
311655ed8ca1SJohan Hedberg 			BT_DBG("%s ignoring unauthenticated key", hdev->name);
311755ed8ca1SJohan Hedberg 			goto not_found;
311855ed8ca1SJohan Hedberg 		}
311955ed8ca1SJohan Hedberg 
312060b83f57SWaldemar Rymarkiewicz 		if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
3121f3fb0b58SJohan Hedberg 		    (conn->pending_sec_level == BT_SECURITY_HIGH ||
3122f3fb0b58SJohan Hedberg 		     conn->pending_sec_level == BT_SECURITY_FIPS)) {
31238fc9ced3SGustavo Padovan 			BT_DBG("%s ignoring key unauthenticated for high security",
31248fc9ced3SGustavo Padovan 			       hdev->name);
312560b83f57SWaldemar Rymarkiewicz 			goto not_found;
312660b83f57SWaldemar Rymarkiewicz 		}
312760b83f57SWaldemar Rymarkiewicz 
312860b83f57SWaldemar Rymarkiewicz 		conn->key_type = key->type;
312960b83f57SWaldemar Rymarkiewicz 		conn->pin_length = key->pin_len;
313060b83f57SWaldemar Rymarkiewicz 	}
313160b83f57SWaldemar Rymarkiewicz 
313255ed8ca1SJohan Hedberg 	bacpy(&cp.bdaddr, &ev->bdaddr);
31339b3b4460SAndrei Emeltchenko 	memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
313455ed8ca1SJohan Hedberg 
313555ed8ca1SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
313655ed8ca1SJohan Hedberg 
313755ed8ca1SJohan Hedberg 	hci_dev_unlock(hdev);
313855ed8ca1SJohan Hedberg 
313955ed8ca1SJohan Hedberg 	return;
314055ed8ca1SJohan Hedberg 
314155ed8ca1SJohan Hedberg not_found:
314255ed8ca1SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
314355ed8ca1SJohan Hedberg 	hci_dev_unlock(hdev);
31441da177e4SLinus Torvalds }
31451da177e4SLinus Torvalds 
31466039aa73SGustavo Padovan static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
31471da177e4SLinus Torvalds {
3148052b30b0SMarcel Holtmann 	struct hci_ev_link_key_notify *ev = (void *) skb->data;
3149052b30b0SMarcel Holtmann 	struct hci_conn *conn;
31507652ff6aSJohan Hedberg 	struct link_key *key;
31517652ff6aSJohan Hedberg 	bool persistent;
315255ed8ca1SJohan Hedberg 	u8 pin_len = 0;
3153052b30b0SMarcel Holtmann 
3154a9de9248SMarcel Holtmann 	BT_DBG("%s", hdev->name);
3155052b30b0SMarcel Holtmann 
3156052b30b0SMarcel Holtmann 	hci_dev_lock(hdev);
3157052b30b0SMarcel Holtmann 
3158052b30b0SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3159052b30b0SMarcel Holtmann 	if (conn) {
3160052b30b0SMarcel Holtmann 		hci_conn_hold(conn);
3161052b30b0SMarcel Holtmann 		conn->disc_timeout = HCI_DISCONN_TIMEOUT;
3162980e1a53SJohan Hedberg 		pin_len = conn->pin_length;
316313d39315SWaldemar Rymarkiewicz 
316413d39315SWaldemar Rymarkiewicz 		if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
316513d39315SWaldemar Rymarkiewicz 			conn->key_type = ev->key_type;
316613d39315SWaldemar Rymarkiewicz 
316776a68ba0SDavid Herrmann 		hci_conn_drop(conn);
3168052b30b0SMarcel Holtmann 	}
3169052b30b0SMarcel Holtmann 
31707652ff6aSJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
31717652ff6aSJohan Hedberg 		goto unlock;
317255ed8ca1SJohan Hedberg 
31737652ff6aSJohan Hedberg 	key = hci_add_link_key(hdev, conn, &ev->bdaddr, ev->link_key,
31747652ff6aSJohan Hedberg 			        ev->key_type, pin_len, &persistent);
31757652ff6aSJohan Hedberg 	if (!key)
31767652ff6aSJohan Hedberg 		goto unlock;
31777652ff6aSJohan Hedberg 
31787652ff6aSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
31797652ff6aSJohan Hedberg 
31806d5650c4SJohan Hedberg 	/* Keep debug keys around only if the HCI_KEEP_DEBUG_KEYS flag
31816d5650c4SJohan Hedberg 	 * is set. If it's not set simply remove the key from the kernel
31826d5650c4SJohan Hedberg 	 * list (we've still notified user space about it but with
31836d5650c4SJohan Hedberg 	 * store_hint being 0).
31846d5650c4SJohan Hedberg 	 */
31856d5650c4SJohan Hedberg 	if (key->type == HCI_LK_DEBUG_COMBINATION &&
31866d5650c4SJohan Hedberg 	    !test_bit(HCI_KEEP_DEBUG_KEYS, &hdev->dev_flags)) {
31876d5650c4SJohan Hedberg 		list_del(&key->list);
31886d5650c4SJohan Hedberg 		kfree(key);
31896d5650c4SJohan Hedberg 	} else if (conn) {
3190af6a9c32SJohan Hedberg 		if (persistent)
3191af6a9c32SJohan Hedberg 			clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags);
3192af6a9c32SJohan Hedberg 		else
3193af6a9c32SJohan Hedberg 			set_bit(HCI_CONN_FLUSH_KEY, &conn->flags);
31946d5650c4SJohan Hedberg 	}
31957652ff6aSJohan Hedberg 
31967652ff6aSJohan Hedberg unlock:
3197052b30b0SMarcel Holtmann 	hci_dev_unlock(hdev);
31981da177e4SLinus Torvalds }
31991da177e4SLinus Torvalds 
32006039aa73SGustavo Padovan static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
320104837f64SMarcel Holtmann {
3202a9de9248SMarcel Holtmann 	struct hci_ev_clock_offset *ev = (void *) skb->data;
320304837f64SMarcel Holtmann 	struct hci_conn *conn;
320404837f64SMarcel Holtmann 
32059f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
320604837f64SMarcel Holtmann 
320704837f64SMarcel Holtmann 	hci_dev_lock(hdev);
320804837f64SMarcel Holtmann 
320904837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
32101da177e4SLinus Torvalds 	if (conn && !ev->status) {
32111da177e4SLinus Torvalds 		struct inquiry_entry *ie;
32121da177e4SLinus Torvalds 
3213cc11b9c1SAndrei Emeltchenko 		ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
3214cc11b9c1SAndrei Emeltchenko 		if (ie) {
32151da177e4SLinus Torvalds 			ie->data.clock_offset = ev->clock_offset;
32161da177e4SLinus Torvalds 			ie->timestamp = jiffies;
32171da177e4SLinus Torvalds 		}
32181da177e4SLinus Torvalds 	}
32191da177e4SLinus Torvalds 
32201da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
32211da177e4SLinus Torvalds }
32221da177e4SLinus Torvalds 
32236039aa73SGustavo Padovan static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
3224a8746417SMarcel Holtmann {
3225a8746417SMarcel Holtmann 	struct hci_ev_pkt_type_change *ev = (void *) skb->data;
3226a8746417SMarcel Holtmann 	struct hci_conn *conn;
3227a8746417SMarcel Holtmann 
32289f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3229a8746417SMarcel Holtmann 
3230a8746417SMarcel Holtmann 	hci_dev_lock(hdev);
3231a8746417SMarcel Holtmann 
3232a8746417SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3233a8746417SMarcel Holtmann 	if (conn && !ev->status)
3234a8746417SMarcel Holtmann 		conn->pkt_type = __le16_to_cpu(ev->pkt_type);
3235a8746417SMarcel Holtmann 
3236a8746417SMarcel Holtmann 	hci_dev_unlock(hdev);
3237a8746417SMarcel Holtmann }
3238a8746417SMarcel Holtmann 
32396039aa73SGustavo Padovan static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
324085a1e930SMarcel Holtmann {
3241a9de9248SMarcel Holtmann 	struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
324285a1e930SMarcel Holtmann 	struct inquiry_entry *ie;
324385a1e930SMarcel Holtmann 
324485a1e930SMarcel Holtmann 	BT_DBG("%s", hdev->name);
324585a1e930SMarcel Holtmann 
324685a1e930SMarcel Holtmann 	hci_dev_lock(hdev);
324785a1e930SMarcel Holtmann 
3248cc11b9c1SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3249cc11b9c1SAndrei Emeltchenko 	if (ie) {
325085a1e930SMarcel Holtmann 		ie->data.pscan_rep_mode = ev->pscan_rep_mode;
325185a1e930SMarcel Holtmann 		ie->timestamp = jiffies;
325285a1e930SMarcel Holtmann 	}
325385a1e930SMarcel Holtmann 
325485a1e930SMarcel Holtmann 	hci_dev_unlock(hdev);
325585a1e930SMarcel Holtmann }
325685a1e930SMarcel Holtmann 
32576039aa73SGustavo Padovan static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
3258807deac2SGustavo Padovan 					     struct sk_buff *skb)
3259a9de9248SMarcel Holtmann {
3260a9de9248SMarcel Holtmann 	struct inquiry_data data;
3261a9de9248SMarcel Holtmann 	int num_rsp = *((__u8 *) skb->data);
3262a9de9248SMarcel Holtmann 
3263a9de9248SMarcel Holtmann 	BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
3264a9de9248SMarcel Holtmann 
3265a9de9248SMarcel Holtmann 	if (!num_rsp)
3266a9de9248SMarcel Holtmann 		return;
3267a9de9248SMarcel Holtmann 
32681519cc17SAndre Guedes 	if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
32691519cc17SAndre Guedes 		return;
32701519cc17SAndre Guedes 
3271a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
3272a9de9248SMarcel Holtmann 
3273a9de9248SMarcel Holtmann 	if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
3274138d22efSSzymon Janc 		struct inquiry_info_with_rssi_and_pscan_mode *info;
3275138d22efSSzymon Janc 		info = (void *) (skb->data + 1);
3276a9de9248SMarcel Holtmann 
3277e17acd40SJohan Hedberg 		for (; num_rsp; num_rsp--, info++) {
3278af58925cSMarcel Holtmann 			u32 flags;
3279af58925cSMarcel Holtmann 
3280a9de9248SMarcel Holtmann 			bacpy(&data.bdaddr, &info->bdaddr);
3281a9de9248SMarcel Holtmann 			data.pscan_rep_mode	= info->pscan_rep_mode;
3282a9de9248SMarcel Holtmann 			data.pscan_period_mode	= info->pscan_period_mode;
3283a9de9248SMarcel Holtmann 			data.pscan_mode		= info->pscan_mode;
3284a9de9248SMarcel Holtmann 			memcpy(data.dev_class, info->dev_class, 3);
3285a9de9248SMarcel Holtmann 			data.clock_offset	= info->clock_offset;
3286a9de9248SMarcel Holtmann 			data.rssi		= info->rssi;
328741a96212SMarcel Holtmann 			data.ssp_mode		= 0x00;
32883175405bSJohan Hedberg 
3289af58925cSMarcel Holtmann 			flags = hci_inquiry_cache_update(hdev, &data, false);
3290af58925cSMarcel Holtmann 
329148264f06SJohan Hedberg 			mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
3292e17acd40SJohan Hedberg 					  info->dev_class, info->rssi,
3293af58925cSMarcel Holtmann 					  flags, NULL, 0, NULL, 0);
3294a9de9248SMarcel Holtmann 		}
3295a9de9248SMarcel Holtmann 	} else {
3296a9de9248SMarcel Holtmann 		struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
3297a9de9248SMarcel Holtmann 
3298e17acd40SJohan Hedberg 		for (; num_rsp; num_rsp--, info++) {
3299af58925cSMarcel Holtmann 			u32 flags;
3300af58925cSMarcel Holtmann 
3301a9de9248SMarcel Holtmann 			bacpy(&data.bdaddr, &info->bdaddr);
3302a9de9248SMarcel Holtmann 			data.pscan_rep_mode	= info->pscan_rep_mode;
3303a9de9248SMarcel Holtmann 			data.pscan_period_mode	= info->pscan_period_mode;
3304a9de9248SMarcel Holtmann 			data.pscan_mode		= 0x00;
3305a9de9248SMarcel Holtmann 			memcpy(data.dev_class, info->dev_class, 3);
3306a9de9248SMarcel Holtmann 			data.clock_offset	= info->clock_offset;
3307a9de9248SMarcel Holtmann 			data.rssi		= info->rssi;
330841a96212SMarcel Holtmann 			data.ssp_mode		= 0x00;
3309af58925cSMarcel Holtmann 
3310af58925cSMarcel Holtmann 			flags = hci_inquiry_cache_update(hdev, &data, false);
3311af58925cSMarcel Holtmann 
331248264f06SJohan Hedberg 			mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
3313e17acd40SJohan Hedberg 					  info->dev_class, info->rssi,
3314af58925cSMarcel Holtmann 					  flags, NULL, 0, NULL, 0);
3315a9de9248SMarcel Holtmann 		}
3316a9de9248SMarcel Holtmann 	}
3317a9de9248SMarcel Holtmann 
3318a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
3319a9de9248SMarcel Holtmann }
3320a9de9248SMarcel Holtmann 
33216039aa73SGustavo Padovan static void hci_remote_ext_features_evt(struct hci_dev *hdev,
3322807deac2SGustavo Padovan 					struct sk_buff *skb)
3323a9de9248SMarcel Holtmann {
332441a96212SMarcel Holtmann 	struct hci_ev_remote_ext_features *ev = (void *) skb->data;
332541a96212SMarcel Holtmann 	struct hci_conn *conn;
332641a96212SMarcel Holtmann 
3327a9de9248SMarcel Holtmann 	BT_DBG("%s", hdev->name);
332841a96212SMarcel Holtmann 
332941a96212SMarcel Holtmann 	hci_dev_lock(hdev);
333041a96212SMarcel Holtmann 
333141a96212SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3332ccd556feSJohan Hedberg 	if (!conn)
3333ccd556feSJohan Hedberg 		goto unlock;
3334ccd556feSJohan Hedberg 
3335cad718edSJohan Hedberg 	if (ev->page < HCI_MAX_PAGES)
3336cad718edSJohan Hedberg 		memcpy(conn->features[ev->page], ev->features, 8);
3337cad718edSJohan Hedberg 
3338769be974SMarcel Holtmann 	if (!ev->status && ev->page == 0x01) {
333941a96212SMarcel Holtmann 		struct inquiry_entry *ie;
334041a96212SMarcel Holtmann 
3341cc11b9c1SAndrei Emeltchenko 		ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
3342cc11b9c1SAndrei Emeltchenko 		if (ie)
334302b7cc62SJohan Hedberg 			ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
334441a96212SMarcel Holtmann 
3345bbb0eadaSJaganath Kanakkassery 		if (ev->features[0] & LMP_HOST_SSP) {
334658a681efSJohan Hedberg 			set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
3347bbb0eadaSJaganath Kanakkassery 		} else {
3348bbb0eadaSJaganath Kanakkassery 			/* It is mandatory by the Bluetooth specification that
3349bbb0eadaSJaganath Kanakkassery 			 * Extended Inquiry Results are only used when Secure
3350bbb0eadaSJaganath Kanakkassery 			 * Simple Pairing is enabled, but some devices violate
3351bbb0eadaSJaganath Kanakkassery 			 * this.
3352bbb0eadaSJaganath Kanakkassery 			 *
3353bbb0eadaSJaganath Kanakkassery 			 * To make these devices work, the internal SSP
3354bbb0eadaSJaganath Kanakkassery 			 * enabled flag needs to be cleared if the remote host
3355bbb0eadaSJaganath Kanakkassery 			 * features do not indicate SSP support */
3356bbb0eadaSJaganath Kanakkassery 			clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
3357bbb0eadaSJaganath Kanakkassery 		}
3358eb9a8f3fSMarcel Holtmann 
3359eb9a8f3fSMarcel Holtmann 		if (ev->features[0] & LMP_HOST_SC)
3360eb9a8f3fSMarcel Holtmann 			set_bit(HCI_CONN_SC_ENABLED, &conn->flags);
336141a96212SMarcel Holtmann 	}
336241a96212SMarcel Holtmann 
3363ccd556feSJohan Hedberg 	if (conn->state != BT_CONFIG)
3364ccd556feSJohan Hedberg 		goto unlock;
3365ccd556feSJohan Hedberg 
3366671267bfSJohan Hedberg 	if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
3367127178d2SJohan Hedberg 		struct hci_cp_remote_name_req cp;
3368127178d2SJohan Hedberg 		memset(&cp, 0, sizeof(cp));
3369127178d2SJohan Hedberg 		bacpy(&cp.bdaddr, &conn->dst);
3370127178d2SJohan Hedberg 		cp.pscan_rep_mode = 0x02;
3371127178d2SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
3372b644ba33SJohan Hedberg 	} else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3373b644ba33SJohan Hedberg 		mgmt_device_connected(hdev, &conn->dst, conn->type,
337408c79b61SJohan Hedberg 				      conn->dst_type, 0, NULL, 0,
3375b644ba33SJohan Hedberg 				      conn->dev_class);
3376392599b9SJohan Hedberg 
3377127178d2SJohan Hedberg 	if (!hci_outgoing_auth_needed(hdev, conn)) {
3378769be974SMarcel Holtmann 		conn->state = BT_CONNECTED;
3379769be974SMarcel Holtmann 		hci_proto_connect_cfm(conn, ev->status);
338076a68ba0SDavid Herrmann 		hci_conn_drop(conn);
3381769be974SMarcel Holtmann 	}
3382769be974SMarcel Holtmann 
3383ccd556feSJohan Hedberg unlock:
338441a96212SMarcel Holtmann 	hci_dev_unlock(hdev);
3385a9de9248SMarcel Holtmann }
3386a9de9248SMarcel Holtmann 
33876039aa73SGustavo Padovan static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
3388807deac2SGustavo Padovan 				       struct sk_buff *skb)
3389a9de9248SMarcel Holtmann {
3390b6a0dc82SMarcel Holtmann 	struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
3391b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
3392b6a0dc82SMarcel Holtmann 
33939f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3394b6a0dc82SMarcel Holtmann 
3395b6a0dc82SMarcel Holtmann 	hci_dev_lock(hdev);
3396b6a0dc82SMarcel Holtmann 
3397b6a0dc82SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
33989dc0a3afSMarcel Holtmann 	if (!conn) {
33999dc0a3afSMarcel Holtmann 		if (ev->link_type == ESCO_LINK)
34009dc0a3afSMarcel Holtmann 			goto unlock;
34019dc0a3afSMarcel Holtmann 
34029dc0a3afSMarcel Holtmann 		conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
3403b6a0dc82SMarcel Holtmann 		if (!conn)
3404b6a0dc82SMarcel Holtmann 			goto unlock;
3405b6a0dc82SMarcel Holtmann 
34069dc0a3afSMarcel Holtmann 		conn->type = SCO_LINK;
34079dc0a3afSMarcel Holtmann 	}
34089dc0a3afSMarcel Holtmann 
3409732547f9SMarcel Holtmann 	switch (ev->status) {
3410732547f9SMarcel Holtmann 	case 0x00:
3411732547f9SMarcel Holtmann 		conn->handle = __le16_to_cpu(ev->handle);
3412732547f9SMarcel Holtmann 		conn->state  = BT_CONNECTED;
3413732547f9SMarcel Holtmann 
3414732547f9SMarcel Holtmann 		hci_conn_add_sysfs(conn);
3415732547f9SMarcel Holtmann 		break;
3416732547f9SMarcel Holtmann 
341781218d20SNick Pelly 	case 0x10:	/* Connection Accept Timeout */
34181a4c958cSFrédéric Dalleau 	case 0x0d:	/* Connection Rejected due to Limited Resources */
3419705e5711SStephen Coe 	case 0x11:	/* Unsupported Feature or Parameter Value */
3420732547f9SMarcel Holtmann 	case 0x1c:	/* SCO interval rejected */
34211038a00bSNick Pelly 	case 0x1a:	/* Unsupported Remote Feature */
3422732547f9SMarcel Holtmann 	case 0x1f:	/* Unspecified error */
342327539bc4SAndrew Earl 	case 0x20:	/* Unsupported LMP Parameter value */
34242dea632fSFrédéric Dalleau 		if (conn->out) {
3425efc7688bSMarcel Holtmann 			conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
3426efc7688bSMarcel Holtmann 					(hdev->esco_type & EDR_ESCO_MASK);
34272dea632fSFrédéric Dalleau 			if (hci_setup_sync(conn, conn->link->handle))
3428efc7688bSMarcel Holtmann 				goto unlock;
3429efc7688bSMarcel Holtmann 		}
3430732547f9SMarcel Holtmann 		/* fall through */
3431efc7688bSMarcel Holtmann 
3432732547f9SMarcel Holtmann 	default:
3433b6a0dc82SMarcel Holtmann 		conn->state = BT_CLOSED;
3434732547f9SMarcel Holtmann 		break;
3435732547f9SMarcel Holtmann 	}
3436b6a0dc82SMarcel Holtmann 
3437b6a0dc82SMarcel Holtmann 	hci_proto_connect_cfm(conn, ev->status);
3438b6a0dc82SMarcel Holtmann 	if (ev->status)
3439b6a0dc82SMarcel Holtmann 		hci_conn_del(conn);
3440b6a0dc82SMarcel Holtmann 
3441b6a0dc82SMarcel Holtmann unlock:
3442b6a0dc82SMarcel Holtmann 	hci_dev_unlock(hdev);
3443a9de9248SMarcel Holtmann }
3444a9de9248SMarcel Holtmann 
3445efdcf8e3SMarcel Holtmann static inline size_t eir_get_length(u8 *eir, size_t eir_len)
3446efdcf8e3SMarcel Holtmann {
3447efdcf8e3SMarcel Holtmann 	size_t parsed = 0;
3448efdcf8e3SMarcel Holtmann 
3449efdcf8e3SMarcel Holtmann 	while (parsed < eir_len) {
3450efdcf8e3SMarcel Holtmann 		u8 field_len = eir[0];
3451efdcf8e3SMarcel Holtmann 
3452efdcf8e3SMarcel Holtmann 		if (field_len == 0)
3453efdcf8e3SMarcel Holtmann 			return parsed;
3454efdcf8e3SMarcel Holtmann 
3455efdcf8e3SMarcel Holtmann 		parsed += field_len + 1;
3456efdcf8e3SMarcel Holtmann 		eir += field_len + 1;
3457efdcf8e3SMarcel Holtmann 	}
3458efdcf8e3SMarcel Holtmann 
3459efdcf8e3SMarcel Holtmann 	return eir_len;
3460efdcf8e3SMarcel Holtmann }
3461efdcf8e3SMarcel Holtmann 
34626039aa73SGustavo Padovan static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
3463807deac2SGustavo Padovan 					    struct sk_buff *skb)
3464a9de9248SMarcel Holtmann {
3465a9de9248SMarcel Holtmann 	struct inquiry_data data;
3466a9de9248SMarcel Holtmann 	struct extended_inquiry_info *info = (void *) (skb->data + 1);
3467a9de9248SMarcel Holtmann 	int num_rsp = *((__u8 *) skb->data);
34689d939d94SVishal Agarwal 	size_t eir_len;
3469a9de9248SMarcel Holtmann 
3470a9de9248SMarcel Holtmann 	BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
3471a9de9248SMarcel Holtmann 
3472a9de9248SMarcel Holtmann 	if (!num_rsp)
3473a9de9248SMarcel Holtmann 		return;
3474a9de9248SMarcel Holtmann 
34751519cc17SAndre Guedes 	if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
34761519cc17SAndre Guedes 		return;
34771519cc17SAndre Guedes 
3478a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
3479a9de9248SMarcel Holtmann 
3480e17acd40SJohan Hedberg 	for (; num_rsp; num_rsp--, info++) {
3481af58925cSMarcel Holtmann 		u32 flags;
3482af58925cSMarcel Holtmann 		bool name_known;
3483561aafbcSJohan Hedberg 
3484a9de9248SMarcel Holtmann 		bacpy(&data.bdaddr, &info->bdaddr);
3485a9de9248SMarcel Holtmann 		data.pscan_rep_mode	= info->pscan_rep_mode;
3486a9de9248SMarcel Holtmann 		data.pscan_period_mode	= info->pscan_period_mode;
3487a9de9248SMarcel Holtmann 		data.pscan_mode		= 0x00;
3488a9de9248SMarcel Holtmann 		memcpy(data.dev_class, info->dev_class, 3);
3489a9de9248SMarcel Holtmann 		data.clock_offset	= info->clock_offset;
3490a9de9248SMarcel Holtmann 		data.rssi		= info->rssi;
349141a96212SMarcel Holtmann 		data.ssp_mode		= 0x01;
3492561aafbcSJohan Hedberg 
3493a8b2d5c2SJohan Hedberg 		if (test_bit(HCI_MGMT, &hdev->dev_flags))
34944ddb1930SJohan Hedberg 			name_known = eir_has_data_type(info->data,
34954ddb1930SJohan Hedberg 						       sizeof(info->data),
34964ddb1930SJohan Hedberg 						       EIR_NAME_COMPLETE);
3497561aafbcSJohan Hedberg 		else
3498561aafbcSJohan Hedberg 			name_known = true;
3499561aafbcSJohan Hedberg 
3500af58925cSMarcel Holtmann 		flags = hci_inquiry_cache_update(hdev, &data, name_known);
3501af58925cSMarcel Holtmann 
35029d939d94SVishal Agarwal 		eir_len = eir_get_length(info->data, sizeof(info->data));
3503af58925cSMarcel Holtmann 
350448264f06SJohan Hedberg 		mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
3505af58925cSMarcel Holtmann 				  info->dev_class, info->rssi,
3506af58925cSMarcel Holtmann 				  flags, info->data, eir_len, NULL, 0);
3507a9de9248SMarcel Holtmann 	}
3508a9de9248SMarcel Holtmann 
3509a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
3510a9de9248SMarcel Holtmann }
3511a9de9248SMarcel Holtmann 
35121c2e0041SJohan Hedberg static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
35131c2e0041SJohan Hedberg 					 struct sk_buff *skb)
35141c2e0041SJohan Hedberg {
35151c2e0041SJohan Hedberg 	struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
35161c2e0041SJohan Hedberg 	struct hci_conn *conn;
35171c2e0041SJohan Hedberg 
35189f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
35191c2e0041SJohan Hedberg 	       __le16_to_cpu(ev->handle));
35201c2e0041SJohan Hedberg 
35211c2e0041SJohan Hedberg 	hci_dev_lock(hdev);
35221c2e0041SJohan Hedberg 
35231c2e0041SJohan Hedberg 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
35241c2e0041SJohan Hedberg 	if (!conn)
35251c2e0041SJohan Hedberg 		goto unlock;
35261c2e0041SJohan Hedberg 
35279eb1fbfaSJohan Hedberg 	/* For BR/EDR the necessary steps are taken through the
35289eb1fbfaSJohan Hedberg 	 * auth_complete event.
35299eb1fbfaSJohan Hedberg 	 */
35309eb1fbfaSJohan Hedberg 	if (conn->type != LE_LINK)
35319eb1fbfaSJohan Hedberg 		goto unlock;
35329eb1fbfaSJohan Hedberg 
35331c2e0041SJohan Hedberg 	if (!ev->status)
35341c2e0041SJohan Hedberg 		conn->sec_level = conn->pending_sec_level;
35351c2e0041SJohan Hedberg 
35361c2e0041SJohan Hedberg 	clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
35371c2e0041SJohan Hedberg 
35381c2e0041SJohan Hedberg 	if (ev->status && conn->state == BT_CONNECTED) {
3539bed71748SAndre Guedes 		hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
354076a68ba0SDavid Herrmann 		hci_conn_drop(conn);
35411c2e0041SJohan Hedberg 		goto unlock;
35421c2e0041SJohan Hedberg 	}
35431c2e0041SJohan Hedberg 
35441c2e0041SJohan Hedberg 	if (conn->state == BT_CONFIG) {
35451c2e0041SJohan Hedberg 		if (!ev->status)
35461c2e0041SJohan Hedberg 			conn->state = BT_CONNECTED;
35471c2e0041SJohan Hedberg 
35481c2e0041SJohan Hedberg 		hci_proto_connect_cfm(conn, ev->status);
354976a68ba0SDavid Herrmann 		hci_conn_drop(conn);
35501c2e0041SJohan Hedberg 	} else {
35511c2e0041SJohan Hedberg 		hci_auth_cfm(conn, ev->status);
35521c2e0041SJohan Hedberg 
35531c2e0041SJohan Hedberg 		hci_conn_hold(conn);
35541c2e0041SJohan Hedberg 		conn->disc_timeout = HCI_DISCONN_TIMEOUT;
355576a68ba0SDavid Herrmann 		hci_conn_drop(conn);
35561c2e0041SJohan Hedberg 	}
35571c2e0041SJohan Hedberg 
35581c2e0041SJohan Hedberg unlock:
35591c2e0041SJohan Hedberg 	hci_dev_unlock(hdev);
35601c2e0041SJohan Hedberg }
35611c2e0041SJohan Hedberg 
35626039aa73SGustavo Padovan static u8 hci_get_auth_req(struct hci_conn *conn)
356317fa4b9dSJohan Hedberg {
356417fa4b9dSJohan Hedberg 	/* If remote requests no-bonding follow that lead */
3565acabae96SMikel Astiz 	if (conn->remote_auth == HCI_AT_NO_BONDING ||
3566acabae96SMikel Astiz 	    conn->remote_auth == HCI_AT_NO_BONDING_MITM)
356758797bf7SWaldemar Rymarkiewicz 		return conn->remote_auth | (conn->auth_type & 0x01);
356817fa4b9dSJohan Hedberg 
3569b7f94c88SMikel Astiz 	/* If both remote and local have enough IO capabilities, require
3570b7f94c88SMikel Astiz 	 * MITM protection
3571b7f94c88SMikel Astiz 	 */
3572b7f94c88SMikel Astiz 	if (conn->remote_cap != HCI_IO_NO_INPUT_OUTPUT &&
3573b7f94c88SMikel Astiz 	    conn->io_capability != HCI_IO_NO_INPUT_OUTPUT)
3574b7f94c88SMikel Astiz 		return conn->remote_auth | 0x01;
3575b7f94c88SMikel Astiz 
35767e74170aSTimo Mueller 	/* No MITM protection possible so ignore remote requirement */
35777e74170aSTimo Mueller 	return (conn->remote_auth & ~0x01) | (conn->auth_type & 0x01);
357817fa4b9dSJohan Hedberg }
357917fa4b9dSJohan Hedberg 
35806039aa73SGustavo Padovan static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
35810493684eSMarcel Holtmann {
35820493684eSMarcel Holtmann 	struct hci_ev_io_capa_request *ev = (void *) skb->data;
35830493684eSMarcel Holtmann 	struct hci_conn *conn;
35840493684eSMarcel Holtmann 
35850493684eSMarcel Holtmann 	BT_DBG("%s", hdev->name);
35860493684eSMarcel Holtmann 
35870493684eSMarcel Holtmann 	hci_dev_lock(hdev);
35880493684eSMarcel Holtmann 
35890493684eSMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
359003b555e1SJohan Hedberg 	if (!conn)
359103b555e1SJohan Hedberg 		goto unlock;
359203b555e1SJohan Hedberg 
35930493684eSMarcel Holtmann 	hci_conn_hold(conn);
35940493684eSMarcel Holtmann 
3595a8b2d5c2SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
359603b555e1SJohan Hedberg 		goto unlock;
359703b555e1SJohan Hedberg 
3598a8b2d5c2SJohan Hedberg 	if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
359903b555e1SJohan Hedberg 	    (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
360017fa4b9dSJohan Hedberg 		struct hci_cp_io_capability_reply cp;
360117fa4b9dSJohan Hedberg 
360217fa4b9dSJohan Hedberg 		bacpy(&cp.bdaddr, &ev->bdaddr);
36037a7f1e7cSHemant Gupta 		/* Change the IO capability from KeyboardDisplay
36047a7f1e7cSHemant Gupta 		 * to DisplayYesNo as it is not supported by BT spec. */
36057a7f1e7cSHemant Gupta 		cp.capability = (conn->io_capability == 0x04) ?
3606a767631aSMikel Astiz 				HCI_IO_DISPLAY_YESNO : conn->io_capability;
3607b7f94c88SMikel Astiz 
3608b7f94c88SMikel Astiz 		/* If we are initiators, there is no remote information yet */
3609b7f94c88SMikel Astiz 		if (conn->remote_auth == 0xff) {
3610b7f94c88SMikel Astiz 			cp.authentication = conn->auth_type;
36116fd6b915SMikel Astiz 
3612b16c6604SMikel Astiz 			/* Request MITM protection if our IO caps allow it
36134ad51a75SJohan Hedberg 			 * except for the no-bonding case.
36144ad51a75SJohan Hedberg 			 * conn->auth_type is not updated here since
36154ad51a75SJohan Hedberg 			 * that might cause the user confirmation to be
36164ad51a75SJohan Hedberg 			 * rejected in case the remote doesn't have the
36174ad51a75SJohan Hedberg 			 * IO capabilities for MITM.
3618b16c6604SMikel Astiz 			 */
36196fd6b915SMikel Astiz 			if (conn->io_capability != HCI_IO_NO_INPUT_OUTPUT &&
3620b16c6604SMikel Astiz 			    cp.authentication != HCI_AT_NO_BONDING)
36216fd6b915SMikel Astiz 				cp.authentication |= 0x01;
3622b7f94c88SMikel Astiz 		} else {
36237cbc9bd9SJohan Hedberg 			conn->auth_type = hci_get_auth_req(conn);
36247cbc9bd9SJohan Hedberg 			cp.authentication = conn->auth_type;
3625b7f94c88SMikel Astiz 		}
362617fa4b9dSJohan Hedberg 
36278fc9ced3SGustavo Padovan 		if (hci_find_remote_oob_data(hdev, &conn->dst) &&
36288fc9ced3SGustavo Padovan 		    (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
3629ce85ee13SSzymon Janc 			cp.oob_data = 0x01;
3630ce85ee13SSzymon Janc 		else
3631ce85ee13SSzymon Janc 			cp.oob_data = 0x00;
3632ce85ee13SSzymon Janc 
363317fa4b9dSJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
363417fa4b9dSJohan Hedberg 			     sizeof(cp), &cp);
363503b555e1SJohan Hedberg 	} else {
363603b555e1SJohan Hedberg 		struct hci_cp_io_capability_neg_reply cp;
363703b555e1SJohan Hedberg 
363803b555e1SJohan Hedberg 		bacpy(&cp.bdaddr, &ev->bdaddr);
36399f5a0d7bSAndrei Emeltchenko 		cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
364003b555e1SJohan Hedberg 
364103b555e1SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
364203b555e1SJohan Hedberg 			     sizeof(cp), &cp);
364303b555e1SJohan Hedberg 	}
364403b555e1SJohan Hedberg 
364503b555e1SJohan Hedberg unlock:
364603b555e1SJohan Hedberg 	hci_dev_unlock(hdev);
364703b555e1SJohan Hedberg }
364803b555e1SJohan Hedberg 
36496039aa73SGustavo Padovan static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
365003b555e1SJohan Hedberg {
365103b555e1SJohan Hedberg 	struct hci_ev_io_capa_reply *ev = (void *) skb->data;
365203b555e1SJohan Hedberg 	struct hci_conn *conn;
365303b555e1SJohan Hedberg 
365403b555e1SJohan Hedberg 	BT_DBG("%s", hdev->name);
365503b555e1SJohan Hedberg 
365603b555e1SJohan Hedberg 	hci_dev_lock(hdev);
365703b555e1SJohan Hedberg 
365803b555e1SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
365903b555e1SJohan Hedberg 	if (!conn)
366003b555e1SJohan Hedberg 		goto unlock;
366103b555e1SJohan Hedberg 
366203b555e1SJohan Hedberg 	conn->remote_cap = ev->capability;
366303b555e1SJohan Hedberg 	conn->remote_auth = ev->authentication;
366458a681efSJohan Hedberg 	if (ev->oob_data)
366558a681efSJohan Hedberg 		set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
366603b555e1SJohan Hedberg 
366703b555e1SJohan Hedberg unlock:
36680493684eSMarcel Holtmann 	hci_dev_unlock(hdev);
36690493684eSMarcel Holtmann }
36700493684eSMarcel Holtmann 
36716039aa73SGustavo Padovan static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3672a5c29683SJohan Hedberg 					 struct sk_buff *skb)
3673a5c29683SJohan Hedberg {
3674a5c29683SJohan Hedberg 	struct hci_ev_user_confirm_req *ev = (void *) skb->data;
367555bc1a37SJohan Hedberg 	int loc_mitm, rem_mitm, confirm_hint = 0;
36767a828908SJohan Hedberg 	struct hci_conn *conn;
3677a5c29683SJohan Hedberg 
3678a5c29683SJohan Hedberg 	BT_DBG("%s", hdev->name);
3679a5c29683SJohan Hedberg 
3680a5c29683SJohan Hedberg 	hci_dev_lock(hdev);
3681a5c29683SJohan Hedberg 
3682a8b2d5c2SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
36837a828908SJohan Hedberg 		goto unlock;
36847a828908SJohan Hedberg 
36857a828908SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
36867a828908SJohan Hedberg 	if (!conn)
36877a828908SJohan Hedberg 		goto unlock;
36887a828908SJohan Hedberg 
36897a828908SJohan Hedberg 	loc_mitm = (conn->auth_type & 0x01);
36907a828908SJohan Hedberg 	rem_mitm = (conn->remote_auth & 0x01);
36917a828908SJohan Hedberg 
36927a828908SJohan Hedberg 	/* If we require MITM but the remote device can't provide that
36936fd6b915SMikel Astiz 	 * (it has NoInputNoOutput) then reject the confirmation request
36946fd6b915SMikel Astiz 	 */
36956fd6b915SMikel Astiz 	if (loc_mitm && conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
36967a828908SJohan Hedberg 		BT_DBG("Rejecting request: remote device can't provide MITM");
36977a828908SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
36987a828908SJohan Hedberg 			     sizeof(ev->bdaddr), &ev->bdaddr);
36997a828908SJohan Hedberg 		goto unlock;
37007a828908SJohan Hedberg 	}
37017a828908SJohan Hedberg 
37027a828908SJohan Hedberg 	/* If no side requires MITM protection; auto-accept */
3703a767631aSMikel Astiz 	if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
3704a767631aSMikel Astiz 	    (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
370555bc1a37SJohan Hedberg 
370655bc1a37SJohan Hedberg 		/* If we're not the initiators request authorization to
370755bc1a37SJohan Hedberg 		 * proceed from user space (mgmt_user_confirm with
3708ba15a58bSJohan Hedberg 		 * confirm_hint set to 1). The exception is if neither
3709ba15a58bSJohan Hedberg 		 * side had MITM in which case we do auto-accept.
3710ba15a58bSJohan Hedberg 		 */
3711ba15a58bSJohan Hedberg 		if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) &&
3712ba15a58bSJohan Hedberg 		    (loc_mitm || rem_mitm)) {
371355bc1a37SJohan Hedberg 			BT_DBG("Confirming auto-accept as acceptor");
371455bc1a37SJohan Hedberg 			confirm_hint = 1;
371555bc1a37SJohan Hedberg 			goto confirm;
371655bc1a37SJohan Hedberg 		}
371755bc1a37SJohan Hedberg 
37189f61656aSJohan Hedberg 		BT_DBG("Auto-accept of user confirmation with %ums delay",
37199f61656aSJohan Hedberg 		       hdev->auto_accept_delay);
37209f61656aSJohan Hedberg 
37219f61656aSJohan Hedberg 		if (hdev->auto_accept_delay > 0) {
37229f61656aSJohan Hedberg 			int delay = msecs_to_jiffies(hdev->auto_accept_delay);
37237bc18d9dSJohan Hedberg 			queue_delayed_work(conn->hdev->workqueue,
37247bc18d9dSJohan Hedberg 					   &conn->auto_accept_work, delay);
37259f61656aSJohan Hedberg 			goto unlock;
37269f61656aSJohan Hedberg 		}
37279f61656aSJohan Hedberg 
37287a828908SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
37297a828908SJohan Hedberg 			     sizeof(ev->bdaddr), &ev->bdaddr);
37307a828908SJohan Hedberg 		goto unlock;
37317a828908SJohan Hedberg 	}
37327a828908SJohan Hedberg 
373355bc1a37SJohan Hedberg confirm:
373439adbffeSJohan Hedberg 	mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0,
373539adbffeSJohan Hedberg 				  le32_to_cpu(ev->passkey), confirm_hint);
3736a5c29683SJohan Hedberg 
37377a828908SJohan Hedberg unlock:
3738a5c29683SJohan Hedberg 	hci_dev_unlock(hdev);
3739a5c29683SJohan Hedberg }
3740a5c29683SJohan Hedberg 
37416039aa73SGustavo Padovan static void hci_user_passkey_request_evt(struct hci_dev *hdev,
37421143d458SBrian Gix 					 struct sk_buff *skb)
37431143d458SBrian Gix {
37441143d458SBrian Gix 	struct hci_ev_user_passkey_req *ev = (void *) skb->data;
37451143d458SBrian Gix 
37461143d458SBrian Gix 	BT_DBG("%s", hdev->name);
37471143d458SBrian Gix 
3748a8b2d5c2SJohan Hedberg 	if (test_bit(HCI_MGMT, &hdev->dev_flags))
3749272d90dfSJohan Hedberg 		mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
37501143d458SBrian Gix }
37511143d458SBrian Gix 
375292a25256SJohan Hedberg static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
375392a25256SJohan Hedberg 					struct sk_buff *skb)
375492a25256SJohan Hedberg {
375592a25256SJohan Hedberg 	struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
375692a25256SJohan Hedberg 	struct hci_conn *conn;
375792a25256SJohan Hedberg 
375892a25256SJohan Hedberg 	BT_DBG("%s", hdev->name);
375992a25256SJohan Hedberg 
376092a25256SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
376192a25256SJohan Hedberg 	if (!conn)
376292a25256SJohan Hedberg 		return;
376392a25256SJohan Hedberg 
376492a25256SJohan Hedberg 	conn->passkey_notify = __le32_to_cpu(ev->passkey);
376592a25256SJohan Hedberg 	conn->passkey_entered = 0;
376692a25256SJohan Hedberg 
376792a25256SJohan Hedberg 	if (test_bit(HCI_MGMT, &hdev->dev_flags))
376892a25256SJohan Hedberg 		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
376992a25256SJohan Hedberg 					 conn->dst_type, conn->passkey_notify,
377092a25256SJohan Hedberg 					 conn->passkey_entered);
377192a25256SJohan Hedberg }
377292a25256SJohan Hedberg 
377392a25256SJohan Hedberg static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
377492a25256SJohan Hedberg {
377592a25256SJohan Hedberg 	struct hci_ev_keypress_notify *ev = (void *) skb->data;
377692a25256SJohan Hedberg 	struct hci_conn *conn;
377792a25256SJohan Hedberg 
377892a25256SJohan Hedberg 	BT_DBG("%s", hdev->name);
377992a25256SJohan Hedberg 
378092a25256SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
378192a25256SJohan Hedberg 	if (!conn)
378292a25256SJohan Hedberg 		return;
378392a25256SJohan Hedberg 
378492a25256SJohan Hedberg 	switch (ev->type) {
378592a25256SJohan Hedberg 	case HCI_KEYPRESS_STARTED:
378692a25256SJohan Hedberg 		conn->passkey_entered = 0;
378792a25256SJohan Hedberg 		return;
378892a25256SJohan Hedberg 
378992a25256SJohan Hedberg 	case HCI_KEYPRESS_ENTERED:
379092a25256SJohan Hedberg 		conn->passkey_entered++;
379192a25256SJohan Hedberg 		break;
379292a25256SJohan Hedberg 
379392a25256SJohan Hedberg 	case HCI_KEYPRESS_ERASED:
379492a25256SJohan Hedberg 		conn->passkey_entered--;
379592a25256SJohan Hedberg 		break;
379692a25256SJohan Hedberg 
379792a25256SJohan Hedberg 	case HCI_KEYPRESS_CLEARED:
379892a25256SJohan Hedberg 		conn->passkey_entered = 0;
379992a25256SJohan Hedberg 		break;
380092a25256SJohan Hedberg 
380192a25256SJohan Hedberg 	case HCI_KEYPRESS_COMPLETED:
380292a25256SJohan Hedberg 		return;
380392a25256SJohan Hedberg 	}
380492a25256SJohan Hedberg 
380592a25256SJohan Hedberg 	if (test_bit(HCI_MGMT, &hdev->dev_flags))
380692a25256SJohan Hedberg 		mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
380792a25256SJohan Hedberg 					 conn->dst_type, conn->passkey_notify,
380892a25256SJohan Hedberg 					 conn->passkey_entered);
380992a25256SJohan Hedberg }
381092a25256SJohan Hedberg 
38116039aa73SGustavo Padovan static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3812807deac2SGustavo Padovan 					 struct sk_buff *skb)
38130493684eSMarcel Holtmann {
38140493684eSMarcel Holtmann 	struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
38150493684eSMarcel Holtmann 	struct hci_conn *conn;
38160493684eSMarcel Holtmann 
38170493684eSMarcel Holtmann 	BT_DBG("%s", hdev->name);
38180493684eSMarcel Holtmann 
38190493684eSMarcel Holtmann 	hci_dev_lock(hdev);
38200493684eSMarcel Holtmann 
38210493684eSMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
38222a611692SJohan Hedberg 	if (!conn)
38232a611692SJohan Hedberg 		goto unlock;
38242a611692SJohan Hedberg 
38252a611692SJohan Hedberg 	/* To avoid duplicate auth_failed events to user space we check
38262a611692SJohan Hedberg 	 * the HCI_CONN_AUTH_PEND flag which will be set if we
38272a611692SJohan Hedberg 	 * initiated the authentication. A traditional auth_complete
38282a611692SJohan Hedberg 	 * event gets always produced as initiator and is also mapped to
38292a611692SJohan Hedberg 	 * the mgmt_auth_failed event */
3830fa1bd918SMikel Astiz 	if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
3831bab73cb6SJohan Hedberg 		mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
3832bab73cb6SJohan Hedberg 				 ev->status);
38332a611692SJohan Hedberg 
383476a68ba0SDavid Herrmann 	hci_conn_drop(conn);
38350493684eSMarcel Holtmann 
38362a611692SJohan Hedberg unlock:
38370493684eSMarcel Holtmann 	hci_dev_unlock(hdev);
38380493684eSMarcel Holtmann }
38390493684eSMarcel Holtmann 
38406039aa73SGustavo Padovan static void hci_remote_host_features_evt(struct hci_dev *hdev,
3841807deac2SGustavo Padovan 					 struct sk_buff *skb)
384241a96212SMarcel Holtmann {
384341a96212SMarcel Holtmann 	struct hci_ev_remote_host_features *ev = (void *) skb->data;
384441a96212SMarcel Holtmann 	struct inquiry_entry *ie;
3845cad718edSJohan Hedberg 	struct hci_conn *conn;
384641a96212SMarcel Holtmann 
384741a96212SMarcel Holtmann 	BT_DBG("%s", hdev->name);
384841a96212SMarcel Holtmann 
384941a96212SMarcel Holtmann 	hci_dev_lock(hdev);
385041a96212SMarcel Holtmann 
3851cad718edSJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3852cad718edSJohan Hedberg 	if (conn)
3853cad718edSJohan Hedberg 		memcpy(conn->features[1], ev->features, 8);
3854cad718edSJohan Hedberg 
3855cc11b9c1SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3856cc11b9c1SAndrei Emeltchenko 	if (ie)
385702b7cc62SJohan Hedberg 		ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
385841a96212SMarcel Holtmann 
385941a96212SMarcel Holtmann 	hci_dev_unlock(hdev);
386041a96212SMarcel Holtmann }
386141a96212SMarcel Holtmann 
38626039aa73SGustavo Padovan static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
38632763eda6SSzymon Janc 					    struct sk_buff *skb)
38642763eda6SSzymon Janc {
38652763eda6SSzymon Janc 	struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
38662763eda6SSzymon Janc 	struct oob_data *data;
38672763eda6SSzymon Janc 
38682763eda6SSzymon Janc 	BT_DBG("%s", hdev->name);
38692763eda6SSzymon Janc 
38702763eda6SSzymon Janc 	hci_dev_lock(hdev);
38712763eda6SSzymon Janc 
3872a8b2d5c2SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
3873e1ba1f15SSzymon Janc 		goto unlock;
3874e1ba1f15SSzymon Janc 
38752763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
38762763eda6SSzymon Janc 	if (data) {
3877519ca9d0SMarcel Holtmann 		if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
3878519ca9d0SMarcel Holtmann 			struct hci_cp_remote_oob_ext_data_reply cp;
3879519ca9d0SMarcel Holtmann 
3880519ca9d0SMarcel Holtmann 			bacpy(&cp.bdaddr, &ev->bdaddr);
3881519ca9d0SMarcel Holtmann 			memcpy(cp.hash192, data->hash192, sizeof(cp.hash192));
3882519ca9d0SMarcel Holtmann 			memcpy(cp.randomizer192, data->randomizer192,
3883519ca9d0SMarcel Holtmann 			       sizeof(cp.randomizer192));
3884519ca9d0SMarcel Holtmann 			memcpy(cp.hash256, data->hash256, sizeof(cp.hash256));
3885519ca9d0SMarcel Holtmann 			memcpy(cp.randomizer256, data->randomizer256,
3886519ca9d0SMarcel Holtmann 			       sizeof(cp.randomizer256));
3887519ca9d0SMarcel Holtmann 
3888519ca9d0SMarcel Holtmann 			hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY,
3889519ca9d0SMarcel Holtmann 				     sizeof(cp), &cp);
3890519ca9d0SMarcel Holtmann 		} else {
38912763eda6SSzymon Janc 			struct hci_cp_remote_oob_data_reply cp;
38922763eda6SSzymon Janc 
38932763eda6SSzymon Janc 			bacpy(&cp.bdaddr, &ev->bdaddr);
3894519ca9d0SMarcel Holtmann 			memcpy(cp.hash, data->hash192, sizeof(cp.hash));
3895519ca9d0SMarcel Holtmann 			memcpy(cp.randomizer, data->randomizer192,
3896519ca9d0SMarcel Holtmann 			       sizeof(cp.randomizer));
38972763eda6SSzymon Janc 
3898519ca9d0SMarcel Holtmann 			hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY,
3899519ca9d0SMarcel Holtmann 				     sizeof(cp), &cp);
3900519ca9d0SMarcel Holtmann 		}
39012763eda6SSzymon Janc 	} else {
39022763eda6SSzymon Janc 		struct hci_cp_remote_oob_data_neg_reply cp;
39032763eda6SSzymon Janc 
39042763eda6SSzymon Janc 		bacpy(&cp.bdaddr, &ev->bdaddr);
3905519ca9d0SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY,
3906519ca9d0SMarcel Holtmann 			     sizeof(cp), &cp);
39072763eda6SSzymon Janc 	}
39082763eda6SSzymon Janc 
3909e1ba1f15SSzymon Janc unlock:
39102763eda6SSzymon Janc 	hci_dev_unlock(hdev);
39112763eda6SSzymon Janc }
39122763eda6SSzymon Janc 
3913d5e91192SAndrei Emeltchenko static void hci_phy_link_complete_evt(struct hci_dev *hdev,
3914d5e91192SAndrei Emeltchenko 				      struct sk_buff *skb)
3915d5e91192SAndrei Emeltchenko {
3916d5e91192SAndrei Emeltchenko 	struct hci_ev_phy_link_complete *ev = (void *) skb->data;
3917d5e91192SAndrei Emeltchenko 	struct hci_conn *hcon, *bredr_hcon;
3918d5e91192SAndrei Emeltchenko 
3919d5e91192SAndrei Emeltchenko 	BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
3920d5e91192SAndrei Emeltchenko 	       ev->status);
3921d5e91192SAndrei Emeltchenko 
3922d5e91192SAndrei Emeltchenko 	hci_dev_lock(hdev);
3923d5e91192SAndrei Emeltchenko 
3924d5e91192SAndrei Emeltchenko 	hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3925d5e91192SAndrei Emeltchenko 	if (!hcon) {
3926d5e91192SAndrei Emeltchenko 		hci_dev_unlock(hdev);
3927d5e91192SAndrei Emeltchenko 		return;
3928d5e91192SAndrei Emeltchenko 	}
3929d5e91192SAndrei Emeltchenko 
3930d5e91192SAndrei Emeltchenko 	if (ev->status) {
3931d5e91192SAndrei Emeltchenko 		hci_conn_del(hcon);
3932d5e91192SAndrei Emeltchenko 		hci_dev_unlock(hdev);
3933d5e91192SAndrei Emeltchenko 		return;
3934d5e91192SAndrei Emeltchenko 	}
3935d5e91192SAndrei Emeltchenko 
3936d5e91192SAndrei Emeltchenko 	bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
3937d5e91192SAndrei Emeltchenko 
3938d5e91192SAndrei Emeltchenko 	hcon->state = BT_CONNECTED;
3939d5e91192SAndrei Emeltchenko 	bacpy(&hcon->dst, &bredr_hcon->dst);
3940d5e91192SAndrei Emeltchenko 
3941d5e91192SAndrei Emeltchenko 	hci_conn_hold(hcon);
3942d5e91192SAndrei Emeltchenko 	hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
394376a68ba0SDavid Herrmann 	hci_conn_drop(hcon);
3944d5e91192SAndrei Emeltchenko 
3945d5e91192SAndrei Emeltchenko 	hci_conn_add_sysfs(hcon);
3946d5e91192SAndrei Emeltchenko 
3947cf70ff22SAndrei Emeltchenko 	amp_physical_cfm(bredr_hcon, hcon);
3948cf70ff22SAndrei Emeltchenko 
3949d5e91192SAndrei Emeltchenko 	hci_dev_unlock(hdev);
3950d5e91192SAndrei Emeltchenko }
3951d5e91192SAndrei Emeltchenko 
395227695fb4SAndrei Emeltchenko static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
395327695fb4SAndrei Emeltchenko {
395427695fb4SAndrei Emeltchenko 	struct hci_ev_logical_link_complete *ev = (void *) skb->data;
395527695fb4SAndrei Emeltchenko 	struct hci_conn *hcon;
395627695fb4SAndrei Emeltchenko 	struct hci_chan *hchan;
395727695fb4SAndrei Emeltchenko 	struct amp_mgr *mgr;
395827695fb4SAndrei Emeltchenko 
395927695fb4SAndrei Emeltchenko 	BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
396027695fb4SAndrei Emeltchenko 	       hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
396127695fb4SAndrei Emeltchenko 	       ev->status);
396227695fb4SAndrei Emeltchenko 
396327695fb4SAndrei Emeltchenko 	hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
396427695fb4SAndrei Emeltchenko 	if (!hcon)
396527695fb4SAndrei Emeltchenko 		return;
396627695fb4SAndrei Emeltchenko 
396727695fb4SAndrei Emeltchenko 	/* Create AMP hchan */
396827695fb4SAndrei Emeltchenko 	hchan = hci_chan_create(hcon);
396927695fb4SAndrei Emeltchenko 	if (!hchan)
397027695fb4SAndrei Emeltchenko 		return;
397127695fb4SAndrei Emeltchenko 
397227695fb4SAndrei Emeltchenko 	hchan->handle = le16_to_cpu(ev->handle);
397327695fb4SAndrei Emeltchenko 
397427695fb4SAndrei Emeltchenko 	BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
397527695fb4SAndrei Emeltchenko 
397627695fb4SAndrei Emeltchenko 	mgr = hcon->amp_mgr;
397727695fb4SAndrei Emeltchenko 	if (mgr && mgr->bredr_chan) {
397827695fb4SAndrei Emeltchenko 		struct l2cap_chan *bredr_chan = mgr->bredr_chan;
397927695fb4SAndrei Emeltchenko 
398027695fb4SAndrei Emeltchenko 		l2cap_chan_lock(bredr_chan);
398127695fb4SAndrei Emeltchenko 
398227695fb4SAndrei Emeltchenko 		bredr_chan->conn->mtu = hdev->block_mtu;
398327695fb4SAndrei Emeltchenko 		l2cap_logical_cfm(bredr_chan, hchan, 0);
398427695fb4SAndrei Emeltchenko 		hci_conn_hold(hcon);
398527695fb4SAndrei Emeltchenko 
398627695fb4SAndrei Emeltchenko 		l2cap_chan_unlock(bredr_chan);
398727695fb4SAndrei Emeltchenko 	}
398827695fb4SAndrei Emeltchenko }
398927695fb4SAndrei Emeltchenko 
3990606e2a10SAndrei Emeltchenko static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
3991606e2a10SAndrei Emeltchenko 					     struct sk_buff *skb)
3992606e2a10SAndrei Emeltchenko {
3993606e2a10SAndrei Emeltchenko 	struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
3994606e2a10SAndrei Emeltchenko 	struct hci_chan *hchan;
3995606e2a10SAndrei Emeltchenko 
3996606e2a10SAndrei Emeltchenko 	BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
3997606e2a10SAndrei Emeltchenko 	       le16_to_cpu(ev->handle), ev->status);
3998606e2a10SAndrei Emeltchenko 
3999606e2a10SAndrei Emeltchenko 	if (ev->status)
4000606e2a10SAndrei Emeltchenko 		return;
4001606e2a10SAndrei Emeltchenko 
4002606e2a10SAndrei Emeltchenko 	hci_dev_lock(hdev);
4003606e2a10SAndrei Emeltchenko 
4004606e2a10SAndrei Emeltchenko 	hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
4005606e2a10SAndrei Emeltchenko 	if (!hchan)
4006606e2a10SAndrei Emeltchenko 		goto unlock;
4007606e2a10SAndrei Emeltchenko 
4008606e2a10SAndrei Emeltchenko 	amp_destroy_logical_link(hchan, ev->reason);
4009606e2a10SAndrei Emeltchenko 
4010606e2a10SAndrei Emeltchenko unlock:
4011606e2a10SAndrei Emeltchenko 	hci_dev_unlock(hdev);
4012606e2a10SAndrei Emeltchenko }
4013606e2a10SAndrei Emeltchenko 
40149eef6b3aSAndrei Emeltchenko static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
40159eef6b3aSAndrei Emeltchenko 					     struct sk_buff *skb)
40169eef6b3aSAndrei Emeltchenko {
40179eef6b3aSAndrei Emeltchenko 	struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
40189eef6b3aSAndrei Emeltchenko 	struct hci_conn *hcon;
40199eef6b3aSAndrei Emeltchenko 
40209eef6b3aSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
40219eef6b3aSAndrei Emeltchenko 
40229eef6b3aSAndrei Emeltchenko 	if (ev->status)
40239eef6b3aSAndrei Emeltchenko 		return;
40249eef6b3aSAndrei Emeltchenko 
40259eef6b3aSAndrei Emeltchenko 	hci_dev_lock(hdev);
40269eef6b3aSAndrei Emeltchenko 
40279eef6b3aSAndrei Emeltchenko 	hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
40289eef6b3aSAndrei Emeltchenko 	if (hcon) {
40299eef6b3aSAndrei Emeltchenko 		hcon->state = BT_CLOSED;
40309eef6b3aSAndrei Emeltchenko 		hci_conn_del(hcon);
40319eef6b3aSAndrei Emeltchenko 	}
40329eef6b3aSAndrei Emeltchenko 
40339eef6b3aSAndrei Emeltchenko 	hci_dev_unlock(hdev);
40349eef6b3aSAndrei Emeltchenko }
40359eef6b3aSAndrei Emeltchenko 
40366039aa73SGustavo Padovan static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
4037fcd89c09SVille Tervo {
4038fcd89c09SVille Tervo 	struct hci_ev_le_conn_complete *ev = (void *) skb->data;
4039fcd89c09SVille Tervo 	struct hci_conn *conn;
404068d6f6deSJohan Hedberg 	struct smp_irk *irk;
4041fcd89c09SVille Tervo 
40429f1db00cSAndrei Emeltchenko 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
4043fcd89c09SVille Tervo 
4044fcd89c09SVille Tervo 	hci_dev_lock(hdev);
4045fcd89c09SVille Tervo 
40464f72b329SAndrzej Kaczmarek 	conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
4047b62f328bSVille Tervo 	if (!conn) {
4048b62f328bSVille Tervo 		conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
4049b62f328bSVille Tervo 		if (!conn) {
4050b62f328bSVille Tervo 			BT_ERR("No memory for new connection");
4051230fd16aSAndre Guedes 			goto unlock;
4052b62f328bSVille Tervo 		}
405329b7988aSAndre Guedes 
405429b7988aSAndre Guedes 		conn->dst_type = ev->bdaddr_type;
4055b9b343d2SAndre Guedes 
4056b9b343d2SAndre Guedes 		if (ev->role == LE_CONN_ROLE_MASTER) {
4057b9b343d2SAndre Guedes 			conn->out = true;
40584dae2798SJohan Hedberg 			set_bit(HCI_CONN_MASTER, &conn->flags);
4059b9b343d2SAndre Guedes 		}
4060cb1d68f7SJohan Hedberg 
4061cb1d68f7SJohan Hedberg 		/* If we didn't have a hci_conn object previously
4062cb1d68f7SJohan Hedberg 		 * but we're in master role this must be something
4063cb1d68f7SJohan Hedberg 		 * initiated using a white list. Since white list based
4064cb1d68f7SJohan Hedberg 		 * connections are not "first class citizens" we don't
4065cb1d68f7SJohan Hedberg 		 * have full tracking of them. Therefore, we go ahead
4066cb1d68f7SJohan Hedberg 		 * with a "best effort" approach of determining the
4067cb1d68f7SJohan Hedberg 		 * initiator address based on the HCI_PRIVACY flag.
4068cb1d68f7SJohan Hedberg 		 */
4069cb1d68f7SJohan Hedberg 		if (conn->out) {
4070cb1d68f7SJohan Hedberg 			conn->resp_addr_type = ev->bdaddr_type;
4071cb1d68f7SJohan Hedberg 			bacpy(&conn->resp_addr, &ev->bdaddr);
4072cb1d68f7SJohan Hedberg 			if (test_bit(HCI_PRIVACY, &hdev->dev_flags)) {
4073cb1d68f7SJohan Hedberg 				conn->init_addr_type = ADDR_LE_DEV_RANDOM;
4074cb1d68f7SJohan Hedberg 				bacpy(&conn->init_addr, &hdev->rpa);
4075cb1d68f7SJohan Hedberg 			} else {
4076cb1d68f7SJohan Hedberg 				hci_copy_identity_address(hdev,
4077cb1d68f7SJohan Hedberg 							  &conn->init_addr,
4078cb1d68f7SJohan Hedberg 							  &conn->init_addr_type);
4079cb1d68f7SJohan Hedberg 			}
408080c24ab8SJohan Hedberg 		}
4081cb1d68f7SJohan Hedberg 	} else {
408280c24ab8SJohan Hedberg 		cancel_delayed_work(&conn->le_conn_timeout);
408380c24ab8SJohan Hedberg 	}
408480c24ab8SJohan Hedberg 
408580c24ab8SJohan Hedberg 	if (!conn->out) {
4086cb1d68f7SJohan Hedberg 		/* Set the responder (our side) address type based on
4087cb1d68f7SJohan Hedberg 		 * the advertising address type.
4088cb1d68f7SJohan Hedberg 		 */
4089cb1d68f7SJohan Hedberg 		conn->resp_addr_type = hdev->adv_addr_type;
4090cb1d68f7SJohan Hedberg 		if (hdev->adv_addr_type == ADDR_LE_DEV_RANDOM)
4091cb1d68f7SJohan Hedberg 			bacpy(&conn->resp_addr, &hdev->random_addr);
4092cb1d68f7SJohan Hedberg 		else
4093cb1d68f7SJohan Hedberg 			bacpy(&conn->resp_addr, &hdev->bdaddr);
4094cb1d68f7SJohan Hedberg 
4095cb1d68f7SJohan Hedberg 		conn->init_addr_type = ev->bdaddr_type;
4096cb1d68f7SJohan Hedberg 		bacpy(&conn->init_addr, &ev->bdaddr);
4097a720d735SMarcel Holtmann 
4098a720d735SMarcel Holtmann 		/* For incoming connections, set the default minimum
4099a720d735SMarcel Holtmann 		 * and maximum connection interval. They will be used
4100a720d735SMarcel Holtmann 		 * to check if the parameters are in range and if not
4101a720d735SMarcel Holtmann 		 * trigger the connection update procedure.
4102a720d735SMarcel Holtmann 		 */
4103a720d735SMarcel Holtmann 		conn->le_conn_min_interval = hdev->le_conn_min_interval;
4104a720d735SMarcel Holtmann 		conn->le_conn_max_interval = hdev->le_conn_max_interval;
4105cb1d68f7SJohan Hedberg 	}
41067be2edbbSJohan Hedberg 
4107edb4b466SMarcel Holtmann 	/* Lookup the identity address from the stored connection
4108edb4b466SMarcel Holtmann 	 * address and address type.
4109edb4b466SMarcel Holtmann 	 *
4110edb4b466SMarcel Holtmann 	 * When establishing connections to an identity address, the
4111edb4b466SMarcel Holtmann 	 * connection procedure will store the resolvable random
4112edb4b466SMarcel Holtmann 	 * address first. Now if it can be converted back into the
4113edb4b466SMarcel Holtmann 	 * identity address, start using the identity address from
4114edb4b466SMarcel Holtmann 	 * now on.
4115edb4b466SMarcel Holtmann 	 */
4116edb4b466SMarcel Holtmann 	irk = hci_get_irk(hdev, &conn->dst, conn->dst_type);
411768d6f6deSJohan Hedberg 	if (irk) {
411868d6f6deSJohan Hedberg 		bacpy(&conn->dst, &irk->bdaddr);
411968d6f6deSJohan Hedberg 		conn->dst_type = irk->addr_type;
412068d6f6deSJohan Hedberg 	}
412168d6f6deSJohan Hedberg 
4122cd17decbSAndre Guedes 	if (ev->status) {
412306c053fbSAndre Guedes 		hci_le_conn_failed(conn, ev->status);
4124cd17decbSAndre Guedes 		goto unlock;
4125cd17decbSAndre Guedes 	}
4126cd17decbSAndre Guedes 
4127b644ba33SJohan Hedberg 	if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
412801fdb0fcSMarcel Holtmann 		mgmt_device_connected(hdev, &conn->dst, conn->type,
412995b23582SSzymon Janc 				      conn->dst_type, 0, NULL, 0, NULL);
413083bc71b4SVinicius Costa Gomes 
41317b5c0d52SVinicius Costa Gomes 	conn->sec_level = BT_SECURITY_LOW;
4132fcd89c09SVille Tervo 	conn->handle = __le16_to_cpu(ev->handle);
4133fcd89c09SVille Tervo 	conn->state = BT_CONNECTED;
4134fcd89c09SVille Tervo 
4135e04fde60SMarcel Holtmann 	conn->le_conn_interval = le16_to_cpu(ev->interval);
4136e04fde60SMarcel Holtmann 	conn->le_conn_latency = le16_to_cpu(ev->latency);
4137e04fde60SMarcel Holtmann 	conn->le_supv_timeout = le16_to_cpu(ev->supervision_timeout);
4138e04fde60SMarcel Holtmann 
4139fcd89c09SVille Tervo 	hci_conn_add_sysfs(conn);
4140fcd89c09SVille Tervo 
4141fcd89c09SVille Tervo 	hci_proto_connect_cfm(conn, ev->status);
4142fcd89c09SVille Tervo 
4143a4790dbdSAndre Guedes 	hci_pend_le_conn_del(hdev, &conn->dst, conn->dst_type);
4144a4790dbdSAndre Guedes 
4145fcd89c09SVille Tervo unlock:
4146fcd89c09SVille Tervo 	hci_dev_unlock(hdev);
4147fcd89c09SVille Tervo }
4148fcd89c09SVille Tervo 
41491855d92dSMarcel Holtmann static void hci_le_conn_update_complete_evt(struct hci_dev *hdev,
41501855d92dSMarcel Holtmann 					    struct sk_buff *skb)
41511855d92dSMarcel Holtmann {
41521855d92dSMarcel Holtmann 	struct hci_ev_le_conn_update_complete *ev = (void *) skb->data;
41531855d92dSMarcel Holtmann 	struct hci_conn *conn;
41541855d92dSMarcel Holtmann 
41551855d92dSMarcel Holtmann 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
41561855d92dSMarcel Holtmann 
41571855d92dSMarcel Holtmann 	if (ev->status)
41581855d92dSMarcel Holtmann 		return;
41591855d92dSMarcel Holtmann 
41601855d92dSMarcel Holtmann 	hci_dev_lock(hdev);
41611855d92dSMarcel Holtmann 
41621855d92dSMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
41631855d92dSMarcel Holtmann 	if (conn) {
41641855d92dSMarcel Holtmann 		conn->le_conn_interval = le16_to_cpu(ev->interval);
41651855d92dSMarcel Holtmann 		conn->le_conn_latency = le16_to_cpu(ev->latency);
41661855d92dSMarcel Holtmann 		conn->le_supv_timeout = le16_to_cpu(ev->supervision_timeout);
41671855d92dSMarcel Holtmann 	}
41681855d92dSMarcel Holtmann 
41691855d92dSMarcel Holtmann 	hci_dev_unlock(hdev);
41701855d92dSMarcel Holtmann }
41711855d92dSMarcel Holtmann 
4172a4790dbdSAndre Guedes /* This function requires the caller holds hdev->lock */
4173a4790dbdSAndre Guedes static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
4174a4790dbdSAndre Guedes 				  u8 addr_type)
4175a4790dbdSAndre Guedes {
4176a4790dbdSAndre Guedes 	struct hci_conn *conn;
41775b906a84SAndre Guedes 	struct smp_irk *irk;
41785b906a84SAndre Guedes 
41795b906a84SAndre Guedes 	/* If this is a resolvable address, we should resolve it and then
41805b906a84SAndre Guedes 	 * update address and address type variables.
41815b906a84SAndre Guedes 	 */
41825b906a84SAndre Guedes 	irk = hci_get_irk(hdev, addr, addr_type);
41835b906a84SAndre Guedes 	if (irk) {
41845b906a84SAndre Guedes 		addr = &irk->bdaddr;
41855b906a84SAndre Guedes 		addr_type = irk->addr_type;
41865b906a84SAndre Guedes 	}
4187a4790dbdSAndre Guedes 
4188a4790dbdSAndre Guedes 	if (!hci_pend_le_conn_lookup(hdev, addr, addr_type))
4189a4790dbdSAndre Guedes 		return;
4190a4790dbdSAndre Guedes 
4191a4790dbdSAndre Guedes 	conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW,
4192a4790dbdSAndre Guedes 			      HCI_AT_NO_BONDING);
4193a4790dbdSAndre Guedes 	if (!IS_ERR(conn))
4194a4790dbdSAndre Guedes 		return;
4195a4790dbdSAndre Guedes 
4196a4790dbdSAndre Guedes 	switch (PTR_ERR(conn)) {
4197a4790dbdSAndre Guedes 	case -EBUSY:
4198a4790dbdSAndre Guedes 		/* If hci_connect() returns -EBUSY it means there is already
4199a4790dbdSAndre Guedes 		 * an LE connection attempt going on. Since controllers don't
4200a4790dbdSAndre Guedes 		 * support more than one connection attempt at the time, we
4201a4790dbdSAndre Guedes 		 * don't consider this an error case.
4202a4790dbdSAndre Guedes 		 */
4203a4790dbdSAndre Guedes 		break;
4204a4790dbdSAndre Guedes 	default:
4205a4790dbdSAndre Guedes 		BT_DBG("Failed to connect: err %ld", PTR_ERR(conn));
4206a4790dbdSAndre Guedes 	}
4207a4790dbdSAndre Guedes }
4208a4790dbdSAndre Guedes 
42094af605d8SJohan Hedberg static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
42104af605d8SJohan Hedberg 			       u8 bdaddr_type, s8 rssi, u8 *data, u8 len)
42114af605d8SJohan Hedberg {
4212b9a6328fSJohan Hedberg 	struct discovery_state *d = &hdev->discovery;
4213474ee066SJohan Hedberg 	bool match;
4214c70a7e4cSMarcel Holtmann 	u32 flags;
4215b9a6328fSJohan Hedberg 
4216ca5c4be7SJohan Hedberg 	/* Passive scanning shouldn't trigger any device found events */
4217ca5c4be7SJohan Hedberg 	if (hdev->le_scan_type == LE_SCAN_PASSIVE) {
42184af605d8SJohan Hedberg 		if (type == LE_ADV_IND || type == LE_ADV_DIRECT_IND)
42194af605d8SJohan Hedberg 			check_pending_le_conn(hdev, bdaddr, bdaddr_type);
4220ca5c4be7SJohan Hedberg 		return;
4221ca5c4be7SJohan Hedberg 	}
42224af605d8SJohan Hedberg 
4223c70a7e4cSMarcel Holtmann 	/* When receiving non-connectable or scannable undirected
4224c70a7e4cSMarcel Holtmann 	 * advertising reports, this means that the remote device is
4225c70a7e4cSMarcel Holtmann 	 * not connectable and then clearly indicate this in the
4226c70a7e4cSMarcel Holtmann 	 * device found event.
4227c70a7e4cSMarcel Holtmann 	 *
4228c70a7e4cSMarcel Holtmann 	 * When receiving a scan response, then there is no way to
4229c70a7e4cSMarcel Holtmann 	 * know if the remote device is connectable or not. However
4230c70a7e4cSMarcel Holtmann 	 * since scan responses are merged with a previously seen
4231c70a7e4cSMarcel Holtmann 	 * advertising report, the flags field from that report
4232c70a7e4cSMarcel Holtmann 	 * will be used.
4233c70a7e4cSMarcel Holtmann 	 *
4234c70a7e4cSMarcel Holtmann 	 * In the really unlikely case that a controller get confused
4235c70a7e4cSMarcel Holtmann 	 * and just sends a scan response event, then it is marked as
4236c70a7e4cSMarcel Holtmann 	 * not connectable as well.
4237c70a7e4cSMarcel Holtmann 	 */
4238c70a7e4cSMarcel Holtmann 	if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND ||
4239c70a7e4cSMarcel Holtmann 	    type == LE_ADV_SCAN_RSP)
4240c70a7e4cSMarcel Holtmann 		flags = MGMT_DEV_FOUND_NOT_CONNECTABLE;
4241c70a7e4cSMarcel Holtmann 	else
4242c70a7e4cSMarcel Holtmann 		flags = 0;
4243c70a7e4cSMarcel Holtmann 
4244b9a6328fSJohan Hedberg 	/* If there's nothing pending either store the data from this
4245b9a6328fSJohan Hedberg 	 * event or send an immediate device found event if the data
4246b9a6328fSJohan Hedberg 	 * should not be stored for later.
4247b9a6328fSJohan Hedberg 	 */
4248b9a6328fSJohan Hedberg 	if (!has_pending_adv_report(hdev)) {
4249b9a6328fSJohan Hedberg 		/* If the report will trigger a SCAN_REQ store it for
4250b9a6328fSJohan Hedberg 		 * later merging.
4251b9a6328fSJohan Hedberg 		 */
4252b9a6328fSJohan Hedberg 		if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) {
4253b9a6328fSJohan Hedberg 			store_pending_adv_report(hdev, bdaddr, bdaddr_type,
4254c70a7e4cSMarcel Holtmann 						 rssi, flags, data, len);
4255b9a6328fSJohan Hedberg 			return;
4256b9a6328fSJohan Hedberg 		}
4257b9a6328fSJohan Hedberg 
4258b9a6328fSJohan Hedberg 		mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
4259c70a7e4cSMarcel Holtmann 				  rssi, flags, data, len, NULL, 0);
4260b9a6328fSJohan Hedberg 		return;
4261b9a6328fSJohan Hedberg 	}
4262b9a6328fSJohan Hedberg 
4263474ee066SJohan Hedberg 	/* Check if the pending report is for the same device as the new one */
4264474ee066SJohan Hedberg 	match = (!bacmp(bdaddr, &d->last_adv_addr) &&
4265474ee066SJohan Hedberg 		 bdaddr_type == d->last_adv_addr_type);
4266474ee066SJohan Hedberg 
4267b9a6328fSJohan Hedberg 	/* If the pending data doesn't match this report or this isn't a
4268b9a6328fSJohan Hedberg 	 * scan response (e.g. we got a duplicate ADV_IND) then force
4269b9a6328fSJohan Hedberg 	 * sending of the pending data.
4270b9a6328fSJohan Hedberg 	 */
4271474ee066SJohan Hedberg 	if (type != LE_ADV_SCAN_RSP || !match) {
4272474ee066SJohan Hedberg 		/* Send out whatever is in the cache, but skip duplicates */
4273474ee066SJohan Hedberg 		if (!match)
4274b9a6328fSJohan Hedberg 			mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
4275ff5cd29fSJohan Hedberg 					  d->last_adv_addr_type, NULL,
4276c70a7e4cSMarcel Holtmann 					  d->last_adv_rssi, d->last_adv_flags,
4277ff5cd29fSJohan Hedberg 					  d->last_adv_data,
4278474ee066SJohan Hedberg 					  d->last_adv_data_len, NULL, 0);
4279b9a6328fSJohan Hedberg 
4280b9a6328fSJohan Hedberg 		/* If the new report will trigger a SCAN_REQ store it for
4281b9a6328fSJohan Hedberg 		 * later merging.
4282b9a6328fSJohan Hedberg 		 */
4283b9a6328fSJohan Hedberg 		if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) {
4284b9a6328fSJohan Hedberg 			store_pending_adv_report(hdev, bdaddr, bdaddr_type,
4285c70a7e4cSMarcel Holtmann 						 rssi, flags, data, len);
4286b9a6328fSJohan Hedberg 			return;
4287b9a6328fSJohan Hedberg 		}
4288b9a6328fSJohan Hedberg 
4289b9a6328fSJohan Hedberg 		/* The advertising reports cannot be merged, so clear
4290b9a6328fSJohan Hedberg 		 * the pending report and send out a device found event.
4291b9a6328fSJohan Hedberg 		 */
4292b9a6328fSJohan Hedberg 		clear_pending_adv_report(hdev);
42935c5b93e4SJohan Hedberg 		mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
4294c70a7e4cSMarcel Holtmann 				  rssi, flags, data, len, NULL, 0);
4295b9a6328fSJohan Hedberg 		return;
4296b9a6328fSJohan Hedberg 	}
4297b9a6328fSJohan Hedberg 
4298b9a6328fSJohan Hedberg 	/* If we get here we've got a pending ADV_IND or ADV_SCAN_IND and
4299b9a6328fSJohan Hedberg 	 * the new event is a SCAN_RSP. We can therefore proceed with
4300b9a6328fSJohan Hedberg 	 * sending a merged device found event.
4301b9a6328fSJohan Hedberg 	 */
4302b9a6328fSJohan Hedberg 	mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
4303c70a7e4cSMarcel Holtmann 			  d->last_adv_addr_type, NULL, rssi, d->last_adv_flags,
430442bd6a56SMarcel Holtmann 			  d->last_adv_data, d->last_adv_data_len, data, len);
4305b9a6328fSJohan Hedberg 	clear_pending_adv_report(hdev);
43064af605d8SJohan Hedberg }
43074af605d8SJohan Hedberg 
43086039aa73SGustavo Padovan static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
43099aa04c91SAndre Guedes {
4310e95beb41SAndre Guedes 	u8 num_reports = skb->data[0];
4311e95beb41SAndre Guedes 	void *ptr = &skb->data[1];
43129aa04c91SAndre Guedes 
4313a4790dbdSAndre Guedes 	hci_dev_lock(hdev);
4314a4790dbdSAndre Guedes 
4315e95beb41SAndre Guedes 	while (num_reports--) {
4316e95beb41SAndre Guedes 		struct hci_ev_le_advertising_info *ev = ptr;
43174af605d8SJohan Hedberg 		s8 rssi;
4318a4790dbdSAndre Guedes 
43193c9e9195SAndre Guedes 		rssi = ev->data[ev->length];
43204af605d8SJohan Hedberg 		process_adv_report(hdev, ev->evt_type, &ev->bdaddr,
43214af605d8SJohan Hedberg 				   ev->bdaddr_type, rssi, ev->data, ev->length);
43223c9e9195SAndre Guedes 
4323e95beb41SAndre Guedes 		ptr += sizeof(*ev) + ev->length + 1;
43249aa04c91SAndre Guedes 	}
4325a4790dbdSAndre Guedes 
4326a4790dbdSAndre Guedes 	hci_dev_unlock(hdev);
43279aa04c91SAndre Guedes }
43289aa04c91SAndre Guedes 
43296039aa73SGustavo Padovan static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
4330a7a595f6SVinicius Costa Gomes {
4331a7a595f6SVinicius Costa Gomes 	struct hci_ev_le_ltk_req *ev = (void *) skb->data;
4332a7a595f6SVinicius Costa Gomes 	struct hci_cp_le_ltk_reply cp;
4333bea710feSVinicius Costa Gomes 	struct hci_cp_le_ltk_neg_reply neg;
4334a7a595f6SVinicius Costa Gomes 	struct hci_conn *conn;
4335c9839a11SVinicius Costa Gomes 	struct smp_ltk *ltk;
4336a7a595f6SVinicius Costa Gomes 
43379f1db00cSAndrei Emeltchenko 	BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
4338a7a595f6SVinicius Costa Gomes 
4339a7a595f6SVinicius Costa Gomes 	hci_dev_lock(hdev);
4340a7a595f6SVinicius Costa Gomes 
4341a7a595f6SVinicius Costa Gomes 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
4342bea710feSVinicius Costa Gomes 	if (conn == NULL)
4343bea710feSVinicius Costa Gomes 		goto not_found;
4344a7a595f6SVinicius Costa Gomes 
4345fe39c7b2SMarcel Holtmann 	ltk = hci_find_ltk(hdev, ev->ediv, ev->rand, conn->out);
4346bea710feSVinicius Costa Gomes 	if (ltk == NULL)
4347bea710feSVinicius Costa Gomes 		goto not_found;
4348bea710feSVinicius Costa Gomes 
4349bea710feSVinicius Costa Gomes 	memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
4350a7a595f6SVinicius Costa Gomes 	cp.handle = cpu_to_le16(conn->handle);
4351c9839a11SVinicius Costa Gomes 
4352c9839a11SVinicius Costa Gomes 	if (ltk->authenticated)
4353f8776218SAndre Guedes 		conn->pending_sec_level = BT_SECURITY_HIGH;
4354f8776218SAndre Guedes 	else
4355f8776218SAndre Guedes 		conn->pending_sec_level = BT_SECURITY_MEDIUM;
4356a7a595f6SVinicius Costa Gomes 
435789cbb4daSAndre Guedes 	conn->enc_key_size = ltk->enc_size;
4358a7a595f6SVinicius Costa Gomes 
4359a7a595f6SVinicius Costa Gomes 	hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
4360a7a595f6SVinicius Costa Gomes 
43615981a882SClaudio Takahasi 	/* Ref. Bluetooth Core SPEC pages 1975 and 2004. STK is a
43625981a882SClaudio Takahasi 	 * temporary key used to encrypt a connection following
43635981a882SClaudio Takahasi 	 * pairing. It is used during the Encrypted Session Setup to
43645981a882SClaudio Takahasi 	 * distribute the keys. Later, security can be re-established
43655981a882SClaudio Takahasi 	 * using a distributed LTK.
43665981a882SClaudio Takahasi 	 */
43672ceba539SJohan Hedberg 	if (ltk->type == SMP_STK) {
4368fe59a05fSJohan Hedberg 		set_bit(HCI_CONN_STK_ENCRYPT, &conn->flags);
4369c9839a11SVinicius Costa Gomes 		list_del(&ltk->list);
4370c9839a11SVinicius Costa Gomes 		kfree(ltk);
4371fe59a05fSJohan Hedberg 	} else {
4372fe59a05fSJohan Hedberg 		clear_bit(HCI_CONN_STK_ENCRYPT, &conn->flags);
4373c9839a11SVinicius Costa Gomes 	}
4374c9839a11SVinicius Costa Gomes 
4375a7a595f6SVinicius Costa Gomes 	hci_dev_unlock(hdev);
4376bea710feSVinicius Costa Gomes 
4377bea710feSVinicius Costa Gomes 	return;
4378bea710feSVinicius Costa Gomes 
4379bea710feSVinicius Costa Gomes not_found:
4380bea710feSVinicius Costa Gomes 	neg.handle = ev->handle;
4381bea710feSVinicius Costa Gomes 	hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
4382bea710feSVinicius Costa Gomes 	hci_dev_unlock(hdev);
4383a7a595f6SVinicius Costa Gomes }
4384a7a595f6SVinicius Costa Gomes 
4385*8e75b46aSAndre Guedes static void send_conn_param_neg_reply(struct hci_dev *hdev, u16 handle,
4386*8e75b46aSAndre Guedes 				      u8 reason)
4387*8e75b46aSAndre Guedes {
4388*8e75b46aSAndre Guedes 	struct hci_cp_le_conn_param_req_neg_reply cp;
4389*8e75b46aSAndre Guedes 
4390*8e75b46aSAndre Guedes 	cp.handle = cpu_to_le16(handle);
4391*8e75b46aSAndre Guedes 	cp.reason = reason;
4392*8e75b46aSAndre Guedes 
4393*8e75b46aSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY, sizeof(cp),
4394*8e75b46aSAndre Guedes 		     &cp);
4395*8e75b46aSAndre Guedes }
4396*8e75b46aSAndre Guedes 
4397*8e75b46aSAndre Guedes static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev,
4398*8e75b46aSAndre Guedes 					     struct sk_buff *skb)
4399*8e75b46aSAndre Guedes {
4400*8e75b46aSAndre Guedes 	struct hci_ev_le_remote_conn_param_req *ev = (void *) skb->data;
4401*8e75b46aSAndre Guedes 	struct hci_cp_le_conn_param_req_reply cp;
4402*8e75b46aSAndre Guedes 	struct hci_conn *hcon;
4403*8e75b46aSAndre Guedes 	u16 handle, min, max, latency, timeout;
4404*8e75b46aSAndre Guedes 
4405*8e75b46aSAndre Guedes 	handle = le16_to_cpu(ev->handle);
4406*8e75b46aSAndre Guedes 	min = le16_to_cpu(ev->interval_min);
4407*8e75b46aSAndre Guedes 	max = le16_to_cpu(ev->interval_max);
4408*8e75b46aSAndre Guedes 	latency = le16_to_cpu(ev->latency);
4409*8e75b46aSAndre Guedes 	timeout = le16_to_cpu(ev->timeout);
4410*8e75b46aSAndre Guedes 
4411*8e75b46aSAndre Guedes 	hcon = hci_conn_hash_lookup_handle(hdev, handle);
4412*8e75b46aSAndre Guedes 	if (!hcon || hcon->state != BT_CONNECTED)
4413*8e75b46aSAndre Guedes 		return send_conn_param_neg_reply(hdev, handle,
4414*8e75b46aSAndre Guedes 						 HCI_ERROR_UNKNOWN_CONN_ID);
4415*8e75b46aSAndre Guedes 
4416*8e75b46aSAndre Guedes 	if (hci_check_conn_params(min, max, latency, timeout))
4417*8e75b46aSAndre Guedes 		return send_conn_param_neg_reply(hdev, handle,
4418*8e75b46aSAndre Guedes 						 HCI_ERROR_INVALID_LL_PARAMS);
4419*8e75b46aSAndre Guedes 
4420*8e75b46aSAndre Guedes 	cp.handle = ev->handle;
4421*8e75b46aSAndre Guedes 	cp.interval_min = ev->interval_min;
4422*8e75b46aSAndre Guedes 	cp.interval_max = ev->interval_max;
4423*8e75b46aSAndre Guedes 	cp.latency = ev->latency;
4424*8e75b46aSAndre Guedes 	cp.timeout = ev->timeout;
4425*8e75b46aSAndre Guedes 	cp.min_ce_len = 0;
4426*8e75b46aSAndre Guedes 	cp.max_ce_len = 0;
4427*8e75b46aSAndre Guedes 
4428*8e75b46aSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_REPLY, sizeof(cp), &cp);
4429*8e75b46aSAndre Guedes }
4430*8e75b46aSAndre Guedes 
44316039aa73SGustavo Padovan static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
4432fcd89c09SVille Tervo {
4433fcd89c09SVille Tervo 	struct hci_ev_le_meta *le_ev = (void *) skb->data;
4434fcd89c09SVille Tervo 
4435fcd89c09SVille Tervo 	skb_pull(skb, sizeof(*le_ev));
4436fcd89c09SVille Tervo 
4437fcd89c09SVille Tervo 	switch (le_ev->subevent) {
4438fcd89c09SVille Tervo 	case HCI_EV_LE_CONN_COMPLETE:
4439fcd89c09SVille Tervo 		hci_le_conn_complete_evt(hdev, skb);
4440fcd89c09SVille Tervo 		break;
4441fcd89c09SVille Tervo 
44421855d92dSMarcel Holtmann 	case HCI_EV_LE_CONN_UPDATE_COMPLETE:
44431855d92dSMarcel Holtmann 		hci_le_conn_update_complete_evt(hdev, skb);
44441855d92dSMarcel Holtmann 		break;
44451855d92dSMarcel Holtmann 
44469aa04c91SAndre Guedes 	case HCI_EV_LE_ADVERTISING_REPORT:
44479aa04c91SAndre Guedes 		hci_le_adv_report_evt(hdev, skb);
44489aa04c91SAndre Guedes 		break;
44499aa04c91SAndre Guedes 
4450a7a595f6SVinicius Costa Gomes 	case HCI_EV_LE_LTK_REQ:
4451a7a595f6SVinicius Costa Gomes 		hci_le_ltk_request_evt(hdev, skb);
4452a7a595f6SVinicius Costa Gomes 		break;
4453a7a595f6SVinicius Costa Gomes 
4454*8e75b46aSAndre Guedes 	case HCI_EV_LE_REMOTE_CONN_PARAM_REQ:
4455*8e75b46aSAndre Guedes 		hci_le_remote_conn_param_req_evt(hdev, skb);
4456*8e75b46aSAndre Guedes 		break;
4457*8e75b46aSAndre Guedes 
4458fcd89c09SVille Tervo 	default:
4459fcd89c09SVille Tervo 		break;
4460fcd89c09SVille Tervo 	}
4461fcd89c09SVille Tervo }
4462fcd89c09SVille Tervo 
44639495b2eeSAndrei Emeltchenko static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
44649495b2eeSAndrei Emeltchenko {
44659495b2eeSAndrei Emeltchenko 	struct hci_ev_channel_selected *ev = (void *) skb->data;
44669495b2eeSAndrei Emeltchenko 	struct hci_conn *hcon;
44679495b2eeSAndrei Emeltchenko 
44689495b2eeSAndrei Emeltchenko 	BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
44699495b2eeSAndrei Emeltchenko 
44709495b2eeSAndrei Emeltchenko 	skb_pull(skb, sizeof(*ev));
44719495b2eeSAndrei Emeltchenko 
44729495b2eeSAndrei Emeltchenko 	hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
44739495b2eeSAndrei Emeltchenko 	if (!hcon)
44749495b2eeSAndrei Emeltchenko 		return;
44759495b2eeSAndrei Emeltchenko 
44769495b2eeSAndrei Emeltchenko 	amp_read_loc_assoc_final_data(hdev, hcon);
44779495b2eeSAndrei Emeltchenko }
44789495b2eeSAndrei Emeltchenko 
44791da177e4SLinus Torvalds void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
44801da177e4SLinus Torvalds {
4481a9de9248SMarcel Holtmann 	struct hci_event_hdr *hdr = (void *) skb->data;
4482a9de9248SMarcel Holtmann 	__u8 event = hdr->evt;
44831da177e4SLinus Torvalds 
4484b6ddb638SJohan Hedberg 	hci_dev_lock(hdev);
4485b6ddb638SJohan Hedberg 
4486b6ddb638SJohan Hedberg 	/* Received events are (currently) only needed when a request is
4487b6ddb638SJohan Hedberg 	 * ongoing so avoid unnecessary memory allocation.
4488b6ddb638SJohan Hedberg 	 */
4489b6ddb638SJohan Hedberg 	if (hdev->req_status == HCI_REQ_PEND) {
4490b6ddb638SJohan Hedberg 		kfree_skb(hdev->recv_evt);
4491b6ddb638SJohan Hedberg 		hdev->recv_evt = skb_clone(skb, GFP_KERNEL);
4492b6ddb638SJohan Hedberg 	}
4493b6ddb638SJohan Hedberg 
4494b6ddb638SJohan Hedberg 	hci_dev_unlock(hdev);
4495b6ddb638SJohan Hedberg 
44961da177e4SLinus Torvalds 	skb_pull(skb, HCI_EVENT_HDR_SIZE);
44971da177e4SLinus Torvalds 
449802350a72SJohan Hedberg 	if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
4499c1f23a2bSJohannes Berg 		struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data;
4500c1f23a2bSJohannes Berg 		u16 opcode = __le16_to_cpu(cmd_hdr->opcode);
450102350a72SJohan Hedberg 
450202350a72SJohan Hedberg 		hci_req_cmd_complete(hdev, opcode, 0);
450302350a72SJohan Hedberg 	}
450402350a72SJohan Hedberg 
4505a9de9248SMarcel Holtmann 	switch (event) {
45061da177e4SLinus Torvalds 	case HCI_EV_INQUIRY_COMPLETE:
45071da177e4SLinus Torvalds 		hci_inquiry_complete_evt(hdev, skb);
45081da177e4SLinus Torvalds 		break;
45091da177e4SLinus Torvalds 
45101da177e4SLinus Torvalds 	case HCI_EV_INQUIRY_RESULT:
45111da177e4SLinus Torvalds 		hci_inquiry_result_evt(hdev, skb);
45121da177e4SLinus Torvalds 		break;
45131da177e4SLinus Torvalds 
4514a9de9248SMarcel Holtmann 	case HCI_EV_CONN_COMPLETE:
4515a9de9248SMarcel Holtmann 		hci_conn_complete_evt(hdev, skb);
451621d9e30eSMarcel Holtmann 		break;
451721d9e30eSMarcel Holtmann 
45181da177e4SLinus Torvalds 	case HCI_EV_CONN_REQUEST:
45191da177e4SLinus Torvalds 		hci_conn_request_evt(hdev, skb);
45201da177e4SLinus Torvalds 		break;
45211da177e4SLinus Torvalds 
45221da177e4SLinus Torvalds 	case HCI_EV_DISCONN_COMPLETE:
45231da177e4SLinus Torvalds 		hci_disconn_complete_evt(hdev, skb);
45241da177e4SLinus Torvalds 		break;
45251da177e4SLinus Torvalds 
45261da177e4SLinus Torvalds 	case HCI_EV_AUTH_COMPLETE:
45271da177e4SLinus Torvalds 		hci_auth_complete_evt(hdev, skb);
45281da177e4SLinus Torvalds 		break;
45291da177e4SLinus Torvalds 
4530a9de9248SMarcel Holtmann 	case HCI_EV_REMOTE_NAME:
4531a9de9248SMarcel Holtmann 		hci_remote_name_evt(hdev, skb);
4532a9de9248SMarcel Holtmann 		break;
4533a9de9248SMarcel Holtmann 
45341da177e4SLinus Torvalds 	case HCI_EV_ENCRYPT_CHANGE:
45351da177e4SLinus Torvalds 		hci_encrypt_change_evt(hdev, skb);
45361da177e4SLinus Torvalds 		break;
45371da177e4SLinus Torvalds 
4538a9de9248SMarcel Holtmann 	case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
4539a9de9248SMarcel Holtmann 		hci_change_link_key_complete_evt(hdev, skb);
4540a9de9248SMarcel Holtmann 		break;
4541a9de9248SMarcel Holtmann 
4542a9de9248SMarcel Holtmann 	case HCI_EV_REMOTE_FEATURES:
4543a9de9248SMarcel Holtmann 		hci_remote_features_evt(hdev, skb);
4544a9de9248SMarcel Holtmann 		break;
4545a9de9248SMarcel Holtmann 
4546a9de9248SMarcel Holtmann 	case HCI_EV_CMD_COMPLETE:
4547a9de9248SMarcel Holtmann 		hci_cmd_complete_evt(hdev, skb);
4548a9de9248SMarcel Holtmann 		break;
4549a9de9248SMarcel Holtmann 
4550a9de9248SMarcel Holtmann 	case HCI_EV_CMD_STATUS:
4551a9de9248SMarcel Holtmann 		hci_cmd_status_evt(hdev, skb);
4552a9de9248SMarcel Holtmann 		break;
4553a9de9248SMarcel Holtmann 
4554a9de9248SMarcel Holtmann 	case HCI_EV_ROLE_CHANGE:
4555a9de9248SMarcel Holtmann 		hci_role_change_evt(hdev, skb);
4556a9de9248SMarcel Holtmann 		break;
4557a9de9248SMarcel Holtmann 
4558a9de9248SMarcel Holtmann 	case HCI_EV_NUM_COMP_PKTS:
4559a9de9248SMarcel Holtmann 		hci_num_comp_pkts_evt(hdev, skb);
4560a9de9248SMarcel Holtmann 		break;
4561a9de9248SMarcel Holtmann 
4562a9de9248SMarcel Holtmann 	case HCI_EV_MODE_CHANGE:
4563a9de9248SMarcel Holtmann 		hci_mode_change_evt(hdev, skb);
45641da177e4SLinus Torvalds 		break;
45651da177e4SLinus Torvalds 
45661da177e4SLinus Torvalds 	case HCI_EV_PIN_CODE_REQ:
45671da177e4SLinus Torvalds 		hci_pin_code_request_evt(hdev, skb);
45681da177e4SLinus Torvalds 		break;
45691da177e4SLinus Torvalds 
45701da177e4SLinus Torvalds 	case HCI_EV_LINK_KEY_REQ:
45711da177e4SLinus Torvalds 		hci_link_key_request_evt(hdev, skb);
45721da177e4SLinus Torvalds 		break;
45731da177e4SLinus Torvalds 
45741da177e4SLinus Torvalds 	case HCI_EV_LINK_KEY_NOTIFY:
45751da177e4SLinus Torvalds 		hci_link_key_notify_evt(hdev, skb);
45761da177e4SLinus Torvalds 		break;
45771da177e4SLinus Torvalds 
45781da177e4SLinus Torvalds 	case HCI_EV_CLOCK_OFFSET:
45791da177e4SLinus Torvalds 		hci_clock_offset_evt(hdev, skb);
45801da177e4SLinus Torvalds 		break;
45811da177e4SLinus Torvalds 
4582a8746417SMarcel Holtmann 	case HCI_EV_PKT_TYPE_CHANGE:
4583a8746417SMarcel Holtmann 		hci_pkt_type_change_evt(hdev, skb);
4584a8746417SMarcel Holtmann 		break;
4585a8746417SMarcel Holtmann 
458685a1e930SMarcel Holtmann 	case HCI_EV_PSCAN_REP_MODE:
458785a1e930SMarcel Holtmann 		hci_pscan_rep_mode_evt(hdev, skb);
458885a1e930SMarcel Holtmann 		break;
458985a1e930SMarcel Holtmann 
4590a9de9248SMarcel Holtmann 	case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
4591a9de9248SMarcel Holtmann 		hci_inquiry_result_with_rssi_evt(hdev, skb);
4592a9de9248SMarcel Holtmann 		break;
4593a9de9248SMarcel Holtmann 
4594a9de9248SMarcel Holtmann 	case HCI_EV_REMOTE_EXT_FEATURES:
4595a9de9248SMarcel Holtmann 		hci_remote_ext_features_evt(hdev, skb);
4596a9de9248SMarcel Holtmann 		break;
4597a9de9248SMarcel Holtmann 
4598a9de9248SMarcel Holtmann 	case HCI_EV_SYNC_CONN_COMPLETE:
4599a9de9248SMarcel Holtmann 		hci_sync_conn_complete_evt(hdev, skb);
4600a9de9248SMarcel Holtmann 		break;
4601a9de9248SMarcel Holtmann 
4602a9de9248SMarcel Holtmann 	case HCI_EV_EXTENDED_INQUIRY_RESULT:
4603a9de9248SMarcel Holtmann 		hci_extended_inquiry_result_evt(hdev, skb);
46041da177e4SLinus Torvalds 		break;
46051da177e4SLinus Torvalds 
46061c2e0041SJohan Hedberg 	case HCI_EV_KEY_REFRESH_COMPLETE:
46071c2e0041SJohan Hedberg 		hci_key_refresh_complete_evt(hdev, skb);
46081c2e0041SJohan Hedberg 		break;
46091c2e0041SJohan Hedberg 
46100493684eSMarcel Holtmann 	case HCI_EV_IO_CAPA_REQUEST:
46110493684eSMarcel Holtmann 		hci_io_capa_request_evt(hdev, skb);
46120493684eSMarcel Holtmann 		break;
46130493684eSMarcel Holtmann 
461403b555e1SJohan Hedberg 	case HCI_EV_IO_CAPA_REPLY:
461503b555e1SJohan Hedberg 		hci_io_capa_reply_evt(hdev, skb);
461603b555e1SJohan Hedberg 		break;
461703b555e1SJohan Hedberg 
4618a5c29683SJohan Hedberg 	case HCI_EV_USER_CONFIRM_REQUEST:
4619a5c29683SJohan Hedberg 		hci_user_confirm_request_evt(hdev, skb);
4620a5c29683SJohan Hedberg 		break;
4621a5c29683SJohan Hedberg 
46221143d458SBrian Gix 	case HCI_EV_USER_PASSKEY_REQUEST:
46231143d458SBrian Gix 		hci_user_passkey_request_evt(hdev, skb);
46241143d458SBrian Gix 		break;
46251143d458SBrian Gix 
462692a25256SJohan Hedberg 	case HCI_EV_USER_PASSKEY_NOTIFY:
462792a25256SJohan Hedberg 		hci_user_passkey_notify_evt(hdev, skb);
462892a25256SJohan Hedberg 		break;
462992a25256SJohan Hedberg 
463092a25256SJohan Hedberg 	case HCI_EV_KEYPRESS_NOTIFY:
463192a25256SJohan Hedberg 		hci_keypress_notify_evt(hdev, skb);
463292a25256SJohan Hedberg 		break;
463392a25256SJohan Hedberg 
46340493684eSMarcel Holtmann 	case HCI_EV_SIMPLE_PAIR_COMPLETE:
46350493684eSMarcel Holtmann 		hci_simple_pair_complete_evt(hdev, skb);
46360493684eSMarcel Holtmann 		break;
46370493684eSMarcel Holtmann 
463841a96212SMarcel Holtmann 	case HCI_EV_REMOTE_HOST_FEATURES:
463941a96212SMarcel Holtmann 		hci_remote_host_features_evt(hdev, skb);
464041a96212SMarcel Holtmann 		break;
464141a96212SMarcel Holtmann 
4642fcd89c09SVille Tervo 	case HCI_EV_LE_META:
4643fcd89c09SVille Tervo 		hci_le_meta_evt(hdev, skb);
4644fcd89c09SVille Tervo 		break;
4645fcd89c09SVille Tervo 
46469495b2eeSAndrei Emeltchenko 	case HCI_EV_CHANNEL_SELECTED:
46479495b2eeSAndrei Emeltchenko 		hci_chan_selected_evt(hdev, skb);
46489495b2eeSAndrei Emeltchenko 		break;
46499495b2eeSAndrei Emeltchenko 
46502763eda6SSzymon Janc 	case HCI_EV_REMOTE_OOB_DATA_REQUEST:
46512763eda6SSzymon Janc 		hci_remote_oob_data_request_evt(hdev, skb);
46522763eda6SSzymon Janc 		break;
46532763eda6SSzymon Janc 
4654d5e91192SAndrei Emeltchenko 	case HCI_EV_PHY_LINK_COMPLETE:
4655d5e91192SAndrei Emeltchenko 		hci_phy_link_complete_evt(hdev, skb);
4656d5e91192SAndrei Emeltchenko 		break;
4657d5e91192SAndrei Emeltchenko 
465827695fb4SAndrei Emeltchenko 	case HCI_EV_LOGICAL_LINK_COMPLETE:
465927695fb4SAndrei Emeltchenko 		hci_loglink_complete_evt(hdev, skb);
466027695fb4SAndrei Emeltchenko 		break;
466127695fb4SAndrei Emeltchenko 
4662606e2a10SAndrei Emeltchenko 	case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
4663606e2a10SAndrei Emeltchenko 		hci_disconn_loglink_complete_evt(hdev, skb);
4664606e2a10SAndrei Emeltchenko 		break;
4665606e2a10SAndrei Emeltchenko 
46669eef6b3aSAndrei Emeltchenko 	case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
46679eef6b3aSAndrei Emeltchenko 		hci_disconn_phylink_complete_evt(hdev, skb);
46689eef6b3aSAndrei Emeltchenko 		break;
46699eef6b3aSAndrei Emeltchenko 
467025e89e99SAndrei Emeltchenko 	case HCI_EV_NUM_COMP_BLOCKS:
467125e89e99SAndrei Emeltchenko 		hci_num_comp_blocks_evt(hdev, skb);
467225e89e99SAndrei Emeltchenko 		break;
467325e89e99SAndrei Emeltchenko 
46741da177e4SLinus Torvalds 	default:
46759f1db00cSAndrei Emeltchenko 		BT_DBG("%s event 0x%2.2x", hdev->name, event);
46761da177e4SLinus Torvalds 		break;
46771da177e4SLinus Torvalds 	}
46781da177e4SLinus Torvalds 
46791da177e4SLinus Torvalds 	kfree_skb(skb);
46801da177e4SLinus Torvalds 	hdev->stat.evt_rx++;
46811da177e4SLinus Torvalds }
4682