xref: /openbmc/linux/net/bluetooth/hci_event.c (revision b312b161)
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 <linux/module.h>
281da177e4SLinus Torvalds 
291da177e4SLinus Torvalds #include <linux/types.h>
301da177e4SLinus Torvalds #include <linux/errno.h>
311da177e4SLinus Torvalds #include <linux/kernel.h>
321da177e4SLinus Torvalds #include <linux/slab.h>
331da177e4SLinus Torvalds #include <linux/poll.h>
341da177e4SLinus Torvalds #include <linux/fcntl.h>
351da177e4SLinus Torvalds #include <linux/init.h>
361da177e4SLinus Torvalds #include <linux/skbuff.h>
371da177e4SLinus Torvalds #include <linux/interrupt.h>
381da177e4SLinus Torvalds #include <linux/notifier.h>
391da177e4SLinus Torvalds #include <net/sock.h>
401da177e4SLinus Torvalds 
411da177e4SLinus Torvalds #include <asm/system.h>
4270f23020SAndrei Emeltchenko #include <linux/uaccess.h>
431da177e4SLinus Torvalds #include <asm/unaligned.h>
441da177e4SLinus Torvalds 
451da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
461da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
471da177e4SLinus Torvalds 
481da177e4SLinus Torvalds /* Handle HCI Event packets */
491da177e4SLinus Torvalds 
50a9de9248SMarcel Holtmann static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
511da177e4SLinus Torvalds {
52a9de9248SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
531da177e4SLinus Torvalds 
54a9de9248SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, status);
551da177e4SLinus Torvalds 
56a9de9248SMarcel Holtmann 	if (status)
57a9de9248SMarcel Holtmann 		return;
581da177e4SLinus Torvalds 
591da177e4SLinus Torvalds 	clear_bit(HCI_INQUIRY, &hdev->flags);
60a9de9248SMarcel Holtmann 
6123bb5763SJohan Hedberg 	hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
62a9de9248SMarcel Holtmann 
63a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
641da177e4SLinus Torvalds }
656bd57416SMarcel Holtmann 
66a9de9248SMarcel Holtmann static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
671da177e4SLinus Torvalds {
68a9de9248SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
69a9de9248SMarcel Holtmann 
70a9de9248SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, status);
71a9de9248SMarcel Holtmann 
72a9de9248SMarcel Holtmann 	if (status)
73a9de9248SMarcel Holtmann 		return;
74a9de9248SMarcel Holtmann 
75a9de9248SMarcel Holtmann 	clear_bit(HCI_INQUIRY, &hdev->flags);
76a9de9248SMarcel Holtmann 
77a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
78a9de9248SMarcel Holtmann }
79a9de9248SMarcel Holtmann 
80a9de9248SMarcel Holtmann static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb)
81a9de9248SMarcel Holtmann {
82a9de9248SMarcel Holtmann 	BT_DBG("%s", hdev->name);
83a9de9248SMarcel Holtmann }
84a9de9248SMarcel Holtmann 
85a9de9248SMarcel Holtmann static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
86a9de9248SMarcel Holtmann {
87a9de9248SMarcel Holtmann 	struct hci_rp_role_discovery *rp = (void *) skb->data;
881da177e4SLinus Torvalds 	struct hci_conn *conn;
891da177e4SLinus Torvalds 
90a9de9248SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, rp->status);
911da177e4SLinus Torvalds 
92a9de9248SMarcel Holtmann 	if (rp->status)
93a9de9248SMarcel Holtmann 		return;
941da177e4SLinus Torvalds 
951da177e4SLinus Torvalds 	hci_dev_lock(hdev);
961da177e4SLinus Torvalds 
97a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
981da177e4SLinus Torvalds 	if (conn) {
99a9de9248SMarcel Holtmann 		if (rp->role)
1001da177e4SLinus Torvalds 			conn->link_mode &= ~HCI_LM_MASTER;
1011da177e4SLinus Torvalds 		else
1021da177e4SLinus Torvalds 			conn->link_mode |= HCI_LM_MASTER;
1031da177e4SLinus Torvalds 	}
1041da177e4SLinus Torvalds 
1051da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
106a9de9248SMarcel Holtmann }
1071da177e4SLinus Torvalds 
108e4e8e37cSMarcel Holtmann static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
109e4e8e37cSMarcel Holtmann {
110e4e8e37cSMarcel Holtmann 	struct hci_rp_read_link_policy *rp = (void *) skb->data;
111e4e8e37cSMarcel Holtmann 	struct hci_conn *conn;
112e4e8e37cSMarcel Holtmann 
113e4e8e37cSMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, rp->status);
114e4e8e37cSMarcel Holtmann 
115e4e8e37cSMarcel Holtmann 	if (rp->status)
116e4e8e37cSMarcel Holtmann 		return;
117e4e8e37cSMarcel Holtmann 
118e4e8e37cSMarcel Holtmann 	hci_dev_lock(hdev);
119e4e8e37cSMarcel Holtmann 
120e4e8e37cSMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
121e4e8e37cSMarcel Holtmann 	if (conn)
122e4e8e37cSMarcel Holtmann 		conn->link_policy = __le16_to_cpu(rp->policy);
123e4e8e37cSMarcel Holtmann 
124e4e8e37cSMarcel Holtmann 	hci_dev_unlock(hdev);
125e4e8e37cSMarcel Holtmann }
126e4e8e37cSMarcel Holtmann 
127a9de9248SMarcel Holtmann static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
128a9de9248SMarcel Holtmann {
129a9de9248SMarcel Holtmann 	struct hci_rp_write_link_policy *rp = (void *) skb->data;
130a9de9248SMarcel Holtmann 	struct hci_conn *conn;
131a9de9248SMarcel Holtmann 	void *sent;
132a9de9248SMarcel Holtmann 
133a9de9248SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, rp->status);
134a9de9248SMarcel Holtmann 
135a9de9248SMarcel Holtmann 	if (rp->status)
136a9de9248SMarcel Holtmann 		return;
137a9de9248SMarcel Holtmann 
138a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
13904837f64SMarcel Holtmann 	if (!sent)
140a9de9248SMarcel Holtmann 		return;
14104837f64SMarcel Holtmann 
14204837f64SMarcel Holtmann 	hci_dev_lock(hdev);
14304837f64SMarcel Holtmann 
144a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
145e4e8e37cSMarcel Holtmann 	if (conn)
14683985319SHarvey Harrison 		conn->link_policy = get_unaligned_le16(sent + 2);
14704837f64SMarcel Holtmann 
14804837f64SMarcel Holtmann 	hci_dev_unlock(hdev);
1491da177e4SLinus Torvalds }
1501da177e4SLinus Torvalds 
151e4e8e37cSMarcel Holtmann static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
152e4e8e37cSMarcel Holtmann {
153e4e8e37cSMarcel Holtmann 	struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
154e4e8e37cSMarcel Holtmann 
155e4e8e37cSMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, rp->status);
156e4e8e37cSMarcel Holtmann 
157e4e8e37cSMarcel Holtmann 	if (rp->status)
158e4e8e37cSMarcel Holtmann 		return;
159e4e8e37cSMarcel Holtmann 
160e4e8e37cSMarcel Holtmann 	hdev->link_policy = __le16_to_cpu(rp->policy);
161e4e8e37cSMarcel Holtmann }
162e4e8e37cSMarcel Holtmann 
163e4e8e37cSMarcel Holtmann static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
164e4e8e37cSMarcel Holtmann {
165e4e8e37cSMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
166e4e8e37cSMarcel Holtmann 	void *sent;
167e4e8e37cSMarcel Holtmann 
168e4e8e37cSMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, status);
169e4e8e37cSMarcel Holtmann 
170e4e8e37cSMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
171e4e8e37cSMarcel Holtmann 	if (!sent)
172e4e8e37cSMarcel Holtmann 		return;
173e4e8e37cSMarcel Holtmann 
174e4e8e37cSMarcel Holtmann 	if (!status)
175e4e8e37cSMarcel Holtmann 		hdev->link_policy = get_unaligned_le16(sent);
176e4e8e37cSMarcel Holtmann 
17723bb5763SJohan Hedberg 	hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status);
178e4e8e37cSMarcel Holtmann }
179e4e8e37cSMarcel Holtmann 
180a9de9248SMarcel Holtmann static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
1811da177e4SLinus Torvalds {
182a9de9248SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
183a9de9248SMarcel Holtmann 
184a9de9248SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, status);
185a9de9248SMarcel Holtmann 
18623bb5763SJohan Hedberg 	hci_req_complete(hdev, HCI_OP_RESET, status);
187a9de9248SMarcel Holtmann }
188a9de9248SMarcel Holtmann 
189a9de9248SMarcel Holtmann static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
190a9de9248SMarcel Holtmann {
191a9de9248SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
1921da177e4SLinus Torvalds 	void *sent;
1931da177e4SLinus Torvalds 
194a9de9248SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, status);
1951da177e4SLinus Torvalds 
196a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
1971da177e4SLinus Torvalds 	if (!sent)
198a9de9248SMarcel Holtmann 		return;
1991da177e4SLinus Torvalds 
200b312b161SJohan Hedberg 	if (test_bit(HCI_MGMT, &hdev->flags))
201b312b161SJohan Hedberg 		mgmt_set_local_name_complete(hdev->id, sent, status);
202b312b161SJohan Hedberg 
203b312b161SJohan Hedberg 	if (status)
204b312b161SJohan Hedberg 		return;
205b312b161SJohan Hedberg 
2061f6c6378SJohan Hedberg 	memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
207a9de9248SMarcel Holtmann }
208a9de9248SMarcel Holtmann 
209a9de9248SMarcel Holtmann static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
210a9de9248SMarcel Holtmann {
211a9de9248SMarcel Holtmann 	struct hci_rp_read_local_name *rp = (void *) skb->data;
212a9de9248SMarcel Holtmann 
213a9de9248SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, rp->status);
214a9de9248SMarcel Holtmann 
215a9de9248SMarcel Holtmann 	if (rp->status)
216a9de9248SMarcel Holtmann 		return;
217a9de9248SMarcel Holtmann 
2181f6c6378SJohan Hedberg 	memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
219a9de9248SMarcel Holtmann }
220a9de9248SMarcel Holtmann 
221a9de9248SMarcel Holtmann static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
222a9de9248SMarcel Holtmann {
223a9de9248SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
224a9de9248SMarcel Holtmann 	void *sent;
225a9de9248SMarcel Holtmann 
226a9de9248SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, status);
227a9de9248SMarcel Holtmann 
228a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
229a9de9248SMarcel Holtmann 	if (!sent)
230a9de9248SMarcel Holtmann 		return;
2311da177e4SLinus Torvalds 
2321da177e4SLinus Torvalds 	if (!status) {
233a9de9248SMarcel Holtmann 		__u8 param = *((__u8 *) sent);
234a9de9248SMarcel Holtmann 
2351da177e4SLinus Torvalds 		if (param == AUTH_ENABLED)
2361da177e4SLinus Torvalds 			set_bit(HCI_AUTH, &hdev->flags);
2371da177e4SLinus Torvalds 		else
2381da177e4SLinus Torvalds 			clear_bit(HCI_AUTH, &hdev->flags);
2391da177e4SLinus Torvalds 	}
240a9de9248SMarcel Holtmann 
24123bb5763SJohan Hedberg 	hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
242a9de9248SMarcel Holtmann }
2431da177e4SLinus Torvalds 
244a9de9248SMarcel Holtmann static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
245a9de9248SMarcel Holtmann {
246a9de9248SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
247a9de9248SMarcel Holtmann 	void *sent;
248a9de9248SMarcel Holtmann 
249a9de9248SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, status);
250a9de9248SMarcel Holtmann 
251a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
2521da177e4SLinus Torvalds 	if (!sent)
253a9de9248SMarcel Holtmann 		return;
2541da177e4SLinus Torvalds 
2551da177e4SLinus Torvalds 	if (!status) {
256a9de9248SMarcel Holtmann 		__u8 param = *((__u8 *) sent);
257a9de9248SMarcel Holtmann 
2581da177e4SLinus Torvalds 		if (param)
2591da177e4SLinus Torvalds 			set_bit(HCI_ENCRYPT, &hdev->flags);
2601da177e4SLinus Torvalds 		else
2611da177e4SLinus Torvalds 			clear_bit(HCI_ENCRYPT, &hdev->flags);
2621da177e4SLinus Torvalds 	}
263a9de9248SMarcel Holtmann 
26423bb5763SJohan Hedberg 	hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
2651da177e4SLinus Torvalds }
2661da177e4SLinus Torvalds 
267a9de9248SMarcel Holtmann static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
268a9de9248SMarcel Holtmann {
269a9de9248SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
270a9de9248SMarcel Holtmann 	void *sent;
2711da177e4SLinus Torvalds 
272a9de9248SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, status);
273a9de9248SMarcel Holtmann 
274a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
2751da177e4SLinus Torvalds 	if (!sent)
276a9de9248SMarcel Holtmann 		return;
2771da177e4SLinus Torvalds 
2781da177e4SLinus Torvalds 	if (!status) {
279a9de9248SMarcel Holtmann 		__u8 param = *((__u8 *) sent);
2809fbcbb45SJohan Hedberg 		int old_pscan, old_iscan;
281a9de9248SMarcel Holtmann 
2829fbcbb45SJohan Hedberg 		old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
2839fbcbb45SJohan Hedberg 		old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
284a9de9248SMarcel Holtmann 
28573f22f62SJohan Hedberg 		if (param & SCAN_INQUIRY) {
2861da177e4SLinus Torvalds 			set_bit(HCI_ISCAN, &hdev->flags);
2879fbcbb45SJohan Hedberg 			if (!old_iscan)
28873f22f62SJohan Hedberg 				mgmt_discoverable(hdev->id, 1);
2899fbcbb45SJohan Hedberg 		} else if (old_iscan)
29073f22f62SJohan Hedberg 			mgmt_discoverable(hdev->id, 0);
2911da177e4SLinus Torvalds 
2929fbcbb45SJohan Hedberg 		if (param & SCAN_PAGE) {
2931da177e4SLinus Torvalds 			set_bit(HCI_PSCAN, &hdev->flags);
2949fbcbb45SJohan Hedberg 			if (!old_pscan)
2959fbcbb45SJohan Hedberg 				mgmt_connectable(hdev->id, 1);
2969fbcbb45SJohan Hedberg 		} else if (old_pscan)
2979fbcbb45SJohan Hedberg 			mgmt_connectable(hdev->id, 0);
2981da177e4SLinus Torvalds 	}
299a9de9248SMarcel Holtmann 
30023bb5763SJohan Hedberg 	hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
3011da177e4SLinus Torvalds }
3021da177e4SLinus Torvalds 
303a9de9248SMarcel Holtmann static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
304a9de9248SMarcel Holtmann {
305a9de9248SMarcel Holtmann 	struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
306a9de9248SMarcel Holtmann 
307a9de9248SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, rp->status);
308a9de9248SMarcel Holtmann 
309a9de9248SMarcel Holtmann 	if (rp->status)
310a9de9248SMarcel Holtmann 		return;
311a9de9248SMarcel Holtmann 
312a9de9248SMarcel Holtmann 	memcpy(hdev->dev_class, rp->dev_class, 3);
313a9de9248SMarcel Holtmann 
314a9de9248SMarcel Holtmann 	BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
315a9de9248SMarcel Holtmann 		hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
316a9de9248SMarcel Holtmann }
317a9de9248SMarcel Holtmann 
318a9de9248SMarcel Holtmann static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
319a9de9248SMarcel Holtmann {
320a9de9248SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
321a9de9248SMarcel Holtmann 	void *sent;
322a9de9248SMarcel Holtmann 
323a9de9248SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, status);
324a9de9248SMarcel Holtmann 
325f383f275SMarcel Holtmann 	if (status)
326f383f275SMarcel Holtmann 		return;
327f383f275SMarcel Holtmann 
328a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
329a9de9248SMarcel Holtmann 	if (!sent)
330a9de9248SMarcel Holtmann 		return;
331a9de9248SMarcel Holtmann 
332a9de9248SMarcel Holtmann 	memcpy(hdev->dev_class, sent, 3);
333a9de9248SMarcel Holtmann }
334a9de9248SMarcel Holtmann 
335a9de9248SMarcel Holtmann static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
336a9de9248SMarcel Holtmann {
337a9de9248SMarcel Holtmann 	struct hci_rp_read_voice_setting *rp = (void *) skb->data;
338a9de9248SMarcel Holtmann 	__u16 setting;
339a9de9248SMarcel Holtmann 
340a9de9248SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, rp->status);
341a9de9248SMarcel Holtmann 
342a9de9248SMarcel Holtmann 	if (rp->status)
343a9de9248SMarcel Holtmann 		return;
344a9de9248SMarcel Holtmann 
345a9de9248SMarcel Holtmann 	setting = __le16_to_cpu(rp->voice_setting);
346a9de9248SMarcel Holtmann 
347a9de9248SMarcel Holtmann 	if (hdev->voice_setting == setting)
348a9de9248SMarcel Holtmann 		return;
349a9de9248SMarcel Holtmann 
350a9de9248SMarcel Holtmann 	hdev->voice_setting = setting;
351a9de9248SMarcel Holtmann 
352a9de9248SMarcel Holtmann 	BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
353a9de9248SMarcel Holtmann 
354a9de9248SMarcel Holtmann 	if (hdev->notify) {
355a9de9248SMarcel Holtmann 		tasklet_disable(&hdev->tx_task);
356a9de9248SMarcel Holtmann 		hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
357a9de9248SMarcel Holtmann 		tasklet_enable(&hdev->tx_task);
358a9de9248SMarcel Holtmann 	}
359a9de9248SMarcel Holtmann }
360a9de9248SMarcel Holtmann 
361a9de9248SMarcel Holtmann static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
362a9de9248SMarcel Holtmann {
363a9de9248SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
364f383f275SMarcel Holtmann 	__u16 setting;
365a9de9248SMarcel Holtmann 	void *sent;
366a9de9248SMarcel Holtmann 
367a9de9248SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, status);
368a9de9248SMarcel Holtmann 
369f383f275SMarcel Holtmann 	if (status)
370f383f275SMarcel Holtmann 		return;
371f383f275SMarcel Holtmann 
372a9de9248SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
373a9de9248SMarcel Holtmann 	if (!sent)
374a9de9248SMarcel Holtmann 		return;
375a9de9248SMarcel Holtmann 
376f383f275SMarcel Holtmann 	setting = get_unaligned_le16(sent);
3771da177e4SLinus Torvalds 
378f383f275SMarcel Holtmann 	if (hdev->voice_setting == setting)
379f383f275SMarcel Holtmann 		return;
380f383f275SMarcel Holtmann 
3811da177e4SLinus Torvalds 	hdev->voice_setting = setting;
3821da177e4SLinus Torvalds 
383a9de9248SMarcel Holtmann 	BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
3841da177e4SLinus Torvalds 
3851da177e4SLinus Torvalds 	if (hdev->notify) {
3861da177e4SLinus Torvalds 		tasklet_disable(&hdev->tx_task);
3871da177e4SLinus Torvalds 		hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
3881da177e4SLinus Torvalds 		tasklet_enable(&hdev->tx_task);
3891da177e4SLinus Torvalds 	}
3901da177e4SLinus Torvalds }
3911da177e4SLinus Torvalds 
392a9de9248SMarcel Holtmann static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
3931da177e4SLinus Torvalds {
394a9de9248SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
3951da177e4SLinus Torvalds 
396a9de9248SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, status);
3971da177e4SLinus Torvalds 
39823bb5763SJohan Hedberg 	hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
3991143e5a6SMarcel Holtmann }
4001143e5a6SMarcel Holtmann 
401333140b5SMarcel Holtmann static void hci_cc_read_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
402333140b5SMarcel Holtmann {
403333140b5SMarcel Holtmann 	struct hci_rp_read_ssp_mode *rp = (void *) skb->data;
404333140b5SMarcel Holtmann 
405333140b5SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, rp->status);
406333140b5SMarcel Holtmann 
407333140b5SMarcel Holtmann 	if (rp->status)
408333140b5SMarcel Holtmann 		return;
409333140b5SMarcel Holtmann 
410333140b5SMarcel Holtmann 	hdev->ssp_mode = rp->mode;
411333140b5SMarcel Holtmann }
412333140b5SMarcel Holtmann 
413333140b5SMarcel Holtmann static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
414333140b5SMarcel Holtmann {
415333140b5SMarcel Holtmann 	__u8 status = *((__u8 *) skb->data);
416333140b5SMarcel Holtmann 	void *sent;
417333140b5SMarcel Holtmann 
418333140b5SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, status);
419333140b5SMarcel Holtmann 
420333140b5SMarcel Holtmann 	if (status)
421333140b5SMarcel Holtmann 		return;
422333140b5SMarcel Holtmann 
423333140b5SMarcel Holtmann 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
424333140b5SMarcel Holtmann 	if (!sent)
425333140b5SMarcel Holtmann 		return;
426333140b5SMarcel Holtmann 
427333140b5SMarcel Holtmann 	hdev->ssp_mode = *((__u8 *) sent);
428333140b5SMarcel Holtmann }
429333140b5SMarcel Holtmann 
430d5859e22SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
431d5859e22SJohan Hedberg {
432d5859e22SJohan Hedberg 	if (hdev->features[6] & LMP_EXT_INQ)
433d5859e22SJohan Hedberg 		return 2;
434d5859e22SJohan Hedberg 
435d5859e22SJohan Hedberg 	if (hdev->features[3] & LMP_RSSI_INQ)
436d5859e22SJohan Hedberg 		return 1;
437d5859e22SJohan Hedberg 
438d5859e22SJohan Hedberg 	if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
439d5859e22SJohan Hedberg 						hdev->lmp_subver == 0x0757)
440d5859e22SJohan Hedberg 		return 1;
441d5859e22SJohan Hedberg 
442d5859e22SJohan Hedberg 	if (hdev->manufacturer == 15) {
443d5859e22SJohan Hedberg 		if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
444d5859e22SJohan Hedberg 			return 1;
445d5859e22SJohan Hedberg 		if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
446d5859e22SJohan Hedberg 			return 1;
447d5859e22SJohan Hedberg 		if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
448d5859e22SJohan Hedberg 			return 1;
449d5859e22SJohan Hedberg 	}
450d5859e22SJohan Hedberg 
451d5859e22SJohan Hedberg 	if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
452d5859e22SJohan Hedberg 						hdev->lmp_subver == 0x1805)
453d5859e22SJohan Hedberg 		return 1;
454d5859e22SJohan Hedberg 
455d5859e22SJohan Hedberg 	return 0;
456d5859e22SJohan Hedberg }
457d5859e22SJohan Hedberg 
458d5859e22SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_dev *hdev)
459d5859e22SJohan Hedberg {
460d5859e22SJohan Hedberg 	u8 mode;
461d5859e22SJohan Hedberg 
462d5859e22SJohan Hedberg 	mode = hci_get_inquiry_mode(hdev);
463d5859e22SJohan Hedberg 
464d5859e22SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
465d5859e22SJohan Hedberg }
466d5859e22SJohan Hedberg 
467d5859e22SJohan Hedberg static void hci_setup_event_mask(struct hci_dev *hdev)
468d5859e22SJohan Hedberg {
469d5859e22SJohan Hedberg 	/* The second byte is 0xff instead of 0x9f (two reserved bits
470d5859e22SJohan Hedberg 	 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
471d5859e22SJohan Hedberg 	 * command otherwise */
472d5859e22SJohan Hedberg 	u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
473d5859e22SJohan Hedberg 
474d5859e22SJohan Hedberg 	/* Events for 1.2 and newer controllers */
475d5859e22SJohan Hedberg 	if (hdev->lmp_ver > 1) {
476d5859e22SJohan Hedberg 		events[4] |= 0x01; /* Flow Specification Complete */
477d5859e22SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
478d5859e22SJohan Hedberg 		events[4] |= 0x04; /* Read Remote Extended Features Complete */
479d5859e22SJohan Hedberg 		events[5] |= 0x08; /* Synchronous Connection Complete */
480d5859e22SJohan Hedberg 		events[5] |= 0x10; /* Synchronous Connection Changed */
481d5859e22SJohan Hedberg 	}
482d5859e22SJohan Hedberg 
483d5859e22SJohan Hedberg 	if (hdev->features[3] & LMP_RSSI_INQ)
484d5859e22SJohan Hedberg 		events[4] |= 0x04; /* Inquiry Result with RSSI */
485d5859e22SJohan Hedberg 
486d5859e22SJohan Hedberg 	if (hdev->features[5] & LMP_SNIFF_SUBR)
487d5859e22SJohan Hedberg 		events[5] |= 0x20; /* Sniff Subrating */
488d5859e22SJohan Hedberg 
489d5859e22SJohan Hedberg 	if (hdev->features[5] & LMP_PAUSE_ENC)
490d5859e22SJohan Hedberg 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
491d5859e22SJohan Hedberg 
492d5859e22SJohan Hedberg 	if (hdev->features[6] & LMP_EXT_INQ)
493d5859e22SJohan Hedberg 		events[5] |= 0x40; /* Extended Inquiry Result */
494d5859e22SJohan Hedberg 
495d5859e22SJohan Hedberg 	if (hdev->features[6] & LMP_NO_FLUSH)
496d5859e22SJohan Hedberg 		events[7] |= 0x01; /* Enhanced Flush Complete */
497d5859e22SJohan Hedberg 
498d5859e22SJohan Hedberg 	if (hdev->features[7] & LMP_LSTO)
499d5859e22SJohan Hedberg 		events[6] |= 0x80; /* Link Supervision Timeout Changed */
500d5859e22SJohan Hedberg 
501d5859e22SJohan Hedberg 	if (hdev->features[6] & LMP_SIMPLE_PAIR) {
502d5859e22SJohan Hedberg 		events[6] |= 0x01;	/* IO Capability Request */
503d5859e22SJohan Hedberg 		events[6] |= 0x02;	/* IO Capability Response */
504d5859e22SJohan Hedberg 		events[6] |= 0x04;	/* User Confirmation Request */
505d5859e22SJohan Hedberg 		events[6] |= 0x08;	/* User Passkey Request */
506d5859e22SJohan Hedberg 		events[6] |= 0x10;	/* Remote OOB Data Request */
507d5859e22SJohan Hedberg 		events[6] |= 0x20;	/* Simple Pairing Complete */
508d5859e22SJohan Hedberg 		events[7] |= 0x04;	/* User Passkey Notification */
509d5859e22SJohan Hedberg 		events[7] |= 0x08;	/* Keypress Notification */
510d5859e22SJohan Hedberg 		events[7] |= 0x10;	/* Remote Host Supported
511d5859e22SJohan Hedberg 					 * Features Notification */
512d5859e22SJohan Hedberg 	}
513d5859e22SJohan Hedberg 
514d5859e22SJohan Hedberg 	if (hdev->features[4] & LMP_LE)
515d5859e22SJohan Hedberg 		events[7] |= 0x20;	/* LE Meta-Event */
516d5859e22SJohan Hedberg 
517d5859e22SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
518d5859e22SJohan Hedberg }
519d5859e22SJohan Hedberg 
520d5859e22SJohan Hedberg static void hci_setup(struct hci_dev *hdev)
521d5859e22SJohan Hedberg {
522d5859e22SJohan Hedberg 	hci_setup_event_mask(hdev);
523d5859e22SJohan Hedberg 
524d5859e22SJohan Hedberg 	if (hdev->lmp_ver > 1)
525d5859e22SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
526d5859e22SJohan Hedberg 
527d5859e22SJohan Hedberg 	if (hdev->features[6] & LMP_SIMPLE_PAIR) {
528d5859e22SJohan Hedberg 		u8 mode = 0x01;
529d5859e22SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, sizeof(mode), &mode);
530d5859e22SJohan Hedberg 	}
531d5859e22SJohan Hedberg 
532d5859e22SJohan Hedberg 	if (hdev->features[3] & LMP_RSSI_INQ)
533d5859e22SJohan Hedberg 		hci_setup_inquiry_mode(hdev);
534d5859e22SJohan Hedberg 
535d5859e22SJohan Hedberg 	if (hdev->features[7] & LMP_INQ_TX_PWR)
536d5859e22SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
537d5859e22SJohan Hedberg }
538d5859e22SJohan Hedberg 
539a9de9248SMarcel Holtmann static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
540a9de9248SMarcel Holtmann {
541a9de9248SMarcel Holtmann 	struct hci_rp_read_local_version *rp = (void *) skb->data;
5421143e5a6SMarcel Holtmann 
543a9de9248SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, rp->status);
5441143e5a6SMarcel Holtmann 
545a9de9248SMarcel Holtmann 	if (rp->status)
546a9de9248SMarcel Holtmann 		return;
5471143e5a6SMarcel Holtmann 
548a9de9248SMarcel Holtmann 	hdev->hci_ver = rp->hci_ver;
549e4e8e37cSMarcel Holtmann 	hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
550d5859e22SJohan Hedberg 	hdev->lmp_ver = rp->lmp_ver;
551e4e8e37cSMarcel Holtmann 	hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
552d5859e22SJohan Hedberg 	hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
5531da177e4SLinus Torvalds 
554a9de9248SMarcel Holtmann 	BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
555a9de9248SMarcel Holtmann 					hdev->manufacturer,
556a9de9248SMarcel Holtmann 					hdev->hci_ver, hdev->hci_rev);
557d5859e22SJohan Hedberg 
558d5859e22SJohan Hedberg 	if (test_bit(HCI_INIT, &hdev->flags))
559d5859e22SJohan Hedberg 		hci_setup(hdev);
560d5859e22SJohan Hedberg }
561d5859e22SJohan Hedberg 
562d5859e22SJohan Hedberg static void hci_setup_link_policy(struct hci_dev *hdev)
563d5859e22SJohan Hedberg {
564d5859e22SJohan Hedberg 	u16 link_policy = 0;
565d5859e22SJohan Hedberg 
566d5859e22SJohan Hedberg 	if (hdev->features[0] & LMP_RSWITCH)
567d5859e22SJohan Hedberg 		link_policy |= HCI_LP_RSWITCH;
568d5859e22SJohan Hedberg 	if (hdev->features[0] & LMP_HOLD)
569d5859e22SJohan Hedberg 		link_policy |= HCI_LP_HOLD;
570d5859e22SJohan Hedberg 	if (hdev->features[0] & LMP_SNIFF)
571d5859e22SJohan Hedberg 		link_policy |= HCI_LP_SNIFF;
572d5859e22SJohan Hedberg 	if (hdev->features[1] & LMP_PARK)
573d5859e22SJohan Hedberg 		link_policy |= HCI_LP_PARK;
574d5859e22SJohan Hedberg 
575d5859e22SJohan Hedberg 	link_policy = cpu_to_le16(link_policy);
576d5859e22SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
577d5859e22SJohan Hedberg 					sizeof(link_policy), &link_policy);
5781da177e4SLinus Torvalds }
5791da177e4SLinus Torvalds 
580a9de9248SMarcel Holtmann static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
581a9de9248SMarcel Holtmann {
582a9de9248SMarcel Holtmann 	struct hci_rp_read_local_commands *rp = (void *) skb->data;
583a9de9248SMarcel Holtmann 
584a9de9248SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, rp->status);
585a9de9248SMarcel Holtmann 
586a9de9248SMarcel Holtmann 	if (rp->status)
587d5859e22SJohan Hedberg 		goto done;
588a9de9248SMarcel Holtmann 
589a9de9248SMarcel Holtmann 	memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
590d5859e22SJohan Hedberg 
591d5859e22SJohan Hedberg 	if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
592d5859e22SJohan Hedberg 		hci_setup_link_policy(hdev);
593d5859e22SJohan Hedberg 
594d5859e22SJohan Hedberg done:
595d5859e22SJohan Hedberg 	hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
596a9de9248SMarcel Holtmann }
597a9de9248SMarcel Holtmann 
598a9de9248SMarcel Holtmann static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
599a9de9248SMarcel Holtmann {
600a9de9248SMarcel Holtmann 	struct hci_rp_read_local_features *rp = (void *) skb->data;
601a9de9248SMarcel Holtmann 
602a9de9248SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, rp->status);
603a9de9248SMarcel Holtmann 
604a9de9248SMarcel Holtmann 	if (rp->status)
605a9de9248SMarcel Holtmann 		return;
606a9de9248SMarcel Holtmann 
607a9de9248SMarcel Holtmann 	memcpy(hdev->features, rp->features, 8);
6081da177e4SLinus Torvalds 
6091da177e4SLinus Torvalds 	/* Adjust default settings according to features
6101da177e4SLinus Torvalds 	 * supported by device. */
611a9de9248SMarcel Holtmann 
6121da177e4SLinus Torvalds 	if (hdev->features[0] & LMP_3SLOT)
6131da177e4SLinus Torvalds 		hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
6141da177e4SLinus Torvalds 
6151da177e4SLinus Torvalds 	if (hdev->features[0] & LMP_5SLOT)
6161da177e4SLinus Torvalds 		hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
6171da177e4SLinus Torvalds 
6185b7f9909SMarcel Holtmann 	if (hdev->features[1] & LMP_HV2) {
6191da177e4SLinus Torvalds 		hdev->pkt_type  |= (HCI_HV2);
6205b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_HV2);
6215b7f9909SMarcel Holtmann 	}
6221da177e4SLinus Torvalds 
6235b7f9909SMarcel Holtmann 	if (hdev->features[1] & LMP_HV3) {
6241da177e4SLinus Torvalds 		hdev->pkt_type  |= (HCI_HV3);
6255b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_HV3);
6265b7f9909SMarcel Holtmann 	}
6275b7f9909SMarcel Holtmann 
6285b7f9909SMarcel Holtmann 	if (hdev->features[3] & LMP_ESCO)
6295b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_EV3);
6305b7f9909SMarcel Holtmann 
6315b7f9909SMarcel Holtmann 	if (hdev->features[4] & LMP_EV4)
6325b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_EV4);
6335b7f9909SMarcel Holtmann 
6345b7f9909SMarcel Holtmann 	if (hdev->features[4] & LMP_EV5)
6355b7f9909SMarcel Holtmann 		hdev->esco_type |= (ESCO_EV5);
6361da177e4SLinus Torvalds 
637efc7688bSMarcel Holtmann 	if (hdev->features[5] & LMP_EDR_ESCO_2M)
638efc7688bSMarcel Holtmann 		hdev->esco_type |= (ESCO_2EV3);
639efc7688bSMarcel Holtmann 
640efc7688bSMarcel Holtmann 	if (hdev->features[5] & LMP_EDR_ESCO_3M)
641efc7688bSMarcel Holtmann 		hdev->esco_type |= (ESCO_3EV3);
642efc7688bSMarcel Holtmann 
643efc7688bSMarcel Holtmann 	if (hdev->features[5] & LMP_EDR_3S_ESCO)
644efc7688bSMarcel Holtmann 		hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
645efc7688bSMarcel Holtmann 
646a9de9248SMarcel Holtmann 	BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
647a9de9248SMarcel Holtmann 					hdev->features[0], hdev->features[1],
648a9de9248SMarcel Holtmann 					hdev->features[2], hdev->features[3],
649a9de9248SMarcel Holtmann 					hdev->features[4], hdev->features[5],
650a9de9248SMarcel Holtmann 					hdev->features[6], hdev->features[7]);
6511da177e4SLinus Torvalds }
6521da177e4SLinus Torvalds 
653a9de9248SMarcel Holtmann static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
654a9de9248SMarcel Holtmann {
655a9de9248SMarcel Holtmann 	struct hci_rp_read_buffer_size *rp = (void *) skb->data;
656a9de9248SMarcel Holtmann 
657a9de9248SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, rp->status);
658a9de9248SMarcel Holtmann 
659a9de9248SMarcel Holtmann 	if (rp->status)
660a9de9248SMarcel Holtmann 		return;
661a9de9248SMarcel Holtmann 
662a9de9248SMarcel Holtmann 	hdev->acl_mtu  = __le16_to_cpu(rp->acl_mtu);
663a9de9248SMarcel Holtmann 	hdev->sco_mtu  = rp->sco_mtu;
664a9de9248SMarcel Holtmann 	hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
665a9de9248SMarcel Holtmann 	hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
666da1f5198SMarcel Holtmann 
667da1f5198SMarcel Holtmann 	if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
668da1f5198SMarcel Holtmann 		hdev->sco_mtu  = 64;
669da1f5198SMarcel Holtmann 		hdev->sco_pkts = 8;
670da1f5198SMarcel Holtmann 	}
671da1f5198SMarcel Holtmann 
672da1f5198SMarcel Holtmann 	hdev->acl_cnt = hdev->acl_pkts;
673da1f5198SMarcel Holtmann 	hdev->sco_cnt = hdev->sco_pkts;
6741da177e4SLinus Torvalds 
675a9de9248SMarcel Holtmann 	BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
676a9de9248SMarcel Holtmann 					hdev->acl_mtu, hdev->acl_pkts,
677a9de9248SMarcel Holtmann 					hdev->sco_mtu, hdev->sco_pkts);
6781da177e4SLinus Torvalds }
6791da177e4SLinus Torvalds 
680a9de9248SMarcel Holtmann static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
681a9de9248SMarcel Holtmann {
682a9de9248SMarcel Holtmann 	struct hci_rp_read_bd_addr *rp = (void *) skb->data;
6831da177e4SLinus Torvalds 
684a9de9248SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, rp->status);
685a9de9248SMarcel Holtmann 
686a9de9248SMarcel Holtmann 	if (!rp->status)
687a9de9248SMarcel Holtmann 		bacpy(&hdev->bdaddr, &rp->bdaddr);
688a9de9248SMarcel Holtmann 
68923bb5763SJohan Hedberg 	hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
69023bb5763SJohan Hedberg }
69123bb5763SJohan Hedberg 
69223bb5763SJohan Hedberg static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
69323bb5763SJohan Hedberg {
69423bb5763SJohan Hedberg 	__u8 status = *((__u8 *) skb->data);
69523bb5763SJohan Hedberg 
69623bb5763SJohan Hedberg 	BT_DBG("%s status 0x%x", hdev->name, status);
69723bb5763SJohan Hedberg 
69823bb5763SJohan Hedberg 	hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
6991da177e4SLinus Torvalds }
7001da177e4SLinus Torvalds 
701b0916ea0SJohan Hedberg static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
702b0916ea0SJohan Hedberg 							struct sk_buff *skb)
703b0916ea0SJohan Hedberg {
704b0916ea0SJohan Hedberg 	__u8 status = *((__u8 *) skb->data);
705b0916ea0SJohan Hedberg 
706b0916ea0SJohan Hedberg 	BT_DBG("%s status 0x%x", hdev->name, status);
707b0916ea0SJohan Hedberg 
708b0916ea0SJohan Hedberg 	hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
709b0916ea0SJohan Hedberg }
710b0916ea0SJohan Hedberg 
711d5859e22SJohan Hedberg static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
712d5859e22SJohan Hedberg {
713d5859e22SJohan Hedberg 	__u8 status = *((__u8 *) skb->data);
714d5859e22SJohan Hedberg 
715d5859e22SJohan Hedberg 	BT_DBG("%s status 0x%x", hdev->name, status);
716d5859e22SJohan Hedberg 
717d5859e22SJohan Hedberg 	hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
718d5859e22SJohan Hedberg }
719d5859e22SJohan Hedberg 
720d5859e22SJohan Hedberg static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
721d5859e22SJohan Hedberg 							struct sk_buff *skb)
722d5859e22SJohan Hedberg {
723d5859e22SJohan Hedberg 	__u8 status = *((__u8 *) skb->data);
724d5859e22SJohan Hedberg 
725d5859e22SJohan Hedberg 	BT_DBG("%s status 0x%x", hdev->name, status);
726d5859e22SJohan Hedberg 
727d5859e22SJohan Hedberg 	hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
728d5859e22SJohan Hedberg }
729d5859e22SJohan Hedberg 
730d5859e22SJohan Hedberg static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
731d5859e22SJohan Hedberg 							struct sk_buff *skb)
732d5859e22SJohan Hedberg {
733d5859e22SJohan Hedberg 	__u8 status = *((__u8 *) skb->data);
734d5859e22SJohan Hedberg 
735d5859e22SJohan Hedberg 	BT_DBG("%s status 0x%x", hdev->name, status);
736d5859e22SJohan Hedberg 
737d5859e22SJohan Hedberg 	hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status);
738d5859e22SJohan Hedberg }
739d5859e22SJohan Hedberg 
740d5859e22SJohan Hedberg static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
741d5859e22SJohan Hedberg {
742d5859e22SJohan Hedberg 	__u8 status = *((__u8 *) skb->data);
743d5859e22SJohan Hedberg 
744d5859e22SJohan Hedberg 	BT_DBG("%s status 0x%x", hdev->name, status);
745d5859e22SJohan Hedberg 
746d5859e22SJohan Hedberg 	hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
747d5859e22SJohan Hedberg }
748d5859e22SJohan Hedberg 
749980e1a53SJohan Hedberg static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
750980e1a53SJohan Hedberg {
751980e1a53SJohan Hedberg 	struct hci_rp_pin_code_reply *rp = (void *) skb->data;
752980e1a53SJohan Hedberg 	struct hci_cp_pin_code_reply *cp;
753980e1a53SJohan Hedberg 	struct hci_conn *conn;
754980e1a53SJohan Hedberg 
755980e1a53SJohan Hedberg 	BT_DBG("%s status 0x%x", hdev->name, rp->status);
756980e1a53SJohan Hedberg 
757980e1a53SJohan Hedberg 	if (test_bit(HCI_MGMT, &hdev->flags))
758980e1a53SJohan Hedberg 		mgmt_pin_code_reply_complete(hdev->id, &rp->bdaddr, rp->status);
759980e1a53SJohan Hedberg 
760980e1a53SJohan Hedberg 	if (rp->status != 0)
761980e1a53SJohan Hedberg 		return;
762980e1a53SJohan Hedberg 
763980e1a53SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
764980e1a53SJohan Hedberg 	if (!cp)
765980e1a53SJohan Hedberg 		return;
766980e1a53SJohan Hedberg 
767980e1a53SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
768980e1a53SJohan Hedberg 	if (conn)
769980e1a53SJohan Hedberg 		conn->pin_length = cp->pin_len;
770980e1a53SJohan Hedberg }
771980e1a53SJohan Hedberg 
772980e1a53SJohan Hedberg static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
773980e1a53SJohan Hedberg {
774980e1a53SJohan Hedberg 	struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
775980e1a53SJohan Hedberg 
776980e1a53SJohan Hedberg 	BT_DBG("%s status 0x%x", hdev->name, rp->status);
777980e1a53SJohan Hedberg 
778980e1a53SJohan Hedberg 	if (test_bit(HCI_MGMT, &hdev->flags))
779980e1a53SJohan Hedberg 		mgmt_pin_code_neg_reply_complete(hdev->id, &rp->bdaddr,
780980e1a53SJohan Hedberg 								rp->status);
781980e1a53SJohan Hedberg }
7826ed58ec5SVille Tervo static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
7836ed58ec5SVille Tervo 				       struct sk_buff *skb)
7846ed58ec5SVille Tervo {
7856ed58ec5SVille Tervo 	struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
7866ed58ec5SVille Tervo 
7876ed58ec5SVille Tervo 	BT_DBG("%s status 0x%x", hdev->name, rp->status);
7886ed58ec5SVille Tervo 
7896ed58ec5SVille Tervo 	if (rp->status)
7906ed58ec5SVille Tervo 		return;
7916ed58ec5SVille Tervo 
7926ed58ec5SVille Tervo 	hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
7936ed58ec5SVille Tervo 	hdev->le_pkts = rp->le_max_pkt;
7946ed58ec5SVille Tervo 
7956ed58ec5SVille Tervo 	hdev->le_cnt = hdev->le_pkts;
7966ed58ec5SVille Tervo 
7976ed58ec5SVille Tervo 	BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
7986ed58ec5SVille Tervo 
7996ed58ec5SVille Tervo 	hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
8006ed58ec5SVille Tervo }
801980e1a53SJohan Hedberg 
802a5c29683SJohan Hedberg static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
803a5c29683SJohan Hedberg {
804a5c29683SJohan Hedberg 	struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
805a5c29683SJohan Hedberg 
806a5c29683SJohan Hedberg 	BT_DBG("%s status 0x%x", hdev->name, rp->status);
807a5c29683SJohan Hedberg 
808a5c29683SJohan Hedberg 	if (test_bit(HCI_MGMT, &hdev->flags))
809a5c29683SJohan Hedberg 		mgmt_user_confirm_reply_complete(hdev->id, &rp->bdaddr,
810a5c29683SJohan Hedberg 								rp->status);
811a5c29683SJohan Hedberg }
812a5c29683SJohan Hedberg 
813a5c29683SJohan Hedberg static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
814a5c29683SJohan Hedberg 							struct sk_buff *skb)
815a5c29683SJohan Hedberg {
816a5c29683SJohan Hedberg 	struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
817a5c29683SJohan Hedberg 
818a5c29683SJohan Hedberg 	BT_DBG("%s status 0x%x", hdev->name, rp->status);
819a5c29683SJohan Hedberg 
820a5c29683SJohan Hedberg 	if (test_bit(HCI_MGMT, &hdev->flags))
821a5c29683SJohan Hedberg 		mgmt_user_confirm_neg_reply_complete(hdev->id, &rp->bdaddr,
822a5c29683SJohan Hedberg 								rp->status);
823a5c29683SJohan Hedberg }
824a5c29683SJohan Hedberg 
825a9de9248SMarcel Holtmann static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
826a9de9248SMarcel Holtmann {
827a9de9248SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, status);
828a9de9248SMarcel Holtmann 
829a9de9248SMarcel Holtmann 	if (status) {
83023bb5763SJohan Hedberg 		hci_req_complete(hdev, HCI_OP_INQUIRY, status);
831a9de9248SMarcel Holtmann 
832a9de9248SMarcel Holtmann 		hci_conn_check_pending(hdev);
833a9de9248SMarcel Holtmann 	} else
834a9de9248SMarcel Holtmann 		set_bit(HCI_INQUIRY, &hdev->flags);
835a9de9248SMarcel Holtmann }
836a9de9248SMarcel Holtmann 
8371da177e4SLinus Torvalds static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
8381da177e4SLinus Torvalds {
839a9de9248SMarcel Holtmann 	struct hci_cp_create_conn *cp;
8401da177e4SLinus Torvalds 	struct hci_conn *conn;
8411da177e4SLinus Torvalds 
842a9de9248SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, status);
843a9de9248SMarcel Holtmann 
844a9de9248SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
8451da177e4SLinus Torvalds 	if (!cp)
8461da177e4SLinus Torvalds 		return;
8471da177e4SLinus Torvalds 
8481da177e4SLinus Torvalds 	hci_dev_lock(hdev);
8491da177e4SLinus Torvalds 
8501da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
8511da177e4SLinus Torvalds 
852a9de9248SMarcel Holtmann 	BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
8531da177e4SLinus Torvalds 
8541da177e4SLinus Torvalds 	if (status) {
8551da177e4SLinus Torvalds 		if (conn && conn->state == BT_CONNECT) {
8564c67bc74SMarcel Holtmann 			if (status != 0x0c || conn->attempt > 2) {
8571da177e4SLinus Torvalds 				conn->state = BT_CLOSED;
8581da177e4SLinus Torvalds 				hci_proto_connect_cfm(conn, status);
8591da177e4SLinus Torvalds 				hci_conn_del(conn);
8604c67bc74SMarcel Holtmann 			} else
8614c67bc74SMarcel Holtmann 				conn->state = BT_CONNECT2;
8621da177e4SLinus Torvalds 		}
8631da177e4SLinus Torvalds 	} else {
8641da177e4SLinus Torvalds 		if (!conn) {
8651da177e4SLinus Torvalds 			conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
8661da177e4SLinus Torvalds 			if (conn) {
8671da177e4SLinus Torvalds 				conn->out = 1;
8681da177e4SLinus Torvalds 				conn->link_mode |= HCI_LM_MASTER;
8691da177e4SLinus Torvalds 			} else
870893ef971SGustavo F. Padovan 				BT_ERR("No memory for new connection");
8711da177e4SLinus Torvalds 		}
8721da177e4SLinus Torvalds 	}
8731da177e4SLinus Torvalds 
8741da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
8751da177e4SLinus Torvalds }
8761da177e4SLinus Torvalds 
877a9de9248SMarcel Holtmann static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
8781da177e4SLinus Torvalds {
879a9de9248SMarcel Holtmann 	struct hci_cp_add_sco *cp;
8801da177e4SLinus Torvalds 	struct hci_conn *acl, *sco;
8811da177e4SLinus Torvalds 	__u16 handle;
8821da177e4SLinus Torvalds 
883b6a0dc82SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, status);
884b6a0dc82SMarcel Holtmann 
885a9de9248SMarcel Holtmann 	if (!status)
886a9de9248SMarcel Holtmann 		return;
887a9de9248SMarcel Holtmann 
888a9de9248SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
8891da177e4SLinus Torvalds 	if (!cp)
890a9de9248SMarcel Holtmann 		return;
8911da177e4SLinus Torvalds 
8921da177e4SLinus Torvalds 	handle = __le16_to_cpu(cp->handle);
8931da177e4SLinus Torvalds 
894a9de9248SMarcel Holtmann 	BT_DBG("%s handle %d", hdev->name, handle);
8951da177e4SLinus Torvalds 
8961da177e4SLinus Torvalds 	hci_dev_lock(hdev);
8971da177e4SLinus Torvalds 
8981da177e4SLinus Torvalds 	acl = hci_conn_hash_lookup_handle(hdev, handle);
8995a08ecceSAndrei Emeltchenko 	if (acl) {
9005a08ecceSAndrei Emeltchenko 		sco = acl->link;
9015a08ecceSAndrei Emeltchenko 		if (sco) {
9021da177e4SLinus Torvalds 			sco->state = BT_CLOSED;
9031da177e4SLinus Torvalds 
9041da177e4SLinus Torvalds 			hci_proto_connect_cfm(sco, status);
9051da177e4SLinus Torvalds 			hci_conn_del(sco);
9061da177e4SLinus Torvalds 		}
9075a08ecceSAndrei Emeltchenko 	}
9081da177e4SLinus Torvalds 
9091da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
9101da177e4SLinus Torvalds }
9111da177e4SLinus Torvalds 
912f8558555SMarcel Holtmann static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
913f8558555SMarcel Holtmann {
914f8558555SMarcel Holtmann 	struct hci_cp_auth_requested *cp;
915f8558555SMarcel Holtmann 	struct hci_conn *conn;
916f8558555SMarcel Holtmann 
917f8558555SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, status);
918f8558555SMarcel Holtmann 
919f8558555SMarcel Holtmann 	if (!status)
920f8558555SMarcel Holtmann 		return;
921f8558555SMarcel Holtmann 
922f8558555SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
923f8558555SMarcel Holtmann 	if (!cp)
924f8558555SMarcel Holtmann 		return;
925f8558555SMarcel Holtmann 
926f8558555SMarcel Holtmann 	hci_dev_lock(hdev);
927f8558555SMarcel Holtmann 
928f8558555SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
929f8558555SMarcel Holtmann 	if (conn) {
930f8558555SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
931f8558555SMarcel Holtmann 			hci_proto_connect_cfm(conn, status);
932f8558555SMarcel Holtmann 			hci_conn_put(conn);
933f8558555SMarcel Holtmann 		}
934f8558555SMarcel Holtmann 	}
935f8558555SMarcel Holtmann 
936f8558555SMarcel Holtmann 	hci_dev_unlock(hdev);
937f8558555SMarcel Holtmann }
938f8558555SMarcel Holtmann 
939f8558555SMarcel Holtmann static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
940f8558555SMarcel Holtmann {
941f8558555SMarcel Holtmann 	struct hci_cp_set_conn_encrypt *cp;
942f8558555SMarcel Holtmann 	struct hci_conn *conn;
943f8558555SMarcel Holtmann 
944f8558555SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, status);
945f8558555SMarcel Holtmann 
946f8558555SMarcel Holtmann 	if (!status)
947f8558555SMarcel Holtmann 		return;
948f8558555SMarcel Holtmann 
949f8558555SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
950f8558555SMarcel Holtmann 	if (!cp)
951f8558555SMarcel Holtmann 		return;
952f8558555SMarcel Holtmann 
953f8558555SMarcel Holtmann 	hci_dev_lock(hdev);
954f8558555SMarcel Holtmann 
955f8558555SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
956f8558555SMarcel Holtmann 	if (conn) {
957f8558555SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
958f8558555SMarcel Holtmann 			hci_proto_connect_cfm(conn, status);
959f8558555SMarcel Holtmann 			hci_conn_put(conn);
960f8558555SMarcel Holtmann 		}
961f8558555SMarcel Holtmann 	}
962f8558555SMarcel Holtmann 
963f8558555SMarcel Holtmann 	hci_dev_unlock(hdev);
964f8558555SMarcel Holtmann }
965f8558555SMarcel Holtmann 
966127178d2SJohan Hedberg static int hci_outgoing_auth_needed(struct hci_dev *hdev,
967392599b9SJohan Hedberg 							struct hci_conn *conn)
968392599b9SJohan Hedberg {
969392599b9SJohan Hedberg 	if (conn->state != BT_CONFIG || !conn->out)
970392599b9SJohan Hedberg 		return 0;
971392599b9SJohan Hedberg 
972765c2a96SJohan Hedberg 	if (conn->pending_sec_level == BT_SECURITY_SDP)
973392599b9SJohan Hedberg 		return 0;
974392599b9SJohan Hedberg 
975392599b9SJohan Hedberg 	/* Only request authentication for SSP connections or non-SSP
976392599b9SJohan Hedberg 	 * devices with sec_level HIGH */
977392599b9SJohan Hedberg 	if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) &&
978765c2a96SJohan Hedberg 				conn->pending_sec_level != BT_SECURITY_HIGH)
979392599b9SJohan Hedberg 		return 0;
980392599b9SJohan Hedberg 
981392599b9SJohan Hedberg 	return 1;
982392599b9SJohan Hedberg }
983392599b9SJohan Hedberg 
984a9de9248SMarcel Holtmann static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
9851da177e4SLinus Torvalds {
986127178d2SJohan Hedberg 	struct hci_cp_remote_name_req *cp;
987127178d2SJohan Hedberg 	struct hci_conn *conn;
988127178d2SJohan Hedberg 
989a9de9248SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, status);
990127178d2SJohan Hedberg 
991127178d2SJohan Hedberg 	/* If successful wait for the name req complete event before
992127178d2SJohan Hedberg 	 * checking for the need to do authentication */
993127178d2SJohan Hedberg 	if (!status)
994127178d2SJohan Hedberg 		return;
995127178d2SJohan Hedberg 
996127178d2SJohan Hedberg 	cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
997127178d2SJohan Hedberg 	if (!cp)
998127178d2SJohan Hedberg 		return;
999127178d2SJohan Hedberg 
1000127178d2SJohan Hedberg 	hci_dev_lock(hdev);
1001127178d2SJohan Hedberg 
1002127178d2SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1003127178d2SJohan Hedberg 	if (conn && hci_outgoing_auth_needed(hdev, conn)) {
1004127178d2SJohan Hedberg 		struct hci_cp_auth_requested cp;
1005127178d2SJohan Hedberg 		cp.handle = __cpu_to_le16(conn->handle);
1006127178d2SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1007127178d2SJohan Hedberg 	}
1008127178d2SJohan Hedberg 
1009127178d2SJohan Hedberg 	hci_dev_unlock(hdev);
1010a9de9248SMarcel Holtmann }
10111da177e4SLinus Torvalds 
1012769be974SMarcel Holtmann static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1013769be974SMarcel Holtmann {
1014769be974SMarcel Holtmann 	struct hci_cp_read_remote_features *cp;
1015769be974SMarcel Holtmann 	struct hci_conn *conn;
1016769be974SMarcel Holtmann 
1017769be974SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, status);
1018769be974SMarcel Holtmann 
1019769be974SMarcel Holtmann 	if (!status)
1020769be974SMarcel Holtmann 		return;
1021769be974SMarcel Holtmann 
1022769be974SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1023769be974SMarcel Holtmann 	if (!cp)
1024769be974SMarcel Holtmann 		return;
1025769be974SMarcel Holtmann 
1026769be974SMarcel Holtmann 	hci_dev_lock(hdev);
1027769be974SMarcel Holtmann 
1028769be974SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1029769be974SMarcel Holtmann 	if (conn) {
1030769be974SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
1031769be974SMarcel Holtmann 			hci_proto_connect_cfm(conn, status);
1032769be974SMarcel Holtmann 			hci_conn_put(conn);
1033769be974SMarcel Holtmann 		}
1034769be974SMarcel Holtmann 	}
1035769be974SMarcel Holtmann 
1036769be974SMarcel Holtmann 	hci_dev_unlock(hdev);
1037769be974SMarcel Holtmann }
1038769be974SMarcel Holtmann 
1039769be974SMarcel Holtmann static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1040769be974SMarcel Holtmann {
1041769be974SMarcel Holtmann 	struct hci_cp_read_remote_ext_features *cp;
1042769be974SMarcel Holtmann 	struct hci_conn *conn;
1043769be974SMarcel Holtmann 
1044769be974SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, status);
1045769be974SMarcel Holtmann 
1046769be974SMarcel Holtmann 	if (!status)
1047769be974SMarcel Holtmann 		return;
1048769be974SMarcel Holtmann 
1049769be974SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1050769be974SMarcel Holtmann 	if (!cp)
1051769be974SMarcel Holtmann 		return;
1052769be974SMarcel Holtmann 
1053769be974SMarcel Holtmann 	hci_dev_lock(hdev);
1054769be974SMarcel Holtmann 
1055769be974SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1056769be974SMarcel Holtmann 	if (conn) {
1057769be974SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
1058769be974SMarcel Holtmann 			hci_proto_connect_cfm(conn, status);
1059769be974SMarcel Holtmann 			hci_conn_put(conn);
1060769be974SMarcel Holtmann 		}
1061769be974SMarcel Holtmann 	}
1062769be974SMarcel Holtmann 
1063769be974SMarcel Holtmann 	hci_dev_unlock(hdev);
1064769be974SMarcel Holtmann }
1065769be974SMarcel Holtmann 
1066a9de9248SMarcel Holtmann static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1067a9de9248SMarcel Holtmann {
1068b6a0dc82SMarcel Holtmann 	struct hci_cp_setup_sync_conn *cp;
1069b6a0dc82SMarcel Holtmann 	struct hci_conn *acl, *sco;
1070b6a0dc82SMarcel Holtmann 	__u16 handle;
1071b6a0dc82SMarcel Holtmann 
1072a9de9248SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, status);
1073b6a0dc82SMarcel Holtmann 
1074b6a0dc82SMarcel Holtmann 	if (!status)
1075b6a0dc82SMarcel Holtmann 		return;
1076b6a0dc82SMarcel Holtmann 
1077b6a0dc82SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1078b6a0dc82SMarcel Holtmann 	if (!cp)
1079b6a0dc82SMarcel Holtmann 		return;
1080b6a0dc82SMarcel Holtmann 
1081b6a0dc82SMarcel Holtmann 	handle = __le16_to_cpu(cp->handle);
1082b6a0dc82SMarcel Holtmann 
1083b6a0dc82SMarcel Holtmann 	BT_DBG("%s handle %d", hdev->name, handle);
1084b6a0dc82SMarcel Holtmann 
1085b6a0dc82SMarcel Holtmann 	hci_dev_lock(hdev);
1086b6a0dc82SMarcel Holtmann 
1087b6a0dc82SMarcel Holtmann 	acl = hci_conn_hash_lookup_handle(hdev, handle);
10885a08ecceSAndrei Emeltchenko 	if (acl) {
10895a08ecceSAndrei Emeltchenko 		sco = acl->link;
10905a08ecceSAndrei Emeltchenko 		if (sco) {
1091b6a0dc82SMarcel Holtmann 			sco->state = BT_CLOSED;
1092b6a0dc82SMarcel Holtmann 
1093b6a0dc82SMarcel Holtmann 			hci_proto_connect_cfm(sco, status);
1094b6a0dc82SMarcel Holtmann 			hci_conn_del(sco);
1095b6a0dc82SMarcel Holtmann 		}
10965a08ecceSAndrei Emeltchenko 	}
1097b6a0dc82SMarcel Holtmann 
1098b6a0dc82SMarcel Holtmann 	hci_dev_unlock(hdev);
1099a9de9248SMarcel Holtmann }
1100a9de9248SMarcel Holtmann 
1101a9de9248SMarcel Holtmann static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1102a9de9248SMarcel Holtmann {
1103a9de9248SMarcel Holtmann 	struct hci_cp_sniff_mode *cp;
110404837f64SMarcel Holtmann 	struct hci_conn *conn;
110504837f64SMarcel Holtmann 
1106a9de9248SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, status);
1107a9de9248SMarcel Holtmann 
1108a9de9248SMarcel Holtmann 	if (!status)
1109a9de9248SMarcel Holtmann 		return;
1110a9de9248SMarcel Holtmann 
1111a9de9248SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
111204837f64SMarcel Holtmann 	if (!cp)
1113a9de9248SMarcel Holtmann 		return;
111404837f64SMarcel Holtmann 
111504837f64SMarcel Holtmann 	hci_dev_lock(hdev);
111604837f64SMarcel Holtmann 
111704837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1118e73439d8SMarcel Holtmann 	if (conn) {
111904837f64SMarcel Holtmann 		clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
112004837f64SMarcel Holtmann 
1121e73439d8SMarcel Holtmann 		if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1122e73439d8SMarcel Holtmann 			hci_sco_setup(conn, status);
1123e73439d8SMarcel Holtmann 	}
1124e73439d8SMarcel Holtmann 
112504837f64SMarcel Holtmann 	hci_dev_unlock(hdev);
112604837f64SMarcel Holtmann }
112704837f64SMarcel Holtmann 
1128a9de9248SMarcel Holtmann static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1129a9de9248SMarcel Holtmann {
1130a9de9248SMarcel Holtmann 	struct hci_cp_exit_sniff_mode *cp;
113104837f64SMarcel Holtmann 	struct hci_conn *conn;
113204837f64SMarcel Holtmann 
1133a9de9248SMarcel Holtmann 	BT_DBG("%s status 0x%x", hdev->name, status);
1134a9de9248SMarcel Holtmann 
1135a9de9248SMarcel Holtmann 	if (!status)
1136a9de9248SMarcel Holtmann 		return;
1137a9de9248SMarcel Holtmann 
1138a9de9248SMarcel Holtmann 	cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
113904837f64SMarcel Holtmann 	if (!cp)
1140a9de9248SMarcel Holtmann 		return;
114104837f64SMarcel Holtmann 
114204837f64SMarcel Holtmann 	hci_dev_lock(hdev);
114304837f64SMarcel Holtmann 
114404837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1145e73439d8SMarcel Holtmann 	if (conn) {
114604837f64SMarcel Holtmann 		clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
114704837f64SMarcel Holtmann 
1148e73439d8SMarcel Holtmann 		if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1149e73439d8SMarcel Holtmann 			hci_sco_setup(conn, status);
1150e73439d8SMarcel Holtmann 	}
1151e73439d8SMarcel Holtmann 
115204837f64SMarcel Holtmann 	hci_dev_unlock(hdev);
115304837f64SMarcel Holtmann }
115404837f64SMarcel Holtmann 
1155fcd89c09SVille Tervo static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1156fcd89c09SVille Tervo {
1157fcd89c09SVille Tervo 	struct hci_cp_le_create_conn *cp;
1158fcd89c09SVille Tervo 	struct hci_conn *conn;
1159fcd89c09SVille Tervo 
1160fcd89c09SVille Tervo 	BT_DBG("%s status 0x%x", hdev->name, status);
1161fcd89c09SVille Tervo 
1162fcd89c09SVille Tervo 	cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1163fcd89c09SVille Tervo 	if (!cp)
1164fcd89c09SVille Tervo 		return;
1165fcd89c09SVille Tervo 
1166fcd89c09SVille Tervo 	hci_dev_lock(hdev);
1167fcd89c09SVille Tervo 
1168fcd89c09SVille Tervo 	conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1169fcd89c09SVille Tervo 
1170fcd89c09SVille Tervo 	BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1171fcd89c09SVille Tervo 		conn);
1172fcd89c09SVille Tervo 
1173fcd89c09SVille Tervo 	if (status) {
1174fcd89c09SVille Tervo 		if (conn && conn->state == BT_CONNECT) {
1175fcd89c09SVille Tervo 			conn->state = BT_CLOSED;
1176fcd89c09SVille Tervo 			hci_proto_connect_cfm(conn, status);
1177fcd89c09SVille Tervo 			hci_conn_del(conn);
1178fcd89c09SVille Tervo 		}
1179fcd89c09SVille Tervo 	} else {
1180fcd89c09SVille Tervo 		if (!conn) {
1181fcd89c09SVille Tervo 			conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
1182fcd89c09SVille Tervo 			if (conn)
1183fcd89c09SVille Tervo 				conn->out = 1;
1184fcd89c09SVille Tervo 			else
1185fcd89c09SVille Tervo 				BT_ERR("No memory for new connection");
1186fcd89c09SVille Tervo 		}
1187fcd89c09SVille Tervo 	}
1188fcd89c09SVille Tervo 
1189fcd89c09SVille Tervo 	hci_dev_unlock(hdev);
1190fcd89c09SVille Tervo }
1191fcd89c09SVille Tervo 
11921da177e4SLinus Torvalds static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
11931da177e4SLinus Torvalds {
11941da177e4SLinus Torvalds 	__u8 status = *((__u8 *) skb->data);
11951da177e4SLinus Torvalds 
11961da177e4SLinus Torvalds 	BT_DBG("%s status %d", hdev->name, status);
11971da177e4SLinus Torvalds 
11981da177e4SLinus Torvalds 	clear_bit(HCI_INQUIRY, &hdev->flags);
1199a9de9248SMarcel Holtmann 
120023bb5763SJohan Hedberg 	hci_req_complete(hdev, HCI_OP_INQUIRY, status);
12016bd57416SMarcel Holtmann 
1202a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
12031da177e4SLinus Torvalds }
12041da177e4SLinus Torvalds 
12051da177e4SLinus Torvalds static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
12061da177e4SLinus Torvalds {
120745bb4bf0SMarcel Holtmann 	struct inquiry_data data;
1208a9de9248SMarcel Holtmann 	struct inquiry_info *info = (void *) (skb->data + 1);
12091da177e4SLinus Torvalds 	int num_rsp = *((__u8 *) skb->data);
12101da177e4SLinus Torvalds 
12111da177e4SLinus Torvalds 	BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
12121da177e4SLinus Torvalds 
121345bb4bf0SMarcel Holtmann 	if (!num_rsp)
121445bb4bf0SMarcel Holtmann 		return;
121545bb4bf0SMarcel Holtmann 
12161da177e4SLinus Torvalds 	hci_dev_lock(hdev);
121745bb4bf0SMarcel Holtmann 
12181da177e4SLinus Torvalds 	for (; num_rsp; num_rsp--) {
12191da177e4SLinus Torvalds 		bacpy(&data.bdaddr, &info->bdaddr);
12201da177e4SLinus Torvalds 		data.pscan_rep_mode	= info->pscan_rep_mode;
12211da177e4SLinus Torvalds 		data.pscan_period_mode	= info->pscan_period_mode;
12221da177e4SLinus Torvalds 		data.pscan_mode		= info->pscan_mode;
12231da177e4SLinus Torvalds 		memcpy(data.dev_class, info->dev_class, 3);
12241da177e4SLinus Torvalds 		data.clock_offset	= info->clock_offset;
12251da177e4SLinus Torvalds 		data.rssi		= 0x00;
122641a96212SMarcel Holtmann 		data.ssp_mode		= 0x00;
12271da177e4SLinus Torvalds 		info++;
12281da177e4SLinus Torvalds 		hci_inquiry_cache_update(hdev, &data);
12291da177e4SLinus Torvalds 	}
123045bb4bf0SMarcel Holtmann 
12311da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
12321da177e4SLinus Torvalds }
12331da177e4SLinus Torvalds 
1234a9de9248SMarcel Holtmann static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
12351da177e4SLinus Torvalds {
1236a9de9248SMarcel Holtmann 	struct hci_ev_conn_complete *ev = (void *) skb->data;
1237a9de9248SMarcel Holtmann 	struct hci_conn *conn;
12381da177e4SLinus Torvalds 
1239a9de9248SMarcel Holtmann 	BT_DBG("%s", hdev->name);
124045bb4bf0SMarcel Holtmann 
12411da177e4SLinus Torvalds 	hci_dev_lock(hdev);
124245bb4bf0SMarcel Holtmann 
1243a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
12449499237aSMarcel Holtmann 	if (!conn) {
12459499237aSMarcel Holtmann 		if (ev->link_type != SCO_LINK)
12469499237aSMarcel Holtmann 			goto unlock;
12479499237aSMarcel Holtmann 
12489499237aSMarcel Holtmann 		conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1249a9de9248SMarcel Holtmann 		if (!conn)
1250a9de9248SMarcel Holtmann 			goto unlock;
125145bb4bf0SMarcel Holtmann 
12529499237aSMarcel Holtmann 		conn->type = SCO_LINK;
12539499237aSMarcel Holtmann 	}
12549499237aSMarcel Holtmann 
1255a9de9248SMarcel Holtmann 	if (!ev->status) {
1256a9de9248SMarcel Holtmann 		conn->handle = __le16_to_cpu(ev->handle);
1257769be974SMarcel Holtmann 
1258769be974SMarcel Holtmann 		if (conn->type == ACL_LINK) {
1259769be974SMarcel Holtmann 			conn->state = BT_CONFIG;
1260769be974SMarcel Holtmann 			hci_conn_hold(conn);
1261052b30b0SMarcel Holtmann 			conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1262f7520543SJohan Hedberg 			mgmt_connected(hdev->id, &ev->bdaddr);
1263769be974SMarcel Holtmann 		} else
1264a9de9248SMarcel Holtmann 			conn->state = BT_CONNECTED;
1265a9de9248SMarcel Holtmann 
12669eba32b8SMarcel Holtmann 		hci_conn_hold_device(conn);
12677d0db0a3SMarcel Holtmann 		hci_conn_add_sysfs(conn);
12687d0db0a3SMarcel Holtmann 
1269a9de9248SMarcel Holtmann 		if (test_bit(HCI_AUTH, &hdev->flags))
1270a9de9248SMarcel Holtmann 			conn->link_mode |= HCI_LM_AUTH;
1271a9de9248SMarcel Holtmann 
1272a9de9248SMarcel Holtmann 		if (test_bit(HCI_ENCRYPT, &hdev->flags))
1273a9de9248SMarcel Holtmann 			conn->link_mode |= HCI_LM_ENCRYPT;
1274a9de9248SMarcel Holtmann 
1275a9de9248SMarcel Holtmann 		/* Get remote features */
1276a9de9248SMarcel Holtmann 		if (conn->type == ACL_LINK) {
1277a9de9248SMarcel Holtmann 			struct hci_cp_read_remote_features cp;
1278a9de9248SMarcel Holtmann 			cp.handle = ev->handle;
1279769be974SMarcel Holtmann 			hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1280769be974SMarcel Holtmann 							sizeof(cp), &cp);
128145bb4bf0SMarcel Holtmann 		}
1282a9de9248SMarcel Holtmann 
1283a9de9248SMarcel Holtmann 		/* Set packet type for incoming connection */
1284a8746417SMarcel Holtmann 		if (!conn->out && hdev->hci_ver < 3) {
1285a9de9248SMarcel Holtmann 			struct hci_cp_change_conn_ptype cp;
1286a9de9248SMarcel Holtmann 			cp.handle = ev->handle;
1287a8746417SMarcel Holtmann 			cp.pkt_type = cpu_to_le16(conn->pkt_type);
1288a8746417SMarcel Holtmann 			hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1289a8746417SMarcel Holtmann 							sizeof(cp), &cp);
1290a9de9248SMarcel Holtmann 		}
129117d5c04cSJohan Hedberg 	} else {
1292a9de9248SMarcel Holtmann 		conn->state = BT_CLOSED;
129317d5c04cSJohan Hedberg 		if (conn->type == ACL_LINK)
129417d5c04cSJohan Hedberg 			mgmt_connect_failed(hdev->id, &ev->bdaddr, ev->status);
129517d5c04cSJohan Hedberg 	}
129645bb4bf0SMarcel Holtmann 
1297e73439d8SMarcel Holtmann 	if (conn->type == ACL_LINK)
1298e73439d8SMarcel Holtmann 		hci_sco_setup(conn, ev->status);
129945bb4bf0SMarcel Holtmann 
1300769be974SMarcel Holtmann 	if (ev->status) {
1301a9de9248SMarcel Holtmann 		hci_proto_connect_cfm(conn, ev->status);
1302a9de9248SMarcel Holtmann 		hci_conn_del(conn);
1303c89b6e6bSMarcel Holtmann 	} else if (ev->link_type != ACL_LINK)
1304c89b6e6bSMarcel Holtmann 		hci_proto_connect_cfm(conn, ev->status);
1305a9de9248SMarcel Holtmann 
1306a9de9248SMarcel Holtmann unlock:
13071da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
1308a9de9248SMarcel Holtmann 
1309a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
13101da177e4SLinus Torvalds }
13111da177e4SLinus Torvalds 
13121da177e4SLinus Torvalds static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
13131da177e4SLinus Torvalds {
1314a9de9248SMarcel Holtmann 	struct hci_ev_conn_request *ev = (void *) skb->data;
13151da177e4SLinus Torvalds 	int mask = hdev->link_mode;
13161da177e4SLinus Torvalds 
1317a9de9248SMarcel Holtmann 	BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
13181da177e4SLinus Torvalds 					batostr(&ev->bdaddr), ev->link_type);
13191da177e4SLinus Torvalds 
13201da177e4SLinus Torvalds 	mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
13211da177e4SLinus Torvalds 
1322138d22efSSzymon Janc 	if ((mask & HCI_LM_ACCEPT) &&
1323138d22efSSzymon Janc 			!hci_blacklist_lookup(hdev, &ev->bdaddr)) {
13241da177e4SLinus Torvalds 		/* Connection accepted */
1325c7bdd502SMarcel Holtmann 		struct inquiry_entry *ie;
13261da177e4SLinus Torvalds 		struct hci_conn *conn;
13271da177e4SLinus Torvalds 
13281da177e4SLinus Torvalds 		hci_dev_lock(hdev);
1329b6a0dc82SMarcel Holtmann 
1330cc11b9c1SAndrei Emeltchenko 		ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1331cc11b9c1SAndrei Emeltchenko 		if (ie)
1332c7bdd502SMarcel Holtmann 			memcpy(ie->data.dev_class, ev->dev_class, 3);
1333c7bdd502SMarcel Holtmann 
13341da177e4SLinus Torvalds 		conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
13351da177e4SLinus Torvalds 		if (!conn) {
1336cc11b9c1SAndrei Emeltchenko 			conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1337cc11b9c1SAndrei Emeltchenko 			if (!conn) {
1338893ef971SGustavo F. Padovan 				BT_ERR("No memory for new connection");
13391da177e4SLinus Torvalds 				hci_dev_unlock(hdev);
13401da177e4SLinus Torvalds 				return;
13411da177e4SLinus Torvalds 			}
13421da177e4SLinus Torvalds 		}
1343b6a0dc82SMarcel Holtmann 
13441da177e4SLinus Torvalds 		memcpy(conn->dev_class, ev->dev_class, 3);
13451da177e4SLinus Torvalds 		conn->state = BT_CONNECT;
1346b6a0dc82SMarcel Holtmann 
13471da177e4SLinus Torvalds 		hci_dev_unlock(hdev);
13481da177e4SLinus Torvalds 
1349b6a0dc82SMarcel Holtmann 		if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1350b6a0dc82SMarcel Holtmann 			struct hci_cp_accept_conn_req cp;
1351b6a0dc82SMarcel Holtmann 
13521da177e4SLinus Torvalds 			bacpy(&cp.bdaddr, &ev->bdaddr);
13531da177e4SLinus Torvalds 
13541da177e4SLinus Torvalds 			if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
13551da177e4SLinus Torvalds 				cp.role = 0x00; /* Become master */
13561da177e4SLinus Torvalds 			else
13571da177e4SLinus Torvalds 				cp.role = 0x01; /* Remain slave */
13581da177e4SLinus Torvalds 
1359b6a0dc82SMarcel Holtmann 			hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1360b6a0dc82SMarcel Holtmann 							sizeof(cp), &cp);
1361b6a0dc82SMarcel Holtmann 		} else {
1362b6a0dc82SMarcel Holtmann 			struct hci_cp_accept_sync_conn_req cp;
1363b6a0dc82SMarcel Holtmann 
1364b6a0dc82SMarcel Holtmann 			bacpy(&cp.bdaddr, &ev->bdaddr);
1365a8746417SMarcel Holtmann 			cp.pkt_type = cpu_to_le16(conn->pkt_type);
1366b6a0dc82SMarcel Holtmann 
1367b6a0dc82SMarcel Holtmann 			cp.tx_bandwidth   = cpu_to_le32(0x00001f40);
1368b6a0dc82SMarcel Holtmann 			cp.rx_bandwidth   = cpu_to_le32(0x00001f40);
1369b6a0dc82SMarcel Holtmann 			cp.max_latency    = cpu_to_le16(0xffff);
1370b6a0dc82SMarcel Holtmann 			cp.content_format = cpu_to_le16(hdev->voice_setting);
1371b6a0dc82SMarcel Holtmann 			cp.retrans_effort = 0xff;
1372b6a0dc82SMarcel Holtmann 
1373b6a0dc82SMarcel Holtmann 			hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1374b6a0dc82SMarcel Holtmann 							sizeof(cp), &cp);
1375b6a0dc82SMarcel Holtmann 		}
13761da177e4SLinus Torvalds 	} else {
13771da177e4SLinus Torvalds 		/* Connection rejected */
13781da177e4SLinus Torvalds 		struct hci_cp_reject_conn_req cp;
13791da177e4SLinus Torvalds 
13801da177e4SLinus Torvalds 		bacpy(&cp.bdaddr, &ev->bdaddr);
13811da177e4SLinus Torvalds 		cp.reason = 0x0f;
1382a9de9248SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
13831da177e4SLinus Torvalds 	}
13841da177e4SLinus Torvalds }
13851da177e4SLinus Torvalds 
13861da177e4SLinus Torvalds static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
13871da177e4SLinus Torvalds {
1388a9de9248SMarcel Holtmann 	struct hci_ev_disconn_complete *ev = (void *) skb->data;
138904837f64SMarcel Holtmann 	struct hci_conn *conn;
13901da177e4SLinus Torvalds 
13911da177e4SLinus Torvalds 	BT_DBG("%s status %d", hdev->name, ev->status);
13921da177e4SLinus Torvalds 
13938962ee74SJohan Hedberg 	if (ev->status) {
13948962ee74SJohan Hedberg 		mgmt_disconnect_failed(hdev->id);
13951da177e4SLinus Torvalds 		return;
13968962ee74SJohan Hedberg 	}
13971da177e4SLinus Torvalds 
13981da177e4SLinus Torvalds 	hci_dev_lock(hdev);
13991da177e4SLinus Torvalds 
140004837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1401f7520543SJohan Hedberg 	if (!conn)
1402f7520543SJohan Hedberg 		goto unlock;
1403f7520543SJohan Hedberg 
14041da177e4SLinus Torvalds 	conn->state = BT_CLOSED;
14057d0db0a3SMarcel Holtmann 
1406f7520543SJohan Hedberg 	if (conn->type == ACL_LINK)
1407f7520543SJohan Hedberg 		mgmt_disconnected(hdev->id, &conn->dst);
1408f7520543SJohan Hedberg 
14092950f21aSMarcel Holtmann 	hci_proto_disconn_cfm(conn, ev->reason);
14101da177e4SLinus Torvalds 	hci_conn_del(conn);
14111da177e4SLinus Torvalds 
1412f7520543SJohan Hedberg unlock:
14131da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
14141da177e4SLinus Torvalds }
14151da177e4SLinus Torvalds 
1416a9de9248SMarcel Holtmann static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1417a9de9248SMarcel Holtmann {
1418a9de9248SMarcel Holtmann 	struct hci_ev_auth_complete *ev = (void *) skb->data;
1419a9de9248SMarcel Holtmann 	struct hci_conn *conn;
1420a9de9248SMarcel Holtmann 
1421a9de9248SMarcel Holtmann 	BT_DBG("%s status %d", hdev->name, ev->status);
1422a9de9248SMarcel Holtmann 
1423a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
1424a9de9248SMarcel Holtmann 
1425a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1426a9de9248SMarcel Holtmann 	if (conn) {
1427765c2a96SJohan Hedberg 		if (!ev->status) {
1428a9de9248SMarcel Holtmann 			conn->link_mode |= HCI_LM_AUTH;
1429765c2a96SJohan Hedberg 			conn->sec_level = conn->pending_sec_level;
14302a611692SJohan Hedberg 		} else {
14312a611692SJohan Hedberg 			mgmt_auth_failed(hdev->id, &conn->dst, ev->status);
1432da213f41SJohan Hedberg 			conn->sec_level = BT_SECURITY_LOW;
14332a611692SJohan Hedberg 		}
1434a9de9248SMarcel Holtmann 
1435a9de9248SMarcel Holtmann 		clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1436a9de9248SMarcel Holtmann 
1437f8558555SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
1438f8558555SMarcel Holtmann 			if (!ev->status && hdev->ssp_mode > 0 &&
1439f8558555SMarcel Holtmann 							conn->ssp_mode > 0) {
1440f8558555SMarcel Holtmann 				struct hci_cp_set_conn_encrypt cp;
1441f8558555SMarcel Holtmann 				cp.handle  = ev->handle;
1442f8558555SMarcel Holtmann 				cp.encrypt = 0x01;
1443f8558555SMarcel Holtmann 				hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT,
1444f8558555SMarcel Holtmann 							sizeof(cp), &cp);
1445f8558555SMarcel Holtmann 			} else {
1446f8558555SMarcel Holtmann 				conn->state = BT_CONNECTED;
1447f8558555SMarcel Holtmann 				hci_proto_connect_cfm(conn, ev->status);
1448f8558555SMarcel Holtmann 				hci_conn_put(conn);
1449f8558555SMarcel Holtmann 			}
1450052b30b0SMarcel Holtmann 		} else {
1451a9de9248SMarcel Holtmann 			hci_auth_cfm(conn, ev->status);
1452a9de9248SMarcel Holtmann 
1453052b30b0SMarcel Holtmann 			hci_conn_hold(conn);
1454052b30b0SMarcel Holtmann 			conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1455052b30b0SMarcel Holtmann 			hci_conn_put(conn);
1456052b30b0SMarcel Holtmann 		}
1457052b30b0SMarcel Holtmann 
1458a9de9248SMarcel Holtmann 		if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
1459a9de9248SMarcel Holtmann 			if (!ev->status) {
1460a9de9248SMarcel Holtmann 				struct hci_cp_set_conn_encrypt cp;
1461f8558555SMarcel Holtmann 				cp.handle  = ev->handle;
1462f8558555SMarcel Holtmann 				cp.encrypt = 0x01;
1463f8558555SMarcel Holtmann 				hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT,
1464f8558555SMarcel Holtmann 							sizeof(cp), &cp);
1465a9de9248SMarcel Holtmann 			} else {
1466a9de9248SMarcel Holtmann 				clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1467a9de9248SMarcel Holtmann 				hci_encrypt_cfm(conn, ev->status, 0x00);
1468a9de9248SMarcel Holtmann 			}
1469a9de9248SMarcel Holtmann 		}
1470a9de9248SMarcel Holtmann 	}
1471a9de9248SMarcel Holtmann 
1472a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
1473a9de9248SMarcel Holtmann }
1474a9de9248SMarcel Holtmann 
1475a9de9248SMarcel Holtmann static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1476a9de9248SMarcel Holtmann {
1477127178d2SJohan Hedberg 	struct hci_ev_remote_name *ev = (void *) skb->data;
1478127178d2SJohan Hedberg 	struct hci_conn *conn;
1479127178d2SJohan Hedberg 
1480a9de9248SMarcel Holtmann 	BT_DBG("%s", hdev->name);
1481a9de9248SMarcel Holtmann 
1482a9de9248SMarcel Holtmann 	hci_conn_check_pending(hdev);
1483127178d2SJohan Hedberg 
1484127178d2SJohan Hedberg 	hci_dev_lock(hdev);
1485127178d2SJohan Hedberg 
1486127178d2SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1487127178d2SJohan Hedberg 	if (conn && hci_outgoing_auth_needed(hdev, conn)) {
1488127178d2SJohan Hedberg 		struct hci_cp_auth_requested cp;
1489127178d2SJohan Hedberg 		cp.handle = __cpu_to_le16(conn->handle);
1490127178d2SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1491127178d2SJohan Hedberg 	}
1492127178d2SJohan Hedberg 
1493127178d2SJohan Hedberg 	hci_dev_unlock(hdev);
1494a9de9248SMarcel Holtmann }
1495a9de9248SMarcel Holtmann 
1496a9de9248SMarcel Holtmann static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1497a9de9248SMarcel Holtmann {
1498a9de9248SMarcel Holtmann 	struct hci_ev_encrypt_change *ev = (void *) skb->data;
1499a9de9248SMarcel Holtmann 	struct hci_conn *conn;
1500a9de9248SMarcel Holtmann 
1501a9de9248SMarcel Holtmann 	BT_DBG("%s status %d", hdev->name, ev->status);
1502a9de9248SMarcel Holtmann 
1503a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
1504a9de9248SMarcel Holtmann 
1505a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1506a9de9248SMarcel Holtmann 	if (conn) {
1507a9de9248SMarcel Holtmann 		if (!ev->status) {
1508ae293196SMarcel Holtmann 			if (ev->encrypt) {
1509ae293196SMarcel Holtmann 				/* Encryption implies authentication */
1510ae293196SMarcel Holtmann 				conn->link_mode |= HCI_LM_AUTH;
1511a9de9248SMarcel Holtmann 				conn->link_mode |= HCI_LM_ENCRYPT;
1512ae293196SMarcel Holtmann 			} else
1513a9de9248SMarcel Holtmann 				conn->link_mode &= ~HCI_LM_ENCRYPT;
1514a9de9248SMarcel Holtmann 		}
1515a9de9248SMarcel Holtmann 
1516a9de9248SMarcel Holtmann 		clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1517a9de9248SMarcel Holtmann 
1518f8558555SMarcel Holtmann 		if (conn->state == BT_CONFIG) {
1519f8558555SMarcel Holtmann 			if (!ev->status)
1520f8558555SMarcel Holtmann 				conn->state = BT_CONNECTED;
1521f8558555SMarcel Holtmann 
1522f8558555SMarcel Holtmann 			hci_proto_connect_cfm(conn, ev->status);
1523f8558555SMarcel Holtmann 			hci_conn_put(conn);
1524f8558555SMarcel Holtmann 		} else
1525a9de9248SMarcel Holtmann 			hci_encrypt_cfm(conn, ev->status, ev->encrypt);
1526a9de9248SMarcel Holtmann 	}
1527a9de9248SMarcel Holtmann 
1528a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
1529a9de9248SMarcel Holtmann }
1530a9de9248SMarcel Holtmann 
1531a9de9248SMarcel Holtmann static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1532a9de9248SMarcel Holtmann {
1533a9de9248SMarcel Holtmann 	struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1534a9de9248SMarcel Holtmann 	struct hci_conn *conn;
1535a9de9248SMarcel Holtmann 
1536a9de9248SMarcel Holtmann 	BT_DBG("%s status %d", hdev->name, ev->status);
1537a9de9248SMarcel Holtmann 
1538a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
1539a9de9248SMarcel Holtmann 
1540a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1541a9de9248SMarcel Holtmann 	if (conn) {
1542a9de9248SMarcel Holtmann 		if (!ev->status)
1543a9de9248SMarcel Holtmann 			conn->link_mode |= HCI_LM_SECURE;
1544a9de9248SMarcel Holtmann 
1545a9de9248SMarcel Holtmann 		clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1546a9de9248SMarcel Holtmann 
1547a9de9248SMarcel Holtmann 		hci_key_change_cfm(conn, ev->status);
1548a9de9248SMarcel Holtmann 	}
1549a9de9248SMarcel Holtmann 
1550a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
1551a9de9248SMarcel Holtmann }
1552a9de9248SMarcel Holtmann 
1553a9de9248SMarcel Holtmann static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1554a9de9248SMarcel Holtmann {
1555a9de9248SMarcel Holtmann 	struct hci_ev_remote_features *ev = (void *) skb->data;
1556a9de9248SMarcel Holtmann 	struct hci_conn *conn;
1557a9de9248SMarcel Holtmann 
1558a9de9248SMarcel Holtmann 	BT_DBG("%s status %d", hdev->name, ev->status);
1559a9de9248SMarcel Holtmann 
1560a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
1561a9de9248SMarcel Holtmann 
1562a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1563ccd556feSJohan Hedberg 	if (!conn)
1564ccd556feSJohan Hedberg 		goto unlock;
1565ccd556feSJohan Hedberg 
1566769be974SMarcel Holtmann 	if (!ev->status)
1567a9de9248SMarcel Holtmann 		memcpy(conn->features, ev->features, 8);
1568a9de9248SMarcel Holtmann 
1569ccd556feSJohan Hedberg 	if (conn->state != BT_CONFIG)
1570ccd556feSJohan Hedberg 		goto unlock;
1571ccd556feSJohan Hedberg 
1572ccd556feSJohan Hedberg 	if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
1573769be974SMarcel Holtmann 		struct hci_cp_read_remote_ext_features cp;
1574769be974SMarcel Holtmann 		cp.handle = ev->handle;
1575769be974SMarcel Holtmann 		cp.page = 0x01;
1576ccd556feSJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
1577769be974SMarcel Holtmann 							sizeof(cp), &cp);
1578392599b9SJohan Hedberg 		goto unlock;
1579392599b9SJohan Hedberg 	}
1580392599b9SJohan Hedberg 
1581127178d2SJohan Hedberg 	if (!ev->status) {
1582127178d2SJohan Hedberg 		struct hci_cp_remote_name_req cp;
1583127178d2SJohan Hedberg 		memset(&cp, 0, sizeof(cp));
1584127178d2SJohan Hedberg 		bacpy(&cp.bdaddr, &conn->dst);
1585127178d2SJohan Hedberg 		cp.pscan_rep_mode = 0x02;
1586127178d2SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1587127178d2SJohan Hedberg 	}
1588392599b9SJohan Hedberg 
1589127178d2SJohan Hedberg 	if (!hci_outgoing_auth_needed(hdev, conn)) {
1590769be974SMarcel Holtmann 		conn->state = BT_CONNECTED;
1591769be974SMarcel Holtmann 		hci_proto_connect_cfm(conn, ev->status);
1592769be974SMarcel Holtmann 		hci_conn_put(conn);
1593769be974SMarcel Holtmann 	}
1594769be974SMarcel Holtmann 
1595ccd556feSJohan Hedberg unlock:
1596a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
1597a9de9248SMarcel Holtmann }
1598a9de9248SMarcel Holtmann 
1599a9de9248SMarcel Holtmann static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
1600a9de9248SMarcel Holtmann {
1601a9de9248SMarcel Holtmann 	BT_DBG("%s", hdev->name);
1602a9de9248SMarcel Holtmann }
1603a9de9248SMarcel Holtmann 
1604a9de9248SMarcel Holtmann static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1605a9de9248SMarcel Holtmann {
1606a9de9248SMarcel Holtmann 	BT_DBG("%s", hdev->name);
1607a9de9248SMarcel Holtmann }
1608a9de9248SMarcel Holtmann 
1609a9de9248SMarcel Holtmann static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1610a9de9248SMarcel Holtmann {
1611a9de9248SMarcel Holtmann 	struct hci_ev_cmd_complete *ev = (void *) skb->data;
1612a9de9248SMarcel Holtmann 	__u16 opcode;
1613a9de9248SMarcel Holtmann 
1614a9de9248SMarcel Holtmann 	skb_pull(skb, sizeof(*ev));
1615a9de9248SMarcel Holtmann 
1616a9de9248SMarcel Holtmann 	opcode = __le16_to_cpu(ev->opcode);
1617a9de9248SMarcel Holtmann 
1618a9de9248SMarcel Holtmann 	switch (opcode) {
1619a9de9248SMarcel Holtmann 	case HCI_OP_INQUIRY_CANCEL:
1620a9de9248SMarcel Holtmann 		hci_cc_inquiry_cancel(hdev, skb);
1621a9de9248SMarcel Holtmann 		break;
1622a9de9248SMarcel Holtmann 
1623a9de9248SMarcel Holtmann 	case HCI_OP_EXIT_PERIODIC_INQ:
1624a9de9248SMarcel Holtmann 		hci_cc_exit_periodic_inq(hdev, skb);
1625a9de9248SMarcel Holtmann 		break;
1626a9de9248SMarcel Holtmann 
1627a9de9248SMarcel Holtmann 	case HCI_OP_REMOTE_NAME_REQ_CANCEL:
1628a9de9248SMarcel Holtmann 		hci_cc_remote_name_req_cancel(hdev, skb);
1629a9de9248SMarcel Holtmann 		break;
1630a9de9248SMarcel Holtmann 
1631a9de9248SMarcel Holtmann 	case HCI_OP_ROLE_DISCOVERY:
1632a9de9248SMarcel Holtmann 		hci_cc_role_discovery(hdev, skb);
1633a9de9248SMarcel Holtmann 		break;
1634a9de9248SMarcel Holtmann 
1635e4e8e37cSMarcel Holtmann 	case HCI_OP_READ_LINK_POLICY:
1636e4e8e37cSMarcel Holtmann 		hci_cc_read_link_policy(hdev, skb);
1637e4e8e37cSMarcel Holtmann 		break;
1638e4e8e37cSMarcel Holtmann 
1639a9de9248SMarcel Holtmann 	case HCI_OP_WRITE_LINK_POLICY:
1640a9de9248SMarcel Holtmann 		hci_cc_write_link_policy(hdev, skb);
1641a9de9248SMarcel Holtmann 		break;
1642a9de9248SMarcel Holtmann 
1643e4e8e37cSMarcel Holtmann 	case HCI_OP_READ_DEF_LINK_POLICY:
1644e4e8e37cSMarcel Holtmann 		hci_cc_read_def_link_policy(hdev, skb);
1645e4e8e37cSMarcel Holtmann 		break;
1646e4e8e37cSMarcel Holtmann 
1647e4e8e37cSMarcel Holtmann 	case HCI_OP_WRITE_DEF_LINK_POLICY:
1648e4e8e37cSMarcel Holtmann 		hci_cc_write_def_link_policy(hdev, skb);
1649e4e8e37cSMarcel Holtmann 		break;
1650e4e8e37cSMarcel Holtmann 
1651a9de9248SMarcel Holtmann 	case HCI_OP_RESET:
1652a9de9248SMarcel Holtmann 		hci_cc_reset(hdev, skb);
1653a9de9248SMarcel Holtmann 		break;
1654a9de9248SMarcel Holtmann 
1655a9de9248SMarcel Holtmann 	case HCI_OP_WRITE_LOCAL_NAME:
1656a9de9248SMarcel Holtmann 		hci_cc_write_local_name(hdev, skb);
1657a9de9248SMarcel Holtmann 		break;
1658a9de9248SMarcel Holtmann 
1659a9de9248SMarcel Holtmann 	case HCI_OP_READ_LOCAL_NAME:
1660a9de9248SMarcel Holtmann 		hci_cc_read_local_name(hdev, skb);
1661a9de9248SMarcel Holtmann 		break;
1662a9de9248SMarcel Holtmann 
1663a9de9248SMarcel Holtmann 	case HCI_OP_WRITE_AUTH_ENABLE:
1664a9de9248SMarcel Holtmann 		hci_cc_write_auth_enable(hdev, skb);
1665a9de9248SMarcel Holtmann 		break;
1666a9de9248SMarcel Holtmann 
1667a9de9248SMarcel Holtmann 	case HCI_OP_WRITE_ENCRYPT_MODE:
1668a9de9248SMarcel Holtmann 		hci_cc_write_encrypt_mode(hdev, skb);
1669a9de9248SMarcel Holtmann 		break;
1670a9de9248SMarcel Holtmann 
1671a9de9248SMarcel Holtmann 	case HCI_OP_WRITE_SCAN_ENABLE:
1672a9de9248SMarcel Holtmann 		hci_cc_write_scan_enable(hdev, skb);
1673a9de9248SMarcel Holtmann 		break;
1674a9de9248SMarcel Holtmann 
1675a9de9248SMarcel Holtmann 	case HCI_OP_READ_CLASS_OF_DEV:
1676a9de9248SMarcel Holtmann 		hci_cc_read_class_of_dev(hdev, skb);
1677a9de9248SMarcel Holtmann 		break;
1678a9de9248SMarcel Holtmann 
1679a9de9248SMarcel Holtmann 	case HCI_OP_WRITE_CLASS_OF_DEV:
1680a9de9248SMarcel Holtmann 		hci_cc_write_class_of_dev(hdev, skb);
1681a9de9248SMarcel Holtmann 		break;
1682a9de9248SMarcel Holtmann 
1683a9de9248SMarcel Holtmann 	case HCI_OP_READ_VOICE_SETTING:
1684a9de9248SMarcel Holtmann 		hci_cc_read_voice_setting(hdev, skb);
1685a9de9248SMarcel Holtmann 		break;
1686a9de9248SMarcel Holtmann 
1687a9de9248SMarcel Holtmann 	case HCI_OP_WRITE_VOICE_SETTING:
1688a9de9248SMarcel Holtmann 		hci_cc_write_voice_setting(hdev, skb);
1689a9de9248SMarcel Holtmann 		break;
1690a9de9248SMarcel Holtmann 
1691a9de9248SMarcel Holtmann 	case HCI_OP_HOST_BUFFER_SIZE:
1692a9de9248SMarcel Holtmann 		hci_cc_host_buffer_size(hdev, skb);
1693a9de9248SMarcel Holtmann 		break;
1694a9de9248SMarcel Holtmann 
1695333140b5SMarcel Holtmann 	case HCI_OP_READ_SSP_MODE:
1696333140b5SMarcel Holtmann 		hci_cc_read_ssp_mode(hdev, skb);
1697333140b5SMarcel Holtmann 		break;
1698333140b5SMarcel Holtmann 
1699333140b5SMarcel Holtmann 	case HCI_OP_WRITE_SSP_MODE:
1700333140b5SMarcel Holtmann 		hci_cc_write_ssp_mode(hdev, skb);
1701333140b5SMarcel Holtmann 		break;
1702333140b5SMarcel Holtmann 
1703a9de9248SMarcel Holtmann 	case HCI_OP_READ_LOCAL_VERSION:
1704a9de9248SMarcel Holtmann 		hci_cc_read_local_version(hdev, skb);
1705a9de9248SMarcel Holtmann 		break;
1706a9de9248SMarcel Holtmann 
1707a9de9248SMarcel Holtmann 	case HCI_OP_READ_LOCAL_COMMANDS:
1708a9de9248SMarcel Holtmann 		hci_cc_read_local_commands(hdev, skb);
1709a9de9248SMarcel Holtmann 		break;
1710a9de9248SMarcel Holtmann 
1711a9de9248SMarcel Holtmann 	case HCI_OP_READ_LOCAL_FEATURES:
1712a9de9248SMarcel Holtmann 		hci_cc_read_local_features(hdev, skb);
1713a9de9248SMarcel Holtmann 		break;
1714a9de9248SMarcel Holtmann 
1715a9de9248SMarcel Holtmann 	case HCI_OP_READ_BUFFER_SIZE:
1716a9de9248SMarcel Holtmann 		hci_cc_read_buffer_size(hdev, skb);
1717a9de9248SMarcel Holtmann 		break;
1718a9de9248SMarcel Holtmann 
1719a9de9248SMarcel Holtmann 	case HCI_OP_READ_BD_ADDR:
1720a9de9248SMarcel Holtmann 		hci_cc_read_bd_addr(hdev, skb);
1721a9de9248SMarcel Holtmann 		break;
1722a9de9248SMarcel Holtmann 
172323bb5763SJohan Hedberg 	case HCI_OP_WRITE_CA_TIMEOUT:
172423bb5763SJohan Hedberg 		hci_cc_write_ca_timeout(hdev, skb);
172523bb5763SJohan Hedberg 		break;
172623bb5763SJohan Hedberg 
1727b0916ea0SJohan Hedberg 	case HCI_OP_DELETE_STORED_LINK_KEY:
1728b0916ea0SJohan Hedberg 		hci_cc_delete_stored_link_key(hdev, skb);
1729b0916ea0SJohan Hedberg 		break;
1730b0916ea0SJohan Hedberg 
1731d5859e22SJohan Hedberg 	case HCI_OP_SET_EVENT_MASK:
1732d5859e22SJohan Hedberg 		hci_cc_set_event_mask(hdev, skb);
1733d5859e22SJohan Hedberg 		break;
1734d5859e22SJohan Hedberg 
1735d5859e22SJohan Hedberg 	case HCI_OP_WRITE_INQUIRY_MODE:
1736d5859e22SJohan Hedberg 		hci_cc_write_inquiry_mode(hdev, skb);
1737d5859e22SJohan Hedberg 		break;
1738d5859e22SJohan Hedberg 
1739d5859e22SJohan Hedberg 	case HCI_OP_READ_INQ_RSP_TX_POWER:
1740d5859e22SJohan Hedberg 		hci_cc_read_inq_rsp_tx_power(hdev, skb);
1741d5859e22SJohan Hedberg 		break;
1742d5859e22SJohan Hedberg 
1743d5859e22SJohan Hedberg 	case HCI_OP_SET_EVENT_FLT:
1744d5859e22SJohan Hedberg 		hci_cc_set_event_flt(hdev, skb);
1745d5859e22SJohan Hedberg 		break;
1746d5859e22SJohan Hedberg 
1747980e1a53SJohan Hedberg 	case HCI_OP_PIN_CODE_REPLY:
1748980e1a53SJohan Hedberg 		hci_cc_pin_code_reply(hdev, skb);
1749980e1a53SJohan Hedberg 		break;
1750980e1a53SJohan Hedberg 
1751980e1a53SJohan Hedberg 	case HCI_OP_PIN_CODE_NEG_REPLY:
1752980e1a53SJohan Hedberg 		hci_cc_pin_code_neg_reply(hdev, skb);
1753980e1a53SJohan Hedberg 		break;
1754980e1a53SJohan Hedberg 
17556ed58ec5SVille Tervo 	case HCI_OP_LE_READ_BUFFER_SIZE:
17566ed58ec5SVille Tervo 		hci_cc_le_read_buffer_size(hdev, skb);
17576ed58ec5SVille Tervo 		break;
17586ed58ec5SVille Tervo 
1759a5c29683SJohan Hedberg 	case HCI_OP_USER_CONFIRM_REPLY:
1760a5c29683SJohan Hedberg 		hci_cc_user_confirm_reply(hdev, skb);
1761a5c29683SJohan Hedberg 		break;
1762a5c29683SJohan Hedberg 
1763a5c29683SJohan Hedberg 	case HCI_OP_USER_CONFIRM_NEG_REPLY:
1764a5c29683SJohan Hedberg 		hci_cc_user_confirm_neg_reply(hdev, skb);
1765a5c29683SJohan Hedberg 		break;
1766a5c29683SJohan Hedberg 
1767a9de9248SMarcel Holtmann 	default:
1768a9de9248SMarcel Holtmann 		BT_DBG("%s opcode 0x%x", hdev->name, opcode);
1769a9de9248SMarcel Holtmann 		break;
1770a9de9248SMarcel Holtmann 	}
1771a9de9248SMarcel Holtmann 
17726bd32326SVille Tervo 	if (ev->opcode != HCI_OP_NOP)
17736bd32326SVille Tervo 		del_timer(&hdev->cmd_timer);
17746bd32326SVille Tervo 
1775a9de9248SMarcel Holtmann 	if (ev->ncmd) {
1776a9de9248SMarcel Holtmann 		atomic_set(&hdev->cmd_cnt, 1);
1777a9de9248SMarcel Holtmann 		if (!skb_queue_empty(&hdev->cmd_q))
1778c78ae283SMarcel Holtmann 			tasklet_schedule(&hdev->cmd_task);
1779a9de9248SMarcel Holtmann 	}
1780a9de9248SMarcel Holtmann }
1781a9de9248SMarcel Holtmann 
1782a9de9248SMarcel Holtmann static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
1783a9de9248SMarcel Holtmann {
1784a9de9248SMarcel Holtmann 	struct hci_ev_cmd_status *ev = (void *) skb->data;
1785a9de9248SMarcel Holtmann 	__u16 opcode;
1786a9de9248SMarcel Holtmann 
1787a9de9248SMarcel Holtmann 	skb_pull(skb, sizeof(*ev));
1788a9de9248SMarcel Holtmann 
1789a9de9248SMarcel Holtmann 	opcode = __le16_to_cpu(ev->opcode);
1790a9de9248SMarcel Holtmann 
1791a9de9248SMarcel Holtmann 	switch (opcode) {
1792a9de9248SMarcel Holtmann 	case HCI_OP_INQUIRY:
1793a9de9248SMarcel Holtmann 		hci_cs_inquiry(hdev, ev->status);
1794a9de9248SMarcel Holtmann 		break;
1795a9de9248SMarcel Holtmann 
1796a9de9248SMarcel Holtmann 	case HCI_OP_CREATE_CONN:
1797a9de9248SMarcel Holtmann 		hci_cs_create_conn(hdev, ev->status);
1798a9de9248SMarcel Holtmann 		break;
1799a9de9248SMarcel Holtmann 
1800a9de9248SMarcel Holtmann 	case HCI_OP_ADD_SCO:
1801a9de9248SMarcel Holtmann 		hci_cs_add_sco(hdev, ev->status);
1802a9de9248SMarcel Holtmann 		break;
1803a9de9248SMarcel Holtmann 
1804f8558555SMarcel Holtmann 	case HCI_OP_AUTH_REQUESTED:
1805f8558555SMarcel Holtmann 		hci_cs_auth_requested(hdev, ev->status);
1806f8558555SMarcel Holtmann 		break;
1807f8558555SMarcel Holtmann 
1808f8558555SMarcel Holtmann 	case HCI_OP_SET_CONN_ENCRYPT:
1809f8558555SMarcel Holtmann 		hci_cs_set_conn_encrypt(hdev, ev->status);
1810f8558555SMarcel Holtmann 		break;
1811f8558555SMarcel Holtmann 
1812a9de9248SMarcel Holtmann 	case HCI_OP_REMOTE_NAME_REQ:
1813a9de9248SMarcel Holtmann 		hci_cs_remote_name_req(hdev, ev->status);
1814a9de9248SMarcel Holtmann 		break;
1815a9de9248SMarcel Holtmann 
1816769be974SMarcel Holtmann 	case HCI_OP_READ_REMOTE_FEATURES:
1817769be974SMarcel Holtmann 		hci_cs_read_remote_features(hdev, ev->status);
1818769be974SMarcel Holtmann 		break;
1819769be974SMarcel Holtmann 
1820769be974SMarcel Holtmann 	case HCI_OP_READ_REMOTE_EXT_FEATURES:
1821769be974SMarcel Holtmann 		hci_cs_read_remote_ext_features(hdev, ev->status);
1822769be974SMarcel Holtmann 		break;
1823769be974SMarcel Holtmann 
1824a9de9248SMarcel Holtmann 	case HCI_OP_SETUP_SYNC_CONN:
1825a9de9248SMarcel Holtmann 		hci_cs_setup_sync_conn(hdev, ev->status);
1826a9de9248SMarcel Holtmann 		break;
1827a9de9248SMarcel Holtmann 
1828a9de9248SMarcel Holtmann 	case HCI_OP_SNIFF_MODE:
1829a9de9248SMarcel Holtmann 		hci_cs_sniff_mode(hdev, ev->status);
1830a9de9248SMarcel Holtmann 		break;
1831a9de9248SMarcel Holtmann 
1832a9de9248SMarcel Holtmann 	case HCI_OP_EXIT_SNIFF_MODE:
1833a9de9248SMarcel Holtmann 		hci_cs_exit_sniff_mode(hdev, ev->status);
1834a9de9248SMarcel Holtmann 		break;
1835a9de9248SMarcel Holtmann 
18368962ee74SJohan Hedberg 	case HCI_OP_DISCONNECT:
18378962ee74SJohan Hedberg 		if (ev->status != 0)
18388962ee74SJohan Hedberg 			mgmt_disconnect_failed(hdev->id);
18398962ee74SJohan Hedberg 		break;
18408962ee74SJohan Hedberg 
1841fcd89c09SVille Tervo 	case HCI_OP_LE_CREATE_CONN:
1842fcd89c09SVille Tervo 		hci_cs_le_create_conn(hdev, ev->status);
1843fcd89c09SVille Tervo 		break;
1844fcd89c09SVille Tervo 
1845a9de9248SMarcel Holtmann 	default:
1846a9de9248SMarcel Holtmann 		BT_DBG("%s opcode 0x%x", hdev->name, opcode);
1847a9de9248SMarcel Holtmann 		break;
1848a9de9248SMarcel Holtmann 	}
1849a9de9248SMarcel Holtmann 
18506bd32326SVille Tervo 	if (ev->opcode != HCI_OP_NOP)
18516bd32326SVille Tervo 		del_timer(&hdev->cmd_timer);
18526bd32326SVille Tervo 
1853a9de9248SMarcel Holtmann 	if (ev->ncmd) {
1854a9de9248SMarcel Holtmann 		atomic_set(&hdev->cmd_cnt, 1);
1855a9de9248SMarcel Holtmann 		if (!skb_queue_empty(&hdev->cmd_q))
1856c78ae283SMarcel Holtmann 			tasklet_schedule(&hdev->cmd_task);
1857a9de9248SMarcel Holtmann 	}
1858a9de9248SMarcel Holtmann }
1859a9de9248SMarcel Holtmann 
1860a9de9248SMarcel Holtmann static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1861a9de9248SMarcel Holtmann {
1862a9de9248SMarcel Holtmann 	struct hci_ev_role_change *ev = (void *) skb->data;
1863a9de9248SMarcel Holtmann 	struct hci_conn *conn;
1864a9de9248SMarcel Holtmann 
1865a9de9248SMarcel Holtmann 	BT_DBG("%s status %d", hdev->name, ev->status);
1866a9de9248SMarcel Holtmann 
1867a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
1868a9de9248SMarcel Holtmann 
1869a9de9248SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1870a9de9248SMarcel Holtmann 	if (conn) {
1871a9de9248SMarcel Holtmann 		if (!ev->status) {
1872a9de9248SMarcel Holtmann 			if (ev->role)
1873a9de9248SMarcel Holtmann 				conn->link_mode &= ~HCI_LM_MASTER;
1874a9de9248SMarcel Holtmann 			else
1875a9de9248SMarcel Holtmann 				conn->link_mode |= HCI_LM_MASTER;
1876a9de9248SMarcel Holtmann 		}
1877a9de9248SMarcel Holtmann 
1878a9de9248SMarcel Holtmann 		clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
1879a9de9248SMarcel Holtmann 
1880a9de9248SMarcel Holtmann 		hci_role_switch_cfm(conn, ev->status, ev->role);
1881a9de9248SMarcel Holtmann 	}
1882a9de9248SMarcel Holtmann 
1883a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
1884a9de9248SMarcel Holtmann }
1885a9de9248SMarcel Holtmann 
18861da177e4SLinus Torvalds static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
18871da177e4SLinus Torvalds {
1888a9de9248SMarcel Holtmann 	struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
18891ebb9252SMarcel Holtmann 	__le16 *ptr;
18901da177e4SLinus Torvalds 	int i;
18911da177e4SLinus Torvalds 
18921da177e4SLinus Torvalds 	skb_pull(skb, sizeof(*ev));
18931da177e4SLinus Torvalds 
18941da177e4SLinus Torvalds 	BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
18951da177e4SLinus Torvalds 
18961da177e4SLinus Torvalds 	if (skb->len < ev->num_hndl * 4) {
18971da177e4SLinus Torvalds 		BT_DBG("%s bad parameters", hdev->name);
18981da177e4SLinus Torvalds 		return;
18991da177e4SLinus Torvalds 	}
19001da177e4SLinus Torvalds 
19011da177e4SLinus Torvalds 	tasklet_disable(&hdev->tx_task);
19021da177e4SLinus Torvalds 
19031ebb9252SMarcel Holtmann 	for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
19041da177e4SLinus Torvalds 		struct hci_conn *conn;
19051da177e4SLinus Torvalds 		__u16  handle, count;
19061da177e4SLinus Torvalds 
190783985319SHarvey Harrison 		handle = get_unaligned_le16(ptr++);
190883985319SHarvey Harrison 		count  = get_unaligned_le16(ptr++);
19091da177e4SLinus Torvalds 
19101da177e4SLinus Torvalds 		conn = hci_conn_hash_lookup_handle(hdev, handle);
19111da177e4SLinus Torvalds 		if (conn) {
19121da177e4SLinus Torvalds 			conn->sent -= count;
19131da177e4SLinus Torvalds 
19145b7f9909SMarcel Holtmann 			if (conn->type == ACL_LINK) {
191570f23020SAndrei Emeltchenko 				hdev->acl_cnt += count;
191670f23020SAndrei Emeltchenko 				if (hdev->acl_cnt > hdev->acl_pkts)
19171da177e4SLinus Torvalds 					hdev->acl_cnt = hdev->acl_pkts;
19186ed58ec5SVille Tervo 			} else if (conn->type == LE_LINK) {
19196ed58ec5SVille Tervo 				if (hdev->le_pkts) {
19206ed58ec5SVille Tervo 					hdev->le_cnt += count;
19216ed58ec5SVille Tervo 					if (hdev->le_cnt > hdev->le_pkts)
19226ed58ec5SVille Tervo 						hdev->le_cnt = hdev->le_pkts;
19236ed58ec5SVille Tervo 				} else {
19246ed58ec5SVille Tervo 					hdev->acl_cnt += count;
19256ed58ec5SVille Tervo 					if (hdev->acl_cnt > hdev->acl_pkts)
19266ed58ec5SVille Tervo 						hdev->acl_cnt = hdev->acl_pkts;
19276ed58ec5SVille Tervo 				}
19285b7f9909SMarcel Holtmann 			} else {
192970f23020SAndrei Emeltchenko 				hdev->sco_cnt += count;
193070f23020SAndrei Emeltchenko 				if (hdev->sco_cnt > hdev->sco_pkts)
19315b7f9909SMarcel Holtmann 					hdev->sco_cnt = hdev->sco_pkts;
19321da177e4SLinus Torvalds 			}
19331da177e4SLinus Torvalds 		}
19341da177e4SLinus Torvalds 	}
1935a9de9248SMarcel Holtmann 
1936c78ae283SMarcel Holtmann 	tasklet_schedule(&hdev->tx_task);
19371da177e4SLinus Torvalds 
19381da177e4SLinus Torvalds 	tasklet_enable(&hdev->tx_task);
19391da177e4SLinus Torvalds }
19401da177e4SLinus Torvalds 
194104837f64SMarcel Holtmann static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
19421da177e4SLinus Torvalds {
1943a9de9248SMarcel Holtmann 	struct hci_ev_mode_change *ev = (void *) skb->data;
194404837f64SMarcel Holtmann 	struct hci_conn *conn;
19451da177e4SLinus Torvalds 
19461da177e4SLinus Torvalds 	BT_DBG("%s status %d", hdev->name, ev->status);
19471da177e4SLinus Torvalds 
19481da177e4SLinus Torvalds 	hci_dev_lock(hdev);
19491da177e4SLinus Torvalds 
195004837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
195104837f64SMarcel Holtmann 	if (conn) {
195204837f64SMarcel Holtmann 		conn->mode = ev->mode;
195304837f64SMarcel Holtmann 		conn->interval = __le16_to_cpu(ev->interval);
195404837f64SMarcel Holtmann 
195504837f64SMarcel Holtmann 		if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
195604837f64SMarcel Holtmann 			if (conn->mode == HCI_CM_ACTIVE)
195704837f64SMarcel Holtmann 				conn->power_save = 1;
195804837f64SMarcel Holtmann 			else
195904837f64SMarcel Holtmann 				conn->power_save = 0;
196004837f64SMarcel Holtmann 		}
1961e73439d8SMarcel Holtmann 
1962e73439d8SMarcel Holtmann 		if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1963e73439d8SMarcel Holtmann 			hci_sco_setup(conn, ev->status);
196404837f64SMarcel Holtmann 	}
196504837f64SMarcel Holtmann 
196604837f64SMarcel Holtmann 	hci_dev_unlock(hdev);
196704837f64SMarcel Holtmann }
196804837f64SMarcel Holtmann 
19691da177e4SLinus Torvalds static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
19701da177e4SLinus Torvalds {
1971052b30b0SMarcel Holtmann 	struct hci_ev_pin_code_req *ev = (void *) skb->data;
1972052b30b0SMarcel Holtmann 	struct hci_conn *conn;
1973052b30b0SMarcel Holtmann 
1974a9de9248SMarcel Holtmann 	BT_DBG("%s", hdev->name);
1975052b30b0SMarcel Holtmann 
1976052b30b0SMarcel Holtmann 	hci_dev_lock(hdev);
1977052b30b0SMarcel Holtmann 
1978052b30b0SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
19793d7a9d1cSMarcel Holtmann 	if (conn && conn->state == BT_CONNECTED) {
1980052b30b0SMarcel Holtmann 		hci_conn_hold(conn);
1981052b30b0SMarcel Holtmann 		conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1982052b30b0SMarcel Holtmann 		hci_conn_put(conn);
1983052b30b0SMarcel Holtmann 	}
1984052b30b0SMarcel Holtmann 
198503b555e1SJohan Hedberg 	if (!test_bit(HCI_PAIRABLE, &hdev->flags))
198603b555e1SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
198703b555e1SJohan Hedberg 					sizeof(ev->bdaddr), &ev->bdaddr);
198803b555e1SJohan Hedberg 
1989980e1a53SJohan Hedberg 	if (test_bit(HCI_MGMT, &hdev->flags))
1990980e1a53SJohan Hedberg 		mgmt_pin_code_request(hdev->id, &ev->bdaddr);
1991980e1a53SJohan Hedberg 
1992052b30b0SMarcel Holtmann 	hci_dev_unlock(hdev);
19931da177e4SLinus Torvalds }
19941da177e4SLinus Torvalds 
19951da177e4SLinus Torvalds static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
19961da177e4SLinus Torvalds {
199755ed8ca1SJohan Hedberg 	struct hci_ev_link_key_req *ev = (void *) skb->data;
199855ed8ca1SJohan Hedberg 	struct hci_cp_link_key_reply cp;
199955ed8ca1SJohan Hedberg 	struct hci_conn *conn;
200055ed8ca1SJohan Hedberg 	struct link_key *key;
200155ed8ca1SJohan Hedberg 
2002a9de9248SMarcel Holtmann 	BT_DBG("%s", hdev->name);
200355ed8ca1SJohan Hedberg 
200455ed8ca1SJohan Hedberg 	if (!test_bit(HCI_LINK_KEYS, &hdev->flags))
200555ed8ca1SJohan Hedberg 		return;
200655ed8ca1SJohan Hedberg 
200755ed8ca1SJohan Hedberg 	hci_dev_lock(hdev);
200855ed8ca1SJohan Hedberg 
200955ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, &ev->bdaddr);
201055ed8ca1SJohan Hedberg 	if (!key) {
201155ed8ca1SJohan Hedberg 		BT_DBG("%s link key not found for %s", hdev->name,
201255ed8ca1SJohan Hedberg 							batostr(&ev->bdaddr));
201355ed8ca1SJohan Hedberg 		goto not_found;
201455ed8ca1SJohan Hedberg 	}
201555ed8ca1SJohan Hedberg 
201655ed8ca1SJohan Hedberg 	BT_DBG("%s found key type %u for %s", hdev->name, key->type,
201755ed8ca1SJohan Hedberg 							batostr(&ev->bdaddr));
201855ed8ca1SJohan Hedberg 
201955ed8ca1SJohan Hedberg 	if (!test_bit(HCI_DEBUG_KEYS, &hdev->flags) && key->type == 0x03) {
202055ed8ca1SJohan Hedberg 		BT_DBG("%s ignoring debug key", hdev->name);
202155ed8ca1SJohan Hedberg 		goto not_found;
202255ed8ca1SJohan Hedberg 	}
202355ed8ca1SJohan Hedberg 
202455ed8ca1SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
202555ed8ca1SJohan Hedberg 
202655ed8ca1SJohan Hedberg 	if (key->type == 0x04 && conn && conn->auth_type != 0xff &&
202755ed8ca1SJohan Hedberg 						(conn->auth_type & 0x01)) {
202855ed8ca1SJohan Hedberg 		BT_DBG("%s ignoring unauthenticated key", hdev->name);
202955ed8ca1SJohan Hedberg 		goto not_found;
203055ed8ca1SJohan Hedberg 	}
203155ed8ca1SJohan Hedberg 
203255ed8ca1SJohan Hedberg 	bacpy(&cp.bdaddr, &ev->bdaddr);
203355ed8ca1SJohan Hedberg 	memcpy(cp.link_key, key->val, 16);
203455ed8ca1SJohan Hedberg 
203555ed8ca1SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
203655ed8ca1SJohan Hedberg 
203755ed8ca1SJohan Hedberg 	hci_dev_unlock(hdev);
203855ed8ca1SJohan Hedberg 
203955ed8ca1SJohan Hedberg 	return;
204055ed8ca1SJohan Hedberg 
204155ed8ca1SJohan Hedberg not_found:
204255ed8ca1SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
204355ed8ca1SJohan Hedberg 	hci_dev_unlock(hdev);
20441da177e4SLinus Torvalds }
20451da177e4SLinus Torvalds 
20461da177e4SLinus Torvalds static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
20471da177e4SLinus Torvalds {
2048052b30b0SMarcel Holtmann 	struct hci_ev_link_key_notify *ev = (void *) skb->data;
2049052b30b0SMarcel Holtmann 	struct hci_conn *conn;
205055ed8ca1SJohan Hedberg 	u8 pin_len = 0;
2051052b30b0SMarcel Holtmann 
2052a9de9248SMarcel Holtmann 	BT_DBG("%s", hdev->name);
2053052b30b0SMarcel Holtmann 
2054052b30b0SMarcel Holtmann 	hci_dev_lock(hdev);
2055052b30b0SMarcel Holtmann 
2056052b30b0SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2057052b30b0SMarcel Holtmann 	if (conn) {
2058052b30b0SMarcel Holtmann 		hci_conn_hold(conn);
2059052b30b0SMarcel Holtmann 		conn->disc_timeout = HCI_DISCONN_TIMEOUT;
2060980e1a53SJohan Hedberg 		pin_len = conn->pin_length;
2061052b30b0SMarcel Holtmann 		hci_conn_put(conn);
2062052b30b0SMarcel Holtmann 	}
2063052b30b0SMarcel Holtmann 
206455ed8ca1SJohan Hedberg 	if (test_bit(HCI_LINK_KEYS, &hdev->flags))
206555ed8ca1SJohan Hedberg 		hci_add_link_key(hdev, 1, &ev->bdaddr, ev->link_key,
206655ed8ca1SJohan Hedberg 							ev->key_type, pin_len);
206755ed8ca1SJohan Hedberg 
2068052b30b0SMarcel Holtmann 	hci_dev_unlock(hdev);
20691da177e4SLinus Torvalds }
20701da177e4SLinus Torvalds 
207104837f64SMarcel Holtmann static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
207204837f64SMarcel Holtmann {
2073a9de9248SMarcel Holtmann 	struct hci_ev_clock_offset *ev = (void *) skb->data;
207404837f64SMarcel Holtmann 	struct hci_conn *conn;
207504837f64SMarcel Holtmann 
207604837f64SMarcel Holtmann 	BT_DBG("%s status %d", hdev->name, ev->status);
207704837f64SMarcel Holtmann 
207804837f64SMarcel Holtmann 	hci_dev_lock(hdev);
207904837f64SMarcel Holtmann 
208004837f64SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
20811da177e4SLinus Torvalds 	if (conn && !ev->status) {
20821da177e4SLinus Torvalds 		struct inquiry_entry *ie;
20831da177e4SLinus Torvalds 
2084cc11b9c1SAndrei Emeltchenko 		ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2085cc11b9c1SAndrei Emeltchenko 		if (ie) {
20861da177e4SLinus Torvalds 			ie->data.clock_offset = ev->clock_offset;
20871da177e4SLinus Torvalds 			ie->timestamp = jiffies;
20881da177e4SLinus Torvalds 		}
20891da177e4SLinus Torvalds 	}
20901da177e4SLinus Torvalds 
20911da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
20921da177e4SLinus Torvalds }
20931da177e4SLinus Torvalds 
2094a8746417SMarcel Holtmann static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2095a8746417SMarcel Holtmann {
2096a8746417SMarcel Holtmann 	struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2097a8746417SMarcel Holtmann 	struct hci_conn *conn;
2098a8746417SMarcel Holtmann 
2099a8746417SMarcel Holtmann 	BT_DBG("%s status %d", hdev->name, ev->status);
2100a8746417SMarcel Holtmann 
2101a8746417SMarcel Holtmann 	hci_dev_lock(hdev);
2102a8746417SMarcel Holtmann 
2103a8746417SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2104a8746417SMarcel Holtmann 	if (conn && !ev->status)
2105a8746417SMarcel Holtmann 		conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2106a8746417SMarcel Holtmann 
2107a8746417SMarcel Holtmann 	hci_dev_unlock(hdev);
2108a8746417SMarcel Holtmann }
2109a8746417SMarcel Holtmann 
211085a1e930SMarcel Holtmann static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
211185a1e930SMarcel Holtmann {
2112a9de9248SMarcel Holtmann 	struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
211385a1e930SMarcel Holtmann 	struct inquiry_entry *ie;
211485a1e930SMarcel Holtmann 
211585a1e930SMarcel Holtmann 	BT_DBG("%s", hdev->name);
211685a1e930SMarcel Holtmann 
211785a1e930SMarcel Holtmann 	hci_dev_lock(hdev);
211885a1e930SMarcel Holtmann 
2119cc11b9c1SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2120cc11b9c1SAndrei Emeltchenko 	if (ie) {
212185a1e930SMarcel Holtmann 		ie->data.pscan_rep_mode = ev->pscan_rep_mode;
212285a1e930SMarcel Holtmann 		ie->timestamp = jiffies;
212385a1e930SMarcel Holtmann 	}
212485a1e930SMarcel Holtmann 
212585a1e930SMarcel Holtmann 	hci_dev_unlock(hdev);
212685a1e930SMarcel Holtmann }
212785a1e930SMarcel Holtmann 
2128a9de9248SMarcel Holtmann static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2129a9de9248SMarcel Holtmann {
2130a9de9248SMarcel Holtmann 	struct inquiry_data data;
2131a9de9248SMarcel Holtmann 	int num_rsp = *((__u8 *) skb->data);
2132a9de9248SMarcel Holtmann 
2133a9de9248SMarcel Holtmann 	BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2134a9de9248SMarcel Holtmann 
2135a9de9248SMarcel Holtmann 	if (!num_rsp)
2136a9de9248SMarcel Holtmann 		return;
2137a9de9248SMarcel Holtmann 
2138a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
2139a9de9248SMarcel Holtmann 
2140a9de9248SMarcel Holtmann 	if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
2141138d22efSSzymon Janc 		struct inquiry_info_with_rssi_and_pscan_mode *info;
2142138d22efSSzymon Janc 		info = (void *) (skb->data + 1);
2143a9de9248SMarcel Holtmann 
2144a9de9248SMarcel Holtmann 		for (; num_rsp; num_rsp--) {
2145a9de9248SMarcel Holtmann 			bacpy(&data.bdaddr, &info->bdaddr);
2146a9de9248SMarcel Holtmann 			data.pscan_rep_mode	= info->pscan_rep_mode;
2147a9de9248SMarcel Holtmann 			data.pscan_period_mode	= info->pscan_period_mode;
2148a9de9248SMarcel Holtmann 			data.pscan_mode		= info->pscan_mode;
2149a9de9248SMarcel Holtmann 			memcpy(data.dev_class, info->dev_class, 3);
2150a9de9248SMarcel Holtmann 			data.clock_offset	= info->clock_offset;
2151a9de9248SMarcel Holtmann 			data.rssi		= info->rssi;
215241a96212SMarcel Holtmann 			data.ssp_mode		= 0x00;
2153a9de9248SMarcel Holtmann 			info++;
2154a9de9248SMarcel Holtmann 			hci_inquiry_cache_update(hdev, &data);
2155a9de9248SMarcel Holtmann 		}
2156a9de9248SMarcel Holtmann 	} else {
2157a9de9248SMarcel Holtmann 		struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2158a9de9248SMarcel Holtmann 
2159a9de9248SMarcel Holtmann 		for (; num_rsp; num_rsp--) {
2160a9de9248SMarcel Holtmann 			bacpy(&data.bdaddr, &info->bdaddr);
2161a9de9248SMarcel Holtmann 			data.pscan_rep_mode	= info->pscan_rep_mode;
2162a9de9248SMarcel Holtmann 			data.pscan_period_mode	= info->pscan_period_mode;
2163a9de9248SMarcel Holtmann 			data.pscan_mode		= 0x00;
2164a9de9248SMarcel Holtmann 			memcpy(data.dev_class, info->dev_class, 3);
2165a9de9248SMarcel Holtmann 			data.clock_offset	= info->clock_offset;
2166a9de9248SMarcel Holtmann 			data.rssi		= info->rssi;
216741a96212SMarcel Holtmann 			data.ssp_mode		= 0x00;
2168a9de9248SMarcel Holtmann 			info++;
2169a9de9248SMarcel Holtmann 			hci_inquiry_cache_update(hdev, &data);
2170a9de9248SMarcel Holtmann 		}
2171a9de9248SMarcel Holtmann 	}
2172a9de9248SMarcel Holtmann 
2173a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
2174a9de9248SMarcel Holtmann }
2175a9de9248SMarcel Holtmann 
2176a9de9248SMarcel Holtmann static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2177a9de9248SMarcel Holtmann {
217841a96212SMarcel Holtmann 	struct hci_ev_remote_ext_features *ev = (void *) skb->data;
217941a96212SMarcel Holtmann 	struct hci_conn *conn;
218041a96212SMarcel Holtmann 
2181a9de9248SMarcel Holtmann 	BT_DBG("%s", hdev->name);
218241a96212SMarcel Holtmann 
218341a96212SMarcel Holtmann 	hci_dev_lock(hdev);
218441a96212SMarcel Holtmann 
218541a96212SMarcel Holtmann 	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2186ccd556feSJohan Hedberg 	if (!conn)
2187ccd556feSJohan Hedberg 		goto unlock;
2188ccd556feSJohan Hedberg 
2189769be974SMarcel Holtmann 	if (!ev->status && ev->page == 0x01) {
219041a96212SMarcel Holtmann 		struct inquiry_entry *ie;
219141a96212SMarcel Holtmann 
2192cc11b9c1SAndrei Emeltchenko 		ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2193cc11b9c1SAndrei Emeltchenko 		if (ie)
219441a96212SMarcel Holtmann 			ie->data.ssp_mode = (ev->features[0] & 0x01);
219541a96212SMarcel Holtmann 
219641a96212SMarcel Holtmann 		conn->ssp_mode = (ev->features[0] & 0x01);
219741a96212SMarcel Holtmann 	}
219841a96212SMarcel Holtmann 
2199ccd556feSJohan Hedberg 	if (conn->state != BT_CONFIG)
2200ccd556feSJohan Hedberg 		goto unlock;
2201ccd556feSJohan Hedberg 
2202127178d2SJohan Hedberg 	if (!ev->status) {
2203127178d2SJohan Hedberg 		struct hci_cp_remote_name_req cp;
2204127178d2SJohan Hedberg 		memset(&cp, 0, sizeof(cp));
2205127178d2SJohan Hedberg 		bacpy(&cp.bdaddr, &conn->dst);
2206127178d2SJohan Hedberg 		cp.pscan_rep_mode = 0x02;
2207127178d2SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
2208127178d2SJohan Hedberg 	}
2209392599b9SJohan Hedberg 
2210127178d2SJohan Hedberg 	if (!hci_outgoing_auth_needed(hdev, conn)) {
2211769be974SMarcel Holtmann 		conn->state = BT_CONNECTED;
2212769be974SMarcel Holtmann 		hci_proto_connect_cfm(conn, ev->status);
2213769be974SMarcel Holtmann 		hci_conn_put(conn);
2214769be974SMarcel Holtmann 	}
2215769be974SMarcel Holtmann 
2216ccd556feSJohan Hedberg unlock:
221741a96212SMarcel Holtmann 	hci_dev_unlock(hdev);
2218a9de9248SMarcel Holtmann }
2219a9de9248SMarcel Holtmann 
2220a9de9248SMarcel Holtmann static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2221a9de9248SMarcel Holtmann {
2222b6a0dc82SMarcel Holtmann 	struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2223b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
2224b6a0dc82SMarcel Holtmann 
2225b6a0dc82SMarcel Holtmann 	BT_DBG("%s status %d", hdev->name, ev->status);
2226b6a0dc82SMarcel Holtmann 
2227b6a0dc82SMarcel Holtmann 	hci_dev_lock(hdev);
2228b6a0dc82SMarcel Holtmann 
2229b6a0dc82SMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
22309dc0a3afSMarcel Holtmann 	if (!conn) {
22319dc0a3afSMarcel Holtmann 		if (ev->link_type == ESCO_LINK)
22329dc0a3afSMarcel Holtmann 			goto unlock;
22339dc0a3afSMarcel Holtmann 
22349dc0a3afSMarcel Holtmann 		conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2235b6a0dc82SMarcel Holtmann 		if (!conn)
2236b6a0dc82SMarcel Holtmann 			goto unlock;
2237b6a0dc82SMarcel Holtmann 
22389dc0a3afSMarcel Holtmann 		conn->type = SCO_LINK;
22399dc0a3afSMarcel Holtmann 	}
22409dc0a3afSMarcel Holtmann 
2241732547f9SMarcel Holtmann 	switch (ev->status) {
2242732547f9SMarcel Holtmann 	case 0x00:
2243732547f9SMarcel Holtmann 		conn->handle = __le16_to_cpu(ev->handle);
2244732547f9SMarcel Holtmann 		conn->state  = BT_CONNECTED;
2245732547f9SMarcel Holtmann 
22469eba32b8SMarcel Holtmann 		hci_conn_hold_device(conn);
2247732547f9SMarcel Holtmann 		hci_conn_add_sysfs(conn);
2248732547f9SMarcel Holtmann 		break;
2249732547f9SMarcel Holtmann 
2250705e5711SStephen Coe 	case 0x11:	/* Unsupported Feature or Parameter Value */
2251732547f9SMarcel Holtmann 	case 0x1c:	/* SCO interval rejected */
22521038a00bSNick Pelly 	case 0x1a:	/* Unsupported Remote Feature */
2253732547f9SMarcel Holtmann 	case 0x1f:	/* Unspecified error */
2254732547f9SMarcel Holtmann 		if (conn->out && conn->attempt < 2) {
2255efc7688bSMarcel Holtmann 			conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2256efc7688bSMarcel Holtmann 					(hdev->esco_type & EDR_ESCO_MASK);
2257efc7688bSMarcel Holtmann 			hci_setup_sync(conn, conn->link->handle);
2258efc7688bSMarcel Holtmann 			goto unlock;
2259efc7688bSMarcel Holtmann 		}
2260732547f9SMarcel Holtmann 		/* fall through */
2261efc7688bSMarcel Holtmann 
2262732547f9SMarcel Holtmann 	default:
2263b6a0dc82SMarcel Holtmann 		conn->state = BT_CLOSED;
2264732547f9SMarcel Holtmann 		break;
2265732547f9SMarcel Holtmann 	}
2266b6a0dc82SMarcel Holtmann 
2267b6a0dc82SMarcel Holtmann 	hci_proto_connect_cfm(conn, ev->status);
2268b6a0dc82SMarcel Holtmann 	if (ev->status)
2269b6a0dc82SMarcel Holtmann 		hci_conn_del(conn);
2270b6a0dc82SMarcel Holtmann 
2271b6a0dc82SMarcel Holtmann unlock:
2272b6a0dc82SMarcel Holtmann 	hci_dev_unlock(hdev);
2273a9de9248SMarcel Holtmann }
2274a9de9248SMarcel Holtmann 
2275a9de9248SMarcel Holtmann static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2276a9de9248SMarcel Holtmann {
2277a9de9248SMarcel Holtmann 	BT_DBG("%s", hdev->name);
2278a9de9248SMarcel Holtmann }
2279a9de9248SMarcel Holtmann 
228004837f64SMarcel Holtmann static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
228104837f64SMarcel Holtmann {
2282a9de9248SMarcel Holtmann 	struct hci_ev_sniff_subrate *ev = (void *) skb->data;
228304837f64SMarcel Holtmann 
228404837f64SMarcel Holtmann 	BT_DBG("%s status %d", hdev->name, ev->status);
228504837f64SMarcel Holtmann }
228604837f64SMarcel Holtmann 
2287a9de9248SMarcel Holtmann static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2288a9de9248SMarcel Holtmann {
2289a9de9248SMarcel Holtmann 	struct inquiry_data data;
2290a9de9248SMarcel Holtmann 	struct extended_inquiry_info *info = (void *) (skb->data + 1);
2291a9de9248SMarcel Holtmann 	int num_rsp = *((__u8 *) skb->data);
2292a9de9248SMarcel Holtmann 
2293a9de9248SMarcel Holtmann 	BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2294a9de9248SMarcel Holtmann 
2295a9de9248SMarcel Holtmann 	if (!num_rsp)
2296a9de9248SMarcel Holtmann 		return;
2297a9de9248SMarcel Holtmann 
2298a9de9248SMarcel Holtmann 	hci_dev_lock(hdev);
2299a9de9248SMarcel Holtmann 
2300a9de9248SMarcel Holtmann 	for (; num_rsp; num_rsp--) {
2301a9de9248SMarcel Holtmann 		bacpy(&data.bdaddr, &info->bdaddr);
2302a9de9248SMarcel Holtmann 		data.pscan_rep_mode	= info->pscan_rep_mode;
2303a9de9248SMarcel Holtmann 		data.pscan_period_mode	= info->pscan_period_mode;
2304a9de9248SMarcel Holtmann 		data.pscan_mode		= 0x00;
2305a9de9248SMarcel Holtmann 		memcpy(data.dev_class, info->dev_class, 3);
2306a9de9248SMarcel Holtmann 		data.clock_offset	= info->clock_offset;
2307a9de9248SMarcel Holtmann 		data.rssi		= info->rssi;
230841a96212SMarcel Holtmann 		data.ssp_mode		= 0x01;
2309a9de9248SMarcel Holtmann 		info++;
2310a9de9248SMarcel Holtmann 		hci_inquiry_cache_update(hdev, &data);
2311a9de9248SMarcel Holtmann 	}
2312a9de9248SMarcel Holtmann 
2313a9de9248SMarcel Holtmann 	hci_dev_unlock(hdev);
2314a9de9248SMarcel Holtmann }
2315a9de9248SMarcel Holtmann 
231617fa4b9dSJohan Hedberg static inline u8 hci_get_auth_req(struct hci_conn *conn)
231717fa4b9dSJohan Hedberg {
231817fa4b9dSJohan Hedberg 	/* If remote requests dedicated bonding follow that lead */
231917fa4b9dSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
232017fa4b9dSJohan Hedberg 		/* If both remote and local IO capabilities allow MITM
232117fa4b9dSJohan Hedberg 		 * protection then require it, otherwise don't */
232217fa4b9dSJohan Hedberg 		if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
232317fa4b9dSJohan Hedberg 			return 0x02;
232417fa4b9dSJohan Hedberg 		else
232517fa4b9dSJohan Hedberg 			return 0x03;
232617fa4b9dSJohan Hedberg 	}
232717fa4b9dSJohan Hedberg 
232817fa4b9dSJohan Hedberg 	/* If remote requests no-bonding follow that lead */
232917fa4b9dSJohan Hedberg 	if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
233017fa4b9dSJohan Hedberg 		return 0x00;
233117fa4b9dSJohan Hedberg 
233217fa4b9dSJohan Hedberg 	return conn->auth_type;
233317fa4b9dSJohan Hedberg }
233417fa4b9dSJohan Hedberg 
23350493684eSMarcel Holtmann static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
23360493684eSMarcel Holtmann {
23370493684eSMarcel Holtmann 	struct hci_ev_io_capa_request *ev = (void *) skb->data;
23380493684eSMarcel Holtmann 	struct hci_conn *conn;
23390493684eSMarcel Holtmann 
23400493684eSMarcel Holtmann 	BT_DBG("%s", hdev->name);
23410493684eSMarcel Holtmann 
23420493684eSMarcel Holtmann 	hci_dev_lock(hdev);
23430493684eSMarcel Holtmann 
23440493684eSMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
234503b555e1SJohan Hedberg 	if (!conn)
234603b555e1SJohan Hedberg 		goto unlock;
234703b555e1SJohan Hedberg 
23480493684eSMarcel Holtmann 	hci_conn_hold(conn);
23490493684eSMarcel Holtmann 
235003b555e1SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->flags))
235103b555e1SJohan Hedberg 		goto unlock;
235203b555e1SJohan Hedberg 
235303b555e1SJohan Hedberg 	if (test_bit(HCI_PAIRABLE, &hdev->flags) ||
235403b555e1SJohan Hedberg 			(conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
235517fa4b9dSJohan Hedberg 		struct hci_cp_io_capability_reply cp;
235617fa4b9dSJohan Hedberg 
235717fa4b9dSJohan Hedberg 		bacpy(&cp.bdaddr, &ev->bdaddr);
235817fa4b9dSJohan Hedberg 		cp.capability = conn->io_capability;
235917fa4b9dSJohan Hedberg 		cp.oob_data = 0;
236017fa4b9dSJohan Hedberg 		cp.authentication = hci_get_auth_req(conn);
236117fa4b9dSJohan Hedberg 
236217fa4b9dSJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
236317fa4b9dSJohan Hedberg 							sizeof(cp), &cp);
236403b555e1SJohan Hedberg 	} else {
236503b555e1SJohan Hedberg 		struct hci_cp_io_capability_neg_reply cp;
236603b555e1SJohan Hedberg 
236703b555e1SJohan Hedberg 		bacpy(&cp.bdaddr, &ev->bdaddr);
236803b555e1SJohan Hedberg 		cp.reason = 0x16; /* Pairing not allowed */
236903b555e1SJohan Hedberg 
237003b555e1SJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
237103b555e1SJohan Hedberg 							sizeof(cp), &cp);
237203b555e1SJohan Hedberg 	}
237303b555e1SJohan Hedberg 
237403b555e1SJohan Hedberg unlock:
237503b555e1SJohan Hedberg 	hci_dev_unlock(hdev);
237603b555e1SJohan Hedberg }
237703b555e1SJohan Hedberg 
237803b555e1SJohan Hedberg static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
237903b555e1SJohan Hedberg {
238003b555e1SJohan Hedberg 	struct hci_ev_io_capa_reply *ev = (void *) skb->data;
238103b555e1SJohan Hedberg 	struct hci_conn *conn;
238203b555e1SJohan Hedberg 
238303b555e1SJohan Hedberg 	BT_DBG("%s", hdev->name);
238403b555e1SJohan Hedberg 
238503b555e1SJohan Hedberg 	hci_dev_lock(hdev);
238603b555e1SJohan Hedberg 
238703b555e1SJohan Hedberg 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
238803b555e1SJohan Hedberg 	if (!conn)
238903b555e1SJohan Hedberg 		goto unlock;
239003b555e1SJohan Hedberg 
239103b555e1SJohan Hedberg 	hci_conn_hold(conn);
239203b555e1SJohan Hedberg 
239303b555e1SJohan Hedberg 	conn->remote_cap = ev->capability;
239403b555e1SJohan Hedberg 	conn->remote_oob = ev->oob_data;
239503b555e1SJohan Hedberg 	conn->remote_auth = ev->authentication;
239603b555e1SJohan Hedberg 
239703b555e1SJohan Hedberg unlock:
23980493684eSMarcel Holtmann 	hci_dev_unlock(hdev);
23990493684eSMarcel Holtmann }
24000493684eSMarcel Holtmann 
2401a5c29683SJohan Hedberg static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
2402a5c29683SJohan Hedberg 							struct sk_buff *skb)
2403a5c29683SJohan Hedberg {
2404a5c29683SJohan Hedberg 	struct hci_ev_user_confirm_req *ev = (void *) skb->data;
2405a5c29683SJohan Hedberg 
2406a5c29683SJohan Hedberg 	BT_DBG("%s", hdev->name);
2407a5c29683SJohan Hedberg 
2408a5c29683SJohan Hedberg 	hci_dev_lock(hdev);
2409a5c29683SJohan Hedberg 
2410a5c29683SJohan Hedberg 	if (test_bit(HCI_MGMT, &hdev->flags))
2411a5c29683SJohan Hedberg 		mgmt_user_confirm_request(hdev->id, &ev->bdaddr, ev->passkey);
2412a5c29683SJohan Hedberg 
2413a5c29683SJohan Hedberg 	hci_dev_unlock(hdev);
2414a5c29683SJohan Hedberg }
2415a5c29683SJohan Hedberg 
24160493684eSMarcel Holtmann static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
24170493684eSMarcel Holtmann {
24180493684eSMarcel Holtmann 	struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
24190493684eSMarcel Holtmann 	struct hci_conn *conn;
24200493684eSMarcel Holtmann 
24210493684eSMarcel Holtmann 	BT_DBG("%s", hdev->name);
24220493684eSMarcel Holtmann 
24230493684eSMarcel Holtmann 	hci_dev_lock(hdev);
24240493684eSMarcel Holtmann 
24250493684eSMarcel Holtmann 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
24262a611692SJohan Hedberg 	if (!conn)
24272a611692SJohan Hedberg 		goto unlock;
24282a611692SJohan Hedberg 
24292a611692SJohan Hedberg 	/* To avoid duplicate auth_failed events to user space we check
24302a611692SJohan Hedberg 	 * the HCI_CONN_AUTH_PEND flag which will be set if we
24312a611692SJohan Hedberg 	 * initiated the authentication. A traditional auth_complete
24322a611692SJohan Hedberg 	 * event gets always produced as initiator and is also mapped to
24332a611692SJohan Hedberg 	 * the mgmt_auth_failed event */
24342a611692SJohan Hedberg 	if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend) && ev->status != 0)
24352a611692SJohan Hedberg 		mgmt_auth_failed(hdev->id, &conn->dst, ev->status);
24362a611692SJohan Hedberg 
24370493684eSMarcel Holtmann 	hci_conn_put(conn);
24380493684eSMarcel Holtmann 
24392a611692SJohan Hedberg unlock:
24400493684eSMarcel Holtmann 	hci_dev_unlock(hdev);
24410493684eSMarcel Holtmann }
24420493684eSMarcel Holtmann 
244341a96212SMarcel Holtmann static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
244441a96212SMarcel Holtmann {
244541a96212SMarcel Holtmann 	struct hci_ev_remote_host_features *ev = (void *) skb->data;
244641a96212SMarcel Holtmann 	struct inquiry_entry *ie;
244741a96212SMarcel Holtmann 
244841a96212SMarcel Holtmann 	BT_DBG("%s", hdev->name);
244941a96212SMarcel Holtmann 
245041a96212SMarcel Holtmann 	hci_dev_lock(hdev);
245141a96212SMarcel Holtmann 
2452cc11b9c1SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2453cc11b9c1SAndrei Emeltchenko 	if (ie)
245441a96212SMarcel Holtmann 		ie->data.ssp_mode = (ev->features[0] & 0x01);
245541a96212SMarcel Holtmann 
245641a96212SMarcel Holtmann 	hci_dev_unlock(hdev);
245741a96212SMarcel Holtmann }
245841a96212SMarcel Holtmann 
2459fcd89c09SVille Tervo static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2460fcd89c09SVille Tervo {
2461fcd89c09SVille Tervo 	struct hci_ev_le_conn_complete *ev = (void *) skb->data;
2462fcd89c09SVille Tervo 	struct hci_conn *conn;
2463fcd89c09SVille Tervo 
2464fcd89c09SVille Tervo 	BT_DBG("%s status %d", hdev->name, ev->status);
2465fcd89c09SVille Tervo 
2466fcd89c09SVille Tervo 	hci_dev_lock(hdev);
2467fcd89c09SVille Tervo 
2468fcd89c09SVille Tervo 	conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
2469b62f328bSVille Tervo 	if (!conn) {
2470b62f328bSVille Tervo 		conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
2471b62f328bSVille Tervo 		if (!conn) {
2472b62f328bSVille Tervo 			BT_ERR("No memory for new connection");
2473b62f328bSVille Tervo 			hci_dev_unlock(hdev);
2474b62f328bSVille Tervo 			return;
2475b62f328bSVille Tervo 		}
2476b62f328bSVille Tervo 	}
2477fcd89c09SVille Tervo 
2478fcd89c09SVille Tervo 	if (ev->status) {
2479fcd89c09SVille Tervo 		hci_proto_connect_cfm(conn, ev->status);
2480fcd89c09SVille Tervo 		conn->state = BT_CLOSED;
2481fcd89c09SVille Tervo 		hci_conn_del(conn);
2482fcd89c09SVille Tervo 		goto unlock;
2483fcd89c09SVille Tervo 	}
2484fcd89c09SVille Tervo 
2485fcd89c09SVille Tervo 	conn->handle = __le16_to_cpu(ev->handle);
2486fcd89c09SVille Tervo 	conn->state = BT_CONNECTED;
2487fcd89c09SVille Tervo 
2488fcd89c09SVille Tervo 	hci_conn_hold_device(conn);
2489fcd89c09SVille Tervo 	hci_conn_add_sysfs(conn);
2490fcd89c09SVille Tervo 
2491fcd89c09SVille Tervo 	hci_proto_connect_cfm(conn, ev->status);
2492fcd89c09SVille Tervo 
2493fcd89c09SVille Tervo unlock:
2494fcd89c09SVille Tervo 	hci_dev_unlock(hdev);
2495fcd89c09SVille Tervo }
2496fcd89c09SVille Tervo 
2497fcd89c09SVille Tervo static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
2498fcd89c09SVille Tervo {
2499fcd89c09SVille Tervo 	struct hci_ev_le_meta *le_ev = (void *) skb->data;
2500fcd89c09SVille Tervo 
2501fcd89c09SVille Tervo 	skb_pull(skb, sizeof(*le_ev));
2502fcd89c09SVille Tervo 
2503fcd89c09SVille Tervo 	switch (le_ev->subevent) {
2504fcd89c09SVille Tervo 	case HCI_EV_LE_CONN_COMPLETE:
2505fcd89c09SVille Tervo 		hci_le_conn_complete_evt(hdev, skb);
2506fcd89c09SVille Tervo 		break;
2507fcd89c09SVille Tervo 
2508fcd89c09SVille Tervo 	default:
2509fcd89c09SVille Tervo 		break;
2510fcd89c09SVille Tervo 	}
2511fcd89c09SVille Tervo }
2512fcd89c09SVille Tervo 
25131da177e4SLinus Torvalds void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
25141da177e4SLinus Torvalds {
2515a9de9248SMarcel Holtmann 	struct hci_event_hdr *hdr = (void *) skb->data;
2516a9de9248SMarcel Holtmann 	__u8 event = hdr->evt;
25171da177e4SLinus Torvalds 
25181da177e4SLinus Torvalds 	skb_pull(skb, HCI_EVENT_HDR_SIZE);
25191da177e4SLinus Torvalds 
2520a9de9248SMarcel Holtmann 	switch (event) {
25211da177e4SLinus Torvalds 	case HCI_EV_INQUIRY_COMPLETE:
25221da177e4SLinus Torvalds 		hci_inquiry_complete_evt(hdev, skb);
25231da177e4SLinus Torvalds 		break;
25241da177e4SLinus Torvalds 
25251da177e4SLinus Torvalds 	case HCI_EV_INQUIRY_RESULT:
25261da177e4SLinus Torvalds 		hci_inquiry_result_evt(hdev, skb);
25271da177e4SLinus Torvalds 		break;
25281da177e4SLinus Torvalds 
2529a9de9248SMarcel Holtmann 	case HCI_EV_CONN_COMPLETE:
2530a9de9248SMarcel Holtmann 		hci_conn_complete_evt(hdev, skb);
253121d9e30eSMarcel Holtmann 		break;
253221d9e30eSMarcel Holtmann 
25331da177e4SLinus Torvalds 	case HCI_EV_CONN_REQUEST:
25341da177e4SLinus Torvalds 		hci_conn_request_evt(hdev, skb);
25351da177e4SLinus Torvalds 		break;
25361da177e4SLinus Torvalds 
25371da177e4SLinus Torvalds 	case HCI_EV_DISCONN_COMPLETE:
25381da177e4SLinus Torvalds 		hci_disconn_complete_evt(hdev, skb);
25391da177e4SLinus Torvalds 		break;
25401da177e4SLinus Torvalds 
25411da177e4SLinus Torvalds 	case HCI_EV_AUTH_COMPLETE:
25421da177e4SLinus Torvalds 		hci_auth_complete_evt(hdev, skb);
25431da177e4SLinus Torvalds 		break;
25441da177e4SLinus Torvalds 
2545a9de9248SMarcel Holtmann 	case HCI_EV_REMOTE_NAME:
2546a9de9248SMarcel Holtmann 		hci_remote_name_evt(hdev, skb);
2547a9de9248SMarcel Holtmann 		break;
2548a9de9248SMarcel Holtmann 
25491da177e4SLinus Torvalds 	case HCI_EV_ENCRYPT_CHANGE:
25501da177e4SLinus Torvalds 		hci_encrypt_change_evt(hdev, skb);
25511da177e4SLinus Torvalds 		break;
25521da177e4SLinus Torvalds 
2553a9de9248SMarcel Holtmann 	case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
2554a9de9248SMarcel Holtmann 		hci_change_link_key_complete_evt(hdev, skb);
2555a9de9248SMarcel Holtmann 		break;
2556a9de9248SMarcel Holtmann 
2557a9de9248SMarcel Holtmann 	case HCI_EV_REMOTE_FEATURES:
2558a9de9248SMarcel Holtmann 		hci_remote_features_evt(hdev, skb);
2559a9de9248SMarcel Holtmann 		break;
2560a9de9248SMarcel Holtmann 
2561a9de9248SMarcel Holtmann 	case HCI_EV_REMOTE_VERSION:
2562a9de9248SMarcel Holtmann 		hci_remote_version_evt(hdev, skb);
2563a9de9248SMarcel Holtmann 		break;
2564a9de9248SMarcel Holtmann 
2565a9de9248SMarcel Holtmann 	case HCI_EV_QOS_SETUP_COMPLETE:
2566a9de9248SMarcel Holtmann 		hci_qos_setup_complete_evt(hdev, skb);
2567a9de9248SMarcel Holtmann 		break;
2568a9de9248SMarcel Holtmann 
2569a9de9248SMarcel Holtmann 	case HCI_EV_CMD_COMPLETE:
2570a9de9248SMarcel Holtmann 		hci_cmd_complete_evt(hdev, skb);
2571a9de9248SMarcel Holtmann 		break;
2572a9de9248SMarcel Holtmann 
2573a9de9248SMarcel Holtmann 	case HCI_EV_CMD_STATUS:
2574a9de9248SMarcel Holtmann 		hci_cmd_status_evt(hdev, skb);
2575a9de9248SMarcel Holtmann 		break;
2576a9de9248SMarcel Holtmann 
2577a9de9248SMarcel Holtmann 	case HCI_EV_ROLE_CHANGE:
2578a9de9248SMarcel Holtmann 		hci_role_change_evt(hdev, skb);
2579a9de9248SMarcel Holtmann 		break;
2580a9de9248SMarcel Holtmann 
2581a9de9248SMarcel Holtmann 	case HCI_EV_NUM_COMP_PKTS:
2582a9de9248SMarcel Holtmann 		hci_num_comp_pkts_evt(hdev, skb);
2583a9de9248SMarcel Holtmann 		break;
2584a9de9248SMarcel Holtmann 
2585a9de9248SMarcel Holtmann 	case HCI_EV_MODE_CHANGE:
2586a9de9248SMarcel Holtmann 		hci_mode_change_evt(hdev, skb);
25871da177e4SLinus Torvalds 		break;
25881da177e4SLinus Torvalds 
25891da177e4SLinus Torvalds 	case HCI_EV_PIN_CODE_REQ:
25901da177e4SLinus Torvalds 		hci_pin_code_request_evt(hdev, skb);
25911da177e4SLinus Torvalds 		break;
25921da177e4SLinus Torvalds 
25931da177e4SLinus Torvalds 	case HCI_EV_LINK_KEY_REQ:
25941da177e4SLinus Torvalds 		hci_link_key_request_evt(hdev, skb);
25951da177e4SLinus Torvalds 		break;
25961da177e4SLinus Torvalds 
25971da177e4SLinus Torvalds 	case HCI_EV_LINK_KEY_NOTIFY:
25981da177e4SLinus Torvalds 		hci_link_key_notify_evt(hdev, skb);
25991da177e4SLinus Torvalds 		break;
26001da177e4SLinus Torvalds 
26011da177e4SLinus Torvalds 	case HCI_EV_CLOCK_OFFSET:
26021da177e4SLinus Torvalds 		hci_clock_offset_evt(hdev, skb);
26031da177e4SLinus Torvalds 		break;
26041da177e4SLinus Torvalds 
2605a8746417SMarcel Holtmann 	case HCI_EV_PKT_TYPE_CHANGE:
2606a8746417SMarcel Holtmann 		hci_pkt_type_change_evt(hdev, skb);
2607a8746417SMarcel Holtmann 		break;
2608a8746417SMarcel Holtmann 
260985a1e930SMarcel Holtmann 	case HCI_EV_PSCAN_REP_MODE:
261085a1e930SMarcel Holtmann 		hci_pscan_rep_mode_evt(hdev, skb);
261185a1e930SMarcel Holtmann 		break;
261285a1e930SMarcel Holtmann 
2613a9de9248SMarcel Holtmann 	case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
2614a9de9248SMarcel Holtmann 		hci_inquiry_result_with_rssi_evt(hdev, skb);
2615a9de9248SMarcel Holtmann 		break;
2616a9de9248SMarcel Holtmann 
2617a9de9248SMarcel Holtmann 	case HCI_EV_REMOTE_EXT_FEATURES:
2618a9de9248SMarcel Holtmann 		hci_remote_ext_features_evt(hdev, skb);
2619a9de9248SMarcel Holtmann 		break;
2620a9de9248SMarcel Holtmann 
2621a9de9248SMarcel Holtmann 	case HCI_EV_SYNC_CONN_COMPLETE:
2622a9de9248SMarcel Holtmann 		hci_sync_conn_complete_evt(hdev, skb);
2623a9de9248SMarcel Holtmann 		break;
2624a9de9248SMarcel Holtmann 
2625a9de9248SMarcel Holtmann 	case HCI_EV_SYNC_CONN_CHANGED:
2626a9de9248SMarcel Holtmann 		hci_sync_conn_changed_evt(hdev, skb);
2627a9de9248SMarcel Holtmann 		break;
2628a9de9248SMarcel Holtmann 
262904837f64SMarcel Holtmann 	case HCI_EV_SNIFF_SUBRATE:
263004837f64SMarcel Holtmann 		hci_sniff_subrate_evt(hdev, skb);
263104837f64SMarcel Holtmann 		break;
263204837f64SMarcel Holtmann 
2633a9de9248SMarcel Holtmann 	case HCI_EV_EXTENDED_INQUIRY_RESULT:
2634a9de9248SMarcel Holtmann 		hci_extended_inquiry_result_evt(hdev, skb);
26351da177e4SLinus Torvalds 		break;
26361da177e4SLinus Torvalds 
26370493684eSMarcel Holtmann 	case HCI_EV_IO_CAPA_REQUEST:
26380493684eSMarcel Holtmann 		hci_io_capa_request_evt(hdev, skb);
26390493684eSMarcel Holtmann 		break;
26400493684eSMarcel Holtmann 
264103b555e1SJohan Hedberg 	case HCI_EV_IO_CAPA_REPLY:
264203b555e1SJohan Hedberg 		hci_io_capa_reply_evt(hdev, skb);
264303b555e1SJohan Hedberg 		break;
264403b555e1SJohan Hedberg 
2645a5c29683SJohan Hedberg 	case HCI_EV_USER_CONFIRM_REQUEST:
2646a5c29683SJohan Hedberg 		hci_user_confirm_request_evt(hdev, skb);
2647a5c29683SJohan Hedberg 		break;
2648a5c29683SJohan Hedberg 
26490493684eSMarcel Holtmann 	case HCI_EV_SIMPLE_PAIR_COMPLETE:
26500493684eSMarcel Holtmann 		hci_simple_pair_complete_evt(hdev, skb);
26510493684eSMarcel Holtmann 		break;
26520493684eSMarcel Holtmann 
265341a96212SMarcel Holtmann 	case HCI_EV_REMOTE_HOST_FEATURES:
265441a96212SMarcel Holtmann 		hci_remote_host_features_evt(hdev, skb);
265541a96212SMarcel Holtmann 		break;
265641a96212SMarcel Holtmann 
2657fcd89c09SVille Tervo 	case HCI_EV_LE_META:
2658fcd89c09SVille Tervo 		hci_le_meta_evt(hdev, skb);
2659fcd89c09SVille Tervo 		break;
2660fcd89c09SVille Tervo 
26611da177e4SLinus Torvalds 	default:
2662a9de9248SMarcel Holtmann 		BT_DBG("%s event 0x%x", hdev->name, event);
26631da177e4SLinus Torvalds 		break;
26641da177e4SLinus Torvalds 	}
26651da177e4SLinus Torvalds 
26661da177e4SLinus Torvalds 	kfree_skb(skb);
26671da177e4SLinus Torvalds 	hdev->stat.evt_rx++;
26681da177e4SLinus Torvalds }
26691da177e4SLinus Torvalds 
26701da177e4SLinus Torvalds /* Generate internal stack event */
26711da177e4SLinus Torvalds void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
26721da177e4SLinus Torvalds {
26731da177e4SLinus Torvalds 	struct hci_event_hdr *hdr;
26741da177e4SLinus Torvalds 	struct hci_ev_stack_internal *ev;
26751da177e4SLinus Torvalds 	struct sk_buff *skb;
26761da177e4SLinus Torvalds 
26771da177e4SLinus Torvalds 	skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
26781da177e4SLinus Torvalds 	if (!skb)
26791da177e4SLinus Torvalds 		return;
26801da177e4SLinus Torvalds 
26811da177e4SLinus Torvalds 	hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
26821da177e4SLinus Torvalds 	hdr->evt  = HCI_EV_STACK_INTERNAL;
26831da177e4SLinus Torvalds 	hdr->plen = sizeof(*ev) + dlen;
26841da177e4SLinus Torvalds 
26851da177e4SLinus Torvalds 	ev  = (void *) skb_put(skb, sizeof(*ev) + dlen);
26861da177e4SLinus Torvalds 	ev->type = type;
26871da177e4SLinus Torvalds 	memcpy(ev->data, data, dlen);
26881da177e4SLinus Torvalds 
2689576c7d85SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
2690a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
2691576c7d85SMarcel Holtmann 
26920d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
26931da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
2694eec8d2bcSJohan Hedberg 	hci_send_to_sock(hdev, skb, NULL);
26951da177e4SLinus Torvalds 	kfree_skb(skb);
26961da177e4SLinus Torvalds }
2697