xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 30dc78e1)
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 ---- */
358ff9ef578SJohan Hedberg 
35930dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
36030dc78e1SJohan Hedberg {
36130dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
36230dc78e1SJohan Hedberg 
36330dc78e1SJohan Hedberg 	if (discov->state == DISCOVERY_INQUIRY ||
36430dc78e1SJohan Hedberg 					discov->state == DISCOVERY_RESOLVING)
36530dc78e1SJohan Hedberg 		return true;
36630dc78e1SJohan Hedberg 
36730dc78e1SJohan Hedberg 	return false;
36830dc78e1SJohan Hedberg }
36930dc78e1SJohan Hedberg 
370ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
371ff9ef578SJohan Hedberg {
372ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
373ff9ef578SJohan Hedberg 
374ff9ef578SJohan Hedberg 	if (hdev->discovery.state == state)
375ff9ef578SJohan Hedberg 		return;
376ff9ef578SJohan Hedberg 
377ff9ef578SJohan Hedberg 	switch (state) {
378ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
379ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 0);
380ff9ef578SJohan Hedberg 		break;
381ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
382ff9ef578SJohan Hedberg 		break;
38330dc78e1SJohan Hedberg 	case DISCOVERY_INQUIRY:
384ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
385ff9ef578SJohan Hedberg 		break;
38630dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
38730dc78e1SJohan Hedberg 		break;
388ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
389ff9ef578SJohan Hedberg 		break;
390ff9ef578SJohan Hedberg 	}
391ff9ef578SJohan Hedberg 
392ff9ef578SJohan Hedberg 	hdev->discovery.state = state;
393ff9ef578SJohan Hedberg }
394ff9ef578SJohan Hedberg 
3951da177e4SLinus Torvalds static void inquiry_cache_flush(struct hci_dev *hdev)
3961da177e4SLinus Torvalds {
39730883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
398b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
3991da177e4SLinus Torvalds 
400561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
401561aafbcSJohan Hedberg 		list_del(&p->all);
402b57c1a56SJohan Hedberg 		kfree(p);
4031da177e4SLinus Torvalds 	}
404561aafbcSJohan Hedberg 
405561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
406561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
407ff9ef578SJohan Hedberg 	cache->state = DISCOVERY_STOPPED;
4081da177e4SLinus Torvalds }
4091da177e4SLinus Torvalds 
4101da177e4SLinus Torvalds struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
4111da177e4SLinus Torvalds {
41230883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
4131da177e4SLinus Torvalds 	struct inquiry_entry *e;
4141da177e4SLinus Torvalds 
4151da177e4SLinus Torvalds 	BT_DBG("cache %p, %s", cache, batostr(bdaddr));
4161da177e4SLinus Torvalds 
417561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
4181da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
4191da177e4SLinus Torvalds 			return e;
4201da177e4SLinus Torvalds 	}
4211da177e4SLinus Torvalds 
422b57c1a56SJohan Hedberg 	return NULL;
423b57c1a56SJohan Hedberg }
424b57c1a56SJohan Hedberg 
425561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
426561aafbcSJohan Hedberg 							bdaddr_t *bdaddr)
427561aafbcSJohan Hedberg {
42830883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
429561aafbcSJohan Hedberg 	struct inquiry_entry *e;
430561aafbcSJohan Hedberg 
431561aafbcSJohan Hedberg 	BT_DBG("cache %p, %s", cache, batostr(bdaddr));
432561aafbcSJohan Hedberg 
433561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
434561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
435561aafbcSJohan Hedberg 			return e;
436561aafbcSJohan Hedberg 	}
437561aafbcSJohan Hedberg 
438561aafbcSJohan Hedberg 	return NULL;
439561aafbcSJohan Hedberg }
440561aafbcSJohan Hedberg 
44130dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
44230dc78e1SJohan Hedberg 							bdaddr_t *bdaddr,
44330dc78e1SJohan Hedberg 							int state)
44430dc78e1SJohan Hedberg {
44530dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
44630dc78e1SJohan Hedberg 	struct inquiry_entry *e;
44730dc78e1SJohan Hedberg 
44830dc78e1SJohan Hedberg 	BT_DBG("cache %p bdaddr %s state %d", cache, batostr(bdaddr), state);
44930dc78e1SJohan Hedberg 
45030dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
45130dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
45230dc78e1SJohan Hedberg 			return e;
45330dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
45430dc78e1SJohan Hedberg 			return e;
45530dc78e1SJohan Hedberg 	}
45630dc78e1SJohan Hedberg 
45730dc78e1SJohan Hedberg 	return NULL;
45830dc78e1SJohan Hedberg }
45930dc78e1SJohan Hedberg 
4603175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
461561aafbcSJohan Hedberg 							bool name_known)
4621da177e4SLinus Torvalds {
46330883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
46470f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
4651da177e4SLinus Torvalds 
4661da177e4SLinus Torvalds 	BT_DBG("cache %p, %s", cache, batostr(&data->bdaddr));
4671da177e4SLinus Torvalds 
46870f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
469561aafbcSJohan Hedberg 	if (ie)
470561aafbcSJohan Hedberg 		goto update;
471561aafbcSJohan Hedberg 
4721da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
47370f23020SAndrei Emeltchenko 	ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
47470f23020SAndrei Emeltchenko 	if (!ie)
4753175405bSJohan Hedberg 		return false;
47670f23020SAndrei Emeltchenko 
477561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
478561aafbcSJohan Hedberg 
479561aafbcSJohan Hedberg 	if (name_known) {
480561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
481561aafbcSJohan Hedberg 	} else {
482561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
483561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
484561aafbcSJohan Hedberg 	}
485561aafbcSJohan Hedberg 
486561aafbcSJohan Hedberg update:
487561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
488561aafbcSJohan Hedberg 					ie->name_state != NAME_PENDING) {
489561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
490561aafbcSJohan Hedberg 		list_del(&ie->list);
4911da177e4SLinus Torvalds 	}
4921da177e4SLinus Torvalds 
49370f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
49470f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
4951da177e4SLinus Torvalds 	cache->timestamp = jiffies;
4963175405bSJohan Hedberg 
4973175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
4983175405bSJohan Hedberg 		return false;
4993175405bSJohan Hedberg 
5003175405bSJohan Hedberg 	return true;
5011da177e4SLinus Torvalds }
5021da177e4SLinus Torvalds 
5031da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
5041da177e4SLinus Torvalds {
50530883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
5061da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
5071da177e4SLinus Torvalds 	struct inquiry_entry *e;
5081da177e4SLinus Torvalds 	int copied = 0;
5091da177e4SLinus Torvalds 
510561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
5111da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
512b57c1a56SJohan Hedberg 
513b57c1a56SJohan Hedberg 		if (copied >= num)
514b57c1a56SJohan Hedberg 			break;
515b57c1a56SJohan Hedberg 
5161da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
5171da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
5181da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
5191da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
5201da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
5211da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
522b57c1a56SJohan Hedberg 
5231da177e4SLinus Torvalds 		info++;
524b57c1a56SJohan Hedberg 		copied++;
5251da177e4SLinus Torvalds 	}
5261da177e4SLinus Torvalds 
5271da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
5281da177e4SLinus Torvalds 	return copied;
5291da177e4SLinus Torvalds }
5301da177e4SLinus Torvalds 
5311da177e4SLinus Torvalds static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
5321da177e4SLinus Torvalds {
5331da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
5341da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
5351da177e4SLinus Torvalds 
5361da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
5371da177e4SLinus Torvalds 
5381da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
5391da177e4SLinus Torvalds 		return;
5401da177e4SLinus Torvalds 
5411da177e4SLinus Torvalds 	/* Start Inquiry */
5421da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
5431da177e4SLinus Torvalds 	cp.length  = ir->length;
5441da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
545a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
5461da177e4SLinus Torvalds }
5471da177e4SLinus Torvalds 
5481da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
5491da177e4SLinus Torvalds {
5501da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
5511da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
5521da177e4SLinus Torvalds 	struct hci_dev *hdev;
5531da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
5541da177e4SLinus Torvalds 	long timeo;
5551da177e4SLinus Torvalds 	__u8 *buf;
5561da177e4SLinus Torvalds 
5571da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
5581da177e4SLinus Torvalds 		return -EFAULT;
5591da177e4SLinus Torvalds 
5605a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
5615a08ecceSAndrei Emeltchenko 	if (!hdev)
5621da177e4SLinus Torvalds 		return -ENODEV;
5631da177e4SLinus Torvalds 
56409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
5651da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
5661da177e4SLinus Torvalds 				inquiry_cache_empty(hdev) ||
5671da177e4SLinus Torvalds 				ir.flags & IREQ_CACHE_FLUSH) {
5681da177e4SLinus Torvalds 		inquiry_cache_flush(hdev);
5691da177e4SLinus Torvalds 		do_inquiry = 1;
5701da177e4SLinus Torvalds 	}
57109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
5721da177e4SLinus Torvalds 
57304837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
57470f23020SAndrei Emeltchenko 
57570f23020SAndrei Emeltchenko 	if (do_inquiry) {
57670f23020SAndrei Emeltchenko 		err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo);
57770f23020SAndrei Emeltchenko 		if (err < 0)
5781da177e4SLinus Torvalds 			goto done;
57970f23020SAndrei Emeltchenko 	}
5801da177e4SLinus Torvalds 
5811da177e4SLinus Torvalds 	/* for unlimited number of responses we will use buffer with 255 entries */
5821da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
5831da177e4SLinus Torvalds 
5841da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
5851da177e4SLinus Torvalds 	 * copy it to the user space.
5861da177e4SLinus Torvalds 	 */
58770f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
58870f23020SAndrei Emeltchenko 	if (!buf) {
5891da177e4SLinus Torvalds 		err = -ENOMEM;
5901da177e4SLinus Torvalds 		goto done;
5911da177e4SLinus Torvalds 	}
5921da177e4SLinus Torvalds 
59309fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
5941da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
59509fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
5961da177e4SLinus Torvalds 
5971da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
5981da177e4SLinus Torvalds 
5991da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
6001da177e4SLinus Torvalds 		ptr += sizeof(ir);
6011da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
6021da177e4SLinus Torvalds 					ir.num_rsp))
6031da177e4SLinus Torvalds 			err = -EFAULT;
6041da177e4SLinus Torvalds 	} else
6051da177e4SLinus Torvalds 		err = -EFAULT;
6061da177e4SLinus Torvalds 
6071da177e4SLinus Torvalds 	kfree(buf);
6081da177e4SLinus Torvalds 
6091da177e4SLinus Torvalds done:
6101da177e4SLinus Torvalds 	hci_dev_put(hdev);
6111da177e4SLinus Torvalds 	return err;
6121da177e4SLinus Torvalds }
6131da177e4SLinus Torvalds 
6141da177e4SLinus Torvalds /* ---- HCI ioctl helpers ---- */
6151da177e4SLinus Torvalds 
6161da177e4SLinus Torvalds int hci_dev_open(__u16 dev)
6171da177e4SLinus Torvalds {
6181da177e4SLinus Torvalds 	struct hci_dev *hdev;
6191da177e4SLinus Torvalds 	int ret = 0;
6201da177e4SLinus Torvalds 
6215a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(dev);
6225a08ecceSAndrei Emeltchenko 	if (!hdev)
6231da177e4SLinus Torvalds 		return -ENODEV;
6241da177e4SLinus Torvalds 
6251da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
6261da177e4SLinus Torvalds 
6271da177e4SLinus Torvalds 	hci_req_lock(hdev);
6281da177e4SLinus Torvalds 
629611b30f7SMarcel Holtmann 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) {
630611b30f7SMarcel Holtmann 		ret = -ERFKILL;
631611b30f7SMarcel Holtmann 		goto done;
632611b30f7SMarcel Holtmann 	}
633611b30f7SMarcel Holtmann 
6341da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
6351da177e4SLinus Torvalds 		ret = -EALREADY;
6361da177e4SLinus Torvalds 		goto done;
6371da177e4SLinus Torvalds 	}
6381da177e4SLinus Torvalds 
6391da177e4SLinus Torvalds 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
6401da177e4SLinus Torvalds 		set_bit(HCI_RAW, &hdev->flags);
6411da177e4SLinus Torvalds 
64207e3b94aSAndrei Emeltchenko 	/* Treat all non BR/EDR controllers as raw devices if
64307e3b94aSAndrei Emeltchenko 	   enable_hs is not set */
64407e3b94aSAndrei Emeltchenko 	if (hdev->dev_type != HCI_BREDR && !enable_hs)
645943da25dSMarcel Holtmann 		set_bit(HCI_RAW, &hdev->flags);
646943da25dSMarcel Holtmann 
6471da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
6481da177e4SLinus Torvalds 		ret = -EIO;
6491da177e4SLinus Torvalds 		goto done;
6501da177e4SLinus Torvalds 	}
6511da177e4SLinus Torvalds 
6521da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
6531da177e4SLinus Torvalds 		atomic_set(&hdev->cmd_cnt, 1);
6541da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
655a5040efaSJohan Hedberg 		hdev->init_last_cmd = 0;
6561da177e4SLinus Torvalds 
65704837f64SMarcel Holtmann 		ret = __hci_request(hdev, hci_init_req, 0,
65804837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
6591da177e4SLinus Torvalds 
660eead27daSAndre Guedes 		if (lmp_host_le_capable(hdev))
6616ed58ec5SVille Tervo 			ret = __hci_request(hdev, hci_le_init_req, 0,
6626ed58ec5SVille Tervo 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
6636ed58ec5SVille Tervo 
6641da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
6651da177e4SLinus Torvalds 	}
6661da177e4SLinus Torvalds 
6671da177e4SLinus Torvalds 	if (!ret) {
6681da177e4SLinus Torvalds 		hci_dev_hold(hdev);
6691da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
6701da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
67156e5cb86SJohan Hedberg 		if (!test_bit(HCI_SETUP, &hdev->flags)) {
67209fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
673744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
67409fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
67556e5cb86SJohan Hedberg 		}
6761da177e4SLinus Torvalds 	} else {
6771da177e4SLinus Torvalds 		/* Init failed, cleanup */
6783eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
679c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
680b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
6811da177e4SLinus Torvalds 
6821da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
6831da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
6841da177e4SLinus Torvalds 
6851da177e4SLinus Torvalds 		if (hdev->flush)
6861da177e4SLinus Torvalds 			hdev->flush(hdev);
6871da177e4SLinus Torvalds 
6881da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
6891da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
6901da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
6911da177e4SLinus Torvalds 		}
6921da177e4SLinus Torvalds 
6931da177e4SLinus Torvalds 		hdev->close(hdev);
6941da177e4SLinus Torvalds 		hdev->flags = 0;
6951da177e4SLinus Torvalds 	}
6961da177e4SLinus Torvalds 
6971da177e4SLinus Torvalds done:
6981da177e4SLinus Torvalds 	hci_req_unlock(hdev);
6991da177e4SLinus Torvalds 	hci_dev_put(hdev);
7001da177e4SLinus Torvalds 	return ret;
7011da177e4SLinus Torvalds }
7021da177e4SLinus Torvalds 
7031da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
7041da177e4SLinus Torvalds {
7051da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
7061da177e4SLinus Torvalds 
7071da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
7081da177e4SLinus Torvalds 	hci_req_lock(hdev);
7091da177e4SLinus Torvalds 
7101da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
711b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
7121da177e4SLinus Torvalds 		hci_req_unlock(hdev);
7131da177e4SLinus Torvalds 		return 0;
7141da177e4SLinus Torvalds 	}
7151da177e4SLinus Torvalds 
7163eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
7173eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
718b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
7191da177e4SLinus Torvalds 
72016ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
721e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
72216ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
72316ab91abSJohan Hedberg 	}
72416ab91abSJohan Hedberg 
7253243553fSJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags))
726e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
7273243553fSJohan Hedberg 
7287d78525dSJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->flags))
7297d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
7307d78525dSJohan Hedberg 
73109fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
7321da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
7331da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
73409fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
7351da177e4SLinus Torvalds 
7361da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
7371da177e4SLinus Torvalds 
7381da177e4SLinus Torvalds 	if (hdev->flush)
7391da177e4SLinus Torvalds 		hdev->flush(hdev);
7401da177e4SLinus Torvalds 
7411da177e4SLinus Torvalds 	/* Reset device */
7421da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
7431da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
7441da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
7451da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
74604837f64SMarcel Holtmann 		__hci_request(hdev, hci_reset_req, 0,
747cad44c2bSGustavo F. Padovan 					msecs_to_jiffies(250));
7481da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
7491da177e4SLinus Torvalds 	}
7501da177e4SLinus Torvalds 
751c347b765SGustavo F. Padovan 	/* flush cmd  work */
752c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
7531da177e4SLinus Torvalds 
7541da177e4SLinus Torvalds 	/* Drop queues */
7551da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
7561da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
7571da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
7581da177e4SLinus Torvalds 
7591da177e4SLinus Torvalds 	/* Drop last sent command */
7601da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
761b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
7621da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
7631da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
7641da177e4SLinus Torvalds 	}
7651da177e4SLinus Torvalds 
7661da177e4SLinus Torvalds 	/* After this point our queues are empty
7671da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
7681da177e4SLinus Torvalds 	hdev->close(hdev);
7691da177e4SLinus Torvalds 
77009fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
771744cf19eSJohan Hedberg 	mgmt_powered(hdev, 0);
77209fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
7735add6af8SJohan Hedberg 
7741da177e4SLinus Torvalds 	/* Clear flags */
7751da177e4SLinus Torvalds 	hdev->flags = 0;
7761da177e4SLinus Torvalds 
7771da177e4SLinus Torvalds 	hci_req_unlock(hdev);
7781da177e4SLinus Torvalds 
7791da177e4SLinus Torvalds 	hci_dev_put(hdev);
7801da177e4SLinus Torvalds 	return 0;
7811da177e4SLinus Torvalds }
7821da177e4SLinus Torvalds 
7831da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
7841da177e4SLinus Torvalds {
7851da177e4SLinus Torvalds 	struct hci_dev *hdev;
7861da177e4SLinus Torvalds 	int err;
7871da177e4SLinus Torvalds 
78870f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
78970f23020SAndrei Emeltchenko 	if (!hdev)
7901da177e4SLinus Torvalds 		return -ENODEV;
7911da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
7921da177e4SLinus Torvalds 	hci_dev_put(hdev);
7931da177e4SLinus Torvalds 	return err;
7941da177e4SLinus Torvalds }
7951da177e4SLinus Torvalds 
7961da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
7971da177e4SLinus Torvalds {
7981da177e4SLinus Torvalds 	struct hci_dev *hdev;
7991da177e4SLinus Torvalds 	int ret = 0;
8001da177e4SLinus Torvalds 
80170f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
80270f23020SAndrei Emeltchenko 	if (!hdev)
8031da177e4SLinus Torvalds 		return -ENODEV;
8041da177e4SLinus Torvalds 
8051da177e4SLinus Torvalds 	hci_req_lock(hdev);
8061da177e4SLinus Torvalds 
8071da177e4SLinus Torvalds 	if (!test_bit(HCI_UP, &hdev->flags))
8081da177e4SLinus Torvalds 		goto done;
8091da177e4SLinus Torvalds 
8101da177e4SLinus Torvalds 	/* Drop queues */
8111da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
8121da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
8131da177e4SLinus Torvalds 
81409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
8151da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
8161da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
81709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
8181da177e4SLinus Torvalds 
8191da177e4SLinus Torvalds 	if (hdev->flush)
8201da177e4SLinus Torvalds 		hdev->flush(hdev);
8211da177e4SLinus Torvalds 
8221da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
8236ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
8241da177e4SLinus Torvalds 
8251da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags))
82604837f64SMarcel Holtmann 		ret = __hci_request(hdev, hci_reset_req, 0,
82704837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
8281da177e4SLinus Torvalds 
8291da177e4SLinus Torvalds done:
8301da177e4SLinus Torvalds 	hci_req_unlock(hdev);
8311da177e4SLinus Torvalds 	hci_dev_put(hdev);
8321da177e4SLinus Torvalds 	return ret;
8331da177e4SLinus Torvalds }
8341da177e4SLinus Torvalds 
8351da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
8361da177e4SLinus Torvalds {
8371da177e4SLinus Torvalds 	struct hci_dev *hdev;
8381da177e4SLinus Torvalds 	int ret = 0;
8391da177e4SLinus Torvalds 
84070f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
84170f23020SAndrei Emeltchenko 	if (!hdev)
8421da177e4SLinus Torvalds 		return -ENODEV;
8431da177e4SLinus Torvalds 
8441da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
8451da177e4SLinus Torvalds 
8461da177e4SLinus Torvalds 	hci_dev_put(hdev);
8471da177e4SLinus Torvalds 
8481da177e4SLinus Torvalds 	return ret;
8491da177e4SLinus Torvalds }
8501da177e4SLinus Torvalds 
8511da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
8521da177e4SLinus Torvalds {
8531da177e4SLinus Torvalds 	struct hci_dev *hdev;
8541da177e4SLinus Torvalds 	struct hci_dev_req dr;
8551da177e4SLinus Torvalds 	int err = 0;
8561da177e4SLinus Torvalds 
8571da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
8581da177e4SLinus Torvalds 		return -EFAULT;
8591da177e4SLinus Torvalds 
86070f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
86170f23020SAndrei Emeltchenko 	if (!hdev)
8621da177e4SLinus Torvalds 		return -ENODEV;
8631da177e4SLinus Torvalds 
8641da177e4SLinus Torvalds 	switch (cmd) {
8651da177e4SLinus Torvalds 	case HCISETAUTH:
86604837f64SMarcel Holtmann 		err = hci_request(hdev, hci_auth_req, dr.dev_opt,
86704837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
8681da177e4SLinus Torvalds 		break;
8691da177e4SLinus Torvalds 
8701da177e4SLinus Torvalds 	case HCISETENCRYPT:
8711da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
8721da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
8731da177e4SLinus Torvalds 			break;
8741da177e4SLinus Torvalds 		}
8751da177e4SLinus Torvalds 
8761da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
8771da177e4SLinus Torvalds 			/* Auth must be enabled first */
87804837f64SMarcel Holtmann 			err = hci_request(hdev, hci_auth_req, dr.dev_opt,
87904837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
8801da177e4SLinus Torvalds 			if (err)
8811da177e4SLinus Torvalds 				break;
8821da177e4SLinus Torvalds 		}
8831da177e4SLinus Torvalds 
88404837f64SMarcel Holtmann 		err = hci_request(hdev, hci_encrypt_req, dr.dev_opt,
88504837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
8861da177e4SLinus Torvalds 		break;
8871da177e4SLinus Torvalds 
8881da177e4SLinus Torvalds 	case HCISETSCAN:
88904837f64SMarcel Holtmann 		err = hci_request(hdev, hci_scan_req, dr.dev_opt,
89004837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
8911da177e4SLinus Torvalds 		break;
8921da177e4SLinus Torvalds 
8931da177e4SLinus Torvalds 	case HCISETLINKPOL:
894e4e8e37cSMarcel Holtmann 		err = hci_request(hdev, hci_linkpol_req, dr.dev_opt,
895e4e8e37cSMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
8961da177e4SLinus Torvalds 		break;
8971da177e4SLinus Torvalds 
8981da177e4SLinus Torvalds 	case HCISETLINKMODE:
899e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
900e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
901e4e8e37cSMarcel Holtmann 		break;
902e4e8e37cSMarcel Holtmann 
903e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
904e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
9051da177e4SLinus Torvalds 		break;
9061da177e4SLinus Torvalds 
9071da177e4SLinus Torvalds 	case HCISETACLMTU:
9081da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
9091da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
9101da177e4SLinus Torvalds 		break;
9111da177e4SLinus Torvalds 
9121da177e4SLinus Torvalds 	case HCISETSCOMTU:
9131da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
9141da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
9151da177e4SLinus Torvalds 		break;
9161da177e4SLinus Torvalds 
9171da177e4SLinus Torvalds 	default:
9181da177e4SLinus Torvalds 		err = -EINVAL;
9191da177e4SLinus Torvalds 		break;
9201da177e4SLinus Torvalds 	}
921e4e8e37cSMarcel Holtmann 
9221da177e4SLinus Torvalds 	hci_dev_put(hdev);
9231da177e4SLinus Torvalds 	return err;
9241da177e4SLinus Torvalds }
9251da177e4SLinus Torvalds 
9261da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
9271da177e4SLinus Torvalds {
9288035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
9291da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
9301da177e4SLinus Torvalds 	struct hci_dev_req *dr;
9311da177e4SLinus Torvalds 	int n = 0, size, err;
9321da177e4SLinus Torvalds 	__u16 dev_num;
9331da177e4SLinus Torvalds 
9341da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
9351da177e4SLinus Torvalds 		return -EFAULT;
9361da177e4SLinus Torvalds 
9371da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
9381da177e4SLinus Torvalds 		return -EINVAL;
9391da177e4SLinus Torvalds 
9401da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
9411da177e4SLinus Torvalds 
94270f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
94370f23020SAndrei Emeltchenko 	if (!dl)
9441da177e4SLinus Torvalds 		return -ENOMEM;
9451da177e4SLinus Torvalds 
9461da177e4SLinus Torvalds 	dr = dl->dev_req;
9471da177e4SLinus Torvalds 
948f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
9498035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
9503243553fSJohan Hedberg 		if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags))
951e0f9309fSJohan Hedberg 			cancel_delayed_work(&hdev->power_off);
952c542a06cSJohan Hedberg 
953c542a06cSJohan Hedberg 		if (!test_bit(HCI_MGMT, &hdev->flags))
954c542a06cSJohan Hedberg 			set_bit(HCI_PAIRABLE, &hdev->flags);
955c542a06cSJohan Hedberg 
9561da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
9571da177e4SLinus Torvalds 		(dr + n)->dev_opt = hdev->flags;
958c542a06cSJohan Hedberg 
9591da177e4SLinus Torvalds 		if (++n >= dev_num)
9601da177e4SLinus Torvalds 			break;
9611da177e4SLinus Torvalds 	}
962f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
9631da177e4SLinus Torvalds 
9641da177e4SLinus Torvalds 	dl->dev_num = n;
9651da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
9661da177e4SLinus Torvalds 
9671da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
9681da177e4SLinus Torvalds 	kfree(dl);
9691da177e4SLinus Torvalds 
9701da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
9711da177e4SLinus Torvalds }
9721da177e4SLinus Torvalds 
9731da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
9741da177e4SLinus Torvalds {
9751da177e4SLinus Torvalds 	struct hci_dev *hdev;
9761da177e4SLinus Torvalds 	struct hci_dev_info di;
9771da177e4SLinus Torvalds 	int err = 0;
9781da177e4SLinus Torvalds 
9791da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
9801da177e4SLinus Torvalds 		return -EFAULT;
9811da177e4SLinus Torvalds 
98270f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
98370f23020SAndrei Emeltchenko 	if (!hdev)
9841da177e4SLinus Torvalds 		return -ENODEV;
9851da177e4SLinus Torvalds 
9863243553fSJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags))
9873243553fSJohan Hedberg 		cancel_delayed_work_sync(&hdev->power_off);
988ab81cbf9SJohan Hedberg 
989c542a06cSJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->flags))
990c542a06cSJohan Hedberg 		set_bit(HCI_PAIRABLE, &hdev->flags);
991c542a06cSJohan Hedberg 
9921da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
9931da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
994943da25dSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | (hdev->dev_type << 4);
9951da177e4SLinus Torvalds 	di.flags    = hdev->flags;
9961da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
9971da177e4SLinus Torvalds 	di.acl_mtu  = hdev->acl_mtu;
9981da177e4SLinus Torvalds 	di.acl_pkts = hdev->acl_pkts;
9991da177e4SLinus Torvalds 	di.sco_mtu  = hdev->sco_mtu;
10001da177e4SLinus Torvalds 	di.sco_pkts = hdev->sco_pkts;
10011da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
10021da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
10031da177e4SLinus Torvalds 
10041da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
10051da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
10061da177e4SLinus Torvalds 
10071da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
10081da177e4SLinus Torvalds 		err = -EFAULT;
10091da177e4SLinus Torvalds 
10101da177e4SLinus Torvalds 	hci_dev_put(hdev);
10111da177e4SLinus Torvalds 
10121da177e4SLinus Torvalds 	return err;
10131da177e4SLinus Torvalds }
10141da177e4SLinus Torvalds 
10151da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
10161da177e4SLinus Torvalds 
1017611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
1018611b30f7SMarcel Holtmann {
1019611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
1020611b30f7SMarcel Holtmann 
1021611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
1022611b30f7SMarcel Holtmann 
1023611b30f7SMarcel Holtmann 	if (!blocked)
1024611b30f7SMarcel Holtmann 		return 0;
1025611b30f7SMarcel Holtmann 
1026611b30f7SMarcel Holtmann 	hci_dev_do_close(hdev);
1027611b30f7SMarcel Holtmann 
1028611b30f7SMarcel Holtmann 	return 0;
1029611b30f7SMarcel Holtmann }
1030611b30f7SMarcel Holtmann 
1031611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
1032611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
1033611b30f7SMarcel Holtmann };
1034611b30f7SMarcel Holtmann 
10351da177e4SLinus Torvalds /* Alloc HCI device */
10361da177e4SLinus Torvalds struct hci_dev *hci_alloc_dev(void)
10371da177e4SLinus Torvalds {
10381da177e4SLinus Torvalds 	struct hci_dev *hdev;
10391da177e4SLinus Torvalds 
104025ea6db0SMarcel Holtmann 	hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
10411da177e4SLinus Torvalds 	if (!hdev)
10421da177e4SLinus Torvalds 		return NULL;
10431da177e4SLinus Torvalds 
10440ac7e700SDavid Herrmann 	hci_init_sysfs(hdev);
10451da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->driver_init);
10461da177e4SLinus Torvalds 
10471da177e4SLinus Torvalds 	return hdev;
10481da177e4SLinus Torvalds }
10491da177e4SLinus Torvalds EXPORT_SYMBOL(hci_alloc_dev);
10501da177e4SLinus Torvalds 
10511da177e4SLinus Torvalds /* Free HCI device */
10521da177e4SLinus Torvalds void hci_free_dev(struct hci_dev *hdev)
10531da177e4SLinus Torvalds {
10541da177e4SLinus Torvalds 	skb_queue_purge(&hdev->driver_init);
10551da177e4SLinus Torvalds 
1056a91f2e39SMarcel Holtmann 	/* will free via device release */
1057a91f2e39SMarcel Holtmann 	put_device(&hdev->dev);
10581da177e4SLinus Torvalds }
10591da177e4SLinus Torvalds EXPORT_SYMBOL(hci_free_dev);
10601da177e4SLinus Torvalds 
1061ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
1062ab81cbf9SJohan Hedberg {
1063ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
1064ab81cbf9SJohan Hedberg 
1065ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1066ab81cbf9SJohan Hedberg 
1067ab81cbf9SJohan Hedberg 	if (hci_dev_open(hdev->id) < 0)
1068ab81cbf9SJohan Hedberg 		return;
1069ab81cbf9SJohan Hedberg 
1070ab81cbf9SJohan Hedberg 	if (test_bit(HCI_AUTO_OFF, &hdev->flags))
107180b7ab33SGustavo F. Padovan 		schedule_delayed_work(&hdev->power_off,
10723243553fSJohan Hedberg 					msecs_to_jiffies(AUTO_OFF_TIMEOUT));
1073ab81cbf9SJohan Hedberg 
1074ab81cbf9SJohan Hedberg 	if (test_and_clear_bit(HCI_SETUP, &hdev->flags))
1075744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
1076ab81cbf9SJohan Hedberg }
1077ab81cbf9SJohan Hedberg 
1078ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
1079ab81cbf9SJohan Hedberg {
10803243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
10813243553fSJohan Hedberg 							power_off.work);
1082ab81cbf9SJohan Hedberg 
1083ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1084ab81cbf9SJohan Hedberg 
10853243553fSJohan Hedberg 	clear_bit(HCI_AUTO_OFF, &hdev->flags);
10863243553fSJohan Hedberg 
1087ab81cbf9SJohan Hedberg 	hci_dev_close(hdev->id);
1088ab81cbf9SJohan Hedberg }
1089ab81cbf9SJohan Hedberg 
109016ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
109116ab91abSJohan Hedberg {
109216ab91abSJohan Hedberg 	struct hci_dev *hdev;
109316ab91abSJohan Hedberg 	u8 scan = SCAN_PAGE;
109416ab91abSJohan Hedberg 
109516ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
109616ab91abSJohan Hedberg 
109716ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
109816ab91abSJohan Hedberg 
109909fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
110016ab91abSJohan Hedberg 
110116ab91abSJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan);
110216ab91abSJohan Hedberg 
110316ab91abSJohan Hedberg 	hdev->discov_timeout = 0;
110416ab91abSJohan Hedberg 
110509fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
110616ab91abSJohan Hedberg }
110716ab91abSJohan Hedberg 
11082aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev)
11092aeb9a1aSJohan Hedberg {
11102aeb9a1aSJohan Hedberg 	struct list_head *p, *n;
11112aeb9a1aSJohan Hedberg 
11122aeb9a1aSJohan Hedberg 	list_for_each_safe(p, n, &hdev->uuids) {
11132aeb9a1aSJohan Hedberg 		struct bt_uuid *uuid;
11142aeb9a1aSJohan Hedberg 
11152aeb9a1aSJohan Hedberg 		uuid = list_entry(p, struct bt_uuid, list);
11162aeb9a1aSJohan Hedberg 
11172aeb9a1aSJohan Hedberg 		list_del(p);
11182aeb9a1aSJohan Hedberg 		kfree(uuid);
11192aeb9a1aSJohan Hedberg 	}
11202aeb9a1aSJohan Hedberg 
11212aeb9a1aSJohan Hedberg 	return 0;
11222aeb9a1aSJohan Hedberg }
11232aeb9a1aSJohan Hedberg 
112455ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev)
112555ed8ca1SJohan Hedberg {
112655ed8ca1SJohan Hedberg 	struct list_head *p, *n;
112755ed8ca1SJohan Hedberg 
112855ed8ca1SJohan Hedberg 	list_for_each_safe(p, n, &hdev->link_keys) {
112955ed8ca1SJohan Hedberg 		struct link_key *key;
113055ed8ca1SJohan Hedberg 
113155ed8ca1SJohan Hedberg 		key = list_entry(p, struct link_key, list);
113255ed8ca1SJohan Hedberg 
113355ed8ca1SJohan Hedberg 		list_del(p);
113455ed8ca1SJohan Hedberg 		kfree(key);
113555ed8ca1SJohan Hedberg 	}
113655ed8ca1SJohan Hedberg 
113755ed8ca1SJohan Hedberg 	return 0;
113855ed8ca1SJohan Hedberg }
113955ed8ca1SJohan Hedberg 
114055ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
114155ed8ca1SJohan Hedberg {
114255ed8ca1SJohan Hedberg 	struct link_key *k;
114355ed8ca1SJohan Hedberg 
11448035ded4SLuiz Augusto von Dentz 	list_for_each_entry(k, &hdev->link_keys, list)
114555ed8ca1SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0)
114655ed8ca1SJohan Hedberg 			return k;
114755ed8ca1SJohan Hedberg 
114855ed8ca1SJohan Hedberg 	return NULL;
114955ed8ca1SJohan Hedberg }
115055ed8ca1SJohan Hedberg 
1151d25e28abSJohan Hedberg static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1152d25e28abSJohan Hedberg 						u8 key_type, u8 old_key_type)
1153d25e28abSJohan Hedberg {
1154d25e28abSJohan Hedberg 	/* Legacy key */
1155d25e28abSJohan Hedberg 	if (key_type < 0x03)
1156d25e28abSJohan Hedberg 		return 1;
1157d25e28abSJohan Hedberg 
1158d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
1159d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
1160d25e28abSJohan Hedberg 		return 0;
1161d25e28abSJohan Hedberg 
1162d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
1163d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
1164d25e28abSJohan Hedberg 		return 0;
1165d25e28abSJohan Hedberg 
1166d25e28abSJohan Hedberg 	/* Security mode 3 case */
1167d25e28abSJohan Hedberg 	if (!conn)
1168d25e28abSJohan Hedberg 		return 1;
1169d25e28abSJohan Hedberg 
1170d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
1171d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
1172d25e28abSJohan Hedberg 		return 1;
1173d25e28abSJohan Hedberg 
1174d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
1175d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
1176d25e28abSJohan Hedberg 		return 1;
1177d25e28abSJohan Hedberg 
1178d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
1179d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
1180d25e28abSJohan Hedberg 		return 1;
1181d25e28abSJohan Hedberg 
1182d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
1183d25e28abSJohan Hedberg 	 * persistently */
1184d25e28abSJohan Hedberg 	return 0;
1185d25e28abSJohan Hedberg }
1186d25e28abSJohan Hedberg 
118775d262c2SVinicius Costa Gomes struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
118875d262c2SVinicius Costa Gomes {
118975d262c2SVinicius Costa Gomes 	struct link_key *k;
119075d262c2SVinicius Costa Gomes 
119175d262c2SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->link_keys, list) {
119275d262c2SVinicius Costa Gomes 		struct key_master_id *id;
119375d262c2SVinicius Costa Gomes 
119475d262c2SVinicius Costa Gomes 		if (k->type != HCI_LK_SMP_LTK)
119575d262c2SVinicius Costa Gomes 			continue;
119675d262c2SVinicius Costa Gomes 
119775d262c2SVinicius Costa Gomes 		if (k->dlen != sizeof(*id))
119875d262c2SVinicius Costa Gomes 			continue;
119975d262c2SVinicius Costa Gomes 
120075d262c2SVinicius Costa Gomes 		id = (void *) &k->data;
120175d262c2SVinicius Costa Gomes 		if (id->ediv == ediv &&
120275d262c2SVinicius Costa Gomes 				(memcmp(rand, id->rand, sizeof(id->rand)) == 0))
120375d262c2SVinicius Costa Gomes 			return k;
120475d262c2SVinicius Costa Gomes 	}
120575d262c2SVinicius Costa Gomes 
120675d262c2SVinicius Costa Gomes 	return NULL;
120775d262c2SVinicius Costa Gomes }
120875d262c2SVinicius Costa Gomes EXPORT_SYMBOL(hci_find_ltk);
120975d262c2SVinicius Costa Gomes 
121075d262c2SVinicius Costa Gomes struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
121175d262c2SVinicius Costa Gomes 					bdaddr_t *bdaddr, u8 type)
121275d262c2SVinicius Costa Gomes {
121375d262c2SVinicius Costa Gomes 	struct link_key *k;
121475d262c2SVinicius Costa Gomes 
121575d262c2SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->link_keys, list)
121675d262c2SVinicius Costa Gomes 		if (k->type == type && bacmp(bdaddr, &k->bdaddr) == 0)
121775d262c2SVinicius Costa Gomes 			return k;
121875d262c2SVinicius Costa Gomes 
121975d262c2SVinicius Costa Gomes 	return NULL;
122075d262c2SVinicius Costa Gomes }
122175d262c2SVinicius Costa Gomes EXPORT_SYMBOL(hci_find_link_key_type);
122275d262c2SVinicius Costa Gomes 
1223d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
1224d25e28abSJohan Hedberg 				bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
122555ed8ca1SJohan Hedberg {
122655ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
12274df378a1SJohan Hedberg 	u8 old_key_type, persistent;
122855ed8ca1SJohan Hedberg 
122955ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
123055ed8ca1SJohan Hedberg 	if (old_key) {
123155ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
123255ed8ca1SJohan Hedberg 		key = old_key;
123355ed8ca1SJohan Hedberg 	} else {
123412adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
123555ed8ca1SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
123655ed8ca1SJohan Hedberg 		if (!key)
123755ed8ca1SJohan Hedberg 			return -ENOMEM;
123855ed8ca1SJohan Hedberg 		list_add(&key->list, &hdev->link_keys);
123955ed8ca1SJohan Hedberg 	}
124055ed8ca1SJohan Hedberg 
124155ed8ca1SJohan Hedberg 	BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type);
124255ed8ca1SJohan Hedberg 
1243d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
1244d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
1245d25e28abSJohan Hedberg 	 * previous key */
1246d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
1247d25e28abSJohan Hedberg 					(!conn || conn->remote_auth == 0xff) &&
1248655fe6ecSJohan Hedberg 					old_key_type == 0xff) {
1249d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
1250655fe6ecSJohan Hedberg 		if (conn)
1251655fe6ecSJohan Hedberg 			conn->key_type = type;
1252655fe6ecSJohan Hedberg 	}
1253d25e28abSJohan Hedberg 
125455ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
125555ed8ca1SJohan Hedberg 	memcpy(key->val, val, 16);
125655ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
125755ed8ca1SJohan Hedberg 
1258b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
125955ed8ca1SJohan Hedberg 		key->type = old_key_type;
12604748fed2SJohan Hedberg 	else
12614748fed2SJohan Hedberg 		key->type = type;
12624748fed2SJohan Hedberg 
12634df378a1SJohan Hedberg 	if (!new_key)
12644df378a1SJohan Hedberg 		return 0;
12654df378a1SJohan Hedberg 
12664df378a1SJohan Hedberg 	persistent = hci_persistent_key(hdev, conn, type, old_key_type);
12674df378a1SJohan Hedberg 
1268744cf19eSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
12694df378a1SJohan Hedberg 
12704df378a1SJohan Hedberg 	if (!persistent) {
12714df378a1SJohan Hedberg 		list_del(&key->list);
12724df378a1SJohan Hedberg 		kfree(key);
12734df378a1SJohan Hedberg 	}
127455ed8ca1SJohan Hedberg 
127555ed8ca1SJohan Hedberg 	return 0;
127655ed8ca1SJohan Hedberg }
127755ed8ca1SJohan Hedberg 
127875d262c2SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
1279726b4ffcSVinicius Costa Gomes 			u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16])
128075d262c2SVinicius Costa Gomes {
128175d262c2SVinicius Costa Gomes 	struct link_key *key, *old_key;
128275d262c2SVinicius Costa Gomes 	struct key_master_id *id;
128375d262c2SVinicius Costa Gomes 	u8 old_key_type;
128475d262c2SVinicius Costa Gomes 
128575d262c2SVinicius Costa Gomes 	BT_DBG("%s addr %s", hdev->name, batostr(bdaddr));
128675d262c2SVinicius Costa Gomes 
128775d262c2SVinicius Costa Gomes 	old_key = hci_find_link_key_type(hdev, bdaddr, HCI_LK_SMP_LTK);
128875d262c2SVinicius Costa Gomes 	if (old_key) {
128975d262c2SVinicius Costa Gomes 		key = old_key;
129075d262c2SVinicius Costa Gomes 		old_key_type = old_key->type;
129175d262c2SVinicius Costa Gomes 	} else {
129275d262c2SVinicius Costa Gomes 		key = kzalloc(sizeof(*key) + sizeof(*id), GFP_ATOMIC);
129375d262c2SVinicius Costa Gomes 		if (!key)
129475d262c2SVinicius Costa Gomes 			return -ENOMEM;
129575d262c2SVinicius Costa Gomes 		list_add(&key->list, &hdev->link_keys);
129675d262c2SVinicius Costa Gomes 		old_key_type = 0xff;
129775d262c2SVinicius Costa Gomes 	}
129875d262c2SVinicius Costa Gomes 
129975d262c2SVinicius Costa Gomes 	key->dlen = sizeof(*id);
130075d262c2SVinicius Costa Gomes 
130175d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
130275d262c2SVinicius Costa Gomes 	memcpy(key->val, ltk, sizeof(key->val));
130375d262c2SVinicius Costa Gomes 	key->type = HCI_LK_SMP_LTK;
1304726b4ffcSVinicius Costa Gomes 	key->pin_len = key_size;
130575d262c2SVinicius Costa Gomes 
130675d262c2SVinicius Costa Gomes 	id = (void *) &key->data;
130775d262c2SVinicius Costa Gomes 	id->ediv = ediv;
130875d262c2SVinicius Costa Gomes 	memcpy(id->rand, rand, sizeof(id->rand));
130975d262c2SVinicius Costa Gomes 
131075d262c2SVinicius Costa Gomes 	if (new_key)
1311744cf19eSJohan Hedberg 		mgmt_new_link_key(hdev, key, old_key_type);
131275d262c2SVinicius Costa Gomes 
131375d262c2SVinicius Costa Gomes 	return 0;
131475d262c2SVinicius Costa Gomes }
131575d262c2SVinicius Costa Gomes 
131655ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
131755ed8ca1SJohan Hedberg {
131855ed8ca1SJohan Hedberg 	struct link_key *key;
131955ed8ca1SJohan Hedberg 
132055ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
132155ed8ca1SJohan Hedberg 	if (!key)
132255ed8ca1SJohan Hedberg 		return -ENOENT;
132355ed8ca1SJohan Hedberg 
132455ed8ca1SJohan Hedberg 	BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
132555ed8ca1SJohan Hedberg 
132655ed8ca1SJohan Hedberg 	list_del(&key->list);
132755ed8ca1SJohan Hedberg 	kfree(key);
132855ed8ca1SJohan Hedberg 
132955ed8ca1SJohan Hedberg 	return 0;
133055ed8ca1SJohan Hedberg }
133155ed8ca1SJohan Hedberg 
13326bd32326SVille Tervo /* HCI command timer function */
13336bd32326SVille Tervo static void hci_cmd_timer(unsigned long arg)
13346bd32326SVille Tervo {
13356bd32326SVille Tervo 	struct hci_dev *hdev = (void *) arg;
13366bd32326SVille Tervo 
13376bd32326SVille Tervo 	BT_ERR("%s command tx timeout", hdev->name);
13386bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
1339c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
13406bd32326SVille Tervo }
13416bd32326SVille Tervo 
13422763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
13432763eda6SSzymon Janc 							bdaddr_t *bdaddr)
13442763eda6SSzymon Janc {
13452763eda6SSzymon Janc 	struct oob_data *data;
13462763eda6SSzymon Janc 
13472763eda6SSzymon Janc 	list_for_each_entry(data, &hdev->remote_oob_data, list)
13482763eda6SSzymon Janc 		if (bacmp(bdaddr, &data->bdaddr) == 0)
13492763eda6SSzymon Janc 			return data;
13502763eda6SSzymon Janc 
13512763eda6SSzymon Janc 	return NULL;
13522763eda6SSzymon Janc }
13532763eda6SSzymon Janc 
13542763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
13552763eda6SSzymon Janc {
13562763eda6SSzymon Janc 	struct oob_data *data;
13572763eda6SSzymon Janc 
13582763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
13592763eda6SSzymon Janc 	if (!data)
13602763eda6SSzymon Janc 		return -ENOENT;
13612763eda6SSzymon Janc 
13622763eda6SSzymon Janc 	BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
13632763eda6SSzymon Janc 
13642763eda6SSzymon Janc 	list_del(&data->list);
13652763eda6SSzymon Janc 	kfree(data);
13662763eda6SSzymon Janc 
13672763eda6SSzymon Janc 	return 0;
13682763eda6SSzymon Janc }
13692763eda6SSzymon Janc 
13702763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev)
13712763eda6SSzymon Janc {
13722763eda6SSzymon Janc 	struct oob_data *data, *n;
13732763eda6SSzymon Janc 
13742763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
13752763eda6SSzymon Janc 		list_del(&data->list);
13762763eda6SSzymon Janc 		kfree(data);
13772763eda6SSzymon Janc 	}
13782763eda6SSzymon Janc 
13792763eda6SSzymon Janc 	return 0;
13802763eda6SSzymon Janc }
13812763eda6SSzymon Janc 
13822763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
13832763eda6SSzymon Janc 								u8 *randomizer)
13842763eda6SSzymon Janc {
13852763eda6SSzymon Janc 	struct oob_data *data;
13862763eda6SSzymon Janc 
13872763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
13882763eda6SSzymon Janc 
13892763eda6SSzymon Janc 	if (!data) {
13902763eda6SSzymon Janc 		data = kmalloc(sizeof(*data), GFP_ATOMIC);
13912763eda6SSzymon Janc 		if (!data)
13922763eda6SSzymon Janc 			return -ENOMEM;
13932763eda6SSzymon Janc 
13942763eda6SSzymon Janc 		bacpy(&data->bdaddr, bdaddr);
13952763eda6SSzymon Janc 		list_add(&data->list, &hdev->remote_oob_data);
13962763eda6SSzymon Janc 	}
13972763eda6SSzymon Janc 
13982763eda6SSzymon Janc 	memcpy(data->hash, hash, sizeof(data->hash));
13992763eda6SSzymon Janc 	memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
14002763eda6SSzymon Janc 
14012763eda6SSzymon Janc 	BT_DBG("%s for %s", hdev->name, batostr(bdaddr));
14022763eda6SSzymon Janc 
14032763eda6SSzymon Janc 	return 0;
14042763eda6SSzymon Janc }
14052763eda6SSzymon Janc 
1406b2a66aadSAntti Julku struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev,
1407b2a66aadSAntti Julku 						bdaddr_t *bdaddr)
1408b2a66aadSAntti Julku {
1409b2a66aadSAntti Julku 	struct bdaddr_list *b;
1410b2a66aadSAntti Julku 
14118035ded4SLuiz Augusto von Dentz 	list_for_each_entry(b, &hdev->blacklist, list)
1412b2a66aadSAntti Julku 		if (bacmp(bdaddr, &b->bdaddr) == 0)
1413b2a66aadSAntti Julku 			return b;
1414b2a66aadSAntti Julku 
1415b2a66aadSAntti Julku 	return NULL;
1416b2a66aadSAntti Julku }
1417b2a66aadSAntti Julku 
1418b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev)
1419b2a66aadSAntti Julku {
1420b2a66aadSAntti Julku 	struct list_head *p, *n;
1421b2a66aadSAntti Julku 
1422b2a66aadSAntti Julku 	list_for_each_safe(p, n, &hdev->blacklist) {
1423b2a66aadSAntti Julku 		struct bdaddr_list *b;
1424b2a66aadSAntti Julku 
1425b2a66aadSAntti Julku 		b = list_entry(p, struct bdaddr_list, list);
1426b2a66aadSAntti Julku 
1427b2a66aadSAntti Julku 		list_del(p);
1428b2a66aadSAntti Julku 		kfree(b);
1429b2a66aadSAntti Julku 	}
1430b2a66aadSAntti Julku 
1431b2a66aadSAntti Julku 	return 0;
1432b2a66aadSAntti Julku }
1433b2a66aadSAntti Julku 
1434b2a66aadSAntti Julku int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr)
1435b2a66aadSAntti Julku {
1436b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1437b2a66aadSAntti Julku 
1438b2a66aadSAntti Julku 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
1439b2a66aadSAntti Julku 		return -EBADF;
1440b2a66aadSAntti Julku 
14415e762444SAntti Julku 	if (hci_blacklist_lookup(hdev, bdaddr))
14425e762444SAntti Julku 		return -EEXIST;
1443b2a66aadSAntti Julku 
1444b2a66aadSAntti Julku 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
14455e762444SAntti Julku 	if (!entry)
14465e762444SAntti Julku 		return -ENOMEM;
1447b2a66aadSAntti Julku 
1448b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
1449b2a66aadSAntti Julku 
1450b2a66aadSAntti Julku 	list_add(&entry->list, &hdev->blacklist);
1451b2a66aadSAntti Julku 
1452744cf19eSJohan Hedberg 	return mgmt_device_blocked(hdev, bdaddr);
1453b2a66aadSAntti Julku }
1454b2a66aadSAntti Julku 
1455b2a66aadSAntti Julku int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr)
1456b2a66aadSAntti Julku {
1457b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1458b2a66aadSAntti Julku 
14591ec918ceSSzymon Janc 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
14605e762444SAntti Julku 		return hci_blacklist_clear(hdev);
1461b2a66aadSAntti Julku 
1462b2a66aadSAntti Julku 	entry = hci_blacklist_lookup(hdev, bdaddr);
14631ec918ceSSzymon Janc 	if (!entry)
14645e762444SAntti Julku 		return -ENOENT;
1465b2a66aadSAntti Julku 
1466b2a66aadSAntti Julku 	list_del(&entry->list);
1467b2a66aadSAntti Julku 	kfree(entry);
1468b2a66aadSAntti Julku 
1469744cf19eSJohan Hedberg 	return mgmt_device_unblocked(hdev, bdaddr);
1470b2a66aadSAntti Julku }
1471b2a66aadSAntti Julku 
1472db323f2fSGustavo F. Padovan static void hci_clear_adv_cache(struct work_struct *work)
147335815085SAndre Guedes {
1474db323f2fSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev,
1475db323f2fSGustavo F. Padovan 							adv_work.work);
147635815085SAndre Guedes 
147735815085SAndre Guedes 	hci_dev_lock(hdev);
147835815085SAndre Guedes 
147935815085SAndre Guedes 	hci_adv_entries_clear(hdev);
148035815085SAndre Guedes 
148135815085SAndre Guedes 	hci_dev_unlock(hdev);
148235815085SAndre Guedes }
148335815085SAndre Guedes 
148476c8686fSAndre Guedes int hci_adv_entries_clear(struct hci_dev *hdev)
148576c8686fSAndre Guedes {
148676c8686fSAndre Guedes 	struct adv_entry *entry, *tmp;
148776c8686fSAndre Guedes 
148876c8686fSAndre Guedes 	list_for_each_entry_safe(entry, tmp, &hdev->adv_entries, list) {
148976c8686fSAndre Guedes 		list_del(&entry->list);
149076c8686fSAndre Guedes 		kfree(entry);
149176c8686fSAndre Guedes 	}
149276c8686fSAndre Guedes 
149376c8686fSAndre Guedes 	BT_DBG("%s adv cache cleared", hdev->name);
149476c8686fSAndre Guedes 
149576c8686fSAndre Guedes 	return 0;
149676c8686fSAndre Guedes }
149776c8686fSAndre Guedes 
149876c8686fSAndre Guedes struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr)
149976c8686fSAndre Guedes {
150076c8686fSAndre Guedes 	struct adv_entry *entry;
150176c8686fSAndre Guedes 
150276c8686fSAndre Guedes 	list_for_each_entry(entry, &hdev->adv_entries, list)
150376c8686fSAndre Guedes 		if (bacmp(bdaddr, &entry->bdaddr) == 0)
150476c8686fSAndre Guedes 			return entry;
150576c8686fSAndre Guedes 
150676c8686fSAndre Guedes 	return NULL;
150776c8686fSAndre Guedes }
150876c8686fSAndre Guedes 
150976c8686fSAndre Guedes static inline int is_connectable_adv(u8 evt_type)
151076c8686fSAndre Guedes {
151176c8686fSAndre Guedes 	if (evt_type == ADV_IND || evt_type == ADV_DIRECT_IND)
151276c8686fSAndre Guedes 		return 1;
151376c8686fSAndre Guedes 
151476c8686fSAndre Guedes 	return 0;
151576c8686fSAndre Guedes }
151676c8686fSAndre Guedes 
151776c8686fSAndre Guedes int hci_add_adv_entry(struct hci_dev *hdev,
151876c8686fSAndre Guedes 					struct hci_ev_le_advertising_info *ev)
151976c8686fSAndre Guedes {
152076c8686fSAndre Guedes 	struct adv_entry *entry;
152176c8686fSAndre Guedes 
152276c8686fSAndre Guedes 	if (!is_connectable_adv(ev->evt_type))
152376c8686fSAndre Guedes 		return -EINVAL;
152476c8686fSAndre Guedes 
152576c8686fSAndre Guedes 	/* Only new entries should be added to adv_entries. So, if
152676c8686fSAndre Guedes 	 * bdaddr was found, don't add it. */
152776c8686fSAndre Guedes 	if (hci_find_adv_entry(hdev, &ev->bdaddr))
152876c8686fSAndre Guedes 		return 0;
152976c8686fSAndre Guedes 
153076c8686fSAndre Guedes 	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
153176c8686fSAndre Guedes 	if (!entry)
153276c8686fSAndre Guedes 		return -ENOMEM;
153376c8686fSAndre Guedes 
153476c8686fSAndre Guedes 	bacpy(&entry->bdaddr, &ev->bdaddr);
153576c8686fSAndre Guedes 	entry->bdaddr_type = ev->bdaddr_type;
153676c8686fSAndre Guedes 
153776c8686fSAndre Guedes 	list_add(&entry->list, &hdev->adv_entries);
153876c8686fSAndre Guedes 
153976c8686fSAndre Guedes 	BT_DBG("%s adv entry added: address %s type %u", hdev->name,
154076c8686fSAndre Guedes 				batostr(&entry->bdaddr), entry->bdaddr_type);
154176c8686fSAndre Guedes 
154276c8686fSAndre Guedes 	return 0;
154376c8686fSAndre Guedes }
154476c8686fSAndre Guedes 
15451da177e4SLinus Torvalds /* Register HCI device */
15461da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
15471da177e4SLinus Torvalds {
15481da177e4SLinus Torvalds 	struct list_head *head = &hci_dev_list, *p;
154908add513SMat Martineau 	int i, id, error;
15501da177e4SLinus Torvalds 
1551c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d owner %p", hdev, hdev->name,
1552c13854ceSMarcel Holtmann 						hdev->bus, hdev->owner);
15531da177e4SLinus Torvalds 
15541da177e4SLinus Torvalds 	if (!hdev->open || !hdev->close || !hdev->destruct)
15551da177e4SLinus Torvalds 		return -EINVAL;
15561da177e4SLinus Torvalds 
155708add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
155808add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
155908add513SMat Martineau 	 */
156008add513SMat Martineau 	id = (hdev->dev_type == HCI_BREDR) ? 0 : 1;
156108add513SMat Martineau 
1562f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
15631da177e4SLinus Torvalds 
15641da177e4SLinus Torvalds 	/* Find first available device id */
15651da177e4SLinus Torvalds 	list_for_each(p, &hci_dev_list) {
15661da177e4SLinus Torvalds 		if (list_entry(p, struct hci_dev, list)->id != id)
15671da177e4SLinus Torvalds 			break;
15681da177e4SLinus Torvalds 		head = p; id++;
15691da177e4SLinus Torvalds 	}
15701da177e4SLinus Torvalds 
15711da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
15721da177e4SLinus Torvalds 	hdev->id = id;
1573c6feeb28SAndrei Emeltchenko 	list_add_tail(&hdev->list, head);
15741da177e4SLinus Torvalds 
15751da177e4SLinus Torvalds 	atomic_set(&hdev->refcnt, 1);
157609fd0de5SGustavo F. Padovan 	mutex_init(&hdev->lock);
15771da177e4SLinus Torvalds 
15781da177e4SLinus Torvalds 	hdev->flags = 0;
1579d23264a8SAndre Guedes 	hdev->dev_flags = 0;
15801da177e4SLinus Torvalds 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
15815b7f9909SMarcel Holtmann 	hdev->esco_type = (ESCO_HV1);
15821da177e4SLinus Torvalds 	hdev->link_mode = (HCI_LM_ACCEPT);
158317fa4b9dSJohan Hedberg 	hdev->io_capability = 0x03; /* No Input No Output */
15841da177e4SLinus Torvalds 
158504837f64SMarcel Holtmann 	hdev->idle_timeout = 0;
158604837f64SMarcel Holtmann 	hdev->sniff_max_interval = 800;
158704837f64SMarcel Holtmann 	hdev->sniff_min_interval = 80;
158804837f64SMarcel Holtmann 
1589b78752ccSMarcel Holtmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
1590c347b765SGustavo F. Padovan 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
15913eff45eaSGustavo F. Padovan 	INIT_WORK(&hdev->tx_work, hci_tx_work);
1592b78752ccSMarcel Holtmann 
15931da177e4SLinus Torvalds 
15941da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->rx_q);
15951da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->cmd_q);
15961da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->raw_q);
15971da177e4SLinus Torvalds 
15986bd32326SVille Tervo 	setup_timer(&hdev->cmd_timer, hci_cmd_timer, (unsigned long) hdev);
15996bd32326SVille Tervo 
1600cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
1601ef222013SMarcel Holtmann 		hdev->reassembly[i] = NULL;
1602ef222013SMarcel Holtmann 
16031da177e4SLinus Torvalds 	init_waitqueue_head(&hdev->req_wait_q);
1604a6a67efdSThomas Gleixner 	mutex_init(&hdev->req_lock);
16051da177e4SLinus Torvalds 
160630883512SJohan Hedberg 	discovery_init(hdev);
16071da177e4SLinus Torvalds 
16081da177e4SLinus Torvalds 	hci_conn_hash_init(hdev);
16091da177e4SLinus Torvalds 
16102e58ef3eSJohan Hedberg 	INIT_LIST_HEAD(&hdev->mgmt_pending);
16112e58ef3eSJohan Hedberg 
1612ea4bd8baSDavid Miller 	INIT_LIST_HEAD(&hdev->blacklist);
1613f0358568SJohan Hedberg 
16142aeb9a1aSJohan Hedberg 	INIT_LIST_HEAD(&hdev->uuids);
16152aeb9a1aSJohan Hedberg 
161655ed8ca1SJohan Hedberg 	INIT_LIST_HEAD(&hdev->link_keys);
161755ed8ca1SJohan Hedberg 
16182763eda6SSzymon Janc 	INIT_LIST_HEAD(&hdev->remote_oob_data);
16192763eda6SSzymon Janc 
162076c8686fSAndre Guedes 	INIT_LIST_HEAD(&hdev->adv_entries);
162176c8686fSAndre Guedes 
1622db323f2fSGustavo F. Padovan 	INIT_DELAYED_WORK(&hdev->adv_work, hci_clear_adv_cache);
1623ab81cbf9SJohan Hedberg 	INIT_WORK(&hdev->power_on, hci_power_on);
16243243553fSJohan Hedberg 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
1625ab81cbf9SJohan Hedberg 
162616ab91abSJohan Hedberg 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
162716ab91abSJohan Hedberg 
16281da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
16291da177e4SLinus Torvalds 
16301da177e4SLinus Torvalds 	atomic_set(&hdev->promisc, 0);
16311da177e4SLinus Torvalds 
1632f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
16331da177e4SLinus Torvalds 
163432845eb1SGustavo F. Padovan 	hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND |
163532845eb1SGustavo F. Padovan 							WQ_MEM_RECLAIM, 1);
163633ca954dSDavid Herrmann 	if (!hdev->workqueue) {
163733ca954dSDavid Herrmann 		error = -ENOMEM;
163833ca954dSDavid Herrmann 		goto err;
163933ca954dSDavid Herrmann 	}
1640f48fd9c8SMarcel Holtmann 
164133ca954dSDavid Herrmann 	error = hci_add_sysfs(hdev);
164233ca954dSDavid Herrmann 	if (error < 0)
164333ca954dSDavid Herrmann 		goto err_wqueue;
16441da177e4SLinus Torvalds 
1645611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
1646611b30f7SMarcel Holtmann 				RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, hdev);
1647611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
1648611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
1649611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
1650611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
1651611b30f7SMarcel Holtmann 		}
1652611b30f7SMarcel Holtmann 	}
1653611b30f7SMarcel Holtmann 
1654ab81cbf9SJohan Hedberg 	set_bit(HCI_AUTO_OFF, &hdev->flags);
1655ab81cbf9SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->flags);
16567f971041SGustavo F. Padovan 	schedule_work(&hdev->power_on);
1657ab81cbf9SJohan Hedberg 
16581da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
16591da177e4SLinus Torvalds 
16601da177e4SLinus Torvalds 	return id;
1661f48fd9c8SMarcel Holtmann 
166233ca954dSDavid Herrmann err_wqueue:
166333ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
166433ca954dSDavid Herrmann err:
1665f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
1666f48fd9c8SMarcel Holtmann 	list_del(&hdev->list);
1667f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
1668f48fd9c8SMarcel Holtmann 
166933ca954dSDavid Herrmann 	return error;
16701da177e4SLinus Torvalds }
16711da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
16721da177e4SLinus Torvalds 
16731da177e4SLinus Torvalds /* Unregister HCI device */
167459735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
16751da177e4SLinus Torvalds {
1676ef222013SMarcel Holtmann 	int i;
1677ef222013SMarcel Holtmann 
1678c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
16791da177e4SLinus Torvalds 
1680f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
16811da177e4SLinus Torvalds 	list_del(&hdev->list);
1682f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
16831da177e4SLinus Torvalds 
16841da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
16851da177e4SLinus Torvalds 
1686cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
1687ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
1688ef222013SMarcel Holtmann 
1689ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
169056e5cb86SJohan Hedberg 					!test_bit(HCI_SETUP, &hdev->flags)) {
169109fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
1692744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
169309fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
169456e5cb86SJohan Hedberg 	}
1695ab81cbf9SJohan Hedberg 
16962e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
16972e58ef3eSJohan Hedberg 	 * pending list */
16982e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
16992e58ef3eSJohan Hedberg 
17001da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
17011da177e4SLinus Torvalds 
1702611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
1703611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
1704611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
1705611b30f7SMarcel Holtmann 	}
1706611b30f7SMarcel Holtmann 
1707ce242970SDavid Herrmann 	hci_del_sysfs(hdev);
1708147e2d59SDave Young 
1709db323f2fSGustavo F. Padovan 	cancel_delayed_work_sync(&hdev->adv_work);
1710c6f3c5f7SGustavo F. Padovan 
1711f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
1712f48fd9c8SMarcel Holtmann 
171309fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
1714e2e0cacbSJohan Hedberg 	hci_blacklist_clear(hdev);
17152aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
171655ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
17172763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
171876c8686fSAndre Guedes 	hci_adv_entries_clear(hdev);
171909fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
1720e2e0cacbSJohan Hedberg 
17211da177e4SLinus Torvalds 	__hci_dev_put(hdev);
17221da177e4SLinus Torvalds }
17231da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
17241da177e4SLinus Torvalds 
17251da177e4SLinus Torvalds /* Suspend HCI device */
17261da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
17271da177e4SLinus Torvalds {
17281da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
17291da177e4SLinus Torvalds 	return 0;
17301da177e4SLinus Torvalds }
17311da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
17321da177e4SLinus Torvalds 
17331da177e4SLinus Torvalds /* Resume HCI device */
17341da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
17351da177e4SLinus Torvalds {
17361da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
17371da177e4SLinus Torvalds 	return 0;
17381da177e4SLinus Torvalds }
17391da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
17401da177e4SLinus Torvalds 
174176bca880SMarcel Holtmann /* Receive frame from HCI drivers */
174276bca880SMarcel Holtmann int hci_recv_frame(struct sk_buff *skb)
174376bca880SMarcel Holtmann {
174476bca880SMarcel Holtmann 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
174576bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
174676bca880SMarcel Holtmann 				&& !test_bit(HCI_INIT, &hdev->flags))) {
174776bca880SMarcel Holtmann 		kfree_skb(skb);
174876bca880SMarcel Holtmann 		return -ENXIO;
174976bca880SMarcel Holtmann 	}
175076bca880SMarcel Holtmann 
175176bca880SMarcel Holtmann 	/* Incomming skb */
175276bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
175376bca880SMarcel Holtmann 
175476bca880SMarcel Holtmann 	/* Time stamp */
175576bca880SMarcel Holtmann 	__net_timestamp(skb);
175676bca880SMarcel Holtmann 
175776bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
1758b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
1759c78ae283SMarcel Holtmann 
176076bca880SMarcel Holtmann 	return 0;
176176bca880SMarcel Holtmann }
176276bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
176376bca880SMarcel Holtmann 
176433e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
17651e429f38SGustavo F. Padovan 						  int count, __u8 index)
176633e882a5SSuraj Sumangala {
176733e882a5SSuraj Sumangala 	int len = 0;
176833e882a5SSuraj Sumangala 	int hlen = 0;
176933e882a5SSuraj Sumangala 	int remain = count;
177033e882a5SSuraj Sumangala 	struct sk_buff *skb;
177133e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
177233e882a5SSuraj Sumangala 
177333e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
177433e882a5SSuraj Sumangala 				index >= NUM_REASSEMBLY)
177533e882a5SSuraj Sumangala 		return -EILSEQ;
177633e882a5SSuraj Sumangala 
177733e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
177833e882a5SSuraj Sumangala 
177933e882a5SSuraj Sumangala 	if (!skb) {
178033e882a5SSuraj Sumangala 		switch (type) {
178133e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
178233e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
178333e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
178433e882a5SSuraj Sumangala 			break;
178533e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
178633e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
178733e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
178833e882a5SSuraj Sumangala 			break;
178933e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
179033e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
179133e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
179233e882a5SSuraj Sumangala 			break;
179333e882a5SSuraj Sumangala 		}
179433e882a5SSuraj Sumangala 
17951e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
179633e882a5SSuraj Sumangala 		if (!skb)
179733e882a5SSuraj Sumangala 			return -ENOMEM;
179833e882a5SSuraj Sumangala 
179933e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
180033e882a5SSuraj Sumangala 		scb->expect = hlen;
180133e882a5SSuraj Sumangala 		scb->pkt_type = type;
180233e882a5SSuraj Sumangala 
180333e882a5SSuraj Sumangala 		skb->dev = (void *) hdev;
180433e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
180533e882a5SSuraj Sumangala 	}
180633e882a5SSuraj Sumangala 
180733e882a5SSuraj Sumangala 	while (count) {
180833e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
180933e882a5SSuraj Sumangala 		len = min(scb->expect, (__u16)count);
181033e882a5SSuraj Sumangala 
181133e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
181233e882a5SSuraj Sumangala 
181333e882a5SSuraj Sumangala 		count -= len;
181433e882a5SSuraj Sumangala 		data += len;
181533e882a5SSuraj Sumangala 		scb->expect -= len;
181633e882a5SSuraj Sumangala 		remain = count;
181733e882a5SSuraj Sumangala 
181833e882a5SSuraj Sumangala 		switch (type) {
181933e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
182033e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
182133e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
182233e882a5SSuraj Sumangala 				scb->expect = h->plen;
182333e882a5SSuraj Sumangala 
182433e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
182533e882a5SSuraj Sumangala 					kfree_skb(skb);
182633e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
182733e882a5SSuraj Sumangala 					return -ENOMEM;
182833e882a5SSuraj Sumangala 				}
182933e882a5SSuraj Sumangala 			}
183033e882a5SSuraj Sumangala 			break;
183133e882a5SSuraj Sumangala 
183233e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
183333e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
183433e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
183533e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
183633e882a5SSuraj Sumangala 
183733e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
183833e882a5SSuraj Sumangala 					kfree_skb(skb);
183933e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
184033e882a5SSuraj Sumangala 					return -ENOMEM;
184133e882a5SSuraj Sumangala 				}
184233e882a5SSuraj Sumangala 			}
184333e882a5SSuraj Sumangala 			break;
184433e882a5SSuraj Sumangala 
184533e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
184633e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
184733e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
184833e882a5SSuraj Sumangala 				scb->expect = h->dlen;
184933e882a5SSuraj Sumangala 
185033e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
185133e882a5SSuraj Sumangala 					kfree_skb(skb);
185233e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
185333e882a5SSuraj Sumangala 					return -ENOMEM;
185433e882a5SSuraj Sumangala 				}
185533e882a5SSuraj Sumangala 			}
185633e882a5SSuraj Sumangala 			break;
185733e882a5SSuraj Sumangala 		}
185833e882a5SSuraj Sumangala 
185933e882a5SSuraj Sumangala 		if (scb->expect == 0) {
186033e882a5SSuraj Sumangala 			/* Complete frame */
186133e882a5SSuraj Sumangala 
186233e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
186333e882a5SSuraj Sumangala 			hci_recv_frame(skb);
186433e882a5SSuraj Sumangala 
186533e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
186633e882a5SSuraj Sumangala 			return remain;
186733e882a5SSuraj Sumangala 		}
186833e882a5SSuraj Sumangala 	}
186933e882a5SSuraj Sumangala 
187033e882a5SSuraj Sumangala 	return remain;
187133e882a5SSuraj Sumangala }
187233e882a5SSuraj Sumangala 
1873ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
1874ef222013SMarcel Holtmann {
1875f39a3c06SSuraj Sumangala 	int rem = 0;
1876f39a3c06SSuraj Sumangala 
1877ef222013SMarcel Holtmann 	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
1878ef222013SMarcel Holtmann 		return -EILSEQ;
1879ef222013SMarcel Holtmann 
1880da5f6c37SGustavo F. Padovan 	while (count) {
18811e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count, type - 1);
1882f39a3c06SSuraj Sumangala 		if (rem < 0)
1883f39a3c06SSuraj Sumangala 			return rem;
1884ef222013SMarcel Holtmann 
1885f39a3c06SSuraj Sumangala 		data += (count - rem);
1886f39a3c06SSuraj Sumangala 		count = rem;
1887f81c6224SJoe Perches 	}
1888ef222013SMarcel Holtmann 
1889f39a3c06SSuraj Sumangala 	return rem;
1890ef222013SMarcel Holtmann }
1891ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment);
1892ef222013SMarcel Holtmann 
189399811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
189499811510SSuraj Sumangala 
189599811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
189699811510SSuraj Sumangala {
189799811510SSuraj Sumangala 	int type;
189899811510SSuraj Sumangala 	int rem = 0;
189999811510SSuraj Sumangala 
1900da5f6c37SGustavo F. Padovan 	while (count) {
190199811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
190299811510SSuraj Sumangala 
190399811510SSuraj Sumangala 		if (!skb) {
190499811510SSuraj Sumangala 			struct { char type; } *pkt;
190599811510SSuraj Sumangala 
190699811510SSuraj Sumangala 			/* Start of the frame */
190799811510SSuraj Sumangala 			pkt = data;
190899811510SSuraj Sumangala 			type = pkt->type;
190999811510SSuraj Sumangala 
191099811510SSuraj Sumangala 			data++;
191199811510SSuraj Sumangala 			count--;
191299811510SSuraj Sumangala 		} else
191399811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
191499811510SSuraj Sumangala 
19151e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
19161e429f38SGustavo F. Padovan 							STREAM_REASSEMBLY);
191799811510SSuraj Sumangala 		if (rem < 0)
191899811510SSuraj Sumangala 			return rem;
191999811510SSuraj Sumangala 
192099811510SSuraj Sumangala 		data += (count - rem);
192199811510SSuraj Sumangala 		count = rem;
1922f81c6224SJoe Perches 	}
192399811510SSuraj Sumangala 
192499811510SSuraj Sumangala 	return rem;
192599811510SSuraj Sumangala }
192699811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
192799811510SSuraj Sumangala 
19281da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
19291da177e4SLinus Torvalds 
19301da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
19311da177e4SLinus Torvalds {
19321da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
19331da177e4SLinus Torvalds 
1934f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
19351da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
1936f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
19371da177e4SLinus Torvalds 
19381da177e4SLinus Torvalds 	return 0;
19391da177e4SLinus Torvalds }
19401da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
19411da177e4SLinus Torvalds 
19421da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
19431da177e4SLinus Torvalds {
19441da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
19451da177e4SLinus Torvalds 
1946f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
19471da177e4SLinus Torvalds 	list_del(&cb->list);
1948f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
19491da177e4SLinus Torvalds 
19501da177e4SLinus Torvalds 	return 0;
19511da177e4SLinus Torvalds }
19521da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
19531da177e4SLinus Torvalds 
19541da177e4SLinus Torvalds static int hci_send_frame(struct sk_buff *skb)
19551da177e4SLinus Torvalds {
19561da177e4SLinus Torvalds 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
19571da177e4SLinus Torvalds 
19581da177e4SLinus Torvalds 	if (!hdev) {
19591da177e4SLinus Torvalds 		kfree_skb(skb);
19601da177e4SLinus Torvalds 		return -ENODEV;
19611da177e4SLinus Torvalds 	}
19621da177e4SLinus Torvalds 
19630d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
19641da177e4SLinus Torvalds 
19651da177e4SLinus Torvalds 	if (atomic_read(&hdev->promisc)) {
19661da177e4SLinus Torvalds 		/* Time stamp */
1967a61bbcf2SPatrick McHardy 		__net_timestamp(skb);
19681da177e4SLinus Torvalds 
1969eec8d2bcSJohan Hedberg 		hci_send_to_sock(hdev, skb, NULL);
19701da177e4SLinus Torvalds 	}
19711da177e4SLinus Torvalds 
19721da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
19731da177e4SLinus Torvalds 	skb_orphan(skb);
19741da177e4SLinus Torvalds 
19751da177e4SLinus Torvalds 	return hdev->send(skb);
19761da177e4SLinus Torvalds }
19771da177e4SLinus Torvalds 
19781da177e4SLinus Torvalds /* Send HCI command */
1979a9de9248SMarcel Holtmann int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)
19801da177e4SLinus Torvalds {
19811da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
19821da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
19831da177e4SLinus Torvalds 	struct sk_buff *skb;
19841da177e4SLinus Torvalds 
1985a9de9248SMarcel Holtmann 	BT_DBG("%s opcode 0x%x plen %d", hdev->name, opcode, plen);
19861da177e4SLinus Torvalds 
19871da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
19881da177e4SLinus Torvalds 	if (!skb) {
1989ef222013SMarcel Holtmann 		BT_ERR("%s no memory for command", hdev->name);
19901da177e4SLinus Torvalds 		return -ENOMEM;
19911da177e4SLinus Torvalds 	}
19921da177e4SLinus Torvalds 
19931da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
1994a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
19951da177e4SLinus Torvalds 	hdr->plen   = plen;
19961da177e4SLinus Torvalds 
19971da177e4SLinus Torvalds 	if (plen)
19981da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
19991da177e4SLinus Torvalds 
20001da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
20011da177e4SLinus Torvalds 
20020d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
20031da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
2004c78ae283SMarcel Holtmann 
2005a5040efaSJohan Hedberg 	if (test_bit(HCI_INIT, &hdev->flags))
2006a5040efaSJohan Hedberg 		hdev->init_last_cmd = opcode;
2007a5040efaSJohan Hedberg 
20081da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
2009c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
20101da177e4SLinus Torvalds 
20111da177e4SLinus Torvalds 	return 0;
20121da177e4SLinus Torvalds }
20131da177e4SLinus Torvalds 
20141da177e4SLinus Torvalds /* Get data from the previously sent command */
2015a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
20161da177e4SLinus Torvalds {
20171da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
20181da177e4SLinus Torvalds 
20191da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
20201da177e4SLinus Torvalds 		return NULL;
20211da177e4SLinus Torvalds 
20221da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
20231da177e4SLinus Torvalds 
2024a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
20251da177e4SLinus Torvalds 		return NULL;
20261da177e4SLinus Torvalds 
2027a9de9248SMarcel Holtmann 	BT_DBG("%s opcode 0x%x", hdev->name, opcode);
20281da177e4SLinus Torvalds 
20291da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
20301da177e4SLinus Torvalds }
20311da177e4SLinus Torvalds 
20321da177e4SLinus Torvalds /* Send ACL data */
20331da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
20341da177e4SLinus Torvalds {
20351da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
20361da177e4SLinus Torvalds 	int len = skb->len;
20371da177e4SLinus Torvalds 
2038badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
2039badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
20409c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
2041aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
2042aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
20431da177e4SLinus Torvalds }
20441da177e4SLinus Torvalds 
204573d80debSLuiz Augusto von Dentz static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue,
204673d80debSLuiz Augusto von Dentz 				struct sk_buff *skb, __u16 flags)
20471da177e4SLinus Torvalds {
20481da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
20491da177e4SLinus Torvalds 	struct sk_buff *list;
20501da177e4SLinus Torvalds 
205170f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
205270f23020SAndrei Emeltchenko 	if (!list) {
20531da177e4SLinus Torvalds 		/* Non fragmented */
20541da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
20551da177e4SLinus Torvalds 
205673d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
20571da177e4SLinus Torvalds 	} else {
20581da177e4SLinus Torvalds 		/* Fragmented */
20591da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
20601da177e4SLinus Torvalds 
20611da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
20621da177e4SLinus Torvalds 
20631da177e4SLinus Torvalds 		/* Queue all fragments atomically */
2064af3e6359SGustavo F. Padovan 		spin_lock(&queue->lock);
20651da177e4SLinus Torvalds 
206673d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
2067e702112fSAndrei Emeltchenko 
2068e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
2069e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
20701da177e4SLinus Torvalds 		do {
20711da177e4SLinus Torvalds 			skb = list; list = list->next;
20721da177e4SLinus Torvalds 
20731da177e4SLinus Torvalds 			skb->dev = (void *) hdev;
20740d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2075e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
20761da177e4SLinus Torvalds 
20771da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
20781da177e4SLinus Torvalds 
207973d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
20801da177e4SLinus Torvalds 		} while (list);
20811da177e4SLinus Torvalds 
2082af3e6359SGustavo F. Padovan 		spin_unlock(&queue->lock);
20831da177e4SLinus Torvalds 	}
208473d80debSLuiz Augusto von Dentz }
208573d80debSLuiz Augusto von Dentz 
208673d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
208773d80debSLuiz Augusto von Dentz {
208873d80debSLuiz Augusto von Dentz 	struct hci_conn *conn = chan->conn;
208973d80debSLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
209073d80debSLuiz Augusto von Dentz 
209173d80debSLuiz Augusto von Dentz 	BT_DBG("%s chan %p flags 0x%x", hdev->name, chan, flags);
209273d80debSLuiz Augusto von Dentz 
209373d80debSLuiz Augusto von Dentz 	skb->dev = (void *) hdev;
209473d80debSLuiz Augusto von Dentz 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
209573d80debSLuiz Augusto von Dentz 	hci_add_acl_hdr(skb, conn->handle, flags);
209673d80debSLuiz Augusto von Dentz 
209773d80debSLuiz Augusto von Dentz 	hci_queue_acl(conn, &chan->data_q, skb, flags);
20981da177e4SLinus Torvalds 
20993eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
21001da177e4SLinus Torvalds }
21011da177e4SLinus Torvalds EXPORT_SYMBOL(hci_send_acl);
21021da177e4SLinus Torvalds 
21031da177e4SLinus Torvalds /* Send SCO data */
21040d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
21051da177e4SLinus Torvalds {
21061da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
21071da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
21081da177e4SLinus Torvalds 
21091da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
21101da177e4SLinus Torvalds 
2111aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
21121da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
21131da177e4SLinus Torvalds 
2114badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
2115badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
21169c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
21171da177e4SLinus Torvalds 
21181da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
21190d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
2120c78ae283SMarcel Holtmann 
21211da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
21223eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
21231da177e4SLinus Torvalds }
21241da177e4SLinus Torvalds EXPORT_SYMBOL(hci_send_sco);
21251da177e4SLinus Torvalds 
21261da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
21271da177e4SLinus Torvalds 
21281da177e4SLinus Torvalds /* HCI Connection scheduler */
21291da177e4SLinus Torvalds static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote)
21301da177e4SLinus Torvalds {
21311da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
21328035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
21331da177e4SLinus Torvalds 	int num = 0, min = ~0;
21341da177e4SLinus Torvalds 
21351da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
21361da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
2137bf4c6325SGustavo F. Padovan 
2138bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2139bf4c6325SGustavo F. Padovan 
2140bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2141769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
21421da177e4SLinus Torvalds 			continue;
2143769be974SMarcel Holtmann 
2144769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
2145769be974SMarcel Holtmann 			continue;
2146769be974SMarcel Holtmann 
21471da177e4SLinus Torvalds 		num++;
21481da177e4SLinus Torvalds 
21491da177e4SLinus Torvalds 		if (c->sent < min) {
21501da177e4SLinus Torvalds 			min  = c->sent;
21511da177e4SLinus Torvalds 			conn = c;
21521da177e4SLinus Torvalds 		}
215352087a79SLuiz Augusto von Dentz 
215452087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
215552087a79SLuiz Augusto von Dentz 			break;
21561da177e4SLinus Torvalds 	}
21571da177e4SLinus Torvalds 
2158bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2159bf4c6325SGustavo F. Padovan 
21601da177e4SLinus Torvalds 	if (conn) {
21616ed58ec5SVille Tervo 		int cnt, q;
21626ed58ec5SVille Tervo 
21636ed58ec5SVille Tervo 		switch (conn->type) {
21646ed58ec5SVille Tervo 		case ACL_LINK:
21656ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
21666ed58ec5SVille Tervo 			break;
21676ed58ec5SVille Tervo 		case SCO_LINK:
21686ed58ec5SVille Tervo 		case ESCO_LINK:
21696ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
21706ed58ec5SVille Tervo 			break;
21716ed58ec5SVille Tervo 		case LE_LINK:
21726ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
21736ed58ec5SVille Tervo 			break;
21746ed58ec5SVille Tervo 		default:
21756ed58ec5SVille Tervo 			cnt = 0;
21766ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
21776ed58ec5SVille Tervo 		}
21786ed58ec5SVille Tervo 
21796ed58ec5SVille Tervo 		q = cnt / num;
21801da177e4SLinus Torvalds 		*quote = q ? q : 1;
21811da177e4SLinus Torvalds 	} else
21821da177e4SLinus Torvalds 		*quote = 0;
21831da177e4SLinus Torvalds 
21841da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
21851da177e4SLinus Torvalds 	return conn;
21861da177e4SLinus Torvalds }
21871da177e4SLinus Torvalds 
2188bae1f5d9SVille Tervo static inline void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
21891da177e4SLinus Torvalds {
21901da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
21911da177e4SLinus Torvalds 	struct hci_conn *c;
21921da177e4SLinus Torvalds 
2193bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
21941da177e4SLinus Torvalds 
2195bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2196bf4c6325SGustavo F. Padovan 
21971da177e4SLinus Torvalds 	/* Kill stalled connections */
2198bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2199bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
2200bae1f5d9SVille Tervo 			BT_ERR("%s killing stalled connection %s",
22011da177e4SLinus Torvalds 				hdev->name, batostr(&c->dst));
22021da177e4SLinus Torvalds 			hci_acl_disconn(c, 0x13);
22031da177e4SLinus Torvalds 		}
22041da177e4SLinus Torvalds 	}
2205bf4c6325SGustavo F. Padovan 
2206bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
22071da177e4SLinus Torvalds }
22081da177e4SLinus Torvalds 
220973d80debSLuiz Augusto von Dentz static inline struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
221073d80debSLuiz Augusto von Dentz 						int *quote)
221173d80debSLuiz Augusto von Dentz {
221273d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
221373d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
221473d80debSLuiz Augusto von Dentz 	int num = 0, min = ~0, cur_prio = 0;
221573d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
221673d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
221773d80debSLuiz Augusto von Dentz 
221873d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
221973d80debSLuiz Augusto von Dentz 
2220bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2221bf4c6325SGustavo F. Padovan 
2222bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
222373d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
222473d80debSLuiz Augusto von Dentz 
222573d80debSLuiz Augusto von Dentz 		if (conn->type != type)
222673d80debSLuiz Augusto von Dentz 			continue;
222773d80debSLuiz Augusto von Dentz 
222873d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
222973d80debSLuiz Augusto von Dentz 			continue;
223073d80debSLuiz Augusto von Dentz 
223173d80debSLuiz Augusto von Dentz 		conn_num++;
223273d80debSLuiz Augusto von Dentz 
22338192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
223473d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
223573d80debSLuiz Augusto von Dentz 
223673d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
223773d80debSLuiz Augusto von Dentz 				continue;
223873d80debSLuiz Augusto von Dentz 
223973d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
224073d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
224173d80debSLuiz Augusto von Dentz 				continue;
224273d80debSLuiz Augusto von Dentz 
224373d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
224473d80debSLuiz Augusto von Dentz 				num = 0;
224573d80debSLuiz Augusto von Dentz 				min = ~0;
224673d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
224773d80debSLuiz Augusto von Dentz 			}
224873d80debSLuiz Augusto von Dentz 
224973d80debSLuiz Augusto von Dentz 			num++;
225073d80debSLuiz Augusto von Dentz 
225173d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
225273d80debSLuiz Augusto von Dentz 				min  = conn->sent;
225373d80debSLuiz Augusto von Dentz 				chan = tmp;
225473d80debSLuiz Augusto von Dentz 			}
225573d80debSLuiz Augusto von Dentz 		}
225673d80debSLuiz Augusto von Dentz 
225773d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
225873d80debSLuiz Augusto von Dentz 			break;
225973d80debSLuiz Augusto von Dentz 	}
226073d80debSLuiz Augusto von Dentz 
2261bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2262bf4c6325SGustavo F. Padovan 
226373d80debSLuiz Augusto von Dentz 	if (!chan)
226473d80debSLuiz Augusto von Dentz 		return NULL;
226573d80debSLuiz Augusto von Dentz 
226673d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
226773d80debSLuiz Augusto von Dentz 	case ACL_LINK:
226873d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
226973d80debSLuiz Augusto von Dentz 		break;
227073d80debSLuiz Augusto von Dentz 	case SCO_LINK:
227173d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
227273d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
227373d80debSLuiz Augusto von Dentz 		break;
227473d80debSLuiz Augusto von Dentz 	case LE_LINK:
227573d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
227673d80debSLuiz Augusto von Dentz 		break;
227773d80debSLuiz Augusto von Dentz 	default:
227873d80debSLuiz Augusto von Dentz 		cnt = 0;
227973d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
228073d80debSLuiz Augusto von Dentz 	}
228173d80debSLuiz Augusto von Dentz 
228273d80debSLuiz Augusto von Dentz 	q = cnt / num;
228373d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
228473d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
228573d80debSLuiz Augusto von Dentz 	return chan;
228673d80debSLuiz Augusto von Dentz }
228773d80debSLuiz Augusto von Dentz 
228802b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
228902b20f0bSLuiz Augusto von Dentz {
229002b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
229102b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
229202b20f0bSLuiz Augusto von Dentz 	int num = 0;
229302b20f0bSLuiz Augusto von Dentz 
229402b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
229502b20f0bSLuiz Augusto von Dentz 
2296bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2297bf4c6325SGustavo F. Padovan 
2298bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
229902b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
230002b20f0bSLuiz Augusto von Dentz 
230102b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
230202b20f0bSLuiz Augusto von Dentz 			continue;
230302b20f0bSLuiz Augusto von Dentz 
230402b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
230502b20f0bSLuiz Augusto von Dentz 			continue;
230602b20f0bSLuiz Augusto von Dentz 
230702b20f0bSLuiz Augusto von Dentz 		num++;
230802b20f0bSLuiz Augusto von Dentz 
23098192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
231002b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
231102b20f0bSLuiz Augusto von Dentz 
231202b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
231302b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
231402b20f0bSLuiz Augusto von Dentz 				continue;
231502b20f0bSLuiz Augusto von Dentz 			}
231602b20f0bSLuiz Augusto von Dentz 
231702b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
231802b20f0bSLuiz Augusto von Dentz 				continue;
231902b20f0bSLuiz Augusto von Dentz 
232002b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
232102b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
232202b20f0bSLuiz Augusto von Dentz 				continue;
232302b20f0bSLuiz Augusto von Dentz 
232402b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
232502b20f0bSLuiz Augusto von Dentz 
232602b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
232702b20f0bSLuiz Augusto von Dentz 								skb->priority);
232802b20f0bSLuiz Augusto von Dentz 		}
232902b20f0bSLuiz Augusto von Dentz 
233002b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
233102b20f0bSLuiz Augusto von Dentz 			break;
233202b20f0bSLuiz Augusto von Dentz 	}
2333bf4c6325SGustavo F. Padovan 
2334bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2335bf4c6325SGustavo F. Padovan 
233602b20f0bSLuiz Augusto von Dentz }
233702b20f0bSLuiz Augusto von Dentz 
23381da177e4SLinus Torvalds static inline void hci_sched_acl(struct hci_dev *hdev)
23391da177e4SLinus Torvalds {
234073d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
23411da177e4SLinus Torvalds 	struct sk_buff *skb;
23421da177e4SLinus Torvalds 	int quote;
234373d80debSLuiz Augusto von Dentz 	unsigned int cnt;
23441da177e4SLinus Torvalds 
23451da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
23461da177e4SLinus Torvalds 
234752087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ACL_LINK))
234852087a79SLuiz Augusto von Dentz 		return;
234952087a79SLuiz Augusto von Dentz 
23501da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
23511da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
23521da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
235382453021SS.Çağlar Onur 		if (!hdev->acl_cnt && time_after(jiffies, hdev->acl_last_tx + HZ * 45))
2354bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
23551da177e4SLinus Torvalds 	}
23561da177e4SLinus Torvalds 
235773d80debSLuiz Augusto von Dentz 	cnt = hdev->acl_cnt;
235804837f64SMarcel Holtmann 
235973d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
236073d80debSLuiz Augusto von Dentz 			(chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
2361ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
2362ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
236373d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
236473d80debSLuiz Augusto von Dentz 					skb->len, skb->priority);
236573d80debSLuiz Augusto von Dentz 
2366ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
2367ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
2368ec1cce24SLuiz Augusto von Dentz 				break;
2369ec1cce24SLuiz Augusto von Dentz 
2370ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
2371ec1cce24SLuiz Augusto von Dentz 
237273d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
237373d80debSLuiz Augusto von Dentz 						bt_cb(skb)->force_active);
237404837f64SMarcel Holtmann 
23751da177e4SLinus Torvalds 			hci_send_frame(skb);
23761da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
23771da177e4SLinus Torvalds 
23781da177e4SLinus Torvalds 			hdev->acl_cnt--;
237973d80debSLuiz Augusto von Dentz 			chan->sent++;
238073d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
23811da177e4SLinus Torvalds 		}
23821da177e4SLinus Torvalds 	}
238302b20f0bSLuiz Augusto von Dentz 
238402b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
238502b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
23861da177e4SLinus Torvalds }
23871da177e4SLinus Torvalds 
23881da177e4SLinus Torvalds /* Schedule SCO */
23891da177e4SLinus Torvalds static inline void hci_sched_sco(struct hci_dev *hdev)
23901da177e4SLinus Torvalds {
23911da177e4SLinus Torvalds 	struct hci_conn *conn;
23921da177e4SLinus Torvalds 	struct sk_buff *skb;
23931da177e4SLinus Torvalds 	int quote;
23941da177e4SLinus Torvalds 
23951da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
23961da177e4SLinus Torvalds 
239752087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
239852087a79SLuiz Augusto von Dentz 		return;
239952087a79SLuiz Augusto von Dentz 
24001da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
24011da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
24021da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
24031da177e4SLinus Torvalds 			hci_send_frame(skb);
24041da177e4SLinus Torvalds 
24051da177e4SLinus Torvalds 			conn->sent++;
24061da177e4SLinus Torvalds 			if (conn->sent == ~0)
24071da177e4SLinus Torvalds 				conn->sent = 0;
24081da177e4SLinus Torvalds 		}
24091da177e4SLinus Torvalds 	}
24101da177e4SLinus Torvalds }
24111da177e4SLinus Torvalds 
2412b6a0dc82SMarcel Holtmann static inline void hci_sched_esco(struct hci_dev *hdev)
2413b6a0dc82SMarcel Holtmann {
2414b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
2415b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
2416b6a0dc82SMarcel Holtmann 	int quote;
2417b6a0dc82SMarcel Holtmann 
2418b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
2419b6a0dc82SMarcel Holtmann 
242052087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
242152087a79SLuiz Augusto von Dentz 		return;
242252087a79SLuiz Augusto von Dentz 
2423b6a0dc82SMarcel Holtmann 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, &quote))) {
2424b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
2425b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
2426b6a0dc82SMarcel Holtmann 			hci_send_frame(skb);
2427b6a0dc82SMarcel Holtmann 
2428b6a0dc82SMarcel Holtmann 			conn->sent++;
2429b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
2430b6a0dc82SMarcel Holtmann 				conn->sent = 0;
2431b6a0dc82SMarcel Holtmann 		}
2432b6a0dc82SMarcel Holtmann 	}
2433b6a0dc82SMarcel Holtmann }
2434b6a0dc82SMarcel Holtmann 
24356ed58ec5SVille Tervo static inline void hci_sched_le(struct hci_dev *hdev)
24366ed58ec5SVille Tervo {
243773d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
24386ed58ec5SVille Tervo 	struct sk_buff *skb;
243902b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
24406ed58ec5SVille Tervo 
24416ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
24426ed58ec5SVille Tervo 
244352087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
244452087a79SLuiz Augusto von Dentz 		return;
244552087a79SLuiz Augusto von Dentz 
24466ed58ec5SVille Tervo 	if (!test_bit(HCI_RAW, &hdev->flags)) {
24476ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
24486ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
2449bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
24506ed58ec5SVille Tervo 				time_after(jiffies, hdev->le_last_tx + HZ * 45))
2451bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
24526ed58ec5SVille Tervo 	}
24536ed58ec5SVille Tervo 
24546ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
245502b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
245673d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
2457ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
2458ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
245973d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
246073d80debSLuiz Augusto von Dentz 					skb->len, skb->priority);
24616ed58ec5SVille Tervo 
2462ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
2463ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
2464ec1cce24SLuiz Augusto von Dentz 				break;
2465ec1cce24SLuiz Augusto von Dentz 
2466ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
2467ec1cce24SLuiz Augusto von Dentz 
24686ed58ec5SVille Tervo 			hci_send_frame(skb);
24696ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
24706ed58ec5SVille Tervo 
24716ed58ec5SVille Tervo 			cnt--;
247273d80debSLuiz Augusto von Dentz 			chan->sent++;
247373d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
24746ed58ec5SVille Tervo 		}
24756ed58ec5SVille Tervo 	}
247673d80debSLuiz Augusto von Dentz 
24776ed58ec5SVille Tervo 	if (hdev->le_pkts)
24786ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
24796ed58ec5SVille Tervo 	else
24806ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
248102b20f0bSLuiz Augusto von Dentz 
248202b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
248302b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
24846ed58ec5SVille Tervo }
24856ed58ec5SVille Tervo 
24863eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
24871da177e4SLinus Torvalds {
24883eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
24891da177e4SLinus Torvalds 	struct sk_buff *skb;
24901da177e4SLinus Torvalds 
24916ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
24926ed58ec5SVille Tervo 		hdev->sco_cnt, hdev->le_cnt);
24931da177e4SLinus Torvalds 
24941da177e4SLinus Torvalds 	/* Schedule queues and send stuff to HCI driver */
24951da177e4SLinus Torvalds 
24961da177e4SLinus Torvalds 	hci_sched_acl(hdev);
24971da177e4SLinus Torvalds 
24981da177e4SLinus Torvalds 	hci_sched_sco(hdev);
24991da177e4SLinus Torvalds 
2500b6a0dc82SMarcel Holtmann 	hci_sched_esco(hdev);
2501b6a0dc82SMarcel Holtmann 
25026ed58ec5SVille Tervo 	hci_sched_le(hdev);
25036ed58ec5SVille Tervo 
25041da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
25051da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
25061da177e4SLinus Torvalds 		hci_send_frame(skb);
25071da177e4SLinus Torvalds }
25081da177e4SLinus Torvalds 
250925985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
25101da177e4SLinus Torvalds 
25111da177e4SLinus Torvalds /* ACL data packet */
25121da177e4SLinus Torvalds static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
25131da177e4SLinus Torvalds {
25141da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
25151da177e4SLinus Torvalds 	struct hci_conn *conn;
25161da177e4SLinus Torvalds 	__u16 handle, flags;
25171da177e4SLinus Torvalds 
25181da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
25191da177e4SLinus Torvalds 
25201da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
25211da177e4SLinus Torvalds 	flags  = hci_flags(handle);
25221da177e4SLinus Torvalds 	handle = hci_handle(handle);
25231da177e4SLinus Torvalds 
25241da177e4SLinus Torvalds 	BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags);
25251da177e4SLinus Torvalds 
25261da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
25271da177e4SLinus Torvalds 
25281da177e4SLinus Torvalds 	hci_dev_lock(hdev);
25291da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
25301da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
25311da177e4SLinus Torvalds 
25321da177e4SLinus Torvalds 	if (conn) {
253365983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
253404837f64SMarcel Holtmann 
25351da177e4SLinus Torvalds 		/* Send to upper protocol */
2536686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
25371da177e4SLinus Torvalds 		return;
25381da177e4SLinus Torvalds 	} else {
25391da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
25401da177e4SLinus Torvalds 			hdev->name, handle);
25411da177e4SLinus Torvalds 	}
25421da177e4SLinus Torvalds 
25431da177e4SLinus Torvalds 	kfree_skb(skb);
25441da177e4SLinus Torvalds }
25451da177e4SLinus Torvalds 
25461da177e4SLinus Torvalds /* SCO data packet */
25471da177e4SLinus Torvalds static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
25481da177e4SLinus Torvalds {
25491da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
25501da177e4SLinus Torvalds 	struct hci_conn *conn;
25511da177e4SLinus Torvalds 	__u16 handle;
25521da177e4SLinus Torvalds 
25531da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
25541da177e4SLinus Torvalds 
25551da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
25561da177e4SLinus Torvalds 
25571da177e4SLinus Torvalds 	BT_DBG("%s len %d handle 0x%x", hdev->name, skb->len, handle);
25581da177e4SLinus Torvalds 
25591da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
25601da177e4SLinus Torvalds 
25611da177e4SLinus Torvalds 	hci_dev_lock(hdev);
25621da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
25631da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
25641da177e4SLinus Torvalds 
25651da177e4SLinus Torvalds 	if (conn) {
25661da177e4SLinus Torvalds 		/* Send to upper protocol */
2567686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
25681da177e4SLinus Torvalds 		return;
25691da177e4SLinus Torvalds 	} else {
25701da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
25711da177e4SLinus Torvalds 			hdev->name, handle);
25721da177e4SLinus Torvalds 	}
25731da177e4SLinus Torvalds 
25741da177e4SLinus Torvalds 	kfree_skb(skb);
25751da177e4SLinus Torvalds }
25761da177e4SLinus Torvalds 
2577b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
25781da177e4SLinus Torvalds {
2579b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
25801da177e4SLinus Torvalds 	struct sk_buff *skb;
25811da177e4SLinus Torvalds 
25821da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
25831da177e4SLinus Torvalds 
25841da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
25851da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
25861da177e4SLinus Torvalds 			/* Send copy to the sockets */
2587eec8d2bcSJohan Hedberg 			hci_send_to_sock(hdev, skb, NULL);
25881da177e4SLinus Torvalds 		}
25891da177e4SLinus Torvalds 
25901da177e4SLinus Torvalds 		if (test_bit(HCI_RAW, &hdev->flags)) {
25911da177e4SLinus Torvalds 			kfree_skb(skb);
25921da177e4SLinus Torvalds 			continue;
25931da177e4SLinus Torvalds 		}
25941da177e4SLinus Torvalds 
25951da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
25961da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
25970d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
25981da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
25991da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
26001da177e4SLinus Torvalds 				kfree_skb(skb);
26011da177e4SLinus Torvalds 				continue;
26023ff50b79SStephen Hemminger 			}
26031da177e4SLinus Torvalds 		}
26041da177e4SLinus Torvalds 
26051da177e4SLinus Torvalds 		/* Process frame */
26060d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
26071da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
2608b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
26091da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
26101da177e4SLinus Torvalds 			break;
26111da177e4SLinus Torvalds 
26121da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
26131da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
26141da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
26151da177e4SLinus Torvalds 			break;
26161da177e4SLinus Torvalds 
26171da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
26181da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
26191da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
26201da177e4SLinus Torvalds 			break;
26211da177e4SLinus Torvalds 
26221da177e4SLinus Torvalds 		default:
26231da177e4SLinus Torvalds 			kfree_skb(skb);
26241da177e4SLinus Torvalds 			break;
26251da177e4SLinus Torvalds 		}
26261da177e4SLinus Torvalds 	}
26271da177e4SLinus Torvalds }
26281da177e4SLinus Torvalds 
2629c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
26301da177e4SLinus Torvalds {
2631c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
26321da177e4SLinus Torvalds 	struct sk_buff *skb;
26331da177e4SLinus Torvalds 
26341da177e4SLinus Torvalds 	BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
26351da177e4SLinus Torvalds 
26361da177e4SLinus Torvalds 	/* Send queued commands */
26375a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
26385a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
26395a08ecceSAndrei Emeltchenko 		if (!skb)
26405a08ecceSAndrei Emeltchenko 			return;
26415a08ecceSAndrei Emeltchenko 
26421da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
26431da177e4SLinus Torvalds 
264470f23020SAndrei Emeltchenko 		hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC);
264570f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
26461da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
26471da177e4SLinus Torvalds 			hci_send_frame(skb);
26487bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
26497bdb8a5cSSzymon Janc 				del_timer(&hdev->cmd_timer);
26507bdb8a5cSSzymon Janc 			else
26516bd32326SVille Tervo 				mod_timer(&hdev->cmd_timer,
26526bd32326SVille Tervo 				  jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT));
26531da177e4SLinus Torvalds 		} else {
26541da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
2655c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
26561da177e4SLinus Torvalds 		}
26571da177e4SLinus Torvalds 	}
26581da177e4SLinus Torvalds }
26592519a1fcSAndre Guedes 
26602519a1fcSAndre Guedes int hci_do_inquiry(struct hci_dev *hdev, u8 length)
26612519a1fcSAndre Guedes {
26622519a1fcSAndre Guedes 	/* General inquiry access code (GIAC) */
26632519a1fcSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
26642519a1fcSAndre Guedes 	struct hci_cp_inquiry cp;
26652519a1fcSAndre Guedes 
26662519a1fcSAndre Guedes 	BT_DBG("%s", hdev->name);
26672519a1fcSAndre Guedes 
26682519a1fcSAndre Guedes 	if (test_bit(HCI_INQUIRY, &hdev->flags))
26692519a1fcSAndre Guedes 		return -EINPROGRESS;
26702519a1fcSAndre Guedes 
26714663262cSJohan Hedberg 	inquiry_cache_flush(hdev);
26724663262cSJohan Hedberg 
26732519a1fcSAndre Guedes 	memset(&cp, 0, sizeof(cp));
26742519a1fcSAndre Guedes 	memcpy(&cp.lap, lap, sizeof(cp.lap));
26752519a1fcSAndre Guedes 	cp.length  = length;
26762519a1fcSAndre Guedes 
26772519a1fcSAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
26782519a1fcSAndre Guedes }
2679023d5049SAndre Guedes 
2680023d5049SAndre Guedes int hci_cancel_inquiry(struct hci_dev *hdev)
2681023d5049SAndre Guedes {
2682023d5049SAndre Guedes 	BT_DBG("%s", hdev->name);
2683023d5049SAndre Guedes 
2684023d5049SAndre Guedes 	if (!test_bit(HCI_INQUIRY, &hdev->flags))
2685023d5049SAndre Guedes 		return -EPERM;
2686023d5049SAndre Guedes 
2687023d5049SAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL);
2688023d5049SAndre Guedes }
26897784d78fSAndrei Emeltchenko 
26907784d78fSAndrei Emeltchenko module_param(enable_hs, bool, 0644);
26917784d78fSAndrei Emeltchenko MODULE_PARM_DESC(enable_hs, "Enable High Speed");
2692