xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 711eafe3)
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 
40970c4e46SJohan Hedberg #include "smp.h"
41970c4e46SJohan Hedberg 
42b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work);
43c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work);
443eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work);
451da177e4SLinus Torvalds 
461da177e4SLinus Torvalds /* HCI device list */
471da177e4SLinus Torvalds LIST_HEAD(hci_dev_list);
481da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock);
491da177e4SLinus Torvalds 
501da177e4SLinus Torvalds /* HCI callback list */
511da177e4SLinus Torvalds LIST_HEAD(hci_cb_list);
521da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock);
531da177e4SLinus Torvalds 
543df92b31SSasha Levin /* HCI ID Numbering */
553df92b31SSasha Levin static DEFINE_IDA(hci_index_ida);
563df92b31SSasha Levin 
57899de765SMarcel Holtmann /* ----- HCI requests ----- */
58899de765SMarcel Holtmann 
59899de765SMarcel Holtmann #define HCI_REQ_DONE	  0
60899de765SMarcel Holtmann #define HCI_REQ_PEND	  1
61899de765SMarcel Holtmann #define HCI_REQ_CANCELED  2
62899de765SMarcel Holtmann 
63899de765SMarcel Holtmann #define hci_req_lock(d)		mutex_lock(&d->req_lock)
64899de765SMarcel Holtmann #define hci_req_unlock(d)	mutex_unlock(&d->req_lock)
65899de765SMarcel Holtmann 
661da177e4SLinus Torvalds /* ---- HCI notifications ---- */
671da177e4SLinus Torvalds 
686516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event)
691da177e4SLinus Torvalds {
70040030efSMarcel Holtmann 	hci_sock_dev_event(hdev, event);
711da177e4SLinus Torvalds }
721da177e4SLinus Torvalds 
73baf27f6eSMarcel Holtmann /* ---- HCI debugfs entries ---- */
74baf27f6eSMarcel Holtmann 
754b4148e9SMarcel Holtmann static ssize_t dut_mode_read(struct file *file, char __user *user_buf,
764b4148e9SMarcel Holtmann 			     size_t count, loff_t *ppos)
774b4148e9SMarcel Holtmann {
784b4148e9SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
794b4148e9SMarcel Holtmann 	char buf[3];
804b4148e9SMarcel Holtmann 
81111902f7SMarcel Holtmann 	buf[0] = test_bit(HCI_DUT_MODE, &hdev->dbg_flags) ? 'Y': 'N';
824b4148e9SMarcel Holtmann 	buf[1] = '\n';
834b4148e9SMarcel Holtmann 	buf[2] = '\0';
844b4148e9SMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
854b4148e9SMarcel Holtmann }
864b4148e9SMarcel Holtmann 
874b4148e9SMarcel Holtmann static ssize_t dut_mode_write(struct file *file, const char __user *user_buf,
884b4148e9SMarcel Holtmann 			      size_t count, loff_t *ppos)
894b4148e9SMarcel Holtmann {
904b4148e9SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
914b4148e9SMarcel Holtmann 	struct sk_buff *skb;
924b4148e9SMarcel Holtmann 	char buf[32];
934b4148e9SMarcel Holtmann 	size_t buf_size = min(count, (sizeof(buf)-1));
944b4148e9SMarcel Holtmann 	bool enable;
954b4148e9SMarcel Holtmann 	int err;
964b4148e9SMarcel Holtmann 
974b4148e9SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
984b4148e9SMarcel Holtmann 		return -ENETDOWN;
994b4148e9SMarcel Holtmann 
1004b4148e9SMarcel Holtmann 	if (copy_from_user(buf, user_buf, buf_size))
1014b4148e9SMarcel Holtmann 		return -EFAULT;
1024b4148e9SMarcel Holtmann 
1034b4148e9SMarcel Holtmann 	buf[buf_size] = '\0';
1044b4148e9SMarcel Holtmann 	if (strtobool(buf, &enable))
1054b4148e9SMarcel Holtmann 		return -EINVAL;
1064b4148e9SMarcel Holtmann 
107111902f7SMarcel Holtmann 	if (enable == test_bit(HCI_DUT_MODE, &hdev->dbg_flags))
1084b4148e9SMarcel Holtmann 		return -EALREADY;
1094b4148e9SMarcel Holtmann 
1104b4148e9SMarcel Holtmann 	hci_req_lock(hdev);
1114b4148e9SMarcel Holtmann 	if (enable)
1124b4148e9SMarcel Holtmann 		skb = __hci_cmd_sync(hdev, HCI_OP_ENABLE_DUT_MODE, 0, NULL,
1134b4148e9SMarcel Holtmann 				     HCI_CMD_TIMEOUT);
1144b4148e9SMarcel Holtmann 	else
1154b4148e9SMarcel Holtmann 		skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL,
1164b4148e9SMarcel Holtmann 				     HCI_CMD_TIMEOUT);
1174b4148e9SMarcel Holtmann 	hci_req_unlock(hdev);
1184b4148e9SMarcel Holtmann 
1194b4148e9SMarcel Holtmann 	if (IS_ERR(skb))
1204b4148e9SMarcel Holtmann 		return PTR_ERR(skb);
1214b4148e9SMarcel Holtmann 
1224b4148e9SMarcel Holtmann 	err = -bt_to_errno(skb->data[0]);
1234b4148e9SMarcel Holtmann 	kfree_skb(skb);
1244b4148e9SMarcel Holtmann 
1254b4148e9SMarcel Holtmann 	if (err < 0)
1264b4148e9SMarcel Holtmann 		return err;
1274b4148e9SMarcel Holtmann 
128111902f7SMarcel Holtmann 	change_bit(HCI_DUT_MODE, &hdev->dbg_flags);
1294b4148e9SMarcel Holtmann 
1304b4148e9SMarcel Holtmann 	return count;
1314b4148e9SMarcel Holtmann }
1324b4148e9SMarcel Holtmann 
1334b4148e9SMarcel Holtmann static const struct file_operations dut_mode_fops = {
1344b4148e9SMarcel Holtmann 	.open		= simple_open,
1354b4148e9SMarcel Holtmann 	.read		= dut_mode_read,
1364b4148e9SMarcel Holtmann 	.write		= dut_mode_write,
1374b4148e9SMarcel Holtmann 	.llseek		= default_llseek,
1384b4148e9SMarcel Holtmann };
1394b4148e9SMarcel Holtmann 
140dfb826a8SMarcel Holtmann static int features_show(struct seq_file *f, void *ptr)
141dfb826a8SMarcel Holtmann {
142dfb826a8SMarcel Holtmann 	struct hci_dev *hdev = f->private;
143dfb826a8SMarcel Holtmann 	u8 p;
144dfb826a8SMarcel Holtmann 
145dfb826a8SMarcel Holtmann 	hci_dev_lock(hdev);
146dfb826a8SMarcel Holtmann 	for (p = 0; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
147cfbb2b5bSMarcel Holtmann 		seq_printf(f, "%2u: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
148dfb826a8SMarcel Holtmann 			   "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", p,
149dfb826a8SMarcel Holtmann 			   hdev->features[p][0], hdev->features[p][1],
150dfb826a8SMarcel Holtmann 			   hdev->features[p][2], hdev->features[p][3],
151dfb826a8SMarcel Holtmann 			   hdev->features[p][4], hdev->features[p][5],
152dfb826a8SMarcel Holtmann 			   hdev->features[p][6], hdev->features[p][7]);
153dfb826a8SMarcel Holtmann 	}
154cfbb2b5bSMarcel Holtmann 	if (lmp_le_capable(hdev))
155cfbb2b5bSMarcel Holtmann 		seq_printf(f, "LE: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
156cfbb2b5bSMarcel Holtmann 			   "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n",
157cfbb2b5bSMarcel Holtmann 			   hdev->le_features[0], hdev->le_features[1],
158cfbb2b5bSMarcel Holtmann 			   hdev->le_features[2], hdev->le_features[3],
159cfbb2b5bSMarcel Holtmann 			   hdev->le_features[4], hdev->le_features[5],
160cfbb2b5bSMarcel Holtmann 			   hdev->le_features[6], hdev->le_features[7]);
161dfb826a8SMarcel Holtmann 	hci_dev_unlock(hdev);
162dfb826a8SMarcel Holtmann 
163dfb826a8SMarcel Holtmann 	return 0;
164dfb826a8SMarcel Holtmann }
165dfb826a8SMarcel Holtmann 
166dfb826a8SMarcel Holtmann static int features_open(struct inode *inode, struct file *file)
167dfb826a8SMarcel Holtmann {
168dfb826a8SMarcel Holtmann 	return single_open(file, features_show, inode->i_private);
169dfb826a8SMarcel Holtmann }
170dfb826a8SMarcel Holtmann 
171dfb826a8SMarcel Holtmann static const struct file_operations features_fops = {
172dfb826a8SMarcel Holtmann 	.open		= features_open,
173dfb826a8SMarcel Holtmann 	.read		= seq_read,
174dfb826a8SMarcel Holtmann 	.llseek		= seq_lseek,
175dfb826a8SMarcel Holtmann 	.release	= single_release,
176dfb826a8SMarcel Holtmann };
177dfb826a8SMarcel Holtmann 
17870afe0b8SMarcel Holtmann static int blacklist_show(struct seq_file *f, void *p)
17970afe0b8SMarcel Holtmann {
18070afe0b8SMarcel Holtmann 	struct hci_dev *hdev = f->private;
18170afe0b8SMarcel Holtmann 	struct bdaddr_list *b;
18270afe0b8SMarcel Holtmann 
18370afe0b8SMarcel Holtmann 	hci_dev_lock(hdev);
18470afe0b8SMarcel Holtmann 	list_for_each_entry(b, &hdev->blacklist, list)
185b25f0785SMarcel Holtmann 		seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type);
18670afe0b8SMarcel Holtmann 	hci_dev_unlock(hdev);
18770afe0b8SMarcel Holtmann 
18870afe0b8SMarcel Holtmann 	return 0;
18970afe0b8SMarcel Holtmann }
19070afe0b8SMarcel Holtmann 
19170afe0b8SMarcel Holtmann static int blacklist_open(struct inode *inode, struct file *file)
19270afe0b8SMarcel Holtmann {
19370afe0b8SMarcel Holtmann 	return single_open(file, blacklist_show, inode->i_private);
19470afe0b8SMarcel Holtmann }
19570afe0b8SMarcel Holtmann 
19670afe0b8SMarcel Holtmann static const struct file_operations blacklist_fops = {
19770afe0b8SMarcel Holtmann 	.open		= blacklist_open,
19870afe0b8SMarcel Holtmann 	.read		= seq_read,
19970afe0b8SMarcel Holtmann 	.llseek		= seq_lseek,
20070afe0b8SMarcel Holtmann 	.release	= single_release,
20170afe0b8SMarcel Holtmann };
20270afe0b8SMarcel Holtmann 
2036659358eSJohan Hedberg static int whitelist_show(struct seq_file *f, void *p)
2046659358eSJohan Hedberg {
2056659358eSJohan Hedberg 	struct hci_dev *hdev = f->private;
2066659358eSJohan Hedberg 	struct bdaddr_list *b;
2076659358eSJohan Hedberg 
2086659358eSJohan Hedberg 	hci_dev_lock(hdev);
2096659358eSJohan Hedberg 	list_for_each_entry(b, &hdev->whitelist, list)
2106659358eSJohan Hedberg 		seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type);
2116659358eSJohan Hedberg 	hci_dev_unlock(hdev);
2126659358eSJohan Hedberg 
2136659358eSJohan Hedberg 	return 0;
2146659358eSJohan Hedberg }
2156659358eSJohan Hedberg 
2166659358eSJohan Hedberg static int whitelist_open(struct inode *inode, struct file *file)
2176659358eSJohan Hedberg {
2186659358eSJohan Hedberg 	return single_open(file, whitelist_show, inode->i_private);
2196659358eSJohan Hedberg }
2206659358eSJohan Hedberg 
2216659358eSJohan Hedberg static const struct file_operations whitelist_fops = {
2226659358eSJohan Hedberg 	.open		= whitelist_open,
2236659358eSJohan Hedberg 	.read		= seq_read,
2246659358eSJohan Hedberg 	.llseek		= seq_lseek,
2256659358eSJohan Hedberg 	.release	= single_release,
2266659358eSJohan Hedberg };
2276659358eSJohan Hedberg 
22847219839SMarcel Holtmann static int uuids_show(struct seq_file *f, void *p)
22947219839SMarcel Holtmann {
23047219839SMarcel Holtmann 	struct hci_dev *hdev = f->private;
23147219839SMarcel Holtmann 	struct bt_uuid *uuid;
23247219839SMarcel Holtmann 
23347219839SMarcel Holtmann 	hci_dev_lock(hdev);
23447219839SMarcel Holtmann 	list_for_each_entry(uuid, &hdev->uuids, list) {
23558f01aa9SMarcel Holtmann 		u8 i, val[16];
23647219839SMarcel Holtmann 
23758f01aa9SMarcel Holtmann 		/* The Bluetooth UUID values are stored in big endian,
23858f01aa9SMarcel Holtmann 		 * but with reversed byte order. So convert them into
23958f01aa9SMarcel Holtmann 		 * the right order for the %pUb modifier.
24058f01aa9SMarcel Holtmann 		 */
24158f01aa9SMarcel Holtmann 		for (i = 0; i < 16; i++)
24258f01aa9SMarcel Holtmann 			val[i] = uuid->uuid[15 - i];
24347219839SMarcel Holtmann 
24458f01aa9SMarcel Holtmann 		seq_printf(f, "%pUb\n", val);
24547219839SMarcel Holtmann 	}
24647219839SMarcel Holtmann 	hci_dev_unlock(hdev);
24747219839SMarcel Holtmann 
24847219839SMarcel Holtmann 	return 0;
24947219839SMarcel Holtmann }
25047219839SMarcel Holtmann 
25147219839SMarcel Holtmann static int uuids_open(struct inode *inode, struct file *file)
25247219839SMarcel Holtmann {
25347219839SMarcel Holtmann 	return single_open(file, uuids_show, inode->i_private);
25447219839SMarcel Holtmann }
25547219839SMarcel Holtmann 
25647219839SMarcel Holtmann static const struct file_operations uuids_fops = {
25747219839SMarcel Holtmann 	.open		= uuids_open,
25847219839SMarcel Holtmann 	.read		= seq_read,
25947219839SMarcel Holtmann 	.llseek		= seq_lseek,
26047219839SMarcel Holtmann 	.release	= single_release,
26147219839SMarcel Holtmann };
26247219839SMarcel Holtmann 
263baf27f6eSMarcel Holtmann static int inquiry_cache_show(struct seq_file *f, void *p)
264baf27f6eSMarcel Holtmann {
265baf27f6eSMarcel Holtmann 	struct hci_dev *hdev = f->private;
266baf27f6eSMarcel Holtmann 	struct discovery_state *cache = &hdev->discovery;
267baf27f6eSMarcel Holtmann 	struct inquiry_entry *e;
268baf27f6eSMarcel Holtmann 
269baf27f6eSMarcel Holtmann 	hci_dev_lock(hdev);
270baf27f6eSMarcel Holtmann 
271baf27f6eSMarcel Holtmann 	list_for_each_entry(e, &cache->all, all) {
272baf27f6eSMarcel Holtmann 		struct inquiry_data *data = &e->data;
273baf27f6eSMarcel Holtmann 		seq_printf(f, "%pMR %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n",
274baf27f6eSMarcel Holtmann 			   &data->bdaddr,
275baf27f6eSMarcel Holtmann 			   data->pscan_rep_mode, data->pscan_period_mode,
276baf27f6eSMarcel Holtmann 			   data->pscan_mode, data->dev_class[2],
277baf27f6eSMarcel Holtmann 			   data->dev_class[1], data->dev_class[0],
278baf27f6eSMarcel Holtmann 			   __le16_to_cpu(data->clock_offset),
279baf27f6eSMarcel Holtmann 			   data->rssi, data->ssp_mode, e->timestamp);
280baf27f6eSMarcel Holtmann 	}
281baf27f6eSMarcel Holtmann 
282baf27f6eSMarcel Holtmann 	hci_dev_unlock(hdev);
283baf27f6eSMarcel Holtmann 
284baf27f6eSMarcel Holtmann 	return 0;
285baf27f6eSMarcel Holtmann }
286baf27f6eSMarcel Holtmann 
287baf27f6eSMarcel Holtmann static int inquiry_cache_open(struct inode *inode, struct file *file)
288baf27f6eSMarcel Holtmann {
289baf27f6eSMarcel Holtmann 	return single_open(file, inquiry_cache_show, inode->i_private);
290baf27f6eSMarcel Holtmann }
291baf27f6eSMarcel Holtmann 
292baf27f6eSMarcel Holtmann static const struct file_operations inquiry_cache_fops = {
293baf27f6eSMarcel Holtmann 	.open		= inquiry_cache_open,
294baf27f6eSMarcel Holtmann 	.read		= seq_read,
295baf27f6eSMarcel Holtmann 	.llseek		= seq_lseek,
296baf27f6eSMarcel Holtmann 	.release	= single_release,
297baf27f6eSMarcel Holtmann };
298baf27f6eSMarcel Holtmann 
29902d08d15SMarcel Holtmann static int link_keys_show(struct seq_file *f, void *ptr)
30002d08d15SMarcel Holtmann {
30102d08d15SMarcel Holtmann 	struct hci_dev *hdev = f->private;
30202d08d15SMarcel Holtmann 	struct list_head *p, *n;
30302d08d15SMarcel Holtmann 
30402d08d15SMarcel Holtmann 	hci_dev_lock(hdev);
30502d08d15SMarcel Holtmann 	list_for_each_safe(p, n, &hdev->link_keys) {
30602d08d15SMarcel Holtmann 		struct link_key *key = list_entry(p, struct link_key, list);
30702d08d15SMarcel Holtmann 		seq_printf(f, "%pMR %u %*phN %u\n", &key->bdaddr, key->type,
30802d08d15SMarcel Holtmann 			   HCI_LINK_KEY_SIZE, key->val, key->pin_len);
30902d08d15SMarcel Holtmann 	}
31002d08d15SMarcel Holtmann 	hci_dev_unlock(hdev);
31102d08d15SMarcel Holtmann 
31202d08d15SMarcel Holtmann 	return 0;
31302d08d15SMarcel Holtmann }
31402d08d15SMarcel Holtmann 
31502d08d15SMarcel Holtmann static int link_keys_open(struct inode *inode, struct file *file)
31602d08d15SMarcel Holtmann {
31702d08d15SMarcel Holtmann 	return single_open(file, link_keys_show, inode->i_private);
31802d08d15SMarcel Holtmann }
31902d08d15SMarcel Holtmann 
32002d08d15SMarcel Holtmann static const struct file_operations link_keys_fops = {
32102d08d15SMarcel Holtmann 	.open		= link_keys_open,
32202d08d15SMarcel Holtmann 	.read		= seq_read,
32302d08d15SMarcel Holtmann 	.llseek		= seq_lseek,
32402d08d15SMarcel Holtmann 	.release	= single_release,
32502d08d15SMarcel Holtmann };
32602d08d15SMarcel Holtmann 
327babdbb3cSMarcel Holtmann static int dev_class_show(struct seq_file *f, void *ptr)
328babdbb3cSMarcel Holtmann {
329babdbb3cSMarcel Holtmann 	struct hci_dev *hdev = f->private;
330babdbb3cSMarcel Holtmann 
331babdbb3cSMarcel Holtmann 	hci_dev_lock(hdev);
332babdbb3cSMarcel Holtmann 	seq_printf(f, "0x%.2x%.2x%.2x\n", hdev->dev_class[2],
333babdbb3cSMarcel Holtmann 		   hdev->dev_class[1], hdev->dev_class[0]);
334babdbb3cSMarcel Holtmann 	hci_dev_unlock(hdev);
335babdbb3cSMarcel Holtmann 
336babdbb3cSMarcel Holtmann 	return 0;
337babdbb3cSMarcel Holtmann }
338babdbb3cSMarcel Holtmann 
339babdbb3cSMarcel Holtmann static int dev_class_open(struct inode *inode, struct file *file)
340babdbb3cSMarcel Holtmann {
341babdbb3cSMarcel Holtmann 	return single_open(file, dev_class_show, inode->i_private);
342babdbb3cSMarcel Holtmann }
343babdbb3cSMarcel Holtmann 
344babdbb3cSMarcel Holtmann static const struct file_operations dev_class_fops = {
345babdbb3cSMarcel Holtmann 	.open		= dev_class_open,
346babdbb3cSMarcel Holtmann 	.read		= seq_read,
347babdbb3cSMarcel Holtmann 	.llseek		= seq_lseek,
348babdbb3cSMarcel Holtmann 	.release	= single_release,
349babdbb3cSMarcel Holtmann };
350babdbb3cSMarcel Holtmann 
351041000b9SMarcel Holtmann static int voice_setting_get(void *data, u64 *val)
352041000b9SMarcel Holtmann {
353041000b9SMarcel Holtmann 	struct hci_dev *hdev = data;
354041000b9SMarcel Holtmann 
355041000b9SMarcel Holtmann 	hci_dev_lock(hdev);
356041000b9SMarcel Holtmann 	*val = hdev->voice_setting;
357041000b9SMarcel Holtmann 	hci_dev_unlock(hdev);
358041000b9SMarcel Holtmann 
359041000b9SMarcel Holtmann 	return 0;
360041000b9SMarcel Holtmann }
361041000b9SMarcel Holtmann 
362041000b9SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(voice_setting_fops, voice_setting_get,
363041000b9SMarcel Holtmann 			NULL, "0x%4.4llx\n");
364041000b9SMarcel Holtmann 
365ebd1e33bSMarcel Holtmann static int auto_accept_delay_set(void *data, u64 val)
366ebd1e33bSMarcel Holtmann {
367ebd1e33bSMarcel Holtmann 	struct hci_dev *hdev = data;
368ebd1e33bSMarcel Holtmann 
369ebd1e33bSMarcel Holtmann 	hci_dev_lock(hdev);
370ebd1e33bSMarcel Holtmann 	hdev->auto_accept_delay = val;
371ebd1e33bSMarcel Holtmann 	hci_dev_unlock(hdev);
372ebd1e33bSMarcel Holtmann 
373ebd1e33bSMarcel Holtmann 	return 0;
374ebd1e33bSMarcel Holtmann }
375ebd1e33bSMarcel Holtmann 
376ebd1e33bSMarcel Holtmann static int auto_accept_delay_get(void *data, u64 *val)
377ebd1e33bSMarcel Holtmann {
378ebd1e33bSMarcel Holtmann 	struct hci_dev *hdev = data;
379ebd1e33bSMarcel Holtmann 
380ebd1e33bSMarcel Holtmann 	hci_dev_lock(hdev);
381ebd1e33bSMarcel Holtmann 	*val = hdev->auto_accept_delay;
382ebd1e33bSMarcel Holtmann 	hci_dev_unlock(hdev);
383ebd1e33bSMarcel Holtmann 
384ebd1e33bSMarcel Holtmann 	return 0;
385ebd1e33bSMarcel Holtmann }
386ebd1e33bSMarcel Holtmann 
387ebd1e33bSMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get,
388ebd1e33bSMarcel Holtmann 			auto_accept_delay_set, "%llu\n");
389ebd1e33bSMarcel Holtmann 
3905afeac14SMarcel Holtmann static ssize_t force_sc_support_read(struct file *file, char __user *user_buf,
3915afeac14SMarcel Holtmann 				     size_t count, loff_t *ppos)
3925afeac14SMarcel Holtmann {
3935afeac14SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
3945afeac14SMarcel Holtmann 	char buf[3];
3955afeac14SMarcel Holtmann 
396111902f7SMarcel Holtmann 	buf[0] = test_bit(HCI_FORCE_SC, &hdev->dbg_flags) ? 'Y': 'N';
3975afeac14SMarcel Holtmann 	buf[1] = '\n';
3985afeac14SMarcel Holtmann 	buf[2] = '\0';
3995afeac14SMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
4005afeac14SMarcel Holtmann }
4015afeac14SMarcel Holtmann 
4025afeac14SMarcel Holtmann static ssize_t force_sc_support_write(struct file *file,
4035afeac14SMarcel Holtmann 				      const char __user *user_buf,
4045afeac14SMarcel Holtmann 				      size_t count, loff_t *ppos)
4055afeac14SMarcel Holtmann {
4065afeac14SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
4075afeac14SMarcel Holtmann 	char buf[32];
4085afeac14SMarcel Holtmann 	size_t buf_size = min(count, (sizeof(buf)-1));
4095afeac14SMarcel Holtmann 	bool enable;
4105afeac14SMarcel Holtmann 
4115afeac14SMarcel Holtmann 	if (test_bit(HCI_UP, &hdev->flags))
4125afeac14SMarcel Holtmann 		return -EBUSY;
4135afeac14SMarcel Holtmann 
4145afeac14SMarcel Holtmann 	if (copy_from_user(buf, user_buf, buf_size))
4155afeac14SMarcel Holtmann 		return -EFAULT;
4165afeac14SMarcel Holtmann 
4175afeac14SMarcel Holtmann 	buf[buf_size] = '\0';
4185afeac14SMarcel Holtmann 	if (strtobool(buf, &enable))
4195afeac14SMarcel Holtmann 		return -EINVAL;
4205afeac14SMarcel Holtmann 
421111902f7SMarcel Holtmann 	if (enable == test_bit(HCI_FORCE_SC, &hdev->dbg_flags))
4225afeac14SMarcel Holtmann 		return -EALREADY;
4235afeac14SMarcel Holtmann 
424111902f7SMarcel Holtmann 	change_bit(HCI_FORCE_SC, &hdev->dbg_flags);
4255afeac14SMarcel Holtmann 
4265afeac14SMarcel Holtmann 	return count;
4275afeac14SMarcel Holtmann }
4285afeac14SMarcel Holtmann 
4295afeac14SMarcel Holtmann static const struct file_operations force_sc_support_fops = {
4305afeac14SMarcel Holtmann 	.open		= simple_open,
4315afeac14SMarcel Holtmann 	.read		= force_sc_support_read,
4325afeac14SMarcel Holtmann 	.write		= force_sc_support_write,
4335afeac14SMarcel Holtmann 	.llseek		= default_llseek,
4345afeac14SMarcel Holtmann };
4355afeac14SMarcel Holtmann 
436134c2a89SMarcel Holtmann static ssize_t sc_only_mode_read(struct file *file, char __user *user_buf,
437134c2a89SMarcel Holtmann 				 size_t count, loff_t *ppos)
438134c2a89SMarcel Holtmann {
439134c2a89SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
440134c2a89SMarcel Holtmann 	char buf[3];
441134c2a89SMarcel Holtmann 
442134c2a89SMarcel Holtmann 	buf[0] = test_bit(HCI_SC_ONLY, &hdev->dev_flags) ? 'Y': 'N';
443134c2a89SMarcel Holtmann 	buf[1] = '\n';
444134c2a89SMarcel Holtmann 	buf[2] = '\0';
445134c2a89SMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
446134c2a89SMarcel Holtmann }
447134c2a89SMarcel Holtmann 
448134c2a89SMarcel Holtmann static const struct file_operations sc_only_mode_fops = {
449134c2a89SMarcel Holtmann 	.open		= simple_open,
450134c2a89SMarcel Holtmann 	.read		= sc_only_mode_read,
451134c2a89SMarcel Holtmann 	.llseek		= default_llseek,
452134c2a89SMarcel Holtmann };
453134c2a89SMarcel Holtmann 
4542bfa3531SMarcel Holtmann static int idle_timeout_set(void *data, u64 val)
4552bfa3531SMarcel Holtmann {
4562bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
4572bfa3531SMarcel Holtmann 
4582bfa3531SMarcel Holtmann 	if (val != 0 && (val < 500 || val > 3600000))
4592bfa3531SMarcel Holtmann 		return -EINVAL;
4602bfa3531SMarcel Holtmann 
4612bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
4622bfa3531SMarcel Holtmann 	hdev->idle_timeout = val;
4632bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
4642bfa3531SMarcel Holtmann 
4652bfa3531SMarcel Holtmann 	return 0;
4662bfa3531SMarcel Holtmann }
4672bfa3531SMarcel Holtmann 
4682bfa3531SMarcel Holtmann static int idle_timeout_get(void *data, u64 *val)
4692bfa3531SMarcel Holtmann {
4702bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
4712bfa3531SMarcel Holtmann 
4722bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
4732bfa3531SMarcel Holtmann 	*val = hdev->idle_timeout;
4742bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
4752bfa3531SMarcel Holtmann 
4762bfa3531SMarcel Holtmann 	return 0;
4772bfa3531SMarcel Holtmann }
4782bfa3531SMarcel Holtmann 
4792bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(idle_timeout_fops, idle_timeout_get,
4802bfa3531SMarcel Holtmann 			idle_timeout_set, "%llu\n");
4812bfa3531SMarcel Holtmann 
482c982b2eaSJohan Hedberg static int rpa_timeout_set(void *data, u64 val)
483c982b2eaSJohan Hedberg {
484c982b2eaSJohan Hedberg 	struct hci_dev *hdev = data;
485c982b2eaSJohan Hedberg 
486c982b2eaSJohan Hedberg 	/* Require the RPA timeout to be at least 30 seconds and at most
487c982b2eaSJohan Hedberg 	 * 24 hours.
488c982b2eaSJohan Hedberg 	 */
489c982b2eaSJohan Hedberg 	if (val < 30 || val > (60 * 60 * 24))
490c982b2eaSJohan Hedberg 		return -EINVAL;
491c982b2eaSJohan Hedberg 
492c982b2eaSJohan Hedberg 	hci_dev_lock(hdev);
493c982b2eaSJohan Hedberg 	hdev->rpa_timeout = val;
494c982b2eaSJohan Hedberg 	hci_dev_unlock(hdev);
495c982b2eaSJohan Hedberg 
496c982b2eaSJohan Hedberg 	return 0;
497c982b2eaSJohan Hedberg }
498c982b2eaSJohan Hedberg 
499c982b2eaSJohan Hedberg static int rpa_timeout_get(void *data, u64 *val)
500c982b2eaSJohan Hedberg {
501c982b2eaSJohan Hedberg 	struct hci_dev *hdev = data;
502c982b2eaSJohan Hedberg 
503c982b2eaSJohan Hedberg 	hci_dev_lock(hdev);
504c982b2eaSJohan Hedberg 	*val = hdev->rpa_timeout;
505c982b2eaSJohan Hedberg 	hci_dev_unlock(hdev);
506c982b2eaSJohan Hedberg 
507c982b2eaSJohan Hedberg 	return 0;
508c982b2eaSJohan Hedberg }
509c982b2eaSJohan Hedberg 
510c982b2eaSJohan Hedberg DEFINE_SIMPLE_ATTRIBUTE(rpa_timeout_fops, rpa_timeout_get,
511c982b2eaSJohan Hedberg 			rpa_timeout_set, "%llu\n");
512c982b2eaSJohan Hedberg 
5132bfa3531SMarcel Holtmann static int sniff_min_interval_set(void *data, u64 val)
5142bfa3531SMarcel Holtmann {
5152bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
5162bfa3531SMarcel Holtmann 
5172bfa3531SMarcel Holtmann 	if (val == 0 || val % 2 || val > hdev->sniff_max_interval)
5182bfa3531SMarcel Holtmann 		return -EINVAL;
5192bfa3531SMarcel Holtmann 
5202bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5212bfa3531SMarcel Holtmann 	hdev->sniff_min_interval = val;
5222bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5232bfa3531SMarcel Holtmann 
5242bfa3531SMarcel Holtmann 	return 0;
5252bfa3531SMarcel Holtmann }
5262bfa3531SMarcel Holtmann 
5272bfa3531SMarcel Holtmann static int sniff_min_interval_get(void *data, u64 *val)
5282bfa3531SMarcel Holtmann {
5292bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
5302bfa3531SMarcel Holtmann 
5312bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5322bfa3531SMarcel Holtmann 	*val = hdev->sniff_min_interval;
5332bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5342bfa3531SMarcel Holtmann 
5352bfa3531SMarcel Holtmann 	return 0;
5362bfa3531SMarcel Holtmann }
5372bfa3531SMarcel Holtmann 
5382bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_min_interval_fops, sniff_min_interval_get,
5392bfa3531SMarcel Holtmann 			sniff_min_interval_set, "%llu\n");
5402bfa3531SMarcel Holtmann 
5412bfa3531SMarcel Holtmann static int sniff_max_interval_set(void *data, u64 val)
5422bfa3531SMarcel Holtmann {
5432bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
5442bfa3531SMarcel Holtmann 
5452bfa3531SMarcel Holtmann 	if (val == 0 || val % 2 || val < hdev->sniff_min_interval)
5462bfa3531SMarcel Holtmann 		return -EINVAL;
5472bfa3531SMarcel Holtmann 
5482bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5492bfa3531SMarcel Holtmann 	hdev->sniff_max_interval = val;
5502bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5512bfa3531SMarcel Holtmann 
5522bfa3531SMarcel Holtmann 	return 0;
5532bfa3531SMarcel Holtmann }
5542bfa3531SMarcel Holtmann 
5552bfa3531SMarcel Holtmann static int sniff_max_interval_get(void *data, u64 *val)
5562bfa3531SMarcel Holtmann {
5572bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
5582bfa3531SMarcel Holtmann 
5592bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5602bfa3531SMarcel Holtmann 	*val = hdev->sniff_max_interval;
5612bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5622bfa3531SMarcel Holtmann 
5632bfa3531SMarcel Holtmann 	return 0;
5642bfa3531SMarcel Holtmann }
5652bfa3531SMarcel Holtmann 
5662bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_max_interval_fops, sniff_max_interval_get,
5672bfa3531SMarcel Holtmann 			sniff_max_interval_set, "%llu\n");
5682bfa3531SMarcel Holtmann 
56931ad1691SAndrzej Kaczmarek static int conn_info_min_age_set(void *data, u64 val)
57031ad1691SAndrzej Kaczmarek {
57131ad1691SAndrzej Kaczmarek 	struct hci_dev *hdev = data;
57231ad1691SAndrzej Kaczmarek 
57331ad1691SAndrzej Kaczmarek 	if (val == 0 || val > hdev->conn_info_max_age)
57431ad1691SAndrzej Kaczmarek 		return -EINVAL;
57531ad1691SAndrzej Kaczmarek 
57631ad1691SAndrzej Kaczmarek 	hci_dev_lock(hdev);
57731ad1691SAndrzej Kaczmarek 	hdev->conn_info_min_age = val;
57831ad1691SAndrzej Kaczmarek 	hci_dev_unlock(hdev);
57931ad1691SAndrzej Kaczmarek 
58031ad1691SAndrzej Kaczmarek 	return 0;
58131ad1691SAndrzej Kaczmarek }
58231ad1691SAndrzej Kaczmarek 
58331ad1691SAndrzej Kaczmarek static int conn_info_min_age_get(void *data, u64 *val)
58431ad1691SAndrzej Kaczmarek {
58531ad1691SAndrzej Kaczmarek 	struct hci_dev *hdev = data;
58631ad1691SAndrzej Kaczmarek 
58731ad1691SAndrzej Kaczmarek 	hci_dev_lock(hdev);
58831ad1691SAndrzej Kaczmarek 	*val = hdev->conn_info_min_age;
58931ad1691SAndrzej Kaczmarek 	hci_dev_unlock(hdev);
59031ad1691SAndrzej Kaczmarek 
59131ad1691SAndrzej Kaczmarek 	return 0;
59231ad1691SAndrzej Kaczmarek }
59331ad1691SAndrzej Kaczmarek 
59431ad1691SAndrzej Kaczmarek DEFINE_SIMPLE_ATTRIBUTE(conn_info_min_age_fops, conn_info_min_age_get,
59531ad1691SAndrzej Kaczmarek 			conn_info_min_age_set, "%llu\n");
59631ad1691SAndrzej Kaczmarek 
59731ad1691SAndrzej Kaczmarek static int conn_info_max_age_set(void *data, u64 val)
59831ad1691SAndrzej Kaczmarek {
59931ad1691SAndrzej Kaczmarek 	struct hci_dev *hdev = data;
60031ad1691SAndrzej Kaczmarek 
60131ad1691SAndrzej Kaczmarek 	if (val == 0 || val < hdev->conn_info_min_age)
60231ad1691SAndrzej Kaczmarek 		return -EINVAL;
60331ad1691SAndrzej Kaczmarek 
60431ad1691SAndrzej Kaczmarek 	hci_dev_lock(hdev);
60531ad1691SAndrzej Kaczmarek 	hdev->conn_info_max_age = val;
60631ad1691SAndrzej Kaczmarek 	hci_dev_unlock(hdev);
60731ad1691SAndrzej Kaczmarek 
60831ad1691SAndrzej Kaczmarek 	return 0;
60931ad1691SAndrzej Kaczmarek }
61031ad1691SAndrzej Kaczmarek 
61131ad1691SAndrzej Kaczmarek static int conn_info_max_age_get(void *data, u64 *val)
61231ad1691SAndrzej Kaczmarek {
61331ad1691SAndrzej Kaczmarek 	struct hci_dev *hdev = data;
61431ad1691SAndrzej Kaczmarek 
61531ad1691SAndrzej Kaczmarek 	hci_dev_lock(hdev);
61631ad1691SAndrzej Kaczmarek 	*val = hdev->conn_info_max_age;
61731ad1691SAndrzej Kaczmarek 	hci_dev_unlock(hdev);
61831ad1691SAndrzej Kaczmarek 
61931ad1691SAndrzej Kaczmarek 	return 0;
62031ad1691SAndrzej Kaczmarek }
62131ad1691SAndrzej Kaczmarek 
62231ad1691SAndrzej Kaczmarek DEFINE_SIMPLE_ATTRIBUTE(conn_info_max_age_fops, conn_info_max_age_get,
62331ad1691SAndrzej Kaczmarek 			conn_info_max_age_set, "%llu\n");
62431ad1691SAndrzej Kaczmarek 
625ac345813SMarcel Holtmann static int identity_show(struct seq_file *f, void *p)
626ac345813SMarcel Holtmann {
627ac345813SMarcel Holtmann 	struct hci_dev *hdev = f->private;
628a1f4c318SJohan Hedberg 	bdaddr_t addr;
629ac345813SMarcel Holtmann 	u8 addr_type;
630ac345813SMarcel Holtmann 
631ac345813SMarcel Holtmann 	hci_dev_lock(hdev);
632ac345813SMarcel Holtmann 
633a1f4c318SJohan Hedberg 	hci_copy_identity_address(hdev, &addr, &addr_type);
634ac345813SMarcel Holtmann 
635a1f4c318SJohan Hedberg 	seq_printf(f, "%pMR (type %u) %*phN %pMR\n", &addr, addr_type,
636473deef2SMarcel Holtmann 		   16, hdev->irk, &hdev->rpa);
637ac345813SMarcel Holtmann 
638ac345813SMarcel Holtmann 	hci_dev_unlock(hdev);
639ac345813SMarcel Holtmann 
640ac345813SMarcel Holtmann 	return 0;
641ac345813SMarcel Holtmann }
642ac345813SMarcel Holtmann 
643ac345813SMarcel Holtmann static int identity_open(struct inode *inode, struct file *file)
644ac345813SMarcel Holtmann {
645ac345813SMarcel Holtmann 	return single_open(file, identity_show, inode->i_private);
646ac345813SMarcel Holtmann }
647ac345813SMarcel Holtmann 
648ac345813SMarcel Holtmann static const struct file_operations identity_fops = {
649ac345813SMarcel Holtmann 	.open		= identity_open,
650ac345813SMarcel Holtmann 	.read		= seq_read,
651ac345813SMarcel Holtmann 	.llseek		= seq_lseek,
652ac345813SMarcel Holtmann 	.release	= single_release,
653ac345813SMarcel Holtmann };
654ac345813SMarcel Holtmann 
6557a4cd51dSMarcel Holtmann static int random_address_show(struct seq_file *f, void *p)
6567a4cd51dSMarcel Holtmann {
6577a4cd51dSMarcel Holtmann 	struct hci_dev *hdev = f->private;
6587a4cd51dSMarcel Holtmann 
6597a4cd51dSMarcel Holtmann 	hci_dev_lock(hdev);
6607a4cd51dSMarcel Holtmann 	seq_printf(f, "%pMR\n", &hdev->random_addr);
6617a4cd51dSMarcel Holtmann 	hci_dev_unlock(hdev);
6627a4cd51dSMarcel Holtmann 
6637a4cd51dSMarcel Holtmann 	return 0;
6647a4cd51dSMarcel Holtmann }
6657a4cd51dSMarcel Holtmann 
6667a4cd51dSMarcel Holtmann static int random_address_open(struct inode *inode, struct file *file)
6677a4cd51dSMarcel Holtmann {
6687a4cd51dSMarcel Holtmann 	return single_open(file, random_address_show, inode->i_private);
6697a4cd51dSMarcel Holtmann }
6707a4cd51dSMarcel Holtmann 
6717a4cd51dSMarcel Holtmann static const struct file_operations random_address_fops = {
6727a4cd51dSMarcel Holtmann 	.open		= random_address_open,
6737a4cd51dSMarcel Holtmann 	.read		= seq_read,
6747a4cd51dSMarcel Holtmann 	.llseek		= seq_lseek,
6757a4cd51dSMarcel Holtmann 	.release	= single_release,
6767a4cd51dSMarcel Holtmann };
6777a4cd51dSMarcel Holtmann 
678e7b8fc92SMarcel Holtmann static int static_address_show(struct seq_file *f, void *p)
679e7b8fc92SMarcel Holtmann {
680e7b8fc92SMarcel Holtmann 	struct hci_dev *hdev = f->private;
681e7b8fc92SMarcel Holtmann 
682e7b8fc92SMarcel Holtmann 	hci_dev_lock(hdev);
683e7b8fc92SMarcel Holtmann 	seq_printf(f, "%pMR\n", &hdev->static_addr);
684e7b8fc92SMarcel Holtmann 	hci_dev_unlock(hdev);
685e7b8fc92SMarcel Holtmann 
686e7b8fc92SMarcel Holtmann 	return 0;
687e7b8fc92SMarcel Holtmann }
688e7b8fc92SMarcel Holtmann 
689e7b8fc92SMarcel Holtmann static int static_address_open(struct inode *inode, struct file *file)
690e7b8fc92SMarcel Holtmann {
691e7b8fc92SMarcel Holtmann 	return single_open(file, static_address_show, inode->i_private);
692e7b8fc92SMarcel Holtmann }
693e7b8fc92SMarcel Holtmann 
694e7b8fc92SMarcel Holtmann static const struct file_operations static_address_fops = {
695e7b8fc92SMarcel Holtmann 	.open		= static_address_open,
696e7b8fc92SMarcel Holtmann 	.read		= seq_read,
697e7b8fc92SMarcel Holtmann 	.llseek		= seq_lseek,
698e7b8fc92SMarcel Holtmann 	.release	= single_release,
699e7b8fc92SMarcel Holtmann };
700e7b8fc92SMarcel Holtmann 
701b32bba6cSMarcel Holtmann static ssize_t force_static_address_read(struct file *file,
702b32bba6cSMarcel Holtmann 					 char __user *user_buf,
703b32bba6cSMarcel Holtmann 					 size_t count, loff_t *ppos)
70492202185SMarcel Holtmann {
705b32bba6cSMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
706b32bba6cSMarcel Holtmann 	char buf[3];
70792202185SMarcel Holtmann 
708111902f7SMarcel Holtmann 	buf[0] = test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) ? 'Y': 'N';
709b32bba6cSMarcel Holtmann 	buf[1] = '\n';
710b32bba6cSMarcel Holtmann 	buf[2] = '\0';
711b32bba6cSMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
712b32bba6cSMarcel Holtmann }
713b32bba6cSMarcel Holtmann 
714b32bba6cSMarcel Holtmann static ssize_t force_static_address_write(struct file *file,
715b32bba6cSMarcel Holtmann 					  const char __user *user_buf,
716b32bba6cSMarcel Holtmann 					  size_t count, loff_t *ppos)
717b32bba6cSMarcel Holtmann {
718b32bba6cSMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
719b32bba6cSMarcel Holtmann 	char buf[32];
720b32bba6cSMarcel Holtmann 	size_t buf_size = min(count, (sizeof(buf)-1));
721b32bba6cSMarcel Holtmann 	bool enable;
722b32bba6cSMarcel Holtmann 
723b32bba6cSMarcel Holtmann 	if (test_bit(HCI_UP, &hdev->flags))
724b32bba6cSMarcel Holtmann 		return -EBUSY;
725b32bba6cSMarcel Holtmann 
726b32bba6cSMarcel Holtmann 	if (copy_from_user(buf, user_buf, buf_size))
727b32bba6cSMarcel Holtmann 		return -EFAULT;
728b32bba6cSMarcel Holtmann 
729b32bba6cSMarcel Holtmann 	buf[buf_size] = '\0';
730b32bba6cSMarcel Holtmann 	if (strtobool(buf, &enable))
73192202185SMarcel Holtmann 		return -EINVAL;
73292202185SMarcel Holtmann 
733111902f7SMarcel Holtmann 	if (enable == test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags))
734b32bba6cSMarcel Holtmann 		return -EALREADY;
73592202185SMarcel Holtmann 
736111902f7SMarcel Holtmann 	change_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags);
737b32bba6cSMarcel Holtmann 
738b32bba6cSMarcel Holtmann 	return count;
73992202185SMarcel Holtmann }
74092202185SMarcel Holtmann 
741b32bba6cSMarcel Holtmann static const struct file_operations force_static_address_fops = {
742b32bba6cSMarcel Holtmann 	.open		= simple_open,
743b32bba6cSMarcel Holtmann 	.read		= force_static_address_read,
744b32bba6cSMarcel Holtmann 	.write		= force_static_address_write,
745b32bba6cSMarcel Holtmann 	.llseek		= default_llseek,
746b32bba6cSMarcel Holtmann };
74792202185SMarcel Holtmann 
748d2ab0ac1SMarcel Holtmann static int white_list_show(struct seq_file *f, void *ptr)
749d2ab0ac1SMarcel Holtmann {
750d2ab0ac1SMarcel Holtmann 	struct hci_dev *hdev = f->private;
751d2ab0ac1SMarcel Holtmann 	struct bdaddr_list *b;
752d2ab0ac1SMarcel Holtmann 
753d2ab0ac1SMarcel Holtmann 	hci_dev_lock(hdev);
754d2ab0ac1SMarcel Holtmann 	list_for_each_entry(b, &hdev->le_white_list, list)
755d2ab0ac1SMarcel Holtmann 		seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type);
756d2ab0ac1SMarcel Holtmann 	hci_dev_unlock(hdev);
757d2ab0ac1SMarcel Holtmann 
758d2ab0ac1SMarcel Holtmann 	return 0;
759d2ab0ac1SMarcel Holtmann }
760d2ab0ac1SMarcel Holtmann 
761d2ab0ac1SMarcel Holtmann static int white_list_open(struct inode *inode, struct file *file)
762d2ab0ac1SMarcel Holtmann {
763d2ab0ac1SMarcel Holtmann 	return single_open(file, white_list_show, inode->i_private);
764d2ab0ac1SMarcel Holtmann }
765d2ab0ac1SMarcel Holtmann 
766d2ab0ac1SMarcel Holtmann static const struct file_operations white_list_fops = {
767d2ab0ac1SMarcel Holtmann 	.open		= white_list_open,
768d2ab0ac1SMarcel Holtmann 	.read		= seq_read,
769d2ab0ac1SMarcel Holtmann 	.llseek		= seq_lseek,
770d2ab0ac1SMarcel Holtmann 	.release	= single_release,
771d2ab0ac1SMarcel Holtmann };
772d2ab0ac1SMarcel Holtmann 
7733698d704SMarcel Holtmann static int identity_resolving_keys_show(struct seq_file *f, void *ptr)
7743698d704SMarcel Holtmann {
7753698d704SMarcel Holtmann 	struct hci_dev *hdev = f->private;
7763698d704SMarcel Holtmann 	struct list_head *p, *n;
7773698d704SMarcel Holtmann 
7783698d704SMarcel Holtmann 	hci_dev_lock(hdev);
7793698d704SMarcel Holtmann 	list_for_each_safe(p, n, &hdev->identity_resolving_keys) {
7803698d704SMarcel Holtmann 		struct smp_irk *irk = list_entry(p, struct smp_irk, list);
7813698d704SMarcel Holtmann 		seq_printf(f, "%pMR (type %u) %*phN %pMR\n",
7823698d704SMarcel Holtmann 			   &irk->bdaddr, irk->addr_type,
7833698d704SMarcel Holtmann 			   16, irk->val, &irk->rpa);
7843698d704SMarcel Holtmann 	}
7853698d704SMarcel Holtmann 	hci_dev_unlock(hdev);
7863698d704SMarcel Holtmann 
7873698d704SMarcel Holtmann 	return 0;
7883698d704SMarcel Holtmann }
7893698d704SMarcel Holtmann 
7903698d704SMarcel Holtmann static int identity_resolving_keys_open(struct inode *inode, struct file *file)
7913698d704SMarcel Holtmann {
7923698d704SMarcel Holtmann 	return single_open(file, identity_resolving_keys_show,
7933698d704SMarcel Holtmann 			   inode->i_private);
7943698d704SMarcel Holtmann }
7953698d704SMarcel Holtmann 
7963698d704SMarcel Holtmann static const struct file_operations identity_resolving_keys_fops = {
7973698d704SMarcel Holtmann 	.open		= identity_resolving_keys_open,
7983698d704SMarcel Holtmann 	.read		= seq_read,
7993698d704SMarcel Holtmann 	.llseek		= seq_lseek,
8003698d704SMarcel Holtmann 	.release	= single_release,
8013698d704SMarcel Holtmann };
8023698d704SMarcel Holtmann 
8038f8625cdSMarcel Holtmann static int long_term_keys_show(struct seq_file *f, void *ptr)
8048f8625cdSMarcel Holtmann {
8058f8625cdSMarcel Holtmann 	struct hci_dev *hdev = f->private;
8068f8625cdSMarcel Holtmann 	struct list_head *p, *n;
8078f8625cdSMarcel Holtmann 
8088f8625cdSMarcel Holtmann 	hci_dev_lock(hdev);
809f813f1beSJohan Hedberg 	list_for_each_safe(p, n, &hdev->long_term_keys) {
8108f8625cdSMarcel Holtmann 		struct smp_ltk *ltk = list_entry(p, struct smp_ltk, list);
811fe39c7b2SMarcel Holtmann 		seq_printf(f, "%pMR (type %u) %u 0x%02x %u %.4x %.16llx %*phN\n",
8128f8625cdSMarcel Holtmann 			   &ltk->bdaddr, ltk->bdaddr_type, ltk->authenticated,
8138f8625cdSMarcel Holtmann 			   ltk->type, ltk->enc_size, __le16_to_cpu(ltk->ediv),
814fe39c7b2SMarcel Holtmann 			   __le64_to_cpu(ltk->rand), 16, ltk->val);
8158f8625cdSMarcel Holtmann 	}
8168f8625cdSMarcel Holtmann 	hci_dev_unlock(hdev);
8178f8625cdSMarcel Holtmann 
8188f8625cdSMarcel Holtmann 	return 0;
8198f8625cdSMarcel Holtmann }
8208f8625cdSMarcel Holtmann 
8218f8625cdSMarcel Holtmann static int long_term_keys_open(struct inode *inode, struct file *file)
8228f8625cdSMarcel Holtmann {
8238f8625cdSMarcel Holtmann 	return single_open(file, long_term_keys_show, inode->i_private);
8248f8625cdSMarcel Holtmann }
8258f8625cdSMarcel Holtmann 
8268f8625cdSMarcel Holtmann static const struct file_operations long_term_keys_fops = {
8278f8625cdSMarcel Holtmann 	.open		= long_term_keys_open,
8288f8625cdSMarcel Holtmann 	.read		= seq_read,
8298f8625cdSMarcel Holtmann 	.llseek		= seq_lseek,
8308f8625cdSMarcel Holtmann 	.release	= single_release,
8318f8625cdSMarcel Holtmann };
8328f8625cdSMarcel Holtmann 
8334e70c7e7SMarcel Holtmann static int conn_min_interval_set(void *data, u64 val)
8344e70c7e7SMarcel Holtmann {
8354e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
8364e70c7e7SMarcel Holtmann 
8374e70c7e7SMarcel Holtmann 	if (val < 0x0006 || val > 0x0c80 || val > hdev->le_conn_max_interval)
8384e70c7e7SMarcel Holtmann 		return -EINVAL;
8394e70c7e7SMarcel Holtmann 
8404e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
8414e70c7e7SMarcel Holtmann 	hdev->le_conn_min_interval = val;
8424e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
8434e70c7e7SMarcel Holtmann 
8444e70c7e7SMarcel Holtmann 	return 0;
8454e70c7e7SMarcel Holtmann }
8464e70c7e7SMarcel Holtmann 
8474e70c7e7SMarcel Holtmann static int conn_min_interval_get(void *data, u64 *val)
8484e70c7e7SMarcel Holtmann {
8494e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
8504e70c7e7SMarcel Holtmann 
8514e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
8524e70c7e7SMarcel Holtmann 	*val = hdev->le_conn_min_interval;
8534e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
8544e70c7e7SMarcel Holtmann 
8554e70c7e7SMarcel Holtmann 	return 0;
8564e70c7e7SMarcel Holtmann }
8574e70c7e7SMarcel Holtmann 
8584e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_min_interval_fops, conn_min_interval_get,
8594e70c7e7SMarcel Holtmann 			conn_min_interval_set, "%llu\n");
8604e70c7e7SMarcel Holtmann 
8614e70c7e7SMarcel Holtmann static int conn_max_interval_set(void *data, u64 val)
8624e70c7e7SMarcel Holtmann {
8634e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
8644e70c7e7SMarcel Holtmann 
8654e70c7e7SMarcel Holtmann 	if (val < 0x0006 || val > 0x0c80 || val < hdev->le_conn_min_interval)
8664e70c7e7SMarcel Holtmann 		return -EINVAL;
8674e70c7e7SMarcel Holtmann 
8684e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
8694e70c7e7SMarcel Holtmann 	hdev->le_conn_max_interval = val;
8704e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
8714e70c7e7SMarcel Holtmann 
8724e70c7e7SMarcel Holtmann 	return 0;
8734e70c7e7SMarcel Holtmann }
8744e70c7e7SMarcel Holtmann 
8754e70c7e7SMarcel Holtmann static int conn_max_interval_get(void *data, u64 *val)
8764e70c7e7SMarcel Holtmann {
8774e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
8784e70c7e7SMarcel Holtmann 
8794e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
8804e70c7e7SMarcel Holtmann 	*val = hdev->le_conn_max_interval;
8814e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
8824e70c7e7SMarcel Holtmann 
8834e70c7e7SMarcel Holtmann 	return 0;
8844e70c7e7SMarcel Holtmann }
8854e70c7e7SMarcel Holtmann 
8864e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get,
8874e70c7e7SMarcel Holtmann 			conn_max_interval_set, "%llu\n");
8884e70c7e7SMarcel Holtmann 
889816a93d1SMarcel Holtmann static int conn_latency_set(void *data, u64 val)
890816a93d1SMarcel Holtmann {
891816a93d1SMarcel Holtmann 	struct hci_dev *hdev = data;
892816a93d1SMarcel Holtmann 
893816a93d1SMarcel Holtmann 	if (val > 0x01f3)
894816a93d1SMarcel Holtmann 		return -EINVAL;
895816a93d1SMarcel Holtmann 
896816a93d1SMarcel Holtmann 	hci_dev_lock(hdev);
897816a93d1SMarcel Holtmann 	hdev->le_conn_latency = val;
898816a93d1SMarcel Holtmann 	hci_dev_unlock(hdev);
899816a93d1SMarcel Holtmann 
900816a93d1SMarcel Holtmann 	return 0;
901816a93d1SMarcel Holtmann }
902816a93d1SMarcel Holtmann 
903816a93d1SMarcel Holtmann static int conn_latency_get(void *data, u64 *val)
904816a93d1SMarcel Holtmann {
905816a93d1SMarcel Holtmann 	struct hci_dev *hdev = data;
906816a93d1SMarcel Holtmann 
907816a93d1SMarcel Holtmann 	hci_dev_lock(hdev);
908816a93d1SMarcel Holtmann 	*val = hdev->le_conn_latency;
909816a93d1SMarcel Holtmann 	hci_dev_unlock(hdev);
910816a93d1SMarcel Holtmann 
911816a93d1SMarcel Holtmann 	return 0;
912816a93d1SMarcel Holtmann }
913816a93d1SMarcel Holtmann 
914816a93d1SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_latency_fops, conn_latency_get,
915816a93d1SMarcel Holtmann 			conn_latency_set, "%llu\n");
916816a93d1SMarcel Holtmann 
917f1649577SMarcel Holtmann static int supervision_timeout_set(void *data, u64 val)
918f1649577SMarcel Holtmann {
919f1649577SMarcel Holtmann 	struct hci_dev *hdev = data;
920f1649577SMarcel Holtmann 
921f1649577SMarcel Holtmann 	if (val < 0x000a || val > 0x0c80)
922f1649577SMarcel Holtmann 		return -EINVAL;
923f1649577SMarcel Holtmann 
924f1649577SMarcel Holtmann 	hci_dev_lock(hdev);
925f1649577SMarcel Holtmann 	hdev->le_supv_timeout = val;
926f1649577SMarcel Holtmann 	hci_dev_unlock(hdev);
927f1649577SMarcel Holtmann 
928f1649577SMarcel Holtmann 	return 0;
929f1649577SMarcel Holtmann }
930f1649577SMarcel Holtmann 
931f1649577SMarcel Holtmann static int supervision_timeout_get(void *data, u64 *val)
932f1649577SMarcel Holtmann {
933f1649577SMarcel Holtmann 	struct hci_dev *hdev = data;
934f1649577SMarcel Holtmann 
935f1649577SMarcel Holtmann 	hci_dev_lock(hdev);
936f1649577SMarcel Holtmann 	*val = hdev->le_supv_timeout;
937f1649577SMarcel Holtmann 	hci_dev_unlock(hdev);
938f1649577SMarcel Holtmann 
939f1649577SMarcel Holtmann 	return 0;
940f1649577SMarcel Holtmann }
941f1649577SMarcel Holtmann 
942f1649577SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(supervision_timeout_fops, supervision_timeout_get,
943f1649577SMarcel Holtmann 			supervision_timeout_set, "%llu\n");
944f1649577SMarcel Holtmann 
9453f959d46SMarcel Holtmann static int adv_channel_map_set(void *data, u64 val)
9463f959d46SMarcel Holtmann {
9473f959d46SMarcel Holtmann 	struct hci_dev *hdev = data;
9483f959d46SMarcel Holtmann 
9493f959d46SMarcel Holtmann 	if (val < 0x01 || val > 0x07)
9503f959d46SMarcel Holtmann 		return -EINVAL;
9513f959d46SMarcel Holtmann 
9523f959d46SMarcel Holtmann 	hci_dev_lock(hdev);
9533f959d46SMarcel Holtmann 	hdev->le_adv_channel_map = val;
9543f959d46SMarcel Holtmann 	hci_dev_unlock(hdev);
9553f959d46SMarcel Holtmann 
9563f959d46SMarcel Holtmann 	return 0;
9573f959d46SMarcel Holtmann }
9583f959d46SMarcel Holtmann 
9593f959d46SMarcel Holtmann static int adv_channel_map_get(void *data, u64 *val)
9603f959d46SMarcel Holtmann {
9613f959d46SMarcel Holtmann 	struct hci_dev *hdev = data;
9623f959d46SMarcel Holtmann 
9633f959d46SMarcel Holtmann 	hci_dev_lock(hdev);
9643f959d46SMarcel Holtmann 	*val = hdev->le_adv_channel_map;
9653f959d46SMarcel Holtmann 	hci_dev_unlock(hdev);
9663f959d46SMarcel Holtmann 
9673f959d46SMarcel Holtmann 	return 0;
9683f959d46SMarcel Holtmann }
9693f959d46SMarcel Holtmann 
9703f959d46SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(adv_channel_map_fops, adv_channel_map_get,
9713f959d46SMarcel Holtmann 			adv_channel_map_set, "%llu\n");
9723f959d46SMarcel Holtmann 
973729a1051SGeorg Lukas static int adv_min_interval_set(void *data, u64 val)
97489863109SJukka Rissanen {
975729a1051SGeorg Lukas 	struct hci_dev *hdev = data;
97689863109SJukka Rissanen 
977729a1051SGeorg Lukas 	if (val < 0x0020 || val > 0x4000 || val > hdev->le_adv_max_interval)
97889863109SJukka Rissanen 		return -EINVAL;
97989863109SJukka Rissanen 
9807d474e06SAndre Guedes 	hci_dev_lock(hdev);
981729a1051SGeorg Lukas 	hdev->le_adv_min_interval = val;
9827d474e06SAndre Guedes 	hci_dev_unlock(hdev);
9837d474e06SAndre Guedes 
9847d474e06SAndre Guedes 	return 0;
9857d474e06SAndre Guedes }
9867d474e06SAndre Guedes 
987729a1051SGeorg Lukas static int adv_min_interval_get(void *data, u64 *val)
9887d474e06SAndre Guedes {
989729a1051SGeorg Lukas 	struct hci_dev *hdev = data;
990729a1051SGeorg Lukas 
991729a1051SGeorg Lukas 	hci_dev_lock(hdev);
992729a1051SGeorg Lukas 	*val = hdev->le_adv_min_interval;
993729a1051SGeorg Lukas 	hci_dev_unlock(hdev);
994729a1051SGeorg Lukas 
995729a1051SGeorg Lukas 	return 0;
9967d474e06SAndre Guedes }
9977d474e06SAndre Guedes 
998729a1051SGeorg Lukas DEFINE_SIMPLE_ATTRIBUTE(adv_min_interval_fops, adv_min_interval_get,
999729a1051SGeorg Lukas 			adv_min_interval_set, "%llu\n");
10007d474e06SAndre Guedes 
1001729a1051SGeorg Lukas static int adv_max_interval_set(void *data, u64 val)
1002729a1051SGeorg Lukas {
1003729a1051SGeorg Lukas 	struct hci_dev *hdev = data;
1004729a1051SGeorg Lukas 
1005729a1051SGeorg Lukas 	if (val < 0x0020 || val > 0x4000 || val < hdev->le_adv_min_interval)
10067d474e06SAndre Guedes 		return -EINVAL;
10077d474e06SAndre Guedes 
10087d474e06SAndre Guedes 	hci_dev_lock(hdev);
1009729a1051SGeorg Lukas 	hdev->le_adv_max_interval = val;
10107d474e06SAndre Guedes 	hci_dev_unlock(hdev);
10117d474e06SAndre Guedes 
1012729a1051SGeorg Lukas 	return 0;
10137d474e06SAndre Guedes }
10147d474e06SAndre Guedes 
1015729a1051SGeorg Lukas static int adv_max_interval_get(void *data, u64 *val)
1016729a1051SGeorg Lukas {
1017729a1051SGeorg Lukas 	struct hci_dev *hdev = data;
1018729a1051SGeorg Lukas 
10197d474e06SAndre Guedes 	hci_dev_lock(hdev);
1020729a1051SGeorg Lukas 	*val = hdev->le_adv_max_interval;
10217d474e06SAndre Guedes 	hci_dev_unlock(hdev);
1022729a1051SGeorg Lukas 
1023729a1051SGeorg Lukas 	return 0;
1024729a1051SGeorg Lukas }
1025729a1051SGeorg Lukas 
1026729a1051SGeorg Lukas DEFINE_SIMPLE_ATTRIBUTE(adv_max_interval_fops, adv_max_interval_get,
1027729a1051SGeorg Lukas 			adv_max_interval_set, "%llu\n");
1028729a1051SGeorg Lukas 
10290b3c7d37SMarcel Holtmann static int device_list_show(struct seq_file *f, void *ptr)
10307d474e06SAndre Guedes {
10310b3c7d37SMarcel Holtmann 	struct hci_dev *hdev = f->private;
10327d474e06SAndre Guedes 	struct hci_conn_params *p;
10337d474e06SAndre Guedes 
10347d474e06SAndre Guedes 	hci_dev_lock(hdev);
10357d474e06SAndre Guedes 	list_for_each_entry(p, &hdev->le_conn_params, list) {
10360b3c7d37SMarcel Holtmann 		seq_printf(f, "%pMR %u %u\n", &p->addr, p->addr_type,
10377d474e06SAndre Guedes 			   p->auto_connect);
10387d474e06SAndre Guedes 	}
10397d474e06SAndre Guedes 	hci_dev_unlock(hdev);
10407d474e06SAndre Guedes 
10417d474e06SAndre Guedes 	return 0;
10427d474e06SAndre Guedes }
10437d474e06SAndre Guedes 
10440b3c7d37SMarcel Holtmann static int device_list_open(struct inode *inode, struct file *file)
10457d474e06SAndre Guedes {
10460b3c7d37SMarcel Holtmann 	return single_open(file, device_list_show, inode->i_private);
10477d474e06SAndre Guedes }
10487d474e06SAndre Guedes 
10490b3c7d37SMarcel Holtmann static const struct file_operations device_list_fops = {
10500b3c7d37SMarcel Holtmann 	.open		= device_list_open,
10517d474e06SAndre Guedes 	.read		= seq_read,
10527d474e06SAndre Guedes 	.llseek		= seq_lseek,
10537d474e06SAndre Guedes 	.release	= single_release,
10547d474e06SAndre Guedes };
10557d474e06SAndre Guedes 
10561da177e4SLinus Torvalds /* ---- HCI requests ---- */
10571da177e4SLinus Torvalds 
105842c6b129SJohan Hedberg static void hci_req_sync_complete(struct hci_dev *hdev, u8 result)
10591da177e4SLinus Torvalds {
106042c6b129SJohan Hedberg 	BT_DBG("%s result 0x%2.2x", hdev->name, result);
106175fb0e32SJohan Hedberg 
10621da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
10631da177e4SLinus Torvalds 		hdev->req_result = result;
10641da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_DONE;
10651da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
10661da177e4SLinus Torvalds 	}
10671da177e4SLinus Torvalds }
10681da177e4SLinus Torvalds 
10691da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err)
10701da177e4SLinus Torvalds {
10711da177e4SLinus Torvalds 	BT_DBG("%s err 0x%2.2x", hdev->name, err);
10721da177e4SLinus Torvalds 
10731da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
10741da177e4SLinus Torvalds 		hdev->req_result = err;
10751da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_CANCELED;
10761da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
10771da177e4SLinus Torvalds 	}
10781da177e4SLinus Torvalds }
10791da177e4SLinus Torvalds 
108077a63e0aSFengguang Wu static struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode,
108177a63e0aSFengguang Wu 					    u8 event)
108275e84b7cSJohan Hedberg {
108375e84b7cSJohan Hedberg 	struct hci_ev_cmd_complete *ev;
108475e84b7cSJohan Hedberg 	struct hci_event_hdr *hdr;
108575e84b7cSJohan Hedberg 	struct sk_buff *skb;
108675e84b7cSJohan Hedberg 
108775e84b7cSJohan Hedberg 	hci_dev_lock(hdev);
108875e84b7cSJohan Hedberg 
108975e84b7cSJohan Hedberg 	skb = hdev->recv_evt;
109075e84b7cSJohan Hedberg 	hdev->recv_evt = NULL;
109175e84b7cSJohan Hedberg 
109275e84b7cSJohan Hedberg 	hci_dev_unlock(hdev);
109375e84b7cSJohan Hedberg 
109475e84b7cSJohan Hedberg 	if (!skb)
109575e84b7cSJohan Hedberg 		return ERR_PTR(-ENODATA);
109675e84b7cSJohan Hedberg 
109775e84b7cSJohan Hedberg 	if (skb->len < sizeof(*hdr)) {
109875e84b7cSJohan Hedberg 		BT_ERR("Too short HCI event");
109975e84b7cSJohan Hedberg 		goto failed;
110075e84b7cSJohan Hedberg 	}
110175e84b7cSJohan Hedberg 
110275e84b7cSJohan Hedberg 	hdr = (void *) skb->data;
110375e84b7cSJohan Hedberg 	skb_pull(skb, HCI_EVENT_HDR_SIZE);
110475e84b7cSJohan Hedberg 
11057b1abbbeSJohan Hedberg 	if (event) {
11067b1abbbeSJohan Hedberg 		if (hdr->evt != event)
11077b1abbbeSJohan Hedberg 			goto failed;
11087b1abbbeSJohan Hedberg 		return skb;
11097b1abbbeSJohan Hedberg 	}
11107b1abbbeSJohan Hedberg 
111175e84b7cSJohan Hedberg 	if (hdr->evt != HCI_EV_CMD_COMPLETE) {
111275e84b7cSJohan Hedberg 		BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt);
111375e84b7cSJohan Hedberg 		goto failed;
111475e84b7cSJohan Hedberg 	}
111575e84b7cSJohan Hedberg 
111675e84b7cSJohan Hedberg 	if (skb->len < sizeof(*ev)) {
111775e84b7cSJohan Hedberg 		BT_ERR("Too short cmd_complete event");
111875e84b7cSJohan Hedberg 		goto failed;
111975e84b7cSJohan Hedberg 	}
112075e84b7cSJohan Hedberg 
112175e84b7cSJohan Hedberg 	ev = (void *) skb->data;
112275e84b7cSJohan Hedberg 	skb_pull(skb, sizeof(*ev));
112375e84b7cSJohan Hedberg 
112475e84b7cSJohan Hedberg 	if (opcode == __le16_to_cpu(ev->opcode))
112575e84b7cSJohan Hedberg 		return skb;
112675e84b7cSJohan Hedberg 
112775e84b7cSJohan Hedberg 	BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode,
112875e84b7cSJohan Hedberg 	       __le16_to_cpu(ev->opcode));
112975e84b7cSJohan Hedberg 
113075e84b7cSJohan Hedberg failed:
113175e84b7cSJohan Hedberg 	kfree_skb(skb);
113275e84b7cSJohan Hedberg 	return ERR_PTR(-ENODATA);
113375e84b7cSJohan Hedberg }
113475e84b7cSJohan Hedberg 
11357b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
113607dc93ddSJohan Hedberg 				  const void *param, u8 event, u32 timeout)
113775e84b7cSJohan Hedberg {
113875e84b7cSJohan Hedberg 	DECLARE_WAITQUEUE(wait, current);
113975e84b7cSJohan Hedberg 	struct hci_request req;
114075e84b7cSJohan Hedberg 	int err = 0;
114175e84b7cSJohan Hedberg 
114275e84b7cSJohan Hedberg 	BT_DBG("%s", hdev->name);
114375e84b7cSJohan Hedberg 
114475e84b7cSJohan Hedberg 	hci_req_init(&req, hdev);
114575e84b7cSJohan Hedberg 
11467b1abbbeSJohan Hedberg 	hci_req_add_ev(&req, opcode, plen, param, event);
114775e84b7cSJohan Hedberg 
114875e84b7cSJohan Hedberg 	hdev->req_status = HCI_REQ_PEND;
114975e84b7cSJohan Hedberg 
115075e84b7cSJohan Hedberg 	err = hci_req_run(&req, hci_req_sync_complete);
115175e84b7cSJohan Hedberg 	if (err < 0)
115275e84b7cSJohan Hedberg 		return ERR_PTR(err);
115375e84b7cSJohan Hedberg 
115475e84b7cSJohan Hedberg 	add_wait_queue(&hdev->req_wait_q, &wait);
115575e84b7cSJohan Hedberg 	set_current_state(TASK_INTERRUPTIBLE);
115675e84b7cSJohan Hedberg 
115775e84b7cSJohan Hedberg 	schedule_timeout(timeout);
115875e84b7cSJohan Hedberg 
115975e84b7cSJohan Hedberg 	remove_wait_queue(&hdev->req_wait_q, &wait);
116075e84b7cSJohan Hedberg 
116175e84b7cSJohan Hedberg 	if (signal_pending(current))
116275e84b7cSJohan Hedberg 		return ERR_PTR(-EINTR);
116375e84b7cSJohan Hedberg 
116475e84b7cSJohan Hedberg 	switch (hdev->req_status) {
116575e84b7cSJohan Hedberg 	case HCI_REQ_DONE:
116675e84b7cSJohan Hedberg 		err = -bt_to_errno(hdev->req_result);
116775e84b7cSJohan Hedberg 		break;
116875e84b7cSJohan Hedberg 
116975e84b7cSJohan Hedberg 	case HCI_REQ_CANCELED:
117075e84b7cSJohan Hedberg 		err = -hdev->req_result;
117175e84b7cSJohan Hedberg 		break;
117275e84b7cSJohan Hedberg 
117375e84b7cSJohan Hedberg 	default:
117475e84b7cSJohan Hedberg 		err = -ETIMEDOUT;
117575e84b7cSJohan Hedberg 		break;
117675e84b7cSJohan Hedberg 	}
117775e84b7cSJohan Hedberg 
117875e84b7cSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
117975e84b7cSJohan Hedberg 
118075e84b7cSJohan Hedberg 	BT_DBG("%s end: err %d", hdev->name, err);
118175e84b7cSJohan Hedberg 
118275e84b7cSJohan Hedberg 	if (err < 0)
118375e84b7cSJohan Hedberg 		return ERR_PTR(err);
118475e84b7cSJohan Hedberg 
11857b1abbbeSJohan Hedberg 	return hci_get_cmd_complete(hdev, opcode, event);
11867b1abbbeSJohan Hedberg }
11877b1abbbeSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync_ev);
11887b1abbbeSJohan Hedberg 
11897b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
119007dc93ddSJohan Hedberg 			       const void *param, u32 timeout)
11917b1abbbeSJohan Hedberg {
11927b1abbbeSJohan Hedberg 	return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout);
119375e84b7cSJohan Hedberg }
119475e84b7cSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync);
119575e84b7cSJohan Hedberg 
11961da177e4SLinus Torvalds /* Execute request and wait for completion. */
119701178cd4SJohan Hedberg static int __hci_req_sync(struct hci_dev *hdev,
119842c6b129SJohan Hedberg 			  void (*func)(struct hci_request *req,
119942c6b129SJohan Hedberg 				      unsigned long opt),
12001da177e4SLinus Torvalds 			  unsigned long opt, __u32 timeout)
12011da177e4SLinus Torvalds {
120242c6b129SJohan Hedberg 	struct hci_request req;
12031da177e4SLinus Torvalds 	DECLARE_WAITQUEUE(wait, current);
12041da177e4SLinus Torvalds 	int err = 0;
12051da177e4SLinus Torvalds 
12061da177e4SLinus Torvalds 	BT_DBG("%s start", hdev->name);
12071da177e4SLinus Torvalds 
120842c6b129SJohan Hedberg 	hci_req_init(&req, hdev);
120942c6b129SJohan Hedberg 
12101da177e4SLinus Torvalds 	hdev->req_status = HCI_REQ_PEND;
12111da177e4SLinus Torvalds 
121242c6b129SJohan Hedberg 	func(&req, opt);
121353cce22dSJohan Hedberg 
121442c6b129SJohan Hedberg 	err = hci_req_run(&req, hci_req_sync_complete);
121542c6b129SJohan Hedberg 	if (err < 0) {
121653cce22dSJohan Hedberg 		hdev->req_status = 0;
1217920c8300SAndre Guedes 
1218920c8300SAndre Guedes 		/* ENODATA means the HCI request command queue is empty.
1219920c8300SAndre Guedes 		 * This can happen when a request with conditionals doesn't
1220920c8300SAndre Guedes 		 * trigger any commands to be sent. This is normal behavior
1221920c8300SAndre Guedes 		 * and should not trigger an error return.
122242c6b129SJohan Hedberg 		 */
1223920c8300SAndre Guedes 		if (err == -ENODATA)
122442c6b129SJohan Hedberg 			return 0;
1225920c8300SAndre Guedes 
1226920c8300SAndre Guedes 		return err;
122753cce22dSJohan Hedberg 	}
122853cce22dSJohan Hedberg 
1229bc4445c7SAndre Guedes 	add_wait_queue(&hdev->req_wait_q, &wait);
1230bc4445c7SAndre Guedes 	set_current_state(TASK_INTERRUPTIBLE);
1231bc4445c7SAndre Guedes 
12321da177e4SLinus Torvalds 	schedule_timeout(timeout);
12331da177e4SLinus Torvalds 
12341da177e4SLinus Torvalds 	remove_wait_queue(&hdev->req_wait_q, &wait);
12351da177e4SLinus Torvalds 
12361da177e4SLinus Torvalds 	if (signal_pending(current))
12371da177e4SLinus Torvalds 		return -EINTR;
12381da177e4SLinus Torvalds 
12391da177e4SLinus Torvalds 	switch (hdev->req_status) {
12401da177e4SLinus Torvalds 	case HCI_REQ_DONE:
1241e175072fSJoe Perches 		err = -bt_to_errno(hdev->req_result);
12421da177e4SLinus Torvalds 		break;
12431da177e4SLinus Torvalds 
12441da177e4SLinus Torvalds 	case HCI_REQ_CANCELED:
12451da177e4SLinus Torvalds 		err = -hdev->req_result;
12461da177e4SLinus Torvalds 		break;
12471da177e4SLinus Torvalds 
12481da177e4SLinus Torvalds 	default:
12491da177e4SLinus Torvalds 		err = -ETIMEDOUT;
12501da177e4SLinus Torvalds 		break;
12513ff50b79SStephen Hemminger 	}
12521da177e4SLinus Torvalds 
1253a5040efaSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
12541da177e4SLinus Torvalds 
12551da177e4SLinus Torvalds 	BT_DBG("%s end: err %d", hdev->name, err);
12561da177e4SLinus Torvalds 
12571da177e4SLinus Torvalds 	return err;
12581da177e4SLinus Torvalds }
12591da177e4SLinus Torvalds 
126001178cd4SJohan Hedberg static int hci_req_sync(struct hci_dev *hdev,
126142c6b129SJohan Hedberg 			void (*req)(struct hci_request *req,
126242c6b129SJohan Hedberg 				    unsigned long opt),
12631da177e4SLinus Torvalds 			unsigned long opt, __u32 timeout)
12641da177e4SLinus Torvalds {
12651da177e4SLinus Torvalds 	int ret;
12661da177e4SLinus Torvalds 
12677c6a329eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
12687c6a329eSMarcel Holtmann 		return -ENETDOWN;
12697c6a329eSMarcel Holtmann 
12701da177e4SLinus Torvalds 	/* Serialize all requests */
12711da177e4SLinus Torvalds 	hci_req_lock(hdev);
127201178cd4SJohan Hedberg 	ret = __hci_req_sync(hdev, req, opt, timeout);
12731da177e4SLinus Torvalds 	hci_req_unlock(hdev);
12741da177e4SLinus Torvalds 
12751da177e4SLinus Torvalds 	return ret;
12761da177e4SLinus Torvalds }
12771da177e4SLinus Torvalds 
127842c6b129SJohan Hedberg static void hci_reset_req(struct hci_request *req, unsigned long opt)
12791da177e4SLinus Torvalds {
128042c6b129SJohan Hedberg 	BT_DBG("%s %ld", req->hdev->name, opt);
12811da177e4SLinus Torvalds 
12821da177e4SLinus Torvalds 	/* Reset device */
128342c6b129SJohan Hedberg 	set_bit(HCI_RESET, &req->hdev->flags);
128442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_RESET, 0, NULL);
12851da177e4SLinus Torvalds }
12861da177e4SLinus Torvalds 
128742c6b129SJohan Hedberg static void bredr_init(struct hci_request *req)
12881da177e4SLinus Torvalds {
128942c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
12902455a3eaSAndrei Emeltchenko 
12911da177e4SLinus Torvalds 	/* Read Local Supported Features */
129242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
12931da177e4SLinus Torvalds 
12941143e5a6SMarcel Holtmann 	/* Read Local Version */
129542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
12962177bab5SJohan Hedberg 
12972177bab5SJohan Hedberg 	/* Read BD Address */
129842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
12991da177e4SLinus Torvalds }
13001da177e4SLinus Torvalds 
130142c6b129SJohan Hedberg static void amp_init(struct hci_request *req)
1302e61ef499SAndrei Emeltchenko {
130342c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
13042455a3eaSAndrei Emeltchenko 
1305e61ef499SAndrei Emeltchenko 	/* Read Local Version */
130642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
13076bcbc489SAndrei Emeltchenko 
1308f6996cfeSMarcel Holtmann 	/* Read Local Supported Commands */
1309f6996cfeSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
1310f6996cfeSMarcel Holtmann 
1311f6996cfeSMarcel Holtmann 	/* Read Local Supported Features */
1312f6996cfeSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
1313f6996cfeSMarcel Holtmann 
13146bcbc489SAndrei Emeltchenko 	/* Read Local AMP Info */
131542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
1316e71dfabaSAndrei Emeltchenko 
1317e71dfabaSAndrei Emeltchenko 	/* Read Data Blk size */
131842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL);
13197528ca1cSMarcel Holtmann 
1320f38ba941SMarcel Holtmann 	/* Read Flow Control Mode */
1321f38ba941SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL);
1322f38ba941SMarcel Holtmann 
13237528ca1cSMarcel Holtmann 	/* Read Location Data */
13247528ca1cSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL);
1325e61ef499SAndrei Emeltchenko }
1326e61ef499SAndrei Emeltchenko 
132742c6b129SJohan Hedberg static void hci_init1_req(struct hci_request *req, unsigned long opt)
1328e61ef499SAndrei Emeltchenko {
132942c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1330e61ef499SAndrei Emeltchenko 
1331e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
1332e61ef499SAndrei Emeltchenko 
133311778716SAndrei Emeltchenko 	/* Reset */
133411778716SAndrei Emeltchenko 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
133542c6b129SJohan Hedberg 		hci_reset_req(req, 0);
133611778716SAndrei Emeltchenko 
1337e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
1338e61ef499SAndrei Emeltchenko 	case HCI_BREDR:
133942c6b129SJohan Hedberg 		bredr_init(req);
1340e61ef499SAndrei Emeltchenko 		break;
1341e61ef499SAndrei Emeltchenko 
1342e61ef499SAndrei Emeltchenko 	case HCI_AMP:
134342c6b129SJohan Hedberg 		amp_init(req);
1344e61ef499SAndrei Emeltchenko 		break;
1345e61ef499SAndrei Emeltchenko 
1346e61ef499SAndrei Emeltchenko 	default:
1347e61ef499SAndrei Emeltchenko 		BT_ERR("Unknown device type %d", hdev->dev_type);
1348e61ef499SAndrei Emeltchenko 		break;
1349e61ef499SAndrei Emeltchenko 	}
1350e61ef499SAndrei Emeltchenko }
1351e61ef499SAndrei Emeltchenko 
135242c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req)
13532177bab5SJohan Hedberg {
13544ca048e3SMarcel Holtmann 	struct hci_dev *hdev = req->hdev;
13554ca048e3SMarcel Holtmann 
13562177bab5SJohan Hedberg 	__le16 param;
13572177bab5SJohan Hedberg 	__u8 flt_type;
13582177bab5SJohan Hedberg 
13592177bab5SJohan Hedberg 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
136042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
13612177bab5SJohan Hedberg 
13622177bab5SJohan Hedberg 	/* Read Class of Device */
136342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
13642177bab5SJohan Hedberg 
13652177bab5SJohan Hedberg 	/* Read Local Name */
136642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL);
13672177bab5SJohan Hedberg 
13682177bab5SJohan Hedberg 	/* Read Voice Setting */
136942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL);
13702177bab5SJohan Hedberg 
1371b4cb9fb2SMarcel Holtmann 	/* Read Number of Supported IAC */
1372b4cb9fb2SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL);
1373b4cb9fb2SMarcel Holtmann 
13744b836f39SMarcel Holtmann 	/* Read Current IAC LAP */
13754b836f39SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL);
13764b836f39SMarcel Holtmann 
13772177bab5SJohan Hedberg 	/* Clear Event Filters */
13782177bab5SJohan Hedberg 	flt_type = HCI_FLT_CLEAR_ALL;
137942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
13802177bab5SJohan Hedberg 
13812177bab5SJohan Hedberg 	/* Connection accept timeout ~20 secs */
1382dcf4adbfSJoe Perches 	param = cpu_to_le16(0x7d00);
138342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
13842177bab5SJohan Hedberg 
13854ca048e3SMarcel Holtmann 	/* AVM Berlin (31), aka "BlueFRITZ!", reports version 1.2,
13864ca048e3SMarcel Holtmann 	 * but it does not support page scan related HCI commands.
13874ca048e3SMarcel Holtmann 	 */
13884ca048e3SMarcel Holtmann 	if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) {
1389f332ec66SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL);
1390f332ec66SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL);
1391f332ec66SJohan Hedberg 	}
13922177bab5SJohan Hedberg }
13932177bab5SJohan Hedberg 
139442c6b129SJohan Hedberg static void le_setup(struct hci_request *req)
13952177bab5SJohan Hedberg {
1396c73eee91SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1397c73eee91SJohan Hedberg 
13982177bab5SJohan Hedberg 	/* Read LE Buffer Size */
139942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
14002177bab5SJohan Hedberg 
14012177bab5SJohan Hedberg 	/* Read LE Local Supported Features */
140242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
14032177bab5SJohan Hedberg 
1404747d3f03SMarcel Holtmann 	/* Read LE Supported States */
1405747d3f03SMarcel Holtmann 	hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);
1406747d3f03SMarcel Holtmann 
14072177bab5SJohan Hedberg 	/* Read LE White List Size */
140842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL);
14092177bab5SJohan Hedberg 
1410747d3f03SMarcel Holtmann 	/* Clear LE White List */
1411747d3f03SMarcel Holtmann 	hci_req_add(req, HCI_OP_LE_CLEAR_WHITE_LIST, 0, NULL);
1412c73eee91SJohan Hedberg 
1413c73eee91SJohan Hedberg 	/* LE-only controllers have LE implicitly enabled */
1414c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
1415c73eee91SJohan Hedberg 		set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
14162177bab5SJohan Hedberg }
14172177bab5SJohan Hedberg 
14182177bab5SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
14192177bab5SJohan Hedberg {
14202177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
14212177bab5SJohan Hedberg 		return 0x02;
14222177bab5SJohan Hedberg 
14232177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
14242177bab5SJohan Hedberg 		return 0x01;
14252177bab5SJohan Hedberg 
14262177bab5SJohan Hedberg 	if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
14272177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x0757)
14282177bab5SJohan Hedberg 		return 0x01;
14292177bab5SJohan Hedberg 
14302177bab5SJohan Hedberg 	if (hdev->manufacturer == 15) {
14312177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
14322177bab5SJohan Hedberg 			return 0x01;
14332177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
14342177bab5SJohan Hedberg 			return 0x01;
14352177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
14362177bab5SJohan Hedberg 			return 0x01;
14372177bab5SJohan Hedberg 	}
14382177bab5SJohan Hedberg 
14392177bab5SJohan Hedberg 	if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
14402177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x1805)
14412177bab5SJohan Hedberg 		return 0x01;
14422177bab5SJohan Hedberg 
14432177bab5SJohan Hedberg 	return 0x00;
14442177bab5SJohan Hedberg }
14452177bab5SJohan Hedberg 
144642c6b129SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_request *req)
14472177bab5SJohan Hedberg {
14482177bab5SJohan Hedberg 	u8 mode;
14492177bab5SJohan Hedberg 
145042c6b129SJohan Hedberg 	mode = hci_get_inquiry_mode(req->hdev);
14512177bab5SJohan Hedberg 
145242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
14532177bab5SJohan Hedberg }
14542177bab5SJohan Hedberg 
145542c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req)
14562177bab5SJohan Hedberg {
145742c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
145842c6b129SJohan Hedberg 
14592177bab5SJohan Hedberg 	/* The second byte is 0xff instead of 0x9f (two reserved bits
14602177bab5SJohan Hedberg 	 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
14612177bab5SJohan Hedberg 	 * command otherwise.
14622177bab5SJohan Hedberg 	 */
14632177bab5SJohan Hedberg 	u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
14642177bab5SJohan Hedberg 
14652177bab5SJohan Hedberg 	/* CSR 1.1 dongles does not accept any bitfield so don't try to set
14662177bab5SJohan Hedberg 	 * any event mask for pre 1.2 devices.
14672177bab5SJohan Hedberg 	 */
14682177bab5SJohan Hedberg 	if (hdev->hci_ver < BLUETOOTH_VER_1_2)
14692177bab5SJohan Hedberg 		return;
14702177bab5SJohan Hedberg 
14712177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
14722177bab5SJohan Hedberg 		events[4] |= 0x01; /* Flow Specification Complete */
14732177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
14742177bab5SJohan Hedberg 		events[4] |= 0x04; /* Read Remote Extended Features Complete */
14752177bab5SJohan Hedberg 		events[5] |= 0x08; /* Synchronous Connection Complete */
14762177bab5SJohan Hedberg 		events[5] |= 0x10; /* Synchronous Connection Changed */
1477c7882cbdSMarcel Holtmann 	} else {
1478c7882cbdSMarcel Holtmann 		/* Use a different default for LE-only devices */
1479c7882cbdSMarcel Holtmann 		memset(events, 0, sizeof(events));
1480c7882cbdSMarcel Holtmann 		events[0] |= 0x10; /* Disconnection Complete */
1481c7882cbdSMarcel Holtmann 		events[1] |= 0x08; /* Read Remote Version Information Complete */
1482c7882cbdSMarcel Holtmann 		events[1] |= 0x20; /* Command Complete */
1483c7882cbdSMarcel Holtmann 		events[1] |= 0x40; /* Command Status */
1484c7882cbdSMarcel Holtmann 		events[1] |= 0x80; /* Hardware Error */
1485c7882cbdSMarcel Holtmann 		events[2] |= 0x04; /* Number of Completed Packets */
1486c7882cbdSMarcel Holtmann 		events[3] |= 0x02; /* Data Buffer Overflow */
14870da71f1bSMarcel Holtmann 
14880da71f1bSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_ENCRYPTION) {
14890da71f1bSMarcel Holtmann 			events[0] |= 0x80; /* Encryption Change */
1490c7882cbdSMarcel Holtmann 			events[5] |= 0x80; /* Encryption Key Refresh Complete */
14912177bab5SJohan Hedberg 		}
14920da71f1bSMarcel Holtmann 	}
14932177bab5SJohan Hedberg 
14942177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
14952177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
14962177bab5SJohan Hedberg 
14972177bab5SJohan Hedberg 	if (lmp_sniffsubr_capable(hdev))
14982177bab5SJohan Hedberg 		events[5] |= 0x20; /* Sniff Subrating */
14992177bab5SJohan Hedberg 
15002177bab5SJohan Hedberg 	if (lmp_pause_enc_capable(hdev))
15012177bab5SJohan Hedberg 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
15022177bab5SJohan Hedberg 
15032177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
15042177bab5SJohan Hedberg 		events[5] |= 0x40; /* Extended Inquiry Result */
15052177bab5SJohan Hedberg 
15062177bab5SJohan Hedberg 	if (lmp_no_flush_capable(hdev))
15072177bab5SJohan Hedberg 		events[7] |= 0x01; /* Enhanced Flush Complete */
15082177bab5SJohan Hedberg 
15092177bab5SJohan Hedberg 	if (lmp_lsto_capable(hdev))
15102177bab5SJohan Hedberg 		events[6] |= 0x80; /* Link Supervision Timeout Changed */
15112177bab5SJohan Hedberg 
15122177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
15132177bab5SJohan Hedberg 		events[6] |= 0x01;	/* IO Capability Request */
15142177bab5SJohan Hedberg 		events[6] |= 0x02;	/* IO Capability Response */
15152177bab5SJohan Hedberg 		events[6] |= 0x04;	/* User Confirmation Request */
15162177bab5SJohan Hedberg 		events[6] |= 0x08;	/* User Passkey Request */
15172177bab5SJohan Hedberg 		events[6] |= 0x10;	/* Remote OOB Data Request */
15182177bab5SJohan Hedberg 		events[6] |= 0x20;	/* Simple Pairing Complete */
15192177bab5SJohan Hedberg 		events[7] |= 0x04;	/* User Passkey Notification */
15202177bab5SJohan Hedberg 		events[7] |= 0x08;	/* Keypress Notification */
15212177bab5SJohan Hedberg 		events[7] |= 0x10;	/* Remote Host Supported
15222177bab5SJohan Hedberg 					 * Features Notification
15232177bab5SJohan Hedberg 					 */
15242177bab5SJohan Hedberg 	}
15252177bab5SJohan Hedberg 
15262177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
15272177bab5SJohan Hedberg 		events[7] |= 0x20;	/* LE Meta-Event */
15282177bab5SJohan Hedberg 
152942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
15302177bab5SJohan Hedberg }
15312177bab5SJohan Hedberg 
153242c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt)
15332177bab5SJohan Hedberg {
153442c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
153542c6b129SJohan Hedberg 
15362177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev))
153742c6b129SJohan Hedberg 		bredr_setup(req);
153856f87901SJohan Hedberg 	else
153956f87901SJohan Hedberg 		clear_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
15402177bab5SJohan Hedberg 
15412177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
154242c6b129SJohan Hedberg 		le_setup(req);
15432177bab5SJohan Hedberg 
15443f8e2d75SJohan Hedberg 	/* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read
15453f8e2d75SJohan Hedberg 	 * local supported commands HCI command.
15463f8e2d75SJohan Hedberg 	 */
15473f8e2d75SJohan Hedberg 	if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1)
154842c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
15492177bab5SJohan Hedberg 
15502177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
155157af75a8SMarcel Holtmann 		/* When SSP is available, then the host features page
155257af75a8SMarcel Holtmann 		 * should also be available as well. However some
155357af75a8SMarcel Holtmann 		 * controllers list the max_page as 0 as long as SSP
155457af75a8SMarcel Holtmann 		 * has not been enabled. To achieve proper debugging
155557af75a8SMarcel Holtmann 		 * output, force the minimum max_page to 1 at least.
155657af75a8SMarcel Holtmann 		 */
155757af75a8SMarcel Holtmann 		hdev->max_page = 0x01;
155857af75a8SMarcel Holtmann 
15592177bab5SJohan Hedberg 		if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
15602177bab5SJohan Hedberg 			u8 mode = 0x01;
156142c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_SSP_MODE,
15622177bab5SJohan Hedberg 				    sizeof(mode), &mode);
15632177bab5SJohan Hedberg 		} else {
15642177bab5SJohan Hedberg 			struct hci_cp_write_eir cp;
15652177bab5SJohan Hedberg 
15662177bab5SJohan Hedberg 			memset(hdev->eir, 0, sizeof(hdev->eir));
15672177bab5SJohan Hedberg 			memset(&cp, 0, sizeof(cp));
15682177bab5SJohan Hedberg 
156942c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
15702177bab5SJohan Hedberg 		}
15712177bab5SJohan Hedberg 	}
15722177bab5SJohan Hedberg 
15732177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
157442c6b129SJohan Hedberg 		hci_setup_inquiry_mode(req);
15752177bab5SJohan Hedberg 
15762177bab5SJohan Hedberg 	if (lmp_inq_tx_pwr_capable(hdev))
157742c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
15782177bab5SJohan Hedberg 
15792177bab5SJohan Hedberg 	if (lmp_ext_feat_capable(hdev)) {
15802177bab5SJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
15812177bab5SJohan Hedberg 
15822177bab5SJohan Hedberg 		cp.page = 0x01;
158342c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
158442c6b129SJohan Hedberg 			    sizeof(cp), &cp);
15852177bab5SJohan Hedberg 	}
15862177bab5SJohan Hedberg 
15872177bab5SJohan Hedberg 	if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
15882177bab5SJohan Hedberg 		u8 enable = 1;
158942c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
15902177bab5SJohan Hedberg 			    &enable);
15912177bab5SJohan Hedberg 	}
15922177bab5SJohan Hedberg }
15932177bab5SJohan Hedberg 
159442c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req)
15952177bab5SJohan Hedberg {
159642c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
15972177bab5SJohan Hedberg 	struct hci_cp_write_def_link_policy cp;
15982177bab5SJohan Hedberg 	u16 link_policy = 0;
15992177bab5SJohan Hedberg 
16002177bab5SJohan Hedberg 	if (lmp_rswitch_capable(hdev))
16012177bab5SJohan Hedberg 		link_policy |= HCI_LP_RSWITCH;
16022177bab5SJohan Hedberg 	if (lmp_hold_capable(hdev))
16032177bab5SJohan Hedberg 		link_policy |= HCI_LP_HOLD;
16042177bab5SJohan Hedberg 	if (lmp_sniff_capable(hdev))
16052177bab5SJohan Hedberg 		link_policy |= HCI_LP_SNIFF;
16062177bab5SJohan Hedberg 	if (lmp_park_capable(hdev))
16072177bab5SJohan Hedberg 		link_policy |= HCI_LP_PARK;
16082177bab5SJohan Hedberg 
16092177bab5SJohan Hedberg 	cp.policy = cpu_to_le16(link_policy);
161042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp);
16112177bab5SJohan Hedberg }
16122177bab5SJohan Hedberg 
161342c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req)
16142177bab5SJohan Hedberg {
161542c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
16162177bab5SJohan Hedberg 	struct hci_cp_write_le_host_supported cp;
16172177bab5SJohan Hedberg 
1618c73eee91SJohan Hedberg 	/* LE-only devices do not support explicit enablement */
1619c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
1620c73eee91SJohan Hedberg 		return;
1621c73eee91SJohan Hedberg 
16222177bab5SJohan Hedberg 	memset(&cp, 0, sizeof(cp));
16232177bab5SJohan Hedberg 
16242177bab5SJohan Hedberg 	if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
16252177bab5SJohan Hedberg 		cp.le = 0x01;
162632226e4fSMarcel Holtmann 		cp.simul = 0x00;
16272177bab5SJohan Hedberg 	}
16282177bab5SJohan Hedberg 
16292177bab5SJohan Hedberg 	if (cp.le != lmp_host_le_capable(hdev))
163042c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
16312177bab5SJohan Hedberg 			    &cp);
16322177bab5SJohan Hedberg }
16332177bab5SJohan Hedberg 
1634d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req)
1635d62e6d67SJohan Hedberg {
1636d62e6d67SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1637d62e6d67SJohan Hedberg 	u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1638d62e6d67SJohan Hedberg 
1639d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast master role is supported
1640d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
1641d62e6d67SJohan Hedberg 	 */
164253b834d2SMarcel Holtmann 	if (lmp_csb_master_capable(hdev)) {
1643d62e6d67SJohan Hedberg 		events[1] |= 0x40;	/* Triggered Clock Capture */
1644d62e6d67SJohan Hedberg 		events[1] |= 0x80;	/* Synchronization Train Complete */
1645d62e6d67SJohan Hedberg 		events[2] |= 0x10;	/* Slave Page Response Timeout */
1646d62e6d67SJohan Hedberg 		events[2] |= 0x20;	/* CSB Channel Map Change */
1647d62e6d67SJohan Hedberg 	}
1648d62e6d67SJohan Hedberg 
1649d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast slave role is supported
1650d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
1651d62e6d67SJohan Hedberg 	 */
165253b834d2SMarcel Holtmann 	if (lmp_csb_slave_capable(hdev)) {
1653d62e6d67SJohan Hedberg 		events[2] |= 0x01;	/* Synchronization Train Received */
1654d62e6d67SJohan Hedberg 		events[2] |= 0x02;	/* CSB Receive */
1655d62e6d67SJohan Hedberg 		events[2] |= 0x04;	/* CSB Timeout */
1656d62e6d67SJohan Hedberg 		events[2] |= 0x08;	/* Truncated Page Complete */
1657d62e6d67SJohan Hedberg 	}
1658d62e6d67SJohan Hedberg 
165940c59fcbSMarcel Holtmann 	/* Enable Authenticated Payload Timeout Expired event if supported */
1660cd7ca0ecSMarcel Holtmann 	if (lmp_ping_capable(hdev) || hdev->le_features[0] & HCI_LE_PING)
166140c59fcbSMarcel Holtmann 		events[2] |= 0x80;
166240c59fcbSMarcel Holtmann 
1663d62e6d67SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events);
1664d62e6d67SJohan Hedberg }
1665d62e6d67SJohan Hedberg 
166642c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt)
16672177bab5SJohan Hedberg {
166842c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1669d2c5d77fSJohan Hedberg 	u8 p;
167042c6b129SJohan Hedberg 
16710da71f1bSMarcel Holtmann 	hci_setup_event_mask(req);
16720da71f1bSMarcel Holtmann 
1673b8f4e068SGustavo Padovan 	/* Some Broadcom based Bluetooth controllers do not support the
1674b8f4e068SGustavo Padovan 	 * Delete Stored Link Key command. They are clearly indicating its
1675b8f4e068SGustavo Padovan 	 * absence in the bit mask of supported commands.
1676b8f4e068SGustavo Padovan 	 *
1677b8f4e068SGustavo Padovan 	 * Check the supported commands and only if the the command is marked
1678b8f4e068SGustavo Padovan 	 * as supported send it. If not supported assume that the controller
1679b8f4e068SGustavo Padovan 	 * does not have actual support for stored link keys which makes this
1680b8f4e068SGustavo Padovan 	 * command redundant anyway.
1681f9f462faSMarcel Holtmann 	 *
1682f9f462faSMarcel Holtmann 	 * Some controllers indicate that they support handling deleting
1683f9f462faSMarcel Holtmann 	 * stored link keys, but they don't. The quirk lets a driver
1684f9f462faSMarcel Holtmann 	 * just disable this command.
1685b8f4e068SGustavo Padovan 	 */
1686f9f462faSMarcel Holtmann 	if (hdev->commands[6] & 0x80 &&
1687f9f462faSMarcel Holtmann 	    !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) {
168859f45d57SJohan Hedberg 		struct hci_cp_delete_stored_link_key cp;
168959f45d57SJohan Hedberg 
169059f45d57SJohan Hedberg 		bacpy(&cp.bdaddr, BDADDR_ANY);
169159f45d57SJohan Hedberg 		cp.delete_all = 0x01;
169259f45d57SJohan Hedberg 		hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY,
169359f45d57SJohan Hedberg 			    sizeof(cp), &cp);
169459f45d57SJohan Hedberg 	}
169559f45d57SJohan Hedberg 
16962177bab5SJohan Hedberg 	if (hdev->commands[5] & 0x10)
169742c6b129SJohan Hedberg 		hci_setup_link_policy(req);
16982177bab5SJohan Hedberg 
16999193c6e8SAndre Guedes 	if (lmp_le_capable(hdev)) {
17009193c6e8SAndre Guedes 		u8 events[8];
17019193c6e8SAndre Guedes 
17029193c6e8SAndre Guedes 		memset(events, 0, sizeof(events));
17034d6c705bSMarcel Holtmann 		events[0] = 0x0f;
17044d6c705bSMarcel Holtmann 
17054d6c705bSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_ENCRYPTION)
17064d6c705bSMarcel Holtmann 			events[0] |= 0x10;	/* LE Long Term Key Request */
1707662bc2e6SAndre Guedes 
1708662bc2e6SAndre Guedes 		/* If controller supports the Connection Parameters Request
1709662bc2e6SAndre Guedes 		 * Link Layer Procedure, enable the corresponding event.
1710662bc2e6SAndre Guedes 		 */
1711662bc2e6SAndre Guedes 		if (hdev->le_features[0] & HCI_LE_CONN_PARAM_REQ_PROC)
1712662bc2e6SAndre Guedes 			events[0] |= 0x20;	/* LE Remote Connection
1713662bc2e6SAndre Guedes 						 * Parameter Request
1714662bc2e6SAndre Guedes 						 */
1715662bc2e6SAndre Guedes 
17169193c6e8SAndre Guedes 		hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, sizeof(events),
17179193c6e8SAndre Guedes 			    events);
17189193c6e8SAndre Guedes 
171915a49ccaSMarcel Holtmann 		if (hdev->commands[25] & 0x40) {
172015a49ccaSMarcel Holtmann 			/* Read LE Advertising Channel TX Power */
172115a49ccaSMarcel Holtmann 			hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
172215a49ccaSMarcel Holtmann 		}
172315a49ccaSMarcel Holtmann 
172442c6b129SJohan Hedberg 		hci_set_le_support(req);
17259193c6e8SAndre Guedes 	}
1726d2c5d77fSJohan Hedberg 
1727d2c5d77fSJohan Hedberg 	/* Read features beyond page 1 if available */
1728d2c5d77fSJohan Hedberg 	for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
1729d2c5d77fSJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
1730d2c5d77fSJohan Hedberg 
1731d2c5d77fSJohan Hedberg 		cp.page = p;
1732d2c5d77fSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
1733d2c5d77fSJohan Hedberg 			    sizeof(cp), &cp);
1734d2c5d77fSJohan Hedberg 	}
17352177bab5SJohan Hedberg }
17362177bab5SJohan Hedberg 
17375d4e7e8dSJohan Hedberg static void hci_init4_req(struct hci_request *req, unsigned long opt)
17385d4e7e8dSJohan Hedberg {
17395d4e7e8dSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
17405d4e7e8dSJohan Hedberg 
1741d62e6d67SJohan Hedberg 	/* Set event mask page 2 if the HCI command for it is supported */
1742d62e6d67SJohan Hedberg 	if (hdev->commands[22] & 0x04)
1743d62e6d67SJohan Hedberg 		hci_set_event_mask_page_2(req);
1744d62e6d67SJohan Hedberg 
1745109e3191SMarcel Holtmann 	/* Read local codec list if the HCI command is supported */
1746109e3191SMarcel Holtmann 	if (hdev->commands[29] & 0x20)
1747109e3191SMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_LOCAL_CODECS, 0, NULL);
1748109e3191SMarcel Holtmann 
1749f4fe73edSMarcel Holtmann 	/* Get MWS transport configuration if the HCI command is supported */
1750f4fe73edSMarcel Holtmann 	if (hdev->commands[30] & 0x08)
1751f4fe73edSMarcel Holtmann 		hci_req_add(req, HCI_OP_GET_MWS_TRANSPORT_CONFIG, 0, NULL);
1752f4fe73edSMarcel Holtmann 
17535d4e7e8dSJohan Hedberg 	/* Check for Synchronization Train support */
175453b834d2SMarcel Holtmann 	if (lmp_sync_train_capable(hdev))
17555d4e7e8dSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL);
1756a6d0d690SMarcel Holtmann 
1757a6d0d690SMarcel Holtmann 	/* Enable Secure Connections if supported and configured */
17585afeac14SMarcel Holtmann 	if ((lmp_sc_capable(hdev) ||
1759111902f7SMarcel Holtmann 	     test_bit(HCI_FORCE_SC, &hdev->dbg_flags)) &&
1760a6d0d690SMarcel Holtmann 	    test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
1761a6d0d690SMarcel Holtmann 		u8 support = 0x01;
1762a6d0d690SMarcel Holtmann 		hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT,
1763a6d0d690SMarcel Holtmann 			    sizeof(support), &support);
1764a6d0d690SMarcel Holtmann 	}
17655d4e7e8dSJohan Hedberg }
17665d4e7e8dSJohan Hedberg 
17672177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev)
17682177bab5SJohan Hedberg {
17692177bab5SJohan Hedberg 	int err;
17702177bab5SJohan Hedberg 
17712177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT);
17722177bab5SJohan Hedberg 	if (err < 0)
17732177bab5SJohan Hedberg 		return err;
17742177bab5SJohan Hedberg 
17754b4148e9SMarcel Holtmann 	/* The Device Under Test (DUT) mode is special and available for
17764b4148e9SMarcel Holtmann 	 * all controller types. So just create it early on.
17774b4148e9SMarcel Holtmann 	 */
17784b4148e9SMarcel Holtmann 	if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
17794b4148e9SMarcel Holtmann 		debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev,
17804b4148e9SMarcel Holtmann 				    &dut_mode_fops);
17814b4148e9SMarcel Holtmann 	}
17824b4148e9SMarcel Holtmann 
17832177bab5SJohan Hedberg 	/* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode
17842177bab5SJohan Hedberg 	 * BR/EDR/LE type controllers. AMP controllers only need the
17852177bab5SJohan Hedberg 	 * first stage init.
17862177bab5SJohan Hedberg 	 */
17872177bab5SJohan Hedberg 	if (hdev->dev_type != HCI_BREDR)
17882177bab5SJohan Hedberg 		return 0;
17892177bab5SJohan Hedberg 
17902177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT);
17912177bab5SJohan Hedberg 	if (err < 0)
17922177bab5SJohan Hedberg 		return err;
17932177bab5SJohan Hedberg 
17945d4e7e8dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT);
17955d4e7e8dSJohan Hedberg 	if (err < 0)
17965d4e7e8dSJohan Hedberg 		return err;
17975d4e7e8dSJohan Hedberg 
1798baf27f6eSMarcel Holtmann 	err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT);
1799baf27f6eSMarcel Holtmann 	if (err < 0)
1800baf27f6eSMarcel Holtmann 		return err;
1801baf27f6eSMarcel Holtmann 
1802baf27f6eSMarcel Holtmann 	/* Only create debugfs entries during the initial setup
1803baf27f6eSMarcel Holtmann 	 * phase and not every time the controller gets powered on.
1804baf27f6eSMarcel Holtmann 	 */
1805baf27f6eSMarcel Holtmann 	if (!test_bit(HCI_SETUP, &hdev->dev_flags))
1806baf27f6eSMarcel Holtmann 		return 0;
1807baf27f6eSMarcel Holtmann 
1808dfb826a8SMarcel Holtmann 	debugfs_create_file("features", 0444, hdev->debugfs, hdev,
1809dfb826a8SMarcel Holtmann 			    &features_fops);
1810ceeb3bc0SMarcel Holtmann 	debugfs_create_u16("manufacturer", 0444, hdev->debugfs,
1811ceeb3bc0SMarcel Holtmann 			   &hdev->manufacturer);
1812ceeb3bc0SMarcel Holtmann 	debugfs_create_u8("hci_version", 0444, hdev->debugfs, &hdev->hci_ver);
1813ceeb3bc0SMarcel Holtmann 	debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev);
181470afe0b8SMarcel Holtmann 	debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev,
181570afe0b8SMarcel Holtmann 			    &blacklist_fops);
18166659358eSJohan Hedberg 	debugfs_create_file("whitelist", 0444, hdev->debugfs, hdev,
18176659358eSJohan Hedberg 			    &whitelist_fops);
181847219839SMarcel Holtmann 	debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops);
181947219839SMarcel Holtmann 
182031ad1691SAndrzej Kaczmarek 	debugfs_create_file("conn_info_min_age", 0644, hdev->debugfs, hdev,
182131ad1691SAndrzej Kaczmarek 			    &conn_info_min_age_fops);
182231ad1691SAndrzej Kaczmarek 	debugfs_create_file("conn_info_max_age", 0644, hdev->debugfs, hdev,
182331ad1691SAndrzej Kaczmarek 			    &conn_info_max_age_fops);
182431ad1691SAndrzej Kaczmarek 
1825baf27f6eSMarcel Holtmann 	if (lmp_bredr_capable(hdev)) {
1826baf27f6eSMarcel Holtmann 		debugfs_create_file("inquiry_cache", 0444, hdev->debugfs,
1827baf27f6eSMarcel Holtmann 				    hdev, &inquiry_cache_fops);
182802d08d15SMarcel Holtmann 		debugfs_create_file("link_keys", 0400, hdev->debugfs,
182902d08d15SMarcel Holtmann 				    hdev, &link_keys_fops);
1830babdbb3cSMarcel Holtmann 		debugfs_create_file("dev_class", 0444, hdev->debugfs,
1831babdbb3cSMarcel Holtmann 				    hdev, &dev_class_fops);
1832041000b9SMarcel Holtmann 		debugfs_create_file("voice_setting", 0444, hdev->debugfs,
1833041000b9SMarcel Holtmann 				    hdev, &voice_setting_fops);
1834baf27f6eSMarcel Holtmann 	}
1835baf27f6eSMarcel Holtmann 
183606f5b778SMarcel Holtmann 	if (lmp_ssp_capable(hdev)) {
1837ebd1e33bSMarcel Holtmann 		debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs,
1838ebd1e33bSMarcel Holtmann 				    hdev, &auto_accept_delay_fops);
18395afeac14SMarcel Holtmann 		debugfs_create_file("force_sc_support", 0644, hdev->debugfs,
18405afeac14SMarcel Holtmann 				    hdev, &force_sc_support_fops);
1841134c2a89SMarcel Holtmann 		debugfs_create_file("sc_only_mode", 0444, hdev->debugfs,
1842134c2a89SMarcel Holtmann 				    hdev, &sc_only_mode_fops);
184306f5b778SMarcel Holtmann 	}
1844ebd1e33bSMarcel Holtmann 
18452bfa3531SMarcel Holtmann 	if (lmp_sniff_capable(hdev)) {
18462bfa3531SMarcel Holtmann 		debugfs_create_file("idle_timeout", 0644, hdev->debugfs,
18472bfa3531SMarcel Holtmann 				    hdev, &idle_timeout_fops);
18482bfa3531SMarcel Holtmann 		debugfs_create_file("sniff_min_interval", 0644, hdev->debugfs,
18492bfa3531SMarcel Holtmann 				    hdev, &sniff_min_interval_fops);
18502bfa3531SMarcel Holtmann 		debugfs_create_file("sniff_max_interval", 0644, hdev->debugfs,
18512bfa3531SMarcel Holtmann 				    hdev, &sniff_max_interval_fops);
18522bfa3531SMarcel Holtmann 	}
18532bfa3531SMarcel Holtmann 
1854d0f729b8SMarcel Holtmann 	if (lmp_le_capable(hdev)) {
1855ac345813SMarcel Holtmann 		debugfs_create_file("identity", 0400, hdev->debugfs,
1856ac345813SMarcel Holtmann 				    hdev, &identity_fops);
1857ac345813SMarcel Holtmann 		debugfs_create_file("rpa_timeout", 0644, hdev->debugfs,
1858ac345813SMarcel Holtmann 				    hdev, &rpa_timeout_fops);
18597a4cd51dSMarcel Holtmann 		debugfs_create_file("random_address", 0444, hdev->debugfs,
18607a4cd51dSMarcel Holtmann 				    hdev, &random_address_fops);
1861e7b8fc92SMarcel Holtmann 		debugfs_create_file("static_address", 0444, hdev->debugfs,
1862e7b8fc92SMarcel Holtmann 				    hdev, &static_address_fops);
1863b32bba6cSMarcel Holtmann 
1864b32bba6cSMarcel Holtmann 		/* For controllers with a public address, provide a debug
1865b32bba6cSMarcel Holtmann 		 * option to force the usage of the configured static
1866b32bba6cSMarcel Holtmann 		 * address. By default the public address is used.
1867b32bba6cSMarcel Holtmann 		 */
1868b32bba6cSMarcel Holtmann 		if (bacmp(&hdev->bdaddr, BDADDR_ANY))
1869b32bba6cSMarcel Holtmann 			debugfs_create_file("force_static_address", 0644,
1870b32bba6cSMarcel Holtmann 					    hdev->debugfs, hdev,
1871b32bba6cSMarcel Holtmann 					    &force_static_address_fops);
1872b32bba6cSMarcel Holtmann 
1873b32bba6cSMarcel Holtmann 		debugfs_create_u8("white_list_size", 0444, hdev->debugfs,
1874b32bba6cSMarcel Holtmann 				  &hdev->le_white_list_size);
1875d2ab0ac1SMarcel Holtmann 		debugfs_create_file("white_list", 0444, hdev->debugfs, hdev,
1876d2ab0ac1SMarcel Holtmann 				    &white_list_fops);
18773698d704SMarcel Holtmann 		debugfs_create_file("identity_resolving_keys", 0400,
18783698d704SMarcel Holtmann 				    hdev->debugfs, hdev,
18793698d704SMarcel Holtmann 				    &identity_resolving_keys_fops);
18808f8625cdSMarcel Holtmann 		debugfs_create_file("long_term_keys", 0400, hdev->debugfs,
18818f8625cdSMarcel Holtmann 				    hdev, &long_term_keys_fops);
18824e70c7e7SMarcel Holtmann 		debugfs_create_file("conn_min_interval", 0644, hdev->debugfs,
18834e70c7e7SMarcel Holtmann 				    hdev, &conn_min_interval_fops);
18844e70c7e7SMarcel Holtmann 		debugfs_create_file("conn_max_interval", 0644, hdev->debugfs,
18854e70c7e7SMarcel Holtmann 				    hdev, &conn_max_interval_fops);
1886816a93d1SMarcel Holtmann 		debugfs_create_file("conn_latency", 0644, hdev->debugfs,
1887816a93d1SMarcel Holtmann 				    hdev, &conn_latency_fops);
1888f1649577SMarcel Holtmann 		debugfs_create_file("supervision_timeout", 0644, hdev->debugfs,
1889f1649577SMarcel Holtmann 				    hdev, &supervision_timeout_fops);
18903f959d46SMarcel Holtmann 		debugfs_create_file("adv_channel_map", 0644, hdev->debugfs,
18913f959d46SMarcel Holtmann 				    hdev, &adv_channel_map_fops);
1892729a1051SGeorg Lukas 		debugfs_create_file("adv_min_interval", 0644, hdev->debugfs,
1893729a1051SGeorg Lukas 				    hdev, &adv_min_interval_fops);
1894729a1051SGeorg Lukas 		debugfs_create_file("adv_max_interval", 0644, hdev->debugfs,
1895729a1051SGeorg Lukas 				    hdev, &adv_max_interval_fops);
18960b3c7d37SMarcel Holtmann 		debugfs_create_file("device_list", 0444, hdev->debugfs, hdev,
18970b3c7d37SMarcel Holtmann 				    &device_list_fops);
1898b9a7a61eSLukasz Rymanowski 		debugfs_create_u16("discov_interleaved_timeout", 0644,
1899b9a7a61eSLukasz Rymanowski 				   hdev->debugfs,
1900b9a7a61eSLukasz Rymanowski 				   &hdev->discov_interleaved_timeout);
190154506918SJohan Hedberg 
1902711eafe3SJohan Hedberg 		smp_register(hdev);
1903d0f729b8SMarcel Holtmann 	}
1904e7b8fc92SMarcel Holtmann 
1905baf27f6eSMarcel Holtmann 	return 0;
19062177bab5SJohan Hedberg }
19072177bab5SJohan Hedberg 
19080ebca7d6SMarcel Holtmann static void hci_init0_req(struct hci_request *req, unsigned long opt)
19090ebca7d6SMarcel Holtmann {
19100ebca7d6SMarcel Holtmann 	struct hci_dev *hdev = req->hdev;
19110ebca7d6SMarcel Holtmann 
19120ebca7d6SMarcel Holtmann 	BT_DBG("%s %ld", hdev->name, opt);
19130ebca7d6SMarcel Holtmann 
19140ebca7d6SMarcel Holtmann 	/* Reset */
19150ebca7d6SMarcel Holtmann 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
19160ebca7d6SMarcel Holtmann 		hci_reset_req(req, 0);
19170ebca7d6SMarcel Holtmann 
19180ebca7d6SMarcel Holtmann 	/* Read Local Version */
19190ebca7d6SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
19200ebca7d6SMarcel Holtmann 
19210ebca7d6SMarcel Holtmann 	/* Read BD Address */
19220ebca7d6SMarcel Holtmann 	if (hdev->set_bdaddr)
19230ebca7d6SMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
19240ebca7d6SMarcel Holtmann }
19250ebca7d6SMarcel Holtmann 
19260ebca7d6SMarcel Holtmann static int __hci_unconf_init(struct hci_dev *hdev)
19270ebca7d6SMarcel Holtmann {
19280ebca7d6SMarcel Holtmann 	int err;
19290ebca7d6SMarcel Holtmann 
1930cc78b44bSMarcel Holtmann 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
1931cc78b44bSMarcel Holtmann 		return 0;
1932cc78b44bSMarcel Holtmann 
19330ebca7d6SMarcel Holtmann 	err = __hci_req_sync(hdev, hci_init0_req, 0, HCI_INIT_TIMEOUT);
19340ebca7d6SMarcel Holtmann 	if (err < 0)
19350ebca7d6SMarcel Holtmann 		return err;
19360ebca7d6SMarcel Holtmann 
19370ebca7d6SMarcel Holtmann 	return 0;
19380ebca7d6SMarcel Holtmann }
19390ebca7d6SMarcel Holtmann 
194042c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt)
19411da177e4SLinus Torvalds {
19421da177e4SLinus Torvalds 	__u8 scan = opt;
19431da177e4SLinus Torvalds 
194442c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, scan);
19451da177e4SLinus Torvalds 
19461da177e4SLinus Torvalds 	/* Inquiry and Page scans */
194742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
19481da177e4SLinus Torvalds }
19491da177e4SLinus Torvalds 
195042c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt)
19511da177e4SLinus Torvalds {
19521da177e4SLinus Torvalds 	__u8 auth = opt;
19531da177e4SLinus Torvalds 
195442c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, auth);
19551da177e4SLinus Torvalds 
19561da177e4SLinus Torvalds 	/* Authentication */
195742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
19581da177e4SLinus Torvalds }
19591da177e4SLinus Torvalds 
196042c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt)
19611da177e4SLinus Torvalds {
19621da177e4SLinus Torvalds 	__u8 encrypt = opt;
19631da177e4SLinus Torvalds 
196442c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, encrypt);
19651da177e4SLinus Torvalds 
1966e4e8e37cSMarcel Holtmann 	/* Encryption */
196742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
19681da177e4SLinus Torvalds }
19691da177e4SLinus Torvalds 
197042c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt)
1971e4e8e37cSMarcel Holtmann {
1972e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
1973e4e8e37cSMarcel Holtmann 
197442c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, policy);
1975e4e8e37cSMarcel Holtmann 
1976e4e8e37cSMarcel Holtmann 	/* Default link policy */
197742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
1978e4e8e37cSMarcel Holtmann }
1979e4e8e37cSMarcel Holtmann 
19801da177e4SLinus Torvalds /* Get HCI device by index.
19811da177e4SLinus Torvalds  * Device is held on return. */
19821da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
19831da177e4SLinus Torvalds {
19848035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
19851da177e4SLinus Torvalds 
19861da177e4SLinus Torvalds 	BT_DBG("%d", index);
19871da177e4SLinus Torvalds 
19881da177e4SLinus Torvalds 	if (index < 0)
19891da177e4SLinus Torvalds 		return NULL;
19901da177e4SLinus Torvalds 
19911da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
19928035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
19931da177e4SLinus Torvalds 		if (d->id == index) {
19941da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
19951da177e4SLinus Torvalds 			break;
19961da177e4SLinus Torvalds 		}
19971da177e4SLinus Torvalds 	}
19981da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
19991da177e4SLinus Torvalds 	return hdev;
20001da177e4SLinus Torvalds }
20011da177e4SLinus Torvalds 
20021da177e4SLinus Torvalds /* ---- Inquiry support ---- */
2003ff9ef578SJohan Hedberg 
200430dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
200530dc78e1SJohan Hedberg {
200630dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
200730dc78e1SJohan Hedberg 
20086fbe195dSAndre Guedes 	switch (discov->state) {
2009343f935bSAndre Guedes 	case DISCOVERY_FINDING:
20106fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
201130dc78e1SJohan Hedberg 		return true;
201230dc78e1SJohan Hedberg 
20136fbe195dSAndre Guedes 	default:
201430dc78e1SJohan Hedberg 		return false;
201530dc78e1SJohan Hedberg 	}
20166fbe195dSAndre Guedes }
201730dc78e1SJohan Hedberg 
2018ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
2019ff9ef578SJohan Hedberg {
2020bb3e0a33SJohan Hedberg 	int old_state = hdev->discovery.state;
2021bb3e0a33SJohan Hedberg 
2022ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
2023ff9ef578SJohan Hedberg 
2024bb3e0a33SJohan Hedberg 	if (old_state == state)
2025ff9ef578SJohan Hedberg 		return;
2026ff9ef578SJohan Hedberg 
2027bb3e0a33SJohan Hedberg 	hdev->discovery.state = state;
2028bb3e0a33SJohan Hedberg 
2029ff9ef578SJohan Hedberg 	switch (state) {
2030ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
2031c54c3860SAndre Guedes 		hci_update_background_scan(hdev);
2032c54c3860SAndre Guedes 
2033bb3e0a33SJohan Hedberg 		if (old_state != DISCOVERY_STARTING)
2034ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
2035ff9ef578SJohan Hedberg 		break;
2036ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
2037ff9ef578SJohan Hedberg 		break;
2038343f935bSAndre Guedes 	case DISCOVERY_FINDING:
2039ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
2040ff9ef578SJohan Hedberg 		break;
204130dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
204230dc78e1SJohan Hedberg 		break;
2043ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
2044ff9ef578SJohan Hedberg 		break;
2045ff9ef578SJohan Hedberg 	}
2046ff9ef578SJohan Hedberg }
2047ff9ef578SJohan Hedberg 
20481f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev)
20491da177e4SLinus Torvalds {
205030883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
2051b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
20521da177e4SLinus Torvalds 
2053561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
2054561aafbcSJohan Hedberg 		list_del(&p->all);
2055b57c1a56SJohan Hedberg 		kfree(p);
20561da177e4SLinus Torvalds 	}
2057561aafbcSJohan Hedberg 
2058561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
2059561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
20601da177e4SLinus Torvalds }
20611da177e4SLinus Torvalds 
2062a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
2063a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
20641da177e4SLinus Torvalds {
206530883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
20661da177e4SLinus Torvalds 	struct inquiry_entry *e;
20671da177e4SLinus Torvalds 
20686ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
20691da177e4SLinus Torvalds 
2070561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
20711da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
20721da177e4SLinus Torvalds 			return e;
20731da177e4SLinus Torvalds 	}
20741da177e4SLinus Torvalds 
2075b57c1a56SJohan Hedberg 	return NULL;
2076b57c1a56SJohan Hedberg }
2077b57c1a56SJohan Hedberg 
2078561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
2079561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
2080561aafbcSJohan Hedberg {
208130883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
2082561aafbcSJohan Hedberg 	struct inquiry_entry *e;
2083561aafbcSJohan Hedberg 
20846ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
2085561aafbcSJohan Hedberg 
2086561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
2087561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
2088561aafbcSJohan Hedberg 			return e;
2089561aafbcSJohan Hedberg 	}
2090561aafbcSJohan Hedberg 
2091561aafbcSJohan Hedberg 	return NULL;
2092561aafbcSJohan Hedberg }
2093561aafbcSJohan Hedberg 
209430dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
209530dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
209630dc78e1SJohan Hedberg 						       int state)
209730dc78e1SJohan Hedberg {
209830dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
209930dc78e1SJohan Hedberg 	struct inquiry_entry *e;
210030dc78e1SJohan Hedberg 
21016ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
210230dc78e1SJohan Hedberg 
210330dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
210430dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
210530dc78e1SJohan Hedberg 			return e;
210630dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
210730dc78e1SJohan Hedberg 			return e;
210830dc78e1SJohan Hedberg 	}
210930dc78e1SJohan Hedberg 
211030dc78e1SJohan Hedberg 	return NULL;
211130dc78e1SJohan Hedberg }
211230dc78e1SJohan Hedberg 
2113a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
2114a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
2115a3d4e20aSJohan Hedberg {
2116a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
2117a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
2118a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
2119a3d4e20aSJohan Hedberg 
2120a3d4e20aSJohan Hedberg 	list_del(&ie->list);
2121a3d4e20aSJohan Hedberg 
2122a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
2123a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
2124a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
2125a3d4e20aSJohan Hedberg 			break;
2126a3d4e20aSJohan Hedberg 		pos = &p->list;
2127a3d4e20aSJohan Hedberg 	}
2128a3d4e20aSJohan Hedberg 
2129a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
2130a3d4e20aSJohan Hedberg }
2131a3d4e20aSJohan Hedberg 
2132af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
2133af58925cSMarcel Holtmann 			     bool name_known)
21341da177e4SLinus Torvalds {
213530883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
213670f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
2137af58925cSMarcel Holtmann 	u32 flags = 0;
21381da177e4SLinus Torvalds 
21396ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
21401da177e4SLinus Torvalds 
21412b2fec4dSSzymon Janc 	hci_remove_remote_oob_data(hdev, &data->bdaddr);
21422b2fec4dSSzymon Janc 
2143af58925cSMarcel Holtmann 	if (!data->ssp_mode)
2144af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
2145388fc8faSJohan Hedberg 
214670f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
2147a3d4e20aSJohan Hedberg 	if (ie) {
2148af58925cSMarcel Holtmann 		if (!ie->data.ssp_mode)
2149af58925cSMarcel Holtmann 			flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
2150388fc8faSJohan Hedberg 
2151a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
2152a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
2153a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
2154a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
2155a3d4e20aSJohan Hedberg 		}
2156a3d4e20aSJohan Hedberg 
2157561aafbcSJohan Hedberg 		goto update;
2158a3d4e20aSJohan Hedberg 	}
2159561aafbcSJohan Hedberg 
21601da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
216127f70f3eSJohan Hedberg 	ie = kzalloc(sizeof(*ie), GFP_KERNEL);
2162af58925cSMarcel Holtmann 	if (!ie) {
2163af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
2164af58925cSMarcel Holtmann 		goto done;
2165af58925cSMarcel Holtmann 	}
216670f23020SAndrei Emeltchenko 
2167561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
2168561aafbcSJohan Hedberg 
2169561aafbcSJohan Hedberg 	if (name_known) {
2170561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
2171561aafbcSJohan Hedberg 	} else {
2172561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
2173561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
2174561aafbcSJohan Hedberg 	}
2175561aafbcSJohan Hedberg 
2176561aafbcSJohan Hedberg update:
2177561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
2178561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
2179561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
2180561aafbcSJohan Hedberg 		list_del(&ie->list);
21811da177e4SLinus Torvalds 	}
21821da177e4SLinus Torvalds 
218370f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
218470f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
21851da177e4SLinus Torvalds 	cache->timestamp = jiffies;
21863175405bSJohan Hedberg 
21873175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
2188af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
21893175405bSJohan Hedberg 
2190af58925cSMarcel Holtmann done:
2191af58925cSMarcel Holtmann 	return flags;
21921da177e4SLinus Torvalds }
21931da177e4SLinus Torvalds 
21941da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
21951da177e4SLinus Torvalds {
219630883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
21971da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
21981da177e4SLinus Torvalds 	struct inquiry_entry *e;
21991da177e4SLinus Torvalds 	int copied = 0;
22001da177e4SLinus Torvalds 
2201561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
22021da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
2203b57c1a56SJohan Hedberg 
2204b57c1a56SJohan Hedberg 		if (copied >= num)
2205b57c1a56SJohan Hedberg 			break;
2206b57c1a56SJohan Hedberg 
22071da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
22081da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
22091da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
22101da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
22111da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
22121da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
2213b57c1a56SJohan Hedberg 
22141da177e4SLinus Torvalds 		info++;
2215b57c1a56SJohan Hedberg 		copied++;
22161da177e4SLinus Torvalds 	}
22171da177e4SLinus Torvalds 
22181da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
22191da177e4SLinus Torvalds 	return copied;
22201da177e4SLinus Torvalds }
22211da177e4SLinus Torvalds 
222242c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt)
22231da177e4SLinus Torvalds {
22241da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
222542c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
22261da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
22271da177e4SLinus Torvalds 
22281da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
22291da177e4SLinus Torvalds 
22301da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
22311da177e4SLinus Torvalds 		return;
22321da177e4SLinus Torvalds 
22331da177e4SLinus Torvalds 	/* Start Inquiry */
22341da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
22351da177e4SLinus Torvalds 	cp.length  = ir->length;
22361da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
223742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
22381da177e4SLinus Torvalds }
22391da177e4SLinus Torvalds 
22401da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
22411da177e4SLinus Torvalds {
22421da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
22431da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
22441da177e4SLinus Torvalds 	struct hci_dev *hdev;
22451da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
22461da177e4SLinus Torvalds 	long timeo;
22471da177e4SLinus Torvalds 	__u8 *buf;
22481da177e4SLinus Torvalds 
22491da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
22501da177e4SLinus Torvalds 		return -EFAULT;
22511da177e4SLinus Torvalds 
22525a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
22535a08ecceSAndrei Emeltchenko 	if (!hdev)
22541da177e4SLinus Torvalds 		return -ENODEV;
22551da177e4SLinus Torvalds 
22560736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
22570736cfa8SMarcel Holtmann 		err = -EBUSY;
22580736cfa8SMarcel Holtmann 		goto done;
22590736cfa8SMarcel Holtmann 	}
22600736cfa8SMarcel Holtmann 
22614a964404SMarcel Holtmann 	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
2262fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
2263fee746b0SMarcel Holtmann 		goto done;
2264fee746b0SMarcel Holtmann 	}
2265fee746b0SMarcel Holtmann 
22665b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
22675b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
22685b69bef5SMarcel Holtmann 		goto done;
22695b69bef5SMarcel Holtmann 	}
22705b69bef5SMarcel Holtmann 
227156f87901SJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
227256f87901SJohan Hedberg 		err = -EOPNOTSUPP;
227356f87901SJohan Hedberg 		goto done;
227456f87901SJohan Hedberg 	}
227556f87901SJohan Hedberg 
227609fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
22771da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
2278a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
22791f9b9a5dSAndre Guedes 		hci_inquiry_cache_flush(hdev);
22801da177e4SLinus Torvalds 		do_inquiry = 1;
22811da177e4SLinus Torvalds 	}
228209fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
22831da177e4SLinus Torvalds 
228404837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
228570f23020SAndrei Emeltchenko 
228670f23020SAndrei Emeltchenko 	if (do_inquiry) {
228701178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
228801178cd4SJohan Hedberg 				   timeo);
228970f23020SAndrei Emeltchenko 		if (err < 0)
22901da177e4SLinus Torvalds 			goto done;
22913e13fa1eSAndre Guedes 
22923e13fa1eSAndre Guedes 		/* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
22933e13fa1eSAndre Guedes 		 * cleared). If it is interrupted by a signal, return -EINTR.
22943e13fa1eSAndre Guedes 		 */
229574316201SNeilBrown 		if (wait_on_bit(&hdev->flags, HCI_INQUIRY,
22963e13fa1eSAndre Guedes 				TASK_INTERRUPTIBLE))
22973e13fa1eSAndre Guedes 			return -EINTR;
229870f23020SAndrei Emeltchenko 	}
22991da177e4SLinus Torvalds 
23008fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
23018fc9ced3SGustavo Padovan 	 * 255 entries
23028fc9ced3SGustavo Padovan 	 */
23031da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
23041da177e4SLinus Torvalds 
23051da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
23061da177e4SLinus Torvalds 	 * copy it to the user space.
23071da177e4SLinus Torvalds 	 */
230870f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
230970f23020SAndrei Emeltchenko 	if (!buf) {
23101da177e4SLinus Torvalds 		err = -ENOMEM;
23111da177e4SLinus Torvalds 		goto done;
23121da177e4SLinus Torvalds 	}
23131da177e4SLinus Torvalds 
231409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
23151da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
231609fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
23171da177e4SLinus Torvalds 
23181da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
23191da177e4SLinus Torvalds 
23201da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
23211da177e4SLinus Torvalds 		ptr += sizeof(ir);
23221da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
23231da177e4SLinus Torvalds 				 ir.num_rsp))
23241da177e4SLinus Torvalds 			err = -EFAULT;
23251da177e4SLinus Torvalds 	} else
23261da177e4SLinus Torvalds 		err = -EFAULT;
23271da177e4SLinus Torvalds 
23281da177e4SLinus Torvalds 	kfree(buf);
23291da177e4SLinus Torvalds 
23301da177e4SLinus Torvalds done:
23311da177e4SLinus Torvalds 	hci_dev_put(hdev);
23321da177e4SLinus Torvalds 	return err;
23331da177e4SLinus Torvalds }
23341da177e4SLinus Torvalds 
2335cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev)
23361da177e4SLinus Torvalds {
23371da177e4SLinus Torvalds 	int ret = 0;
23381da177e4SLinus Torvalds 
23391da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
23401da177e4SLinus Torvalds 
23411da177e4SLinus Torvalds 	hci_req_lock(hdev);
23421da177e4SLinus Torvalds 
234394324962SJohan Hovold 	if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) {
234494324962SJohan Hovold 		ret = -ENODEV;
234594324962SJohan Hovold 		goto done;
234694324962SJohan Hovold 	}
234794324962SJohan Hovold 
2348d603b76bSMarcel Holtmann 	if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
2349d603b76bSMarcel Holtmann 	    !test_bit(HCI_CONFIG, &hdev->dev_flags)) {
2350a5c8f270SMarcel Holtmann 		/* Check for rfkill but allow the HCI setup stage to
2351a5c8f270SMarcel Holtmann 		 * proceed (which in itself doesn't cause any RF activity).
2352bf543036SJohan Hedberg 		 */
2353a5c8f270SMarcel Holtmann 		if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) {
2354611b30f7SMarcel Holtmann 			ret = -ERFKILL;
2355611b30f7SMarcel Holtmann 			goto done;
2356611b30f7SMarcel Holtmann 		}
2357611b30f7SMarcel Holtmann 
2358a5c8f270SMarcel Holtmann 		/* Check for valid public address or a configured static
2359a5c8f270SMarcel Holtmann 		 * random adddress, but let the HCI setup proceed to
2360a5c8f270SMarcel Holtmann 		 * be able to determine if there is a public address
2361a5c8f270SMarcel Holtmann 		 * or not.
2362a5c8f270SMarcel Holtmann 		 *
2363c6beca0eSMarcel Holtmann 		 * In case of user channel usage, it is not important
2364c6beca0eSMarcel Holtmann 		 * if a public address or static random address is
2365c6beca0eSMarcel Holtmann 		 * available.
2366c6beca0eSMarcel Holtmann 		 *
2367a5c8f270SMarcel Holtmann 		 * This check is only valid for BR/EDR controllers
2368a5c8f270SMarcel Holtmann 		 * since AMP controllers do not have an address.
2369a5c8f270SMarcel Holtmann 		 */
2370c6beca0eSMarcel Holtmann 		if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
2371c6beca0eSMarcel Holtmann 		    hdev->dev_type == HCI_BREDR &&
2372a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
2373a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->static_addr, BDADDR_ANY)) {
2374a5c8f270SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
2375a5c8f270SMarcel Holtmann 			goto done;
2376a5c8f270SMarcel Holtmann 		}
2377a5c8f270SMarcel Holtmann 	}
2378a5c8f270SMarcel Holtmann 
23791da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
23801da177e4SLinus Torvalds 		ret = -EALREADY;
23811da177e4SLinus Torvalds 		goto done;
23821da177e4SLinus Torvalds 	}
23831da177e4SLinus Torvalds 
23841da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
23851da177e4SLinus Torvalds 		ret = -EIO;
23861da177e4SLinus Torvalds 		goto done;
23871da177e4SLinus Torvalds 	}
23881da177e4SLinus Torvalds 
23891da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
23901da177e4SLinus Torvalds 	set_bit(HCI_INIT, &hdev->flags);
2391f41c70c4SMarcel Holtmann 
2392af202f84SMarcel Holtmann 	if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
2393af202f84SMarcel Holtmann 		if (hdev->setup)
2394f41c70c4SMarcel Holtmann 			ret = hdev->setup(hdev);
2395f41c70c4SMarcel Holtmann 
2396af202f84SMarcel Holtmann 		/* The transport driver can set these quirks before
2397af202f84SMarcel Holtmann 		 * creating the HCI device or in its setup callback.
2398af202f84SMarcel Holtmann 		 *
2399af202f84SMarcel Holtmann 		 * In case any of them is set, the controller has to
2400af202f84SMarcel Holtmann 		 * start up as unconfigured.
2401af202f84SMarcel Holtmann 		 */
2402eb1904f4SMarcel Holtmann 		if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) ||
2403eb1904f4SMarcel Holtmann 		    test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks))
240489bc22d2SMarcel Holtmann 			set_bit(HCI_UNCONFIGURED, &hdev->dev_flags);
2405f41c70c4SMarcel Holtmann 
24060ebca7d6SMarcel Holtmann 		/* For an unconfigured controller it is required to
24070ebca7d6SMarcel Holtmann 		 * read at least the version information provided by
24080ebca7d6SMarcel Holtmann 		 * the Read Local Version Information command.
24090ebca7d6SMarcel Holtmann 		 *
24100ebca7d6SMarcel Holtmann 		 * If the set_bdaddr driver callback is provided, then
24110ebca7d6SMarcel Holtmann 		 * also the original Bluetooth public device address
24120ebca7d6SMarcel Holtmann 		 * will be read using the Read BD Address command.
24130ebca7d6SMarcel Holtmann 		 */
24140ebca7d6SMarcel Holtmann 		if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
24150ebca7d6SMarcel Holtmann 			ret = __hci_unconf_init(hdev);
241689bc22d2SMarcel Holtmann 	}
241789bc22d2SMarcel Holtmann 
24189713c17bSMarcel Holtmann 	if (test_bit(HCI_CONFIG, &hdev->dev_flags)) {
24199713c17bSMarcel Holtmann 		/* If public address change is configured, ensure that
24209713c17bSMarcel Holtmann 		 * the address gets programmed. If the driver does not
24219713c17bSMarcel Holtmann 		 * support changing the public address, fail the power
24229713c17bSMarcel Holtmann 		 * on procedure.
242324c457e2SMarcel Holtmann 		 */
24249713c17bSMarcel Holtmann 		if (bacmp(&hdev->public_addr, BDADDR_ANY) &&
24259713c17bSMarcel Holtmann 		    hdev->set_bdaddr)
242624c457e2SMarcel Holtmann 			ret = hdev->set_bdaddr(hdev, &hdev->public_addr);
242724c457e2SMarcel Holtmann 		else
242824c457e2SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
242924c457e2SMarcel Holtmann 	}
243024c457e2SMarcel Holtmann 
2431f41c70c4SMarcel Holtmann 	if (!ret) {
24324a964404SMarcel Holtmann 		if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
24330736cfa8SMarcel Holtmann 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
24342177bab5SJohan Hedberg 			ret = __hci_init(hdev);
24351da177e4SLinus Torvalds 	}
24361da177e4SLinus Torvalds 
2437f41c70c4SMarcel Holtmann 	clear_bit(HCI_INIT, &hdev->flags);
2438f41c70c4SMarcel Holtmann 
24391da177e4SLinus Torvalds 	if (!ret) {
24401da177e4SLinus Torvalds 		hci_dev_hold(hdev);
2441d6bfd59cSJohan Hedberg 		set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags);
24421da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
24431da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
2444bb4b2a9aSAndrei Emeltchenko 		if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
2445d603b76bSMarcel Holtmann 		    !test_bit(HCI_CONFIG, &hdev->dev_flags) &&
24464a964404SMarcel Holtmann 		    !test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
24470736cfa8SMarcel Holtmann 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
24481514b892SMarcel Holtmann 		    hdev->dev_type == HCI_BREDR) {
244909fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
2450744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
245109fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
245256e5cb86SJohan Hedberg 		}
24531da177e4SLinus Torvalds 	} else {
24541da177e4SLinus Torvalds 		/* Init failed, cleanup */
24553eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
2456c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
2457b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
24581da177e4SLinus Torvalds 
24591da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
24601da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
24611da177e4SLinus Torvalds 
24621da177e4SLinus Torvalds 		if (hdev->flush)
24631da177e4SLinus Torvalds 			hdev->flush(hdev);
24641da177e4SLinus Torvalds 
24651da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
24661da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
24671da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
24681da177e4SLinus Torvalds 		}
24691da177e4SLinus Torvalds 
24701da177e4SLinus Torvalds 		hdev->close(hdev);
2471fee746b0SMarcel Holtmann 		hdev->flags &= BIT(HCI_RAW);
24721da177e4SLinus Torvalds 	}
24731da177e4SLinus Torvalds 
24741da177e4SLinus Torvalds done:
24751da177e4SLinus Torvalds 	hci_req_unlock(hdev);
24761da177e4SLinus Torvalds 	return ret;
24771da177e4SLinus Torvalds }
24781da177e4SLinus Torvalds 
2479cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */
2480cbed0ca1SJohan Hedberg 
2481cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev)
2482cbed0ca1SJohan Hedberg {
2483cbed0ca1SJohan Hedberg 	struct hci_dev *hdev;
2484cbed0ca1SJohan Hedberg 	int err;
2485cbed0ca1SJohan Hedberg 
2486cbed0ca1SJohan Hedberg 	hdev = hci_dev_get(dev);
2487cbed0ca1SJohan Hedberg 	if (!hdev)
2488cbed0ca1SJohan Hedberg 		return -ENODEV;
2489cbed0ca1SJohan Hedberg 
24904a964404SMarcel Holtmann 	/* Devices that are marked as unconfigured can only be powered
2491fee746b0SMarcel Holtmann 	 * up as user channel. Trying to bring them up as normal devices
2492fee746b0SMarcel Holtmann 	 * will result into a failure. Only user channel operation is
2493fee746b0SMarcel Holtmann 	 * possible.
2494fee746b0SMarcel Holtmann 	 *
2495fee746b0SMarcel Holtmann 	 * When this function is called for a user channel, the flag
2496fee746b0SMarcel Holtmann 	 * HCI_USER_CHANNEL will be set first before attempting to
2497fee746b0SMarcel Holtmann 	 * open the device.
2498fee746b0SMarcel Holtmann 	 */
24994a964404SMarcel Holtmann 	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
2500fee746b0SMarcel Holtmann 	    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
2501fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
2502fee746b0SMarcel Holtmann 		goto done;
2503fee746b0SMarcel Holtmann 	}
2504fee746b0SMarcel Holtmann 
2505e1d08f40SJohan Hedberg 	/* We need to ensure that no other power on/off work is pending
2506e1d08f40SJohan Hedberg 	 * before proceeding to call hci_dev_do_open. This is
2507e1d08f40SJohan Hedberg 	 * particularly important if the setup procedure has not yet
2508e1d08f40SJohan Hedberg 	 * completed.
2509e1d08f40SJohan Hedberg 	 */
2510e1d08f40SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
2511e1d08f40SJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
2512e1d08f40SJohan Hedberg 
2513a5c8f270SMarcel Holtmann 	/* After this call it is guaranteed that the setup procedure
2514a5c8f270SMarcel Holtmann 	 * has finished. This means that error conditions like RFKILL
2515a5c8f270SMarcel Holtmann 	 * or no valid public or static random address apply.
2516a5c8f270SMarcel Holtmann 	 */
2517e1d08f40SJohan Hedberg 	flush_workqueue(hdev->req_workqueue);
2518e1d08f40SJohan Hedberg 
251912aa4f0aSMarcel Holtmann 	/* For controllers not using the management interface and that
2520b6ae8457SJohan Hedberg 	 * are brought up using legacy ioctl, set the HCI_BONDABLE bit
252112aa4f0aSMarcel Holtmann 	 * so that pairing works for them. Once the management interface
252212aa4f0aSMarcel Holtmann 	 * is in use this bit will be cleared again and userspace has
252312aa4f0aSMarcel Holtmann 	 * to explicitly enable it.
252412aa4f0aSMarcel Holtmann 	 */
252512aa4f0aSMarcel Holtmann 	if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
252612aa4f0aSMarcel Holtmann 	    !test_bit(HCI_MGMT, &hdev->dev_flags))
2527b6ae8457SJohan Hedberg 		set_bit(HCI_BONDABLE, &hdev->dev_flags);
252812aa4f0aSMarcel Holtmann 
2529cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
2530cbed0ca1SJohan Hedberg 
2531fee746b0SMarcel Holtmann done:
2532cbed0ca1SJohan Hedberg 	hci_dev_put(hdev);
2533cbed0ca1SJohan Hedberg 	return err;
2534cbed0ca1SJohan Hedberg }
2535cbed0ca1SJohan Hedberg 
2536d7347f3cSJohan Hedberg /* This function requires the caller holds hdev->lock */
2537d7347f3cSJohan Hedberg static void hci_pend_le_actions_clear(struct hci_dev *hdev)
2538d7347f3cSJohan Hedberg {
2539d7347f3cSJohan Hedberg 	struct hci_conn_params *p;
2540d7347f3cSJohan Hedberg 
2541d7347f3cSJohan Hedberg 	list_for_each_entry(p, &hdev->le_conn_params, list)
2542d7347f3cSJohan Hedberg 		list_del_init(&p->action);
2543d7347f3cSJohan Hedberg 
2544d7347f3cSJohan Hedberg 	BT_DBG("All LE pending actions cleared");
2545d7347f3cSJohan Hedberg }
2546d7347f3cSJohan Hedberg 
25471da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
25481da177e4SLinus Torvalds {
25491da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
25501da177e4SLinus Torvalds 
255178c04c0bSVinicius Costa Gomes 	cancel_delayed_work(&hdev->power_off);
255278c04c0bSVinicius Costa Gomes 
25531da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
25541da177e4SLinus Torvalds 	hci_req_lock(hdev);
25551da177e4SLinus Torvalds 
25561da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
255765cc2b49SMarcel Holtmann 		cancel_delayed_work_sync(&hdev->cmd_timer);
25581da177e4SLinus Torvalds 		hci_req_unlock(hdev);
25591da177e4SLinus Torvalds 		return 0;
25601da177e4SLinus Torvalds 	}
25611da177e4SLinus Torvalds 
25623eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
25633eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
2564b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
25651da177e4SLinus Torvalds 
256616ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
2567e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
256816ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
25695e5282bbSJohan Hedberg 		clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
2570310a3d48SMarcel Holtmann 		clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
257116ab91abSJohan Hedberg 	}
257216ab91abSJohan Hedberg 
2573a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
25747d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
25757d78525dSJohan Hedberg 
25767ba8b4beSAndre Guedes 	cancel_delayed_work_sync(&hdev->le_scan_disable);
25774518bb0fSJohan Hedberg 
25784518bb0fSJohan Hedberg 	if (test_bit(HCI_MGMT, &hdev->dev_flags))
2579d6bfd59cSJohan Hedberg 		cancel_delayed_work_sync(&hdev->rpa_expired);
25807ba8b4beSAndre Guedes 
258109fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
25821f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
25831da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
2584d7347f3cSJohan Hedberg 	hci_pend_le_actions_clear(hdev);
258509fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
25861da177e4SLinus Torvalds 
25871da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
25881da177e4SLinus Torvalds 
25891da177e4SLinus Torvalds 	if (hdev->flush)
25901da177e4SLinus Torvalds 		hdev->flush(hdev);
25911da177e4SLinus Torvalds 
25921da177e4SLinus Torvalds 	/* Reset device */
25931da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
25941da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
25954a964404SMarcel Holtmann 	if (!test_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
25964a964404SMarcel Holtmann 	    !test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
2597a6c511c6SSzymon Janc 	    test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
25981da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
259901178cd4SJohan Hedberg 		__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
26001da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
26011da177e4SLinus Torvalds 	}
26021da177e4SLinus Torvalds 
2603c347b765SGustavo F. Padovan 	/* flush cmd  work */
2604c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
26051da177e4SLinus Torvalds 
26061da177e4SLinus Torvalds 	/* Drop queues */
26071da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
26081da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
26091da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
26101da177e4SLinus Torvalds 
26111da177e4SLinus Torvalds 	/* Drop last sent command */
26121da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
261365cc2b49SMarcel Holtmann 		cancel_delayed_work_sync(&hdev->cmd_timer);
26141da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
26151da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
26161da177e4SLinus Torvalds 	}
26171da177e4SLinus Torvalds 
2618b6ddb638SJohan Hedberg 	kfree_skb(hdev->recv_evt);
2619b6ddb638SJohan Hedberg 	hdev->recv_evt = NULL;
2620b6ddb638SJohan Hedberg 
26211da177e4SLinus Torvalds 	/* After this point our queues are empty
26221da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
26231da177e4SLinus Torvalds 	hdev->close(hdev);
26241da177e4SLinus Torvalds 
262535b973c9SJohan Hedberg 	/* Clear flags */
2626fee746b0SMarcel Holtmann 	hdev->flags &= BIT(HCI_RAW);
262735b973c9SJohan Hedberg 	hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
262835b973c9SJohan Hedberg 
262993c311a0SMarcel Holtmann 	if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
263093c311a0SMarcel Holtmann 		if (hdev->dev_type == HCI_BREDR) {
263109fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
2632744cf19eSJohan Hedberg 			mgmt_powered(hdev, 0);
263309fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
26348ee56540SMarcel Holtmann 		}
263593c311a0SMarcel Holtmann 	}
26365add6af8SJohan Hedberg 
2637ced5c338SAndrei Emeltchenko 	/* Controller radio is available but is currently powered down */
2638536619e8SMarcel Holtmann 	hdev->amp_status = AMP_STATUS_POWERED_DOWN;
2639ced5c338SAndrei Emeltchenko 
2640e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
264109b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
26427a4cd51dSMarcel Holtmann 	bacpy(&hdev->random_addr, BDADDR_ANY);
2643e59fda8dSJohan Hedberg 
26441da177e4SLinus Torvalds 	hci_req_unlock(hdev);
26451da177e4SLinus Torvalds 
26461da177e4SLinus Torvalds 	hci_dev_put(hdev);
26471da177e4SLinus Torvalds 	return 0;
26481da177e4SLinus Torvalds }
26491da177e4SLinus Torvalds 
26501da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
26511da177e4SLinus Torvalds {
26521da177e4SLinus Torvalds 	struct hci_dev *hdev;
26531da177e4SLinus Torvalds 	int err;
26541da177e4SLinus Torvalds 
265570f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
265670f23020SAndrei Emeltchenko 	if (!hdev)
26571da177e4SLinus Torvalds 		return -ENODEV;
26588ee56540SMarcel Holtmann 
26590736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
26600736cfa8SMarcel Holtmann 		err = -EBUSY;
26610736cfa8SMarcel Holtmann 		goto done;
26620736cfa8SMarcel Holtmann 	}
26630736cfa8SMarcel Holtmann 
26648ee56540SMarcel Holtmann 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
26658ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
26668ee56540SMarcel Holtmann 
26671da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
26688ee56540SMarcel Holtmann 
26690736cfa8SMarcel Holtmann done:
26701da177e4SLinus Torvalds 	hci_dev_put(hdev);
26711da177e4SLinus Torvalds 	return err;
26721da177e4SLinus Torvalds }
26731da177e4SLinus Torvalds 
26741da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
26751da177e4SLinus Torvalds {
26761da177e4SLinus Torvalds 	struct hci_dev *hdev;
26771da177e4SLinus Torvalds 	int ret = 0;
26781da177e4SLinus Torvalds 
267970f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
268070f23020SAndrei Emeltchenko 	if (!hdev)
26811da177e4SLinus Torvalds 		return -ENODEV;
26821da177e4SLinus Torvalds 
26831da177e4SLinus Torvalds 	hci_req_lock(hdev);
26841da177e4SLinus Torvalds 
2685808a049eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
2686808a049eSMarcel Holtmann 		ret = -ENETDOWN;
26871da177e4SLinus Torvalds 		goto done;
2688808a049eSMarcel Holtmann 	}
26891da177e4SLinus Torvalds 
26900736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
26910736cfa8SMarcel Holtmann 		ret = -EBUSY;
26920736cfa8SMarcel Holtmann 		goto done;
26930736cfa8SMarcel Holtmann 	}
26940736cfa8SMarcel Holtmann 
26954a964404SMarcel Holtmann 	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
2696fee746b0SMarcel Holtmann 		ret = -EOPNOTSUPP;
2697fee746b0SMarcel Holtmann 		goto done;
2698fee746b0SMarcel Holtmann 	}
2699fee746b0SMarcel Holtmann 
27001da177e4SLinus Torvalds 	/* Drop queues */
27011da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
27021da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
27031da177e4SLinus Torvalds 
270409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
27051f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
27061da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
270709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
27081da177e4SLinus Torvalds 
27091da177e4SLinus Torvalds 	if (hdev->flush)
27101da177e4SLinus Torvalds 		hdev->flush(hdev);
27111da177e4SLinus Torvalds 
27121da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
27136ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
27141da177e4SLinus Torvalds 
271501178cd4SJohan Hedberg 	ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
27161da177e4SLinus Torvalds 
27171da177e4SLinus Torvalds done:
27181da177e4SLinus Torvalds 	hci_req_unlock(hdev);
27191da177e4SLinus Torvalds 	hci_dev_put(hdev);
27201da177e4SLinus Torvalds 	return ret;
27211da177e4SLinus Torvalds }
27221da177e4SLinus Torvalds 
27231da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
27241da177e4SLinus Torvalds {
27251da177e4SLinus Torvalds 	struct hci_dev *hdev;
27261da177e4SLinus Torvalds 	int ret = 0;
27271da177e4SLinus Torvalds 
272870f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
272970f23020SAndrei Emeltchenko 	if (!hdev)
27301da177e4SLinus Torvalds 		return -ENODEV;
27311da177e4SLinus Torvalds 
27320736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
27330736cfa8SMarcel Holtmann 		ret = -EBUSY;
27340736cfa8SMarcel Holtmann 		goto done;
27350736cfa8SMarcel Holtmann 	}
27360736cfa8SMarcel Holtmann 
27374a964404SMarcel Holtmann 	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
2738fee746b0SMarcel Holtmann 		ret = -EOPNOTSUPP;
2739fee746b0SMarcel Holtmann 		goto done;
2740fee746b0SMarcel Holtmann 	}
2741fee746b0SMarcel Holtmann 
27421da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
27431da177e4SLinus Torvalds 
27440736cfa8SMarcel Holtmann done:
27451da177e4SLinus Torvalds 	hci_dev_put(hdev);
27461da177e4SLinus Torvalds 	return ret;
27471da177e4SLinus Torvalds }
27481da177e4SLinus Torvalds 
2749123abc08SJohan Hedberg static void hci_update_scan_state(struct hci_dev *hdev, u8 scan)
2750123abc08SJohan Hedberg {
2751bc6d2d04SJohan Hedberg 	bool conn_changed, discov_changed;
2752123abc08SJohan Hedberg 
2753123abc08SJohan Hedberg 	BT_DBG("%s scan 0x%02x", hdev->name, scan);
2754123abc08SJohan Hedberg 
2755123abc08SJohan Hedberg 	if ((scan & SCAN_PAGE))
2756123abc08SJohan Hedberg 		conn_changed = !test_and_set_bit(HCI_CONNECTABLE,
2757123abc08SJohan Hedberg 						 &hdev->dev_flags);
2758123abc08SJohan Hedberg 	else
2759123abc08SJohan Hedberg 		conn_changed = test_and_clear_bit(HCI_CONNECTABLE,
2760123abc08SJohan Hedberg 						  &hdev->dev_flags);
2761123abc08SJohan Hedberg 
2762bc6d2d04SJohan Hedberg 	if ((scan & SCAN_INQUIRY)) {
2763bc6d2d04SJohan Hedberg 		discov_changed = !test_and_set_bit(HCI_DISCOVERABLE,
2764bc6d2d04SJohan Hedberg 						   &hdev->dev_flags);
2765bc6d2d04SJohan Hedberg 	} else {
2766bc6d2d04SJohan Hedberg 		clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
2767bc6d2d04SJohan Hedberg 		discov_changed = test_and_clear_bit(HCI_DISCOVERABLE,
2768bc6d2d04SJohan Hedberg 						    &hdev->dev_flags);
2769bc6d2d04SJohan Hedberg 	}
2770bc6d2d04SJohan Hedberg 
2771123abc08SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2772123abc08SJohan Hedberg 		return;
2773123abc08SJohan Hedberg 
2774bc6d2d04SJohan Hedberg 	if (conn_changed || discov_changed) {
2775bc6d2d04SJohan Hedberg 		/* In case this was disabled through mgmt */
2776bc6d2d04SJohan Hedberg 		set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
2777bc6d2d04SJohan Hedberg 
2778bc6d2d04SJohan Hedberg 		if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags))
2779bc6d2d04SJohan Hedberg 			mgmt_update_adv_data(hdev);
2780bc6d2d04SJohan Hedberg 
2781123abc08SJohan Hedberg 		mgmt_new_settings(hdev);
2782123abc08SJohan Hedberg 	}
2783bc6d2d04SJohan Hedberg }
2784123abc08SJohan Hedberg 
27851da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
27861da177e4SLinus Torvalds {
27871da177e4SLinus Torvalds 	struct hci_dev *hdev;
27881da177e4SLinus Torvalds 	struct hci_dev_req dr;
27891da177e4SLinus Torvalds 	int err = 0;
27901da177e4SLinus Torvalds 
27911da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
27921da177e4SLinus Torvalds 		return -EFAULT;
27931da177e4SLinus Torvalds 
279470f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
279570f23020SAndrei Emeltchenko 	if (!hdev)
27961da177e4SLinus Torvalds 		return -ENODEV;
27971da177e4SLinus Torvalds 
27980736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
27990736cfa8SMarcel Holtmann 		err = -EBUSY;
28000736cfa8SMarcel Holtmann 		goto done;
28010736cfa8SMarcel Holtmann 	}
28020736cfa8SMarcel Holtmann 
28034a964404SMarcel Holtmann 	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
2804fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
2805fee746b0SMarcel Holtmann 		goto done;
2806fee746b0SMarcel Holtmann 	}
2807fee746b0SMarcel Holtmann 
28085b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
28095b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
28105b69bef5SMarcel Holtmann 		goto done;
28115b69bef5SMarcel Holtmann 	}
28125b69bef5SMarcel Holtmann 
281356f87901SJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
281456f87901SJohan Hedberg 		err = -EOPNOTSUPP;
281556f87901SJohan Hedberg 		goto done;
281656f87901SJohan Hedberg 	}
281756f87901SJohan Hedberg 
28181da177e4SLinus Torvalds 	switch (cmd) {
28191da177e4SLinus Torvalds 	case HCISETAUTH:
282001178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
28215f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
28221da177e4SLinus Torvalds 		break;
28231da177e4SLinus Torvalds 
28241da177e4SLinus Torvalds 	case HCISETENCRYPT:
28251da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
28261da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
28271da177e4SLinus Torvalds 			break;
28281da177e4SLinus Torvalds 		}
28291da177e4SLinus Torvalds 
28301da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
28311da177e4SLinus Torvalds 			/* Auth must be enabled first */
283201178cd4SJohan Hedberg 			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
28335f246e89SAndrei Emeltchenko 					   HCI_INIT_TIMEOUT);
28341da177e4SLinus Torvalds 			if (err)
28351da177e4SLinus Torvalds 				break;
28361da177e4SLinus Torvalds 		}
28371da177e4SLinus Torvalds 
283801178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
28395f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
28401da177e4SLinus Torvalds 		break;
28411da177e4SLinus Torvalds 
28421da177e4SLinus Torvalds 	case HCISETSCAN:
284301178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
28445f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
284591a668b0SJohan Hedberg 
2846bc6d2d04SJohan Hedberg 		/* Ensure that the connectable and discoverable states
2847bc6d2d04SJohan Hedberg 		 * get correctly modified as this was a non-mgmt change.
284891a668b0SJohan Hedberg 		 */
2849123abc08SJohan Hedberg 		if (!err)
2850123abc08SJohan Hedberg 			hci_update_scan_state(hdev, dr.dev_opt);
28511da177e4SLinus Torvalds 		break;
28521da177e4SLinus Torvalds 
28531da177e4SLinus Torvalds 	case HCISETLINKPOL:
285401178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
28555f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
28561da177e4SLinus Torvalds 		break;
28571da177e4SLinus Torvalds 
28581da177e4SLinus Torvalds 	case HCISETLINKMODE:
2859e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
2860e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
2861e4e8e37cSMarcel Holtmann 		break;
2862e4e8e37cSMarcel Holtmann 
2863e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
2864e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
28651da177e4SLinus Torvalds 		break;
28661da177e4SLinus Torvalds 
28671da177e4SLinus Torvalds 	case HCISETACLMTU:
28681da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
28691da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
28701da177e4SLinus Torvalds 		break;
28711da177e4SLinus Torvalds 
28721da177e4SLinus Torvalds 	case HCISETSCOMTU:
28731da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
28741da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
28751da177e4SLinus Torvalds 		break;
28761da177e4SLinus Torvalds 
28771da177e4SLinus Torvalds 	default:
28781da177e4SLinus Torvalds 		err = -EINVAL;
28791da177e4SLinus Torvalds 		break;
28801da177e4SLinus Torvalds 	}
2881e4e8e37cSMarcel Holtmann 
28820736cfa8SMarcel Holtmann done:
28831da177e4SLinus Torvalds 	hci_dev_put(hdev);
28841da177e4SLinus Torvalds 	return err;
28851da177e4SLinus Torvalds }
28861da177e4SLinus Torvalds 
28871da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
28881da177e4SLinus Torvalds {
28898035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
28901da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
28911da177e4SLinus Torvalds 	struct hci_dev_req *dr;
28921da177e4SLinus Torvalds 	int n = 0, size, err;
28931da177e4SLinus Torvalds 	__u16 dev_num;
28941da177e4SLinus Torvalds 
28951da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
28961da177e4SLinus Torvalds 		return -EFAULT;
28971da177e4SLinus Torvalds 
28981da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
28991da177e4SLinus Torvalds 		return -EINVAL;
29001da177e4SLinus Torvalds 
29011da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
29021da177e4SLinus Torvalds 
290370f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
290470f23020SAndrei Emeltchenko 	if (!dl)
29051da177e4SLinus Torvalds 		return -ENOMEM;
29061da177e4SLinus Torvalds 
29071da177e4SLinus Torvalds 	dr = dl->dev_req;
29081da177e4SLinus Torvalds 
2909f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
29108035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
29112e84d8dbSMarcel Holtmann 		unsigned long flags = hdev->flags;
2912c542a06cSJohan Hedberg 
29132e84d8dbSMarcel Holtmann 		/* When the auto-off is configured it means the transport
29142e84d8dbSMarcel Holtmann 		 * is running, but in that case still indicate that the
29152e84d8dbSMarcel Holtmann 		 * device is actually down.
29162e84d8dbSMarcel Holtmann 		 */
29172e84d8dbSMarcel Holtmann 		if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
29182e84d8dbSMarcel Holtmann 			flags &= ~BIT(HCI_UP);
2919c542a06cSJohan Hedberg 
29201da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
29212e84d8dbSMarcel Holtmann 		(dr + n)->dev_opt = flags;
2922c542a06cSJohan Hedberg 
29231da177e4SLinus Torvalds 		if (++n >= dev_num)
29241da177e4SLinus Torvalds 			break;
29251da177e4SLinus Torvalds 	}
2926f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
29271da177e4SLinus Torvalds 
29281da177e4SLinus Torvalds 	dl->dev_num = n;
29291da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
29301da177e4SLinus Torvalds 
29311da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
29321da177e4SLinus Torvalds 	kfree(dl);
29331da177e4SLinus Torvalds 
29341da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
29351da177e4SLinus Torvalds }
29361da177e4SLinus Torvalds 
29371da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
29381da177e4SLinus Torvalds {
29391da177e4SLinus Torvalds 	struct hci_dev *hdev;
29401da177e4SLinus Torvalds 	struct hci_dev_info di;
29412e84d8dbSMarcel Holtmann 	unsigned long flags;
29421da177e4SLinus Torvalds 	int err = 0;
29431da177e4SLinus Torvalds 
29441da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
29451da177e4SLinus Torvalds 		return -EFAULT;
29461da177e4SLinus Torvalds 
294770f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
294870f23020SAndrei Emeltchenko 	if (!hdev)
29491da177e4SLinus Torvalds 		return -ENODEV;
29501da177e4SLinus Torvalds 
29512e84d8dbSMarcel Holtmann 	/* When the auto-off is configured it means the transport
29522e84d8dbSMarcel Holtmann 	 * is running, but in that case still indicate that the
29532e84d8dbSMarcel Holtmann 	 * device is actually down.
29542e84d8dbSMarcel Holtmann 	 */
29552e84d8dbSMarcel Holtmann 	if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
29562e84d8dbSMarcel Holtmann 		flags = hdev->flags & ~BIT(HCI_UP);
29572e84d8dbSMarcel Holtmann 	else
29582e84d8dbSMarcel Holtmann 		flags = hdev->flags;
2959c542a06cSJohan Hedberg 
29601da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
29611da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
296260f2a3edSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4);
29632e84d8dbSMarcel Holtmann 	di.flags    = flags;
29641da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
2965572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
29661da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
29671da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
29681da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
29691da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
2970572c7f84SJohan Hedberg 	} else {
2971572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
2972572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
2973572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
2974572c7f84SJohan Hedberg 		di.sco_pkts = 0;
2975572c7f84SJohan Hedberg 	}
29761da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
29771da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
29781da177e4SLinus Torvalds 
29791da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
29801da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
29811da177e4SLinus Torvalds 
29821da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
29831da177e4SLinus Torvalds 		err = -EFAULT;
29841da177e4SLinus Torvalds 
29851da177e4SLinus Torvalds 	hci_dev_put(hdev);
29861da177e4SLinus Torvalds 
29871da177e4SLinus Torvalds 	return err;
29881da177e4SLinus Torvalds }
29891da177e4SLinus Torvalds 
29901da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
29911da177e4SLinus Torvalds 
2992611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
2993611b30f7SMarcel Holtmann {
2994611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
2995611b30f7SMarcel Holtmann 
2996611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
2997611b30f7SMarcel Holtmann 
29980736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
29990736cfa8SMarcel Holtmann 		return -EBUSY;
30000736cfa8SMarcel Holtmann 
30015e130367SJohan Hedberg 	if (blocked) {
30025e130367SJohan Hedberg 		set_bit(HCI_RFKILLED, &hdev->dev_flags);
3003d603b76bSMarcel Holtmann 		if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
3004d603b76bSMarcel Holtmann 		    !test_bit(HCI_CONFIG, &hdev->dev_flags))
3005611b30f7SMarcel Holtmann 			hci_dev_do_close(hdev);
30065e130367SJohan Hedberg 	} else {
30075e130367SJohan Hedberg 		clear_bit(HCI_RFKILLED, &hdev->dev_flags);
30085e130367SJohan Hedberg 	}
3009611b30f7SMarcel Holtmann 
3010611b30f7SMarcel Holtmann 	return 0;
3011611b30f7SMarcel Holtmann }
3012611b30f7SMarcel Holtmann 
3013611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
3014611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
3015611b30f7SMarcel Holtmann };
3016611b30f7SMarcel Holtmann 
3017ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
3018ab81cbf9SJohan Hedberg {
3019ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
302096570ffcSJohan Hedberg 	int err;
3021ab81cbf9SJohan Hedberg 
3022ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
3023ab81cbf9SJohan Hedberg 
3024cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
302596570ffcSJohan Hedberg 	if (err < 0) {
302696570ffcSJohan Hedberg 		mgmt_set_powered_failed(hdev, err);
3027ab81cbf9SJohan Hedberg 		return;
302896570ffcSJohan Hedberg 	}
3029ab81cbf9SJohan Hedberg 
3030a5c8f270SMarcel Holtmann 	/* During the HCI setup phase, a few error conditions are
3031a5c8f270SMarcel Holtmann 	 * ignored and they need to be checked now. If they are still
3032a5c8f270SMarcel Holtmann 	 * valid, it is important to turn the device back off.
3033a5c8f270SMarcel Holtmann 	 */
3034a5c8f270SMarcel Holtmann 	if (test_bit(HCI_RFKILLED, &hdev->dev_flags) ||
30354a964404SMarcel Holtmann 	    test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) ||
3036a5c8f270SMarcel Holtmann 	    (hdev->dev_type == HCI_BREDR &&
3037a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
3038a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->static_addr, BDADDR_ANY))) {
3039bf543036SJohan Hedberg 		clear_bit(HCI_AUTO_OFF, &hdev->dev_flags);
3040bf543036SJohan Hedberg 		hci_dev_do_close(hdev);
3041bf543036SJohan Hedberg 	} else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
304219202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
304319202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
3044bf543036SJohan Hedberg 	}
3045ab81cbf9SJohan Hedberg 
3046fee746b0SMarcel Holtmann 	if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) {
30474a964404SMarcel Holtmann 		/* For unconfigured devices, set the HCI_RAW flag
30484a964404SMarcel Holtmann 		 * so that userspace can easily identify them.
30494a964404SMarcel Holtmann 		 */
30504a964404SMarcel Holtmann 		if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
30514a964404SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
30520602a8adSMarcel Holtmann 
30530602a8adSMarcel Holtmann 		/* For fully configured devices, this will send
30540602a8adSMarcel Holtmann 		 * the Index Added event. For unconfigured devices,
30550602a8adSMarcel Holtmann 		 * it will send Unconfigued Index Added event.
30560602a8adSMarcel Holtmann 		 *
30570602a8adSMarcel Holtmann 		 * Devices with HCI_QUIRK_RAW_DEVICE are ignored
30580602a8adSMarcel Holtmann 		 * and no event will be send.
30590602a8adSMarcel Holtmann 		 */
3060744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
3061d603b76bSMarcel Holtmann 	} else if (test_and_clear_bit(HCI_CONFIG, &hdev->dev_flags)) {
30625ea234d3SMarcel Holtmann 		/* When the controller is now configured, then it
30635ea234d3SMarcel Holtmann 		 * is important to clear the HCI_RAW flag.
30645ea234d3SMarcel Holtmann 		 */
30655ea234d3SMarcel Holtmann 		if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
30665ea234d3SMarcel Holtmann 			clear_bit(HCI_RAW, &hdev->flags);
30675ea234d3SMarcel Holtmann 
3068d603b76bSMarcel Holtmann 		/* Powering on the controller with HCI_CONFIG set only
3069d603b76bSMarcel Holtmann 		 * happens with the transition from unconfigured to
3070d603b76bSMarcel Holtmann 		 * configured. This will send the Index Added event.
3071d603b76bSMarcel Holtmann 		 */
3072d603b76bSMarcel Holtmann 		mgmt_index_added(hdev);
3073ab81cbf9SJohan Hedberg 	}
3074ab81cbf9SJohan Hedberg }
3075ab81cbf9SJohan Hedberg 
3076ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
3077ab81cbf9SJohan Hedberg {
30783243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
30793243553fSJohan Hedberg 					    power_off.work);
3080ab81cbf9SJohan Hedberg 
3081ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
3082ab81cbf9SJohan Hedberg 
30838ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
3084ab81cbf9SJohan Hedberg }
3085ab81cbf9SJohan Hedberg 
308616ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
308716ab91abSJohan Hedberg {
308816ab91abSJohan Hedberg 	struct hci_dev *hdev;
308916ab91abSJohan Hedberg 
309016ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
309116ab91abSJohan Hedberg 
309216ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
309316ab91abSJohan Hedberg 
3094d1967ff8SMarcel Holtmann 	mgmt_discoverable_timeout(hdev);
309516ab91abSJohan Hedberg }
309616ab91abSJohan Hedberg 
309735f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev)
30982aeb9a1aSJohan Hedberg {
30994821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
31002aeb9a1aSJohan Hedberg 
31014821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
31024821002cSJohan Hedberg 		list_del(&uuid->list);
31032aeb9a1aSJohan Hedberg 		kfree(uuid);
31042aeb9a1aSJohan Hedberg 	}
31052aeb9a1aSJohan Hedberg }
31062aeb9a1aSJohan Hedberg 
310735f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev)
310855ed8ca1SJohan Hedberg {
310955ed8ca1SJohan Hedberg 	struct list_head *p, *n;
311055ed8ca1SJohan Hedberg 
311155ed8ca1SJohan Hedberg 	list_for_each_safe(p, n, &hdev->link_keys) {
311255ed8ca1SJohan Hedberg 		struct link_key *key;
311355ed8ca1SJohan Hedberg 
311455ed8ca1SJohan Hedberg 		key = list_entry(p, struct link_key, list);
311555ed8ca1SJohan Hedberg 
311655ed8ca1SJohan Hedberg 		list_del(p);
311755ed8ca1SJohan Hedberg 		kfree(key);
311855ed8ca1SJohan Hedberg 	}
311955ed8ca1SJohan Hedberg }
312055ed8ca1SJohan Hedberg 
312135f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev)
3122b899efafSVinicius Costa Gomes {
3123b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
3124b899efafSVinicius Costa Gomes 
3125b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
3126b899efafSVinicius Costa Gomes 		list_del(&k->list);
3127b899efafSVinicius Costa Gomes 		kfree(k);
3128b899efafSVinicius Costa Gomes 	}
3129b899efafSVinicius Costa Gomes }
3130b899efafSVinicius Costa Gomes 
3131970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev)
3132970c4e46SJohan Hedberg {
3133970c4e46SJohan Hedberg 	struct smp_irk *k, *tmp;
3134970c4e46SJohan Hedberg 
3135970c4e46SJohan Hedberg 	list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) {
3136970c4e46SJohan Hedberg 		list_del(&k->list);
3137970c4e46SJohan Hedberg 		kfree(k);
3138970c4e46SJohan Hedberg 	}
3139970c4e46SJohan Hedberg }
3140970c4e46SJohan Hedberg 
314155ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
314255ed8ca1SJohan Hedberg {
314355ed8ca1SJohan Hedberg 	struct link_key *k;
314455ed8ca1SJohan Hedberg 
31458035ded4SLuiz Augusto von Dentz 	list_for_each_entry(k, &hdev->link_keys, list)
314655ed8ca1SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0)
314755ed8ca1SJohan Hedberg 			return k;
314855ed8ca1SJohan Hedberg 
314955ed8ca1SJohan Hedberg 	return NULL;
315055ed8ca1SJohan Hedberg }
315155ed8ca1SJohan Hedberg 
3152745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
3153d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
3154d25e28abSJohan Hedberg {
3155d25e28abSJohan Hedberg 	/* Legacy key */
3156d25e28abSJohan Hedberg 	if (key_type < 0x03)
3157745c0ce3SVishal Agarwal 		return true;
3158d25e28abSJohan Hedberg 
3159d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
3160d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
3161745c0ce3SVishal Agarwal 		return false;
3162d25e28abSJohan Hedberg 
3163d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
3164d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
3165745c0ce3SVishal Agarwal 		return false;
3166d25e28abSJohan Hedberg 
3167d25e28abSJohan Hedberg 	/* Security mode 3 case */
3168d25e28abSJohan Hedberg 	if (!conn)
3169745c0ce3SVishal Agarwal 		return true;
3170d25e28abSJohan Hedberg 
3171d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
3172d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
3173745c0ce3SVishal Agarwal 		return true;
3174d25e28abSJohan Hedberg 
3175d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
3176d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
3177745c0ce3SVishal Agarwal 		return true;
3178d25e28abSJohan Hedberg 
3179d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
3180d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
3181745c0ce3SVishal Agarwal 		return true;
3182d25e28abSJohan Hedberg 
3183d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
3184d25e28abSJohan Hedberg 	 * persistently */
3185745c0ce3SVishal Agarwal 	return false;
3186d25e28abSJohan Hedberg }
3187d25e28abSJohan Hedberg 
3188e804d25dSJohan Hedberg static u8 ltk_role(u8 type)
318998a0b845SJohan Hedberg {
3190e804d25dSJohan Hedberg 	if (type == SMP_LTK)
3191e804d25dSJohan Hedberg 		return HCI_ROLE_MASTER;
319298a0b845SJohan Hedberg 
3193e804d25dSJohan Hedberg 	return HCI_ROLE_SLAVE;
319498a0b845SJohan Hedberg }
319598a0b845SJohan Hedberg 
3196fe39c7b2SMarcel Holtmann struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, __le64 rand,
3197e804d25dSJohan Hedberg 			     u8 role)
319875d262c2SVinicius Costa Gomes {
3199c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
320075d262c2SVinicius Costa Gomes 
3201c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list) {
3202fe39c7b2SMarcel Holtmann 		if (k->ediv != ediv || k->rand != rand)
320375d262c2SVinicius Costa Gomes 			continue;
320475d262c2SVinicius Costa Gomes 
3205e804d25dSJohan Hedberg 		if (ltk_role(k->type) != role)
320698a0b845SJohan Hedberg 			continue;
320798a0b845SJohan Hedberg 
320875d262c2SVinicius Costa Gomes 		return k;
320975d262c2SVinicius Costa Gomes 	}
321075d262c2SVinicius Costa Gomes 
321175d262c2SVinicius Costa Gomes 	return NULL;
321275d262c2SVinicius Costa Gomes }
321375d262c2SVinicius Costa Gomes 
3214c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
3215e804d25dSJohan Hedberg 				     u8 addr_type, u8 role)
321675d262c2SVinicius Costa Gomes {
3217c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
321875d262c2SVinicius Costa Gomes 
3219c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list)
3220c9839a11SVinicius Costa Gomes 		if (addr_type == k->bdaddr_type &&
322198a0b845SJohan Hedberg 		    bacmp(bdaddr, &k->bdaddr) == 0 &&
3222e804d25dSJohan Hedberg 		    ltk_role(k->type) == role)
322375d262c2SVinicius Costa Gomes 			return k;
322475d262c2SVinicius Costa Gomes 
322575d262c2SVinicius Costa Gomes 	return NULL;
322675d262c2SVinicius Costa Gomes }
322775d262c2SVinicius Costa Gomes 
3228970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa)
3229970c4e46SJohan Hedberg {
3230970c4e46SJohan Hedberg 	struct smp_irk *irk;
3231970c4e46SJohan Hedberg 
3232970c4e46SJohan Hedberg 	list_for_each_entry(irk, &hdev->identity_resolving_keys, list) {
3233970c4e46SJohan Hedberg 		if (!bacmp(&irk->rpa, rpa))
3234970c4e46SJohan Hedberg 			return irk;
3235970c4e46SJohan Hedberg 	}
3236970c4e46SJohan Hedberg 
3237893ededeSJohan Hedberg 	if (!hdev->tfm_aes)
3238893ededeSJohan Hedberg 		return NULL;
3239893ededeSJohan Hedberg 
3240970c4e46SJohan Hedberg 	list_for_each_entry(irk, &hdev->identity_resolving_keys, list) {
3241970c4e46SJohan Hedberg 		if (smp_irk_matches(hdev->tfm_aes, irk->val, rpa)) {
3242970c4e46SJohan Hedberg 			bacpy(&irk->rpa, rpa);
3243970c4e46SJohan Hedberg 			return irk;
3244970c4e46SJohan Hedberg 		}
3245970c4e46SJohan Hedberg 	}
3246970c4e46SJohan Hedberg 
3247970c4e46SJohan Hedberg 	return NULL;
3248970c4e46SJohan Hedberg }
3249970c4e46SJohan Hedberg 
3250970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
3251970c4e46SJohan Hedberg 				     u8 addr_type)
3252970c4e46SJohan Hedberg {
3253970c4e46SJohan Hedberg 	struct smp_irk *irk;
3254970c4e46SJohan Hedberg 
32556cfc9988SJohan Hedberg 	/* Identity Address must be public or static random */
32566cfc9988SJohan Hedberg 	if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0)
32576cfc9988SJohan Hedberg 		return NULL;
32586cfc9988SJohan Hedberg 
3259970c4e46SJohan Hedberg 	list_for_each_entry(irk, &hdev->identity_resolving_keys, list) {
3260970c4e46SJohan Hedberg 		if (addr_type == irk->addr_type &&
3261970c4e46SJohan Hedberg 		    bacmp(bdaddr, &irk->bdaddr) == 0)
3262970c4e46SJohan Hedberg 			return irk;
3263970c4e46SJohan Hedberg 	}
3264970c4e46SJohan Hedberg 
3265970c4e46SJohan Hedberg 	return NULL;
3266970c4e46SJohan Hedberg }
3267970c4e46SJohan Hedberg 
3268567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn,
32697652ff6aSJohan Hedberg 				  bdaddr_t *bdaddr, u8 *val, u8 type,
32707652ff6aSJohan Hedberg 				  u8 pin_len, bool *persistent)
327155ed8ca1SJohan Hedberg {
327255ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
3273745c0ce3SVishal Agarwal 	u8 old_key_type;
327455ed8ca1SJohan Hedberg 
327555ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
327655ed8ca1SJohan Hedberg 	if (old_key) {
327755ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
327855ed8ca1SJohan Hedberg 		key = old_key;
327955ed8ca1SJohan Hedberg 	} else {
328012adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
32810a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
328255ed8ca1SJohan Hedberg 		if (!key)
3283567fa2aaSJohan Hedberg 			return NULL;
328455ed8ca1SJohan Hedberg 		list_add(&key->list, &hdev->link_keys);
328555ed8ca1SJohan Hedberg 	}
328655ed8ca1SJohan Hedberg 
32876ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
328855ed8ca1SJohan Hedberg 
3289d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
3290d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
3291d25e28abSJohan Hedberg 	 * previous key */
3292d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
3293a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
3294d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
3295655fe6ecSJohan Hedberg 		if (conn)
3296655fe6ecSJohan Hedberg 			conn->key_type = type;
3297655fe6ecSJohan Hedberg 	}
3298d25e28abSJohan Hedberg 
329955ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
33009b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
330155ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
330255ed8ca1SJohan Hedberg 
3303b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
330455ed8ca1SJohan Hedberg 		key->type = old_key_type;
33054748fed2SJohan Hedberg 	else
33064748fed2SJohan Hedberg 		key->type = type;
33074748fed2SJohan Hedberg 
33087652ff6aSJohan Hedberg 	if (persistent)
33097652ff6aSJohan Hedberg 		*persistent = hci_persistent_key(hdev, conn, type,
33107652ff6aSJohan Hedberg 						 old_key_type);
33114df378a1SJohan Hedberg 
3312567fa2aaSJohan Hedberg 	return key;
331355ed8ca1SJohan Hedberg }
331455ed8ca1SJohan Hedberg 
3315ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
331635d70271SJohan Hedberg 			    u8 addr_type, u8 type, u8 authenticated,
3317fe39c7b2SMarcel Holtmann 			    u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand)
331875d262c2SVinicius Costa Gomes {
3319c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
3320e804d25dSJohan Hedberg 	u8 role = ltk_role(type);
332175d262c2SVinicius Costa Gomes 
3322e804d25dSJohan Hedberg 	old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type, role);
3323c9839a11SVinicius Costa Gomes 	if (old_key)
332475d262c2SVinicius Costa Gomes 		key = old_key;
3325c9839a11SVinicius Costa Gomes 	else {
33260a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
332775d262c2SVinicius Costa Gomes 		if (!key)
3328ca9142b8SJohan Hedberg 			return NULL;
3329c9839a11SVinicius Costa Gomes 		list_add(&key->list, &hdev->long_term_keys);
333075d262c2SVinicius Costa Gomes 	}
333175d262c2SVinicius Costa Gomes 
333275d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
3333c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
3334c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
3335c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
3336c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
3337fe39c7b2SMarcel Holtmann 	key->rand = rand;
3338c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
3339c9839a11SVinicius Costa Gomes 	key->type = type;
334075d262c2SVinicius Costa Gomes 
3341ca9142b8SJohan Hedberg 	return key;
334275d262c2SVinicius Costa Gomes }
334375d262c2SVinicius Costa Gomes 
3344ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr,
3345ca9142b8SJohan Hedberg 			    u8 addr_type, u8 val[16], bdaddr_t *rpa)
3346970c4e46SJohan Hedberg {
3347970c4e46SJohan Hedberg 	struct smp_irk *irk;
3348970c4e46SJohan Hedberg 
3349970c4e46SJohan Hedberg 	irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type);
3350970c4e46SJohan Hedberg 	if (!irk) {
3351970c4e46SJohan Hedberg 		irk = kzalloc(sizeof(*irk), GFP_KERNEL);
3352970c4e46SJohan Hedberg 		if (!irk)
3353ca9142b8SJohan Hedberg 			return NULL;
3354970c4e46SJohan Hedberg 
3355970c4e46SJohan Hedberg 		bacpy(&irk->bdaddr, bdaddr);
3356970c4e46SJohan Hedberg 		irk->addr_type = addr_type;
3357970c4e46SJohan Hedberg 
3358970c4e46SJohan Hedberg 		list_add(&irk->list, &hdev->identity_resolving_keys);
3359970c4e46SJohan Hedberg 	}
3360970c4e46SJohan Hedberg 
3361970c4e46SJohan Hedberg 	memcpy(irk->val, val, 16);
3362970c4e46SJohan Hedberg 	bacpy(&irk->rpa, rpa);
3363970c4e46SJohan Hedberg 
3364ca9142b8SJohan Hedberg 	return irk;
3365970c4e46SJohan Hedberg }
3366970c4e46SJohan Hedberg 
336755ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
336855ed8ca1SJohan Hedberg {
336955ed8ca1SJohan Hedberg 	struct link_key *key;
337055ed8ca1SJohan Hedberg 
337155ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
337255ed8ca1SJohan Hedberg 	if (!key)
337355ed8ca1SJohan Hedberg 		return -ENOENT;
337455ed8ca1SJohan Hedberg 
33756ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
337655ed8ca1SJohan Hedberg 
337755ed8ca1SJohan Hedberg 	list_del(&key->list);
337855ed8ca1SJohan Hedberg 	kfree(key);
337955ed8ca1SJohan Hedberg 
338055ed8ca1SJohan Hedberg 	return 0;
338155ed8ca1SJohan Hedberg }
338255ed8ca1SJohan Hedberg 
3383e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type)
3384b899efafSVinicius Costa Gomes {
3385b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
3386c51ffa0bSJohan Hedberg 	int removed = 0;
3387b899efafSVinicius Costa Gomes 
3388b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
3389e0b2b27eSJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type)
3390b899efafSVinicius Costa Gomes 			continue;
3391b899efafSVinicius Costa Gomes 
33926ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
3393b899efafSVinicius Costa Gomes 
3394b899efafSVinicius Costa Gomes 		list_del(&k->list);
3395b899efafSVinicius Costa Gomes 		kfree(k);
3396c51ffa0bSJohan Hedberg 		removed++;
3397b899efafSVinicius Costa Gomes 	}
3398b899efafSVinicius Costa Gomes 
3399c51ffa0bSJohan Hedberg 	return removed ? 0 : -ENOENT;
3400b899efafSVinicius Costa Gomes }
3401b899efafSVinicius Costa Gomes 
3402a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type)
3403a7ec7338SJohan Hedberg {
3404a7ec7338SJohan Hedberg 	struct smp_irk *k, *tmp;
3405a7ec7338SJohan Hedberg 
3406668b7b19SJohan Hedberg 	list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) {
3407a7ec7338SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type)
3408a7ec7338SJohan Hedberg 			continue;
3409a7ec7338SJohan Hedberg 
3410a7ec7338SJohan Hedberg 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
3411a7ec7338SJohan Hedberg 
3412a7ec7338SJohan Hedberg 		list_del(&k->list);
3413a7ec7338SJohan Hedberg 		kfree(k);
3414a7ec7338SJohan Hedberg 	}
3415a7ec7338SJohan Hedberg }
3416a7ec7338SJohan Hedberg 
34176bd32326SVille Tervo /* HCI command timer function */
341865cc2b49SMarcel Holtmann static void hci_cmd_timeout(struct work_struct *work)
34196bd32326SVille Tervo {
342065cc2b49SMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev,
342165cc2b49SMarcel Holtmann 					    cmd_timer.work);
34226bd32326SVille Tervo 
3423bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
3424bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
3425bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
3426bda4f23aSAndrei Emeltchenko 
3427bda4f23aSAndrei Emeltchenko 		BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode);
3428bda4f23aSAndrei Emeltchenko 	} else {
34296bd32326SVille Tervo 		BT_ERR("%s command tx timeout", hdev->name);
3430bda4f23aSAndrei Emeltchenko 	}
3431bda4f23aSAndrei Emeltchenko 
34326bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
3433c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
34346bd32326SVille Tervo }
34356bd32326SVille Tervo 
34362763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
34372763eda6SSzymon Janc 					  bdaddr_t *bdaddr)
34382763eda6SSzymon Janc {
34392763eda6SSzymon Janc 	struct oob_data *data;
34402763eda6SSzymon Janc 
34412763eda6SSzymon Janc 	list_for_each_entry(data, &hdev->remote_oob_data, list)
34422763eda6SSzymon Janc 		if (bacmp(bdaddr, &data->bdaddr) == 0)
34432763eda6SSzymon Janc 			return data;
34442763eda6SSzymon Janc 
34452763eda6SSzymon Janc 	return NULL;
34462763eda6SSzymon Janc }
34472763eda6SSzymon Janc 
34482763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
34492763eda6SSzymon Janc {
34502763eda6SSzymon Janc 	struct oob_data *data;
34512763eda6SSzymon Janc 
34522763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
34532763eda6SSzymon Janc 	if (!data)
34542763eda6SSzymon Janc 		return -ENOENT;
34552763eda6SSzymon Janc 
34566ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
34572763eda6SSzymon Janc 
34582763eda6SSzymon Janc 	list_del(&data->list);
34592763eda6SSzymon Janc 	kfree(data);
34602763eda6SSzymon Janc 
34612763eda6SSzymon Janc 	return 0;
34622763eda6SSzymon Janc }
34632763eda6SSzymon Janc 
346435f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev)
34652763eda6SSzymon Janc {
34662763eda6SSzymon Janc 	struct oob_data *data, *n;
34672763eda6SSzymon Janc 
34682763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
34692763eda6SSzymon Janc 		list_del(&data->list);
34702763eda6SSzymon Janc 		kfree(data);
34712763eda6SSzymon Janc 	}
34722763eda6SSzymon Janc }
34732763eda6SSzymon Janc 
34740798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
34750798872eSMarcel Holtmann 			    u8 *hash, u8 *randomizer)
34762763eda6SSzymon Janc {
34772763eda6SSzymon Janc 	struct oob_data *data;
34782763eda6SSzymon Janc 
34792763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
34802763eda6SSzymon Janc 	if (!data) {
34810a14ab41SJohan Hedberg 		data = kmalloc(sizeof(*data), GFP_KERNEL);
34822763eda6SSzymon Janc 		if (!data)
34832763eda6SSzymon Janc 			return -ENOMEM;
34842763eda6SSzymon Janc 
34852763eda6SSzymon Janc 		bacpy(&data->bdaddr, bdaddr);
34862763eda6SSzymon Janc 		list_add(&data->list, &hdev->remote_oob_data);
34872763eda6SSzymon Janc 	}
34882763eda6SSzymon Janc 
3489519ca9d0SMarcel Holtmann 	memcpy(data->hash192, hash, sizeof(data->hash192));
3490519ca9d0SMarcel Holtmann 	memcpy(data->randomizer192, randomizer, sizeof(data->randomizer192));
34912763eda6SSzymon Janc 
34920798872eSMarcel Holtmann 	memset(data->hash256, 0, sizeof(data->hash256));
34930798872eSMarcel Holtmann 	memset(data->randomizer256, 0, sizeof(data->randomizer256));
34940798872eSMarcel Holtmann 
34950798872eSMarcel Holtmann 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
34960798872eSMarcel Holtmann 
34970798872eSMarcel Holtmann 	return 0;
34980798872eSMarcel Holtmann }
34990798872eSMarcel Holtmann 
35000798872eSMarcel Holtmann int hci_add_remote_oob_ext_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
35010798872eSMarcel Holtmann 				u8 *hash192, u8 *randomizer192,
35020798872eSMarcel Holtmann 				u8 *hash256, u8 *randomizer256)
35030798872eSMarcel Holtmann {
35040798872eSMarcel Holtmann 	struct oob_data *data;
35050798872eSMarcel Holtmann 
35060798872eSMarcel Holtmann 	data = hci_find_remote_oob_data(hdev, bdaddr);
35070798872eSMarcel Holtmann 	if (!data) {
35080a14ab41SJohan Hedberg 		data = kmalloc(sizeof(*data), GFP_KERNEL);
35090798872eSMarcel Holtmann 		if (!data)
35100798872eSMarcel Holtmann 			return -ENOMEM;
35110798872eSMarcel Holtmann 
35120798872eSMarcel Holtmann 		bacpy(&data->bdaddr, bdaddr);
35130798872eSMarcel Holtmann 		list_add(&data->list, &hdev->remote_oob_data);
35140798872eSMarcel Holtmann 	}
35150798872eSMarcel Holtmann 
35160798872eSMarcel Holtmann 	memcpy(data->hash192, hash192, sizeof(data->hash192));
35170798872eSMarcel Holtmann 	memcpy(data->randomizer192, randomizer192, sizeof(data->randomizer192));
35180798872eSMarcel Holtmann 
35190798872eSMarcel Holtmann 	memcpy(data->hash256, hash256, sizeof(data->hash256));
35200798872eSMarcel Holtmann 	memcpy(data->randomizer256, randomizer256, sizeof(data->randomizer256));
35210798872eSMarcel Holtmann 
35226ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
35232763eda6SSzymon Janc 
35242763eda6SSzymon Janc 	return 0;
35252763eda6SSzymon Janc }
35262763eda6SSzymon Janc 
3527dcc36c16SJohan Hedberg struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
3528b9ee0a78SMarcel Holtmann 					 bdaddr_t *bdaddr, u8 type)
3529b2a66aadSAntti Julku {
3530b2a66aadSAntti Julku 	struct bdaddr_list *b;
3531b2a66aadSAntti Julku 
3532dcc36c16SJohan Hedberg 	list_for_each_entry(b, bdaddr_list, list) {
3533b9ee0a78SMarcel Holtmann 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
3534b2a66aadSAntti Julku 			return b;
3535b9ee0a78SMarcel Holtmann 	}
3536b2a66aadSAntti Julku 
3537b2a66aadSAntti Julku 	return NULL;
3538b2a66aadSAntti Julku }
3539b2a66aadSAntti Julku 
3540dcc36c16SJohan Hedberg void hci_bdaddr_list_clear(struct list_head *bdaddr_list)
3541b2a66aadSAntti Julku {
3542b2a66aadSAntti Julku 	struct list_head *p, *n;
3543b2a66aadSAntti Julku 
3544dcc36c16SJohan Hedberg 	list_for_each_safe(p, n, bdaddr_list) {
3545b9ee0a78SMarcel Holtmann 		struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list);
3546b2a66aadSAntti Julku 
3547b2a66aadSAntti Julku 		list_del(p);
3548b2a66aadSAntti Julku 		kfree(b);
3549b2a66aadSAntti Julku 	}
3550b2a66aadSAntti Julku }
3551b2a66aadSAntti Julku 
3552dcc36c16SJohan Hedberg int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type)
3553b2a66aadSAntti Julku {
3554b2a66aadSAntti Julku 	struct bdaddr_list *entry;
3555b2a66aadSAntti Julku 
3556b9ee0a78SMarcel Holtmann 	if (!bacmp(bdaddr, BDADDR_ANY))
3557b2a66aadSAntti Julku 		return -EBADF;
3558b2a66aadSAntti Julku 
3559dcc36c16SJohan Hedberg 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
35605e762444SAntti Julku 		return -EEXIST;
3561b2a66aadSAntti Julku 
356227f70f3eSJohan Hedberg 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
35635e762444SAntti Julku 	if (!entry)
35645e762444SAntti Julku 		return -ENOMEM;
3565b2a66aadSAntti Julku 
3566b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
3567b9ee0a78SMarcel Holtmann 	entry->bdaddr_type = type;
3568b2a66aadSAntti Julku 
3569dcc36c16SJohan Hedberg 	list_add(&entry->list, list);
3570b2a66aadSAntti Julku 
35712a8357f2SJohan Hedberg 	return 0;
3572b2a66aadSAntti Julku }
3573b2a66aadSAntti Julku 
3574dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type)
3575b2a66aadSAntti Julku {
3576b2a66aadSAntti Julku 	struct bdaddr_list *entry;
3577b2a66aadSAntti Julku 
357835f7498aSJohan Hedberg 	if (!bacmp(bdaddr, BDADDR_ANY)) {
3579dcc36c16SJohan Hedberg 		hci_bdaddr_list_clear(list);
358035f7498aSJohan Hedberg 		return 0;
358135f7498aSJohan Hedberg 	}
3582b2a66aadSAntti Julku 
3583dcc36c16SJohan Hedberg 	entry = hci_bdaddr_list_lookup(list, bdaddr, type);
3584d2ab0ac1SMarcel Holtmann 	if (!entry)
3585d2ab0ac1SMarcel Holtmann 		return -ENOENT;
3586d2ab0ac1SMarcel Holtmann 
3587d2ab0ac1SMarcel Holtmann 	list_del(&entry->list);
3588d2ab0ac1SMarcel Holtmann 	kfree(entry);
3589d2ab0ac1SMarcel Holtmann 
3590d2ab0ac1SMarcel Holtmann 	return 0;
3591d2ab0ac1SMarcel Holtmann }
3592d2ab0ac1SMarcel Holtmann 
359315819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
359415819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
359515819a70SAndre Guedes 					       bdaddr_t *addr, u8 addr_type)
359615819a70SAndre Guedes {
359715819a70SAndre Guedes 	struct hci_conn_params *params;
359815819a70SAndre Guedes 
3599738f6185SJohan Hedberg 	/* The conn params list only contains identity addresses */
3600738f6185SJohan Hedberg 	if (!hci_is_identity_address(addr, addr_type))
3601738f6185SJohan Hedberg 		return NULL;
3602738f6185SJohan Hedberg 
360315819a70SAndre Guedes 	list_for_each_entry(params, &hdev->le_conn_params, list) {
360415819a70SAndre Guedes 		if (bacmp(&params->addr, addr) == 0 &&
360515819a70SAndre Guedes 		    params->addr_type == addr_type) {
360615819a70SAndre Guedes 			return params;
360715819a70SAndre Guedes 		}
360815819a70SAndre Guedes 	}
360915819a70SAndre Guedes 
361015819a70SAndre Guedes 	return NULL;
361115819a70SAndre Guedes }
361215819a70SAndre Guedes 
3613cef952ceSAndre Guedes static bool is_connected(struct hci_dev *hdev, bdaddr_t *addr, u8 type)
3614cef952ceSAndre Guedes {
3615cef952ceSAndre Guedes 	struct hci_conn *conn;
3616cef952ceSAndre Guedes 
3617cef952ceSAndre Guedes 	conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, addr);
3618cef952ceSAndre Guedes 	if (!conn)
3619cef952ceSAndre Guedes 		return false;
3620cef952ceSAndre Guedes 
3621cef952ceSAndre Guedes 	if (conn->dst_type != type)
3622cef952ceSAndre Guedes 		return false;
3623cef952ceSAndre Guedes 
3624cef952ceSAndre Guedes 	if (conn->state != BT_CONNECTED)
3625cef952ceSAndre Guedes 		return false;
3626cef952ceSAndre Guedes 
3627cef952ceSAndre Guedes 	return true;
3628cef952ceSAndre Guedes }
3629cef952ceSAndre Guedes 
363015819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
3631501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list,
36324b10966fSMarcel Holtmann 						  bdaddr_t *addr, u8 addr_type)
363315819a70SAndre Guedes {
3634912b42efSJohan Hedberg 	struct hci_conn_params *param;
363515819a70SAndre Guedes 
3636738f6185SJohan Hedberg 	/* The list only contains identity addresses */
3637738f6185SJohan Hedberg 	if (!hci_is_identity_address(addr, addr_type))
3638738f6185SJohan Hedberg 		return NULL;
363915819a70SAndre Guedes 
3640501f8827SJohan Hedberg 	list_for_each_entry(param, list, action) {
3641912b42efSJohan Hedberg 		if (bacmp(&param->addr, addr) == 0 &&
3642912b42efSJohan Hedberg 		    param->addr_type == addr_type)
3643912b42efSJohan Hedberg 			return param;
36444b10966fSMarcel Holtmann 	}
36454b10966fSMarcel Holtmann 
36464b10966fSMarcel Holtmann 	return NULL;
364715819a70SAndre Guedes }
364815819a70SAndre Guedes 
364915819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
365051d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev,
365151d167c0SMarcel Holtmann 					    bdaddr_t *addr, u8 addr_type)
365215819a70SAndre Guedes {
365315819a70SAndre Guedes 	struct hci_conn_params *params;
365415819a70SAndre Guedes 
3655c46245b3SJohan Hedberg 	if (!hci_is_identity_address(addr, addr_type))
365651d167c0SMarcel Holtmann 		return NULL;
3657a9b0a04cSAndre Guedes 
365815819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
3659cef952ceSAndre Guedes 	if (params)
366051d167c0SMarcel Holtmann 		return params;
366115819a70SAndre Guedes 
366215819a70SAndre Guedes 	params = kzalloc(sizeof(*params), GFP_KERNEL);
366315819a70SAndre Guedes 	if (!params) {
366415819a70SAndre Guedes 		BT_ERR("Out of memory");
366551d167c0SMarcel Holtmann 		return NULL;
366615819a70SAndre Guedes 	}
366715819a70SAndre Guedes 
366815819a70SAndre Guedes 	bacpy(&params->addr, addr);
366915819a70SAndre Guedes 	params->addr_type = addr_type;
3670cef952ceSAndre Guedes 
3671cef952ceSAndre Guedes 	list_add(&params->list, &hdev->le_conn_params);
367293450c75SJohan Hedberg 	INIT_LIST_HEAD(&params->action);
3673cef952ceSAndre Guedes 
3674bf5b3c8bSMarcel Holtmann 	params->conn_min_interval = hdev->le_conn_min_interval;
3675bf5b3c8bSMarcel Holtmann 	params->conn_max_interval = hdev->le_conn_max_interval;
3676bf5b3c8bSMarcel Holtmann 	params->conn_latency = hdev->le_conn_latency;
3677bf5b3c8bSMarcel Holtmann 	params->supervision_timeout = hdev->le_supv_timeout;
3678bf5b3c8bSMarcel Holtmann 	params->auto_connect = HCI_AUTO_CONN_DISABLED;
3679bf5b3c8bSMarcel Holtmann 
3680bf5b3c8bSMarcel Holtmann 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
3681bf5b3c8bSMarcel Holtmann 
368251d167c0SMarcel Holtmann 	return params;
3683bf5b3c8bSMarcel Holtmann }
3684bf5b3c8bSMarcel Holtmann 
3685bf5b3c8bSMarcel Holtmann /* This function requires the caller holds hdev->lock */
3686bf5b3c8bSMarcel Holtmann int hci_conn_params_set(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
3687d06b50ceSMarcel Holtmann 			u8 auto_connect)
368815819a70SAndre Guedes {
368915819a70SAndre Guedes 	struct hci_conn_params *params;
369015819a70SAndre Guedes 
36918c87aae1SMarcel Holtmann 	params = hci_conn_params_add(hdev, addr, addr_type);
36928c87aae1SMarcel Holtmann 	if (!params)
36938c87aae1SMarcel Holtmann 		return -EIO;
369415819a70SAndre Guedes 
369542ce26deSJohan Hedberg 	if (params->auto_connect == auto_connect)
369642ce26deSJohan Hedberg 		return 0;
369742ce26deSJohan Hedberg 
369866f8455aSJohan Hedberg 	list_del_init(&params->action);
369915819a70SAndre Guedes 
3700cef952ceSAndre Guedes 	switch (auto_connect) {
3701cef952ceSAndre Guedes 	case HCI_AUTO_CONN_DISABLED:
3702cef952ceSAndre Guedes 	case HCI_AUTO_CONN_LINK_LOSS:
370395305baaSJohan Hedberg 		hci_update_background_scan(hdev);
3704cef952ceSAndre Guedes 		break;
3705851efca8SJohan Hedberg 	case HCI_AUTO_CONN_REPORT:
370695305baaSJohan Hedberg 		list_add(&params->action, &hdev->pend_le_reports);
370795305baaSJohan Hedberg 		hci_update_background_scan(hdev);
3708851efca8SJohan Hedberg 		break;
37094b9e7e75SMarcel Holtmann 	case HCI_AUTO_CONN_DIRECT:
3710cef952ceSAndre Guedes 	case HCI_AUTO_CONN_ALWAYS:
371195305baaSJohan Hedberg 		if (!is_connected(hdev, addr, addr_type)) {
371295305baaSJohan Hedberg 			list_add(&params->action, &hdev->pend_le_conns);
371395305baaSJohan Hedberg 			hci_update_background_scan(hdev);
371495305baaSJohan Hedberg 		}
3715cef952ceSAndre Guedes 		break;
3716cef952ceSAndre Guedes 	}
371715819a70SAndre Guedes 
3718851efca8SJohan Hedberg 	params->auto_connect = auto_connect;
3719851efca8SJohan Hedberg 
3720d06b50ceSMarcel Holtmann 	BT_DBG("addr %pMR (type %u) auto_connect %u", addr, addr_type,
3721d06b50ceSMarcel Holtmann 	       auto_connect);
3722a9b0a04cSAndre Guedes 
3723a9b0a04cSAndre Guedes 	return 0;
372415819a70SAndre Guedes }
372515819a70SAndre Guedes 
372615819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
372715819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
372815819a70SAndre Guedes {
372915819a70SAndre Guedes 	struct hci_conn_params *params;
373015819a70SAndre Guedes 
373115819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
373215819a70SAndre Guedes 	if (!params)
373315819a70SAndre Guedes 		return;
373415819a70SAndre Guedes 
373595305baaSJohan Hedberg 	list_del(&params->action);
373615819a70SAndre Guedes 	list_del(&params->list);
373715819a70SAndre Guedes 	kfree(params);
373815819a70SAndre Guedes 
373995305baaSJohan Hedberg 	hci_update_background_scan(hdev);
374095305baaSJohan Hedberg 
374115819a70SAndre Guedes 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
374215819a70SAndre Guedes }
374315819a70SAndre Guedes 
374415819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
374555af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev)
374615819a70SAndre Guedes {
374715819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
374815819a70SAndre Guedes 
374915819a70SAndre Guedes 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
375055af49a8SJohan Hedberg 		if (params->auto_connect != HCI_AUTO_CONN_DISABLED)
375155af49a8SJohan Hedberg 			continue;
375215819a70SAndre Guedes 		list_del(&params->list);
375315819a70SAndre Guedes 		kfree(params);
375415819a70SAndre Guedes 	}
375515819a70SAndre Guedes 
375655af49a8SJohan Hedberg 	BT_DBG("All LE disabled connection parameters were removed");
375755af49a8SJohan Hedberg }
375855af49a8SJohan Hedberg 
375955af49a8SJohan Hedberg /* This function requires the caller holds hdev->lock */
3760373110c5SJohan Hedberg void hci_conn_params_clear_all(struct hci_dev *hdev)
376115819a70SAndre Guedes {
376215819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
376315819a70SAndre Guedes 
376415819a70SAndre Guedes 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
3765a2f41a8fSJohan Hedberg 		list_del(&params->action);
376615819a70SAndre Guedes 		list_del(&params->list);
376715819a70SAndre Guedes 		kfree(params);
376815819a70SAndre Guedes 	}
376915819a70SAndre Guedes 
3770a2f41a8fSJohan Hedberg 	hci_update_background_scan(hdev);
37711089b67dSMarcel Holtmann 
377215819a70SAndre Guedes 	BT_DBG("All LE connection parameters were removed");
377315819a70SAndre Guedes }
377415819a70SAndre Guedes 
37754c87eaabSAndre Guedes static void inquiry_complete(struct hci_dev *hdev, u8 status)
37767ba8b4beSAndre Guedes {
37774c87eaabSAndre Guedes 	if (status) {
37784c87eaabSAndre Guedes 		BT_ERR("Failed to start inquiry: status %d", status);
37797ba8b4beSAndre Guedes 
37804c87eaabSAndre Guedes 		hci_dev_lock(hdev);
37814c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
37824c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
37834c87eaabSAndre Guedes 		return;
37844c87eaabSAndre Guedes 	}
37857ba8b4beSAndre Guedes }
37867ba8b4beSAndre Guedes 
37874c87eaabSAndre Guedes static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status)
37887ba8b4beSAndre Guedes {
37894c87eaabSAndre Guedes 	/* General inquiry access code (GIAC) */
37904c87eaabSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
37914c87eaabSAndre Guedes 	struct hci_request req;
37924c87eaabSAndre Guedes 	struct hci_cp_inquiry cp;
37937ba8b4beSAndre Guedes 	int err;
37947ba8b4beSAndre Guedes 
37954c87eaabSAndre Guedes 	if (status) {
37964c87eaabSAndre Guedes 		BT_ERR("Failed to disable LE scanning: status %d", status);
37974c87eaabSAndre Guedes 		return;
37987ba8b4beSAndre Guedes 	}
37997ba8b4beSAndre Guedes 
38004c87eaabSAndre Guedes 	switch (hdev->discovery.type) {
38014c87eaabSAndre Guedes 	case DISCOV_TYPE_LE:
38024c87eaabSAndre Guedes 		hci_dev_lock(hdev);
38034c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
38044c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
38054c87eaabSAndre Guedes 		break;
38067dbfac1dSAndre Guedes 
38074c87eaabSAndre Guedes 	case DISCOV_TYPE_INTERLEAVED:
38084c87eaabSAndre Guedes 		hci_req_init(&req, hdev);
38097dbfac1dSAndre Guedes 
38107dbfac1dSAndre Guedes 		memset(&cp, 0, sizeof(cp));
38114c87eaabSAndre Guedes 		memcpy(&cp.lap, lap, sizeof(cp.lap));
38124c87eaabSAndre Guedes 		cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN;
38134c87eaabSAndre Guedes 		hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp);
38144c87eaabSAndre Guedes 
38154c87eaabSAndre Guedes 		hci_dev_lock(hdev);
38164c87eaabSAndre Guedes 
38174c87eaabSAndre Guedes 		hci_inquiry_cache_flush(hdev);
38184c87eaabSAndre Guedes 
38194c87eaabSAndre Guedes 		err = hci_req_run(&req, inquiry_complete);
38204c87eaabSAndre Guedes 		if (err) {
38214c87eaabSAndre Guedes 			BT_ERR("Inquiry request failed: err %d", err);
38224c87eaabSAndre Guedes 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
38237dbfac1dSAndre Guedes 		}
38247dbfac1dSAndre Guedes 
38254c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
38264c87eaabSAndre Guedes 		break;
38274c87eaabSAndre Guedes 	}
38287dbfac1dSAndre Guedes }
38297dbfac1dSAndre Guedes 
38307ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work)
38317ba8b4beSAndre Guedes {
38327ba8b4beSAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev,
38337ba8b4beSAndre Guedes 					    le_scan_disable.work);
38344c87eaabSAndre Guedes 	struct hci_request req;
38354c87eaabSAndre Guedes 	int err;
38367ba8b4beSAndre Guedes 
38377ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
38387ba8b4beSAndre Guedes 
38394c87eaabSAndre Guedes 	hci_req_init(&req, hdev);
38407ba8b4beSAndre Guedes 
3841b1efcc28SAndre Guedes 	hci_req_add_le_scan_disable(&req);
38427ba8b4beSAndre Guedes 
38434c87eaabSAndre Guedes 	err = hci_req_run(&req, le_scan_disable_work_complete);
38444c87eaabSAndre Guedes 	if (err)
38454c87eaabSAndre Guedes 		BT_ERR("Disable LE scanning request failed: err %d", err);
384628b75a89SAndre Guedes }
384728b75a89SAndre Guedes 
38488d97250eSJohan Hedberg static void set_random_addr(struct hci_request *req, bdaddr_t *rpa)
38498d97250eSJohan Hedberg {
38508d97250eSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
38518d97250eSJohan Hedberg 
38528d97250eSJohan Hedberg 	/* If we're advertising or initiating an LE connection we can't
38538d97250eSJohan Hedberg 	 * go ahead and change the random address at this time. This is
38548d97250eSJohan Hedberg 	 * because the eventual initiator address used for the
38558d97250eSJohan Hedberg 	 * subsequently created connection will be undefined (some
38568d97250eSJohan Hedberg 	 * controllers use the new address and others the one we had
38578d97250eSJohan Hedberg 	 * when the operation started).
38588d97250eSJohan Hedberg 	 *
38598d97250eSJohan Hedberg 	 * In this kind of scenario skip the update and let the random
38608d97250eSJohan Hedberg 	 * address be updated at the next cycle.
38618d97250eSJohan Hedberg 	 */
38625ce194c4SJohan Hedberg 	if (test_bit(HCI_LE_ADV, &hdev->dev_flags) ||
38638d97250eSJohan Hedberg 	    hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT)) {
38648d97250eSJohan Hedberg 		BT_DBG("Deferring random address update");
38658d97250eSJohan Hedberg 		return;
38668d97250eSJohan Hedberg 	}
38678d97250eSJohan Hedberg 
38688d97250eSJohan Hedberg 	hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6, rpa);
38698d97250eSJohan Hedberg }
38708d97250eSJohan Hedberg 
387194b1fc92SMarcel Holtmann int hci_update_random_address(struct hci_request *req, bool require_privacy,
387294b1fc92SMarcel Holtmann 			      u8 *own_addr_type)
3873ebd3a747SJohan Hedberg {
3874ebd3a747SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
3875ebd3a747SJohan Hedberg 	int err;
3876ebd3a747SJohan Hedberg 
3877ebd3a747SJohan Hedberg 	/* If privacy is enabled use a resolvable private address. If
38782b5224dcSMarcel Holtmann 	 * current RPA has expired or there is something else than
38792b5224dcSMarcel Holtmann 	 * the current RPA in use, then generate a new one.
3880ebd3a747SJohan Hedberg 	 */
3881ebd3a747SJohan Hedberg 	if (test_bit(HCI_PRIVACY, &hdev->dev_flags)) {
3882ebd3a747SJohan Hedberg 		int to;
3883ebd3a747SJohan Hedberg 
3884ebd3a747SJohan Hedberg 		*own_addr_type = ADDR_LE_DEV_RANDOM;
3885ebd3a747SJohan Hedberg 
3886ebd3a747SJohan Hedberg 		if (!test_and_clear_bit(HCI_RPA_EXPIRED, &hdev->dev_flags) &&
38872b5224dcSMarcel Holtmann 		    !bacmp(&hdev->random_addr, &hdev->rpa))
3888ebd3a747SJohan Hedberg 			return 0;
3889ebd3a747SJohan Hedberg 
3890fabed38fSJohan Hedberg 		if (!hdev->tfm_aes) {
3891fabed38fSJohan Hedberg 			BT_ERR("%s crypto not available to generate RPA",
3892fabed38fSJohan Hedberg 			       hdev->name);
3893fabed38fSJohan Hedberg 			return -EOPNOTSUPP;
3894fabed38fSJohan Hedberg 		}
3895fabed38fSJohan Hedberg 
38962b5224dcSMarcel Holtmann 		err = smp_generate_rpa(hdev->tfm_aes, hdev->irk, &hdev->rpa);
3897ebd3a747SJohan Hedberg 		if (err < 0) {
3898ebd3a747SJohan Hedberg 			BT_ERR("%s failed to generate new RPA", hdev->name);
3899ebd3a747SJohan Hedberg 			return err;
3900ebd3a747SJohan Hedberg 		}
3901ebd3a747SJohan Hedberg 
39028d97250eSJohan Hedberg 		set_random_addr(req, &hdev->rpa);
3903ebd3a747SJohan Hedberg 
3904ebd3a747SJohan Hedberg 		to = msecs_to_jiffies(hdev->rpa_timeout * 1000);
3905ebd3a747SJohan Hedberg 		queue_delayed_work(hdev->workqueue, &hdev->rpa_expired, to);
3906ebd3a747SJohan Hedberg 
3907ebd3a747SJohan Hedberg 		return 0;
3908ebd3a747SJohan Hedberg 	}
3909ebd3a747SJohan Hedberg 
391094b1fc92SMarcel Holtmann 	/* In case of required privacy without resolvable private address,
391194b1fc92SMarcel Holtmann 	 * use an unresolvable private address. This is useful for active
391294b1fc92SMarcel Holtmann 	 * scanning and non-connectable advertising.
391394b1fc92SMarcel Holtmann 	 */
391494b1fc92SMarcel Holtmann 	if (require_privacy) {
391594b1fc92SMarcel Holtmann 		bdaddr_t urpa;
391694b1fc92SMarcel Holtmann 
391794b1fc92SMarcel Holtmann 		get_random_bytes(&urpa, 6);
391894b1fc92SMarcel Holtmann 		urpa.b[5] &= 0x3f;	/* Clear two most significant bits */
391994b1fc92SMarcel Holtmann 
392094b1fc92SMarcel Holtmann 		*own_addr_type = ADDR_LE_DEV_RANDOM;
39218d97250eSJohan Hedberg 		set_random_addr(req, &urpa);
392294b1fc92SMarcel Holtmann 		return 0;
392394b1fc92SMarcel Holtmann 	}
392494b1fc92SMarcel Holtmann 
3925ebd3a747SJohan Hedberg 	/* If forcing static address is in use or there is no public
3926ebd3a747SJohan Hedberg 	 * address use the static address as random address (but skip
3927ebd3a747SJohan Hedberg 	 * the HCI command if the current random address is already the
3928ebd3a747SJohan Hedberg 	 * static one.
3929ebd3a747SJohan Hedberg 	 */
3930111902f7SMarcel Holtmann 	if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) ||
3931ebd3a747SJohan Hedberg 	    !bacmp(&hdev->bdaddr, BDADDR_ANY)) {
3932ebd3a747SJohan Hedberg 		*own_addr_type = ADDR_LE_DEV_RANDOM;
3933ebd3a747SJohan Hedberg 		if (bacmp(&hdev->static_addr, &hdev->random_addr))
3934ebd3a747SJohan Hedberg 			hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6,
3935ebd3a747SJohan Hedberg 				    &hdev->static_addr);
3936ebd3a747SJohan Hedberg 		return 0;
3937ebd3a747SJohan Hedberg 	}
3938ebd3a747SJohan Hedberg 
3939ebd3a747SJohan Hedberg 	/* Neither privacy nor static address is being used so use a
3940ebd3a747SJohan Hedberg 	 * public address.
3941ebd3a747SJohan Hedberg 	 */
3942ebd3a747SJohan Hedberg 	*own_addr_type = ADDR_LE_DEV_PUBLIC;
3943ebd3a747SJohan Hedberg 
3944ebd3a747SJohan Hedberg 	return 0;
3945ebd3a747SJohan Hedberg }
3946ebd3a747SJohan Hedberg 
3947a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller.
3948a1f4c318SJohan Hedberg  *
3949a1f4c318SJohan Hedberg  * If the controller has a public BD_ADDR, then by default use that one.
3950a1f4c318SJohan Hedberg  * If this is a LE only controller without a public address, default to
3951a1f4c318SJohan Hedberg  * the static random address.
3952a1f4c318SJohan Hedberg  *
3953a1f4c318SJohan Hedberg  * For debugging purposes it is possible to force controllers with a
3954a1f4c318SJohan Hedberg  * public address to use the static random address instead.
3955a1f4c318SJohan Hedberg  */
3956a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
3957a1f4c318SJohan Hedberg 			       u8 *bdaddr_type)
3958a1f4c318SJohan Hedberg {
3959111902f7SMarcel Holtmann 	if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) ||
3960a1f4c318SJohan Hedberg 	    !bacmp(&hdev->bdaddr, BDADDR_ANY)) {
3961a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->static_addr);
3962a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_RANDOM;
3963a1f4c318SJohan Hedberg 	} else {
3964a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->bdaddr);
3965a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_PUBLIC;
3966a1f4c318SJohan Hedberg 	}
3967a1f4c318SJohan Hedberg }
3968a1f4c318SJohan Hedberg 
39699be0dab7SDavid Herrmann /* Alloc HCI device */
39709be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void)
39719be0dab7SDavid Herrmann {
39729be0dab7SDavid Herrmann 	struct hci_dev *hdev;
39739be0dab7SDavid Herrmann 
397427f70f3eSJohan Hedberg 	hdev = kzalloc(sizeof(*hdev), GFP_KERNEL);
39759be0dab7SDavid Herrmann 	if (!hdev)
39769be0dab7SDavid Herrmann 		return NULL;
39779be0dab7SDavid Herrmann 
3978b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
3979b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
3980b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
3981b4cb9fb2SMarcel Holtmann 	hdev->num_iac = 0x01;		/* One IAC support is mandatory */
3982b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03;	/* No Input No Output */
398396c2103aSMarcel Holtmann 	hdev->manufacturer = 0xffff;	/* Default to internal use */
3984bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
3985bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
3986b1b813d4SDavid Herrmann 
3987b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
3988b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
3989b1b813d4SDavid Herrmann 
39903f959d46SMarcel Holtmann 	hdev->le_adv_channel_map = 0x07;
3991628531c9SGeorg Lukas 	hdev->le_adv_min_interval = 0x0800;
3992628531c9SGeorg Lukas 	hdev->le_adv_max_interval = 0x0800;
3993bef64738SMarcel Holtmann 	hdev->le_scan_interval = 0x0060;
3994bef64738SMarcel Holtmann 	hdev->le_scan_window = 0x0030;
39954e70c7e7SMarcel Holtmann 	hdev->le_conn_min_interval = 0x0028;
39964e70c7e7SMarcel Holtmann 	hdev->le_conn_max_interval = 0x0038;
399704fb7d90SMarcel Holtmann 	hdev->le_conn_latency = 0x0000;
399804fb7d90SMarcel Holtmann 	hdev->le_supv_timeout = 0x002a;
3999bef64738SMarcel Holtmann 
4000d6bfd59cSJohan Hedberg 	hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT;
4001b9a7a61eSLukasz Rymanowski 	hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT;
400231ad1691SAndrzej Kaczmarek 	hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE;
400331ad1691SAndrzej Kaczmarek 	hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE;
4004d6bfd59cSJohan Hedberg 
4005b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
4006b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
4007b1b813d4SDavid Herrmann 
4008b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
4009b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->blacklist);
40106659358eSJohan Hedberg 	INIT_LIST_HEAD(&hdev->whitelist);
4011b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
4012b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
4013b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
4014970c4e46SJohan Hedberg 	INIT_LIST_HEAD(&hdev->identity_resolving_keys);
4015b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
4016d2ab0ac1SMarcel Holtmann 	INIT_LIST_HEAD(&hdev->le_white_list);
401715819a70SAndre Guedes 	INIT_LIST_HEAD(&hdev->le_conn_params);
401877a77a30SAndre Guedes 	INIT_LIST_HEAD(&hdev->pend_le_conns);
401966f8455aSJohan Hedberg 	INIT_LIST_HEAD(&hdev->pend_le_reports);
40206b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
4021b1b813d4SDavid Herrmann 
4022b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
4023b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
4024b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
4025b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
4026b1b813d4SDavid Herrmann 
4027b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
4028b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
4029b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
4030b1b813d4SDavid Herrmann 
4031b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
4032b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
4033b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
4034b1b813d4SDavid Herrmann 
4035b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
4036b1b813d4SDavid Herrmann 
403765cc2b49SMarcel Holtmann 	INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout);
4038b1b813d4SDavid Herrmann 
4039b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
4040b1b813d4SDavid Herrmann 	discovery_init(hdev);
40419be0dab7SDavid Herrmann 
40429be0dab7SDavid Herrmann 	return hdev;
40439be0dab7SDavid Herrmann }
40449be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev);
40459be0dab7SDavid Herrmann 
40469be0dab7SDavid Herrmann /* Free HCI device */
40479be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
40489be0dab7SDavid Herrmann {
40499be0dab7SDavid Herrmann 	/* will free via device release */
40509be0dab7SDavid Herrmann 	put_device(&hdev->dev);
40519be0dab7SDavid Herrmann }
40529be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
40539be0dab7SDavid Herrmann 
40541da177e4SLinus Torvalds /* Register HCI device */
40551da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
40561da177e4SLinus Torvalds {
4057b1b813d4SDavid Herrmann 	int id, error;
40581da177e4SLinus Torvalds 
405974292d5aSMarcel Holtmann 	if (!hdev->open || !hdev->close || !hdev->send)
40601da177e4SLinus Torvalds 		return -EINVAL;
40611da177e4SLinus Torvalds 
406208add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
406308add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
406408add513SMat Martineau 	 */
40653df92b31SSasha Levin 	switch (hdev->dev_type) {
40663df92b31SSasha Levin 	case HCI_BREDR:
40673df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
40681da177e4SLinus Torvalds 		break;
40693df92b31SSasha Levin 	case HCI_AMP:
40703df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
40713df92b31SSasha Levin 		break;
40723df92b31SSasha Levin 	default:
40733df92b31SSasha Levin 		return -EINVAL;
40741da177e4SLinus Torvalds 	}
40751da177e4SLinus Torvalds 
40763df92b31SSasha Levin 	if (id < 0)
40773df92b31SSasha Levin 		return id;
40783df92b31SSasha Levin 
40791da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
40801da177e4SLinus Torvalds 	hdev->id = id;
40812d8b3a11SAndrei Emeltchenko 
40822d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
40832d8b3a11SAndrei Emeltchenko 
4084d8537548SKees Cook 	hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
4085d8537548SKees Cook 					  WQ_MEM_RECLAIM, 1, hdev->name);
408633ca954dSDavid Herrmann 	if (!hdev->workqueue) {
408733ca954dSDavid Herrmann 		error = -ENOMEM;
408833ca954dSDavid Herrmann 		goto err;
408933ca954dSDavid Herrmann 	}
4090f48fd9c8SMarcel Holtmann 
4091d8537548SKees Cook 	hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
4092d8537548SKees Cook 					      WQ_MEM_RECLAIM, 1, hdev->name);
40936ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
40946ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
40956ead1bbcSJohan Hedberg 		error = -ENOMEM;
40966ead1bbcSJohan Hedberg 		goto err;
40976ead1bbcSJohan Hedberg 	}
40986ead1bbcSJohan Hedberg 
40990153e2ecSMarcel Holtmann 	if (!IS_ERR_OR_NULL(bt_debugfs))
41000153e2ecSMarcel Holtmann 		hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs);
41010153e2ecSMarcel Holtmann 
4102bdc3e0f1SMarcel Holtmann 	dev_set_name(&hdev->dev, "%s", hdev->name);
4103bdc3e0f1SMarcel Holtmann 
4104bdc3e0f1SMarcel Holtmann 	error = device_add(&hdev->dev);
410533ca954dSDavid Herrmann 	if (error < 0)
410654506918SJohan Hedberg 		goto err_wqueue;
41071da177e4SLinus Torvalds 
4108611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
4109a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
4110a8c5fb1aSGustavo Padovan 				    hdev);
4111611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
4112611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
4113611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
4114611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
4115611b30f7SMarcel Holtmann 		}
4116611b30f7SMarcel Holtmann 	}
4117611b30f7SMarcel Holtmann 
41185e130367SJohan Hedberg 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill))
41195e130367SJohan Hedberg 		set_bit(HCI_RFKILLED, &hdev->dev_flags);
41205e130367SJohan Hedberg 
4121a8b2d5c2SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->dev_flags);
4122004b0258SMarcel Holtmann 	set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
4123ce2be9acSAndrei Emeltchenko 
412401cd3404SMarcel Holtmann 	if (hdev->dev_type == HCI_BREDR) {
412556f87901SJohan Hedberg 		/* Assume BR/EDR support until proven otherwise (such as
412656f87901SJohan Hedberg 		 * through reading supported features during init.
412756f87901SJohan Hedberg 		 */
412856f87901SJohan Hedberg 		set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
412956f87901SJohan Hedberg 	}
4130ce2be9acSAndrei Emeltchenko 
4131fcee3377SGustavo Padovan 	write_lock(&hci_dev_list_lock);
4132fcee3377SGustavo Padovan 	list_add(&hdev->list, &hci_dev_list);
4133fcee3377SGustavo Padovan 	write_unlock(&hci_dev_list_lock);
4134fcee3377SGustavo Padovan 
41354a964404SMarcel Holtmann 	/* Devices that are marked for raw-only usage are unconfigured
41364a964404SMarcel Holtmann 	 * and should not be included in normal operation.
4137fee746b0SMarcel Holtmann 	 */
4138fee746b0SMarcel Holtmann 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
41394a964404SMarcel Holtmann 		set_bit(HCI_UNCONFIGURED, &hdev->dev_flags);
4140fee746b0SMarcel Holtmann 
41411da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
4142dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
41431da177e4SLinus Torvalds 
414419202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
4145fbe96d6fSMarcel Holtmann 
41461da177e4SLinus Torvalds 	return id;
4147f48fd9c8SMarcel Holtmann 
414833ca954dSDavid Herrmann err_wqueue:
414933ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
41506ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
415133ca954dSDavid Herrmann err:
41523df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
4153f48fd9c8SMarcel Holtmann 
415433ca954dSDavid Herrmann 	return error;
41551da177e4SLinus Torvalds }
41561da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
41571da177e4SLinus Torvalds 
41581da177e4SLinus Torvalds /* Unregister HCI device */
415959735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
41601da177e4SLinus Torvalds {
41613df92b31SSasha Levin 	int i, id;
4162ef222013SMarcel Holtmann 
4163c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
41641da177e4SLinus Torvalds 
416594324962SJohan Hovold 	set_bit(HCI_UNREGISTER, &hdev->dev_flags);
416694324962SJohan Hovold 
41673df92b31SSasha Levin 	id = hdev->id;
41683df92b31SSasha Levin 
4169f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
41701da177e4SLinus Torvalds 	list_del(&hdev->list);
4171f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
41721da177e4SLinus Torvalds 
41731da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
41741da177e4SLinus Torvalds 
4175cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
4176ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
4177ef222013SMarcel Holtmann 
4178b9b5ef18SGustavo Padovan 	cancel_work_sync(&hdev->power_on);
4179b9b5ef18SGustavo Padovan 
4180ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
4181d603b76bSMarcel Holtmann 	    !test_bit(HCI_SETUP, &hdev->dev_flags) &&
4182d603b76bSMarcel Holtmann 	    !test_bit(HCI_CONFIG, &hdev->dev_flags)) {
418309fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
4184744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
418509fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
418656e5cb86SJohan Hedberg 	}
4187ab81cbf9SJohan Hedberg 
41882e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
41892e58ef3eSJohan Hedberg 	 * pending list */
41902e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
41912e58ef3eSJohan Hedberg 
41921da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
41931da177e4SLinus Torvalds 
4194611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
4195611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
4196611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
4197611b30f7SMarcel Holtmann 	}
4198611b30f7SMarcel Holtmann 
4199711eafe3SJohan Hedberg 	smp_unregister(hdev);
420099780a7bSJohan Hedberg 
4201bdc3e0f1SMarcel Holtmann 	device_del(&hdev->dev);
4202147e2d59SDave Young 
42030153e2ecSMarcel Holtmann 	debugfs_remove_recursive(hdev->debugfs);
42040153e2ecSMarcel Holtmann 
4205f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
42066ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
4207f48fd9c8SMarcel Holtmann 
420809fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
4209dcc36c16SJohan Hedberg 	hci_bdaddr_list_clear(&hdev->blacklist);
42106659358eSJohan Hedberg 	hci_bdaddr_list_clear(&hdev->whitelist);
42112aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
421255ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
4213b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
4214970c4e46SJohan Hedberg 	hci_smp_irks_clear(hdev);
42152763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
4216dcc36c16SJohan Hedberg 	hci_bdaddr_list_clear(&hdev->le_white_list);
4217373110c5SJohan Hedberg 	hci_conn_params_clear_all(hdev);
421809fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
4219e2e0cacbSJohan Hedberg 
4220dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
42213df92b31SSasha Levin 
42223df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, id);
42231da177e4SLinus Torvalds }
42241da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
42251da177e4SLinus Torvalds 
42261da177e4SLinus Torvalds /* Suspend HCI device */
42271da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
42281da177e4SLinus Torvalds {
42291da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
42301da177e4SLinus Torvalds 	return 0;
42311da177e4SLinus Torvalds }
42321da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
42331da177e4SLinus Torvalds 
42341da177e4SLinus Torvalds /* Resume HCI device */
42351da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
42361da177e4SLinus Torvalds {
42371da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
42381da177e4SLinus Torvalds 	return 0;
42391da177e4SLinus Torvalds }
42401da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
42411da177e4SLinus Torvalds 
424276bca880SMarcel Holtmann /* Receive frame from HCI drivers */
4243e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
424476bca880SMarcel Holtmann {
424576bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
424676bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
424776bca880SMarcel Holtmann 		kfree_skb(skb);
424876bca880SMarcel Holtmann 		return -ENXIO;
424976bca880SMarcel Holtmann 	}
425076bca880SMarcel Holtmann 
4251d82603c6SJorrit Schippers 	/* Incoming skb */
425276bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
425376bca880SMarcel Holtmann 
425476bca880SMarcel Holtmann 	/* Time stamp */
425576bca880SMarcel Holtmann 	__net_timestamp(skb);
425676bca880SMarcel Holtmann 
425776bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
4258b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
4259c78ae283SMarcel Holtmann 
426076bca880SMarcel Holtmann 	return 0;
426176bca880SMarcel Holtmann }
426276bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
426376bca880SMarcel Holtmann 
426433e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
42651e429f38SGustavo F. Padovan 			  int count, __u8 index)
426633e882a5SSuraj Sumangala {
426733e882a5SSuraj Sumangala 	int len = 0;
426833e882a5SSuraj Sumangala 	int hlen = 0;
426933e882a5SSuraj Sumangala 	int remain = count;
427033e882a5SSuraj Sumangala 	struct sk_buff *skb;
427133e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
427233e882a5SSuraj Sumangala 
427333e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
427433e882a5SSuraj Sumangala 	    index >= NUM_REASSEMBLY)
427533e882a5SSuraj Sumangala 		return -EILSEQ;
427633e882a5SSuraj Sumangala 
427733e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
427833e882a5SSuraj Sumangala 
427933e882a5SSuraj Sumangala 	if (!skb) {
428033e882a5SSuraj Sumangala 		switch (type) {
428133e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
428233e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
428333e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
428433e882a5SSuraj Sumangala 			break;
428533e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
428633e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
428733e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
428833e882a5SSuraj Sumangala 			break;
428933e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
429033e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
429133e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
429233e882a5SSuraj Sumangala 			break;
429333e882a5SSuraj Sumangala 		}
429433e882a5SSuraj Sumangala 
42951e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
429633e882a5SSuraj Sumangala 		if (!skb)
429733e882a5SSuraj Sumangala 			return -ENOMEM;
429833e882a5SSuraj Sumangala 
429933e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
430033e882a5SSuraj Sumangala 		scb->expect = hlen;
430133e882a5SSuraj Sumangala 		scb->pkt_type = type;
430233e882a5SSuraj Sumangala 
430333e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
430433e882a5SSuraj Sumangala 	}
430533e882a5SSuraj Sumangala 
430633e882a5SSuraj Sumangala 	while (count) {
430733e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
430889bb46d0SDan Carpenter 		len = min_t(uint, scb->expect, count);
430933e882a5SSuraj Sumangala 
431033e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
431133e882a5SSuraj Sumangala 
431233e882a5SSuraj Sumangala 		count -= len;
431333e882a5SSuraj Sumangala 		data += len;
431433e882a5SSuraj Sumangala 		scb->expect -= len;
431533e882a5SSuraj Sumangala 		remain = count;
431633e882a5SSuraj Sumangala 
431733e882a5SSuraj Sumangala 		switch (type) {
431833e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
431933e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
432033e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
432133e882a5SSuraj Sumangala 				scb->expect = h->plen;
432233e882a5SSuraj Sumangala 
432333e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
432433e882a5SSuraj Sumangala 					kfree_skb(skb);
432533e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
432633e882a5SSuraj Sumangala 					return -ENOMEM;
432733e882a5SSuraj Sumangala 				}
432833e882a5SSuraj Sumangala 			}
432933e882a5SSuraj Sumangala 			break;
433033e882a5SSuraj Sumangala 
433133e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
433233e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
433333e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
433433e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
433533e882a5SSuraj Sumangala 
433633e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
433733e882a5SSuraj Sumangala 					kfree_skb(skb);
433833e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
433933e882a5SSuraj Sumangala 					return -ENOMEM;
434033e882a5SSuraj Sumangala 				}
434133e882a5SSuraj Sumangala 			}
434233e882a5SSuraj Sumangala 			break;
434333e882a5SSuraj Sumangala 
434433e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
434533e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
434633e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
434733e882a5SSuraj Sumangala 				scb->expect = h->dlen;
434833e882a5SSuraj Sumangala 
434933e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
435033e882a5SSuraj Sumangala 					kfree_skb(skb);
435133e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
435233e882a5SSuraj Sumangala 					return -ENOMEM;
435333e882a5SSuraj Sumangala 				}
435433e882a5SSuraj Sumangala 			}
435533e882a5SSuraj Sumangala 			break;
435633e882a5SSuraj Sumangala 		}
435733e882a5SSuraj Sumangala 
435833e882a5SSuraj Sumangala 		if (scb->expect == 0) {
435933e882a5SSuraj Sumangala 			/* Complete frame */
436033e882a5SSuraj Sumangala 
436133e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
4362e1a26170SMarcel Holtmann 			hci_recv_frame(hdev, skb);
436333e882a5SSuraj Sumangala 
436433e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
436533e882a5SSuraj Sumangala 			return remain;
436633e882a5SSuraj Sumangala 		}
436733e882a5SSuraj Sumangala 	}
436833e882a5SSuraj Sumangala 
436933e882a5SSuraj Sumangala 	return remain;
437033e882a5SSuraj Sumangala }
437133e882a5SSuraj Sumangala 
4372ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
4373ef222013SMarcel Holtmann {
4374f39a3c06SSuraj Sumangala 	int rem = 0;
4375f39a3c06SSuraj Sumangala 
4376ef222013SMarcel Holtmann 	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
4377ef222013SMarcel Holtmann 		return -EILSEQ;
4378ef222013SMarcel Holtmann 
4379da5f6c37SGustavo F. Padovan 	while (count) {
43801e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count, type - 1);
4381f39a3c06SSuraj Sumangala 		if (rem < 0)
4382f39a3c06SSuraj Sumangala 			return rem;
4383ef222013SMarcel Holtmann 
4384f39a3c06SSuraj Sumangala 		data += (count - rem);
4385f39a3c06SSuraj Sumangala 		count = rem;
4386f81c6224SJoe Perches 	}
4387ef222013SMarcel Holtmann 
4388f39a3c06SSuraj Sumangala 	return rem;
4389ef222013SMarcel Holtmann }
4390ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment);
4391ef222013SMarcel Holtmann 
439299811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
439399811510SSuraj Sumangala 
439499811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
439599811510SSuraj Sumangala {
439699811510SSuraj Sumangala 	int type;
439799811510SSuraj Sumangala 	int rem = 0;
439899811510SSuraj Sumangala 
4399da5f6c37SGustavo F. Padovan 	while (count) {
440099811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
440199811510SSuraj Sumangala 
440299811510SSuraj Sumangala 		if (!skb) {
440399811510SSuraj Sumangala 			struct { char type; } *pkt;
440499811510SSuraj Sumangala 
440599811510SSuraj Sumangala 			/* Start of the frame */
440699811510SSuraj Sumangala 			pkt = data;
440799811510SSuraj Sumangala 			type = pkt->type;
440899811510SSuraj Sumangala 
440999811510SSuraj Sumangala 			data++;
441099811510SSuraj Sumangala 			count--;
441199811510SSuraj Sumangala 		} else
441299811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
441399811510SSuraj Sumangala 
44141e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
44151e429f38SGustavo F. Padovan 				     STREAM_REASSEMBLY);
441699811510SSuraj Sumangala 		if (rem < 0)
441799811510SSuraj Sumangala 			return rem;
441899811510SSuraj Sumangala 
441999811510SSuraj Sumangala 		data += (count - rem);
442099811510SSuraj Sumangala 		count = rem;
4421f81c6224SJoe Perches 	}
442299811510SSuraj Sumangala 
442399811510SSuraj Sumangala 	return rem;
442499811510SSuraj Sumangala }
442599811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
442699811510SSuraj Sumangala 
44271da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
44281da177e4SLinus Torvalds 
44291da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
44301da177e4SLinus Torvalds {
44311da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
44321da177e4SLinus Torvalds 
4433f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
44341da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
4435f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
44361da177e4SLinus Torvalds 
44371da177e4SLinus Torvalds 	return 0;
44381da177e4SLinus Torvalds }
44391da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
44401da177e4SLinus Torvalds 
44411da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
44421da177e4SLinus Torvalds {
44431da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
44441da177e4SLinus Torvalds 
4445f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
44461da177e4SLinus Torvalds 	list_del(&cb->list);
4447f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
44481da177e4SLinus Torvalds 
44491da177e4SLinus Torvalds 	return 0;
44501da177e4SLinus Torvalds }
44511da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
44521da177e4SLinus Torvalds 
445351086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
44541da177e4SLinus Torvalds {
4455cdc52faaSMarcel Holtmann 	int err;
4456cdc52faaSMarcel Holtmann 
44570d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
44581da177e4SLinus Torvalds 
44591da177e4SLinus Torvalds 	/* Time stamp */
4460a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
44611da177e4SLinus Torvalds 
4462cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
4463cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
4464cd82e61cSMarcel Holtmann 
4465cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
4466cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
4467470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
44681da177e4SLinus Torvalds 	}
44691da177e4SLinus Torvalds 
44701da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
44711da177e4SLinus Torvalds 	skb_orphan(skb);
44721da177e4SLinus Torvalds 
4473cdc52faaSMarcel Holtmann 	err = hdev->send(hdev, skb);
4474cdc52faaSMarcel Holtmann 	if (err < 0) {
4475cdc52faaSMarcel Holtmann 		BT_ERR("%s sending frame failed (%d)", hdev->name, err);
4476cdc52faaSMarcel Holtmann 		kfree_skb(skb);
4477cdc52faaSMarcel Holtmann 	}
44781da177e4SLinus Torvalds }
44791da177e4SLinus Torvalds 
44803119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev)
44813119ae95SJohan Hedberg {
44823119ae95SJohan Hedberg 	skb_queue_head_init(&req->cmd_q);
44833119ae95SJohan Hedberg 	req->hdev = hdev;
44845d73e034SAndre Guedes 	req->err = 0;
44853119ae95SJohan Hedberg }
44863119ae95SJohan Hedberg 
44873119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete)
44883119ae95SJohan Hedberg {
44893119ae95SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
44903119ae95SJohan Hedberg 	struct sk_buff *skb;
44913119ae95SJohan Hedberg 	unsigned long flags;
44923119ae95SJohan Hedberg 
44933119ae95SJohan Hedberg 	BT_DBG("length %u", skb_queue_len(&req->cmd_q));
44943119ae95SJohan Hedberg 
44955d73e034SAndre Guedes 	/* If an error occured during request building, remove all HCI
44965d73e034SAndre Guedes 	 * commands queued on the HCI request queue.
44975d73e034SAndre Guedes 	 */
44985d73e034SAndre Guedes 	if (req->err) {
44995d73e034SAndre Guedes 		skb_queue_purge(&req->cmd_q);
45005d73e034SAndre Guedes 		return req->err;
45015d73e034SAndre Guedes 	}
45025d73e034SAndre Guedes 
45033119ae95SJohan Hedberg 	/* Do not allow empty requests */
45043119ae95SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
4505382b0c39SAndre Guedes 		return -ENODATA;
45063119ae95SJohan Hedberg 
45073119ae95SJohan Hedberg 	skb = skb_peek_tail(&req->cmd_q);
45083119ae95SJohan Hedberg 	bt_cb(skb)->req.complete = complete;
45093119ae95SJohan Hedberg 
45103119ae95SJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
45113119ae95SJohan Hedberg 	skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q);
45123119ae95SJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
45133119ae95SJohan Hedberg 
45143119ae95SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
45153119ae95SJohan Hedberg 
45163119ae95SJohan Hedberg 	return 0;
45173119ae95SJohan Hedberg }
45183119ae95SJohan Hedberg 
4519899de765SMarcel Holtmann bool hci_req_pending(struct hci_dev *hdev)
4520899de765SMarcel Holtmann {
4521899de765SMarcel Holtmann 	return (hdev->req_status == HCI_REQ_PEND);
4522899de765SMarcel Holtmann }
4523899de765SMarcel Holtmann 
45241ca3a9d0SJohan Hedberg static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode,
452507dc93ddSJohan Hedberg 				       u32 plen, const void *param)
45261da177e4SLinus Torvalds {
45271da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
45281da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
45291da177e4SLinus Torvalds 	struct sk_buff *skb;
45301da177e4SLinus Torvalds 
45311da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
45321ca3a9d0SJohan Hedberg 	if (!skb)
45331ca3a9d0SJohan Hedberg 		return NULL;
45341da177e4SLinus Torvalds 
45351da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
4536a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
45371da177e4SLinus Torvalds 	hdr->plen   = plen;
45381da177e4SLinus Torvalds 
45391da177e4SLinus Torvalds 	if (plen)
45401da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
45411da177e4SLinus Torvalds 
45421da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
45431da177e4SLinus Torvalds 
45440d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
4545c78ae283SMarcel Holtmann 
45461ca3a9d0SJohan Hedberg 	return skb;
45471ca3a9d0SJohan Hedberg }
45481ca3a9d0SJohan Hedberg 
45491ca3a9d0SJohan Hedberg /* Send HCI command */
455007dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
455107dc93ddSJohan Hedberg 		 const void *param)
45521ca3a9d0SJohan Hedberg {
45531ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
45541ca3a9d0SJohan Hedberg 
45551ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
45561ca3a9d0SJohan Hedberg 
45571ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
45581ca3a9d0SJohan Hedberg 	if (!skb) {
45591ca3a9d0SJohan Hedberg 		BT_ERR("%s no memory for command", hdev->name);
45601ca3a9d0SJohan Hedberg 		return -ENOMEM;
45611ca3a9d0SJohan Hedberg 	}
45621ca3a9d0SJohan Hedberg 
456311714b3dSJohan Hedberg 	/* Stand-alone HCI commands must be flaged as
456411714b3dSJohan Hedberg 	 * single-command requests.
456511714b3dSJohan Hedberg 	 */
456611714b3dSJohan Hedberg 	bt_cb(skb)->req.start = true;
456711714b3dSJohan Hedberg 
45681da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
4569c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
45701da177e4SLinus Torvalds 
45711da177e4SLinus Torvalds 	return 0;
45721da177e4SLinus Torvalds }
45731da177e4SLinus Torvalds 
457471c76a17SJohan Hedberg /* Queue a command to an asynchronous HCI request */
457507dc93ddSJohan Hedberg void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen,
457607dc93ddSJohan Hedberg 		    const void *param, u8 event)
457771c76a17SJohan Hedberg {
457871c76a17SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
457971c76a17SJohan Hedberg 	struct sk_buff *skb;
458071c76a17SJohan Hedberg 
458171c76a17SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
458271c76a17SJohan Hedberg 
458334739c1eSAndre Guedes 	/* If an error occured during request building, there is no point in
458434739c1eSAndre Guedes 	 * queueing the HCI command. We can simply return.
458534739c1eSAndre Guedes 	 */
458634739c1eSAndre Guedes 	if (req->err)
458734739c1eSAndre Guedes 		return;
458834739c1eSAndre Guedes 
458971c76a17SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
459071c76a17SJohan Hedberg 	if (!skb) {
45915d73e034SAndre Guedes 		BT_ERR("%s no memory for command (opcode 0x%4.4x)",
45925d73e034SAndre Guedes 		       hdev->name, opcode);
45935d73e034SAndre Guedes 		req->err = -ENOMEM;
4594e348fe6bSAndre Guedes 		return;
459571c76a17SJohan Hedberg 	}
459671c76a17SJohan Hedberg 
459771c76a17SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
459871c76a17SJohan Hedberg 		bt_cb(skb)->req.start = true;
459971c76a17SJohan Hedberg 
460002350a72SJohan Hedberg 	bt_cb(skb)->req.event = event;
460102350a72SJohan Hedberg 
460271c76a17SJohan Hedberg 	skb_queue_tail(&req->cmd_q, skb);
460371c76a17SJohan Hedberg }
460471c76a17SJohan Hedberg 
460507dc93ddSJohan Hedberg void hci_req_add(struct hci_request *req, u16 opcode, u32 plen,
460607dc93ddSJohan Hedberg 		 const void *param)
460702350a72SJohan Hedberg {
460802350a72SJohan Hedberg 	hci_req_add_ev(req, opcode, plen, param, 0);
460902350a72SJohan Hedberg }
461002350a72SJohan Hedberg 
46111da177e4SLinus Torvalds /* Get data from the previously sent command */
4612a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
46131da177e4SLinus Torvalds {
46141da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
46151da177e4SLinus Torvalds 
46161da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
46171da177e4SLinus Torvalds 		return NULL;
46181da177e4SLinus Torvalds 
46191da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
46201da177e4SLinus Torvalds 
4621a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
46221da177e4SLinus Torvalds 		return NULL;
46231da177e4SLinus Torvalds 
4624f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
46251da177e4SLinus Torvalds 
46261da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
46271da177e4SLinus Torvalds }
46281da177e4SLinus Torvalds 
46291da177e4SLinus Torvalds /* Send ACL data */
46301da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
46311da177e4SLinus Torvalds {
46321da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
46331da177e4SLinus Torvalds 	int len = skb->len;
46341da177e4SLinus Torvalds 
4635badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
4636badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
46379c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
4638aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
4639aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
46401da177e4SLinus Torvalds }
46411da177e4SLinus Torvalds 
4642ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
464373d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
46441da177e4SLinus Torvalds {
4645ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
46461da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
46471da177e4SLinus Torvalds 	struct sk_buff *list;
46481da177e4SLinus Torvalds 
4649087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
4650087bfd99SGustavo Padovan 	skb->data_len = 0;
4651087bfd99SGustavo Padovan 
4652087bfd99SGustavo Padovan 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
4653204a6e54SAndrei Emeltchenko 
4654204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
4655204a6e54SAndrei Emeltchenko 	case HCI_BREDR:
4656087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
4657204a6e54SAndrei Emeltchenko 		break;
4658204a6e54SAndrei Emeltchenko 	case HCI_AMP:
4659204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
4660204a6e54SAndrei Emeltchenko 		break;
4661204a6e54SAndrei Emeltchenko 	default:
4662204a6e54SAndrei Emeltchenko 		BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
4663204a6e54SAndrei Emeltchenko 		return;
4664204a6e54SAndrei Emeltchenko 	}
4665087bfd99SGustavo Padovan 
466670f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
466770f23020SAndrei Emeltchenko 	if (!list) {
46681da177e4SLinus Torvalds 		/* Non fragmented */
46691da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
46701da177e4SLinus Torvalds 
467173d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
46721da177e4SLinus Torvalds 	} else {
46731da177e4SLinus Torvalds 		/* Fragmented */
46741da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
46751da177e4SLinus Torvalds 
46761da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
46771da177e4SLinus Torvalds 
46781da177e4SLinus Torvalds 		/* Queue all fragments atomically */
4679af3e6359SGustavo F. Padovan 		spin_lock(&queue->lock);
46801da177e4SLinus Torvalds 
468173d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
4682e702112fSAndrei Emeltchenko 
4683e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
4684e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
46851da177e4SLinus Torvalds 		do {
46861da177e4SLinus Torvalds 			skb = list; list = list->next;
46871da177e4SLinus Torvalds 
46880d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
4689e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
46901da177e4SLinus Torvalds 
46911da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
46921da177e4SLinus Torvalds 
469373d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
46941da177e4SLinus Torvalds 		} while (list);
46951da177e4SLinus Torvalds 
4696af3e6359SGustavo F. Padovan 		spin_unlock(&queue->lock);
46971da177e4SLinus Torvalds 	}
469873d80debSLuiz Augusto von Dentz }
469973d80debSLuiz Augusto von Dentz 
470073d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
470173d80debSLuiz Augusto von Dentz {
4702ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
470373d80debSLuiz Augusto von Dentz 
4704f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
470573d80debSLuiz Augusto von Dentz 
4706ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
47071da177e4SLinus Torvalds 
47083eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
47091da177e4SLinus Torvalds }
47101da177e4SLinus Torvalds 
47111da177e4SLinus Torvalds /* Send SCO data */
47120d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
47131da177e4SLinus Torvalds {
47141da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
47151da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
47161da177e4SLinus Torvalds 
47171da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
47181da177e4SLinus Torvalds 
4719aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
47201da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
47211da177e4SLinus Torvalds 
4722badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
4723badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
47249c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
47251da177e4SLinus Torvalds 
47260d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
4727c78ae283SMarcel Holtmann 
47281da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
47293eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
47301da177e4SLinus Torvalds }
47311da177e4SLinus Torvalds 
47321da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
47331da177e4SLinus Torvalds 
47341da177e4SLinus Torvalds /* HCI Connection scheduler */
47356039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
4736a8c5fb1aSGustavo Padovan 				     int *quote)
47371da177e4SLinus Torvalds {
47381da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
47398035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
4740abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
47411da177e4SLinus Torvalds 
47421da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
47431da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
4744bf4c6325SGustavo F. Padovan 
4745bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4746bf4c6325SGustavo F. Padovan 
4747bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
4748769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
47491da177e4SLinus Torvalds 			continue;
4750769be974SMarcel Holtmann 
4751769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
4752769be974SMarcel Holtmann 			continue;
4753769be974SMarcel Holtmann 
47541da177e4SLinus Torvalds 		num++;
47551da177e4SLinus Torvalds 
47561da177e4SLinus Torvalds 		if (c->sent < min) {
47571da177e4SLinus Torvalds 			min  = c->sent;
47581da177e4SLinus Torvalds 			conn = c;
47591da177e4SLinus Torvalds 		}
476052087a79SLuiz Augusto von Dentz 
476152087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
476252087a79SLuiz Augusto von Dentz 			break;
47631da177e4SLinus Torvalds 	}
47641da177e4SLinus Torvalds 
4765bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4766bf4c6325SGustavo F. Padovan 
47671da177e4SLinus Torvalds 	if (conn) {
47686ed58ec5SVille Tervo 		int cnt, q;
47696ed58ec5SVille Tervo 
47706ed58ec5SVille Tervo 		switch (conn->type) {
47716ed58ec5SVille Tervo 		case ACL_LINK:
47726ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
47736ed58ec5SVille Tervo 			break;
47746ed58ec5SVille Tervo 		case SCO_LINK:
47756ed58ec5SVille Tervo 		case ESCO_LINK:
47766ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
47776ed58ec5SVille Tervo 			break;
47786ed58ec5SVille Tervo 		case LE_LINK:
47796ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
47806ed58ec5SVille Tervo 			break;
47816ed58ec5SVille Tervo 		default:
47826ed58ec5SVille Tervo 			cnt = 0;
47836ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
47846ed58ec5SVille Tervo 		}
47856ed58ec5SVille Tervo 
47866ed58ec5SVille Tervo 		q = cnt / num;
47871da177e4SLinus Torvalds 		*quote = q ? q : 1;
47881da177e4SLinus Torvalds 	} else
47891da177e4SLinus Torvalds 		*quote = 0;
47901da177e4SLinus Torvalds 
47911da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
47921da177e4SLinus Torvalds 	return conn;
47931da177e4SLinus Torvalds }
47941da177e4SLinus Torvalds 
47956039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
47961da177e4SLinus Torvalds {
47971da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
47981da177e4SLinus Torvalds 	struct hci_conn *c;
47991da177e4SLinus Torvalds 
4800bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
48011da177e4SLinus Torvalds 
4802bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4803bf4c6325SGustavo F. Padovan 
48041da177e4SLinus Torvalds 	/* Kill stalled connections */
4805bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
4806bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
48076ed93dc6SAndrei Emeltchenko 			BT_ERR("%s killing stalled connection %pMR",
48086ed93dc6SAndrei Emeltchenko 			       hdev->name, &c->dst);
4809bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
48101da177e4SLinus Torvalds 		}
48111da177e4SLinus Torvalds 	}
4812bf4c6325SGustavo F. Padovan 
4813bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
48141da177e4SLinus Torvalds }
48151da177e4SLinus Torvalds 
48166039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
481773d80debSLuiz Augusto von Dentz 				      int *quote)
481873d80debSLuiz Augusto von Dentz {
481973d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
482073d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
4821abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
482273d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
482373d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
482473d80debSLuiz Augusto von Dentz 
482573d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
482673d80debSLuiz Augusto von Dentz 
4827bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4828bf4c6325SGustavo F. Padovan 
4829bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
483073d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
483173d80debSLuiz Augusto von Dentz 
483273d80debSLuiz Augusto von Dentz 		if (conn->type != type)
483373d80debSLuiz Augusto von Dentz 			continue;
483473d80debSLuiz Augusto von Dentz 
483573d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
483673d80debSLuiz Augusto von Dentz 			continue;
483773d80debSLuiz Augusto von Dentz 
483873d80debSLuiz Augusto von Dentz 		conn_num++;
483973d80debSLuiz Augusto von Dentz 
48408192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
484173d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
484273d80debSLuiz Augusto von Dentz 
484373d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
484473d80debSLuiz Augusto von Dentz 				continue;
484573d80debSLuiz Augusto von Dentz 
484673d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
484773d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
484873d80debSLuiz Augusto von Dentz 				continue;
484973d80debSLuiz Augusto von Dentz 
485073d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
485173d80debSLuiz Augusto von Dentz 				num = 0;
485273d80debSLuiz Augusto von Dentz 				min = ~0;
485373d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
485473d80debSLuiz Augusto von Dentz 			}
485573d80debSLuiz Augusto von Dentz 
485673d80debSLuiz Augusto von Dentz 			num++;
485773d80debSLuiz Augusto von Dentz 
485873d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
485973d80debSLuiz Augusto von Dentz 				min  = conn->sent;
486073d80debSLuiz Augusto von Dentz 				chan = tmp;
486173d80debSLuiz Augusto von Dentz 			}
486273d80debSLuiz Augusto von Dentz 		}
486373d80debSLuiz Augusto von Dentz 
486473d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
486573d80debSLuiz Augusto von Dentz 			break;
486673d80debSLuiz Augusto von Dentz 	}
486773d80debSLuiz Augusto von Dentz 
4868bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4869bf4c6325SGustavo F. Padovan 
487073d80debSLuiz Augusto von Dentz 	if (!chan)
487173d80debSLuiz Augusto von Dentz 		return NULL;
487273d80debSLuiz Augusto von Dentz 
487373d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
487473d80debSLuiz Augusto von Dentz 	case ACL_LINK:
487573d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
487673d80debSLuiz Augusto von Dentz 		break;
4877bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
4878bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
4879bd1eb66bSAndrei Emeltchenko 		break;
488073d80debSLuiz Augusto von Dentz 	case SCO_LINK:
488173d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
488273d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
488373d80debSLuiz Augusto von Dentz 		break;
488473d80debSLuiz Augusto von Dentz 	case LE_LINK:
488573d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
488673d80debSLuiz Augusto von Dentz 		break;
488773d80debSLuiz Augusto von Dentz 	default:
488873d80debSLuiz Augusto von Dentz 		cnt = 0;
488973d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
489073d80debSLuiz Augusto von Dentz 	}
489173d80debSLuiz Augusto von Dentz 
489273d80debSLuiz Augusto von Dentz 	q = cnt / num;
489373d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
489473d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
489573d80debSLuiz Augusto von Dentz 	return chan;
489673d80debSLuiz Augusto von Dentz }
489773d80debSLuiz Augusto von Dentz 
489802b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
489902b20f0bSLuiz Augusto von Dentz {
490002b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
490102b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
490202b20f0bSLuiz Augusto von Dentz 	int num = 0;
490302b20f0bSLuiz Augusto von Dentz 
490402b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
490502b20f0bSLuiz Augusto von Dentz 
4906bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4907bf4c6325SGustavo F. Padovan 
4908bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
490902b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
491002b20f0bSLuiz Augusto von Dentz 
491102b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
491202b20f0bSLuiz Augusto von Dentz 			continue;
491302b20f0bSLuiz Augusto von Dentz 
491402b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
491502b20f0bSLuiz Augusto von Dentz 			continue;
491602b20f0bSLuiz Augusto von Dentz 
491702b20f0bSLuiz Augusto von Dentz 		num++;
491802b20f0bSLuiz Augusto von Dentz 
49198192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
492002b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
492102b20f0bSLuiz Augusto von Dentz 
492202b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
492302b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
492402b20f0bSLuiz Augusto von Dentz 				continue;
492502b20f0bSLuiz Augusto von Dentz 			}
492602b20f0bSLuiz Augusto von Dentz 
492702b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
492802b20f0bSLuiz Augusto von Dentz 				continue;
492902b20f0bSLuiz Augusto von Dentz 
493002b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
493102b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
493202b20f0bSLuiz Augusto von Dentz 				continue;
493302b20f0bSLuiz Augusto von Dentz 
493402b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
493502b20f0bSLuiz Augusto von Dentz 
493602b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
493702b20f0bSLuiz Augusto von Dentz 			       skb->priority);
493802b20f0bSLuiz Augusto von Dentz 		}
493902b20f0bSLuiz Augusto von Dentz 
494002b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
494102b20f0bSLuiz Augusto von Dentz 			break;
494202b20f0bSLuiz Augusto von Dentz 	}
4943bf4c6325SGustavo F. Padovan 
4944bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4945bf4c6325SGustavo F. Padovan 
494602b20f0bSLuiz Augusto von Dentz }
494702b20f0bSLuiz Augusto von Dentz 
4948b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
4949b71d385aSAndrei Emeltchenko {
4950b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
4951b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
4952b71d385aSAndrei Emeltchenko }
4953b71d385aSAndrei Emeltchenko 
49546039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
49551da177e4SLinus Torvalds {
49564a964404SMarcel Holtmann 	if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
49571da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
49581da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
495963d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
49605f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
4961bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
49621da177e4SLinus Torvalds 	}
496363d2bc1bSAndrei Emeltchenko }
49641da177e4SLinus Torvalds 
49656039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
496663d2bc1bSAndrei Emeltchenko {
496763d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
496863d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
496963d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
497063d2bc1bSAndrei Emeltchenko 	int quote;
497163d2bc1bSAndrei Emeltchenko 
497263d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
497304837f64SMarcel Holtmann 
497473d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
497573d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
4976ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
4977ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
497873d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
497973d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
498073d80debSLuiz Augusto von Dentz 
4981ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
4982ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
4983ec1cce24SLuiz Augusto von Dentz 				break;
4984ec1cce24SLuiz Augusto von Dentz 
4985ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
4986ec1cce24SLuiz Augusto von Dentz 
498773d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
498873d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
498904837f64SMarcel Holtmann 
499057d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
49911da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
49921da177e4SLinus Torvalds 
49931da177e4SLinus Torvalds 			hdev->acl_cnt--;
499473d80debSLuiz Augusto von Dentz 			chan->sent++;
499573d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
49961da177e4SLinus Torvalds 		}
49971da177e4SLinus Torvalds 	}
499802b20f0bSLuiz Augusto von Dentz 
499902b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
500002b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
50011da177e4SLinus Torvalds }
50021da177e4SLinus Torvalds 
50036039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
5004b71d385aSAndrei Emeltchenko {
500563d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
5006b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
5007b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
5008b71d385aSAndrei Emeltchenko 	int quote;
5009bd1eb66bSAndrei Emeltchenko 	u8 type;
5010b71d385aSAndrei Emeltchenko 
501163d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
5012b71d385aSAndrei Emeltchenko 
5013bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
5014bd1eb66bSAndrei Emeltchenko 
5015bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
5016bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
5017bd1eb66bSAndrei Emeltchenko 	else
5018bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
5019bd1eb66bSAndrei Emeltchenko 
5020b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
5021bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
5022b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
5023b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
5024b71d385aSAndrei Emeltchenko 			int blocks;
5025b71d385aSAndrei Emeltchenko 
5026b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
5027b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
5028b71d385aSAndrei Emeltchenko 
5029b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
5030b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
5031b71d385aSAndrei Emeltchenko 				break;
5032b71d385aSAndrei Emeltchenko 
5033b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
5034b71d385aSAndrei Emeltchenko 
5035b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
5036b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
5037b71d385aSAndrei Emeltchenko 				return;
5038b71d385aSAndrei Emeltchenko 
5039b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
5040b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
5041b71d385aSAndrei Emeltchenko 
504257d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
5043b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
5044b71d385aSAndrei Emeltchenko 
5045b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
5046b71d385aSAndrei Emeltchenko 			quote -= blocks;
5047b71d385aSAndrei Emeltchenko 
5048b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
5049b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
5050b71d385aSAndrei Emeltchenko 		}
5051b71d385aSAndrei Emeltchenko 	}
5052b71d385aSAndrei Emeltchenko 
5053b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
5054bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
5055b71d385aSAndrei Emeltchenko }
5056b71d385aSAndrei Emeltchenko 
50576039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
5058b71d385aSAndrei Emeltchenko {
5059b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
5060b71d385aSAndrei Emeltchenko 
5061bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
5062bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR)
5063bd1eb66bSAndrei Emeltchenko 		return;
5064bd1eb66bSAndrei Emeltchenko 
5065bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
5066bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
5067b71d385aSAndrei Emeltchenko 		return;
5068b71d385aSAndrei Emeltchenko 
5069b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
5070b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
5071b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
5072b71d385aSAndrei Emeltchenko 		break;
5073b71d385aSAndrei Emeltchenko 
5074b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
5075b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
5076b71d385aSAndrei Emeltchenko 		break;
5077b71d385aSAndrei Emeltchenko 	}
5078b71d385aSAndrei Emeltchenko }
5079b71d385aSAndrei Emeltchenko 
50801da177e4SLinus Torvalds /* Schedule SCO */
50816039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev)
50821da177e4SLinus Torvalds {
50831da177e4SLinus Torvalds 	struct hci_conn *conn;
50841da177e4SLinus Torvalds 	struct sk_buff *skb;
50851da177e4SLinus Torvalds 	int quote;
50861da177e4SLinus Torvalds 
50871da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
50881da177e4SLinus Torvalds 
508952087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
509052087a79SLuiz Augusto von Dentz 		return;
509152087a79SLuiz Augusto von Dentz 
50921da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
50931da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
50941da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
509557d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
50961da177e4SLinus Torvalds 
50971da177e4SLinus Torvalds 			conn->sent++;
50981da177e4SLinus Torvalds 			if (conn->sent == ~0)
50991da177e4SLinus Torvalds 				conn->sent = 0;
51001da177e4SLinus Torvalds 		}
51011da177e4SLinus Torvalds 	}
51021da177e4SLinus Torvalds }
51031da177e4SLinus Torvalds 
51046039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev)
5105b6a0dc82SMarcel Holtmann {
5106b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
5107b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
5108b6a0dc82SMarcel Holtmann 	int quote;
5109b6a0dc82SMarcel Holtmann 
5110b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
5111b6a0dc82SMarcel Holtmann 
511252087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
511352087a79SLuiz Augusto von Dentz 		return;
511452087a79SLuiz Augusto von Dentz 
51158fc9ced3SGustavo Padovan 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
51168fc9ced3SGustavo Padovan 						     &quote))) {
5117b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
5118b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
511957d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
5120b6a0dc82SMarcel Holtmann 
5121b6a0dc82SMarcel Holtmann 			conn->sent++;
5122b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
5123b6a0dc82SMarcel Holtmann 				conn->sent = 0;
5124b6a0dc82SMarcel Holtmann 		}
5125b6a0dc82SMarcel Holtmann 	}
5126b6a0dc82SMarcel Holtmann }
5127b6a0dc82SMarcel Holtmann 
51286039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
51296ed58ec5SVille Tervo {
513073d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
51316ed58ec5SVille Tervo 	struct sk_buff *skb;
513202b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
51336ed58ec5SVille Tervo 
51346ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
51356ed58ec5SVille Tervo 
513652087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
513752087a79SLuiz Augusto von Dentz 		return;
513852087a79SLuiz Augusto von Dentz 
51394a964404SMarcel Holtmann 	if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
51406ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
51416ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
5142bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
51436ed58ec5SVille Tervo 		    time_after(jiffies, hdev->le_last_tx + HZ * 45))
5144bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
51456ed58ec5SVille Tervo 	}
51466ed58ec5SVille Tervo 
51476ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
514802b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
514973d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
5150ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
5151ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
515273d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
515373d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
51546ed58ec5SVille Tervo 
5155ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
5156ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
5157ec1cce24SLuiz Augusto von Dentz 				break;
5158ec1cce24SLuiz Augusto von Dentz 
5159ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
5160ec1cce24SLuiz Augusto von Dentz 
516157d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
51626ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
51636ed58ec5SVille Tervo 
51646ed58ec5SVille Tervo 			cnt--;
516573d80debSLuiz Augusto von Dentz 			chan->sent++;
516673d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
51676ed58ec5SVille Tervo 		}
51686ed58ec5SVille Tervo 	}
516973d80debSLuiz Augusto von Dentz 
51706ed58ec5SVille Tervo 	if (hdev->le_pkts)
51716ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
51726ed58ec5SVille Tervo 	else
51736ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
517402b20f0bSLuiz Augusto von Dentz 
517502b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
517602b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
51776ed58ec5SVille Tervo }
51786ed58ec5SVille Tervo 
51793eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
51801da177e4SLinus Torvalds {
51813eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
51821da177e4SLinus Torvalds 	struct sk_buff *skb;
51831da177e4SLinus Torvalds 
51846ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
51856ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
51861da177e4SLinus Torvalds 
518752de599eSMarcel Holtmann 	if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
51881da177e4SLinus Torvalds 		/* Schedule queues and send stuff to HCI driver */
51891da177e4SLinus Torvalds 		hci_sched_acl(hdev);
51901da177e4SLinus Torvalds 		hci_sched_sco(hdev);
5191b6a0dc82SMarcel Holtmann 		hci_sched_esco(hdev);
51926ed58ec5SVille Tervo 		hci_sched_le(hdev);
519352de599eSMarcel Holtmann 	}
51946ed58ec5SVille Tervo 
51951da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
51961da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
519757d17d70SMarcel Holtmann 		hci_send_frame(hdev, skb);
51981da177e4SLinus Torvalds }
51991da177e4SLinus Torvalds 
520025985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
52011da177e4SLinus Torvalds 
52021da177e4SLinus Torvalds /* ACL data packet */
52036039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
52041da177e4SLinus Torvalds {
52051da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
52061da177e4SLinus Torvalds 	struct hci_conn *conn;
52071da177e4SLinus Torvalds 	__u16 handle, flags;
52081da177e4SLinus Torvalds 
52091da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
52101da177e4SLinus Torvalds 
52111da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
52121da177e4SLinus Torvalds 	flags  = hci_flags(handle);
52131da177e4SLinus Torvalds 	handle = hci_handle(handle);
52141da177e4SLinus Torvalds 
5215f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
5216a8c5fb1aSGustavo Padovan 	       handle, flags);
52171da177e4SLinus Torvalds 
52181da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
52191da177e4SLinus Torvalds 
52201da177e4SLinus Torvalds 	hci_dev_lock(hdev);
52211da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
52221da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
52231da177e4SLinus Torvalds 
52241da177e4SLinus Torvalds 	if (conn) {
522565983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
522604837f64SMarcel Holtmann 
52271da177e4SLinus Torvalds 		/* Send to upper protocol */
5228686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
52291da177e4SLinus Torvalds 		return;
52301da177e4SLinus Torvalds 	} else {
52311da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
52321da177e4SLinus Torvalds 		       hdev->name, handle);
52331da177e4SLinus Torvalds 	}
52341da177e4SLinus Torvalds 
52351da177e4SLinus Torvalds 	kfree_skb(skb);
52361da177e4SLinus Torvalds }
52371da177e4SLinus Torvalds 
52381da177e4SLinus Torvalds /* SCO data packet */
52396039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
52401da177e4SLinus Torvalds {
52411da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
52421da177e4SLinus Torvalds 	struct hci_conn *conn;
52431da177e4SLinus Torvalds 	__u16 handle;
52441da177e4SLinus Torvalds 
52451da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
52461da177e4SLinus Torvalds 
52471da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
52481da177e4SLinus Torvalds 
5249f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle);
52501da177e4SLinus Torvalds 
52511da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
52521da177e4SLinus Torvalds 
52531da177e4SLinus Torvalds 	hci_dev_lock(hdev);
52541da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
52551da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
52561da177e4SLinus Torvalds 
52571da177e4SLinus Torvalds 	if (conn) {
52581da177e4SLinus Torvalds 		/* Send to upper protocol */
5259686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
52601da177e4SLinus Torvalds 		return;
52611da177e4SLinus Torvalds 	} else {
52621da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
52631da177e4SLinus Torvalds 		       hdev->name, handle);
52641da177e4SLinus Torvalds 	}
52651da177e4SLinus Torvalds 
52661da177e4SLinus Torvalds 	kfree_skb(skb);
52671da177e4SLinus Torvalds }
52681da177e4SLinus Torvalds 
52699238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
52709238f36aSJohan Hedberg {
52719238f36aSJohan Hedberg 	struct sk_buff *skb;
52729238f36aSJohan Hedberg 
52739238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
52749238f36aSJohan Hedberg 	if (!skb)
52759238f36aSJohan Hedberg 		return true;
52769238f36aSJohan Hedberg 
52779238f36aSJohan Hedberg 	return bt_cb(skb)->req.start;
52789238f36aSJohan Hedberg }
52799238f36aSJohan Hedberg 
528042c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
528142c6b129SJohan Hedberg {
528242c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
528342c6b129SJohan Hedberg 	struct sk_buff *skb;
528442c6b129SJohan Hedberg 	u16 opcode;
528542c6b129SJohan Hedberg 
528642c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
528742c6b129SJohan Hedberg 		return;
528842c6b129SJohan Hedberg 
528942c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
529042c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
529142c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
529242c6b129SJohan Hedberg 		return;
529342c6b129SJohan Hedberg 
529442c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
529542c6b129SJohan Hedberg 	if (!skb)
529642c6b129SJohan Hedberg 		return;
529742c6b129SJohan Hedberg 
529842c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
529942c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
530042c6b129SJohan Hedberg }
530142c6b129SJohan Hedberg 
53029238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status)
53039238f36aSJohan Hedberg {
53049238f36aSJohan Hedberg 	hci_req_complete_t req_complete = NULL;
53059238f36aSJohan Hedberg 	struct sk_buff *skb;
53069238f36aSJohan Hedberg 	unsigned long flags;
53079238f36aSJohan Hedberg 
53089238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
53099238f36aSJohan Hedberg 
531042c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
531142c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
53129238f36aSJohan Hedberg 	 */
531342c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
531442c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
531542c6b129SJohan Hedberg 		 * reset complete event during init and any pending
531642c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
531742c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
531842c6b129SJohan Hedberg 		 * command.
531942c6b129SJohan Hedberg 		 */
532042c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
532142c6b129SJohan Hedberg 			hci_resend_last(hdev);
532242c6b129SJohan Hedberg 
53239238f36aSJohan Hedberg 		return;
532442c6b129SJohan Hedberg 	}
53259238f36aSJohan Hedberg 
53269238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
53279238f36aSJohan Hedberg 	 * this request the request is not yet complete.
53289238f36aSJohan Hedberg 	 */
53299238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
53309238f36aSJohan Hedberg 		return;
53319238f36aSJohan Hedberg 
53329238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
53339238f36aSJohan Hedberg 	 * callback would be found in hdev->sent_cmd instead of the
53349238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
53359238f36aSJohan Hedberg 	 */
53369238f36aSJohan Hedberg 	if (hdev->sent_cmd) {
53379238f36aSJohan Hedberg 		req_complete = bt_cb(hdev->sent_cmd)->req.complete;
533853e21fbcSJohan Hedberg 
533953e21fbcSJohan Hedberg 		if (req_complete) {
534053e21fbcSJohan Hedberg 			/* We must set the complete callback to NULL to
534153e21fbcSJohan Hedberg 			 * avoid calling the callback more than once if
534253e21fbcSJohan Hedberg 			 * this function gets called again.
534353e21fbcSJohan Hedberg 			 */
534453e21fbcSJohan Hedberg 			bt_cb(hdev->sent_cmd)->req.complete = NULL;
534553e21fbcSJohan Hedberg 
53469238f36aSJohan Hedberg 			goto call_complete;
53479238f36aSJohan Hedberg 		}
534853e21fbcSJohan Hedberg 	}
53499238f36aSJohan Hedberg 
53509238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
53519238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
53529238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
53539238f36aSJohan Hedberg 		if (bt_cb(skb)->req.start) {
53549238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
53559238f36aSJohan Hedberg 			break;
53569238f36aSJohan Hedberg 		}
53579238f36aSJohan Hedberg 
53589238f36aSJohan Hedberg 		req_complete = bt_cb(skb)->req.complete;
53599238f36aSJohan Hedberg 		kfree_skb(skb);
53609238f36aSJohan Hedberg 	}
53619238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
53629238f36aSJohan Hedberg 
53639238f36aSJohan Hedberg call_complete:
53649238f36aSJohan Hedberg 	if (req_complete)
53659238f36aSJohan Hedberg 		req_complete(hdev, status);
53669238f36aSJohan Hedberg }
53679238f36aSJohan Hedberg 
5368b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
53691da177e4SLinus Torvalds {
5370b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
53711da177e4SLinus Torvalds 	struct sk_buff *skb;
53721da177e4SLinus Torvalds 
53731da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
53741da177e4SLinus Torvalds 
53751da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
5376cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
5377cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
5378cd82e61cSMarcel Holtmann 
53791da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
53801da177e4SLinus Torvalds 			/* Send copy to the sockets */
5381470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
53821da177e4SLinus Torvalds 		}
53831da177e4SLinus Torvalds 
5384fee746b0SMarcel Holtmann 		if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
53851da177e4SLinus Torvalds 			kfree_skb(skb);
53861da177e4SLinus Torvalds 			continue;
53871da177e4SLinus Torvalds 		}
53881da177e4SLinus Torvalds 
53891da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
53901da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
53910d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
53921da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
53931da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
53941da177e4SLinus Torvalds 				kfree_skb(skb);
53951da177e4SLinus Torvalds 				continue;
53963ff50b79SStephen Hemminger 			}
53971da177e4SLinus Torvalds 		}
53981da177e4SLinus Torvalds 
53991da177e4SLinus Torvalds 		/* Process frame */
54000d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
54011da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
5402b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
54031da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
54041da177e4SLinus Torvalds 			break;
54051da177e4SLinus Torvalds 
54061da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
54071da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
54081da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
54091da177e4SLinus Torvalds 			break;
54101da177e4SLinus Torvalds 
54111da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
54121da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
54131da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
54141da177e4SLinus Torvalds 			break;
54151da177e4SLinus Torvalds 
54161da177e4SLinus Torvalds 		default:
54171da177e4SLinus Torvalds 			kfree_skb(skb);
54181da177e4SLinus Torvalds 			break;
54191da177e4SLinus Torvalds 		}
54201da177e4SLinus Torvalds 	}
54211da177e4SLinus Torvalds }
54221da177e4SLinus Torvalds 
5423c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
54241da177e4SLinus Torvalds {
5425c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
54261da177e4SLinus Torvalds 	struct sk_buff *skb;
54271da177e4SLinus Torvalds 
54282104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
54292104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
54301da177e4SLinus Torvalds 
54311da177e4SLinus Torvalds 	/* Send queued commands */
54325a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
54335a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
54345a08ecceSAndrei Emeltchenko 		if (!skb)
54355a08ecceSAndrei Emeltchenko 			return;
54365a08ecceSAndrei Emeltchenko 
54371da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
54381da177e4SLinus Torvalds 
5439a675d7f1SMarcel Holtmann 		hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
544070f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
54411da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
544257d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
54437bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
544465cc2b49SMarcel Holtmann 				cancel_delayed_work(&hdev->cmd_timer);
54457bdb8a5cSSzymon Janc 			else
544665cc2b49SMarcel Holtmann 				schedule_delayed_work(&hdev->cmd_timer,
544765cc2b49SMarcel Holtmann 						      HCI_CMD_TIMEOUT);
54481da177e4SLinus Torvalds 		} else {
54491da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
5450c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
54511da177e4SLinus Torvalds 		}
54521da177e4SLinus Torvalds 	}
54531da177e4SLinus Torvalds }
5454b1efcc28SAndre Guedes 
5455b1efcc28SAndre Guedes void hci_req_add_le_scan_disable(struct hci_request *req)
5456b1efcc28SAndre Guedes {
5457b1efcc28SAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
5458b1efcc28SAndre Guedes 
5459b1efcc28SAndre Guedes 	memset(&cp, 0, sizeof(cp));
5460b1efcc28SAndre Guedes 	cp.enable = LE_SCAN_DISABLE;
5461b1efcc28SAndre Guedes 	hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
5462b1efcc28SAndre Guedes }
5463a4790dbdSAndre Guedes 
54648540f6c0SMarcel Holtmann static void add_to_white_list(struct hci_request *req,
54658540f6c0SMarcel Holtmann 			      struct hci_conn_params *params)
54668540f6c0SMarcel Holtmann {
54678540f6c0SMarcel Holtmann 	struct hci_cp_le_add_to_white_list cp;
54688540f6c0SMarcel Holtmann 
54698540f6c0SMarcel Holtmann 	cp.bdaddr_type = params->addr_type;
54708540f6c0SMarcel Holtmann 	bacpy(&cp.bdaddr, &params->addr);
54718540f6c0SMarcel Holtmann 
54728540f6c0SMarcel Holtmann 	hci_req_add(req, HCI_OP_LE_ADD_TO_WHITE_LIST, sizeof(cp), &cp);
54738540f6c0SMarcel Holtmann }
54748540f6c0SMarcel Holtmann 
54758540f6c0SMarcel Holtmann static u8 update_white_list(struct hci_request *req)
54768540f6c0SMarcel Holtmann {
54778540f6c0SMarcel Holtmann 	struct hci_dev *hdev = req->hdev;
54788540f6c0SMarcel Holtmann 	struct hci_conn_params *params;
54798540f6c0SMarcel Holtmann 	struct bdaddr_list *b;
54808540f6c0SMarcel Holtmann 	uint8_t white_list_entries = 0;
54818540f6c0SMarcel Holtmann 
54828540f6c0SMarcel Holtmann 	/* Go through the current white list programmed into the
54838540f6c0SMarcel Holtmann 	 * controller one by one and check if that address is still
54848540f6c0SMarcel Holtmann 	 * in the list of pending connections or list of devices to
54858540f6c0SMarcel Holtmann 	 * report. If not present in either list, then queue the
54868540f6c0SMarcel Holtmann 	 * command to remove it from the controller.
54878540f6c0SMarcel Holtmann 	 */
54888540f6c0SMarcel Holtmann 	list_for_each_entry(b, &hdev->le_white_list, list) {
54898540f6c0SMarcel Holtmann 		struct hci_cp_le_del_from_white_list cp;
54908540f6c0SMarcel Holtmann 
54918540f6c0SMarcel Holtmann 		if (hci_pend_le_action_lookup(&hdev->pend_le_conns,
54928540f6c0SMarcel Holtmann 					      &b->bdaddr, b->bdaddr_type) ||
54938540f6c0SMarcel Holtmann 		    hci_pend_le_action_lookup(&hdev->pend_le_reports,
54948540f6c0SMarcel Holtmann 					      &b->bdaddr, b->bdaddr_type)) {
54958540f6c0SMarcel Holtmann 			white_list_entries++;
54968540f6c0SMarcel Holtmann 			continue;
54978540f6c0SMarcel Holtmann 		}
54988540f6c0SMarcel Holtmann 
54998540f6c0SMarcel Holtmann 		cp.bdaddr_type = b->bdaddr_type;
55008540f6c0SMarcel Holtmann 		bacpy(&cp.bdaddr, &b->bdaddr);
55018540f6c0SMarcel Holtmann 
55028540f6c0SMarcel Holtmann 		hci_req_add(req, HCI_OP_LE_DEL_FROM_WHITE_LIST,
55038540f6c0SMarcel Holtmann 			    sizeof(cp), &cp);
55048540f6c0SMarcel Holtmann 	}
55058540f6c0SMarcel Holtmann 
55068540f6c0SMarcel Holtmann 	/* Since all no longer valid white list entries have been
55078540f6c0SMarcel Holtmann 	 * removed, walk through the list of pending connections
55088540f6c0SMarcel Holtmann 	 * and ensure that any new device gets programmed into
55098540f6c0SMarcel Holtmann 	 * the controller.
55108540f6c0SMarcel Holtmann 	 *
55118540f6c0SMarcel Holtmann 	 * If the list of the devices is larger than the list of
55128540f6c0SMarcel Holtmann 	 * available white list entries in the controller, then
55138540f6c0SMarcel Holtmann 	 * just abort and return filer policy value to not use the
55148540f6c0SMarcel Holtmann 	 * white list.
55158540f6c0SMarcel Holtmann 	 */
55168540f6c0SMarcel Holtmann 	list_for_each_entry(params, &hdev->pend_le_conns, action) {
55178540f6c0SMarcel Holtmann 		if (hci_bdaddr_list_lookup(&hdev->le_white_list,
55188540f6c0SMarcel Holtmann 					   &params->addr, params->addr_type))
55198540f6c0SMarcel Holtmann 			continue;
55208540f6c0SMarcel Holtmann 
55218540f6c0SMarcel Holtmann 		if (white_list_entries >= hdev->le_white_list_size) {
55228540f6c0SMarcel Holtmann 			/* Select filter policy to accept all advertising */
55238540f6c0SMarcel Holtmann 			return 0x00;
55248540f6c0SMarcel Holtmann 		}
55258540f6c0SMarcel Holtmann 
552666d8e837SMarcel Holtmann 		if (hci_find_irk_by_addr(hdev, &params->addr,
552766d8e837SMarcel Holtmann 					 params->addr_type)) {
552866d8e837SMarcel Holtmann 			/* White list can not be used with RPAs */
552966d8e837SMarcel Holtmann 			return 0x00;
553066d8e837SMarcel Holtmann 		}
553166d8e837SMarcel Holtmann 
55328540f6c0SMarcel Holtmann 		white_list_entries++;
55338540f6c0SMarcel Holtmann 		add_to_white_list(req, params);
55348540f6c0SMarcel Holtmann 	}
55358540f6c0SMarcel Holtmann 
55368540f6c0SMarcel Holtmann 	/* After adding all new pending connections, walk through
55378540f6c0SMarcel Holtmann 	 * the list of pending reports and also add these to the
55388540f6c0SMarcel Holtmann 	 * white list if there is still space.
55398540f6c0SMarcel Holtmann 	 */
55408540f6c0SMarcel Holtmann 	list_for_each_entry(params, &hdev->pend_le_reports, action) {
55418540f6c0SMarcel Holtmann 		if (hci_bdaddr_list_lookup(&hdev->le_white_list,
55428540f6c0SMarcel Holtmann 					   &params->addr, params->addr_type))
55438540f6c0SMarcel Holtmann 			continue;
55448540f6c0SMarcel Holtmann 
55458540f6c0SMarcel Holtmann 		if (white_list_entries >= hdev->le_white_list_size) {
55468540f6c0SMarcel Holtmann 			/* Select filter policy to accept all advertising */
55478540f6c0SMarcel Holtmann 			return 0x00;
55488540f6c0SMarcel Holtmann 		}
55498540f6c0SMarcel Holtmann 
555066d8e837SMarcel Holtmann 		if (hci_find_irk_by_addr(hdev, &params->addr,
555166d8e837SMarcel Holtmann 					 params->addr_type)) {
555266d8e837SMarcel Holtmann 			/* White list can not be used with RPAs */
555366d8e837SMarcel Holtmann 			return 0x00;
555466d8e837SMarcel Holtmann 		}
555566d8e837SMarcel Holtmann 
55568540f6c0SMarcel Holtmann 		white_list_entries++;
55578540f6c0SMarcel Holtmann 		add_to_white_list(req, params);
55588540f6c0SMarcel Holtmann 	}
55598540f6c0SMarcel Holtmann 
55608540f6c0SMarcel Holtmann 	/* Select filter policy to use white list */
55618540f6c0SMarcel Holtmann 	return 0x01;
55628540f6c0SMarcel Holtmann }
55638540f6c0SMarcel Holtmann 
55648ef30fd3SAndre Guedes void hci_req_add_le_passive_scan(struct hci_request *req)
55658ef30fd3SAndre Guedes {
55668ef30fd3SAndre Guedes 	struct hci_cp_le_set_scan_param param_cp;
55678ef30fd3SAndre Guedes 	struct hci_cp_le_set_scan_enable enable_cp;
55688ef30fd3SAndre Guedes 	struct hci_dev *hdev = req->hdev;
55698ef30fd3SAndre Guedes 	u8 own_addr_type;
55708540f6c0SMarcel Holtmann 	u8 filter_policy;
55718ef30fd3SAndre Guedes 
55726ab535a7SMarcel Holtmann 	/* Set require_privacy to false since no SCAN_REQ are send
55736ab535a7SMarcel Holtmann 	 * during passive scanning. Not using an unresolvable address
55746ab535a7SMarcel Holtmann 	 * here is important so that peer devices using direct
55756ab535a7SMarcel Holtmann 	 * advertising with our address will be correctly reported
55766ab535a7SMarcel Holtmann 	 * by the controller.
55778ef30fd3SAndre Guedes 	 */
55786ab535a7SMarcel Holtmann 	if (hci_update_random_address(req, false, &own_addr_type))
55798ef30fd3SAndre Guedes 		return;
55808ef30fd3SAndre Guedes 
55818540f6c0SMarcel Holtmann 	/* Adding or removing entries from the white list must
55828540f6c0SMarcel Holtmann 	 * happen before enabling scanning. The controller does
55838540f6c0SMarcel Holtmann 	 * not allow white list modification while scanning.
55848540f6c0SMarcel Holtmann 	 */
55858540f6c0SMarcel Holtmann 	filter_policy = update_white_list(req);
55868540f6c0SMarcel Holtmann 
55878ef30fd3SAndre Guedes 	memset(&param_cp, 0, sizeof(param_cp));
55888ef30fd3SAndre Guedes 	param_cp.type = LE_SCAN_PASSIVE;
55898ef30fd3SAndre Guedes 	param_cp.interval = cpu_to_le16(hdev->le_scan_interval);
55908ef30fd3SAndre Guedes 	param_cp.window = cpu_to_le16(hdev->le_scan_window);
55918ef30fd3SAndre Guedes 	param_cp.own_address_type = own_addr_type;
55928540f6c0SMarcel Holtmann 	param_cp.filter_policy = filter_policy;
55938ef30fd3SAndre Guedes 	hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp),
55948ef30fd3SAndre Guedes 		    &param_cp);
55958ef30fd3SAndre Guedes 
55968ef30fd3SAndre Guedes 	memset(&enable_cp, 0, sizeof(enable_cp));
55978ef30fd3SAndre Guedes 	enable_cp.enable = LE_SCAN_ENABLE;
55984340a124SAndre Guedes 	enable_cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
55998ef30fd3SAndre Guedes 	hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp),
56008ef30fd3SAndre Guedes 		    &enable_cp);
56018ef30fd3SAndre Guedes }
56028ef30fd3SAndre Guedes 
5603a4790dbdSAndre Guedes static void update_background_scan_complete(struct hci_dev *hdev, u8 status)
5604a4790dbdSAndre Guedes {
5605a4790dbdSAndre Guedes 	if (status)
5606a4790dbdSAndre Guedes 		BT_DBG("HCI request failed to update background scanning: "
5607a4790dbdSAndre Guedes 		       "status 0x%2.2x", status);
5608a4790dbdSAndre Guedes }
5609a4790dbdSAndre Guedes 
5610a4790dbdSAndre Guedes /* This function controls the background scanning based on hdev->pend_le_conns
5611a4790dbdSAndre Guedes  * list. If there are pending LE connection we start the background scanning,
5612a4790dbdSAndre Guedes  * otherwise we stop it.
5613a4790dbdSAndre Guedes  *
5614a4790dbdSAndre Guedes  * This function requires the caller holds hdev->lock.
5615a4790dbdSAndre Guedes  */
5616a4790dbdSAndre Guedes void hci_update_background_scan(struct hci_dev *hdev)
5617a4790dbdSAndre Guedes {
5618a4790dbdSAndre Guedes 	struct hci_request req;
5619a4790dbdSAndre Guedes 	struct hci_conn *conn;
5620a4790dbdSAndre Guedes 	int err;
5621a4790dbdSAndre Guedes 
5622c20c02d5SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags) ||
5623c20c02d5SMarcel Holtmann 	    test_bit(HCI_INIT, &hdev->flags) ||
5624c20c02d5SMarcel Holtmann 	    test_bit(HCI_SETUP, &hdev->dev_flags) ||
5625d603b76bSMarcel Holtmann 	    test_bit(HCI_CONFIG, &hdev->dev_flags) ||
5626b8221770SMarcel Holtmann 	    test_bit(HCI_AUTO_OFF, &hdev->dev_flags) ||
5627c20c02d5SMarcel Holtmann 	    test_bit(HCI_UNREGISTER, &hdev->dev_flags))
56281c1697c0SMarcel Holtmann 		return;
56291c1697c0SMarcel Holtmann 
5630a70f4b5fSJohan Hedberg 	/* No point in doing scanning if LE support hasn't been enabled */
5631a70f4b5fSJohan Hedberg 	if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags))
5632a70f4b5fSJohan Hedberg 		return;
5633a70f4b5fSJohan Hedberg 
5634ae23ada4SJohan Hedberg 	/* If discovery is active don't interfere with it */
5635ae23ada4SJohan Hedberg 	if (hdev->discovery.state != DISCOVERY_STOPPED)
5636ae23ada4SJohan Hedberg 		return;
5637ae23ada4SJohan Hedberg 
5638a4790dbdSAndre Guedes 	hci_req_init(&req, hdev);
5639a4790dbdSAndre Guedes 
5640d1d588c1SJohan Hedberg 	if (list_empty(&hdev->pend_le_conns) &&
564166f8455aSJohan Hedberg 	    list_empty(&hdev->pend_le_reports)) {
56420d2bf134SJohan Hedberg 		/* If there is no pending LE connections or devices
56430d2bf134SJohan Hedberg 		 * to be scanned for, we should stop the background
56440d2bf134SJohan Hedberg 		 * scanning.
5645a4790dbdSAndre Guedes 		 */
5646a4790dbdSAndre Guedes 
5647a4790dbdSAndre Guedes 		/* If controller is not scanning we are done. */
5648a4790dbdSAndre Guedes 		if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags))
5649a4790dbdSAndre Guedes 			return;
5650a4790dbdSAndre Guedes 
5651a4790dbdSAndre Guedes 		hci_req_add_le_scan_disable(&req);
5652a4790dbdSAndre Guedes 
5653a4790dbdSAndre Guedes 		BT_DBG("%s stopping background scanning", hdev->name);
5654a4790dbdSAndre Guedes 	} else {
5655a4790dbdSAndre Guedes 		/* If there is at least one pending LE connection, we should
5656a4790dbdSAndre Guedes 		 * keep the background scan running.
5657a4790dbdSAndre Guedes 		 */
5658a4790dbdSAndre Guedes 
5659a4790dbdSAndre Guedes 		/* If controller is connecting, we should not start scanning
5660a4790dbdSAndre Guedes 		 * since some controllers are not able to scan and connect at
5661a4790dbdSAndre Guedes 		 * the same time.
5662a4790dbdSAndre Guedes 		 */
5663a4790dbdSAndre Guedes 		conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
5664a4790dbdSAndre Guedes 		if (conn)
5665a4790dbdSAndre Guedes 			return;
5666a4790dbdSAndre Guedes 
56674340a124SAndre Guedes 		/* If controller is currently scanning, we stop it to ensure we
56684340a124SAndre Guedes 		 * don't miss any advertising (due to duplicates filter).
56694340a124SAndre Guedes 		 */
56704340a124SAndre Guedes 		if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
56714340a124SAndre Guedes 			hci_req_add_le_scan_disable(&req);
56724340a124SAndre Guedes 
56738ef30fd3SAndre Guedes 		hci_req_add_le_passive_scan(&req);
5674a4790dbdSAndre Guedes 
5675a4790dbdSAndre Guedes 		BT_DBG("%s starting background scanning", hdev->name);
5676a4790dbdSAndre Guedes 	}
5677a4790dbdSAndre Guedes 
5678a4790dbdSAndre Guedes 	err = hci_req_run(&req, update_background_scan_complete);
5679a4790dbdSAndre Guedes 	if (err)
5680a4790dbdSAndre Guedes 		BT_ERR("Failed to run HCI request: err %d", err);
5681a4790dbdSAndre Guedes }
5682432df05eSJohan Hedberg 
568322f433dcSJohan Hedberg static bool disconnected_whitelist_entries(struct hci_dev *hdev)
568422f433dcSJohan Hedberg {
568522f433dcSJohan Hedberg 	struct bdaddr_list *b;
568622f433dcSJohan Hedberg 
568722f433dcSJohan Hedberg 	list_for_each_entry(b, &hdev->whitelist, list) {
568822f433dcSJohan Hedberg 		struct hci_conn *conn;
568922f433dcSJohan Hedberg 
569022f433dcSJohan Hedberg 		conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &b->bdaddr);
569122f433dcSJohan Hedberg 		if (!conn)
569222f433dcSJohan Hedberg 			return true;
569322f433dcSJohan Hedberg 
569422f433dcSJohan Hedberg 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
569522f433dcSJohan Hedberg 			return true;
569622f433dcSJohan Hedberg 	}
569722f433dcSJohan Hedberg 
569822f433dcSJohan Hedberg 	return false;
569922f433dcSJohan Hedberg }
570022f433dcSJohan Hedberg 
5701432df05eSJohan Hedberg void hci_update_page_scan(struct hci_dev *hdev, struct hci_request *req)
5702432df05eSJohan Hedberg {
5703432df05eSJohan Hedberg 	u8 scan;
5704432df05eSJohan Hedberg 
5705432df05eSJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
5706432df05eSJohan Hedberg 		return;
5707432df05eSJohan Hedberg 
5708432df05eSJohan Hedberg 	if (!hdev_is_powered(hdev))
5709432df05eSJohan Hedberg 		return;
5710432df05eSJohan Hedberg 
5711432df05eSJohan Hedberg 	if (mgmt_powering_down(hdev))
5712432df05eSJohan Hedberg 		return;
5713432df05eSJohan Hedberg 
5714432df05eSJohan Hedberg 	if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags) ||
571522f433dcSJohan Hedberg 	    disconnected_whitelist_entries(hdev))
5716432df05eSJohan Hedberg 		scan = SCAN_PAGE;
5717432df05eSJohan Hedberg 	else
5718432df05eSJohan Hedberg 		scan = SCAN_DISABLED;
5719432df05eSJohan Hedberg 
5720432df05eSJohan Hedberg 	if (test_bit(HCI_PSCAN, &hdev->flags) == !!(scan & SCAN_PAGE))
5721432df05eSJohan Hedberg 		return;
5722432df05eSJohan Hedberg 
5723432df05eSJohan Hedberg 	if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
5724432df05eSJohan Hedberg 		scan |= SCAN_INQUIRY;
5725432df05eSJohan Hedberg 
5726432df05eSJohan Hedberg 	if (req)
5727432df05eSJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
5728432df05eSJohan Hedberg 	else
5729432df05eSJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
5730432df05eSJohan Hedberg }
5731