xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 04124681)
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 
481da177e4SLinus Torvalds #include <asm/system.h>
4970f23020SAndrei Emeltchenko #include <linux/uaccess.h>
501da177e4SLinus Torvalds #include <asm/unaligned.h>
511da177e4SLinus Torvalds 
521da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
531da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
541da177e4SLinus Torvalds 
55ab81cbf9SJohan Hedberg #define AUTO_OFF_TIMEOUT 2000
56ab81cbf9SJohan Hedberg 
57b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work);
58c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work);
593eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work);
601da177e4SLinus Torvalds 
611da177e4SLinus Torvalds /* HCI device list */
621da177e4SLinus Torvalds LIST_HEAD(hci_dev_list);
631da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock);
641da177e4SLinus Torvalds 
651da177e4SLinus Torvalds /* HCI callback list */
661da177e4SLinus Torvalds LIST_HEAD(hci_cb_list);
671da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock);
681da177e4SLinus Torvalds 
691da177e4SLinus Torvalds /* ---- HCI notifications ---- */
701da177e4SLinus Torvalds 
716516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event)
721da177e4SLinus Torvalds {
73040030efSMarcel Holtmann 	hci_sock_dev_event(hdev, event);
741da177e4SLinus Torvalds }
751da177e4SLinus Torvalds 
761da177e4SLinus Torvalds /* ---- HCI requests ---- */
771da177e4SLinus Torvalds 
7823bb5763SJohan Hedberg void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result)
791da177e4SLinus Torvalds {
8023bb5763SJohan Hedberg 	BT_DBG("%s command 0x%04x result 0x%2.2x", hdev->name, cmd, result);
8123bb5763SJohan Hedberg 
82a5040efaSJohan Hedberg 	/* If this is the init phase check if the completed command matches
83a5040efaSJohan Hedberg 	 * the last init command, and if not just return.
84a5040efaSJohan Hedberg 	 */
8575fb0e32SJohan Hedberg 	if (test_bit(HCI_INIT, &hdev->flags) && hdev->init_last_cmd != cmd) {
8675fb0e32SJohan Hedberg 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
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 
9675fb0e32SJohan Hedberg 		if (cmd != HCI_OP_RESET || sent->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);
255e61ef499SAndrei Emeltchenko }
256e61ef499SAndrei Emeltchenko 
257e61ef499SAndrei Emeltchenko static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
258e61ef499SAndrei Emeltchenko {
259e61ef499SAndrei Emeltchenko 	struct sk_buff *skb;
260e61ef499SAndrei Emeltchenko 
261e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
262e61ef499SAndrei Emeltchenko 
263e61ef499SAndrei Emeltchenko 	/* Driver initialization */
264e61ef499SAndrei Emeltchenko 
265e61ef499SAndrei Emeltchenko 	/* Special commands */
266e61ef499SAndrei Emeltchenko 	while ((skb = skb_dequeue(&hdev->driver_init))) {
267e61ef499SAndrei Emeltchenko 		bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
268e61ef499SAndrei Emeltchenko 		skb->dev = (void *) hdev;
269e61ef499SAndrei Emeltchenko 
270e61ef499SAndrei Emeltchenko 		skb_queue_tail(&hdev->cmd_q, skb);
271e61ef499SAndrei Emeltchenko 		queue_work(hdev->workqueue, &hdev->cmd_work);
272e61ef499SAndrei Emeltchenko 	}
273e61ef499SAndrei Emeltchenko 	skb_queue_purge(&hdev->driver_init);
274e61ef499SAndrei Emeltchenko 
275e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
276e61ef499SAndrei Emeltchenko 	case HCI_BREDR:
277e61ef499SAndrei Emeltchenko 		bredr_init(hdev);
278e61ef499SAndrei Emeltchenko 		break;
279e61ef499SAndrei Emeltchenko 
280e61ef499SAndrei Emeltchenko 	case HCI_AMP:
281e61ef499SAndrei Emeltchenko 		amp_init(hdev);
282e61ef499SAndrei Emeltchenko 		break;
283e61ef499SAndrei Emeltchenko 
284e61ef499SAndrei Emeltchenko 	default:
285e61ef499SAndrei Emeltchenko 		BT_ERR("Unknown device type %d", hdev->dev_type);
286e61ef499SAndrei Emeltchenko 		break;
287e61ef499SAndrei Emeltchenko 	}
288e61ef499SAndrei Emeltchenko 
289e61ef499SAndrei Emeltchenko }
290e61ef499SAndrei Emeltchenko 
2916ed58ec5SVille Tervo static void hci_le_init_req(struct hci_dev *hdev, unsigned long opt)
2926ed58ec5SVille Tervo {
2936ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
2946ed58ec5SVille Tervo 
2956ed58ec5SVille Tervo 	/* Read LE buffer size */
2966ed58ec5SVille Tervo 	hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
2976ed58ec5SVille Tervo }
2986ed58ec5SVille Tervo 
2991da177e4SLinus Torvalds static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
3001da177e4SLinus Torvalds {
3011da177e4SLinus Torvalds 	__u8 scan = opt;
3021da177e4SLinus Torvalds 
3031da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, scan);
3041da177e4SLinus Torvalds 
3051da177e4SLinus Torvalds 	/* Inquiry and Page scans */
306a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
3071da177e4SLinus Torvalds }
3081da177e4SLinus Torvalds 
3091da177e4SLinus Torvalds static void hci_auth_req(struct hci_dev *hdev, unsigned long opt)
3101da177e4SLinus Torvalds {
3111da177e4SLinus Torvalds 	__u8 auth = opt;
3121da177e4SLinus Torvalds 
3131da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, auth);
3141da177e4SLinus Torvalds 
3151da177e4SLinus Torvalds 	/* Authentication */
316a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
3171da177e4SLinus Torvalds }
3181da177e4SLinus Torvalds 
3191da177e4SLinus Torvalds static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt)
3201da177e4SLinus Torvalds {
3211da177e4SLinus Torvalds 	__u8 encrypt = opt;
3221da177e4SLinus Torvalds 
3231da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, encrypt);
3241da177e4SLinus Torvalds 
325e4e8e37cSMarcel Holtmann 	/* Encryption */
326a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
3271da177e4SLinus Torvalds }
3281da177e4SLinus Torvalds 
329e4e8e37cSMarcel Holtmann static void hci_linkpol_req(struct hci_dev *hdev, unsigned long opt)
330e4e8e37cSMarcel Holtmann {
331e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
332e4e8e37cSMarcel Holtmann 
333a418b893SMarcel Holtmann 	BT_DBG("%s %x", hdev->name, policy);
334e4e8e37cSMarcel Holtmann 
335e4e8e37cSMarcel Holtmann 	/* Default link policy */
336e4e8e37cSMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
337e4e8e37cSMarcel Holtmann }
338e4e8e37cSMarcel Holtmann 
3391da177e4SLinus Torvalds /* Get HCI device by index.
3401da177e4SLinus Torvalds  * Device is held on return. */
3411da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
3421da177e4SLinus Torvalds {
3438035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
3441da177e4SLinus Torvalds 
3451da177e4SLinus Torvalds 	BT_DBG("%d", index);
3461da177e4SLinus Torvalds 
3471da177e4SLinus Torvalds 	if (index < 0)
3481da177e4SLinus Torvalds 		return NULL;
3491da177e4SLinus Torvalds 
3501da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
3518035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
3521da177e4SLinus Torvalds 		if (d->id == index) {
3531da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
3541da177e4SLinus Torvalds 			break;
3551da177e4SLinus Torvalds 		}
3561da177e4SLinus Torvalds 	}
3571da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
3581da177e4SLinus Torvalds 	return hdev;
3591da177e4SLinus Torvalds }
3601da177e4SLinus Torvalds 
3611da177e4SLinus Torvalds /* ---- Inquiry support ---- */
362ff9ef578SJohan Hedberg 
36330dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
36430dc78e1SJohan Hedberg {
36530dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
36630dc78e1SJohan Hedberg 
3676fbe195dSAndre Guedes 	switch (discov->state) {
368343f935bSAndre Guedes 	case DISCOVERY_FINDING:
3696fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
37030dc78e1SJohan Hedberg 		return true;
37130dc78e1SJohan Hedberg 
3726fbe195dSAndre Guedes 	default:
37330dc78e1SJohan Hedberg 		return false;
37430dc78e1SJohan Hedberg 	}
3756fbe195dSAndre Guedes }
37630dc78e1SJohan Hedberg 
377ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
378ff9ef578SJohan Hedberg {
379ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
380ff9ef578SJohan Hedberg 
381ff9ef578SJohan Hedberg 	if (hdev->discovery.state == state)
382ff9ef578SJohan Hedberg 		return;
383ff9ef578SJohan Hedberg 
384ff9ef578SJohan Hedberg 	switch (state) {
385ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
3867b99b659SAndre Guedes 		if (hdev->discovery.state != DISCOVERY_STARTING)
387ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
388f963e8e9SJohan Hedberg 		hdev->discovery.type = 0;
389ff9ef578SJohan Hedberg 		break;
390ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
391ff9ef578SJohan Hedberg 		break;
392343f935bSAndre Guedes 	case DISCOVERY_FINDING:
393ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
394ff9ef578SJohan Hedberg 		break;
39530dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
39630dc78e1SJohan Hedberg 		break;
397ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
398ff9ef578SJohan Hedberg 		break;
399ff9ef578SJohan Hedberg 	}
400ff9ef578SJohan Hedberg 
401ff9ef578SJohan Hedberg 	hdev->discovery.state = state;
402ff9ef578SJohan Hedberg }
403ff9ef578SJohan Hedberg 
4041da177e4SLinus Torvalds static void inquiry_cache_flush(struct hci_dev *hdev)
4051da177e4SLinus Torvalds {
40630883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
407b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
4081da177e4SLinus Torvalds 
409561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
410561aafbcSJohan Hedberg 		list_del(&p->all);
411b57c1a56SJohan Hedberg 		kfree(p);
4121da177e4SLinus Torvalds 	}
413561aafbcSJohan Hedberg 
414561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
415561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
4161da177e4SLinus Torvalds }
4171da177e4SLinus Torvalds 
4181da177e4SLinus Torvalds struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
4191da177e4SLinus Torvalds {
42030883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
4211da177e4SLinus Torvalds 	struct inquiry_entry *e;
4221da177e4SLinus Torvalds 
4231da177e4SLinus Torvalds 	BT_DBG("cache %p, %s", cache, batostr(bdaddr));
4241da177e4SLinus Torvalds 
425561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
4261da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
4271da177e4SLinus Torvalds 			return e;
4281da177e4SLinus Torvalds 	}
4291da177e4SLinus Torvalds 
430b57c1a56SJohan Hedberg 	return NULL;
431b57c1a56SJohan Hedberg }
432b57c1a56SJohan Hedberg 
433561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
434561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
435561aafbcSJohan Hedberg {
43630883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
437561aafbcSJohan Hedberg 	struct inquiry_entry *e;
438561aafbcSJohan Hedberg 
439561aafbcSJohan Hedberg 	BT_DBG("cache %p, %s", cache, batostr(bdaddr));
440561aafbcSJohan Hedberg 
441561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
442561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
443561aafbcSJohan Hedberg 			return e;
444561aafbcSJohan Hedberg 	}
445561aafbcSJohan Hedberg 
446561aafbcSJohan Hedberg 	return NULL;
447561aafbcSJohan Hedberg }
448561aafbcSJohan Hedberg 
44930dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
45030dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
45130dc78e1SJohan Hedberg 						       int state)
45230dc78e1SJohan Hedberg {
45330dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
45430dc78e1SJohan Hedberg 	struct inquiry_entry *e;
45530dc78e1SJohan Hedberg 
45630dc78e1SJohan Hedberg 	BT_DBG("cache %p bdaddr %s state %d", cache, batostr(bdaddr), state);
45730dc78e1SJohan Hedberg 
45830dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
45930dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
46030dc78e1SJohan Hedberg 			return e;
46130dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
46230dc78e1SJohan Hedberg 			return e;
46330dc78e1SJohan Hedberg 	}
46430dc78e1SJohan Hedberg 
46530dc78e1SJohan Hedberg 	return NULL;
46630dc78e1SJohan Hedberg }
46730dc78e1SJohan Hedberg 
468a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
469a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
470a3d4e20aSJohan Hedberg {
471a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
472a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
473a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
474a3d4e20aSJohan Hedberg 
475a3d4e20aSJohan Hedberg 	list_del(&ie->list);
476a3d4e20aSJohan Hedberg 
477a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
478a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
479a3d4e20aSJohan Hedberg 				abs(p->data.rssi) >= abs(ie->data.rssi))
480a3d4e20aSJohan Hedberg 			break;
481a3d4e20aSJohan Hedberg 		pos = &p->list;
482a3d4e20aSJohan Hedberg 	}
483a3d4e20aSJohan Hedberg 
484a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
485a3d4e20aSJohan Hedberg }
486a3d4e20aSJohan Hedberg 
4873175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
488388fc8faSJohan Hedberg 			      bool name_known, bool *ssp)
4891da177e4SLinus Torvalds {
49030883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
49170f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
4921da177e4SLinus Torvalds 
4931da177e4SLinus Torvalds 	BT_DBG("cache %p, %s", cache, batostr(&data->bdaddr));
4941da177e4SLinus Torvalds 
495388fc8faSJohan Hedberg 	if (ssp)
496388fc8faSJohan Hedberg 		*ssp = data->ssp_mode;
497388fc8faSJohan Hedberg 
49870f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
499a3d4e20aSJohan Hedberg 	if (ie) {
500388fc8faSJohan Hedberg 		if (ie->data.ssp_mode && ssp)
501388fc8faSJohan Hedberg 			*ssp = true;
502388fc8faSJohan Hedberg 
503a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
504a3d4e20aSJohan Hedberg 						data->rssi != ie->data.rssi) {
505a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
506a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
507a3d4e20aSJohan Hedberg 		}
508a3d4e20aSJohan Hedberg 
509561aafbcSJohan Hedberg 		goto update;
510a3d4e20aSJohan Hedberg 	}
511561aafbcSJohan Hedberg 
5121da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
51370f23020SAndrei Emeltchenko 	ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
51470f23020SAndrei Emeltchenko 	if (!ie)
5153175405bSJohan Hedberg 		return false;
51670f23020SAndrei Emeltchenko 
517561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
518561aafbcSJohan Hedberg 
519561aafbcSJohan Hedberg 	if (name_known) {
520561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
521561aafbcSJohan Hedberg 	} else {
522561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
523561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
524561aafbcSJohan Hedberg 	}
525561aafbcSJohan Hedberg 
526561aafbcSJohan Hedberg update:
527561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
528561aafbcSJohan Hedberg 					ie->name_state != NAME_PENDING) {
529561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
530561aafbcSJohan Hedberg 		list_del(&ie->list);
5311da177e4SLinus Torvalds 	}
5321da177e4SLinus Torvalds 
53370f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
53470f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
5351da177e4SLinus Torvalds 	cache->timestamp = jiffies;
5363175405bSJohan Hedberg 
5373175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
5383175405bSJohan Hedberg 		return false;
5393175405bSJohan Hedberg 
5403175405bSJohan Hedberg 	return true;
5411da177e4SLinus Torvalds }
5421da177e4SLinus Torvalds 
5431da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
5441da177e4SLinus Torvalds {
54530883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
5461da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
5471da177e4SLinus Torvalds 	struct inquiry_entry *e;
5481da177e4SLinus Torvalds 	int copied = 0;
5491da177e4SLinus Torvalds 
550561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
5511da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
552b57c1a56SJohan Hedberg 
553b57c1a56SJohan Hedberg 		if (copied >= num)
554b57c1a56SJohan Hedberg 			break;
555b57c1a56SJohan Hedberg 
5561da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
5571da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
5581da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
5591da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
5601da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
5611da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
562b57c1a56SJohan Hedberg 
5631da177e4SLinus Torvalds 		info++;
564b57c1a56SJohan Hedberg 		copied++;
5651da177e4SLinus Torvalds 	}
5661da177e4SLinus Torvalds 
5671da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
5681da177e4SLinus Torvalds 	return copied;
5691da177e4SLinus Torvalds }
5701da177e4SLinus Torvalds 
5711da177e4SLinus Torvalds static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
5721da177e4SLinus Torvalds {
5731da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
5741da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
5751da177e4SLinus Torvalds 
5761da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
5771da177e4SLinus Torvalds 
5781da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
5791da177e4SLinus Torvalds 		return;
5801da177e4SLinus Torvalds 
5811da177e4SLinus Torvalds 	/* Start Inquiry */
5821da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
5831da177e4SLinus Torvalds 	cp.length  = ir->length;
5841da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
585a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
5861da177e4SLinus Torvalds }
5871da177e4SLinus Torvalds 
5881da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
5891da177e4SLinus Torvalds {
5901da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
5911da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
5921da177e4SLinus Torvalds 	struct hci_dev *hdev;
5931da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
5941da177e4SLinus Torvalds 	long timeo;
5951da177e4SLinus Torvalds 	__u8 *buf;
5961da177e4SLinus Torvalds 
5971da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
5981da177e4SLinus Torvalds 		return -EFAULT;
5991da177e4SLinus Torvalds 
6005a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
6015a08ecceSAndrei Emeltchenko 	if (!hdev)
6021da177e4SLinus Torvalds 		return -ENODEV;
6031da177e4SLinus Torvalds 
60409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
6051da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
6061da177e4SLinus Torvalds 				inquiry_cache_empty(hdev) ||
6071da177e4SLinus Torvalds 				ir.flags & IREQ_CACHE_FLUSH) {
6081da177e4SLinus Torvalds 		inquiry_cache_flush(hdev);
6091da177e4SLinus Torvalds 		do_inquiry = 1;
6101da177e4SLinus Torvalds 	}
61109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
6121da177e4SLinus Torvalds 
61304837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
61470f23020SAndrei Emeltchenko 
61570f23020SAndrei Emeltchenko 	if (do_inquiry) {
61670f23020SAndrei Emeltchenko 		err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo);
61770f23020SAndrei Emeltchenko 		if (err < 0)
6181da177e4SLinus Torvalds 			goto done;
61970f23020SAndrei Emeltchenko 	}
6201da177e4SLinus Torvalds 
6211da177e4SLinus Torvalds 	/* for unlimited number of responses we will use buffer with 255 entries */
6221da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
6231da177e4SLinus Torvalds 
6241da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
6251da177e4SLinus Torvalds 	 * copy it to the user space.
6261da177e4SLinus Torvalds 	 */
62770f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
62870f23020SAndrei Emeltchenko 	if (!buf) {
6291da177e4SLinus Torvalds 		err = -ENOMEM;
6301da177e4SLinus Torvalds 		goto done;
6311da177e4SLinus Torvalds 	}
6321da177e4SLinus Torvalds 
63309fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
6341da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
63509fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
6361da177e4SLinus Torvalds 
6371da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
6381da177e4SLinus Torvalds 
6391da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
6401da177e4SLinus Torvalds 		ptr += sizeof(ir);
6411da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
6421da177e4SLinus Torvalds 					ir.num_rsp))
6431da177e4SLinus Torvalds 			err = -EFAULT;
6441da177e4SLinus Torvalds 	} else
6451da177e4SLinus Torvalds 		err = -EFAULT;
6461da177e4SLinus Torvalds 
6471da177e4SLinus Torvalds 	kfree(buf);
6481da177e4SLinus Torvalds 
6491da177e4SLinus Torvalds done:
6501da177e4SLinus Torvalds 	hci_dev_put(hdev);
6511da177e4SLinus Torvalds 	return err;
6521da177e4SLinus Torvalds }
6531da177e4SLinus Torvalds 
6541da177e4SLinus Torvalds /* ---- HCI ioctl helpers ---- */
6551da177e4SLinus Torvalds 
6561da177e4SLinus Torvalds int hci_dev_open(__u16 dev)
6571da177e4SLinus Torvalds {
6581da177e4SLinus Torvalds 	struct hci_dev *hdev;
6591da177e4SLinus Torvalds 	int ret = 0;
6601da177e4SLinus Torvalds 
6615a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(dev);
6625a08ecceSAndrei Emeltchenko 	if (!hdev)
6631da177e4SLinus Torvalds 		return -ENODEV;
6641da177e4SLinus Torvalds 
6651da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
6661da177e4SLinus Torvalds 
6671da177e4SLinus Torvalds 	hci_req_lock(hdev);
6681da177e4SLinus Torvalds 
669611b30f7SMarcel Holtmann 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) {
670611b30f7SMarcel Holtmann 		ret = -ERFKILL;
671611b30f7SMarcel Holtmann 		goto done;
672611b30f7SMarcel Holtmann 	}
673611b30f7SMarcel Holtmann 
6741da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
6751da177e4SLinus Torvalds 		ret = -EALREADY;
6761da177e4SLinus Torvalds 		goto done;
6771da177e4SLinus Torvalds 	}
6781da177e4SLinus Torvalds 
6791da177e4SLinus Torvalds 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
6801da177e4SLinus Torvalds 		set_bit(HCI_RAW, &hdev->flags);
6811da177e4SLinus Torvalds 
68207e3b94aSAndrei Emeltchenko 	/* Treat all non BR/EDR controllers as raw devices if
68307e3b94aSAndrei Emeltchenko 	   enable_hs is not set */
68407e3b94aSAndrei Emeltchenko 	if (hdev->dev_type != HCI_BREDR && !enable_hs)
685943da25dSMarcel Holtmann 		set_bit(HCI_RAW, &hdev->flags);
686943da25dSMarcel Holtmann 
6871da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
6881da177e4SLinus Torvalds 		ret = -EIO;
6891da177e4SLinus Torvalds 		goto done;
6901da177e4SLinus Torvalds 	}
6911da177e4SLinus Torvalds 
6921da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
6931da177e4SLinus Torvalds 		atomic_set(&hdev->cmd_cnt, 1);
6941da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
695a5040efaSJohan Hedberg 		hdev->init_last_cmd = 0;
6961da177e4SLinus Torvalds 
69704837f64SMarcel Holtmann 		ret = __hci_request(hdev, hci_init_req, 0,
69804837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
6991da177e4SLinus Torvalds 
700eead27daSAndre Guedes 		if (lmp_host_le_capable(hdev))
7016ed58ec5SVille Tervo 			ret = __hci_request(hdev, hci_le_init_req, 0,
7026ed58ec5SVille Tervo 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
7036ed58ec5SVille Tervo 
7041da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
7051da177e4SLinus Torvalds 	}
7061da177e4SLinus Torvalds 
7071da177e4SLinus Torvalds 	if (!ret) {
7081da177e4SLinus Torvalds 		hci_dev_hold(hdev);
7091da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
7101da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
711a8b2d5c2SJohan Hedberg 		if (!test_bit(HCI_SETUP, &hdev->dev_flags)) {
71209fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
713744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
71409fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
71556e5cb86SJohan Hedberg 		}
7161da177e4SLinus Torvalds 	} else {
7171da177e4SLinus Torvalds 		/* Init failed, cleanup */
7183eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
719c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
720b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
7211da177e4SLinus Torvalds 
7221da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
7231da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
7241da177e4SLinus Torvalds 
7251da177e4SLinus Torvalds 		if (hdev->flush)
7261da177e4SLinus Torvalds 			hdev->flush(hdev);
7271da177e4SLinus Torvalds 
7281da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
7291da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
7301da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
7311da177e4SLinus Torvalds 		}
7321da177e4SLinus Torvalds 
7331da177e4SLinus Torvalds 		hdev->close(hdev);
7341da177e4SLinus Torvalds 		hdev->flags = 0;
7351da177e4SLinus Torvalds 	}
7361da177e4SLinus Torvalds 
7371da177e4SLinus Torvalds done:
7381da177e4SLinus Torvalds 	hci_req_unlock(hdev);
7391da177e4SLinus Torvalds 	hci_dev_put(hdev);
7401da177e4SLinus Torvalds 	return ret;
7411da177e4SLinus Torvalds }
7421da177e4SLinus Torvalds 
7431da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
7441da177e4SLinus Torvalds {
7451da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
7461da177e4SLinus Torvalds 
74728b75a89SAndre Guedes 	cancel_work_sync(&hdev->le_scan);
74828b75a89SAndre Guedes 
7491da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
7501da177e4SLinus Torvalds 	hci_req_lock(hdev);
7511da177e4SLinus Torvalds 
7521da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
753b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
7541da177e4SLinus Torvalds 		hci_req_unlock(hdev);
7551da177e4SLinus Torvalds 		return 0;
7561da177e4SLinus Torvalds 	}
7571da177e4SLinus Torvalds 
7583eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
7593eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
760b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
7611da177e4SLinus Torvalds 
76216ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
763e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
76416ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
7655e5282bbSJohan Hedberg 		clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
76616ab91abSJohan Hedberg 	}
76716ab91abSJohan Hedberg 
768a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
7697d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
7707d78525dSJohan Hedberg 
7717ba8b4beSAndre Guedes 	cancel_delayed_work_sync(&hdev->le_scan_disable);
7727ba8b4beSAndre Guedes 
77309fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
7741da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
7751da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
77609fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
7771da177e4SLinus Torvalds 
7781da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
7791da177e4SLinus Torvalds 
7801da177e4SLinus Torvalds 	if (hdev->flush)
7811da177e4SLinus Torvalds 		hdev->flush(hdev);
7821da177e4SLinus Torvalds 
7831da177e4SLinus Torvalds 	/* Reset device */
7841da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
7851da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
7868af59467SJohan Hedberg 	if (!test_bit(HCI_RAW, &hdev->flags) &&
7878af59467SJohan Hedberg 				test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) {
7881da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
78904837f64SMarcel Holtmann 		__hci_request(hdev, hci_reset_req, 0,
790cad44c2bSGustavo F. Padovan 					msecs_to_jiffies(250));
7911da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
7921da177e4SLinus Torvalds 	}
7931da177e4SLinus Torvalds 
794c347b765SGustavo F. Padovan 	/* flush cmd  work */
795c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
7961da177e4SLinus Torvalds 
7971da177e4SLinus Torvalds 	/* Drop queues */
7981da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
7991da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
8001da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
8011da177e4SLinus Torvalds 
8021da177e4SLinus Torvalds 	/* Drop last sent command */
8031da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
804b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
8051da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
8061da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
8071da177e4SLinus Torvalds 	}
8081da177e4SLinus Torvalds 
8091da177e4SLinus Torvalds 	/* After this point our queues are empty
8101da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
8111da177e4SLinus Torvalds 	hdev->close(hdev);
8121da177e4SLinus Torvalds 
8138ee56540SMarcel Holtmann 	if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
81409fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
815744cf19eSJohan Hedberg 		mgmt_powered(hdev, 0);
81609fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
8178ee56540SMarcel Holtmann 	}
8185add6af8SJohan Hedberg 
8191da177e4SLinus Torvalds 	/* Clear flags */
8201da177e4SLinus Torvalds 	hdev->flags = 0;
8211da177e4SLinus Torvalds 
822e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
82309b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
824e59fda8dSJohan Hedberg 
8251da177e4SLinus Torvalds 	hci_req_unlock(hdev);
8261da177e4SLinus Torvalds 
8271da177e4SLinus Torvalds 	hci_dev_put(hdev);
8281da177e4SLinus Torvalds 	return 0;
8291da177e4SLinus Torvalds }
8301da177e4SLinus Torvalds 
8311da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
8321da177e4SLinus Torvalds {
8331da177e4SLinus Torvalds 	struct hci_dev *hdev;
8341da177e4SLinus Torvalds 	int err;
8351da177e4SLinus Torvalds 
83670f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
83770f23020SAndrei Emeltchenko 	if (!hdev)
8381da177e4SLinus Torvalds 		return -ENODEV;
8398ee56540SMarcel Holtmann 
8408ee56540SMarcel Holtmann 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
8418ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
8428ee56540SMarcel Holtmann 
8431da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
8448ee56540SMarcel Holtmann 
8451da177e4SLinus Torvalds 	hci_dev_put(hdev);
8461da177e4SLinus Torvalds 	return err;
8471da177e4SLinus Torvalds }
8481da177e4SLinus Torvalds 
8491da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
8501da177e4SLinus Torvalds {
8511da177e4SLinus Torvalds 	struct hci_dev *hdev;
8521da177e4SLinus Torvalds 	int ret = 0;
8531da177e4SLinus Torvalds 
85470f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
85570f23020SAndrei Emeltchenko 	if (!hdev)
8561da177e4SLinus Torvalds 		return -ENODEV;
8571da177e4SLinus Torvalds 
8581da177e4SLinus Torvalds 	hci_req_lock(hdev);
8591da177e4SLinus Torvalds 
8601da177e4SLinus Torvalds 	if (!test_bit(HCI_UP, &hdev->flags))
8611da177e4SLinus Torvalds 		goto done;
8621da177e4SLinus Torvalds 
8631da177e4SLinus Torvalds 	/* Drop queues */
8641da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
8651da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
8661da177e4SLinus Torvalds 
86709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
8681da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
8691da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
87009fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
8711da177e4SLinus Torvalds 
8721da177e4SLinus Torvalds 	if (hdev->flush)
8731da177e4SLinus Torvalds 		hdev->flush(hdev);
8741da177e4SLinus Torvalds 
8751da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
8766ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
8771da177e4SLinus Torvalds 
8781da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags))
87904837f64SMarcel Holtmann 		ret = __hci_request(hdev, hci_reset_req, 0,
88004837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
8811da177e4SLinus Torvalds 
8821da177e4SLinus Torvalds done:
8831da177e4SLinus Torvalds 	hci_req_unlock(hdev);
8841da177e4SLinus Torvalds 	hci_dev_put(hdev);
8851da177e4SLinus Torvalds 	return ret;
8861da177e4SLinus Torvalds }
8871da177e4SLinus Torvalds 
8881da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
8891da177e4SLinus Torvalds {
8901da177e4SLinus Torvalds 	struct hci_dev *hdev;
8911da177e4SLinus Torvalds 	int ret = 0;
8921da177e4SLinus Torvalds 
89370f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
89470f23020SAndrei Emeltchenko 	if (!hdev)
8951da177e4SLinus Torvalds 		return -ENODEV;
8961da177e4SLinus Torvalds 
8971da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
8981da177e4SLinus Torvalds 
8991da177e4SLinus Torvalds 	hci_dev_put(hdev);
9001da177e4SLinus Torvalds 
9011da177e4SLinus Torvalds 	return ret;
9021da177e4SLinus Torvalds }
9031da177e4SLinus Torvalds 
9041da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
9051da177e4SLinus Torvalds {
9061da177e4SLinus Torvalds 	struct hci_dev *hdev;
9071da177e4SLinus Torvalds 	struct hci_dev_req dr;
9081da177e4SLinus Torvalds 	int err = 0;
9091da177e4SLinus Torvalds 
9101da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
9111da177e4SLinus Torvalds 		return -EFAULT;
9121da177e4SLinus Torvalds 
91370f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
91470f23020SAndrei Emeltchenko 	if (!hdev)
9151da177e4SLinus Torvalds 		return -ENODEV;
9161da177e4SLinus Torvalds 
9171da177e4SLinus Torvalds 	switch (cmd) {
9181da177e4SLinus Torvalds 	case HCISETAUTH:
91904837f64SMarcel Holtmann 		err = hci_request(hdev, hci_auth_req, dr.dev_opt,
92004837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
9211da177e4SLinus Torvalds 		break;
9221da177e4SLinus Torvalds 
9231da177e4SLinus Torvalds 	case HCISETENCRYPT:
9241da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
9251da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
9261da177e4SLinus Torvalds 			break;
9271da177e4SLinus Torvalds 		}
9281da177e4SLinus Torvalds 
9291da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
9301da177e4SLinus Torvalds 			/* Auth must be enabled first */
93104837f64SMarcel Holtmann 			err = hci_request(hdev, hci_auth_req, dr.dev_opt,
93204837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
9331da177e4SLinus Torvalds 			if (err)
9341da177e4SLinus Torvalds 				break;
9351da177e4SLinus Torvalds 		}
9361da177e4SLinus Torvalds 
93704837f64SMarcel Holtmann 		err = hci_request(hdev, hci_encrypt_req, dr.dev_opt,
93804837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
9391da177e4SLinus Torvalds 		break;
9401da177e4SLinus Torvalds 
9411da177e4SLinus Torvalds 	case HCISETSCAN:
94204837f64SMarcel Holtmann 		err = hci_request(hdev, hci_scan_req, dr.dev_opt,
94304837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
9441da177e4SLinus Torvalds 		break;
9451da177e4SLinus Torvalds 
9461da177e4SLinus Torvalds 	case HCISETLINKPOL:
947e4e8e37cSMarcel Holtmann 		err = hci_request(hdev, hci_linkpol_req, dr.dev_opt,
948e4e8e37cSMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
9491da177e4SLinus Torvalds 		break;
9501da177e4SLinus Torvalds 
9511da177e4SLinus Torvalds 	case HCISETLINKMODE:
952e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
953e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
954e4e8e37cSMarcel Holtmann 		break;
955e4e8e37cSMarcel Holtmann 
956e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
957e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
9581da177e4SLinus Torvalds 		break;
9591da177e4SLinus Torvalds 
9601da177e4SLinus Torvalds 	case HCISETACLMTU:
9611da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
9621da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
9631da177e4SLinus Torvalds 		break;
9641da177e4SLinus Torvalds 
9651da177e4SLinus Torvalds 	case HCISETSCOMTU:
9661da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
9671da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
9681da177e4SLinus Torvalds 		break;
9691da177e4SLinus Torvalds 
9701da177e4SLinus Torvalds 	default:
9711da177e4SLinus Torvalds 		err = -EINVAL;
9721da177e4SLinus Torvalds 		break;
9731da177e4SLinus Torvalds 	}
974e4e8e37cSMarcel Holtmann 
9751da177e4SLinus Torvalds 	hci_dev_put(hdev);
9761da177e4SLinus Torvalds 	return err;
9771da177e4SLinus Torvalds }
9781da177e4SLinus Torvalds 
9791da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
9801da177e4SLinus Torvalds {
9818035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
9821da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
9831da177e4SLinus Torvalds 	struct hci_dev_req *dr;
9841da177e4SLinus Torvalds 	int n = 0, size, err;
9851da177e4SLinus Torvalds 	__u16 dev_num;
9861da177e4SLinus Torvalds 
9871da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
9881da177e4SLinus Torvalds 		return -EFAULT;
9891da177e4SLinus Torvalds 
9901da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
9911da177e4SLinus Torvalds 		return -EINVAL;
9921da177e4SLinus Torvalds 
9931da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
9941da177e4SLinus Torvalds 
99570f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
99670f23020SAndrei Emeltchenko 	if (!dl)
9971da177e4SLinus Torvalds 		return -ENOMEM;
9981da177e4SLinus Torvalds 
9991da177e4SLinus Torvalds 	dr = dl->dev_req;
10001da177e4SLinus Torvalds 
1001f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
10028035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
1003a8b2d5c2SJohan Hedberg 		if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
1004e0f9309fSJohan Hedberg 			cancel_delayed_work(&hdev->power_off);
1005c542a06cSJohan Hedberg 
1006a8b2d5c2SJohan Hedberg 		if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1007a8b2d5c2SJohan Hedberg 			set_bit(HCI_PAIRABLE, &hdev->dev_flags);
1008c542a06cSJohan Hedberg 
10091da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
10101da177e4SLinus Torvalds 		(dr + n)->dev_opt = hdev->flags;
1011c542a06cSJohan Hedberg 
10121da177e4SLinus Torvalds 		if (++n >= dev_num)
10131da177e4SLinus Torvalds 			break;
10141da177e4SLinus Torvalds 	}
1015f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
10161da177e4SLinus Torvalds 
10171da177e4SLinus Torvalds 	dl->dev_num = n;
10181da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
10191da177e4SLinus Torvalds 
10201da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
10211da177e4SLinus Torvalds 	kfree(dl);
10221da177e4SLinus Torvalds 
10231da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
10241da177e4SLinus Torvalds }
10251da177e4SLinus Torvalds 
10261da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
10271da177e4SLinus Torvalds {
10281da177e4SLinus Torvalds 	struct hci_dev *hdev;
10291da177e4SLinus Torvalds 	struct hci_dev_info di;
10301da177e4SLinus Torvalds 	int err = 0;
10311da177e4SLinus Torvalds 
10321da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
10331da177e4SLinus Torvalds 		return -EFAULT;
10341da177e4SLinus Torvalds 
103570f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
103670f23020SAndrei Emeltchenko 	if (!hdev)
10371da177e4SLinus Torvalds 		return -ENODEV;
10381da177e4SLinus Torvalds 
1039a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
10403243553fSJohan Hedberg 		cancel_delayed_work_sync(&hdev->power_off);
1041ab81cbf9SJohan Hedberg 
1042a8b2d5c2SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1043a8b2d5c2SJohan Hedberg 		set_bit(HCI_PAIRABLE, &hdev->dev_flags);
1044c542a06cSJohan Hedberg 
10451da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
10461da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
1047943da25dSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | (hdev->dev_type << 4);
10481da177e4SLinus Torvalds 	di.flags    = hdev->flags;
10491da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
10501da177e4SLinus Torvalds 	di.acl_mtu  = hdev->acl_mtu;
10511da177e4SLinus Torvalds 	di.acl_pkts = hdev->acl_pkts;
10521da177e4SLinus Torvalds 	di.sco_mtu  = hdev->sco_mtu;
10531da177e4SLinus Torvalds 	di.sco_pkts = hdev->sco_pkts;
10541da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
10551da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
10561da177e4SLinus Torvalds 
10571da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
10581da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
10591da177e4SLinus Torvalds 
10601da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
10611da177e4SLinus Torvalds 		err = -EFAULT;
10621da177e4SLinus Torvalds 
10631da177e4SLinus Torvalds 	hci_dev_put(hdev);
10641da177e4SLinus Torvalds 
10651da177e4SLinus Torvalds 	return err;
10661da177e4SLinus Torvalds }
10671da177e4SLinus Torvalds 
10681da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
10691da177e4SLinus Torvalds 
1070611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
1071611b30f7SMarcel Holtmann {
1072611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
1073611b30f7SMarcel Holtmann 
1074611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
1075611b30f7SMarcel Holtmann 
1076611b30f7SMarcel Holtmann 	if (!blocked)
1077611b30f7SMarcel Holtmann 		return 0;
1078611b30f7SMarcel Holtmann 
1079611b30f7SMarcel Holtmann 	hci_dev_do_close(hdev);
1080611b30f7SMarcel Holtmann 
1081611b30f7SMarcel Holtmann 	return 0;
1082611b30f7SMarcel Holtmann }
1083611b30f7SMarcel Holtmann 
1084611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
1085611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
1086611b30f7SMarcel Holtmann };
1087611b30f7SMarcel Holtmann 
10881da177e4SLinus Torvalds /* Alloc HCI device */
10891da177e4SLinus Torvalds struct hci_dev *hci_alloc_dev(void)
10901da177e4SLinus Torvalds {
10911da177e4SLinus Torvalds 	struct hci_dev *hdev;
10921da177e4SLinus Torvalds 
109325ea6db0SMarcel Holtmann 	hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
10941da177e4SLinus Torvalds 	if (!hdev)
10951da177e4SLinus Torvalds 		return NULL;
10961da177e4SLinus Torvalds 
10970ac7e700SDavid Herrmann 	hci_init_sysfs(hdev);
10981da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->driver_init);
10991da177e4SLinus Torvalds 
11001da177e4SLinus Torvalds 	return hdev;
11011da177e4SLinus Torvalds }
11021da177e4SLinus Torvalds EXPORT_SYMBOL(hci_alloc_dev);
11031da177e4SLinus Torvalds 
11041da177e4SLinus Torvalds /* Free HCI device */
11051da177e4SLinus Torvalds void hci_free_dev(struct hci_dev *hdev)
11061da177e4SLinus Torvalds {
11071da177e4SLinus Torvalds 	skb_queue_purge(&hdev->driver_init);
11081da177e4SLinus Torvalds 
1109a91f2e39SMarcel Holtmann 	/* will free via device release */
1110a91f2e39SMarcel Holtmann 	put_device(&hdev->dev);
11111da177e4SLinus Torvalds }
11121da177e4SLinus Torvalds EXPORT_SYMBOL(hci_free_dev);
11131da177e4SLinus Torvalds 
1114ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
1115ab81cbf9SJohan Hedberg {
1116ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
1117ab81cbf9SJohan Hedberg 
1118ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1119ab81cbf9SJohan Hedberg 
1120ab81cbf9SJohan Hedberg 	if (hci_dev_open(hdev->id) < 0)
1121ab81cbf9SJohan Hedberg 		return;
1122ab81cbf9SJohan Hedberg 
1123a8b2d5c2SJohan Hedberg 	if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
112480b7ab33SGustavo F. Padovan 		schedule_delayed_work(&hdev->power_off,
11253243553fSJohan Hedberg 					msecs_to_jiffies(AUTO_OFF_TIMEOUT));
1126ab81cbf9SJohan Hedberg 
1127a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags))
1128744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
1129ab81cbf9SJohan Hedberg }
1130ab81cbf9SJohan Hedberg 
1131ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
1132ab81cbf9SJohan Hedberg {
11333243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
11343243553fSJohan Hedberg 							power_off.work);
1135ab81cbf9SJohan Hedberg 
1136ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1137ab81cbf9SJohan Hedberg 
11388ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
1139ab81cbf9SJohan Hedberg }
1140ab81cbf9SJohan Hedberg 
114116ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
114216ab91abSJohan Hedberg {
114316ab91abSJohan Hedberg 	struct hci_dev *hdev;
114416ab91abSJohan Hedberg 	u8 scan = SCAN_PAGE;
114516ab91abSJohan Hedberg 
114616ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
114716ab91abSJohan Hedberg 
114816ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
114916ab91abSJohan Hedberg 
115009fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
115116ab91abSJohan Hedberg 
115216ab91abSJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan);
115316ab91abSJohan Hedberg 
115416ab91abSJohan Hedberg 	hdev->discov_timeout = 0;
115516ab91abSJohan Hedberg 
115609fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
115716ab91abSJohan Hedberg }
115816ab91abSJohan Hedberg 
11592aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev)
11602aeb9a1aSJohan Hedberg {
11612aeb9a1aSJohan Hedberg 	struct list_head *p, *n;
11622aeb9a1aSJohan Hedberg 
11632aeb9a1aSJohan Hedberg 	list_for_each_safe(p, n, &hdev->uuids) {
11642aeb9a1aSJohan Hedberg 		struct bt_uuid *uuid;
11652aeb9a1aSJohan Hedberg 
11662aeb9a1aSJohan Hedberg 		uuid = list_entry(p, struct bt_uuid, list);
11672aeb9a1aSJohan Hedberg 
11682aeb9a1aSJohan Hedberg 		list_del(p);
11692aeb9a1aSJohan Hedberg 		kfree(uuid);
11702aeb9a1aSJohan Hedberg 	}
11712aeb9a1aSJohan Hedberg 
11722aeb9a1aSJohan Hedberg 	return 0;
11732aeb9a1aSJohan Hedberg }
11742aeb9a1aSJohan Hedberg 
117555ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev)
117655ed8ca1SJohan Hedberg {
117755ed8ca1SJohan Hedberg 	struct list_head *p, *n;
117855ed8ca1SJohan Hedberg 
117955ed8ca1SJohan Hedberg 	list_for_each_safe(p, n, &hdev->link_keys) {
118055ed8ca1SJohan Hedberg 		struct link_key *key;
118155ed8ca1SJohan Hedberg 
118255ed8ca1SJohan Hedberg 		key = list_entry(p, struct link_key, list);
118355ed8ca1SJohan Hedberg 
118455ed8ca1SJohan Hedberg 		list_del(p);
118555ed8ca1SJohan Hedberg 		kfree(key);
118655ed8ca1SJohan Hedberg 	}
118755ed8ca1SJohan Hedberg 
118855ed8ca1SJohan Hedberg 	return 0;
118955ed8ca1SJohan Hedberg }
119055ed8ca1SJohan Hedberg 
1191b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev)
1192b899efafSVinicius Costa Gomes {
1193b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1194b899efafSVinicius Costa Gomes 
1195b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1196b899efafSVinicius Costa Gomes 		list_del(&k->list);
1197b899efafSVinicius Costa Gomes 		kfree(k);
1198b899efafSVinicius Costa Gomes 	}
1199b899efafSVinicius Costa Gomes 
1200b899efafSVinicius Costa Gomes 	return 0;
1201b899efafSVinicius Costa Gomes }
1202b899efafSVinicius Costa Gomes 
120355ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
120455ed8ca1SJohan Hedberg {
120555ed8ca1SJohan Hedberg 	struct link_key *k;
120655ed8ca1SJohan Hedberg 
12078035ded4SLuiz Augusto von Dentz 	list_for_each_entry(k, &hdev->link_keys, list)
120855ed8ca1SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0)
120955ed8ca1SJohan Hedberg 			return k;
121055ed8ca1SJohan Hedberg 
121155ed8ca1SJohan Hedberg 	return NULL;
121255ed8ca1SJohan Hedberg }
121355ed8ca1SJohan Hedberg 
1214d25e28abSJohan Hedberg static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1215d25e28abSJohan Hedberg 						u8 key_type, u8 old_key_type)
1216d25e28abSJohan Hedberg {
1217d25e28abSJohan Hedberg 	/* Legacy key */
1218d25e28abSJohan Hedberg 	if (key_type < 0x03)
1219d25e28abSJohan Hedberg 		return 1;
1220d25e28abSJohan Hedberg 
1221d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
1222d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
1223d25e28abSJohan Hedberg 		return 0;
1224d25e28abSJohan Hedberg 
1225d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
1226d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
1227d25e28abSJohan Hedberg 		return 0;
1228d25e28abSJohan Hedberg 
1229d25e28abSJohan Hedberg 	/* Security mode 3 case */
1230d25e28abSJohan Hedberg 	if (!conn)
1231d25e28abSJohan Hedberg 		return 1;
1232d25e28abSJohan Hedberg 
1233d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
1234d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
1235d25e28abSJohan Hedberg 		return 1;
1236d25e28abSJohan Hedberg 
1237d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
1238d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
1239d25e28abSJohan Hedberg 		return 1;
1240d25e28abSJohan Hedberg 
1241d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
1242d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
1243d25e28abSJohan Hedberg 		return 1;
1244d25e28abSJohan Hedberg 
1245d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
1246d25e28abSJohan Hedberg 	 * persistently */
1247d25e28abSJohan Hedberg 	return 0;
1248d25e28abSJohan Hedberg }
1249d25e28abSJohan Hedberg 
1250c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
125175d262c2SVinicius Costa Gomes {
1252c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
125375d262c2SVinicius Costa Gomes 
1254c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list) {
1255c9839a11SVinicius Costa Gomes 		if (k->ediv != ediv ||
1256c9839a11SVinicius Costa Gomes 				memcmp(rand, k->rand, sizeof(k->rand)))
125775d262c2SVinicius Costa Gomes 			continue;
125875d262c2SVinicius Costa Gomes 
125975d262c2SVinicius Costa Gomes 		return k;
126075d262c2SVinicius Costa Gomes 	}
126175d262c2SVinicius Costa Gomes 
126275d262c2SVinicius Costa Gomes 	return NULL;
126375d262c2SVinicius Costa Gomes }
126475d262c2SVinicius Costa Gomes EXPORT_SYMBOL(hci_find_ltk);
126575d262c2SVinicius Costa Gomes 
1266c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
1267c9839a11SVinicius Costa Gomes 				     u8 addr_type)
126875d262c2SVinicius Costa Gomes {
1269c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
127075d262c2SVinicius Costa Gomes 
1271c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list)
1272c9839a11SVinicius Costa Gomes 		if (addr_type == k->bdaddr_type &&
1273c9839a11SVinicius Costa Gomes 					bacmp(bdaddr, &k->bdaddr) == 0)
127475d262c2SVinicius Costa Gomes 			return k;
127575d262c2SVinicius Costa Gomes 
127675d262c2SVinicius Costa Gomes 	return NULL;
127775d262c2SVinicius Costa Gomes }
1278c9839a11SVinicius Costa Gomes EXPORT_SYMBOL(hci_find_ltk_by_addr);
127975d262c2SVinicius Costa Gomes 
1280d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
1281d25e28abSJohan Hedberg 		     bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
128255ed8ca1SJohan Hedberg {
128355ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
12844df378a1SJohan Hedberg 	u8 old_key_type, persistent;
128555ed8ca1SJohan Hedberg 
128655ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
128755ed8ca1SJohan Hedberg 	if (old_key) {
128855ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
128955ed8ca1SJohan Hedberg 		key = old_key;
129055ed8ca1SJohan Hedberg 	} else {
129112adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
129255ed8ca1SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
129355ed8ca1SJohan Hedberg 		if (!key)
129455ed8ca1SJohan Hedberg 			return -ENOMEM;
129555ed8ca1SJohan Hedberg 		list_add(&key->list, &hdev->link_keys);
129655ed8ca1SJohan Hedberg 	}
129755ed8ca1SJohan Hedberg 
129855ed8ca1SJohan Hedberg 	BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type);
129955ed8ca1SJohan Hedberg 
1300d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
1301d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
1302d25e28abSJohan Hedberg 	 * previous key */
1303d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
1304d25e28abSJohan Hedberg 					(!conn || conn->remote_auth == 0xff) &&
1305655fe6ecSJohan Hedberg 					old_key_type == 0xff) {
1306d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
1307655fe6ecSJohan Hedberg 		if (conn)
1308655fe6ecSJohan Hedberg 			conn->key_type = type;
1309655fe6ecSJohan Hedberg 	}
1310d25e28abSJohan Hedberg 
131155ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
131255ed8ca1SJohan Hedberg 	memcpy(key->val, val, 16);
131355ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
131455ed8ca1SJohan Hedberg 
1315b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
131655ed8ca1SJohan Hedberg 		key->type = old_key_type;
13174748fed2SJohan Hedberg 	else
13184748fed2SJohan Hedberg 		key->type = type;
13194748fed2SJohan Hedberg 
13204df378a1SJohan Hedberg 	if (!new_key)
13214df378a1SJohan Hedberg 		return 0;
13224df378a1SJohan Hedberg 
13234df378a1SJohan Hedberg 	persistent = hci_persistent_key(hdev, conn, type, old_key_type);
13244df378a1SJohan Hedberg 
1325744cf19eSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
13264df378a1SJohan Hedberg 
13274df378a1SJohan Hedberg 	if (!persistent) {
13284df378a1SJohan Hedberg 		list_del(&key->list);
13294df378a1SJohan Hedberg 		kfree(key);
13304df378a1SJohan Hedberg 	}
133155ed8ca1SJohan Hedberg 
133255ed8ca1SJohan Hedberg 	return 0;
133355ed8ca1SJohan Hedberg }
133455ed8ca1SJohan Hedberg 
1335c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
133604124681SGustavo F. Padovan 		int new_key, u8 authenticated, u8 tk[16], u8 enc_size, u16
133704124681SGustavo F. Padovan 		ediv, u8 rand[8])
133875d262c2SVinicius Costa Gomes {
1339c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
134075d262c2SVinicius Costa Gomes 
1341c9839a11SVinicius Costa Gomes 	if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK))
1342c9839a11SVinicius Costa Gomes 		return 0;
134375d262c2SVinicius Costa Gomes 
1344c9839a11SVinicius Costa Gomes 	old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type);
1345c9839a11SVinicius Costa Gomes 	if (old_key)
134675d262c2SVinicius Costa Gomes 		key = old_key;
1347c9839a11SVinicius Costa Gomes 	else {
1348c9839a11SVinicius Costa Gomes 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
134975d262c2SVinicius Costa Gomes 		if (!key)
135075d262c2SVinicius Costa Gomes 			return -ENOMEM;
1351c9839a11SVinicius Costa Gomes 		list_add(&key->list, &hdev->long_term_keys);
135275d262c2SVinicius Costa Gomes 	}
135375d262c2SVinicius Costa Gomes 
135475d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
1355c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
1356c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
1357c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
1358c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
1359c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
1360c9839a11SVinicius Costa Gomes 	key->type = type;
1361c9839a11SVinicius Costa Gomes 	memcpy(key->rand, rand, sizeof(key->rand));
136275d262c2SVinicius Costa Gomes 
1363c9839a11SVinicius Costa Gomes 	if (!new_key)
1364c9839a11SVinicius Costa Gomes 		return 0;
136575d262c2SVinicius Costa Gomes 
1366261cc5aaSVinicius Costa Gomes 	if (type & HCI_SMP_LTK)
1367261cc5aaSVinicius Costa Gomes 		mgmt_new_ltk(hdev, key, 1);
1368261cc5aaSVinicius Costa Gomes 
136975d262c2SVinicius Costa Gomes 	return 0;
137075d262c2SVinicius Costa Gomes }
137175d262c2SVinicius Costa Gomes 
137255ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
137355ed8ca1SJohan Hedberg {
137455ed8ca1SJohan Hedberg 	struct link_key *key;
137555ed8ca1SJohan Hedberg 
137655ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
137755ed8ca1SJohan Hedberg 	if (!key)
137855ed8ca1SJohan Hedberg 		return -ENOENT;
137955ed8ca1SJohan Hedberg 
138055ed8ca1SJohan Hedberg 	BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
138155ed8ca1SJohan Hedberg 
138255ed8ca1SJohan Hedberg 	list_del(&key->list);
138355ed8ca1SJohan Hedberg 	kfree(key);
138455ed8ca1SJohan Hedberg 
138555ed8ca1SJohan Hedberg 	return 0;
138655ed8ca1SJohan Hedberg }
138755ed8ca1SJohan Hedberg 
1388b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr)
1389b899efafSVinicius Costa Gomes {
1390b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1391b899efafSVinicius Costa Gomes 
1392b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1393b899efafSVinicius Costa Gomes 		if (bacmp(bdaddr, &k->bdaddr))
1394b899efafSVinicius Costa Gomes 			continue;
1395b899efafSVinicius Costa Gomes 
1396b899efafSVinicius Costa Gomes 		BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
1397b899efafSVinicius Costa Gomes 
1398b899efafSVinicius Costa Gomes 		list_del(&k->list);
1399b899efafSVinicius Costa Gomes 		kfree(k);
1400b899efafSVinicius Costa Gomes 	}
1401b899efafSVinicius Costa Gomes 
1402b899efafSVinicius Costa Gomes 	return 0;
1403b899efafSVinicius Costa Gomes }
1404b899efafSVinicius Costa Gomes 
14056bd32326SVille Tervo /* HCI command timer function */
14066bd32326SVille Tervo static void hci_cmd_timer(unsigned long arg)
14076bd32326SVille Tervo {
14086bd32326SVille Tervo 	struct hci_dev *hdev = (void *) arg;
14096bd32326SVille Tervo 
14106bd32326SVille Tervo 	BT_ERR("%s command tx timeout", hdev->name);
14116bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
1412c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
14136bd32326SVille Tervo }
14146bd32326SVille Tervo 
14152763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
14162763eda6SSzymon Janc 					  bdaddr_t *bdaddr)
14172763eda6SSzymon Janc {
14182763eda6SSzymon Janc 	struct oob_data *data;
14192763eda6SSzymon Janc 
14202763eda6SSzymon Janc 	list_for_each_entry(data, &hdev->remote_oob_data, list)
14212763eda6SSzymon Janc 		if (bacmp(bdaddr, &data->bdaddr) == 0)
14222763eda6SSzymon Janc 			return data;
14232763eda6SSzymon Janc 
14242763eda6SSzymon Janc 	return NULL;
14252763eda6SSzymon Janc }
14262763eda6SSzymon Janc 
14272763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
14282763eda6SSzymon Janc {
14292763eda6SSzymon Janc 	struct oob_data *data;
14302763eda6SSzymon Janc 
14312763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
14322763eda6SSzymon Janc 	if (!data)
14332763eda6SSzymon Janc 		return -ENOENT;
14342763eda6SSzymon Janc 
14352763eda6SSzymon Janc 	BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
14362763eda6SSzymon Janc 
14372763eda6SSzymon Janc 	list_del(&data->list);
14382763eda6SSzymon Janc 	kfree(data);
14392763eda6SSzymon Janc 
14402763eda6SSzymon Janc 	return 0;
14412763eda6SSzymon Janc }
14422763eda6SSzymon Janc 
14432763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev)
14442763eda6SSzymon Janc {
14452763eda6SSzymon Janc 	struct oob_data *data, *n;
14462763eda6SSzymon Janc 
14472763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
14482763eda6SSzymon Janc 		list_del(&data->list);
14492763eda6SSzymon Janc 		kfree(data);
14502763eda6SSzymon Janc 	}
14512763eda6SSzymon Janc 
14522763eda6SSzymon Janc 	return 0;
14532763eda6SSzymon Janc }
14542763eda6SSzymon Janc 
14552763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
14562763eda6SSzymon Janc 			    u8 *randomizer)
14572763eda6SSzymon Janc {
14582763eda6SSzymon Janc 	struct oob_data *data;
14592763eda6SSzymon Janc 
14602763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
14612763eda6SSzymon Janc 
14622763eda6SSzymon Janc 	if (!data) {
14632763eda6SSzymon Janc 		data = kmalloc(sizeof(*data), GFP_ATOMIC);
14642763eda6SSzymon Janc 		if (!data)
14652763eda6SSzymon Janc 			return -ENOMEM;
14662763eda6SSzymon Janc 
14672763eda6SSzymon Janc 		bacpy(&data->bdaddr, bdaddr);
14682763eda6SSzymon Janc 		list_add(&data->list, &hdev->remote_oob_data);
14692763eda6SSzymon Janc 	}
14702763eda6SSzymon Janc 
14712763eda6SSzymon Janc 	memcpy(data->hash, hash, sizeof(data->hash));
14722763eda6SSzymon Janc 	memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
14732763eda6SSzymon Janc 
14742763eda6SSzymon Janc 	BT_DBG("%s for %s", hdev->name, batostr(bdaddr));
14752763eda6SSzymon Janc 
14762763eda6SSzymon Janc 	return 0;
14772763eda6SSzymon Janc }
14782763eda6SSzymon Janc 
147904124681SGustavo F. Padovan struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
1480b2a66aadSAntti Julku {
1481b2a66aadSAntti Julku 	struct bdaddr_list *b;
1482b2a66aadSAntti Julku 
14838035ded4SLuiz Augusto von Dentz 	list_for_each_entry(b, &hdev->blacklist, list)
1484b2a66aadSAntti Julku 		if (bacmp(bdaddr, &b->bdaddr) == 0)
1485b2a66aadSAntti Julku 			return b;
1486b2a66aadSAntti Julku 
1487b2a66aadSAntti Julku 	return NULL;
1488b2a66aadSAntti Julku }
1489b2a66aadSAntti Julku 
1490b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev)
1491b2a66aadSAntti Julku {
1492b2a66aadSAntti Julku 	struct list_head *p, *n;
1493b2a66aadSAntti Julku 
1494b2a66aadSAntti Julku 	list_for_each_safe(p, n, &hdev->blacklist) {
1495b2a66aadSAntti Julku 		struct bdaddr_list *b;
1496b2a66aadSAntti Julku 
1497b2a66aadSAntti Julku 		b = list_entry(p, struct bdaddr_list, list);
1498b2a66aadSAntti Julku 
1499b2a66aadSAntti Julku 		list_del(p);
1500b2a66aadSAntti Julku 		kfree(b);
1501b2a66aadSAntti Julku 	}
1502b2a66aadSAntti Julku 
1503b2a66aadSAntti Julku 	return 0;
1504b2a66aadSAntti Julku }
1505b2a66aadSAntti Julku 
150688c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
1507b2a66aadSAntti Julku {
1508b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1509b2a66aadSAntti Julku 
1510b2a66aadSAntti Julku 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
1511b2a66aadSAntti Julku 		return -EBADF;
1512b2a66aadSAntti Julku 
15135e762444SAntti Julku 	if (hci_blacklist_lookup(hdev, bdaddr))
15145e762444SAntti Julku 		return -EEXIST;
1515b2a66aadSAntti Julku 
1516b2a66aadSAntti Julku 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
15175e762444SAntti Julku 	if (!entry)
15185e762444SAntti Julku 		return -ENOMEM;
1519b2a66aadSAntti Julku 
1520b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
1521b2a66aadSAntti Julku 
1522b2a66aadSAntti Julku 	list_add(&entry->list, &hdev->blacklist);
1523b2a66aadSAntti Julku 
152488c1fe4bSJohan Hedberg 	return mgmt_device_blocked(hdev, bdaddr, type);
1525b2a66aadSAntti Julku }
1526b2a66aadSAntti Julku 
152788c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
1528b2a66aadSAntti Julku {
1529b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1530b2a66aadSAntti Julku 
15311ec918ceSSzymon Janc 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
15325e762444SAntti Julku 		return hci_blacklist_clear(hdev);
1533b2a66aadSAntti Julku 
1534b2a66aadSAntti Julku 	entry = hci_blacklist_lookup(hdev, bdaddr);
15351ec918ceSSzymon Janc 	if (!entry)
15365e762444SAntti Julku 		return -ENOENT;
1537b2a66aadSAntti Julku 
1538b2a66aadSAntti Julku 	list_del(&entry->list);
1539b2a66aadSAntti Julku 	kfree(entry);
1540b2a66aadSAntti Julku 
154188c1fe4bSJohan Hedberg 	return mgmt_device_unblocked(hdev, bdaddr, type);
1542b2a66aadSAntti Julku }
1543b2a66aadSAntti Julku 
1544db323f2fSGustavo F. Padovan static void hci_clear_adv_cache(struct work_struct *work)
154535815085SAndre Guedes {
1546db323f2fSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev,
1547db323f2fSGustavo F. Padovan 					    adv_work.work);
154835815085SAndre Guedes 
154935815085SAndre Guedes 	hci_dev_lock(hdev);
155035815085SAndre Guedes 
155135815085SAndre Guedes 	hci_adv_entries_clear(hdev);
155235815085SAndre Guedes 
155335815085SAndre Guedes 	hci_dev_unlock(hdev);
155435815085SAndre Guedes }
155535815085SAndre Guedes 
155676c8686fSAndre Guedes int hci_adv_entries_clear(struct hci_dev *hdev)
155776c8686fSAndre Guedes {
155876c8686fSAndre Guedes 	struct adv_entry *entry, *tmp;
155976c8686fSAndre Guedes 
156076c8686fSAndre Guedes 	list_for_each_entry_safe(entry, tmp, &hdev->adv_entries, list) {
156176c8686fSAndre Guedes 		list_del(&entry->list);
156276c8686fSAndre Guedes 		kfree(entry);
156376c8686fSAndre Guedes 	}
156476c8686fSAndre Guedes 
156576c8686fSAndre Guedes 	BT_DBG("%s adv cache cleared", hdev->name);
156676c8686fSAndre Guedes 
156776c8686fSAndre Guedes 	return 0;
156876c8686fSAndre Guedes }
156976c8686fSAndre Guedes 
157076c8686fSAndre Guedes struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr)
157176c8686fSAndre Guedes {
157276c8686fSAndre Guedes 	struct adv_entry *entry;
157376c8686fSAndre Guedes 
157476c8686fSAndre Guedes 	list_for_each_entry(entry, &hdev->adv_entries, list)
157576c8686fSAndre Guedes 		if (bacmp(bdaddr, &entry->bdaddr) == 0)
157676c8686fSAndre Guedes 			return entry;
157776c8686fSAndre Guedes 
157876c8686fSAndre Guedes 	return NULL;
157976c8686fSAndre Guedes }
158076c8686fSAndre Guedes 
158176c8686fSAndre Guedes static inline int is_connectable_adv(u8 evt_type)
158276c8686fSAndre Guedes {
158376c8686fSAndre Guedes 	if (evt_type == ADV_IND || evt_type == ADV_DIRECT_IND)
158476c8686fSAndre Guedes 		return 1;
158576c8686fSAndre Guedes 
158676c8686fSAndre Guedes 	return 0;
158776c8686fSAndre Guedes }
158876c8686fSAndre Guedes 
158976c8686fSAndre Guedes int hci_add_adv_entry(struct hci_dev *hdev,
159004124681SGustavo F. Padovan 					struct hci_ev_le_advertising_info *ev) { struct adv_entry *entry; if (!is_connectable_adv(ev->evt_type))
159176c8686fSAndre Guedes 		return -EINVAL;
159276c8686fSAndre Guedes 
159376c8686fSAndre Guedes 	/* Only new entries should be added to adv_entries. So, if
159476c8686fSAndre Guedes 	 * bdaddr was found, don't add it. */
159576c8686fSAndre Guedes 	if (hci_find_adv_entry(hdev, &ev->bdaddr))
159676c8686fSAndre Guedes 		return 0;
159776c8686fSAndre Guedes 
15984777bfdeSAndre Guedes 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
159976c8686fSAndre Guedes 	if (!entry)
160076c8686fSAndre Guedes 		return -ENOMEM;
160176c8686fSAndre Guedes 
160276c8686fSAndre Guedes 	bacpy(&entry->bdaddr, &ev->bdaddr);
160376c8686fSAndre Guedes 	entry->bdaddr_type = ev->bdaddr_type;
160476c8686fSAndre Guedes 
160576c8686fSAndre Guedes 	list_add(&entry->list, &hdev->adv_entries);
160676c8686fSAndre Guedes 
160776c8686fSAndre Guedes 	BT_DBG("%s adv entry added: address %s type %u", hdev->name,
160876c8686fSAndre Guedes 				batostr(&entry->bdaddr), entry->bdaddr_type);
160976c8686fSAndre Guedes 
161076c8686fSAndre Guedes 	return 0;
161176c8686fSAndre Guedes }
161276c8686fSAndre Guedes 
16137ba8b4beSAndre Guedes static void le_scan_param_req(struct hci_dev *hdev, unsigned long opt)
16147ba8b4beSAndre Guedes {
16157ba8b4beSAndre Guedes 	struct le_scan_params *param =  (struct le_scan_params *) opt;
16167ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_param cp;
16177ba8b4beSAndre Guedes 
16187ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
16197ba8b4beSAndre Guedes 	cp.type = param->type;
16207ba8b4beSAndre Guedes 	cp.interval = cpu_to_le16(param->interval);
16217ba8b4beSAndre Guedes 	cp.window = cpu_to_le16(param->window);
16227ba8b4beSAndre Guedes 
16237ba8b4beSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp);
16247ba8b4beSAndre Guedes }
16257ba8b4beSAndre Guedes 
16267ba8b4beSAndre Guedes static void le_scan_enable_req(struct hci_dev *hdev, unsigned long opt)
16277ba8b4beSAndre Guedes {
16287ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
16297ba8b4beSAndre Guedes 
16307ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
16317ba8b4beSAndre Guedes 	cp.enable = 1;
16327ba8b4beSAndre Guedes 
16337ba8b4beSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
16347ba8b4beSAndre Guedes }
16357ba8b4beSAndre Guedes 
16367ba8b4beSAndre Guedes static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval,
16377ba8b4beSAndre Guedes 			  u16 window, int timeout)
16387ba8b4beSAndre Guedes {
16397ba8b4beSAndre Guedes 	long timeo = msecs_to_jiffies(3000);
16407ba8b4beSAndre Guedes 	struct le_scan_params param;
16417ba8b4beSAndre Guedes 	int err;
16427ba8b4beSAndre Guedes 
16437ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
16447ba8b4beSAndre Guedes 
16457ba8b4beSAndre Guedes 	if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
16467ba8b4beSAndre Guedes 		return -EINPROGRESS;
16477ba8b4beSAndre Guedes 
16487ba8b4beSAndre Guedes 	param.type = type;
16497ba8b4beSAndre Guedes 	param.interval = interval;
16507ba8b4beSAndre Guedes 	param.window = window;
16517ba8b4beSAndre Guedes 
16527ba8b4beSAndre Guedes 	hci_req_lock(hdev);
16537ba8b4beSAndre Guedes 
16547ba8b4beSAndre Guedes 	err = __hci_request(hdev, le_scan_param_req, (unsigned long) &param,
16557ba8b4beSAndre Guedes 			    timeo);
16567ba8b4beSAndre Guedes 	if (!err)
16577ba8b4beSAndre Guedes 		err = __hci_request(hdev, le_scan_enable_req, 0, timeo);
16587ba8b4beSAndre Guedes 
16597ba8b4beSAndre Guedes 	hci_req_unlock(hdev);
16607ba8b4beSAndre Guedes 
16617ba8b4beSAndre Guedes 	if (err < 0)
16627ba8b4beSAndre Guedes 		return err;
16637ba8b4beSAndre Guedes 
16647ba8b4beSAndre Guedes 	schedule_delayed_work(&hdev->le_scan_disable,
16657ba8b4beSAndre Guedes 			      msecs_to_jiffies(timeout));
16667ba8b4beSAndre Guedes 
16677ba8b4beSAndre Guedes 	return 0;
16687ba8b4beSAndre Guedes }
16697ba8b4beSAndre Guedes 
16707ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work)
16717ba8b4beSAndre Guedes {
16727ba8b4beSAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev,
16737ba8b4beSAndre Guedes 					    le_scan_disable.work);
16747ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
16757ba8b4beSAndre Guedes 
16767ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
16777ba8b4beSAndre Guedes 
16787ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
16797ba8b4beSAndre Guedes 
16807ba8b4beSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
16817ba8b4beSAndre Guedes }
16827ba8b4beSAndre Guedes 
168328b75a89SAndre Guedes static void le_scan_work(struct work_struct *work)
168428b75a89SAndre Guedes {
168528b75a89SAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev, le_scan);
168628b75a89SAndre Guedes 	struct le_scan_params *param = &hdev->le_scan_params;
168728b75a89SAndre Guedes 
168828b75a89SAndre Guedes 	BT_DBG("%s", hdev->name);
168928b75a89SAndre Guedes 
169004124681SGustavo F. Padovan 	hci_do_le_scan(hdev, param->type, param->interval, param->window,
169104124681SGustavo F. Padovan 		       param->timeout);
169228b75a89SAndre Guedes }
169328b75a89SAndre Guedes 
169428b75a89SAndre Guedes int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window,
169528b75a89SAndre Guedes 		int timeout)
169628b75a89SAndre Guedes {
169728b75a89SAndre Guedes 	struct le_scan_params *param = &hdev->le_scan_params;
169828b75a89SAndre Guedes 
169928b75a89SAndre Guedes 	BT_DBG("%s", hdev->name);
170028b75a89SAndre Guedes 
170128b75a89SAndre Guedes 	if (work_busy(&hdev->le_scan))
170228b75a89SAndre Guedes 		return -EINPROGRESS;
170328b75a89SAndre Guedes 
170428b75a89SAndre Guedes 	param->type = type;
170528b75a89SAndre Guedes 	param->interval = interval;
170628b75a89SAndre Guedes 	param->window = window;
170728b75a89SAndre Guedes 	param->timeout = timeout;
170828b75a89SAndre Guedes 
170928b75a89SAndre Guedes 	queue_work(system_long_wq, &hdev->le_scan);
171028b75a89SAndre Guedes 
171128b75a89SAndre Guedes 	return 0;
171228b75a89SAndre Guedes }
171328b75a89SAndre Guedes 
17141da177e4SLinus Torvalds /* Register HCI device */
17151da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
17161da177e4SLinus Torvalds {
17171da177e4SLinus Torvalds 	struct list_head *head = &hci_dev_list, *p;
171808add513SMat Martineau 	int i, id, error;
17191da177e4SLinus Torvalds 
1720e9b9cfa1SDavid Herrmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
17211da177e4SLinus Torvalds 
1722010666a1SDavid Herrmann 	if (!hdev->open || !hdev->close)
17231da177e4SLinus Torvalds 		return -EINVAL;
17241da177e4SLinus Torvalds 
172508add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
172608add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
172708add513SMat Martineau 	 */
172808add513SMat Martineau 	id = (hdev->dev_type == HCI_BREDR) ? 0 : 1;
172908add513SMat Martineau 
1730f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
17311da177e4SLinus Torvalds 
17321da177e4SLinus Torvalds 	/* Find first available device id */
17331da177e4SLinus Torvalds 	list_for_each(p, &hci_dev_list) {
17341da177e4SLinus Torvalds 		if (list_entry(p, struct hci_dev, list)->id != id)
17351da177e4SLinus Torvalds 			break;
17361da177e4SLinus Torvalds 		head = p; id++;
17371da177e4SLinus Torvalds 	}
17381da177e4SLinus Torvalds 
17391da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
17401da177e4SLinus Torvalds 	hdev->id = id;
1741c6feeb28SAndrei Emeltchenko 	list_add_tail(&hdev->list, head);
17421da177e4SLinus Torvalds 
174309fd0de5SGustavo F. Padovan 	mutex_init(&hdev->lock);
17441da177e4SLinus Torvalds 
17451da177e4SLinus Torvalds 	hdev->flags = 0;
1746d23264a8SAndre Guedes 	hdev->dev_flags = 0;
17471da177e4SLinus Torvalds 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
17485b7f9909SMarcel Holtmann 	hdev->esco_type = (ESCO_HV1);
17491da177e4SLinus Torvalds 	hdev->link_mode = (HCI_LM_ACCEPT);
175017fa4b9dSJohan Hedberg 	hdev->io_capability = 0x03; /* No Input No Output */
17511da177e4SLinus Torvalds 
175204837f64SMarcel Holtmann 	hdev->idle_timeout = 0;
175304837f64SMarcel Holtmann 	hdev->sniff_max_interval = 800;
175404837f64SMarcel Holtmann 	hdev->sniff_min_interval = 80;
175504837f64SMarcel Holtmann 
1756b78752ccSMarcel Holtmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
1757c347b765SGustavo F. Padovan 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
17583eff45eaSGustavo F. Padovan 	INIT_WORK(&hdev->tx_work, hci_tx_work);
1759b78752ccSMarcel Holtmann 
17601da177e4SLinus Torvalds 
17611da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->rx_q);
17621da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->cmd_q);
17631da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->raw_q);
17641da177e4SLinus Torvalds 
17656bd32326SVille Tervo 	setup_timer(&hdev->cmd_timer, hci_cmd_timer, (unsigned long) hdev);
17666bd32326SVille Tervo 
1767cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
1768ef222013SMarcel Holtmann 		hdev->reassembly[i] = NULL;
1769ef222013SMarcel Holtmann 
17701da177e4SLinus Torvalds 	init_waitqueue_head(&hdev->req_wait_q);
1771a6a67efdSThomas Gleixner 	mutex_init(&hdev->req_lock);
17721da177e4SLinus Torvalds 
177330883512SJohan Hedberg 	discovery_init(hdev);
17741da177e4SLinus Torvalds 
17751da177e4SLinus Torvalds 	hci_conn_hash_init(hdev);
17761da177e4SLinus Torvalds 
17772e58ef3eSJohan Hedberg 	INIT_LIST_HEAD(&hdev->mgmt_pending);
17782e58ef3eSJohan Hedberg 
1779ea4bd8baSDavid Miller 	INIT_LIST_HEAD(&hdev->blacklist);
1780f0358568SJohan Hedberg 
17812aeb9a1aSJohan Hedberg 	INIT_LIST_HEAD(&hdev->uuids);
17822aeb9a1aSJohan Hedberg 
178355ed8ca1SJohan Hedberg 	INIT_LIST_HEAD(&hdev->link_keys);
1784b899efafSVinicius Costa Gomes 	INIT_LIST_HEAD(&hdev->long_term_keys);
178555ed8ca1SJohan Hedberg 
17862763eda6SSzymon Janc 	INIT_LIST_HEAD(&hdev->remote_oob_data);
17872763eda6SSzymon Janc 
178876c8686fSAndre Guedes 	INIT_LIST_HEAD(&hdev->adv_entries);
178976c8686fSAndre Guedes 
1790db323f2fSGustavo F. Padovan 	INIT_DELAYED_WORK(&hdev->adv_work, hci_clear_adv_cache);
1791ab81cbf9SJohan Hedberg 	INIT_WORK(&hdev->power_on, hci_power_on);
17923243553fSJohan Hedberg 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
1793ab81cbf9SJohan Hedberg 
179416ab91abSJohan Hedberg 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
179516ab91abSJohan Hedberg 
17961da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
17971da177e4SLinus Torvalds 
17981da177e4SLinus Torvalds 	atomic_set(&hdev->promisc, 0);
17991da177e4SLinus Torvalds 
180028b75a89SAndre Guedes 	INIT_WORK(&hdev->le_scan, le_scan_work);
180128b75a89SAndre Guedes 
18027ba8b4beSAndre Guedes 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
18037ba8b4beSAndre Guedes 
1804f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
18051da177e4SLinus Torvalds 
180632845eb1SGustavo F. Padovan 	hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND |
180732845eb1SGustavo F. Padovan 							WQ_MEM_RECLAIM, 1);
180833ca954dSDavid Herrmann 	if (!hdev->workqueue) {
180933ca954dSDavid Herrmann 		error = -ENOMEM;
181033ca954dSDavid Herrmann 		goto err;
181133ca954dSDavid Herrmann 	}
1812f48fd9c8SMarcel Holtmann 
181333ca954dSDavid Herrmann 	error = hci_add_sysfs(hdev);
181433ca954dSDavid Herrmann 	if (error < 0)
181533ca954dSDavid Herrmann 		goto err_wqueue;
18161da177e4SLinus Torvalds 
1817611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
1818611b30f7SMarcel Holtmann 				RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, hdev);
1819611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
1820611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
1821611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
1822611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
1823611b30f7SMarcel Holtmann 		}
1824611b30f7SMarcel Holtmann 	}
1825611b30f7SMarcel Holtmann 
1826a8b2d5c2SJohan Hedberg 	set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
1827a8b2d5c2SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->dev_flags);
18287f971041SGustavo F. Padovan 	schedule_work(&hdev->power_on);
1829ab81cbf9SJohan Hedberg 
18301da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
1831dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
18321da177e4SLinus Torvalds 
18331da177e4SLinus Torvalds 	return id;
1834f48fd9c8SMarcel Holtmann 
183533ca954dSDavid Herrmann err_wqueue:
183633ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
183733ca954dSDavid Herrmann err:
1838f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
1839f48fd9c8SMarcel Holtmann 	list_del(&hdev->list);
1840f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
1841f48fd9c8SMarcel Holtmann 
184233ca954dSDavid Herrmann 	return error;
18431da177e4SLinus Torvalds }
18441da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
18451da177e4SLinus Torvalds 
18461da177e4SLinus Torvalds /* Unregister HCI device */
184759735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
18481da177e4SLinus Torvalds {
1849ef222013SMarcel Holtmann 	int i;
1850ef222013SMarcel Holtmann 
1851c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
18521da177e4SLinus Torvalds 
1853f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
18541da177e4SLinus Torvalds 	list_del(&hdev->list);
1855f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
18561da177e4SLinus Torvalds 
18571da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
18581da177e4SLinus Torvalds 
1859cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
1860ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
1861ef222013SMarcel Holtmann 
1862ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
1863a8b2d5c2SJohan Hedberg 				!test_bit(HCI_SETUP, &hdev->dev_flags)) {
186409fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
1865744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
186609fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
186756e5cb86SJohan Hedberg 	}
1868ab81cbf9SJohan Hedberg 
18692e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
18702e58ef3eSJohan Hedberg 	 * pending list */
18712e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
18722e58ef3eSJohan Hedberg 
18731da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
18741da177e4SLinus Torvalds 
1875611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
1876611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
1877611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
1878611b30f7SMarcel Holtmann 	}
1879611b30f7SMarcel Holtmann 
1880ce242970SDavid Herrmann 	hci_del_sysfs(hdev);
1881147e2d59SDave Young 
1882db323f2fSGustavo F. Padovan 	cancel_delayed_work_sync(&hdev->adv_work);
1883c6f3c5f7SGustavo F. Padovan 
1884f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
1885f48fd9c8SMarcel Holtmann 
188609fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
1887e2e0cacbSJohan Hedberg 	hci_blacklist_clear(hdev);
18882aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
188955ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
1890b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
18912763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
189276c8686fSAndre Guedes 	hci_adv_entries_clear(hdev);
189309fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
1894e2e0cacbSJohan Hedberg 
1895dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
18961da177e4SLinus Torvalds }
18971da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
18981da177e4SLinus Torvalds 
18991da177e4SLinus Torvalds /* Suspend HCI device */
19001da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
19011da177e4SLinus Torvalds {
19021da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
19031da177e4SLinus Torvalds 	return 0;
19041da177e4SLinus Torvalds }
19051da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
19061da177e4SLinus Torvalds 
19071da177e4SLinus Torvalds /* Resume HCI device */
19081da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
19091da177e4SLinus Torvalds {
19101da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
19111da177e4SLinus Torvalds 	return 0;
19121da177e4SLinus Torvalds }
19131da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
19141da177e4SLinus Torvalds 
191576bca880SMarcel Holtmann /* Receive frame from HCI drivers */
191676bca880SMarcel Holtmann int hci_recv_frame(struct sk_buff *skb)
191776bca880SMarcel Holtmann {
191876bca880SMarcel Holtmann 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
191976bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
192076bca880SMarcel Holtmann 				&& !test_bit(HCI_INIT, &hdev->flags))) {
192176bca880SMarcel Holtmann 		kfree_skb(skb);
192276bca880SMarcel Holtmann 		return -ENXIO;
192376bca880SMarcel Holtmann 	}
192476bca880SMarcel Holtmann 
192576bca880SMarcel Holtmann 	/* Incomming skb */
192676bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
192776bca880SMarcel Holtmann 
192876bca880SMarcel Holtmann 	/* Time stamp */
192976bca880SMarcel Holtmann 	__net_timestamp(skb);
193076bca880SMarcel Holtmann 
193176bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
1932b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
1933c78ae283SMarcel Holtmann 
193476bca880SMarcel Holtmann 	return 0;
193576bca880SMarcel Holtmann }
193676bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
193776bca880SMarcel Holtmann 
193833e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
19391e429f38SGustavo F. Padovan 						  int count, __u8 index)
194033e882a5SSuraj Sumangala {
194133e882a5SSuraj Sumangala 	int len = 0;
194233e882a5SSuraj Sumangala 	int hlen = 0;
194333e882a5SSuraj Sumangala 	int remain = count;
194433e882a5SSuraj Sumangala 	struct sk_buff *skb;
194533e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
194633e882a5SSuraj Sumangala 
194733e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
194833e882a5SSuraj Sumangala 				index >= NUM_REASSEMBLY)
194933e882a5SSuraj Sumangala 		return -EILSEQ;
195033e882a5SSuraj Sumangala 
195133e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
195233e882a5SSuraj Sumangala 
195333e882a5SSuraj Sumangala 	if (!skb) {
195433e882a5SSuraj Sumangala 		switch (type) {
195533e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
195633e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
195733e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
195833e882a5SSuraj Sumangala 			break;
195933e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
196033e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
196133e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
196233e882a5SSuraj Sumangala 			break;
196333e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
196433e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
196533e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
196633e882a5SSuraj Sumangala 			break;
196733e882a5SSuraj Sumangala 		}
196833e882a5SSuraj Sumangala 
19691e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
197033e882a5SSuraj Sumangala 		if (!skb)
197133e882a5SSuraj Sumangala 			return -ENOMEM;
197233e882a5SSuraj Sumangala 
197333e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
197433e882a5SSuraj Sumangala 		scb->expect = hlen;
197533e882a5SSuraj Sumangala 		scb->pkt_type = type;
197633e882a5SSuraj Sumangala 
197733e882a5SSuraj Sumangala 		skb->dev = (void *) hdev;
197833e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
197933e882a5SSuraj Sumangala 	}
198033e882a5SSuraj Sumangala 
198133e882a5SSuraj Sumangala 	while (count) {
198233e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
198389bb46d0SDan Carpenter 		len = min_t(uint, scb->expect, count);
198433e882a5SSuraj Sumangala 
198533e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
198633e882a5SSuraj Sumangala 
198733e882a5SSuraj Sumangala 		count -= len;
198833e882a5SSuraj Sumangala 		data += len;
198933e882a5SSuraj Sumangala 		scb->expect -= len;
199033e882a5SSuraj Sumangala 		remain = count;
199133e882a5SSuraj Sumangala 
199233e882a5SSuraj Sumangala 		switch (type) {
199333e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
199433e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
199533e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
199633e882a5SSuraj Sumangala 				scb->expect = h->plen;
199733e882a5SSuraj Sumangala 
199833e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
199933e882a5SSuraj Sumangala 					kfree_skb(skb);
200033e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
200133e882a5SSuraj Sumangala 					return -ENOMEM;
200233e882a5SSuraj Sumangala 				}
200333e882a5SSuraj Sumangala 			}
200433e882a5SSuraj Sumangala 			break;
200533e882a5SSuraj Sumangala 
200633e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
200733e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
200833e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
200933e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
201033e882a5SSuraj Sumangala 
201133e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
201233e882a5SSuraj Sumangala 					kfree_skb(skb);
201333e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
201433e882a5SSuraj Sumangala 					return -ENOMEM;
201533e882a5SSuraj Sumangala 				}
201633e882a5SSuraj Sumangala 			}
201733e882a5SSuraj Sumangala 			break;
201833e882a5SSuraj Sumangala 
201933e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
202033e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
202133e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
202233e882a5SSuraj Sumangala 				scb->expect = h->dlen;
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 
203333e882a5SSuraj Sumangala 		if (scb->expect == 0) {
203433e882a5SSuraj Sumangala 			/* Complete frame */
203533e882a5SSuraj Sumangala 
203633e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
203733e882a5SSuraj Sumangala 			hci_recv_frame(skb);
203833e882a5SSuraj Sumangala 
203933e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
204033e882a5SSuraj Sumangala 			return remain;
204133e882a5SSuraj Sumangala 		}
204233e882a5SSuraj Sumangala 	}
204333e882a5SSuraj Sumangala 
204433e882a5SSuraj Sumangala 	return remain;
204533e882a5SSuraj Sumangala }
204633e882a5SSuraj Sumangala 
2047ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
2048ef222013SMarcel Holtmann {
2049f39a3c06SSuraj Sumangala 	int rem = 0;
2050f39a3c06SSuraj Sumangala 
2051ef222013SMarcel Holtmann 	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
2052ef222013SMarcel Holtmann 		return -EILSEQ;
2053ef222013SMarcel Holtmann 
2054da5f6c37SGustavo F. Padovan 	while (count) {
20551e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count, type - 1);
2056f39a3c06SSuraj Sumangala 		if (rem < 0)
2057f39a3c06SSuraj Sumangala 			return rem;
2058ef222013SMarcel Holtmann 
2059f39a3c06SSuraj Sumangala 		data += (count - rem);
2060f39a3c06SSuraj Sumangala 		count = rem;
2061f81c6224SJoe Perches 	}
2062ef222013SMarcel Holtmann 
2063f39a3c06SSuraj Sumangala 	return rem;
2064ef222013SMarcel Holtmann }
2065ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment);
2066ef222013SMarcel Holtmann 
206799811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
206899811510SSuraj Sumangala 
206999811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
207099811510SSuraj Sumangala {
207199811510SSuraj Sumangala 	int type;
207299811510SSuraj Sumangala 	int rem = 0;
207399811510SSuraj Sumangala 
2074da5f6c37SGustavo F. Padovan 	while (count) {
207599811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
207699811510SSuraj Sumangala 
207799811510SSuraj Sumangala 		if (!skb) {
207899811510SSuraj Sumangala 			struct { char type; } *pkt;
207999811510SSuraj Sumangala 
208099811510SSuraj Sumangala 			/* Start of the frame */
208199811510SSuraj Sumangala 			pkt = data;
208299811510SSuraj Sumangala 			type = pkt->type;
208399811510SSuraj Sumangala 
208499811510SSuraj Sumangala 			data++;
208599811510SSuraj Sumangala 			count--;
208699811510SSuraj Sumangala 		} else
208799811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
208899811510SSuraj Sumangala 
20891e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
20901e429f38SGustavo F. Padovan 							STREAM_REASSEMBLY);
209199811510SSuraj Sumangala 		if (rem < 0)
209299811510SSuraj Sumangala 			return rem;
209399811510SSuraj Sumangala 
209499811510SSuraj Sumangala 		data += (count - rem);
209599811510SSuraj Sumangala 		count = rem;
2096f81c6224SJoe Perches 	}
209799811510SSuraj Sumangala 
209899811510SSuraj Sumangala 	return rem;
209999811510SSuraj Sumangala }
210099811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
210199811510SSuraj Sumangala 
21021da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
21031da177e4SLinus Torvalds 
21041da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
21051da177e4SLinus Torvalds {
21061da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
21071da177e4SLinus Torvalds 
2108f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
21091da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
2110f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
21111da177e4SLinus Torvalds 
21121da177e4SLinus Torvalds 	return 0;
21131da177e4SLinus Torvalds }
21141da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
21151da177e4SLinus Torvalds 
21161da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
21171da177e4SLinus Torvalds {
21181da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
21191da177e4SLinus Torvalds 
2120f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
21211da177e4SLinus Torvalds 	list_del(&cb->list);
2122f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
21231da177e4SLinus Torvalds 
21241da177e4SLinus Torvalds 	return 0;
21251da177e4SLinus Torvalds }
21261da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
21271da177e4SLinus Torvalds 
21281da177e4SLinus Torvalds static int hci_send_frame(struct sk_buff *skb)
21291da177e4SLinus Torvalds {
21301da177e4SLinus Torvalds 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
21311da177e4SLinus Torvalds 
21321da177e4SLinus Torvalds 	if (!hdev) {
21331da177e4SLinus Torvalds 		kfree_skb(skb);
21341da177e4SLinus Torvalds 		return -ENODEV;
21351da177e4SLinus Torvalds 	}
21361da177e4SLinus Torvalds 
21370d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
21381da177e4SLinus Torvalds 
21391da177e4SLinus Torvalds 	/* Time stamp */
2140a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
21411da177e4SLinus Torvalds 
2142cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
2143cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
2144cd82e61cSMarcel Holtmann 
2145cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
2146cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
2147470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
21481da177e4SLinus Torvalds 	}
21491da177e4SLinus Torvalds 
21501da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
21511da177e4SLinus Torvalds 	skb_orphan(skb);
21521da177e4SLinus Torvalds 
21531da177e4SLinus Torvalds 	return hdev->send(skb);
21541da177e4SLinus Torvalds }
21551da177e4SLinus Torvalds 
21561da177e4SLinus Torvalds /* Send HCI command */
2157a9de9248SMarcel Holtmann int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)
21581da177e4SLinus Torvalds {
21591da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
21601da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
21611da177e4SLinus Torvalds 	struct sk_buff *skb;
21621da177e4SLinus Torvalds 
2163a9de9248SMarcel Holtmann 	BT_DBG("%s opcode 0x%x plen %d", hdev->name, opcode, plen);
21641da177e4SLinus Torvalds 
21651da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
21661da177e4SLinus Torvalds 	if (!skb) {
2167ef222013SMarcel Holtmann 		BT_ERR("%s no memory for command", hdev->name);
21681da177e4SLinus Torvalds 		return -ENOMEM;
21691da177e4SLinus Torvalds 	}
21701da177e4SLinus Torvalds 
21711da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
2172a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
21731da177e4SLinus Torvalds 	hdr->plen   = plen;
21741da177e4SLinus Torvalds 
21751da177e4SLinus Torvalds 	if (plen)
21761da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
21771da177e4SLinus Torvalds 
21781da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
21791da177e4SLinus Torvalds 
21800d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
21811da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
2182c78ae283SMarcel Holtmann 
2183a5040efaSJohan Hedberg 	if (test_bit(HCI_INIT, &hdev->flags))
2184a5040efaSJohan Hedberg 		hdev->init_last_cmd = opcode;
2185a5040efaSJohan Hedberg 
21861da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
2187c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
21881da177e4SLinus Torvalds 
21891da177e4SLinus Torvalds 	return 0;
21901da177e4SLinus Torvalds }
21911da177e4SLinus Torvalds 
21921da177e4SLinus Torvalds /* Get data from the previously sent command */
2193a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
21941da177e4SLinus Torvalds {
21951da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
21961da177e4SLinus Torvalds 
21971da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
21981da177e4SLinus Torvalds 		return NULL;
21991da177e4SLinus Torvalds 
22001da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
22011da177e4SLinus Torvalds 
2202a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
22031da177e4SLinus Torvalds 		return NULL;
22041da177e4SLinus Torvalds 
2205a9de9248SMarcel Holtmann 	BT_DBG("%s opcode 0x%x", hdev->name, opcode);
22061da177e4SLinus Torvalds 
22071da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
22081da177e4SLinus Torvalds }
22091da177e4SLinus Torvalds 
22101da177e4SLinus Torvalds /* Send ACL data */
22111da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
22121da177e4SLinus Torvalds {
22131da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
22141da177e4SLinus Torvalds 	int len = skb->len;
22151da177e4SLinus Torvalds 
2216badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
2217badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
22189c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
2219aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
2220aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
22211da177e4SLinus Torvalds }
22221da177e4SLinus Torvalds 
222373d80debSLuiz Augusto von Dentz static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue,
222473d80debSLuiz Augusto von Dentz 				struct sk_buff *skb, __u16 flags)
22251da177e4SLinus Torvalds {
22261da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
22271da177e4SLinus Torvalds 	struct sk_buff *list;
22281da177e4SLinus Torvalds 
222970f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
223070f23020SAndrei Emeltchenko 	if (!list) {
22311da177e4SLinus Torvalds 		/* Non fragmented */
22321da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
22331da177e4SLinus Torvalds 
223473d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
22351da177e4SLinus Torvalds 	} else {
22361da177e4SLinus Torvalds 		/* Fragmented */
22371da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
22381da177e4SLinus Torvalds 
22391da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
22401da177e4SLinus Torvalds 
22411da177e4SLinus Torvalds 		/* Queue all fragments atomically */
2242af3e6359SGustavo F. Padovan 		spin_lock(&queue->lock);
22431da177e4SLinus Torvalds 
224473d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
2245e702112fSAndrei Emeltchenko 
2246e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
2247e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
22481da177e4SLinus Torvalds 		do {
22491da177e4SLinus Torvalds 			skb = list; list = list->next;
22501da177e4SLinus Torvalds 
22511da177e4SLinus Torvalds 			skb->dev = (void *) hdev;
22520d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2253e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
22541da177e4SLinus Torvalds 
22551da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
22561da177e4SLinus Torvalds 
225773d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
22581da177e4SLinus Torvalds 		} while (list);
22591da177e4SLinus Torvalds 
2260af3e6359SGustavo F. Padovan 		spin_unlock(&queue->lock);
22611da177e4SLinus Torvalds 	}
226273d80debSLuiz Augusto von Dentz }
226373d80debSLuiz Augusto von Dentz 
226473d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
226573d80debSLuiz Augusto von Dentz {
226673d80debSLuiz Augusto von Dentz 	struct hci_conn *conn = chan->conn;
226773d80debSLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
226873d80debSLuiz Augusto von Dentz 
226973d80debSLuiz Augusto von Dentz 	BT_DBG("%s chan %p flags 0x%x", hdev->name, chan, flags);
227073d80debSLuiz Augusto von Dentz 
227173d80debSLuiz Augusto von Dentz 	skb->dev = (void *) hdev;
227273d80debSLuiz Augusto von Dentz 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
227373d80debSLuiz Augusto von Dentz 	hci_add_acl_hdr(skb, conn->handle, flags);
227473d80debSLuiz Augusto von Dentz 
227573d80debSLuiz Augusto von Dentz 	hci_queue_acl(conn, &chan->data_q, skb, flags);
22761da177e4SLinus Torvalds 
22773eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
22781da177e4SLinus Torvalds }
22791da177e4SLinus Torvalds EXPORT_SYMBOL(hci_send_acl);
22801da177e4SLinus Torvalds 
22811da177e4SLinus Torvalds /* Send SCO data */
22820d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
22831da177e4SLinus Torvalds {
22841da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
22851da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
22861da177e4SLinus Torvalds 
22871da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
22881da177e4SLinus Torvalds 
2289aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
22901da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
22911da177e4SLinus Torvalds 
2292badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
2293badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
22949c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
22951da177e4SLinus Torvalds 
22961da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
22970d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
2298c78ae283SMarcel Holtmann 
22991da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
23003eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
23011da177e4SLinus Torvalds }
23021da177e4SLinus Torvalds EXPORT_SYMBOL(hci_send_sco);
23031da177e4SLinus Torvalds 
23041da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
23051da177e4SLinus Torvalds 
23061da177e4SLinus Torvalds /* HCI Connection scheduler */
23071da177e4SLinus Torvalds static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote)
23081da177e4SLinus Torvalds {
23091da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
23108035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
23111da177e4SLinus Torvalds 	int num = 0, min = ~0;
23121da177e4SLinus Torvalds 
23131da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
23141da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
2315bf4c6325SGustavo F. Padovan 
2316bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2317bf4c6325SGustavo F. Padovan 
2318bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2319769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
23201da177e4SLinus Torvalds 			continue;
2321769be974SMarcel Holtmann 
2322769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
2323769be974SMarcel Holtmann 			continue;
2324769be974SMarcel Holtmann 
23251da177e4SLinus Torvalds 		num++;
23261da177e4SLinus Torvalds 
23271da177e4SLinus Torvalds 		if (c->sent < min) {
23281da177e4SLinus Torvalds 			min  = c->sent;
23291da177e4SLinus Torvalds 			conn = c;
23301da177e4SLinus Torvalds 		}
233152087a79SLuiz Augusto von Dentz 
233252087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
233352087a79SLuiz Augusto von Dentz 			break;
23341da177e4SLinus Torvalds 	}
23351da177e4SLinus Torvalds 
2336bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2337bf4c6325SGustavo F. Padovan 
23381da177e4SLinus Torvalds 	if (conn) {
23396ed58ec5SVille Tervo 		int cnt, q;
23406ed58ec5SVille Tervo 
23416ed58ec5SVille Tervo 		switch (conn->type) {
23426ed58ec5SVille Tervo 		case ACL_LINK:
23436ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
23446ed58ec5SVille Tervo 			break;
23456ed58ec5SVille Tervo 		case SCO_LINK:
23466ed58ec5SVille Tervo 		case ESCO_LINK:
23476ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
23486ed58ec5SVille Tervo 			break;
23496ed58ec5SVille Tervo 		case LE_LINK:
23506ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
23516ed58ec5SVille Tervo 			break;
23526ed58ec5SVille Tervo 		default:
23536ed58ec5SVille Tervo 			cnt = 0;
23546ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
23556ed58ec5SVille Tervo 		}
23566ed58ec5SVille Tervo 
23576ed58ec5SVille Tervo 		q = cnt / num;
23581da177e4SLinus Torvalds 		*quote = q ? q : 1;
23591da177e4SLinus Torvalds 	} else
23601da177e4SLinus Torvalds 		*quote = 0;
23611da177e4SLinus Torvalds 
23621da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
23631da177e4SLinus Torvalds 	return conn;
23641da177e4SLinus Torvalds }
23651da177e4SLinus Torvalds 
2366bae1f5d9SVille Tervo static inline void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
23671da177e4SLinus Torvalds {
23681da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
23691da177e4SLinus Torvalds 	struct hci_conn *c;
23701da177e4SLinus Torvalds 
2371bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
23721da177e4SLinus Torvalds 
2373bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2374bf4c6325SGustavo F. Padovan 
23751da177e4SLinus Torvalds 	/* Kill stalled connections */
2376bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2377bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
2378bae1f5d9SVille Tervo 			BT_ERR("%s killing stalled connection %s",
23791da177e4SLinus Torvalds 				hdev->name, batostr(&c->dst));
23801da177e4SLinus Torvalds 			hci_acl_disconn(c, 0x13);
23811da177e4SLinus Torvalds 		}
23821da177e4SLinus Torvalds 	}
2383bf4c6325SGustavo F. Padovan 
2384bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
23851da177e4SLinus Torvalds }
23861da177e4SLinus Torvalds 
238773d80debSLuiz Augusto von Dentz static inline struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
238873d80debSLuiz Augusto von Dentz 						int *quote)
238973d80debSLuiz Augusto von Dentz {
239073d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
239173d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
239273d80debSLuiz Augusto von Dentz 	int num = 0, min = ~0, cur_prio = 0;
239373d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
239473d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
239573d80debSLuiz Augusto von Dentz 
239673d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
239773d80debSLuiz Augusto von Dentz 
2398bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2399bf4c6325SGustavo F. Padovan 
2400bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
240173d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
240273d80debSLuiz Augusto von Dentz 
240373d80debSLuiz Augusto von Dentz 		if (conn->type != type)
240473d80debSLuiz Augusto von Dentz 			continue;
240573d80debSLuiz Augusto von Dentz 
240673d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
240773d80debSLuiz Augusto von Dentz 			continue;
240873d80debSLuiz Augusto von Dentz 
240973d80debSLuiz Augusto von Dentz 		conn_num++;
241073d80debSLuiz Augusto von Dentz 
24118192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
241273d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
241373d80debSLuiz Augusto von Dentz 
241473d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
241573d80debSLuiz Augusto von Dentz 				continue;
241673d80debSLuiz Augusto von Dentz 
241773d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
241873d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
241973d80debSLuiz Augusto von Dentz 				continue;
242073d80debSLuiz Augusto von Dentz 
242173d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
242273d80debSLuiz Augusto von Dentz 				num = 0;
242373d80debSLuiz Augusto von Dentz 				min = ~0;
242473d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
242573d80debSLuiz Augusto von Dentz 			}
242673d80debSLuiz Augusto von Dentz 
242773d80debSLuiz Augusto von Dentz 			num++;
242873d80debSLuiz Augusto von Dentz 
242973d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
243073d80debSLuiz Augusto von Dentz 				min  = conn->sent;
243173d80debSLuiz Augusto von Dentz 				chan = tmp;
243273d80debSLuiz Augusto von Dentz 			}
243373d80debSLuiz Augusto von Dentz 		}
243473d80debSLuiz Augusto von Dentz 
243573d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
243673d80debSLuiz Augusto von Dentz 			break;
243773d80debSLuiz Augusto von Dentz 	}
243873d80debSLuiz Augusto von Dentz 
2439bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2440bf4c6325SGustavo F. Padovan 
244173d80debSLuiz Augusto von Dentz 	if (!chan)
244273d80debSLuiz Augusto von Dentz 		return NULL;
244373d80debSLuiz Augusto von Dentz 
244473d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
244573d80debSLuiz Augusto von Dentz 	case ACL_LINK:
244673d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
244773d80debSLuiz Augusto von Dentz 		break;
244873d80debSLuiz Augusto von Dentz 	case SCO_LINK:
244973d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
245073d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
245173d80debSLuiz Augusto von Dentz 		break;
245273d80debSLuiz Augusto von Dentz 	case LE_LINK:
245373d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
245473d80debSLuiz Augusto von Dentz 		break;
245573d80debSLuiz Augusto von Dentz 	default:
245673d80debSLuiz Augusto von Dentz 		cnt = 0;
245773d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
245873d80debSLuiz Augusto von Dentz 	}
245973d80debSLuiz Augusto von Dentz 
246073d80debSLuiz Augusto von Dentz 	q = cnt / num;
246173d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
246273d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
246373d80debSLuiz Augusto von Dentz 	return chan;
246473d80debSLuiz Augusto von Dentz }
246573d80debSLuiz Augusto von Dentz 
246602b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
246702b20f0bSLuiz Augusto von Dentz {
246802b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
246902b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
247002b20f0bSLuiz Augusto von Dentz 	int num = 0;
247102b20f0bSLuiz Augusto von Dentz 
247202b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
247302b20f0bSLuiz Augusto von Dentz 
2474bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2475bf4c6325SGustavo F. Padovan 
2476bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
247702b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
247802b20f0bSLuiz Augusto von Dentz 
247902b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
248002b20f0bSLuiz Augusto von Dentz 			continue;
248102b20f0bSLuiz Augusto von Dentz 
248202b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
248302b20f0bSLuiz Augusto von Dentz 			continue;
248402b20f0bSLuiz Augusto von Dentz 
248502b20f0bSLuiz Augusto von Dentz 		num++;
248602b20f0bSLuiz Augusto von Dentz 
24878192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
248802b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
248902b20f0bSLuiz Augusto von Dentz 
249002b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
249102b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
249202b20f0bSLuiz Augusto von Dentz 				continue;
249302b20f0bSLuiz Augusto von Dentz 			}
249402b20f0bSLuiz Augusto von Dentz 
249502b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
249602b20f0bSLuiz Augusto von Dentz 				continue;
249702b20f0bSLuiz Augusto von Dentz 
249802b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
249902b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
250002b20f0bSLuiz Augusto von Dentz 				continue;
250102b20f0bSLuiz Augusto von Dentz 
250202b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
250302b20f0bSLuiz Augusto von Dentz 
250402b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
250502b20f0bSLuiz Augusto von Dentz 								skb->priority);
250602b20f0bSLuiz Augusto von Dentz 		}
250702b20f0bSLuiz Augusto von Dentz 
250802b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
250902b20f0bSLuiz Augusto von Dentz 			break;
251002b20f0bSLuiz Augusto von Dentz 	}
2511bf4c6325SGustavo F. Padovan 
2512bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2513bf4c6325SGustavo F. Padovan 
251402b20f0bSLuiz Augusto von Dentz }
251502b20f0bSLuiz Augusto von Dentz 
2516b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
2517b71d385aSAndrei Emeltchenko {
2518b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
2519b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
2520b71d385aSAndrei Emeltchenko }
2521b71d385aSAndrei Emeltchenko 
252263d2bc1bSAndrei Emeltchenko static inline void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
25231da177e4SLinus Torvalds {
25241da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
25251da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
25261da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
252763d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
2528cc48dc0aSAndrei Emeltchenko 					msecs_to_jiffies(HCI_ACL_TX_TIMEOUT)))
2529bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
25301da177e4SLinus Torvalds 	}
253163d2bc1bSAndrei Emeltchenko }
25321da177e4SLinus Torvalds 
253363d2bc1bSAndrei Emeltchenko static inline void hci_sched_acl_pkt(struct hci_dev *hdev)
253463d2bc1bSAndrei Emeltchenko {
253563d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
253663d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
253763d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
253863d2bc1bSAndrei Emeltchenko 	int quote;
253963d2bc1bSAndrei Emeltchenko 
254063d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
254104837f64SMarcel Holtmann 
254273d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
254373d80debSLuiz Augusto von Dentz 			(chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
2544ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
2545ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
254673d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
254773d80debSLuiz Augusto von Dentz 					skb->len, skb->priority);
254873d80debSLuiz Augusto von Dentz 
2549ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
2550ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
2551ec1cce24SLuiz Augusto von Dentz 				break;
2552ec1cce24SLuiz Augusto von Dentz 
2553ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
2554ec1cce24SLuiz Augusto von Dentz 
255573d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
255673d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
255704837f64SMarcel Holtmann 
25581da177e4SLinus Torvalds 			hci_send_frame(skb);
25591da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
25601da177e4SLinus Torvalds 
25611da177e4SLinus Torvalds 			hdev->acl_cnt--;
256273d80debSLuiz Augusto von Dentz 			chan->sent++;
256373d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
25641da177e4SLinus Torvalds 		}
25651da177e4SLinus Torvalds 	}
256602b20f0bSLuiz Augusto von Dentz 
256702b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
256802b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
25691da177e4SLinus Torvalds }
25701da177e4SLinus Torvalds 
2571b71d385aSAndrei Emeltchenko static inline void hci_sched_acl_blk(struct hci_dev *hdev)
2572b71d385aSAndrei Emeltchenko {
257363d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
2574b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
2575b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
2576b71d385aSAndrei Emeltchenko 	int quote;
2577b71d385aSAndrei Emeltchenko 
257863d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
2579b71d385aSAndrei Emeltchenko 
2580b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
2581b71d385aSAndrei Emeltchenko 			(chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
2582b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
2583b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
2584b71d385aSAndrei Emeltchenko 			int blocks;
2585b71d385aSAndrei Emeltchenko 
2586b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
2587b71d385aSAndrei Emeltchenko 						skb->len, skb->priority);
2588b71d385aSAndrei Emeltchenko 
2589b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
2590b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
2591b71d385aSAndrei Emeltchenko 				break;
2592b71d385aSAndrei Emeltchenko 
2593b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
2594b71d385aSAndrei Emeltchenko 
2595b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
2596b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
2597b71d385aSAndrei Emeltchenko 				return;
2598b71d385aSAndrei Emeltchenko 
2599b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
2600b71d385aSAndrei Emeltchenko 						bt_cb(skb)->force_active);
2601b71d385aSAndrei Emeltchenko 
2602b71d385aSAndrei Emeltchenko 			hci_send_frame(skb);
2603b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
2604b71d385aSAndrei Emeltchenko 
2605b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
2606b71d385aSAndrei Emeltchenko 			quote -= blocks;
2607b71d385aSAndrei Emeltchenko 
2608b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
2609b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
2610b71d385aSAndrei Emeltchenko 		}
2611b71d385aSAndrei Emeltchenko 	}
2612b71d385aSAndrei Emeltchenko 
2613b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
2614b71d385aSAndrei Emeltchenko 		hci_prio_recalculate(hdev, ACL_LINK);
2615b71d385aSAndrei Emeltchenko }
2616b71d385aSAndrei Emeltchenko 
2617b71d385aSAndrei Emeltchenko static inline void hci_sched_acl(struct hci_dev *hdev)
2618b71d385aSAndrei Emeltchenko {
2619b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
2620b71d385aSAndrei Emeltchenko 
2621b71d385aSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK))
2622b71d385aSAndrei Emeltchenko 		return;
2623b71d385aSAndrei Emeltchenko 
2624b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
2625b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
2626b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
2627b71d385aSAndrei Emeltchenko 		break;
2628b71d385aSAndrei Emeltchenko 
2629b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
2630b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
2631b71d385aSAndrei Emeltchenko 		break;
2632b71d385aSAndrei Emeltchenko 	}
2633b71d385aSAndrei Emeltchenko }
2634b71d385aSAndrei Emeltchenko 
26351da177e4SLinus Torvalds /* Schedule SCO */
26361da177e4SLinus Torvalds static inline void hci_sched_sco(struct hci_dev *hdev)
26371da177e4SLinus Torvalds {
26381da177e4SLinus Torvalds 	struct hci_conn *conn;
26391da177e4SLinus Torvalds 	struct sk_buff *skb;
26401da177e4SLinus Torvalds 	int quote;
26411da177e4SLinus Torvalds 
26421da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
26431da177e4SLinus Torvalds 
264452087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
264552087a79SLuiz Augusto von Dentz 		return;
264652087a79SLuiz Augusto von Dentz 
26471da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
26481da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
26491da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
26501da177e4SLinus Torvalds 			hci_send_frame(skb);
26511da177e4SLinus Torvalds 
26521da177e4SLinus Torvalds 			conn->sent++;
26531da177e4SLinus Torvalds 			if (conn->sent == ~0)
26541da177e4SLinus Torvalds 				conn->sent = 0;
26551da177e4SLinus Torvalds 		}
26561da177e4SLinus Torvalds 	}
26571da177e4SLinus Torvalds }
26581da177e4SLinus Torvalds 
2659b6a0dc82SMarcel Holtmann static inline void hci_sched_esco(struct hci_dev *hdev)
2660b6a0dc82SMarcel Holtmann {
2661b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
2662b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
2663b6a0dc82SMarcel Holtmann 	int quote;
2664b6a0dc82SMarcel Holtmann 
2665b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
2666b6a0dc82SMarcel Holtmann 
266752087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
266852087a79SLuiz Augusto von Dentz 		return;
266952087a79SLuiz Augusto von Dentz 
2670b6a0dc82SMarcel Holtmann 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, &quote))) {
2671b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
2672b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
2673b6a0dc82SMarcel Holtmann 			hci_send_frame(skb);
2674b6a0dc82SMarcel Holtmann 
2675b6a0dc82SMarcel Holtmann 			conn->sent++;
2676b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
2677b6a0dc82SMarcel Holtmann 				conn->sent = 0;
2678b6a0dc82SMarcel Holtmann 		}
2679b6a0dc82SMarcel Holtmann 	}
2680b6a0dc82SMarcel Holtmann }
2681b6a0dc82SMarcel Holtmann 
26826ed58ec5SVille Tervo static inline void hci_sched_le(struct hci_dev *hdev)
26836ed58ec5SVille Tervo {
268473d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
26856ed58ec5SVille Tervo 	struct sk_buff *skb;
268602b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
26876ed58ec5SVille Tervo 
26886ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
26896ed58ec5SVille Tervo 
269052087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
269152087a79SLuiz Augusto von Dentz 		return;
269252087a79SLuiz Augusto von Dentz 
26936ed58ec5SVille Tervo 	if (!test_bit(HCI_RAW, &hdev->flags)) {
26946ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
26956ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
2696bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
26976ed58ec5SVille Tervo 				time_after(jiffies, hdev->le_last_tx + HZ * 45))
2698bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
26996ed58ec5SVille Tervo 	}
27006ed58ec5SVille Tervo 
27016ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
270202b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
270373d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
2704ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
2705ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
270673d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
270773d80debSLuiz Augusto von Dentz 					skb->len, skb->priority);
27086ed58ec5SVille Tervo 
2709ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
2710ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
2711ec1cce24SLuiz Augusto von Dentz 				break;
2712ec1cce24SLuiz Augusto von Dentz 
2713ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
2714ec1cce24SLuiz Augusto von Dentz 
27156ed58ec5SVille Tervo 			hci_send_frame(skb);
27166ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
27176ed58ec5SVille Tervo 
27186ed58ec5SVille Tervo 			cnt--;
271973d80debSLuiz Augusto von Dentz 			chan->sent++;
272073d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
27216ed58ec5SVille Tervo 		}
27226ed58ec5SVille Tervo 	}
272373d80debSLuiz Augusto von Dentz 
27246ed58ec5SVille Tervo 	if (hdev->le_pkts)
27256ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
27266ed58ec5SVille Tervo 	else
27276ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
272802b20f0bSLuiz Augusto von Dentz 
272902b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
273002b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
27316ed58ec5SVille Tervo }
27326ed58ec5SVille Tervo 
27333eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
27341da177e4SLinus Torvalds {
27353eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
27361da177e4SLinus Torvalds 	struct sk_buff *skb;
27371da177e4SLinus Torvalds 
27386ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
27396ed58ec5SVille Tervo 		hdev->sco_cnt, hdev->le_cnt);
27401da177e4SLinus Torvalds 
27411da177e4SLinus Torvalds 	/* Schedule queues and send stuff to HCI driver */
27421da177e4SLinus Torvalds 
27431da177e4SLinus Torvalds 	hci_sched_acl(hdev);
27441da177e4SLinus Torvalds 
27451da177e4SLinus Torvalds 	hci_sched_sco(hdev);
27461da177e4SLinus Torvalds 
2747b6a0dc82SMarcel Holtmann 	hci_sched_esco(hdev);
2748b6a0dc82SMarcel Holtmann 
27496ed58ec5SVille Tervo 	hci_sched_le(hdev);
27506ed58ec5SVille Tervo 
27511da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
27521da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
27531da177e4SLinus Torvalds 		hci_send_frame(skb);
27541da177e4SLinus Torvalds }
27551da177e4SLinus Torvalds 
275625985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
27571da177e4SLinus Torvalds 
27581da177e4SLinus Torvalds /* ACL data packet */
27591da177e4SLinus Torvalds static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
27601da177e4SLinus Torvalds {
27611da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
27621da177e4SLinus Torvalds 	struct hci_conn *conn;
27631da177e4SLinus Torvalds 	__u16 handle, flags;
27641da177e4SLinus Torvalds 
27651da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
27661da177e4SLinus Torvalds 
27671da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
27681da177e4SLinus Torvalds 	flags  = hci_flags(handle);
27691da177e4SLinus Torvalds 	handle = hci_handle(handle);
27701da177e4SLinus Torvalds 
27711da177e4SLinus Torvalds 	BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags);
27721da177e4SLinus Torvalds 
27731da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
27741da177e4SLinus Torvalds 
27751da177e4SLinus Torvalds 	hci_dev_lock(hdev);
27761da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
27771da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
27781da177e4SLinus Torvalds 
27791da177e4SLinus Torvalds 	if (conn) {
278065983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
278104837f64SMarcel Holtmann 
27821da177e4SLinus Torvalds 		/* Send to upper protocol */
2783686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
27841da177e4SLinus Torvalds 		return;
27851da177e4SLinus Torvalds 	} else {
27861da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
27871da177e4SLinus Torvalds 			hdev->name, handle);
27881da177e4SLinus Torvalds 	}
27891da177e4SLinus Torvalds 
27901da177e4SLinus Torvalds 	kfree_skb(skb);
27911da177e4SLinus Torvalds }
27921da177e4SLinus Torvalds 
27931da177e4SLinus Torvalds /* SCO data packet */
27941da177e4SLinus Torvalds static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
27951da177e4SLinus Torvalds {
27961da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
27971da177e4SLinus Torvalds 	struct hci_conn *conn;
27981da177e4SLinus Torvalds 	__u16 handle;
27991da177e4SLinus Torvalds 
28001da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
28011da177e4SLinus Torvalds 
28021da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
28031da177e4SLinus Torvalds 
28041da177e4SLinus Torvalds 	BT_DBG("%s len %d handle 0x%x", hdev->name, skb->len, handle);
28051da177e4SLinus Torvalds 
28061da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
28071da177e4SLinus Torvalds 
28081da177e4SLinus Torvalds 	hci_dev_lock(hdev);
28091da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
28101da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
28111da177e4SLinus Torvalds 
28121da177e4SLinus Torvalds 	if (conn) {
28131da177e4SLinus Torvalds 		/* Send to upper protocol */
2814686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
28151da177e4SLinus Torvalds 		return;
28161da177e4SLinus Torvalds 	} else {
28171da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
28181da177e4SLinus Torvalds 			hdev->name, handle);
28191da177e4SLinus Torvalds 	}
28201da177e4SLinus Torvalds 
28211da177e4SLinus Torvalds 	kfree_skb(skb);
28221da177e4SLinus Torvalds }
28231da177e4SLinus Torvalds 
2824b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
28251da177e4SLinus Torvalds {
2826b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
28271da177e4SLinus Torvalds 	struct sk_buff *skb;
28281da177e4SLinus Torvalds 
28291da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
28301da177e4SLinus Torvalds 
28311da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
2832cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
2833cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
2834cd82e61cSMarcel Holtmann 
28351da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
28361da177e4SLinus Torvalds 			/* Send copy to the sockets */
2837470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
28381da177e4SLinus Torvalds 		}
28391da177e4SLinus Torvalds 
28401da177e4SLinus Torvalds 		if (test_bit(HCI_RAW, &hdev->flags)) {
28411da177e4SLinus Torvalds 			kfree_skb(skb);
28421da177e4SLinus Torvalds 			continue;
28431da177e4SLinus Torvalds 		}
28441da177e4SLinus Torvalds 
28451da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
28461da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
28470d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
28481da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
28491da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
28501da177e4SLinus Torvalds 				kfree_skb(skb);
28511da177e4SLinus Torvalds 				continue;
28523ff50b79SStephen Hemminger 			}
28531da177e4SLinus Torvalds 		}
28541da177e4SLinus Torvalds 
28551da177e4SLinus Torvalds 		/* Process frame */
28560d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
28571da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
2858b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
28591da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
28601da177e4SLinus Torvalds 			break;
28611da177e4SLinus Torvalds 
28621da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
28631da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
28641da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
28651da177e4SLinus Torvalds 			break;
28661da177e4SLinus Torvalds 
28671da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
28681da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
28691da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
28701da177e4SLinus Torvalds 			break;
28711da177e4SLinus Torvalds 
28721da177e4SLinus Torvalds 		default:
28731da177e4SLinus Torvalds 			kfree_skb(skb);
28741da177e4SLinus Torvalds 			break;
28751da177e4SLinus Torvalds 		}
28761da177e4SLinus Torvalds 	}
28771da177e4SLinus Torvalds }
28781da177e4SLinus Torvalds 
2879c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
28801da177e4SLinus Torvalds {
2881c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
28821da177e4SLinus Torvalds 	struct sk_buff *skb;
28831da177e4SLinus Torvalds 
28841da177e4SLinus Torvalds 	BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
28851da177e4SLinus Torvalds 
28861da177e4SLinus Torvalds 	/* Send queued commands */
28875a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
28885a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
28895a08ecceSAndrei Emeltchenko 		if (!skb)
28905a08ecceSAndrei Emeltchenko 			return;
28915a08ecceSAndrei Emeltchenko 
28921da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
28931da177e4SLinus Torvalds 
289470f23020SAndrei Emeltchenko 		hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC);
289570f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
28961da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
28971da177e4SLinus Torvalds 			hci_send_frame(skb);
28987bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
28997bdb8a5cSSzymon Janc 				del_timer(&hdev->cmd_timer);
29007bdb8a5cSSzymon Janc 			else
29016bd32326SVille Tervo 				mod_timer(&hdev->cmd_timer,
29026bd32326SVille Tervo 				  jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT));
29031da177e4SLinus Torvalds 		} else {
29041da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
2905c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
29061da177e4SLinus Torvalds 		}
29071da177e4SLinus Torvalds 	}
29081da177e4SLinus Torvalds }
29092519a1fcSAndre Guedes 
29102519a1fcSAndre Guedes int hci_do_inquiry(struct hci_dev *hdev, u8 length)
29112519a1fcSAndre Guedes {
29122519a1fcSAndre Guedes 	/* General inquiry access code (GIAC) */
29132519a1fcSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
29142519a1fcSAndre Guedes 	struct hci_cp_inquiry cp;
29152519a1fcSAndre Guedes 
29162519a1fcSAndre Guedes 	BT_DBG("%s", hdev->name);
29172519a1fcSAndre Guedes 
29182519a1fcSAndre Guedes 	if (test_bit(HCI_INQUIRY, &hdev->flags))
29192519a1fcSAndre Guedes 		return -EINPROGRESS;
29202519a1fcSAndre Guedes 
29214663262cSJohan Hedberg 	inquiry_cache_flush(hdev);
29224663262cSJohan Hedberg 
29232519a1fcSAndre Guedes 	memset(&cp, 0, sizeof(cp));
29242519a1fcSAndre Guedes 	memcpy(&cp.lap, lap, sizeof(cp.lap));
29252519a1fcSAndre Guedes 	cp.length  = length;
29262519a1fcSAndre Guedes 
29272519a1fcSAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
29282519a1fcSAndre Guedes }
2929023d5049SAndre Guedes 
2930023d5049SAndre Guedes int hci_cancel_inquiry(struct hci_dev *hdev)
2931023d5049SAndre Guedes {
2932023d5049SAndre Guedes 	BT_DBG("%s", hdev->name);
2933023d5049SAndre Guedes 
2934023d5049SAndre Guedes 	if (!test_bit(HCI_INQUIRY, &hdev->flags))
2935023d5049SAndre Guedes 		return -EPERM;
2936023d5049SAndre Guedes 
2937023d5049SAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL);
2938023d5049SAndre Guedes }
2939