xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 4b71bba4)
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 
20347219839SMarcel Holtmann static int uuids_show(struct seq_file *f, void *p)
20447219839SMarcel Holtmann {
20547219839SMarcel Holtmann 	struct hci_dev *hdev = f->private;
20647219839SMarcel Holtmann 	struct bt_uuid *uuid;
20747219839SMarcel Holtmann 
20847219839SMarcel Holtmann 	hci_dev_lock(hdev);
20947219839SMarcel Holtmann 	list_for_each_entry(uuid, &hdev->uuids, list) {
21058f01aa9SMarcel Holtmann 		u8 i, val[16];
21147219839SMarcel Holtmann 
21258f01aa9SMarcel Holtmann 		/* The Bluetooth UUID values are stored in big endian,
21358f01aa9SMarcel Holtmann 		 * but with reversed byte order. So convert them into
21458f01aa9SMarcel Holtmann 		 * the right order for the %pUb modifier.
21558f01aa9SMarcel Holtmann 		 */
21658f01aa9SMarcel Holtmann 		for (i = 0; i < 16; i++)
21758f01aa9SMarcel Holtmann 			val[i] = uuid->uuid[15 - i];
21847219839SMarcel Holtmann 
21958f01aa9SMarcel Holtmann 		seq_printf(f, "%pUb\n", val);
22047219839SMarcel Holtmann 	}
22147219839SMarcel Holtmann 	hci_dev_unlock(hdev);
22247219839SMarcel Holtmann 
22347219839SMarcel Holtmann 	return 0;
22447219839SMarcel Holtmann }
22547219839SMarcel Holtmann 
22647219839SMarcel Holtmann static int uuids_open(struct inode *inode, struct file *file)
22747219839SMarcel Holtmann {
22847219839SMarcel Holtmann 	return single_open(file, uuids_show, inode->i_private);
22947219839SMarcel Holtmann }
23047219839SMarcel Holtmann 
23147219839SMarcel Holtmann static const struct file_operations uuids_fops = {
23247219839SMarcel Holtmann 	.open		= uuids_open,
23347219839SMarcel Holtmann 	.read		= seq_read,
23447219839SMarcel Holtmann 	.llseek		= seq_lseek,
23547219839SMarcel Holtmann 	.release	= single_release,
23647219839SMarcel Holtmann };
23747219839SMarcel Holtmann 
238baf27f6eSMarcel Holtmann static int inquiry_cache_show(struct seq_file *f, void *p)
239baf27f6eSMarcel Holtmann {
240baf27f6eSMarcel Holtmann 	struct hci_dev *hdev = f->private;
241baf27f6eSMarcel Holtmann 	struct discovery_state *cache = &hdev->discovery;
242baf27f6eSMarcel Holtmann 	struct inquiry_entry *e;
243baf27f6eSMarcel Holtmann 
244baf27f6eSMarcel Holtmann 	hci_dev_lock(hdev);
245baf27f6eSMarcel Holtmann 
246baf27f6eSMarcel Holtmann 	list_for_each_entry(e, &cache->all, all) {
247baf27f6eSMarcel Holtmann 		struct inquiry_data *data = &e->data;
248baf27f6eSMarcel Holtmann 		seq_printf(f, "%pMR %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n",
249baf27f6eSMarcel Holtmann 			   &data->bdaddr,
250baf27f6eSMarcel Holtmann 			   data->pscan_rep_mode, data->pscan_period_mode,
251baf27f6eSMarcel Holtmann 			   data->pscan_mode, data->dev_class[2],
252baf27f6eSMarcel Holtmann 			   data->dev_class[1], data->dev_class[0],
253baf27f6eSMarcel Holtmann 			   __le16_to_cpu(data->clock_offset),
254baf27f6eSMarcel Holtmann 			   data->rssi, data->ssp_mode, e->timestamp);
255baf27f6eSMarcel Holtmann 	}
256baf27f6eSMarcel Holtmann 
257baf27f6eSMarcel Holtmann 	hci_dev_unlock(hdev);
258baf27f6eSMarcel Holtmann 
259baf27f6eSMarcel Holtmann 	return 0;
260baf27f6eSMarcel Holtmann }
261baf27f6eSMarcel Holtmann 
262baf27f6eSMarcel Holtmann static int inquiry_cache_open(struct inode *inode, struct file *file)
263baf27f6eSMarcel Holtmann {
264baf27f6eSMarcel Holtmann 	return single_open(file, inquiry_cache_show, inode->i_private);
265baf27f6eSMarcel Holtmann }
266baf27f6eSMarcel Holtmann 
267baf27f6eSMarcel Holtmann static const struct file_operations inquiry_cache_fops = {
268baf27f6eSMarcel Holtmann 	.open		= inquiry_cache_open,
269baf27f6eSMarcel Holtmann 	.read		= seq_read,
270baf27f6eSMarcel Holtmann 	.llseek		= seq_lseek,
271baf27f6eSMarcel Holtmann 	.release	= single_release,
272baf27f6eSMarcel Holtmann };
273baf27f6eSMarcel Holtmann 
27402d08d15SMarcel Holtmann static int link_keys_show(struct seq_file *f, void *ptr)
27502d08d15SMarcel Holtmann {
27602d08d15SMarcel Holtmann 	struct hci_dev *hdev = f->private;
2770378b597SJohan Hedberg 	struct link_key *key;
27802d08d15SMarcel Holtmann 
2790378b597SJohan Hedberg 	rcu_read_lock();
2800378b597SJohan Hedberg 	list_for_each_entry_rcu(key, &hdev->link_keys, list)
28102d08d15SMarcel Holtmann 		seq_printf(f, "%pMR %u %*phN %u\n", &key->bdaddr, key->type,
28202d08d15SMarcel Holtmann 			   HCI_LINK_KEY_SIZE, key->val, key->pin_len);
2830378b597SJohan Hedberg 	rcu_read_unlock();
28402d08d15SMarcel Holtmann 
28502d08d15SMarcel Holtmann 	return 0;
28602d08d15SMarcel Holtmann }
28702d08d15SMarcel Holtmann 
28802d08d15SMarcel Holtmann static int link_keys_open(struct inode *inode, struct file *file)
28902d08d15SMarcel Holtmann {
29002d08d15SMarcel Holtmann 	return single_open(file, link_keys_show, inode->i_private);
29102d08d15SMarcel Holtmann }
29202d08d15SMarcel Holtmann 
29302d08d15SMarcel Holtmann static const struct file_operations link_keys_fops = {
29402d08d15SMarcel Holtmann 	.open		= link_keys_open,
29502d08d15SMarcel Holtmann 	.read		= seq_read,
29602d08d15SMarcel Holtmann 	.llseek		= seq_lseek,
29702d08d15SMarcel Holtmann 	.release	= single_release,
29802d08d15SMarcel Holtmann };
29902d08d15SMarcel Holtmann 
300babdbb3cSMarcel Holtmann static int dev_class_show(struct seq_file *f, void *ptr)
301babdbb3cSMarcel Holtmann {
302babdbb3cSMarcel Holtmann 	struct hci_dev *hdev = f->private;
303babdbb3cSMarcel Holtmann 
304babdbb3cSMarcel Holtmann 	hci_dev_lock(hdev);
305babdbb3cSMarcel Holtmann 	seq_printf(f, "0x%.2x%.2x%.2x\n", hdev->dev_class[2],
306babdbb3cSMarcel Holtmann 		   hdev->dev_class[1], hdev->dev_class[0]);
307babdbb3cSMarcel Holtmann 	hci_dev_unlock(hdev);
308babdbb3cSMarcel Holtmann 
309babdbb3cSMarcel Holtmann 	return 0;
310babdbb3cSMarcel Holtmann }
311babdbb3cSMarcel Holtmann 
312babdbb3cSMarcel Holtmann static int dev_class_open(struct inode *inode, struct file *file)
313babdbb3cSMarcel Holtmann {
314babdbb3cSMarcel Holtmann 	return single_open(file, dev_class_show, inode->i_private);
315babdbb3cSMarcel Holtmann }
316babdbb3cSMarcel Holtmann 
317babdbb3cSMarcel Holtmann static const struct file_operations dev_class_fops = {
318babdbb3cSMarcel Holtmann 	.open		= dev_class_open,
319babdbb3cSMarcel Holtmann 	.read		= seq_read,
320babdbb3cSMarcel Holtmann 	.llseek		= seq_lseek,
321babdbb3cSMarcel Holtmann 	.release	= single_release,
322babdbb3cSMarcel Holtmann };
323babdbb3cSMarcel Holtmann 
324041000b9SMarcel Holtmann static int voice_setting_get(void *data, u64 *val)
325041000b9SMarcel Holtmann {
326041000b9SMarcel Holtmann 	struct hci_dev *hdev = data;
327041000b9SMarcel Holtmann 
328041000b9SMarcel Holtmann 	hci_dev_lock(hdev);
329041000b9SMarcel Holtmann 	*val = hdev->voice_setting;
330041000b9SMarcel Holtmann 	hci_dev_unlock(hdev);
331041000b9SMarcel Holtmann 
332041000b9SMarcel Holtmann 	return 0;
333041000b9SMarcel Holtmann }
334041000b9SMarcel Holtmann 
335041000b9SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(voice_setting_fops, voice_setting_get,
336041000b9SMarcel Holtmann 			NULL, "0x%4.4llx\n");
337041000b9SMarcel Holtmann 
338ebd1e33bSMarcel Holtmann static int auto_accept_delay_set(void *data, u64 val)
339ebd1e33bSMarcel Holtmann {
340ebd1e33bSMarcel Holtmann 	struct hci_dev *hdev = data;
341ebd1e33bSMarcel Holtmann 
342ebd1e33bSMarcel Holtmann 	hci_dev_lock(hdev);
343ebd1e33bSMarcel Holtmann 	hdev->auto_accept_delay = val;
344ebd1e33bSMarcel Holtmann 	hci_dev_unlock(hdev);
345ebd1e33bSMarcel Holtmann 
346ebd1e33bSMarcel Holtmann 	return 0;
347ebd1e33bSMarcel Holtmann }
348ebd1e33bSMarcel Holtmann 
349ebd1e33bSMarcel Holtmann static int auto_accept_delay_get(void *data, u64 *val)
350ebd1e33bSMarcel Holtmann {
351ebd1e33bSMarcel Holtmann 	struct hci_dev *hdev = data;
352ebd1e33bSMarcel Holtmann 
353ebd1e33bSMarcel Holtmann 	hci_dev_lock(hdev);
354ebd1e33bSMarcel Holtmann 	*val = hdev->auto_accept_delay;
355ebd1e33bSMarcel Holtmann 	hci_dev_unlock(hdev);
356ebd1e33bSMarcel Holtmann 
357ebd1e33bSMarcel Holtmann 	return 0;
358ebd1e33bSMarcel Holtmann }
359ebd1e33bSMarcel Holtmann 
360ebd1e33bSMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get,
361ebd1e33bSMarcel Holtmann 			auto_accept_delay_set, "%llu\n");
362ebd1e33bSMarcel Holtmann 
3635afeac14SMarcel Holtmann static ssize_t force_sc_support_read(struct file *file, char __user *user_buf,
3645afeac14SMarcel Holtmann 				     size_t count, loff_t *ppos)
3655afeac14SMarcel Holtmann {
3665afeac14SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
3675afeac14SMarcel Holtmann 	char buf[3];
3685afeac14SMarcel Holtmann 
369111902f7SMarcel Holtmann 	buf[0] = test_bit(HCI_FORCE_SC, &hdev->dbg_flags) ? 'Y': 'N';
3705afeac14SMarcel Holtmann 	buf[1] = '\n';
3715afeac14SMarcel Holtmann 	buf[2] = '\0';
3725afeac14SMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
3735afeac14SMarcel Holtmann }
3745afeac14SMarcel Holtmann 
3755afeac14SMarcel Holtmann static ssize_t force_sc_support_write(struct file *file,
3765afeac14SMarcel Holtmann 				      const char __user *user_buf,
3775afeac14SMarcel Holtmann 				      size_t count, loff_t *ppos)
3785afeac14SMarcel Holtmann {
3795afeac14SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
3805afeac14SMarcel Holtmann 	char buf[32];
3815afeac14SMarcel Holtmann 	size_t buf_size = min(count, (sizeof(buf)-1));
3825afeac14SMarcel Holtmann 	bool enable;
3835afeac14SMarcel Holtmann 
3845afeac14SMarcel Holtmann 	if (test_bit(HCI_UP, &hdev->flags))
3855afeac14SMarcel Holtmann 		return -EBUSY;
3865afeac14SMarcel Holtmann 
3875afeac14SMarcel Holtmann 	if (copy_from_user(buf, user_buf, buf_size))
3885afeac14SMarcel Holtmann 		return -EFAULT;
3895afeac14SMarcel Holtmann 
3905afeac14SMarcel Holtmann 	buf[buf_size] = '\0';
3915afeac14SMarcel Holtmann 	if (strtobool(buf, &enable))
3925afeac14SMarcel Holtmann 		return -EINVAL;
3935afeac14SMarcel Holtmann 
394111902f7SMarcel Holtmann 	if (enable == test_bit(HCI_FORCE_SC, &hdev->dbg_flags))
3955afeac14SMarcel Holtmann 		return -EALREADY;
3965afeac14SMarcel Holtmann 
397111902f7SMarcel Holtmann 	change_bit(HCI_FORCE_SC, &hdev->dbg_flags);
3985afeac14SMarcel Holtmann 
3995afeac14SMarcel Holtmann 	return count;
4005afeac14SMarcel Holtmann }
4015afeac14SMarcel Holtmann 
4025afeac14SMarcel Holtmann static const struct file_operations force_sc_support_fops = {
4035afeac14SMarcel Holtmann 	.open		= simple_open,
4045afeac14SMarcel Holtmann 	.read		= force_sc_support_read,
4055afeac14SMarcel Holtmann 	.write		= force_sc_support_write,
4065afeac14SMarcel Holtmann 	.llseek		= default_llseek,
4075afeac14SMarcel Holtmann };
4085afeac14SMarcel Holtmann 
409858cdc78SJohan Hedberg static ssize_t force_lesc_support_read(struct file *file, char __user *user_buf,
410858cdc78SJohan Hedberg 				       size_t count, loff_t *ppos)
411858cdc78SJohan Hedberg {
412858cdc78SJohan Hedberg 	struct hci_dev *hdev = file->private_data;
413858cdc78SJohan Hedberg 	char buf[3];
414858cdc78SJohan Hedberg 
415858cdc78SJohan Hedberg 	buf[0] = test_bit(HCI_FORCE_LESC, &hdev->dbg_flags) ? 'Y': 'N';
416858cdc78SJohan Hedberg 	buf[1] = '\n';
417858cdc78SJohan Hedberg 	buf[2] = '\0';
418858cdc78SJohan Hedberg 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
419858cdc78SJohan Hedberg }
420858cdc78SJohan Hedberg 
421858cdc78SJohan Hedberg static ssize_t force_lesc_support_write(struct file *file,
422858cdc78SJohan Hedberg 					const char __user *user_buf,
423858cdc78SJohan Hedberg 					size_t count, loff_t *ppos)
424858cdc78SJohan Hedberg {
425858cdc78SJohan Hedberg 	struct hci_dev *hdev = file->private_data;
426858cdc78SJohan Hedberg 	char buf[32];
427858cdc78SJohan Hedberg 	size_t buf_size = min(count, (sizeof(buf)-1));
428858cdc78SJohan Hedberg 	bool enable;
429858cdc78SJohan Hedberg 
430858cdc78SJohan Hedberg 	if (copy_from_user(buf, user_buf, buf_size))
431858cdc78SJohan Hedberg 		return -EFAULT;
432858cdc78SJohan Hedberg 
433858cdc78SJohan Hedberg 	buf[buf_size] = '\0';
434858cdc78SJohan Hedberg 	if (strtobool(buf, &enable))
435858cdc78SJohan Hedberg 		return -EINVAL;
436858cdc78SJohan Hedberg 
437858cdc78SJohan Hedberg 	if (enable == test_bit(HCI_FORCE_LESC, &hdev->dbg_flags))
438858cdc78SJohan Hedberg 		return -EALREADY;
439858cdc78SJohan Hedberg 
440858cdc78SJohan Hedberg 	change_bit(HCI_FORCE_LESC, &hdev->dbg_flags);
441858cdc78SJohan Hedberg 
442858cdc78SJohan Hedberg 	return count;
443858cdc78SJohan Hedberg }
444858cdc78SJohan Hedberg 
445858cdc78SJohan Hedberg static const struct file_operations force_lesc_support_fops = {
446858cdc78SJohan Hedberg 	.open		= simple_open,
447858cdc78SJohan Hedberg 	.read		= force_lesc_support_read,
448858cdc78SJohan Hedberg 	.write		= force_lesc_support_write,
449858cdc78SJohan Hedberg 	.llseek		= default_llseek,
450858cdc78SJohan Hedberg };
451858cdc78SJohan Hedberg 
452134c2a89SMarcel Holtmann static ssize_t sc_only_mode_read(struct file *file, char __user *user_buf,
453134c2a89SMarcel Holtmann 				 size_t count, loff_t *ppos)
454134c2a89SMarcel Holtmann {
455134c2a89SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
456134c2a89SMarcel Holtmann 	char buf[3];
457134c2a89SMarcel Holtmann 
458134c2a89SMarcel Holtmann 	buf[0] = test_bit(HCI_SC_ONLY, &hdev->dev_flags) ? 'Y': 'N';
459134c2a89SMarcel Holtmann 	buf[1] = '\n';
460134c2a89SMarcel Holtmann 	buf[2] = '\0';
461134c2a89SMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
462134c2a89SMarcel Holtmann }
463134c2a89SMarcel Holtmann 
464134c2a89SMarcel Holtmann static const struct file_operations sc_only_mode_fops = {
465134c2a89SMarcel Holtmann 	.open		= simple_open,
466134c2a89SMarcel Holtmann 	.read		= sc_only_mode_read,
467134c2a89SMarcel Holtmann 	.llseek		= default_llseek,
468134c2a89SMarcel Holtmann };
469134c2a89SMarcel Holtmann 
4702bfa3531SMarcel Holtmann static int idle_timeout_set(void *data, u64 val)
4712bfa3531SMarcel Holtmann {
4722bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
4732bfa3531SMarcel Holtmann 
4742bfa3531SMarcel Holtmann 	if (val != 0 && (val < 500 || val > 3600000))
4752bfa3531SMarcel Holtmann 		return -EINVAL;
4762bfa3531SMarcel Holtmann 
4772bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
4782bfa3531SMarcel Holtmann 	hdev->idle_timeout = val;
4792bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
4802bfa3531SMarcel Holtmann 
4812bfa3531SMarcel Holtmann 	return 0;
4822bfa3531SMarcel Holtmann }
4832bfa3531SMarcel Holtmann 
4842bfa3531SMarcel Holtmann static int idle_timeout_get(void *data, u64 *val)
4852bfa3531SMarcel Holtmann {
4862bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
4872bfa3531SMarcel Holtmann 
4882bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
4892bfa3531SMarcel Holtmann 	*val = hdev->idle_timeout;
4902bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
4912bfa3531SMarcel Holtmann 
4922bfa3531SMarcel Holtmann 	return 0;
4932bfa3531SMarcel Holtmann }
4942bfa3531SMarcel Holtmann 
4952bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(idle_timeout_fops, idle_timeout_get,
4962bfa3531SMarcel Holtmann 			idle_timeout_set, "%llu\n");
4972bfa3531SMarcel Holtmann 
498c982b2eaSJohan Hedberg static int rpa_timeout_set(void *data, u64 val)
499c982b2eaSJohan Hedberg {
500c982b2eaSJohan Hedberg 	struct hci_dev *hdev = data;
501c982b2eaSJohan Hedberg 
502c982b2eaSJohan Hedberg 	/* Require the RPA timeout to be at least 30 seconds and at most
503c982b2eaSJohan Hedberg 	 * 24 hours.
504c982b2eaSJohan Hedberg 	 */
505c982b2eaSJohan Hedberg 	if (val < 30 || val > (60 * 60 * 24))
506c982b2eaSJohan Hedberg 		return -EINVAL;
507c982b2eaSJohan Hedberg 
508c982b2eaSJohan Hedberg 	hci_dev_lock(hdev);
509c982b2eaSJohan Hedberg 	hdev->rpa_timeout = val;
510c982b2eaSJohan Hedberg 	hci_dev_unlock(hdev);
511c982b2eaSJohan Hedberg 
512c982b2eaSJohan Hedberg 	return 0;
513c982b2eaSJohan Hedberg }
514c982b2eaSJohan Hedberg 
515c982b2eaSJohan Hedberg static int rpa_timeout_get(void *data, u64 *val)
516c982b2eaSJohan Hedberg {
517c982b2eaSJohan Hedberg 	struct hci_dev *hdev = data;
518c982b2eaSJohan Hedberg 
519c982b2eaSJohan Hedberg 	hci_dev_lock(hdev);
520c982b2eaSJohan Hedberg 	*val = hdev->rpa_timeout;
521c982b2eaSJohan Hedberg 	hci_dev_unlock(hdev);
522c982b2eaSJohan Hedberg 
523c982b2eaSJohan Hedberg 	return 0;
524c982b2eaSJohan Hedberg }
525c982b2eaSJohan Hedberg 
526c982b2eaSJohan Hedberg DEFINE_SIMPLE_ATTRIBUTE(rpa_timeout_fops, rpa_timeout_get,
527c982b2eaSJohan Hedberg 			rpa_timeout_set, "%llu\n");
528c982b2eaSJohan Hedberg 
5292bfa3531SMarcel Holtmann static int sniff_min_interval_set(void *data, u64 val)
5302bfa3531SMarcel Holtmann {
5312bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
5322bfa3531SMarcel Holtmann 
5332bfa3531SMarcel Holtmann 	if (val == 0 || val % 2 || val > hdev->sniff_max_interval)
5342bfa3531SMarcel Holtmann 		return -EINVAL;
5352bfa3531SMarcel Holtmann 
5362bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5372bfa3531SMarcel Holtmann 	hdev->sniff_min_interval = val;
5382bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5392bfa3531SMarcel Holtmann 
5402bfa3531SMarcel Holtmann 	return 0;
5412bfa3531SMarcel Holtmann }
5422bfa3531SMarcel Holtmann 
5432bfa3531SMarcel Holtmann static int sniff_min_interval_get(void *data, u64 *val)
5442bfa3531SMarcel Holtmann {
5452bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
5462bfa3531SMarcel Holtmann 
5472bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5482bfa3531SMarcel Holtmann 	*val = hdev->sniff_min_interval;
5492bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5502bfa3531SMarcel Holtmann 
5512bfa3531SMarcel Holtmann 	return 0;
5522bfa3531SMarcel Holtmann }
5532bfa3531SMarcel Holtmann 
5542bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_min_interval_fops, sniff_min_interval_get,
5552bfa3531SMarcel Holtmann 			sniff_min_interval_set, "%llu\n");
5562bfa3531SMarcel Holtmann 
5572bfa3531SMarcel Holtmann static int sniff_max_interval_set(void *data, u64 val)
5582bfa3531SMarcel Holtmann {
5592bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
5602bfa3531SMarcel Holtmann 
5612bfa3531SMarcel Holtmann 	if (val == 0 || val % 2 || val < hdev->sniff_min_interval)
5622bfa3531SMarcel Holtmann 		return -EINVAL;
5632bfa3531SMarcel Holtmann 
5642bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5652bfa3531SMarcel Holtmann 	hdev->sniff_max_interval = val;
5662bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5672bfa3531SMarcel Holtmann 
5682bfa3531SMarcel Holtmann 	return 0;
5692bfa3531SMarcel Holtmann }
5702bfa3531SMarcel Holtmann 
5712bfa3531SMarcel Holtmann static int sniff_max_interval_get(void *data, u64 *val)
5722bfa3531SMarcel Holtmann {
5732bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
5742bfa3531SMarcel Holtmann 
5752bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5762bfa3531SMarcel Holtmann 	*val = hdev->sniff_max_interval;
5772bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5782bfa3531SMarcel Holtmann 
5792bfa3531SMarcel Holtmann 	return 0;
5802bfa3531SMarcel Holtmann }
5812bfa3531SMarcel Holtmann 
5822bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_max_interval_fops, sniff_max_interval_get,
5832bfa3531SMarcel Holtmann 			sniff_max_interval_set, "%llu\n");
5842bfa3531SMarcel Holtmann 
58531ad1691SAndrzej Kaczmarek static int conn_info_min_age_set(void *data, u64 val)
58631ad1691SAndrzej Kaczmarek {
58731ad1691SAndrzej Kaczmarek 	struct hci_dev *hdev = data;
58831ad1691SAndrzej Kaczmarek 
58931ad1691SAndrzej Kaczmarek 	if (val == 0 || val > hdev->conn_info_max_age)
59031ad1691SAndrzej Kaczmarek 		return -EINVAL;
59131ad1691SAndrzej Kaczmarek 
59231ad1691SAndrzej Kaczmarek 	hci_dev_lock(hdev);
59331ad1691SAndrzej Kaczmarek 	hdev->conn_info_min_age = val;
59431ad1691SAndrzej Kaczmarek 	hci_dev_unlock(hdev);
59531ad1691SAndrzej Kaczmarek 
59631ad1691SAndrzej Kaczmarek 	return 0;
59731ad1691SAndrzej Kaczmarek }
59831ad1691SAndrzej Kaczmarek 
59931ad1691SAndrzej Kaczmarek static int conn_info_min_age_get(void *data, u64 *val)
60031ad1691SAndrzej Kaczmarek {
60131ad1691SAndrzej Kaczmarek 	struct hci_dev *hdev = data;
60231ad1691SAndrzej Kaczmarek 
60331ad1691SAndrzej Kaczmarek 	hci_dev_lock(hdev);
60431ad1691SAndrzej Kaczmarek 	*val = hdev->conn_info_min_age;
60531ad1691SAndrzej Kaczmarek 	hci_dev_unlock(hdev);
60631ad1691SAndrzej Kaczmarek 
60731ad1691SAndrzej Kaczmarek 	return 0;
60831ad1691SAndrzej Kaczmarek }
60931ad1691SAndrzej Kaczmarek 
61031ad1691SAndrzej Kaczmarek DEFINE_SIMPLE_ATTRIBUTE(conn_info_min_age_fops, conn_info_min_age_get,
61131ad1691SAndrzej Kaczmarek 			conn_info_min_age_set, "%llu\n");
61231ad1691SAndrzej Kaczmarek 
61331ad1691SAndrzej Kaczmarek static int conn_info_max_age_set(void *data, u64 val)
61431ad1691SAndrzej Kaczmarek {
61531ad1691SAndrzej Kaczmarek 	struct hci_dev *hdev = data;
61631ad1691SAndrzej Kaczmarek 
61731ad1691SAndrzej Kaczmarek 	if (val == 0 || val < hdev->conn_info_min_age)
61831ad1691SAndrzej Kaczmarek 		return -EINVAL;
61931ad1691SAndrzej Kaczmarek 
62031ad1691SAndrzej Kaczmarek 	hci_dev_lock(hdev);
62131ad1691SAndrzej Kaczmarek 	hdev->conn_info_max_age = val;
62231ad1691SAndrzej Kaczmarek 	hci_dev_unlock(hdev);
62331ad1691SAndrzej Kaczmarek 
62431ad1691SAndrzej Kaczmarek 	return 0;
62531ad1691SAndrzej Kaczmarek }
62631ad1691SAndrzej Kaczmarek 
62731ad1691SAndrzej Kaczmarek static int conn_info_max_age_get(void *data, u64 *val)
62831ad1691SAndrzej Kaczmarek {
62931ad1691SAndrzej Kaczmarek 	struct hci_dev *hdev = data;
63031ad1691SAndrzej Kaczmarek 
63131ad1691SAndrzej Kaczmarek 	hci_dev_lock(hdev);
63231ad1691SAndrzej Kaczmarek 	*val = hdev->conn_info_max_age;
63331ad1691SAndrzej Kaczmarek 	hci_dev_unlock(hdev);
63431ad1691SAndrzej Kaczmarek 
63531ad1691SAndrzej Kaczmarek 	return 0;
63631ad1691SAndrzej Kaczmarek }
63731ad1691SAndrzej Kaczmarek 
63831ad1691SAndrzej Kaczmarek DEFINE_SIMPLE_ATTRIBUTE(conn_info_max_age_fops, conn_info_max_age_get,
63931ad1691SAndrzej Kaczmarek 			conn_info_max_age_set, "%llu\n");
64031ad1691SAndrzej Kaczmarek 
641ac345813SMarcel Holtmann static int identity_show(struct seq_file *f, void *p)
642ac345813SMarcel Holtmann {
643ac345813SMarcel Holtmann 	struct hci_dev *hdev = f->private;
644a1f4c318SJohan Hedberg 	bdaddr_t addr;
645ac345813SMarcel Holtmann 	u8 addr_type;
646ac345813SMarcel Holtmann 
647ac345813SMarcel Holtmann 	hci_dev_lock(hdev);
648ac345813SMarcel Holtmann 
649a1f4c318SJohan Hedberg 	hci_copy_identity_address(hdev, &addr, &addr_type);
650ac345813SMarcel Holtmann 
651a1f4c318SJohan Hedberg 	seq_printf(f, "%pMR (type %u) %*phN %pMR\n", &addr, addr_type,
652473deef2SMarcel Holtmann 		   16, hdev->irk, &hdev->rpa);
653ac345813SMarcel Holtmann 
654ac345813SMarcel Holtmann 	hci_dev_unlock(hdev);
655ac345813SMarcel Holtmann 
656ac345813SMarcel Holtmann 	return 0;
657ac345813SMarcel Holtmann }
658ac345813SMarcel Holtmann 
659ac345813SMarcel Holtmann static int identity_open(struct inode *inode, struct file *file)
660ac345813SMarcel Holtmann {
661ac345813SMarcel Holtmann 	return single_open(file, identity_show, inode->i_private);
662ac345813SMarcel Holtmann }
663ac345813SMarcel Holtmann 
664ac345813SMarcel Holtmann static const struct file_operations identity_fops = {
665ac345813SMarcel Holtmann 	.open		= identity_open,
666ac345813SMarcel Holtmann 	.read		= seq_read,
667ac345813SMarcel Holtmann 	.llseek		= seq_lseek,
668ac345813SMarcel Holtmann 	.release	= single_release,
669ac345813SMarcel Holtmann };
670ac345813SMarcel Holtmann 
6717a4cd51dSMarcel Holtmann static int random_address_show(struct seq_file *f, void *p)
6727a4cd51dSMarcel Holtmann {
6737a4cd51dSMarcel Holtmann 	struct hci_dev *hdev = f->private;
6747a4cd51dSMarcel Holtmann 
6757a4cd51dSMarcel Holtmann 	hci_dev_lock(hdev);
6767a4cd51dSMarcel Holtmann 	seq_printf(f, "%pMR\n", &hdev->random_addr);
6777a4cd51dSMarcel Holtmann 	hci_dev_unlock(hdev);
6787a4cd51dSMarcel Holtmann 
6797a4cd51dSMarcel Holtmann 	return 0;
6807a4cd51dSMarcel Holtmann }
6817a4cd51dSMarcel Holtmann 
6827a4cd51dSMarcel Holtmann static int random_address_open(struct inode *inode, struct file *file)
6837a4cd51dSMarcel Holtmann {
6847a4cd51dSMarcel Holtmann 	return single_open(file, random_address_show, inode->i_private);
6857a4cd51dSMarcel Holtmann }
6867a4cd51dSMarcel Holtmann 
6877a4cd51dSMarcel Holtmann static const struct file_operations random_address_fops = {
6887a4cd51dSMarcel Holtmann 	.open		= random_address_open,
6897a4cd51dSMarcel Holtmann 	.read		= seq_read,
6907a4cd51dSMarcel Holtmann 	.llseek		= seq_lseek,
6917a4cd51dSMarcel Holtmann 	.release	= single_release,
6927a4cd51dSMarcel Holtmann };
6937a4cd51dSMarcel Holtmann 
694e7b8fc92SMarcel Holtmann static int static_address_show(struct seq_file *f, void *p)
695e7b8fc92SMarcel Holtmann {
696e7b8fc92SMarcel Holtmann 	struct hci_dev *hdev = f->private;
697e7b8fc92SMarcel Holtmann 
698e7b8fc92SMarcel Holtmann 	hci_dev_lock(hdev);
699e7b8fc92SMarcel Holtmann 	seq_printf(f, "%pMR\n", &hdev->static_addr);
700e7b8fc92SMarcel Holtmann 	hci_dev_unlock(hdev);
701e7b8fc92SMarcel Holtmann 
702e7b8fc92SMarcel Holtmann 	return 0;
703e7b8fc92SMarcel Holtmann }
704e7b8fc92SMarcel Holtmann 
705e7b8fc92SMarcel Holtmann static int static_address_open(struct inode *inode, struct file *file)
706e7b8fc92SMarcel Holtmann {
707e7b8fc92SMarcel Holtmann 	return single_open(file, static_address_show, inode->i_private);
708e7b8fc92SMarcel Holtmann }
709e7b8fc92SMarcel Holtmann 
710e7b8fc92SMarcel Holtmann static const struct file_operations static_address_fops = {
711e7b8fc92SMarcel Holtmann 	.open		= static_address_open,
712e7b8fc92SMarcel Holtmann 	.read		= seq_read,
713e7b8fc92SMarcel Holtmann 	.llseek		= seq_lseek,
714e7b8fc92SMarcel Holtmann 	.release	= single_release,
715e7b8fc92SMarcel Holtmann };
716e7b8fc92SMarcel Holtmann 
717b32bba6cSMarcel Holtmann static ssize_t force_static_address_read(struct file *file,
718b32bba6cSMarcel Holtmann 					 char __user *user_buf,
719b32bba6cSMarcel Holtmann 					 size_t count, loff_t *ppos)
72092202185SMarcel Holtmann {
721b32bba6cSMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
722b32bba6cSMarcel Holtmann 	char buf[3];
72392202185SMarcel Holtmann 
724111902f7SMarcel Holtmann 	buf[0] = test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) ? 'Y': 'N';
725b32bba6cSMarcel Holtmann 	buf[1] = '\n';
726b32bba6cSMarcel Holtmann 	buf[2] = '\0';
727b32bba6cSMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
728b32bba6cSMarcel Holtmann }
729b32bba6cSMarcel Holtmann 
730b32bba6cSMarcel Holtmann static ssize_t force_static_address_write(struct file *file,
731b32bba6cSMarcel Holtmann 					  const char __user *user_buf,
732b32bba6cSMarcel Holtmann 					  size_t count, loff_t *ppos)
733b32bba6cSMarcel Holtmann {
734b32bba6cSMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
735b32bba6cSMarcel Holtmann 	char buf[32];
736b32bba6cSMarcel Holtmann 	size_t buf_size = min(count, (sizeof(buf)-1));
737b32bba6cSMarcel Holtmann 	bool enable;
738b32bba6cSMarcel Holtmann 
739b32bba6cSMarcel Holtmann 	if (test_bit(HCI_UP, &hdev->flags))
740b32bba6cSMarcel Holtmann 		return -EBUSY;
741b32bba6cSMarcel Holtmann 
742b32bba6cSMarcel Holtmann 	if (copy_from_user(buf, user_buf, buf_size))
743b32bba6cSMarcel Holtmann 		return -EFAULT;
744b32bba6cSMarcel Holtmann 
745b32bba6cSMarcel Holtmann 	buf[buf_size] = '\0';
746b32bba6cSMarcel Holtmann 	if (strtobool(buf, &enable))
74792202185SMarcel Holtmann 		return -EINVAL;
74892202185SMarcel Holtmann 
749111902f7SMarcel Holtmann 	if (enable == test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags))
750b32bba6cSMarcel Holtmann 		return -EALREADY;
75192202185SMarcel Holtmann 
752111902f7SMarcel Holtmann 	change_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags);
753b32bba6cSMarcel Holtmann 
754b32bba6cSMarcel Holtmann 	return count;
75592202185SMarcel Holtmann }
75692202185SMarcel Holtmann 
757b32bba6cSMarcel Holtmann static const struct file_operations force_static_address_fops = {
758b32bba6cSMarcel Holtmann 	.open		= simple_open,
759b32bba6cSMarcel Holtmann 	.read		= force_static_address_read,
760b32bba6cSMarcel Holtmann 	.write		= force_static_address_write,
761b32bba6cSMarcel Holtmann 	.llseek		= default_llseek,
762b32bba6cSMarcel Holtmann };
76392202185SMarcel Holtmann 
764d2ab0ac1SMarcel Holtmann static int white_list_show(struct seq_file *f, void *ptr)
765d2ab0ac1SMarcel Holtmann {
766d2ab0ac1SMarcel Holtmann 	struct hci_dev *hdev = f->private;
767d2ab0ac1SMarcel Holtmann 	struct bdaddr_list *b;
768d2ab0ac1SMarcel Holtmann 
769d2ab0ac1SMarcel Holtmann 	hci_dev_lock(hdev);
770d2ab0ac1SMarcel Holtmann 	list_for_each_entry(b, &hdev->le_white_list, list)
771d2ab0ac1SMarcel Holtmann 		seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type);
772d2ab0ac1SMarcel Holtmann 	hci_dev_unlock(hdev);
773d2ab0ac1SMarcel Holtmann 
774d2ab0ac1SMarcel Holtmann 	return 0;
775d2ab0ac1SMarcel Holtmann }
776d2ab0ac1SMarcel Holtmann 
777d2ab0ac1SMarcel Holtmann static int white_list_open(struct inode *inode, struct file *file)
778d2ab0ac1SMarcel Holtmann {
779d2ab0ac1SMarcel Holtmann 	return single_open(file, white_list_show, inode->i_private);
780d2ab0ac1SMarcel Holtmann }
781d2ab0ac1SMarcel Holtmann 
782d2ab0ac1SMarcel Holtmann static const struct file_operations white_list_fops = {
783d2ab0ac1SMarcel Holtmann 	.open		= white_list_open,
784d2ab0ac1SMarcel Holtmann 	.read		= seq_read,
785d2ab0ac1SMarcel Holtmann 	.llseek		= seq_lseek,
786d2ab0ac1SMarcel Holtmann 	.release	= single_release,
787d2ab0ac1SMarcel Holtmann };
788d2ab0ac1SMarcel Holtmann 
7893698d704SMarcel Holtmann static int identity_resolving_keys_show(struct seq_file *f, void *ptr)
7903698d704SMarcel Holtmann {
7913698d704SMarcel Holtmann 	struct hci_dev *hdev = f->private;
792adae20cbSJohan Hedberg 	struct smp_irk *irk;
7933698d704SMarcel Holtmann 
794adae20cbSJohan Hedberg 	rcu_read_lock();
795adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
7963698d704SMarcel Holtmann 		seq_printf(f, "%pMR (type %u) %*phN %pMR\n",
7973698d704SMarcel Holtmann 			   &irk->bdaddr, irk->addr_type,
7983698d704SMarcel Holtmann 			   16, irk->val, &irk->rpa);
7993698d704SMarcel Holtmann 	}
800adae20cbSJohan Hedberg 	rcu_read_unlock();
8013698d704SMarcel Holtmann 
8023698d704SMarcel Holtmann 	return 0;
8033698d704SMarcel Holtmann }
8043698d704SMarcel Holtmann 
8053698d704SMarcel Holtmann static int identity_resolving_keys_open(struct inode *inode, struct file *file)
8063698d704SMarcel Holtmann {
8073698d704SMarcel Holtmann 	return single_open(file, identity_resolving_keys_show,
8083698d704SMarcel Holtmann 			   inode->i_private);
8093698d704SMarcel Holtmann }
8103698d704SMarcel Holtmann 
8113698d704SMarcel Holtmann static const struct file_operations identity_resolving_keys_fops = {
8123698d704SMarcel Holtmann 	.open		= identity_resolving_keys_open,
8133698d704SMarcel Holtmann 	.read		= seq_read,
8143698d704SMarcel Holtmann 	.llseek		= seq_lseek,
8153698d704SMarcel Holtmann 	.release	= single_release,
8163698d704SMarcel Holtmann };
8173698d704SMarcel Holtmann 
8188f8625cdSMarcel Holtmann static int long_term_keys_show(struct seq_file *f, void *ptr)
8198f8625cdSMarcel Holtmann {
8208f8625cdSMarcel Holtmann 	struct hci_dev *hdev = f->private;
821970d0f1bSJohan Hedberg 	struct smp_ltk *ltk;
8228f8625cdSMarcel Holtmann 
823970d0f1bSJohan Hedberg 	rcu_read_lock();
824970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(ltk, &hdev->long_term_keys, list)
825fe39c7b2SMarcel Holtmann 		seq_printf(f, "%pMR (type %u) %u 0x%02x %u %.4x %.16llx %*phN\n",
8268f8625cdSMarcel Holtmann 			   &ltk->bdaddr, ltk->bdaddr_type, ltk->authenticated,
8278f8625cdSMarcel Holtmann 			   ltk->type, ltk->enc_size, __le16_to_cpu(ltk->ediv),
828fe39c7b2SMarcel Holtmann 			   __le64_to_cpu(ltk->rand), 16, ltk->val);
829970d0f1bSJohan Hedberg 	rcu_read_unlock();
8308f8625cdSMarcel Holtmann 
8318f8625cdSMarcel Holtmann 	return 0;
8328f8625cdSMarcel Holtmann }
8338f8625cdSMarcel Holtmann 
8348f8625cdSMarcel Holtmann static int long_term_keys_open(struct inode *inode, struct file *file)
8358f8625cdSMarcel Holtmann {
8368f8625cdSMarcel Holtmann 	return single_open(file, long_term_keys_show, inode->i_private);
8378f8625cdSMarcel Holtmann }
8388f8625cdSMarcel Holtmann 
8398f8625cdSMarcel Holtmann static const struct file_operations long_term_keys_fops = {
8408f8625cdSMarcel Holtmann 	.open		= long_term_keys_open,
8418f8625cdSMarcel Holtmann 	.read		= seq_read,
8428f8625cdSMarcel Holtmann 	.llseek		= seq_lseek,
8438f8625cdSMarcel Holtmann 	.release	= single_release,
8448f8625cdSMarcel Holtmann };
8458f8625cdSMarcel Holtmann 
8464e70c7e7SMarcel Holtmann static int conn_min_interval_set(void *data, u64 val)
8474e70c7e7SMarcel Holtmann {
8484e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
8494e70c7e7SMarcel Holtmann 
8504e70c7e7SMarcel Holtmann 	if (val < 0x0006 || val > 0x0c80 || val > hdev->le_conn_max_interval)
8514e70c7e7SMarcel Holtmann 		return -EINVAL;
8524e70c7e7SMarcel Holtmann 
8534e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
8544e70c7e7SMarcel Holtmann 	hdev->le_conn_min_interval = val;
8554e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
8564e70c7e7SMarcel Holtmann 
8574e70c7e7SMarcel Holtmann 	return 0;
8584e70c7e7SMarcel Holtmann }
8594e70c7e7SMarcel Holtmann 
8604e70c7e7SMarcel Holtmann static int conn_min_interval_get(void *data, u64 *val)
8614e70c7e7SMarcel Holtmann {
8624e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
8634e70c7e7SMarcel Holtmann 
8644e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
8654e70c7e7SMarcel Holtmann 	*val = hdev->le_conn_min_interval;
8664e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
8674e70c7e7SMarcel Holtmann 
8684e70c7e7SMarcel Holtmann 	return 0;
8694e70c7e7SMarcel Holtmann }
8704e70c7e7SMarcel Holtmann 
8714e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_min_interval_fops, conn_min_interval_get,
8724e70c7e7SMarcel Holtmann 			conn_min_interval_set, "%llu\n");
8734e70c7e7SMarcel Holtmann 
8744e70c7e7SMarcel Holtmann static int conn_max_interval_set(void *data, u64 val)
8754e70c7e7SMarcel Holtmann {
8764e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
8774e70c7e7SMarcel Holtmann 
8784e70c7e7SMarcel Holtmann 	if (val < 0x0006 || val > 0x0c80 || val < hdev->le_conn_min_interval)
8794e70c7e7SMarcel Holtmann 		return -EINVAL;
8804e70c7e7SMarcel Holtmann 
8814e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
8824e70c7e7SMarcel Holtmann 	hdev->le_conn_max_interval = val;
8834e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
8844e70c7e7SMarcel Holtmann 
8854e70c7e7SMarcel Holtmann 	return 0;
8864e70c7e7SMarcel Holtmann }
8874e70c7e7SMarcel Holtmann 
8884e70c7e7SMarcel Holtmann static int conn_max_interval_get(void *data, u64 *val)
8894e70c7e7SMarcel Holtmann {
8904e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
8914e70c7e7SMarcel Holtmann 
8924e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
8934e70c7e7SMarcel Holtmann 	*val = hdev->le_conn_max_interval;
8944e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
8954e70c7e7SMarcel Holtmann 
8964e70c7e7SMarcel Holtmann 	return 0;
8974e70c7e7SMarcel Holtmann }
8984e70c7e7SMarcel Holtmann 
8994e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get,
9004e70c7e7SMarcel Holtmann 			conn_max_interval_set, "%llu\n");
9014e70c7e7SMarcel Holtmann 
902816a93d1SMarcel Holtmann static int conn_latency_set(void *data, u64 val)
903816a93d1SMarcel Holtmann {
904816a93d1SMarcel Holtmann 	struct hci_dev *hdev = data;
905816a93d1SMarcel Holtmann 
906816a93d1SMarcel Holtmann 	if (val > 0x01f3)
907816a93d1SMarcel Holtmann 		return -EINVAL;
908816a93d1SMarcel Holtmann 
909816a93d1SMarcel Holtmann 	hci_dev_lock(hdev);
910816a93d1SMarcel Holtmann 	hdev->le_conn_latency = val;
911816a93d1SMarcel Holtmann 	hci_dev_unlock(hdev);
912816a93d1SMarcel Holtmann 
913816a93d1SMarcel Holtmann 	return 0;
914816a93d1SMarcel Holtmann }
915816a93d1SMarcel Holtmann 
916816a93d1SMarcel Holtmann static int conn_latency_get(void *data, u64 *val)
917816a93d1SMarcel Holtmann {
918816a93d1SMarcel Holtmann 	struct hci_dev *hdev = data;
919816a93d1SMarcel Holtmann 
920816a93d1SMarcel Holtmann 	hci_dev_lock(hdev);
921816a93d1SMarcel Holtmann 	*val = hdev->le_conn_latency;
922816a93d1SMarcel Holtmann 	hci_dev_unlock(hdev);
923816a93d1SMarcel Holtmann 
924816a93d1SMarcel Holtmann 	return 0;
925816a93d1SMarcel Holtmann }
926816a93d1SMarcel Holtmann 
927816a93d1SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_latency_fops, conn_latency_get,
928816a93d1SMarcel Holtmann 			conn_latency_set, "%llu\n");
929816a93d1SMarcel Holtmann 
930f1649577SMarcel Holtmann static int supervision_timeout_set(void *data, u64 val)
931f1649577SMarcel Holtmann {
932f1649577SMarcel Holtmann 	struct hci_dev *hdev = data;
933f1649577SMarcel Holtmann 
934f1649577SMarcel Holtmann 	if (val < 0x000a || val > 0x0c80)
935f1649577SMarcel Holtmann 		return -EINVAL;
936f1649577SMarcel Holtmann 
937f1649577SMarcel Holtmann 	hci_dev_lock(hdev);
938f1649577SMarcel Holtmann 	hdev->le_supv_timeout = val;
939f1649577SMarcel Holtmann 	hci_dev_unlock(hdev);
940f1649577SMarcel Holtmann 
941f1649577SMarcel Holtmann 	return 0;
942f1649577SMarcel Holtmann }
943f1649577SMarcel Holtmann 
944f1649577SMarcel Holtmann static int supervision_timeout_get(void *data, u64 *val)
945f1649577SMarcel Holtmann {
946f1649577SMarcel Holtmann 	struct hci_dev *hdev = data;
947f1649577SMarcel Holtmann 
948f1649577SMarcel Holtmann 	hci_dev_lock(hdev);
949f1649577SMarcel Holtmann 	*val = hdev->le_supv_timeout;
950f1649577SMarcel Holtmann 	hci_dev_unlock(hdev);
951f1649577SMarcel Holtmann 
952f1649577SMarcel Holtmann 	return 0;
953f1649577SMarcel Holtmann }
954f1649577SMarcel Holtmann 
955f1649577SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(supervision_timeout_fops, supervision_timeout_get,
956f1649577SMarcel Holtmann 			supervision_timeout_set, "%llu\n");
957f1649577SMarcel Holtmann 
9583f959d46SMarcel Holtmann static int adv_channel_map_set(void *data, u64 val)
9593f959d46SMarcel Holtmann {
9603f959d46SMarcel Holtmann 	struct hci_dev *hdev = data;
9613f959d46SMarcel Holtmann 
9623f959d46SMarcel Holtmann 	if (val < 0x01 || val > 0x07)
9633f959d46SMarcel Holtmann 		return -EINVAL;
9643f959d46SMarcel Holtmann 
9653f959d46SMarcel Holtmann 	hci_dev_lock(hdev);
9663f959d46SMarcel Holtmann 	hdev->le_adv_channel_map = val;
9673f959d46SMarcel Holtmann 	hci_dev_unlock(hdev);
9683f959d46SMarcel Holtmann 
9693f959d46SMarcel Holtmann 	return 0;
9703f959d46SMarcel Holtmann }
9713f959d46SMarcel Holtmann 
9723f959d46SMarcel Holtmann static int adv_channel_map_get(void *data, u64 *val)
9733f959d46SMarcel Holtmann {
9743f959d46SMarcel Holtmann 	struct hci_dev *hdev = data;
9753f959d46SMarcel Holtmann 
9763f959d46SMarcel Holtmann 	hci_dev_lock(hdev);
9773f959d46SMarcel Holtmann 	*val = hdev->le_adv_channel_map;
9783f959d46SMarcel Holtmann 	hci_dev_unlock(hdev);
9793f959d46SMarcel Holtmann 
9803f959d46SMarcel Holtmann 	return 0;
9813f959d46SMarcel Holtmann }
9823f959d46SMarcel Holtmann 
9833f959d46SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(adv_channel_map_fops, adv_channel_map_get,
9843f959d46SMarcel Holtmann 			adv_channel_map_set, "%llu\n");
9853f959d46SMarcel Holtmann 
986729a1051SGeorg Lukas static int adv_min_interval_set(void *data, u64 val)
98789863109SJukka Rissanen {
988729a1051SGeorg Lukas 	struct hci_dev *hdev = data;
98989863109SJukka Rissanen 
990729a1051SGeorg Lukas 	if (val < 0x0020 || val > 0x4000 || val > hdev->le_adv_max_interval)
99189863109SJukka Rissanen 		return -EINVAL;
99289863109SJukka Rissanen 
9937d474e06SAndre Guedes 	hci_dev_lock(hdev);
994729a1051SGeorg Lukas 	hdev->le_adv_min_interval = val;
9957d474e06SAndre Guedes 	hci_dev_unlock(hdev);
9967d474e06SAndre Guedes 
9977d474e06SAndre Guedes 	return 0;
9987d474e06SAndre Guedes }
9997d474e06SAndre Guedes 
1000729a1051SGeorg Lukas static int adv_min_interval_get(void *data, u64 *val)
10017d474e06SAndre Guedes {
1002729a1051SGeorg Lukas 	struct hci_dev *hdev = data;
1003729a1051SGeorg Lukas 
1004729a1051SGeorg Lukas 	hci_dev_lock(hdev);
1005729a1051SGeorg Lukas 	*val = hdev->le_adv_min_interval;
1006729a1051SGeorg Lukas 	hci_dev_unlock(hdev);
1007729a1051SGeorg Lukas 
1008729a1051SGeorg Lukas 	return 0;
10097d474e06SAndre Guedes }
10107d474e06SAndre Guedes 
1011729a1051SGeorg Lukas DEFINE_SIMPLE_ATTRIBUTE(adv_min_interval_fops, adv_min_interval_get,
1012729a1051SGeorg Lukas 			adv_min_interval_set, "%llu\n");
10137d474e06SAndre Guedes 
1014729a1051SGeorg Lukas static int adv_max_interval_set(void *data, u64 val)
1015729a1051SGeorg Lukas {
1016729a1051SGeorg Lukas 	struct hci_dev *hdev = data;
1017729a1051SGeorg Lukas 
1018729a1051SGeorg Lukas 	if (val < 0x0020 || val > 0x4000 || val < hdev->le_adv_min_interval)
10197d474e06SAndre Guedes 		return -EINVAL;
10207d474e06SAndre Guedes 
10217d474e06SAndre Guedes 	hci_dev_lock(hdev);
1022729a1051SGeorg Lukas 	hdev->le_adv_max_interval = val;
10237d474e06SAndre Guedes 	hci_dev_unlock(hdev);
10247d474e06SAndre Guedes 
1025729a1051SGeorg Lukas 	return 0;
10267d474e06SAndre Guedes }
10277d474e06SAndre Guedes 
1028729a1051SGeorg Lukas static int adv_max_interval_get(void *data, u64 *val)
1029729a1051SGeorg Lukas {
1030729a1051SGeorg Lukas 	struct hci_dev *hdev = data;
1031729a1051SGeorg Lukas 
10327d474e06SAndre Guedes 	hci_dev_lock(hdev);
1033729a1051SGeorg Lukas 	*val = hdev->le_adv_max_interval;
10347d474e06SAndre Guedes 	hci_dev_unlock(hdev);
1035729a1051SGeorg Lukas 
1036729a1051SGeorg Lukas 	return 0;
1037729a1051SGeorg Lukas }
1038729a1051SGeorg Lukas 
1039729a1051SGeorg Lukas DEFINE_SIMPLE_ATTRIBUTE(adv_max_interval_fops, adv_max_interval_get,
1040729a1051SGeorg Lukas 			adv_max_interval_set, "%llu\n");
1041729a1051SGeorg Lukas 
10420b3c7d37SMarcel Holtmann static int device_list_show(struct seq_file *f, void *ptr)
10437d474e06SAndre Guedes {
10440b3c7d37SMarcel Holtmann 	struct hci_dev *hdev = f->private;
10457d474e06SAndre Guedes 	struct hci_conn_params *p;
104640f4938aSMarcel Holtmann 	struct bdaddr_list *b;
10477d474e06SAndre Guedes 
10487d474e06SAndre Guedes 	hci_dev_lock(hdev);
104940f4938aSMarcel Holtmann 	list_for_each_entry(b, &hdev->whitelist, list)
105040f4938aSMarcel Holtmann 		seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type);
10517d474e06SAndre Guedes 	list_for_each_entry(p, &hdev->le_conn_params, list) {
105240f4938aSMarcel Holtmann 		seq_printf(f, "%pMR (type %u) %u\n", &p->addr, p->addr_type,
10537d474e06SAndre Guedes 			   p->auto_connect);
10547d474e06SAndre Guedes 	}
10557d474e06SAndre Guedes 	hci_dev_unlock(hdev);
10567d474e06SAndre Guedes 
10577d474e06SAndre Guedes 	return 0;
10587d474e06SAndre Guedes }
10597d474e06SAndre Guedes 
10600b3c7d37SMarcel Holtmann static int device_list_open(struct inode *inode, struct file *file)
10617d474e06SAndre Guedes {
10620b3c7d37SMarcel Holtmann 	return single_open(file, device_list_show, inode->i_private);
10637d474e06SAndre Guedes }
10647d474e06SAndre Guedes 
10650b3c7d37SMarcel Holtmann static const struct file_operations device_list_fops = {
10660b3c7d37SMarcel Holtmann 	.open		= device_list_open,
10677d474e06SAndre Guedes 	.read		= seq_read,
10687d474e06SAndre Guedes 	.llseek		= seq_lseek,
10697d474e06SAndre Guedes 	.release	= single_release,
10707d474e06SAndre Guedes };
10717d474e06SAndre Guedes 
10721da177e4SLinus Torvalds /* ---- HCI requests ---- */
10731da177e4SLinus Torvalds 
107442c6b129SJohan Hedberg static void hci_req_sync_complete(struct hci_dev *hdev, u8 result)
10751da177e4SLinus Torvalds {
107642c6b129SJohan Hedberg 	BT_DBG("%s result 0x%2.2x", hdev->name, result);
107775fb0e32SJohan Hedberg 
10781da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
10791da177e4SLinus Torvalds 		hdev->req_result = result;
10801da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_DONE;
10811da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
10821da177e4SLinus Torvalds 	}
10831da177e4SLinus Torvalds }
10841da177e4SLinus Torvalds 
10851da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err)
10861da177e4SLinus Torvalds {
10871da177e4SLinus Torvalds 	BT_DBG("%s err 0x%2.2x", hdev->name, err);
10881da177e4SLinus Torvalds 
10891da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
10901da177e4SLinus Torvalds 		hdev->req_result = err;
10911da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_CANCELED;
10921da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
10931da177e4SLinus Torvalds 	}
10941da177e4SLinus Torvalds }
10951da177e4SLinus Torvalds 
109677a63e0aSFengguang Wu static struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode,
109777a63e0aSFengguang Wu 					    u8 event)
109875e84b7cSJohan Hedberg {
109975e84b7cSJohan Hedberg 	struct hci_ev_cmd_complete *ev;
110075e84b7cSJohan Hedberg 	struct hci_event_hdr *hdr;
110175e84b7cSJohan Hedberg 	struct sk_buff *skb;
110275e84b7cSJohan Hedberg 
110375e84b7cSJohan Hedberg 	hci_dev_lock(hdev);
110475e84b7cSJohan Hedberg 
110575e84b7cSJohan Hedberg 	skb = hdev->recv_evt;
110675e84b7cSJohan Hedberg 	hdev->recv_evt = NULL;
110775e84b7cSJohan Hedberg 
110875e84b7cSJohan Hedberg 	hci_dev_unlock(hdev);
110975e84b7cSJohan Hedberg 
111075e84b7cSJohan Hedberg 	if (!skb)
111175e84b7cSJohan Hedberg 		return ERR_PTR(-ENODATA);
111275e84b7cSJohan Hedberg 
111375e84b7cSJohan Hedberg 	if (skb->len < sizeof(*hdr)) {
111475e84b7cSJohan Hedberg 		BT_ERR("Too short HCI event");
111575e84b7cSJohan Hedberg 		goto failed;
111675e84b7cSJohan Hedberg 	}
111775e84b7cSJohan Hedberg 
111875e84b7cSJohan Hedberg 	hdr = (void *) skb->data;
111975e84b7cSJohan Hedberg 	skb_pull(skb, HCI_EVENT_HDR_SIZE);
112075e84b7cSJohan Hedberg 
11217b1abbbeSJohan Hedberg 	if (event) {
11227b1abbbeSJohan Hedberg 		if (hdr->evt != event)
11237b1abbbeSJohan Hedberg 			goto failed;
11247b1abbbeSJohan Hedberg 		return skb;
11257b1abbbeSJohan Hedberg 	}
11267b1abbbeSJohan Hedberg 
112775e84b7cSJohan Hedberg 	if (hdr->evt != HCI_EV_CMD_COMPLETE) {
112875e84b7cSJohan Hedberg 		BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt);
112975e84b7cSJohan Hedberg 		goto failed;
113075e84b7cSJohan Hedberg 	}
113175e84b7cSJohan Hedberg 
113275e84b7cSJohan Hedberg 	if (skb->len < sizeof(*ev)) {
113375e84b7cSJohan Hedberg 		BT_ERR("Too short cmd_complete event");
113475e84b7cSJohan Hedberg 		goto failed;
113575e84b7cSJohan Hedberg 	}
113675e84b7cSJohan Hedberg 
113775e84b7cSJohan Hedberg 	ev = (void *) skb->data;
113875e84b7cSJohan Hedberg 	skb_pull(skb, sizeof(*ev));
113975e84b7cSJohan Hedberg 
114075e84b7cSJohan Hedberg 	if (opcode == __le16_to_cpu(ev->opcode))
114175e84b7cSJohan Hedberg 		return skb;
114275e84b7cSJohan Hedberg 
114375e84b7cSJohan Hedberg 	BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode,
114475e84b7cSJohan Hedberg 	       __le16_to_cpu(ev->opcode));
114575e84b7cSJohan Hedberg 
114675e84b7cSJohan Hedberg failed:
114775e84b7cSJohan Hedberg 	kfree_skb(skb);
114875e84b7cSJohan Hedberg 	return ERR_PTR(-ENODATA);
114975e84b7cSJohan Hedberg }
115075e84b7cSJohan Hedberg 
11517b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
115207dc93ddSJohan Hedberg 				  const void *param, u8 event, u32 timeout)
115375e84b7cSJohan Hedberg {
115475e84b7cSJohan Hedberg 	DECLARE_WAITQUEUE(wait, current);
115575e84b7cSJohan Hedberg 	struct hci_request req;
115675e84b7cSJohan Hedberg 	int err = 0;
115775e84b7cSJohan Hedberg 
115875e84b7cSJohan Hedberg 	BT_DBG("%s", hdev->name);
115975e84b7cSJohan Hedberg 
116075e84b7cSJohan Hedberg 	hci_req_init(&req, hdev);
116175e84b7cSJohan Hedberg 
11627b1abbbeSJohan Hedberg 	hci_req_add_ev(&req, opcode, plen, param, event);
116375e84b7cSJohan Hedberg 
116475e84b7cSJohan Hedberg 	hdev->req_status = HCI_REQ_PEND;
116575e84b7cSJohan Hedberg 
116675e84b7cSJohan Hedberg 	add_wait_queue(&hdev->req_wait_q, &wait);
116775e84b7cSJohan Hedberg 	set_current_state(TASK_INTERRUPTIBLE);
116875e84b7cSJohan Hedberg 
1169039fada5SChan-yeol Park 	err = hci_req_run(&req, hci_req_sync_complete);
1170039fada5SChan-yeol Park 	if (err < 0) {
1171039fada5SChan-yeol Park 		remove_wait_queue(&hdev->req_wait_q, &wait);
117222a3ceabSJohan Hedberg 		set_current_state(TASK_RUNNING);
1173039fada5SChan-yeol Park 		return ERR_PTR(err);
1174039fada5SChan-yeol Park 	}
1175039fada5SChan-yeol Park 
117675e84b7cSJohan Hedberg 	schedule_timeout(timeout);
117775e84b7cSJohan Hedberg 
117875e84b7cSJohan Hedberg 	remove_wait_queue(&hdev->req_wait_q, &wait);
117975e84b7cSJohan Hedberg 
118075e84b7cSJohan Hedberg 	if (signal_pending(current))
118175e84b7cSJohan Hedberg 		return ERR_PTR(-EINTR);
118275e84b7cSJohan Hedberg 
118375e84b7cSJohan Hedberg 	switch (hdev->req_status) {
118475e84b7cSJohan Hedberg 	case HCI_REQ_DONE:
118575e84b7cSJohan Hedberg 		err = -bt_to_errno(hdev->req_result);
118675e84b7cSJohan Hedberg 		break;
118775e84b7cSJohan Hedberg 
118875e84b7cSJohan Hedberg 	case HCI_REQ_CANCELED:
118975e84b7cSJohan Hedberg 		err = -hdev->req_result;
119075e84b7cSJohan Hedberg 		break;
119175e84b7cSJohan Hedberg 
119275e84b7cSJohan Hedberg 	default:
119375e84b7cSJohan Hedberg 		err = -ETIMEDOUT;
119475e84b7cSJohan Hedberg 		break;
119575e84b7cSJohan Hedberg 	}
119675e84b7cSJohan Hedberg 
119775e84b7cSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
119875e84b7cSJohan Hedberg 
119975e84b7cSJohan Hedberg 	BT_DBG("%s end: err %d", hdev->name, err);
120075e84b7cSJohan Hedberg 
120175e84b7cSJohan Hedberg 	if (err < 0)
120275e84b7cSJohan Hedberg 		return ERR_PTR(err);
120375e84b7cSJohan Hedberg 
12047b1abbbeSJohan Hedberg 	return hci_get_cmd_complete(hdev, opcode, event);
12057b1abbbeSJohan Hedberg }
12067b1abbbeSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync_ev);
12077b1abbbeSJohan Hedberg 
12087b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
120907dc93ddSJohan Hedberg 			       const void *param, u32 timeout)
12107b1abbbeSJohan Hedberg {
12117b1abbbeSJohan Hedberg 	return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout);
121275e84b7cSJohan Hedberg }
121375e84b7cSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync);
121475e84b7cSJohan Hedberg 
12151da177e4SLinus Torvalds /* Execute request and wait for completion. */
121601178cd4SJohan Hedberg static int __hci_req_sync(struct hci_dev *hdev,
121742c6b129SJohan Hedberg 			  void (*func)(struct hci_request *req,
121842c6b129SJohan Hedberg 				      unsigned long opt),
12191da177e4SLinus Torvalds 			  unsigned long opt, __u32 timeout)
12201da177e4SLinus Torvalds {
122142c6b129SJohan Hedberg 	struct hci_request req;
12221da177e4SLinus Torvalds 	DECLARE_WAITQUEUE(wait, current);
12231da177e4SLinus Torvalds 	int err = 0;
12241da177e4SLinus Torvalds 
12251da177e4SLinus Torvalds 	BT_DBG("%s start", hdev->name);
12261da177e4SLinus Torvalds 
122742c6b129SJohan Hedberg 	hci_req_init(&req, hdev);
122842c6b129SJohan Hedberg 
12291da177e4SLinus Torvalds 	hdev->req_status = HCI_REQ_PEND;
12301da177e4SLinus Torvalds 
123142c6b129SJohan Hedberg 	func(&req, opt);
123253cce22dSJohan Hedberg 
1233039fada5SChan-yeol Park 	add_wait_queue(&hdev->req_wait_q, &wait);
1234039fada5SChan-yeol Park 	set_current_state(TASK_INTERRUPTIBLE);
1235039fada5SChan-yeol Park 
123642c6b129SJohan Hedberg 	err = hci_req_run(&req, hci_req_sync_complete);
123742c6b129SJohan Hedberg 	if (err < 0) {
123853cce22dSJohan Hedberg 		hdev->req_status = 0;
1239920c8300SAndre Guedes 
1240039fada5SChan-yeol Park 		remove_wait_queue(&hdev->req_wait_q, &wait);
124122a3ceabSJohan Hedberg 		set_current_state(TASK_RUNNING);
1242039fada5SChan-yeol Park 
1243920c8300SAndre Guedes 		/* ENODATA means the HCI request command queue is empty.
1244920c8300SAndre Guedes 		 * This can happen when a request with conditionals doesn't
1245920c8300SAndre Guedes 		 * trigger any commands to be sent. This is normal behavior
1246920c8300SAndre Guedes 		 * and should not trigger an error return.
124742c6b129SJohan Hedberg 		 */
1248920c8300SAndre Guedes 		if (err == -ENODATA)
124942c6b129SJohan Hedberg 			return 0;
1250920c8300SAndre Guedes 
1251920c8300SAndre Guedes 		return err;
125253cce22dSJohan Hedberg 	}
125353cce22dSJohan Hedberg 
12541da177e4SLinus Torvalds 	schedule_timeout(timeout);
12551da177e4SLinus Torvalds 
12561da177e4SLinus Torvalds 	remove_wait_queue(&hdev->req_wait_q, &wait);
12571da177e4SLinus Torvalds 
12581da177e4SLinus Torvalds 	if (signal_pending(current))
12591da177e4SLinus Torvalds 		return -EINTR;
12601da177e4SLinus Torvalds 
12611da177e4SLinus Torvalds 	switch (hdev->req_status) {
12621da177e4SLinus Torvalds 	case HCI_REQ_DONE:
1263e175072fSJoe Perches 		err = -bt_to_errno(hdev->req_result);
12641da177e4SLinus Torvalds 		break;
12651da177e4SLinus Torvalds 
12661da177e4SLinus Torvalds 	case HCI_REQ_CANCELED:
12671da177e4SLinus Torvalds 		err = -hdev->req_result;
12681da177e4SLinus Torvalds 		break;
12691da177e4SLinus Torvalds 
12701da177e4SLinus Torvalds 	default:
12711da177e4SLinus Torvalds 		err = -ETIMEDOUT;
12721da177e4SLinus Torvalds 		break;
12733ff50b79SStephen Hemminger 	}
12741da177e4SLinus Torvalds 
1275a5040efaSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
12761da177e4SLinus Torvalds 
12771da177e4SLinus Torvalds 	BT_DBG("%s end: err %d", hdev->name, err);
12781da177e4SLinus Torvalds 
12791da177e4SLinus Torvalds 	return err;
12801da177e4SLinus Torvalds }
12811da177e4SLinus Torvalds 
128201178cd4SJohan Hedberg static int hci_req_sync(struct hci_dev *hdev,
128342c6b129SJohan Hedberg 			void (*req)(struct hci_request *req,
128442c6b129SJohan Hedberg 				    unsigned long opt),
12851da177e4SLinus Torvalds 			unsigned long opt, __u32 timeout)
12861da177e4SLinus Torvalds {
12871da177e4SLinus Torvalds 	int ret;
12881da177e4SLinus Torvalds 
12897c6a329eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
12907c6a329eSMarcel Holtmann 		return -ENETDOWN;
12917c6a329eSMarcel Holtmann 
12921da177e4SLinus Torvalds 	/* Serialize all requests */
12931da177e4SLinus Torvalds 	hci_req_lock(hdev);
129401178cd4SJohan Hedberg 	ret = __hci_req_sync(hdev, req, opt, timeout);
12951da177e4SLinus Torvalds 	hci_req_unlock(hdev);
12961da177e4SLinus Torvalds 
12971da177e4SLinus Torvalds 	return ret;
12981da177e4SLinus Torvalds }
12991da177e4SLinus Torvalds 
130042c6b129SJohan Hedberg static void hci_reset_req(struct hci_request *req, unsigned long opt)
13011da177e4SLinus Torvalds {
130242c6b129SJohan Hedberg 	BT_DBG("%s %ld", req->hdev->name, opt);
13031da177e4SLinus Torvalds 
13041da177e4SLinus Torvalds 	/* Reset device */
130542c6b129SJohan Hedberg 	set_bit(HCI_RESET, &req->hdev->flags);
130642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_RESET, 0, NULL);
13071da177e4SLinus Torvalds }
13081da177e4SLinus Torvalds 
130942c6b129SJohan Hedberg static void bredr_init(struct hci_request *req)
13101da177e4SLinus Torvalds {
131142c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
13122455a3eaSAndrei Emeltchenko 
13131da177e4SLinus Torvalds 	/* Read Local Supported Features */
131442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
13151da177e4SLinus Torvalds 
13161143e5a6SMarcel Holtmann 	/* Read Local Version */
131742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
13182177bab5SJohan Hedberg 
13192177bab5SJohan Hedberg 	/* Read BD Address */
132042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
13211da177e4SLinus Torvalds }
13221da177e4SLinus Torvalds 
132342c6b129SJohan Hedberg static void amp_init(struct hci_request *req)
1324e61ef499SAndrei Emeltchenko {
132542c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
13262455a3eaSAndrei Emeltchenko 
1327e61ef499SAndrei Emeltchenko 	/* Read Local Version */
132842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
13296bcbc489SAndrei Emeltchenko 
1330f6996cfeSMarcel Holtmann 	/* Read Local Supported Commands */
1331f6996cfeSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
1332f6996cfeSMarcel Holtmann 
1333f6996cfeSMarcel Holtmann 	/* Read Local Supported Features */
1334f6996cfeSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
1335f6996cfeSMarcel Holtmann 
13366bcbc489SAndrei Emeltchenko 	/* Read Local AMP Info */
133742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
1338e71dfabaSAndrei Emeltchenko 
1339e71dfabaSAndrei Emeltchenko 	/* Read Data Blk size */
134042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL);
13417528ca1cSMarcel Holtmann 
1342f38ba941SMarcel Holtmann 	/* Read Flow Control Mode */
1343f38ba941SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL);
1344f38ba941SMarcel Holtmann 
13457528ca1cSMarcel Holtmann 	/* Read Location Data */
13467528ca1cSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL);
1347e61ef499SAndrei Emeltchenko }
1348e61ef499SAndrei Emeltchenko 
134942c6b129SJohan Hedberg static void hci_init1_req(struct hci_request *req, unsigned long opt)
1350e61ef499SAndrei Emeltchenko {
135142c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1352e61ef499SAndrei Emeltchenko 
1353e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
1354e61ef499SAndrei Emeltchenko 
135511778716SAndrei Emeltchenko 	/* Reset */
135611778716SAndrei Emeltchenko 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
135742c6b129SJohan Hedberg 		hci_reset_req(req, 0);
135811778716SAndrei Emeltchenko 
1359e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
1360e61ef499SAndrei Emeltchenko 	case HCI_BREDR:
136142c6b129SJohan Hedberg 		bredr_init(req);
1362e61ef499SAndrei Emeltchenko 		break;
1363e61ef499SAndrei Emeltchenko 
1364e61ef499SAndrei Emeltchenko 	case HCI_AMP:
136542c6b129SJohan Hedberg 		amp_init(req);
1366e61ef499SAndrei Emeltchenko 		break;
1367e61ef499SAndrei Emeltchenko 
1368e61ef499SAndrei Emeltchenko 	default:
1369e61ef499SAndrei Emeltchenko 		BT_ERR("Unknown device type %d", hdev->dev_type);
1370e61ef499SAndrei Emeltchenko 		break;
1371e61ef499SAndrei Emeltchenko 	}
1372e61ef499SAndrei Emeltchenko }
1373e61ef499SAndrei Emeltchenko 
137442c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req)
13752177bab5SJohan Hedberg {
13764ca048e3SMarcel Holtmann 	struct hci_dev *hdev = req->hdev;
13774ca048e3SMarcel Holtmann 
13782177bab5SJohan Hedberg 	__le16 param;
13792177bab5SJohan Hedberg 	__u8 flt_type;
13802177bab5SJohan Hedberg 
13812177bab5SJohan Hedberg 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
138242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
13832177bab5SJohan Hedberg 
13842177bab5SJohan Hedberg 	/* Read Class of Device */
138542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
13862177bab5SJohan Hedberg 
13872177bab5SJohan Hedberg 	/* Read Local Name */
138842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL);
13892177bab5SJohan Hedberg 
13902177bab5SJohan Hedberg 	/* Read Voice Setting */
139142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL);
13922177bab5SJohan Hedberg 
1393b4cb9fb2SMarcel Holtmann 	/* Read Number of Supported IAC */
1394b4cb9fb2SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL);
1395b4cb9fb2SMarcel Holtmann 
13964b836f39SMarcel Holtmann 	/* Read Current IAC LAP */
13974b836f39SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL);
13984b836f39SMarcel Holtmann 
13992177bab5SJohan Hedberg 	/* Clear Event Filters */
14002177bab5SJohan Hedberg 	flt_type = HCI_FLT_CLEAR_ALL;
140142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
14022177bab5SJohan Hedberg 
14032177bab5SJohan Hedberg 	/* Connection accept timeout ~20 secs */
1404dcf4adbfSJoe Perches 	param = cpu_to_le16(0x7d00);
140542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
14062177bab5SJohan Hedberg 
14074ca048e3SMarcel Holtmann 	/* AVM Berlin (31), aka "BlueFRITZ!", reports version 1.2,
14084ca048e3SMarcel Holtmann 	 * but it does not support page scan related HCI commands.
14094ca048e3SMarcel Holtmann 	 */
14104ca048e3SMarcel Holtmann 	if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) {
1411f332ec66SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL);
1412f332ec66SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL);
1413f332ec66SJohan Hedberg 	}
14142177bab5SJohan Hedberg }
14152177bab5SJohan Hedberg 
141642c6b129SJohan Hedberg static void le_setup(struct hci_request *req)
14172177bab5SJohan Hedberg {
1418c73eee91SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1419c73eee91SJohan Hedberg 
14202177bab5SJohan Hedberg 	/* Read LE Buffer Size */
142142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
14222177bab5SJohan Hedberg 
14232177bab5SJohan Hedberg 	/* Read LE Local Supported Features */
142442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
14252177bab5SJohan Hedberg 
1426747d3f03SMarcel Holtmann 	/* Read LE Supported States */
1427747d3f03SMarcel Holtmann 	hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);
1428747d3f03SMarcel Holtmann 
14292177bab5SJohan Hedberg 	/* Read LE White List Size */
143042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL);
14312177bab5SJohan Hedberg 
1432747d3f03SMarcel Holtmann 	/* Clear LE White List */
1433747d3f03SMarcel Holtmann 	hci_req_add(req, HCI_OP_LE_CLEAR_WHITE_LIST, 0, NULL);
1434c73eee91SJohan Hedberg 
1435c73eee91SJohan Hedberg 	/* LE-only controllers have LE implicitly enabled */
1436c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
1437c73eee91SJohan Hedberg 		set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
14382177bab5SJohan Hedberg }
14392177bab5SJohan Hedberg 
14402177bab5SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
14412177bab5SJohan Hedberg {
14422177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
14432177bab5SJohan Hedberg 		return 0x02;
14442177bab5SJohan Hedberg 
14452177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
14462177bab5SJohan Hedberg 		return 0x01;
14472177bab5SJohan Hedberg 
14482177bab5SJohan Hedberg 	if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
14492177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x0757)
14502177bab5SJohan Hedberg 		return 0x01;
14512177bab5SJohan Hedberg 
14522177bab5SJohan Hedberg 	if (hdev->manufacturer == 15) {
14532177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
14542177bab5SJohan Hedberg 			return 0x01;
14552177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
14562177bab5SJohan Hedberg 			return 0x01;
14572177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
14582177bab5SJohan Hedberg 			return 0x01;
14592177bab5SJohan Hedberg 	}
14602177bab5SJohan Hedberg 
14612177bab5SJohan Hedberg 	if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
14622177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x1805)
14632177bab5SJohan Hedberg 		return 0x01;
14642177bab5SJohan Hedberg 
14652177bab5SJohan Hedberg 	return 0x00;
14662177bab5SJohan Hedberg }
14672177bab5SJohan Hedberg 
146842c6b129SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_request *req)
14692177bab5SJohan Hedberg {
14702177bab5SJohan Hedberg 	u8 mode;
14712177bab5SJohan Hedberg 
147242c6b129SJohan Hedberg 	mode = hci_get_inquiry_mode(req->hdev);
14732177bab5SJohan Hedberg 
147442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
14752177bab5SJohan Hedberg }
14762177bab5SJohan Hedberg 
147742c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req)
14782177bab5SJohan Hedberg {
147942c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
148042c6b129SJohan Hedberg 
14812177bab5SJohan Hedberg 	/* The second byte is 0xff instead of 0x9f (two reserved bits
14822177bab5SJohan Hedberg 	 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
14832177bab5SJohan Hedberg 	 * command otherwise.
14842177bab5SJohan Hedberg 	 */
14852177bab5SJohan Hedberg 	u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
14862177bab5SJohan Hedberg 
14872177bab5SJohan Hedberg 	/* CSR 1.1 dongles does not accept any bitfield so don't try to set
14882177bab5SJohan Hedberg 	 * any event mask for pre 1.2 devices.
14892177bab5SJohan Hedberg 	 */
14902177bab5SJohan Hedberg 	if (hdev->hci_ver < BLUETOOTH_VER_1_2)
14912177bab5SJohan Hedberg 		return;
14922177bab5SJohan Hedberg 
14932177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
14942177bab5SJohan Hedberg 		events[4] |= 0x01; /* Flow Specification Complete */
14952177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
14962177bab5SJohan Hedberg 		events[4] |= 0x04; /* Read Remote Extended Features Complete */
14972177bab5SJohan Hedberg 		events[5] |= 0x08; /* Synchronous Connection Complete */
14982177bab5SJohan Hedberg 		events[5] |= 0x10; /* Synchronous Connection Changed */
1499c7882cbdSMarcel Holtmann 	} else {
1500c7882cbdSMarcel Holtmann 		/* Use a different default for LE-only devices */
1501c7882cbdSMarcel Holtmann 		memset(events, 0, sizeof(events));
1502c7882cbdSMarcel Holtmann 		events[0] |= 0x10; /* Disconnection Complete */
1503c7882cbdSMarcel Holtmann 		events[1] |= 0x08; /* Read Remote Version Information Complete */
1504c7882cbdSMarcel Holtmann 		events[1] |= 0x20; /* Command Complete */
1505c7882cbdSMarcel Holtmann 		events[1] |= 0x40; /* Command Status */
1506c7882cbdSMarcel Holtmann 		events[1] |= 0x80; /* Hardware Error */
1507c7882cbdSMarcel Holtmann 		events[2] |= 0x04; /* Number of Completed Packets */
1508c7882cbdSMarcel Holtmann 		events[3] |= 0x02; /* Data Buffer Overflow */
15090da71f1bSMarcel Holtmann 
15100da71f1bSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_ENCRYPTION) {
15110da71f1bSMarcel Holtmann 			events[0] |= 0x80; /* Encryption Change */
1512c7882cbdSMarcel Holtmann 			events[5] |= 0x80; /* Encryption Key Refresh Complete */
15132177bab5SJohan Hedberg 		}
15140da71f1bSMarcel Holtmann 	}
15152177bab5SJohan Hedberg 
15162177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
15172177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
15182177bab5SJohan Hedberg 
15192177bab5SJohan Hedberg 	if (lmp_sniffsubr_capable(hdev))
15202177bab5SJohan Hedberg 		events[5] |= 0x20; /* Sniff Subrating */
15212177bab5SJohan Hedberg 
15222177bab5SJohan Hedberg 	if (lmp_pause_enc_capable(hdev))
15232177bab5SJohan Hedberg 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
15242177bab5SJohan Hedberg 
15252177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
15262177bab5SJohan Hedberg 		events[5] |= 0x40; /* Extended Inquiry Result */
15272177bab5SJohan Hedberg 
15282177bab5SJohan Hedberg 	if (lmp_no_flush_capable(hdev))
15292177bab5SJohan Hedberg 		events[7] |= 0x01; /* Enhanced Flush Complete */
15302177bab5SJohan Hedberg 
15312177bab5SJohan Hedberg 	if (lmp_lsto_capable(hdev))
15322177bab5SJohan Hedberg 		events[6] |= 0x80; /* Link Supervision Timeout Changed */
15332177bab5SJohan Hedberg 
15342177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
15352177bab5SJohan Hedberg 		events[6] |= 0x01;	/* IO Capability Request */
15362177bab5SJohan Hedberg 		events[6] |= 0x02;	/* IO Capability Response */
15372177bab5SJohan Hedberg 		events[6] |= 0x04;	/* User Confirmation Request */
15382177bab5SJohan Hedberg 		events[6] |= 0x08;	/* User Passkey Request */
15392177bab5SJohan Hedberg 		events[6] |= 0x10;	/* Remote OOB Data Request */
15402177bab5SJohan Hedberg 		events[6] |= 0x20;	/* Simple Pairing Complete */
15412177bab5SJohan Hedberg 		events[7] |= 0x04;	/* User Passkey Notification */
15422177bab5SJohan Hedberg 		events[7] |= 0x08;	/* Keypress Notification */
15432177bab5SJohan Hedberg 		events[7] |= 0x10;	/* Remote Host Supported
15442177bab5SJohan Hedberg 					 * Features Notification
15452177bab5SJohan Hedberg 					 */
15462177bab5SJohan Hedberg 	}
15472177bab5SJohan Hedberg 
15482177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
15492177bab5SJohan Hedberg 		events[7] |= 0x20;	/* LE Meta-Event */
15502177bab5SJohan Hedberg 
155142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
15522177bab5SJohan Hedberg }
15532177bab5SJohan Hedberg 
155442c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt)
15552177bab5SJohan Hedberg {
155642c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
155742c6b129SJohan Hedberg 
15582177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev))
155942c6b129SJohan Hedberg 		bredr_setup(req);
156056f87901SJohan Hedberg 	else
156156f87901SJohan Hedberg 		clear_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
15622177bab5SJohan Hedberg 
15632177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
156442c6b129SJohan Hedberg 		le_setup(req);
15652177bab5SJohan Hedberg 
15663f8e2d75SJohan Hedberg 	/* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read
15673f8e2d75SJohan Hedberg 	 * local supported commands HCI command.
15683f8e2d75SJohan Hedberg 	 */
15693f8e2d75SJohan Hedberg 	if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1)
157042c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
15712177bab5SJohan Hedberg 
15722177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
157357af75a8SMarcel Holtmann 		/* When SSP is available, then the host features page
157457af75a8SMarcel Holtmann 		 * should also be available as well. However some
157557af75a8SMarcel Holtmann 		 * controllers list the max_page as 0 as long as SSP
157657af75a8SMarcel Holtmann 		 * has not been enabled. To achieve proper debugging
157757af75a8SMarcel Holtmann 		 * output, force the minimum max_page to 1 at least.
157857af75a8SMarcel Holtmann 		 */
157957af75a8SMarcel Holtmann 		hdev->max_page = 0x01;
158057af75a8SMarcel Holtmann 
15812177bab5SJohan Hedberg 		if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
15822177bab5SJohan Hedberg 			u8 mode = 0x01;
158342c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_SSP_MODE,
15842177bab5SJohan Hedberg 				    sizeof(mode), &mode);
15852177bab5SJohan Hedberg 		} else {
15862177bab5SJohan Hedberg 			struct hci_cp_write_eir cp;
15872177bab5SJohan Hedberg 
15882177bab5SJohan Hedberg 			memset(hdev->eir, 0, sizeof(hdev->eir));
15892177bab5SJohan Hedberg 			memset(&cp, 0, sizeof(cp));
15902177bab5SJohan Hedberg 
159142c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
15922177bab5SJohan Hedberg 		}
15932177bab5SJohan Hedberg 	}
15942177bab5SJohan Hedberg 
15952177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
159642c6b129SJohan Hedberg 		hci_setup_inquiry_mode(req);
15972177bab5SJohan Hedberg 
15982177bab5SJohan Hedberg 	if (lmp_inq_tx_pwr_capable(hdev))
159942c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
16002177bab5SJohan Hedberg 
16012177bab5SJohan Hedberg 	if (lmp_ext_feat_capable(hdev)) {
16022177bab5SJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
16032177bab5SJohan Hedberg 
16042177bab5SJohan Hedberg 		cp.page = 0x01;
160542c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
160642c6b129SJohan Hedberg 			    sizeof(cp), &cp);
16072177bab5SJohan Hedberg 	}
16082177bab5SJohan Hedberg 
16092177bab5SJohan Hedberg 	if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
16102177bab5SJohan Hedberg 		u8 enable = 1;
161142c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
16122177bab5SJohan Hedberg 			    &enable);
16132177bab5SJohan Hedberg 	}
16142177bab5SJohan Hedberg }
16152177bab5SJohan Hedberg 
161642c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req)
16172177bab5SJohan Hedberg {
161842c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
16192177bab5SJohan Hedberg 	struct hci_cp_write_def_link_policy cp;
16202177bab5SJohan Hedberg 	u16 link_policy = 0;
16212177bab5SJohan Hedberg 
16222177bab5SJohan Hedberg 	if (lmp_rswitch_capable(hdev))
16232177bab5SJohan Hedberg 		link_policy |= HCI_LP_RSWITCH;
16242177bab5SJohan Hedberg 	if (lmp_hold_capable(hdev))
16252177bab5SJohan Hedberg 		link_policy |= HCI_LP_HOLD;
16262177bab5SJohan Hedberg 	if (lmp_sniff_capable(hdev))
16272177bab5SJohan Hedberg 		link_policy |= HCI_LP_SNIFF;
16282177bab5SJohan Hedberg 	if (lmp_park_capable(hdev))
16292177bab5SJohan Hedberg 		link_policy |= HCI_LP_PARK;
16302177bab5SJohan Hedberg 
16312177bab5SJohan Hedberg 	cp.policy = cpu_to_le16(link_policy);
163242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp);
16332177bab5SJohan Hedberg }
16342177bab5SJohan Hedberg 
163542c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req)
16362177bab5SJohan Hedberg {
163742c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
16382177bab5SJohan Hedberg 	struct hci_cp_write_le_host_supported cp;
16392177bab5SJohan Hedberg 
1640c73eee91SJohan Hedberg 	/* LE-only devices do not support explicit enablement */
1641c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
1642c73eee91SJohan Hedberg 		return;
1643c73eee91SJohan Hedberg 
16442177bab5SJohan Hedberg 	memset(&cp, 0, sizeof(cp));
16452177bab5SJohan Hedberg 
16462177bab5SJohan Hedberg 	if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
16472177bab5SJohan Hedberg 		cp.le = 0x01;
164832226e4fSMarcel Holtmann 		cp.simul = 0x00;
16492177bab5SJohan Hedberg 	}
16502177bab5SJohan Hedberg 
16512177bab5SJohan Hedberg 	if (cp.le != lmp_host_le_capable(hdev))
165242c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
16532177bab5SJohan Hedberg 			    &cp);
16542177bab5SJohan Hedberg }
16552177bab5SJohan Hedberg 
1656d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req)
1657d62e6d67SJohan Hedberg {
1658d62e6d67SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1659d62e6d67SJohan Hedberg 	u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1660d62e6d67SJohan Hedberg 
1661d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast master role is supported
1662d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
1663d62e6d67SJohan Hedberg 	 */
166453b834d2SMarcel Holtmann 	if (lmp_csb_master_capable(hdev)) {
1665d62e6d67SJohan Hedberg 		events[1] |= 0x40;	/* Triggered Clock Capture */
1666d62e6d67SJohan Hedberg 		events[1] |= 0x80;	/* Synchronization Train Complete */
1667d62e6d67SJohan Hedberg 		events[2] |= 0x10;	/* Slave Page Response Timeout */
1668d62e6d67SJohan Hedberg 		events[2] |= 0x20;	/* CSB Channel Map Change */
1669d62e6d67SJohan Hedberg 	}
1670d62e6d67SJohan Hedberg 
1671d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast slave role is supported
1672d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
1673d62e6d67SJohan Hedberg 	 */
167453b834d2SMarcel Holtmann 	if (lmp_csb_slave_capable(hdev)) {
1675d62e6d67SJohan Hedberg 		events[2] |= 0x01;	/* Synchronization Train Received */
1676d62e6d67SJohan Hedberg 		events[2] |= 0x02;	/* CSB Receive */
1677d62e6d67SJohan Hedberg 		events[2] |= 0x04;	/* CSB Timeout */
1678d62e6d67SJohan Hedberg 		events[2] |= 0x08;	/* Truncated Page Complete */
1679d62e6d67SJohan Hedberg 	}
1680d62e6d67SJohan Hedberg 
168140c59fcbSMarcel Holtmann 	/* Enable Authenticated Payload Timeout Expired event if supported */
1682cd7ca0ecSMarcel Holtmann 	if (lmp_ping_capable(hdev) || hdev->le_features[0] & HCI_LE_PING)
168340c59fcbSMarcel Holtmann 		events[2] |= 0x80;
168440c59fcbSMarcel Holtmann 
1685d62e6d67SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events);
1686d62e6d67SJohan Hedberg }
1687d62e6d67SJohan Hedberg 
168842c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt)
16892177bab5SJohan Hedberg {
169042c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1691d2c5d77fSJohan Hedberg 	u8 p;
169242c6b129SJohan Hedberg 
16930da71f1bSMarcel Holtmann 	hci_setup_event_mask(req);
16940da71f1bSMarcel Holtmann 
1695b8f4e068SGustavo Padovan 	/* Some Broadcom based Bluetooth controllers do not support the
1696b8f4e068SGustavo Padovan 	 * Delete Stored Link Key command. They are clearly indicating its
1697b8f4e068SGustavo Padovan 	 * absence in the bit mask of supported commands.
1698b8f4e068SGustavo Padovan 	 *
1699b8f4e068SGustavo Padovan 	 * Check the supported commands and only if the the command is marked
1700b8f4e068SGustavo Padovan 	 * as supported send it. If not supported assume that the controller
1701b8f4e068SGustavo Padovan 	 * does not have actual support for stored link keys which makes this
1702b8f4e068SGustavo Padovan 	 * command redundant anyway.
1703f9f462faSMarcel Holtmann 	 *
1704f9f462faSMarcel Holtmann 	 * Some controllers indicate that they support handling deleting
1705f9f462faSMarcel Holtmann 	 * stored link keys, but they don't. The quirk lets a driver
1706f9f462faSMarcel Holtmann 	 * just disable this command.
1707b8f4e068SGustavo Padovan 	 */
1708f9f462faSMarcel Holtmann 	if (hdev->commands[6] & 0x80 &&
1709f9f462faSMarcel Holtmann 	    !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) {
171059f45d57SJohan Hedberg 		struct hci_cp_delete_stored_link_key cp;
171159f45d57SJohan Hedberg 
171259f45d57SJohan Hedberg 		bacpy(&cp.bdaddr, BDADDR_ANY);
171359f45d57SJohan Hedberg 		cp.delete_all = 0x01;
171459f45d57SJohan Hedberg 		hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY,
171559f45d57SJohan Hedberg 			    sizeof(cp), &cp);
171659f45d57SJohan Hedberg 	}
171759f45d57SJohan Hedberg 
17182177bab5SJohan Hedberg 	if (hdev->commands[5] & 0x10)
171942c6b129SJohan Hedberg 		hci_setup_link_policy(req);
17202177bab5SJohan Hedberg 
17219193c6e8SAndre Guedes 	if (lmp_le_capable(hdev)) {
17229193c6e8SAndre Guedes 		u8 events[8];
17239193c6e8SAndre Guedes 
17249193c6e8SAndre Guedes 		memset(events, 0, sizeof(events));
17254d6c705bSMarcel Holtmann 		events[0] = 0x0f;
17264d6c705bSMarcel Holtmann 
17274d6c705bSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_ENCRYPTION)
17284d6c705bSMarcel Holtmann 			events[0] |= 0x10;	/* LE Long Term Key Request */
1729662bc2e6SAndre Guedes 
1730662bc2e6SAndre Guedes 		/* If controller supports the Connection Parameters Request
1731662bc2e6SAndre Guedes 		 * Link Layer Procedure, enable the corresponding event.
1732662bc2e6SAndre Guedes 		 */
1733662bc2e6SAndre Guedes 		if (hdev->le_features[0] & HCI_LE_CONN_PARAM_REQ_PROC)
1734662bc2e6SAndre Guedes 			events[0] |= 0x20;	/* LE Remote Connection
1735662bc2e6SAndre Guedes 						 * Parameter Request
1736662bc2e6SAndre Guedes 						 */
1737662bc2e6SAndre Guedes 
17384b71bba4SMarcel Holtmann 		/* If the controller supports Extended Scanner Filter
17394b71bba4SMarcel Holtmann 		 * Policies, enable the correspondig event.
17404b71bba4SMarcel Holtmann 		 */
17414b71bba4SMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_EXT_SCAN_POLICY)
17424b71bba4SMarcel Holtmann 			events[1] |= 0x04;	/* LE Direct Advertising
17434b71bba4SMarcel Holtmann 						 * Report
17444b71bba4SMarcel Holtmann 						 */
17454b71bba4SMarcel Holtmann 
17469193c6e8SAndre Guedes 		hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, sizeof(events),
17479193c6e8SAndre Guedes 			    events);
17489193c6e8SAndre Guedes 
174915a49ccaSMarcel Holtmann 		if (hdev->commands[25] & 0x40) {
175015a49ccaSMarcel Holtmann 			/* Read LE Advertising Channel TX Power */
175115a49ccaSMarcel Holtmann 			hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
175215a49ccaSMarcel Holtmann 		}
175315a49ccaSMarcel Holtmann 
175442c6b129SJohan Hedberg 		hci_set_le_support(req);
17559193c6e8SAndre Guedes 	}
1756d2c5d77fSJohan Hedberg 
1757d2c5d77fSJohan Hedberg 	/* Read features beyond page 1 if available */
1758d2c5d77fSJohan Hedberg 	for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
1759d2c5d77fSJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
1760d2c5d77fSJohan Hedberg 
1761d2c5d77fSJohan Hedberg 		cp.page = p;
1762d2c5d77fSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
1763d2c5d77fSJohan Hedberg 			    sizeof(cp), &cp);
1764d2c5d77fSJohan Hedberg 	}
17652177bab5SJohan Hedberg }
17662177bab5SJohan Hedberg 
17675d4e7e8dSJohan Hedberg static void hci_init4_req(struct hci_request *req, unsigned long opt)
17685d4e7e8dSJohan Hedberg {
17695d4e7e8dSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
17705d4e7e8dSJohan Hedberg 
1771d62e6d67SJohan Hedberg 	/* Set event mask page 2 if the HCI command for it is supported */
1772d62e6d67SJohan Hedberg 	if (hdev->commands[22] & 0x04)
1773d62e6d67SJohan Hedberg 		hci_set_event_mask_page_2(req);
1774d62e6d67SJohan Hedberg 
1775109e3191SMarcel Holtmann 	/* Read local codec list if the HCI command is supported */
1776109e3191SMarcel Holtmann 	if (hdev->commands[29] & 0x20)
1777109e3191SMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_LOCAL_CODECS, 0, NULL);
1778109e3191SMarcel Holtmann 
1779f4fe73edSMarcel Holtmann 	/* Get MWS transport configuration if the HCI command is supported */
1780f4fe73edSMarcel Holtmann 	if (hdev->commands[30] & 0x08)
1781f4fe73edSMarcel Holtmann 		hci_req_add(req, HCI_OP_GET_MWS_TRANSPORT_CONFIG, 0, NULL);
1782f4fe73edSMarcel Holtmann 
17835d4e7e8dSJohan Hedberg 	/* Check for Synchronization Train support */
178453b834d2SMarcel Holtmann 	if (lmp_sync_train_capable(hdev))
17855d4e7e8dSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL);
1786a6d0d690SMarcel Holtmann 
1787a6d0d690SMarcel Holtmann 	/* Enable Secure Connections if supported and configured */
1788710f11c0SJohan Hedberg 	if (bredr_sc_enabled(hdev)) {
1789a6d0d690SMarcel Holtmann 		u8 support = 0x01;
1790a6d0d690SMarcel Holtmann 		hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT,
1791a6d0d690SMarcel Holtmann 			    sizeof(support), &support);
1792a6d0d690SMarcel Holtmann 	}
17935d4e7e8dSJohan Hedberg }
17945d4e7e8dSJohan Hedberg 
17952177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev)
17962177bab5SJohan Hedberg {
17972177bab5SJohan Hedberg 	int err;
17982177bab5SJohan Hedberg 
17992177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT);
18002177bab5SJohan Hedberg 	if (err < 0)
18012177bab5SJohan Hedberg 		return err;
18022177bab5SJohan Hedberg 
18034b4148e9SMarcel Holtmann 	/* The Device Under Test (DUT) mode is special and available for
18044b4148e9SMarcel Holtmann 	 * all controller types. So just create it early on.
18054b4148e9SMarcel Holtmann 	 */
18064b4148e9SMarcel Holtmann 	if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
18074b4148e9SMarcel Holtmann 		debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev,
18084b4148e9SMarcel Holtmann 				    &dut_mode_fops);
18094b4148e9SMarcel Holtmann 	}
18104b4148e9SMarcel Holtmann 
18112177bab5SJohan Hedberg 	/* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode
18122177bab5SJohan Hedberg 	 * BR/EDR/LE type controllers. AMP controllers only need the
18132177bab5SJohan Hedberg 	 * first stage init.
18142177bab5SJohan Hedberg 	 */
18152177bab5SJohan Hedberg 	if (hdev->dev_type != HCI_BREDR)
18162177bab5SJohan Hedberg 		return 0;
18172177bab5SJohan Hedberg 
18182177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT);
18192177bab5SJohan Hedberg 	if (err < 0)
18202177bab5SJohan Hedberg 		return err;
18212177bab5SJohan Hedberg 
18225d4e7e8dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT);
18235d4e7e8dSJohan Hedberg 	if (err < 0)
18245d4e7e8dSJohan Hedberg 		return err;
18255d4e7e8dSJohan Hedberg 
1826baf27f6eSMarcel Holtmann 	err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT);
1827baf27f6eSMarcel Holtmann 	if (err < 0)
1828baf27f6eSMarcel Holtmann 		return err;
1829baf27f6eSMarcel Holtmann 
1830baf27f6eSMarcel Holtmann 	/* Only create debugfs entries during the initial setup
1831baf27f6eSMarcel Holtmann 	 * phase and not every time the controller gets powered on.
1832baf27f6eSMarcel Holtmann 	 */
1833baf27f6eSMarcel Holtmann 	if (!test_bit(HCI_SETUP, &hdev->dev_flags))
1834baf27f6eSMarcel Holtmann 		return 0;
1835baf27f6eSMarcel Holtmann 
1836dfb826a8SMarcel Holtmann 	debugfs_create_file("features", 0444, hdev->debugfs, hdev,
1837dfb826a8SMarcel Holtmann 			    &features_fops);
1838ceeb3bc0SMarcel Holtmann 	debugfs_create_u16("manufacturer", 0444, hdev->debugfs,
1839ceeb3bc0SMarcel Holtmann 			   &hdev->manufacturer);
1840ceeb3bc0SMarcel Holtmann 	debugfs_create_u8("hci_version", 0444, hdev->debugfs, &hdev->hci_ver);
1841ceeb3bc0SMarcel Holtmann 	debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev);
184240f4938aSMarcel Holtmann 	debugfs_create_file("device_list", 0444, hdev->debugfs, hdev,
184340f4938aSMarcel Holtmann 			    &device_list_fops);
184470afe0b8SMarcel Holtmann 	debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev,
184570afe0b8SMarcel Holtmann 			    &blacklist_fops);
184647219839SMarcel Holtmann 	debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops);
184747219839SMarcel Holtmann 
184831ad1691SAndrzej Kaczmarek 	debugfs_create_file("conn_info_min_age", 0644, hdev->debugfs, hdev,
184931ad1691SAndrzej Kaczmarek 			    &conn_info_min_age_fops);
185031ad1691SAndrzej Kaczmarek 	debugfs_create_file("conn_info_max_age", 0644, hdev->debugfs, hdev,
185131ad1691SAndrzej Kaczmarek 			    &conn_info_max_age_fops);
185231ad1691SAndrzej Kaczmarek 
1853baf27f6eSMarcel Holtmann 	if (lmp_bredr_capable(hdev)) {
1854baf27f6eSMarcel Holtmann 		debugfs_create_file("inquiry_cache", 0444, hdev->debugfs,
1855baf27f6eSMarcel Holtmann 				    hdev, &inquiry_cache_fops);
185602d08d15SMarcel Holtmann 		debugfs_create_file("link_keys", 0400, hdev->debugfs,
185702d08d15SMarcel Holtmann 				    hdev, &link_keys_fops);
1858babdbb3cSMarcel Holtmann 		debugfs_create_file("dev_class", 0444, hdev->debugfs,
1859babdbb3cSMarcel Holtmann 				    hdev, &dev_class_fops);
1860041000b9SMarcel Holtmann 		debugfs_create_file("voice_setting", 0444, hdev->debugfs,
1861041000b9SMarcel Holtmann 				    hdev, &voice_setting_fops);
1862baf27f6eSMarcel Holtmann 	}
1863baf27f6eSMarcel Holtmann 
186406f5b778SMarcel Holtmann 	if (lmp_ssp_capable(hdev)) {
1865ebd1e33bSMarcel Holtmann 		debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs,
1866ebd1e33bSMarcel Holtmann 				    hdev, &auto_accept_delay_fops);
18675afeac14SMarcel Holtmann 		debugfs_create_file("force_sc_support", 0644, hdev->debugfs,
18685afeac14SMarcel Holtmann 				    hdev, &force_sc_support_fops);
1869134c2a89SMarcel Holtmann 		debugfs_create_file("sc_only_mode", 0444, hdev->debugfs,
1870134c2a89SMarcel Holtmann 				    hdev, &sc_only_mode_fops);
1871858cdc78SJohan Hedberg 		if (lmp_le_capable(hdev))
1872858cdc78SJohan Hedberg 			debugfs_create_file("force_lesc_support", 0644,
1873858cdc78SJohan Hedberg 					    hdev->debugfs, hdev,
1874858cdc78SJohan Hedberg 					    &force_lesc_support_fops);
187506f5b778SMarcel Holtmann 	}
1876ebd1e33bSMarcel Holtmann 
18772bfa3531SMarcel Holtmann 	if (lmp_sniff_capable(hdev)) {
18782bfa3531SMarcel Holtmann 		debugfs_create_file("idle_timeout", 0644, hdev->debugfs,
18792bfa3531SMarcel Holtmann 				    hdev, &idle_timeout_fops);
18802bfa3531SMarcel Holtmann 		debugfs_create_file("sniff_min_interval", 0644, hdev->debugfs,
18812bfa3531SMarcel Holtmann 				    hdev, &sniff_min_interval_fops);
18822bfa3531SMarcel Holtmann 		debugfs_create_file("sniff_max_interval", 0644, hdev->debugfs,
18832bfa3531SMarcel Holtmann 				    hdev, &sniff_max_interval_fops);
18842bfa3531SMarcel Holtmann 	}
18852bfa3531SMarcel Holtmann 
1886d0f729b8SMarcel Holtmann 	if (lmp_le_capable(hdev)) {
1887ac345813SMarcel Holtmann 		debugfs_create_file("identity", 0400, hdev->debugfs,
1888ac345813SMarcel Holtmann 				    hdev, &identity_fops);
1889ac345813SMarcel Holtmann 		debugfs_create_file("rpa_timeout", 0644, hdev->debugfs,
1890ac345813SMarcel Holtmann 				    hdev, &rpa_timeout_fops);
18917a4cd51dSMarcel Holtmann 		debugfs_create_file("random_address", 0444, hdev->debugfs,
18927a4cd51dSMarcel Holtmann 				    hdev, &random_address_fops);
1893e7b8fc92SMarcel Holtmann 		debugfs_create_file("static_address", 0444, hdev->debugfs,
1894e7b8fc92SMarcel Holtmann 				    hdev, &static_address_fops);
1895b32bba6cSMarcel Holtmann 
1896b32bba6cSMarcel Holtmann 		/* For controllers with a public address, provide a debug
1897b32bba6cSMarcel Holtmann 		 * option to force the usage of the configured static
1898b32bba6cSMarcel Holtmann 		 * address. By default the public address is used.
1899b32bba6cSMarcel Holtmann 		 */
1900b32bba6cSMarcel Holtmann 		if (bacmp(&hdev->bdaddr, BDADDR_ANY))
1901b32bba6cSMarcel Holtmann 			debugfs_create_file("force_static_address", 0644,
1902b32bba6cSMarcel Holtmann 					    hdev->debugfs, hdev,
1903b32bba6cSMarcel Holtmann 					    &force_static_address_fops);
1904b32bba6cSMarcel Holtmann 
1905b32bba6cSMarcel Holtmann 		debugfs_create_u8("white_list_size", 0444, hdev->debugfs,
1906b32bba6cSMarcel Holtmann 				  &hdev->le_white_list_size);
1907d2ab0ac1SMarcel Holtmann 		debugfs_create_file("white_list", 0444, hdev->debugfs, hdev,
1908d2ab0ac1SMarcel Holtmann 				    &white_list_fops);
19093698d704SMarcel Holtmann 		debugfs_create_file("identity_resolving_keys", 0400,
19103698d704SMarcel Holtmann 				    hdev->debugfs, hdev,
19113698d704SMarcel Holtmann 				    &identity_resolving_keys_fops);
19128f8625cdSMarcel Holtmann 		debugfs_create_file("long_term_keys", 0400, hdev->debugfs,
19138f8625cdSMarcel Holtmann 				    hdev, &long_term_keys_fops);
19144e70c7e7SMarcel Holtmann 		debugfs_create_file("conn_min_interval", 0644, hdev->debugfs,
19154e70c7e7SMarcel Holtmann 				    hdev, &conn_min_interval_fops);
19164e70c7e7SMarcel Holtmann 		debugfs_create_file("conn_max_interval", 0644, hdev->debugfs,
19174e70c7e7SMarcel Holtmann 				    hdev, &conn_max_interval_fops);
1918816a93d1SMarcel Holtmann 		debugfs_create_file("conn_latency", 0644, hdev->debugfs,
1919816a93d1SMarcel Holtmann 				    hdev, &conn_latency_fops);
1920f1649577SMarcel Holtmann 		debugfs_create_file("supervision_timeout", 0644, hdev->debugfs,
1921f1649577SMarcel Holtmann 				    hdev, &supervision_timeout_fops);
19223f959d46SMarcel Holtmann 		debugfs_create_file("adv_channel_map", 0644, hdev->debugfs,
19233f959d46SMarcel Holtmann 				    hdev, &adv_channel_map_fops);
1924729a1051SGeorg Lukas 		debugfs_create_file("adv_min_interval", 0644, hdev->debugfs,
1925729a1051SGeorg Lukas 				    hdev, &adv_min_interval_fops);
1926729a1051SGeorg Lukas 		debugfs_create_file("adv_max_interval", 0644, hdev->debugfs,
1927729a1051SGeorg Lukas 				    hdev, &adv_max_interval_fops);
1928b9a7a61eSLukasz Rymanowski 		debugfs_create_u16("discov_interleaved_timeout", 0644,
1929b9a7a61eSLukasz Rymanowski 				   hdev->debugfs,
1930b9a7a61eSLukasz Rymanowski 				   &hdev->discov_interleaved_timeout);
193154506918SJohan Hedberg 
1932711eafe3SJohan Hedberg 		smp_register(hdev);
1933d0f729b8SMarcel Holtmann 	}
1934e7b8fc92SMarcel Holtmann 
1935baf27f6eSMarcel Holtmann 	return 0;
19362177bab5SJohan Hedberg }
19372177bab5SJohan Hedberg 
19380ebca7d6SMarcel Holtmann static void hci_init0_req(struct hci_request *req, unsigned long opt)
19390ebca7d6SMarcel Holtmann {
19400ebca7d6SMarcel Holtmann 	struct hci_dev *hdev = req->hdev;
19410ebca7d6SMarcel Holtmann 
19420ebca7d6SMarcel Holtmann 	BT_DBG("%s %ld", hdev->name, opt);
19430ebca7d6SMarcel Holtmann 
19440ebca7d6SMarcel Holtmann 	/* Reset */
19450ebca7d6SMarcel Holtmann 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
19460ebca7d6SMarcel Holtmann 		hci_reset_req(req, 0);
19470ebca7d6SMarcel Holtmann 
19480ebca7d6SMarcel Holtmann 	/* Read Local Version */
19490ebca7d6SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
19500ebca7d6SMarcel Holtmann 
19510ebca7d6SMarcel Holtmann 	/* Read BD Address */
19520ebca7d6SMarcel Holtmann 	if (hdev->set_bdaddr)
19530ebca7d6SMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
19540ebca7d6SMarcel Holtmann }
19550ebca7d6SMarcel Holtmann 
19560ebca7d6SMarcel Holtmann static int __hci_unconf_init(struct hci_dev *hdev)
19570ebca7d6SMarcel Holtmann {
19580ebca7d6SMarcel Holtmann 	int err;
19590ebca7d6SMarcel Holtmann 
1960cc78b44bSMarcel Holtmann 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
1961cc78b44bSMarcel Holtmann 		return 0;
1962cc78b44bSMarcel Holtmann 
19630ebca7d6SMarcel Holtmann 	err = __hci_req_sync(hdev, hci_init0_req, 0, HCI_INIT_TIMEOUT);
19640ebca7d6SMarcel Holtmann 	if (err < 0)
19650ebca7d6SMarcel Holtmann 		return err;
19660ebca7d6SMarcel Holtmann 
19670ebca7d6SMarcel Holtmann 	return 0;
19680ebca7d6SMarcel Holtmann }
19690ebca7d6SMarcel Holtmann 
197042c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt)
19711da177e4SLinus Torvalds {
19721da177e4SLinus Torvalds 	__u8 scan = opt;
19731da177e4SLinus Torvalds 
197442c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, scan);
19751da177e4SLinus Torvalds 
19761da177e4SLinus Torvalds 	/* Inquiry and Page scans */
197742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
19781da177e4SLinus Torvalds }
19791da177e4SLinus Torvalds 
198042c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt)
19811da177e4SLinus Torvalds {
19821da177e4SLinus Torvalds 	__u8 auth = opt;
19831da177e4SLinus Torvalds 
198442c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, auth);
19851da177e4SLinus Torvalds 
19861da177e4SLinus Torvalds 	/* Authentication */
198742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
19881da177e4SLinus Torvalds }
19891da177e4SLinus Torvalds 
199042c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt)
19911da177e4SLinus Torvalds {
19921da177e4SLinus Torvalds 	__u8 encrypt = opt;
19931da177e4SLinus Torvalds 
199442c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, encrypt);
19951da177e4SLinus Torvalds 
1996e4e8e37cSMarcel Holtmann 	/* Encryption */
199742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
19981da177e4SLinus Torvalds }
19991da177e4SLinus Torvalds 
200042c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt)
2001e4e8e37cSMarcel Holtmann {
2002e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
2003e4e8e37cSMarcel Holtmann 
200442c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, policy);
2005e4e8e37cSMarcel Holtmann 
2006e4e8e37cSMarcel Holtmann 	/* Default link policy */
200742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
2008e4e8e37cSMarcel Holtmann }
2009e4e8e37cSMarcel Holtmann 
20101da177e4SLinus Torvalds /* Get HCI device by index.
20111da177e4SLinus Torvalds  * Device is held on return. */
20121da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
20131da177e4SLinus Torvalds {
20148035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
20151da177e4SLinus Torvalds 
20161da177e4SLinus Torvalds 	BT_DBG("%d", index);
20171da177e4SLinus Torvalds 
20181da177e4SLinus Torvalds 	if (index < 0)
20191da177e4SLinus Torvalds 		return NULL;
20201da177e4SLinus Torvalds 
20211da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
20228035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
20231da177e4SLinus Torvalds 		if (d->id == index) {
20241da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
20251da177e4SLinus Torvalds 			break;
20261da177e4SLinus Torvalds 		}
20271da177e4SLinus Torvalds 	}
20281da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
20291da177e4SLinus Torvalds 	return hdev;
20301da177e4SLinus Torvalds }
20311da177e4SLinus Torvalds 
20321da177e4SLinus Torvalds /* ---- Inquiry support ---- */
2033ff9ef578SJohan Hedberg 
203430dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
203530dc78e1SJohan Hedberg {
203630dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
203730dc78e1SJohan Hedberg 
20386fbe195dSAndre Guedes 	switch (discov->state) {
2039343f935bSAndre Guedes 	case DISCOVERY_FINDING:
20406fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
204130dc78e1SJohan Hedberg 		return true;
204230dc78e1SJohan Hedberg 
20436fbe195dSAndre Guedes 	default:
204430dc78e1SJohan Hedberg 		return false;
204530dc78e1SJohan Hedberg 	}
20466fbe195dSAndre Guedes }
204730dc78e1SJohan Hedberg 
2048ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
2049ff9ef578SJohan Hedberg {
2050bb3e0a33SJohan Hedberg 	int old_state = hdev->discovery.state;
2051bb3e0a33SJohan Hedberg 
2052ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
2053ff9ef578SJohan Hedberg 
2054bb3e0a33SJohan Hedberg 	if (old_state == state)
2055ff9ef578SJohan Hedberg 		return;
2056ff9ef578SJohan Hedberg 
2057bb3e0a33SJohan Hedberg 	hdev->discovery.state = state;
2058bb3e0a33SJohan Hedberg 
2059ff9ef578SJohan Hedberg 	switch (state) {
2060ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
2061c54c3860SAndre Guedes 		hci_update_background_scan(hdev);
2062c54c3860SAndre Guedes 
2063bb3e0a33SJohan Hedberg 		if (old_state != DISCOVERY_STARTING)
2064ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
2065ff9ef578SJohan Hedberg 		break;
2066ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
2067ff9ef578SJohan Hedberg 		break;
2068343f935bSAndre Guedes 	case DISCOVERY_FINDING:
2069ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
2070ff9ef578SJohan Hedberg 		break;
207130dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
207230dc78e1SJohan Hedberg 		break;
2073ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
2074ff9ef578SJohan Hedberg 		break;
2075ff9ef578SJohan Hedberg 	}
2076ff9ef578SJohan Hedberg }
2077ff9ef578SJohan Hedberg 
20781f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev)
20791da177e4SLinus Torvalds {
208030883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
2081b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
20821da177e4SLinus Torvalds 
2083561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
2084561aafbcSJohan Hedberg 		list_del(&p->all);
2085b57c1a56SJohan Hedberg 		kfree(p);
20861da177e4SLinus Torvalds 	}
2087561aafbcSJohan Hedberg 
2088561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
2089561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
20901da177e4SLinus Torvalds }
20911da177e4SLinus Torvalds 
2092a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
2093a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
20941da177e4SLinus Torvalds {
209530883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
20961da177e4SLinus Torvalds 	struct inquiry_entry *e;
20971da177e4SLinus Torvalds 
20986ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
20991da177e4SLinus Torvalds 
2100561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
21011da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
21021da177e4SLinus Torvalds 			return e;
21031da177e4SLinus Torvalds 	}
21041da177e4SLinus Torvalds 
2105b57c1a56SJohan Hedberg 	return NULL;
2106b57c1a56SJohan Hedberg }
2107b57c1a56SJohan Hedberg 
2108561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
2109561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
2110561aafbcSJohan Hedberg {
211130883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
2112561aafbcSJohan Hedberg 	struct inquiry_entry *e;
2113561aafbcSJohan Hedberg 
21146ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
2115561aafbcSJohan Hedberg 
2116561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
2117561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
2118561aafbcSJohan Hedberg 			return e;
2119561aafbcSJohan Hedberg 	}
2120561aafbcSJohan Hedberg 
2121561aafbcSJohan Hedberg 	return NULL;
2122561aafbcSJohan Hedberg }
2123561aafbcSJohan Hedberg 
212430dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
212530dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
212630dc78e1SJohan Hedberg 						       int state)
212730dc78e1SJohan Hedberg {
212830dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
212930dc78e1SJohan Hedberg 	struct inquiry_entry *e;
213030dc78e1SJohan Hedberg 
21316ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
213230dc78e1SJohan Hedberg 
213330dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
213430dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
213530dc78e1SJohan Hedberg 			return e;
213630dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
213730dc78e1SJohan Hedberg 			return e;
213830dc78e1SJohan Hedberg 	}
213930dc78e1SJohan Hedberg 
214030dc78e1SJohan Hedberg 	return NULL;
214130dc78e1SJohan Hedberg }
214230dc78e1SJohan Hedberg 
2143a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
2144a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
2145a3d4e20aSJohan Hedberg {
2146a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
2147a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
2148a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
2149a3d4e20aSJohan Hedberg 
2150a3d4e20aSJohan Hedberg 	list_del(&ie->list);
2151a3d4e20aSJohan Hedberg 
2152a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
2153a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
2154a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
2155a3d4e20aSJohan Hedberg 			break;
2156a3d4e20aSJohan Hedberg 		pos = &p->list;
2157a3d4e20aSJohan Hedberg 	}
2158a3d4e20aSJohan Hedberg 
2159a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
2160a3d4e20aSJohan Hedberg }
2161a3d4e20aSJohan Hedberg 
2162af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
2163af58925cSMarcel Holtmann 			     bool name_known)
21641da177e4SLinus Torvalds {
216530883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
216670f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
2167af58925cSMarcel Holtmann 	u32 flags = 0;
21681da177e4SLinus Torvalds 
21696ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
21701da177e4SLinus Torvalds 
21716928a924SJohan Hedberg 	hci_remove_remote_oob_data(hdev, &data->bdaddr, BDADDR_BREDR);
21722b2fec4dSSzymon Janc 
2173af58925cSMarcel Holtmann 	if (!data->ssp_mode)
2174af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
2175388fc8faSJohan Hedberg 
217670f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
2177a3d4e20aSJohan Hedberg 	if (ie) {
2178af58925cSMarcel Holtmann 		if (!ie->data.ssp_mode)
2179af58925cSMarcel Holtmann 			flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
2180388fc8faSJohan Hedberg 
2181a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
2182a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
2183a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
2184a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
2185a3d4e20aSJohan Hedberg 		}
2186a3d4e20aSJohan Hedberg 
2187561aafbcSJohan Hedberg 		goto update;
2188a3d4e20aSJohan Hedberg 	}
2189561aafbcSJohan Hedberg 
21901da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
219127f70f3eSJohan Hedberg 	ie = kzalloc(sizeof(*ie), GFP_KERNEL);
2192af58925cSMarcel Holtmann 	if (!ie) {
2193af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
2194af58925cSMarcel Holtmann 		goto done;
2195af58925cSMarcel Holtmann 	}
219670f23020SAndrei Emeltchenko 
2197561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
2198561aafbcSJohan Hedberg 
2199561aafbcSJohan Hedberg 	if (name_known) {
2200561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
2201561aafbcSJohan Hedberg 	} else {
2202561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
2203561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
2204561aafbcSJohan Hedberg 	}
2205561aafbcSJohan Hedberg 
2206561aafbcSJohan Hedberg update:
2207561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
2208561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
2209561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
2210561aafbcSJohan Hedberg 		list_del(&ie->list);
22111da177e4SLinus Torvalds 	}
22121da177e4SLinus Torvalds 
221370f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
221470f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
22151da177e4SLinus Torvalds 	cache->timestamp = jiffies;
22163175405bSJohan Hedberg 
22173175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
2218af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
22193175405bSJohan Hedberg 
2220af58925cSMarcel Holtmann done:
2221af58925cSMarcel Holtmann 	return flags;
22221da177e4SLinus Torvalds }
22231da177e4SLinus Torvalds 
22241da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
22251da177e4SLinus Torvalds {
222630883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
22271da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
22281da177e4SLinus Torvalds 	struct inquiry_entry *e;
22291da177e4SLinus Torvalds 	int copied = 0;
22301da177e4SLinus Torvalds 
2231561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
22321da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
2233b57c1a56SJohan Hedberg 
2234b57c1a56SJohan Hedberg 		if (copied >= num)
2235b57c1a56SJohan Hedberg 			break;
2236b57c1a56SJohan Hedberg 
22371da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
22381da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
22391da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
22401da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
22411da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
22421da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
2243b57c1a56SJohan Hedberg 
22441da177e4SLinus Torvalds 		info++;
2245b57c1a56SJohan Hedberg 		copied++;
22461da177e4SLinus Torvalds 	}
22471da177e4SLinus Torvalds 
22481da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
22491da177e4SLinus Torvalds 	return copied;
22501da177e4SLinus Torvalds }
22511da177e4SLinus Torvalds 
225242c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt)
22531da177e4SLinus Torvalds {
22541da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
225542c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
22561da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
22571da177e4SLinus Torvalds 
22581da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
22591da177e4SLinus Torvalds 
22601da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
22611da177e4SLinus Torvalds 		return;
22621da177e4SLinus Torvalds 
22631da177e4SLinus Torvalds 	/* Start Inquiry */
22641da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
22651da177e4SLinus Torvalds 	cp.length  = ir->length;
22661da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
226742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
22681da177e4SLinus Torvalds }
22691da177e4SLinus Torvalds 
22701da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
22711da177e4SLinus Torvalds {
22721da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
22731da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
22741da177e4SLinus Torvalds 	struct hci_dev *hdev;
22751da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
22761da177e4SLinus Torvalds 	long timeo;
22771da177e4SLinus Torvalds 	__u8 *buf;
22781da177e4SLinus Torvalds 
22791da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
22801da177e4SLinus Torvalds 		return -EFAULT;
22811da177e4SLinus Torvalds 
22825a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
22835a08ecceSAndrei Emeltchenko 	if (!hdev)
22841da177e4SLinus Torvalds 		return -ENODEV;
22851da177e4SLinus Torvalds 
22860736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
22870736cfa8SMarcel Holtmann 		err = -EBUSY;
22880736cfa8SMarcel Holtmann 		goto done;
22890736cfa8SMarcel Holtmann 	}
22900736cfa8SMarcel Holtmann 
22914a964404SMarcel Holtmann 	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
2292fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
2293fee746b0SMarcel Holtmann 		goto done;
2294fee746b0SMarcel Holtmann 	}
2295fee746b0SMarcel Holtmann 
22965b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
22975b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
22985b69bef5SMarcel Holtmann 		goto done;
22995b69bef5SMarcel Holtmann 	}
23005b69bef5SMarcel Holtmann 
230156f87901SJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
230256f87901SJohan Hedberg 		err = -EOPNOTSUPP;
230356f87901SJohan Hedberg 		goto done;
230456f87901SJohan Hedberg 	}
230556f87901SJohan Hedberg 
230609fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
23071da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
2308a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
23091f9b9a5dSAndre Guedes 		hci_inquiry_cache_flush(hdev);
23101da177e4SLinus Torvalds 		do_inquiry = 1;
23111da177e4SLinus Torvalds 	}
231209fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
23131da177e4SLinus Torvalds 
231404837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
231570f23020SAndrei Emeltchenko 
231670f23020SAndrei Emeltchenko 	if (do_inquiry) {
231701178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
231801178cd4SJohan Hedberg 				   timeo);
231970f23020SAndrei Emeltchenko 		if (err < 0)
23201da177e4SLinus Torvalds 			goto done;
23213e13fa1eSAndre Guedes 
23223e13fa1eSAndre Guedes 		/* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
23233e13fa1eSAndre Guedes 		 * cleared). If it is interrupted by a signal, return -EINTR.
23243e13fa1eSAndre Guedes 		 */
232574316201SNeilBrown 		if (wait_on_bit(&hdev->flags, HCI_INQUIRY,
23263e13fa1eSAndre Guedes 				TASK_INTERRUPTIBLE))
23273e13fa1eSAndre Guedes 			return -EINTR;
232870f23020SAndrei Emeltchenko 	}
23291da177e4SLinus Torvalds 
23308fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
23318fc9ced3SGustavo Padovan 	 * 255 entries
23328fc9ced3SGustavo Padovan 	 */
23331da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
23341da177e4SLinus Torvalds 
23351da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
23361da177e4SLinus Torvalds 	 * copy it to the user space.
23371da177e4SLinus Torvalds 	 */
233870f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
233970f23020SAndrei Emeltchenko 	if (!buf) {
23401da177e4SLinus Torvalds 		err = -ENOMEM;
23411da177e4SLinus Torvalds 		goto done;
23421da177e4SLinus Torvalds 	}
23431da177e4SLinus Torvalds 
234409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
23451da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
234609fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
23471da177e4SLinus Torvalds 
23481da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
23491da177e4SLinus Torvalds 
23501da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
23511da177e4SLinus Torvalds 		ptr += sizeof(ir);
23521da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
23531da177e4SLinus Torvalds 				 ir.num_rsp))
23541da177e4SLinus Torvalds 			err = -EFAULT;
23551da177e4SLinus Torvalds 	} else
23561da177e4SLinus Torvalds 		err = -EFAULT;
23571da177e4SLinus Torvalds 
23581da177e4SLinus Torvalds 	kfree(buf);
23591da177e4SLinus Torvalds 
23601da177e4SLinus Torvalds done:
23611da177e4SLinus Torvalds 	hci_dev_put(hdev);
23621da177e4SLinus Torvalds 	return err;
23631da177e4SLinus Torvalds }
23641da177e4SLinus Torvalds 
2365cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev)
23661da177e4SLinus Torvalds {
23671da177e4SLinus Torvalds 	int ret = 0;
23681da177e4SLinus Torvalds 
23691da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
23701da177e4SLinus Torvalds 
23711da177e4SLinus Torvalds 	hci_req_lock(hdev);
23721da177e4SLinus Torvalds 
237394324962SJohan Hovold 	if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) {
237494324962SJohan Hovold 		ret = -ENODEV;
237594324962SJohan Hovold 		goto done;
237694324962SJohan Hovold 	}
237794324962SJohan Hovold 
2378d603b76bSMarcel Holtmann 	if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
2379d603b76bSMarcel Holtmann 	    !test_bit(HCI_CONFIG, &hdev->dev_flags)) {
2380a5c8f270SMarcel Holtmann 		/* Check for rfkill but allow the HCI setup stage to
2381a5c8f270SMarcel Holtmann 		 * proceed (which in itself doesn't cause any RF activity).
2382bf543036SJohan Hedberg 		 */
2383a5c8f270SMarcel Holtmann 		if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) {
2384611b30f7SMarcel Holtmann 			ret = -ERFKILL;
2385611b30f7SMarcel Holtmann 			goto done;
2386611b30f7SMarcel Holtmann 		}
2387611b30f7SMarcel Holtmann 
2388a5c8f270SMarcel Holtmann 		/* Check for valid public address or a configured static
2389a5c8f270SMarcel Holtmann 		 * random adddress, but let the HCI setup proceed to
2390a5c8f270SMarcel Holtmann 		 * be able to determine if there is a public address
2391a5c8f270SMarcel Holtmann 		 * or not.
2392a5c8f270SMarcel Holtmann 		 *
2393c6beca0eSMarcel Holtmann 		 * In case of user channel usage, it is not important
2394c6beca0eSMarcel Holtmann 		 * if a public address or static random address is
2395c6beca0eSMarcel Holtmann 		 * available.
2396c6beca0eSMarcel Holtmann 		 *
2397a5c8f270SMarcel Holtmann 		 * This check is only valid for BR/EDR controllers
2398a5c8f270SMarcel Holtmann 		 * since AMP controllers do not have an address.
2399a5c8f270SMarcel Holtmann 		 */
2400c6beca0eSMarcel Holtmann 		if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
2401c6beca0eSMarcel Holtmann 		    hdev->dev_type == HCI_BREDR &&
2402a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
2403a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->static_addr, BDADDR_ANY)) {
2404a5c8f270SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
2405a5c8f270SMarcel Holtmann 			goto done;
2406a5c8f270SMarcel Holtmann 		}
2407a5c8f270SMarcel Holtmann 	}
2408a5c8f270SMarcel Holtmann 
24091da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
24101da177e4SLinus Torvalds 		ret = -EALREADY;
24111da177e4SLinus Torvalds 		goto done;
24121da177e4SLinus Torvalds 	}
24131da177e4SLinus Torvalds 
24141da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
24151da177e4SLinus Torvalds 		ret = -EIO;
24161da177e4SLinus Torvalds 		goto done;
24171da177e4SLinus Torvalds 	}
24181da177e4SLinus Torvalds 
24191da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
24201da177e4SLinus Torvalds 	set_bit(HCI_INIT, &hdev->flags);
2421f41c70c4SMarcel Holtmann 
2422af202f84SMarcel Holtmann 	if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
2423af202f84SMarcel Holtmann 		if (hdev->setup)
2424f41c70c4SMarcel Holtmann 			ret = hdev->setup(hdev);
2425f41c70c4SMarcel Holtmann 
2426af202f84SMarcel Holtmann 		/* The transport driver can set these quirks before
2427af202f84SMarcel Holtmann 		 * creating the HCI device or in its setup callback.
2428af202f84SMarcel Holtmann 		 *
2429af202f84SMarcel Holtmann 		 * In case any of them is set, the controller has to
2430af202f84SMarcel Holtmann 		 * start up as unconfigured.
2431af202f84SMarcel Holtmann 		 */
2432eb1904f4SMarcel Holtmann 		if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) ||
2433eb1904f4SMarcel Holtmann 		    test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks))
243489bc22d2SMarcel Holtmann 			set_bit(HCI_UNCONFIGURED, &hdev->dev_flags);
2435f41c70c4SMarcel Holtmann 
24360ebca7d6SMarcel Holtmann 		/* For an unconfigured controller it is required to
24370ebca7d6SMarcel Holtmann 		 * read at least the version information provided by
24380ebca7d6SMarcel Holtmann 		 * the Read Local Version Information command.
24390ebca7d6SMarcel Holtmann 		 *
24400ebca7d6SMarcel Holtmann 		 * If the set_bdaddr driver callback is provided, then
24410ebca7d6SMarcel Holtmann 		 * also the original Bluetooth public device address
24420ebca7d6SMarcel Holtmann 		 * will be read using the Read BD Address command.
24430ebca7d6SMarcel Holtmann 		 */
24440ebca7d6SMarcel Holtmann 		if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
24450ebca7d6SMarcel Holtmann 			ret = __hci_unconf_init(hdev);
244689bc22d2SMarcel Holtmann 	}
244789bc22d2SMarcel Holtmann 
24489713c17bSMarcel Holtmann 	if (test_bit(HCI_CONFIG, &hdev->dev_flags)) {
24499713c17bSMarcel Holtmann 		/* If public address change is configured, ensure that
24509713c17bSMarcel Holtmann 		 * the address gets programmed. If the driver does not
24519713c17bSMarcel Holtmann 		 * support changing the public address, fail the power
24529713c17bSMarcel Holtmann 		 * on procedure.
245324c457e2SMarcel Holtmann 		 */
24549713c17bSMarcel Holtmann 		if (bacmp(&hdev->public_addr, BDADDR_ANY) &&
24559713c17bSMarcel Holtmann 		    hdev->set_bdaddr)
245624c457e2SMarcel Holtmann 			ret = hdev->set_bdaddr(hdev, &hdev->public_addr);
245724c457e2SMarcel Holtmann 		else
245824c457e2SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
245924c457e2SMarcel Holtmann 	}
246024c457e2SMarcel Holtmann 
2461f41c70c4SMarcel Holtmann 	if (!ret) {
24624a964404SMarcel Holtmann 		if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
24630736cfa8SMarcel Holtmann 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
24642177bab5SJohan Hedberg 			ret = __hci_init(hdev);
24651da177e4SLinus Torvalds 	}
24661da177e4SLinus Torvalds 
2467f41c70c4SMarcel Holtmann 	clear_bit(HCI_INIT, &hdev->flags);
2468f41c70c4SMarcel Holtmann 
24691da177e4SLinus Torvalds 	if (!ret) {
24701da177e4SLinus Torvalds 		hci_dev_hold(hdev);
2471d6bfd59cSJohan Hedberg 		set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags);
24721da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
24731da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
2474bb4b2a9aSAndrei Emeltchenko 		if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
2475d603b76bSMarcel Holtmann 		    !test_bit(HCI_CONFIG, &hdev->dev_flags) &&
24764a964404SMarcel Holtmann 		    !test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
24770736cfa8SMarcel Holtmann 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
24781514b892SMarcel Holtmann 		    hdev->dev_type == HCI_BREDR) {
247909fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
2480744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
248109fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
248256e5cb86SJohan Hedberg 		}
24831da177e4SLinus Torvalds 	} else {
24841da177e4SLinus Torvalds 		/* Init failed, cleanup */
24853eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
2486c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
2487b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
24881da177e4SLinus Torvalds 
24891da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
24901da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
24911da177e4SLinus Torvalds 
24921da177e4SLinus Torvalds 		if (hdev->flush)
24931da177e4SLinus Torvalds 			hdev->flush(hdev);
24941da177e4SLinus Torvalds 
24951da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
24961da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
24971da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
24981da177e4SLinus Torvalds 		}
24991da177e4SLinus Torvalds 
25001da177e4SLinus Torvalds 		hdev->close(hdev);
2501fee746b0SMarcel Holtmann 		hdev->flags &= BIT(HCI_RAW);
25021da177e4SLinus Torvalds 	}
25031da177e4SLinus Torvalds 
25041da177e4SLinus Torvalds done:
25051da177e4SLinus Torvalds 	hci_req_unlock(hdev);
25061da177e4SLinus Torvalds 	return ret;
25071da177e4SLinus Torvalds }
25081da177e4SLinus Torvalds 
2509cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */
2510cbed0ca1SJohan Hedberg 
2511cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev)
2512cbed0ca1SJohan Hedberg {
2513cbed0ca1SJohan Hedberg 	struct hci_dev *hdev;
2514cbed0ca1SJohan Hedberg 	int err;
2515cbed0ca1SJohan Hedberg 
2516cbed0ca1SJohan Hedberg 	hdev = hci_dev_get(dev);
2517cbed0ca1SJohan Hedberg 	if (!hdev)
2518cbed0ca1SJohan Hedberg 		return -ENODEV;
2519cbed0ca1SJohan Hedberg 
25204a964404SMarcel Holtmann 	/* Devices that are marked as unconfigured can only be powered
2521fee746b0SMarcel Holtmann 	 * up as user channel. Trying to bring them up as normal devices
2522fee746b0SMarcel Holtmann 	 * will result into a failure. Only user channel operation is
2523fee746b0SMarcel Holtmann 	 * possible.
2524fee746b0SMarcel Holtmann 	 *
2525fee746b0SMarcel Holtmann 	 * When this function is called for a user channel, the flag
2526fee746b0SMarcel Holtmann 	 * HCI_USER_CHANNEL will be set first before attempting to
2527fee746b0SMarcel Holtmann 	 * open the device.
2528fee746b0SMarcel Holtmann 	 */
25294a964404SMarcel Holtmann 	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
2530fee746b0SMarcel Holtmann 	    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
2531fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
2532fee746b0SMarcel Holtmann 		goto done;
2533fee746b0SMarcel Holtmann 	}
2534fee746b0SMarcel Holtmann 
2535e1d08f40SJohan Hedberg 	/* We need to ensure that no other power on/off work is pending
2536e1d08f40SJohan Hedberg 	 * before proceeding to call hci_dev_do_open. This is
2537e1d08f40SJohan Hedberg 	 * particularly important if the setup procedure has not yet
2538e1d08f40SJohan Hedberg 	 * completed.
2539e1d08f40SJohan Hedberg 	 */
2540e1d08f40SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
2541e1d08f40SJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
2542e1d08f40SJohan Hedberg 
2543a5c8f270SMarcel Holtmann 	/* After this call it is guaranteed that the setup procedure
2544a5c8f270SMarcel Holtmann 	 * has finished. This means that error conditions like RFKILL
2545a5c8f270SMarcel Holtmann 	 * or no valid public or static random address apply.
2546a5c8f270SMarcel Holtmann 	 */
2547e1d08f40SJohan Hedberg 	flush_workqueue(hdev->req_workqueue);
2548e1d08f40SJohan Hedberg 
254912aa4f0aSMarcel Holtmann 	/* For controllers not using the management interface and that
2550b6ae8457SJohan Hedberg 	 * are brought up using legacy ioctl, set the HCI_BONDABLE bit
255112aa4f0aSMarcel Holtmann 	 * so that pairing works for them. Once the management interface
255212aa4f0aSMarcel Holtmann 	 * is in use this bit will be cleared again and userspace has
255312aa4f0aSMarcel Holtmann 	 * to explicitly enable it.
255412aa4f0aSMarcel Holtmann 	 */
255512aa4f0aSMarcel Holtmann 	if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
255612aa4f0aSMarcel Holtmann 	    !test_bit(HCI_MGMT, &hdev->dev_flags))
2557b6ae8457SJohan Hedberg 		set_bit(HCI_BONDABLE, &hdev->dev_flags);
255812aa4f0aSMarcel Holtmann 
2559cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
2560cbed0ca1SJohan Hedberg 
2561fee746b0SMarcel Holtmann done:
2562cbed0ca1SJohan Hedberg 	hci_dev_put(hdev);
2563cbed0ca1SJohan Hedberg 	return err;
2564cbed0ca1SJohan Hedberg }
2565cbed0ca1SJohan Hedberg 
2566d7347f3cSJohan Hedberg /* This function requires the caller holds hdev->lock */
2567d7347f3cSJohan Hedberg static void hci_pend_le_actions_clear(struct hci_dev *hdev)
2568d7347f3cSJohan Hedberg {
2569d7347f3cSJohan Hedberg 	struct hci_conn_params *p;
2570d7347f3cSJohan Hedberg 
2571f161dd41SJohan Hedberg 	list_for_each_entry(p, &hdev->le_conn_params, list) {
2572f161dd41SJohan Hedberg 		if (p->conn) {
2573f161dd41SJohan Hedberg 			hci_conn_drop(p->conn);
2574f8aaf9b6SJohan Hedberg 			hci_conn_put(p->conn);
2575f161dd41SJohan Hedberg 			p->conn = NULL;
2576f161dd41SJohan Hedberg 		}
2577d7347f3cSJohan Hedberg 		list_del_init(&p->action);
2578f161dd41SJohan Hedberg 	}
2579d7347f3cSJohan Hedberg 
2580d7347f3cSJohan Hedberg 	BT_DBG("All LE pending actions cleared");
2581d7347f3cSJohan Hedberg }
2582d7347f3cSJohan Hedberg 
25831da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
25841da177e4SLinus Torvalds {
25851da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
25861da177e4SLinus Torvalds 
258778c04c0bSVinicius Costa Gomes 	cancel_delayed_work(&hdev->power_off);
258878c04c0bSVinicius Costa Gomes 
25891da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
25901da177e4SLinus Torvalds 	hci_req_lock(hdev);
25911da177e4SLinus Torvalds 
25921da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
259365cc2b49SMarcel Holtmann 		cancel_delayed_work_sync(&hdev->cmd_timer);
25941da177e4SLinus Torvalds 		hci_req_unlock(hdev);
25951da177e4SLinus Torvalds 		return 0;
25961da177e4SLinus Torvalds 	}
25971da177e4SLinus Torvalds 
25983eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
25993eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
2600b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
26011da177e4SLinus Torvalds 
260216ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
2603e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
260416ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
26055e5282bbSJohan Hedberg 		clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
2606310a3d48SMarcel Holtmann 		clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
260716ab91abSJohan Hedberg 	}
260816ab91abSJohan Hedberg 
2609a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
26107d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
26117d78525dSJohan Hedberg 
26127ba8b4beSAndre Guedes 	cancel_delayed_work_sync(&hdev->le_scan_disable);
26134518bb0fSJohan Hedberg 
26144518bb0fSJohan Hedberg 	if (test_bit(HCI_MGMT, &hdev->dev_flags))
2615d6bfd59cSJohan Hedberg 		cancel_delayed_work_sync(&hdev->rpa_expired);
26167ba8b4beSAndre Guedes 
261776727c02SJohan Hedberg 	/* Avoid potential lockdep warnings from the *_flush() calls by
261876727c02SJohan Hedberg 	 * ensuring the workqueue is empty up front.
261976727c02SJohan Hedberg 	 */
262076727c02SJohan Hedberg 	drain_workqueue(hdev->workqueue);
262176727c02SJohan Hedberg 
262209fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
26231f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
2624d7347f3cSJohan Hedberg 	hci_pend_le_actions_clear(hdev);
2625f161dd41SJohan Hedberg 	hci_conn_hash_flush(hdev);
262609fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
26271da177e4SLinus Torvalds 
26281da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
26291da177e4SLinus Torvalds 
26301da177e4SLinus Torvalds 	if (hdev->flush)
26311da177e4SLinus Torvalds 		hdev->flush(hdev);
26321da177e4SLinus Torvalds 
26331da177e4SLinus Torvalds 	/* Reset device */
26341da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
26351da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
26364a964404SMarcel Holtmann 	if (!test_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
26374a964404SMarcel Holtmann 	    !test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
2638a6c511c6SSzymon Janc 	    test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
26391da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
264001178cd4SJohan Hedberg 		__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
26411da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
26421da177e4SLinus Torvalds 	}
26431da177e4SLinus Torvalds 
2644c347b765SGustavo F. Padovan 	/* flush cmd  work */
2645c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
26461da177e4SLinus Torvalds 
26471da177e4SLinus Torvalds 	/* Drop queues */
26481da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
26491da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
26501da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
26511da177e4SLinus Torvalds 
26521da177e4SLinus Torvalds 	/* Drop last sent command */
26531da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
265465cc2b49SMarcel Holtmann 		cancel_delayed_work_sync(&hdev->cmd_timer);
26551da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
26561da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
26571da177e4SLinus Torvalds 	}
26581da177e4SLinus Torvalds 
2659b6ddb638SJohan Hedberg 	kfree_skb(hdev->recv_evt);
2660b6ddb638SJohan Hedberg 	hdev->recv_evt = NULL;
2661b6ddb638SJohan Hedberg 
26621da177e4SLinus Torvalds 	/* After this point our queues are empty
26631da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
26641da177e4SLinus Torvalds 	hdev->close(hdev);
26651da177e4SLinus Torvalds 
266635b973c9SJohan Hedberg 	/* Clear flags */
2667fee746b0SMarcel Holtmann 	hdev->flags &= BIT(HCI_RAW);
266835b973c9SJohan Hedberg 	hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
266935b973c9SJohan Hedberg 
267093c311a0SMarcel Holtmann 	if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
267193c311a0SMarcel Holtmann 		if (hdev->dev_type == HCI_BREDR) {
267209fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
2673744cf19eSJohan Hedberg 			mgmt_powered(hdev, 0);
267409fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
26758ee56540SMarcel Holtmann 		}
267693c311a0SMarcel Holtmann 	}
26775add6af8SJohan Hedberg 
2678ced5c338SAndrei Emeltchenko 	/* Controller radio is available but is currently powered down */
2679536619e8SMarcel Holtmann 	hdev->amp_status = AMP_STATUS_POWERED_DOWN;
2680ced5c338SAndrei Emeltchenko 
2681e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
268209b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
26837a4cd51dSMarcel Holtmann 	bacpy(&hdev->random_addr, BDADDR_ANY);
2684e59fda8dSJohan Hedberg 
26851da177e4SLinus Torvalds 	hci_req_unlock(hdev);
26861da177e4SLinus Torvalds 
26871da177e4SLinus Torvalds 	hci_dev_put(hdev);
26881da177e4SLinus Torvalds 	return 0;
26891da177e4SLinus Torvalds }
26901da177e4SLinus Torvalds 
26911da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
26921da177e4SLinus Torvalds {
26931da177e4SLinus Torvalds 	struct hci_dev *hdev;
26941da177e4SLinus Torvalds 	int err;
26951da177e4SLinus Torvalds 
269670f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
269770f23020SAndrei Emeltchenko 	if (!hdev)
26981da177e4SLinus Torvalds 		return -ENODEV;
26998ee56540SMarcel Holtmann 
27000736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
27010736cfa8SMarcel Holtmann 		err = -EBUSY;
27020736cfa8SMarcel Holtmann 		goto done;
27030736cfa8SMarcel Holtmann 	}
27040736cfa8SMarcel Holtmann 
27058ee56540SMarcel Holtmann 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
27068ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
27078ee56540SMarcel Holtmann 
27081da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
27098ee56540SMarcel Holtmann 
27100736cfa8SMarcel Holtmann done:
27111da177e4SLinus Torvalds 	hci_dev_put(hdev);
27121da177e4SLinus Torvalds 	return err;
27131da177e4SLinus Torvalds }
27141da177e4SLinus Torvalds 
27151da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
27161da177e4SLinus Torvalds {
27171da177e4SLinus Torvalds 	struct hci_dev *hdev;
27181da177e4SLinus Torvalds 	int ret = 0;
27191da177e4SLinus Torvalds 
272070f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
272170f23020SAndrei Emeltchenko 	if (!hdev)
27221da177e4SLinus Torvalds 		return -ENODEV;
27231da177e4SLinus Torvalds 
27241da177e4SLinus Torvalds 	hci_req_lock(hdev);
27251da177e4SLinus Torvalds 
2726808a049eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
2727808a049eSMarcel Holtmann 		ret = -ENETDOWN;
27281da177e4SLinus Torvalds 		goto done;
2729808a049eSMarcel Holtmann 	}
27301da177e4SLinus Torvalds 
27310736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
27320736cfa8SMarcel Holtmann 		ret = -EBUSY;
27330736cfa8SMarcel Holtmann 		goto done;
27340736cfa8SMarcel Holtmann 	}
27350736cfa8SMarcel Holtmann 
27364a964404SMarcel Holtmann 	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
2737fee746b0SMarcel Holtmann 		ret = -EOPNOTSUPP;
2738fee746b0SMarcel Holtmann 		goto done;
2739fee746b0SMarcel Holtmann 	}
2740fee746b0SMarcel Holtmann 
27411da177e4SLinus Torvalds 	/* Drop queues */
27421da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
27431da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
27441da177e4SLinus Torvalds 
274576727c02SJohan Hedberg 	/* Avoid potential lockdep warnings from the *_flush() calls by
274676727c02SJohan Hedberg 	 * ensuring the workqueue is empty up front.
274776727c02SJohan Hedberg 	 */
274876727c02SJohan Hedberg 	drain_workqueue(hdev->workqueue);
274976727c02SJohan Hedberg 
275009fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
27511f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
27521da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
275309fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
27541da177e4SLinus Torvalds 
27551da177e4SLinus Torvalds 	if (hdev->flush)
27561da177e4SLinus Torvalds 		hdev->flush(hdev);
27571da177e4SLinus Torvalds 
27581da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
27596ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
27601da177e4SLinus Torvalds 
276101178cd4SJohan Hedberg 	ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
27621da177e4SLinus Torvalds 
27631da177e4SLinus Torvalds done:
27641da177e4SLinus Torvalds 	hci_req_unlock(hdev);
27651da177e4SLinus Torvalds 	hci_dev_put(hdev);
27661da177e4SLinus Torvalds 	return ret;
27671da177e4SLinus Torvalds }
27681da177e4SLinus Torvalds 
27691da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
27701da177e4SLinus Torvalds {
27711da177e4SLinus Torvalds 	struct hci_dev *hdev;
27721da177e4SLinus Torvalds 	int ret = 0;
27731da177e4SLinus Torvalds 
277470f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
277570f23020SAndrei Emeltchenko 	if (!hdev)
27761da177e4SLinus Torvalds 		return -ENODEV;
27771da177e4SLinus Torvalds 
27780736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
27790736cfa8SMarcel Holtmann 		ret = -EBUSY;
27800736cfa8SMarcel Holtmann 		goto done;
27810736cfa8SMarcel Holtmann 	}
27820736cfa8SMarcel Holtmann 
27834a964404SMarcel Holtmann 	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
2784fee746b0SMarcel Holtmann 		ret = -EOPNOTSUPP;
2785fee746b0SMarcel Holtmann 		goto done;
2786fee746b0SMarcel Holtmann 	}
2787fee746b0SMarcel Holtmann 
27881da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
27891da177e4SLinus Torvalds 
27900736cfa8SMarcel Holtmann done:
27911da177e4SLinus Torvalds 	hci_dev_put(hdev);
27921da177e4SLinus Torvalds 	return ret;
27931da177e4SLinus Torvalds }
27941da177e4SLinus Torvalds 
2795123abc08SJohan Hedberg static void hci_update_scan_state(struct hci_dev *hdev, u8 scan)
2796123abc08SJohan Hedberg {
2797bc6d2d04SJohan Hedberg 	bool conn_changed, discov_changed;
2798123abc08SJohan Hedberg 
2799123abc08SJohan Hedberg 	BT_DBG("%s scan 0x%02x", hdev->name, scan);
2800123abc08SJohan Hedberg 
2801123abc08SJohan Hedberg 	if ((scan & SCAN_PAGE))
2802123abc08SJohan Hedberg 		conn_changed = !test_and_set_bit(HCI_CONNECTABLE,
2803123abc08SJohan Hedberg 						 &hdev->dev_flags);
2804123abc08SJohan Hedberg 	else
2805123abc08SJohan Hedberg 		conn_changed = test_and_clear_bit(HCI_CONNECTABLE,
2806123abc08SJohan Hedberg 						  &hdev->dev_flags);
2807123abc08SJohan Hedberg 
2808bc6d2d04SJohan Hedberg 	if ((scan & SCAN_INQUIRY)) {
2809bc6d2d04SJohan Hedberg 		discov_changed = !test_and_set_bit(HCI_DISCOVERABLE,
2810bc6d2d04SJohan Hedberg 						   &hdev->dev_flags);
2811bc6d2d04SJohan Hedberg 	} else {
2812bc6d2d04SJohan Hedberg 		clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
2813bc6d2d04SJohan Hedberg 		discov_changed = test_and_clear_bit(HCI_DISCOVERABLE,
2814bc6d2d04SJohan Hedberg 						    &hdev->dev_flags);
2815bc6d2d04SJohan Hedberg 	}
2816bc6d2d04SJohan Hedberg 
2817123abc08SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2818123abc08SJohan Hedberg 		return;
2819123abc08SJohan Hedberg 
2820bc6d2d04SJohan Hedberg 	if (conn_changed || discov_changed) {
2821bc6d2d04SJohan Hedberg 		/* In case this was disabled through mgmt */
2822bc6d2d04SJohan Hedberg 		set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
2823bc6d2d04SJohan Hedberg 
2824bc6d2d04SJohan Hedberg 		if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags))
2825bc6d2d04SJohan Hedberg 			mgmt_update_adv_data(hdev);
2826bc6d2d04SJohan Hedberg 
2827123abc08SJohan Hedberg 		mgmt_new_settings(hdev);
2828123abc08SJohan Hedberg 	}
2829bc6d2d04SJohan Hedberg }
2830123abc08SJohan Hedberg 
28311da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
28321da177e4SLinus Torvalds {
28331da177e4SLinus Torvalds 	struct hci_dev *hdev;
28341da177e4SLinus Torvalds 	struct hci_dev_req dr;
28351da177e4SLinus Torvalds 	int err = 0;
28361da177e4SLinus Torvalds 
28371da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
28381da177e4SLinus Torvalds 		return -EFAULT;
28391da177e4SLinus Torvalds 
284070f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
284170f23020SAndrei Emeltchenko 	if (!hdev)
28421da177e4SLinus Torvalds 		return -ENODEV;
28431da177e4SLinus Torvalds 
28440736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
28450736cfa8SMarcel Holtmann 		err = -EBUSY;
28460736cfa8SMarcel Holtmann 		goto done;
28470736cfa8SMarcel Holtmann 	}
28480736cfa8SMarcel Holtmann 
28494a964404SMarcel Holtmann 	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
2850fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
2851fee746b0SMarcel Holtmann 		goto done;
2852fee746b0SMarcel Holtmann 	}
2853fee746b0SMarcel Holtmann 
28545b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
28555b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
28565b69bef5SMarcel Holtmann 		goto done;
28575b69bef5SMarcel Holtmann 	}
28585b69bef5SMarcel Holtmann 
285956f87901SJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
286056f87901SJohan Hedberg 		err = -EOPNOTSUPP;
286156f87901SJohan Hedberg 		goto done;
286256f87901SJohan Hedberg 	}
286356f87901SJohan Hedberg 
28641da177e4SLinus Torvalds 	switch (cmd) {
28651da177e4SLinus Torvalds 	case HCISETAUTH:
286601178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
28675f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
28681da177e4SLinus Torvalds 		break;
28691da177e4SLinus Torvalds 
28701da177e4SLinus Torvalds 	case HCISETENCRYPT:
28711da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
28721da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
28731da177e4SLinus Torvalds 			break;
28741da177e4SLinus Torvalds 		}
28751da177e4SLinus Torvalds 
28761da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
28771da177e4SLinus Torvalds 			/* Auth must be enabled first */
287801178cd4SJohan Hedberg 			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
28795f246e89SAndrei Emeltchenko 					   HCI_INIT_TIMEOUT);
28801da177e4SLinus Torvalds 			if (err)
28811da177e4SLinus Torvalds 				break;
28821da177e4SLinus Torvalds 		}
28831da177e4SLinus Torvalds 
288401178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
28855f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
28861da177e4SLinus Torvalds 		break;
28871da177e4SLinus Torvalds 
28881da177e4SLinus Torvalds 	case HCISETSCAN:
288901178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
28905f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
289191a668b0SJohan Hedberg 
2892bc6d2d04SJohan Hedberg 		/* Ensure that the connectable and discoverable states
2893bc6d2d04SJohan Hedberg 		 * get correctly modified as this was a non-mgmt change.
289491a668b0SJohan Hedberg 		 */
2895123abc08SJohan Hedberg 		if (!err)
2896123abc08SJohan Hedberg 			hci_update_scan_state(hdev, dr.dev_opt);
28971da177e4SLinus Torvalds 		break;
28981da177e4SLinus Torvalds 
28991da177e4SLinus Torvalds 	case HCISETLINKPOL:
290001178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
29015f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
29021da177e4SLinus Torvalds 		break;
29031da177e4SLinus Torvalds 
29041da177e4SLinus Torvalds 	case HCISETLINKMODE:
2905e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
2906e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
2907e4e8e37cSMarcel Holtmann 		break;
2908e4e8e37cSMarcel Holtmann 
2909e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
2910e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
29111da177e4SLinus Torvalds 		break;
29121da177e4SLinus Torvalds 
29131da177e4SLinus Torvalds 	case HCISETACLMTU:
29141da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
29151da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
29161da177e4SLinus Torvalds 		break;
29171da177e4SLinus Torvalds 
29181da177e4SLinus Torvalds 	case HCISETSCOMTU:
29191da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
29201da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
29211da177e4SLinus Torvalds 		break;
29221da177e4SLinus Torvalds 
29231da177e4SLinus Torvalds 	default:
29241da177e4SLinus Torvalds 		err = -EINVAL;
29251da177e4SLinus Torvalds 		break;
29261da177e4SLinus Torvalds 	}
2927e4e8e37cSMarcel Holtmann 
29280736cfa8SMarcel Holtmann done:
29291da177e4SLinus Torvalds 	hci_dev_put(hdev);
29301da177e4SLinus Torvalds 	return err;
29311da177e4SLinus Torvalds }
29321da177e4SLinus Torvalds 
29331da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
29341da177e4SLinus Torvalds {
29358035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
29361da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
29371da177e4SLinus Torvalds 	struct hci_dev_req *dr;
29381da177e4SLinus Torvalds 	int n = 0, size, err;
29391da177e4SLinus Torvalds 	__u16 dev_num;
29401da177e4SLinus Torvalds 
29411da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
29421da177e4SLinus Torvalds 		return -EFAULT;
29431da177e4SLinus Torvalds 
29441da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
29451da177e4SLinus Torvalds 		return -EINVAL;
29461da177e4SLinus Torvalds 
29471da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
29481da177e4SLinus Torvalds 
294970f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
295070f23020SAndrei Emeltchenko 	if (!dl)
29511da177e4SLinus Torvalds 		return -ENOMEM;
29521da177e4SLinus Torvalds 
29531da177e4SLinus Torvalds 	dr = dl->dev_req;
29541da177e4SLinus Torvalds 
2955f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
29568035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
29572e84d8dbSMarcel Holtmann 		unsigned long flags = hdev->flags;
2958c542a06cSJohan Hedberg 
29592e84d8dbSMarcel Holtmann 		/* When the auto-off is configured it means the transport
29602e84d8dbSMarcel Holtmann 		 * is running, but in that case still indicate that the
29612e84d8dbSMarcel Holtmann 		 * device is actually down.
29622e84d8dbSMarcel Holtmann 		 */
29632e84d8dbSMarcel Holtmann 		if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
29642e84d8dbSMarcel Holtmann 			flags &= ~BIT(HCI_UP);
2965c542a06cSJohan Hedberg 
29661da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
29672e84d8dbSMarcel Holtmann 		(dr + n)->dev_opt = flags;
2968c542a06cSJohan Hedberg 
29691da177e4SLinus Torvalds 		if (++n >= dev_num)
29701da177e4SLinus Torvalds 			break;
29711da177e4SLinus Torvalds 	}
2972f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
29731da177e4SLinus Torvalds 
29741da177e4SLinus Torvalds 	dl->dev_num = n;
29751da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
29761da177e4SLinus Torvalds 
29771da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
29781da177e4SLinus Torvalds 	kfree(dl);
29791da177e4SLinus Torvalds 
29801da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
29811da177e4SLinus Torvalds }
29821da177e4SLinus Torvalds 
29831da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
29841da177e4SLinus Torvalds {
29851da177e4SLinus Torvalds 	struct hci_dev *hdev;
29861da177e4SLinus Torvalds 	struct hci_dev_info di;
29872e84d8dbSMarcel Holtmann 	unsigned long flags;
29881da177e4SLinus Torvalds 	int err = 0;
29891da177e4SLinus Torvalds 
29901da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
29911da177e4SLinus Torvalds 		return -EFAULT;
29921da177e4SLinus Torvalds 
299370f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
299470f23020SAndrei Emeltchenko 	if (!hdev)
29951da177e4SLinus Torvalds 		return -ENODEV;
29961da177e4SLinus Torvalds 
29972e84d8dbSMarcel Holtmann 	/* When the auto-off is configured it means the transport
29982e84d8dbSMarcel Holtmann 	 * is running, but in that case still indicate that the
29992e84d8dbSMarcel Holtmann 	 * device is actually down.
30002e84d8dbSMarcel Holtmann 	 */
30012e84d8dbSMarcel Holtmann 	if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
30022e84d8dbSMarcel Holtmann 		flags = hdev->flags & ~BIT(HCI_UP);
30032e84d8dbSMarcel Holtmann 	else
30042e84d8dbSMarcel Holtmann 		flags = hdev->flags;
3005c542a06cSJohan Hedberg 
30061da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
30071da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
300860f2a3edSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4);
30092e84d8dbSMarcel Holtmann 	di.flags    = flags;
30101da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
3011572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
30121da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
30131da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
30141da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
30151da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
3016572c7f84SJohan Hedberg 	} else {
3017572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
3018572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
3019572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
3020572c7f84SJohan Hedberg 		di.sco_pkts = 0;
3021572c7f84SJohan Hedberg 	}
30221da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
30231da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
30241da177e4SLinus Torvalds 
30251da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
30261da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
30271da177e4SLinus Torvalds 
30281da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
30291da177e4SLinus Torvalds 		err = -EFAULT;
30301da177e4SLinus Torvalds 
30311da177e4SLinus Torvalds 	hci_dev_put(hdev);
30321da177e4SLinus Torvalds 
30331da177e4SLinus Torvalds 	return err;
30341da177e4SLinus Torvalds }
30351da177e4SLinus Torvalds 
30361da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
30371da177e4SLinus Torvalds 
3038611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
3039611b30f7SMarcel Holtmann {
3040611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
3041611b30f7SMarcel Holtmann 
3042611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
3043611b30f7SMarcel Holtmann 
30440736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
30450736cfa8SMarcel Holtmann 		return -EBUSY;
30460736cfa8SMarcel Holtmann 
30475e130367SJohan Hedberg 	if (blocked) {
30485e130367SJohan Hedberg 		set_bit(HCI_RFKILLED, &hdev->dev_flags);
3049d603b76bSMarcel Holtmann 		if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
3050d603b76bSMarcel Holtmann 		    !test_bit(HCI_CONFIG, &hdev->dev_flags))
3051611b30f7SMarcel Holtmann 			hci_dev_do_close(hdev);
30525e130367SJohan Hedberg 	} else {
30535e130367SJohan Hedberg 		clear_bit(HCI_RFKILLED, &hdev->dev_flags);
30545e130367SJohan Hedberg 	}
3055611b30f7SMarcel Holtmann 
3056611b30f7SMarcel Holtmann 	return 0;
3057611b30f7SMarcel Holtmann }
3058611b30f7SMarcel Holtmann 
3059611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
3060611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
3061611b30f7SMarcel Holtmann };
3062611b30f7SMarcel Holtmann 
3063ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
3064ab81cbf9SJohan Hedberg {
3065ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
306696570ffcSJohan Hedberg 	int err;
3067ab81cbf9SJohan Hedberg 
3068ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
3069ab81cbf9SJohan Hedberg 
3070cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
307196570ffcSJohan Hedberg 	if (err < 0) {
307296570ffcSJohan Hedberg 		mgmt_set_powered_failed(hdev, err);
3073ab81cbf9SJohan Hedberg 		return;
307496570ffcSJohan Hedberg 	}
3075ab81cbf9SJohan Hedberg 
3076a5c8f270SMarcel Holtmann 	/* During the HCI setup phase, a few error conditions are
3077a5c8f270SMarcel Holtmann 	 * ignored and they need to be checked now. If they are still
3078a5c8f270SMarcel Holtmann 	 * valid, it is important to turn the device back off.
3079a5c8f270SMarcel Holtmann 	 */
3080a5c8f270SMarcel Holtmann 	if (test_bit(HCI_RFKILLED, &hdev->dev_flags) ||
30814a964404SMarcel Holtmann 	    test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) ||
3082a5c8f270SMarcel Holtmann 	    (hdev->dev_type == HCI_BREDR &&
3083a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
3084a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->static_addr, BDADDR_ANY))) {
3085bf543036SJohan Hedberg 		clear_bit(HCI_AUTO_OFF, &hdev->dev_flags);
3086bf543036SJohan Hedberg 		hci_dev_do_close(hdev);
3087bf543036SJohan Hedberg 	} else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
308819202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
308919202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
3090bf543036SJohan Hedberg 	}
3091ab81cbf9SJohan Hedberg 
3092fee746b0SMarcel Holtmann 	if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) {
30934a964404SMarcel Holtmann 		/* For unconfigured devices, set the HCI_RAW flag
30944a964404SMarcel Holtmann 		 * so that userspace can easily identify them.
30954a964404SMarcel Holtmann 		 */
30964a964404SMarcel Holtmann 		if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
30974a964404SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
30980602a8adSMarcel Holtmann 
30990602a8adSMarcel Holtmann 		/* For fully configured devices, this will send
31000602a8adSMarcel Holtmann 		 * the Index Added event. For unconfigured devices,
31010602a8adSMarcel Holtmann 		 * it will send Unconfigued Index Added event.
31020602a8adSMarcel Holtmann 		 *
31030602a8adSMarcel Holtmann 		 * Devices with HCI_QUIRK_RAW_DEVICE are ignored
31040602a8adSMarcel Holtmann 		 * and no event will be send.
31050602a8adSMarcel Holtmann 		 */
3106744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
3107d603b76bSMarcel Holtmann 	} else if (test_and_clear_bit(HCI_CONFIG, &hdev->dev_flags)) {
31085ea234d3SMarcel Holtmann 		/* When the controller is now configured, then it
31095ea234d3SMarcel Holtmann 		 * is important to clear the HCI_RAW flag.
31105ea234d3SMarcel Holtmann 		 */
31115ea234d3SMarcel Holtmann 		if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
31125ea234d3SMarcel Holtmann 			clear_bit(HCI_RAW, &hdev->flags);
31135ea234d3SMarcel Holtmann 
3114d603b76bSMarcel Holtmann 		/* Powering on the controller with HCI_CONFIG set only
3115d603b76bSMarcel Holtmann 		 * happens with the transition from unconfigured to
3116d603b76bSMarcel Holtmann 		 * configured. This will send the Index Added event.
3117d603b76bSMarcel Holtmann 		 */
3118d603b76bSMarcel Holtmann 		mgmt_index_added(hdev);
3119ab81cbf9SJohan Hedberg 	}
3120ab81cbf9SJohan Hedberg }
3121ab81cbf9SJohan Hedberg 
3122ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
3123ab81cbf9SJohan Hedberg {
31243243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
31253243553fSJohan Hedberg 					    power_off.work);
3126ab81cbf9SJohan Hedberg 
3127ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
3128ab81cbf9SJohan Hedberg 
31298ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
3130ab81cbf9SJohan Hedberg }
3131ab81cbf9SJohan Hedberg 
313216ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
313316ab91abSJohan Hedberg {
313416ab91abSJohan Hedberg 	struct hci_dev *hdev;
313516ab91abSJohan Hedberg 
313616ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
313716ab91abSJohan Hedberg 
313816ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
313916ab91abSJohan Hedberg 
3140d1967ff8SMarcel Holtmann 	mgmt_discoverable_timeout(hdev);
314116ab91abSJohan Hedberg }
314216ab91abSJohan Hedberg 
314335f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev)
31442aeb9a1aSJohan Hedberg {
31454821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
31462aeb9a1aSJohan Hedberg 
31474821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
31484821002cSJohan Hedberg 		list_del(&uuid->list);
31492aeb9a1aSJohan Hedberg 		kfree(uuid);
31502aeb9a1aSJohan Hedberg 	}
31512aeb9a1aSJohan Hedberg }
31522aeb9a1aSJohan Hedberg 
315335f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev)
315455ed8ca1SJohan Hedberg {
315555ed8ca1SJohan Hedberg 	struct link_key *key;
315655ed8ca1SJohan Hedberg 
31570378b597SJohan Hedberg 	list_for_each_entry_rcu(key, &hdev->link_keys, list) {
31580378b597SJohan Hedberg 		list_del_rcu(&key->list);
31590378b597SJohan Hedberg 		kfree_rcu(key, rcu);
316055ed8ca1SJohan Hedberg 	}
316155ed8ca1SJohan Hedberg }
316255ed8ca1SJohan Hedberg 
316335f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev)
3164b899efafSVinicius Costa Gomes {
3165970d0f1bSJohan Hedberg 	struct smp_ltk *k;
3166b899efafSVinicius Costa Gomes 
3167970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
3168970d0f1bSJohan Hedberg 		list_del_rcu(&k->list);
3169970d0f1bSJohan Hedberg 		kfree_rcu(k, rcu);
3170b899efafSVinicius Costa Gomes 	}
3171b899efafSVinicius Costa Gomes }
3172b899efafSVinicius Costa Gomes 
3173970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev)
3174970c4e46SJohan Hedberg {
3175adae20cbSJohan Hedberg 	struct smp_irk *k;
3176970c4e46SJohan Hedberg 
3177adae20cbSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) {
3178adae20cbSJohan Hedberg 		list_del_rcu(&k->list);
3179adae20cbSJohan Hedberg 		kfree_rcu(k, rcu);
3180970c4e46SJohan Hedberg 	}
3181970c4e46SJohan Hedberg }
3182970c4e46SJohan Hedberg 
318355ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
318455ed8ca1SJohan Hedberg {
318555ed8ca1SJohan Hedberg 	struct link_key *k;
318655ed8ca1SJohan Hedberg 
31870378b597SJohan Hedberg 	rcu_read_lock();
31880378b597SJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->link_keys, list) {
31890378b597SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0) {
31900378b597SJohan Hedberg 			rcu_read_unlock();
319155ed8ca1SJohan Hedberg 			return k;
31920378b597SJohan Hedberg 		}
31930378b597SJohan Hedberg 	}
31940378b597SJohan Hedberg 	rcu_read_unlock();
319555ed8ca1SJohan Hedberg 
319655ed8ca1SJohan Hedberg 	return NULL;
319755ed8ca1SJohan Hedberg }
319855ed8ca1SJohan Hedberg 
3199745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
3200d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
3201d25e28abSJohan Hedberg {
3202d25e28abSJohan Hedberg 	/* Legacy key */
3203d25e28abSJohan Hedberg 	if (key_type < 0x03)
3204745c0ce3SVishal Agarwal 		return true;
3205d25e28abSJohan Hedberg 
3206d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
3207d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
3208745c0ce3SVishal Agarwal 		return false;
3209d25e28abSJohan Hedberg 
3210d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
3211d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
3212745c0ce3SVishal Agarwal 		return false;
3213d25e28abSJohan Hedberg 
3214d25e28abSJohan Hedberg 	/* Security mode 3 case */
3215d25e28abSJohan Hedberg 	if (!conn)
3216745c0ce3SVishal Agarwal 		return true;
3217d25e28abSJohan Hedberg 
3218e3befab9SJohan Hedberg 	/* BR/EDR key derived using SC from an LE link */
3219e3befab9SJohan Hedberg 	if (conn->type == LE_LINK)
3220e3befab9SJohan Hedberg 		return true;
3221e3befab9SJohan Hedberg 
3222d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
3223d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
3224745c0ce3SVishal Agarwal 		return true;
3225d25e28abSJohan Hedberg 
3226d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
3227d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
3228745c0ce3SVishal Agarwal 		return true;
3229d25e28abSJohan Hedberg 
3230d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
3231d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
3232745c0ce3SVishal Agarwal 		return true;
3233d25e28abSJohan Hedberg 
3234d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
3235d25e28abSJohan Hedberg 	 * persistently */
3236745c0ce3SVishal Agarwal 	return false;
3237d25e28abSJohan Hedberg }
3238d25e28abSJohan Hedberg 
3239e804d25dSJohan Hedberg static u8 ltk_role(u8 type)
324098a0b845SJohan Hedberg {
3241e804d25dSJohan Hedberg 	if (type == SMP_LTK)
3242e804d25dSJohan Hedberg 		return HCI_ROLE_MASTER;
324398a0b845SJohan Hedberg 
3244e804d25dSJohan Hedberg 	return HCI_ROLE_SLAVE;
324598a0b845SJohan Hedberg }
324698a0b845SJohan Hedberg 
3247f3a73d97SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
3248e804d25dSJohan Hedberg 			     u8 addr_type, u8 role)
324975d262c2SVinicius Costa Gomes {
3250c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
325175d262c2SVinicius Costa Gomes 
3252970d0f1bSJohan Hedberg 	rcu_read_lock();
3253970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
32545378bc56SJohan Hedberg 		if (addr_type != k->bdaddr_type || bacmp(bdaddr, &k->bdaddr))
32555378bc56SJohan Hedberg 			continue;
32565378bc56SJohan Hedberg 
3257923e2414SJohan Hedberg 		if (smp_ltk_is_sc(k) || ltk_role(k->type) == role) {
3258970d0f1bSJohan Hedberg 			rcu_read_unlock();
325975d262c2SVinicius Costa Gomes 			return k;
3260970d0f1bSJohan Hedberg 		}
3261970d0f1bSJohan Hedberg 	}
3262970d0f1bSJohan Hedberg 	rcu_read_unlock();
326375d262c2SVinicius Costa Gomes 
326475d262c2SVinicius Costa Gomes 	return NULL;
326575d262c2SVinicius Costa Gomes }
326675d262c2SVinicius Costa Gomes 
3267970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa)
3268970c4e46SJohan Hedberg {
3269970c4e46SJohan Hedberg 	struct smp_irk *irk;
3270970c4e46SJohan Hedberg 
3271adae20cbSJohan Hedberg 	rcu_read_lock();
3272adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
3273adae20cbSJohan Hedberg 		if (!bacmp(&irk->rpa, rpa)) {
3274adae20cbSJohan Hedberg 			rcu_read_unlock();
3275970c4e46SJohan Hedberg 			return irk;
3276970c4e46SJohan Hedberg 		}
3277adae20cbSJohan Hedberg 	}
3278970c4e46SJohan Hedberg 
3279adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
3280defce9e8SJohan Hedberg 		if (smp_irk_matches(hdev, irk->val, rpa)) {
3281970c4e46SJohan Hedberg 			bacpy(&irk->rpa, rpa);
3282adae20cbSJohan Hedberg 			rcu_read_unlock();
3283970c4e46SJohan Hedberg 			return irk;
3284970c4e46SJohan Hedberg 		}
3285970c4e46SJohan Hedberg 	}
3286adae20cbSJohan Hedberg 	rcu_read_unlock();
3287970c4e46SJohan Hedberg 
3288970c4e46SJohan Hedberg 	return NULL;
3289970c4e46SJohan Hedberg }
3290970c4e46SJohan Hedberg 
3291970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
3292970c4e46SJohan Hedberg 				     u8 addr_type)
3293970c4e46SJohan Hedberg {
3294970c4e46SJohan Hedberg 	struct smp_irk *irk;
3295970c4e46SJohan Hedberg 
32966cfc9988SJohan Hedberg 	/* Identity Address must be public or static random */
32976cfc9988SJohan Hedberg 	if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0)
32986cfc9988SJohan Hedberg 		return NULL;
32996cfc9988SJohan Hedberg 
3300adae20cbSJohan Hedberg 	rcu_read_lock();
3301adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
3302970c4e46SJohan Hedberg 		if (addr_type == irk->addr_type &&
3303adae20cbSJohan Hedberg 		    bacmp(bdaddr, &irk->bdaddr) == 0) {
3304adae20cbSJohan Hedberg 			rcu_read_unlock();
3305970c4e46SJohan Hedberg 			return irk;
3306970c4e46SJohan Hedberg 		}
3307adae20cbSJohan Hedberg 	}
3308adae20cbSJohan Hedberg 	rcu_read_unlock();
3309970c4e46SJohan Hedberg 
3310970c4e46SJohan Hedberg 	return NULL;
3311970c4e46SJohan Hedberg }
3312970c4e46SJohan Hedberg 
3313567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn,
33147652ff6aSJohan Hedberg 				  bdaddr_t *bdaddr, u8 *val, u8 type,
33157652ff6aSJohan Hedberg 				  u8 pin_len, bool *persistent)
331655ed8ca1SJohan Hedberg {
331755ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
3318745c0ce3SVishal Agarwal 	u8 old_key_type;
331955ed8ca1SJohan Hedberg 
332055ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
332155ed8ca1SJohan Hedberg 	if (old_key) {
332255ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
332355ed8ca1SJohan Hedberg 		key = old_key;
332455ed8ca1SJohan Hedberg 	} else {
332512adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
33260a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
332755ed8ca1SJohan Hedberg 		if (!key)
3328567fa2aaSJohan Hedberg 			return NULL;
33290378b597SJohan Hedberg 		list_add_rcu(&key->list, &hdev->link_keys);
333055ed8ca1SJohan Hedberg 	}
333155ed8ca1SJohan Hedberg 
33326ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
333355ed8ca1SJohan Hedberg 
3334d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
3335d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
3336d25e28abSJohan Hedberg 	 * previous key */
3337d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
3338a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
3339d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
3340655fe6ecSJohan Hedberg 		if (conn)
3341655fe6ecSJohan Hedberg 			conn->key_type = type;
3342655fe6ecSJohan Hedberg 	}
3343d25e28abSJohan Hedberg 
334455ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
33459b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
334655ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
334755ed8ca1SJohan Hedberg 
3348b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
334955ed8ca1SJohan Hedberg 		key->type = old_key_type;
33504748fed2SJohan Hedberg 	else
33514748fed2SJohan Hedberg 		key->type = type;
33524748fed2SJohan Hedberg 
33537652ff6aSJohan Hedberg 	if (persistent)
33547652ff6aSJohan Hedberg 		*persistent = hci_persistent_key(hdev, conn, type,
33557652ff6aSJohan Hedberg 						 old_key_type);
33564df378a1SJohan Hedberg 
3357567fa2aaSJohan Hedberg 	return key;
335855ed8ca1SJohan Hedberg }
335955ed8ca1SJohan Hedberg 
3360ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
336135d70271SJohan Hedberg 			    u8 addr_type, u8 type, u8 authenticated,
3362fe39c7b2SMarcel Holtmann 			    u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand)
336375d262c2SVinicius Costa Gomes {
3364c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
3365e804d25dSJohan Hedberg 	u8 role = ltk_role(type);
336675d262c2SVinicius Costa Gomes 
3367f3a73d97SJohan Hedberg 	old_key = hci_find_ltk(hdev, bdaddr, addr_type, role);
3368c9839a11SVinicius Costa Gomes 	if (old_key)
336975d262c2SVinicius Costa Gomes 		key = old_key;
3370c9839a11SVinicius Costa Gomes 	else {
33710a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
337275d262c2SVinicius Costa Gomes 		if (!key)
3373ca9142b8SJohan Hedberg 			return NULL;
3374970d0f1bSJohan Hedberg 		list_add_rcu(&key->list, &hdev->long_term_keys);
337575d262c2SVinicius Costa Gomes 	}
337675d262c2SVinicius Costa Gomes 
337775d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
3378c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
3379c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
3380c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
3381c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
3382fe39c7b2SMarcel Holtmann 	key->rand = rand;
3383c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
3384c9839a11SVinicius Costa Gomes 	key->type = type;
338575d262c2SVinicius Costa Gomes 
3386ca9142b8SJohan Hedberg 	return key;
338775d262c2SVinicius Costa Gomes }
338875d262c2SVinicius Costa Gomes 
3389ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr,
3390ca9142b8SJohan Hedberg 			    u8 addr_type, u8 val[16], bdaddr_t *rpa)
3391970c4e46SJohan Hedberg {
3392970c4e46SJohan Hedberg 	struct smp_irk *irk;
3393970c4e46SJohan Hedberg 
3394970c4e46SJohan Hedberg 	irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type);
3395970c4e46SJohan Hedberg 	if (!irk) {
3396970c4e46SJohan Hedberg 		irk = kzalloc(sizeof(*irk), GFP_KERNEL);
3397970c4e46SJohan Hedberg 		if (!irk)
3398ca9142b8SJohan Hedberg 			return NULL;
3399970c4e46SJohan Hedberg 
3400970c4e46SJohan Hedberg 		bacpy(&irk->bdaddr, bdaddr);
3401970c4e46SJohan Hedberg 		irk->addr_type = addr_type;
3402970c4e46SJohan Hedberg 
3403adae20cbSJohan Hedberg 		list_add_rcu(&irk->list, &hdev->identity_resolving_keys);
3404970c4e46SJohan Hedberg 	}
3405970c4e46SJohan Hedberg 
3406970c4e46SJohan Hedberg 	memcpy(irk->val, val, 16);
3407970c4e46SJohan Hedberg 	bacpy(&irk->rpa, rpa);
3408970c4e46SJohan Hedberg 
3409ca9142b8SJohan Hedberg 	return irk;
3410970c4e46SJohan Hedberg }
3411970c4e46SJohan Hedberg 
341255ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
341355ed8ca1SJohan Hedberg {
341455ed8ca1SJohan Hedberg 	struct link_key *key;
341555ed8ca1SJohan Hedberg 
341655ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
341755ed8ca1SJohan Hedberg 	if (!key)
341855ed8ca1SJohan Hedberg 		return -ENOENT;
341955ed8ca1SJohan Hedberg 
34206ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
342155ed8ca1SJohan Hedberg 
34220378b597SJohan Hedberg 	list_del_rcu(&key->list);
34230378b597SJohan Hedberg 	kfree_rcu(key, rcu);
342455ed8ca1SJohan Hedberg 
342555ed8ca1SJohan Hedberg 	return 0;
342655ed8ca1SJohan Hedberg }
342755ed8ca1SJohan Hedberg 
3428e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type)
3429b899efafSVinicius Costa Gomes {
3430970d0f1bSJohan Hedberg 	struct smp_ltk *k;
3431c51ffa0bSJohan Hedberg 	int removed = 0;
3432b899efafSVinicius Costa Gomes 
3433970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
3434e0b2b27eSJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type)
3435b899efafSVinicius Costa Gomes 			continue;
3436b899efafSVinicius Costa Gomes 
34376ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
3438b899efafSVinicius Costa Gomes 
3439970d0f1bSJohan Hedberg 		list_del_rcu(&k->list);
3440970d0f1bSJohan Hedberg 		kfree_rcu(k, rcu);
3441c51ffa0bSJohan Hedberg 		removed++;
3442b899efafSVinicius Costa Gomes 	}
3443b899efafSVinicius Costa Gomes 
3444c51ffa0bSJohan Hedberg 	return removed ? 0 : -ENOENT;
3445b899efafSVinicius Costa Gomes }
3446b899efafSVinicius Costa Gomes 
3447a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type)
3448a7ec7338SJohan Hedberg {
3449adae20cbSJohan Hedberg 	struct smp_irk *k;
3450a7ec7338SJohan Hedberg 
3451adae20cbSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) {
3452a7ec7338SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type)
3453a7ec7338SJohan Hedberg 			continue;
3454a7ec7338SJohan Hedberg 
3455a7ec7338SJohan Hedberg 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
3456a7ec7338SJohan Hedberg 
3457adae20cbSJohan Hedberg 		list_del_rcu(&k->list);
3458adae20cbSJohan Hedberg 		kfree_rcu(k, rcu);
3459a7ec7338SJohan Hedberg 	}
3460a7ec7338SJohan Hedberg }
3461a7ec7338SJohan Hedberg 
34626bd32326SVille Tervo /* HCI command timer function */
346365cc2b49SMarcel Holtmann static void hci_cmd_timeout(struct work_struct *work)
34646bd32326SVille Tervo {
346565cc2b49SMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev,
346665cc2b49SMarcel Holtmann 					    cmd_timer.work);
34676bd32326SVille Tervo 
3468bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
3469bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
3470bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
3471bda4f23aSAndrei Emeltchenko 
3472bda4f23aSAndrei Emeltchenko 		BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode);
3473bda4f23aSAndrei Emeltchenko 	} else {
34746bd32326SVille Tervo 		BT_ERR("%s command tx timeout", hdev->name);
3475bda4f23aSAndrei Emeltchenko 	}
3476bda4f23aSAndrei Emeltchenko 
34776bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
3478c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
34796bd32326SVille Tervo }
34806bd32326SVille Tervo 
34812763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
34826928a924SJohan Hedberg 					  bdaddr_t *bdaddr, u8 bdaddr_type)
34832763eda6SSzymon Janc {
34842763eda6SSzymon Janc 	struct oob_data *data;
34852763eda6SSzymon Janc 
34866928a924SJohan Hedberg 	list_for_each_entry(data, &hdev->remote_oob_data, list) {
34876928a924SJohan Hedberg 		if (bacmp(bdaddr, &data->bdaddr) != 0)
34886928a924SJohan Hedberg 			continue;
34896928a924SJohan Hedberg 		if (data->bdaddr_type != bdaddr_type)
34906928a924SJohan Hedberg 			continue;
34912763eda6SSzymon Janc 		return data;
34926928a924SJohan Hedberg 	}
34932763eda6SSzymon Janc 
34942763eda6SSzymon Janc 	return NULL;
34952763eda6SSzymon Janc }
34962763eda6SSzymon Janc 
34976928a924SJohan Hedberg int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
34986928a924SJohan Hedberg 			       u8 bdaddr_type)
34992763eda6SSzymon Janc {
35002763eda6SSzymon Janc 	struct oob_data *data;
35012763eda6SSzymon Janc 
35026928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
35032763eda6SSzymon Janc 	if (!data)
35042763eda6SSzymon Janc 		return -ENOENT;
35052763eda6SSzymon Janc 
35066928a924SJohan Hedberg 	BT_DBG("%s removing %pMR (%u)", hdev->name, bdaddr, bdaddr_type);
35072763eda6SSzymon Janc 
35082763eda6SSzymon Janc 	list_del(&data->list);
35092763eda6SSzymon Janc 	kfree(data);
35102763eda6SSzymon Janc 
35112763eda6SSzymon Janc 	return 0;
35122763eda6SSzymon Janc }
35132763eda6SSzymon Janc 
351435f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev)
35152763eda6SSzymon Janc {
35162763eda6SSzymon Janc 	struct oob_data *data, *n;
35172763eda6SSzymon Janc 
35182763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
35192763eda6SSzymon Janc 		list_del(&data->list);
35202763eda6SSzymon Janc 		kfree(data);
35212763eda6SSzymon Janc 	}
35222763eda6SSzymon Janc }
35232763eda6SSzymon Janc 
35240798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
35256928a924SJohan Hedberg 			    u8 bdaddr_type, u8 *hash192, u8 *rand192,
352638da1703SJohan Hedberg 			    u8 *hash256, u8 *rand256)
35270798872eSMarcel Holtmann {
35280798872eSMarcel Holtmann 	struct oob_data *data;
35290798872eSMarcel Holtmann 
35306928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
35310798872eSMarcel Holtmann 	if (!data) {
35320a14ab41SJohan Hedberg 		data = kmalloc(sizeof(*data), GFP_KERNEL);
35330798872eSMarcel Holtmann 		if (!data)
35340798872eSMarcel Holtmann 			return -ENOMEM;
35350798872eSMarcel Holtmann 
35360798872eSMarcel Holtmann 		bacpy(&data->bdaddr, bdaddr);
35376928a924SJohan Hedberg 		data->bdaddr_type = bdaddr_type;
35380798872eSMarcel Holtmann 		list_add(&data->list, &hdev->remote_oob_data);
35390798872eSMarcel Holtmann 	}
35400798872eSMarcel Holtmann 
354181328d5cSJohan Hedberg 	if (hash192 && rand192) {
35420798872eSMarcel Holtmann 		memcpy(data->hash192, hash192, sizeof(data->hash192));
354338da1703SJohan Hedberg 		memcpy(data->rand192, rand192, sizeof(data->rand192));
354481328d5cSJohan Hedberg 	} else {
354581328d5cSJohan Hedberg 		memset(data->hash192, 0, sizeof(data->hash192));
354681328d5cSJohan Hedberg 		memset(data->rand192, 0, sizeof(data->rand192));
354781328d5cSJohan Hedberg 	}
35480798872eSMarcel Holtmann 
354981328d5cSJohan Hedberg 	if (hash256 && rand256) {
35500798872eSMarcel Holtmann 		memcpy(data->hash256, hash256, sizeof(data->hash256));
355138da1703SJohan Hedberg 		memcpy(data->rand256, rand256, sizeof(data->rand256));
355281328d5cSJohan Hedberg 	} else {
355381328d5cSJohan Hedberg 		memset(data->hash256, 0, sizeof(data->hash256));
355481328d5cSJohan Hedberg 		memset(data->rand256, 0, sizeof(data->rand256));
355581328d5cSJohan Hedberg 	}
35560798872eSMarcel Holtmann 
35576ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
35582763eda6SSzymon Janc 
35592763eda6SSzymon Janc 	return 0;
35602763eda6SSzymon Janc }
35612763eda6SSzymon Janc 
3562dcc36c16SJohan Hedberg struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
3563b9ee0a78SMarcel Holtmann 					 bdaddr_t *bdaddr, u8 type)
3564b2a66aadSAntti Julku {
3565b2a66aadSAntti Julku 	struct bdaddr_list *b;
3566b2a66aadSAntti Julku 
3567dcc36c16SJohan Hedberg 	list_for_each_entry(b, bdaddr_list, list) {
3568b9ee0a78SMarcel Holtmann 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
3569b2a66aadSAntti Julku 			return b;
3570b9ee0a78SMarcel Holtmann 	}
3571b2a66aadSAntti Julku 
3572b2a66aadSAntti Julku 	return NULL;
3573b2a66aadSAntti Julku }
3574b2a66aadSAntti Julku 
3575dcc36c16SJohan Hedberg void hci_bdaddr_list_clear(struct list_head *bdaddr_list)
3576b2a66aadSAntti Julku {
3577b2a66aadSAntti Julku 	struct list_head *p, *n;
3578b2a66aadSAntti Julku 
3579dcc36c16SJohan Hedberg 	list_for_each_safe(p, n, bdaddr_list) {
3580b9ee0a78SMarcel Holtmann 		struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list);
3581b2a66aadSAntti Julku 
3582b2a66aadSAntti Julku 		list_del(p);
3583b2a66aadSAntti Julku 		kfree(b);
3584b2a66aadSAntti Julku 	}
3585b2a66aadSAntti Julku }
3586b2a66aadSAntti Julku 
3587dcc36c16SJohan Hedberg int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type)
3588b2a66aadSAntti Julku {
3589b2a66aadSAntti Julku 	struct bdaddr_list *entry;
3590b2a66aadSAntti Julku 
3591b9ee0a78SMarcel Holtmann 	if (!bacmp(bdaddr, BDADDR_ANY))
3592b2a66aadSAntti Julku 		return -EBADF;
3593b2a66aadSAntti Julku 
3594dcc36c16SJohan Hedberg 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
35955e762444SAntti Julku 		return -EEXIST;
3596b2a66aadSAntti Julku 
359727f70f3eSJohan Hedberg 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
35985e762444SAntti Julku 	if (!entry)
35995e762444SAntti Julku 		return -ENOMEM;
3600b2a66aadSAntti Julku 
3601b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
3602b9ee0a78SMarcel Holtmann 	entry->bdaddr_type = type;
3603b2a66aadSAntti Julku 
3604dcc36c16SJohan Hedberg 	list_add(&entry->list, list);
3605b2a66aadSAntti Julku 
36062a8357f2SJohan Hedberg 	return 0;
3607b2a66aadSAntti Julku }
3608b2a66aadSAntti Julku 
3609dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type)
3610b2a66aadSAntti Julku {
3611b2a66aadSAntti Julku 	struct bdaddr_list *entry;
3612b2a66aadSAntti Julku 
361335f7498aSJohan Hedberg 	if (!bacmp(bdaddr, BDADDR_ANY)) {
3614dcc36c16SJohan Hedberg 		hci_bdaddr_list_clear(list);
361535f7498aSJohan Hedberg 		return 0;
361635f7498aSJohan Hedberg 	}
3617b2a66aadSAntti Julku 
3618dcc36c16SJohan Hedberg 	entry = hci_bdaddr_list_lookup(list, bdaddr, type);
3619d2ab0ac1SMarcel Holtmann 	if (!entry)
3620d2ab0ac1SMarcel Holtmann 		return -ENOENT;
3621d2ab0ac1SMarcel Holtmann 
3622d2ab0ac1SMarcel Holtmann 	list_del(&entry->list);
3623d2ab0ac1SMarcel Holtmann 	kfree(entry);
3624d2ab0ac1SMarcel Holtmann 
3625d2ab0ac1SMarcel Holtmann 	return 0;
3626d2ab0ac1SMarcel Holtmann }
3627d2ab0ac1SMarcel Holtmann 
362815819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
362915819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
363015819a70SAndre Guedes 					       bdaddr_t *addr, u8 addr_type)
363115819a70SAndre Guedes {
363215819a70SAndre Guedes 	struct hci_conn_params *params;
363315819a70SAndre Guedes 
3634738f6185SJohan Hedberg 	/* The conn params list only contains identity addresses */
3635738f6185SJohan Hedberg 	if (!hci_is_identity_address(addr, addr_type))
3636738f6185SJohan Hedberg 		return NULL;
3637738f6185SJohan Hedberg 
363815819a70SAndre Guedes 	list_for_each_entry(params, &hdev->le_conn_params, list) {
363915819a70SAndre Guedes 		if (bacmp(&params->addr, addr) == 0 &&
364015819a70SAndre Guedes 		    params->addr_type == addr_type) {
364115819a70SAndre Guedes 			return params;
364215819a70SAndre Guedes 		}
364315819a70SAndre Guedes 	}
364415819a70SAndre Guedes 
364515819a70SAndre Guedes 	return NULL;
364615819a70SAndre Guedes }
364715819a70SAndre Guedes 
3648cef952ceSAndre Guedes static bool is_connected(struct hci_dev *hdev, bdaddr_t *addr, u8 type)
3649cef952ceSAndre Guedes {
3650cef952ceSAndre Guedes 	struct hci_conn *conn;
3651cef952ceSAndre Guedes 
3652cef952ceSAndre Guedes 	conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, addr);
3653cef952ceSAndre Guedes 	if (!conn)
3654cef952ceSAndre Guedes 		return false;
3655cef952ceSAndre Guedes 
3656cef952ceSAndre Guedes 	if (conn->dst_type != type)
3657cef952ceSAndre Guedes 		return false;
3658cef952ceSAndre Guedes 
3659cef952ceSAndre Guedes 	if (conn->state != BT_CONNECTED)
3660cef952ceSAndre Guedes 		return false;
3661cef952ceSAndre Guedes 
3662cef952ceSAndre Guedes 	return true;
3663cef952ceSAndre Guedes }
3664cef952ceSAndre Guedes 
366515819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
3666501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list,
36674b10966fSMarcel Holtmann 						  bdaddr_t *addr, u8 addr_type)
366815819a70SAndre Guedes {
3669912b42efSJohan Hedberg 	struct hci_conn_params *param;
367015819a70SAndre Guedes 
3671738f6185SJohan Hedberg 	/* The list only contains identity addresses */
3672738f6185SJohan Hedberg 	if (!hci_is_identity_address(addr, addr_type))
3673738f6185SJohan Hedberg 		return NULL;
367415819a70SAndre Guedes 
3675501f8827SJohan Hedberg 	list_for_each_entry(param, list, action) {
3676912b42efSJohan Hedberg 		if (bacmp(&param->addr, addr) == 0 &&
3677912b42efSJohan Hedberg 		    param->addr_type == addr_type)
3678912b42efSJohan Hedberg 			return param;
36794b10966fSMarcel Holtmann 	}
36804b10966fSMarcel Holtmann 
36814b10966fSMarcel Holtmann 	return NULL;
368215819a70SAndre Guedes }
368315819a70SAndre Guedes 
368415819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
368551d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev,
368651d167c0SMarcel Holtmann 					    bdaddr_t *addr, u8 addr_type)
368715819a70SAndre Guedes {
368815819a70SAndre Guedes 	struct hci_conn_params *params;
368915819a70SAndre Guedes 
3690c46245b3SJohan Hedberg 	if (!hci_is_identity_address(addr, addr_type))
369151d167c0SMarcel Holtmann 		return NULL;
3692a9b0a04cSAndre Guedes 
369315819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
3694cef952ceSAndre Guedes 	if (params)
369551d167c0SMarcel Holtmann 		return params;
369615819a70SAndre Guedes 
369715819a70SAndre Guedes 	params = kzalloc(sizeof(*params), GFP_KERNEL);
369815819a70SAndre Guedes 	if (!params) {
369915819a70SAndre Guedes 		BT_ERR("Out of memory");
370051d167c0SMarcel Holtmann 		return NULL;
370115819a70SAndre Guedes 	}
370215819a70SAndre Guedes 
370315819a70SAndre Guedes 	bacpy(&params->addr, addr);
370415819a70SAndre Guedes 	params->addr_type = addr_type;
3705cef952ceSAndre Guedes 
3706cef952ceSAndre Guedes 	list_add(&params->list, &hdev->le_conn_params);
370793450c75SJohan Hedberg 	INIT_LIST_HEAD(&params->action);
3708cef952ceSAndre Guedes 
3709bf5b3c8bSMarcel Holtmann 	params->conn_min_interval = hdev->le_conn_min_interval;
3710bf5b3c8bSMarcel Holtmann 	params->conn_max_interval = hdev->le_conn_max_interval;
3711bf5b3c8bSMarcel Holtmann 	params->conn_latency = hdev->le_conn_latency;
3712bf5b3c8bSMarcel Holtmann 	params->supervision_timeout = hdev->le_supv_timeout;
3713bf5b3c8bSMarcel Holtmann 	params->auto_connect = HCI_AUTO_CONN_DISABLED;
3714bf5b3c8bSMarcel Holtmann 
3715bf5b3c8bSMarcel Holtmann 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
3716bf5b3c8bSMarcel Holtmann 
371751d167c0SMarcel Holtmann 	return params;
3718bf5b3c8bSMarcel Holtmann }
3719bf5b3c8bSMarcel Holtmann 
3720bf5b3c8bSMarcel Holtmann /* This function requires the caller holds hdev->lock */
3721bf5b3c8bSMarcel Holtmann int hci_conn_params_set(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
3722d06b50ceSMarcel Holtmann 			u8 auto_connect)
372315819a70SAndre Guedes {
372415819a70SAndre Guedes 	struct hci_conn_params *params;
372515819a70SAndre Guedes 
37268c87aae1SMarcel Holtmann 	params = hci_conn_params_add(hdev, addr, addr_type);
37278c87aae1SMarcel Holtmann 	if (!params)
37288c87aae1SMarcel Holtmann 		return -EIO;
372915819a70SAndre Guedes 
373042ce26deSJohan Hedberg 	if (params->auto_connect == auto_connect)
373142ce26deSJohan Hedberg 		return 0;
373242ce26deSJohan Hedberg 
373366f8455aSJohan Hedberg 	list_del_init(&params->action);
373415819a70SAndre Guedes 
3735cef952ceSAndre Guedes 	switch (auto_connect) {
3736cef952ceSAndre Guedes 	case HCI_AUTO_CONN_DISABLED:
3737cef952ceSAndre Guedes 	case HCI_AUTO_CONN_LINK_LOSS:
373895305baaSJohan Hedberg 		hci_update_background_scan(hdev);
3739cef952ceSAndre Guedes 		break;
3740851efca8SJohan Hedberg 	case HCI_AUTO_CONN_REPORT:
374195305baaSJohan Hedberg 		list_add(&params->action, &hdev->pend_le_reports);
374295305baaSJohan Hedberg 		hci_update_background_scan(hdev);
3743851efca8SJohan Hedberg 		break;
37444b9e7e75SMarcel Holtmann 	case HCI_AUTO_CONN_DIRECT:
3745cef952ceSAndre Guedes 	case HCI_AUTO_CONN_ALWAYS:
374695305baaSJohan Hedberg 		if (!is_connected(hdev, addr, addr_type)) {
374795305baaSJohan Hedberg 			list_add(&params->action, &hdev->pend_le_conns);
374895305baaSJohan Hedberg 			hci_update_background_scan(hdev);
374995305baaSJohan Hedberg 		}
3750cef952ceSAndre Guedes 		break;
3751cef952ceSAndre Guedes 	}
375215819a70SAndre Guedes 
3753851efca8SJohan Hedberg 	params->auto_connect = auto_connect;
3754851efca8SJohan Hedberg 
3755d06b50ceSMarcel Holtmann 	BT_DBG("addr %pMR (type %u) auto_connect %u", addr, addr_type,
3756d06b50ceSMarcel Holtmann 	       auto_connect);
3757a9b0a04cSAndre Guedes 
3758a9b0a04cSAndre Guedes 	return 0;
375915819a70SAndre Guedes }
376015819a70SAndre Guedes 
3761f6c63249SJohan Hedberg static void hci_conn_params_free(struct hci_conn_params *params)
3762f6c63249SJohan Hedberg {
3763f6c63249SJohan Hedberg 	if (params->conn) {
3764f6c63249SJohan Hedberg 		hci_conn_drop(params->conn);
3765f6c63249SJohan Hedberg 		hci_conn_put(params->conn);
3766f6c63249SJohan Hedberg 	}
3767f6c63249SJohan Hedberg 
3768f6c63249SJohan Hedberg 	list_del(&params->action);
3769f6c63249SJohan Hedberg 	list_del(&params->list);
3770f6c63249SJohan Hedberg 	kfree(params);
3771f6c63249SJohan Hedberg }
3772f6c63249SJohan Hedberg 
377315819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
377415819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
377515819a70SAndre Guedes {
377615819a70SAndre Guedes 	struct hci_conn_params *params;
377715819a70SAndre Guedes 
377815819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
377915819a70SAndre Guedes 	if (!params)
378015819a70SAndre Guedes 		return;
378115819a70SAndre Guedes 
3782f6c63249SJohan Hedberg 	hci_conn_params_free(params);
378315819a70SAndre Guedes 
378495305baaSJohan Hedberg 	hci_update_background_scan(hdev);
378595305baaSJohan Hedberg 
378615819a70SAndre Guedes 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
378715819a70SAndre Guedes }
378815819a70SAndre Guedes 
378915819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
379055af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev)
379115819a70SAndre Guedes {
379215819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
379315819a70SAndre Guedes 
379415819a70SAndre Guedes 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
379555af49a8SJohan Hedberg 		if (params->auto_connect != HCI_AUTO_CONN_DISABLED)
379655af49a8SJohan Hedberg 			continue;
379715819a70SAndre Guedes 		list_del(&params->list);
379815819a70SAndre Guedes 		kfree(params);
379915819a70SAndre Guedes 	}
380015819a70SAndre Guedes 
380155af49a8SJohan Hedberg 	BT_DBG("All LE disabled connection parameters were removed");
380255af49a8SJohan Hedberg }
380355af49a8SJohan Hedberg 
380455af49a8SJohan Hedberg /* This function requires the caller holds hdev->lock */
3805373110c5SJohan Hedberg void hci_conn_params_clear_all(struct hci_dev *hdev)
380615819a70SAndre Guedes {
380715819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
380815819a70SAndre Guedes 
3809f6c63249SJohan Hedberg 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list)
3810f6c63249SJohan Hedberg 		hci_conn_params_free(params);
381115819a70SAndre Guedes 
3812a2f41a8fSJohan Hedberg 	hci_update_background_scan(hdev);
38131089b67dSMarcel Holtmann 
381415819a70SAndre Guedes 	BT_DBG("All LE connection parameters were removed");
381515819a70SAndre Guedes }
381615819a70SAndre Guedes 
38174c87eaabSAndre Guedes static void inquiry_complete(struct hci_dev *hdev, u8 status)
38187ba8b4beSAndre Guedes {
38194c87eaabSAndre Guedes 	if (status) {
38204c87eaabSAndre Guedes 		BT_ERR("Failed to start inquiry: status %d", status);
38217ba8b4beSAndre Guedes 
38224c87eaabSAndre Guedes 		hci_dev_lock(hdev);
38234c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
38244c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
38254c87eaabSAndre Guedes 		return;
38264c87eaabSAndre Guedes 	}
38277ba8b4beSAndre Guedes }
38287ba8b4beSAndre Guedes 
38294c87eaabSAndre Guedes static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status)
38307ba8b4beSAndre Guedes {
38314c87eaabSAndre Guedes 	/* General inquiry access code (GIAC) */
38324c87eaabSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
38334c87eaabSAndre Guedes 	struct hci_request req;
38344c87eaabSAndre Guedes 	struct hci_cp_inquiry cp;
38357ba8b4beSAndre Guedes 	int err;
38367ba8b4beSAndre Guedes 
38374c87eaabSAndre Guedes 	if (status) {
38384c87eaabSAndre Guedes 		BT_ERR("Failed to disable LE scanning: status %d", status);
38394c87eaabSAndre Guedes 		return;
38407ba8b4beSAndre Guedes 	}
38417ba8b4beSAndre Guedes 
38424c87eaabSAndre Guedes 	switch (hdev->discovery.type) {
38434c87eaabSAndre Guedes 	case DISCOV_TYPE_LE:
38444c87eaabSAndre Guedes 		hci_dev_lock(hdev);
38454c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
38464c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
38474c87eaabSAndre Guedes 		break;
38487dbfac1dSAndre Guedes 
38494c87eaabSAndre Guedes 	case DISCOV_TYPE_INTERLEAVED:
38504c87eaabSAndre Guedes 		hci_req_init(&req, hdev);
38517dbfac1dSAndre Guedes 
38527dbfac1dSAndre Guedes 		memset(&cp, 0, sizeof(cp));
38534c87eaabSAndre Guedes 		memcpy(&cp.lap, lap, sizeof(cp.lap));
38544c87eaabSAndre Guedes 		cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN;
38554c87eaabSAndre Guedes 		hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp);
38564c87eaabSAndre Guedes 
38574c87eaabSAndre Guedes 		hci_dev_lock(hdev);
38584c87eaabSAndre Guedes 
38594c87eaabSAndre Guedes 		hci_inquiry_cache_flush(hdev);
38604c87eaabSAndre Guedes 
38614c87eaabSAndre Guedes 		err = hci_req_run(&req, inquiry_complete);
38624c87eaabSAndre Guedes 		if (err) {
38634c87eaabSAndre Guedes 			BT_ERR("Inquiry request failed: err %d", err);
38644c87eaabSAndre Guedes 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
38657dbfac1dSAndre Guedes 		}
38667dbfac1dSAndre Guedes 
38674c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
38684c87eaabSAndre Guedes 		break;
38694c87eaabSAndre Guedes 	}
38707dbfac1dSAndre Guedes }
38717dbfac1dSAndre Guedes 
38727ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work)
38737ba8b4beSAndre Guedes {
38747ba8b4beSAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev,
38757ba8b4beSAndre Guedes 					    le_scan_disable.work);
38764c87eaabSAndre Guedes 	struct hci_request req;
38774c87eaabSAndre Guedes 	int err;
38787ba8b4beSAndre Guedes 
38797ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
38807ba8b4beSAndre Guedes 
38814c87eaabSAndre Guedes 	hci_req_init(&req, hdev);
38827ba8b4beSAndre Guedes 
3883b1efcc28SAndre Guedes 	hci_req_add_le_scan_disable(&req);
38847ba8b4beSAndre Guedes 
38854c87eaabSAndre Guedes 	err = hci_req_run(&req, le_scan_disable_work_complete);
38864c87eaabSAndre Guedes 	if (err)
38874c87eaabSAndre Guedes 		BT_ERR("Disable LE scanning request failed: err %d", err);
388828b75a89SAndre Guedes }
388928b75a89SAndre Guedes 
38908d97250eSJohan Hedberg static void set_random_addr(struct hci_request *req, bdaddr_t *rpa)
38918d97250eSJohan Hedberg {
38928d97250eSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
38938d97250eSJohan Hedberg 
38948d97250eSJohan Hedberg 	/* If we're advertising or initiating an LE connection we can't
38958d97250eSJohan Hedberg 	 * go ahead and change the random address at this time. This is
38968d97250eSJohan Hedberg 	 * because the eventual initiator address used for the
38978d97250eSJohan Hedberg 	 * subsequently created connection will be undefined (some
38988d97250eSJohan Hedberg 	 * controllers use the new address and others the one we had
38998d97250eSJohan Hedberg 	 * when the operation started).
39008d97250eSJohan Hedberg 	 *
39018d97250eSJohan Hedberg 	 * In this kind of scenario skip the update and let the random
39028d97250eSJohan Hedberg 	 * address be updated at the next cycle.
39038d97250eSJohan Hedberg 	 */
39045ce194c4SJohan Hedberg 	if (test_bit(HCI_LE_ADV, &hdev->dev_flags) ||
39058d97250eSJohan Hedberg 	    hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT)) {
39068d97250eSJohan Hedberg 		BT_DBG("Deferring random address update");
39079a783a13SJohan Hedberg 		set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags);
39088d97250eSJohan Hedberg 		return;
39098d97250eSJohan Hedberg 	}
39108d97250eSJohan Hedberg 
39118d97250eSJohan Hedberg 	hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6, rpa);
39128d97250eSJohan Hedberg }
39138d97250eSJohan Hedberg 
391494b1fc92SMarcel Holtmann int hci_update_random_address(struct hci_request *req, bool require_privacy,
391594b1fc92SMarcel Holtmann 			      u8 *own_addr_type)
3916ebd3a747SJohan Hedberg {
3917ebd3a747SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
3918ebd3a747SJohan Hedberg 	int err;
3919ebd3a747SJohan Hedberg 
3920ebd3a747SJohan Hedberg 	/* If privacy is enabled use a resolvable private address. If
39212b5224dcSMarcel Holtmann 	 * current RPA has expired or there is something else than
39222b5224dcSMarcel Holtmann 	 * the current RPA in use, then generate a new one.
3923ebd3a747SJohan Hedberg 	 */
3924ebd3a747SJohan Hedberg 	if (test_bit(HCI_PRIVACY, &hdev->dev_flags)) {
3925ebd3a747SJohan Hedberg 		int to;
3926ebd3a747SJohan Hedberg 
3927ebd3a747SJohan Hedberg 		*own_addr_type = ADDR_LE_DEV_RANDOM;
3928ebd3a747SJohan Hedberg 
3929ebd3a747SJohan Hedberg 		if (!test_and_clear_bit(HCI_RPA_EXPIRED, &hdev->dev_flags) &&
39302b5224dcSMarcel Holtmann 		    !bacmp(&hdev->random_addr, &hdev->rpa))
3931ebd3a747SJohan Hedberg 			return 0;
3932ebd3a747SJohan Hedberg 
3933defce9e8SJohan Hedberg 		err = smp_generate_rpa(hdev, hdev->irk, &hdev->rpa);
3934ebd3a747SJohan Hedberg 		if (err < 0) {
3935ebd3a747SJohan Hedberg 			BT_ERR("%s failed to generate new RPA", hdev->name);
3936ebd3a747SJohan Hedberg 			return err;
3937ebd3a747SJohan Hedberg 		}
3938ebd3a747SJohan Hedberg 
39398d97250eSJohan Hedberg 		set_random_addr(req, &hdev->rpa);
3940ebd3a747SJohan Hedberg 
3941ebd3a747SJohan Hedberg 		to = msecs_to_jiffies(hdev->rpa_timeout * 1000);
3942ebd3a747SJohan Hedberg 		queue_delayed_work(hdev->workqueue, &hdev->rpa_expired, to);
3943ebd3a747SJohan Hedberg 
3944ebd3a747SJohan Hedberg 		return 0;
3945ebd3a747SJohan Hedberg 	}
3946ebd3a747SJohan Hedberg 
394794b1fc92SMarcel Holtmann 	/* In case of required privacy without resolvable private address,
394894b1fc92SMarcel Holtmann 	 * use an unresolvable private address. This is useful for active
394994b1fc92SMarcel Holtmann 	 * scanning and non-connectable advertising.
395094b1fc92SMarcel Holtmann 	 */
395194b1fc92SMarcel Holtmann 	if (require_privacy) {
395294b1fc92SMarcel Holtmann 		bdaddr_t urpa;
395394b1fc92SMarcel Holtmann 
395494b1fc92SMarcel Holtmann 		get_random_bytes(&urpa, 6);
395594b1fc92SMarcel Holtmann 		urpa.b[5] &= 0x3f;	/* Clear two most significant bits */
395694b1fc92SMarcel Holtmann 
395794b1fc92SMarcel Holtmann 		*own_addr_type = ADDR_LE_DEV_RANDOM;
39588d97250eSJohan Hedberg 		set_random_addr(req, &urpa);
395994b1fc92SMarcel Holtmann 		return 0;
396094b1fc92SMarcel Holtmann 	}
396194b1fc92SMarcel Holtmann 
3962ebd3a747SJohan Hedberg 	/* If forcing static address is in use or there is no public
3963ebd3a747SJohan Hedberg 	 * address use the static address as random address (but skip
3964ebd3a747SJohan Hedberg 	 * the HCI command if the current random address is already the
3965ebd3a747SJohan Hedberg 	 * static one.
3966ebd3a747SJohan Hedberg 	 */
3967111902f7SMarcel Holtmann 	if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) ||
3968ebd3a747SJohan Hedberg 	    !bacmp(&hdev->bdaddr, BDADDR_ANY)) {
3969ebd3a747SJohan Hedberg 		*own_addr_type = ADDR_LE_DEV_RANDOM;
3970ebd3a747SJohan Hedberg 		if (bacmp(&hdev->static_addr, &hdev->random_addr))
3971ebd3a747SJohan Hedberg 			hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6,
3972ebd3a747SJohan Hedberg 				    &hdev->static_addr);
3973ebd3a747SJohan Hedberg 		return 0;
3974ebd3a747SJohan Hedberg 	}
3975ebd3a747SJohan Hedberg 
3976ebd3a747SJohan Hedberg 	/* Neither privacy nor static address is being used so use a
3977ebd3a747SJohan Hedberg 	 * public address.
3978ebd3a747SJohan Hedberg 	 */
3979ebd3a747SJohan Hedberg 	*own_addr_type = ADDR_LE_DEV_PUBLIC;
3980ebd3a747SJohan Hedberg 
3981ebd3a747SJohan Hedberg 	return 0;
3982ebd3a747SJohan Hedberg }
3983ebd3a747SJohan Hedberg 
3984a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller.
3985a1f4c318SJohan Hedberg  *
3986a1f4c318SJohan Hedberg  * If the controller has a public BD_ADDR, then by default use that one.
3987a1f4c318SJohan Hedberg  * If this is a LE only controller without a public address, default to
3988a1f4c318SJohan Hedberg  * the static random address.
3989a1f4c318SJohan Hedberg  *
3990a1f4c318SJohan Hedberg  * For debugging purposes it is possible to force controllers with a
3991a1f4c318SJohan Hedberg  * public address to use the static random address instead.
3992a1f4c318SJohan Hedberg  */
3993a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
3994a1f4c318SJohan Hedberg 			       u8 *bdaddr_type)
3995a1f4c318SJohan Hedberg {
3996111902f7SMarcel Holtmann 	if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) ||
3997a1f4c318SJohan Hedberg 	    !bacmp(&hdev->bdaddr, BDADDR_ANY)) {
3998a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->static_addr);
3999a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_RANDOM;
4000a1f4c318SJohan Hedberg 	} else {
4001a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->bdaddr);
4002a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_PUBLIC;
4003a1f4c318SJohan Hedberg 	}
4004a1f4c318SJohan Hedberg }
4005a1f4c318SJohan Hedberg 
40069be0dab7SDavid Herrmann /* Alloc HCI device */
40079be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void)
40089be0dab7SDavid Herrmann {
40099be0dab7SDavid Herrmann 	struct hci_dev *hdev;
40109be0dab7SDavid Herrmann 
401127f70f3eSJohan Hedberg 	hdev = kzalloc(sizeof(*hdev), GFP_KERNEL);
40129be0dab7SDavid Herrmann 	if (!hdev)
40139be0dab7SDavid Herrmann 		return NULL;
40149be0dab7SDavid Herrmann 
4015b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
4016b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
4017b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
4018b4cb9fb2SMarcel Holtmann 	hdev->num_iac = 0x01;		/* One IAC support is mandatory */
4019b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03;	/* No Input No Output */
402096c2103aSMarcel Holtmann 	hdev->manufacturer = 0xffff;	/* Default to internal use */
4021bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
4022bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
4023b1b813d4SDavid Herrmann 
4024b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
4025b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
4026b1b813d4SDavid Herrmann 
40273f959d46SMarcel Holtmann 	hdev->le_adv_channel_map = 0x07;
4028628531c9SGeorg Lukas 	hdev->le_adv_min_interval = 0x0800;
4029628531c9SGeorg Lukas 	hdev->le_adv_max_interval = 0x0800;
4030bef64738SMarcel Holtmann 	hdev->le_scan_interval = 0x0060;
4031bef64738SMarcel Holtmann 	hdev->le_scan_window = 0x0030;
40324e70c7e7SMarcel Holtmann 	hdev->le_conn_min_interval = 0x0028;
40334e70c7e7SMarcel Holtmann 	hdev->le_conn_max_interval = 0x0038;
403404fb7d90SMarcel Holtmann 	hdev->le_conn_latency = 0x0000;
403504fb7d90SMarcel Holtmann 	hdev->le_supv_timeout = 0x002a;
4036bef64738SMarcel Holtmann 
4037d6bfd59cSJohan Hedberg 	hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT;
4038b9a7a61eSLukasz Rymanowski 	hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT;
403931ad1691SAndrzej Kaczmarek 	hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE;
404031ad1691SAndrzej Kaczmarek 	hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE;
4041d6bfd59cSJohan Hedberg 
4042b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
4043b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
4044b1b813d4SDavid Herrmann 
4045b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
4046b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->blacklist);
40476659358eSJohan Hedberg 	INIT_LIST_HEAD(&hdev->whitelist);
4048b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
4049b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
4050b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
4051970c4e46SJohan Hedberg 	INIT_LIST_HEAD(&hdev->identity_resolving_keys);
4052b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
4053d2ab0ac1SMarcel Holtmann 	INIT_LIST_HEAD(&hdev->le_white_list);
405415819a70SAndre Guedes 	INIT_LIST_HEAD(&hdev->le_conn_params);
405577a77a30SAndre Guedes 	INIT_LIST_HEAD(&hdev->pend_le_conns);
405666f8455aSJohan Hedberg 	INIT_LIST_HEAD(&hdev->pend_le_reports);
40576b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
4058b1b813d4SDavid Herrmann 
4059b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
4060b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
4061b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
4062b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
4063b1b813d4SDavid Herrmann 
4064b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
4065b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
4066b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
4067b1b813d4SDavid Herrmann 
4068b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
4069b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
4070b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
4071b1b813d4SDavid Herrmann 
4072b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
4073b1b813d4SDavid Herrmann 
407465cc2b49SMarcel Holtmann 	INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout);
4075b1b813d4SDavid Herrmann 
4076b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
4077b1b813d4SDavid Herrmann 	discovery_init(hdev);
40789be0dab7SDavid Herrmann 
40799be0dab7SDavid Herrmann 	return hdev;
40809be0dab7SDavid Herrmann }
40819be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev);
40829be0dab7SDavid Herrmann 
40839be0dab7SDavid Herrmann /* Free HCI device */
40849be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
40859be0dab7SDavid Herrmann {
40869be0dab7SDavid Herrmann 	/* will free via device release */
40879be0dab7SDavid Herrmann 	put_device(&hdev->dev);
40889be0dab7SDavid Herrmann }
40899be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
40909be0dab7SDavid Herrmann 
40911da177e4SLinus Torvalds /* Register HCI device */
40921da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
40931da177e4SLinus Torvalds {
4094b1b813d4SDavid Herrmann 	int id, error;
40951da177e4SLinus Torvalds 
409674292d5aSMarcel Holtmann 	if (!hdev->open || !hdev->close || !hdev->send)
40971da177e4SLinus Torvalds 		return -EINVAL;
40981da177e4SLinus Torvalds 
409908add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
410008add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
410108add513SMat Martineau 	 */
41023df92b31SSasha Levin 	switch (hdev->dev_type) {
41033df92b31SSasha Levin 	case HCI_BREDR:
41043df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
41051da177e4SLinus Torvalds 		break;
41063df92b31SSasha Levin 	case HCI_AMP:
41073df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
41083df92b31SSasha Levin 		break;
41093df92b31SSasha Levin 	default:
41103df92b31SSasha Levin 		return -EINVAL;
41111da177e4SLinus Torvalds 	}
41121da177e4SLinus Torvalds 
41133df92b31SSasha Levin 	if (id < 0)
41143df92b31SSasha Levin 		return id;
41153df92b31SSasha Levin 
41161da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
41171da177e4SLinus Torvalds 	hdev->id = id;
41182d8b3a11SAndrei Emeltchenko 
41192d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
41202d8b3a11SAndrei Emeltchenko 
4121d8537548SKees Cook 	hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
4122d8537548SKees Cook 					  WQ_MEM_RECLAIM, 1, hdev->name);
412333ca954dSDavid Herrmann 	if (!hdev->workqueue) {
412433ca954dSDavid Herrmann 		error = -ENOMEM;
412533ca954dSDavid Herrmann 		goto err;
412633ca954dSDavid Herrmann 	}
4127f48fd9c8SMarcel Holtmann 
4128d8537548SKees Cook 	hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
4129d8537548SKees Cook 					      WQ_MEM_RECLAIM, 1, hdev->name);
41306ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
41316ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
41326ead1bbcSJohan Hedberg 		error = -ENOMEM;
41336ead1bbcSJohan Hedberg 		goto err;
41346ead1bbcSJohan Hedberg 	}
41356ead1bbcSJohan Hedberg 
41360153e2ecSMarcel Holtmann 	if (!IS_ERR_OR_NULL(bt_debugfs))
41370153e2ecSMarcel Holtmann 		hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs);
41380153e2ecSMarcel Holtmann 
4139bdc3e0f1SMarcel Holtmann 	dev_set_name(&hdev->dev, "%s", hdev->name);
4140bdc3e0f1SMarcel Holtmann 
4141bdc3e0f1SMarcel Holtmann 	error = device_add(&hdev->dev);
414233ca954dSDavid Herrmann 	if (error < 0)
414354506918SJohan Hedberg 		goto err_wqueue;
41441da177e4SLinus Torvalds 
4145611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
4146a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
4147a8c5fb1aSGustavo Padovan 				    hdev);
4148611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
4149611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
4150611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
4151611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
4152611b30f7SMarcel Holtmann 		}
4153611b30f7SMarcel Holtmann 	}
4154611b30f7SMarcel Holtmann 
41555e130367SJohan Hedberg 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill))
41565e130367SJohan Hedberg 		set_bit(HCI_RFKILLED, &hdev->dev_flags);
41575e130367SJohan Hedberg 
4158a8b2d5c2SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->dev_flags);
4159004b0258SMarcel Holtmann 	set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
4160ce2be9acSAndrei Emeltchenko 
416101cd3404SMarcel Holtmann 	if (hdev->dev_type == HCI_BREDR) {
416256f87901SJohan Hedberg 		/* Assume BR/EDR support until proven otherwise (such as
416356f87901SJohan Hedberg 		 * through reading supported features during init.
416456f87901SJohan Hedberg 		 */
416556f87901SJohan Hedberg 		set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
416656f87901SJohan Hedberg 	}
4167ce2be9acSAndrei Emeltchenko 
4168fcee3377SGustavo Padovan 	write_lock(&hci_dev_list_lock);
4169fcee3377SGustavo Padovan 	list_add(&hdev->list, &hci_dev_list);
4170fcee3377SGustavo Padovan 	write_unlock(&hci_dev_list_lock);
4171fcee3377SGustavo Padovan 
41724a964404SMarcel Holtmann 	/* Devices that are marked for raw-only usage are unconfigured
41734a964404SMarcel Holtmann 	 * and should not be included in normal operation.
4174fee746b0SMarcel Holtmann 	 */
4175fee746b0SMarcel Holtmann 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
41764a964404SMarcel Holtmann 		set_bit(HCI_UNCONFIGURED, &hdev->dev_flags);
4177fee746b0SMarcel Holtmann 
41781da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
4179dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
41801da177e4SLinus Torvalds 
418119202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
4182fbe96d6fSMarcel Holtmann 
41831da177e4SLinus Torvalds 	return id;
4184f48fd9c8SMarcel Holtmann 
418533ca954dSDavid Herrmann err_wqueue:
418633ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
41876ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
418833ca954dSDavid Herrmann err:
41893df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
4190f48fd9c8SMarcel Holtmann 
419133ca954dSDavid Herrmann 	return error;
41921da177e4SLinus Torvalds }
41931da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
41941da177e4SLinus Torvalds 
41951da177e4SLinus Torvalds /* Unregister HCI device */
419659735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
41971da177e4SLinus Torvalds {
41983df92b31SSasha Levin 	int i, id;
4199ef222013SMarcel Holtmann 
4200c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
42011da177e4SLinus Torvalds 
420294324962SJohan Hovold 	set_bit(HCI_UNREGISTER, &hdev->dev_flags);
420394324962SJohan Hovold 
42043df92b31SSasha Levin 	id = hdev->id;
42053df92b31SSasha Levin 
4206f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
42071da177e4SLinus Torvalds 	list_del(&hdev->list);
4208f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
42091da177e4SLinus Torvalds 
42101da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
42111da177e4SLinus Torvalds 
4212cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
4213ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
4214ef222013SMarcel Holtmann 
4215b9b5ef18SGustavo Padovan 	cancel_work_sync(&hdev->power_on);
4216b9b5ef18SGustavo Padovan 
4217ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
4218d603b76bSMarcel Holtmann 	    !test_bit(HCI_SETUP, &hdev->dev_flags) &&
4219d603b76bSMarcel Holtmann 	    !test_bit(HCI_CONFIG, &hdev->dev_flags)) {
422009fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
4221744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
422209fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
422356e5cb86SJohan Hedberg 	}
4224ab81cbf9SJohan Hedberg 
42252e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
42262e58ef3eSJohan Hedberg 	 * pending list */
42272e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
42282e58ef3eSJohan Hedberg 
42291da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
42301da177e4SLinus Torvalds 
4231611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
4232611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
4233611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
4234611b30f7SMarcel Holtmann 	}
4235611b30f7SMarcel Holtmann 
4236711eafe3SJohan Hedberg 	smp_unregister(hdev);
423799780a7bSJohan Hedberg 
4238bdc3e0f1SMarcel Holtmann 	device_del(&hdev->dev);
4239147e2d59SDave Young 
42400153e2ecSMarcel Holtmann 	debugfs_remove_recursive(hdev->debugfs);
42410153e2ecSMarcel Holtmann 
4242f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
42436ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
4244f48fd9c8SMarcel Holtmann 
424509fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
4246dcc36c16SJohan Hedberg 	hci_bdaddr_list_clear(&hdev->blacklist);
42476659358eSJohan Hedberg 	hci_bdaddr_list_clear(&hdev->whitelist);
42482aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
424955ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
4250b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
4251970c4e46SJohan Hedberg 	hci_smp_irks_clear(hdev);
42522763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
4253dcc36c16SJohan Hedberg 	hci_bdaddr_list_clear(&hdev->le_white_list);
4254373110c5SJohan Hedberg 	hci_conn_params_clear_all(hdev);
425522078800SMarcel Holtmann 	hci_discovery_filter_clear(hdev);
425609fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
4257e2e0cacbSJohan Hedberg 
4258dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
42593df92b31SSasha Levin 
42603df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, id);
42611da177e4SLinus Torvalds }
42621da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
42631da177e4SLinus Torvalds 
42641da177e4SLinus Torvalds /* Suspend HCI device */
42651da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
42661da177e4SLinus Torvalds {
42671da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
42681da177e4SLinus Torvalds 	return 0;
42691da177e4SLinus Torvalds }
42701da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
42711da177e4SLinus Torvalds 
42721da177e4SLinus Torvalds /* Resume HCI device */
42731da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
42741da177e4SLinus Torvalds {
42751da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
42761da177e4SLinus Torvalds 	return 0;
42771da177e4SLinus Torvalds }
42781da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
42791da177e4SLinus Torvalds 
428075e0569fSMarcel Holtmann /* Reset HCI device */
428175e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev)
428275e0569fSMarcel Holtmann {
428375e0569fSMarcel Holtmann 	const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 };
428475e0569fSMarcel Holtmann 	struct sk_buff *skb;
428575e0569fSMarcel Holtmann 
428675e0569fSMarcel Holtmann 	skb = bt_skb_alloc(3, GFP_ATOMIC);
428775e0569fSMarcel Holtmann 	if (!skb)
428875e0569fSMarcel Holtmann 		return -ENOMEM;
428975e0569fSMarcel Holtmann 
429075e0569fSMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
429175e0569fSMarcel Holtmann 	memcpy(skb_put(skb, 3), hw_err, 3);
429275e0569fSMarcel Holtmann 
429375e0569fSMarcel Holtmann 	/* Send Hardware Error to upper stack */
429475e0569fSMarcel Holtmann 	return hci_recv_frame(hdev, skb);
429575e0569fSMarcel Holtmann }
429675e0569fSMarcel Holtmann EXPORT_SYMBOL(hci_reset_dev);
429775e0569fSMarcel Holtmann 
429876bca880SMarcel Holtmann /* Receive frame from HCI drivers */
4299e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
430076bca880SMarcel Holtmann {
430176bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
430276bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
430376bca880SMarcel Holtmann 		kfree_skb(skb);
430476bca880SMarcel Holtmann 		return -ENXIO;
430576bca880SMarcel Holtmann 	}
430676bca880SMarcel Holtmann 
4307d82603c6SJorrit Schippers 	/* Incoming skb */
430876bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
430976bca880SMarcel Holtmann 
431076bca880SMarcel Holtmann 	/* Time stamp */
431176bca880SMarcel Holtmann 	__net_timestamp(skb);
431276bca880SMarcel Holtmann 
431376bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
4314b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
4315c78ae283SMarcel Holtmann 
431676bca880SMarcel Holtmann 	return 0;
431776bca880SMarcel Holtmann }
431876bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
431976bca880SMarcel Holtmann 
432033e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
43211e429f38SGustavo F. Padovan 			  int count, __u8 index)
432233e882a5SSuraj Sumangala {
432333e882a5SSuraj Sumangala 	int len = 0;
432433e882a5SSuraj Sumangala 	int hlen = 0;
432533e882a5SSuraj Sumangala 	int remain = count;
432633e882a5SSuraj Sumangala 	struct sk_buff *skb;
432733e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
432833e882a5SSuraj Sumangala 
432933e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
433033e882a5SSuraj Sumangala 	    index >= NUM_REASSEMBLY)
433133e882a5SSuraj Sumangala 		return -EILSEQ;
433233e882a5SSuraj Sumangala 
433333e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
433433e882a5SSuraj Sumangala 
433533e882a5SSuraj Sumangala 	if (!skb) {
433633e882a5SSuraj Sumangala 		switch (type) {
433733e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
433833e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
433933e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
434033e882a5SSuraj Sumangala 			break;
434133e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
434233e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
434333e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
434433e882a5SSuraj Sumangala 			break;
434533e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
434633e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
434733e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
434833e882a5SSuraj Sumangala 			break;
434933e882a5SSuraj Sumangala 		}
435033e882a5SSuraj Sumangala 
43511e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
435233e882a5SSuraj Sumangala 		if (!skb)
435333e882a5SSuraj Sumangala 			return -ENOMEM;
435433e882a5SSuraj Sumangala 
435533e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
435633e882a5SSuraj Sumangala 		scb->expect = hlen;
435733e882a5SSuraj Sumangala 		scb->pkt_type = type;
435833e882a5SSuraj Sumangala 
435933e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
436033e882a5SSuraj Sumangala 	}
436133e882a5SSuraj Sumangala 
436233e882a5SSuraj Sumangala 	while (count) {
436333e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
436489bb46d0SDan Carpenter 		len = min_t(uint, scb->expect, count);
436533e882a5SSuraj Sumangala 
436633e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
436733e882a5SSuraj Sumangala 
436833e882a5SSuraj Sumangala 		count -= len;
436933e882a5SSuraj Sumangala 		data += len;
437033e882a5SSuraj Sumangala 		scb->expect -= len;
437133e882a5SSuraj Sumangala 		remain = count;
437233e882a5SSuraj Sumangala 
437333e882a5SSuraj Sumangala 		switch (type) {
437433e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
437533e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
437633e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
437733e882a5SSuraj Sumangala 				scb->expect = h->plen;
437833e882a5SSuraj Sumangala 
437933e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
438033e882a5SSuraj Sumangala 					kfree_skb(skb);
438133e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
438233e882a5SSuraj Sumangala 					return -ENOMEM;
438333e882a5SSuraj Sumangala 				}
438433e882a5SSuraj Sumangala 			}
438533e882a5SSuraj Sumangala 			break;
438633e882a5SSuraj Sumangala 
438733e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
438833e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
438933e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
439033e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
439133e882a5SSuraj Sumangala 
439233e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
439333e882a5SSuraj Sumangala 					kfree_skb(skb);
439433e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
439533e882a5SSuraj Sumangala 					return -ENOMEM;
439633e882a5SSuraj Sumangala 				}
439733e882a5SSuraj Sumangala 			}
439833e882a5SSuraj Sumangala 			break;
439933e882a5SSuraj Sumangala 
440033e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
440133e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
440233e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
440333e882a5SSuraj Sumangala 				scb->expect = h->dlen;
440433e882a5SSuraj Sumangala 
440533e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
440633e882a5SSuraj Sumangala 					kfree_skb(skb);
440733e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
440833e882a5SSuraj Sumangala 					return -ENOMEM;
440933e882a5SSuraj Sumangala 				}
441033e882a5SSuraj Sumangala 			}
441133e882a5SSuraj Sumangala 			break;
441233e882a5SSuraj Sumangala 		}
441333e882a5SSuraj Sumangala 
441433e882a5SSuraj Sumangala 		if (scb->expect == 0) {
441533e882a5SSuraj Sumangala 			/* Complete frame */
441633e882a5SSuraj Sumangala 
441733e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
4418e1a26170SMarcel Holtmann 			hci_recv_frame(hdev, skb);
441933e882a5SSuraj Sumangala 
442033e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
442133e882a5SSuraj Sumangala 			return remain;
442233e882a5SSuraj Sumangala 		}
442333e882a5SSuraj Sumangala 	}
442433e882a5SSuraj Sumangala 
442533e882a5SSuraj Sumangala 	return remain;
442633e882a5SSuraj Sumangala }
442733e882a5SSuraj Sumangala 
442899811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
442999811510SSuraj Sumangala 
443099811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
443199811510SSuraj Sumangala {
443299811510SSuraj Sumangala 	int type;
443399811510SSuraj Sumangala 	int rem = 0;
443499811510SSuraj Sumangala 
4435da5f6c37SGustavo F. Padovan 	while (count) {
443699811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
443799811510SSuraj Sumangala 
443899811510SSuraj Sumangala 		if (!skb) {
443999811510SSuraj Sumangala 			struct { char type; } *pkt;
444099811510SSuraj Sumangala 
444199811510SSuraj Sumangala 			/* Start of the frame */
444299811510SSuraj Sumangala 			pkt = data;
444399811510SSuraj Sumangala 			type = pkt->type;
444499811510SSuraj Sumangala 
444599811510SSuraj Sumangala 			data++;
444699811510SSuraj Sumangala 			count--;
444799811510SSuraj Sumangala 		} else
444899811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
444999811510SSuraj Sumangala 
44501e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
44511e429f38SGustavo F. Padovan 				     STREAM_REASSEMBLY);
445299811510SSuraj Sumangala 		if (rem < 0)
445399811510SSuraj Sumangala 			return rem;
445499811510SSuraj Sumangala 
445599811510SSuraj Sumangala 		data += (count - rem);
445699811510SSuraj Sumangala 		count = rem;
4457f81c6224SJoe Perches 	}
445899811510SSuraj Sumangala 
445999811510SSuraj Sumangala 	return rem;
446099811510SSuraj Sumangala }
446199811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
446299811510SSuraj Sumangala 
44631da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
44641da177e4SLinus Torvalds 
44651da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
44661da177e4SLinus Torvalds {
44671da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
44681da177e4SLinus Torvalds 
4469f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
44701da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
4471f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
44721da177e4SLinus Torvalds 
44731da177e4SLinus Torvalds 	return 0;
44741da177e4SLinus Torvalds }
44751da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
44761da177e4SLinus Torvalds 
44771da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
44781da177e4SLinus Torvalds {
44791da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
44801da177e4SLinus Torvalds 
4481f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
44821da177e4SLinus Torvalds 	list_del(&cb->list);
4483f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
44841da177e4SLinus Torvalds 
44851da177e4SLinus Torvalds 	return 0;
44861da177e4SLinus Torvalds }
44871da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
44881da177e4SLinus Torvalds 
448951086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
44901da177e4SLinus Torvalds {
4491cdc52faaSMarcel Holtmann 	int err;
4492cdc52faaSMarcel Holtmann 
44930d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
44941da177e4SLinus Torvalds 
44951da177e4SLinus Torvalds 	/* Time stamp */
4496a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
44971da177e4SLinus Torvalds 
4498cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
4499cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
4500cd82e61cSMarcel Holtmann 
4501cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
4502cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
4503470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
45041da177e4SLinus Torvalds 	}
45051da177e4SLinus Torvalds 
45061da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
45071da177e4SLinus Torvalds 	skb_orphan(skb);
45081da177e4SLinus Torvalds 
4509cdc52faaSMarcel Holtmann 	err = hdev->send(hdev, skb);
4510cdc52faaSMarcel Holtmann 	if (err < 0) {
4511cdc52faaSMarcel Holtmann 		BT_ERR("%s sending frame failed (%d)", hdev->name, err);
4512cdc52faaSMarcel Holtmann 		kfree_skb(skb);
4513cdc52faaSMarcel Holtmann 	}
45141da177e4SLinus Torvalds }
45151da177e4SLinus Torvalds 
45163119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev)
45173119ae95SJohan Hedberg {
45183119ae95SJohan Hedberg 	skb_queue_head_init(&req->cmd_q);
45193119ae95SJohan Hedberg 	req->hdev = hdev;
45205d73e034SAndre Guedes 	req->err = 0;
45213119ae95SJohan Hedberg }
45223119ae95SJohan Hedberg 
45233119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete)
45243119ae95SJohan Hedberg {
45253119ae95SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
45263119ae95SJohan Hedberg 	struct sk_buff *skb;
45273119ae95SJohan Hedberg 	unsigned long flags;
45283119ae95SJohan Hedberg 
45293119ae95SJohan Hedberg 	BT_DBG("length %u", skb_queue_len(&req->cmd_q));
45303119ae95SJohan Hedberg 
453149c922bbSStephen Hemminger 	/* If an error occurred during request building, remove all HCI
45325d73e034SAndre Guedes 	 * commands queued on the HCI request queue.
45335d73e034SAndre Guedes 	 */
45345d73e034SAndre Guedes 	if (req->err) {
45355d73e034SAndre Guedes 		skb_queue_purge(&req->cmd_q);
45365d73e034SAndre Guedes 		return req->err;
45375d73e034SAndre Guedes 	}
45385d73e034SAndre Guedes 
45393119ae95SJohan Hedberg 	/* Do not allow empty requests */
45403119ae95SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
4541382b0c39SAndre Guedes 		return -ENODATA;
45423119ae95SJohan Hedberg 
45433119ae95SJohan Hedberg 	skb = skb_peek_tail(&req->cmd_q);
45443119ae95SJohan Hedberg 	bt_cb(skb)->req.complete = complete;
45453119ae95SJohan Hedberg 
45463119ae95SJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
45473119ae95SJohan Hedberg 	skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q);
45483119ae95SJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
45493119ae95SJohan Hedberg 
45503119ae95SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
45513119ae95SJohan Hedberg 
45523119ae95SJohan Hedberg 	return 0;
45533119ae95SJohan Hedberg }
45543119ae95SJohan Hedberg 
4555899de765SMarcel Holtmann bool hci_req_pending(struct hci_dev *hdev)
4556899de765SMarcel Holtmann {
4557899de765SMarcel Holtmann 	return (hdev->req_status == HCI_REQ_PEND);
4558899de765SMarcel Holtmann }
4559899de765SMarcel Holtmann 
45601ca3a9d0SJohan Hedberg static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode,
456107dc93ddSJohan Hedberg 				       u32 plen, const void *param)
45621da177e4SLinus Torvalds {
45631da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
45641da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
45651da177e4SLinus Torvalds 	struct sk_buff *skb;
45661da177e4SLinus Torvalds 
45671da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
45681ca3a9d0SJohan Hedberg 	if (!skb)
45691ca3a9d0SJohan Hedberg 		return NULL;
45701da177e4SLinus Torvalds 
45711da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
4572a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
45731da177e4SLinus Torvalds 	hdr->plen   = plen;
45741da177e4SLinus Torvalds 
45751da177e4SLinus Torvalds 	if (plen)
45761da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
45771da177e4SLinus Torvalds 
45781da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
45791da177e4SLinus Torvalds 
45800d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
458143e73e4eSMarcel Holtmann 	bt_cb(skb)->opcode = opcode;
4582c78ae283SMarcel Holtmann 
45831ca3a9d0SJohan Hedberg 	return skb;
45841ca3a9d0SJohan Hedberg }
45851ca3a9d0SJohan Hedberg 
45861ca3a9d0SJohan Hedberg /* Send HCI command */
458707dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
458807dc93ddSJohan Hedberg 		 const void *param)
45891ca3a9d0SJohan Hedberg {
45901ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
45911ca3a9d0SJohan Hedberg 
45921ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
45931ca3a9d0SJohan Hedberg 
45941ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
45951ca3a9d0SJohan Hedberg 	if (!skb) {
45961ca3a9d0SJohan Hedberg 		BT_ERR("%s no memory for command", hdev->name);
45971ca3a9d0SJohan Hedberg 		return -ENOMEM;
45981ca3a9d0SJohan Hedberg 	}
45991ca3a9d0SJohan Hedberg 
460049c922bbSStephen Hemminger 	/* Stand-alone HCI commands must be flagged as
460111714b3dSJohan Hedberg 	 * single-command requests.
460211714b3dSJohan Hedberg 	 */
460311714b3dSJohan Hedberg 	bt_cb(skb)->req.start = true;
460411714b3dSJohan Hedberg 
46051da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
4606c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
46071da177e4SLinus Torvalds 
46081da177e4SLinus Torvalds 	return 0;
46091da177e4SLinus Torvalds }
46101da177e4SLinus Torvalds 
461171c76a17SJohan Hedberg /* Queue a command to an asynchronous HCI request */
461207dc93ddSJohan Hedberg void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen,
461307dc93ddSJohan Hedberg 		    const void *param, u8 event)
461471c76a17SJohan Hedberg {
461571c76a17SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
461671c76a17SJohan Hedberg 	struct sk_buff *skb;
461771c76a17SJohan Hedberg 
461871c76a17SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
461971c76a17SJohan Hedberg 
462049c922bbSStephen Hemminger 	/* If an error occurred during request building, there is no point in
462134739c1eSAndre Guedes 	 * queueing the HCI command. We can simply return.
462234739c1eSAndre Guedes 	 */
462334739c1eSAndre Guedes 	if (req->err)
462434739c1eSAndre Guedes 		return;
462534739c1eSAndre Guedes 
462671c76a17SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
462771c76a17SJohan Hedberg 	if (!skb) {
46285d73e034SAndre Guedes 		BT_ERR("%s no memory for command (opcode 0x%4.4x)",
46295d73e034SAndre Guedes 		       hdev->name, opcode);
46305d73e034SAndre Guedes 		req->err = -ENOMEM;
4631e348fe6bSAndre Guedes 		return;
463271c76a17SJohan Hedberg 	}
463371c76a17SJohan Hedberg 
463471c76a17SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
463571c76a17SJohan Hedberg 		bt_cb(skb)->req.start = true;
463671c76a17SJohan Hedberg 
463702350a72SJohan Hedberg 	bt_cb(skb)->req.event = event;
463802350a72SJohan Hedberg 
463971c76a17SJohan Hedberg 	skb_queue_tail(&req->cmd_q, skb);
464071c76a17SJohan Hedberg }
464171c76a17SJohan Hedberg 
464207dc93ddSJohan Hedberg void hci_req_add(struct hci_request *req, u16 opcode, u32 plen,
464307dc93ddSJohan Hedberg 		 const void *param)
464402350a72SJohan Hedberg {
464502350a72SJohan Hedberg 	hci_req_add_ev(req, opcode, plen, param, 0);
464602350a72SJohan Hedberg }
464702350a72SJohan Hedberg 
46481da177e4SLinus Torvalds /* Get data from the previously sent command */
4649a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
46501da177e4SLinus Torvalds {
46511da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
46521da177e4SLinus Torvalds 
46531da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
46541da177e4SLinus Torvalds 		return NULL;
46551da177e4SLinus Torvalds 
46561da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
46571da177e4SLinus Torvalds 
4658a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
46591da177e4SLinus Torvalds 		return NULL;
46601da177e4SLinus Torvalds 
4661f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
46621da177e4SLinus Torvalds 
46631da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
46641da177e4SLinus Torvalds }
46651da177e4SLinus Torvalds 
46661da177e4SLinus Torvalds /* Send ACL data */
46671da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
46681da177e4SLinus Torvalds {
46691da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
46701da177e4SLinus Torvalds 	int len = skb->len;
46711da177e4SLinus Torvalds 
4672badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
4673badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
46749c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
4675aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
4676aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
46771da177e4SLinus Torvalds }
46781da177e4SLinus Torvalds 
4679ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
468073d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
46811da177e4SLinus Torvalds {
4682ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
46831da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
46841da177e4SLinus Torvalds 	struct sk_buff *list;
46851da177e4SLinus Torvalds 
4686087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
4687087bfd99SGustavo Padovan 	skb->data_len = 0;
4688087bfd99SGustavo Padovan 
4689087bfd99SGustavo Padovan 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
4690204a6e54SAndrei Emeltchenko 
4691204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
4692204a6e54SAndrei Emeltchenko 	case HCI_BREDR:
4693087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
4694204a6e54SAndrei Emeltchenko 		break;
4695204a6e54SAndrei Emeltchenko 	case HCI_AMP:
4696204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
4697204a6e54SAndrei Emeltchenko 		break;
4698204a6e54SAndrei Emeltchenko 	default:
4699204a6e54SAndrei Emeltchenko 		BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
4700204a6e54SAndrei Emeltchenko 		return;
4701204a6e54SAndrei Emeltchenko 	}
4702087bfd99SGustavo Padovan 
470370f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
470470f23020SAndrei Emeltchenko 	if (!list) {
47051da177e4SLinus Torvalds 		/* Non fragmented */
47061da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
47071da177e4SLinus Torvalds 
470873d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
47091da177e4SLinus Torvalds 	} else {
47101da177e4SLinus Torvalds 		/* Fragmented */
47111da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
47121da177e4SLinus Torvalds 
47131da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
47141da177e4SLinus Torvalds 
47159cfd5a23SJukka Rissanen 		/* Queue all fragments atomically. We need to use spin_lock_bh
47169cfd5a23SJukka Rissanen 		 * here because of 6LoWPAN links, as there this function is
47179cfd5a23SJukka Rissanen 		 * called from softirq and using normal spin lock could cause
47189cfd5a23SJukka Rissanen 		 * deadlocks.
47199cfd5a23SJukka Rissanen 		 */
47209cfd5a23SJukka Rissanen 		spin_lock_bh(&queue->lock);
47211da177e4SLinus Torvalds 
472273d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
4723e702112fSAndrei Emeltchenko 
4724e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
4725e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
47261da177e4SLinus Torvalds 		do {
47271da177e4SLinus Torvalds 			skb = list; list = list->next;
47281da177e4SLinus Torvalds 
47290d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
4730e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
47311da177e4SLinus Torvalds 
47321da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
47331da177e4SLinus Torvalds 
473473d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
47351da177e4SLinus Torvalds 		} while (list);
47361da177e4SLinus Torvalds 
47379cfd5a23SJukka Rissanen 		spin_unlock_bh(&queue->lock);
47381da177e4SLinus Torvalds 	}
473973d80debSLuiz Augusto von Dentz }
474073d80debSLuiz Augusto von Dentz 
474173d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
474273d80debSLuiz Augusto von Dentz {
4743ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
474473d80debSLuiz Augusto von Dentz 
4745f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
474673d80debSLuiz Augusto von Dentz 
4747ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
47481da177e4SLinus Torvalds 
47493eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
47501da177e4SLinus Torvalds }
47511da177e4SLinus Torvalds 
47521da177e4SLinus Torvalds /* Send SCO data */
47530d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
47541da177e4SLinus Torvalds {
47551da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
47561da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
47571da177e4SLinus Torvalds 
47581da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
47591da177e4SLinus Torvalds 
4760aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
47611da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
47621da177e4SLinus Torvalds 
4763badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
4764badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
47659c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
47661da177e4SLinus Torvalds 
47670d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
4768c78ae283SMarcel Holtmann 
47691da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
47703eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
47711da177e4SLinus Torvalds }
47721da177e4SLinus Torvalds 
47731da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
47741da177e4SLinus Torvalds 
47751da177e4SLinus Torvalds /* HCI Connection scheduler */
47766039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
4777a8c5fb1aSGustavo Padovan 				     int *quote)
47781da177e4SLinus Torvalds {
47791da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
47808035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
4781abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
47821da177e4SLinus Torvalds 
47831da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
47841da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
4785bf4c6325SGustavo F. Padovan 
4786bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4787bf4c6325SGustavo F. Padovan 
4788bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
4789769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
47901da177e4SLinus Torvalds 			continue;
4791769be974SMarcel Holtmann 
4792769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
4793769be974SMarcel Holtmann 			continue;
4794769be974SMarcel Holtmann 
47951da177e4SLinus Torvalds 		num++;
47961da177e4SLinus Torvalds 
47971da177e4SLinus Torvalds 		if (c->sent < min) {
47981da177e4SLinus Torvalds 			min  = c->sent;
47991da177e4SLinus Torvalds 			conn = c;
48001da177e4SLinus Torvalds 		}
480152087a79SLuiz Augusto von Dentz 
480252087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
480352087a79SLuiz Augusto von Dentz 			break;
48041da177e4SLinus Torvalds 	}
48051da177e4SLinus Torvalds 
4806bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4807bf4c6325SGustavo F. Padovan 
48081da177e4SLinus Torvalds 	if (conn) {
48096ed58ec5SVille Tervo 		int cnt, q;
48106ed58ec5SVille Tervo 
48116ed58ec5SVille Tervo 		switch (conn->type) {
48126ed58ec5SVille Tervo 		case ACL_LINK:
48136ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
48146ed58ec5SVille Tervo 			break;
48156ed58ec5SVille Tervo 		case SCO_LINK:
48166ed58ec5SVille Tervo 		case ESCO_LINK:
48176ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
48186ed58ec5SVille Tervo 			break;
48196ed58ec5SVille Tervo 		case LE_LINK:
48206ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
48216ed58ec5SVille Tervo 			break;
48226ed58ec5SVille Tervo 		default:
48236ed58ec5SVille Tervo 			cnt = 0;
48246ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
48256ed58ec5SVille Tervo 		}
48266ed58ec5SVille Tervo 
48276ed58ec5SVille Tervo 		q = cnt / num;
48281da177e4SLinus Torvalds 		*quote = q ? q : 1;
48291da177e4SLinus Torvalds 	} else
48301da177e4SLinus Torvalds 		*quote = 0;
48311da177e4SLinus Torvalds 
48321da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
48331da177e4SLinus Torvalds 	return conn;
48341da177e4SLinus Torvalds }
48351da177e4SLinus Torvalds 
48366039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
48371da177e4SLinus Torvalds {
48381da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
48391da177e4SLinus Torvalds 	struct hci_conn *c;
48401da177e4SLinus Torvalds 
4841bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
48421da177e4SLinus Torvalds 
4843bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4844bf4c6325SGustavo F. Padovan 
48451da177e4SLinus Torvalds 	/* Kill stalled connections */
4846bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
4847bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
48486ed93dc6SAndrei Emeltchenko 			BT_ERR("%s killing stalled connection %pMR",
48496ed93dc6SAndrei Emeltchenko 			       hdev->name, &c->dst);
4850bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
48511da177e4SLinus Torvalds 		}
48521da177e4SLinus Torvalds 	}
4853bf4c6325SGustavo F. Padovan 
4854bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
48551da177e4SLinus Torvalds }
48561da177e4SLinus Torvalds 
48576039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
485873d80debSLuiz Augusto von Dentz 				      int *quote)
485973d80debSLuiz Augusto von Dentz {
486073d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
486173d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
4862abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
486373d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
486473d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
486573d80debSLuiz Augusto von Dentz 
486673d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
486773d80debSLuiz Augusto von Dentz 
4868bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4869bf4c6325SGustavo F. Padovan 
4870bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
487173d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
487273d80debSLuiz Augusto von Dentz 
487373d80debSLuiz Augusto von Dentz 		if (conn->type != type)
487473d80debSLuiz Augusto von Dentz 			continue;
487573d80debSLuiz Augusto von Dentz 
487673d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
487773d80debSLuiz Augusto von Dentz 			continue;
487873d80debSLuiz Augusto von Dentz 
487973d80debSLuiz Augusto von Dentz 		conn_num++;
488073d80debSLuiz Augusto von Dentz 
48818192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
488273d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
488373d80debSLuiz Augusto von Dentz 
488473d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
488573d80debSLuiz Augusto von Dentz 				continue;
488673d80debSLuiz Augusto von Dentz 
488773d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
488873d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
488973d80debSLuiz Augusto von Dentz 				continue;
489073d80debSLuiz Augusto von Dentz 
489173d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
489273d80debSLuiz Augusto von Dentz 				num = 0;
489373d80debSLuiz Augusto von Dentz 				min = ~0;
489473d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
489573d80debSLuiz Augusto von Dentz 			}
489673d80debSLuiz Augusto von Dentz 
489773d80debSLuiz Augusto von Dentz 			num++;
489873d80debSLuiz Augusto von Dentz 
489973d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
490073d80debSLuiz Augusto von Dentz 				min  = conn->sent;
490173d80debSLuiz Augusto von Dentz 				chan = tmp;
490273d80debSLuiz Augusto von Dentz 			}
490373d80debSLuiz Augusto von Dentz 		}
490473d80debSLuiz Augusto von Dentz 
490573d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
490673d80debSLuiz Augusto von Dentz 			break;
490773d80debSLuiz Augusto von Dentz 	}
490873d80debSLuiz Augusto von Dentz 
4909bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4910bf4c6325SGustavo F. Padovan 
491173d80debSLuiz Augusto von Dentz 	if (!chan)
491273d80debSLuiz Augusto von Dentz 		return NULL;
491373d80debSLuiz Augusto von Dentz 
491473d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
491573d80debSLuiz Augusto von Dentz 	case ACL_LINK:
491673d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
491773d80debSLuiz Augusto von Dentz 		break;
4918bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
4919bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
4920bd1eb66bSAndrei Emeltchenko 		break;
492173d80debSLuiz Augusto von Dentz 	case SCO_LINK:
492273d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
492373d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
492473d80debSLuiz Augusto von Dentz 		break;
492573d80debSLuiz Augusto von Dentz 	case LE_LINK:
492673d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
492773d80debSLuiz Augusto von Dentz 		break;
492873d80debSLuiz Augusto von Dentz 	default:
492973d80debSLuiz Augusto von Dentz 		cnt = 0;
493073d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
493173d80debSLuiz Augusto von Dentz 	}
493273d80debSLuiz Augusto von Dentz 
493373d80debSLuiz Augusto von Dentz 	q = cnt / num;
493473d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
493573d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
493673d80debSLuiz Augusto von Dentz 	return chan;
493773d80debSLuiz Augusto von Dentz }
493873d80debSLuiz Augusto von Dentz 
493902b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
494002b20f0bSLuiz Augusto von Dentz {
494102b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
494202b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
494302b20f0bSLuiz Augusto von Dentz 	int num = 0;
494402b20f0bSLuiz Augusto von Dentz 
494502b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
494602b20f0bSLuiz Augusto von Dentz 
4947bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4948bf4c6325SGustavo F. Padovan 
4949bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
495002b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
495102b20f0bSLuiz Augusto von Dentz 
495202b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
495302b20f0bSLuiz Augusto von Dentz 			continue;
495402b20f0bSLuiz Augusto von Dentz 
495502b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
495602b20f0bSLuiz Augusto von Dentz 			continue;
495702b20f0bSLuiz Augusto von Dentz 
495802b20f0bSLuiz Augusto von Dentz 		num++;
495902b20f0bSLuiz Augusto von Dentz 
49608192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
496102b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
496202b20f0bSLuiz Augusto von Dentz 
496302b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
496402b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
496502b20f0bSLuiz Augusto von Dentz 				continue;
496602b20f0bSLuiz Augusto von Dentz 			}
496702b20f0bSLuiz Augusto von Dentz 
496802b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
496902b20f0bSLuiz Augusto von Dentz 				continue;
497002b20f0bSLuiz Augusto von Dentz 
497102b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
497202b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
497302b20f0bSLuiz Augusto von Dentz 				continue;
497402b20f0bSLuiz Augusto von Dentz 
497502b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
497602b20f0bSLuiz Augusto von Dentz 
497702b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
497802b20f0bSLuiz Augusto von Dentz 			       skb->priority);
497902b20f0bSLuiz Augusto von Dentz 		}
498002b20f0bSLuiz Augusto von Dentz 
498102b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
498202b20f0bSLuiz Augusto von Dentz 			break;
498302b20f0bSLuiz Augusto von Dentz 	}
4984bf4c6325SGustavo F. Padovan 
4985bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4986bf4c6325SGustavo F. Padovan 
498702b20f0bSLuiz Augusto von Dentz }
498802b20f0bSLuiz Augusto von Dentz 
4989b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
4990b71d385aSAndrei Emeltchenko {
4991b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
4992b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
4993b71d385aSAndrei Emeltchenko }
4994b71d385aSAndrei Emeltchenko 
49956039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
49961da177e4SLinus Torvalds {
49974a964404SMarcel Holtmann 	if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
49981da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
49991da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
500063d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
50015f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
5002bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
50031da177e4SLinus Torvalds 	}
500463d2bc1bSAndrei Emeltchenko }
50051da177e4SLinus Torvalds 
50066039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
500763d2bc1bSAndrei Emeltchenko {
500863d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
500963d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
501063d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
501163d2bc1bSAndrei Emeltchenko 	int quote;
501263d2bc1bSAndrei Emeltchenko 
501363d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
501404837f64SMarcel Holtmann 
501573d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
501673d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
5017ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
5018ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
501973d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
502073d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
502173d80debSLuiz Augusto von Dentz 
5022ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
5023ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
5024ec1cce24SLuiz Augusto von Dentz 				break;
5025ec1cce24SLuiz Augusto von Dentz 
5026ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
5027ec1cce24SLuiz Augusto von Dentz 
502873d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
502973d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
503004837f64SMarcel Holtmann 
503157d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
50321da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
50331da177e4SLinus Torvalds 
50341da177e4SLinus Torvalds 			hdev->acl_cnt--;
503573d80debSLuiz Augusto von Dentz 			chan->sent++;
503673d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
50371da177e4SLinus Torvalds 		}
50381da177e4SLinus Torvalds 	}
503902b20f0bSLuiz Augusto von Dentz 
504002b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
504102b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
50421da177e4SLinus Torvalds }
50431da177e4SLinus Torvalds 
50446039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
5045b71d385aSAndrei Emeltchenko {
504663d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
5047b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
5048b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
5049b71d385aSAndrei Emeltchenko 	int quote;
5050bd1eb66bSAndrei Emeltchenko 	u8 type;
5051b71d385aSAndrei Emeltchenko 
505263d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
5053b71d385aSAndrei Emeltchenko 
5054bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
5055bd1eb66bSAndrei Emeltchenko 
5056bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
5057bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
5058bd1eb66bSAndrei Emeltchenko 	else
5059bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
5060bd1eb66bSAndrei Emeltchenko 
5061b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
5062bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
5063b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
5064b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
5065b71d385aSAndrei Emeltchenko 			int blocks;
5066b71d385aSAndrei Emeltchenko 
5067b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
5068b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
5069b71d385aSAndrei Emeltchenko 
5070b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
5071b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
5072b71d385aSAndrei Emeltchenko 				break;
5073b71d385aSAndrei Emeltchenko 
5074b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
5075b71d385aSAndrei Emeltchenko 
5076b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
5077b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
5078b71d385aSAndrei Emeltchenko 				return;
5079b71d385aSAndrei Emeltchenko 
5080b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
5081b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
5082b71d385aSAndrei Emeltchenko 
508357d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
5084b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
5085b71d385aSAndrei Emeltchenko 
5086b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
5087b71d385aSAndrei Emeltchenko 			quote -= blocks;
5088b71d385aSAndrei Emeltchenko 
5089b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
5090b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
5091b71d385aSAndrei Emeltchenko 		}
5092b71d385aSAndrei Emeltchenko 	}
5093b71d385aSAndrei Emeltchenko 
5094b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
5095bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
5096b71d385aSAndrei Emeltchenko }
5097b71d385aSAndrei Emeltchenko 
50986039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
5099b71d385aSAndrei Emeltchenko {
5100b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
5101b71d385aSAndrei Emeltchenko 
5102bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
5103bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR)
5104bd1eb66bSAndrei Emeltchenko 		return;
5105bd1eb66bSAndrei Emeltchenko 
5106bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
5107bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
5108b71d385aSAndrei Emeltchenko 		return;
5109b71d385aSAndrei Emeltchenko 
5110b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
5111b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
5112b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
5113b71d385aSAndrei Emeltchenko 		break;
5114b71d385aSAndrei Emeltchenko 
5115b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
5116b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
5117b71d385aSAndrei Emeltchenko 		break;
5118b71d385aSAndrei Emeltchenko 	}
5119b71d385aSAndrei Emeltchenko }
5120b71d385aSAndrei Emeltchenko 
51211da177e4SLinus Torvalds /* Schedule SCO */
51226039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev)
51231da177e4SLinus Torvalds {
51241da177e4SLinus Torvalds 	struct hci_conn *conn;
51251da177e4SLinus Torvalds 	struct sk_buff *skb;
51261da177e4SLinus Torvalds 	int quote;
51271da177e4SLinus Torvalds 
51281da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
51291da177e4SLinus Torvalds 
513052087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
513152087a79SLuiz Augusto von Dentz 		return;
513252087a79SLuiz Augusto von Dentz 
51331da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
51341da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
51351da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
513657d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
51371da177e4SLinus Torvalds 
51381da177e4SLinus Torvalds 			conn->sent++;
51391da177e4SLinus Torvalds 			if (conn->sent == ~0)
51401da177e4SLinus Torvalds 				conn->sent = 0;
51411da177e4SLinus Torvalds 		}
51421da177e4SLinus Torvalds 	}
51431da177e4SLinus Torvalds }
51441da177e4SLinus Torvalds 
51456039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev)
5146b6a0dc82SMarcel Holtmann {
5147b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
5148b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
5149b6a0dc82SMarcel Holtmann 	int quote;
5150b6a0dc82SMarcel Holtmann 
5151b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
5152b6a0dc82SMarcel Holtmann 
515352087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
515452087a79SLuiz Augusto von Dentz 		return;
515552087a79SLuiz Augusto von Dentz 
51568fc9ced3SGustavo Padovan 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
51578fc9ced3SGustavo Padovan 						     &quote))) {
5158b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
5159b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
516057d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
5161b6a0dc82SMarcel Holtmann 
5162b6a0dc82SMarcel Holtmann 			conn->sent++;
5163b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
5164b6a0dc82SMarcel Holtmann 				conn->sent = 0;
5165b6a0dc82SMarcel Holtmann 		}
5166b6a0dc82SMarcel Holtmann 	}
5167b6a0dc82SMarcel Holtmann }
5168b6a0dc82SMarcel Holtmann 
51696039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
51706ed58ec5SVille Tervo {
517173d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
51726ed58ec5SVille Tervo 	struct sk_buff *skb;
517302b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
51746ed58ec5SVille Tervo 
51756ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
51766ed58ec5SVille Tervo 
517752087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
517852087a79SLuiz Augusto von Dentz 		return;
517952087a79SLuiz Augusto von Dentz 
51804a964404SMarcel Holtmann 	if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
51816ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
51826ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
5183bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
51846ed58ec5SVille Tervo 		    time_after(jiffies, hdev->le_last_tx + HZ * 45))
5185bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
51866ed58ec5SVille Tervo 	}
51876ed58ec5SVille Tervo 
51886ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
518902b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
519073d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
5191ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
5192ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
519373d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
519473d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
51956ed58ec5SVille Tervo 
5196ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
5197ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
5198ec1cce24SLuiz Augusto von Dentz 				break;
5199ec1cce24SLuiz Augusto von Dentz 
5200ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
5201ec1cce24SLuiz Augusto von Dentz 
520257d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
52036ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
52046ed58ec5SVille Tervo 
52056ed58ec5SVille Tervo 			cnt--;
520673d80debSLuiz Augusto von Dentz 			chan->sent++;
520773d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
52086ed58ec5SVille Tervo 		}
52096ed58ec5SVille Tervo 	}
521073d80debSLuiz Augusto von Dentz 
52116ed58ec5SVille Tervo 	if (hdev->le_pkts)
52126ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
52136ed58ec5SVille Tervo 	else
52146ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
521502b20f0bSLuiz Augusto von Dentz 
521602b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
521702b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
52186ed58ec5SVille Tervo }
52196ed58ec5SVille Tervo 
52203eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
52211da177e4SLinus Torvalds {
52223eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
52231da177e4SLinus Torvalds 	struct sk_buff *skb;
52241da177e4SLinus Torvalds 
52256ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
52266ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
52271da177e4SLinus Torvalds 
522852de599eSMarcel Holtmann 	if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
52291da177e4SLinus Torvalds 		/* Schedule queues and send stuff to HCI driver */
52301da177e4SLinus Torvalds 		hci_sched_acl(hdev);
52311da177e4SLinus Torvalds 		hci_sched_sco(hdev);
5232b6a0dc82SMarcel Holtmann 		hci_sched_esco(hdev);
52336ed58ec5SVille Tervo 		hci_sched_le(hdev);
523452de599eSMarcel Holtmann 	}
52356ed58ec5SVille Tervo 
52361da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
52371da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
523857d17d70SMarcel Holtmann 		hci_send_frame(hdev, skb);
52391da177e4SLinus Torvalds }
52401da177e4SLinus Torvalds 
524125985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
52421da177e4SLinus Torvalds 
52431da177e4SLinus Torvalds /* ACL data packet */
52446039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
52451da177e4SLinus Torvalds {
52461da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
52471da177e4SLinus Torvalds 	struct hci_conn *conn;
52481da177e4SLinus Torvalds 	__u16 handle, flags;
52491da177e4SLinus Torvalds 
52501da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
52511da177e4SLinus Torvalds 
52521da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
52531da177e4SLinus Torvalds 	flags  = hci_flags(handle);
52541da177e4SLinus Torvalds 	handle = hci_handle(handle);
52551da177e4SLinus Torvalds 
5256f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
5257a8c5fb1aSGustavo Padovan 	       handle, flags);
52581da177e4SLinus Torvalds 
52591da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
52601da177e4SLinus Torvalds 
52611da177e4SLinus Torvalds 	hci_dev_lock(hdev);
52621da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
52631da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
52641da177e4SLinus Torvalds 
52651da177e4SLinus Torvalds 	if (conn) {
526665983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
526704837f64SMarcel Holtmann 
52681da177e4SLinus Torvalds 		/* Send to upper protocol */
5269686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
52701da177e4SLinus Torvalds 		return;
52711da177e4SLinus Torvalds 	} else {
52721da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
52731da177e4SLinus Torvalds 		       hdev->name, handle);
52741da177e4SLinus Torvalds 	}
52751da177e4SLinus Torvalds 
52761da177e4SLinus Torvalds 	kfree_skb(skb);
52771da177e4SLinus Torvalds }
52781da177e4SLinus Torvalds 
52791da177e4SLinus Torvalds /* SCO data packet */
52806039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
52811da177e4SLinus Torvalds {
52821da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
52831da177e4SLinus Torvalds 	struct hci_conn *conn;
52841da177e4SLinus Torvalds 	__u16 handle;
52851da177e4SLinus Torvalds 
52861da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
52871da177e4SLinus Torvalds 
52881da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
52891da177e4SLinus Torvalds 
5290f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle);
52911da177e4SLinus Torvalds 
52921da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
52931da177e4SLinus Torvalds 
52941da177e4SLinus Torvalds 	hci_dev_lock(hdev);
52951da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
52961da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
52971da177e4SLinus Torvalds 
52981da177e4SLinus Torvalds 	if (conn) {
52991da177e4SLinus Torvalds 		/* Send to upper protocol */
5300686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
53011da177e4SLinus Torvalds 		return;
53021da177e4SLinus Torvalds 	} else {
53031da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
53041da177e4SLinus Torvalds 		       hdev->name, handle);
53051da177e4SLinus Torvalds 	}
53061da177e4SLinus Torvalds 
53071da177e4SLinus Torvalds 	kfree_skb(skb);
53081da177e4SLinus Torvalds }
53091da177e4SLinus Torvalds 
53109238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
53119238f36aSJohan Hedberg {
53129238f36aSJohan Hedberg 	struct sk_buff *skb;
53139238f36aSJohan Hedberg 
53149238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
53159238f36aSJohan Hedberg 	if (!skb)
53169238f36aSJohan Hedberg 		return true;
53179238f36aSJohan Hedberg 
53189238f36aSJohan Hedberg 	return bt_cb(skb)->req.start;
53199238f36aSJohan Hedberg }
53209238f36aSJohan Hedberg 
532142c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
532242c6b129SJohan Hedberg {
532342c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
532442c6b129SJohan Hedberg 	struct sk_buff *skb;
532542c6b129SJohan Hedberg 	u16 opcode;
532642c6b129SJohan Hedberg 
532742c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
532842c6b129SJohan Hedberg 		return;
532942c6b129SJohan Hedberg 
533042c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
533142c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
533242c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
533342c6b129SJohan Hedberg 		return;
533442c6b129SJohan Hedberg 
533542c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
533642c6b129SJohan Hedberg 	if (!skb)
533742c6b129SJohan Hedberg 		return;
533842c6b129SJohan Hedberg 
533942c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
534042c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
534142c6b129SJohan Hedberg }
534242c6b129SJohan Hedberg 
53439238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status)
53449238f36aSJohan Hedberg {
53459238f36aSJohan Hedberg 	hci_req_complete_t req_complete = NULL;
53469238f36aSJohan Hedberg 	struct sk_buff *skb;
53479238f36aSJohan Hedberg 	unsigned long flags;
53489238f36aSJohan Hedberg 
53499238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
53509238f36aSJohan Hedberg 
535142c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
535242c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
53539238f36aSJohan Hedberg 	 */
535442c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
535542c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
535642c6b129SJohan Hedberg 		 * reset complete event during init and any pending
535742c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
535842c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
535942c6b129SJohan Hedberg 		 * command.
536042c6b129SJohan Hedberg 		 */
536142c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
536242c6b129SJohan Hedberg 			hci_resend_last(hdev);
536342c6b129SJohan Hedberg 
53649238f36aSJohan Hedberg 		return;
536542c6b129SJohan Hedberg 	}
53669238f36aSJohan Hedberg 
53679238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
53689238f36aSJohan Hedberg 	 * this request the request is not yet complete.
53699238f36aSJohan Hedberg 	 */
53709238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
53719238f36aSJohan Hedberg 		return;
53729238f36aSJohan Hedberg 
53739238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
53749238f36aSJohan Hedberg 	 * callback would be found in hdev->sent_cmd instead of the
53759238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
53769238f36aSJohan Hedberg 	 */
53779238f36aSJohan Hedberg 	if (hdev->sent_cmd) {
53789238f36aSJohan Hedberg 		req_complete = bt_cb(hdev->sent_cmd)->req.complete;
537953e21fbcSJohan Hedberg 
538053e21fbcSJohan Hedberg 		if (req_complete) {
538153e21fbcSJohan Hedberg 			/* We must set the complete callback to NULL to
538253e21fbcSJohan Hedberg 			 * avoid calling the callback more than once if
538353e21fbcSJohan Hedberg 			 * this function gets called again.
538453e21fbcSJohan Hedberg 			 */
538553e21fbcSJohan Hedberg 			bt_cb(hdev->sent_cmd)->req.complete = NULL;
538653e21fbcSJohan Hedberg 
53879238f36aSJohan Hedberg 			goto call_complete;
53889238f36aSJohan Hedberg 		}
538953e21fbcSJohan Hedberg 	}
53909238f36aSJohan Hedberg 
53919238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
53929238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
53939238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
53949238f36aSJohan Hedberg 		if (bt_cb(skb)->req.start) {
53959238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
53969238f36aSJohan Hedberg 			break;
53979238f36aSJohan Hedberg 		}
53989238f36aSJohan Hedberg 
53999238f36aSJohan Hedberg 		req_complete = bt_cb(skb)->req.complete;
54009238f36aSJohan Hedberg 		kfree_skb(skb);
54019238f36aSJohan Hedberg 	}
54029238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
54039238f36aSJohan Hedberg 
54049238f36aSJohan Hedberg call_complete:
54059238f36aSJohan Hedberg 	if (req_complete)
54069238f36aSJohan Hedberg 		req_complete(hdev, status);
54079238f36aSJohan Hedberg }
54089238f36aSJohan Hedberg 
5409b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
54101da177e4SLinus Torvalds {
5411b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
54121da177e4SLinus Torvalds 	struct sk_buff *skb;
54131da177e4SLinus Torvalds 
54141da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
54151da177e4SLinus Torvalds 
54161da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
5417cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
5418cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
5419cd82e61cSMarcel Holtmann 
54201da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
54211da177e4SLinus Torvalds 			/* Send copy to the sockets */
5422470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
54231da177e4SLinus Torvalds 		}
54241da177e4SLinus Torvalds 
5425fee746b0SMarcel Holtmann 		if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
54261da177e4SLinus Torvalds 			kfree_skb(skb);
54271da177e4SLinus Torvalds 			continue;
54281da177e4SLinus Torvalds 		}
54291da177e4SLinus Torvalds 
54301da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
54311da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
54320d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
54331da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
54341da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
54351da177e4SLinus Torvalds 				kfree_skb(skb);
54361da177e4SLinus Torvalds 				continue;
54373ff50b79SStephen Hemminger 			}
54381da177e4SLinus Torvalds 		}
54391da177e4SLinus Torvalds 
54401da177e4SLinus Torvalds 		/* Process frame */
54410d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
54421da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
5443b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
54441da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
54451da177e4SLinus Torvalds 			break;
54461da177e4SLinus Torvalds 
54471da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
54481da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
54491da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
54501da177e4SLinus Torvalds 			break;
54511da177e4SLinus Torvalds 
54521da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
54531da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
54541da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
54551da177e4SLinus Torvalds 			break;
54561da177e4SLinus Torvalds 
54571da177e4SLinus Torvalds 		default:
54581da177e4SLinus Torvalds 			kfree_skb(skb);
54591da177e4SLinus Torvalds 			break;
54601da177e4SLinus Torvalds 		}
54611da177e4SLinus Torvalds 	}
54621da177e4SLinus Torvalds }
54631da177e4SLinus Torvalds 
5464c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
54651da177e4SLinus Torvalds {
5466c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
54671da177e4SLinus Torvalds 	struct sk_buff *skb;
54681da177e4SLinus Torvalds 
54692104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
54702104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
54711da177e4SLinus Torvalds 
54721da177e4SLinus Torvalds 	/* Send queued commands */
54735a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
54745a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
54755a08ecceSAndrei Emeltchenko 		if (!skb)
54765a08ecceSAndrei Emeltchenko 			return;
54775a08ecceSAndrei Emeltchenko 
54781da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
54791da177e4SLinus Torvalds 
5480a675d7f1SMarcel Holtmann 		hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
548170f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
54821da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
548357d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
54847bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
548565cc2b49SMarcel Holtmann 				cancel_delayed_work(&hdev->cmd_timer);
54867bdb8a5cSSzymon Janc 			else
548765cc2b49SMarcel Holtmann 				schedule_delayed_work(&hdev->cmd_timer,
548865cc2b49SMarcel Holtmann 						      HCI_CMD_TIMEOUT);
54891da177e4SLinus Torvalds 		} else {
54901da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
5491c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
54921da177e4SLinus Torvalds 		}
54931da177e4SLinus Torvalds 	}
54941da177e4SLinus Torvalds }
5495b1efcc28SAndre Guedes 
5496b1efcc28SAndre Guedes void hci_req_add_le_scan_disable(struct hci_request *req)
5497b1efcc28SAndre Guedes {
5498b1efcc28SAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
5499b1efcc28SAndre Guedes 
5500b1efcc28SAndre Guedes 	memset(&cp, 0, sizeof(cp));
5501b1efcc28SAndre Guedes 	cp.enable = LE_SCAN_DISABLE;
5502b1efcc28SAndre Guedes 	hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
5503b1efcc28SAndre Guedes }
5504a4790dbdSAndre Guedes 
55058540f6c0SMarcel Holtmann static void add_to_white_list(struct hci_request *req,
55068540f6c0SMarcel Holtmann 			      struct hci_conn_params *params)
55078540f6c0SMarcel Holtmann {
55088540f6c0SMarcel Holtmann 	struct hci_cp_le_add_to_white_list cp;
55098540f6c0SMarcel Holtmann 
55108540f6c0SMarcel Holtmann 	cp.bdaddr_type = params->addr_type;
55118540f6c0SMarcel Holtmann 	bacpy(&cp.bdaddr, &params->addr);
55128540f6c0SMarcel Holtmann 
55138540f6c0SMarcel Holtmann 	hci_req_add(req, HCI_OP_LE_ADD_TO_WHITE_LIST, sizeof(cp), &cp);
55148540f6c0SMarcel Holtmann }
55158540f6c0SMarcel Holtmann 
55168540f6c0SMarcel Holtmann static u8 update_white_list(struct hci_request *req)
55178540f6c0SMarcel Holtmann {
55188540f6c0SMarcel Holtmann 	struct hci_dev *hdev = req->hdev;
55198540f6c0SMarcel Holtmann 	struct hci_conn_params *params;
55208540f6c0SMarcel Holtmann 	struct bdaddr_list *b;
55218540f6c0SMarcel Holtmann 	uint8_t white_list_entries = 0;
55228540f6c0SMarcel Holtmann 
55238540f6c0SMarcel Holtmann 	/* Go through the current white list programmed into the
55248540f6c0SMarcel Holtmann 	 * controller one by one and check if that address is still
55258540f6c0SMarcel Holtmann 	 * in the list of pending connections or list of devices to
55268540f6c0SMarcel Holtmann 	 * report. If not present in either list, then queue the
55278540f6c0SMarcel Holtmann 	 * command to remove it from the controller.
55288540f6c0SMarcel Holtmann 	 */
55298540f6c0SMarcel Holtmann 	list_for_each_entry(b, &hdev->le_white_list, list) {
55308540f6c0SMarcel Holtmann 		struct hci_cp_le_del_from_white_list cp;
55318540f6c0SMarcel Holtmann 
55328540f6c0SMarcel Holtmann 		if (hci_pend_le_action_lookup(&hdev->pend_le_conns,
55338540f6c0SMarcel Holtmann 					      &b->bdaddr, b->bdaddr_type) ||
55348540f6c0SMarcel Holtmann 		    hci_pend_le_action_lookup(&hdev->pend_le_reports,
55358540f6c0SMarcel Holtmann 					      &b->bdaddr, b->bdaddr_type)) {
55368540f6c0SMarcel Holtmann 			white_list_entries++;
55378540f6c0SMarcel Holtmann 			continue;
55388540f6c0SMarcel Holtmann 		}
55398540f6c0SMarcel Holtmann 
55408540f6c0SMarcel Holtmann 		cp.bdaddr_type = b->bdaddr_type;
55418540f6c0SMarcel Holtmann 		bacpy(&cp.bdaddr, &b->bdaddr);
55428540f6c0SMarcel Holtmann 
55438540f6c0SMarcel Holtmann 		hci_req_add(req, HCI_OP_LE_DEL_FROM_WHITE_LIST,
55448540f6c0SMarcel Holtmann 			    sizeof(cp), &cp);
55458540f6c0SMarcel Holtmann 	}
55468540f6c0SMarcel Holtmann 
55478540f6c0SMarcel Holtmann 	/* Since all no longer valid white list entries have been
55488540f6c0SMarcel Holtmann 	 * removed, walk through the list of pending connections
55498540f6c0SMarcel Holtmann 	 * and ensure that any new device gets programmed into
55508540f6c0SMarcel Holtmann 	 * the controller.
55518540f6c0SMarcel Holtmann 	 *
55528540f6c0SMarcel Holtmann 	 * If the list of the devices is larger than the list of
55538540f6c0SMarcel Holtmann 	 * available white list entries in the controller, then
55548540f6c0SMarcel Holtmann 	 * just abort and return filer policy value to not use the
55558540f6c0SMarcel Holtmann 	 * white list.
55568540f6c0SMarcel Holtmann 	 */
55578540f6c0SMarcel Holtmann 	list_for_each_entry(params, &hdev->pend_le_conns, action) {
55588540f6c0SMarcel Holtmann 		if (hci_bdaddr_list_lookup(&hdev->le_white_list,
55598540f6c0SMarcel Holtmann 					   &params->addr, params->addr_type))
55608540f6c0SMarcel Holtmann 			continue;
55618540f6c0SMarcel Holtmann 
55628540f6c0SMarcel Holtmann 		if (white_list_entries >= hdev->le_white_list_size) {
55638540f6c0SMarcel Holtmann 			/* Select filter policy to accept all advertising */
55648540f6c0SMarcel Holtmann 			return 0x00;
55658540f6c0SMarcel Holtmann 		}
55668540f6c0SMarcel Holtmann 
556766d8e837SMarcel Holtmann 		if (hci_find_irk_by_addr(hdev, &params->addr,
556866d8e837SMarcel Holtmann 					 params->addr_type)) {
556966d8e837SMarcel Holtmann 			/* White list can not be used with RPAs */
557066d8e837SMarcel Holtmann 			return 0x00;
557166d8e837SMarcel Holtmann 		}
557266d8e837SMarcel Holtmann 
55738540f6c0SMarcel Holtmann 		white_list_entries++;
55748540f6c0SMarcel Holtmann 		add_to_white_list(req, params);
55758540f6c0SMarcel Holtmann 	}
55768540f6c0SMarcel Holtmann 
55778540f6c0SMarcel Holtmann 	/* After adding all new pending connections, walk through
55788540f6c0SMarcel Holtmann 	 * the list of pending reports and also add these to the
55798540f6c0SMarcel Holtmann 	 * white list if there is still space.
55808540f6c0SMarcel Holtmann 	 */
55818540f6c0SMarcel Holtmann 	list_for_each_entry(params, &hdev->pend_le_reports, action) {
55828540f6c0SMarcel Holtmann 		if (hci_bdaddr_list_lookup(&hdev->le_white_list,
55838540f6c0SMarcel Holtmann 					   &params->addr, params->addr_type))
55848540f6c0SMarcel Holtmann 			continue;
55858540f6c0SMarcel Holtmann 
55868540f6c0SMarcel Holtmann 		if (white_list_entries >= hdev->le_white_list_size) {
55878540f6c0SMarcel Holtmann 			/* Select filter policy to accept all advertising */
55888540f6c0SMarcel Holtmann 			return 0x00;
55898540f6c0SMarcel Holtmann 		}
55908540f6c0SMarcel Holtmann 
559166d8e837SMarcel Holtmann 		if (hci_find_irk_by_addr(hdev, &params->addr,
559266d8e837SMarcel Holtmann 					 params->addr_type)) {
559366d8e837SMarcel Holtmann 			/* White list can not be used with RPAs */
559466d8e837SMarcel Holtmann 			return 0x00;
559566d8e837SMarcel Holtmann 		}
559666d8e837SMarcel Holtmann 
55978540f6c0SMarcel Holtmann 		white_list_entries++;
55988540f6c0SMarcel Holtmann 		add_to_white_list(req, params);
55998540f6c0SMarcel Holtmann 	}
56008540f6c0SMarcel Holtmann 
56018540f6c0SMarcel Holtmann 	/* Select filter policy to use white list */
56028540f6c0SMarcel Holtmann 	return 0x01;
56038540f6c0SMarcel Holtmann }
56048540f6c0SMarcel Holtmann 
56058ef30fd3SAndre Guedes void hci_req_add_le_passive_scan(struct hci_request *req)
56068ef30fd3SAndre Guedes {
56078ef30fd3SAndre Guedes 	struct hci_cp_le_set_scan_param param_cp;
56088ef30fd3SAndre Guedes 	struct hci_cp_le_set_scan_enable enable_cp;
56098ef30fd3SAndre Guedes 	struct hci_dev *hdev = req->hdev;
56108ef30fd3SAndre Guedes 	u8 own_addr_type;
56118540f6c0SMarcel Holtmann 	u8 filter_policy;
56128ef30fd3SAndre Guedes 
56136ab535a7SMarcel Holtmann 	/* Set require_privacy to false since no SCAN_REQ are send
56146ab535a7SMarcel Holtmann 	 * during passive scanning. Not using an unresolvable address
56156ab535a7SMarcel Holtmann 	 * here is important so that peer devices using direct
56166ab535a7SMarcel Holtmann 	 * advertising with our address will be correctly reported
56176ab535a7SMarcel Holtmann 	 * by the controller.
56188ef30fd3SAndre Guedes 	 */
56196ab535a7SMarcel Holtmann 	if (hci_update_random_address(req, false, &own_addr_type))
56208ef30fd3SAndre Guedes 		return;
56218ef30fd3SAndre Guedes 
56228540f6c0SMarcel Holtmann 	/* Adding or removing entries from the white list must
56238540f6c0SMarcel Holtmann 	 * happen before enabling scanning. The controller does
56248540f6c0SMarcel Holtmann 	 * not allow white list modification while scanning.
56258540f6c0SMarcel Holtmann 	 */
56268540f6c0SMarcel Holtmann 	filter_policy = update_white_list(req);
56278540f6c0SMarcel Holtmann 
56288ef30fd3SAndre Guedes 	memset(&param_cp, 0, sizeof(param_cp));
56298ef30fd3SAndre Guedes 	param_cp.type = LE_SCAN_PASSIVE;
56308ef30fd3SAndre Guedes 	param_cp.interval = cpu_to_le16(hdev->le_scan_interval);
56318ef30fd3SAndre Guedes 	param_cp.window = cpu_to_le16(hdev->le_scan_window);
56328ef30fd3SAndre Guedes 	param_cp.own_address_type = own_addr_type;
56338540f6c0SMarcel Holtmann 	param_cp.filter_policy = filter_policy;
56348ef30fd3SAndre Guedes 	hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp),
56358ef30fd3SAndre Guedes 		    &param_cp);
56368ef30fd3SAndre Guedes 
56378ef30fd3SAndre Guedes 	memset(&enable_cp, 0, sizeof(enable_cp));
56388ef30fd3SAndre Guedes 	enable_cp.enable = LE_SCAN_ENABLE;
56394340a124SAndre Guedes 	enable_cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
56408ef30fd3SAndre Guedes 	hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp),
56418ef30fd3SAndre Guedes 		    &enable_cp);
56428ef30fd3SAndre Guedes }
56438ef30fd3SAndre Guedes 
5644a4790dbdSAndre Guedes static void update_background_scan_complete(struct hci_dev *hdev, u8 status)
5645a4790dbdSAndre Guedes {
5646a4790dbdSAndre Guedes 	if (status)
5647a4790dbdSAndre Guedes 		BT_DBG("HCI request failed to update background scanning: "
5648a4790dbdSAndre Guedes 		       "status 0x%2.2x", status);
5649a4790dbdSAndre Guedes }
5650a4790dbdSAndre Guedes 
5651a4790dbdSAndre Guedes /* This function controls the background scanning based on hdev->pend_le_conns
5652a4790dbdSAndre Guedes  * list. If there are pending LE connection we start the background scanning,
5653a4790dbdSAndre Guedes  * otherwise we stop it.
5654a4790dbdSAndre Guedes  *
5655a4790dbdSAndre Guedes  * This function requires the caller holds hdev->lock.
5656a4790dbdSAndre Guedes  */
5657a4790dbdSAndre Guedes void hci_update_background_scan(struct hci_dev *hdev)
5658a4790dbdSAndre Guedes {
5659a4790dbdSAndre Guedes 	struct hci_request req;
5660a4790dbdSAndre Guedes 	struct hci_conn *conn;
5661a4790dbdSAndre Guedes 	int err;
5662a4790dbdSAndre Guedes 
5663c20c02d5SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags) ||
5664c20c02d5SMarcel Holtmann 	    test_bit(HCI_INIT, &hdev->flags) ||
5665c20c02d5SMarcel Holtmann 	    test_bit(HCI_SETUP, &hdev->dev_flags) ||
5666d603b76bSMarcel Holtmann 	    test_bit(HCI_CONFIG, &hdev->dev_flags) ||
5667b8221770SMarcel Holtmann 	    test_bit(HCI_AUTO_OFF, &hdev->dev_flags) ||
5668c20c02d5SMarcel Holtmann 	    test_bit(HCI_UNREGISTER, &hdev->dev_flags))
56691c1697c0SMarcel Holtmann 		return;
56701c1697c0SMarcel Holtmann 
5671a70f4b5fSJohan Hedberg 	/* No point in doing scanning if LE support hasn't been enabled */
5672a70f4b5fSJohan Hedberg 	if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags))
5673a70f4b5fSJohan Hedberg 		return;
5674a70f4b5fSJohan Hedberg 
5675ae23ada4SJohan Hedberg 	/* If discovery is active don't interfere with it */
5676ae23ada4SJohan Hedberg 	if (hdev->discovery.state != DISCOVERY_STOPPED)
5677ae23ada4SJohan Hedberg 		return;
5678ae23ada4SJohan Hedberg 
5679ee3c3ca5SMarcel Holtmann 	/* Reset RSSI and UUID filters when starting background scanning
5680ee3c3ca5SMarcel Holtmann 	 * since these filters are meant for service discovery only.
5681ee3c3ca5SMarcel Holtmann 	 *
5682ee3c3ca5SMarcel Holtmann 	 * The Start Discovery and Start Service Discovery operations
5683ee3c3ca5SMarcel Holtmann 	 * ensure to set proper values for RSSI threshold and UUID
5684ee3c3ca5SMarcel Holtmann 	 * filter list. So it is safe to just reset them here.
5685ee3c3ca5SMarcel Holtmann 	 */
5686ee3c3ca5SMarcel Holtmann 	hci_discovery_filter_clear(hdev);
5687ee3c3ca5SMarcel Holtmann 
5688a4790dbdSAndre Guedes 	hci_req_init(&req, hdev);
5689a4790dbdSAndre Guedes 
5690d1d588c1SJohan Hedberg 	if (list_empty(&hdev->pend_le_conns) &&
569166f8455aSJohan Hedberg 	    list_empty(&hdev->pend_le_reports)) {
56920d2bf134SJohan Hedberg 		/* If there is no pending LE connections or devices
56930d2bf134SJohan Hedberg 		 * to be scanned for, we should stop the background
56940d2bf134SJohan Hedberg 		 * scanning.
5695a4790dbdSAndre Guedes 		 */
5696a4790dbdSAndre Guedes 
5697a4790dbdSAndre Guedes 		/* If controller is not scanning we are done. */
5698a4790dbdSAndre Guedes 		if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags))
5699a4790dbdSAndre Guedes 			return;
5700a4790dbdSAndre Guedes 
5701a4790dbdSAndre Guedes 		hci_req_add_le_scan_disable(&req);
5702a4790dbdSAndre Guedes 
5703a4790dbdSAndre Guedes 		BT_DBG("%s stopping background scanning", hdev->name);
5704a4790dbdSAndre Guedes 	} else {
5705a4790dbdSAndre Guedes 		/* If there is at least one pending LE connection, we should
5706a4790dbdSAndre Guedes 		 * keep the background scan running.
5707a4790dbdSAndre Guedes 		 */
5708a4790dbdSAndre Guedes 
5709a4790dbdSAndre Guedes 		/* If controller is connecting, we should not start scanning
5710a4790dbdSAndre Guedes 		 * since some controllers are not able to scan and connect at
5711a4790dbdSAndre Guedes 		 * the same time.
5712a4790dbdSAndre Guedes 		 */
5713a4790dbdSAndre Guedes 		conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
5714a4790dbdSAndre Guedes 		if (conn)
5715a4790dbdSAndre Guedes 			return;
5716a4790dbdSAndre Guedes 
57174340a124SAndre Guedes 		/* If controller is currently scanning, we stop it to ensure we
57184340a124SAndre Guedes 		 * don't miss any advertising (due to duplicates filter).
57194340a124SAndre Guedes 		 */
57204340a124SAndre Guedes 		if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
57214340a124SAndre Guedes 			hci_req_add_le_scan_disable(&req);
57224340a124SAndre Guedes 
57238ef30fd3SAndre Guedes 		hci_req_add_le_passive_scan(&req);
5724a4790dbdSAndre Guedes 
5725a4790dbdSAndre Guedes 		BT_DBG("%s starting background scanning", hdev->name);
5726a4790dbdSAndre Guedes 	}
5727a4790dbdSAndre Guedes 
5728a4790dbdSAndre Guedes 	err = hci_req_run(&req, update_background_scan_complete);
5729a4790dbdSAndre Guedes 	if (err)
5730a4790dbdSAndre Guedes 		BT_ERR("Failed to run HCI request: err %d", err);
5731a4790dbdSAndre Guedes }
5732432df05eSJohan Hedberg 
573322f433dcSJohan Hedberg static bool disconnected_whitelist_entries(struct hci_dev *hdev)
573422f433dcSJohan Hedberg {
573522f433dcSJohan Hedberg 	struct bdaddr_list *b;
573622f433dcSJohan Hedberg 
573722f433dcSJohan Hedberg 	list_for_each_entry(b, &hdev->whitelist, list) {
573822f433dcSJohan Hedberg 		struct hci_conn *conn;
573922f433dcSJohan Hedberg 
574022f433dcSJohan Hedberg 		conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &b->bdaddr);
574122f433dcSJohan Hedberg 		if (!conn)
574222f433dcSJohan Hedberg 			return true;
574322f433dcSJohan Hedberg 
574422f433dcSJohan Hedberg 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
574522f433dcSJohan Hedberg 			return true;
574622f433dcSJohan Hedberg 	}
574722f433dcSJohan Hedberg 
574822f433dcSJohan Hedberg 	return false;
574922f433dcSJohan Hedberg }
575022f433dcSJohan Hedberg 
5751432df05eSJohan Hedberg void hci_update_page_scan(struct hci_dev *hdev, struct hci_request *req)
5752432df05eSJohan Hedberg {
5753432df05eSJohan Hedberg 	u8 scan;
5754432df05eSJohan Hedberg 
5755432df05eSJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
5756432df05eSJohan Hedberg 		return;
5757432df05eSJohan Hedberg 
5758432df05eSJohan Hedberg 	if (!hdev_is_powered(hdev))
5759432df05eSJohan Hedberg 		return;
5760432df05eSJohan Hedberg 
5761432df05eSJohan Hedberg 	if (mgmt_powering_down(hdev))
5762432df05eSJohan Hedberg 		return;
5763432df05eSJohan Hedberg 
5764432df05eSJohan Hedberg 	if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags) ||
576522f433dcSJohan Hedberg 	    disconnected_whitelist_entries(hdev))
5766432df05eSJohan Hedberg 		scan = SCAN_PAGE;
5767432df05eSJohan Hedberg 	else
5768432df05eSJohan Hedberg 		scan = SCAN_DISABLED;
5769432df05eSJohan Hedberg 
5770432df05eSJohan Hedberg 	if (test_bit(HCI_PSCAN, &hdev->flags) == !!(scan & SCAN_PAGE))
5771432df05eSJohan Hedberg 		return;
5772432df05eSJohan Hedberg 
5773432df05eSJohan Hedberg 	if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
5774432df05eSJohan Hedberg 		scan |= SCAN_INQUIRY;
5775432df05eSJohan Hedberg 
5776432df05eSJohan Hedberg 	if (req)
5777432df05eSJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
5778432df05eSJohan Hedberg 	else
5779432df05eSJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
5780432df05eSJohan Hedberg }
5781