xref: /openbmc/linux/net/bluetooth/hci_core.c (revision db323f2f)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds    BlueZ - Bluetooth protocol stack for Linux
31da177e4SLinus Torvalds    Copyright (C) 2000-2001 Qualcomm Incorporated
41da177e4SLinus Torvalds 
51da177e4SLinus Torvalds    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
61da177e4SLinus Torvalds 
71da177e4SLinus Torvalds    This program is free software; you can redistribute it and/or modify
81da177e4SLinus Torvalds    it under the terms of the GNU General Public License version 2 as
91da177e4SLinus Torvalds    published by the Free Software Foundation;
101da177e4SLinus Torvalds 
111da177e4SLinus Torvalds    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
121da177e4SLinus Torvalds    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
131da177e4SLinus Torvalds    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
141da177e4SLinus Torvalds    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
151da177e4SLinus Torvalds    CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
161da177e4SLinus Torvalds    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
171da177e4SLinus Torvalds    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
181da177e4SLinus Torvalds    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
191da177e4SLinus Torvalds 
201da177e4SLinus Torvalds    ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
211da177e4SLinus Torvalds    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
221da177e4SLinus Torvalds    SOFTWARE IS DISCLAIMED.
231da177e4SLinus Torvalds */
241da177e4SLinus Torvalds 
251da177e4SLinus Torvalds /* Bluetooth HCI core. */
261da177e4SLinus Torvalds 
2782453021SS.Çağlar Onur #include <linux/jiffies.h>
281da177e4SLinus Torvalds #include <linux/module.h>
291da177e4SLinus Torvalds #include <linux/kmod.h>
301da177e4SLinus Torvalds 
311da177e4SLinus Torvalds #include <linux/types.h>
321da177e4SLinus Torvalds #include <linux/errno.h>
331da177e4SLinus Torvalds #include <linux/kernel.h>
341da177e4SLinus Torvalds #include <linux/sched.h>
351da177e4SLinus Torvalds #include <linux/slab.h>
361da177e4SLinus Torvalds #include <linux/poll.h>
371da177e4SLinus Torvalds #include <linux/fcntl.h>
381da177e4SLinus Torvalds #include <linux/init.h>
391da177e4SLinus Torvalds #include <linux/skbuff.h>
40f48fd9c8SMarcel Holtmann #include <linux/workqueue.h>
411da177e4SLinus Torvalds #include <linux/interrupt.h>
421da177e4SLinus Torvalds #include <linux/notifier.h>
43611b30f7SMarcel Holtmann #include <linux/rfkill.h>
446bd32326SVille Tervo #include <linux/timer.h>
453a0259bbSVinicius Costa Gomes #include <linux/crypto.h>
461da177e4SLinus Torvalds #include <net/sock.h>
471da177e4SLinus Torvalds 
481da177e4SLinus Torvalds #include <asm/system.h>
4970f23020SAndrei Emeltchenko #include <linux/uaccess.h>
501da177e4SLinus Torvalds #include <asm/unaligned.h>
511da177e4SLinus Torvalds 
521da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
531da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
541da177e4SLinus Torvalds 
55ab81cbf9SJohan Hedberg #define AUTO_OFF_TIMEOUT 2000
56ab81cbf9SJohan Hedberg 
577784d78fSAndrei Emeltchenko int enable_hs;
587784d78fSAndrei Emeltchenko 
59b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work);
601da177e4SLinus Torvalds static void hci_cmd_task(unsigned long arg);
611da177e4SLinus Torvalds static void hci_tx_task(unsigned long arg);
621da177e4SLinus Torvalds 
631da177e4SLinus Torvalds static DEFINE_RWLOCK(hci_task_lock);
641da177e4SLinus Torvalds 
651da177e4SLinus Torvalds /* HCI device list */
661da177e4SLinus Torvalds LIST_HEAD(hci_dev_list);
671da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock);
681da177e4SLinus Torvalds 
691da177e4SLinus Torvalds /* HCI callback list */
701da177e4SLinus Torvalds LIST_HEAD(hci_cb_list);
711da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock);
721da177e4SLinus Torvalds 
731da177e4SLinus Torvalds /* HCI protocols */
741da177e4SLinus Torvalds #define HCI_MAX_PROTO	2
751da177e4SLinus Torvalds struct hci_proto *hci_proto[HCI_MAX_PROTO];
761da177e4SLinus Torvalds 
771da177e4SLinus Torvalds /* HCI notifiers list */
78e041c683SAlan Stern static ATOMIC_NOTIFIER_HEAD(hci_notifier);
791da177e4SLinus Torvalds 
801da177e4SLinus Torvalds /* ---- HCI notifications ---- */
811da177e4SLinus Torvalds 
821da177e4SLinus Torvalds int hci_register_notifier(struct notifier_block *nb)
831da177e4SLinus Torvalds {
84e041c683SAlan Stern 	return atomic_notifier_chain_register(&hci_notifier, nb);
851da177e4SLinus Torvalds }
861da177e4SLinus Torvalds 
871da177e4SLinus Torvalds int hci_unregister_notifier(struct notifier_block *nb)
881da177e4SLinus Torvalds {
89e041c683SAlan Stern 	return atomic_notifier_chain_unregister(&hci_notifier, nb);
901da177e4SLinus Torvalds }
911da177e4SLinus Torvalds 
926516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event)
931da177e4SLinus Torvalds {
94e041c683SAlan Stern 	atomic_notifier_call_chain(&hci_notifier, event, hdev);
951da177e4SLinus Torvalds }
961da177e4SLinus Torvalds 
971da177e4SLinus Torvalds /* ---- HCI requests ---- */
981da177e4SLinus Torvalds 
9923bb5763SJohan Hedberg void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result)
1001da177e4SLinus Torvalds {
10123bb5763SJohan Hedberg 	BT_DBG("%s command 0x%04x result 0x%2.2x", hdev->name, cmd, result);
10223bb5763SJohan Hedberg 
103a5040efaSJohan Hedberg 	/* If this is the init phase check if the completed command matches
104a5040efaSJohan Hedberg 	 * the last init command, and if not just return.
105a5040efaSJohan Hedberg 	 */
106a5040efaSJohan Hedberg 	if (test_bit(HCI_INIT, &hdev->flags) && hdev->init_last_cmd != cmd)
10723bb5763SJohan Hedberg 		return;
1081da177e4SLinus Torvalds 
1091da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
1101da177e4SLinus Torvalds 		hdev->req_result = result;
1111da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_DONE;
1121da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
1131da177e4SLinus Torvalds 	}
1141da177e4SLinus Torvalds }
1151da177e4SLinus Torvalds 
1161da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err)
1171da177e4SLinus Torvalds {
1181da177e4SLinus Torvalds 	BT_DBG("%s err 0x%2.2x", hdev->name, err);
1191da177e4SLinus Torvalds 
1201da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
1211da177e4SLinus Torvalds 		hdev->req_result = err;
1221da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_CANCELED;
1231da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
1241da177e4SLinus Torvalds 	}
1251da177e4SLinus Torvalds }
1261da177e4SLinus Torvalds 
1271da177e4SLinus Torvalds /* Execute request and wait for completion. */
1281da177e4SLinus Torvalds static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt),
1291da177e4SLinus Torvalds 					unsigned long opt, __u32 timeout)
1301da177e4SLinus Torvalds {
1311da177e4SLinus Torvalds 	DECLARE_WAITQUEUE(wait, current);
1321da177e4SLinus Torvalds 	int err = 0;
1331da177e4SLinus Torvalds 
1341da177e4SLinus Torvalds 	BT_DBG("%s start", hdev->name);
1351da177e4SLinus Torvalds 
1361da177e4SLinus Torvalds 	hdev->req_status = HCI_REQ_PEND;
1371da177e4SLinus Torvalds 
1381da177e4SLinus Torvalds 	add_wait_queue(&hdev->req_wait_q, &wait);
1391da177e4SLinus Torvalds 	set_current_state(TASK_INTERRUPTIBLE);
1401da177e4SLinus Torvalds 
1411da177e4SLinus Torvalds 	req(hdev, opt);
1421da177e4SLinus Torvalds 	schedule_timeout(timeout);
1431da177e4SLinus Torvalds 
1441da177e4SLinus Torvalds 	remove_wait_queue(&hdev->req_wait_q, &wait);
1451da177e4SLinus Torvalds 
1461da177e4SLinus Torvalds 	if (signal_pending(current))
1471da177e4SLinus Torvalds 		return -EINTR;
1481da177e4SLinus Torvalds 
1491da177e4SLinus Torvalds 	switch (hdev->req_status) {
1501da177e4SLinus Torvalds 	case HCI_REQ_DONE:
151e175072fSJoe Perches 		err = -bt_to_errno(hdev->req_result);
1521da177e4SLinus Torvalds 		break;
1531da177e4SLinus Torvalds 
1541da177e4SLinus Torvalds 	case HCI_REQ_CANCELED:
1551da177e4SLinus Torvalds 		err = -hdev->req_result;
1561da177e4SLinus Torvalds 		break;
1571da177e4SLinus Torvalds 
1581da177e4SLinus Torvalds 	default:
1591da177e4SLinus Torvalds 		err = -ETIMEDOUT;
1601da177e4SLinus Torvalds 		break;
1613ff50b79SStephen Hemminger 	}
1621da177e4SLinus Torvalds 
163a5040efaSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
1641da177e4SLinus Torvalds 
1651da177e4SLinus Torvalds 	BT_DBG("%s end: err %d", hdev->name, err);
1661da177e4SLinus Torvalds 
1671da177e4SLinus Torvalds 	return err;
1681da177e4SLinus Torvalds }
1691da177e4SLinus Torvalds 
1701da177e4SLinus Torvalds static inline int hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt),
1711da177e4SLinus Torvalds 					unsigned long opt, __u32 timeout)
1721da177e4SLinus Torvalds {
1731da177e4SLinus Torvalds 	int ret;
1741da177e4SLinus Torvalds 
1757c6a329eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
1767c6a329eSMarcel Holtmann 		return -ENETDOWN;
1777c6a329eSMarcel Holtmann 
1781da177e4SLinus Torvalds 	/* Serialize all requests */
1791da177e4SLinus Torvalds 	hci_req_lock(hdev);
1801da177e4SLinus Torvalds 	ret = __hci_request(hdev, req, opt, timeout);
1811da177e4SLinus Torvalds 	hci_req_unlock(hdev);
1821da177e4SLinus Torvalds 
1831da177e4SLinus Torvalds 	return ret;
1841da177e4SLinus Torvalds }
1851da177e4SLinus Torvalds 
1861da177e4SLinus Torvalds static void hci_reset_req(struct hci_dev *hdev, unsigned long opt)
1871da177e4SLinus Torvalds {
1881da177e4SLinus Torvalds 	BT_DBG("%s %ld", hdev->name, opt);
1891da177e4SLinus Torvalds 
1901da177e4SLinus Torvalds 	/* Reset device */
191f630cf0dSGustavo F. Padovan 	set_bit(HCI_RESET, &hdev->flags);
192a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
1931da177e4SLinus Torvalds }
1941da177e4SLinus Torvalds 
1951da177e4SLinus Torvalds static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
1961da177e4SLinus Torvalds {
197b0916ea0SJohan Hedberg 	struct hci_cp_delete_stored_link_key cp;
1981da177e4SLinus Torvalds 	struct sk_buff *skb;
1991ebb9252SMarcel Holtmann 	__le16 param;
20089f2783dSMarcel Holtmann 	__u8 flt_type;
2011da177e4SLinus Torvalds 
2021da177e4SLinus Torvalds 	BT_DBG("%s %ld", hdev->name, opt);
2031da177e4SLinus Torvalds 
2041da177e4SLinus Torvalds 	/* Driver initialization */
2051da177e4SLinus Torvalds 
2061da177e4SLinus Torvalds 	/* Special commands */
2071da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->driver_init))) {
2080d48d939SMarcel Holtmann 		bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
2091da177e4SLinus Torvalds 		skb->dev = (void *) hdev;
210c78ae283SMarcel Holtmann 
2111da177e4SLinus Torvalds 		skb_queue_tail(&hdev->cmd_q, skb);
212c78ae283SMarcel Holtmann 		tasklet_schedule(&hdev->cmd_task);
2131da177e4SLinus Torvalds 	}
2141da177e4SLinus Torvalds 	skb_queue_purge(&hdev->driver_init);
2151da177e4SLinus Torvalds 
2161da177e4SLinus Torvalds 	/* Mandatory initialization */
2171da177e4SLinus Torvalds 
2181da177e4SLinus Torvalds 	/* Reset */
219f630cf0dSGustavo F. Padovan 	if (!test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) {
220f630cf0dSGustavo F. Padovan 			set_bit(HCI_RESET, &hdev->flags);
221a9de9248SMarcel Holtmann 			hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
222f630cf0dSGustavo F. Padovan 	}
2231da177e4SLinus Torvalds 
2241da177e4SLinus Torvalds 	/* Read Local Supported Features */
225a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
2261da177e4SLinus Torvalds 
2271143e5a6SMarcel Holtmann 	/* Read Local Version */
228a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
2291143e5a6SMarcel Holtmann 
2301da177e4SLinus Torvalds 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
231a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
2321da177e4SLinus Torvalds 
2331da177e4SLinus Torvalds 	/* Read BD Address */
234a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL);
235a9de9248SMarcel Holtmann 
236a9de9248SMarcel Holtmann 	/* Read Class of Device */
237a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
238a9de9248SMarcel Holtmann 
239a9de9248SMarcel Holtmann 	/* Read Local Name */
240a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL);
2411da177e4SLinus Torvalds 
2421da177e4SLinus Torvalds 	/* Read Voice Setting */
243a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL);
2441da177e4SLinus Torvalds 
2451da177e4SLinus Torvalds 	/* Optional initialization */
2461da177e4SLinus Torvalds 
2471da177e4SLinus Torvalds 	/* Clear Event Filters */
24889f2783dSMarcel Holtmann 	flt_type = HCI_FLT_CLEAR_ALL;
249a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
2501da177e4SLinus Torvalds 
2511da177e4SLinus Torvalds 	/* Connection accept timeout ~20 secs */
252aca3192cSYOSHIFUJI Hideaki 	param = cpu_to_le16(0x7d00);
253a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
254b0916ea0SJohan Hedberg 
255b0916ea0SJohan Hedberg 	bacpy(&cp.bdaddr, BDADDR_ANY);
256b0916ea0SJohan Hedberg 	cp.delete_all = 1;
257b0916ea0SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp);
2581da177e4SLinus Torvalds }
2591da177e4SLinus Torvalds 
2606ed58ec5SVille Tervo static void hci_le_init_req(struct hci_dev *hdev, unsigned long opt)
2616ed58ec5SVille Tervo {
2626ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
2636ed58ec5SVille Tervo 
2646ed58ec5SVille Tervo 	/* Read LE buffer size */
2656ed58ec5SVille Tervo 	hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
2666ed58ec5SVille Tervo }
2676ed58ec5SVille Tervo 
2681da177e4SLinus Torvalds static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
2691da177e4SLinus Torvalds {
2701da177e4SLinus Torvalds 	__u8 scan = opt;
2711da177e4SLinus Torvalds 
2721da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, scan);
2731da177e4SLinus Torvalds 
2741da177e4SLinus Torvalds 	/* Inquiry and Page scans */
275a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
2761da177e4SLinus Torvalds }
2771da177e4SLinus Torvalds 
2781da177e4SLinus Torvalds static void hci_auth_req(struct hci_dev *hdev, unsigned long opt)
2791da177e4SLinus Torvalds {
2801da177e4SLinus Torvalds 	__u8 auth = opt;
2811da177e4SLinus Torvalds 
2821da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, auth);
2831da177e4SLinus Torvalds 
2841da177e4SLinus Torvalds 	/* Authentication */
285a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
2861da177e4SLinus Torvalds }
2871da177e4SLinus Torvalds 
2881da177e4SLinus Torvalds static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt)
2891da177e4SLinus Torvalds {
2901da177e4SLinus Torvalds 	__u8 encrypt = opt;
2911da177e4SLinus Torvalds 
2921da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, encrypt);
2931da177e4SLinus Torvalds 
294e4e8e37cSMarcel Holtmann 	/* Encryption */
295a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
2961da177e4SLinus Torvalds }
2971da177e4SLinus Torvalds 
298e4e8e37cSMarcel Holtmann static void hci_linkpol_req(struct hci_dev *hdev, unsigned long opt)
299e4e8e37cSMarcel Holtmann {
300e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
301e4e8e37cSMarcel Holtmann 
302a418b893SMarcel Holtmann 	BT_DBG("%s %x", hdev->name, policy);
303e4e8e37cSMarcel Holtmann 
304e4e8e37cSMarcel Holtmann 	/* Default link policy */
305e4e8e37cSMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
306e4e8e37cSMarcel Holtmann }
307e4e8e37cSMarcel Holtmann 
3081da177e4SLinus Torvalds /* Get HCI device by index.
3091da177e4SLinus Torvalds  * Device is held on return. */
3101da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
3111da177e4SLinus Torvalds {
3128035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
3131da177e4SLinus Torvalds 
3141da177e4SLinus Torvalds 	BT_DBG("%d", index);
3151da177e4SLinus Torvalds 
3161da177e4SLinus Torvalds 	if (index < 0)
3171da177e4SLinus Torvalds 		return NULL;
3181da177e4SLinus Torvalds 
3191da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
3208035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
3211da177e4SLinus Torvalds 		if (d->id == index) {
3221da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
3231da177e4SLinus Torvalds 			break;
3241da177e4SLinus Torvalds 		}
3251da177e4SLinus Torvalds 	}
3261da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
3271da177e4SLinus Torvalds 	return hdev;
3281da177e4SLinus Torvalds }
3291da177e4SLinus Torvalds 
3301da177e4SLinus Torvalds /* ---- Inquiry support ---- */
3311da177e4SLinus Torvalds static void inquiry_cache_flush(struct hci_dev *hdev)
3321da177e4SLinus Torvalds {
3331da177e4SLinus Torvalds 	struct inquiry_cache *cache = &hdev->inq_cache;
3341da177e4SLinus Torvalds 	struct inquiry_entry *next  = cache->list, *e;
3351da177e4SLinus Torvalds 
3361da177e4SLinus Torvalds 	BT_DBG("cache %p", cache);
3371da177e4SLinus Torvalds 
3381da177e4SLinus Torvalds 	cache->list = NULL;
3391da177e4SLinus Torvalds 	while ((e = next)) {
3401da177e4SLinus Torvalds 		next = e->next;
3411da177e4SLinus Torvalds 		kfree(e);
3421da177e4SLinus Torvalds 	}
3431da177e4SLinus Torvalds }
3441da177e4SLinus Torvalds 
3451da177e4SLinus Torvalds struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
3461da177e4SLinus Torvalds {
3471da177e4SLinus Torvalds 	struct inquiry_cache *cache = &hdev->inq_cache;
3481da177e4SLinus Torvalds 	struct inquiry_entry *e;
3491da177e4SLinus Torvalds 
3501da177e4SLinus Torvalds 	BT_DBG("cache %p, %s", cache, batostr(bdaddr));
3511da177e4SLinus Torvalds 
3521da177e4SLinus Torvalds 	for (e = cache->list; e; e = e->next)
3531da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
3541da177e4SLinus Torvalds 			break;
3551da177e4SLinus Torvalds 	return e;
3561da177e4SLinus Torvalds }
3571da177e4SLinus Torvalds 
3581da177e4SLinus Torvalds void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data)
3591da177e4SLinus Torvalds {
3601da177e4SLinus Torvalds 	struct inquiry_cache *cache = &hdev->inq_cache;
36170f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
3621da177e4SLinus Torvalds 
3631da177e4SLinus Torvalds 	BT_DBG("cache %p, %s", cache, batostr(&data->bdaddr));
3641da177e4SLinus Torvalds 
36570f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
36670f23020SAndrei Emeltchenko 	if (!ie) {
3671da177e4SLinus Torvalds 		/* Entry not in the cache. Add new one. */
36870f23020SAndrei Emeltchenko 		ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
36970f23020SAndrei Emeltchenko 		if (!ie)
3701da177e4SLinus Torvalds 			return;
37170f23020SAndrei Emeltchenko 
37270f23020SAndrei Emeltchenko 		ie->next = cache->list;
37370f23020SAndrei Emeltchenko 		cache->list = ie;
3741da177e4SLinus Torvalds 	}
3751da177e4SLinus Torvalds 
37670f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
37770f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
3781da177e4SLinus Torvalds 	cache->timestamp = jiffies;
3791da177e4SLinus Torvalds }
3801da177e4SLinus Torvalds 
3811da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
3821da177e4SLinus Torvalds {
3831da177e4SLinus Torvalds 	struct inquiry_cache *cache = &hdev->inq_cache;
3841da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
3851da177e4SLinus Torvalds 	struct inquiry_entry *e;
3861da177e4SLinus Torvalds 	int copied = 0;
3871da177e4SLinus Torvalds 
3881da177e4SLinus Torvalds 	for (e = cache->list; e && copied < num; e = e->next, copied++) {
3891da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
3901da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
3911da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
3921da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
3931da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
3941da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
3951da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
3961da177e4SLinus Torvalds 		info++;
3971da177e4SLinus Torvalds 	}
3981da177e4SLinus Torvalds 
3991da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
4001da177e4SLinus Torvalds 	return copied;
4011da177e4SLinus Torvalds }
4021da177e4SLinus Torvalds 
4031da177e4SLinus Torvalds static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
4041da177e4SLinus Torvalds {
4051da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
4061da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
4071da177e4SLinus Torvalds 
4081da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
4091da177e4SLinus Torvalds 
4101da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
4111da177e4SLinus Torvalds 		return;
4121da177e4SLinus Torvalds 
4131da177e4SLinus Torvalds 	/* Start Inquiry */
4141da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
4151da177e4SLinus Torvalds 	cp.length  = ir->length;
4161da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
417a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
4181da177e4SLinus Torvalds }
4191da177e4SLinus Torvalds 
4201da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
4211da177e4SLinus Torvalds {
4221da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
4231da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
4241da177e4SLinus Torvalds 	struct hci_dev *hdev;
4251da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
4261da177e4SLinus Torvalds 	long timeo;
4271da177e4SLinus Torvalds 	__u8 *buf;
4281da177e4SLinus Torvalds 
4291da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
4301da177e4SLinus Torvalds 		return -EFAULT;
4311da177e4SLinus Torvalds 
4325a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
4335a08ecceSAndrei Emeltchenko 	if (!hdev)
4341da177e4SLinus Torvalds 		return -ENODEV;
4351da177e4SLinus Torvalds 
43609fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
4371da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
4381da177e4SLinus Torvalds 				inquiry_cache_empty(hdev) ||
4391da177e4SLinus Torvalds 				ir.flags & IREQ_CACHE_FLUSH) {
4401da177e4SLinus Torvalds 		inquiry_cache_flush(hdev);
4411da177e4SLinus Torvalds 		do_inquiry = 1;
4421da177e4SLinus Torvalds 	}
44309fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
4441da177e4SLinus Torvalds 
44504837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
44670f23020SAndrei Emeltchenko 
44770f23020SAndrei Emeltchenko 	if (do_inquiry) {
44870f23020SAndrei Emeltchenko 		err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo);
44970f23020SAndrei Emeltchenko 		if (err < 0)
4501da177e4SLinus Torvalds 			goto done;
45170f23020SAndrei Emeltchenko 	}
4521da177e4SLinus Torvalds 
4531da177e4SLinus Torvalds 	/* for unlimited number of responses we will use buffer with 255 entries */
4541da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
4551da177e4SLinus Torvalds 
4561da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
4571da177e4SLinus Torvalds 	 * copy it to the user space.
4581da177e4SLinus Torvalds 	 */
45970f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
46070f23020SAndrei Emeltchenko 	if (!buf) {
4611da177e4SLinus Torvalds 		err = -ENOMEM;
4621da177e4SLinus Torvalds 		goto done;
4631da177e4SLinus Torvalds 	}
4641da177e4SLinus Torvalds 
46509fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
4661da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
46709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
4681da177e4SLinus Torvalds 
4691da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
4701da177e4SLinus Torvalds 
4711da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
4721da177e4SLinus Torvalds 		ptr += sizeof(ir);
4731da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
4741da177e4SLinus Torvalds 					ir.num_rsp))
4751da177e4SLinus Torvalds 			err = -EFAULT;
4761da177e4SLinus Torvalds 	} else
4771da177e4SLinus Torvalds 		err = -EFAULT;
4781da177e4SLinus Torvalds 
4791da177e4SLinus Torvalds 	kfree(buf);
4801da177e4SLinus Torvalds 
4811da177e4SLinus Torvalds done:
4821da177e4SLinus Torvalds 	hci_dev_put(hdev);
4831da177e4SLinus Torvalds 	return err;
4841da177e4SLinus Torvalds }
4851da177e4SLinus Torvalds 
4861da177e4SLinus Torvalds /* ---- HCI ioctl helpers ---- */
4871da177e4SLinus Torvalds 
4881da177e4SLinus Torvalds int hci_dev_open(__u16 dev)
4891da177e4SLinus Torvalds {
4901da177e4SLinus Torvalds 	struct hci_dev *hdev;
4911da177e4SLinus Torvalds 	int ret = 0;
4921da177e4SLinus Torvalds 
4935a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(dev);
4945a08ecceSAndrei Emeltchenko 	if (!hdev)
4951da177e4SLinus Torvalds 		return -ENODEV;
4961da177e4SLinus Torvalds 
4971da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
4981da177e4SLinus Torvalds 
4991da177e4SLinus Torvalds 	hci_req_lock(hdev);
5001da177e4SLinus Torvalds 
501611b30f7SMarcel Holtmann 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) {
502611b30f7SMarcel Holtmann 		ret = -ERFKILL;
503611b30f7SMarcel Holtmann 		goto done;
504611b30f7SMarcel Holtmann 	}
505611b30f7SMarcel Holtmann 
5061da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
5071da177e4SLinus Torvalds 		ret = -EALREADY;
5081da177e4SLinus Torvalds 		goto done;
5091da177e4SLinus Torvalds 	}
5101da177e4SLinus Torvalds 
5111da177e4SLinus Torvalds 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
5121da177e4SLinus Torvalds 		set_bit(HCI_RAW, &hdev->flags);
5131da177e4SLinus Torvalds 
51407e3b94aSAndrei Emeltchenko 	/* Treat all non BR/EDR controllers as raw devices if
51507e3b94aSAndrei Emeltchenko 	   enable_hs is not set */
51607e3b94aSAndrei Emeltchenko 	if (hdev->dev_type != HCI_BREDR && !enable_hs)
517943da25dSMarcel Holtmann 		set_bit(HCI_RAW, &hdev->flags);
518943da25dSMarcel Holtmann 
5191da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
5201da177e4SLinus Torvalds 		ret = -EIO;
5211da177e4SLinus Torvalds 		goto done;
5221da177e4SLinus Torvalds 	}
5231da177e4SLinus Torvalds 
5241da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
5251da177e4SLinus Torvalds 		atomic_set(&hdev->cmd_cnt, 1);
5261da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
527a5040efaSJohan Hedberg 		hdev->init_last_cmd = 0;
5281da177e4SLinus Torvalds 
52904837f64SMarcel Holtmann 		ret = __hci_request(hdev, hci_init_req, 0,
53004837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
5311da177e4SLinus Torvalds 
532eead27daSAndre Guedes 		if (lmp_host_le_capable(hdev))
5336ed58ec5SVille Tervo 			ret = __hci_request(hdev, hci_le_init_req, 0,
5346ed58ec5SVille Tervo 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
5356ed58ec5SVille Tervo 
5361da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
5371da177e4SLinus Torvalds 	}
5381da177e4SLinus Torvalds 
5391da177e4SLinus Torvalds 	if (!ret) {
5401da177e4SLinus Torvalds 		hci_dev_hold(hdev);
5411da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
5421da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
54356e5cb86SJohan Hedberg 		if (!test_bit(HCI_SETUP, &hdev->flags)) {
54409fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
545744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
54609fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
54756e5cb86SJohan Hedberg 		}
5481da177e4SLinus Torvalds 	} else {
5491da177e4SLinus Torvalds 		/* Init failed, cleanup */
5501da177e4SLinus Torvalds 		tasklet_kill(&hdev->tx_task);
5511da177e4SLinus Torvalds 		tasklet_kill(&hdev->cmd_task);
552b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
5531da177e4SLinus Torvalds 
5541da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
5551da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
5561da177e4SLinus Torvalds 
5571da177e4SLinus Torvalds 		if (hdev->flush)
5581da177e4SLinus Torvalds 			hdev->flush(hdev);
5591da177e4SLinus Torvalds 
5601da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
5611da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
5621da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
5631da177e4SLinus Torvalds 		}
5641da177e4SLinus Torvalds 
5651da177e4SLinus Torvalds 		hdev->close(hdev);
5661da177e4SLinus Torvalds 		hdev->flags = 0;
5671da177e4SLinus Torvalds 	}
5681da177e4SLinus Torvalds 
5691da177e4SLinus Torvalds done:
5701da177e4SLinus Torvalds 	hci_req_unlock(hdev);
5711da177e4SLinus Torvalds 	hci_dev_put(hdev);
5721da177e4SLinus Torvalds 	return ret;
5731da177e4SLinus Torvalds }
5741da177e4SLinus Torvalds 
5751da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
5761da177e4SLinus Torvalds {
5771da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
5781da177e4SLinus Torvalds 
5791da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
5801da177e4SLinus Torvalds 	hci_req_lock(hdev);
5811da177e4SLinus Torvalds 
5821da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
583b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
5841da177e4SLinus Torvalds 		hci_req_unlock(hdev);
5851da177e4SLinus Torvalds 		return 0;
5861da177e4SLinus Torvalds 	}
5871da177e4SLinus Torvalds 
5881da177e4SLinus Torvalds 	/* Kill RX and TX tasks */
5891da177e4SLinus Torvalds 	tasklet_kill(&hdev->tx_task);
590b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
5911da177e4SLinus Torvalds 
59216ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
593e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
59416ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
59516ab91abSJohan Hedberg 	}
59616ab91abSJohan Hedberg 
5973243553fSJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags))
598e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
5993243553fSJohan Hedberg 
60009fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
6011da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
6021da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
60309fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
6041da177e4SLinus Torvalds 
6051da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
6061da177e4SLinus Torvalds 
6071da177e4SLinus Torvalds 	if (hdev->flush)
6081da177e4SLinus Torvalds 		hdev->flush(hdev);
6091da177e4SLinus Torvalds 
6101da177e4SLinus Torvalds 	/* Reset device */
6111da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
6121da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
6131da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
6141da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
61504837f64SMarcel Holtmann 		__hci_request(hdev, hci_reset_req, 0,
61643611a7bSSzymon Janc 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
6171da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
6181da177e4SLinus Torvalds 	}
6191da177e4SLinus Torvalds 
6201da177e4SLinus Torvalds 	/* Kill cmd task */
6211da177e4SLinus Torvalds 	tasklet_kill(&hdev->cmd_task);
6221da177e4SLinus Torvalds 
6231da177e4SLinus Torvalds 	/* Drop queues */
6241da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
6251da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
6261da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
6271da177e4SLinus Torvalds 
6281da177e4SLinus Torvalds 	/* Drop last sent command */
6291da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
630b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
6311da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
6321da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
6331da177e4SLinus Torvalds 	}
6341da177e4SLinus Torvalds 
6351da177e4SLinus Torvalds 	/* After this point our queues are empty
6361da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
6371da177e4SLinus Torvalds 	hdev->close(hdev);
6381da177e4SLinus Torvalds 
63909fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
640744cf19eSJohan Hedberg 	mgmt_powered(hdev, 0);
64109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
6425add6af8SJohan Hedberg 
6431da177e4SLinus Torvalds 	/* Clear flags */
6441da177e4SLinus Torvalds 	hdev->flags = 0;
6451da177e4SLinus Torvalds 
6461da177e4SLinus Torvalds 	hci_req_unlock(hdev);
6471da177e4SLinus Torvalds 
6481da177e4SLinus Torvalds 	hci_dev_put(hdev);
6491da177e4SLinus Torvalds 	return 0;
6501da177e4SLinus Torvalds }
6511da177e4SLinus Torvalds 
6521da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
6531da177e4SLinus Torvalds {
6541da177e4SLinus Torvalds 	struct hci_dev *hdev;
6551da177e4SLinus Torvalds 	int err;
6561da177e4SLinus Torvalds 
65770f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
65870f23020SAndrei Emeltchenko 	if (!hdev)
6591da177e4SLinus Torvalds 		return -ENODEV;
6601da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
6611da177e4SLinus Torvalds 	hci_dev_put(hdev);
6621da177e4SLinus Torvalds 	return err;
6631da177e4SLinus Torvalds }
6641da177e4SLinus Torvalds 
6651da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
6661da177e4SLinus Torvalds {
6671da177e4SLinus Torvalds 	struct hci_dev *hdev;
6681da177e4SLinus Torvalds 	int ret = 0;
6691da177e4SLinus Torvalds 
67070f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
67170f23020SAndrei Emeltchenko 	if (!hdev)
6721da177e4SLinus Torvalds 		return -ENODEV;
6731da177e4SLinus Torvalds 
6741da177e4SLinus Torvalds 	hci_req_lock(hdev);
6751da177e4SLinus Torvalds 	tasklet_disable(&hdev->tx_task);
6761da177e4SLinus Torvalds 
6771da177e4SLinus Torvalds 	if (!test_bit(HCI_UP, &hdev->flags))
6781da177e4SLinus Torvalds 		goto done;
6791da177e4SLinus Torvalds 
6801da177e4SLinus Torvalds 	/* Drop queues */
6811da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
6821da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
6831da177e4SLinus Torvalds 
68409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
6851da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
6861da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
68709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
6881da177e4SLinus Torvalds 
6891da177e4SLinus Torvalds 	if (hdev->flush)
6901da177e4SLinus Torvalds 		hdev->flush(hdev);
6911da177e4SLinus Torvalds 
6921da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
6936ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
6941da177e4SLinus Torvalds 
6951da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags))
69604837f64SMarcel Holtmann 		ret = __hci_request(hdev, hci_reset_req, 0,
69704837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
6981da177e4SLinus Torvalds 
6991da177e4SLinus Torvalds done:
7001da177e4SLinus Torvalds 	tasklet_enable(&hdev->tx_task);
7011da177e4SLinus Torvalds 	hci_req_unlock(hdev);
7021da177e4SLinus Torvalds 	hci_dev_put(hdev);
7031da177e4SLinus Torvalds 	return ret;
7041da177e4SLinus Torvalds }
7051da177e4SLinus Torvalds 
7061da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
7071da177e4SLinus Torvalds {
7081da177e4SLinus Torvalds 	struct hci_dev *hdev;
7091da177e4SLinus Torvalds 	int ret = 0;
7101da177e4SLinus Torvalds 
71170f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
71270f23020SAndrei Emeltchenko 	if (!hdev)
7131da177e4SLinus Torvalds 		return -ENODEV;
7141da177e4SLinus Torvalds 
7151da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
7161da177e4SLinus Torvalds 
7171da177e4SLinus Torvalds 	hci_dev_put(hdev);
7181da177e4SLinus Torvalds 
7191da177e4SLinus Torvalds 	return ret;
7201da177e4SLinus Torvalds }
7211da177e4SLinus Torvalds 
7221da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
7231da177e4SLinus Torvalds {
7241da177e4SLinus Torvalds 	struct hci_dev *hdev;
7251da177e4SLinus Torvalds 	struct hci_dev_req dr;
7261da177e4SLinus Torvalds 	int err = 0;
7271da177e4SLinus Torvalds 
7281da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
7291da177e4SLinus Torvalds 		return -EFAULT;
7301da177e4SLinus Torvalds 
73170f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
73270f23020SAndrei Emeltchenko 	if (!hdev)
7331da177e4SLinus Torvalds 		return -ENODEV;
7341da177e4SLinus Torvalds 
7351da177e4SLinus Torvalds 	switch (cmd) {
7361da177e4SLinus Torvalds 	case HCISETAUTH:
73704837f64SMarcel Holtmann 		err = hci_request(hdev, hci_auth_req, dr.dev_opt,
73804837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
7391da177e4SLinus Torvalds 		break;
7401da177e4SLinus Torvalds 
7411da177e4SLinus Torvalds 	case HCISETENCRYPT:
7421da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
7431da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
7441da177e4SLinus Torvalds 			break;
7451da177e4SLinus Torvalds 		}
7461da177e4SLinus Torvalds 
7471da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
7481da177e4SLinus Torvalds 			/* Auth must be enabled first */
74904837f64SMarcel Holtmann 			err = hci_request(hdev, hci_auth_req, dr.dev_opt,
75004837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
7511da177e4SLinus Torvalds 			if (err)
7521da177e4SLinus Torvalds 				break;
7531da177e4SLinus Torvalds 		}
7541da177e4SLinus Torvalds 
75504837f64SMarcel Holtmann 		err = hci_request(hdev, hci_encrypt_req, dr.dev_opt,
75604837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
7571da177e4SLinus Torvalds 		break;
7581da177e4SLinus Torvalds 
7591da177e4SLinus Torvalds 	case HCISETSCAN:
76004837f64SMarcel Holtmann 		err = hci_request(hdev, hci_scan_req, dr.dev_opt,
76104837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
7621da177e4SLinus Torvalds 		break;
7631da177e4SLinus Torvalds 
7641da177e4SLinus Torvalds 	case HCISETLINKPOL:
765e4e8e37cSMarcel Holtmann 		err = hci_request(hdev, hci_linkpol_req, dr.dev_opt,
766e4e8e37cSMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
7671da177e4SLinus Torvalds 		break;
7681da177e4SLinus Torvalds 
7691da177e4SLinus Torvalds 	case HCISETLINKMODE:
770e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
771e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
772e4e8e37cSMarcel Holtmann 		break;
773e4e8e37cSMarcel Holtmann 
774e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
775e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
7761da177e4SLinus Torvalds 		break;
7771da177e4SLinus Torvalds 
7781da177e4SLinus Torvalds 	case HCISETACLMTU:
7791da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
7801da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
7811da177e4SLinus Torvalds 		break;
7821da177e4SLinus Torvalds 
7831da177e4SLinus Torvalds 	case HCISETSCOMTU:
7841da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
7851da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
7861da177e4SLinus Torvalds 		break;
7871da177e4SLinus Torvalds 
7881da177e4SLinus Torvalds 	default:
7891da177e4SLinus Torvalds 		err = -EINVAL;
7901da177e4SLinus Torvalds 		break;
7911da177e4SLinus Torvalds 	}
792e4e8e37cSMarcel Holtmann 
7931da177e4SLinus Torvalds 	hci_dev_put(hdev);
7941da177e4SLinus Torvalds 	return err;
7951da177e4SLinus Torvalds }
7961da177e4SLinus Torvalds 
7971da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
7981da177e4SLinus Torvalds {
7998035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
8001da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
8011da177e4SLinus Torvalds 	struct hci_dev_req *dr;
8021da177e4SLinus Torvalds 	int n = 0, size, err;
8031da177e4SLinus Torvalds 	__u16 dev_num;
8041da177e4SLinus Torvalds 
8051da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
8061da177e4SLinus Torvalds 		return -EFAULT;
8071da177e4SLinus Torvalds 
8081da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
8091da177e4SLinus Torvalds 		return -EINVAL;
8101da177e4SLinus Torvalds 
8111da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
8121da177e4SLinus Torvalds 
81370f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
81470f23020SAndrei Emeltchenko 	if (!dl)
8151da177e4SLinus Torvalds 		return -ENOMEM;
8161da177e4SLinus Torvalds 
8171da177e4SLinus Torvalds 	dr = dl->dev_req;
8181da177e4SLinus Torvalds 
8191da177e4SLinus Torvalds 	read_lock_bh(&hci_dev_list_lock);
8208035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
8213243553fSJohan Hedberg 		if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags))
822e0f9309fSJohan Hedberg 			cancel_delayed_work(&hdev->power_off);
823c542a06cSJohan Hedberg 
824c542a06cSJohan Hedberg 		if (!test_bit(HCI_MGMT, &hdev->flags))
825c542a06cSJohan Hedberg 			set_bit(HCI_PAIRABLE, &hdev->flags);
826c542a06cSJohan Hedberg 
8271da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
8281da177e4SLinus Torvalds 		(dr + n)->dev_opt = hdev->flags;
829c542a06cSJohan Hedberg 
8301da177e4SLinus Torvalds 		if (++n >= dev_num)
8311da177e4SLinus Torvalds 			break;
8321da177e4SLinus Torvalds 	}
8331da177e4SLinus Torvalds 	read_unlock_bh(&hci_dev_list_lock);
8341da177e4SLinus Torvalds 
8351da177e4SLinus Torvalds 	dl->dev_num = n;
8361da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
8371da177e4SLinus Torvalds 
8381da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
8391da177e4SLinus Torvalds 	kfree(dl);
8401da177e4SLinus Torvalds 
8411da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
8421da177e4SLinus Torvalds }
8431da177e4SLinus Torvalds 
8441da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
8451da177e4SLinus Torvalds {
8461da177e4SLinus Torvalds 	struct hci_dev *hdev;
8471da177e4SLinus Torvalds 	struct hci_dev_info di;
8481da177e4SLinus Torvalds 	int err = 0;
8491da177e4SLinus Torvalds 
8501da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
8511da177e4SLinus Torvalds 		return -EFAULT;
8521da177e4SLinus Torvalds 
85370f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
85470f23020SAndrei Emeltchenko 	if (!hdev)
8551da177e4SLinus Torvalds 		return -ENODEV;
8561da177e4SLinus Torvalds 
8573243553fSJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags))
8583243553fSJohan Hedberg 		cancel_delayed_work_sync(&hdev->power_off);
859ab81cbf9SJohan Hedberg 
860c542a06cSJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->flags))
861c542a06cSJohan Hedberg 		set_bit(HCI_PAIRABLE, &hdev->flags);
862c542a06cSJohan Hedberg 
8631da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
8641da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
865943da25dSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | (hdev->dev_type << 4);
8661da177e4SLinus Torvalds 	di.flags    = hdev->flags;
8671da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
8681da177e4SLinus Torvalds 	di.acl_mtu  = hdev->acl_mtu;
8691da177e4SLinus Torvalds 	di.acl_pkts = hdev->acl_pkts;
8701da177e4SLinus Torvalds 	di.sco_mtu  = hdev->sco_mtu;
8711da177e4SLinus Torvalds 	di.sco_pkts = hdev->sco_pkts;
8721da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
8731da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
8741da177e4SLinus Torvalds 
8751da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
8761da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
8771da177e4SLinus Torvalds 
8781da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
8791da177e4SLinus Torvalds 		err = -EFAULT;
8801da177e4SLinus Torvalds 
8811da177e4SLinus Torvalds 	hci_dev_put(hdev);
8821da177e4SLinus Torvalds 
8831da177e4SLinus Torvalds 	return err;
8841da177e4SLinus Torvalds }
8851da177e4SLinus Torvalds 
8861da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
8871da177e4SLinus Torvalds 
888611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
889611b30f7SMarcel Holtmann {
890611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
891611b30f7SMarcel Holtmann 
892611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
893611b30f7SMarcel Holtmann 
894611b30f7SMarcel Holtmann 	if (!blocked)
895611b30f7SMarcel Holtmann 		return 0;
896611b30f7SMarcel Holtmann 
897611b30f7SMarcel Holtmann 	hci_dev_do_close(hdev);
898611b30f7SMarcel Holtmann 
899611b30f7SMarcel Holtmann 	return 0;
900611b30f7SMarcel Holtmann }
901611b30f7SMarcel Holtmann 
902611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
903611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
904611b30f7SMarcel Holtmann };
905611b30f7SMarcel Holtmann 
9061da177e4SLinus Torvalds /* Alloc HCI device */
9071da177e4SLinus Torvalds struct hci_dev *hci_alloc_dev(void)
9081da177e4SLinus Torvalds {
9091da177e4SLinus Torvalds 	struct hci_dev *hdev;
9101da177e4SLinus Torvalds 
91125ea6db0SMarcel Holtmann 	hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
9121da177e4SLinus Torvalds 	if (!hdev)
9131da177e4SLinus Torvalds 		return NULL;
9141da177e4SLinus Torvalds 
9150ac7e700SDavid Herrmann 	hci_init_sysfs(hdev);
9161da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->driver_init);
9171da177e4SLinus Torvalds 
9181da177e4SLinus Torvalds 	return hdev;
9191da177e4SLinus Torvalds }
9201da177e4SLinus Torvalds EXPORT_SYMBOL(hci_alloc_dev);
9211da177e4SLinus Torvalds 
9221da177e4SLinus Torvalds /* Free HCI device */
9231da177e4SLinus Torvalds void hci_free_dev(struct hci_dev *hdev)
9241da177e4SLinus Torvalds {
9251da177e4SLinus Torvalds 	skb_queue_purge(&hdev->driver_init);
9261da177e4SLinus Torvalds 
927a91f2e39SMarcel Holtmann 	/* will free via device release */
928a91f2e39SMarcel Holtmann 	put_device(&hdev->dev);
9291da177e4SLinus Torvalds }
9301da177e4SLinus Torvalds EXPORT_SYMBOL(hci_free_dev);
9311da177e4SLinus Torvalds 
932ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
933ab81cbf9SJohan Hedberg {
934ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
935ab81cbf9SJohan Hedberg 
936ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
937ab81cbf9SJohan Hedberg 
938ab81cbf9SJohan Hedberg 	if (hci_dev_open(hdev->id) < 0)
939ab81cbf9SJohan Hedberg 		return;
940ab81cbf9SJohan Hedberg 
941ab81cbf9SJohan Hedberg 	if (test_bit(HCI_AUTO_OFF, &hdev->flags))
9423243553fSJohan Hedberg 		queue_delayed_work(hdev->workqueue, &hdev->power_off,
9433243553fSJohan Hedberg 					msecs_to_jiffies(AUTO_OFF_TIMEOUT));
944ab81cbf9SJohan Hedberg 
945ab81cbf9SJohan Hedberg 	if (test_and_clear_bit(HCI_SETUP, &hdev->flags))
946744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
947ab81cbf9SJohan Hedberg }
948ab81cbf9SJohan Hedberg 
949ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
950ab81cbf9SJohan Hedberg {
9513243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
9523243553fSJohan Hedberg 							power_off.work);
953ab81cbf9SJohan Hedberg 
954ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
955ab81cbf9SJohan Hedberg 
9563243553fSJohan Hedberg 	clear_bit(HCI_AUTO_OFF, &hdev->flags);
9573243553fSJohan Hedberg 
958ab81cbf9SJohan Hedberg 	hci_dev_close(hdev->id);
959ab81cbf9SJohan Hedberg }
960ab81cbf9SJohan Hedberg 
96116ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
96216ab91abSJohan Hedberg {
96316ab91abSJohan Hedberg 	struct hci_dev *hdev;
96416ab91abSJohan Hedberg 	u8 scan = SCAN_PAGE;
96516ab91abSJohan Hedberg 
96616ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
96716ab91abSJohan Hedberg 
96816ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
96916ab91abSJohan Hedberg 
97009fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
97116ab91abSJohan Hedberg 
97216ab91abSJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan);
97316ab91abSJohan Hedberg 
97416ab91abSJohan Hedberg 	hdev->discov_timeout = 0;
97516ab91abSJohan Hedberg 
97609fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
97716ab91abSJohan Hedberg }
97816ab91abSJohan Hedberg 
9792aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev)
9802aeb9a1aSJohan Hedberg {
9812aeb9a1aSJohan Hedberg 	struct list_head *p, *n;
9822aeb9a1aSJohan Hedberg 
9832aeb9a1aSJohan Hedberg 	list_for_each_safe(p, n, &hdev->uuids) {
9842aeb9a1aSJohan Hedberg 		struct bt_uuid *uuid;
9852aeb9a1aSJohan Hedberg 
9862aeb9a1aSJohan Hedberg 		uuid = list_entry(p, struct bt_uuid, list);
9872aeb9a1aSJohan Hedberg 
9882aeb9a1aSJohan Hedberg 		list_del(p);
9892aeb9a1aSJohan Hedberg 		kfree(uuid);
9902aeb9a1aSJohan Hedberg 	}
9912aeb9a1aSJohan Hedberg 
9922aeb9a1aSJohan Hedberg 	return 0;
9932aeb9a1aSJohan Hedberg }
9942aeb9a1aSJohan Hedberg 
99555ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev)
99655ed8ca1SJohan Hedberg {
99755ed8ca1SJohan Hedberg 	struct list_head *p, *n;
99855ed8ca1SJohan Hedberg 
99955ed8ca1SJohan Hedberg 	list_for_each_safe(p, n, &hdev->link_keys) {
100055ed8ca1SJohan Hedberg 		struct link_key *key;
100155ed8ca1SJohan Hedberg 
100255ed8ca1SJohan Hedberg 		key = list_entry(p, struct link_key, list);
100355ed8ca1SJohan Hedberg 
100455ed8ca1SJohan Hedberg 		list_del(p);
100555ed8ca1SJohan Hedberg 		kfree(key);
100655ed8ca1SJohan Hedberg 	}
100755ed8ca1SJohan Hedberg 
100855ed8ca1SJohan Hedberg 	return 0;
100955ed8ca1SJohan Hedberg }
101055ed8ca1SJohan Hedberg 
101155ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
101255ed8ca1SJohan Hedberg {
101355ed8ca1SJohan Hedberg 	struct link_key *k;
101455ed8ca1SJohan Hedberg 
10158035ded4SLuiz Augusto von Dentz 	list_for_each_entry(k, &hdev->link_keys, list)
101655ed8ca1SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0)
101755ed8ca1SJohan Hedberg 			return k;
101855ed8ca1SJohan Hedberg 
101955ed8ca1SJohan Hedberg 	return NULL;
102055ed8ca1SJohan Hedberg }
102155ed8ca1SJohan Hedberg 
1022d25e28abSJohan Hedberg static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1023d25e28abSJohan Hedberg 						u8 key_type, u8 old_key_type)
1024d25e28abSJohan Hedberg {
1025d25e28abSJohan Hedberg 	/* Legacy key */
1026d25e28abSJohan Hedberg 	if (key_type < 0x03)
1027d25e28abSJohan Hedberg 		return 1;
1028d25e28abSJohan Hedberg 
1029d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
1030d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
1031d25e28abSJohan Hedberg 		return 0;
1032d25e28abSJohan Hedberg 
1033d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
1034d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
1035d25e28abSJohan Hedberg 		return 0;
1036d25e28abSJohan Hedberg 
1037d25e28abSJohan Hedberg 	/* Security mode 3 case */
1038d25e28abSJohan Hedberg 	if (!conn)
1039d25e28abSJohan Hedberg 		return 1;
1040d25e28abSJohan Hedberg 
1041d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
1042d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
1043d25e28abSJohan Hedberg 		return 1;
1044d25e28abSJohan Hedberg 
1045d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
1046d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
1047d25e28abSJohan Hedberg 		return 1;
1048d25e28abSJohan Hedberg 
1049d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
1050d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
1051d25e28abSJohan Hedberg 		return 1;
1052d25e28abSJohan Hedberg 
1053d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
1054d25e28abSJohan Hedberg 	 * persistently */
1055d25e28abSJohan Hedberg 	return 0;
1056d25e28abSJohan Hedberg }
1057d25e28abSJohan Hedberg 
105875d262c2SVinicius Costa Gomes struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
105975d262c2SVinicius Costa Gomes {
106075d262c2SVinicius Costa Gomes 	struct link_key *k;
106175d262c2SVinicius Costa Gomes 
106275d262c2SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->link_keys, list) {
106375d262c2SVinicius Costa Gomes 		struct key_master_id *id;
106475d262c2SVinicius Costa Gomes 
106575d262c2SVinicius Costa Gomes 		if (k->type != HCI_LK_SMP_LTK)
106675d262c2SVinicius Costa Gomes 			continue;
106775d262c2SVinicius Costa Gomes 
106875d262c2SVinicius Costa Gomes 		if (k->dlen != sizeof(*id))
106975d262c2SVinicius Costa Gomes 			continue;
107075d262c2SVinicius Costa Gomes 
107175d262c2SVinicius Costa Gomes 		id = (void *) &k->data;
107275d262c2SVinicius Costa Gomes 		if (id->ediv == ediv &&
107375d262c2SVinicius Costa Gomes 				(memcmp(rand, id->rand, sizeof(id->rand)) == 0))
107475d262c2SVinicius Costa Gomes 			return k;
107575d262c2SVinicius Costa Gomes 	}
107675d262c2SVinicius Costa Gomes 
107775d262c2SVinicius Costa Gomes 	return NULL;
107875d262c2SVinicius Costa Gomes }
107975d262c2SVinicius Costa Gomes EXPORT_SYMBOL(hci_find_ltk);
108075d262c2SVinicius Costa Gomes 
108175d262c2SVinicius Costa Gomes struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
108275d262c2SVinicius Costa Gomes 					bdaddr_t *bdaddr, u8 type)
108375d262c2SVinicius Costa Gomes {
108475d262c2SVinicius Costa Gomes 	struct link_key *k;
108575d262c2SVinicius Costa Gomes 
108675d262c2SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->link_keys, list)
108775d262c2SVinicius Costa Gomes 		if (k->type == type && bacmp(bdaddr, &k->bdaddr) == 0)
108875d262c2SVinicius Costa Gomes 			return k;
108975d262c2SVinicius Costa Gomes 
109075d262c2SVinicius Costa Gomes 	return NULL;
109175d262c2SVinicius Costa Gomes }
109275d262c2SVinicius Costa Gomes EXPORT_SYMBOL(hci_find_link_key_type);
109375d262c2SVinicius Costa Gomes 
1094d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
1095d25e28abSJohan Hedberg 				bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
109655ed8ca1SJohan Hedberg {
109755ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
10984df378a1SJohan Hedberg 	u8 old_key_type, persistent;
109955ed8ca1SJohan Hedberg 
110055ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
110155ed8ca1SJohan Hedberg 	if (old_key) {
110255ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
110355ed8ca1SJohan Hedberg 		key = old_key;
110455ed8ca1SJohan Hedberg 	} else {
110512adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
110655ed8ca1SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
110755ed8ca1SJohan Hedberg 		if (!key)
110855ed8ca1SJohan Hedberg 			return -ENOMEM;
110955ed8ca1SJohan Hedberg 		list_add(&key->list, &hdev->link_keys);
111055ed8ca1SJohan Hedberg 	}
111155ed8ca1SJohan Hedberg 
111255ed8ca1SJohan Hedberg 	BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type);
111355ed8ca1SJohan Hedberg 
1114d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
1115d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
1116d25e28abSJohan Hedberg 	 * previous key */
1117d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
1118d25e28abSJohan Hedberg 					(!conn || conn->remote_auth == 0xff) &&
1119655fe6ecSJohan Hedberg 					old_key_type == 0xff) {
1120d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
1121655fe6ecSJohan Hedberg 		if (conn)
1122655fe6ecSJohan Hedberg 			conn->key_type = type;
1123655fe6ecSJohan Hedberg 	}
1124d25e28abSJohan Hedberg 
112555ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
112655ed8ca1SJohan Hedberg 	memcpy(key->val, val, 16);
112755ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
112855ed8ca1SJohan Hedberg 
1129b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
113055ed8ca1SJohan Hedberg 		key->type = old_key_type;
11314748fed2SJohan Hedberg 	else
11324748fed2SJohan Hedberg 		key->type = type;
11334748fed2SJohan Hedberg 
11344df378a1SJohan Hedberg 	if (!new_key)
11354df378a1SJohan Hedberg 		return 0;
11364df378a1SJohan Hedberg 
11374df378a1SJohan Hedberg 	persistent = hci_persistent_key(hdev, conn, type, old_key_type);
11384df378a1SJohan Hedberg 
1139744cf19eSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
11404df378a1SJohan Hedberg 
11414df378a1SJohan Hedberg 	if (!persistent) {
11424df378a1SJohan Hedberg 		list_del(&key->list);
11434df378a1SJohan Hedberg 		kfree(key);
11444df378a1SJohan Hedberg 	}
114555ed8ca1SJohan Hedberg 
114655ed8ca1SJohan Hedberg 	return 0;
114755ed8ca1SJohan Hedberg }
114855ed8ca1SJohan Hedberg 
114975d262c2SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
1150726b4ffcSVinicius Costa Gomes 			u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16])
115175d262c2SVinicius Costa Gomes {
115275d262c2SVinicius Costa Gomes 	struct link_key *key, *old_key;
115375d262c2SVinicius Costa Gomes 	struct key_master_id *id;
115475d262c2SVinicius Costa Gomes 	u8 old_key_type;
115575d262c2SVinicius Costa Gomes 
115675d262c2SVinicius Costa Gomes 	BT_DBG("%s addr %s", hdev->name, batostr(bdaddr));
115775d262c2SVinicius Costa Gomes 
115875d262c2SVinicius Costa Gomes 	old_key = hci_find_link_key_type(hdev, bdaddr, HCI_LK_SMP_LTK);
115975d262c2SVinicius Costa Gomes 	if (old_key) {
116075d262c2SVinicius Costa Gomes 		key = old_key;
116175d262c2SVinicius Costa Gomes 		old_key_type = old_key->type;
116275d262c2SVinicius Costa Gomes 	} else {
116375d262c2SVinicius Costa Gomes 		key = kzalloc(sizeof(*key) + sizeof(*id), GFP_ATOMIC);
116475d262c2SVinicius Costa Gomes 		if (!key)
116575d262c2SVinicius Costa Gomes 			return -ENOMEM;
116675d262c2SVinicius Costa Gomes 		list_add(&key->list, &hdev->link_keys);
116775d262c2SVinicius Costa Gomes 		old_key_type = 0xff;
116875d262c2SVinicius Costa Gomes 	}
116975d262c2SVinicius Costa Gomes 
117075d262c2SVinicius Costa Gomes 	key->dlen = sizeof(*id);
117175d262c2SVinicius Costa Gomes 
117275d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
117375d262c2SVinicius Costa Gomes 	memcpy(key->val, ltk, sizeof(key->val));
117475d262c2SVinicius Costa Gomes 	key->type = HCI_LK_SMP_LTK;
1175726b4ffcSVinicius Costa Gomes 	key->pin_len = key_size;
117675d262c2SVinicius Costa Gomes 
117775d262c2SVinicius Costa Gomes 	id = (void *) &key->data;
117875d262c2SVinicius Costa Gomes 	id->ediv = ediv;
117975d262c2SVinicius Costa Gomes 	memcpy(id->rand, rand, sizeof(id->rand));
118075d262c2SVinicius Costa Gomes 
118175d262c2SVinicius Costa Gomes 	if (new_key)
1182744cf19eSJohan Hedberg 		mgmt_new_link_key(hdev, key, old_key_type);
118375d262c2SVinicius Costa Gomes 
118475d262c2SVinicius Costa Gomes 	return 0;
118575d262c2SVinicius Costa Gomes }
118675d262c2SVinicius Costa Gomes 
118755ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
118855ed8ca1SJohan Hedberg {
118955ed8ca1SJohan Hedberg 	struct link_key *key;
119055ed8ca1SJohan Hedberg 
119155ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
119255ed8ca1SJohan Hedberg 	if (!key)
119355ed8ca1SJohan Hedberg 		return -ENOENT;
119455ed8ca1SJohan Hedberg 
119555ed8ca1SJohan Hedberg 	BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
119655ed8ca1SJohan Hedberg 
119755ed8ca1SJohan Hedberg 	list_del(&key->list);
119855ed8ca1SJohan Hedberg 	kfree(key);
119955ed8ca1SJohan Hedberg 
120055ed8ca1SJohan Hedberg 	return 0;
120155ed8ca1SJohan Hedberg }
120255ed8ca1SJohan Hedberg 
12036bd32326SVille Tervo /* HCI command timer function */
12046bd32326SVille Tervo static void hci_cmd_timer(unsigned long arg)
12056bd32326SVille Tervo {
12066bd32326SVille Tervo 	struct hci_dev *hdev = (void *) arg;
12076bd32326SVille Tervo 
12086bd32326SVille Tervo 	BT_ERR("%s command tx timeout", hdev->name);
12096bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
12106bd32326SVille Tervo 	tasklet_schedule(&hdev->cmd_task);
12116bd32326SVille Tervo }
12126bd32326SVille Tervo 
12132763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
12142763eda6SSzymon Janc 							bdaddr_t *bdaddr)
12152763eda6SSzymon Janc {
12162763eda6SSzymon Janc 	struct oob_data *data;
12172763eda6SSzymon Janc 
12182763eda6SSzymon Janc 	list_for_each_entry(data, &hdev->remote_oob_data, list)
12192763eda6SSzymon Janc 		if (bacmp(bdaddr, &data->bdaddr) == 0)
12202763eda6SSzymon Janc 			return data;
12212763eda6SSzymon Janc 
12222763eda6SSzymon Janc 	return NULL;
12232763eda6SSzymon Janc }
12242763eda6SSzymon Janc 
12252763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
12262763eda6SSzymon Janc {
12272763eda6SSzymon Janc 	struct oob_data *data;
12282763eda6SSzymon Janc 
12292763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
12302763eda6SSzymon Janc 	if (!data)
12312763eda6SSzymon Janc 		return -ENOENT;
12322763eda6SSzymon Janc 
12332763eda6SSzymon Janc 	BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
12342763eda6SSzymon Janc 
12352763eda6SSzymon Janc 	list_del(&data->list);
12362763eda6SSzymon Janc 	kfree(data);
12372763eda6SSzymon Janc 
12382763eda6SSzymon Janc 	return 0;
12392763eda6SSzymon Janc }
12402763eda6SSzymon Janc 
12412763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev)
12422763eda6SSzymon Janc {
12432763eda6SSzymon Janc 	struct oob_data *data, *n;
12442763eda6SSzymon Janc 
12452763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
12462763eda6SSzymon Janc 		list_del(&data->list);
12472763eda6SSzymon Janc 		kfree(data);
12482763eda6SSzymon Janc 	}
12492763eda6SSzymon Janc 
12502763eda6SSzymon Janc 	return 0;
12512763eda6SSzymon Janc }
12522763eda6SSzymon Janc 
12532763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
12542763eda6SSzymon Janc 								u8 *randomizer)
12552763eda6SSzymon Janc {
12562763eda6SSzymon Janc 	struct oob_data *data;
12572763eda6SSzymon Janc 
12582763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
12592763eda6SSzymon Janc 
12602763eda6SSzymon Janc 	if (!data) {
12612763eda6SSzymon Janc 		data = kmalloc(sizeof(*data), GFP_ATOMIC);
12622763eda6SSzymon Janc 		if (!data)
12632763eda6SSzymon Janc 			return -ENOMEM;
12642763eda6SSzymon Janc 
12652763eda6SSzymon Janc 		bacpy(&data->bdaddr, bdaddr);
12662763eda6SSzymon Janc 		list_add(&data->list, &hdev->remote_oob_data);
12672763eda6SSzymon Janc 	}
12682763eda6SSzymon Janc 
12692763eda6SSzymon Janc 	memcpy(data->hash, hash, sizeof(data->hash));
12702763eda6SSzymon Janc 	memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
12712763eda6SSzymon Janc 
12722763eda6SSzymon Janc 	BT_DBG("%s for %s", hdev->name, batostr(bdaddr));
12732763eda6SSzymon Janc 
12742763eda6SSzymon Janc 	return 0;
12752763eda6SSzymon Janc }
12762763eda6SSzymon Janc 
1277b2a66aadSAntti Julku struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev,
1278b2a66aadSAntti Julku 						bdaddr_t *bdaddr)
1279b2a66aadSAntti Julku {
1280b2a66aadSAntti Julku 	struct bdaddr_list *b;
1281b2a66aadSAntti Julku 
12828035ded4SLuiz Augusto von Dentz 	list_for_each_entry(b, &hdev->blacklist, list)
1283b2a66aadSAntti Julku 		if (bacmp(bdaddr, &b->bdaddr) == 0)
1284b2a66aadSAntti Julku 			return b;
1285b2a66aadSAntti Julku 
1286b2a66aadSAntti Julku 	return NULL;
1287b2a66aadSAntti Julku }
1288b2a66aadSAntti Julku 
1289b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev)
1290b2a66aadSAntti Julku {
1291b2a66aadSAntti Julku 	struct list_head *p, *n;
1292b2a66aadSAntti Julku 
1293b2a66aadSAntti Julku 	list_for_each_safe(p, n, &hdev->blacklist) {
1294b2a66aadSAntti Julku 		struct bdaddr_list *b;
1295b2a66aadSAntti Julku 
1296b2a66aadSAntti Julku 		b = list_entry(p, struct bdaddr_list, list);
1297b2a66aadSAntti Julku 
1298b2a66aadSAntti Julku 		list_del(p);
1299b2a66aadSAntti Julku 		kfree(b);
1300b2a66aadSAntti Julku 	}
1301b2a66aadSAntti Julku 
1302b2a66aadSAntti Julku 	return 0;
1303b2a66aadSAntti Julku }
1304b2a66aadSAntti Julku 
1305b2a66aadSAntti Julku int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr)
1306b2a66aadSAntti Julku {
1307b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1308b2a66aadSAntti Julku 
1309b2a66aadSAntti Julku 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
1310b2a66aadSAntti Julku 		return -EBADF;
1311b2a66aadSAntti Julku 
13125e762444SAntti Julku 	if (hci_blacklist_lookup(hdev, bdaddr))
13135e762444SAntti Julku 		return -EEXIST;
1314b2a66aadSAntti Julku 
1315b2a66aadSAntti Julku 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
13165e762444SAntti Julku 	if (!entry)
13175e762444SAntti Julku 		return -ENOMEM;
1318b2a66aadSAntti Julku 
1319b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
1320b2a66aadSAntti Julku 
1321b2a66aadSAntti Julku 	list_add(&entry->list, &hdev->blacklist);
1322b2a66aadSAntti Julku 
1323744cf19eSJohan Hedberg 	return mgmt_device_blocked(hdev, bdaddr);
1324b2a66aadSAntti Julku }
1325b2a66aadSAntti Julku 
1326b2a66aadSAntti Julku int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr)
1327b2a66aadSAntti Julku {
1328b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1329b2a66aadSAntti Julku 
13301ec918ceSSzymon Janc 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
13315e762444SAntti Julku 		return hci_blacklist_clear(hdev);
1332b2a66aadSAntti Julku 
1333b2a66aadSAntti Julku 	entry = hci_blacklist_lookup(hdev, bdaddr);
13341ec918ceSSzymon Janc 	if (!entry)
13355e762444SAntti Julku 		return -ENOENT;
1336b2a66aadSAntti Julku 
1337b2a66aadSAntti Julku 	list_del(&entry->list);
1338b2a66aadSAntti Julku 	kfree(entry);
1339b2a66aadSAntti Julku 
1340744cf19eSJohan Hedberg 	return mgmt_device_unblocked(hdev, bdaddr);
1341b2a66aadSAntti Julku }
1342b2a66aadSAntti Julku 
1343db323f2fSGustavo F. Padovan static void hci_clear_adv_cache(struct work_struct *work)
134435815085SAndre Guedes {
1345db323f2fSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev,
1346db323f2fSGustavo F. Padovan 							adv_work.work);
134735815085SAndre Guedes 
134835815085SAndre Guedes 	hci_dev_lock(hdev);
134935815085SAndre Guedes 
135035815085SAndre Guedes 	hci_adv_entries_clear(hdev);
135135815085SAndre Guedes 
135235815085SAndre Guedes 	hci_dev_unlock(hdev);
135335815085SAndre Guedes }
135435815085SAndre Guedes 
135576c8686fSAndre Guedes int hci_adv_entries_clear(struct hci_dev *hdev)
135676c8686fSAndre Guedes {
135776c8686fSAndre Guedes 	struct adv_entry *entry, *tmp;
135876c8686fSAndre Guedes 
135976c8686fSAndre Guedes 	list_for_each_entry_safe(entry, tmp, &hdev->adv_entries, list) {
136076c8686fSAndre Guedes 		list_del(&entry->list);
136176c8686fSAndre Guedes 		kfree(entry);
136276c8686fSAndre Guedes 	}
136376c8686fSAndre Guedes 
136476c8686fSAndre Guedes 	BT_DBG("%s adv cache cleared", hdev->name);
136576c8686fSAndre Guedes 
136676c8686fSAndre Guedes 	return 0;
136776c8686fSAndre Guedes }
136876c8686fSAndre Guedes 
136976c8686fSAndre Guedes struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr)
137076c8686fSAndre Guedes {
137176c8686fSAndre Guedes 	struct adv_entry *entry;
137276c8686fSAndre Guedes 
137376c8686fSAndre Guedes 	list_for_each_entry(entry, &hdev->adv_entries, list)
137476c8686fSAndre Guedes 		if (bacmp(bdaddr, &entry->bdaddr) == 0)
137576c8686fSAndre Guedes 			return entry;
137676c8686fSAndre Guedes 
137776c8686fSAndre Guedes 	return NULL;
137876c8686fSAndre Guedes }
137976c8686fSAndre Guedes 
138076c8686fSAndre Guedes static inline int is_connectable_adv(u8 evt_type)
138176c8686fSAndre Guedes {
138276c8686fSAndre Guedes 	if (evt_type == ADV_IND || evt_type == ADV_DIRECT_IND)
138376c8686fSAndre Guedes 		return 1;
138476c8686fSAndre Guedes 
138576c8686fSAndre Guedes 	return 0;
138676c8686fSAndre Guedes }
138776c8686fSAndre Guedes 
138876c8686fSAndre Guedes int hci_add_adv_entry(struct hci_dev *hdev,
138976c8686fSAndre Guedes 					struct hci_ev_le_advertising_info *ev)
139076c8686fSAndre Guedes {
139176c8686fSAndre Guedes 	struct adv_entry *entry;
139276c8686fSAndre Guedes 
139376c8686fSAndre Guedes 	if (!is_connectable_adv(ev->evt_type))
139476c8686fSAndre Guedes 		return -EINVAL;
139576c8686fSAndre Guedes 
139676c8686fSAndre Guedes 	/* Only new entries should be added to adv_entries. So, if
139776c8686fSAndre Guedes 	 * bdaddr was found, don't add it. */
139876c8686fSAndre Guedes 	if (hci_find_adv_entry(hdev, &ev->bdaddr))
139976c8686fSAndre Guedes 		return 0;
140076c8686fSAndre Guedes 
140176c8686fSAndre Guedes 	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
140276c8686fSAndre Guedes 	if (!entry)
140376c8686fSAndre Guedes 		return -ENOMEM;
140476c8686fSAndre Guedes 
140576c8686fSAndre Guedes 	bacpy(&entry->bdaddr, &ev->bdaddr);
140676c8686fSAndre Guedes 	entry->bdaddr_type = ev->bdaddr_type;
140776c8686fSAndre Guedes 
140876c8686fSAndre Guedes 	list_add(&entry->list, &hdev->adv_entries);
140976c8686fSAndre Guedes 
141076c8686fSAndre Guedes 	BT_DBG("%s adv entry added: address %s type %u", hdev->name,
141176c8686fSAndre Guedes 				batostr(&entry->bdaddr), entry->bdaddr_type);
141276c8686fSAndre Guedes 
141376c8686fSAndre Guedes 	return 0;
141476c8686fSAndre Guedes }
141576c8686fSAndre Guedes 
14161da177e4SLinus Torvalds /* Register HCI device */
14171da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
14181da177e4SLinus Torvalds {
14191da177e4SLinus Torvalds 	struct list_head *head = &hci_dev_list, *p;
142008add513SMat Martineau 	int i, id, error;
14211da177e4SLinus Torvalds 
1422c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d owner %p", hdev, hdev->name,
1423c13854ceSMarcel Holtmann 						hdev->bus, hdev->owner);
14241da177e4SLinus Torvalds 
14251da177e4SLinus Torvalds 	if (!hdev->open || !hdev->close || !hdev->destruct)
14261da177e4SLinus Torvalds 		return -EINVAL;
14271da177e4SLinus Torvalds 
142808add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
142908add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
143008add513SMat Martineau 	 */
143108add513SMat Martineau 	id = (hdev->dev_type == HCI_BREDR) ? 0 : 1;
143208add513SMat Martineau 
14331da177e4SLinus Torvalds 	write_lock_bh(&hci_dev_list_lock);
14341da177e4SLinus Torvalds 
14351da177e4SLinus Torvalds 	/* Find first available device id */
14361da177e4SLinus Torvalds 	list_for_each(p, &hci_dev_list) {
14371da177e4SLinus Torvalds 		if (list_entry(p, struct hci_dev, list)->id != id)
14381da177e4SLinus Torvalds 			break;
14391da177e4SLinus Torvalds 		head = p; id++;
14401da177e4SLinus Torvalds 	}
14411da177e4SLinus Torvalds 
14421da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
14431da177e4SLinus Torvalds 	hdev->id = id;
1444c6feeb28SAndrei Emeltchenko 	list_add_tail(&hdev->list, head);
14451da177e4SLinus Torvalds 
14461da177e4SLinus Torvalds 	atomic_set(&hdev->refcnt, 1);
144709fd0de5SGustavo F. Padovan 	mutex_init(&hdev->lock);
14481da177e4SLinus Torvalds 
14491da177e4SLinus Torvalds 	hdev->flags = 0;
1450d23264a8SAndre Guedes 	hdev->dev_flags = 0;
14511da177e4SLinus Torvalds 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
14525b7f9909SMarcel Holtmann 	hdev->esco_type = (ESCO_HV1);
14531da177e4SLinus Torvalds 	hdev->link_mode = (HCI_LM_ACCEPT);
145417fa4b9dSJohan Hedberg 	hdev->io_capability = 0x03; /* No Input No Output */
14551da177e4SLinus Torvalds 
145604837f64SMarcel Holtmann 	hdev->idle_timeout = 0;
145704837f64SMarcel Holtmann 	hdev->sniff_max_interval = 800;
145804837f64SMarcel Holtmann 	hdev->sniff_min_interval = 80;
145904837f64SMarcel Holtmann 
1460b78752ccSMarcel Holtmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
1461b78752ccSMarcel Holtmann 
14621da177e4SLinus Torvalds 	tasklet_init(&hdev->cmd_task, hci_cmd_task,(unsigned long) hdev);
14631da177e4SLinus Torvalds 	tasklet_init(&hdev->tx_task, hci_tx_task, (unsigned long) hdev);
14641da177e4SLinus Torvalds 
14651da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->rx_q);
14661da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->cmd_q);
14671da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->raw_q);
14681da177e4SLinus Torvalds 
14696bd32326SVille Tervo 	setup_timer(&hdev->cmd_timer, hci_cmd_timer, (unsigned long) hdev);
14706bd32326SVille Tervo 
1471cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
1472ef222013SMarcel Holtmann 		hdev->reassembly[i] = NULL;
1473ef222013SMarcel Holtmann 
14741da177e4SLinus Torvalds 	init_waitqueue_head(&hdev->req_wait_q);
1475a6a67efdSThomas Gleixner 	mutex_init(&hdev->req_lock);
14761da177e4SLinus Torvalds 
14771da177e4SLinus Torvalds 	inquiry_cache_init(hdev);
14781da177e4SLinus Torvalds 
14791da177e4SLinus Torvalds 	hci_conn_hash_init(hdev);
14801da177e4SLinus Torvalds 
14812e58ef3eSJohan Hedberg 	INIT_LIST_HEAD(&hdev->mgmt_pending);
14822e58ef3eSJohan Hedberg 
1483ea4bd8baSDavid Miller 	INIT_LIST_HEAD(&hdev->blacklist);
1484f0358568SJohan Hedberg 
14852aeb9a1aSJohan Hedberg 	INIT_LIST_HEAD(&hdev->uuids);
14862aeb9a1aSJohan Hedberg 
148755ed8ca1SJohan Hedberg 	INIT_LIST_HEAD(&hdev->link_keys);
148855ed8ca1SJohan Hedberg 
14892763eda6SSzymon Janc 	INIT_LIST_HEAD(&hdev->remote_oob_data);
14902763eda6SSzymon Janc 
149176c8686fSAndre Guedes 	INIT_LIST_HEAD(&hdev->adv_entries);
149276c8686fSAndre Guedes 
1493db323f2fSGustavo F. Padovan 	INIT_DELAYED_WORK(&hdev->adv_work, hci_clear_adv_cache);
1494ab81cbf9SJohan Hedberg 	INIT_WORK(&hdev->power_on, hci_power_on);
14953243553fSJohan Hedberg 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
1496ab81cbf9SJohan Hedberg 
149716ab91abSJohan Hedberg 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
149816ab91abSJohan Hedberg 
14991da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
15001da177e4SLinus Torvalds 
15011da177e4SLinus Torvalds 	atomic_set(&hdev->promisc, 0);
15021da177e4SLinus Torvalds 
15031da177e4SLinus Torvalds 	write_unlock_bh(&hci_dev_list_lock);
15041da177e4SLinus Torvalds 
1505f48fd9c8SMarcel Holtmann 	hdev->workqueue = create_singlethread_workqueue(hdev->name);
150633ca954dSDavid Herrmann 	if (!hdev->workqueue) {
150733ca954dSDavid Herrmann 		error = -ENOMEM;
150833ca954dSDavid Herrmann 		goto err;
150933ca954dSDavid Herrmann 	}
1510f48fd9c8SMarcel Holtmann 
151133ca954dSDavid Herrmann 	error = hci_add_sysfs(hdev);
151233ca954dSDavid Herrmann 	if (error < 0)
151333ca954dSDavid Herrmann 		goto err_wqueue;
15141da177e4SLinus Torvalds 
1515611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
1516611b30f7SMarcel Holtmann 				RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, hdev);
1517611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
1518611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
1519611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
1520611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
1521611b30f7SMarcel Holtmann 		}
1522611b30f7SMarcel Holtmann 	}
1523611b30f7SMarcel Holtmann 
1524ab81cbf9SJohan Hedberg 	set_bit(HCI_AUTO_OFF, &hdev->flags);
1525ab81cbf9SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->flags);
1526ab81cbf9SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->power_on);
1527ab81cbf9SJohan Hedberg 
15281da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
15291da177e4SLinus Torvalds 
15301da177e4SLinus Torvalds 	return id;
1531f48fd9c8SMarcel Holtmann 
153233ca954dSDavid Herrmann err_wqueue:
153333ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
153433ca954dSDavid Herrmann err:
1535f48fd9c8SMarcel Holtmann 	write_lock_bh(&hci_dev_list_lock);
1536f48fd9c8SMarcel Holtmann 	list_del(&hdev->list);
1537f48fd9c8SMarcel Holtmann 	write_unlock_bh(&hci_dev_list_lock);
1538f48fd9c8SMarcel Holtmann 
153933ca954dSDavid Herrmann 	return error;
15401da177e4SLinus Torvalds }
15411da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
15421da177e4SLinus Torvalds 
15431da177e4SLinus Torvalds /* Unregister HCI device */
154459735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
15451da177e4SLinus Torvalds {
1546ef222013SMarcel Holtmann 	int i;
1547ef222013SMarcel Holtmann 
1548c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
15491da177e4SLinus Torvalds 
15501da177e4SLinus Torvalds 	write_lock_bh(&hci_dev_list_lock);
15511da177e4SLinus Torvalds 	list_del(&hdev->list);
15521da177e4SLinus Torvalds 	write_unlock_bh(&hci_dev_list_lock);
15531da177e4SLinus Torvalds 
15541da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
15551da177e4SLinus Torvalds 
1556cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
1557ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
1558ef222013SMarcel Holtmann 
1559ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
156056e5cb86SJohan Hedberg 					!test_bit(HCI_SETUP, &hdev->flags)) {
156109fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
1562744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
156309fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
156456e5cb86SJohan Hedberg 	}
1565ab81cbf9SJohan Hedberg 
15662e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
15672e58ef3eSJohan Hedberg 	 * pending list */
15682e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
15692e58ef3eSJohan Hedberg 
15701da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
15711da177e4SLinus Torvalds 
1572611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
1573611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
1574611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
1575611b30f7SMarcel Holtmann 	}
1576611b30f7SMarcel Holtmann 
1577ce242970SDavid Herrmann 	hci_del_sysfs(hdev);
1578147e2d59SDave Young 
1579db323f2fSGustavo F. Padovan 	cancel_delayed_work_sync(&hdev->adv_work);
1580c6f3c5f7SGustavo F. Padovan 
1581f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
1582f48fd9c8SMarcel Holtmann 
158309fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
1584e2e0cacbSJohan Hedberg 	hci_blacklist_clear(hdev);
15852aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
158655ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
15872763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
158876c8686fSAndre Guedes 	hci_adv_entries_clear(hdev);
158909fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
1590e2e0cacbSJohan Hedberg 
15911da177e4SLinus Torvalds 	__hci_dev_put(hdev);
15921da177e4SLinus Torvalds }
15931da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
15941da177e4SLinus Torvalds 
15951da177e4SLinus Torvalds /* Suspend HCI device */
15961da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
15971da177e4SLinus Torvalds {
15981da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
15991da177e4SLinus Torvalds 	return 0;
16001da177e4SLinus Torvalds }
16011da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
16021da177e4SLinus Torvalds 
16031da177e4SLinus Torvalds /* Resume HCI device */
16041da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
16051da177e4SLinus Torvalds {
16061da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
16071da177e4SLinus Torvalds 	return 0;
16081da177e4SLinus Torvalds }
16091da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
16101da177e4SLinus Torvalds 
161176bca880SMarcel Holtmann /* Receive frame from HCI drivers */
161276bca880SMarcel Holtmann int hci_recv_frame(struct sk_buff *skb)
161376bca880SMarcel Holtmann {
161476bca880SMarcel Holtmann 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
161576bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
161676bca880SMarcel Holtmann 				&& !test_bit(HCI_INIT, &hdev->flags))) {
161776bca880SMarcel Holtmann 		kfree_skb(skb);
161876bca880SMarcel Holtmann 		return -ENXIO;
161976bca880SMarcel Holtmann 	}
162076bca880SMarcel Holtmann 
162176bca880SMarcel Holtmann 	/* Incomming skb */
162276bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
162376bca880SMarcel Holtmann 
162476bca880SMarcel Holtmann 	/* Time stamp */
162576bca880SMarcel Holtmann 	__net_timestamp(skb);
162676bca880SMarcel Holtmann 
162776bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
1628b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
1629c78ae283SMarcel Holtmann 
163076bca880SMarcel Holtmann 	return 0;
163176bca880SMarcel Holtmann }
163276bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
163376bca880SMarcel Holtmann 
163433e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
16351e429f38SGustavo F. Padovan 						  int count, __u8 index)
163633e882a5SSuraj Sumangala {
163733e882a5SSuraj Sumangala 	int len = 0;
163833e882a5SSuraj Sumangala 	int hlen = 0;
163933e882a5SSuraj Sumangala 	int remain = count;
164033e882a5SSuraj Sumangala 	struct sk_buff *skb;
164133e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
164233e882a5SSuraj Sumangala 
164333e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
164433e882a5SSuraj Sumangala 				index >= NUM_REASSEMBLY)
164533e882a5SSuraj Sumangala 		return -EILSEQ;
164633e882a5SSuraj Sumangala 
164733e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
164833e882a5SSuraj Sumangala 
164933e882a5SSuraj Sumangala 	if (!skb) {
165033e882a5SSuraj Sumangala 		switch (type) {
165133e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
165233e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
165333e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
165433e882a5SSuraj Sumangala 			break;
165533e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
165633e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
165733e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
165833e882a5SSuraj Sumangala 			break;
165933e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
166033e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
166133e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
166233e882a5SSuraj Sumangala 			break;
166333e882a5SSuraj Sumangala 		}
166433e882a5SSuraj Sumangala 
16651e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
166633e882a5SSuraj Sumangala 		if (!skb)
166733e882a5SSuraj Sumangala 			return -ENOMEM;
166833e882a5SSuraj Sumangala 
166933e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
167033e882a5SSuraj Sumangala 		scb->expect = hlen;
167133e882a5SSuraj Sumangala 		scb->pkt_type = type;
167233e882a5SSuraj Sumangala 
167333e882a5SSuraj Sumangala 		skb->dev = (void *) hdev;
167433e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
167533e882a5SSuraj Sumangala 	}
167633e882a5SSuraj Sumangala 
167733e882a5SSuraj Sumangala 	while (count) {
167833e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
167933e882a5SSuraj Sumangala 		len = min(scb->expect, (__u16)count);
168033e882a5SSuraj Sumangala 
168133e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
168233e882a5SSuraj Sumangala 
168333e882a5SSuraj Sumangala 		count -= len;
168433e882a5SSuraj Sumangala 		data += len;
168533e882a5SSuraj Sumangala 		scb->expect -= len;
168633e882a5SSuraj Sumangala 		remain = count;
168733e882a5SSuraj Sumangala 
168833e882a5SSuraj Sumangala 		switch (type) {
168933e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
169033e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
169133e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
169233e882a5SSuraj Sumangala 				scb->expect = h->plen;
169333e882a5SSuraj Sumangala 
169433e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
169533e882a5SSuraj Sumangala 					kfree_skb(skb);
169633e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
169733e882a5SSuraj Sumangala 					return -ENOMEM;
169833e882a5SSuraj Sumangala 				}
169933e882a5SSuraj Sumangala 			}
170033e882a5SSuraj Sumangala 			break;
170133e882a5SSuraj Sumangala 
170233e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
170333e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
170433e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
170533e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
170633e882a5SSuraj Sumangala 
170733e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
170833e882a5SSuraj Sumangala 					kfree_skb(skb);
170933e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
171033e882a5SSuraj Sumangala 					return -ENOMEM;
171133e882a5SSuraj Sumangala 				}
171233e882a5SSuraj Sumangala 			}
171333e882a5SSuraj Sumangala 			break;
171433e882a5SSuraj Sumangala 
171533e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
171633e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
171733e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
171833e882a5SSuraj Sumangala 				scb->expect = h->dlen;
171933e882a5SSuraj Sumangala 
172033e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
172133e882a5SSuraj Sumangala 					kfree_skb(skb);
172233e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
172333e882a5SSuraj Sumangala 					return -ENOMEM;
172433e882a5SSuraj Sumangala 				}
172533e882a5SSuraj Sumangala 			}
172633e882a5SSuraj Sumangala 			break;
172733e882a5SSuraj Sumangala 		}
172833e882a5SSuraj Sumangala 
172933e882a5SSuraj Sumangala 		if (scb->expect == 0) {
173033e882a5SSuraj Sumangala 			/* Complete frame */
173133e882a5SSuraj Sumangala 
173233e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
173333e882a5SSuraj Sumangala 			hci_recv_frame(skb);
173433e882a5SSuraj Sumangala 
173533e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
173633e882a5SSuraj Sumangala 			return remain;
173733e882a5SSuraj Sumangala 		}
173833e882a5SSuraj Sumangala 	}
173933e882a5SSuraj Sumangala 
174033e882a5SSuraj Sumangala 	return remain;
174133e882a5SSuraj Sumangala }
174233e882a5SSuraj Sumangala 
1743ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
1744ef222013SMarcel Holtmann {
1745f39a3c06SSuraj Sumangala 	int rem = 0;
1746f39a3c06SSuraj Sumangala 
1747ef222013SMarcel Holtmann 	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
1748ef222013SMarcel Holtmann 		return -EILSEQ;
1749ef222013SMarcel Holtmann 
1750da5f6c37SGustavo F. Padovan 	while (count) {
17511e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count, type - 1);
1752f39a3c06SSuraj Sumangala 		if (rem < 0)
1753f39a3c06SSuraj Sumangala 			return rem;
1754ef222013SMarcel Holtmann 
1755f39a3c06SSuraj Sumangala 		data += (count - rem);
1756f39a3c06SSuraj Sumangala 		count = rem;
1757f81c6224SJoe Perches 	}
1758ef222013SMarcel Holtmann 
1759f39a3c06SSuraj Sumangala 	return rem;
1760ef222013SMarcel Holtmann }
1761ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment);
1762ef222013SMarcel Holtmann 
176399811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
176499811510SSuraj Sumangala 
176599811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
176699811510SSuraj Sumangala {
176799811510SSuraj Sumangala 	int type;
176899811510SSuraj Sumangala 	int rem = 0;
176999811510SSuraj Sumangala 
1770da5f6c37SGustavo F. Padovan 	while (count) {
177199811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
177299811510SSuraj Sumangala 
177399811510SSuraj Sumangala 		if (!skb) {
177499811510SSuraj Sumangala 			struct { char type; } *pkt;
177599811510SSuraj Sumangala 
177699811510SSuraj Sumangala 			/* Start of the frame */
177799811510SSuraj Sumangala 			pkt = data;
177899811510SSuraj Sumangala 			type = pkt->type;
177999811510SSuraj Sumangala 
178099811510SSuraj Sumangala 			data++;
178199811510SSuraj Sumangala 			count--;
178299811510SSuraj Sumangala 		} else
178399811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
178499811510SSuraj Sumangala 
17851e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
17861e429f38SGustavo F. Padovan 							STREAM_REASSEMBLY);
178799811510SSuraj Sumangala 		if (rem < 0)
178899811510SSuraj Sumangala 			return rem;
178999811510SSuraj Sumangala 
179099811510SSuraj Sumangala 		data += (count - rem);
179199811510SSuraj Sumangala 		count = rem;
1792f81c6224SJoe Perches 	}
179399811510SSuraj Sumangala 
179499811510SSuraj Sumangala 	return rem;
179599811510SSuraj Sumangala }
179699811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
179799811510SSuraj Sumangala 
17981da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
17991da177e4SLinus Torvalds 
18001da177e4SLinus Torvalds /* Register/Unregister protocols.
18011da177e4SLinus Torvalds  * hci_task_lock is used to ensure that no tasks are running. */
18021da177e4SLinus Torvalds int hci_register_proto(struct hci_proto *hp)
18031da177e4SLinus Torvalds {
18041da177e4SLinus Torvalds 	int err = 0;
18051da177e4SLinus Torvalds 
18061da177e4SLinus Torvalds 	BT_DBG("%p name %s id %d", hp, hp->name, hp->id);
18071da177e4SLinus Torvalds 
18081da177e4SLinus Torvalds 	if (hp->id >= HCI_MAX_PROTO)
18091da177e4SLinus Torvalds 		return -EINVAL;
18101da177e4SLinus Torvalds 
18111da177e4SLinus Torvalds 	write_lock_bh(&hci_task_lock);
18121da177e4SLinus Torvalds 
18131da177e4SLinus Torvalds 	if (!hci_proto[hp->id])
18141da177e4SLinus Torvalds 		hci_proto[hp->id] = hp;
18151da177e4SLinus Torvalds 	else
18161da177e4SLinus Torvalds 		err = -EEXIST;
18171da177e4SLinus Torvalds 
18181da177e4SLinus Torvalds 	write_unlock_bh(&hci_task_lock);
18191da177e4SLinus Torvalds 
18201da177e4SLinus Torvalds 	return err;
18211da177e4SLinus Torvalds }
18221da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_proto);
18231da177e4SLinus Torvalds 
18241da177e4SLinus Torvalds int hci_unregister_proto(struct hci_proto *hp)
18251da177e4SLinus Torvalds {
18261da177e4SLinus Torvalds 	int err = 0;
18271da177e4SLinus Torvalds 
18281da177e4SLinus Torvalds 	BT_DBG("%p name %s id %d", hp, hp->name, hp->id);
18291da177e4SLinus Torvalds 
18301da177e4SLinus Torvalds 	if (hp->id >= HCI_MAX_PROTO)
18311da177e4SLinus Torvalds 		return -EINVAL;
18321da177e4SLinus Torvalds 
18331da177e4SLinus Torvalds 	write_lock_bh(&hci_task_lock);
18341da177e4SLinus Torvalds 
18351da177e4SLinus Torvalds 	if (hci_proto[hp->id])
18361da177e4SLinus Torvalds 		hci_proto[hp->id] = NULL;
18371da177e4SLinus Torvalds 	else
18381da177e4SLinus Torvalds 		err = -ENOENT;
18391da177e4SLinus Torvalds 
18401da177e4SLinus Torvalds 	write_unlock_bh(&hci_task_lock);
18411da177e4SLinus Torvalds 
18421da177e4SLinus Torvalds 	return err;
18431da177e4SLinus Torvalds }
18441da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_proto);
18451da177e4SLinus Torvalds 
18461da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
18471da177e4SLinus Torvalds {
18481da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
18491da177e4SLinus Torvalds 
18501da177e4SLinus Torvalds 	write_lock_bh(&hci_cb_list_lock);
18511da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
18521da177e4SLinus Torvalds 	write_unlock_bh(&hci_cb_list_lock);
18531da177e4SLinus Torvalds 
18541da177e4SLinus Torvalds 	return 0;
18551da177e4SLinus Torvalds }
18561da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
18571da177e4SLinus Torvalds 
18581da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
18591da177e4SLinus Torvalds {
18601da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
18611da177e4SLinus Torvalds 
18621da177e4SLinus Torvalds 	write_lock_bh(&hci_cb_list_lock);
18631da177e4SLinus Torvalds 	list_del(&cb->list);
18641da177e4SLinus Torvalds 	write_unlock_bh(&hci_cb_list_lock);
18651da177e4SLinus Torvalds 
18661da177e4SLinus Torvalds 	return 0;
18671da177e4SLinus Torvalds }
18681da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
18691da177e4SLinus Torvalds 
18701da177e4SLinus Torvalds static int hci_send_frame(struct sk_buff *skb)
18711da177e4SLinus Torvalds {
18721da177e4SLinus Torvalds 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
18731da177e4SLinus Torvalds 
18741da177e4SLinus Torvalds 	if (!hdev) {
18751da177e4SLinus Torvalds 		kfree_skb(skb);
18761da177e4SLinus Torvalds 		return -ENODEV;
18771da177e4SLinus Torvalds 	}
18781da177e4SLinus Torvalds 
18790d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
18801da177e4SLinus Torvalds 
18811da177e4SLinus Torvalds 	if (atomic_read(&hdev->promisc)) {
18821da177e4SLinus Torvalds 		/* Time stamp */
1883a61bbcf2SPatrick McHardy 		__net_timestamp(skb);
18841da177e4SLinus Torvalds 
1885eec8d2bcSJohan Hedberg 		hci_send_to_sock(hdev, skb, NULL);
18861da177e4SLinus Torvalds 	}
18871da177e4SLinus Torvalds 
18881da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
18891da177e4SLinus Torvalds 	skb_orphan(skb);
18901da177e4SLinus Torvalds 
18911da177e4SLinus Torvalds 	return hdev->send(skb);
18921da177e4SLinus Torvalds }
18931da177e4SLinus Torvalds 
18941da177e4SLinus Torvalds /* Send HCI command */
1895a9de9248SMarcel Holtmann int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)
18961da177e4SLinus Torvalds {
18971da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
18981da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
18991da177e4SLinus Torvalds 	struct sk_buff *skb;
19001da177e4SLinus Torvalds 
1901a9de9248SMarcel Holtmann 	BT_DBG("%s opcode 0x%x plen %d", hdev->name, opcode, plen);
19021da177e4SLinus Torvalds 
19031da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
19041da177e4SLinus Torvalds 	if (!skb) {
1905ef222013SMarcel Holtmann 		BT_ERR("%s no memory for command", hdev->name);
19061da177e4SLinus Torvalds 		return -ENOMEM;
19071da177e4SLinus Torvalds 	}
19081da177e4SLinus Torvalds 
19091da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
1910a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
19111da177e4SLinus Torvalds 	hdr->plen   = plen;
19121da177e4SLinus Torvalds 
19131da177e4SLinus Torvalds 	if (plen)
19141da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
19151da177e4SLinus Torvalds 
19161da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
19171da177e4SLinus Torvalds 
19180d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
19191da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
1920c78ae283SMarcel Holtmann 
1921a5040efaSJohan Hedberg 	if (test_bit(HCI_INIT, &hdev->flags))
1922a5040efaSJohan Hedberg 		hdev->init_last_cmd = opcode;
1923a5040efaSJohan Hedberg 
19241da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
1925c78ae283SMarcel Holtmann 	tasklet_schedule(&hdev->cmd_task);
19261da177e4SLinus Torvalds 
19271da177e4SLinus Torvalds 	return 0;
19281da177e4SLinus Torvalds }
19291da177e4SLinus Torvalds 
19301da177e4SLinus Torvalds /* Get data from the previously sent command */
1931a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
19321da177e4SLinus Torvalds {
19331da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
19341da177e4SLinus Torvalds 
19351da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
19361da177e4SLinus Torvalds 		return NULL;
19371da177e4SLinus Torvalds 
19381da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
19391da177e4SLinus Torvalds 
1940a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
19411da177e4SLinus Torvalds 		return NULL;
19421da177e4SLinus Torvalds 
1943a9de9248SMarcel Holtmann 	BT_DBG("%s opcode 0x%x", hdev->name, opcode);
19441da177e4SLinus Torvalds 
19451da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
19461da177e4SLinus Torvalds }
19471da177e4SLinus Torvalds 
19481da177e4SLinus Torvalds /* Send ACL data */
19491da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
19501da177e4SLinus Torvalds {
19511da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
19521da177e4SLinus Torvalds 	int len = skb->len;
19531da177e4SLinus Torvalds 
1954badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
1955badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
19569c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
1957aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
1958aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
19591da177e4SLinus Torvalds }
19601da177e4SLinus Torvalds 
196173d80debSLuiz Augusto von Dentz static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue,
196273d80debSLuiz Augusto von Dentz 				struct sk_buff *skb, __u16 flags)
19631da177e4SLinus Torvalds {
19641da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
19651da177e4SLinus Torvalds 	struct sk_buff *list;
19661da177e4SLinus Torvalds 
196770f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
196870f23020SAndrei Emeltchenko 	if (!list) {
19691da177e4SLinus Torvalds 		/* Non fragmented */
19701da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
19711da177e4SLinus Torvalds 
197273d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
19731da177e4SLinus Torvalds 	} else {
19741da177e4SLinus Torvalds 		/* Fragmented */
19751da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
19761da177e4SLinus Torvalds 
19771da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
19781da177e4SLinus Torvalds 
19791da177e4SLinus Torvalds 		/* Queue all fragments atomically */
198073d80debSLuiz Augusto von Dentz 		spin_lock_bh(&queue->lock);
19811da177e4SLinus Torvalds 
198273d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
1983e702112fSAndrei Emeltchenko 
1984e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
1985e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
19861da177e4SLinus Torvalds 		do {
19871da177e4SLinus Torvalds 			skb = list; list = list->next;
19881da177e4SLinus Torvalds 
19891da177e4SLinus Torvalds 			skb->dev = (void *) hdev;
19900d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
1991e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
19921da177e4SLinus Torvalds 
19931da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
19941da177e4SLinus Torvalds 
199573d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
19961da177e4SLinus Torvalds 		} while (list);
19971da177e4SLinus Torvalds 
199873d80debSLuiz Augusto von Dentz 		spin_unlock_bh(&queue->lock);
19991da177e4SLinus Torvalds 	}
200073d80debSLuiz Augusto von Dentz }
200173d80debSLuiz Augusto von Dentz 
200273d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
200373d80debSLuiz Augusto von Dentz {
200473d80debSLuiz Augusto von Dentz 	struct hci_conn *conn = chan->conn;
200573d80debSLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
200673d80debSLuiz Augusto von Dentz 
200773d80debSLuiz Augusto von Dentz 	BT_DBG("%s chan %p flags 0x%x", hdev->name, chan, flags);
200873d80debSLuiz Augusto von Dentz 
200973d80debSLuiz Augusto von Dentz 	skb->dev = (void *) hdev;
201073d80debSLuiz Augusto von Dentz 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
201173d80debSLuiz Augusto von Dentz 	hci_add_acl_hdr(skb, conn->handle, flags);
201273d80debSLuiz Augusto von Dentz 
201373d80debSLuiz Augusto von Dentz 	hci_queue_acl(conn, &chan->data_q, skb, flags);
20141da177e4SLinus Torvalds 
2015c78ae283SMarcel Holtmann 	tasklet_schedule(&hdev->tx_task);
20161da177e4SLinus Torvalds }
20171da177e4SLinus Torvalds EXPORT_SYMBOL(hci_send_acl);
20181da177e4SLinus Torvalds 
20191da177e4SLinus Torvalds /* Send SCO data */
20200d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
20211da177e4SLinus Torvalds {
20221da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
20231da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
20241da177e4SLinus Torvalds 
20251da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
20261da177e4SLinus Torvalds 
2027aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
20281da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
20291da177e4SLinus Torvalds 
2030badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
2031badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
20329c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
20331da177e4SLinus Torvalds 
20341da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
20350d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
2036c78ae283SMarcel Holtmann 
20371da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
2038c78ae283SMarcel Holtmann 	tasklet_schedule(&hdev->tx_task);
20391da177e4SLinus Torvalds }
20401da177e4SLinus Torvalds EXPORT_SYMBOL(hci_send_sco);
20411da177e4SLinus Torvalds 
20421da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
20431da177e4SLinus Torvalds 
20441da177e4SLinus Torvalds /* HCI Connection scheduler */
20451da177e4SLinus Torvalds static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote)
20461da177e4SLinus Torvalds {
20471da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
20488035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
20491da177e4SLinus Torvalds 	int num = 0, min = ~0;
20501da177e4SLinus Torvalds 
20511da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
20521da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
20538035ded4SLuiz Augusto von Dentz 	list_for_each_entry(c, &h->list, list) {
2054769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
20551da177e4SLinus Torvalds 			continue;
2056769be974SMarcel Holtmann 
2057769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
2058769be974SMarcel Holtmann 			continue;
2059769be974SMarcel Holtmann 
20601da177e4SLinus Torvalds 		num++;
20611da177e4SLinus Torvalds 
20621da177e4SLinus Torvalds 		if (c->sent < min) {
20631da177e4SLinus Torvalds 			min  = c->sent;
20641da177e4SLinus Torvalds 			conn = c;
20651da177e4SLinus Torvalds 		}
206652087a79SLuiz Augusto von Dentz 
206752087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
206852087a79SLuiz Augusto von Dentz 			break;
20691da177e4SLinus Torvalds 	}
20701da177e4SLinus Torvalds 
20711da177e4SLinus Torvalds 	if (conn) {
20726ed58ec5SVille Tervo 		int cnt, q;
20736ed58ec5SVille Tervo 
20746ed58ec5SVille Tervo 		switch (conn->type) {
20756ed58ec5SVille Tervo 		case ACL_LINK:
20766ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
20776ed58ec5SVille Tervo 			break;
20786ed58ec5SVille Tervo 		case SCO_LINK:
20796ed58ec5SVille Tervo 		case ESCO_LINK:
20806ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
20816ed58ec5SVille Tervo 			break;
20826ed58ec5SVille Tervo 		case LE_LINK:
20836ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
20846ed58ec5SVille Tervo 			break;
20856ed58ec5SVille Tervo 		default:
20866ed58ec5SVille Tervo 			cnt = 0;
20876ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
20886ed58ec5SVille Tervo 		}
20896ed58ec5SVille Tervo 
20906ed58ec5SVille Tervo 		q = cnt / num;
20911da177e4SLinus Torvalds 		*quote = q ? q : 1;
20921da177e4SLinus Torvalds 	} else
20931da177e4SLinus Torvalds 		*quote = 0;
20941da177e4SLinus Torvalds 
20951da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
20961da177e4SLinus Torvalds 	return conn;
20971da177e4SLinus Torvalds }
20981da177e4SLinus Torvalds 
2099bae1f5d9SVille Tervo static inline void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
21001da177e4SLinus Torvalds {
21011da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
21021da177e4SLinus Torvalds 	struct hci_conn *c;
21031da177e4SLinus Torvalds 
2104bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
21051da177e4SLinus Torvalds 
21061da177e4SLinus Torvalds 	/* Kill stalled connections */
21078035ded4SLuiz Augusto von Dentz 	list_for_each_entry(c, &h->list, list) {
2108bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
2109bae1f5d9SVille Tervo 			BT_ERR("%s killing stalled connection %s",
21101da177e4SLinus Torvalds 				hdev->name, batostr(&c->dst));
21111da177e4SLinus Torvalds 			hci_acl_disconn(c, 0x13);
21121da177e4SLinus Torvalds 		}
21131da177e4SLinus Torvalds 	}
21141da177e4SLinus Torvalds }
21151da177e4SLinus Torvalds 
211673d80debSLuiz Augusto von Dentz static inline struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
211773d80debSLuiz Augusto von Dentz 						int *quote)
211873d80debSLuiz Augusto von Dentz {
211973d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
212073d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
212173d80debSLuiz Augusto von Dentz 	int num = 0, min = ~0, cur_prio = 0;
212273d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
212373d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
212473d80debSLuiz Augusto von Dentz 
212573d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
212673d80debSLuiz Augusto von Dentz 
212773d80debSLuiz Augusto von Dentz 	list_for_each_entry(conn, &h->list, list) {
212873d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
212973d80debSLuiz Augusto von Dentz 
213073d80debSLuiz Augusto von Dentz 		if (conn->type != type)
213173d80debSLuiz Augusto von Dentz 			continue;
213273d80debSLuiz Augusto von Dentz 
213373d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
213473d80debSLuiz Augusto von Dentz 			continue;
213573d80debSLuiz Augusto von Dentz 
213673d80debSLuiz Augusto von Dentz 		conn_num++;
213773d80debSLuiz Augusto von Dentz 
21382c33c06aSGustavo F. Padovan 		list_for_each_entry(tmp, &conn->chan_list, list) {
213973d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
214073d80debSLuiz Augusto von Dentz 
214173d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
214273d80debSLuiz Augusto von Dentz 				continue;
214373d80debSLuiz Augusto von Dentz 
214473d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
214573d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
214673d80debSLuiz Augusto von Dentz 				continue;
214773d80debSLuiz Augusto von Dentz 
214873d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
214973d80debSLuiz Augusto von Dentz 				num = 0;
215073d80debSLuiz Augusto von Dentz 				min = ~0;
215173d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
215273d80debSLuiz Augusto von Dentz 			}
215373d80debSLuiz Augusto von Dentz 
215473d80debSLuiz Augusto von Dentz 			num++;
215573d80debSLuiz Augusto von Dentz 
215673d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
215773d80debSLuiz Augusto von Dentz 				min  = conn->sent;
215873d80debSLuiz Augusto von Dentz 				chan = tmp;
215973d80debSLuiz Augusto von Dentz 			}
216073d80debSLuiz Augusto von Dentz 		}
216173d80debSLuiz Augusto von Dentz 
216273d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
216373d80debSLuiz Augusto von Dentz 			break;
216473d80debSLuiz Augusto von Dentz 	}
216573d80debSLuiz Augusto von Dentz 
216673d80debSLuiz Augusto von Dentz 	if (!chan)
216773d80debSLuiz Augusto von Dentz 		return NULL;
216873d80debSLuiz Augusto von Dentz 
216973d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
217073d80debSLuiz Augusto von Dentz 	case ACL_LINK:
217173d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
217273d80debSLuiz Augusto von Dentz 		break;
217373d80debSLuiz Augusto von Dentz 	case SCO_LINK:
217473d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
217573d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
217673d80debSLuiz Augusto von Dentz 		break;
217773d80debSLuiz Augusto von Dentz 	case LE_LINK:
217873d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
217973d80debSLuiz Augusto von Dentz 		break;
218073d80debSLuiz Augusto von Dentz 	default:
218173d80debSLuiz Augusto von Dentz 		cnt = 0;
218273d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
218373d80debSLuiz Augusto von Dentz 	}
218473d80debSLuiz Augusto von Dentz 
218573d80debSLuiz Augusto von Dentz 	q = cnt / num;
218673d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
218773d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
218873d80debSLuiz Augusto von Dentz 	return chan;
218973d80debSLuiz Augusto von Dentz }
219073d80debSLuiz Augusto von Dentz 
219102b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
219202b20f0bSLuiz Augusto von Dentz {
219302b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
219402b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
219502b20f0bSLuiz Augusto von Dentz 	int num = 0;
219602b20f0bSLuiz Augusto von Dentz 
219702b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
219802b20f0bSLuiz Augusto von Dentz 
219902b20f0bSLuiz Augusto von Dentz 	list_for_each_entry(conn, &h->list, list) {
220002b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
220102b20f0bSLuiz Augusto von Dentz 
220202b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
220302b20f0bSLuiz Augusto von Dentz 			continue;
220402b20f0bSLuiz Augusto von Dentz 
220502b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
220602b20f0bSLuiz Augusto von Dentz 			continue;
220702b20f0bSLuiz Augusto von Dentz 
220802b20f0bSLuiz Augusto von Dentz 		num++;
220902b20f0bSLuiz Augusto von Dentz 
22102c33c06aSGustavo F. Padovan 		list_for_each_entry(chan, &conn->chan_list, list) {
221102b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
221202b20f0bSLuiz Augusto von Dentz 
221302b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
221402b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
221502b20f0bSLuiz Augusto von Dentz 				continue;
221602b20f0bSLuiz Augusto von Dentz 			}
221702b20f0bSLuiz Augusto von Dentz 
221802b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
221902b20f0bSLuiz Augusto von Dentz 				continue;
222002b20f0bSLuiz Augusto von Dentz 
222102b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
222202b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
222302b20f0bSLuiz Augusto von Dentz 				continue;
222402b20f0bSLuiz Augusto von Dentz 
222502b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
222602b20f0bSLuiz Augusto von Dentz 
222702b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
222802b20f0bSLuiz Augusto von Dentz 								skb->priority);
222902b20f0bSLuiz Augusto von Dentz 		}
223002b20f0bSLuiz Augusto von Dentz 
223102b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
223202b20f0bSLuiz Augusto von Dentz 			break;
223302b20f0bSLuiz Augusto von Dentz 	}
223402b20f0bSLuiz Augusto von Dentz }
223502b20f0bSLuiz Augusto von Dentz 
22361da177e4SLinus Torvalds static inline void hci_sched_acl(struct hci_dev *hdev)
22371da177e4SLinus Torvalds {
223873d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
22391da177e4SLinus Torvalds 	struct sk_buff *skb;
22401da177e4SLinus Torvalds 	int quote;
224173d80debSLuiz Augusto von Dentz 	unsigned int cnt;
22421da177e4SLinus Torvalds 
22431da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
22441da177e4SLinus Torvalds 
224552087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ACL_LINK))
224652087a79SLuiz Augusto von Dentz 		return;
224752087a79SLuiz Augusto von Dentz 
22481da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
22491da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
22501da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
225182453021SS.Çağlar Onur 		if (!hdev->acl_cnt && time_after(jiffies, hdev->acl_last_tx + HZ * 45))
2252bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
22531da177e4SLinus Torvalds 	}
22541da177e4SLinus Torvalds 
225573d80debSLuiz Augusto von Dentz 	cnt = hdev->acl_cnt;
225604837f64SMarcel Holtmann 
225773d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
225873d80debSLuiz Augusto von Dentz 			(chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
2259ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
2260ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
226173d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
226273d80debSLuiz Augusto von Dentz 					skb->len, skb->priority);
226373d80debSLuiz Augusto von Dentz 
2264ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
2265ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
2266ec1cce24SLuiz Augusto von Dentz 				break;
2267ec1cce24SLuiz Augusto von Dentz 
2268ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
2269ec1cce24SLuiz Augusto von Dentz 
227073d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
227173d80debSLuiz Augusto von Dentz 						bt_cb(skb)->force_active);
227204837f64SMarcel Holtmann 
22731da177e4SLinus Torvalds 			hci_send_frame(skb);
22741da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
22751da177e4SLinus Torvalds 
22761da177e4SLinus Torvalds 			hdev->acl_cnt--;
227773d80debSLuiz Augusto von Dentz 			chan->sent++;
227873d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
22791da177e4SLinus Torvalds 		}
22801da177e4SLinus Torvalds 	}
228102b20f0bSLuiz Augusto von Dentz 
228202b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
228302b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
22841da177e4SLinus Torvalds }
22851da177e4SLinus Torvalds 
22861da177e4SLinus Torvalds /* Schedule SCO */
22871da177e4SLinus Torvalds static inline void hci_sched_sco(struct hci_dev *hdev)
22881da177e4SLinus Torvalds {
22891da177e4SLinus Torvalds 	struct hci_conn *conn;
22901da177e4SLinus Torvalds 	struct sk_buff *skb;
22911da177e4SLinus Torvalds 	int quote;
22921da177e4SLinus Torvalds 
22931da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
22941da177e4SLinus Torvalds 
229552087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
229652087a79SLuiz Augusto von Dentz 		return;
229752087a79SLuiz Augusto von Dentz 
22981da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
22991da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
23001da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
23011da177e4SLinus Torvalds 			hci_send_frame(skb);
23021da177e4SLinus Torvalds 
23031da177e4SLinus Torvalds 			conn->sent++;
23041da177e4SLinus Torvalds 			if (conn->sent == ~0)
23051da177e4SLinus Torvalds 				conn->sent = 0;
23061da177e4SLinus Torvalds 		}
23071da177e4SLinus Torvalds 	}
23081da177e4SLinus Torvalds }
23091da177e4SLinus Torvalds 
2310b6a0dc82SMarcel Holtmann static inline void hci_sched_esco(struct hci_dev *hdev)
2311b6a0dc82SMarcel Holtmann {
2312b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
2313b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
2314b6a0dc82SMarcel Holtmann 	int quote;
2315b6a0dc82SMarcel Holtmann 
2316b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
2317b6a0dc82SMarcel Holtmann 
231852087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
231952087a79SLuiz Augusto von Dentz 		return;
232052087a79SLuiz Augusto von Dentz 
2321b6a0dc82SMarcel Holtmann 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, &quote))) {
2322b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
2323b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
2324b6a0dc82SMarcel Holtmann 			hci_send_frame(skb);
2325b6a0dc82SMarcel Holtmann 
2326b6a0dc82SMarcel Holtmann 			conn->sent++;
2327b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
2328b6a0dc82SMarcel Holtmann 				conn->sent = 0;
2329b6a0dc82SMarcel Holtmann 		}
2330b6a0dc82SMarcel Holtmann 	}
2331b6a0dc82SMarcel Holtmann }
2332b6a0dc82SMarcel Holtmann 
23336ed58ec5SVille Tervo static inline void hci_sched_le(struct hci_dev *hdev)
23346ed58ec5SVille Tervo {
233573d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
23366ed58ec5SVille Tervo 	struct sk_buff *skb;
233702b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
23386ed58ec5SVille Tervo 
23396ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
23406ed58ec5SVille Tervo 
234152087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
234252087a79SLuiz Augusto von Dentz 		return;
234352087a79SLuiz Augusto von Dentz 
23446ed58ec5SVille Tervo 	if (!test_bit(HCI_RAW, &hdev->flags)) {
23456ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
23466ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
2347bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
23486ed58ec5SVille Tervo 				time_after(jiffies, hdev->le_last_tx + HZ * 45))
2349bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
23506ed58ec5SVille Tervo 	}
23516ed58ec5SVille Tervo 
23526ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
235302b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
235473d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
2355ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
2356ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
235773d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
235873d80debSLuiz Augusto von Dentz 					skb->len, skb->priority);
23596ed58ec5SVille Tervo 
2360ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
2361ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
2362ec1cce24SLuiz Augusto von Dentz 				break;
2363ec1cce24SLuiz Augusto von Dentz 
2364ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
2365ec1cce24SLuiz Augusto von Dentz 
23666ed58ec5SVille Tervo 			hci_send_frame(skb);
23676ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
23686ed58ec5SVille Tervo 
23696ed58ec5SVille Tervo 			cnt--;
237073d80debSLuiz Augusto von Dentz 			chan->sent++;
237173d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
23726ed58ec5SVille Tervo 		}
23736ed58ec5SVille Tervo 	}
237473d80debSLuiz Augusto von Dentz 
23756ed58ec5SVille Tervo 	if (hdev->le_pkts)
23766ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
23776ed58ec5SVille Tervo 	else
23786ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
237902b20f0bSLuiz Augusto von Dentz 
238002b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
238102b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
23826ed58ec5SVille Tervo }
23836ed58ec5SVille Tervo 
23841da177e4SLinus Torvalds static void hci_tx_task(unsigned long arg)
23851da177e4SLinus Torvalds {
23861da177e4SLinus Torvalds 	struct hci_dev *hdev = (struct hci_dev *) arg;
23871da177e4SLinus Torvalds 	struct sk_buff *skb;
23881da177e4SLinus Torvalds 
23891da177e4SLinus Torvalds 	read_lock(&hci_task_lock);
23901da177e4SLinus Torvalds 
23916ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
23926ed58ec5SVille Tervo 		hdev->sco_cnt, hdev->le_cnt);
23931da177e4SLinus Torvalds 
23941da177e4SLinus Torvalds 	/* Schedule queues and send stuff to HCI driver */
23951da177e4SLinus Torvalds 
23961da177e4SLinus Torvalds 	hci_sched_acl(hdev);
23971da177e4SLinus Torvalds 
23981da177e4SLinus Torvalds 	hci_sched_sco(hdev);
23991da177e4SLinus Torvalds 
2400b6a0dc82SMarcel Holtmann 	hci_sched_esco(hdev);
2401b6a0dc82SMarcel Holtmann 
24026ed58ec5SVille Tervo 	hci_sched_le(hdev);
24036ed58ec5SVille Tervo 
24041da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
24051da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
24061da177e4SLinus Torvalds 		hci_send_frame(skb);
24071da177e4SLinus Torvalds 
24081da177e4SLinus Torvalds 	read_unlock(&hci_task_lock);
24091da177e4SLinus Torvalds }
24101da177e4SLinus Torvalds 
241125985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
24121da177e4SLinus Torvalds 
24131da177e4SLinus Torvalds /* ACL data packet */
24141da177e4SLinus Torvalds static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
24151da177e4SLinus Torvalds {
24161da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
24171da177e4SLinus Torvalds 	struct hci_conn *conn;
24181da177e4SLinus Torvalds 	__u16 handle, flags;
24191da177e4SLinus Torvalds 
24201da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
24211da177e4SLinus Torvalds 
24221da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
24231da177e4SLinus Torvalds 	flags  = hci_flags(handle);
24241da177e4SLinus Torvalds 	handle = hci_handle(handle);
24251da177e4SLinus Torvalds 
24261da177e4SLinus Torvalds 	BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags);
24271da177e4SLinus Torvalds 
24281da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
24291da177e4SLinus Torvalds 
24301da177e4SLinus Torvalds 	hci_dev_lock(hdev);
24311da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
24321da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
24331da177e4SLinus Torvalds 
24341da177e4SLinus Torvalds 	if (conn) {
24351da177e4SLinus Torvalds 		register struct hci_proto *hp;
24361da177e4SLinus Torvalds 
243714b12d0bSJaikumar Ganesh 		hci_conn_enter_active_mode(conn, bt_cb(skb)->force_active);
243804837f64SMarcel Holtmann 
24391da177e4SLinus Torvalds 		/* Send to upper protocol */
244070f23020SAndrei Emeltchenko 		hp = hci_proto[HCI_PROTO_L2CAP];
244170f23020SAndrei Emeltchenko 		if (hp && hp->recv_acldata) {
24421da177e4SLinus Torvalds 			hp->recv_acldata(conn, skb, flags);
24431da177e4SLinus Torvalds 			return;
24441da177e4SLinus Torvalds 		}
24451da177e4SLinus Torvalds 	} else {
24461da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
24471da177e4SLinus Torvalds 			hdev->name, handle);
24481da177e4SLinus Torvalds 	}
24491da177e4SLinus Torvalds 
24501da177e4SLinus Torvalds 	kfree_skb(skb);
24511da177e4SLinus Torvalds }
24521da177e4SLinus Torvalds 
24531da177e4SLinus Torvalds /* SCO data packet */
24541da177e4SLinus Torvalds static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
24551da177e4SLinus Torvalds {
24561da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
24571da177e4SLinus Torvalds 	struct hci_conn *conn;
24581da177e4SLinus Torvalds 	__u16 handle;
24591da177e4SLinus Torvalds 
24601da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
24611da177e4SLinus Torvalds 
24621da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
24631da177e4SLinus Torvalds 
24641da177e4SLinus Torvalds 	BT_DBG("%s len %d handle 0x%x", hdev->name, skb->len, handle);
24651da177e4SLinus Torvalds 
24661da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
24671da177e4SLinus Torvalds 
24681da177e4SLinus Torvalds 	hci_dev_lock(hdev);
24691da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
24701da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
24711da177e4SLinus Torvalds 
24721da177e4SLinus Torvalds 	if (conn) {
24731da177e4SLinus Torvalds 		register struct hci_proto *hp;
24741da177e4SLinus Torvalds 
24751da177e4SLinus Torvalds 		/* Send to upper protocol */
247670f23020SAndrei Emeltchenko 		hp = hci_proto[HCI_PROTO_SCO];
247770f23020SAndrei Emeltchenko 		if (hp && hp->recv_scodata) {
24781da177e4SLinus Torvalds 			hp->recv_scodata(conn, skb);
24791da177e4SLinus Torvalds 			return;
24801da177e4SLinus Torvalds 		}
24811da177e4SLinus Torvalds 	} else {
24821da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
24831da177e4SLinus Torvalds 			hdev->name, handle);
24841da177e4SLinus Torvalds 	}
24851da177e4SLinus Torvalds 
24861da177e4SLinus Torvalds 	kfree_skb(skb);
24871da177e4SLinus Torvalds }
24881da177e4SLinus Torvalds 
2489b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
24901da177e4SLinus Torvalds {
2491b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
24921da177e4SLinus Torvalds 	struct sk_buff *skb;
24931da177e4SLinus Torvalds 
24941da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
24951da177e4SLinus Torvalds 
24961da177e4SLinus Torvalds 	read_lock(&hci_task_lock);
24971da177e4SLinus Torvalds 
24981da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
24991da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
25001da177e4SLinus Torvalds 			/* Send copy to the sockets */
2501eec8d2bcSJohan Hedberg 			hci_send_to_sock(hdev, skb, NULL);
25021da177e4SLinus Torvalds 		}
25031da177e4SLinus Torvalds 
25041da177e4SLinus Torvalds 		if (test_bit(HCI_RAW, &hdev->flags)) {
25051da177e4SLinus Torvalds 			kfree_skb(skb);
25061da177e4SLinus Torvalds 			continue;
25071da177e4SLinus Torvalds 		}
25081da177e4SLinus Torvalds 
25091da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
25101da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
25110d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
25121da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
25131da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
25141da177e4SLinus Torvalds 				kfree_skb(skb);
25151da177e4SLinus Torvalds 				continue;
25163ff50b79SStephen Hemminger 			}
25171da177e4SLinus Torvalds 		}
25181da177e4SLinus Torvalds 
25191da177e4SLinus Torvalds 		/* Process frame */
25200d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
25211da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
2522b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
25231da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
25241da177e4SLinus Torvalds 			break;
25251da177e4SLinus Torvalds 
25261da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
25271da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
25281da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
25291da177e4SLinus Torvalds 			break;
25301da177e4SLinus Torvalds 
25311da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
25321da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
25331da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
25341da177e4SLinus Torvalds 			break;
25351da177e4SLinus Torvalds 
25361da177e4SLinus Torvalds 		default:
25371da177e4SLinus Torvalds 			kfree_skb(skb);
25381da177e4SLinus Torvalds 			break;
25391da177e4SLinus Torvalds 		}
25401da177e4SLinus Torvalds 	}
25411da177e4SLinus Torvalds 
25421da177e4SLinus Torvalds 	read_unlock(&hci_task_lock);
25431da177e4SLinus Torvalds }
25441da177e4SLinus Torvalds 
25451da177e4SLinus Torvalds static void hci_cmd_task(unsigned long arg)
25461da177e4SLinus Torvalds {
25471da177e4SLinus Torvalds 	struct hci_dev *hdev = (struct hci_dev *) arg;
25481da177e4SLinus Torvalds 	struct sk_buff *skb;
25491da177e4SLinus Torvalds 
25501da177e4SLinus Torvalds 	BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
25511da177e4SLinus Torvalds 
25521da177e4SLinus Torvalds 	/* Send queued commands */
25535a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
25545a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
25555a08ecceSAndrei Emeltchenko 		if (!skb)
25565a08ecceSAndrei Emeltchenko 			return;
25575a08ecceSAndrei Emeltchenko 
25581da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
25591da177e4SLinus Torvalds 
256070f23020SAndrei Emeltchenko 		hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC);
256170f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
25621da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
25631da177e4SLinus Torvalds 			hci_send_frame(skb);
25647bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
25657bdb8a5cSSzymon Janc 				del_timer(&hdev->cmd_timer);
25667bdb8a5cSSzymon Janc 			else
25676bd32326SVille Tervo 				mod_timer(&hdev->cmd_timer,
25686bd32326SVille Tervo 				  jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT));
25691da177e4SLinus Torvalds 		} else {
25701da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
2571c78ae283SMarcel Holtmann 			tasklet_schedule(&hdev->cmd_task);
25721da177e4SLinus Torvalds 		}
25731da177e4SLinus Torvalds 	}
25741da177e4SLinus Torvalds }
25752519a1fcSAndre Guedes 
25762519a1fcSAndre Guedes int hci_do_inquiry(struct hci_dev *hdev, u8 length)
25772519a1fcSAndre Guedes {
25782519a1fcSAndre Guedes 	/* General inquiry access code (GIAC) */
25792519a1fcSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
25802519a1fcSAndre Guedes 	struct hci_cp_inquiry cp;
25812519a1fcSAndre Guedes 
25822519a1fcSAndre Guedes 	BT_DBG("%s", hdev->name);
25832519a1fcSAndre Guedes 
25842519a1fcSAndre Guedes 	if (test_bit(HCI_INQUIRY, &hdev->flags))
25852519a1fcSAndre Guedes 		return -EINPROGRESS;
25862519a1fcSAndre Guedes 
25872519a1fcSAndre Guedes 	memset(&cp, 0, sizeof(cp));
25882519a1fcSAndre Guedes 	memcpy(&cp.lap, lap, sizeof(cp.lap));
25892519a1fcSAndre Guedes 	cp.length  = length;
25902519a1fcSAndre Guedes 
25912519a1fcSAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
25922519a1fcSAndre Guedes }
2593023d5049SAndre Guedes 
2594023d5049SAndre Guedes int hci_cancel_inquiry(struct hci_dev *hdev)
2595023d5049SAndre Guedes {
2596023d5049SAndre Guedes 	BT_DBG("%s", hdev->name);
2597023d5049SAndre Guedes 
2598023d5049SAndre Guedes 	if (!test_bit(HCI_INQUIRY, &hdev->flags))
2599023d5049SAndre Guedes 		return -EPERM;
2600023d5049SAndre Guedes 
2601023d5049SAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL);
2602023d5049SAndre Guedes }
26037784d78fSAndrei Emeltchenko 
26047784d78fSAndrei Emeltchenko module_param(enable_hs, bool, 0644);
26057784d78fSAndrei Emeltchenko MODULE_PARM_DESC(enable_hs, "Enable High Speed");
2606