xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 757aa0b5)
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 	int err;
984b4148e9SMarcel Holtmann 
994b4148e9SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
1004b4148e9SMarcel Holtmann 		return -ENETDOWN;
1014b4148e9SMarcel Holtmann 
1024b4148e9SMarcel Holtmann 	if (copy_from_user(buf, user_buf, buf_size))
1034b4148e9SMarcel Holtmann 		return -EFAULT;
1044b4148e9SMarcel Holtmann 
1054b4148e9SMarcel Holtmann 	buf[buf_size] = '\0';
1064b4148e9SMarcel Holtmann 	if (strtobool(buf, &enable))
1074b4148e9SMarcel Holtmann 		return -EINVAL;
1084b4148e9SMarcel Holtmann 
109b7cb93e5SMarcel Holtmann 	if (enable == hci_dev_test_flag(hdev, HCI_DUT_MODE))
1104b4148e9SMarcel Holtmann 		return -EALREADY;
1114b4148e9SMarcel Holtmann 
1124b4148e9SMarcel Holtmann 	hci_req_lock(hdev);
1134b4148e9SMarcel Holtmann 	if (enable)
1144b4148e9SMarcel Holtmann 		skb = __hci_cmd_sync(hdev, HCI_OP_ENABLE_DUT_MODE, 0, NULL,
1154b4148e9SMarcel Holtmann 				     HCI_CMD_TIMEOUT);
1164b4148e9SMarcel Holtmann 	else
1174b4148e9SMarcel Holtmann 		skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL,
1184b4148e9SMarcel Holtmann 				     HCI_CMD_TIMEOUT);
1194b4148e9SMarcel Holtmann 	hci_req_unlock(hdev);
1204b4148e9SMarcel Holtmann 
1214b4148e9SMarcel Holtmann 	if (IS_ERR(skb))
1224b4148e9SMarcel Holtmann 		return PTR_ERR(skb);
1234b4148e9SMarcel Holtmann 
1244b4148e9SMarcel Holtmann 	err = -bt_to_errno(skb->data[0]);
1254b4148e9SMarcel Holtmann 	kfree_skb(skb);
1264b4148e9SMarcel Holtmann 
1274b4148e9SMarcel Holtmann 	if (err < 0)
1284b4148e9SMarcel Holtmann 		return err;
1294b4148e9SMarcel Holtmann 
130b7cb93e5SMarcel Holtmann 	hci_dev_change_flag(hdev, HCI_DUT_MODE);
1314b4148e9SMarcel Holtmann 
1324b4148e9SMarcel Holtmann 	return count;
1334b4148e9SMarcel Holtmann }
1344b4148e9SMarcel Holtmann 
1354b4148e9SMarcel Holtmann static const struct file_operations dut_mode_fops = {
1364b4148e9SMarcel Holtmann 	.open		= simple_open,
1374b4148e9SMarcel Holtmann 	.read		= dut_mode_read,
1384b4148e9SMarcel Holtmann 	.write		= dut_mode_write,
1394b4148e9SMarcel Holtmann 	.llseek		= default_llseek,
1404b4148e9SMarcel Holtmann };
1414b4148e9SMarcel Holtmann 
1421da177e4SLinus Torvalds /* ---- HCI requests ---- */
1431da177e4SLinus Torvalds 
144f60cb305SJohan Hedberg static void hci_req_sync_complete(struct hci_dev *hdev, u8 result, u16 opcode,
145f60cb305SJohan Hedberg 				  struct sk_buff *skb)
1461da177e4SLinus Torvalds {
14742c6b129SJohan Hedberg 	BT_DBG("%s result 0x%2.2x", hdev->name, result);
14875fb0e32SJohan Hedberg 
1491da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
1501da177e4SLinus Torvalds 		hdev->req_result = result;
1511da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_DONE;
152f60cb305SJohan Hedberg 		if (skb)
153f60cb305SJohan Hedberg 			hdev->req_skb = skb_get(skb);
1541da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
1551da177e4SLinus Torvalds 	}
1561da177e4SLinus Torvalds }
1571da177e4SLinus Torvalds 
1581da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err)
1591da177e4SLinus Torvalds {
1601da177e4SLinus Torvalds 	BT_DBG("%s err 0x%2.2x", hdev->name, err);
1611da177e4SLinus Torvalds 
1621da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
1631da177e4SLinus Torvalds 		hdev->req_result = err;
1641da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_CANCELED;
1651da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
1661da177e4SLinus Torvalds 	}
1671da177e4SLinus Torvalds }
1681da177e4SLinus Torvalds 
1697b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
17007dc93ddSJohan Hedberg 				  const void *param, u8 event, u32 timeout)
17175e84b7cSJohan Hedberg {
17275e84b7cSJohan Hedberg 	DECLARE_WAITQUEUE(wait, current);
17375e84b7cSJohan Hedberg 	struct hci_request req;
174f60cb305SJohan Hedberg 	struct sk_buff *skb;
17575e84b7cSJohan Hedberg 	int err = 0;
17675e84b7cSJohan Hedberg 
17775e84b7cSJohan Hedberg 	BT_DBG("%s", hdev->name);
17875e84b7cSJohan Hedberg 
17975e84b7cSJohan Hedberg 	hci_req_init(&req, hdev);
18075e84b7cSJohan Hedberg 
1817b1abbbeSJohan Hedberg 	hci_req_add_ev(&req, opcode, plen, param, event);
18275e84b7cSJohan Hedberg 
18375e84b7cSJohan Hedberg 	hdev->req_status = HCI_REQ_PEND;
18475e84b7cSJohan Hedberg 
18575e84b7cSJohan Hedberg 	add_wait_queue(&hdev->req_wait_q, &wait);
18675e84b7cSJohan Hedberg 	set_current_state(TASK_INTERRUPTIBLE);
18775e84b7cSJohan Hedberg 
188f60cb305SJohan Hedberg 	err = hci_req_run_skb(&req, hci_req_sync_complete);
189039fada5SChan-yeol Park 	if (err < 0) {
190039fada5SChan-yeol Park 		remove_wait_queue(&hdev->req_wait_q, &wait);
19122a3ceabSJohan Hedberg 		set_current_state(TASK_RUNNING);
192039fada5SChan-yeol Park 		return ERR_PTR(err);
193039fada5SChan-yeol Park 	}
194039fada5SChan-yeol Park 
19575e84b7cSJohan Hedberg 	schedule_timeout(timeout);
19675e84b7cSJohan Hedberg 
19775e84b7cSJohan Hedberg 	remove_wait_queue(&hdev->req_wait_q, &wait);
19875e84b7cSJohan Hedberg 
19975e84b7cSJohan Hedberg 	if (signal_pending(current))
20075e84b7cSJohan Hedberg 		return ERR_PTR(-EINTR);
20175e84b7cSJohan Hedberg 
20275e84b7cSJohan Hedberg 	switch (hdev->req_status) {
20375e84b7cSJohan Hedberg 	case HCI_REQ_DONE:
20475e84b7cSJohan Hedberg 		err = -bt_to_errno(hdev->req_result);
20575e84b7cSJohan Hedberg 		break;
20675e84b7cSJohan Hedberg 
20775e84b7cSJohan Hedberg 	case HCI_REQ_CANCELED:
20875e84b7cSJohan Hedberg 		err = -hdev->req_result;
20975e84b7cSJohan Hedberg 		break;
21075e84b7cSJohan Hedberg 
21175e84b7cSJohan Hedberg 	default:
21275e84b7cSJohan Hedberg 		err = -ETIMEDOUT;
21375e84b7cSJohan Hedberg 		break;
21475e84b7cSJohan Hedberg 	}
21575e84b7cSJohan Hedberg 
21675e84b7cSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
217f60cb305SJohan Hedberg 	skb = hdev->req_skb;
218f60cb305SJohan Hedberg 	hdev->req_skb = NULL;
21975e84b7cSJohan Hedberg 
22075e84b7cSJohan Hedberg 	BT_DBG("%s end: err %d", hdev->name, err);
22175e84b7cSJohan Hedberg 
222f60cb305SJohan Hedberg 	if (err < 0) {
223f60cb305SJohan Hedberg 		kfree_skb(skb);
22475e84b7cSJohan Hedberg 		return ERR_PTR(err);
225f60cb305SJohan Hedberg 	}
22675e84b7cSJohan Hedberg 
227757aa0b5SJohan Hedberg 	if (!skb)
228757aa0b5SJohan Hedberg 		return ERR_PTR(-ENODATA);
229757aa0b5SJohan Hedberg 
230757aa0b5SJohan Hedberg 	return skb;
2317b1abbbeSJohan Hedberg }
2327b1abbbeSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync_ev);
2337b1abbbeSJohan Hedberg 
2347b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
23507dc93ddSJohan Hedberg 			       const void *param, u32 timeout)
2367b1abbbeSJohan Hedberg {
2377b1abbbeSJohan Hedberg 	return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout);
23875e84b7cSJohan Hedberg }
23975e84b7cSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync);
24075e84b7cSJohan Hedberg 
2411da177e4SLinus Torvalds /* Execute request and wait for completion. */
24201178cd4SJohan Hedberg static int __hci_req_sync(struct hci_dev *hdev,
24342c6b129SJohan Hedberg 			  void (*func)(struct hci_request *req,
24442c6b129SJohan Hedberg 				      unsigned long opt),
2451da177e4SLinus Torvalds 			  unsigned long opt, __u32 timeout)
2461da177e4SLinus Torvalds {
24742c6b129SJohan Hedberg 	struct hci_request req;
2481da177e4SLinus Torvalds 	DECLARE_WAITQUEUE(wait, current);
2491da177e4SLinus Torvalds 	int err = 0;
2501da177e4SLinus Torvalds 
2511da177e4SLinus Torvalds 	BT_DBG("%s start", hdev->name);
2521da177e4SLinus Torvalds 
25342c6b129SJohan Hedberg 	hci_req_init(&req, hdev);
25442c6b129SJohan Hedberg 
2551da177e4SLinus Torvalds 	hdev->req_status = HCI_REQ_PEND;
2561da177e4SLinus Torvalds 
25742c6b129SJohan Hedberg 	func(&req, opt);
25853cce22dSJohan Hedberg 
259039fada5SChan-yeol Park 	add_wait_queue(&hdev->req_wait_q, &wait);
260039fada5SChan-yeol Park 	set_current_state(TASK_INTERRUPTIBLE);
261039fada5SChan-yeol Park 
262f60cb305SJohan Hedberg 	err = hci_req_run_skb(&req, hci_req_sync_complete);
26342c6b129SJohan Hedberg 	if (err < 0) {
26453cce22dSJohan Hedberg 		hdev->req_status = 0;
265920c8300SAndre Guedes 
266039fada5SChan-yeol Park 		remove_wait_queue(&hdev->req_wait_q, &wait);
26722a3ceabSJohan Hedberg 		set_current_state(TASK_RUNNING);
268039fada5SChan-yeol Park 
269920c8300SAndre Guedes 		/* ENODATA means the HCI request command queue is empty.
270920c8300SAndre Guedes 		 * This can happen when a request with conditionals doesn't
271920c8300SAndre Guedes 		 * trigger any commands to be sent. This is normal behavior
272920c8300SAndre Guedes 		 * and should not trigger an error return.
27342c6b129SJohan Hedberg 		 */
274920c8300SAndre Guedes 		if (err == -ENODATA)
27542c6b129SJohan Hedberg 			return 0;
276920c8300SAndre Guedes 
277920c8300SAndre Guedes 		return err;
27853cce22dSJohan Hedberg 	}
27953cce22dSJohan Hedberg 
2801da177e4SLinus Torvalds 	schedule_timeout(timeout);
2811da177e4SLinus Torvalds 
2821da177e4SLinus Torvalds 	remove_wait_queue(&hdev->req_wait_q, &wait);
2831da177e4SLinus Torvalds 
2841da177e4SLinus Torvalds 	if (signal_pending(current))
2851da177e4SLinus Torvalds 		return -EINTR;
2861da177e4SLinus Torvalds 
2871da177e4SLinus Torvalds 	switch (hdev->req_status) {
2881da177e4SLinus Torvalds 	case HCI_REQ_DONE:
289e175072fSJoe Perches 		err = -bt_to_errno(hdev->req_result);
2901da177e4SLinus Torvalds 		break;
2911da177e4SLinus Torvalds 
2921da177e4SLinus Torvalds 	case HCI_REQ_CANCELED:
2931da177e4SLinus Torvalds 		err = -hdev->req_result;
2941da177e4SLinus Torvalds 		break;
2951da177e4SLinus Torvalds 
2961da177e4SLinus Torvalds 	default:
2971da177e4SLinus Torvalds 		err = -ETIMEDOUT;
2981da177e4SLinus Torvalds 		break;
2993ff50b79SStephen Hemminger 	}
3001da177e4SLinus Torvalds 
301a5040efaSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
3021da177e4SLinus Torvalds 
3031da177e4SLinus Torvalds 	BT_DBG("%s end: err %d", hdev->name, err);
3041da177e4SLinus Torvalds 
3051da177e4SLinus Torvalds 	return err;
3061da177e4SLinus Torvalds }
3071da177e4SLinus Torvalds 
30801178cd4SJohan Hedberg static int hci_req_sync(struct hci_dev *hdev,
30942c6b129SJohan Hedberg 			void (*req)(struct hci_request *req,
31042c6b129SJohan Hedberg 				    unsigned long opt),
3111da177e4SLinus Torvalds 			unsigned long opt, __u32 timeout)
3121da177e4SLinus Torvalds {
3131da177e4SLinus Torvalds 	int ret;
3141da177e4SLinus Torvalds 
3157c6a329eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
3167c6a329eSMarcel Holtmann 		return -ENETDOWN;
3177c6a329eSMarcel Holtmann 
3181da177e4SLinus Torvalds 	/* Serialize all requests */
3191da177e4SLinus Torvalds 	hci_req_lock(hdev);
32001178cd4SJohan Hedberg 	ret = __hci_req_sync(hdev, req, opt, timeout);
3211da177e4SLinus Torvalds 	hci_req_unlock(hdev);
3221da177e4SLinus Torvalds 
3231da177e4SLinus Torvalds 	return ret;
3241da177e4SLinus Torvalds }
3251da177e4SLinus Torvalds 
32642c6b129SJohan Hedberg static void hci_reset_req(struct hci_request *req, unsigned long opt)
3271da177e4SLinus Torvalds {
32842c6b129SJohan Hedberg 	BT_DBG("%s %ld", req->hdev->name, opt);
3291da177e4SLinus Torvalds 
3301da177e4SLinus Torvalds 	/* Reset device */
33142c6b129SJohan Hedberg 	set_bit(HCI_RESET, &req->hdev->flags);
33242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_RESET, 0, NULL);
3331da177e4SLinus Torvalds }
3341da177e4SLinus Torvalds 
33542c6b129SJohan Hedberg static void bredr_init(struct hci_request *req)
3361da177e4SLinus Torvalds {
33742c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
3382455a3eaSAndrei Emeltchenko 
3391da177e4SLinus Torvalds 	/* Read Local Supported Features */
34042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
3411da177e4SLinus Torvalds 
3421143e5a6SMarcel Holtmann 	/* Read Local Version */
34342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
3442177bab5SJohan Hedberg 
3452177bab5SJohan Hedberg 	/* Read BD Address */
34642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
3471da177e4SLinus Torvalds }
3481da177e4SLinus Torvalds 
3490af801b9SJohan Hedberg static void amp_init1(struct hci_request *req)
350e61ef499SAndrei Emeltchenko {
35142c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
3522455a3eaSAndrei Emeltchenko 
353e61ef499SAndrei Emeltchenko 	/* Read Local Version */
35442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
3556bcbc489SAndrei Emeltchenko 
356f6996cfeSMarcel Holtmann 	/* Read Local Supported Commands */
357f6996cfeSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
358f6996cfeSMarcel Holtmann 
3596bcbc489SAndrei Emeltchenko 	/* Read Local AMP Info */
36042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
361e71dfabaSAndrei Emeltchenko 
362e71dfabaSAndrei Emeltchenko 	/* Read Data Blk size */
36342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL);
3647528ca1cSMarcel Holtmann 
365f38ba941SMarcel Holtmann 	/* Read Flow Control Mode */
366f38ba941SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL);
367f38ba941SMarcel Holtmann 
3687528ca1cSMarcel Holtmann 	/* Read Location Data */
3697528ca1cSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL);
370e61ef499SAndrei Emeltchenko }
371e61ef499SAndrei Emeltchenko 
3720af801b9SJohan Hedberg static void amp_init2(struct hci_request *req)
3730af801b9SJohan Hedberg {
3740af801b9SJohan Hedberg 	/* Read Local Supported Features. Not all AMP controllers
3750af801b9SJohan Hedberg 	 * support this so it's placed conditionally in the second
3760af801b9SJohan Hedberg 	 * stage init.
3770af801b9SJohan Hedberg 	 */
3780af801b9SJohan Hedberg 	if (req->hdev->commands[14] & 0x20)
3790af801b9SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
3800af801b9SJohan Hedberg }
3810af801b9SJohan Hedberg 
38242c6b129SJohan Hedberg static void hci_init1_req(struct hci_request *req, unsigned long opt)
383e61ef499SAndrei Emeltchenko {
38442c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
385e61ef499SAndrei Emeltchenko 
386e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
387e61ef499SAndrei Emeltchenko 
38811778716SAndrei Emeltchenko 	/* Reset */
38911778716SAndrei Emeltchenko 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
39042c6b129SJohan Hedberg 		hci_reset_req(req, 0);
39111778716SAndrei Emeltchenko 
392e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
393e61ef499SAndrei Emeltchenko 	case HCI_BREDR:
39442c6b129SJohan Hedberg 		bredr_init(req);
395e61ef499SAndrei Emeltchenko 		break;
396e61ef499SAndrei Emeltchenko 
397e61ef499SAndrei Emeltchenko 	case HCI_AMP:
3980af801b9SJohan Hedberg 		amp_init1(req);
399e61ef499SAndrei Emeltchenko 		break;
400e61ef499SAndrei Emeltchenko 
401e61ef499SAndrei Emeltchenko 	default:
402e61ef499SAndrei Emeltchenko 		BT_ERR("Unknown device type %d", hdev->dev_type);
403e61ef499SAndrei Emeltchenko 		break;
404e61ef499SAndrei Emeltchenko 	}
405e61ef499SAndrei Emeltchenko }
406e61ef499SAndrei Emeltchenko 
40742c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req)
4082177bab5SJohan Hedberg {
4092177bab5SJohan Hedberg 	__le16 param;
4102177bab5SJohan Hedberg 	__u8 flt_type;
4112177bab5SJohan Hedberg 
4122177bab5SJohan Hedberg 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
41342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
4142177bab5SJohan Hedberg 
4152177bab5SJohan Hedberg 	/* Read Class of Device */
41642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
4172177bab5SJohan Hedberg 
4182177bab5SJohan Hedberg 	/* Read Local Name */
41942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL);
4202177bab5SJohan Hedberg 
4212177bab5SJohan Hedberg 	/* Read Voice Setting */
42242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL);
4232177bab5SJohan Hedberg 
424b4cb9fb2SMarcel Holtmann 	/* Read Number of Supported IAC */
425b4cb9fb2SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL);
426b4cb9fb2SMarcel Holtmann 
4274b836f39SMarcel Holtmann 	/* Read Current IAC LAP */
4284b836f39SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL);
4294b836f39SMarcel Holtmann 
4302177bab5SJohan Hedberg 	/* Clear Event Filters */
4312177bab5SJohan Hedberg 	flt_type = HCI_FLT_CLEAR_ALL;
43242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
4332177bab5SJohan Hedberg 
4342177bab5SJohan Hedberg 	/* Connection accept timeout ~20 secs */
435dcf4adbfSJoe Perches 	param = cpu_to_le16(0x7d00);
43642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
4372177bab5SJohan Hedberg }
4382177bab5SJohan Hedberg 
43942c6b129SJohan Hedberg static void le_setup(struct hci_request *req)
4402177bab5SJohan Hedberg {
441c73eee91SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
442c73eee91SJohan Hedberg 
4432177bab5SJohan Hedberg 	/* Read LE Buffer Size */
44442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
4452177bab5SJohan Hedberg 
4462177bab5SJohan Hedberg 	/* Read LE Local Supported Features */
44742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
4482177bab5SJohan Hedberg 
449747d3f03SMarcel Holtmann 	/* Read LE Supported States */
450747d3f03SMarcel Holtmann 	hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);
451747d3f03SMarcel Holtmann 
4522177bab5SJohan Hedberg 	/* Read LE White List Size */
45342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL);
4542177bab5SJohan Hedberg 
455747d3f03SMarcel Holtmann 	/* Clear LE White List */
456747d3f03SMarcel Holtmann 	hci_req_add(req, HCI_OP_LE_CLEAR_WHITE_LIST, 0, NULL);
457c73eee91SJohan Hedberg 
458c73eee91SJohan Hedberg 	/* LE-only controllers have LE implicitly enabled */
459c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
460a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_LE_ENABLED);
4612177bab5SJohan Hedberg }
4622177bab5SJohan Hedberg 
46342c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req)
4642177bab5SJohan Hedberg {
46542c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
46642c6b129SJohan Hedberg 
4672177bab5SJohan Hedberg 	/* The second byte is 0xff instead of 0x9f (two reserved bits
4682177bab5SJohan Hedberg 	 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
4692177bab5SJohan Hedberg 	 * command otherwise.
4702177bab5SJohan Hedberg 	 */
4712177bab5SJohan Hedberg 	u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
4722177bab5SJohan Hedberg 
4732177bab5SJohan Hedberg 	/* CSR 1.1 dongles does not accept any bitfield so don't try to set
4742177bab5SJohan Hedberg 	 * any event mask for pre 1.2 devices.
4752177bab5SJohan Hedberg 	 */
4762177bab5SJohan Hedberg 	if (hdev->hci_ver < BLUETOOTH_VER_1_2)
4772177bab5SJohan Hedberg 		return;
4782177bab5SJohan Hedberg 
4792177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
4802177bab5SJohan Hedberg 		events[4] |= 0x01; /* Flow Specification Complete */
4812177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
4822177bab5SJohan Hedberg 		events[4] |= 0x04; /* Read Remote Extended Features Complete */
4832177bab5SJohan Hedberg 		events[5] |= 0x08; /* Synchronous Connection Complete */
4842177bab5SJohan Hedberg 		events[5] |= 0x10; /* Synchronous Connection Changed */
485c7882cbdSMarcel Holtmann 	} else {
486c7882cbdSMarcel Holtmann 		/* Use a different default for LE-only devices */
487c7882cbdSMarcel Holtmann 		memset(events, 0, sizeof(events));
488c7882cbdSMarcel Holtmann 		events[0] |= 0x10; /* Disconnection Complete */
489c7882cbdSMarcel Holtmann 		events[1] |= 0x08; /* Read Remote Version Information Complete */
490c7882cbdSMarcel Holtmann 		events[1] |= 0x20; /* Command Complete */
491c7882cbdSMarcel Holtmann 		events[1] |= 0x40; /* Command Status */
492c7882cbdSMarcel Holtmann 		events[1] |= 0x80; /* Hardware Error */
493c7882cbdSMarcel Holtmann 		events[2] |= 0x04; /* Number of Completed Packets */
494c7882cbdSMarcel Holtmann 		events[3] |= 0x02; /* Data Buffer Overflow */
4950da71f1bSMarcel Holtmann 
4960da71f1bSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_ENCRYPTION) {
4970da71f1bSMarcel Holtmann 			events[0] |= 0x80; /* Encryption Change */
498c7882cbdSMarcel Holtmann 			events[5] |= 0x80; /* Encryption Key Refresh Complete */
4992177bab5SJohan Hedberg 		}
5000da71f1bSMarcel Holtmann 	}
5012177bab5SJohan Hedberg 
5022177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
5032177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
5042177bab5SJohan Hedberg 
5052177bab5SJohan Hedberg 	if (lmp_sniffsubr_capable(hdev))
5062177bab5SJohan Hedberg 		events[5] |= 0x20; /* Sniff Subrating */
5072177bab5SJohan Hedberg 
5082177bab5SJohan Hedberg 	if (lmp_pause_enc_capable(hdev))
5092177bab5SJohan Hedberg 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
5102177bab5SJohan Hedberg 
5112177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
5122177bab5SJohan Hedberg 		events[5] |= 0x40; /* Extended Inquiry Result */
5132177bab5SJohan Hedberg 
5142177bab5SJohan Hedberg 	if (lmp_no_flush_capable(hdev))
5152177bab5SJohan Hedberg 		events[7] |= 0x01; /* Enhanced Flush Complete */
5162177bab5SJohan Hedberg 
5172177bab5SJohan Hedberg 	if (lmp_lsto_capable(hdev))
5182177bab5SJohan Hedberg 		events[6] |= 0x80; /* Link Supervision Timeout Changed */
5192177bab5SJohan Hedberg 
5202177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
5212177bab5SJohan Hedberg 		events[6] |= 0x01;	/* IO Capability Request */
5222177bab5SJohan Hedberg 		events[6] |= 0x02;	/* IO Capability Response */
5232177bab5SJohan Hedberg 		events[6] |= 0x04;	/* User Confirmation Request */
5242177bab5SJohan Hedberg 		events[6] |= 0x08;	/* User Passkey Request */
5252177bab5SJohan Hedberg 		events[6] |= 0x10;	/* Remote OOB Data Request */
5262177bab5SJohan Hedberg 		events[6] |= 0x20;	/* Simple Pairing Complete */
5272177bab5SJohan Hedberg 		events[7] |= 0x04;	/* User Passkey Notification */
5282177bab5SJohan Hedberg 		events[7] |= 0x08;	/* Keypress Notification */
5292177bab5SJohan Hedberg 		events[7] |= 0x10;	/* Remote Host Supported
5302177bab5SJohan Hedberg 					 * Features Notification
5312177bab5SJohan Hedberg 					 */
5322177bab5SJohan Hedberg 	}
5332177bab5SJohan Hedberg 
5342177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
5352177bab5SJohan Hedberg 		events[7] |= 0x20;	/* LE Meta-Event */
5362177bab5SJohan Hedberg 
53742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
5382177bab5SJohan Hedberg }
5392177bab5SJohan Hedberg 
54042c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt)
5412177bab5SJohan Hedberg {
54242c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
54342c6b129SJohan Hedberg 
5440af801b9SJohan Hedberg 	if (hdev->dev_type == HCI_AMP)
5450af801b9SJohan Hedberg 		return amp_init2(req);
5460af801b9SJohan Hedberg 
5472177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev))
54842c6b129SJohan Hedberg 		bredr_setup(req);
54956f87901SJohan Hedberg 	else
550a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_BREDR_ENABLED);
5512177bab5SJohan Hedberg 
5522177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
55342c6b129SJohan Hedberg 		le_setup(req);
5542177bab5SJohan Hedberg 
5550f3adeaeSMarcel Holtmann 	/* All Bluetooth 1.2 and later controllers should support the
5560f3adeaeSMarcel Holtmann 	 * HCI command for reading the local supported commands.
5570f3adeaeSMarcel Holtmann 	 *
5580f3adeaeSMarcel Holtmann 	 * Unfortunately some controllers indicate Bluetooth 1.2 support,
5590f3adeaeSMarcel Holtmann 	 * but do not have support for this command. If that is the case,
5600f3adeaeSMarcel Holtmann 	 * the driver can quirk the behavior and skip reading the local
5610f3adeaeSMarcel Holtmann 	 * supported commands.
5623f8e2d75SJohan Hedberg 	 */
5630f3adeaeSMarcel Holtmann 	if (hdev->hci_ver > BLUETOOTH_VER_1_1 &&
5640f3adeaeSMarcel Holtmann 	    !test_bit(HCI_QUIRK_BROKEN_LOCAL_COMMANDS, &hdev->quirks))
56542c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
5662177bab5SJohan Hedberg 
5672177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
56857af75a8SMarcel Holtmann 		/* When SSP is available, then the host features page
56957af75a8SMarcel Holtmann 		 * should also be available as well. However some
57057af75a8SMarcel Holtmann 		 * controllers list the max_page as 0 as long as SSP
57157af75a8SMarcel Holtmann 		 * has not been enabled. To achieve proper debugging
57257af75a8SMarcel Holtmann 		 * output, force the minimum max_page to 1 at least.
57357af75a8SMarcel Holtmann 		 */
57457af75a8SMarcel Holtmann 		hdev->max_page = 0x01;
57557af75a8SMarcel Holtmann 
576d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED)) {
5772177bab5SJohan Hedberg 			u8 mode = 0x01;
578574ea3c7SMarcel Holtmann 
57942c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_SSP_MODE,
5802177bab5SJohan Hedberg 				    sizeof(mode), &mode);
5812177bab5SJohan Hedberg 		} else {
5822177bab5SJohan Hedberg 			struct hci_cp_write_eir cp;
5832177bab5SJohan Hedberg 
5842177bab5SJohan Hedberg 			memset(hdev->eir, 0, sizeof(hdev->eir));
5852177bab5SJohan Hedberg 			memset(&cp, 0, sizeof(cp));
5862177bab5SJohan Hedberg 
58742c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
5882177bab5SJohan Hedberg 		}
5892177bab5SJohan Hedberg 	}
5902177bab5SJohan Hedberg 
591043ec9bfSMarcel Holtmann 	if (lmp_inq_rssi_capable(hdev) ||
592043ec9bfSMarcel Holtmann 	    test_bit(HCI_QUIRK_FIXUP_INQUIRY_MODE, &hdev->quirks)) {
59304422da9SMarcel Holtmann 		u8 mode;
59404422da9SMarcel Holtmann 
59504422da9SMarcel Holtmann 		/* If Extended Inquiry Result events are supported, then
59604422da9SMarcel Holtmann 		 * they are clearly preferred over Inquiry Result with RSSI
59704422da9SMarcel Holtmann 		 * events.
59804422da9SMarcel Holtmann 		 */
59904422da9SMarcel Holtmann 		mode = lmp_ext_inq_capable(hdev) ? 0x02 : 0x01;
60004422da9SMarcel Holtmann 
60104422da9SMarcel Holtmann 		hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
60204422da9SMarcel Holtmann 	}
6032177bab5SJohan Hedberg 
6042177bab5SJohan Hedberg 	if (lmp_inq_tx_pwr_capable(hdev))
60542c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
6062177bab5SJohan Hedberg 
6072177bab5SJohan Hedberg 	if (lmp_ext_feat_capable(hdev)) {
6082177bab5SJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
6092177bab5SJohan Hedberg 
6102177bab5SJohan Hedberg 		cp.page = 0x01;
61142c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
61242c6b129SJohan Hedberg 			    sizeof(cp), &cp);
6132177bab5SJohan Hedberg 	}
6142177bab5SJohan Hedberg 
615d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_LINK_SECURITY)) {
6162177bab5SJohan Hedberg 		u8 enable = 1;
61742c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
6182177bab5SJohan Hedberg 			    &enable);
6192177bab5SJohan Hedberg 	}
6202177bab5SJohan Hedberg }
6212177bab5SJohan Hedberg 
62242c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req)
6232177bab5SJohan Hedberg {
62442c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
6252177bab5SJohan Hedberg 	struct hci_cp_write_def_link_policy cp;
6262177bab5SJohan Hedberg 	u16 link_policy = 0;
6272177bab5SJohan Hedberg 
6282177bab5SJohan Hedberg 	if (lmp_rswitch_capable(hdev))
6292177bab5SJohan Hedberg 		link_policy |= HCI_LP_RSWITCH;
6302177bab5SJohan Hedberg 	if (lmp_hold_capable(hdev))
6312177bab5SJohan Hedberg 		link_policy |= HCI_LP_HOLD;
6322177bab5SJohan Hedberg 	if (lmp_sniff_capable(hdev))
6332177bab5SJohan Hedberg 		link_policy |= HCI_LP_SNIFF;
6342177bab5SJohan Hedberg 	if (lmp_park_capable(hdev))
6352177bab5SJohan Hedberg 		link_policy |= HCI_LP_PARK;
6362177bab5SJohan Hedberg 
6372177bab5SJohan Hedberg 	cp.policy = cpu_to_le16(link_policy);
63842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp);
6392177bab5SJohan Hedberg }
6402177bab5SJohan Hedberg 
64142c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req)
6422177bab5SJohan Hedberg {
64342c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
6442177bab5SJohan Hedberg 	struct hci_cp_write_le_host_supported cp;
6452177bab5SJohan Hedberg 
646c73eee91SJohan Hedberg 	/* LE-only devices do not support explicit enablement */
647c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
648c73eee91SJohan Hedberg 		return;
649c73eee91SJohan Hedberg 
6502177bab5SJohan Hedberg 	memset(&cp, 0, sizeof(cp));
6512177bab5SJohan Hedberg 
652d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_LE_ENABLED)) {
6532177bab5SJohan Hedberg 		cp.le = 0x01;
65432226e4fSMarcel Holtmann 		cp.simul = 0x00;
6552177bab5SJohan Hedberg 	}
6562177bab5SJohan Hedberg 
6572177bab5SJohan Hedberg 	if (cp.le != lmp_host_le_capable(hdev))
65842c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
6592177bab5SJohan Hedberg 			    &cp);
6602177bab5SJohan Hedberg }
6612177bab5SJohan Hedberg 
662d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req)
663d62e6d67SJohan Hedberg {
664d62e6d67SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
665d62e6d67SJohan Hedberg 	u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
666d62e6d67SJohan Hedberg 
667d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast master role is supported
668d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
669d62e6d67SJohan Hedberg 	 */
67053b834d2SMarcel Holtmann 	if (lmp_csb_master_capable(hdev)) {
671d62e6d67SJohan Hedberg 		events[1] |= 0x40;	/* Triggered Clock Capture */
672d62e6d67SJohan Hedberg 		events[1] |= 0x80;	/* Synchronization Train Complete */
673d62e6d67SJohan Hedberg 		events[2] |= 0x10;	/* Slave Page Response Timeout */
674d62e6d67SJohan Hedberg 		events[2] |= 0x20;	/* CSB Channel Map Change */
675d62e6d67SJohan Hedberg 	}
676d62e6d67SJohan Hedberg 
677d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast slave role is supported
678d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
679d62e6d67SJohan Hedberg 	 */
68053b834d2SMarcel Holtmann 	if (lmp_csb_slave_capable(hdev)) {
681d62e6d67SJohan Hedberg 		events[2] |= 0x01;	/* Synchronization Train Received */
682d62e6d67SJohan Hedberg 		events[2] |= 0x02;	/* CSB Receive */
683d62e6d67SJohan Hedberg 		events[2] |= 0x04;	/* CSB Timeout */
684d62e6d67SJohan Hedberg 		events[2] |= 0x08;	/* Truncated Page Complete */
685d62e6d67SJohan Hedberg 	}
686d62e6d67SJohan Hedberg 
68740c59fcbSMarcel Holtmann 	/* Enable Authenticated Payload Timeout Expired event if supported */
688cd7ca0ecSMarcel Holtmann 	if (lmp_ping_capable(hdev) || hdev->le_features[0] & HCI_LE_PING)
68940c59fcbSMarcel Holtmann 		events[2] |= 0x80;
69040c59fcbSMarcel Holtmann 
691d62e6d67SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events);
692d62e6d67SJohan Hedberg }
693d62e6d67SJohan Hedberg 
69442c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt)
6952177bab5SJohan Hedberg {
69642c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
697d2c5d77fSJohan Hedberg 	u8 p;
69842c6b129SJohan Hedberg 
6990da71f1bSMarcel Holtmann 	hci_setup_event_mask(req);
7000da71f1bSMarcel Holtmann 
70148ce62c4SMarcel Holtmann 	if (hdev->commands[6] & 0x20) {
70248ce62c4SMarcel Holtmann 		struct hci_cp_read_stored_link_key cp;
70348ce62c4SMarcel Holtmann 
70448ce62c4SMarcel Holtmann 		bacpy(&cp.bdaddr, BDADDR_ANY);
70548ce62c4SMarcel Holtmann 		cp.read_all = 0x01;
70648ce62c4SMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_STORED_LINK_KEY, sizeof(cp), &cp);
70748ce62c4SMarcel Holtmann 	}
70848ce62c4SMarcel Holtmann 
7092177bab5SJohan Hedberg 	if (hdev->commands[5] & 0x10)
71042c6b129SJohan Hedberg 		hci_setup_link_policy(req);
7112177bab5SJohan Hedberg 
712417287deSMarcel Holtmann 	if (hdev->commands[8] & 0x01)
713417287deSMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL);
714417287deSMarcel Holtmann 
715417287deSMarcel Holtmann 	/* Some older Broadcom based Bluetooth 1.2 controllers do not
716417287deSMarcel Holtmann 	 * support the Read Page Scan Type command. Check support for
717417287deSMarcel Holtmann 	 * this command in the bit mask of supported commands.
718417287deSMarcel Holtmann 	 */
719417287deSMarcel Holtmann 	if (hdev->commands[13] & 0x01)
720417287deSMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL);
721417287deSMarcel Holtmann 
7229193c6e8SAndre Guedes 	if (lmp_le_capable(hdev)) {
7239193c6e8SAndre Guedes 		u8 events[8];
7249193c6e8SAndre Guedes 
7259193c6e8SAndre Guedes 		memset(events, 0, sizeof(events));
7264d6c705bSMarcel Holtmann 		events[0] = 0x0f;
7274d6c705bSMarcel Holtmann 
7284d6c705bSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_ENCRYPTION)
7294d6c705bSMarcel Holtmann 			events[0] |= 0x10;	/* LE Long Term Key Request */
730662bc2e6SAndre Guedes 
731662bc2e6SAndre Guedes 		/* If controller supports the Connection Parameters Request
732662bc2e6SAndre Guedes 		 * Link Layer Procedure, enable the corresponding event.
733662bc2e6SAndre Guedes 		 */
734662bc2e6SAndre Guedes 		if (hdev->le_features[0] & HCI_LE_CONN_PARAM_REQ_PROC)
735662bc2e6SAndre Guedes 			events[0] |= 0x20;	/* LE Remote Connection
736662bc2e6SAndre Guedes 						 * Parameter Request
737662bc2e6SAndre Guedes 						 */
738662bc2e6SAndre Guedes 
739a9f6068eSMarcel Holtmann 		/* If the controller supports the Data Length Extension
740a9f6068eSMarcel Holtmann 		 * feature, enable the corresponding event.
741a9f6068eSMarcel Holtmann 		 */
742a9f6068eSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT)
743a9f6068eSMarcel Holtmann 			events[0] |= 0x40;	/* LE Data Length Change */
744a9f6068eSMarcel Holtmann 
7454b71bba4SMarcel Holtmann 		/* If the controller supports Extended Scanner Filter
7464b71bba4SMarcel Holtmann 		 * Policies, enable the correspondig event.
7474b71bba4SMarcel Holtmann 		 */
7484b71bba4SMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_EXT_SCAN_POLICY)
7494b71bba4SMarcel Holtmann 			events[1] |= 0x04;	/* LE Direct Advertising
7504b71bba4SMarcel Holtmann 						 * Report
7514b71bba4SMarcel Holtmann 						 */
7524b71bba4SMarcel Holtmann 
7535a34bd5fSMarcel Holtmann 		/* If the controller supports the LE Read Local P-256
7545a34bd5fSMarcel Holtmann 		 * Public Key command, enable the corresponding event.
7555a34bd5fSMarcel Holtmann 		 */
7565a34bd5fSMarcel Holtmann 		if (hdev->commands[34] & 0x02)
7575a34bd5fSMarcel Holtmann 			events[0] |= 0x80;	/* LE Read Local P-256
7585a34bd5fSMarcel Holtmann 						 * Public Key Complete
7595a34bd5fSMarcel Holtmann 						 */
7605a34bd5fSMarcel Holtmann 
7615a34bd5fSMarcel Holtmann 		/* If the controller supports the LE Generate DHKey
7625a34bd5fSMarcel Holtmann 		 * command, enable the corresponding event.
7635a34bd5fSMarcel Holtmann 		 */
7645a34bd5fSMarcel Holtmann 		if (hdev->commands[34] & 0x04)
7655a34bd5fSMarcel Holtmann 			events[1] |= 0x01;	/* LE Generate DHKey Complete */
7665a34bd5fSMarcel Holtmann 
7679193c6e8SAndre Guedes 		hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, sizeof(events),
7689193c6e8SAndre Guedes 			    events);
7699193c6e8SAndre Guedes 
77015a49ccaSMarcel Holtmann 		if (hdev->commands[25] & 0x40) {
77115a49ccaSMarcel Holtmann 			/* Read LE Advertising Channel TX Power */
77215a49ccaSMarcel Holtmann 			hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
77315a49ccaSMarcel Holtmann 		}
77415a49ccaSMarcel Holtmann 
775a9f6068eSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) {
776a9f6068eSMarcel Holtmann 			/* Read LE Maximum Data Length */
777a9f6068eSMarcel Holtmann 			hci_req_add(req, HCI_OP_LE_READ_MAX_DATA_LEN, 0, NULL);
778a9f6068eSMarcel Holtmann 
779a9f6068eSMarcel Holtmann 			/* Read LE Suggested Default Data Length */
780a9f6068eSMarcel Holtmann 			hci_req_add(req, HCI_OP_LE_READ_DEF_DATA_LEN, 0, NULL);
781a9f6068eSMarcel Holtmann 		}
782a9f6068eSMarcel Holtmann 
78342c6b129SJohan Hedberg 		hci_set_le_support(req);
7849193c6e8SAndre Guedes 	}
785d2c5d77fSJohan Hedberg 
786d2c5d77fSJohan Hedberg 	/* Read features beyond page 1 if available */
787d2c5d77fSJohan Hedberg 	for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
788d2c5d77fSJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
789d2c5d77fSJohan Hedberg 
790d2c5d77fSJohan Hedberg 		cp.page = p;
791d2c5d77fSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
792d2c5d77fSJohan Hedberg 			    sizeof(cp), &cp);
793d2c5d77fSJohan Hedberg 	}
7942177bab5SJohan Hedberg }
7952177bab5SJohan Hedberg 
7965d4e7e8dSJohan Hedberg static void hci_init4_req(struct hci_request *req, unsigned long opt)
7975d4e7e8dSJohan Hedberg {
7985d4e7e8dSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
7995d4e7e8dSJohan Hedberg 
80036f260ceSMarcel Holtmann 	/* Some Broadcom based Bluetooth controllers do not support the
80136f260ceSMarcel Holtmann 	 * Delete Stored Link Key command. They are clearly indicating its
80236f260ceSMarcel Holtmann 	 * absence in the bit mask of supported commands.
80336f260ceSMarcel Holtmann 	 *
80436f260ceSMarcel Holtmann 	 * Check the supported commands and only if the the command is marked
80536f260ceSMarcel Holtmann 	 * as supported send it. If not supported assume that the controller
80636f260ceSMarcel Holtmann 	 * does not have actual support for stored link keys which makes this
80736f260ceSMarcel Holtmann 	 * command redundant anyway.
80836f260ceSMarcel Holtmann 	 *
80936f260ceSMarcel Holtmann 	 * Some controllers indicate that they support handling deleting
81036f260ceSMarcel Holtmann 	 * stored link keys, but they don't. The quirk lets a driver
81136f260ceSMarcel Holtmann 	 * just disable this command.
81236f260ceSMarcel Holtmann 	 */
81336f260ceSMarcel Holtmann 	if (hdev->commands[6] & 0x80 &&
81436f260ceSMarcel Holtmann 	    !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) {
81536f260ceSMarcel Holtmann 		struct hci_cp_delete_stored_link_key cp;
81636f260ceSMarcel Holtmann 
81736f260ceSMarcel Holtmann 		bacpy(&cp.bdaddr, BDADDR_ANY);
81836f260ceSMarcel Holtmann 		cp.delete_all = 0x01;
81936f260ceSMarcel Holtmann 		hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY,
82036f260ceSMarcel Holtmann 			    sizeof(cp), &cp);
82136f260ceSMarcel Holtmann 	}
82236f260ceSMarcel Holtmann 
823d62e6d67SJohan Hedberg 	/* Set event mask page 2 if the HCI command for it is supported */
824d62e6d67SJohan Hedberg 	if (hdev->commands[22] & 0x04)
825d62e6d67SJohan Hedberg 		hci_set_event_mask_page_2(req);
826d62e6d67SJohan Hedberg 
827109e3191SMarcel Holtmann 	/* Read local codec list if the HCI command is supported */
828109e3191SMarcel Holtmann 	if (hdev->commands[29] & 0x20)
829109e3191SMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_LOCAL_CODECS, 0, NULL);
830109e3191SMarcel Holtmann 
831f4fe73edSMarcel Holtmann 	/* Get MWS transport configuration if the HCI command is supported */
832f4fe73edSMarcel Holtmann 	if (hdev->commands[30] & 0x08)
833f4fe73edSMarcel Holtmann 		hci_req_add(req, HCI_OP_GET_MWS_TRANSPORT_CONFIG, 0, NULL);
834f4fe73edSMarcel Holtmann 
8355d4e7e8dSJohan Hedberg 	/* Check for Synchronization Train support */
83653b834d2SMarcel Holtmann 	if (lmp_sync_train_capable(hdev))
8375d4e7e8dSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL);
838a6d0d690SMarcel Holtmann 
839a6d0d690SMarcel Holtmann 	/* Enable Secure Connections if supported and configured */
840d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED) &&
841574ea3c7SMarcel Holtmann 	    bredr_sc_enabled(hdev)) {
842a6d0d690SMarcel Holtmann 		u8 support = 0x01;
843574ea3c7SMarcel Holtmann 
844a6d0d690SMarcel Holtmann 		hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT,
845a6d0d690SMarcel Holtmann 			    sizeof(support), &support);
846a6d0d690SMarcel Holtmann 	}
8475d4e7e8dSJohan Hedberg }
8485d4e7e8dSJohan Hedberg 
8492177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev)
8502177bab5SJohan Hedberg {
8512177bab5SJohan Hedberg 	int err;
8522177bab5SJohan Hedberg 
8532177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT);
8542177bab5SJohan Hedberg 	if (err < 0)
8552177bab5SJohan Hedberg 		return err;
8562177bab5SJohan Hedberg 
8574b4148e9SMarcel Holtmann 	/* The Device Under Test (DUT) mode is special and available for
8584b4148e9SMarcel Holtmann 	 * all controller types. So just create it early on.
8594b4148e9SMarcel Holtmann 	 */
860d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP)) {
8614b4148e9SMarcel Holtmann 		debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev,
8624b4148e9SMarcel Holtmann 				    &dut_mode_fops);
8634b4148e9SMarcel Holtmann 	}
8644b4148e9SMarcel Holtmann 
8652177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT);
8662177bab5SJohan Hedberg 	if (err < 0)
8672177bab5SJohan Hedberg 		return err;
8682177bab5SJohan Hedberg 
8690af801b9SJohan Hedberg 	/* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode
8700af801b9SJohan Hedberg 	 * BR/EDR/LE type controllers. AMP controllers only need the
8710af801b9SJohan Hedberg 	 * first two stages of init.
8720af801b9SJohan Hedberg 	 */
8730af801b9SJohan Hedberg 	if (hdev->dev_type != HCI_BREDR)
8740af801b9SJohan Hedberg 		return 0;
8750af801b9SJohan Hedberg 
8765d4e7e8dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT);
8775d4e7e8dSJohan Hedberg 	if (err < 0)
8785d4e7e8dSJohan Hedberg 		return err;
8795d4e7e8dSJohan Hedberg 
880baf27f6eSMarcel Holtmann 	err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT);
881baf27f6eSMarcel Holtmann 	if (err < 0)
882baf27f6eSMarcel Holtmann 		return err;
883baf27f6eSMarcel Holtmann 
884ec6cef9cSMarcel Holtmann 	/* This function is only called when the controller is actually in
885ec6cef9cSMarcel Holtmann 	 * configured state. When the controller is marked as unconfigured,
886ec6cef9cSMarcel Holtmann 	 * this initialization procedure is not run.
887ec6cef9cSMarcel Holtmann 	 *
888ec6cef9cSMarcel Holtmann 	 * It means that it is possible that a controller runs through its
889ec6cef9cSMarcel Holtmann 	 * setup phase and then discovers missing settings. If that is the
890ec6cef9cSMarcel Holtmann 	 * case, then this function will not be called. It then will only
891ec6cef9cSMarcel Holtmann 	 * be called during the config phase.
892ec6cef9cSMarcel Holtmann 	 *
893ec6cef9cSMarcel Holtmann 	 * So only when in setup phase or config phase, create the debugfs
894ec6cef9cSMarcel Holtmann 	 * entries and register the SMP channels.
895baf27f6eSMarcel Holtmann 	 */
896d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
897d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONFIG))
898baf27f6eSMarcel Holtmann 		return 0;
899baf27f6eSMarcel Holtmann 
90060c5f5fbSMarcel Holtmann 	hci_debugfs_create_common(hdev);
90160c5f5fbSMarcel Holtmann 
90271c3b60eSMarcel Holtmann 	if (lmp_bredr_capable(hdev))
90360c5f5fbSMarcel Holtmann 		hci_debugfs_create_bredr(hdev);
9042bfa3531SMarcel Holtmann 
905162a3bacSMarcel Holtmann 	if (lmp_le_capable(hdev))
90660c5f5fbSMarcel Holtmann 		hci_debugfs_create_le(hdev);
907e7b8fc92SMarcel Holtmann 
908baf27f6eSMarcel Holtmann 	return 0;
9092177bab5SJohan Hedberg }
9102177bab5SJohan Hedberg 
9110ebca7d6SMarcel Holtmann static void hci_init0_req(struct hci_request *req, unsigned long opt)
9120ebca7d6SMarcel Holtmann {
9130ebca7d6SMarcel Holtmann 	struct hci_dev *hdev = req->hdev;
9140ebca7d6SMarcel Holtmann 
9150ebca7d6SMarcel Holtmann 	BT_DBG("%s %ld", hdev->name, opt);
9160ebca7d6SMarcel Holtmann 
9170ebca7d6SMarcel Holtmann 	/* Reset */
9180ebca7d6SMarcel Holtmann 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
9190ebca7d6SMarcel Holtmann 		hci_reset_req(req, 0);
9200ebca7d6SMarcel Holtmann 
9210ebca7d6SMarcel Holtmann 	/* Read Local Version */
9220ebca7d6SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
9230ebca7d6SMarcel Holtmann 
9240ebca7d6SMarcel Holtmann 	/* Read BD Address */
9250ebca7d6SMarcel Holtmann 	if (hdev->set_bdaddr)
9260ebca7d6SMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
9270ebca7d6SMarcel Holtmann }
9280ebca7d6SMarcel Holtmann 
9290ebca7d6SMarcel Holtmann static int __hci_unconf_init(struct hci_dev *hdev)
9300ebca7d6SMarcel Holtmann {
9310ebca7d6SMarcel Holtmann 	int err;
9320ebca7d6SMarcel Holtmann 
933cc78b44bSMarcel Holtmann 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
934cc78b44bSMarcel Holtmann 		return 0;
935cc78b44bSMarcel Holtmann 
9360ebca7d6SMarcel Holtmann 	err = __hci_req_sync(hdev, hci_init0_req, 0, HCI_INIT_TIMEOUT);
9370ebca7d6SMarcel Holtmann 	if (err < 0)
9380ebca7d6SMarcel Holtmann 		return err;
9390ebca7d6SMarcel Holtmann 
9400ebca7d6SMarcel Holtmann 	return 0;
9410ebca7d6SMarcel Holtmann }
9420ebca7d6SMarcel Holtmann 
94342c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt)
9441da177e4SLinus Torvalds {
9451da177e4SLinus Torvalds 	__u8 scan = opt;
9461da177e4SLinus Torvalds 
94742c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, scan);
9481da177e4SLinus Torvalds 
9491da177e4SLinus Torvalds 	/* Inquiry and Page scans */
95042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
9511da177e4SLinus Torvalds }
9521da177e4SLinus Torvalds 
95342c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt)
9541da177e4SLinus Torvalds {
9551da177e4SLinus Torvalds 	__u8 auth = opt;
9561da177e4SLinus Torvalds 
95742c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, auth);
9581da177e4SLinus Torvalds 
9591da177e4SLinus Torvalds 	/* Authentication */
96042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
9611da177e4SLinus Torvalds }
9621da177e4SLinus Torvalds 
96342c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt)
9641da177e4SLinus Torvalds {
9651da177e4SLinus Torvalds 	__u8 encrypt = opt;
9661da177e4SLinus Torvalds 
96742c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, encrypt);
9681da177e4SLinus Torvalds 
969e4e8e37cSMarcel Holtmann 	/* Encryption */
97042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
9711da177e4SLinus Torvalds }
9721da177e4SLinus Torvalds 
97342c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt)
974e4e8e37cSMarcel Holtmann {
975e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
976e4e8e37cSMarcel Holtmann 
97742c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, policy);
978e4e8e37cSMarcel Holtmann 
979e4e8e37cSMarcel Holtmann 	/* Default link policy */
98042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
981e4e8e37cSMarcel Holtmann }
982e4e8e37cSMarcel Holtmann 
9831da177e4SLinus Torvalds /* Get HCI device by index.
9841da177e4SLinus Torvalds  * Device is held on return. */
9851da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
9861da177e4SLinus Torvalds {
9878035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
9881da177e4SLinus Torvalds 
9891da177e4SLinus Torvalds 	BT_DBG("%d", index);
9901da177e4SLinus Torvalds 
9911da177e4SLinus Torvalds 	if (index < 0)
9921da177e4SLinus Torvalds 		return NULL;
9931da177e4SLinus Torvalds 
9941da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
9958035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
9961da177e4SLinus Torvalds 		if (d->id == index) {
9971da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
9981da177e4SLinus Torvalds 			break;
9991da177e4SLinus Torvalds 		}
10001da177e4SLinus Torvalds 	}
10011da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
10021da177e4SLinus Torvalds 	return hdev;
10031da177e4SLinus Torvalds }
10041da177e4SLinus Torvalds 
10051da177e4SLinus Torvalds /* ---- Inquiry support ---- */
1006ff9ef578SJohan Hedberg 
100730dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
100830dc78e1SJohan Hedberg {
100930dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
101030dc78e1SJohan Hedberg 
10116fbe195dSAndre Guedes 	switch (discov->state) {
1012343f935bSAndre Guedes 	case DISCOVERY_FINDING:
10136fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
101430dc78e1SJohan Hedberg 		return true;
101530dc78e1SJohan Hedberg 
10166fbe195dSAndre Guedes 	default:
101730dc78e1SJohan Hedberg 		return false;
101830dc78e1SJohan Hedberg 	}
10196fbe195dSAndre Guedes }
102030dc78e1SJohan Hedberg 
1021ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
1022ff9ef578SJohan Hedberg {
1023bb3e0a33SJohan Hedberg 	int old_state = hdev->discovery.state;
1024bb3e0a33SJohan Hedberg 
1025ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
1026ff9ef578SJohan Hedberg 
1027bb3e0a33SJohan Hedberg 	if (old_state == state)
1028ff9ef578SJohan Hedberg 		return;
1029ff9ef578SJohan Hedberg 
1030bb3e0a33SJohan Hedberg 	hdev->discovery.state = state;
1031bb3e0a33SJohan Hedberg 
1032ff9ef578SJohan Hedberg 	switch (state) {
1033ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
1034c54c3860SAndre Guedes 		hci_update_background_scan(hdev);
1035c54c3860SAndre Guedes 
1036bb3e0a33SJohan Hedberg 		if (old_state != DISCOVERY_STARTING)
1037ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
1038ff9ef578SJohan Hedberg 		break;
1039ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
1040ff9ef578SJohan Hedberg 		break;
1041343f935bSAndre Guedes 	case DISCOVERY_FINDING:
1042ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
1043ff9ef578SJohan Hedberg 		break;
104430dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
104530dc78e1SJohan Hedberg 		break;
1046ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
1047ff9ef578SJohan Hedberg 		break;
1048ff9ef578SJohan Hedberg 	}
1049ff9ef578SJohan Hedberg }
1050ff9ef578SJohan Hedberg 
10511f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev)
10521da177e4SLinus Torvalds {
105330883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1054b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
10551da177e4SLinus Torvalds 
1056561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
1057561aafbcSJohan Hedberg 		list_del(&p->all);
1058b57c1a56SJohan Hedberg 		kfree(p);
10591da177e4SLinus Torvalds 	}
1060561aafbcSJohan Hedberg 
1061561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
1062561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
10631da177e4SLinus Torvalds }
10641da177e4SLinus Torvalds 
1065a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
1066a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
10671da177e4SLinus Torvalds {
106830883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
10691da177e4SLinus Torvalds 	struct inquiry_entry *e;
10701da177e4SLinus Torvalds 
10716ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
10721da177e4SLinus Torvalds 
1073561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
10741da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
10751da177e4SLinus Torvalds 			return e;
10761da177e4SLinus Torvalds 	}
10771da177e4SLinus Torvalds 
1078b57c1a56SJohan Hedberg 	return NULL;
1079b57c1a56SJohan Hedberg }
1080b57c1a56SJohan Hedberg 
1081561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
1082561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
1083561aafbcSJohan Hedberg {
108430883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1085561aafbcSJohan Hedberg 	struct inquiry_entry *e;
1086561aafbcSJohan Hedberg 
10876ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
1088561aafbcSJohan Hedberg 
1089561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
1090561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
1091561aafbcSJohan Hedberg 			return e;
1092561aafbcSJohan Hedberg 	}
1093561aafbcSJohan Hedberg 
1094561aafbcSJohan Hedberg 	return NULL;
1095561aafbcSJohan Hedberg }
1096561aafbcSJohan Hedberg 
109730dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
109830dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
109930dc78e1SJohan Hedberg 						       int state)
110030dc78e1SJohan Hedberg {
110130dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
110230dc78e1SJohan Hedberg 	struct inquiry_entry *e;
110330dc78e1SJohan Hedberg 
11046ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
110530dc78e1SJohan Hedberg 
110630dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
110730dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
110830dc78e1SJohan Hedberg 			return e;
110930dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
111030dc78e1SJohan Hedberg 			return e;
111130dc78e1SJohan Hedberg 	}
111230dc78e1SJohan Hedberg 
111330dc78e1SJohan Hedberg 	return NULL;
111430dc78e1SJohan Hedberg }
111530dc78e1SJohan Hedberg 
1116a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
1117a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
1118a3d4e20aSJohan Hedberg {
1119a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1120a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
1121a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
1122a3d4e20aSJohan Hedberg 
1123a3d4e20aSJohan Hedberg 	list_del(&ie->list);
1124a3d4e20aSJohan Hedberg 
1125a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
1126a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
1127a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
1128a3d4e20aSJohan Hedberg 			break;
1129a3d4e20aSJohan Hedberg 		pos = &p->list;
1130a3d4e20aSJohan Hedberg 	}
1131a3d4e20aSJohan Hedberg 
1132a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
1133a3d4e20aSJohan Hedberg }
1134a3d4e20aSJohan Hedberg 
1135af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
1136af58925cSMarcel Holtmann 			     bool name_known)
11371da177e4SLinus Torvalds {
113830883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
113970f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
1140af58925cSMarcel Holtmann 	u32 flags = 0;
11411da177e4SLinus Torvalds 
11426ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
11431da177e4SLinus Torvalds 
11446928a924SJohan Hedberg 	hci_remove_remote_oob_data(hdev, &data->bdaddr, BDADDR_BREDR);
11452b2fec4dSSzymon Janc 
1146af58925cSMarcel Holtmann 	if (!data->ssp_mode)
1147af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
1148388fc8faSJohan Hedberg 
114970f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
1150a3d4e20aSJohan Hedberg 	if (ie) {
1151af58925cSMarcel Holtmann 		if (!ie->data.ssp_mode)
1152af58925cSMarcel Holtmann 			flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
1153388fc8faSJohan Hedberg 
1154a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
1155a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
1156a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
1157a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
1158a3d4e20aSJohan Hedberg 		}
1159a3d4e20aSJohan Hedberg 
1160561aafbcSJohan Hedberg 		goto update;
1161a3d4e20aSJohan Hedberg 	}
1162561aafbcSJohan Hedberg 
11631da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
116427f70f3eSJohan Hedberg 	ie = kzalloc(sizeof(*ie), GFP_KERNEL);
1165af58925cSMarcel Holtmann 	if (!ie) {
1166af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
1167af58925cSMarcel Holtmann 		goto done;
1168af58925cSMarcel Holtmann 	}
116970f23020SAndrei Emeltchenko 
1170561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
1171561aafbcSJohan Hedberg 
1172561aafbcSJohan Hedberg 	if (name_known) {
1173561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
1174561aafbcSJohan Hedberg 	} else {
1175561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
1176561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
1177561aafbcSJohan Hedberg 	}
1178561aafbcSJohan Hedberg 
1179561aafbcSJohan Hedberg update:
1180561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
1181561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
1182561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
1183561aafbcSJohan Hedberg 		list_del(&ie->list);
11841da177e4SLinus Torvalds 	}
11851da177e4SLinus Torvalds 
118670f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
118770f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
11881da177e4SLinus Torvalds 	cache->timestamp = jiffies;
11893175405bSJohan Hedberg 
11903175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
1191af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
11923175405bSJohan Hedberg 
1193af58925cSMarcel Holtmann done:
1194af58925cSMarcel Holtmann 	return flags;
11951da177e4SLinus Torvalds }
11961da177e4SLinus Torvalds 
11971da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
11981da177e4SLinus Torvalds {
119930883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
12001da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
12011da177e4SLinus Torvalds 	struct inquiry_entry *e;
12021da177e4SLinus Torvalds 	int copied = 0;
12031da177e4SLinus Torvalds 
1204561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
12051da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
1206b57c1a56SJohan Hedberg 
1207b57c1a56SJohan Hedberg 		if (copied >= num)
1208b57c1a56SJohan Hedberg 			break;
1209b57c1a56SJohan Hedberg 
12101da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
12111da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
12121da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
12131da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
12141da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
12151da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
1216b57c1a56SJohan Hedberg 
12171da177e4SLinus Torvalds 		info++;
1218b57c1a56SJohan Hedberg 		copied++;
12191da177e4SLinus Torvalds 	}
12201da177e4SLinus Torvalds 
12211da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
12221da177e4SLinus Torvalds 	return copied;
12231da177e4SLinus Torvalds }
12241da177e4SLinus Torvalds 
122542c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt)
12261da177e4SLinus Torvalds {
12271da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
122842c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
12291da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
12301da177e4SLinus Torvalds 
12311da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
12321da177e4SLinus Torvalds 
12331da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
12341da177e4SLinus Torvalds 		return;
12351da177e4SLinus Torvalds 
12361da177e4SLinus Torvalds 	/* Start Inquiry */
12371da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
12381da177e4SLinus Torvalds 	cp.length  = ir->length;
12391da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
124042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
12411da177e4SLinus Torvalds }
12421da177e4SLinus Torvalds 
12431da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
12441da177e4SLinus Torvalds {
12451da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
12461da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
12471da177e4SLinus Torvalds 	struct hci_dev *hdev;
12481da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
12491da177e4SLinus Torvalds 	long timeo;
12501da177e4SLinus Torvalds 	__u8 *buf;
12511da177e4SLinus Torvalds 
12521da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
12531da177e4SLinus Torvalds 		return -EFAULT;
12541da177e4SLinus Torvalds 
12555a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
12565a08ecceSAndrei Emeltchenko 	if (!hdev)
12571da177e4SLinus Torvalds 		return -ENODEV;
12581da177e4SLinus Torvalds 
1259d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
12600736cfa8SMarcel Holtmann 		err = -EBUSY;
12610736cfa8SMarcel Holtmann 		goto done;
12620736cfa8SMarcel Holtmann 	}
12630736cfa8SMarcel Holtmann 
1264d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
1265fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
1266fee746b0SMarcel Holtmann 		goto done;
1267fee746b0SMarcel Holtmann 	}
1268fee746b0SMarcel Holtmann 
12695b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
12705b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
12715b69bef5SMarcel Holtmann 		goto done;
12725b69bef5SMarcel Holtmann 	}
12735b69bef5SMarcel Holtmann 
1274d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
127556f87901SJohan Hedberg 		err = -EOPNOTSUPP;
127656f87901SJohan Hedberg 		goto done;
127756f87901SJohan Hedberg 	}
127856f87901SJohan Hedberg 
127909fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
12801da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
1281a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
12821f9b9a5dSAndre Guedes 		hci_inquiry_cache_flush(hdev);
12831da177e4SLinus Torvalds 		do_inquiry = 1;
12841da177e4SLinus Torvalds 	}
128509fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
12861da177e4SLinus Torvalds 
128704837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
128870f23020SAndrei Emeltchenko 
128970f23020SAndrei Emeltchenko 	if (do_inquiry) {
129001178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
129101178cd4SJohan Hedberg 				   timeo);
129270f23020SAndrei Emeltchenko 		if (err < 0)
12931da177e4SLinus Torvalds 			goto done;
12943e13fa1eSAndre Guedes 
12953e13fa1eSAndre Guedes 		/* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
12963e13fa1eSAndre Guedes 		 * cleared). If it is interrupted by a signal, return -EINTR.
12973e13fa1eSAndre Guedes 		 */
129874316201SNeilBrown 		if (wait_on_bit(&hdev->flags, HCI_INQUIRY,
12993e13fa1eSAndre Guedes 				TASK_INTERRUPTIBLE))
13003e13fa1eSAndre Guedes 			return -EINTR;
130170f23020SAndrei Emeltchenko 	}
13021da177e4SLinus Torvalds 
13038fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
13048fc9ced3SGustavo Padovan 	 * 255 entries
13058fc9ced3SGustavo Padovan 	 */
13061da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
13071da177e4SLinus Torvalds 
13081da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
13091da177e4SLinus Torvalds 	 * copy it to the user space.
13101da177e4SLinus Torvalds 	 */
131170f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
131270f23020SAndrei Emeltchenko 	if (!buf) {
13131da177e4SLinus Torvalds 		err = -ENOMEM;
13141da177e4SLinus Torvalds 		goto done;
13151da177e4SLinus Torvalds 	}
13161da177e4SLinus Torvalds 
131709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
13181da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
131909fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
13201da177e4SLinus Torvalds 
13211da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
13221da177e4SLinus Torvalds 
13231da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
13241da177e4SLinus Torvalds 		ptr += sizeof(ir);
13251da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
13261da177e4SLinus Torvalds 				 ir.num_rsp))
13271da177e4SLinus Torvalds 			err = -EFAULT;
13281da177e4SLinus Torvalds 	} else
13291da177e4SLinus Torvalds 		err = -EFAULT;
13301da177e4SLinus Torvalds 
13311da177e4SLinus Torvalds 	kfree(buf);
13321da177e4SLinus Torvalds 
13331da177e4SLinus Torvalds done:
13341da177e4SLinus Torvalds 	hci_dev_put(hdev);
13351da177e4SLinus Torvalds 	return err;
13361da177e4SLinus Torvalds }
13371da177e4SLinus Torvalds 
1338cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev)
13391da177e4SLinus Torvalds {
13401da177e4SLinus Torvalds 	int ret = 0;
13411da177e4SLinus Torvalds 
13421da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
13431da177e4SLinus Torvalds 
13441da177e4SLinus Torvalds 	hci_req_lock(hdev);
13451da177e4SLinus Torvalds 
1346d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
134794324962SJohan Hovold 		ret = -ENODEV;
134894324962SJohan Hovold 		goto done;
134994324962SJohan Hovold 	}
135094324962SJohan Hovold 
1351d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
1352d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONFIG)) {
1353a5c8f270SMarcel Holtmann 		/* Check for rfkill but allow the HCI setup stage to
1354a5c8f270SMarcel Holtmann 		 * proceed (which in itself doesn't cause any RF activity).
1355bf543036SJohan Hedberg 		 */
1356d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_RFKILLED)) {
1357611b30f7SMarcel Holtmann 			ret = -ERFKILL;
1358611b30f7SMarcel Holtmann 			goto done;
1359611b30f7SMarcel Holtmann 		}
1360611b30f7SMarcel Holtmann 
1361a5c8f270SMarcel Holtmann 		/* Check for valid public address or a configured static
1362a5c8f270SMarcel Holtmann 		 * random adddress, but let the HCI setup proceed to
1363a5c8f270SMarcel Holtmann 		 * be able to determine if there is a public address
1364a5c8f270SMarcel Holtmann 		 * or not.
1365a5c8f270SMarcel Holtmann 		 *
1366c6beca0eSMarcel Holtmann 		 * In case of user channel usage, it is not important
1367c6beca0eSMarcel Holtmann 		 * if a public address or static random address is
1368c6beca0eSMarcel Holtmann 		 * available.
1369c6beca0eSMarcel Holtmann 		 *
1370a5c8f270SMarcel Holtmann 		 * This check is only valid for BR/EDR controllers
1371a5c8f270SMarcel Holtmann 		 * since AMP controllers do not have an address.
1372a5c8f270SMarcel Holtmann 		 */
1373d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
1374c6beca0eSMarcel Holtmann 		    hdev->dev_type == HCI_BREDR &&
1375a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
1376a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->static_addr, BDADDR_ANY)) {
1377a5c8f270SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
1378a5c8f270SMarcel Holtmann 			goto done;
1379a5c8f270SMarcel Holtmann 		}
1380a5c8f270SMarcel Holtmann 	}
1381a5c8f270SMarcel Holtmann 
13821da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
13831da177e4SLinus Torvalds 		ret = -EALREADY;
13841da177e4SLinus Torvalds 		goto done;
13851da177e4SLinus Torvalds 	}
13861da177e4SLinus Torvalds 
13871da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
13881da177e4SLinus Torvalds 		ret = -EIO;
13891da177e4SLinus Torvalds 		goto done;
13901da177e4SLinus Torvalds 	}
13911da177e4SLinus Torvalds 
13921da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
13931da177e4SLinus Torvalds 	set_bit(HCI_INIT, &hdev->flags);
1394f41c70c4SMarcel Holtmann 
1395d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP)) {
1396af202f84SMarcel Holtmann 		if (hdev->setup)
1397f41c70c4SMarcel Holtmann 			ret = hdev->setup(hdev);
1398f41c70c4SMarcel Holtmann 
1399af202f84SMarcel Holtmann 		/* The transport driver can set these quirks before
1400af202f84SMarcel Holtmann 		 * creating the HCI device or in its setup callback.
1401af202f84SMarcel Holtmann 		 *
1402af202f84SMarcel Holtmann 		 * In case any of them is set, the controller has to
1403af202f84SMarcel Holtmann 		 * start up as unconfigured.
1404af202f84SMarcel Holtmann 		 */
1405eb1904f4SMarcel Holtmann 		if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) ||
1406eb1904f4SMarcel Holtmann 		    test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks))
1407a1536da2SMarcel Holtmann 			hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
1408f41c70c4SMarcel Holtmann 
14090ebca7d6SMarcel Holtmann 		/* For an unconfigured controller it is required to
14100ebca7d6SMarcel Holtmann 		 * read at least the version information provided by
14110ebca7d6SMarcel Holtmann 		 * the Read Local Version Information command.
14120ebca7d6SMarcel Holtmann 		 *
14130ebca7d6SMarcel Holtmann 		 * If the set_bdaddr driver callback is provided, then
14140ebca7d6SMarcel Holtmann 		 * also the original Bluetooth public device address
14150ebca7d6SMarcel Holtmann 		 * will be read using the Read BD Address command.
14160ebca7d6SMarcel Holtmann 		 */
1417d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
14180ebca7d6SMarcel Holtmann 			ret = __hci_unconf_init(hdev);
141989bc22d2SMarcel Holtmann 	}
142089bc22d2SMarcel Holtmann 
1421d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_CONFIG)) {
14229713c17bSMarcel Holtmann 		/* If public address change is configured, ensure that
14239713c17bSMarcel Holtmann 		 * the address gets programmed. If the driver does not
14249713c17bSMarcel Holtmann 		 * support changing the public address, fail the power
14259713c17bSMarcel Holtmann 		 * on procedure.
142624c457e2SMarcel Holtmann 		 */
14279713c17bSMarcel Holtmann 		if (bacmp(&hdev->public_addr, BDADDR_ANY) &&
14289713c17bSMarcel Holtmann 		    hdev->set_bdaddr)
142924c457e2SMarcel Holtmann 			ret = hdev->set_bdaddr(hdev, &hdev->public_addr);
143024c457e2SMarcel Holtmann 		else
143124c457e2SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
143224c457e2SMarcel Holtmann 	}
143324c457e2SMarcel Holtmann 
1434f41c70c4SMarcel Holtmann 	if (!ret) {
1435d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
1436d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
14372177bab5SJohan Hedberg 			ret = __hci_init(hdev);
14381da177e4SLinus Torvalds 	}
14391da177e4SLinus Torvalds 
1440f41c70c4SMarcel Holtmann 	clear_bit(HCI_INIT, &hdev->flags);
1441f41c70c4SMarcel Holtmann 
14421da177e4SLinus Torvalds 	if (!ret) {
14431da177e4SLinus Torvalds 		hci_dev_hold(hdev);
1444a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
14451da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
14461da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
1447d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
1448d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_CONFIG) &&
1449d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
1450d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
14511514b892SMarcel Holtmann 		    hdev->dev_type == HCI_BREDR) {
145209fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
1453744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
145409fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
145556e5cb86SJohan Hedberg 		}
14561da177e4SLinus Torvalds 	} else {
14571da177e4SLinus Torvalds 		/* Init failed, cleanup */
14583eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
1459c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
1460b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
14611da177e4SLinus Torvalds 
14621da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
14631da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
14641da177e4SLinus Torvalds 
14651da177e4SLinus Torvalds 		if (hdev->flush)
14661da177e4SLinus Torvalds 			hdev->flush(hdev);
14671da177e4SLinus Torvalds 
14681da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
14691da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
14701da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
14711da177e4SLinus Torvalds 		}
14721da177e4SLinus Torvalds 
14731da177e4SLinus Torvalds 		hdev->close(hdev);
1474fee746b0SMarcel Holtmann 		hdev->flags &= BIT(HCI_RAW);
14751da177e4SLinus Torvalds 	}
14761da177e4SLinus Torvalds 
14771da177e4SLinus Torvalds done:
14781da177e4SLinus Torvalds 	hci_req_unlock(hdev);
14791da177e4SLinus Torvalds 	return ret;
14801da177e4SLinus Torvalds }
14811da177e4SLinus Torvalds 
1482cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */
1483cbed0ca1SJohan Hedberg 
1484cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev)
1485cbed0ca1SJohan Hedberg {
1486cbed0ca1SJohan Hedberg 	struct hci_dev *hdev;
1487cbed0ca1SJohan Hedberg 	int err;
1488cbed0ca1SJohan Hedberg 
1489cbed0ca1SJohan Hedberg 	hdev = hci_dev_get(dev);
1490cbed0ca1SJohan Hedberg 	if (!hdev)
1491cbed0ca1SJohan Hedberg 		return -ENODEV;
1492cbed0ca1SJohan Hedberg 
14934a964404SMarcel Holtmann 	/* Devices that are marked as unconfigured can only be powered
1494fee746b0SMarcel Holtmann 	 * up as user channel. Trying to bring them up as normal devices
1495fee746b0SMarcel Holtmann 	 * will result into a failure. Only user channel operation is
1496fee746b0SMarcel Holtmann 	 * possible.
1497fee746b0SMarcel Holtmann 	 *
1498fee746b0SMarcel Holtmann 	 * When this function is called for a user channel, the flag
1499fee746b0SMarcel Holtmann 	 * HCI_USER_CHANNEL will be set first before attempting to
1500fee746b0SMarcel Holtmann 	 * open the device.
1501fee746b0SMarcel Holtmann 	 */
1502d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
1503d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
1504fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
1505fee746b0SMarcel Holtmann 		goto done;
1506fee746b0SMarcel Holtmann 	}
1507fee746b0SMarcel Holtmann 
1508e1d08f40SJohan Hedberg 	/* We need to ensure that no other power on/off work is pending
1509e1d08f40SJohan Hedberg 	 * before proceeding to call hci_dev_do_open. This is
1510e1d08f40SJohan Hedberg 	 * particularly important if the setup procedure has not yet
1511e1d08f40SJohan Hedberg 	 * completed.
1512e1d08f40SJohan Hedberg 	 */
1513a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF))
1514e1d08f40SJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
1515e1d08f40SJohan Hedberg 
1516a5c8f270SMarcel Holtmann 	/* After this call it is guaranteed that the setup procedure
1517a5c8f270SMarcel Holtmann 	 * has finished. This means that error conditions like RFKILL
1518a5c8f270SMarcel Holtmann 	 * or no valid public or static random address apply.
1519a5c8f270SMarcel Holtmann 	 */
1520e1d08f40SJohan Hedberg 	flush_workqueue(hdev->req_workqueue);
1521e1d08f40SJohan Hedberg 
152212aa4f0aSMarcel Holtmann 	/* For controllers not using the management interface and that
1523b6ae8457SJohan Hedberg 	 * are brought up using legacy ioctl, set the HCI_BONDABLE bit
152412aa4f0aSMarcel Holtmann 	 * so that pairing works for them. Once the management interface
152512aa4f0aSMarcel Holtmann 	 * is in use this bit will be cleared again and userspace has
152612aa4f0aSMarcel Holtmann 	 * to explicitly enable it.
152712aa4f0aSMarcel Holtmann 	 */
1528d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
1529d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_MGMT))
1530a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BONDABLE);
153112aa4f0aSMarcel Holtmann 
1532cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
1533cbed0ca1SJohan Hedberg 
1534fee746b0SMarcel Holtmann done:
1535cbed0ca1SJohan Hedberg 	hci_dev_put(hdev);
1536cbed0ca1SJohan Hedberg 	return err;
1537cbed0ca1SJohan Hedberg }
1538cbed0ca1SJohan Hedberg 
1539d7347f3cSJohan Hedberg /* This function requires the caller holds hdev->lock */
1540d7347f3cSJohan Hedberg static void hci_pend_le_actions_clear(struct hci_dev *hdev)
1541d7347f3cSJohan Hedberg {
1542d7347f3cSJohan Hedberg 	struct hci_conn_params *p;
1543d7347f3cSJohan Hedberg 
1544f161dd41SJohan Hedberg 	list_for_each_entry(p, &hdev->le_conn_params, list) {
1545f161dd41SJohan Hedberg 		if (p->conn) {
1546f161dd41SJohan Hedberg 			hci_conn_drop(p->conn);
1547f8aaf9b6SJohan Hedberg 			hci_conn_put(p->conn);
1548f161dd41SJohan Hedberg 			p->conn = NULL;
1549f161dd41SJohan Hedberg 		}
1550d7347f3cSJohan Hedberg 		list_del_init(&p->action);
1551f161dd41SJohan Hedberg 	}
1552d7347f3cSJohan Hedberg 
1553d7347f3cSJohan Hedberg 	BT_DBG("All LE pending actions cleared");
1554d7347f3cSJohan Hedberg }
1555d7347f3cSJohan Hedberg 
15561da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
15571da177e4SLinus Torvalds {
15581da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
15591da177e4SLinus Torvalds 
1560d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
1561a44fecbdSTedd Ho-Jeong An 		/* Execute vendor specific shutdown routine */
1562a44fecbdSTedd Ho-Jeong An 		if (hdev->shutdown)
1563a44fecbdSTedd Ho-Jeong An 			hdev->shutdown(hdev);
1564a44fecbdSTedd Ho-Jeong An 	}
1565a44fecbdSTedd Ho-Jeong An 
156678c04c0bSVinicius Costa Gomes 	cancel_delayed_work(&hdev->power_off);
156778c04c0bSVinicius Costa Gomes 
15681da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
15691da177e4SLinus Torvalds 	hci_req_lock(hdev);
15701da177e4SLinus Torvalds 
15711da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
157265cc2b49SMarcel Holtmann 		cancel_delayed_work_sync(&hdev->cmd_timer);
15731da177e4SLinus Torvalds 		hci_req_unlock(hdev);
15741da177e4SLinus Torvalds 		return 0;
15751da177e4SLinus Torvalds 	}
15761da177e4SLinus Torvalds 
15773eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
15783eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
1579b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
15801da177e4SLinus Torvalds 
158116ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
1582e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
158316ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
1584a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_DISCOVERABLE);
1585a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
158616ab91abSJohan Hedberg 	}
158716ab91abSJohan Hedberg 
1588a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_SERVICE_CACHE))
15897d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
15907d78525dSJohan Hedberg 
15917ba8b4beSAndre Guedes 	cancel_delayed_work_sync(&hdev->le_scan_disable);
15922d28cfe7SJakub Pawlowski 	cancel_delayed_work_sync(&hdev->le_scan_restart);
15934518bb0fSJohan Hedberg 
1594d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
1595d6bfd59cSJohan Hedberg 		cancel_delayed_work_sync(&hdev->rpa_expired);
15967ba8b4beSAndre Guedes 
159776727c02SJohan Hedberg 	/* Avoid potential lockdep warnings from the *_flush() calls by
159876727c02SJohan Hedberg 	 * ensuring the workqueue is empty up front.
159976727c02SJohan Hedberg 	 */
160076727c02SJohan Hedberg 	drain_workqueue(hdev->workqueue);
160176727c02SJohan Hedberg 
160209fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
16031aeb9c65SJohan Hedberg 
16048f502f84SJohan Hedberg 	hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
16058f502f84SJohan Hedberg 
1606a69d8927SMarcel Holtmann 	if (!hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) {
16071aeb9c65SJohan Hedberg 		if (hdev->dev_type == HCI_BREDR)
16081aeb9c65SJohan Hedberg 			mgmt_powered(hdev, 0);
16091aeb9c65SJohan Hedberg 	}
16101aeb9c65SJohan Hedberg 
16111f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
1612d7347f3cSJohan Hedberg 	hci_pend_le_actions_clear(hdev);
1613f161dd41SJohan Hedberg 	hci_conn_hash_flush(hdev);
161409fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
16151da177e4SLinus Torvalds 
161664dae967SMarcel Holtmann 	smp_unregister(hdev);
161764dae967SMarcel Holtmann 
16181da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
16191da177e4SLinus Torvalds 
16201da177e4SLinus Torvalds 	if (hdev->flush)
16211da177e4SLinus Torvalds 		hdev->flush(hdev);
16221da177e4SLinus Torvalds 
16231da177e4SLinus Torvalds 	/* Reset device */
16241da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
16251da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
1626d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_AUTO_OFF) &&
1627d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
1628a6c511c6SSzymon Janc 	    test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
16291da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
163001178cd4SJohan Hedberg 		__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
16311da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
16321da177e4SLinus Torvalds 	}
16331da177e4SLinus Torvalds 
1634c347b765SGustavo F. Padovan 	/* flush cmd  work */
1635c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
16361da177e4SLinus Torvalds 
16371da177e4SLinus Torvalds 	/* Drop queues */
16381da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
16391da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
16401da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
16411da177e4SLinus Torvalds 
16421da177e4SLinus Torvalds 	/* Drop last sent command */
16431da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
164465cc2b49SMarcel Holtmann 		cancel_delayed_work_sync(&hdev->cmd_timer);
16451da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
16461da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
16471da177e4SLinus Torvalds 	}
16481da177e4SLinus Torvalds 
16491da177e4SLinus Torvalds 	/* After this point our queues are empty
16501da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
16511da177e4SLinus Torvalds 	hdev->close(hdev);
16521da177e4SLinus Torvalds 
165335b973c9SJohan Hedberg 	/* Clear flags */
1654fee746b0SMarcel Holtmann 	hdev->flags &= BIT(HCI_RAW);
1655eacb44dfSMarcel Holtmann 	hci_dev_clear_volatile_flags(hdev);
165635b973c9SJohan Hedberg 
1657ced5c338SAndrei Emeltchenko 	/* Controller radio is available but is currently powered down */
1658536619e8SMarcel Holtmann 	hdev->amp_status = AMP_STATUS_POWERED_DOWN;
1659ced5c338SAndrei Emeltchenko 
1660e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
166109b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
16627a4cd51dSMarcel Holtmann 	bacpy(&hdev->random_addr, BDADDR_ANY);
1663e59fda8dSJohan Hedberg 
16641da177e4SLinus Torvalds 	hci_req_unlock(hdev);
16651da177e4SLinus Torvalds 
16661da177e4SLinus Torvalds 	hci_dev_put(hdev);
16671da177e4SLinus Torvalds 	return 0;
16681da177e4SLinus Torvalds }
16691da177e4SLinus Torvalds 
16701da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
16711da177e4SLinus Torvalds {
16721da177e4SLinus Torvalds 	struct hci_dev *hdev;
16731da177e4SLinus Torvalds 	int err;
16741da177e4SLinus Torvalds 
167570f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
167670f23020SAndrei Emeltchenko 	if (!hdev)
16771da177e4SLinus Torvalds 		return -ENODEV;
16788ee56540SMarcel Holtmann 
1679d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
16800736cfa8SMarcel Holtmann 		err = -EBUSY;
16810736cfa8SMarcel Holtmann 		goto done;
16820736cfa8SMarcel Holtmann 	}
16830736cfa8SMarcel Holtmann 
1684a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF))
16858ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
16868ee56540SMarcel Holtmann 
16871da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
16888ee56540SMarcel Holtmann 
16890736cfa8SMarcel Holtmann done:
16901da177e4SLinus Torvalds 	hci_dev_put(hdev);
16911da177e4SLinus Torvalds 	return err;
16921da177e4SLinus Torvalds }
16931da177e4SLinus Torvalds 
16945c912495SMarcel Holtmann static int hci_dev_do_reset(struct hci_dev *hdev)
16951da177e4SLinus Torvalds {
16965c912495SMarcel Holtmann 	int ret;
16971da177e4SLinus Torvalds 
16985c912495SMarcel Holtmann 	BT_DBG("%s %p", hdev->name, hdev);
16991da177e4SLinus Torvalds 
17001da177e4SLinus Torvalds 	hci_req_lock(hdev);
17011da177e4SLinus Torvalds 
17021da177e4SLinus Torvalds 	/* Drop queues */
17031da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
17041da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
17051da177e4SLinus Torvalds 
170676727c02SJohan Hedberg 	/* Avoid potential lockdep warnings from the *_flush() calls by
170776727c02SJohan Hedberg 	 * ensuring the workqueue is empty up front.
170876727c02SJohan Hedberg 	 */
170976727c02SJohan Hedberg 	drain_workqueue(hdev->workqueue);
171076727c02SJohan Hedberg 
171109fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
17121f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
17131da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
171409fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
17151da177e4SLinus Torvalds 
17161da177e4SLinus Torvalds 	if (hdev->flush)
17171da177e4SLinus Torvalds 		hdev->flush(hdev);
17181da177e4SLinus Torvalds 
17191da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
17206ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
17211da177e4SLinus Torvalds 
172201178cd4SJohan Hedberg 	ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
17231da177e4SLinus Torvalds 
17241da177e4SLinus Torvalds 	hci_req_unlock(hdev);
17251da177e4SLinus Torvalds 	return ret;
17261da177e4SLinus Torvalds }
17271da177e4SLinus Torvalds 
17285c912495SMarcel Holtmann int hci_dev_reset(__u16 dev)
17295c912495SMarcel Holtmann {
17305c912495SMarcel Holtmann 	struct hci_dev *hdev;
17315c912495SMarcel Holtmann 	int err;
17325c912495SMarcel Holtmann 
17335c912495SMarcel Holtmann 	hdev = hci_dev_get(dev);
17345c912495SMarcel Holtmann 	if (!hdev)
17355c912495SMarcel Holtmann 		return -ENODEV;
17365c912495SMarcel Holtmann 
17375c912495SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
17385c912495SMarcel Holtmann 		err = -ENETDOWN;
17395c912495SMarcel Holtmann 		goto done;
17405c912495SMarcel Holtmann 	}
17415c912495SMarcel Holtmann 
1742d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
17435c912495SMarcel Holtmann 		err = -EBUSY;
17445c912495SMarcel Holtmann 		goto done;
17455c912495SMarcel Holtmann 	}
17465c912495SMarcel Holtmann 
1747d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
17485c912495SMarcel Holtmann 		err = -EOPNOTSUPP;
17495c912495SMarcel Holtmann 		goto done;
17505c912495SMarcel Holtmann 	}
17515c912495SMarcel Holtmann 
17525c912495SMarcel Holtmann 	err = hci_dev_do_reset(hdev);
17535c912495SMarcel Holtmann 
17545c912495SMarcel Holtmann done:
17555c912495SMarcel Holtmann 	hci_dev_put(hdev);
17565c912495SMarcel Holtmann 	return err;
17575c912495SMarcel Holtmann }
17585c912495SMarcel Holtmann 
17591da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
17601da177e4SLinus Torvalds {
17611da177e4SLinus Torvalds 	struct hci_dev *hdev;
17621da177e4SLinus Torvalds 	int ret = 0;
17631da177e4SLinus Torvalds 
176470f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
176570f23020SAndrei Emeltchenko 	if (!hdev)
17661da177e4SLinus Torvalds 		return -ENODEV;
17671da177e4SLinus Torvalds 
1768d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
17690736cfa8SMarcel Holtmann 		ret = -EBUSY;
17700736cfa8SMarcel Holtmann 		goto done;
17710736cfa8SMarcel Holtmann 	}
17720736cfa8SMarcel Holtmann 
1773d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
1774fee746b0SMarcel Holtmann 		ret = -EOPNOTSUPP;
1775fee746b0SMarcel Holtmann 		goto done;
1776fee746b0SMarcel Holtmann 	}
1777fee746b0SMarcel Holtmann 
17781da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
17791da177e4SLinus Torvalds 
17800736cfa8SMarcel Holtmann done:
17811da177e4SLinus Torvalds 	hci_dev_put(hdev);
17821da177e4SLinus Torvalds 	return ret;
17831da177e4SLinus Torvalds }
17841da177e4SLinus Torvalds 
1785123abc08SJohan Hedberg static void hci_update_scan_state(struct hci_dev *hdev, u8 scan)
1786123abc08SJohan Hedberg {
1787bc6d2d04SJohan Hedberg 	bool conn_changed, discov_changed;
1788123abc08SJohan Hedberg 
1789123abc08SJohan Hedberg 	BT_DBG("%s scan 0x%02x", hdev->name, scan);
1790123abc08SJohan Hedberg 
1791123abc08SJohan Hedberg 	if ((scan & SCAN_PAGE))
1792238be788SMarcel Holtmann 		conn_changed = !hci_dev_test_and_set_flag(hdev,
1793238be788SMarcel Holtmann 							  HCI_CONNECTABLE);
1794123abc08SJohan Hedberg 	else
1795a69d8927SMarcel Holtmann 		conn_changed = hci_dev_test_and_clear_flag(hdev,
1796a69d8927SMarcel Holtmann 							   HCI_CONNECTABLE);
1797123abc08SJohan Hedberg 
1798bc6d2d04SJohan Hedberg 	if ((scan & SCAN_INQUIRY)) {
1799238be788SMarcel Holtmann 		discov_changed = !hci_dev_test_and_set_flag(hdev,
1800238be788SMarcel Holtmann 							    HCI_DISCOVERABLE);
1801bc6d2d04SJohan Hedberg 	} else {
1802a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
1803a69d8927SMarcel Holtmann 		discov_changed = hci_dev_test_and_clear_flag(hdev,
1804a69d8927SMarcel Holtmann 							     HCI_DISCOVERABLE);
1805bc6d2d04SJohan Hedberg 	}
1806bc6d2d04SJohan Hedberg 
1807d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
1808123abc08SJohan Hedberg 		return;
1809123abc08SJohan Hedberg 
1810bc6d2d04SJohan Hedberg 	if (conn_changed || discov_changed) {
1811bc6d2d04SJohan Hedberg 		/* In case this was disabled through mgmt */
1812a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
1813bc6d2d04SJohan Hedberg 
1814d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_LE_ENABLED))
1815bc6d2d04SJohan Hedberg 			mgmt_update_adv_data(hdev);
1816bc6d2d04SJohan Hedberg 
1817123abc08SJohan Hedberg 		mgmt_new_settings(hdev);
1818123abc08SJohan Hedberg 	}
1819bc6d2d04SJohan Hedberg }
1820123abc08SJohan Hedberg 
18211da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
18221da177e4SLinus Torvalds {
18231da177e4SLinus Torvalds 	struct hci_dev *hdev;
18241da177e4SLinus Torvalds 	struct hci_dev_req dr;
18251da177e4SLinus Torvalds 	int err = 0;
18261da177e4SLinus Torvalds 
18271da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
18281da177e4SLinus Torvalds 		return -EFAULT;
18291da177e4SLinus Torvalds 
183070f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
183170f23020SAndrei Emeltchenko 	if (!hdev)
18321da177e4SLinus Torvalds 		return -ENODEV;
18331da177e4SLinus Torvalds 
1834d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
18350736cfa8SMarcel Holtmann 		err = -EBUSY;
18360736cfa8SMarcel Holtmann 		goto done;
18370736cfa8SMarcel Holtmann 	}
18380736cfa8SMarcel Holtmann 
1839d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
1840fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
1841fee746b0SMarcel Holtmann 		goto done;
1842fee746b0SMarcel Holtmann 	}
1843fee746b0SMarcel Holtmann 
18445b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
18455b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
18465b69bef5SMarcel Holtmann 		goto done;
18475b69bef5SMarcel Holtmann 	}
18485b69bef5SMarcel Holtmann 
1849d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
185056f87901SJohan Hedberg 		err = -EOPNOTSUPP;
185156f87901SJohan Hedberg 		goto done;
185256f87901SJohan Hedberg 	}
185356f87901SJohan Hedberg 
18541da177e4SLinus Torvalds 	switch (cmd) {
18551da177e4SLinus Torvalds 	case HCISETAUTH:
185601178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
18575f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
18581da177e4SLinus Torvalds 		break;
18591da177e4SLinus Torvalds 
18601da177e4SLinus Torvalds 	case HCISETENCRYPT:
18611da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
18621da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
18631da177e4SLinus Torvalds 			break;
18641da177e4SLinus Torvalds 		}
18651da177e4SLinus Torvalds 
18661da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
18671da177e4SLinus Torvalds 			/* Auth must be enabled first */
186801178cd4SJohan Hedberg 			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
18695f246e89SAndrei Emeltchenko 					   HCI_INIT_TIMEOUT);
18701da177e4SLinus Torvalds 			if (err)
18711da177e4SLinus Torvalds 				break;
18721da177e4SLinus Torvalds 		}
18731da177e4SLinus Torvalds 
187401178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
18755f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
18761da177e4SLinus Torvalds 		break;
18771da177e4SLinus Torvalds 
18781da177e4SLinus Torvalds 	case HCISETSCAN:
187901178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
18805f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
188191a668b0SJohan Hedberg 
1882bc6d2d04SJohan Hedberg 		/* Ensure that the connectable and discoverable states
1883bc6d2d04SJohan Hedberg 		 * get correctly modified as this was a non-mgmt change.
188491a668b0SJohan Hedberg 		 */
1885123abc08SJohan Hedberg 		if (!err)
1886123abc08SJohan Hedberg 			hci_update_scan_state(hdev, dr.dev_opt);
18871da177e4SLinus Torvalds 		break;
18881da177e4SLinus Torvalds 
18891da177e4SLinus Torvalds 	case HCISETLINKPOL:
189001178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
18915f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
18921da177e4SLinus Torvalds 		break;
18931da177e4SLinus Torvalds 
18941da177e4SLinus Torvalds 	case HCISETLINKMODE:
1895e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
1896e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
1897e4e8e37cSMarcel Holtmann 		break;
1898e4e8e37cSMarcel Holtmann 
1899e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
1900e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
19011da177e4SLinus Torvalds 		break;
19021da177e4SLinus Torvalds 
19031da177e4SLinus Torvalds 	case HCISETACLMTU:
19041da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
19051da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
19061da177e4SLinus Torvalds 		break;
19071da177e4SLinus Torvalds 
19081da177e4SLinus Torvalds 	case HCISETSCOMTU:
19091da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
19101da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
19111da177e4SLinus Torvalds 		break;
19121da177e4SLinus Torvalds 
19131da177e4SLinus Torvalds 	default:
19141da177e4SLinus Torvalds 		err = -EINVAL;
19151da177e4SLinus Torvalds 		break;
19161da177e4SLinus Torvalds 	}
1917e4e8e37cSMarcel Holtmann 
19180736cfa8SMarcel Holtmann done:
19191da177e4SLinus Torvalds 	hci_dev_put(hdev);
19201da177e4SLinus Torvalds 	return err;
19211da177e4SLinus Torvalds }
19221da177e4SLinus Torvalds 
19231da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
19241da177e4SLinus Torvalds {
19258035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
19261da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
19271da177e4SLinus Torvalds 	struct hci_dev_req *dr;
19281da177e4SLinus Torvalds 	int n = 0, size, err;
19291da177e4SLinus Torvalds 	__u16 dev_num;
19301da177e4SLinus Torvalds 
19311da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
19321da177e4SLinus Torvalds 		return -EFAULT;
19331da177e4SLinus Torvalds 
19341da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
19351da177e4SLinus Torvalds 		return -EINVAL;
19361da177e4SLinus Torvalds 
19371da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
19381da177e4SLinus Torvalds 
193970f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
194070f23020SAndrei Emeltchenko 	if (!dl)
19411da177e4SLinus Torvalds 		return -ENOMEM;
19421da177e4SLinus Torvalds 
19431da177e4SLinus Torvalds 	dr = dl->dev_req;
19441da177e4SLinus Torvalds 
1945f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
19468035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
19472e84d8dbSMarcel Holtmann 		unsigned long flags = hdev->flags;
1948c542a06cSJohan Hedberg 
19492e84d8dbSMarcel Holtmann 		/* When the auto-off is configured it means the transport
19502e84d8dbSMarcel Holtmann 		 * is running, but in that case still indicate that the
19512e84d8dbSMarcel Holtmann 		 * device is actually down.
19522e84d8dbSMarcel Holtmann 		 */
1953d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_AUTO_OFF))
19542e84d8dbSMarcel Holtmann 			flags &= ~BIT(HCI_UP);
1955c542a06cSJohan Hedberg 
19561da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
19572e84d8dbSMarcel Holtmann 		(dr + n)->dev_opt = flags;
1958c542a06cSJohan Hedberg 
19591da177e4SLinus Torvalds 		if (++n >= dev_num)
19601da177e4SLinus Torvalds 			break;
19611da177e4SLinus Torvalds 	}
1962f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
19631da177e4SLinus Torvalds 
19641da177e4SLinus Torvalds 	dl->dev_num = n;
19651da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
19661da177e4SLinus Torvalds 
19671da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
19681da177e4SLinus Torvalds 	kfree(dl);
19691da177e4SLinus Torvalds 
19701da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
19711da177e4SLinus Torvalds }
19721da177e4SLinus Torvalds 
19731da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
19741da177e4SLinus Torvalds {
19751da177e4SLinus Torvalds 	struct hci_dev *hdev;
19761da177e4SLinus Torvalds 	struct hci_dev_info di;
19772e84d8dbSMarcel Holtmann 	unsigned long flags;
19781da177e4SLinus Torvalds 	int err = 0;
19791da177e4SLinus Torvalds 
19801da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
19811da177e4SLinus Torvalds 		return -EFAULT;
19821da177e4SLinus Torvalds 
198370f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
198470f23020SAndrei Emeltchenko 	if (!hdev)
19851da177e4SLinus Torvalds 		return -ENODEV;
19861da177e4SLinus Torvalds 
19872e84d8dbSMarcel Holtmann 	/* When the auto-off is configured it means the transport
19882e84d8dbSMarcel Holtmann 	 * is running, but in that case still indicate that the
19892e84d8dbSMarcel Holtmann 	 * device is actually down.
19902e84d8dbSMarcel Holtmann 	 */
1991d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_AUTO_OFF))
19922e84d8dbSMarcel Holtmann 		flags = hdev->flags & ~BIT(HCI_UP);
19932e84d8dbSMarcel Holtmann 	else
19942e84d8dbSMarcel Holtmann 		flags = hdev->flags;
1995c542a06cSJohan Hedberg 
19961da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
19971da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
199860f2a3edSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4);
19992e84d8dbSMarcel Holtmann 	di.flags    = flags;
20001da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
2001572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
20021da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
20031da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
20041da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
20051da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
2006572c7f84SJohan Hedberg 	} else {
2007572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
2008572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
2009572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
2010572c7f84SJohan Hedberg 		di.sco_pkts = 0;
2011572c7f84SJohan Hedberg 	}
20121da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
20131da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
20141da177e4SLinus Torvalds 
20151da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
20161da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
20171da177e4SLinus Torvalds 
20181da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
20191da177e4SLinus Torvalds 		err = -EFAULT;
20201da177e4SLinus Torvalds 
20211da177e4SLinus Torvalds 	hci_dev_put(hdev);
20221da177e4SLinus Torvalds 
20231da177e4SLinus Torvalds 	return err;
20241da177e4SLinus Torvalds }
20251da177e4SLinus Torvalds 
20261da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
20271da177e4SLinus Torvalds 
2028611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
2029611b30f7SMarcel Holtmann {
2030611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
2031611b30f7SMarcel Holtmann 
2032611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
2033611b30f7SMarcel Holtmann 
2034d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
20350736cfa8SMarcel Holtmann 		return -EBUSY;
20360736cfa8SMarcel Holtmann 
20375e130367SJohan Hedberg 	if (blocked) {
2038a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RFKILLED);
2039d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
2040d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_CONFIG))
2041611b30f7SMarcel Holtmann 			hci_dev_do_close(hdev);
20425e130367SJohan Hedberg 	} else {
2043a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_RFKILLED);
20445e130367SJohan Hedberg 	}
2045611b30f7SMarcel Holtmann 
2046611b30f7SMarcel Holtmann 	return 0;
2047611b30f7SMarcel Holtmann }
2048611b30f7SMarcel Holtmann 
2049611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
2050611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
2051611b30f7SMarcel Holtmann };
2052611b30f7SMarcel Holtmann 
2053ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
2054ab81cbf9SJohan Hedberg {
2055ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
205696570ffcSJohan Hedberg 	int err;
2057ab81cbf9SJohan Hedberg 
2058ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
2059ab81cbf9SJohan Hedberg 
2060cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
206196570ffcSJohan Hedberg 	if (err < 0) {
20623ad67582SJaganath Kanakkassery 		hci_dev_lock(hdev);
206396570ffcSJohan Hedberg 		mgmt_set_powered_failed(hdev, err);
20643ad67582SJaganath Kanakkassery 		hci_dev_unlock(hdev);
2065ab81cbf9SJohan Hedberg 		return;
206696570ffcSJohan Hedberg 	}
2067ab81cbf9SJohan Hedberg 
2068a5c8f270SMarcel Holtmann 	/* During the HCI setup phase, a few error conditions are
2069a5c8f270SMarcel Holtmann 	 * ignored and they need to be checked now. If they are still
2070a5c8f270SMarcel Holtmann 	 * valid, it is important to turn the device back off.
2071a5c8f270SMarcel Holtmann 	 */
2072d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_RFKILLED) ||
2073d7a5a11dSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_UNCONFIGURED) ||
2074a5c8f270SMarcel Holtmann 	    (hdev->dev_type == HCI_BREDR &&
2075a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
2076a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->static_addr, BDADDR_ANY))) {
2077a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_AUTO_OFF);
2078bf543036SJohan Hedberg 		hci_dev_do_close(hdev);
2079d7a5a11dSMarcel Holtmann 	} else if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) {
208019202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
208119202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
2082bf543036SJohan Hedberg 	}
2083ab81cbf9SJohan Hedberg 
2084a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_SETUP)) {
20854a964404SMarcel Holtmann 		/* For unconfigured devices, set the HCI_RAW flag
20864a964404SMarcel Holtmann 		 * so that userspace can easily identify them.
20874a964404SMarcel Holtmann 		 */
2088d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
20894a964404SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
20900602a8adSMarcel Holtmann 
20910602a8adSMarcel Holtmann 		/* For fully configured devices, this will send
20920602a8adSMarcel Holtmann 		 * the Index Added event. For unconfigured devices,
20930602a8adSMarcel Holtmann 		 * it will send Unconfigued Index Added event.
20940602a8adSMarcel Holtmann 		 *
20950602a8adSMarcel Holtmann 		 * Devices with HCI_QUIRK_RAW_DEVICE are ignored
20960602a8adSMarcel Holtmann 		 * and no event will be send.
20970602a8adSMarcel Holtmann 		 */
2098744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
2099a69d8927SMarcel Holtmann 	} else if (hci_dev_test_and_clear_flag(hdev, HCI_CONFIG)) {
21005ea234d3SMarcel Holtmann 		/* When the controller is now configured, then it
21015ea234d3SMarcel Holtmann 		 * is important to clear the HCI_RAW flag.
21025ea234d3SMarcel Holtmann 		 */
2103d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
21045ea234d3SMarcel Holtmann 			clear_bit(HCI_RAW, &hdev->flags);
21055ea234d3SMarcel Holtmann 
2106d603b76bSMarcel Holtmann 		/* Powering on the controller with HCI_CONFIG set only
2107d603b76bSMarcel Holtmann 		 * happens with the transition from unconfigured to
2108d603b76bSMarcel Holtmann 		 * configured. This will send the Index Added event.
2109d603b76bSMarcel Holtmann 		 */
2110d603b76bSMarcel Holtmann 		mgmt_index_added(hdev);
2111ab81cbf9SJohan Hedberg 	}
2112ab81cbf9SJohan Hedberg }
2113ab81cbf9SJohan Hedberg 
2114ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
2115ab81cbf9SJohan Hedberg {
21163243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
21173243553fSJohan Hedberg 					    power_off.work);
2118ab81cbf9SJohan Hedberg 
2119ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
2120ab81cbf9SJohan Hedberg 
21218ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
2122ab81cbf9SJohan Hedberg }
2123ab81cbf9SJohan Hedberg 
2124c7741d16SMarcel Holtmann static void hci_error_reset(struct work_struct *work)
2125c7741d16SMarcel Holtmann {
2126c7741d16SMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, error_reset);
2127c7741d16SMarcel Holtmann 
2128c7741d16SMarcel Holtmann 	BT_DBG("%s", hdev->name);
2129c7741d16SMarcel Holtmann 
2130c7741d16SMarcel Holtmann 	if (hdev->hw_error)
2131c7741d16SMarcel Holtmann 		hdev->hw_error(hdev, hdev->hw_error_code);
2132c7741d16SMarcel Holtmann 	else
2133c7741d16SMarcel Holtmann 		BT_ERR("%s hardware error 0x%2.2x", hdev->name,
2134c7741d16SMarcel Holtmann 		       hdev->hw_error_code);
2135c7741d16SMarcel Holtmann 
2136c7741d16SMarcel Holtmann 	if (hci_dev_do_close(hdev))
2137c7741d16SMarcel Holtmann 		return;
2138c7741d16SMarcel Holtmann 
2139c7741d16SMarcel Holtmann 	hci_dev_do_open(hdev);
2140c7741d16SMarcel Holtmann }
2141c7741d16SMarcel Holtmann 
214216ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
214316ab91abSJohan Hedberg {
214416ab91abSJohan Hedberg 	struct hci_dev *hdev;
214516ab91abSJohan Hedberg 
214616ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
214716ab91abSJohan Hedberg 
214816ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
214916ab91abSJohan Hedberg 
2150d1967ff8SMarcel Holtmann 	mgmt_discoverable_timeout(hdev);
215116ab91abSJohan Hedberg }
215216ab91abSJohan Hedberg 
215335f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev)
21542aeb9a1aSJohan Hedberg {
21554821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
21562aeb9a1aSJohan Hedberg 
21574821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
21584821002cSJohan Hedberg 		list_del(&uuid->list);
21592aeb9a1aSJohan Hedberg 		kfree(uuid);
21602aeb9a1aSJohan Hedberg 	}
21612aeb9a1aSJohan Hedberg }
21622aeb9a1aSJohan Hedberg 
216335f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev)
216455ed8ca1SJohan Hedberg {
216555ed8ca1SJohan Hedberg 	struct link_key *key;
216655ed8ca1SJohan Hedberg 
21670378b597SJohan Hedberg 	list_for_each_entry_rcu(key, &hdev->link_keys, list) {
21680378b597SJohan Hedberg 		list_del_rcu(&key->list);
21690378b597SJohan Hedberg 		kfree_rcu(key, rcu);
217055ed8ca1SJohan Hedberg 	}
217155ed8ca1SJohan Hedberg }
217255ed8ca1SJohan Hedberg 
217335f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev)
2174b899efafSVinicius Costa Gomes {
2175970d0f1bSJohan Hedberg 	struct smp_ltk *k;
2176b899efafSVinicius Costa Gomes 
2177970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
2178970d0f1bSJohan Hedberg 		list_del_rcu(&k->list);
2179970d0f1bSJohan Hedberg 		kfree_rcu(k, rcu);
2180b899efafSVinicius Costa Gomes 	}
2181b899efafSVinicius Costa Gomes }
2182b899efafSVinicius Costa Gomes 
2183970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev)
2184970c4e46SJohan Hedberg {
2185adae20cbSJohan Hedberg 	struct smp_irk *k;
2186970c4e46SJohan Hedberg 
2187adae20cbSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) {
2188adae20cbSJohan Hedberg 		list_del_rcu(&k->list);
2189adae20cbSJohan Hedberg 		kfree_rcu(k, rcu);
2190970c4e46SJohan Hedberg 	}
2191970c4e46SJohan Hedberg }
2192970c4e46SJohan Hedberg 
219355ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
219455ed8ca1SJohan Hedberg {
219555ed8ca1SJohan Hedberg 	struct link_key *k;
219655ed8ca1SJohan Hedberg 
21970378b597SJohan Hedberg 	rcu_read_lock();
21980378b597SJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->link_keys, list) {
21990378b597SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0) {
22000378b597SJohan Hedberg 			rcu_read_unlock();
220155ed8ca1SJohan Hedberg 			return k;
22020378b597SJohan Hedberg 		}
22030378b597SJohan Hedberg 	}
22040378b597SJohan Hedberg 	rcu_read_unlock();
220555ed8ca1SJohan Hedberg 
220655ed8ca1SJohan Hedberg 	return NULL;
220755ed8ca1SJohan Hedberg }
220855ed8ca1SJohan Hedberg 
2209745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
2210d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
2211d25e28abSJohan Hedberg {
2212d25e28abSJohan Hedberg 	/* Legacy key */
2213d25e28abSJohan Hedberg 	if (key_type < 0x03)
2214745c0ce3SVishal Agarwal 		return true;
2215d25e28abSJohan Hedberg 
2216d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
2217d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
2218745c0ce3SVishal Agarwal 		return false;
2219d25e28abSJohan Hedberg 
2220d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
2221d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
2222745c0ce3SVishal Agarwal 		return false;
2223d25e28abSJohan Hedberg 
2224d25e28abSJohan Hedberg 	/* Security mode 3 case */
2225d25e28abSJohan Hedberg 	if (!conn)
2226745c0ce3SVishal Agarwal 		return true;
2227d25e28abSJohan Hedberg 
2228e3befab9SJohan Hedberg 	/* BR/EDR key derived using SC from an LE link */
2229e3befab9SJohan Hedberg 	if (conn->type == LE_LINK)
2230e3befab9SJohan Hedberg 		return true;
2231e3befab9SJohan Hedberg 
2232d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
2233d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
2234745c0ce3SVishal Agarwal 		return true;
2235d25e28abSJohan Hedberg 
2236d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
2237d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
2238745c0ce3SVishal Agarwal 		return true;
2239d25e28abSJohan Hedberg 
2240d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
2241d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
2242745c0ce3SVishal Agarwal 		return true;
2243d25e28abSJohan Hedberg 
2244d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
2245d25e28abSJohan Hedberg 	 * persistently */
2246745c0ce3SVishal Agarwal 	return false;
2247d25e28abSJohan Hedberg }
2248d25e28abSJohan Hedberg 
2249e804d25dSJohan Hedberg static u8 ltk_role(u8 type)
225098a0b845SJohan Hedberg {
2251e804d25dSJohan Hedberg 	if (type == SMP_LTK)
2252e804d25dSJohan Hedberg 		return HCI_ROLE_MASTER;
225398a0b845SJohan Hedberg 
2254e804d25dSJohan Hedberg 	return HCI_ROLE_SLAVE;
225598a0b845SJohan Hedberg }
225698a0b845SJohan Hedberg 
2257f3a73d97SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
2258e804d25dSJohan Hedberg 			     u8 addr_type, u8 role)
225975d262c2SVinicius Costa Gomes {
2260c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
226175d262c2SVinicius Costa Gomes 
2262970d0f1bSJohan Hedberg 	rcu_read_lock();
2263970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
22645378bc56SJohan Hedberg 		if (addr_type != k->bdaddr_type || bacmp(bdaddr, &k->bdaddr))
22655378bc56SJohan Hedberg 			continue;
22665378bc56SJohan Hedberg 
2267923e2414SJohan Hedberg 		if (smp_ltk_is_sc(k) || ltk_role(k->type) == role) {
2268970d0f1bSJohan Hedberg 			rcu_read_unlock();
226975d262c2SVinicius Costa Gomes 			return k;
2270970d0f1bSJohan Hedberg 		}
2271970d0f1bSJohan Hedberg 	}
2272970d0f1bSJohan Hedberg 	rcu_read_unlock();
227375d262c2SVinicius Costa Gomes 
227475d262c2SVinicius Costa Gomes 	return NULL;
227575d262c2SVinicius Costa Gomes }
227675d262c2SVinicius Costa Gomes 
2277970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa)
2278970c4e46SJohan Hedberg {
2279970c4e46SJohan Hedberg 	struct smp_irk *irk;
2280970c4e46SJohan Hedberg 
2281adae20cbSJohan Hedberg 	rcu_read_lock();
2282adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
2283adae20cbSJohan Hedberg 		if (!bacmp(&irk->rpa, rpa)) {
2284adae20cbSJohan Hedberg 			rcu_read_unlock();
2285970c4e46SJohan Hedberg 			return irk;
2286970c4e46SJohan Hedberg 		}
2287adae20cbSJohan Hedberg 	}
2288970c4e46SJohan Hedberg 
2289adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
2290defce9e8SJohan Hedberg 		if (smp_irk_matches(hdev, irk->val, rpa)) {
2291970c4e46SJohan Hedberg 			bacpy(&irk->rpa, rpa);
2292adae20cbSJohan Hedberg 			rcu_read_unlock();
2293970c4e46SJohan Hedberg 			return irk;
2294970c4e46SJohan Hedberg 		}
2295970c4e46SJohan Hedberg 	}
2296adae20cbSJohan Hedberg 	rcu_read_unlock();
2297970c4e46SJohan Hedberg 
2298970c4e46SJohan Hedberg 	return NULL;
2299970c4e46SJohan Hedberg }
2300970c4e46SJohan Hedberg 
2301970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
2302970c4e46SJohan Hedberg 				     u8 addr_type)
2303970c4e46SJohan Hedberg {
2304970c4e46SJohan Hedberg 	struct smp_irk *irk;
2305970c4e46SJohan Hedberg 
23066cfc9988SJohan Hedberg 	/* Identity Address must be public or static random */
23076cfc9988SJohan Hedberg 	if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0)
23086cfc9988SJohan Hedberg 		return NULL;
23096cfc9988SJohan Hedberg 
2310adae20cbSJohan Hedberg 	rcu_read_lock();
2311adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
2312970c4e46SJohan Hedberg 		if (addr_type == irk->addr_type &&
2313adae20cbSJohan Hedberg 		    bacmp(bdaddr, &irk->bdaddr) == 0) {
2314adae20cbSJohan Hedberg 			rcu_read_unlock();
2315970c4e46SJohan Hedberg 			return irk;
2316970c4e46SJohan Hedberg 		}
2317adae20cbSJohan Hedberg 	}
2318adae20cbSJohan Hedberg 	rcu_read_unlock();
2319970c4e46SJohan Hedberg 
2320970c4e46SJohan Hedberg 	return NULL;
2321970c4e46SJohan Hedberg }
2322970c4e46SJohan Hedberg 
2323567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn,
23247652ff6aSJohan Hedberg 				  bdaddr_t *bdaddr, u8 *val, u8 type,
23257652ff6aSJohan Hedberg 				  u8 pin_len, bool *persistent)
232655ed8ca1SJohan Hedberg {
232755ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
2328745c0ce3SVishal Agarwal 	u8 old_key_type;
232955ed8ca1SJohan Hedberg 
233055ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
233155ed8ca1SJohan Hedberg 	if (old_key) {
233255ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
233355ed8ca1SJohan Hedberg 		key = old_key;
233455ed8ca1SJohan Hedberg 	} else {
233512adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
23360a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
233755ed8ca1SJohan Hedberg 		if (!key)
2338567fa2aaSJohan Hedberg 			return NULL;
23390378b597SJohan Hedberg 		list_add_rcu(&key->list, &hdev->link_keys);
234055ed8ca1SJohan Hedberg 	}
234155ed8ca1SJohan Hedberg 
23426ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
234355ed8ca1SJohan Hedberg 
2344d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
2345d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
2346d25e28abSJohan Hedberg 	 * previous key */
2347d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
2348a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
2349d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
2350655fe6ecSJohan Hedberg 		if (conn)
2351655fe6ecSJohan Hedberg 			conn->key_type = type;
2352655fe6ecSJohan Hedberg 	}
2353d25e28abSJohan Hedberg 
235455ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
23559b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
235655ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
235755ed8ca1SJohan Hedberg 
2358b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
235955ed8ca1SJohan Hedberg 		key->type = old_key_type;
23604748fed2SJohan Hedberg 	else
23614748fed2SJohan Hedberg 		key->type = type;
23624748fed2SJohan Hedberg 
23637652ff6aSJohan Hedberg 	if (persistent)
23647652ff6aSJohan Hedberg 		*persistent = hci_persistent_key(hdev, conn, type,
23657652ff6aSJohan Hedberg 						 old_key_type);
23664df378a1SJohan Hedberg 
2367567fa2aaSJohan Hedberg 	return key;
236855ed8ca1SJohan Hedberg }
236955ed8ca1SJohan Hedberg 
2370ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
237135d70271SJohan Hedberg 			    u8 addr_type, u8 type, u8 authenticated,
2372fe39c7b2SMarcel Holtmann 			    u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand)
237375d262c2SVinicius Costa Gomes {
2374c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
2375e804d25dSJohan Hedberg 	u8 role = ltk_role(type);
237675d262c2SVinicius Costa Gomes 
2377f3a73d97SJohan Hedberg 	old_key = hci_find_ltk(hdev, bdaddr, addr_type, role);
2378c9839a11SVinicius Costa Gomes 	if (old_key)
237975d262c2SVinicius Costa Gomes 		key = old_key;
2380c9839a11SVinicius Costa Gomes 	else {
23810a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
238275d262c2SVinicius Costa Gomes 		if (!key)
2383ca9142b8SJohan Hedberg 			return NULL;
2384970d0f1bSJohan Hedberg 		list_add_rcu(&key->list, &hdev->long_term_keys);
238575d262c2SVinicius Costa Gomes 	}
238675d262c2SVinicius Costa Gomes 
238775d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
2388c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
2389c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
2390c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
2391c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
2392fe39c7b2SMarcel Holtmann 	key->rand = rand;
2393c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
2394c9839a11SVinicius Costa Gomes 	key->type = type;
239575d262c2SVinicius Costa Gomes 
2396ca9142b8SJohan Hedberg 	return key;
239775d262c2SVinicius Costa Gomes }
239875d262c2SVinicius Costa Gomes 
2399ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr,
2400ca9142b8SJohan Hedberg 			    u8 addr_type, u8 val[16], bdaddr_t *rpa)
2401970c4e46SJohan Hedberg {
2402970c4e46SJohan Hedberg 	struct smp_irk *irk;
2403970c4e46SJohan Hedberg 
2404970c4e46SJohan Hedberg 	irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type);
2405970c4e46SJohan Hedberg 	if (!irk) {
2406970c4e46SJohan Hedberg 		irk = kzalloc(sizeof(*irk), GFP_KERNEL);
2407970c4e46SJohan Hedberg 		if (!irk)
2408ca9142b8SJohan Hedberg 			return NULL;
2409970c4e46SJohan Hedberg 
2410970c4e46SJohan Hedberg 		bacpy(&irk->bdaddr, bdaddr);
2411970c4e46SJohan Hedberg 		irk->addr_type = addr_type;
2412970c4e46SJohan Hedberg 
2413adae20cbSJohan Hedberg 		list_add_rcu(&irk->list, &hdev->identity_resolving_keys);
2414970c4e46SJohan Hedberg 	}
2415970c4e46SJohan Hedberg 
2416970c4e46SJohan Hedberg 	memcpy(irk->val, val, 16);
2417970c4e46SJohan Hedberg 	bacpy(&irk->rpa, rpa);
2418970c4e46SJohan Hedberg 
2419ca9142b8SJohan Hedberg 	return irk;
2420970c4e46SJohan Hedberg }
2421970c4e46SJohan Hedberg 
242255ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
242355ed8ca1SJohan Hedberg {
242455ed8ca1SJohan Hedberg 	struct link_key *key;
242555ed8ca1SJohan Hedberg 
242655ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
242755ed8ca1SJohan Hedberg 	if (!key)
242855ed8ca1SJohan Hedberg 		return -ENOENT;
242955ed8ca1SJohan Hedberg 
24306ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
243155ed8ca1SJohan Hedberg 
24320378b597SJohan Hedberg 	list_del_rcu(&key->list);
24330378b597SJohan Hedberg 	kfree_rcu(key, rcu);
243455ed8ca1SJohan Hedberg 
243555ed8ca1SJohan Hedberg 	return 0;
243655ed8ca1SJohan Hedberg }
243755ed8ca1SJohan Hedberg 
2438e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type)
2439b899efafSVinicius Costa Gomes {
2440970d0f1bSJohan Hedberg 	struct smp_ltk *k;
2441c51ffa0bSJohan Hedberg 	int removed = 0;
2442b899efafSVinicius Costa Gomes 
2443970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
2444e0b2b27eSJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type)
2445b899efafSVinicius Costa Gomes 			continue;
2446b899efafSVinicius Costa Gomes 
24476ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
2448b899efafSVinicius Costa Gomes 
2449970d0f1bSJohan Hedberg 		list_del_rcu(&k->list);
2450970d0f1bSJohan Hedberg 		kfree_rcu(k, rcu);
2451c51ffa0bSJohan Hedberg 		removed++;
2452b899efafSVinicius Costa Gomes 	}
2453b899efafSVinicius Costa Gomes 
2454c51ffa0bSJohan Hedberg 	return removed ? 0 : -ENOENT;
2455b899efafSVinicius Costa Gomes }
2456b899efafSVinicius Costa Gomes 
2457a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type)
2458a7ec7338SJohan Hedberg {
2459adae20cbSJohan Hedberg 	struct smp_irk *k;
2460a7ec7338SJohan Hedberg 
2461adae20cbSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) {
2462a7ec7338SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type)
2463a7ec7338SJohan Hedberg 			continue;
2464a7ec7338SJohan Hedberg 
2465a7ec7338SJohan Hedberg 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
2466a7ec7338SJohan Hedberg 
2467adae20cbSJohan Hedberg 		list_del_rcu(&k->list);
2468adae20cbSJohan Hedberg 		kfree_rcu(k, rcu);
2469a7ec7338SJohan Hedberg 	}
2470a7ec7338SJohan Hedberg }
2471a7ec7338SJohan Hedberg 
247255e76b38SJohan Hedberg bool hci_bdaddr_is_paired(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
247355e76b38SJohan Hedberg {
247455e76b38SJohan Hedberg 	struct smp_ltk *k;
24754ba9faf3SJohan Hedberg 	struct smp_irk *irk;
247655e76b38SJohan Hedberg 	u8 addr_type;
247755e76b38SJohan Hedberg 
247855e76b38SJohan Hedberg 	if (type == BDADDR_BREDR) {
247955e76b38SJohan Hedberg 		if (hci_find_link_key(hdev, bdaddr))
248055e76b38SJohan Hedberg 			return true;
248155e76b38SJohan Hedberg 		return false;
248255e76b38SJohan Hedberg 	}
248355e76b38SJohan Hedberg 
248455e76b38SJohan Hedberg 	/* Convert to HCI addr type which struct smp_ltk uses */
248555e76b38SJohan Hedberg 	if (type == BDADDR_LE_PUBLIC)
248655e76b38SJohan Hedberg 		addr_type = ADDR_LE_DEV_PUBLIC;
248755e76b38SJohan Hedberg 	else
248855e76b38SJohan Hedberg 		addr_type = ADDR_LE_DEV_RANDOM;
248955e76b38SJohan Hedberg 
24904ba9faf3SJohan Hedberg 	irk = hci_get_irk(hdev, bdaddr, addr_type);
24914ba9faf3SJohan Hedberg 	if (irk) {
24924ba9faf3SJohan Hedberg 		bdaddr = &irk->bdaddr;
24934ba9faf3SJohan Hedberg 		addr_type = irk->addr_type;
24944ba9faf3SJohan Hedberg 	}
24954ba9faf3SJohan Hedberg 
249655e76b38SJohan Hedberg 	rcu_read_lock();
249755e76b38SJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
249887c8b28dSJohan Hedberg 		if (k->bdaddr_type == addr_type && !bacmp(bdaddr, &k->bdaddr)) {
249987c8b28dSJohan Hedberg 			rcu_read_unlock();
250055e76b38SJohan Hedberg 			return true;
250155e76b38SJohan Hedberg 		}
250287c8b28dSJohan Hedberg 	}
250355e76b38SJohan Hedberg 	rcu_read_unlock();
250455e76b38SJohan Hedberg 
250555e76b38SJohan Hedberg 	return false;
250655e76b38SJohan Hedberg }
250755e76b38SJohan Hedberg 
25086bd32326SVille Tervo /* HCI command timer function */
250965cc2b49SMarcel Holtmann static void hci_cmd_timeout(struct work_struct *work)
25106bd32326SVille Tervo {
251165cc2b49SMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev,
251265cc2b49SMarcel Holtmann 					    cmd_timer.work);
25136bd32326SVille Tervo 
2514bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
2515bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
2516bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
2517bda4f23aSAndrei Emeltchenko 
2518bda4f23aSAndrei Emeltchenko 		BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode);
2519bda4f23aSAndrei Emeltchenko 	} else {
25206bd32326SVille Tervo 		BT_ERR("%s command tx timeout", hdev->name);
2521bda4f23aSAndrei Emeltchenko 	}
2522bda4f23aSAndrei Emeltchenko 
25236bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
2524c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
25256bd32326SVille Tervo }
25266bd32326SVille Tervo 
25272763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
25286928a924SJohan Hedberg 					  bdaddr_t *bdaddr, u8 bdaddr_type)
25292763eda6SSzymon Janc {
25302763eda6SSzymon Janc 	struct oob_data *data;
25312763eda6SSzymon Janc 
25326928a924SJohan Hedberg 	list_for_each_entry(data, &hdev->remote_oob_data, list) {
25336928a924SJohan Hedberg 		if (bacmp(bdaddr, &data->bdaddr) != 0)
25346928a924SJohan Hedberg 			continue;
25356928a924SJohan Hedberg 		if (data->bdaddr_type != bdaddr_type)
25366928a924SJohan Hedberg 			continue;
25372763eda6SSzymon Janc 		return data;
25386928a924SJohan Hedberg 	}
25392763eda6SSzymon Janc 
25402763eda6SSzymon Janc 	return NULL;
25412763eda6SSzymon Janc }
25422763eda6SSzymon Janc 
25436928a924SJohan Hedberg int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
25446928a924SJohan Hedberg 			       u8 bdaddr_type)
25452763eda6SSzymon Janc {
25462763eda6SSzymon Janc 	struct oob_data *data;
25472763eda6SSzymon Janc 
25486928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
25492763eda6SSzymon Janc 	if (!data)
25502763eda6SSzymon Janc 		return -ENOENT;
25512763eda6SSzymon Janc 
25526928a924SJohan Hedberg 	BT_DBG("%s removing %pMR (%u)", hdev->name, bdaddr, bdaddr_type);
25532763eda6SSzymon Janc 
25542763eda6SSzymon Janc 	list_del(&data->list);
25552763eda6SSzymon Janc 	kfree(data);
25562763eda6SSzymon Janc 
25572763eda6SSzymon Janc 	return 0;
25582763eda6SSzymon Janc }
25592763eda6SSzymon Janc 
256035f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev)
25612763eda6SSzymon Janc {
25622763eda6SSzymon Janc 	struct oob_data *data, *n;
25632763eda6SSzymon Janc 
25642763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
25652763eda6SSzymon Janc 		list_del(&data->list);
25662763eda6SSzymon Janc 		kfree(data);
25672763eda6SSzymon Janc 	}
25682763eda6SSzymon Janc }
25692763eda6SSzymon Janc 
25700798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
25716928a924SJohan Hedberg 			    u8 bdaddr_type, u8 *hash192, u8 *rand192,
257238da1703SJohan Hedberg 			    u8 *hash256, u8 *rand256)
25730798872eSMarcel Holtmann {
25740798872eSMarcel Holtmann 	struct oob_data *data;
25750798872eSMarcel Holtmann 
25766928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
25770798872eSMarcel Holtmann 	if (!data) {
25780a14ab41SJohan Hedberg 		data = kmalloc(sizeof(*data), GFP_KERNEL);
25790798872eSMarcel Holtmann 		if (!data)
25800798872eSMarcel Holtmann 			return -ENOMEM;
25810798872eSMarcel Holtmann 
25820798872eSMarcel Holtmann 		bacpy(&data->bdaddr, bdaddr);
25836928a924SJohan Hedberg 		data->bdaddr_type = bdaddr_type;
25840798872eSMarcel Holtmann 		list_add(&data->list, &hdev->remote_oob_data);
25850798872eSMarcel Holtmann 	}
25860798872eSMarcel Holtmann 
258781328d5cSJohan Hedberg 	if (hash192 && rand192) {
25880798872eSMarcel Holtmann 		memcpy(data->hash192, hash192, sizeof(data->hash192));
258938da1703SJohan Hedberg 		memcpy(data->rand192, rand192, sizeof(data->rand192));
2590f7697b16SMarcel Holtmann 		if (hash256 && rand256)
2591f7697b16SMarcel Holtmann 			data->present = 0x03;
259281328d5cSJohan Hedberg 	} else {
259381328d5cSJohan Hedberg 		memset(data->hash192, 0, sizeof(data->hash192));
259481328d5cSJohan Hedberg 		memset(data->rand192, 0, sizeof(data->rand192));
2595f7697b16SMarcel Holtmann 		if (hash256 && rand256)
2596f7697b16SMarcel Holtmann 			data->present = 0x02;
2597f7697b16SMarcel Holtmann 		else
2598f7697b16SMarcel Holtmann 			data->present = 0x00;
259981328d5cSJohan Hedberg 	}
26000798872eSMarcel Holtmann 
260181328d5cSJohan Hedberg 	if (hash256 && rand256) {
26020798872eSMarcel Holtmann 		memcpy(data->hash256, hash256, sizeof(data->hash256));
260338da1703SJohan Hedberg 		memcpy(data->rand256, rand256, sizeof(data->rand256));
260481328d5cSJohan Hedberg 	} else {
260581328d5cSJohan Hedberg 		memset(data->hash256, 0, sizeof(data->hash256));
260681328d5cSJohan Hedberg 		memset(data->rand256, 0, sizeof(data->rand256));
2607f7697b16SMarcel Holtmann 		if (hash192 && rand192)
2608f7697b16SMarcel Holtmann 			data->present = 0x01;
260981328d5cSJohan Hedberg 	}
26100798872eSMarcel Holtmann 
26116ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
26122763eda6SSzymon Janc 
26132763eda6SSzymon Janc 	return 0;
26142763eda6SSzymon Janc }
26152763eda6SSzymon Janc 
2616dcc36c16SJohan Hedberg struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
2617b9ee0a78SMarcel Holtmann 					 bdaddr_t *bdaddr, u8 type)
2618b2a66aadSAntti Julku {
2619b2a66aadSAntti Julku 	struct bdaddr_list *b;
2620b2a66aadSAntti Julku 
2621dcc36c16SJohan Hedberg 	list_for_each_entry(b, bdaddr_list, list) {
2622b9ee0a78SMarcel Holtmann 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
2623b2a66aadSAntti Julku 			return b;
2624b9ee0a78SMarcel Holtmann 	}
2625b2a66aadSAntti Julku 
2626b2a66aadSAntti Julku 	return NULL;
2627b2a66aadSAntti Julku }
2628b2a66aadSAntti Julku 
2629dcc36c16SJohan Hedberg void hci_bdaddr_list_clear(struct list_head *bdaddr_list)
2630b2a66aadSAntti Julku {
2631b2a66aadSAntti Julku 	struct list_head *p, *n;
2632b2a66aadSAntti Julku 
2633dcc36c16SJohan Hedberg 	list_for_each_safe(p, n, bdaddr_list) {
2634b9ee0a78SMarcel Holtmann 		struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list);
2635b2a66aadSAntti Julku 
2636b2a66aadSAntti Julku 		list_del(p);
2637b2a66aadSAntti Julku 		kfree(b);
2638b2a66aadSAntti Julku 	}
2639b2a66aadSAntti Julku }
2640b2a66aadSAntti Julku 
2641dcc36c16SJohan Hedberg int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type)
2642b2a66aadSAntti Julku {
2643b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2644b2a66aadSAntti Julku 
2645b9ee0a78SMarcel Holtmann 	if (!bacmp(bdaddr, BDADDR_ANY))
2646b2a66aadSAntti Julku 		return -EBADF;
2647b2a66aadSAntti Julku 
2648dcc36c16SJohan Hedberg 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
26495e762444SAntti Julku 		return -EEXIST;
2650b2a66aadSAntti Julku 
265127f70f3eSJohan Hedberg 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
26525e762444SAntti Julku 	if (!entry)
26535e762444SAntti Julku 		return -ENOMEM;
2654b2a66aadSAntti Julku 
2655b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
2656b9ee0a78SMarcel Holtmann 	entry->bdaddr_type = type;
2657b2a66aadSAntti Julku 
2658dcc36c16SJohan Hedberg 	list_add(&entry->list, list);
2659b2a66aadSAntti Julku 
26602a8357f2SJohan Hedberg 	return 0;
2661b2a66aadSAntti Julku }
2662b2a66aadSAntti Julku 
2663dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type)
2664b2a66aadSAntti Julku {
2665b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2666b2a66aadSAntti Julku 
266735f7498aSJohan Hedberg 	if (!bacmp(bdaddr, BDADDR_ANY)) {
2668dcc36c16SJohan Hedberg 		hci_bdaddr_list_clear(list);
266935f7498aSJohan Hedberg 		return 0;
267035f7498aSJohan Hedberg 	}
2671b2a66aadSAntti Julku 
2672dcc36c16SJohan Hedberg 	entry = hci_bdaddr_list_lookup(list, bdaddr, type);
2673d2ab0ac1SMarcel Holtmann 	if (!entry)
2674d2ab0ac1SMarcel Holtmann 		return -ENOENT;
2675d2ab0ac1SMarcel Holtmann 
2676d2ab0ac1SMarcel Holtmann 	list_del(&entry->list);
2677d2ab0ac1SMarcel Holtmann 	kfree(entry);
2678d2ab0ac1SMarcel Holtmann 
2679d2ab0ac1SMarcel Holtmann 	return 0;
2680d2ab0ac1SMarcel Holtmann }
2681d2ab0ac1SMarcel Holtmann 
268215819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
268315819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
268415819a70SAndre Guedes 					       bdaddr_t *addr, u8 addr_type)
268515819a70SAndre Guedes {
268615819a70SAndre Guedes 	struct hci_conn_params *params;
268715819a70SAndre Guedes 
2688738f6185SJohan Hedberg 	/* The conn params list only contains identity addresses */
2689738f6185SJohan Hedberg 	if (!hci_is_identity_address(addr, addr_type))
2690738f6185SJohan Hedberg 		return NULL;
2691738f6185SJohan Hedberg 
269215819a70SAndre Guedes 	list_for_each_entry(params, &hdev->le_conn_params, list) {
269315819a70SAndre Guedes 		if (bacmp(&params->addr, addr) == 0 &&
269415819a70SAndre Guedes 		    params->addr_type == addr_type) {
269515819a70SAndre Guedes 			return params;
269615819a70SAndre Guedes 		}
269715819a70SAndre Guedes 	}
269815819a70SAndre Guedes 
269915819a70SAndre Guedes 	return NULL;
270015819a70SAndre Guedes }
270115819a70SAndre Guedes 
270215819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
2703501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list,
27044b10966fSMarcel Holtmann 						  bdaddr_t *addr, u8 addr_type)
270515819a70SAndre Guedes {
2706912b42efSJohan Hedberg 	struct hci_conn_params *param;
270715819a70SAndre Guedes 
2708738f6185SJohan Hedberg 	/* The list only contains identity addresses */
2709738f6185SJohan Hedberg 	if (!hci_is_identity_address(addr, addr_type))
2710738f6185SJohan Hedberg 		return NULL;
271115819a70SAndre Guedes 
2712501f8827SJohan Hedberg 	list_for_each_entry(param, list, action) {
2713912b42efSJohan Hedberg 		if (bacmp(&param->addr, addr) == 0 &&
2714912b42efSJohan Hedberg 		    param->addr_type == addr_type)
2715912b42efSJohan Hedberg 			return param;
27164b10966fSMarcel Holtmann 	}
27174b10966fSMarcel Holtmann 
27184b10966fSMarcel Holtmann 	return NULL;
271915819a70SAndre Guedes }
272015819a70SAndre Guedes 
272115819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
272251d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev,
272351d167c0SMarcel Holtmann 					    bdaddr_t *addr, u8 addr_type)
272415819a70SAndre Guedes {
272515819a70SAndre Guedes 	struct hci_conn_params *params;
272615819a70SAndre Guedes 
2727c46245b3SJohan Hedberg 	if (!hci_is_identity_address(addr, addr_type))
272851d167c0SMarcel Holtmann 		return NULL;
2729a9b0a04cSAndre Guedes 
273015819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
2731cef952ceSAndre Guedes 	if (params)
273251d167c0SMarcel Holtmann 		return params;
273315819a70SAndre Guedes 
273415819a70SAndre Guedes 	params = kzalloc(sizeof(*params), GFP_KERNEL);
273515819a70SAndre Guedes 	if (!params) {
273615819a70SAndre Guedes 		BT_ERR("Out of memory");
273751d167c0SMarcel Holtmann 		return NULL;
273815819a70SAndre Guedes 	}
273915819a70SAndre Guedes 
274015819a70SAndre Guedes 	bacpy(&params->addr, addr);
274115819a70SAndre Guedes 	params->addr_type = addr_type;
2742cef952ceSAndre Guedes 
2743cef952ceSAndre Guedes 	list_add(&params->list, &hdev->le_conn_params);
274493450c75SJohan Hedberg 	INIT_LIST_HEAD(&params->action);
2745cef952ceSAndre Guedes 
2746bf5b3c8bSMarcel Holtmann 	params->conn_min_interval = hdev->le_conn_min_interval;
2747bf5b3c8bSMarcel Holtmann 	params->conn_max_interval = hdev->le_conn_max_interval;
2748bf5b3c8bSMarcel Holtmann 	params->conn_latency = hdev->le_conn_latency;
2749bf5b3c8bSMarcel Holtmann 	params->supervision_timeout = hdev->le_supv_timeout;
2750bf5b3c8bSMarcel Holtmann 	params->auto_connect = HCI_AUTO_CONN_DISABLED;
2751bf5b3c8bSMarcel Holtmann 
2752bf5b3c8bSMarcel Holtmann 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
2753bf5b3c8bSMarcel Holtmann 
275451d167c0SMarcel Holtmann 	return params;
2755bf5b3c8bSMarcel Holtmann }
2756bf5b3c8bSMarcel Holtmann 
2757f6c63249SJohan Hedberg static void hci_conn_params_free(struct hci_conn_params *params)
2758f6c63249SJohan Hedberg {
2759f6c63249SJohan Hedberg 	if (params->conn) {
2760f6c63249SJohan Hedberg 		hci_conn_drop(params->conn);
2761f6c63249SJohan Hedberg 		hci_conn_put(params->conn);
2762f6c63249SJohan Hedberg 	}
2763f6c63249SJohan Hedberg 
2764f6c63249SJohan Hedberg 	list_del(&params->action);
2765f6c63249SJohan Hedberg 	list_del(&params->list);
2766f6c63249SJohan Hedberg 	kfree(params);
2767f6c63249SJohan Hedberg }
2768f6c63249SJohan Hedberg 
276915819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
277015819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
277115819a70SAndre Guedes {
277215819a70SAndre Guedes 	struct hci_conn_params *params;
277315819a70SAndre Guedes 
277415819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
277515819a70SAndre Guedes 	if (!params)
277615819a70SAndre Guedes 		return;
277715819a70SAndre Guedes 
2778f6c63249SJohan Hedberg 	hci_conn_params_free(params);
277915819a70SAndre Guedes 
278095305baaSJohan Hedberg 	hci_update_background_scan(hdev);
278195305baaSJohan Hedberg 
278215819a70SAndre Guedes 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
278315819a70SAndre Guedes }
278415819a70SAndre Guedes 
278515819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
278655af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev)
278715819a70SAndre Guedes {
278815819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
278915819a70SAndre Guedes 
279015819a70SAndre Guedes 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
279155af49a8SJohan Hedberg 		if (params->auto_connect != HCI_AUTO_CONN_DISABLED)
279255af49a8SJohan Hedberg 			continue;
279315819a70SAndre Guedes 		list_del(&params->list);
279415819a70SAndre Guedes 		kfree(params);
279515819a70SAndre Guedes 	}
279615819a70SAndre Guedes 
279755af49a8SJohan Hedberg 	BT_DBG("All LE disabled connection parameters were removed");
279855af49a8SJohan Hedberg }
279955af49a8SJohan Hedberg 
280055af49a8SJohan Hedberg /* This function requires the caller holds hdev->lock */
2801373110c5SJohan Hedberg void hci_conn_params_clear_all(struct hci_dev *hdev)
280215819a70SAndre Guedes {
280315819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
280415819a70SAndre Guedes 
2805f6c63249SJohan Hedberg 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list)
2806f6c63249SJohan Hedberg 		hci_conn_params_free(params);
280715819a70SAndre Guedes 
2808a2f41a8fSJohan Hedberg 	hci_update_background_scan(hdev);
28091089b67dSMarcel Holtmann 
281015819a70SAndre Guedes 	BT_DBG("All LE connection parameters were removed");
281115819a70SAndre Guedes }
281215819a70SAndre Guedes 
28131904a853SMarcel Holtmann static void inquiry_complete(struct hci_dev *hdev, u8 status, u16 opcode)
28147ba8b4beSAndre Guedes {
28154c87eaabSAndre Guedes 	if (status) {
28164c87eaabSAndre Guedes 		BT_ERR("Failed to start inquiry: status %d", status);
28177ba8b4beSAndre Guedes 
28184c87eaabSAndre Guedes 		hci_dev_lock(hdev);
28194c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
28204c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
28214c87eaabSAndre Guedes 		return;
28224c87eaabSAndre Guedes 	}
28237ba8b4beSAndre Guedes }
28247ba8b4beSAndre Guedes 
28251904a853SMarcel Holtmann static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status,
28261904a853SMarcel Holtmann 					  u16 opcode)
28277ba8b4beSAndre Guedes {
28284c87eaabSAndre Guedes 	/* General inquiry access code (GIAC) */
28294c87eaabSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
28304c87eaabSAndre Guedes 	struct hci_cp_inquiry cp;
28317ba8b4beSAndre Guedes 	int err;
28327ba8b4beSAndre Guedes 
28334c87eaabSAndre Guedes 	if (status) {
28344c87eaabSAndre Guedes 		BT_ERR("Failed to disable LE scanning: status %d", status);
28354c87eaabSAndre Guedes 		return;
28367ba8b4beSAndre Guedes 	}
28377ba8b4beSAndre Guedes 
28382d28cfe7SJakub Pawlowski 	hdev->discovery.scan_start = 0;
28392d28cfe7SJakub Pawlowski 
28404c87eaabSAndre Guedes 	switch (hdev->discovery.type) {
28414c87eaabSAndre Guedes 	case DISCOV_TYPE_LE:
28424c87eaabSAndre Guedes 		hci_dev_lock(hdev);
28434c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
28444c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
28454c87eaabSAndre Guedes 		break;
28467dbfac1dSAndre Guedes 
28474c87eaabSAndre Guedes 	case DISCOV_TYPE_INTERLEAVED:
28484c87eaabSAndre Guedes 		hci_dev_lock(hdev);
28494c87eaabSAndre Guedes 
285007d2334aSJakub Pawlowski 		if (test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY,
285107d2334aSJakub Pawlowski 			     &hdev->quirks)) {
285207d2334aSJakub Pawlowski 			/* If we were running LE only scan, change discovery
285307d2334aSJakub Pawlowski 			 * state. If we were running both LE and BR/EDR inquiry
285407d2334aSJakub Pawlowski 			 * simultaneously, and BR/EDR inquiry is already
285507d2334aSJakub Pawlowski 			 * finished, stop discovery, otherwise BR/EDR inquiry
285607d2334aSJakub Pawlowski 			 * will stop discovery when finished.
285707d2334aSJakub Pawlowski 			 */
285807d2334aSJakub Pawlowski 			if (!test_bit(HCI_INQUIRY, &hdev->flags))
285907d2334aSJakub Pawlowski 				hci_discovery_set_state(hdev,
286007d2334aSJakub Pawlowski 							DISCOVERY_STOPPED);
286107d2334aSJakub Pawlowski 		} else {
2862baf880a9SJohan Hedberg 			struct hci_request req;
2863baf880a9SJohan Hedberg 
28644c87eaabSAndre Guedes 			hci_inquiry_cache_flush(hdev);
28654c87eaabSAndre Guedes 
2866baf880a9SJohan Hedberg 			hci_req_init(&req, hdev);
2867baf880a9SJohan Hedberg 
2868baf880a9SJohan Hedberg 			memset(&cp, 0, sizeof(cp));
2869baf880a9SJohan Hedberg 			memcpy(&cp.lap, lap, sizeof(cp.lap));
2870baf880a9SJohan Hedberg 			cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN;
2871baf880a9SJohan Hedberg 			hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp);
2872baf880a9SJohan Hedberg 
28734c87eaabSAndre Guedes 			err = hci_req_run(&req, inquiry_complete);
28744c87eaabSAndre Guedes 			if (err) {
28754c87eaabSAndre Guedes 				BT_ERR("Inquiry request failed: err %d", err);
287607d2334aSJakub Pawlowski 				hci_discovery_set_state(hdev,
287707d2334aSJakub Pawlowski 							DISCOVERY_STOPPED);
287807d2334aSJakub Pawlowski 			}
28797dbfac1dSAndre Guedes 		}
28807dbfac1dSAndre Guedes 
28814c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
28824c87eaabSAndre Guedes 		break;
28834c87eaabSAndre Guedes 	}
28847dbfac1dSAndre Guedes }
28857dbfac1dSAndre Guedes 
28867ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work)
28877ba8b4beSAndre Guedes {
28887ba8b4beSAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev,
28897ba8b4beSAndre Guedes 					    le_scan_disable.work);
28904c87eaabSAndre Guedes 	struct hci_request req;
28914c87eaabSAndre Guedes 	int err;
28927ba8b4beSAndre Guedes 
28937ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
28947ba8b4beSAndre Guedes 
28952d28cfe7SJakub Pawlowski 	cancel_delayed_work_sync(&hdev->le_scan_restart);
28962d28cfe7SJakub Pawlowski 
28974c87eaabSAndre Guedes 	hci_req_init(&req, hdev);
28987ba8b4beSAndre Guedes 
2899b1efcc28SAndre Guedes 	hci_req_add_le_scan_disable(&req);
29007ba8b4beSAndre Guedes 
29014c87eaabSAndre Guedes 	err = hci_req_run(&req, le_scan_disable_work_complete);
29024c87eaabSAndre Guedes 	if (err)
29034c87eaabSAndre Guedes 		BT_ERR("Disable LE scanning request failed: err %d", err);
290428b75a89SAndre Guedes }
290528b75a89SAndre Guedes 
29062d28cfe7SJakub Pawlowski static void le_scan_restart_work_complete(struct hci_dev *hdev, u8 status,
29072d28cfe7SJakub Pawlowski 					  u16 opcode)
29082d28cfe7SJakub Pawlowski {
29092d28cfe7SJakub Pawlowski 	unsigned long timeout, duration, scan_start, now;
29102d28cfe7SJakub Pawlowski 
29112d28cfe7SJakub Pawlowski 	BT_DBG("%s", hdev->name);
29122d28cfe7SJakub Pawlowski 
29132d28cfe7SJakub Pawlowski 	if (status) {
29142d28cfe7SJakub Pawlowski 		BT_ERR("Failed to restart LE scan: status %d", status);
29152d28cfe7SJakub Pawlowski 		return;
29162d28cfe7SJakub Pawlowski 	}
29172d28cfe7SJakub Pawlowski 
29182d28cfe7SJakub Pawlowski 	if (!test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks) ||
29192d28cfe7SJakub Pawlowski 	    !hdev->discovery.scan_start)
29202d28cfe7SJakub Pawlowski 		return;
29212d28cfe7SJakub Pawlowski 
29222d28cfe7SJakub Pawlowski 	/* When the scan was started, hdev->le_scan_disable has been queued
29232d28cfe7SJakub Pawlowski 	 * after duration from scan_start. During scan restart this job
29242d28cfe7SJakub Pawlowski 	 * has been canceled, and we need to queue it again after proper
29252d28cfe7SJakub Pawlowski 	 * timeout, to make sure that scan does not run indefinitely.
29262d28cfe7SJakub Pawlowski 	 */
29272d28cfe7SJakub Pawlowski 	duration = hdev->discovery.scan_duration;
29282d28cfe7SJakub Pawlowski 	scan_start = hdev->discovery.scan_start;
29292d28cfe7SJakub Pawlowski 	now = jiffies;
29302d28cfe7SJakub Pawlowski 	if (now - scan_start <= duration) {
29312d28cfe7SJakub Pawlowski 		int elapsed;
29322d28cfe7SJakub Pawlowski 
29332d28cfe7SJakub Pawlowski 		if (now >= scan_start)
29342d28cfe7SJakub Pawlowski 			elapsed = now - scan_start;
29352d28cfe7SJakub Pawlowski 		else
29362d28cfe7SJakub Pawlowski 			elapsed = ULONG_MAX - scan_start + now;
29372d28cfe7SJakub Pawlowski 
29382d28cfe7SJakub Pawlowski 		timeout = duration - elapsed;
29392d28cfe7SJakub Pawlowski 	} else {
29402d28cfe7SJakub Pawlowski 		timeout = 0;
29412d28cfe7SJakub Pawlowski 	}
29422d28cfe7SJakub Pawlowski 	queue_delayed_work(hdev->workqueue,
29432d28cfe7SJakub Pawlowski 			   &hdev->le_scan_disable, timeout);
29442d28cfe7SJakub Pawlowski }
29452d28cfe7SJakub Pawlowski 
29462d28cfe7SJakub Pawlowski static void le_scan_restart_work(struct work_struct *work)
29472d28cfe7SJakub Pawlowski {
29482d28cfe7SJakub Pawlowski 	struct hci_dev *hdev = container_of(work, struct hci_dev,
29492d28cfe7SJakub Pawlowski 					    le_scan_restart.work);
29502d28cfe7SJakub Pawlowski 	struct hci_request req;
29512d28cfe7SJakub Pawlowski 	struct hci_cp_le_set_scan_enable cp;
29522d28cfe7SJakub Pawlowski 	int err;
29532d28cfe7SJakub Pawlowski 
29542d28cfe7SJakub Pawlowski 	BT_DBG("%s", hdev->name);
29552d28cfe7SJakub Pawlowski 
29562d28cfe7SJakub Pawlowski 	/* If controller is not scanning we are done. */
2957d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_LE_SCAN))
29582d28cfe7SJakub Pawlowski 		return;
29592d28cfe7SJakub Pawlowski 
29602d28cfe7SJakub Pawlowski 	hci_req_init(&req, hdev);
29612d28cfe7SJakub Pawlowski 
29622d28cfe7SJakub Pawlowski 	hci_req_add_le_scan_disable(&req);
29632d28cfe7SJakub Pawlowski 
29642d28cfe7SJakub Pawlowski 	memset(&cp, 0, sizeof(cp));
29652d28cfe7SJakub Pawlowski 	cp.enable = LE_SCAN_ENABLE;
29662d28cfe7SJakub Pawlowski 	cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
29672d28cfe7SJakub Pawlowski 	hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
29682d28cfe7SJakub Pawlowski 
29692d28cfe7SJakub Pawlowski 	err = hci_req_run(&req, le_scan_restart_work_complete);
29702d28cfe7SJakub Pawlowski 	if (err)
29712d28cfe7SJakub Pawlowski 		BT_ERR("Restart LE scan request failed: err %d", err);
29722d28cfe7SJakub Pawlowski }
29732d28cfe7SJakub Pawlowski 
2974a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller.
2975a1f4c318SJohan Hedberg  *
2976a1f4c318SJohan Hedberg  * If the controller has a public BD_ADDR, then by default use that one.
2977a1f4c318SJohan Hedberg  * If this is a LE only controller without a public address, default to
2978a1f4c318SJohan Hedberg  * the static random address.
2979a1f4c318SJohan Hedberg  *
2980a1f4c318SJohan Hedberg  * For debugging purposes it is possible to force controllers with a
2981a1f4c318SJohan Hedberg  * public address to use the static random address instead.
298250b5b952SMarcel Holtmann  *
298350b5b952SMarcel Holtmann  * In case BR/EDR has been disabled on a dual-mode controller and
298450b5b952SMarcel Holtmann  * userspace has configured a static address, then that address
298550b5b952SMarcel Holtmann  * becomes the identity address instead of the public BR/EDR address.
2986a1f4c318SJohan Hedberg  */
2987a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
2988a1f4c318SJohan Hedberg 			       u8 *bdaddr_type)
2989a1f4c318SJohan Hedberg {
2990b7cb93e5SMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) ||
299150b5b952SMarcel Holtmann 	    !bacmp(&hdev->bdaddr, BDADDR_ANY) ||
2992d7a5a11dSMarcel Holtmann 	    (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) &&
299350b5b952SMarcel Holtmann 	     bacmp(&hdev->static_addr, BDADDR_ANY))) {
2994a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->static_addr);
2995a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_RANDOM;
2996a1f4c318SJohan Hedberg 	} else {
2997a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->bdaddr);
2998a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_PUBLIC;
2999a1f4c318SJohan Hedberg 	}
3000a1f4c318SJohan Hedberg }
3001a1f4c318SJohan Hedberg 
30029be0dab7SDavid Herrmann /* Alloc HCI device */
30039be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void)
30049be0dab7SDavid Herrmann {
30059be0dab7SDavid Herrmann 	struct hci_dev *hdev;
30069be0dab7SDavid Herrmann 
300727f70f3eSJohan Hedberg 	hdev = kzalloc(sizeof(*hdev), GFP_KERNEL);
30089be0dab7SDavid Herrmann 	if (!hdev)
30099be0dab7SDavid Herrmann 		return NULL;
30109be0dab7SDavid Herrmann 
3011b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
3012b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
3013b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
3014b4cb9fb2SMarcel Holtmann 	hdev->num_iac = 0x01;		/* One IAC support is mandatory */
3015b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03;	/* No Input No Output */
301696c2103aSMarcel Holtmann 	hdev->manufacturer = 0xffff;	/* Default to internal use */
3017bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
3018bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
3019b1b813d4SDavid Herrmann 
3020b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
3021b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
3022b1b813d4SDavid Herrmann 
30233f959d46SMarcel Holtmann 	hdev->le_adv_channel_map = 0x07;
3024628531c9SGeorg Lukas 	hdev->le_adv_min_interval = 0x0800;
3025628531c9SGeorg Lukas 	hdev->le_adv_max_interval = 0x0800;
3026bef64738SMarcel Holtmann 	hdev->le_scan_interval = 0x0060;
3027bef64738SMarcel Holtmann 	hdev->le_scan_window = 0x0030;
30284e70c7e7SMarcel Holtmann 	hdev->le_conn_min_interval = 0x0028;
30294e70c7e7SMarcel Holtmann 	hdev->le_conn_max_interval = 0x0038;
303004fb7d90SMarcel Holtmann 	hdev->le_conn_latency = 0x0000;
303104fb7d90SMarcel Holtmann 	hdev->le_supv_timeout = 0x002a;
3032a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_len = 0x001b;
3033a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_time = 0x0148;
3034a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_len = 0x001b;
3035a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_time = 0x0148;
3036a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_len = 0x001b;
3037a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_time = 0x0148;
3038bef64738SMarcel Holtmann 
3039d6bfd59cSJohan Hedberg 	hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT;
3040b9a7a61eSLukasz Rymanowski 	hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT;
304131ad1691SAndrzej Kaczmarek 	hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE;
304231ad1691SAndrzej Kaczmarek 	hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE;
3043d6bfd59cSJohan Hedberg 
3044b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
3045b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
3046b1b813d4SDavid Herrmann 
3047b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
3048b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->blacklist);
30496659358eSJohan Hedberg 	INIT_LIST_HEAD(&hdev->whitelist);
3050b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
3051b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
3052b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
3053970c4e46SJohan Hedberg 	INIT_LIST_HEAD(&hdev->identity_resolving_keys);
3054b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
3055d2ab0ac1SMarcel Holtmann 	INIT_LIST_HEAD(&hdev->le_white_list);
305615819a70SAndre Guedes 	INIT_LIST_HEAD(&hdev->le_conn_params);
305777a77a30SAndre Guedes 	INIT_LIST_HEAD(&hdev->pend_le_conns);
305866f8455aSJohan Hedberg 	INIT_LIST_HEAD(&hdev->pend_le_reports);
30596b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
3060b1b813d4SDavid Herrmann 
3061b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
3062b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
3063b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
3064b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
3065c7741d16SMarcel Holtmann 	INIT_WORK(&hdev->error_reset, hci_error_reset);
3066b1b813d4SDavid Herrmann 
3067b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
3068b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
3069b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
30702d28cfe7SJakub Pawlowski 	INIT_DELAYED_WORK(&hdev->le_scan_restart, le_scan_restart_work);
3071b1b813d4SDavid Herrmann 
3072b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
3073b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
3074b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
3075b1b813d4SDavid Herrmann 
3076b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
3077b1b813d4SDavid Herrmann 
307865cc2b49SMarcel Holtmann 	INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout);
3079b1b813d4SDavid Herrmann 
3080b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
3081b1b813d4SDavid Herrmann 	discovery_init(hdev);
3082203fea01SArman Uguray 	adv_info_init(hdev);
30839be0dab7SDavid Herrmann 
30849be0dab7SDavid Herrmann 	return hdev;
30859be0dab7SDavid Herrmann }
30869be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev);
30879be0dab7SDavid Herrmann 
30889be0dab7SDavid Herrmann /* Free HCI device */
30899be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
30909be0dab7SDavid Herrmann {
30919be0dab7SDavid Herrmann 	/* will free via device release */
30929be0dab7SDavid Herrmann 	put_device(&hdev->dev);
30939be0dab7SDavid Herrmann }
30949be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
30959be0dab7SDavid Herrmann 
30961da177e4SLinus Torvalds /* Register HCI device */
30971da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
30981da177e4SLinus Torvalds {
3099b1b813d4SDavid Herrmann 	int id, error;
31001da177e4SLinus Torvalds 
310174292d5aSMarcel Holtmann 	if (!hdev->open || !hdev->close || !hdev->send)
31021da177e4SLinus Torvalds 		return -EINVAL;
31031da177e4SLinus Torvalds 
310408add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
310508add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
310608add513SMat Martineau 	 */
31073df92b31SSasha Levin 	switch (hdev->dev_type) {
31083df92b31SSasha Levin 	case HCI_BREDR:
31093df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
31101da177e4SLinus Torvalds 		break;
31113df92b31SSasha Levin 	case HCI_AMP:
31123df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
31133df92b31SSasha Levin 		break;
31143df92b31SSasha Levin 	default:
31153df92b31SSasha Levin 		return -EINVAL;
31161da177e4SLinus Torvalds 	}
31171da177e4SLinus Torvalds 
31183df92b31SSasha Levin 	if (id < 0)
31193df92b31SSasha Levin 		return id;
31203df92b31SSasha Levin 
31211da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
31221da177e4SLinus Torvalds 	hdev->id = id;
31232d8b3a11SAndrei Emeltchenko 
31242d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
31252d8b3a11SAndrei Emeltchenko 
3126d8537548SKees Cook 	hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
3127d8537548SKees Cook 					  WQ_MEM_RECLAIM, 1, hdev->name);
312833ca954dSDavid Herrmann 	if (!hdev->workqueue) {
312933ca954dSDavid Herrmann 		error = -ENOMEM;
313033ca954dSDavid Herrmann 		goto err;
313133ca954dSDavid Herrmann 	}
3132f48fd9c8SMarcel Holtmann 
3133d8537548SKees Cook 	hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
3134d8537548SKees Cook 					      WQ_MEM_RECLAIM, 1, hdev->name);
31356ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
31366ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
31376ead1bbcSJohan Hedberg 		error = -ENOMEM;
31386ead1bbcSJohan Hedberg 		goto err;
31396ead1bbcSJohan Hedberg 	}
31406ead1bbcSJohan Hedberg 
31410153e2ecSMarcel Holtmann 	if (!IS_ERR_OR_NULL(bt_debugfs))
31420153e2ecSMarcel Holtmann 		hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs);
31430153e2ecSMarcel Holtmann 
3144bdc3e0f1SMarcel Holtmann 	dev_set_name(&hdev->dev, "%s", hdev->name);
3145bdc3e0f1SMarcel Holtmann 
3146bdc3e0f1SMarcel Holtmann 	error = device_add(&hdev->dev);
314733ca954dSDavid Herrmann 	if (error < 0)
314854506918SJohan Hedberg 		goto err_wqueue;
31491da177e4SLinus Torvalds 
3150611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
3151a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
3152a8c5fb1aSGustavo Padovan 				    hdev);
3153611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
3154611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
3155611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
3156611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
3157611b30f7SMarcel Holtmann 		}
3158611b30f7SMarcel Holtmann 	}
3159611b30f7SMarcel Holtmann 
31605e130367SJohan Hedberg 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill))
3161a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RFKILLED);
31625e130367SJohan Hedberg 
3163a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_SETUP);
3164a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_AUTO_OFF);
3165ce2be9acSAndrei Emeltchenko 
316601cd3404SMarcel Holtmann 	if (hdev->dev_type == HCI_BREDR) {
316756f87901SJohan Hedberg 		/* Assume BR/EDR support until proven otherwise (such as
316856f87901SJohan Hedberg 		 * through reading supported features during init.
316956f87901SJohan Hedberg 		 */
3170a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
317156f87901SJohan Hedberg 	}
3172ce2be9acSAndrei Emeltchenko 
3173fcee3377SGustavo Padovan 	write_lock(&hci_dev_list_lock);
3174fcee3377SGustavo Padovan 	list_add(&hdev->list, &hci_dev_list);
3175fcee3377SGustavo Padovan 	write_unlock(&hci_dev_list_lock);
3176fcee3377SGustavo Padovan 
31774a964404SMarcel Holtmann 	/* Devices that are marked for raw-only usage are unconfigured
31784a964404SMarcel Holtmann 	 * and should not be included in normal operation.
3179fee746b0SMarcel Holtmann 	 */
3180fee746b0SMarcel Holtmann 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
3181a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
3182fee746b0SMarcel Holtmann 
31831da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
3184dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
31851da177e4SLinus Torvalds 
318619202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
3187fbe96d6fSMarcel Holtmann 
31881da177e4SLinus Torvalds 	return id;
3189f48fd9c8SMarcel Holtmann 
319033ca954dSDavid Herrmann err_wqueue:
319133ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
31926ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
319333ca954dSDavid Herrmann err:
31943df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
3195f48fd9c8SMarcel Holtmann 
319633ca954dSDavid Herrmann 	return error;
31971da177e4SLinus Torvalds }
31981da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
31991da177e4SLinus Torvalds 
32001da177e4SLinus Torvalds /* Unregister HCI device */
320159735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
32021da177e4SLinus Torvalds {
32033df92b31SSasha Levin 	int i, id;
3204ef222013SMarcel Holtmann 
3205c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
32061da177e4SLinus Torvalds 
3207a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_UNREGISTER);
320894324962SJohan Hovold 
32093df92b31SSasha Levin 	id = hdev->id;
32103df92b31SSasha Levin 
3211f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
32121da177e4SLinus Torvalds 	list_del(&hdev->list);
3213f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
32141da177e4SLinus Torvalds 
32151da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
32161da177e4SLinus Torvalds 
3217cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
3218ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
3219ef222013SMarcel Holtmann 
3220b9b5ef18SGustavo Padovan 	cancel_work_sync(&hdev->power_on);
3221b9b5ef18SGustavo Padovan 
3222ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
3223d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_SETUP) &&
3224d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONFIG)) {
322509fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
3226744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
322709fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
322856e5cb86SJohan Hedberg 	}
3229ab81cbf9SJohan Hedberg 
32302e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
32312e58ef3eSJohan Hedberg 	 * pending list */
32322e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
32332e58ef3eSJohan Hedberg 
32341da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
32351da177e4SLinus Torvalds 
3236611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
3237611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
3238611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
3239611b30f7SMarcel Holtmann 	}
3240611b30f7SMarcel Holtmann 
3241bdc3e0f1SMarcel Holtmann 	device_del(&hdev->dev);
3242147e2d59SDave Young 
32430153e2ecSMarcel Holtmann 	debugfs_remove_recursive(hdev->debugfs);
32440153e2ecSMarcel Holtmann 
3245f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
32466ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
3247f48fd9c8SMarcel Holtmann 
324809fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
3249dcc36c16SJohan Hedberg 	hci_bdaddr_list_clear(&hdev->blacklist);
32506659358eSJohan Hedberg 	hci_bdaddr_list_clear(&hdev->whitelist);
32512aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
325255ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
3253b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
3254970c4e46SJohan Hedberg 	hci_smp_irks_clear(hdev);
32552763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
3256dcc36c16SJohan Hedberg 	hci_bdaddr_list_clear(&hdev->le_white_list);
3257373110c5SJohan Hedberg 	hci_conn_params_clear_all(hdev);
325822078800SMarcel Holtmann 	hci_discovery_filter_clear(hdev);
325909fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
3260e2e0cacbSJohan Hedberg 
3261dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
32623df92b31SSasha Levin 
32633df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, id);
32641da177e4SLinus Torvalds }
32651da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
32661da177e4SLinus Torvalds 
32671da177e4SLinus Torvalds /* Suspend HCI device */
32681da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
32691da177e4SLinus Torvalds {
32701da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
32711da177e4SLinus Torvalds 	return 0;
32721da177e4SLinus Torvalds }
32731da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
32741da177e4SLinus Torvalds 
32751da177e4SLinus Torvalds /* Resume HCI device */
32761da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
32771da177e4SLinus Torvalds {
32781da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
32791da177e4SLinus Torvalds 	return 0;
32801da177e4SLinus Torvalds }
32811da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
32821da177e4SLinus Torvalds 
328375e0569fSMarcel Holtmann /* Reset HCI device */
328475e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev)
328575e0569fSMarcel Holtmann {
328675e0569fSMarcel Holtmann 	const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 };
328775e0569fSMarcel Holtmann 	struct sk_buff *skb;
328875e0569fSMarcel Holtmann 
328975e0569fSMarcel Holtmann 	skb = bt_skb_alloc(3, GFP_ATOMIC);
329075e0569fSMarcel Holtmann 	if (!skb)
329175e0569fSMarcel Holtmann 		return -ENOMEM;
329275e0569fSMarcel Holtmann 
329375e0569fSMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
329475e0569fSMarcel Holtmann 	memcpy(skb_put(skb, 3), hw_err, 3);
329575e0569fSMarcel Holtmann 
329675e0569fSMarcel Holtmann 	/* Send Hardware Error to upper stack */
329775e0569fSMarcel Holtmann 	return hci_recv_frame(hdev, skb);
329875e0569fSMarcel Holtmann }
329975e0569fSMarcel Holtmann EXPORT_SYMBOL(hci_reset_dev);
330075e0569fSMarcel Holtmann 
330176bca880SMarcel Holtmann /* Receive frame from HCI drivers */
3302e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
330376bca880SMarcel Holtmann {
330476bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
330576bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
330676bca880SMarcel Holtmann 		kfree_skb(skb);
330776bca880SMarcel Holtmann 		return -ENXIO;
330876bca880SMarcel Holtmann 	}
330976bca880SMarcel Holtmann 
3310d82603c6SJorrit Schippers 	/* Incoming skb */
331176bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
331276bca880SMarcel Holtmann 
331376bca880SMarcel Holtmann 	/* Time stamp */
331476bca880SMarcel Holtmann 	__net_timestamp(skb);
331576bca880SMarcel Holtmann 
331676bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
3317b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
3318c78ae283SMarcel Holtmann 
331976bca880SMarcel Holtmann 	return 0;
332076bca880SMarcel Holtmann }
332176bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
332276bca880SMarcel Holtmann 
332333e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
33241e429f38SGustavo F. Padovan 			  int count, __u8 index)
332533e882a5SSuraj Sumangala {
332633e882a5SSuraj Sumangala 	int len = 0;
332733e882a5SSuraj Sumangala 	int hlen = 0;
332833e882a5SSuraj Sumangala 	int remain = count;
332933e882a5SSuraj Sumangala 	struct sk_buff *skb;
333033e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
333133e882a5SSuraj Sumangala 
333233e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
333333e882a5SSuraj Sumangala 	    index >= NUM_REASSEMBLY)
333433e882a5SSuraj Sumangala 		return -EILSEQ;
333533e882a5SSuraj Sumangala 
333633e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
333733e882a5SSuraj Sumangala 
333833e882a5SSuraj Sumangala 	if (!skb) {
333933e882a5SSuraj Sumangala 		switch (type) {
334033e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
334133e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
334233e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
334333e882a5SSuraj Sumangala 			break;
334433e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
334533e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
334633e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
334733e882a5SSuraj Sumangala 			break;
334833e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
334933e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
335033e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
335133e882a5SSuraj Sumangala 			break;
335233e882a5SSuraj Sumangala 		}
335333e882a5SSuraj Sumangala 
33541e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
335533e882a5SSuraj Sumangala 		if (!skb)
335633e882a5SSuraj Sumangala 			return -ENOMEM;
335733e882a5SSuraj Sumangala 
335833e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
335933e882a5SSuraj Sumangala 		scb->expect = hlen;
336033e882a5SSuraj Sumangala 		scb->pkt_type = type;
336133e882a5SSuraj Sumangala 
336233e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
336333e882a5SSuraj Sumangala 	}
336433e882a5SSuraj Sumangala 
336533e882a5SSuraj Sumangala 	while (count) {
336633e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
336789bb46d0SDan Carpenter 		len = min_t(uint, scb->expect, count);
336833e882a5SSuraj Sumangala 
336933e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
337033e882a5SSuraj Sumangala 
337133e882a5SSuraj Sumangala 		count -= len;
337233e882a5SSuraj Sumangala 		data += len;
337333e882a5SSuraj Sumangala 		scb->expect -= len;
337433e882a5SSuraj Sumangala 		remain = count;
337533e882a5SSuraj Sumangala 
337633e882a5SSuraj Sumangala 		switch (type) {
337733e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
337833e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
337933e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
338033e882a5SSuraj Sumangala 				scb->expect = h->plen;
338133e882a5SSuraj Sumangala 
338233e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
338333e882a5SSuraj Sumangala 					kfree_skb(skb);
338433e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
338533e882a5SSuraj Sumangala 					return -ENOMEM;
338633e882a5SSuraj Sumangala 				}
338733e882a5SSuraj Sumangala 			}
338833e882a5SSuraj Sumangala 			break;
338933e882a5SSuraj Sumangala 
339033e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
339133e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
339233e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
339333e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
339433e882a5SSuraj Sumangala 
339533e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
339633e882a5SSuraj Sumangala 					kfree_skb(skb);
339733e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
339833e882a5SSuraj Sumangala 					return -ENOMEM;
339933e882a5SSuraj Sumangala 				}
340033e882a5SSuraj Sumangala 			}
340133e882a5SSuraj Sumangala 			break;
340233e882a5SSuraj Sumangala 
340333e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
340433e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
340533e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
340633e882a5SSuraj Sumangala 				scb->expect = h->dlen;
340733e882a5SSuraj Sumangala 
340833e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
340933e882a5SSuraj Sumangala 					kfree_skb(skb);
341033e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
341133e882a5SSuraj Sumangala 					return -ENOMEM;
341233e882a5SSuraj Sumangala 				}
341333e882a5SSuraj Sumangala 			}
341433e882a5SSuraj Sumangala 			break;
341533e882a5SSuraj Sumangala 		}
341633e882a5SSuraj Sumangala 
341733e882a5SSuraj Sumangala 		if (scb->expect == 0) {
341833e882a5SSuraj Sumangala 			/* Complete frame */
341933e882a5SSuraj Sumangala 
342033e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
3421e1a26170SMarcel Holtmann 			hci_recv_frame(hdev, skb);
342233e882a5SSuraj Sumangala 
342333e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
342433e882a5SSuraj Sumangala 			return remain;
342533e882a5SSuraj Sumangala 		}
342633e882a5SSuraj Sumangala 	}
342733e882a5SSuraj Sumangala 
342833e882a5SSuraj Sumangala 	return remain;
342933e882a5SSuraj Sumangala }
343033e882a5SSuraj Sumangala 
343199811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
343299811510SSuraj Sumangala 
343399811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
343499811510SSuraj Sumangala {
343599811510SSuraj Sumangala 	int type;
343699811510SSuraj Sumangala 	int rem = 0;
343799811510SSuraj Sumangala 
3438da5f6c37SGustavo F. Padovan 	while (count) {
343999811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
344099811510SSuraj Sumangala 
344199811510SSuraj Sumangala 		if (!skb) {
344299811510SSuraj Sumangala 			struct { char type; } *pkt;
344399811510SSuraj Sumangala 
344499811510SSuraj Sumangala 			/* Start of the frame */
344599811510SSuraj Sumangala 			pkt = data;
344699811510SSuraj Sumangala 			type = pkt->type;
344799811510SSuraj Sumangala 
344899811510SSuraj Sumangala 			data++;
344999811510SSuraj Sumangala 			count--;
345099811510SSuraj Sumangala 		} else
345199811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
345299811510SSuraj Sumangala 
34531e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
34541e429f38SGustavo F. Padovan 				     STREAM_REASSEMBLY);
345599811510SSuraj Sumangala 		if (rem < 0)
345699811510SSuraj Sumangala 			return rem;
345799811510SSuraj Sumangala 
345899811510SSuraj Sumangala 		data += (count - rem);
345999811510SSuraj Sumangala 		count = rem;
3460f81c6224SJoe Perches 	}
346199811510SSuraj Sumangala 
346299811510SSuraj Sumangala 	return rem;
346399811510SSuraj Sumangala }
346499811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
346599811510SSuraj Sumangala 
34661da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
34671da177e4SLinus Torvalds 
34681da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
34691da177e4SLinus Torvalds {
34701da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
34711da177e4SLinus Torvalds 
3472fba7ecf0SJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
347300629e0fSJohan Hedberg 	list_add_tail(&cb->list, &hci_cb_list);
3474fba7ecf0SJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
34751da177e4SLinus Torvalds 
34761da177e4SLinus Torvalds 	return 0;
34771da177e4SLinus Torvalds }
34781da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
34791da177e4SLinus Torvalds 
34801da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
34811da177e4SLinus Torvalds {
34821da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
34831da177e4SLinus Torvalds 
3484fba7ecf0SJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
34851da177e4SLinus Torvalds 	list_del(&cb->list);
3486fba7ecf0SJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
34871da177e4SLinus Torvalds 
34881da177e4SLinus Torvalds 	return 0;
34891da177e4SLinus Torvalds }
34901da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
34911da177e4SLinus Torvalds 
349251086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
34931da177e4SLinus Torvalds {
3494cdc52faaSMarcel Holtmann 	int err;
3495cdc52faaSMarcel Holtmann 
34960d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
34971da177e4SLinus Torvalds 
34981da177e4SLinus Torvalds 	/* Time stamp */
3499a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
35001da177e4SLinus Torvalds 
3501cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
3502cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
3503cd82e61cSMarcel Holtmann 
3504cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
3505cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
3506470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
35071da177e4SLinus Torvalds 	}
35081da177e4SLinus Torvalds 
35091da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
35101da177e4SLinus Torvalds 	skb_orphan(skb);
35111da177e4SLinus Torvalds 
3512cdc52faaSMarcel Holtmann 	err = hdev->send(hdev, skb);
3513cdc52faaSMarcel Holtmann 	if (err < 0) {
3514cdc52faaSMarcel Holtmann 		BT_ERR("%s sending frame failed (%d)", hdev->name, err);
3515cdc52faaSMarcel Holtmann 		kfree_skb(skb);
3516cdc52faaSMarcel Holtmann 	}
35171da177e4SLinus Torvalds }
35181da177e4SLinus Torvalds 
35191ca3a9d0SJohan Hedberg /* Send HCI command */
352007dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
352107dc93ddSJohan Hedberg 		 const void *param)
35221ca3a9d0SJohan Hedberg {
35231ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
35241ca3a9d0SJohan Hedberg 
35251ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
35261ca3a9d0SJohan Hedberg 
35271ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
35281ca3a9d0SJohan Hedberg 	if (!skb) {
35291ca3a9d0SJohan Hedberg 		BT_ERR("%s no memory for command", hdev->name);
35301ca3a9d0SJohan Hedberg 		return -ENOMEM;
35311ca3a9d0SJohan Hedberg 	}
35321ca3a9d0SJohan Hedberg 
353349c922bbSStephen Hemminger 	/* Stand-alone HCI commands must be flagged as
353411714b3dSJohan Hedberg 	 * single-command requests.
353511714b3dSJohan Hedberg 	 */
3536db6e3e8dSJohan Hedberg 	bt_cb(skb)->req.start = true;
353711714b3dSJohan Hedberg 
35381da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
3539c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
35401da177e4SLinus Torvalds 
35411da177e4SLinus Torvalds 	return 0;
35421da177e4SLinus Torvalds }
35431da177e4SLinus Torvalds 
35441da177e4SLinus Torvalds /* Get data from the previously sent command */
3545a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
35461da177e4SLinus Torvalds {
35471da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
35481da177e4SLinus Torvalds 
35491da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
35501da177e4SLinus Torvalds 		return NULL;
35511da177e4SLinus Torvalds 
35521da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
35531da177e4SLinus Torvalds 
3554a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
35551da177e4SLinus Torvalds 		return NULL;
35561da177e4SLinus Torvalds 
3557f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
35581da177e4SLinus Torvalds 
35591da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
35601da177e4SLinus Torvalds }
35611da177e4SLinus Torvalds 
35621da177e4SLinus Torvalds /* Send ACL data */
35631da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
35641da177e4SLinus Torvalds {
35651da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
35661da177e4SLinus Torvalds 	int len = skb->len;
35671da177e4SLinus Torvalds 
3568badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
3569badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
35709c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
3571aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
3572aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
35731da177e4SLinus Torvalds }
35741da177e4SLinus Torvalds 
3575ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
357673d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
35771da177e4SLinus Torvalds {
3578ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
35791da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
35801da177e4SLinus Torvalds 	struct sk_buff *list;
35811da177e4SLinus Torvalds 
3582087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
3583087bfd99SGustavo Padovan 	skb->data_len = 0;
3584087bfd99SGustavo Padovan 
3585087bfd99SGustavo Padovan 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
3586204a6e54SAndrei Emeltchenko 
3587204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
3588204a6e54SAndrei Emeltchenko 	case HCI_BREDR:
3589087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
3590204a6e54SAndrei Emeltchenko 		break;
3591204a6e54SAndrei Emeltchenko 	case HCI_AMP:
3592204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
3593204a6e54SAndrei Emeltchenko 		break;
3594204a6e54SAndrei Emeltchenko 	default:
3595204a6e54SAndrei Emeltchenko 		BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
3596204a6e54SAndrei Emeltchenko 		return;
3597204a6e54SAndrei Emeltchenko 	}
3598087bfd99SGustavo Padovan 
359970f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
360070f23020SAndrei Emeltchenko 	if (!list) {
36011da177e4SLinus Torvalds 		/* Non fragmented */
36021da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
36031da177e4SLinus Torvalds 
360473d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
36051da177e4SLinus Torvalds 	} else {
36061da177e4SLinus Torvalds 		/* Fragmented */
36071da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
36081da177e4SLinus Torvalds 
36091da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
36101da177e4SLinus Torvalds 
36119cfd5a23SJukka Rissanen 		/* Queue all fragments atomically. We need to use spin_lock_bh
36129cfd5a23SJukka Rissanen 		 * here because of 6LoWPAN links, as there this function is
36139cfd5a23SJukka Rissanen 		 * called from softirq and using normal spin lock could cause
36149cfd5a23SJukka Rissanen 		 * deadlocks.
36159cfd5a23SJukka Rissanen 		 */
36169cfd5a23SJukka Rissanen 		spin_lock_bh(&queue->lock);
36171da177e4SLinus Torvalds 
361873d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
3619e702112fSAndrei Emeltchenko 
3620e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
3621e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
36221da177e4SLinus Torvalds 		do {
36231da177e4SLinus Torvalds 			skb = list; list = list->next;
36241da177e4SLinus Torvalds 
36250d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
3626e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
36271da177e4SLinus Torvalds 
36281da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
36291da177e4SLinus Torvalds 
363073d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
36311da177e4SLinus Torvalds 		} while (list);
36321da177e4SLinus Torvalds 
36339cfd5a23SJukka Rissanen 		spin_unlock_bh(&queue->lock);
36341da177e4SLinus Torvalds 	}
363573d80debSLuiz Augusto von Dentz }
363673d80debSLuiz Augusto von Dentz 
363773d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
363873d80debSLuiz Augusto von Dentz {
3639ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
364073d80debSLuiz Augusto von Dentz 
3641f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
364273d80debSLuiz Augusto von Dentz 
3643ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
36441da177e4SLinus Torvalds 
36453eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
36461da177e4SLinus Torvalds }
36471da177e4SLinus Torvalds 
36481da177e4SLinus Torvalds /* Send SCO data */
36490d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
36501da177e4SLinus Torvalds {
36511da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
36521da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
36531da177e4SLinus Torvalds 
36541da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
36551da177e4SLinus Torvalds 
3656aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
36571da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
36581da177e4SLinus Torvalds 
3659badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
3660badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
36619c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
36621da177e4SLinus Torvalds 
36630d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
3664c78ae283SMarcel Holtmann 
36651da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
36663eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
36671da177e4SLinus Torvalds }
36681da177e4SLinus Torvalds 
36691da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
36701da177e4SLinus Torvalds 
36711da177e4SLinus Torvalds /* HCI Connection scheduler */
36726039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
3673a8c5fb1aSGustavo Padovan 				     int *quote)
36741da177e4SLinus Torvalds {
36751da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
36768035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
3677abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
36781da177e4SLinus Torvalds 
36791da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
36801da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
3681bf4c6325SGustavo F. Padovan 
3682bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3683bf4c6325SGustavo F. Padovan 
3684bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
3685769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
36861da177e4SLinus Torvalds 			continue;
3687769be974SMarcel Holtmann 
3688769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
3689769be974SMarcel Holtmann 			continue;
3690769be974SMarcel Holtmann 
36911da177e4SLinus Torvalds 		num++;
36921da177e4SLinus Torvalds 
36931da177e4SLinus Torvalds 		if (c->sent < min) {
36941da177e4SLinus Torvalds 			min  = c->sent;
36951da177e4SLinus Torvalds 			conn = c;
36961da177e4SLinus Torvalds 		}
369752087a79SLuiz Augusto von Dentz 
369852087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
369952087a79SLuiz Augusto von Dentz 			break;
37001da177e4SLinus Torvalds 	}
37011da177e4SLinus Torvalds 
3702bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3703bf4c6325SGustavo F. Padovan 
37041da177e4SLinus Torvalds 	if (conn) {
37056ed58ec5SVille Tervo 		int cnt, q;
37066ed58ec5SVille Tervo 
37076ed58ec5SVille Tervo 		switch (conn->type) {
37086ed58ec5SVille Tervo 		case ACL_LINK:
37096ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
37106ed58ec5SVille Tervo 			break;
37116ed58ec5SVille Tervo 		case SCO_LINK:
37126ed58ec5SVille Tervo 		case ESCO_LINK:
37136ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
37146ed58ec5SVille Tervo 			break;
37156ed58ec5SVille Tervo 		case LE_LINK:
37166ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
37176ed58ec5SVille Tervo 			break;
37186ed58ec5SVille Tervo 		default:
37196ed58ec5SVille Tervo 			cnt = 0;
37206ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
37216ed58ec5SVille Tervo 		}
37226ed58ec5SVille Tervo 
37236ed58ec5SVille Tervo 		q = cnt / num;
37241da177e4SLinus Torvalds 		*quote = q ? q : 1;
37251da177e4SLinus Torvalds 	} else
37261da177e4SLinus Torvalds 		*quote = 0;
37271da177e4SLinus Torvalds 
37281da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
37291da177e4SLinus Torvalds 	return conn;
37301da177e4SLinus Torvalds }
37311da177e4SLinus Torvalds 
37326039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
37331da177e4SLinus Torvalds {
37341da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
37351da177e4SLinus Torvalds 	struct hci_conn *c;
37361da177e4SLinus Torvalds 
3737bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
37381da177e4SLinus Torvalds 
3739bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3740bf4c6325SGustavo F. Padovan 
37411da177e4SLinus Torvalds 	/* Kill stalled connections */
3742bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
3743bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
37446ed93dc6SAndrei Emeltchenko 			BT_ERR("%s killing stalled connection %pMR",
37456ed93dc6SAndrei Emeltchenko 			       hdev->name, &c->dst);
3746bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
37471da177e4SLinus Torvalds 		}
37481da177e4SLinus Torvalds 	}
3749bf4c6325SGustavo F. Padovan 
3750bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
37511da177e4SLinus Torvalds }
37521da177e4SLinus Torvalds 
37536039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
375473d80debSLuiz Augusto von Dentz 				      int *quote)
375573d80debSLuiz Augusto von Dentz {
375673d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
375773d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
3758abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
375973d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
376073d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
376173d80debSLuiz Augusto von Dentz 
376273d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
376373d80debSLuiz Augusto von Dentz 
3764bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3765bf4c6325SGustavo F. Padovan 
3766bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
376773d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
376873d80debSLuiz Augusto von Dentz 
376973d80debSLuiz Augusto von Dentz 		if (conn->type != type)
377073d80debSLuiz Augusto von Dentz 			continue;
377173d80debSLuiz Augusto von Dentz 
377273d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
377373d80debSLuiz Augusto von Dentz 			continue;
377473d80debSLuiz Augusto von Dentz 
377573d80debSLuiz Augusto von Dentz 		conn_num++;
377673d80debSLuiz Augusto von Dentz 
37778192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
377873d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
377973d80debSLuiz Augusto von Dentz 
378073d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
378173d80debSLuiz Augusto von Dentz 				continue;
378273d80debSLuiz Augusto von Dentz 
378373d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
378473d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
378573d80debSLuiz Augusto von Dentz 				continue;
378673d80debSLuiz Augusto von Dentz 
378773d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
378873d80debSLuiz Augusto von Dentz 				num = 0;
378973d80debSLuiz Augusto von Dentz 				min = ~0;
379073d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
379173d80debSLuiz Augusto von Dentz 			}
379273d80debSLuiz Augusto von Dentz 
379373d80debSLuiz Augusto von Dentz 			num++;
379473d80debSLuiz Augusto von Dentz 
379573d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
379673d80debSLuiz Augusto von Dentz 				min  = conn->sent;
379773d80debSLuiz Augusto von Dentz 				chan = tmp;
379873d80debSLuiz Augusto von Dentz 			}
379973d80debSLuiz Augusto von Dentz 		}
380073d80debSLuiz Augusto von Dentz 
380173d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
380273d80debSLuiz Augusto von Dentz 			break;
380373d80debSLuiz Augusto von Dentz 	}
380473d80debSLuiz Augusto von Dentz 
3805bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3806bf4c6325SGustavo F. Padovan 
380773d80debSLuiz Augusto von Dentz 	if (!chan)
380873d80debSLuiz Augusto von Dentz 		return NULL;
380973d80debSLuiz Augusto von Dentz 
381073d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
381173d80debSLuiz Augusto von Dentz 	case ACL_LINK:
381273d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
381373d80debSLuiz Augusto von Dentz 		break;
3814bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
3815bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
3816bd1eb66bSAndrei Emeltchenko 		break;
381773d80debSLuiz Augusto von Dentz 	case SCO_LINK:
381873d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
381973d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
382073d80debSLuiz Augusto von Dentz 		break;
382173d80debSLuiz Augusto von Dentz 	case LE_LINK:
382273d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
382373d80debSLuiz Augusto von Dentz 		break;
382473d80debSLuiz Augusto von Dentz 	default:
382573d80debSLuiz Augusto von Dentz 		cnt = 0;
382673d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
382773d80debSLuiz Augusto von Dentz 	}
382873d80debSLuiz Augusto von Dentz 
382973d80debSLuiz Augusto von Dentz 	q = cnt / num;
383073d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
383173d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
383273d80debSLuiz Augusto von Dentz 	return chan;
383373d80debSLuiz Augusto von Dentz }
383473d80debSLuiz Augusto von Dentz 
383502b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
383602b20f0bSLuiz Augusto von Dentz {
383702b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
383802b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
383902b20f0bSLuiz Augusto von Dentz 	int num = 0;
384002b20f0bSLuiz Augusto von Dentz 
384102b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
384202b20f0bSLuiz Augusto von Dentz 
3843bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3844bf4c6325SGustavo F. Padovan 
3845bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
384602b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
384702b20f0bSLuiz Augusto von Dentz 
384802b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
384902b20f0bSLuiz Augusto von Dentz 			continue;
385002b20f0bSLuiz Augusto von Dentz 
385102b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
385202b20f0bSLuiz Augusto von Dentz 			continue;
385302b20f0bSLuiz Augusto von Dentz 
385402b20f0bSLuiz Augusto von Dentz 		num++;
385502b20f0bSLuiz Augusto von Dentz 
38568192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
385702b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
385802b20f0bSLuiz Augusto von Dentz 
385902b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
386002b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
386102b20f0bSLuiz Augusto von Dentz 				continue;
386202b20f0bSLuiz Augusto von Dentz 			}
386302b20f0bSLuiz Augusto von Dentz 
386402b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
386502b20f0bSLuiz Augusto von Dentz 				continue;
386602b20f0bSLuiz Augusto von Dentz 
386702b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
386802b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
386902b20f0bSLuiz Augusto von Dentz 				continue;
387002b20f0bSLuiz Augusto von Dentz 
387102b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
387202b20f0bSLuiz Augusto von Dentz 
387302b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
387402b20f0bSLuiz Augusto von Dentz 			       skb->priority);
387502b20f0bSLuiz Augusto von Dentz 		}
387602b20f0bSLuiz Augusto von Dentz 
387702b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
387802b20f0bSLuiz Augusto von Dentz 			break;
387902b20f0bSLuiz Augusto von Dentz 	}
3880bf4c6325SGustavo F. Padovan 
3881bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3882bf4c6325SGustavo F. Padovan 
388302b20f0bSLuiz Augusto von Dentz }
388402b20f0bSLuiz Augusto von Dentz 
3885b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
3886b71d385aSAndrei Emeltchenko {
3887b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
3888b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
3889b71d385aSAndrei Emeltchenko }
3890b71d385aSAndrei Emeltchenko 
38916039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
38921da177e4SLinus Torvalds {
3893d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
38941da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
38951da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
389663d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
38975f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
3898bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
38991da177e4SLinus Torvalds 	}
390063d2bc1bSAndrei Emeltchenko }
39011da177e4SLinus Torvalds 
39026039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
390363d2bc1bSAndrei Emeltchenko {
390463d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
390563d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
390663d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
390763d2bc1bSAndrei Emeltchenko 	int quote;
390863d2bc1bSAndrei Emeltchenko 
390963d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
391004837f64SMarcel Holtmann 
391173d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
391273d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
3913ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3914ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
391573d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
391673d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
391773d80debSLuiz Augusto von Dentz 
3918ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3919ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3920ec1cce24SLuiz Augusto von Dentz 				break;
3921ec1cce24SLuiz Augusto von Dentz 
3922ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3923ec1cce24SLuiz Augusto von Dentz 
392473d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
392573d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
392604837f64SMarcel Holtmann 
392757d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
39281da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
39291da177e4SLinus Torvalds 
39301da177e4SLinus Torvalds 			hdev->acl_cnt--;
393173d80debSLuiz Augusto von Dentz 			chan->sent++;
393273d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
39331da177e4SLinus Torvalds 		}
39341da177e4SLinus Torvalds 	}
393502b20f0bSLuiz Augusto von Dentz 
393602b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
393702b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
39381da177e4SLinus Torvalds }
39391da177e4SLinus Torvalds 
39406039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
3941b71d385aSAndrei Emeltchenko {
394263d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
3943b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
3944b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
3945b71d385aSAndrei Emeltchenko 	int quote;
3946bd1eb66bSAndrei Emeltchenko 	u8 type;
3947b71d385aSAndrei Emeltchenko 
394863d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
3949b71d385aSAndrei Emeltchenko 
3950bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3951bd1eb66bSAndrei Emeltchenko 
3952bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
3953bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
3954bd1eb66bSAndrei Emeltchenko 	else
3955bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
3956bd1eb66bSAndrei Emeltchenko 
3957b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
3958bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
3959b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
3960b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
3961b71d385aSAndrei Emeltchenko 			int blocks;
3962b71d385aSAndrei Emeltchenko 
3963b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
3964b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
3965b71d385aSAndrei Emeltchenko 
3966b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
3967b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
3968b71d385aSAndrei Emeltchenko 				break;
3969b71d385aSAndrei Emeltchenko 
3970b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
3971b71d385aSAndrei Emeltchenko 
3972b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
3973b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
3974b71d385aSAndrei Emeltchenko 				return;
3975b71d385aSAndrei Emeltchenko 
3976b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
3977b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
3978b71d385aSAndrei Emeltchenko 
397957d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
3980b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
3981b71d385aSAndrei Emeltchenko 
3982b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
3983b71d385aSAndrei Emeltchenko 			quote -= blocks;
3984b71d385aSAndrei Emeltchenko 
3985b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
3986b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
3987b71d385aSAndrei Emeltchenko 		}
3988b71d385aSAndrei Emeltchenko 	}
3989b71d385aSAndrei Emeltchenko 
3990b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
3991bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
3992b71d385aSAndrei Emeltchenko }
3993b71d385aSAndrei Emeltchenko 
39946039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
3995b71d385aSAndrei Emeltchenko {
3996b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3997b71d385aSAndrei Emeltchenko 
3998bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
3999bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR)
4000bd1eb66bSAndrei Emeltchenko 		return;
4001bd1eb66bSAndrei Emeltchenko 
4002bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
4003bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
4004b71d385aSAndrei Emeltchenko 		return;
4005b71d385aSAndrei Emeltchenko 
4006b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
4007b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
4008b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
4009b71d385aSAndrei Emeltchenko 		break;
4010b71d385aSAndrei Emeltchenko 
4011b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
4012b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
4013b71d385aSAndrei Emeltchenko 		break;
4014b71d385aSAndrei Emeltchenko 	}
4015b71d385aSAndrei Emeltchenko }
4016b71d385aSAndrei Emeltchenko 
40171da177e4SLinus Torvalds /* Schedule SCO */
40186039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev)
40191da177e4SLinus Torvalds {
40201da177e4SLinus Torvalds 	struct hci_conn *conn;
40211da177e4SLinus Torvalds 	struct sk_buff *skb;
40221da177e4SLinus Torvalds 	int quote;
40231da177e4SLinus Torvalds 
40241da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
40251da177e4SLinus Torvalds 
402652087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
402752087a79SLuiz Augusto von Dentz 		return;
402852087a79SLuiz Augusto von Dentz 
40291da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
40301da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
40311da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
403257d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
40331da177e4SLinus Torvalds 
40341da177e4SLinus Torvalds 			conn->sent++;
40351da177e4SLinus Torvalds 			if (conn->sent == ~0)
40361da177e4SLinus Torvalds 				conn->sent = 0;
40371da177e4SLinus Torvalds 		}
40381da177e4SLinus Torvalds 	}
40391da177e4SLinus Torvalds }
40401da177e4SLinus Torvalds 
40416039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev)
4042b6a0dc82SMarcel Holtmann {
4043b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
4044b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
4045b6a0dc82SMarcel Holtmann 	int quote;
4046b6a0dc82SMarcel Holtmann 
4047b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
4048b6a0dc82SMarcel Holtmann 
404952087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
405052087a79SLuiz Augusto von Dentz 		return;
405152087a79SLuiz Augusto von Dentz 
40528fc9ced3SGustavo Padovan 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
40538fc9ced3SGustavo Padovan 						     &quote))) {
4054b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
4055b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
405657d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
4057b6a0dc82SMarcel Holtmann 
4058b6a0dc82SMarcel Holtmann 			conn->sent++;
4059b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
4060b6a0dc82SMarcel Holtmann 				conn->sent = 0;
4061b6a0dc82SMarcel Holtmann 		}
4062b6a0dc82SMarcel Holtmann 	}
4063b6a0dc82SMarcel Holtmann }
4064b6a0dc82SMarcel Holtmann 
40656039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
40666ed58ec5SVille Tervo {
406773d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
40686ed58ec5SVille Tervo 	struct sk_buff *skb;
406902b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
40706ed58ec5SVille Tervo 
40716ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
40726ed58ec5SVille Tervo 
407352087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
407452087a79SLuiz Augusto von Dentz 		return;
407552087a79SLuiz Augusto von Dentz 
4076d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
40776ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
40786ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
4079bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
40806ed58ec5SVille Tervo 		    time_after(jiffies, hdev->le_last_tx + HZ * 45))
4081bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
40826ed58ec5SVille Tervo 	}
40836ed58ec5SVille Tervo 
40846ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
408502b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
408673d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
4087ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
4088ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
408973d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
409073d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
40916ed58ec5SVille Tervo 
4092ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
4093ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
4094ec1cce24SLuiz Augusto von Dentz 				break;
4095ec1cce24SLuiz Augusto von Dentz 
4096ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
4097ec1cce24SLuiz Augusto von Dentz 
409857d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
40996ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
41006ed58ec5SVille Tervo 
41016ed58ec5SVille Tervo 			cnt--;
410273d80debSLuiz Augusto von Dentz 			chan->sent++;
410373d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
41046ed58ec5SVille Tervo 		}
41056ed58ec5SVille Tervo 	}
410673d80debSLuiz Augusto von Dentz 
41076ed58ec5SVille Tervo 	if (hdev->le_pkts)
41086ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
41096ed58ec5SVille Tervo 	else
41106ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
411102b20f0bSLuiz Augusto von Dentz 
411202b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
411302b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
41146ed58ec5SVille Tervo }
41156ed58ec5SVille Tervo 
41163eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
41171da177e4SLinus Torvalds {
41183eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
41191da177e4SLinus Torvalds 	struct sk_buff *skb;
41201da177e4SLinus Torvalds 
41216ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
41226ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
41231da177e4SLinus Torvalds 
4124d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
41251da177e4SLinus Torvalds 		/* Schedule queues and send stuff to HCI driver */
41261da177e4SLinus Torvalds 		hci_sched_acl(hdev);
41271da177e4SLinus Torvalds 		hci_sched_sco(hdev);
4128b6a0dc82SMarcel Holtmann 		hci_sched_esco(hdev);
41296ed58ec5SVille Tervo 		hci_sched_le(hdev);
413052de599eSMarcel Holtmann 	}
41316ed58ec5SVille Tervo 
41321da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
41331da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
413457d17d70SMarcel Holtmann 		hci_send_frame(hdev, skb);
41351da177e4SLinus Torvalds }
41361da177e4SLinus Torvalds 
413725985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
41381da177e4SLinus Torvalds 
41391da177e4SLinus Torvalds /* ACL data packet */
41406039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
41411da177e4SLinus Torvalds {
41421da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
41431da177e4SLinus Torvalds 	struct hci_conn *conn;
41441da177e4SLinus Torvalds 	__u16 handle, flags;
41451da177e4SLinus Torvalds 
41461da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
41471da177e4SLinus Torvalds 
41481da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
41491da177e4SLinus Torvalds 	flags  = hci_flags(handle);
41501da177e4SLinus Torvalds 	handle = hci_handle(handle);
41511da177e4SLinus Torvalds 
4152f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
4153a8c5fb1aSGustavo Padovan 	       handle, flags);
41541da177e4SLinus Torvalds 
41551da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
41561da177e4SLinus Torvalds 
41571da177e4SLinus Torvalds 	hci_dev_lock(hdev);
41581da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
41591da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
41601da177e4SLinus Torvalds 
41611da177e4SLinus Torvalds 	if (conn) {
416265983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
416304837f64SMarcel Holtmann 
41641da177e4SLinus Torvalds 		/* Send to upper protocol */
4165686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
41661da177e4SLinus Torvalds 		return;
41671da177e4SLinus Torvalds 	} else {
41681da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
41691da177e4SLinus Torvalds 		       hdev->name, handle);
41701da177e4SLinus Torvalds 	}
41711da177e4SLinus Torvalds 
41721da177e4SLinus Torvalds 	kfree_skb(skb);
41731da177e4SLinus Torvalds }
41741da177e4SLinus Torvalds 
41751da177e4SLinus Torvalds /* SCO data packet */
41766039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
41771da177e4SLinus Torvalds {
41781da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
41791da177e4SLinus Torvalds 	struct hci_conn *conn;
41801da177e4SLinus Torvalds 	__u16 handle;
41811da177e4SLinus Torvalds 
41821da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
41831da177e4SLinus Torvalds 
41841da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
41851da177e4SLinus Torvalds 
4186f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle);
41871da177e4SLinus Torvalds 
41881da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
41891da177e4SLinus Torvalds 
41901da177e4SLinus Torvalds 	hci_dev_lock(hdev);
41911da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
41921da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
41931da177e4SLinus Torvalds 
41941da177e4SLinus Torvalds 	if (conn) {
41951da177e4SLinus Torvalds 		/* Send to upper protocol */
4196686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
41971da177e4SLinus Torvalds 		return;
41981da177e4SLinus Torvalds 	} else {
41991da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
42001da177e4SLinus Torvalds 		       hdev->name, handle);
42011da177e4SLinus Torvalds 	}
42021da177e4SLinus Torvalds 
42031da177e4SLinus Torvalds 	kfree_skb(skb);
42041da177e4SLinus Torvalds }
42051da177e4SLinus Torvalds 
42069238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
42079238f36aSJohan Hedberg {
42089238f36aSJohan Hedberg 	struct sk_buff *skb;
42099238f36aSJohan Hedberg 
42109238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
42119238f36aSJohan Hedberg 	if (!skb)
42129238f36aSJohan Hedberg 		return true;
42139238f36aSJohan Hedberg 
4214db6e3e8dSJohan Hedberg 	return bt_cb(skb)->req.start;
42159238f36aSJohan Hedberg }
42169238f36aSJohan Hedberg 
421742c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
421842c6b129SJohan Hedberg {
421942c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
422042c6b129SJohan Hedberg 	struct sk_buff *skb;
422142c6b129SJohan Hedberg 	u16 opcode;
422242c6b129SJohan Hedberg 
422342c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
422442c6b129SJohan Hedberg 		return;
422542c6b129SJohan Hedberg 
422642c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
422742c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
422842c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
422942c6b129SJohan Hedberg 		return;
423042c6b129SJohan Hedberg 
423142c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
423242c6b129SJohan Hedberg 	if (!skb)
423342c6b129SJohan Hedberg 		return;
423442c6b129SJohan Hedberg 
423542c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
423642c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
423742c6b129SJohan Hedberg }
423842c6b129SJohan Hedberg 
4239e6214487SJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status,
4240e6214487SJohan Hedberg 			  hci_req_complete_t *req_complete,
4241e6214487SJohan Hedberg 			  hci_req_complete_skb_t *req_complete_skb)
42429238f36aSJohan Hedberg {
42439238f36aSJohan Hedberg 	struct sk_buff *skb;
42449238f36aSJohan Hedberg 	unsigned long flags;
42459238f36aSJohan Hedberg 
42469238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
42479238f36aSJohan Hedberg 
424842c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
424942c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
42509238f36aSJohan Hedberg 	 */
425142c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
425242c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
425342c6b129SJohan Hedberg 		 * reset complete event during init and any pending
425442c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
425542c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
425642c6b129SJohan Hedberg 		 * command.
425742c6b129SJohan Hedberg 		 */
425842c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
425942c6b129SJohan Hedberg 			hci_resend_last(hdev);
426042c6b129SJohan Hedberg 
42619238f36aSJohan Hedberg 		return;
426242c6b129SJohan Hedberg 	}
42639238f36aSJohan Hedberg 
42649238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
42659238f36aSJohan Hedberg 	 * this request the request is not yet complete.
42669238f36aSJohan Hedberg 	 */
42679238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
42689238f36aSJohan Hedberg 		return;
42699238f36aSJohan Hedberg 
42709238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
42719238f36aSJohan Hedberg 	 * callback would be found in hdev->sent_cmd instead of the
42729238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
42739238f36aSJohan Hedberg 	 */
4274e6214487SJohan Hedberg 	if (bt_cb(hdev->sent_cmd)->req.complete) {
4275e6214487SJohan Hedberg 		*req_complete = bt_cb(hdev->sent_cmd)->req.complete;
4276e6214487SJohan Hedberg 		return;
42779238f36aSJohan Hedberg 	}
4278e6214487SJohan Hedberg 
4279e6214487SJohan Hedberg 	if (bt_cb(hdev->sent_cmd)->req.complete_skb) {
4280e6214487SJohan Hedberg 		*req_complete_skb = bt_cb(hdev->sent_cmd)->req.complete_skb;
4281e6214487SJohan Hedberg 		return;
428253e21fbcSJohan Hedberg 	}
42839238f36aSJohan Hedberg 
42849238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
42859238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
42869238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
4287db6e3e8dSJohan Hedberg 		if (bt_cb(skb)->req.start) {
42889238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
42899238f36aSJohan Hedberg 			break;
42909238f36aSJohan Hedberg 		}
42919238f36aSJohan Hedberg 
4292e6214487SJohan Hedberg 		*req_complete = bt_cb(skb)->req.complete;
4293e6214487SJohan Hedberg 		*req_complete_skb = bt_cb(skb)->req.complete_skb;
42949238f36aSJohan Hedberg 		kfree_skb(skb);
42959238f36aSJohan Hedberg 	}
42969238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
42979238f36aSJohan Hedberg }
42989238f36aSJohan Hedberg 
4299b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
43001da177e4SLinus Torvalds {
4301b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
43021da177e4SLinus Torvalds 	struct sk_buff *skb;
43031da177e4SLinus Torvalds 
43041da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
43051da177e4SLinus Torvalds 
43061da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
4307cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
4308cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
4309cd82e61cSMarcel Holtmann 
43101da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
43111da177e4SLinus Torvalds 			/* Send copy to the sockets */
4312470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
43131da177e4SLinus Torvalds 		}
43141da177e4SLinus Torvalds 
4315d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
43161da177e4SLinus Torvalds 			kfree_skb(skb);
43171da177e4SLinus Torvalds 			continue;
43181da177e4SLinus Torvalds 		}
43191da177e4SLinus Torvalds 
43201da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
43211da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
43220d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
43231da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
43241da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
43251da177e4SLinus Torvalds 				kfree_skb(skb);
43261da177e4SLinus Torvalds 				continue;
43273ff50b79SStephen Hemminger 			}
43281da177e4SLinus Torvalds 		}
43291da177e4SLinus Torvalds 
43301da177e4SLinus Torvalds 		/* Process frame */
43310d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
43321da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
4333b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
43341da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
43351da177e4SLinus Torvalds 			break;
43361da177e4SLinus Torvalds 
43371da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
43381da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
43391da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
43401da177e4SLinus Torvalds 			break;
43411da177e4SLinus Torvalds 
43421da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
43431da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
43441da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
43451da177e4SLinus Torvalds 			break;
43461da177e4SLinus Torvalds 
43471da177e4SLinus Torvalds 		default:
43481da177e4SLinus Torvalds 			kfree_skb(skb);
43491da177e4SLinus Torvalds 			break;
43501da177e4SLinus Torvalds 		}
43511da177e4SLinus Torvalds 	}
43521da177e4SLinus Torvalds }
43531da177e4SLinus Torvalds 
4354c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
43551da177e4SLinus Torvalds {
4356c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
43571da177e4SLinus Torvalds 	struct sk_buff *skb;
43581da177e4SLinus Torvalds 
43592104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
43602104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
43611da177e4SLinus Torvalds 
43621da177e4SLinus Torvalds 	/* Send queued commands */
43635a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
43645a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
43655a08ecceSAndrei Emeltchenko 		if (!skb)
43665a08ecceSAndrei Emeltchenko 			return;
43675a08ecceSAndrei Emeltchenko 
43681da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
43691da177e4SLinus Torvalds 
4370a675d7f1SMarcel Holtmann 		hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
437170f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
43721da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
437357d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
43747bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
437565cc2b49SMarcel Holtmann 				cancel_delayed_work(&hdev->cmd_timer);
43767bdb8a5cSSzymon Janc 			else
437765cc2b49SMarcel Holtmann 				schedule_delayed_work(&hdev->cmd_timer,
437865cc2b49SMarcel Holtmann 						      HCI_CMD_TIMEOUT);
43791da177e4SLinus Torvalds 		} else {
43801da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
4381c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
43821da177e4SLinus Torvalds 		}
43831da177e4SLinus Torvalds 	}
43841da177e4SLinus Torvalds }
4385