xref: /openbmc/linux/net/bluetooth/hci_core.c (revision f20d09d5)
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 
641da177e4SLinus Torvalds /* HCI device list */
651da177e4SLinus Torvalds LIST_HEAD(hci_dev_list);
661da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock);
671da177e4SLinus Torvalds 
681da177e4SLinus Torvalds /* HCI callback list */
691da177e4SLinus Torvalds LIST_HEAD(hci_cb_list);
701da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock);
711da177e4SLinus Torvalds 
721da177e4SLinus Torvalds /* HCI notifiers list */
73e041c683SAlan Stern static ATOMIC_NOTIFIER_HEAD(hci_notifier);
741da177e4SLinus Torvalds 
751da177e4SLinus Torvalds /* ---- HCI notifications ---- */
761da177e4SLinus Torvalds 
771da177e4SLinus Torvalds int hci_register_notifier(struct notifier_block *nb)
781da177e4SLinus Torvalds {
79e041c683SAlan Stern 	return atomic_notifier_chain_register(&hci_notifier, nb);
801da177e4SLinus Torvalds }
811da177e4SLinus Torvalds 
821da177e4SLinus Torvalds int hci_unregister_notifier(struct notifier_block *nb)
831da177e4SLinus Torvalds {
84e041c683SAlan Stern 	return atomic_notifier_chain_unregister(&hci_notifier, nb);
851da177e4SLinus Torvalds }
861da177e4SLinus Torvalds 
876516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event)
881da177e4SLinus Torvalds {
89e041c683SAlan Stern 	atomic_notifier_call_chain(&hci_notifier, event, hdev);
901da177e4SLinus Torvalds }
911da177e4SLinus Torvalds 
921da177e4SLinus Torvalds /* ---- HCI requests ---- */
931da177e4SLinus Torvalds 
9423bb5763SJohan Hedberg void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result)
951da177e4SLinus Torvalds {
9623bb5763SJohan Hedberg 	BT_DBG("%s command 0x%04x result 0x%2.2x", hdev->name, cmd, result);
9723bb5763SJohan Hedberg 
98a5040efaSJohan Hedberg 	/* If this is the init phase check if the completed command matches
99a5040efaSJohan Hedberg 	 * the last init command, and if not just return.
100a5040efaSJohan Hedberg 	 */
101a5040efaSJohan Hedberg 	if (test_bit(HCI_INIT, &hdev->flags) && hdev->init_last_cmd != cmd)
10223bb5763SJohan Hedberg 		return;
1031da177e4SLinus Torvalds 
1041da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
1051da177e4SLinus Torvalds 		hdev->req_result = result;
1061da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_DONE;
1071da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
1081da177e4SLinus Torvalds 	}
1091da177e4SLinus Torvalds }
1101da177e4SLinus Torvalds 
1111da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err)
1121da177e4SLinus Torvalds {
1131da177e4SLinus Torvalds 	BT_DBG("%s err 0x%2.2x", hdev->name, err);
1141da177e4SLinus Torvalds 
1151da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
1161da177e4SLinus Torvalds 		hdev->req_result = err;
1171da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_CANCELED;
1181da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
1191da177e4SLinus Torvalds 	}
1201da177e4SLinus Torvalds }
1211da177e4SLinus Torvalds 
1221da177e4SLinus Torvalds /* Execute request and wait for completion. */
1231da177e4SLinus Torvalds static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt),
1241da177e4SLinus Torvalds 					unsigned long opt, __u32 timeout)
1251da177e4SLinus Torvalds {
1261da177e4SLinus Torvalds 	DECLARE_WAITQUEUE(wait, current);
1271da177e4SLinus Torvalds 	int err = 0;
1281da177e4SLinus Torvalds 
1291da177e4SLinus Torvalds 	BT_DBG("%s start", hdev->name);
1301da177e4SLinus Torvalds 
1311da177e4SLinus Torvalds 	hdev->req_status = HCI_REQ_PEND;
1321da177e4SLinus Torvalds 
1331da177e4SLinus Torvalds 	add_wait_queue(&hdev->req_wait_q, &wait);
1341da177e4SLinus Torvalds 	set_current_state(TASK_INTERRUPTIBLE);
1351da177e4SLinus Torvalds 
1361da177e4SLinus Torvalds 	req(hdev, opt);
1371da177e4SLinus Torvalds 	schedule_timeout(timeout);
1381da177e4SLinus Torvalds 
1391da177e4SLinus Torvalds 	remove_wait_queue(&hdev->req_wait_q, &wait);
1401da177e4SLinus Torvalds 
1411da177e4SLinus Torvalds 	if (signal_pending(current))
1421da177e4SLinus Torvalds 		return -EINTR;
1431da177e4SLinus Torvalds 
1441da177e4SLinus Torvalds 	switch (hdev->req_status) {
1451da177e4SLinus Torvalds 	case HCI_REQ_DONE:
146e175072fSJoe Perches 		err = -bt_to_errno(hdev->req_result);
1471da177e4SLinus Torvalds 		break;
1481da177e4SLinus Torvalds 
1491da177e4SLinus Torvalds 	case HCI_REQ_CANCELED:
1501da177e4SLinus Torvalds 		err = -hdev->req_result;
1511da177e4SLinus Torvalds 		break;
1521da177e4SLinus Torvalds 
1531da177e4SLinus Torvalds 	default:
1541da177e4SLinus Torvalds 		err = -ETIMEDOUT;
1551da177e4SLinus Torvalds 		break;
1563ff50b79SStephen Hemminger 	}
1571da177e4SLinus Torvalds 
158a5040efaSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
1591da177e4SLinus Torvalds 
1601da177e4SLinus Torvalds 	BT_DBG("%s end: err %d", hdev->name, err);
1611da177e4SLinus Torvalds 
1621da177e4SLinus Torvalds 	return err;
1631da177e4SLinus Torvalds }
1641da177e4SLinus Torvalds 
1651da177e4SLinus Torvalds static inline int hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt),
1661da177e4SLinus Torvalds 					unsigned long opt, __u32 timeout)
1671da177e4SLinus Torvalds {
1681da177e4SLinus Torvalds 	int ret;
1691da177e4SLinus Torvalds 
1707c6a329eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
1717c6a329eSMarcel Holtmann 		return -ENETDOWN;
1727c6a329eSMarcel Holtmann 
1731da177e4SLinus Torvalds 	/* Serialize all requests */
1741da177e4SLinus Torvalds 	hci_req_lock(hdev);
1751da177e4SLinus Torvalds 	ret = __hci_request(hdev, req, opt, timeout);
1761da177e4SLinus Torvalds 	hci_req_unlock(hdev);
1771da177e4SLinus Torvalds 
1781da177e4SLinus Torvalds 	return ret;
1791da177e4SLinus Torvalds }
1801da177e4SLinus Torvalds 
1811da177e4SLinus Torvalds static void hci_reset_req(struct hci_dev *hdev, unsigned long opt)
1821da177e4SLinus Torvalds {
1831da177e4SLinus Torvalds 	BT_DBG("%s %ld", hdev->name, opt);
1841da177e4SLinus Torvalds 
1851da177e4SLinus Torvalds 	/* Reset device */
186f630cf0dSGustavo F. Padovan 	set_bit(HCI_RESET, &hdev->flags);
187a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
1881da177e4SLinus Torvalds }
1891da177e4SLinus Torvalds 
190e61ef499SAndrei Emeltchenko static void bredr_init(struct hci_dev *hdev)
1911da177e4SLinus Torvalds {
192b0916ea0SJohan Hedberg 	struct hci_cp_delete_stored_link_key cp;
1931ebb9252SMarcel Holtmann 	__le16 param;
19489f2783dSMarcel Holtmann 	__u8 flt_type;
1951da177e4SLinus Torvalds 
1962455a3eaSAndrei Emeltchenko 	hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
1972455a3eaSAndrei Emeltchenko 
1981da177e4SLinus Torvalds 	/* Mandatory initialization */
1991da177e4SLinus Torvalds 
2001da177e4SLinus Torvalds 	/* Reset */
201f630cf0dSGustavo F. Padovan 	if (!test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) {
202f630cf0dSGustavo F. Padovan 		set_bit(HCI_RESET, &hdev->flags);
203a9de9248SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
204f630cf0dSGustavo F. Padovan 	}
2051da177e4SLinus Torvalds 
2061da177e4SLinus Torvalds 	/* Read Local Supported Features */
207a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
2081da177e4SLinus Torvalds 
2091143e5a6SMarcel Holtmann 	/* Read Local Version */
210a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
2111143e5a6SMarcel Holtmann 
2121da177e4SLinus Torvalds 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
213a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
2141da177e4SLinus Torvalds 
2151da177e4SLinus Torvalds 	/* Read BD Address */
216a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL);
217a9de9248SMarcel Holtmann 
218a9de9248SMarcel Holtmann 	/* Read Class of Device */
219a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
220a9de9248SMarcel Holtmann 
221a9de9248SMarcel Holtmann 	/* Read Local Name */
222a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL);
2231da177e4SLinus Torvalds 
2241da177e4SLinus Torvalds 	/* Read Voice Setting */
225a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL);
2261da177e4SLinus Torvalds 
2271da177e4SLinus Torvalds 	/* Optional initialization */
2281da177e4SLinus Torvalds 
2291da177e4SLinus Torvalds 	/* Clear Event Filters */
23089f2783dSMarcel Holtmann 	flt_type = HCI_FLT_CLEAR_ALL;
231a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
2321da177e4SLinus Torvalds 
2331da177e4SLinus Torvalds 	/* Connection accept timeout ~20 secs */
234aca3192cSYOSHIFUJI Hideaki 	param = cpu_to_le16(0x7d00);
235a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
236b0916ea0SJohan Hedberg 
237b0916ea0SJohan Hedberg 	bacpy(&cp.bdaddr, BDADDR_ANY);
238b0916ea0SJohan Hedberg 	cp.delete_all = 1;
239b0916ea0SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp);
2401da177e4SLinus Torvalds }
2411da177e4SLinus Torvalds 
242e61ef499SAndrei Emeltchenko static void amp_init(struct hci_dev *hdev)
243e61ef499SAndrei Emeltchenko {
2442455a3eaSAndrei Emeltchenko 	hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
2452455a3eaSAndrei Emeltchenko 
246e61ef499SAndrei Emeltchenko 	/* Reset */
247e61ef499SAndrei Emeltchenko 	hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
248e61ef499SAndrei Emeltchenko 
249e61ef499SAndrei Emeltchenko 	/* Read Local Version */
250e61ef499SAndrei Emeltchenko 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
251e61ef499SAndrei Emeltchenko }
252e61ef499SAndrei Emeltchenko 
253e61ef499SAndrei Emeltchenko static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
254e61ef499SAndrei Emeltchenko {
255e61ef499SAndrei Emeltchenko 	struct sk_buff *skb;
256e61ef499SAndrei Emeltchenko 
257e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
258e61ef499SAndrei Emeltchenko 
259e61ef499SAndrei Emeltchenko 	/* Driver initialization */
260e61ef499SAndrei Emeltchenko 
261e61ef499SAndrei Emeltchenko 	/* Special commands */
262e61ef499SAndrei Emeltchenko 	while ((skb = skb_dequeue(&hdev->driver_init))) {
263e61ef499SAndrei Emeltchenko 		bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
264e61ef499SAndrei Emeltchenko 		skb->dev = (void *) hdev;
265e61ef499SAndrei Emeltchenko 
266e61ef499SAndrei Emeltchenko 		skb_queue_tail(&hdev->cmd_q, skb);
267e61ef499SAndrei Emeltchenko 		queue_work(hdev->workqueue, &hdev->cmd_work);
268e61ef499SAndrei Emeltchenko 	}
269e61ef499SAndrei Emeltchenko 	skb_queue_purge(&hdev->driver_init);
270e61ef499SAndrei Emeltchenko 
271e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
272e61ef499SAndrei Emeltchenko 	case HCI_BREDR:
273e61ef499SAndrei Emeltchenko 		bredr_init(hdev);
274e61ef499SAndrei Emeltchenko 		break;
275e61ef499SAndrei Emeltchenko 
276e61ef499SAndrei Emeltchenko 	case HCI_AMP:
277e61ef499SAndrei Emeltchenko 		amp_init(hdev);
278e61ef499SAndrei Emeltchenko 		break;
279e61ef499SAndrei Emeltchenko 
280e61ef499SAndrei Emeltchenko 	default:
281e61ef499SAndrei Emeltchenko 		BT_ERR("Unknown device type %d", hdev->dev_type);
282e61ef499SAndrei Emeltchenko 		break;
283e61ef499SAndrei Emeltchenko 	}
284e61ef499SAndrei Emeltchenko 
285e61ef499SAndrei Emeltchenko }
286e61ef499SAndrei Emeltchenko 
2876ed58ec5SVille Tervo static void hci_le_init_req(struct hci_dev *hdev, unsigned long opt)
2886ed58ec5SVille Tervo {
2896ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
2906ed58ec5SVille Tervo 
2916ed58ec5SVille Tervo 	/* Read LE buffer size */
2926ed58ec5SVille Tervo 	hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
2936ed58ec5SVille Tervo }
2946ed58ec5SVille Tervo 
2951da177e4SLinus Torvalds static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
2961da177e4SLinus Torvalds {
2971da177e4SLinus Torvalds 	__u8 scan = opt;
2981da177e4SLinus Torvalds 
2991da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, scan);
3001da177e4SLinus Torvalds 
3011da177e4SLinus Torvalds 	/* Inquiry and Page scans */
302a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
3031da177e4SLinus Torvalds }
3041da177e4SLinus Torvalds 
3051da177e4SLinus Torvalds static void hci_auth_req(struct hci_dev *hdev, unsigned long opt)
3061da177e4SLinus Torvalds {
3071da177e4SLinus Torvalds 	__u8 auth = opt;
3081da177e4SLinus Torvalds 
3091da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, auth);
3101da177e4SLinus Torvalds 
3111da177e4SLinus Torvalds 	/* Authentication */
312a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
3131da177e4SLinus Torvalds }
3141da177e4SLinus Torvalds 
3151da177e4SLinus Torvalds static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt)
3161da177e4SLinus Torvalds {
3171da177e4SLinus Torvalds 	__u8 encrypt = opt;
3181da177e4SLinus Torvalds 
3191da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, encrypt);
3201da177e4SLinus Torvalds 
321e4e8e37cSMarcel Holtmann 	/* Encryption */
322a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
3231da177e4SLinus Torvalds }
3241da177e4SLinus Torvalds 
325e4e8e37cSMarcel Holtmann static void hci_linkpol_req(struct hci_dev *hdev, unsigned long opt)
326e4e8e37cSMarcel Holtmann {
327e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
328e4e8e37cSMarcel Holtmann 
329a418b893SMarcel Holtmann 	BT_DBG("%s %x", hdev->name, policy);
330e4e8e37cSMarcel Holtmann 
331e4e8e37cSMarcel Holtmann 	/* Default link policy */
332e4e8e37cSMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
333e4e8e37cSMarcel Holtmann }
334e4e8e37cSMarcel Holtmann 
3351da177e4SLinus Torvalds /* Get HCI device by index.
3361da177e4SLinus Torvalds  * Device is held on return. */
3371da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
3381da177e4SLinus Torvalds {
3398035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
3401da177e4SLinus Torvalds 
3411da177e4SLinus Torvalds 	BT_DBG("%d", index);
3421da177e4SLinus Torvalds 
3431da177e4SLinus Torvalds 	if (index < 0)
3441da177e4SLinus Torvalds 		return NULL;
3451da177e4SLinus Torvalds 
3461da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
3478035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
3481da177e4SLinus Torvalds 		if (d->id == index) {
3491da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
3501da177e4SLinus Torvalds 			break;
3511da177e4SLinus Torvalds 		}
3521da177e4SLinus Torvalds 	}
3531da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
3541da177e4SLinus Torvalds 	return hdev;
3551da177e4SLinus Torvalds }
3561da177e4SLinus Torvalds 
3571da177e4SLinus Torvalds /* ---- Inquiry support ---- */
3581da177e4SLinus Torvalds static void inquiry_cache_flush(struct hci_dev *hdev)
3591da177e4SLinus Torvalds {
3601da177e4SLinus Torvalds 	struct inquiry_cache *cache = &hdev->inq_cache;
3611da177e4SLinus Torvalds 	struct inquiry_entry *next  = cache->list, *e;
3621da177e4SLinus Torvalds 
3631da177e4SLinus Torvalds 	BT_DBG("cache %p", cache);
3641da177e4SLinus Torvalds 
3651da177e4SLinus Torvalds 	cache->list = NULL;
3661da177e4SLinus Torvalds 	while ((e = next)) {
3671da177e4SLinus Torvalds 		next = e->next;
3681da177e4SLinus Torvalds 		kfree(e);
3691da177e4SLinus Torvalds 	}
3701da177e4SLinus Torvalds }
3711da177e4SLinus Torvalds 
3721da177e4SLinus Torvalds struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
3731da177e4SLinus Torvalds {
3741da177e4SLinus Torvalds 	struct inquiry_cache *cache = &hdev->inq_cache;
3751da177e4SLinus Torvalds 	struct inquiry_entry *e;
3761da177e4SLinus Torvalds 
3771da177e4SLinus Torvalds 	BT_DBG("cache %p, %s", cache, batostr(bdaddr));
3781da177e4SLinus Torvalds 
3791da177e4SLinus Torvalds 	for (e = cache->list; e; e = e->next)
3801da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
3811da177e4SLinus Torvalds 			break;
3821da177e4SLinus Torvalds 	return e;
3831da177e4SLinus Torvalds }
3841da177e4SLinus Torvalds 
3851da177e4SLinus Torvalds void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data)
3861da177e4SLinus Torvalds {
3871da177e4SLinus Torvalds 	struct inquiry_cache *cache = &hdev->inq_cache;
38870f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
3891da177e4SLinus Torvalds 
3901da177e4SLinus Torvalds 	BT_DBG("cache %p, %s", cache, batostr(&data->bdaddr));
3911da177e4SLinus Torvalds 
39270f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
39370f23020SAndrei Emeltchenko 	if (!ie) {
3941da177e4SLinus Torvalds 		/* Entry not in the cache. Add new one. */
39570f23020SAndrei Emeltchenko 		ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
39670f23020SAndrei Emeltchenko 		if (!ie)
3971da177e4SLinus Torvalds 			return;
39870f23020SAndrei Emeltchenko 
39970f23020SAndrei Emeltchenko 		ie->next = cache->list;
40070f23020SAndrei Emeltchenko 		cache->list = ie;
4011da177e4SLinus Torvalds 	}
4021da177e4SLinus Torvalds 
40370f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
40470f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
4051da177e4SLinus Torvalds 	cache->timestamp = jiffies;
4061da177e4SLinus Torvalds }
4071da177e4SLinus Torvalds 
4081da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
4091da177e4SLinus Torvalds {
4101da177e4SLinus Torvalds 	struct inquiry_cache *cache = &hdev->inq_cache;
4111da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
4121da177e4SLinus Torvalds 	struct inquiry_entry *e;
4131da177e4SLinus Torvalds 	int copied = 0;
4141da177e4SLinus Torvalds 
4151da177e4SLinus Torvalds 	for (e = cache->list; e && copied < num; e = e->next, copied++) {
4161da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
4171da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
4181da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
4191da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
4201da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
4211da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
4221da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
4231da177e4SLinus Torvalds 		info++;
4241da177e4SLinus Torvalds 	}
4251da177e4SLinus Torvalds 
4261da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
4271da177e4SLinus Torvalds 	return copied;
4281da177e4SLinus Torvalds }
4291da177e4SLinus Torvalds 
4301da177e4SLinus Torvalds static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
4311da177e4SLinus Torvalds {
4321da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
4331da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
4341da177e4SLinus Torvalds 
4351da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
4361da177e4SLinus Torvalds 
4371da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
4381da177e4SLinus Torvalds 		return;
4391da177e4SLinus Torvalds 
4401da177e4SLinus Torvalds 	/* Start Inquiry */
4411da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
4421da177e4SLinus Torvalds 	cp.length  = ir->length;
4431da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
444a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
4451da177e4SLinus Torvalds }
4461da177e4SLinus Torvalds 
4471da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
4481da177e4SLinus Torvalds {
4491da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
4501da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
4511da177e4SLinus Torvalds 	struct hci_dev *hdev;
4521da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
4531da177e4SLinus Torvalds 	long timeo;
4541da177e4SLinus Torvalds 	__u8 *buf;
4551da177e4SLinus Torvalds 
4561da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
4571da177e4SLinus Torvalds 		return -EFAULT;
4581da177e4SLinus Torvalds 
4595a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
4605a08ecceSAndrei Emeltchenko 	if (!hdev)
4611da177e4SLinus Torvalds 		return -ENODEV;
4621da177e4SLinus Torvalds 
46309fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
4641da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
4651da177e4SLinus Torvalds 				inquiry_cache_empty(hdev) ||
4661da177e4SLinus Torvalds 				ir.flags & IREQ_CACHE_FLUSH) {
4671da177e4SLinus Torvalds 		inquiry_cache_flush(hdev);
4681da177e4SLinus Torvalds 		do_inquiry = 1;
4691da177e4SLinus Torvalds 	}
47009fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
4711da177e4SLinus Torvalds 
47204837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
47370f23020SAndrei Emeltchenko 
47470f23020SAndrei Emeltchenko 	if (do_inquiry) {
47570f23020SAndrei Emeltchenko 		err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo);
47670f23020SAndrei Emeltchenko 		if (err < 0)
4771da177e4SLinus Torvalds 			goto done;
47870f23020SAndrei Emeltchenko 	}
4791da177e4SLinus Torvalds 
4801da177e4SLinus Torvalds 	/* for unlimited number of responses we will use buffer with 255 entries */
4811da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
4821da177e4SLinus Torvalds 
4831da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
4841da177e4SLinus Torvalds 	 * copy it to the user space.
4851da177e4SLinus Torvalds 	 */
48670f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
48770f23020SAndrei Emeltchenko 	if (!buf) {
4881da177e4SLinus Torvalds 		err = -ENOMEM;
4891da177e4SLinus Torvalds 		goto done;
4901da177e4SLinus Torvalds 	}
4911da177e4SLinus Torvalds 
49209fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
4931da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
49409fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
4951da177e4SLinus Torvalds 
4961da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
4971da177e4SLinus Torvalds 
4981da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
4991da177e4SLinus Torvalds 		ptr += sizeof(ir);
5001da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
5011da177e4SLinus Torvalds 					ir.num_rsp))
5021da177e4SLinus Torvalds 			err = -EFAULT;
5031da177e4SLinus Torvalds 	} else
5041da177e4SLinus Torvalds 		err = -EFAULT;
5051da177e4SLinus Torvalds 
5061da177e4SLinus Torvalds 	kfree(buf);
5071da177e4SLinus Torvalds 
5081da177e4SLinus Torvalds done:
5091da177e4SLinus Torvalds 	hci_dev_put(hdev);
5101da177e4SLinus Torvalds 	return err;
5111da177e4SLinus Torvalds }
5121da177e4SLinus Torvalds 
5131da177e4SLinus Torvalds /* ---- HCI ioctl helpers ---- */
5141da177e4SLinus Torvalds 
5151da177e4SLinus Torvalds int hci_dev_open(__u16 dev)
5161da177e4SLinus Torvalds {
5171da177e4SLinus Torvalds 	struct hci_dev *hdev;
5181da177e4SLinus Torvalds 	int ret = 0;
5191da177e4SLinus Torvalds 
5205a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(dev);
5215a08ecceSAndrei Emeltchenko 	if (!hdev)
5221da177e4SLinus Torvalds 		return -ENODEV;
5231da177e4SLinus Torvalds 
5241da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
5251da177e4SLinus Torvalds 
5261da177e4SLinus Torvalds 	hci_req_lock(hdev);
5271da177e4SLinus Torvalds 
528611b30f7SMarcel Holtmann 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) {
529611b30f7SMarcel Holtmann 		ret = -ERFKILL;
530611b30f7SMarcel Holtmann 		goto done;
531611b30f7SMarcel Holtmann 	}
532611b30f7SMarcel Holtmann 
5331da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
5341da177e4SLinus Torvalds 		ret = -EALREADY;
5351da177e4SLinus Torvalds 		goto done;
5361da177e4SLinus Torvalds 	}
5371da177e4SLinus Torvalds 
5381da177e4SLinus Torvalds 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
5391da177e4SLinus Torvalds 		set_bit(HCI_RAW, &hdev->flags);
5401da177e4SLinus Torvalds 
54107e3b94aSAndrei Emeltchenko 	/* Treat all non BR/EDR controllers as raw devices if
54207e3b94aSAndrei Emeltchenko 	   enable_hs is not set */
54307e3b94aSAndrei Emeltchenko 	if (hdev->dev_type != HCI_BREDR && !enable_hs)
544943da25dSMarcel Holtmann 		set_bit(HCI_RAW, &hdev->flags);
545943da25dSMarcel Holtmann 
5461da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
5471da177e4SLinus Torvalds 		ret = -EIO;
5481da177e4SLinus Torvalds 		goto done;
5491da177e4SLinus Torvalds 	}
5501da177e4SLinus Torvalds 
5511da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
5521da177e4SLinus Torvalds 		atomic_set(&hdev->cmd_cnt, 1);
5531da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
554a5040efaSJohan Hedberg 		hdev->init_last_cmd = 0;
5551da177e4SLinus Torvalds 
55604837f64SMarcel Holtmann 		ret = __hci_request(hdev, hci_init_req, 0,
55704837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
5581da177e4SLinus Torvalds 
559eead27daSAndre Guedes 		if (lmp_host_le_capable(hdev))
5606ed58ec5SVille Tervo 			ret = __hci_request(hdev, hci_le_init_req, 0,
5616ed58ec5SVille Tervo 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
5626ed58ec5SVille Tervo 
5631da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
5641da177e4SLinus Torvalds 	}
5651da177e4SLinus Torvalds 
5661da177e4SLinus Torvalds 	if (!ret) {
5671da177e4SLinus Torvalds 		hci_dev_hold(hdev);
5681da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
5691da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
57056e5cb86SJohan Hedberg 		if (!test_bit(HCI_SETUP, &hdev->flags)) {
57109fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
572744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
57309fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
57456e5cb86SJohan Hedberg 		}
5751da177e4SLinus Torvalds 	} else {
5761da177e4SLinus Torvalds 		/* Init failed, cleanup */
5773eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
578c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
579b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
5801da177e4SLinus Torvalds 
5811da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
5821da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
5831da177e4SLinus Torvalds 
5841da177e4SLinus Torvalds 		if (hdev->flush)
5851da177e4SLinus Torvalds 			hdev->flush(hdev);
5861da177e4SLinus Torvalds 
5871da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
5881da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
5891da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
5901da177e4SLinus Torvalds 		}
5911da177e4SLinus Torvalds 
5921da177e4SLinus Torvalds 		hdev->close(hdev);
5931da177e4SLinus Torvalds 		hdev->flags = 0;
5941da177e4SLinus Torvalds 	}
5951da177e4SLinus Torvalds 
5961da177e4SLinus Torvalds done:
5971da177e4SLinus Torvalds 	hci_req_unlock(hdev);
5981da177e4SLinus Torvalds 	hci_dev_put(hdev);
5991da177e4SLinus Torvalds 	return ret;
6001da177e4SLinus Torvalds }
6011da177e4SLinus Torvalds 
6021da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
6031da177e4SLinus Torvalds {
6041da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
6051da177e4SLinus Torvalds 
6061da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
6071da177e4SLinus Torvalds 	hci_req_lock(hdev);
6081da177e4SLinus Torvalds 
6091da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
610b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
6111da177e4SLinus Torvalds 		hci_req_unlock(hdev);
6121da177e4SLinus Torvalds 		return 0;
6131da177e4SLinus Torvalds 	}
6141da177e4SLinus Torvalds 
6153eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
6163eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
617b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
6181da177e4SLinus Torvalds 
61916ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
620e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
62116ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
62216ab91abSJohan Hedberg 	}
62316ab91abSJohan Hedberg 
6243243553fSJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags))
625e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
6263243553fSJohan Hedberg 
6277d78525dSJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->flags))
6287d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
6297d78525dSJohan Hedberg 
63009fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
6311da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
6321da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
63309fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
6341da177e4SLinus Torvalds 
6351da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
6361da177e4SLinus Torvalds 
6371da177e4SLinus Torvalds 	if (hdev->flush)
6381da177e4SLinus Torvalds 		hdev->flush(hdev);
6391da177e4SLinus Torvalds 
6401da177e4SLinus Torvalds 	/* Reset device */
6411da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
6421da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
6431da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
6441da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
64504837f64SMarcel Holtmann 		__hci_request(hdev, hci_reset_req, 0,
64643611a7bSSzymon Janc 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
6471da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
6481da177e4SLinus Torvalds 	}
6491da177e4SLinus Torvalds 
650c347b765SGustavo F. Padovan 	/* flush cmd  work */
651c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
6521da177e4SLinus Torvalds 
6531da177e4SLinus Torvalds 	/* Drop queues */
6541da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
6551da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
6561da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
6571da177e4SLinus Torvalds 
6581da177e4SLinus Torvalds 	/* Drop last sent command */
6591da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
660b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
6611da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
6621da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
6631da177e4SLinus Torvalds 	}
6641da177e4SLinus Torvalds 
6651da177e4SLinus Torvalds 	/* After this point our queues are empty
6661da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
6671da177e4SLinus Torvalds 	hdev->close(hdev);
6681da177e4SLinus Torvalds 
66909fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
670744cf19eSJohan Hedberg 	mgmt_powered(hdev, 0);
67109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
6725add6af8SJohan Hedberg 
6731da177e4SLinus Torvalds 	/* Clear flags */
6741da177e4SLinus Torvalds 	hdev->flags = 0;
6751da177e4SLinus Torvalds 
6761da177e4SLinus Torvalds 	hci_req_unlock(hdev);
6771da177e4SLinus Torvalds 
6781da177e4SLinus Torvalds 	hci_dev_put(hdev);
6791da177e4SLinus Torvalds 	return 0;
6801da177e4SLinus Torvalds }
6811da177e4SLinus Torvalds 
6821da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
6831da177e4SLinus Torvalds {
6841da177e4SLinus Torvalds 	struct hci_dev *hdev;
6851da177e4SLinus Torvalds 	int err;
6861da177e4SLinus Torvalds 
68770f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
68870f23020SAndrei Emeltchenko 	if (!hdev)
6891da177e4SLinus Torvalds 		return -ENODEV;
6901da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
6911da177e4SLinus Torvalds 	hci_dev_put(hdev);
6921da177e4SLinus Torvalds 	return err;
6931da177e4SLinus Torvalds }
6941da177e4SLinus Torvalds 
6951da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
6961da177e4SLinus Torvalds {
6971da177e4SLinus Torvalds 	struct hci_dev *hdev;
6981da177e4SLinus Torvalds 	int ret = 0;
6991da177e4SLinus Torvalds 
70070f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
70170f23020SAndrei Emeltchenko 	if (!hdev)
7021da177e4SLinus Torvalds 		return -ENODEV;
7031da177e4SLinus Torvalds 
7041da177e4SLinus Torvalds 	hci_req_lock(hdev);
7051da177e4SLinus Torvalds 
7061da177e4SLinus Torvalds 	if (!test_bit(HCI_UP, &hdev->flags))
7071da177e4SLinus Torvalds 		goto done;
7081da177e4SLinus Torvalds 
7091da177e4SLinus Torvalds 	/* Drop queues */
7101da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
7111da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
7121da177e4SLinus Torvalds 
71309fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
7141da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
7151da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
71609fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
7171da177e4SLinus Torvalds 
7181da177e4SLinus Torvalds 	if (hdev->flush)
7191da177e4SLinus Torvalds 		hdev->flush(hdev);
7201da177e4SLinus Torvalds 
7211da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
7226ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
7231da177e4SLinus Torvalds 
7241da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags))
72504837f64SMarcel Holtmann 		ret = __hci_request(hdev, hci_reset_req, 0,
72604837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
7271da177e4SLinus Torvalds 
7281da177e4SLinus Torvalds done:
7291da177e4SLinus Torvalds 	hci_req_unlock(hdev);
7301da177e4SLinus Torvalds 	hci_dev_put(hdev);
7311da177e4SLinus Torvalds 	return ret;
7321da177e4SLinus Torvalds }
7331da177e4SLinus Torvalds 
7341da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
7351da177e4SLinus Torvalds {
7361da177e4SLinus Torvalds 	struct hci_dev *hdev;
7371da177e4SLinus Torvalds 	int ret = 0;
7381da177e4SLinus Torvalds 
73970f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
74070f23020SAndrei Emeltchenko 	if (!hdev)
7411da177e4SLinus Torvalds 		return -ENODEV;
7421da177e4SLinus Torvalds 
7431da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
7441da177e4SLinus Torvalds 
7451da177e4SLinus Torvalds 	hci_dev_put(hdev);
7461da177e4SLinus Torvalds 
7471da177e4SLinus Torvalds 	return ret;
7481da177e4SLinus Torvalds }
7491da177e4SLinus Torvalds 
7501da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
7511da177e4SLinus Torvalds {
7521da177e4SLinus Torvalds 	struct hci_dev *hdev;
7531da177e4SLinus Torvalds 	struct hci_dev_req dr;
7541da177e4SLinus Torvalds 	int err = 0;
7551da177e4SLinus Torvalds 
7561da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
7571da177e4SLinus Torvalds 		return -EFAULT;
7581da177e4SLinus Torvalds 
75970f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
76070f23020SAndrei Emeltchenko 	if (!hdev)
7611da177e4SLinus Torvalds 		return -ENODEV;
7621da177e4SLinus Torvalds 
7631da177e4SLinus Torvalds 	switch (cmd) {
7641da177e4SLinus Torvalds 	case HCISETAUTH:
76504837f64SMarcel Holtmann 		err = hci_request(hdev, hci_auth_req, dr.dev_opt,
76604837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
7671da177e4SLinus Torvalds 		break;
7681da177e4SLinus Torvalds 
7691da177e4SLinus Torvalds 	case HCISETENCRYPT:
7701da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
7711da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
7721da177e4SLinus Torvalds 			break;
7731da177e4SLinus Torvalds 		}
7741da177e4SLinus Torvalds 
7751da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
7761da177e4SLinus Torvalds 			/* Auth must be enabled first */
77704837f64SMarcel Holtmann 			err = hci_request(hdev, hci_auth_req, dr.dev_opt,
77804837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
7791da177e4SLinus Torvalds 			if (err)
7801da177e4SLinus Torvalds 				break;
7811da177e4SLinus Torvalds 		}
7821da177e4SLinus Torvalds 
78304837f64SMarcel Holtmann 		err = hci_request(hdev, hci_encrypt_req, dr.dev_opt,
78404837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
7851da177e4SLinus Torvalds 		break;
7861da177e4SLinus Torvalds 
7871da177e4SLinus Torvalds 	case HCISETSCAN:
78804837f64SMarcel Holtmann 		err = hci_request(hdev, hci_scan_req, dr.dev_opt,
78904837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
7901da177e4SLinus Torvalds 		break;
7911da177e4SLinus Torvalds 
7921da177e4SLinus Torvalds 	case HCISETLINKPOL:
793e4e8e37cSMarcel Holtmann 		err = hci_request(hdev, hci_linkpol_req, dr.dev_opt,
794e4e8e37cSMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
7951da177e4SLinus Torvalds 		break;
7961da177e4SLinus Torvalds 
7971da177e4SLinus Torvalds 	case HCISETLINKMODE:
798e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
799e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
800e4e8e37cSMarcel Holtmann 		break;
801e4e8e37cSMarcel Holtmann 
802e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
803e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
8041da177e4SLinus Torvalds 		break;
8051da177e4SLinus Torvalds 
8061da177e4SLinus Torvalds 	case HCISETACLMTU:
8071da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
8081da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
8091da177e4SLinus Torvalds 		break;
8101da177e4SLinus Torvalds 
8111da177e4SLinus Torvalds 	case HCISETSCOMTU:
8121da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
8131da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
8141da177e4SLinus Torvalds 		break;
8151da177e4SLinus Torvalds 
8161da177e4SLinus Torvalds 	default:
8171da177e4SLinus Torvalds 		err = -EINVAL;
8181da177e4SLinus Torvalds 		break;
8191da177e4SLinus Torvalds 	}
820e4e8e37cSMarcel Holtmann 
8211da177e4SLinus Torvalds 	hci_dev_put(hdev);
8221da177e4SLinus Torvalds 	return err;
8231da177e4SLinus Torvalds }
8241da177e4SLinus Torvalds 
8251da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
8261da177e4SLinus Torvalds {
8278035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
8281da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
8291da177e4SLinus Torvalds 	struct hci_dev_req *dr;
8301da177e4SLinus Torvalds 	int n = 0, size, err;
8311da177e4SLinus Torvalds 	__u16 dev_num;
8321da177e4SLinus Torvalds 
8331da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
8341da177e4SLinus Torvalds 		return -EFAULT;
8351da177e4SLinus Torvalds 
8361da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
8371da177e4SLinus Torvalds 		return -EINVAL;
8381da177e4SLinus Torvalds 
8391da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
8401da177e4SLinus Torvalds 
84170f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
84270f23020SAndrei Emeltchenko 	if (!dl)
8431da177e4SLinus Torvalds 		return -ENOMEM;
8441da177e4SLinus Torvalds 
8451da177e4SLinus Torvalds 	dr = dl->dev_req;
8461da177e4SLinus Torvalds 
847f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
8488035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
8493243553fSJohan Hedberg 		if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags))
850e0f9309fSJohan Hedberg 			cancel_delayed_work(&hdev->power_off);
851c542a06cSJohan Hedberg 
852c542a06cSJohan Hedberg 		if (!test_bit(HCI_MGMT, &hdev->flags))
853c542a06cSJohan Hedberg 			set_bit(HCI_PAIRABLE, &hdev->flags);
854c542a06cSJohan Hedberg 
8551da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
8561da177e4SLinus Torvalds 		(dr + n)->dev_opt = hdev->flags;
857c542a06cSJohan Hedberg 
8581da177e4SLinus Torvalds 		if (++n >= dev_num)
8591da177e4SLinus Torvalds 			break;
8601da177e4SLinus Torvalds 	}
861f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
8621da177e4SLinus Torvalds 
8631da177e4SLinus Torvalds 	dl->dev_num = n;
8641da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
8651da177e4SLinus Torvalds 
8661da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
8671da177e4SLinus Torvalds 	kfree(dl);
8681da177e4SLinus Torvalds 
8691da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
8701da177e4SLinus Torvalds }
8711da177e4SLinus Torvalds 
8721da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
8731da177e4SLinus Torvalds {
8741da177e4SLinus Torvalds 	struct hci_dev *hdev;
8751da177e4SLinus Torvalds 	struct hci_dev_info di;
8761da177e4SLinus Torvalds 	int err = 0;
8771da177e4SLinus Torvalds 
8781da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
8791da177e4SLinus Torvalds 		return -EFAULT;
8801da177e4SLinus Torvalds 
88170f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
88270f23020SAndrei Emeltchenko 	if (!hdev)
8831da177e4SLinus Torvalds 		return -ENODEV;
8841da177e4SLinus Torvalds 
8853243553fSJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags))
8863243553fSJohan Hedberg 		cancel_delayed_work_sync(&hdev->power_off);
887ab81cbf9SJohan Hedberg 
888c542a06cSJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->flags))
889c542a06cSJohan Hedberg 		set_bit(HCI_PAIRABLE, &hdev->flags);
890c542a06cSJohan Hedberg 
8911da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
8921da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
893943da25dSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | (hdev->dev_type << 4);
8941da177e4SLinus Torvalds 	di.flags    = hdev->flags;
8951da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
8961da177e4SLinus Torvalds 	di.acl_mtu  = hdev->acl_mtu;
8971da177e4SLinus Torvalds 	di.acl_pkts = hdev->acl_pkts;
8981da177e4SLinus Torvalds 	di.sco_mtu  = hdev->sco_mtu;
8991da177e4SLinus Torvalds 	di.sco_pkts = hdev->sco_pkts;
9001da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
9011da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
9021da177e4SLinus Torvalds 
9031da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
9041da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
9051da177e4SLinus Torvalds 
9061da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
9071da177e4SLinus Torvalds 		err = -EFAULT;
9081da177e4SLinus Torvalds 
9091da177e4SLinus Torvalds 	hci_dev_put(hdev);
9101da177e4SLinus Torvalds 
9111da177e4SLinus Torvalds 	return err;
9121da177e4SLinus Torvalds }
9131da177e4SLinus Torvalds 
9141da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
9151da177e4SLinus Torvalds 
916611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
917611b30f7SMarcel Holtmann {
918611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
919611b30f7SMarcel Holtmann 
920611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
921611b30f7SMarcel Holtmann 
922611b30f7SMarcel Holtmann 	if (!blocked)
923611b30f7SMarcel Holtmann 		return 0;
924611b30f7SMarcel Holtmann 
925611b30f7SMarcel Holtmann 	hci_dev_do_close(hdev);
926611b30f7SMarcel Holtmann 
927611b30f7SMarcel Holtmann 	return 0;
928611b30f7SMarcel Holtmann }
929611b30f7SMarcel Holtmann 
930611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
931611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
932611b30f7SMarcel Holtmann };
933611b30f7SMarcel Holtmann 
9341da177e4SLinus Torvalds /* Alloc HCI device */
9351da177e4SLinus Torvalds struct hci_dev *hci_alloc_dev(void)
9361da177e4SLinus Torvalds {
9371da177e4SLinus Torvalds 	struct hci_dev *hdev;
9381da177e4SLinus Torvalds 
93925ea6db0SMarcel Holtmann 	hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
9401da177e4SLinus Torvalds 	if (!hdev)
9411da177e4SLinus Torvalds 		return NULL;
9421da177e4SLinus Torvalds 
9430ac7e700SDavid Herrmann 	hci_init_sysfs(hdev);
9441da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->driver_init);
9451da177e4SLinus Torvalds 
9461da177e4SLinus Torvalds 	return hdev;
9471da177e4SLinus Torvalds }
9481da177e4SLinus Torvalds EXPORT_SYMBOL(hci_alloc_dev);
9491da177e4SLinus Torvalds 
9501da177e4SLinus Torvalds /* Free HCI device */
9511da177e4SLinus Torvalds void hci_free_dev(struct hci_dev *hdev)
9521da177e4SLinus Torvalds {
9531da177e4SLinus Torvalds 	skb_queue_purge(&hdev->driver_init);
9541da177e4SLinus Torvalds 
955a91f2e39SMarcel Holtmann 	/* will free via device release */
956a91f2e39SMarcel Holtmann 	put_device(&hdev->dev);
9571da177e4SLinus Torvalds }
9581da177e4SLinus Torvalds EXPORT_SYMBOL(hci_free_dev);
9591da177e4SLinus Torvalds 
960ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
961ab81cbf9SJohan Hedberg {
962ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
963ab81cbf9SJohan Hedberg 
964ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
965ab81cbf9SJohan Hedberg 
966ab81cbf9SJohan Hedberg 	if (hci_dev_open(hdev->id) < 0)
967ab81cbf9SJohan Hedberg 		return;
968ab81cbf9SJohan Hedberg 
969ab81cbf9SJohan Hedberg 	if (test_bit(HCI_AUTO_OFF, &hdev->flags))
97080b7ab33SGustavo F. Padovan 		schedule_delayed_work(&hdev->power_off,
9713243553fSJohan Hedberg 					msecs_to_jiffies(AUTO_OFF_TIMEOUT));
972ab81cbf9SJohan Hedberg 
973ab81cbf9SJohan Hedberg 	if (test_and_clear_bit(HCI_SETUP, &hdev->flags))
974744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
975ab81cbf9SJohan Hedberg }
976ab81cbf9SJohan Hedberg 
977ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
978ab81cbf9SJohan Hedberg {
9793243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
9803243553fSJohan Hedberg 							power_off.work);
981ab81cbf9SJohan Hedberg 
982ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
983ab81cbf9SJohan Hedberg 
9843243553fSJohan Hedberg 	clear_bit(HCI_AUTO_OFF, &hdev->flags);
9853243553fSJohan Hedberg 
986ab81cbf9SJohan Hedberg 	hci_dev_close(hdev->id);
987ab81cbf9SJohan Hedberg }
988ab81cbf9SJohan Hedberg 
98916ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
99016ab91abSJohan Hedberg {
99116ab91abSJohan Hedberg 	struct hci_dev *hdev;
99216ab91abSJohan Hedberg 	u8 scan = SCAN_PAGE;
99316ab91abSJohan Hedberg 
99416ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
99516ab91abSJohan Hedberg 
99616ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
99716ab91abSJohan Hedberg 
99809fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
99916ab91abSJohan Hedberg 
100016ab91abSJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan);
100116ab91abSJohan Hedberg 
100216ab91abSJohan Hedberg 	hdev->discov_timeout = 0;
100316ab91abSJohan Hedberg 
100409fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
100516ab91abSJohan Hedberg }
100616ab91abSJohan Hedberg 
10072aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev)
10082aeb9a1aSJohan Hedberg {
10092aeb9a1aSJohan Hedberg 	struct list_head *p, *n;
10102aeb9a1aSJohan Hedberg 
10112aeb9a1aSJohan Hedberg 	list_for_each_safe(p, n, &hdev->uuids) {
10122aeb9a1aSJohan Hedberg 		struct bt_uuid *uuid;
10132aeb9a1aSJohan Hedberg 
10142aeb9a1aSJohan Hedberg 		uuid = list_entry(p, struct bt_uuid, list);
10152aeb9a1aSJohan Hedberg 
10162aeb9a1aSJohan Hedberg 		list_del(p);
10172aeb9a1aSJohan Hedberg 		kfree(uuid);
10182aeb9a1aSJohan Hedberg 	}
10192aeb9a1aSJohan Hedberg 
10202aeb9a1aSJohan Hedberg 	return 0;
10212aeb9a1aSJohan Hedberg }
10222aeb9a1aSJohan Hedberg 
102355ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev)
102455ed8ca1SJohan Hedberg {
102555ed8ca1SJohan Hedberg 	struct list_head *p, *n;
102655ed8ca1SJohan Hedberg 
102755ed8ca1SJohan Hedberg 	list_for_each_safe(p, n, &hdev->link_keys) {
102855ed8ca1SJohan Hedberg 		struct link_key *key;
102955ed8ca1SJohan Hedberg 
103055ed8ca1SJohan Hedberg 		key = list_entry(p, struct link_key, list);
103155ed8ca1SJohan Hedberg 
103255ed8ca1SJohan Hedberg 		list_del(p);
103355ed8ca1SJohan Hedberg 		kfree(key);
103455ed8ca1SJohan Hedberg 	}
103555ed8ca1SJohan Hedberg 
103655ed8ca1SJohan Hedberg 	return 0;
103755ed8ca1SJohan Hedberg }
103855ed8ca1SJohan Hedberg 
103955ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
104055ed8ca1SJohan Hedberg {
104155ed8ca1SJohan Hedberg 	struct link_key *k;
104255ed8ca1SJohan Hedberg 
10438035ded4SLuiz Augusto von Dentz 	list_for_each_entry(k, &hdev->link_keys, list)
104455ed8ca1SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0)
104555ed8ca1SJohan Hedberg 			return k;
104655ed8ca1SJohan Hedberg 
104755ed8ca1SJohan Hedberg 	return NULL;
104855ed8ca1SJohan Hedberg }
104955ed8ca1SJohan Hedberg 
1050d25e28abSJohan Hedberg static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1051d25e28abSJohan Hedberg 						u8 key_type, u8 old_key_type)
1052d25e28abSJohan Hedberg {
1053d25e28abSJohan Hedberg 	/* Legacy key */
1054d25e28abSJohan Hedberg 	if (key_type < 0x03)
1055d25e28abSJohan Hedberg 		return 1;
1056d25e28abSJohan Hedberg 
1057d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
1058d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
1059d25e28abSJohan Hedberg 		return 0;
1060d25e28abSJohan Hedberg 
1061d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
1062d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
1063d25e28abSJohan Hedberg 		return 0;
1064d25e28abSJohan Hedberg 
1065d25e28abSJohan Hedberg 	/* Security mode 3 case */
1066d25e28abSJohan Hedberg 	if (!conn)
1067d25e28abSJohan Hedberg 		return 1;
1068d25e28abSJohan Hedberg 
1069d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
1070d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
1071d25e28abSJohan Hedberg 		return 1;
1072d25e28abSJohan Hedberg 
1073d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
1074d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
1075d25e28abSJohan Hedberg 		return 1;
1076d25e28abSJohan Hedberg 
1077d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
1078d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
1079d25e28abSJohan Hedberg 		return 1;
1080d25e28abSJohan Hedberg 
1081d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
1082d25e28abSJohan Hedberg 	 * persistently */
1083d25e28abSJohan Hedberg 	return 0;
1084d25e28abSJohan Hedberg }
1085d25e28abSJohan Hedberg 
108675d262c2SVinicius Costa Gomes struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
108775d262c2SVinicius Costa Gomes {
108875d262c2SVinicius Costa Gomes 	struct link_key *k;
108975d262c2SVinicius Costa Gomes 
109075d262c2SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->link_keys, list) {
109175d262c2SVinicius Costa Gomes 		struct key_master_id *id;
109275d262c2SVinicius Costa Gomes 
109375d262c2SVinicius Costa Gomes 		if (k->type != HCI_LK_SMP_LTK)
109475d262c2SVinicius Costa Gomes 			continue;
109575d262c2SVinicius Costa Gomes 
109675d262c2SVinicius Costa Gomes 		if (k->dlen != sizeof(*id))
109775d262c2SVinicius Costa Gomes 			continue;
109875d262c2SVinicius Costa Gomes 
109975d262c2SVinicius Costa Gomes 		id = (void *) &k->data;
110075d262c2SVinicius Costa Gomes 		if (id->ediv == ediv &&
110175d262c2SVinicius Costa Gomes 				(memcmp(rand, id->rand, sizeof(id->rand)) == 0))
110275d262c2SVinicius Costa Gomes 			return k;
110375d262c2SVinicius Costa Gomes 	}
110475d262c2SVinicius Costa Gomes 
110575d262c2SVinicius Costa Gomes 	return NULL;
110675d262c2SVinicius Costa Gomes }
110775d262c2SVinicius Costa Gomes EXPORT_SYMBOL(hci_find_ltk);
110875d262c2SVinicius Costa Gomes 
110975d262c2SVinicius Costa Gomes struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
111075d262c2SVinicius Costa Gomes 					bdaddr_t *bdaddr, u8 type)
111175d262c2SVinicius Costa Gomes {
111275d262c2SVinicius Costa Gomes 	struct link_key *k;
111375d262c2SVinicius Costa Gomes 
111475d262c2SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->link_keys, list)
111575d262c2SVinicius Costa Gomes 		if (k->type == type && bacmp(bdaddr, &k->bdaddr) == 0)
111675d262c2SVinicius Costa Gomes 			return k;
111775d262c2SVinicius Costa Gomes 
111875d262c2SVinicius Costa Gomes 	return NULL;
111975d262c2SVinicius Costa Gomes }
112075d262c2SVinicius Costa Gomes EXPORT_SYMBOL(hci_find_link_key_type);
112175d262c2SVinicius Costa Gomes 
1122d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
1123d25e28abSJohan Hedberg 				bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
112455ed8ca1SJohan Hedberg {
112555ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
11264df378a1SJohan Hedberg 	u8 old_key_type, persistent;
112755ed8ca1SJohan Hedberg 
112855ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
112955ed8ca1SJohan Hedberg 	if (old_key) {
113055ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
113155ed8ca1SJohan Hedberg 		key = old_key;
113255ed8ca1SJohan Hedberg 	} else {
113312adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
113455ed8ca1SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
113555ed8ca1SJohan Hedberg 		if (!key)
113655ed8ca1SJohan Hedberg 			return -ENOMEM;
113755ed8ca1SJohan Hedberg 		list_add(&key->list, &hdev->link_keys);
113855ed8ca1SJohan Hedberg 	}
113955ed8ca1SJohan Hedberg 
114055ed8ca1SJohan Hedberg 	BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type);
114155ed8ca1SJohan Hedberg 
1142d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
1143d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
1144d25e28abSJohan Hedberg 	 * previous key */
1145d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
1146d25e28abSJohan Hedberg 					(!conn || conn->remote_auth == 0xff) &&
1147655fe6ecSJohan Hedberg 					old_key_type == 0xff) {
1148d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
1149655fe6ecSJohan Hedberg 		if (conn)
1150655fe6ecSJohan Hedberg 			conn->key_type = type;
1151655fe6ecSJohan Hedberg 	}
1152d25e28abSJohan Hedberg 
115355ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
115455ed8ca1SJohan Hedberg 	memcpy(key->val, val, 16);
115555ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
115655ed8ca1SJohan Hedberg 
1157b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
115855ed8ca1SJohan Hedberg 		key->type = old_key_type;
11594748fed2SJohan Hedberg 	else
11604748fed2SJohan Hedberg 		key->type = type;
11614748fed2SJohan Hedberg 
11624df378a1SJohan Hedberg 	if (!new_key)
11634df378a1SJohan Hedberg 		return 0;
11644df378a1SJohan Hedberg 
11654df378a1SJohan Hedberg 	persistent = hci_persistent_key(hdev, conn, type, old_key_type);
11664df378a1SJohan Hedberg 
1167744cf19eSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
11684df378a1SJohan Hedberg 
11694df378a1SJohan Hedberg 	if (!persistent) {
11704df378a1SJohan Hedberg 		list_del(&key->list);
11714df378a1SJohan Hedberg 		kfree(key);
11724df378a1SJohan Hedberg 	}
117355ed8ca1SJohan Hedberg 
117455ed8ca1SJohan Hedberg 	return 0;
117555ed8ca1SJohan Hedberg }
117655ed8ca1SJohan Hedberg 
117775d262c2SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
1178726b4ffcSVinicius Costa Gomes 			u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16])
117975d262c2SVinicius Costa Gomes {
118075d262c2SVinicius Costa Gomes 	struct link_key *key, *old_key;
118175d262c2SVinicius Costa Gomes 	struct key_master_id *id;
118275d262c2SVinicius Costa Gomes 	u8 old_key_type;
118375d262c2SVinicius Costa Gomes 
118475d262c2SVinicius Costa Gomes 	BT_DBG("%s addr %s", hdev->name, batostr(bdaddr));
118575d262c2SVinicius Costa Gomes 
118675d262c2SVinicius Costa Gomes 	old_key = hci_find_link_key_type(hdev, bdaddr, HCI_LK_SMP_LTK);
118775d262c2SVinicius Costa Gomes 	if (old_key) {
118875d262c2SVinicius Costa Gomes 		key = old_key;
118975d262c2SVinicius Costa Gomes 		old_key_type = old_key->type;
119075d262c2SVinicius Costa Gomes 	} else {
119175d262c2SVinicius Costa Gomes 		key = kzalloc(sizeof(*key) + sizeof(*id), GFP_ATOMIC);
119275d262c2SVinicius Costa Gomes 		if (!key)
119375d262c2SVinicius Costa Gomes 			return -ENOMEM;
119475d262c2SVinicius Costa Gomes 		list_add(&key->list, &hdev->link_keys);
119575d262c2SVinicius Costa Gomes 		old_key_type = 0xff;
119675d262c2SVinicius Costa Gomes 	}
119775d262c2SVinicius Costa Gomes 
119875d262c2SVinicius Costa Gomes 	key->dlen = sizeof(*id);
119975d262c2SVinicius Costa Gomes 
120075d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
120175d262c2SVinicius Costa Gomes 	memcpy(key->val, ltk, sizeof(key->val));
120275d262c2SVinicius Costa Gomes 	key->type = HCI_LK_SMP_LTK;
1203726b4ffcSVinicius Costa Gomes 	key->pin_len = key_size;
120475d262c2SVinicius Costa Gomes 
120575d262c2SVinicius Costa Gomes 	id = (void *) &key->data;
120675d262c2SVinicius Costa Gomes 	id->ediv = ediv;
120775d262c2SVinicius Costa Gomes 	memcpy(id->rand, rand, sizeof(id->rand));
120875d262c2SVinicius Costa Gomes 
120975d262c2SVinicius Costa Gomes 	if (new_key)
1210744cf19eSJohan Hedberg 		mgmt_new_link_key(hdev, key, old_key_type);
121175d262c2SVinicius Costa Gomes 
121275d262c2SVinicius Costa Gomes 	return 0;
121375d262c2SVinicius Costa Gomes }
121475d262c2SVinicius Costa Gomes 
121555ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
121655ed8ca1SJohan Hedberg {
121755ed8ca1SJohan Hedberg 	struct link_key *key;
121855ed8ca1SJohan Hedberg 
121955ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
122055ed8ca1SJohan Hedberg 	if (!key)
122155ed8ca1SJohan Hedberg 		return -ENOENT;
122255ed8ca1SJohan Hedberg 
122355ed8ca1SJohan Hedberg 	BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
122455ed8ca1SJohan Hedberg 
122555ed8ca1SJohan Hedberg 	list_del(&key->list);
122655ed8ca1SJohan Hedberg 	kfree(key);
122755ed8ca1SJohan Hedberg 
122855ed8ca1SJohan Hedberg 	return 0;
122955ed8ca1SJohan Hedberg }
123055ed8ca1SJohan Hedberg 
12316bd32326SVille Tervo /* HCI command timer function */
12326bd32326SVille Tervo static void hci_cmd_timer(unsigned long arg)
12336bd32326SVille Tervo {
12346bd32326SVille Tervo 	struct hci_dev *hdev = (void *) arg;
12356bd32326SVille Tervo 
12366bd32326SVille Tervo 	BT_ERR("%s command tx timeout", hdev->name);
12376bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
1238c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
12396bd32326SVille Tervo }
12406bd32326SVille Tervo 
12412763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
12422763eda6SSzymon Janc 							bdaddr_t *bdaddr)
12432763eda6SSzymon Janc {
12442763eda6SSzymon Janc 	struct oob_data *data;
12452763eda6SSzymon Janc 
12462763eda6SSzymon Janc 	list_for_each_entry(data, &hdev->remote_oob_data, list)
12472763eda6SSzymon Janc 		if (bacmp(bdaddr, &data->bdaddr) == 0)
12482763eda6SSzymon Janc 			return data;
12492763eda6SSzymon Janc 
12502763eda6SSzymon Janc 	return NULL;
12512763eda6SSzymon Janc }
12522763eda6SSzymon Janc 
12532763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
12542763eda6SSzymon Janc {
12552763eda6SSzymon Janc 	struct oob_data *data;
12562763eda6SSzymon Janc 
12572763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
12582763eda6SSzymon Janc 	if (!data)
12592763eda6SSzymon Janc 		return -ENOENT;
12602763eda6SSzymon Janc 
12612763eda6SSzymon Janc 	BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
12622763eda6SSzymon Janc 
12632763eda6SSzymon Janc 	list_del(&data->list);
12642763eda6SSzymon Janc 	kfree(data);
12652763eda6SSzymon Janc 
12662763eda6SSzymon Janc 	return 0;
12672763eda6SSzymon Janc }
12682763eda6SSzymon Janc 
12692763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev)
12702763eda6SSzymon Janc {
12712763eda6SSzymon Janc 	struct oob_data *data, *n;
12722763eda6SSzymon Janc 
12732763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
12742763eda6SSzymon Janc 		list_del(&data->list);
12752763eda6SSzymon Janc 		kfree(data);
12762763eda6SSzymon Janc 	}
12772763eda6SSzymon Janc 
12782763eda6SSzymon Janc 	return 0;
12792763eda6SSzymon Janc }
12802763eda6SSzymon Janc 
12812763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
12822763eda6SSzymon Janc 								u8 *randomizer)
12832763eda6SSzymon Janc {
12842763eda6SSzymon Janc 	struct oob_data *data;
12852763eda6SSzymon Janc 
12862763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
12872763eda6SSzymon Janc 
12882763eda6SSzymon Janc 	if (!data) {
12892763eda6SSzymon Janc 		data = kmalloc(sizeof(*data), GFP_ATOMIC);
12902763eda6SSzymon Janc 		if (!data)
12912763eda6SSzymon Janc 			return -ENOMEM;
12922763eda6SSzymon Janc 
12932763eda6SSzymon Janc 		bacpy(&data->bdaddr, bdaddr);
12942763eda6SSzymon Janc 		list_add(&data->list, &hdev->remote_oob_data);
12952763eda6SSzymon Janc 	}
12962763eda6SSzymon Janc 
12972763eda6SSzymon Janc 	memcpy(data->hash, hash, sizeof(data->hash));
12982763eda6SSzymon Janc 	memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
12992763eda6SSzymon Janc 
13002763eda6SSzymon Janc 	BT_DBG("%s for %s", hdev->name, batostr(bdaddr));
13012763eda6SSzymon Janc 
13022763eda6SSzymon Janc 	return 0;
13032763eda6SSzymon Janc }
13042763eda6SSzymon Janc 
1305b2a66aadSAntti Julku struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev,
1306b2a66aadSAntti Julku 						bdaddr_t *bdaddr)
1307b2a66aadSAntti Julku {
1308b2a66aadSAntti Julku 	struct bdaddr_list *b;
1309b2a66aadSAntti Julku 
13108035ded4SLuiz Augusto von Dentz 	list_for_each_entry(b, &hdev->blacklist, list)
1311b2a66aadSAntti Julku 		if (bacmp(bdaddr, &b->bdaddr) == 0)
1312b2a66aadSAntti Julku 			return b;
1313b2a66aadSAntti Julku 
1314b2a66aadSAntti Julku 	return NULL;
1315b2a66aadSAntti Julku }
1316b2a66aadSAntti Julku 
1317b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev)
1318b2a66aadSAntti Julku {
1319b2a66aadSAntti Julku 	struct list_head *p, *n;
1320b2a66aadSAntti Julku 
1321b2a66aadSAntti Julku 	list_for_each_safe(p, n, &hdev->blacklist) {
1322b2a66aadSAntti Julku 		struct bdaddr_list *b;
1323b2a66aadSAntti Julku 
1324b2a66aadSAntti Julku 		b = list_entry(p, struct bdaddr_list, list);
1325b2a66aadSAntti Julku 
1326b2a66aadSAntti Julku 		list_del(p);
1327b2a66aadSAntti Julku 		kfree(b);
1328b2a66aadSAntti Julku 	}
1329b2a66aadSAntti Julku 
1330b2a66aadSAntti Julku 	return 0;
1331b2a66aadSAntti Julku }
1332b2a66aadSAntti Julku 
1333b2a66aadSAntti Julku int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr)
1334b2a66aadSAntti Julku {
1335b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1336b2a66aadSAntti Julku 
1337b2a66aadSAntti Julku 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
1338b2a66aadSAntti Julku 		return -EBADF;
1339b2a66aadSAntti Julku 
13405e762444SAntti Julku 	if (hci_blacklist_lookup(hdev, bdaddr))
13415e762444SAntti Julku 		return -EEXIST;
1342b2a66aadSAntti Julku 
1343b2a66aadSAntti Julku 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
13445e762444SAntti Julku 	if (!entry)
13455e762444SAntti Julku 		return -ENOMEM;
1346b2a66aadSAntti Julku 
1347b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
1348b2a66aadSAntti Julku 
1349b2a66aadSAntti Julku 	list_add(&entry->list, &hdev->blacklist);
1350b2a66aadSAntti Julku 
1351744cf19eSJohan Hedberg 	return mgmt_device_blocked(hdev, bdaddr);
1352b2a66aadSAntti Julku }
1353b2a66aadSAntti Julku 
1354b2a66aadSAntti Julku int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr)
1355b2a66aadSAntti Julku {
1356b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1357b2a66aadSAntti Julku 
13581ec918ceSSzymon Janc 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
13595e762444SAntti Julku 		return hci_blacklist_clear(hdev);
1360b2a66aadSAntti Julku 
1361b2a66aadSAntti Julku 	entry = hci_blacklist_lookup(hdev, bdaddr);
13621ec918ceSSzymon Janc 	if (!entry)
13635e762444SAntti Julku 		return -ENOENT;
1364b2a66aadSAntti Julku 
1365b2a66aadSAntti Julku 	list_del(&entry->list);
1366b2a66aadSAntti Julku 	kfree(entry);
1367b2a66aadSAntti Julku 
1368744cf19eSJohan Hedberg 	return mgmt_device_unblocked(hdev, bdaddr);
1369b2a66aadSAntti Julku }
1370b2a66aadSAntti Julku 
1371db323f2fSGustavo F. Padovan static void hci_clear_adv_cache(struct work_struct *work)
137235815085SAndre Guedes {
1373db323f2fSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev,
1374db323f2fSGustavo F. Padovan 							adv_work.work);
137535815085SAndre Guedes 
137635815085SAndre Guedes 	hci_dev_lock(hdev);
137735815085SAndre Guedes 
137835815085SAndre Guedes 	hci_adv_entries_clear(hdev);
137935815085SAndre Guedes 
138035815085SAndre Guedes 	hci_dev_unlock(hdev);
138135815085SAndre Guedes }
138235815085SAndre Guedes 
138376c8686fSAndre Guedes int hci_adv_entries_clear(struct hci_dev *hdev)
138476c8686fSAndre Guedes {
138576c8686fSAndre Guedes 	struct adv_entry *entry, *tmp;
138676c8686fSAndre Guedes 
138776c8686fSAndre Guedes 	list_for_each_entry_safe(entry, tmp, &hdev->adv_entries, list) {
138876c8686fSAndre Guedes 		list_del(&entry->list);
138976c8686fSAndre Guedes 		kfree(entry);
139076c8686fSAndre Guedes 	}
139176c8686fSAndre Guedes 
139276c8686fSAndre Guedes 	BT_DBG("%s adv cache cleared", hdev->name);
139376c8686fSAndre Guedes 
139476c8686fSAndre Guedes 	return 0;
139576c8686fSAndre Guedes }
139676c8686fSAndre Guedes 
139776c8686fSAndre Guedes struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr)
139876c8686fSAndre Guedes {
139976c8686fSAndre Guedes 	struct adv_entry *entry;
140076c8686fSAndre Guedes 
140176c8686fSAndre Guedes 	list_for_each_entry(entry, &hdev->adv_entries, list)
140276c8686fSAndre Guedes 		if (bacmp(bdaddr, &entry->bdaddr) == 0)
140376c8686fSAndre Guedes 			return entry;
140476c8686fSAndre Guedes 
140576c8686fSAndre Guedes 	return NULL;
140676c8686fSAndre Guedes }
140776c8686fSAndre Guedes 
140876c8686fSAndre Guedes static inline int is_connectable_adv(u8 evt_type)
140976c8686fSAndre Guedes {
141076c8686fSAndre Guedes 	if (evt_type == ADV_IND || evt_type == ADV_DIRECT_IND)
141176c8686fSAndre Guedes 		return 1;
141276c8686fSAndre Guedes 
141376c8686fSAndre Guedes 	return 0;
141476c8686fSAndre Guedes }
141576c8686fSAndre Guedes 
141676c8686fSAndre Guedes int hci_add_adv_entry(struct hci_dev *hdev,
141776c8686fSAndre Guedes 					struct hci_ev_le_advertising_info *ev)
141876c8686fSAndre Guedes {
141976c8686fSAndre Guedes 	struct adv_entry *entry;
142076c8686fSAndre Guedes 
142176c8686fSAndre Guedes 	if (!is_connectable_adv(ev->evt_type))
142276c8686fSAndre Guedes 		return -EINVAL;
142376c8686fSAndre Guedes 
142476c8686fSAndre Guedes 	/* Only new entries should be added to adv_entries. So, if
142576c8686fSAndre Guedes 	 * bdaddr was found, don't add it. */
142676c8686fSAndre Guedes 	if (hci_find_adv_entry(hdev, &ev->bdaddr))
142776c8686fSAndre Guedes 		return 0;
142876c8686fSAndre Guedes 
142976c8686fSAndre Guedes 	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
143076c8686fSAndre Guedes 	if (!entry)
143176c8686fSAndre Guedes 		return -ENOMEM;
143276c8686fSAndre Guedes 
143376c8686fSAndre Guedes 	bacpy(&entry->bdaddr, &ev->bdaddr);
143476c8686fSAndre Guedes 	entry->bdaddr_type = ev->bdaddr_type;
143576c8686fSAndre Guedes 
143676c8686fSAndre Guedes 	list_add(&entry->list, &hdev->adv_entries);
143776c8686fSAndre Guedes 
143876c8686fSAndre Guedes 	BT_DBG("%s adv entry added: address %s type %u", hdev->name,
143976c8686fSAndre Guedes 				batostr(&entry->bdaddr), entry->bdaddr_type);
144076c8686fSAndre Guedes 
144176c8686fSAndre Guedes 	return 0;
144276c8686fSAndre Guedes }
144376c8686fSAndre Guedes 
14441da177e4SLinus Torvalds /* Register HCI device */
14451da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
14461da177e4SLinus Torvalds {
14471da177e4SLinus Torvalds 	struct list_head *head = &hci_dev_list, *p;
144808add513SMat Martineau 	int i, id, error;
14491da177e4SLinus Torvalds 
1450c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d owner %p", hdev, hdev->name,
1451c13854ceSMarcel Holtmann 						hdev->bus, hdev->owner);
14521da177e4SLinus Torvalds 
14531da177e4SLinus Torvalds 	if (!hdev->open || !hdev->close || !hdev->destruct)
14541da177e4SLinus Torvalds 		return -EINVAL;
14551da177e4SLinus Torvalds 
145608add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
145708add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
145808add513SMat Martineau 	 */
145908add513SMat Martineau 	id = (hdev->dev_type == HCI_BREDR) ? 0 : 1;
146008add513SMat Martineau 
1461f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
14621da177e4SLinus Torvalds 
14631da177e4SLinus Torvalds 	/* Find first available device id */
14641da177e4SLinus Torvalds 	list_for_each(p, &hci_dev_list) {
14651da177e4SLinus Torvalds 		if (list_entry(p, struct hci_dev, list)->id != id)
14661da177e4SLinus Torvalds 			break;
14671da177e4SLinus Torvalds 		head = p; id++;
14681da177e4SLinus Torvalds 	}
14691da177e4SLinus Torvalds 
14701da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
14711da177e4SLinus Torvalds 	hdev->id = id;
1472c6feeb28SAndrei Emeltchenko 	list_add_tail(&hdev->list, head);
14731da177e4SLinus Torvalds 
14741da177e4SLinus Torvalds 	atomic_set(&hdev->refcnt, 1);
147509fd0de5SGustavo F. Padovan 	mutex_init(&hdev->lock);
14761da177e4SLinus Torvalds 
14771da177e4SLinus Torvalds 	hdev->flags = 0;
1478d23264a8SAndre Guedes 	hdev->dev_flags = 0;
14791da177e4SLinus Torvalds 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
14805b7f9909SMarcel Holtmann 	hdev->esco_type = (ESCO_HV1);
14811da177e4SLinus Torvalds 	hdev->link_mode = (HCI_LM_ACCEPT);
148217fa4b9dSJohan Hedberg 	hdev->io_capability = 0x03; /* No Input No Output */
14831da177e4SLinus Torvalds 
148404837f64SMarcel Holtmann 	hdev->idle_timeout = 0;
148504837f64SMarcel Holtmann 	hdev->sniff_max_interval = 800;
148604837f64SMarcel Holtmann 	hdev->sniff_min_interval = 80;
148704837f64SMarcel Holtmann 
1488b78752ccSMarcel Holtmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
1489c347b765SGustavo F. Padovan 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
14903eff45eaSGustavo F. Padovan 	INIT_WORK(&hdev->tx_work, hci_tx_work);
1491b78752ccSMarcel Holtmann 
14921da177e4SLinus Torvalds 
14931da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->rx_q);
14941da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->cmd_q);
14951da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->raw_q);
14961da177e4SLinus Torvalds 
14976bd32326SVille Tervo 	setup_timer(&hdev->cmd_timer, hci_cmd_timer, (unsigned long) hdev);
14986bd32326SVille Tervo 
1499cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
1500ef222013SMarcel Holtmann 		hdev->reassembly[i] = NULL;
1501ef222013SMarcel Holtmann 
15021da177e4SLinus Torvalds 	init_waitqueue_head(&hdev->req_wait_q);
1503a6a67efdSThomas Gleixner 	mutex_init(&hdev->req_lock);
15041da177e4SLinus Torvalds 
15051da177e4SLinus Torvalds 	inquiry_cache_init(hdev);
15061da177e4SLinus Torvalds 
15071da177e4SLinus Torvalds 	hci_conn_hash_init(hdev);
15081da177e4SLinus Torvalds 
15092e58ef3eSJohan Hedberg 	INIT_LIST_HEAD(&hdev->mgmt_pending);
15102e58ef3eSJohan Hedberg 
1511ea4bd8baSDavid Miller 	INIT_LIST_HEAD(&hdev->blacklist);
1512f0358568SJohan Hedberg 
15132aeb9a1aSJohan Hedberg 	INIT_LIST_HEAD(&hdev->uuids);
15142aeb9a1aSJohan Hedberg 
151555ed8ca1SJohan Hedberg 	INIT_LIST_HEAD(&hdev->link_keys);
151655ed8ca1SJohan Hedberg 
15172763eda6SSzymon Janc 	INIT_LIST_HEAD(&hdev->remote_oob_data);
15182763eda6SSzymon Janc 
151976c8686fSAndre Guedes 	INIT_LIST_HEAD(&hdev->adv_entries);
152076c8686fSAndre Guedes 
1521db323f2fSGustavo F. Padovan 	INIT_DELAYED_WORK(&hdev->adv_work, hci_clear_adv_cache);
1522ab81cbf9SJohan Hedberg 	INIT_WORK(&hdev->power_on, hci_power_on);
15233243553fSJohan Hedberg 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
1524ab81cbf9SJohan Hedberg 
152516ab91abSJohan Hedberg 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
152616ab91abSJohan Hedberg 
15271da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
15281da177e4SLinus Torvalds 
15291da177e4SLinus Torvalds 	atomic_set(&hdev->promisc, 0);
15301da177e4SLinus Torvalds 
1531f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
15321da177e4SLinus Torvalds 
153332845eb1SGustavo F. Padovan 	hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND |
153432845eb1SGustavo F. Padovan 							WQ_MEM_RECLAIM, 1);
153533ca954dSDavid Herrmann 	if (!hdev->workqueue) {
153633ca954dSDavid Herrmann 		error = -ENOMEM;
153733ca954dSDavid Herrmann 		goto err;
153833ca954dSDavid Herrmann 	}
1539f48fd9c8SMarcel Holtmann 
154033ca954dSDavid Herrmann 	error = hci_add_sysfs(hdev);
154133ca954dSDavid Herrmann 	if (error < 0)
154233ca954dSDavid Herrmann 		goto err_wqueue;
15431da177e4SLinus Torvalds 
1544611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
1545611b30f7SMarcel Holtmann 				RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, hdev);
1546611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
1547611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
1548611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
1549611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
1550611b30f7SMarcel Holtmann 		}
1551611b30f7SMarcel Holtmann 	}
1552611b30f7SMarcel Holtmann 
1553ab81cbf9SJohan Hedberg 	set_bit(HCI_AUTO_OFF, &hdev->flags);
1554ab81cbf9SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->flags);
15557f971041SGustavo F. Padovan 	schedule_work(&hdev->power_on);
1556ab81cbf9SJohan Hedberg 
15571da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
15581da177e4SLinus Torvalds 
15591da177e4SLinus Torvalds 	return id;
1560f48fd9c8SMarcel Holtmann 
156133ca954dSDavid Herrmann err_wqueue:
156233ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
156333ca954dSDavid Herrmann err:
1564f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
1565f48fd9c8SMarcel Holtmann 	list_del(&hdev->list);
1566f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
1567f48fd9c8SMarcel Holtmann 
156833ca954dSDavid Herrmann 	return error;
15691da177e4SLinus Torvalds }
15701da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
15711da177e4SLinus Torvalds 
15721da177e4SLinus Torvalds /* Unregister HCI device */
157359735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
15741da177e4SLinus Torvalds {
1575ef222013SMarcel Holtmann 	int i;
1576ef222013SMarcel Holtmann 
1577c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
15781da177e4SLinus Torvalds 
1579f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
15801da177e4SLinus Torvalds 	list_del(&hdev->list);
1581f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
15821da177e4SLinus Torvalds 
15831da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
15841da177e4SLinus Torvalds 
1585cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
1586ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
1587ef222013SMarcel Holtmann 
1588ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
158956e5cb86SJohan Hedberg 					!test_bit(HCI_SETUP, &hdev->flags)) {
159009fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
1591744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
159209fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
159356e5cb86SJohan Hedberg 	}
1594ab81cbf9SJohan Hedberg 
15952e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
15962e58ef3eSJohan Hedberg 	 * pending list */
15972e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
15982e58ef3eSJohan Hedberg 
15991da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
16001da177e4SLinus Torvalds 
1601611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
1602611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
1603611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
1604611b30f7SMarcel Holtmann 	}
1605611b30f7SMarcel Holtmann 
1606ce242970SDavid Herrmann 	hci_del_sysfs(hdev);
1607147e2d59SDave Young 
1608db323f2fSGustavo F. Padovan 	cancel_delayed_work_sync(&hdev->adv_work);
1609c6f3c5f7SGustavo F. Padovan 
1610f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
1611f48fd9c8SMarcel Holtmann 
161209fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
1613e2e0cacbSJohan Hedberg 	hci_blacklist_clear(hdev);
16142aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
161555ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
16162763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
161776c8686fSAndre Guedes 	hci_adv_entries_clear(hdev);
161809fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
1619e2e0cacbSJohan Hedberg 
16201da177e4SLinus Torvalds 	__hci_dev_put(hdev);
16211da177e4SLinus Torvalds }
16221da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
16231da177e4SLinus Torvalds 
16241da177e4SLinus Torvalds /* Suspend HCI device */
16251da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
16261da177e4SLinus Torvalds {
16271da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
16281da177e4SLinus Torvalds 	return 0;
16291da177e4SLinus Torvalds }
16301da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
16311da177e4SLinus Torvalds 
16321da177e4SLinus Torvalds /* Resume HCI device */
16331da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
16341da177e4SLinus Torvalds {
16351da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
16361da177e4SLinus Torvalds 	return 0;
16371da177e4SLinus Torvalds }
16381da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
16391da177e4SLinus Torvalds 
164076bca880SMarcel Holtmann /* Receive frame from HCI drivers */
164176bca880SMarcel Holtmann int hci_recv_frame(struct sk_buff *skb)
164276bca880SMarcel Holtmann {
164376bca880SMarcel Holtmann 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
164476bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
164576bca880SMarcel Holtmann 				&& !test_bit(HCI_INIT, &hdev->flags))) {
164676bca880SMarcel Holtmann 		kfree_skb(skb);
164776bca880SMarcel Holtmann 		return -ENXIO;
164876bca880SMarcel Holtmann 	}
164976bca880SMarcel Holtmann 
165076bca880SMarcel Holtmann 	/* Incomming skb */
165176bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
165276bca880SMarcel Holtmann 
165376bca880SMarcel Holtmann 	/* Time stamp */
165476bca880SMarcel Holtmann 	__net_timestamp(skb);
165576bca880SMarcel Holtmann 
165676bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
1657b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
1658c78ae283SMarcel Holtmann 
165976bca880SMarcel Holtmann 	return 0;
166076bca880SMarcel Holtmann }
166176bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
166276bca880SMarcel Holtmann 
166333e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
16641e429f38SGustavo F. Padovan 						  int count, __u8 index)
166533e882a5SSuraj Sumangala {
166633e882a5SSuraj Sumangala 	int len = 0;
166733e882a5SSuraj Sumangala 	int hlen = 0;
166833e882a5SSuraj Sumangala 	int remain = count;
166933e882a5SSuraj Sumangala 	struct sk_buff *skb;
167033e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
167133e882a5SSuraj Sumangala 
167233e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
167333e882a5SSuraj Sumangala 				index >= NUM_REASSEMBLY)
167433e882a5SSuraj Sumangala 		return -EILSEQ;
167533e882a5SSuraj Sumangala 
167633e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
167733e882a5SSuraj Sumangala 
167833e882a5SSuraj Sumangala 	if (!skb) {
167933e882a5SSuraj Sumangala 		switch (type) {
168033e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
168133e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
168233e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
168333e882a5SSuraj Sumangala 			break;
168433e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
168533e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
168633e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
168733e882a5SSuraj Sumangala 			break;
168833e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
168933e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
169033e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
169133e882a5SSuraj Sumangala 			break;
169233e882a5SSuraj Sumangala 		}
169333e882a5SSuraj Sumangala 
16941e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
169533e882a5SSuraj Sumangala 		if (!skb)
169633e882a5SSuraj Sumangala 			return -ENOMEM;
169733e882a5SSuraj Sumangala 
169833e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
169933e882a5SSuraj Sumangala 		scb->expect = hlen;
170033e882a5SSuraj Sumangala 		scb->pkt_type = type;
170133e882a5SSuraj Sumangala 
170233e882a5SSuraj Sumangala 		skb->dev = (void *) hdev;
170333e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
170433e882a5SSuraj Sumangala 	}
170533e882a5SSuraj Sumangala 
170633e882a5SSuraj Sumangala 	while (count) {
170733e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
170833e882a5SSuraj Sumangala 		len = min(scb->expect, (__u16)count);
170933e882a5SSuraj Sumangala 
171033e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
171133e882a5SSuraj Sumangala 
171233e882a5SSuraj Sumangala 		count -= len;
171333e882a5SSuraj Sumangala 		data += len;
171433e882a5SSuraj Sumangala 		scb->expect -= len;
171533e882a5SSuraj Sumangala 		remain = count;
171633e882a5SSuraj Sumangala 
171733e882a5SSuraj Sumangala 		switch (type) {
171833e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
171933e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
172033e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
172133e882a5SSuraj Sumangala 				scb->expect = h->plen;
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 		case HCI_ACLDATA_PKT:
173233e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
173333e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
173433e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
173533e882a5SSuraj Sumangala 
173633e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
173733e882a5SSuraj Sumangala 					kfree_skb(skb);
173833e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
173933e882a5SSuraj Sumangala 					return -ENOMEM;
174033e882a5SSuraj Sumangala 				}
174133e882a5SSuraj Sumangala 			}
174233e882a5SSuraj Sumangala 			break;
174333e882a5SSuraj Sumangala 
174433e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
174533e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
174633e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
174733e882a5SSuraj Sumangala 				scb->expect = h->dlen;
174833e882a5SSuraj Sumangala 
174933e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
175033e882a5SSuraj Sumangala 					kfree_skb(skb);
175133e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
175233e882a5SSuraj Sumangala 					return -ENOMEM;
175333e882a5SSuraj Sumangala 				}
175433e882a5SSuraj Sumangala 			}
175533e882a5SSuraj Sumangala 			break;
175633e882a5SSuraj Sumangala 		}
175733e882a5SSuraj Sumangala 
175833e882a5SSuraj Sumangala 		if (scb->expect == 0) {
175933e882a5SSuraj Sumangala 			/* Complete frame */
176033e882a5SSuraj Sumangala 
176133e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
176233e882a5SSuraj Sumangala 			hci_recv_frame(skb);
176333e882a5SSuraj Sumangala 
176433e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
176533e882a5SSuraj Sumangala 			return remain;
176633e882a5SSuraj Sumangala 		}
176733e882a5SSuraj Sumangala 	}
176833e882a5SSuraj Sumangala 
176933e882a5SSuraj Sumangala 	return remain;
177033e882a5SSuraj Sumangala }
177133e882a5SSuraj Sumangala 
1772ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
1773ef222013SMarcel Holtmann {
1774f39a3c06SSuraj Sumangala 	int rem = 0;
1775f39a3c06SSuraj Sumangala 
1776ef222013SMarcel Holtmann 	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
1777ef222013SMarcel Holtmann 		return -EILSEQ;
1778ef222013SMarcel Holtmann 
1779da5f6c37SGustavo F. Padovan 	while (count) {
17801e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count, type - 1);
1781f39a3c06SSuraj Sumangala 		if (rem < 0)
1782f39a3c06SSuraj Sumangala 			return rem;
1783ef222013SMarcel Holtmann 
1784f39a3c06SSuraj Sumangala 		data += (count - rem);
1785f39a3c06SSuraj Sumangala 		count = rem;
1786f81c6224SJoe Perches 	}
1787ef222013SMarcel Holtmann 
1788f39a3c06SSuraj Sumangala 	return rem;
1789ef222013SMarcel Holtmann }
1790ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment);
1791ef222013SMarcel Holtmann 
179299811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
179399811510SSuraj Sumangala 
179499811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
179599811510SSuraj Sumangala {
179699811510SSuraj Sumangala 	int type;
179799811510SSuraj Sumangala 	int rem = 0;
179899811510SSuraj Sumangala 
1799da5f6c37SGustavo F. Padovan 	while (count) {
180099811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
180199811510SSuraj Sumangala 
180299811510SSuraj Sumangala 		if (!skb) {
180399811510SSuraj Sumangala 			struct { char type; } *pkt;
180499811510SSuraj Sumangala 
180599811510SSuraj Sumangala 			/* Start of the frame */
180699811510SSuraj Sumangala 			pkt = data;
180799811510SSuraj Sumangala 			type = pkt->type;
180899811510SSuraj Sumangala 
180999811510SSuraj Sumangala 			data++;
181099811510SSuraj Sumangala 			count--;
181199811510SSuraj Sumangala 		} else
181299811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
181399811510SSuraj Sumangala 
18141e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
18151e429f38SGustavo F. Padovan 							STREAM_REASSEMBLY);
181699811510SSuraj Sumangala 		if (rem < 0)
181799811510SSuraj Sumangala 			return rem;
181899811510SSuraj Sumangala 
181999811510SSuraj Sumangala 		data += (count - rem);
182099811510SSuraj Sumangala 		count = rem;
1821f81c6224SJoe Perches 	}
182299811510SSuraj Sumangala 
182399811510SSuraj Sumangala 	return rem;
182499811510SSuraj Sumangala }
182599811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
182699811510SSuraj Sumangala 
18271da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
18281da177e4SLinus Torvalds 
18291da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
18301da177e4SLinus Torvalds {
18311da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
18321da177e4SLinus Torvalds 
1833f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
18341da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
1835f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
18361da177e4SLinus Torvalds 
18371da177e4SLinus Torvalds 	return 0;
18381da177e4SLinus Torvalds }
18391da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
18401da177e4SLinus Torvalds 
18411da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
18421da177e4SLinus Torvalds {
18431da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
18441da177e4SLinus Torvalds 
1845f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
18461da177e4SLinus Torvalds 	list_del(&cb->list);
1847f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
18481da177e4SLinus Torvalds 
18491da177e4SLinus Torvalds 	return 0;
18501da177e4SLinus Torvalds }
18511da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
18521da177e4SLinus Torvalds 
18531da177e4SLinus Torvalds static int hci_send_frame(struct sk_buff *skb)
18541da177e4SLinus Torvalds {
18551da177e4SLinus Torvalds 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
18561da177e4SLinus Torvalds 
18571da177e4SLinus Torvalds 	if (!hdev) {
18581da177e4SLinus Torvalds 		kfree_skb(skb);
18591da177e4SLinus Torvalds 		return -ENODEV;
18601da177e4SLinus Torvalds 	}
18611da177e4SLinus Torvalds 
18620d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
18631da177e4SLinus Torvalds 
18641da177e4SLinus Torvalds 	if (atomic_read(&hdev->promisc)) {
18651da177e4SLinus Torvalds 		/* Time stamp */
1866a61bbcf2SPatrick McHardy 		__net_timestamp(skb);
18671da177e4SLinus Torvalds 
1868eec8d2bcSJohan Hedberg 		hci_send_to_sock(hdev, skb, NULL);
18691da177e4SLinus Torvalds 	}
18701da177e4SLinus Torvalds 
18711da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
18721da177e4SLinus Torvalds 	skb_orphan(skb);
18731da177e4SLinus Torvalds 
18741da177e4SLinus Torvalds 	return hdev->send(skb);
18751da177e4SLinus Torvalds }
18761da177e4SLinus Torvalds 
18771da177e4SLinus Torvalds /* Send HCI command */
1878a9de9248SMarcel Holtmann int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)
18791da177e4SLinus Torvalds {
18801da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
18811da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
18821da177e4SLinus Torvalds 	struct sk_buff *skb;
18831da177e4SLinus Torvalds 
1884a9de9248SMarcel Holtmann 	BT_DBG("%s opcode 0x%x plen %d", hdev->name, opcode, plen);
18851da177e4SLinus Torvalds 
18861da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
18871da177e4SLinus Torvalds 	if (!skb) {
1888ef222013SMarcel Holtmann 		BT_ERR("%s no memory for command", hdev->name);
18891da177e4SLinus Torvalds 		return -ENOMEM;
18901da177e4SLinus Torvalds 	}
18911da177e4SLinus Torvalds 
18921da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
1893a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
18941da177e4SLinus Torvalds 	hdr->plen   = plen;
18951da177e4SLinus Torvalds 
18961da177e4SLinus Torvalds 	if (plen)
18971da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
18981da177e4SLinus Torvalds 
18991da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
19001da177e4SLinus Torvalds 
19010d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
19021da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
1903c78ae283SMarcel Holtmann 
1904a5040efaSJohan Hedberg 	if (test_bit(HCI_INIT, &hdev->flags))
1905a5040efaSJohan Hedberg 		hdev->init_last_cmd = opcode;
1906a5040efaSJohan Hedberg 
19071da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
1908c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
19091da177e4SLinus Torvalds 
19101da177e4SLinus Torvalds 	return 0;
19111da177e4SLinus Torvalds }
19121da177e4SLinus Torvalds 
19131da177e4SLinus Torvalds /* Get data from the previously sent command */
1914a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
19151da177e4SLinus Torvalds {
19161da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
19171da177e4SLinus Torvalds 
19181da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
19191da177e4SLinus Torvalds 		return NULL;
19201da177e4SLinus Torvalds 
19211da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
19221da177e4SLinus Torvalds 
1923a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
19241da177e4SLinus Torvalds 		return NULL;
19251da177e4SLinus Torvalds 
1926a9de9248SMarcel Holtmann 	BT_DBG("%s opcode 0x%x", hdev->name, opcode);
19271da177e4SLinus Torvalds 
19281da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
19291da177e4SLinus Torvalds }
19301da177e4SLinus Torvalds 
19311da177e4SLinus Torvalds /* Send ACL data */
19321da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
19331da177e4SLinus Torvalds {
19341da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
19351da177e4SLinus Torvalds 	int len = skb->len;
19361da177e4SLinus Torvalds 
1937badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
1938badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
19399c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
1940aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
1941aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
19421da177e4SLinus Torvalds }
19431da177e4SLinus Torvalds 
194473d80debSLuiz Augusto von Dentz static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue,
194573d80debSLuiz Augusto von Dentz 				struct sk_buff *skb, __u16 flags)
19461da177e4SLinus Torvalds {
19471da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
19481da177e4SLinus Torvalds 	struct sk_buff *list;
19491da177e4SLinus Torvalds 
195070f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
195170f23020SAndrei Emeltchenko 	if (!list) {
19521da177e4SLinus Torvalds 		/* Non fragmented */
19531da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
19541da177e4SLinus Torvalds 
195573d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
19561da177e4SLinus Torvalds 	} else {
19571da177e4SLinus Torvalds 		/* Fragmented */
19581da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
19591da177e4SLinus Torvalds 
19601da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
19611da177e4SLinus Torvalds 
19621da177e4SLinus Torvalds 		/* Queue all fragments atomically */
196373d80debSLuiz Augusto von Dentz 		spin_lock_bh(&queue->lock);
19641da177e4SLinus Torvalds 
196573d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
1966e702112fSAndrei Emeltchenko 
1967e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
1968e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
19691da177e4SLinus Torvalds 		do {
19701da177e4SLinus Torvalds 			skb = list; list = list->next;
19711da177e4SLinus Torvalds 
19721da177e4SLinus Torvalds 			skb->dev = (void *) hdev;
19730d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
1974e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
19751da177e4SLinus Torvalds 
19761da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
19771da177e4SLinus Torvalds 
197873d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
19791da177e4SLinus Torvalds 		} while (list);
19801da177e4SLinus Torvalds 
198173d80debSLuiz Augusto von Dentz 		spin_unlock_bh(&queue->lock);
19821da177e4SLinus Torvalds 	}
198373d80debSLuiz Augusto von Dentz }
198473d80debSLuiz Augusto von Dentz 
198573d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
198673d80debSLuiz Augusto von Dentz {
198773d80debSLuiz Augusto von Dentz 	struct hci_conn *conn = chan->conn;
198873d80debSLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
198973d80debSLuiz Augusto von Dentz 
199073d80debSLuiz Augusto von Dentz 	BT_DBG("%s chan %p flags 0x%x", hdev->name, chan, flags);
199173d80debSLuiz Augusto von Dentz 
199273d80debSLuiz Augusto von Dentz 	skb->dev = (void *) hdev;
199373d80debSLuiz Augusto von Dentz 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
199473d80debSLuiz Augusto von Dentz 	hci_add_acl_hdr(skb, conn->handle, flags);
199573d80debSLuiz Augusto von Dentz 
199673d80debSLuiz Augusto von Dentz 	hci_queue_acl(conn, &chan->data_q, skb, flags);
19971da177e4SLinus Torvalds 
19983eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
19991da177e4SLinus Torvalds }
20001da177e4SLinus Torvalds EXPORT_SYMBOL(hci_send_acl);
20011da177e4SLinus Torvalds 
20021da177e4SLinus Torvalds /* Send SCO data */
20030d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
20041da177e4SLinus Torvalds {
20051da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
20061da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
20071da177e4SLinus Torvalds 
20081da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
20091da177e4SLinus Torvalds 
2010aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
20111da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
20121da177e4SLinus Torvalds 
2013badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
2014badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
20159c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
20161da177e4SLinus Torvalds 
20171da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
20180d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
2019c78ae283SMarcel Holtmann 
20201da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
20213eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
20221da177e4SLinus Torvalds }
20231da177e4SLinus Torvalds EXPORT_SYMBOL(hci_send_sco);
20241da177e4SLinus Torvalds 
20251da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
20261da177e4SLinus Torvalds 
20271da177e4SLinus Torvalds /* HCI Connection scheduler */
20281da177e4SLinus Torvalds static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote)
20291da177e4SLinus Torvalds {
20301da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
20318035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
20321da177e4SLinus Torvalds 	int num = 0, min = ~0;
20331da177e4SLinus Torvalds 
20341da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
20351da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
2036bf4c6325SGustavo F. Padovan 
2037bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2038bf4c6325SGustavo F. Padovan 
2039bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2040769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
20411da177e4SLinus Torvalds 			continue;
2042769be974SMarcel Holtmann 
2043769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
2044769be974SMarcel Holtmann 			continue;
2045769be974SMarcel Holtmann 
20461da177e4SLinus Torvalds 		num++;
20471da177e4SLinus Torvalds 
20481da177e4SLinus Torvalds 		if (c->sent < min) {
20491da177e4SLinus Torvalds 			min  = c->sent;
20501da177e4SLinus Torvalds 			conn = c;
20511da177e4SLinus Torvalds 		}
205252087a79SLuiz Augusto von Dentz 
205352087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
205452087a79SLuiz Augusto von Dentz 			break;
20551da177e4SLinus Torvalds 	}
20561da177e4SLinus Torvalds 
2057bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2058bf4c6325SGustavo F. Padovan 
20591da177e4SLinus Torvalds 	if (conn) {
20606ed58ec5SVille Tervo 		int cnt, q;
20616ed58ec5SVille Tervo 
20626ed58ec5SVille Tervo 		switch (conn->type) {
20636ed58ec5SVille Tervo 		case ACL_LINK:
20646ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
20656ed58ec5SVille Tervo 			break;
20666ed58ec5SVille Tervo 		case SCO_LINK:
20676ed58ec5SVille Tervo 		case ESCO_LINK:
20686ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
20696ed58ec5SVille Tervo 			break;
20706ed58ec5SVille Tervo 		case LE_LINK:
20716ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
20726ed58ec5SVille Tervo 			break;
20736ed58ec5SVille Tervo 		default:
20746ed58ec5SVille Tervo 			cnt = 0;
20756ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
20766ed58ec5SVille Tervo 		}
20776ed58ec5SVille Tervo 
20786ed58ec5SVille Tervo 		q = cnt / num;
20791da177e4SLinus Torvalds 		*quote = q ? q : 1;
20801da177e4SLinus Torvalds 	} else
20811da177e4SLinus Torvalds 		*quote = 0;
20821da177e4SLinus Torvalds 
20831da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
20841da177e4SLinus Torvalds 	return conn;
20851da177e4SLinus Torvalds }
20861da177e4SLinus Torvalds 
2087bae1f5d9SVille Tervo static inline void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
20881da177e4SLinus Torvalds {
20891da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
20901da177e4SLinus Torvalds 	struct hci_conn *c;
20911da177e4SLinus Torvalds 
2092bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
20931da177e4SLinus Torvalds 
2094bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2095bf4c6325SGustavo F. Padovan 
20961da177e4SLinus Torvalds 	/* Kill stalled connections */
2097bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2098bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
2099bae1f5d9SVille Tervo 			BT_ERR("%s killing stalled connection %s",
21001da177e4SLinus Torvalds 				hdev->name, batostr(&c->dst));
21011da177e4SLinus Torvalds 			hci_acl_disconn(c, 0x13);
21021da177e4SLinus Torvalds 		}
21031da177e4SLinus Torvalds 	}
2104bf4c6325SGustavo F. Padovan 
2105bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
21061da177e4SLinus Torvalds }
21071da177e4SLinus Torvalds 
210873d80debSLuiz Augusto von Dentz static inline struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
210973d80debSLuiz Augusto von Dentz 						int *quote)
211073d80debSLuiz Augusto von Dentz {
211173d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
211273d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
211373d80debSLuiz Augusto von Dentz 	int num = 0, min = ~0, cur_prio = 0;
211473d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
211573d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
211673d80debSLuiz Augusto von Dentz 
211773d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
211873d80debSLuiz Augusto von Dentz 
2119bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2120bf4c6325SGustavo F. Padovan 
2121bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
212273d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
212373d80debSLuiz Augusto von Dentz 
212473d80debSLuiz Augusto von Dentz 		if (conn->type != type)
212573d80debSLuiz Augusto von Dentz 			continue;
212673d80debSLuiz Augusto von Dentz 
212773d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
212873d80debSLuiz Augusto von Dentz 			continue;
212973d80debSLuiz Augusto von Dentz 
213073d80debSLuiz Augusto von Dentz 		conn_num++;
213173d80debSLuiz Augusto von Dentz 
21328192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
213373d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
213473d80debSLuiz Augusto von Dentz 
213573d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
213673d80debSLuiz Augusto von Dentz 				continue;
213773d80debSLuiz Augusto von Dentz 
213873d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
213973d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
214073d80debSLuiz Augusto von Dentz 				continue;
214173d80debSLuiz Augusto von Dentz 
214273d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
214373d80debSLuiz Augusto von Dentz 				num = 0;
214473d80debSLuiz Augusto von Dentz 				min = ~0;
214573d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
214673d80debSLuiz Augusto von Dentz 			}
214773d80debSLuiz Augusto von Dentz 
214873d80debSLuiz Augusto von Dentz 			num++;
214973d80debSLuiz Augusto von Dentz 
215073d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
215173d80debSLuiz Augusto von Dentz 				min  = conn->sent;
215273d80debSLuiz Augusto von Dentz 				chan = tmp;
215373d80debSLuiz Augusto von Dentz 			}
215473d80debSLuiz Augusto von Dentz 		}
215573d80debSLuiz Augusto von Dentz 
215673d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
215773d80debSLuiz Augusto von Dentz 			break;
215873d80debSLuiz Augusto von Dentz 	}
215973d80debSLuiz Augusto von Dentz 
2160bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2161bf4c6325SGustavo F. Padovan 
216273d80debSLuiz Augusto von Dentz 	if (!chan)
216373d80debSLuiz Augusto von Dentz 		return NULL;
216473d80debSLuiz Augusto von Dentz 
216573d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
216673d80debSLuiz Augusto von Dentz 	case ACL_LINK:
216773d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
216873d80debSLuiz Augusto von Dentz 		break;
216973d80debSLuiz Augusto von Dentz 	case SCO_LINK:
217073d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
217173d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
217273d80debSLuiz Augusto von Dentz 		break;
217373d80debSLuiz Augusto von Dentz 	case LE_LINK:
217473d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
217573d80debSLuiz Augusto von Dentz 		break;
217673d80debSLuiz Augusto von Dentz 	default:
217773d80debSLuiz Augusto von Dentz 		cnt = 0;
217873d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
217973d80debSLuiz Augusto von Dentz 	}
218073d80debSLuiz Augusto von Dentz 
218173d80debSLuiz Augusto von Dentz 	q = cnt / num;
218273d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
218373d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
218473d80debSLuiz Augusto von Dentz 	return chan;
218573d80debSLuiz Augusto von Dentz }
218673d80debSLuiz Augusto von Dentz 
218702b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
218802b20f0bSLuiz Augusto von Dentz {
218902b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
219002b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
219102b20f0bSLuiz Augusto von Dentz 	int num = 0;
219202b20f0bSLuiz Augusto von Dentz 
219302b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
219402b20f0bSLuiz Augusto von Dentz 
2195bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2196bf4c6325SGustavo F. Padovan 
2197bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
219802b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
219902b20f0bSLuiz Augusto von Dentz 
220002b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
220102b20f0bSLuiz Augusto von Dentz 			continue;
220202b20f0bSLuiz Augusto von Dentz 
220302b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
220402b20f0bSLuiz Augusto von Dentz 			continue;
220502b20f0bSLuiz Augusto von Dentz 
220602b20f0bSLuiz Augusto von Dentz 		num++;
220702b20f0bSLuiz Augusto von Dentz 
22088192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
220902b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
221002b20f0bSLuiz Augusto von Dentz 
221102b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
221202b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
221302b20f0bSLuiz Augusto von Dentz 				continue;
221402b20f0bSLuiz Augusto von Dentz 			}
221502b20f0bSLuiz Augusto von Dentz 
221602b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
221702b20f0bSLuiz Augusto von Dentz 				continue;
221802b20f0bSLuiz Augusto von Dentz 
221902b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
222002b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
222102b20f0bSLuiz Augusto von Dentz 				continue;
222202b20f0bSLuiz Augusto von Dentz 
222302b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
222402b20f0bSLuiz Augusto von Dentz 
222502b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
222602b20f0bSLuiz Augusto von Dentz 								skb->priority);
222702b20f0bSLuiz Augusto von Dentz 		}
222802b20f0bSLuiz Augusto von Dentz 
222902b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
223002b20f0bSLuiz Augusto von Dentz 			break;
223102b20f0bSLuiz Augusto von Dentz 	}
2232bf4c6325SGustavo F. Padovan 
2233bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2234bf4c6325SGustavo F. Padovan 
223502b20f0bSLuiz Augusto von Dentz }
223602b20f0bSLuiz Augusto von Dentz 
22371da177e4SLinus Torvalds static inline void hci_sched_acl(struct hci_dev *hdev)
22381da177e4SLinus Torvalds {
223973d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
22401da177e4SLinus Torvalds 	struct sk_buff *skb;
22411da177e4SLinus Torvalds 	int quote;
224273d80debSLuiz Augusto von Dentz 	unsigned int cnt;
22431da177e4SLinus Torvalds 
22441da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
22451da177e4SLinus Torvalds 
224652087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ACL_LINK))
224752087a79SLuiz Augusto von Dentz 		return;
224852087a79SLuiz Augusto von Dentz 
22491da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
22501da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
22511da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
225282453021SS.Çağlar Onur 		if (!hdev->acl_cnt && time_after(jiffies, hdev->acl_last_tx + HZ * 45))
2253bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
22541da177e4SLinus Torvalds 	}
22551da177e4SLinus Torvalds 
225673d80debSLuiz Augusto von Dentz 	cnt = hdev->acl_cnt;
225704837f64SMarcel Holtmann 
225873d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
225973d80debSLuiz Augusto von Dentz 			(chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
2260ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
2261ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
226273d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
226373d80debSLuiz Augusto von Dentz 					skb->len, skb->priority);
226473d80debSLuiz Augusto von Dentz 
2265ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
2266ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
2267ec1cce24SLuiz Augusto von Dentz 				break;
2268ec1cce24SLuiz Augusto von Dentz 
2269ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
2270ec1cce24SLuiz Augusto von Dentz 
227173d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
227273d80debSLuiz Augusto von Dentz 						bt_cb(skb)->force_active);
227304837f64SMarcel Holtmann 
22741da177e4SLinus Torvalds 			hci_send_frame(skb);
22751da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
22761da177e4SLinus Torvalds 
22771da177e4SLinus Torvalds 			hdev->acl_cnt--;
227873d80debSLuiz Augusto von Dentz 			chan->sent++;
227973d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
22801da177e4SLinus Torvalds 		}
22811da177e4SLinus Torvalds 	}
228202b20f0bSLuiz Augusto von Dentz 
228302b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
228402b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
22851da177e4SLinus Torvalds }
22861da177e4SLinus Torvalds 
22871da177e4SLinus Torvalds /* Schedule SCO */
22881da177e4SLinus Torvalds static inline void hci_sched_sco(struct hci_dev *hdev)
22891da177e4SLinus Torvalds {
22901da177e4SLinus Torvalds 	struct hci_conn *conn;
22911da177e4SLinus Torvalds 	struct sk_buff *skb;
22921da177e4SLinus Torvalds 	int quote;
22931da177e4SLinus Torvalds 
22941da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
22951da177e4SLinus Torvalds 
229652087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
229752087a79SLuiz Augusto von Dentz 		return;
229852087a79SLuiz Augusto von Dentz 
22991da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
23001da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
23011da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
23021da177e4SLinus Torvalds 			hci_send_frame(skb);
23031da177e4SLinus Torvalds 
23041da177e4SLinus Torvalds 			conn->sent++;
23051da177e4SLinus Torvalds 			if (conn->sent == ~0)
23061da177e4SLinus Torvalds 				conn->sent = 0;
23071da177e4SLinus Torvalds 		}
23081da177e4SLinus Torvalds 	}
23091da177e4SLinus Torvalds }
23101da177e4SLinus Torvalds 
2311b6a0dc82SMarcel Holtmann static inline void hci_sched_esco(struct hci_dev *hdev)
2312b6a0dc82SMarcel Holtmann {
2313b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
2314b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
2315b6a0dc82SMarcel Holtmann 	int quote;
2316b6a0dc82SMarcel Holtmann 
2317b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
2318b6a0dc82SMarcel Holtmann 
231952087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
232052087a79SLuiz Augusto von Dentz 		return;
232152087a79SLuiz Augusto von Dentz 
2322b6a0dc82SMarcel Holtmann 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, &quote))) {
2323b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
2324b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
2325b6a0dc82SMarcel Holtmann 			hci_send_frame(skb);
2326b6a0dc82SMarcel Holtmann 
2327b6a0dc82SMarcel Holtmann 			conn->sent++;
2328b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
2329b6a0dc82SMarcel Holtmann 				conn->sent = 0;
2330b6a0dc82SMarcel Holtmann 		}
2331b6a0dc82SMarcel Holtmann 	}
2332b6a0dc82SMarcel Holtmann }
2333b6a0dc82SMarcel Holtmann 
23346ed58ec5SVille Tervo static inline void hci_sched_le(struct hci_dev *hdev)
23356ed58ec5SVille Tervo {
233673d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
23376ed58ec5SVille Tervo 	struct sk_buff *skb;
233802b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
23396ed58ec5SVille Tervo 
23406ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
23416ed58ec5SVille Tervo 
234252087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
234352087a79SLuiz Augusto von Dentz 		return;
234452087a79SLuiz Augusto von Dentz 
23456ed58ec5SVille Tervo 	if (!test_bit(HCI_RAW, &hdev->flags)) {
23466ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
23476ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
2348bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
23496ed58ec5SVille Tervo 				time_after(jiffies, hdev->le_last_tx + HZ * 45))
2350bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
23516ed58ec5SVille Tervo 	}
23526ed58ec5SVille Tervo 
23536ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
235402b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
235573d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
2356ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
2357ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
235873d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
235973d80debSLuiz Augusto von Dentz 					skb->len, skb->priority);
23606ed58ec5SVille Tervo 
2361ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
2362ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
2363ec1cce24SLuiz Augusto von Dentz 				break;
2364ec1cce24SLuiz Augusto von Dentz 
2365ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
2366ec1cce24SLuiz Augusto von Dentz 
23676ed58ec5SVille Tervo 			hci_send_frame(skb);
23686ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
23696ed58ec5SVille Tervo 
23706ed58ec5SVille Tervo 			cnt--;
237173d80debSLuiz Augusto von Dentz 			chan->sent++;
237273d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
23736ed58ec5SVille Tervo 		}
23746ed58ec5SVille Tervo 	}
237573d80debSLuiz Augusto von Dentz 
23766ed58ec5SVille Tervo 	if (hdev->le_pkts)
23776ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
23786ed58ec5SVille Tervo 	else
23796ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
238002b20f0bSLuiz Augusto von Dentz 
238102b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
238202b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
23836ed58ec5SVille Tervo }
23846ed58ec5SVille Tervo 
23853eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
23861da177e4SLinus Torvalds {
23873eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
23881da177e4SLinus Torvalds 	struct sk_buff *skb;
23891da177e4SLinus Torvalds 
23906ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
23916ed58ec5SVille Tervo 		hdev->sco_cnt, hdev->le_cnt);
23921da177e4SLinus Torvalds 
23931da177e4SLinus Torvalds 	/* Schedule queues and send stuff to HCI driver */
23941da177e4SLinus Torvalds 
23951da177e4SLinus Torvalds 	hci_sched_acl(hdev);
23961da177e4SLinus Torvalds 
23971da177e4SLinus Torvalds 	hci_sched_sco(hdev);
23981da177e4SLinus Torvalds 
2399b6a0dc82SMarcel Holtmann 	hci_sched_esco(hdev);
2400b6a0dc82SMarcel Holtmann 
24016ed58ec5SVille Tervo 	hci_sched_le(hdev);
24026ed58ec5SVille Tervo 
24031da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
24041da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
24051da177e4SLinus Torvalds 		hci_send_frame(skb);
24061da177e4SLinus Torvalds }
24071da177e4SLinus Torvalds 
240825985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
24091da177e4SLinus Torvalds 
24101da177e4SLinus Torvalds /* ACL data packet */
24111da177e4SLinus Torvalds static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
24121da177e4SLinus Torvalds {
24131da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
24141da177e4SLinus Torvalds 	struct hci_conn *conn;
24151da177e4SLinus Torvalds 	__u16 handle, flags;
24161da177e4SLinus Torvalds 
24171da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
24181da177e4SLinus Torvalds 
24191da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
24201da177e4SLinus Torvalds 	flags  = hci_flags(handle);
24211da177e4SLinus Torvalds 	handle = hci_handle(handle);
24221da177e4SLinus Torvalds 
24231da177e4SLinus Torvalds 	BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags);
24241da177e4SLinus Torvalds 
24251da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
24261da177e4SLinus Torvalds 
24271da177e4SLinus Torvalds 	hci_dev_lock(hdev);
24281da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
24291da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
24301da177e4SLinus Torvalds 
24311da177e4SLinus Torvalds 	if (conn) {
243265983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
243304837f64SMarcel Holtmann 
24341da177e4SLinus Torvalds 		/* Send to upper protocol */
2435686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
24361da177e4SLinus Torvalds 		return;
24371da177e4SLinus Torvalds 	} else {
24381da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
24391da177e4SLinus Torvalds 			hdev->name, handle);
24401da177e4SLinus Torvalds 	}
24411da177e4SLinus Torvalds 
24421da177e4SLinus Torvalds 	kfree_skb(skb);
24431da177e4SLinus Torvalds }
24441da177e4SLinus Torvalds 
24451da177e4SLinus Torvalds /* SCO data packet */
24461da177e4SLinus Torvalds static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
24471da177e4SLinus Torvalds {
24481da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
24491da177e4SLinus Torvalds 	struct hci_conn *conn;
24501da177e4SLinus Torvalds 	__u16 handle;
24511da177e4SLinus Torvalds 
24521da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
24531da177e4SLinus Torvalds 
24541da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
24551da177e4SLinus Torvalds 
24561da177e4SLinus Torvalds 	BT_DBG("%s len %d handle 0x%x", hdev->name, skb->len, handle);
24571da177e4SLinus Torvalds 
24581da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
24591da177e4SLinus Torvalds 
24601da177e4SLinus Torvalds 	hci_dev_lock(hdev);
24611da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
24621da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
24631da177e4SLinus Torvalds 
24641da177e4SLinus Torvalds 	if (conn) {
24651da177e4SLinus Torvalds 		/* Send to upper protocol */
2466686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
24671da177e4SLinus Torvalds 		return;
24681da177e4SLinus Torvalds 	} else {
24691da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
24701da177e4SLinus Torvalds 			hdev->name, handle);
24711da177e4SLinus Torvalds 	}
24721da177e4SLinus Torvalds 
24731da177e4SLinus Torvalds 	kfree_skb(skb);
24741da177e4SLinus Torvalds }
24751da177e4SLinus Torvalds 
2476b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
24771da177e4SLinus Torvalds {
2478b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
24791da177e4SLinus Torvalds 	struct sk_buff *skb;
24801da177e4SLinus Torvalds 
24811da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
24821da177e4SLinus Torvalds 
24831da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
24841da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
24851da177e4SLinus Torvalds 			/* Send copy to the sockets */
2486eec8d2bcSJohan Hedberg 			hci_send_to_sock(hdev, skb, NULL);
24871da177e4SLinus Torvalds 		}
24881da177e4SLinus Torvalds 
24891da177e4SLinus Torvalds 		if (test_bit(HCI_RAW, &hdev->flags)) {
24901da177e4SLinus Torvalds 			kfree_skb(skb);
24911da177e4SLinus Torvalds 			continue;
24921da177e4SLinus Torvalds 		}
24931da177e4SLinus Torvalds 
24941da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
24951da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
24960d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
24971da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
24981da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
24991da177e4SLinus Torvalds 				kfree_skb(skb);
25001da177e4SLinus Torvalds 				continue;
25013ff50b79SStephen Hemminger 			}
25021da177e4SLinus Torvalds 		}
25031da177e4SLinus Torvalds 
25041da177e4SLinus Torvalds 		/* Process frame */
25050d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
25061da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
2507b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
25081da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
25091da177e4SLinus Torvalds 			break;
25101da177e4SLinus Torvalds 
25111da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
25121da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
25131da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
25141da177e4SLinus Torvalds 			break;
25151da177e4SLinus Torvalds 
25161da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
25171da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
25181da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
25191da177e4SLinus Torvalds 			break;
25201da177e4SLinus Torvalds 
25211da177e4SLinus Torvalds 		default:
25221da177e4SLinus Torvalds 			kfree_skb(skb);
25231da177e4SLinus Torvalds 			break;
25241da177e4SLinus Torvalds 		}
25251da177e4SLinus Torvalds 	}
25261da177e4SLinus Torvalds }
25271da177e4SLinus Torvalds 
2528c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
25291da177e4SLinus Torvalds {
2530c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
25311da177e4SLinus Torvalds 	struct sk_buff *skb;
25321da177e4SLinus Torvalds 
25331da177e4SLinus Torvalds 	BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
25341da177e4SLinus Torvalds 
25351da177e4SLinus Torvalds 	/* Send queued commands */
25365a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
25375a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
25385a08ecceSAndrei Emeltchenko 		if (!skb)
25395a08ecceSAndrei Emeltchenko 			return;
25405a08ecceSAndrei Emeltchenko 
25411da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
25421da177e4SLinus Torvalds 
254370f23020SAndrei Emeltchenko 		hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC);
254470f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
25451da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
25461da177e4SLinus Torvalds 			hci_send_frame(skb);
25477bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
25487bdb8a5cSSzymon Janc 				del_timer(&hdev->cmd_timer);
25497bdb8a5cSSzymon Janc 			else
25506bd32326SVille Tervo 				mod_timer(&hdev->cmd_timer,
25516bd32326SVille Tervo 				  jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT));
25521da177e4SLinus Torvalds 		} else {
25531da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
2554c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
25551da177e4SLinus Torvalds 		}
25561da177e4SLinus Torvalds 	}
25571da177e4SLinus Torvalds }
25582519a1fcSAndre Guedes 
25592519a1fcSAndre Guedes int hci_do_inquiry(struct hci_dev *hdev, u8 length)
25602519a1fcSAndre Guedes {
25612519a1fcSAndre Guedes 	/* General inquiry access code (GIAC) */
25622519a1fcSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
25632519a1fcSAndre Guedes 	struct hci_cp_inquiry cp;
25642519a1fcSAndre Guedes 
25652519a1fcSAndre Guedes 	BT_DBG("%s", hdev->name);
25662519a1fcSAndre Guedes 
25672519a1fcSAndre Guedes 	if (test_bit(HCI_INQUIRY, &hdev->flags))
25682519a1fcSAndre Guedes 		return -EINPROGRESS;
25692519a1fcSAndre Guedes 
25702519a1fcSAndre Guedes 	memset(&cp, 0, sizeof(cp));
25712519a1fcSAndre Guedes 	memcpy(&cp.lap, lap, sizeof(cp.lap));
25722519a1fcSAndre Guedes 	cp.length  = length;
25732519a1fcSAndre Guedes 
25742519a1fcSAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
25752519a1fcSAndre Guedes }
2576023d5049SAndre Guedes 
2577023d5049SAndre Guedes int hci_cancel_inquiry(struct hci_dev *hdev)
2578023d5049SAndre Guedes {
2579023d5049SAndre Guedes 	BT_DBG("%s", hdev->name);
2580023d5049SAndre Guedes 
2581023d5049SAndre Guedes 	if (!test_bit(HCI_INQUIRY, &hdev->flags))
2582023d5049SAndre Guedes 		return -EPERM;
2583023d5049SAndre Guedes 
2584023d5049SAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL);
2585023d5049SAndre Guedes }
25867784d78fSAndrei Emeltchenko 
25877784d78fSAndrei Emeltchenko module_param(enable_hs, bool, 0644);
25887784d78fSAndrei Emeltchenko MODULE_PARM_DESC(enable_hs, "Enable High Speed");
2589