xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 867146a0)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds    BlueZ - Bluetooth protocol stack for Linux
31da177e4SLinus Torvalds    Copyright (C) 2000-2001 Qualcomm Incorporated
4590051deSGustavo F. Padovan    Copyright (C) 2011 ProFUSION Embedded Systems
51da177e4SLinus Torvalds 
61da177e4SLinus Torvalds    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
71da177e4SLinus Torvalds 
81da177e4SLinus Torvalds    This program is free software; you can redistribute it and/or modify
91da177e4SLinus Torvalds    it under the terms of the GNU General Public License version 2 as
101da177e4SLinus Torvalds    published by the Free Software Foundation;
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
131da177e4SLinus Torvalds    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
141da177e4SLinus Torvalds    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
151da177e4SLinus Torvalds    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
161da177e4SLinus Torvalds    CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
171da177e4SLinus Torvalds    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
181da177e4SLinus Torvalds    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
191da177e4SLinus Torvalds    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
201da177e4SLinus Torvalds 
211da177e4SLinus Torvalds    ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
221da177e4SLinus Torvalds    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
231da177e4SLinus Torvalds    SOFTWARE IS DISCLAIMED.
241da177e4SLinus Torvalds */
251da177e4SLinus Torvalds 
261da177e4SLinus Torvalds /* Bluetooth HCI core. */
271da177e4SLinus Torvalds 
288c520a59SGustavo Padovan #include <linux/export.h>
293df92b31SSasha Levin #include <linux/idr.h>
30611b30f7SMarcel Holtmann #include <linux/rfkill.h>
31baf27f6eSMarcel Holtmann #include <linux/debugfs.h>
3299780a7bSJohan Hedberg #include <linux/crypto.h>
3347219839SMarcel Holtmann #include <asm/unaligned.h>
341da177e4SLinus Torvalds 
351da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
361da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
374bc58f51SJohan Hedberg #include <net/bluetooth/l2cap.h>
38af58925cSMarcel Holtmann #include <net/bluetooth/mgmt.h>
391da177e4SLinus Torvalds 
400857dd3bSJohan Hedberg #include "hci_request.h"
4160c5f5fbSMarcel Holtmann #include "hci_debugfs.h"
42970c4e46SJohan Hedberg #include "smp.h"
43970c4e46SJohan Hedberg 
44b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work);
45c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work);
463eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work);
471da177e4SLinus Torvalds 
481da177e4SLinus Torvalds /* HCI device list */
491da177e4SLinus Torvalds LIST_HEAD(hci_dev_list);
501da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock);
511da177e4SLinus Torvalds 
521da177e4SLinus Torvalds /* HCI callback list */
531da177e4SLinus Torvalds LIST_HEAD(hci_cb_list);
54fba7ecf0SJohan Hedberg DEFINE_MUTEX(hci_cb_list_lock);
551da177e4SLinus Torvalds 
563df92b31SSasha Levin /* HCI ID Numbering */
573df92b31SSasha Levin static DEFINE_IDA(hci_index_ida);
583df92b31SSasha Levin 
59899de765SMarcel Holtmann /* ----- HCI requests ----- */
60899de765SMarcel Holtmann 
61899de765SMarcel Holtmann #define HCI_REQ_DONE	  0
62899de765SMarcel Holtmann #define HCI_REQ_PEND	  1
63899de765SMarcel Holtmann #define HCI_REQ_CANCELED  2
64899de765SMarcel Holtmann 
65899de765SMarcel Holtmann #define hci_req_lock(d)		mutex_lock(&d->req_lock)
66899de765SMarcel Holtmann #define hci_req_unlock(d)	mutex_unlock(&d->req_lock)
67899de765SMarcel Holtmann 
681da177e4SLinus Torvalds /* ---- HCI notifications ---- */
691da177e4SLinus Torvalds 
706516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event)
711da177e4SLinus Torvalds {
72040030efSMarcel Holtmann 	hci_sock_dev_event(hdev, event);
731da177e4SLinus Torvalds }
741da177e4SLinus Torvalds 
75baf27f6eSMarcel Holtmann /* ---- HCI debugfs entries ---- */
76baf27f6eSMarcel Holtmann 
774b4148e9SMarcel Holtmann static ssize_t dut_mode_read(struct file *file, char __user *user_buf,
784b4148e9SMarcel Holtmann 			     size_t count, loff_t *ppos)
794b4148e9SMarcel Holtmann {
804b4148e9SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
814b4148e9SMarcel Holtmann 	char buf[3];
824b4148e9SMarcel Holtmann 
83b7cb93e5SMarcel Holtmann 	buf[0] = hci_dev_test_flag(hdev, HCI_DUT_MODE) ? 'Y': 'N';
844b4148e9SMarcel Holtmann 	buf[1] = '\n';
854b4148e9SMarcel Holtmann 	buf[2] = '\0';
864b4148e9SMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
874b4148e9SMarcel Holtmann }
884b4148e9SMarcel Holtmann 
894b4148e9SMarcel Holtmann static ssize_t dut_mode_write(struct file *file, const char __user *user_buf,
904b4148e9SMarcel Holtmann 			      size_t count, loff_t *ppos)
914b4148e9SMarcel Holtmann {
924b4148e9SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
934b4148e9SMarcel Holtmann 	struct sk_buff *skb;
944b4148e9SMarcel Holtmann 	char buf[32];
954b4148e9SMarcel Holtmann 	size_t buf_size = min(count, (sizeof(buf)-1));
964b4148e9SMarcel Holtmann 	bool enable;
974b4148e9SMarcel Holtmann 
984b4148e9SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
994b4148e9SMarcel Holtmann 		return -ENETDOWN;
1004b4148e9SMarcel Holtmann 
1014b4148e9SMarcel Holtmann 	if (copy_from_user(buf, user_buf, buf_size))
1024b4148e9SMarcel Holtmann 		return -EFAULT;
1034b4148e9SMarcel Holtmann 
1044b4148e9SMarcel Holtmann 	buf[buf_size] = '\0';
1054b4148e9SMarcel Holtmann 	if (strtobool(buf, &enable))
1064b4148e9SMarcel Holtmann 		return -EINVAL;
1074b4148e9SMarcel Holtmann 
108b7cb93e5SMarcel Holtmann 	if (enable == hci_dev_test_flag(hdev, HCI_DUT_MODE))
1094b4148e9SMarcel Holtmann 		return -EALREADY;
1104b4148e9SMarcel Holtmann 
1114b4148e9SMarcel Holtmann 	hci_req_lock(hdev);
1124b4148e9SMarcel Holtmann 	if (enable)
1134b4148e9SMarcel Holtmann 		skb = __hci_cmd_sync(hdev, HCI_OP_ENABLE_DUT_MODE, 0, NULL,
1144b4148e9SMarcel Holtmann 				     HCI_CMD_TIMEOUT);
1154b4148e9SMarcel Holtmann 	else
1164b4148e9SMarcel Holtmann 		skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL,
1174b4148e9SMarcel Holtmann 				     HCI_CMD_TIMEOUT);
1184b4148e9SMarcel Holtmann 	hci_req_unlock(hdev);
1194b4148e9SMarcel Holtmann 
1204b4148e9SMarcel Holtmann 	if (IS_ERR(skb))
1214b4148e9SMarcel Holtmann 		return PTR_ERR(skb);
1224b4148e9SMarcel Holtmann 
1234b4148e9SMarcel Holtmann 	kfree_skb(skb);
1244b4148e9SMarcel Holtmann 
125b7cb93e5SMarcel Holtmann 	hci_dev_change_flag(hdev, HCI_DUT_MODE);
1264b4148e9SMarcel Holtmann 
1274b4148e9SMarcel Holtmann 	return count;
1284b4148e9SMarcel Holtmann }
1294b4148e9SMarcel Holtmann 
1304b4148e9SMarcel Holtmann static const struct file_operations dut_mode_fops = {
1314b4148e9SMarcel Holtmann 	.open		= simple_open,
1324b4148e9SMarcel Holtmann 	.read		= dut_mode_read,
1334b4148e9SMarcel Holtmann 	.write		= dut_mode_write,
1344b4148e9SMarcel Holtmann 	.llseek		= default_llseek,
1354b4148e9SMarcel Holtmann };
1364b4148e9SMarcel Holtmann 
1371da177e4SLinus Torvalds /* ---- HCI requests ---- */
1381da177e4SLinus Torvalds 
139f60cb305SJohan Hedberg static void hci_req_sync_complete(struct hci_dev *hdev, u8 result, u16 opcode,
140f60cb305SJohan Hedberg 				  struct sk_buff *skb)
1411da177e4SLinus Torvalds {
14242c6b129SJohan Hedberg 	BT_DBG("%s result 0x%2.2x", hdev->name, result);
14375fb0e32SJohan Hedberg 
1441da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
1451da177e4SLinus Torvalds 		hdev->req_result = result;
1461da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_DONE;
147f60cb305SJohan Hedberg 		if (skb)
148f60cb305SJohan Hedberg 			hdev->req_skb = skb_get(skb);
1491da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
1501da177e4SLinus Torvalds 	}
1511da177e4SLinus Torvalds }
1521da177e4SLinus Torvalds 
1531da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err)
1541da177e4SLinus Torvalds {
1551da177e4SLinus Torvalds 	BT_DBG("%s err 0x%2.2x", hdev->name, err);
1561da177e4SLinus Torvalds 
1571da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
1581da177e4SLinus Torvalds 		hdev->req_result = err;
1591da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_CANCELED;
1601da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
1611da177e4SLinus Torvalds 	}
1621da177e4SLinus Torvalds }
1631da177e4SLinus Torvalds 
1647b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
16507dc93ddSJohan Hedberg 				  const void *param, u8 event, u32 timeout)
16675e84b7cSJohan Hedberg {
16775e84b7cSJohan Hedberg 	DECLARE_WAITQUEUE(wait, current);
16875e84b7cSJohan Hedberg 	struct hci_request req;
169f60cb305SJohan Hedberg 	struct sk_buff *skb;
17075e84b7cSJohan Hedberg 	int err = 0;
17175e84b7cSJohan Hedberg 
17275e84b7cSJohan Hedberg 	BT_DBG("%s", hdev->name);
17375e84b7cSJohan Hedberg 
17475e84b7cSJohan Hedberg 	hci_req_init(&req, hdev);
17575e84b7cSJohan Hedberg 
1767b1abbbeSJohan Hedberg 	hci_req_add_ev(&req, opcode, plen, param, event);
17775e84b7cSJohan Hedberg 
17875e84b7cSJohan Hedberg 	hdev->req_status = HCI_REQ_PEND;
17975e84b7cSJohan Hedberg 
18075e84b7cSJohan Hedberg 	add_wait_queue(&hdev->req_wait_q, &wait);
18175e84b7cSJohan Hedberg 	set_current_state(TASK_INTERRUPTIBLE);
18275e84b7cSJohan Hedberg 
183f60cb305SJohan Hedberg 	err = hci_req_run_skb(&req, hci_req_sync_complete);
184039fada5SChan-yeol Park 	if (err < 0) {
185039fada5SChan-yeol Park 		remove_wait_queue(&hdev->req_wait_q, &wait);
18622a3ceabSJohan Hedberg 		set_current_state(TASK_RUNNING);
187039fada5SChan-yeol Park 		return ERR_PTR(err);
188039fada5SChan-yeol Park 	}
189039fada5SChan-yeol Park 
19075e84b7cSJohan Hedberg 	schedule_timeout(timeout);
19175e84b7cSJohan Hedberg 
19275e84b7cSJohan Hedberg 	remove_wait_queue(&hdev->req_wait_q, &wait);
19375e84b7cSJohan Hedberg 
19475e84b7cSJohan Hedberg 	if (signal_pending(current))
19575e84b7cSJohan Hedberg 		return ERR_PTR(-EINTR);
19675e84b7cSJohan Hedberg 
19775e84b7cSJohan Hedberg 	switch (hdev->req_status) {
19875e84b7cSJohan Hedberg 	case HCI_REQ_DONE:
19975e84b7cSJohan Hedberg 		err = -bt_to_errno(hdev->req_result);
20075e84b7cSJohan Hedberg 		break;
20175e84b7cSJohan Hedberg 
20275e84b7cSJohan Hedberg 	case HCI_REQ_CANCELED:
20375e84b7cSJohan Hedberg 		err = -hdev->req_result;
20475e84b7cSJohan Hedberg 		break;
20575e84b7cSJohan Hedberg 
20675e84b7cSJohan Hedberg 	default:
20775e84b7cSJohan Hedberg 		err = -ETIMEDOUT;
20875e84b7cSJohan Hedberg 		break;
20975e84b7cSJohan Hedberg 	}
21075e84b7cSJohan Hedberg 
21175e84b7cSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
212f60cb305SJohan Hedberg 	skb = hdev->req_skb;
213f60cb305SJohan Hedberg 	hdev->req_skb = NULL;
21475e84b7cSJohan Hedberg 
21575e84b7cSJohan Hedberg 	BT_DBG("%s end: err %d", hdev->name, err);
21675e84b7cSJohan Hedberg 
217f60cb305SJohan Hedberg 	if (err < 0) {
218f60cb305SJohan Hedberg 		kfree_skb(skb);
21975e84b7cSJohan Hedberg 		return ERR_PTR(err);
220f60cb305SJohan Hedberg 	}
22175e84b7cSJohan Hedberg 
222757aa0b5SJohan Hedberg 	if (!skb)
223757aa0b5SJohan Hedberg 		return ERR_PTR(-ENODATA);
224757aa0b5SJohan Hedberg 
225757aa0b5SJohan Hedberg 	return skb;
2267b1abbbeSJohan Hedberg }
2277b1abbbeSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync_ev);
2287b1abbbeSJohan Hedberg 
2297b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
23007dc93ddSJohan Hedberg 			       const void *param, u32 timeout)
2317b1abbbeSJohan Hedberg {
2327b1abbbeSJohan Hedberg 	return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout);
23375e84b7cSJohan Hedberg }
23475e84b7cSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync);
23575e84b7cSJohan Hedberg 
2361da177e4SLinus Torvalds /* Execute request and wait for completion. */
23701178cd4SJohan Hedberg static int __hci_req_sync(struct hci_dev *hdev,
23842c6b129SJohan Hedberg 			  void (*func)(struct hci_request *req,
23942c6b129SJohan Hedberg 				      unsigned long opt),
2401da177e4SLinus Torvalds 			  unsigned long opt, __u32 timeout)
2411da177e4SLinus Torvalds {
24242c6b129SJohan Hedberg 	struct hci_request req;
2431da177e4SLinus Torvalds 	DECLARE_WAITQUEUE(wait, current);
2441da177e4SLinus Torvalds 	int err = 0;
2451da177e4SLinus Torvalds 
2461da177e4SLinus Torvalds 	BT_DBG("%s start", hdev->name);
2471da177e4SLinus Torvalds 
24842c6b129SJohan Hedberg 	hci_req_init(&req, hdev);
24942c6b129SJohan Hedberg 
2501da177e4SLinus Torvalds 	hdev->req_status = HCI_REQ_PEND;
2511da177e4SLinus Torvalds 
25242c6b129SJohan Hedberg 	func(&req, opt);
25353cce22dSJohan Hedberg 
254039fada5SChan-yeol Park 	add_wait_queue(&hdev->req_wait_q, &wait);
255039fada5SChan-yeol Park 	set_current_state(TASK_INTERRUPTIBLE);
256039fada5SChan-yeol Park 
257f60cb305SJohan Hedberg 	err = hci_req_run_skb(&req, hci_req_sync_complete);
25842c6b129SJohan Hedberg 	if (err < 0) {
25953cce22dSJohan Hedberg 		hdev->req_status = 0;
260920c8300SAndre Guedes 
261039fada5SChan-yeol Park 		remove_wait_queue(&hdev->req_wait_q, &wait);
26222a3ceabSJohan Hedberg 		set_current_state(TASK_RUNNING);
263039fada5SChan-yeol Park 
264920c8300SAndre Guedes 		/* ENODATA means the HCI request command queue is empty.
265920c8300SAndre Guedes 		 * This can happen when a request with conditionals doesn't
266920c8300SAndre Guedes 		 * trigger any commands to be sent. This is normal behavior
267920c8300SAndre Guedes 		 * and should not trigger an error return.
26842c6b129SJohan Hedberg 		 */
269920c8300SAndre Guedes 		if (err == -ENODATA)
27042c6b129SJohan Hedberg 			return 0;
271920c8300SAndre Guedes 
272920c8300SAndre Guedes 		return err;
27353cce22dSJohan Hedberg 	}
27453cce22dSJohan Hedberg 
2751da177e4SLinus Torvalds 	schedule_timeout(timeout);
2761da177e4SLinus Torvalds 
2771da177e4SLinus Torvalds 	remove_wait_queue(&hdev->req_wait_q, &wait);
2781da177e4SLinus Torvalds 
2791da177e4SLinus Torvalds 	if (signal_pending(current))
2801da177e4SLinus Torvalds 		return -EINTR;
2811da177e4SLinus Torvalds 
2821da177e4SLinus Torvalds 	switch (hdev->req_status) {
2831da177e4SLinus Torvalds 	case HCI_REQ_DONE:
284e175072fSJoe Perches 		err = -bt_to_errno(hdev->req_result);
2851da177e4SLinus Torvalds 		break;
2861da177e4SLinus Torvalds 
2871da177e4SLinus Torvalds 	case HCI_REQ_CANCELED:
2881da177e4SLinus Torvalds 		err = -hdev->req_result;
2891da177e4SLinus Torvalds 		break;
2901da177e4SLinus Torvalds 
2911da177e4SLinus Torvalds 	default:
2921da177e4SLinus Torvalds 		err = -ETIMEDOUT;
2931da177e4SLinus Torvalds 		break;
2943ff50b79SStephen Hemminger 	}
2951da177e4SLinus Torvalds 
296a5040efaSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
2971da177e4SLinus Torvalds 
2981da177e4SLinus Torvalds 	BT_DBG("%s end: err %d", hdev->name, err);
2991da177e4SLinus Torvalds 
3001da177e4SLinus Torvalds 	return err;
3011da177e4SLinus Torvalds }
3021da177e4SLinus Torvalds 
30301178cd4SJohan Hedberg static int hci_req_sync(struct hci_dev *hdev,
30442c6b129SJohan Hedberg 			void (*req)(struct hci_request *req,
30542c6b129SJohan Hedberg 				    unsigned long opt),
3061da177e4SLinus Torvalds 			unsigned long opt, __u32 timeout)
3071da177e4SLinus Torvalds {
3081da177e4SLinus Torvalds 	int ret;
3091da177e4SLinus Torvalds 
3107c6a329eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
3117c6a329eSMarcel Holtmann 		return -ENETDOWN;
3127c6a329eSMarcel Holtmann 
3131da177e4SLinus Torvalds 	/* Serialize all requests */
3141da177e4SLinus Torvalds 	hci_req_lock(hdev);
31501178cd4SJohan Hedberg 	ret = __hci_req_sync(hdev, req, opt, timeout);
3161da177e4SLinus Torvalds 	hci_req_unlock(hdev);
3171da177e4SLinus Torvalds 
3181da177e4SLinus Torvalds 	return ret;
3191da177e4SLinus Torvalds }
3201da177e4SLinus Torvalds 
32142c6b129SJohan Hedberg static void hci_reset_req(struct hci_request *req, unsigned long opt)
3221da177e4SLinus Torvalds {
32342c6b129SJohan Hedberg 	BT_DBG("%s %ld", req->hdev->name, opt);
3241da177e4SLinus Torvalds 
3251da177e4SLinus Torvalds 	/* Reset device */
32642c6b129SJohan Hedberg 	set_bit(HCI_RESET, &req->hdev->flags);
32742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_RESET, 0, NULL);
3281da177e4SLinus Torvalds }
3291da177e4SLinus Torvalds 
33042c6b129SJohan Hedberg static void bredr_init(struct hci_request *req)
3311da177e4SLinus Torvalds {
33242c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
3332455a3eaSAndrei Emeltchenko 
3341da177e4SLinus Torvalds 	/* Read Local Supported Features */
33542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
3361da177e4SLinus Torvalds 
3371143e5a6SMarcel Holtmann 	/* Read Local Version */
33842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
3392177bab5SJohan Hedberg 
3402177bab5SJohan Hedberg 	/* Read BD Address */
34142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
3421da177e4SLinus Torvalds }
3431da177e4SLinus Torvalds 
3440af801b9SJohan Hedberg static void amp_init1(struct hci_request *req)
345e61ef499SAndrei Emeltchenko {
34642c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
3472455a3eaSAndrei Emeltchenko 
348e61ef499SAndrei Emeltchenko 	/* Read Local Version */
34942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
3506bcbc489SAndrei Emeltchenko 
351f6996cfeSMarcel Holtmann 	/* Read Local Supported Commands */
352f6996cfeSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
353f6996cfeSMarcel Holtmann 
3546bcbc489SAndrei Emeltchenko 	/* Read Local AMP Info */
35542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
356e71dfabaSAndrei Emeltchenko 
357e71dfabaSAndrei Emeltchenko 	/* Read Data Blk size */
35842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL);
3597528ca1cSMarcel Holtmann 
360f38ba941SMarcel Holtmann 	/* Read Flow Control Mode */
361f38ba941SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL);
362f38ba941SMarcel Holtmann 
3637528ca1cSMarcel Holtmann 	/* Read Location Data */
3647528ca1cSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL);
365e61ef499SAndrei Emeltchenko }
366e61ef499SAndrei Emeltchenko 
3670af801b9SJohan Hedberg static void amp_init2(struct hci_request *req)
3680af801b9SJohan Hedberg {
3690af801b9SJohan Hedberg 	/* Read Local Supported Features. Not all AMP controllers
3700af801b9SJohan Hedberg 	 * support this so it's placed conditionally in the second
3710af801b9SJohan Hedberg 	 * stage init.
3720af801b9SJohan Hedberg 	 */
3730af801b9SJohan Hedberg 	if (req->hdev->commands[14] & 0x20)
3740af801b9SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
3750af801b9SJohan Hedberg }
3760af801b9SJohan Hedberg 
37742c6b129SJohan Hedberg static void hci_init1_req(struct hci_request *req, unsigned long opt)
378e61ef499SAndrei Emeltchenko {
37942c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
380e61ef499SAndrei Emeltchenko 
381e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
382e61ef499SAndrei Emeltchenko 
38311778716SAndrei Emeltchenko 	/* Reset */
38411778716SAndrei Emeltchenko 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
38542c6b129SJohan Hedberg 		hci_reset_req(req, 0);
38611778716SAndrei Emeltchenko 
387e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
388e61ef499SAndrei Emeltchenko 	case HCI_BREDR:
38942c6b129SJohan Hedberg 		bredr_init(req);
390e61ef499SAndrei Emeltchenko 		break;
391e61ef499SAndrei Emeltchenko 
392e61ef499SAndrei Emeltchenko 	case HCI_AMP:
3930af801b9SJohan Hedberg 		amp_init1(req);
394e61ef499SAndrei Emeltchenko 		break;
395e61ef499SAndrei Emeltchenko 
396e61ef499SAndrei Emeltchenko 	default:
397e61ef499SAndrei Emeltchenko 		BT_ERR("Unknown device type %d", hdev->dev_type);
398e61ef499SAndrei Emeltchenko 		break;
399e61ef499SAndrei Emeltchenko 	}
400e61ef499SAndrei Emeltchenko }
401e61ef499SAndrei Emeltchenko 
40242c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req)
4032177bab5SJohan Hedberg {
4042177bab5SJohan Hedberg 	__le16 param;
4052177bab5SJohan Hedberg 	__u8 flt_type;
4062177bab5SJohan Hedberg 
4072177bab5SJohan Hedberg 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
40842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
4092177bab5SJohan Hedberg 
4102177bab5SJohan Hedberg 	/* Read Class of Device */
41142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
4122177bab5SJohan Hedberg 
4132177bab5SJohan Hedberg 	/* Read Local Name */
41442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL);
4152177bab5SJohan Hedberg 
4162177bab5SJohan Hedberg 	/* Read Voice Setting */
41742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL);
4182177bab5SJohan Hedberg 
419b4cb9fb2SMarcel Holtmann 	/* Read Number of Supported IAC */
420b4cb9fb2SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL);
421b4cb9fb2SMarcel Holtmann 
4224b836f39SMarcel Holtmann 	/* Read Current IAC LAP */
4234b836f39SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL);
4244b836f39SMarcel Holtmann 
4252177bab5SJohan Hedberg 	/* Clear Event Filters */
4262177bab5SJohan Hedberg 	flt_type = HCI_FLT_CLEAR_ALL;
42742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
4282177bab5SJohan Hedberg 
4292177bab5SJohan Hedberg 	/* Connection accept timeout ~20 secs */
430dcf4adbfSJoe Perches 	param = cpu_to_le16(0x7d00);
43142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
4322177bab5SJohan Hedberg }
4332177bab5SJohan Hedberg 
43442c6b129SJohan Hedberg static void le_setup(struct hci_request *req)
4352177bab5SJohan Hedberg {
436c73eee91SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
437c73eee91SJohan Hedberg 
4382177bab5SJohan Hedberg 	/* Read LE Buffer Size */
43942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
4402177bab5SJohan Hedberg 
4412177bab5SJohan Hedberg 	/* Read LE Local Supported Features */
44242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
4432177bab5SJohan Hedberg 
444747d3f03SMarcel Holtmann 	/* Read LE Supported States */
445747d3f03SMarcel Holtmann 	hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);
446747d3f03SMarcel Holtmann 
4472177bab5SJohan Hedberg 	/* Read LE White List Size */
44842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL);
4492177bab5SJohan Hedberg 
450747d3f03SMarcel Holtmann 	/* Clear LE White List */
451747d3f03SMarcel Holtmann 	hci_req_add(req, HCI_OP_LE_CLEAR_WHITE_LIST, 0, NULL);
452c73eee91SJohan Hedberg 
453c73eee91SJohan Hedberg 	/* LE-only controllers have LE implicitly enabled */
454c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
455a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_LE_ENABLED);
4562177bab5SJohan Hedberg }
4572177bab5SJohan Hedberg 
45842c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req)
4592177bab5SJohan Hedberg {
46042c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
46142c6b129SJohan Hedberg 
4622177bab5SJohan Hedberg 	/* The second byte is 0xff instead of 0x9f (two reserved bits
4632177bab5SJohan Hedberg 	 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
4642177bab5SJohan Hedberg 	 * command otherwise.
4652177bab5SJohan Hedberg 	 */
4662177bab5SJohan Hedberg 	u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
4672177bab5SJohan Hedberg 
4682177bab5SJohan Hedberg 	/* CSR 1.1 dongles does not accept any bitfield so don't try to set
4692177bab5SJohan Hedberg 	 * any event mask for pre 1.2 devices.
4702177bab5SJohan Hedberg 	 */
4712177bab5SJohan Hedberg 	if (hdev->hci_ver < BLUETOOTH_VER_1_2)
4722177bab5SJohan Hedberg 		return;
4732177bab5SJohan Hedberg 
4742177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
4752177bab5SJohan Hedberg 		events[4] |= 0x01; /* Flow Specification Complete */
4762177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
4772177bab5SJohan Hedberg 		events[4] |= 0x04; /* Read Remote Extended Features Complete */
4782177bab5SJohan Hedberg 		events[5] |= 0x08; /* Synchronous Connection Complete */
4792177bab5SJohan Hedberg 		events[5] |= 0x10; /* Synchronous Connection Changed */
480c7882cbdSMarcel Holtmann 	} else {
481c7882cbdSMarcel Holtmann 		/* Use a different default for LE-only devices */
482c7882cbdSMarcel Holtmann 		memset(events, 0, sizeof(events));
483c7882cbdSMarcel Holtmann 		events[0] |= 0x10; /* Disconnection Complete */
484c7882cbdSMarcel Holtmann 		events[1] |= 0x08; /* Read Remote Version Information Complete */
485c7882cbdSMarcel Holtmann 		events[1] |= 0x20; /* Command Complete */
486c7882cbdSMarcel Holtmann 		events[1] |= 0x40; /* Command Status */
487c7882cbdSMarcel Holtmann 		events[1] |= 0x80; /* Hardware Error */
488c7882cbdSMarcel Holtmann 		events[2] |= 0x04; /* Number of Completed Packets */
489c7882cbdSMarcel Holtmann 		events[3] |= 0x02; /* Data Buffer Overflow */
4900da71f1bSMarcel Holtmann 
4910da71f1bSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_ENCRYPTION) {
4920da71f1bSMarcel Holtmann 			events[0] |= 0x80; /* Encryption Change */
493c7882cbdSMarcel Holtmann 			events[5] |= 0x80; /* Encryption Key Refresh Complete */
4942177bab5SJohan Hedberg 		}
4950da71f1bSMarcel Holtmann 	}
4962177bab5SJohan Hedberg 
4972177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
4982177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
4992177bab5SJohan Hedberg 
5002177bab5SJohan Hedberg 	if (lmp_sniffsubr_capable(hdev))
5012177bab5SJohan Hedberg 		events[5] |= 0x20; /* Sniff Subrating */
5022177bab5SJohan Hedberg 
5032177bab5SJohan Hedberg 	if (lmp_pause_enc_capable(hdev))
5042177bab5SJohan Hedberg 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
5052177bab5SJohan Hedberg 
5062177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
5072177bab5SJohan Hedberg 		events[5] |= 0x40; /* Extended Inquiry Result */
5082177bab5SJohan Hedberg 
5092177bab5SJohan Hedberg 	if (lmp_no_flush_capable(hdev))
5102177bab5SJohan Hedberg 		events[7] |= 0x01; /* Enhanced Flush Complete */
5112177bab5SJohan Hedberg 
5122177bab5SJohan Hedberg 	if (lmp_lsto_capable(hdev))
5132177bab5SJohan Hedberg 		events[6] |= 0x80; /* Link Supervision Timeout Changed */
5142177bab5SJohan Hedberg 
5152177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
5162177bab5SJohan Hedberg 		events[6] |= 0x01;	/* IO Capability Request */
5172177bab5SJohan Hedberg 		events[6] |= 0x02;	/* IO Capability Response */
5182177bab5SJohan Hedberg 		events[6] |= 0x04;	/* User Confirmation Request */
5192177bab5SJohan Hedberg 		events[6] |= 0x08;	/* User Passkey Request */
5202177bab5SJohan Hedberg 		events[6] |= 0x10;	/* Remote OOB Data Request */
5212177bab5SJohan Hedberg 		events[6] |= 0x20;	/* Simple Pairing Complete */
5222177bab5SJohan Hedberg 		events[7] |= 0x04;	/* User Passkey Notification */
5232177bab5SJohan Hedberg 		events[7] |= 0x08;	/* Keypress Notification */
5242177bab5SJohan Hedberg 		events[7] |= 0x10;	/* Remote Host Supported
5252177bab5SJohan Hedberg 					 * Features Notification
5262177bab5SJohan Hedberg 					 */
5272177bab5SJohan Hedberg 	}
5282177bab5SJohan Hedberg 
5292177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
5302177bab5SJohan Hedberg 		events[7] |= 0x20;	/* LE Meta-Event */
5312177bab5SJohan Hedberg 
53242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
5332177bab5SJohan Hedberg }
5342177bab5SJohan Hedberg 
53542c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt)
5362177bab5SJohan Hedberg {
53742c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
53842c6b129SJohan Hedberg 
5390af801b9SJohan Hedberg 	if (hdev->dev_type == HCI_AMP)
5400af801b9SJohan Hedberg 		return amp_init2(req);
5410af801b9SJohan Hedberg 
5422177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev))
54342c6b129SJohan Hedberg 		bredr_setup(req);
54456f87901SJohan Hedberg 	else
545a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_BREDR_ENABLED);
5462177bab5SJohan Hedberg 
5472177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
54842c6b129SJohan Hedberg 		le_setup(req);
5492177bab5SJohan Hedberg 
5500f3adeaeSMarcel Holtmann 	/* All Bluetooth 1.2 and later controllers should support the
5510f3adeaeSMarcel Holtmann 	 * HCI command for reading the local supported commands.
5520f3adeaeSMarcel Holtmann 	 *
5530f3adeaeSMarcel Holtmann 	 * Unfortunately some controllers indicate Bluetooth 1.2 support,
5540f3adeaeSMarcel Holtmann 	 * but do not have support for this command. If that is the case,
5550f3adeaeSMarcel Holtmann 	 * the driver can quirk the behavior and skip reading the local
5560f3adeaeSMarcel Holtmann 	 * supported commands.
5573f8e2d75SJohan Hedberg 	 */
5580f3adeaeSMarcel Holtmann 	if (hdev->hci_ver > BLUETOOTH_VER_1_1 &&
5590f3adeaeSMarcel Holtmann 	    !test_bit(HCI_QUIRK_BROKEN_LOCAL_COMMANDS, &hdev->quirks))
56042c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
5612177bab5SJohan Hedberg 
5622177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
56357af75a8SMarcel Holtmann 		/* When SSP is available, then the host features page
56457af75a8SMarcel Holtmann 		 * should also be available as well. However some
56557af75a8SMarcel Holtmann 		 * controllers list the max_page as 0 as long as SSP
56657af75a8SMarcel Holtmann 		 * has not been enabled. To achieve proper debugging
56757af75a8SMarcel Holtmann 		 * output, force the minimum max_page to 1 at least.
56857af75a8SMarcel Holtmann 		 */
56957af75a8SMarcel Holtmann 		hdev->max_page = 0x01;
57057af75a8SMarcel Holtmann 
571d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED)) {
5722177bab5SJohan Hedberg 			u8 mode = 0x01;
573574ea3c7SMarcel Holtmann 
57442c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_SSP_MODE,
5752177bab5SJohan Hedberg 				    sizeof(mode), &mode);
5762177bab5SJohan Hedberg 		} else {
5772177bab5SJohan Hedberg 			struct hci_cp_write_eir cp;
5782177bab5SJohan Hedberg 
5792177bab5SJohan Hedberg 			memset(hdev->eir, 0, sizeof(hdev->eir));
5802177bab5SJohan Hedberg 			memset(&cp, 0, sizeof(cp));
5812177bab5SJohan Hedberg 
58242c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
5832177bab5SJohan Hedberg 		}
5842177bab5SJohan Hedberg 	}
5852177bab5SJohan Hedberg 
586043ec9bfSMarcel Holtmann 	if (lmp_inq_rssi_capable(hdev) ||
587043ec9bfSMarcel Holtmann 	    test_bit(HCI_QUIRK_FIXUP_INQUIRY_MODE, &hdev->quirks)) {
58804422da9SMarcel Holtmann 		u8 mode;
58904422da9SMarcel Holtmann 
59004422da9SMarcel Holtmann 		/* If Extended Inquiry Result events are supported, then
59104422da9SMarcel Holtmann 		 * they are clearly preferred over Inquiry Result with RSSI
59204422da9SMarcel Holtmann 		 * events.
59304422da9SMarcel Holtmann 		 */
59404422da9SMarcel Holtmann 		mode = lmp_ext_inq_capable(hdev) ? 0x02 : 0x01;
59504422da9SMarcel Holtmann 
59604422da9SMarcel Holtmann 		hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
59704422da9SMarcel Holtmann 	}
5982177bab5SJohan Hedberg 
5992177bab5SJohan Hedberg 	if (lmp_inq_tx_pwr_capable(hdev))
60042c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
6012177bab5SJohan Hedberg 
6022177bab5SJohan Hedberg 	if (lmp_ext_feat_capable(hdev)) {
6032177bab5SJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
6042177bab5SJohan Hedberg 
6052177bab5SJohan Hedberg 		cp.page = 0x01;
60642c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
60742c6b129SJohan Hedberg 			    sizeof(cp), &cp);
6082177bab5SJohan Hedberg 	}
6092177bab5SJohan Hedberg 
610d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_LINK_SECURITY)) {
6112177bab5SJohan Hedberg 		u8 enable = 1;
61242c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
6132177bab5SJohan Hedberg 			    &enable);
6142177bab5SJohan Hedberg 	}
6152177bab5SJohan Hedberg }
6162177bab5SJohan Hedberg 
61742c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req)
6182177bab5SJohan Hedberg {
61942c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
6202177bab5SJohan Hedberg 	struct hci_cp_write_def_link_policy cp;
6212177bab5SJohan Hedberg 	u16 link_policy = 0;
6222177bab5SJohan Hedberg 
6232177bab5SJohan Hedberg 	if (lmp_rswitch_capable(hdev))
6242177bab5SJohan Hedberg 		link_policy |= HCI_LP_RSWITCH;
6252177bab5SJohan Hedberg 	if (lmp_hold_capable(hdev))
6262177bab5SJohan Hedberg 		link_policy |= HCI_LP_HOLD;
6272177bab5SJohan Hedberg 	if (lmp_sniff_capable(hdev))
6282177bab5SJohan Hedberg 		link_policy |= HCI_LP_SNIFF;
6292177bab5SJohan Hedberg 	if (lmp_park_capable(hdev))
6302177bab5SJohan Hedberg 		link_policy |= HCI_LP_PARK;
6312177bab5SJohan Hedberg 
6322177bab5SJohan Hedberg 	cp.policy = cpu_to_le16(link_policy);
63342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp);
6342177bab5SJohan Hedberg }
6352177bab5SJohan Hedberg 
63642c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req)
6372177bab5SJohan Hedberg {
63842c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
6392177bab5SJohan Hedberg 	struct hci_cp_write_le_host_supported cp;
6402177bab5SJohan Hedberg 
641c73eee91SJohan Hedberg 	/* LE-only devices do not support explicit enablement */
642c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
643c73eee91SJohan Hedberg 		return;
644c73eee91SJohan Hedberg 
6452177bab5SJohan Hedberg 	memset(&cp, 0, sizeof(cp));
6462177bab5SJohan Hedberg 
647d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_LE_ENABLED)) {
6482177bab5SJohan Hedberg 		cp.le = 0x01;
64932226e4fSMarcel Holtmann 		cp.simul = 0x00;
6502177bab5SJohan Hedberg 	}
6512177bab5SJohan Hedberg 
6522177bab5SJohan Hedberg 	if (cp.le != lmp_host_le_capable(hdev))
65342c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
6542177bab5SJohan Hedberg 			    &cp);
6552177bab5SJohan Hedberg }
6562177bab5SJohan Hedberg 
657d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req)
658d62e6d67SJohan Hedberg {
659d62e6d67SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
660d62e6d67SJohan Hedberg 	u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
661d62e6d67SJohan Hedberg 
662d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast master role is supported
663d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
664d62e6d67SJohan Hedberg 	 */
66553b834d2SMarcel Holtmann 	if (lmp_csb_master_capable(hdev)) {
666d62e6d67SJohan Hedberg 		events[1] |= 0x40;	/* Triggered Clock Capture */
667d62e6d67SJohan Hedberg 		events[1] |= 0x80;	/* Synchronization Train Complete */
668d62e6d67SJohan Hedberg 		events[2] |= 0x10;	/* Slave Page Response Timeout */
669d62e6d67SJohan Hedberg 		events[2] |= 0x20;	/* CSB Channel Map Change */
670d62e6d67SJohan Hedberg 	}
671d62e6d67SJohan Hedberg 
672d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast slave role is supported
673d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
674d62e6d67SJohan Hedberg 	 */
67553b834d2SMarcel Holtmann 	if (lmp_csb_slave_capable(hdev)) {
676d62e6d67SJohan Hedberg 		events[2] |= 0x01;	/* Synchronization Train Received */
677d62e6d67SJohan Hedberg 		events[2] |= 0x02;	/* CSB Receive */
678d62e6d67SJohan Hedberg 		events[2] |= 0x04;	/* CSB Timeout */
679d62e6d67SJohan Hedberg 		events[2] |= 0x08;	/* Truncated Page Complete */
680d62e6d67SJohan Hedberg 	}
681d62e6d67SJohan Hedberg 
68240c59fcbSMarcel Holtmann 	/* Enable Authenticated Payload Timeout Expired event if supported */
683cd7ca0ecSMarcel Holtmann 	if (lmp_ping_capable(hdev) || hdev->le_features[0] & HCI_LE_PING)
68440c59fcbSMarcel Holtmann 		events[2] |= 0x80;
68540c59fcbSMarcel Holtmann 
686d62e6d67SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events);
687d62e6d67SJohan Hedberg }
688d62e6d67SJohan Hedberg 
68942c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt)
6902177bab5SJohan Hedberg {
69142c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
692d2c5d77fSJohan Hedberg 	u8 p;
69342c6b129SJohan Hedberg 
6940da71f1bSMarcel Holtmann 	hci_setup_event_mask(req);
6950da71f1bSMarcel Holtmann 
69648ce62c4SMarcel Holtmann 	if (hdev->commands[6] & 0x20) {
69748ce62c4SMarcel Holtmann 		struct hci_cp_read_stored_link_key cp;
69848ce62c4SMarcel Holtmann 
69948ce62c4SMarcel Holtmann 		bacpy(&cp.bdaddr, BDADDR_ANY);
70048ce62c4SMarcel Holtmann 		cp.read_all = 0x01;
70148ce62c4SMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_STORED_LINK_KEY, sizeof(cp), &cp);
70248ce62c4SMarcel Holtmann 	}
70348ce62c4SMarcel Holtmann 
7042177bab5SJohan Hedberg 	if (hdev->commands[5] & 0x10)
70542c6b129SJohan Hedberg 		hci_setup_link_policy(req);
7062177bab5SJohan Hedberg 
707417287deSMarcel Holtmann 	if (hdev->commands[8] & 0x01)
708417287deSMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL);
709417287deSMarcel Holtmann 
710417287deSMarcel Holtmann 	/* Some older Broadcom based Bluetooth 1.2 controllers do not
711417287deSMarcel Holtmann 	 * support the Read Page Scan Type command. Check support for
712417287deSMarcel Holtmann 	 * this command in the bit mask of supported commands.
713417287deSMarcel Holtmann 	 */
714417287deSMarcel Holtmann 	if (hdev->commands[13] & 0x01)
715417287deSMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL);
716417287deSMarcel Holtmann 
7179193c6e8SAndre Guedes 	if (lmp_le_capable(hdev)) {
7189193c6e8SAndre Guedes 		u8 events[8];
7199193c6e8SAndre Guedes 
7209193c6e8SAndre Guedes 		memset(events, 0, sizeof(events));
7214d6c705bSMarcel Holtmann 		events[0] = 0x0f;
7224d6c705bSMarcel Holtmann 
7234d6c705bSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_ENCRYPTION)
7244d6c705bSMarcel Holtmann 			events[0] |= 0x10;	/* LE Long Term Key Request */
725662bc2e6SAndre Guedes 
726662bc2e6SAndre Guedes 		/* If controller supports the Connection Parameters Request
727662bc2e6SAndre Guedes 		 * Link Layer Procedure, enable the corresponding event.
728662bc2e6SAndre Guedes 		 */
729662bc2e6SAndre Guedes 		if (hdev->le_features[0] & HCI_LE_CONN_PARAM_REQ_PROC)
730662bc2e6SAndre Guedes 			events[0] |= 0x20;	/* LE Remote Connection
731662bc2e6SAndre Guedes 						 * Parameter Request
732662bc2e6SAndre Guedes 						 */
733662bc2e6SAndre Guedes 
734a9f6068eSMarcel Holtmann 		/* If the controller supports the Data Length Extension
735a9f6068eSMarcel Holtmann 		 * feature, enable the corresponding event.
736a9f6068eSMarcel Holtmann 		 */
737a9f6068eSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT)
738a9f6068eSMarcel Holtmann 			events[0] |= 0x40;	/* LE Data Length Change */
739a9f6068eSMarcel Holtmann 
7404b71bba4SMarcel Holtmann 		/* If the controller supports Extended Scanner Filter
7414b71bba4SMarcel Holtmann 		 * Policies, enable the correspondig event.
7424b71bba4SMarcel Holtmann 		 */
7434b71bba4SMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_EXT_SCAN_POLICY)
7444b71bba4SMarcel Holtmann 			events[1] |= 0x04;	/* LE Direct Advertising
7454b71bba4SMarcel Holtmann 						 * Report
7464b71bba4SMarcel Holtmann 						 */
7474b71bba4SMarcel Holtmann 
7485a34bd5fSMarcel Holtmann 		/* If the controller supports the LE Read Local P-256
7495a34bd5fSMarcel Holtmann 		 * Public Key command, enable the corresponding event.
7505a34bd5fSMarcel Holtmann 		 */
7515a34bd5fSMarcel Holtmann 		if (hdev->commands[34] & 0x02)
7525a34bd5fSMarcel Holtmann 			events[0] |= 0x80;	/* LE Read Local P-256
7535a34bd5fSMarcel Holtmann 						 * Public Key Complete
7545a34bd5fSMarcel Holtmann 						 */
7555a34bd5fSMarcel Holtmann 
7565a34bd5fSMarcel Holtmann 		/* If the controller supports the LE Generate DHKey
7575a34bd5fSMarcel Holtmann 		 * command, enable the corresponding event.
7585a34bd5fSMarcel Holtmann 		 */
7595a34bd5fSMarcel Holtmann 		if (hdev->commands[34] & 0x04)
7605a34bd5fSMarcel Holtmann 			events[1] |= 0x01;	/* LE Generate DHKey Complete */
7615a34bd5fSMarcel Holtmann 
7629193c6e8SAndre Guedes 		hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, sizeof(events),
7639193c6e8SAndre Guedes 			    events);
7649193c6e8SAndre Guedes 
76515a49ccaSMarcel Holtmann 		if (hdev->commands[25] & 0x40) {
76615a49ccaSMarcel Holtmann 			/* Read LE Advertising Channel TX Power */
76715a49ccaSMarcel Holtmann 			hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
76815a49ccaSMarcel Holtmann 		}
76915a49ccaSMarcel Holtmann 
770a9f6068eSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) {
771a9f6068eSMarcel Holtmann 			/* Read LE Maximum Data Length */
772a9f6068eSMarcel Holtmann 			hci_req_add(req, HCI_OP_LE_READ_MAX_DATA_LEN, 0, NULL);
773a9f6068eSMarcel Holtmann 
774a9f6068eSMarcel Holtmann 			/* Read LE Suggested Default Data Length */
775a9f6068eSMarcel Holtmann 			hci_req_add(req, HCI_OP_LE_READ_DEF_DATA_LEN, 0, NULL);
776a9f6068eSMarcel Holtmann 		}
777a9f6068eSMarcel Holtmann 
77842c6b129SJohan Hedberg 		hci_set_le_support(req);
7799193c6e8SAndre Guedes 	}
780d2c5d77fSJohan Hedberg 
781d2c5d77fSJohan Hedberg 	/* Read features beyond page 1 if available */
782d2c5d77fSJohan Hedberg 	for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
783d2c5d77fSJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
784d2c5d77fSJohan Hedberg 
785d2c5d77fSJohan Hedberg 		cp.page = p;
786d2c5d77fSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
787d2c5d77fSJohan Hedberg 			    sizeof(cp), &cp);
788d2c5d77fSJohan Hedberg 	}
7892177bab5SJohan Hedberg }
7902177bab5SJohan Hedberg 
7915d4e7e8dSJohan Hedberg static void hci_init4_req(struct hci_request *req, unsigned long opt)
7925d4e7e8dSJohan Hedberg {
7935d4e7e8dSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
7945d4e7e8dSJohan Hedberg 
79536f260ceSMarcel Holtmann 	/* Some Broadcom based Bluetooth controllers do not support the
79636f260ceSMarcel Holtmann 	 * Delete Stored Link Key command. They are clearly indicating its
79736f260ceSMarcel Holtmann 	 * absence in the bit mask of supported commands.
79836f260ceSMarcel Holtmann 	 *
79936f260ceSMarcel Holtmann 	 * Check the supported commands and only if the the command is marked
80036f260ceSMarcel Holtmann 	 * as supported send it. If not supported assume that the controller
80136f260ceSMarcel Holtmann 	 * does not have actual support for stored link keys which makes this
80236f260ceSMarcel Holtmann 	 * command redundant anyway.
80336f260ceSMarcel Holtmann 	 *
80436f260ceSMarcel Holtmann 	 * Some controllers indicate that they support handling deleting
80536f260ceSMarcel Holtmann 	 * stored link keys, but they don't. The quirk lets a driver
80636f260ceSMarcel Holtmann 	 * just disable this command.
80736f260ceSMarcel Holtmann 	 */
80836f260ceSMarcel Holtmann 	if (hdev->commands[6] & 0x80 &&
80936f260ceSMarcel Holtmann 	    !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) {
81036f260ceSMarcel Holtmann 		struct hci_cp_delete_stored_link_key cp;
81136f260ceSMarcel Holtmann 
81236f260ceSMarcel Holtmann 		bacpy(&cp.bdaddr, BDADDR_ANY);
81336f260ceSMarcel Holtmann 		cp.delete_all = 0x01;
81436f260ceSMarcel Holtmann 		hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY,
81536f260ceSMarcel Holtmann 			    sizeof(cp), &cp);
81636f260ceSMarcel Holtmann 	}
81736f260ceSMarcel Holtmann 
818d62e6d67SJohan Hedberg 	/* Set event mask page 2 if the HCI command for it is supported */
819d62e6d67SJohan Hedberg 	if (hdev->commands[22] & 0x04)
820d62e6d67SJohan Hedberg 		hci_set_event_mask_page_2(req);
821d62e6d67SJohan Hedberg 
822109e3191SMarcel Holtmann 	/* Read local codec list if the HCI command is supported */
823109e3191SMarcel Holtmann 	if (hdev->commands[29] & 0x20)
824109e3191SMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_LOCAL_CODECS, 0, NULL);
825109e3191SMarcel Holtmann 
826f4fe73edSMarcel Holtmann 	/* Get MWS transport configuration if the HCI command is supported */
827f4fe73edSMarcel Holtmann 	if (hdev->commands[30] & 0x08)
828f4fe73edSMarcel Holtmann 		hci_req_add(req, HCI_OP_GET_MWS_TRANSPORT_CONFIG, 0, NULL);
829f4fe73edSMarcel Holtmann 
8305d4e7e8dSJohan Hedberg 	/* Check for Synchronization Train support */
83153b834d2SMarcel Holtmann 	if (lmp_sync_train_capable(hdev))
8325d4e7e8dSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL);
833a6d0d690SMarcel Holtmann 
834a6d0d690SMarcel Holtmann 	/* Enable Secure Connections if supported and configured */
835d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SSP_ENABLED) &&
836574ea3c7SMarcel Holtmann 	    bredr_sc_enabled(hdev)) {
837a6d0d690SMarcel Holtmann 		u8 support = 0x01;
838574ea3c7SMarcel Holtmann 
839a6d0d690SMarcel Holtmann 		hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT,
840a6d0d690SMarcel Holtmann 			    sizeof(support), &support);
841a6d0d690SMarcel Holtmann 	}
8425d4e7e8dSJohan Hedberg }
8435d4e7e8dSJohan Hedberg 
8442177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev)
8452177bab5SJohan Hedberg {
8462177bab5SJohan Hedberg 	int err;
8472177bab5SJohan Hedberg 
8482177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT);
8492177bab5SJohan Hedberg 	if (err < 0)
8502177bab5SJohan Hedberg 		return err;
8512177bab5SJohan Hedberg 
8524b4148e9SMarcel Holtmann 	/* The Device Under Test (DUT) mode is special and available for
8534b4148e9SMarcel Holtmann 	 * all controller types. So just create it early on.
8544b4148e9SMarcel Holtmann 	 */
855d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP)) {
8564b4148e9SMarcel Holtmann 		debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev,
8574b4148e9SMarcel Holtmann 				    &dut_mode_fops);
8584b4148e9SMarcel Holtmann 	}
8594b4148e9SMarcel Holtmann 
8602177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT);
8612177bab5SJohan Hedberg 	if (err < 0)
8622177bab5SJohan Hedberg 		return err;
8632177bab5SJohan Hedberg 
8640af801b9SJohan Hedberg 	/* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode
8650af801b9SJohan Hedberg 	 * BR/EDR/LE type controllers. AMP controllers only need the
8660af801b9SJohan Hedberg 	 * first two stages of init.
8670af801b9SJohan Hedberg 	 */
8680af801b9SJohan Hedberg 	if (hdev->dev_type != HCI_BREDR)
8690af801b9SJohan Hedberg 		return 0;
8700af801b9SJohan Hedberg 
8715d4e7e8dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT);
8725d4e7e8dSJohan Hedberg 	if (err < 0)
8735d4e7e8dSJohan Hedberg 		return err;
8745d4e7e8dSJohan Hedberg 
875baf27f6eSMarcel Holtmann 	err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT);
876baf27f6eSMarcel Holtmann 	if (err < 0)
877baf27f6eSMarcel Holtmann 		return err;
878baf27f6eSMarcel Holtmann 
879ec6cef9cSMarcel Holtmann 	/* This function is only called when the controller is actually in
880ec6cef9cSMarcel Holtmann 	 * configured state. When the controller is marked as unconfigured,
881ec6cef9cSMarcel Holtmann 	 * this initialization procedure is not run.
882ec6cef9cSMarcel Holtmann 	 *
883ec6cef9cSMarcel Holtmann 	 * It means that it is possible that a controller runs through its
884ec6cef9cSMarcel Holtmann 	 * setup phase and then discovers missing settings. If that is the
885ec6cef9cSMarcel Holtmann 	 * case, then this function will not be called. It then will only
886ec6cef9cSMarcel Holtmann 	 * be called during the config phase.
887ec6cef9cSMarcel Holtmann 	 *
888ec6cef9cSMarcel Holtmann 	 * So only when in setup phase or config phase, create the debugfs
889ec6cef9cSMarcel Holtmann 	 * entries and register the SMP channels.
890baf27f6eSMarcel Holtmann 	 */
891d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
892d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONFIG))
893baf27f6eSMarcel Holtmann 		return 0;
894baf27f6eSMarcel Holtmann 
89560c5f5fbSMarcel Holtmann 	hci_debugfs_create_common(hdev);
89660c5f5fbSMarcel Holtmann 
89771c3b60eSMarcel Holtmann 	if (lmp_bredr_capable(hdev))
89860c5f5fbSMarcel Holtmann 		hci_debugfs_create_bredr(hdev);
8992bfa3531SMarcel Holtmann 
900162a3bacSMarcel Holtmann 	if (lmp_le_capable(hdev))
90160c5f5fbSMarcel Holtmann 		hci_debugfs_create_le(hdev);
902e7b8fc92SMarcel Holtmann 
903baf27f6eSMarcel Holtmann 	return 0;
9042177bab5SJohan Hedberg }
9052177bab5SJohan Hedberg 
9060ebca7d6SMarcel Holtmann static void hci_init0_req(struct hci_request *req, unsigned long opt)
9070ebca7d6SMarcel Holtmann {
9080ebca7d6SMarcel Holtmann 	struct hci_dev *hdev = req->hdev;
9090ebca7d6SMarcel Holtmann 
9100ebca7d6SMarcel Holtmann 	BT_DBG("%s %ld", hdev->name, opt);
9110ebca7d6SMarcel Holtmann 
9120ebca7d6SMarcel Holtmann 	/* Reset */
9130ebca7d6SMarcel Holtmann 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
9140ebca7d6SMarcel Holtmann 		hci_reset_req(req, 0);
9150ebca7d6SMarcel Holtmann 
9160ebca7d6SMarcel Holtmann 	/* Read Local Version */
9170ebca7d6SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
9180ebca7d6SMarcel Holtmann 
9190ebca7d6SMarcel Holtmann 	/* Read BD Address */
9200ebca7d6SMarcel Holtmann 	if (hdev->set_bdaddr)
9210ebca7d6SMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
9220ebca7d6SMarcel Holtmann }
9230ebca7d6SMarcel Holtmann 
9240ebca7d6SMarcel Holtmann static int __hci_unconf_init(struct hci_dev *hdev)
9250ebca7d6SMarcel Holtmann {
9260ebca7d6SMarcel Holtmann 	int err;
9270ebca7d6SMarcel Holtmann 
928cc78b44bSMarcel Holtmann 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
929cc78b44bSMarcel Holtmann 		return 0;
930cc78b44bSMarcel Holtmann 
9310ebca7d6SMarcel Holtmann 	err = __hci_req_sync(hdev, hci_init0_req, 0, HCI_INIT_TIMEOUT);
9320ebca7d6SMarcel Holtmann 	if (err < 0)
9330ebca7d6SMarcel Holtmann 		return err;
9340ebca7d6SMarcel Holtmann 
9350ebca7d6SMarcel Holtmann 	return 0;
9360ebca7d6SMarcel Holtmann }
9370ebca7d6SMarcel Holtmann 
93842c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt)
9391da177e4SLinus Torvalds {
9401da177e4SLinus Torvalds 	__u8 scan = opt;
9411da177e4SLinus Torvalds 
94242c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, scan);
9431da177e4SLinus Torvalds 
9441da177e4SLinus Torvalds 	/* Inquiry and Page scans */
94542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
9461da177e4SLinus Torvalds }
9471da177e4SLinus Torvalds 
94842c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt)
9491da177e4SLinus Torvalds {
9501da177e4SLinus Torvalds 	__u8 auth = opt;
9511da177e4SLinus Torvalds 
95242c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, auth);
9531da177e4SLinus Torvalds 
9541da177e4SLinus Torvalds 	/* Authentication */
95542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
9561da177e4SLinus Torvalds }
9571da177e4SLinus Torvalds 
95842c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt)
9591da177e4SLinus Torvalds {
9601da177e4SLinus Torvalds 	__u8 encrypt = opt;
9611da177e4SLinus Torvalds 
96242c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, encrypt);
9631da177e4SLinus Torvalds 
964e4e8e37cSMarcel Holtmann 	/* Encryption */
96542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
9661da177e4SLinus Torvalds }
9671da177e4SLinus Torvalds 
96842c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt)
969e4e8e37cSMarcel Holtmann {
970e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
971e4e8e37cSMarcel Holtmann 
97242c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, policy);
973e4e8e37cSMarcel Holtmann 
974e4e8e37cSMarcel Holtmann 	/* Default link policy */
97542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
976e4e8e37cSMarcel Holtmann }
977e4e8e37cSMarcel Holtmann 
9781da177e4SLinus Torvalds /* Get HCI device by index.
9791da177e4SLinus Torvalds  * Device is held on return. */
9801da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
9811da177e4SLinus Torvalds {
9828035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
9831da177e4SLinus Torvalds 
9841da177e4SLinus Torvalds 	BT_DBG("%d", index);
9851da177e4SLinus Torvalds 
9861da177e4SLinus Torvalds 	if (index < 0)
9871da177e4SLinus Torvalds 		return NULL;
9881da177e4SLinus Torvalds 
9891da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
9908035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
9911da177e4SLinus Torvalds 		if (d->id == index) {
9921da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
9931da177e4SLinus Torvalds 			break;
9941da177e4SLinus Torvalds 		}
9951da177e4SLinus Torvalds 	}
9961da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
9971da177e4SLinus Torvalds 	return hdev;
9981da177e4SLinus Torvalds }
9991da177e4SLinus Torvalds 
10001da177e4SLinus Torvalds /* ---- Inquiry support ---- */
1001ff9ef578SJohan Hedberg 
100230dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
100330dc78e1SJohan Hedberg {
100430dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
100530dc78e1SJohan Hedberg 
10066fbe195dSAndre Guedes 	switch (discov->state) {
1007343f935bSAndre Guedes 	case DISCOVERY_FINDING:
10086fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
100930dc78e1SJohan Hedberg 		return true;
101030dc78e1SJohan Hedberg 
10116fbe195dSAndre Guedes 	default:
101230dc78e1SJohan Hedberg 		return false;
101330dc78e1SJohan Hedberg 	}
10146fbe195dSAndre Guedes }
101530dc78e1SJohan Hedberg 
1016ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
1017ff9ef578SJohan Hedberg {
1018bb3e0a33SJohan Hedberg 	int old_state = hdev->discovery.state;
1019bb3e0a33SJohan Hedberg 
1020ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
1021ff9ef578SJohan Hedberg 
1022bb3e0a33SJohan Hedberg 	if (old_state == state)
1023ff9ef578SJohan Hedberg 		return;
1024ff9ef578SJohan Hedberg 
1025bb3e0a33SJohan Hedberg 	hdev->discovery.state = state;
1026bb3e0a33SJohan Hedberg 
1027ff9ef578SJohan Hedberg 	switch (state) {
1028ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
1029c54c3860SAndre Guedes 		hci_update_background_scan(hdev);
1030c54c3860SAndre Guedes 
1031bb3e0a33SJohan Hedberg 		if (old_state != DISCOVERY_STARTING)
1032ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
1033ff9ef578SJohan Hedberg 		break;
1034ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
1035ff9ef578SJohan Hedberg 		break;
1036343f935bSAndre Guedes 	case DISCOVERY_FINDING:
1037ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
1038ff9ef578SJohan Hedberg 		break;
103930dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
104030dc78e1SJohan Hedberg 		break;
1041ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
1042ff9ef578SJohan Hedberg 		break;
1043ff9ef578SJohan Hedberg 	}
1044ff9ef578SJohan Hedberg }
1045ff9ef578SJohan Hedberg 
10461f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev)
10471da177e4SLinus Torvalds {
104830883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1049b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
10501da177e4SLinus Torvalds 
1051561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
1052561aafbcSJohan Hedberg 		list_del(&p->all);
1053b57c1a56SJohan Hedberg 		kfree(p);
10541da177e4SLinus Torvalds 	}
1055561aafbcSJohan Hedberg 
1056561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
1057561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
10581da177e4SLinus Torvalds }
10591da177e4SLinus Torvalds 
1060a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
1061a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
10621da177e4SLinus Torvalds {
106330883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
10641da177e4SLinus Torvalds 	struct inquiry_entry *e;
10651da177e4SLinus Torvalds 
10666ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
10671da177e4SLinus Torvalds 
1068561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
10691da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
10701da177e4SLinus Torvalds 			return e;
10711da177e4SLinus Torvalds 	}
10721da177e4SLinus Torvalds 
1073b57c1a56SJohan Hedberg 	return NULL;
1074b57c1a56SJohan Hedberg }
1075b57c1a56SJohan Hedberg 
1076561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
1077561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
1078561aafbcSJohan Hedberg {
107930883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1080561aafbcSJohan Hedberg 	struct inquiry_entry *e;
1081561aafbcSJohan Hedberg 
10826ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
1083561aafbcSJohan Hedberg 
1084561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
1085561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
1086561aafbcSJohan Hedberg 			return e;
1087561aafbcSJohan Hedberg 	}
1088561aafbcSJohan Hedberg 
1089561aafbcSJohan Hedberg 	return NULL;
1090561aafbcSJohan Hedberg }
1091561aafbcSJohan Hedberg 
109230dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
109330dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
109430dc78e1SJohan Hedberg 						       int state)
109530dc78e1SJohan Hedberg {
109630dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
109730dc78e1SJohan Hedberg 	struct inquiry_entry *e;
109830dc78e1SJohan Hedberg 
10996ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
110030dc78e1SJohan Hedberg 
110130dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
110230dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
110330dc78e1SJohan Hedberg 			return e;
110430dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
110530dc78e1SJohan Hedberg 			return e;
110630dc78e1SJohan Hedberg 	}
110730dc78e1SJohan Hedberg 
110830dc78e1SJohan Hedberg 	return NULL;
110930dc78e1SJohan Hedberg }
111030dc78e1SJohan Hedberg 
1111a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
1112a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
1113a3d4e20aSJohan Hedberg {
1114a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1115a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
1116a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
1117a3d4e20aSJohan Hedberg 
1118a3d4e20aSJohan Hedberg 	list_del(&ie->list);
1119a3d4e20aSJohan Hedberg 
1120a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
1121a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
1122a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
1123a3d4e20aSJohan Hedberg 			break;
1124a3d4e20aSJohan Hedberg 		pos = &p->list;
1125a3d4e20aSJohan Hedberg 	}
1126a3d4e20aSJohan Hedberg 
1127a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
1128a3d4e20aSJohan Hedberg }
1129a3d4e20aSJohan Hedberg 
1130af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
1131af58925cSMarcel Holtmann 			     bool name_known)
11321da177e4SLinus Torvalds {
113330883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
113470f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
1135af58925cSMarcel Holtmann 	u32 flags = 0;
11361da177e4SLinus Torvalds 
11376ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
11381da177e4SLinus Torvalds 
11396928a924SJohan Hedberg 	hci_remove_remote_oob_data(hdev, &data->bdaddr, BDADDR_BREDR);
11402b2fec4dSSzymon Janc 
1141af58925cSMarcel Holtmann 	if (!data->ssp_mode)
1142af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
1143388fc8faSJohan Hedberg 
114470f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
1145a3d4e20aSJohan Hedberg 	if (ie) {
1146af58925cSMarcel Holtmann 		if (!ie->data.ssp_mode)
1147af58925cSMarcel Holtmann 			flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
1148388fc8faSJohan Hedberg 
1149a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
1150a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
1151a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
1152a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
1153a3d4e20aSJohan Hedberg 		}
1154a3d4e20aSJohan Hedberg 
1155561aafbcSJohan Hedberg 		goto update;
1156a3d4e20aSJohan Hedberg 	}
1157561aafbcSJohan Hedberg 
11581da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
115927f70f3eSJohan Hedberg 	ie = kzalloc(sizeof(*ie), GFP_KERNEL);
1160af58925cSMarcel Holtmann 	if (!ie) {
1161af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
1162af58925cSMarcel Holtmann 		goto done;
1163af58925cSMarcel Holtmann 	}
116470f23020SAndrei Emeltchenko 
1165561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
1166561aafbcSJohan Hedberg 
1167561aafbcSJohan Hedberg 	if (name_known) {
1168561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
1169561aafbcSJohan Hedberg 	} else {
1170561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
1171561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
1172561aafbcSJohan Hedberg 	}
1173561aafbcSJohan Hedberg 
1174561aafbcSJohan Hedberg update:
1175561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
1176561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
1177561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
1178561aafbcSJohan Hedberg 		list_del(&ie->list);
11791da177e4SLinus Torvalds 	}
11801da177e4SLinus Torvalds 
118170f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
118270f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
11831da177e4SLinus Torvalds 	cache->timestamp = jiffies;
11843175405bSJohan Hedberg 
11853175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
1186af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
11873175405bSJohan Hedberg 
1188af58925cSMarcel Holtmann done:
1189af58925cSMarcel Holtmann 	return flags;
11901da177e4SLinus Torvalds }
11911da177e4SLinus Torvalds 
11921da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
11931da177e4SLinus Torvalds {
119430883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
11951da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
11961da177e4SLinus Torvalds 	struct inquiry_entry *e;
11971da177e4SLinus Torvalds 	int copied = 0;
11981da177e4SLinus Torvalds 
1199561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
12001da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
1201b57c1a56SJohan Hedberg 
1202b57c1a56SJohan Hedberg 		if (copied >= num)
1203b57c1a56SJohan Hedberg 			break;
1204b57c1a56SJohan Hedberg 
12051da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
12061da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
12071da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
12081da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
12091da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
12101da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
1211b57c1a56SJohan Hedberg 
12121da177e4SLinus Torvalds 		info++;
1213b57c1a56SJohan Hedberg 		copied++;
12141da177e4SLinus Torvalds 	}
12151da177e4SLinus Torvalds 
12161da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
12171da177e4SLinus Torvalds 	return copied;
12181da177e4SLinus Torvalds }
12191da177e4SLinus Torvalds 
122042c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt)
12211da177e4SLinus Torvalds {
12221da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
122342c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
12241da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
12251da177e4SLinus Torvalds 
12261da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
12271da177e4SLinus Torvalds 
12281da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
12291da177e4SLinus Torvalds 		return;
12301da177e4SLinus Torvalds 
12311da177e4SLinus Torvalds 	/* Start Inquiry */
12321da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
12331da177e4SLinus Torvalds 	cp.length  = ir->length;
12341da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
123542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
12361da177e4SLinus Torvalds }
12371da177e4SLinus Torvalds 
12381da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
12391da177e4SLinus Torvalds {
12401da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
12411da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
12421da177e4SLinus Torvalds 	struct hci_dev *hdev;
12431da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
12441da177e4SLinus Torvalds 	long timeo;
12451da177e4SLinus Torvalds 	__u8 *buf;
12461da177e4SLinus Torvalds 
12471da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
12481da177e4SLinus Torvalds 		return -EFAULT;
12491da177e4SLinus Torvalds 
12505a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
12515a08ecceSAndrei Emeltchenko 	if (!hdev)
12521da177e4SLinus Torvalds 		return -ENODEV;
12531da177e4SLinus Torvalds 
1254d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
12550736cfa8SMarcel Holtmann 		err = -EBUSY;
12560736cfa8SMarcel Holtmann 		goto done;
12570736cfa8SMarcel Holtmann 	}
12580736cfa8SMarcel Holtmann 
1259d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
1260fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
1261fee746b0SMarcel Holtmann 		goto done;
1262fee746b0SMarcel Holtmann 	}
1263fee746b0SMarcel Holtmann 
12645b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
12655b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
12665b69bef5SMarcel Holtmann 		goto done;
12675b69bef5SMarcel Holtmann 	}
12685b69bef5SMarcel Holtmann 
1269d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
127056f87901SJohan Hedberg 		err = -EOPNOTSUPP;
127156f87901SJohan Hedberg 		goto done;
127256f87901SJohan Hedberg 	}
127356f87901SJohan Hedberg 
127409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
12751da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
1276a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
12771f9b9a5dSAndre Guedes 		hci_inquiry_cache_flush(hdev);
12781da177e4SLinus Torvalds 		do_inquiry = 1;
12791da177e4SLinus Torvalds 	}
128009fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
12811da177e4SLinus Torvalds 
128204837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
128370f23020SAndrei Emeltchenko 
128470f23020SAndrei Emeltchenko 	if (do_inquiry) {
128501178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
128601178cd4SJohan Hedberg 				   timeo);
128770f23020SAndrei Emeltchenko 		if (err < 0)
12881da177e4SLinus Torvalds 			goto done;
12893e13fa1eSAndre Guedes 
12903e13fa1eSAndre Guedes 		/* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
12913e13fa1eSAndre Guedes 		 * cleared). If it is interrupted by a signal, return -EINTR.
12923e13fa1eSAndre Guedes 		 */
129374316201SNeilBrown 		if (wait_on_bit(&hdev->flags, HCI_INQUIRY,
12943e13fa1eSAndre Guedes 				TASK_INTERRUPTIBLE))
12953e13fa1eSAndre Guedes 			return -EINTR;
129670f23020SAndrei Emeltchenko 	}
12971da177e4SLinus Torvalds 
12988fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
12998fc9ced3SGustavo Padovan 	 * 255 entries
13008fc9ced3SGustavo Padovan 	 */
13011da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
13021da177e4SLinus Torvalds 
13031da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
13041da177e4SLinus Torvalds 	 * copy it to the user space.
13051da177e4SLinus Torvalds 	 */
130670f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
130770f23020SAndrei Emeltchenko 	if (!buf) {
13081da177e4SLinus Torvalds 		err = -ENOMEM;
13091da177e4SLinus Torvalds 		goto done;
13101da177e4SLinus Torvalds 	}
13111da177e4SLinus Torvalds 
131209fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
13131da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
131409fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
13151da177e4SLinus Torvalds 
13161da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
13171da177e4SLinus Torvalds 
13181da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
13191da177e4SLinus Torvalds 		ptr += sizeof(ir);
13201da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
13211da177e4SLinus Torvalds 				 ir.num_rsp))
13221da177e4SLinus Torvalds 			err = -EFAULT;
13231da177e4SLinus Torvalds 	} else
13241da177e4SLinus Torvalds 		err = -EFAULT;
13251da177e4SLinus Torvalds 
13261da177e4SLinus Torvalds 	kfree(buf);
13271da177e4SLinus Torvalds 
13281da177e4SLinus Torvalds done:
13291da177e4SLinus Torvalds 	hci_dev_put(hdev);
13301da177e4SLinus Torvalds 	return err;
13311da177e4SLinus Torvalds }
13321da177e4SLinus Torvalds 
1333cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev)
13341da177e4SLinus Torvalds {
13351da177e4SLinus Torvalds 	int ret = 0;
13361da177e4SLinus Torvalds 
13371da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
13381da177e4SLinus Torvalds 
13391da177e4SLinus Torvalds 	hci_req_lock(hdev);
13401da177e4SLinus Torvalds 
1341d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
134294324962SJohan Hovold 		ret = -ENODEV;
134394324962SJohan Hovold 		goto done;
134494324962SJohan Hovold 	}
134594324962SJohan Hovold 
1346d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
1347d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONFIG)) {
1348a5c8f270SMarcel Holtmann 		/* Check for rfkill but allow the HCI setup stage to
1349a5c8f270SMarcel Holtmann 		 * proceed (which in itself doesn't cause any RF activity).
1350bf543036SJohan Hedberg 		 */
1351d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_RFKILLED)) {
1352611b30f7SMarcel Holtmann 			ret = -ERFKILL;
1353611b30f7SMarcel Holtmann 			goto done;
1354611b30f7SMarcel Holtmann 		}
1355611b30f7SMarcel Holtmann 
1356a5c8f270SMarcel Holtmann 		/* Check for valid public address or a configured static
1357a5c8f270SMarcel Holtmann 		 * random adddress, but let the HCI setup proceed to
1358a5c8f270SMarcel Holtmann 		 * be able to determine if there is a public address
1359a5c8f270SMarcel Holtmann 		 * or not.
1360a5c8f270SMarcel Holtmann 		 *
1361c6beca0eSMarcel Holtmann 		 * In case of user channel usage, it is not important
1362c6beca0eSMarcel Holtmann 		 * if a public address or static random address is
1363c6beca0eSMarcel Holtmann 		 * available.
1364c6beca0eSMarcel Holtmann 		 *
1365a5c8f270SMarcel Holtmann 		 * This check is only valid for BR/EDR controllers
1366a5c8f270SMarcel Holtmann 		 * since AMP controllers do not have an address.
1367a5c8f270SMarcel Holtmann 		 */
1368d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
1369c6beca0eSMarcel Holtmann 		    hdev->dev_type == HCI_BREDR &&
1370a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
1371a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->static_addr, BDADDR_ANY)) {
1372a5c8f270SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
1373a5c8f270SMarcel Holtmann 			goto done;
1374a5c8f270SMarcel Holtmann 		}
1375a5c8f270SMarcel Holtmann 	}
1376a5c8f270SMarcel Holtmann 
13771da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
13781da177e4SLinus Torvalds 		ret = -EALREADY;
13791da177e4SLinus Torvalds 		goto done;
13801da177e4SLinus Torvalds 	}
13811da177e4SLinus Torvalds 
13821da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
13831da177e4SLinus Torvalds 		ret = -EIO;
13841da177e4SLinus Torvalds 		goto done;
13851da177e4SLinus Torvalds 	}
13861da177e4SLinus Torvalds 
13871da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
13881da177e4SLinus Torvalds 	set_bit(HCI_INIT, &hdev->flags);
1389f41c70c4SMarcel Holtmann 
1390d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_SETUP)) {
1391af202f84SMarcel Holtmann 		if (hdev->setup)
1392f41c70c4SMarcel Holtmann 			ret = hdev->setup(hdev);
1393f41c70c4SMarcel Holtmann 
1394af202f84SMarcel Holtmann 		/* The transport driver can set these quirks before
1395af202f84SMarcel Holtmann 		 * creating the HCI device or in its setup callback.
1396af202f84SMarcel Holtmann 		 *
1397af202f84SMarcel Holtmann 		 * In case any of them is set, the controller has to
1398af202f84SMarcel Holtmann 		 * start up as unconfigured.
1399af202f84SMarcel Holtmann 		 */
1400eb1904f4SMarcel Holtmann 		if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) ||
1401eb1904f4SMarcel Holtmann 		    test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks))
1402a1536da2SMarcel Holtmann 			hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
1403f41c70c4SMarcel Holtmann 
14040ebca7d6SMarcel Holtmann 		/* For an unconfigured controller it is required to
14050ebca7d6SMarcel Holtmann 		 * read at least the version information provided by
14060ebca7d6SMarcel Holtmann 		 * the Read Local Version Information command.
14070ebca7d6SMarcel Holtmann 		 *
14080ebca7d6SMarcel Holtmann 		 * If the set_bdaddr driver callback is provided, then
14090ebca7d6SMarcel Holtmann 		 * also the original Bluetooth public device address
14100ebca7d6SMarcel Holtmann 		 * will be read using the Read BD Address command.
14110ebca7d6SMarcel Holtmann 		 */
1412d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
14130ebca7d6SMarcel Holtmann 			ret = __hci_unconf_init(hdev);
141489bc22d2SMarcel Holtmann 	}
141589bc22d2SMarcel Holtmann 
1416d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_CONFIG)) {
14179713c17bSMarcel Holtmann 		/* If public address change is configured, ensure that
14189713c17bSMarcel Holtmann 		 * the address gets programmed. If the driver does not
14199713c17bSMarcel Holtmann 		 * support changing the public address, fail the power
14209713c17bSMarcel Holtmann 		 * on procedure.
142124c457e2SMarcel Holtmann 		 */
14229713c17bSMarcel Holtmann 		if (bacmp(&hdev->public_addr, BDADDR_ANY) &&
14239713c17bSMarcel Holtmann 		    hdev->set_bdaddr)
142424c457e2SMarcel Holtmann 			ret = hdev->set_bdaddr(hdev, &hdev->public_addr);
142524c457e2SMarcel Holtmann 		else
142624c457e2SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
142724c457e2SMarcel Holtmann 	}
142824c457e2SMarcel Holtmann 
1429f41c70c4SMarcel Holtmann 	if (!ret) {
1430d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
1431d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
14322177bab5SJohan Hedberg 			ret = __hci_init(hdev);
14331da177e4SLinus Torvalds 	}
14341da177e4SLinus Torvalds 
1435f41c70c4SMarcel Holtmann 	clear_bit(HCI_INIT, &hdev->flags);
1436f41c70c4SMarcel Holtmann 
14371da177e4SLinus Torvalds 	if (!ret) {
14381da177e4SLinus Torvalds 		hci_dev_hold(hdev);
1439a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
14401da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
14411da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
1442d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
1443d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_CONFIG) &&
1444d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
1445d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
14461514b892SMarcel Holtmann 		    hdev->dev_type == HCI_BREDR) {
144709fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
1448744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
144909fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
145056e5cb86SJohan Hedberg 		}
14511da177e4SLinus Torvalds 	} else {
14521da177e4SLinus Torvalds 		/* Init failed, cleanup */
14533eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
1454c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
1455b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
14561da177e4SLinus Torvalds 
14571da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
14581da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
14591da177e4SLinus Torvalds 
14601da177e4SLinus Torvalds 		if (hdev->flush)
14611da177e4SLinus Torvalds 			hdev->flush(hdev);
14621da177e4SLinus Torvalds 
14631da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
14641da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
14651da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
14661da177e4SLinus Torvalds 		}
14671da177e4SLinus Torvalds 
14681da177e4SLinus Torvalds 		hdev->close(hdev);
1469fee746b0SMarcel Holtmann 		hdev->flags &= BIT(HCI_RAW);
14701da177e4SLinus Torvalds 	}
14711da177e4SLinus Torvalds 
14721da177e4SLinus Torvalds done:
14731da177e4SLinus Torvalds 	hci_req_unlock(hdev);
14741da177e4SLinus Torvalds 	return ret;
14751da177e4SLinus Torvalds }
14761da177e4SLinus Torvalds 
1477cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */
1478cbed0ca1SJohan Hedberg 
1479cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev)
1480cbed0ca1SJohan Hedberg {
1481cbed0ca1SJohan Hedberg 	struct hci_dev *hdev;
1482cbed0ca1SJohan Hedberg 	int err;
1483cbed0ca1SJohan Hedberg 
1484cbed0ca1SJohan Hedberg 	hdev = hci_dev_get(dev);
1485cbed0ca1SJohan Hedberg 	if (!hdev)
1486cbed0ca1SJohan Hedberg 		return -ENODEV;
1487cbed0ca1SJohan Hedberg 
14884a964404SMarcel Holtmann 	/* Devices that are marked as unconfigured can only be powered
1489fee746b0SMarcel Holtmann 	 * up as user channel. Trying to bring them up as normal devices
1490fee746b0SMarcel Holtmann 	 * will result into a failure. Only user channel operation is
1491fee746b0SMarcel Holtmann 	 * possible.
1492fee746b0SMarcel Holtmann 	 *
1493fee746b0SMarcel Holtmann 	 * When this function is called for a user channel, the flag
1494fee746b0SMarcel Holtmann 	 * HCI_USER_CHANNEL will be set first before attempting to
1495fee746b0SMarcel Holtmann 	 * open the device.
1496fee746b0SMarcel Holtmann 	 */
1497d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
1498d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
1499fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
1500fee746b0SMarcel Holtmann 		goto done;
1501fee746b0SMarcel Holtmann 	}
1502fee746b0SMarcel Holtmann 
1503e1d08f40SJohan Hedberg 	/* We need to ensure that no other power on/off work is pending
1504e1d08f40SJohan Hedberg 	 * before proceeding to call hci_dev_do_open. This is
1505e1d08f40SJohan Hedberg 	 * particularly important if the setup procedure has not yet
1506e1d08f40SJohan Hedberg 	 * completed.
1507e1d08f40SJohan Hedberg 	 */
1508a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF))
1509e1d08f40SJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
1510e1d08f40SJohan Hedberg 
1511a5c8f270SMarcel Holtmann 	/* After this call it is guaranteed that the setup procedure
1512a5c8f270SMarcel Holtmann 	 * has finished. This means that error conditions like RFKILL
1513a5c8f270SMarcel Holtmann 	 * or no valid public or static random address apply.
1514a5c8f270SMarcel Holtmann 	 */
1515e1d08f40SJohan Hedberg 	flush_workqueue(hdev->req_workqueue);
1516e1d08f40SJohan Hedberg 
151712aa4f0aSMarcel Holtmann 	/* For controllers not using the management interface and that
1518b6ae8457SJohan Hedberg 	 * are brought up using legacy ioctl, set the HCI_BONDABLE bit
151912aa4f0aSMarcel Holtmann 	 * so that pairing works for them. Once the management interface
152012aa4f0aSMarcel Holtmann 	 * is in use this bit will be cleared again and userspace has
152112aa4f0aSMarcel Holtmann 	 * to explicitly enable it.
152212aa4f0aSMarcel Holtmann 	 */
1523d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
1524d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_MGMT))
1525a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BONDABLE);
152612aa4f0aSMarcel Holtmann 
1527cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
1528cbed0ca1SJohan Hedberg 
1529fee746b0SMarcel Holtmann done:
1530cbed0ca1SJohan Hedberg 	hci_dev_put(hdev);
1531cbed0ca1SJohan Hedberg 	return err;
1532cbed0ca1SJohan Hedberg }
1533cbed0ca1SJohan Hedberg 
1534d7347f3cSJohan Hedberg /* This function requires the caller holds hdev->lock */
1535d7347f3cSJohan Hedberg static void hci_pend_le_actions_clear(struct hci_dev *hdev)
1536d7347f3cSJohan Hedberg {
1537d7347f3cSJohan Hedberg 	struct hci_conn_params *p;
1538d7347f3cSJohan Hedberg 
1539f161dd41SJohan Hedberg 	list_for_each_entry(p, &hdev->le_conn_params, list) {
1540f161dd41SJohan Hedberg 		if (p->conn) {
1541f161dd41SJohan Hedberg 			hci_conn_drop(p->conn);
1542f8aaf9b6SJohan Hedberg 			hci_conn_put(p->conn);
1543f161dd41SJohan Hedberg 			p->conn = NULL;
1544f161dd41SJohan Hedberg 		}
1545d7347f3cSJohan Hedberg 		list_del_init(&p->action);
1546f161dd41SJohan Hedberg 	}
1547d7347f3cSJohan Hedberg 
1548d7347f3cSJohan Hedberg 	BT_DBG("All LE pending actions cleared");
1549d7347f3cSJohan Hedberg }
1550d7347f3cSJohan Hedberg 
15511da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
15521da177e4SLinus Torvalds {
15531da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
15541da177e4SLinus Torvalds 
1555d24d8144SGabriele Mazzotta 	if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) &&
1556867146a0SLoic Poulain 	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
1557d24d8144SGabriele Mazzotta 	    test_bit(HCI_UP, &hdev->flags)) {
1558a44fecbdSTedd Ho-Jeong An 		/* Execute vendor specific shutdown routine */
1559a44fecbdSTedd Ho-Jeong An 		if (hdev->shutdown)
1560a44fecbdSTedd Ho-Jeong An 			hdev->shutdown(hdev);
1561a44fecbdSTedd Ho-Jeong An 	}
1562a44fecbdSTedd Ho-Jeong An 
156378c04c0bSVinicius Costa Gomes 	cancel_delayed_work(&hdev->power_off);
156478c04c0bSVinicius Costa Gomes 
15651da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
15661da177e4SLinus Torvalds 	hci_req_lock(hdev);
15671da177e4SLinus Torvalds 
15681da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
156965cc2b49SMarcel Holtmann 		cancel_delayed_work_sync(&hdev->cmd_timer);
15701da177e4SLinus Torvalds 		hci_req_unlock(hdev);
15711da177e4SLinus Torvalds 		return 0;
15721da177e4SLinus Torvalds 	}
15731da177e4SLinus Torvalds 
15743eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
15753eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
1576b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
15771da177e4SLinus Torvalds 
157816ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
1579e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
158016ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
1581a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_DISCOVERABLE);
1582a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
158316ab91abSJohan Hedberg 	}
158416ab91abSJohan Hedberg 
1585a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_SERVICE_CACHE))
15867d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
15877d78525dSJohan Hedberg 
15887ba8b4beSAndre Guedes 	cancel_delayed_work_sync(&hdev->le_scan_disable);
15892d28cfe7SJakub Pawlowski 	cancel_delayed_work_sync(&hdev->le_scan_restart);
15904518bb0fSJohan Hedberg 
1591d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_MGMT))
1592d6bfd59cSJohan Hedberg 		cancel_delayed_work_sync(&hdev->rpa_expired);
15937ba8b4beSAndre Guedes 
159476727c02SJohan Hedberg 	/* Avoid potential lockdep warnings from the *_flush() calls by
159576727c02SJohan Hedberg 	 * ensuring the workqueue is empty up front.
159676727c02SJohan Hedberg 	 */
159776727c02SJohan Hedberg 	drain_workqueue(hdev->workqueue);
159876727c02SJohan Hedberg 
159909fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
16001aeb9c65SJohan Hedberg 
16018f502f84SJohan Hedberg 	hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
16028f502f84SJohan Hedberg 
1603a69d8927SMarcel Holtmann 	if (!hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) {
16041aeb9c65SJohan Hedberg 		if (hdev->dev_type == HCI_BREDR)
16051aeb9c65SJohan Hedberg 			mgmt_powered(hdev, 0);
16061aeb9c65SJohan Hedberg 	}
16071aeb9c65SJohan Hedberg 
16081f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
1609d7347f3cSJohan Hedberg 	hci_pend_le_actions_clear(hdev);
1610f161dd41SJohan Hedberg 	hci_conn_hash_flush(hdev);
161109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
16121da177e4SLinus Torvalds 
161364dae967SMarcel Holtmann 	smp_unregister(hdev);
161464dae967SMarcel Holtmann 
16151da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
16161da177e4SLinus Torvalds 
16171da177e4SLinus Torvalds 	if (hdev->flush)
16181da177e4SLinus Torvalds 		hdev->flush(hdev);
16191da177e4SLinus Torvalds 
16201da177e4SLinus Torvalds 	/* Reset device */
16211da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
16221da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
1623d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_AUTO_OFF) &&
1624d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
1625a6c511c6SSzymon Janc 	    test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
16261da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
162701178cd4SJohan Hedberg 		__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
16281da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
16291da177e4SLinus Torvalds 	}
16301da177e4SLinus Torvalds 
1631c347b765SGustavo F. Padovan 	/* flush cmd  work */
1632c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
16331da177e4SLinus Torvalds 
16341da177e4SLinus Torvalds 	/* Drop queues */
16351da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
16361da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
16371da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
16381da177e4SLinus Torvalds 
16391da177e4SLinus Torvalds 	/* Drop last sent command */
16401da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
164165cc2b49SMarcel Holtmann 		cancel_delayed_work_sync(&hdev->cmd_timer);
16421da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
16431da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
16441da177e4SLinus Torvalds 	}
16451da177e4SLinus Torvalds 
16461da177e4SLinus Torvalds 	/* After this point our queues are empty
16471da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
16481da177e4SLinus Torvalds 	hdev->close(hdev);
16491da177e4SLinus Torvalds 
165035b973c9SJohan Hedberg 	/* Clear flags */
1651fee746b0SMarcel Holtmann 	hdev->flags &= BIT(HCI_RAW);
1652eacb44dfSMarcel Holtmann 	hci_dev_clear_volatile_flags(hdev);
165335b973c9SJohan Hedberg 
1654ced5c338SAndrei Emeltchenko 	/* Controller radio is available but is currently powered down */
1655536619e8SMarcel Holtmann 	hdev->amp_status = AMP_STATUS_POWERED_DOWN;
1656ced5c338SAndrei Emeltchenko 
1657e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
165809b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
16597a4cd51dSMarcel Holtmann 	bacpy(&hdev->random_addr, BDADDR_ANY);
1660e59fda8dSJohan Hedberg 
16611da177e4SLinus Torvalds 	hci_req_unlock(hdev);
16621da177e4SLinus Torvalds 
16631da177e4SLinus Torvalds 	hci_dev_put(hdev);
16641da177e4SLinus Torvalds 	return 0;
16651da177e4SLinus Torvalds }
16661da177e4SLinus Torvalds 
16671da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
16681da177e4SLinus Torvalds {
16691da177e4SLinus Torvalds 	struct hci_dev *hdev;
16701da177e4SLinus Torvalds 	int err;
16711da177e4SLinus Torvalds 
167270f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
167370f23020SAndrei Emeltchenko 	if (!hdev)
16741da177e4SLinus Torvalds 		return -ENODEV;
16758ee56540SMarcel Holtmann 
1676d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
16770736cfa8SMarcel Holtmann 		err = -EBUSY;
16780736cfa8SMarcel Holtmann 		goto done;
16790736cfa8SMarcel Holtmann 	}
16800736cfa8SMarcel Holtmann 
1681a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF))
16828ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
16838ee56540SMarcel Holtmann 
16841da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
16858ee56540SMarcel Holtmann 
16860736cfa8SMarcel Holtmann done:
16871da177e4SLinus Torvalds 	hci_dev_put(hdev);
16881da177e4SLinus Torvalds 	return err;
16891da177e4SLinus Torvalds }
16901da177e4SLinus Torvalds 
16915c912495SMarcel Holtmann static int hci_dev_do_reset(struct hci_dev *hdev)
16921da177e4SLinus Torvalds {
16935c912495SMarcel Holtmann 	int ret;
16941da177e4SLinus Torvalds 
16955c912495SMarcel Holtmann 	BT_DBG("%s %p", hdev->name, hdev);
16961da177e4SLinus Torvalds 
16971da177e4SLinus Torvalds 	hci_req_lock(hdev);
16981da177e4SLinus Torvalds 
16991da177e4SLinus Torvalds 	/* Drop queues */
17001da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
17011da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
17021da177e4SLinus Torvalds 
170376727c02SJohan Hedberg 	/* Avoid potential lockdep warnings from the *_flush() calls by
170476727c02SJohan Hedberg 	 * ensuring the workqueue is empty up front.
170576727c02SJohan Hedberg 	 */
170676727c02SJohan Hedberg 	drain_workqueue(hdev->workqueue);
170776727c02SJohan Hedberg 
170809fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
17091f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
17101da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
171109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
17121da177e4SLinus Torvalds 
17131da177e4SLinus Torvalds 	if (hdev->flush)
17141da177e4SLinus Torvalds 		hdev->flush(hdev);
17151da177e4SLinus Torvalds 
17161da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
17176ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
17181da177e4SLinus Torvalds 
171901178cd4SJohan Hedberg 	ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
17201da177e4SLinus Torvalds 
17211da177e4SLinus Torvalds 	hci_req_unlock(hdev);
17221da177e4SLinus Torvalds 	return ret;
17231da177e4SLinus Torvalds }
17241da177e4SLinus Torvalds 
17255c912495SMarcel Holtmann int hci_dev_reset(__u16 dev)
17265c912495SMarcel Holtmann {
17275c912495SMarcel Holtmann 	struct hci_dev *hdev;
17285c912495SMarcel Holtmann 	int err;
17295c912495SMarcel Holtmann 
17305c912495SMarcel Holtmann 	hdev = hci_dev_get(dev);
17315c912495SMarcel Holtmann 	if (!hdev)
17325c912495SMarcel Holtmann 		return -ENODEV;
17335c912495SMarcel Holtmann 
17345c912495SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
17355c912495SMarcel Holtmann 		err = -ENETDOWN;
17365c912495SMarcel Holtmann 		goto done;
17375c912495SMarcel Holtmann 	}
17385c912495SMarcel Holtmann 
1739d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
17405c912495SMarcel Holtmann 		err = -EBUSY;
17415c912495SMarcel Holtmann 		goto done;
17425c912495SMarcel Holtmann 	}
17435c912495SMarcel Holtmann 
1744d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
17455c912495SMarcel Holtmann 		err = -EOPNOTSUPP;
17465c912495SMarcel Holtmann 		goto done;
17475c912495SMarcel Holtmann 	}
17485c912495SMarcel Holtmann 
17495c912495SMarcel Holtmann 	err = hci_dev_do_reset(hdev);
17505c912495SMarcel Holtmann 
17515c912495SMarcel Holtmann done:
17525c912495SMarcel Holtmann 	hci_dev_put(hdev);
17535c912495SMarcel Holtmann 	return err;
17545c912495SMarcel Holtmann }
17555c912495SMarcel Holtmann 
17561da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
17571da177e4SLinus Torvalds {
17581da177e4SLinus Torvalds 	struct hci_dev *hdev;
17591da177e4SLinus Torvalds 	int ret = 0;
17601da177e4SLinus Torvalds 
176170f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
176270f23020SAndrei Emeltchenko 	if (!hdev)
17631da177e4SLinus Torvalds 		return -ENODEV;
17641da177e4SLinus Torvalds 
1765d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
17660736cfa8SMarcel Holtmann 		ret = -EBUSY;
17670736cfa8SMarcel Holtmann 		goto done;
17680736cfa8SMarcel Holtmann 	}
17690736cfa8SMarcel Holtmann 
1770d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
1771fee746b0SMarcel Holtmann 		ret = -EOPNOTSUPP;
1772fee746b0SMarcel Holtmann 		goto done;
1773fee746b0SMarcel Holtmann 	}
1774fee746b0SMarcel Holtmann 
17751da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
17761da177e4SLinus Torvalds 
17770736cfa8SMarcel Holtmann done:
17781da177e4SLinus Torvalds 	hci_dev_put(hdev);
17791da177e4SLinus Torvalds 	return ret;
17801da177e4SLinus Torvalds }
17811da177e4SLinus Torvalds 
1782123abc08SJohan Hedberg static void hci_update_scan_state(struct hci_dev *hdev, u8 scan)
1783123abc08SJohan Hedberg {
1784bc6d2d04SJohan Hedberg 	bool conn_changed, discov_changed;
1785123abc08SJohan Hedberg 
1786123abc08SJohan Hedberg 	BT_DBG("%s scan 0x%02x", hdev->name, scan);
1787123abc08SJohan Hedberg 
1788123abc08SJohan Hedberg 	if ((scan & SCAN_PAGE))
1789238be788SMarcel Holtmann 		conn_changed = !hci_dev_test_and_set_flag(hdev,
1790238be788SMarcel Holtmann 							  HCI_CONNECTABLE);
1791123abc08SJohan Hedberg 	else
1792a69d8927SMarcel Holtmann 		conn_changed = hci_dev_test_and_clear_flag(hdev,
1793a69d8927SMarcel Holtmann 							   HCI_CONNECTABLE);
1794123abc08SJohan Hedberg 
1795bc6d2d04SJohan Hedberg 	if ((scan & SCAN_INQUIRY)) {
1796238be788SMarcel Holtmann 		discov_changed = !hci_dev_test_and_set_flag(hdev,
1797238be788SMarcel Holtmann 							    HCI_DISCOVERABLE);
1798bc6d2d04SJohan Hedberg 	} else {
1799a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
1800a69d8927SMarcel Holtmann 		discov_changed = hci_dev_test_and_clear_flag(hdev,
1801a69d8927SMarcel Holtmann 							     HCI_DISCOVERABLE);
1802bc6d2d04SJohan Hedberg 	}
1803bc6d2d04SJohan Hedberg 
1804d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
1805123abc08SJohan Hedberg 		return;
1806123abc08SJohan Hedberg 
1807bc6d2d04SJohan Hedberg 	if (conn_changed || discov_changed) {
1808bc6d2d04SJohan Hedberg 		/* In case this was disabled through mgmt */
1809a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
1810bc6d2d04SJohan Hedberg 
1811d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_LE_ENABLED))
1812bc6d2d04SJohan Hedberg 			mgmt_update_adv_data(hdev);
1813bc6d2d04SJohan Hedberg 
1814123abc08SJohan Hedberg 		mgmt_new_settings(hdev);
1815123abc08SJohan Hedberg 	}
1816bc6d2d04SJohan Hedberg }
1817123abc08SJohan Hedberg 
18181da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
18191da177e4SLinus Torvalds {
18201da177e4SLinus Torvalds 	struct hci_dev *hdev;
18211da177e4SLinus Torvalds 	struct hci_dev_req dr;
18221da177e4SLinus Torvalds 	int err = 0;
18231da177e4SLinus Torvalds 
18241da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
18251da177e4SLinus Torvalds 		return -EFAULT;
18261da177e4SLinus Torvalds 
182770f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
182870f23020SAndrei Emeltchenko 	if (!hdev)
18291da177e4SLinus Torvalds 		return -ENODEV;
18301da177e4SLinus Torvalds 
1831d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
18320736cfa8SMarcel Holtmann 		err = -EBUSY;
18330736cfa8SMarcel Holtmann 		goto done;
18340736cfa8SMarcel Holtmann 	}
18350736cfa8SMarcel Holtmann 
1836d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
1837fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
1838fee746b0SMarcel Holtmann 		goto done;
1839fee746b0SMarcel Holtmann 	}
1840fee746b0SMarcel Holtmann 
18415b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
18425b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
18435b69bef5SMarcel Holtmann 		goto done;
18445b69bef5SMarcel Holtmann 	}
18455b69bef5SMarcel Holtmann 
1846d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
184756f87901SJohan Hedberg 		err = -EOPNOTSUPP;
184856f87901SJohan Hedberg 		goto done;
184956f87901SJohan Hedberg 	}
185056f87901SJohan Hedberg 
18511da177e4SLinus Torvalds 	switch (cmd) {
18521da177e4SLinus Torvalds 	case HCISETAUTH:
185301178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
18545f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
18551da177e4SLinus Torvalds 		break;
18561da177e4SLinus Torvalds 
18571da177e4SLinus Torvalds 	case HCISETENCRYPT:
18581da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
18591da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
18601da177e4SLinus Torvalds 			break;
18611da177e4SLinus Torvalds 		}
18621da177e4SLinus Torvalds 
18631da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
18641da177e4SLinus Torvalds 			/* Auth must be enabled first */
186501178cd4SJohan Hedberg 			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
18665f246e89SAndrei Emeltchenko 					   HCI_INIT_TIMEOUT);
18671da177e4SLinus Torvalds 			if (err)
18681da177e4SLinus Torvalds 				break;
18691da177e4SLinus Torvalds 		}
18701da177e4SLinus Torvalds 
187101178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
18725f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
18731da177e4SLinus Torvalds 		break;
18741da177e4SLinus Torvalds 
18751da177e4SLinus Torvalds 	case HCISETSCAN:
187601178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
18775f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
187891a668b0SJohan Hedberg 
1879bc6d2d04SJohan Hedberg 		/* Ensure that the connectable and discoverable states
1880bc6d2d04SJohan Hedberg 		 * get correctly modified as this was a non-mgmt change.
188191a668b0SJohan Hedberg 		 */
1882123abc08SJohan Hedberg 		if (!err)
1883123abc08SJohan Hedberg 			hci_update_scan_state(hdev, dr.dev_opt);
18841da177e4SLinus Torvalds 		break;
18851da177e4SLinus Torvalds 
18861da177e4SLinus Torvalds 	case HCISETLINKPOL:
188701178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
18885f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
18891da177e4SLinus Torvalds 		break;
18901da177e4SLinus Torvalds 
18911da177e4SLinus Torvalds 	case HCISETLINKMODE:
1892e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
1893e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
1894e4e8e37cSMarcel Holtmann 		break;
1895e4e8e37cSMarcel Holtmann 
1896e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
1897e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
18981da177e4SLinus Torvalds 		break;
18991da177e4SLinus Torvalds 
19001da177e4SLinus Torvalds 	case HCISETACLMTU:
19011da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
19021da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
19031da177e4SLinus Torvalds 		break;
19041da177e4SLinus Torvalds 
19051da177e4SLinus Torvalds 	case HCISETSCOMTU:
19061da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
19071da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
19081da177e4SLinus Torvalds 		break;
19091da177e4SLinus Torvalds 
19101da177e4SLinus Torvalds 	default:
19111da177e4SLinus Torvalds 		err = -EINVAL;
19121da177e4SLinus Torvalds 		break;
19131da177e4SLinus Torvalds 	}
1914e4e8e37cSMarcel Holtmann 
19150736cfa8SMarcel Holtmann done:
19161da177e4SLinus Torvalds 	hci_dev_put(hdev);
19171da177e4SLinus Torvalds 	return err;
19181da177e4SLinus Torvalds }
19191da177e4SLinus Torvalds 
19201da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
19211da177e4SLinus Torvalds {
19228035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
19231da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
19241da177e4SLinus Torvalds 	struct hci_dev_req *dr;
19251da177e4SLinus Torvalds 	int n = 0, size, err;
19261da177e4SLinus Torvalds 	__u16 dev_num;
19271da177e4SLinus Torvalds 
19281da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
19291da177e4SLinus Torvalds 		return -EFAULT;
19301da177e4SLinus Torvalds 
19311da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
19321da177e4SLinus Torvalds 		return -EINVAL;
19331da177e4SLinus Torvalds 
19341da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
19351da177e4SLinus Torvalds 
193670f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
193770f23020SAndrei Emeltchenko 	if (!dl)
19381da177e4SLinus Torvalds 		return -ENOMEM;
19391da177e4SLinus Torvalds 
19401da177e4SLinus Torvalds 	dr = dl->dev_req;
19411da177e4SLinus Torvalds 
1942f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
19438035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
19442e84d8dbSMarcel Holtmann 		unsigned long flags = hdev->flags;
1945c542a06cSJohan Hedberg 
19462e84d8dbSMarcel Holtmann 		/* When the auto-off is configured it means the transport
19472e84d8dbSMarcel Holtmann 		 * is running, but in that case still indicate that the
19482e84d8dbSMarcel Holtmann 		 * device is actually down.
19492e84d8dbSMarcel Holtmann 		 */
1950d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_AUTO_OFF))
19512e84d8dbSMarcel Holtmann 			flags &= ~BIT(HCI_UP);
1952c542a06cSJohan Hedberg 
19531da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
19542e84d8dbSMarcel Holtmann 		(dr + n)->dev_opt = flags;
1955c542a06cSJohan Hedberg 
19561da177e4SLinus Torvalds 		if (++n >= dev_num)
19571da177e4SLinus Torvalds 			break;
19581da177e4SLinus Torvalds 	}
1959f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
19601da177e4SLinus Torvalds 
19611da177e4SLinus Torvalds 	dl->dev_num = n;
19621da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
19631da177e4SLinus Torvalds 
19641da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
19651da177e4SLinus Torvalds 	kfree(dl);
19661da177e4SLinus Torvalds 
19671da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
19681da177e4SLinus Torvalds }
19691da177e4SLinus Torvalds 
19701da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
19711da177e4SLinus Torvalds {
19721da177e4SLinus Torvalds 	struct hci_dev *hdev;
19731da177e4SLinus Torvalds 	struct hci_dev_info di;
19742e84d8dbSMarcel Holtmann 	unsigned long flags;
19751da177e4SLinus Torvalds 	int err = 0;
19761da177e4SLinus Torvalds 
19771da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
19781da177e4SLinus Torvalds 		return -EFAULT;
19791da177e4SLinus Torvalds 
198070f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
198170f23020SAndrei Emeltchenko 	if (!hdev)
19821da177e4SLinus Torvalds 		return -ENODEV;
19831da177e4SLinus Torvalds 
19842e84d8dbSMarcel Holtmann 	/* When the auto-off is configured it means the transport
19852e84d8dbSMarcel Holtmann 	 * is running, but in that case still indicate that the
19862e84d8dbSMarcel Holtmann 	 * device is actually down.
19872e84d8dbSMarcel Holtmann 	 */
1988d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_AUTO_OFF))
19892e84d8dbSMarcel Holtmann 		flags = hdev->flags & ~BIT(HCI_UP);
19902e84d8dbSMarcel Holtmann 	else
19912e84d8dbSMarcel Holtmann 		flags = hdev->flags;
1992c542a06cSJohan Hedberg 
19931da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
19941da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
199560f2a3edSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4);
19962e84d8dbSMarcel Holtmann 	di.flags    = flags;
19971da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
1998572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
19991da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
20001da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
20011da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
20021da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
2003572c7f84SJohan Hedberg 	} else {
2004572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
2005572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
2006572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
2007572c7f84SJohan Hedberg 		di.sco_pkts = 0;
2008572c7f84SJohan Hedberg 	}
20091da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
20101da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
20111da177e4SLinus Torvalds 
20121da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
20131da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
20141da177e4SLinus Torvalds 
20151da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
20161da177e4SLinus Torvalds 		err = -EFAULT;
20171da177e4SLinus Torvalds 
20181da177e4SLinus Torvalds 	hci_dev_put(hdev);
20191da177e4SLinus Torvalds 
20201da177e4SLinus Torvalds 	return err;
20211da177e4SLinus Torvalds }
20221da177e4SLinus Torvalds 
20231da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
20241da177e4SLinus Torvalds 
2025611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
2026611b30f7SMarcel Holtmann {
2027611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
2028611b30f7SMarcel Holtmann 
2029611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
2030611b30f7SMarcel Holtmann 
2031d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
20320736cfa8SMarcel Holtmann 		return -EBUSY;
20330736cfa8SMarcel Holtmann 
20345e130367SJohan Hedberg 	if (blocked) {
2035a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RFKILLED);
2036d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
2037d7a5a11dSMarcel Holtmann 		    !hci_dev_test_flag(hdev, HCI_CONFIG))
2038611b30f7SMarcel Holtmann 			hci_dev_do_close(hdev);
20395e130367SJohan Hedberg 	} else {
2040a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_RFKILLED);
20415e130367SJohan Hedberg 	}
2042611b30f7SMarcel Holtmann 
2043611b30f7SMarcel Holtmann 	return 0;
2044611b30f7SMarcel Holtmann }
2045611b30f7SMarcel Holtmann 
2046611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
2047611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
2048611b30f7SMarcel Holtmann };
2049611b30f7SMarcel Holtmann 
2050ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
2051ab81cbf9SJohan Hedberg {
2052ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
205396570ffcSJohan Hedberg 	int err;
2054ab81cbf9SJohan Hedberg 
2055ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
2056ab81cbf9SJohan Hedberg 
2057cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
205896570ffcSJohan Hedberg 	if (err < 0) {
20593ad67582SJaganath Kanakkassery 		hci_dev_lock(hdev);
206096570ffcSJohan Hedberg 		mgmt_set_powered_failed(hdev, err);
20613ad67582SJaganath Kanakkassery 		hci_dev_unlock(hdev);
2062ab81cbf9SJohan Hedberg 		return;
206396570ffcSJohan Hedberg 	}
2064ab81cbf9SJohan Hedberg 
2065a5c8f270SMarcel Holtmann 	/* During the HCI setup phase, a few error conditions are
2066a5c8f270SMarcel Holtmann 	 * ignored and they need to be checked now. If they are still
2067a5c8f270SMarcel Holtmann 	 * valid, it is important to turn the device back off.
2068a5c8f270SMarcel Holtmann 	 */
2069d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_RFKILLED) ||
2070d7a5a11dSMarcel Holtmann 	    hci_dev_test_flag(hdev, HCI_UNCONFIGURED) ||
2071a5c8f270SMarcel Holtmann 	    (hdev->dev_type == HCI_BREDR &&
2072a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
2073a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->static_addr, BDADDR_ANY))) {
2074a358dc11SMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_AUTO_OFF);
2075bf543036SJohan Hedberg 		hci_dev_do_close(hdev);
2076d7a5a11dSMarcel Holtmann 	} else if (hci_dev_test_flag(hdev, HCI_AUTO_OFF)) {
207719202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
207819202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
2079bf543036SJohan Hedberg 	}
2080ab81cbf9SJohan Hedberg 
2081a69d8927SMarcel Holtmann 	if (hci_dev_test_and_clear_flag(hdev, HCI_SETUP)) {
20824a964404SMarcel Holtmann 		/* For unconfigured devices, set the HCI_RAW flag
20834a964404SMarcel Holtmann 		 * so that userspace can easily identify them.
20844a964404SMarcel Holtmann 		 */
2085d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
20864a964404SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
20870602a8adSMarcel Holtmann 
20880602a8adSMarcel Holtmann 		/* For fully configured devices, this will send
20890602a8adSMarcel Holtmann 		 * the Index Added event. For unconfigured devices,
20900602a8adSMarcel Holtmann 		 * it will send Unconfigued Index Added event.
20910602a8adSMarcel Holtmann 		 *
20920602a8adSMarcel Holtmann 		 * Devices with HCI_QUIRK_RAW_DEVICE are ignored
20930602a8adSMarcel Holtmann 		 * and no event will be send.
20940602a8adSMarcel Holtmann 		 */
2095744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
2096a69d8927SMarcel Holtmann 	} else if (hci_dev_test_and_clear_flag(hdev, HCI_CONFIG)) {
20975ea234d3SMarcel Holtmann 		/* When the controller is now configured, then it
20985ea234d3SMarcel Holtmann 		 * is important to clear the HCI_RAW flag.
20995ea234d3SMarcel Holtmann 		 */
2100d7a5a11dSMarcel Holtmann 		if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
21015ea234d3SMarcel Holtmann 			clear_bit(HCI_RAW, &hdev->flags);
21025ea234d3SMarcel Holtmann 
2103d603b76bSMarcel Holtmann 		/* Powering on the controller with HCI_CONFIG set only
2104d603b76bSMarcel Holtmann 		 * happens with the transition from unconfigured to
2105d603b76bSMarcel Holtmann 		 * configured. This will send the Index Added event.
2106d603b76bSMarcel Holtmann 		 */
2107d603b76bSMarcel Holtmann 		mgmt_index_added(hdev);
2108ab81cbf9SJohan Hedberg 	}
2109ab81cbf9SJohan Hedberg }
2110ab81cbf9SJohan Hedberg 
2111ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
2112ab81cbf9SJohan Hedberg {
21133243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
21143243553fSJohan Hedberg 					    power_off.work);
2115ab81cbf9SJohan Hedberg 
2116ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
2117ab81cbf9SJohan Hedberg 
21188ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
2119ab81cbf9SJohan Hedberg }
2120ab81cbf9SJohan Hedberg 
2121c7741d16SMarcel Holtmann static void hci_error_reset(struct work_struct *work)
2122c7741d16SMarcel Holtmann {
2123c7741d16SMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, error_reset);
2124c7741d16SMarcel Holtmann 
2125c7741d16SMarcel Holtmann 	BT_DBG("%s", hdev->name);
2126c7741d16SMarcel Holtmann 
2127c7741d16SMarcel Holtmann 	if (hdev->hw_error)
2128c7741d16SMarcel Holtmann 		hdev->hw_error(hdev, hdev->hw_error_code);
2129c7741d16SMarcel Holtmann 	else
2130c7741d16SMarcel Holtmann 		BT_ERR("%s hardware error 0x%2.2x", hdev->name,
2131c7741d16SMarcel Holtmann 		       hdev->hw_error_code);
2132c7741d16SMarcel Holtmann 
2133c7741d16SMarcel Holtmann 	if (hci_dev_do_close(hdev))
2134c7741d16SMarcel Holtmann 		return;
2135c7741d16SMarcel Holtmann 
2136c7741d16SMarcel Holtmann 	hci_dev_do_open(hdev);
2137c7741d16SMarcel Holtmann }
2138c7741d16SMarcel Holtmann 
213916ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
214016ab91abSJohan Hedberg {
214116ab91abSJohan Hedberg 	struct hci_dev *hdev;
214216ab91abSJohan Hedberg 
214316ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
214416ab91abSJohan Hedberg 
214516ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
214616ab91abSJohan Hedberg 
2147d1967ff8SMarcel Holtmann 	mgmt_discoverable_timeout(hdev);
214816ab91abSJohan Hedberg }
214916ab91abSJohan Hedberg 
215035f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev)
21512aeb9a1aSJohan Hedberg {
21524821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
21532aeb9a1aSJohan Hedberg 
21544821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
21554821002cSJohan Hedberg 		list_del(&uuid->list);
21562aeb9a1aSJohan Hedberg 		kfree(uuid);
21572aeb9a1aSJohan Hedberg 	}
21582aeb9a1aSJohan Hedberg }
21592aeb9a1aSJohan Hedberg 
216035f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev)
216155ed8ca1SJohan Hedberg {
216255ed8ca1SJohan Hedberg 	struct link_key *key;
216355ed8ca1SJohan Hedberg 
21640378b597SJohan Hedberg 	list_for_each_entry_rcu(key, &hdev->link_keys, list) {
21650378b597SJohan Hedberg 		list_del_rcu(&key->list);
21660378b597SJohan Hedberg 		kfree_rcu(key, rcu);
216755ed8ca1SJohan Hedberg 	}
216855ed8ca1SJohan Hedberg }
216955ed8ca1SJohan Hedberg 
217035f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev)
2171b899efafSVinicius Costa Gomes {
2172970d0f1bSJohan Hedberg 	struct smp_ltk *k;
2173b899efafSVinicius Costa Gomes 
2174970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
2175970d0f1bSJohan Hedberg 		list_del_rcu(&k->list);
2176970d0f1bSJohan Hedberg 		kfree_rcu(k, rcu);
2177b899efafSVinicius Costa Gomes 	}
2178b899efafSVinicius Costa Gomes }
2179b899efafSVinicius Costa Gomes 
2180970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev)
2181970c4e46SJohan Hedberg {
2182adae20cbSJohan Hedberg 	struct smp_irk *k;
2183970c4e46SJohan Hedberg 
2184adae20cbSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) {
2185adae20cbSJohan Hedberg 		list_del_rcu(&k->list);
2186adae20cbSJohan Hedberg 		kfree_rcu(k, rcu);
2187970c4e46SJohan Hedberg 	}
2188970c4e46SJohan Hedberg }
2189970c4e46SJohan Hedberg 
219055ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
219155ed8ca1SJohan Hedberg {
219255ed8ca1SJohan Hedberg 	struct link_key *k;
219355ed8ca1SJohan Hedberg 
21940378b597SJohan Hedberg 	rcu_read_lock();
21950378b597SJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->link_keys, list) {
21960378b597SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0) {
21970378b597SJohan Hedberg 			rcu_read_unlock();
219855ed8ca1SJohan Hedberg 			return k;
21990378b597SJohan Hedberg 		}
22000378b597SJohan Hedberg 	}
22010378b597SJohan Hedberg 	rcu_read_unlock();
220255ed8ca1SJohan Hedberg 
220355ed8ca1SJohan Hedberg 	return NULL;
220455ed8ca1SJohan Hedberg }
220555ed8ca1SJohan Hedberg 
2206745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
2207d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
2208d25e28abSJohan Hedberg {
2209d25e28abSJohan Hedberg 	/* Legacy key */
2210d25e28abSJohan Hedberg 	if (key_type < 0x03)
2211745c0ce3SVishal Agarwal 		return true;
2212d25e28abSJohan Hedberg 
2213d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
2214d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
2215745c0ce3SVishal Agarwal 		return false;
2216d25e28abSJohan Hedberg 
2217d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
2218d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
2219745c0ce3SVishal Agarwal 		return false;
2220d25e28abSJohan Hedberg 
2221d25e28abSJohan Hedberg 	/* Security mode 3 case */
2222d25e28abSJohan Hedberg 	if (!conn)
2223745c0ce3SVishal Agarwal 		return true;
2224d25e28abSJohan Hedberg 
2225e3befab9SJohan Hedberg 	/* BR/EDR key derived using SC from an LE link */
2226e3befab9SJohan Hedberg 	if (conn->type == LE_LINK)
2227e3befab9SJohan Hedberg 		return true;
2228e3befab9SJohan Hedberg 
2229d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
2230d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
2231745c0ce3SVishal Agarwal 		return true;
2232d25e28abSJohan Hedberg 
2233d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
2234d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
2235745c0ce3SVishal Agarwal 		return true;
2236d25e28abSJohan Hedberg 
2237d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
2238d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
2239745c0ce3SVishal Agarwal 		return true;
2240d25e28abSJohan Hedberg 
2241d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
2242d25e28abSJohan Hedberg 	 * persistently */
2243745c0ce3SVishal Agarwal 	return false;
2244d25e28abSJohan Hedberg }
2245d25e28abSJohan Hedberg 
2246e804d25dSJohan Hedberg static u8 ltk_role(u8 type)
224798a0b845SJohan Hedberg {
2248e804d25dSJohan Hedberg 	if (type == SMP_LTK)
2249e804d25dSJohan Hedberg 		return HCI_ROLE_MASTER;
225098a0b845SJohan Hedberg 
2251e804d25dSJohan Hedberg 	return HCI_ROLE_SLAVE;
225298a0b845SJohan Hedberg }
225398a0b845SJohan Hedberg 
2254f3a73d97SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
2255e804d25dSJohan Hedberg 			     u8 addr_type, u8 role)
225675d262c2SVinicius Costa Gomes {
2257c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
225875d262c2SVinicius Costa Gomes 
2259970d0f1bSJohan Hedberg 	rcu_read_lock();
2260970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
22615378bc56SJohan Hedberg 		if (addr_type != k->bdaddr_type || bacmp(bdaddr, &k->bdaddr))
22625378bc56SJohan Hedberg 			continue;
22635378bc56SJohan Hedberg 
2264923e2414SJohan Hedberg 		if (smp_ltk_is_sc(k) || ltk_role(k->type) == role) {
2265970d0f1bSJohan Hedberg 			rcu_read_unlock();
226675d262c2SVinicius Costa Gomes 			return k;
2267970d0f1bSJohan Hedberg 		}
2268970d0f1bSJohan Hedberg 	}
2269970d0f1bSJohan Hedberg 	rcu_read_unlock();
227075d262c2SVinicius Costa Gomes 
227175d262c2SVinicius Costa Gomes 	return NULL;
227275d262c2SVinicius Costa Gomes }
227375d262c2SVinicius Costa Gomes 
2274970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa)
2275970c4e46SJohan Hedberg {
2276970c4e46SJohan Hedberg 	struct smp_irk *irk;
2277970c4e46SJohan Hedberg 
2278adae20cbSJohan Hedberg 	rcu_read_lock();
2279adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
2280adae20cbSJohan Hedberg 		if (!bacmp(&irk->rpa, rpa)) {
2281adae20cbSJohan Hedberg 			rcu_read_unlock();
2282970c4e46SJohan Hedberg 			return irk;
2283970c4e46SJohan Hedberg 		}
2284adae20cbSJohan Hedberg 	}
2285970c4e46SJohan Hedberg 
2286adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
2287defce9e8SJohan Hedberg 		if (smp_irk_matches(hdev, irk->val, rpa)) {
2288970c4e46SJohan Hedberg 			bacpy(&irk->rpa, rpa);
2289adae20cbSJohan Hedberg 			rcu_read_unlock();
2290970c4e46SJohan Hedberg 			return irk;
2291970c4e46SJohan Hedberg 		}
2292970c4e46SJohan Hedberg 	}
2293adae20cbSJohan Hedberg 	rcu_read_unlock();
2294970c4e46SJohan Hedberg 
2295970c4e46SJohan Hedberg 	return NULL;
2296970c4e46SJohan Hedberg }
2297970c4e46SJohan Hedberg 
2298970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
2299970c4e46SJohan Hedberg 				     u8 addr_type)
2300970c4e46SJohan Hedberg {
2301970c4e46SJohan Hedberg 	struct smp_irk *irk;
2302970c4e46SJohan Hedberg 
23036cfc9988SJohan Hedberg 	/* Identity Address must be public or static random */
23046cfc9988SJohan Hedberg 	if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0)
23056cfc9988SJohan Hedberg 		return NULL;
23066cfc9988SJohan Hedberg 
2307adae20cbSJohan Hedberg 	rcu_read_lock();
2308adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
2309970c4e46SJohan Hedberg 		if (addr_type == irk->addr_type &&
2310adae20cbSJohan Hedberg 		    bacmp(bdaddr, &irk->bdaddr) == 0) {
2311adae20cbSJohan Hedberg 			rcu_read_unlock();
2312970c4e46SJohan Hedberg 			return irk;
2313970c4e46SJohan Hedberg 		}
2314adae20cbSJohan Hedberg 	}
2315adae20cbSJohan Hedberg 	rcu_read_unlock();
2316970c4e46SJohan Hedberg 
2317970c4e46SJohan Hedberg 	return NULL;
2318970c4e46SJohan Hedberg }
2319970c4e46SJohan Hedberg 
2320567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn,
23217652ff6aSJohan Hedberg 				  bdaddr_t *bdaddr, u8 *val, u8 type,
23227652ff6aSJohan Hedberg 				  u8 pin_len, bool *persistent)
232355ed8ca1SJohan Hedberg {
232455ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
2325745c0ce3SVishal Agarwal 	u8 old_key_type;
232655ed8ca1SJohan Hedberg 
232755ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
232855ed8ca1SJohan Hedberg 	if (old_key) {
232955ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
233055ed8ca1SJohan Hedberg 		key = old_key;
233155ed8ca1SJohan Hedberg 	} else {
233212adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
23330a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
233455ed8ca1SJohan Hedberg 		if (!key)
2335567fa2aaSJohan Hedberg 			return NULL;
23360378b597SJohan Hedberg 		list_add_rcu(&key->list, &hdev->link_keys);
233755ed8ca1SJohan Hedberg 	}
233855ed8ca1SJohan Hedberg 
23396ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
234055ed8ca1SJohan Hedberg 
2341d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
2342d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
2343d25e28abSJohan Hedberg 	 * previous key */
2344d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
2345a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
2346d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
2347655fe6ecSJohan Hedberg 		if (conn)
2348655fe6ecSJohan Hedberg 			conn->key_type = type;
2349655fe6ecSJohan Hedberg 	}
2350d25e28abSJohan Hedberg 
235155ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
23529b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
235355ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
235455ed8ca1SJohan Hedberg 
2355b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
235655ed8ca1SJohan Hedberg 		key->type = old_key_type;
23574748fed2SJohan Hedberg 	else
23584748fed2SJohan Hedberg 		key->type = type;
23594748fed2SJohan Hedberg 
23607652ff6aSJohan Hedberg 	if (persistent)
23617652ff6aSJohan Hedberg 		*persistent = hci_persistent_key(hdev, conn, type,
23627652ff6aSJohan Hedberg 						 old_key_type);
23634df378a1SJohan Hedberg 
2364567fa2aaSJohan Hedberg 	return key;
236555ed8ca1SJohan Hedberg }
236655ed8ca1SJohan Hedberg 
2367ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
236835d70271SJohan Hedberg 			    u8 addr_type, u8 type, u8 authenticated,
2369fe39c7b2SMarcel Holtmann 			    u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand)
237075d262c2SVinicius Costa Gomes {
2371c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
2372e804d25dSJohan Hedberg 	u8 role = ltk_role(type);
237375d262c2SVinicius Costa Gomes 
2374f3a73d97SJohan Hedberg 	old_key = hci_find_ltk(hdev, bdaddr, addr_type, role);
2375c9839a11SVinicius Costa Gomes 	if (old_key)
237675d262c2SVinicius Costa Gomes 		key = old_key;
2377c9839a11SVinicius Costa Gomes 	else {
23780a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
237975d262c2SVinicius Costa Gomes 		if (!key)
2380ca9142b8SJohan Hedberg 			return NULL;
2381970d0f1bSJohan Hedberg 		list_add_rcu(&key->list, &hdev->long_term_keys);
238275d262c2SVinicius Costa Gomes 	}
238375d262c2SVinicius Costa Gomes 
238475d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
2385c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
2386c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
2387c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
2388c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
2389fe39c7b2SMarcel Holtmann 	key->rand = rand;
2390c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
2391c9839a11SVinicius Costa Gomes 	key->type = type;
239275d262c2SVinicius Costa Gomes 
2393ca9142b8SJohan Hedberg 	return key;
239475d262c2SVinicius Costa Gomes }
239575d262c2SVinicius Costa Gomes 
2396ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr,
2397ca9142b8SJohan Hedberg 			    u8 addr_type, u8 val[16], bdaddr_t *rpa)
2398970c4e46SJohan Hedberg {
2399970c4e46SJohan Hedberg 	struct smp_irk *irk;
2400970c4e46SJohan Hedberg 
2401970c4e46SJohan Hedberg 	irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type);
2402970c4e46SJohan Hedberg 	if (!irk) {
2403970c4e46SJohan Hedberg 		irk = kzalloc(sizeof(*irk), GFP_KERNEL);
2404970c4e46SJohan Hedberg 		if (!irk)
2405ca9142b8SJohan Hedberg 			return NULL;
2406970c4e46SJohan Hedberg 
2407970c4e46SJohan Hedberg 		bacpy(&irk->bdaddr, bdaddr);
2408970c4e46SJohan Hedberg 		irk->addr_type = addr_type;
2409970c4e46SJohan Hedberg 
2410adae20cbSJohan Hedberg 		list_add_rcu(&irk->list, &hdev->identity_resolving_keys);
2411970c4e46SJohan Hedberg 	}
2412970c4e46SJohan Hedberg 
2413970c4e46SJohan Hedberg 	memcpy(irk->val, val, 16);
2414970c4e46SJohan Hedberg 	bacpy(&irk->rpa, rpa);
2415970c4e46SJohan Hedberg 
2416ca9142b8SJohan Hedberg 	return irk;
2417970c4e46SJohan Hedberg }
2418970c4e46SJohan Hedberg 
241955ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
242055ed8ca1SJohan Hedberg {
242155ed8ca1SJohan Hedberg 	struct link_key *key;
242255ed8ca1SJohan Hedberg 
242355ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
242455ed8ca1SJohan Hedberg 	if (!key)
242555ed8ca1SJohan Hedberg 		return -ENOENT;
242655ed8ca1SJohan Hedberg 
24276ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
242855ed8ca1SJohan Hedberg 
24290378b597SJohan Hedberg 	list_del_rcu(&key->list);
24300378b597SJohan Hedberg 	kfree_rcu(key, rcu);
243155ed8ca1SJohan Hedberg 
243255ed8ca1SJohan Hedberg 	return 0;
243355ed8ca1SJohan Hedberg }
243455ed8ca1SJohan Hedberg 
2435e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type)
2436b899efafSVinicius Costa Gomes {
2437970d0f1bSJohan Hedberg 	struct smp_ltk *k;
2438c51ffa0bSJohan Hedberg 	int removed = 0;
2439b899efafSVinicius Costa Gomes 
2440970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
2441e0b2b27eSJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type)
2442b899efafSVinicius Costa Gomes 			continue;
2443b899efafSVinicius Costa Gomes 
24446ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
2445b899efafSVinicius Costa Gomes 
2446970d0f1bSJohan Hedberg 		list_del_rcu(&k->list);
2447970d0f1bSJohan Hedberg 		kfree_rcu(k, rcu);
2448c51ffa0bSJohan Hedberg 		removed++;
2449b899efafSVinicius Costa Gomes 	}
2450b899efafSVinicius Costa Gomes 
2451c51ffa0bSJohan Hedberg 	return removed ? 0 : -ENOENT;
2452b899efafSVinicius Costa Gomes }
2453b899efafSVinicius Costa Gomes 
2454a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type)
2455a7ec7338SJohan Hedberg {
2456adae20cbSJohan Hedberg 	struct smp_irk *k;
2457a7ec7338SJohan Hedberg 
2458adae20cbSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) {
2459a7ec7338SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type)
2460a7ec7338SJohan Hedberg 			continue;
2461a7ec7338SJohan Hedberg 
2462a7ec7338SJohan Hedberg 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
2463a7ec7338SJohan Hedberg 
2464adae20cbSJohan Hedberg 		list_del_rcu(&k->list);
2465adae20cbSJohan Hedberg 		kfree_rcu(k, rcu);
2466a7ec7338SJohan Hedberg 	}
2467a7ec7338SJohan Hedberg }
2468a7ec7338SJohan Hedberg 
246955e76b38SJohan Hedberg bool hci_bdaddr_is_paired(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
247055e76b38SJohan Hedberg {
247155e76b38SJohan Hedberg 	struct smp_ltk *k;
24724ba9faf3SJohan Hedberg 	struct smp_irk *irk;
247355e76b38SJohan Hedberg 	u8 addr_type;
247455e76b38SJohan Hedberg 
247555e76b38SJohan Hedberg 	if (type == BDADDR_BREDR) {
247655e76b38SJohan Hedberg 		if (hci_find_link_key(hdev, bdaddr))
247755e76b38SJohan Hedberg 			return true;
247855e76b38SJohan Hedberg 		return false;
247955e76b38SJohan Hedberg 	}
248055e76b38SJohan Hedberg 
248155e76b38SJohan Hedberg 	/* Convert to HCI addr type which struct smp_ltk uses */
248255e76b38SJohan Hedberg 	if (type == BDADDR_LE_PUBLIC)
248355e76b38SJohan Hedberg 		addr_type = ADDR_LE_DEV_PUBLIC;
248455e76b38SJohan Hedberg 	else
248555e76b38SJohan Hedberg 		addr_type = ADDR_LE_DEV_RANDOM;
248655e76b38SJohan Hedberg 
24874ba9faf3SJohan Hedberg 	irk = hci_get_irk(hdev, bdaddr, addr_type);
24884ba9faf3SJohan Hedberg 	if (irk) {
24894ba9faf3SJohan Hedberg 		bdaddr = &irk->bdaddr;
24904ba9faf3SJohan Hedberg 		addr_type = irk->addr_type;
24914ba9faf3SJohan Hedberg 	}
24924ba9faf3SJohan Hedberg 
249355e76b38SJohan Hedberg 	rcu_read_lock();
249455e76b38SJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
249587c8b28dSJohan Hedberg 		if (k->bdaddr_type == addr_type && !bacmp(bdaddr, &k->bdaddr)) {
249687c8b28dSJohan Hedberg 			rcu_read_unlock();
249755e76b38SJohan Hedberg 			return true;
249855e76b38SJohan Hedberg 		}
249987c8b28dSJohan Hedberg 	}
250055e76b38SJohan Hedberg 	rcu_read_unlock();
250155e76b38SJohan Hedberg 
250255e76b38SJohan Hedberg 	return false;
250355e76b38SJohan Hedberg }
250455e76b38SJohan Hedberg 
25056bd32326SVille Tervo /* HCI command timer function */
250665cc2b49SMarcel Holtmann static void hci_cmd_timeout(struct work_struct *work)
25076bd32326SVille Tervo {
250865cc2b49SMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev,
250965cc2b49SMarcel Holtmann 					    cmd_timer.work);
25106bd32326SVille Tervo 
2511bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
2512bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
2513bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
2514bda4f23aSAndrei Emeltchenko 
2515bda4f23aSAndrei Emeltchenko 		BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode);
2516bda4f23aSAndrei Emeltchenko 	} else {
25176bd32326SVille Tervo 		BT_ERR("%s command tx timeout", hdev->name);
2518bda4f23aSAndrei Emeltchenko 	}
2519bda4f23aSAndrei Emeltchenko 
25206bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
2521c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
25226bd32326SVille Tervo }
25236bd32326SVille Tervo 
25242763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
25256928a924SJohan Hedberg 					  bdaddr_t *bdaddr, u8 bdaddr_type)
25262763eda6SSzymon Janc {
25272763eda6SSzymon Janc 	struct oob_data *data;
25282763eda6SSzymon Janc 
25296928a924SJohan Hedberg 	list_for_each_entry(data, &hdev->remote_oob_data, list) {
25306928a924SJohan Hedberg 		if (bacmp(bdaddr, &data->bdaddr) != 0)
25316928a924SJohan Hedberg 			continue;
25326928a924SJohan Hedberg 		if (data->bdaddr_type != bdaddr_type)
25336928a924SJohan Hedberg 			continue;
25342763eda6SSzymon Janc 		return data;
25356928a924SJohan Hedberg 	}
25362763eda6SSzymon Janc 
25372763eda6SSzymon Janc 	return NULL;
25382763eda6SSzymon Janc }
25392763eda6SSzymon Janc 
25406928a924SJohan Hedberg int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
25416928a924SJohan Hedberg 			       u8 bdaddr_type)
25422763eda6SSzymon Janc {
25432763eda6SSzymon Janc 	struct oob_data *data;
25442763eda6SSzymon Janc 
25456928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
25462763eda6SSzymon Janc 	if (!data)
25472763eda6SSzymon Janc 		return -ENOENT;
25482763eda6SSzymon Janc 
25496928a924SJohan Hedberg 	BT_DBG("%s removing %pMR (%u)", hdev->name, bdaddr, bdaddr_type);
25502763eda6SSzymon Janc 
25512763eda6SSzymon Janc 	list_del(&data->list);
25522763eda6SSzymon Janc 	kfree(data);
25532763eda6SSzymon Janc 
25542763eda6SSzymon Janc 	return 0;
25552763eda6SSzymon Janc }
25562763eda6SSzymon Janc 
255735f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev)
25582763eda6SSzymon Janc {
25592763eda6SSzymon Janc 	struct oob_data *data, *n;
25602763eda6SSzymon Janc 
25612763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
25622763eda6SSzymon Janc 		list_del(&data->list);
25632763eda6SSzymon Janc 		kfree(data);
25642763eda6SSzymon Janc 	}
25652763eda6SSzymon Janc }
25662763eda6SSzymon Janc 
25670798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
25686928a924SJohan Hedberg 			    u8 bdaddr_type, u8 *hash192, u8 *rand192,
256938da1703SJohan Hedberg 			    u8 *hash256, u8 *rand256)
25700798872eSMarcel Holtmann {
25710798872eSMarcel Holtmann 	struct oob_data *data;
25720798872eSMarcel Holtmann 
25736928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
25740798872eSMarcel Holtmann 	if (!data) {
25750a14ab41SJohan Hedberg 		data = kmalloc(sizeof(*data), GFP_KERNEL);
25760798872eSMarcel Holtmann 		if (!data)
25770798872eSMarcel Holtmann 			return -ENOMEM;
25780798872eSMarcel Holtmann 
25790798872eSMarcel Holtmann 		bacpy(&data->bdaddr, bdaddr);
25806928a924SJohan Hedberg 		data->bdaddr_type = bdaddr_type;
25810798872eSMarcel Holtmann 		list_add(&data->list, &hdev->remote_oob_data);
25820798872eSMarcel Holtmann 	}
25830798872eSMarcel Holtmann 
258481328d5cSJohan Hedberg 	if (hash192 && rand192) {
25850798872eSMarcel Holtmann 		memcpy(data->hash192, hash192, sizeof(data->hash192));
258638da1703SJohan Hedberg 		memcpy(data->rand192, rand192, sizeof(data->rand192));
2587f7697b16SMarcel Holtmann 		if (hash256 && rand256)
2588f7697b16SMarcel Holtmann 			data->present = 0x03;
258981328d5cSJohan Hedberg 	} else {
259081328d5cSJohan Hedberg 		memset(data->hash192, 0, sizeof(data->hash192));
259181328d5cSJohan Hedberg 		memset(data->rand192, 0, sizeof(data->rand192));
2592f7697b16SMarcel Holtmann 		if (hash256 && rand256)
2593f7697b16SMarcel Holtmann 			data->present = 0x02;
2594f7697b16SMarcel Holtmann 		else
2595f7697b16SMarcel Holtmann 			data->present = 0x00;
259681328d5cSJohan Hedberg 	}
25970798872eSMarcel Holtmann 
259881328d5cSJohan Hedberg 	if (hash256 && rand256) {
25990798872eSMarcel Holtmann 		memcpy(data->hash256, hash256, sizeof(data->hash256));
260038da1703SJohan Hedberg 		memcpy(data->rand256, rand256, sizeof(data->rand256));
260181328d5cSJohan Hedberg 	} else {
260281328d5cSJohan Hedberg 		memset(data->hash256, 0, sizeof(data->hash256));
260381328d5cSJohan Hedberg 		memset(data->rand256, 0, sizeof(data->rand256));
2604f7697b16SMarcel Holtmann 		if (hash192 && rand192)
2605f7697b16SMarcel Holtmann 			data->present = 0x01;
260681328d5cSJohan Hedberg 	}
26070798872eSMarcel Holtmann 
26086ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
26092763eda6SSzymon Janc 
26102763eda6SSzymon Janc 	return 0;
26112763eda6SSzymon Janc }
26122763eda6SSzymon Janc 
2613dcc36c16SJohan Hedberg struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
2614b9ee0a78SMarcel Holtmann 					 bdaddr_t *bdaddr, u8 type)
2615b2a66aadSAntti Julku {
2616b2a66aadSAntti Julku 	struct bdaddr_list *b;
2617b2a66aadSAntti Julku 
2618dcc36c16SJohan Hedberg 	list_for_each_entry(b, bdaddr_list, list) {
2619b9ee0a78SMarcel Holtmann 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
2620b2a66aadSAntti Julku 			return b;
2621b9ee0a78SMarcel Holtmann 	}
2622b2a66aadSAntti Julku 
2623b2a66aadSAntti Julku 	return NULL;
2624b2a66aadSAntti Julku }
2625b2a66aadSAntti Julku 
2626dcc36c16SJohan Hedberg void hci_bdaddr_list_clear(struct list_head *bdaddr_list)
2627b2a66aadSAntti Julku {
2628b2a66aadSAntti Julku 	struct list_head *p, *n;
2629b2a66aadSAntti Julku 
2630dcc36c16SJohan Hedberg 	list_for_each_safe(p, n, bdaddr_list) {
2631b9ee0a78SMarcel Holtmann 		struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list);
2632b2a66aadSAntti Julku 
2633b2a66aadSAntti Julku 		list_del(p);
2634b2a66aadSAntti Julku 		kfree(b);
2635b2a66aadSAntti Julku 	}
2636b2a66aadSAntti Julku }
2637b2a66aadSAntti Julku 
2638dcc36c16SJohan Hedberg int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type)
2639b2a66aadSAntti Julku {
2640b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2641b2a66aadSAntti Julku 
2642b9ee0a78SMarcel Holtmann 	if (!bacmp(bdaddr, BDADDR_ANY))
2643b2a66aadSAntti Julku 		return -EBADF;
2644b2a66aadSAntti Julku 
2645dcc36c16SJohan Hedberg 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
26465e762444SAntti Julku 		return -EEXIST;
2647b2a66aadSAntti Julku 
264827f70f3eSJohan Hedberg 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
26495e762444SAntti Julku 	if (!entry)
26505e762444SAntti Julku 		return -ENOMEM;
2651b2a66aadSAntti Julku 
2652b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
2653b9ee0a78SMarcel Holtmann 	entry->bdaddr_type = type;
2654b2a66aadSAntti Julku 
2655dcc36c16SJohan Hedberg 	list_add(&entry->list, list);
2656b2a66aadSAntti Julku 
26572a8357f2SJohan Hedberg 	return 0;
2658b2a66aadSAntti Julku }
2659b2a66aadSAntti Julku 
2660dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type)
2661b2a66aadSAntti Julku {
2662b2a66aadSAntti Julku 	struct bdaddr_list *entry;
2663b2a66aadSAntti Julku 
266435f7498aSJohan Hedberg 	if (!bacmp(bdaddr, BDADDR_ANY)) {
2665dcc36c16SJohan Hedberg 		hci_bdaddr_list_clear(list);
266635f7498aSJohan Hedberg 		return 0;
266735f7498aSJohan Hedberg 	}
2668b2a66aadSAntti Julku 
2669dcc36c16SJohan Hedberg 	entry = hci_bdaddr_list_lookup(list, bdaddr, type);
2670d2ab0ac1SMarcel Holtmann 	if (!entry)
2671d2ab0ac1SMarcel Holtmann 		return -ENOENT;
2672d2ab0ac1SMarcel Holtmann 
2673d2ab0ac1SMarcel Holtmann 	list_del(&entry->list);
2674d2ab0ac1SMarcel Holtmann 	kfree(entry);
2675d2ab0ac1SMarcel Holtmann 
2676d2ab0ac1SMarcel Holtmann 	return 0;
2677d2ab0ac1SMarcel Holtmann }
2678d2ab0ac1SMarcel Holtmann 
267915819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
268015819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
268115819a70SAndre Guedes 					       bdaddr_t *addr, u8 addr_type)
268215819a70SAndre Guedes {
268315819a70SAndre Guedes 	struct hci_conn_params *params;
268415819a70SAndre Guedes 
2685738f6185SJohan Hedberg 	/* The conn params list only contains identity addresses */
2686738f6185SJohan Hedberg 	if (!hci_is_identity_address(addr, addr_type))
2687738f6185SJohan Hedberg 		return NULL;
2688738f6185SJohan Hedberg 
268915819a70SAndre Guedes 	list_for_each_entry(params, &hdev->le_conn_params, list) {
269015819a70SAndre Guedes 		if (bacmp(&params->addr, addr) == 0 &&
269115819a70SAndre Guedes 		    params->addr_type == addr_type) {
269215819a70SAndre Guedes 			return params;
269315819a70SAndre Guedes 		}
269415819a70SAndre Guedes 	}
269515819a70SAndre Guedes 
269615819a70SAndre Guedes 	return NULL;
269715819a70SAndre Guedes }
269815819a70SAndre Guedes 
269915819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
2700501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list,
27014b10966fSMarcel Holtmann 						  bdaddr_t *addr, u8 addr_type)
270215819a70SAndre Guedes {
2703912b42efSJohan Hedberg 	struct hci_conn_params *param;
270415819a70SAndre Guedes 
2705738f6185SJohan Hedberg 	/* The list only contains identity addresses */
2706738f6185SJohan Hedberg 	if (!hci_is_identity_address(addr, addr_type))
2707738f6185SJohan Hedberg 		return NULL;
270815819a70SAndre Guedes 
2709501f8827SJohan Hedberg 	list_for_each_entry(param, list, action) {
2710912b42efSJohan Hedberg 		if (bacmp(&param->addr, addr) == 0 &&
2711912b42efSJohan Hedberg 		    param->addr_type == addr_type)
2712912b42efSJohan Hedberg 			return param;
27134b10966fSMarcel Holtmann 	}
27144b10966fSMarcel Holtmann 
27154b10966fSMarcel Holtmann 	return NULL;
271615819a70SAndre Guedes }
271715819a70SAndre Guedes 
271815819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
271951d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev,
272051d167c0SMarcel Holtmann 					    bdaddr_t *addr, u8 addr_type)
272115819a70SAndre Guedes {
272215819a70SAndre Guedes 	struct hci_conn_params *params;
272315819a70SAndre Guedes 
2724c46245b3SJohan Hedberg 	if (!hci_is_identity_address(addr, addr_type))
272551d167c0SMarcel Holtmann 		return NULL;
2726a9b0a04cSAndre Guedes 
272715819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
2728cef952ceSAndre Guedes 	if (params)
272951d167c0SMarcel Holtmann 		return params;
273015819a70SAndre Guedes 
273115819a70SAndre Guedes 	params = kzalloc(sizeof(*params), GFP_KERNEL);
273215819a70SAndre Guedes 	if (!params) {
273315819a70SAndre Guedes 		BT_ERR("Out of memory");
273451d167c0SMarcel Holtmann 		return NULL;
273515819a70SAndre Guedes 	}
273615819a70SAndre Guedes 
273715819a70SAndre Guedes 	bacpy(&params->addr, addr);
273815819a70SAndre Guedes 	params->addr_type = addr_type;
2739cef952ceSAndre Guedes 
2740cef952ceSAndre Guedes 	list_add(&params->list, &hdev->le_conn_params);
274193450c75SJohan Hedberg 	INIT_LIST_HEAD(&params->action);
2742cef952ceSAndre Guedes 
2743bf5b3c8bSMarcel Holtmann 	params->conn_min_interval = hdev->le_conn_min_interval;
2744bf5b3c8bSMarcel Holtmann 	params->conn_max_interval = hdev->le_conn_max_interval;
2745bf5b3c8bSMarcel Holtmann 	params->conn_latency = hdev->le_conn_latency;
2746bf5b3c8bSMarcel Holtmann 	params->supervision_timeout = hdev->le_supv_timeout;
2747bf5b3c8bSMarcel Holtmann 	params->auto_connect = HCI_AUTO_CONN_DISABLED;
2748bf5b3c8bSMarcel Holtmann 
2749bf5b3c8bSMarcel Holtmann 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
2750bf5b3c8bSMarcel Holtmann 
275151d167c0SMarcel Holtmann 	return params;
2752bf5b3c8bSMarcel Holtmann }
2753bf5b3c8bSMarcel Holtmann 
2754f6c63249SJohan Hedberg static void hci_conn_params_free(struct hci_conn_params *params)
2755f6c63249SJohan Hedberg {
2756f6c63249SJohan Hedberg 	if (params->conn) {
2757f6c63249SJohan Hedberg 		hci_conn_drop(params->conn);
2758f6c63249SJohan Hedberg 		hci_conn_put(params->conn);
2759f6c63249SJohan Hedberg 	}
2760f6c63249SJohan Hedberg 
2761f6c63249SJohan Hedberg 	list_del(&params->action);
2762f6c63249SJohan Hedberg 	list_del(&params->list);
2763f6c63249SJohan Hedberg 	kfree(params);
2764f6c63249SJohan Hedberg }
2765f6c63249SJohan Hedberg 
276615819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
276715819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
276815819a70SAndre Guedes {
276915819a70SAndre Guedes 	struct hci_conn_params *params;
277015819a70SAndre Guedes 
277115819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
277215819a70SAndre Guedes 	if (!params)
277315819a70SAndre Guedes 		return;
277415819a70SAndre Guedes 
2775f6c63249SJohan Hedberg 	hci_conn_params_free(params);
277615819a70SAndre Guedes 
277795305baaSJohan Hedberg 	hci_update_background_scan(hdev);
277895305baaSJohan Hedberg 
277915819a70SAndre Guedes 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
278015819a70SAndre Guedes }
278115819a70SAndre Guedes 
278215819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
278355af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev)
278415819a70SAndre Guedes {
278515819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
278615819a70SAndre Guedes 
278715819a70SAndre Guedes 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
278855af49a8SJohan Hedberg 		if (params->auto_connect != HCI_AUTO_CONN_DISABLED)
278955af49a8SJohan Hedberg 			continue;
279015819a70SAndre Guedes 		list_del(&params->list);
279115819a70SAndre Guedes 		kfree(params);
279215819a70SAndre Guedes 	}
279315819a70SAndre Guedes 
279455af49a8SJohan Hedberg 	BT_DBG("All LE disabled connection parameters were removed");
279555af49a8SJohan Hedberg }
279655af49a8SJohan Hedberg 
279755af49a8SJohan Hedberg /* This function requires the caller holds hdev->lock */
2798373110c5SJohan Hedberg void hci_conn_params_clear_all(struct hci_dev *hdev)
279915819a70SAndre Guedes {
280015819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
280115819a70SAndre Guedes 
2802f6c63249SJohan Hedberg 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list)
2803f6c63249SJohan Hedberg 		hci_conn_params_free(params);
280415819a70SAndre Guedes 
2805a2f41a8fSJohan Hedberg 	hci_update_background_scan(hdev);
28061089b67dSMarcel Holtmann 
280715819a70SAndre Guedes 	BT_DBG("All LE connection parameters were removed");
280815819a70SAndre Guedes }
280915819a70SAndre Guedes 
28101904a853SMarcel Holtmann static void inquiry_complete(struct hci_dev *hdev, u8 status, u16 opcode)
28117ba8b4beSAndre Guedes {
28124c87eaabSAndre Guedes 	if (status) {
28134c87eaabSAndre Guedes 		BT_ERR("Failed to start inquiry: status %d", status);
28147ba8b4beSAndre Guedes 
28154c87eaabSAndre Guedes 		hci_dev_lock(hdev);
28164c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
28174c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
28184c87eaabSAndre Guedes 		return;
28194c87eaabSAndre Guedes 	}
28207ba8b4beSAndre Guedes }
28217ba8b4beSAndre Guedes 
28221904a853SMarcel Holtmann static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status,
28231904a853SMarcel Holtmann 					  u16 opcode)
28247ba8b4beSAndre Guedes {
28254c87eaabSAndre Guedes 	/* General inquiry access code (GIAC) */
28264c87eaabSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
28274c87eaabSAndre Guedes 	struct hci_cp_inquiry cp;
28287ba8b4beSAndre Guedes 	int err;
28297ba8b4beSAndre Guedes 
28304c87eaabSAndre Guedes 	if (status) {
28314c87eaabSAndre Guedes 		BT_ERR("Failed to disable LE scanning: status %d", status);
28324c87eaabSAndre Guedes 		return;
28337ba8b4beSAndre Guedes 	}
28347ba8b4beSAndre Guedes 
28352d28cfe7SJakub Pawlowski 	hdev->discovery.scan_start = 0;
28362d28cfe7SJakub Pawlowski 
28374c87eaabSAndre Guedes 	switch (hdev->discovery.type) {
28384c87eaabSAndre Guedes 	case DISCOV_TYPE_LE:
28394c87eaabSAndre Guedes 		hci_dev_lock(hdev);
28404c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
28414c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
28424c87eaabSAndre Guedes 		break;
28437dbfac1dSAndre Guedes 
28444c87eaabSAndre Guedes 	case DISCOV_TYPE_INTERLEAVED:
28454c87eaabSAndre Guedes 		hci_dev_lock(hdev);
28464c87eaabSAndre Guedes 
284707d2334aSJakub Pawlowski 		if (test_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY,
284807d2334aSJakub Pawlowski 			     &hdev->quirks)) {
284907d2334aSJakub Pawlowski 			/* If we were running LE only scan, change discovery
285007d2334aSJakub Pawlowski 			 * state. If we were running both LE and BR/EDR inquiry
285107d2334aSJakub Pawlowski 			 * simultaneously, and BR/EDR inquiry is already
285207d2334aSJakub Pawlowski 			 * finished, stop discovery, otherwise BR/EDR inquiry
2853177d0506SWesley Kuo 			 * will stop discovery when finished. If we will resolve
2854177d0506SWesley Kuo 			 * remote device name, do not change discovery state.
285507d2334aSJakub Pawlowski 			 */
2856177d0506SWesley Kuo 			if (!test_bit(HCI_INQUIRY, &hdev->flags) &&
2857177d0506SWesley Kuo 			    hdev->discovery.state != DISCOVERY_RESOLVING)
285807d2334aSJakub Pawlowski 				hci_discovery_set_state(hdev,
285907d2334aSJakub Pawlowski 							DISCOVERY_STOPPED);
286007d2334aSJakub Pawlowski 		} else {
2861baf880a9SJohan Hedberg 			struct hci_request req;
2862baf880a9SJohan Hedberg 
28634c87eaabSAndre Guedes 			hci_inquiry_cache_flush(hdev);
28644c87eaabSAndre Guedes 
2865baf880a9SJohan Hedberg 			hci_req_init(&req, hdev);
2866baf880a9SJohan Hedberg 
2867baf880a9SJohan Hedberg 			memset(&cp, 0, sizeof(cp));
2868baf880a9SJohan Hedberg 			memcpy(&cp.lap, lap, sizeof(cp.lap));
2869baf880a9SJohan Hedberg 			cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN;
2870baf880a9SJohan Hedberg 			hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp);
2871baf880a9SJohan Hedberg 
28724c87eaabSAndre Guedes 			err = hci_req_run(&req, inquiry_complete);
28734c87eaabSAndre Guedes 			if (err) {
28744c87eaabSAndre Guedes 				BT_ERR("Inquiry request failed: err %d", err);
287507d2334aSJakub Pawlowski 				hci_discovery_set_state(hdev,
287607d2334aSJakub Pawlowski 							DISCOVERY_STOPPED);
287707d2334aSJakub Pawlowski 			}
28787dbfac1dSAndre Guedes 		}
28797dbfac1dSAndre Guedes 
28804c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
28814c87eaabSAndre Guedes 		break;
28824c87eaabSAndre Guedes 	}
28837dbfac1dSAndre Guedes }
28847dbfac1dSAndre Guedes 
28857ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work)
28867ba8b4beSAndre Guedes {
28877ba8b4beSAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev,
28887ba8b4beSAndre Guedes 					    le_scan_disable.work);
28894c87eaabSAndre Guedes 	struct hci_request req;
28904c87eaabSAndre Guedes 	int err;
28917ba8b4beSAndre Guedes 
28927ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
28937ba8b4beSAndre Guedes 
28942d28cfe7SJakub Pawlowski 	cancel_delayed_work_sync(&hdev->le_scan_restart);
28952d28cfe7SJakub Pawlowski 
28964c87eaabSAndre Guedes 	hci_req_init(&req, hdev);
28977ba8b4beSAndre Guedes 
2898b1efcc28SAndre Guedes 	hci_req_add_le_scan_disable(&req);
28997ba8b4beSAndre Guedes 
29004c87eaabSAndre Guedes 	err = hci_req_run(&req, le_scan_disable_work_complete);
29014c87eaabSAndre Guedes 	if (err)
29024c87eaabSAndre Guedes 		BT_ERR("Disable LE scanning request failed: err %d", err);
290328b75a89SAndre Guedes }
290428b75a89SAndre Guedes 
29052d28cfe7SJakub Pawlowski static void le_scan_restart_work_complete(struct hci_dev *hdev, u8 status,
29062d28cfe7SJakub Pawlowski 					  u16 opcode)
29072d28cfe7SJakub Pawlowski {
29082d28cfe7SJakub Pawlowski 	unsigned long timeout, duration, scan_start, now;
29092d28cfe7SJakub Pawlowski 
29102d28cfe7SJakub Pawlowski 	BT_DBG("%s", hdev->name);
29112d28cfe7SJakub Pawlowski 
29122d28cfe7SJakub Pawlowski 	if (status) {
29132d28cfe7SJakub Pawlowski 		BT_ERR("Failed to restart LE scan: status %d", status);
29142d28cfe7SJakub Pawlowski 		return;
29152d28cfe7SJakub Pawlowski 	}
29162d28cfe7SJakub Pawlowski 
29172d28cfe7SJakub Pawlowski 	if (!test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks) ||
29182d28cfe7SJakub Pawlowski 	    !hdev->discovery.scan_start)
29192d28cfe7SJakub Pawlowski 		return;
29202d28cfe7SJakub Pawlowski 
29212d28cfe7SJakub Pawlowski 	/* When the scan was started, hdev->le_scan_disable has been queued
29222d28cfe7SJakub Pawlowski 	 * after duration from scan_start. During scan restart this job
29232d28cfe7SJakub Pawlowski 	 * has been canceled, and we need to queue it again after proper
29242d28cfe7SJakub Pawlowski 	 * timeout, to make sure that scan does not run indefinitely.
29252d28cfe7SJakub Pawlowski 	 */
29262d28cfe7SJakub Pawlowski 	duration = hdev->discovery.scan_duration;
29272d28cfe7SJakub Pawlowski 	scan_start = hdev->discovery.scan_start;
29282d28cfe7SJakub Pawlowski 	now = jiffies;
29292d28cfe7SJakub Pawlowski 	if (now - scan_start <= duration) {
29302d28cfe7SJakub Pawlowski 		int elapsed;
29312d28cfe7SJakub Pawlowski 
29322d28cfe7SJakub Pawlowski 		if (now >= scan_start)
29332d28cfe7SJakub Pawlowski 			elapsed = now - scan_start;
29342d28cfe7SJakub Pawlowski 		else
29352d28cfe7SJakub Pawlowski 			elapsed = ULONG_MAX - scan_start + now;
29362d28cfe7SJakub Pawlowski 
29372d28cfe7SJakub Pawlowski 		timeout = duration - elapsed;
29382d28cfe7SJakub Pawlowski 	} else {
29392d28cfe7SJakub Pawlowski 		timeout = 0;
29402d28cfe7SJakub Pawlowski 	}
29412d28cfe7SJakub Pawlowski 	queue_delayed_work(hdev->workqueue,
29422d28cfe7SJakub Pawlowski 			   &hdev->le_scan_disable, timeout);
29432d28cfe7SJakub Pawlowski }
29442d28cfe7SJakub Pawlowski 
29452d28cfe7SJakub Pawlowski static void le_scan_restart_work(struct work_struct *work)
29462d28cfe7SJakub Pawlowski {
29472d28cfe7SJakub Pawlowski 	struct hci_dev *hdev = container_of(work, struct hci_dev,
29482d28cfe7SJakub Pawlowski 					    le_scan_restart.work);
29492d28cfe7SJakub Pawlowski 	struct hci_request req;
29502d28cfe7SJakub Pawlowski 	struct hci_cp_le_set_scan_enable cp;
29512d28cfe7SJakub Pawlowski 	int err;
29522d28cfe7SJakub Pawlowski 
29532d28cfe7SJakub Pawlowski 	BT_DBG("%s", hdev->name);
29542d28cfe7SJakub Pawlowski 
29552d28cfe7SJakub Pawlowski 	/* If controller is not scanning we are done. */
2956d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_LE_SCAN))
29572d28cfe7SJakub Pawlowski 		return;
29582d28cfe7SJakub Pawlowski 
29592d28cfe7SJakub Pawlowski 	hci_req_init(&req, hdev);
29602d28cfe7SJakub Pawlowski 
29612d28cfe7SJakub Pawlowski 	hci_req_add_le_scan_disable(&req);
29622d28cfe7SJakub Pawlowski 
29632d28cfe7SJakub Pawlowski 	memset(&cp, 0, sizeof(cp));
29642d28cfe7SJakub Pawlowski 	cp.enable = LE_SCAN_ENABLE;
29652d28cfe7SJakub Pawlowski 	cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
29662d28cfe7SJakub Pawlowski 	hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
29672d28cfe7SJakub Pawlowski 
29682d28cfe7SJakub Pawlowski 	err = hci_req_run(&req, le_scan_restart_work_complete);
29692d28cfe7SJakub Pawlowski 	if (err)
29702d28cfe7SJakub Pawlowski 		BT_ERR("Restart LE scan request failed: err %d", err);
29712d28cfe7SJakub Pawlowski }
29722d28cfe7SJakub Pawlowski 
2973a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller.
2974a1f4c318SJohan Hedberg  *
2975a1f4c318SJohan Hedberg  * If the controller has a public BD_ADDR, then by default use that one.
2976a1f4c318SJohan Hedberg  * If this is a LE only controller without a public address, default to
2977a1f4c318SJohan Hedberg  * the static random address.
2978a1f4c318SJohan Hedberg  *
2979a1f4c318SJohan Hedberg  * For debugging purposes it is possible to force controllers with a
2980a1f4c318SJohan Hedberg  * public address to use the static random address instead.
298150b5b952SMarcel Holtmann  *
298250b5b952SMarcel Holtmann  * In case BR/EDR has been disabled on a dual-mode controller and
298350b5b952SMarcel Holtmann  * userspace has configured a static address, then that address
298450b5b952SMarcel Holtmann  * becomes the identity address instead of the public BR/EDR address.
2985a1f4c318SJohan Hedberg  */
2986a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
2987a1f4c318SJohan Hedberg 			       u8 *bdaddr_type)
2988a1f4c318SJohan Hedberg {
2989b7cb93e5SMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) ||
299050b5b952SMarcel Holtmann 	    !bacmp(&hdev->bdaddr, BDADDR_ANY) ||
2991d7a5a11dSMarcel Holtmann 	    (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED) &&
299250b5b952SMarcel Holtmann 	     bacmp(&hdev->static_addr, BDADDR_ANY))) {
2993a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->static_addr);
2994a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_RANDOM;
2995a1f4c318SJohan Hedberg 	} else {
2996a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->bdaddr);
2997a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_PUBLIC;
2998a1f4c318SJohan Hedberg 	}
2999a1f4c318SJohan Hedberg }
3000a1f4c318SJohan Hedberg 
30019be0dab7SDavid Herrmann /* Alloc HCI device */
30029be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void)
30039be0dab7SDavid Herrmann {
30049be0dab7SDavid Herrmann 	struct hci_dev *hdev;
30059be0dab7SDavid Herrmann 
300627f70f3eSJohan Hedberg 	hdev = kzalloc(sizeof(*hdev), GFP_KERNEL);
30079be0dab7SDavid Herrmann 	if (!hdev)
30089be0dab7SDavid Herrmann 		return NULL;
30099be0dab7SDavid Herrmann 
3010b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
3011b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
3012b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
3013b4cb9fb2SMarcel Holtmann 	hdev->num_iac = 0x01;		/* One IAC support is mandatory */
3014b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03;	/* No Input No Output */
301596c2103aSMarcel Holtmann 	hdev->manufacturer = 0xffff;	/* Default to internal use */
3016bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
3017bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
3018b1b813d4SDavid Herrmann 
3019b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
3020b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
3021b1b813d4SDavid Herrmann 
30223f959d46SMarcel Holtmann 	hdev->le_adv_channel_map = 0x07;
3023628531c9SGeorg Lukas 	hdev->le_adv_min_interval = 0x0800;
3024628531c9SGeorg Lukas 	hdev->le_adv_max_interval = 0x0800;
3025bef64738SMarcel Holtmann 	hdev->le_scan_interval = 0x0060;
3026bef64738SMarcel Holtmann 	hdev->le_scan_window = 0x0030;
30274e70c7e7SMarcel Holtmann 	hdev->le_conn_min_interval = 0x0028;
30284e70c7e7SMarcel Holtmann 	hdev->le_conn_max_interval = 0x0038;
302904fb7d90SMarcel Holtmann 	hdev->le_conn_latency = 0x0000;
303004fb7d90SMarcel Holtmann 	hdev->le_supv_timeout = 0x002a;
3031a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_len = 0x001b;
3032a8e1bfaaSMarcel Holtmann 	hdev->le_def_tx_time = 0x0148;
3033a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_len = 0x001b;
3034a8e1bfaaSMarcel Holtmann 	hdev->le_max_tx_time = 0x0148;
3035a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_len = 0x001b;
3036a8e1bfaaSMarcel Holtmann 	hdev->le_max_rx_time = 0x0148;
3037bef64738SMarcel Holtmann 
3038d6bfd59cSJohan Hedberg 	hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT;
3039b9a7a61eSLukasz Rymanowski 	hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT;
304031ad1691SAndrzej Kaczmarek 	hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE;
304131ad1691SAndrzej Kaczmarek 	hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE;
3042d6bfd59cSJohan Hedberg 
3043b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
3044b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
3045b1b813d4SDavid Herrmann 
3046b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
3047b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->blacklist);
30486659358eSJohan Hedberg 	INIT_LIST_HEAD(&hdev->whitelist);
3049b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
3050b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
3051b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
3052970c4e46SJohan Hedberg 	INIT_LIST_HEAD(&hdev->identity_resolving_keys);
3053b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
3054d2ab0ac1SMarcel Holtmann 	INIT_LIST_HEAD(&hdev->le_white_list);
305515819a70SAndre Guedes 	INIT_LIST_HEAD(&hdev->le_conn_params);
305677a77a30SAndre Guedes 	INIT_LIST_HEAD(&hdev->pend_le_conns);
305766f8455aSJohan Hedberg 	INIT_LIST_HEAD(&hdev->pend_le_reports);
30586b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
3059b1b813d4SDavid Herrmann 
3060b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
3061b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
3062b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
3063b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
3064c7741d16SMarcel Holtmann 	INIT_WORK(&hdev->error_reset, hci_error_reset);
3065b1b813d4SDavid Herrmann 
3066b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
3067b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
3068b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
30692d28cfe7SJakub Pawlowski 	INIT_DELAYED_WORK(&hdev->le_scan_restart, le_scan_restart_work);
3070b1b813d4SDavid Herrmann 
3071b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
3072b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
3073b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
3074b1b813d4SDavid Herrmann 
3075b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
3076b1b813d4SDavid Herrmann 
307765cc2b49SMarcel Holtmann 	INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout);
3078b1b813d4SDavid Herrmann 
3079b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
3080b1b813d4SDavid Herrmann 	discovery_init(hdev);
3081203fea01SArman Uguray 	adv_info_init(hdev);
30829be0dab7SDavid Herrmann 
30839be0dab7SDavid Herrmann 	return hdev;
30849be0dab7SDavid Herrmann }
30859be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev);
30869be0dab7SDavid Herrmann 
30879be0dab7SDavid Herrmann /* Free HCI device */
30889be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
30899be0dab7SDavid Herrmann {
30909be0dab7SDavid Herrmann 	/* will free via device release */
30919be0dab7SDavid Herrmann 	put_device(&hdev->dev);
30929be0dab7SDavid Herrmann }
30939be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
30949be0dab7SDavid Herrmann 
30951da177e4SLinus Torvalds /* Register HCI device */
30961da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
30971da177e4SLinus Torvalds {
3098b1b813d4SDavid Herrmann 	int id, error;
30991da177e4SLinus Torvalds 
310074292d5aSMarcel Holtmann 	if (!hdev->open || !hdev->close || !hdev->send)
31011da177e4SLinus Torvalds 		return -EINVAL;
31021da177e4SLinus Torvalds 
310308add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
310408add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
310508add513SMat Martineau 	 */
31063df92b31SSasha Levin 	switch (hdev->dev_type) {
31073df92b31SSasha Levin 	case HCI_BREDR:
31083df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
31091da177e4SLinus Torvalds 		break;
31103df92b31SSasha Levin 	case HCI_AMP:
31113df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
31123df92b31SSasha Levin 		break;
31133df92b31SSasha Levin 	default:
31143df92b31SSasha Levin 		return -EINVAL;
31151da177e4SLinus Torvalds 	}
31161da177e4SLinus Torvalds 
31173df92b31SSasha Levin 	if (id < 0)
31183df92b31SSasha Levin 		return id;
31193df92b31SSasha Levin 
31201da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
31211da177e4SLinus Torvalds 	hdev->id = id;
31222d8b3a11SAndrei Emeltchenko 
31232d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
31242d8b3a11SAndrei Emeltchenko 
3125d8537548SKees Cook 	hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
3126d8537548SKees Cook 					  WQ_MEM_RECLAIM, 1, hdev->name);
312733ca954dSDavid Herrmann 	if (!hdev->workqueue) {
312833ca954dSDavid Herrmann 		error = -ENOMEM;
312933ca954dSDavid Herrmann 		goto err;
313033ca954dSDavid Herrmann 	}
3131f48fd9c8SMarcel Holtmann 
3132d8537548SKees Cook 	hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
3133d8537548SKees Cook 					      WQ_MEM_RECLAIM, 1, hdev->name);
31346ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
31356ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
31366ead1bbcSJohan Hedberg 		error = -ENOMEM;
31376ead1bbcSJohan Hedberg 		goto err;
31386ead1bbcSJohan Hedberg 	}
31396ead1bbcSJohan Hedberg 
31400153e2ecSMarcel Holtmann 	if (!IS_ERR_OR_NULL(bt_debugfs))
31410153e2ecSMarcel Holtmann 		hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs);
31420153e2ecSMarcel Holtmann 
3143bdc3e0f1SMarcel Holtmann 	dev_set_name(&hdev->dev, "%s", hdev->name);
3144bdc3e0f1SMarcel Holtmann 
3145bdc3e0f1SMarcel Holtmann 	error = device_add(&hdev->dev);
314633ca954dSDavid Herrmann 	if (error < 0)
314754506918SJohan Hedberg 		goto err_wqueue;
31481da177e4SLinus Torvalds 
3149611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
3150a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
3151a8c5fb1aSGustavo Padovan 				    hdev);
3152611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
3153611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
3154611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
3155611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
3156611b30f7SMarcel Holtmann 		}
3157611b30f7SMarcel Holtmann 	}
3158611b30f7SMarcel Holtmann 
31595e130367SJohan Hedberg 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill))
3160a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_RFKILLED);
31615e130367SJohan Hedberg 
3162a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_SETUP);
3163a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_AUTO_OFF);
3164ce2be9acSAndrei Emeltchenko 
316501cd3404SMarcel Holtmann 	if (hdev->dev_type == HCI_BREDR) {
316656f87901SJohan Hedberg 		/* Assume BR/EDR support until proven otherwise (such as
316756f87901SJohan Hedberg 		 * through reading supported features during init.
316856f87901SJohan Hedberg 		 */
3169a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_BREDR_ENABLED);
317056f87901SJohan Hedberg 	}
3171ce2be9acSAndrei Emeltchenko 
3172fcee3377SGustavo Padovan 	write_lock(&hci_dev_list_lock);
3173fcee3377SGustavo Padovan 	list_add(&hdev->list, &hci_dev_list);
3174fcee3377SGustavo Padovan 	write_unlock(&hci_dev_list_lock);
3175fcee3377SGustavo Padovan 
31764a964404SMarcel Holtmann 	/* Devices that are marked for raw-only usage are unconfigured
31774a964404SMarcel Holtmann 	 * and should not be included in normal operation.
3178fee746b0SMarcel Holtmann 	 */
3179fee746b0SMarcel Holtmann 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
3180a1536da2SMarcel Holtmann 		hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
3181fee746b0SMarcel Holtmann 
31821da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
3183dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
31841da177e4SLinus Torvalds 
318519202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
3186fbe96d6fSMarcel Holtmann 
31871da177e4SLinus Torvalds 	return id;
3188f48fd9c8SMarcel Holtmann 
318933ca954dSDavid Herrmann err_wqueue:
319033ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
31916ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
319233ca954dSDavid Herrmann err:
31933df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
3194f48fd9c8SMarcel Holtmann 
319533ca954dSDavid Herrmann 	return error;
31961da177e4SLinus Torvalds }
31971da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
31981da177e4SLinus Torvalds 
31991da177e4SLinus Torvalds /* Unregister HCI device */
320059735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
32011da177e4SLinus Torvalds {
32022d7cc19eSMarcel Holtmann 	int id;
3203ef222013SMarcel Holtmann 
3204c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
32051da177e4SLinus Torvalds 
3206a1536da2SMarcel Holtmann 	hci_dev_set_flag(hdev, HCI_UNREGISTER);
320794324962SJohan Hovold 
32083df92b31SSasha Levin 	id = hdev->id;
32093df92b31SSasha Levin 
3210f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
32111da177e4SLinus Torvalds 	list_del(&hdev->list);
3212f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
32131da177e4SLinus Torvalds 
32141da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
32151da177e4SLinus Torvalds 
3216b9b5ef18SGustavo Padovan 	cancel_work_sync(&hdev->power_on);
3217b9b5ef18SGustavo Padovan 
3218ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
3219d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_SETUP) &&
3220d7a5a11dSMarcel Holtmann 	    !hci_dev_test_flag(hdev, HCI_CONFIG)) {
322109fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
3222744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
322309fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
322456e5cb86SJohan Hedberg 	}
3225ab81cbf9SJohan Hedberg 
32262e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
32272e58ef3eSJohan Hedberg 	 * pending list */
32282e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
32292e58ef3eSJohan Hedberg 
32301da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
32311da177e4SLinus Torvalds 
3232611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
3233611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
3234611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
3235611b30f7SMarcel Holtmann 	}
3236611b30f7SMarcel Holtmann 
3237bdc3e0f1SMarcel Holtmann 	device_del(&hdev->dev);
3238147e2d59SDave Young 
32390153e2ecSMarcel Holtmann 	debugfs_remove_recursive(hdev->debugfs);
32400153e2ecSMarcel Holtmann 
3241f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
32426ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
3243f48fd9c8SMarcel Holtmann 
324409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
3245dcc36c16SJohan Hedberg 	hci_bdaddr_list_clear(&hdev->blacklist);
32466659358eSJohan Hedberg 	hci_bdaddr_list_clear(&hdev->whitelist);
32472aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
324855ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
3249b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
3250970c4e46SJohan Hedberg 	hci_smp_irks_clear(hdev);
32512763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
3252dcc36c16SJohan Hedberg 	hci_bdaddr_list_clear(&hdev->le_white_list);
3253373110c5SJohan Hedberg 	hci_conn_params_clear_all(hdev);
325422078800SMarcel Holtmann 	hci_discovery_filter_clear(hdev);
325509fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
3256e2e0cacbSJohan Hedberg 
3257dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
32583df92b31SSasha Levin 
32593df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, id);
32601da177e4SLinus Torvalds }
32611da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
32621da177e4SLinus Torvalds 
32631da177e4SLinus Torvalds /* Suspend HCI device */
32641da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
32651da177e4SLinus Torvalds {
32661da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
32671da177e4SLinus Torvalds 	return 0;
32681da177e4SLinus Torvalds }
32691da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
32701da177e4SLinus Torvalds 
32711da177e4SLinus Torvalds /* Resume HCI device */
32721da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
32731da177e4SLinus Torvalds {
32741da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
32751da177e4SLinus Torvalds 	return 0;
32761da177e4SLinus Torvalds }
32771da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
32781da177e4SLinus Torvalds 
327975e0569fSMarcel Holtmann /* Reset HCI device */
328075e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev)
328175e0569fSMarcel Holtmann {
328275e0569fSMarcel Holtmann 	const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 };
328375e0569fSMarcel Holtmann 	struct sk_buff *skb;
328475e0569fSMarcel Holtmann 
328575e0569fSMarcel Holtmann 	skb = bt_skb_alloc(3, GFP_ATOMIC);
328675e0569fSMarcel Holtmann 	if (!skb)
328775e0569fSMarcel Holtmann 		return -ENOMEM;
328875e0569fSMarcel Holtmann 
328975e0569fSMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
329075e0569fSMarcel Holtmann 	memcpy(skb_put(skb, 3), hw_err, 3);
329175e0569fSMarcel Holtmann 
329275e0569fSMarcel Holtmann 	/* Send Hardware Error to upper stack */
329375e0569fSMarcel Holtmann 	return hci_recv_frame(hdev, skb);
329475e0569fSMarcel Holtmann }
329575e0569fSMarcel Holtmann EXPORT_SYMBOL(hci_reset_dev);
329675e0569fSMarcel Holtmann 
329776bca880SMarcel Holtmann /* Receive frame from HCI drivers */
3298e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
329976bca880SMarcel Holtmann {
330076bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
330176bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
330276bca880SMarcel Holtmann 		kfree_skb(skb);
330376bca880SMarcel Holtmann 		return -ENXIO;
330476bca880SMarcel Holtmann 	}
330576bca880SMarcel Holtmann 
3306d82603c6SJorrit Schippers 	/* Incoming skb */
330776bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
330876bca880SMarcel Holtmann 
330976bca880SMarcel Holtmann 	/* Time stamp */
331076bca880SMarcel Holtmann 	__net_timestamp(skb);
331176bca880SMarcel Holtmann 
331276bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
3313b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
3314c78ae283SMarcel Holtmann 
331576bca880SMarcel Holtmann 	return 0;
331676bca880SMarcel Holtmann }
331776bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
331876bca880SMarcel Holtmann 
33191da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
33201da177e4SLinus Torvalds 
33211da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
33221da177e4SLinus Torvalds {
33231da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
33241da177e4SLinus Torvalds 
3325fba7ecf0SJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
332600629e0fSJohan Hedberg 	list_add_tail(&cb->list, &hci_cb_list);
3327fba7ecf0SJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
33281da177e4SLinus Torvalds 
33291da177e4SLinus Torvalds 	return 0;
33301da177e4SLinus Torvalds }
33311da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
33321da177e4SLinus Torvalds 
33331da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
33341da177e4SLinus Torvalds {
33351da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
33361da177e4SLinus Torvalds 
3337fba7ecf0SJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
33381da177e4SLinus Torvalds 	list_del(&cb->list);
3339fba7ecf0SJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
33401da177e4SLinus Torvalds 
33411da177e4SLinus Torvalds 	return 0;
33421da177e4SLinus Torvalds }
33431da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
33441da177e4SLinus Torvalds 
334551086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
33461da177e4SLinus Torvalds {
3347cdc52faaSMarcel Holtmann 	int err;
3348cdc52faaSMarcel Holtmann 
33490d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
33501da177e4SLinus Torvalds 
33511da177e4SLinus Torvalds 	/* Time stamp */
3352a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
33531da177e4SLinus Torvalds 
3354cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
3355cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
3356cd82e61cSMarcel Holtmann 
3357cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
3358cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
3359470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
33601da177e4SLinus Torvalds 	}
33611da177e4SLinus Torvalds 
33621da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
33631da177e4SLinus Torvalds 	skb_orphan(skb);
33641da177e4SLinus Torvalds 
3365cdc52faaSMarcel Holtmann 	err = hdev->send(hdev, skb);
3366cdc52faaSMarcel Holtmann 	if (err < 0) {
3367cdc52faaSMarcel Holtmann 		BT_ERR("%s sending frame failed (%d)", hdev->name, err);
3368cdc52faaSMarcel Holtmann 		kfree_skb(skb);
3369cdc52faaSMarcel Holtmann 	}
33701da177e4SLinus Torvalds }
33711da177e4SLinus Torvalds 
33721ca3a9d0SJohan Hedberg /* Send HCI command */
337307dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
337407dc93ddSJohan Hedberg 		 const void *param)
33751ca3a9d0SJohan Hedberg {
33761ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
33771ca3a9d0SJohan Hedberg 
33781ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
33791ca3a9d0SJohan Hedberg 
33801ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
33811ca3a9d0SJohan Hedberg 	if (!skb) {
33821ca3a9d0SJohan Hedberg 		BT_ERR("%s no memory for command", hdev->name);
33831ca3a9d0SJohan Hedberg 		return -ENOMEM;
33841ca3a9d0SJohan Hedberg 	}
33851ca3a9d0SJohan Hedberg 
338649c922bbSStephen Hemminger 	/* Stand-alone HCI commands must be flagged as
338711714b3dSJohan Hedberg 	 * single-command requests.
338811714b3dSJohan Hedberg 	 */
3389db6e3e8dSJohan Hedberg 	bt_cb(skb)->req.start = true;
339011714b3dSJohan Hedberg 
33911da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
3392c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
33931da177e4SLinus Torvalds 
33941da177e4SLinus Torvalds 	return 0;
33951da177e4SLinus Torvalds }
33961da177e4SLinus Torvalds 
33971da177e4SLinus Torvalds /* Get data from the previously sent command */
3398a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
33991da177e4SLinus Torvalds {
34001da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
34011da177e4SLinus Torvalds 
34021da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
34031da177e4SLinus Torvalds 		return NULL;
34041da177e4SLinus Torvalds 
34051da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
34061da177e4SLinus Torvalds 
3407a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
34081da177e4SLinus Torvalds 		return NULL;
34091da177e4SLinus Torvalds 
3410f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
34111da177e4SLinus Torvalds 
34121da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
34131da177e4SLinus Torvalds }
34141da177e4SLinus Torvalds 
34151da177e4SLinus Torvalds /* Send ACL data */
34161da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
34171da177e4SLinus Torvalds {
34181da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
34191da177e4SLinus Torvalds 	int len = skb->len;
34201da177e4SLinus Torvalds 
3421badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
3422badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
34239c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
3424aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
3425aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
34261da177e4SLinus Torvalds }
34271da177e4SLinus Torvalds 
3428ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
342973d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
34301da177e4SLinus Torvalds {
3431ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
34321da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
34331da177e4SLinus Torvalds 	struct sk_buff *list;
34341da177e4SLinus Torvalds 
3435087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
3436087bfd99SGustavo Padovan 	skb->data_len = 0;
3437087bfd99SGustavo Padovan 
3438087bfd99SGustavo Padovan 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
3439204a6e54SAndrei Emeltchenko 
3440204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
3441204a6e54SAndrei Emeltchenko 	case HCI_BREDR:
3442087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
3443204a6e54SAndrei Emeltchenko 		break;
3444204a6e54SAndrei Emeltchenko 	case HCI_AMP:
3445204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
3446204a6e54SAndrei Emeltchenko 		break;
3447204a6e54SAndrei Emeltchenko 	default:
3448204a6e54SAndrei Emeltchenko 		BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
3449204a6e54SAndrei Emeltchenko 		return;
3450204a6e54SAndrei Emeltchenko 	}
3451087bfd99SGustavo Padovan 
345270f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
345370f23020SAndrei Emeltchenko 	if (!list) {
34541da177e4SLinus Torvalds 		/* Non fragmented */
34551da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
34561da177e4SLinus Torvalds 
345773d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
34581da177e4SLinus Torvalds 	} else {
34591da177e4SLinus Torvalds 		/* Fragmented */
34601da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
34611da177e4SLinus Torvalds 
34621da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
34631da177e4SLinus Torvalds 
34649cfd5a23SJukka Rissanen 		/* Queue all fragments atomically. We need to use spin_lock_bh
34659cfd5a23SJukka Rissanen 		 * here because of 6LoWPAN links, as there this function is
34669cfd5a23SJukka Rissanen 		 * called from softirq and using normal spin lock could cause
34679cfd5a23SJukka Rissanen 		 * deadlocks.
34689cfd5a23SJukka Rissanen 		 */
34699cfd5a23SJukka Rissanen 		spin_lock_bh(&queue->lock);
34701da177e4SLinus Torvalds 
347173d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
3472e702112fSAndrei Emeltchenko 
3473e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
3474e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
34751da177e4SLinus Torvalds 		do {
34761da177e4SLinus Torvalds 			skb = list; list = list->next;
34771da177e4SLinus Torvalds 
34780d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
3479e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
34801da177e4SLinus Torvalds 
34811da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
34821da177e4SLinus Torvalds 
348373d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
34841da177e4SLinus Torvalds 		} while (list);
34851da177e4SLinus Torvalds 
34869cfd5a23SJukka Rissanen 		spin_unlock_bh(&queue->lock);
34871da177e4SLinus Torvalds 	}
348873d80debSLuiz Augusto von Dentz }
348973d80debSLuiz Augusto von Dentz 
349073d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
349173d80debSLuiz Augusto von Dentz {
3492ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
349373d80debSLuiz Augusto von Dentz 
3494f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
349573d80debSLuiz Augusto von Dentz 
3496ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
34971da177e4SLinus Torvalds 
34983eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
34991da177e4SLinus Torvalds }
35001da177e4SLinus Torvalds 
35011da177e4SLinus Torvalds /* Send SCO data */
35020d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
35031da177e4SLinus Torvalds {
35041da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
35051da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
35061da177e4SLinus Torvalds 
35071da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
35081da177e4SLinus Torvalds 
3509aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
35101da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
35111da177e4SLinus Torvalds 
3512badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
3513badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
35149c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
35151da177e4SLinus Torvalds 
35160d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
3517c78ae283SMarcel Holtmann 
35181da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
35193eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
35201da177e4SLinus Torvalds }
35211da177e4SLinus Torvalds 
35221da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
35231da177e4SLinus Torvalds 
35241da177e4SLinus Torvalds /* HCI Connection scheduler */
35256039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
3526a8c5fb1aSGustavo Padovan 				     int *quote)
35271da177e4SLinus Torvalds {
35281da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
35298035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
3530abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
35311da177e4SLinus Torvalds 
35321da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
35331da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
3534bf4c6325SGustavo F. Padovan 
3535bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3536bf4c6325SGustavo F. Padovan 
3537bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
3538769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
35391da177e4SLinus Torvalds 			continue;
3540769be974SMarcel Holtmann 
3541769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
3542769be974SMarcel Holtmann 			continue;
3543769be974SMarcel Holtmann 
35441da177e4SLinus Torvalds 		num++;
35451da177e4SLinus Torvalds 
35461da177e4SLinus Torvalds 		if (c->sent < min) {
35471da177e4SLinus Torvalds 			min  = c->sent;
35481da177e4SLinus Torvalds 			conn = c;
35491da177e4SLinus Torvalds 		}
355052087a79SLuiz Augusto von Dentz 
355152087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
355252087a79SLuiz Augusto von Dentz 			break;
35531da177e4SLinus Torvalds 	}
35541da177e4SLinus Torvalds 
3555bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3556bf4c6325SGustavo F. Padovan 
35571da177e4SLinus Torvalds 	if (conn) {
35586ed58ec5SVille Tervo 		int cnt, q;
35596ed58ec5SVille Tervo 
35606ed58ec5SVille Tervo 		switch (conn->type) {
35616ed58ec5SVille Tervo 		case ACL_LINK:
35626ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
35636ed58ec5SVille Tervo 			break;
35646ed58ec5SVille Tervo 		case SCO_LINK:
35656ed58ec5SVille Tervo 		case ESCO_LINK:
35666ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
35676ed58ec5SVille Tervo 			break;
35686ed58ec5SVille Tervo 		case LE_LINK:
35696ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
35706ed58ec5SVille Tervo 			break;
35716ed58ec5SVille Tervo 		default:
35726ed58ec5SVille Tervo 			cnt = 0;
35736ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
35746ed58ec5SVille Tervo 		}
35756ed58ec5SVille Tervo 
35766ed58ec5SVille Tervo 		q = cnt / num;
35771da177e4SLinus Torvalds 		*quote = q ? q : 1;
35781da177e4SLinus Torvalds 	} else
35791da177e4SLinus Torvalds 		*quote = 0;
35801da177e4SLinus Torvalds 
35811da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
35821da177e4SLinus Torvalds 	return conn;
35831da177e4SLinus Torvalds }
35841da177e4SLinus Torvalds 
35856039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
35861da177e4SLinus Torvalds {
35871da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
35881da177e4SLinus Torvalds 	struct hci_conn *c;
35891da177e4SLinus Torvalds 
3590bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
35911da177e4SLinus Torvalds 
3592bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3593bf4c6325SGustavo F. Padovan 
35941da177e4SLinus Torvalds 	/* Kill stalled connections */
3595bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
3596bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
35976ed93dc6SAndrei Emeltchenko 			BT_ERR("%s killing stalled connection %pMR",
35986ed93dc6SAndrei Emeltchenko 			       hdev->name, &c->dst);
3599bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
36001da177e4SLinus Torvalds 		}
36011da177e4SLinus Torvalds 	}
3602bf4c6325SGustavo F. Padovan 
3603bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
36041da177e4SLinus Torvalds }
36051da177e4SLinus Torvalds 
36066039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
360773d80debSLuiz Augusto von Dentz 				      int *quote)
360873d80debSLuiz Augusto von Dentz {
360973d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
361073d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
3611abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
361273d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
361373d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
361473d80debSLuiz Augusto von Dentz 
361573d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
361673d80debSLuiz Augusto von Dentz 
3617bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3618bf4c6325SGustavo F. Padovan 
3619bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
362073d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
362173d80debSLuiz Augusto von Dentz 
362273d80debSLuiz Augusto von Dentz 		if (conn->type != type)
362373d80debSLuiz Augusto von Dentz 			continue;
362473d80debSLuiz Augusto von Dentz 
362573d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
362673d80debSLuiz Augusto von Dentz 			continue;
362773d80debSLuiz Augusto von Dentz 
362873d80debSLuiz Augusto von Dentz 		conn_num++;
362973d80debSLuiz Augusto von Dentz 
36308192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
363173d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
363273d80debSLuiz Augusto von Dentz 
363373d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
363473d80debSLuiz Augusto von Dentz 				continue;
363573d80debSLuiz Augusto von Dentz 
363673d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
363773d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
363873d80debSLuiz Augusto von Dentz 				continue;
363973d80debSLuiz Augusto von Dentz 
364073d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
364173d80debSLuiz Augusto von Dentz 				num = 0;
364273d80debSLuiz Augusto von Dentz 				min = ~0;
364373d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
364473d80debSLuiz Augusto von Dentz 			}
364573d80debSLuiz Augusto von Dentz 
364673d80debSLuiz Augusto von Dentz 			num++;
364773d80debSLuiz Augusto von Dentz 
364873d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
364973d80debSLuiz Augusto von Dentz 				min  = conn->sent;
365073d80debSLuiz Augusto von Dentz 				chan = tmp;
365173d80debSLuiz Augusto von Dentz 			}
365273d80debSLuiz Augusto von Dentz 		}
365373d80debSLuiz Augusto von Dentz 
365473d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
365573d80debSLuiz Augusto von Dentz 			break;
365673d80debSLuiz Augusto von Dentz 	}
365773d80debSLuiz Augusto von Dentz 
3658bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3659bf4c6325SGustavo F. Padovan 
366073d80debSLuiz Augusto von Dentz 	if (!chan)
366173d80debSLuiz Augusto von Dentz 		return NULL;
366273d80debSLuiz Augusto von Dentz 
366373d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
366473d80debSLuiz Augusto von Dentz 	case ACL_LINK:
366573d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
366673d80debSLuiz Augusto von Dentz 		break;
3667bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
3668bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
3669bd1eb66bSAndrei Emeltchenko 		break;
367073d80debSLuiz Augusto von Dentz 	case SCO_LINK:
367173d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
367273d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
367373d80debSLuiz Augusto von Dentz 		break;
367473d80debSLuiz Augusto von Dentz 	case LE_LINK:
367573d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
367673d80debSLuiz Augusto von Dentz 		break;
367773d80debSLuiz Augusto von Dentz 	default:
367873d80debSLuiz Augusto von Dentz 		cnt = 0;
367973d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
368073d80debSLuiz Augusto von Dentz 	}
368173d80debSLuiz Augusto von Dentz 
368273d80debSLuiz Augusto von Dentz 	q = cnt / num;
368373d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
368473d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
368573d80debSLuiz Augusto von Dentz 	return chan;
368673d80debSLuiz Augusto von Dentz }
368773d80debSLuiz Augusto von Dentz 
368802b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
368902b20f0bSLuiz Augusto von Dentz {
369002b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
369102b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
369202b20f0bSLuiz Augusto von Dentz 	int num = 0;
369302b20f0bSLuiz Augusto von Dentz 
369402b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
369502b20f0bSLuiz Augusto von Dentz 
3696bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3697bf4c6325SGustavo F. Padovan 
3698bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
369902b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
370002b20f0bSLuiz Augusto von Dentz 
370102b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
370202b20f0bSLuiz Augusto von Dentz 			continue;
370302b20f0bSLuiz Augusto von Dentz 
370402b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
370502b20f0bSLuiz Augusto von Dentz 			continue;
370602b20f0bSLuiz Augusto von Dentz 
370702b20f0bSLuiz Augusto von Dentz 		num++;
370802b20f0bSLuiz Augusto von Dentz 
37098192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
371002b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
371102b20f0bSLuiz Augusto von Dentz 
371202b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
371302b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
371402b20f0bSLuiz Augusto von Dentz 				continue;
371502b20f0bSLuiz Augusto von Dentz 			}
371602b20f0bSLuiz Augusto von Dentz 
371702b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
371802b20f0bSLuiz Augusto von Dentz 				continue;
371902b20f0bSLuiz Augusto von Dentz 
372002b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
372102b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
372202b20f0bSLuiz Augusto von Dentz 				continue;
372302b20f0bSLuiz Augusto von Dentz 
372402b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
372502b20f0bSLuiz Augusto von Dentz 
372602b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
372702b20f0bSLuiz Augusto von Dentz 			       skb->priority);
372802b20f0bSLuiz Augusto von Dentz 		}
372902b20f0bSLuiz Augusto von Dentz 
373002b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
373102b20f0bSLuiz Augusto von Dentz 			break;
373202b20f0bSLuiz Augusto von Dentz 	}
3733bf4c6325SGustavo F. Padovan 
3734bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3735bf4c6325SGustavo F. Padovan 
373602b20f0bSLuiz Augusto von Dentz }
373702b20f0bSLuiz Augusto von Dentz 
3738b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
3739b71d385aSAndrei Emeltchenko {
3740b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
3741b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
3742b71d385aSAndrei Emeltchenko }
3743b71d385aSAndrei Emeltchenko 
37446039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
37451da177e4SLinus Torvalds {
3746d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
37471da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
37481da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
374963d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
37505f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
3751bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
37521da177e4SLinus Torvalds 	}
375363d2bc1bSAndrei Emeltchenko }
37541da177e4SLinus Torvalds 
37556039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
375663d2bc1bSAndrei Emeltchenko {
375763d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
375863d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
375963d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
376063d2bc1bSAndrei Emeltchenko 	int quote;
376163d2bc1bSAndrei Emeltchenko 
376263d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
376304837f64SMarcel Holtmann 
376473d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
376573d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
3766ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3767ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
376873d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
376973d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
377073d80debSLuiz Augusto von Dentz 
3771ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3772ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3773ec1cce24SLuiz Augusto von Dentz 				break;
3774ec1cce24SLuiz Augusto von Dentz 
3775ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3776ec1cce24SLuiz Augusto von Dentz 
377773d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
377873d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
377904837f64SMarcel Holtmann 
378057d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
37811da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
37821da177e4SLinus Torvalds 
37831da177e4SLinus Torvalds 			hdev->acl_cnt--;
378473d80debSLuiz Augusto von Dentz 			chan->sent++;
378573d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
37861da177e4SLinus Torvalds 		}
37871da177e4SLinus Torvalds 	}
378802b20f0bSLuiz Augusto von Dentz 
378902b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
379002b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
37911da177e4SLinus Torvalds }
37921da177e4SLinus Torvalds 
37936039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
3794b71d385aSAndrei Emeltchenko {
379563d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
3796b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
3797b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
3798b71d385aSAndrei Emeltchenko 	int quote;
3799bd1eb66bSAndrei Emeltchenko 	u8 type;
3800b71d385aSAndrei Emeltchenko 
380163d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
3802b71d385aSAndrei Emeltchenko 
3803bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3804bd1eb66bSAndrei Emeltchenko 
3805bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
3806bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
3807bd1eb66bSAndrei Emeltchenko 	else
3808bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
3809bd1eb66bSAndrei Emeltchenko 
3810b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
3811bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
3812b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
3813b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
3814b71d385aSAndrei Emeltchenko 			int blocks;
3815b71d385aSAndrei Emeltchenko 
3816b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
3817b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
3818b71d385aSAndrei Emeltchenko 
3819b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
3820b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
3821b71d385aSAndrei Emeltchenko 				break;
3822b71d385aSAndrei Emeltchenko 
3823b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
3824b71d385aSAndrei Emeltchenko 
3825b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
3826b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
3827b71d385aSAndrei Emeltchenko 				return;
3828b71d385aSAndrei Emeltchenko 
3829b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
3830b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
3831b71d385aSAndrei Emeltchenko 
383257d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
3833b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
3834b71d385aSAndrei Emeltchenko 
3835b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
3836b71d385aSAndrei Emeltchenko 			quote -= blocks;
3837b71d385aSAndrei Emeltchenko 
3838b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
3839b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
3840b71d385aSAndrei Emeltchenko 		}
3841b71d385aSAndrei Emeltchenko 	}
3842b71d385aSAndrei Emeltchenko 
3843b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
3844bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
3845b71d385aSAndrei Emeltchenko }
3846b71d385aSAndrei Emeltchenko 
38476039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
3848b71d385aSAndrei Emeltchenko {
3849b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
3850b71d385aSAndrei Emeltchenko 
3851bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
3852bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR)
3853bd1eb66bSAndrei Emeltchenko 		return;
3854bd1eb66bSAndrei Emeltchenko 
3855bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
3856bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
3857b71d385aSAndrei Emeltchenko 		return;
3858b71d385aSAndrei Emeltchenko 
3859b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
3860b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
3861b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
3862b71d385aSAndrei Emeltchenko 		break;
3863b71d385aSAndrei Emeltchenko 
3864b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
3865b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
3866b71d385aSAndrei Emeltchenko 		break;
3867b71d385aSAndrei Emeltchenko 	}
3868b71d385aSAndrei Emeltchenko }
3869b71d385aSAndrei Emeltchenko 
38701da177e4SLinus Torvalds /* Schedule SCO */
38716039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev)
38721da177e4SLinus Torvalds {
38731da177e4SLinus Torvalds 	struct hci_conn *conn;
38741da177e4SLinus Torvalds 	struct sk_buff *skb;
38751da177e4SLinus Torvalds 	int quote;
38761da177e4SLinus Torvalds 
38771da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
38781da177e4SLinus Torvalds 
387952087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
388052087a79SLuiz Augusto von Dentz 		return;
388152087a79SLuiz Augusto von Dentz 
38821da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
38831da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
38841da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
388557d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
38861da177e4SLinus Torvalds 
38871da177e4SLinus Torvalds 			conn->sent++;
38881da177e4SLinus Torvalds 			if (conn->sent == ~0)
38891da177e4SLinus Torvalds 				conn->sent = 0;
38901da177e4SLinus Torvalds 		}
38911da177e4SLinus Torvalds 	}
38921da177e4SLinus Torvalds }
38931da177e4SLinus Torvalds 
38946039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev)
3895b6a0dc82SMarcel Holtmann {
3896b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
3897b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
3898b6a0dc82SMarcel Holtmann 	int quote;
3899b6a0dc82SMarcel Holtmann 
3900b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
3901b6a0dc82SMarcel Holtmann 
390252087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
390352087a79SLuiz Augusto von Dentz 		return;
390452087a79SLuiz Augusto von Dentz 
39058fc9ced3SGustavo Padovan 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
39068fc9ced3SGustavo Padovan 						     &quote))) {
3907b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
3908b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
390957d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
3910b6a0dc82SMarcel Holtmann 
3911b6a0dc82SMarcel Holtmann 			conn->sent++;
3912b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
3913b6a0dc82SMarcel Holtmann 				conn->sent = 0;
3914b6a0dc82SMarcel Holtmann 		}
3915b6a0dc82SMarcel Holtmann 	}
3916b6a0dc82SMarcel Holtmann }
3917b6a0dc82SMarcel Holtmann 
39186039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
39196ed58ec5SVille Tervo {
392073d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
39216ed58ec5SVille Tervo 	struct sk_buff *skb;
392202b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
39236ed58ec5SVille Tervo 
39246ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
39256ed58ec5SVille Tervo 
392652087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
392752087a79SLuiz Augusto von Dentz 		return;
392852087a79SLuiz Augusto von Dentz 
3929d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
39306ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
39316ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
3932bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
39336ed58ec5SVille Tervo 		    time_after(jiffies, hdev->le_last_tx + HZ * 45))
3934bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
39356ed58ec5SVille Tervo 	}
39366ed58ec5SVille Tervo 
39376ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
393802b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
393973d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
3940ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
3941ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
394273d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
394373d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
39446ed58ec5SVille Tervo 
3945ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
3946ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
3947ec1cce24SLuiz Augusto von Dentz 				break;
3948ec1cce24SLuiz Augusto von Dentz 
3949ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
3950ec1cce24SLuiz Augusto von Dentz 
395157d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
39526ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
39536ed58ec5SVille Tervo 
39546ed58ec5SVille Tervo 			cnt--;
395573d80debSLuiz Augusto von Dentz 			chan->sent++;
395673d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
39576ed58ec5SVille Tervo 		}
39586ed58ec5SVille Tervo 	}
395973d80debSLuiz Augusto von Dentz 
39606ed58ec5SVille Tervo 	if (hdev->le_pkts)
39616ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
39626ed58ec5SVille Tervo 	else
39636ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
396402b20f0bSLuiz Augusto von Dentz 
396502b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
396602b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
39676ed58ec5SVille Tervo }
39686ed58ec5SVille Tervo 
39693eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
39701da177e4SLinus Torvalds {
39713eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
39721da177e4SLinus Torvalds 	struct sk_buff *skb;
39731da177e4SLinus Torvalds 
39746ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
39756ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
39761da177e4SLinus Torvalds 
3977d7a5a11dSMarcel Holtmann 	if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
39781da177e4SLinus Torvalds 		/* Schedule queues and send stuff to HCI driver */
39791da177e4SLinus Torvalds 		hci_sched_acl(hdev);
39801da177e4SLinus Torvalds 		hci_sched_sco(hdev);
3981b6a0dc82SMarcel Holtmann 		hci_sched_esco(hdev);
39826ed58ec5SVille Tervo 		hci_sched_le(hdev);
398352de599eSMarcel Holtmann 	}
39846ed58ec5SVille Tervo 
39851da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
39861da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
398757d17d70SMarcel Holtmann 		hci_send_frame(hdev, skb);
39881da177e4SLinus Torvalds }
39891da177e4SLinus Torvalds 
399025985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
39911da177e4SLinus Torvalds 
39921da177e4SLinus Torvalds /* ACL data packet */
39936039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
39941da177e4SLinus Torvalds {
39951da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
39961da177e4SLinus Torvalds 	struct hci_conn *conn;
39971da177e4SLinus Torvalds 	__u16 handle, flags;
39981da177e4SLinus Torvalds 
39991da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
40001da177e4SLinus Torvalds 
40011da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
40021da177e4SLinus Torvalds 	flags  = hci_flags(handle);
40031da177e4SLinus Torvalds 	handle = hci_handle(handle);
40041da177e4SLinus Torvalds 
4005f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
4006a8c5fb1aSGustavo Padovan 	       handle, flags);
40071da177e4SLinus Torvalds 
40081da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
40091da177e4SLinus Torvalds 
40101da177e4SLinus Torvalds 	hci_dev_lock(hdev);
40111da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
40121da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
40131da177e4SLinus Torvalds 
40141da177e4SLinus Torvalds 	if (conn) {
401565983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
401604837f64SMarcel Holtmann 
40171da177e4SLinus Torvalds 		/* Send to upper protocol */
4018686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
40191da177e4SLinus Torvalds 		return;
40201da177e4SLinus Torvalds 	} else {
40211da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
40221da177e4SLinus Torvalds 		       hdev->name, handle);
40231da177e4SLinus Torvalds 	}
40241da177e4SLinus Torvalds 
40251da177e4SLinus Torvalds 	kfree_skb(skb);
40261da177e4SLinus Torvalds }
40271da177e4SLinus Torvalds 
40281da177e4SLinus Torvalds /* SCO data packet */
40296039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
40301da177e4SLinus Torvalds {
40311da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
40321da177e4SLinus Torvalds 	struct hci_conn *conn;
40331da177e4SLinus Torvalds 	__u16 handle;
40341da177e4SLinus Torvalds 
40351da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
40361da177e4SLinus Torvalds 
40371da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
40381da177e4SLinus Torvalds 
4039f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle);
40401da177e4SLinus Torvalds 
40411da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
40421da177e4SLinus Torvalds 
40431da177e4SLinus Torvalds 	hci_dev_lock(hdev);
40441da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
40451da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
40461da177e4SLinus Torvalds 
40471da177e4SLinus Torvalds 	if (conn) {
40481da177e4SLinus Torvalds 		/* Send to upper protocol */
4049686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
40501da177e4SLinus Torvalds 		return;
40511da177e4SLinus Torvalds 	} else {
40521da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
40531da177e4SLinus Torvalds 		       hdev->name, handle);
40541da177e4SLinus Torvalds 	}
40551da177e4SLinus Torvalds 
40561da177e4SLinus Torvalds 	kfree_skb(skb);
40571da177e4SLinus Torvalds }
40581da177e4SLinus Torvalds 
40599238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
40609238f36aSJohan Hedberg {
40619238f36aSJohan Hedberg 	struct sk_buff *skb;
40629238f36aSJohan Hedberg 
40639238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
40649238f36aSJohan Hedberg 	if (!skb)
40659238f36aSJohan Hedberg 		return true;
40669238f36aSJohan Hedberg 
4067db6e3e8dSJohan Hedberg 	return bt_cb(skb)->req.start;
40689238f36aSJohan Hedberg }
40699238f36aSJohan Hedberg 
407042c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
407142c6b129SJohan Hedberg {
407242c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
407342c6b129SJohan Hedberg 	struct sk_buff *skb;
407442c6b129SJohan Hedberg 	u16 opcode;
407542c6b129SJohan Hedberg 
407642c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
407742c6b129SJohan Hedberg 		return;
407842c6b129SJohan Hedberg 
407942c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
408042c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
408142c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
408242c6b129SJohan Hedberg 		return;
408342c6b129SJohan Hedberg 
408442c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
408542c6b129SJohan Hedberg 	if (!skb)
408642c6b129SJohan Hedberg 		return;
408742c6b129SJohan Hedberg 
408842c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
408942c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
409042c6b129SJohan Hedberg }
409142c6b129SJohan Hedberg 
4092e6214487SJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status,
4093e6214487SJohan Hedberg 			  hci_req_complete_t *req_complete,
4094e6214487SJohan Hedberg 			  hci_req_complete_skb_t *req_complete_skb)
40959238f36aSJohan Hedberg {
40969238f36aSJohan Hedberg 	struct sk_buff *skb;
40979238f36aSJohan Hedberg 	unsigned long flags;
40989238f36aSJohan Hedberg 
40999238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
41009238f36aSJohan Hedberg 
410142c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
410242c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
41039238f36aSJohan Hedberg 	 */
410442c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
410542c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
410642c6b129SJohan Hedberg 		 * reset complete event during init and any pending
410742c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
410842c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
410942c6b129SJohan Hedberg 		 * command.
411042c6b129SJohan Hedberg 		 */
411142c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
411242c6b129SJohan Hedberg 			hci_resend_last(hdev);
411342c6b129SJohan Hedberg 
41149238f36aSJohan Hedberg 		return;
411542c6b129SJohan Hedberg 	}
41169238f36aSJohan Hedberg 
41179238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
41189238f36aSJohan Hedberg 	 * this request the request is not yet complete.
41199238f36aSJohan Hedberg 	 */
41209238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
41219238f36aSJohan Hedberg 		return;
41229238f36aSJohan Hedberg 
41239238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
41249238f36aSJohan Hedberg 	 * callback would be found in hdev->sent_cmd instead of the
41259238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
41269238f36aSJohan Hedberg 	 */
4127e6214487SJohan Hedberg 	if (bt_cb(hdev->sent_cmd)->req.complete) {
4128e6214487SJohan Hedberg 		*req_complete = bt_cb(hdev->sent_cmd)->req.complete;
4129e6214487SJohan Hedberg 		return;
41309238f36aSJohan Hedberg 	}
4131e6214487SJohan Hedberg 
4132e6214487SJohan Hedberg 	if (bt_cb(hdev->sent_cmd)->req.complete_skb) {
4133e6214487SJohan Hedberg 		*req_complete_skb = bt_cb(hdev->sent_cmd)->req.complete_skb;
4134e6214487SJohan Hedberg 		return;
413553e21fbcSJohan Hedberg 	}
41369238f36aSJohan Hedberg 
41379238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
41389238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
41399238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
4140db6e3e8dSJohan Hedberg 		if (bt_cb(skb)->req.start) {
41419238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
41429238f36aSJohan Hedberg 			break;
41439238f36aSJohan Hedberg 		}
41449238f36aSJohan Hedberg 
4145e6214487SJohan Hedberg 		*req_complete = bt_cb(skb)->req.complete;
4146e6214487SJohan Hedberg 		*req_complete_skb = bt_cb(skb)->req.complete_skb;
41479238f36aSJohan Hedberg 		kfree_skb(skb);
41489238f36aSJohan Hedberg 	}
41499238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
41509238f36aSJohan Hedberg }
41519238f36aSJohan Hedberg 
4152b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
41531da177e4SLinus Torvalds {
4154b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
41551da177e4SLinus Torvalds 	struct sk_buff *skb;
41561da177e4SLinus Torvalds 
41571da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
41581da177e4SLinus Torvalds 
41591da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
4160cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
4161cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
4162cd82e61cSMarcel Holtmann 
41631da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
41641da177e4SLinus Torvalds 			/* Send copy to the sockets */
4165470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
41661da177e4SLinus Torvalds 		}
41671da177e4SLinus Torvalds 
4168d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
41691da177e4SLinus Torvalds 			kfree_skb(skb);
41701da177e4SLinus Torvalds 			continue;
41711da177e4SLinus Torvalds 		}
41721da177e4SLinus Torvalds 
41731da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
41741da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
41750d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
41761da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
41771da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
41781da177e4SLinus Torvalds 				kfree_skb(skb);
41791da177e4SLinus Torvalds 				continue;
41803ff50b79SStephen Hemminger 			}
41811da177e4SLinus Torvalds 		}
41821da177e4SLinus Torvalds 
41831da177e4SLinus Torvalds 		/* Process frame */
41840d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
41851da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
4186b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
41871da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
41881da177e4SLinus Torvalds 			break;
41891da177e4SLinus Torvalds 
41901da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
41911da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
41921da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
41931da177e4SLinus Torvalds 			break;
41941da177e4SLinus Torvalds 
41951da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
41961da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
41971da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
41981da177e4SLinus Torvalds 			break;
41991da177e4SLinus Torvalds 
42001da177e4SLinus Torvalds 		default:
42011da177e4SLinus Torvalds 			kfree_skb(skb);
42021da177e4SLinus Torvalds 			break;
42031da177e4SLinus Torvalds 		}
42041da177e4SLinus Torvalds 	}
42051da177e4SLinus Torvalds }
42061da177e4SLinus Torvalds 
4207c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
42081da177e4SLinus Torvalds {
4209c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
42101da177e4SLinus Torvalds 	struct sk_buff *skb;
42111da177e4SLinus Torvalds 
42122104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
42132104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
42141da177e4SLinus Torvalds 
42151da177e4SLinus Torvalds 	/* Send queued commands */
42165a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
42175a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
42185a08ecceSAndrei Emeltchenko 		if (!skb)
42195a08ecceSAndrei Emeltchenko 			return;
42205a08ecceSAndrei Emeltchenko 
42211da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
42221da177e4SLinus Torvalds 
4223a675d7f1SMarcel Holtmann 		hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
422470f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
42251da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
422657d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
42277bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
422865cc2b49SMarcel Holtmann 				cancel_delayed_work(&hdev->cmd_timer);
42297bdb8a5cSSzymon Janc 			else
423065cc2b49SMarcel Holtmann 				schedule_delayed_work(&hdev->cmd_timer,
423165cc2b49SMarcel Holtmann 						      HCI_CMD_TIMEOUT);
42321da177e4SLinus Torvalds 		} else {
42331da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
4234c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
42351da177e4SLinus Torvalds 		}
42361da177e4SLinus Torvalds 	}
42371da177e4SLinus Torvalds }
4238