xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 3175405b)
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 {
360561aafbcSJohan Hedberg 	struct inquiry_cache *cache = &hdev->inq_cache;
361b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
3621da177e4SLinus Torvalds 
363561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
364561aafbcSJohan Hedberg 		list_del(&p->all);
365b57c1a56SJohan Hedberg 		kfree(p);
3661da177e4SLinus Torvalds 	}
367561aafbcSJohan Hedberg 
368561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
369561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
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 
379561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
3801da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
3811da177e4SLinus Torvalds 			return e;
3821da177e4SLinus Torvalds 	}
3831da177e4SLinus Torvalds 
384b57c1a56SJohan Hedberg 	return NULL;
385b57c1a56SJohan Hedberg }
386b57c1a56SJohan Hedberg 
387561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
388561aafbcSJohan Hedberg 							bdaddr_t *bdaddr)
389561aafbcSJohan Hedberg {
390561aafbcSJohan Hedberg 	struct inquiry_cache *cache = &hdev->inq_cache;
391561aafbcSJohan Hedberg 	struct inquiry_entry *e;
392561aafbcSJohan Hedberg 
393561aafbcSJohan Hedberg 	BT_DBG("cache %p, %s", cache, batostr(bdaddr));
394561aafbcSJohan Hedberg 
395561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
396561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
397561aafbcSJohan Hedberg 			return e;
398561aafbcSJohan Hedberg 	}
399561aafbcSJohan Hedberg 
400561aafbcSJohan Hedberg 	return NULL;
401561aafbcSJohan Hedberg }
402561aafbcSJohan Hedberg 
4033175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
404561aafbcSJohan Hedberg 							bool name_known)
4051da177e4SLinus Torvalds {
4061da177e4SLinus Torvalds 	struct inquiry_cache *cache = &hdev->inq_cache;
40770f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
4081da177e4SLinus Torvalds 
4091da177e4SLinus Torvalds 	BT_DBG("cache %p, %s", cache, batostr(&data->bdaddr));
4101da177e4SLinus Torvalds 
41170f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
412561aafbcSJohan Hedberg 	if (ie)
413561aafbcSJohan Hedberg 		goto update;
414561aafbcSJohan Hedberg 
4151da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
41670f23020SAndrei Emeltchenko 	ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
41770f23020SAndrei Emeltchenko 	if (!ie)
4183175405bSJohan Hedberg 		return false;
41970f23020SAndrei Emeltchenko 
420561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
421561aafbcSJohan Hedberg 
422561aafbcSJohan Hedberg 	if (name_known) {
423561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
424561aafbcSJohan Hedberg 	} else {
425561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
426561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
427561aafbcSJohan Hedberg 	}
428561aafbcSJohan Hedberg 
429561aafbcSJohan Hedberg update:
430561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
431561aafbcSJohan Hedberg 					ie->name_state != NAME_PENDING) {
432561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
433561aafbcSJohan Hedberg 		list_del(&ie->list);
4341da177e4SLinus Torvalds 	}
4351da177e4SLinus Torvalds 
43670f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
43770f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
4381da177e4SLinus Torvalds 	cache->timestamp = jiffies;
4393175405bSJohan Hedberg 
4403175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
4413175405bSJohan Hedberg 		return false;
4423175405bSJohan Hedberg 
4433175405bSJohan Hedberg 	return true;
4441da177e4SLinus Torvalds }
4451da177e4SLinus Torvalds 
4461da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
4471da177e4SLinus Torvalds {
4481da177e4SLinus Torvalds 	struct inquiry_cache *cache = &hdev->inq_cache;
4491da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
4501da177e4SLinus Torvalds 	struct inquiry_entry *e;
4511da177e4SLinus Torvalds 	int copied = 0;
4521da177e4SLinus Torvalds 
453561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
4541da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
455b57c1a56SJohan Hedberg 
456b57c1a56SJohan Hedberg 		if (copied >= num)
457b57c1a56SJohan Hedberg 			break;
458b57c1a56SJohan Hedberg 
4591da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
4601da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
4611da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
4621da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
4631da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
4641da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
465b57c1a56SJohan Hedberg 
4661da177e4SLinus Torvalds 		info++;
467b57c1a56SJohan Hedberg 		copied++;
4681da177e4SLinus Torvalds 	}
4691da177e4SLinus Torvalds 
4701da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
4711da177e4SLinus Torvalds 	return copied;
4721da177e4SLinus Torvalds }
4731da177e4SLinus Torvalds 
4741da177e4SLinus Torvalds static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
4751da177e4SLinus Torvalds {
4761da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
4771da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
4781da177e4SLinus Torvalds 
4791da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
4801da177e4SLinus Torvalds 
4811da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
4821da177e4SLinus Torvalds 		return;
4831da177e4SLinus Torvalds 
4841da177e4SLinus Torvalds 	/* Start Inquiry */
4851da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
4861da177e4SLinus Torvalds 	cp.length  = ir->length;
4871da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
488a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
4891da177e4SLinus Torvalds }
4901da177e4SLinus Torvalds 
4911da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
4921da177e4SLinus Torvalds {
4931da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
4941da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
4951da177e4SLinus Torvalds 	struct hci_dev *hdev;
4961da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
4971da177e4SLinus Torvalds 	long timeo;
4981da177e4SLinus Torvalds 	__u8 *buf;
4991da177e4SLinus Torvalds 
5001da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
5011da177e4SLinus Torvalds 		return -EFAULT;
5021da177e4SLinus Torvalds 
5035a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
5045a08ecceSAndrei Emeltchenko 	if (!hdev)
5051da177e4SLinus Torvalds 		return -ENODEV;
5061da177e4SLinus Torvalds 
50709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
5081da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
5091da177e4SLinus Torvalds 				inquiry_cache_empty(hdev) ||
5101da177e4SLinus Torvalds 				ir.flags & IREQ_CACHE_FLUSH) {
5111da177e4SLinus Torvalds 		inquiry_cache_flush(hdev);
5121da177e4SLinus Torvalds 		do_inquiry = 1;
5131da177e4SLinus Torvalds 	}
51409fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
5151da177e4SLinus Torvalds 
51604837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
51770f23020SAndrei Emeltchenko 
51870f23020SAndrei Emeltchenko 	if (do_inquiry) {
51970f23020SAndrei Emeltchenko 		err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo);
52070f23020SAndrei Emeltchenko 		if (err < 0)
5211da177e4SLinus Torvalds 			goto done;
52270f23020SAndrei Emeltchenko 	}
5231da177e4SLinus Torvalds 
5241da177e4SLinus Torvalds 	/* for unlimited number of responses we will use buffer with 255 entries */
5251da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
5261da177e4SLinus Torvalds 
5271da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
5281da177e4SLinus Torvalds 	 * copy it to the user space.
5291da177e4SLinus Torvalds 	 */
53070f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
53170f23020SAndrei Emeltchenko 	if (!buf) {
5321da177e4SLinus Torvalds 		err = -ENOMEM;
5331da177e4SLinus Torvalds 		goto done;
5341da177e4SLinus Torvalds 	}
5351da177e4SLinus Torvalds 
53609fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
5371da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
53809fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
5391da177e4SLinus Torvalds 
5401da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
5411da177e4SLinus Torvalds 
5421da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
5431da177e4SLinus Torvalds 		ptr += sizeof(ir);
5441da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
5451da177e4SLinus Torvalds 					ir.num_rsp))
5461da177e4SLinus Torvalds 			err = -EFAULT;
5471da177e4SLinus Torvalds 	} else
5481da177e4SLinus Torvalds 		err = -EFAULT;
5491da177e4SLinus Torvalds 
5501da177e4SLinus Torvalds 	kfree(buf);
5511da177e4SLinus Torvalds 
5521da177e4SLinus Torvalds done:
5531da177e4SLinus Torvalds 	hci_dev_put(hdev);
5541da177e4SLinus Torvalds 	return err;
5551da177e4SLinus Torvalds }
5561da177e4SLinus Torvalds 
5571da177e4SLinus Torvalds /* ---- HCI ioctl helpers ---- */
5581da177e4SLinus Torvalds 
5591da177e4SLinus Torvalds int hci_dev_open(__u16 dev)
5601da177e4SLinus Torvalds {
5611da177e4SLinus Torvalds 	struct hci_dev *hdev;
5621da177e4SLinus Torvalds 	int ret = 0;
5631da177e4SLinus Torvalds 
5645a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(dev);
5655a08ecceSAndrei Emeltchenko 	if (!hdev)
5661da177e4SLinus Torvalds 		return -ENODEV;
5671da177e4SLinus Torvalds 
5681da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
5691da177e4SLinus Torvalds 
5701da177e4SLinus Torvalds 	hci_req_lock(hdev);
5711da177e4SLinus Torvalds 
572611b30f7SMarcel Holtmann 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) {
573611b30f7SMarcel Holtmann 		ret = -ERFKILL;
574611b30f7SMarcel Holtmann 		goto done;
575611b30f7SMarcel Holtmann 	}
576611b30f7SMarcel Holtmann 
5771da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
5781da177e4SLinus Torvalds 		ret = -EALREADY;
5791da177e4SLinus Torvalds 		goto done;
5801da177e4SLinus Torvalds 	}
5811da177e4SLinus Torvalds 
5821da177e4SLinus Torvalds 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
5831da177e4SLinus Torvalds 		set_bit(HCI_RAW, &hdev->flags);
5841da177e4SLinus Torvalds 
58507e3b94aSAndrei Emeltchenko 	/* Treat all non BR/EDR controllers as raw devices if
58607e3b94aSAndrei Emeltchenko 	   enable_hs is not set */
58707e3b94aSAndrei Emeltchenko 	if (hdev->dev_type != HCI_BREDR && !enable_hs)
588943da25dSMarcel Holtmann 		set_bit(HCI_RAW, &hdev->flags);
589943da25dSMarcel Holtmann 
5901da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
5911da177e4SLinus Torvalds 		ret = -EIO;
5921da177e4SLinus Torvalds 		goto done;
5931da177e4SLinus Torvalds 	}
5941da177e4SLinus Torvalds 
5951da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
5961da177e4SLinus Torvalds 		atomic_set(&hdev->cmd_cnt, 1);
5971da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
598a5040efaSJohan Hedberg 		hdev->init_last_cmd = 0;
5991da177e4SLinus Torvalds 
60004837f64SMarcel Holtmann 		ret = __hci_request(hdev, hci_init_req, 0,
60104837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
6021da177e4SLinus Torvalds 
603eead27daSAndre Guedes 		if (lmp_host_le_capable(hdev))
6046ed58ec5SVille Tervo 			ret = __hci_request(hdev, hci_le_init_req, 0,
6056ed58ec5SVille Tervo 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
6066ed58ec5SVille Tervo 
6071da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
6081da177e4SLinus Torvalds 	}
6091da177e4SLinus Torvalds 
6101da177e4SLinus Torvalds 	if (!ret) {
6111da177e4SLinus Torvalds 		hci_dev_hold(hdev);
6121da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
6131da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
61456e5cb86SJohan Hedberg 		if (!test_bit(HCI_SETUP, &hdev->flags)) {
61509fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
616744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
61709fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
61856e5cb86SJohan Hedberg 		}
6191da177e4SLinus Torvalds 	} else {
6201da177e4SLinus Torvalds 		/* Init failed, cleanup */
6213eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
622c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
623b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
6241da177e4SLinus Torvalds 
6251da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
6261da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
6271da177e4SLinus Torvalds 
6281da177e4SLinus Torvalds 		if (hdev->flush)
6291da177e4SLinus Torvalds 			hdev->flush(hdev);
6301da177e4SLinus Torvalds 
6311da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
6321da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
6331da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
6341da177e4SLinus Torvalds 		}
6351da177e4SLinus Torvalds 
6361da177e4SLinus Torvalds 		hdev->close(hdev);
6371da177e4SLinus Torvalds 		hdev->flags = 0;
6381da177e4SLinus Torvalds 	}
6391da177e4SLinus Torvalds 
6401da177e4SLinus Torvalds done:
6411da177e4SLinus Torvalds 	hci_req_unlock(hdev);
6421da177e4SLinus Torvalds 	hci_dev_put(hdev);
6431da177e4SLinus Torvalds 	return ret;
6441da177e4SLinus Torvalds }
6451da177e4SLinus Torvalds 
6461da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
6471da177e4SLinus Torvalds {
6481da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
6491da177e4SLinus Torvalds 
6501da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
6511da177e4SLinus Torvalds 	hci_req_lock(hdev);
6521da177e4SLinus Torvalds 
6531da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
654b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
6551da177e4SLinus Torvalds 		hci_req_unlock(hdev);
6561da177e4SLinus Torvalds 		return 0;
6571da177e4SLinus Torvalds 	}
6581da177e4SLinus Torvalds 
6593eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
6603eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
661b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
6621da177e4SLinus Torvalds 
66316ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
664e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
66516ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
66616ab91abSJohan Hedberg 	}
66716ab91abSJohan Hedberg 
6683243553fSJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags))
669e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
6703243553fSJohan Hedberg 
6717d78525dSJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->flags))
6727d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
6737d78525dSJohan Hedberg 
67409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
6751da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
6761da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
67709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
6781da177e4SLinus Torvalds 
6791da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
6801da177e4SLinus Torvalds 
6811da177e4SLinus Torvalds 	if (hdev->flush)
6821da177e4SLinus Torvalds 		hdev->flush(hdev);
6831da177e4SLinus Torvalds 
6841da177e4SLinus Torvalds 	/* Reset device */
6851da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
6861da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
6871da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
6881da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
68904837f64SMarcel Holtmann 		__hci_request(hdev, hci_reset_req, 0,
690cad44c2bSGustavo F. Padovan 					msecs_to_jiffies(250));
6911da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
6921da177e4SLinus Torvalds 	}
6931da177e4SLinus Torvalds 
694c347b765SGustavo F. Padovan 	/* flush cmd  work */
695c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
6961da177e4SLinus Torvalds 
6971da177e4SLinus Torvalds 	/* Drop queues */
6981da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
6991da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
7001da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
7011da177e4SLinus Torvalds 
7021da177e4SLinus Torvalds 	/* Drop last sent command */
7031da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
704b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
7051da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
7061da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
7071da177e4SLinus Torvalds 	}
7081da177e4SLinus Torvalds 
7091da177e4SLinus Torvalds 	/* After this point our queues are empty
7101da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
7111da177e4SLinus Torvalds 	hdev->close(hdev);
7121da177e4SLinus Torvalds 
71309fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
714744cf19eSJohan Hedberg 	mgmt_powered(hdev, 0);
71509fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
7165add6af8SJohan Hedberg 
7171da177e4SLinus Torvalds 	/* Clear flags */
7181da177e4SLinus Torvalds 	hdev->flags = 0;
7191da177e4SLinus Torvalds 
7201da177e4SLinus Torvalds 	hci_req_unlock(hdev);
7211da177e4SLinus Torvalds 
7221da177e4SLinus Torvalds 	hci_dev_put(hdev);
7231da177e4SLinus Torvalds 	return 0;
7241da177e4SLinus Torvalds }
7251da177e4SLinus Torvalds 
7261da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
7271da177e4SLinus Torvalds {
7281da177e4SLinus Torvalds 	struct hci_dev *hdev;
7291da177e4SLinus Torvalds 	int err;
7301da177e4SLinus Torvalds 
73170f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
73270f23020SAndrei Emeltchenko 	if (!hdev)
7331da177e4SLinus Torvalds 		return -ENODEV;
7341da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
7351da177e4SLinus Torvalds 	hci_dev_put(hdev);
7361da177e4SLinus Torvalds 	return err;
7371da177e4SLinus Torvalds }
7381da177e4SLinus Torvalds 
7391da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
7401da177e4SLinus Torvalds {
7411da177e4SLinus Torvalds 	struct hci_dev *hdev;
7421da177e4SLinus Torvalds 	int ret = 0;
7431da177e4SLinus Torvalds 
74470f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
74570f23020SAndrei Emeltchenko 	if (!hdev)
7461da177e4SLinus Torvalds 		return -ENODEV;
7471da177e4SLinus Torvalds 
7481da177e4SLinus Torvalds 	hci_req_lock(hdev);
7491da177e4SLinus Torvalds 
7501da177e4SLinus Torvalds 	if (!test_bit(HCI_UP, &hdev->flags))
7511da177e4SLinus Torvalds 		goto done;
7521da177e4SLinus Torvalds 
7531da177e4SLinus Torvalds 	/* Drop queues */
7541da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
7551da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
7561da177e4SLinus Torvalds 
75709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
7581da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
7591da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
76009fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
7611da177e4SLinus Torvalds 
7621da177e4SLinus Torvalds 	if (hdev->flush)
7631da177e4SLinus Torvalds 		hdev->flush(hdev);
7641da177e4SLinus Torvalds 
7651da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
7666ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
7671da177e4SLinus Torvalds 
7681da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags))
76904837f64SMarcel Holtmann 		ret = __hci_request(hdev, hci_reset_req, 0,
77004837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
7711da177e4SLinus Torvalds 
7721da177e4SLinus Torvalds done:
7731da177e4SLinus Torvalds 	hci_req_unlock(hdev);
7741da177e4SLinus Torvalds 	hci_dev_put(hdev);
7751da177e4SLinus Torvalds 	return ret;
7761da177e4SLinus Torvalds }
7771da177e4SLinus Torvalds 
7781da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
7791da177e4SLinus Torvalds {
7801da177e4SLinus Torvalds 	struct hci_dev *hdev;
7811da177e4SLinus Torvalds 	int ret = 0;
7821da177e4SLinus Torvalds 
78370f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
78470f23020SAndrei Emeltchenko 	if (!hdev)
7851da177e4SLinus Torvalds 		return -ENODEV;
7861da177e4SLinus Torvalds 
7871da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
7881da177e4SLinus Torvalds 
7891da177e4SLinus Torvalds 	hci_dev_put(hdev);
7901da177e4SLinus Torvalds 
7911da177e4SLinus Torvalds 	return ret;
7921da177e4SLinus Torvalds }
7931da177e4SLinus Torvalds 
7941da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
7951da177e4SLinus Torvalds {
7961da177e4SLinus Torvalds 	struct hci_dev *hdev;
7971da177e4SLinus Torvalds 	struct hci_dev_req dr;
7981da177e4SLinus Torvalds 	int err = 0;
7991da177e4SLinus Torvalds 
8001da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
8011da177e4SLinus Torvalds 		return -EFAULT;
8021da177e4SLinus Torvalds 
80370f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
80470f23020SAndrei Emeltchenko 	if (!hdev)
8051da177e4SLinus Torvalds 		return -ENODEV;
8061da177e4SLinus Torvalds 
8071da177e4SLinus Torvalds 	switch (cmd) {
8081da177e4SLinus Torvalds 	case HCISETAUTH:
80904837f64SMarcel Holtmann 		err = hci_request(hdev, hci_auth_req, dr.dev_opt,
81004837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
8111da177e4SLinus Torvalds 		break;
8121da177e4SLinus Torvalds 
8131da177e4SLinus Torvalds 	case HCISETENCRYPT:
8141da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
8151da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
8161da177e4SLinus Torvalds 			break;
8171da177e4SLinus Torvalds 		}
8181da177e4SLinus Torvalds 
8191da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
8201da177e4SLinus Torvalds 			/* Auth must be enabled first */
82104837f64SMarcel Holtmann 			err = hci_request(hdev, hci_auth_req, dr.dev_opt,
82204837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
8231da177e4SLinus Torvalds 			if (err)
8241da177e4SLinus Torvalds 				break;
8251da177e4SLinus Torvalds 		}
8261da177e4SLinus Torvalds 
82704837f64SMarcel Holtmann 		err = hci_request(hdev, hci_encrypt_req, dr.dev_opt,
82804837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
8291da177e4SLinus Torvalds 		break;
8301da177e4SLinus Torvalds 
8311da177e4SLinus Torvalds 	case HCISETSCAN:
83204837f64SMarcel Holtmann 		err = hci_request(hdev, hci_scan_req, dr.dev_opt,
83304837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
8341da177e4SLinus Torvalds 		break;
8351da177e4SLinus Torvalds 
8361da177e4SLinus Torvalds 	case HCISETLINKPOL:
837e4e8e37cSMarcel Holtmann 		err = hci_request(hdev, hci_linkpol_req, dr.dev_opt,
838e4e8e37cSMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
8391da177e4SLinus Torvalds 		break;
8401da177e4SLinus Torvalds 
8411da177e4SLinus Torvalds 	case HCISETLINKMODE:
842e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
843e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
844e4e8e37cSMarcel Holtmann 		break;
845e4e8e37cSMarcel Holtmann 
846e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
847e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
8481da177e4SLinus Torvalds 		break;
8491da177e4SLinus Torvalds 
8501da177e4SLinus Torvalds 	case HCISETACLMTU:
8511da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
8521da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
8531da177e4SLinus Torvalds 		break;
8541da177e4SLinus Torvalds 
8551da177e4SLinus Torvalds 	case HCISETSCOMTU:
8561da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
8571da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
8581da177e4SLinus Torvalds 		break;
8591da177e4SLinus Torvalds 
8601da177e4SLinus Torvalds 	default:
8611da177e4SLinus Torvalds 		err = -EINVAL;
8621da177e4SLinus Torvalds 		break;
8631da177e4SLinus Torvalds 	}
864e4e8e37cSMarcel Holtmann 
8651da177e4SLinus Torvalds 	hci_dev_put(hdev);
8661da177e4SLinus Torvalds 	return err;
8671da177e4SLinus Torvalds }
8681da177e4SLinus Torvalds 
8691da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
8701da177e4SLinus Torvalds {
8718035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
8721da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
8731da177e4SLinus Torvalds 	struct hci_dev_req *dr;
8741da177e4SLinus Torvalds 	int n = 0, size, err;
8751da177e4SLinus Torvalds 	__u16 dev_num;
8761da177e4SLinus Torvalds 
8771da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
8781da177e4SLinus Torvalds 		return -EFAULT;
8791da177e4SLinus Torvalds 
8801da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
8811da177e4SLinus Torvalds 		return -EINVAL;
8821da177e4SLinus Torvalds 
8831da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
8841da177e4SLinus Torvalds 
88570f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
88670f23020SAndrei Emeltchenko 	if (!dl)
8871da177e4SLinus Torvalds 		return -ENOMEM;
8881da177e4SLinus Torvalds 
8891da177e4SLinus Torvalds 	dr = dl->dev_req;
8901da177e4SLinus Torvalds 
891f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
8928035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
8933243553fSJohan Hedberg 		if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags))
894e0f9309fSJohan Hedberg 			cancel_delayed_work(&hdev->power_off);
895c542a06cSJohan Hedberg 
896c542a06cSJohan Hedberg 		if (!test_bit(HCI_MGMT, &hdev->flags))
897c542a06cSJohan Hedberg 			set_bit(HCI_PAIRABLE, &hdev->flags);
898c542a06cSJohan Hedberg 
8991da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
9001da177e4SLinus Torvalds 		(dr + n)->dev_opt = hdev->flags;
901c542a06cSJohan Hedberg 
9021da177e4SLinus Torvalds 		if (++n >= dev_num)
9031da177e4SLinus Torvalds 			break;
9041da177e4SLinus Torvalds 	}
905f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
9061da177e4SLinus Torvalds 
9071da177e4SLinus Torvalds 	dl->dev_num = n;
9081da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
9091da177e4SLinus Torvalds 
9101da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
9111da177e4SLinus Torvalds 	kfree(dl);
9121da177e4SLinus Torvalds 
9131da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
9141da177e4SLinus Torvalds }
9151da177e4SLinus Torvalds 
9161da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
9171da177e4SLinus Torvalds {
9181da177e4SLinus Torvalds 	struct hci_dev *hdev;
9191da177e4SLinus Torvalds 	struct hci_dev_info di;
9201da177e4SLinus Torvalds 	int err = 0;
9211da177e4SLinus Torvalds 
9221da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
9231da177e4SLinus Torvalds 		return -EFAULT;
9241da177e4SLinus Torvalds 
92570f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
92670f23020SAndrei Emeltchenko 	if (!hdev)
9271da177e4SLinus Torvalds 		return -ENODEV;
9281da177e4SLinus Torvalds 
9293243553fSJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags))
9303243553fSJohan Hedberg 		cancel_delayed_work_sync(&hdev->power_off);
931ab81cbf9SJohan Hedberg 
932c542a06cSJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->flags))
933c542a06cSJohan Hedberg 		set_bit(HCI_PAIRABLE, &hdev->flags);
934c542a06cSJohan Hedberg 
9351da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
9361da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
937943da25dSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | (hdev->dev_type << 4);
9381da177e4SLinus Torvalds 	di.flags    = hdev->flags;
9391da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
9401da177e4SLinus Torvalds 	di.acl_mtu  = hdev->acl_mtu;
9411da177e4SLinus Torvalds 	di.acl_pkts = hdev->acl_pkts;
9421da177e4SLinus Torvalds 	di.sco_mtu  = hdev->sco_mtu;
9431da177e4SLinus Torvalds 	di.sco_pkts = hdev->sco_pkts;
9441da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
9451da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
9461da177e4SLinus Torvalds 
9471da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
9481da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
9491da177e4SLinus Torvalds 
9501da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
9511da177e4SLinus Torvalds 		err = -EFAULT;
9521da177e4SLinus Torvalds 
9531da177e4SLinus Torvalds 	hci_dev_put(hdev);
9541da177e4SLinus Torvalds 
9551da177e4SLinus Torvalds 	return err;
9561da177e4SLinus Torvalds }
9571da177e4SLinus Torvalds 
9581da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
9591da177e4SLinus Torvalds 
960611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
961611b30f7SMarcel Holtmann {
962611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
963611b30f7SMarcel Holtmann 
964611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
965611b30f7SMarcel Holtmann 
966611b30f7SMarcel Holtmann 	if (!blocked)
967611b30f7SMarcel Holtmann 		return 0;
968611b30f7SMarcel Holtmann 
969611b30f7SMarcel Holtmann 	hci_dev_do_close(hdev);
970611b30f7SMarcel Holtmann 
971611b30f7SMarcel Holtmann 	return 0;
972611b30f7SMarcel Holtmann }
973611b30f7SMarcel Holtmann 
974611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
975611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
976611b30f7SMarcel Holtmann };
977611b30f7SMarcel Holtmann 
9781da177e4SLinus Torvalds /* Alloc HCI device */
9791da177e4SLinus Torvalds struct hci_dev *hci_alloc_dev(void)
9801da177e4SLinus Torvalds {
9811da177e4SLinus Torvalds 	struct hci_dev *hdev;
9821da177e4SLinus Torvalds 
98325ea6db0SMarcel Holtmann 	hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
9841da177e4SLinus Torvalds 	if (!hdev)
9851da177e4SLinus Torvalds 		return NULL;
9861da177e4SLinus Torvalds 
9870ac7e700SDavid Herrmann 	hci_init_sysfs(hdev);
9881da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->driver_init);
9891da177e4SLinus Torvalds 
9901da177e4SLinus Torvalds 	return hdev;
9911da177e4SLinus Torvalds }
9921da177e4SLinus Torvalds EXPORT_SYMBOL(hci_alloc_dev);
9931da177e4SLinus Torvalds 
9941da177e4SLinus Torvalds /* Free HCI device */
9951da177e4SLinus Torvalds void hci_free_dev(struct hci_dev *hdev)
9961da177e4SLinus Torvalds {
9971da177e4SLinus Torvalds 	skb_queue_purge(&hdev->driver_init);
9981da177e4SLinus Torvalds 
999a91f2e39SMarcel Holtmann 	/* will free via device release */
1000a91f2e39SMarcel Holtmann 	put_device(&hdev->dev);
10011da177e4SLinus Torvalds }
10021da177e4SLinus Torvalds EXPORT_SYMBOL(hci_free_dev);
10031da177e4SLinus Torvalds 
1004ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
1005ab81cbf9SJohan Hedberg {
1006ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
1007ab81cbf9SJohan Hedberg 
1008ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1009ab81cbf9SJohan Hedberg 
1010ab81cbf9SJohan Hedberg 	if (hci_dev_open(hdev->id) < 0)
1011ab81cbf9SJohan Hedberg 		return;
1012ab81cbf9SJohan Hedberg 
1013ab81cbf9SJohan Hedberg 	if (test_bit(HCI_AUTO_OFF, &hdev->flags))
101480b7ab33SGustavo F. Padovan 		schedule_delayed_work(&hdev->power_off,
10153243553fSJohan Hedberg 					msecs_to_jiffies(AUTO_OFF_TIMEOUT));
1016ab81cbf9SJohan Hedberg 
1017ab81cbf9SJohan Hedberg 	if (test_and_clear_bit(HCI_SETUP, &hdev->flags))
1018744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
1019ab81cbf9SJohan Hedberg }
1020ab81cbf9SJohan Hedberg 
1021ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
1022ab81cbf9SJohan Hedberg {
10233243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
10243243553fSJohan Hedberg 							power_off.work);
1025ab81cbf9SJohan Hedberg 
1026ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1027ab81cbf9SJohan Hedberg 
10283243553fSJohan Hedberg 	clear_bit(HCI_AUTO_OFF, &hdev->flags);
10293243553fSJohan Hedberg 
1030ab81cbf9SJohan Hedberg 	hci_dev_close(hdev->id);
1031ab81cbf9SJohan Hedberg }
1032ab81cbf9SJohan Hedberg 
103316ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
103416ab91abSJohan Hedberg {
103516ab91abSJohan Hedberg 	struct hci_dev *hdev;
103616ab91abSJohan Hedberg 	u8 scan = SCAN_PAGE;
103716ab91abSJohan Hedberg 
103816ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
103916ab91abSJohan Hedberg 
104016ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
104116ab91abSJohan Hedberg 
104209fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
104316ab91abSJohan Hedberg 
104416ab91abSJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan);
104516ab91abSJohan Hedberg 
104616ab91abSJohan Hedberg 	hdev->discov_timeout = 0;
104716ab91abSJohan Hedberg 
104809fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
104916ab91abSJohan Hedberg }
105016ab91abSJohan Hedberg 
10512aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev)
10522aeb9a1aSJohan Hedberg {
10532aeb9a1aSJohan Hedberg 	struct list_head *p, *n;
10542aeb9a1aSJohan Hedberg 
10552aeb9a1aSJohan Hedberg 	list_for_each_safe(p, n, &hdev->uuids) {
10562aeb9a1aSJohan Hedberg 		struct bt_uuid *uuid;
10572aeb9a1aSJohan Hedberg 
10582aeb9a1aSJohan Hedberg 		uuid = list_entry(p, struct bt_uuid, list);
10592aeb9a1aSJohan Hedberg 
10602aeb9a1aSJohan Hedberg 		list_del(p);
10612aeb9a1aSJohan Hedberg 		kfree(uuid);
10622aeb9a1aSJohan Hedberg 	}
10632aeb9a1aSJohan Hedberg 
10642aeb9a1aSJohan Hedberg 	return 0;
10652aeb9a1aSJohan Hedberg }
10662aeb9a1aSJohan Hedberg 
106755ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev)
106855ed8ca1SJohan Hedberg {
106955ed8ca1SJohan Hedberg 	struct list_head *p, *n;
107055ed8ca1SJohan Hedberg 
107155ed8ca1SJohan Hedberg 	list_for_each_safe(p, n, &hdev->link_keys) {
107255ed8ca1SJohan Hedberg 		struct link_key *key;
107355ed8ca1SJohan Hedberg 
107455ed8ca1SJohan Hedberg 		key = list_entry(p, struct link_key, list);
107555ed8ca1SJohan Hedberg 
107655ed8ca1SJohan Hedberg 		list_del(p);
107755ed8ca1SJohan Hedberg 		kfree(key);
107855ed8ca1SJohan Hedberg 	}
107955ed8ca1SJohan Hedberg 
108055ed8ca1SJohan Hedberg 	return 0;
108155ed8ca1SJohan Hedberg }
108255ed8ca1SJohan Hedberg 
108355ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
108455ed8ca1SJohan Hedberg {
108555ed8ca1SJohan Hedberg 	struct link_key *k;
108655ed8ca1SJohan Hedberg 
10878035ded4SLuiz Augusto von Dentz 	list_for_each_entry(k, &hdev->link_keys, list)
108855ed8ca1SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0)
108955ed8ca1SJohan Hedberg 			return k;
109055ed8ca1SJohan Hedberg 
109155ed8ca1SJohan Hedberg 	return NULL;
109255ed8ca1SJohan Hedberg }
109355ed8ca1SJohan Hedberg 
1094d25e28abSJohan Hedberg static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1095d25e28abSJohan Hedberg 						u8 key_type, u8 old_key_type)
1096d25e28abSJohan Hedberg {
1097d25e28abSJohan Hedberg 	/* Legacy key */
1098d25e28abSJohan Hedberg 	if (key_type < 0x03)
1099d25e28abSJohan Hedberg 		return 1;
1100d25e28abSJohan Hedberg 
1101d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
1102d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
1103d25e28abSJohan Hedberg 		return 0;
1104d25e28abSJohan Hedberg 
1105d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
1106d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
1107d25e28abSJohan Hedberg 		return 0;
1108d25e28abSJohan Hedberg 
1109d25e28abSJohan Hedberg 	/* Security mode 3 case */
1110d25e28abSJohan Hedberg 	if (!conn)
1111d25e28abSJohan Hedberg 		return 1;
1112d25e28abSJohan Hedberg 
1113d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
1114d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
1115d25e28abSJohan Hedberg 		return 1;
1116d25e28abSJohan Hedberg 
1117d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
1118d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
1119d25e28abSJohan Hedberg 		return 1;
1120d25e28abSJohan Hedberg 
1121d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
1122d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
1123d25e28abSJohan Hedberg 		return 1;
1124d25e28abSJohan Hedberg 
1125d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
1126d25e28abSJohan Hedberg 	 * persistently */
1127d25e28abSJohan Hedberg 	return 0;
1128d25e28abSJohan Hedberg }
1129d25e28abSJohan Hedberg 
113075d262c2SVinicius Costa Gomes struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
113175d262c2SVinicius Costa Gomes {
113275d262c2SVinicius Costa Gomes 	struct link_key *k;
113375d262c2SVinicius Costa Gomes 
113475d262c2SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->link_keys, list) {
113575d262c2SVinicius Costa Gomes 		struct key_master_id *id;
113675d262c2SVinicius Costa Gomes 
113775d262c2SVinicius Costa Gomes 		if (k->type != HCI_LK_SMP_LTK)
113875d262c2SVinicius Costa Gomes 			continue;
113975d262c2SVinicius Costa Gomes 
114075d262c2SVinicius Costa Gomes 		if (k->dlen != sizeof(*id))
114175d262c2SVinicius Costa Gomes 			continue;
114275d262c2SVinicius Costa Gomes 
114375d262c2SVinicius Costa Gomes 		id = (void *) &k->data;
114475d262c2SVinicius Costa Gomes 		if (id->ediv == ediv &&
114575d262c2SVinicius Costa Gomes 				(memcmp(rand, id->rand, sizeof(id->rand)) == 0))
114675d262c2SVinicius Costa Gomes 			return k;
114775d262c2SVinicius Costa Gomes 	}
114875d262c2SVinicius Costa Gomes 
114975d262c2SVinicius Costa Gomes 	return NULL;
115075d262c2SVinicius Costa Gomes }
115175d262c2SVinicius Costa Gomes EXPORT_SYMBOL(hci_find_ltk);
115275d262c2SVinicius Costa Gomes 
115375d262c2SVinicius Costa Gomes struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
115475d262c2SVinicius Costa Gomes 					bdaddr_t *bdaddr, u8 type)
115575d262c2SVinicius Costa Gomes {
115675d262c2SVinicius Costa Gomes 	struct link_key *k;
115775d262c2SVinicius Costa Gomes 
115875d262c2SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->link_keys, list)
115975d262c2SVinicius Costa Gomes 		if (k->type == type && bacmp(bdaddr, &k->bdaddr) == 0)
116075d262c2SVinicius Costa Gomes 			return k;
116175d262c2SVinicius Costa Gomes 
116275d262c2SVinicius Costa Gomes 	return NULL;
116375d262c2SVinicius Costa Gomes }
116475d262c2SVinicius Costa Gomes EXPORT_SYMBOL(hci_find_link_key_type);
116575d262c2SVinicius Costa Gomes 
1166d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
1167d25e28abSJohan Hedberg 				bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
116855ed8ca1SJohan Hedberg {
116955ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
11704df378a1SJohan Hedberg 	u8 old_key_type, persistent;
117155ed8ca1SJohan Hedberg 
117255ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
117355ed8ca1SJohan Hedberg 	if (old_key) {
117455ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
117555ed8ca1SJohan Hedberg 		key = old_key;
117655ed8ca1SJohan Hedberg 	} else {
117712adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
117855ed8ca1SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
117955ed8ca1SJohan Hedberg 		if (!key)
118055ed8ca1SJohan Hedberg 			return -ENOMEM;
118155ed8ca1SJohan Hedberg 		list_add(&key->list, &hdev->link_keys);
118255ed8ca1SJohan Hedberg 	}
118355ed8ca1SJohan Hedberg 
118455ed8ca1SJohan Hedberg 	BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type);
118555ed8ca1SJohan Hedberg 
1186d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
1187d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
1188d25e28abSJohan Hedberg 	 * previous key */
1189d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
1190d25e28abSJohan Hedberg 					(!conn || conn->remote_auth == 0xff) &&
1191655fe6ecSJohan Hedberg 					old_key_type == 0xff) {
1192d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
1193655fe6ecSJohan Hedberg 		if (conn)
1194655fe6ecSJohan Hedberg 			conn->key_type = type;
1195655fe6ecSJohan Hedberg 	}
1196d25e28abSJohan Hedberg 
119755ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
119855ed8ca1SJohan Hedberg 	memcpy(key->val, val, 16);
119955ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
120055ed8ca1SJohan Hedberg 
1201b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
120255ed8ca1SJohan Hedberg 		key->type = old_key_type;
12034748fed2SJohan Hedberg 	else
12044748fed2SJohan Hedberg 		key->type = type;
12054748fed2SJohan Hedberg 
12064df378a1SJohan Hedberg 	if (!new_key)
12074df378a1SJohan Hedberg 		return 0;
12084df378a1SJohan Hedberg 
12094df378a1SJohan Hedberg 	persistent = hci_persistent_key(hdev, conn, type, old_key_type);
12104df378a1SJohan Hedberg 
1211744cf19eSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
12124df378a1SJohan Hedberg 
12134df378a1SJohan Hedberg 	if (!persistent) {
12144df378a1SJohan Hedberg 		list_del(&key->list);
12154df378a1SJohan Hedberg 		kfree(key);
12164df378a1SJohan Hedberg 	}
121755ed8ca1SJohan Hedberg 
121855ed8ca1SJohan Hedberg 	return 0;
121955ed8ca1SJohan Hedberg }
122055ed8ca1SJohan Hedberg 
122175d262c2SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
1222726b4ffcSVinicius Costa Gomes 			u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16])
122375d262c2SVinicius Costa Gomes {
122475d262c2SVinicius Costa Gomes 	struct link_key *key, *old_key;
122575d262c2SVinicius Costa Gomes 	struct key_master_id *id;
122675d262c2SVinicius Costa Gomes 	u8 old_key_type;
122775d262c2SVinicius Costa Gomes 
122875d262c2SVinicius Costa Gomes 	BT_DBG("%s addr %s", hdev->name, batostr(bdaddr));
122975d262c2SVinicius Costa Gomes 
123075d262c2SVinicius Costa Gomes 	old_key = hci_find_link_key_type(hdev, bdaddr, HCI_LK_SMP_LTK);
123175d262c2SVinicius Costa Gomes 	if (old_key) {
123275d262c2SVinicius Costa Gomes 		key = old_key;
123375d262c2SVinicius Costa Gomes 		old_key_type = old_key->type;
123475d262c2SVinicius Costa Gomes 	} else {
123575d262c2SVinicius Costa Gomes 		key = kzalloc(sizeof(*key) + sizeof(*id), GFP_ATOMIC);
123675d262c2SVinicius Costa Gomes 		if (!key)
123775d262c2SVinicius Costa Gomes 			return -ENOMEM;
123875d262c2SVinicius Costa Gomes 		list_add(&key->list, &hdev->link_keys);
123975d262c2SVinicius Costa Gomes 		old_key_type = 0xff;
124075d262c2SVinicius Costa Gomes 	}
124175d262c2SVinicius Costa Gomes 
124275d262c2SVinicius Costa Gomes 	key->dlen = sizeof(*id);
124375d262c2SVinicius Costa Gomes 
124475d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
124575d262c2SVinicius Costa Gomes 	memcpy(key->val, ltk, sizeof(key->val));
124675d262c2SVinicius Costa Gomes 	key->type = HCI_LK_SMP_LTK;
1247726b4ffcSVinicius Costa Gomes 	key->pin_len = key_size;
124875d262c2SVinicius Costa Gomes 
124975d262c2SVinicius Costa Gomes 	id = (void *) &key->data;
125075d262c2SVinicius Costa Gomes 	id->ediv = ediv;
125175d262c2SVinicius Costa Gomes 	memcpy(id->rand, rand, sizeof(id->rand));
125275d262c2SVinicius Costa Gomes 
125375d262c2SVinicius Costa Gomes 	if (new_key)
1254744cf19eSJohan Hedberg 		mgmt_new_link_key(hdev, key, old_key_type);
125575d262c2SVinicius Costa Gomes 
125675d262c2SVinicius Costa Gomes 	return 0;
125775d262c2SVinicius Costa Gomes }
125875d262c2SVinicius Costa Gomes 
125955ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
126055ed8ca1SJohan Hedberg {
126155ed8ca1SJohan Hedberg 	struct link_key *key;
126255ed8ca1SJohan Hedberg 
126355ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
126455ed8ca1SJohan Hedberg 	if (!key)
126555ed8ca1SJohan Hedberg 		return -ENOENT;
126655ed8ca1SJohan Hedberg 
126755ed8ca1SJohan Hedberg 	BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
126855ed8ca1SJohan Hedberg 
126955ed8ca1SJohan Hedberg 	list_del(&key->list);
127055ed8ca1SJohan Hedberg 	kfree(key);
127155ed8ca1SJohan Hedberg 
127255ed8ca1SJohan Hedberg 	return 0;
127355ed8ca1SJohan Hedberg }
127455ed8ca1SJohan Hedberg 
12756bd32326SVille Tervo /* HCI command timer function */
12766bd32326SVille Tervo static void hci_cmd_timer(unsigned long arg)
12776bd32326SVille Tervo {
12786bd32326SVille Tervo 	struct hci_dev *hdev = (void *) arg;
12796bd32326SVille Tervo 
12806bd32326SVille Tervo 	BT_ERR("%s command tx timeout", hdev->name);
12816bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
1282c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
12836bd32326SVille Tervo }
12846bd32326SVille Tervo 
12852763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
12862763eda6SSzymon Janc 							bdaddr_t *bdaddr)
12872763eda6SSzymon Janc {
12882763eda6SSzymon Janc 	struct oob_data *data;
12892763eda6SSzymon Janc 
12902763eda6SSzymon Janc 	list_for_each_entry(data, &hdev->remote_oob_data, list)
12912763eda6SSzymon Janc 		if (bacmp(bdaddr, &data->bdaddr) == 0)
12922763eda6SSzymon Janc 			return data;
12932763eda6SSzymon Janc 
12942763eda6SSzymon Janc 	return NULL;
12952763eda6SSzymon Janc }
12962763eda6SSzymon Janc 
12972763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
12982763eda6SSzymon Janc {
12992763eda6SSzymon Janc 	struct oob_data *data;
13002763eda6SSzymon Janc 
13012763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
13022763eda6SSzymon Janc 	if (!data)
13032763eda6SSzymon Janc 		return -ENOENT;
13042763eda6SSzymon Janc 
13052763eda6SSzymon Janc 	BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
13062763eda6SSzymon Janc 
13072763eda6SSzymon Janc 	list_del(&data->list);
13082763eda6SSzymon Janc 	kfree(data);
13092763eda6SSzymon Janc 
13102763eda6SSzymon Janc 	return 0;
13112763eda6SSzymon Janc }
13122763eda6SSzymon Janc 
13132763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev)
13142763eda6SSzymon Janc {
13152763eda6SSzymon Janc 	struct oob_data *data, *n;
13162763eda6SSzymon Janc 
13172763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
13182763eda6SSzymon Janc 		list_del(&data->list);
13192763eda6SSzymon Janc 		kfree(data);
13202763eda6SSzymon Janc 	}
13212763eda6SSzymon Janc 
13222763eda6SSzymon Janc 	return 0;
13232763eda6SSzymon Janc }
13242763eda6SSzymon Janc 
13252763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
13262763eda6SSzymon Janc 								u8 *randomizer)
13272763eda6SSzymon Janc {
13282763eda6SSzymon Janc 	struct oob_data *data;
13292763eda6SSzymon Janc 
13302763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
13312763eda6SSzymon Janc 
13322763eda6SSzymon Janc 	if (!data) {
13332763eda6SSzymon Janc 		data = kmalloc(sizeof(*data), GFP_ATOMIC);
13342763eda6SSzymon Janc 		if (!data)
13352763eda6SSzymon Janc 			return -ENOMEM;
13362763eda6SSzymon Janc 
13372763eda6SSzymon Janc 		bacpy(&data->bdaddr, bdaddr);
13382763eda6SSzymon Janc 		list_add(&data->list, &hdev->remote_oob_data);
13392763eda6SSzymon Janc 	}
13402763eda6SSzymon Janc 
13412763eda6SSzymon Janc 	memcpy(data->hash, hash, sizeof(data->hash));
13422763eda6SSzymon Janc 	memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
13432763eda6SSzymon Janc 
13442763eda6SSzymon Janc 	BT_DBG("%s for %s", hdev->name, batostr(bdaddr));
13452763eda6SSzymon Janc 
13462763eda6SSzymon Janc 	return 0;
13472763eda6SSzymon Janc }
13482763eda6SSzymon Janc 
1349b2a66aadSAntti Julku struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev,
1350b2a66aadSAntti Julku 						bdaddr_t *bdaddr)
1351b2a66aadSAntti Julku {
1352b2a66aadSAntti Julku 	struct bdaddr_list *b;
1353b2a66aadSAntti Julku 
13548035ded4SLuiz Augusto von Dentz 	list_for_each_entry(b, &hdev->blacklist, list)
1355b2a66aadSAntti Julku 		if (bacmp(bdaddr, &b->bdaddr) == 0)
1356b2a66aadSAntti Julku 			return b;
1357b2a66aadSAntti Julku 
1358b2a66aadSAntti Julku 	return NULL;
1359b2a66aadSAntti Julku }
1360b2a66aadSAntti Julku 
1361b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev)
1362b2a66aadSAntti Julku {
1363b2a66aadSAntti Julku 	struct list_head *p, *n;
1364b2a66aadSAntti Julku 
1365b2a66aadSAntti Julku 	list_for_each_safe(p, n, &hdev->blacklist) {
1366b2a66aadSAntti Julku 		struct bdaddr_list *b;
1367b2a66aadSAntti Julku 
1368b2a66aadSAntti Julku 		b = list_entry(p, struct bdaddr_list, list);
1369b2a66aadSAntti Julku 
1370b2a66aadSAntti Julku 		list_del(p);
1371b2a66aadSAntti Julku 		kfree(b);
1372b2a66aadSAntti Julku 	}
1373b2a66aadSAntti Julku 
1374b2a66aadSAntti Julku 	return 0;
1375b2a66aadSAntti Julku }
1376b2a66aadSAntti Julku 
1377b2a66aadSAntti Julku int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr)
1378b2a66aadSAntti Julku {
1379b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1380b2a66aadSAntti Julku 
1381b2a66aadSAntti Julku 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
1382b2a66aadSAntti Julku 		return -EBADF;
1383b2a66aadSAntti Julku 
13845e762444SAntti Julku 	if (hci_blacklist_lookup(hdev, bdaddr))
13855e762444SAntti Julku 		return -EEXIST;
1386b2a66aadSAntti Julku 
1387b2a66aadSAntti Julku 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
13885e762444SAntti Julku 	if (!entry)
13895e762444SAntti Julku 		return -ENOMEM;
1390b2a66aadSAntti Julku 
1391b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
1392b2a66aadSAntti Julku 
1393b2a66aadSAntti Julku 	list_add(&entry->list, &hdev->blacklist);
1394b2a66aadSAntti Julku 
1395744cf19eSJohan Hedberg 	return mgmt_device_blocked(hdev, bdaddr);
1396b2a66aadSAntti Julku }
1397b2a66aadSAntti Julku 
1398b2a66aadSAntti Julku int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr)
1399b2a66aadSAntti Julku {
1400b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1401b2a66aadSAntti Julku 
14021ec918ceSSzymon Janc 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
14035e762444SAntti Julku 		return hci_blacklist_clear(hdev);
1404b2a66aadSAntti Julku 
1405b2a66aadSAntti Julku 	entry = hci_blacklist_lookup(hdev, bdaddr);
14061ec918ceSSzymon Janc 	if (!entry)
14075e762444SAntti Julku 		return -ENOENT;
1408b2a66aadSAntti Julku 
1409b2a66aadSAntti Julku 	list_del(&entry->list);
1410b2a66aadSAntti Julku 	kfree(entry);
1411b2a66aadSAntti Julku 
1412744cf19eSJohan Hedberg 	return mgmt_device_unblocked(hdev, bdaddr);
1413b2a66aadSAntti Julku }
1414b2a66aadSAntti Julku 
1415db323f2fSGustavo F. Padovan static void hci_clear_adv_cache(struct work_struct *work)
141635815085SAndre Guedes {
1417db323f2fSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev,
1418db323f2fSGustavo F. Padovan 							adv_work.work);
141935815085SAndre Guedes 
142035815085SAndre Guedes 	hci_dev_lock(hdev);
142135815085SAndre Guedes 
142235815085SAndre Guedes 	hci_adv_entries_clear(hdev);
142335815085SAndre Guedes 
142435815085SAndre Guedes 	hci_dev_unlock(hdev);
142535815085SAndre Guedes }
142635815085SAndre Guedes 
142776c8686fSAndre Guedes int hci_adv_entries_clear(struct hci_dev *hdev)
142876c8686fSAndre Guedes {
142976c8686fSAndre Guedes 	struct adv_entry *entry, *tmp;
143076c8686fSAndre Guedes 
143176c8686fSAndre Guedes 	list_for_each_entry_safe(entry, tmp, &hdev->adv_entries, list) {
143276c8686fSAndre Guedes 		list_del(&entry->list);
143376c8686fSAndre Guedes 		kfree(entry);
143476c8686fSAndre Guedes 	}
143576c8686fSAndre Guedes 
143676c8686fSAndre Guedes 	BT_DBG("%s adv cache cleared", hdev->name);
143776c8686fSAndre Guedes 
143876c8686fSAndre Guedes 	return 0;
143976c8686fSAndre Guedes }
144076c8686fSAndre Guedes 
144176c8686fSAndre Guedes struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr)
144276c8686fSAndre Guedes {
144376c8686fSAndre Guedes 	struct adv_entry *entry;
144476c8686fSAndre Guedes 
144576c8686fSAndre Guedes 	list_for_each_entry(entry, &hdev->adv_entries, list)
144676c8686fSAndre Guedes 		if (bacmp(bdaddr, &entry->bdaddr) == 0)
144776c8686fSAndre Guedes 			return entry;
144876c8686fSAndre Guedes 
144976c8686fSAndre Guedes 	return NULL;
145076c8686fSAndre Guedes }
145176c8686fSAndre Guedes 
145276c8686fSAndre Guedes static inline int is_connectable_adv(u8 evt_type)
145376c8686fSAndre Guedes {
145476c8686fSAndre Guedes 	if (evt_type == ADV_IND || evt_type == ADV_DIRECT_IND)
145576c8686fSAndre Guedes 		return 1;
145676c8686fSAndre Guedes 
145776c8686fSAndre Guedes 	return 0;
145876c8686fSAndre Guedes }
145976c8686fSAndre Guedes 
146076c8686fSAndre Guedes int hci_add_adv_entry(struct hci_dev *hdev,
146176c8686fSAndre Guedes 					struct hci_ev_le_advertising_info *ev)
146276c8686fSAndre Guedes {
146376c8686fSAndre Guedes 	struct adv_entry *entry;
146476c8686fSAndre Guedes 
146576c8686fSAndre Guedes 	if (!is_connectable_adv(ev->evt_type))
146676c8686fSAndre Guedes 		return -EINVAL;
146776c8686fSAndre Guedes 
146876c8686fSAndre Guedes 	/* Only new entries should be added to adv_entries. So, if
146976c8686fSAndre Guedes 	 * bdaddr was found, don't add it. */
147076c8686fSAndre Guedes 	if (hci_find_adv_entry(hdev, &ev->bdaddr))
147176c8686fSAndre Guedes 		return 0;
147276c8686fSAndre Guedes 
147376c8686fSAndre Guedes 	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
147476c8686fSAndre Guedes 	if (!entry)
147576c8686fSAndre Guedes 		return -ENOMEM;
147676c8686fSAndre Guedes 
147776c8686fSAndre Guedes 	bacpy(&entry->bdaddr, &ev->bdaddr);
147876c8686fSAndre Guedes 	entry->bdaddr_type = ev->bdaddr_type;
147976c8686fSAndre Guedes 
148076c8686fSAndre Guedes 	list_add(&entry->list, &hdev->adv_entries);
148176c8686fSAndre Guedes 
148276c8686fSAndre Guedes 	BT_DBG("%s adv entry added: address %s type %u", hdev->name,
148376c8686fSAndre Guedes 				batostr(&entry->bdaddr), entry->bdaddr_type);
148476c8686fSAndre Guedes 
148576c8686fSAndre Guedes 	return 0;
148676c8686fSAndre Guedes }
148776c8686fSAndre Guedes 
14881da177e4SLinus Torvalds /* Register HCI device */
14891da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
14901da177e4SLinus Torvalds {
14911da177e4SLinus Torvalds 	struct list_head *head = &hci_dev_list, *p;
149208add513SMat Martineau 	int i, id, error;
14931da177e4SLinus Torvalds 
1494c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d owner %p", hdev, hdev->name,
1495c13854ceSMarcel Holtmann 						hdev->bus, hdev->owner);
14961da177e4SLinus Torvalds 
14971da177e4SLinus Torvalds 	if (!hdev->open || !hdev->close || !hdev->destruct)
14981da177e4SLinus Torvalds 		return -EINVAL;
14991da177e4SLinus Torvalds 
150008add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
150108add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
150208add513SMat Martineau 	 */
150308add513SMat Martineau 	id = (hdev->dev_type == HCI_BREDR) ? 0 : 1;
150408add513SMat Martineau 
1505f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
15061da177e4SLinus Torvalds 
15071da177e4SLinus Torvalds 	/* Find first available device id */
15081da177e4SLinus Torvalds 	list_for_each(p, &hci_dev_list) {
15091da177e4SLinus Torvalds 		if (list_entry(p, struct hci_dev, list)->id != id)
15101da177e4SLinus Torvalds 			break;
15111da177e4SLinus Torvalds 		head = p; id++;
15121da177e4SLinus Torvalds 	}
15131da177e4SLinus Torvalds 
15141da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
15151da177e4SLinus Torvalds 	hdev->id = id;
1516c6feeb28SAndrei Emeltchenko 	list_add_tail(&hdev->list, head);
15171da177e4SLinus Torvalds 
15181da177e4SLinus Torvalds 	atomic_set(&hdev->refcnt, 1);
151909fd0de5SGustavo F. Padovan 	mutex_init(&hdev->lock);
15201da177e4SLinus Torvalds 
15211da177e4SLinus Torvalds 	hdev->flags = 0;
1522d23264a8SAndre Guedes 	hdev->dev_flags = 0;
15231da177e4SLinus Torvalds 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
15245b7f9909SMarcel Holtmann 	hdev->esco_type = (ESCO_HV1);
15251da177e4SLinus Torvalds 	hdev->link_mode = (HCI_LM_ACCEPT);
152617fa4b9dSJohan Hedberg 	hdev->io_capability = 0x03; /* No Input No Output */
15271da177e4SLinus Torvalds 
152804837f64SMarcel Holtmann 	hdev->idle_timeout = 0;
152904837f64SMarcel Holtmann 	hdev->sniff_max_interval = 800;
153004837f64SMarcel Holtmann 	hdev->sniff_min_interval = 80;
153104837f64SMarcel Holtmann 
1532b78752ccSMarcel Holtmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
1533c347b765SGustavo F. Padovan 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
15343eff45eaSGustavo F. Padovan 	INIT_WORK(&hdev->tx_work, hci_tx_work);
1535b78752ccSMarcel Holtmann 
15361da177e4SLinus Torvalds 
15371da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->rx_q);
15381da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->cmd_q);
15391da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->raw_q);
15401da177e4SLinus Torvalds 
15416bd32326SVille Tervo 	setup_timer(&hdev->cmd_timer, hci_cmd_timer, (unsigned long) hdev);
15426bd32326SVille Tervo 
1543cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
1544ef222013SMarcel Holtmann 		hdev->reassembly[i] = NULL;
1545ef222013SMarcel Holtmann 
15461da177e4SLinus Torvalds 	init_waitqueue_head(&hdev->req_wait_q);
1547a6a67efdSThomas Gleixner 	mutex_init(&hdev->req_lock);
15481da177e4SLinus Torvalds 
15491da177e4SLinus Torvalds 	inquiry_cache_init(hdev);
15501da177e4SLinus Torvalds 
15511da177e4SLinus Torvalds 	hci_conn_hash_init(hdev);
15521da177e4SLinus Torvalds 
15532e58ef3eSJohan Hedberg 	INIT_LIST_HEAD(&hdev->mgmt_pending);
15542e58ef3eSJohan Hedberg 
1555ea4bd8baSDavid Miller 	INIT_LIST_HEAD(&hdev->blacklist);
1556f0358568SJohan Hedberg 
15572aeb9a1aSJohan Hedberg 	INIT_LIST_HEAD(&hdev->uuids);
15582aeb9a1aSJohan Hedberg 
155955ed8ca1SJohan Hedberg 	INIT_LIST_HEAD(&hdev->link_keys);
156055ed8ca1SJohan Hedberg 
15612763eda6SSzymon Janc 	INIT_LIST_HEAD(&hdev->remote_oob_data);
15622763eda6SSzymon Janc 
156376c8686fSAndre Guedes 	INIT_LIST_HEAD(&hdev->adv_entries);
156476c8686fSAndre Guedes 
1565db323f2fSGustavo F. Padovan 	INIT_DELAYED_WORK(&hdev->adv_work, hci_clear_adv_cache);
1566ab81cbf9SJohan Hedberg 	INIT_WORK(&hdev->power_on, hci_power_on);
15673243553fSJohan Hedberg 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
1568ab81cbf9SJohan Hedberg 
156916ab91abSJohan Hedberg 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
157016ab91abSJohan Hedberg 
15711da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
15721da177e4SLinus Torvalds 
15731da177e4SLinus Torvalds 	atomic_set(&hdev->promisc, 0);
15741da177e4SLinus Torvalds 
1575f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
15761da177e4SLinus Torvalds 
157732845eb1SGustavo F. Padovan 	hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND |
157832845eb1SGustavo F. Padovan 							WQ_MEM_RECLAIM, 1);
157933ca954dSDavid Herrmann 	if (!hdev->workqueue) {
158033ca954dSDavid Herrmann 		error = -ENOMEM;
158133ca954dSDavid Herrmann 		goto err;
158233ca954dSDavid Herrmann 	}
1583f48fd9c8SMarcel Holtmann 
158433ca954dSDavid Herrmann 	error = hci_add_sysfs(hdev);
158533ca954dSDavid Herrmann 	if (error < 0)
158633ca954dSDavid Herrmann 		goto err_wqueue;
15871da177e4SLinus Torvalds 
1588611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
1589611b30f7SMarcel Holtmann 				RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, hdev);
1590611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
1591611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
1592611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
1593611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
1594611b30f7SMarcel Holtmann 		}
1595611b30f7SMarcel Holtmann 	}
1596611b30f7SMarcel Holtmann 
1597ab81cbf9SJohan Hedberg 	set_bit(HCI_AUTO_OFF, &hdev->flags);
1598ab81cbf9SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->flags);
15997f971041SGustavo F. Padovan 	schedule_work(&hdev->power_on);
1600ab81cbf9SJohan Hedberg 
16011da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
16021da177e4SLinus Torvalds 
16031da177e4SLinus Torvalds 	return id;
1604f48fd9c8SMarcel Holtmann 
160533ca954dSDavid Herrmann err_wqueue:
160633ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
160733ca954dSDavid Herrmann err:
1608f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
1609f48fd9c8SMarcel Holtmann 	list_del(&hdev->list);
1610f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
1611f48fd9c8SMarcel Holtmann 
161233ca954dSDavid Herrmann 	return error;
16131da177e4SLinus Torvalds }
16141da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
16151da177e4SLinus Torvalds 
16161da177e4SLinus Torvalds /* Unregister HCI device */
161759735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
16181da177e4SLinus Torvalds {
1619ef222013SMarcel Holtmann 	int i;
1620ef222013SMarcel Holtmann 
1621c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
16221da177e4SLinus Torvalds 
1623f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
16241da177e4SLinus Torvalds 	list_del(&hdev->list);
1625f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
16261da177e4SLinus Torvalds 
16271da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
16281da177e4SLinus Torvalds 
1629cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
1630ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
1631ef222013SMarcel Holtmann 
1632ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
163356e5cb86SJohan Hedberg 					!test_bit(HCI_SETUP, &hdev->flags)) {
163409fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
1635744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
163609fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
163756e5cb86SJohan Hedberg 	}
1638ab81cbf9SJohan Hedberg 
16392e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
16402e58ef3eSJohan Hedberg 	 * pending list */
16412e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
16422e58ef3eSJohan Hedberg 
16431da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
16441da177e4SLinus Torvalds 
1645611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
1646611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
1647611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
1648611b30f7SMarcel Holtmann 	}
1649611b30f7SMarcel Holtmann 
1650ce242970SDavid Herrmann 	hci_del_sysfs(hdev);
1651147e2d59SDave Young 
1652db323f2fSGustavo F. Padovan 	cancel_delayed_work_sync(&hdev->adv_work);
1653c6f3c5f7SGustavo F. Padovan 
1654f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
1655f48fd9c8SMarcel Holtmann 
165609fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
1657e2e0cacbSJohan Hedberg 	hci_blacklist_clear(hdev);
16582aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
165955ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
16602763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
166176c8686fSAndre Guedes 	hci_adv_entries_clear(hdev);
166209fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
1663e2e0cacbSJohan Hedberg 
16641da177e4SLinus Torvalds 	__hci_dev_put(hdev);
16651da177e4SLinus Torvalds }
16661da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
16671da177e4SLinus Torvalds 
16681da177e4SLinus Torvalds /* Suspend HCI device */
16691da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
16701da177e4SLinus Torvalds {
16711da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
16721da177e4SLinus Torvalds 	return 0;
16731da177e4SLinus Torvalds }
16741da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
16751da177e4SLinus Torvalds 
16761da177e4SLinus Torvalds /* Resume HCI device */
16771da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
16781da177e4SLinus Torvalds {
16791da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
16801da177e4SLinus Torvalds 	return 0;
16811da177e4SLinus Torvalds }
16821da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
16831da177e4SLinus Torvalds 
168476bca880SMarcel Holtmann /* Receive frame from HCI drivers */
168576bca880SMarcel Holtmann int hci_recv_frame(struct sk_buff *skb)
168676bca880SMarcel Holtmann {
168776bca880SMarcel Holtmann 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
168876bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
168976bca880SMarcel Holtmann 				&& !test_bit(HCI_INIT, &hdev->flags))) {
169076bca880SMarcel Holtmann 		kfree_skb(skb);
169176bca880SMarcel Holtmann 		return -ENXIO;
169276bca880SMarcel Holtmann 	}
169376bca880SMarcel Holtmann 
169476bca880SMarcel Holtmann 	/* Incomming skb */
169576bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
169676bca880SMarcel Holtmann 
169776bca880SMarcel Holtmann 	/* Time stamp */
169876bca880SMarcel Holtmann 	__net_timestamp(skb);
169976bca880SMarcel Holtmann 
170076bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
1701b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
1702c78ae283SMarcel Holtmann 
170376bca880SMarcel Holtmann 	return 0;
170476bca880SMarcel Holtmann }
170576bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
170676bca880SMarcel Holtmann 
170733e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
17081e429f38SGustavo F. Padovan 						  int count, __u8 index)
170933e882a5SSuraj Sumangala {
171033e882a5SSuraj Sumangala 	int len = 0;
171133e882a5SSuraj Sumangala 	int hlen = 0;
171233e882a5SSuraj Sumangala 	int remain = count;
171333e882a5SSuraj Sumangala 	struct sk_buff *skb;
171433e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
171533e882a5SSuraj Sumangala 
171633e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
171733e882a5SSuraj Sumangala 				index >= NUM_REASSEMBLY)
171833e882a5SSuraj Sumangala 		return -EILSEQ;
171933e882a5SSuraj Sumangala 
172033e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
172133e882a5SSuraj Sumangala 
172233e882a5SSuraj Sumangala 	if (!skb) {
172333e882a5SSuraj Sumangala 		switch (type) {
172433e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
172533e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
172633e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
172733e882a5SSuraj Sumangala 			break;
172833e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
172933e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
173033e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
173133e882a5SSuraj Sumangala 			break;
173233e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
173333e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
173433e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
173533e882a5SSuraj Sumangala 			break;
173633e882a5SSuraj Sumangala 		}
173733e882a5SSuraj Sumangala 
17381e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
173933e882a5SSuraj Sumangala 		if (!skb)
174033e882a5SSuraj Sumangala 			return -ENOMEM;
174133e882a5SSuraj Sumangala 
174233e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
174333e882a5SSuraj Sumangala 		scb->expect = hlen;
174433e882a5SSuraj Sumangala 		scb->pkt_type = type;
174533e882a5SSuraj Sumangala 
174633e882a5SSuraj Sumangala 		skb->dev = (void *) hdev;
174733e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
174833e882a5SSuraj Sumangala 	}
174933e882a5SSuraj Sumangala 
175033e882a5SSuraj Sumangala 	while (count) {
175133e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
175233e882a5SSuraj Sumangala 		len = min(scb->expect, (__u16)count);
175333e882a5SSuraj Sumangala 
175433e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
175533e882a5SSuraj Sumangala 
175633e882a5SSuraj Sumangala 		count -= len;
175733e882a5SSuraj Sumangala 		data += len;
175833e882a5SSuraj Sumangala 		scb->expect -= len;
175933e882a5SSuraj Sumangala 		remain = count;
176033e882a5SSuraj Sumangala 
176133e882a5SSuraj Sumangala 		switch (type) {
176233e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
176333e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
176433e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
176533e882a5SSuraj Sumangala 				scb->expect = h->plen;
176633e882a5SSuraj Sumangala 
176733e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
176833e882a5SSuraj Sumangala 					kfree_skb(skb);
176933e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
177033e882a5SSuraj Sumangala 					return -ENOMEM;
177133e882a5SSuraj Sumangala 				}
177233e882a5SSuraj Sumangala 			}
177333e882a5SSuraj Sumangala 			break;
177433e882a5SSuraj Sumangala 
177533e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
177633e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
177733e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
177833e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
177933e882a5SSuraj Sumangala 
178033e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
178133e882a5SSuraj Sumangala 					kfree_skb(skb);
178233e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
178333e882a5SSuraj Sumangala 					return -ENOMEM;
178433e882a5SSuraj Sumangala 				}
178533e882a5SSuraj Sumangala 			}
178633e882a5SSuraj Sumangala 			break;
178733e882a5SSuraj Sumangala 
178833e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
178933e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
179033e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
179133e882a5SSuraj Sumangala 				scb->expect = h->dlen;
179233e882a5SSuraj Sumangala 
179333e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
179433e882a5SSuraj Sumangala 					kfree_skb(skb);
179533e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
179633e882a5SSuraj Sumangala 					return -ENOMEM;
179733e882a5SSuraj Sumangala 				}
179833e882a5SSuraj Sumangala 			}
179933e882a5SSuraj Sumangala 			break;
180033e882a5SSuraj Sumangala 		}
180133e882a5SSuraj Sumangala 
180233e882a5SSuraj Sumangala 		if (scb->expect == 0) {
180333e882a5SSuraj Sumangala 			/* Complete frame */
180433e882a5SSuraj Sumangala 
180533e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
180633e882a5SSuraj Sumangala 			hci_recv_frame(skb);
180733e882a5SSuraj Sumangala 
180833e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
180933e882a5SSuraj Sumangala 			return remain;
181033e882a5SSuraj Sumangala 		}
181133e882a5SSuraj Sumangala 	}
181233e882a5SSuraj Sumangala 
181333e882a5SSuraj Sumangala 	return remain;
181433e882a5SSuraj Sumangala }
181533e882a5SSuraj Sumangala 
1816ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
1817ef222013SMarcel Holtmann {
1818f39a3c06SSuraj Sumangala 	int rem = 0;
1819f39a3c06SSuraj Sumangala 
1820ef222013SMarcel Holtmann 	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
1821ef222013SMarcel Holtmann 		return -EILSEQ;
1822ef222013SMarcel Holtmann 
1823da5f6c37SGustavo F. Padovan 	while (count) {
18241e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count, type - 1);
1825f39a3c06SSuraj Sumangala 		if (rem < 0)
1826f39a3c06SSuraj Sumangala 			return rem;
1827ef222013SMarcel Holtmann 
1828f39a3c06SSuraj Sumangala 		data += (count - rem);
1829f39a3c06SSuraj Sumangala 		count = rem;
1830f81c6224SJoe Perches 	}
1831ef222013SMarcel Holtmann 
1832f39a3c06SSuraj Sumangala 	return rem;
1833ef222013SMarcel Holtmann }
1834ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment);
1835ef222013SMarcel Holtmann 
183699811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
183799811510SSuraj Sumangala 
183899811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
183999811510SSuraj Sumangala {
184099811510SSuraj Sumangala 	int type;
184199811510SSuraj Sumangala 	int rem = 0;
184299811510SSuraj Sumangala 
1843da5f6c37SGustavo F. Padovan 	while (count) {
184499811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
184599811510SSuraj Sumangala 
184699811510SSuraj Sumangala 		if (!skb) {
184799811510SSuraj Sumangala 			struct { char type; } *pkt;
184899811510SSuraj Sumangala 
184999811510SSuraj Sumangala 			/* Start of the frame */
185099811510SSuraj Sumangala 			pkt = data;
185199811510SSuraj Sumangala 			type = pkt->type;
185299811510SSuraj Sumangala 
185399811510SSuraj Sumangala 			data++;
185499811510SSuraj Sumangala 			count--;
185599811510SSuraj Sumangala 		} else
185699811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
185799811510SSuraj Sumangala 
18581e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
18591e429f38SGustavo F. Padovan 							STREAM_REASSEMBLY);
186099811510SSuraj Sumangala 		if (rem < 0)
186199811510SSuraj Sumangala 			return rem;
186299811510SSuraj Sumangala 
186399811510SSuraj Sumangala 		data += (count - rem);
186499811510SSuraj Sumangala 		count = rem;
1865f81c6224SJoe Perches 	}
186699811510SSuraj Sumangala 
186799811510SSuraj Sumangala 	return rem;
186899811510SSuraj Sumangala }
186999811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
187099811510SSuraj Sumangala 
18711da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
18721da177e4SLinus Torvalds 
18731da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
18741da177e4SLinus Torvalds {
18751da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
18761da177e4SLinus Torvalds 
1877f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
18781da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
1879f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
18801da177e4SLinus Torvalds 
18811da177e4SLinus Torvalds 	return 0;
18821da177e4SLinus Torvalds }
18831da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
18841da177e4SLinus Torvalds 
18851da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
18861da177e4SLinus Torvalds {
18871da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
18881da177e4SLinus Torvalds 
1889f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
18901da177e4SLinus Torvalds 	list_del(&cb->list);
1891f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
18921da177e4SLinus Torvalds 
18931da177e4SLinus Torvalds 	return 0;
18941da177e4SLinus Torvalds }
18951da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
18961da177e4SLinus Torvalds 
18971da177e4SLinus Torvalds static int hci_send_frame(struct sk_buff *skb)
18981da177e4SLinus Torvalds {
18991da177e4SLinus Torvalds 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
19001da177e4SLinus Torvalds 
19011da177e4SLinus Torvalds 	if (!hdev) {
19021da177e4SLinus Torvalds 		kfree_skb(skb);
19031da177e4SLinus Torvalds 		return -ENODEV;
19041da177e4SLinus Torvalds 	}
19051da177e4SLinus Torvalds 
19060d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
19071da177e4SLinus Torvalds 
19081da177e4SLinus Torvalds 	if (atomic_read(&hdev->promisc)) {
19091da177e4SLinus Torvalds 		/* Time stamp */
1910a61bbcf2SPatrick McHardy 		__net_timestamp(skb);
19111da177e4SLinus Torvalds 
1912eec8d2bcSJohan Hedberg 		hci_send_to_sock(hdev, skb, NULL);
19131da177e4SLinus Torvalds 	}
19141da177e4SLinus Torvalds 
19151da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
19161da177e4SLinus Torvalds 	skb_orphan(skb);
19171da177e4SLinus Torvalds 
19181da177e4SLinus Torvalds 	return hdev->send(skb);
19191da177e4SLinus Torvalds }
19201da177e4SLinus Torvalds 
19211da177e4SLinus Torvalds /* Send HCI command */
1922a9de9248SMarcel Holtmann int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)
19231da177e4SLinus Torvalds {
19241da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
19251da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
19261da177e4SLinus Torvalds 	struct sk_buff *skb;
19271da177e4SLinus Torvalds 
1928a9de9248SMarcel Holtmann 	BT_DBG("%s opcode 0x%x plen %d", hdev->name, opcode, plen);
19291da177e4SLinus Torvalds 
19301da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
19311da177e4SLinus Torvalds 	if (!skb) {
1932ef222013SMarcel Holtmann 		BT_ERR("%s no memory for command", hdev->name);
19331da177e4SLinus Torvalds 		return -ENOMEM;
19341da177e4SLinus Torvalds 	}
19351da177e4SLinus Torvalds 
19361da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
1937a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
19381da177e4SLinus Torvalds 	hdr->plen   = plen;
19391da177e4SLinus Torvalds 
19401da177e4SLinus Torvalds 	if (plen)
19411da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
19421da177e4SLinus Torvalds 
19431da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
19441da177e4SLinus Torvalds 
19450d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
19461da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
1947c78ae283SMarcel Holtmann 
1948a5040efaSJohan Hedberg 	if (test_bit(HCI_INIT, &hdev->flags))
1949a5040efaSJohan Hedberg 		hdev->init_last_cmd = opcode;
1950a5040efaSJohan Hedberg 
19511da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
1952c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
19531da177e4SLinus Torvalds 
19541da177e4SLinus Torvalds 	return 0;
19551da177e4SLinus Torvalds }
19561da177e4SLinus Torvalds 
19571da177e4SLinus Torvalds /* Get data from the previously sent command */
1958a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
19591da177e4SLinus Torvalds {
19601da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
19611da177e4SLinus Torvalds 
19621da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
19631da177e4SLinus Torvalds 		return NULL;
19641da177e4SLinus Torvalds 
19651da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
19661da177e4SLinus Torvalds 
1967a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
19681da177e4SLinus Torvalds 		return NULL;
19691da177e4SLinus Torvalds 
1970a9de9248SMarcel Holtmann 	BT_DBG("%s opcode 0x%x", hdev->name, opcode);
19711da177e4SLinus Torvalds 
19721da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
19731da177e4SLinus Torvalds }
19741da177e4SLinus Torvalds 
19751da177e4SLinus Torvalds /* Send ACL data */
19761da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
19771da177e4SLinus Torvalds {
19781da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
19791da177e4SLinus Torvalds 	int len = skb->len;
19801da177e4SLinus Torvalds 
1981badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
1982badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
19839c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
1984aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
1985aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
19861da177e4SLinus Torvalds }
19871da177e4SLinus Torvalds 
198873d80debSLuiz Augusto von Dentz static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue,
198973d80debSLuiz Augusto von Dentz 				struct sk_buff *skb, __u16 flags)
19901da177e4SLinus Torvalds {
19911da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
19921da177e4SLinus Torvalds 	struct sk_buff *list;
19931da177e4SLinus Torvalds 
199470f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
199570f23020SAndrei Emeltchenko 	if (!list) {
19961da177e4SLinus Torvalds 		/* Non fragmented */
19971da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
19981da177e4SLinus Torvalds 
199973d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
20001da177e4SLinus Torvalds 	} else {
20011da177e4SLinus Torvalds 		/* Fragmented */
20021da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
20031da177e4SLinus Torvalds 
20041da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
20051da177e4SLinus Torvalds 
20061da177e4SLinus Torvalds 		/* Queue all fragments atomically */
2007af3e6359SGustavo F. Padovan 		spin_lock(&queue->lock);
20081da177e4SLinus Torvalds 
200973d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
2010e702112fSAndrei Emeltchenko 
2011e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
2012e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
20131da177e4SLinus Torvalds 		do {
20141da177e4SLinus Torvalds 			skb = list; list = list->next;
20151da177e4SLinus Torvalds 
20161da177e4SLinus Torvalds 			skb->dev = (void *) hdev;
20170d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2018e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
20191da177e4SLinus Torvalds 
20201da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
20211da177e4SLinus Torvalds 
202273d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
20231da177e4SLinus Torvalds 		} while (list);
20241da177e4SLinus Torvalds 
2025af3e6359SGustavo F. Padovan 		spin_unlock(&queue->lock);
20261da177e4SLinus Torvalds 	}
202773d80debSLuiz Augusto von Dentz }
202873d80debSLuiz Augusto von Dentz 
202973d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
203073d80debSLuiz Augusto von Dentz {
203173d80debSLuiz Augusto von Dentz 	struct hci_conn *conn = chan->conn;
203273d80debSLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
203373d80debSLuiz Augusto von Dentz 
203473d80debSLuiz Augusto von Dentz 	BT_DBG("%s chan %p flags 0x%x", hdev->name, chan, flags);
203573d80debSLuiz Augusto von Dentz 
203673d80debSLuiz Augusto von Dentz 	skb->dev = (void *) hdev;
203773d80debSLuiz Augusto von Dentz 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
203873d80debSLuiz Augusto von Dentz 	hci_add_acl_hdr(skb, conn->handle, flags);
203973d80debSLuiz Augusto von Dentz 
204073d80debSLuiz Augusto von Dentz 	hci_queue_acl(conn, &chan->data_q, skb, flags);
20411da177e4SLinus Torvalds 
20423eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
20431da177e4SLinus Torvalds }
20441da177e4SLinus Torvalds EXPORT_SYMBOL(hci_send_acl);
20451da177e4SLinus Torvalds 
20461da177e4SLinus Torvalds /* Send SCO data */
20470d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
20481da177e4SLinus Torvalds {
20491da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
20501da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
20511da177e4SLinus Torvalds 
20521da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
20531da177e4SLinus Torvalds 
2054aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
20551da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
20561da177e4SLinus Torvalds 
2057badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
2058badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
20599c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
20601da177e4SLinus Torvalds 
20611da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
20620d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
2063c78ae283SMarcel Holtmann 
20641da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
20653eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
20661da177e4SLinus Torvalds }
20671da177e4SLinus Torvalds EXPORT_SYMBOL(hci_send_sco);
20681da177e4SLinus Torvalds 
20691da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
20701da177e4SLinus Torvalds 
20711da177e4SLinus Torvalds /* HCI Connection scheduler */
20721da177e4SLinus Torvalds static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote)
20731da177e4SLinus Torvalds {
20741da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
20758035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
20761da177e4SLinus Torvalds 	int num = 0, min = ~0;
20771da177e4SLinus Torvalds 
20781da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
20791da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
2080bf4c6325SGustavo F. Padovan 
2081bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2082bf4c6325SGustavo F. Padovan 
2083bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2084769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
20851da177e4SLinus Torvalds 			continue;
2086769be974SMarcel Holtmann 
2087769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
2088769be974SMarcel Holtmann 			continue;
2089769be974SMarcel Holtmann 
20901da177e4SLinus Torvalds 		num++;
20911da177e4SLinus Torvalds 
20921da177e4SLinus Torvalds 		if (c->sent < min) {
20931da177e4SLinus Torvalds 			min  = c->sent;
20941da177e4SLinus Torvalds 			conn = c;
20951da177e4SLinus Torvalds 		}
209652087a79SLuiz Augusto von Dentz 
209752087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
209852087a79SLuiz Augusto von Dentz 			break;
20991da177e4SLinus Torvalds 	}
21001da177e4SLinus Torvalds 
2101bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2102bf4c6325SGustavo F. Padovan 
21031da177e4SLinus Torvalds 	if (conn) {
21046ed58ec5SVille Tervo 		int cnt, q;
21056ed58ec5SVille Tervo 
21066ed58ec5SVille Tervo 		switch (conn->type) {
21076ed58ec5SVille Tervo 		case ACL_LINK:
21086ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
21096ed58ec5SVille Tervo 			break;
21106ed58ec5SVille Tervo 		case SCO_LINK:
21116ed58ec5SVille Tervo 		case ESCO_LINK:
21126ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
21136ed58ec5SVille Tervo 			break;
21146ed58ec5SVille Tervo 		case LE_LINK:
21156ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
21166ed58ec5SVille Tervo 			break;
21176ed58ec5SVille Tervo 		default:
21186ed58ec5SVille Tervo 			cnt = 0;
21196ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
21206ed58ec5SVille Tervo 		}
21216ed58ec5SVille Tervo 
21226ed58ec5SVille Tervo 		q = cnt / num;
21231da177e4SLinus Torvalds 		*quote = q ? q : 1;
21241da177e4SLinus Torvalds 	} else
21251da177e4SLinus Torvalds 		*quote = 0;
21261da177e4SLinus Torvalds 
21271da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
21281da177e4SLinus Torvalds 	return conn;
21291da177e4SLinus Torvalds }
21301da177e4SLinus Torvalds 
2131bae1f5d9SVille Tervo static inline void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
21321da177e4SLinus Torvalds {
21331da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
21341da177e4SLinus Torvalds 	struct hci_conn *c;
21351da177e4SLinus Torvalds 
2136bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
21371da177e4SLinus Torvalds 
2138bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2139bf4c6325SGustavo F. Padovan 
21401da177e4SLinus Torvalds 	/* Kill stalled connections */
2141bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2142bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
2143bae1f5d9SVille Tervo 			BT_ERR("%s killing stalled connection %s",
21441da177e4SLinus Torvalds 				hdev->name, batostr(&c->dst));
21451da177e4SLinus Torvalds 			hci_acl_disconn(c, 0x13);
21461da177e4SLinus Torvalds 		}
21471da177e4SLinus Torvalds 	}
2148bf4c6325SGustavo F. Padovan 
2149bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
21501da177e4SLinus Torvalds }
21511da177e4SLinus Torvalds 
215273d80debSLuiz Augusto von Dentz static inline struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
215373d80debSLuiz Augusto von Dentz 						int *quote)
215473d80debSLuiz Augusto von Dentz {
215573d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
215673d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
215773d80debSLuiz Augusto von Dentz 	int num = 0, min = ~0, cur_prio = 0;
215873d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
215973d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
216073d80debSLuiz Augusto von Dentz 
216173d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
216273d80debSLuiz Augusto von Dentz 
2163bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2164bf4c6325SGustavo F. Padovan 
2165bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
216673d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
216773d80debSLuiz Augusto von Dentz 
216873d80debSLuiz Augusto von Dentz 		if (conn->type != type)
216973d80debSLuiz Augusto von Dentz 			continue;
217073d80debSLuiz Augusto von Dentz 
217173d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
217273d80debSLuiz Augusto von Dentz 			continue;
217373d80debSLuiz Augusto von Dentz 
217473d80debSLuiz Augusto von Dentz 		conn_num++;
217573d80debSLuiz Augusto von Dentz 
21768192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
217773d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
217873d80debSLuiz Augusto von Dentz 
217973d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
218073d80debSLuiz Augusto von Dentz 				continue;
218173d80debSLuiz Augusto von Dentz 
218273d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
218373d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
218473d80debSLuiz Augusto von Dentz 				continue;
218573d80debSLuiz Augusto von Dentz 
218673d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
218773d80debSLuiz Augusto von Dentz 				num = 0;
218873d80debSLuiz Augusto von Dentz 				min = ~0;
218973d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
219073d80debSLuiz Augusto von Dentz 			}
219173d80debSLuiz Augusto von Dentz 
219273d80debSLuiz Augusto von Dentz 			num++;
219373d80debSLuiz Augusto von Dentz 
219473d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
219573d80debSLuiz Augusto von Dentz 				min  = conn->sent;
219673d80debSLuiz Augusto von Dentz 				chan = tmp;
219773d80debSLuiz Augusto von Dentz 			}
219873d80debSLuiz Augusto von Dentz 		}
219973d80debSLuiz Augusto von Dentz 
220073d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
220173d80debSLuiz Augusto von Dentz 			break;
220273d80debSLuiz Augusto von Dentz 	}
220373d80debSLuiz Augusto von Dentz 
2204bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2205bf4c6325SGustavo F. Padovan 
220673d80debSLuiz Augusto von Dentz 	if (!chan)
220773d80debSLuiz Augusto von Dentz 		return NULL;
220873d80debSLuiz Augusto von Dentz 
220973d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
221073d80debSLuiz Augusto von Dentz 	case ACL_LINK:
221173d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
221273d80debSLuiz Augusto von Dentz 		break;
221373d80debSLuiz Augusto von Dentz 	case SCO_LINK:
221473d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
221573d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
221673d80debSLuiz Augusto von Dentz 		break;
221773d80debSLuiz Augusto von Dentz 	case LE_LINK:
221873d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
221973d80debSLuiz Augusto von Dentz 		break;
222073d80debSLuiz Augusto von Dentz 	default:
222173d80debSLuiz Augusto von Dentz 		cnt = 0;
222273d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
222373d80debSLuiz Augusto von Dentz 	}
222473d80debSLuiz Augusto von Dentz 
222573d80debSLuiz Augusto von Dentz 	q = cnt / num;
222673d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
222773d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
222873d80debSLuiz Augusto von Dentz 	return chan;
222973d80debSLuiz Augusto von Dentz }
223073d80debSLuiz Augusto von Dentz 
223102b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
223202b20f0bSLuiz Augusto von Dentz {
223302b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
223402b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
223502b20f0bSLuiz Augusto von Dentz 	int num = 0;
223602b20f0bSLuiz Augusto von Dentz 
223702b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
223802b20f0bSLuiz Augusto von Dentz 
2239bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2240bf4c6325SGustavo F. Padovan 
2241bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
224202b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
224302b20f0bSLuiz Augusto von Dentz 
224402b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
224502b20f0bSLuiz Augusto von Dentz 			continue;
224602b20f0bSLuiz Augusto von Dentz 
224702b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
224802b20f0bSLuiz Augusto von Dentz 			continue;
224902b20f0bSLuiz Augusto von Dentz 
225002b20f0bSLuiz Augusto von Dentz 		num++;
225102b20f0bSLuiz Augusto von Dentz 
22528192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
225302b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
225402b20f0bSLuiz Augusto von Dentz 
225502b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
225602b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
225702b20f0bSLuiz Augusto von Dentz 				continue;
225802b20f0bSLuiz Augusto von Dentz 			}
225902b20f0bSLuiz Augusto von Dentz 
226002b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
226102b20f0bSLuiz Augusto von Dentz 				continue;
226202b20f0bSLuiz Augusto von Dentz 
226302b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
226402b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
226502b20f0bSLuiz Augusto von Dentz 				continue;
226602b20f0bSLuiz Augusto von Dentz 
226702b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
226802b20f0bSLuiz Augusto von Dentz 
226902b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
227002b20f0bSLuiz Augusto von Dentz 								skb->priority);
227102b20f0bSLuiz Augusto von Dentz 		}
227202b20f0bSLuiz Augusto von Dentz 
227302b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
227402b20f0bSLuiz Augusto von Dentz 			break;
227502b20f0bSLuiz Augusto von Dentz 	}
2276bf4c6325SGustavo F. Padovan 
2277bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2278bf4c6325SGustavo F. Padovan 
227902b20f0bSLuiz Augusto von Dentz }
228002b20f0bSLuiz Augusto von Dentz 
22811da177e4SLinus Torvalds static inline void hci_sched_acl(struct hci_dev *hdev)
22821da177e4SLinus Torvalds {
228373d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
22841da177e4SLinus Torvalds 	struct sk_buff *skb;
22851da177e4SLinus Torvalds 	int quote;
228673d80debSLuiz Augusto von Dentz 	unsigned int cnt;
22871da177e4SLinus Torvalds 
22881da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
22891da177e4SLinus Torvalds 
229052087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ACL_LINK))
229152087a79SLuiz Augusto von Dentz 		return;
229252087a79SLuiz Augusto von Dentz 
22931da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
22941da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
22951da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
229682453021SS.Çağlar Onur 		if (!hdev->acl_cnt && time_after(jiffies, hdev->acl_last_tx + HZ * 45))
2297bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
22981da177e4SLinus Torvalds 	}
22991da177e4SLinus Torvalds 
230073d80debSLuiz Augusto von Dentz 	cnt = hdev->acl_cnt;
230104837f64SMarcel Holtmann 
230273d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
230373d80debSLuiz Augusto von Dentz 			(chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
2304ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
2305ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
230673d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
230773d80debSLuiz Augusto von Dentz 					skb->len, skb->priority);
230873d80debSLuiz Augusto von Dentz 
2309ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
2310ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
2311ec1cce24SLuiz Augusto von Dentz 				break;
2312ec1cce24SLuiz Augusto von Dentz 
2313ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
2314ec1cce24SLuiz Augusto von Dentz 
231573d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
231673d80debSLuiz Augusto von Dentz 						bt_cb(skb)->force_active);
231704837f64SMarcel Holtmann 
23181da177e4SLinus Torvalds 			hci_send_frame(skb);
23191da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
23201da177e4SLinus Torvalds 
23211da177e4SLinus Torvalds 			hdev->acl_cnt--;
232273d80debSLuiz Augusto von Dentz 			chan->sent++;
232373d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
23241da177e4SLinus Torvalds 		}
23251da177e4SLinus Torvalds 	}
232602b20f0bSLuiz Augusto von Dentz 
232702b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
232802b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
23291da177e4SLinus Torvalds }
23301da177e4SLinus Torvalds 
23311da177e4SLinus Torvalds /* Schedule SCO */
23321da177e4SLinus Torvalds static inline void hci_sched_sco(struct hci_dev *hdev)
23331da177e4SLinus Torvalds {
23341da177e4SLinus Torvalds 	struct hci_conn *conn;
23351da177e4SLinus Torvalds 	struct sk_buff *skb;
23361da177e4SLinus Torvalds 	int quote;
23371da177e4SLinus Torvalds 
23381da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
23391da177e4SLinus Torvalds 
234052087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
234152087a79SLuiz Augusto von Dentz 		return;
234252087a79SLuiz Augusto von Dentz 
23431da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
23441da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
23451da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
23461da177e4SLinus Torvalds 			hci_send_frame(skb);
23471da177e4SLinus Torvalds 
23481da177e4SLinus Torvalds 			conn->sent++;
23491da177e4SLinus Torvalds 			if (conn->sent == ~0)
23501da177e4SLinus Torvalds 				conn->sent = 0;
23511da177e4SLinus Torvalds 		}
23521da177e4SLinus Torvalds 	}
23531da177e4SLinus Torvalds }
23541da177e4SLinus Torvalds 
2355b6a0dc82SMarcel Holtmann static inline void hci_sched_esco(struct hci_dev *hdev)
2356b6a0dc82SMarcel Holtmann {
2357b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
2358b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
2359b6a0dc82SMarcel Holtmann 	int quote;
2360b6a0dc82SMarcel Holtmann 
2361b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
2362b6a0dc82SMarcel Holtmann 
236352087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
236452087a79SLuiz Augusto von Dentz 		return;
236552087a79SLuiz Augusto von Dentz 
2366b6a0dc82SMarcel Holtmann 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, &quote))) {
2367b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
2368b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
2369b6a0dc82SMarcel Holtmann 			hci_send_frame(skb);
2370b6a0dc82SMarcel Holtmann 
2371b6a0dc82SMarcel Holtmann 			conn->sent++;
2372b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
2373b6a0dc82SMarcel Holtmann 				conn->sent = 0;
2374b6a0dc82SMarcel Holtmann 		}
2375b6a0dc82SMarcel Holtmann 	}
2376b6a0dc82SMarcel Holtmann }
2377b6a0dc82SMarcel Holtmann 
23786ed58ec5SVille Tervo static inline void hci_sched_le(struct hci_dev *hdev)
23796ed58ec5SVille Tervo {
238073d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
23816ed58ec5SVille Tervo 	struct sk_buff *skb;
238202b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
23836ed58ec5SVille Tervo 
23846ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
23856ed58ec5SVille Tervo 
238652087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
238752087a79SLuiz Augusto von Dentz 		return;
238852087a79SLuiz Augusto von Dentz 
23896ed58ec5SVille Tervo 	if (!test_bit(HCI_RAW, &hdev->flags)) {
23906ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
23916ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
2392bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
23936ed58ec5SVille Tervo 				time_after(jiffies, hdev->le_last_tx + HZ * 45))
2394bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
23956ed58ec5SVille Tervo 	}
23966ed58ec5SVille Tervo 
23976ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
239802b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
239973d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
2400ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
2401ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
240273d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
240373d80debSLuiz Augusto von Dentz 					skb->len, skb->priority);
24046ed58ec5SVille Tervo 
2405ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
2406ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
2407ec1cce24SLuiz Augusto von Dentz 				break;
2408ec1cce24SLuiz Augusto von Dentz 
2409ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
2410ec1cce24SLuiz Augusto von Dentz 
24116ed58ec5SVille Tervo 			hci_send_frame(skb);
24126ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
24136ed58ec5SVille Tervo 
24146ed58ec5SVille Tervo 			cnt--;
241573d80debSLuiz Augusto von Dentz 			chan->sent++;
241673d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
24176ed58ec5SVille Tervo 		}
24186ed58ec5SVille Tervo 	}
241973d80debSLuiz Augusto von Dentz 
24206ed58ec5SVille Tervo 	if (hdev->le_pkts)
24216ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
24226ed58ec5SVille Tervo 	else
24236ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
242402b20f0bSLuiz Augusto von Dentz 
242502b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
242602b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
24276ed58ec5SVille Tervo }
24286ed58ec5SVille Tervo 
24293eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
24301da177e4SLinus Torvalds {
24313eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
24321da177e4SLinus Torvalds 	struct sk_buff *skb;
24331da177e4SLinus Torvalds 
24346ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
24356ed58ec5SVille Tervo 		hdev->sco_cnt, hdev->le_cnt);
24361da177e4SLinus Torvalds 
24371da177e4SLinus Torvalds 	/* Schedule queues and send stuff to HCI driver */
24381da177e4SLinus Torvalds 
24391da177e4SLinus Torvalds 	hci_sched_acl(hdev);
24401da177e4SLinus Torvalds 
24411da177e4SLinus Torvalds 	hci_sched_sco(hdev);
24421da177e4SLinus Torvalds 
2443b6a0dc82SMarcel Holtmann 	hci_sched_esco(hdev);
2444b6a0dc82SMarcel Holtmann 
24456ed58ec5SVille Tervo 	hci_sched_le(hdev);
24466ed58ec5SVille Tervo 
24471da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
24481da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
24491da177e4SLinus Torvalds 		hci_send_frame(skb);
24501da177e4SLinus Torvalds }
24511da177e4SLinus Torvalds 
245225985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
24531da177e4SLinus Torvalds 
24541da177e4SLinus Torvalds /* ACL data packet */
24551da177e4SLinus Torvalds static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
24561da177e4SLinus Torvalds {
24571da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
24581da177e4SLinus Torvalds 	struct hci_conn *conn;
24591da177e4SLinus Torvalds 	__u16 handle, flags;
24601da177e4SLinus Torvalds 
24611da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
24621da177e4SLinus Torvalds 
24631da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
24641da177e4SLinus Torvalds 	flags  = hci_flags(handle);
24651da177e4SLinus Torvalds 	handle = hci_handle(handle);
24661da177e4SLinus Torvalds 
24671da177e4SLinus Torvalds 	BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags);
24681da177e4SLinus Torvalds 
24691da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
24701da177e4SLinus Torvalds 
24711da177e4SLinus Torvalds 	hci_dev_lock(hdev);
24721da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
24731da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
24741da177e4SLinus Torvalds 
24751da177e4SLinus Torvalds 	if (conn) {
247665983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
247704837f64SMarcel Holtmann 
24781da177e4SLinus Torvalds 		/* Send to upper protocol */
2479686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
24801da177e4SLinus Torvalds 		return;
24811da177e4SLinus Torvalds 	} else {
24821da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
24831da177e4SLinus Torvalds 			hdev->name, handle);
24841da177e4SLinus Torvalds 	}
24851da177e4SLinus Torvalds 
24861da177e4SLinus Torvalds 	kfree_skb(skb);
24871da177e4SLinus Torvalds }
24881da177e4SLinus Torvalds 
24891da177e4SLinus Torvalds /* SCO data packet */
24901da177e4SLinus Torvalds static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
24911da177e4SLinus Torvalds {
24921da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
24931da177e4SLinus Torvalds 	struct hci_conn *conn;
24941da177e4SLinus Torvalds 	__u16 handle;
24951da177e4SLinus Torvalds 
24961da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
24971da177e4SLinus Torvalds 
24981da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
24991da177e4SLinus Torvalds 
25001da177e4SLinus Torvalds 	BT_DBG("%s len %d handle 0x%x", hdev->name, skb->len, handle);
25011da177e4SLinus Torvalds 
25021da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
25031da177e4SLinus Torvalds 
25041da177e4SLinus Torvalds 	hci_dev_lock(hdev);
25051da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
25061da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
25071da177e4SLinus Torvalds 
25081da177e4SLinus Torvalds 	if (conn) {
25091da177e4SLinus Torvalds 		/* Send to upper protocol */
2510686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
25111da177e4SLinus Torvalds 		return;
25121da177e4SLinus Torvalds 	} else {
25131da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
25141da177e4SLinus Torvalds 			hdev->name, handle);
25151da177e4SLinus Torvalds 	}
25161da177e4SLinus Torvalds 
25171da177e4SLinus Torvalds 	kfree_skb(skb);
25181da177e4SLinus Torvalds }
25191da177e4SLinus Torvalds 
2520b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
25211da177e4SLinus Torvalds {
2522b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
25231da177e4SLinus Torvalds 	struct sk_buff *skb;
25241da177e4SLinus Torvalds 
25251da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
25261da177e4SLinus Torvalds 
25271da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
25281da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
25291da177e4SLinus Torvalds 			/* Send copy to the sockets */
2530eec8d2bcSJohan Hedberg 			hci_send_to_sock(hdev, skb, NULL);
25311da177e4SLinus Torvalds 		}
25321da177e4SLinus Torvalds 
25331da177e4SLinus Torvalds 		if (test_bit(HCI_RAW, &hdev->flags)) {
25341da177e4SLinus Torvalds 			kfree_skb(skb);
25351da177e4SLinus Torvalds 			continue;
25361da177e4SLinus Torvalds 		}
25371da177e4SLinus Torvalds 
25381da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
25391da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
25400d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
25411da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
25421da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
25431da177e4SLinus Torvalds 				kfree_skb(skb);
25441da177e4SLinus Torvalds 				continue;
25453ff50b79SStephen Hemminger 			}
25461da177e4SLinus Torvalds 		}
25471da177e4SLinus Torvalds 
25481da177e4SLinus Torvalds 		/* Process frame */
25490d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
25501da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
2551b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
25521da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
25531da177e4SLinus Torvalds 			break;
25541da177e4SLinus Torvalds 
25551da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
25561da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
25571da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
25581da177e4SLinus Torvalds 			break;
25591da177e4SLinus Torvalds 
25601da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
25611da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
25621da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
25631da177e4SLinus Torvalds 			break;
25641da177e4SLinus Torvalds 
25651da177e4SLinus Torvalds 		default:
25661da177e4SLinus Torvalds 			kfree_skb(skb);
25671da177e4SLinus Torvalds 			break;
25681da177e4SLinus Torvalds 		}
25691da177e4SLinus Torvalds 	}
25701da177e4SLinus Torvalds }
25711da177e4SLinus Torvalds 
2572c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
25731da177e4SLinus Torvalds {
2574c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
25751da177e4SLinus Torvalds 	struct sk_buff *skb;
25761da177e4SLinus Torvalds 
25771da177e4SLinus Torvalds 	BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
25781da177e4SLinus Torvalds 
25791da177e4SLinus Torvalds 	/* Send queued commands */
25805a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
25815a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
25825a08ecceSAndrei Emeltchenko 		if (!skb)
25835a08ecceSAndrei Emeltchenko 			return;
25845a08ecceSAndrei Emeltchenko 
25851da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
25861da177e4SLinus Torvalds 
258770f23020SAndrei Emeltchenko 		hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC);
258870f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
25891da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
25901da177e4SLinus Torvalds 			hci_send_frame(skb);
25917bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
25927bdb8a5cSSzymon Janc 				del_timer(&hdev->cmd_timer);
25937bdb8a5cSSzymon Janc 			else
25946bd32326SVille Tervo 				mod_timer(&hdev->cmd_timer,
25956bd32326SVille Tervo 				  jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT));
25961da177e4SLinus Torvalds 		} else {
25971da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
2598c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
25991da177e4SLinus Torvalds 		}
26001da177e4SLinus Torvalds 	}
26011da177e4SLinus Torvalds }
26022519a1fcSAndre Guedes 
26032519a1fcSAndre Guedes int hci_do_inquiry(struct hci_dev *hdev, u8 length)
26042519a1fcSAndre Guedes {
26052519a1fcSAndre Guedes 	/* General inquiry access code (GIAC) */
26062519a1fcSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
26072519a1fcSAndre Guedes 	struct hci_cp_inquiry cp;
26082519a1fcSAndre Guedes 
26092519a1fcSAndre Guedes 	BT_DBG("%s", hdev->name);
26102519a1fcSAndre Guedes 
26112519a1fcSAndre Guedes 	if (test_bit(HCI_INQUIRY, &hdev->flags))
26122519a1fcSAndre Guedes 		return -EINPROGRESS;
26132519a1fcSAndre Guedes 
26142519a1fcSAndre Guedes 	memset(&cp, 0, sizeof(cp));
26152519a1fcSAndre Guedes 	memcpy(&cp.lap, lap, sizeof(cp.lap));
26162519a1fcSAndre Guedes 	cp.length  = length;
26172519a1fcSAndre Guedes 
26182519a1fcSAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
26192519a1fcSAndre Guedes }
2620023d5049SAndre Guedes 
2621023d5049SAndre Guedes int hci_cancel_inquiry(struct hci_dev *hdev)
2622023d5049SAndre Guedes {
2623023d5049SAndre Guedes 	BT_DBG("%s", hdev->name);
2624023d5049SAndre Guedes 
2625023d5049SAndre Guedes 	if (!test_bit(HCI_INQUIRY, &hdev->flags))
2626023d5049SAndre Guedes 		return -EPERM;
2627023d5049SAndre Guedes 
2628023d5049SAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL);
2629023d5049SAndre Guedes }
26307784d78fSAndrei Emeltchenko 
26317784d78fSAndrei Emeltchenko module_param(enable_hs, bool, 0644);
26327784d78fSAndrei Emeltchenko MODULE_PARM_DESC(enable_hs, "Enable High Speed");
2633