xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 6b3cc1db)
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 
288c520a59SGustavo Padovan #include <linux/export.h>
293df92b31SSasha Levin #include <linux/idr.h>
30611b30f7SMarcel Holtmann #include <linux/rfkill.h>
31baf27f6eSMarcel Holtmann #include <linux/debugfs.h>
3299780a7bSJohan Hedberg #include <linux/crypto.h>
3347219839SMarcel Holtmann #include <asm/unaligned.h>
341da177e4SLinus Torvalds 
351da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
361da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
374bc58f51SJohan Hedberg #include <net/bluetooth/l2cap.h>
38af58925cSMarcel Holtmann #include <net/bluetooth/mgmt.h>
391da177e4SLinus Torvalds 
400857dd3bSJohan Hedberg #include "hci_request.h"
4160c5f5fbSMarcel Holtmann #include "hci_debugfs.h"
42970c4e46SJohan Hedberg #include "smp.h"
43970c4e46SJohan Hedberg 
44b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work);
45c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work);
463eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work);
471da177e4SLinus Torvalds 
481da177e4SLinus Torvalds /* HCI device list */
491da177e4SLinus Torvalds LIST_HEAD(hci_dev_list);
501da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock);
511da177e4SLinus Torvalds 
521da177e4SLinus Torvalds /* HCI callback list */
531da177e4SLinus Torvalds LIST_HEAD(hci_cb_list);
54fba7ecf0SJohan Hedberg DEFINE_MUTEX(hci_cb_list_lock);
551da177e4SLinus Torvalds 
563df92b31SSasha Levin /* HCI ID Numbering */
573df92b31SSasha Levin static DEFINE_IDA(hci_index_ida);
583df92b31SSasha Levin 
59899de765SMarcel Holtmann /* ----- HCI requests ----- */
60899de765SMarcel Holtmann 
61899de765SMarcel Holtmann #define HCI_REQ_DONE	  0
62899de765SMarcel Holtmann #define HCI_REQ_PEND	  1
63899de765SMarcel Holtmann #define HCI_REQ_CANCELED  2
64899de765SMarcel Holtmann 
65899de765SMarcel Holtmann #define hci_req_lock(d)		mutex_lock(&d->req_lock)
66899de765SMarcel Holtmann #define hci_req_unlock(d)	mutex_unlock(&d->req_lock)
67899de765SMarcel Holtmann 
681da177e4SLinus Torvalds /* ---- HCI notifications ---- */
691da177e4SLinus Torvalds 
706516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event)
711da177e4SLinus Torvalds {
72040030efSMarcel Holtmann 	hci_sock_dev_event(hdev, event);
731da177e4SLinus Torvalds }
741da177e4SLinus Torvalds 
75baf27f6eSMarcel Holtmann /* ---- HCI debugfs entries ---- */
76baf27f6eSMarcel Holtmann 
774b4148e9SMarcel Holtmann static ssize_t dut_mode_read(struct file *file, char __user *user_buf,
784b4148e9SMarcel Holtmann 			     size_t count, loff_t *ppos)
794b4148e9SMarcel Holtmann {
804b4148e9SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
814b4148e9SMarcel Holtmann 	char buf[3];
824b4148e9SMarcel Holtmann 
83b7cb93e5SMarcel Holtmann 	buf[0] = hci_dev_test_flag(hdev, HCI_DUT_MODE) ? 'Y': 'N';
844b4148e9SMarcel Holtmann 	buf[1] = '\n';
854b4148e9SMarcel Holtmann 	buf[2] = '\0';
864b4148e9SMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
874b4148e9SMarcel Holtmann }
884b4148e9SMarcel Holtmann 
894b4148e9SMarcel Holtmann static ssize_t dut_mode_write(struct file *file, const char __user *user_buf,
904b4148e9SMarcel Holtmann 			      size_t count, loff_t *ppos)
914b4148e9SMarcel Holtmann {
924b4148e9SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
934b4148e9SMarcel Holtmann 	struct sk_buff *skb;
944b4148e9SMarcel Holtmann 	char buf[32];
954b4148e9SMarcel Holtmann 	size_t buf_size = min(count, (sizeof(buf)-1));
964b4148e9SMarcel Holtmann 	bool enable;
974b4148e9SMarcel Holtmann 
984b4148e9SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
994b4148e9SMarcel Holtmann 		return -ENETDOWN;
1004b4148e9SMarcel Holtmann 
1014b4148e9SMarcel Holtmann 	if (copy_from_user(buf, user_buf, buf_size))
1024b4148e9SMarcel Holtmann 		return -EFAULT;
1034b4148e9SMarcel Holtmann 
1044b4148e9SMarcel Holtmann 	buf[buf_size] = '\0';
1054b4148e9SMarcel Holtmann 	if (strtobool(buf, &enable))
1064b4148e9SMarcel Holtmann 		return -EINVAL;
1074b4148e9SMarcel Holtmann 
108b7cb93e5SMarcel Holtmann 	if (enable == hci_dev_test_flag(hdev, HCI_DUT_MODE))
1094b4148e9SMarcel Holtmann 		return -EALREADY;
1104b4148e9SMarcel Holtmann 
1114b4148e9SMarcel Holtmann 	hci_req_lock(hdev);
1124b4148e9SMarcel Holtmann 	if (enable)
1134b4148e9SMarcel Holtmann 		skb = __hci_cmd_sync(hdev, HCI_OP_ENABLE_DUT_MODE, 0, NULL,
1144b4148e9SMarcel Holtmann 				     HCI_CMD_TIMEOUT);
1154b4148e9SMarcel Holtmann 	else
1164b4148e9SMarcel Holtmann 		skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL,
1174b4148e9SMarcel Holtmann 				     HCI_CMD_TIMEOUT);
1184b4148e9SMarcel Holtmann 	hci_req_unlock(hdev);
1194b4148e9SMarcel Holtmann 
1204b4148e9SMarcel Holtmann 	if (IS_ERR(skb))
1214b4148e9SMarcel Holtmann 		return PTR_ERR(skb);
1224b4148e9SMarcel Holtmann 
1234b4148e9SMarcel Holtmann 	kfree_skb(skb);
1244b4148e9SMarcel Holtmann 
125b7cb93e5SMarcel Holtmann 	hci_dev_change_flag(hdev, HCI_DUT_MODE);
1264b4148e9SMarcel Holtmann 
1274b4148e9SMarcel Holtmann 	return count;
1284b4148e9SMarcel Holtmann }
1294b4148e9SMarcel Holtmann 
1304b4148e9SMarcel Holtmann static const struct file_operations dut_mode_fops = {
1314b4148e9SMarcel Holtmann 	.open		= simple_open,
1324b4148e9SMarcel Holtmann 	.read		= dut_mode_read,
1334b4148e9SMarcel Holtmann 	.write		= dut_mode_write,
1344b4148e9SMarcel Holtmann 	.llseek		= default_llseek,
1354b4148e9SMarcel Holtmann };
1364b4148e9SMarcel Holtmann 
1371da177e4SLinus Torvalds /* ---- HCI requests ---- */
1381da177e4SLinus Torvalds 
139f60cb305SJohan Hedberg static void hci_req_sync_complete(struct hci_dev *hdev, u8 result, u16 opcode,
140f60cb305SJohan Hedberg 				  struct sk_buff *skb)
1411da177e4SLinus Torvalds {
14242c6b129SJohan Hedberg 	BT_DBG("%s result 0x%2.2x", hdev->name, result);
14375fb0e32SJohan Hedberg 
1441da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
1451da177e4SLinus Torvalds 		hdev->req_result = result;
1461da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_DONE;
147f60cb305SJohan Hedberg 		if (skb)
148f60cb305SJohan Hedberg 			hdev->req_skb = skb_get(skb);
1491da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
1501da177e4SLinus Torvalds 	}
1511da177e4SLinus Torvalds }
1521da177e4SLinus Torvalds 
1531da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err)
1541da177e4SLinus Torvalds {
1551da177e4SLinus Torvalds 	BT_DBG("%s err 0x%2.2x", hdev->name, err);
1561da177e4SLinus Torvalds 
1571da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
1581da177e4SLinus Torvalds 		hdev->req_result = err;
1591da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_CANCELED;
1601da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
1611da177e4SLinus Torvalds 	}
1621da177e4SLinus Torvalds }
1631da177e4SLinus Torvalds 
1647b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
16507dc93ddSJohan Hedberg 				  const void *param, u8 event, u32 timeout)
16675e84b7cSJohan Hedberg {
16775e84b7cSJohan Hedberg 	DECLARE_WAITQUEUE(wait, current);
16875e84b7cSJohan Hedberg 	struct hci_request req;
169f60cb305SJohan Hedberg 	struct sk_buff *skb;
17075e84b7cSJohan Hedberg 	int err = 0;
17175e84b7cSJohan Hedberg 
17275e84b7cSJohan Hedberg 	BT_DBG("%s", hdev->name);
17375e84b7cSJohan Hedberg 
17475e84b7cSJohan Hedberg 	hci_req_init(&req, hdev);
17575e84b7cSJohan Hedberg 
1767b1abbbeSJohan Hedberg 	hci_req_add_ev(&req, opcode, plen, param, event);
17775e84b7cSJohan Hedberg 
17875e84b7cSJohan Hedberg 	hdev->req_status = HCI_REQ_PEND;
17975e84b7cSJohan Hedberg 
18075e84b7cSJohan Hedberg 	add_wait_queue(&hdev->req_wait_q, &wait);
18175e84b7cSJohan Hedberg 	set_current_state(TASK_INTERRUPTIBLE);
18275e84b7cSJohan Hedberg 
183f60cb305SJohan Hedberg 	err = hci_req_run_skb(&req, hci_req_sync_complete);
184039fada5SChan-yeol Park 	if (err < 0) {
185039fada5SChan-yeol Park 		remove_wait_queue(&hdev->req_wait_q, &wait);
18622a3ceabSJohan Hedberg 		set_current_state(TASK_RUNNING);
187039fada5SChan-yeol Park 		return ERR_PTR(err);
188039fada5SChan-yeol Park 	}
189039fada5SChan-yeol Park 
19075e84b7cSJohan Hedberg 	schedule_timeout(timeout);
19175e84b7cSJohan Hedberg 
19275e84b7cSJohan Hedberg 	remove_wait_queue(&hdev->req_wait_q, &wait);
19375e84b7cSJohan Hedberg 
19475e84b7cSJohan Hedberg 	if (signal_pending(current))
19575e84b7cSJohan Hedberg 		return ERR_PTR(-EINTR);
19675e84b7cSJohan Hedberg 
19775e84b7cSJohan Hedberg 	switch (hdev->req_status) {
19875e84b7cSJohan Hedberg 	case HCI_REQ_DONE:
19975e84b7cSJohan Hedberg 		err = -bt_to_errno(hdev->req_result);
20075e84b7cSJohan Hedberg 		break;
20175e84b7cSJohan Hedberg 
20275e84b7cSJohan Hedberg 	case HCI_REQ_CANCELED:
20375e84b7cSJohan Hedberg 		err = -hdev->req_result;
20475e84b7cSJohan Hedberg 		break;
20575e84b7cSJohan Hedberg 
20675e84b7cSJohan Hedberg 	default:
20775e84b7cSJohan Hedberg 		err = -ETIMEDOUT;
20875e84b7cSJohan Hedberg 		break;
20975e84b7cSJohan Hedberg 	}
21075e84b7cSJohan Hedberg 
21175e84b7cSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
212f60cb305SJohan Hedberg 	skb = hdev->req_skb;
213f60cb305SJohan Hedberg 	hdev->req_skb = NULL;
21475e84b7cSJohan Hedberg 
21575e84b7cSJohan Hedberg 	BT_DBG("%s end: err %d", hdev->name, err);
21675e84b7cSJohan Hedberg 
217f60cb305SJohan Hedberg 	if (err < 0) {
218f60cb305SJohan Hedberg 		kfree_skb(skb);
21975e84b7cSJohan Hedberg 		return ERR_PTR(err);
220f60cb305SJohan Hedberg 	}
22175e84b7cSJohan Hedberg 
222757aa0b5SJohan Hedberg 	if (!skb)
223757aa0b5SJohan Hedberg 		return ERR_PTR(-ENODATA);
224757aa0b5SJohan Hedberg 
225757aa0b5SJohan Hedberg 	return skb;
2267b1abbbeSJohan Hedberg }
2277b1abbbeSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync_ev);
2287b1abbbeSJohan Hedberg 
2297b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
23007dc93ddSJohan Hedberg 			       const void *param, u32 timeout)
2317b1abbbeSJohan Hedberg {
2327b1abbbeSJohan Hedberg 	return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout);
23375e84b7cSJohan Hedberg }
23475e84b7cSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync);
23575e84b7cSJohan Hedberg 
2361da177e4SLinus Torvalds /* Execute request and wait for completion. */
23701178cd4SJohan Hedberg static int __hci_req_sync(struct hci_dev *hdev,
23842c6b129SJohan Hedberg 			  void (*func)(struct hci_request *req,
23942c6b129SJohan Hedberg 				      unsigned long opt),
2401da177e4SLinus Torvalds 			  unsigned long opt, __u32 timeout)
2411da177e4SLinus Torvalds {
24242c6b129SJohan Hedberg 	struct hci_request req;
2431da177e4SLinus Torvalds 	DECLARE_WAITQUEUE(wait, current);
2441da177e4SLinus Torvalds 	int err = 0;
2451da177e4SLinus Torvalds 
2461da177e4SLinus Torvalds 	BT_DBG("%s start", hdev->name);
2471da177e4SLinus Torvalds 
24842c6b129SJohan Hedberg 	hci_req_init(&req, hdev);
24942c6b129SJohan Hedberg 
2501da177e4SLinus Torvalds 	hdev->req_status = HCI_REQ_PEND;
2511da177e4SLinus Torvalds 
25242c6b129SJohan Hedberg 	func(&req, opt);
25353cce22dSJohan Hedberg 
254039fada5SChan-yeol Park 	add_wait_queue(&hdev->req_wait_q, &wait);
255039fada5SChan-yeol Park 	set_current_state(TASK_INTERRUPTIBLE);
256039fada5SChan-yeol Park 
257f60cb305SJohan Hedberg 	err = hci_req_run_skb(&req, hci_req_sync_complete);
25842c6b129SJohan Hedberg 	if (err < 0) {
25953cce22dSJohan Hedberg 		hdev->req_status = 0;
260920c8300SAndre Guedes 
261039fada5SChan-yeol Park 		remove_wait_queue(&hdev->req_wait_q, &wait);
26222a3ceabSJohan Hedberg 		set_current_state(TASK_RUNNING);
263039fada5SChan-yeol Park 
264920c8300SAndre Guedes 		/* ENODATA means the HCI request command queue is empty.
265920c8300SAndre Guedes 		 * This can happen when a request with conditionals doesn't
266920c8300SAndre Guedes 		 * trigger any commands to be sent. This is normal behavior
267920c8300SAndre Guedes 		 * and should not trigger an error return.
26842c6b129SJohan Hedberg 		 */
269920c8300SAndre Guedes 		if (err == -ENODATA)
27042c6b129SJohan Hedberg 			return 0;
271920c8300SAndre Guedes 
272920c8300SAndre Guedes 		return err;
27353cce22dSJohan Hedberg 	}
27453cce22dSJohan Hedberg 
2751da177e4SLinus Torvalds 	schedule_timeout(timeout);
2761da177e4SLinus Torvalds 
2771da177e4SLinus Torvalds 	remove_wait_queue(&hdev->req_wait_q, &wait);
2781da177e4SLinus Torvalds 
2791da177e4SLinus Torvalds 	if (signal_pending(current))
2801da177e4SLinus Torvalds 		return -EINTR;
2811da177e4SLinus Torvalds 
2821da177e4SLinus Torvalds 	switch (hdev->req_status) {
2831da177e4SLinus Torvalds 	case HCI_REQ_DONE:
284e175072fSJoe Perches 		err = -bt_to_errno(hdev->req_result);
2851da177e4SLinus Torvalds 		break;
2861da177e4SLinus Torvalds 
2871da177e4SLinus Torvalds 	case HCI_REQ_CANCELED:
2881da177e4SLinus Torvalds 		err = -hdev->req_result;
2891da177e4SLinus Torvalds 		break;
2901da177e4SLinus Torvalds 
2911da177e4SLinus Torvalds 	default:
2921da177e4SLinus Torvalds 		err = -ETIMEDOUT;
2931da177e4SLinus Torvalds 		break;
2943ff50b79SStephen Hemminger 	}
2951da177e4SLinus Torvalds 
296a5040efaSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
2971da177e4SLinus Torvalds 
2981da177e4SLinus Torvalds 	BT_DBG("%s end: err %d", hdev->name, err);
2991da177e4SLinus Torvalds 
3001da177e4SLinus Torvalds 	return err;
3011da177e4SLinus Torvalds }
3021da177e4SLinus Torvalds 
30301178cd4SJohan Hedberg static int hci_req_sync(struct hci_dev *hdev,
30442c6b129SJohan Hedberg 			void (*req)(struct hci_request *req,
30542c6b129SJohan Hedberg 				    unsigned long opt),
3061da177e4SLinus Torvalds 			unsigned long opt, __u32 timeout)
3071da177e4SLinus Torvalds {
3081da177e4SLinus Torvalds 	int ret;
3091da177e4SLinus Torvalds 
3107c6a329eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
3117c6a329eSMarcel Holtmann 		return -ENETDOWN;
3127c6a329eSMarcel Holtmann 
3131da177e4SLinus Torvalds 	/* Serialize all requests */
3141da177e4SLinus Torvalds 	hci_req_lock(hdev);
31501178cd4SJohan Hedberg 	ret = __hci_req_sync(hdev, req, opt, timeout);
3161da177e4SLinus Torvalds 	hci_req_unlock(hdev);
3171da177e4SLinus Torvalds 
3181da177e4SLinus Torvalds 	return ret;
3191da177e4SLinus Torvalds }
3201da177e4SLinus Torvalds 
32142c6b129SJohan Hedberg static void hci_reset_req(struct hci_request *req, unsigned long opt)
3221da177e4SLinus Torvalds {
32342c6b129SJohan Hedberg 	BT_DBG("%s %ld", req->hdev->name, opt);
3241da177e4SLinus Torvalds 
3251da177e4SLinus Torvalds 	/* Reset device */
32642c6b129SJohan Hedberg 	set_bit(HCI_RESET, &req->hdev->flags);
32742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_RESET, 0, NULL);
3281da177e4SLinus Torvalds }
3291da177e4SLinus Torvalds 
33042c6b129SJohan Hedberg static void bredr_init(struct hci_request *req)
3311da177e4SLinus Torvalds {
33242c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
3332455a3eaSAndrei Emeltchenko 
3341da177e4SLinus Torvalds 	/* Read Local Supported Features */
33542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
3361da177e4SLinus Torvalds 
3371143e5a6SMarcel Holtmann 	/* Read Local Version */
33842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
3392177bab5SJohan Hedberg 
3402177bab5SJohan Hedberg 	/* Read BD Address */
34142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
3421da177e4SLinus Torvalds }
3431da177e4SLinus Torvalds 
3440af801b9SJohan Hedberg static void amp_init1(struct hci_request *req)
345e61ef499SAndrei Emeltchenko {
34642c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
3472455a3eaSAndrei Emeltchenko 
348e61ef499SAndrei Emeltchenko 	/* Read Local Version */
34942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
3506bcbc489SAndrei Emeltchenko 
351f6996cfeSMarcel Holtmann 	/* Read Local Supported Commands */
352f6996cfeSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
353f6996cfeSMarcel Holtmann 
3546bcbc489SAndrei Emeltchenko 	/* Read Local AMP Info */
35542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
356e71dfabaSAndrei Emeltchenko 
357e71dfabaSAndrei Emeltchenko 	/* Read Data Blk size */
35842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL);
3597528ca1cSMarcel Holtmann 
360f38ba941SMarcel Holtmann 	/* Read Flow Control Mode */
361f38ba941SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL);
362f38ba941SMarcel Holtmann 
3637528ca1cSMarcel Holtmann 	/* Read Location Data */
3647528ca1cSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL);
365e61ef499SAndrei Emeltchenko }
366e61ef499SAndrei Emeltchenko 
3670af801b9SJohan Hedberg static void amp_init2(struct hci_request *req)
3680af801b9SJohan Hedberg {
3690af801b9SJohan Hedberg 	/* Read Local Supported Features. Not all AMP controllers
3700af801b9SJohan Hedberg 	 * support this so it's placed conditionally in the second
3710af801b9SJohan Hedberg 	 * stage init.
3720af801b9SJohan Hedberg 	 */
3730af801b9SJohan Hedberg 	if (req->hdev->commands[14] & 0x20)
3740af801b9SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
3750af801b9SJohan Hedberg }
3760af801b9SJohan Hedberg 
37742c6b129SJohan Hedberg static void hci_init1_req(struct hci_request *req, unsigned long opt)
378e61ef499SAndrei Emeltchenko {
37942c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
380e61ef499SAndrei Emeltchenko 
381e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
382e61ef499SAndrei Emeltchenko 
38311778716SAndrei Emeltchenko 	/* Reset */
38411778716SAndrei Emeltchenko 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
38542c6b129SJohan Hedberg 		hci_reset_req(req, 0);
38611778716SAndrei Emeltchenko 
387e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
388e61ef499SAndrei Emeltchenko 	case HCI_BREDR:
38942c6b129SJohan Hedberg 		bredr_init(req);
390e61ef499SAndrei Emeltchenko 		break;
391e61ef499SAndrei Emeltchenko 
392e61ef499SAndrei Emeltchenko 	case HCI_AMP:
3930af801b9SJohan Hedberg 		amp_init1(req);
394e61ef499SAndrei Emeltchenko 		break;
395e61ef499SAndrei Emeltchenko 
396e61ef499SAndrei Emeltchenko 	default:
397e61ef499SAndrei Emeltchenko 		BT_ERR("Unknown device type %d", hdev->dev_type);
398e61ef499SAndrei Emeltchenko 		break;
399e61ef499SAndrei Emeltchenko 	}
400e61ef499SAndrei Emeltchenko }
401e61ef499SAndrei Emeltchenko 
40242c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req)
4032177bab5SJohan Hedberg {
4042177bab5SJohan Hedberg 	__le16 param;
4052177bab5SJohan Hedberg 	__u8 flt_type;
4062177bab5SJohan Hedberg 
4072177bab5SJohan Hedberg 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
40842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
4092177bab5SJohan Hedberg 
4102177bab5SJohan Hedberg 	/* Read Class of Device */
41142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
4122177bab5SJohan Hedberg 
4132177bab5SJohan Hedberg 	/* Read Local Name */
41442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL);
4152177bab5SJohan Hedberg 
4162177bab5SJohan Hedberg 	/* Read Voice Setting */
41742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL);
4182177bab5SJohan Hedberg 
419b4cb9fb2SMarcel Holtmann 	/* Read Number of Supported IAC */
420b4cb9fb2SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL);
421b4cb9fb2SMarcel Holtmann 
4224b836f39SMarcel Holtmann 	/* Read Current IAC LAP */
4234b836f39SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL);
4244b836f39SMarcel Holtmann 
4252177bab5SJohan Hedberg 	/* Clear Event Filters */
4262177bab5SJohan Hedberg 	flt_type = HCI_FLT_CLEAR_ALL;
42742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
4282177bab5SJohan Hedberg 
4292177bab5SJohan Hedberg 	/* Connection accept timeout ~20 secs */
430dcf4adbfSJoe Perches 	param = cpu_to_le16(0x7d00);
43142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
4322177bab5SJohan Hedberg }
4332177bab5SJohan Hedberg 
43442c6b129SJohan Hedberg static void le_setup(struct hci_request *req)
4352177bab5SJohan Hedberg {
436c73eee91SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
437c73eee91SJohan Hedberg 
4382177bab5SJohan Hedberg 	/* Read LE Buffer Size */
43942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
4402177bab5SJohan Hedberg 
4412177bab5SJohan Hedberg 	/* Read LE Local Supported Features */
44242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
4432177bab5SJohan Hedberg 
444747d3f03SMarcel Holtmann 	/* Read LE Supported States */
445747d3f03SMarcel Holtmann 	hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);
446747d3f03SMarcel Holtmann 
4472177bab5SJohan Hedberg 	/* Read LE White List Size */
44842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL);
4492177bab5SJohan Hedberg 
450747d3f03SMarcel Holtmann 	/* Clear LE White List */
451747d3f03SMarcel Holtmann 	hci_req_add(req, HCI_OP_LE_CLEAR_WHITE_LIST, 0, NULL);
452c73eee91SJohan Hedberg 
453c73eee91SJohan Hedberg 	/* LE-only controllers have LE implicitly enabled */
454c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
455a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_LE_ENABLED);
4562177bab5SJohan Hedberg }
4572177bab5SJohan Hedberg 
45842c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req)
4592177bab5SJohan Hedberg {
46042c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
46142c6b129SJohan Hedberg 
4622177bab5SJohan Hedberg 	/* The second byte is 0xff instead of 0x9f (two reserved bits
4632177bab5SJohan Hedberg 	 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
4642177bab5SJohan Hedberg 	 * command otherwise.
4652177bab5SJohan Hedberg 	 */
4662177bab5SJohan Hedberg 	u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
4672177bab5SJohan Hedberg 
4682177bab5SJohan Hedberg 	/* CSR 1.1 dongles does not accept any bitfield so don't try to set
4692177bab5SJohan Hedberg 	 * any event mask for pre 1.2 devices.
4702177bab5SJohan Hedberg 	 */
4712177bab5SJohan Hedberg 	if (hdev->hci_ver < BLUETOOTH_VER_1_2)
4722177bab5SJohan Hedberg 		return;
4732177bab5SJohan Hedberg 
4742177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
4752177bab5SJohan Hedberg 		events[4] |= 0x01; /* Flow Specification Complete */
4762177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
4772177bab5SJohan Hedberg 		events[4] |= 0x04; /* Read Remote Extended Features Complete */
4782177bab5SJohan Hedberg 		events[5] |= 0x08; /* Synchronous Connection Complete */
4792177bab5SJohan Hedberg 		events[5] |= 0x10; /* Synchronous Connection Changed */
480c7882cbdSMarcel Holtmann 	} else {
481c7882cbdSMarcel Holtmann 		/* Use a different default for LE-only devices */
482c7882cbdSMarcel Holtmann 		memset(events, 0, sizeof(events));
483c7882cbdSMarcel Holtmann 		events[0] |= 0x10; /* Disconnection Complete */
484c7882cbdSMarcel Holtmann 		events[1] |= 0x08; /* Read Remote Version Information Complete */
485c7882cbdSMarcel Holtmann 		events[1] |= 0x20; /* Command Complete */
486c7882cbdSMarcel Holtmann 		events[1] |= 0x40; /* Command Status */
487c7882cbdSMarcel Holtmann 		events[1] |= 0x80; /* Hardware Error */
488c7882cbdSMarcel Holtmann 		events[2] |= 0x04; /* Number of Completed Packets */
489c7882cbdSMarcel Holtmann 		events[3] |= 0x02; /* Data Buffer Overflow */
4900da71f1bSMarcel Holtmann 
4910da71f1bSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_ENCRYPTION) {
4920da71f1bSMarcel Holtmann 			events[0] |= 0x80; /* Encryption Change */
493c7882cbdSMarcel Holtmann 			events[5] |= 0x80; /* Encryption Key Refresh Complete */
4942177bab5SJohan Hedberg 		}
4950da71f1bSMarcel Holtmann 	}
4962177bab5SJohan Hedberg 
4972177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
4982177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
4992177bab5SJohan Hedberg 
5002177bab5SJohan Hedberg 	if (lmp_sniffsubr_capable(hdev))
5012177bab5SJohan Hedberg 		events[5] |= 0x20; /* Sniff Subrating */
5022177bab5SJohan Hedberg 
5032177bab5SJohan Hedberg 	if (lmp_pause_enc_capable(hdev))
5042177bab5SJohan Hedberg 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
5052177bab5SJohan Hedberg 
5062177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
5072177bab5SJohan Hedberg 		events[5] |= 0x40; /* Extended Inquiry Result */
5082177bab5SJohan Hedberg 
5092177bab5SJohan Hedberg 	if (lmp_no_flush_capable(hdev))
5102177bab5SJohan Hedberg 		events[7] |= 0x01; /* Enhanced Flush Complete */
5112177bab5SJohan Hedberg 
5122177bab5SJohan Hedberg 	if (lmp_lsto_capable(hdev))
5132177bab5SJohan Hedberg 		events[6] |= 0x80; /* Link Supervision Timeout Changed */
5142177bab5SJohan Hedberg 
5152177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
5162177bab5SJohan Hedberg 		events[6] |= 0x01;	/* IO Capability Request */
5172177bab5SJohan Hedberg 		events[6] |= 0x02;	/* IO Capability Response */
5182177bab5SJohan Hedberg 		events[6] |= 0x04;	/* User Confirmation Request */
5192177bab5SJohan Hedberg 		events[6] |= 0x08;	/* User Passkey Request */
5202177bab5SJohan Hedberg 		events[6] |= 0x10;	/* Remote OOB Data Request */
5212177bab5SJohan Hedberg 		events[6] |= 0x20;	/* Simple Pairing Complete */
5222177bab5SJohan Hedberg 		events[7] |= 0x04;	/* User Passkey Notification */
5232177bab5SJohan Hedberg 		events[7] |= 0x08;	/* Keypress Notification */
5242177bab5SJohan Hedberg 		events[7] |= 0x10;	/* Remote Host Supported
5252177bab5SJohan Hedberg 					 * Features Notification
5262177bab5SJohan Hedberg 					 */
5272177bab5SJohan Hedberg 	}
5282177bab5SJohan Hedberg 
5292177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
5302177bab5SJohan Hedberg 		events[7] |= 0x20;	/* LE Meta-Event */
5312177bab5SJohan Hedberg 
53242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
5332177bab5SJohan Hedberg }
5342177bab5SJohan Hedberg 
53542c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt)
5362177bab5SJohan Hedberg {
53742c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
53842c6b129SJohan Hedberg 
5390af801b9SJohan Hedberg 	if (hdev->dev_type == HCI_AMP)
5400af801b9SJohan Hedberg 		return amp_init2(req);
5410af801b9SJohan Hedberg 
5422177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev))
54342c6b129SJohan Hedberg 		bredr_setup(req);
54456f87901SJohan Hedberg 	else
545a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_BREDR_ENABLED);
5462177bab5SJohan Hedberg 
5472177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
54842c6b129SJohan Hedberg 		le_setup(req);
5492177bab5SJohan Hedberg 
5500f3adeaeSMarcel Holtmann 	/* All Bluetooth 1.2 and later controllers should support the
5510f3adeaeSMarcel Holtmann 	 * HCI command for reading the local supported commands.
5520f3adeaeSMarcel Holtmann 	 *
5530f3adeaeSMarcel Holtmann 	 * Unfortunately some controllers indicate Bluetooth 1.2 support,
5540f3adeaeSMarcel Holtmann 	 * but do not have support for this command. If that is the case,
5550f3adeaeSMarcel Holtmann 	 * the driver can quirk the behavior and skip reading the local
5560f3adeaeSMarcel Holtmann 	 * supported commands.
5573f8e2d75SJohan Hedberg 	 */
5580f3adeaeSMarcel Holtmann 	if (hdev->hci_ver > BLUETOOTH_VER_1_1 &&
5590f3adeaeSMarcel Holtmann 	    !test_bit(HCI_QUIRK_BROKEN_LOCAL_COMMANDS, &hdev->quirks))
56042c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
5612177bab5SJohan Hedberg 
5622177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
56357af75a8SMarcel Holtmann 		/* When SSP is available, then the host features page
56457af75a8SMarcel Holtmann 		 * should also be available as well. However some
56557af75a8SMarcel Holtmann 		 * controllers list the max_page as 0 as long as SSP
56657af75a8SMarcel Holtmann 		 * has not been enabled. To achieve proper debugging
56757af75a8SMarcel Holtmann 		 * output, force the minimum max_page to 1 at least.
56857af75a8SMarcel Holtmann 		 */
56957af75a8SMarcel Holtmann 		hdev->max_page = 0x01;
57057af75a8SMarcel Holtmann 
571d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED)) {
5722177bab5SJohan Hedberg 			u8 mode = 0x01;
573574ea3c7SMarcel Holtmann 
57442c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_SSP_MODE,
5752177bab5SJohan Hedberg 				    sizeof(mode), &mode);
5762177bab5SJohan Hedberg 		} else {
5772177bab5SJohan Hedberg 			struct hci_cp_write_eir cp;
5782177bab5SJohan Hedberg 
5792177bab5SJohan Hedberg 			memset(hdev->eir, 0, sizeof(hdev->eir));
5802177bab5SJohan Hedberg 			memset(&cp, 0, sizeof(cp));
5812177bab5SJohan Hedberg 
58242c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
5832177bab5SJohan Hedberg 		}
5842177bab5SJohan Hedberg 	}
5852177bab5SJohan Hedberg 
586043ec9bfSMarcel Holtmann 	if (lmp_inq_rssi_capable(hdev) ||
587043ec9bfSMarcel Holtmann 	    test_bit(HCI_QUIRK_FIXUP_INQUIRY_MODE, &hdev->quirks)) {
58804422da9SMarcel Holtmann 		u8 mode;
58904422da9SMarcel Holtmann 
59004422da9SMarcel Holtmann 		/* If Extended Inquiry Result events are supported, then
59104422da9SMarcel Holtmann 		 * they are clearly preferred over Inquiry Result with RSSI
59204422da9SMarcel Holtmann 		 * events.
59304422da9SMarcel Holtmann 		 */
59404422da9SMarcel Holtmann 		mode = lmp_ext_inq_capable(hdev) ? 0x02 : 0x01;
59504422da9SMarcel Holtmann 
59604422da9SMarcel Holtmann 		hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
59704422da9SMarcel Holtmann 	}
5982177bab5SJohan Hedberg 
5992177bab5SJohan Hedberg 	if (lmp_inq_tx_pwr_capable(hdev))
60042c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
6012177bab5SJohan Hedberg 
6022177bab5SJohan Hedberg 	if (lmp_ext_feat_capable(hdev)) {
6032177bab5SJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
6042177bab5SJohan Hedberg 
6052177bab5SJohan Hedberg 		cp.page = 0x01;
60642c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
60742c6b129SJohan Hedberg 			    sizeof(cp), &cp);
6082177bab5SJohan Hedberg 	}
6092177bab5SJohan Hedberg 
610d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_LINK_SECURITY)) {
6112177bab5SJohan Hedberg 		u8 enable = 1;
61242c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
6132177bab5SJohan Hedberg 			    &enable);
6142177bab5SJohan Hedberg 	}
6152177bab5SJohan Hedberg }
6162177bab5SJohan Hedberg 
61742c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req)
6182177bab5SJohan Hedberg {
61942c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
6202177bab5SJohan Hedberg 	struct hci_cp_write_def_link_policy cp;
6212177bab5SJohan Hedberg 	u16 link_policy = 0;
6222177bab5SJohan Hedberg 
6232177bab5SJohan Hedberg 	if (lmp_rswitch_capable(hdev))
6242177bab5SJohan Hedberg 		link_policy |= HCI_LP_RSWITCH;
6252177bab5SJohan Hedberg 	if (lmp_hold_capable(hdev))
6262177bab5SJohan Hedberg 		link_policy |= HCI_LP_HOLD;
6272177bab5SJohan Hedberg 	if (lmp_sniff_capable(hdev))
6282177bab5SJohan Hedberg 		link_policy |= HCI_LP_SNIFF;
6292177bab5SJohan Hedberg 	if (lmp_park_capable(hdev))
6302177bab5SJohan Hedberg 		link_policy |= HCI_LP_PARK;
6312177bab5SJohan Hedberg 
6322177bab5SJohan Hedberg 	cp.policy = cpu_to_le16(link_policy);
63342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp);
6342177bab5SJohan Hedberg }
6352177bab5SJohan Hedberg 
63642c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req)
6372177bab5SJohan Hedberg {
63842c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
6392177bab5SJohan Hedberg 	struct hci_cp_write_le_host_supported cp;
6402177bab5SJohan Hedberg 
641c73eee91SJohan Hedberg 	/* LE-only devices do not support explicit enablement */
642c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
643c73eee91SJohan Hedberg 		return;
644c73eee91SJohan Hedberg 
6452177bab5SJohan Hedberg 	memset(&cp, 0, sizeof(cp));
6462177bab5SJohan Hedberg 
647d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_LE_ENABLED)) {
6482177bab5SJohan Hedberg 		cp.le = 0x01;
64932226e4fSMarcel Holtmann 		cp.simul = 0x00;
6502177bab5SJohan Hedberg 	}
6512177bab5SJohan Hedberg 
6522177bab5SJohan Hedberg 	if (cp.le != lmp_host_le_capable(hdev))
65342c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
6542177bab5SJohan Hedberg 			    &cp);
6552177bab5SJohan Hedberg }
6562177bab5SJohan Hedberg 
657d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req)
658d62e6d67SJohan Hedberg {
659d62e6d67SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
660d62e6d67SJohan Hedberg 	u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
661d62e6d67SJohan Hedberg 
662d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast master role is supported
663d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
664d62e6d67SJohan Hedberg 	 */
66553b834d2SMarcel Holtmann 	if (lmp_csb_master_capable(hdev)) {
666d62e6d67SJohan Hedberg 		events[1] |= 0x40;	/* Triggered Clock Capture */
667d62e6d67SJohan Hedberg 		events[1] |= 0x80;	/* Synchronization Train Complete */
668d62e6d67SJohan Hedberg 		events[2] |= 0x10;	/* Slave Page Response Timeout */
669d62e6d67SJohan Hedberg 		events[2] |= 0x20;	/* CSB Channel Map Change */
670d62e6d67SJohan Hedberg 	}
671d62e6d67SJohan Hedberg 
672d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast slave role is supported
673d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
674d62e6d67SJohan Hedberg 	 */
67553b834d2SMarcel Holtmann 	if (lmp_csb_slave_capable(hdev)) {
676d62e6d67SJohan Hedberg 		events[2] |= 0x01;	/* Synchronization Train Received */
677d62e6d67SJohan Hedberg 		events[2] |= 0x02;	/* CSB Receive */
678d62e6d67SJohan Hedberg 		events[2] |= 0x04;	/* CSB Timeout */
679d62e6d67SJohan Hedberg 		events[2] |= 0x08;	/* Truncated Page Complete */
680d62e6d67SJohan Hedberg 	}
681d62e6d67SJohan Hedberg 
68240c59fcbSMarcel Holtmann 	/* Enable Authenticated Payload Timeout Expired event if supported */
683cd7ca0ecSMarcel Holtmann 	if (lmp_ping_capable(hdev) || hdev->le_features[0] & HCI_LE_PING)
68440c59fcbSMarcel Holtmann 		events[2] |= 0x80;
68540c59fcbSMarcel Holtmann 
686d62e6d67SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events);
687d62e6d67SJohan Hedberg }
688d62e6d67SJohan Hedberg 
68942c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt)
6902177bab5SJohan Hedberg {
69142c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
692d2c5d77fSJohan Hedberg 	u8 p;
69342c6b129SJohan Hedberg 
6940da71f1bSMarcel Holtmann 	hci_setup_event_mask(req);
6950da71f1bSMarcel Holtmann 
696e81be90bSJohan Hedberg 	if (hdev->commands[6] & 0x20 &&
697e81be90bSJohan Hedberg 	    !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) {
69848ce62c4SMarcel Holtmann 		struct hci_cp_read_stored_link_key cp;
69948ce62c4SMarcel Holtmann 
70048ce62c4SMarcel Holtmann 		bacpy(&cp.bdaddr, BDADDR_ANY);
70148ce62c4SMarcel Holtmann 		cp.read_all = 0x01;
70248ce62c4SMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_STORED_LINK_KEY, sizeof(cp), &cp);
70348ce62c4SMarcel Holtmann 	}
70448ce62c4SMarcel Holtmann 
7052177bab5SJohan Hedberg 	if (hdev->commands[5] & 0x10)
70642c6b129SJohan Hedberg 		hci_setup_link_policy(req);
7072177bab5SJohan Hedberg 
708417287deSMarcel Holtmann 	if (hdev->commands[8] & 0x01)
709417287deSMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL);
710417287deSMarcel Holtmann 
711417287deSMarcel Holtmann 	/* Some older Broadcom based Bluetooth 1.2 controllers do not
712417287deSMarcel Holtmann 	 * support the Read Page Scan Type command. Check support for
713417287deSMarcel Holtmann 	 * this command in the bit mask of supported commands.
714417287deSMarcel Holtmann 	 */
715417287deSMarcel Holtmann 	if (hdev->commands[13] & 0x01)
716417287deSMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL);
717417287deSMarcel Holtmann 
7189193c6e8SAndre Guedes 	if (lmp_le_capable(hdev)) {
7199193c6e8SAndre Guedes 		u8 events[8];
7209193c6e8SAndre Guedes 
7219193c6e8SAndre Guedes 		memset(events, 0, sizeof(events));
7224d6c705bSMarcel Holtmann 		events[0] = 0x0f;
7234d6c705bSMarcel Holtmann 
7244d6c705bSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_ENCRYPTION)
7254d6c705bSMarcel Holtmann 			events[0] |= 0x10;	/* LE Long Term Key Request */
726662bc2e6SAndre Guedes 
727662bc2e6SAndre Guedes 		/* If controller supports the Connection Parameters Request
728662bc2e6SAndre Guedes 		 * Link Layer Procedure, enable the corresponding event.
729662bc2e6SAndre Guedes 		 */
730662bc2e6SAndre Guedes 		if (hdev->le_features[0] & HCI_LE_CONN_PARAM_REQ_PROC)
731662bc2e6SAndre Guedes 			events[0] |= 0x20;	/* LE Remote Connection
732662bc2e6SAndre Guedes 						 * Parameter Request
733662bc2e6SAndre Guedes 						 */
734662bc2e6SAndre Guedes 
735a9f6068eSMarcel Holtmann 		/* If the controller supports the Data Length Extension
736a9f6068eSMarcel Holtmann 		 * feature, enable the corresponding event.
737a9f6068eSMarcel Holtmann 		 */
738a9f6068eSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT)
739a9f6068eSMarcel Holtmann 			events[0] |= 0x40;	/* LE Data Length Change */
740a9f6068eSMarcel Holtmann 
7414b71bba4SMarcel Holtmann 		/* If the controller supports Extended Scanner Filter
7424b71bba4SMarcel Holtmann 		 * Policies, enable the correspondig event.
7434b71bba4SMarcel Holtmann 		 */
7444b71bba4SMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_EXT_SCAN_POLICY)
7454b71bba4SMarcel Holtmann 			events[1] |= 0x04;	/* LE Direct Advertising
7464b71bba4SMarcel Holtmann 						 * Report
7474b71bba4SMarcel Holtmann 						 */
7484b71bba4SMarcel Holtmann 
7495a34bd5fSMarcel Holtmann 		/* If the controller supports the LE Read Local P-256
7505a34bd5fSMarcel Holtmann 		 * Public Key command, enable the corresponding event.
7515a34bd5fSMarcel Holtmann 		 */
7525a34bd5fSMarcel Holtmann 		if (hdev->commands[34] & 0x02)
7535a34bd5fSMarcel Holtmann 			events[0] |= 0x80;	/* LE Read Local P-256
7545a34bd5fSMarcel Holtmann 						 * Public Key Complete
7555a34bd5fSMarcel Holtmann 						 */
7565a34bd5fSMarcel Holtmann 
7575a34bd5fSMarcel Holtmann 		/* If the controller supports the LE Generate DHKey
7585a34bd5fSMarcel Holtmann 		 * command, enable the corresponding event.
7595a34bd5fSMarcel Holtmann 		 */
7605a34bd5fSMarcel Holtmann 		if (hdev->commands[34] & 0x04)
7615a34bd5fSMarcel Holtmann 			events[1] |= 0x01;	/* LE Generate DHKey Complete */
7625a34bd5fSMarcel Holtmann 
7639193c6e8SAndre Guedes 		hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, sizeof(events),
7649193c6e8SAndre Guedes 			    events);
7659193c6e8SAndre Guedes 
76615a49ccaSMarcel Holtmann 		if (hdev->commands[25] & 0x40) {
76715a49ccaSMarcel Holtmann 			/* Read LE Advertising Channel TX Power */
76815a49ccaSMarcel Holtmann 			hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
76915a49ccaSMarcel Holtmann 		}
77015a49ccaSMarcel Holtmann 
771a9f6068eSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) {
772a9f6068eSMarcel Holtmann 			/* Read LE Maximum Data Length */
773a9f6068eSMarcel Holtmann 			hci_req_add(req, HCI_OP_LE_READ_MAX_DATA_LEN, 0, NULL);
774a9f6068eSMarcel Holtmann 
775a9f6068eSMarcel Holtmann 			/* Read LE Suggested Default Data Length */
776a9f6068eSMarcel Holtmann 			hci_req_add(req, HCI_OP_LE_READ_DEF_DATA_LEN, 0, NULL);
777a9f6068eSMarcel Holtmann 		}
778a9f6068eSMarcel Holtmann 
77942c6b129SJohan Hedberg 		hci_set_le_support(req);
7809193c6e8SAndre Guedes 	}
781d2c5d77fSJohan Hedberg 
782d2c5d77fSJohan Hedberg 	/* Read features beyond page 1 if available */
783d2c5d77fSJohan Hedberg 	for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
784d2c5d77fSJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
785d2c5d77fSJohan Hedberg 
786d2c5d77fSJohan Hedberg 		cp.page = p;
787d2c5d77fSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
788d2c5d77fSJohan Hedberg 			    sizeof(cp), &cp);
789d2c5d77fSJohan Hedberg 	}
7902177bab5SJohan Hedberg }
7912177bab5SJohan Hedberg 
7925d4e7e8dSJohan Hedberg static void hci_init4_req(struct hci_request *req, unsigned long opt)
7935d4e7e8dSJohan Hedberg {
7945d4e7e8dSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
7955d4e7e8dSJohan Hedberg 
79636f260ceSMarcel Holtmann 	/* Some Broadcom based Bluetooth controllers do not support the
79736f260ceSMarcel Holtmann 	 * Delete Stored Link Key command. They are clearly indicating its
79836f260ceSMarcel Holtmann 	 * absence in the bit mask of supported commands.
79936f260ceSMarcel Holtmann 	 *
80036f260ceSMarcel Holtmann 	 * Check the supported commands and only if the the command is marked
80136f260ceSMarcel Holtmann 	 * as supported send it. If not supported assume that the controller
80236f260ceSMarcel Holtmann 	 * does not have actual support for stored link keys which makes this
80336f260ceSMarcel Holtmann 	 * command redundant anyway.
80436f260ceSMarcel Holtmann 	 *
80536f260ceSMarcel Holtmann 	 * Some controllers indicate that they support handling deleting
80636f260ceSMarcel Holtmann 	 * stored link keys, but they don't. The quirk lets a driver
80736f260ceSMarcel Holtmann 	 * just disable this command.
80836f260ceSMarcel Holtmann 	 */
80936f260ceSMarcel Holtmann 	if (hdev->commands[6] & 0x80 &&
81036f260ceSMarcel Holtmann 	    !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) {
81136f260ceSMarcel Holtmann 		struct hci_cp_delete_stored_link_key cp;
81236f260ceSMarcel Holtmann 
81336f260ceSMarcel Holtmann 		bacpy(&cp.bdaddr, BDADDR_ANY);
81436f260ceSMarcel Holtmann 		cp.delete_all = 0x01;
81536f260ceSMarcel Holtmann 		hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY,
81636f260ceSMarcel Holtmann 			    sizeof(cp), &cp);
81736f260ceSMarcel Holtmann 	}
81836f260ceSMarcel Holtmann 
819d62e6d67SJohan Hedberg 	/* Set event mask page 2 if the HCI command for it is supported */
820d62e6d67SJohan Hedberg 	if (hdev->commands[22] & 0x04)
821d62e6d67SJohan Hedberg 		hci_set_event_mask_page_2(req);
822d62e6d67SJohan Hedberg 
823109e3191SMarcel Holtmann 	/* Read local codec list if the HCI command is supported */
824109e3191SMarcel Holtmann 	if (hdev->commands[29] & 0x20)
825109e3191SMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_LOCAL_CODECS, 0, NULL);
826109e3191SMarcel Holtmann 
827f4fe73edSMarcel Holtmann 	/* Get MWS transport configuration if the HCI command is supported */
828f4fe73edSMarcel Holtmann 	if (hdev->commands[30] & 0x08)
829f4fe73edSMarcel Holtmann 		hci_req_add(req, HCI_OP_GET_MWS_TRANSPORT_CONFIG, 0, NULL);
830f4fe73edSMarcel Holtmann 
8315d4e7e8dSJohan Hedberg 	/* Check for Synchronization Train support */
83253b834d2SMarcel Holtmann 	if (lmp_sync_train_capable(hdev))
8335d4e7e8dSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL);
834a6d0d690SMarcel Holtmann 
835a6d0d690SMarcel Holtmann 	/* Enable Secure Connections if supported and configured */
836d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED) &&
837574ea3c7SMarcel Holtmann 	    bredr_sc_enabled(hdev)) {
838a6d0d690SMarcel Holtmann 		u8 support = 0x01;
839574ea3c7SMarcel Holtmann 
840a6d0d690SMarcel Holtmann 		hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT,
841a6d0d690SMarcel Holtmann 			    sizeof(support), &support);
842a6d0d690SMarcel Holtmann 	}
8435d4e7e8dSJohan Hedberg }
8445d4e7e8dSJohan Hedberg 
8452177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev)
8462177bab5SJohan Hedberg {
8472177bab5SJohan Hedberg 	int err;
8482177bab5SJohan Hedberg 
8492177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT);
8502177bab5SJohan Hedberg 	if (err < 0)
8512177bab5SJohan Hedberg 		return err;
8522177bab5SJohan Hedberg 
8534b4148e9SMarcel Holtmann 	/* The Device Under Test (DUT) mode is special and available for
8544b4148e9SMarcel Holtmann 	 * all controller types. So just create it early on.
8554b4148e9SMarcel Holtmann 	 */
856d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP)) {
8574b4148e9SMarcel Holtmann 		debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev,
8584b4148e9SMarcel Holtmann 				    &dut_mode_fops);
8594b4148e9SMarcel Holtmann 	}
8604b4148e9SMarcel Holtmann 
8612177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT);
8622177bab5SJohan Hedberg 	if (err < 0)
8632177bab5SJohan Hedberg 		return err;
8642177bab5SJohan Hedberg 
8650af801b9SJohan Hedberg 	/* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode
8660af801b9SJohan Hedberg 	 * BR/EDR/LE type controllers. AMP controllers only need the
8670af801b9SJohan Hedberg 	 * first two stages of init.
8680af801b9SJohan Hedberg 	 */
8690af801b9SJohan Hedberg 	if (hdev->dev_type != HCI_BREDR)
8700af801b9SJohan Hedberg 		return 0;
8710af801b9SJohan Hedberg 
8725d4e7e8dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT);
8735d4e7e8dSJohan Hedberg 	if (err < 0)
8745d4e7e8dSJohan Hedberg 		return err;
8755d4e7e8dSJohan Hedberg 
876baf27f6eSMarcel Holtmann 	err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT);
877baf27f6eSMarcel Holtmann 	if (err < 0)
878baf27f6eSMarcel Holtmann 		return err;
879baf27f6eSMarcel Holtmann 
880ec6cef9cSMarcel Holtmann 	/* This function is only called when the controller is actually in
881ec6cef9cSMarcel Holtmann 	 * configured state. When the controller is marked as unconfigured,
882ec6cef9cSMarcel Holtmann 	 * this initialization procedure is not run.
883ec6cef9cSMarcel Holtmann 	 *
884ec6cef9cSMarcel Holtmann 	 * It means that it is possible that a controller runs through its
885ec6cef9cSMarcel Holtmann 	 * setup phase and then discovers missing settings. If that is the
886ec6cef9cSMarcel Holtmann 	 * case, then this function will not be called. It then will only
887ec6cef9cSMarcel Holtmann 	 * be called during the config phase.
888ec6cef9cSMarcel Holtmann 	 *
889ec6cef9cSMarcel Holtmann 	 * So only when in setup phase or config phase, create the debugfs
890ec6cef9cSMarcel Holtmann 	 * entries and register the SMP channels.
891baf27f6eSMarcel Holtmann 	 */
892d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
893d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONFIG))
894baf27f6eSMarcel Holtmann 		return 0;
895baf27f6eSMarcel Holtmann 
89660c5f5fbSMarcel Holtmann 	hci_debugfs_create_common(hdev);
89760c5f5fbSMarcel Holtmann 
89871c3b60eSMarcel Holtmann 	if (lmp_bredr_capable(hdev))
89960c5f5fbSMarcel Holtmann 		hci_debugfs_create_bredr(hdev);
9002bfa3531SMarcel Holtmann 
901162a3bacSMarcel Holtmann 	if (lmp_le_capable(hdev))
90260c5f5fbSMarcel Holtmann 		hci_debugfs_create_le(hdev);
903e7b8fc92SMarcel Holtmann 
904baf27f6eSMarcel Holtmann 	return 0;
9052177bab5SJohan Hedberg }
9062177bab5SJohan Hedberg 
9070ebca7d6SMarcel Holtmann static void hci_init0_req(struct hci_request *req, unsigned long opt)
9080ebca7d6SMarcel Holtmann {
9090ebca7d6SMarcel Holtmann 	struct hci_dev *hdev = req->hdev;
9100ebca7d6SMarcel Holtmann 
9110ebca7d6SMarcel Holtmann 	BT_DBG("%s %ld", hdev->name, opt);
9120ebca7d6SMarcel Holtmann 
9130ebca7d6SMarcel Holtmann 	/* Reset */
9140ebca7d6SMarcel Holtmann 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
9150ebca7d6SMarcel Holtmann 		hci_reset_req(req, 0);
9160ebca7d6SMarcel Holtmann 
9170ebca7d6SMarcel Holtmann 	/* Read Local Version */
9180ebca7d6SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
9190ebca7d6SMarcel Holtmann 
9200ebca7d6SMarcel Holtmann 	/* Read BD Address */
9210ebca7d6SMarcel Holtmann 	if (hdev->set_bdaddr)
9220ebca7d6SMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
9230ebca7d6SMarcel Holtmann }
9240ebca7d6SMarcel Holtmann 
9250ebca7d6SMarcel Holtmann static int __hci_unconf_init(struct hci_dev *hdev)
9260ebca7d6SMarcel Holtmann {
9270ebca7d6SMarcel Holtmann 	int err;
9280ebca7d6SMarcel Holtmann 
929cc78b44bSMarcel Holtmann 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
930cc78b44bSMarcel Holtmann 		return 0;
931cc78b44bSMarcel Holtmann 
9320ebca7d6SMarcel Holtmann 	err = __hci_req_sync(hdev, hci_init0_req, 0, HCI_INIT_TIMEOUT);
9330ebca7d6SMarcel Holtmann 	if (err < 0)
9340ebca7d6SMarcel Holtmann 		return err;
9350ebca7d6SMarcel Holtmann 
9360ebca7d6SMarcel Holtmann 	return 0;
9370ebca7d6SMarcel Holtmann }
9380ebca7d6SMarcel Holtmann 
93942c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt)
9401da177e4SLinus Torvalds {
9411da177e4SLinus Torvalds 	__u8 scan = opt;
9421da177e4SLinus Torvalds 
94342c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, scan);
9441da177e4SLinus Torvalds 
9451da177e4SLinus Torvalds 	/* Inquiry and Page scans */
94642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
9471da177e4SLinus Torvalds }
9481da177e4SLinus Torvalds 
94942c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt)
9501da177e4SLinus Torvalds {
9511da177e4SLinus Torvalds 	__u8 auth = opt;
9521da177e4SLinus Torvalds 
95342c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, auth);
9541da177e4SLinus Torvalds 
9551da177e4SLinus Torvalds 	/* Authentication */
95642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
9571da177e4SLinus Torvalds }
9581da177e4SLinus Torvalds 
95942c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt)
9601da177e4SLinus Torvalds {
9611da177e4SLinus Torvalds 	__u8 encrypt = opt;
9621da177e4SLinus Torvalds 
96342c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, encrypt);
9641da177e4SLinus Torvalds 
965e4e8e37cSMarcel Holtmann 	/* Encryption */
96642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
9671da177e4SLinus Torvalds }
9681da177e4SLinus Torvalds 
96942c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt)
970e4e8e37cSMarcel Holtmann {
971e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
972e4e8e37cSMarcel Holtmann 
97342c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, policy);
974e4e8e37cSMarcel Holtmann 
975e4e8e37cSMarcel Holtmann 	/* Default link policy */
97642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
977e4e8e37cSMarcel Holtmann }
978e4e8e37cSMarcel Holtmann 
9791da177e4SLinus Torvalds /* Get HCI device by index.
9801da177e4SLinus Torvalds  * Device is held on return. */
9811da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
9821da177e4SLinus Torvalds {
9838035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
9841da177e4SLinus Torvalds 
9851da177e4SLinus Torvalds 	BT_DBG("%d", index);
9861da177e4SLinus Torvalds 
9871da177e4SLinus Torvalds 	if (index < 0)
9881da177e4SLinus Torvalds 		return NULL;
9891da177e4SLinus Torvalds 
9901da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
9918035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
9921da177e4SLinus Torvalds 		if (d->id == index) {
9931da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
9941da177e4SLinus Torvalds 			break;
9951da177e4SLinus Torvalds 		}
9961da177e4SLinus Torvalds 	}
9971da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
9981da177e4SLinus Torvalds 	return hdev;
9991da177e4SLinus Torvalds }
10001da177e4SLinus Torvalds 
10011da177e4SLinus Torvalds /* ---- Inquiry support ---- */
1002ff9ef578SJohan Hedberg 
100330dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
100430dc78e1SJohan Hedberg {
100530dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
100630dc78e1SJohan Hedberg 
10076fbe195dSAndre Guedes 	switch (discov->state) {
1008343f935bSAndre Guedes 	case DISCOVERY_FINDING:
10096fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
101030dc78e1SJohan Hedberg 		return true;
101130dc78e1SJohan Hedberg 
10126fbe195dSAndre Guedes 	default:
101330dc78e1SJohan Hedberg 		return false;
101430dc78e1SJohan Hedberg 	}
10156fbe195dSAndre Guedes }
101630dc78e1SJohan Hedberg 
1017ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
1018ff9ef578SJohan Hedberg {
1019bb3e0a33SJohan Hedberg 	int old_state = hdev->discovery.state;
1020bb3e0a33SJohan Hedberg 
1021ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
1022ff9ef578SJohan Hedberg 
1023bb3e0a33SJohan Hedberg 	if (old_state == state)
1024ff9ef578SJohan Hedberg 		return;
1025ff9ef578SJohan Hedberg 
1026bb3e0a33SJohan Hedberg 	hdev->discovery.state = state;
1027bb3e0a33SJohan Hedberg 
1028ff9ef578SJohan Hedberg 	switch (state) {
1029ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
1030c54c3860SAndre Guedes 		hci_update_background_scan(hdev);
1031c54c3860SAndre Guedes 
1032bb3e0a33SJohan Hedberg 		if (old_state != DISCOVERY_STARTING)
1033ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
1034ff9ef578SJohan Hedberg 		break;
1035ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
1036ff9ef578SJohan Hedberg 		break;
1037343f935bSAndre Guedes 	case DISCOVERY_FINDING:
1038ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
1039ff9ef578SJohan Hedberg 		break;
104030dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
104130dc78e1SJohan Hedberg 		break;
1042ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
1043ff9ef578SJohan Hedberg 		break;
1044ff9ef578SJohan Hedberg 	}
1045ff9ef578SJohan Hedberg }
1046ff9ef578SJohan Hedberg 
10471f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev)
10481da177e4SLinus Torvalds {
104930883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1050b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
10511da177e4SLinus Torvalds 
1052561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
1053561aafbcSJohan Hedberg 		list_del(&p->all);
1054b57c1a56SJohan Hedberg 		kfree(p);
10551da177e4SLinus Torvalds 	}
1056561aafbcSJohan Hedberg 
1057561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
1058561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
10591da177e4SLinus Torvalds }
10601da177e4SLinus Torvalds 
1061a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
1062a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
10631da177e4SLinus Torvalds {
106430883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
10651da177e4SLinus Torvalds 	struct inquiry_entry *e;
10661da177e4SLinus Torvalds 
10676ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
10681da177e4SLinus Torvalds 
1069561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
10701da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
10711da177e4SLinus Torvalds 			return e;
10721da177e4SLinus Torvalds 	}
10731da177e4SLinus Torvalds 
1074b57c1a56SJohan Hedberg 	return NULL;
1075b57c1a56SJohan Hedberg }
1076b57c1a56SJohan Hedberg 
1077561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
1078561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
1079561aafbcSJohan Hedberg {
108030883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1081561aafbcSJohan Hedberg 	struct inquiry_entry *e;
1082561aafbcSJohan Hedberg 
10836ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
1084561aafbcSJohan Hedberg 
1085561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
1086561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
1087561aafbcSJohan Hedberg 			return e;
1088561aafbcSJohan Hedberg 	}
1089561aafbcSJohan Hedberg 
1090561aafbcSJohan Hedberg 	return NULL;
1091561aafbcSJohan Hedberg }
1092561aafbcSJohan Hedberg 
109330dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
109430dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
109530dc78e1SJohan Hedberg 						       int state)
109630dc78e1SJohan Hedberg {
109730dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
109830dc78e1SJohan Hedberg 	struct inquiry_entry *e;
109930dc78e1SJohan Hedberg 
11006ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
110130dc78e1SJohan Hedberg 
110230dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
110330dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
110430dc78e1SJohan Hedberg 			return e;
110530dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
110630dc78e1SJohan Hedberg 			return e;
110730dc78e1SJohan Hedberg 	}
110830dc78e1SJohan Hedberg 
110930dc78e1SJohan Hedberg 	return NULL;
111030dc78e1SJohan Hedberg }
111130dc78e1SJohan Hedberg 
1112a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
1113a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
1114a3d4e20aSJohan Hedberg {
1115a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1116a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
1117a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
1118a3d4e20aSJohan Hedberg 
1119a3d4e20aSJohan Hedberg 	list_del(&ie->list);
1120a3d4e20aSJohan Hedberg 
1121a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
1122a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
1123a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
1124a3d4e20aSJohan Hedberg 			break;
1125a3d4e20aSJohan Hedberg 		pos = &p->list;
1126a3d4e20aSJohan Hedberg 	}
1127a3d4e20aSJohan Hedberg 
1128a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
1129a3d4e20aSJohan Hedberg }
1130a3d4e20aSJohan Hedberg 
1131af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
1132af58925cSMarcel Holtmann 			     bool name_known)
11331da177e4SLinus Torvalds {
113430883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
113570f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
1136af58925cSMarcel Holtmann 	u32 flags = 0;
11371da177e4SLinus Torvalds 
11386ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
11391da177e4SLinus Torvalds 
11406928a924SJohan Hedberg 	hci_remove_remote_oob_data(hdev, &data->bdaddr, BDADDR_BREDR);
11412b2fec4dSSzymon Janc 
1142af58925cSMarcel Holtmann 	if (!data->ssp_mode)
1143af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
1144388fc8faSJohan Hedberg 
114570f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
1146a3d4e20aSJohan Hedberg 	if (ie) {
1147af58925cSMarcel Holtmann 		if (!ie->data.ssp_mode)
1148af58925cSMarcel Holtmann 			flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
1149388fc8faSJohan Hedberg 
1150a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
1151a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
1152a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
1153a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
1154a3d4e20aSJohan Hedberg 		}
1155a3d4e20aSJohan Hedberg 
1156561aafbcSJohan Hedberg 		goto update;
1157a3d4e20aSJohan Hedberg 	}
1158561aafbcSJohan Hedberg 
11591da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
116027f70f3eSJohan Hedberg 	ie = kzalloc(sizeof(*ie), GFP_KERNEL);
1161af58925cSMarcel Holtmann 	if (!ie) {
1162af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
1163af58925cSMarcel Holtmann 		goto done;
1164af58925cSMarcel Holtmann 	}
116570f23020SAndrei Emeltchenko 
1166561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
1167561aafbcSJohan Hedberg 
1168561aafbcSJohan Hedberg 	if (name_known) {
1169561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
1170561aafbcSJohan Hedberg 	} else {
1171561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
1172561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
1173561aafbcSJohan Hedberg 	}
1174561aafbcSJohan Hedberg 
1175561aafbcSJohan Hedberg update:
1176561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
1177561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
1178561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
1179561aafbcSJohan Hedberg 		list_del(&ie->list);
11801da177e4SLinus Torvalds 	}
11811da177e4SLinus Torvalds 
118270f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
118370f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
11841da177e4SLinus Torvalds 	cache->timestamp = jiffies;
11853175405bSJohan Hedberg 
11863175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
1187af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
11883175405bSJohan Hedberg 
1189af58925cSMarcel Holtmann done:
1190af58925cSMarcel Holtmann 	return flags;
11911da177e4SLinus Torvalds }
11921da177e4SLinus Torvalds 
11931da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
11941da177e4SLinus Torvalds {
119530883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
11961da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
11971da177e4SLinus Torvalds 	struct inquiry_entry *e;
11981da177e4SLinus Torvalds 	int copied = 0;
11991da177e4SLinus Torvalds 
1200561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
12011da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
1202b57c1a56SJohan Hedberg 
1203b57c1a56SJohan Hedberg 		if (copied >= num)
1204b57c1a56SJohan Hedberg 			break;
1205b57c1a56SJohan Hedberg 
12061da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
12071da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
12081da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
12091da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
12101da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
12111da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
1212b57c1a56SJohan Hedberg 
12131da177e4SLinus Torvalds 		info++;
1214b57c1a56SJohan Hedberg 		copied++;
12151da177e4SLinus Torvalds 	}
12161da177e4SLinus Torvalds 
12171da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
12181da177e4SLinus Torvalds 	return copied;
12191da177e4SLinus Torvalds }
12201da177e4SLinus Torvalds 
122142c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt)
12221da177e4SLinus Torvalds {
12231da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
122442c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
12251da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
12261da177e4SLinus Torvalds 
12271da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
12281da177e4SLinus Torvalds 
12291da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
12301da177e4SLinus Torvalds 		return;
12311da177e4SLinus Torvalds 
12321da177e4SLinus Torvalds 	/* Start Inquiry */
12331da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
12341da177e4SLinus Torvalds 	cp.length  = ir->length;
12351da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
123642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
12371da177e4SLinus Torvalds }
12381da177e4SLinus Torvalds 
12391da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
12401da177e4SLinus Torvalds {
12411da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
12421da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
12431da177e4SLinus Torvalds 	struct hci_dev *hdev;
12441da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
12451da177e4SLinus Torvalds 	long timeo;
12461da177e4SLinus Torvalds 	__u8 *buf;
12471da177e4SLinus Torvalds 
12481da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
12491da177e4SLinus Torvalds 		return -EFAULT;
12501da177e4SLinus Torvalds 
12515a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
12525a08ecceSAndrei Emeltchenko 	if (!hdev)
12531da177e4SLinus Torvalds 		return -ENODEV;
12541da177e4SLinus Torvalds 
1255d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
12560736cfa8SMarcel Holtmann 		err = -EBUSY;
12570736cfa8SMarcel Holtmann 		goto done;
12580736cfa8SMarcel Holtmann 	}
12590736cfa8SMarcel Holtmann 
1260d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
1261fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
1262fee746b0SMarcel Holtmann 		goto done;
1263fee746b0SMarcel Holtmann 	}
1264fee746b0SMarcel Holtmann 
12655b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
12665b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
12675b69bef5SMarcel Holtmann 		goto done;
12685b69bef5SMarcel Holtmann 	}
12695b69bef5SMarcel Holtmann 
1270d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
127156f87901SJohan Hedberg 		err = -EOPNOTSUPP;
127256f87901SJohan Hedberg 		goto done;
127356f87901SJohan Hedberg 	}
127456f87901SJohan Hedberg 
127509fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
12761da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
1277a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
12781f9b9a5dSAndre Guedes 		hci_inquiry_cache_flush(hdev);
12791da177e4SLinus Torvalds 		do_inquiry = 1;
12801da177e4SLinus Torvalds 	}
128109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
12821da177e4SLinus Torvalds 
128304837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
128470f23020SAndrei Emeltchenko 
128570f23020SAndrei Emeltchenko 	if (do_inquiry) {
128601178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
128701178cd4SJohan Hedberg 				   timeo);
128870f23020SAndrei Emeltchenko 		if (err < 0)
12891da177e4SLinus Torvalds 			goto done;
12903e13fa1eSAndre Guedes 
12913e13fa1eSAndre Guedes 		/* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
12923e13fa1eSAndre Guedes 		 * cleared). If it is interrupted by a signal, return -EINTR.
12933e13fa1eSAndre Guedes 		 */
129474316201SNeilBrown 		if (wait_on_bit(&hdev->flags, HCI_INQUIRY,
12953e13fa1eSAndre Guedes 				TASK_INTERRUPTIBLE))
12963e13fa1eSAndre Guedes 			return -EINTR;
129770f23020SAndrei Emeltchenko 	}
12981da177e4SLinus Torvalds 
12998fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
13008fc9ced3SGustavo Padovan 	 * 255 entries
13018fc9ced3SGustavo Padovan 	 */
13021da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
13031da177e4SLinus Torvalds 
13041da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
13051da177e4SLinus Torvalds 	 * copy it to the user space.
13061da177e4SLinus Torvalds 	 */
130770f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
130870f23020SAndrei Emeltchenko 	if (!buf) {
13091da177e4SLinus Torvalds 		err = -ENOMEM;
13101da177e4SLinus Torvalds 		goto done;
13111da177e4SLinus Torvalds 	}
13121da177e4SLinus Torvalds 
131309fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
13141da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
131509fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
13161da177e4SLinus Torvalds 
13171da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
13181da177e4SLinus Torvalds 
13191da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
13201da177e4SLinus Torvalds 		ptr += sizeof(ir);
13211da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
13221da177e4SLinus Torvalds 				 ir.num_rsp))
13231da177e4SLinus Torvalds 			err = -EFAULT;
13241da177e4SLinus Torvalds 	} else
13251da177e4SLinus Torvalds 		err = -EFAULT;
13261da177e4SLinus Torvalds 
13271da177e4SLinus Torvalds 	kfree(buf);
13281da177e4SLinus Torvalds 
13291da177e4SLinus Torvalds done:
13301da177e4SLinus Torvalds 	hci_dev_put(hdev);
13311da177e4SLinus Torvalds 	return err;
13321da177e4SLinus Torvalds }
13331da177e4SLinus Torvalds 
1334cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev)
13351da177e4SLinus Torvalds {
13361da177e4SLinus Torvalds 	int ret = 0;
13371da177e4SLinus Torvalds 
13381da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
13391da177e4SLinus Torvalds 
13401da177e4SLinus Torvalds 	hci_req_lock(hdev);
13411da177e4SLinus Torvalds 
1342d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
134394324962SJohan Hovold 		ret = -ENODEV;
134494324962SJohan Hovold 		goto done;
134594324962SJohan Hovold 	}
134694324962SJohan Hovold 
1347d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
1348d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONFIG)) {
1349a5c8f270SMarcel Holtmann 		/* Check for rfkill but allow the HCI setup stage to
1350a5c8f270SMarcel Holtmann 		 * proceed (which in itself doesn't cause any RF activity).
1351bf543036SJohan Hedberg 		 */
1352d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_RFKILLED)) {
1353611b30f7SMarcel Holtmann 			ret = -ERFKILL;
1354611b30f7SMarcel Holtmann 			goto done;
1355611b30f7SMarcel Holtmann 		}
1356611b30f7SMarcel Holtmann 
1357a5c8f270SMarcel Holtmann 		/* Check for valid public address or a configured static
1358a5c8f270SMarcel Holtmann 		 * random adddress, but let the HCI setup proceed to
1359a5c8f270SMarcel Holtmann 		 * be able to determine if there is a public address
1360a5c8f270SMarcel Holtmann 		 * or not.
1361a5c8f270SMarcel Holtmann 		 *
1362c6beca0eSMarcel Holtmann 		 * In case of user channel usage, it is not important
1363c6beca0eSMarcel Holtmann 		 * if a public address or static random address is
1364c6beca0eSMarcel Holtmann 		 * available.
1365c6beca0eSMarcel Holtmann 		 *
1366a5c8f270SMarcel Holtmann 		 * This check is only valid for BR/EDR controllers
1367a5c8f270SMarcel Holtmann 		 * since AMP controllers do not have an address.
1368a5c8f270SMarcel Holtmann 		 */
1369d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
1370c6beca0eSMarcel Holtmann 		    hdev->dev_type == HCI_BREDR &&
1371a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
1372a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->static_addr, BDADDR_ANY)) {
1373a5c8f270SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
1374a5c8f270SMarcel Holtmann 			goto done;
1375a5c8f270SMarcel Holtmann 		}
1376a5c8f270SMarcel Holtmann 	}
1377a5c8f270SMarcel Holtmann 
13781da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
13791da177e4SLinus Torvalds 		ret = -EALREADY;
13801da177e4SLinus Torvalds 		goto done;
13811da177e4SLinus Torvalds 	}
13821da177e4SLinus Torvalds 
13831da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
13841da177e4SLinus Torvalds 		ret = -EIO;
13851da177e4SLinus Torvalds 		goto done;
13861da177e4SLinus Torvalds 	}
13871da177e4SLinus Torvalds 
13881da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
13891da177e4SLinus Torvalds 	set_bit(HCI_INIT, &hdev->flags);
1390f41c70c4SMarcel Holtmann 
1391d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP)) {
1392af202f84SMarcel Holtmann 		if (hdev->setup)
1393f41c70c4SMarcel Holtmann 			ret = hdev->setup(hdev);
1394f41c70c4SMarcel Holtmann 
1395af202f84SMarcel Holtmann 		/* The transport driver can set these quirks before
1396af202f84SMarcel Holtmann 		 * creating the HCI device or in its setup callback.
1397af202f84SMarcel Holtmann 		 *
1398af202f84SMarcel Holtmann 		 * In case any of them is set, the controller has to
1399af202f84SMarcel Holtmann 		 * start up as unconfigured.
1400af202f84SMarcel Holtmann 		 */
1401eb1904f4SMarcel Holtmann 		if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) ||
1402eb1904f4SMarcel Holtmann 		    test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks))
1403a1536da2SMarcel Holtmann 			hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
1404f41c70c4SMarcel Holtmann 
14050ebca7d6SMarcel Holtmann 		/* For an unconfigured controller it is required to
14060ebca7d6SMarcel Holtmann 		 * read at least the version information provided by
14070ebca7d6SMarcel Holtmann 		 * the Read Local Version Information command.
14080ebca7d6SMarcel Holtmann 		 *
14090ebca7d6SMarcel Holtmann 		 * If the set_bdaddr driver callback is provided, then
14100ebca7d6SMarcel Holtmann 		 * also the original Bluetooth public device address
14110ebca7d6SMarcel Holtmann 		 * will be read using the Read BD Address command.
14120ebca7d6SMarcel Holtmann 		 */
1413d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
14140ebca7d6SMarcel Holtmann 			ret = __hci_unconf_init(hdev);
141589bc22d2SMarcel Holtmann 	}
141689bc22d2SMarcel Holtmann 
1417d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_CONFIG)) {
14189713c17bSMarcel Holtmann 		/* If public address change is configured, ensure that
14199713c17bSMarcel Holtmann 		 * the address gets programmed. If the driver does not
14209713c17bSMarcel Holtmann 		 * support changing the public address, fail the power
14219713c17bSMarcel Holtmann 		 * on procedure.
142224c457e2SMarcel Holtmann 		 */
14239713c17bSMarcel Holtmann 		if (bacmp(&hdev->public_addr, BDADDR_ANY) &&
14249713c17bSMarcel Holtmann 		    hdev->set_bdaddr)
142524c457e2SMarcel Holtmann 			ret = hdev->set_bdaddr(hdev, &hdev->public_addr);
142624c457e2SMarcel Holtmann 		else
142724c457e2SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
142824c457e2SMarcel Holtmann 	}
142924c457e2SMarcel Holtmann 
1430f41c70c4SMarcel Holtmann 	if (!ret) {
1431d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
1432d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
14332177bab5SJohan Hedberg 			ret = __hci_init(hdev);
14341da177e4SLinus Torvalds 	}
14351da177e4SLinus Torvalds 
1436f41c70c4SMarcel Holtmann 	clear_bit(HCI_INIT, &hdev->flags);
1437f41c70c4SMarcel Holtmann 
14381da177e4SLinus Torvalds 	if (!ret) {
14391da177e4SLinus Torvalds 		hci_dev_hold(hdev);
1440a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
14411da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
14421da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
1443d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
1444d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_CONFIG) &&
1445d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
1446d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
14471514b892SMarcel Holtmann 		    hdev->dev_type == HCI_BREDR) {
144809fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
1449744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
145009fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
145156e5cb86SJohan Hedberg 		}
14521da177e4SLinus Torvalds 	} else {
14531da177e4SLinus Torvalds 		/* Init failed, cleanup */
14543eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
1455c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
1456b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
14571da177e4SLinus Torvalds 
14581da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
14591da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
14601da177e4SLinus Torvalds 
14611da177e4SLinus Torvalds 		if (hdev->flush)
14621da177e4SLinus Torvalds 			hdev->flush(hdev);
14631da177e4SLinus Torvalds 
14641da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
14651da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
14661da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
14671da177e4SLinus Torvalds 		}
14681da177e4SLinus Torvalds 
14691da177e4SLinus Torvalds 		hdev->close(hdev);
1470fee746b0SMarcel Holtmann 		hdev->flags &= BIT(HCI_RAW);
14711da177e4SLinus Torvalds 	}
14721da177e4SLinus Torvalds 
14731da177e4SLinus Torvalds done:
14741da177e4SLinus Torvalds 	hci_req_unlock(hdev);
14751da177e4SLinus Torvalds 	return ret;
14761da177e4SLinus Torvalds }
14771da177e4SLinus Torvalds 
1478cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */
1479cbed0ca1SJohan Hedberg 
1480cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev)
1481cbed0ca1SJohan Hedberg {
1482cbed0ca1SJohan Hedberg 	struct hci_dev *hdev;
1483cbed0ca1SJohan Hedberg 	int err;
1484cbed0ca1SJohan Hedberg 
1485cbed0ca1SJohan Hedberg 	hdev = hci_dev_get(dev);
1486cbed0ca1SJohan Hedberg 	if (!hdev)
1487cbed0ca1SJohan Hedberg 		return -ENODEV;
1488cbed0ca1SJohan Hedberg 
14894a964404SMarcel Holtmann 	/* Devices that are marked as unconfigured can only be powered
1490fee746b0SMarcel Holtmann 	 * up as user channel. Trying to bring them up as normal devices
1491fee746b0SMarcel Holtmann 	 * will result into a failure. Only user channel operation is
1492fee746b0SMarcel Holtmann 	 * possible.
1493fee746b0SMarcel Holtmann 	 *
1494fee746b0SMarcel Holtmann 	 * When this function is called for a user channel, the flag
1495fee746b0SMarcel Holtmann 	 * HCI_USER_CHANNEL will be set first before attempting to
1496fee746b0SMarcel Holtmann 	 * open the device.
1497fee746b0SMarcel Holtmann 	 */
1498d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
1499d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
1500fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
1501fee746b0SMarcel Holtmann 		goto done;
1502fee746b0SMarcel Holtmann 	}
1503fee746b0SMarcel Holtmann 
1504e1d08f40SJohan Hedberg 	/* We need to ensure that no other power on/off work is pending
1505e1d08f40SJohan Hedberg 	 * before proceeding to call hci_dev_do_open. This is
1506e1d08f40SJohan Hedberg 	 * particularly important if the setup procedure has not yet
1507e1d08f40SJohan Hedberg 	 * completed.
1508e1d08f40SJohan Hedberg 	 */
1509a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF))
1510e1d08f40SJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
1511e1d08f40SJohan Hedberg 
1512a5c8f270SMarcel Holtmann 	/* After this call it is guaranteed that the setup procedure
1513a5c8f270SMarcel Holtmann 	 * has finished. This means that error conditions like RFKILL
1514a5c8f270SMarcel Holtmann 	 * or no valid public or static random address apply.
1515a5c8f270SMarcel Holtmann 	 */
1516e1d08f40SJohan Hedberg 	flush_workqueue(hdev->req_workqueue);
1517e1d08f40SJohan Hedberg 
151812aa4f0aSMarcel Holtmann 	/* For controllers not using the management interface and that
1519b6ae8457SJohan Hedberg 	 * are brought up using legacy ioctl, set the HCI_BONDABLE bit
152012aa4f0aSMarcel Holtmann 	 * so that pairing works for them. Once the management interface
152112aa4f0aSMarcel Holtmann 	 * is in use this bit will be cleared again and userspace has
152212aa4f0aSMarcel Holtmann 	 * to explicitly enable it.
152312aa4f0aSMarcel Holtmann 	 */
1524d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
1525d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_MGMT))
1526a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BONDABLE);
152712aa4f0aSMarcel Holtmann 
1528cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
1529cbed0ca1SJohan Hedberg 
1530fee746b0SMarcel Holtmann done:
1531cbed0ca1SJohan Hedberg 	hci_dev_put(hdev);
1532cbed0ca1SJohan Hedberg 	return err;
1533cbed0ca1SJohan Hedberg }
1534cbed0ca1SJohan Hedberg 
1535d7347f3cSJohan Hedberg /* This function requires the caller holds hdev->lock */
1536d7347f3cSJohan Hedberg static void hci_pend_le_actions_clear(struct hci_dev *hdev)
1537d7347f3cSJohan Hedberg {
1538d7347f3cSJohan Hedberg 	struct hci_conn_params *p;
1539d7347f3cSJohan Hedberg 
1540f161dd41SJohan Hedberg 	list_for_each_entry(p, &hdev->le_conn_params, list) {
1541f161dd41SJohan Hedberg 		if (p->conn) {
1542f161dd41SJohan Hedberg 			hci_conn_drop(p->conn);
1543f8aaf9b6SJohan Hedberg 			hci_conn_put(p->conn);
1544f161dd41SJohan Hedberg 			p->conn = NULL;
1545f161dd41SJohan Hedberg 		}
1546d7347f3cSJohan Hedberg 		list_del_init(&p->action);
1547f161dd41SJohan Hedberg 	}
1548d7347f3cSJohan Hedberg 
1549d7347f3cSJohan Hedberg 	BT_DBG("All LE pending actions cleared");
1550d7347f3cSJohan Hedberg }
1551d7347f3cSJohan Hedberg 
15526b3cc1dbSSimon Fels int hci_dev_do_close(struct hci_dev *hdev)
15531da177e4SLinus Torvalds {
15541da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
15551da177e4SLinus Torvalds 
1556d24d8144SGabriele Mazzotta 	if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) &&
1557867146a0SLoic Poulain 	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
1558d24d8144SGabriele Mazzotta 	    test_bit(HCI_UP, &hdev->flags)) {
1559a44fecbdSTedd Ho-Jeong An 		/* Execute vendor specific shutdown routine */
1560a44fecbdSTedd Ho-Jeong An 		if (hdev->shutdown)
1561a44fecbdSTedd Ho-Jeong An 			hdev->shutdown(hdev);
1562a44fecbdSTedd Ho-Jeong An 	}
1563a44fecbdSTedd Ho-Jeong An 
156478c04c0bSVinicius Costa Gomes 	cancel_delayed_work(&hdev->power_off);
156578c04c0bSVinicius Costa Gomes 
15661da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
15671da177e4SLinus Torvalds 	hci_req_lock(hdev);
15681da177e4SLinus Torvalds 
15691da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
157065cc2b49SMarcel Holtmann 		cancel_delayed_work_sync(&hdev->cmd_timer);
15711da177e4SLinus Torvalds 		hci_req_unlock(hdev);
15721da177e4SLinus Torvalds 		return 0;
15731da177e4SLinus Torvalds 	}
15741da177e4SLinus Torvalds 
15753eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
15763eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
1577b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
15781da177e4SLinus Torvalds 
157916ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
1580e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
158116ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
1582a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_DISCOVERABLE);
1583a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
158416ab91abSJohan Hedberg 	}
158516ab91abSJohan Hedberg 
1586a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_SERVICE_CACHE))
15877d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
15887d78525dSJohan Hedberg 
15897ba8b4beSAndre Guedes 	cancel_delayed_work_sync(&hdev->le_scan_disable);
15902d28cfe7SJakub Pawlowski 	cancel_delayed_work_sync(&hdev->le_scan_restart);
15914518bb0fSJohan Hedberg 
1592d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
1593d6bfd59cSJohan Hedberg 		cancel_delayed_work_sync(&hdev->rpa_expired);
15947ba8b4beSAndre Guedes 
15955d900e46SFlorian Grandel 	if (hdev->adv_instance_timeout) {
15965d900e46SFlorian Grandel 		cancel_delayed_work_sync(&hdev->adv_instance_expire);
15975d900e46SFlorian Grandel 		hdev->adv_instance_timeout = 0;
15985d900e46SFlorian Grandel 	}
15995d900e46SFlorian Grandel 
160076727c02SJohan Hedberg 	/* Avoid potential lockdep warnings from the *_flush() calls by
160176727c02SJohan Hedberg 	 * ensuring the workqueue is empty up front.
160276727c02SJohan Hedberg 	 */
160376727c02SJohan Hedberg 	drain_workqueue(hdev->workqueue);
160476727c02SJohan Hedberg 
160509fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
16061aeb9c65SJohan Hedberg 
16078f502f84SJohan Hedberg 	hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
16088f502f84SJohan Hedberg 
1609a69d8927SMarcel Holtmann 	if (!hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) {
16101aeb9c65SJohan Hedberg 		if (hdev->dev_type == HCI_BREDR)
16111aeb9c65SJohan Hedberg 			mgmt_powered(hdev, 0);
16121aeb9c65SJohan Hedberg 	}
16131aeb9c65SJohan Hedberg 
16141f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
1615d7347f3cSJohan Hedberg 	hci_pend_le_actions_clear(hdev);
1616f161dd41SJohan Hedberg 	hci_conn_hash_flush(hdev);
161709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
16181da177e4SLinus Torvalds 
161964dae967SMarcel Holtmann 	smp_unregister(hdev);
162064dae967SMarcel Holtmann 
16211da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
16221da177e4SLinus Torvalds 
16231da177e4SLinus Torvalds 	if (hdev->flush)
16241da177e4SLinus Torvalds 		hdev->flush(hdev);
16251da177e4SLinus Torvalds 
16261da177e4SLinus Torvalds 	/* Reset device */
16271da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
16281da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
1629d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_AUTO_OFF) &&
1630d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
1631a6c511c6SSzymon Janc 	    test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
16321da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
163301178cd4SJohan Hedberg 		__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
16341da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
16351da177e4SLinus Torvalds 	}
16361da177e4SLinus Torvalds 
1637c347b765SGustavo F. Padovan 	/* flush cmd  work */
1638c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
16391da177e4SLinus Torvalds 
16401da177e4SLinus Torvalds 	/* Drop queues */
16411da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
16421da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
16431da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
16441da177e4SLinus Torvalds 
16451da177e4SLinus Torvalds 	/* Drop last sent command */
16461da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
164765cc2b49SMarcel Holtmann 		cancel_delayed_work_sync(&hdev->cmd_timer);
16481da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
16491da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
16501da177e4SLinus Torvalds 	}
16511da177e4SLinus Torvalds 
16521da177e4SLinus Torvalds 	/* After this point our queues are empty
16531da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
16541da177e4SLinus Torvalds 	hdev->close(hdev);
16551da177e4SLinus Torvalds 
165635b973c9SJohan Hedberg 	/* Clear flags */
1657fee746b0SMarcel Holtmann 	hdev->flags &= BIT(HCI_RAW);
1658eacb44dfSMarcel Holtmann 	hci_dev_clear_volatile_flags(hdev);
165935b973c9SJohan Hedberg 
1660ced5c338SAndrei Emeltchenko 	/* Controller radio is available but is currently powered down */
1661536619e8SMarcel Holtmann 	hdev->amp_status = AMP_STATUS_POWERED_DOWN;
1662ced5c338SAndrei Emeltchenko 
1663e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
166409b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
16657a4cd51dSMarcel Holtmann 	bacpy(&hdev->random_addr, BDADDR_ANY);
1666e59fda8dSJohan Hedberg 
16671da177e4SLinus Torvalds 	hci_req_unlock(hdev);
16681da177e4SLinus Torvalds 
16691da177e4SLinus Torvalds 	hci_dev_put(hdev);
16701da177e4SLinus Torvalds 	return 0;
16711da177e4SLinus Torvalds }
16721da177e4SLinus Torvalds 
16731da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
16741da177e4SLinus Torvalds {
16751da177e4SLinus Torvalds 	struct hci_dev *hdev;
16761da177e4SLinus Torvalds 	int err;
16771da177e4SLinus Torvalds 
167870f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
167970f23020SAndrei Emeltchenko 	if (!hdev)
16801da177e4SLinus Torvalds 		return -ENODEV;
16818ee56540SMarcel Holtmann 
1682d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
16830736cfa8SMarcel Holtmann 		err = -EBUSY;
16840736cfa8SMarcel Holtmann 		goto done;
16850736cfa8SMarcel Holtmann 	}
16860736cfa8SMarcel Holtmann 
1687a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF))
16888ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
16898ee56540SMarcel Holtmann 
16901da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
16918ee56540SMarcel Holtmann 
16920736cfa8SMarcel Holtmann done:
16931da177e4SLinus Torvalds 	hci_dev_put(hdev);
16941da177e4SLinus Torvalds 	return err;
16951da177e4SLinus Torvalds }
16961da177e4SLinus Torvalds 
16975c912495SMarcel Holtmann static int hci_dev_do_reset(struct hci_dev *hdev)
16981da177e4SLinus Torvalds {
16995c912495SMarcel Holtmann 	int ret;
17001da177e4SLinus Torvalds 
17015c912495SMarcel Holtmann 	BT_DBG("%s %p", hdev->name, hdev);
17021da177e4SLinus Torvalds 
17031da177e4SLinus Torvalds 	hci_req_lock(hdev);
17041da177e4SLinus Torvalds 
17051da177e4SLinus Torvalds 	/* Drop queues */
17061da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
17071da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
17081da177e4SLinus Torvalds 
170976727c02SJohan Hedberg 	/* Avoid potential lockdep warnings from the *_flush() calls by
171076727c02SJohan Hedberg 	 * ensuring the workqueue is empty up front.
171176727c02SJohan Hedberg 	 */
171276727c02SJohan Hedberg 	drain_workqueue(hdev->workqueue);
171376727c02SJohan Hedberg 
171409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
17151f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
17161da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
171709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
17181da177e4SLinus Torvalds 
17191da177e4SLinus Torvalds 	if (hdev->flush)
17201da177e4SLinus Torvalds 		hdev->flush(hdev);
17211da177e4SLinus Torvalds 
17221da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
17236ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
17241da177e4SLinus Torvalds 
172501178cd4SJohan Hedberg 	ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
17261da177e4SLinus Torvalds 
17271da177e4SLinus Torvalds 	hci_req_unlock(hdev);
17281da177e4SLinus Torvalds 	return ret;
17291da177e4SLinus Torvalds }
17301da177e4SLinus Torvalds 
17315c912495SMarcel Holtmann int hci_dev_reset(__u16 dev)
17325c912495SMarcel Holtmann {
17335c912495SMarcel Holtmann 	struct hci_dev *hdev;
17345c912495SMarcel Holtmann 	int err;
17355c912495SMarcel Holtmann 
17365c912495SMarcel Holtmann 	hdev = hci_dev_get(dev);
17375c912495SMarcel Holtmann 	if (!hdev)
17385c912495SMarcel Holtmann 		return -ENODEV;
17395c912495SMarcel Holtmann 
17405c912495SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
17415c912495SMarcel Holtmann 		err = -ENETDOWN;
17425c912495SMarcel Holtmann 		goto done;
17435c912495SMarcel Holtmann 	}
17445c912495SMarcel Holtmann 
1745d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
17465c912495SMarcel Holtmann 		err = -EBUSY;
17475c912495SMarcel Holtmann 		goto done;
17485c912495SMarcel Holtmann 	}
17495c912495SMarcel Holtmann 
1750d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
17515c912495SMarcel Holtmann 		err = -EOPNOTSUPP;
17525c912495SMarcel Holtmann 		goto done;
17535c912495SMarcel Holtmann 	}
17545c912495SMarcel Holtmann 
17555c912495SMarcel Holtmann 	err = hci_dev_do_reset(hdev);
17565c912495SMarcel Holtmann 
17575c912495SMarcel Holtmann done:
17585c912495SMarcel Holtmann 	hci_dev_put(hdev);
17595c912495SMarcel Holtmann 	return err;
17605c912495SMarcel Holtmann }
17615c912495SMarcel Holtmann 
17621da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
17631da177e4SLinus Torvalds {
17641da177e4SLinus Torvalds 	struct hci_dev *hdev;
17651da177e4SLinus Torvalds 	int ret = 0;
17661da177e4SLinus Torvalds 
176770f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
176870f23020SAndrei Emeltchenko 	if (!hdev)
17691da177e4SLinus Torvalds 		return -ENODEV;
17701da177e4SLinus Torvalds 
1771d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
17720736cfa8SMarcel Holtmann 		ret = -EBUSY;
17730736cfa8SMarcel Holtmann 		goto done;
17740736cfa8SMarcel Holtmann 	}
17750736cfa8SMarcel Holtmann 
1776d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
1777fee746b0SMarcel Holtmann 		ret = -EOPNOTSUPP;
1778fee746b0SMarcel Holtmann 		goto done;
1779fee746b0SMarcel Holtmann 	}
1780fee746b0SMarcel Holtmann 
17811da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
17821da177e4SLinus Torvalds 
17830736cfa8SMarcel Holtmann done:
17841da177e4SLinus Torvalds 	hci_dev_put(hdev);
17851da177e4SLinus Torvalds 	return ret;
17861da177e4SLinus Torvalds }
17871da177e4SLinus Torvalds 
1788123abc08SJohan Hedberg static void hci_update_scan_state(struct hci_dev *hdev, u8 scan)
1789123abc08SJohan Hedberg {
1790bc6d2d04SJohan Hedberg 	bool conn_changed, discov_changed;
1791123abc08SJohan Hedberg 
1792123abc08SJohan Hedberg 	BT_DBG("%s scan 0x%02x", hdev->name, scan);
1793123abc08SJohan Hedberg 
1794123abc08SJohan Hedberg 	if ((scan & SCAN_PAGE))
1795238be788SMarcel Holtmann 		conn_changed = !hci_dev_test_and_set_flag(hdev,
1796238be788SMarcel Holtmann 							  HCI_CONNECTABLE);
1797123abc08SJohan Hedberg 	else
1798a69d8927SMarcel Holtmann 		conn_changed = hci_dev_test_and_clear_flag(hdev,
1799a69d8927SMarcel Holtmann 							   HCI_CONNECTABLE);
1800123abc08SJohan Hedberg 
1801bc6d2d04SJohan Hedberg 	if ((scan & SCAN_INQUIRY)) {
1802238be788SMarcel Holtmann 		discov_changed = !hci_dev_test_and_set_flag(hdev,
1803238be788SMarcel Holtmann 							    HCI_DISCOVERABLE);
1804bc6d2d04SJohan Hedberg 	} else {
1805a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
1806a69d8927SMarcel Holtmann 		discov_changed = hci_dev_test_and_clear_flag(hdev,
1807a69d8927SMarcel Holtmann 							     HCI_DISCOVERABLE);
1808bc6d2d04SJohan Hedberg 	}
1809bc6d2d04SJohan Hedberg 
1810d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
1811123abc08SJohan Hedberg 		return;
1812123abc08SJohan Hedberg 
1813bc6d2d04SJohan Hedberg 	if (conn_changed || discov_changed) {
1814bc6d2d04SJohan Hedberg 		/* In case this was disabled through mgmt */
1815a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
1816bc6d2d04SJohan Hedberg 
1817d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_LE_ENABLED))
1818bc6d2d04SJohan Hedberg 			mgmt_update_adv_data(hdev);
1819bc6d2d04SJohan Hedberg 
1820123abc08SJohan Hedberg 		mgmt_new_settings(hdev);
1821123abc08SJohan Hedberg 	}
1822bc6d2d04SJohan Hedberg }
1823123abc08SJohan Hedberg 
18241da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
18251da177e4SLinus Torvalds {
18261da177e4SLinus Torvalds 	struct hci_dev *hdev;
18271da177e4SLinus Torvalds 	struct hci_dev_req dr;
18281da177e4SLinus Torvalds 	int err = 0;
18291da177e4SLinus Torvalds 
18301da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
18311da177e4SLinus Torvalds 		return -EFAULT;
18321da177e4SLinus Torvalds 
183370f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
183470f23020SAndrei Emeltchenko 	if (!hdev)
18351da177e4SLinus Torvalds 		return -ENODEV;
18361da177e4SLinus Torvalds 
1837d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
18380736cfa8SMarcel Holtmann 		err = -EBUSY;
18390736cfa8SMarcel Holtmann 		goto done;
18400736cfa8SMarcel Holtmann 	}
18410736cfa8SMarcel Holtmann 
1842d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
1843fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
1844fee746b0SMarcel Holtmann 		goto done;
1845fee746b0SMarcel Holtmann 	}
1846fee746b0SMarcel Holtmann 
18475b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
18485b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
18495b69bef5SMarcel Holtmann 		goto done;
18505b69bef5SMarcel Holtmann 	}
18515b69bef5SMarcel Holtmann 
1852d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
185356f87901SJohan Hedberg 		err = -EOPNOTSUPP;
185456f87901SJohan Hedberg 		goto done;
185556f87901SJohan Hedberg 	}
185656f87901SJohan Hedberg 
18571da177e4SLinus Torvalds 	switch (cmd) {
18581da177e4SLinus Torvalds 	case HCISETAUTH:
185901178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
18605f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
18611da177e4SLinus Torvalds 		break;
18621da177e4SLinus Torvalds 
18631da177e4SLinus Torvalds 	case HCISETENCRYPT:
18641da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
18651da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
18661da177e4SLinus Torvalds 			break;
18671da177e4SLinus Torvalds 		}
18681da177e4SLinus Torvalds 
18691da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
18701da177e4SLinus Torvalds 			/* Auth must be enabled first */
187101178cd4SJohan Hedberg 			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
18725f246e89SAndrei Emeltchenko 					   HCI_INIT_TIMEOUT);
18731da177e4SLinus Torvalds 			if (err)
18741da177e4SLinus Torvalds 				break;
18751da177e4SLinus Torvalds 		}
18761da177e4SLinus Torvalds 
187701178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
18785f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
18791da177e4SLinus Torvalds 		break;
18801da177e4SLinus Torvalds 
18811da177e4SLinus Torvalds 	case HCISETSCAN:
188201178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
18835f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
188491a668b0SJohan Hedberg 
1885bc6d2d04SJohan Hedberg 		/* Ensure that the connectable and discoverable states
1886bc6d2d04SJohan Hedberg 		 * get correctly modified as this was a non-mgmt change.
188791a668b0SJohan Hedberg 		 */
1888123abc08SJohan Hedberg 		if (!err)
1889123abc08SJohan Hedberg 			hci_update_scan_state(hdev, dr.dev_opt);
18901da177e4SLinus Torvalds 		break;
18911da177e4SLinus Torvalds 
18921da177e4SLinus Torvalds 	case HCISETLINKPOL:
189301178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
18945f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
18951da177e4SLinus Torvalds 		break;
18961da177e4SLinus Torvalds 
18971da177e4SLinus Torvalds 	case HCISETLINKMODE:
1898e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
1899e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
1900e4e8e37cSMarcel Holtmann 		break;
1901e4e8e37cSMarcel Holtmann 
1902e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
1903e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
19041da177e4SLinus Torvalds 		break;
19051da177e4SLinus Torvalds 
19061da177e4SLinus Torvalds 	case HCISETACLMTU:
19071da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
19081da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
19091da177e4SLinus Torvalds 		break;
19101da177e4SLinus Torvalds 
19111da177e4SLinus Torvalds 	case HCISETSCOMTU:
19121da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
19131da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
19141da177e4SLinus Torvalds 		break;
19151da177e4SLinus Torvalds 
19161da177e4SLinus Torvalds 	default:
19171da177e4SLinus Torvalds 		err = -EINVAL;
19181da177e4SLinus Torvalds 		break;
19191da177e4SLinus Torvalds 	}
1920e4e8e37cSMarcel Holtmann 
19210736cfa8SMarcel Holtmann done:
19221da177e4SLinus Torvalds 	hci_dev_put(hdev);
19231da177e4SLinus Torvalds 	return err;
19241da177e4SLinus Torvalds }
19251da177e4SLinus Torvalds 
19261da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
19271da177e4SLinus Torvalds {
19288035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
19291da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
19301da177e4SLinus Torvalds 	struct hci_dev_req *dr;
19311da177e4SLinus Torvalds 	int n = 0, size, err;
19321da177e4SLinus Torvalds 	__u16 dev_num;
19331da177e4SLinus Torvalds 
19341da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
19351da177e4SLinus Torvalds 		return -EFAULT;
19361da177e4SLinus Torvalds 
19371da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
19381da177e4SLinus Torvalds 		return -EINVAL;
19391da177e4SLinus Torvalds 
19401da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
19411da177e4SLinus Torvalds 
194270f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
194370f23020SAndrei Emeltchenko 	if (!dl)
19441da177e4SLinus Torvalds 		return -ENOMEM;
19451da177e4SLinus Torvalds 
19461da177e4SLinus Torvalds 	dr = dl->dev_req;
19471da177e4SLinus Torvalds 
1948f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
19498035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
19502e84d8dbSMarcel Holtmann 		unsigned long flags = hdev->flags;
1951c542a06cSJohan Hedberg 
19522e84d8dbSMarcel Holtmann 		/* When the auto-off is configured it means the transport
19532e84d8dbSMarcel Holtmann 		 * is running, but in that case still indicate that the
19542e84d8dbSMarcel Holtmann 		 * device is actually down.
19552e84d8dbSMarcel Holtmann 		 */
1956d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_AUTO_OFF))
19572e84d8dbSMarcel Holtmann 			flags &= ~BIT(HCI_UP);
1958c542a06cSJohan Hedberg 
19591da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
19602e84d8dbSMarcel Holtmann 		(dr + n)->dev_opt = flags;
1961c542a06cSJohan Hedberg 
19621da177e4SLinus Torvalds 		if (++n >= dev_num)
19631da177e4SLinus Torvalds 			break;
19641da177e4SLinus Torvalds 	}
1965f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
19661da177e4SLinus Torvalds 
19671da177e4SLinus Torvalds 	dl->dev_num = n;
19681da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
19691da177e4SLinus Torvalds 
19701da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
19711da177e4SLinus Torvalds 	kfree(dl);
19721da177e4SLinus Torvalds 
19731da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
19741da177e4SLinus Torvalds }
19751da177e4SLinus Torvalds 
19761da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
19771da177e4SLinus Torvalds {
19781da177e4SLinus Torvalds 	struct hci_dev *hdev;
19791da177e4SLinus Torvalds 	struct hci_dev_info di;
19802e84d8dbSMarcel Holtmann 	unsigned long flags;
19811da177e4SLinus Torvalds 	int err = 0;
19821da177e4SLinus Torvalds 
19831da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
19841da177e4SLinus Torvalds 		return -EFAULT;
19851da177e4SLinus Torvalds 
198670f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
198770f23020SAndrei Emeltchenko 	if (!hdev)
19881da177e4SLinus Torvalds 		return -ENODEV;
19891da177e4SLinus Torvalds 
19902e84d8dbSMarcel Holtmann 	/* When the auto-off is configured it means the transport
19912e84d8dbSMarcel Holtmann 	 * is running, but in that case still indicate that the
19922e84d8dbSMarcel Holtmann 	 * device is actually down.
19932e84d8dbSMarcel Holtmann 	 */
1994d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_AUTO_OFF))
19952e84d8dbSMarcel Holtmann 		flags = hdev->flags & ~BIT(HCI_UP);
19962e84d8dbSMarcel Holtmann 	else
19972e84d8dbSMarcel Holtmann 		flags = hdev->flags;
1998c542a06cSJohan Hedberg 
19991da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
20001da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
200160f2a3edSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4);
20022e84d8dbSMarcel Holtmann 	di.flags    = flags;
20031da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
2004572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
20051da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
20061da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
20071da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
20081da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
2009572c7f84SJohan Hedberg 	} else {
2010572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
2011572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
2012572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
2013572c7f84SJohan Hedberg 		di.sco_pkts = 0;
2014572c7f84SJohan Hedberg 	}
20151da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
20161da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
20171da177e4SLinus Torvalds 
20181da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
20191da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
20201da177e4SLinus Torvalds 
20211da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
20221da177e4SLinus Torvalds 		err = -EFAULT;
20231da177e4SLinus Torvalds 
20241da177e4SLinus Torvalds 	hci_dev_put(hdev);
20251da177e4SLinus Torvalds 
20261da177e4SLinus Torvalds 	return err;
20271da177e4SLinus Torvalds }
20281da177e4SLinus Torvalds 
20291da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
20301da177e4SLinus Torvalds 
2031611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
2032611b30f7SMarcel Holtmann {
2033611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
2034611b30f7SMarcel Holtmann 
2035611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
2036611b30f7SMarcel Holtmann 
2037d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
20380736cfa8SMarcel Holtmann 		return -EBUSY;
20390736cfa8SMarcel Holtmann 
20405e130367SJohan Hedberg 	if (blocked) {
2041a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RFKILLED);
2042d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
2043d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_CONFIG))
2044611b30f7SMarcel Holtmann 			hci_dev_do_close(hdev);
20455e130367SJohan Hedberg 	} else {
2046a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_RFKILLED);
20475e130367SJohan Hedberg 	}
2048611b30f7SMarcel Holtmann 
2049611b30f7SMarcel Holtmann 	return 0;
2050611b30f7SMarcel Holtmann }
2051611b30f7SMarcel Holtmann 
2052611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
2053611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
2054611b30f7SMarcel Holtmann };
2055611b30f7SMarcel Holtmann 
2056ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
2057ab81cbf9SJohan Hedberg {
2058ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
205996570ffcSJohan Hedberg 	int err;
2060ab81cbf9SJohan Hedberg 
2061ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
2062ab81cbf9SJohan Hedberg 
2063cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
206496570ffcSJohan Hedberg 	if (err < 0) {
20653ad67582SJaganath Kanakkassery 		hci_dev_lock(hdev);
206696570ffcSJohan Hedberg 		mgmt_set_powered_failed(hdev, err);
20673ad67582SJaganath Kanakkassery 		hci_dev_unlock(hdev);
2068ab81cbf9SJohan Hedberg 		return;
206996570ffcSJohan Hedberg 	}
2070ab81cbf9SJohan Hedberg 
2071a5c8f270SMarcel Holtmann 	/* During the HCI setup phase, a few error conditions are
2072a5c8f270SMarcel Holtmann 	 * ignored and they need to be checked now. If they are still
2073a5c8f270SMarcel Holtmann 	 * valid, it is important to turn the device back off.
2074a5c8f270SMarcel Holtmann 	 */
2075d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_RFKILLED) ||
2076d7a5a11dSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_UNCONFIGURED) ||
2077a5c8f270SMarcel Holtmann 	    (hdev->dev_type == HCI_BREDR &&
2078a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
2079a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->static_addr, BDADDR_ANY))) {
2080a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_AUTO_OFF);
2081bf543036SJohan Hedberg 		hci_dev_do_close(hdev);
2082d7a5a11dSMarcel Holtmann 	} else if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) {
208319202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
208419202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
2085bf543036SJohan Hedberg 	}
2086ab81cbf9SJohan Hedberg 
2087a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_SETUP)) {
20884a964404SMarcel Holtmann 		/* For unconfigured devices, set the HCI_RAW flag
20894a964404SMarcel Holtmann 		 * so that userspace can easily identify them.
20904a964404SMarcel Holtmann 		 */
2091d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
20924a964404SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
20930602a8adSMarcel Holtmann 
20940602a8adSMarcel Holtmann 		/* For fully configured devices, this will send
20950602a8adSMarcel Holtmann 		 * the Index Added event. For unconfigured devices,
20960602a8adSMarcel Holtmann 		 * it will send Unconfigued Index Added event.
20970602a8adSMarcel Holtmann 		 *
20980602a8adSMarcel Holtmann 		 * Devices with HCI_QUIRK_RAW_DEVICE are ignored
20990602a8adSMarcel Holtmann 		 * and no event will be send.
21000602a8adSMarcel Holtmann 		 */
2101744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
2102a69d8927SMarcel Holtmann 	} else if (hci_dev_test_and_clear_flag(hdev, HCI_CONFIG)) {
21035ea234d3SMarcel Holtmann 		/* When the controller is now configured, then it
21045ea234d3SMarcel Holtmann 		 * is important to clear the HCI_RAW flag.
21055ea234d3SMarcel Holtmann 		 */
2106d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
21075ea234d3SMarcel Holtmann 			clear_bit(HCI_RAW, &hdev->flags);
21085ea234d3SMarcel Holtmann 
2109d603b76bSMarcel Holtmann 		/* Powering on the controller with HCI_CONFIG set only
2110d603b76bSMarcel Holtmann 		 * happens with the transition from unconfigured to
2111d603b76bSMarcel Holtmann 		 * configured. This will send the Index Added event.
2112d603b76bSMarcel Holtmann 		 */
2113d603b76bSMarcel Holtmann 		mgmt_index_added(hdev);
2114ab81cbf9SJohan Hedberg 	}
2115ab81cbf9SJohan Hedberg }
2116ab81cbf9SJohan Hedberg 
2117ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
2118ab81cbf9SJohan Hedberg {
21193243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
21203243553fSJohan Hedberg 					    power_off.work);
2121ab81cbf9SJohan Hedberg 
2122ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
2123ab81cbf9SJohan Hedberg 
21248ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
2125ab81cbf9SJohan Hedberg }
2126ab81cbf9SJohan Hedberg 
2127c7741d16SMarcel Holtmann static void hci_error_reset(struct work_struct *work)
2128c7741d16SMarcel Holtmann {
2129c7741d16SMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, error_reset);
2130c7741d16SMarcel Holtmann 
2131c7741d16SMarcel Holtmann 	BT_DBG("%s", hdev->name);
2132c7741d16SMarcel Holtmann 
2133c7741d16SMarcel Holtmann 	if (hdev->hw_error)
2134c7741d16SMarcel Holtmann 		hdev->hw_error(hdev, hdev->hw_error_code);
2135c7741d16SMarcel Holtmann 	else
2136c7741d16SMarcel Holtmann 		BT_ERR("%s hardware error 0x%2.2x", hdev->name,
2137c7741d16SMarcel Holtmann 		       hdev->hw_error_code);
2138c7741d16SMarcel Holtmann 
2139c7741d16SMarcel Holtmann 	if (hci_dev_do_close(hdev))
2140c7741d16SMarcel Holtmann 		return;
2141c7741d16SMarcel Holtmann 
2142c7741d16SMarcel Holtmann 	hci_dev_do_open(hdev);
2143c7741d16SMarcel Holtmann }
2144c7741d16SMarcel Holtmann 
214516ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
214616ab91abSJohan Hedberg {
214716ab91abSJohan Hedberg 	struct hci_dev *hdev;
214816ab91abSJohan Hedberg 
214916ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
215016ab91abSJohan Hedberg 
215116ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
215216ab91abSJohan Hedberg 
2153d1967ff8SMarcel Holtmann 	mgmt_discoverable_timeout(hdev);
215416ab91abSJohan Hedberg }
215516ab91abSJohan Hedberg 
21565d900e46SFlorian Grandel static void hci_adv_timeout_expire(struct work_struct *work)
21575d900e46SFlorian Grandel {
21585d900e46SFlorian Grandel 	struct hci_dev *hdev;
21595d900e46SFlorian Grandel 
21605d900e46SFlorian Grandel 	hdev = container_of(work, struct hci_dev, adv_instance_expire.work);
21615d900e46SFlorian Grandel 
21625d900e46SFlorian Grandel 	BT_DBG("%s", hdev->name);
21635d900e46SFlorian Grandel 
21645d900e46SFlorian Grandel 	mgmt_adv_timeout_expired(hdev);
21655d900e46SFlorian Grandel }
21665d900e46SFlorian Grandel 
216735f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev)
21682aeb9a1aSJohan Hedberg {
21694821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
21702aeb9a1aSJohan Hedberg 
21714821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
21724821002cSJohan Hedberg 		list_del(&uuid->list);
21732aeb9a1aSJohan Hedberg 		kfree(uuid);
21742aeb9a1aSJohan Hedberg 	}
21752aeb9a1aSJohan Hedberg }
21762aeb9a1aSJohan Hedberg 
217735f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev)
217855ed8ca1SJohan Hedberg {
217955ed8ca1SJohan Hedberg 	struct link_key *key;
218055ed8ca1SJohan Hedberg 
21810378b597SJohan Hedberg 	list_for_each_entry_rcu(key, &hdev->link_keys, list) {
21820378b597SJohan Hedberg 		list_del_rcu(&key->list);
21830378b597SJohan Hedberg 		kfree_rcu(key, rcu);
218455ed8ca1SJohan Hedberg 	}
218555ed8ca1SJohan Hedberg }
218655ed8ca1SJohan Hedberg 
218735f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev)
2188b899efafSVinicius Costa Gomes {
2189970d0f1bSJohan Hedberg 	struct smp_ltk *k;
2190b899efafSVinicius Costa Gomes 
2191970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
2192970d0f1bSJohan Hedberg 		list_del_rcu(&k->list);
2193970d0f1bSJohan Hedberg 		kfree_rcu(k, rcu);
2194b899efafSVinicius Costa Gomes 	}
2195b899efafSVinicius Costa Gomes }
2196b899efafSVinicius Costa Gomes 
2197970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev)
2198970c4e46SJohan Hedberg {
2199adae20cbSJohan Hedberg 	struct smp_irk *k;
2200970c4e46SJohan Hedberg 
2201adae20cbSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) {
2202adae20cbSJohan Hedberg 		list_del_rcu(&k->list);
2203adae20cbSJohan Hedberg 		kfree_rcu(k, rcu);
2204970c4e46SJohan Hedberg 	}
2205970c4e46SJohan Hedberg }
2206970c4e46SJohan Hedberg 
220755ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
220855ed8ca1SJohan Hedberg {
220955ed8ca1SJohan Hedberg 	struct link_key *k;
221055ed8ca1SJohan Hedberg 
22110378b597SJohan Hedberg 	rcu_read_lock();
22120378b597SJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->link_keys, list) {
22130378b597SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0) {
22140378b597SJohan Hedberg 			rcu_read_unlock();
221555ed8ca1SJohan Hedberg 			return k;
22160378b597SJohan Hedberg 		}
22170378b597SJohan Hedberg 	}
22180378b597SJohan Hedberg 	rcu_read_unlock();
221955ed8ca1SJohan Hedberg 
222055ed8ca1SJohan Hedberg 	return NULL;
222155ed8ca1SJohan Hedberg }
222255ed8ca1SJohan Hedberg 
2223745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
2224d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
2225d25e28abSJohan Hedberg {
2226d25e28abSJohan Hedberg 	/* Legacy key */
2227d25e28abSJohan Hedberg 	if (key_type < 0x03)
2228745c0ce3SVishal Agarwal 		return true;
2229d25e28abSJohan Hedberg 
2230d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
2231d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
2232745c0ce3SVishal Agarwal 		return false;
2233d25e28abSJohan Hedberg 
2234d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
2235d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
2236745c0ce3SVishal Agarwal 		return false;
2237d25e28abSJohan Hedberg 
2238d25e28abSJohan Hedberg 	/* Security mode 3 case */
2239d25e28abSJohan Hedberg 	if (!conn)
2240745c0ce3SVishal Agarwal 		return true;
2241d25e28abSJohan Hedberg 
2242e3befab9SJohan Hedberg 	/* BR/EDR key derived using SC from an LE link */
2243e3befab9SJohan Hedberg 	if (conn->type == LE_LINK)
2244e3befab9SJohan Hedberg 		return true;
2245e3befab9SJohan Hedberg 
2246d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
2247d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
2248745c0ce3SVishal Agarwal 		return true;
2249d25e28abSJohan Hedberg 
2250d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
2251d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
2252745c0ce3SVishal Agarwal 		return true;
2253d25e28abSJohan Hedberg 
2254d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
2255d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
2256745c0ce3SVishal Agarwal 		return true;
2257d25e28abSJohan Hedberg 
2258d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
2259d25e28abSJohan Hedberg 	 * persistently */
2260745c0ce3SVishal Agarwal 	return false;
2261d25e28abSJohan Hedberg }
2262d25e28abSJohan Hedberg 
2263e804d25dSJohan Hedberg static u8 ltk_role(u8 type)
226498a0b845SJohan Hedberg {
2265e804d25dSJohan Hedberg 	if (type == SMP_LTK)
2266e804d25dSJohan Hedberg 		return HCI_ROLE_MASTER;
226798a0b845SJohan Hedberg 
2268e804d25dSJohan Hedberg 	return HCI_ROLE_SLAVE;
226998a0b845SJohan Hedberg }
227098a0b845SJohan Hedberg 
2271f3a73d97SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
2272e804d25dSJohan Hedberg 			     u8 addr_type, u8 role)
227375d262c2SVinicius Costa Gomes {
2274c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
227575d262c2SVinicius Costa Gomes 
2276970d0f1bSJohan Hedberg 	rcu_read_lock();
2277970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
22785378bc56SJohan Hedberg 		if (addr_type != k->bdaddr_type || bacmp(bdaddr, &k->bdaddr))
22795378bc56SJohan Hedberg 			continue;
22805378bc56SJohan Hedberg 
2281923e2414SJohan Hedberg 		if (smp_ltk_is_sc(k) || ltk_role(k->type) == role) {
2282970d0f1bSJohan Hedberg 			rcu_read_unlock();
228375d262c2SVinicius Costa Gomes 			return k;
2284970d0f1bSJohan Hedberg 		}
2285970d0f1bSJohan Hedberg 	}
2286970d0f1bSJohan Hedberg 	rcu_read_unlock();
228775d262c2SVinicius Costa Gomes 
228875d262c2SVinicius Costa Gomes 	return NULL;
228975d262c2SVinicius Costa Gomes }
229075d262c2SVinicius Costa Gomes 
2291970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa)
2292970c4e46SJohan Hedberg {
2293970c4e46SJohan Hedberg 	struct smp_irk *irk;
2294970c4e46SJohan Hedberg 
2295adae20cbSJohan Hedberg 	rcu_read_lock();
2296adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
2297adae20cbSJohan Hedberg 		if (!bacmp(&irk->rpa, rpa)) {
2298adae20cbSJohan Hedberg 			rcu_read_unlock();
2299970c4e46SJohan Hedberg 			return irk;
2300970c4e46SJohan Hedberg 		}
2301adae20cbSJohan Hedberg 	}
2302970c4e46SJohan Hedberg 
2303adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
2304defce9e8SJohan Hedberg 		if (smp_irk_matches(hdev, irk->val, rpa)) {
2305970c4e46SJohan Hedberg 			bacpy(&irk->rpa, rpa);
2306adae20cbSJohan Hedberg 			rcu_read_unlock();
2307970c4e46SJohan Hedberg 			return irk;
2308970c4e46SJohan Hedberg 		}
2309970c4e46SJohan Hedberg 	}
2310adae20cbSJohan Hedberg 	rcu_read_unlock();
2311970c4e46SJohan Hedberg 
2312970c4e46SJohan Hedberg 	return NULL;
2313970c4e46SJohan Hedberg }
2314970c4e46SJohan Hedberg 
2315970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
2316970c4e46SJohan Hedberg 				     u8 addr_type)
2317970c4e46SJohan Hedberg {
2318970c4e46SJohan Hedberg 	struct smp_irk *irk;
2319970c4e46SJohan Hedberg 
23206cfc9988SJohan Hedberg 	/* Identity Address must be public or static random */
23216cfc9988SJohan Hedberg 	if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0)
23226cfc9988SJohan Hedberg 		return NULL;
23236cfc9988SJohan Hedberg 
2324adae20cbSJohan Hedberg 	rcu_read_lock();
2325adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
2326970c4e46SJohan Hedberg 		if (addr_type == irk->addr_type &&
2327adae20cbSJohan Hedberg 		    bacmp(bdaddr, &irk->bdaddr) == 0) {
2328adae20cbSJohan Hedberg 			rcu_read_unlock();
2329970c4e46SJohan Hedberg 			return irk;
2330970c4e46SJohan Hedberg 		}
2331adae20cbSJohan Hedberg 	}
2332adae20cbSJohan Hedberg 	rcu_read_unlock();
2333970c4e46SJohan Hedberg 
2334970c4e46SJohan Hedberg 	return NULL;
2335970c4e46SJohan Hedberg }
2336970c4e46SJohan Hedberg 
2337567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn,
23387652ff6aSJohan Hedberg 				  bdaddr_t *bdaddr, u8 *val, u8 type,
23397652ff6aSJohan Hedberg 				  u8 pin_len, bool *persistent)
234055ed8ca1SJohan Hedberg {
234155ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
2342745c0ce3SVishal Agarwal 	u8 old_key_type;
234355ed8ca1SJohan Hedberg 
234455ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
234555ed8ca1SJohan Hedberg 	if (old_key) {
234655ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
234755ed8ca1SJohan Hedberg 		key = old_key;
234855ed8ca1SJohan Hedberg 	} else {
234912adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
23500a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
235155ed8ca1SJohan Hedberg 		if (!key)
2352567fa2aaSJohan Hedberg 			return NULL;
23530378b597SJohan Hedberg 		list_add_rcu(&key->list, &hdev->link_keys);
235455ed8ca1SJohan Hedberg 	}
235555ed8ca1SJohan Hedberg 
23566ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
235755ed8ca1SJohan Hedberg 
2358d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
2359d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
2360d25e28abSJohan Hedberg 	 * previous key */
2361d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
2362a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
2363d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
2364655fe6ecSJohan Hedberg 		if (conn)
2365655fe6ecSJohan Hedberg 			conn->key_type = type;
2366655fe6ecSJohan Hedberg 	}
2367d25e28abSJohan Hedberg 
236855ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
23699b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
237055ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
237155ed8ca1SJohan Hedberg 
2372b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
237355ed8ca1SJohan Hedberg 		key->type = old_key_type;
23744748fed2SJohan Hedberg 	else
23754748fed2SJohan Hedberg 		key->type = type;
23764748fed2SJohan Hedberg 
23777652ff6aSJohan Hedberg 	if (persistent)
23787652ff6aSJohan Hedberg 		*persistent = hci_persistent_key(hdev, conn, type,
23797652ff6aSJohan Hedberg 						 old_key_type);
23804df378a1SJohan Hedberg 
2381567fa2aaSJohan Hedberg 	return key;
238255ed8ca1SJohan Hedberg }
238355ed8ca1SJohan Hedberg 
2384ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
238535d70271SJohan Hedberg 			    u8 addr_type, u8 type, u8 authenticated,
2386fe39c7b2SMarcel Holtmann 			    u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand)
238775d262c2SVinicius Costa Gomes {
2388c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
2389e804d25dSJohan Hedberg 	u8 role = ltk_role(type);
239075d262c2SVinicius Costa Gomes 
2391f3a73d97SJohan Hedberg 	old_key = hci_find_ltk(hdev, bdaddr, addr_type, role);
2392c9839a11SVinicius Costa Gomes 	if (old_key)
239375d262c2SVinicius Costa Gomes 		key = old_key;
2394c9839a11SVinicius Costa Gomes 	else {
23950a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
239675d262c2SVinicius Costa Gomes 		if (!key)
2397ca9142b8SJohan Hedberg 			return NULL;
2398970d0f1bSJohan Hedberg 		list_add_rcu(&key->list, &hdev->long_term_keys);
239975d262c2SVinicius Costa Gomes 	}
240075d262c2SVinicius Costa Gomes 
240175d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
2402c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
2403c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
2404c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
2405c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
2406fe39c7b2SMarcel Holtmann 	key->rand = rand;
2407c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
2408c9839a11SVinicius Costa Gomes 	key->type = type;
240975d262c2SVinicius Costa Gomes 
2410ca9142b8SJohan Hedberg 	return key;
241175d262c2SVinicius Costa Gomes }
241275d262c2SVinicius Costa Gomes 
2413ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr,
2414ca9142b8SJohan Hedberg 			    u8 addr_type, u8 val[16], bdaddr_t *rpa)
2415970c4e46SJohan Hedberg {
2416970c4e46SJohan Hedberg 	struct smp_irk *irk;
2417970c4e46SJohan Hedberg 
2418970c4e46SJohan Hedberg 	irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type);
2419970c4e46SJohan Hedberg 	if (!irk) {
2420970c4e46SJohan Hedberg 		irk = kzalloc(sizeof(*irk), GFP_KERNEL);
2421970c4e46SJohan Hedberg 		if (!irk)
2422ca9142b8SJohan Hedberg 			return NULL;
2423970c4e46SJohan Hedberg 
2424970c4e46SJohan Hedberg 		bacpy(&irk->bdaddr, bdaddr);
2425970c4e46SJohan Hedberg 		irk->addr_type = addr_type;
2426970c4e46SJohan Hedberg 
2427adae20cbSJohan Hedberg 		list_add_rcu(&irk->list, &hdev->identity_resolving_keys);
2428970c4e46SJohan Hedberg 	}
2429970c4e46SJohan Hedberg 
2430970c4e46SJohan Hedberg 	memcpy(irk->val, val, 16);
2431970c4e46SJohan Hedberg 	bacpy(&irk->rpa, rpa);
2432970c4e46SJohan Hedberg 
2433ca9142b8SJohan Hedberg 	return irk;
2434970c4e46SJohan Hedberg }
2435970c4e46SJohan Hedberg 
243655ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
243755ed8ca1SJohan Hedberg {
243855ed8ca1SJohan Hedberg 	struct link_key *key;
243955ed8ca1SJohan Hedberg 
244055ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
244155ed8ca1SJohan Hedberg 	if (!key)
244255ed8ca1SJohan Hedberg 		return -ENOENT;
244355ed8ca1SJohan Hedberg 
24446ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
244555ed8ca1SJohan Hedberg 
24460378b597SJohan Hedberg 	list_del_rcu(&key->list);
24470378b597SJohan Hedberg 	kfree_rcu(key, rcu);
244855ed8ca1SJohan Hedberg 
244955ed8ca1SJohan Hedberg 	return 0;
245055ed8ca1SJohan Hedberg }
245155ed8ca1SJohan Hedberg 
2452e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type)
2453b899efafSVinicius Costa Gomes {
2454970d0f1bSJohan Hedberg 	struct smp_ltk *k;
2455c51ffa0bSJohan Hedberg 	int removed = 0;
2456b899efafSVinicius Costa Gomes 
2457970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
2458e0b2b27eSJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type)
2459b899efafSVinicius Costa Gomes 			continue;
2460b899efafSVinicius Costa Gomes 
24616ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
2462b899efafSVinicius Costa Gomes 
2463970d0f1bSJohan Hedberg 		list_del_rcu(&k->list);
2464970d0f1bSJohan Hedberg 		kfree_rcu(k, rcu);
2465c51ffa0bSJohan Hedberg 		removed++;
2466b899efafSVinicius Costa Gomes 	}
2467b899efafSVinicius Costa Gomes 
2468c51ffa0bSJohan Hedberg 	return removed ? 0 : -ENOENT;
2469b899efafSVinicius Costa Gomes }
2470b899efafSVinicius Costa Gomes 
2471a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type)
2472a7ec7338SJohan Hedberg {
2473adae20cbSJohan Hedberg 	struct smp_irk *k;
2474a7ec7338SJohan Hedberg 
2475adae20cbSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) {
2476a7ec7338SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type)
2477a7ec7338SJohan Hedberg 			continue;
2478a7ec7338SJohan Hedberg 
2479a7ec7338SJohan Hedberg 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
2480a7ec7338SJohan Hedberg 
2481adae20cbSJohan Hedberg 		list_del_rcu(&k->list);
2482adae20cbSJohan Hedberg 		kfree_rcu(k, rcu);
2483a7ec7338SJohan Hedberg 	}
2484a7ec7338SJohan Hedberg }
2485a7ec7338SJohan Hedberg 
248655e76b38SJohan Hedberg bool hci_bdaddr_is_paired(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
248755e76b38SJohan Hedberg {
248855e76b38SJohan Hedberg 	struct smp_ltk *k;
24894ba9faf3SJohan Hedberg 	struct smp_irk *irk;
249055e76b38SJohan Hedberg 	u8 addr_type;
249155e76b38SJohan Hedberg 
249255e76b38SJohan Hedberg 	if (type == BDADDR_BREDR) {
249355e76b38SJohan Hedberg 		if (hci_find_link_key(hdev, bdaddr))
249455e76b38SJohan Hedberg 			return true;
249555e76b38SJohan Hedberg 		return false;
249655e76b38SJohan Hedberg 	}
249755e76b38SJohan Hedberg 
249855e76b38SJohan Hedberg 	/* Convert to HCI addr type which struct smp_ltk uses */
249955e76b38SJohan Hedberg 	if (type == BDADDR_LE_PUBLIC)
250055e76b38SJohan Hedberg 		addr_type = ADDR_LE_DEV_PUBLIC;
250155e76b38SJohan Hedberg 	else
250255e76b38SJohan Hedberg 		addr_type = ADDR_LE_DEV_RANDOM;
250355e76b38SJohan Hedberg 
25044ba9faf3SJohan Hedberg 	irk = hci_get_irk(hdev, bdaddr, addr_type);
25054ba9faf3SJohan Hedberg 	if (irk) {
25064ba9faf3SJohan Hedberg 		bdaddr = &irk->bdaddr;
25074ba9faf3SJohan Hedberg 		addr_type = irk->addr_type;
25084ba9faf3SJohan Hedberg 	}
25094ba9faf3SJohan Hedberg 
251055e76b38SJohan Hedberg 	rcu_read_lock();
251155e76b38SJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
251287c8b28dSJohan Hedberg 		if (k->bdaddr_type == addr_type && !bacmp(bdaddr, &k->bdaddr)) {
251387c8b28dSJohan Hedberg 			rcu_read_unlock();
251455e76b38SJohan Hedberg 			return true;
251555e76b38SJohan Hedberg 		}
251687c8b28dSJohan Hedberg 	}
251755e76b38SJohan Hedberg 	rcu_read_unlock();
251855e76b38SJohan Hedberg 
251955e76b38SJohan Hedberg 	return false;
252055e76b38SJohan Hedberg }
252155e76b38SJohan Hedberg 
25226bd32326SVille Tervo /* HCI command timer function */
252365cc2b49SMarcel Holtmann static void hci_cmd_timeout(struct work_struct *work)
25246bd32326SVille Tervo {
252565cc2b49SMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev,
252665cc2b49SMarcel Holtmann 					    cmd_timer.work);
25276bd32326SVille Tervo 
2528bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
2529bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
2530bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
2531bda4f23aSAndrei Emeltchenko 
2532bda4f23aSAndrei Emeltchenko 		BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode);
2533bda4f23aSAndrei Emeltchenko 	} else {
25346bd32326SVille Tervo 		BT_ERR("%s command tx timeout", hdev->name);
2535bda4f23aSAndrei Emeltchenko 	}
2536bda4f23aSAndrei Emeltchenko 
25376bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
2538c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
25396bd32326SVille Tervo }
25406bd32326SVille Tervo 
25412763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
25426928a924SJohan Hedberg 					  bdaddr_t *bdaddr, u8 bdaddr_type)
25432763eda6SSzymon Janc {
25442763eda6SSzymon Janc 	struct oob_data *data;
25452763eda6SSzymon Janc 
25466928a924SJohan Hedberg 	list_for_each_entry(data, &hdev->remote_oob_data, list) {
25476928a924SJohan Hedberg 		if (bacmp(bdaddr, &data->bdaddr) != 0)
25486928a924SJohan Hedberg 			continue;
25496928a924SJohan Hedberg 		if (data->bdaddr_type != bdaddr_type)
25506928a924SJohan Hedberg 			continue;
25512763eda6SSzymon Janc 		return data;
25526928a924SJohan Hedberg 	}
25532763eda6SSzymon Janc 
25542763eda6SSzymon Janc 	return NULL;
25552763eda6SSzymon Janc }
25562763eda6SSzymon Janc 
25576928a924SJohan Hedberg int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
25586928a924SJohan Hedberg 			       u8 bdaddr_type)
25592763eda6SSzymon Janc {
25602763eda6SSzymon Janc 	struct oob_data *data;
25612763eda6SSzymon Janc 
25626928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
25632763eda6SSzymon Janc 	if (!data)
25642763eda6SSzymon Janc 		return -ENOENT;
25652763eda6SSzymon Janc 
25666928a924SJohan Hedberg 	BT_DBG("%s removing %pMR (%u)", hdev->name, bdaddr, bdaddr_type);
25672763eda6SSzymon Janc 
25682763eda6SSzymon Janc 	list_del(&data->list);
25692763eda6SSzymon Janc 	kfree(data);
25702763eda6SSzymon Janc 
25712763eda6SSzymon Janc 	return 0;
25722763eda6SSzymon Janc }
25732763eda6SSzymon Janc 
257435f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev)
25752763eda6SSzymon Janc {
25762763eda6SSzymon Janc 	struct oob_data *data, *n;
25772763eda6SSzymon Janc 
25782763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
25792763eda6SSzymon Janc 		list_del(&data->list);
25802763eda6SSzymon Janc 		kfree(data);
25812763eda6SSzymon Janc 	}
25822763eda6SSzymon Janc }
25832763eda6SSzymon Janc 
25840798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
25856928a924SJohan Hedberg 			    u8 bdaddr_type, u8 *hash192, u8 *rand192,
258638da1703SJohan Hedberg 			    u8 *hash256, u8 *rand256)
25870798872eSMarcel Holtmann {
25880798872eSMarcel Holtmann 	struct oob_data *data;
25890798872eSMarcel Holtmann 
25906928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
25910798872eSMarcel Holtmann 	if (!data) {
25920a14ab41SJohan Hedberg 		data = kmalloc(sizeof(*data), GFP_KERNEL);
25930798872eSMarcel Holtmann 		if (!data)
25940798872eSMarcel Holtmann 			return -ENOMEM;
25950798872eSMarcel Holtmann 
25960798872eSMarcel Holtmann 		bacpy(&data->bdaddr, bdaddr);
25976928a924SJohan Hedberg 		data->bdaddr_type = bdaddr_type;
25980798872eSMarcel Holtmann 		list_add(&data->list, &hdev->remote_oob_data);
25990798872eSMarcel Holtmann 	}
26000798872eSMarcel Holtmann 
260181328d5cSJohan Hedberg 	if (hash192 && rand192) {
26020798872eSMarcel Holtmann 		memcpy(data->hash192, hash192, sizeof(data->hash192));
260338da1703SJohan Hedberg 		memcpy(data->rand192, rand192, sizeof(data->rand192));
2604f7697b16SMarcel Holtmann 		if (hash256 && rand256)
2605f7697b16SMarcel Holtmann 			data->present = 0x03;
260681328d5cSJohan Hedberg 	} else {
260781328d5cSJohan Hedberg 		memset(data->hash192, 0, sizeof(data->hash192));
260881328d5cSJohan Hedberg 		memset(data->rand192, 0, sizeof(data->rand192));
2609f7697b16SMarcel Holtmann 		if (hash256 && rand256)
2610f7697b16SMarcel Holtmann 			data->present = 0x02;
2611f7697b16SMarcel Holtmann 		else
2612f7697b16SMarcel Holtmann 			data->present = 0x00;
261381328d5cSJohan Hedberg 	}
26140798872eSMarcel Holtmann 
261581328d5cSJohan Hedberg 	if (hash256 && rand256) {
26160798872eSMarcel Holtmann 		memcpy(data->hash256, hash256, sizeof(data->hash256));
261738da1703SJohan Hedberg 		memcpy(data->rand256, rand256, sizeof(data->rand256));
261881328d5cSJohan Hedberg 	} else {
261981328d5cSJohan Hedberg 		memset(data->hash256, 0, sizeof(data->hash256));
262081328d5cSJohan Hedberg 		memset(data->rand256, 0, sizeof(data->rand256));
2621f7697b16SMarcel Holtmann 		if (hash192 && rand192)
2622f7697b16SMarcel Holtmann 			data->present = 0x01;
262381328d5cSJohan Hedberg 	}
26240798872eSMarcel Holtmann 
26256ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
26262763eda6SSzymon Janc 
26272763eda6SSzymon Janc 	return 0;
26282763eda6SSzymon Janc }
26292763eda6SSzymon Janc 
2630d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
2631d2609b34SFlorian Grandel struct adv_info *hci_find_adv_instance(struct hci_dev *hdev, u8 instance)
2632d2609b34SFlorian Grandel {
2633d2609b34SFlorian Grandel 	struct adv_info *adv_instance;
2634d2609b34SFlorian Grandel 
2635d2609b34SFlorian Grandel 	list_for_each_entry(adv_instance, &hdev->adv_instances, list) {
2636d2609b34SFlorian Grandel 		if (adv_instance->instance == instance)
2637d2609b34SFlorian Grandel 			return adv_instance;
2638d2609b34SFlorian Grandel 	}
2639d2609b34SFlorian Grandel 
2640d2609b34SFlorian Grandel 	return NULL;
2641d2609b34SFlorian Grandel }
2642d2609b34SFlorian Grandel 
2643d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
2644d2609b34SFlorian Grandel struct adv_info *hci_get_next_instance(struct hci_dev *hdev, u8 instance) {
2645d2609b34SFlorian Grandel 	struct adv_info *cur_instance;
2646d2609b34SFlorian Grandel 
2647d2609b34SFlorian Grandel 	cur_instance = hci_find_adv_instance(hdev, instance);
2648d2609b34SFlorian Grandel 	if (!cur_instance)
2649d2609b34SFlorian Grandel 		return NULL;
2650d2609b34SFlorian Grandel 
2651d2609b34SFlorian Grandel 	if (cur_instance == list_last_entry(&hdev->adv_instances,
2652d2609b34SFlorian Grandel 					    struct adv_info, list))
2653d2609b34SFlorian Grandel 		return list_first_entry(&hdev->adv_instances,
2654d2609b34SFlorian Grandel 						 struct adv_info, list);
2655d2609b34SFlorian Grandel 	else
2656d2609b34SFlorian Grandel 		return list_next_entry(cur_instance, list);
2657d2609b34SFlorian Grandel }
2658d2609b34SFlorian Grandel 
2659d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
2660d2609b34SFlorian Grandel int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance)
2661d2609b34SFlorian Grandel {
2662d2609b34SFlorian Grandel 	struct adv_info *adv_instance;
2663d2609b34SFlorian Grandel 
2664d2609b34SFlorian Grandel 	adv_instance = hci_find_adv_instance(hdev, instance);
2665d2609b34SFlorian Grandel 	if (!adv_instance)
2666d2609b34SFlorian Grandel 		return -ENOENT;
2667d2609b34SFlorian Grandel 
2668d2609b34SFlorian Grandel 	BT_DBG("%s removing %dMR", hdev->name, instance);
2669d2609b34SFlorian Grandel 
26705d900e46SFlorian Grandel 	if (hdev->cur_adv_instance == instance && hdev->adv_instance_timeout) {
26715d900e46SFlorian Grandel 		cancel_delayed_work(&hdev->adv_instance_expire);
26725d900e46SFlorian Grandel 		hdev->adv_instance_timeout = 0;
26735d900e46SFlorian Grandel 	}
26745d900e46SFlorian Grandel 
2675d2609b34SFlorian Grandel 	list_del(&adv_instance->list);
2676d2609b34SFlorian Grandel 	kfree(adv_instance);
2677d2609b34SFlorian Grandel 
2678d2609b34SFlorian Grandel 	hdev->adv_instance_cnt--;
2679d2609b34SFlorian Grandel 
2680d2609b34SFlorian Grandel 	return 0;
2681d2609b34SFlorian Grandel }
2682d2609b34SFlorian Grandel 
2683d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
2684d2609b34SFlorian Grandel void hci_adv_instances_clear(struct hci_dev *hdev)
2685d2609b34SFlorian Grandel {
2686d2609b34SFlorian Grandel 	struct adv_info *adv_instance, *n;
2687d2609b34SFlorian Grandel 
26885d900e46SFlorian Grandel 	if (hdev->adv_instance_timeout) {
26895d900e46SFlorian Grandel 		cancel_delayed_work(&hdev->adv_instance_expire);
26905d900e46SFlorian Grandel 		hdev->adv_instance_timeout = 0;
26915d900e46SFlorian Grandel 	}
26925d900e46SFlorian Grandel 
2693d2609b34SFlorian Grandel 	list_for_each_entry_safe(adv_instance, n, &hdev->adv_instances, list) {
2694d2609b34SFlorian Grandel 		list_del(&adv_instance->list);
2695d2609b34SFlorian Grandel 		kfree(adv_instance);
2696d2609b34SFlorian Grandel 	}
2697d2609b34SFlorian Grandel 
2698d2609b34SFlorian Grandel 	hdev->adv_instance_cnt = 0;
2699d2609b34SFlorian Grandel }
2700d2609b34SFlorian Grandel 
2701d2609b34SFlorian Grandel /* This function requires the caller holds hdev->lock */
2702d2609b34SFlorian Grandel int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags,
2703d2609b34SFlorian Grandel 			 u16 adv_data_len, u8 *adv_data,
2704d2609b34SFlorian Grandel 			 u16 scan_rsp_len, u8 *scan_rsp_data,
2705d2609b34SFlorian Grandel 			 u16 timeout, u16 duration)
2706d2609b34SFlorian Grandel {
2707d2609b34SFlorian Grandel 	struct adv_info *adv_instance;
2708d2609b34SFlorian Grandel 
2709d2609b34SFlorian Grandel 	adv_instance = hci_find_adv_instance(hdev, instance);
2710d2609b34SFlorian Grandel 	if (adv_instance) {
2711d2609b34SFlorian Grandel 		memset(adv_instance->adv_data, 0,
2712d2609b34SFlorian Grandel 		       sizeof(adv_instance->adv_data));
2713d2609b34SFlorian Grandel 		memset(adv_instance->scan_rsp_data, 0,
2714d2609b34SFlorian Grandel 		       sizeof(adv_instance->scan_rsp_data));
2715d2609b34SFlorian Grandel 	} else {
2716d2609b34SFlorian Grandel 		if (hdev->adv_instance_cnt >= HCI_MAX_ADV_INSTANCES ||
2717d2609b34SFlorian Grandel 		    instance < 1 || instance > HCI_MAX_ADV_INSTANCES)
2718d2609b34SFlorian Grandel 			return -EOVERFLOW;
2719d2609b34SFlorian Grandel 
272039ecfad6SJohan Hedberg 		adv_instance = kzalloc(sizeof(*adv_instance), GFP_KERNEL);
2721d2609b34SFlorian Grandel 		if (!adv_instance)
2722d2609b34SFlorian Grandel 			return -ENOMEM;
2723d2609b34SFlorian Grandel 
2724fffd38bcSFlorian Grandel 		adv_instance->pending = true;
2725d2609b34SFlorian Grandel 		adv_instance->instance = instance;
2726d2609b34SFlorian Grandel 		list_add(&adv_instance->list, &hdev->adv_instances);
2727d2609b34SFlorian Grandel 		hdev->adv_instance_cnt++;
2728d2609b34SFlorian Grandel 	}
2729d2609b34SFlorian Grandel 
2730d2609b34SFlorian Grandel 	adv_instance->flags = flags;
2731d2609b34SFlorian Grandel 	adv_instance->adv_data_len = adv_data_len;
2732d2609b34SFlorian Grandel 	adv_instance->scan_rsp_len = scan_rsp_len;
2733d2609b34SFlorian Grandel 
2734d2609b34SFlorian Grandel 	if (adv_data_len)
2735d2609b34SFlorian Grandel 		memcpy(adv_instance->adv_data, adv_data, adv_data_len);
2736d2609b34SFlorian Grandel 
2737d2609b34SFlorian Grandel 	if (scan_rsp_len)
2738d2609b34SFlorian Grandel 		memcpy(adv_instance->scan_rsp_data,
2739d2609b34SFlorian Grandel 		       scan_rsp_data, scan_rsp_len);
2740d2609b34SFlorian Grandel 
2741d2609b34SFlorian Grandel 	adv_instance->timeout = timeout;
27425d900e46SFlorian Grandel 	adv_instance->remaining_time = timeout;
2743d2609b34SFlorian Grandel 
2744d2609b34SFlorian Grandel 	if (duration == 0)
2745d2609b34SFlorian Grandel 		adv_instance->duration = HCI_DEFAULT_ADV_DURATION;
2746d2609b34SFlorian Grandel 	else
2747d2609b34SFlorian Grandel 		adv_instance->duration = duration;
2748d2609b34SFlorian Grandel 
2749d2609b34SFlorian Grandel 	BT_DBG("%s for %dMR", hdev->name, instance);
2750d2609b34SFlorian Grandel 
2751d2609b34SFlorian Grandel 	return 0;
2752d2609b34SFlorian Grandel }
2753d2609b34SFlorian Grandel 
2754dcc36c16SJohan Hedberg struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
2755b9ee0a78SMarcel Holtmann 					 bdaddr_t *bdaddr, u8 type)
2756b2a66aadSAntti Julku {
2757b2a66aadSAntti Julku 	struct bdaddr_list *b;
2758b2a66aadSAntti Julku 
2759dcc36c16SJohan Hedberg 	list_for_each_entry(b, bdaddr_list, list) {
2760b9ee0a78SMarcel Holtmann 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
2761b2a66aadSAntti Julku 			return b;
2762b9ee0a78SMarcel Holtmann 	}
2763b2a66aadSAntti Julku 
2764b2a66aadSAntti Julku 	return NULL;
2765b2a66aadSAntti Julku }
2766b2a66aadSAntti Julku 
2767dcc36c16SJohan Hedberg void hci_bdaddr_list_clear(struct list_head *bdaddr_list)
2768b2a66aadSAntti Julku {
2769b2a66aadSAntti Julku 	struct list_head *p, *n;
2770b2a66aadSAntti Julku 
2771dcc36c16SJohan Hedberg 	list_for_each_safe(p, n, bdaddr_list) {
2772b9ee0a78SMarcel Holtmann 		struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list);
2773b2a66aadSAntti Julku 
2774b2a66aadSAntti Julku 		list_del(p);
2775b2a66aadSAntti Julku 		kfree(b);
2776b2a66aadSAntti Julku 	}
2777b2a66aadSAntti Julku }
2778b2a66aadSAntti Julku 
2779dcc36c16SJohan Hedberg int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type)
2780b2a66aadSAntti Julku {
2781b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2782b2a66aadSAntti Julku 
2783b9ee0a78SMarcel Holtmann 	if (!bacmp(bdaddr, BDADDR_ANY))
2784b2a66aadSAntti Julku 		return -EBADF;
2785b2a66aadSAntti Julku 
2786dcc36c16SJohan Hedberg 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
27875e762444SAntti Julku 		return -EEXIST;
2788b2a66aadSAntti Julku 
278927f70f3eSJohan Hedberg 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
27905e762444SAntti Julku 	if (!entry)
27915e762444SAntti Julku 		return -ENOMEM;
2792b2a66aadSAntti Julku 
2793b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
2794b9ee0a78SMarcel Holtmann 	entry->bdaddr_type = type;
2795b2a66aadSAntti Julku 
2796dcc36c16SJohan Hedberg 	list_add(&entry->list, list);
2797b2a66aadSAntti Julku 
27982a8357f2SJohan Hedberg 	return 0;
2799b2a66aadSAntti Julku }
2800b2a66aadSAntti Julku 
2801dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type)
2802b2a66aadSAntti Julku {
2803b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2804b2a66aadSAntti Julku 
280535f7498aSJohan Hedberg 	if (!bacmp(bdaddr, BDADDR_ANY)) {
2806dcc36c16SJohan Hedberg 		hci_bdaddr_list_clear(list);
280735f7498aSJohan Hedberg 		return 0;
280835f7498aSJohan Hedberg 	}
2809b2a66aadSAntti Julku 
2810dcc36c16SJohan Hedberg 	entry = hci_bdaddr_list_lookup(list, bdaddr, type);
2811d2ab0ac1SMarcel Holtmann 	if (!entry)
2812d2ab0ac1SMarcel Holtmann 		return -ENOENT;
2813d2ab0ac1SMarcel Holtmann 
2814d2ab0ac1SMarcel Holtmann 	list_del(&entry->list);
2815d2ab0ac1SMarcel Holtmann 	kfree(entry);
2816d2ab0ac1SMarcel Holtmann 
2817d2ab0ac1SMarcel Holtmann 	return 0;
2818d2ab0ac1SMarcel Holtmann }
2819d2ab0ac1SMarcel Holtmann 
282015819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
282115819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
282215819a70SAndre Guedes 					       bdaddr_t *addr, u8 addr_type)
282315819a70SAndre Guedes {
282415819a70SAndre Guedes 	struct hci_conn_params *params;
282515819a70SAndre Guedes 
282615819a70SAndre Guedes 	list_for_each_entry(params, &hdev->le_conn_params, list) {
282715819a70SAndre Guedes 		if (bacmp(&params->addr, addr) == 0 &&
282815819a70SAndre Guedes 		    params->addr_type == addr_type) {
282915819a70SAndre Guedes 			return params;
283015819a70SAndre Guedes 		}
283115819a70SAndre Guedes 	}
283215819a70SAndre Guedes 
283315819a70SAndre Guedes 	return NULL;
283415819a70SAndre Guedes }
283515819a70SAndre Guedes 
283615819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
2837501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list,
28384b10966fSMarcel Holtmann 						  bdaddr_t *addr, u8 addr_type)
283915819a70SAndre Guedes {
2840912b42efSJohan Hedberg 	struct hci_conn_params *param;
284115819a70SAndre Guedes 
2842501f8827SJohan Hedberg 	list_for_each_entry(param, list, action) {
2843912b42efSJohan Hedberg 		if (bacmp(&param->addr, addr) == 0 &&
2844912b42efSJohan Hedberg 		    param->addr_type == addr_type)
2845912b42efSJohan Hedberg 			return param;
28464b10966fSMarcel Holtmann 	}
28474b10966fSMarcel Holtmann 
28484b10966fSMarcel Holtmann 	return NULL;
284915819a70SAndre Guedes }
285015819a70SAndre Guedes 
285115819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
2852f75113a2SJakub Pawlowski struct hci_conn_params *hci_explicit_connect_lookup(struct hci_dev *hdev,
2853f75113a2SJakub Pawlowski 						    bdaddr_t *addr,
2854f75113a2SJakub Pawlowski 						    u8 addr_type)
2855f75113a2SJakub Pawlowski {
2856f75113a2SJakub Pawlowski 	struct hci_conn_params *param;
2857f75113a2SJakub Pawlowski 
2858f75113a2SJakub Pawlowski 	list_for_each_entry(param, &hdev->pend_le_conns, action) {
2859f75113a2SJakub Pawlowski 		if (bacmp(&param->addr, addr) == 0 &&
2860f75113a2SJakub Pawlowski 		    param->addr_type == addr_type &&
2861f75113a2SJakub Pawlowski 		    param->explicit_connect)
2862f75113a2SJakub Pawlowski 			return param;
2863f75113a2SJakub Pawlowski 	}
2864f75113a2SJakub Pawlowski 
2865f75113a2SJakub Pawlowski 	list_for_each_entry(param, &hdev->pend_le_reports, action) {
2866f75113a2SJakub Pawlowski 		if (bacmp(&param->addr, addr) == 0 &&
2867f75113a2SJakub Pawlowski 		    param->addr_type == addr_type &&
2868f75113a2SJakub Pawlowski 		    param->explicit_connect)
2869f75113a2SJakub Pawlowski 			return param;
2870f75113a2SJakub Pawlowski 	}
2871f75113a2SJakub Pawlowski 
2872f75113a2SJakub Pawlowski 	return NULL;
2873f75113a2SJakub Pawlowski }
2874f75113a2SJakub Pawlowski 
2875f75113a2SJakub Pawlowski /* This function requires the caller holds hdev->lock */
287651d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev,
287751d167c0SMarcel Holtmann 					    bdaddr_t *addr, u8 addr_type)
287815819a70SAndre Guedes {
287915819a70SAndre Guedes 	struct hci_conn_params *params;
288015819a70SAndre Guedes 
288115819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
2882cef952ceSAndre Guedes 	if (params)
288351d167c0SMarcel Holtmann 		return params;
288415819a70SAndre Guedes 
288515819a70SAndre Guedes 	params = kzalloc(sizeof(*params), GFP_KERNEL);
288615819a70SAndre Guedes 	if (!params) {
288715819a70SAndre Guedes 		BT_ERR("Out of memory");
288851d167c0SMarcel Holtmann 		return NULL;
288915819a70SAndre Guedes 	}
289015819a70SAndre Guedes 
289115819a70SAndre Guedes 	bacpy(&params->addr, addr);
289215819a70SAndre Guedes 	params->addr_type = addr_type;
2893cef952ceSAndre Guedes 
2894cef952ceSAndre Guedes 	list_add(&params->list, &hdev->le_conn_params);
289593450c75SJohan Hedberg 	INIT_LIST_HEAD(&params->action);
2896cef952ceSAndre Guedes 
2897bf5b3c8bSMarcel Holtmann 	params->conn_min_interval = hdev->le_conn_min_interval;
2898bf5b3c8bSMarcel Holtmann 	params->conn_max_interval = hdev->le_conn_max_interval;
2899bf5b3c8bSMarcel Holtmann 	params->conn_latency = hdev->le_conn_latency;
2900bf5b3c8bSMarcel Holtmann 	params->supervision_timeout = hdev->le_supv_timeout;
2901bf5b3c8bSMarcel Holtmann 	params->auto_connect = HCI_AUTO_CONN_DISABLED;
2902bf5b3c8bSMarcel Holtmann 
2903bf5b3c8bSMarcel Holtmann 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
2904bf5b3c8bSMarcel Holtmann 
290551d167c0SMarcel Holtmann 	return params;
2906bf5b3c8bSMarcel Holtmann }
2907bf5b3c8bSMarcel Holtmann 
2908f6c63249SJohan Hedberg static void hci_conn_params_free(struct hci_conn_params *params)
2909f6c63249SJohan Hedberg {
2910f6c63249SJohan Hedberg 	if (params->conn) {
2911f6c63249SJohan Hedberg 		hci_conn_drop(params->conn);
2912f6c63249SJohan Hedberg 		hci_conn_put(params->conn);
2913f6c63249SJohan Hedberg 	}
2914f6c63249SJohan Hedberg 
2915f6c63249SJohan Hedberg 	list_del(&params->action);
2916f6c63249SJohan Hedberg 	list_del(&params->list);
2917f6c63249SJohan Hedberg 	kfree(params);
2918f6c63249SJohan Hedberg }
2919f6c63249SJohan Hedberg 
292015819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
292115819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
292215819a70SAndre Guedes {
292315819a70SAndre Guedes 	struct hci_conn_params *params;
292415819a70SAndre Guedes 
292515819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
292615819a70SAndre Guedes 	if (!params)
292715819a70SAndre Guedes 		return;
292815819a70SAndre Guedes 
2929f6c63249SJohan Hedberg 	hci_conn_params_free(params);
293015819a70SAndre Guedes 
293195305baaSJohan Hedberg 	hci_update_background_scan(hdev);
293295305baaSJohan Hedberg 
293315819a70SAndre Guedes 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
293415819a70SAndre Guedes }
293515819a70SAndre Guedes 
293615819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
293755af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev)
293815819a70SAndre Guedes {
293915819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
294015819a70SAndre Guedes 
294115819a70SAndre Guedes 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
294255af49a8SJohan Hedberg 		if (params->auto_connect != HCI_AUTO_CONN_DISABLED)
294355af49a8SJohan Hedberg 			continue;
2944f75113a2SJakub Pawlowski 
2945f75113a2SJakub Pawlowski 		/* If trying to estabilish one time connection to disabled
2946f75113a2SJakub Pawlowski 		 * device, leave the params, but mark them as just once.
2947f75113a2SJakub Pawlowski 		 */
2948f75113a2SJakub Pawlowski 		if (params->explicit_connect) {
2949f75113a2SJakub Pawlowski 			params->auto_connect = HCI_AUTO_CONN_EXPLICIT;
2950f75113a2SJakub Pawlowski 			continue;
2951f75113a2SJakub Pawlowski 		}
2952f75113a2SJakub Pawlowski 
295315819a70SAndre Guedes 		list_del(&params->list);
295415819a70SAndre Guedes 		kfree(params);
295515819a70SAndre Guedes 	}
295615819a70SAndre Guedes 
295755af49a8SJohan Hedberg 	BT_DBG("All LE disabled connection parameters were removed");
295855af49a8SJohan Hedberg }
295955af49a8SJohan Hedberg 
296055af49a8SJohan Hedberg /* This function requires the caller holds hdev->lock */
2961373110c5SJohan Hedberg void hci_conn_params_clear_all(struct hci_dev *hdev)
296215819a70SAndre Guedes {
296315819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
296415819a70SAndre Guedes 
2965f6c63249SJohan Hedberg 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list)
2966f6c63249SJohan Hedberg 		hci_conn_params_free(params);
296715819a70SAndre Guedes 
2968a2f41a8fSJohan Hedberg 	hci_update_background_scan(hdev);
29691089b67dSMarcel Holtmann 
297015819a70SAndre Guedes 	BT_DBG("All LE connection parameters were removed");
297115819a70SAndre Guedes }
297215819a70SAndre Guedes 
29731904a853SMarcel Holtmann static void inquiry_complete(struct hci_dev *hdev, u8 status, u16 opcode)
29747ba8b4beSAndre Guedes {
29754c87eaabSAndre Guedes 	if (status) {
29764c87eaabSAndre Guedes 		BT_ERR("Failed to start inquiry: status %d", status);
29777ba8b4beSAndre Guedes 
29784c87eaabSAndre Guedes 		hci_dev_lock(hdev);
29794c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
29804c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
29814c87eaabSAndre Guedes 		return;
29824c87eaabSAndre Guedes 	}
29837ba8b4beSAndre Guedes }
29847ba8b4beSAndre Guedes 
29851904a853SMarcel Holtmann static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status,
29861904a853SMarcel Holtmann 					  u16 opcode)
29877ba8b4beSAndre Guedes {
29884c87eaabSAndre Guedes 	/* General inquiry access code (GIAC) */
29894c87eaabSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
29904c87eaabSAndre Guedes 	struct hci_cp_inquiry cp;
29917ba8b4beSAndre Guedes 	int err;
29927ba8b4beSAndre Guedes 
29934c87eaabSAndre Guedes 	if (status) {
29944c87eaabSAndre Guedes 		BT_ERR("Failed to disable LE scanning: status %d", status);
29954c87eaabSAndre Guedes 		return;
29967ba8b4beSAndre Guedes 	}
29977ba8b4beSAndre Guedes 
29982d28cfe7SJakub Pawlowski 	hdev->discovery.scan_start = 0;
29992d28cfe7SJakub Pawlowski 
30004c87eaabSAndre Guedes 	switch (hdev->discovery.type) {
30014c87eaabSAndre Guedes 	case DISCOV_TYPE_LE:
30024c87eaabSAndre Guedes 		hci_dev_lock(hdev);
30034c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
30044c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
30054c87eaabSAndre Guedes 		break;
30067dbfac1dSAndre Guedes 
30074c87eaabSAndre Guedes 	case DISCOV_TYPE_INTERLEAVED:
30084c87eaabSAndre Guedes 		hci_dev_lock(hdev);
30094c87eaabSAndre Guedes 
301007d2334aSJakub Pawlowski 		if (test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY,
301107d2334aSJakub Pawlowski 			     &hdev->quirks)) {
301207d2334aSJakub Pawlowski 			/* If we were running LE only scan, change discovery
301307d2334aSJakub Pawlowski 			 * state. If we were running both LE and BR/EDR inquiry
301407d2334aSJakub Pawlowski 			 * simultaneously, and BR/EDR inquiry is already
301507d2334aSJakub Pawlowski 			 * finished, stop discovery, otherwise BR/EDR inquiry
3016177d0506SWesley Kuo 			 * will stop discovery when finished. If we will resolve
3017177d0506SWesley Kuo 			 * remote device name, do not change discovery state.
301807d2334aSJakub Pawlowski 			 */
3019177d0506SWesley Kuo 			if (!test_bit(HCI_INQUIRY, &hdev->flags) &&
3020177d0506SWesley Kuo 			    hdev->discovery.state != DISCOVERY_RESOLVING)
302107d2334aSJakub Pawlowski 				hci_discovery_set_state(hdev,
302207d2334aSJakub Pawlowski 							DISCOVERY_STOPPED);
302307d2334aSJakub Pawlowski 		} else {
3024baf880a9SJohan Hedberg 			struct hci_request req;
3025baf880a9SJohan Hedberg 
30264c87eaabSAndre Guedes 			hci_inquiry_cache_flush(hdev);
30274c87eaabSAndre Guedes 
3028baf880a9SJohan Hedberg 			hci_req_init(&req, hdev);
3029baf880a9SJohan Hedberg 
3030baf880a9SJohan Hedberg 			memset(&cp, 0, sizeof(cp));
3031baf880a9SJohan Hedberg 			memcpy(&cp.lap, lap, sizeof(cp.lap));
3032baf880a9SJohan Hedberg 			cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN;
3033baf880a9SJohan Hedberg 			hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp);
3034baf880a9SJohan Hedberg 
30354c87eaabSAndre Guedes 			err = hci_req_run(&req, inquiry_complete);
30364c87eaabSAndre Guedes 			if (err) {
30374c87eaabSAndre Guedes 				BT_ERR("Inquiry request failed: err %d", err);
303807d2334aSJakub Pawlowski 				hci_discovery_set_state(hdev,
303907d2334aSJakub Pawlowski 							DISCOVERY_STOPPED);
304007d2334aSJakub Pawlowski 			}
30417dbfac1dSAndre Guedes 		}
30427dbfac1dSAndre Guedes 
30434c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
30444c87eaabSAndre Guedes 		break;
30454c87eaabSAndre Guedes 	}
30467dbfac1dSAndre Guedes }
30477dbfac1dSAndre Guedes 
30487ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work)
30497ba8b4beSAndre Guedes {
30507ba8b4beSAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev,
30517ba8b4beSAndre Guedes 					    le_scan_disable.work);
30524c87eaabSAndre Guedes 	struct hci_request req;
30534c87eaabSAndre Guedes 	int err;
30547ba8b4beSAndre Guedes 
30557ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
30567ba8b4beSAndre Guedes 
30572d28cfe7SJakub Pawlowski 	cancel_delayed_work_sync(&hdev->le_scan_restart);
30582d28cfe7SJakub Pawlowski 
30594c87eaabSAndre Guedes 	hci_req_init(&req, hdev);
30607ba8b4beSAndre Guedes 
3061b1efcc28SAndre Guedes 	hci_req_add_le_scan_disable(&req);
30627ba8b4beSAndre Guedes 
30634c87eaabSAndre Guedes 	err = hci_req_run(&req, le_scan_disable_work_complete);
30644c87eaabSAndre Guedes 	if (err)
30654c87eaabSAndre Guedes 		BT_ERR("Disable LE scanning request failed: err %d", err);
306628b75a89SAndre Guedes }
306728b75a89SAndre Guedes 
30682d28cfe7SJakub Pawlowski static void le_scan_restart_work_complete(struct hci_dev *hdev, u8 status,
30692d28cfe7SJakub Pawlowski 					  u16 opcode)
30702d28cfe7SJakub Pawlowski {
30712d28cfe7SJakub Pawlowski 	unsigned long timeout, duration, scan_start, now;
30722d28cfe7SJakub Pawlowski 
30732d28cfe7SJakub Pawlowski 	BT_DBG("%s", hdev->name);
30742d28cfe7SJakub Pawlowski 
30752d28cfe7SJakub Pawlowski 	if (status) {
30762d28cfe7SJakub Pawlowski 		BT_ERR("Failed to restart LE scan: status %d", status);
30772d28cfe7SJakub Pawlowski 		return;
30782d28cfe7SJakub Pawlowski 	}
30792d28cfe7SJakub Pawlowski 
30802d28cfe7SJakub Pawlowski 	if (!test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks) ||
30812d28cfe7SJakub Pawlowski 	    !hdev->discovery.scan_start)
30822d28cfe7SJakub Pawlowski 		return;
30832d28cfe7SJakub Pawlowski 
30842d28cfe7SJakub Pawlowski 	/* When the scan was started, hdev->le_scan_disable has been queued
30852d28cfe7SJakub Pawlowski 	 * after duration from scan_start. During scan restart this job
30862d28cfe7SJakub Pawlowski 	 * has been canceled, and we need to queue it again after proper
30872d28cfe7SJakub Pawlowski 	 * timeout, to make sure that scan does not run indefinitely.
30882d28cfe7SJakub Pawlowski 	 */
30892d28cfe7SJakub Pawlowski 	duration = hdev->discovery.scan_duration;
30902d28cfe7SJakub Pawlowski 	scan_start = hdev->discovery.scan_start;
30912d28cfe7SJakub Pawlowski 	now = jiffies;
30922d28cfe7SJakub Pawlowski 	if (now - scan_start <= duration) {
30932d28cfe7SJakub Pawlowski 		int elapsed;
30942d28cfe7SJakub Pawlowski 
30952d28cfe7SJakub Pawlowski 		if (now >= scan_start)
30962d28cfe7SJakub Pawlowski 			elapsed = now - scan_start;
30972d28cfe7SJakub Pawlowski 		else
30982d28cfe7SJakub Pawlowski 			elapsed = ULONG_MAX - scan_start + now;
30992d28cfe7SJakub Pawlowski 
31002d28cfe7SJakub Pawlowski 		timeout = duration - elapsed;
31012d28cfe7SJakub Pawlowski 	} else {
31022d28cfe7SJakub Pawlowski 		timeout = 0;
31032d28cfe7SJakub Pawlowski 	}
31042d28cfe7SJakub Pawlowski 	queue_delayed_work(hdev->workqueue,
31052d28cfe7SJakub Pawlowski 			   &hdev->le_scan_disable, timeout);
31062d28cfe7SJakub Pawlowski }
31072d28cfe7SJakub Pawlowski 
31082d28cfe7SJakub Pawlowski static void le_scan_restart_work(struct work_struct *work)
31092d28cfe7SJakub Pawlowski {
31102d28cfe7SJakub Pawlowski 	struct hci_dev *hdev = container_of(work, struct hci_dev,
31112d28cfe7SJakub Pawlowski 					    le_scan_restart.work);
31122d28cfe7SJakub Pawlowski 	struct hci_request req;
31132d28cfe7SJakub Pawlowski 	struct hci_cp_le_set_scan_enable cp;
31142d28cfe7SJakub Pawlowski 	int err;
31152d28cfe7SJakub Pawlowski 
31162d28cfe7SJakub Pawlowski 	BT_DBG("%s", hdev->name);
31172d28cfe7SJakub Pawlowski 
31182d28cfe7SJakub Pawlowski 	/* If controller is not scanning we are done. */
3119d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_LE_SCAN))
31202d28cfe7SJakub Pawlowski 		return;
31212d28cfe7SJakub Pawlowski 
31222d28cfe7SJakub Pawlowski 	hci_req_init(&req, hdev);
31232d28cfe7SJakub Pawlowski 
31242d28cfe7SJakub Pawlowski 	hci_req_add_le_scan_disable(&req);
31252d28cfe7SJakub Pawlowski 
31262d28cfe7SJakub Pawlowski 	memset(&cp, 0, sizeof(cp));
31272d28cfe7SJakub Pawlowski 	cp.enable = LE_SCAN_ENABLE;
31282d28cfe7SJakub Pawlowski 	cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
31292d28cfe7SJakub Pawlowski 	hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
31302d28cfe7SJakub Pawlowski 
31312d28cfe7SJakub Pawlowski 	err = hci_req_run(&req, le_scan_restart_work_complete);
31322d28cfe7SJakub Pawlowski 	if (err)
31332d28cfe7SJakub Pawlowski 		BT_ERR("Restart LE scan request failed: err %d", err);
31342d28cfe7SJakub Pawlowski }
31352d28cfe7SJakub Pawlowski 
3136a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller.
3137a1f4c318SJohan Hedberg  *
3138a1f4c318SJohan Hedberg  * If the controller has a public BD_ADDR, then by default use that one.
3139a1f4c318SJohan Hedberg  * If this is a LE only controller without a public address, default to
3140a1f4c318SJohan Hedberg  * the static random address.
3141a1f4c318SJohan Hedberg  *
3142a1f4c318SJohan Hedberg  * For debugging purposes it is possible to force controllers with a
3143a1f4c318SJohan Hedberg  * public address to use the static random address instead.
314450b5b952SMarcel Holtmann  *
314550b5b952SMarcel Holtmann  * In case BR/EDR has been disabled on a dual-mode controller and
314650b5b952SMarcel Holtmann  * userspace has configured a static address, then that address
314750b5b952SMarcel Holtmann  * becomes the identity address instead of the public BR/EDR address.
3148a1f4c318SJohan Hedberg  */
3149a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
3150a1f4c318SJohan Hedberg 			       u8 *bdaddr_type)
3151a1f4c318SJohan Hedberg {
3152b7cb93e5SMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) ||
315350b5b952SMarcel Holtmann 	    !bacmp(&hdev->bdaddr, BDADDR_ANY) ||
3154d7a5a11dSMarcel Holtmann 	    (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) &&
315550b5b952SMarcel Holtmann 	     bacmp(&hdev->static_addr, BDADDR_ANY))) {
3156a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->static_addr);
3157a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_RANDOM;
3158a1f4c318SJohan Hedberg 	} else {
3159a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->bdaddr);
3160a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_PUBLIC;
3161a1f4c318SJohan Hedberg 	}
3162a1f4c318SJohan Hedberg }
3163a1f4c318SJohan Hedberg 
31649be0dab7SDavid Herrmann /* Alloc HCI device */
31659be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void)
31669be0dab7SDavid Herrmann {
31679be0dab7SDavid Herrmann 	struct hci_dev *hdev;
31689be0dab7SDavid Herrmann 
316927f70f3eSJohan Hedberg 	hdev = kzalloc(sizeof(*hdev), GFP_KERNEL);
31709be0dab7SDavid Herrmann 	if (!hdev)
31719be0dab7SDavid Herrmann 		return NULL;
31729be0dab7SDavid Herrmann 
3173b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
3174b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
3175b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
3176b4cb9fb2SMarcel Holtmann 	hdev->num_iac = 0x01;		/* One IAC support is mandatory */
3177b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03;	/* No Input No Output */
317896c2103aSMarcel Holtmann 	hdev->manufacturer = 0xffff;	/* Default to internal use */
3179bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
3180bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
3181d2609b34SFlorian Grandel 	hdev->adv_instance_cnt = 0;
3182d2609b34SFlorian Grandel 	hdev->cur_adv_instance = 0x00;
31835d900e46SFlorian Grandel 	hdev->adv_instance_timeout = 0;
3184b1b813d4SDavid Herrmann 
3185b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
3186b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
3187b1b813d4SDavid Herrmann 
31883f959d46SMarcel Holtmann 	hdev->le_adv_channel_map = 0x07;
3189628531c9SGeorg Lukas 	hdev->le_adv_min_interval = 0x0800;
3190628531c9SGeorg Lukas 	hdev->le_adv_max_interval = 0x0800;
3191bef64738SMarcel Holtmann 	hdev->le_scan_interval = 0x0060;
3192bef64738SMarcel Holtmann 	hdev->le_scan_window = 0x0030;
31934e70c7e7SMarcel Holtmann 	hdev->le_conn_min_interval = 0x0028;
31944e70c7e7SMarcel Holtmann 	hdev->le_conn_max_interval = 0x0038;
319504fb7d90SMarcel Holtmann 	hdev->le_conn_latency = 0x0000;
319604fb7d90SMarcel Holtmann 	hdev->le_supv_timeout = 0x002a;
3197a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_len = 0x001b;
3198a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_time = 0x0148;
3199a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_len = 0x001b;
3200a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_time = 0x0148;
3201a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_len = 0x001b;
3202a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_time = 0x0148;
3203bef64738SMarcel Holtmann 
3204d6bfd59cSJohan Hedberg 	hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT;
3205b9a7a61eSLukasz Rymanowski 	hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT;
320631ad1691SAndrzej Kaczmarek 	hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE;
320731ad1691SAndrzej Kaczmarek 	hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE;
3208d6bfd59cSJohan Hedberg 
3209b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
3210b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
3211b1b813d4SDavid Herrmann 
3212b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
3213b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->blacklist);
32146659358eSJohan Hedberg 	INIT_LIST_HEAD(&hdev->whitelist);
3215b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
3216b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
3217b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
3218970c4e46SJohan Hedberg 	INIT_LIST_HEAD(&hdev->identity_resolving_keys);
3219b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
3220d2ab0ac1SMarcel Holtmann 	INIT_LIST_HEAD(&hdev->le_white_list);
322115819a70SAndre Guedes 	INIT_LIST_HEAD(&hdev->le_conn_params);
322277a77a30SAndre Guedes 	INIT_LIST_HEAD(&hdev->pend_le_conns);
322366f8455aSJohan Hedberg 	INIT_LIST_HEAD(&hdev->pend_le_reports);
32246b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
3225d2609b34SFlorian Grandel 	INIT_LIST_HEAD(&hdev->adv_instances);
3226b1b813d4SDavid Herrmann 
3227b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
3228b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
3229b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
3230b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
3231c7741d16SMarcel Holtmann 	INIT_WORK(&hdev->error_reset, hci_error_reset);
3232b1b813d4SDavid Herrmann 
3233b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
3234b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
3235b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
32362d28cfe7SJakub Pawlowski 	INIT_DELAYED_WORK(&hdev->le_scan_restart, le_scan_restart_work);
32375d900e46SFlorian Grandel 	INIT_DELAYED_WORK(&hdev->adv_instance_expire, hci_adv_timeout_expire);
3238b1b813d4SDavid Herrmann 
3239b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
3240b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
3241b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
3242b1b813d4SDavid Herrmann 
3243b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
3244b1b813d4SDavid Herrmann 
324565cc2b49SMarcel Holtmann 	INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout);
3246b1b813d4SDavid Herrmann 
3247b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
3248b1b813d4SDavid Herrmann 	discovery_init(hdev);
32499be0dab7SDavid Herrmann 
32509be0dab7SDavid Herrmann 	return hdev;
32519be0dab7SDavid Herrmann }
32529be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev);
32539be0dab7SDavid Herrmann 
32549be0dab7SDavid Herrmann /* Free HCI device */
32559be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
32569be0dab7SDavid Herrmann {
32579be0dab7SDavid Herrmann 	/* will free via device release */
32589be0dab7SDavid Herrmann 	put_device(&hdev->dev);
32599be0dab7SDavid Herrmann }
32609be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
32619be0dab7SDavid Herrmann 
32621da177e4SLinus Torvalds /* Register HCI device */
32631da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
32641da177e4SLinus Torvalds {
3265b1b813d4SDavid Herrmann 	int id, error;
32661da177e4SLinus Torvalds 
326774292d5aSMarcel Holtmann 	if (!hdev->open || !hdev->close || !hdev->send)
32681da177e4SLinus Torvalds 		return -EINVAL;
32691da177e4SLinus Torvalds 
327008add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
327108add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
327208add513SMat Martineau 	 */
32733df92b31SSasha Levin 	switch (hdev->dev_type) {
32743df92b31SSasha Levin 	case HCI_BREDR:
32753df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
32761da177e4SLinus Torvalds 		break;
32773df92b31SSasha Levin 	case HCI_AMP:
32783df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
32793df92b31SSasha Levin 		break;
32803df92b31SSasha Levin 	default:
32813df92b31SSasha Levin 		return -EINVAL;
32821da177e4SLinus Torvalds 	}
32831da177e4SLinus Torvalds 
32843df92b31SSasha Levin 	if (id < 0)
32853df92b31SSasha Levin 		return id;
32863df92b31SSasha Levin 
32871da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
32881da177e4SLinus Torvalds 	hdev->id = id;
32892d8b3a11SAndrei Emeltchenko 
32902d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
32912d8b3a11SAndrei Emeltchenko 
3292d8537548SKees Cook 	hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
3293d8537548SKees Cook 					  WQ_MEM_RECLAIM, 1, hdev->name);
329433ca954dSDavid Herrmann 	if (!hdev->workqueue) {
329533ca954dSDavid Herrmann 		error = -ENOMEM;
329633ca954dSDavid Herrmann 		goto err;
329733ca954dSDavid Herrmann 	}
3298f48fd9c8SMarcel Holtmann 
3299d8537548SKees Cook 	hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
3300d8537548SKees Cook 					      WQ_MEM_RECLAIM, 1, hdev->name);
33016ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
33026ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
33036ead1bbcSJohan Hedberg 		error = -ENOMEM;
33046ead1bbcSJohan Hedberg 		goto err;
33056ead1bbcSJohan Hedberg 	}
33066ead1bbcSJohan Hedberg 
33070153e2ecSMarcel Holtmann 	if (!IS_ERR_OR_NULL(bt_debugfs))
33080153e2ecSMarcel Holtmann 		hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs);
33090153e2ecSMarcel Holtmann 
3310bdc3e0f1SMarcel Holtmann 	dev_set_name(&hdev->dev, "%s", hdev->name);
3311bdc3e0f1SMarcel Holtmann 
3312bdc3e0f1SMarcel Holtmann 	error = device_add(&hdev->dev);
331333ca954dSDavid Herrmann 	if (error < 0)
331454506918SJohan Hedberg 		goto err_wqueue;
33151da177e4SLinus Torvalds 
3316611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
3317a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
3318a8c5fb1aSGustavo Padovan 				    hdev);
3319611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
3320611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
3321611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
3322611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
3323611b30f7SMarcel Holtmann 		}
3324611b30f7SMarcel Holtmann 	}
3325611b30f7SMarcel Holtmann 
33265e130367SJohan Hedberg 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill))
3327a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RFKILLED);
33285e130367SJohan Hedberg 
3329a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_SETUP);
3330a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_AUTO_OFF);
3331ce2be9acSAndrei Emeltchenko 
333201cd3404SMarcel Holtmann 	if (hdev->dev_type == HCI_BREDR) {
333356f87901SJohan Hedberg 		/* Assume BR/EDR support until proven otherwise (such as
333456f87901SJohan Hedberg 		 * through reading supported features during init.
333556f87901SJohan Hedberg 		 */
3336a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
333756f87901SJohan Hedberg 	}
3338ce2be9acSAndrei Emeltchenko 
3339fcee3377SGustavo Padovan 	write_lock(&hci_dev_list_lock);
3340fcee3377SGustavo Padovan 	list_add(&hdev->list, &hci_dev_list);
3341fcee3377SGustavo Padovan 	write_unlock(&hci_dev_list_lock);
3342fcee3377SGustavo Padovan 
33434a964404SMarcel Holtmann 	/* Devices that are marked for raw-only usage are unconfigured
33444a964404SMarcel Holtmann 	 * and should not be included in normal operation.
3345fee746b0SMarcel Holtmann 	 */
3346fee746b0SMarcel Holtmann 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
3347a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
3348fee746b0SMarcel Holtmann 
33491da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
3350dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
33511da177e4SLinus Torvalds 
335219202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
3353fbe96d6fSMarcel Holtmann 
33541da177e4SLinus Torvalds 	return id;
3355f48fd9c8SMarcel Holtmann 
335633ca954dSDavid Herrmann err_wqueue:
335733ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
33586ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
335933ca954dSDavid Herrmann err:
33603df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
3361f48fd9c8SMarcel Holtmann 
336233ca954dSDavid Herrmann 	return error;
33631da177e4SLinus Torvalds }
33641da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
33651da177e4SLinus Torvalds 
33661da177e4SLinus Torvalds /* Unregister HCI device */
336759735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
33681da177e4SLinus Torvalds {
33692d7cc19eSMarcel Holtmann 	int id;
3370ef222013SMarcel Holtmann 
3371c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
33721da177e4SLinus Torvalds 
3373a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_UNREGISTER);
337494324962SJohan Hovold 
33753df92b31SSasha Levin 	id = hdev->id;
33763df92b31SSasha Levin 
3377f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
33781da177e4SLinus Torvalds 	list_del(&hdev->list);
3379f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
33801da177e4SLinus Torvalds 
33811da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
33821da177e4SLinus Torvalds 
3383b9b5ef18SGustavo Padovan 	cancel_work_sync(&hdev->power_on);
3384b9b5ef18SGustavo Padovan 
3385ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
3386d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_SETUP) &&
3387d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONFIG)) {
338809fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
3389744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
339009fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
339156e5cb86SJohan Hedberg 	}
3392ab81cbf9SJohan Hedberg 
33932e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
33942e58ef3eSJohan Hedberg 	 * pending list */
33952e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
33962e58ef3eSJohan Hedberg 
33971da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
33981da177e4SLinus Torvalds 
3399611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
3400611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
3401611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
3402611b30f7SMarcel Holtmann 	}
3403611b30f7SMarcel Holtmann 
3404bdc3e0f1SMarcel Holtmann 	device_del(&hdev->dev);
3405147e2d59SDave Young 
34060153e2ecSMarcel Holtmann 	debugfs_remove_recursive(hdev->debugfs);
34070153e2ecSMarcel Holtmann 
3408f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
34096ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
3410f48fd9c8SMarcel Holtmann 
341109fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
3412dcc36c16SJohan Hedberg 	hci_bdaddr_list_clear(&hdev->blacklist);
34136659358eSJohan Hedberg 	hci_bdaddr_list_clear(&hdev->whitelist);
34142aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
341555ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
3416b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
3417970c4e46SJohan Hedberg 	hci_smp_irks_clear(hdev);
34182763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
3419d2609b34SFlorian Grandel 	hci_adv_instances_clear(hdev);
3420dcc36c16SJohan Hedberg 	hci_bdaddr_list_clear(&hdev->le_white_list);
3421373110c5SJohan Hedberg 	hci_conn_params_clear_all(hdev);
342222078800SMarcel Holtmann 	hci_discovery_filter_clear(hdev);
342309fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
3424e2e0cacbSJohan Hedberg 
3425dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
34263df92b31SSasha Levin 
34273df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, id);
34281da177e4SLinus Torvalds }
34291da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
34301da177e4SLinus Torvalds 
34311da177e4SLinus Torvalds /* Suspend HCI device */
34321da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
34331da177e4SLinus Torvalds {
34341da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
34351da177e4SLinus Torvalds 	return 0;
34361da177e4SLinus Torvalds }
34371da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
34381da177e4SLinus Torvalds 
34391da177e4SLinus Torvalds /* Resume HCI device */
34401da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
34411da177e4SLinus Torvalds {
34421da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
34431da177e4SLinus Torvalds 	return 0;
34441da177e4SLinus Torvalds }
34451da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
34461da177e4SLinus Torvalds 
344775e0569fSMarcel Holtmann /* Reset HCI device */
344875e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev)
344975e0569fSMarcel Holtmann {
345075e0569fSMarcel Holtmann 	const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 };
345175e0569fSMarcel Holtmann 	struct sk_buff *skb;
345275e0569fSMarcel Holtmann 
345375e0569fSMarcel Holtmann 	skb = bt_skb_alloc(3, GFP_ATOMIC);
345475e0569fSMarcel Holtmann 	if (!skb)
345575e0569fSMarcel Holtmann 		return -ENOMEM;
345675e0569fSMarcel Holtmann 
345775e0569fSMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
345875e0569fSMarcel Holtmann 	memcpy(skb_put(skb, 3), hw_err, 3);
345975e0569fSMarcel Holtmann 
346075e0569fSMarcel Holtmann 	/* Send Hardware Error to upper stack */
346175e0569fSMarcel Holtmann 	return hci_recv_frame(hdev, skb);
346275e0569fSMarcel Holtmann }
346375e0569fSMarcel Holtmann EXPORT_SYMBOL(hci_reset_dev);
346475e0569fSMarcel Holtmann 
346576bca880SMarcel Holtmann /* Receive frame from HCI drivers */
3466e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
346776bca880SMarcel Holtmann {
346876bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
346976bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
347076bca880SMarcel Holtmann 		kfree_skb(skb);
347176bca880SMarcel Holtmann 		return -ENXIO;
347276bca880SMarcel Holtmann 	}
347376bca880SMarcel Holtmann 
3474d82603c6SJorrit Schippers 	/* Incoming skb */
347576bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
347676bca880SMarcel Holtmann 
347776bca880SMarcel Holtmann 	/* Time stamp */
347876bca880SMarcel Holtmann 	__net_timestamp(skb);
347976bca880SMarcel Holtmann 
348076bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
3481b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
3482c78ae283SMarcel Holtmann 
348376bca880SMarcel Holtmann 	return 0;
348476bca880SMarcel Holtmann }
348576bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
348676bca880SMarcel Holtmann 
34871da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
34881da177e4SLinus Torvalds 
34891da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
34901da177e4SLinus Torvalds {
34911da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
34921da177e4SLinus Torvalds 
3493fba7ecf0SJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
349400629e0fSJohan Hedberg 	list_add_tail(&cb->list, &hci_cb_list);
3495fba7ecf0SJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
34961da177e4SLinus Torvalds 
34971da177e4SLinus Torvalds 	return 0;
34981da177e4SLinus Torvalds }
34991da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
35001da177e4SLinus Torvalds 
35011da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
35021da177e4SLinus Torvalds {
35031da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
35041da177e4SLinus Torvalds 
3505fba7ecf0SJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
35061da177e4SLinus Torvalds 	list_del(&cb->list);
3507fba7ecf0SJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
35081da177e4SLinus Torvalds 
35091da177e4SLinus Torvalds 	return 0;
35101da177e4SLinus Torvalds }
35111da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
35121da177e4SLinus Torvalds 
351351086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
35141da177e4SLinus Torvalds {
3515cdc52faaSMarcel Holtmann 	int err;
3516cdc52faaSMarcel Holtmann 
35170d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
35181da177e4SLinus Torvalds 
35191da177e4SLinus Torvalds 	/* Time stamp */
3520a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
35211da177e4SLinus Torvalds 
3522cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
3523cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
3524cd82e61cSMarcel Holtmann 
3525cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
3526cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
3527470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
35281da177e4SLinus Torvalds 	}
35291da177e4SLinus Torvalds 
35301da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
35311da177e4SLinus Torvalds 	skb_orphan(skb);
35321da177e4SLinus Torvalds 
3533cdc52faaSMarcel Holtmann 	err = hdev->send(hdev, skb);
3534cdc52faaSMarcel Holtmann 	if (err < 0) {
3535cdc52faaSMarcel Holtmann 		BT_ERR("%s sending frame failed (%d)", hdev->name, err);
3536cdc52faaSMarcel Holtmann 		kfree_skb(skb);
3537cdc52faaSMarcel Holtmann 	}
35381da177e4SLinus Torvalds }
35391da177e4SLinus Torvalds 
35401ca3a9d0SJohan Hedberg /* Send HCI command */
354107dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
354207dc93ddSJohan Hedberg 		 const void *param)
35431ca3a9d0SJohan Hedberg {
35441ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
35451ca3a9d0SJohan Hedberg 
35461ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
35471ca3a9d0SJohan Hedberg 
35481ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
35491ca3a9d0SJohan Hedberg 	if (!skb) {
35501ca3a9d0SJohan Hedberg 		BT_ERR("%s no memory for command", hdev->name);
35511ca3a9d0SJohan Hedberg 		return -ENOMEM;
35521ca3a9d0SJohan Hedberg 	}
35531ca3a9d0SJohan Hedberg 
355449c922bbSStephen Hemminger 	/* Stand-alone HCI commands must be flagged as
355511714b3dSJohan Hedberg 	 * single-command requests.
355611714b3dSJohan Hedberg 	 */
3557db6e3e8dSJohan Hedberg 	bt_cb(skb)->req.start = true;
355811714b3dSJohan Hedberg 
35591da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
3560c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
35611da177e4SLinus Torvalds 
35621da177e4SLinus Torvalds 	return 0;
35631da177e4SLinus Torvalds }
35641da177e4SLinus Torvalds 
35651da177e4SLinus Torvalds /* Get data from the previously sent command */
3566a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
35671da177e4SLinus Torvalds {
35681da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
35691da177e4SLinus Torvalds 
35701da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
35711da177e4SLinus Torvalds 		return NULL;
35721da177e4SLinus Torvalds 
35731da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
35741da177e4SLinus Torvalds 
3575a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
35761da177e4SLinus Torvalds 		return NULL;
35771da177e4SLinus Torvalds 
3578f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
35791da177e4SLinus Torvalds 
35801da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
35811da177e4SLinus Torvalds }
35821da177e4SLinus Torvalds 
35831da177e4SLinus Torvalds /* Send ACL data */
35841da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
35851da177e4SLinus Torvalds {
35861da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
35871da177e4SLinus Torvalds 	int len = skb->len;
35881da177e4SLinus Torvalds 
3589badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
3590badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
35919c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
3592aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
3593aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
35941da177e4SLinus Torvalds }
35951da177e4SLinus Torvalds 
3596ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
359773d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
35981da177e4SLinus Torvalds {
3599ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
36001da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
36011da177e4SLinus Torvalds 	struct sk_buff *list;
36021da177e4SLinus Torvalds 
3603087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
3604087bfd99SGustavo Padovan 	skb->data_len = 0;
3605087bfd99SGustavo Padovan 
3606087bfd99SGustavo Padovan 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
3607204a6e54SAndrei Emeltchenko 
3608204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
3609204a6e54SAndrei Emeltchenko 	case HCI_BREDR:
3610087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
3611204a6e54SAndrei Emeltchenko 		break;
3612204a6e54SAndrei Emeltchenko 	case HCI_AMP:
3613204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
3614204a6e54SAndrei Emeltchenko 		break;
3615204a6e54SAndrei Emeltchenko 	default:
3616204a6e54SAndrei Emeltchenko 		BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
3617204a6e54SAndrei Emeltchenko 		return;
3618204a6e54SAndrei Emeltchenko 	}
3619087bfd99SGustavo Padovan 
362070f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
362170f23020SAndrei Emeltchenko 	if (!list) {
36221da177e4SLinus Torvalds 		/* Non fragmented */
36231da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
36241da177e4SLinus Torvalds 
362573d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
36261da177e4SLinus Torvalds 	} else {
36271da177e4SLinus Torvalds 		/* Fragmented */
36281da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
36291da177e4SLinus Torvalds 
36301da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
36311da177e4SLinus Torvalds 
36329cfd5a23SJukka Rissanen 		/* Queue all fragments atomically. We need to use spin_lock_bh
36339cfd5a23SJukka Rissanen 		 * here because of 6LoWPAN links, as there this function is
36349cfd5a23SJukka Rissanen 		 * called from softirq and using normal spin lock could cause
36359cfd5a23SJukka Rissanen 		 * deadlocks.
36369cfd5a23SJukka Rissanen 		 */
36379cfd5a23SJukka Rissanen 		spin_lock_bh(&queue->lock);
36381da177e4SLinus Torvalds 
363973d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
3640e702112fSAndrei Emeltchenko 
3641e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
3642e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
36431da177e4SLinus Torvalds 		do {
36441da177e4SLinus Torvalds 			skb = list; list = list->next;
36451da177e4SLinus Torvalds 
36460d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
3647e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
36481da177e4SLinus Torvalds 
36491da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
36501da177e4SLinus Torvalds 
365173d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
36521da177e4SLinus Torvalds 		} while (list);
36531da177e4SLinus Torvalds 
36549cfd5a23SJukka Rissanen 		spin_unlock_bh(&queue->lock);
36551da177e4SLinus Torvalds 	}
365673d80debSLuiz Augusto von Dentz }
365773d80debSLuiz Augusto von Dentz 
365873d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
365973d80debSLuiz Augusto von Dentz {
3660ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
366173d80debSLuiz Augusto von Dentz 
3662f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
366373d80debSLuiz Augusto von Dentz 
3664ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
36651da177e4SLinus Torvalds 
36663eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
36671da177e4SLinus Torvalds }
36681da177e4SLinus Torvalds 
36691da177e4SLinus Torvalds /* Send SCO data */
36700d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
36711da177e4SLinus Torvalds {
36721da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
36731da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
36741da177e4SLinus Torvalds 
36751da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
36761da177e4SLinus Torvalds 
3677aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
36781da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
36791da177e4SLinus Torvalds 
3680badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
3681badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
36829c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
36831da177e4SLinus Torvalds 
36840d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
3685c78ae283SMarcel Holtmann 
36861da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
36873eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
36881da177e4SLinus Torvalds }
36891da177e4SLinus Torvalds 
36901da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
36911da177e4SLinus Torvalds 
36921da177e4SLinus Torvalds /* HCI Connection scheduler */
36936039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
3694a8c5fb1aSGustavo Padovan 				     int *quote)
36951da177e4SLinus Torvalds {
36961da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
36978035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
3698abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
36991da177e4SLinus Torvalds 
37001da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
37011da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
3702bf4c6325SGustavo F. Padovan 
3703bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3704bf4c6325SGustavo F. Padovan 
3705bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
3706769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
37071da177e4SLinus Torvalds 			continue;
3708769be974SMarcel Holtmann 
3709769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
3710769be974SMarcel Holtmann 			continue;
3711769be974SMarcel Holtmann 
37121da177e4SLinus Torvalds 		num++;
37131da177e4SLinus Torvalds 
37141da177e4SLinus Torvalds 		if (c->sent < min) {
37151da177e4SLinus Torvalds 			min  = c->sent;
37161da177e4SLinus Torvalds 			conn = c;
37171da177e4SLinus Torvalds 		}
371852087a79SLuiz Augusto von Dentz 
371952087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
372052087a79SLuiz Augusto von Dentz 			break;
37211da177e4SLinus Torvalds 	}
37221da177e4SLinus Torvalds 
3723bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3724bf4c6325SGustavo F. Padovan 
37251da177e4SLinus Torvalds 	if (conn) {
37266ed58ec5SVille Tervo 		int cnt, q;
37276ed58ec5SVille Tervo 
37286ed58ec5SVille Tervo 		switch (conn->type) {
37296ed58ec5SVille Tervo 		case ACL_LINK:
37306ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
37316ed58ec5SVille Tervo 			break;
37326ed58ec5SVille Tervo 		case SCO_LINK:
37336ed58ec5SVille Tervo 		case ESCO_LINK:
37346ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
37356ed58ec5SVille Tervo 			break;
37366ed58ec5SVille Tervo 		case LE_LINK:
37376ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
37386ed58ec5SVille Tervo 			break;
37396ed58ec5SVille Tervo 		default:
37406ed58ec5SVille Tervo 			cnt = 0;
37416ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
37426ed58ec5SVille Tervo 		}
37436ed58ec5SVille Tervo 
37446ed58ec5SVille Tervo 		q = cnt / num;
37451da177e4SLinus Torvalds 		*quote = q ? q : 1;
37461da177e4SLinus Torvalds 	} else
37471da177e4SLinus Torvalds 		*quote = 0;
37481da177e4SLinus Torvalds 
37491da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
37501da177e4SLinus Torvalds 	return conn;
37511da177e4SLinus Torvalds }
37521da177e4SLinus Torvalds 
37536039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
37541da177e4SLinus Torvalds {
37551da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
37561da177e4SLinus Torvalds 	struct hci_conn *c;
37571da177e4SLinus Torvalds 
3758bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
37591da177e4SLinus Torvalds 
3760bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3761bf4c6325SGustavo F. Padovan 
37621da177e4SLinus Torvalds 	/* Kill stalled connections */
3763bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
3764bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
37656ed93dc6SAndrei Emeltchenko 			BT_ERR("%s killing stalled connection %pMR",
37666ed93dc6SAndrei Emeltchenko 			       hdev->name, &c->dst);
3767bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
37681da177e4SLinus Torvalds 		}
37691da177e4SLinus Torvalds 	}
3770bf4c6325SGustavo F. Padovan 
3771bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
37721da177e4SLinus Torvalds }
37731da177e4SLinus Torvalds 
37746039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
377573d80debSLuiz Augusto von Dentz 				      int *quote)
377673d80debSLuiz Augusto von Dentz {
377773d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
377873d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
3779abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
378073d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
378173d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
378273d80debSLuiz Augusto von Dentz 
378373d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
378473d80debSLuiz Augusto von Dentz 
3785bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3786bf4c6325SGustavo F. Padovan 
3787bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
378873d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
378973d80debSLuiz Augusto von Dentz 
379073d80debSLuiz Augusto von Dentz 		if (conn->type != type)
379173d80debSLuiz Augusto von Dentz 			continue;
379273d80debSLuiz Augusto von Dentz 
379373d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
379473d80debSLuiz Augusto von Dentz 			continue;
379573d80debSLuiz Augusto von Dentz 
379673d80debSLuiz Augusto von Dentz 		conn_num++;
379773d80debSLuiz Augusto von Dentz 
37988192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
379973d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
380073d80debSLuiz Augusto von Dentz 
380173d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
380273d80debSLuiz Augusto von Dentz 				continue;
380373d80debSLuiz Augusto von Dentz 
380473d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
380573d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
380673d80debSLuiz Augusto von Dentz 				continue;
380773d80debSLuiz Augusto von Dentz 
380873d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
380973d80debSLuiz Augusto von Dentz 				num = 0;
381073d80debSLuiz Augusto von Dentz 				min = ~0;
381173d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
381273d80debSLuiz Augusto von Dentz 			}
381373d80debSLuiz Augusto von Dentz 
381473d80debSLuiz Augusto von Dentz 			num++;
381573d80debSLuiz Augusto von Dentz 
381673d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
381773d80debSLuiz Augusto von Dentz 				min  = conn->sent;
381873d80debSLuiz Augusto von Dentz 				chan = tmp;
381973d80debSLuiz Augusto von Dentz 			}
382073d80debSLuiz Augusto von Dentz 		}
382173d80debSLuiz Augusto von Dentz 
382273d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
382373d80debSLuiz Augusto von Dentz 			break;
382473d80debSLuiz Augusto von Dentz 	}
382573d80debSLuiz Augusto von Dentz 
3826bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3827bf4c6325SGustavo F. Padovan 
382873d80debSLuiz Augusto von Dentz 	if (!chan)
382973d80debSLuiz Augusto von Dentz 		return NULL;
383073d80debSLuiz Augusto von Dentz 
383173d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
383273d80debSLuiz Augusto von Dentz 	case ACL_LINK:
383373d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
383473d80debSLuiz Augusto von Dentz 		break;
3835bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
3836bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
3837bd1eb66bSAndrei Emeltchenko 		break;
383873d80debSLuiz Augusto von Dentz 	case SCO_LINK:
383973d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
384073d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
384173d80debSLuiz Augusto von Dentz 		break;
384273d80debSLuiz Augusto von Dentz 	case LE_LINK:
384373d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
384473d80debSLuiz Augusto von Dentz 		break;
384573d80debSLuiz Augusto von Dentz 	default:
384673d80debSLuiz Augusto von Dentz 		cnt = 0;
384773d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
384873d80debSLuiz Augusto von Dentz 	}
384973d80debSLuiz Augusto von Dentz 
385073d80debSLuiz Augusto von Dentz 	q = cnt / num;
385173d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
385273d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
385373d80debSLuiz Augusto von Dentz 	return chan;
385473d80debSLuiz Augusto von Dentz }
385573d80debSLuiz Augusto von Dentz 
385602b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
385702b20f0bSLuiz Augusto von Dentz {
385802b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
385902b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
386002b20f0bSLuiz Augusto von Dentz 	int num = 0;
386102b20f0bSLuiz Augusto von Dentz 
386202b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
386302b20f0bSLuiz Augusto von Dentz 
3864bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3865bf4c6325SGustavo F. Padovan 
3866bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
386702b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
386802b20f0bSLuiz Augusto von Dentz 
386902b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
387002b20f0bSLuiz Augusto von Dentz 			continue;
387102b20f0bSLuiz Augusto von Dentz 
387202b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
387302b20f0bSLuiz Augusto von Dentz 			continue;
387402b20f0bSLuiz Augusto von Dentz 
387502b20f0bSLuiz Augusto von Dentz 		num++;
387602b20f0bSLuiz Augusto von Dentz 
38778192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
387802b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
387902b20f0bSLuiz Augusto von Dentz 
388002b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
388102b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
388202b20f0bSLuiz Augusto von Dentz 				continue;
388302b20f0bSLuiz Augusto von Dentz 			}
388402b20f0bSLuiz Augusto von Dentz 
388502b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
388602b20f0bSLuiz Augusto von Dentz 				continue;
388702b20f0bSLuiz Augusto von Dentz 
388802b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
388902b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
389002b20f0bSLuiz Augusto von Dentz 				continue;
389102b20f0bSLuiz Augusto von Dentz 
389202b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
389302b20f0bSLuiz Augusto von Dentz 
389402b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
389502b20f0bSLuiz Augusto von Dentz 			       skb->priority);
389602b20f0bSLuiz Augusto von Dentz 		}
389702b20f0bSLuiz Augusto von Dentz 
389802b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
389902b20f0bSLuiz Augusto von Dentz 			break;
390002b20f0bSLuiz Augusto von Dentz 	}
3901bf4c6325SGustavo F. Padovan 
3902bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3903bf4c6325SGustavo F. Padovan 
390402b20f0bSLuiz Augusto von Dentz }
390502b20f0bSLuiz Augusto von Dentz 
3906b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
3907b71d385aSAndrei Emeltchenko {
3908b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
3909b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
3910b71d385aSAndrei Emeltchenko }
3911b71d385aSAndrei Emeltchenko 
39126039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
39131da177e4SLinus Torvalds {
3914d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
39151da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
39161da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
391763d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
39185f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
3919bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
39201da177e4SLinus Torvalds 	}
392163d2bc1bSAndrei Emeltchenko }
39221da177e4SLinus Torvalds 
39236039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
392463d2bc1bSAndrei Emeltchenko {
392563d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
392663d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
392763d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
392863d2bc1bSAndrei Emeltchenko 	int quote;
392963d2bc1bSAndrei Emeltchenko 
393063d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
393104837f64SMarcel Holtmann 
393273d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
393373d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
3934ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3935ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
393673d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
393773d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
393873d80debSLuiz Augusto von Dentz 
3939ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3940ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3941ec1cce24SLuiz Augusto von Dentz 				break;
3942ec1cce24SLuiz Augusto von Dentz 
3943ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3944ec1cce24SLuiz Augusto von Dentz 
394573d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
394673d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
394704837f64SMarcel Holtmann 
394857d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
39491da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
39501da177e4SLinus Torvalds 
39511da177e4SLinus Torvalds 			hdev->acl_cnt--;
395273d80debSLuiz Augusto von Dentz 			chan->sent++;
395373d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
39541da177e4SLinus Torvalds 		}
39551da177e4SLinus Torvalds 	}
395602b20f0bSLuiz Augusto von Dentz 
395702b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
395802b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
39591da177e4SLinus Torvalds }
39601da177e4SLinus Torvalds 
39616039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
3962b71d385aSAndrei Emeltchenko {
396363d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
3964b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
3965b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
3966b71d385aSAndrei Emeltchenko 	int quote;
3967bd1eb66bSAndrei Emeltchenko 	u8 type;
3968b71d385aSAndrei Emeltchenko 
396963d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
3970b71d385aSAndrei Emeltchenko 
3971bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3972bd1eb66bSAndrei Emeltchenko 
3973bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
3974bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
3975bd1eb66bSAndrei Emeltchenko 	else
3976bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
3977bd1eb66bSAndrei Emeltchenko 
3978b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
3979bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
3980b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
3981b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
3982b71d385aSAndrei Emeltchenko 			int blocks;
3983b71d385aSAndrei Emeltchenko 
3984b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
3985b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
3986b71d385aSAndrei Emeltchenko 
3987b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
3988b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
3989b71d385aSAndrei Emeltchenko 				break;
3990b71d385aSAndrei Emeltchenko 
3991b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
3992b71d385aSAndrei Emeltchenko 
3993b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
3994b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
3995b71d385aSAndrei Emeltchenko 				return;
3996b71d385aSAndrei Emeltchenko 
3997b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
3998b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
3999b71d385aSAndrei Emeltchenko 
400057d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
4001b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
4002b71d385aSAndrei Emeltchenko 
4003b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
4004b71d385aSAndrei Emeltchenko 			quote -= blocks;
4005b71d385aSAndrei Emeltchenko 
4006b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
4007b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
4008b71d385aSAndrei Emeltchenko 		}
4009b71d385aSAndrei Emeltchenko 	}
4010b71d385aSAndrei Emeltchenko 
4011b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
4012bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
4013b71d385aSAndrei Emeltchenko }
4014b71d385aSAndrei Emeltchenko 
40156039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
4016b71d385aSAndrei Emeltchenko {
4017b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
4018b71d385aSAndrei Emeltchenko 
4019bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
4020bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR)
4021bd1eb66bSAndrei Emeltchenko 		return;
4022bd1eb66bSAndrei Emeltchenko 
4023bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
4024bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
4025b71d385aSAndrei Emeltchenko 		return;
4026b71d385aSAndrei Emeltchenko 
4027b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
4028b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
4029b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
4030b71d385aSAndrei Emeltchenko 		break;
4031b71d385aSAndrei Emeltchenko 
4032b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
4033b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
4034b71d385aSAndrei Emeltchenko 		break;
4035b71d385aSAndrei Emeltchenko 	}
4036b71d385aSAndrei Emeltchenko }
4037b71d385aSAndrei Emeltchenko 
40381da177e4SLinus Torvalds /* Schedule SCO */
40396039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev)
40401da177e4SLinus Torvalds {
40411da177e4SLinus Torvalds 	struct hci_conn *conn;
40421da177e4SLinus Torvalds 	struct sk_buff *skb;
40431da177e4SLinus Torvalds 	int quote;
40441da177e4SLinus Torvalds 
40451da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
40461da177e4SLinus Torvalds 
404752087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
404852087a79SLuiz Augusto von Dentz 		return;
404952087a79SLuiz Augusto von Dentz 
40501da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
40511da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
40521da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
405357d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
40541da177e4SLinus Torvalds 
40551da177e4SLinus Torvalds 			conn->sent++;
40561da177e4SLinus Torvalds 			if (conn->sent == ~0)
40571da177e4SLinus Torvalds 				conn->sent = 0;
40581da177e4SLinus Torvalds 		}
40591da177e4SLinus Torvalds 	}
40601da177e4SLinus Torvalds }
40611da177e4SLinus Torvalds 
40626039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev)
4063b6a0dc82SMarcel Holtmann {
4064b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
4065b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
4066b6a0dc82SMarcel Holtmann 	int quote;
4067b6a0dc82SMarcel Holtmann 
4068b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
4069b6a0dc82SMarcel Holtmann 
407052087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
407152087a79SLuiz Augusto von Dentz 		return;
407252087a79SLuiz Augusto von Dentz 
40738fc9ced3SGustavo Padovan 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
40748fc9ced3SGustavo Padovan 						     &quote))) {
4075b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
4076b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
407757d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
4078b6a0dc82SMarcel Holtmann 
4079b6a0dc82SMarcel Holtmann 			conn->sent++;
4080b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
4081b6a0dc82SMarcel Holtmann 				conn->sent = 0;
4082b6a0dc82SMarcel Holtmann 		}
4083b6a0dc82SMarcel Holtmann 	}
4084b6a0dc82SMarcel Holtmann }
4085b6a0dc82SMarcel Holtmann 
40866039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
40876ed58ec5SVille Tervo {
408873d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
40896ed58ec5SVille Tervo 	struct sk_buff *skb;
409002b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
40916ed58ec5SVille Tervo 
40926ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
40936ed58ec5SVille Tervo 
409452087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
409552087a79SLuiz Augusto von Dentz 		return;
409652087a79SLuiz Augusto von Dentz 
4097d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
40986ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
40996ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
4100bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
41016ed58ec5SVille Tervo 		    time_after(jiffies, hdev->le_last_tx + HZ * 45))
4102bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
41036ed58ec5SVille Tervo 	}
41046ed58ec5SVille Tervo 
41056ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
410602b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
410773d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
4108ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
4109ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
411073d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
411173d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
41126ed58ec5SVille Tervo 
4113ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
4114ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
4115ec1cce24SLuiz Augusto von Dentz 				break;
4116ec1cce24SLuiz Augusto von Dentz 
4117ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
4118ec1cce24SLuiz Augusto von Dentz 
411957d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
41206ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
41216ed58ec5SVille Tervo 
41226ed58ec5SVille Tervo 			cnt--;
412373d80debSLuiz Augusto von Dentz 			chan->sent++;
412473d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
41256ed58ec5SVille Tervo 		}
41266ed58ec5SVille Tervo 	}
412773d80debSLuiz Augusto von Dentz 
41286ed58ec5SVille Tervo 	if (hdev->le_pkts)
41296ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
41306ed58ec5SVille Tervo 	else
41316ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
413202b20f0bSLuiz Augusto von Dentz 
413302b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
413402b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
41356ed58ec5SVille Tervo }
41366ed58ec5SVille Tervo 
41373eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
41381da177e4SLinus Torvalds {
41393eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
41401da177e4SLinus Torvalds 	struct sk_buff *skb;
41411da177e4SLinus Torvalds 
41426ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
41436ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
41441da177e4SLinus Torvalds 
4145d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
41461da177e4SLinus Torvalds 		/* Schedule queues and send stuff to HCI driver */
41471da177e4SLinus Torvalds 		hci_sched_acl(hdev);
41481da177e4SLinus Torvalds 		hci_sched_sco(hdev);
4149b6a0dc82SMarcel Holtmann 		hci_sched_esco(hdev);
41506ed58ec5SVille Tervo 		hci_sched_le(hdev);
415152de599eSMarcel Holtmann 	}
41526ed58ec5SVille Tervo 
41531da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
41541da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
415557d17d70SMarcel Holtmann 		hci_send_frame(hdev, skb);
41561da177e4SLinus Torvalds }
41571da177e4SLinus Torvalds 
415825985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
41591da177e4SLinus Torvalds 
41601da177e4SLinus Torvalds /* ACL data packet */
41616039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
41621da177e4SLinus Torvalds {
41631da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
41641da177e4SLinus Torvalds 	struct hci_conn *conn;
41651da177e4SLinus Torvalds 	__u16 handle, flags;
41661da177e4SLinus Torvalds 
41671da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
41681da177e4SLinus Torvalds 
41691da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
41701da177e4SLinus Torvalds 	flags  = hci_flags(handle);
41711da177e4SLinus Torvalds 	handle = hci_handle(handle);
41721da177e4SLinus Torvalds 
4173f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
4174a8c5fb1aSGustavo Padovan 	       handle, flags);
41751da177e4SLinus Torvalds 
41761da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
41771da177e4SLinus Torvalds 
41781da177e4SLinus Torvalds 	hci_dev_lock(hdev);
41791da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
41801da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
41811da177e4SLinus Torvalds 
41821da177e4SLinus Torvalds 	if (conn) {
418365983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
418404837f64SMarcel Holtmann 
41851da177e4SLinus Torvalds 		/* Send to upper protocol */
4186686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
41871da177e4SLinus Torvalds 		return;
41881da177e4SLinus Torvalds 	} else {
41891da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
41901da177e4SLinus Torvalds 		       hdev->name, handle);
41911da177e4SLinus Torvalds 	}
41921da177e4SLinus Torvalds 
41931da177e4SLinus Torvalds 	kfree_skb(skb);
41941da177e4SLinus Torvalds }
41951da177e4SLinus Torvalds 
41961da177e4SLinus Torvalds /* SCO data packet */
41976039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
41981da177e4SLinus Torvalds {
41991da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
42001da177e4SLinus Torvalds 	struct hci_conn *conn;
42011da177e4SLinus Torvalds 	__u16 handle;
42021da177e4SLinus Torvalds 
42031da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
42041da177e4SLinus Torvalds 
42051da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
42061da177e4SLinus Torvalds 
4207f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle);
42081da177e4SLinus Torvalds 
42091da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
42101da177e4SLinus Torvalds 
42111da177e4SLinus Torvalds 	hci_dev_lock(hdev);
42121da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
42131da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
42141da177e4SLinus Torvalds 
42151da177e4SLinus Torvalds 	if (conn) {
42161da177e4SLinus Torvalds 		/* Send to upper protocol */
4217686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
42181da177e4SLinus Torvalds 		return;
42191da177e4SLinus Torvalds 	} else {
42201da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
42211da177e4SLinus Torvalds 		       hdev->name, handle);
42221da177e4SLinus Torvalds 	}
42231da177e4SLinus Torvalds 
42241da177e4SLinus Torvalds 	kfree_skb(skb);
42251da177e4SLinus Torvalds }
42261da177e4SLinus Torvalds 
42279238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
42289238f36aSJohan Hedberg {
42299238f36aSJohan Hedberg 	struct sk_buff *skb;
42309238f36aSJohan Hedberg 
42319238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
42329238f36aSJohan Hedberg 	if (!skb)
42339238f36aSJohan Hedberg 		return true;
42349238f36aSJohan Hedberg 
4235db6e3e8dSJohan Hedberg 	return bt_cb(skb)->req.start;
42369238f36aSJohan Hedberg }
42379238f36aSJohan Hedberg 
423842c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
423942c6b129SJohan Hedberg {
424042c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
424142c6b129SJohan Hedberg 	struct sk_buff *skb;
424242c6b129SJohan Hedberg 	u16 opcode;
424342c6b129SJohan Hedberg 
424442c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
424542c6b129SJohan Hedberg 		return;
424642c6b129SJohan Hedberg 
424742c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
424842c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
424942c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
425042c6b129SJohan Hedberg 		return;
425142c6b129SJohan Hedberg 
425242c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
425342c6b129SJohan Hedberg 	if (!skb)
425442c6b129SJohan Hedberg 		return;
425542c6b129SJohan Hedberg 
425642c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
425742c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
425842c6b129SJohan Hedberg }
425942c6b129SJohan Hedberg 
4260e6214487SJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status,
4261e6214487SJohan Hedberg 			  hci_req_complete_t *req_complete,
4262e6214487SJohan Hedberg 			  hci_req_complete_skb_t *req_complete_skb)
42639238f36aSJohan Hedberg {
42649238f36aSJohan Hedberg 	struct sk_buff *skb;
42659238f36aSJohan Hedberg 	unsigned long flags;
42669238f36aSJohan Hedberg 
42679238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
42689238f36aSJohan Hedberg 
426942c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
427042c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
42719238f36aSJohan Hedberg 	 */
427242c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
427342c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
427442c6b129SJohan Hedberg 		 * reset complete event during init and any pending
427542c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
427642c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
427742c6b129SJohan Hedberg 		 * command.
427842c6b129SJohan Hedberg 		 */
427942c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
428042c6b129SJohan Hedberg 			hci_resend_last(hdev);
428142c6b129SJohan Hedberg 
42829238f36aSJohan Hedberg 		return;
428342c6b129SJohan Hedberg 	}
42849238f36aSJohan Hedberg 
42859238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
42869238f36aSJohan Hedberg 	 * this request the request is not yet complete.
42879238f36aSJohan Hedberg 	 */
42889238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
42899238f36aSJohan Hedberg 		return;
42909238f36aSJohan Hedberg 
42919238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
42929238f36aSJohan Hedberg 	 * callback would be found in hdev->sent_cmd instead of the
42939238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
42949238f36aSJohan Hedberg 	 */
4295e6214487SJohan Hedberg 	if (bt_cb(hdev->sent_cmd)->req.complete) {
4296e6214487SJohan Hedberg 		*req_complete = bt_cb(hdev->sent_cmd)->req.complete;
4297e6214487SJohan Hedberg 		return;
42989238f36aSJohan Hedberg 	}
4299e6214487SJohan Hedberg 
4300e6214487SJohan Hedberg 	if (bt_cb(hdev->sent_cmd)->req.complete_skb) {
4301e6214487SJohan Hedberg 		*req_complete_skb = bt_cb(hdev->sent_cmd)->req.complete_skb;
4302e6214487SJohan Hedberg 		return;
430353e21fbcSJohan Hedberg 	}
43049238f36aSJohan Hedberg 
43059238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
43069238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
43079238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
4308db6e3e8dSJohan Hedberg 		if (bt_cb(skb)->req.start) {
43099238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
43109238f36aSJohan Hedberg 			break;
43119238f36aSJohan Hedberg 		}
43129238f36aSJohan Hedberg 
4313e6214487SJohan Hedberg 		*req_complete = bt_cb(skb)->req.complete;
4314e6214487SJohan Hedberg 		*req_complete_skb = bt_cb(skb)->req.complete_skb;
43159238f36aSJohan Hedberg 		kfree_skb(skb);
43169238f36aSJohan Hedberg 	}
43179238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
43189238f36aSJohan Hedberg }
43199238f36aSJohan Hedberg 
4320b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
43211da177e4SLinus Torvalds {
4322b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
43231da177e4SLinus Torvalds 	struct sk_buff *skb;
43241da177e4SLinus Torvalds 
43251da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
43261da177e4SLinus Torvalds 
43271da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
4328cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
4329cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
4330cd82e61cSMarcel Holtmann 
43311da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
43321da177e4SLinus Torvalds 			/* Send copy to the sockets */
4333470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
43341da177e4SLinus Torvalds 		}
43351da177e4SLinus Torvalds 
4336d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
43371da177e4SLinus Torvalds 			kfree_skb(skb);
43381da177e4SLinus Torvalds 			continue;
43391da177e4SLinus Torvalds 		}
43401da177e4SLinus Torvalds 
43411da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
43421da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
43430d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
43441da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
43451da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
43461da177e4SLinus Torvalds 				kfree_skb(skb);
43471da177e4SLinus Torvalds 				continue;
43483ff50b79SStephen Hemminger 			}
43491da177e4SLinus Torvalds 		}
43501da177e4SLinus Torvalds 
43511da177e4SLinus Torvalds 		/* Process frame */
43520d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
43531da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
4354b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
43551da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
43561da177e4SLinus Torvalds 			break;
43571da177e4SLinus Torvalds 
43581da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
43591da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
43601da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
43611da177e4SLinus Torvalds 			break;
43621da177e4SLinus Torvalds 
43631da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
43641da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
43651da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
43661da177e4SLinus Torvalds 			break;
43671da177e4SLinus Torvalds 
43681da177e4SLinus Torvalds 		default:
43691da177e4SLinus Torvalds 			kfree_skb(skb);
43701da177e4SLinus Torvalds 			break;
43711da177e4SLinus Torvalds 		}
43721da177e4SLinus Torvalds 	}
43731da177e4SLinus Torvalds }
43741da177e4SLinus Torvalds 
4375c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
43761da177e4SLinus Torvalds {
4377c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
43781da177e4SLinus Torvalds 	struct sk_buff *skb;
43791da177e4SLinus Torvalds 
43802104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
43812104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
43821da177e4SLinus Torvalds 
43831da177e4SLinus Torvalds 	/* Send queued commands */
43845a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
43855a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
43865a08ecceSAndrei Emeltchenko 		if (!skb)
43875a08ecceSAndrei Emeltchenko 			return;
43885a08ecceSAndrei Emeltchenko 
43891da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
43901da177e4SLinus Torvalds 
4391a675d7f1SMarcel Holtmann 		hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
439270f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
43931da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
439457d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
43957bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
439665cc2b49SMarcel Holtmann 				cancel_delayed_work(&hdev->cmd_timer);
43977bdb8a5cSSzymon Janc 			else
439865cc2b49SMarcel Holtmann 				schedule_delayed_work(&hdev->cmd_timer,
439965cc2b49SMarcel Holtmann 						      HCI_CMD_TIMEOUT);
44001da177e4SLinus Torvalds 		} else {
44011da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
4402c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
44031da177e4SLinus Torvalds 		}
44041da177e4SLinus Torvalds 	}
44051da177e4SLinus Torvalds }
4406