xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 6bcbc489)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds    BlueZ - Bluetooth protocol stack for Linux
31da177e4SLinus Torvalds    Copyright (C) 2000-2001 Qualcomm Incorporated
4590051deSGustavo F. Padovan    Copyright (C) 2011 ProFUSION Embedded Systems
51da177e4SLinus Torvalds 
61da177e4SLinus Torvalds    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
71da177e4SLinus Torvalds 
81da177e4SLinus Torvalds    This program is free software; you can redistribute it and/or modify
91da177e4SLinus Torvalds    it under the terms of the GNU General Public License version 2 as
101da177e4SLinus Torvalds    published by the Free Software Foundation;
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
131da177e4SLinus Torvalds    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
141da177e4SLinus Torvalds    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
151da177e4SLinus Torvalds    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
161da177e4SLinus Torvalds    CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
171da177e4SLinus Torvalds    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
181da177e4SLinus Torvalds    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
191da177e4SLinus Torvalds    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
201da177e4SLinus Torvalds 
211da177e4SLinus Torvalds    ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
221da177e4SLinus Torvalds    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
231da177e4SLinus Torvalds    SOFTWARE IS DISCLAIMED.
241da177e4SLinus Torvalds */
251da177e4SLinus Torvalds 
261da177e4SLinus Torvalds /* Bluetooth HCI core. */
271da177e4SLinus Torvalds 
2882453021SS.Çağlar Onur #include <linux/jiffies.h>
291da177e4SLinus Torvalds #include <linux/module.h>
301da177e4SLinus Torvalds #include <linux/kmod.h>
311da177e4SLinus Torvalds 
321da177e4SLinus Torvalds #include <linux/types.h>
331da177e4SLinus Torvalds #include <linux/errno.h>
341da177e4SLinus Torvalds #include <linux/kernel.h>
351da177e4SLinus Torvalds #include <linux/sched.h>
361da177e4SLinus Torvalds #include <linux/slab.h>
371da177e4SLinus Torvalds #include <linux/poll.h>
381da177e4SLinus Torvalds #include <linux/fcntl.h>
391da177e4SLinus Torvalds #include <linux/init.h>
401da177e4SLinus Torvalds #include <linux/skbuff.h>
41f48fd9c8SMarcel Holtmann #include <linux/workqueue.h>
421da177e4SLinus Torvalds #include <linux/interrupt.h>
43611b30f7SMarcel Holtmann #include <linux/rfkill.h>
446bd32326SVille Tervo #include <linux/timer.h>
453a0259bbSVinicius Costa Gomes #include <linux/crypto.h>
461da177e4SLinus Torvalds #include <net/sock.h>
471da177e4SLinus Torvalds 
4870f23020SAndrei Emeltchenko #include <linux/uaccess.h>
491da177e4SLinus Torvalds #include <asm/unaligned.h>
501da177e4SLinus Torvalds 
511da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
521da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
531da177e4SLinus Torvalds 
54ab81cbf9SJohan Hedberg #define AUTO_OFF_TIMEOUT 2000
55ab81cbf9SJohan Hedberg 
56b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work);
57c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work);
583eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work);
591da177e4SLinus Torvalds 
601da177e4SLinus Torvalds /* HCI device list */
611da177e4SLinus Torvalds LIST_HEAD(hci_dev_list);
621da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock);
631da177e4SLinus Torvalds 
641da177e4SLinus Torvalds /* HCI callback list */
651da177e4SLinus Torvalds LIST_HEAD(hci_cb_list);
661da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock);
671da177e4SLinus Torvalds 
681da177e4SLinus Torvalds /* ---- HCI notifications ---- */
691da177e4SLinus Torvalds 
706516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event)
711da177e4SLinus Torvalds {
72040030efSMarcel Holtmann 	hci_sock_dev_event(hdev, event);
731da177e4SLinus Torvalds }
741da177e4SLinus Torvalds 
751da177e4SLinus Torvalds /* ---- HCI requests ---- */
761da177e4SLinus Torvalds 
7723bb5763SJohan Hedberg void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result)
781da177e4SLinus Torvalds {
7923bb5763SJohan Hedberg 	BT_DBG("%s command 0x%04x result 0x%2.2x", hdev->name, cmd, result);
8023bb5763SJohan Hedberg 
81a5040efaSJohan Hedberg 	/* If this is the init phase check if the completed command matches
82a5040efaSJohan Hedberg 	 * the last init command, and if not just return.
83a5040efaSJohan Hedberg 	 */
8475fb0e32SJohan Hedberg 	if (test_bit(HCI_INIT, &hdev->flags) && hdev->init_last_cmd != cmd) {
8575fb0e32SJohan Hedberg 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
861036b890SAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
8775fb0e32SJohan Hedberg 		struct sk_buff *skb;
8875fb0e32SJohan Hedberg 
8975fb0e32SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
9075fb0e32SJohan Hedberg 		 * reset complete event during init and any pending
9175fb0e32SJohan Hedberg 		 * command will never be completed. In such a case we
9275fb0e32SJohan Hedberg 		 * need to resend whatever was the last sent
9375fb0e32SJohan Hedberg 		 * command.
9475fb0e32SJohan Hedberg 		 */
9575fb0e32SJohan Hedberg 
961036b890SAndrei Emeltchenko 		if (cmd != HCI_OP_RESET || opcode == HCI_OP_RESET)
9723bb5763SJohan Hedberg 			return;
981da177e4SLinus Torvalds 
9975fb0e32SJohan Hedberg 		skb = skb_clone(hdev->sent_cmd, GFP_ATOMIC);
10075fb0e32SJohan Hedberg 		if (skb) {
10175fb0e32SJohan Hedberg 			skb_queue_head(&hdev->cmd_q, skb);
10275fb0e32SJohan Hedberg 			queue_work(hdev->workqueue, &hdev->cmd_work);
10375fb0e32SJohan Hedberg 		}
10475fb0e32SJohan Hedberg 
10575fb0e32SJohan Hedberg 		return;
10675fb0e32SJohan Hedberg 	}
10775fb0e32SJohan Hedberg 
1081da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
1091da177e4SLinus Torvalds 		hdev->req_result = result;
1101da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_DONE;
1111da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
1121da177e4SLinus Torvalds 	}
1131da177e4SLinus Torvalds }
1141da177e4SLinus Torvalds 
1151da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err)
1161da177e4SLinus Torvalds {
1171da177e4SLinus Torvalds 	BT_DBG("%s err 0x%2.2x", hdev->name, err);
1181da177e4SLinus Torvalds 
1191da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
1201da177e4SLinus Torvalds 		hdev->req_result = err;
1211da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_CANCELED;
1221da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
1231da177e4SLinus Torvalds 	}
1241da177e4SLinus Torvalds }
1251da177e4SLinus Torvalds 
1261da177e4SLinus Torvalds /* Execute request and wait for completion. */
1271da177e4SLinus Torvalds static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt),
1281da177e4SLinus Torvalds 					unsigned long opt, __u32 timeout)
1291da177e4SLinus Torvalds {
1301da177e4SLinus Torvalds 	DECLARE_WAITQUEUE(wait, current);
1311da177e4SLinus Torvalds 	int err = 0;
1321da177e4SLinus Torvalds 
1331da177e4SLinus Torvalds 	BT_DBG("%s start", hdev->name);
1341da177e4SLinus Torvalds 
1351da177e4SLinus Torvalds 	hdev->req_status = HCI_REQ_PEND;
1361da177e4SLinus Torvalds 
1371da177e4SLinus Torvalds 	add_wait_queue(&hdev->req_wait_q, &wait);
1381da177e4SLinus Torvalds 	set_current_state(TASK_INTERRUPTIBLE);
1391da177e4SLinus Torvalds 
1401da177e4SLinus Torvalds 	req(hdev, opt);
1411da177e4SLinus Torvalds 	schedule_timeout(timeout);
1421da177e4SLinus Torvalds 
1431da177e4SLinus Torvalds 	remove_wait_queue(&hdev->req_wait_q, &wait);
1441da177e4SLinus Torvalds 
1451da177e4SLinus Torvalds 	if (signal_pending(current))
1461da177e4SLinus Torvalds 		return -EINTR;
1471da177e4SLinus Torvalds 
1481da177e4SLinus Torvalds 	switch (hdev->req_status) {
1491da177e4SLinus Torvalds 	case HCI_REQ_DONE:
150e175072fSJoe Perches 		err = -bt_to_errno(hdev->req_result);
1511da177e4SLinus Torvalds 		break;
1521da177e4SLinus Torvalds 
1531da177e4SLinus Torvalds 	case HCI_REQ_CANCELED:
1541da177e4SLinus Torvalds 		err = -hdev->req_result;
1551da177e4SLinus Torvalds 		break;
1561da177e4SLinus Torvalds 
1571da177e4SLinus Torvalds 	default:
1581da177e4SLinus Torvalds 		err = -ETIMEDOUT;
1591da177e4SLinus Torvalds 		break;
1603ff50b79SStephen Hemminger 	}
1611da177e4SLinus Torvalds 
162a5040efaSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
1631da177e4SLinus Torvalds 
1641da177e4SLinus Torvalds 	BT_DBG("%s end: err %d", hdev->name, err);
1651da177e4SLinus Torvalds 
1661da177e4SLinus Torvalds 	return err;
1671da177e4SLinus Torvalds }
1681da177e4SLinus Torvalds 
1691da177e4SLinus Torvalds static inline int hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt),
1701da177e4SLinus Torvalds 					unsigned long opt, __u32 timeout)
1711da177e4SLinus Torvalds {
1721da177e4SLinus Torvalds 	int ret;
1731da177e4SLinus Torvalds 
1747c6a329eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
1757c6a329eSMarcel Holtmann 		return -ENETDOWN;
1767c6a329eSMarcel Holtmann 
1771da177e4SLinus Torvalds 	/* Serialize all requests */
1781da177e4SLinus Torvalds 	hci_req_lock(hdev);
1791da177e4SLinus Torvalds 	ret = __hci_request(hdev, req, opt, timeout);
1801da177e4SLinus Torvalds 	hci_req_unlock(hdev);
1811da177e4SLinus Torvalds 
1821da177e4SLinus Torvalds 	return ret;
1831da177e4SLinus Torvalds }
1841da177e4SLinus Torvalds 
1851da177e4SLinus Torvalds static void hci_reset_req(struct hci_dev *hdev, unsigned long opt)
1861da177e4SLinus Torvalds {
1871da177e4SLinus Torvalds 	BT_DBG("%s %ld", hdev->name, opt);
1881da177e4SLinus Torvalds 
1891da177e4SLinus Torvalds 	/* Reset device */
190f630cf0dSGustavo F. Padovan 	set_bit(HCI_RESET, &hdev->flags);
191a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
1921da177e4SLinus Torvalds }
1931da177e4SLinus Torvalds 
194e61ef499SAndrei Emeltchenko static void bredr_init(struct hci_dev *hdev)
1951da177e4SLinus Torvalds {
196b0916ea0SJohan Hedberg 	struct hci_cp_delete_stored_link_key cp;
1971ebb9252SMarcel Holtmann 	__le16 param;
19889f2783dSMarcel Holtmann 	__u8 flt_type;
1991da177e4SLinus Torvalds 
2002455a3eaSAndrei Emeltchenko 	hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
2012455a3eaSAndrei Emeltchenko 
2021da177e4SLinus Torvalds 	/* Mandatory initialization */
2031da177e4SLinus Torvalds 
2041da177e4SLinus Torvalds 	/* Reset */
205f630cf0dSGustavo F. Padovan 	if (!test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) {
206f630cf0dSGustavo F. Padovan 		set_bit(HCI_RESET, &hdev->flags);
207a9de9248SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
208f630cf0dSGustavo F. Padovan 	}
2091da177e4SLinus Torvalds 
2101da177e4SLinus Torvalds 	/* Read Local Supported Features */
211a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
2121da177e4SLinus Torvalds 
2131143e5a6SMarcel Holtmann 	/* Read Local Version */
214a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
2151143e5a6SMarcel Holtmann 
2161da177e4SLinus Torvalds 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
217a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
2181da177e4SLinus Torvalds 
2191da177e4SLinus Torvalds 	/* Read BD Address */
220a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL);
221a9de9248SMarcel Holtmann 
222a9de9248SMarcel Holtmann 	/* Read Class of Device */
223a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
224a9de9248SMarcel Holtmann 
225a9de9248SMarcel Holtmann 	/* Read Local Name */
226a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL);
2271da177e4SLinus Torvalds 
2281da177e4SLinus Torvalds 	/* Read Voice Setting */
229a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL);
2301da177e4SLinus Torvalds 
2311da177e4SLinus Torvalds 	/* Optional initialization */
2321da177e4SLinus Torvalds 
2331da177e4SLinus Torvalds 	/* Clear Event Filters */
23489f2783dSMarcel Holtmann 	flt_type = HCI_FLT_CLEAR_ALL;
235a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
2361da177e4SLinus Torvalds 
2371da177e4SLinus Torvalds 	/* Connection accept timeout ~20 secs */
238aca3192cSYOSHIFUJI Hideaki 	param = cpu_to_le16(0x7d00);
239a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
240b0916ea0SJohan Hedberg 
241b0916ea0SJohan Hedberg 	bacpy(&cp.bdaddr, BDADDR_ANY);
242b0916ea0SJohan Hedberg 	cp.delete_all = 1;
243b0916ea0SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp);
2441da177e4SLinus Torvalds }
2451da177e4SLinus Torvalds 
246e61ef499SAndrei Emeltchenko static void amp_init(struct hci_dev *hdev)
247e61ef499SAndrei Emeltchenko {
2482455a3eaSAndrei Emeltchenko 	hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
2492455a3eaSAndrei Emeltchenko 
250e61ef499SAndrei Emeltchenko 	/* Reset */
251e61ef499SAndrei Emeltchenko 	hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
252e61ef499SAndrei Emeltchenko 
253e61ef499SAndrei Emeltchenko 	/* Read Local Version */
254e61ef499SAndrei Emeltchenko 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
2556bcbc489SAndrei Emeltchenko 
2566bcbc489SAndrei Emeltchenko 	/* Read Local AMP Info */
2576bcbc489SAndrei Emeltchenko 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
258e61ef499SAndrei Emeltchenko }
259e61ef499SAndrei Emeltchenko 
260e61ef499SAndrei Emeltchenko static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
261e61ef499SAndrei Emeltchenko {
262e61ef499SAndrei Emeltchenko 	struct sk_buff *skb;
263e61ef499SAndrei Emeltchenko 
264e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
265e61ef499SAndrei Emeltchenko 
266e61ef499SAndrei Emeltchenko 	/* Driver initialization */
267e61ef499SAndrei Emeltchenko 
268e61ef499SAndrei Emeltchenko 	/* Special commands */
269e61ef499SAndrei Emeltchenko 	while ((skb = skb_dequeue(&hdev->driver_init))) {
270e61ef499SAndrei Emeltchenko 		bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
271e61ef499SAndrei Emeltchenko 		skb->dev = (void *) hdev;
272e61ef499SAndrei Emeltchenko 
273e61ef499SAndrei Emeltchenko 		skb_queue_tail(&hdev->cmd_q, skb);
274e61ef499SAndrei Emeltchenko 		queue_work(hdev->workqueue, &hdev->cmd_work);
275e61ef499SAndrei Emeltchenko 	}
276e61ef499SAndrei Emeltchenko 	skb_queue_purge(&hdev->driver_init);
277e61ef499SAndrei Emeltchenko 
278e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
279e61ef499SAndrei Emeltchenko 	case HCI_BREDR:
280e61ef499SAndrei Emeltchenko 		bredr_init(hdev);
281e61ef499SAndrei Emeltchenko 		break;
282e61ef499SAndrei Emeltchenko 
283e61ef499SAndrei Emeltchenko 	case HCI_AMP:
284e61ef499SAndrei Emeltchenko 		amp_init(hdev);
285e61ef499SAndrei Emeltchenko 		break;
286e61ef499SAndrei Emeltchenko 
287e61ef499SAndrei Emeltchenko 	default:
288e61ef499SAndrei Emeltchenko 		BT_ERR("Unknown device type %d", hdev->dev_type);
289e61ef499SAndrei Emeltchenko 		break;
290e61ef499SAndrei Emeltchenko 	}
291e61ef499SAndrei Emeltchenko 
292e61ef499SAndrei Emeltchenko }
293e61ef499SAndrei Emeltchenko 
2946ed58ec5SVille Tervo static void hci_le_init_req(struct hci_dev *hdev, unsigned long opt)
2956ed58ec5SVille Tervo {
2966ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
2976ed58ec5SVille Tervo 
2986ed58ec5SVille Tervo 	/* Read LE buffer size */
2996ed58ec5SVille Tervo 	hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
3006ed58ec5SVille Tervo }
3016ed58ec5SVille Tervo 
3021da177e4SLinus Torvalds static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
3031da177e4SLinus Torvalds {
3041da177e4SLinus Torvalds 	__u8 scan = opt;
3051da177e4SLinus Torvalds 
3061da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, scan);
3071da177e4SLinus Torvalds 
3081da177e4SLinus Torvalds 	/* Inquiry and Page scans */
309a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
3101da177e4SLinus Torvalds }
3111da177e4SLinus Torvalds 
3121da177e4SLinus Torvalds static void hci_auth_req(struct hci_dev *hdev, unsigned long opt)
3131da177e4SLinus Torvalds {
3141da177e4SLinus Torvalds 	__u8 auth = opt;
3151da177e4SLinus Torvalds 
3161da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, auth);
3171da177e4SLinus Torvalds 
3181da177e4SLinus Torvalds 	/* Authentication */
319a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
3201da177e4SLinus Torvalds }
3211da177e4SLinus Torvalds 
3221da177e4SLinus Torvalds static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt)
3231da177e4SLinus Torvalds {
3241da177e4SLinus Torvalds 	__u8 encrypt = opt;
3251da177e4SLinus Torvalds 
3261da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, encrypt);
3271da177e4SLinus Torvalds 
328e4e8e37cSMarcel Holtmann 	/* Encryption */
329a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
3301da177e4SLinus Torvalds }
3311da177e4SLinus Torvalds 
332e4e8e37cSMarcel Holtmann static void hci_linkpol_req(struct hci_dev *hdev, unsigned long opt)
333e4e8e37cSMarcel Holtmann {
334e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
335e4e8e37cSMarcel Holtmann 
336a418b893SMarcel Holtmann 	BT_DBG("%s %x", hdev->name, policy);
337e4e8e37cSMarcel Holtmann 
338e4e8e37cSMarcel Holtmann 	/* Default link policy */
339e4e8e37cSMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
340e4e8e37cSMarcel Holtmann }
341e4e8e37cSMarcel Holtmann 
3421da177e4SLinus Torvalds /* Get HCI device by index.
3431da177e4SLinus Torvalds  * Device is held on return. */
3441da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
3451da177e4SLinus Torvalds {
3468035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
3471da177e4SLinus Torvalds 
3481da177e4SLinus Torvalds 	BT_DBG("%d", index);
3491da177e4SLinus Torvalds 
3501da177e4SLinus Torvalds 	if (index < 0)
3511da177e4SLinus Torvalds 		return NULL;
3521da177e4SLinus Torvalds 
3531da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
3548035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
3551da177e4SLinus Torvalds 		if (d->id == index) {
3561da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
3571da177e4SLinus Torvalds 			break;
3581da177e4SLinus Torvalds 		}
3591da177e4SLinus Torvalds 	}
3601da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
3611da177e4SLinus Torvalds 	return hdev;
3621da177e4SLinus Torvalds }
3631da177e4SLinus Torvalds 
3641da177e4SLinus Torvalds /* ---- Inquiry support ---- */
365ff9ef578SJohan Hedberg 
36630dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
36730dc78e1SJohan Hedberg {
36830dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
36930dc78e1SJohan Hedberg 
3706fbe195dSAndre Guedes 	switch (discov->state) {
371343f935bSAndre Guedes 	case DISCOVERY_FINDING:
3726fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
37330dc78e1SJohan Hedberg 		return true;
37430dc78e1SJohan Hedberg 
3756fbe195dSAndre Guedes 	default:
37630dc78e1SJohan Hedberg 		return false;
37730dc78e1SJohan Hedberg 	}
3786fbe195dSAndre Guedes }
37930dc78e1SJohan Hedberg 
380ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
381ff9ef578SJohan Hedberg {
382ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
383ff9ef578SJohan Hedberg 
384ff9ef578SJohan Hedberg 	if (hdev->discovery.state == state)
385ff9ef578SJohan Hedberg 		return;
386ff9ef578SJohan Hedberg 
387ff9ef578SJohan Hedberg 	switch (state) {
388ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
3897b99b659SAndre Guedes 		if (hdev->discovery.state != DISCOVERY_STARTING)
390ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
391ff9ef578SJohan Hedberg 		break;
392ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
393ff9ef578SJohan Hedberg 		break;
394343f935bSAndre Guedes 	case DISCOVERY_FINDING:
395ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
396ff9ef578SJohan Hedberg 		break;
39730dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
39830dc78e1SJohan Hedberg 		break;
399ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
400ff9ef578SJohan Hedberg 		break;
401ff9ef578SJohan Hedberg 	}
402ff9ef578SJohan Hedberg 
403ff9ef578SJohan Hedberg 	hdev->discovery.state = state;
404ff9ef578SJohan Hedberg }
405ff9ef578SJohan Hedberg 
4061da177e4SLinus Torvalds static void inquiry_cache_flush(struct hci_dev *hdev)
4071da177e4SLinus Torvalds {
40830883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
409b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
4101da177e4SLinus Torvalds 
411561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
412561aafbcSJohan Hedberg 		list_del(&p->all);
413b57c1a56SJohan Hedberg 		kfree(p);
4141da177e4SLinus Torvalds 	}
415561aafbcSJohan Hedberg 
416561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
417561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
4181da177e4SLinus Torvalds }
4191da177e4SLinus Torvalds 
4201da177e4SLinus Torvalds struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
4211da177e4SLinus Torvalds {
42230883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
4231da177e4SLinus Torvalds 	struct inquiry_entry *e;
4241da177e4SLinus Torvalds 
4251da177e4SLinus Torvalds 	BT_DBG("cache %p, %s", cache, batostr(bdaddr));
4261da177e4SLinus Torvalds 
427561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
4281da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
4291da177e4SLinus Torvalds 			return e;
4301da177e4SLinus Torvalds 	}
4311da177e4SLinus Torvalds 
432b57c1a56SJohan Hedberg 	return NULL;
433b57c1a56SJohan Hedberg }
434b57c1a56SJohan Hedberg 
435561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
436561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
437561aafbcSJohan Hedberg {
43830883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
439561aafbcSJohan Hedberg 	struct inquiry_entry *e;
440561aafbcSJohan Hedberg 
441561aafbcSJohan Hedberg 	BT_DBG("cache %p, %s", cache, batostr(bdaddr));
442561aafbcSJohan Hedberg 
443561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
444561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
445561aafbcSJohan Hedberg 			return e;
446561aafbcSJohan Hedberg 	}
447561aafbcSJohan Hedberg 
448561aafbcSJohan Hedberg 	return NULL;
449561aafbcSJohan Hedberg }
450561aafbcSJohan Hedberg 
45130dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
45230dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
45330dc78e1SJohan Hedberg 						       int state)
45430dc78e1SJohan Hedberg {
45530dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
45630dc78e1SJohan Hedberg 	struct inquiry_entry *e;
45730dc78e1SJohan Hedberg 
45830dc78e1SJohan Hedberg 	BT_DBG("cache %p bdaddr %s state %d", cache, batostr(bdaddr), state);
45930dc78e1SJohan Hedberg 
46030dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
46130dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
46230dc78e1SJohan Hedberg 			return e;
46330dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
46430dc78e1SJohan Hedberg 			return e;
46530dc78e1SJohan Hedberg 	}
46630dc78e1SJohan Hedberg 
46730dc78e1SJohan Hedberg 	return NULL;
46830dc78e1SJohan Hedberg }
46930dc78e1SJohan Hedberg 
470a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
471a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
472a3d4e20aSJohan Hedberg {
473a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
474a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
475a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
476a3d4e20aSJohan Hedberg 
477a3d4e20aSJohan Hedberg 	list_del(&ie->list);
478a3d4e20aSJohan Hedberg 
479a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
480a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
481a3d4e20aSJohan Hedberg 				abs(p->data.rssi) >= abs(ie->data.rssi))
482a3d4e20aSJohan Hedberg 			break;
483a3d4e20aSJohan Hedberg 		pos = &p->list;
484a3d4e20aSJohan Hedberg 	}
485a3d4e20aSJohan Hedberg 
486a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
487a3d4e20aSJohan Hedberg }
488a3d4e20aSJohan Hedberg 
4893175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
490388fc8faSJohan Hedberg 			      bool name_known, bool *ssp)
4911da177e4SLinus Torvalds {
49230883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
49370f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
4941da177e4SLinus Torvalds 
4951da177e4SLinus Torvalds 	BT_DBG("cache %p, %s", cache, batostr(&data->bdaddr));
4961da177e4SLinus Torvalds 
497388fc8faSJohan Hedberg 	if (ssp)
498388fc8faSJohan Hedberg 		*ssp = data->ssp_mode;
499388fc8faSJohan Hedberg 
50070f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
501a3d4e20aSJohan Hedberg 	if (ie) {
502388fc8faSJohan Hedberg 		if (ie->data.ssp_mode && ssp)
503388fc8faSJohan Hedberg 			*ssp = true;
504388fc8faSJohan Hedberg 
505a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
506a3d4e20aSJohan Hedberg 						data->rssi != ie->data.rssi) {
507a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
508a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
509a3d4e20aSJohan Hedberg 		}
510a3d4e20aSJohan Hedberg 
511561aafbcSJohan Hedberg 		goto update;
512a3d4e20aSJohan Hedberg 	}
513561aafbcSJohan Hedberg 
5141da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
51570f23020SAndrei Emeltchenko 	ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
51670f23020SAndrei Emeltchenko 	if (!ie)
5173175405bSJohan Hedberg 		return false;
51870f23020SAndrei Emeltchenko 
519561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
520561aafbcSJohan Hedberg 
521561aafbcSJohan Hedberg 	if (name_known) {
522561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
523561aafbcSJohan Hedberg 	} else {
524561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
525561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
526561aafbcSJohan Hedberg 	}
527561aafbcSJohan Hedberg 
528561aafbcSJohan Hedberg update:
529561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
530561aafbcSJohan Hedberg 					ie->name_state != NAME_PENDING) {
531561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
532561aafbcSJohan Hedberg 		list_del(&ie->list);
5331da177e4SLinus Torvalds 	}
5341da177e4SLinus Torvalds 
53570f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
53670f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
5371da177e4SLinus Torvalds 	cache->timestamp = jiffies;
5383175405bSJohan Hedberg 
5393175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
5403175405bSJohan Hedberg 		return false;
5413175405bSJohan Hedberg 
5423175405bSJohan Hedberg 	return true;
5431da177e4SLinus Torvalds }
5441da177e4SLinus Torvalds 
5451da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
5461da177e4SLinus Torvalds {
54730883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
5481da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
5491da177e4SLinus Torvalds 	struct inquiry_entry *e;
5501da177e4SLinus Torvalds 	int copied = 0;
5511da177e4SLinus Torvalds 
552561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
5531da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
554b57c1a56SJohan Hedberg 
555b57c1a56SJohan Hedberg 		if (copied >= num)
556b57c1a56SJohan Hedberg 			break;
557b57c1a56SJohan Hedberg 
5581da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
5591da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
5601da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
5611da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
5621da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
5631da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
564b57c1a56SJohan Hedberg 
5651da177e4SLinus Torvalds 		info++;
566b57c1a56SJohan Hedberg 		copied++;
5671da177e4SLinus Torvalds 	}
5681da177e4SLinus Torvalds 
5691da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
5701da177e4SLinus Torvalds 	return copied;
5711da177e4SLinus Torvalds }
5721da177e4SLinus Torvalds 
5731da177e4SLinus Torvalds static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
5741da177e4SLinus Torvalds {
5751da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
5761da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
5771da177e4SLinus Torvalds 
5781da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
5791da177e4SLinus Torvalds 
5801da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
5811da177e4SLinus Torvalds 		return;
5821da177e4SLinus Torvalds 
5831da177e4SLinus Torvalds 	/* Start Inquiry */
5841da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
5851da177e4SLinus Torvalds 	cp.length  = ir->length;
5861da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
587a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
5881da177e4SLinus Torvalds }
5891da177e4SLinus Torvalds 
5901da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
5911da177e4SLinus Torvalds {
5921da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
5931da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
5941da177e4SLinus Torvalds 	struct hci_dev *hdev;
5951da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
5961da177e4SLinus Torvalds 	long timeo;
5971da177e4SLinus Torvalds 	__u8 *buf;
5981da177e4SLinus Torvalds 
5991da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
6001da177e4SLinus Torvalds 		return -EFAULT;
6011da177e4SLinus Torvalds 
6025a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
6035a08ecceSAndrei Emeltchenko 	if (!hdev)
6041da177e4SLinus Torvalds 		return -ENODEV;
6051da177e4SLinus Torvalds 
60609fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
6071da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
6081da177e4SLinus Torvalds 				inquiry_cache_empty(hdev) ||
6091da177e4SLinus Torvalds 				ir.flags & IREQ_CACHE_FLUSH) {
6101da177e4SLinus Torvalds 		inquiry_cache_flush(hdev);
6111da177e4SLinus Torvalds 		do_inquiry = 1;
6121da177e4SLinus Torvalds 	}
61309fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
6141da177e4SLinus Torvalds 
61504837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
61670f23020SAndrei Emeltchenko 
61770f23020SAndrei Emeltchenko 	if (do_inquiry) {
61870f23020SAndrei Emeltchenko 		err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo);
61970f23020SAndrei Emeltchenko 		if (err < 0)
6201da177e4SLinus Torvalds 			goto done;
62170f23020SAndrei Emeltchenko 	}
6221da177e4SLinus Torvalds 
6231da177e4SLinus Torvalds 	/* for unlimited number of responses we will use buffer with 255 entries */
6241da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
6251da177e4SLinus Torvalds 
6261da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
6271da177e4SLinus Torvalds 	 * copy it to the user space.
6281da177e4SLinus Torvalds 	 */
62970f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
63070f23020SAndrei Emeltchenko 	if (!buf) {
6311da177e4SLinus Torvalds 		err = -ENOMEM;
6321da177e4SLinus Torvalds 		goto done;
6331da177e4SLinus Torvalds 	}
6341da177e4SLinus Torvalds 
63509fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
6361da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
63709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
6381da177e4SLinus Torvalds 
6391da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
6401da177e4SLinus Torvalds 
6411da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
6421da177e4SLinus Torvalds 		ptr += sizeof(ir);
6431da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
6441da177e4SLinus Torvalds 					ir.num_rsp))
6451da177e4SLinus Torvalds 			err = -EFAULT;
6461da177e4SLinus Torvalds 	} else
6471da177e4SLinus Torvalds 		err = -EFAULT;
6481da177e4SLinus Torvalds 
6491da177e4SLinus Torvalds 	kfree(buf);
6501da177e4SLinus Torvalds 
6511da177e4SLinus Torvalds done:
6521da177e4SLinus Torvalds 	hci_dev_put(hdev);
6531da177e4SLinus Torvalds 	return err;
6541da177e4SLinus Torvalds }
6551da177e4SLinus Torvalds 
6561da177e4SLinus Torvalds /* ---- HCI ioctl helpers ---- */
6571da177e4SLinus Torvalds 
6581da177e4SLinus Torvalds int hci_dev_open(__u16 dev)
6591da177e4SLinus Torvalds {
6601da177e4SLinus Torvalds 	struct hci_dev *hdev;
6611da177e4SLinus Torvalds 	int ret = 0;
6621da177e4SLinus Torvalds 
6635a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(dev);
6645a08ecceSAndrei Emeltchenko 	if (!hdev)
6651da177e4SLinus Torvalds 		return -ENODEV;
6661da177e4SLinus Torvalds 
6671da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
6681da177e4SLinus Torvalds 
6691da177e4SLinus Torvalds 	hci_req_lock(hdev);
6701da177e4SLinus Torvalds 
67194324962SJohan Hovold 	if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) {
67294324962SJohan Hovold 		ret = -ENODEV;
67394324962SJohan Hovold 		goto done;
67494324962SJohan Hovold 	}
67594324962SJohan Hovold 
676611b30f7SMarcel Holtmann 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) {
677611b30f7SMarcel Holtmann 		ret = -ERFKILL;
678611b30f7SMarcel Holtmann 		goto done;
679611b30f7SMarcel Holtmann 	}
680611b30f7SMarcel Holtmann 
6811da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
6821da177e4SLinus Torvalds 		ret = -EALREADY;
6831da177e4SLinus Torvalds 		goto done;
6841da177e4SLinus Torvalds 	}
6851da177e4SLinus Torvalds 
6861da177e4SLinus Torvalds 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
6871da177e4SLinus Torvalds 		set_bit(HCI_RAW, &hdev->flags);
6881da177e4SLinus Torvalds 
68907e3b94aSAndrei Emeltchenko 	/* Treat all non BR/EDR controllers as raw devices if
69007e3b94aSAndrei Emeltchenko 	   enable_hs is not set */
69107e3b94aSAndrei Emeltchenko 	if (hdev->dev_type != HCI_BREDR && !enable_hs)
692943da25dSMarcel Holtmann 		set_bit(HCI_RAW, &hdev->flags);
693943da25dSMarcel Holtmann 
6941da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
6951da177e4SLinus Torvalds 		ret = -EIO;
6961da177e4SLinus Torvalds 		goto done;
6971da177e4SLinus Torvalds 	}
6981da177e4SLinus Torvalds 
6991da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
7001da177e4SLinus Torvalds 		atomic_set(&hdev->cmd_cnt, 1);
7011da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
702a5040efaSJohan Hedberg 		hdev->init_last_cmd = 0;
7031da177e4SLinus Torvalds 
70404837f64SMarcel Holtmann 		ret = __hci_request(hdev, hci_init_req, 0,
70504837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
7061da177e4SLinus Torvalds 
707eead27daSAndre Guedes 		if (lmp_host_le_capable(hdev))
7086ed58ec5SVille Tervo 			ret = __hci_request(hdev, hci_le_init_req, 0,
7096ed58ec5SVille Tervo 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
7106ed58ec5SVille Tervo 
7111da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
7121da177e4SLinus Torvalds 	}
7131da177e4SLinus Torvalds 
7141da177e4SLinus Torvalds 	if (!ret) {
7151da177e4SLinus Torvalds 		hci_dev_hold(hdev);
7161da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
7171da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
718a8b2d5c2SJohan Hedberg 		if (!test_bit(HCI_SETUP, &hdev->dev_flags)) {
71909fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
720744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
72109fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
72256e5cb86SJohan Hedberg 		}
7231da177e4SLinus Torvalds 	} else {
7241da177e4SLinus Torvalds 		/* Init failed, cleanup */
7253eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
726c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
727b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
7281da177e4SLinus Torvalds 
7291da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
7301da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
7311da177e4SLinus Torvalds 
7321da177e4SLinus Torvalds 		if (hdev->flush)
7331da177e4SLinus Torvalds 			hdev->flush(hdev);
7341da177e4SLinus Torvalds 
7351da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
7361da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
7371da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
7381da177e4SLinus Torvalds 		}
7391da177e4SLinus Torvalds 
7401da177e4SLinus Torvalds 		hdev->close(hdev);
7411da177e4SLinus Torvalds 		hdev->flags = 0;
7421da177e4SLinus Torvalds 	}
7431da177e4SLinus Torvalds 
7441da177e4SLinus Torvalds done:
7451da177e4SLinus Torvalds 	hci_req_unlock(hdev);
7461da177e4SLinus Torvalds 	hci_dev_put(hdev);
7471da177e4SLinus Torvalds 	return ret;
7481da177e4SLinus Torvalds }
7491da177e4SLinus Torvalds 
7501da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
7511da177e4SLinus Torvalds {
7521da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
7531da177e4SLinus Torvalds 
75428b75a89SAndre Guedes 	cancel_work_sync(&hdev->le_scan);
75528b75a89SAndre Guedes 
7561da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
7571da177e4SLinus Torvalds 	hci_req_lock(hdev);
7581da177e4SLinus Torvalds 
7591da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
760b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
7611da177e4SLinus Torvalds 		hci_req_unlock(hdev);
7621da177e4SLinus Torvalds 		return 0;
7631da177e4SLinus Torvalds 	}
7641da177e4SLinus Torvalds 
7653eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
7663eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
767b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
7681da177e4SLinus Torvalds 
76916ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
770e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
77116ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
7725e5282bbSJohan Hedberg 		clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
77316ab91abSJohan Hedberg 	}
77416ab91abSJohan Hedberg 
775a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
7767d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
7777d78525dSJohan Hedberg 
7787ba8b4beSAndre Guedes 	cancel_delayed_work_sync(&hdev->le_scan_disable);
7797ba8b4beSAndre Guedes 
78009fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
7811da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
7821da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
78309fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
7841da177e4SLinus Torvalds 
7851da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
7861da177e4SLinus Torvalds 
7871da177e4SLinus Torvalds 	if (hdev->flush)
7881da177e4SLinus Torvalds 		hdev->flush(hdev);
7891da177e4SLinus Torvalds 
7901da177e4SLinus Torvalds 	/* Reset device */
7911da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
7921da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
7938af59467SJohan Hedberg 	if (!test_bit(HCI_RAW, &hdev->flags) &&
7948af59467SJohan Hedberg 				test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) {
7951da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
79604837f64SMarcel Holtmann 		__hci_request(hdev, hci_reset_req, 0,
797cad44c2bSGustavo F. Padovan 					msecs_to_jiffies(250));
7981da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
7991da177e4SLinus Torvalds 	}
8001da177e4SLinus Torvalds 
801c347b765SGustavo F. Padovan 	/* flush cmd  work */
802c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
8031da177e4SLinus Torvalds 
8041da177e4SLinus Torvalds 	/* Drop queues */
8051da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
8061da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
8071da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
8081da177e4SLinus Torvalds 
8091da177e4SLinus Torvalds 	/* Drop last sent command */
8101da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
811b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
8121da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
8131da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
8141da177e4SLinus Torvalds 	}
8151da177e4SLinus Torvalds 
8161da177e4SLinus Torvalds 	/* After this point our queues are empty
8171da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
8181da177e4SLinus Torvalds 	hdev->close(hdev);
8191da177e4SLinus Torvalds 
8208ee56540SMarcel Holtmann 	if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
82109fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
822744cf19eSJohan Hedberg 		mgmt_powered(hdev, 0);
82309fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
8248ee56540SMarcel Holtmann 	}
8255add6af8SJohan Hedberg 
8261da177e4SLinus Torvalds 	/* Clear flags */
8271da177e4SLinus Torvalds 	hdev->flags = 0;
8281da177e4SLinus Torvalds 
829e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
83009b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
831e59fda8dSJohan Hedberg 
8321da177e4SLinus Torvalds 	hci_req_unlock(hdev);
8331da177e4SLinus Torvalds 
8341da177e4SLinus Torvalds 	hci_dev_put(hdev);
8351da177e4SLinus Torvalds 	return 0;
8361da177e4SLinus Torvalds }
8371da177e4SLinus Torvalds 
8381da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
8391da177e4SLinus Torvalds {
8401da177e4SLinus Torvalds 	struct hci_dev *hdev;
8411da177e4SLinus Torvalds 	int err;
8421da177e4SLinus Torvalds 
84370f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
84470f23020SAndrei Emeltchenko 	if (!hdev)
8451da177e4SLinus Torvalds 		return -ENODEV;
8468ee56540SMarcel Holtmann 
8478ee56540SMarcel Holtmann 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
8488ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
8498ee56540SMarcel Holtmann 
8501da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
8518ee56540SMarcel Holtmann 
8521da177e4SLinus Torvalds 	hci_dev_put(hdev);
8531da177e4SLinus Torvalds 	return err;
8541da177e4SLinus Torvalds }
8551da177e4SLinus Torvalds 
8561da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
8571da177e4SLinus Torvalds {
8581da177e4SLinus Torvalds 	struct hci_dev *hdev;
8591da177e4SLinus Torvalds 	int ret = 0;
8601da177e4SLinus Torvalds 
86170f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
86270f23020SAndrei Emeltchenko 	if (!hdev)
8631da177e4SLinus Torvalds 		return -ENODEV;
8641da177e4SLinus Torvalds 
8651da177e4SLinus Torvalds 	hci_req_lock(hdev);
8661da177e4SLinus Torvalds 
8671da177e4SLinus Torvalds 	if (!test_bit(HCI_UP, &hdev->flags))
8681da177e4SLinus Torvalds 		goto done;
8691da177e4SLinus Torvalds 
8701da177e4SLinus Torvalds 	/* Drop queues */
8711da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
8721da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
8731da177e4SLinus Torvalds 
87409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
8751da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
8761da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
87709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
8781da177e4SLinus Torvalds 
8791da177e4SLinus Torvalds 	if (hdev->flush)
8801da177e4SLinus Torvalds 		hdev->flush(hdev);
8811da177e4SLinus Torvalds 
8821da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
8836ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
8841da177e4SLinus Torvalds 
8851da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags))
88604837f64SMarcel Holtmann 		ret = __hci_request(hdev, hci_reset_req, 0,
88704837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
8881da177e4SLinus Torvalds 
8891da177e4SLinus Torvalds done:
8901da177e4SLinus Torvalds 	hci_req_unlock(hdev);
8911da177e4SLinus Torvalds 	hci_dev_put(hdev);
8921da177e4SLinus Torvalds 	return ret;
8931da177e4SLinus Torvalds }
8941da177e4SLinus Torvalds 
8951da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
8961da177e4SLinus Torvalds {
8971da177e4SLinus Torvalds 	struct hci_dev *hdev;
8981da177e4SLinus Torvalds 	int ret = 0;
8991da177e4SLinus Torvalds 
90070f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
90170f23020SAndrei Emeltchenko 	if (!hdev)
9021da177e4SLinus Torvalds 		return -ENODEV;
9031da177e4SLinus Torvalds 
9041da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
9051da177e4SLinus Torvalds 
9061da177e4SLinus Torvalds 	hci_dev_put(hdev);
9071da177e4SLinus Torvalds 
9081da177e4SLinus Torvalds 	return ret;
9091da177e4SLinus Torvalds }
9101da177e4SLinus Torvalds 
9111da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
9121da177e4SLinus Torvalds {
9131da177e4SLinus Torvalds 	struct hci_dev *hdev;
9141da177e4SLinus Torvalds 	struct hci_dev_req dr;
9151da177e4SLinus Torvalds 	int err = 0;
9161da177e4SLinus Torvalds 
9171da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
9181da177e4SLinus Torvalds 		return -EFAULT;
9191da177e4SLinus Torvalds 
92070f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
92170f23020SAndrei Emeltchenko 	if (!hdev)
9221da177e4SLinus Torvalds 		return -ENODEV;
9231da177e4SLinus Torvalds 
9241da177e4SLinus Torvalds 	switch (cmd) {
9251da177e4SLinus Torvalds 	case HCISETAUTH:
92604837f64SMarcel Holtmann 		err = hci_request(hdev, hci_auth_req, dr.dev_opt,
92704837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
9281da177e4SLinus Torvalds 		break;
9291da177e4SLinus Torvalds 
9301da177e4SLinus Torvalds 	case HCISETENCRYPT:
9311da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
9321da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
9331da177e4SLinus Torvalds 			break;
9341da177e4SLinus Torvalds 		}
9351da177e4SLinus Torvalds 
9361da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
9371da177e4SLinus Torvalds 			/* Auth must be enabled first */
93804837f64SMarcel Holtmann 			err = hci_request(hdev, hci_auth_req, dr.dev_opt,
93904837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
9401da177e4SLinus Torvalds 			if (err)
9411da177e4SLinus Torvalds 				break;
9421da177e4SLinus Torvalds 		}
9431da177e4SLinus Torvalds 
94404837f64SMarcel Holtmann 		err = hci_request(hdev, hci_encrypt_req, dr.dev_opt,
94504837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
9461da177e4SLinus Torvalds 		break;
9471da177e4SLinus Torvalds 
9481da177e4SLinus Torvalds 	case HCISETSCAN:
94904837f64SMarcel Holtmann 		err = hci_request(hdev, hci_scan_req, dr.dev_opt,
95004837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
9511da177e4SLinus Torvalds 		break;
9521da177e4SLinus Torvalds 
9531da177e4SLinus Torvalds 	case HCISETLINKPOL:
954e4e8e37cSMarcel Holtmann 		err = hci_request(hdev, hci_linkpol_req, dr.dev_opt,
955e4e8e37cSMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
9561da177e4SLinus Torvalds 		break;
9571da177e4SLinus Torvalds 
9581da177e4SLinus Torvalds 	case HCISETLINKMODE:
959e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
960e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
961e4e8e37cSMarcel Holtmann 		break;
962e4e8e37cSMarcel Holtmann 
963e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
964e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
9651da177e4SLinus Torvalds 		break;
9661da177e4SLinus Torvalds 
9671da177e4SLinus Torvalds 	case HCISETACLMTU:
9681da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
9691da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
9701da177e4SLinus Torvalds 		break;
9711da177e4SLinus Torvalds 
9721da177e4SLinus Torvalds 	case HCISETSCOMTU:
9731da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
9741da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
9751da177e4SLinus Torvalds 		break;
9761da177e4SLinus Torvalds 
9771da177e4SLinus Torvalds 	default:
9781da177e4SLinus Torvalds 		err = -EINVAL;
9791da177e4SLinus Torvalds 		break;
9801da177e4SLinus Torvalds 	}
981e4e8e37cSMarcel Holtmann 
9821da177e4SLinus Torvalds 	hci_dev_put(hdev);
9831da177e4SLinus Torvalds 	return err;
9841da177e4SLinus Torvalds }
9851da177e4SLinus Torvalds 
9861da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
9871da177e4SLinus Torvalds {
9888035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
9891da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
9901da177e4SLinus Torvalds 	struct hci_dev_req *dr;
9911da177e4SLinus Torvalds 	int n = 0, size, err;
9921da177e4SLinus Torvalds 	__u16 dev_num;
9931da177e4SLinus Torvalds 
9941da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
9951da177e4SLinus Torvalds 		return -EFAULT;
9961da177e4SLinus Torvalds 
9971da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
9981da177e4SLinus Torvalds 		return -EINVAL;
9991da177e4SLinus Torvalds 
10001da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
10011da177e4SLinus Torvalds 
100270f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
100370f23020SAndrei Emeltchenko 	if (!dl)
10041da177e4SLinus Torvalds 		return -ENOMEM;
10051da177e4SLinus Torvalds 
10061da177e4SLinus Torvalds 	dr = dl->dev_req;
10071da177e4SLinus Torvalds 
1008f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
10098035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
1010a8b2d5c2SJohan Hedberg 		if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
1011e0f9309fSJohan Hedberg 			cancel_delayed_work(&hdev->power_off);
1012c542a06cSJohan Hedberg 
1013a8b2d5c2SJohan Hedberg 		if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1014a8b2d5c2SJohan Hedberg 			set_bit(HCI_PAIRABLE, &hdev->dev_flags);
1015c542a06cSJohan Hedberg 
10161da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
10171da177e4SLinus Torvalds 		(dr + n)->dev_opt = hdev->flags;
1018c542a06cSJohan Hedberg 
10191da177e4SLinus Torvalds 		if (++n >= dev_num)
10201da177e4SLinus Torvalds 			break;
10211da177e4SLinus Torvalds 	}
1022f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
10231da177e4SLinus Torvalds 
10241da177e4SLinus Torvalds 	dl->dev_num = n;
10251da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
10261da177e4SLinus Torvalds 
10271da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
10281da177e4SLinus Torvalds 	kfree(dl);
10291da177e4SLinus Torvalds 
10301da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
10311da177e4SLinus Torvalds }
10321da177e4SLinus Torvalds 
10331da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
10341da177e4SLinus Torvalds {
10351da177e4SLinus Torvalds 	struct hci_dev *hdev;
10361da177e4SLinus Torvalds 	struct hci_dev_info di;
10371da177e4SLinus Torvalds 	int err = 0;
10381da177e4SLinus Torvalds 
10391da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
10401da177e4SLinus Torvalds 		return -EFAULT;
10411da177e4SLinus Torvalds 
104270f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
104370f23020SAndrei Emeltchenko 	if (!hdev)
10441da177e4SLinus Torvalds 		return -ENODEV;
10451da177e4SLinus Torvalds 
1046a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
10473243553fSJohan Hedberg 		cancel_delayed_work_sync(&hdev->power_off);
1048ab81cbf9SJohan Hedberg 
1049a8b2d5c2SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1050a8b2d5c2SJohan Hedberg 		set_bit(HCI_PAIRABLE, &hdev->dev_flags);
1051c542a06cSJohan Hedberg 
10521da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
10531da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
1054943da25dSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | (hdev->dev_type << 4);
10551da177e4SLinus Torvalds 	di.flags    = hdev->flags;
10561da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
10571da177e4SLinus Torvalds 	di.acl_mtu  = hdev->acl_mtu;
10581da177e4SLinus Torvalds 	di.acl_pkts = hdev->acl_pkts;
10591da177e4SLinus Torvalds 	di.sco_mtu  = hdev->sco_mtu;
10601da177e4SLinus Torvalds 	di.sco_pkts = hdev->sco_pkts;
10611da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
10621da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
10631da177e4SLinus Torvalds 
10641da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
10651da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
10661da177e4SLinus Torvalds 
10671da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
10681da177e4SLinus Torvalds 		err = -EFAULT;
10691da177e4SLinus Torvalds 
10701da177e4SLinus Torvalds 	hci_dev_put(hdev);
10711da177e4SLinus Torvalds 
10721da177e4SLinus Torvalds 	return err;
10731da177e4SLinus Torvalds }
10741da177e4SLinus Torvalds 
10751da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
10761da177e4SLinus Torvalds 
1077611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
1078611b30f7SMarcel Holtmann {
1079611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
1080611b30f7SMarcel Holtmann 
1081611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
1082611b30f7SMarcel Holtmann 
1083611b30f7SMarcel Holtmann 	if (!blocked)
1084611b30f7SMarcel Holtmann 		return 0;
1085611b30f7SMarcel Holtmann 
1086611b30f7SMarcel Holtmann 	hci_dev_do_close(hdev);
1087611b30f7SMarcel Holtmann 
1088611b30f7SMarcel Holtmann 	return 0;
1089611b30f7SMarcel Holtmann }
1090611b30f7SMarcel Holtmann 
1091611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
1092611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
1093611b30f7SMarcel Holtmann };
1094611b30f7SMarcel Holtmann 
10951da177e4SLinus Torvalds /* Alloc HCI device */
10961da177e4SLinus Torvalds struct hci_dev *hci_alloc_dev(void)
10971da177e4SLinus Torvalds {
10981da177e4SLinus Torvalds 	struct hci_dev *hdev;
10991da177e4SLinus Torvalds 
110025ea6db0SMarcel Holtmann 	hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
11011da177e4SLinus Torvalds 	if (!hdev)
11021da177e4SLinus Torvalds 		return NULL;
11031da177e4SLinus Torvalds 
11040ac7e700SDavid Herrmann 	hci_init_sysfs(hdev);
11051da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->driver_init);
11061da177e4SLinus Torvalds 
11071da177e4SLinus Torvalds 	return hdev;
11081da177e4SLinus Torvalds }
11091da177e4SLinus Torvalds EXPORT_SYMBOL(hci_alloc_dev);
11101da177e4SLinus Torvalds 
11111da177e4SLinus Torvalds /* Free HCI device */
11121da177e4SLinus Torvalds void hci_free_dev(struct hci_dev *hdev)
11131da177e4SLinus Torvalds {
11141da177e4SLinus Torvalds 	skb_queue_purge(&hdev->driver_init);
11151da177e4SLinus Torvalds 
1116a91f2e39SMarcel Holtmann 	/* will free via device release */
1117a91f2e39SMarcel Holtmann 	put_device(&hdev->dev);
11181da177e4SLinus Torvalds }
11191da177e4SLinus Torvalds EXPORT_SYMBOL(hci_free_dev);
11201da177e4SLinus Torvalds 
1121ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
1122ab81cbf9SJohan Hedberg {
1123ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
1124ab81cbf9SJohan Hedberg 
1125ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1126ab81cbf9SJohan Hedberg 
1127ab81cbf9SJohan Hedberg 	if (hci_dev_open(hdev->id) < 0)
1128ab81cbf9SJohan Hedberg 		return;
1129ab81cbf9SJohan Hedberg 
1130a8b2d5c2SJohan Hedberg 	if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
113180b7ab33SGustavo F. Padovan 		schedule_delayed_work(&hdev->power_off,
11323243553fSJohan Hedberg 					msecs_to_jiffies(AUTO_OFF_TIMEOUT));
1133ab81cbf9SJohan Hedberg 
1134a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags))
1135744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
1136ab81cbf9SJohan Hedberg }
1137ab81cbf9SJohan Hedberg 
1138ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
1139ab81cbf9SJohan Hedberg {
11403243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
11413243553fSJohan Hedberg 							power_off.work);
1142ab81cbf9SJohan Hedberg 
1143ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1144ab81cbf9SJohan Hedberg 
11458ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
1146ab81cbf9SJohan Hedberg }
1147ab81cbf9SJohan Hedberg 
114816ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
114916ab91abSJohan Hedberg {
115016ab91abSJohan Hedberg 	struct hci_dev *hdev;
115116ab91abSJohan Hedberg 	u8 scan = SCAN_PAGE;
115216ab91abSJohan Hedberg 
115316ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
115416ab91abSJohan Hedberg 
115516ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
115616ab91abSJohan Hedberg 
115709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
115816ab91abSJohan Hedberg 
115916ab91abSJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan);
116016ab91abSJohan Hedberg 
116116ab91abSJohan Hedberg 	hdev->discov_timeout = 0;
116216ab91abSJohan Hedberg 
116309fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
116416ab91abSJohan Hedberg }
116516ab91abSJohan Hedberg 
11662aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev)
11672aeb9a1aSJohan Hedberg {
11682aeb9a1aSJohan Hedberg 	struct list_head *p, *n;
11692aeb9a1aSJohan Hedberg 
11702aeb9a1aSJohan Hedberg 	list_for_each_safe(p, n, &hdev->uuids) {
11712aeb9a1aSJohan Hedberg 		struct bt_uuid *uuid;
11722aeb9a1aSJohan Hedberg 
11732aeb9a1aSJohan Hedberg 		uuid = list_entry(p, struct bt_uuid, list);
11742aeb9a1aSJohan Hedberg 
11752aeb9a1aSJohan Hedberg 		list_del(p);
11762aeb9a1aSJohan Hedberg 		kfree(uuid);
11772aeb9a1aSJohan Hedberg 	}
11782aeb9a1aSJohan Hedberg 
11792aeb9a1aSJohan Hedberg 	return 0;
11802aeb9a1aSJohan Hedberg }
11812aeb9a1aSJohan Hedberg 
118255ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev)
118355ed8ca1SJohan Hedberg {
118455ed8ca1SJohan Hedberg 	struct list_head *p, *n;
118555ed8ca1SJohan Hedberg 
118655ed8ca1SJohan Hedberg 	list_for_each_safe(p, n, &hdev->link_keys) {
118755ed8ca1SJohan Hedberg 		struct link_key *key;
118855ed8ca1SJohan Hedberg 
118955ed8ca1SJohan Hedberg 		key = list_entry(p, struct link_key, list);
119055ed8ca1SJohan Hedberg 
119155ed8ca1SJohan Hedberg 		list_del(p);
119255ed8ca1SJohan Hedberg 		kfree(key);
119355ed8ca1SJohan Hedberg 	}
119455ed8ca1SJohan Hedberg 
119555ed8ca1SJohan Hedberg 	return 0;
119655ed8ca1SJohan Hedberg }
119755ed8ca1SJohan Hedberg 
1198b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev)
1199b899efafSVinicius Costa Gomes {
1200b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1201b899efafSVinicius Costa Gomes 
1202b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1203b899efafSVinicius Costa Gomes 		list_del(&k->list);
1204b899efafSVinicius Costa Gomes 		kfree(k);
1205b899efafSVinicius Costa Gomes 	}
1206b899efafSVinicius Costa Gomes 
1207b899efafSVinicius Costa Gomes 	return 0;
1208b899efafSVinicius Costa Gomes }
1209b899efafSVinicius Costa Gomes 
121055ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
121155ed8ca1SJohan Hedberg {
121255ed8ca1SJohan Hedberg 	struct link_key *k;
121355ed8ca1SJohan Hedberg 
12148035ded4SLuiz Augusto von Dentz 	list_for_each_entry(k, &hdev->link_keys, list)
121555ed8ca1SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0)
121655ed8ca1SJohan Hedberg 			return k;
121755ed8ca1SJohan Hedberg 
121855ed8ca1SJohan Hedberg 	return NULL;
121955ed8ca1SJohan Hedberg }
122055ed8ca1SJohan Hedberg 
1221745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1222d25e28abSJohan Hedberg 						u8 key_type, u8 old_key_type)
1223d25e28abSJohan Hedberg {
1224d25e28abSJohan Hedberg 	/* Legacy key */
1225d25e28abSJohan Hedberg 	if (key_type < 0x03)
1226745c0ce3SVishal Agarwal 		return true;
1227d25e28abSJohan Hedberg 
1228d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
1229d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
1230745c0ce3SVishal Agarwal 		return false;
1231d25e28abSJohan Hedberg 
1232d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
1233d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
1234745c0ce3SVishal Agarwal 		return false;
1235d25e28abSJohan Hedberg 
1236d25e28abSJohan Hedberg 	/* Security mode 3 case */
1237d25e28abSJohan Hedberg 	if (!conn)
1238745c0ce3SVishal Agarwal 		return true;
1239d25e28abSJohan Hedberg 
1240d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
1241d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
1242745c0ce3SVishal Agarwal 		return true;
1243d25e28abSJohan Hedberg 
1244d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
1245d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
1246745c0ce3SVishal Agarwal 		return true;
1247d25e28abSJohan Hedberg 
1248d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
1249d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
1250745c0ce3SVishal Agarwal 		return true;
1251d25e28abSJohan Hedberg 
1252d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
1253d25e28abSJohan Hedberg 	 * persistently */
1254745c0ce3SVishal Agarwal 	return false;
1255d25e28abSJohan Hedberg }
1256d25e28abSJohan Hedberg 
1257c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
125875d262c2SVinicius Costa Gomes {
1259c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
126075d262c2SVinicius Costa Gomes 
1261c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list) {
1262c9839a11SVinicius Costa Gomes 		if (k->ediv != ediv ||
1263c9839a11SVinicius Costa Gomes 				memcmp(rand, k->rand, sizeof(k->rand)))
126475d262c2SVinicius Costa Gomes 			continue;
126575d262c2SVinicius Costa Gomes 
126675d262c2SVinicius Costa Gomes 		return k;
126775d262c2SVinicius Costa Gomes 	}
126875d262c2SVinicius Costa Gomes 
126975d262c2SVinicius Costa Gomes 	return NULL;
127075d262c2SVinicius Costa Gomes }
127175d262c2SVinicius Costa Gomes EXPORT_SYMBOL(hci_find_ltk);
127275d262c2SVinicius Costa Gomes 
1273c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
1274c9839a11SVinicius Costa Gomes 				     u8 addr_type)
127575d262c2SVinicius Costa Gomes {
1276c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
127775d262c2SVinicius Costa Gomes 
1278c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list)
1279c9839a11SVinicius Costa Gomes 		if (addr_type == k->bdaddr_type &&
1280c9839a11SVinicius Costa Gomes 					bacmp(bdaddr, &k->bdaddr) == 0)
128175d262c2SVinicius Costa Gomes 			return k;
128275d262c2SVinicius Costa Gomes 
128375d262c2SVinicius Costa Gomes 	return NULL;
128475d262c2SVinicius Costa Gomes }
1285c9839a11SVinicius Costa Gomes EXPORT_SYMBOL(hci_find_ltk_by_addr);
128675d262c2SVinicius Costa Gomes 
1287d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
1288d25e28abSJohan Hedberg 		     bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
128955ed8ca1SJohan Hedberg {
129055ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
1291745c0ce3SVishal Agarwal 	u8 old_key_type;
1292745c0ce3SVishal Agarwal 	bool persistent;
129355ed8ca1SJohan Hedberg 
129455ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
129555ed8ca1SJohan Hedberg 	if (old_key) {
129655ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
129755ed8ca1SJohan Hedberg 		key = old_key;
129855ed8ca1SJohan Hedberg 	} else {
129912adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
130055ed8ca1SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
130155ed8ca1SJohan Hedberg 		if (!key)
130255ed8ca1SJohan Hedberg 			return -ENOMEM;
130355ed8ca1SJohan Hedberg 		list_add(&key->list, &hdev->link_keys);
130455ed8ca1SJohan Hedberg 	}
130555ed8ca1SJohan Hedberg 
130655ed8ca1SJohan Hedberg 	BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type);
130755ed8ca1SJohan Hedberg 
1308d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
1309d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
1310d25e28abSJohan Hedberg 	 * previous key */
1311d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
1312d25e28abSJohan Hedberg 					(!conn || conn->remote_auth == 0xff) &&
1313655fe6ecSJohan Hedberg 					old_key_type == 0xff) {
1314d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
1315655fe6ecSJohan Hedberg 		if (conn)
1316655fe6ecSJohan Hedberg 			conn->key_type = type;
1317655fe6ecSJohan Hedberg 	}
1318d25e28abSJohan Hedberg 
131955ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
132055ed8ca1SJohan Hedberg 	memcpy(key->val, val, 16);
132155ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
132255ed8ca1SJohan Hedberg 
1323b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
132455ed8ca1SJohan Hedberg 		key->type = old_key_type;
13254748fed2SJohan Hedberg 	else
13264748fed2SJohan Hedberg 		key->type = type;
13274748fed2SJohan Hedberg 
13284df378a1SJohan Hedberg 	if (!new_key)
13294df378a1SJohan Hedberg 		return 0;
13304df378a1SJohan Hedberg 
13314df378a1SJohan Hedberg 	persistent = hci_persistent_key(hdev, conn, type, old_key_type);
13324df378a1SJohan Hedberg 
1333744cf19eSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
13344df378a1SJohan Hedberg 
13356ec5bcadSVishal Agarwal 	if (conn)
13366ec5bcadSVishal Agarwal 		conn->flush_key = !persistent;
133755ed8ca1SJohan Hedberg 
133855ed8ca1SJohan Hedberg 	return 0;
133955ed8ca1SJohan Hedberg }
134055ed8ca1SJohan Hedberg 
1341c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
13429a006657SAndrei Emeltchenko 		int new_key, u8 authenticated, u8 tk[16], u8 enc_size, __le16
134304124681SGustavo F. Padovan 		ediv, u8 rand[8])
134475d262c2SVinicius Costa Gomes {
1345c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
134675d262c2SVinicius Costa Gomes 
1347c9839a11SVinicius Costa Gomes 	if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK))
1348c9839a11SVinicius Costa Gomes 		return 0;
134975d262c2SVinicius Costa Gomes 
1350c9839a11SVinicius Costa Gomes 	old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type);
1351c9839a11SVinicius Costa Gomes 	if (old_key)
135275d262c2SVinicius Costa Gomes 		key = old_key;
1353c9839a11SVinicius Costa Gomes 	else {
1354c9839a11SVinicius Costa Gomes 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
135575d262c2SVinicius Costa Gomes 		if (!key)
135675d262c2SVinicius Costa Gomes 			return -ENOMEM;
1357c9839a11SVinicius Costa Gomes 		list_add(&key->list, &hdev->long_term_keys);
135875d262c2SVinicius Costa Gomes 	}
135975d262c2SVinicius Costa Gomes 
136075d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
1361c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
1362c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
1363c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
1364c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
1365c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
1366c9839a11SVinicius Costa Gomes 	key->type = type;
1367c9839a11SVinicius Costa Gomes 	memcpy(key->rand, rand, sizeof(key->rand));
136875d262c2SVinicius Costa Gomes 
1369c9839a11SVinicius Costa Gomes 	if (!new_key)
1370c9839a11SVinicius Costa Gomes 		return 0;
137175d262c2SVinicius Costa Gomes 
1372261cc5aaSVinicius Costa Gomes 	if (type & HCI_SMP_LTK)
1373261cc5aaSVinicius Costa Gomes 		mgmt_new_ltk(hdev, key, 1);
1374261cc5aaSVinicius Costa Gomes 
137575d262c2SVinicius Costa Gomes 	return 0;
137675d262c2SVinicius Costa Gomes }
137775d262c2SVinicius Costa Gomes 
137855ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
137955ed8ca1SJohan Hedberg {
138055ed8ca1SJohan Hedberg 	struct link_key *key;
138155ed8ca1SJohan Hedberg 
138255ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
138355ed8ca1SJohan Hedberg 	if (!key)
138455ed8ca1SJohan Hedberg 		return -ENOENT;
138555ed8ca1SJohan Hedberg 
138655ed8ca1SJohan Hedberg 	BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
138755ed8ca1SJohan Hedberg 
138855ed8ca1SJohan Hedberg 	list_del(&key->list);
138955ed8ca1SJohan Hedberg 	kfree(key);
139055ed8ca1SJohan Hedberg 
139155ed8ca1SJohan Hedberg 	return 0;
139255ed8ca1SJohan Hedberg }
139355ed8ca1SJohan Hedberg 
1394b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr)
1395b899efafSVinicius Costa Gomes {
1396b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1397b899efafSVinicius Costa Gomes 
1398b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1399b899efafSVinicius Costa Gomes 		if (bacmp(bdaddr, &k->bdaddr))
1400b899efafSVinicius Costa Gomes 			continue;
1401b899efafSVinicius Costa Gomes 
1402b899efafSVinicius Costa Gomes 		BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
1403b899efafSVinicius Costa Gomes 
1404b899efafSVinicius Costa Gomes 		list_del(&k->list);
1405b899efafSVinicius Costa Gomes 		kfree(k);
1406b899efafSVinicius Costa Gomes 	}
1407b899efafSVinicius Costa Gomes 
1408b899efafSVinicius Costa Gomes 	return 0;
1409b899efafSVinicius Costa Gomes }
1410b899efafSVinicius Costa Gomes 
14116bd32326SVille Tervo /* HCI command timer function */
14126bd32326SVille Tervo static void hci_cmd_timer(unsigned long arg)
14136bd32326SVille Tervo {
14146bd32326SVille Tervo 	struct hci_dev *hdev = (void *) arg;
14156bd32326SVille Tervo 
14166bd32326SVille Tervo 	BT_ERR("%s command tx timeout", hdev->name);
14176bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
1418c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
14196bd32326SVille Tervo }
14206bd32326SVille Tervo 
14212763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
14222763eda6SSzymon Janc 					  bdaddr_t *bdaddr)
14232763eda6SSzymon Janc {
14242763eda6SSzymon Janc 	struct oob_data *data;
14252763eda6SSzymon Janc 
14262763eda6SSzymon Janc 	list_for_each_entry(data, &hdev->remote_oob_data, list)
14272763eda6SSzymon Janc 		if (bacmp(bdaddr, &data->bdaddr) == 0)
14282763eda6SSzymon Janc 			return data;
14292763eda6SSzymon Janc 
14302763eda6SSzymon Janc 	return NULL;
14312763eda6SSzymon Janc }
14322763eda6SSzymon Janc 
14332763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
14342763eda6SSzymon Janc {
14352763eda6SSzymon Janc 	struct oob_data *data;
14362763eda6SSzymon Janc 
14372763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
14382763eda6SSzymon Janc 	if (!data)
14392763eda6SSzymon Janc 		return -ENOENT;
14402763eda6SSzymon Janc 
14412763eda6SSzymon Janc 	BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
14422763eda6SSzymon Janc 
14432763eda6SSzymon Janc 	list_del(&data->list);
14442763eda6SSzymon Janc 	kfree(data);
14452763eda6SSzymon Janc 
14462763eda6SSzymon Janc 	return 0;
14472763eda6SSzymon Janc }
14482763eda6SSzymon Janc 
14492763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev)
14502763eda6SSzymon Janc {
14512763eda6SSzymon Janc 	struct oob_data *data, *n;
14522763eda6SSzymon Janc 
14532763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
14542763eda6SSzymon Janc 		list_del(&data->list);
14552763eda6SSzymon Janc 		kfree(data);
14562763eda6SSzymon Janc 	}
14572763eda6SSzymon Janc 
14582763eda6SSzymon Janc 	return 0;
14592763eda6SSzymon Janc }
14602763eda6SSzymon Janc 
14612763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
14622763eda6SSzymon Janc 			    u8 *randomizer)
14632763eda6SSzymon Janc {
14642763eda6SSzymon Janc 	struct oob_data *data;
14652763eda6SSzymon Janc 
14662763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
14672763eda6SSzymon Janc 
14682763eda6SSzymon Janc 	if (!data) {
14692763eda6SSzymon Janc 		data = kmalloc(sizeof(*data), GFP_ATOMIC);
14702763eda6SSzymon Janc 		if (!data)
14712763eda6SSzymon Janc 			return -ENOMEM;
14722763eda6SSzymon Janc 
14732763eda6SSzymon Janc 		bacpy(&data->bdaddr, bdaddr);
14742763eda6SSzymon Janc 		list_add(&data->list, &hdev->remote_oob_data);
14752763eda6SSzymon Janc 	}
14762763eda6SSzymon Janc 
14772763eda6SSzymon Janc 	memcpy(data->hash, hash, sizeof(data->hash));
14782763eda6SSzymon Janc 	memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
14792763eda6SSzymon Janc 
14802763eda6SSzymon Janc 	BT_DBG("%s for %s", hdev->name, batostr(bdaddr));
14812763eda6SSzymon Janc 
14822763eda6SSzymon Janc 	return 0;
14832763eda6SSzymon Janc }
14842763eda6SSzymon Janc 
148504124681SGustavo F. Padovan struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
1486b2a66aadSAntti Julku {
1487b2a66aadSAntti Julku 	struct bdaddr_list *b;
1488b2a66aadSAntti Julku 
14898035ded4SLuiz Augusto von Dentz 	list_for_each_entry(b, &hdev->blacklist, list)
1490b2a66aadSAntti Julku 		if (bacmp(bdaddr, &b->bdaddr) == 0)
1491b2a66aadSAntti Julku 			return b;
1492b2a66aadSAntti Julku 
1493b2a66aadSAntti Julku 	return NULL;
1494b2a66aadSAntti Julku }
1495b2a66aadSAntti Julku 
1496b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev)
1497b2a66aadSAntti Julku {
1498b2a66aadSAntti Julku 	struct list_head *p, *n;
1499b2a66aadSAntti Julku 
1500b2a66aadSAntti Julku 	list_for_each_safe(p, n, &hdev->blacklist) {
1501b2a66aadSAntti Julku 		struct bdaddr_list *b;
1502b2a66aadSAntti Julku 
1503b2a66aadSAntti Julku 		b = list_entry(p, struct bdaddr_list, list);
1504b2a66aadSAntti Julku 
1505b2a66aadSAntti Julku 		list_del(p);
1506b2a66aadSAntti Julku 		kfree(b);
1507b2a66aadSAntti Julku 	}
1508b2a66aadSAntti Julku 
1509b2a66aadSAntti Julku 	return 0;
1510b2a66aadSAntti Julku }
1511b2a66aadSAntti Julku 
151288c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
1513b2a66aadSAntti Julku {
1514b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1515b2a66aadSAntti Julku 
1516b2a66aadSAntti Julku 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
1517b2a66aadSAntti Julku 		return -EBADF;
1518b2a66aadSAntti Julku 
15195e762444SAntti Julku 	if (hci_blacklist_lookup(hdev, bdaddr))
15205e762444SAntti Julku 		return -EEXIST;
1521b2a66aadSAntti Julku 
1522b2a66aadSAntti Julku 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
15235e762444SAntti Julku 	if (!entry)
15245e762444SAntti Julku 		return -ENOMEM;
1525b2a66aadSAntti Julku 
1526b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
1527b2a66aadSAntti Julku 
1528b2a66aadSAntti Julku 	list_add(&entry->list, &hdev->blacklist);
1529b2a66aadSAntti Julku 
153088c1fe4bSJohan Hedberg 	return mgmt_device_blocked(hdev, bdaddr, type);
1531b2a66aadSAntti Julku }
1532b2a66aadSAntti Julku 
153388c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
1534b2a66aadSAntti Julku {
1535b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1536b2a66aadSAntti Julku 
15371ec918ceSSzymon Janc 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
15385e762444SAntti Julku 		return hci_blacklist_clear(hdev);
1539b2a66aadSAntti Julku 
1540b2a66aadSAntti Julku 	entry = hci_blacklist_lookup(hdev, bdaddr);
15411ec918ceSSzymon Janc 	if (!entry)
15425e762444SAntti Julku 		return -ENOENT;
1543b2a66aadSAntti Julku 
1544b2a66aadSAntti Julku 	list_del(&entry->list);
1545b2a66aadSAntti Julku 	kfree(entry);
1546b2a66aadSAntti Julku 
154788c1fe4bSJohan Hedberg 	return mgmt_device_unblocked(hdev, bdaddr, type);
1548b2a66aadSAntti Julku }
1549b2a66aadSAntti Julku 
1550db323f2fSGustavo F. Padovan static void hci_clear_adv_cache(struct work_struct *work)
155135815085SAndre Guedes {
1552db323f2fSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev,
1553db323f2fSGustavo F. Padovan 					    adv_work.work);
155435815085SAndre Guedes 
155535815085SAndre Guedes 	hci_dev_lock(hdev);
155635815085SAndre Guedes 
155735815085SAndre Guedes 	hci_adv_entries_clear(hdev);
155835815085SAndre Guedes 
155935815085SAndre Guedes 	hci_dev_unlock(hdev);
156035815085SAndre Guedes }
156135815085SAndre Guedes 
156276c8686fSAndre Guedes int hci_adv_entries_clear(struct hci_dev *hdev)
156376c8686fSAndre Guedes {
156476c8686fSAndre Guedes 	struct adv_entry *entry, *tmp;
156576c8686fSAndre Guedes 
156676c8686fSAndre Guedes 	list_for_each_entry_safe(entry, tmp, &hdev->adv_entries, list) {
156776c8686fSAndre Guedes 		list_del(&entry->list);
156876c8686fSAndre Guedes 		kfree(entry);
156976c8686fSAndre Guedes 	}
157076c8686fSAndre Guedes 
157176c8686fSAndre Guedes 	BT_DBG("%s adv cache cleared", hdev->name);
157276c8686fSAndre Guedes 
157376c8686fSAndre Guedes 	return 0;
157476c8686fSAndre Guedes }
157576c8686fSAndre Guedes 
157676c8686fSAndre Guedes struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr)
157776c8686fSAndre Guedes {
157876c8686fSAndre Guedes 	struct adv_entry *entry;
157976c8686fSAndre Guedes 
158076c8686fSAndre Guedes 	list_for_each_entry(entry, &hdev->adv_entries, list)
158176c8686fSAndre Guedes 		if (bacmp(bdaddr, &entry->bdaddr) == 0)
158276c8686fSAndre Guedes 			return entry;
158376c8686fSAndre Guedes 
158476c8686fSAndre Guedes 	return NULL;
158576c8686fSAndre Guedes }
158676c8686fSAndre Guedes 
158776c8686fSAndre Guedes static inline int is_connectable_adv(u8 evt_type)
158876c8686fSAndre Guedes {
158976c8686fSAndre Guedes 	if (evt_type == ADV_IND || evt_type == ADV_DIRECT_IND)
159076c8686fSAndre Guedes 		return 1;
159176c8686fSAndre Guedes 
159276c8686fSAndre Guedes 	return 0;
159376c8686fSAndre Guedes }
159476c8686fSAndre Guedes 
159576c8686fSAndre Guedes int hci_add_adv_entry(struct hci_dev *hdev,
159604124681SGustavo F. Padovan 					struct hci_ev_le_advertising_info *ev) { struct adv_entry *entry; if (!is_connectable_adv(ev->evt_type))
159776c8686fSAndre Guedes 		return -EINVAL;
159876c8686fSAndre Guedes 
159976c8686fSAndre Guedes 	/* Only new entries should be added to adv_entries. So, if
160076c8686fSAndre Guedes 	 * bdaddr was found, don't add it. */
160176c8686fSAndre Guedes 	if (hci_find_adv_entry(hdev, &ev->bdaddr))
160276c8686fSAndre Guedes 		return 0;
160376c8686fSAndre Guedes 
16044777bfdeSAndre Guedes 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
160576c8686fSAndre Guedes 	if (!entry)
160676c8686fSAndre Guedes 		return -ENOMEM;
160776c8686fSAndre Guedes 
160876c8686fSAndre Guedes 	bacpy(&entry->bdaddr, &ev->bdaddr);
160976c8686fSAndre Guedes 	entry->bdaddr_type = ev->bdaddr_type;
161076c8686fSAndre Guedes 
161176c8686fSAndre Guedes 	list_add(&entry->list, &hdev->adv_entries);
161276c8686fSAndre Guedes 
161376c8686fSAndre Guedes 	BT_DBG("%s adv entry added: address %s type %u", hdev->name,
161476c8686fSAndre Guedes 				batostr(&entry->bdaddr), entry->bdaddr_type);
161576c8686fSAndre Guedes 
161676c8686fSAndre Guedes 	return 0;
161776c8686fSAndre Guedes }
161876c8686fSAndre Guedes 
16197ba8b4beSAndre Guedes static void le_scan_param_req(struct hci_dev *hdev, unsigned long opt)
16207ba8b4beSAndre Guedes {
16217ba8b4beSAndre Guedes 	struct le_scan_params *param =  (struct le_scan_params *) opt;
16227ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_param cp;
16237ba8b4beSAndre Guedes 
16247ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
16257ba8b4beSAndre Guedes 	cp.type = param->type;
16267ba8b4beSAndre Guedes 	cp.interval = cpu_to_le16(param->interval);
16277ba8b4beSAndre Guedes 	cp.window = cpu_to_le16(param->window);
16287ba8b4beSAndre Guedes 
16297ba8b4beSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp);
16307ba8b4beSAndre Guedes }
16317ba8b4beSAndre Guedes 
16327ba8b4beSAndre Guedes static void le_scan_enable_req(struct hci_dev *hdev, unsigned long opt)
16337ba8b4beSAndre Guedes {
16347ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
16357ba8b4beSAndre Guedes 
16367ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
16377ba8b4beSAndre Guedes 	cp.enable = 1;
16387ba8b4beSAndre Guedes 
16397ba8b4beSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
16407ba8b4beSAndre Guedes }
16417ba8b4beSAndre Guedes 
16427ba8b4beSAndre Guedes static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval,
16437ba8b4beSAndre Guedes 			  u16 window, int timeout)
16447ba8b4beSAndre Guedes {
16457ba8b4beSAndre Guedes 	long timeo = msecs_to_jiffies(3000);
16467ba8b4beSAndre Guedes 	struct le_scan_params param;
16477ba8b4beSAndre Guedes 	int err;
16487ba8b4beSAndre Guedes 
16497ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
16507ba8b4beSAndre Guedes 
16517ba8b4beSAndre Guedes 	if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
16527ba8b4beSAndre Guedes 		return -EINPROGRESS;
16537ba8b4beSAndre Guedes 
16547ba8b4beSAndre Guedes 	param.type = type;
16557ba8b4beSAndre Guedes 	param.interval = interval;
16567ba8b4beSAndre Guedes 	param.window = window;
16577ba8b4beSAndre Guedes 
16587ba8b4beSAndre Guedes 	hci_req_lock(hdev);
16597ba8b4beSAndre Guedes 
16607ba8b4beSAndre Guedes 	err = __hci_request(hdev, le_scan_param_req, (unsigned long) &param,
16617ba8b4beSAndre Guedes 			    timeo);
16627ba8b4beSAndre Guedes 	if (!err)
16637ba8b4beSAndre Guedes 		err = __hci_request(hdev, le_scan_enable_req, 0, timeo);
16647ba8b4beSAndre Guedes 
16657ba8b4beSAndre Guedes 	hci_req_unlock(hdev);
16667ba8b4beSAndre Guedes 
16677ba8b4beSAndre Guedes 	if (err < 0)
16687ba8b4beSAndre Guedes 		return err;
16697ba8b4beSAndre Guedes 
16707ba8b4beSAndre Guedes 	schedule_delayed_work(&hdev->le_scan_disable,
16717ba8b4beSAndre Guedes 			      msecs_to_jiffies(timeout));
16727ba8b4beSAndre Guedes 
16737ba8b4beSAndre Guedes 	return 0;
16747ba8b4beSAndre Guedes }
16757ba8b4beSAndre Guedes 
16767dbfac1dSAndre Guedes int hci_cancel_le_scan(struct hci_dev *hdev)
16777dbfac1dSAndre Guedes {
16787dbfac1dSAndre Guedes 	BT_DBG("%s", hdev->name);
16797dbfac1dSAndre Guedes 
16807dbfac1dSAndre Guedes 	if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags))
16817dbfac1dSAndre Guedes 		return -EALREADY;
16827dbfac1dSAndre Guedes 
16837dbfac1dSAndre Guedes 	if (cancel_delayed_work(&hdev->le_scan_disable)) {
16847dbfac1dSAndre Guedes 		struct hci_cp_le_set_scan_enable cp;
16857dbfac1dSAndre Guedes 
16867dbfac1dSAndre Guedes 		/* Send HCI command to disable LE Scan */
16877dbfac1dSAndre Guedes 		memset(&cp, 0, sizeof(cp));
16887dbfac1dSAndre Guedes 		hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
16897dbfac1dSAndre Guedes 	}
16907dbfac1dSAndre Guedes 
16917dbfac1dSAndre Guedes 	return 0;
16927dbfac1dSAndre Guedes }
16937dbfac1dSAndre Guedes 
16947ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work)
16957ba8b4beSAndre Guedes {
16967ba8b4beSAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev,
16977ba8b4beSAndre Guedes 					    le_scan_disable.work);
16987ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
16997ba8b4beSAndre Guedes 
17007ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
17017ba8b4beSAndre Guedes 
17027ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
17037ba8b4beSAndre Guedes 
17047ba8b4beSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
17057ba8b4beSAndre Guedes }
17067ba8b4beSAndre Guedes 
170728b75a89SAndre Guedes static void le_scan_work(struct work_struct *work)
170828b75a89SAndre Guedes {
170928b75a89SAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev, le_scan);
171028b75a89SAndre Guedes 	struct le_scan_params *param = &hdev->le_scan_params;
171128b75a89SAndre Guedes 
171228b75a89SAndre Guedes 	BT_DBG("%s", hdev->name);
171328b75a89SAndre Guedes 
171404124681SGustavo F. Padovan 	hci_do_le_scan(hdev, param->type, param->interval, param->window,
171504124681SGustavo F. Padovan 		       param->timeout);
171628b75a89SAndre Guedes }
171728b75a89SAndre Guedes 
171828b75a89SAndre Guedes int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window,
171928b75a89SAndre Guedes 		int timeout)
172028b75a89SAndre Guedes {
172128b75a89SAndre Guedes 	struct le_scan_params *param = &hdev->le_scan_params;
172228b75a89SAndre Guedes 
172328b75a89SAndre Guedes 	BT_DBG("%s", hdev->name);
172428b75a89SAndre Guedes 
172528b75a89SAndre Guedes 	if (work_busy(&hdev->le_scan))
172628b75a89SAndre Guedes 		return -EINPROGRESS;
172728b75a89SAndre Guedes 
172828b75a89SAndre Guedes 	param->type = type;
172928b75a89SAndre Guedes 	param->interval = interval;
173028b75a89SAndre Guedes 	param->window = window;
173128b75a89SAndre Guedes 	param->timeout = timeout;
173228b75a89SAndre Guedes 
173328b75a89SAndre Guedes 	queue_work(system_long_wq, &hdev->le_scan);
173428b75a89SAndre Guedes 
173528b75a89SAndre Guedes 	return 0;
173628b75a89SAndre Guedes }
173728b75a89SAndre Guedes 
17381da177e4SLinus Torvalds /* Register HCI device */
17391da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
17401da177e4SLinus Torvalds {
17411da177e4SLinus Torvalds 	struct list_head *head = &hci_dev_list, *p;
174208add513SMat Martineau 	int i, id, error;
17431da177e4SLinus Torvalds 
1744e9b9cfa1SDavid Herrmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
17451da177e4SLinus Torvalds 
1746010666a1SDavid Herrmann 	if (!hdev->open || !hdev->close)
17471da177e4SLinus Torvalds 		return -EINVAL;
17481da177e4SLinus Torvalds 
174908add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
175008add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
175108add513SMat Martineau 	 */
175208add513SMat Martineau 	id = (hdev->dev_type == HCI_BREDR) ? 0 : 1;
175308add513SMat Martineau 
1754f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
17551da177e4SLinus Torvalds 
17561da177e4SLinus Torvalds 	/* Find first available device id */
17571da177e4SLinus Torvalds 	list_for_each(p, &hci_dev_list) {
17581da177e4SLinus Torvalds 		if (list_entry(p, struct hci_dev, list)->id != id)
17591da177e4SLinus Torvalds 			break;
17601da177e4SLinus Torvalds 		head = p; id++;
17611da177e4SLinus Torvalds 	}
17621da177e4SLinus Torvalds 
17631da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
17641da177e4SLinus Torvalds 	hdev->id = id;
1765c6feeb28SAndrei Emeltchenko 	list_add_tail(&hdev->list, head);
17661da177e4SLinus Torvalds 
176709fd0de5SGustavo F. Padovan 	mutex_init(&hdev->lock);
17681da177e4SLinus Torvalds 
17691da177e4SLinus Torvalds 	hdev->flags = 0;
1770d23264a8SAndre Guedes 	hdev->dev_flags = 0;
17711da177e4SLinus Torvalds 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
17725b7f9909SMarcel Holtmann 	hdev->esco_type = (ESCO_HV1);
17731da177e4SLinus Torvalds 	hdev->link_mode = (HCI_LM_ACCEPT);
177417fa4b9dSJohan Hedberg 	hdev->io_capability = 0x03; /* No Input No Output */
17751da177e4SLinus Torvalds 
177604837f64SMarcel Holtmann 	hdev->idle_timeout = 0;
177704837f64SMarcel Holtmann 	hdev->sniff_max_interval = 800;
177804837f64SMarcel Holtmann 	hdev->sniff_min_interval = 80;
177904837f64SMarcel Holtmann 
1780b78752ccSMarcel Holtmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
1781c347b765SGustavo F. Padovan 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
17823eff45eaSGustavo F. Padovan 	INIT_WORK(&hdev->tx_work, hci_tx_work);
1783b78752ccSMarcel Holtmann 
17841da177e4SLinus Torvalds 
17851da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->rx_q);
17861da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->cmd_q);
17871da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->raw_q);
17881da177e4SLinus Torvalds 
17896bd32326SVille Tervo 	setup_timer(&hdev->cmd_timer, hci_cmd_timer, (unsigned long) hdev);
17906bd32326SVille Tervo 
1791cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
1792ef222013SMarcel Holtmann 		hdev->reassembly[i] = NULL;
1793ef222013SMarcel Holtmann 
17941da177e4SLinus Torvalds 	init_waitqueue_head(&hdev->req_wait_q);
1795a6a67efdSThomas Gleixner 	mutex_init(&hdev->req_lock);
17961da177e4SLinus Torvalds 
179730883512SJohan Hedberg 	discovery_init(hdev);
17981da177e4SLinus Torvalds 
17991da177e4SLinus Torvalds 	hci_conn_hash_init(hdev);
18001da177e4SLinus Torvalds 
18012e58ef3eSJohan Hedberg 	INIT_LIST_HEAD(&hdev->mgmt_pending);
18022e58ef3eSJohan Hedberg 
1803ea4bd8baSDavid Miller 	INIT_LIST_HEAD(&hdev->blacklist);
1804f0358568SJohan Hedberg 
18052aeb9a1aSJohan Hedberg 	INIT_LIST_HEAD(&hdev->uuids);
18062aeb9a1aSJohan Hedberg 
180755ed8ca1SJohan Hedberg 	INIT_LIST_HEAD(&hdev->link_keys);
1808b899efafSVinicius Costa Gomes 	INIT_LIST_HEAD(&hdev->long_term_keys);
180955ed8ca1SJohan Hedberg 
18102763eda6SSzymon Janc 	INIT_LIST_HEAD(&hdev->remote_oob_data);
18112763eda6SSzymon Janc 
181276c8686fSAndre Guedes 	INIT_LIST_HEAD(&hdev->adv_entries);
181376c8686fSAndre Guedes 
1814db323f2fSGustavo F. Padovan 	INIT_DELAYED_WORK(&hdev->adv_work, hci_clear_adv_cache);
1815ab81cbf9SJohan Hedberg 	INIT_WORK(&hdev->power_on, hci_power_on);
18163243553fSJohan Hedberg 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
1817ab81cbf9SJohan Hedberg 
181816ab91abSJohan Hedberg 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
181916ab91abSJohan Hedberg 
18201da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
18211da177e4SLinus Torvalds 
18221da177e4SLinus Torvalds 	atomic_set(&hdev->promisc, 0);
18231da177e4SLinus Torvalds 
182428b75a89SAndre Guedes 	INIT_WORK(&hdev->le_scan, le_scan_work);
182528b75a89SAndre Guedes 
18267ba8b4beSAndre Guedes 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
18277ba8b4beSAndre Guedes 
1828f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
18291da177e4SLinus Torvalds 
183032845eb1SGustavo F. Padovan 	hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND |
183132845eb1SGustavo F. Padovan 							WQ_MEM_RECLAIM, 1);
183233ca954dSDavid Herrmann 	if (!hdev->workqueue) {
183333ca954dSDavid Herrmann 		error = -ENOMEM;
183433ca954dSDavid Herrmann 		goto err;
183533ca954dSDavid Herrmann 	}
1836f48fd9c8SMarcel Holtmann 
183733ca954dSDavid Herrmann 	error = hci_add_sysfs(hdev);
183833ca954dSDavid Herrmann 	if (error < 0)
183933ca954dSDavid Herrmann 		goto err_wqueue;
18401da177e4SLinus Torvalds 
1841611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
1842611b30f7SMarcel Holtmann 				RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, hdev);
1843611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
1844611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
1845611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
1846611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
1847611b30f7SMarcel Holtmann 		}
1848611b30f7SMarcel Holtmann 	}
1849611b30f7SMarcel Holtmann 
1850a8b2d5c2SJohan Hedberg 	set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
1851a8b2d5c2SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->dev_flags);
18527f971041SGustavo F. Padovan 	schedule_work(&hdev->power_on);
1853ab81cbf9SJohan Hedberg 
18541da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
1855dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
18561da177e4SLinus Torvalds 
18571da177e4SLinus Torvalds 	return id;
1858f48fd9c8SMarcel Holtmann 
185933ca954dSDavid Herrmann err_wqueue:
186033ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
186133ca954dSDavid Herrmann err:
1862f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
1863f48fd9c8SMarcel Holtmann 	list_del(&hdev->list);
1864f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
1865f48fd9c8SMarcel Holtmann 
186633ca954dSDavid Herrmann 	return error;
18671da177e4SLinus Torvalds }
18681da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
18691da177e4SLinus Torvalds 
18701da177e4SLinus Torvalds /* Unregister HCI device */
187159735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
18721da177e4SLinus Torvalds {
1873ef222013SMarcel Holtmann 	int i;
1874ef222013SMarcel Holtmann 
1875c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
18761da177e4SLinus Torvalds 
187794324962SJohan Hovold 	set_bit(HCI_UNREGISTER, &hdev->dev_flags);
187894324962SJohan Hovold 
1879f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
18801da177e4SLinus Torvalds 	list_del(&hdev->list);
1881f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
18821da177e4SLinus Torvalds 
18831da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
18841da177e4SLinus Torvalds 
1885cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
1886ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
1887ef222013SMarcel Holtmann 
1888ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
1889a8b2d5c2SJohan Hedberg 				!test_bit(HCI_SETUP, &hdev->dev_flags)) {
189009fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
1891744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
189209fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
189356e5cb86SJohan Hedberg 	}
1894ab81cbf9SJohan Hedberg 
18952e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
18962e58ef3eSJohan Hedberg 	 * pending list */
18972e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
18982e58ef3eSJohan Hedberg 
18991da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
19001da177e4SLinus Torvalds 
1901611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
1902611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
1903611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
1904611b30f7SMarcel Holtmann 	}
1905611b30f7SMarcel Holtmann 
1906ce242970SDavid Herrmann 	hci_del_sysfs(hdev);
1907147e2d59SDave Young 
1908db323f2fSGustavo F. Padovan 	cancel_delayed_work_sync(&hdev->adv_work);
1909c6f3c5f7SGustavo F. Padovan 
1910f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
1911f48fd9c8SMarcel Holtmann 
191209fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
1913e2e0cacbSJohan Hedberg 	hci_blacklist_clear(hdev);
19142aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
191555ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
1916b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
19172763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
191876c8686fSAndre Guedes 	hci_adv_entries_clear(hdev);
191909fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
1920e2e0cacbSJohan Hedberg 
1921dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
19221da177e4SLinus Torvalds }
19231da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
19241da177e4SLinus Torvalds 
19251da177e4SLinus Torvalds /* Suspend HCI device */
19261da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
19271da177e4SLinus Torvalds {
19281da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
19291da177e4SLinus Torvalds 	return 0;
19301da177e4SLinus Torvalds }
19311da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
19321da177e4SLinus Torvalds 
19331da177e4SLinus Torvalds /* Resume HCI device */
19341da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
19351da177e4SLinus Torvalds {
19361da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
19371da177e4SLinus Torvalds 	return 0;
19381da177e4SLinus Torvalds }
19391da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
19401da177e4SLinus Torvalds 
194176bca880SMarcel Holtmann /* Receive frame from HCI drivers */
194276bca880SMarcel Holtmann int hci_recv_frame(struct sk_buff *skb)
194376bca880SMarcel Holtmann {
194476bca880SMarcel Holtmann 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
194576bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
194676bca880SMarcel Holtmann 				&& !test_bit(HCI_INIT, &hdev->flags))) {
194776bca880SMarcel Holtmann 		kfree_skb(skb);
194876bca880SMarcel Holtmann 		return -ENXIO;
194976bca880SMarcel Holtmann 	}
195076bca880SMarcel Holtmann 
195176bca880SMarcel Holtmann 	/* Incomming skb */
195276bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
195376bca880SMarcel Holtmann 
195476bca880SMarcel Holtmann 	/* Time stamp */
195576bca880SMarcel Holtmann 	__net_timestamp(skb);
195676bca880SMarcel Holtmann 
195776bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
1958b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
1959c78ae283SMarcel Holtmann 
196076bca880SMarcel Holtmann 	return 0;
196176bca880SMarcel Holtmann }
196276bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
196376bca880SMarcel Holtmann 
196433e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
19651e429f38SGustavo F. Padovan 						  int count, __u8 index)
196633e882a5SSuraj Sumangala {
196733e882a5SSuraj Sumangala 	int len = 0;
196833e882a5SSuraj Sumangala 	int hlen = 0;
196933e882a5SSuraj Sumangala 	int remain = count;
197033e882a5SSuraj Sumangala 	struct sk_buff *skb;
197133e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
197233e882a5SSuraj Sumangala 
197333e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
197433e882a5SSuraj Sumangala 				index >= NUM_REASSEMBLY)
197533e882a5SSuraj Sumangala 		return -EILSEQ;
197633e882a5SSuraj Sumangala 
197733e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
197833e882a5SSuraj Sumangala 
197933e882a5SSuraj Sumangala 	if (!skb) {
198033e882a5SSuraj Sumangala 		switch (type) {
198133e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
198233e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
198333e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
198433e882a5SSuraj Sumangala 			break;
198533e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
198633e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
198733e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
198833e882a5SSuraj Sumangala 			break;
198933e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
199033e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
199133e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
199233e882a5SSuraj Sumangala 			break;
199333e882a5SSuraj Sumangala 		}
199433e882a5SSuraj Sumangala 
19951e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
199633e882a5SSuraj Sumangala 		if (!skb)
199733e882a5SSuraj Sumangala 			return -ENOMEM;
199833e882a5SSuraj Sumangala 
199933e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
200033e882a5SSuraj Sumangala 		scb->expect = hlen;
200133e882a5SSuraj Sumangala 		scb->pkt_type = type;
200233e882a5SSuraj Sumangala 
200333e882a5SSuraj Sumangala 		skb->dev = (void *) hdev;
200433e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
200533e882a5SSuraj Sumangala 	}
200633e882a5SSuraj Sumangala 
200733e882a5SSuraj Sumangala 	while (count) {
200833e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
200989bb46d0SDan Carpenter 		len = min_t(uint, scb->expect, count);
201033e882a5SSuraj Sumangala 
201133e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
201233e882a5SSuraj Sumangala 
201333e882a5SSuraj Sumangala 		count -= len;
201433e882a5SSuraj Sumangala 		data += len;
201533e882a5SSuraj Sumangala 		scb->expect -= len;
201633e882a5SSuraj Sumangala 		remain = count;
201733e882a5SSuraj Sumangala 
201833e882a5SSuraj Sumangala 		switch (type) {
201933e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
202033e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
202133e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
202233e882a5SSuraj Sumangala 				scb->expect = h->plen;
202333e882a5SSuraj Sumangala 
202433e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
202533e882a5SSuraj Sumangala 					kfree_skb(skb);
202633e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
202733e882a5SSuraj Sumangala 					return -ENOMEM;
202833e882a5SSuraj Sumangala 				}
202933e882a5SSuraj Sumangala 			}
203033e882a5SSuraj Sumangala 			break;
203133e882a5SSuraj Sumangala 
203233e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
203333e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
203433e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
203533e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
203633e882a5SSuraj Sumangala 
203733e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
203833e882a5SSuraj Sumangala 					kfree_skb(skb);
203933e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
204033e882a5SSuraj Sumangala 					return -ENOMEM;
204133e882a5SSuraj Sumangala 				}
204233e882a5SSuraj Sumangala 			}
204333e882a5SSuraj Sumangala 			break;
204433e882a5SSuraj Sumangala 
204533e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
204633e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
204733e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
204833e882a5SSuraj Sumangala 				scb->expect = h->dlen;
204933e882a5SSuraj Sumangala 
205033e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
205133e882a5SSuraj Sumangala 					kfree_skb(skb);
205233e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
205333e882a5SSuraj Sumangala 					return -ENOMEM;
205433e882a5SSuraj Sumangala 				}
205533e882a5SSuraj Sumangala 			}
205633e882a5SSuraj Sumangala 			break;
205733e882a5SSuraj Sumangala 		}
205833e882a5SSuraj Sumangala 
205933e882a5SSuraj Sumangala 		if (scb->expect == 0) {
206033e882a5SSuraj Sumangala 			/* Complete frame */
206133e882a5SSuraj Sumangala 
206233e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
206333e882a5SSuraj Sumangala 			hci_recv_frame(skb);
206433e882a5SSuraj Sumangala 
206533e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
206633e882a5SSuraj Sumangala 			return remain;
206733e882a5SSuraj Sumangala 		}
206833e882a5SSuraj Sumangala 	}
206933e882a5SSuraj Sumangala 
207033e882a5SSuraj Sumangala 	return remain;
207133e882a5SSuraj Sumangala }
207233e882a5SSuraj Sumangala 
2073ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
2074ef222013SMarcel Holtmann {
2075f39a3c06SSuraj Sumangala 	int rem = 0;
2076f39a3c06SSuraj Sumangala 
2077ef222013SMarcel Holtmann 	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
2078ef222013SMarcel Holtmann 		return -EILSEQ;
2079ef222013SMarcel Holtmann 
2080da5f6c37SGustavo F. Padovan 	while (count) {
20811e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count, type - 1);
2082f39a3c06SSuraj Sumangala 		if (rem < 0)
2083f39a3c06SSuraj Sumangala 			return rem;
2084ef222013SMarcel Holtmann 
2085f39a3c06SSuraj Sumangala 		data += (count - rem);
2086f39a3c06SSuraj Sumangala 		count = rem;
2087f81c6224SJoe Perches 	}
2088ef222013SMarcel Holtmann 
2089f39a3c06SSuraj Sumangala 	return rem;
2090ef222013SMarcel Holtmann }
2091ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment);
2092ef222013SMarcel Holtmann 
209399811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
209499811510SSuraj Sumangala 
209599811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
209699811510SSuraj Sumangala {
209799811510SSuraj Sumangala 	int type;
209899811510SSuraj Sumangala 	int rem = 0;
209999811510SSuraj Sumangala 
2100da5f6c37SGustavo F. Padovan 	while (count) {
210199811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
210299811510SSuraj Sumangala 
210399811510SSuraj Sumangala 		if (!skb) {
210499811510SSuraj Sumangala 			struct { char type; } *pkt;
210599811510SSuraj Sumangala 
210699811510SSuraj Sumangala 			/* Start of the frame */
210799811510SSuraj Sumangala 			pkt = data;
210899811510SSuraj Sumangala 			type = pkt->type;
210999811510SSuraj Sumangala 
211099811510SSuraj Sumangala 			data++;
211199811510SSuraj Sumangala 			count--;
211299811510SSuraj Sumangala 		} else
211399811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
211499811510SSuraj Sumangala 
21151e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
21161e429f38SGustavo F. Padovan 							STREAM_REASSEMBLY);
211799811510SSuraj Sumangala 		if (rem < 0)
211899811510SSuraj Sumangala 			return rem;
211999811510SSuraj Sumangala 
212099811510SSuraj Sumangala 		data += (count - rem);
212199811510SSuraj Sumangala 		count = rem;
2122f81c6224SJoe Perches 	}
212399811510SSuraj Sumangala 
212499811510SSuraj Sumangala 	return rem;
212599811510SSuraj Sumangala }
212699811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
212799811510SSuraj Sumangala 
21281da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
21291da177e4SLinus Torvalds 
21301da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
21311da177e4SLinus Torvalds {
21321da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
21331da177e4SLinus Torvalds 
2134f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
21351da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
2136f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
21371da177e4SLinus Torvalds 
21381da177e4SLinus Torvalds 	return 0;
21391da177e4SLinus Torvalds }
21401da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
21411da177e4SLinus Torvalds 
21421da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
21431da177e4SLinus Torvalds {
21441da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
21451da177e4SLinus Torvalds 
2146f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
21471da177e4SLinus Torvalds 	list_del(&cb->list);
2148f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
21491da177e4SLinus Torvalds 
21501da177e4SLinus Torvalds 	return 0;
21511da177e4SLinus Torvalds }
21521da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
21531da177e4SLinus Torvalds 
21541da177e4SLinus Torvalds static int hci_send_frame(struct sk_buff *skb)
21551da177e4SLinus Torvalds {
21561da177e4SLinus Torvalds 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
21571da177e4SLinus Torvalds 
21581da177e4SLinus Torvalds 	if (!hdev) {
21591da177e4SLinus Torvalds 		kfree_skb(skb);
21601da177e4SLinus Torvalds 		return -ENODEV;
21611da177e4SLinus Torvalds 	}
21621da177e4SLinus Torvalds 
21630d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
21641da177e4SLinus Torvalds 
21651da177e4SLinus Torvalds 	/* Time stamp */
2166a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
21671da177e4SLinus Torvalds 
2168cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
2169cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
2170cd82e61cSMarcel Holtmann 
2171cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
2172cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
2173470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
21741da177e4SLinus Torvalds 	}
21751da177e4SLinus Torvalds 
21761da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
21771da177e4SLinus Torvalds 	skb_orphan(skb);
21781da177e4SLinus Torvalds 
21791da177e4SLinus Torvalds 	return hdev->send(skb);
21801da177e4SLinus Torvalds }
21811da177e4SLinus Torvalds 
21821da177e4SLinus Torvalds /* Send HCI command */
2183a9de9248SMarcel Holtmann int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)
21841da177e4SLinus Torvalds {
21851da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
21861da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
21871da177e4SLinus Torvalds 	struct sk_buff *skb;
21881da177e4SLinus Torvalds 
2189a9de9248SMarcel Holtmann 	BT_DBG("%s opcode 0x%x plen %d", hdev->name, opcode, plen);
21901da177e4SLinus Torvalds 
21911da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
21921da177e4SLinus Torvalds 	if (!skb) {
2193ef222013SMarcel Holtmann 		BT_ERR("%s no memory for command", hdev->name);
21941da177e4SLinus Torvalds 		return -ENOMEM;
21951da177e4SLinus Torvalds 	}
21961da177e4SLinus Torvalds 
21971da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
2198a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
21991da177e4SLinus Torvalds 	hdr->plen   = plen;
22001da177e4SLinus Torvalds 
22011da177e4SLinus Torvalds 	if (plen)
22021da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
22031da177e4SLinus Torvalds 
22041da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
22051da177e4SLinus Torvalds 
22060d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
22071da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
2208c78ae283SMarcel Holtmann 
2209a5040efaSJohan Hedberg 	if (test_bit(HCI_INIT, &hdev->flags))
2210a5040efaSJohan Hedberg 		hdev->init_last_cmd = opcode;
2211a5040efaSJohan Hedberg 
22121da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
2213c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
22141da177e4SLinus Torvalds 
22151da177e4SLinus Torvalds 	return 0;
22161da177e4SLinus Torvalds }
22171da177e4SLinus Torvalds 
22181da177e4SLinus Torvalds /* Get data from the previously sent command */
2219a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
22201da177e4SLinus Torvalds {
22211da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
22221da177e4SLinus Torvalds 
22231da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
22241da177e4SLinus Torvalds 		return NULL;
22251da177e4SLinus Torvalds 
22261da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
22271da177e4SLinus Torvalds 
2228a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
22291da177e4SLinus Torvalds 		return NULL;
22301da177e4SLinus Torvalds 
2231a9de9248SMarcel Holtmann 	BT_DBG("%s opcode 0x%x", hdev->name, opcode);
22321da177e4SLinus Torvalds 
22331da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
22341da177e4SLinus Torvalds }
22351da177e4SLinus Torvalds 
22361da177e4SLinus Torvalds /* Send ACL data */
22371da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
22381da177e4SLinus Torvalds {
22391da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
22401da177e4SLinus Torvalds 	int len = skb->len;
22411da177e4SLinus Torvalds 
2242badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
2243badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
22449c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
2245aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
2246aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
22471da177e4SLinus Torvalds }
22481da177e4SLinus Torvalds 
224973d80debSLuiz Augusto von Dentz static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue,
225073d80debSLuiz Augusto von Dentz 				struct sk_buff *skb, __u16 flags)
22511da177e4SLinus Torvalds {
22521da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
22531da177e4SLinus Torvalds 	struct sk_buff *list;
22541da177e4SLinus Torvalds 
225570f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
225670f23020SAndrei Emeltchenko 	if (!list) {
22571da177e4SLinus Torvalds 		/* Non fragmented */
22581da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
22591da177e4SLinus Torvalds 
226073d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
22611da177e4SLinus Torvalds 	} else {
22621da177e4SLinus Torvalds 		/* Fragmented */
22631da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
22641da177e4SLinus Torvalds 
22651da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
22661da177e4SLinus Torvalds 
22671da177e4SLinus Torvalds 		/* Queue all fragments atomically */
2268af3e6359SGustavo F. Padovan 		spin_lock(&queue->lock);
22691da177e4SLinus Torvalds 
227073d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
2271e702112fSAndrei Emeltchenko 
2272e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
2273e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
22741da177e4SLinus Torvalds 		do {
22751da177e4SLinus Torvalds 			skb = list; list = list->next;
22761da177e4SLinus Torvalds 
22771da177e4SLinus Torvalds 			skb->dev = (void *) hdev;
22780d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2279e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
22801da177e4SLinus Torvalds 
22811da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
22821da177e4SLinus Torvalds 
228373d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
22841da177e4SLinus Torvalds 		} while (list);
22851da177e4SLinus Torvalds 
2286af3e6359SGustavo F. Padovan 		spin_unlock(&queue->lock);
22871da177e4SLinus Torvalds 	}
228873d80debSLuiz Augusto von Dentz }
228973d80debSLuiz Augusto von Dentz 
229073d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
229173d80debSLuiz Augusto von Dentz {
229273d80debSLuiz Augusto von Dentz 	struct hci_conn *conn = chan->conn;
229373d80debSLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
229473d80debSLuiz Augusto von Dentz 
229573d80debSLuiz Augusto von Dentz 	BT_DBG("%s chan %p flags 0x%x", hdev->name, chan, flags);
229673d80debSLuiz Augusto von Dentz 
229773d80debSLuiz Augusto von Dentz 	skb->dev = (void *) hdev;
229873d80debSLuiz Augusto von Dentz 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
229973d80debSLuiz Augusto von Dentz 	hci_add_acl_hdr(skb, conn->handle, flags);
230073d80debSLuiz Augusto von Dentz 
230173d80debSLuiz Augusto von Dentz 	hci_queue_acl(conn, &chan->data_q, skb, flags);
23021da177e4SLinus Torvalds 
23033eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
23041da177e4SLinus Torvalds }
23051da177e4SLinus Torvalds EXPORT_SYMBOL(hci_send_acl);
23061da177e4SLinus Torvalds 
23071da177e4SLinus Torvalds /* Send SCO data */
23080d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
23091da177e4SLinus Torvalds {
23101da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
23111da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
23121da177e4SLinus Torvalds 
23131da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
23141da177e4SLinus Torvalds 
2315aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
23161da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
23171da177e4SLinus Torvalds 
2318badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
2319badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
23209c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
23211da177e4SLinus Torvalds 
23221da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
23230d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
2324c78ae283SMarcel Holtmann 
23251da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
23263eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
23271da177e4SLinus Torvalds }
23281da177e4SLinus Torvalds EXPORT_SYMBOL(hci_send_sco);
23291da177e4SLinus Torvalds 
23301da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
23311da177e4SLinus Torvalds 
23321da177e4SLinus Torvalds /* HCI Connection scheduler */
23331da177e4SLinus Torvalds static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote)
23341da177e4SLinus Torvalds {
23351da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
23368035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
23371da177e4SLinus Torvalds 	int num = 0, min = ~0;
23381da177e4SLinus Torvalds 
23391da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
23401da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
2341bf4c6325SGustavo F. Padovan 
2342bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2343bf4c6325SGustavo F. Padovan 
2344bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2345769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
23461da177e4SLinus Torvalds 			continue;
2347769be974SMarcel Holtmann 
2348769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
2349769be974SMarcel Holtmann 			continue;
2350769be974SMarcel Holtmann 
23511da177e4SLinus Torvalds 		num++;
23521da177e4SLinus Torvalds 
23531da177e4SLinus Torvalds 		if (c->sent < min) {
23541da177e4SLinus Torvalds 			min  = c->sent;
23551da177e4SLinus Torvalds 			conn = c;
23561da177e4SLinus Torvalds 		}
235752087a79SLuiz Augusto von Dentz 
235852087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
235952087a79SLuiz Augusto von Dentz 			break;
23601da177e4SLinus Torvalds 	}
23611da177e4SLinus Torvalds 
2362bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2363bf4c6325SGustavo F. Padovan 
23641da177e4SLinus Torvalds 	if (conn) {
23656ed58ec5SVille Tervo 		int cnt, q;
23666ed58ec5SVille Tervo 
23676ed58ec5SVille Tervo 		switch (conn->type) {
23686ed58ec5SVille Tervo 		case ACL_LINK:
23696ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
23706ed58ec5SVille Tervo 			break;
23716ed58ec5SVille Tervo 		case SCO_LINK:
23726ed58ec5SVille Tervo 		case ESCO_LINK:
23736ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
23746ed58ec5SVille Tervo 			break;
23756ed58ec5SVille Tervo 		case LE_LINK:
23766ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
23776ed58ec5SVille Tervo 			break;
23786ed58ec5SVille Tervo 		default:
23796ed58ec5SVille Tervo 			cnt = 0;
23806ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
23816ed58ec5SVille Tervo 		}
23826ed58ec5SVille Tervo 
23836ed58ec5SVille Tervo 		q = cnt / num;
23841da177e4SLinus Torvalds 		*quote = q ? q : 1;
23851da177e4SLinus Torvalds 	} else
23861da177e4SLinus Torvalds 		*quote = 0;
23871da177e4SLinus Torvalds 
23881da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
23891da177e4SLinus Torvalds 	return conn;
23901da177e4SLinus Torvalds }
23911da177e4SLinus Torvalds 
2392bae1f5d9SVille Tervo static inline void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
23931da177e4SLinus Torvalds {
23941da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
23951da177e4SLinus Torvalds 	struct hci_conn *c;
23961da177e4SLinus Torvalds 
2397bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
23981da177e4SLinus Torvalds 
2399bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2400bf4c6325SGustavo F. Padovan 
24011da177e4SLinus Torvalds 	/* Kill stalled connections */
2402bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2403bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
2404bae1f5d9SVille Tervo 			BT_ERR("%s killing stalled connection %s",
24051da177e4SLinus Torvalds 				hdev->name, batostr(&c->dst));
24061da177e4SLinus Torvalds 			hci_acl_disconn(c, 0x13);
24071da177e4SLinus Torvalds 		}
24081da177e4SLinus Torvalds 	}
2409bf4c6325SGustavo F. Padovan 
2410bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
24111da177e4SLinus Torvalds }
24121da177e4SLinus Torvalds 
241373d80debSLuiz Augusto von Dentz static inline struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
241473d80debSLuiz Augusto von Dentz 						int *quote)
241573d80debSLuiz Augusto von Dentz {
241673d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
241773d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
241873d80debSLuiz Augusto von Dentz 	int num = 0, min = ~0, cur_prio = 0;
241973d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
242073d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
242173d80debSLuiz Augusto von Dentz 
242273d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
242373d80debSLuiz Augusto von Dentz 
2424bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2425bf4c6325SGustavo F. Padovan 
2426bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
242773d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
242873d80debSLuiz Augusto von Dentz 
242973d80debSLuiz Augusto von Dentz 		if (conn->type != type)
243073d80debSLuiz Augusto von Dentz 			continue;
243173d80debSLuiz Augusto von Dentz 
243273d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
243373d80debSLuiz Augusto von Dentz 			continue;
243473d80debSLuiz Augusto von Dentz 
243573d80debSLuiz Augusto von Dentz 		conn_num++;
243673d80debSLuiz Augusto von Dentz 
24378192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
243873d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
243973d80debSLuiz Augusto von Dentz 
244073d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
244173d80debSLuiz Augusto von Dentz 				continue;
244273d80debSLuiz Augusto von Dentz 
244373d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
244473d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
244573d80debSLuiz Augusto von Dentz 				continue;
244673d80debSLuiz Augusto von Dentz 
244773d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
244873d80debSLuiz Augusto von Dentz 				num = 0;
244973d80debSLuiz Augusto von Dentz 				min = ~0;
245073d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
245173d80debSLuiz Augusto von Dentz 			}
245273d80debSLuiz Augusto von Dentz 
245373d80debSLuiz Augusto von Dentz 			num++;
245473d80debSLuiz Augusto von Dentz 
245573d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
245673d80debSLuiz Augusto von Dentz 				min  = conn->sent;
245773d80debSLuiz Augusto von Dentz 				chan = tmp;
245873d80debSLuiz Augusto von Dentz 			}
245973d80debSLuiz Augusto von Dentz 		}
246073d80debSLuiz Augusto von Dentz 
246173d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
246273d80debSLuiz Augusto von Dentz 			break;
246373d80debSLuiz Augusto von Dentz 	}
246473d80debSLuiz Augusto von Dentz 
2465bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2466bf4c6325SGustavo F. Padovan 
246773d80debSLuiz Augusto von Dentz 	if (!chan)
246873d80debSLuiz Augusto von Dentz 		return NULL;
246973d80debSLuiz Augusto von Dentz 
247073d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
247173d80debSLuiz Augusto von Dentz 	case ACL_LINK:
247273d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
247373d80debSLuiz Augusto von Dentz 		break;
247473d80debSLuiz Augusto von Dentz 	case SCO_LINK:
247573d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
247673d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
247773d80debSLuiz Augusto von Dentz 		break;
247873d80debSLuiz Augusto von Dentz 	case LE_LINK:
247973d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
248073d80debSLuiz Augusto von Dentz 		break;
248173d80debSLuiz Augusto von Dentz 	default:
248273d80debSLuiz Augusto von Dentz 		cnt = 0;
248373d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
248473d80debSLuiz Augusto von Dentz 	}
248573d80debSLuiz Augusto von Dentz 
248673d80debSLuiz Augusto von Dentz 	q = cnt / num;
248773d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
248873d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
248973d80debSLuiz Augusto von Dentz 	return chan;
249073d80debSLuiz Augusto von Dentz }
249173d80debSLuiz Augusto von Dentz 
249202b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
249302b20f0bSLuiz Augusto von Dentz {
249402b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
249502b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
249602b20f0bSLuiz Augusto von Dentz 	int num = 0;
249702b20f0bSLuiz Augusto von Dentz 
249802b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
249902b20f0bSLuiz Augusto von Dentz 
2500bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2501bf4c6325SGustavo F. Padovan 
2502bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
250302b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
250402b20f0bSLuiz Augusto von Dentz 
250502b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
250602b20f0bSLuiz Augusto von Dentz 			continue;
250702b20f0bSLuiz Augusto von Dentz 
250802b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
250902b20f0bSLuiz Augusto von Dentz 			continue;
251002b20f0bSLuiz Augusto von Dentz 
251102b20f0bSLuiz Augusto von Dentz 		num++;
251202b20f0bSLuiz Augusto von Dentz 
25138192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
251402b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
251502b20f0bSLuiz Augusto von Dentz 
251602b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
251702b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
251802b20f0bSLuiz Augusto von Dentz 				continue;
251902b20f0bSLuiz Augusto von Dentz 			}
252002b20f0bSLuiz Augusto von Dentz 
252102b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
252202b20f0bSLuiz Augusto von Dentz 				continue;
252302b20f0bSLuiz Augusto von Dentz 
252402b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
252502b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
252602b20f0bSLuiz Augusto von Dentz 				continue;
252702b20f0bSLuiz Augusto von Dentz 
252802b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
252902b20f0bSLuiz Augusto von Dentz 
253002b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
253102b20f0bSLuiz Augusto von Dentz 								skb->priority);
253202b20f0bSLuiz Augusto von Dentz 		}
253302b20f0bSLuiz Augusto von Dentz 
253402b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
253502b20f0bSLuiz Augusto von Dentz 			break;
253602b20f0bSLuiz Augusto von Dentz 	}
2537bf4c6325SGustavo F. Padovan 
2538bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2539bf4c6325SGustavo F. Padovan 
254002b20f0bSLuiz Augusto von Dentz }
254102b20f0bSLuiz Augusto von Dentz 
2542b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
2543b71d385aSAndrei Emeltchenko {
2544b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
2545b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
2546b71d385aSAndrei Emeltchenko }
2547b71d385aSAndrei Emeltchenko 
254863d2bc1bSAndrei Emeltchenko static inline void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
25491da177e4SLinus Torvalds {
25501da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
25511da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
25521da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
255363d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
2554cc48dc0aSAndrei Emeltchenko 					msecs_to_jiffies(HCI_ACL_TX_TIMEOUT)))
2555bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
25561da177e4SLinus Torvalds 	}
255763d2bc1bSAndrei Emeltchenko }
25581da177e4SLinus Torvalds 
255963d2bc1bSAndrei Emeltchenko static inline void hci_sched_acl_pkt(struct hci_dev *hdev)
256063d2bc1bSAndrei Emeltchenko {
256163d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
256263d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
256363d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
256463d2bc1bSAndrei Emeltchenko 	int quote;
256563d2bc1bSAndrei Emeltchenko 
256663d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
256704837f64SMarcel Holtmann 
256873d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
256973d80debSLuiz Augusto von Dentz 			(chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
2570ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
2571ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
257273d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
257373d80debSLuiz Augusto von Dentz 					skb->len, skb->priority);
257473d80debSLuiz Augusto von Dentz 
2575ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
2576ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
2577ec1cce24SLuiz Augusto von Dentz 				break;
2578ec1cce24SLuiz Augusto von Dentz 
2579ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
2580ec1cce24SLuiz Augusto von Dentz 
258173d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
258273d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
258304837f64SMarcel Holtmann 
25841da177e4SLinus Torvalds 			hci_send_frame(skb);
25851da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
25861da177e4SLinus Torvalds 
25871da177e4SLinus Torvalds 			hdev->acl_cnt--;
258873d80debSLuiz Augusto von Dentz 			chan->sent++;
258973d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
25901da177e4SLinus Torvalds 		}
25911da177e4SLinus Torvalds 	}
259202b20f0bSLuiz Augusto von Dentz 
259302b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
259402b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
25951da177e4SLinus Torvalds }
25961da177e4SLinus Torvalds 
2597b71d385aSAndrei Emeltchenko static inline void hci_sched_acl_blk(struct hci_dev *hdev)
2598b71d385aSAndrei Emeltchenko {
259963d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
2600b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
2601b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
2602b71d385aSAndrei Emeltchenko 	int quote;
2603b71d385aSAndrei Emeltchenko 
260463d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
2605b71d385aSAndrei Emeltchenko 
2606b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
2607b71d385aSAndrei Emeltchenko 			(chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
2608b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
2609b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
2610b71d385aSAndrei Emeltchenko 			int blocks;
2611b71d385aSAndrei Emeltchenko 
2612b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
2613b71d385aSAndrei Emeltchenko 						skb->len, skb->priority);
2614b71d385aSAndrei Emeltchenko 
2615b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
2616b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
2617b71d385aSAndrei Emeltchenko 				break;
2618b71d385aSAndrei Emeltchenko 
2619b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
2620b71d385aSAndrei Emeltchenko 
2621b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
2622b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
2623b71d385aSAndrei Emeltchenko 				return;
2624b71d385aSAndrei Emeltchenko 
2625b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
2626b71d385aSAndrei Emeltchenko 						bt_cb(skb)->force_active);
2627b71d385aSAndrei Emeltchenko 
2628b71d385aSAndrei Emeltchenko 			hci_send_frame(skb);
2629b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
2630b71d385aSAndrei Emeltchenko 
2631b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
2632b71d385aSAndrei Emeltchenko 			quote -= blocks;
2633b71d385aSAndrei Emeltchenko 
2634b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
2635b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
2636b71d385aSAndrei Emeltchenko 		}
2637b71d385aSAndrei Emeltchenko 	}
2638b71d385aSAndrei Emeltchenko 
2639b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
2640b71d385aSAndrei Emeltchenko 		hci_prio_recalculate(hdev, ACL_LINK);
2641b71d385aSAndrei Emeltchenko }
2642b71d385aSAndrei Emeltchenko 
2643b71d385aSAndrei Emeltchenko static inline void hci_sched_acl(struct hci_dev *hdev)
2644b71d385aSAndrei Emeltchenko {
2645b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
2646b71d385aSAndrei Emeltchenko 
2647b71d385aSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK))
2648b71d385aSAndrei Emeltchenko 		return;
2649b71d385aSAndrei Emeltchenko 
2650b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
2651b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
2652b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
2653b71d385aSAndrei Emeltchenko 		break;
2654b71d385aSAndrei Emeltchenko 
2655b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
2656b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
2657b71d385aSAndrei Emeltchenko 		break;
2658b71d385aSAndrei Emeltchenko 	}
2659b71d385aSAndrei Emeltchenko }
2660b71d385aSAndrei Emeltchenko 
26611da177e4SLinus Torvalds /* Schedule SCO */
26621da177e4SLinus Torvalds static inline void hci_sched_sco(struct hci_dev *hdev)
26631da177e4SLinus Torvalds {
26641da177e4SLinus Torvalds 	struct hci_conn *conn;
26651da177e4SLinus Torvalds 	struct sk_buff *skb;
26661da177e4SLinus Torvalds 	int quote;
26671da177e4SLinus Torvalds 
26681da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
26691da177e4SLinus Torvalds 
267052087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
267152087a79SLuiz Augusto von Dentz 		return;
267252087a79SLuiz Augusto von Dentz 
26731da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
26741da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
26751da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
26761da177e4SLinus Torvalds 			hci_send_frame(skb);
26771da177e4SLinus Torvalds 
26781da177e4SLinus Torvalds 			conn->sent++;
26791da177e4SLinus Torvalds 			if (conn->sent == ~0)
26801da177e4SLinus Torvalds 				conn->sent = 0;
26811da177e4SLinus Torvalds 		}
26821da177e4SLinus Torvalds 	}
26831da177e4SLinus Torvalds }
26841da177e4SLinus Torvalds 
2685b6a0dc82SMarcel Holtmann static inline void hci_sched_esco(struct hci_dev *hdev)
2686b6a0dc82SMarcel Holtmann {
2687b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
2688b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
2689b6a0dc82SMarcel Holtmann 	int quote;
2690b6a0dc82SMarcel Holtmann 
2691b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
2692b6a0dc82SMarcel Holtmann 
269352087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
269452087a79SLuiz Augusto von Dentz 		return;
269552087a79SLuiz Augusto von Dentz 
2696b6a0dc82SMarcel Holtmann 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, &quote))) {
2697b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
2698b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
2699b6a0dc82SMarcel Holtmann 			hci_send_frame(skb);
2700b6a0dc82SMarcel Holtmann 
2701b6a0dc82SMarcel Holtmann 			conn->sent++;
2702b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
2703b6a0dc82SMarcel Holtmann 				conn->sent = 0;
2704b6a0dc82SMarcel Holtmann 		}
2705b6a0dc82SMarcel Holtmann 	}
2706b6a0dc82SMarcel Holtmann }
2707b6a0dc82SMarcel Holtmann 
27086ed58ec5SVille Tervo static inline void hci_sched_le(struct hci_dev *hdev)
27096ed58ec5SVille Tervo {
271073d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
27116ed58ec5SVille Tervo 	struct sk_buff *skb;
271202b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
27136ed58ec5SVille Tervo 
27146ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
27156ed58ec5SVille Tervo 
271652087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
271752087a79SLuiz Augusto von Dentz 		return;
271852087a79SLuiz Augusto von Dentz 
27196ed58ec5SVille Tervo 	if (!test_bit(HCI_RAW, &hdev->flags)) {
27206ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
27216ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
2722bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
27236ed58ec5SVille Tervo 				time_after(jiffies, hdev->le_last_tx + HZ * 45))
2724bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
27256ed58ec5SVille Tervo 	}
27266ed58ec5SVille Tervo 
27276ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
272802b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
272973d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
2730ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
2731ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
273273d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
273373d80debSLuiz Augusto von Dentz 					skb->len, skb->priority);
27346ed58ec5SVille Tervo 
2735ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
2736ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
2737ec1cce24SLuiz Augusto von Dentz 				break;
2738ec1cce24SLuiz Augusto von Dentz 
2739ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
2740ec1cce24SLuiz Augusto von Dentz 
27416ed58ec5SVille Tervo 			hci_send_frame(skb);
27426ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
27436ed58ec5SVille Tervo 
27446ed58ec5SVille Tervo 			cnt--;
274573d80debSLuiz Augusto von Dentz 			chan->sent++;
274673d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
27476ed58ec5SVille Tervo 		}
27486ed58ec5SVille Tervo 	}
274973d80debSLuiz Augusto von Dentz 
27506ed58ec5SVille Tervo 	if (hdev->le_pkts)
27516ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
27526ed58ec5SVille Tervo 	else
27536ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
275402b20f0bSLuiz Augusto von Dentz 
275502b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
275602b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
27576ed58ec5SVille Tervo }
27586ed58ec5SVille Tervo 
27593eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
27601da177e4SLinus Torvalds {
27613eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
27621da177e4SLinus Torvalds 	struct sk_buff *skb;
27631da177e4SLinus Torvalds 
27646ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
27656ed58ec5SVille Tervo 		hdev->sco_cnt, hdev->le_cnt);
27661da177e4SLinus Torvalds 
27671da177e4SLinus Torvalds 	/* Schedule queues and send stuff to HCI driver */
27681da177e4SLinus Torvalds 
27691da177e4SLinus Torvalds 	hci_sched_acl(hdev);
27701da177e4SLinus Torvalds 
27711da177e4SLinus Torvalds 	hci_sched_sco(hdev);
27721da177e4SLinus Torvalds 
2773b6a0dc82SMarcel Holtmann 	hci_sched_esco(hdev);
2774b6a0dc82SMarcel Holtmann 
27756ed58ec5SVille Tervo 	hci_sched_le(hdev);
27766ed58ec5SVille Tervo 
27771da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
27781da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
27791da177e4SLinus Torvalds 		hci_send_frame(skb);
27801da177e4SLinus Torvalds }
27811da177e4SLinus Torvalds 
278225985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
27831da177e4SLinus Torvalds 
27841da177e4SLinus Torvalds /* ACL data packet */
27851da177e4SLinus Torvalds static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
27861da177e4SLinus Torvalds {
27871da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
27881da177e4SLinus Torvalds 	struct hci_conn *conn;
27891da177e4SLinus Torvalds 	__u16 handle, flags;
27901da177e4SLinus Torvalds 
27911da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
27921da177e4SLinus Torvalds 
27931da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
27941da177e4SLinus Torvalds 	flags  = hci_flags(handle);
27951da177e4SLinus Torvalds 	handle = hci_handle(handle);
27961da177e4SLinus Torvalds 
27971da177e4SLinus Torvalds 	BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags);
27981da177e4SLinus Torvalds 
27991da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
28001da177e4SLinus Torvalds 
28011da177e4SLinus Torvalds 	hci_dev_lock(hdev);
28021da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
28031da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
28041da177e4SLinus Torvalds 
28051da177e4SLinus Torvalds 	if (conn) {
280665983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
280704837f64SMarcel Holtmann 
28081da177e4SLinus Torvalds 		/* Send to upper protocol */
2809686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
28101da177e4SLinus Torvalds 		return;
28111da177e4SLinus Torvalds 	} else {
28121da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
28131da177e4SLinus Torvalds 			hdev->name, handle);
28141da177e4SLinus Torvalds 	}
28151da177e4SLinus Torvalds 
28161da177e4SLinus Torvalds 	kfree_skb(skb);
28171da177e4SLinus Torvalds }
28181da177e4SLinus Torvalds 
28191da177e4SLinus Torvalds /* SCO data packet */
28201da177e4SLinus Torvalds static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
28211da177e4SLinus Torvalds {
28221da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
28231da177e4SLinus Torvalds 	struct hci_conn *conn;
28241da177e4SLinus Torvalds 	__u16 handle;
28251da177e4SLinus Torvalds 
28261da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
28271da177e4SLinus Torvalds 
28281da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
28291da177e4SLinus Torvalds 
28301da177e4SLinus Torvalds 	BT_DBG("%s len %d handle 0x%x", hdev->name, skb->len, handle);
28311da177e4SLinus Torvalds 
28321da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
28331da177e4SLinus Torvalds 
28341da177e4SLinus Torvalds 	hci_dev_lock(hdev);
28351da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
28361da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
28371da177e4SLinus Torvalds 
28381da177e4SLinus Torvalds 	if (conn) {
28391da177e4SLinus Torvalds 		/* Send to upper protocol */
2840686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
28411da177e4SLinus Torvalds 		return;
28421da177e4SLinus Torvalds 	} else {
28431da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
28441da177e4SLinus Torvalds 			hdev->name, handle);
28451da177e4SLinus Torvalds 	}
28461da177e4SLinus Torvalds 
28471da177e4SLinus Torvalds 	kfree_skb(skb);
28481da177e4SLinus Torvalds }
28491da177e4SLinus Torvalds 
2850b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
28511da177e4SLinus Torvalds {
2852b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
28531da177e4SLinus Torvalds 	struct sk_buff *skb;
28541da177e4SLinus Torvalds 
28551da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
28561da177e4SLinus Torvalds 
28571da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
2858cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
2859cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
2860cd82e61cSMarcel Holtmann 
28611da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
28621da177e4SLinus Torvalds 			/* Send copy to the sockets */
2863470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
28641da177e4SLinus Torvalds 		}
28651da177e4SLinus Torvalds 
28661da177e4SLinus Torvalds 		if (test_bit(HCI_RAW, &hdev->flags)) {
28671da177e4SLinus Torvalds 			kfree_skb(skb);
28681da177e4SLinus Torvalds 			continue;
28691da177e4SLinus Torvalds 		}
28701da177e4SLinus Torvalds 
28711da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
28721da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
28730d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
28741da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
28751da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
28761da177e4SLinus Torvalds 				kfree_skb(skb);
28771da177e4SLinus Torvalds 				continue;
28783ff50b79SStephen Hemminger 			}
28791da177e4SLinus Torvalds 		}
28801da177e4SLinus Torvalds 
28811da177e4SLinus Torvalds 		/* Process frame */
28820d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
28831da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
2884b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
28851da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
28861da177e4SLinus Torvalds 			break;
28871da177e4SLinus Torvalds 
28881da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
28891da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
28901da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
28911da177e4SLinus Torvalds 			break;
28921da177e4SLinus Torvalds 
28931da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
28941da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
28951da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
28961da177e4SLinus Torvalds 			break;
28971da177e4SLinus Torvalds 
28981da177e4SLinus Torvalds 		default:
28991da177e4SLinus Torvalds 			kfree_skb(skb);
29001da177e4SLinus Torvalds 			break;
29011da177e4SLinus Torvalds 		}
29021da177e4SLinus Torvalds 	}
29031da177e4SLinus Torvalds }
29041da177e4SLinus Torvalds 
2905c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
29061da177e4SLinus Torvalds {
2907c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
29081da177e4SLinus Torvalds 	struct sk_buff *skb;
29091da177e4SLinus Torvalds 
29101da177e4SLinus Torvalds 	BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
29111da177e4SLinus Torvalds 
29121da177e4SLinus Torvalds 	/* Send queued commands */
29135a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
29145a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
29155a08ecceSAndrei Emeltchenko 		if (!skb)
29165a08ecceSAndrei Emeltchenko 			return;
29175a08ecceSAndrei Emeltchenko 
29181da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
29191da177e4SLinus Torvalds 
292070f23020SAndrei Emeltchenko 		hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC);
292170f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
29221da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
29231da177e4SLinus Torvalds 			hci_send_frame(skb);
29247bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
29257bdb8a5cSSzymon Janc 				del_timer(&hdev->cmd_timer);
29267bdb8a5cSSzymon Janc 			else
29276bd32326SVille Tervo 				mod_timer(&hdev->cmd_timer,
29286bd32326SVille Tervo 				  jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT));
29291da177e4SLinus Torvalds 		} else {
29301da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
2931c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
29321da177e4SLinus Torvalds 		}
29331da177e4SLinus Torvalds 	}
29341da177e4SLinus Torvalds }
29352519a1fcSAndre Guedes 
29362519a1fcSAndre Guedes int hci_do_inquiry(struct hci_dev *hdev, u8 length)
29372519a1fcSAndre Guedes {
29382519a1fcSAndre Guedes 	/* General inquiry access code (GIAC) */
29392519a1fcSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
29402519a1fcSAndre Guedes 	struct hci_cp_inquiry cp;
29412519a1fcSAndre Guedes 
29422519a1fcSAndre Guedes 	BT_DBG("%s", hdev->name);
29432519a1fcSAndre Guedes 
29442519a1fcSAndre Guedes 	if (test_bit(HCI_INQUIRY, &hdev->flags))
29452519a1fcSAndre Guedes 		return -EINPROGRESS;
29462519a1fcSAndre Guedes 
29474663262cSJohan Hedberg 	inquiry_cache_flush(hdev);
29484663262cSJohan Hedberg 
29492519a1fcSAndre Guedes 	memset(&cp, 0, sizeof(cp));
29502519a1fcSAndre Guedes 	memcpy(&cp.lap, lap, sizeof(cp.lap));
29512519a1fcSAndre Guedes 	cp.length  = length;
29522519a1fcSAndre Guedes 
29532519a1fcSAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
29542519a1fcSAndre Guedes }
2955023d5049SAndre Guedes 
2956023d5049SAndre Guedes int hci_cancel_inquiry(struct hci_dev *hdev)
2957023d5049SAndre Guedes {
2958023d5049SAndre Guedes 	BT_DBG("%s", hdev->name);
2959023d5049SAndre Guedes 
2960023d5049SAndre Guedes 	if (!test_bit(HCI_INQUIRY, &hdev->flags))
29617537e5c3SAndre Guedes 		return -EALREADY;
2962023d5049SAndre Guedes 
2963023d5049SAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL);
2964023d5049SAndre Guedes }
2965