xref: /openbmc/linux/net/bluetooth/hci_core.c (revision b71d385a)
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>
431da177e4SLinus Torvalds #include <linux/notifier.h>
44611b30f7SMarcel Holtmann #include <linux/rfkill.h>
456bd32326SVille Tervo #include <linux/timer.h>
463a0259bbSVinicius Costa Gomes #include <linux/crypto.h>
471da177e4SLinus Torvalds #include <net/sock.h>
481da177e4SLinus Torvalds 
491da177e4SLinus Torvalds #include <asm/system.h>
5070f23020SAndrei Emeltchenko #include <linux/uaccess.h>
511da177e4SLinus Torvalds #include <asm/unaligned.h>
521da177e4SLinus Torvalds 
531da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
541da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
551da177e4SLinus Torvalds 
56ab81cbf9SJohan Hedberg #define AUTO_OFF_TIMEOUT 2000
57ab81cbf9SJohan Hedberg 
588b281b9cSFabio Estevam bool enable_hs;
597784d78fSAndrei Emeltchenko 
60b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work);
61c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work);
623eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work);
631da177e4SLinus Torvalds 
641da177e4SLinus Torvalds /* HCI device list */
651da177e4SLinus Torvalds LIST_HEAD(hci_dev_list);
661da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock);
671da177e4SLinus Torvalds 
681da177e4SLinus Torvalds /* HCI callback list */
691da177e4SLinus Torvalds LIST_HEAD(hci_cb_list);
701da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock);
711da177e4SLinus Torvalds 
721da177e4SLinus Torvalds /* HCI notifiers list */
73e041c683SAlan Stern static ATOMIC_NOTIFIER_HEAD(hci_notifier);
741da177e4SLinus Torvalds 
751da177e4SLinus Torvalds /* ---- HCI notifications ---- */
761da177e4SLinus Torvalds 
771da177e4SLinus Torvalds int hci_register_notifier(struct notifier_block *nb)
781da177e4SLinus Torvalds {
79e041c683SAlan Stern 	return atomic_notifier_chain_register(&hci_notifier, nb);
801da177e4SLinus Torvalds }
811da177e4SLinus Torvalds 
821da177e4SLinus Torvalds int hci_unregister_notifier(struct notifier_block *nb)
831da177e4SLinus Torvalds {
84e041c683SAlan Stern 	return atomic_notifier_chain_unregister(&hci_notifier, nb);
851da177e4SLinus Torvalds }
861da177e4SLinus Torvalds 
876516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event)
881da177e4SLinus Torvalds {
89e041c683SAlan Stern 	atomic_notifier_call_chain(&hci_notifier, event, hdev);
901da177e4SLinus Torvalds }
911da177e4SLinus Torvalds 
921da177e4SLinus Torvalds /* ---- HCI requests ---- */
931da177e4SLinus Torvalds 
9423bb5763SJohan Hedberg void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result)
951da177e4SLinus Torvalds {
9623bb5763SJohan Hedberg 	BT_DBG("%s command 0x%04x result 0x%2.2x", hdev->name, cmd, result);
9723bb5763SJohan Hedberg 
98a5040efaSJohan Hedberg 	/* If this is the init phase check if the completed command matches
99a5040efaSJohan Hedberg 	 * the last init command, and if not just return.
100a5040efaSJohan Hedberg 	 */
101a5040efaSJohan Hedberg 	if (test_bit(HCI_INIT, &hdev->flags) && hdev->init_last_cmd != cmd)
10223bb5763SJohan Hedberg 		return;
1031da177e4SLinus Torvalds 
1041da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
1051da177e4SLinus Torvalds 		hdev->req_result = result;
1061da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_DONE;
1071da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
1081da177e4SLinus Torvalds 	}
1091da177e4SLinus Torvalds }
1101da177e4SLinus Torvalds 
1111da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err)
1121da177e4SLinus Torvalds {
1131da177e4SLinus Torvalds 	BT_DBG("%s err 0x%2.2x", hdev->name, err);
1141da177e4SLinus Torvalds 
1151da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
1161da177e4SLinus Torvalds 		hdev->req_result = err;
1171da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_CANCELED;
1181da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
1191da177e4SLinus Torvalds 	}
1201da177e4SLinus Torvalds }
1211da177e4SLinus Torvalds 
1221da177e4SLinus Torvalds /* Execute request and wait for completion. */
1231da177e4SLinus Torvalds static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt),
1241da177e4SLinus Torvalds 					unsigned long opt, __u32 timeout)
1251da177e4SLinus Torvalds {
1261da177e4SLinus Torvalds 	DECLARE_WAITQUEUE(wait, current);
1271da177e4SLinus Torvalds 	int err = 0;
1281da177e4SLinus Torvalds 
1291da177e4SLinus Torvalds 	BT_DBG("%s start", hdev->name);
1301da177e4SLinus Torvalds 
1311da177e4SLinus Torvalds 	hdev->req_status = HCI_REQ_PEND;
1321da177e4SLinus Torvalds 
1331da177e4SLinus Torvalds 	add_wait_queue(&hdev->req_wait_q, &wait);
1341da177e4SLinus Torvalds 	set_current_state(TASK_INTERRUPTIBLE);
1351da177e4SLinus Torvalds 
1361da177e4SLinus Torvalds 	req(hdev, opt);
1371da177e4SLinus Torvalds 	schedule_timeout(timeout);
1381da177e4SLinus Torvalds 
1391da177e4SLinus Torvalds 	remove_wait_queue(&hdev->req_wait_q, &wait);
1401da177e4SLinus Torvalds 
1411da177e4SLinus Torvalds 	if (signal_pending(current))
1421da177e4SLinus Torvalds 		return -EINTR;
1431da177e4SLinus Torvalds 
1441da177e4SLinus Torvalds 	switch (hdev->req_status) {
1451da177e4SLinus Torvalds 	case HCI_REQ_DONE:
146e175072fSJoe Perches 		err = -bt_to_errno(hdev->req_result);
1471da177e4SLinus Torvalds 		break;
1481da177e4SLinus Torvalds 
1491da177e4SLinus Torvalds 	case HCI_REQ_CANCELED:
1501da177e4SLinus Torvalds 		err = -hdev->req_result;
1511da177e4SLinus Torvalds 		break;
1521da177e4SLinus Torvalds 
1531da177e4SLinus Torvalds 	default:
1541da177e4SLinus Torvalds 		err = -ETIMEDOUT;
1551da177e4SLinus Torvalds 		break;
1563ff50b79SStephen Hemminger 	}
1571da177e4SLinus Torvalds 
158a5040efaSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
1591da177e4SLinus Torvalds 
1601da177e4SLinus Torvalds 	BT_DBG("%s end: err %d", hdev->name, err);
1611da177e4SLinus Torvalds 
1621da177e4SLinus Torvalds 	return err;
1631da177e4SLinus Torvalds }
1641da177e4SLinus Torvalds 
1651da177e4SLinus Torvalds static inline int hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt),
1661da177e4SLinus Torvalds 					unsigned long opt, __u32 timeout)
1671da177e4SLinus Torvalds {
1681da177e4SLinus Torvalds 	int ret;
1691da177e4SLinus Torvalds 
1707c6a329eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
1717c6a329eSMarcel Holtmann 		return -ENETDOWN;
1727c6a329eSMarcel Holtmann 
1731da177e4SLinus Torvalds 	/* Serialize all requests */
1741da177e4SLinus Torvalds 	hci_req_lock(hdev);
1751da177e4SLinus Torvalds 	ret = __hci_request(hdev, req, opt, timeout);
1761da177e4SLinus Torvalds 	hci_req_unlock(hdev);
1771da177e4SLinus Torvalds 
1781da177e4SLinus Torvalds 	return ret;
1791da177e4SLinus Torvalds }
1801da177e4SLinus Torvalds 
1811da177e4SLinus Torvalds static void hci_reset_req(struct hci_dev *hdev, unsigned long opt)
1821da177e4SLinus Torvalds {
1831da177e4SLinus Torvalds 	BT_DBG("%s %ld", hdev->name, opt);
1841da177e4SLinus Torvalds 
1851da177e4SLinus Torvalds 	/* Reset device */
186f630cf0dSGustavo F. Padovan 	set_bit(HCI_RESET, &hdev->flags);
187a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
1881da177e4SLinus Torvalds }
1891da177e4SLinus Torvalds 
190e61ef499SAndrei Emeltchenko static void bredr_init(struct hci_dev *hdev)
1911da177e4SLinus Torvalds {
192b0916ea0SJohan Hedberg 	struct hci_cp_delete_stored_link_key cp;
1931ebb9252SMarcel Holtmann 	__le16 param;
19489f2783dSMarcel Holtmann 	__u8 flt_type;
1951da177e4SLinus Torvalds 
1962455a3eaSAndrei Emeltchenko 	hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
1972455a3eaSAndrei Emeltchenko 
1981da177e4SLinus Torvalds 	/* Mandatory initialization */
1991da177e4SLinus Torvalds 
2001da177e4SLinus Torvalds 	/* Reset */
201f630cf0dSGustavo F. Padovan 	if (!test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) {
202f630cf0dSGustavo F. Padovan 		set_bit(HCI_RESET, &hdev->flags);
203a9de9248SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
204f630cf0dSGustavo F. Padovan 	}
2051da177e4SLinus Torvalds 
2061da177e4SLinus Torvalds 	/* Read Local Supported Features */
207a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
2081da177e4SLinus Torvalds 
2091143e5a6SMarcel Holtmann 	/* Read Local Version */
210a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
2111143e5a6SMarcel Holtmann 
2121da177e4SLinus Torvalds 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
213a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
2141da177e4SLinus Torvalds 
2151da177e4SLinus Torvalds 	/* Read BD Address */
216a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL);
217a9de9248SMarcel Holtmann 
218a9de9248SMarcel Holtmann 	/* Read Class of Device */
219a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
220a9de9248SMarcel Holtmann 
221a9de9248SMarcel Holtmann 	/* Read Local Name */
222a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL);
2231da177e4SLinus Torvalds 
2241da177e4SLinus Torvalds 	/* Read Voice Setting */
225a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL);
2261da177e4SLinus Torvalds 
2271da177e4SLinus Torvalds 	/* Optional initialization */
2281da177e4SLinus Torvalds 
2291da177e4SLinus Torvalds 	/* Clear Event Filters */
23089f2783dSMarcel Holtmann 	flt_type = HCI_FLT_CLEAR_ALL;
231a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
2321da177e4SLinus Torvalds 
2331da177e4SLinus Torvalds 	/* Connection accept timeout ~20 secs */
234aca3192cSYOSHIFUJI Hideaki 	param = cpu_to_le16(0x7d00);
235a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
236b0916ea0SJohan Hedberg 
237b0916ea0SJohan Hedberg 	bacpy(&cp.bdaddr, BDADDR_ANY);
238b0916ea0SJohan Hedberg 	cp.delete_all = 1;
239b0916ea0SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp);
2401da177e4SLinus Torvalds }
2411da177e4SLinus Torvalds 
242e61ef499SAndrei Emeltchenko static void amp_init(struct hci_dev *hdev)
243e61ef499SAndrei Emeltchenko {
2442455a3eaSAndrei Emeltchenko 	hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
2452455a3eaSAndrei Emeltchenko 
246e61ef499SAndrei Emeltchenko 	/* Reset */
247e61ef499SAndrei Emeltchenko 	hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
248e61ef499SAndrei Emeltchenko 
249e61ef499SAndrei Emeltchenko 	/* Read Local Version */
250e61ef499SAndrei Emeltchenko 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
251e61ef499SAndrei Emeltchenko }
252e61ef499SAndrei Emeltchenko 
253e61ef499SAndrei Emeltchenko static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
254e61ef499SAndrei Emeltchenko {
255e61ef499SAndrei Emeltchenko 	struct sk_buff *skb;
256e61ef499SAndrei Emeltchenko 
257e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
258e61ef499SAndrei Emeltchenko 
259e61ef499SAndrei Emeltchenko 	/* Driver initialization */
260e61ef499SAndrei Emeltchenko 
261e61ef499SAndrei Emeltchenko 	/* Special commands */
262e61ef499SAndrei Emeltchenko 	while ((skb = skb_dequeue(&hdev->driver_init))) {
263e61ef499SAndrei Emeltchenko 		bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
264e61ef499SAndrei Emeltchenko 		skb->dev = (void *) hdev;
265e61ef499SAndrei Emeltchenko 
266e61ef499SAndrei Emeltchenko 		skb_queue_tail(&hdev->cmd_q, skb);
267e61ef499SAndrei Emeltchenko 		queue_work(hdev->workqueue, &hdev->cmd_work);
268e61ef499SAndrei Emeltchenko 	}
269e61ef499SAndrei Emeltchenko 	skb_queue_purge(&hdev->driver_init);
270e61ef499SAndrei Emeltchenko 
271e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
272e61ef499SAndrei Emeltchenko 	case HCI_BREDR:
273e61ef499SAndrei Emeltchenko 		bredr_init(hdev);
274e61ef499SAndrei Emeltchenko 		break;
275e61ef499SAndrei Emeltchenko 
276e61ef499SAndrei Emeltchenko 	case HCI_AMP:
277e61ef499SAndrei Emeltchenko 		amp_init(hdev);
278e61ef499SAndrei Emeltchenko 		break;
279e61ef499SAndrei Emeltchenko 
280e61ef499SAndrei Emeltchenko 	default:
281e61ef499SAndrei Emeltchenko 		BT_ERR("Unknown device type %d", hdev->dev_type);
282e61ef499SAndrei Emeltchenko 		break;
283e61ef499SAndrei Emeltchenko 	}
284e61ef499SAndrei Emeltchenko 
285e61ef499SAndrei Emeltchenko }
286e61ef499SAndrei Emeltchenko 
2876ed58ec5SVille Tervo static void hci_le_init_req(struct hci_dev *hdev, unsigned long opt)
2886ed58ec5SVille Tervo {
2896ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
2906ed58ec5SVille Tervo 
2916ed58ec5SVille Tervo 	/* Read LE buffer size */
2926ed58ec5SVille Tervo 	hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
2936ed58ec5SVille Tervo }
2946ed58ec5SVille Tervo 
2951da177e4SLinus Torvalds static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
2961da177e4SLinus Torvalds {
2971da177e4SLinus Torvalds 	__u8 scan = opt;
2981da177e4SLinus Torvalds 
2991da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, scan);
3001da177e4SLinus Torvalds 
3011da177e4SLinus Torvalds 	/* Inquiry and Page scans */
302a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
3031da177e4SLinus Torvalds }
3041da177e4SLinus Torvalds 
3051da177e4SLinus Torvalds static void hci_auth_req(struct hci_dev *hdev, unsigned long opt)
3061da177e4SLinus Torvalds {
3071da177e4SLinus Torvalds 	__u8 auth = opt;
3081da177e4SLinus Torvalds 
3091da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, auth);
3101da177e4SLinus Torvalds 
3111da177e4SLinus Torvalds 	/* Authentication */
312a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
3131da177e4SLinus Torvalds }
3141da177e4SLinus Torvalds 
3151da177e4SLinus Torvalds static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt)
3161da177e4SLinus Torvalds {
3171da177e4SLinus Torvalds 	__u8 encrypt = opt;
3181da177e4SLinus Torvalds 
3191da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, encrypt);
3201da177e4SLinus Torvalds 
321e4e8e37cSMarcel Holtmann 	/* Encryption */
322a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
3231da177e4SLinus Torvalds }
3241da177e4SLinus Torvalds 
325e4e8e37cSMarcel Holtmann static void hci_linkpol_req(struct hci_dev *hdev, unsigned long opt)
326e4e8e37cSMarcel Holtmann {
327e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
328e4e8e37cSMarcel Holtmann 
329a418b893SMarcel Holtmann 	BT_DBG("%s %x", hdev->name, policy);
330e4e8e37cSMarcel Holtmann 
331e4e8e37cSMarcel Holtmann 	/* Default link policy */
332e4e8e37cSMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
333e4e8e37cSMarcel Holtmann }
334e4e8e37cSMarcel Holtmann 
3351da177e4SLinus Torvalds /* Get HCI device by index.
3361da177e4SLinus Torvalds  * Device is held on return. */
3371da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
3381da177e4SLinus Torvalds {
3398035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
3401da177e4SLinus Torvalds 
3411da177e4SLinus Torvalds 	BT_DBG("%d", index);
3421da177e4SLinus Torvalds 
3431da177e4SLinus Torvalds 	if (index < 0)
3441da177e4SLinus Torvalds 		return NULL;
3451da177e4SLinus Torvalds 
3461da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
3478035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
3481da177e4SLinus Torvalds 		if (d->id == index) {
3491da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
3501da177e4SLinus Torvalds 			break;
3511da177e4SLinus Torvalds 		}
3521da177e4SLinus Torvalds 	}
3531da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
3541da177e4SLinus Torvalds 	return hdev;
3551da177e4SLinus Torvalds }
3561da177e4SLinus Torvalds 
3571da177e4SLinus Torvalds /* ---- Inquiry support ---- */
358ff9ef578SJohan Hedberg 
35930dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
36030dc78e1SJohan Hedberg {
36130dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
36230dc78e1SJohan Hedberg 
36330dc78e1SJohan Hedberg 	if (discov->state == DISCOVERY_INQUIRY ||
36430dc78e1SJohan Hedberg 					discov->state == DISCOVERY_RESOLVING)
36530dc78e1SJohan Hedberg 		return true;
36630dc78e1SJohan Hedberg 
36730dc78e1SJohan Hedberg 	return false;
36830dc78e1SJohan Hedberg }
36930dc78e1SJohan Hedberg 
370ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
371ff9ef578SJohan Hedberg {
372ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
373ff9ef578SJohan Hedberg 
374ff9ef578SJohan Hedberg 	if (hdev->discovery.state == state)
375ff9ef578SJohan Hedberg 		return;
376ff9ef578SJohan Hedberg 
377ff9ef578SJohan Hedberg 	switch (state) {
378ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
379ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 0);
380ff9ef578SJohan Hedberg 		break;
381ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
382ff9ef578SJohan Hedberg 		break;
38330dc78e1SJohan Hedberg 	case DISCOVERY_INQUIRY:
384ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
385ff9ef578SJohan Hedberg 		break;
38630dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
38730dc78e1SJohan Hedberg 		break;
388ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
389ff9ef578SJohan Hedberg 		break;
390ff9ef578SJohan Hedberg 	}
391ff9ef578SJohan Hedberg 
392ff9ef578SJohan Hedberg 	hdev->discovery.state = state;
393ff9ef578SJohan Hedberg }
394ff9ef578SJohan Hedberg 
3951da177e4SLinus Torvalds static void inquiry_cache_flush(struct hci_dev *hdev)
3961da177e4SLinus Torvalds {
39730883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
398b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
3991da177e4SLinus Torvalds 
400561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
401561aafbcSJohan Hedberg 		list_del(&p->all);
402b57c1a56SJohan Hedberg 		kfree(p);
4031da177e4SLinus Torvalds 	}
404561aafbcSJohan Hedberg 
405561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
406561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
407ff9ef578SJohan Hedberg 	cache->state = DISCOVERY_STOPPED;
4081da177e4SLinus Torvalds }
4091da177e4SLinus Torvalds 
4101da177e4SLinus Torvalds struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
4111da177e4SLinus Torvalds {
41230883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
4131da177e4SLinus Torvalds 	struct inquiry_entry *e;
4141da177e4SLinus Torvalds 
4151da177e4SLinus Torvalds 	BT_DBG("cache %p, %s", cache, batostr(bdaddr));
4161da177e4SLinus Torvalds 
417561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
4181da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
4191da177e4SLinus Torvalds 			return e;
4201da177e4SLinus Torvalds 	}
4211da177e4SLinus Torvalds 
422b57c1a56SJohan Hedberg 	return NULL;
423b57c1a56SJohan Hedberg }
424b57c1a56SJohan Hedberg 
425561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
426561aafbcSJohan Hedberg 							bdaddr_t *bdaddr)
427561aafbcSJohan Hedberg {
42830883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
429561aafbcSJohan Hedberg 	struct inquiry_entry *e;
430561aafbcSJohan Hedberg 
431561aafbcSJohan Hedberg 	BT_DBG("cache %p, %s", cache, batostr(bdaddr));
432561aafbcSJohan Hedberg 
433561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
434561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
435561aafbcSJohan Hedberg 			return e;
436561aafbcSJohan Hedberg 	}
437561aafbcSJohan Hedberg 
438561aafbcSJohan Hedberg 	return NULL;
439561aafbcSJohan Hedberg }
440561aafbcSJohan Hedberg 
44130dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
44230dc78e1SJohan Hedberg 							bdaddr_t *bdaddr,
44330dc78e1SJohan Hedberg 							int state)
44430dc78e1SJohan Hedberg {
44530dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
44630dc78e1SJohan Hedberg 	struct inquiry_entry *e;
44730dc78e1SJohan Hedberg 
44830dc78e1SJohan Hedberg 	BT_DBG("cache %p bdaddr %s state %d", cache, batostr(bdaddr), state);
44930dc78e1SJohan Hedberg 
45030dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
45130dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
45230dc78e1SJohan Hedberg 			return e;
45330dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
45430dc78e1SJohan Hedberg 			return e;
45530dc78e1SJohan Hedberg 	}
45630dc78e1SJohan Hedberg 
45730dc78e1SJohan Hedberg 	return NULL;
45830dc78e1SJohan Hedberg }
45930dc78e1SJohan Hedberg 
460a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
461a3d4e20aSJohan Hedberg 						struct inquiry_entry *ie)
462a3d4e20aSJohan Hedberg {
463a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
464a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
465a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
466a3d4e20aSJohan Hedberg 
467a3d4e20aSJohan Hedberg 	list_del(&ie->list);
468a3d4e20aSJohan Hedberg 
469a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
470a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
471a3d4e20aSJohan Hedberg 				abs(p->data.rssi) >= abs(ie->data.rssi))
472a3d4e20aSJohan Hedberg 			break;
473a3d4e20aSJohan Hedberg 		pos = &p->list;
474a3d4e20aSJohan Hedberg 	}
475a3d4e20aSJohan Hedberg 
476a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
477a3d4e20aSJohan Hedberg }
478a3d4e20aSJohan Hedberg 
4793175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
480561aafbcSJohan Hedberg 							bool name_known)
4811da177e4SLinus Torvalds {
48230883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
48370f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
4841da177e4SLinus Torvalds 
4851da177e4SLinus Torvalds 	BT_DBG("cache %p, %s", cache, batostr(&data->bdaddr));
4861da177e4SLinus Torvalds 
48770f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
488a3d4e20aSJohan Hedberg 	if (ie) {
489a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
490a3d4e20aSJohan Hedberg 						data->rssi != ie->data.rssi) {
491a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
492a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
493a3d4e20aSJohan Hedberg 		}
494a3d4e20aSJohan Hedberg 
495561aafbcSJohan Hedberg 		goto update;
496a3d4e20aSJohan Hedberg 	}
497561aafbcSJohan Hedberg 
4981da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
49970f23020SAndrei Emeltchenko 	ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
50070f23020SAndrei Emeltchenko 	if (!ie)
5013175405bSJohan Hedberg 		return false;
50270f23020SAndrei Emeltchenko 
503561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
504561aafbcSJohan Hedberg 
505561aafbcSJohan Hedberg 	if (name_known) {
506561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
507561aafbcSJohan Hedberg 	} else {
508561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
509561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
510561aafbcSJohan Hedberg 	}
511561aafbcSJohan Hedberg 
512561aafbcSJohan Hedberg update:
513561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
514561aafbcSJohan Hedberg 					ie->name_state != NAME_PENDING) {
515561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
516561aafbcSJohan Hedberg 		list_del(&ie->list);
5171da177e4SLinus Torvalds 	}
5181da177e4SLinus Torvalds 
51970f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
52070f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
5211da177e4SLinus Torvalds 	cache->timestamp = jiffies;
5223175405bSJohan Hedberg 
5233175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
5243175405bSJohan Hedberg 		return false;
5253175405bSJohan Hedberg 
5263175405bSJohan Hedberg 	return true;
5271da177e4SLinus Torvalds }
5281da177e4SLinus Torvalds 
5291da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
5301da177e4SLinus Torvalds {
53130883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
5321da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
5331da177e4SLinus Torvalds 	struct inquiry_entry *e;
5341da177e4SLinus Torvalds 	int copied = 0;
5351da177e4SLinus Torvalds 
536561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
5371da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
538b57c1a56SJohan Hedberg 
539b57c1a56SJohan Hedberg 		if (copied >= num)
540b57c1a56SJohan Hedberg 			break;
541b57c1a56SJohan Hedberg 
5421da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
5431da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
5441da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
5451da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
5461da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
5471da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
548b57c1a56SJohan Hedberg 
5491da177e4SLinus Torvalds 		info++;
550b57c1a56SJohan Hedberg 		copied++;
5511da177e4SLinus Torvalds 	}
5521da177e4SLinus Torvalds 
5531da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
5541da177e4SLinus Torvalds 	return copied;
5551da177e4SLinus Torvalds }
5561da177e4SLinus Torvalds 
5571da177e4SLinus Torvalds static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
5581da177e4SLinus Torvalds {
5591da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
5601da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
5611da177e4SLinus Torvalds 
5621da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
5631da177e4SLinus Torvalds 
5641da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
5651da177e4SLinus Torvalds 		return;
5661da177e4SLinus Torvalds 
5671da177e4SLinus Torvalds 	/* Start Inquiry */
5681da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
5691da177e4SLinus Torvalds 	cp.length  = ir->length;
5701da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
571a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
5721da177e4SLinus Torvalds }
5731da177e4SLinus Torvalds 
5741da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
5751da177e4SLinus Torvalds {
5761da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
5771da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
5781da177e4SLinus Torvalds 	struct hci_dev *hdev;
5791da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
5801da177e4SLinus Torvalds 	long timeo;
5811da177e4SLinus Torvalds 	__u8 *buf;
5821da177e4SLinus Torvalds 
5831da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
5841da177e4SLinus Torvalds 		return -EFAULT;
5851da177e4SLinus Torvalds 
5865a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
5875a08ecceSAndrei Emeltchenko 	if (!hdev)
5881da177e4SLinus Torvalds 		return -ENODEV;
5891da177e4SLinus Torvalds 
59009fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
5911da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
5921da177e4SLinus Torvalds 				inquiry_cache_empty(hdev) ||
5931da177e4SLinus Torvalds 				ir.flags & IREQ_CACHE_FLUSH) {
5941da177e4SLinus Torvalds 		inquiry_cache_flush(hdev);
5951da177e4SLinus Torvalds 		do_inquiry = 1;
5961da177e4SLinus Torvalds 	}
59709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
5981da177e4SLinus Torvalds 
59904837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
60070f23020SAndrei Emeltchenko 
60170f23020SAndrei Emeltchenko 	if (do_inquiry) {
60270f23020SAndrei Emeltchenko 		err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo);
60370f23020SAndrei Emeltchenko 		if (err < 0)
6041da177e4SLinus Torvalds 			goto done;
60570f23020SAndrei Emeltchenko 	}
6061da177e4SLinus Torvalds 
6071da177e4SLinus Torvalds 	/* for unlimited number of responses we will use buffer with 255 entries */
6081da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
6091da177e4SLinus Torvalds 
6101da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
6111da177e4SLinus Torvalds 	 * copy it to the user space.
6121da177e4SLinus Torvalds 	 */
61370f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
61470f23020SAndrei Emeltchenko 	if (!buf) {
6151da177e4SLinus Torvalds 		err = -ENOMEM;
6161da177e4SLinus Torvalds 		goto done;
6171da177e4SLinus Torvalds 	}
6181da177e4SLinus Torvalds 
61909fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
6201da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
62109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
6221da177e4SLinus Torvalds 
6231da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
6241da177e4SLinus Torvalds 
6251da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
6261da177e4SLinus Torvalds 		ptr += sizeof(ir);
6271da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
6281da177e4SLinus Torvalds 					ir.num_rsp))
6291da177e4SLinus Torvalds 			err = -EFAULT;
6301da177e4SLinus Torvalds 	} else
6311da177e4SLinus Torvalds 		err = -EFAULT;
6321da177e4SLinus Torvalds 
6331da177e4SLinus Torvalds 	kfree(buf);
6341da177e4SLinus Torvalds 
6351da177e4SLinus Torvalds done:
6361da177e4SLinus Torvalds 	hci_dev_put(hdev);
6371da177e4SLinus Torvalds 	return err;
6381da177e4SLinus Torvalds }
6391da177e4SLinus Torvalds 
6401da177e4SLinus Torvalds /* ---- HCI ioctl helpers ---- */
6411da177e4SLinus Torvalds 
6421da177e4SLinus Torvalds int hci_dev_open(__u16 dev)
6431da177e4SLinus Torvalds {
6441da177e4SLinus Torvalds 	struct hci_dev *hdev;
6451da177e4SLinus Torvalds 	int ret = 0;
6461da177e4SLinus Torvalds 
6475a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(dev);
6485a08ecceSAndrei Emeltchenko 	if (!hdev)
6491da177e4SLinus Torvalds 		return -ENODEV;
6501da177e4SLinus Torvalds 
6511da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
6521da177e4SLinus Torvalds 
6531da177e4SLinus Torvalds 	hci_req_lock(hdev);
6541da177e4SLinus Torvalds 
655611b30f7SMarcel Holtmann 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) {
656611b30f7SMarcel Holtmann 		ret = -ERFKILL;
657611b30f7SMarcel Holtmann 		goto done;
658611b30f7SMarcel Holtmann 	}
659611b30f7SMarcel Holtmann 
6601da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
6611da177e4SLinus Torvalds 		ret = -EALREADY;
6621da177e4SLinus Torvalds 		goto done;
6631da177e4SLinus Torvalds 	}
6641da177e4SLinus Torvalds 
6651da177e4SLinus Torvalds 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
6661da177e4SLinus Torvalds 		set_bit(HCI_RAW, &hdev->flags);
6671da177e4SLinus Torvalds 
66807e3b94aSAndrei Emeltchenko 	/* Treat all non BR/EDR controllers as raw devices if
66907e3b94aSAndrei Emeltchenko 	   enable_hs is not set */
67007e3b94aSAndrei Emeltchenko 	if (hdev->dev_type != HCI_BREDR && !enable_hs)
671943da25dSMarcel Holtmann 		set_bit(HCI_RAW, &hdev->flags);
672943da25dSMarcel Holtmann 
6731da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
6741da177e4SLinus Torvalds 		ret = -EIO;
6751da177e4SLinus Torvalds 		goto done;
6761da177e4SLinus Torvalds 	}
6771da177e4SLinus Torvalds 
6781da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
6791da177e4SLinus Torvalds 		atomic_set(&hdev->cmd_cnt, 1);
6801da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
681a5040efaSJohan Hedberg 		hdev->init_last_cmd = 0;
6821da177e4SLinus Torvalds 
68304837f64SMarcel Holtmann 		ret = __hci_request(hdev, hci_init_req, 0,
68404837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
6851da177e4SLinus Torvalds 
686eead27daSAndre Guedes 		if (lmp_host_le_capable(hdev))
6876ed58ec5SVille Tervo 			ret = __hci_request(hdev, hci_le_init_req, 0,
6886ed58ec5SVille Tervo 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
6896ed58ec5SVille Tervo 
6901da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
6911da177e4SLinus Torvalds 	}
6921da177e4SLinus Torvalds 
6931da177e4SLinus Torvalds 	if (!ret) {
6941da177e4SLinus Torvalds 		hci_dev_hold(hdev);
6951da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
6961da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
697a8b2d5c2SJohan Hedberg 		if (!test_bit(HCI_SETUP, &hdev->dev_flags)) {
69809fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
699744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
70009fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
70156e5cb86SJohan Hedberg 		}
7021da177e4SLinus Torvalds 	} else {
7031da177e4SLinus Torvalds 		/* Init failed, cleanup */
7043eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
705c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
706b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
7071da177e4SLinus Torvalds 
7081da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
7091da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
7101da177e4SLinus Torvalds 
7111da177e4SLinus Torvalds 		if (hdev->flush)
7121da177e4SLinus Torvalds 			hdev->flush(hdev);
7131da177e4SLinus Torvalds 
7141da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
7151da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
7161da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
7171da177e4SLinus Torvalds 		}
7181da177e4SLinus Torvalds 
7191da177e4SLinus Torvalds 		hdev->close(hdev);
7201da177e4SLinus Torvalds 		hdev->flags = 0;
7211da177e4SLinus Torvalds 	}
7221da177e4SLinus Torvalds 
7231da177e4SLinus Torvalds done:
7241da177e4SLinus Torvalds 	hci_req_unlock(hdev);
7251da177e4SLinus Torvalds 	hci_dev_put(hdev);
7261da177e4SLinus Torvalds 	return ret;
7271da177e4SLinus Torvalds }
7281da177e4SLinus Torvalds 
7291da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
7301da177e4SLinus Torvalds {
7311da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
7321da177e4SLinus Torvalds 
7331da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
7341da177e4SLinus Torvalds 	hci_req_lock(hdev);
7351da177e4SLinus Torvalds 
7361da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
737b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
7381da177e4SLinus Torvalds 		hci_req_unlock(hdev);
7391da177e4SLinus Torvalds 		return 0;
7401da177e4SLinus Torvalds 	}
7411da177e4SLinus Torvalds 
7423eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
7433eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
744b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
7451da177e4SLinus Torvalds 
74616ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
747e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
74816ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
74916ab91abSJohan Hedberg 	}
75016ab91abSJohan Hedberg 
751a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
752e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
7533243553fSJohan Hedberg 
754a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
7557d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
7567d78525dSJohan Hedberg 
75709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
7581da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
7591da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
76009fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
7611da177e4SLinus Torvalds 
7621da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
7631da177e4SLinus Torvalds 
7641da177e4SLinus Torvalds 	if (hdev->flush)
7651da177e4SLinus Torvalds 		hdev->flush(hdev);
7661da177e4SLinus Torvalds 
7671da177e4SLinus Torvalds 	/* Reset device */
7681da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
7691da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
7701da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
7711da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
77204837f64SMarcel Holtmann 		__hci_request(hdev, hci_reset_req, 0,
773cad44c2bSGustavo F. Padovan 					msecs_to_jiffies(250));
7741da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
7751da177e4SLinus Torvalds 	}
7761da177e4SLinus Torvalds 
777c347b765SGustavo F. Padovan 	/* flush cmd  work */
778c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
7791da177e4SLinus Torvalds 
7801da177e4SLinus Torvalds 	/* Drop queues */
7811da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
7821da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
7831da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
7841da177e4SLinus Torvalds 
7851da177e4SLinus Torvalds 	/* Drop last sent command */
7861da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
787b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
7881da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
7891da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
7901da177e4SLinus Torvalds 	}
7911da177e4SLinus Torvalds 
7921da177e4SLinus Torvalds 	/* After this point our queues are empty
7931da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
7941da177e4SLinus Torvalds 	hdev->close(hdev);
7951da177e4SLinus Torvalds 
79609fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
797744cf19eSJohan Hedberg 	mgmt_powered(hdev, 0);
79809fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
7995add6af8SJohan Hedberg 
8001da177e4SLinus Torvalds 	/* Clear flags */
8011da177e4SLinus Torvalds 	hdev->flags = 0;
8021da177e4SLinus Torvalds 
8031da177e4SLinus Torvalds 	hci_req_unlock(hdev);
8041da177e4SLinus Torvalds 
8051da177e4SLinus Torvalds 	hci_dev_put(hdev);
8061da177e4SLinus Torvalds 	return 0;
8071da177e4SLinus Torvalds }
8081da177e4SLinus Torvalds 
8091da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
8101da177e4SLinus Torvalds {
8111da177e4SLinus Torvalds 	struct hci_dev *hdev;
8121da177e4SLinus Torvalds 	int err;
8131da177e4SLinus Torvalds 
81470f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
81570f23020SAndrei Emeltchenko 	if (!hdev)
8161da177e4SLinus Torvalds 		return -ENODEV;
8171da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
8181da177e4SLinus Torvalds 	hci_dev_put(hdev);
8191da177e4SLinus Torvalds 	return err;
8201da177e4SLinus Torvalds }
8211da177e4SLinus Torvalds 
8221da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
8231da177e4SLinus Torvalds {
8241da177e4SLinus Torvalds 	struct hci_dev *hdev;
8251da177e4SLinus Torvalds 	int ret = 0;
8261da177e4SLinus Torvalds 
82770f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
82870f23020SAndrei Emeltchenko 	if (!hdev)
8291da177e4SLinus Torvalds 		return -ENODEV;
8301da177e4SLinus Torvalds 
8311da177e4SLinus Torvalds 	hci_req_lock(hdev);
8321da177e4SLinus Torvalds 
8331da177e4SLinus Torvalds 	if (!test_bit(HCI_UP, &hdev->flags))
8341da177e4SLinus Torvalds 		goto done;
8351da177e4SLinus Torvalds 
8361da177e4SLinus Torvalds 	/* Drop queues */
8371da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
8381da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
8391da177e4SLinus Torvalds 
84009fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
8411da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
8421da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
84309fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
8441da177e4SLinus Torvalds 
8451da177e4SLinus Torvalds 	if (hdev->flush)
8461da177e4SLinus Torvalds 		hdev->flush(hdev);
8471da177e4SLinus Torvalds 
8481da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
8496ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
8501da177e4SLinus Torvalds 
8511da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags))
85204837f64SMarcel Holtmann 		ret = __hci_request(hdev, hci_reset_req, 0,
85304837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
8541da177e4SLinus Torvalds 
8551da177e4SLinus Torvalds done:
8561da177e4SLinus Torvalds 	hci_req_unlock(hdev);
8571da177e4SLinus Torvalds 	hci_dev_put(hdev);
8581da177e4SLinus Torvalds 	return ret;
8591da177e4SLinus Torvalds }
8601da177e4SLinus Torvalds 
8611da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
8621da177e4SLinus Torvalds {
8631da177e4SLinus Torvalds 	struct hci_dev *hdev;
8641da177e4SLinus Torvalds 	int ret = 0;
8651da177e4SLinus Torvalds 
86670f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
86770f23020SAndrei Emeltchenko 	if (!hdev)
8681da177e4SLinus Torvalds 		return -ENODEV;
8691da177e4SLinus Torvalds 
8701da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
8711da177e4SLinus Torvalds 
8721da177e4SLinus Torvalds 	hci_dev_put(hdev);
8731da177e4SLinus Torvalds 
8741da177e4SLinus Torvalds 	return ret;
8751da177e4SLinus Torvalds }
8761da177e4SLinus Torvalds 
8771da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
8781da177e4SLinus Torvalds {
8791da177e4SLinus Torvalds 	struct hci_dev *hdev;
8801da177e4SLinus Torvalds 	struct hci_dev_req dr;
8811da177e4SLinus Torvalds 	int err = 0;
8821da177e4SLinus Torvalds 
8831da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
8841da177e4SLinus Torvalds 		return -EFAULT;
8851da177e4SLinus Torvalds 
88670f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
88770f23020SAndrei Emeltchenko 	if (!hdev)
8881da177e4SLinus Torvalds 		return -ENODEV;
8891da177e4SLinus Torvalds 
8901da177e4SLinus Torvalds 	switch (cmd) {
8911da177e4SLinus Torvalds 	case HCISETAUTH:
89204837f64SMarcel Holtmann 		err = hci_request(hdev, hci_auth_req, dr.dev_opt,
89304837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
8941da177e4SLinus Torvalds 		break;
8951da177e4SLinus Torvalds 
8961da177e4SLinus Torvalds 	case HCISETENCRYPT:
8971da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
8981da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
8991da177e4SLinus Torvalds 			break;
9001da177e4SLinus Torvalds 		}
9011da177e4SLinus Torvalds 
9021da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
9031da177e4SLinus Torvalds 			/* Auth must be enabled first */
90404837f64SMarcel Holtmann 			err = hci_request(hdev, hci_auth_req, dr.dev_opt,
90504837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
9061da177e4SLinus Torvalds 			if (err)
9071da177e4SLinus Torvalds 				break;
9081da177e4SLinus Torvalds 		}
9091da177e4SLinus Torvalds 
91004837f64SMarcel Holtmann 		err = hci_request(hdev, hci_encrypt_req, dr.dev_opt,
91104837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
9121da177e4SLinus Torvalds 		break;
9131da177e4SLinus Torvalds 
9141da177e4SLinus Torvalds 	case HCISETSCAN:
91504837f64SMarcel Holtmann 		err = hci_request(hdev, hci_scan_req, dr.dev_opt,
91604837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
9171da177e4SLinus Torvalds 		break;
9181da177e4SLinus Torvalds 
9191da177e4SLinus Torvalds 	case HCISETLINKPOL:
920e4e8e37cSMarcel Holtmann 		err = hci_request(hdev, hci_linkpol_req, dr.dev_opt,
921e4e8e37cSMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
9221da177e4SLinus Torvalds 		break;
9231da177e4SLinus Torvalds 
9241da177e4SLinus Torvalds 	case HCISETLINKMODE:
925e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
926e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
927e4e8e37cSMarcel Holtmann 		break;
928e4e8e37cSMarcel Holtmann 
929e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
930e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
9311da177e4SLinus Torvalds 		break;
9321da177e4SLinus Torvalds 
9331da177e4SLinus Torvalds 	case HCISETACLMTU:
9341da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
9351da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
9361da177e4SLinus Torvalds 		break;
9371da177e4SLinus Torvalds 
9381da177e4SLinus Torvalds 	case HCISETSCOMTU:
9391da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
9401da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
9411da177e4SLinus Torvalds 		break;
9421da177e4SLinus Torvalds 
9431da177e4SLinus Torvalds 	default:
9441da177e4SLinus Torvalds 		err = -EINVAL;
9451da177e4SLinus Torvalds 		break;
9461da177e4SLinus Torvalds 	}
947e4e8e37cSMarcel Holtmann 
9481da177e4SLinus Torvalds 	hci_dev_put(hdev);
9491da177e4SLinus Torvalds 	return err;
9501da177e4SLinus Torvalds }
9511da177e4SLinus Torvalds 
9521da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
9531da177e4SLinus Torvalds {
9548035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
9551da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
9561da177e4SLinus Torvalds 	struct hci_dev_req *dr;
9571da177e4SLinus Torvalds 	int n = 0, size, err;
9581da177e4SLinus Torvalds 	__u16 dev_num;
9591da177e4SLinus Torvalds 
9601da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
9611da177e4SLinus Torvalds 		return -EFAULT;
9621da177e4SLinus Torvalds 
9631da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
9641da177e4SLinus Torvalds 		return -EINVAL;
9651da177e4SLinus Torvalds 
9661da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
9671da177e4SLinus Torvalds 
96870f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
96970f23020SAndrei Emeltchenko 	if (!dl)
9701da177e4SLinus Torvalds 		return -ENOMEM;
9711da177e4SLinus Torvalds 
9721da177e4SLinus Torvalds 	dr = dl->dev_req;
9731da177e4SLinus Torvalds 
974f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
9758035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
976a8b2d5c2SJohan Hedberg 		if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
977e0f9309fSJohan Hedberg 			cancel_delayed_work(&hdev->power_off);
978c542a06cSJohan Hedberg 
979a8b2d5c2SJohan Hedberg 		if (!test_bit(HCI_MGMT, &hdev->dev_flags))
980a8b2d5c2SJohan Hedberg 			set_bit(HCI_PAIRABLE, &hdev->dev_flags);
981c542a06cSJohan Hedberg 
9821da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
9831da177e4SLinus Torvalds 		(dr + n)->dev_opt = hdev->flags;
984c542a06cSJohan Hedberg 
9851da177e4SLinus Torvalds 		if (++n >= dev_num)
9861da177e4SLinus Torvalds 			break;
9871da177e4SLinus Torvalds 	}
988f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
9891da177e4SLinus Torvalds 
9901da177e4SLinus Torvalds 	dl->dev_num = n;
9911da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
9921da177e4SLinus Torvalds 
9931da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
9941da177e4SLinus Torvalds 	kfree(dl);
9951da177e4SLinus Torvalds 
9961da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
9971da177e4SLinus Torvalds }
9981da177e4SLinus Torvalds 
9991da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
10001da177e4SLinus Torvalds {
10011da177e4SLinus Torvalds 	struct hci_dev *hdev;
10021da177e4SLinus Torvalds 	struct hci_dev_info di;
10031da177e4SLinus Torvalds 	int err = 0;
10041da177e4SLinus Torvalds 
10051da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
10061da177e4SLinus Torvalds 		return -EFAULT;
10071da177e4SLinus Torvalds 
100870f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
100970f23020SAndrei Emeltchenko 	if (!hdev)
10101da177e4SLinus Torvalds 		return -ENODEV;
10111da177e4SLinus Torvalds 
1012a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
10133243553fSJohan Hedberg 		cancel_delayed_work_sync(&hdev->power_off);
1014ab81cbf9SJohan Hedberg 
1015a8b2d5c2SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1016a8b2d5c2SJohan Hedberg 		set_bit(HCI_PAIRABLE, &hdev->dev_flags);
1017c542a06cSJohan Hedberg 
10181da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
10191da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
1020943da25dSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | (hdev->dev_type << 4);
10211da177e4SLinus Torvalds 	di.flags    = hdev->flags;
10221da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
10231da177e4SLinus Torvalds 	di.acl_mtu  = hdev->acl_mtu;
10241da177e4SLinus Torvalds 	di.acl_pkts = hdev->acl_pkts;
10251da177e4SLinus Torvalds 	di.sco_mtu  = hdev->sco_mtu;
10261da177e4SLinus Torvalds 	di.sco_pkts = hdev->sco_pkts;
10271da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
10281da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
10291da177e4SLinus Torvalds 
10301da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
10311da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
10321da177e4SLinus Torvalds 
10331da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
10341da177e4SLinus Torvalds 		err = -EFAULT;
10351da177e4SLinus Torvalds 
10361da177e4SLinus Torvalds 	hci_dev_put(hdev);
10371da177e4SLinus Torvalds 
10381da177e4SLinus Torvalds 	return err;
10391da177e4SLinus Torvalds }
10401da177e4SLinus Torvalds 
10411da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
10421da177e4SLinus Torvalds 
1043611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
1044611b30f7SMarcel Holtmann {
1045611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
1046611b30f7SMarcel Holtmann 
1047611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
1048611b30f7SMarcel Holtmann 
1049611b30f7SMarcel Holtmann 	if (!blocked)
1050611b30f7SMarcel Holtmann 		return 0;
1051611b30f7SMarcel Holtmann 
1052611b30f7SMarcel Holtmann 	hci_dev_do_close(hdev);
1053611b30f7SMarcel Holtmann 
1054611b30f7SMarcel Holtmann 	return 0;
1055611b30f7SMarcel Holtmann }
1056611b30f7SMarcel Holtmann 
1057611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
1058611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
1059611b30f7SMarcel Holtmann };
1060611b30f7SMarcel Holtmann 
10611da177e4SLinus Torvalds /* Alloc HCI device */
10621da177e4SLinus Torvalds struct hci_dev *hci_alloc_dev(void)
10631da177e4SLinus Torvalds {
10641da177e4SLinus Torvalds 	struct hci_dev *hdev;
10651da177e4SLinus Torvalds 
106625ea6db0SMarcel Holtmann 	hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
10671da177e4SLinus Torvalds 	if (!hdev)
10681da177e4SLinus Torvalds 		return NULL;
10691da177e4SLinus Torvalds 
10700ac7e700SDavid Herrmann 	hci_init_sysfs(hdev);
10711da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->driver_init);
10721da177e4SLinus Torvalds 
10731da177e4SLinus Torvalds 	return hdev;
10741da177e4SLinus Torvalds }
10751da177e4SLinus Torvalds EXPORT_SYMBOL(hci_alloc_dev);
10761da177e4SLinus Torvalds 
10771da177e4SLinus Torvalds /* Free HCI device */
10781da177e4SLinus Torvalds void hci_free_dev(struct hci_dev *hdev)
10791da177e4SLinus Torvalds {
10801da177e4SLinus Torvalds 	skb_queue_purge(&hdev->driver_init);
10811da177e4SLinus Torvalds 
1082a91f2e39SMarcel Holtmann 	/* will free via device release */
1083a91f2e39SMarcel Holtmann 	put_device(&hdev->dev);
10841da177e4SLinus Torvalds }
10851da177e4SLinus Torvalds EXPORT_SYMBOL(hci_free_dev);
10861da177e4SLinus Torvalds 
1087ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
1088ab81cbf9SJohan Hedberg {
1089ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
1090ab81cbf9SJohan Hedberg 
1091ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1092ab81cbf9SJohan Hedberg 
1093ab81cbf9SJohan Hedberg 	if (hci_dev_open(hdev->id) < 0)
1094ab81cbf9SJohan Hedberg 		return;
1095ab81cbf9SJohan Hedberg 
1096a8b2d5c2SJohan Hedberg 	if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
109780b7ab33SGustavo F. Padovan 		schedule_delayed_work(&hdev->power_off,
10983243553fSJohan Hedberg 					msecs_to_jiffies(AUTO_OFF_TIMEOUT));
1099ab81cbf9SJohan Hedberg 
1100a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags))
1101744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
1102ab81cbf9SJohan Hedberg }
1103ab81cbf9SJohan Hedberg 
1104ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
1105ab81cbf9SJohan Hedberg {
11063243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
11073243553fSJohan Hedberg 							power_off.work);
1108ab81cbf9SJohan Hedberg 
1109ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1110ab81cbf9SJohan Hedberg 
1111a8b2d5c2SJohan Hedberg 	clear_bit(HCI_AUTO_OFF, &hdev->dev_flags);
11123243553fSJohan Hedberg 
1113ab81cbf9SJohan Hedberg 	hci_dev_close(hdev->id);
1114ab81cbf9SJohan Hedberg }
1115ab81cbf9SJohan Hedberg 
111616ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
111716ab91abSJohan Hedberg {
111816ab91abSJohan Hedberg 	struct hci_dev *hdev;
111916ab91abSJohan Hedberg 	u8 scan = SCAN_PAGE;
112016ab91abSJohan Hedberg 
112116ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
112216ab91abSJohan Hedberg 
112316ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
112416ab91abSJohan Hedberg 
112509fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
112616ab91abSJohan Hedberg 
112716ab91abSJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan);
112816ab91abSJohan Hedberg 
112916ab91abSJohan Hedberg 	hdev->discov_timeout = 0;
113016ab91abSJohan Hedberg 
113109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
113216ab91abSJohan Hedberg }
113316ab91abSJohan Hedberg 
11342aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev)
11352aeb9a1aSJohan Hedberg {
11362aeb9a1aSJohan Hedberg 	struct list_head *p, *n;
11372aeb9a1aSJohan Hedberg 
11382aeb9a1aSJohan Hedberg 	list_for_each_safe(p, n, &hdev->uuids) {
11392aeb9a1aSJohan Hedberg 		struct bt_uuid *uuid;
11402aeb9a1aSJohan Hedberg 
11412aeb9a1aSJohan Hedberg 		uuid = list_entry(p, struct bt_uuid, list);
11422aeb9a1aSJohan Hedberg 
11432aeb9a1aSJohan Hedberg 		list_del(p);
11442aeb9a1aSJohan Hedberg 		kfree(uuid);
11452aeb9a1aSJohan Hedberg 	}
11462aeb9a1aSJohan Hedberg 
11472aeb9a1aSJohan Hedberg 	return 0;
11482aeb9a1aSJohan Hedberg }
11492aeb9a1aSJohan Hedberg 
115055ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev)
115155ed8ca1SJohan Hedberg {
115255ed8ca1SJohan Hedberg 	struct list_head *p, *n;
115355ed8ca1SJohan Hedberg 
115455ed8ca1SJohan Hedberg 	list_for_each_safe(p, n, &hdev->link_keys) {
115555ed8ca1SJohan Hedberg 		struct link_key *key;
115655ed8ca1SJohan Hedberg 
115755ed8ca1SJohan Hedberg 		key = list_entry(p, struct link_key, list);
115855ed8ca1SJohan Hedberg 
115955ed8ca1SJohan Hedberg 		list_del(p);
116055ed8ca1SJohan Hedberg 		kfree(key);
116155ed8ca1SJohan Hedberg 	}
116255ed8ca1SJohan Hedberg 
116355ed8ca1SJohan Hedberg 	return 0;
116455ed8ca1SJohan Hedberg }
116555ed8ca1SJohan Hedberg 
1166b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev)
1167b899efafSVinicius Costa Gomes {
1168b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1169b899efafSVinicius Costa Gomes 
1170b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1171b899efafSVinicius Costa Gomes 		list_del(&k->list);
1172b899efafSVinicius Costa Gomes 		kfree(k);
1173b899efafSVinicius Costa Gomes 	}
1174b899efafSVinicius Costa Gomes 
1175b899efafSVinicius Costa Gomes 	return 0;
1176b899efafSVinicius Costa Gomes }
1177b899efafSVinicius Costa Gomes 
117855ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
117955ed8ca1SJohan Hedberg {
118055ed8ca1SJohan Hedberg 	struct link_key *k;
118155ed8ca1SJohan Hedberg 
11828035ded4SLuiz Augusto von Dentz 	list_for_each_entry(k, &hdev->link_keys, list)
118355ed8ca1SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0)
118455ed8ca1SJohan Hedberg 			return k;
118555ed8ca1SJohan Hedberg 
118655ed8ca1SJohan Hedberg 	return NULL;
118755ed8ca1SJohan Hedberg }
118855ed8ca1SJohan Hedberg 
1189d25e28abSJohan Hedberg static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1190d25e28abSJohan Hedberg 						u8 key_type, u8 old_key_type)
1191d25e28abSJohan Hedberg {
1192d25e28abSJohan Hedberg 	/* Legacy key */
1193d25e28abSJohan Hedberg 	if (key_type < 0x03)
1194d25e28abSJohan Hedberg 		return 1;
1195d25e28abSJohan Hedberg 
1196d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
1197d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
1198d25e28abSJohan Hedberg 		return 0;
1199d25e28abSJohan Hedberg 
1200d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
1201d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
1202d25e28abSJohan Hedberg 		return 0;
1203d25e28abSJohan Hedberg 
1204d25e28abSJohan Hedberg 	/* Security mode 3 case */
1205d25e28abSJohan Hedberg 	if (!conn)
1206d25e28abSJohan Hedberg 		return 1;
1207d25e28abSJohan Hedberg 
1208d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
1209d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
1210d25e28abSJohan Hedberg 		return 1;
1211d25e28abSJohan Hedberg 
1212d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
1213d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
1214d25e28abSJohan Hedberg 		return 1;
1215d25e28abSJohan Hedberg 
1216d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
1217d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
1218d25e28abSJohan Hedberg 		return 1;
1219d25e28abSJohan Hedberg 
1220d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
1221d25e28abSJohan Hedberg 	 * persistently */
1222d25e28abSJohan Hedberg 	return 0;
1223d25e28abSJohan Hedberg }
1224d25e28abSJohan Hedberg 
1225c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
122675d262c2SVinicius Costa Gomes {
1227c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
122875d262c2SVinicius Costa Gomes 
1229c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list) {
1230c9839a11SVinicius Costa Gomes 		if (k->ediv != ediv ||
1231c9839a11SVinicius Costa Gomes 				memcmp(rand, k->rand, sizeof(k->rand)))
123275d262c2SVinicius Costa Gomes 			continue;
123375d262c2SVinicius Costa Gomes 
123475d262c2SVinicius Costa Gomes 		return k;
123575d262c2SVinicius Costa Gomes 	}
123675d262c2SVinicius Costa Gomes 
123775d262c2SVinicius Costa Gomes 	return NULL;
123875d262c2SVinicius Costa Gomes }
123975d262c2SVinicius Costa Gomes EXPORT_SYMBOL(hci_find_ltk);
124075d262c2SVinicius Costa Gomes 
1241c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
1242c9839a11SVinicius Costa Gomes 								u8 addr_type)
124375d262c2SVinicius Costa Gomes {
1244c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
124575d262c2SVinicius Costa Gomes 
1246c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list)
1247c9839a11SVinicius Costa Gomes 		if (addr_type == k->bdaddr_type &&
1248c9839a11SVinicius Costa Gomes 					bacmp(bdaddr, &k->bdaddr) == 0)
124975d262c2SVinicius Costa Gomes 			return k;
125075d262c2SVinicius Costa Gomes 
125175d262c2SVinicius Costa Gomes 	return NULL;
125275d262c2SVinicius Costa Gomes }
1253c9839a11SVinicius Costa Gomes EXPORT_SYMBOL(hci_find_ltk_by_addr);
125475d262c2SVinicius Costa Gomes 
1255d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
1256d25e28abSJohan Hedberg 				bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
125755ed8ca1SJohan Hedberg {
125855ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
12594df378a1SJohan Hedberg 	u8 old_key_type, persistent;
126055ed8ca1SJohan Hedberg 
126155ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
126255ed8ca1SJohan Hedberg 	if (old_key) {
126355ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
126455ed8ca1SJohan Hedberg 		key = old_key;
126555ed8ca1SJohan Hedberg 	} else {
126612adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
126755ed8ca1SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
126855ed8ca1SJohan Hedberg 		if (!key)
126955ed8ca1SJohan Hedberg 			return -ENOMEM;
127055ed8ca1SJohan Hedberg 		list_add(&key->list, &hdev->link_keys);
127155ed8ca1SJohan Hedberg 	}
127255ed8ca1SJohan Hedberg 
127355ed8ca1SJohan Hedberg 	BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type);
127455ed8ca1SJohan Hedberg 
1275d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
1276d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
1277d25e28abSJohan Hedberg 	 * previous key */
1278d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
1279d25e28abSJohan Hedberg 					(!conn || conn->remote_auth == 0xff) &&
1280655fe6ecSJohan Hedberg 					old_key_type == 0xff) {
1281d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
1282655fe6ecSJohan Hedberg 		if (conn)
1283655fe6ecSJohan Hedberg 			conn->key_type = type;
1284655fe6ecSJohan Hedberg 	}
1285d25e28abSJohan Hedberg 
128655ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
128755ed8ca1SJohan Hedberg 	memcpy(key->val, val, 16);
128855ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
128955ed8ca1SJohan Hedberg 
1290b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
129155ed8ca1SJohan Hedberg 		key->type = old_key_type;
12924748fed2SJohan Hedberg 	else
12934748fed2SJohan Hedberg 		key->type = type;
12944748fed2SJohan Hedberg 
12954df378a1SJohan Hedberg 	if (!new_key)
12964df378a1SJohan Hedberg 		return 0;
12974df378a1SJohan Hedberg 
12984df378a1SJohan Hedberg 	persistent = hci_persistent_key(hdev, conn, type, old_key_type);
12994df378a1SJohan Hedberg 
1300744cf19eSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
13014df378a1SJohan Hedberg 
13024df378a1SJohan Hedberg 	if (!persistent) {
13034df378a1SJohan Hedberg 		list_del(&key->list);
13044df378a1SJohan Hedberg 		kfree(key);
13054df378a1SJohan Hedberg 	}
130655ed8ca1SJohan Hedberg 
130755ed8ca1SJohan Hedberg 	return 0;
130855ed8ca1SJohan Hedberg }
130955ed8ca1SJohan Hedberg 
1310c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
1311c9839a11SVinicius Costa Gomes 				int new_key, u8 authenticated, u8 tk[16],
1312c9839a11SVinicius Costa Gomes 				u8 enc_size, u16 ediv, u8 rand[8])
131375d262c2SVinicius Costa Gomes {
1314c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
131575d262c2SVinicius Costa Gomes 
1316c9839a11SVinicius Costa Gomes 	if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK))
1317c9839a11SVinicius Costa Gomes 		return 0;
131875d262c2SVinicius Costa Gomes 
1319c9839a11SVinicius Costa Gomes 	old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type);
1320c9839a11SVinicius Costa Gomes 	if (old_key)
132175d262c2SVinicius Costa Gomes 		key = old_key;
1322c9839a11SVinicius Costa Gomes 	else {
1323c9839a11SVinicius Costa Gomes 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
132475d262c2SVinicius Costa Gomes 		if (!key)
132575d262c2SVinicius Costa Gomes 			return -ENOMEM;
1326c9839a11SVinicius Costa Gomes 		list_add(&key->list, &hdev->long_term_keys);
132775d262c2SVinicius Costa Gomes 	}
132875d262c2SVinicius Costa Gomes 
132975d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
1330c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
1331c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
1332c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
1333c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
1334c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
1335c9839a11SVinicius Costa Gomes 	key->type = type;
1336c9839a11SVinicius Costa Gomes 	memcpy(key->rand, rand, sizeof(key->rand));
133775d262c2SVinicius Costa Gomes 
1338c9839a11SVinicius Costa Gomes 	if (!new_key)
1339c9839a11SVinicius Costa Gomes 		return 0;
134075d262c2SVinicius Costa Gomes 
1341261cc5aaSVinicius Costa Gomes 	if (type & HCI_SMP_LTK)
1342261cc5aaSVinicius Costa Gomes 		mgmt_new_ltk(hdev, key, 1);
1343261cc5aaSVinicius Costa Gomes 
134475d262c2SVinicius Costa Gomes 	return 0;
134575d262c2SVinicius Costa Gomes }
134675d262c2SVinicius Costa Gomes 
134755ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
134855ed8ca1SJohan Hedberg {
134955ed8ca1SJohan Hedberg 	struct link_key *key;
135055ed8ca1SJohan Hedberg 
135155ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
135255ed8ca1SJohan Hedberg 	if (!key)
135355ed8ca1SJohan Hedberg 		return -ENOENT;
135455ed8ca1SJohan Hedberg 
135555ed8ca1SJohan Hedberg 	BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
135655ed8ca1SJohan Hedberg 
135755ed8ca1SJohan Hedberg 	list_del(&key->list);
135855ed8ca1SJohan Hedberg 	kfree(key);
135955ed8ca1SJohan Hedberg 
136055ed8ca1SJohan Hedberg 	return 0;
136155ed8ca1SJohan Hedberg }
136255ed8ca1SJohan Hedberg 
1363b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr)
1364b899efafSVinicius Costa Gomes {
1365b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1366b899efafSVinicius Costa Gomes 
1367b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1368b899efafSVinicius Costa Gomes 		if (bacmp(bdaddr, &k->bdaddr))
1369b899efafSVinicius Costa Gomes 			continue;
1370b899efafSVinicius Costa Gomes 
1371b899efafSVinicius Costa Gomes 		BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
1372b899efafSVinicius Costa Gomes 
1373b899efafSVinicius Costa Gomes 		list_del(&k->list);
1374b899efafSVinicius Costa Gomes 		kfree(k);
1375b899efafSVinicius Costa Gomes 	}
1376b899efafSVinicius Costa Gomes 
1377b899efafSVinicius Costa Gomes 	return 0;
1378b899efafSVinicius Costa Gomes }
1379b899efafSVinicius Costa Gomes 
13806bd32326SVille Tervo /* HCI command timer function */
13816bd32326SVille Tervo static void hci_cmd_timer(unsigned long arg)
13826bd32326SVille Tervo {
13836bd32326SVille Tervo 	struct hci_dev *hdev = (void *) arg;
13846bd32326SVille Tervo 
13856bd32326SVille Tervo 	BT_ERR("%s command tx timeout", hdev->name);
13866bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
1387c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
13886bd32326SVille Tervo }
13896bd32326SVille Tervo 
13902763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
13912763eda6SSzymon Janc 							bdaddr_t *bdaddr)
13922763eda6SSzymon Janc {
13932763eda6SSzymon Janc 	struct oob_data *data;
13942763eda6SSzymon Janc 
13952763eda6SSzymon Janc 	list_for_each_entry(data, &hdev->remote_oob_data, list)
13962763eda6SSzymon Janc 		if (bacmp(bdaddr, &data->bdaddr) == 0)
13972763eda6SSzymon Janc 			return data;
13982763eda6SSzymon Janc 
13992763eda6SSzymon Janc 	return NULL;
14002763eda6SSzymon Janc }
14012763eda6SSzymon Janc 
14022763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
14032763eda6SSzymon Janc {
14042763eda6SSzymon Janc 	struct oob_data *data;
14052763eda6SSzymon Janc 
14062763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
14072763eda6SSzymon Janc 	if (!data)
14082763eda6SSzymon Janc 		return -ENOENT;
14092763eda6SSzymon Janc 
14102763eda6SSzymon Janc 	BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
14112763eda6SSzymon Janc 
14122763eda6SSzymon Janc 	list_del(&data->list);
14132763eda6SSzymon Janc 	kfree(data);
14142763eda6SSzymon Janc 
14152763eda6SSzymon Janc 	return 0;
14162763eda6SSzymon Janc }
14172763eda6SSzymon Janc 
14182763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev)
14192763eda6SSzymon Janc {
14202763eda6SSzymon Janc 	struct oob_data *data, *n;
14212763eda6SSzymon Janc 
14222763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
14232763eda6SSzymon Janc 		list_del(&data->list);
14242763eda6SSzymon Janc 		kfree(data);
14252763eda6SSzymon Janc 	}
14262763eda6SSzymon Janc 
14272763eda6SSzymon Janc 	return 0;
14282763eda6SSzymon Janc }
14292763eda6SSzymon Janc 
14302763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
14312763eda6SSzymon Janc 								u8 *randomizer)
14322763eda6SSzymon Janc {
14332763eda6SSzymon Janc 	struct oob_data *data;
14342763eda6SSzymon Janc 
14352763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
14362763eda6SSzymon Janc 
14372763eda6SSzymon Janc 	if (!data) {
14382763eda6SSzymon Janc 		data = kmalloc(sizeof(*data), GFP_ATOMIC);
14392763eda6SSzymon Janc 		if (!data)
14402763eda6SSzymon Janc 			return -ENOMEM;
14412763eda6SSzymon Janc 
14422763eda6SSzymon Janc 		bacpy(&data->bdaddr, bdaddr);
14432763eda6SSzymon Janc 		list_add(&data->list, &hdev->remote_oob_data);
14442763eda6SSzymon Janc 	}
14452763eda6SSzymon Janc 
14462763eda6SSzymon Janc 	memcpy(data->hash, hash, sizeof(data->hash));
14472763eda6SSzymon Janc 	memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
14482763eda6SSzymon Janc 
14492763eda6SSzymon Janc 	BT_DBG("%s for %s", hdev->name, batostr(bdaddr));
14502763eda6SSzymon Janc 
14512763eda6SSzymon Janc 	return 0;
14522763eda6SSzymon Janc }
14532763eda6SSzymon Janc 
1454b2a66aadSAntti Julku struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev,
1455b2a66aadSAntti Julku 						bdaddr_t *bdaddr)
1456b2a66aadSAntti Julku {
1457b2a66aadSAntti Julku 	struct bdaddr_list *b;
1458b2a66aadSAntti Julku 
14598035ded4SLuiz Augusto von Dentz 	list_for_each_entry(b, &hdev->blacklist, list)
1460b2a66aadSAntti Julku 		if (bacmp(bdaddr, &b->bdaddr) == 0)
1461b2a66aadSAntti Julku 			return b;
1462b2a66aadSAntti Julku 
1463b2a66aadSAntti Julku 	return NULL;
1464b2a66aadSAntti Julku }
1465b2a66aadSAntti Julku 
1466b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev)
1467b2a66aadSAntti Julku {
1468b2a66aadSAntti Julku 	struct list_head *p, *n;
1469b2a66aadSAntti Julku 
1470b2a66aadSAntti Julku 	list_for_each_safe(p, n, &hdev->blacklist) {
1471b2a66aadSAntti Julku 		struct bdaddr_list *b;
1472b2a66aadSAntti Julku 
1473b2a66aadSAntti Julku 		b = list_entry(p, struct bdaddr_list, list);
1474b2a66aadSAntti Julku 
1475b2a66aadSAntti Julku 		list_del(p);
1476b2a66aadSAntti Julku 		kfree(b);
1477b2a66aadSAntti Julku 	}
1478b2a66aadSAntti Julku 
1479b2a66aadSAntti Julku 	return 0;
1480b2a66aadSAntti Julku }
1481b2a66aadSAntti Julku 
1482b2a66aadSAntti Julku int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr)
1483b2a66aadSAntti Julku {
1484b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1485b2a66aadSAntti Julku 
1486b2a66aadSAntti Julku 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
1487b2a66aadSAntti Julku 		return -EBADF;
1488b2a66aadSAntti Julku 
14895e762444SAntti Julku 	if (hci_blacklist_lookup(hdev, bdaddr))
14905e762444SAntti Julku 		return -EEXIST;
1491b2a66aadSAntti Julku 
1492b2a66aadSAntti Julku 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
14935e762444SAntti Julku 	if (!entry)
14945e762444SAntti Julku 		return -ENOMEM;
1495b2a66aadSAntti Julku 
1496b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
1497b2a66aadSAntti Julku 
1498b2a66aadSAntti Julku 	list_add(&entry->list, &hdev->blacklist);
1499b2a66aadSAntti Julku 
1500744cf19eSJohan Hedberg 	return mgmt_device_blocked(hdev, bdaddr);
1501b2a66aadSAntti Julku }
1502b2a66aadSAntti Julku 
1503b2a66aadSAntti Julku int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr)
1504b2a66aadSAntti Julku {
1505b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1506b2a66aadSAntti Julku 
15071ec918ceSSzymon Janc 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
15085e762444SAntti Julku 		return hci_blacklist_clear(hdev);
1509b2a66aadSAntti Julku 
1510b2a66aadSAntti Julku 	entry = hci_blacklist_lookup(hdev, bdaddr);
15111ec918ceSSzymon Janc 	if (!entry)
15125e762444SAntti Julku 		return -ENOENT;
1513b2a66aadSAntti Julku 
1514b2a66aadSAntti Julku 	list_del(&entry->list);
1515b2a66aadSAntti Julku 	kfree(entry);
1516b2a66aadSAntti Julku 
1517744cf19eSJohan Hedberg 	return mgmt_device_unblocked(hdev, bdaddr);
1518b2a66aadSAntti Julku }
1519b2a66aadSAntti Julku 
1520db323f2fSGustavo F. Padovan static void hci_clear_adv_cache(struct work_struct *work)
152135815085SAndre Guedes {
1522db323f2fSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev,
1523db323f2fSGustavo F. Padovan 							adv_work.work);
152435815085SAndre Guedes 
152535815085SAndre Guedes 	hci_dev_lock(hdev);
152635815085SAndre Guedes 
152735815085SAndre Guedes 	hci_adv_entries_clear(hdev);
152835815085SAndre Guedes 
152935815085SAndre Guedes 	hci_dev_unlock(hdev);
153035815085SAndre Guedes }
153135815085SAndre Guedes 
153276c8686fSAndre Guedes int hci_adv_entries_clear(struct hci_dev *hdev)
153376c8686fSAndre Guedes {
153476c8686fSAndre Guedes 	struct adv_entry *entry, *tmp;
153576c8686fSAndre Guedes 
153676c8686fSAndre Guedes 	list_for_each_entry_safe(entry, tmp, &hdev->adv_entries, list) {
153776c8686fSAndre Guedes 		list_del(&entry->list);
153876c8686fSAndre Guedes 		kfree(entry);
153976c8686fSAndre Guedes 	}
154076c8686fSAndre Guedes 
154176c8686fSAndre Guedes 	BT_DBG("%s adv cache cleared", hdev->name);
154276c8686fSAndre Guedes 
154376c8686fSAndre Guedes 	return 0;
154476c8686fSAndre Guedes }
154576c8686fSAndre Guedes 
154676c8686fSAndre Guedes struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr)
154776c8686fSAndre Guedes {
154876c8686fSAndre Guedes 	struct adv_entry *entry;
154976c8686fSAndre Guedes 
155076c8686fSAndre Guedes 	list_for_each_entry(entry, &hdev->adv_entries, list)
155176c8686fSAndre Guedes 		if (bacmp(bdaddr, &entry->bdaddr) == 0)
155276c8686fSAndre Guedes 			return entry;
155376c8686fSAndre Guedes 
155476c8686fSAndre Guedes 	return NULL;
155576c8686fSAndre Guedes }
155676c8686fSAndre Guedes 
155776c8686fSAndre Guedes static inline int is_connectable_adv(u8 evt_type)
155876c8686fSAndre Guedes {
155976c8686fSAndre Guedes 	if (evt_type == ADV_IND || evt_type == ADV_DIRECT_IND)
156076c8686fSAndre Guedes 		return 1;
156176c8686fSAndre Guedes 
156276c8686fSAndre Guedes 	return 0;
156376c8686fSAndre Guedes }
156476c8686fSAndre Guedes 
156576c8686fSAndre Guedes int hci_add_adv_entry(struct hci_dev *hdev,
156676c8686fSAndre Guedes 					struct hci_ev_le_advertising_info *ev)
156776c8686fSAndre Guedes {
156876c8686fSAndre Guedes 	struct adv_entry *entry;
156976c8686fSAndre Guedes 
157076c8686fSAndre Guedes 	if (!is_connectable_adv(ev->evt_type))
157176c8686fSAndre Guedes 		return -EINVAL;
157276c8686fSAndre Guedes 
157376c8686fSAndre Guedes 	/* Only new entries should be added to adv_entries. So, if
157476c8686fSAndre Guedes 	 * bdaddr was found, don't add it. */
157576c8686fSAndre Guedes 	if (hci_find_adv_entry(hdev, &ev->bdaddr))
157676c8686fSAndre Guedes 		return 0;
157776c8686fSAndre Guedes 
15784777bfdeSAndre Guedes 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
157976c8686fSAndre Guedes 	if (!entry)
158076c8686fSAndre Guedes 		return -ENOMEM;
158176c8686fSAndre Guedes 
158276c8686fSAndre Guedes 	bacpy(&entry->bdaddr, &ev->bdaddr);
158376c8686fSAndre Guedes 	entry->bdaddr_type = ev->bdaddr_type;
158476c8686fSAndre Guedes 
158576c8686fSAndre Guedes 	list_add(&entry->list, &hdev->adv_entries);
158676c8686fSAndre Guedes 
158776c8686fSAndre Guedes 	BT_DBG("%s adv entry added: address %s type %u", hdev->name,
158876c8686fSAndre Guedes 				batostr(&entry->bdaddr), entry->bdaddr_type);
158976c8686fSAndre Guedes 
159076c8686fSAndre Guedes 	return 0;
159176c8686fSAndre Guedes }
159276c8686fSAndre Guedes 
15931da177e4SLinus Torvalds /* Register HCI device */
15941da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
15951da177e4SLinus Torvalds {
15961da177e4SLinus Torvalds 	struct list_head *head = &hci_dev_list, *p;
159708add513SMat Martineau 	int i, id, error;
15981da177e4SLinus Torvalds 
1599e9b9cfa1SDavid Herrmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
16001da177e4SLinus Torvalds 
1601010666a1SDavid Herrmann 	if (!hdev->open || !hdev->close)
16021da177e4SLinus Torvalds 		return -EINVAL;
16031da177e4SLinus Torvalds 
160408add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
160508add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
160608add513SMat Martineau 	 */
160708add513SMat Martineau 	id = (hdev->dev_type == HCI_BREDR) ? 0 : 1;
160808add513SMat Martineau 
1609f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
16101da177e4SLinus Torvalds 
16111da177e4SLinus Torvalds 	/* Find first available device id */
16121da177e4SLinus Torvalds 	list_for_each(p, &hci_dev_list) {
16131da177e4SLinus Torvalds 		if (list_entry(p, struct hci_dev, list)->id != id)
16141da177e4SLinus Torvalds 			break;
16151da177e4SLinus Torvalds 		head = p; id++;
16161da177e4SLinus Torvalds 	}
16171da177e4SLinus Torvalds 
16181da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
16191da177e4SLinus Torvalds 	hdev->id = id;
1620c6feeb28SAndrei Emeltchenko 	list_add_tail(&hdev->list, head);
16211da177e4SLinus Torvalds 
162209fd0de5SGustavo F. Padovan 	mutex_init(&hdev->lock);
16231da177e4SLinus Torvalds 
16241da177e4SLinus Torvalds 	hdev->flags = 0;
1625d23264a8SAndre Guedes 	hdev->dev_flags = 0;
16261da177e4SLinus Torvalds 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
16275b7f9909SMarcel Holtmann 	hdev->esco_type = (ESCO_HV1);
16281da177e4SLinus Torvalds 	hdev->link_mode = (HCI_LM_ACCEPT);
162917fa4b9dSJohan Hedberg 	hdev->io_capability = 0x03; /* No Input No Output */
16301da177e4SLinus Torvalds 
163104837f64SMarcel Holtmann 	hdev->idle_timeout = 0;
163204837f64SMarcel Holtmann 	hdev->sniff_max_interval = 800;
163304837f64SMarcel Holtmann 	hdev->sniff_min_interval = 80;
163404837f64SMarcel Holtmann 
1635b78752ccSMarcel Holtmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
1636c347b765SGustavo F. Padovan 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
16373eff45eaSGustavo F. Padovan 	INIT_WORK(&hdev->tx_work, hci_tx_work);
1638b78752ccSMarcel Holtmann 
16391da177e4SLinus Torvalds 
16401da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->rx_q);
16411da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->cmd_q);
16421da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->raw_q);
16431da177e4SLinus Torvalds 
16446bd32326SVille Tervo 	setup_timer(&hdev->cmd_timer, hci_cmd_timer, (unsigned long) hdev);
16456bd32326SVille Tervo 
1646cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
1647ef222013SMarcel Holtmann 		hdev->reassembly[i] = NULL;
1648ef222013SMarcel Holtmann 
16491da177e4SLinus Torvalds 	init_waitqueue_head(&hdev->req_wait_q);
1650a6a67efdSThomas Gleixner 	mutex_init(&hdev->req_lock);
16511da177e4SLinus Torvalds 
165230883512SJohan Hedberg 	discovery_init(hdev);
16531da177e4SLinus Torvalds 
16541da177e4SLinus Torvalds 	hci_conn_hash_init(hdev);
16551da177e4SLinus Torvalds 
16562e58ef3eSJohan Hedberg 	INIT_LIST_HEAD(&hdev->mgmt_pending);
16572e58ef3eSJohan Hedberg 
1658ea4bd8baSDavid Miller 	INIT_LIST_HEAD(&hdev->blacklist);
1659f0358568SJohan Hedberg 
16602aeb9a1aSJohan Hedberg 	INIT_LIST_HEAD(&hdev->uuids);
16612aeb9a1aSJohan Hedberg 
166255ed8ca1SJohan Hedberg 	INIT_LIST_HEAD(&hdev->link_keys);
1663b899efafSVinicius Costa Gomes 	INIT_LIST_HEAD(&hdev->long_term_keys);
166455ed8ca1SJohan Hedberg 
16652763eda6SSzymon Janc 	INIT_LIST_HEAD(&hdev->remote_oob_data);
16662763eda6SSzymon Janc 
166776c8686fSAndre Guedes 	INIT_LIST_HEAD(&hdev->adv_entries);
166876c8686fSAndre Guedes 
1669db323f2fSGustavo F. Padovan 	INIT_DELAYED_WORK(&hdev->adv_work, hci_clear_adv_cache);
1670ab81cbf9SJohan Hedberg 	INIT_WORK(&hdev->power_on, hci_power_on);
16713243553fSJohan Hedberg 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
1672ab81cbf9SJohan Hedberg 
167316ab91abSJohan Hedberg 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
167416ab91abSJohan Hedberg 
16751da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
16761da177e4SLinus Torvalds 
16771da177e4SLinus Torvalds 	atomic_set(&hdev->promisc, 0);
16781da177e4SLinus Torvalds 
1679f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
16801da177e4SLinus Torvalds 
168132845eb1SGustavo F. Padovan 	hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND |
168232845eb1SGustavo F. Padovan 							WQ_MEM_RECLAIM, 1);
168333ca954dSDavid Herrmann 	if (!hdev->workqueue) {
168433ca954dSDavid Herrmann 		error = -ENOMEM;
168533ca954dSDavid Herrmann 		goto err;
168633ca954dSDavid Herrmann 	}
1687f48fd9c8SMarcel Holtmann 
168833ca954dSDavid Herrmann 	error = hci_add_sysfs(hdev);
168933ca954dSDavid Herrmann 	if (error < 0)
169033ca954dSDavid Herrmann 		goto err_wqueue;
16911da177e4SLinus Torvalds 
1692611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
1693611b30f7SMarcel Holtmann 				RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, hdev);
1694611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
1695611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
1696611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
1697611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
1698611b30f7SMarcel Holtmann 		}
1699611b30f7SMarcel Holtmann 	}
1700611b30f7SMarcel Holtmann 
1701a8b2d5c2SJohan Hedberg 	set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
1702a8b2d5c2SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->dev_flags);
17037f971041SGustavo F. Padovan 	schedule_work(&hdev->power_on);
1704ab81cbf9SJohan Hedberg 
17051da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
1706dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
17071da177e4SLinus Torvalds 
17081da177e4SLinus Torvalds 	return id;
1709f48fd9c8SMarcel Holtmann 
171033ca954dSDavid Herrmann err_wqueue:
171133ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
171233ca954dSDavid Herrmann err:
1713f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
1714f48fd9c8SMarcel Holtmann 	list_del(&hdev->list);
1715f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
1716f48fd9c8SMarcel Holtmann 
171733ca954dSDavid Herrmann 	return error;
17181da177e4SLinus Torvalds }
17191da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
17201da177e4SLinus Torvalds 
17211da177e4SLinus Torvalds /* Unregister HCI device */
172259735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
17231da177e4SLinus Torvalds {
1724ef222013SMarcel Holtmann 	int i;
1725ef222013SMarcel Holtmann 
1726c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
17271da177e4SLinus Torvalds 
1728f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
17291da177e4SLinus Torvalds 	list_del(&hdev->list);
1730f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
17311da177e4SLinus Torvalds 
17321da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
17331da177e4SLinus Torvalds 
1734cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
1735ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
1736ef222013SMarcel Holtmann 
1737ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
1738a8b2d5c2SJohan Hedberg 				!test_bit(HCI_SETUP, &hdev->dev_flags)) {
173909fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
1740744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
174109fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
174256e5cb86SJohan Hedberg 	}
1743ab81cbf9SJohan Hedberg 
17442e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
17452e58ef3eSJohan Hedberg 	 * pending list */
17462e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
17472e58ef3eSJohan Hedberg 
17481da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
17491da177e4SLinus Torvalds 
1750611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
1751611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
1752611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
1753611b30f7SMarcel Holtmann 	}
1754611b30f7SMarcel Holtmann 
1755ce242970SDavid Herrmann 	hci_del_sysfs(hdev);
1756147e2d59SDave Young 
1757db323f2fSGustavo F. Padovan 	cancel_delayed_work_sync(&hdev->adv_work);
1758c6f3c5f7SGustavo F. Padovan 
1759f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
1760f48fd9c8SMarcel Holtmann 
176109fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
1762e2e0cacbSJohan Hedberg 	hci_blacklist_clear(hdev);
17632aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
176455ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
1765b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
17662763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
176776c8686fSAndre Guedes 	hci_adv_entries_clear(hdev);
176809fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
1769e2e0cacbSJohan Hedberg 
1770dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
17711da177e4SLinus Torvalds }
17721da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
17731da177e4SLinus Torvalds 
17741da177e4SLinus Torvalds /* Suspend HCI device */
17751da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
17761da177e4SLinus Torvalds {
17771da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
17781da177e4SLinus Torvalds 	return 0;
17791da177e4SLinus Torvalds }
17801da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
17811da177e4SLinus Torvalds 
17821da177e4SLinus Torvalds /* Resume HCI device */
17831da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
17841da177e4SLinus Torvalds {
17851da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
17861da177e4SLinus Torvalds 	return 0;
17871da177e4SLinus Torvalds }
17881da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
17891da177e4SLinus Torvalds 
179076bca880SMarcel Holtmann /* Receive frame from HCI drivers */
179176bca880SMarcel Holtmann int hci_recv_frame(struct sk_buff *skb)
179276bca880SMarcel Holtmann {
179376bca880SMarcel Holtmann 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
179476bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
179576bca880SMarcel Holtmann 				&& !test_bit(HCI_INIT, &hdev->flags))) {
179676bca880SMarcel Holtmann 		kfree_skb(skb);
179776bca880SMarcel Holtmann 		return -ENXIO;
179876bca880SMarcel Holtmann 	}
179976bca880SMarcel Holtmann 
180076bca880SMarcel Holtmann 	/* Incomming skb */
180176bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
180276bca880SMarcel Holtmann 
180376bca880SMarcel Holtmann 	/* Time stamp */
180476bca880SMarcel Holtmann 	__net_timestamp(skb);
180576bca880SMarcel Holtmann 
180676bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
1807b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
1808c78ae283SMarcel Holtmann 
180976bca880SMarcel Holtmann 	return 0;
181076bca880SMarcel Holtmann }
181176bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
181276bca880SMarcel Holtmann 
181333e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
18141e429f38SGustavo F. Padovan 						  int count, __u8 index)
181533e882a5SSuraj Sumangala {
181633e882a5SSuraj Sumangala 	int len = 0;
181733e882a5SSuraj Sumangala 	int hlen = 0;
181833e882a5SSuraj Sumangala 	int remain = count;
181933e882a5SSuraj Sumangala 	struct sk_buff *skb;
182033e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
182133e882a5SSuraj Sumangala 
182233e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
182333e882a5SSuraj Sumangala 				index >= NUM_REASSEMBLY)
182433e882a5SSuraj Sumangala 		return -EILSEQ;
182533e882a5SSuraj Sumangala 
182633e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
182733e882a5SSuraj Sumangala 
182833e882a5SSuraj Sumangala 	if (!skb) {
182933e882a5SSuraj Sumangala 		switch (type) {
183033e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
183133e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
183233e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
183333e882a5SSuraj Sumangala 			break;
183433e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
183533e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
183633e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
183733e882a5SSuraj Sumangala 			break;
183833e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
183933e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
184033e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
184133e882a5SSuraj Sumangala 			break;
184233e882a5SSuraj Sumangala 		}
184333e882a5SSuraj Sumangala 
18441e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
184533e882a5SSuraj Sumangala 		if (!skb)
184633e882a5SSuraj Sumangala 			return -ENOMEM;
184733e882a5SSuraj Sumangala 
184833e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
184933e882a5SSuraj Sumangala 		scb->expect = hlen;
185033e882a5SSuraj Sumangala 		scb->pkt_type = type;
185133e882a5SSuraj Sumangala 
185233e882a5SSuraj Sumangala 		skb->dev = (void *) hdev;
185333e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
185433e882a5SSuraj Sumangala 	}
185533e882a5SSuraj Sumangala 
185633e882a5SSuraj Sumangala 	while (count) {
185733e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
185833e882a5SSuraj Sumangala 		len = min(scb->expect, (__u16)count);
185933e882a5SSuraj Sumangala 
186033e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
186133e882a5SSuraj Sumangala 
186233e882a5SSuraj Sumangala 		count -= len;
186333e882a5SSuraj Sumangala 		data += len;
186433e882a5SSuraj Sumangala 		scb->expect -= len;
186533e882a5SSuraj Sumangala 		remain = count;
186633e882a5SSuraj Sumangala 
186733e882a5SSuraj Sumangala 		switch (type) {
186833e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
186933e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
187033e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
187133e882a5SSuraj Sumangala 				scb->expect = h->plen;
187233e882a5SSuraj Sumangala 
187333e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
187433e882a5SSuraj Sumangala 					kfree_skb(skb);
187533e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
187633e882a5SSuraj Sumangala 					return -ENOMEM;
187733e882a5SSuraj Sumangala 				}
187833e882a5SSuraj Sumangala 			}
187933e882a5SSuraj Sumangala 			break;
188033e882a5SSuraj Sumangala 
188133e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
188233e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
188333e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
188433e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
188533e882a5SSuraj Sumangala 
188633e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
188733e882a5SSuraj Sumangala 					kfree_skb(skb);
188833e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
188933e882a5SSuraj Sumangala 					return -ENOMEM;
189033e882a5SSuraj Sumangala 				}
189133e882a5SSuraj Sumangala 			}
189233e882a5SSuraj Sumangala 			break;
189333e882a5SSuraj Sumangala 
189433e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
189533e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
189633e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
189733e882a5SSuraj Sumangala 				scb->expect = h->dlen;
189833e882a5SSuraj Sumangala 
189933e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
190033e882a5SSuraj Sumangala 					kfree_skb(skb);
190133e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
190233e882a5SSuraj Sumangala 					return -ENOMEM;
190333e882a5SSuraj Sumangala 				}
190433e882a5SSuraj Sumangala 			}
190533e882a5SSuraj Sumangala 			break;
190633e882a5SSuraj Sumangala 		}
190733e882a5SSuraj Sumangala 
190833e882a5SSuraj Sumangala 		if (scb->expect == 0) {
190933e882a5SSuraj Sumangala 			/* Complete frame */
191033e882a5SSuraj Sumangala 
191133e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
191233e882a5SSuraj Sumangala 			hci_recv_frame(skb);
191333e882a5SSuraj Sumangala 
191433e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
191533e882a5SSuraj Sumangala 			return remain;
191633e882a5SSuraj Sumangala 		}
191733e882a5SSuraj Sumangala 	}
191833e882a5SSuraj Sumangala 
191933e882a5SSuraj Sumangala 	return remain;
192033e882a5SSuraj Sumangala }
192133e882a5SSuraj Sumangala 
1922ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
1923ef222013SMarcel Holtmann {
1924f39a3c06SSuraj Sumangala 	int rem = 0;
1925f39a3c06SSuraj Sumangala 
1926ef222013SMarcel Holtmann 	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
1927ef222013SMarcel Holtmann 		return -EILSEQ;
1928ef222013SMarcel Holtmann 
1929da5f6c37SGustavo F. Padovan 	while (count) {
19301e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count, type - 1);
1931f39a3c06SSuraj Sumangala 		if (rem < 0)
1932f39a3c06SSuraj Sumangala 			return rem;
1933ef222013SMarcel Holtmann 
1934f39a3c06SSuraj Sumangala 		data += (count - rem);
1935f39a3c06SSuraj Sumangala 		count = rem;
1936f81c6224SJoe Perches 	}
1937ef222013SMarcel Holtmann 
1938f39a3c06SSuraj Sumangala 	return rem;
1939ef222013SMarcel Holtmann }
1940ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment);
1941ef222013SMarcel Holtmann 
194299811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
194399811510SSuraj Sumangala 
194499811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
194599811510SSuraj Sumangala {
194699811510SSuraj Sumangala 	int type;
194799811510SSuraj Sumangala 	int rem = 0;
194899811510SSuraj Sumangala 
1949da5f6c37SGustavo F. Padovan 	while (count) {
195099811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
195199811510SSuraj Sumangala 
195299811510SSuraj Sumangala 		if (!skb) {
195399811510SSuraj Sumangala 			struct { char type; } *pkt;
195499811510SSuraj Sumangala 
195599811510SSuraj Sumangala 			/* Start of the frame */
195699811510SSuraj Sumangala 			pkt = data;
195799811510SSuraj Sumangala 			type = pkt->type;
195899811510SSuraj Sumangala 
195999811510SSuraj Sumangala 			data++;
196099811510SSuraj Sumangala 			count--;
196199811510SSuraj Sumangala 		} else
196299811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
196399811510SSuraj Sumangala 
19641e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
19651e429f38SGustavo F. Padovan 							STREAM_REASSEMBLY);
196699811510SSuraj Sumangala 		if (rem < 0)
196799811510SSuraj Sumangala 			return rem;
196899811510SSuraj Sumangala 
196999811510SSuraj Sumangala 		data += (count - rem);
197099811510SSuraj Sumangala 		count = rem;
1971f81c6224SJoe Perches 	}
197299811510SSuraj Sumangala 
197399811510SSuraj Sumangala 	return rem;
197499811510SSuraj Sumangala }
197599811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
197699811510SSuraj Sumangala 
19771da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
19781da177e4SLinus Torvalds 
19791da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
19801da177e4SLinus Torvalds {
19811da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
19821da177e4SLinus Torvalds 
1983f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
19841da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
1985f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
19861da177e4SLinus Torvalds 
19871da177e4SLinus Torvalds 	return 0;
19881da177e4SLinus Torvalds }
19891da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
19901da177e4SLinus Torvalds 
19911da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
19921da177e4SLinus Torvalds {
19931da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
19941da177e4SLinus Torvalds 
1995f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
19961da177e4SLinus Torvalds 	list_del(&cb->list);
1997f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
19981da177e4SLinus Torvalds 
19991da177e4SLinus Torvalds 	return 0;
20001da177e4SLinus Torvalds }
20011da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
20021da177e4SLinus Torvalds 
20031da177e4SLinus Torvalds static int hci_send_frame(struct sk_buff *skb)
20041da177e4SLinus Torvalds {
20051da177e4SLinus Torvalds 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
20061da177e4SLinus Torvalds 
20071da177e4SLinus Torvalds 	if (!hdev) {
20081da177e4SLinus Torvalds 		kfree_skb(skb);
20091da177e4SLinus Torvalds 		return -ENODEV;
20101da177e4SLinus Torvalds 	}
20111da177e4SLinus Torvalds 
20120d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
20131da177e4SLinus Torvalds 
20141da177e4SLinus Torvalds 	if (atomic_read(&hdev->promisc)) {
20151da177e4SLinus Torvalds 		/* Time stamp */
2016a61bbcf2SPatrick McHardy 		__net_timestamp(skb);
20171da177e4SLinus Torvalds 
2018eec8d2bcSJohan Hedberg 		hci_send_to_sock(hdev, skb, NULL);
20191da177e4SLinus Torvalds 	}
20201da177e4SLinus Torvalds 
20211da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
20221da177e4SLinus Torvalds 	skb_orphan(skb);
20231da177e4SLinus Torvalds 
20241da177e4SLinus Torvalds 	return hdev->send(skb);
20251da177e4SLinus Torvalds }
20261da177e4SLinus Torvalds 
20271da177e4SLinus Torvalds /* Send HCI command */
2028a9de9248SMarcel Holtmann int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)
20291da177e4SLinus Torvalds {
20301da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
20311da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
20321da177e4SLinus Torvalds 	struct sk_buff *skb;
20331da177e4SLinus Torvalds 
2034a9de9248SMarcel Holtmann 	BT_DBG("%s opcode 0x%x plen %d", hdev->name, opcode, plen);
20351da177e4SLinus Torvalds 
20361da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
20371da177e4SLinus Torvalds 	if (!skb) {
2038ef222013SMarcel Holtmann 		BT_ERR("%s no memory for command", hdev->name);
20391da177e4SLinus Torvalds 		return -ENOMEM;
20401da177e4SLinus Torvalds 	}
20411da177e4SLinus Torvalds 
20421da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
2043a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
20441da177e4SLinus Torvalds 	hdr->plen   = plen;
20451da177e4SLinus Torvalds 
20461da177e4SLinus Torvalds 	if (plen)
20471da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
20481da177e4SLinus Torvalds 
20491da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
20501da177e4SLinus Torvalds 
20510d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
20521da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
2053c78ae283SMarcel Holtmann 
2054a5040efaSJohan Hedberg 	if (test_bit(HCI_INIT, &hdev->flags))
2055a5040efaSJohan Hedberg 		hdev->init_last_cmd = opcode;
2056a5040efaSJohan Hedberg 
20571da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
2058c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
20591da177e4SLinus Torvalds 
20601da177e4SLinus Torvalds 	return 0;
20611da177e4SLinus Torvalds }
20621da177e4SLinus Torvalds 
20631da177e4SLinus Torvalds /* Get data from the previously sent command */
2064a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
20651da177e4SLinus Torvalds {
20661da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
20671da177e4SLinus Torvalds 
20681da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
20691da177e4SLinus Torvalds 		return NULL;
20701da177e4SLinus Torvalds 
20711da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
20721da177e4SLinus Torvalds 
2073a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
20741da177e4SLinus Torvalds 		return NULL;
20751da177e4SLinus Torvalds 
2076a9de9248SMarcel Holtmann 	BT_DBG("%s opcode 0x%x", hdev->name, opcode);
20771da177e4SLinus Torvalds 
20781da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
20791da177e4SLinus Torvalds }
20801da177e4SLinus Torvalds 
20811da177e4SLinus Torvalds /* Send ACL data */
20821da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
20831da177e4SLinus Torvalds {
20841da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
20851da177e4SLinus Torvalds 	int len = skb->len;
20861da177e4SLinus Torvalds 
2087badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
2088badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
20899c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
2090aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
2091aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
20921da177e4SLinus Torvalds }
20931da177e4SLinus Torvalds 
209473d80debSLuiz Augusto von Dentz static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue,
209573d80debSLuiz Augusto von Dentz 				struct sk_buff *skb, __u16 flags)
20961da177e4SLinus Torvalds {
20971da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
20981da177e4SLinus Torvalds 	struct sk_buff *list;
20991da177e4SLinus Torvalds 
210070f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
210170f23020SAndrei Emeltchenko 	if (!list) {
21021da177e4SLinus Torvalds 		/* Non fragmented */
21031da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
21041da177e4SLinus Torvalds 
210573d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
21061da177e4SLinus Torvalds 	} else {
21071da177e4SLinus Torvalds 		/* Fragmented */
21081da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
21091da177e4SLinus Torvalds 
21101da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
21111da177e4SLinus Torvalds 
21121da177e4SLinus Torvalds 		/* Queue all fragments atomically */
2113af3e6359SGustavo F. Padovan 		spin_lock(&queue->lock);
21141da177e4SLinus Torvalds 
211573d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
2116e702112fSAndrei Emeltchenko 
2117e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
2118e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
21191da177e4SLinus Torvalds 		do {
21201da177e4SLinus Torvalds 			skb = list; list = list->next;
21211da177e4SLinus Torvalds 
21221da177e4SLinus Torvalds 			skb->dev = (void *) hdev;
21230d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2124e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
21251da177e4SLinus Torvalds 
21261da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
21271da177e4SLinus Torvalds 
212873d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
21291da177e4SLinus Torvalds 		} while (list);
21301da177e4SLinus Torvalds 
2131af3e6359SGustavo F. Padovan 		spin_unlock(&queue->lock);
21321da177e4SLinus Torvalds 	}
213373d80debSLuiz Augusto von Dentz }
213473d80debSLuiz Augusto von Dentz 
213573d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
213673d80debSLuiz Augusto von Dentz {
213773d80debSLuiz Augusto von Dentz 	struct hci_conn *conn = chan->conn;
213873d80debSLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
213973d80debSLuiz Augusto von Dentz 
214073d80debSLuiz Augusto von Dentz 	BT_DBG("%s chan %p flags 0x%x", hdev->name, chan, flags);
214173d80debSLuiz Augusto von Dentz 
214273d80debSLuiz Augusto von Dentz 	skb->dev = (void *) hdev;
214373d80debSLuiz Augusto von Dentz 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
214473d80debSLuiz Augusto von Dentz 	hci_add_acl_hdr(skb, conn->handle, flags);
214573d80debSLuiz Augusto von Dentz 
214673d80debSLuiz Augusto von Dentz 	hci_queue_acl(conn, &chan->data_q, skb, flags);
21471da177e4SLinus Torvalds 
21483eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
21491da177e4SLinus Torvalds }
21501da177e4SLinus Torvalds EXPORT_SYMBOL(hci_send_acl);
21511da177e4SLinus Torvalds 
21521da177e4SLinus Torvalds /* Send SCO data */
21530d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
21541da177e4SLinus Torvalds {
21551da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
21561da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
21571da177e4SLinus Torvalds 
21581da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
21591da177e4SLinus Torvalds 
2160aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
21611da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
21621da177e4SLinus Torvalds 
2163badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
2164badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
21659c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
21661da177e4SLinus Torvalds 
21671da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
21680d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
2169c78ae283SMarcel Holtmann 
21701da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
21713eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
21721da177e4SLinus Torvalds }
21731da177e4SLinus Torvalds EXPORT_SYMBOL(hci_send_sco);
21741da177e4SLinus Torvalds 
21751da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
21761da177e4SLinus Torvalds 
21771da177e4SLinus Torvalds /* HCI Connection scheduler */
21781da177e4SLinus Torvalds static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote)
21791da177e4SLinus Torvalds {
21801da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
21818035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
21821da177e4SLinus Torvalds 	int num = 0, min = ~0;
21831da177e4SLinus Torvalds 
21841da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
21851da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
2186bf4c6325SGustavo F. Padovan 
2187bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2188bf4c6325SGustavo F. Padovan 
2189bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2190769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
21911da177e4SLinus Torvalds 			continue;
2192769be974SMarcel Holtmann 
2193769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
2194769be974SMarcel Holtmann 			continue;
2195769be974SMarcel Holtmann 
21961da177e4SLinus Torvalds 		num++;
21971da177e4SLinus Torvalds 
21981da177e4SLinus Torvalds 		if (c->sent < min) {
21991da177e4SLinus Torvalds 			min  = c->sent;
22001da177e4SLinus Torvalds 			conn = c;
22011da177e4SLinus Torvalds 		}
220252087a79SLuiz Augusto von Dentz 
220352087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
220452087a79SLuiz Augusto von Dentz 			break;
22051da177e4SLinus Torvalds 	}
22061da177e4SLinus Torvalds 
2207bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2208bf4c6325SGustavo F. Padovan 
22091da177e4SLinus Torvalds 	if (conn) {
22106ed58ec5SVille Tervo 		int cnt, q;
22116ed58ec5SVille Tervo 
22126ed58ec5SVille Tervo 		switch (conn->type) {
22136ed58ec5SVille Tervo 		case ACL_LINK:
22146ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
22156ed58ec5SVille Tervo 			break;
22166ed58ec5SVille Tervo 		case SCO_LINK:
22176ed58ec5SVille Tervo 		case ESCO_LINK:
22186ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
22196ed58ec5SVille Tervo 			break;
22206ed58ec5SVille Tervo 		case LE_LINK:
22216ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
22226ed58ec5SVille Tervo 			break;
22236ed58ec5SVille Tervo 		default:
22246ed58ec5SVille Tervo 			cnt = 0;
22256ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
22266ed58ec5SVille Tervo 		}
22276ed58ec5SVille Tervo 
22286ed58ec5SVille Tervo 		q = cnt / num;
22291da177e4SLinus Torvalds 		*quote = q ? q : 1;
22301da177e4SLinus Torvalds 	} else
22311da177e4SLinus Torvalds 		*quote = 0;
22321da177e4SLinus Torvalds 
22331da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
22341da177e4SLinus Torvalds 	return conn;
22351da177e4SLinus Torvalds }
22361da177e4SLinus Torvalds 
2237bae1f5d9SVille Tervo static inline void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
22381da177e4SLinus Torvalds {
22391da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
22401da177e4SLinus Torvalds 	struct hci_conn *c;
22411da177e4SLinus Torvalds 
2242bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
22431da177e4SLinus Torvalds 
2244bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2245bf4c6325SGustavo F. Padovan 
22461da177e4SLinus Torvalds 	/* Kill stalled connections */
2247bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2248bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
2249bae1f5d9SVille Tervo 			BT_ERR("%s killing stalled connection %s",
22501da177e4SLinus Torvalds 				hdev->name, batostr(&c->dst));
22511da177e4SLinus Torvalds 			hci_acl_disconn(c, 0x13);
22521da177e4SLinus Torvalds 		}
22531da177e4SLinus Torvalds 	}
2254bf4c6325SGustavo F. Padovan 
2255bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
22561da177e4SLinus Torvalds }
22571da177e4SLinus Torvalds 
225873d80debSLuiz Augusto von Dentz static inline struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
225973d80debSLuiz Augusto von Dentz 						int *quote)
226073d80debSLuiz Augusto von Dentz {
226173d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
226273d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
226373d80debSLuiz Augusto von Dentz 	int num = 0, min = ~0, cur_prio = 0;
226473d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
226573d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
226673d80debSLuiz Augusto von Dentz 
226773d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
226873d80debSLuiz Augusto von Dentz 
2269bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2270bf4c6325SGustavo F. Padovan 
2271bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
227273d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
227373d80debSLuiz Augusto von Dentz 
227473d80debSLuiz Augusto von Dentz 		if (conn->type != type)
227573d80debSLuiz Augusto von Dentz 			continue;
227673d80debSLuiz Augusto von Dentz 
227773d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
227873d80debSLuiz Augusto von Dentz 			continue;
227973d80debSLuiz Augusto von Dentz 
228073d80debSLuiz Augusto von Dentz 		conn_num++;
228173d80debSLuiz Augusto von Dentz 
22828192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
228373d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
228473d80debSLuiz Augusto von Dentz 
228573d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
228673d80debSLuiz Augusto von Dentz 				continue;
228773d80debSLuiz Augusto von Dentz 
228873d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
228973d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
229073d80debSLuiz Augusto von Dentz 				continue;
229173d80debSLuiz Augusto von Dentz 
229273d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
229373d80debSLuiz Augusto von Dentz 				num = 0;
229473d80debSLuiz Augusto von Dentz 				min = ~0;
229573d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
229673d80debSLuiz Augusto von Dentz 			}
229773d80debSLuiz Augusto von Dentz 
229873d80debSLuiz Augusto von Dentz 			num++;
229973d80debSLuiz Augusto von Dentz 
230073d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
230173d80debSLuiz Augusto von Dentz 				min  = conn->sent;
230273d80debSLuiz Augusto von Dentz 				chan = tmp;
230373d80debSLuiz Augusto von Dentz 			}
230473d80debSLuiz Augusto von Dentz 		}
230573d80debSLuiz Augusto von Dentz 
230673d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
230773d80debSLuiz Augusto von Dentz 			break;
230873d80debSLuiz Augusto von Dentz 	}
230973d80debSLuiz Augusto von Dentz 
2310bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2311bf4c6325SGustavo F. Padovan 
231273d80debSLuiz Augusto von Dentz 	if (!chan)
231373d80debSLuiz Augusto von Dentz 		return NULL;
231473d80debSLuiz Augusto von Dentz 
231573d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
231673d80debSLuiz Augusto von Dentz 	case ACL_LINK:
231773d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
231873d80debSLuiz Augusto von Dentz 		break;
231973d80debSLuiz Augusto von Dentz 	case SCO_LINK:
232073d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
232173d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
232273d80debSLuiz Augusto von Dentz 		break;
232373d80debSLuiz Augusto von Dentz 	case LE_LINK:
232473d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
232573d80debSLuiz Augusto von Dentz 		break;
232673d80debSLuiz Augusto von Dentz 	default:
232773d80debSLuiz Augusto von Dentz 		cnt = 0;
232873d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
232973d80debSLuiz Augusto von Dentz 	}
233073d80debSLuiz Augusto von Dentz 
233173d80debSLuiz Augusto von Dentz 	q = cnt / num;
233273d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
233373d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
233473d80debSLuiz Augusto von Dentz 	return chan;
233573d80debSLuiz Augusto von Dentz }
233673d80debSLuiz Augusto von Dentz 
233702b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
233802b20f0bSLuiz Augusto von Dentz {
233902b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
234002b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
234102b20f0bSLuiz Augusto von Dentz 	int num = 0;
234202b20f0bSLuiz Augusto von Dentz 
234302b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
234402b20f0bSLuiz Augusto von Dentz 
2345bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2346bf4c6325SGustavo F. Padovan 
2347bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
234802b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
234902b20f0bSLuiz Augusto von Dentz 
235002b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
235102b20f0bSLuiz Augusto von Dentz 			continue;
235202b20f0bSLuiz Augusto von Dentz 
235302b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
235402b20f0bSLuiz Augusto von Dentz 			continue;
235502b20f0bSLuiz Augusto von Dentz 
235602b20f0bSLuiz Augusto von Dentz 		num++;
235702b20f0bSLuiz Augusto von Dentz 
23588192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
235902b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
236002b20f0bSLuiz Augusto von Dentz 
236102b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
236202b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
236302b20f0bSLuiz Augusto von Dentz 				continue;
236402b20f0bSLuiz Augusto von Dentz 			}
236502b20f0bSLuiz Augusto von Dentz 
236602b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
236702b20f0bSLuiz Augusto von Dentz 				continue;
236802b20f0bSLuiz Augusto von Dentz 
236902b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
237002b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
237102b20f0bSLuiz Augusto von Dentz 				continue;
237202b20f0bSLuiz Augusto von Dentz 
237302b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
237402b20f0bSLuiz Augusto von Dentz 
237502b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
237602b20f0bSLuiz Augusto von Dentz 								skb->priority);
237702b20f0bSLuiz Augusto von Dentz 		}
237802b20f0bSLuiz Augusto von Dentz 
237902b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
238002b20f0bSLuiz Augusto von Dentz 			break;
238102b20f0bSLuiz Augusto von Dentz 	}
2382bf4c6325SGustavo F. Padovan 
2383bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2384bf4c6325SGustavo F. Padovan 
238502b20f0bSLuiz Augusto von Dentz }
238602b20f0bSLuiz Augusto von Dentz 
2387b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
2388b71d385aSAndrei Emeltchenko {
2389b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
2390b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
2391b71d385aSAndrei Emeltchenko }
2392b71d385aSAndrei Emeltchenko 
2393b71d385aSAndrei Emeltchenko static inline void hci_sched_acl_pkt(struct hci_dev *hdev)
23941da177e4SLinus Torvalds {
239573d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
23961da177e4SLinus Torvalds 	struct sk_buff *skb;
23971da177e4SLinus Torvalds 	int quote;
239873d80debSLuiz Augusto von Dentz 	unsigned int cnt;
23991da177e4SLinus Torvalds 
24001da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
24011da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
24021da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
2403cc48dc0aSAndrei Emeltchenko 		if (!hdev->acl_cnt && time_after(jiffies, hdev->acl_last_tx +
2404cc48dc0aSAndrei Emeltchenko 					msecs_to_jiffies(HCI_ACL_TX_TIMEOUT)))
2405bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
24061da177e4SLinus Torvalds 	}
24071da177e4SLinus Torvalds 
240873d80debSLuiz Augusto von Dentz 	cnt = hdev->acl_cnt;
240904837f64SMarcel Holtmann 
241073d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
241173d80debSLuiz Augusto von Dentz 			(chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
2412ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
2413ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
241473d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
241573d80debSLuiz Augusto von Dentz 					skb->len, skb->priority);
241673d80debSLuiz Augusto von Dentz 
2417ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
2418ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
2419ec1cce24SLuiz Augusto von Dentz 				break;
2420ec1cce24SLuiz Augusto von Dentz 
2421ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
2422ec1cce24SLuiz Augusto von Dentz 
242373d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
242473d80debSLuiz Augusto von Dentz 						bt_cb(skb)->force_active);
242504837f64SMarcel Holtmann 
24261da177e4SLinus Torvalds 			hci_send_frame(skb);
24271da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
24281da177e4SLinus Torvalds 
24291da177e4SLinus Torvalds 			hdev->acl_cnt--;
243073d80debSLuiz Augusto von Dentz 			chan->sent++;
243173d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
24321da177e4SLinus Torvalds 		}
24331da177e4SLinus Torvalds 	}
243402b20f0bSLuiz Augusto von Dentz 
243502b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
243602b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
24371da177e4SLinus Torvalds }
24381da177e4SLinus Torvalds 
2439b71d385aSAndrei Emeltchenko static inline void hci_sched_acl_blk(struct hci_dev *hdev)
2440b71d385aSAndrei Emeltchenko {
2441b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
2442b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
2443b71d385aSAndrei Emeltchenko 	int quote;
2444b71d385aSAndrei Emeltchenko 	unsigned int cnt;
2445b71d385aSAndrei Emeltchenko 
2446b71d385aSAndrei Emeltchenko 	if (!test_bit(HCI_RAW, &hdev->flags)) {
2447b71d385aSAndrei Emeltchenko 		/* ACL tx timeout must be longer than maximum
2448b71d385aSAndrei Emeltchenko 		 * link supervision timeout (40.9 seconds) */
2449b71d385aSAndrei Emeltchenko 		if (!hdev->block_cnt && time_after(jiffies, hdev->acl_last_tx +
2450b71d385aSAndrei Emeltchenko 					msecs_to_jiffies(HCI_ACL_TX_TIMEOUT)))
2451b71d385aSAndrei Emeltchenko 			hci_link_tx_to(hdev, ACL_LINK);
2452b71d385aSAndrei Emeltchenko 	}
2453b71d385aSAndrei Emeltchenko 
2454b71d385aSAndrei Emeltchenko 	cnt = hdev->block_cnt;
2455b71d385aSAndrei Emeltchenko 
2456b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
2457b71d385aSAndrei Emeltchenko 			(chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
2458b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
2459b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
2460b71d385aSAndrei Emeltchenko 			int blocks;
2461b71d385aSAndrei Emeltchenko 
2462b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
2463b71d385aSAndrei Emeltchenko 						skb->len, skb->priority);
2464b71d385aSAndrei Emeltchenko 
2465b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
2466b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
2467b71d385aSAndrei Emeltchenko 				break;
2468b71d385aSAndrei Emeltchenko 
2469b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
2470b71d385aSAndrei Emeltchenko 
2471b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
2472b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
2473b71d385aSAndrei Emeltchenko 				return;
2474b71d385aSAndrei Emeltchenko 
2475b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
2476b71d385aSAndrei Emeltchenko 						bt_cb(skb)->force_active);
2477b71d385aSAndrei Emeltchenko 
2478b71d385aSAndrei Emeltchenko 			hci_send_frame(skb);
2479b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
2480b71d385aSAndrei Emeltchenko 
2481b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
2482b71d385aSAndrei Emeltchenko 			quote -= blocks;
2483b71d385aSAndrei Emeltchenko 
2484b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
2485b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
2486b71d385aSAndrei Emeltchenko 		}
2487b71d385aSAndrei Emeltchenko 	}
2488b71d385aSAndrei Emeltchenko 
2489b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
2490b71d385aSAndrei Emeltchenko 		hci_prio_recalculate(hdev, ACL_LINK);
2491b71d385aSAndrei Emeltchenko }
2492b71d385aSAndrei Emeltchenko 
2493b71d385aSAndrei Emeltchenko static inline void hci_sched_acl(struct hci_dev *hdev)
2494b71d385aSAndrei Emeltchenko {
2495b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
2496b71d385aSAndrei Emeltchenko 
2497b71d385aSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK))
2498b71d385aSAndrei Emeltchenko 		return;
2499b71d385aSAndrei Emeltchenko 
2500b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
2501b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
2502b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
2503b71d385aSAndrei Emeltchenko 		break;
2504b71d385aSAndrei Emeltchenko 
2505b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
2506b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
2507b71d385aSAndrei Emeltchenko 		break;
2508b71d385aSAndrei Emeltchenko 	}
2509b71d385aSAndrei Emeltchenko }
2510b71d385aSAndrei Emeltchenko 
25111da177e4SLinus Torvalds /* Schedule SCO */
25121da177e4SLinus Torvalds static inline void hci_sched_sco(struct hci_dev *hdev)
25131da177e4SLinus Torvalds {
25141da177e4SLinus Torvalds 	struct hci_conn *conn;
25151da177e4SLinus Torvalds 	struct sk_buff *skb;
25161da177e4SLinus Torvalds 	int quote;
25171da177e4SLinus Torvalds 
25181da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
25191da177e4SLinus Torvalds 
252052087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
252152087a79SLuiz Augusto von Dentz 		return;
252252087a79SLuiz Augusto von Dentz 
25231da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
25241da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
25251da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
25261da177e4SLinus Torvalds 			hci_send_frame(skb);
25271da177e4SLinus Torvalds 
25281da177e4SLinus Torvalds 			conn->sent++;
25291da177e4SLinus Torvalds 			if (conn->sent == ~0)
25301da177e4SLinus Torvalds 				conn->sent = 0;
25311da177e4SLinus Torvalds 		}
25321da177e4SLinus Torvalds 	}
25331da177e4SLinus Torvalds }
25341da177e4SLinus Torvalds 
2535b6a0dc82SMarcel Holtmann static inline void hci_sched_esco(struct hci_dev *hdev)
2536b6a0dc82SMarcel Holtmann {
2537b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
2538b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
2539b6a0dc82SMarcel Holtmann 	int quote;
2540b6a0dc82SMarcel Holtmann 
2541b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
2542b6a0dc82SMarcel Holtmann 
254352087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
254452087a79SLuiz Augusto von Dentz 		return;
254552087a79SLuiz Augusto von Dentz 
2546b6a0dc82SMarcel Holtmann 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, &quote))) {
2547b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
2548b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
2549b6a0dc82SMarcel Holtmann 			hci_send_frame(skb);
2550b6a0dc82SMarcel Holtmann 
2551b6a0dc82SMarcel Holtmann 			conn->sent++;
2552b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
2553b6a0dc82SMarcel Holtmann 				conn->sent = 0;
2554b6a0dc82SMarcel Holtmann 		}
2555b6a0dc82SMarcel Holtmann 	}
2556b6a0dc82SMarcel Holtmann }
2557b6a0dc82SMarcel Holtmann 
25586ed58ec5SVille Tervo static inline void hci_sched_le(struct hci_dev *hdev)
25596ed58ec5SVille Tervo {
256073d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
25616ed58ec5SVille Tervo 	struct sk_buff *skb;
256202b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
25636ed58ec5SVille Tervo 
25646ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
25656ed58ec5SVille Tervo 
256652087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
256752087a79SLuiz Augusto von Dentz 		return;
256852087a79SLuiz Augusto von Dentz 
25696ed58ec5SVille Tervo 	if (!test_bit(HCI_RAW, &hdev->flags)) {
25706ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
25716ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
2572bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
25736ed58ec5SVille Tervo 				time_after(jiffies, hdev->le_last_tx + HZ * 45))
2574bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
25756ed58ec5SVille Tervo 	}
25766ed58ec5SVille Tervo 
25776ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
257802b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
257973d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
2580ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
2581ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
258273d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
258373d80debSLuiz Augusto von Dentz 					skb->len, skb->priority);
25846ed58ec5SVille Tervo 
2585ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
2586ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
2587ec1cce24SLuiz Augusto von Dentz 				break;
2588ec1cce24SLuiz Augusto von Dentz 
2589ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
2590ec1cce24SLuiz Augusto von Dentz 
25916ed58ec5SVille Tervo 			hci_send_frame(skb);
25926ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
25936ed58ec5SVille Tervo 
25946ed58ec5SVille Tervo 			cnt--;
259573d80debSLuiz Augusto von Dentz 			chan->sent++;
259673d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
25976ed58ec5SVille Tervo 		}
25986ed58ec5SVille Tervo 	}
259973d80debSLuiz Augusto von Dentz 
26006ed58ec5SVille Tervo 	if (hdev->le_pkts)
26016ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
26026ed58ec5SVille Tervo 	else
26036ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
260402b20f0bSLuiz Augusto von Dentz 
260502b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
260602b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
26076ed58ec5SVille Tervo }
26086ed58ec5SVille Tervo 
26093eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
26101da177e4SLinus Torvalds {
26113eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
26121da177e4SLinus Torvalds 	struct sk_buff *skb;
26131da177e4SLinus Torvalds 
26146ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
26156ed58ec5SVille Tervo 		hdev->sco_cnt, hdev->le_cnt);
26161da177e4SLinus Torvalds 
26171da177e4SLinus Torvalds 	/* Schedule queues and send stuff to HCI driver */
26181da177e4SLinus Torvalds 
26191da177e4SLinus Torvalds 	hci_sched_acl(hdev);
26201da177e4SLinus Torvalds 
26211da177e4SLinus Torvalds 	hci_sched_sco(hdev);
26221da177e4SLinus Torvalds 
2623b6a0dc82SMarcel Holtmann 	hci_sched_esco(hdev);
2624b6a0dc82SMarcel Holtmann 
26256ed58ec5SVille Tervo 	hci_sched_le(hdev);
26266ed58ec5SVille Tervo 
26271da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
26281da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
26291da177e4SLinus Torvalds 		hci_send_frame(skb);
26301da177e4SLinus Torvalds }
26311da177e4SLinus Torvalds 
263225985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
26331da177e4SLinus Torvalds 
26341da177e4SLinus Torvalds /* ACL data packet */
26351da177e4SLinus Torvalds static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
26361da177e4SLinus Torvalds {
26371da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
26381da177e4SLinus Torvalds 	struct hci_conn *conn;
26391da177e4SLinus Torvalds 	__u16 handle, flags;
26401da177e4SLinus Torvalds 
26411da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
26421da177e4SLinus Torvalds 
26431da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
26441da177e4SLinus Torvalds 	flags  = hci_flags(handle);
26451da177e4SLinus Torvalds 	handle = hci_handle(handle);
26461da177e4SLinus Torvalds 
26471da177e4SLinus Torvalds 	BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags);
26481da177e4SLinus Torvalds 
26491da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
26501da177e4SLinus Torvalds 
26511da177e4SLinus Torvalds 	hci_dev_lock(hdev);
26521da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
26531da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
26541da177e4SLinus Torvalds 
26551da177e4SLinus Torvalds 	if (conn) {
265665983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
265704837f64SMarcel Holtmann 
26581da177e4SLinus Torvalds 		/* Send to upper protocol */
2659686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
26601da177e4SLinus Torvalds 		return;
26611da177e4SLinus Torvalds 	} else {
26621da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
26631da177e4SLinus Torvalds 			hdev->name, handle);
26641da177e4SLinus Torvalds 	}
26651da177e4SLinus Torvalds 
26661da177e4SLinus Torvalds 	kfree_skb(skb);
26671da177e4SLinus Torvalds }
26681da177e4SLinus Torvalds 
26691da177e4SLinus Torvalds /* SCO data packet */
26701da177e4SLinus Torvalds static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
26711da177e4SLinus Torvalds {
26721da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
26731da177e4SLinus Torvalds 	struct hci_conn *conn;
26741da177e4SLinus Torvalds 	__u16 handle;
26751da177e4SLinus Torvalds 
26761da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
26771da177e4SLinus Torvalds 
26781da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
26791da177e4SLinus Torvalds 
26801da177e4SLinus Torvalds 	BT_DBG("%s len %d handle 0x%x", hdev->name, skb->len, handle);
26811da177e4SLinus Torvalds 
26821da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
26831da177e4SLinus Torvalds 
26841da177e4SLinus Torvalds 	hci_dev_lock(hdev);
26851da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
26861da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
26871da177e4SLinus Torvalds 
26881da177e4SLinus Torvalds 	if (conn) {
26891da177e4SLinus Torvalds 		/* Send to upper protocol */
2690686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
26911da177e4SLinus Torvalds 		return;
26921da177e4SLinus Torvalds 	} else {
26931da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
26941da177e4SLinus Torvalds 			hdev->name, handle);
26951da177e4SLinus Torvalds 	}
26961da177e4SLinus Torvalds 
26971da177e4SLinus Torvalds 	kfree_skb(skb);
26981da177e4SLinus Torvalds }
26991da177e4SLinus Torvalds 
2700b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
27011da177e4SLinus Torvalds {
2702b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
27031da177e4SLinus Torvalds 	struct sk_buff *skb;
27041da177e4SLinus Torvalds 
27051da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
27061da177e4SLinus Torvalds 
27071da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
27081da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
27091da177e4SLinus Torvalds 			/* Send copy to the sockets */
2710eec8d2bcSJohan Hedberg 			hci_send_to_sock(hdev, skb, NULL);
27111da177e4SLinus Torvalds 		}
27121da177e4SLinus Torvalds 
27131da177e4SLinus Torvalds 		if (test_bit(HCI_RAW, &hdev->flags)) {
27141da177e4SLinus Torvalds 			kfree_skb(skb);
27151da177e4SLinus Torvalds 			continue;
27161da177e4SLinus Torvalds 		}
27171da177e4SLinus Torvalds 
27181da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
27191da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
27200d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
27211da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
27221da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
27231da177e4SLinus Torvalds 				kfree_skb(skb);
27241da177e4SLinus Torvalds 				continue;
27253ff50b79SStephen Hemminger 			}
27261da177e4SLinus Torvalds 		}
27271da177e4SLinus Torvalds 
27281da177e4SLinus Torvalds 		/* Process frame */
27290d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
27301da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
2731b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
27321da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
27331da177e4SLinus Torvalds 			break;
27341da177e4SLinus Torvalds 
27351da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
27361da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
27371da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
27381da177e4SLinus Torvalds 			break;
27391da177e4SLinus Torvalds 
27401da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
27411da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
27421da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
27431da177e4SLinus Torvalds 			break;
27441da177e4SLinus Torvalds 
27451da177e4SLinus Torvalds 		default:
27461da177e4SLinus Torvalds 			kfree_skb(skb);
27471da177e4SLinus Torvalds 			break;
27481da177e4SLinus Torvalds 		}
27491da177e4SLinus Torvalds 	}
27501da177e4SLinus Torvalds }
27511da177e4SLinus Torvalds 
2752c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
27531da177e4SLinus Torvalds {
2754c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
27551da177e4SLinus Torvalds 	struct sk_buff *skb;
27561da177e4SLinus Torvalds 
27571da177e4SLinus Torvalds 	BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
27581da177e4SLinus Torvalds 
27591da177e4SLinus Torvalds 	/* Send queued commands */
27605a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
27615a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
27625a08ecceSAndrei Emeltchenko 		if (!skb)
27635a08ecceSAndrei Emeltchenko 			return;
27645a08ecceSAndrei Emeltchenko 
27651da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
27661da177e4SLinus Torvalds 
276770f23020SAndrei Emeltchenko 		hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC);
276870f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
27691da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
27701da177e4SLinus Torvalds 			hci_send_frame(skb);
27717bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
27727bdb8a5cSSzymon Janc 				del_timer(&hdev->cmd_timer);
27737bdb8a5cSSzymon Janc 			else
27746bd32326SVille Tervo 				mod_timer(&hdev->cmd_timer,
27756bd32326SVille Tervo 				  jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT));
27761da177e4SLinus Torvalds 		} else {
27771da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
2778c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
27791da177e4SLinus Torvalds 		}
27801da177e4SLinus Torvalds 	}
27811da177e4SLinus Torvalds }
27822519a1fcSAndre Guedes 
27832519a1fcSAndre Guedes int hci_do_inquiry(struct hci_dev *hdev, u8 length)
27842519a1fcSAndre Guedes {
27852519a1fcSAndre Guedes 	/* General inquiry access code (GIAC) */
27862519a1fcSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
27872519a1fcSAndre Guedes 	struct hci_cp_inquiry cp;
27882519a1fcSAndre Guedes 
27892519a1fcSAndre Guedes 	BT_DBG("%s", hdev->name);
27902519a1fcSAndre Guedes 
27912519a1fcSAndre Guedes 	if (test_bit(HCI_INQUIRY, &hdev->flags))
27922519a1fcSAndre Guedes 		return -EINPROGRESS;
27932519a1fcSAndre Guedes 
27944663262cSJohan Hedberg 	inquiry_cache_flush(hdev);
27954663262cSJohan Hedberg 
27962519a1fcSAndre Guedes 	memset(&cp, 0, sizeof(cp));
27972519a1fcSAndre Guedes 	memcpy(&cp.lap, lap, sizeof(cp.lap));
27982519a1fcSAndre Guedes 	cp.length  = length;
27992519a1fcSAndre Guedes 
28002519a1fcSAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
28012519a1fcSAndre Guedes }
2802023d5049SAndre Guedes 
2803023d5049SAndre Guedes int hci_cancel_inquiry(struct hci_dev *hdev)
2804023d5049SAndre Guedes {
2805023d5049SAndre Guedes 	BT_DBG("%s", hdev->name);
2806023d5049SAndre Guedes 
2807023d5049SAndre Guedes 	if (!test_bit(HCI_INQUIRY, &hdev->flags))
2808023d5049SAndre Guedes 		return -EPERM;
2809023d5049SAndre Guedes 
2810023d5049SAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL);
2811023d5049SAndre Guedes }
28127784d78fSAndrei Emeltchenko 
28137784d78fSAndrei Emeltchenko module_param(enable_hs, bool, 0644);
28147784d78fSAndrei Emeltchenko MODULE_PARM_DESC(enable_hs, "Enable High Speed");
2815