xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 388fc8fa)
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>
43611b30f7SMarcel Holtmann #include <linux/rfkill.h>
446bd32326SVille Tervo #include <linux/timer.h>
453a0259bbSVinicius Costa Gomes #include <linux/crypto.h>
461da177e4SLinus Torvalds #include <net/sock.h>
471da177e4SLinus Torvalds 
481da177e4SLinus Torvalds #include <asm/system.h>
4970f23020SAndrei Emeltchenko #include <linux/uaccess.h>
501da177e4SLinus Torvalds #include <asm/unaligned.h>
511da177e4SLinus Torvalds 
521da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
531da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
541da177e4SLinus Torvalds 
55ab81cbf9SJohan Hedberg #define AUTO_OFF_TIMEOUT 2000
56ab81cbf9SJohan Hedberg 
57b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work);
58c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work);
593eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work);
601da177e4SLinus Torvalds 
611da177e4SLinus Torvalds /* HCI device list */
621da177e4SLinus Torvalds LIST_HEAD(hci_dev_list);
631da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock);
641da177e4SLinus Torvalds 
651da177e4SLinus Torvalds /* HCI callback list */
661da177e4SLinus Torvalds LIST_HEAD(hci_cb_list);
671da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock);
681da177e4SLinus Torvalds 
691da177e4SLinus Torvalds /* ---- HCI notifications ---- */
701da177e4SLinus Torvalds 
716516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event)
721da177e4SLinus Torvalds {
73040030efSMarcel Holtmann 	hci_sock_dev_event(hdev, event);
741da177e4SLinus Torvalds }
751da177e4SLinus Torvalds 
761da177e4SLinus Torvalds /* ---- HCI requests ---- */
771da177e4SLinus Torvalds 
7823bb5763SJohan Hedberg void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result)
791da177e4SLinus Torvalds {
8023bb5763SJohan Hedberg 	BT_DBG("%s command 0x%04x result 0x%2.2x", hdev->name, cmd, result);
8123bb5763SJohan Hedberg 
82a5040efaSJohan Hedberg 	/* If this is the init phase check if the completed command matches
83a5040efaSJohan Hedberg 	 * the last init command, and if not just return.
84a5040efaSJohan Hedberg 	 */
85a5040efaSJohan Hedberg 	if (test_bit(HCI_INIT, &hdev->flags) && hdev->init_last_cmd != cmd)
8623bb5763SJohan Hedberg 		return;
871da177e4SLinus Torvalds 
881da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
891da177e4SLinus Torvalds 		hdev->req_result = result;
901da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_DONE;
911da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
921da177e4SLinus Torvalds 	}
931da177e4SLinus Torvalds }
941da177e4SLinus Torvalds 
951da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err)
961da177e4SLinus Torvalds {
971da177e4SLinus Torvalds 	BT_DBG("%s err 0x%2.2x", hdev->name, err);
981da177e4SLinus Torvalds 
991da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
1001da177e4SLinus Torvalds 		hdev->req_result = err;
1011da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_CANCELED;
1021da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
1031da177e4SLinus Torvalds 	}
1041da177e4SLinus Torvalds }
1051da177e4SLinus Torvalds 
1061da177e4SLinus Torvalds /* Execute request and wait for completion. */
1071da177e4SLinus Torvalds static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt),
1081da177e4SLinus Torvalds 					unsigned long opt, __u32 timeout)
1091da177e4SLinus Torvalds {
1101da177e4SLinus Torvalds 	DECLARE_WAITQUEUE(wait, current);
1111da177e4SLinus Torvalds 	int err = 0;
1121da177e4SLinus Torvalds 
1131da177e4SLinus Torvalds 	BT_DBG("%s start", hdev->name);
1141da177e4SLinus Torvalds 
1151da177e4SLinus Torvalds 	hdev->req_status = HCI_REQ_PEND;
1161da177e4SLinus Torvalds 
1171da177e4SLinus Torvalds 	add_wait_queue(&hdev->req_wait_q, &wait);
1181da177e4SLinus Torvalds 	set_current_state(TASK_INTERRUPTIBLE);
1191da177e4SLinus Torvalds 
1201da177e4SLinus Torvalds 	req(hdev, opt);
1211da177e4SLinus Torvalds 	schedule_timeout(timeout);
1221da177e4SLinus Torvalds 
1231da177e4SLinus Torvalds 	remove_wait_queue(&hdev->req_wait_q, &wait);
1241da177e4SLinus Torvalds 
1251da177e4SLinus Torvalds 	if (signal_pending(current))
1261da177e4SLinus Torvalds 		return -EINTR;
1271da177e4SLinus Torvalds 
1281da177e4SLinus Torvalds 	switch (hdev->req_status) {
1291da177e4SLinus Torvalds 	case HCI_REQ_DONE:
130e175072fSJoe Perches 		err = -bt_to_errno(hdev->req_result);
1311da177e4SLinus Torvalds 		break;
1321da177e4SLinus Torvalds 
1331da177e4SLinus Torvalds 	case HCI_REQ_CANCELED:
1341da177e4SLinus Torvalds 		err = -hdev->req_result;
1351da177e4SLinus Torvalds 		break;
1361da177e4SLinus Torvalds 
1371da177e4SLinus Torvalds 	default:
1381da177e4SLinus Torvalds 		err = -ETIMEDOUT;
1391da177e4SLinus Torvalds 		break;
1403ff50b79SStephen Hemminger 	}
1411da177e4SLinus Torvalds 
142a5040efaSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
1431da177e4SLinus Torvalds 
1441da177e4SLinus Torvalds 	BT_DBG("%s end: err %d", hdev->name, err);
1451da177e4SLinus Torvalds 
1461da177e4SLinus Torvalds 	return err;
1471da177e4SLinus Torvalds }
1481da177e4SLinus Torvalds 
1491da177e4SLinus Torvalds static inline int hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt),
1501da177e4SLinus Torvalds 					unsigned long opt, __u32 timeout)
1511da177e4SLinus Torvalds {
1521da177e4SLinus Torvalds 	int ret;
1531da177e4SLinus Torvalds 
1547c6a329eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
1557c6a329eSMarcel Holtmann 		return -ENETDOWN;
1567c6a329eSMarcel Holtmann 
1571da177e4SLinus Torvalds 	/* Serialize all requests */
1581da177e4SLinus Torvalds 	hci_req_lock(hdev);
1591da177e4SLinus Torvalds 	ret = __hci_request(hdev, req, opt, timeout);
1601da177e4SLinus Torvalds 	hci_req_unlock(hdev);
1611da177e4SLinus Torvalds 
1621da177e4SLinus Torvalds 	return ret;
1631da177e4SLinus Torvalds }
1641da177e4SLinus Torvalds 
1651da177e4SLinus Torvalds static void hci_reset_req(struct hci_dev *hdev, unsigned long opt)
1661da177e4SLinus Torvalds {
1671da177e4SLinus Torvalds 	BT_DBG("%s %ld", hdev->name, opt);
1681da177e4SLinus Torvalds 
1691da177e4SLinus Torvalds 	/* Reset device */
170f630cf0dSGustavo F. Padovan 	set_bit(HCI_RESET, &hdev->flags);
171a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
1721da177e4SLinus Torvalds }
1731da177e4SLinus Torvalds 
174e61ef499SAndrei Emeltchenko static void bredr_init(struct hci_dev *hdev)
1751da177e4SLinus Torvalds {
176b0916ea0SJohan Hedberg 	struct hci_cp_delete_stored_link_key cp;
1771ebb9252SMarcel Holtmann 	__le16 param;
17889f2783dSMarcel Holtmann 	__u8 flt_type;
1791da177e4SLinus Torvalds 
1802455a3eaSAndrei Emeltchenko 	hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
1812455a3eaSAndrei Emeltchenko 
1821da177e4SLinus Torvalds 	/* Mandatory initialization */
1831da177e4SLinus Torvalds 
1841da177e4SLinus Torvalds 	/* Reset */
185f630cf0dSGustavo F. Padovan 	if (!test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) {
186f630cf0dSGustavo F. Padovan 		set_bit(HCI_RESET, &hdev->flags);
187a9de9248SMarcel Holtmann 		hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
188f630cf0dSGustavo F. Padovan 	}
1891da177e4SLinus Torvalds 
1901da177e4SLinus Torvalds 	/* Read Local Supported Features */
191a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
1921da177e4SLinus Torvalds 
1931143e5a6SMarcel Holtmann 	/* Read Local Version */
194a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
1951143e5a6SMarcel Holtmann 
1961da177e4SLinus Torvalds 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
197a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
1981da177e4SLinus Torvalds 
1991da177e4SLinus Torvalds 	/* Read BD Address */
200a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL);
201a9de9248SMarcel Holtmann 
202a9de9248SMarcel Holtmann 	/* Read Class of Device */
203a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
204a9de9248SMarcel Holtmann 
205a9de9248SMarcel Holtmann 	/* Read Local Name */
206a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL);
2071da177e4SLinus Torvalds 
2081da177e4SLinus Torvalds 	/* Read Voice Setting */
209a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL);
2101da177e4SLinus Torvalds 
2111da177e4SLinus Torvalds 	/* Optional initialization */
2121da177e4SLinus Torvalds 
2131da177e4SLinus Torvalds 	/* Clear Event Filters */
21489f2783dSMarcel Holtmann 	flt_type = HCI_FLT_CLEAR_ALL;
215a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
2161da177e4SLinus Torvalds 
2171da177e4SLinus Torvalds 	/* Connection accept timeout ~20 secs */
218aca3192cSYOSHIFUJI Hideaki 	param = cpu_to_le16(0x7d00);
219a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
220b0916ea0SJohan Hedberg 
221b0916ea0SJohan Hedberg 	bacpy(&cp.bdaddr, BDADDR_ANY);
222b0916ea0SJohan Hedberg 	cp.delete_all = 1;
223b0916ea0SJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp);
2241da177e4SLinus Torvalds }
2251da177e4SLinus Torvalds 
226e61ef499SAndrei Emeltchenko static void amp_init(struct hci_dev *hdev)
227e61ef499SAndrei Emeltchenko {
2282455a3eaSAndrei Emeltchenko 	hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
2292455a3eaSAndrei Emeltchenko 
230e61ef499SAndrei Emeltchenko 	/* Reset */
231e61ef499SAndrei Emeltchenko 	hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
232e61ef499SAndrei Emeltchenko 
233e61ef499SAndrei Emeltchenko 	/* Read Local Version */
234e61ef499SAndrei Emeltchenko 	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
235e61ef499SAndrei Emeltchenko }
236e61ef499SAndrei Emeltchenko 
237e61ef499SAndrei Emeltchenko static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
238e61ef499SAndrei Emeltchenko {
239e61ef499SAndrei Emeltchenko 	struct sk_buff *skb;
240e61ef499SAndrei Emeltchenko 
241e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
242e61ef499SAndrei Emeltchenko 
243e61ef499SAndrei Emeltchenko 	/* Driver initialization */
244e61ef499SAndrei Emeltchenko 
245e61ef499SAndrei Emeltchenko 	/* Special commands */
246e61ef499SAndrei Emeltchenko 	while ((skb = skb_dequeue(&hdev->driver_init))) {
247e61ef499SAndrei Emeltchenko 		bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
248e61ef499SAndrei Emeltchenko 		skb->dev = (void *) hdev;
249e61ef499SAndrei Emeltchenko 
250e61ef499SAndrei Emeltchenko 		skb_queue_tail(&hdev->cmd_q, skb);
251e61ef499SAndrei Emeltchenko 		queue_work(hdev->workqueue, &hdev->cmd_work);
252e61ef499SAndrei Emeltchenko 	}
253e61ef499SAndrei Emeltchenko 	skb_queue_purge(&hdev->driver_init);
254e61ef499SAndrei Emeltchenko 
255e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
256e61ef499SAndrei Emeltchenko 	case HCI_BREDR:
257e61ef499SAndrei Emeltchenko 		bredr_init(hdev);
258e61ef499SAndrei Emeltchenko 		break;
259e61ef499SAndrei Emeltchenko 
260e61ef499SAndrei Emeltchenko 	case HCI_AMP:
261e61ef499SAndrei Emeltchenko 		amp_init(hdev);
262e61ef499SAndrei Emeltchenko 		break;
263e61ef499SAndrei Emeltchenko 
264e61ef499SAndrei Emeltchenko 	default:
265e61ef499SAndrei Emeltchenko 		BT_ERR("Unknown device type %d", hdev->dev_type);
266e61ef499SAndrei Emeltchenko 		break;
267e61ef499SAndrei Emeltchenko 	}
268e61ef499SAndrei Emeltchenko 
269e61ef499SAndrei Emeltchenko }
270e61ef499SAndrei Emeltchenko 
2716ed58ec5SVille Tervo static void hci_le_init_req(struct hci_dev *hdev, unsigned long opt)
2726ed58ec5SVille Tervo {
2736ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
2746ed58ec5SVille Tervo 
2756ed58ec5SVille Tervo 	/* Read LE buffer size */
2766ed58ec5SVille Tervo 	hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
2776ed58ec5SVille Tervo }
2786ed58ec5SVille Tervo 
2791da177e4SLinus Torvalds static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
2801da177e4SLinus Torvalds {
2811da177e4SLinus Torvalds 	__u8 scan = opt;
2821da177e4SLinus Torvalds 
2831da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, scan);
2841da177e4SLinus Torvalds 
2851da177e4SLinus Torvalds 	/* Inquiry and Page scans */
286a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
2871da177e4SLinus Torvalds }
2881da177e4SLinus Torvalds 
2891da177e4SLinus Torvalds static void hci_auth_req(struct hci_dev *hdev, unsigned long opt)
2901da177e4SLinus Torvalds {
2911da177e4SLinus Torvalds 	__u8 auth = opt;
2921da177e4SLinus Torvalds 
2931da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, auth);
2941da177e4SLinus Torvalds 
2951da177e4SLinus Torvalds 	/* Authentication */
296a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
2971da177e4SLinus Torvalds }
2981da177e4SLinus Torvalds 
2991da177e4SLinus Torvalds static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt)
3001da177e4SLinus Torvalds {
3011da177e4SLinus Torvalds 	__u8 encrypt = opt;
3021da177e4SLinus Torvalds 
3031da177e4SLinus Torvalds 	BT_DBG("%s %x", hdev->name, encrypt);
3041da177e4SLinus Torvalds 
305e4e8e37cSMarcel Holtmann 	/* Encryption */
306a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
3071da177e4SLinus Torvalds }
3081da177e4SLinus Torvalds 
309e4e8e37cSMarcel Holtmann static void hci_linkpol_req(struct hci_dev *hdev, unsigned long opt)
310e4e8e37cSMarcel Holtmann {
311e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
312e4e8e37cSMarcel Holtmann 
313a418b893SMarcel Holtmann 	BT_DBG("%s %x", hdev->name, policy);
314e4e8e37cSMarcel Holtmann 
315e4e8e37cSMarcel Holtmann 	/* Default link policy */
316e4e8e37cSMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
317e4e8e37cSMarcel Holtmann }
318e4e8e37cSMarcel Holtmann 
3191da177e4SLinus Torvalds /* Get HCI device by index.
3201da177e4SLinus Torvalds  * Device is held on return. */
3211da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
3221da177e4SLinus Torvalds {
3238035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
3241da177e4SLinus Torvalds 
3251da177e4SLinus Torvalds 	BT_DBG("%d", index);
3261da177e4SLinus Torvalds 
3271da177e4SLinus Torvalds 	if (index < 0)
3281da177e4SLinus Torvalds 		return NULL;
3291da177e4SLinus Torvalds 
3301da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
3318035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
3321da177e4SLinus Torvalds 		if (d->id == index) {
3331da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
3341da177e4SLinus Torvalds 			break;
3351da177e4SLinus Torvalds 		}
3361da177e4SLinus Torvalds 	}
3371da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
3381da177e4SLinus Torvalds 	return hdev;
3391da177e4SLinus Torvalds }
3401da177e4SLinus Torvalds 
3411da177e4SLinus Torvalds /* ---- Inquiry support ---- */
342ff9ef578SJohan Hedberg 
34330dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
34430dc78e1SJohan Hedberg {
34530dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
34630dc78e1SJohan Hedberg 
3476fbe195dSAndre Guedes 	switch (discov->state) {
348343f935bSAndre Guedes 	case DISCOVERY_FINDING:
3496fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
35030dc78e1SJohan Hedberg 		return true;
35130dc78e1SJohan Hedberg 
3526fbe195dSAndre Guedes 	default:
35330dc78e1SJohan Hedberg 		return false;
35430dc78e1SJohan Hedberg 	}
3556fbe195dSAndre Guedes }
35630dc78e1SJohan Hedberg 
357ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
358ff9ef578SJohan Hedberg {
359ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
360ff9ef578SJohan Hedberg 
361ff9ef578SJohan Hedberg 	if (hdev->discovery.state == state)
362ff9ef578SJohan Hedberg 		return;
363ff9ef578SJohan Hedberg 
364ff9ef578SJohan Hedberg 	switch (state) {
365ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
3667b99b659SAndre Guedes 		if (hdev->discovery.state != DISCOVERY_STARTING)
367ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
368f963e8e9SJohan Hedberg 		hdev->discovery.type = 0;
369ff9ef578SJohan Hedberg 		break;
370ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
371ff9ef578SJohan Hedberg 		break;
372343f935bSAndre Guedes 	case DISCOVERY_FINDING:
373ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
374ff9ef578SJohan Hedberg 		break;
37530dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
37630dc78e1SJohan Hedberg 		break;
377ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
378ff9ef578SJohan Hedberg 		break;
379ff9ef578SJohan Hedberg 	}
380ff9ef578SJohan Hedberg 
381ff9ef578SJohan Hedberg 	hdev->discovery.state = state;
382ff9ef578SJohan Hedberg }
383ff9ef578SJohan Hedberg 
3841da177e4SLinus Torvalds static void inquiry_cache_flush(struct hci_dev *hdev)
3851da177e4SLinus Torvalds {
38630883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
387b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
3881da177e4SLinus Torvalds 
389561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
390561aafbcSJohan Hedberg 		list_del(&p->all);
391b57c1a56SJohan Hedberg 		kfree(p);
3921da177e4SLinus Torvalds 	}
393561aafbcSJohan Hedberg 
394561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
395561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
396ff9ef578SJohan Hedberg 	cache->state = DISCOVERY_STOPPED;
3971da177e4SLinus Torvalds }
3981da177e4SLinus Torvalds 
3991da177e4SLinus Torvalds struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
4001da177e4SLinus Torvalds {
40130883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
4021da177e4SLinus Torvalds 	struct inquiry_entry *e;
4031da177e4SLinus Torvalds 
4041da177e4SLinus Torvalds 	BT_DBG("cache %p, %s", cache, batostr(bdaddr));
4051da177e4SLinus Torvalds 
406561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
4071da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
4081da177e4SLinus Torvalds 			return e;
4091da177e4SLinus Torvalds 	}
4101da177e4SLinus Torvalds 
411b57c1a56SJohan Hedberg 	return NULL;
412b57c1a56SJohan Hedberg }
413b57c1a56SJohan Hedberg 
414561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
415561aafbcSJohan Hedberg 							bdaddr_t *bdaddr)
416561aafbcSJohan Hedberg {
41730883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
418561aafbcSJohan Hedberg 	struct inquiry_entry *e;
419561aafbcSJohan Hedberg 
420561aafbcSJohan Hedberg 	BT_DBG("cache %p, %s", cache, batostr(bdaddr));
421561aafbcSJohan Hedberg 
422561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
423561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
424561aafbcSJohan Hedberg 			return e;
425561aafbcSJohan Hedberg 	}
426561aafbcSJohan Hedberg 
427561aafbcSJohan Hedberg 	return NULL;
428561aafbcSJohan Hedberg }
429561aafbcSJohan Hedberg 
43030dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
43130dc78e1SJohan Hedberg 							bdaddr_t *bdaddr,
43230dc78e1SJohan Hedberg 							int state)
43330dc78e1SJohan Hedberg {
43430dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
43530dc78e1SJohan Hedberg 	struct inquiry_entry *e;
43630dc78e1SJohan Hedberg 
43730dc78e1SJohan Hedberg 	BT_DBG("cache %p bdaddr %s state %d", cache, batostr(bdaddr), state);
43830dc78e1SJohan Hedberg 
43930dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
44030dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
44130dc78e1SJohan Hedberg 			return e;
44230dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
44330dc78e1SJohan Hedberg 			return e;
44430dc78e1SJohan Hedberg 	}
44530dc78e1SJohan Hedberg 
44630dc78e1SJohan Hedberg 	return NULL;
44730dc78e1SJohan Hedberg }
44830dc78e1SJohan Hedberg 
449a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
450a3d4e20aSJohan Hedberg 						struct inquiry_entry *ie)
451a3d4e20aSJohan Hedberg {
452a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
453a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
454a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
455a3d4e20aSJohan Hedberg 
456a3d4e20aSJohan Hedberg 	list_del(&ie->list);
457a3d4e20aSJohan Hedberg 
458a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
459a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
460a3d4e20aSJohan Hedberg 				abs(p->data.rssi) >= abs(ie->data.rssi))
461a3d4e20aSJohan Hedberg 			break;
462a3d4e20aSJohan Hedberg 		pos = &p->list;
463a3d4e20aSJohan Hedberg 	}
464a3d4e20aSJohan Hedberg 
465a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
466a3d4e20aSJohan Hedberg }
467a3d4e20aSJohan Hedberg 
4683175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
469388fc8faSJohan Hedberg 						bool name_known, bool *ssp)
4701da177e4SLinus Torvalds {
47130883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
47270f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
4731da177e4SLinus Torvalds 
4741da177e4SLinus Torvalds 	BT_DBG("cache %p, %s", cache, batostr(&data->bdaddr));
4751da177e4SLinus Torvalds 
476388fc8faSJohan Hedberg 	if (ssp)
477388fc8faSJohan Hedberg 		*ssp = data->ssp_mode;
478388fc8faSJohan Hedberg 
47970f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
480a3d4e20aSJohan Hedberg 	if (ie) {
481388fc8faSJohan Hedberg 		if (ie->data.ssp_mode && ssp)
482388fc8faSJohan Hedberg 			*ssp = true;
483388fc8faSJohan Hedberg 
484a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
485a3d4e20aSJohan Hedberg 						data->rssi != ie->data.rssi) {
486a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
487a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
488a3d4e20aSJohan Hedberg 		}
489a3d4e20aSJohan Hedberg 
490561aafbcSJohan Hedberg 		goto update;
491a3d4e20aSJohan Hedberg 	}
492561aafbcSJohan Hedberg 
4931da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
49470f23020SAndrei Emeltchenko 	ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
49570f23020SAndrei Emeltchenko 	if (!ie)
4963175405bSJohan Hedberg 		return false;
49770f23020SAndrei Emeltchenko 
498561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
499561aafbcSJohan Hedberg 
500561aafbcSJohan Hedberg 	if (name_known) {
501561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
502561aafbcSJohan Hedberg 	} else {
503561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
504561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
505561aafbcSJohan Hedberg 	}
506561aafbcSJohan Hedberg 
507561aafbcSJohan Hedberg update:
508561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
509561aafbcSJohan Hedberg 					ie->name_state != NAME_PENDING) {
510561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
511561aafbcSJohan Hedberg 		list_del(&ie->list);
5121da177e4SLinus Torvalds 	}
5131da177e4SLinus Torvalds 
51470f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
51570f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
5161da177e4SLinus Torvalds 	cache->timestamp = jiffies;
5173175405bSJohan Hedberg 
5183175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
5193175405bSJohan Hedberg 		return false;
5203175405bSJohan Hedberg 
5213175405bSJohan Hedberg 	return true;
5221da177e4SLinus Torvalds }
5231da177e4SLinus Torvalds 
5241da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
5251da177e4SLinus Torvalds {
52630883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
5271da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
5281da177e4SLinus Torvalds 	struct inquiry_entry *e;
5291da177e4SLinus Torvalds 	int copied = 0;
5301da177e4SLinus Torvalds 
531561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
5321da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
533b57c1a56SJohan Hedberg 
534b57c1a56SJohan Hedberg 		if (copied >= num)
535b57c1a56SJohan Hedberg 			break;
536b57c1a56SJohan Hedberg 
5371da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
5381da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
5391da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
5401da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
5411da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
5421da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
543b57c1a56SJohan Hedberg 
5441da177e4SLinus Torvalds 		info++;
545b57c1a56SJohan Hedberg 		copied++;
5461da177e4SLinus Torvalds 	}
5471da177e4SLinus Torvalds 
5481da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
5491da177e4SLinus Torvalds 	return copied;
5501da177e4SLinus Torvalds }
5511da177e4SLinus Torvalds 
5521da177e4SLinus Torvalds static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
5531da177e4SLinus Torvalds {
5541da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
5551da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
5561da177e4SLinus Torvalds 
5571da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
5581da177e4SLinus Torvalds 
5591da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
5601da177e4SLinus Torvalds 		return;
5611da177e4SLinus Torvalds 
5621da177e4SLinus Torvalds 	/* Start Inquiry */
5631da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
5641da177e4SLinus Torvalds 	cp.length  = ir->length;
5651da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
566a9de9248SMarcel Holtmann 	hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
5671da177e4SLinus Torvalds }
5681da177e4SLinus Torvalds 
5691da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
5701da177e4SLinus Torvalds {
5711da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
5721da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
5731da177e4SLinus Torvalds 	struct hci_dev *hdev;
5741da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
5751da177e4SLinus Torvalds 	long timeo;
5761da177e4SLinus Torvalds 	__u8 *buf;
5771da177e4SLinus Torvalds 
5781da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
5791da177e4SLinus Torvalds 		return -EFAULT;
5801da177e4SLinus Torvalds 
5815a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
5825a08ecceSAndrei Emeltchenko 	if (!hdev)
5831da177e4SLinus Torvalds 		return -ENODEV;
5841da177e4SLinus Torvalds 
58509fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
5861da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
5871da177e4SLinus Torvalds 				inquiry_cache_empty(hdev) ||
5881da177e4SLinus Torvalds 				ir.flags & IREQ_CACHE_FLUSH) {
5891da177e4SLinus Torvalds 		inquiry_cache_flush(hdev);
5901da177e4SLinus Torvalds 		do_inquiry = 1;
5911da177e4SLinus Torvalds 	}
59209fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
5931da177e4SLinus Torvalds 
59404837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
59570f23020SAndrei Emeltchenko 
59670f23020SAndrei Emeltchenko 	if (do_inquiry) {
59770f23020SAndrei Emeltchenko 		err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo);
59870f23020SAndrei Emeltchenko 		if (err < 0)
5991da177e4SLinus Torvalds 			goto done;
60070f23020SAndrei Emeltchenko 	}
6011da177e4SLinus Torvalds 
6021da177e4SLinus Torvalds 	/* for unlimited number of responses we will use buffer with 255 entries */
6031da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
6041da177e4SLinus Torvalds 
6051da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
6061da177e4SLinus Torvalds 	 * copy it to the user space.
6071da177e4SLinus Torvalds 	 */
60870f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
60970f23020SAndrei Emeltchenko 	if (!buf) {
6101da177e4SLinus Torvalds 		err = -ENOMEM;
6111da177e4SLinus Torvalds 		goto done;
6121da177e4SLinus Torvalds 	}
6131da177e4SLinus Torvalds 
61409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
6151da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
61609fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
6171da177e4SLinus Torvalds 
6181da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
6191da177e4SLinus Torvalds 
6201da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
6211da177e4SLinus Torvalds 		ptr += sizeof(ir);
6221da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
6231da177e4SLinus Torvalds 					ir.num_rsp))
6241da177e4SLinus Torvalds 			err = -EFAULT;
6251da177e4SLinus Torvalds 	} else
6261da177e4SLinus Torvalds 		err = -EFAULT;
6271da177e4SLinus Torvalds 
6281da177e4SLinus Torvalds 	kfree(buf);
6291da177e4SLinus Torvalds 
6301da177e4SLinus Torvalds done:
6311da177e4SLinus Torvalds 	hci_dev_put(hdev);
6321da177e4SLinus Torvalds 	return err;
6331da177e4SLinus Torvalds }
6341da177e4SLinus Torvalds 
6351da177e4SLinus Torvalds /* ---- HCI ioctl helpers ---- */
6361da177e4SLinus Torvalds 
6371da177e4SLinus Torvalds int hci_dev_open(__u16 dev)
6381da177e4SLinus Torvalds {
6391da177e4SLinus Torvalds 	struct hci_dev *hdev;
6401da177e4SLinus Torvalds 	int ret = 0;
6411da177e4SLinus Torvalds 
6425a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(dev);
6435a08ecceSAndrei Emeltchenko 	if (!hdev)
6441da177e4SLinus Torvalds 		return -ENODEV;
6451da177e4SLinus Torvalds 
6461da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
6471da177e4SLinus Torvalds 
6481da177e4SLinus Torvalds 	hci_req_lock(hdev);
6491da177e4SLinus Torvalds 
650611b30f7SMarcel Holtmann 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) {
651611b30f7SMarcel Holtmann 		ret = -ERFKILL;
652611b30f7SMarcel Holtmann 		goto done;
653611b30f7SMarcel Holtmann 	}
654611b30f7SMarcel Holtmann 
6551da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
6561da177e4SLinus Torvalds 		ret = -EALREADY;
6571da177e4SLinus Torvalds 		goto done;
6581da177e4SLinus Torvalds 	}
6591da177e4SLinus Torvalds 
6601da177e4SLinus Torvalds 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
6611da177e4SLinus Torvalds 		set_bit(HCI_RAW, &hdev->flags);
6621da177e4SLinus Torvalds 
66307e3b94aSAndrei Emeltchenko 	/* Treat all non BR/EDR controllers as raw devices if
66407e3b94aSAndrei Emeltchenko 	   enable_hs is not set */
66507e3b94aSAndrei Emeltchenko 	if (hdev->dev_type != HCI_BREDR && !enable_hs)
666943da25dSMarcel Holtmann 		set_bit(HCI_RAW, &hdev->flags);
667943da25dSMarcel Holtmann 
6681da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
6691da177e4SLinus Torvalds 		ret = -EIO;
6701da177e4SLinus Torvalds 		goto done;
6711da177e4SLinus Torvalds 	}
6721da177e4SLinus Torvalds 
6731da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
6741da177e4SLinus Torvalds 		atomic_set(&hdev->cmd_cnt, 1);
6751da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
676a5040efaSJohan Hedberg 		hdev->init_last_cmd = 0;
6771da177e4SLinus Torvalds 
67804837f64SMarcel Holtmann 		ret = __hci_request(hdev, hci_init_req, 0,
67904837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
6801da177e4SLinus Torvalds 
681eead27daSAndre Guedes 		if (lmp_host_le_capable(hdev))
6826ed58ec5SVille Tervo 			ret = __hci_request(hdev, hci_le_init_req, 0,
6836ed58ec5SVille Tervo 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
6846ed58ec5SVille Tervo 
6851da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
6861da177e4SLinus Torvalds 	}
6871da177e4SLinus Torvalds 
6881da177e4SLinus Torvalds 	if (!ret) {
6891da177e4SLinus Torvalds 		hci_dev_hold(hdev);
6901da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
6911da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
692a8b2d5c2SJohan Hedberg 		if (!test_bit(HCI_SETUP, &hdev->dev_flags)) {
69309fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
694744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
69509fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
69656e5cb86SJohan Hedberg 		}
6971da177e4SLinus Torvalds 	} else {
6981da177e4SLinus Torvalds 		/* Init failed, cleanup */
6993eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
700c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
701b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
7021da177e4SLinus Torvalds 
7031da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
7041da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
7051da177e4SLinus Torvalds 
7061da177e4SLinus Torvalds 		if (hdev->flush)
7071da177e4SLinus Torvalds 			hdev->flush(hdev);
7081da177e4SLinus Torvalds 
7091da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
7101da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
7111da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
7121da177e4SLinus Torvalds 		}
7131da177e4SLinus Torvalds 
7141da177e4SLinus Torvalds 		hdev->close(hdev);
7151da177e4SLinus Torvalds 		hdev->flags = 0;
7161da177e4SLinus Torvalds 	}
7171da177e4SLinus Torvalds 
7181da177e4SLinus Torvalds done:
7191da177e4SLinus Torvalds 	hci_req_unlock(hdev);
7201da177e4SLinus Torvalds 	hci_dev_put(hdev);
7211da177e4SLinus Torvalds 	return ret;
7221da177e4SLinus Torvalds }
7231da177e4SLinus Torvalds 
7241da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
7251da177e4SLinus Torvalds {
7261da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
7271da177e4SLinus Torvalds 
72828b75a89SAndre Guedes 	cancel_work_sync(&hdev->le_scan);
72928b75a89SAndre Guedes 
7301da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
7311da177e4SLinus Torvalds 	hci_req_lock(hdev);
7321da177e4SLinus Torvalds 
7331da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
734b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
7351da177e4SLinus Torvalds 		hci_req_unlock(hdev);
7361da177e4SLinus Torvalds 		return 0;
7371da177e4SLinus Torvalds 	}
7381da177e4SLinus Torvalds 
7393eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
7403eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
741b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
7421da177e4SLinus Torvalds 
74316ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
744e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
74516ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
7465e5282bbSJohan Hedberg 		clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
74716ab91abSJohan Hedberg 	}
74816ab91abSJohan Hedberg 
749a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
7507d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
7517d78525dSJohan Hedberg 
7527ba8b4beSAndre Guedes 	cancel_delayed_work_sync(&hdev->le_scan_disable);
7537ba8b4beSAndre Guedes 
75409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
7551da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
7561da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
75709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
7581da177e4SLinus Torvalds 
7591da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
7601da177e4SLinus Torvalds 
7611da177e4SLinus Torvalds 	if (hdev->flush)
7621da177e4SLinus Torvalds 		hdev->flush(hdev);
7631da177e4SLinus Torvalds 
7641da177e4SLinus Torvalds 	/* Reset device */
7651da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
7661da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
7678af59467SJohan Hedberg 	if (!test_bit(HCI_RAW, &hdev->flags) &&
7688af59467SJohan Hedberg 				test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) {
7691da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
77004837f64SMarcel Holtmann 		__hci_request(hdev, hci_reset_req, 0,
771cad44c2bSGustavo F. Padovan 					msecs_to_jiffies(250));
7721da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
7731da177e4SLinus Torvalds 	}
7741da177e4SLinus Torvalds 
775c347b765SGustavo F. Padovan 	/* flush cmd  work */
776c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
7771da177e4SLinus Torvalds 
7781da177e4SLinus Torvalds 	/* Drop queues */
7791da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
7801da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
7811da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
7821da177e4SLinus Torvalds 
7831da177e4SLinus Torvalds 	/* Drop last sent command */
7841da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
785b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
7861da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
7871da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
7881da177e4SLinus Torvalds 	}
7891da177e4SLinus Torvalds 
7901da177e4SLinus Torvalds 	/* After this point our queues are empty
7911da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
7921da177e4SLinus Torvalds 	hdev->close(hdev);
7931da177e4SLinus Torvalds 
7948ee56540SMarcel Holtmann 	if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
79509fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
796744cf19eSJohan Hedberg 		mgmt_powered(hdev, 0);
79709fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
7988ee56540SMarcel Holtmann 	}
7995add6af8SJohan Hedberg 
8001da177e4SLinus Torvalds 	/* Clear flags */
8011da177e4SLinus Torvalds 	hdev->flags = 0;
8021da177e4SLinus Torvalds 
803e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
80409b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
805e59fda8dSJohan Hedberg 
8061da177e4SLinus Torvalds 	hci_req_unlock(hdev);
8071da177e4SLinus Torvalds 
8081da177e4SLinus Torvalds 	hci_dev_put(hdev);
8091da177e4SLinus Torvalds 	return 0;
8101da177e4SLinus Torvalds }
8111da177e4SLinus Torvalds 
8121da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
8131da177e4SLinus Torvalds {
8141da177e4SLinus Torvalds 	struct hci_dev *hdev;
8151da177e4SLinus Torvalds 	int err;
8161da177e4SLinus Torvalds 
81770f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
81870f23020SAndrei Emeltchenko 	if (!hdev)
8191da177e4SLinus Torvalds 		return -ENODEV;
8208ee56540SMarcel Holtmann 
8218ee56540SMarcel Holtmann 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
8228ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
8238ee56540SMarcel Holtmann 
8241da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
8258ee56540SMarcel Holtmann 
8261da177e4SLinus Torvalds 	hci_dev_put(hdev);
8271da177e4SLinus Torvalds 	return err;
8281da177e4SLinus Torvalds }
8291da177e4SLinus Torvalds 
8301da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
8311da177e4SLinus Torvalds {
8321da177e4SLinus Torvalds 	struct hci_dev *hdev;
8331da177e4SLinus Torvalds 	int ret = 0;
8341da177e4SLinus Torvalds 
83570f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
83670f23020SAndrei Emeltchenko 	if (!hdev)
8371da177e4SLinus Torvalds 		return -ENODEV;
8381da177e4SLinus Torvalds 
8391da177e4SLinus Torvalds 	hci_req_lock(hdev);
8401da177e4SLinus Torvalds 
8411da177e4SLinus Torvalds 	if (!test_bit(HCI_UP, &hdev->flags))
8421da177e4SLinus Torvalds 		goto done;
8431da177e4SLinus Torvalds 
8441da177e4SLinus Torvalds 	/* Drop queues */
8451da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
8461da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
8471da177e4SLinus Torvalds 
84809fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
8491da177e4SLinus Torvalds 	inquiry_cache_flush(hdev);
8501da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
85109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
8521da177e4SLinus Torvalds 
8531da177e4SLinus Torvalds 	if (hdev->flush)
8541da177e4SLinus Torvalds 		hdev->flush(hdev);
8551da177e4SLinus Torvalds 
8561da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
8576ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
8581da177e4SLinus Torvalds 
8591da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags))
86004837f64SMarcel Holtmann 		ret = __hci_request(hdev, hci_reset_req, 0,
86104837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
8621da177e4SLinus Torvalds 
8631da177e4SLinus Torvalds done:
8641da177e4SLinus Torvalds 	hci_req_unlock(hdev);
8651da177e4SLinus Torvalds 	hci_dev_put(hdev);
8661da177e4SLinus Torvalds 	return ret;
8671da177e4SLinus Torvalds }
8681da177e4SLinus Torvalds 
8691da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
8701da177e4SLinus Torvalds {
8711da177e4SLinus Torvalds 	struct hci_dev *hdev;
8721da177e4SLinus Torvalds 	int ret = 0;
8731da177e4SLinus Torvalds 
87470f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
87570f23020SAndrei Emeltchenko 	if (!hdev)
8761da177e4SLinus Torvalds 		return -ENODEV;
8771da177e4SLinus Torvalds 
8781da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
8791da177e4SLinus Torvalds 
8801da177e4SLinus Torvalds 	hci_dev_put(hdev);
8811da177e4SLinus Torvalds 
8821da177e4SLinus Torvalds 	return ret;
8831da177e4SLinus Torvalds }
8841da177e4SLinus Torvalds 
8851da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
8861da177e4SLinus Torvalds {
8871da177e4SLinus Torvalds 	struct hci_dev *hdev;
8881da177e4SLinus Torvalds 	struct hci_dev_req dr;
8891da177e4SLinus Torvalds 	int err = 0;
8901da177e4SLinus Torvalds 
8911da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
8921da177e4SLinus Torvalds 		return -EFAULT;
8931da177e4SLinus Torvalds 
89470f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
89570f23020SAndrei Emeltchenko 	if (!hdev)
8961da177e4SLinus Torvalds 		return -ENODEV;
8971da177e4SLinus Torvalds 
8981da177e4SLinus Torvalds 	switch (cmd) {
8991da177e4SLinus Torvalds 	case HCISETAUTH:
90004837f64SMarcel Holtmann 		err = hci_request(hdev, hci_auth_req, dr.dev_opt,
90104837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
9021da177e4SLinus Torvalds 		break;
9031da177e4SLinus Torvalds 
9041da177e4SLinus Torvalds 	case HCISETENCRYPT:
9051da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
9061da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
9071da177e4SLinus Torvalds 			break;
9081da177e4SLinus Torvalds 		}
9091da177e4SLinus Torvalds 
9101da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
9111da177e4SLinus Torvalds 			/* Auth must be enabled first */
91204837f64SMarcel Holtmann 			err = hci_request(hdev, hci_auth_req, dr.dev_opt,
91304837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
9141da177e4SLinus Torvalds 			if (err)
9151da177e4SLinus Torvalds 				break;
9161da177e4SLinus Torvalds 		}
9171da177e4SLinus Torvalds 
91804837f64SMarcel Holtmann 		err = hci_request(hdev, hci_encrypt_req, dr.dev_opt,
91904837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
9201da177e4SLinus Torvalds 		break;
9211da177e4SLinus Torvalds 
9221da177e4SLinus Torvalds 	case HCISETSCAN:
92304837f64SMarcel Holtmann 		err = hci_request(hdev, hci_scan_req, dr.dev_opt,
92404837f64SMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
9251da177e4SLinus Torvalds 		break;
9261da177e4SLinus Torvalds 
9271da177e4SLinus Torvalds 	case HCISETLINKPOL:
928e4e8e37cSMarcel Holtmann 		err = hci_request(hdev, hci_linkpol_req, dr.dev_opt,
929e4e8e37cSMarcel Holtmann 					msecs_to_jiffies(HCI_INIT_TIMEOUT));
9301da177e4SLinus Torvalds 		break;
9311da177e4SLinus Torvalds 
9321da177e4SLinus Torvalds 	case HCISETLINKMODE:
933e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
934e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
935e4e8e37cSMarcel Holtmann 		break;
936e4e8e37cSMarcel Holtmann 
937e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
938e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
9391da177e4SLinus Torvalds 		break;
9401da177e4SLinus Torvalds 
9411da177e4SLinus Torvalds 	case HCISETACLMTU:
9421da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
9431da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
9441da177e4SLinus Torvalds 		break;
9451da177e4SLinus Torvalds 
9461da177e4SLinus Torvalds 	case HCISETSCOMTU:
9471da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
9481da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
9491da177e4SLinus Torvalds 		break;
9501da177e4SLinus Torvalds 
9511da177e4SLinus Torvalds 	default:
9521da177e4SLinus Torvalds 		err = -EINVAL;
9531da177e4SLinus Torvalds 		break;
9541da177e4SLinus Torvalds 	}
955e4e8e37cSMarcel Holtmann 
9561da177e4SLinus Torvalds 	hci_dev_put(hdev);
9571da177e4SLinus Torvalds 	return err;
9581da177e4SLinus Torvalds }
9591da177e4SLinus Torvalds 
9601da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
9611da177e4SLinus Torvalds {
9628035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
9631da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
9641da177e4SLinus Torvalds 	struct hci_dev_req *dr;
9651da177e4SLinus Torvalds 	int n = 0, size, err;
9661da177e4SLinus Torvalds 	__u16 dev_num;
9671da177e4SLinus Torvalds 
9681da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
9691da177e4SLinus Torvalds 		return -EFAULT;
9701da177e4SLinus Torvalds 
9711da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
9721da177e4SLinus Torvalds 		return -EINVAL;
9731da177e4SLinus Torvalds 
9741da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
9751da177e4SLinus Torvalds 
97670f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
97770f23020SAndrei Emeltchenko 	if (!dl)
9781da177e4SLinus Torvalds 		return -ENOMEM;
9791da177e4SLinus Torvalds 
9801da177e4SLinus Torvalds 	dr = dl->dev_req;
9811da177e4SLinus Torvalds 
982f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
9838035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
984a8b2d5c2SJohan Hedberg 		if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
985e0f9309fSJohan Hedberg 			cancel_delayed_work(&hdev->power_off);
986c542a06cSJohan Hedberg 
987a8b2d5c2SJohan Hedberg 		if (!test_bit(HCI_MGMT, &hdev->dev_flags))
988a8b2d5c2SJohan Hedberg 			set_bit(HCI_PAIRABLE, &hdev->dev_flags);
989c542a06cSJohan Hedberg 
9901da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
9911da177e4SLinus Torvalds 		(dr + n)->dev_opt = hdev->flags;
992c542a06cSJohan Hedberg 
9931da177e4SLinus Torvalds 		if (++n >= dev_num)
9941da177e4SLinus Torvalds 			break;
9951da177e4SLinus Torvalds 	}
996f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
9971da177e4SLinus Torvalds 
9981da177e4SLinus Torvalds 	dl->dev_num = n;
9991da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
10001da177e4SLinus Torvalds 
10011da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
10021da177e4SLinus Torvalds 	kfree(dl);
10031da177e4SLinus Torvalds 
10041da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
10051da177e4SLinus Torvalds }
10061da177e4SLinus Torvalds 
10071da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
10081da177e4SLinus Torvalds {
10091da177e4SLinus Torvalds 	struct hci_dev *hdev;
10101da177e4SLinus Torvalds 	struct hci_dev_info di;
10111da177e4SLinus Torvalds 	int err = 0;
10121da177e4SLinus Torvalds 
10131da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
10141da177e4SLinus Torvalds 		return -EFAULT;
10151da177e4SLinus Torvalds 
101670f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
101770f23020SAndrei Emeltchenko 	if (!hdev)
10181da177e4SLinus Torvalds 		return -ENODEV;
10191da177e4SLinus Torvalds 
1020a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
10213243553fSJohan Hedberg 		cancel_delayed_work_sync(&hdev->power_off);
1022ab81cbf9SJohan Hedberg 
1023a8b2d5c2SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1024a8b2d5c2SJohan Hedberg 		set_bit(HCI_PAIRABLE, &hdev->dev_flags);
1025c542a06cSJohan Hedberg 
10261da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
10271da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
1028943da25dSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | (hdev->dev_type << 4);
10291da177e4SLinus Torvalds 	di.flags    = hdev->flags;
10301da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
10311da177e4SLinus Torvalds 	di.acl_mtu  = hdev->acl_mtu;
10321da177e4SLinus Torvalds 	di.acl_pkts = hdev->acl_pkts;
10331da177e4SLinus Torvalds 	di.sco_mtu  = hdev->sco_mtu;
10341da177e4SLinus Torvalds 	di.sco_pkts = hdev->sco_pkts;
10351da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
10361da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
10371da177e4SLinus Torvalds 
10381da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
10391da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
10401da177e4SLinus Torvalds 
10411da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
10421da177e4SLinus Torvalds 		err = -EFAULT;
10431da177e4SLinus Torvalds 
10441da177e4SLinus Torvalds 	hci_dev_put(hdev);
10451da177e4SLinus Torvalds 
10461da177e4SLinus Torvalds 	return err;
10471da177e4SLinus Torvalds }
10481da177e4SLinus Torvalds 
10491da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
10501da177e4SLinus Torvalds 
1051611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
1052611b30f7SMarcel Holtmann {
1053611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
1054611b30f7SMarcel Holtmann 
1055611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
1056611b30f7SMarcel Holtmann 
1057611b30f7SMarcel Holtmann 	if (!blocked)
1058611b30f7SMarcel Holtmann 		return 0;
1059611b30f7SMarcel Holtmann 
1060611b30f7SMarcel Holtmann 	hci_dev_do_close(hdev);
1061611b30f7SMarcel Holtmann 
1062611b30f7SMarcel Holtmann 	return 0;
1063611b30f7SMarcel Holtmann }
1064611b30f7SMarcel Holtmann 
1065611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
1066611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
1067611b30f7SMarcel Holtmann };
1068611b30f7SMarcel Holtmann 
10691da177e4SLinus Torvalds /* Alloc HCI device */
10701da177e4SLinus Torvalds struct hci_dev *hci_alloc_dev(void)
10711da177e4SLinus Torvalds {
10721da177e4SLinus Torvalds 	struct hci_dev *hdev;
10731da177e4SLinus Torvalds 
107425ea6db0SMarcel Holtmann 	hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
10751da177e4SLinus Torvalds 	if (!hdev)
10761da177e4SLinus Torvalds 		return NULL;
10771da177e4SLinus Torvalds 
10780ac7e700SDavid Herrmann 	hci_init_sysfs(hdev);
10791da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->driver_init);
10801da177e4SLinus Torvalds 
10811da177e4SLinus Torvalds 	return hdev;
10821da177e4SLinus Torvalds }
10831da177e4SLinus Torvalds EXPORT_SYMBOL(hci_alloc_dev);
10841da177e4SLinus Torvalds 
10851da177e4SLinus Torvalds /* Free HCI device */
10861da177e4SLinus Torvalds void hci_free_dev(struct hci_dev *hdev)
10871da177e4SLinus Torvalds {
10881da177e4SLinus Torvalds 	skb_queue_purge(&hdev->driver_init);
10891da177e4SLinus Torvalds 
1090a91f2e39SMarcel Holtmann 	/* will free via device release */
1091a91f2e39SMarcel Holtmann 	put_device(&hdev->dev);
10921da177e4SLinus Torvalds }
10931da177e4SLinus Torvalds EXPORT_SYMBOL(hci_free_dev);
10941da177e4SLinus Torvalds 
1095ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
1096ab81cbf9SJohan Hedberg {
1097ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
1098ab81cbf9SJohan Hedberg 
1099ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1100ab81cbf9SJohan Hedberg 
1101ab81cbf9SJohan Hedberg 	if (hci_dev_open(hdev->id) < 0)
1102ab81cbf9SJohan Hedberg 		return;
1103ab81cbf9SJohan Hedberg 
1104a8b2d5c2SJohan Hedberg 	if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
110580b7ab33SGustavo F. Padovan 		schedule_delayed_work(&hdev->power_off,
11063243553fSJohan Hedberg 					msecs_to_jiffies(AUTO_OFF_TIMEOUT));
1107ab81cbf9SJohan Hedberg 
1108a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags))
1109744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
1110ab81cbf9SJohan Hedberg }
1111ab81cbf9SJohan Hedberg 
1112ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
1113ab81cbf9SJohan Hedberg {
11143243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
11153243553fSJohan Hedberg 							power_off.work);
1116ab81cbf9SJohan Hedberg 
1117ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
1118ab81cbf9SJohan Hedberg 
11198ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
1120ab81cbf9SJohan Hedberg }
1121ab81cbf9SJohan Hedberg 
112216ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
112316ab91abSJohan Hedberg {
112416ab91abSJohan Hedberg 	struct hci_dev *hdev;
112516ab91abSJohan Hedberg 	u8 scan = SCAN_PAGE;
112616ab91abSJohan Hedberg 
112716ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
112816ab91abSJohan Hedberg 
112916ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
113016ab91abSJohan Hedberg 
113109fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
113216ab91abSJohan Hedberg 
113316ab91abSJohan Hedberg 	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan);
113416ab91abSJohan Hedberg 
113516ab91abSJohan Hedberg 	hdev->discov_timeout = 0;
113616ab91abSJohan Hedberg 
113709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
113816ab91abSJohan Hedberg }
113916ab91abSJohan Hedberg 
11402aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev)
11412aeb9a1aSJohan Hedberg {
11422aeb9a1aSJohan Hedberg 	struct list_head *p, *n;
11432aeb9a1aSJohan Hedberg 
11442aeb9a1aSJohan Hedberg 	list_for_each_safe(p, n, &hdev->uuids) {
11452aeb9a1aSJohan Hedberg 		struct bt_uuid *uuid;
11462aeb9a1aSJohan Hedberg 
11472aeb9a1aSJohan Hedberg 		uuid = list_entry(p, struct bt_uuid, list);
11482aeb9a1aSJohan Hedberg 
11492aeb9a1aSJohan Hedberg 		list_del(p);
11502aeb9a1aSJohan Hedberg 		kfree(uuid);
11512aeb9a1aSJohan Hedberg 	}
11522aeb9a1aSJohan Hedberg 
11532aeb9a1aSJohan Hedberg 	return 0;
11542aeb9a1aSJohan Hedberg }
11552aeb9a1aSJohan Hedberg 
115655ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev)
115755ed8ca1SJohan Hedberg {
115855ed8ca1SJohan Hedberg 	struct list_head *p, *n;
115955ed8ca1SJohan Hedberg 
116055ed8ca1SJohan Hedberg 	list_for_each_safe(p, n, &hdev->link_keys) {
116155ed8ca1SJohan Hedberg 		struct link_key *key;
116255ed8ca1SJohan Hedberg 
116355ed8ca1SJohan Hedberg 		key = list_entry(p, struct link_key, list);
116455ed8ca1SJohan Hedberg 
116555ed8ca1SJohan Hedberg 		list_del(p);
116655ed8ca1SJohan Hedberg 		kfree(key);
116755ed8ca1SJohan Hedberg 	}
116855ed8ca1SJohan Hedberg 
116955ed8ca1SJohan Hedberg 	return 0;
117055ed8ca1SJohan Hedberg }
117155ed8ca1SJohan Hedberg 
1172b899efafSVinicius Costa Gomes int hci_smp_ltks_clear(struct hci_dev *hdev)
1173b899efafSVinicius Costa Gomes {
1174b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1175b899efafSVinicius Costa Gomes 
1176b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1177b899efafSVinicius Costa Gomes 		list_del(&k->list);
1178b899efafSVinicius Costa Gomes 		kfree(k);
1179b899efafSVinicius Costa Gomes 	}
1180b899efafSVinicius Costa Gomes 
1181b899efafSVinicius Costa Gomes 	return 0;
1182b899efafSVinicius Costa Gomes }
1183b899efafSVinicius Costa Gomes 
118455ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
118555ed8ca1SJohan Hedberg {
118655ed8ca1SJohan Hedberg 	struct link_key *k;
118755ed8ca1SJohan Hedberg 
11888035ded4SLuiz Augusto von Dentz 	list_for_each_entry(k, &hdev->link_keys, list)
118955ed8ca1SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0)
119055ed8ca1SJohan Hedberg 			return k;
119155ed8ca1SJohan Hedberg 
119255ed8ca1SJohan Hedberg 	return NULL;
119355ed8ca1SJohan Hedberg }
119455ed8ca1SJohan Hedberg 
1195d25e28abSJohan Hedberg static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
1196d25e28abSJohan Hedberg 						u8 key_type, u8 old_key_type)
1197d25e28abSJohan Hedberg {
1198d25e28abSJohan Hedberg 	/* Legacy key */
1199d25e28abSJohan Hedberg 	if (key_type < 0x03)
1200d25e28abSJohan Hedberg 		return 1;
1201d25e28abSJohan Hedberg 
1202d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
1203d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
1204d25e28abSJohan Hedberg 		return 0;
1205d25e28abSJohan Hedberg 
1206d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
1207d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
1208d25e28abSJohan Hedberg 		return 0;
1209d25e28abSJohan Hedberg 
1210d25e28abSJohan Hedberg 	/* Security mode 3 case */
1211d25e28abSJohan Hedberg 	if (!conn)
1212d25e28abSJohan Hedberg 		return 1;
1213d25e28abSJohan Hedberg 
1214d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
1215d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
1216d25e28abSJohan Hedberg 		return 1;
1217d25e28abSJohan Hedberg 
1218d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
1219d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
1220d25e28abSJohan Hedberg 		return 1;
1221d25e28abSJohan Hedberg 
1222d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
1223d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
1224d25e28abSJohan Hedberg 		return 1;
1225d25e28abSJohan Hedberg 
1226d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
1227d25e28abSJohan Hedberg 	 * persistently */
1228d25e28abSJohan Hedberg 	return 0;
1229d25e28abSJohan Hedberg }
1230d25e28abSJohan Hedberg 
1231c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
123275d262c2SVinicius Costa Gomes {
1233c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
123475d262c2SVinicius Costa Gomes 
1235c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list) {
1236c9839a11SVinicius Costa Gomes 		if (k->ediv != ediv ||
1237c9839a11SVinicius Costa Gomes 				memcmp(rand, k->rand, sizeof(k->rand)))
123875d262c2SVinicius Costa Gomes 			continue;
123975d262c2SVinicius Costa Gomes 
124075d262c2SVinicius Costa Gomes 		return k;
124175d262c2SVinicius Costa Gomes 	}
124275d262c2SVinicius Costa Gomes 
124375d262c2SVinicius Costa Gomes 	return NULL;
124475d262c2SVinicius Costa Gomes }
124575d262c2SVinicius Costa Gomes EXPORT_SYMBOL(hci_find_ltk);
124675d262c2SVinicius Costa Gomes 
1247c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
1248c9839a11SVinicius Costa Gomes 								u8 addr_type)
124975d262c2SVinicius Costa Gomes {
1250c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
125175d262c2SVinicius Costa Gomes 
1252c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list)
1253c9839a11SVinicius Costa Gomes 		if (addr_type == k->bdaddr_type &&
1254c9839a11SVinicius Costa Gomes 					bacmp(bdaddr, &k->bdaddr) == 0)
125575d262c2SVinicius Costa Gomes 			return k;
125675d262c2SVinicius Costa Gomes 
125775d262c2SVinicius Costa Gomes 	return NULL;
125875d262c2SVinicius Costa Gomes }
1259c9839a11SVinicius Costa Gomes EXPORT_SYMBOL(hci_find_ltk_by_addr);
126075d262c2SVinicius Costa Gomes 
1261d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
1262d25e28abSJohan Hedberg 				bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
126355ed8ca1SJohan Hedberg {
126455ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
12654df378a1SJohan Hedberg 	u8 old_key_type, persistent;
126655ed8ca1SJohan Hedberg 
126755ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
126855ed8ca1SJohan Hedberg 	if (old_key) {
126955ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
127055ed8ca1SJohan Hedberg 		key = old_key;
127155ed8ca1SJohan Hedberg 	} else {
127212adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
127355ed8ca1SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
127455ed8ca1SJohan Hedberg 		if (!key)
127555ed8ca1SJohan Hedberg 			return -ENOMEM;
127655ed8ca1SJohan Hedberg 		list_add(&key->list, &hdev->link_keys);
127755ed8ca1SJohan Hedberg 	}
127855ed8ca1SJohan Hedberg 
127955ed8ca1SJohan Hedberg 	BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type);
128055ed8ca1SJohan Hedberg 
1281d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
1282d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
1283d25e28abSJohan Hedberg 	 * previous key */
1284d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
1285d25e28abSJohan Hedberg 					(!conn || conn->remote_auth == 0xff) &&
1286655fe6ecSJohan Hedberg 					old_key_type == 0xff) {
1287d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
1288655fe6ecSJohan Hedberg 		if (conn)
1289655fe6ecSJohan Hedberg 			conn->key_type = type;
1290655fe6ecSJohan Hedberg 	}
1291d25e28abSJohan Hedberg 
129255ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
129355ed8ca1SJohan Hedberg 	memcpy(key->val, val, 16);
129455ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
129555ed8ca1SJohan Hedberg 
1296b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
129755ed8ca1SJohan Hedberg 		key->type = old_key_type;
12984748fed2SJohan Hedberg 	else
12994748fed2SJohan Hedberg 		key->type = type;
13004748fed2SJohan Hedberg 
13014df378a1SJohan Hedberg 	if (!new_key)
13024df378a1SJohan Hedberg 		return 0;
13034df378a1SJohan Hedberg 
13044df378a1SJohan Hedberg 	persistent = hci_persistent_key(hdev, conn, type, old_key_type);
13054df378a1SJohan Hedberg 
1306744cf19eSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
13074df378a1SJohan Hedberg 
13084df378a1SJohan Hedberg 	if (!persistent) {
13094df378a1SJohan Hedberg 		list_del(&key->list);
13104df378a1SJohan Hedberg 		kfree(key);
13114df378a1SJohan Hedberg 	}
131255ed8ca1SJohan Hedberg 
131355ed8ca1SJohan Hedberg 	return 0;
131455ed8ca1SJohan Hedberg }
131555ed8ca1SJohan Hedberg 
1316c9839a11SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
1317c9839a11SVinicius Costa Gomes 				int new_key, u8 authenticated, u8 tk[16],
1318c9839a11SVinicius Costa Gomes 				u8 enc_size, u16 ediv, u8 rand[8])
131975d262c2SVinicius Costa Gomes {
1320c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
132175d262c2SVinicius Costa Gomes 
1322c9839a11SVinicius Costa Gomes 	if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK))
1323c9839a11SVinicius Costa Gomes 		return 0;
132475d262c2SVinicius Costa Gomes 
1325c9839a11SVinicius Costa Gomes 	old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type);
1326c9839a11SVinicius Costa Gomes 	if (old_key)
132775d262c2SVinicius Costa Gomes 		key = old_key;
1328c9839a11SVinicius Costa Gomes 	else {
1329c9839a11SVinicius Costa Gomes 		key = kzalloc(sizeof(*key), GFP_ATOMIC);
133075d262c2SVinicius Costa Gomes 		if (!key)
133175d262c2SVinicius Costa Gomes 			return -ENOMEM;
1332c9839a11SVinicius Costa Gomes 		list_add(&key->list, &hdev->long_term_keys);
133375d262c2SVinicius Costa Gomes 	}
133475d262c2SVinicius Costa Gomes 
133575d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
1336c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
1337c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
1338c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
1339c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
1340c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
1341c9839a11SVinicius Costa Gomes 	key->type = type;
1342c9839a11SVinicius Costa Gomes 	memcpy(key->rand, rand, sizeof(key->rand));
134375d262c2SVinicius Costa Gomes 
1344c9839a11SVinicius Costa Gomes 	if (!new_key)
1345c9839a11SVinicius Costa Gomes 		return 0;
134675d262c2SVinicius Costa Gomes 
1347261cc5aaSVinicius Costa Gomes 	if (type & HCI_SMP_LTK)
1348261cc5aaSVinicius Costa Gomes 		mgmt_new_ltk(hdev, key, 1);
1349261cc5aaSVinicius Costa Gomes 
135075d262c2SVinicius Costa Gomes 	return 0;
135175d262c2SVinicius Costa Gomes }
135275d262c2SVinicius Costa Gomes 
135355ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
135455ed8ca1SJohan Hedberg {
135555ed8ca1SJohan Hedberg 	struct link_key *key;
135655ed8ca1SJohan Hedberg 
135755ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
135855ed8ca1SJohan Hedberg 	if (!key)
135955ed8ca1SJohan Hedberg 		return -ENOENT;
136055ed8ca1SJohan Hedberg 
136155ed8ca1SJohan Hedberg 	BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
136255ed8ca1SJohan Hedberg 
136355ed8ca1SJohan Hedberg 	list_del(&key->list);
136455ed8ca1SJohan Hedberg 	kfree(key);
136555ed8ca1SJohan Hedberg 
136655ed8ca1SJohan Hedberg 	return 0;
136755ed8ca1SJohan Hedberg }
136855ed8ca1SJohan Hedberg 
1369b899efafSVinicius Costa Gomes int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr)
1370b899efafSVinicius Costa Gomes {
1371b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
1372b899efafSVinicius Costa Gomes 
1373b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
1374b899efafSVinicius Costa Gomes 		if (bacmp(bdaddr, &k->bdaddr))
1375b899efafSVinicius Costa Gomes 			continue;
1376b899efafSVinicius Costa Gomes 
1377b899efafSVinicius Costa Gomes 		BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
1378b899efafSVinicius Costa Gomes 
1379b899efafSVinicius Costa Gomes 		list_del(&k->list);
1380b899efafSVinicius Costa Gomes 		kfree(k);
1381b899efafSVinicius Costa Gomes 	}
1382b899efafSVinicius Costa Gomes 
1383b899efafSVinicius Costa Gomes 	return 0;
1384b899efafSVinicius Costa Gomes }
1385b899efafSVinicius Costa Gomes 
13866bd32326SVille Tervo /* HCI command timer function */
13876bd32326SVille Tervo static void hci_cmd_timer(unsigned long arg)
13886bd32326SVille Tervo {
13896bd32326SVille Tervo 	struct hci_dev *hdev = (void *) arg;
13906bd32326SVille Tervo 
13916bd32326SVille Tervo 	BT_ERR("%s command tx timeout", hdev->name);
13926bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
1393c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
13946bd32326SVille Tervo }
13956bd32326SVille Tervo 
13962763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
13972763eda6SSzymon Janc 							bdaddr_t *bdaddr)
13982763eda6SSzymon Janc {
13992763eda6SSzymon Janc 	struct oob_data *data;
14002763eda6SSzymon Janc 
14012763eda6SSzymon Janc 	list_for_each_entry(data, &hdev->remote_oob_data, list)
14022763eda6SSzymon Janc 		if (bacmp(bdaddr, &data->bdaddr) == 0)
14032763eda6SSzymon Janc 			return data;
14042763eda6SSzymon Janc 
14052763eda6SSzymon Janc 	return NULL;
14062763eda6SSzymon Janc }
14072763eda6SSzymon Janc 
14082763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
14092763eda6SSzymon Janc {
14102763eda6SSzymon Janc 	struct oob_data *data;
14112763eda6SSzymon Janc 
14122763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
14132763eda6SSzymon Janc 	if (!data)
14142763eda6SSzymon Janc 		return -ENOENT;
14152763eda6SSzymon Janc 
14162763eda6SSzymon Janc 	BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
14172763eda6SSzymon Janc 
14182763eda6SSzymon Janc 	list_del(&data->list);
14192763eda6SSzymon Janc 	kfree(data);
14202763eda6SSzymon Janc 
14212763eda6SSzymon Janc 	return 0;
14222763eda6SSzymon Janc }
14232763eda6SSzymon Janc 
14242763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev)
14252763eda6SSzymon Janc {
14262763eda6SSzymon Janc 	struct oob_data *data, *n;
14272763eda6SSzymon Janc 
14282763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
14292763eda6SSzymon Janc 		list_del(&data->list);
14302763eda6SSzymon Janc 		kfree(data);
14312763eda6SSzymon Janc 	}
14322763eda6SSzymon Janc 
14332763eda6SSzymon Janc 	return 0;
14342763eda6SSzymon Janc }
14352763eda6SSzymon Janc 
14362763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
14372763eda6SSzymon Janc 								u8 *randomizer)
14382763eda6SSzymon Janc {
14392763eda6SSzymon Janc 	struct oob_data *data;
14402763eda6SSzymon Janc 
14412763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
14422763eda6SSzymon Janc 
14432763eda6SSzymon Janc 	if (!data) {
14442763eda6SSzymon Janc 		data = kmalloc(sizeof(*data), GFP_ATOMIC);
14452763eda6SSzymon Janc 		if (!data)
14462763eda6SSzymon Janc 			return -ENOMEM;
14472763eda6SSzymon Janc 
14482763eda6SSzymon Janc 		bacpy(&data->bdaddr, bdaddr);
14492763eda6SSzymon Janc 		list_add(&data->list, &hdev->remote_oob_data);
14502763eda6SSzymon Janc 	}
14512763eda6SSzymon Janc 
14522763eda6SSzymon Janc 	memcpy(data->hash, hash, sizeof(data->hash));
14532763eda6SSzymon Janc 	memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
14542763eda6SSzymon Janc 
14552763eda6SSzymon Janc 	BT_DBG("%s for %s", hdev->name, batostr(bdaddr));
14562763eda6SSzymon Janc 
14572763eda6SSzymon Janc 	return 0;
14582763eda6SSzymon Janc }
14592763eda6SSzymon Janc 
1460b2a66aadSAntti Julku struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev,
1461b2a66aadSAntti Julku 						bdaddr_t *bdaddr)
1462b2a66aadSAntti Julku {
1463b2a66aadSAntti Julku 	struct bdaddr_list *b;
1464b2a66aadSAntti Julku 
14658035ded4SLuiz Augusto von Dentz 	list_for_each_entry(b, &hdev->blacklist, list)
1466b2a66aadSAntti Julku 		if (bacmp(bdaddr, &b->bdaddr) == 0)
1467b2a66aadSAntti Julku 			return b;
1468b2a66aadSAntti Julku 
1469b2a66aadSAntti Julku 	return NULL;
1470b2a66aadSAntti Julku }
1471b2a66aadSAntti Julku 
1472b2a66aadSAntti Julku int hci_blacklist_clear(struct hci_dev *hdev)
1473b2a66aadSAntti Julku {
1474b2a66aadSAntti Julku 	struct list_head *p, *n;
1475b2a66aadSAntti Julku 
1476b2a66aadSAntti Julku 	list_for_each_safe(p, n, &hdev->blacklist) {
1477b2a66aadSAntti Julku 		struct bdaddr_list *b;
1478b2a66aadSAntti Julku 
1479b2a66aadSAntti Julku 		b = list_entry(p, struct bdaddr_list, list);
1480b2a66aadSAntti Julku 
1481b2a66aadSAntti Julku 		list_del(p);
1482b2a66aadSAntti Julku 		kfree(b);
1483b2a66aadSAntti Julku 	}
1484b2a66aadSAntti Julku 
1485b2a66aadSAntti Julku 	return 0;
1486b2a66aadSAntti Julku }
1487b2a66aadSAntti Julku 
148888c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
1489b2a66aadSAntti Julku {
1490b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1491b2a66aadSAntti Julku 
1492b2a66aadSAntti Julku 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
1493b2a66aadSAntti Julku 		return -EBADF;
1494b2a66aadSAntti Julku 
14955e762444SAntti Julku 	if (hci_blacklist_lookup(hdev, bdaddr))
14965e762444SAntti Julku 		return -EEXIST;
1497b2a66aadSAntti Julku 
1498b2a66aadSAntti Julku 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
14995e762444SAntti Julku 	if (!entry)
15005e762444SAntti Julku 		return -ENOMEM;
1501b2a66aadSAntti Julku 
1502b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
1503b2a66aadSAntti Julku 
1504b2a66aadSAntti Julku 	list_add(&entry->list, &hdev->blacklist);
1505b2a66aadSAntti Julku 
150688c1fe4bSJohan Hedberg 	return mgmt_device_blocked(hdev, bdaddr, type);
1507b2a66aadSAntti Julku }
1508b2a66aadSAntti Julku 
150988c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
1510b2a66aadSAntti Julku {
1511b2a66aadSAntti Julku 	struct bdaddr_list *entry;
1512b2a66aadSAntti Julku 
15131ec918ceSSzymon Janc 	if (bacmp(bdaddr, BDADDR_ANY) == 0)
15145e762444SAntti Julku 		return hci_blacklist_clear(hdev);
1515b2a66aadSAntti Julku 
1516b2a66aadSAntti Julku 	entry = hci_blacklist_lookup(hdev, bdaddr);
15171ec918ceSSzymon Janc 	if (!entry)
15185e762444SAntti Julku 		return -ENOENT;
1519b2a66aadSAntti Julku 
1520b2a66aadSAntti Julku 	list_del(&entry->list);
1521b2a66aadSAntti Julku 	kfree(entry);
1522b2a66aadSAntti Julku 
152388c1fe4bSJohan Hedberg 	return mgmt_device_unblocked(hdev, bdaddr, type);
1524b2a66aadSAntti Julku }
1525b2a66aadSAntti Julku 
1526db323f2fSGustavo F. Padovan static void hci_clear_adv_cache(struct work_struct *work)
152735815085SAndre Guedes {
1528db323f2fSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev,
1529db323f2fSGustavo F. Padovan 							adv_work.work);
153035815085SAndre Guedes 
153135815085SAndre Guedes 	hci_dev_lock(hdev);
153235815085SAndre Guedes 
153335815085SAndre Guedes 	hci_adv_entries_clear(hdev);
153435815085SAndre Guedes 
153535815085SAndre Guedes 	hci_dev_unlock(hdev);
153635815085SAndre Guedes }
153735815085SAndre Guedes 
153876c8686fSAndre Guedes int hci_adv_entries_clear(struct hci_dev *hdev)
153976c8686fSAndre Guedes {
154076c8686fSAndre Guedes 	struct adv_entry *entry, *tmp;
154176c8686fSAndre Guedes 
154276c8686fSAndre Guedes 	list_for_each_entry_safe(entry, tmp, &hdev->adv_entries, list) {
154376c8686fSAndre Guedes 		list_del(&entry->list);
154476c8686fSAndre Guedes 		kfree(entry);
154576c8686fSAndre Guedes 	}
154676c8686fSAndre Guedes 
154776c8686fSAndre Guedes 	BT_DBG("%s adv cache cleared", hdev->name);
154876c8686fSAndre Guedes 
154976c8686fSAndre Guedes 	return 0;
155076c8686fSAndre Guedes }
155176c8686fSAndre Guedes 
155276c8686fSAndre Guedes struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr)
155376c8686fSAndre Guedes {
155476c8686fSAndre Guedes 	struct adv_entry *entry;
155576c8686fSAndre Guedes 
155676c8686fSAndre Guedes 	list_for_each_entry(entry, &hdev->adv_entries, list)
155776c8686fSAndre Guedes 		if (bacmp(bdaddr, &entry->bdaddr) == 0)
155876c8686fSAndre Guedes 			return entry;
155976c8686fSAndre Guedes 
156076c8686fSAndre Guedes 	return NULL;
156176c8686fSAndre Guedes }
156276c8686fSAndre Guedes 
156376c8686fSAndre Guedes static inline int is_connectable_adv(u8 evt_type)
156476c8686fSAndre Guedes {
156576c8686fSAndre Guedes 	if (evt_type == ADV_IND || evt_type == ADV_DIRECT_IND)
156676c8686fSAndre Guedes 		return 1;
156776c8686fSAndre Guedes 
156876c8686fSAndre Guedes 	return 0;
156976c8686fSAndre Guedes }
157076c8686fSAndre Guedes 
157176c8686fSAndre Guedes int hci_add_adv_entry(struct hci_dev *hdev,
157276c8686fSAndre Guedes 					struct hci_ev_le_advertising_info *ev)
157376c8686fSAndre Guedes {
157476c8686fSAndre Guedes 	struct adv_entry *entry;
157576c8686fSAndre Guedes 
157676c8686fSAndre Guedes 	if (!is_connectable_adv(ev->evt_type))
157776c8686fSAndre Guedes 		return -EINVAL;
157876c8686fSAndre Guedes 
157976c8686fSAndre Guedes 	/* Only new entries should be added to adv_entries. So, if
158076c8686fSAndre Guedes 	 * bdaddr was found, don't add it. */
158176c8686fSAndre Guedes 	if (hci_find_adv_entry(hdev, &ev->bdaddr))
158276c8686fSAndre Guedes 		return 0;
158376c8686fSAndre Guedes 
15844777bfdeSAndre Guedes 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
158576c8686fSAndre Guedes 	if (!entry)
158676c8686fSAndre Guedes 		return -ENOMEM;
158776c8686fSAndre Guedes 
158876c8686fSAndre Guedes 	bacpy(&entry->bdaddr, &ev->bdaddr);
158976c8686fSAndre Guedes 	entry->bdaddr_type = ev->bdaddr_type;
159076c8686fSAndre Guedes 
159176c8686fSAndre Guedes 	list_add(&entry->list, &hdev->adv_entries);
159276c8686fSAndre Guedes 
159376c8686fSAndre Guedes 	BT_DBG("%s adv entry added: address %s type %u", hdev->name,
159476c8686fSAndre Guedes 				batostr(&entry->bdaddr), entry->bdaddr_type);
159576c8686fSAndre Guedes 
159676c8686fSAndre Guedes 	return 0;
159776c8686fSAndre Guedes }
159876c8686fSAndre Guedes 
15997ba8b4beSAndre Guedes static void le_scan_param_req(struct hci_dev *hdev, unsigned long opt)
16007ba8b4beSAndre Guedes {
16017ba8b4beSAndre Guedes 	struct le_scan_params *param =  (struct le_scan_params *) opt;
16027ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_param cp;
16037ba8b4beSAndre Guedes 
16047ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
16057ba8b4beSAndre Guedes 	cp.type = param->type;
16067ba8b4beSAndre Guedes 	cp.interval = cpu_to_le16(param->interval);
16077ba8b4beSAndre Guedes 	cp.window = cpu_to_le16(param->window);
16087ba8b4beSAndre Guedes 
16097ba8b4beSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp);
16107ba8b4beSAndre Guedes }
16117ba8b4beSAndre Guedes 
16127ba8b4beSAndre Guedes static void le_scan_enable_req(struct hci_dev *hdev, unsigned long opt)
16137ba8b4beSAndre Guedes {
16147ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
16157ba8b4beSAndre Guedes 
16167ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
16177ba8b4beSAndre Guedes 	cp.enable = 1;
16187ba8b4beSAndre Guedes 
16197ba8b4beSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
16207ba8b4beSAndre Guedes }
16217ba8b4beSAndre Guedes 
16227ba8b4beSAndre Guedes static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval,
16237ba8b4beSAndre Guedes 						u16 window, int timeout)
16247ba8b4beSAndre Guedes {
16257ba8b4beSAndre Guedes 	long timeo = msecs_to_jiffies(3000);
16267ba8b4beSAndre Guedes 	struct le_scan_params param;
16277ba8b4beSAndre Guedes 	int err;
16287ba8b4beSAndre Guedes 
16297ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
16307ba8b4beSAndre Guedes 
16317ba8b4beSAndre Guedes 	if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
16327ba8b4beSAndre Guedes 		return -EINPROGRESS;
16337ba8b4beSAndre Guedes 
16347ba8b4beSAndre Guedes 	param.type = type;
16357ba8b4beSAndre Guedes 	param.interval = interval;
16367ba8b4beSAndre Guedes 	param.window = window;
16377ba8b4beSAndre Guedes 
16387ba8b4beSAndre Guedes 	hci_req_lock(hdev);
16397ba8b4beSAndre Guedes 
16407ba8b4beSAndre Guedes 	err = __hci_request(hdev, le_scan_param_req, (unsigned long) &param,
16417ba8b4beSAndre Guedes 									timeo);
16427ba8b4beSAndre Guedes 	if (!err)
16437ba8b4beSAndre Guedes 		err = __hci_request(hdev, le_scan_enable_req, 0, timeo);
16447ba8b4beSAndre Guedes 
16457ba8b4beSAndre Guedes 	hci_req_unlock(hdev);
16467ba8b4beSAndre Guedes 
16477ba8b4beSAndre Guedes 	if (err < 0)
16487ba8b4beSAndre Guedes 		return err;
16497ba8b4beSAndre Guedes 
16507ba8b4beSAndre Guedes 	schedule_delayed_work(&hdev->le_scan_disable,
16517ba8b4beSAndre Guedes 						msecs_to_jiffies(timeout));
16527ba8b4beSAndre Guedes 
16537ba8b4beSAndre Guedes 	return 0;
16547ba8b4beSAndre Guedes }
16557ba8b4beSAndre Guedes 
16567ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work)
16577ba8b4beSAndre Guedes {
16587ba8b4beSAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev,
16597ba8b4beSAndre Guedes 						le_scan_disable.work);
16607ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
16617ba8b4beSAndre Guedes 
16627ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
16637ba8b4beSAndre Guedes 
16647ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
16657ba8b4beSAndre Guedes 
16667ba8b4beSAndre Guedes 	hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
16677ba8b4beSAndre Guedes }
16687ba8b4beSAndre Guedes 
166928b75a89SAndre Guedes static void le_scan_work(struct work_struct *work)
167028b75a89SAndre Guedes {
167128b75a89SAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev, le_scan);
167228b75a89SAndre Guedes 	struct le_scan_params *param = &hdev->le_scan_params;
167328b75a89SAndre Guedes 
167428b75a89SAndre Guedes 	BT_DBG("%s", hdev->name);
167528b75a89SAndre Guedes 
167628b75a89SAndre Guedes 	hci_do_le_scan(hdev, param->type, param->interval,
167728b75a89SAndre Guedes 					param->window, param->timeout);
167828b75a89SAndre Guedes }
167928b75a89SAndre Guedes 
168028b75a89SAndre Guedes int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window,
168128b75a89SAndre Guedes 								int timeout)
168228b75a89SAndre Guedes {
168328b75a89SAndre Guedes 	struct le_scan_params *param = &hdev->le_scan_params;
168428b75a89SAndre Guedes 
168528b75a89SAndre Guedes 	BT_DBG("%s", hdev->name);
168628b75a89SAndre Guedes 
168728b75a89SAndre Guedes 	if (work_busy(&hdev->le_scan))
168828b75a89SAndre Guedes 		return -EINPROGRESS;
168928b75a89SAndre Guedes 
169028b75a89SAndre Guedes 	param->type = type;
169128b75a89SAndre Guedes 	param->interval = interval;
169228b75a89SAndre Guedes 	param->window = window;
169328b75a89SAndre Guedes 	param->timeout = timeout;
169428b75a89SAndre Guedes 
169528b75a89SAndre Guedes 	queue_work(system_long_wq, &hdev->le_scan);
169628b75a89SAndre Guedes 
169728b75a89SAndre Guedes 	return 0;
169828b75a89SAndre Guedes }
169928b75a89SAndre Guedes 
17001da177e4SLinus Torvalds /* Register HCI device */
17011da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
17021da177e4SLinus Torvalds {
17031da177e4SLinus Torvalds 	struct list_head *head = &hci_dev_list, *p;
170408add513SMat Martineau 	int i, id, error;
17051da177e4SLinus Torvalds 
1706e9b9cfa1SDavid Herrmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
17071da177e4SLinus Torvalds 
1708010666a1SDavid Herrmann 	if (!hdev->open || !hdev->close)
17091da177e4SLinus Torvalds 		return -EINVAL;
17101da177e4SLinus Torvalds 
171108add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
171208add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
171308add513SMat Martineau 	 */
171408add513SMat Martineau 	id = (hdev->dev_type == HCI_BREDR) ? 0 : 1;
171508add513SMat Martineau 
1716f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
17171da177e4SLinus Torvalds 
17181da177e4SLinus Torvalds 	/* Find first available device id */
17191da177e4SLinus Torvalds 	list_for_each(p, &hci_dev_list) {
17201da177e4SLinus Torvalds 		if (list_entry(p, struct hci_dev, list)->id != id)
17211da177e4SLinus Torvalds 			break;
17221da177e4SLinus Torvalds 		head = p; id++;
17231da177e4SLinus Torvalds 	}
17241da177e4SLinus Torvalds 
17251da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
17261da177e4SLinus Torvalds 	hdev->id = id;
1727c6feeb28SAndrei Emeltchenko 	list_add_tail(&hdev->list, head);
17281da177e4SLinus Torvalds 
172909fd0de5SGustavo F. Padovan 	mutex_init(&hdev->lock);
17301da177e4SLinus Torvalds 
17311da177e4SLinus Torvalds 	hdev->flags = 0;
1732d23264a8SAndre Guedes 	hdev->dev_flags = 0;
17331da177e4SLinus Torvalds 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
17345b7f9909SMarcel Holtmann 	hdev->esco_type = (ESCO_HV1);
17351da177e4SLinus Torvalds 	hdev->link_mode = (HCI_LM_ACCEPT);
173617fa4b9dSJohan Hedberg 	hdev->io_capability = 0x03; /* No Input No Output */
17371da177e4SLinus Torvalds 
173804837f64SMarcel Holtmann 	hdev->idle_timeout = 0;
173904837f64SMarcel Holtmann 	hdev->sniff_max_interval = 800;
174004837f64SMarcel Holtmann 	hdev->sniff_min_interval = 80;
174104837f64SMarcel Holtmann 
1742b78752ccSMarcel Holtmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
1743c347b765SGustavo F. Padovan 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
17443eff45eaSGustavo F. Padovan 	INIT_WORK(&hdev->tx_work, hci_tx_work);
1745b78752ccSMarcel Holtmann 
17461da177e4SLinus Torvalds 
17471da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->rx_q);
17481da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->cmd_q);
17491da177e4SLinus Torvalds 	skb_queue_head_init(&hdev->raw_q);
17501da177e4SLinus Torvalds 
17516bd32326SVille Tervo 	setup_timer(&hdev->cmd_timer, hci_cmd_timer, (unsigned long) hdev);
17526bd32326SVille Tervo 
1753cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
1754ef222013SMarcel Holtmann 		hdev->reassembly[i] = NULL;
1755ef222013SMarcel Holtmann 
17561da177e4SLinus Torvalds 	init_waitqueue_head(&hdev->req_wait_q);
1757a6a67efdSThomas Gleixner 	mutex_init(&hdev->req_lock);
17581da177e4SLinus Torvalds 
175930883512SJohan Hedberg 	discovery_init(hdev);
17601da177e4SLinus Torvalds 
17611da177e4SLinus Torvalds 	hci_conn_hash_init(hdev);
17621da177e4SLinus Torvalds 
17632e58ef3eSJohan Hedberg 	INIT_LIST_HEAD(&hdev->mgmt_pending);
17642e58ef3eSJohan Hedberg 
1765ea4bd8baSDavid Miller 	INIT_LIST_HEAD(&hdev->blacklist);
1766f0358568SJohan Hedberg 
17672aeb9a1aSJohan Hedberg 	INIT_LIST_HEAD(&hdev->uuids);
17682aeb9a1aSJohan Hedberg 
176955ed8ca1SJohan Hedberg 	INIT_LIST_HEAD(&hdev->link_keys);
1770b899efafSVinicius Costa Gomes 	INIT_LIST_HEAD(&hdev->long_term_keys);
177155ed8ca1SJohan Hedberg 
17722763eda6SSzymon Janc 	INIT_LIST_HEAD(&hdev->remote_oob_data);
17732763eda6SSzymon Janc 
177476c8686fSAndre Guedes 	INIT_LIST_HEAD(&hdev->adv_entries);
177576c8686fSAndre Guedes 
1776db323f2fSGustavo F. Padovan 	INIT_DELAYED_WORK(&hdev->adv_work, hci_clear_adv_cache);
1777ab81cbf9SJohan Hedberg 	INIT_WORK(&hdev->power_on, hci_power_on);
17783243553fSJohan Hedberg 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
1779ab81cbf9SJohan Hedberg 
178016ab91abSJohan Hedberg 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
178116ab91abSJohan Hedberg 
17821da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
17831da177e4SLinus Torvalds 
17841da177e4SLinus Torvalds 	atomic_set(&hdev->promisc, 0);
17851da177e4SLinus Torvalds 
178628b75a89SAndre Guedes 	INIT_WORK(&hdev->le_scan, le_scan_work);
178728b75a89SAndre Guedes 
17887ba8b4beSAndre Guedes 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
17897ba8b4beSAndre Guedes 
1790f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
17911da177e4SLinus Torvalds 
179232845eb1SGustavo F. Padovan 	hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND |
179332845eb1SGustavo F. Padovan 							WQ_MEM_RECLAIM, 1);
179433ca954dSDavid Herrmann 	if (!hdev->workqueue) {
179533ca954dSDavid Herrmann 		error = -ENOMEM;
179633ca954dSDavid Herrmann 		goto err;
179733ca954dSDavid Herrmann 	}
1798f48fd9c8SMarcel Holtmann 
179933ca954dSDavid Herrmann 	error = hci_add_sysfs(hdev);
180033ca954dSDavid Herrmann 	if (error < 0)
180133ca954dSDavid Herrmann 		goto err_wqueue;
18021da177e4SLinus Torvalds 
1803611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
1804611b30f7SMarcel Holtmann 				RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, hdev);
1805611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
1806611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
1807611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
1808611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
1809611b30f7SMarcel Holtmann 		}
1810611b30f7SMarcel Holtmann 	}
1811611b30f7SMarcel Holtmann 
1812a8b2d5c2SJohan Hedberg 	set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
1813a8b2d5c2SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->dev_flags);
18147f971041SGustavo F. Padovan 	schedule_work(&hdev->power_on);
1815ab81cbf9SJohan Hedberg 
18161da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
1817dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
18181da177e4SLinus Torvalds 
18191da177e4SLinus Torvalds 	return id;
1820f48fd9c8SMarcel Holtmann 
182133ca954dSDavid Herrmann err_wqueue:
182233ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
182333ca954dSDavid Herrmann err:
1824f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
1825f48fd9c8SMarcel Holtmann 	list_del(&hdev->list);
1826f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
1827f48fd9c8SMarcel Holtmann 
182833ca954dSDavid Herrmann 	return error;
18291da177e4SLinus Torvalds }
18301da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
18311da177e4SLinus Torvalds 
18321da177e4SLinus Torvalds /* Unregister HCI device */
183359735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
18341da177e4SLinus Torvalds {
1835ef222013SMarcel Holtmann 	int i;
1836ef222013SMarcel Holtmann 
1837c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
18381da177e4SLinus Torvalds 
1839f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
18401da177e4SLinus Torvalds 	list_del(&hdev->list);
1841f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
18421da177e4SLinus Torvalds 
18431da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
18441da177e4SLinus Torvalds 
1845cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
1846ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
1847ef222013SMarcel Holtmann 
1848ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
1849a8b2d5c2SJohan Hedberg 				!test_bit(HCI_SETUP, &hdev->dev_flags)) {
185009fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
1851744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
185209fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
185356e5cb86SJohan Hedberg 	}
1854ab81cbf9SJohan Hedberg 
18552e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
18562e58ef3eSJohan Hedberg 	 * pending list */
18572e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
18582e58ef3eSJohan Hedberg 
18591da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
18601da177e4SLinus Torvalds 
1861611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
1862611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
1863611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
1864611b30f7SMarcel Holtmann 	}
1865611b30f7SMarcel Holtmann 
1866ce242970SDavid Herrmann 	hci_del_sysfs(hdev);
1867147e2d59SDave Young 
1868db323f2fSGustavo F. Padovan 	cancel_delayed_work_sync(&hdev->adv_work);
1869c6f3c5f7SGustavo F. Padovan 
1870f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
1871f48fd9c8SMarcel Holtmann 
187209fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
1873e2e0cacbSJohan Hedberg 	hci_blacklist_clear(hdev);
18742aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
187555ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
1876b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
18772763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
187876c8686fSAndre Guedes 	hci_adv_entries_clear(hdev);
187909fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
1880e2e0cacbSJohan Hedberg 
1881dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
18821da177e4SLinus Torvalds }
18831da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
18841da177e4SLinus Torvalds 
18851da177e4SLinus Torvalds /* Suspend HCI device */
18861da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
18871da177e4SLinus Torvalds {
18881da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
18891da177e4SLinus Torvalds 	return 0;
18901da177e4SLinus Torvalds }
18911da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
18921da177e4SLinus Torvalds 
18931da177e4SLinus Torvalds /* Resume HCI device */
18941da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
18951da177e4SLinus Torvalds {
18961da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
18971da177e4SLinus Torvalds 	return 0;
18981da177e4SLinus Torvalds }
18991da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
19001da177e4SLinus Torvalds 
190176bca880SMarcel Holtmann /* Receive frame from HCI drivers */
190276bca880SMarcel Holtmann int hci_recv_frame(struct sk_buff *skb)
190376bca880SMarcel Holtmann {
190476bca880SMarcel Holtmann 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
190576bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
190676bca880SMarcel Holtmann 				&& !test_bit(HCI_INIT, &hdev->flags))) {
190776bca880SMarcel Holtmann 		kfree_skb(skb);
190876bca880SMarcel Holtmann 		return -ENXIO;
190976bca880SMarcel Holtmann 	}
191076bca880SMarcel Holtmann 
191176bca880SMarcel Holtmann 	/* Incomming skb */
191276bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
191376bca880SMarcel Holtmann 
191476bca880SMarcel Holtmann 	/* Time stamp */
191576bca880SMarcel Holtmann 	__net_timestamp(skb);
191676bca880SMarcel Holtmann 
191776bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
1918b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
1919c78ae283SMarcel Holtmann 
192076bca880SMarcel Holtmann 	return 0;
192176bca880SMarcel Holtmann }
192276bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
192376bca880SMarcel Holtmann 
192433e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
19251e429f38SGustavo F. Padovan 						  int count, __u8 index)
192633e882a5SSuraj Sumangala {
192733e882a5SSuraj Sumangala 	int len = 0;
192833e882a5SSuraj Sumangala 	int hlen = 0;
192933e882a5SSuraj Sumangala 	int remain = count;
193033e882a5SSuraj Sumangala 	struct sk_buff *skb;
193133e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
193233e882a5SSuraj Sumangala 
193333e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
193433e882a5SSuraj Sumangala 				index >= NUM_REASSEMBLY)
193533e882a5SSuraj Sumangala 		return -EILSEQ;
193633e882a5SSuraj Sumangala 
193733e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
193833e882a5SSuraj Sumangala 
193933e882a5SSuraj Sumangala 	if (!skb) {
194033e882a5SSuraj Sumangala 		switch (type) {
194133e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
194233e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
194333e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
194433e882a5SSuraj Sumangala 			break;
194533e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
194633e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
194733e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
194833e882a5SSuraj Sumangala 			break;
194933e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
195033e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
195133e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
195233e882a5SSuraj Sumangala 			break;
195333e882a5SSuraj Sumangala 		}
195433e882a5SSuraj Sumangala 
19551e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
195633e882a5SSuraj Sumangala 		if (!skb)
195733e882a5SSuraj Sumangala 			return -ENOMEM;
195833e882a5SSuraj Sumangala 
195933e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
196033e882a5SSuraj Sumangala 		scb->expect = hlen;
196133e882a5SSuraj Sumangala 		scb->pkt_type = type;
196233e882a5SSuraj Sumangala 
196333e882a5SSuraj Sumangala 		skb->dev = (void *) hdev;
196433e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
196533e882a5SSuraj Sumangala 	}
196633e882a5SSuraj Sumangala 
196733e882a5SSuraj Sumangala 	while (count) {
196833e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
196970c1f20bSMarcel Holtmann 		len = min_t(__u16, scb->expect, count);
197033e882a5SSuraj Sumangala 
197133e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
197233e882a5SSuraj Sumangala 
197333e882a5SSuraj Sumangala 		count -= len;
197433e882a5SSuraj Sumangala 		data += len;
197533e882a5SSuraj Sumangala 		scb->expect -= len;
197633e882a5SSuraj Sumangala 		remain = count;
197733e882a5SSuraj Sumangala 
197833e882a5SSuraj Sumangala 		switch (type) {
197933e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
198033e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
198133e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
198233e882a5SSuraj Sumangala 				scb->expect = h->plen;
198333e882a5SSuraj Sumangala 
198433e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
198533e882a5SSuraj Sumangala 					kfree_skb(skb);
198633e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
198733e882a5SSuraj Sumangala 					return -ENOMEM;
198833e882a5SSuraj Sumangala 				}
198933e882a5SSuraj Sumangala 			}
199033e882a5SSuraj Sumangala 			break;
199133e882a5SSuraj Sumangala 
199233e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
199333e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
199433e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
199533e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
199633e882a5SSuraj Sumangala 
199733e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
199833e882a5SSuraj Sumangala 					kfree_skb(skb);
199933e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
200033e882a5SSuraj Sumangala 					return -ENOMEM;
200133e882a5SSuraj Sumangala 				}
200233e882a5SSuraj Sumangala 			}
200333e882a5SSuraj Sumangala 			break;
200433e882a5SSuraj Sumangala 
200533e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
200633e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
200733e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
200833e882a5SSuraj Sumangala 				scb->expect = h->dlen;
200933e882a5SSuraj Sumangala 
201033e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
201133e882a5SSuraj Sumangala 					kfree_skb(skb);
201233e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
201333e882a5SSuraj Sumangala 					return -ENOMEM;
201433e882a5SSuraj Sumangala 				}
201533e882a5SSuraj Sumangala 			}
201633e882a5SSuraj Sumangala 			break;
201733e882a5SSuraj Sumangala 		}
201833e882a5SSuraj Sumangala 
201933e882a5SSuraj Sumangala 		if (scb->expect == 0) {
202033e882a5SSuraj Sumangala 			/* Complete frame */
202133e882a5SSuraj Sumangala 
202233e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
202333e882a5SSuraj Sumangala 			hci_recv_frame(skb);
202433e882a5SSuraj Sumangala 
202533e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
202633e882a5SSuraj Sumangala 			return remain;
202733e882a5SSuraj Sumangala 		}
202833e882a5SSuraj Sumangala 	}
202933e882a5SSuraj Sumangala 
203033e882a5SSuraj Sumangala 	return remain;
203133e882a5SSuraj Sumangala }
203233e882a5SSuraj Sumangala 
2033ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
2034ef222013SMarcel Holtmann {
2035f39a3c06SSuraj Sumangala 	int rem = 0;
2036f39a3c06SSuraj Sumangala 
2037ef222013SMarcel Holtmann 	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
2038ef222013SMarcel Holtmann 		return -EILSEQ;
2039ef222013SMarcel Holtmann 
2040da5f6c37SGustavo F. Padovan 	while (count) {
20411e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count, type - 1);
2042f39a3c06SSuraj Sumangala 		if (rem < 0)
2043f39a3c06SSuraj Sumangala 			return rem;
2044ef222013SMarcel Holtmann 
2045f39a3c06SSuraj Sumangala 		data += (count - rem);
2046f39a3c06SSuraj Sumangala 		count = rem;
2047f81c6224SJoe Perches 	}
2048ef222013SMarcel Holtmann 
2049f39a3c06SSuraj Sumangala 	return rem;
2050ef222013SMarcel Holtmann }
2051ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment);
2052ef222013SMarcel Holtmann 
205399811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
205499811510SSuraj Sumangala 
205599811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
205699811510SSuraj Sumangala {
205799811510SSuraj Sumangala 	int type;
205899811510SSuraj Sumangala 	int rem = 0;
205999811510SSuraj Sumangala 
2060da5f6c37SGustavo F. Padovan 	while (count) {
206199811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
206299811510SSuraj Sumangala 
206399811510SSuraj Sumangala 		if (!skb) {
206499811510SSuraj Sumangala 			struct { char type; } *pkt;
206599811510SSuraj Sumangala 
206699811510SSuraj Sumangala 			/* Start of the frame */
206799811510SSuraj Sumangala 			pkt = data;
206899811510SSuraj Sumangala 			type = pkt->type;
206999811510SSuraj Sumangala 
207099811510SSuraj Sumangala 			data++;
207199811510SSuraj Sumangala 			count--;
207299811510SSuraj Sumangala 		} else
207399811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
207499811510SSuraj Sumangala 
20751e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
20761e429f38SGustavo F. Padovan 							STREAM_REASSEMBLY);
207799811510SSuraj Sumangala 		if (rem < 0)
207899811510SSuraj Sumangala 			return rem;
207999811510SSuraj Sumangala 
208099811510SSuraj Sumangala 		data += (count - rem);
208199811510SSuraj Sumangala 		count = rem;
2082f81c6224SJoe Perches 	}
208399811510SSuraj Sumangala 
208499811510SSuraj Sumangala 	return rem;
208599811510SSuraj Sumangala }
208699811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
208799811510SSuraj Sumangala 
20881da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
20891da177e4SLinus Torvalds 
20901da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
20911da177e4SLinus Torvalds {
20921da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
20931da177e4SLinus Torvalds 
2094f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
20951da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
2096f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
20971da177e4SLinus Torvalds 
20981da177e4SLinus Torvalds 	return 0;
20991da177e4SLinus Torvalds }
21001da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
21011da177e4SLinus Torvalds 
21021da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
21031da177e4SLinus Torvalds {
21041da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
21051da177e4SLinus Torvalds 
2106f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
21071da177e4SLinus Torvalds 	list_del(&cb->list);
2108f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
21091da177e4SLinus Torvalds 
21101da177e4SLinus Torvalds 	return 0;
21111da177e4SLinus Torvalds }
21121da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
21131da177e4SLinus Torvalds 
21141da177e4SLinus Torvalds static int hci_send_frame(struct sk_buff *skb)
21151da177e4SLinus Torvalds {
21161da177e4SLinus Torvalds 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
21171da177e4SLinus Torvalds 
21181da177e4SLinus Torvalds 	if (!hdev) {
21191da177e4SLinus Torvalds 		kfree_skb(skb);
21201da177e4SLinus Torvalds 		return -ENODEV;
21211da177e4SLinus Torvalds 	}
21221da177e4SLinus Torvalds 
21230d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
21241da177e4SLinus Torvalds 
21251da177e4SLinus Torvalds 	/* Time stamp */
2126a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
21271da177e4SLinus Torvalds 
2128cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
2129cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
2130cd82e61cSMarcel Holtmann 
2131cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
2132cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
2133470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
21341da177e4SLinus Torvalds 	}
21351da177e4SLinus Torvalds 
21361da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
21371da177e4SLinus Torvalds 	skb_orphan(skb);
21381da177e4SLinus Torvalds 
21391da177e4SLinus Torvalds 	return hdev->send(skb);
21401da177e4SLinus Torvalds }
21411da177e4SLinus Torvalds 
21421da177e4SLinus Torvalds /* Send HCI command */
2143a9de9248SMarcel Holtmann int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)
21441da177e4SLinus Torvalds {
21451da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
21461da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
21471da177e4SLinus Torvalds 	struct sk_buff *skb;
21481da177e4SLinus Torvalds 
2149a9de9248SMarcel Holtmann 	BT_DBG("%s opcode 0x%x plen %d", hdev->name, opcode, plen);
21501da177e4SLinus Torvalds 
21511da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
21521da177e4SLinus Torvalds 	if (!skb) {
2153ef222013SMarcel Holtmann 		BT_ERR("%s no memory for command", hdev->name);
21541da177e4SLinus Torvalds 		return -ENOMEM;
21551da177e4SLinus Torvalds 	}
21561da177e4SLinus Torvalds 
21571da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
2158a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
21591da177e4SLinus Torvalds 	hdr->plen   = plen;
21601da177e4SLinus Torvalds 
21611da177e4SLinus Torvalds 	if (plen)
21621da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
21631da177e4SLinus Torvalds 
21641da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
21651da177e4SLinus Torvalds 
21660d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
21671da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
2168c78ae283SMarcel Holtmann 
2169a5040efaSJohan Hedberg 	if (test_bit(HCI_INIT, &hdev->flags))
2170a5040efaSJohan Hedberg 		hdev->init_last_cmd = opcode;
2171a5040efaSJohan Hedberg 
21721da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
2173c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
21741da177e4SLinus Torvalds 
21751da177e4SLinus Torvalds 	return 0;
21761da177e4SLinus Torvalds }
21771da177e4SLinus Torvalds 
21781da177e4SLinus Torvalds /* Get data from the previously sent command */
2179a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
21801da177e4SLinus Torvalds {
21811da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
21821da177e4SLinus Torvalds 
21831da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
21841da177e4SLinus Torvalds 		return NULL;
21851da177e4SLinus Torvalds 
21861da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
21871da177e4SLinus Torvalds 
2188a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
21891da177e4SLinus Torvalds 		return NULL;
21901da177e4SLinus Torvalds 
2191a9de9248SMarcel Holtmann 	BT_DBG("%s opcode 0x%x", hdev->name, opcode);
21921da177e4SLinus Torvalds 
21931da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
21941da177e4SLinus Torvalds }
21951da177e4SLinus Torvalds 
21961da177e4SLinus Torvalds /* Send ACL data */
21971da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
21981da177e4SLinus Torvalds {
21991da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
22001da177e4SLinus Torvalds 	int len = skb->len;
22011da177e4SLinus Torvalds 
2202badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
2203badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
22049c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
2205aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
2206aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
22071da177e4SLinus Torvalds }
22081da177e4SLinus Torvalds 
220973d80debSLuiz Augusto von Dentz static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue,
221073d80debSLuiz Augusto von Dentz 				struct sk_buff *skb, __u16 flags)
22111da177e4SLinus Torvalds {
22121da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
22131da177e4SLinus Torvalds 	struct sk_buff *list;
22141da177e4SLinus Torvalds 
221570f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
221670f23020SAndrei Emeltchenko 	if (!list) {
22171da177e4SLinus Torvalds 		/* Non fragmented */
22181da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
22191da177e4SLinus Torvalds 
222073d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
22211da177e4SLinus Torvalds 	} else {
22221da177e4SLinus Torvalds 		/* Fragmented */
22231da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
22241da177e4SLinus Torvalds 
22251da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
22261da177e4SLinus Torvalds 
22271da177e4SLinus Torvalds 		/* Queue all fragments atomically */
2228af3e6359SGustavo F. Padovan 		spin_lock(&queue->lock);
22291da177e4SLinus Torvalds 
223073d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
2231e702112fSAndrei Emeltchenko 
2232e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
2233e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
22341da177e4SLinus Torvalds 		do {
22351da177e4SLinus Torvalds 			skb = list; list = list->next;
22361da177e4SLinus Torvalds 
22371da177e4SLinus Torvalds 			skb->dev = (void *) hdev;
22380d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
2239e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
22401da177e4SLinus Torvalds 
22411da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
22421da177e4SLinus Torvalds 
224373d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
22441da177e4SLinus Torvalds 		} while (list);
22451da177e4SLinus Torvalds 
2246af3e6359SGustavo F. Padovan 		spin_unlock(&queue->lock);
22471da177e4SLinus Torvalds 	}
224873d80debSLuiz Augusto von Dentz }
224973d80debSLuiz Augusto von Dentz 
225073d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
225173d80debSLuiz Augusto von Dentz {
225273d80debSLuiz Augusto von Dentz 	struct hci_conn *conn = chan->conn;
225373d80debSLuiz Augusto von Dentz 	struct hci_dev *hdev = conn->hdev;
225473d80debSLuiz Augusto von Dentz 
225573d80debSLuiz Augusto von Dentz 	BT_DBG("%s chan %p flags 0x%x", hdev->name, chan, flags);
225673d80debSLuiz Augusto von Dentz 
225773d80debSLuiz Augusto von Dentz 	skb->dev = (void *) hdev;
225873d80debSLuiz Augusto von Dentz 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
225973d80debSLuiz Augusto von Dentz 	hci_add_acl_hdr(skb, conn->handle, flags);
226073d80debSLuiz Augusto von Dentz 
226173d80debSLuiz Augusto von Dentz 	hci_queue_acl(conn, &chan->data_q, skb, flags);
22621da177e4SLinus Torvalds 
22633eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
22641da177e4SLinus Torvalds }
22651da177e4SLinus Torvalds EXPORT_SYMBOL(hci_send_acl);
22661da177e4SLinus Torvalds 
22671da177e4SLinus Torvalds /* Send SCO data */
22680d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
22691da177e4SLinus Torvalds {
22701da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
22711da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
22721da177e4SLinus Torvalds 
22731da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
22741da177e4SLinus Torvalds 
2275aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
22761da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
22771da177e4SLinus Torvalds 
2278badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
2279badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
22809c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
22811da177e4SLinus Torvalds 
22821da177e4SLinus Torvalds 	skb->dev = (void *) hdev;
22830d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
2284c78ae283SMarcel Holtmann 
22851da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
22863eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
22871da177e4SLinus Torvalds }
22881da177e4SLinus Torvalds EXPORT_SYMBOL(hci_send_sco);
22891da177e4SLinus Torvalds 
22901da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
22911da177e4SLinus Torvalds 
22921da177e4SLinus Torvalds /* HCI Connection scheduler */
22931da177e4SLinus Torvalds static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote)
22941da177e4SLinus Torvalds {
22951da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
22968035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
22971da177e4SLinus Torvalds 	int num = 0, min = ~0;
22981da177e4SLinus Torvalds 
22991da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
23001da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
2301bf4c6325SGustavo F. Padovan 
2302bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2303bf4c6325SGustavo F. Padovan 
2304bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2305769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
23061da177e4SLinus Torvalds 			continue;
2307769be974SMarcel Holtmann 
2308769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
2309769be974SMarcel Holtmann 			continue;
2310769be974SMarcel Holtmann 
23111da177e4SLinus Torvalds 		num++;
23121da177e4SLinus Torvalds 
23131da177e4SLinus Torvalds 		if (c->sent < min) {
23141da177e4SLinus Torvalds 			min  = c->sent;
23151da177e4SLinus Torvalds 			conn = c;
23161da177e4SLinus Torvalds 		}
231752087a79SLuiz Augusto von Dentz 
231852087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
231952087a79SLuiz Augusto von Dentz 			break;
23201da177e4SLinus Torvalds 	}
23211da177e4SLinus Torvalds 
2322bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2323bf4c6325SGustavo F. Padovan 
23241da177e4SLinus Torvalds 	if (conn) {
23256ed58ec5SVille Tervo 		int cnt, q;
23266ed58ec5SVille Tervo 
23276ed58ec5SVille Tervo 		switch (conn->type) {
23286ed58ec5SVille Tervo 		case ACL_LINK:
23296ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
23306ed58ec5SVille Tervo 			break;
23316ed58ec5SVille Tervo 		case SCO_LINK:
23326ed58ec5SVille Tervo 		case ESCO_LINK:
23336ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
23346ed58ec5SVille Tervo 			break;
23356ed58ec5SVille Tervo 		case LE_LINK:
23366ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
23376ed58ec5SVille Tervo 			break;
23386ed58ec5SVille Tervo 		default:
23396ed58ec5SVille Tervo 			cnt = 0;
23406ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
23416ed58ec5SVille Tervo 		}
23426ed58ec5SVille Tervo 
23436ed58ec5SVille Tervo 		q = cnt / num;
23441da177e4SLinus Torvalds 		*quote = q ? q : 1;
23451da177e4SLinus Torvalds 	} else
23461da177e4SLinus Torvalds 		*quote = 0;
23471da177e4SLinus Torvalds 
23481da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
23491da177e4SLinus Torvalds 	return conn;
23501da177e4SLinus Torvalds }
23511da177e4SLinus Torvalds 
2352bae1f5d9SVille Tervo static inline void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
23531da177e4SLinus Torvalds {
23541da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
23551da177e4SLinus Torvalds 	struct hci_conn *c;
23561da177e4SLinus Torvalds 
2357bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
23581da177e4SLinus Torvalds 
2359bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2360bf4c6325SGustavo F. Padovan 
23611da177e4SLinus Torvalds 	/* Kill stalled connections */
2362bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
2363bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
2364bae1f5d9SVille Tervo 			BT_ERR("%s killing stalled connection %s",
23651da177e4SLinus Torvalds 				hdev->name, batostr(&c->dst));
23661da177e4SLinus Torvalds 			hci_acl_disconn(c, 0x13);
23671da177e4SLinus Torvalds 		}
23681da177e4SLinus Torvalds 	}
2369bf4c6325SGustavo F. Padovan 
2370bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
23711da177e4SLinus Torvalds }
23721da177e4SLinus Torvalds 
237373d80debSLuiz Augusto von Dentz static inline struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
237473d80debSLuiz Augusto von Dentz 						int *quote)
237573d80debSLuiz Augusto von Dentz {
237673d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
237773d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
237873d80debSLuiz Augusto von Dentz 	int num = 0, min = ~0, cur_prio = 0;
237973d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
238073d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
238173d80debSLuiz Augusto von Dentz 
238273d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
238373d80debSLuiz Augusto von Dentz 
2384bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2385bf4c6325SGustavo F. Padovan 
2386bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
238773d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
238873d80debSLuiz Augusto von Dentz 
238973d80debSLuiz Augusto von Dentz 		if (conn->type != type)
239073d80debSLuiz Augusto von Dentz 			continue;
239173d80debSLuiz Augusto von Dentz 
239273d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
239373d80debSLuiz Augusto von Dentz 			continue;
239473d80debSLuiz Augusto von Dentz 
239573d80debSLuiz Augusto von Dentz 		conn_num++;
239673d80debSLuiz Augusto von Dentz 
23978192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
239873d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
239973d80debSLuiz Augusto von Dentz 
240073d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
240173d80debSLuiz Augusto von Dentz 				continue;
240273d80debSLuiz Augusto von Dentz 
240373d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
240473d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
240573d80debSLuiz Augusto von Dentz 				continue;
240673d80debSLuiz Augusto von Dentz 
240773d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
240873d80debSLuiz Augusto von Dentz 				num = 0;
240973d80debSLuiz Augusto von Dentz 				min = ~0;
241073d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
241173d80debSLuiz Augusto von Dentz 			}
241273d80debSLuiz Augusto von Dentz 
241373d80debSLuiz Augusto von Dentz 			num++;
241473d80debSLuiz Augusto von Dentz 
241573d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
241673d80debSLuiz Augusto von Dentz 				min  = conn->sent;
241773d80debSLuiz Augusto von Dentz 				chan = tmp;
241873d80debSLuiz Augusto von Dentz 			}
241973d80debSLuiz Augusto von Dentz 		}
242073d80debSLuiz Augusto von Dentz 
242173d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
242273d80debSLuiz Augusto von Dentz 			break;
242373d80debSLuiz Augusto von Dentz 	}
242473d80debSLuiz Augusto von Dentz 
2425bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2426bf4c6325SGustavo F. Padovan 
242773d80debSLuiz Augusto von Dentz 	if (!chan)
242873d80debSLuiz Augusto von Dentz 		return NULL;
242973d80debSLuiz Augusto von Dentz 
243073d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
243173d80debSLuiz Augusto von Dentz 	case ACL_LINK:
243273d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
243373d80debSLuiz Augusto von Dentz 		break;
243473d80debSLuiz Augusto von Dentz 	case SCO_LINK:
243573d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
243673d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
243773d80debSLuiz Augusto von Dentz 		break;
243873d80debSLuiz Augusto von Dentz 	case LE_LINK:
243973d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
244073d80debSLuiz Augusto von Dentz 		break;
244173d80debSLuiz Augusto von Dentz 	default:
244273d80debSLuiz Augusto von Dentz 		cnt = 0;
244373d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
244473d80debSLuiz Augusto von Dentz 	}
244573d80debSLuiz Augusto von Dentz 
244673d80debSLuiz Augusto von Dentz 	q = cnt / num;
244773d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
244873d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
244973d80debSLuiz Augusto von Dentz 	return chan;
245073d80debSLuiz Augusto von Dentz }
245173d80debSLuiz Augusto von Dentz 
245202b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
245302b20f0bSLuiz Augusto von Dentz {
245402b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
245502b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
245602b20f0bSLuiz Augusto von Dentz 	int num = 0;
245702b20f0bSLuiz Augusto von Dentz 
245802b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
245902b20f0bSLuiz Augusto von Dentz 
2460bf4c6325SGustavo F. Padovan 	rcu_read_lock();
2461bf4c6325SGustavo F. Padovan 
2462bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
246302b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
246402b20f0bSLuiz Augusto von Dentz 
246502b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
246602b20f0bSLuiz Augusto von Dentz 			continue;
246702b20f0bSLuiz Augusto von Dentz 
246802b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
246902b20f0bSLuiz Augusto von Dentz 			continue;
247002b20f0bSLuiz Augusto von Dentz 
247102b20f0bSLuiz Augusto von Dentz 		num++;
247202b20f0bSLuiz Augusto von Dentz 
24738192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
247402b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
247502b20f0bSLuiz Augusto von Dentz 
247602b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
247702b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
247802b20f0bSLuiz Augusto von Dentz 				continue;
247902b20f0bSLuiz Augusto von Dentz 			}
248002b20f0bSLuiz Augusto von Dentz 
248102b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
248202b20f0bSLuiz Augusto von Dentz 				continue;
248302b20f0bSLuiz Augusto von Dentz 
248402b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
248502b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
248602b20f0bSLuiz Augusto von Dentz 				continue;
248702b20f0bSLuiz Augusto von Dentz 
248802b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
248902b20f0bSLuiz Augusto von Dentz 
249002b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
249102b20f0bSLuiz Augusto von Dentz 								skb->priority);
249202b20f0bSLuiz Augusto von Dentz 		}
249302b20f0bSLuiz Augusto von Dentz 
249402b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
249502b20f0bSLuiz Augusto von Dentz 			break;
249602b20f0bSLuiz Augusto von Dentz 	}
2497bf4c6325SGustavo F. Padovan 
2498bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
2499bf4c6325SGustavo F. Padovan 
250002b20f0bSLuiz Augusto von Dentz }
250102b20f0bSLuiz Augusto von Dentz 
2502b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
2503b71d385aSAndrei Emeltchenko {
2504b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
2505b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
2506b71d385aSAndrei Emeltchenko }
2507b71d385aSAndrei Emeltchenko 
250863d2bc1bSAndrei Emeltchenko static inline void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
25091da177e4SLinus Torvalds {
25101da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
25111da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
25121da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
251363d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
2514cc48dc0aSAndrei Emeltchenko 					msecs_to_jiffies(HCI_ACL_TX_TIMEOUT)))
2515bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
25161da177e4SLinus Torvalds 	}
251763d2bc1bSAndrei Emeltchenko }
25181da177e4SLinus Torvalds 
251963d2bc1bSAndrei Emeltchenko static inline void hci_sched_acl_pkt(struct hci_dev *hdev)
252063d2bc1bSAndrei Emeltchenko {
252163d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
252263d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
252363d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
252463d2bc1bSAndrei Emeltchenko 	int quote;
252563d2bc1bSAndrei Emeltchenko 
252663d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
252704837f64SMarcel Holtmann 
252873d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
252973d80debSLuiz Augusto von Dentz 			(chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
2530ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
2531ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
253273d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
253373d80debSLuiz Augusto von Dentz 					skb->len, skb->priority);
253473d80debSLuiz Augusto von Dentz 
2535ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
2536ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
2537ec1cce24SLuiz Augusto von Dentz 				break;
2538ec1cce24SLuiz Augusto von Dentz 
2539ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
2540ec1cce24SLuiz Augusto von Dentz 
254173d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
254273d80debSLuiz Augusto von Dentz 						bt_cb(skb)->force_active);
254304837f64SMarcel Holtmann 
25441da177e4SLinus Torvalds 			hci_send_frame(skb);
25451da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
25461da177e4SLinus Torvalds 
25471da177e4SLinus Torvalds 			hdev->acl_cnt--;
254873d80debSLuiz Augusto von Dentz 			chan->sent++;
254973d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
25501da177e4SLinus Torvalds 		}
25511da177e4SLinus Torvalds 	}
255202b20f0bSLuiz Augusto von Dentz 
255302b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
255402b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
25551da177e4SLinus Torvalds }
25561da177e4SLinus Torvalds 
2557b71d385aSAndrei Emeltchenko static inline void hci_sched_acl_blk(struct hci_dev *hdev)
2558b71d385aSAndrei Emeltchenko {
255963d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
2560b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
2561b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
2562b71d385aSAndrei Emeltchenko 	int quote;
2563b71d385aSAndrei Emeltchenko 
256463d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
2565b71d385aSAndrei Emeltchenko 
2566b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
2567b71d385aSAndrei Emeltchenko 			(chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
2568b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
2569b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
2570b71d385aSAndrei Emeltchenko 			int blocks;
2571b71d385aSAndrei Emeltchenko 
2572b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
2573b71d385aSAndrei Emeltchenko 						skb->len, skb->priority);
2574b71d385aSAndrei Emeltchenko 
2575b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
2576b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
2577b71d385aSAndrei Emeltchenko 				break;
2578b71d385aSAndrei Emeltchenko 
2579b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
2580b71d385aSAndrei Emeltchenko 
2581b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
2582b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
2583b71d385aSAndrei Emeltchenko 				return;
2584b71d385aSAndrei Emeltchenko 
2585b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
2586b71d385aSAndrei Emeltchenko 						bt_cb(skb)->force_active);
2587b71d385aSAndrei Emeltchenko 
2588b71d385aSAndrei Emeltchenko 			hci_send_frame(skb);
2589b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
2590b71d385aSAndrei Emeltchenko 
2591b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
2592b71d385aSAndrei Emeltchenko 			quote -= blocks;
2593b71d385aSAndrei Emeltchenko 
2594b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
2595b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
2596b71d385aSAndrei Emeltchenko 		}
2597b71d385aSAndrei Emeltchenko 	}
2598b71d385aSAndrei Emeltchenko 
2599b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
2600b71d385aSAndrei Emeltchenko 		hci_prio_recalculate(hdev, ACL_LINK);
2601b71d385aSAndrei Emeltchenko }
2602b71d385aSAndrei Emeltchenko 
2603b71d385aSAndrei Emeltchenko static inline void hci_sched_acl(struct hci_dev *hdev)
2604b71d385aSAndrei Emeltchenko {
2605b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
2606b71d385aSAndrei Emeltchenko 
2607b71d385aSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK))
2608b71d385aSAndrei Emeltchenko 		return;
2609b71d385aSAndrei Emeltchenko 
2610b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
2611b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
2612b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
2613b71d385aSAndrei Emeltchenko 		break;
2614b71d385aSAndrei Emeltchenko 
2615b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
2616b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
2617b71d385aSAndrei Emeltchenko 		break;
2618b71d385aSAndrei Emeltchenko 	}
2619b71d385aSAndrei Emeltchenko }
2620b71d385aSAndrei Emeltchenko 
26211da177e4SLinus Torvalds /* Schedule SCO */
26221da177e4SLinus Torvalds static inline void hci_sched_sco(struct hci_dev *hdev)
26231da177e4SLinus Torvalds {
26241da177e4SLinus Torvalds 	struct hci_conn *conn;
26251da177e4SLinus Torvalds 	struct sk_buff *skb;
26261da177e4SLinus Torvalds 	int quote;
26271da177e4SLinus Torvalds 
26281da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
26291da177e4SLinus Torvalds 
263052087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
263152087a79SLuiz Augusto von Dentz 		return;
263252087a79SLuiz Augusto von Dentz 
26331da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
26341da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
26351da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
26361da177e4SLinus Torvalds 			hci_send_frame(skb);
26371da177e4SLinus Torvalds 
26381da177e4SLinus Torvalds 			conn->sent++;
26391da177e4SLinus Torvalds 			if (conn->sent == ~0)
26401da177e4SLinus Torvalds 				conn->sent = 0;
26411da177e4SLinus Torvalds 		}
26421da177e4SLinus Torvalds 	}
26431da177e4SLinus Torvalds }
26441da177e4SLinus Torvalds 
2645b6a0dc82SMarcel Holtmann static inline void hci_sched_esco(struct hci_dev *hdev)
2646b6a0dc82SMarcel Holtmann {
2647b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
2648b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
2649b6a0dc82SMarcel Holtmann 	int quote;
2650b6a0dc82SMarcel Holtmann 
2651b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
2652b6a0dc82SMarcel Holtmann 
265352087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
265452087a79SLuiz Augusto von Dentz 		return;
265552087a79SLuiz Augusto von Dentz 
2656b6a0dc82SMarcel Holtmann 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, &quote))) {
2657b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
2658b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
2659b6a0dc82SMarcel Holtmann 			hci_send_frame(skb);
2660b6a0dc82SMarcel Holtmann 
2661b6a0dc82SMarcel Holtmann 			conn->sent++;
2662b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
2663b6a0dc82SMarcel Holtmann 				conn->sent = 0;
2664b6a0dc82SMarcel Holtmann 		}
2665b6a0dc82SMarcel Holtmann 	}
2666b6a0dc82SMarcel Holtmann }
2667b6a0dc82SMarcel Holtmann 
26686ed58ec5SVille Tervo static inline void hci_sched_le(struct hci_dev *hdev)
26696ed58ec5SVille Tervo {
267073d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
26716ed58ec5SVille Tervo 	struct sk_buff *skb;
267202b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
26736ed58ec5SVille Tervo 
26746ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
26756ed58ec5SVille Tervo 
267652087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
267752087a79SLuiz Augusto von Dentz 		return;
267852087a79SLuiz Augusto von Dentz 
26796ed58ec5SVille Tervo 	if (!test_bit(HCI_RAW, &hdev->flags)) {
26806ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
26816ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
2682bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
26836ed58ec5SVille Tervo 				time_after(jiffies, hdev->le_last_tx + HZ * 45))
2684bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
26856ed58ec5SVille Tervo 	}
26866ed58ec5SVille Tervo 
26876ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
268802b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
268973d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
2690ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
2691ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
269273d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
269373d80debSLuiz Augusto von Dentz 					skb->len, skb->priority);
26946ed58ec5SVille Tervo 
2695ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
2696ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
2697ec1cce24SLuiz Augusto von Dentz 				break;
2698ec1cce24SLuiz Augusto von Dentz 
2699ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
2700ec1cce24SLuiz Augusto von Dentz 
27016ed58ec5SVille Tervo 			hci_send_frame(skb);
27026ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
27036ed58ec5SVille Tervo 
27046ed58ec5SVille Tervo 			cnt--;
270573d80debSLuiz Augusto von Dentz 			chan->sent++;
270673d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
27076ed58ec5SVille Tervo 		}
27086ed58ec5SVille Tervo 	}
270973d80debSLuiz Augusto von Dentz 
27106ed58ec5SVille Tervo 	if (hdev->le_pkts)
27116ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
27126ed58ec5SVille Tervo 	else
27136ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
271402b20f0bSLuiz Augusto von Dentz 
271502b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
271602b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
27176ed58ec5SVille Tervo }
27186ed58ec5SVille Tervo 
27193eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
27201da177e4SLinus Torvalds {
27213eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
27221da177e4SLinus Torvalds 	struct sk_buff *skb;
27231da177e4SLinus Torvalds 
27246ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
27256ed58ec5SVille Tervo 		hdev->sco_cnt, hdev->le_cnt);
27261da177e4SLinus Torvalds 
27271da177e4SLinus Torvalds 	/* Schedule queues and send stuff to HCI driver */
27281da177e4SLinus Torvalds 
27291da177e4SLinus Torvalds 	hci_sched_acl(hdev);
27301da177e4SLinus Torvalds 
27311da177e4SLinus Torvalds 	hci_sched_sco(hdev);
27321da177e4SLinus Torvalds 
2733b6a0dc82SMarcel Holtmann 	hci_sched_esco(hdev);
2734b6a0dc82SMarcel Holtmann 
27356ed58ec5SVille Tervo 	hci_sched_le(hdev);
27366ed58ec5SVille Tervo 
27371da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
27381da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
27391da177e4SLinus Torvalds 		hci_send_frame(skb);
27401da177e4SLinus Torvalds }
27411da177e4SLinus Torvalds 
274225985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
27431da177e4SLinus Torvalds 
27441da177e4SLinus Torvalds /* ACL data packet */
27451da177e4SLinus Torvalds static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
27461da177e4SLinus Torvalds {
27471da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
27481da177e4SLinus Torvalds 	struct hci_conn *conn;
27491da177e4SLinus Torvalds 	__u16 handle, flags;
27501da177e4SLinus Torvalds 
27511da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
27521da177e4SLinus Torvalds 
27531da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
27541da177e4SLinus Torvalds 	flags  = hci_flags(handle);
27551da177e4SLinus Torvalds 	handle = hci_handle(handle);
27561da177e4SLinus Torvalds 
27571da177e4SLinus Torvalds 	BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags);
27581da177e4SLinus Torvalds 
27591da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
27601da177e4SLinus Torvalds 
27611da177e4SLinus Torvalds 	hci_dev_lock(hdev);
27621da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
27631da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
27641da177e4SLinus Torvalds 
27651da177e4SLinus Torvalds 	if (conn) {
276665983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
276704837f64SMarcel Holtmann 
27681da177e4SLinus Torvalds 		/* Send to upper protocol */
2769686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
27701da177e4SLinus Torvalds 		return;
27711da177e4SLinus Torvalds 	} else {
27721da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
27731da177e4SLinus Torvalds 			hdev->name, handle);
27741da177e4SLinus Torvalds 	}
27751da177e4SLinus Torvalds 
27761da177e4SLinus Torvalds 	kfree_skb(skb);
27771da177e4SLinus Torvalds }
27781da177e4SLinus Torvalds 
27791da177e4SLinus Torvalds /* SCO data packet */
27801da177e4SLinus Torvalds static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
27811da177e4SLinus Torvalds {
27821da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
27831da177e4SLinus Torvalds 	struct hci_conn *conn;
27841da177e4SLinus Torvalds 	__u16 handle;
27851da177e4SLinus Torvalds 
27861da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
27871da177e4SLinus Torvalds 
27881da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
27891da177e4SLinus Torvalds 
27901da177e4SLinus Torvalds 	BT_DBG("%s len %d handle 0x%x", hdev->name, skb->len, handle);
27911da177e4SLinus Torvalds 
27921da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
27931da177e4SLinus Torvalds 
27941da177e4SLinus Torvalds 	hci_dev_lock(hdev);
27951da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
27961da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
27971da177e4SLinus Torvalds 
27981da177e4SLinus Torvalds 	if (conn) {
27991da177e4SLinus Torvalds 		/* Send to upper protocol */
2800686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
28011da177e4SLinus Torvalds 		return;
28021da177e4SLinus Torvalds 	} else {
28031da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
28041da177e4SLinus Torvalds 			hdev->name, handle);
28051da177e4SLinus Torvalds 	}
28061da177e4SLinus Torvalds 
28071da177e4SLinus Torvalds 	kfree_skb(skb);
28081da177e4SLinus Torvalds }
28091da177e4SLinus Torvalds 
2810b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
28111da177e4SLinus Torvalds {
2812b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
28131da177e4SLinus Torvalds 	struct sk_buff *skb;
28141da177e4SLinus Torvalds 
28151da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
28161da177e4SLinus Torvalds 
28171da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
2818cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
2819cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
2820cd82e61cSMarcel Holtmann 
28211da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
28221da177e4SLinus Torvalds 			/* Send copy to the sockets */
2823470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
28241da177e4SLinus Torvalds 		}
28251da177e4SLinus Torvalds 
28261da177e4SLinus Torvalds 		if (test_bit(HCI_RAW, &hdev->flags)) {
28271da177e4SLinus Torvalds 			kfree_skb(skb);
28281da177e4SLinus Torvalds 			continue;
28291da177e4SLinus Torvalds 		}
28301da177e4SLinus Torvalds 
28311da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
28321da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
28330d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
28341da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
28351da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
28361da177e4SLinus Torvalds 				kfree_skb(skb);
28371da177e4SLinus Torvalds 				continue;
28383ff50b79SStephen Hemminger 			}
28391da177e4SLinus Torvalds 		}
28401da177e4SLinus Torvalds 
28411da177e4SLinus Torvalds 		/* Process frame */
28420d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
28431da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
2844b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
28451da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
28461da177e4SLinus Torvalds 			break;
28471da177e4SLinus Torvalds 
28481da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
28491da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
28501da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
28511da177e4SLinus Torvalds 			break;
28521da177e4SLinus Torvalds 
28531da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
28541da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
28551da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
28561da177e4SLinus Torvalds 			break;
28571da177e4SLinus Torvalds 
28581da177e4SLinus Torvalds 		default:
28591da177e4SLinus Torvalds 			kfree_skb(skb);
28601da177e4SLinus Torvalds 			break;
28611da177e4SLinus Torvalds 		}
28621da177e4SLinus Torvalds 	}
28631da177e4SLinus Torvalds }
28641da177e4SLinus Torvalds 
2865c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
28661da177e4SLinus Torvalds {
2867c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
28681da177e4SLinus Torvalds 	struct sk_buff *skb;
28691da177e4SLinus Torvalds 
28701da177e4SLinus Torvalds 	BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
28711da177e4SLinus Torvalds 
28721da177e4SLinus Torvalds 	/* Send queued commands */
28735a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
28745a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
28755a08ecceSAndrei Emeltchenko 		if (!skb)
28765a08ecceSAndrei Emeltchenko 			return;
28775a08ecceSAndrei Emeltchenko 
28781da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
28791da177e4SLinus Torvalds 
288070f23020SAndrei Emeltchenko 		hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC);
288170f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
28821da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
28831da177e4SLinus Torvalds 			hci_send_frame(skb);
28847bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
28857bdb8a5cSSzymon Janc 				del_timer(&hdev->cmd_timer);
28867bdb8a5cSSzymon Janc 			else
28876bd32326SVille Tervo 				mod_timer(&hdev->cmd_timer,
28886bd32326SVille Tervo 				  jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT));
28891da177e4SLinus Torvalds 		} else {
28901da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
2891c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
28921da177e4SLinus Torvalds 		}
28931da177e4SLinus Torvalds 	}
28941da177e4SLinus Torvalds }
28952519a1fcSAndre Guedes 
28962519a1fcSAndre Guedes int hci_do_inquiry(struct hci_dev *hdev, u8 length)
28972519a1fcSAndre Guedes {
28982519a1fcSAndre Guedes 	/* General inquiry access code (GIAC) */
28992519a1fcSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
29002519a1fcSAndre Guedes 	struct hci_cp_inquiry cp;
29012519a1fcSAndre Guedes 
29022519a1fcSAndre Guedes 	BT_DBG("%s", hdev->name);
29032519a1fcSAndre Guedes 
29042519a1fcSAndre Guedes 	if (test_bit(HCI_INQUIRY, &hdev->flags))
29052519a1fcSAndre Guedes 		return -EINPROGRESS;
29062519a1fcSAndre Guedes 
29074663262cSJohan Hedberg 	inquiry_cache_flush(hdev);
29084663262cSJohan Hedberg 
29092519a1fcSAndre Guedes 	memset(&cp, 0, sizeof(cp));
29102519a1fcSAndre Guedes 	memcpy(&cp.lap, lap, sizeof(cp.lap));
29112519a1fcSAndre Guedes 	cp.length  = length;
29122519a1fcSAndre Guedes 
29132519a1fcSAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
29142519a1fcSAndre Guedes }
2915023d5049SAndre Guedes 
2916023d5049SAndre Guedes int hci_cancel_inquiry(struct hci_dev *hdev)
2917023d5049SAndre Guedes {
2918023d5049SAndre Guedes 	BT_DBG("%s", hdev->name);
2919023d5049SAndre Guedes 
2920023d5049SAndre Guedes 	if (!test_bit(HCI_INQUIRY, &hdev->flags))
2921023d5049SAndre Guedes 		return -EPERM;
2922023d5049SAndre Guedes 
2923023d5049SAndre Guedes 	return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL);
2924023d5049SAndre Guedes }
2925