xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 65983fc7)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds    BlueZ - Bluetooth protocol stack for Linux
31da177e4SLinus Torvalds    Copyright (C) 2000-2001 Qualcomm Incorporated
4590051deSGustavo F. Padovan    Copyright (C) 2011 ProFUSION Embedded Systems
51da177e4SLinus Torvalds 
61da177e4SLinus Torvalds    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
71da177e4SLinus Torvalds 
81da177e4SLinus Torvalds    This program is free software; you can redistribute it and/or modify
91da177e4SLinus Torvalds    it under the terms of the GNU General Public License version 2 as
101da177e4SLinus Torvalds    published by the Free Software Foundation;
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
131da177e4SLinus Torvalds    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
141da177e4SLinus Torvalds    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
151da177e4SLinus Torvalds    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
161da177e4SLinus Torvalds    CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
171da177e4SLinus Torvalds    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
181da177e4SLinus Torvalds    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
191da177e4SLinus Torvalds    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
201da177e4SLinus Torvalds 
211da177e4SLinus Torvalds    ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
221da177e4SLinus Torvalds    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
231da177e4SLinus Torvalds    SOFTWARE IS DISCLAIMED.
241da177e4SLinus Torvalds */
251da177e4SLinus Torvalds 
261da177e4SLinus Torvalds /* Bluetooth HCI core. */
271da177e4SLinus Torvalds 
2882453021SS.Çağlar Onur #include <linux/jiffies.h>
291da177e4SLinus Torvalds #include <linux/module.h>
301da177e4SLinus Torvalds #include <linux/kmod.h>
311da177e4SLinus Torvalds 
321da177e4SLinus Torvalds #include <linux/types.h>
331da177e4SLinus Torvalds #include <linux/errno.h>
341da177e4SLinus Torvalds #include <linux/kernel.h>
351da177e4SLinus Torvalds #include <linux/sched.h>
361da177e4SLinus Torvalds #include <linux/slab.h>
371da177e4SLinus Torvalds #include <linux/poll.h>
381da177e4SLinus Torvalds #include <linux/fcntl.h>
391da177e4SLinus Torvalds #include <linux/init.h>
401da177e4SLinus Torvalds #include <linux/skbuff.h>
41f48fd9c8SMarcel Holtmann #include <linux/workqueue.h>
421da177e4SLinus Torvalds #include <linux/interrupt.h>
431da177e4SLinus Torvalds #include <linux/notifier.h>
44611b30f7SMarcel Holtmann #include <linux/rfkill.h>
456bd32326SVille Tervo #include <linux/timer.h>
463a0259bbSVinicius Costa Gomes #include <linux/crypto.h>
471da177e4SLinus Torvalds #include <net/sock.h>
481da177e4SLinus Torvalds 
491da177e4SLinus Torvalds #include <asm/system.h>
5070f23020SAndrei Emeltchenko #include <linux/uaccess.h>
511da177e4SLinus Torvalds #include <asm/unaligned.h>
521da177e4SLinus Torvalds 
531da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
541da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
551da177e4SLinus Torvalds 
56ab81cbf9SJohan Hedberg #define AUTO_OFF_TIMEOUT 2000
57ab81cbf9SJohan Hedberg 
587784d78fSAndrei Emeltchenko int enable_hs;
597784d78fSAndrei Emeltchenko 
60b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work);
61c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work);
623eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work);
631da177e4SLinus Torvalds 
6467d0dfb5SGustavo F. Padovan static DEFINE_MUTEX(hci_task_lock);
651da177e4SLinus Torvalds 
661da177e4SLinus Torvalds /* HCI device list */
671da177e4SLinus Torvalds LIST_HEAD(hci_dev_list);
681da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock);
691da177e4SLinus Torvalds 
701da177e4SLinus Torvalds /* HCI callback list */
711da177e4SLinus Torvalds LIST_HEAD(hci_cb_list);
721da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock);
731da177e4SLinus Torvalds 
741da177e4SLinus Torvalds /* HCI protocols */
751da177e4SLinus Torvalds #define HCI_MAX_PROTO	2
761da177e4SLinus Torvalds struct hci_proto *hci_proto[HCI_MAX_PROTO];
771da177e4SLinus Torvalds 
781da177e4SLinus Torvalds /* HCI notifiers list */
79e041c683SAlan Stern static ATOMIC_NOTIFIER_HEAD(hci_notifier);
801da177e4SLinus Torvalds 
811da177e4SLinus Torvalds /* ---- HCI notifications ---- */
821da177e4SLinus Torvalds 
831da177e4SLinus Torvalds int hci_register_notifier(struct notifier_block *nb)
841da177e4SLinus Torvalds {
85e041c683SAlan Stern 	return atomic_notifier_chain_register(&hci_notifier, nb);
861da177e4SLinus Torvalds }
871da177e4SLinus Torvalds 
881da177e4SLinus Torvalds int hci_unregister_notifier(struct notifier_block *nb)
891da177e4SLinus Torvalds {
90e041c683SAlan Stern 	return atomic_notifier_chain_unregister(&hci_notifier, nb);
911da177e4SLinus Torvalds }
921da177e4SLinus Torvalds 
936516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event)
941da177e4SLinus Torvalds {
95e041c683SAlan Stern 	atomic_notifier_call_chain(&hci_notifier, event, hdev);
961da177e4SLinus Torvalds }
971da177e4SLinus Torvalds 
981da177e4SLinus Torvalds /* ---- HCI requests ---- */
991da177e4SLinus Torvalds 
10023bb5763SJohan Hedberg void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result)
1011da177e4SLinus Torvalds {
10223bb5763SJohan Hedberg 	BT_DBG("%s command 0x%04x result 0x%2.2x", hdev->name, cmd, result);
10323bb5763SJohan Hedberg 
104a5040efaSJohan Hedberg 	/* If this is the init phase check if the completed command matches
105a5040efaSJohan Hedberg 	 * the last init command, and if not just return.
106a5040efaSJohan Hedberg 	 */
107a5040efaSJohan Hedberg 	if (test_bit(HCI_INIT, &hdev->flags) && hdev->init_last_cmd != cmd)
10823bb5763SJohan Hedberg 		return;
1091da177e4SLinus Torvalds 
1101da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
1111da177e4SLinus Torvalds 		hdev->req_result = result;
1121da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_DONE;
1131da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
1141da177e4SLinus Torvalds 	}
1151da177e4SLinus Torvalds }
1161da177e4SLinus Torvalds 
1171da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err)
1181da177e4SLinus Torvalds {
1191da177e4SLinus Torvalds 	BT_DBG("%s err 0x%2.2x", hdev->name, err);
1201da177e4SLinus Torvalds 
1211da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
1221da177e4SLinus Torvalds 		hdev->req_result = err;
1231da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_CANCELED;
1241da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
1251da177e4SLinus Torvalds 	}
1261da177e4SLinus Torvalds }
1271da177e4SLinus Torvalds 
1281da177e4SLinus Torvalds /* Execute request and wait for completion. */
1291da177e4SLinus Torvalds static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt),
1301da177e4SLinus Torvalds 					unsigned long opt, __u32 timeout)
1311da177e4SLinus Torvalds {
1321da177e4SLinus Torvalds 	DECLARE_WAITQUEUE(wait, current);
1331da177e4SLinus Torvalds 	int err = 0;
1341da177e4SLinus Torvalds 
1351da177e4SLinus Torvalds 	BT_DBG("%s start", hdev->name);
1361da177e4SLinus Torvalds 
1371da177e4SLinus Torvalds 	hdev->req_status = HCI_REQ_PEND;
1381da177e4SLinus Torvalds 
1391da177e4SLinus Torvalds 	add_wait_queue(&hdev->req_wait_q, &wait);
1401da177e4SLinus Torvalds 	set_current_state(TASK_INTERRUPTIBLE);
1411da177e4SLinus Torvalds 
1421da177e4SLinus Torvalds 	req(hdev, opt);
1431da177e4SLinus Torvalds 	schedule_timeout(timeout);
1441da177e4SLinus Torvalds 
1451da177e4SLinus Torvalds 	remove_wait_queue(&hdev->req_wait_q, &wait);
1461da177e4SLinus Torvalds 
1471da177e4SLinus Torvalds 	if (signal_pending(current))
1481da177e4SLinus Torvalds 		return -EINTR;
1491da177e4SLinus Torvalds 
1501da177e4SLinus Torvalds 	switch (hdev->req_status) {
1511da177e4SLinus Torvalds 	case HCI_REQ_DONE:
152e175072fSJoe Perches 		err = -bt_to_errno(hdev->req_result);
1531da177e4SLinus Torvalds 		break;
1541da177e4SLinus Torvalds 
1551da177e4SLinus Torvalds 	case HCI_REQ_CANCELED:
1561da177e4SLinus Torvalds 		err = -hdev->req_result;
1571da177e4SLinus Torvalds 		break;
1581da177e4SLinus Torvalds 
1591da177e4SLinus Torvalds 	default:
1601da177e4SLinus Torvalds 		err = -ETIMEDOUT;
1611da177e4SLinus Torvalds 		break;
1623ff50b79SStephen Hemminger 	}
1631da177e4SLinus Torvalds 
164a5040efaSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
1651da177e4SLinus Torvalds 
1661da177e4SLinus Torvalds 	BT_DBG("%s end: err %d", hdev->name, err);
1671da177e4SLinus Torvalds 
1681da177e4SLinus Torvalds 	return err;
1691da177e4SLinus Torvalds }
1701da177e4SLinus Torvalds 
1711da177e4SLinus Torvalds static inline int hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt),
1721da177e4SLinus Torvalds 					unsigned long opt, __u32 timeout)
1731da177e4SLinus Torvalds {
1741da177e4SLinus Torvalds 	int ret;
1751da177e4SLinus Torvalds 
1767c6a329eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
1777c6a329eSMarcel Holtmann 		return -ENETDOWN;
1787c6a329eSMarcel Holtmann 
1791da177e4SLinus Torvalds 	/* Serialize all requests */
1801da177e4SLinus Torvalds 	hci_req_lock(hdev);
1811da177e4SLinus Torvalds 	ret = __hci_request(hdev, req, opt, timeout);
1821da177e4SLinus Torvalds 	hci_req_unlock(hdev);
1831da177e4SLinus Torvalds 
1841da177e4SLinus Torvalds 	return ret;
1851da177e4SLinus Torvalds }
1861da177e4SLinus Torvalds 
1871da177e4SLinus Torvalds static void hci_reset_req(struct hci_dev *hdev, unsigned long opt)
1881da177e4SLinus Torvalds {
1891da177e4SLinus Torvalds 	BT_DBG("%s %ld", hdev->name, opt);
1901da177e4SLinus Torvalds 
1911da177e4SLinus Torvalds 	/* Reset device */
192f630cf0dSGustavo F. Padovan 	set_bit(HCI_RESET, &hdev->flags);
193a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
1941da177e4SLinus Torvalds }
1951da177e4SLinus Torvalds 
1961da177e4SLinus Torvalds static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
1971da177e4SLinus Torvalds {
198b0916ea0SJohan Hedberg 	struct hci_cp_delete_stored_link_key cp;
1991da177e4SLinus Torvalds 	struct sk_buff *skb;
2001ebb9252SMarcel Holtmann 	__le16 param;
20189f2783dSMarcel Holtmann 	__u8 flt_type;
2021da177e4SLinus Torvalds 
2031da177e4SLinus Torvalds 	BT_DBG("%s %ld", hdev->name, opt);
2041da177e4SLinus Torvalds 
2051da177e4SLinus Torvalds 	/* Driver initialization */
2061da177e4SLinus Torvalds 
2071da177e4SLinus Torvalds 	/* Special commands */
2081da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->driver_init))) {
2090d48d939SMarcel Holtmann 		bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
2101da177e4SLinus Torvalds 		skb->dev = (void *) hdev;
211c78ae283SMarcel Holtmann 
2121da177e4SLinus Torvalds 		skb_queue_tail(&hdev->cmd_q, skb);
213c347b765SGustavo F. Padovan 		queue_work(hdev->workqueue, &hdev->cmd_work);
2141da177e4SLinus Torvalds 	}
2151da177e4SLinus Torvalds 	skb_queue_purge(&hdev->driver_init);
2161da177e4SLinus Torvalds 
2171da177e4SLinus Torvalds 	/* Mandatory initialization */
2181da177e4SLinus Torvalds 
2191da177e4SLinus Torvalds 	/* Reset */
220f630cf0dSGustavo F. Padovan 	if (!test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) {
221f630cf0dSGustavo F. Padovan 			set_bit(HCI_RESET, &hdev->flags);
222a9de9248SMarcel Holtmann 			hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
223f630cf0dSGustavo F. Padovan 	}
2241da177e4SLinus Torvalds 
2251da177e4SLinus Torvalds 	/* Read Local Supported Features */
226a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
2271da177e4SLinus Torvalds 
2281143e5a6SMarcel Holtmann 	/* Read Local Version */
229a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
2301143e5a6SMarcel Holtmann 
2311da177e4SLinus Torvalds 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
232a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
2331da177e4SLinus Torvalds 
2341da177e4SLinus Torvalds 	/* Read BD Address */
235a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL);
236a9de9248SMarcel Holtmann 
237a9de9248SMarcel Holtmann 	/* Read Class of Device */
238a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
239a9de9248SMarcel Holtmann 
240a9de9248SMarcel Holtmann 	/* Read Local Name */
241a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL);
2421da177e4SLinus Torvalds 
2431da177e4SLinus Torvalds 	/* Read Voice Setting */
244a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL);
2451da177e4SLinus Torvalds 
2461da177e4SLinus Torvalds 	/* Optional initialization */
2471da177e4SLinus Torvalds 
2481da177e4SLinus Torvalds 	/* Clear Event Filters */
24989f2783dSMarcel Holtmann 	flt_type = HCI_FLT_CLEAR_ALL;
250a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
2511da177e4SLinus Torvalds 
2521da177e4SLinus Torvalds 	/* Connection accept timeout ~20 secs */
253aca3192cSYOSHIFUJI Hideaki 	param = cpu_to_le16(0x7d00);
254a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
255b0916ea0SJohan Hedberg 
256b0916ea0SJohan Hedberg 	bacpy(&cp.bdaddr, BDADDR_ANY);
257b0916ea0SJohan Hedberg 	cp.delete_all = 1;
258b0916ea0SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp);
2591da177e4SLinus Torvalds }
2601da177e4SLinus Torvalds 
2616ed58ec5SVille Tervo static void hci_le_init_req(struct hci_dev *hdev, unsigned long opt)
2626ed58ec5SVille Tervo {
2636ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
2646ed58ec5SVille Tervo 
2656ed58ec5SVille Tervo 	/* Read LE buffer size */
2666ed58ec5SVille Tervo 	hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
2676ed58ec5SVille Tervo }
2686ed58ec5SVille Tervo 
2691da177e4SLinus Torvalds static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
2701da177e4SLinus Torvalds {
2711da177e4SLinus Torvalds 	__u8 scan = opt;
2721da177e4SLinus Torvalds 
2731da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, scan);
2741da177e4SLinus Torvalds 
2751da177e4SLinus Torvalds 	/* Inquiry and Page scans */
276a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
2771da177e4SLinus Torvalds }
2781da177e4SLinus Torvalds 
2791da177e4SLinus Torvalds static void hci_auth_req(struct hci_dev *hdev, unsigned long opt)
2801da177e4SLinus Torvalds {
2811da177e4SLinus Torvalds 	__u8 auth = opt;
2821da177e4SLinus Torvalds 
2831da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, auth);
2841da177e4SLinus Torvalds 
2851da177e4SLinus Torvalds 	/* Authentication */
286a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
2871da177e4SLinus Torvalds }
2881da177e4SLinus Torvalds 
2891da177e4SLinus Torvalds static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt)
2901da177e4SLinus Torvalds {
2911da177e4SLinus Torvalds 	__u8 encrypt = opt;
2921da177e4SLinus Torvalds 
2931da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, encrypt);
2941da177e4SLinus Torvalds 
295e4e8e37cSMarcel Holtmann 	/* Encryption */
296a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
2971da177e4SLinus Torvalds }
2981da177e4SLinus Torvalds 
299e4e8e37cSMarcel Holtmann static void hci_linkpol_req(struct hci_dev *hdev, unsigned long opt)
300e4e8e37cSMarcel Holtmann {
301e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
302e4e8e37cSMarcel Holtmann 
303a418b893SMarcel Holtmann 	BT_DBG("%s %x", hdev->name, policy);
304e4e8e37cSMarcel Holtmann 
305e4e8e37cSMarcel Holtmann 	/* Default link policy */
306e4e8e37cSMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
307e4e8e37cSMarcel Holtmann }
308e4e8e37cSMarcel Holtmann 
3091da177e4SLinus Torvalds /* Get HCI device by index.
3101da177e4SLinus Torvalds  * Device is held on return. */
3111da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
3121da177e4SLinus Torvalds {
3138035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
3141da177e4SLinus Torvalds 
3151da177e4SLinus Torvalds 	BT_DBG("%d", index);
3161da177e4SLinus Torvalds 
3171da177e4SLinus Torvalds 	if (index < 0)
3181da177e4SLinus Torvalds 		return NULL;
3191da177e4SLinus Torvalds 
3201da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
3218035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
3221da177e4SLinus Torvalds 		if (d->id == index) {
3231da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
3241da177e4SLinus Torvalds 			break;
3251da177e4SLinus Torvalds 		}
3261da177e4SLinus Torvalds 	}
3271da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
3281da177e4SLinus Torvalds 	return hdev;
3291da177e4SLinus Torvalds }
3301da177e4SLinus Torvalds 
3311da177e4SLinus Torvalds /* ---- Inquiry support ---- */
3321da177e4SLinus Torvalds static void inquiry_cache_flush(struct hci_dev *hdev)
3331da177e4SLinus Torvalds {
3341da177e4SLinus Torvalds 	struct inquiry_cache *cache = &hdev->inq_cache;
3351da177e4SLinus Torvalds 	struct inquiry_entry *next  = cache->list, *e;
3361da177e4SLinus Torvalds 
3371da177e4SLinus Torvalds 	BT_DBG("cache %p", cache);
3381da177e4SLinus Torvalds 
3391da177e4SLinus Torvalds 	cache->list = NULL;
3401da177e4SLinus Torvalds 	while ((e = next)) {
3411da177e4SLinus Torvalds 		next = e->next;
3421da177e4SLinus Torvalds 		kfree(e);
3431da177e4SLinus Torvalds 	}
3441da177e4SLinus Torvalds }
3451da177e4SLinus Torvalds 
3461da177e4SLinus Torvalds struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
3471da177e4SLinus Torvalds {
3481da177e4SLinus Torvalds 	struct inquiry_cache *cache = &hdev->inq_cache;
3491da177e4SLinus Torvalds 	struct inquiry_entry *e;
3501da177e4SLinus Torvalds 
3511da177e4SLinus Torvalds 	BT_DBG("cache %p, %s", cache, batostr(bdaddr));
3521da177e4SLinus Torvalds 
3531da177e4SLinus Torvalds 	for (e = cache->list; e; e = e->next)
3541da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
3551da177e4SLinus Torvalds 			break;
3561da177e4SLinus Torvalds 	return e;
3571da177e4SLinus Torvalds }
3581da177e4SLinus Torvalds 
3591da177e4SLinus Torvalds void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data)
3601da177e4SLinus Torvalds {
3611da177e4SLinus Torvalds 	struct inquiry_cache *cache = &hdev->inq_cache;
36270f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
3631da177e4SLinus Torvalds 
3641da177e4SLinus Torvalds 	BT_DBG("cache %p, %s", cache, batostr(&data->bdaddr));
3651da177e4SLinus Torvalds 
36670f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
36770f23020SAndrei Emeltchenko 	if (!ie) {
3681da177e4SLinus Torvalds 		/* Entry not in the cache. Add new one. */
36970f23020SAndrei Emeltchenko 		ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
37070f23020SAndrei Emeltchenko 		if (!ie)
3711da177e4SLinus Torvalds 			return;
37270f23020SAndrei Emeltchenko 
37370f23020SAndrei Emeltchenko 		ie->next = cache->list;
37470f23020SAndrei Emeltchenko 		cache->list = ie;
3751da177e4SLinus Torvalds 	}
3761da177e4SLinus Torvalds 
37770f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
37870f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
3791da177e4SLinus Torvalds 	cache->timestamp = jiffies;
3801da177e4SLinus Torvalds }
3811da177e4SLinus Torvalds 
3821da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
3831da177e4SLinus Torvalds {
3841da177e4SLinus Torvalds 	struct inquiry_cache *cache = &hdev->inq_cache;
3851da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
3861da177e4SLinus Torvalds 	struct inquiry_entry *e;
3871da177e4SLinus Torvalds 	int copied = 0;
3881da177e4SLinus Torvalds 
3891da177e4SLinus Torvalds 	for (e = cache->list; e && copied < num; e = e->next, copied++) {
3901da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
3911da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
3921da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
3931da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
3941da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
3951da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
3961da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
3971da177e4SLinus Torvalds 		info++;
3981da177e4SLinus Torvalds 	}
3991da177e4SLinus Torvalds 
4001da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
4011da177e4SLinus Torvalds 	return copied;
4021da177e4SLinus Torvalds }
4031da177e4SLinus Torvalds 
4041da177e4SLinus Torvalds static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
4051da177e4SLinus Torvalds {
4061da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
4071da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
4081da177e4SLinus Torvalds 
4091da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
4101da177e4SLinus Torvalds 
4111da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
4121da177e4SLinus Torvalds 		return;
4131da177e4SLinus Torvalds 
4141da177e4SLinus Torvalds 	/* Start Inquiry */
4151da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
4161da177e4SLinus Torvalds 	cp.length  = ir->length;
4171da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
418a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
4191da177e4SLinus Torvalds }
4201da177e4SLinus Torvalds 
4211da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
4221da177e4SLinus Torvalds {
4231da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
4241da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
4251da177e4SLinus Torvalds 	struct hci_dev *hdev;
4261da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
4271da177e4SLinus Torvalds 	long timeo;
4281da177e4SLinus Torvalds 	__u8 *buf;
4291da177e4SLinus Torvalds 
4301da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
4311da177e4SLinus Torvalds 		return -EFAULT;
4321da177e4SLinus Torvalds 
4335a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
4345a08ecceSAndrei Emeltchenko 	if (!hdev)
4351da177e4SLinus Torvalds 		return -ENODEV;
4361da177e4SLinus Torvalds 
43709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
4381da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
4391da177e4SLinus Torvalds 				inquiry_cache_empty(hdev) ||
4401da177e4SLinus Torvalds 				ir.flags & IREQ_CACHE_FLUSH) {
4411da177e4SLinus Torvalds 		inquiry_cache_flush(hdev);
4421da177e4SLinus Torvalds 		do_inquiry = 1;
4431da177e4SLinus Torvalds 	}
44409fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
4451da177e4SLinus Torvalds 
44604837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
44770f23020SAndrei Emeltchenko 
44870f23020SAndrei Emeltchenko 	if (do_inquiry) {
44970f23020SAndrei Emeltchenko 		err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo);
45070f23020SAndrei Emeltchenko 		if (err < 0)
4511da177e4SLinus Torvalds 			goto done;
45270f23020SAndrei Emeltchenko 	}
4531da177e4SLinus Torvalds 
4541da177e4SLinus Torvalds 	/* for unlimited number of responses we will use buffer with 255 entries */
4551da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
4561da177e4SLinus Torvalds 
4571da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
4581da177e4SLinus Torvalds 	 * copy it to the user space.
4591da177e4SLinus Torvalds 	 */
46070f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
46170f23020SAndrei Emeltchenko 	if (!buf) {
4621da177e4SLinus Torvalds 		err = -ENOMEM;
4631da177e4SLinus Torvalds 		goto done;
4641da177e4SLinus Torvalds 	}
4651da177e4SLinus Torvalds 
46609fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
4671da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
46809fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
4691da177e4SLinus Torvalds 
4701da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
4711da177e4SLinus Torvalds 
4721da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
4731da177e4SLinus Torvalds 		ptr += sizeof(ir);
4741da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
4751da177e4SLinus Torvalds 					ir.num_rsp))
4761da177e4SLinus Torvalds 			err = -EFAULT;
4771da177e4SLinus Torvalds 	} else
4781da177e4SLinus Torvalds 		err = -EFAULT;
4791da177e4SLinus Torvalds 
4801da177e4SLinus Torvalds 	kfree(buf);
4811da177e4SLinus Torvalds 
4821da177e4SLinus Torvalds done:
4831da177e4SLinus Torvalds 	hci_dev_put(hdev);
4841da177e4SLinus Torvalds 	return err;
4851da177e4SLinus Torvalds }
4861da177e4SLinus Torvalds 
4871da177e4SLinus Torvalds /* ---- HCI ioctl helpers ---- */
4881da177e4SLinus Torvalds 
4891da177e4SLinus Torvalds int hci_dev_open(__u16 dev)
4901da177e4SLinus Torvalds {
4911da177e4SLinus Torvalds 	struct hci_dev *hdev;
4921da177e4SLinus Torvalds 	int ret = 0;
4931da177e4SLinus Torvalds 
4945a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(dev);
4955a08ecceSAndrei Emeltchenko 	if (!hdev)
4961da177e4SLinus Torvalds 		return -ENODEV;
4971da177e4SLinus Torvalds 
4981da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
4991da177e4SLinus Torvalds 
5001da177e4SLinus Torvalds 	hci_req_lock(hdev);
5011da177e4SLinus Torvalds 
502611b30f7SMarcel Holtmann 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) {
503611b30f7SMarcel Holtmann 		ret = -ERFKILL;
504611b30f7SMarcel Holtmann 		goto done;
505611b30f7SMarcel Holtmann 	}
506611b30f7SMarcel Holtmann 
5071da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
5081da177e4SLinus Torvalds 		ret = -EALREADY;
5091da177e4SLinus Torvalds 		goto done;
5101da177e4SLinus Torvalds 	}
5111da177e4SLinus Torvalds 
5121da177e4SLinus Torvalds 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
5131da177e4SLinus Torvalds 		set_bit(HCI_RAW, &hdev->flags);
5141da177e4SLinus Torvalds 
51507e3b94aSAndrei Emeltchenko 	/* Treat all non BR/EDR controllers as raw devices if
51607e3b94aSAndrei Emeltchenko 	   enable_hs is not set */
51707e3b94aSAndrei Emeltchenko 	if (hdev->dev_type != HCI_BREDR && !enable_hs)
518943da25dSMarcel Holtmann 		set_bit(HCI_RAW, &hdev->flags);
519943da25dSMarcel Holtmann 
5201da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
5211da177e4SLinus Torvalds 		ret = -EIO;
5221da177e4SLinus Torvalds 		goto done;
5231da177e4SLinus Torvalds 	}
5241da177e4SLinus Torvalds 
5251da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
5261da177e4SLinus Torvalds 		atomic_set(&hdev->cmd_cnt, 1);
5271da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
528a5040efaSJohan Hedberg 		hdev->init_last_cmd = 0;
5291da177e4SLinus Torvalds 
53004837f64SMarcel Holtmann 		ret = __hci_request(hdev, hci_init_req, 0,
53104837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
5321da177e4SLinus Torvalds 
533eead27daSAndre Guedes 		if (lmp_host_le_capable(hdev))
5346ed58ec5SVille Tervo 			ret = __hci_request(hdev, hci_le_init_req, 0,
5356ed58ec5SVille Tervo 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
5366ed58ec5SVille Tervo 
5371da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
5381da177e4SLinus Torvalds 	}
5391da177e4SLinus Torvalds 
5401da177e4SLinus Torvalds 	if (!ret) {
5411da177e4SLinus Torvalds 		hci_dev_hold(hdev);
5421da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
5431da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
54456e5cb86SJohan Hedberg 		if (!test_bit(HCI_SETUP, &hdev->flags)) {
54509fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
546744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
54709fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
54856e5cb86SJohan Hedberg 		}
5491da177e4SLinus Torvalds 	} else {
5501da177e4SLinus Torvalds 		/* Init failed, cleanup */
5513eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
552c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
553b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
5541da177e4SLinus Torvalds 
5551da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
5561da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
5571da177e4SLinus Torvalds 
5581da177e4SLinus Torvalds 		if (hdev->flush)
5591da177e4SLinus Torvalds 			hdev->flush(hdev);
5601da177e4SLinus Torvalds 
5611da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
5621da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
5631da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
5641da177e4SLinus Torvalds 		}
5651da177e4SLinus Torvalds 
5661da177e4SLinus Torvalds 		hdev->close(hdev);
5671da177e4SLinus Torvalds 		hdev->flags = 0;
5681da177e4SLinus Torvalds 	}
5691da177e4SLinus Torvalds 
5701da177e4SLinus Torvalds done:
5711da177e4SLinus Torvalds 	hci_req_unlock(hdev);
5721da177e4SLinus Torvalds 	hci_dev_put(hdev);
5731da177e4SLinus Torvalds 	return ret;
5741da177e4SLinus Torvalds }
5751da177e4SLinus Torvalds 
5761da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
5771da177e4SLinus Torvalds {
5781da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
5791da177e4SLinus Torvalds 
5801da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
5811da177e4SLinus Torvalds 	hci_req_lock(hdev);
5821da177e4SLinus Torvalds 
5831da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
584b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
5851da177e4SLinus Torvalds 		hci_req_unlock(hdev);
5861da177e4SLinus Torvalds 		return 0;
5871da177e4SLinus Torvalds 	}
5881da177e4SLinus Torvalds 
5893eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
5903eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
591b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
5921da177e4SLinus Torvalds 
59316ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
594e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
59516ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
59616ab91abSJohan Hedberg 	}
59716ab91abSJohan Hedberg 
5983243553fSJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags))
599e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
6003243553fSJohan Hedberg 
6017d78525dSJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->flags))
6027d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
6037d78525dSJohan Hedberg 
60409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
6051da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
6061da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
60709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
6081da177e4SLinus Torvalds 
6091da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
6101da177e4SLinus Torvalds 
6111da177e4SLinus Torvalds 	if (hdev->flush)
6121da177e4SLinus Torvalds 		hdev->flush(hdev);
6131da177e4SLinus Torvalds 
6141da177e4SLinus Torvalds 	/* Reset device */
6151da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
6161da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
6171da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
6181da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
61904837f64SMarcel Holtmann 		__hci_request(hdev, hci_reset_req, 0,
62043611a7bSSzymon Janc 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
6211da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
6221da177e4SLinus Torvalds 	}
6231da177e4SLinus Torvalds 
624c347b765SGustavo F. Padovan 	/* flush cmd  work */
625c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
6261da177e4SLinus Torvalds 
6271da177e4SLinus Torvalds 	/* Drop queues */
6281da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
6291da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
6301da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
6311da177e4SLinus Torvalds 
6321da177e4SLinus Torvalds 	/* Drop last sent command */
6331da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
634b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
6351da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
6361da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
6371da177e4SLinus Torvalds 	}
6381da177e4SLinus Torvalds 
6391da177e4SLinus Torvalds 	/* After this point our queues are empty
6401da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
6411da177e4SLinus Torvalds 	hdev->close(hdev);
6421da177e4SLinus Torvalds 
64309fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
644744cf19eSJohan Hedberg 	mgmt_powered(hdev, 0);
64509fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
6465add6af8SJohan Hedberg 
6471da177e4SLinus Torvalds 	/* Clear flags */
6481da177e4SLinus Torvalds 	hdev->flags = 0;
6491da177e4SLinus Torvalds 
6501da177e4SLinus Torvalds 	hci_req_unlock(hdev);
6511da177e4SLinus Torvalds 
6521da177e4SLinus Torvalds 	hci_dev_put(hdev);
6531da177e4SLinus Torvalds 	return 0;
6541da177e4SLinus Torvalds }
6551da177e4SLinus Torvalds 
6561da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
6571da177e4SLinus Torvalds {
6581da177e4SLinus Torvalds 	struct hci_dev *hdev;
6591da177e4SLinus Torvalds 	int err;
6601da177e4SLinus Torvalds 
66170f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
66270f23020SAndrei Emeltchenko 	if (!hdev)
6631da177e4SLinus Torvalds 		return -ENODEV;
6641da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
6651da177e4SLinus Torvalds 	hci_dev_put(hdev);
6661da177e4SLinus Torvalds 	return err;
6671da177e4SLinus Torvalds }
6681da177e4SLinus Torvalds 
6691da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
6701da177e4SLinus Torvalds {
6711da177e4SLinus Torvalds 	struct hci_dev *hdev;
6721da177e4SLinus Torvalds 	int ret = 0;
6731da177e4SLinus Torvalds 
67470f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
67570f23020SAndrei Emeltchenko 	if (!hdev)
6761da177e4SLinus Torvalds 		return -ENODEV;
6771da177e4SLinus Torvalds 
6781da177e4SLinus Torvalds 	hci_req_lock(hdev);
6791da177e4SLinus Torvalds 
6801da177e4SLinus Torvalds 	if (!test_bit(HCI_UP, &hdev->flags))
6811da177e4SLinus Torvalds 		goto done;
6821da177e4SLinus Torvalds 
6831da177e4SLinus Torvalds 	/* Drop queues */
6841da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
6851da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
6861da177e4SLinus Torvalds 
68709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
6881da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
6891da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
69009fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
6911da177e4SLinus Torvalds 
6921da177e4SLinus Torvalds 	if (hdev->flush)
6931da177e4SLinus Torvalds 		hdev->flush(hdev);
6941da177e4SLinus Torvalds 
6951da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
6966ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
6971da177e4SLinus Torvalds 
6981da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags))
69904837f64SMarcel Holtmann 		ret = __hci_request(hdev, hci_reset_req, 0,
70004837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
7011da177e4SLinus Torvalds 
7021da177e4SLinus Torvalds done:
7031da177e4SLinus Torvalds 	hci_req_unlock(hdev);
7041da177e4SLinus Torvalds 	hci_dev_put(hdev);
7051da177e4SLinus Torvalds 	return ret;
7061da177e4SLinus Torvalds }
7071da177e4SLinus Torvalds 
7081da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
7091da177e4SLinus Torvalds {
7101da177e4SLinus Torvalds 	struct hci_dev *hdev;
7111da177e4SLinus Torvalds 	int ret = 0;
7121da177e4SLinus Torvalds 
71370f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
71470f23020SAndrei Emeltchenko 	if (!hdev)
7151da177e4SLinus Torvalds 		return -ENODEV;
7161da177e4SLinus Torvalds 
7171da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
7181da177e4SLinus Torvalds 
7191da177e4SLinus Torvalds 	hci_dev_put(hdev);
7201da177e4SLinus Torvalds 
7211da177e4SLinus Torvalds 	return ret;
7221da177e4SLinus Torvalds }
7231da177e4SLinus Torvalds 
7241da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
7251da177e4SLinus Torvalds {
7261da177e4SLinus Torvalds 	struct hci_dev *hdev;
7271da177e4SLinus Torvalds 	struct hci_dev_req dr;
7281da177e4SLinus Torvalds 	int err = 0;
7291da177e4SLinus Torvalds 
7301da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
7311da177e4SLinus Torvalds 		return -EFAULT;
7321da177e4SLinus Torvalds 
73370f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
73470f23020SAndrei Emeltchenko 	if (!hdev)
7351da177e4SLinus Torvalds 		return -ENODEV;
7361da177e4SLinus Torvalds 
7371da177e4SLinus Torvalds 	switch (cmd) {
7381da177e4SLinus Torvalds 	case HCISETAUTH:
73904837f64SMarcel Holtmann 		err = hci_request(hdev, hci_auth_req, dr.dev_opt,
74004837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
7411da177e4SLinus Torvalds 		break;
7421da177e4SLinus Torvalds 
7431da177e4SLinus Torvalds 	case HCISETENCRYPT:
7441da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
7451da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
7461da177e4SLinus Torvalds 			break;
7471da177e4SLinus Torvalds 		}
7481da177e4SLinus Torvalds 
7491da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
7501da177e4SLinus Torvalds 			/* Auth must be enabled first */
75104837f64SMarcel Holtmann 			err = hci_request(hdev, hci_auth_req, dr.dev_opt,
75204837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
7531da177e4SLinus Torvalds 			if (err)
7541da177e4SLinus Torvalds 				break;
7551da177e4SLinus Torvalds 		}
7561da177e4SLinus Torvalds 
75704837f64SMarcel Holtmann 		err = hci_request(hdev, hci_encrypt_req, dr.dev_opt,
75804837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
7591da177e4SLinus Torvalds 		break;
7601da177e4SLinus Torvalds 
7611da177e4SLinus Torvalds 	case HCISETSCAN:
76204837f64SMarcel Holtmann 		err = hci_request(hdev, hci_scan_req, dr.dev_opt,
76304837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
7641da177e4SLinus Torvalds 		break;
7651da177e4SLinus Torvalds 
7661da177e4SLinus Torvalds 	case HCISETLINKPOL:
767e4e8e37cSMarcel Holtmann 		err = hci_request(hdev, hci_linkpol_req, dr.dev_opt,
768e4e8e37cSMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
7691da177e4SLinus Torvalds 		break;
7701da177e4SLinus Torvalds 
7711da177e4SLinus Torvalds 	case HCISETLINKMODE:
772e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
773e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
774e4e8e37cSMarcel Holtmann 		break;
775e4e8e37cSMarcel Holtmann 
776e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
777e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
7781da177e4SLinus Torvalds 		break;
7791da177e4SLinus Torvalds 
7801da177e4SLinus Torvalds 	case HCISETACLMTU:
7811da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
7821da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
7831da177e4SLinus Torvalds 		break;
7841da177e4SLinus Torvalds 
7851da177e4SLinus Torvalds 	case HCISETSCOMTU:
7861da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
7871da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
7881da177e4SLinus Torvalds 		break;
7891da177e4SLinus Torvalds 
7901da177e4SLinus Torvalds 	default:
7911da177e4SLinus Torvalds 		err = -EINVAL;
7921da177e4SLinus Torvalds 		break;
7931da177e4SLinus Torvalds 	}
794e4e8e37cSMarcel Holtmann 
7951da177e4SLinus Torvalds 	hci_dev_put(hdev);
7961da177e4SLinus Torvalds 	return err;
7971da177e4SLinus Torvalds }
7981da177e4SLinus Torvalds 
7991da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
8001da177e4SLinus Torvalds {
8018035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
8021da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
8031da177e4SLinus Torvalds 	struct hci_dev_req *dr;
8041da177e4SLinus Torvalds 	int n = 0, size, err;
8051da177e4SLinus Torvalds 	__u16 dev_num;
8061da177e4SLinus Torvalds 
8071da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
8081da177e4SLinus Torvalds 		return -EFAULT;
8091da177e4SLinus Torvalds 
8101da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
8111da177e4SLinus Torvalds 		return -EINVAL;
8121da177e4SLinus Torvalds 
8131da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
8141da177e4SLinus Torvalds 
81570f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
81670f23020SAndrei Emeltchenko 	if (!dl)
8171da177e4SLinus Torvalds 		return -ENOMEM;
8181da177e4SLinus Torvalds 
8191da177e4SLinus Torvalds 	dr = dl->dev_req;
8201da177e4SLinus Torvalds 
8211da177e4SLinus Torvalds 	read_lock_bh(&hci_dev_list_lock);
8228035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
8233243553fSJohan Hedberg 		if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags))
824e0f9309fSJohan Hedberg 			cancel_delayed_work(&hdev->power_off);
825c542a06cSJohan Hedberg 
826c542a06cSJohan Hedberg 		if (!test_bit(HCI_MGMT, &hdev->flags))
827c542a06cSJohan Hedberg 			set_bit(HCI_PAIRABLE, &hdev->flags);
828c542a06cSJohan Hedberg 
8291da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
8301da177e4SLinus Torvalds 		(dr + n)->dev_opt = hdev->flags;
831c542a06cSJohan Hedberg 
8321da177e4SLinus Torvalds 		if (++n >= dev_num)
8331da177e4SLinus Torvalds 			break;
8341da177e4SLinus Torvalds 	}
8351da177e4SLinus Torvalds 	read_unlock_bh(&hci_dev_list_lock);
8361da177e4SLinus Torvalds 
8371da177e4SLinus Torvalds 	dl->dev_num = n;
8381da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
8391da177e4SLinus Torvalds 
8401da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
8411da177e4SLinus Torvalds 	kfree(dl);
8421da177e4SLinus Torvalds 
8431da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
8441da177e4SLinus Torvalds }
8451da177e4SLinus Torvalds 
8461da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
8471da177e4SLinus Torvalds {
8481da177e4SLinus Torvalds 	struct hci_dev *hdev;
8491da177e4SLinus Torvalds 	struct hci_dev_info di;
8501da177e4SLinus Torvalds 	int err = 0;
8511da177e4SLinus Torvalds 
8521da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
8531da177e4SLinus Torvalds 		return -EFAULT;
8541da177e4SLinus Torvalds 
85570f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
85670f23020SAndrei Emeltchenko 	if (!hdev)
8571da177e4SLinus Torvalds 		return -ENODEV;
8581da177e4SLinus Torvalds 
8593243553fSJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags))
8603243553fSJohan Hedberg 		cancel_delayed_work_sync(&hdev->power_off);
861ab81cbf9SJohan Hedberg 
862c542a06cSJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->flags))
863c542a06cSJohan Hedberg 		set_bit(HCI_PAIRABLE, &hdev->flags);
864c542a06cSJohan Hedberg 
8651da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
8661da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
867943da25dSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | (hdev->dev_type << 4);
8681da177e4SLinus Torvalds 	di.flags    = hdev->flags;
8691da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
8701da177e4SLinus Torvalds 	di.acl_mtu  = hdev->acl_mtu;
8711da177e4SLinus Torvalds 	di.acl_pkts = hdev->acl_pkts;
8721da177e4SLinus Torvalds 	di.sco_mtu  = hdev->sco_mtu;
8731da177e4SLinus Torvalds 	di.sco_pkts = hdev->sco_pkts;
8741da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
8751da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
8761da177e4SLinus Torvalds 
8771da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
8781da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
8791da177e4SLinus Torvalds 
8801da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
8811da177e4SLinus Torvalds 		err = -EFAULT;
8821da177e4SLinus Torvalds 
8831da177e4SLinus Torvalds 	hci_dev_put(hdev);
8841da177e4SLinus Torvalds 
8851da177e4SLinus Torvalds 	return err;
8861da177e4SLinus Torvalds }
8871da177e4SLinus Torvalds 
8881da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
8891da177e4SLinus Torvalds 
890611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
891611b30f7SMarcel Holtmann {
892611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
893611b30f7SMarcel Holtmann 
894611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
895611b30f7SMarcel Holtmann 
896611b30f7SMarcel Holtmann 	if (!blocked)
897611b30f7SMarcel Holtmann 		return 0;
898611b30f7SMarcel Holtmann 
899611b30f7SMarcel Holtmann 	hci_dev_do_close(hdev);
900611b30f7SMarcel Holtmann 
901611b30f7SMarcel Holtmann 	return 0;
902611b30f7SMarcel Holtmann }
903611b30f7SMarcel Holtmann 
904611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
905611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
906611b30f7SMarcel Holtmann };
907611b30f7SMarcel Holtmann 
9081da177e4SLinus Torvalds /* Alloc HCI device */
9091da177e4SLinus Torvalds struct hci_dev *hci_alloc_dev(void)
9101da177e4SLinus Torvalds {
9111da177e4SLinus Torvalds 	struct hci_dev *hdev;
9121da177e4SLinus Torvalds 
91325ea6db0SMarcel Holtmann 	hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
9141da177e4SLinus Torvalds 	if (!hdev)
9151da177e4SLinus Torvalds 		return NULL;
9161da177e4SLinus Torvalds 
9170ac7e700SDavid Herrmann 	hci_init_sysfs(hdev);
9181da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->driver_init);
9191da177e4SLinus Torvalds 
9201da177e4SLinus Torvalds 	return hdev;
9211da177e4SLinus Torvalds }
9221da177e4SLinus Torvalds EXPORT_SYMBOL(hci_alloc_dev);
9231da177e4SLinus Torvalds 
9241da177e4SLinus Torvalds /* Free HCI device */
9251da177e4SLinus Torvalds void hci_free_dev(struct hci_dev *hdev)
9261da177e4SLinus Torvalds {
9271da177e4SLinus Torvalds 	skb_queue_purge(&hdev->driver_init);
9281da177e4SLinus Torvalds 
929a91f2e39SMarcel Holtmann 	/* will free via device release */
930a91f2e39SMarcel Holtmann 	put_device(&hdev->dev);
9311da177e4SLinus Torvalds }
9321da177e4SLinus Torvalds EXPORT_SYMBOL(hci_free_dev);
9331da177e4SLinus Torvalds 
934ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
935ab81cbf9SJohan Hedberg {
936ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
937ab81cbf9SJohan Hedberg 
938ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
939ab81cbf9SJohan Hedberg 
940ab81cbf9SJohan Hedberg 	if (hci_dev_open(hdev->id) < 0)
941ab81cbf9SJohan Hedberg 		return;
942ab81cbf9SJohan Hedberg 
943ab81cbf9SJohan Hedberg 	if (test_bit(HCI_AUTO_OFF, &hdev->flags))
94480b7ab33SGustavo F. Padovan 		schedule_delayed_work(&hdev->power_off,
9453243553fSJohan Hedberg 					msecs_to_jiffies(AUTO_OFF_TIMEOUT));
946ab81cbf9SJohan Hedberg 
947ab81cbf9SJohan Hedberg 	if (test_and_clear_bit(HCI_SETUP, &hdev->flags))
948744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
949ab81cbf9SJohan Hedberg }
950ab81cbf9SJohan Hedberg 
951ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
952ab81cbf9SJohan Hedberg {
9533243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
9543243553fSJohan Hedberg 							power_off.work);
955ab81cbf9SJohan Hedberg 
956ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
957ab81cbf9SJohan Hedberg 
9583243553fSJohan Hedberg 	clear_bit(HCI_AUTO_OFF, &hdev->flags);
9593243553fSJohan Hedberg 
960ab81cbf9SJohan Hedberg 	hci_dev_close(hdev->id);
961ab81cbf9SJohan Hedberg }
962ab81cbf9SJohan Hedberg 
96316ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
96416ab91abSJohan Hedberg {
96516ab91abSJohan Hedberg 	struct hci_dev *hdev;
96616ab91abSJohan Hedberg 	u8 scan = SCAN_PAGE;
96716ab91abSJohan Hedberg 
96816ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
96916ab91abSJohan Hedberg 
97016ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
97116ab91abSJohan Hedberg 
97209fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
97316ab91abSJohan Hedberg 
97416ab91abSJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan);
97516ab91abSJohan Hedberg 
97616ab91abSJohan Hedberg 	hdev->discov_timeout = 0;
97716ab91abSJohan Hedberg 
97809fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
97916ab91abSJohan Hedberg }
98016ab91abSJohan Hedberg 
9812aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev)
9822aeb9a1aSJohan Hedberg {
9832aeb9a1aSJohan Hedberg 	struct list_head *p, *n;
9842aeb9a1aSJohan Hedberg 
9852aeb9a1aSJohan Hedberg 	list_for_each_safe(p, n, &hdev->uuids) {
9862aeb9a1aSJohan Hedberg 		struct bt_uuid *uuid;
9872aeb9a1aSJohan Hedberg 
9882aeb9a1aSJohan Hedberg 		uuid = list_entry(p, struct bt_uuid, list);
9892aeb9a1aSJohan Hedberg 
9902aeb9a1aSJohan Hedberg 		list_del(p);
9912aeb9a1aSJohan Hedberg 		kfree(uuid);
9922aeb9a1aSJohan Hedberg 	}
9932aeb9a1aSJohan Hedberg 
9942aeb9a1aSJohan Hedberg 	return 0;
9952aeb9a1aSJohan Hedberg }
9962aeb9a1aSJohan Hedberg 
99755ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev)
99855ed8ca1SJohan Hedberg {
99955ed8ca1SJohan Hedberg 	struct list_head *p, *n;
100055ed8ca1SJohan Hedberg 
100155ed8ca1SJohan Hedberg 	list_for_each_safe(p, n, &hdev->link_keys) {
100255ed8ca1SJohan Hedberg 		struct link_key *key;
100355ed8ca1SJohan Hedberg 
100455ed8ca1SJohan Hedberg 		key = list_entry(p, struct link_key, list);
100555ed8ca1SJohan Hedberg 
100655ed8ca1SJohan Hedberg 		list_del(p);
100755ed8ca1SJohan Hedberg 		kfree(key);
100855ed8ca1SJohan Hedberg 	}
100955ed8ca1SJohan Hedberg 
101055ed8ca1SJohan Hedberg 	return 0;
101155ed8ca1SJohan Hedberg }
101255ed8ca1SJohan Hedberg 
101355ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
101455ed8ca1SJohan Hedberg {
101555ed8ca1SJohan Hedberg 	struct link_key *k;
101655ed8ca1SJohan Hedberg 
10178035ded4SLuiz Augusto von Dentz 	list_for_each_entry(k, &hdev->link_keys, list)
101855ed8ca1SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0)
101955ed8ca1SJohan Hedberg 			return k;
102055ed8ca1SJohan Hedberg 
102155ed8ca1SJohan Hedberg 	return NULL;
102255ed8ca1SJohan Hedberg }
102355ed8ca1SJohan Hedberg 
1024d25e28abSJohan Hedberg static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1025d25e28abSJohan Hedberg 						u8 key_type, u8 old_key_type)
1026d25e28abSJohan Hedberg {
1027d25e28abSJohan Hedberg 	/* Legacy key */
1028d25e28abSJohan Hedberg 	if (key_type < 0x03)
1029d25e28abSJohan Hedberg 		return 1;
1030d25e28abSJohan Hedberg 
1031d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
1032d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
1033d25e28abSJohan Hedberg 		return 0;
1034d25e28abSJohan Hedberg 
1035d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
1036d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
1037d25e28abSJohan Hedberg 		return 0;
1038d25e28abSJohan Hedberg 
1039d25e28abSJohan Hedberg 	/* Security mode 3 case */
1040d25e28abSJohan Hedberg 	if (!conn)
1041d25e28abSJohan Hedberg 		return 1;
1042d25e28abSJohan Hedberg 
1043d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
1044d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
1045d25e28abSJohan Hedberg 		return 1;
1046d25e28abSJohan Hedberg 
1047d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
1048d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
1049d25e28abSJohan Hedberg 		return 1;
1050d25e28abSJohan Hedberg 
1051d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
1052d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
1053d25e28abSJohan Hedberg 		return 1;
1054d25e28abSJohan Hedberg 
1055d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
1056d25e28abSJohan Hedberg 	 * persistently */
1057d25e28abSJohan Hedberg 	return 0;
1058d25e28abSJohan Hedberg }
1059d25e28abSJohan Hedberg 
106075d262c2SVinicius Costa Gomes struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
106175d262c2SVinicius Costa Gomes {
106275d262c2SVinicius Costa Gomes 	struct link_key *k;
106375d262c2SVinicius Costa Gomes 
106475d262c2SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->link_keys, list) {
106575d262c2SVinicius Costa Gomes 		struct key_master_id *id;
106675d262c2SVinicius Costa Gomes 
106775d262c2SVinicius Costa Gomes 		if (k->type != HCI_LK_SMP_LTK)
106875d262c2SVinicius Costa Gomes 			continue;
106975d262c2SVinicius Costa Gomes 
107075d262c2SVinicius Costa Gomes 		if (k->dlen != sizeof(*id))
107175d262c2SVinicius Costa Gomes 			continue;
107275d262c2SVinicius Costa Gomes 
107375d262c2SVinicius Costa Gomes 		id = (void *) &k->data;
107475d262c2SVinicius Costa Gomes 		if (id->ediv == ediv &&
107575d262c2SVinicius Costa Gomes 				(memcmp(rand, id->rand, sizeof(id->rand)) == 0))
107675d262c2SVinicius Costa Gomes 			return k;
107775d262c2SVinicius Costa Gomes 	}
107875d262c2SVinicius Costa Gomes 
107975d262c2SVinicius Costa Gomes 	return NULL;
108075d262c2SVinicius Costa Gomes }
108175d262c2SVinicius Costa Gomes EXPORT_SYMBOL(hci_find_ltk);
108275d262c2SVinicius Costa Gomes 
108375d262c2SVinicius Costa Gomes struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
108475d262c2SVinicius Costa Gomes 					bdaddr_t *bdaddr, u8 type)
108575d262c2SVinicius Costa Gomes {
108675d262c2SVinicius Costa Gomes 	struct link_key *k;
108775d262c2SVinicius Costa Gomes 
108875d262c2SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->link_keys, list)
108975d262c2SVinicius Costa Gomes 		if (k->type == type && bacmp(bdaddr, &k->bdaddr) == 0)
109075d262c2SVinicius Costa Gomes 			return k;
109175d262c2SVinicius Costa Gomes 
109275d262c2SVinicius Costa Gomes 	return NULL;
109375d262c2SVinicius Costa Gomes }
109475d262c2SVinicius Costa Gomes EXPORT_SYMBOL(hci_find_link_key_type);
109575d262c2SVinicius Costa Gomes 
1096d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
1097d25e28abSJohan Hedberg 				bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
109855ed8ca1SJohan Hedberg {
109955ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
11004df378a1SJohan Hedberg 	u8 old_key_type, persistent;
110155ed8ca1SJohan Hedberg 
110255ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
110355ed8ca1SJohan Hedberg 	if (old_key) {
110455ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
110555ed8ca1SJohan Hedberg 		key = old_key;
110655ed8ca1SJohan Hedberg 	} else {
110712adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
110855ed8ca1SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
110955ed8ca1SJohan Hedberg 		if (!key)
111055ed8ca1SJohan Hedberg 			return -ENOMEM;
111155ed8ca1SJohan Hedberg 		list_add(&key->list, &hdev->link_keys);
111255ed8ca1SJohan Hedberg 	}
111355ed8ca1SJohan Hedberg 
111455ed8ca1SJohan Hedberg 	BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type);
111555ed8ca1SJohan Hedberg 
1116d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
1117d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
1118d25e28abSJohan Hedberg 	 * previous key */
1119d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
1120d25e28abSJohan Hedberg 					(!conn || conn->remote_auth == 0xff) &&
1121655fe6ecSJohan Hedberg 					old_key_type == 0xff) {
1122d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
1123655fe6ecSJohan Hedberg 		if (conn)
1124655fe6ecSJohan Hedberg 			conn->key_type = type;
1125655fe6ecSJohan Hedberg 	}
1126d25e28abSJohan Hedberg 
112755ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
112855ed8ca1SJohan Hedberg 	memcpy(key->val, val, 16);
112955ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
113055ed8ca1SJohan Hedberg 
1131b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
113255ed8ca1SJohan Hedberg 		key->type = old_key_type;
11334748fed2SJohan Hedberg 	else
11344748fed2SJohan Hedberg 		key->type = type;
11354748fed2SJohan Hedberg 
11364df378a1SJohan Hedberg 	if (!new_key)
11374df378a1SJohan Hedberg 		return 0;
11384df378a1SJohan Hedberg 
11394df378a1SJohan Hedberg 	persistent = hci_persistent_key(hdev, conn, type, old_key_type);
11404df378a1SJohan Hedberg 
1141744cf19eSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
11424df378a1SJohan Hedberg 
11434df378a1SJohan Hedberg 	if (!persistent) {
11444df378a1SJohan Hedberg 		list_del(&key->list);
11454df378a1SJohan Hedberg 		kfree(key);
11464df378a1SJohan Hedberg 	}
114755ed8ca1SJohan Hedberg 
114855ed8ca1SJohan Hedberg 	return 0;
114955ed8ca1SJohan Hedberg }
115055ed8ca1SJohan Hedberg 
115175d262c2SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
1152726b4ffcSVinicius Costa Gomes 			u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16])
115375d262c2SVinicius Costa Gomes {
115475d262c2SVinicius Costa Gomes 	struct link_key *key, *old_key;
115575d262c2SVinicius Costa Gomes 	struct key_master_id *id;
115675d262c2SVinicius Costa Gomes 	u8 old_key_type;
115775d262c2SVinicius Costa Gomes 
115875d262c2SVinicius Costa Gomes 	BT_DBG("%s addr %s", hdev->name, batostr(bdaddr));
115975d262c2SVinicius Costa Gomes 
116075d262c2SVinicius Costa Gomes 	old_key = hci_find_link_key_type(hdev, bdaddr, HCI_LK_SMP_LTK);
116175d262c2SVinicius Costa Gomes 	if (old_key) {
116275d262c2SVinicius Costa Gomes 		key = old_key;
116375d262c2SVinicius Costa Gomes 		old_key_type = old_key->type;
116475d262c2SVinicius Costa Gomes 	} else {
116575d262c2SVinicius Costa Gomes 		key = kzalloc(sizeof(*key) + sizeof(*id), GFP_ATOMIC);
116675d262c2SVinicius Costa Gomes 		if (!key)
116775d262c2SVinicius Costa Gomes 			return -ENOMEM;
116875d262c2SVinicius Costa Gomes 		list_add(&key->list, &hdev->link_keys);
116975d262c2SVinicius Costa Gomes 		old_key_type = 0xff;
117075d262c2SVinicius Costa Gomes 	}
117175d262c2SVinicius Costa Gomes 
117275d262c2SVinicius Costa Gomes 	key->dlen = sizeof(*id);
117375d262c2SVinicius Costa Gomes 
117475d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
117575d262c2SVinicius Costa Gomes 	memcpy(key->val, ltk, sizeof(key->val));
117675d262c2SVinicius Costa Gomes 	key->type = HCI_LK_SMP_LTK;
1177726b4ffcSVinicius Costa Gomes 	key->pin_len = key_size;
117875d262c2SVinicius Costa Gomes 
117975d262c2SVinicius Costa Gomes 	id = (void *) &key->data;
118075d262c2SVinicius Costa Gomes 	id->ediv = ediv;
118175d262c2SVinicius Costa Gomes 	memcpy(id->rand, rand, sizeof(id->rand));
118275d262c2SVinicius Costa Gomes 
118375d262c2SVinicius Costa Gomes 	if (new_key)
1184744cf19eSJohan Hedberg 		mgmt_new_link_key(hdev, key, old_key_type);
118575d262c2SVinicius Costa Gomes 
118675d262c2SVinicius Costa Gomes 	return 0;
118775d262c2SVinicius Costa Gomes }
118875d262c2SVinicius Costa Gomes 
118955ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
119055ed8ca1SJohan Hedberg {
119155ed8ca1SJohan Hedberg 	struct link_key *key;
119255ed8ca1SJohan Hedberg 
119355ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
119455ed8ca1SJohan Hedberg 	if (!key)
119555ed8ca1SJohan Hedberg 		return -ENOENT;
119655ed8ca1SJohan Hedberg 
119755ed8ca1SJohan Hedberg 	BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
119855ed8ca1SJohan Hedberg 
119955ed8ca1SJohan Hedberg 	list_del(&key->list);
120055ed8ca1SJohan Hedberg 	kfree(key);
120155ed8ca1SJohan Hedberg 
120255ed8ca1SJohan Hedberg 	return 0;
120355ed8ca1SJohan Hedberg }
120455ed8ca1SJohan Hedberg 
12056bd32326SVille Tervo /* HCI command timer function */
12066bd32326SVille Tervo static void hci_cmd_timer(unsigned long arg)
12076bd32326SVille Tervo {
12086bd32326SVille Tervo 	struct hci_dev *hdev = (void *) arg;
12096bd32326SVille Tervo 
12106bd32326SVille Tervo 	BT_ERR("%s command tx timeout", hdev->name);
12116bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
1212c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
12136bd32326SVille Tervo }
12146bd32326SVille Tervo 
12152763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
12162763eda6SSzymon Janc 							bdaddr_t *bdaddr)
12172763eda6SSzymon Janc {
12182763eda6SSzymon Janc 	struct oob_data *data;
12192763eda6SSzymon Janc 
12202763eda6SSzymon Janc 	list_for_each_entry(data, &hdev->remote_oob_data, list)
12212763eda6SSzymon Janc 		if (bacmp(bdaddr, &data->bdaddr) == 0)
12222763eda6SSzymon Janc 			return data;
12232763eda6SSzymon Janc 
12242763eda6SSzymon Janc 	return NULL;
12252763eda6SSzymon Janc }
12262763eda6SSzymon Janc 
12272763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
12282763eda6SSzymon Janc {
12292763eda6SSzymon Janc 	struct oob_data *data;
12302763eda6SSzymon Janc 
12312763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
12322763eda6SSzymon Janc 	if (!data)
12332763eda6SSzymon Janc 		return -ENOENT;
12342763eda6SSzymon Janc 
12352763eda6SSzymon Janc 	BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
12362763eda6SSzymon Janc 
12372763eda6SSzymon Janc 	list_del(&data->list);
12382763eda6SSzymon Janc 	kfree(data);
12392763eda6SSzymon Janc 
12402763eda6SSzymon Janc 	return 0;
12412763eda6SSzymon Janc }
12422763eda6SSzymon Janc 
12432763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev)
12442763eda6SSzymon Janc {
12452763eda6SSzymon Janc 	struct oob_data *data, *n;
12462763eda6SSzymon Janc 
12472763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
12482763eda6SSzymon Janc 		list_del(&data->list);
12492763eda6SSzymon Janc 		kfree(data);
12502763eda6SSzymon Janc 	}
12512763eda6SSzymon Janc 
12522763eda6SSzymon Janc 	return 0;
12532763eda6SSzymon Janc }
12542763eda6SSzymon Janc 
12552763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
12562763eda6SSzymon Janc 								u8 *randomizer)
12572763eda6SSzymon Janc {
12582763eda6SSzymon Janc 	struct oob_data *data;
12592763eda6SSzymon Janc 
12602763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
12612763eda6SSzymon Janc 
12622763eda6SSzymon Janc 	if (!data) {
12632763eda6SSzymon Janc 		data = kmalloc(sizeof(*data), GFP_ATOMIC);
12642763eda6SSzymon Janc 		if (!data)
12652763eda6SSzymon Janc 			return -ENOMEM;
12662763eda6SSzymon Janc 
12672763eda6SSzymon Janc 		bacpy(&data->bdaddr, bdaddr);
12682763eda6SSzymon Janc 		list_add(&data->list, &hdev->remote_oob_data);
12692763eda6SSzymon Janc 	}
12702763eda6SSzymon Janc 
12712763eda6SSzymon Janc 	memcpy(data->hash, hash, sizeof(data->hash));
12722763eda6SSzymon Janc 	memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
12732763eda6SSzymon Janc 
12742763eda6SSzymon Janc 	BT_DBG("%s for %s", hdev->name, batostr(bdaddr));
12752763eda6SSzymon Janc 
12762763eda6SSzymon Janc 	return 0;
12772763eda6SSzymon Janc }
12782763eda6SSzymon Janc 
1279b2a66aadSAntti Julku struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev,
1280b2a66aadSAntti Julku 						bdaddr_t *bdaddr)
1281b2a66aadSAntti Julku {
1282b2a66aadSAntti Julku 	struct bdaddr_list *b;
1283b2a66aadSAntti Julku 
12848035ded4SLuiz Augusto von Dentz 	list_for_each_entry(b, &hdev->blacklist, list)
1285b2a66aadSAntti Julku 		if (bacmp(bdaddr, &b->bdaddr) == 0)
1286b2a66aadSAntti Julku 			return b;
1287b2a66aadSAntti Julku 
1288b2a66aadSAntti Julku 	return NULL;
1289b2a66aadSAntti Julku }
1290b2a66aadSAntti Julku 
1291b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev)
1292b2a66aadSAntti Julku {
1293b2a66aadSAntti Julku 	struct list_head *p, *n;
1294b2a66aadSAntti Julku 
1295b2a66aadSAntti Julku 	list_for_each_safe(p, n, &hdev->blacklist) {
1296b2a66aadSAntti Julku 		struct bdaddr_list *b;
1297b2a66aadSAntti Julku 
1298b2a66aadSAntti Julku 		b = list_entry(p, struct bdaddr_list, list);
1299b2a66aadSAntti Julku 
1300b2a66aadSAntti Julku 		list_del(p);
1301b2a66aadSAntti Julku 		kfree(b);
1302b2a66aadSAntti Julku 	}
1303b2a66aadSAntti Julku 
1304b2a66aadSAntti Julku 	return 0;
1305b2a66aadSAntti Julku }
1306b2a66aadSAntti Julku 
1307b2a66aadSAntti Julku int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr)
1308b2a66aadSAntti Julku {
1309b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1310b2a66aadSAntti Julku 
1311b2a66aadSAntti Julku 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
1312b2a66aadSAntti Julku 		return -EBADF;
1313b2a66aadSAntti Julku 
13145e762444SAntti Julku 	if (hci_blacklist_lookup(hdev, bdaddr))
13155e762444SAntti Julku 		return -EEXIST;
1316b2a66aadSAntti Julku 
1317b2a66aadSAntti Julku 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
13185e762444SAntti Julku 	if (!entry)
13195e762444SAntti Julku 		return -ENOMEM;
1320b2a66aadSAntti Julku 
1321b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
1322b2a66aadSAntti Julku 
1323b2a66aadSAntti Julku 	list_add(&entry->list, &hdev->blacklist);
1324b2a66aadSAntti Julku 
1325744cf19eSJohan Hedberg 	return mgmt_device_blocked(hdev, bdaddr);
1326b2a66aadSAntti Julku }
1327b2a66aadSAntti Julku 
1328b2a66aadSAntti Julku int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr)
1329b2a66aadSAntti Julku {
1330b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1331b2a66aadSAntti Julku 
13321ec918ceSSzymon Janc 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
13335e762444SAntti Julku 		return hci_blacklist_clear(hdev);
1334b2a66aadSAntti Julku 
1335b2a66aadSAntti Julku 	entry = hci_blacklist_lookup(hdev, bdaddr);
13361ec918ceSSzymon Janc 	if (!entry)
13375e762444SAntti Julku 		return -ENOENT;
1338b2a66aadSAntti Julku 
1339b2a66aadSAntti Julku 	list_del(&entry->list);
1340b2a66aadSAntti Julku 	kfree(entry);
1341b2a66aadSAntti Julku 
1342744cf19eSJohan Hedberg 	return mgmt_device_unblocked(hdev, bdaddr);
1343b2a66aadSAntti Julku }
1344b2a66aadSAntti Julku 
1345db323f2fSGustavo F. Padovan static void hci_clear_adv_cache(struct work_struct *work)
134635815085SAndre Guedes {
1347db323f2fSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev,
1348db323f2fSGustavo F. Padovan 							adv_work.work);
134935815085SAndre Guedes 
135035815085SAndre Guedes 	hci_dev_lock(hdev);
135135815085SAndre Guedes 
135235815085SAndre Guedes 	hci_adv_entries_clear(hdev);
135335815085SAndre Guedes 
135435815085SAndre Guedes 	hci_dev_unlock(hdev);
135535815085SAndre Guedes }
135635815085SAndre Guedes 
135776c8686fSAndre Guedes int hci_adv_entries_clear(struct hci_dev *hdev)
135876c8686fSAndre Guedes {
135976c8686fSAndre Guedes 	struct adv_entry *entry, *tmp;
136076c8686fSAndre Guedes 
136176c8686fSAndre Guedes 	list_for_each_entry_safe(entry, tmp, &hdev->adv_entries, list) {
136276c8686fSAndre Guedes 		list_del(&entry->list);
136376c8686fSAndre Guedes 		kfree(entry);
136476c8686fSAndre Guedes 	}
136576c8686fSAndre Guedes 
136676c8686fSAndre Guedes 	BT_DBG("%s adv cache cleared", hdev->name);
136776c8686fSAndre Guedes 
136876c8686fSAndre Guedes 	return 0;
136976c8686fSAndre Guedes }
137076c8686fSAndre Guedes 
137176c8686fSAndre Guedes struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr)
137276c8686fSAndre Guedes {
137376c8686fSAndre Guedes 	struct adv_entry *entry;
137476c8686fSAndre Guedes 
137576c8686fSAndre Guedes 	list_for_each_entry(entry, &hdev->adv_entries, list)
137676c8686fSAndre Guedes 		if (bacmp(bdaddr, &entry->bdaddr) == 0)
137776c8686fSAndre Guedes 			return entry;
137876c8686fSAndre Guedes 
137976c8686fSAndre Guedes 	return NULL;
138076c8686fSAndre Guedes }
138176c8686fSAndre Guedes 
138276c8686fSAndre Guedes static inline int is_connectable_adv(u8 evt_type)
138376c8686fSAndre Guedes {
138476c8686fSAndre Guedes 	if (evt_type == ADV_IND || evt_type == ADV_DIRECT_IND)
138576c8686fSAndre Guedes 		return 1;
138676c8686fSAndre Guedes 
138776c8686fSAndre Guedes 	return 0;
138876c8686fSAndre Guedes }
138976c8686fSAndre Guedes 
139076c8686fSAndre Guedes int hci_add_adv_entry(struct hci_dev *hdev,
139176c8686fSAndre Guedes 					struct hci_ev_le_advertising_info *ev)
139276c8686fSAndre Guedes {
139376c8686fSAndre Guedes 	struct adv_entry *entry;
139476c8686fSAndre Guedes 
139576c8686fSAndre Guedes 	if (!is_connectable_adv(ev->evt_type))
139676c8686fSAndre Guedes 		return -EINVAL;
139776c8686fSAndre Guedes 
139876c8686fSAndre Guedes 	/* Only new entries should be added to adv_entries. So, if
139976c8686fSAndre Guedes 	 * bdaddr was found, don't add it. */
140076c8686fSAndre Guedes 	if (hci_find_adv_entry(hdev, &ev->bdaddr))
140176c8686fSAndre Guedes 		return 0;
140276c8686fSAndre Guedes 
140376c8686fSAndre Guedes 	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
140476c8686fSAndre Guedes 	if (!entry)
140576c8686fSAndre Guedes 		return -ENOMEM;
140676c8686fSAndre Guedes 
140776c8686fSAndre Guedes 	bacpy(&entry->bdaddr, &ev->bdaddr);
140876c8686fSAndre Guedes 	entry->bdaddr_type = ev->bdaddr_type;
140976c8686fSAndre Guedes 
141076c8686fSAndre Guedes 	list_add(&entry->list, &hdev->adv_entries);
141176c8686fSAndre Guedes 
141276c8686fSAndre Guedes 	BT_DBG("%s adv entry added: address %s type %u", hdev->name,
141376c8686fSAndre Guedes 				batostr(&entry->bdaddr), entry->bdaddr_type);
141476c8686fSAndre Guedes 
141576c8686fSAndre Guedes 	return 0;
141676c8686fSAndre Guedes }
141776c8686fSAndre Guedes 
14181da177e4SLinus Torvalds /* Register HCI device */
14191da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
14201da177e4SLinus Torvalds {
14211da177e4SLinus Torvalds 	struct list_head *head = &hci_dev_list, *p;
142208add513SMat Martineau 	int i, id, error;
14231da177e4SLinus Torvalds 
1424c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d owner %p", hdev, hdev->name,
1425c13854ceSMarcel Holtmann 						hdev->bus, hdev->owner);
14261da177e4SLinus Torvalds 
14271da177e4SLinus Torvalds 	if (!hdev->open || !hdev->close || !hdev->destruct)
14281da177e4SLinus Torvalds 		return -EINVAL;
14291da177e4SLinus Torvalds 
143008add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
143108add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
143208add513SMat Martineau 	 */
143308add513SMat Martineau 	id = (hdev->dev_type == HCI_BREDR) ? 0 : 1;
143408add513SMat Martineau 
14351da177e4SLinus Torvalds 	write_lock_bh(&hci_dev_list_lock);
14361da177e4SLinus Torvalds 
14371da177e4SLinus Torvalds 	/* Find first available device id */
14381da177e4SLinus Torvalds 	list_for_each(p, &hci_dev_list) {
14391da177e4SLinus Torvalds 		if (list_entry(p, struct hci_dev, list)->id != id)
14401da177e4SLinus Torvalds 			break;
14411da177e4SLinus Torvalds 		head = p; id++;
14421da177e4SLinus Torvalds 	}
14431da177e4SLinus Torvalds 
14441da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
14451da177e4SLinus Torvalds 	hdev->id = id;
1446c6feeb28SAndrei Emeltchenko 	list_add_tail(&hdev->list, head);
14471da177e4SLinus Torvalds 
14481da177e4SLinus Torvalds 	atomic_set(&hdev->refcnt, 1);
144909fd0de5SGustavo F. Padovan 	mutex_init(&hdev->lock);
14501da177e4SLinus Torvalds 
14511da177e4SLinus Torvalds 	hdev->flags = 0;
1452d23264a8SAndre Guedes 	hdev->dev_flags = 0;
14531da177e4SLinus Torvalds 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
14545b7f9909SMarcel Holtmann 	hdev->esco_type = (ESCO_HV1);
14551da177e4SLinus Torvalds 	hdev->link_mode = (HCI_LM_ACCEPT);
145617fa4b9dSJohan Hedberg 	hdev->io_capability = 0x03; /* No Input No Output */
14571da177e4SLinus Torvalds 
145804837f64SMarcel Holtmann 	hdev->idle_timeout = 0;
145904837f64SMarcel Holtmann 	hdev->sniff_max_interval = 800;
146004837f64SMarcel Holtmann 	hdev->sniff_min_interval = 80;
146104837f64SMarcel Holtmann 
1462b78752ccSMarcel Holtmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
1463c347b765SGustavo F. Padovan 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
14643eff45eaSGustavo F. Padovan 	INIT_WORK(&hdev->tx_work, hci_tx_work);
1465b78752ccSMarcel Holtmann 
14661da177e4SLinus Torvalds 
14671da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->rx_q);
14681da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->cmd_q);
14691da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->raw_q);
14701da177e4SLinus Torvalds 
14716bd32326SVille Tervo 	setup_timer(&hdev->cmd_timer, hci_cmd_timer, (unsigned long) hdev);
14726bd32326SVille Tervo 
1473cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
1474ef222013SMarcel Holtmann 		hdev->reassembly[i] = NULL;
1475ef222013SMarcel Holtmann 
14761da177e4SLinus Torvalds 	init_waitqueue_head(&hdev->req_wait_q);
1477a6a67efdSThomas Gleixner 	mutex_init(&hdev->req_lock);
14781da177e4SLinus Torvalds 
14791da177e4SLinus Torvalds 	inquiry_cache_init(hdev);
14801da177e4SLinus Torvalds 
14811da177e4SLinus Torvalds 	hci_conn_hash_init(hdev);
14821da177e4SLinus Torvalds 
14832e58ef3eSJohan Hedberg 	INIT_LIST_HEAD(&hdev->mgmt_pending);
14842e58ef3eSJohan Hedberg 
1485ea4bd8baSDavid Miller 	INIT_LIST_HEAD(&hdev->blacklist);
1486f0358568SJohan Hedberg 
14872aeb9a1aSJohan Hedberg 	INIT_LIST_HEAD(&hdev->uuids);
14882aeb9a1aSJohan Hedberg 
148955ed8ca1SJohan Hedberg 	INIT_LIST_HEAD(&hdev->link_keys);
149055ed8ca1SJohan Hedberg 
14912763eda6SSzymon Janc 	INIT_LIST_HEAD(&hdev->remote_oob_data);
14922763eda6SSzymon Janc 
149376c8686fSAndre Guedes 	INIT_LIST_HEAD(&hdev->adv_entries);
149476c8686fSAndre Guedes 
1495db323f2fSGustavo F. Padovan 	INIT_DELAYED_WORK(&hdev->adv_work, hci_clear_adv_cache);
1496ab81cbf9SJohan Hedberg 	INIT_WORK(&hdev->power_on, hci_power_on);
14973243553fSJohan Hedberg 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
1498ab81cbf9SJohan Hedberg 
149916ab91abSJohan Hedberg 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
150016ab91abSJohan Hedberg 
15011da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
15021da177e4SLinus Torvalds 
15031da177e4SLinus Torvalds 	atomic_set(&hdev->promisc, 0);
15041da177e4SLinus Torvalds 
15051da177e4SLinus Torvalds 	write_unlock_bh(&hci_dev_list_lock);
15061da177e4SLinus Torvalds 
150732845eb1SGustavo F. Padovan 	hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND |
150832845eb1SGustavo F. Padovan 							WQ_MEM_RECLAIM, 1);
150933ca954dSDavid Herrmann 	if (!hdev->workqueue) {
151033ca954dSDavid Herrmann 		error = -ENOMEM;
151133ca954dSDavid Herrmann 		goto err;
151233ca954dSDavid Herrmann 	}
1513f48fd9c8SMarcel Holtmann 
151433ca954dSDavid Herrmann 	error = hci_add_sysfs(hdev);
151533ca954dSDavid Herrmann 	if (error < 0)
151633ca954dSDavid Herrmann 		goto err_wqueue;
15171da177e4SLinus Torvalds 
1518611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
1519611b30f7SMarcel Holtmann 				RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, hdev);
1520611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
1521611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
1522611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
1523611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
1524611b30f7SMarcel Holtmann 		}
1525611b30f7SMarcel Holtmann 	}
1526611b30f7SMarcel Holtmann 
1527ab81cbf9SJohan Hedberg 	set_bit(HCI_AUTO_OFF, &hdev->flags);
1528ab81cbf9SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->flags);
15297f971041SGustavo F. Padovan 	schedule_work(&hdev->power_on);
1530ab81cbf9SJohan Hedberg 
15311da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
15321da177e4SLinus Torvalds 
15331da177e4SLinus Torvalds 	return id;
1534f48fd9c8SMarcel Holtmann 
153533ca954dSDavid Herrmann err_wqueue:
153633ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
153733ca954dSDavid Herrmann err:
1538f48fd9c8SMarcel Holtmann 	write_lock_bh(&hci_dev_list_lock);
1539f48fd9c8SMarcel Holtmann 	list_del(&hdev->list);
1540f48fd9c8SMarcel Holtmann 	write_unlock_bh(&hci_dev_list_lock);
1541f48fd9c8SMarcel Holtmann 
154233ca954dSDavid Herrmann 	return error;
15431da177e4SLinus Torvalds }
15441da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
15451da177e4SLinus Torvalds 
15461da177e4SLinus Torvalds /* Unregister HCI device */
154759735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
15481da177e4SLinus Torvalds {
1549ef222013SMarcel Holtmann 	int i;
1550ef222013SMarcel Holtmann 
1551c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
15521da177e4SLinus Torvalds 
15531da177e4SLinus Torvalds 	write_lock_bh(&hci_dev_list_lock);
15541da177e4SLinus Torvalds 	list_del(&hdev->list);
15551da177e4SLinus Torvalds 	write_unlock_bh(&hci_dev_list_lock);
15561da177e4SLinus Torvalds 
15571da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
15581da177e4SLinus Torvalds 
1559cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
1560ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
1561ef222013SMarcel Holtmann 
1562ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
156356e5cb86SJohan Hedberg 					!test_bit(HCI_SETUP, &hdev->flags)) {
156409fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
1565744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
156609fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
156756e5cb86SJohan Hedberg 	}
1568ab81cbf9SJohan Hedberg 
15692e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
15702e58ef3eSJohan Hedberg 	 * pending list */
15712e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
15722e58ef3eSJohan Hedberg 
15731da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
15741da177e4SLinus Torvalds 
1575611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
1576611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
1577611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
1578611b30f7SMarcel Holtmann 	}
1579611b30f7SMarcel Holtmann 
1580ce242970SDavid Herrmann 	hci_del_sysfs(hdev);
1581147e2d59SDave Young 
1582db323f2fSGustavo F. Padovan 	cancel_delayed_work_sync(&hdev->adv_work);
1583c6f3c5f7SGustavo F. Padovan 
1584f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
1585f48fd9c8SMarcel Holtmann 
158609fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
1587e2e0cacbSJohan Hedberg 	hci_blacklist_clear(hdev);
15882aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
158955ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
15902763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
159176c8686fSAndre Guedes 	hci_adv_entries_clear(hdev);
159209fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
1593e2e0cacbSJohan Hedberg 
15941da177e4SLinus Torvalds 	__hci_dev_put(hdev);
15951da177e4SLinus Torvalds }
15961da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
15971da177e4SLinus Torvalds 
15981da177e4SLinus Torvalds /* Suspend HCI device */
15991da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
16001da177e4SLinus Torvalds {
16011da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
16021da177e4SLinus Torvalds 	return 0;
16031da177e4SLinus Torvalds }
16041da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
16051da177e4SLinus Torvalds 
16061da177e4SLinus Torvalds /* Resume HCI device */
16071da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
16081da177e4SLinus Torvalds {
16091da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
16101da177e4SLinus Torvalds 	return 0;
16111da177e4SLinus Torvalds }
16121da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
16131da177e4SLinus Torvalds 
161476bca880SMarcel Holtmann /* Receive frame from HCI drivers */
161576bca880SMarcel Holtmann int hci_recv_frame(struct sk_buff *skb)
161676bca880SMarcel Holtmann {
161776bca880SMarcel Holtmann 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
161876bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
161976bca880SMarcel Holtmann 				&& !test_bit(HCI_INIT, &hdev->flags))) {
162076bca880SMarcel Holtmann 		kfree_skb(skb);
162176bca880SMarcel Holtmann 		return -ENXIO;
162276bca880SMarcel Holtmann 	}
162376bca880SMarcel Holtmann 
162476bca880SMarcel Holtmann 	/* Incomming skb */
162576bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
162676bca880SMarcel Holtmann 
162776bca880SMarcel Holtmann 	/* Time stamp */
162876bca880SMarcel Holtmann 	__net_timestamp(skb);
162976bca880SMarcel Holtmann 
163076bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
1631b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
1632c78ae283SMarcel Holtmann 
163376bca880SMarcel Holtmann 	return 0;
163476bca880SMarcel Holtmann }
163576bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
163676bca880SMarcel Holtmann 
163733e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
16381e429f38SGustavo F. Padovan 						  int count, __u8 index)
163933e882a5SSuraj Sumangala {
164033e882a5SSuraj Sumangala 	int len = 0;
164133e882a5SSuraj Sumangala 	int hlen = 0;
164233e882a5SSuraj Sumangala 	int remain = count;
164333e882a5SSuraj Sumangala 	struct sk_buff *skb;
164433e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
164533e882a5SSuraj Sumangala 
164633e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
164733e882a5SSuraj Sumangala 				index >= NUM_REASSEMBLY)
164833e882a5SSuraj Sumangala 		return -EILSEQ;
164933e882a5SSuraj Sumangala 
165033e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
165133e882a5SSuraj Sumangala 
165233e882a5SSuraj Sumangala 	if (!skb) {
165333e882a5SSuraj Sumangala 		switch (type) {
165433e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
165533e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
165633e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
165733e882a5SSuraj Sumangala 			break;
165833e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
165933e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
166033e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
166133e882a5SSuraj Sumangala 			break;
166233e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
166333e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
166433e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
166533e882a5SSuraj Sumangala 			break;
166633e882a5SSuraj Sumangala 		}
166733e882a5SSuraj Sumangala 
16681e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
166933e882a5SSuraj Sumangala 		if (!skb)
167033e882a5SSuraj Sumangala 			return -ENOMEM;
167133e882a5SSuraj Sumangala 
167233e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
167333e882a5SSuraj Sumangala 		scb->expect = hlen;
167433e882a5SSuraj Sumangala 		scb->pkt_type = type;
167533e882a5SSuraj Sumangala 
167633e882a5SSuraj Sumangala 		skb->dev = (void *) hdev;
167733e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
167833e882a5SSuraj Sumangala 	}
167933e882a5SSuraj Sumangala 
168033e882a5SSuraj Sumangala 	while (count) {
168133e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
168233e882a5SSuraj Sumangala 		len = min(scb->expect, (__u16)count);
168333e882a5SSuraj Sumangala 
168433e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
168533e882a5SSuraj Sumangala 
168633e882a5SSuraj Sumangala 		count -= len;
168733e882a5SSuraj Sumangala 		data += len;
168833e882a5SSuraj Sumangala 		scb->expect -= len;
168933e882a5SSuraj Sumangala 		remain = count;
169033e882a5SSuraj Sumangala 
169133e882a5SSuraj Sumangala 		switch (type) {
169233e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
169333e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
169433e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
169533e882a5SSuraj Sumangala 				scb->expect = h->plen;
169633e882a5SSuraj Sumangala 
169733e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
169833e882a5SSuraj Sumangala 					kfree_skb(skb);
169933e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
170033e882a5SSuraj Sumangala 					return -ENOMEM;
170133e882a5SSuraj Sumangala 				}
170233e882a5SSuraj Sumangala 			}
170333e882a5SSuraj Sumangala 			break;
170433e882a5SSuraj Sumangala 
170533e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
170633e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
170733e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
170833e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
170933e882a5SSuraj Sumangala 
171033e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
171133e882a5SSuraj Sumangala 					kfree_skb(skb);
171233e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
171333e882a5SSuraj Sumangala 					return -ENOMEM;
171433e882a5SSuraj Sumangala 				}
171533e882a5SSuraj Sumangala 			}
171633e882a5SSuraj Sumangala 			break;
171733e882a5SSuraj Sumangala 
171833e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
171933e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
172033e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
172133e882a5SSuraj Sumangala 				scb->expect = h->dlen;
172233e882a5SSuraj Sumangala 
172333e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
172433e882a5SSuraj Sumangala 					kfree_skb(skb);
172533e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
172633e882a5SSuraj Sumangala 					return -ENOMEM;
172733e882a5SSuraj Sumangala 				}
172833e882a5SSuraj Sumangala 			}
172933e882a5SSuraj Sumangala 			break;
173033e882a5SSuraj Sumangala 		}
173133e882a5SSuraj Sumangala 
173233e882a5SSuraj Sumangala 		if (scb->expect == 0) {
173333e882a5SSuraj Sumangala 			/* Complete frame */
173433e882a5SSuraj Sumangala 
173533e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
173633e882a5SSuraj Sumangala 			hci_recv_frame(skb);
173733e882a5SSuraj Sumangala 
173833e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
173933e882a5SSuraj Sumangala 			return remain;
174033e882a5SSuraj Sumangala 		}
174133e882a5SSuraj Sumangala 	}
174233e882a5SSuraj Sumangala 
174333e882a5SSuraj Sumangala 	return remain;
174433e882a5SSuraj Sumangala }
174533e882a5SSuraj Sumangala 
1746ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
1747ef222013SMarcel Holtmann {
1748f39a3c06SSuraj Sumangala 	int rem = 0;
1749f39a3c06SSuraj Sumangala 
1750ef222013SMarcel Holtmann 	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
1751ef222013SMarcel Holtmann 		return -EILSEQ;
1752ef222013SMarcel Holtmann 
1753da5f6c37SGustavo F. Padovan 	while (count) {
17541e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count, type - 1);
1755f39a3c06SSuraj Sumangala 		if (rem < 0)
1756f39a3c06SSuraj Sumangala 			return rem;
1757ef222013SMarcel Holtmann 
1758f39a3c06SSuraj Sumangala 		data += (count - rem);
1759f39a3c06SSuraj Sumangala 		count = rem;
1760f81c6224SJoe Perches 	}
1761ef222013SMarcel Holtmann 
1762f39a3c06SSuraj Sumangala 	return rem;
1763ef222013SMarcel Holtmann }
1764ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment);
1765ef222013SMarcel Holtmann 
176699811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
176799811510SSuraj Sumangala 
176899811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
176999811510SSuraj Sumangala {
177099811510SSuraj Sumangala 	int type;
177199811510SSuraj Sumangala 	int rem = 0;
177299811510SSuraj Sumangala 
1773da5f6c37SGustavo F. Padovan 	while (count) {
177499811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
177599811510SSuraj Sumangala 
177699811510SSuraj Sumangala 		if (!skb) {
177799811510SSuraj Sumangala 			struct { char type; } *pkt;
177899811510SSuraj Sumangala 
177999811510SSuraj Sumangala 			/* Start of the frame */
178099811510SSuraj Sumangala 			pkt = data;
178199811510SSuraj Sumangala 			type = pkt->type;
178299811510SSuraj Sumangala 
178399811510SSuraj Sumangala 			data++;
178499811510SSuraj Sumangala 			count--;
178599811510SSuraj Sumangala 		} else
178699811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
178799811510SSuraj Sumangala 
17881e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
17891e429f38SGustavo F. Padovan 							STREAM_REASSEMBLY);
179099811510SSuraj Sumangala 		if (rem < 0)
179199811510SSuraj Sumangala 			return rem;
179299811510SSuraj Sumangala 
179399811510SSuraj Sumangala 		data += (count - rem);
179499811510SSuraj Sumangala 		count = rem;
1795f81c6224SJoe Perches 	}
179699811510SSuraj Sumangala 
179799811510SSuraj Sumangala 	return rem;
179899811510SSuraj Sumangala }
179999811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
180099811510SSuraj Sumangala 
18011da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
18021da177e4SLinus Torvalds 
18031da177e4SLinus Torvalds /* Register/Unregister protocols.
18041da177e4SLinus Torvalds  * hci_task_lock is used to ensure that no tasks are running. */
18051da177e4SLinus Torvalds int hci_register_proto(struct hci_proto *hp)
18061da177e4SLinus Torvalds {
18071da177e4SLinus Torvalds 	int err = 0;
18081da177e4SLinus Torvalds 
18091da177e4SLinus Torvalds 	BT_DBG("%p name %s id %d", hp, hp->name, hp->id);
18101da177e4SLinus Torvalds 
18111da177e4SLinus Torvalds 	if (hp->id >= HCI_MAX_PROTO)
18121da177e4SLinus Torvalds 		return -EINVAL;
18131da177e4SLinus Torvalds 
181467d0dfb5SGustavo F. Padovan 	mutex_lock(&hci_task_lock);
18151da177e4SLinus Torvalds 
18161da177e4SLinus Torvalds 	if (!hci_proto[hp->id])
18171da177e4SLinus Torvalds 		hci_proto[hp->id] = hp;
18181da177e4SLinus Torvalds 	else
18191da177e4SLinus Torvalds 		err = -EEXIST;
18201da177e4SLinus Torvalds 
182167d0dfb5SGustavo F. Padovan 	mutex_unlock(&hci_task_lock);
18221da177e4SLinus Torvalds 
18231da177e4SLinus Torvalds 	return err;
18241da177e4SLinus Torvalds }
18251da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_proto);
18261da177e4SLinus Torvalds 
18271da177e4SLinus Torvalds int hci_unregister_proto(struct hci_proto *hp)
18281da177e4SLinus Torvalds {
18291da177e4SLinus Torvalds 	int err = 0;
18301da177e4SLinus Torvalds 
18311da177e4SLinus Torvalds 	BT_DBG("%p name %s id %d", hp, hp->name, hp->id);
18321da177e4SLinus Torvalds 
18331da177e4SLinus Torvalds 	if (hp->id >= HCI_MAX_PROTO)
18341da177e4SLinus Torvalds 		return -EINVAL;
18351da177e4SLinus Torvalds 
183667d0dfb5SGustavo F. Padovan 	mutex_lock(&hci_task_lock);
18371da177e4SLinus Torvalds 
18381da177e4SLinus Torvalds 	if (hci_proto[hp->id])
18391da177e4SLinus Torvalds 		hci_proto[hp->id] = NULL;
18401da177e4SLinus Torvalds 	else
18411da177e4SLinus Torvalds 		err = -ENOENT;
18421da177e4SLinus Torvalds 
184367d0dfb5SGustavo F. Padovan 	mutex_unlock(&hci_task_lock);
18441da177e4SLinus Torvalds 
18451da177e4SLinus Torvalds 	return err;
18461da177e4SLinus Torvalds }
18471da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_proto);
18481da177e4SLinus Torvalds 
18491da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
18501da177e4SLinus Torvalds {
18511da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
18521da177e4SLinus Torvalds 
18531da177e4SLinus Torvalds 	write_lock_bh(&hci_cb_list_lock);
18541da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
18551da177e4SLinus Torvalds 	write_unlock_bh(&hci_cb_list_lock);
18561da177e4SLinus Torvalds 
18571da177e4SLinus Torvalds 	return 0;
18581da177e4SLinus Torvalds }
18591da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
18601da177e4SLinus Torvalds 
18611da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
18621da177e4SLinus Torvalds {
18631da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
18641da177e4SLinus Torvalds 
18651da177e4SLinus Torvalds 	write_lock_bh(&hci_cb_list_lock);
18661da177e4SLinus Torvalds 	list_del(&cb->list);
18671da177e4SLinus Torvalds 	write_unlock_bh(&hci_cb_list_lock);
18681da177e4SLinus Torvalds 
18691da177e4SLinus Torvalds 	return 0;
18701da177e4SLinus Torvalds }
18711da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
18721da177e4SLinus Torvalds 
18731da177e4SLinus Torvalds static int hci_send_frame(struct sk_buff *skb)
18741da177e4SLinus Torvalds {
18751da177e4SLinus Torvalds 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
18761da177e4SLinus Torvalds 
18771da177e4SLinus Torvalds 	if (!hdev) {
18781da177e4SLinus Torvalds 		kfree_skb(skb);
18791da177e4SLinus Torvalds 		return -ENODEV;
18801da177e4SLinus Torvalds 	}
18811da177e4SLinus Torvalds 
18820d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
18831da177e4SLinus Torvalds 
18841da177e4SLinus Torvalds 	if (atomic_read(&hdev->promisc)) {
18851da177e4SLinus Torvalds 		/* Time stamp */
1886a61bbcf2SPatrick McHardy 		__net_timestamp(skb);
18871da177e4SLinus Torvalds 
1888eec8d2bcSJohan Hedberg 		hci_send_to_sock(hdev, skb, NULL);
18891da177e4SLinus Torvalds 	}
18901da177e4SLinus Torvalds 
18911da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
18921da177e4SLinus Torvalds 	skb_orphan(skb);
18931da177e4SLinus Torvalds 
18941da177e4SLinus Torvalds 	return hdev->send(skb);
18951da177e4SLinus Torvalds }
18961da177e4SLinus Torvalds 
18971da177e4SLinus Torvalds /* Send HCI command */
1898a9de9248SMarcel Holtmann int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)
18991da177e4SLinus Torvalds {
19001da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
19011da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
19021da177e4SLinus Torvalds 	struct sk_buff *skb;
19031da177e4SLinus Torvalds 
1904a9de9248SMarcel Holtmann 	BT_DBG("%s opcode 0x%x plen %d", hdev->name, opcode, plen);
19051da177e4SLinus Torvalds 
19061da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
19071da177e4SLinus Torvalds 	if (!skb) {
1908ef222013SMarcel Holtmann 		BT_ERR("%s no memory for command", hdev->name);
19091da177e4SLinus Torvalds 		return -ENOMEM;
19101da177e4SLinus Torvalds 	}
19111da177e4SLinus Torvalds 
19121da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
1913a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
19141da177e4SLinus Torvalds 	hdr->plen   = plen;
19151da177e4SLinus Torvalds 
19161da177e4SLinus Torvalds 	if (plen)
19171da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
19181da177e4SLinus Torvalds 
19191da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
19201da177e4SLinus Torvalds 
19210d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
19221da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
1923c78ae283SMarcel Holtmann 
1924a5040efaSJohan Hedberg 	if (test_bit(HCI_INIT, &hdev->flags))
1925a5040efaSJohan Hedberg 		hdev->init_last_cmd = opcode;
1926a5040efaSJohan Hedberg 
19271da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
1928c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
19291da177e4SLinus Torvalds 
19301da177e4SLinus Torvalds 	return 0;
19311da177e4SLinus Torvalds }
19321da177e4SLinus Torvalds 
19331da177e4SLinus Torvalds /* Get data from the previously sent command */
1934a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
19351da177e4SLinus Torvalds {
19361da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
19371da177e4SLinus Torvalds 
19381da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
19391da177e4SLinus Torvalds 		return NULL;
19401da177e4SLinus Torvalds 
19411da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
19421da177e4SLinus Torvalds 
1943a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
19441da177e4SLinus Torvalds 		return NULL;
19451da177e4SLinus Torvalds 
1946a9de9248SMarcel Holtmann 	BT_DBG("%s opcode 0x%x", hdev->name, opcode);
19471da177e4SLinus Torvalds 
19481da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
19491da177e4SLinus Torvalds }
19501da177e4SLinus Torvalds 
19511da177e4SLinus Torvalds /* Send ACL data */
19521da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
19531da177e4SLinus Torvalds {
19541da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
19551da177e4SLinus Torvalds 	int len = skb->len;
19561da177e4SLinus Torvalds 
1957badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
1958badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
19599c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
1960aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
1961aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
19621da177e4SLinus Torvalds }
19631da177e4SLinus Torvalds 
196473d80debSLuiz Augusto von Dentz static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue,
196573d80debSLuiz Augusto von Dentz 				struct sk_buff *skb, __u16 flags)
19661da177e4SLinus Torvalds {
19671da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
19681da177e4SLinus Torvalds 	struct sk_buff *list;
19691da177e4SLinus Torvalds 
197070f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
197170f23020SAndrei Emeltchenko 	if (!list) {
19721da177e4SLinus Torvalds 		/* Non fragmented */
19731da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
19741da177e4SLinus Torvalds 
197573d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
19761da177e4SLinus Torvalds 	} else {
19771da177e4SLinus Torvalds 		/* Fragmented */
19781da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
19791da177e4SLinus Torvalds 
19801da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
19811da177e4SLinus Torvalds 
19821da177e4SLinus Torvalds 		/* Queue all fragments atomically */
198373d80debSLuiz Augusto von Dentz 		spin_lock_bh(&queue->lock);
19841da177e4SLinus Torvalds 
198573d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
1986e702112fSAndrei Emeltchenko 
1987e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
1988e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
19891da177e4SLinus Torvalds 		do {
19901da177e4SLinus Torvalds 			skb = list; list = list->next;
19911da177e4SLinus Torvalds 
19921da177e4SLinus Torvalds 			skb->dev = (void *) hdev;
19930d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
1994e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
19951da177e4SLinus Torvalds 
19961da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
19971da177e4SLinus Torvalds 
199873d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
19991da177e4SLinus Torvalds 		} while (list);
20001da177e4SLinus Torvalds 
200173d80debSLuiz Augusto von Dentz 		spin_unlock_bh(&queue->lock);
20021da177e4SLinus Torvalds 	}
200373d80debSLuiz Augusto von Dentz }
200473d80debSLuiz Augusto von Dentz 
200573d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
200673d80debSLuiz Augusto von Dentz {
200773d80debSLuiz Augusto von Dentz 	struct hci_conn *conn = chan->conn;
200873d80debSLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
200973d80debSLuiz Augusto von Dentz 
201073d80debSLuiz Augusto von Dentz 	BT_DBG("%s chan %p flags 0x%x", hdev->name, chan, flags);
201173d80debSLuiz Augusto von Dentz 
201273d80debSLuiz Augusto von Dentz 	skb->dev = (void *) hdev;
201373d80debSLuiz Augusto von Dentz 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
201473d80debSLuiz Augusto von Dentz 	hci_add_acl_hdr(skb, conn->handle, flags);
201573d80debSLuiz Augusto von Dentz 
201673d80debSLuiz Augusto von Dentz 	hci_queue_acl(conn, &chan->data_q, skb, flags);
20171da177e4SLinus Torvalds 
20183eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
20191da177e4SLinus Torvalds }
20201da177e4SLinus Torvalds EXPORT_SYMBOL(hci_send_acl);
20211da177e4SLinus Torvalds 
20221da177e4SLinus Torvalds /* Send SCO data */
20230d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
20241da177e4SLinus Torvalds {
20251da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
20261da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
20271da177e4SLinus Torvalds 
20281da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
20291da177e4SLinus Torvalds 
2030aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
20311da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
20321da177e4SLinus Torvalds 
2033badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
2034badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
20359c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
20361da177e4SLinus Torvalds 
20371da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
20380d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
2039c78ae283SMarcel Holtmann 
20401da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
20413eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
20421da177e4SLinus Torvalds }
20431da177e4SLinus Torvalds EXPORT_SYMBOL(hci_send_sco);
20441da177e4SLinus Torvalds 
20451da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
20461da177e4SLinus Torvalds 
20471da177e4SLinus Torvalds /* HCI Connection scheduler */
20481da177e4SLinus Torvalds static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote)
20491da177e4SLinus Torvalds {
20501da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
20518035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
20521da177e4SLinus Torvalds 	int num = 0, min = ~0;
20531da177e4SLinus Torvalds 
20541da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
20551da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
2056bf4c6325SGustavo F. Padovan 
2057bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2058bf4c6325SGustavo F. Padovan 
2059bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2060769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
20611da177e4SLinus Torvalds 			continue;
2062769be974SMarcel Holtmann 
2063769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
2064769be974SMarcel Holtmann 			continue;
2065769be974SMarcel Holtmann 
20661da177e4SLinus Torvalds 		num++;
20671da177e4SLinus Torvalds 
20681da177e4SLinus Torvalds 		if (c->sent < min) {
20691da177e4SLinus Torvalds 			min  = c->sent;
20701da177e4SLinus Torvalds 			conn = c;
20711da177e4SLinus Torvalds 		}
207252087a79SLuiz Augusto von Dentz 
207352087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
207452087a79SLuiz Augusto von Dentz 			break;
20751da177e4SLinus Torvalds 	}
20761da177e4SLinus Torvalds 
2077bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2078bf4c6325SGustavo F. Padovan 
20791da177e4SLinus Torvalds 	if (conn) {
20806ed58ec5SVille Tervo 		int cnt, q;
20816ed58ec5SVille Tervo 
20826ed58ec5SVille Tervo 		switch (conn->type) {
20836ed58ec5SVille Tervo 		case ACL_LINK:
20846ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
20856ed58ec5SVille Tervo 			break;
20866ed58ec5SVille Tervo 		case SCO_LINK:
20876ed58ec5SVille Tervo 		case ESCO_LINK:
20886ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
20896ed58ec5SVille Tervo 			break;
20906ed58ec5SVille Tervo 		case LE_LINK:
20916ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
20926ed58ec5SVille Tervo 			break;
20936ed58ec5SVille Tervo 		default:
20946ed58ec5SVille Tervo 			cnt = 0;
20956ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
20966ed58ec5SVille Tervo 		}
20976ed58ec5SVille Tervo 
20986ed58ec5SVille Tervo 		q = cnt / num;
20991da177e4SLinus Torvalds 		*quote = q ? q : 1;
21001da177e4SLinus Torvalds 	} else
21011da177e4SLinus Torvalds 		*quote = 0;
21021da177e4SLinus Torvalds 
21031da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
21041da177e4SLinus Torvalds 	return conn;
21051da177e4SLinus Torvalds }
21061da177e4SLinus Torvalds 
2107bae1f5d9SVille Tervo static inline void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
21081da177e4SLinus Torvalds {
21091da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
21101da177e4SLinus Torvalds 	struct hci_conn *c;
21111da177e4SLinus Torvalds 
2112bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
21131da177e4SLinus Torvalds 
2114bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2115bf4c6325SGustavo F. Padovan 
21161da177e4SLinus Torvalds 	/* Kill stalled connections */
2117bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2118bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
2119bae1f5d9SVille Tervo 			BT_ERR("%s killing stalled connection %s",
21201da177e4SLinus Torvalds 				hdev->name, batostr(&c->dst));
21211da177e4SLinus Torvalds 			hci_acl_disconn(c, 0x13);
21221da177e4SLinus Torvalds 		}
21231da177e4SLinus Torvalds 	}
2124bf4c6325SGustavo F. Padovan 
2125bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
21261da177e4SLinus Torvalds }
21271da177e4SLinus Torvalds 
212873d80debSLuiz Augusto von Dentz static inline struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
212973d80debSLuiz Augusto von Dentz 						int *quote)
213073d80debSLuiz Augusto von Dentz {
213173d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
213273d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
213373d80debSLuiz Augusto von Dentz 	int num = 0, min = ~0, cur_prio = 0;
213473d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
213573d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
213673d80debSLuiz Augusto von Dentz 
213773d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
213873d80debSLuiz Augusto von Dentz 
2139bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2140bf4c6325SGustavo F. Padovan 
2141bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
214273d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
214373d80debSLuiz Augusto von Dentz 
214473d80debSLuiz Augusto von Dentz 		if (conn->type != type)
214573d80debSLuiz Augusto von Dentz 			continue;
214673d80debSLuiz Augusto von Dentz 
214773d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
214873d80debSLuiz Augusto von Dentz 			continue;
214973d80debSLuiz Augusto von Dentz 
215073d80debSLuiz Augusto von Dentz 		conn_num++;
215173d80debSLuiz Augusto von Dentz 
21528192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
215373d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
215473d80debSLuiz Augusto von Dentz 
215573d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
215673d80debSLuiz Augusto von Dentz 				continue;
215773d80debSLuiz Augusto von Dentz 
215873d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
215973d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
216073d80debSLuiz Augusto von Dentz 				continue;
216173d80debSLuiz Augusto von Dentz 
216273d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
216373d80debSLuiz Augusto von Dentz 				num = 0;
216473d80debSLuiz Augusto von Dentz 				min = ~0;
216573d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
216673d80debSLuiz Augusto von Dentz 			}
216773d80debSLuiz Augusto von Dentz 
216873d80debSLuiz Augusto von Dentz 			num++;
216973d80debSLuiz Augusto von Dentz 
217073d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
217173d80debSLuiz Augusto von Dentz 				min  = conn->sent;
217273d80debSLuiz Augusto von Dentz 				chan = tmp;
217373d80debSLuiz Augusto von Dentz 			}
217473d80debSLuiz Augusto von Dentz 		}
217573d80debSLuiz Augusto von Dentz 
217673d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
217773d80debSLuiz Augusto von Dentz 			break;
217873d80debSLuiz Augusto von Dentz 	}
217973d80debSLuiz Augusto von Dentz 
2180bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2181bf4c6325SGustavo F. Padovan 
218273d80debSLuiz Augusto von Dentz 	if (!chan)
218373d80debSLuiz Augusto von Dentz 		return NULL;
218473d80debSLuiz Augusto von Dentz 
218573d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
218673d80debSLuiz Augusto von Dentz 	case ACL_LINK:
218773d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
218873d80debSLuiz Augusto von Dentz 		break;
218973d80debSLuiz Augusto von Dentz 	case SCO_LINK:
219073d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
219173d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
219273d80debSLuiz Augusto von Dentz 		break;
219373d80debSLuiz Augusto von Dentz 	case LE_LINK:
219473d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
219573d80debSLuiz Augusto von Dentz 		break;
219673d80debSLuiz Augusto von Dentz 	default:
219773d80debSLuiz Augusto von Dentz 		cnt = 0;
219873d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
219973d80debSLuiz Augusto von Dentz 	}
220073d80debSLuiz Augusto von Dentz 
220173d80debSLuiz Augusto von Dentz 	q = cnt / num;
220273d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
220373d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
220473d80debSLuiz Augusto von Dentz 	return chan;
220573d80debSLuiz Augusto von Dentz }
220673d80debSLuiz Augusto von Dentz 
220702b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
220802b20f0bSLuiz Augusto von Dentz {
220902b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
221002b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
221102b20f0bSLuiz Augusto von Dentz 	int num = 0;
221202b20f0bSLuiz Augusto von Dentz 
221302b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
221402b20f0bSLuiz Augusto von Dentz 
2215bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2216bf4c6325SGustavo F. Padovan 
2217bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
221802b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
221902b20f0bSLuiz Augusto von Dentz 
222002b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
222102b20f0bSLuiz Augusto von Dentz 			continue;
222202b20f0bSLuiz Augusto von Dentz 
222302b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
222402b20f0bSLuiz Augusto von Dentz 			continue;
222502b20f0bSLuiz Augusto von Dentz 
222602b20f0bSLuiz Augusto von Dentz 		num++;
222702b20f0bSLuiz Augusto von Dentz 
22288192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
222902b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
223002b20f0bSLuiz Augusto von Dentz 
223102b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
223202b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
223302b20f0bSLuiz Augusto von Dentz 				continue;
223402b20f0bSLuiz Augusto von Dentz 			}
223502b20f0bSLuiz Augusto von Dentz 
223602b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
223702b20f0bSLuiz Augusto von Dentz 				continue;
223802b20f0bSLuiz Augusto von Dentz 
223902b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
224002b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
224102b20f0bSLuiz Augusto von Dentz 				continue;
224202b20f0bSLuiz Augusto von Dentz 
224302b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
224402b20f0bSLuiz Augusto von Dentz 
224502b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
224602b20f0bSLuiz Augusto von Dentz 								skb->priority);
224702b20f0bSLuiz Augusto von Dentz 		}
224802b20f0bSLuiz Augusto von Dentz 
224902b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
225002b20f0bSLuiz Augusto von Dentz 			break;
225102b20f0bSLuiz Augusto von Dentz 	}
2252bf4c6325SGustavo F. Padovan 
2253bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2254bf4c6325SGustavo F. Padovan 
225502b20f0bSLuiz Augusto von Dentz }
225602b20f0bSLuiz Augusto von Dentz 
22571da177e4SLinus Torvalds static inline void hci_sched_acl(struct hci_dev *hdev)
22581da177e4SLinus Torvalds {
225973d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
22601da177e4SLinus Torvalds 	struct sk_buff *skb;
22611da177e4SLinus Torvalds 	int quote;
226273d80debSLuiz Augusto von Dentz 	unsigned int cnt;
22631da177e4SLinus Torvalds 
22641da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
22651da177e4SLinus Torvalds 
226652087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ACL_LINK))
226752087a79SLuiz Augusto von Dentz 		return;
226852087a79SLuiz Augusto von Dentz 
22691da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
22701da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
22711da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
227282453021SS.Çağlar Onur 		if (!hdev->acl_cnt && time_after(jiffies, hdev->acl_last_tx + HZ * 45))
2273bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
22741da177e4SLinus Torvalds 	}
22751da177e4SLinus Torvalds 
227673d80debSLuiz Augusto von Dentz 	cnt = hdev->acl_cnt;
227704837f64SMarcel Holtmann 
227873d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
227973d80debSLuiz Augusto von Dentz 			(chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
2280ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
2281ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
228273d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
228373d80debSLuiz Augusto von Dentz 					skb->len, skb->priority);
228473d80debSLuiz Augusto von Dentz 
2285ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
2286ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
2287ec1cce24SLuiz Augusto von Dentz 				break;
2288ec1cce24SLuiz Augusto von Dentz 
2289ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
2290ec1cce24SLuiz Augusto von Dentz 
229173d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
229273d80debSLuiz Augusto von Dentz 						bt_cb(skb)->force_active);
229304837f64SMarcel Holtmann 
22941da177e4SLinus Torvalds 			hci_send_frame(skb);
22951da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
22961da177e4SLinus Torvalds 
22971da177e4SLinus Torvalds 			hdev->acl_cnt--;
229873d80debSLuiz Augusto von Dentz 			chan->sent++;
229973d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
23001da177e4SLinus Torvalds 		}
23011da177e4SLinus Torvalds 	}
230202b20f0bSLuiz Augusto von Dentz 
230302b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
230402b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
23051da177e4SLinus Torvalds }
23061da177e4SLinus Torvalds 
23071da177e4SLinus Torvalds /* Schedule SCO */
23081da177e4SLinus Torvalds static inline void hci_sched_sco(struct hci_dev *hdev)
23091da177e4SLinus Torvalds {
23101da177e4SLinus Torvalds 	struct hci_conn *conn;
23111da177e4SLinus Torvalds 	struct sk_buff *skb;
23121da177e4SLinus Torvalds 	int quote;
23131da177e4SLinus Torvalds 
23141da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
23151da177e4SLinus Torvalds 
231652087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
231752087a79SLuiz Augusto von Dentz 		return;
231852087a79SLuiz Augusto von Dentz 
23191da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
23201da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
23211da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
23221da177e4SLinus Torvalds 			hci_send_frame(skb);
23231da177e4SLinus Torvalds 
23241da177e4SLinus Torvalds 			conn->sent++;
23251da177e4SLinus Torvalds 			if (conn->sent == ~0)
23261da177e4SLinus Torvalds 				conn->sent = 0;
23271da177e4SLinus Torvalds 		}
23281da177e4SLinus Torvalds 	}
23291da177e4SLinus Torvalds }
23301da177e4SLinus Torvalds 
2331b6a0dc82SMarcel Holtmann static inline void hci_sched_esco(struct hci_dev *hdev)
2332b6a0dc82SMarcel Holtmann {
2333b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
2334b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
2335b6a0dc82SMarcel Holtmann 	int quote;
2336b6a0dc82SMarcel Holtmann 
2337b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
2338b6a0dc82SMarcel Holtmann 
233952087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
234052087a79SLuiz Augusto von Dentz 		return;
234152087a79SLuiz Augusto von Dentz 
2342b6a0dc82SMarcel Holtmann 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, &quote))) {
2343b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
2344b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
2345b6a0dc82SMarcel Holtmann 			hci_send_frame(skb);
2346b6a0dc82SMarcel Holtmann 
2347b6a0dc82SMarcel Holtmann 			conn->sent++;
2348b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
2349b6a0dc82SMarcel Holtmann 				conn->sent = 0;
2350b6a0dc82SMarcel Holtmann 		}
2351b6a0dc82SMarcel Holtmann 	}
2352b6a0dc82SMarcel Holtmann }
2353b6a0dc82SMarcel Holtmann 
23546ed58ec5SVille Tervo static inline void hci_sched_le(struct hci_dev *hdev)
23556ed58ec5SVille Tervo {
235673d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
23576ed58ec5SVille Tervo 	struct sk_buff *skb;
235802b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
23596ed58ec5SVille Tervo 
23606ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
23616ed58ec5SVille Tervo 
236252087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
236352087a79SLuiz Augusto von Dentz 		return;
236452087a79SLuiz Augusto von Dentz 
23656ed58ec5SVille Tervo 	if (!test_bit(HCI_RAW, &hdev->flags)) {
23666ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
23676ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
2368bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
23696ed58ec5SVille Tervo 				time_after(jiffies, hdev->le_last_tx + HZ * 45))
2370bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
23716ed58ec5SVille Tervo 	}
23726ed58ec5SVille Tervo 
23736ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
237402b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
237573d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
2376ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
2377ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
237873d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
237973d80debSLuiz Augusto von Dentz 					skb->len, skb->priority);
23806ed58ec5SVille Tervo 
2381ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
2382ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
2383ec1cce24SLuiz Augusto von Dentz 				break;
2384ec1cce24SLuiz Augusto von Dentz 
2385ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
2386ec1cce24SLuiz Augusto von Dentz 
23876ed58ec5SVille Tervo 			hci_send_frame(skb);
23886ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
23896ed58ec5SVille Tervo 
23906ed58ec5SVille Tervo 			cnt--;
239173d80debSLuiz Augusto von Dentz 			chan->sent++;
239273d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
23936ed58ec5SVille Tervo 		}
23946ed58ec5SVille Tervo 	}
239573d80debSLuiz Augusto von Dentz 
23966ed58ec5SVille Tervo 	if (hdev->le_pkts)
23976ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
23986ed58ec5SVille Tervo 	else
23996ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
240002b20f0bSLuiz Augusto von Dentz 
240102b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
240202b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
24036ed58ec5SVille Tervo }
24046ed58ec5SVille Tervo 
24053eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
24061da177e4SLinus Torvalds {
24073eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
24081da177e4SLinus Torvalds 	struct sk_buff *skb;
24091da177e4SLinus Torvalds 
241067d0dfb5SGustavo F. Padovan 	mutex_lock(&hci_task_lock);
24111da177e4SLinus Torvalds 
24126ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
24136ed58ec5SVille Tervo 		hdev->sco_cnt, hdev->le_cnt);
24141da177e4SLinus Torvalds 
24151da177e4SLinus Torvalds 	/* Schedule queues and send stuff to HCI driver */
24161da177e4SLinus Torvalds 
24171da177e4SLinus Torvalds 	hci_sched_acl(hdev);
24181da177e4SLinus Torvalds 
24191da177e4SLinus Torvalds 	hci_sched_sco(hdev);
24201da177e4SLinus Torvalds 
2421b6a0dc82SMarcel Holtmann 	hci_sched_esco(hdev);
2422b6a0dc82SMarcel Holtmann 
24236ed58ec5SVille Tervo 	hci_sched_le(hdev);
24246ed58ec5SVille Tervo 
24251da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
24261da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
24271da177e4SLinus Torvalds 		hci_send_frame(skb);
24281da177e4SLinus Torvalds 
242967d0dfb5SGustavo F. Padovan 	mutex_unlock(&hci_task_lock);
24301da177e4SLinus Torvalds }
24311da177e4SLinus Torvalds 
243225985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
24331da177e4SLinus Torvalds 
24341da177e4SLinus Torvalds /* ACL data packet */
24351da177e4SLinus Torvalds static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
24361da177e4SLinus Torvalds {
24371da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
24381da177e4SLinus Torvalds 	struct hci_conn *conn;
24391da177e4SLinus Torvalds 	__u16 handle, flags;
24401da177e4SLinus Torvalds 
24411da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
24421da177e4SLinus Torvalds 
24431da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
24441da177e4SLinus Torvalds 	flags  = hci_flags(handle);
24451da177e4SLinus Torvalds 	handle = hci_handle(handle);
24461da177e4SLinus Torvalds 
24471da177e4SLinus Torvalds 	BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags);
24481da177e4SLinus Torvalds 
24491da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
24501da177e4SLinus Torvalds 
24511da177e4SLinus Torvalds 	hci_dev_lock(hdev);
24521da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
24531da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
24541da177e4SLinus Torvalds 
24551da177e4SLinus Torvalds 	if (conn) {
24561da177e4SLinus Torvalds 		register struct hci_proto *hp;
24571da177e4SLinus Torvalds 
245865983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
245904837f64SMarcel Holtmann 
24601da177e4SLinus Torvalds 		/* Send to upper protocol */
246170f23020SAndrei Emeltchenko 		hp = hci_proto[HCI_PROTO_L2CAP];
246270f23020SAndrei Emeltchenko 		if (hp && hp->recv_acldata) {
24631da177e4SLinus Torvalds 			hp->recv_acldata(conn, skb, flags);
24641da177e4SLinus Torvalds 			return;
24651da177e4SLinus Torvalds 		}
24661da177e4SLinus Torvalds 	} else {
24671da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
24681da177e4SLinus Torvalds 			hdev->name, handle);
24691da177e4SLinus Torvalds 	}
24701da177e4SLinus Torvalds 
24711da177e4SLinus Torvalds 	kfree_skb(skb);
24721da177e4SLinus Torvalds }
24731da177e4SLinus Torvalds 
24741da177e4SLinus Torvalds /* SCO data packet */
24751da177e4SLinus Torvalds static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
24761da177e4SLinus Torvalds {
24771da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
24781da177e4SLinus Torvalds 	struct hci_conn *conn;
24791da177e4SLinus Torvalds 	__u16 handle;
24801da177e4SLinus Torvalds 
24811da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
24821da177e4SLinus Torvalds 
24831da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
24841da177e4SLinus Torvalds 
24851da177e4SLinus Torvalds 	BT_DBG("%s len %d handle 0x%x", hdev->name, skb->len, handle);
24861da177e4SLinus Torvalds 
24871da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
24881da177e4SLinus Torvalds 
24891da177e4SLinus Torvalds 	hci_dev_lock(hdev);
24901da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
24911da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
24921da177e4SLinus Torvalds 
24931da177e4SLinus Torvalds 	if (conn) {
24941da177e4SLinus Torvalds 		register struct hci_proto *hp;
24951da177e4SLinus Torvalds 
24961da177e4SLinus Torvalds 		/* Send to upper protocol */
249770f23020SAndrei Emeltchenko 		hp = hci_proto[HCI_PROTO_SCO];
249870f23020SAndrei Emeltchenko 		if (hp && hp->recv_scodata) {
24991da177e4SLinus Torvalds 			hp->recv_scodata(conn, skb);
25001da177e4SLinus Torvalds 			return;
25011da177e4SLinus Torvalds 		}
25021da177e4SLinus Torvalds 	} else {
25031da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
25041da177e4SLinus Torvalds 			hdev->name, handle);
25051da177e4SLinus Torvalds 	}
25061da177e4SLinus Torvalds 
25071da177e4SLinus Torvalds 	kfree_skb(skb);
25081da177e4SLinus Torvalds }
25091da177e4SLinus Torvalds 
2510b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
25111da177e4SLinus Torvalds {
2512b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
25131da177e4SLinus Torvalds 	struct sk_buff *skb;
25141da177e4SLinus Torvalds 
25151da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
25161da177e4SLinus Torvalds 
251767d0dfb5SGustavo F. Padovan 	mutex_lock(&hci_task_lock);
25181da177e4SLinus Torvalds 
25191da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
25201da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
25211da177e4SLinus Torvalds 			/* Send copy to the sockets */
2522eec8d2bcSJohan Hedberg 			hci_send_to_sock(hdev, skb, NULL);
25231da177e4SLinus Torvalds 		}
25241da177e4SLinus Torvalds 
25251da177e4SLinus Torvalds 		if (test_bit(HCI_RAW, &hdev->flags)) {
25261da177e4SLinus Torvalds 			kfree_skb(skb);
25271da177e4SLinus Torvalds 			continue;
25281da177e4SLinus Torvalds 		}
25291da177e4SLinus Torvalds 
25301da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
25311da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
25320d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
25331da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
25341da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
25351da177e4SLinus Torvalds 				kfree_skb(skb);
25361da177e4SLinus Torvalds 				continue;
25373ff50b79SStephen Hemminger 			}
25381da177e4SLinus Torvalds 		}
25391da177e4SLinus Torvalds 
25401da177e4SLinus Torvalds 		/* Process frame */
25410d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
25421da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
2543b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
25441da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
25451da177e4SLinus Torvalds 			break;
25461da177e4SLinus Torvalds 
25471da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
25481da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
25491da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
25501da177e4SLinus Torvalds 			break;
25511da177e4SLinus Torvalds 
25521da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
25531da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
25541da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
25551da177e4SLinus Torvalds 			break;
25561da177e4SLinus Torvalds 
25571da177e4SLinus Torvalds 		default:
25581da177e4SLinus Torvalds 			kfree_skb(skb);
25591da177e4SLinus Torvalds 			break;
25601da177e4SLinus Torvalds 		}
25611da177e4SLinus Torvalds 	}
25621da177e4SLinus Torvalds 
256367d0dfb5SGustavo F. Padovan 	mutex_unlock(&hci_task_lock);
25641da177e4SLinus Torvalds }
25651da177e4SLinus Torvalds 
2566c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
25671da177e4SLinus Torvalds {
2568c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
25691da177e4SLinus Torvalds 	struct sk_buff *skb;
25701da177e4SLinus Torvalds 
25711da177e4SLinus Torvalds 	BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
25721da177e4SLinus Torvalds 
25731da177e4SLinus Torvalds 	/* Send queued commands */
25745a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
25755a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
25765a08ecceSAndrei Emeltchenko 		if (!skb)
25775a08ecceSAndrei Emeltchenko 			return;
25785a08ecceSAndrei Emeltchenko 
25791da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
25801da177e4SLinus Torvalds 
258170f23020SAndrei Emeltchenko 		hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC);
258270f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
25831da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
25841da177e4SLinus Torvalds 			hci_send_frame(skb);
25857bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
25867bdb8a5cSSzymon Janc 				del_timer(&hdev->cmd_timer);
25877bdb8a5cSSzymon Janc 			else
25886bd32326SVille Tervo 				mod_timer(&hdev->cmd_timer,
25896bd32326SVille Tervo 				  jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT));
25901da177e4SLinus Torvalds 		} else {
25911da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
2592c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
25931da177e4SLinus Torvalds 		}
25941da177e4SLinus Torvalds 	}
25951da177e4SLinus Torvalds }
25962519a1fcSAndre Guedes 
25972519a1fcSAndre Guedes int hci_do_inquiry(struct hci_dev *hdev, u8 length)
25982519a1fcSAndre Guedes {
25992519a1fcSAndre Guedes 	/* General inquiry access code (GIAC) */
26002519a1fcSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
26012519a1fcSAndre Guedes 	struct hci_cp_inquiry cp;
26022519a1fcSAndre Guedes 
26032519a1fcSAndre Guedes 	BT_DBG("%s", hdev->name);
26042519a1fcSAndre Guedes 
26052519a1fcSAndre Guedes 	if (test_bit(HCI_INQUIRY, &hdev->flags))
26062519a1fcSAndre Guedes 		return -EINPROGRESS;
26072519a1fcSAndre Guedes 
26082519a1fcSAndre Guedes 	memset(&cp, 0, sizeof(cp));
26092519a1fcSAndre Guedes 	memcpy(&cp.lap, lap, sizeof(cp.lap));
26102519a1fcSAndre Guedes 	cp.length  = length;
26112519a1fcSAndre Guedes 
26122519a1fcSAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
26132519a1fcSAndre Guedes }
2614023d5049SAndre Guedes 
2615023d5049SAndre Guedes int hci_cancel_inquiry(struct hci_dev *hdev)
2616023d5049SAndre Guedes {
2617023d5049SAndre Guedes 	BT_DBG("%s", hdev->name);
2618023d5049SAndre Guedes 
2619023d5049SAndre Guedes 	if (!test_bit(HCI_INQUIRY, &hdev->flags))
2620023d5049SAndre Guedes 		return -EPERM;
2621023d5049SAndre Guedes 
2622023d5049SAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL);
2623023d5049SAndre Guedes }
26247784d78fSAndrei Emeltchenko 
26257784d78fSAndrei Emeltchenko module_param(enable_hs, bool, 0644);
26267784d78fSAndrei Emeltchenko MODULE_PARM_DESC(enable_hs, "Enable High Speed");
2627