xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 0857dd3b)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds    BlueZ - Bluetooth protocol stack for Linux
31da177e4SLinus Torvalds    Copyright (C) 2000-2001 Qualcomm Incorporated
4590051deSGustavo F. Padovan    Copyright (C) 2011 ProFUSION Embedded Systems
51da177e4SLinus Torvalds 
61da177e4SLinus Torvalds    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
71da177e4SLinus Torvalds 
81da177e4SLinus Torvalds    This program is free software; you can redistribute it and/or modify
91da177e4SLinus Torvalds    it under the terms of the GNU General Public License version 2 as
101da177e4SLinus Torvalds    published by the Free Software Foundation;
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
131da177e4SLinus Torvalds    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
141da177e4SLinus Torvalds    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
151da177e4SLinus Torvalds    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
161da177e4SLinus Torvalds    CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
171da177e4SLinus Torvalds    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
181da177e4SLinus Torvalds    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
191da177e4SLinus Torvalds    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
201da177e4SLinus Torvalds 
211da177e4SLinus Torvalds    ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
221da177e4SLinus Torvalds    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
231da177e4SLinus Torvalds    SOFTWARE IS DISCLAIMED.
241da177e4SLinus Torvalds */
251da177e4SLinus Torvalds 
261da177e4SLinus Torvalds /* Bluetooth HCI core. */
271da177e4SLinus Torvalds 
288c520a59SGustavo Padovan #include <linux/export.h>
293df92b31SSasha Levin #include <linux/idr.h>
30611b30f7SMarcel Holtmann #include <linux/rfkill.h>
31baf27f6eSMarcel Holtmann #include <linux/debugfs.h>
3299780a7bSJohan Hedberg #include <linux/crypto.h>
3347219839SMarcel Holtmann #include <asm/unaligned.h>
341da177e4SLinus Torvalds 
351da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
361da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
374bc58f51SJohan Hedberg #include <net/bluetooth/l2cap.h>
38af58925cSMarcel Holtmann #include <net/bluetooth/mgmt.h>
391da177e4SLinus Torvalds 
400857dd3bSJohan Hedberg #include "hci_request.h"
41970c4e46SJohan Hedberg #include "smp.h"
42970c4e46SJohan Hedberg 
43b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work);
44c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work);
453eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work);
461da177e4SLinus Torvalds 
471da177e4SLinus Torvalds /* HCI device list */
481da177e4SLinus Torvalds LIST_HEAD(hci_dev_list);
491da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock);
501da177e4SLinus Torvalds 
511da177e4SLinus Torvalds /* HCI callback list */
521da177e4SLinus Torvalds LIST_HEAD(hci_cb_list);
531da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock);
541da177e4SLinus Torvalds 
553df92b31SSasha Levin /* HCI ID Numbering */
563df92b31SSasha Levin static DEFINE_IDA(hci_index_ida);
573df92b31SSasha Levin 
58899de765SMarcel Holtmann /* ----- HCI requests ----- */
59899de765SMarcel Holtmann 
60899de765SMarcel Holtmann #define HCI_REQ_DONE	  0
61899de765SMarcel Holtmann #define HCI_REQ_PEND	  1
62899de765SMarcel Holtmann #define HCI_REQ_CANCELED  2
63899de765SMarcel Holtmann 
64899de765SMarcel Holtmann #define hci_req_lock(d)		mutex_lock(&d->req_lock)
65899de765SMarcel Holtmann #define hci_req_unlock(d)	mutex_unlock(&d->req_lock)
66899de765SMarcel Holtmann 
671da177e4SLinus Torvalds /* ---- HCI notifications ---- */
681da177e4SLinus Torvalds 
696516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event)
701da177e4SLinus Torvalds {
71040030efSMarcel Holtmann 	hci_sock_dev_event(hdev, event);
721da177e4SLinus Torvalds }
731da177e4SLinus Torvalds 
74baf27f6eSMarcel Holtmann /* ---- HCI debugfs entries ---- */
75baf27f6eSMarcel Holtmann 
764b4148e9SMarcel Holtmann static ssize_t dut_mode_read(struct file *file, char __user *user_buf,
774b4148e9SMarcel Holtmann 			     size_t count, loff_t *ppos)
784b4148e9SMarcel Holtmann {
794b4148e9SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
804b4148e9SMarcel Holtmann 	char buf[3];
814b4148e9SMarcel Holtmann 
82111902f7SMarcel Holtmann 	buf[0] = test_bit(HCI_DUT_MODE, &hdev->dbg_flags) ? 'Y': 'N';
834b4148e9SMarcel Holtmann 	buf[1] = '\n';
844b4148e9SMarcel Holtmann 	buf[2] = '\0';
854b4148e9SMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
864b4148e9SMarcel Holtmann }
874b4148e9SMarcel Holtmann 
884b4148e9SMarcel Holtmann static ssize_t dut_mode_write(struct file *file, const char __user *user_buf,
894b4148e9SMarcel Holtmann 			      size_t count, loff_t *ppos)
904b4148e9SMarcel Holtmann {
914b4148e9SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
924b4148e9SMarcel Holtmann 	struct sk_buff *skb;
934b4148e9SMarcel Holtmann 	char buf[32];
944b4148e9SMarcel Holtmann 	size_t buf_size = min(count, (sizeof(buf)-1));
954b4148e9SMarcel Holtmann 	bool enable;
964b4148e9SMarcel Holtmann 	int err;
974b4148e9SMarcel Holtmann 
984b4148e9SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
994b4148e9SMarcel Holtmann 		return -ENETDOWN;
1004b4148e9SMarcel Holtmann 
1014b4148e9SMarcel Holtmann 	if (copy_from_user(buf, user_buf, buf_size))
1024b4148e9SMarcel Holtmann 		return -EFAULT;
1034b4148e9SMarcel Holtmann 
1044b4148e9SMarcel Holtmann 	buf[buf_size] = '\0';
1054b4148e9SMarcel Holtmann 	if (strtobool(buf, &enable))
1064b4148e9SMarcel Holtmann 		return -EINVAL;
1074b4148e9SMarcel Holtmann 
108111902f7SMarcel Holtmann 	if (enable == test_bit(HCI_DUT_MODE, &hdev->dbg_flags))
1094b4148e9SMarcel Holtmann 		return -EALREADY;
1104b4148e9SMarcel Holtmann 
1114b4148e9SMarcel Holtmann 	hci_req_lock(hdev);
1124b4148e9SMarcel Holtmann 	if (enable)
1134b4148e9SMarcel Holtmann 		skb = __hci_cmd_sync(hdev, HCI_OP_ENABLE_DUT_MODE, 0, NULL,
1144b4148e9SMarcel Holtmann 				     HCI_CMD_TIMEOUT);
1154b4148e9SMarcel Holtmann 	else
1164b4148e9SMarcel Holtmann 		skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL,
1174b4148e9SMarcel Holtmann 				     HCI_CMD_TIMEOUT);
1184b4148e9SMarcel Holtmann 	hci_req_unlock(hdev);
1194b4148e9SMarcel Holtmann 
1204b4148e9SMarcel Holtmann 	if (IS_ERR(skb))
1214b4148e9SMarcel Holtmann 		return PTR_ERR(skb);
1224b4148e9SMarcel Holtmann 
1234b4148e9SMarcel Holtmann 	err = -bt_to_errno(skb->data[0]);
1244b4148e9SMarcel Holtmann 	kfree_skb(skb);
1254b4148e9SMarcel Holtmann 
1264b4148e9SMarcel Holtmann 	if (err < 0)
1274b4148e9SMarcel Holtmann 		return err;
1284b4148e9SMarcel Holtmann 
129111902f7SMarcel Holtmann 	change_bit(HCI_DUT_MODE, &hdev->dbg_flags);
1304b4148e9SMarcel Holtmann 
1314b4148e9SMarcel Holtmann 	return count;
1324b4148e9SMarcel Holtmann }
1334b4148e9SMarcel Holtmann 
1344b4148e9SMarcel Holtmann static const struct file_operations dut_mode_fops = {
1354b4148e9SMarcel Holtmann 	.open		= simple_open,
1364b4148e9SMarcel Holtmann 	.read		= dut_mode_read,
1374b4148e9SMarcel Holtmann 	.write		= dut_mode_write,
1384b4148e9SMarcel Holtmann 	.llseek		= default_llseek,
1394b4148e9SMarcel Holtmann };
1404b4148e9SMarcel Holtmann 
141dfb826a8SMarcel Holtmann static int features_show(struct seq_file *f, void *ptr)
142dfb826a8SMarcel Holtmann {
143dfb826a8SMarcel Holtmann 	struct hci_dev *hdev = f->private;
144dfb826a8SMarcel Holtmann 	u8 p;
145dfb826a8SMarcel Holtmann 
146dfb826a8SMarcel Holtmann 	hci_dev_lock(hdev);
147dfb826a8SMarcel Holtmann 	for (p = 0; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
148cfbb2b5bSMarcel Holtmann 		seq_printf(f, "%2u: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
149dfb826a8SMarcel Holtmann 			   "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", p,
150dfb826a8SMarcel Holtmann 			   hdev->features[p][0], hdev->features[p][1],
151dfb826a8SMarcel Holtmann 			   hdev->features[p][2], hdev->features[p][3],
152dfb826a8SMarcel Holtmann 			   hdev->features[p][4], hdev->features[p][5],
153dfb826a8SMarcel Holtmann 			   hdev->features[p][6], hdev->features[p][7]);
154dfb826a8SMarcel Holtmann 	}
155cfbb2b5bSMarcel Holtmann 	if (lmp_le_capable(hdev))
156cfbb2b5bSMarcel Holtmann 		seq_printf(f, "LE: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
157cfbb2b5bSMarcel Holtmann 			   "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n",
158cfbb2b5bSMarcel Holtmann 			   hdev->le_features[0], hdev->le_features[1],
159cfbb2b5bSMarcel Holtmann 			   hdev->le_features[2], hdev->le_features[3],
160cfbb2b5bSMarcel Holtmann 			   hdev->le_features[4], hdev->le_features[5],
161cfbb2b5bSMarcel Holtmann 			   hdev->le_features[6], hdev->le_features[7]);
162dfb826a8SMarcel Holtmann 	hci_dev_unlock(hdev);
163dfb826a8SMarcel Holtmann 
164dfb826a8SMarcel Holtmann 	return 0;
165dfb826a8SMarcel Holtmann }
166dfb826a8SMarcel Holtmann 
167dfb826a8SMarcel Holtmann static int features_open(struct inode *inode, struct file *file)
168dfb826a8SMarcel Holtmann {
169dfb826a8SMarcel Holtmann 	return single_open(file, features_show, inode->i_private);
170dfb826a8SMarcel Holtmann }
171dfb826a8SMarcel Holtmann 
172dfb826a8SMarcel Holtmann static const struct file_operations features_fops = {
173dfb826a8SMarcel Holtmann 	.open		= features_open,
174dfb826a8SMarcel Holtmann 	.read		= seq_read,
175dfb826a8SMarcel Holtmann 	.llseek		= seq_lseek,
176dfb826a8SMarcel Holtmann 	.release	= single_release,
177dfb826a8SMarcel Holtmann };
178dfb826a8SMarcel Holtmann 
17970afe0b8SMarcel Holtmann static int blacklist_show(struct seq_file *f, void *p)
18070afe0b8SMarcel Holtmann {
18170afe0b8SMarcel Holtmann 	struct hci_dev *hdev = f->private;
18270afe0b8SMarcel Holtmann 	struct bdaddr_list *b;
18370afe0b8SMarcel Holtmann 
18470afe0b8SMarcel Holtmann 	hci_dev_lock(hdev);
18570afe0b8SMarcel Holtmann 	list_for_each_entry(b, &hdev->blacklist, list)
186b25f0785SMarcel Holtmann 		seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type);
18770afe0b8SMarcel Holtmann 	hci_dev_unlock(hdev);
18870afe0b8SMarcel Holtmann 
18970afe0b8SMarcel Holtmann 	return 0;
19070afe0b8SMarcel Holtmann }
19170afe0b8SMarcel Holtmann 
19270afe0b8SMarcel Holtmann static int blacklist_open(struct inode *inode, struct file *file)
19370afe0b8SMarcel Holtmann {
19470afe0b8SMarcel Holtmann 	return single_open(file, blacklist_show, inode->i_private);
19570afe0b8SMarcel Holtmann }
19670afe0b8SMarcel Holtmann 
19770afe0b8SMarcel Holtmann static const struct file_operations blacklist_fops = {
19870afe0b8SMarcel Holtmann 	.open		= blacklist_open,
19970afe0b8SMarcel Holtmann 	.read		= seq_read,
20070afe0b8SMarcel Holtmann 	.llseek		= seq_lseek,
20170afe0b8SMarcel Holtmann 	.release	= single_release,
20270afe0b8SMarcel Holtmann };
20370afe0b8SMarcel Holtmann 
20447219839SMarcel Holtmann static int uuids_show(struct seq_file *f, void *p)
20547219839SMarcel Holtmann {
20647219839SMarcel Holtmann 	struct hci_dev *hdev = f->private;
20747219839SMarcel Holtmann 	struct bt_uuid *uuid;
20847219839SMarcel Holtmann 
20947219839SMarcel Holtmann 	hci_dev_lock(hdev);
21047219839SMarcel Holtmann 	list_for_each_entry(uuid, &hdev->uuids, list) {
21158f01aa9SMarcel Holtmann 		u8 i, val[16];
21247219839SMarcel Holtmann 
21358f01aa9SMarcel Holtmann 		/* The Bluetooth UUID values are stored in big endian,
21458f01aa9SMarcel Holtmann 		 * but with reversed byte order. So convert them into
21558f01aa9SMarcel Holtmann 		 * the right order for the %pUb modifier.
21658f01aa9SMarcel Holtmann 		 */
21758f01aa9SMarcel Holtmann 		for (i = 0; i < 16; i++)
21858f01aa9SMarcel Holtmann 			val[i] = uuid->uuid[15 - i];
21947219839SMarcel Holtmann 
22058f01aa9SMarcel Holtmann 		seq_printf(f, "%pUb\n", val);
22147219839SMarcel Holtmann 	}
22247219839SMarcel Holtmann 	hci_dev_unlock(hdev);
22347219839SMarcel Holtmann 
22447219839SMarcel Holtmann 	return 0;
22547219839SMarcel Holtmann }
22647219839SMarcel Holtmann 
22747219839SMarcel Holtmann static int uuids_open(struct inode *inode, struct file *file)
22847219839SMarcel Holtmann {
22947219839SMarcel Holtmann 	return single_open(file, uuids_show, inode->i_private);
23047219839SMarcel Holtmann }
23147219839SMarcel Holtmann 
23247219839SMarcel Holtmann static const struct file_operations uuids_fops = {
23347219839SMarcel Holtmann 	.open		= uuids_open,
23447219839SMarcel Holtmann 	.read		= seq_read,
23547219839SMarcel Holtmann 	.llseek		= seq_lseek,
23647219839SMarcel Holtmann 	.release	= single_release,
23747219839SMarcel Holtmann };
23847219839SMarcel Holtmann 
239baf27f6eSMarcel Holtmann static int inquiry_cache_show(struct seq_file *f, void *p)
240baf27f6eSMarcel Holtmann {
241baf27f6eSMarcel Holtmann 	struct hci_dev *hdev = f->private;
242baf27f6eSMarcel Holtmann 	struct discovery_state *cache = &hdev->discovery;
243baf27f6eSMarcel Holtmann 	struct inquiry_entry *e;
244baf27f6eSMarcel Holtmann 
245baf27f6eSMarcel Holtmann 	hci_dev_lock(hdev);
246baf27f6eSMarcel Holtmann 
247baf27f6eSMarcel Holtmann 	list_for_each_entry(e, &cache->all, all) {
248baf27f6eSMarcel Holtmann 		struct inquiry_data *data = &e->data;
249baf27f6eSMarcel Holtmann 		seq_printf(f, "%pMR %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n",
250baf27f6eSMarcel Holtmann 			   &data->bdaddr,
251baf27f6eSMarcel Holtmann 			   data->pscan_rep_mode, data->pscan_period_mode,
252baf27f6eSMarcel Holtmann 			   data->pscan_mode, data->dev_class[2],
253baf27f6eSMarcel Holtmann 			   data->dev_class[1], data->dev_class[0],
254baf27f6eSMarcel Holtmann 			   __le16_to_cpu(data->clock_offset),
255baf27f6eSMarcel Holtmann 			   data->rssi, data->ssp_mode, e->timestamp);
256baf27f6eSMarcel Holtmann 	}
257baf27f6eSMarcel Holtmann 
258baf27f6eSMarcel Holtmann 	hci_dev_unlock(hdev);
259baf27f6eSMarcel Holtmann 
260baf27f6eSMarcel Holtmann 	return 0;
261baf27f6eSMarcel Holtmann }
262baf27f6eSMarcel Holtmann 
263baf27f6eSMarcel Holtmann static int inquiry_cache_open(struct inode *inode, struct file *file)
264baf27f6eSMarcel Holtmann {
265baf27f6eSMarcel Holtmann 	return single_open(file, inquiry_cache_show, inode->i_private);
266baf27f6eSMarcel Holtmann }
267baf27f6eSMarcel Holtmann 
268baf27f6eSMarcel Holtmann static const struct file_operations inquiry_cache_fops = {
269baf27f6eSMarcel Holtmann 	.open		= inquiry_cache_open,
270baf27f6eSMarcel Holtmann 	.read		= seq_read,
271baf27f6eSMarcel Holtmann 	.llseek		= seq_lseek,
272baf27f6eSMarcel Holtmann 	.release	= single_release,
273baf27f6eSMarcel Holtmann };
274baf27f6eSMarcel Holtmann 
27502d08d15SMarcel Holtmann static int link_keys_show(struct seq_file *f, void *ptr)
27602d08d15SMarcel Holtmann {
27702d08d15SMarcel Holtmann 	struct hci_dev *hdev = f->private;
2780378b597SJohan Hedberg 	struct link_key *key;
27902d08d15SMarcel Holtmann 
2800378b597SJohan Hedberg 	rcu_read_lock();
2810378b597SJohan Hedberg 	list_for_each_entry_rcu(key, &hdev->link_keys, list)
28202d08d15SMarcel Holtmann 		seq_printf(f, "%pMR %u %*phN %u\n", &key->bdaddr, key->type,
28302d08d15SMarcel Holtmann 			   HCI_LINK_KEY_SIZE, key->val, key->pin_len);
2840378b597SJohan Hedberg 	rcu_read_unlock();
28502d08d15SMarcel Holtmann 
28602d08d15SMarcel Holtmann 	return 0;
28702d08d15SMarcel Holtmann }
28802d08d15SMarcel Holtmann 
28902d08d15SMarcel Holtmann static int link_keys_open(struct inode *inode, struct file *file)
29002d08d15SMarcel Holtmann {
29102d08d15SMarcel Holtmann 	return single_open(file, link_keys_show, inode->i_private);
29202d08d15SMarcel Holtmann }
29302d08d15SMarcel Holtmann 
29402d08d15SMarcel Holtmann static const struct file_operations link_keys_fops = {
29502d08d15SMarcel Holtmann 	.open		= link_keys_open,
29602d08d15SMarcel Holtmann 	.read		= seq_read,
29702d08d15SMarcel Holtmann 	.llseek		= seq_lseek,
29802d08d15SMarcel Holtmann 	.release	= single_release,
29902d08d15SMarcel Holtmann };
30002d08d15SMarcel Holtmann 
301babdbb3cSMarcel Holtmann static int dev_class_show(struct seq_file *f, void *ptr)
302babdbb3cSMarcel Holtmann {
303babdbb3cSMarcel Holtmann 	struct hci_dev *hdev = f->private;
304babdbb3cSMarcel Holtmann 
305babdbb3cSMarcel Holtmann 	hci_dev_lock(hdev);
306babdbb3cSMarcel Holtmann 	seq_printf(f, "0x%.2x%.2x%.2x\n", hdev->dev_class[2],
307babdbb3cSMarcel Holtmann 		   hdev->dev_class[1], hdev->dev_class[0]);
308babdbb3cSMarcel Holtmann 	hci_dev_unlock(hdev);
309babdbb3cSMarcel Holtmann 
310babdbb3cSMarcel Holtmann 	return 0;
311babdbb3cSMarcel Holtmann }
312babdbb3cSMarcel Holtmann 
313babdbb3cSMarcel Holtmann static int dev_class_open(struct inode *inode, struct file *file)
314babdbb3cSMarcel Holtmann {
315babdbb3cSMarcel Holtmann 	return single_open(file, dev_class_show, inode->i_private);
316babdbb3cSMarcel Holtmann }
317babdbb3cSMarcel Holtmann 
318babdbb3cSMarcel Holtmann static const struct file_operations dev_class_fops = {
319babdbb3cSMarcel Holtmann 	.open		= dev_class_open,
320babdbb3cSMarcel Holtmann 	.read		= seq_read,
321babdbb3cSMarcel Holtmann 	.llseek		= seq_lseek,
322babdbb3cSMarcel Holtmann 	.release	= single_release,
323babdbb3cSMarcel Holtmann };
324babdbb3cSMarcel Holtmann 
325041000b9SMarcel Holtmann static int voice_setting_get(void *data, u64 *val)
326041000b9SMarcel Holtmann {
327041000b9SMarcel Holtmann 	struct hci_dev *hdev = data;
328041000b9SMarcel Holtmann 
329041000b9SMarcel Holtmann 	hci_dev_lock(hdev);
330041000b9SMarcel Holtmann 	*val = hdev->voice_setting;
331041000b9SMarcel Holtmann 	hci_dev_unlock(hdev);
332041000b9SMarcel Holtmann 
333041000b9SMarcel Holtmann 	return 0;
334041000b9SMarcel Holtmann }
335041000b9SMarcel Holtmann 
336041000b9SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(voice_setting_fops, voice_setting_get,
337041000b9SMarcel Holtmann 			NULL, "0x%4.4llx\n");
338041000b9SMarcel Holtmann 
339ebd1e33bSMarcel Holtmann static int auto_accept_delay_set(void *data, u64 val)
340ebd1e33bSMarcel Holtmann {
341ebd1e33bSMarcel Holtmann 	struct hci_dev *hdev = data;
342ebd1e33bSMarcel Holtmann 
343ebd1e33bSMarcel Holtmann 	hci_dev_lock(hdev);
344ebd1e33bSMarcel Holtmann 	hdev->auto_accept_delay = val;
345ebd1e33bSMarcel Holtmann 	hci_dev_unlock(hdev);
346ebd1e33bSMarcel Holtmann 
347ebd1e33bSMarcel Holtmann 	return 0;
348ebd1e33bSMarcel Holtmann }
349ebd1e33bSMarcel Holtmann 
350ebd1e33bSMarcel Holtmann static int auto_accept_delay_get(void *data, u64 *val)
351ebd1e33bSMarcel Holtmann {
352ebd1e33bSMarcel Holtmann 	struct hci_dev *hdev = data;
353ebd1e33bSMarcel Holtmann 
354ebd1e33bSMarcel Holtmann 	hci_dev_lock(hdev);
355ebd1e33bSMarcel Holtmann 	*val = hdev->auto_accept_delay;
356ebd1e33bSMarcel Holtmann 	hci_dev_unlock(hdev);
357ebd1e33bSMarcel Holtmann 
358ebd1e33bSMarcel Holtmann 	return 0;
359ebd1e33bSMarcel Holtmann }
360ebd1e33bSMarcel Holtmann 
361ebd1e33bSMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get,
362ebd1e33bSMarcel Holtmann 			auto_accept_delay_set, "%llu\n");
363ebd1e33bSMarcel Holtmann 
3645afeac14SMarcel Holtmann static ssize_t force_sc_support_read(struct file *file, char __user *user_buf,
3655afeac14SMarcel Holtmann 				     size_t count, loff_t *ppos)
3665afeac14SMarcel Holtmann {
3675afeac14SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
3685afeac14SMarcel Holtmann 	char buf[3];
3695afeac14SMarcel Holtmann 
370111902f7SMarcel Holtmann 	buf[0] = test_bit(HCI_FORCE_SC, &hdev->dbg_flags) ? 'Y': 'N';
3715afeac14SMarcel Holtmann 	buf[1] = '\n';
3725afeac14SMarcel Holtmann 	buf[2] = '\0';
3735afeac14SMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
3745afeac14SMarcel Holtmann }
3755afeac14SMarcel Holtmann 
3765afeac14SMarcel Holtmann static ssize_t force_sc_support_write(struct file *file,
3775afeac14SMarcel Holtmann 				      const char __user *user_buf,
3785afeac14SMarcel Holtmann 				      size_t count, loff_t *ppos)
3795afeac14SMarcel Holtmann {
3805afeac14SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
3815afeac14SMarcel Holtmann 	char buf[32];
3825afeac14SMarcel Holtmann 	size_t buf_size = min(count, (sizeof(buf)-1));
3835afeac14SMarcel Holtmann 	bool enable;
3845afeac14SMarcel Holtmann 
3855afeac14SMarcel Holtmann 	if (test_bit(HCI_UP, &hdev->flags))
3865afeac14SMarcel Holtmann 		return -EBUSY;
3875afeac14SMarcel Holtmann 
3885afeac14SMarcel Holtmann 	if (copy_from_user(buf, user_buf, buf_size))
3895afeac14SMarcel Holtmann 		return -EFAULT;
3905afeac14SMarcel Holtmann 
3915afeac14SMarcel Holtmann 	buf[buf_size] = '\0';
3925afeac14SMarcel Holtmann 	if (strtobool(buf, &enable))
3935afeac14SMarcel Holtmann 		return -EINVAL;
3945afeac14SMarcel Holtmann 
395111902f7SMarcel Holtmann 	if (enable == test_bit(HCI_FORCE_SC, &hdev->dbg_flags))
3965afeac14SMarcel Holtmann 		return -EALREADY;
3975afeac14SMarcel Holtmann 
398111902f7SMarcel Holtmann 	change_bit(HCI_FORCE_SC, &hdev->dbg_flags);
3995afeac14SMarcel Holtmann 
4005afeac14SMarcel Holtmann 	return count;
4015afeac14SMarcel Holtmann }
4025afeac14SMarcel Holtmann 
4035afeac14SMarcel Holtmann static const struct file_operations force_sc_support_fops = {
4045afeac14SMarcel Holtmann 	.open		= simple_open,
4055afeac14SMarcel Holtmann 	.read		= force_sc_support_read,
4065afeac14SMarcel Holtmann 	.write		= force_sc_support_write,
4075afeac14SMarcel Holtmann 	.llseek		= default_llseek,
4085afeac14SMarcel Holtmann };
4095afeac14SMarcel Holtmann 
410858cdc78SJohan Hedberg static ssize_t force_lesc_support_read(struct file *file, char __user *user_buf,
411858cdc78SJohan Hedberg 				       size_t count, loff_t *ppos)
412858cdc78SJohan Hedberg {
413858cdc78SJohan Hedberg 	struct hci_dev *hdev = file->private_data;
414858cdc78SJohan Hedberg 	char buf[3];
415858cdc78SJohan Hedberg 
416858cdc78SJohan Hedberg 	buf[0] = test_bit(HCI_FORCE_LESC, &hdev->dbg_flags) ? 'Y': 'N';
417858cdc78SJohan Hedberg 	buf[1] = '\n';
418858cdc78SJohan Hedberg 	buf[2] = '\0';
419858cdc78SJohan Hedberg 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
420858cdc78SJohan Hedberg }
421858cdc78SJohan Hedberg 
422858cdc78SJohan Hedberg static ssize_t force_lesc_support_write(struct file *file,
423858cdc78SJohan Hedberg 					const char __user *user_buf,
424858cdc78SJohan Hedberg 					size_t count, loff_t *ppos)
425858cdc78SJohan Hedberg {
426858cdc78SJohan Hedberg 	struct hci_dev *hdev = file->private_data;
427858cdc78SJohan Hedberg 	char buf[32];
428858cdc78SJohan Hedberg 	size_t buf_size = min(count, (sizeof(buf)-1));
429858cdc78SJohan Hedberg 	bool enable;
430858cdc78SJohan Hedberg 
431858cdc78SJohan Hedberg 	if (copy_from_user(buf, user_buf, buf_size))
432858cdc78SJohan Hedberg 		return -EFAULT;
433858cdc78SJohan Hedberg 
434858cdc78SJohan Hedberg 	buf[buf_size] = '\0';
435858cdc78SJohan Hedberg 	if (strtobool(buf, &enable))
436858cdc78SJohan Hedberg 		return -EINVAL;
437858cdc78SJohan Hedberg 
438858cdc78SJohan Hedberg 	if (enable == test_bit(HCI_FORCE_LESC, &hdev->dbg_flags))
439858cdc78SJohan Hedberg 		return -EALREADY;
440858cdc78SJohan Hedberg 
441858cdc78SJohan Hedberg 	change_bit(HCI_FORCE_LESC, &hdev->dbg_flags);
442858cdc78SJohan Hedberg 
443858cdc78SJohan Hedberg 	return count;
444858cdc78SJohan Hedberg }
445858cdc78SJohan Hedberg 
446858cdc78SJohan Hedberg static const struct file_operations force_lesc_support_fops = {
447858cdc78SJohan Hedberg 	.open		= simple_open,
448858cdc78SJohan Hedberg 	.read		= force_lesc_support_read,
449858cdc78SJohan Hedberg 	.write		= force_lesc_support_write,
450858cdc78SJohan Hedberg 	.llseek		= default_llseek,
451858cdc78SJohan Hedberg };
452858cdc78SJohan Hedberg 
453134c2a89SMarcel Holtmann static ssize_t sc_only_mode_read(struct file *file, char __user *user_buf,
454134c2a89SMarcel Holtmann 				 size_t count, loff_t *ppos)
455134c2a89SMarcel Holtmann {
456134c2a89SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
457134c2a89SMarcel Holtmann 	char buf[3];
458134c2a89SMarcel Holtmann 
459134c2a89SMarcel Holtmann 	buf[0] = test_bit(HCI_SC_ONLY, &hdev->dev_flags) ? 'Y': 'N';
460134c2a89SMarcel Holtmann 	buf[1] = '\n';
461134c2a89SMarcel Holtmann 	buf[2] = '\0';
462134c2a89SMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
463134c2a89SMarcel Holtmann }
464134c2a89SMarcel Holtmann 
465134c2a89SMarcel Holtmann static const struct file_operations sc_only_mode_fops = {
466134c2a89SMarcel Holtmann 	.open		= simple_open,
467134c2a89SMarcel Holtmann 	.read		= sc_only_mode_read,
468134c2a89SMarcel Holtmann 	.llseek		= default_llseek,
469134c2a89SMarcel Holtmann };
470134c2a89SMarcel Holtmann 
4712bfa3531SMarcel Holtmann static int idle_timeout_set(void *data, u64 val)
4722bfa3531SMarcel Holtmann {
4732bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
4742bfa3531SMarcel Holtmann 
4752bfa3531SMarcel Holtmann 	if (val != 0 && (val < 500 || val > 3600000))
4762bfa3531SMarcel Holtmann 		return -EINVAL;
4772bfa3531SMarcel Holtmann 
4782bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
4792bfa3531SMarcel Holtmann 	hdev->idle_timeout = val;
4802bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
4812bfa3531SMarcel Holtmann 
4822bfa3531SMarcel Holtmann 	return 0;
4832bfa3531SMarcel Holtmann }
4842bfa3531SMarcel Holtmann 
4852bfa3531SMarcel Holtmann static int idle_timeout_get(void *data, u64 *val)
4862bfa3531SMarcel Holtmann {
4872bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
4882bfa3531SMarcel Holtmann 
4892bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
4902bfa3531SMarcel Holtmann 	*val = hdev->idle_timeout;
4912bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
4922bfa3531SMarcel Holtmann 
4932bfa3531SMarcel Holtmann 	return 0;
4942bfa3531SMarcel Holtmann }
4952bfa3531SMarcel Holtmann 
4962bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(idle_timeout_fops, idle_timeout_get,
4972bfa3531SMarcel Holtmann 			idle_timeout_set, "%llu\n");
4982bfa3531SMarcel Holtmann 
499c982b2eaSJohan Hedberg static int rpa_timeout_set(void *data, u64 val)
500c982b2eaSJohan Hedberg {
501c982b2eaSJohan Hedberg 	struct hci_dev *hdev = data;
502c982b2eaSJohan Hedberg 
503c982b2eaSJohan Hedberg 	/* Require the RPA timeout to be at least 30 seconds and at most
504c982b2eaSJohan Hedberg 	 * 24 hours.
505c982b2eaSJohan Hedberg 	 */
506c982b2eaSJohan Hedberg 	if (val < 30 || val > (60 * 60 * 24))
507c982b2eaSJohan Hedberg 		return -EINVAL;
508c982b2eaSJohan Hedberg 
509c982b2eaSJohan Hedberg 	hci_dev_lock(hdev);
510c982b2eaSJohan Hedberg 	hdev->rpa_timeout = val;
511c982b2eaSJohan Hedberg 	hci_dev_unlock(hdev);
512c982b2eaSJohan Hedberg 
513c982b2eaSJohan Hedberg 	return 0;
514c982b2eaSJohan Hedberg }
515c982b2eaSJohan Hedberg 
516c982b2eaSJohan Hedberg static int rpa_timeout_get(void *data, u64 *val)
517c982b2eaSJohan Hedberg {
518c982b2eaSJohan Hedberg 	struct hci_dev *hdev = data;
519c982b2eaSJohan Hedberg 
520c982b2eaSJohan Hedberg 	hci_dev_lock(hdev);
521c982b2eaSJohan Hedberg 	*val = hdev->rpa_timeout;
522c982b2eaSJohan Hedberg 	hci_dev_unlock(hdev);
523c982b2eaSJohan Hedberg 
524c982b2eaSJohan Hedberg 	return 0;
525c982b2eaSJohan Hedberg }
526c982b2eaSJohan Hedberg 
527c982b2eaSJohan Hedberg DEFINE_SIMPLE_ATTRIBUTE(rpa_timeout_fops, rpa_timeout_get,
528c982b2eaSJohan Hedberg 			rpa_timeout_set, "%llu\n");
529c982b2eaSJohan Hedberg 
5302bfa3531SMarcel Holtmann static int sniff_min_interval_set(void *data, u64 val)
5312bfa3531SMarcel Holtmann {
5322bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
5332bfa3531SMarcel Holtmann 
5342bfa3531SMarcel Holtmann 	if (val == 0 || val % 2 || val > hdev->sniff_max_interval)
5352bfa3531SMarcel Holtmann 		return -EINVAL;
5362bfa3531SMarcel Holtmann 
5372bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5382bfa3531SMarcel Holtmann 	hdev->sniff_min_interval = val;
5392bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5402bfa3531SMarcel Holtmann 
5412bfa3531SMarcel Holtmann 	return 0;
5422bfa3531SMarcel Holtmann }
5432bfa3531SMarcel Holtmann 
5442bfa3531SMarcel Holtmann static int sniff_min_interval_get(void *data, u64 *val)
5452bfa3531SMarcel Holtmann {
5462bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
5472bfa3531SMarcel Holtmann 
5482bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5492bfa3531SMarcel Holtmann 	*val = hdev->sniff_min_interval;
5502bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5512bfa3531SMarcel Holtmann 
5522bfa3531SMarcel Holtmann 	return 0;
5532bfa3531SMarcel Holtmann }
5542bfa3531SMarcel Holtmann 
5552bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_min_interval_fops, sniff_min_interval_get,
5562bfa3531SMarcel Holtmann 			sniff_min_interval_set, "%llu\n");
5572bfa3531SMarcel Holtmann 
5582bfa3531SMarcel Holtmann static int sniff_max_interval_set(void *data, u64 val)
5592bfa3531SMarcel Holtmann {
5602bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
5612bfa3531SMarcel Holtmann 
5622bfa3531SMarcel Holtmann 	if (val == 0 || val % 2 || val < hdev->sniff_min_interval)
5632bfa3531SMarcel Holtmann 		return -EINVAL;
5642bfa3531SMarcel Holtmann 
5652bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5662bfa3531SMarcel Holtmann 	hdev->sniff_max_interval = val;
5672bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5682bfa3531SMarcel Holtmann 
5692bfa3531SMarcel Holtmann 	return 0;
5702bfa3531SMarcel Holtmann }
5712bfa3531SMarcel Holtmann 
5722bfa3531SMarcel Holtmann static int sniff_max_interval_get(void *data, u64 *val)
5732bfa3531SMarcel Holtmann {
5742bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
5752bfa3531SMarcel Holtmann 
5762bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5772bfa3531SMarcel Holtmann 	*val = hdev->sniff_max_interval;
5782bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5792bfa3531SMarcel Holtmann 
5802bfa3531SMarcel Holtmann 	return 0;
5812bfa3531SMarcel Holtmann }
5822bfa3531SMarcel Holtmann 
5832bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_max_interval_fops, sniff_max_interval_get,
5842bfa3531SMarcel Holtmann 			sniff_max_interval_set, "%llu\n");
5852bfa3531SMarcel Holtmann 
58631ad1691SAndrzej Kaczmarek static int conn_info_min_age_set(void *data, u64 val)
58731ad1691SAndrzej Kaczmarek {
58831ad1691SAndrzej Kaczmarek 	struct hci_dev *hdev = data;
58931ad1691SAndrzej Kaczmarek 
59031ad1691SAndrzej Kaczmarek 	if (val == 0 || val > hdev->conn_info_max_age)
59131ad1691SAndrzej Kaczmarek 		return -EINVAL;
59231ad1691SAndrzej Kaczmarek 
59331ad1691SAndrzej Kaczmarek 	hci_dev_lock(hdev);
59431ad1691SAndrzej Kaczmarek 	hdev->conn_info_min_age = val;
59531ad1691SAndrzej Kaczmarek 	hci_dev_unlock(hdev);
59631ad1691SAndrzej Kaczmarek 
59731ad1691SAndrzej Kaczmarek 	return 0;
59831ad1691SAndrzej Kaczmarek }
59931ad1691SAndrzej Kaczmarek 
60031ad1691SAndrzej Kaczmarek static int conn_info_min_age_get(void *data, u64 *val)
60131ad1691SAndrzej Kaczmarek {
60231ad1691SAndrzej Kaczmarek 	struct hci_dev *hdev = data;
60331ad1691SAndrzej Kaczmarek 
60431ad1691SAndrzej Kaczmarek 	hci_dev_lock(hdev);
60531ad1691SAndrzej Kaczmarek 	*val = hdev->conn_info_min_age;
60631ad1691SAndrzej Kaczmarek 	hci_dev_unlock(hdev);
60731ad1691SAndrzej Kaczmarek 
60831ad1691SAndrzej Kaczmarek 	return 0;
60931ad1691SAndrzej Kaczmarek }
61031ad1691SAndrzej Kaczmarek 
61131ad1691SAndrzej Kaczmarek DEFINE_SIMPLE_ATTRIBUTE(conn_info_min_age_fops, conn_info_min_age_get,
61231ad1691SAndrzej Kaczmarek 			conn_info_min_age_set, "%llu\n");
61331ad1691SAndrzej Kaczmarek 
61431ad1691SAndrzej Kaczmarek static int conn_info_max_age_set(void *data, u64 val)
61531ad1691SAndrzej Kaczmarek {
61631ad1691SAndrzej Kaczmarek 	struct hci_dev *hdev = data;
61731ad1691SAndrzej Kaczmarek 
61831ad1691SAndrzej Kaczmarek 	if (val == 0 || val < hdev->conn_info_min_age)
61931ad1691SAndrzej Kaczmarek 		return -EINVAL;
62031ad1691SAndrzej Kaczmarek 
62131ad1691SAndrzej Kaczmarek 	hci_dev_lock(hdev);
62231ad1691SAndrzej Kaczmarek 	hdev->conn_info_max_age = val;
62331ad1691SAndrzej Kaczmarek 	hci_dev_unlock(hdev);
62431ad1691SAndrzej Kaczmarek 
62531ad1691SAndrzej Kaczmarek 	return 0;
62631ad1691SAndrzej Kaczmarek }
62731ad1691SAndrzej Kaczmarek 
62831ad1691SAndrzej Kaczmarek static int conn_info_max_age_get(void *data, u64 *val)
62931ad1691SAndrzej Kaczmarek {
63031ad1691SAndrzej Kaczmarek 	struct hci_dev *hdev = data;
63131ad1691SAndrzej Kaczmarek 
63231ad1691SAndrzej Kaczmarek 	hci_dev_lock(hdev);
63331ad1691SAndrzej Kaczmarek 	*val = hdev->conn_info_max_age;
63431ad1691SAndrzej Kaczmarek 	hci_dev_unlock(hdev);
63531ad1691SAndrzej Kaczmarek 
63631ad1691SAndrzej Kaczmarek 	return 0;
63731ad1691SAndrzej Kaczmarek }
63831ad1691SAndrzej Kaczmarek 
63931ad1691SAndrzej Kaczmarek DEFINE_SIMPLE_ATTRIBUTE(conn_info_max_age_fops, conn_info_max_age_get,
64031ad1691SAndrzej Kaczmarek 			conn_info_max_age_set, "%llu\n");
64131ad1691SAndrzej Kaczmarek 
642ac345813SMarcel Holtmann static int identity_show(struct seq_file *f, void *p)
643ac345813SMarcel Holtmann {
644ac345813SMarcel Holtmann 	struct hci_dev *hdev = f->private;
645a1f4c318SJohan Hedberg 	bdaddr_t addr;
646ac345813SMarcel Holtmann 	u8 addr_type;
647ac345813SMarcel Holtmann 
648ac345813SMarcel Holtmann 	hci_dev_lock(hdev);
649ac345813SMarcel Holtmann 
650a1f4c318SJohan Hedberg 	hci_copy_identity_address(hdev, &addr, &addr_type);
651ac345813SMarcel Holtmann 
652a1f4c318SJohan Hedberg 	seq_printf(f, "%pMR (type %u) %*phN %pMR\n", &addr, addr_type,
653473deef2SMarcel Holtmann 		   16, hdev->irk, &hdev->rpa);
654ac345813SMarcel Holtmann 
655ac345813SMarcel Holtmann 	hci_dev_unlock(hdev);
656ac345813SMarcel Holtmann 
657ac345813SMarcel Holtmann 	return 0;
658ac345813SMarcel Holtmann }
659ac345813SMarcel Holtmann 
660ac345813SMarcel Holtmann static int identity_open(struct inode *inode, struct file *file)
661ac345813SMarcel Holtmann {
662ac345813SMarcel Holtmann 	return single_open(file, identity_show, inode->i_private);
663ac345813SMarcel Holtmann }
664ac345813SMarcel Holtmann 
665ac345813SMarcel Holtmann static const struct file_operations identity_fops = {
666ac345813SMarcel Holtmann 	.open		= identity_open,
667ac345813SMarcel Holtmann 	.read		= seq_read,
668ac345813SMarcel Holtmann 	.llseek		= seq_lseek,
669ac345813SMarcel Holtmann 	.release	= single_release,
670ac345813SMarcel Holtmann };
671ac345813SMarcel Holtmann 
6727a4cd51dSMarcel Holtmann static int random_address_show(struct seq_file *f, void *p)
6737a4cd51dSMarcel Holtmann {
6747a4cd51dSMarcel Holtmann 	struct hci_dev *hdev = f->private;
6757a4cd51dSMarcel Holtmann 
6767a4cd51dSMarcel Holtmann 	hci_dev_lock(hdev);
6777a4cd51dSMarcel Holtmann 	seq_printf(f, "%pMR\n", &hdev->random_addr);
6787a4cd51dSMarcel Holtmann 	hci_dev_unlock(hdev);
6797a4cd51dSMarcel Holtmann 
6807a4cd51dSMarcel Holtmann 	return 0;
6817a4cd51dSMarcel Holtmann }
6827a4cd51dSMarcel Holtmann 
6837a4cd51dSMarcel Holtmann static int random_address_open(struct inode *inode, struct file *file)
6847a4cd51dSMarcel Holtmann {
6857a4cd51dSMarcel Holtmann 	return single_open(file, random_address_show, inode->i_private);
6867a4cd51dSMarcel Holtmann }
6877a4cd51dSMarcel Holtmann 
6887a4cd51dSMarcel Holtmann static const struct file_operations random_address_fops = {
6897a4cd51dSMarcel Holtmann 	.open		= random_address_open,
6907a4cd51dSMarcel Holtmann 	.read		= seq_read,
6917a4cd51dSMarcel Holtmann 	.llseek		= seq_lseek,
6927a4cd51dSMarcel Holtmann 	.release	= single_release,
6937a4cd51dSMarcel Holtmann };
6947a4cd51dSMarcel Holtmann 
695e7b8fc92SMarcel Holtmann static int static_address_show(struct seq_file *f, void *p)
696e7b8fc92SMarcel Holtmann {
697e7b8fc92SMarcel Holtmann 	struct hci_dev *hdev = f->private;
698e7b8fc92SMarcel Holtmann 
699e7b8fc92SMarcel Holtmann 	hci_dev_lock(hdev);
700e7b8fc92SMarcel Holtmann 	seq_printf(f, "%pMR\n", &hdev->static_addr);
701e7b8fc92SMarcel Holtmann 	hci_dev_unlock(hdev);
702e7b8fc92SMarcel Holtmann 
703e7b8fc92SMarcel Holtmann 	return 0;
704e7b8fc92SMarcel Holtmann }
705e7b8fc92SMarcel Holtmann 
706e7b8fc92SMarcel Holtmann static int static_address_open(struct inode *inode, struct file *file)
707e7b8fc92SMarcel Holtmann {
708e7b8fc92SMarcel Holtmann 	return single_open(file, static_address_show, inode->i_private);
709e7b8fc92SMarcel Holtmann }
710e7b8fc92SMarcel Holtmann 
711e7b8fc92SMarcel Holtmann static const struct file_operations static_address_fops = {
712e7b8fc92SMarcel Holtmann 	.open		= static_address_open,
713e7b8fc92SMarcel Holtmann 	.read		= seq_read,
714e7b8fc92SMarcel Holtmann 	.llseek		= seq_lseek,
715e7b8fc92SMarcel Holtmann 	.release	= single_release,
716e7b8fc92SMarcel Holtmann };
717e7b8fc92SMarcel Holtmann 
718b32bba6cSMarcel Holtmann static ssize_t force_static_address_read(struct file *file,
719b32bba6cSMarcel Holtmann 					 char __user *user_buf,
720b32bba6cSMarcel Holtmann 					 size_t count, loff_t *ppos)
72192202185SMarcel Holtmann {
722b32bba6cSMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
723b32bba6cSMarcel Holtmann 	char buf[3];
72492202185SMarcel Holtmann 
725111902f7SMarcel Holtmann 	buf[0] = test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) ? 'Y': 'N';
726b32bba6cSMarcel Holtmann 	buf[1] = '\n';
727b32bba6cSMarcel Holtmann 	buf[2] = '\0';
728b32bba6cSMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
729b32bba6cSMarcel Holtmann }
730b32bba6cSMarcel Holtmann 
731b32bba6cSMarcel Holtmann static ssize_t force_static_address_write(struct file *file,
732b32bba6cSMarcel Holtmann 					  const char __user *user_buf,
733b32bba6cSMarcel Holtmann 					  size_t count, loff_t *ppos)
734b32bba6cSMarcel Holtmann {
735b32bba6cSMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
736b32bba6cSMarcel Holtmann 	char buf[32];
737b32bba6cSMarcel Holtmann 	size_t buf_size = min(count, (sizeof(buf)-1));
738b32bba6cSMarcel Holtmann 	bool enable;
739b32bba6cSMarcel Holtmann 
740b32bba6cSMarcel Holtmann 	if (test_bit(HCI_UP, &hdev->flags))
741b32bba6cSMarcel Holtmann 		return -EBUSY;
742b32bba6cSMarcel Holtmann 
743b32bba6cSMarcel Holtmann 	if (copy_from_user(buf, user_buf, buf_size))
744b32bba6cSMarcel Holtmann 		return -EFAULT;
745b32bba6cSMarcel Holtmann 
746b32bba6cSMarcel Holtmann 	buf[buf_size] = '\0';
747b32bba6cSMarcel Holtmann 	if (strtobool(buf, &enable))
74892202185SMarcel Holtmann 		return -EINVAL;
74992202185SMarcel Holtmann 
750111902f7SMarcel Holtmann 	if (enable == test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags))
751b32bba6cSMarcel Holtmann 		return -EALREADY;
75292202185SMarcel Holtmann 
753111902f7SMarcel Holtmann 	change_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags);
754b32bba6cSMarcel Holtmann 
755b32bba6cSMarcel Holtmann 	return count;
75692202185SMarcel Holtmann }
75792202185SMarcel Holtmann 
758b32bba6cSMarcel Holtmann static const struct file_operations force_static_address_fops = {
759b32bba6cSMarcel Holtmann 	.open		= simple_open,
760b32bba6cSMarcel Holtmann 	.read		= force_static_address_read,
761b32bba6cSMarcel Holtmann 	.write		= force_static_address_write,
762b32bba6cSMarcel Holtmann 	.llseek		= default_llseek,
763b32bba6cSMarcel Holtmann };
76492202185SMarcel Holtmann 
765d2ab0ac1SMarcel Holtmann static int white_list_show(struct seq_file *f, void *ptr)
766d2ab0ac1SMarcel Holtmann {
767d2ab0ac1SMarcel Holtmann 	struct hci_dev *hdev = f->private;
768d2ab0ac1SMarcel Holtmann 	struct bdaddr_list *b;
769d2ab0ac1SMarcel Holtmann 
770d2ab0ac1SMarcel Holtmann 	hci_dev_lock(hdev);
771d2ab0ac1SMarcel Holtmann 	list_for_each_entry(b, &hdev->le_white_list, list)
772d2ab0ac1SMarcel Holtmann 		seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type);
773d2ab0ac1SMarcel Holtmann 	hci_dev_unlock(hdev);
774d2ab0ac1SMarcel Holtmann 
775d2ab0ac1SMarcel Holtmann 	return 0;
776d2ab0ac1SMarcel Holtmann }
777d2ab0ac1SMarcel Holtmann 
778d2ab0ac1SMarcel Holtmann static int white_list_open(struct inode *inode, struct file *file)
779d2ab0ac1SMarcel Holtmann {
780d2ab0ac1SMarcel Holtmann 	return single_open(file, white_list_show, inode->i_private);
781d2ab0ac1SMarcel Holtmann }
782d2ab0ac1SMarcel Holtmann 
783d2ab0ac1SMarcel Holtmann static const struct file_operations white_list_fops = {
784d2ab0ac1SMarcel Holtmann 	.open		= white_list_open,
785d2ab0ac1SMarcel Holtmann 	.read		= seq_read,
786d2ab0ac1SMarcel Holtmann 	.llseek		= seq_lseek,
787d2ab0ac1SMarcel Holtmann 	.release	= single_release,
788d2ab0ac1SMarcel Holtmann };
789d2ab0ac1SMarcel Holtmann 
7903698d704SMarcel Holtmann static int identity_resolving_keys_show(struct seq_file *f, void *ptr)
7913698d704SMarcel Holtmann {
7923698d704SMarcel Holtmann 	struct hci_dev *hdev = f->private;
793adae20cbSJohan Hedberg 	struct smp_irk *irk;
7943698d704SMarcel Holtmann 
795adae20cbSJohan Hedberg 	rcu_read_lock();
796adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
7973698d704SMarcel Holtmann 		seq_printf(f, "%pMR (type %u) %*phN %pMR\n",
7983698d704SMarcel Holtmann 			   &irk->bdaddr, irk->addr_type,
7993698d704SMarcel Holtmann 			   16, irk->val, &irk->rpa);
8003698d704SMarcel Holtmann 	}
801adae20cbSJohan Hedberg 	rcu_read_unlock();
8023698d704SMarcel Holtmann 
8033698d704SMarcel Holtmann 	return 0;
8043698d704SMarcel Holtmann }
8053698d704SMarcel Holtmann 
8063698d704SMarcel Holtmann static int identity_resolving_keys_open(struct inode *inode, struct file *file)
8073698d704SMarcel Holtmann {
8083698d704SMarcel Holtmann 	return single_open(file, identity_resolving_keys_show,
8093698d704SMarcel Holtmann 			   inode->i_private);
8103698d704SMarcel Holtmann }
8113698d704SMarcel Holtmann 
8123698d704SMarcel Holtmann static const struct file_operations identity_resolving_keys_fops = {
8133698d704SMarcel Holtmann 	.open		= identity_resolving_keys_open,
8143698d704SMarcel Holtmann 	.read		= seq_read,
8153698d704SMarcel Holtmann 	.llseek		= seq_lseek,
8163698d704SMarcel Holtmann 	.release	= single_release,
8173698d704SMarcel Holtmann };
8183698d704SMarcel Holtmann 
8198f8625cdSMarcel Holtmann static int long_term_keys_show(struct seq_file *f, void *ptr)
8208f8625cdSMarcel Holtmann {
8218f8625cdSMarcel Holtmann 	struct hci_dev *hdev = f->private;
822970d0f1bSJohan Hedberg 	struct smp_ltk *ltk;
8238f8625cdSMarcel Holtmann 
824970d0f1bSJohan Hedberg 	rcu_read_lock();
825970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(ltk, &hdev->long_term_keys, list)
826fe39c7b2SMarcel Holtmann 		seq_printf(f, "%pMR (type %u) %u 0x%02x %u %.4x %.16llx %*phN\n",
8278f8625cdSMarcel Holtmann 			   &ltk->bdaddr, ltk->bdaddr_type, ltk->authenticated,
8288f8625cdSMarcel Holtmann 			   ltk->type, ltk->enc_size, __le16_to_cpu(ltk->ediv),
829fe39c7b2SMarcel Holtmann 			   __le64_to_cpu(ltk->rand), 16, ltk->val);
830970d0f1bSJohan Hedberg 	rcu_read_unlock();
8318f8625cdSMarcel Holtmann 
8328f8625cdSMarcel Holtmann 	return 0;
8338f8625cdSMarcel Holtmann }
8348f8625cdSMarcel Holtmann 
8358f8625cdSMarcel Holtmann static int long_term_keys_open(struct inode *inode, struct file *file)
8368f8625cdSMarcel Holtmann {
8378f8625cdSMarcel Holtmann 	return single_open(file, long_term_keys_show, inode->i_private);
8388f8625cdSMarcel Holtmann }
8398f8625cdSMarcel Holtmann 
8408f8625cdSMarcel Holtmann static const struct file_operations long_term_keys_fops = {
8418f8625cdSMarcel Holtmann 	.open		= long_term_keys_open,
8428f8625cdSMarcel Holtmann 	.read		= seq_read,
8438f8625cdSMarcel Holtmann 	.llseek		= seq_lseek,
8448f8625cdSMarcel Holtmann 	.release	= single_release,
8458f8625cdSMarcel Holtmann };
8468f8625cdSMarcel Holtmann 
8474e70c7e7SMarcel Holtmann static int conn_min_interval_set(void *data, u64 val)
8484e70c7e7SMarcel Holtmann {
8494e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
8504e70c7e7SMarcel Holtmann 
8514e70c7e7SMarcel Holtmann 	if (val < 0x0006 || val > 0x0c80 || val > hdev->le_conn_max_interval)
8524e70c7e7SMarcel Holtmann 		return -EINVAL;
8534e70c7e7SMarcel Holtmann 
8544e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
8554e70c7e7SMarcel Holtmann 	hdev->le_conn_min_interval = val;
8564e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
8574e70c7e7SMarcel Holtmann 
8584e70c7e7SMarcel Holtmann 	return 0;
8594e70c7e7SMarcel Holtmann }
8604e70c7e7SMarcel Holtmann 
8614e70c7e7SMarcel Holtmann static int conn_min_interval_get(void *data, u64 *val)
8624e70c7e7SMarcel Holtmann {
8634e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
8644e70c7e7SMarcel Holtmann 
8654e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
8664e70c7e7SMarcel Holtmann 	*val = hdev->le_conn_min_interval;
8674e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
8684e70c7e7SMarcel Holtmann 
8694e70c7e7SMarcel Holtmann 	return 0;
8704e70c7e7SMarcel Holtmann }
8714e70c7e7SMarcel Holtmann 
8724e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_min_interval_fops, conn_min_interval_get,
8734e70c7e7SMarcel Holtmann 			conn_min_interval_set, "%llu\n");
8744e70c7e7SMarcel Holtmann 
8754e70c7e7SMarcel Holtmann static int conn_max_interval_set(void *data, u64 val)
8764e70c7e7SMarcel Holtmann {
8774e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
8784e70c7e7SMarcel Holtmann 
8794e70c7e7SMarcel Holtmann 	if (val < 0x0006 || val > 0x0c80 || val < hdev->le_conn_min_interval)
8804e70c7e7SMarcel Holtmann 		return -EINVAL;
8814e70c7e7SMarcel Holtmann 
8824e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
8834e70c7e7SMarcel Holtmann 	hdev->le_conn_max_interval = val;
8844e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
8854e70c7e7SMarcel Holtmann 
8864e70c7e7SMarcel Holtmann 	return 0;
8874e70c7e7SMarcel Holtmann }
8884e70c7e7SMarcel Holtmann 
8894e70c7e7SMarcel Holtmann static int conn_max_interval_get(void *data, u64 *val)
8904e70c7e7SMarcel Holtmann {
8914e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
8924e70c7e7SMarcel Holtmann 
8934e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
8944e70c7e7SMarcel Holtmann 	*val = hdev->le_conn_max_interval;
8954e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
8964e70c7e7SMarcel Holtmann 
8974e70c7e7SMarcel Holtmann 	return 0;
8984e70c7e7SMarcel Holtmann }
8994e70c7e7SMarcel Holtmann 
9004e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get,
9014e70c7e7SMarcel Holtmann 			conn_max_interval_set, "%llu\n");
9024e70c7e7SMarcel Holtmann 
903816a93d1SMarcel Holtmann static int conn_latency_set(void *data, u64 val)
904816a93d1SMarcel Holtmann {
905816a93d1SMarcel Holtmann 	struct hci_dev *hdev = data;
906816a93d1SMarcel Holtmann 
907816a93d1SMarcel Holtmann 	if (val > 0x01f3)
908816a93d1SMarcel Holtmann 		return -EINVAL;
909816a93d1SMarcel Holtmann 
910816a93d1SMarcel Holtmann 	hci_dev_lock(hdev);
911816a93d1SMarcel Holtmann 	hdev->le_conn_latency = val;
912816a93d1SMarcel Holtmann 	hci_dev_unlock(hdev);
913816a93d1SMarcel Holtmann 
914816a93d1SMarcel Holtmann 	return 0;
915816a93d1SMarcel Holtmann }
916816a93d1SMarcel Holtmann 
917816a93d1SMarcel Holtmann static int conn_latency_get(void *data, u64 *val)
918816a93d1SMarcel Holtmann {
919816a93d1SMarcel Holtmann 	struct hci_dev *hdev = data;
920816a93d1SMarcel Holtmann 
921816a93d1SMarcel Holtmann 	hci_dev_lock(hdev);
922816a93d1SMarcel Holtmann 	*val = hdev->le_conn_latency;
923816a93d1SMarcel Holtmann 	hci_dev_unlock(hdev);
924816a93d1SMarcel Holtmann 
925816a93d1SMarcel Holtmann 	return 0;
926816a93d1SMarcel Holtmann }
927816a93d1SMarcel Holtmann 
928816a93d1SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_latency_fops, conn_latency_get,
929816a93d1SMarcel Holtmann 			conn_latency_set, "%llu\n");
930816a93d1SMarcel Holtmann 
931f1649577SMarcel Holtmann static int supervision_timeout_set(void *data, u64 val)
932f1649577SMarcel Holtmann {
933f1649577SMarcel Holtmann 	struct hci_dev *hdev = data;
934f1649577SMarcel Holtmann 
935f1649577SMarcel Holtmann 	if (val < 0x000a || val > 0x0c80)
936f1649577SMarcel Holtmann 		return -EINVAL;
937f1649577SMarcel Holtmann 
938f1649577SMarcel Holtmann 	hci_dev_lock(hdev);
939f1649577SMarcel Holtmann 	hdev->le_supv_timeout = val;
940f1649577SMarcel Holtmann 	hci_dev_unlock(hdev);
941f1649577SMarcel Holtmann 
942f1649577SMarcel Holtmann 	return 0;
943f1649577SMarcel Holtmann }
944f1649577SMarcel Holtmann 
945f1649577SMarcel Holtmann static int supervision_timeout_get(void *data, u64 *val)
946f1649577SMarcel Holtmann {
947f1649577SMarcel Holtmann 	struct hci_dev *hdev = data;
948f1649577SMarcel Holtmann 
949f1649577SMarcel Holtmann 	hci_dev_lock(hdev);
950f1649577SMarcel Holtmann 	*val = hdev->le_supv_timeout;
951f1649577SMarcel Holtmann 	hci_dev_unlock(hdev);
952f1649577SMarcel Holtmann 
953f1649577SMarcel Holtmann 	return 0;
954f1649577SMarcel Holtmann }
955f1649577SMarcel Holtmann 
956f1649577SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(supervision_timeout_fops, supervision_timeout_get,
957f1649577SMarcel Holtmann 			supervision_timeout_set, "%llu\n");
958f1649577SMarcel Holtmann 
9593f959d46SMarcel Holtmann static int adv_channel_map_set(void *data, u64 val)
9603f959d46SMarcel Holtmann {
9613f959d46SMarcel Holtmann 	struct hci_dev *hdev = data;
9623f959d46SMarcel Holtmann 
9633f959d46SMarcel Holtmann 	if (val < 0x01 || val > 0x07)
9643f959d46SMarcel Holtmann 		return -EINVAL;
9653f959d46SMarcel Holtmann 
9663f959d46SMarcel Holtmann 	hci_dev_lock(hdev);
9673f959d46SMarcel Holtmann 	hdev->le_adv_channel_map = val;
9683f959d46SMarcel Holtmann 	hci_dev_unlock(hdev);
9693f959d46SMarcel Holtmann 
9703f959d46SMarcel Holtmann 	return 0;
9713f959d46SMarcel Holtmann }
9723f959d46SMarcel Holtmann 
9733f959d46SMarcel Holtmann static int adv_channel_map_get(void *data, u64 *val)
9743f959d46SMarcel Holtmann {
9753f959d46SMarcel Holtmann 	struct hci_dev *hdev = data;
9763f959d46SMarcel Holtmann 
9773f959d46SMarcel Holtmann 	hci_dev_lock(hdev);
9783f959d46SMarcel Holtmann 	*val = hdev->le_adv_channel_map;
9793f959d46SMarcel Holtmann 	hci_dev_unlock(hdev);
9803f959d46SMarcel Holtmann 
9813f959d46SMarcel Holtmann 	return 0;
9823f959d46SMarcel Holtmann }
9833f959d46SMarcel Holtmann 
9843f959d46SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(adv_channel_map_fops, adv_channel_map_get,
9853f959d46SMarcel Holtmann 			adv_channel_map_set, "%llu\n");
9863f959d46SMarcel Holtmann 
987729a1051SGeorg Lukas static int adv_min_interval_set(void *data, u64 val)
98889863109SJukka Rissanen {
989729a1051SGeorg Lukas 	struct hci_dev *hdev = data;
99089863109SJukka Rissanen 
991729a1051SGeorg Lukas 	if (val < 0x0020 || val > 0x4000 || val > hdev->le_adv_max_interval)
99289863109SJukka Rissanen 		return -EINVAL;
99389863109SJukka Rissanen 
9947d474e06SAndre Guedes 	hci_dev_lock(hdev);
995729a1051SGeorg Lukas 	hdev->le_adv_min_interval = val;
9967d474e06SAndre Guedes 	hci_dev_unlock(hdev);
9977d474e06SAndre Guedes 
9987d474e06SAndre Guedes 	return 0;
9997d474e06SAndre Guedes }
10007d474e06SAndre Guedes 
1001729a1051SGeorg Lukas static int adv_min_interval_get(void *data, u64 *val)
10027d474e06SAndre Guedes {
1003729a1051SGeorg Lukas 	struct hci_dev *hdev = data;
1004729a1051SGeorg Lukas 
1005729a1051SGeorg Lukas 	hci_dev_lock(hdev);
1006729a1051SGeorg Lukas 	*val = hdev->le_adv_min_interval;
1007729a1051SGeorg Lukas 	hci_dev_unlock(hdev);
1008729a1051SGeorg Lukas 
1009729a1051SGeorg Lukas 	return 0;
10107d474e06SAndre Guedes }
10117d474e06SAndre Guedes 
1012729a1051SGeorg Lukas DEFINE_SIMPLE_ATTRIBUTE(adv_min_interval_fops, adv_min_interval_get,
1013729a1051SGeorg Lukas 			adv_min_interval_set, "%llu\n");
10147d474e06SAndre Guedes 
1015729a1051SGeorg Lukas static int adv_max_interval_set(void *data, u64 val)
1016729a1051SGeorg Lukas {
1017729a1051SGeorg Lukas 	struct hci_dev *hdev = data;
1018729a1051SGeorg Lukas 
1019729a1051SGeorg Lukas 	if (val < 0x0020 || val > 0x4000 || val < hdev->le_adv_min_interval)
10207d474e06SAndre Guedes 		return -EINVAL;
10217d474e06SAndre Guedes 
10227d474e06SAndre Guedes 	hci_dev_lock(hdev);
1023729a1051SGeorg Lukas 	hdev->le_adv_max_interval = val;
10247d474e06SAndre Guedes 	hci_dev_unlock(hdev);
10257d474e06SAndre Guedes 
1026729a1051SGeorg Lukas 	return 0;
10277d474e06SAndre Guedes }
10287d474e06SAndre Guedes 
1029729a1051SGeorg Lukas static int adv_max_interval_get(void *data, u64 *val)
1030729a1051SGeorg Lukas {
1031729a1051SGeorg Lukas 	struct hci_dev *hdev = data;
1032729a1051SGeorg Lukas 
10337d474e06SAndre Guedes 	hci_dev_lock(hdev);
1034729a1051SGeorg Lukas 	*val = hdev->le_adv_max_interval;
10357d474e06SAndre Guedes 	hci_dev_unlock(hdev);
1036729a1051SGeorg Lukas 
1037729a1051SGeorg Lukas 	return 0;
1038729a1051SGeorg Lukas }
1039729a1051SGeorg Lukas 
1040729a1051SGeorg Lukas DEFINE_SIMPLE_ATTRIBUTE(adv_max_interval_fops, adv_max_interval_get,
1041729a1051SGeorg Lukas 			adv_max_interval_set, "%llu\n");
1042729a1051SGeorg Lukas 
10430b3c7d37SMarcel Holtmann static int device_list_show(struct seq_file *f, void *ptr)
10447d474e06SAndre Guedes {
10450b3c7d37SMarcel Holtmann 	struct hci_dev *hdev = f->private;
10467d474e06SAndre Guedes 	struct hci_conn_params *p;
104740f4938aSMarcel Holtmann 	struct bdaddr_list *b;
10487d474e06SAndre Guedes 
10497d474e06SAndre Guedes 	hci_dev_lock(hdev);
105040f4938aSMarcel Holtmann 	list_for_each_entry(b, &hdev->whitelist, list)
105140f4938aSMarcel Holtmann 		seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type);
10527d474e06SAndre Guedes 	list_for_each_entry(p, &hdev->le_conn_params, list) {
105340f4938aSMarcel Holtmann 		seq_printf(f, "%pMR (type %u) %u\n", &p->addr, p->addr_type,
10547d474e06SAndre Guedes 			   p->auto_connect);
10557d474e06SAndre Guedes 	}
10567d474e06SAndre Guedes 	hci_dev_unlock(hdev);
10577d474e06SAndre Guedes 
10587d474e06SAndre Guedes 	return 0;
10597d474e06SAndre Guedes }
10607d474e06SAndre Guedes 
10610b3c7d37SMarcel Holtmann static int device_list_open(struct inode *inode, struct file *file)
10627d474e06SAndre Guedes {
10630b3c7d37SMarcel Holtmann 	return single_open(file, device_list_show, inode->i_private);
10647d474e06SAndre Guedes }
10657d474e06SAndre Guedes 
10660b3c7d37SMarcel Holtmann static const struct file_operations device_list_fops = {
10670b3c7d37SMarcel Holtmann 	.open		= device_list_open,
10687d474e06SAndre Guedes 	.read		= seq_read,
10697d474e06SAndre Guedes 	.llseek		= seq_lseek,
10707d474e06SAndre Guedes 	.release	= single_release,
10717d474e06SAndre Guedes };
10727d474e06SAndre Guedes 
10731da177e4SLinus Torvalds /* ---- HCI requests ---- */
10741da177e4SLinus Torvalds 
107542c6b129SJohan Hedberg static void hci_req_sync_complete(struct hci_dev *hdev, u8 result)
10761da177e4SLinus Torvalds {
107742c6b129SJohan Hedberg 	BT_DBG("%s result 0x%2.2x", hdev->name, result);
107875fb0e32SJohan Hedberg 
10791da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
10801da177e4SLinus Torvalds 		hdev->req_result = result;
10811da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_DONE;
10821da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
10831da177e4SLinus Torvalds 	}
10841da177e4SLinus Torvalds }
10851da177e4SLinus Torvalds 
10861da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err)
10871da177e4SLinus Torvalds {
10881da177e4SLinus Torvalds 	BT_DBG("%s err 0x%2.2x", hdev->name, err);
10891da177e4SLinus Torvalds 
10901da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
10911da177e4SLinus Torvalds 		hdev->req_result = err;
10921da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_CANCELED;
10931da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
10941da177e4SLinus Torvalds 	}
10951da177e4SLinus Torvalds }
10961da177e4SLinus Torvalds 
109777a63e0aSFengguang Wu static struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode,
109877a63e0aSFengguang Wu 					    u8 event)
109975e84b7cSJohan Hedberg {
110075e84b7cSJohan Hedberg 	struct hci_ev_cmd_complete *ev;
110175e84b7cSJohan Hedberg 	struct hci_event_hdr *hdr;
110275e84b7cSJohan Hedberg 	struct sk_buff *skb;
110375e84b7cSJohan Hedberg 
110475e84b7cSJohan Hedberg 	hci_dev_lock(hdev);
110575e84b7cSJohan Hedberg 
110675e84b7cSJohan Hedberg 	skb = hdev->recv_evt;
110775e84b7cSJohan Hedberg 	hdev->recv_evt = NULL;
110875e84b7cSJohan Hedberg 
110975e84b7cSJohan Hedberg 	hci_dev_unlock(hdev);
111075e84b7cSJohan Hedberg 
111175e84b7cSJohan Hedberg 	if (!skb)
111275e84b7cSJohan Hedberg 		return ERR_PTR(-ENODATA);
111375e84b7cSJohan Hedberg 
111475e84b7cSJohan Hedberg 	if (skb->len < sizeof(*hdr)) {
111575e84b7cSJohan Hedberg 		BT_ERR("Too short HCI event");
111675e84b7cSJohan Hedberg 		goto failed;
111775e84b7cSJohan Hedberg 	}
111875e84b7cSJohan Hedberg 
111975e84b7cSJohan Hedberg 	hdr = (void *) skb->data;
112075e84b7cSJohan Hedberg 	skb_pull(skb, HCI_EVENT_HDR_SIZE);
112175e84b7cSJohan Hedberg 
11227b1abbbeSJohan Hedberg 	if (event) {
11237b1abbbeSJohan Hedberg 		if (hdr->evt != event)
11247b1abbbeSJohan Hedberg 			goto failed;
11257b1abbbeSJohan Hedberg 		return skb;
11267b1abbbeSJohan Hedberg 	}
11277b1abbbeSJohan Hedberg 
112875e84b7cSJohan Hedberg 	if (hdr->evt != HCI_EV_CMD_COMPLETE) {
112975e84b7cSJohan Hedberg 		BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt);
113075e84b7cSJohan Hedberg 		goto failed;
113175e84b7cSJohan Hedberg 	}
113275e84b7cSJohan Hedberg 
113375e84b7cSJohan Hedberg 	if (skb->len < sizeof(*ev)) {
113475e84b7cSJohan Hedberg 		BT_ERR("Too short cmd_complete event");
113575e84b7cSJohan Hedberg 		goto failed;
113675e84b7cSJohan Hedberg 	}
113775e84b7cSJohan Hedberg 
113875e84b7cSJohan Hedberg 	ev = (void *) skb->data;
113975e84b7cSJohan Hedberg 	skb_pull(skb, sizeof(*ev));
114075e84b7cSJohan Hedberg 
114175e84b7cSJohan Hedberg 	if (opcode == __le16_to_cpu(ev->opcode))
114275e84b7cSJohan Hedberg 		return skb;
114375e84b7cSJohan Hedberg 
114475e84b7cSJohan Hedberg 	BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode,
114575e84b7cSJohan Hedberg 	       __le16_to_cpu(ev->opcode));
114675e84b7cSJohan Hedberg 
114775e84b7cSJohan Hedberg failed:
114875e84b7cSJohan Hedberg 	kfree_skb(skb);
114975e84b7cSJohan Hedberg 	return ERR_PTR(-ENODATA);
115075e84b7cSJohan Hedberg }
115175e84b7cSJohan Hedberg 
11527b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
115307dc93ddSJohan Hedberg 				  const void *param, u8 event, u32 timeout)
115475e84b7cSJohan Hedberg {
115575e84b7cSJohan Hedberg 	DECLARE_WAITQUEUE(wait, current);
115675e84b7cSJohan Hedberg 	struct hci_request req;
115775e84b7cSJohan Hedberg 	int err = 0;
115875e84b7cSJohan Hedberg 
115975e84b7cSJohan Hedberg 	BT_DBG("%s", hdev->name);
116075e84b7cSJohan Hedberg 
116175e84b7cSJohan Hedberg 	hci_req_init(&req, hdev);
116275e84b7cSJohan Hedberg 
11637b1abbbeSJohan Hedberg 	hci_req_add_ev(&req, opcode, plen, param, event);
116475e84b7cSJohan Hedberg 
116575e84b7cSJohan Hedberg 	hdev->req_status = HCI_REQ_PEND;
116675e84b7cSJohan Hedberg 
116775e84b7cSJohan Hedberg 	add_wait_queue(&hdev->req_wait_q, &wait);
116875e84b7cSJohan Hedberg 	set_current_state(TASK_INTERRUPTIBLE);
116975e84b7cSJohan Hedberg 
1170039fada5SChan-yeol Park 	err = hci_req_run(&req, hci_req_sync_complete);
1171039fada5SChan-yeol Park 	if (err < 0) {
1172039fada5SChan-yeol Park 		remove_wait_queue(&hdev->req_wait_q, &wait);
117322a3ceabSJohan Hedberg 		set_current_state(TASK_RUNNING);
1174039fada5SChan-yeol Park 		return ERR_PTR(err);
1175039fada5SChan-yeol Park 	}
1176039fada5SChan-yeol Park 
117775e84b7cSJohan Hedberg 	schedule_timeout(timeout);
117875e84b7cSJohan Hedberg 
117975e84b7cSJohan Hedberg 	remove_wait_queue(&hdev->req_wait_q, &wait);
118075e84b7cSJohan Hedberg 
118175e84b7cSJohan Hedberg 	if (signal_pending(current))
118275e84b7cSJohan Hedberg 		return ERR_PTR(-EINTR);
118375e84b7cSJohan Hedberg 
118475e84b7cSJohan Hedberg 	switch (hdev->req_status) {
118575e84b7cSJohan Hedberg 	case HCI_REQ_DONE:
118675e84b7cSJohan Hedberg 		err = -bt_to_errno(hdev->req_result);
118775e84b7cSJohan Hedberg 		break;
118875e84b7cSJohan Hedberg 
118975e84b7cSJohan Hedberg 	case HCI_REQ_CANCELED:
119075e84b7cSJohan Hedberg 		err = -hdev->req_result;
119175e84b7cSJohan Hedberg 		break;
119275e84b7cSJohan Hedberg 
119375e84b7cSJohan Hedberg 	default:
119475e84b7cSJohan Hedberg 		err = -ETIMEDOUT;
119575e84b7cSJohan Hedberg 		break;
119675e84b7cSJohan Hedberg 	}
119775e84b7cSJohan Hedberg 
119875e84b7cSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
119975e84b7cSJohan Hedberg 
120075e84b7cSJohan Hedberg 	BT_DBG("%s end: err %d", hdev->name, err);
120175e84b7cSJohan Hedberg 
120275e84b7cSJohan Hedberg 	if (err < 0)
120375e84b7cSJohan Hedberg 		return ERR_PTR(err);
120475e84b7cSJohan Hedberg 
12057b1abbbeSJohan Hedberg 	return hci_get_cmd_complete(hdev, opcode, event);
12067b1abbbeSJohan Hedberg }
12077b1abbbeSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync_ev);
12087b1abbbeSJohan Hedberg 
12097b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
121007dc93ddSJohan Hedberg 			       const void *param, u32 timeout)
12117b1abbbeSJohan Hedberg {
12127b1abbbeSJohan Hedberg 	return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout);
121375e84b7cSJohan Hedberg }
121475e84b7cSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync);
121575e84b7cSJohan Hedberg 
12161da177e4SLinus Torvalds /* Execute request and wait for completion. */
121701178cd4SJohan Hedberg static int __hci_req_sync(struct hci_dev *hdev,
121842c6b129SJohan Hedberg 			  void (*func)(struct hci_request *req,
121942c6b129SJohan Hedberg 				      unsigned long opt),
12201da177e4SLinus Torvalds 			  unsigned long opt, __u32 timeout)
12211da177e4SLinus Torvalds {
122242c6b129SJohan Hedberg 	struct hci_request req;
12231da177e4SLinus Torvalds 	DECLARE_WAITQUEUE(wait, current);
12241da177e4SLinus Torvalds 	int err = 0;
12251da177e4SLinus Torvalds 
12261da177e4SLinus Torvalds 	BT_DBG("%s start", hdev->name);
12271da177e4SLinus Torvalds 
122842c6b129SJohan Hedberg 	hci_req_init(&req, hdev);
122942c6b129SJohan Hedberg 
12301da177e4SLinus Torvalds 	hdev->req_status = HCI_REQ_PEND;
12311da177e4SLinus Torvalds 
123242c6b129SJohan Hedberg 	func(&req, opt);
123353cce22dSJohan Hedberg 
1234039fada5SChan-yeol Park 	add_wait_queue(&hdev->req_wait_q, &wait);
1235039fada5SChan-yeol Park 	set_current_state(TASK_INTERRUPTIBLE);
1236039fada5SChan-yeol Park 
123742c6b129SJohan Hedberg 	err = hci_req_run(&req, hci_req_sync_complete);
123842c6b129SJohan Hedberg 	if (err < 0) {
123953cce22dSJohan Hedberg 		hdev->req_status = 0;
1240920c8300SAndre Guedes 
1241039fada5SChan-yeol Park 		remove_wait_queue(&hdev->req_wait_q, &wait);
124222a3ceabSJohan Hedberg 		set_current_state(TASK_RUNNING);
1243039fada5SChan-yeol Park 
1244920c8300SAndre Guedes 		/* ENODATA means the HCI request command queue is empty.
1245920c8300SAndre Guedes 		 * This can happen when a request with conditionals doesn't
1246920c8300SAndre Guedes 		 * trigger any commands to be sent. This is normal behavior
1247920c8300SAndre Guedes 		 * and should not trigger an error return.
124842c6b129SJohan Hedberg 		 */
1249920c8300SAndre Guedes 		if (err == -ENODATA)
125042c6b129SJohan Hedberg 			return 0;
1251920c8300SAndre Guedes 
1252920c8300SAndre Guedes 		return err;
125353cce22dSJohan Hedberg 	}
125453cce22dSJohan Hedberg 
12551da177e4SLinus Torvalds 	schedule_timeout(timeout);
12561da177e4SLinus Torvalds 
12571da177e4SLinus Torvalds 	remove_wait_queue(&hdev->req_wait_q, &wait);
12581da177e4SLinus Torvalds 
12591da177e4SLinus Torvalds 	if (signal_pending(current))
12601da177e4SLinus Torvalds 		return -EINTR;
12611da177e4SLinus Torvalds 
12621da177e4SLinus Torvalds 	switch (hdev->req_status) {
12631da177e4SLinus Torvalds 	case HCI_REQ_DONE:
1264e175072fSJoe Perches 		err = -bt_to_errno(hdev->req_result);
12651da177e4SLinus Torvalds 		break;
12661da177e4SLinus Torvalds 
12671da177e4SLinus Torvalds 	case HCI_REQ_CANCELED:
12681da177e4SLinus Torvalds 		err = -hdev->req_result;
12691da177e4SLinus Torvalds 		break;
12701da177e4SLinus Torvalds 
12711da177e4SLinus Torvalds 	default:
12721da177e4SLinus Torvalds 		err = -ETIMEDOUT;
12731da177e4SLinus Torvalds 		break;
12743ff50b79SStephen Hemminger 	}
12751da177e4SLinus Torvalds 
1276a5040efaSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
12771da177e4SLinus Torvalds 
12781da177e4SLinus Torvalds 	BT_DBG("%s end: err %d", hdev->name, err);
12791da177e4SLinus Torvalds 
12801da177e4SLinus Torvalds 	return err;
12811da177e4SLinus Torvalds }
12821da177e4SLinus Torvalds 
128301178cd4SJohan Hedberg static int hci_req_sync(struct hci_dev *hdev,
128442c6b129SJohan Hedberg 			void (*req)(struct hci_request *req,
128542c6b129SJohan Hedberg 				    unsigned long opt),
12861da177e4SLinus Torvalds 			unsigned long opt, __u32 timeout)
12871da177e4SLinus Torvalds {
12881da177e4SLinus Torvalds 	int ret;
12891da177e4SLinus Torvalds 
12907c6a329eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
12917c6a329eSMarcel Holtmann 		return -ENETDOWN;
12927c6a329eSMarcel Holtmann 
12931da177e4SLinus Torvalds 	/* Serialize all requests */
12941da177e4SLinus Torvalds 	hci_req_lock(hdev);
129501178cd4SJohan Hedberg 	ret = __hci_req_sync(hdev, req, opt, timeout);
12961da177e4SLinus Torvalds 	hci_req_unlock(hdev);
12971da177e4SLinus Torvalds 
12981da177e4SLinus Torvalds 	return ret;
12991da177e4SLinus Torvalds }
13001da177e4SLinus Torvalds 
130142c6b129SJohan Hedberg static void hci_reset_req(struct hci_request *req, unsigned long opt)
13021da177e4SLinus Torvalds {
130342c6b129SJohan Hedberg 	BT_DBG("%s %ld", req->hdev->name, opt);
13041da177e4SLinus Torvalds 
13051da177e4SLinus Torvalds 	/* Reset device */
130642c6b129SJohan Hedberg 	set_bit(HCI_RESET, &req->hdev->flags);
130742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_RESET, 0, NULL);
13081da177e4SLinus Torvalds }
13091da177e4SLinus Torvalds 
131042c6b129SJohan Hedberg static void bredr_init(struct hci_request *req)
13111da177e4SLinus Torvalds {
131242c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
13132455a3eaSAndrei Emeltchenko 
13141da177e4SLinus Torvalds 	/* Read Local Supported Features */
131542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
13161da177e4SLinus Torvalds 
13171143e5a6SMarcel Holtmann 	/* Read Local Version */
131842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
13192177bab5SJohan Hedberg 
13202177bab5SJohan Hedberg 	/* Read BD Address */
132142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
13221da177e4SLinus Torvalds }
13231da177e4SLinus Torvalds 
132442c6b129SJohan Hedberg static void amp_init(struct hci_request *req)
1325e61ef499SAndrei Emeltchenko {
132642c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
13272455a3eaSAndrei Emeltchenko 
1328e61ef499SAndrei Emeltchenko 	/* Read Local Version */
132942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
13306bcbc489SAndrei Emeltchenko 
1331f6996cfeSMarcel Holtmann 	/* Read Local Supported Commands */
1332f6996cfeSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
1333f6996cfeSMarcel Holtmann 
1334f6996cfeSMarcel Holtmann 	/* Read Local Supported Features */
1335f6996cfeSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
1336f6996cfeSMarcel Holtmann 
13376bcbc489SAndrei Emeltchenko 	/* Read Local AMP Info */
133842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
1339e71dfabaSAndrei Emeltchenko 
1340e71dfabaSAndrei Emeltchenko 	/* Read Data Blk size */
134142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL);
13427528ca1cSMarcel Holtmann 
1343f38ba941SMarcel Holtmann 	/* Read Flow Control Mode */
1344f38ba941SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL);
1345f38ba941SMarcel Holtmann 
13467528ca1cSMarcel Holtmann 	/* Read Location Data */
13477528ca1cSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL);
1348e61ef499SAndrei Emeltchenko }
1349e61ef499SAndrei Emeltchenko 
135042c6b129SJohan Hedberg static void hci_init1_req(struct hci_request *req, unsigned long opt)
1351e61ef499SAndrei Emeltchenko {
135242c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1353e61ef499SAndrei Emeltchenko 
1354e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
1355e61ef499SAndrei Emeltchenko 
135611778716SAndrei Emeltchenko 	/* Reset */
135711778716SAndrei Emeltchenko 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
135842c6b129SJohan Hedberg 		hci_reset_req(req, 0);
135911778716SAndrei Emeltchenko 
1360e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
1361e61ef499SAndrei Emeltchenko 	case HCI_BREDR:
136242c6b129SJohan Hedberg 		bredr_init(req);
1363e61ef499SAndrei Emeltchenko 		break;
1364e61ef499SAndrei Emeltchenko 
1365e61ef499SAndrei Emeltchenko 	case HCI_AMP:
136642c6b129SJohan Hedberg 		amp_init(req);
1367e61ef499SAndrei Emeltchenko 		break;
1368e61ef499SAndrei Emeltchenko 
1369e61ef499SAndrei Emeltchenko 	default:
1370e61ef499SAndrei Emeltchenko 		BT_ERR("Unknown device type %d", hdev->dev_type);
1371e61ef499SAndrei Emeltchenko 		break;
1372e61ef499SAndrei Emeltchenko 	}
1373e61ef499SAndrei Emeltchenko }
1374e61ef499SAndrei Emeltchenko 
137542c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req)
13762177bab5SJohan Hedberg {
13772177bab5SJohan Hedberg 	__le16 param;
13782177bab5SJohan Hedberg 	__u8 flt_type;
13792177bab5SJohan Hedberg 
13802177bab5SJohan Hedberg 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
138142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
13822177bab5SJohan Hedberg 
13832177bab5SJohan Hedberg 	/* Read Class of Device */
138442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
13852177bab5SJohan Hedberg 
13862177bab5SJohan Hedberg 	/* Read Local Name */
138742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL);
13882177bab5SJohan Hedberg 
13892177bab5SJohan Hedberg 	/* Read Voice Setting */
139042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL);
13912177bab5SJohan Hedberg 
1392b4cb9fb2SMarcel Holtmann 	/* Read Number of Supported IAC */
1393b4cb9fb2SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL);
1394b4cb9fb2SMarcel Holtmann 
13954b836f39SMarcel Holtmann 	/* Read Current IAC LAP */
13964b836f39SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL);
13974b836f39SMarcel Holtmann 
13982177bab5SJohan Hedberg 	/* Clear Event Filters */
13992177bab5SJohan Hedberg 	flt_type = HCI_FLT_CLEAR_ALL;
140042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
14012177bab5SJohan Hedberg 
14022177bab5SJohan Hedberg 	/* Connection accept timeout ~20 secs */
1403dcf4adbfSJoe Perches 	param = cpu_to_le16(0x7d00);
140442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
14052177bab5SJohan Hedberg }
14062177bab5SJohan Hedberg 
140742c6b129SJohan Hedberg static void le_setup(struct hci_request *req)
14082177bab5SJohan Hedberg {
1409c73eee91SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1410c73eee91SJohan Hedberg 
14112177bab5SJohan Hedberg 	/* Read LE Buffer Size */
141242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
14132177bab5SJohan Hedberg 
14142177bab5SJohan Hedberg 	/* Read LE Local Supported Features */
141542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
14162177bab5SJohan Hedberg 
1417747d3f03SMarcel Holtmann 	/* Read LE Supported States */
1418747d3f03SMarcel Holtmann 	hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);
1419747d3f03SMarcel Holtmann 
14202177bab5SJohan Hedberg 	/* Read LE White List Size */
142142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL);
14222177bab5SJohan Hedberg 
1423747d3f03SMarcel Holtmann 	/* Clear LE White List */
1424747d3f03SMarcel Holtmann 	hci_req_add(req, HCI_OP_LE_CLEAR_WHITE_LIST, 0, NULL);
1425c73eee91SJohan Hedberg 
1426c73eee91SJohan Hedberg 	/* LE-only controllers have LE implicitly enabled */
1427c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
1428c73eee91SJohan Hedberg 		set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
14292177bab5SJohan Hedberg }
14302177bab5SJohan Hedberg 
14312177bab5SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
14322177bab5SJohan Hedberg {
14332177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
14342177bab5SJohan Hedberg 		return 0x02;
14352177bab5SJohan Hedberg 
14362177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
14372177bab5SJohan Hedberg 		return 0x01;
14382177bab5SJohan Hedberg 
14392177bab5SJohan Hedberg 	if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
14402177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x0757)
14412177bab5SJohan Hedberg 		return 0x01;
14422177bab5SJohan Hedberg 
14432177bab5SJohan Hedberg 	if (hdev->manufacturer == 15) {
14442177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
14452177bab5SJohan Hedberg 			return 0x01;
14462177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
14472177bab5SJohan Hedberg 			return 0x01;
14482177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
14492177bab5SJohan Hedberg 			return 0x01;
14502177bab5SJohan Hedberg 	}
14512177bab5SJohan Hedberg 
14522177bab5SJohan Hedberg 	if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
14532177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x1805)
14542177bab5SJohan Hedberg 		return 0x01;
14552177bab5SJohan Hedberg 
14562177bab5SJohan Hedberg 	return 0x00;
14572177bab5SJohan Hedberg }
14582177bab5SJohan Hedberg 
145942c6b129SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_request *req)
14602177bab5SJohan Hedberg {
14612177bab5SJohan Hedberg 	u8 mode;
14622177bab5SJohan Hedberg 
146342c6b129SJohan Hedberg 	mode = hci_get_inquiry_mode(req->hdev);
14642177bab5SJohan Hedberg 
146542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
14662177bab5SJohan Hedberg }
14672177bab5SJohan Hedberg 
146842c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req)
14692177bab5SJohan Hedberg {
147042c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
147142c6b129SJohan Hedberg 
14722177bab5SJohan Hedberg 	/* The second byte is 0xff instead of 0x9f (two reserved bits
14732177bab5SJohan Hedberg 	 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
14742177bab5SJohan Hedberg 	 * command otherwise.
14752177bab5SJohan Hedberg 	 */
14762177bab5SJohan Hedberg 	u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
14772177bab5SJohan Hedberg 
14782177bab5SJohan Hedberg 	/* CSR 1.1 dongles does not accept any bitfield so don't try to set
14792177bab5SJohan Hedberg 	 * any event mask for pre 1.2 devices.
14802177bab5SJohan Hedberg 	 */
14812177bab5SJohan Hedberg 	if (hdev->hci_ver < BLUETOOTH_VER_1_2)
14822177bab5SJohan Hedberg 		return;
14832177bab5SJohan Hedberg 
14842177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
14852177bab5SJohan Hedberg 		events[4] |= 0x01; /* Flow Specification Complete */
14862177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
14872177bab5SJohan Hedberg 		events[4] |= 0x04; /* Read Remote Extended Features Complete */
14882177bab5SJohan Hedberg 		events[5] |= 0x08; /* Synchronous Connection Complete */
14892177bab5SJohan Hedberg 		events[5] |= 0x10; /* Synchronous Connection Changed */
1490c7882cbdSMarcel Holtmann 	} else {
1491c7882cbdSMarcel Holtmann 		/* Use a different default for LE-only devices */
1492c7882cbdSMarcel Holtmann 		memset(events, 0, sizeof(events));
1493c7882cbdSMarcel Holtmann 		events[0] |= 0x10; /* Disconnection Complete */
1494c7882cbdSMarcel Holtmann 		events[1] |= 0x08; /* Read Remote Version Information Complete */
1495c7882cbdSMarcel Holtmann 		events[1] |= 0x20; /* Command Complete */
1496c7882cbdSMarcel Holtmann 		events[1] |= 0x40; /* Command Status */
1497c7882cbdSMarcel Holtmann 		events[1] |= 0x80; /* Hardware Error */
1498c7882cbdSMarcel Holtmann 		events[2] |= 0x04; /* Number of Completed Packets */
1499c7882cbdSMarcel Holtmann 		events[3] |= 0x02; /* Data Buffer Overflow */
15000da71f1bSMarcel Holtmann 
15010da71f1bSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_ENCRYPTION) {
15020da71f1bSMarcel Holtmann 			events[0] |= 0x80; /* Encryption Change */
1503c7882cbdSMarcel Holtmann 			events[5] |= 0x80; /* Encryption Key Refresh Complete */
15042177bab5SJohan Hedberg 		}
15050da71f1bSMarcel Holtmann 	}
15062177bab5SJohan Hedberg 
15072177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
15082177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
15092177bab5SJohan Hedberg 
15102177bab5SJohan Hedberg 	if (lmp_sniffsubr_capable(hdev))
15112177bab5SJohan Hedberg 		events[5] |= 0x20; /* Sniff Subrating */
15122177bab5SJohan Hedberg 
15132177bab5SJohan Hedberg 	if (lmp_pause_enc_capable(hdev))
15142177bab5SJohan Hedberg 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
15152177bab5SJohan Hedberg 
15162177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
15172177bab5SJohan Hedberg 		events[5] |= 0x40; /* Extended Inquiry Result */
15182177bab5SJohan Hedberg 
15192177bab5SJohan Hedberg 	if (lmp_no_flush_capable(hdev))
15202177bab5SJohan Hedberg 		events[7] |= 0x01; /* Enhanced Flush Complete */
15212177bab5SJohan Hedberg 
15222177bab5SJohan Hedberg 	if (lmp_lsto_capable(hdev))
15232177bab5SJohan Hedberg 		events[6] |= 0x80; /* Link Supervision Timeout Changed */
15242177bab5SJohan Hedberg 
15252177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
15262177bab5SJohan Hedberg 		events[6] |= 0x01;	/* IO Capability Request */
15272177bab5SJohan Hedberg 		events[6] |= 0x02;	/* IO Capability Response */
15282177bab5SJohan Hedberg 		events[6] |= 0x04;	/* User Confirmation Request */
15292177bab5SJohan Hedberg 		events[6] |= 0x08;	/* User Passkey Request */
15302177bab5SJohan Hedberg 		events[6] |= 0x10;	/* Remote OOB Data Request */
15312177bab5SJohan Hedberg 		events[6] |= 0x20;	/* Simple Pairing Complete */
15322177bab5SJohan Hedberg 		events[7] |= 0x04;	/* User Passkey Notification */
15332177bab5SJohan Hedberg 		events[7] |= 0x08;	/* Keypress Notification */
15342177bab5SJohan Hedberg 		events[7] |= 0x10;	/* Remote Host Supported
15352177bab5SJohan Hedberg 					 * Features Notification
15362177bab5SJohan Hedberg 					 */
15372177bab5SJohan Hedberg 	}
15382177bab5SJohan Hedberg 
15392177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
15402177bab5SJohan Hedberg 		events[7] |= 0x20;	/* LE Meta-Event */
15412177bab5SJohan Hedberg 
154242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
15432177bab5SJohan Hedberg }
15442177bab5SJohan Hedberg 
154542c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt)
15462177bab5SJohan Hedberg {
154742c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
154842c6b129SJohan Hedberg 
15492177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev))
155042c6b129SJohan Hedberg 		bredr_setup(req);
155156f87901SJohan Hedberg 	else
155256f87901SJohan Hedberg 		clear_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
15532177bab5SJohan Hedberg 
15542177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
155542c6b129SJohan Hedberg 		le_setup(req);
15562177bab5SJohan Hedberg 
15573f8e2d75SJohan Hedberg 	/* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read
15583f8e2d75SJohan Hedberg 	 * local supported commands HCI command.
15593f8e2d75SJohan Hedberg 	 */
15603f8e2d75SJohan Hedberg 	if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1)
156142c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
15622177bab5SJohan Hedberg 
15632177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
156457af75a8SMarcel Holtmann 		/* When SSP is available, then the host features page
156557af75a8SMarcel Holtmann 		 * should also be available as well. However some
156657af75a8SMarcel Holtmann 		 * controllers list the max_page as 0 as long as SSP
156757af75a8SMarcel Holtmann 		 * has not been enabled. To achieve proper debugging
156857af75a8SMarcel Holtmann 		 * output, force the minimum max_page to 1 at least.
156957af75a8SMarcel Holtmann 		 */
157057af75a8SMarcel Holtmann 		hdev->max_page = 0x01;
157157af75a8SMarcel Holtmann 
15722177bab5SJohan Hedberg 		if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
15732177bab5SJohan Hedberg 			u8 mode = 0x01;
157442c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_SSP_MODE,
15752177bab5SJohan Hedberg 				    sizeof(mode), &mode);
15762177bab5SJohan Hedberg 		} else {
15772177bab5SJohan Hedberg 			struct hci_cp_write_eir cp;
15782177bab5SJohan Hedberg 
15792177bab5SJohan Hedberg 			memset(hdev->eir, 0, sizeof(hdev->eir));
15802177bab5SJohan Hedberg 			memset(&cp, 0, sizeof(cp));
15812177bab5SJohan Hedberg 
158242c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
15832177bab5SJohan Hedberg 		}
15842177bab5SJohan Hedberg 	}
15852177bab5SJohan Hedberg 
15862177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
158742c6b129SJohan Hedberg 		hci_setup_inquiry_mode(req);
15882177bab5SJohan Hedberg 
15892177bab5SJohan Hedberg 	if (lmp_inq_tx_pwr_capable(hdev))
159042c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
15912177bab5SJohan Hedberg 
15922177bab5SJohan Hedberg 	if (lmp_ext_feat_capable(hdev)) {
15932177bab5SJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
15942177bab5SJohan Hedberg 
15952177bab5SJohan Hedberg 		cp.page = 0x01;
159642c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
159742c6b129SJohan Hedberg 			    sizeof(cp), &cp);
15982177bab5SJohan Hedberg 	}
15992177bab5SJohan Hedberg 
16002177bab5SJohan Hedberg 	if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
16012177bab5SJohan Hedberg 		u8 enable = 1;
160242c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
16032177bab5SJohan Hedberg 			    &enable);
16042177bab5SJohan Hedberg 	}
16052177bab5SJohan Hedberg }
16062177bab5SJohan Hedberg 
160742c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req)
16082177bab5SJohan Hedberg {
160942c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
16102177bab5SJohan Hedberg 	struct hci_cp_write_def_link_policy cp;
16112177bab5SJohan Hedberg 	u16 link_policy = 0;
16122177bab5SJohan Hedberg 
16132177bab5SJohan Hedberg 	if (lmp_rswitch_capable(hdev))
16142177bab5SJohan Hedberg 		link_policy |= HCI_LP_RSWITCH;
16152177bab5SJohan Hedberg 	if (lmp_hold_capable(hdev))
16162177bab5SJohan Hedberg 		link_policy |= HCI_LP_HOLD;
16172177bab5SJohan Hedberg 	if (lmp_sniff_capable(hdev))
16182177bab5SJohan Hedberg 		link_policy |= HCI_LP_SNIFF;
16192177bab5SJohan Hedberg 	if (lmp_park_capable(hdev))
16202177bab5SJohan Hedberg 		link_policy |= HCI_LP_PARK;
16212177bab5SJohan Hedberg 
16222177bab5SJohan Hedberg 	cp.policy = cpu_to_le16(link_policy);
162342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp);
16242177bab5SJohan Hedberg }
16252177bab5SJohan Hedberg 
162642c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req)
16272177bab5SJohan Hedberg {
162842c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
16292177bab5SJohan Hedberg 	struct hci_cp_write_le_host_supported cp;
16302177bab5SJohan Hedberg 
1631c73eee91SJohan Hedberg 	/* LE-only devices do not support explicit enablement */
1632c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
1633c73eee91SJohan Hedberg 		return;
1634c73eee91SJohan Hedberg 
16352177bab5SJohan Hedberg 	memset(&cp, 0, sizeof(cp));
16362177bab5SJohan Hedberg 
16372177bab5SJohan Hedberg 	if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
16382177bab5SJohan Hedberg 		cp.le = 0x01;
163932226e4fSMarcel Holtmann 		cp.simul = 0x00;
16402177bab5SJohan Hedberg 	}
16412177bab5SJohan Hedberg 
16422177bab5SJohan Hedberg 	if (cp.le != lmp_host_le_capable(hdev))
164342c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
16442177bab5SJohan Hedberg 			    &cp);
16452177bab5SJohan Hedberg }
16462177bab5SJohan Hedberg 
1647d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req)
1648d62e6d67SJohan Hedberg {
1649d62e6d67SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1650d62e6d67SJohan Hedberg 	u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1651d62e6d67SJohan Hedberg 
1652d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast master role is supported
1653d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
1654d62e6d67SJohan Hedberg 	 */
165553b834d2SMarcel Holtmann 	if (lmp_csb_master_capable(hdev)) {
1656d62e6d67SJohan Hedberg 		events[1] |= 0x40;	/* Triggered Clock Capture */
1657d62e6d67SJohan Hedberg 		events[1] |= 0x80;	/* Synchronization Train Complete */
1658d62e6d67SJohan Hedberg 		events[2] |= 0x10;	/* Slave Page Response Timeout */
1659d62e6d67SJohan Hedberg 		events[2] |= 0x20;	/* CSB Channel Map Change */
1660d62e6d67SJohan Hedberg 	}
1661d62e6d67SJohan Hedberg 
1662d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast slave role is supported
1663d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
1664d62e6d67SJohan Hedberg 	 */
166553b834d2SMarcel Holtmann 	if (lmp_csb_slave_capable(hdev)) {
1666d62e6d67SJohan Hedberg 		events[2] |= 0x01;	/* Synchronization Train Received */
1667d62e6d67SJohan Hedberg 		events[2] |= 0x02;	/* CSB Receive */
1668d62e6d67SJohan Hedberg 		events[2] |= 0x04;	/* CSB Timeout */
1669d62e6d67SJohan Hedberg 		events[2] |= 0x08;	/* Truncated Page Complete */
1670d62e6d67SJohan Hedberg 	}
1671d62e6d67SJohan Hedberg 
167240c59fcbSMarcel Holtmann 	/* Enable Authenticated Payload Timeout Expired event if supported */
1673cd7ca0ecSMarcel Holtmann 	if (lmp_ping_capable(hdev) || hdev->le_features[0] & HCI_LE_PING)
167440c59fcbSMarcel Holtmann 		events[2] |= 0x80;
167540c59fcbSMarcel Holtmann 
1676d62e6d67SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events);
1677d62e6d67SJohan Hedberg }
1678d62e6d67SJohan Hedberg 
167942c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt)
16802177bab5SJohan Hedberg {
168142c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1682d2c5d77fSJohan Hedberg 	u8 p;
168342c6b129SJohan Hedberg 
16840da71f1bSMarcel Holtmann 	hci_setup_event_mask(req);
16850da71f1bSMarcel Holtmann 
1686b8f4e068SGustavo Padovan 	/* Some Broadcom based Bluetooth controllers do not support the
1687b8f4e068SGustavo Padovan 	 * Delete Stored Link Key command. They are clearly indicating its
1688b8f4e068SGustavo Padovan 	 * absence in the bit mask of supported commands.
1689b8f4e068SGustavo Padovan 	 *
1690b8f4e068SGustavo Padovan 	 * Check the supported commands and only if the the command is marked
1691b8f4e068SGustavo Padovan 	 * as supported send it. If not supported assume that the controller
1692b8f4e068SGustavo Padovan 	 * does not have actual support for stored link keys which makes this
1693b8f4e068SGustavo Padovan 	 * command redundant anyway.
1694f9f462faSMarcel Holtmann 	 *
1695f9f462faSMarcel Holtmann 	 * Some controllers indicate that they support handling deleting
1696f9f462faSMarcel Holtmann 	 * stored link keys, but they don't. The quirk lets a driver
1697f9f462faSMarcel Holtmann 	 * just disable this command.
1698b8f4e068SGustavo Padovan 	 */
1699f9f462faSMarcel Holtmann 	if (hdev->commands[6] & 0x80 &&
1700f9f462faSMarcel Holtmann 	    !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) {
170159f45d57SJohan Hedberg 		struct hci_cp_delete_stored_link_key cp;
170259f45d57SJohan Hedberg 
170359f45d57SJohan Hedberg 		bacpy(&cp.bdaddr, BDADDR_ANY);
170459f45d57SJohan Hedberg 		cp.delete_all = 0x01;
170559f45d57SJohan Hedberg 		hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY,
170659f45d57SJohan Hedberg 			    sizeof(cp), &cp);
170759f45d57SJohan Hedberg 	}
170859f45d57SJohan Hedberg 
17092177bab5SJohan Hedberg 	if (hdev->commands[5] & 0x10)
171042c6b129SJohan Hedberg 		hci_setup_link_policy(req);
17112177bab5SJohan Hedberg 
1712417287deSMarcel Holtmann 	if (hdev->commands[8] & 0x01)
1713417287deSMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL);
1714417287deSMarcel Holtmann 
1715417287deSMarcel Holtmann 	/* Some older Broadcom based Bluetooth 1.2 controllers do not
1716417287deSMarcel Holtmann 	 * support the Read Page Scan Type command. Check support for
1717417287deSMarcel Holtmann 	 * this command in the bit mask of supported commands.
1718417287deSMarcel Holtmann 	 */
1719417287deSMarcel Holtmann 	if (hdev->commands[13] & 0x01)
1720417287deSMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL);
1721417287deSMarcel Holtmann 
17229193c6e8SAndre Guedes 	if (lmp_le_capable(hdev)) {
17239193c6e8SAndre Guedes 		u8 events[8];
17249193c6e8SAndre Guedes 
17259193c6e8SAndre Guedes 		memset(events, 0, sizeof(events));
17264d6c705bSMarcel Holtmann 		events[0] = 0x0f;
17274d6c705bSMarcel Holtmann 
17284d6c705bSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_ENCRYPTION)
17294d6c705bSMarcel Holtmann 			events[0] |= 0x10;	/* LE Long Term Key Request */
1730662bc2e6SAndre Guedes 
1731662bc2e6SAndre Guedes 		/* If controller supports the Connection Parameters Request
1732662bc2e6SAndre Guedes 		 * Link Layer Procedure, enable the corresponding event.
1733662bc2e6SAndre Guedes 		 */
1734662bc2e6SAndre Guedes 		if (hdev->le_features[0] & HCI_LE_CONN_PARAM_REQ_PROC)
1735662bc2e6SAndre Guedes 			events[0] |= 0x20;	/* LE Remote Connection
1736662bc2e6SAndre Guedes 						 * Parameter Request
1737662bc2e6SAndre Guedes 						 */
1738662bc2e6SAndre Guedes 
17394b71bba4SMarcel Holtmann 		/* If the controller supports Extended Scanner Filter
17404b71bba4SMarcel Holtmann 		 * Policies, enable the correspondig event.
17414b71bba4SMarcel Holtmann 		 */
17424b71bba4SMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_EXT_SCAN_POLICY)
17434b71bba4SMarcel Holtmann 			events[1] |= 0x04;	/* LE Direct Advertising
17444b71bba4SMarcel Holtmann 						 * Report
17454b71bba4SMarcel Holtmann 						 */
17464b71bba4SMarcel Holtmann 
17475a34bd5fSMarcel Holtmann 		/* If the controller supports the LE Read Local P-256
17485a34bd5fSMarcel Holtmann 		 * Public Key command, enable the corresponding event.
17495a34bd5fSMarcel Holtmann 		 */
17505a34bd5fSMarcel Holtmann 		if (hdev->commands[34] & 0x02)
17515a34bd5fSMarcel Holtmann 			events[0] |= 0x80;	/* LE Read Local P-256
17525a34bd5fSMarcel Holtmann 						 * Public Key Complete
17535a34bd5fSMarcel Holtmann 						 */
17545a34bd5fSMarcel Holtmann 
17555a34bd5fSMarcel Holtmann 		/* If the controller supports the LE Generate DHKey
17565a34bd5fSMarcel Holtmann 		 * command, enable the corresponding event.
17575a34bd5fSMarcel Holtmann 		 */
17585a34bd5fSMarcel Holtmann 		if (hdev->commands[34] & 0x04)
17595a34bd5fSMarcel Holtmann 			events[1] |= 0x01;	/* LE Generate DHKey Complete */
17605a34bd5fSMarcel Holtmann 
17619193c6e8SAndre Guedes 		hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, sizeof(events),
17629193c6e8SAndre Guedes 			    events);
17639193c6e8SAndre Guedes 
176415a49ccaSMarcel Holtmann 		if (hdev->commands[25] & 0x40) {
176515a49ccaSMarcel Holtmann 			/* Read LE Advertising Channel TX Power */
176615a49ccaSMarcel Holtmann 			hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
176715a49ccaSMarcel Holtmann 		}
176815a49ccaSMarcel Holtmann 
176942c6b129SJohan Hedberg 		hci_set_le_support(req);
17709193c6e8SAndre Guedes 	}
1771d2c5d77fSJohan Hedberg 
1772d2c5d77fSJohan Hedberg 	/* Read features beyond page 1 if available */
1773d2c5d77fSJohan Hedberg 	for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
1774d2c5d77fSJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
1775d2c5d77fSJohan Hedberg 
1776d2c5d77fSJohan Hedberg 		cp.page = p;
1777d2c5d77fSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
1778d2c5d77fSJohan Hedberg 			    sizeof(cp), &cp);
1779d2c5d77fSJohan Hedberg 	}
17802177bab5SJohan Hedberg }
17812177bab5SJohan Hedberg 
17825d4e7e8dSJohan Hedberg static void hci_init4_req(struct hci_request *req, unsigned long opt)
17835d4e7e8dSJohan Hedberg {
17845d4e7e8dSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
17855d4e7e8dSJohan Hedberg 
1786d62e6d67SJohan Hedberg 	/* Set event mask page 2 if the HCI command for it is supported */
1787d62e6d67SJohan Hedberg 	if (hdev->commands[22] & 0x04)
1788d62e6d67SJohan Hedberg 		hci_set_event_mask_page_2(req);
1789d62e6d67SJohan Hedberg 
1790109e3191SMarcel Holtmann 	/* Read local codec list if the HCI command is supported */
1791109e3191SMarcel Holtmann 	if (hdev->commands[29] & 0x20)
1792109e3191SMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_LOCAL_CODECS, 0, NULL);
1793109e3191SMarcel Holtmann 
1794f4fe73edSMarcel Holtmann 	/* Get MWS transport configuration if the HCI command is supported */
1795f4fe73edSMarcel Holtmann 	if (hdev->commands[30] & 0x08)
1796f4fe73edSMarcel Holtmann 		hci_req_add(req, HCI_OP_GET_MWS_TRANSPORT_CONFIG, 0, NULL);
1797f4fe73edSMarcel Holtmann 
17985d4e7e8dSJohan Hedberg 	/* Check for Synchronization Train support */
179953b834d2SMarcel Holtmann 	if (lmp_sync_train_capable(hdev))
18005d4e7e8dSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL);
1801a6d0d690SMarcel Holtmann 
1802a6d0d690SMarcel Holtmann 	/* Enable Secure Connections if supported and configured */
1803710f11c0SJohan Hedberg 	if (bredr_sc_enabled(hdev)) {
1804a6d0d690SMarcel Holtmann 		u8 support = 0x01;
1805a6d0d690SMarcel Holtmann 		hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT,
1806a6d0d690SMarcel Holtmann 			    sizeof(support), &support);
1807a6d0d690SMarcel Holtmann 	}
18085d4e7e8dSJohan Hedberg }
18095d4e7e8dSJohan Hedberg 
18102177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev)
18112177bab5SJohan Hedberg {
18122177bab5SJohan Hedberg 	int err;
18132177bab5SJohan Hedberg 
18142177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT);
18152177bab5SJohan Hedberg 	if (err < 0)
18162177bab5SJohan Hedberg 		return err;
18172177bab5SJohan Hedberg 
18184b4148e9SMarcel Holtmann 	/* The Device Under Test (DUT) mode is special and available for
18194b4148e9SMarcel Holtmann 	 * all controller types. So just create it early on.
18204b4148e9SMarcel Holtmann 	 */
18214b4148e9SMarcel Holtmann 	if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
18224b4148e9SMarcel Holtmann 		debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev,
18234b4148e9SMarcel Holtmann 				    &dut_mode_fops);
18244b4148e9SMarcel Holtmann 	}
18254b4148e9SMarcel Holtmann 
18262177bab5SJohan Hedberg 	/* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode
18272177bab5SJohan Hedberg 	 * BR/EDR/LE type controllers. AMP controllers only need the
18282177bab5SJohan Hedberg 	 * first stage init.
18292177bab5SJohan Hedberg 	 */
18302177bab5SJohan Hedberg 	if (hdev->dev_type != HCI_BREDR)
18312177bab5SJohan Hedberg 		return 0;
18322177bab5SJohan Hedberg 
18332177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT);
18342177bab5SJohan Hedberg 	if (err < 0)
18352177bab5SJohan Hedberg 		return err;
18362177bab5SJohan Hedberg 
18375d4e7e8dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT);
18385d4e7e8dSJohan Hedberg 	if (err < 0)
18395d4e7e8dSJohan Hedberg 		return err;
18405d4e7e8dSJohan Hedberg 
1841baf27f6eSMarcel Holtmann 	err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT);
1842baf27f6eSMarcel Holtmann 	if (err < 0)
1843baf27f6eSMarcel Holtmann 		return err;
1844baf27f6eSMarcel Holtmann 
1845baf27f6eSMarcel Holtmann 	/* Only create debugfs entries during the initial setup
1846baf27f6eSMarcel Holtmann 	 * phase and not every time the controller gets powered on.
1847baf27f6eSMarcel Holtmann 	 */
1848baf27f6eSMarcel Holtmann 	if (!test_bit(HCI_SETUP, &hdev->dev_flags))
1849baf27f6eSMarcel Holtmann 		return 0;
1850baf27f6eSMarcel Holtmann 
1851dfb826a8SMarcel Holtmann 	debugfs_create_file("features", 0444, hdev->debugfs, hdev,
1852dfb826a8SMarcel Holtmann 			    &features_fops);
1853ceeb3bc0SMarcel Holtmann 	debugfs_create_u16("manufacturer", 0444, hdev->debugfs,
1854ceeb3bc0SMarcel Holtmann 			   &hdev->manufacturer);
1855ceeb3bc0SMarcel Holtmann 	debugfs_create_u8("hci_version", 0444, hdev->debugfs, &hdev->hci_ver);
1856ceeb3bc0SMarcel Holtmann 	debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev);
185740f4938aSMarcel Holtmann 	debugfs_create_file("device_list", 0444, hdev->debugfs, hdev,
185840f4938aSMarcel Holtmann 			    &device_list_fops);
185970afe0b8SMarcel Holtmann 	debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev,
186070afe0b8SMarcel Holtmann 			    &blacklist_fops);
186147219839SMarcel Holtmann 	debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops);
186247219839SMarcel Holtmann 
186331ad1691SAndrzej Kaczmarek 	debugfs_create_file("conn_info_min_age", 0644, hdev->debugfs, hdev,
186431ad1691SAndrzej Kaczmarek 			    &conn_info_min_age_fops);
186531ad1691SAndrzej Kaczmarek 	debugfs_create_file("conn_info_max_age", 0644, hdev->debugfs, hdev,
186631ad1691SAndrzej Kaczmarek 			    &conn_info_max_age_fops);
186731ad1691SAndrzej Kaczmarek 
1868baf27f6eSMarcel Holtmann 	if (lmp_bredr_capable(hdev)) {
1869baf27f6eSMarcel Holtmann 		debugfs_create_file("inquiry_cache", 0444, hdev->debugfs,
1870baf27f6eSMarcel Holtmann 				    hdev, &inquiry_cache_fops);
187102d08d15SMarcel Holtmann 		debugfs_create_file("link_keys", 0400, hdev->debugfs,
187202d08d15SMarcel Holtmann 				    hdev, &link_keys_fops);
1873babdbb3cSMarcel Holtmann 		debugfs_create_file("dev_class", 0444, hdev->debugfs,
1874babdbb3cSMarcel Holtmann 				    hdev, &dev_class_fops);
1875041000b9SMarcel Holtmann 		debugfs_create_file("voice_setting", 0444, hdev->debugfs,
1876041000b9SMarcel Holtmann 				    hdev, &voice_setting_fops);
1877baf27f6eSMarcel Holtmann 	}
1878baf27f6eSMarcel Holtmann 
187906f5b778SMarcel Holtmann 	if (lmp_ssp_capable(hdev)) {
1880ebd1e33bSMarcel Holtmann 		debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs,
1881ebd1e33bSMarcel Holtmann 				    hdev, &auto_accept_delay_fops);
18825afeac14SMarcel Holtmann 		debugfs_create_file("force_sc_support", 0644, hdev->debugfs,
18835afeac14SMarcel Holtmann 				    hdev, &force_sc_support_fops);
1884134c2a89SMarcel Holtmann 		debugfs_create_file("sc_only_mode", 0444, hdev->debugfs,
1885134c2a89SMarcel Holtmann 				    hdev, &sc_only_mode_fops);
1886858cdc78SJohan Hedberg 		if (lmp_le_capable(hdev))
1887858cdc78SJohan Hedberg 			debugfs_create_file("force_lesc_support", 0644,
1888858cdc78SJohan Hedberg 					    hdev->debugfs, hdev,
1889858cdc78SJohan Hedberg 					    &force_lesc_support_fops);
189006f5b778SMarcel Holtmann 	}
1891ebd1e33bSMarcel Holtmann 
18922bfa3531SMarcel Holtmann 	if (lmp_sniff_capable(hdev)) {
18932bfa3531SMarcel Holtmann 		debugfs_create_file("idle_timeout", 0644, hdev->debugfs,
18942bfa3531SMarcel Holtmann 				    hdev, &idle_timeout_fops);
18952bfa3531SMarcel Holtmann 		debugfs_create_file("sniff_min_interval", 0644, hdev->debugfs,
18962bfa3531SMarcel Holtmann 				    hdev, &sniff_min_interval_fops);
18972bfa3531SMarcel Holtmann 		debugfs_create_file("sniff_max_interval", 0644, hdev->debugfs,
18982bfa3531SMarcel Holtmann 				    hdev, &sniff_max_interval_fops);
18992bfa3531SMarcel Holtmann 	}
19002bfa3531SMarcel Holtmann 
1901d0f729b8SMarcel Holtmann 	if (lmp_le_capable(hdev)) {
1902ac345813SMarcel Holtmann 		debugfs_create_file("identity", 0400, hdev->debugfs,
1903ac345813SMarcel Holtmann 				    hdev, &identity_fops);
1904ac345813SMarcel Holtmann 		debugfs_create_file("rpa_timeout", 0644, hdev->debugfs,
1905ac345813SMarcel Holtmann 				    hdev, &rpa_timeout_fops);
19067a4cd51dSMarcel Holtmann 		debugfs_create_file("random_address", 0444, hdev->debugfs,
19077a4cd51dSMarcel Holtmann 				    hdev, &random_address_fops);
1908e7b8fc92SMarcel Holtmann 		debugfs_create_file("static_address", 0444, hdev->debugfs,
1909e7b8fc92SMarcel Holtmann 				    hdev, &static_address_fops);
1910b32bba6cSMarcel Holtmann 
1911b32bba6cSMarcel Holtmann 		/* For controllers with a public address, provide a debug
1912b32bba6cSMarcel Holtmann 		 * option to force the usage of the configured static
1913b32bba6cSMarcel Holtmann 		 * address. By default the public address is used.
1914b32bba6cSMarcel Holtmann 		 */
1915b32bba6cSMarcel Holtmann 		if (bacmp(&hdev->bdaddr, BDADDR_ANY))
1916b32bba6cSMarcel Holtmann 			debugfs_create_file("force_static_address", 0644,
1917b32bba6cSMarcel Holtmann 					    hdev->debugfs, hdev,
1918b32bba6cSMarcel Holtmann 					    &force_static_address_fops);
1919b32bba6cSMarcel Holtmann 
1920b32bba6cSMarcel Holtmann 		debugfs_create_u8("white_list_size", 0444, hdev->debugfs,
1921b32bba6cSMarcel Holtmann 				  &hdev->le_white_list_size);
1922d2ab0ac1SMarcel Holtmann 		debugfs_create_file("white_list", 0444, hdev->debugfs, hdev,
1923d2ab0ac1SMarcel Holtmann 				    &white_list_fops);
19243698d704SMarcel Holtmann 		debugfs_create_file("identity_resolving_keys", 0400,
19253698d704SMarcel Holtmann 				    hdev->debugfs, hdev,
19263698d704SMarcel Holtmann 				    &identity_resolving_keys_fops);
19278f8625cdSMarcel Holtmann 		debugfs_create_file("long_term_keys", 0400, hdev->debugfs,
19288f8625cdSMarcel Holtmann 				    hdev, &long_term_keys_fops);
19294e70c7e7SMarcel Holtmann 		debugfs_create_file("conn_min_interval", 0644, hdev->debugfs,
19304e70c7e7SMarcel Holtmann 				    hdev, &conn_min_interval_fops);
19314e70c7e7SMarcel Holtmann 		debugfs_create_file("conn_max_interval", 0644, hdev->debugfs,
19324e70c7e7SMarcel Holtmann 				    hdev, &conn_max_interval_fops);
1933816a93d1SMarcel Holtmann 		debugfs_create_file("conn_latency", 0644, hdev->debugfs,
1934816a93d1SMarcel Holtmann 				    hdev, &conn_latency_fops);
1935f1649577SMarcel Holtmann 		debugfs_create_file("supervision_timeout", 0644, hdev->debugfs,
1936f1649577SMarcel Holtmann 				    hdev, &supervision_timeout_fops);
19373f959d46SMarcel Holtmann 		debugfs_create_file("adv_channel_map", 0644, hdev->debugfs,
19383f959d46SMarcel Holtmann 				    hdev, &adv_channel_map_fops);
1939729a1051SGeorg Lukas 		debugfs_create_file("adv_min_interval", 0644, hdev->debugfs,
1940729a1051SGeorg Lukas 				    hdev, &adv_min_interval_fops);
1941729a1051SGeorg Lukas 		debugfs_create_file("adv_max_interval", 0644, hdev->debugfs,
1942729a1051SGeorg Lukas 				    hdev, &adv_max_interval_fops);
1943b9a7a61eSLukasz Rymanowski 		debugfs_create_u16("discov_interleaved_timeout", 0644,
1944b9a7a61eSLukasz Rymanowski 				   hdev->debugfs,
1945b9a7a61eSLukasz Rymanowski 				   &hdev->discov_interleaved_timeout);
194654506918SJohan Hedberg 
1947711eafe3SJohan Hedberg 		smp_register(hdev);
1948d0f729b8SMarcel Holtmann 	}
1949e7b8fc92SMarcel Holtmann 
1950baf27f6eSMarcel Holtmann 	return 0;
19512177bab5SJohan Hedberg }
19522177bab5SJohan Hedberg 
19530ebca7d6SMarcel Holtmann static void hci_init0_req(struct hci_request *req, unsigned long opt)
19540ebca7d6SMarcel Holtmann {
19550ebca7d6SMarcel Holtmann 	struct hci_dev *hdev = req->hdev;
19560ebca7d6SMarcel Holtmann 
19570ebca7d6SMarcel Holtmann 	BT_DBG("%s %ld", hdev->name, opt);
19580ebca7d6SMarcel Holtmann 
19590ebca7d6SMarcel Holtmann 	/* Reset */
19600ebca7d6SMarcel Holtmann 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
19610ebca7d6SMarcel Holtmann 		hci_reset_req(req, 0);
19620ebca7d6SMarcel Holtmann 
19630ebca7d6SMarcel Holtmann 	/* Read Local Version */
19640ebca7d6SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
19650ebca7d6SMarcel Holtmann 
19660ebca7d6SMarcel Holtmann 	/* Read BD Address */
19670ebca7d6SMarcel Holtmann 	if (hdev->set_bdaddr)
19680ebca7d6SMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
19690ebca7d6SMarcel Holtmann }
19700ebca7d6SMarcel Holtmann 
19710ebca7d6SMarcel Holtmann static int __hci_unconf_init(struct hci_dev *hdev)
19720ebca7d6SMarcel Holtmann {
19730ebca7d6SMarcel Holtmann 	int err;
19740ebca7d6SMarcel Holtmann 
1975cc78b44bSMarcel Holtmann 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
1976cc78b44bSMarcel Holtmann 		return 0;
1977cc78b44bSMarcel Holtmann 
19780ebca7d6SMarcel Holtmann 	err = __hci_req_sync(hdev, hci_init0_req, 0, HCI_INIT_TIMEOUT);
19790ebca7d6SMarcel Holtmann 	if (err < 0)
19800ebca7d6SMarcel Holtmann 		return err;
19810ebca7d6SMarcel Holtmann 
19820ebca7d6SMarcel Holtmann 	return 0;
19830ebca7d6SMarcel Holtmann }
19840ebca7d6SMarcel Holtmann 
198542c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt)
19861da177e4SLinus Torvalds {
19871da177e4SLinus Torvalds 	__u8 scan = opt;
19881da177e4SLinus Torvalds 
198942c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, scan);
19901da177e4SLinus Torvalds 
19911da177e4SLinus Torvalds 	/* Inquiry and Page scans */
199242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
19931da177e4SLinus Torvalds }
19941da177e4SLinus Torvalds 
199542c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt)
19961da177e4SLinus Torvalds {
19971da177e4SLinus Torvalds 	__u8 auth = opt;
19981da177e4SLinus Torvalds 
199942c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, auth);
20001da177e4SLinus Torvalds 
20011da177e4SLinus Torvalds 	/* Authentication */
200242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
20031da177e4SLinus Torvalds }
20041da177e4SLinus Torvalds 
200542c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt)
20061da177e4SLinus Torvalds {
20071da177e4SLinus Torvalds 	__u8 encrypt = opt;
20081da177e4SLinus Torvalds 
200942c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, encrypt);
20101da177e4SLinus Torvalds 
2011e4e8e37cSMarcel Holtmann 	/* Encryption */
201242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
20131da177e4SLinus Torvalds }
20141da177e4SLinus Torvalds 
201542c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt)
2016e4e8e37cSMarcel Holtmann {
2017e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
2018e4e8e37cSMarcel Holtmann 
201942c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, policy);
2020e4e8e37cSMarcel Holtmann 
2021e4e8e37cSMarcel Holtmann 	/* Default link policy */
202242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
2023e4e8e37cSMarcel Holtmann }
2024e4e8e37cSMarcel Holtmann 
20251da177e4SLinus Torvalds /* Get HCI device by index.
20261da177e4SLinus Torvalds  * Device is held on return. */
20271da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
20281da177e4SLinus Torvalds {
20298035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
20301da177e4SLinus Torvalds 
20311da177e4SLinus Torvalds 	BT_DBG("%d", index);
20321da177e4SLinus Torvalds 
20331da177e4SLinus Torvalds 	if (index < 0)
20341da177e4SLinus Torvalds 		return NULL;
20351da177e4SLinus Torvalds 
20361da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
20378035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
20381da177e4SLinus Torvalds 		if (d->id == index) {
20391da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
20401da177e4SLinus Torvalds 			break;
20411da177e4SLinus Torvalds 		}
20421da177e4SLinus Torvalds 	}
20431da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
20441da177e4SLinus Torvalds 	return hdev;
20451da177e4SLinus Torvalds }
20461da177e4SLinus Torvalds 
20471da177e4SLinus Torvalds /* ---- Inquiry support ---- */
2048ff9ef578SJohan Hedberg 
204930dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
205030dc78e1SJohan Hedberg {
205130dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
205230dc78e1SJohan Hedberg 
20536fbe195dSAndre Guedes 	switch (discov->state) {
2054343f935bSAndre Guedes 	case DISCOVERY_FINDING:
20556fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
205630dc78e1SJohan Hedberg 		return true;
205730dc78e1SJohan Hedberg 
20586fbe195dSAndre Guedes 	default:
205930dc78e1SJohan Hedberg 		return false;
206030dc78e1SJohan Hedberg 	}
20616fbe195dSAndre Guedes }
206230dc78e1SJohan Hedberg 
2063ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
2064ff9ef578SJohan Hedberg {
2065bb3e0a33SJohan Hedberg 	int old_state = hdev->discovery.state;
2066bb3e0a33SJohan Hedberg 
2067ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
2068ff9ef578SJohan Hedberg 
2069bb3e0a33SJohan Hedberg 	if (old_state == state)
2070ff9ef578SJohan Hedberg 		return;
2071ff9ef578SJohan Hedberg 
2072bb3e0a33SJohan Hedberg 	hdev->discovery.state = state;
2073bb3e0a33SJohan Hedberg 
2074ff9ef578SJohan Hedberg 	switch (state) {
2075ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
2076c54c3860SAndre Guedes 		hci_update_background_scan(hdev);
2077c54c3860SAndre Guedes 
2078bb3e0a33SJohan Hedberg 		if (old_state != DISCOVERY_STARTING)
2079ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
2080ff9ef578SJohan Hedberg 		break;
2081ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
2082ff9ef578SJohan Hedberg 		break;
2083343f935bSAndre Guedes 	case DISCOVERY_FINDING:
2084ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
2085ff9ef578SJohan Hedberg 		break;
208630dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
208730dc78e1SJohan Hedberg 		break;
2088ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
2089ff9ef578SJohan Hedberg 		break;
2090ff9ef578SJohan Hedberg 	}
2091ff9ef578SJohan Hedberg }
2092ff9ef578SJohan Hedberg 
20931f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev)
20941da177e4SLinus Torvalds {
209530883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
2096b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
20971da177e4SLinus Torvalds 
2098561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
2099561aafbcSJohan Hedberg 		list_del(&p->all);
2100b57c1a56SJohan Hedberg 		kfree(p);
21011da177e4SLinus Torvalds 	}
2102561aafbcSJohan Hedberg 
2103561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
2104561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
21051da177e4SLinus Torvalds }
21061da177e4SLinus Torvalds 
2107a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
2108a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
21091da177e4SLinus Torvalds {
211030883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
21111da177e4SLinus Torvalds 	struct inquiry_entry *e;
21121da177e4SLinus Torvalds 
21136ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
21141da177e4SLinus Torvalds 
2115561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
21161da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
21171da177e4SLinus Torvalds 			return e;
21181da177e4SLinus Torvalds 	}
21191da177e4SLinus Torvalds 
2120b57c1a56SJohan Hedberg 	return NULL;
2121b57c1a56SJohan Hedberg }
2122b57c1a56SJohan Hedberg 
2123561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
2124561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
2125561aafbcSJohan Hedberg {
212630883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
2127561aafbcSJohan Hedberg 	struct inquiry_entry *e;
2128561aafbcSJohan Hedberg 
21296ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
2130561aafbcSJohan Hedberg 
2131561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
2132561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
2133561aafbcSJohan Hedberg 			return e;
2134561aafbcSJohan Hedberg 	}
2135561aafbcSJohan Hedberg 
2136561aafbcSJohan Hedberg 	return NULL;
2137561aafbcSJohan Hedberg }
2138561aafbcSJohan Hedberg 
213930dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
214030dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
214130dc78e1SJohan Hedberg 						       int state)
214230dc78e1SJohan Hedberg {
214330dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
214430dc78e1SJohan Hedberg 	struct inquiry_entry *e;
214530dc78e1SJohan Hedberg 
21466ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
214730dc78e1SJohan Hedberg 
214830dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
214930dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
215030dc78e1SJohan Hedberg 			return e;
215130dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
215230dc78e1SJohan Hedberg 			return e;
215330dc78e1SJohan Hedberg 	}
215430dc78e1SJohan Hedberg 
215530dc78e1SJohan Hedberg 	return NULL;
215630dc78e1SJohan Hedberg }
215730dc78e1SJohan Hedberg 
2158a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
2159a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
2160a3d4e20aSJohan Hedberg {
2161a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
2162a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
2163a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
2164a3d4e20aSJohan Hedberg 
2165a3d4e20aSJohan Hedberg 	list_del(&ie->list);
2166a3d4e20aSJohan Hedberg 
2167a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
2168a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
2169a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
2170a3d4e20aSJohan Hedberg 			break;
2171a3d4e20aSJohan Hedberg 		pos = &p->list;
2172a3d4e20aSJohan Hedberg 	}
2173a3d4e20aSJohan Hedberg 
2174a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
2175a3d4e20aSJohan Hedberg }
2176a3d4e20aSJohan Hedberg 
2177af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
2178af58925cSMarcel Holtmann 			     bool name_known)
21791da177e4SLinus Torvalds {
218030883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
218170f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
2182af58925cSMarcel Holtmann 	u32 flags = 0;
21831da177e4SLinus Torvalds 
21846ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
21851da177e4SLinus Torvalds 
21866928a924SJohan Hedberg 	hci_remove_remote_oob_data(hdev, &data->bdaddr, BDADDR_BREDR);
21872b2fec4dSSzymon Janc 
2188af58925cSMarcel Holtmann 	if (!data->ssp_mode)
2189af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
2190388fc8faSJohan Hedberg 
219170f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
2192a3d4e20aSJohan Hedberg 	if (ie) {
2193af58925cSMarcel Holtmann 		if (!ie->data.ssp_mode)
2194af58925cSMarcel Holtmann 			flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
2195388fc8faSJohan Hedberg 
2196a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
2197a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
2198a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
2199a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
2200a3d4e20aSJohan Hedberg 		}
2201a3d4e20aSJohan Hedberg 
2202561aafbcSJohan Hedberg 		goto update;
2203a3d4e20aSJohan Hedberg 	}
2204561aafbcSJohan Hedberg 
22051da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
220627f70f3eSJohan Hedberg 	ie = kzalloc(sizeof(*ie), GFP_KERNEL);
2207af58925cSMarcel Holtmann 	if (!ie) {
2208af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
2209af58925cSMarcel Holtmann 		goto done;
2210af58925cSMarcel Holtmann 	}
221170f23020SAndrei Emeltchenko 
2212561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
2213561aafbcSJohan Hedberg 
2214561aafbcSJohan Hedberg 	if (name_known) {
2215561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
2216561aafbcSJohan Hedberg 	} else {
2217561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
2218561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
2219561aafbcSJohan Hedberg 	}
2220561aafbcSJohan Hedberg 
2221561aafbcSJohan Hedberg update:
2222561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
2223561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
2224561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
2225561aafbcSJohan Hedberg 		list_del(&ie->list);
22261da177e4SLinus Torvalds 	}
22271da177e4SLinus Torvalds 
222870f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
222970f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
22301da177e4SLinus Torvalds 	cache->timestamp = jiffies;
22313175405bSJohan Hedberg 
22323175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
2233af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
22343175405bSJohan Hedberg 
2235af58925cSMarcel Holtmann done:
2236af58925cSMarcel Holtmann 	return flags;
22371da177e4SLinus Torvalds }
22381da177e4SLinus Torvalds 
22391da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
22401da177e4SLinus Torvalds {
224130883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
22421da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
22431da177e4SLinus Torvalds 	struct inquiry_entry *e;
22441da177e4SLinus Torvalds 	int copied = 0;
22451da177e4SLinus Torvalds 
2246561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
22471da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
2248b57c1a56SJohan Hedberg 
2249b57c1a56SJohan Hedberg 		if (copied >= num)
2250b57c1a56SJohan Hedberg 			break;
2251b57c1a56SJohan Hedberg 
22521da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
22531da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
22541da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
22551da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
22561da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
22571da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
2258b57c1a56SJohan Hedberg 
22591da177e4SLinus Torvalds 		info++;
2260b57c1a56SJohan Hedberg 		copied++;
22611da177e4SLinus Torvalds 	}
22621da177e4SLinus Torvalds 
22631da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
22641da177e4SLinus Torvalds 	return copied;
22651da177e4SLinus Torvalds }
22661da177e4SLinus Torvalds 
226742c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt)
22681da177e4SLinus Torvalds {
22691da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
227042c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
22711da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
22721da177e4SLinus Torvalds 
22731da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
22741da177e4SLinus Torvalds 
22751da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
22761da177e4SLinus Torvalds 		return;
22771da177e4SLinus Torvalds 
22781da177e4SLinus Torvalds 	/* Start Inquiry */
22791da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
22801da177e4SLinus Torvalds 	cp.length  = ir->length;
22811da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
228242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
22831da177e4SLinus Torvalds }
22841da177e4SLinus Torvalds 
22851da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
22861da177e4SLinus Torvalds {
22871da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
22881da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
22891da177e4SLinus Torvalds 	struct hci_dev *hdev;
22901da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
22911da177e4SLinus Torvalds 	long timeo;
22921da177e4SLinus Torvalds 	__u8 *buf;
22931da177e4SLinus Torvalds 
22941da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
22951da177e4SLinus Torvalds 		return -EFAULT;
22961da177e4SLinus Torvalds 
22975a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
22985a08ecceSAndrei Emeltchenko 	if (!hdev)
22991da177e4SLinus Torvalds 		return -ENODEV;
23001da177e4SLinus Torvalds 
23010736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
23020736cfa8SMarcel Holtmann 		err = -EBUSY;
23030736cfa8SMarcel Holtmann 		goto done;
23040736cfa8SMarcel Holtmann 	}
23050736cfa8SMarcel Holtmann 
23064a964404SMarcel Holtmann 	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
2307fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
2308fee746b0SMarcel Holtmann 		goto done;
2309fee746b0SMarcel Holtmann 	}
2310fee746b0SMarcel Holtmann 
23115b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
23125b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
23135b69bef5SMarcel Holtmann 		goto done;
23145b69bef5SMarcel Holtmann 	}
23155b69bef5SMarcel Holtmann 
231656f87901SJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
231756f87901SJohan Hedberg 		err = -EOPNOTSUPP;
231856f87901SJohan Hedberg 		goto done;
231956f87901SJohan Hedberg 	}
232056f87901SJohan Hedberg 
232109fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
23221da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
2323a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
23241f9b9a5dSAndre Guedes 		hci_inquiry_cache_flush(hdev);
23251da177e4SLinus Torvalds 		do_inquiry = 1;
23261da177e4SLinus Torvalds 	}
232709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
23281da177e4SLinus Torvalds 
232904837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
233070f23020SAndrei Emeltchenko 
233170f23020SAndrei Emeltchenko 	if (do_inquiry) {
233201178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
233301178cd4SJohan Hedberg 				   timeo);
233470f23020SAndrei Emeltchenko 		if (err < 0)
23351da177e4SLinus Torvalds 			goto done;
23363e13fa1eSAndre Guedes 
23373e13fa1eSAndre Guedes 		/* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
23383e13fa1eSAndre Guedes 		 * cleared). If it is interrupted by a signal, return -EINTR.
23393e13fa1eSAndre Guedes 		 */
234074316201SNeilBrown 		if (wait_on_bit(&hdev->flags, HCI_INQUIRY,
23413e13fa1eSAndre Guedes 				TASK_INTERRUPTIBLE))
23423e13fa1eSAndre Guedes 			return -EINTR;
234370f23020SAndrei Emeltchenko 	}
23441da177e4SLinus Torvalds 
23458fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
23468fc9ced3SGustavo Padovan 	 * 255 entries
23478fc9ced3SGustavo Padovan 	 */
23481da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
23491da177e4SLinus Torvalds 
23501da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
23511da177e4SLinus Torvalds 	 * copy it to the user space.
23521da177e4SLinus Torvalds 	 */
235370f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
235470f23020SAndrei Emeltchenko 	if (!buf) {
23551da177e4SLinus Torvalds 		err = -ENOMEM;
23561da177e4SLinus Torvalds 		goto done;
23571da177e4SLinus Torvalds 	}
23581da177e4SLinus Torvalds 
235909fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
23601da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
236109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
23621da177e4SLinus Torvalds 
23631da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
23641da177e4SLinus Torvalds 
23651da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
23661da177e4SLinus Torvalds 		ptr += sizeof(ir);
23671da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
23681da177e4SLinus Torvalds 				 ir.num_rsp))
23691da177e4SLinus Torvalds 			err = -EFAULT;
23701da177e4SLinus Torvalds 	} else
23711da177e4SLinus Torvalds 		err = -EFAULT;
23721da177e4SLinus Torvalds 
23731da177e4SLinus Torvalds 	kfree(buf);
23741da177e4SLinus Torvalds 
23751da177e4SLinus Torvalds done:
23761da177e4SLinus Torvalds 	hci_dev_put(hdev);
23771da177e4SLinus Torvalds 	return err;
23781da177e4SLinus Torvalds }
23791da177e4SLinus Torvalds 
2380cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev)
23811da177e4SLinus Torvalds {
23821da177e4SLinus Torvalds 	int ret = 0;
23831da177e4SLinus Torvalds 
23841da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
23851da177e4SLinus Torvalds 
23861da177e4SLinus Torvalds 	hci_req_lock(hdev);
23871da177e4SLinus Torvalds 
238894324962SJohan Hovold 	if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) {
238994324962SJohan Hovold 		ret = -ENODEV;
239094324962SJohan Hovold 		goto done;
239194324962SJohan Hovold 	}
239294324962SJohan Hovold 
2393d603b76bSMarcel Holtmann 	if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
2394d603b76bSMarcel Holtmann 	    !test_bit(HCI_CONFIG, &hdev->dev_flags)) {
2395a5c8f270SMarcel Holtmann 		/* Check for rfkill but allow the HCI setup stage to
2396a5c8f270SMarcel Holtmann 		 * proceed (which in itself doesn't cause any RF activity).
2397bf543036SJohan Hedberg 		 */
2398a5c8f270SMarcel Holtmann 		if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) {
2399611b30f7SMarcel Holtmann 			ret = -ERFKILL;
2400611b30f7SMarcel Holtmann 			goto done;
2401611b30f7SMarcel Holtmann 		}
2402611b30f7SMarcel Holtmann 
2403a5c8f270SMarcel Holtmann 		/* Check for valid public address or a configured static
2404a5c8f270SMarcel Holtmann 		 * random adddress, but let the HCI setup proceed to
2405a5c8f270SMarcel Holtmann 		 * be able to determine if there is a public address
2406a5c8f270SMarcel Holtmann 		 * or not.
2407a5c8f270SMarcel Holtmann 		 *
2408c6beca0eSMarcel Holtmann 		 * In case of user channel usage, it is not important
2409c6beca0eSMarcel Holtmann 		 * if a public address or static random address is
2410c6beca0eSMarcel Holtmann 		 * available.
2411c6beca0eSMarcel Holtmann 		 *
2412a5c8f270SMarcel Holtmann 		 * This check is only valid for BR/EDR controllers
2413a5c8f270SMarcel Holtmann 		 * since AMP controllers do not have an address.
2414a5c8f270SMarcel Holtmann 		 */
2415c6beca0eSMarcel Holtmann 		if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
2416c6beca0eSMarcel Holtmann 		    hdev->dev_type == HCI_BREDR &&
2417a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
2418a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->static_addr, BDADDR_ANY)) {
2419a5c8f270SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
2420a5c8f270SMarcel Holtmann 			goto done;
2421a5c8f270SMarcel Holtmann 		}
2422a5c8f270SMarcel Holtmann 	}
2423a5c8f270SMarcel Holtmann 
24241da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
24251da177e4SLinus Torvalds 		ret = -EALREADY;
24261da177e4SLinus Torvalds 		goto done;
24271da177e4SLinus Torvalds 	}
24281da177e4SLinus Torvalds 
24291da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
24301da177e4SLinus Torvalds 		ret = -EIO;
24311da177e4SLinus Torvalds 		goto done;
24321da177e4SLinus Torvalds 	}
24331da177e4SLinus Torvalds 
24341da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
24351da177e4SLinus Torvalds 	set_bit(HCI_INIT, &hdev->flags);
2436f41c70c4SMarcel Holtmann 
2437af202f84SMarcel Holtmann 	if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
2438af202f84SMarcel Holtmann 		if (hdev->setup)
2439f41c70c4SMarcel Holtmann 			ret = hdev->setup(hdev);
2440f41c70c4SMarcel Holtmann 
2441af202f84SMarcel Holtmann 		/* The transport driver can set these quirks before
2442af202f84SMarcel Holtmann 		 * creating the HCI device or in its setup callback.
2443af202f84SMarcel Holtmann 		 *
2444af202f84SMarcel Holtmann 		 * In case any of them is set, the controller has to
2445af202f84SMarcel Holtmann 		 * start up as unconfigured.
2446af202f84SMarcel Holtmann 		 */
2447eb1904f4SMarcel Holtmann 		if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) ||
2448eb1904f4SMarcel Holtmann 		    test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks))
244989bc22d2SMarcel Holtmann 			set_bit(HCI_UNCONFIGURED, &hdev->dev_flags);
2450f41c70c4SMarcel Holtmann 
24510ebca7d6SMarcel Holtmann 		/* For an unconfigured controller it is required to
24520ebca7d6SMarcel Holtmann 		 * read at least the version information provided by
24530ebca7d6SMarcel Holtmann 		 * the Read Local Version Information command.
24540ebca7d6SMarcel Holtmann 		 *
24550ebca7d6SMarcel Holtmann 		 * If the set_bdaddr driver callback is provided, then
24560ebca7d6SMarcel Holtmann 		 * also the original Bluetooth public device address
24570ebca7d6SMarcel Holtmann 		 * will be read using the Read BD Address command.
24580ebca7d6SMarcel Holtmann 		 */
24590ebca7d6SMarcel Holtmann 		if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
24600ebca7d6SMarcel Holtmann 			ret = __hci_unconf_init(hdev);
246189bc22d2SMarcel Holtmann 	}
246289bc22d2SMarcel Holtmann 
24639713c17bSMarcel Holtmann 	if (test_bit(HCI_CONFIG, &hdev->dev_flags)) {
24649713c17bSMarcel Holtmann 		/* If public address change is configured, ensure that
24659713c17bSMarcel Holtmann 		 * the address gets programmed. If the driver does not
24669713c17bSMarcel Holtmann 		 * support changing the public address, fail the power
24679713c17bSMarcel Holtmann 		 * on procedure.
246824c457e2SMarcel Holtmann 		 */
24699713c17bSMarcel Holtmann 		if (bacmp(&hdev->public_addr, BDADDR_ANY) &&
24709713c17bSMarcel Holtmann 		    hdev->set_bdaddr)
247124c457e2SMarcel Holtmann 			ret = hdev->set_bdaddr(hdev, &hdev->public_addr);
247224c457e2SMarcel Holtmann 		else
247324c457e2SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
247424c457e2SMarcel Holtmann 	}
247524c457e2SMarcel Holtmann 
2476f41c70c4SMarcel Holtmann 	if (!ret) {
24774a964404SMarcel Holtmann 		if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
24780736cfa8SMarcel Holtmann 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
24792177bab5SJohan Hedberg 			ret = __hci_init(hdev);
24801da177e4SLinus Torvalds 	}
24811da177e4SLinus Torvalds 
2482f41c70c4SMarcel Holtmann 	clear_bit(HCI_INIT, &hdev->flags);
2483f41c70c4SMarcel Holtmann 
24841da177e4SLinus Torvalds 	if (!ret) {
24851da177e4SLinus Torvalds 		hci_dev_hold(hdev);
2486d6bfd59cSJohan Hedberg 		set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags);
24871da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
24881da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
2489bb4b2a9aSAndrei Emeltchenko 		if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
2490d603b76bSMarcel Holtmann 		    !test_bit(HCI_CONFIG, &hdev->dev_flags) &&
24914a964404SMarcel Holtmann 		    !test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
24920736cfa8SMarcel Holtmann 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
24931514b892SMarcel Holtmann 		    hdev->dev_type == HCI_BREDR) {
249409fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
2495744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
249609fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
249756e5cb86SJohan Hedberg 		}
24981da177e4SLinus Torvalds 	} else {
24991da177e4SLinus Torvalds 		/* Init failed, cleanup */
25003eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
2501c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
2502b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
25031da177e4SLinus Torvalds 
25041da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
25051da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
25061da177e4SLinus Torvalds 
25071da177e4SLinus Torvalds 		if (hdev->flush)
25081da177e4SLinus Torvalds 			hdev->flush(hdev);
25091da177e4SLinus Torvalds 
25101da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
25111da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
25121da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
25131da177e4SLinus Torvalds 		}
25141da177e4SLinus Torvalds 
25151da177e4SLinus Torvalds 		hdev->close(hdev);
2516fee746b0SMarcel Holtmann 		hdev->flags &= BIT(HCI_RAW);
25171da177e4SLinus Torvalds 	}
25181da177e4SLinus Torvalds 
25191da177e4SLinus Torvalds done:
25201da177e4SLinus Torvalds 	hci_req_unlock(hdev);
25211da177e4SLinus Torvalds 	return ret;
25221da177e4SLinus Torvalds }
25231da177e4SLinus Torvalds 
2524cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */
2525cbed0ca1SJohan Hedberg 
2526cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev)
2527cbed0ca1SJohan Hedberg {
2528cbed0ca1SJohan Hedberg 	struct hci_dev *hdev;
2529cbed0ca1SJohan Hedberg 	int err;
2530cbed0ca1SJohan Hedberg 
2531cbed0ca1SJohan Hedberg 	hdev = hci_dev_get(dev);
2532cbed0ca1SJohan Hedberg 	if (!hdev)
2533cbed0ca1SJohan Hedberg 		return -ENODEV;
2534cbed0ca1SJohan Hedberg 
25354a964404SMarcel Holtmann 	/* Devices that are marked as unconfigured can only be powered
2536fee746b0SMarcel Holtmann 	 * up as user channel. Trying to bring them up as normal devices
2537fee746b0SMarcel Holtmann 	 * will result into a failure. Only user channel operation is
2538fee746b0SMarcel Holtmann 	 * possible.
2539fee746b0SMarcel Holtmann 	 *
2540fee746b0SMarcel Holtmann 	 * When this function is called for a user channel, the flag
2541fee746b0SMarcel Holtmann 	 * HCI_USER_CHANNEL will be set first before attempting to
2542fee746b0SMarcel Holtmann 	 * open the device.
2543fee746b0SMarcel Holtmann 	 */
25444a964404SMarcel Holtmann 	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
2545fee746b0SMarcel Holtmann 	    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
2546fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
2547fee746b0SMarcel Holtmann 		goto done;
2548fee746b0SMarcel Holtmann 	}
2549fee746b0SMarcel Holtmann 
2550e1d08f40SJohan Hedberg 	/* We need to ensure that no other power on/off work is pending
2551e1d08f40SJohan Hedberg 	 * before proceeding to call hci_dev_do_open. This is
2552e1d08f40SJohan Hedberg 	 * particularly important if the setup procedure has not yet
2553e1d08f40SJohan Hedberg 	 * completed.
2554e1d08f40SJohan Hedberg 	 */
2555e1d08f40SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
2556e1d08f40SJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
2557e1d08f40SJohan Hedberg 
2558a5c8f270SMarcel Holtmann 	/* After this call it is guaranteed that the setup procedure
2559a5c8f270SMarcel Holtmann 	 * has finished. This means that error conditions like RFKILL
2560a5c8f270SMarcel Holtmann 	 * or no valid public or static random address apply.
2561a5c8f270SMarcel Holtmann 	 */
2562e1d08f40SJohan Hedberg 	flush_workqueue(hdev->req_workqueue);
2563e1d08f40SJohan Hedberg 
256412aa4f0aSMarcel Holtmann 	/* For controllers not using the management interface and that
2565b6ae8457SJohan Hedberg 	 * are brought up using legacy ioctl, set the HCI_BONDABLE bit
256612aa4f0aSMarcel Holtmann 	 * so that pairing works for them. Once the management interface
256712aa4f0aSMarcel Holtmann 	 * is in use this bit will be cleared again and userspace has
256812aa4f0aSMarcel Holtmann 	 * to explicitly enable it.
256912aa4f0aSMarcel Holtmann 	 */
257012aa4f0aSMarcel Holtmann 	if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
257112aa4f0aSMarcel Holtmann 	    !test_bit(HCI_MGMT, &hdev->dev_flags))
2572b6ae8457SJohan Hedberg 		set_bit(HCI_BONDABLE, &hdev->dev_flags);
257312aa4f0aSMarcel Holtmann 
2574cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
2575cbed0ca1SJohan Hedberg 
2576fee746b0SMarcel Holtmann done:
2577cbed0ca1SJohan Hedberg 	hci_dev_put(hdev);
2578cbed0ca1SJohan Hedberg 	return err;
2579cbed0ca1SJohan Hedberg }
2580cbed0ca1SJohan Hedberg 
2581d7347f3cSJohan Hedberg /* This function requires the caller holds hdev->lock */
2582d7347f3cSJohan Hedberg static void hci_pend_le_actions_clear(struct hci_dev *hdev)
2583d7347f3cSJohan Hedberg {
2584d7347f3cSJohan Hedberg 	struct hci_conn_params *p;
2585d7347f3cSJohan Hedberg 
2586f161dd41SJohan Hedberg 	list_for_each_entry(p, &hdev->le_conn_params, list) {
2587f161dd41SJohan Hedberg 		if (p->conn) {
2588f161dd41SJohan Hedberg 			hci_conn_drop(p->conn);
2589f8aaf9b6SJohan Hedberg 			hci_conn_put(p->conn);
2590f161dd41SJohan Hedberg 			p->conn = NULL;
2591f161dd41SJohan Hedberg 		}
2592d7347f3cSJohan Hedberg 		list_del_init(&p->action);
2593f161dd41SJohan Hedberg 	}
2594d7347f3cSJohan Hedberg 
2595d7347f3cSJohan Hedberg 	BT_DBG("All LE pending actions cleared");
2596d7347f3cSJohan Hedberg }
2597d7347f3cSJohan Hedberg 
25981da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
25991da177e4SLinus Torvalds {
26001da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
26011da177e4SLinus Torvalds 
260278c04c0bSVinicius Costa Gomes 	cancel_delayed_work(&hdev->power_off);
260378c04c0bSVinicius Costa Gomes 
26041da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
26051da177e4SLinus Torvalds 	hci_req_lock(hdev);
26061da177e4SLinus Torvalds 
26071da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
260865cc2b49SMarcel Holtmann 		cancel_delayed_work_sync(&hdev->cmd_timer);
26091da177e4SLinus Torvalds 		hci_req_unlock(hdev);
26101da177e4SLinus Torvalds 		return 0;
26111da177e4SLinus Torvalds 	}
26121da177e4SLinus Torvalds 
26133eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
26143eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
2615b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
26161da177e4SLinus Torvalds 
261716ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
2618e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
261916ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
26205e5282bbSJohan Hedberg 		clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
2621310a3d48SMarcel Holtmann 		clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
262216ab91abSJohan Hedberg 	}
262316ab91abSJohan Hedberg 
2624a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
26257d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
26267d78525dSJohan Hedberg 
26277ba8b4beSAndre Guedes 	cancel_delayed_work_sync(&hdev->le_scan_disable);
26284518bb0fSJohan Hedberg 
26294518bb0fSJohan Hedberg 	if (test_bit(HCI_MGMT, &hdev->dev_flags))
2630d6bfd59cSJohan Hedberg 		cancel_delayed_work_sync(&hdev->rpa_expired);
26317ba8b4beSAndre Guedes 
263276727c02SJohan Hedberg 	/* Avoid potential lockdep warnings from the *_flush() calls by
263376727c02SJohan Hedberg 	 * ensuring the workqueue is empty up front.
263476727c02SJohan Hedberg 	 */
263576727c02SJohan Hedberg 	drain_workqueue(hdev->workqueue);
263676727c02SJohan Hedberg 
263709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
26381aeb9c65SJohan Hedberg 
26391aeb9c65SJohan Hedberg 	if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
26401aeb9c65SJohan Hedberg 		if (hdev->dev_type == HCI_BREDR)
26411aeb9c65SJohan Hedberg 			mgmt_powered(hdev, 0);
26421aeb9c65SJohan Hedberg 	}
26431aeb9c65SJohan Hedberg 
26441f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
2645d7347f3cSJohan Hedberg 	hci_pend_le_actions_clear(hdev);
2646f161dd41SJohan Hedberg 	hci_conn_hash_flush(hdev);
264709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
26481da177e4SLinus Torvalds 
26491da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
26501da177e4SLinus Torvalds 
26511da177e4SLinus Torvalds 	if (hdev->flush)
26521da177e4SLinus Torvalds 		hdev->flush(hdev);
26531da177e4SLinus Torvalds 
26541da177e4SLinus Torvalds 	/* Reset device */
26551da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
26561da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
26574a964404SMarcel Holtmann 	if (!test_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
26584a964404SMarcel Holtmann 	    !test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
2659a6c511c6SSzymon Janc 	    test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
26601da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
266101178cd4SJohan Hedberg 		__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
26621da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
26631da177e4SLinus Torvalds 	}
26641da177e4SLinus Torvalds 
2665c347b765SGustavo F. Padovan 	/* flush cmd  work */
2666c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
26671da177e4SLinus Torvalds 
26681da177e4SLinus Torvalds 	/* Drop queues */
26691da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
26701da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
26711da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
26721da177e4SLinus Torvalds 
26731da177e4SLinus Torvalds 	/* Drop last sent command */
26741da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
267565cc2b49SMarcel Holtmann 		cancel_delayed_work_sync(&hdev->cmd_timer);
26761da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
26771da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
26781da177e4SLinus Torvalds 	}
26791da177e4SLinus Torvalds 
2680b6ddb638SJohan Hedberg 	kfree_skb(hdev->recv_evt);
2681b6ddb638SJohan Hedberg 	hdev->recv_evt = NULL;
2682b6ddb638SJohan Hedberg 
26831da177e4SLinus Torvalds 	/* After this point our queues are empty
26841da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
26851da177e4SLinus Torvalds 	hdev->close(hdev);
26861da177e4SLinus Torvalds 
268735b973c9SJohan Hedberg 	/* Clear flags */
2688fee746b0SMarcel Holtmann 	hdev->flags &= BIT(HCI_RAW);
268935b973c9SJohan Hedberg 	hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
269035b973c9SJohan Hedberg 
2691ced5c338SAndrei Emeltchenko 	/* Controller radio is available but is currently powered down */
2692536619e8SMarcel Holtmann 	hdev->amp_status = AMP_STATUS_POWERED_DOWN;
2693ced5c338SAndrei Emeltchenko 
2694e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
269509b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
26967a4cd51dSMarcel Holtmann 	bacpy(&hdev->random_addr, BDADDR_ANY);
2697e59fda8dSJohan Hedberg 
26981da177e4SLinus Torvalds 	hci_req_unlock(hdev);
26991da177e4SLinus Torvalds 
27001da177e4SLinus Torvalds 	hci_dev_put(hdev);
27011da177e4SLinus Torvalds 	return 0;
27021da177e4SLinus Torvalds }
27031da177e4SLinus Torvalds 
27041da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
27051da177e4SLinus Torvalds {
27061da177e4SLinus Torvalds 	struct hci_dev *hdev;
27071da177e4SLinus Torvalds 	int err;
27081da177e4SLinus Torvalds 
270970f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
271070f23020SAndrei Emeltchenko 	if (!hdev)
27111da177e4SLinus Torvalds 		return -ENODEV;
27128ee56540SMarcel Holtmann 
27130736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
27140736cfa8SMarcel Holtmann 		err = -EBUSY;
27150736cfa8SMarcel Holtmann 		goto done;
27160736cfa8SMarcel Holtmann 	}
27170736cfa8SMarcel Holtmann 
27188ee56540SMarcel Holtmann 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
27198ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
27208ee56540SMarcel Holtmann 
27211da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
27228ee56540SMarcel Holtmann 
27230736cfa8SMarcel Holtmann done:
27241da177e4SLinus Torvalds 	hci_dev_put(hdev);
27251da177e4SLinus Torvalds 	return err;
27261da177e4SLinus Torvalds }
27271da177e4SLinus Torvalds 
27281da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
27291da177e4SLinus Torvalds {
27301da177e4SLinus Torvalds 	struct hci_dev *hdev;
27311da177e4SLinus Torvalds 	int ret = 0;
27321da177e4SLinus Torvalds 
273370f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
273470f23020SAndrei Emeltchenko 	if (!hdev)
27351da177e4SLinus Torvalds 		return -ENODEV;
27361da177e4SLinus Torvalds 
27371da177e4SLinus Torvalds 	hci_req_lock(hdev);
27381da177e4SLinus Torvalds 
2739808a049eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
2740808a049eSMarcel Holtmann 		ret = -ENETDOWN;
27411da177e4SLinus Torvalds 		goto done;
2742808a049eSMarcel Holtmann 	}
27431da177e4SLinus Torvalds 
27440736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
27450736cfa8SMarcel Holtmann 		ret = -EBUSY;
27460736cfa8SMarcel Holtmann 		goto done;
27470736cfa8SMarcel Holtmann 	}
27480736cfa8SMarcel Holtmann 
27494a964404SMarcel Holtmann 	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
2750fee746b0SMarcel Holtmann 		ret = -EOPNOTSUPP;
2751fee746b0SMarcel Holtmann 		goto done;
2752fee746b0SMarcel Holtmann 	}
2753fee746b0SMarcel Holtmann 
27541da177e4SLinus Torvalds 	/* Drop queues */
27551da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
27561da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
27571da177e4SLinus Torvalds 
275876727c02SJohan Hedberg 	/* Avoid potential lockdep warnings from the *_flush() calls by
275976727c02SJohan Hedberg 	 * ensuring the workqueue is empty up front.
276076727c02SJohan Hedberg 	 */
276176727c02SJohan Hedberg 	drain_workqueue(hdev->workqueue);
276276727c02SJohan Hedberg 
276309fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
27641f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
27651da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
276609fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
27671da177e4SLinus Torvalds 
27681da177e4SLinus Torvalds 	if (hdev->flush)
27691da177e4SLinus Torvalds 		hdev->flush(hdev);
27701da177e4SLinus Torvalds 
27711da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
27726ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
27731da177e4SLinus Torvalds 
277401178cd4SJohan Hedberg 	ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
27751da177e4SLinus Torvalds 
27761da177e4SLinus Torvalds done:
27771da177e4SLinus Torvalds 	hci_req_unlock(hdev);
27781da177e4SLinus Torvalds 	hci_dev_put(hdev);
27791da177e4SLinus Torvalds 	return ret;
27801da177e4SLinus Torvalds }
27811da177e4SLinus Torvalds 
27821da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
27831da177e4SLinus Torvalds {
27841da177e4SLinus Torvalds 	struct hci_dev *hdev;
27851da177e4SLinus Torvalds 	int ret = 0;
27861da177e4SLinus Torvalds 
278770f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
278870f23020SAndrei Emeltchenko 	if (!hdev)
27891da177e4SLinus Torvalds 		return -ENODEV;
27901da177e4SLinus Torvalds 
27910736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
27920736cfa8SMarcel Holtmann 		ret = -EBUSY;
27930736cfa8SMarcel Holtmann 		goto done;
27940736cfa8SMarcel Holtmann 	}
27950736cfa8SMarcel Holtmann 
27964a964404SMarcel Holtmann 	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
2797fee746b0SMarcel Holtmann 		ret = -EOPNOTSUPP;
2798fee746b0SMarcel Holtmann 		goto done;
2799fee746b0SMarcel Holtmann 	}
2800fee746b0SMarcel Holtmann 
28011da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
28021da177e4SLinus Torvalds 
28030736cfa8SMarcel Holtmann done:
28041da177e4SLinus Torvalds 	hci_dev_put(hdev);
28051da177e4SLinus Torvalds 	return ret;
28061da177e4SLinus Torvalds }
28071da177e4SLinus Torvalds 
2808123abc08SJohan Hedberg static void hci_update_scan_state(struct hci_dev *hdev, u8 scan)
2809123abc08SJohan Hedberg {
2810bc6d2d04SJohan Hedberg 	bool conn_changed, discov_changed;
2811123abc08SJohan Hedberg 
2812123abc08SJohan Hedberg 	BT_DBG("%s scan 0x%02x", hdev->name, scan);
2813123abc08SJohan Hedberg 
2814123abc08SJohan Hedberg 	if ((scan & SCAN_PAGE))
2815123abc08SJohan Hedberg 		conn_changed = !test_and_set_bit(HCI_CONNECTABLE,
2816123abc08SJohan Hedberg 						 &hdev->dev_flags);
2817123abc08SJohan Hedberg 	else
2818123abc08SJohan Hedberg 		conn_changed = test_and_clear_bit(HCI_CONNECTABLE,
2819123abc08SJohan Hedberg 						  &hdev->dev_flags);
2820123abc08SJohan Hedberg 
2821bc6d2d04SJohan Hedberg 	if ((scan & SCAN_INQUIRY)) {
2822bc6d2d04SJohan Hedberg 		discov_changed = !test_and_set_bit(HCI_DISCOVERABLE,
2823bc6d2d04SJohan Hedberg 						   &hdev->dev_flags);
2824bc6d2d04SJohan Hedberg 	} else {
2825bc6d2d04SJohan Hedberg 		clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
2826bc6d2d04SJohan Hedberg 		discov_changed = test_and_clear_bit(HCI_DISCOVERABLE,
2827bc6d2d04SJohan Hedberg 						    &hdev->dev_flags);
2828bc6d2d04SJohan Hedberg 	}
2829bc6d2d04SJohan Hedberg 
2830123abc08SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2831123abc08SJohan Hedberg 		return;
2832123abc08SJohan Hedberg 
2833bc6d2d04SJohan Hedberg 	if (conn_changed || discov_changed) {
2834bc6d2d04SJohan Hedberg 		/* In case this was disabled through mgmt */
2835bc6d2d04SJohan Hedberg 		set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
2836bc6d2d04SJohan Hedberg 
2837bc6d2d04SJohan Hedberg 		if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags))
2838bc6d2d04SJohan Hedberg 			mgmt_update_adv_data(hdev);
2839bc6d2d04SJohan Hedberg 
2840123abc08SJohan Hedberg 		mgmt_new_settings(hdev);
2841123abc08SJohan Hedberg 	}
2842bc6d2d04SJohan Hedberg }
2843123abc08SJohan Hedberg 
28441da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
28451da177e4SLinus Torvalds {
28461da177e4SLinus Torvalds 	struct hci_dev *hdev;
28471da177e4SLinus Torvalds 	struct hci_dev_req dr;
28481da177e4SLinus Torvalds 	int err = 0;
28491da177e4SLinus Torvalds 
28501da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
28511da177e4SLinus Torvalds 		return -EFAULT;
28521da177e4SLinus Torvalds 
285370f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
285470f23020SAndrei Emeltchenko 	if (!hdev)
28551da177e4SLinus Torvalds 		return -ENODEV;
28561da177e4SLinus Torvalds 
28570736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
28580736cfa8SMarcel Holtmann 		err = -EBUSY;
28590736cfa8SMarcel Holtmann 		goto done;
28600736cfa8SMarcel Holtmann 	}
28610736cfa8SMarcel Holtmann 
28624a964404SMarcel Holtmann 	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
2863fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
2864fee746b0SMarcel Holtmann 		goto done;
2865fee746b0SMarcel Holtmann 	}
2866fee746b0SMarcel Holtmann 
28675b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
28685b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
28695b69bef5SMarcel Holtmann 		goto done;
28705b69bef5SMarcel Holtmann 	}
28715b69bef5SMarcel Holtmann 
287256f87901SJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
287356f87901SJohan Hedberg 		err = -EOPNOTSUPP;
287456f87901SJohan Hedberg 		goto done;
287556f87901SJohan Hedberg 	}
287656f87901SJohan Hedberg 
28771da177e4SLinus Torvalds 	switch (cmd) {
28781da177e4SLinus Torvalds 	case HCISETAUTH:
287901178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
28805f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
28811da177e4SLinus Torvalds 		break;
28821da177e4SLinus Torvalds 
28831da177e4SLinus Torvalds 	case HCISETENCRYPT:
28841da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
28851da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
28861da177e4SLinus Torvalds 			break;
28871da177e4SLinus Torvalds 		}
28881da177e4SLinus Torvalds 
28891da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
28901da177e4SLinus Torvalds 			/* Auth must be enabled first */
289101178cd4SJohan Hedberg 			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
28925f246e89SAndrei Emeltchenko 					   HCI_INIT_TIMEOUT);
28931da177e4SLinus Torvalds 			if (err)
28941da177e4SLinus Torvalds 				break;
28951da177e4SLinus Torvalds 		}
28961da177e4SLinus Torvalds 
289701178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
28985f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
28991da177e4SLinus Torvalds 		break;
29001da177e4SLinus Torvalds 
29011da177e4SLinus Torvalds 	case HCISETSCAN:
290201178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
29035f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
290491a668b0SJohan Hedberg 
2905bc6d2d04SJohan Hedberg 		/* Ensure that the connectable and discoverable states
2906bc6d2d04SJohan Hedberg 		 * get correctly modified as this was a non-mgmt change.
290791a668b0SJohan Hedberg 		 */
2908123abc08SJohan Hedberg 		if (!err)
2909123abc08SJohan Hedberg 			hci_update_scan_state(hdev, dr.dev_opt);
29101da177e4SLinus Torvalds 		break;
29111da177e4SLinus Torvalds 
29121da177e4SLinus Torvalds 	case HCISETLINKPOL:
291301178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
29145f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
29151da177e4SLinus Torvalds 		break;
29161da177e4SLinus Torvalds 
29171da177e4SLinus Torvalds 	case HCISETLINKMODE:
2918e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
2919e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
2920e4e8e37cSMarcel Holtmann 		break;
2921e4e8e37cSMarcel Holtmann 
2922e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
2923e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
29241da177e4SLinus Torvalds 		break;
29251da177e4SLinus Torvalds 
29261da177e4SLinus Torvalds 	case HCISETACLMTU:
29271da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
29281da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
29291da177e4SLinus Torvalds 		break;
29301da177e4SLinus Torvalds 
29311da177e4SLinus Torvalds 	case HCISETSCOMTU:
29321da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
29331da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
29341da177e4SLinus Torvalds 		break;
29351da177e4SLinus Torvalds 
29361da177e4SLinus Torvalds 	default:
29371da177e4SLinus Torvalds 		err = -EINVAL;
29381da177e4SLinus Torvalds 		break;
29391da177e4SLinus Torvalds 	}
2940e4e8e37cSMarcel Holtmann 
29410736cfa8SMarcel Holtmann done:
29421da177e4SLinus Torvalds 	hci_dev_put(hdev);
29431da177e4SLinus Torvalds 	return err;
29441da177e4SLinus Torvalds }
29451da177e4SLinus Torvalds 
29461da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
29471da177e4SLinus Torvalds {
29488035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
29491da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
29501da177e4SLinus Torvalds 	struct hci_dev_req *dr;
29511da177e4SLinus Torvalds 	int n = 0, size, err;
29521da177e4SLinus Torvalds 	__u16 dev_num;
29531da177e4SLinus Torvalds 
29541da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
29551da177e4SLinus Torvalds 		return -EFAULT;
29561da177e4SLinus Torvalds 
29571da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
29581da177e4SLinus Torvalds 		return -EINVAL;
29591da177e4SLinus Torvalds 
29601da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
29611da177e4SLinus Torvalds 
296270f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
296370f23020SAndrei Emeltchenko 	if (!dl)
29641da177e4SLinus Torvalds 		return -ENOMEM;
29651da177e4SLinus Torvalds 
29661da177e4SLinus Torvalds 	dr = dl->dev_req;
29671da177e4SLinus Torvalds 
2968f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
29698035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
29702e84d8dbSMarcel Holtmann 		unsigned long flags = hdev->flags;
2971c542a06cSJohan Hedberg 
29722e84d8dbSMarcel Holtmann 		/* When the auto-off is configured it means the transport
29732e84d8dbSMarcel Holtmann 		 * is running, but in that case still indicate that the
29742e84d8dbSMarcel Holtmann 		 * device is actually down.
29752e84d8dbSMarcel Holtmann 		 */
29762e84d8dbSMarcel Holtmann 		if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
29772e84d8dbSMarcel Holtmann 			flags &= ~BIT(HCI_UP);
2978c542a06cSJohan Hedberg 
29791da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
29802e84d8dbSMarcel Holtmann 		(dr + n)->dev_opt = flags;
2981c542a06cSJohan Hedberg 
29821da177e4SLinus Torvalds 		if (++n >= dev_num)
29831da177e4SLinus Torvalds 			break;
29841da177e4SLinus Torvalds 	}
2985f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
29861da177e4SLinus Torvalds 
29871da177e4SLinus Torvalds 	dl->dev_num = n;
29881da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
29891da177e4SLinus Torvalds 
29901da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
29911da177e4SLinus Torvalds 	kfree(dl);
29921da177e4SLinus Torvalds 
29931da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
29941da177e4SLinus Torvalds }
29951da177e4SLinus Torvalds 
29961da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
29971da177e4SLinus Torvalds {
29981da177e4SLinus Torvalds 	struct hci_dev *hdev;
29991da177e4SLinus Torvalds 	struct hci_dev_info di;
30002e84d8dbSMarcel Holtmann 	unsigned long flags;
30011da177e4SLinus Torvalds 	int err = 0;
30021da177e4SLinus Torvalds 
30031da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
30041da177e4SLinus Torvalds 		return -EFAULT;
30051da177e4SLinus Torvalds 
300670f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
300770f23020SAndrei Emeltchenko 	if (!hdev)
30081da177e4SLinus Torvalds 		return -ENODEV;
30091da177e4SLinus Torvalds 
30102e84d8dbSMarcel Holtmann 	/* When the auto-off is configured it means the transport
30112e84d8dbSMarcel Holtmann 	 * is running, but in that case still indicate that the
30122e84d8dbSMarcel Holtmann 	 * device is actually down.
30132e84d8dbSMarcel Holtmann 	 */
30142e84d8dbSMarcel Holtmann 	if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
30152e84d8dbSMarcel Holtmann 		flags = hdev->flags & ~BIT(HCI_UP);
30162e84d8dbSMarcel Holtmann 	else
30172e84d8dbSMarcel Holtmann 		flags = hdev->flags;
3018c542a06cSJohan Hedberg 
30191da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
30201da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
302160f2a3edSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4);
30222e84d8dbSMarcel Holtmann 	di.flags    = flags;
30231da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
3024572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
30251da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
30261da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
30271da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
30281da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
3029572c7f84SJohan Hedberg 	} else {
3030572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
3031572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
3032572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
3033572c7f84SJohan Hedberg 		di.sco_pkts = 0;
3034572c7f84SJohan Hedberg 	}
30351da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
30361da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
30371da177e4SLinus Torvalds 
30381da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
30391da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
30401da177e4SLinus Torvalds 
30411da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
30421da177e4SLinus Torvalds 		err = -EFAULT;
30431da177e4SLinus Torvalds 
30441da177e4SLinus Torvalds 	hci_dev_put(hdev);
30451da177e4SLinus Torvalds 
30461da177e4SLinus Torvalds 	return err;
30471da177e4SLinus Torvalds }
30481da177e4SLinus Torvalds 
30491da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
30501da177e4SLinus Torvalds 
3051611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
3052611b30f7SMarcel Holtmann {
3053611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
3054611b30f7SMarcel Holtmann 
3055611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
3056611b30f7SMarcel Holtmann 
30570736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
30580736cfa8SMarcel Holtmann 		return -EBUSY;
30590736cfa8SMarcel Holtmann 
30605e130367SJohan Hedberg 	if (blocked) {
30615e130367SJohan Hedberg 		set_bit(HCI_RFKILLED, &hdev->dev_flags);
3062d603b76bSMarcel Holtmann 		if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
3063d603b76bSMarcel Holtmann 		    !test_bit(HCI_CONFIG, &hdev->dev_flags))
3064611b30f7SMarcel Holtmann 			hci_dev_do_close(hdev);
30655e130367SJohan Hedberg 	} else {
30665e130367SJohan Hedberg 		clear_bit(HCI_RFKILLED, &hdev->dev_flags);
30675e130367SJohan Hedberg 	}
3068611b30f7SMarcel Holtmann 
3069611b30f7SMarcel Holtmann 	return 0;
3070611b30f7SMarcel Holtmann }
3071611b30f7SMarcel Holtmann 
3072611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
3073611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
3074611b30f7SMarcel Holtmann };
3075611b30f7SMarcel Holtmann 
3076ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
3077ab81cbf9SJohan Hedberg {
3078ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
307996570ffcSJohan Hedberg 	int err;
3080ab81cbf9SJohan Hedberg 
3081ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
3082ab81cbf9SJohan Hedberg 
3083cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
308496570ffcSJohan Hedberg 	if (err < 0) {
30853ad67582SJaganath Kanakkassery 		hci_dev_lock(hdev);
308696570ffcSJohan Hedberg 		mgmt_set_powered_failed(hdev, err);
30873ad67582SJaganath Kanakkassery 		hci_dev_unlock(hdev);
3088ab81cbf9SJohan Hedberg 		return;
308996570ffcSJohan Hedberg 	}
3090ab81cbf9SJohan Hedberg 
3091a5c8f270SMarcel Holtmann 	/* During the HCI setup phase, a few error conditions are
3092a5c8f270SMarcel Holtmann 	 * ignored and they need to be checked now. If they are still
3093a5c8f270SMarcel Holtmann 	 * valid, it is important to turn the device back off.
3094a5c8f270SMarcel Holtmann 	 */
3095a5c8f270SMarcel Holtmann 	if (test_bit(HCI_RFKILLED, &hdev->dev_flags) ||
30964a964404SMarcel Holtmann 	    test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) ||
3097a5c8f270SMarcel Holtmann 	    (hdev->dev_type == HCI_BREDR &&
3098a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
3099a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->static_addr, BDADDR_ANY))) {
3100bf543036SJohan Hedberg 		clear_bit(HCI_AUTO_OFF, &hdev->dev_flags);
3101bf543036SJohan Hedberg 		hci_dev_do_close(hdev);
3102bf543036SJohan Hedberg 	} else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
310319202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
310419202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
3105bf543036SJohan Hedberg 	}
3106ab81cbf9SJohan Hedberg 
3107fee746b0SMarcel Holtmann 	if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) {
31084a964404SMarcel Holtmann 		/* For unconfigured devices, set the HCI_RAW flag
31094a964404SMarcel Holtmann 		 * so that userspace can easily identify them.
31104a964404SMarcel Holtmann 		 */
31114a964404SMarcel Holtmann 		if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
31124a964404SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
31130602a8adSMarcel Holtmann 
31140602a8adSMarcel Holtmann 		/* For fully configured devices, this will send
31150602a8adSMarcel Holtmann 		 * the Index Added event. For unconfigured devices,
31160602a8adSMarcel Holtmann 		 * it will send Unconfigued Index Added event.
31170602a8adSMarcel Holtmann 		 *
31180602a8adSMarcel Holtmann 		 * Devices with HCI_QUIRK_RAW_DEVICE are ignored
31190602a8adSMarcel Holtmann 		 * and no event will be send.
31200602a8adSMarcel Holtmann 		 */
3121744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
3122d603b76bSMarcel Holtmann 	} else if (test_and_clear_bit(HCI_CONFIG, &hdev->dev_flags)) {
31235ea234d3SMarcel Holtmann 		/* When the controller is now configured, then it
31245ea234d3SMarcel Holtmann 		 * is important to clear the HCI_RAW flag.
31255ea234d3SMarcel Holtmann 		 */
31265ea234d3SMarcel Holtmann 		if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
31275ea234d3SMarcel Holtmann 			clear_bit(HCI_RAW, &hdev->flags);
31285ea234d3SMarcel Holtmann 
3129d603b76bSMarcel Holtmann 		/* Powering on the controller with HCI_CONFIG set only
3130d603b76bSMarcel Holtmann 		 * happens with the transition from unconfigured to
3131d603b76bSMarcel Holtmann 		 * configured. This will send the Index Added event.
3132d603b76bSMarcel Holtmann 		 */
3133d603b76bSMarcel Holtmann 		mgmt_index_added(hdev);
3134ab81cbf9SJohan Hedberg 	}
3135ab81cbf9SJohan Hedberg }
3136ab81cbf9SJohan Hedberg 
3137ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
3138ab81cbf9SJohan Hedberg {
31393243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
31403243553fSJohan Hedberg 					    power_off.work);
3141ab81cbf9SJohan Hedberg 
3142ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
3143ab81cbf9SJohan Hedberg 
31448ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
3145ab81cbf9SJohan Hedberg }
3146ab81cbf9SJohan Hedberg 
314716ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
314816ab91abSJohan Hedberg {
314916ab91abSJohan Hedberg 	struct hci_dev *hdev;
315016ab91abSJohan Hedberg 
315116ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
315216ab91abSJohan Hedberg 
315316ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
315416ab91abSJohan Hedberg 
3155d1967ff8SMarcel Holtmann 	mgmt_discoverable_timeout(hdev);
315616ab91abSJohan Hedberg }
315716ab91abSJohan Hedberg 
315835f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev)
31592aeb9a1aSJohan Hedberg {
31604821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
31612aeb9a1aSJohan Hedberg 
31624821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
31634821002cSJohan Hedberg 		list_del(&uuid->list);
31642aeb9a1aSJohan Hedberg 		kfree(uuid);
31652aeb9a1aSJohan Hedberg 	}
31662aeb9a1aSJohan Hedberg }
31672aeb9a1aSJohan Hedberg 
316835f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev)
316955ed8ca1SJohan Hedberg {
317055ed8ca1SJohan Hedberg 	struct link_key *key;
317155ed8ca1SJohan Hedberg 
31720378b597SJohan Hedberg 	list_for_each_entry_rcu(key, &hdev->link_keys, list) {
31730378b597SJohan Hedberg 		list_del_rcu(&key->list);
31740378b597SJohan Hedberg 		kfree_rcu(key, rcu);
317555ed8ca1SJohan Hedberg 	}
317655ed8ca1SJohan Hedberg }
317755ed8ca1SJohan Hedberg 
317835f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev)
3179b899efafSVinicius Costa Gomes {
3180970d0f1bSJohan Hedberg 	struct smp_ltk *k;
3181b899efafSVinicius Costa Gomes 
3182970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
3183970d0f1bSJohan Hedberg 		list_del_rcu(&k->list);
3184970d0f1bSJohan Hedberg 		kfree_rcu(k, rcu);
3185b899efafSVinicius Costa Gomes 	}
3186b899efafSVinicius Costa Gomes }
3187b899efafSVinicius Costa Gomes 
3188970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev)
3189970c4e46SJohan Hedberg {
3190adae20cbSJohan Hedberg 	struct smp_irk *k;
3191970c4e46SJohan Hedberg 
3192adae20cbSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) {
3193adae20cbSJohan Hedberg 		list_del_rcu(&k->list);
3194adae20cbSJohan Hedberg 		kfree_rcu(k, rcu);
3195970c4e46SJohan Hedberg 	}
3196970c4e46SJohan Hedberg }
3197970c4e46SJohan Hedberg 
319855ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
319955ed8ca1SJohan Hedberg {
320055ed8ca1SJohan Hedberg 	struct link_key *k;
320155ed8ca1SJohan Hedberg 
32020378b597SJohan Hedberg 	rcu_read_lock();
32030378b597SJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->link_keys, list) {
32040378b597SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0) {
32050378b597SJohan Hedberg 			rcu_read_unlock();
320655ed8ca1SJohan Hedberg 			return k;
32070378b597SJohan Hedberg 		}
32080378b597SJohan Hedberg 	}
32090378b597SJohan Hedberg 	rcu_read_unlock();
321055ed8ca1SJohan Hedberg 
321155ed8ca1SJohan Hedberg 	return NULL;
321255ed8ca1SJohan Hedberg }
321355ed8ca1SJohan Hedberg 
3214745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
3215d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
3216d25e28abSJohan Hedberg {
3217d25e28abSJohan Hedberg 	/* Legacy key */
3218d25e28abSJohan Hedberg 	if (key_type < 0x03)
3219745c0ce3SVishal Agarwal 		return true;
3220d25e28abSJohan Hedberg 
3221d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
3222d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
3223745c0ce3SVishal Agarwal 		return false;
3224d25e28abSJohan Hedberg 
3225d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
3226d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
3227745c0ce3SVishal Agarwal 		return false;
3228d25e28abSJohan Hedberg 
3229d25e28abSJohan Hedberg 	/* Security mode 3 case */
3230d25e28abSJohan Hedberg 	if (!conn)
3231745c0ce3SVishal Agarwal 		return true;
3232d25e28abSJohan Hedberg 
3233e3befab9SJohan Hedberg 	/* BR/EDR key derived using SC from an LE link */
3234e3befab9SJohan Hedberg 	if (conn->type == LE_LINK)
3235e3befab9SJohan Hedberg 		return true;
3236e3befab9SJohan Hedberg 
3237d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
3238d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
3239745c0ce3SVishal Agarwal 		return true;
3240d25e28abSJohan Hedberg 
3241d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
3242d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
3243745c0ce3SVishal Agarwal 		return true;
3244d25e28abSJohan Hedberg 
3245d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
3246d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
3247745c0ce3SVishal Agarwal 		return true;
3248d25e28abSJohan Hedberg 
3249d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
3250d25e28abSJohan Hedberg 	 * persistently */
3251745c0ce3SVishal Agarwal 	return false;
3252d25e28abSJohan Hedberg }
3253d25e28abSJohan Hedberg 
3254e804d25dSJohan Hedberg static u8 ltk_role(u8 type)
325598a0b845SJohan Hedberg {
3256e804d25dSJohan Hedberg 	if (type == SMP_LTK)
3257e804d25dSJohan Hedberg 		return HCI_ROLE_MASTER;
325898a0b845SJohan Hedberg 
3259e804d25dSJohan Hedberg 	return HCI_ROLE_SLAVE;
326098a0b845SJohan Hedberg }
326198a0b845SJohan Hedberg 
3262f3a73d97SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
3263e804d25dSJohan Hedberg 			     u8 addr_type, u8 role)
326475d262c2SVinicius Costa Gomes {
3265c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
326675d262c2SVinicius Costa Gomes 
3267970d0f1bSJohan Hedberg 	rcu_read_lock();
3268970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
32695378bc56SJohan Hedberg 		if (addr_type != k->bdaddr_type || bacmp(bdaddr, &k->bdaddr))
32705378bc56SJohan Hedberg 			continue;
32715378bc56SJohan Hedberg 
3272923e2414SJohan Hedberg 		if (smp_ltk_is_sc(k) || ltk_role(k->type) == role) {
3273970d0f1bSJohan Hedberg 			rcu_read_unlock();
327475d262c2SVinicius Costa Gomes 			return k;
3275970d0f1bSJohan Hedberg 		}
3276970d0f1bSJohan Hedberg 	}
3277970d0f1bSJohan Hedberg 	rcu_read_unlock();
327875d262c2SVinicius Costa Gomes 
327975d262c2SVinicius Costa Gomes 	return NULL;
328075d262c2SVinicius Costa Gomes }
328175d262c2SVinicius Costa Gomes 
3282970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa)
3283970c4e46SJohan Hedberg {
3284970c4e46SJohan Hedberg 	struct smp_irk *irk;
3285970c4e46SJohan Hedberg 
3286adae20cbSJohan Hedberg 	rcu_read_lock();
3287adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
3288adae20cbSJohan Hedberg 		if (!bacmp(&irk->rpa, rpa)) {
3289adae20cbSJohan Hedberg 			rcu_read_unlock();
3290970c4e46SJohan Hedberg 			return irk;
3291970c4e46SJohan Hedberg 		}
3292adae20cbSJohan Hedberg 	}
3293970c4e46SJohan Hedberg 
3294adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
3295defce9e8SJohan Hedberg 		if (smp_irk_matches(hdev, irk->val, rpa)) {
3296970c4e46SJohan Hedberg 			bacpy(&irk->rpa, rpa);
3297adae20cbSJohan Hedberg 			rcu_read_unlock();
3298970c4e46SJohan Hedberg 			return irk;
3299970c4e46SJohan Hedberg 		}
3300970c4e46SJohan Hedberg 	}
3301adae20cbSJohan Hedberg 	rcu_read_unlock();
3302970c4e46SJohan Hedberg 
3303970c4e46SJohan Hedberg 	return NULL;
3304970c4e46SJohan Hedberg }
3305970c4e46SJohan Hedberg 
3306970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
3307970c4e46SJohan Hedberg 				     u8 addr_type)
3308970c4e46SJohan Hedberg {
3309970c4e46SJohan Hedberg 	struct smp_irk *irk;
3310970c4e46SJohan Hedberg 
33116cfc9988SJohan Hedberg 	/* Identity Address must be public or static random */
33126cfc9988SJohan Hedberg 	if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0)
33136cfc9988SJohan Hedberg 		return NULL;
33146cfc9988SJohan Hedberg 
3315adae20cbSJohan Hedberg 	rcu_read_lock();
3316adae20cbSJohan Hedberg 	list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
3317970c4e46SJohan Hedberg 		if (addr_type == irk->addr_type &&
3318adae20cbSJohan Hedberg 		    bacmp(bdaddr, &irk->bdaddr) == 0) {
3319adae20cbSJohan Hedberg 			rcu_read_unlock();
3320970c4e46SJohan Hedberg 			return irk;
3321970c4e46SJohan Hedberg 		}
3322adae20cbSJohan Hedberg 	}
3323adae20cbSJohan Hedberg 	rcu_read_unlock();
3324970c4e46SJohan Hedberg 
3325970c4e46SJohan Hedberg 	return NULL;
3326970c4e46SJohan Hedberg }
3327970c4e46SJohan Hedberg 
3328567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn,
33297652ff6aSJohan Hedberg 				  bdaddr_t *bdaddr, u8 *val, u8 type,
33307652ff6aSJohan Hedberg 				  u8 pin_len, bool *persistent)
333155ed8ca1SJohan Hedberg {
333255ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
3333745c0ce3SVishal Agarwal 	u8 old_key_type;
333455ed8ca1SJohan Hedberg 
333555ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
333655ed8ca1SJohan Hedberg 	if (old_key) {
333755ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
333855ed8ca1SJohan Hedberg 		key = old_key;
333955ed8ca1SJohan Hedberg 	} else {
334012adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
33410a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
334255ed8ca1SJohan Hedberg 		if (!key)
3343567fa2aaSJohan Hedberg 			return NULL;
33440378b597SJohan Hedberg 		list_add_rcu(&key->list, &hdev->link_keys);
334555ed8ca1SJohan Hedberg 	}
334655ed8ca1SJohan Hedberg 
33476ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
334855ed8ca1SJohan Hedberg 
3349d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
3350d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
3351d25e28abSJohan Hedberg 	 * previous key */
3352d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
3353a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
3354d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
3355655fe6ecSJohan Hedberg 		if (conn)
3356655fe6ecSJohan Hedberg 			conn->key_type = type;
3357655fe6ecSJohan Hedberg 	}
3358d25e28abSJohan Hedberg 
335955ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
33609b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
336155ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
336255ed8ca1SJohan Hedberg 
3363b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
336455ed8ca1SJohan Hedberg 		key->type = old_key_type;
33654748fed2SJohan Hedberg 	else
33664748fed2SJohan Hedberg 		key->type = type;
33674748fed2SJohan Hedberg 
33687652ff6aSJohan Hedberg 	if (persistent)
33697652ff6aSJohan Hedberg 		*persistent = hci_persistent_key(hdev, conn, type,
33707652ff6aSJohan Hedberg 						 old_key_type);
33714df378a1SJohan Hedberg 
3372567fa2aaSJohan Hedberg 	return key;
337355ed8ca1SJohan Hedberg }
337455ed8ca1SJohan Hedberg 
3375ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
337635d70271SJohan Hedberg 			    u8 addr_type, u8 type, u8 authenticated,
3377fe39c7b2SMarcel Holtmann 			    u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand)
337875d262c2SVinicius Costa Gomes {
3379c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
3380e804d25dSJohan Hedberg 	u8 role = ltk_role(type);
338175d262c2SVinicius Costa Gomes 
3382f3a73d97SJohan Hedberg 	old_key = hci_find_ltk(hdev, bdaddr, addr_type, role);
3383c9839a11SVinicius Costa Gomes 	if (old_key)
338475d262c2SVinicius Costa Gomes 		key = old_key;
3385c9839a11SVinicius Costa Gomes 	else {
33860a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
338775d262c2SVinicius Costa Gomes 		if (!key)
3388ca9142b8SJohan Hedberg 			return NULL;
3389970d0f1bSJohan Hedberg 		list_add_rcu(&key->list, &hdev->long_term_keys);
339075d262c2SVinicius Costa Gomes 	}
339175d262c2SVinicius Costa Gomes 
339275d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
3393c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
3394c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
3395c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
3396c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
3397fe39c7b2SMarcel Holtmann 	key->rand = rand;
3398c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
3399c9839a11SVinicius Costa Gomes 	key->type = type;
340075d262c2SVinicius Costa Gomes 
3401ca9142b8SJohan Hedberg 	return key;
340275d262c2SVinicius Costa Gomes }
340375d262c2SVinicius Costa Gomes 
3404ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr,
3405ca9142b8SJohan Hedberg 			    u8 addr_type, u8 val[16], bdaddr_t *rpa)
3406970c4e46SJohan Hedberg {
3407970c4e46SJohan Hedberg 	struct smp_irk *irk;
3408970c4e46SJohan Hedberg 
3409970c4e46SJohan Hedberg 	irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type);
3410970c4e46SJohan Hedberg 	if (!irk) {
3411970c4e46SJohan Hedberg 		irk = kzalloc(sizeof(*irk), GFP_KERNEL);
3412970c4e46SJohan Hedberg 		if (!irk)
3413ca9142b8SJohan Hedberg 			return NULL;
3414970c4e46SJohan Hedberg 
3415970c4e46SJohan Hedberg 		bacpy(&irk->bdaddr, bdaddr);
3416970c4e46SJohan Hedberg 		irk->addr_type = addr_type;
3417970c4e46SJohan Hedberg 
3418adae20cbSJohan Hedberg 		list_add_rcu(&irk->list, &hdev->identity_resolving_keys);
3419970c4e46SJohan Hedberg 	}
3420970c4e46SJohan Hedberg 
3421970c4e46SJohan Hedberg 	memcpy(irk->val, val, 16);
3422970c4e46SJohan Hedberg 	bacpy(&irk->rpa, rpa);
3423970c4e46SJohan Hedberg 
3424ca9142b8SJohan Hedberg 	return irk;
3425970c4e46SJohan Hedberg }
3426970c4e46SJohan Hedberg 
342755ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
342855ed8ca1SJohan Hedberg {
342955ed8ca1SJohan Hedberg 	struct link_key *key;
343055ed8ca1SJohan Hedberg 
343155ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
343255ed8ca1SJohan Hedberg 	if (!key)
343355ed8ca1SJohan Hedberg 		return -ENOENT;
343455ed8ca1SJohan Hedberg 
34356ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
343655ed8ca1SJohan Hedberg 
34370378b597SJohan Hedberg 	list_del_rcu(&key->list);
34380378b597SJohan Hedberg 	kfree_rcu(key, rcu);
343955ed8ca1SJohan Hedberg 
344055ed8ca1SJohan Hedberg 	return 0;
344155ed8ca1SJohan Hedberg }
344255ed8ca1SJohan Hedberg 
3443e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type)
3444b899efafSVinicius Costa Gomes {
3445970d0f1bSJohan Hedberg 	struct smp_ltk *k;
3446c51ffa0bSJohan Hedberg 	int removed = 0;
3447b899efafSVinicius Costa Gomes 
3448970d0f1bSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
3449e0b2b27eSJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type)
3450b899efafSVinicius Costa Gomes 			continue;
3451b899efafSVinicius Costa Gomes 
34526ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
3453b899efafSVinicius Costa Gomes 
3454970d0f1bSJohan Hedberg 		list_del_rcu(&k->list);
3455970d0f1bSJohan Hedberg 		kfree_rcu(k, rcu);
3456c51ffa0bSJohan Hedberg 		removed++;
3457b899efafSVinicius Costa Gomes 	}
3458b899efafSVinicius Costa Gomes 
3459c51ffa0bSJohan Hedberg 	return removed ? 0 : -ENOENT;
3460b899efafSVinicius Costa Gomes }
3461b899efafSVinicius Costa Gomes 
3462a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type)
3463a7ec7338SJohan Hedberg {
3464adae20cbSJohan Hedberg 	struct smp_irk *k;
3465a7ec7338SJohan Hedberg 
3466adae20cbSJohan Hedberg 	list_for_each_entry_rcu(k, &hdev->identity_resolving_keys, list) {
3467a7ec7338SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type)
3468a7ec7338SJohan Hedberg 			continue;
3469a7ec7338SJohan Hedberg 
3470a7ec7338SJohan Hedberg 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
3471a7ec7338SJohan Hedberg 
3472adae20cbSJohan Hedberg 		list_del_rcu(&k->list);
3473adae20cbSJohan Hedberg 		kfree_rcu(k, rcu);
3474a7ec7338SJohan Hedberg 	}
3475a7ec7338SJohan Hedberg }
3476a7ec7338SJohan Hedberg 
34776bd32326SVille Tervo /* HCI command timer function */
347865cc2b49SMarcel Holtmann static void hci_cmd_timeout(struct work_struct *work)
34796bd32326SVille Tervo {
348065cc2b49SMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev,
348165cc2b49SMarcel Holtmann 					    cmd_timer.work);
34826bd32326SVille Tervo 
3483bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
3484bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
3485bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
3486bda4f23aSAndrei Emeltchenko 
3487bda4f23aSAndrei Emeltchenko 		BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode);
3488bda4f23aSAndrei Emeltchenko 	} else {
34896bd32326SVille Tervo 		BT_ERR("%s command tx timeout", hdev->name);
3490bda4f23aSAndrei Emeltchenko 	}
3491bda4f23aSAndrei Emeltchenko 
34926bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
3493c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
34946bd32326SVille Tervo }
34956bd32326SVille Tervo 
34962763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
34976928a924SJohan Hedberg 					  bdaddr_t *bdaddr, u8 bdaddr_type)
34982763eda6SSzymon Janc {
34992763eda6SSzymon Janc 	struct oob_data *data;
35002763eda6SSzymon Janc 
35016928a924SJohan Hedberg 	list_for_each_entry(data, &hdev->remote_oob_data, list) {
35026928a924SJohan Hedberg 		if (bacmp(bdaddr, &data->bdaddr) != 0)
35036928a924SJohan Hedberg 			continue;
35046928a924SJohan Hedberg 		if (data->bdaddr_type != bdaddr_type)
35056928a924SJohan Hedberg 			continue;
35062763eda6SSzymon Janc 		return data;
35076928a924SJohan Hedberg 	}
35082763eda6SSzymon Janc 
35092763eda6SSzymon Janc 	return NULL;
35102763eda6SSzymon Janc }
35112763eda6SSzymon Janc 
35126928a924SJohan Hedberg int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
35136928a924SJohan Hedberg 			       u8 bdaddr_type)
35142763eda6SSzymon Janc {
35152763eda6SSzymon Janc 	struct oob_data *data;
35162763eda6SSzymon Janc 
35176928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
35182763eda6SSzymon Janc 	if (!data)
35192763eda6SSzymon Janc 		return -ENOENT;
35202763eda6SSzymon Janc 
35216928a924SJohan Hedberg 	BT_DBG("%s removing %pMR (%u)", hdev->name, bdaddr, bdaddr_type);
35222763eda6SSzymon Janc 
35232763eda6SSzymon Janc 	list_del(&data->list);
35242763eda6SSzymon Janc 	kfree(data);
35252763eda6SSzymon Janc 
35262763eda6SSzymon Janc 	return 0;
35272763eda6SSzymon Janc }
35282763eda6SSzymon Janc 
352935f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev)
35302763eda6SSzymon Janc {
35312763eda6SSzymon Janc 	struct oob_data *data, *n;
35322763eda6SSzymon Janc 
35332763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
35342763eda6SSzymon Janc 		list_del(&data->list);
35352763eda6SSzymon Janc 		kfree(data);
35362763eda6SSzymon Janc 	}
35372763eda6SSzymon Janc }
35382763eda6SSzymon Janc 
35390798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
35406928a924SJohan Hedberg 			    u8 bdaddr_type, u8 *hash192, u8 *rand192,
354138da1703SJohan Hedberg 			    u8 *hash256, u8 *rand256)
35420798872eSMarcel Holtmann {
35430798872eSMarcel Holtmann 	struct oob_data *data;
35440798872eSMarcel Holtmann 
35456928a924SJohan Hedberg 	data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type);
35460798872eSMarcel Holtmann 	if (!data) {
35470a14ab41SJohan Hedberg 		data = kmalloc(sizeof(*data), GFP_KERNEL);
35480798872eSMarcel Holtmann 		if (!data)
35490798872eSMarcel Holtmann 			return -ENOMEM;
35500798872eSMarcel Holtmann 
35510798872eSMarcel Holtmann 		bacpy(&data->bdaddr, bdaddr);
35526928a924SJohan Hedberg 		data->bdaddr_type = bdaddr_type;
35530798872eSMarcel Holtmann 		list_add(&data->list, &hdev->remote_oob_data);
35540798872eSMarcel Holtmann 	}
35550798872eSMarcel Holtmann 
355681328d5cSJohan Hedberg 	if (hash192 && rand192) {
35570798872eSMarcel Holtmann 		memcpy(data->hash192, hash192, sizeof(data->hash192));
355838da1703SJohan Hedberg 		memcpy(data->rand192, rand192, sizeof(data->rand192));
355981328d5cSJohan Hedberg 	} else {
356081328d5cSJohan Hedberg 		memset(data->hash192, 0, sizeof(data->hash192));
356181328d5cSJohan Hedberg 		memset(data->rand192, 0, sizeof(data->rand192));
356281328d5cSJohan Hedberg 	}
35630798872eSMarcel Holtmann 
356481328d5cSJohan Hedberg 	if (hash256 && rand256) {
35650798872eSMarcel Holtmann 		memcpy(data->hash256, hash256, sizeof(data->hash256));
356638da1703SJohan Hedberg 		memcpy(data->rand256, rand256, sizeof(data->rand256));
356781328d5cSJohan Hedberg 	} else {
356881328d5cSJohan Hedberg 		memset(data->hash256, 0, sizeof(data->hash256));
356981328d5cSJohan Hedberg 		memset(data->rand256, 0, sizeof(data->rand256));
357081328d5cSJohan Hedberg 	}
35710798872eSMarcel Holtmann 
35726ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
35732763eda6SSzymon Janc 
35742763eda6SSzymon Janc 	return 0;
35752763eda6SSzymon Janc }
35762763eda6SSzymon Janc 
3577dcc36c16SJohan Hedberg struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
3578b9ee0a78SMarcel Holtmann 					 bdaddr_t *bdaddr, u8 type)
3579b2a66aadSAntti Julku {
3580b2a66aadSAntti Julku 	struct bdaddr_list *b;
3581b2a66aadSAntti Julku 
3582dcc36c16SJohan Hedberg 	list_for_each_entry(b, bdaddr_list, list) {
3583b9ee0a78SMarcel Holtmann 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
3584b2a66aadSAntti Julku 			return b;
3585b9ee0a78SMarcel Holtmann 	}
3586b2a66aadSAntti Julku 
3587b2a66aadSAntti Julku 	return NULL;
3588b2a66aadSAntti Julku }
3589b2a66aadSAntti Julku 
3590dcc36c16SJohan Hedberg void hci_bdaddr_list_clear(struct list_head *bdaddr_list)
3591b2a66aadSAntti Julku {
3592b2a66aadSAntti Julku 	struct list_head *p, *n;
3593b2a66aadSAntti Julku 
3594dcc36c16SJohan Hedberg 	list_for_each_safe(p, n, bdaddr_list) {
3595b9ee0a78SMarcel Holtmann 		struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list);
3596b2a66aadSAntti Julku 
3597b2a66aadSAntti Julku 		list_del(p);
3598b2a66aadSAntti Julku 		kfree(b);
3599b2a66aadSAntti Julku 	}
3600b2a66aadSAntti Julku }
3601b2a66aadSAntti Julku 
3602dcc36c16SJohan Hedberg int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type)
3603b2a66aadSAntti Julku {
3604b2a66aadSAntti Julku 	struct bdaddr_list *entry;
3605b2a66aadSAntti Julku 
3606b9ee0a78SMarcel Holtmann 	if (!bacmp(bdaddr, BDADDR_ANY))
3607b2a66aadSAntti Julku 		return -EBADF;
3608b2a66aadSAntti Julku 
3609dcc36c16SJohan Hedberg 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
36105e762444SAntti Julku 		return -EEXIST;
3611b2a66aadSAntti Julku 
361227f70f3eSJohan Hedberg 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
36135e762444SAntti Julku 	if (!entry)
36145e762444SAntti Julku 		return -ENOMEM;
3615b2a66aadSAntti Julku 
3616b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
3617b9ee0a78SMarcel Holtmann 	entry->bdaddr_type = type;
3618b2a66aadSAntti Julku 
3619dcc36c16SJohan Hedberg 	list_add(&entry->list, list);
3620b2a66aadSAntti Julku 
36212a8357f2SJohan Hedberg 	return 0;
3622b2a66aadSAntti Julku }
3623b2a66aadSAntti Julku 
3624dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type)
3625b2a66aadSAntti Julku {
3626b2a66aadSAntti Julku 	struct bdaddr_list *entry;
3627b2a66aadSAntti Julku 
362835f7498aSJohan Hedberg 	if (!bacmp(bdaddr, BDADDR_ANY)) {
3629dcc36c16SJohan Hedberg 		hci_bdaddr_list_clear(list);
363035f7498aSJohan Hedberg 		return 0;
363135f7498aSJohan Hedberg 	}
3632b2a66aadSAntti Julku 
3633dcc36c16SJohan Hedberg 	entry = hci_bdaddr_list_lookup(list, bdaddr, type);
3634d2ab0ac1SMarcel Holtmann 	if (!entry)
3635d2ab0ac1SMarcel Holtmann 		return -ENOENT;
3636d2ab0ac1SMarcel Holtmann 
3637d2ab0ac1SMarcel Holtmann 	list_del(&entry->list);
3638d2ab0ac1SMarcel Holtmann 	kfree(entry);
3639d2ab0ac1SMarcel Holtmann 
3640d2ab0ac1SMarcel Holtmann 	return 0;
3641d2ab0ac1SMarcel Holtmann }
3642d2ab0ac1SMarcel Holtmann 
364315819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
364415819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
364515819a70SAndre Guedes 					       bdaddr_t *addr, u8 addr_type)
364615819a70SAndre Guedes {
364715819a70SAndre Guedes 	struct hci_conn_params *params;
364815819a70SAndre Guedes 
3649738f6185SJohan Hedberg 	/* The conn params list only contains identity addresses */
3650738f6185SJohan Hedberg 	if (!hci_is_identity_address(addr, addr_type))
3651738f6185SJohan Hedberg 		return NULL;
3652738f6185SJohan Hedberg 
365315819a70SAndre Guedes 	list_for_each_entry(params, &hdev->le_conn_params, list) {
365415819a70SAndre Guedes 		if (bacmp(&params->addr, addr) == 0 &&
365515819a70SAndre Guedes 		    params->addr_type == addr_type) {
365615819a70SAndre Guedes 			return params;
365715819a70SAndre Guedes 		}
365815819a70SAndre Guedes 	}
365915819a70SAndre Guedes 
366015819a70SAndre Guedes 	return NULL;
366115819a70SAndre Guedes }
366215819a70SAndre Guedes 
3663cef952ceSAndre Guedes static bool is_connected(struct hci_dev *hdev, bdaddr_t *addr, u8 type)
3664cef952ceSAndre Guedes {
3665cef952ceSAndre Guedes 	struct hci_conn *conn;
3666cef952ceSAndre Guedes 
3667cef952ceSAndre Guedes 	conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, addr);
3668cef952ceSAndre Guedes 	if (!conn)
3669cef952ceSAndre Guedes 		return false;
3670cef952ceSAndre Guedes 
3671cef952ceSAndre Guedes 	if (conn->dst_type != type)
3672cef952ceSAndre Guedes 		return false;
3673cef952ceSAndre Guedes 
3674cef952ceSAndre Guedes 	if (conn->state != BT_CONNECTED)
3675cef952ceSAndre Guedes 		return false;
3676cef952ceSAndre Guedes 
3677cef952ceSAndre Guedes 	return true;
3678cef952ceSAndre Guedes }
3679cef952ceSAndre Guedes 
368015819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
3681501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list,
36824b10966fSMarcel Holtmann 						  bdaddr_t *addr, u8 addr_type)
368315819a70SAndre Guedes {
3684912b42efSJohan Hedberg 	struct hci_conn_params *param;
368515819a70SAndre Guedes 
3686738f6185SJohan Hedberg 	/* The list only contains identity addresses */
3687738f6185SJohan Hedberg 	if (!hci_is_identity_address(addr, addr_type))
3688738f6185SJohan Hedberg 		return NULL;
368915819a70SAndre Guedes 
3690501f8827SJohan Hedberg 	list_for_each_entry(param, list, action) {
3691912b42efSJohan Hedberg 		if (bacmp(&param->addr, addr) == 0 &&
3692912b42efSJohan Hedberg 		    param->addr_type == addr_type)
3693912b42efSJohan Hedberg 			return param;
36944b10966fSMarcel Holtmann 	}
36954b10966fSMarcel Holtmann 
36964b10966fSMarcel Holtmann 	return NULL;
369715819a70SAndre Guedes }
369815819a70SAndre Guedes 
369915819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
370051d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev,
370151d167c0SMarcel Holtmann 					    bdaddr_t *addr, u8 addr_type)
370215819a70SAndre Guedes {
370315819a70SAndre Guedes 	struct hci_conn_params *params;
370415819a70SAndre Guedes 
3705c46245b3SJohan Hedberg 	if (!hci_is_identity_address(addr, addr_type))
370651d167c0SMarcel Holtmann 		return NULL;
3707a9b0a04cSAndre Guedes 
370815819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
3709cef952ceSAndre Guedes 	if (params)
371051d167c0SMarcel Holtmann 		return params;
371115819a70SAndre Guedes 
371215819a70SAndre Guedes 	params = kzalloc(sizeof(*params), GFP_KERNEL);
371315819a70SAndre Guedes 	if (!params) {
371415819a70SAndre Guedes 		BT_ERR("Out of memory");
371551d167c0SMarcel Holtmann 		return NULL;
371615819a70SAndre Guedes 	}
371715819a70SAndre Guedes 
371815819a70SAndre Guedes 	bacpy(&params->addr, addr);
371915819a70SAndre Guedes 	params->addr_type = addr_type;
3720cef952ceSAndre Guedes 
3721cef952ceSAndre Guedes 	list_add(&params->list, &hdev->le_conn_params);
372293450c75SJohan Hedberg 	INIT_LIST_HEAD(&params->action);
3723cef952ceSAndre Guedes 
3724bf5b3c8bSMarcel Holtmann 	params->conn_min_interval = hdev->le_conn_min_interval;
3725bf5b3c8bSMarcel Holtmann 	params->conn_max_interval = hdev->le_conn_max_interval;
3726bf5b3c8bSMarcel Holtmann 	params->conn_latency = hdev->le_conn_latency;
3727bf5b3c8bSMarcel Holtmann 	params->supervision_timeout = hdev->le_supv_timeout;
3728bf5b3c8bSMarcel Holtmann 	params->auto_connect = HCI_AUTO_CONN_DISABLED;
3729bf5b3c8bSMarcel Holtmann 
3730bf5b3c8bSMarcel Holtmann 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
3731bf5b3c8bSMarcel Holtmann 
373251d167c0SMarcel Holtmann 	return params;
3733bf5b3c8bSMarcel Holtmann }
3734bf5b3c8bSMarcel Holtmann 
3735bf5b3c8bSMarcel Holtmann /* This function requires the caller holds hdev->lock */
3736bf5b3c8bSMarcel Holtmann int hci_conn_params_set(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
3737d06b50ceSMarcel Holtmann 			u8 auto_connect)
373815819a70SAndre Guedes {
373915819a70SAndre Guedes 	struct hci_conn_params *params;
374015819a70SAndre Guedes 
37418c87aae1SMarcel Holtmann 	params = hci_conn_params_add(hdev, addr, addr_type);
37428c87aae1SMarcel Holtmann 	if (!params)
37438c87aae1SMarcel Holtmann 		return -EIO;
374415819a70SAndre Guedes 
374542ce26deSJohan Hedberg 	if (params->auto_connect == auto_connect)
374642ce26deSJohan Hedberg 		return 0;
374742ce26deSJohan Hedberg 
374866f8455aSJohan Hedberg 	list_del_init(&params->action);
374915819a70SAndre Guedes 
3750cef952ceSAndre Guedes 	switch (auto_connect) {
3751cef952ceSAndre Guedes 	case HCI_AUTO_CONN_DISABLED:
3752cef952ceSAndre Guedes 	case HCI_AUTO_CONN_LINK_LOSS:
375395305baaSJohan Hedberg 		hci_update_background_scan(hdev);
3754cef952ceSAndre Guedes 		break;
3755851efca8SJohan Hedberg 	case HCI_AUTO_CONN_REPORT:
375695305baaSJohan Hedberg 		list_add(&params->action, &hdev->pend_le_reports);
375795305baaSJohan Hedberg 		hci_update_background_scan(hdev);
3758851efca8SJohan Hedberg 		break;
37594b9e7e75SMarcel Holtmann 	case HCI_AUTO_CONN_DIRECT:
3760cef952ceSAndre Guedes 	case HCI_AUTO_CONN_ALWAYS:
376195305baaSJohan Hedberg 		if (!is_connected(hdev, addr, addr_type)) {
376295305baaSJohan Hedberg 			list_add(&params->action, &hdev->pend_le_conns);
376395305baaSJohan Hedberg 			hci_update_background_scan(hdev);
376495305baaSJohan Hedberg 		}
3765cef952ceSAndre Guedes 		break;
3766cef952ceSAndre Guedes 	}
376715819a70SAndre Guedes 
3768851efca8SJohan Hedberg 	params->auto_connect = auto_connect;
3769851efca8SJohan Hedberg 
3770d06b50ceSMarcel Holtmann 	BT_DBG("addr %pMR (type %u) auto_connect %u", addr, addr_type,
3771d06b50ceSMarcel Holtmann 	       auto_connect);
3772a9b0a04cSAndre Guedes 
3773a9b0a04cSAndre Guedes 	return 0;
377415819a70SAndre Guedes }
377515819a70SAndre Guedes 
3776f6c63249SJohan Hedberg static void hci_conn_params_free(struct hci_conn_params *params)
3777f6c63249SJohan Hedberg {
3778f6c63249SJohan Hedberg 	if (params->conn) {
3779f6c63249SJohan Hedberg 		hci_conn_drop(params->conn);
3780f6c63249SJohan Hedberg 		hci_conn_put(params->conn);
3781f6c63249SJohan Hedberg 	}
3782f6c63249SJohan Hedberg 
3783f6c63249SJohan Hedberg 	list_del(&params->action);
3784f6c63249SJohan Hedberg 	list_del(&params->list);
3785f6c63249SJohan Hedberg 	kfree(params);
3786f6c63249SJohan Hedberg }
3787f6c63249SJohan Hedberg 
378815819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
378915819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
379015819a70SAndre Guedes {
379115819a70SAndre Guedes 	struct hci_conn_params *params;
379215819a70SAndre Guedes 
379315819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
379415819a70SAndre Guedes 	if (!params)
379515819a70SAndre Guedes 		return;
379615819a70SAndre Guedes 
3797f6c63249SJohan Hedberg 	hci_conn_params_free(params);
379815819a70SAndre Guedes 
379995305baaSJohan Hedberg 	hci_update_background_scan(hdev);
380095305baaSJohan Hedberg 
380115819a70SAndre Guedes 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
380215819a70SAndre Guedes }
380315819a70SAndre Guedes 
380415819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
380555af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev)
380615819a70SAndre Guedes {
380715819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
380815819a70SAndre Guedes 
380915819a70SAndre Guedes 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
381055af49a8SJohan Hedberg 		if (params->auto_connect != HCI_AUTO_CONN_DISABLED)
381155af49a8SJohan Hedberg 			continue;
381215819a70SAndre Guedes 		list_del(&params->list);
381315819a70SAndre Guedes 		kfree(params);
381415819a70SAndre Guedes 	}
381515819a70SAndre Guedes 
381655af49a8SJohan Hedberg 	BT_DBG("All LE disabled connection parameters were removed");
381755af49a8SJohan Hedberg }
381855af49a8SJohan Hedberg 
381955af49a8SJohan Hedberg /* This function requires the caller holds hdev->lock */
3820373110c5SJohan Hedberg void hci_conn_params_clear_all(struct hci_dev *hdev)
382115819a70SAndre Guedes {
382215819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
382315819a70SAndre Guedes 
3824f6c63249SJohan Hedberg 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list)
3825f6c63249SJohan Hedberg 		hci_conn_params_free(params);
382615819a70SAndre Guedes 
3827a2f41a8fSJohan Hedberg 	hci_update_background_scan(hdev);
38281089b67dSMarcel Holtmann 
382915819a70SAndre Guedes 	BT_DBG("All LE connection parameters were removed");
383015819a70SAndre Guedes }
383115819a70SAndre Guedes 
38324c87eaabSAndre Guedes static void inquiry_complete(struct hci_dev *hdev, u8 status)
38337ba8b4beSAndre Guedes {
38344c87eaabSAndre Guedes 	if (status) {
38354c87eaabSAndre Guedes 		BT_ERR("Failed to start inquiry: status %d", status);
38367ba8b4beSAndre Guedes 
38374c87eaabSAndre Guedes 		hci_dev_lock(hdev);
38384c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
38394c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
38404c87eaabSAndre Guedes 		return;
38414c87eaabSAndre Guedes 	}
38427ba8b4beSAndre Guedes }
38437ba8b4beSAndre Guedes 
38444c87eaabSAndre Guedes static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status)
38457ba8b4beSAndre Guedes {
38464c87eaabSAndre Guedes 	/* General inquiry access code (GIAC) */
38474c87eaabSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
38484c87eaabSAndre Guedes 	struct hci_request req;
38494c87eaabSAndre Guedes 	struct hci_cp_inquiry cp;
38507ba8b4beSAndre Guedes 	int err;
38517ba8b4beSAndre Guedes 
38524c87eaabSAndre Guedes 	if (status) {
38534c87eaabSAndre Guedes 		BT_ERR("Failed to disable LE scanning: status %d", status);
38544c87eaabSAndre Guedes 		return;
38557ba8b4beSAndre Guedes 	}
38567ba8b4beSAndre Guedes 
38574c87eaabSAndre Guedes 	switch (hdev->discovery.type) {
38584c87eaabSAndre Guedes 	case DISCOV_TYPE_LE:
38594c87eaabSAndre Guedes 		hci_dev_lock(hdev);
38604c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
38614c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
38624c87eaabSAndre Guedes 		break;
38637dbfac1dSAndre Guedes 
38644c87eaabSAndre Guedes 	case DISCOV_TYPE_INTERLEAVED:
38654c87eaabSAndre Guedes 		hci_req_init(&req, hdev);
38667dbfac1dSAndre Guedes 
38677dbfac1dSAndre Guedes 		memset(&cp, 0, sizeof(cp));
38684c87eaabSAndre Guedes 		memcpy(&cp.lap, lap, sizeof(cp.lap));
38694c87eaabSAndre Guedes 		cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN;
38704c87eaabSAndre Guedes 		hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp);
38714c87eaabSAndre Guedes 
38724c87eaabSAndre Guedes 		hci_dev_lock(hdev);
38734c87eaabSAndre Guedes 
38744c87eaabSAndre Guedes 		hci_inquiry_cache_flush(hdev);
38754c87eaabSAndre Guedes 
38764c87eaabSAndre Guedes 		err = hci_req_run(&req, inquiry_complete);
38774c87eaabSAndre Guedes 		if (err) {
38784c87eaabSAndre Guedes 			BT_ERR("Inquiry request failed: err %d", err);
38794c87eaabSAndre Guedes 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
38807dbfac1dSAndre Guedes 		}
38817dbfac1dSAndre Guedes 
38824c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
38834c87eaabSAndre Guedes 		break;
38844c87eaabSAndre Guedes 	}
38857dbfac1dSAndre Guedes }
38867dbfac1dSAndre Guedes 
38877ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work)
38887ba8b4beSAndre Guedes {
38897ba8b4beSAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev,
38907ba8b4beSAndre Guedes 					    le_scan_disable.work);
38914c87eaabSAndre Guedes 	struct hci_request req;
38924c87eaabSAndre Guedes 	int err;
38937ba8b4beSAndre Guedes 
38947ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
38957ba8b4beSAndre Guedes 
38964c87eaabSAndre Guedes 	hci_req_init(&req, hdev);
38977ba8b4beSAndre Guedes 
3898b1efcc28SAndre Guedes 	hci_req_add_le_scan_disable(&req);
38997ba8b4beSAndre Guedes 
39004c87eaabSAndre Guedes 	err = hci_req_run(&req, le_scan_disable_work_complete);
39014c87eaabSAndre Guedes 	if (err)
39024c87eaabSAndre Guedes 		BT_ERR("Disable LE scanning request failed: err %d", err);
390328b75a89SAndre Guedes }
390428b75a89SAndre Guedes 
3905a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller.
3906a1f4c318SJohan Hedberg  *
3907a1f4c318SJohan Hedberg  * If the controller has a public BD_ADDR, then by default use that one.
3908a1f4c318SJohan Hedberg  * If this is a LE only controller without a public address, default to
3909a1f4c318SJohan Hedberg  * the static random address.
3910a1f4c318SJohan Hedberg  *
3911a1f4c318SJohan Hedberg  * For debugging purposes it is possible to force controllers with a
3912a1f4c318SJohan Hedberg  * public address to use the static random address instead.
3913a1f4c318SJohan Hedberg  */
3914a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
3915a1f4c318SJohan Hedberg 			       u8 *bdaddr_type)
3916a1f4c318SJohan Hedberg {
3917111902f7SMarcel Holtmann 	if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) ||
3918a1f4c318SJohan Hedberg 	    !bacmp(&hdev->bdaddr, BDADDR_ANY)) {
3919a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->static_addr);
3920a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_RANDOM;
3921a1f4c318SJohan Hedberg 	} else {
3922a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->bdaddr);
3923a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_PUBLIC;
3924a1f4c318SJohan Hedberg 	}
3925a1f4c318SJohan Hedberg }
3926a1f4c318SJohan Hedberg 
39279be0dab7SDavid Herrmann /* Alloc HCI device */
39289be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void)
39299be0dab7SDavid Herrmann {
39309be0dab7SDavid Herrmann 	struct hci_dev *hdev;
39319be0dab7SDavid Herrmann 
393227f70f3eSJohan Hedberg 	hdev = kzalloc(sizeof(*hdev), GFP_KERNEL);
39339be0dab7SDavid Herrmann 	if (!hdev)
39349be0dab7SDavid Herrmann 		return NULL;
39359be0dab7SDavid Herrmann 
3936b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
3937b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
3938b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
3939b4cb9fb2SMarcel Holtmann 	hdev->num_iac = 0x01;		/* One IAC support is mandatory */
3940b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03;	/* No Input No Output */
394196c2103aSMarcel Holtmann 	hdev->manufacturer = 0xffff;	/* Default to internal use */
3942bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
3943bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
3944b1b813d4SDavid Herrmann 
3945b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
3946b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
3947b1b813d4SDavid Herrmann 
39483f959d46SMarcel Holtmann 	hdev->le_adv_channel_map = 0x07;
3949628531c9SGeorg Lukas 	hdev->le_adv_min_interval = 0x0800;
3950628531c9SGeorg Lukas 	hdev->le_adv_max_interval = 0x0800;
3951bef64738SMarcel Holtmann 	hdev->le_scan_interval = 0x0060;
3952bef64738SMarcel Holtmann 	hdev->le_scan_window = 0x0030;
39534e70c7e7SMarcel Holtmann 	hdev->le_conn_min_interval = 0x0028;
39544e70c7e7SMarcel Holtmann 	hdev->le_conn_max_interval = 0x0038;
395504fb7d90SMarcel Holtmann 	hdev->le_conn_latency = 0x0000;
395604fb7d90SMarcel Holtmann 	hdev->le_supv_timeout = 0x002a;
3957bef64738SMarcel Holtmann 
3958d6bfd59cSJohan Hedberg 	hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT;
3959b9a7a61eSLukasz Rymanowski 	hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT;
396031ad1691SAndrzej Kaczmarek 	hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE;
396131ad1691SAndrzej Kaczmarek 	hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE;
3962d6bfd59cSJohan Hedberg 
3963b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
3964b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
3965b1b813d4SDavid Herrmann 
3966b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
3967b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->blacklist);
39686659358eSJohan Hedberg 	INIT_LIST_HEAD(&hdev->whitelist);
3969b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
3970b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
3971b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
3972970c4e46SJohan Hedberg 	INIT_LIST_HEAD(&hdev->identity_resolving_keys);
3973b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
3974d2ab0ac1SMarcel Holtmann 	INIT_LIST_HEAD(&hdev->le_white_list);
397515819a70SAndre Guedes 	INIT_LIST_HEAD(&hdev->le_conn_params);
397677a77a30SAndre Guedes 	INIT_LIST_HEAD(&hdev->pend_le_conns);
397766f8455aSJohan Hedberg 	INIT_LIST_HEAD(&hdev->pend_le_reports);
39786b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
3979b1b813d4SDavid Herrmann 
3980b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
3981b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
3982b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
3983b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
3984b1b813d4SDavid Herrmann 
3985b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
3986b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
3987b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
3988b1b813d4SDavid Herrmann 
3989b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
3990b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
3991b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
3992b1b813d4SDavid Herrmann 
3993b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
3994b1b813d4SDavid Herrmann 
399565cc2b49SMarcel Holtmann 	INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout);
3996b1b813d4SDavid Herrmann 
3997b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
3998b1b813d4SDavid Herrmann 	discovery_init(hdev);
39999be0dab7SDavid Herrmann 
40009be0dab7SDavid Herrmann 	return hdev;
40019be0dab7SDavid Herrmann }
40029be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev);
40039be0dab7SDavid Herrmann 
40049be0dab7SDavid Herrmann /* Free HCI device */
40059be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
40069be0dab7SDavid Herrmann {
40079be0dab7SDavid Herrmann 	/* will free via device release */
40089be0dab7SDavid Herrmann 	put_device(&hdev->dev);
40099be0dab7SDavid Herrmann }
40109be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
40119be0dab7SDavid Herrmann 
40121da177e4SLinus Torvalds /* Register HCI device */
40131da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
40141da177e4SLinus Torvalds {
4015b1b813d4SDavid Herrmann 	int id, error;
40161da177e4SLinus Torvalds 
401774292d5aSMarcel Holtmann 	if (!hdev->open || !hdev->close || !hdev->send)
40181da177e4SLinus Torvalds 		return -EINVAL;
40191da177e4SLinus Torvalds 
402008add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
402108add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
402208add513SMat Martineau 	 */
40233df92b31SSasha Levin 	switch (hdev->dev_type) {
40243df92b31SSasha Levin 	case HCI_BREDR:
40253df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
40261da177e4SLinus Torvalds 		break;
40273df92b31SSasha Levin 	case HCI_AMP:
40283df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
40293df92b31SSasha Levin 		break;
40303df92b31SSasha Levin 	default:
40313df92b31SSasha Levin 		return -EINVAL;
40321da177e4SLinus Torvalds 	}
40331da177e4SLinus Torvalds 
40343df92b31SSasha Levin 	if (id < 0)
40353df92b31SSasha Levin 		return id;
40363df92b31SSasha Levin 
40371da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
40381da177e4SLinus Torvalds 	hdev->id = id;
40392d8b3a11SAndrei Emeltchenko 
40402d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
40412d8b3a11SAndrei Emeltchenko 
4042d8537548SKees Cook 	hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
4043d8537548SKees Cook 					  WQ_MEM_RECLAIM, 1, hdev->name);
404433ca954dSDavid Herrmann 	if (!hdev->workqueue) {
404533ca954dSDavid Herrmann 		error = -ENOMEM;
404633ca954dSDavid Herrmann 		goto err;
404733ca954dSDavid Herrmann 	}
4048f48fd9c8SMarcel Holtmann 
4049d8537548SKees Cook 	hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
4050d8537548SKees Cook 					      WQ_MEM_RECLAIM, 1, hdev->name);
40516ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
40526ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
40536ead1bbcSJohan Hedberg 		error = -ENOMEM;
40546ead1bbcSJohan Hedberg 		goto err;
40556ead1bbcSJohan Hedberg 	}
40566ead1bbcSJohan Hedberg 
40570153e2ecSMarcel Holtmann 	if (!IS_ERR_OR_NULL(bt_debugfs))
40580153e2ecSMarcel Holtmann 		hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs);
40590153e2ecSMarcel Holtmann 
4060bdc3e0f1SMarcel Holtmann 	dev_set_name(&hdev->dev, "%s", hdev->name);
4061bdc3e0f1SMarcel Holtmann 
4062bdc3e0f1SMarcel Holtmann 	error = device_add(&hdev->dev);
406333ca954dSDavid Herrmann 	if (error < 0)
406454506918SJohan Hedberg 		goto err_wqueue;
40651da177e4SLinus Torvalds 
4066611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
4067a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
4068a8c5fb1aSGustavo Padovan 				    hdev);
4069611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
4070611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
4071611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
4072611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
4073611b30f7SMarcel Holtmann 		}
4074611b30f7SMarcel Holtmann 	}
4075611b30f7SMarcel Holtmann 
40765e130367SJohan Hedberg 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill))
40775e130367SJohan Hedberg 		set_bit(HCI_RFKILLED, &hdev->dev_flags);
40785e130367SJohan Hedberg 
4079a8b2d5c2SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->dev_flags);
4080004b0258SMarcel Holtmann 	set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
4081ce2be9acSAndrei Emeltchenko 
408201cd3404SMarcel Holtmann 	if (hdev->dev_type == HCI_BREDR) {
408356f87901SJohan Hedberg 		/* Assume BR/EDR support until proven otherwise (such as
408456f87901SJohan Hedberg 		 * through reading supported features during init.
408556f87901SJohan Hedberg 		 */
408656f87901SJohan Hedberg 		set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
408756f87901SJohan Hedberg 	}
4088ce2be9acSAndrei Emeltchenko 
4089fcee3377SGustavo Padovan 	write_lock(&hci_dev_list_lock);
4090fcee3377SGustavo Padovan 	list_add(&hdev->list, &hci_dev_list);
4091fcee3377SGustavo Padovan 	write_unlock(&hci_dev_list_lock);
4092fcee3377SGustavo Padovan 
40934a964404SMarcel Holtmann 	/* Devices that are marked for raw-only usage are unconfigured
40944a964404SMarcel Holtmann 	 * and should not be included in normal operation.
4095fee746b0SMarcel Holtmann 	 */
4096fee746b0SMarcel Holtmann 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
40974a964404SMarcel Holtmann 		set_bit(HCI_UNCONFIGURED, &hdev->dev_flags);
4098fee746b0SMarcel Holtmann 
40991da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
4100dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
41011da177e4SLinus Torvalds 
410219202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
4103fbe96d6fSMarcel Holtmann 
41041da177e4SLinus Torvalds 	return id;
4105f48fd9c8SMarcel Holtmann 
410633ca954dSDavid Herrmann err_wqueue:
410733ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
41086ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
410933ca954dSDavid Herrmann err:
41103df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
4111f48fd9c8SMarcel Holtmann 
411233ca954dSDavid Herrmann 	return error;
41131da177e4SLinus Torvalds }
41141da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
41151da177e4SLinus Torvalds 
41161da177e4SLinus Torvalds /* Unregister HCI device */
411759735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
41181da177e4SLinus Torvalds {
41193df92b31SSasha Levin 	int i, id;
4120ef222013SMarcel Holtmann 
4121c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
41221da177e4SLinus Torvalds 
412394324962SJohan Hovold 	set_bit(HCI_UNREGISTER, &hdev->dev_flags);
412494324962SJohan Hovold 
41253df92b31SSasha Levin 	id = hdev->id;
41263df92b31SSasha Levin 
4127f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
41281da177e4SLinus Torvalds 	list_del(&hdev->list);
4129f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
41301da177e4SLinus Torvalds 
41311da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
41321da177e4SLinus Torvalds 
4133cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
4134ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
4135ef222013SMarcel Holtmann 
4136b9b5ef18SGustavo Padovan 	cancel_work_sync(&hdev->power_on);
4137b9b5ef18SGustavo Padovan 
4138ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
4139d603b76bSMarcel Holtmann 	    !test_bit(HCI_SETUP, &hdev->dev_flags) &&
4140d603b76bSMarcel Holtmann 	    !test_bit(HCI_CONFIG, &hdev->dev_flags)) {
414109fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
4142744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
414309fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
414456e5cb86SJohan Hedberg 	}
4145ab81cbf9SJohan Hedberg 
41462e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
41472e58ef3eSJohan Hedberg 	 * pending list */
41482e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
41492e58ef3eSJohan Hedberg 
41501da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
41511da177e4SLinus Torvalds 
4152611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
4153611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
4154611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
4155611b30f7SMarcel Holtmann 	}
4156611b30f7SMarcel Holtmann 
4157711eafe3SJohan Hedberg 	smp_unregister(hdev);
415899780a7bSJohan Hedberg 
4159bdc3e0f1SMarcel Holtmann 	device_del(&hdev->dev);
4160147e2d59SDave Young 
41610153e2ecSMarcel Holtmann 	debugfs_remove_recursive(hdev->debugfs);
41620153e2ecSMarcel Holtmann 
4163f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
41646ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
4165f48fd9c8SMarcel Holtmann 
416609fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
4167dcc36c16SJohan Hedberg 	hci_bdaddr_list_clear(&hdev->blacklist);
41686659358eSJohan Hedberg 	hci_bdaddr_list_clear(&hdev->whitelist);
41692aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
417055ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
4171b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
4172970c4e46SJohan Hedberg 	hci_smp_irks_clear(hdev);
41732763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
4174dcc36c16SJohan Hedberg 	hci_bdaddr_list_clear(&hdev->le_white_list);
4175373110c5SJohan Hedberg 	hci_conn_params_clear_all(hdev);
417622078800SMarcel Holtmann 	hci_discovery_filter_clear(hdev);
417709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
4178e2e0cacbSJohan Hedberg 
4179dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
41803df92b31SSasha Levin 
41813df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, id);
41821da177e4SLinus Torvalds }
41831da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
41841da177e4SLinus Torvalds 
41851da177e4SLinus Torvalds /* Suspend HCI device */
41861da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
41871da177e4SLinus Torvalds {
41881da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
41891da177e4SLinus Torvalds 	return 0;
41901da177e4SLinus Torvalds }
41911da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
41921da177e4SLinus Torvalds 
41931da177e4SLinus Torvalds /* Resume HCI device */
41941da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
41951da177e4SLinus Torvalds {
41961da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
41971da177e4SLinus Torvalds 	return 0;
41981da177e4SLinus Torvalds }
41991da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
42001da177e4SLinus Torvalds 
420175e0569fSMarcel Holtmann /* Reset HCI device */
420275e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev)
420375e0569fSMarcel Holtmann {
420475e0569fSMarcel Holtmann 	const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 };
420575e0569fSMarcel Holtmann 	struct sk_buff *skb;
420675e0569fSMarcel Holtmann 
420775e0569fSMarcel Holtmann 	skb = bt_skb_alloc(3, GFP_ATOMIC);
420875e0569fSMarcel Holtmann 	if (!skb)
420975e0569fSMarcel Holtmann 		return -ENOMEM;
421075e0569fSMarcel Holtmann 
421175e0569fSMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
421275e0569fSMarcel Holtmann 	memcpy(skb_put(skb, 3), hw_err, 3);
421375e0569fSMarcel Holtmann 
421475e0569fSMarcel Holtmann 	/* Send Hardware Error to upper stack */
421575e0569fSMarcel Holtmann 	return hci_recv_frame(hdev, skb);
421675e0569fSMarcel Holtmann }
421775e0569fSMarcel Holtmann EXPORT_SYMBOL(hci_reset_dev);
421875e0569fSMarcel Holtmann 
421976bca880SMarcel Holtmann /* Receive frame from HCI drivers */
4220e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
422176bca880SMarcel Holtmann {
422276bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
422376bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
422476bca880SMarcel Holtmann 		kfree_skb(skb);
422576bca880SMarcel Holtmann 		return -ENXIO;
422676bca880SMarcel Holtmann 	}
422776bca880SMarcel Holtmann 
4228d82603c6SJorrit Schippers 	/* Incoming skb */
422976bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
423076bca880SMarcel Holtmann 
423176bca880SMarcel Holtmann 	/* Time stamp */
423276bca880SMarcel Holtmann 	__net_timestamp(skb);
423376bca880SMarcel Holtmann 
423476bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
4235b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
4236c78ae283SMarcel Holtmann 
423776bca880SMarcel Holtmann 	return 0;
423876bca880SMarcel Holtmann }
423976bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
424076bca880SMarcel Holtmann 
424133e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
42421e429f38SGustavo F. Padovan 			  int count, __u8 index)
424333e882a5SSuraj Sumangala {
424433e882a5SSuraj Sumangala 	int len = 0;
424533e882a5SSuraj Sumangala 	int hlen = 0;
424633e882a5SSuraj Sumangala 	int remain = count;
424733e882a5SSuraj Sumangala 	struct sk_buff *skb;
424833e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
424933e882a5SSuraj Sumangala 
425033e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
425133e882a5SSuraj Sumangala 	    index >= NUM_REASSEMBLY)
425233e882a5SSuraj Sumangala 		return -EILSEQ;
425333e882a5SSuraj Sumangala 
425433e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
425533e882a5SSuraj Sumangala 
425633e882a5SSuraj Sumangala 	if (!skb) {
425733e882a5SSuraj Sumangala 		switch (type) {
425833e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
425933e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
426033e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
426133e882a5SSuraj Sumangala 			break;
426233e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
426333e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
426433e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
426533e882a5SSuraj Sumangala 			break;
426633e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
426733e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
426833e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
426933e882a5SSuraj Sumangala 			break;
427033e882a5SSuraj Sumangala 		}
427133e882a5SSuraj Sumangala 
42721e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
427333e882a5SSuraj Sumangala 		if (!skb)
427433e882a5SSuraj Sumangala 			return -ENOMEM;
427533e882a5SSuraj Sumangala 
427633e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
427733e882a5SSuraj Sumangala 		scb->expect = hlen;
427833e882a5SSuraj Sumangala 		scb->pkt_type = type;
427933e882a5SSuraj Sumangala 
428033e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
428133e882a5SSuraj Sumangala 	}
428233e882a5SSuraj Sumangala 
428333e882a5SSuraj Sumangala 	while (count) {
428433e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
428589bb46d0SDan Carpenter 		len = min_t(uint, scb->expect, count);
428633e882a5SSuraj Sumangala 
428733e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
428833e882a5SSuraj Sumangala 
428933e882a5SSuraj Sumangala 		count -= len;
429033e882a5SSuraj Sumangala 		data += len;
429133e882a5SSuraj Sumangala 		scb->expect -= len;
429233e882a5SSuraj Sumangala 		remain = count;
429333e882a5SSuraj Sumangala 
429433e882a5SSuraj Sumangala 		switch (type) {
429533e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
429633e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
429733e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
429833e882a5SSuraj Sumangala 				scb->expect = h->plen;
429933e882a5SSuraj Sumangala 
430033e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
430133e882a5SSuraj Sumangala 					kfree_skb(skb);
430233e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
430333e882a5SSuraj Sumangala 					return -ENOMEM;
430433e882a5SSuraj Sumangala 				}
430533e882a5SSuraj Sumangala 			}
430633e882a5SSuraj Sumangala 			break;
430733e882a5SSuraj Sumangala 
430833e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
430933e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
431033e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
431133e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
431233e882a5SSuraj Sumangala 
431333e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
431433e882a5SSuraj Sumangala 					kfree_skb(skb);
431533e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
431633e882a5SSuraj Sumangala 					return -ENOMEM;
431733e882a5SSuraj Sumangala 				}
431833e882a5SSuraj Sumangala 			}
431933e882a5SSuraj Sumangala 			break;
432033e882a5SSuraj Sumangala 
432133e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
432233e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
432333e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
432433e882a5SSuraj Sumangala 				scb->expect = h->dlen;
432533e882a5SSuraj Sumangala 
432633e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
432733e882a5SSuraj Sumangala 					kfree_skb(skb);
432833e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
432933e882a5SSuraj Sumangala 					return -ENOMEM;
433033e882a5SSuraj Sumangala 				}
433133e882a5SSuraj Sumangala 			}
433233e882a5SSuraj Sumangala 			break;
433333e882a5SSuraj Sumangala 		}
433433e882a5SSuraj Sumangala 
433533e882a5SSuraj Sumangala 		if (scb->expect == 0) {
433633e882a5SSuraj Sumangala 			/* Complete frame */
433733e882a5SSuraj Sumangala 
433833e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
4339e1a26170SMarcel Holtmann 			hci_recv_frame(hdev, skb);
434033e882a5SSuraj Sumangala 
434133e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
434233e882a5SSuraj Sumangala 			return remain;
434333e882a5SSuraj Sumangala 		}
434433e882a5SSuraj Sumangala 	}
434533e882a5SSuraj Sumangala 
434633e882a5SSuraj Sumangala 	return remain;
434733e882a5SSuraj Sumangala }
434833e882a5SSuraj Sumangala 
434999811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
435099811510SSuraj Sumangala 
435199811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
435299811510SSuraj Sumangala {
435399811510SSuraj Sumangala 	int type;
435499811510SSuraj Sumangala 	int rem = 0;
435599811510SSuraj Sumangala 
4356da5f6c37SGustavo F. Padovan 	while (count) {
435799811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
435899811510SSuraj Sumangala 
435999811510SSuraj Sumangala 		if (!skb) {
436099811510SSuraj Sumangala 			struct { char type; } *pkt;
436199811510SSuraj Sumangala 
436299811510SSuraj Sumangala 			/* Start of the frame */
436399811510SSuraj Sumangala 			pkt = data;
436499811510SSuraj Sumangala 			type = pkt->type;
436599811510SSuraj Sumangala 
436699811510SSuraj Sumangala 			data++;
436799811510SSuraj Sumangala 			count--;
436899811510SSuraj Sumangala 		} else
436999811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
437099811510SSuraj Sumangala 
43711e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
43721e429f38SGustavo F. Padovan 				     STREAM_REASSEMBLY);
437399811510SSuraj Sumangala 		if (rem < 0)
437499811510SSuraj Sumangala 			return rem;
437599811510SSuraj Sumangala 
437699811510SSuraj Sumangala 		data += (count - rem);
437799811510SSuraj Sumangala 		count = rem;
4378f81c6224SJoe Perches 	}
437999811510SSuraj Sumangala 
438099811510SSuraj Sumangala 	return rem;
438199811510SSuraj Sumangala }
438299811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
438399811510SSuraj Sumangala 
43841da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
43851da177e4SLinus Torvalds 
43861da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
43871da177e4SLinus Torvalds {
43881da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
43891da177e4SLinus Torvalds 
4390f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
43911da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
4392f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
43931da177e4SLinus Torvalds 
43941da177e4SLinus Torvalds 	return 0;
43951da177e4SLinus Torvalds }
43961da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
43971da177e4SLinus Torvalds 
43981da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
43991da177e4SLinus Torvalds {
44001da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
44011da177e4SLinus Torvalds 
4402f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
44031da177e4SLinus Torvalds 	list_del(&cb->list);
4404f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
44051da177e4SLinus Torvalds 
44061da177e4SLinus Torvalds 	return 0;
44071da177e4SLinus Torvalds }
44081da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
44091da177e4SLinus Torvalds 
441051086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
44111da177e4SLinus Torvalds {
4412cdc52faaSMarcel Holtmann 	int err;
4413cdc52faaSMarcel Holtmann 
44140d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
44151da177e4SLinus Torvalds 
44161da177e4SLinus Torvalds 	/* Time stamp */
4417a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
44181da177e4SLinus Torvalds 
4419cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
4420cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
4421cd82e61cSMarcel Holtmann 
4422cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
4423cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
4424470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
44251da177e4SLinus Torvalds 	}
44261da177e4SLinus Torvalds 
44271da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
44281da177e4SLinus Torvalds 	skb_orphan(skb);
44291da177e4SLinus Torvalds 
4430cdc52faaSMarcel Holtmann 	err = hdev->send(hdev, skb);
4431cdc52faaSMarcel Holtmann 	if (err < 0) {
4432cdc52faaSMarcel Holtmann 		BT_ERR("%s sending frame failed (%d)", hdev->name, err);
4433cdc52faaSMarcel Holtmann 		kfree_skb(skb);
4434cdc52faaSMarcel Holtmann 	}
44351da177e4SLinus Torvalds }
44361da177e4SLinus Torvalds 
4437899de765SMarcel Holtmann bool hci_req_pending(struct hci_dev *hdev)
4438899de765SMarcel Holtmann {
4439899de765SMarcel Holtmann 	return (hdev->req_status == HCI_REQ_PEND);
4440899de765SMarcel Holtmann }
4441899de765SMarcel Holtmann 
44421ca3a9d0SJohan Hedberg /* Send HCI command */
444307dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
444407dc93ddSJohan Hedberg 		 const void *param)
44451ca3a9d0SJohan Hedberg {
44461ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
44471ca3a9d0SJohan Hedberg 
44481ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
44491ca3a9d0SJohan Hedberg 
44501ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
44511ca3a9d0SJohan Hedberg 	if (!skb) {
44521ca3a9d0SJohan Hedberg 		BT_ERR("%s no memory for command", hdev->name);
44531ca3a9d0SJohan Hedberg 		return -ENOMEM;
44541ca3a9d0SJohan Hedberg 	}
44551ca3a9d0SJohan Hedberg 
445649c922bbSStephen Hemminger 	/* Stand-alone HCI commands must be flagged as
445711714b3dSJohan Hedberg 	 * single-command requests.
445811714b3dSJohan Hedberg 	 */
445911714b3dSJohan Hedberg 	bt_cb(skb)->req.start = true;
446011714b3dSJohan Hedberg 
44611da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
4462c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
44631da177e4SLinus Torvalds 
44641da177e4SLinus Torvalds 	return 0;
44651da177e4SLinus Torvalds }
44661da177e4SLinus Torvalds 
44671da177e4SLinus Torvalds /* Get data from the previously sent command */
4468a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
44691da177e4SLinus Torvalds {
44701da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
44711da177e4SLinus Torvalds 
44721da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
44731da177e4SLinus Torvalds 		return NULL;
44741da177e4SLinus Torvalds 
44751da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
44761da177e4SLinus Torvalds 
4477a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
44781da177e4SLinus Torvalds 		return NULL;
44791da177e4SLinus Torvalds 
4480f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
44811da177e4SLinus Torvalds 
44821da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
44831da177e4SLinus Torvalds }
44841da177e4SLinus Torvalds 
44851da177e4SLinus Torvalds /* Send ACL data */
44861da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
44871da177e4SLinus Torvalds {
44881da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
44891da177e4SLinus Torvalds 	int len = skb->len;
44901da177e4SLinus Torvalds 
4491badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
4492badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
44939c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
4494aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
4495aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
44961da177e4SLinus Torvalds }
44971da177e4SLinus Torvalds 
4498ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
449973d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
45001da177e4SLinus Torvalds {
4501ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
45021da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
45031da177e4SLinus Torvalds 	struct sk_buff *list;
45041da177e4SLinus Torvalds 
4505087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
4506087bfd99SGustavo Padovan 	skb->data_len = 0;
4507087bfd99SGustavo Padovan 
4508087bfd99SGustavo Padovan 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
4509204a6e54SAndrei Emeltchenko 
4510204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
4511204a6e54SAndrei Emeltchenko 	case HCI_BREDR:
4512087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
4513204a6e54SAndrei Emeltchenko 		break;
4514204a6e54SAndrei Emeltchenko 	case HCI_AMP:
4515204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
4516204a6e54SAndrei Emeltchenko 		break;
4517204a6e54SAndrei Emeltchenko 	default:
4518204a6e54SAndrei Emeltchenko 		BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
4519204a6e54SAndrei Emeltchenko 		return;
4520204a6e54SAndrei Emeltchenko 	}
4521087bfd99SGustavo Padovan 
452270f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
452370f23020SAndrei Emeltchenko 	if (!list) {
45241da177e4SLinus Torvalds 		/* Non fragmented */
45251da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
45261da177e4SLinus Torvalds 
452773d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
45281da177e4SLinus Torvalds 	} else {
45291da177e4SLinus Torvalds 		/* Fragmented */
45301da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
45311da177e4SLinus Torvalds 
45321da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
45331da177e4SLinus Torvalds 
45349cfd5a23SJukka Rissanen 		/* Queue all fragments atomically. We need to use spin_lock_bh
45359cfd5a23SJukka Rissanen 		 * here because of 6LoWPAN links, as there this function is
45369cfd5a23SJukka Rissanen 		 * called from softirq and using normal spin lock could cause
45379cfd5a23SJukka Rissanen 		 * deadlocks.
45389cfd5a23SJukka Rissanen 		 */
45399cfd5a23SJukka Rissanen 		spin_lock_bh(&queue->lock);
45401da177e4SLinus Torvalds 
454173d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
4542e702112fSAndrei Emeltchenko 
4543e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
4544e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
45451da177e4SLinus Torvalds 		do {
45461da177e4SLinus Torvalds 			skb = list; list = list->next;
45471da177e4SLinus Torvalds 
45480d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
4549e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
45501da177e4SLinus Torvalds 
45511da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
45521da177e4SLinus Torvalds 
455373d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
45541da177e4SLinus Torvalds 		} while (list);
45551da177e4SLinus Torvalds 
45569cfd5a23SJukka Rissanen 		spin_unlock_bh(&queue->lock);
45571da177e4SLinus Torvalds 	}
455873d80debSLuiz Augusto von Dentz }
455973d80debSLuiz Augusto von Dentz 
456073d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
456173d80debSLuiz Augusto von Dentz {
4562ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
456373d80debSLuiz Augusto von Dentz 
4564f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
456573d80debSLuiz Augusto von Dentz 
4566ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
45671da177e4SLinus Torvalds 
45683eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
45691da177e4SLinus Torvalds }
45701da177e4SLinus Torvalds 
45711da177e4SLinus Torvalds /* Send SCO data */
45720d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
45731da177e4SLinus Torvalds {
45741da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
45751da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
45761da177e4SLinus Torvalds 
45771da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
45781da177e4SLinus Torvalds 
4579aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
45801da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
45811da177e4SLinus Torvalds 
4582badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
4583badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
45849c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
45851da177e4SLinus Torvalds 
45860d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
4587c78ae283SMarcel Holtmann 
45881da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
45893eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
45901da177e4SLinus Torvalds }
45911da177e4SLinus Torvalds 
45921da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
45931da177e4SLinus Torvalds 
45941da177e4SLinus Torvalds /* HCI Connection scheduler */
45956039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
4596a8c5fb1aSGustavo Padovan 				     int *quote)
45971da177e4SLinus Torvalds {
45981da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
45998035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
4600abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
46011da177e4SLinus Torvalds 
46021da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
46031da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
4604bf4c6325SGustavo F. Padovan 
4605bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4606bf4c6325SGustavo F. Padovan 
4607bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
4608769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
46091da177e4SLinus Torvalds 			continue;
4610769be974SMarcel Holtmann 
4611769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
4612769be974SMarcel Holtmann 			continue;
4613769be974SMarcel Holtmann 
46141da177e4SLinus Torvalds 		num++;
46151da177e4SLinus Torvalds 
46161da177e4SLinus Torvalds 		if (c->sent < min) {
46171da177e4SLinus Torvalds 			min  = c->sent;
46181da177e4SLinus Torvalds 			conn = c;
46191da177e4SLinus Torvalds 		}
462052087a79SLuiz Augusto von Dentz 
462152087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
462252087a79SLuiz Augusto von Dentz 			break;
46231da177e4SLinus Torvalds 	}
46241da177e4SLinus Torvalds 
4625bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4626bf4c6325SGustavo F. Padovan 
46271da177e4SLinus Torvalds 	if (conn) {
46286ed58ec5SVille Tervo 		int cnt, q;
46296ed58ec5SVille Tervo 
46306ed58ec5SVille Tervo 		switch (conn->type) {
46316ed58ec5SVille Tervo 		case ACL_LINK:
46326ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
46336ed58ec5SVille Tervo 			break;
46346ed58ec5SVille Tervo 		case SCO_LINK:
46356ed58ec5SVille Tervo 		case ESCO_LINK:
46366ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
46376ed58ec5SVille Tervo 			break;
46386ed58ec5SVille Tervo 		case LE_LINK:
46396ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
46406ed58ec5SVille Tervo 			break;
46416ed58ec5SVille Tervo 		default:
46426ed58ec5SVille Tervo 			cnt = 0;
46436ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
46446ed58ec5SVille Tervo 		}
46456ed58ec5SVille Tervo 
46466ed58ec5SVille Tervo 		q = cnt / num;
46471da177e4SLinus Torvalds 		*quote = q ? q : 1;
46481da177e4SLinus Torvalds 	} else
46491da177e4SLinus Torvalds 		*quote = 0;
46501da177e4SLinus Torvalds 
46511da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
46521da177e4SLinus Torvalds 	return conn;
46531da177e4SLinus Torvalds }
46541da177e4SLinus Torvalds 
46556039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
46561da177e4SLinus Torvalds {
46571da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
46581da177e4SLinus Torvalds 	struct hci_conn *c;
46591da177e4SLinus Torvalds 
4660bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
46611da177e4SLinus Torvalds 
4662bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4663bf4c6325SGustavo F. Padovan 
46641da177e4SLinus Torvalds 	/* Kill stalled connections */
4665bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
4666bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
46676ed93dc6SAndrei Emeltchenko 			BT_ERR("%s killing stalled connection %pMR",
46686ed93dc6SAndrei Emeltchenko 			       hdev->name, &c->dst);
4669bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
46701da177e4SLinus Torvalds 		}
46711da177e4SLinus Torvalds 	}
4672bf4c6325SGustavo F. Padovan 
4673bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
46741da177e4SLinus Torvalds }
46751da177e4SLinus Torvalds 
46766039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
467773d80debSLuiz Augusto von Dentz 				      int *quote)
467873d80debSLuiz Augusto von Dentz {
467973d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
468073d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
4681abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
468273d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
468373d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
468473d80debSLuiz Augusto von Dentz 
468573d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
468673d80debSLuiz Augusto von Dentz 
4687bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4688bf4c6325SGustavo F. Padovan 
4689bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
469073d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
469173d80debSLuiz Augusto von Dentz 
469273d80debSLuiz Augusto von Dentz 		if (conn->type != type)
469373d80debSLuiz Augusto von Dentz 			continue;
469473d80debSLuiz Augusto von Dentz 
469573d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
469673d80debSLuiz Augusto von Dentz 			continue;
469773d80debSLuiz Augusto von Dentz 
469873d80debSLuiz Augusto von Dentz 		conn_num++;
469973d80debSLuiz Augusto von Dentz 
47008192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
470173d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
470273d80debSLuiz Augusto von Dentz 
470373d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
470473d80debSLuiz Augusto von Dentz 				continue;
470573d80debSLuiz Augusto von Dentz 
470673d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
470773d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
470873d80debSLuiz Augusto von Dentz 				continue;
470973d80debSLuiz Augusto von Dentz 
471073d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
471173d80debSLuiz Augusto von Dentz 				num = 0;
471273d80debSLuiz Augusto von Dentz 				min = ~0;
471373d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
471473d80debSLuiz Augusto von Dentz 			}
471573d80debSLuiz Augusto von Dentz 
471673d80debSLuiz Augusto von Dentz 			num++;
471773d80debSLuiz Augusto von Dentz 
471873d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
471973d80debSLuiz Augusto von Dentz 				min  = conn->sent;
472073d80debSLuiz Augusto von Dentz 				chan = tmp;
472173d80debSLuiz Augusto von Dentz 			}
472273d80debSLuiz Augusto von Dentz 		}
472373d80debSLuiz Augusto von Dentz 
472473d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
472573d80debSLuiz Augusto von Dentz 			break;
472673d80debSLuiz Augusto von Dentz 	}
472773d80debSLuiz Augusto von Dentz 
4728bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4729bf4c6325SGustavo F. Padovan 
473073d80debSLuiz Augusto von Dentz 	if (!chan)
473173d80debSLuiz Augusto von Dentz 		return NULL;
473273d80debSLuiz Augusto von Dentz 
473373d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
473473d80debSLuiz Augusto von Dentz 	case ACL_LINK:
473573d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
473673d80debSLuiz Augusto von Dentz 		break;
4737bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
4738bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
4739bd1eb66bSAndrei Emeltchenko 		break;
474073d80debSLuiz Augusto von Dentz 	case SCO_LINK:
474173d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
474273d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
474373d80debSLuiz Augusto von Dentz 		break;
474473d80debSLuiz Augusto von Dentz 	case LE_LINK:
474573d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
474673d80debSLuiz Augusto von Dentz 		break;
474773d80debSLuiz Augusto von Dentz 	default:
474873d80debSLuiz Augusto von Dentz 		cnt = 0;
474973d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
475073d80debSLuiz Augusto von Dentz 	}
475173d80debSLuiz Augusto von Dentz 
475273d80debSLuiz Augusto von Dentz 	q = cnt / num;
475373d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
475473d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
475573d80debSLuiz Augusto von Dentz 	return chan;
475673d80debSLuiz Augusto von Dentz }
475773d80debSLuiz Augusto von Dentz 
475802b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
475902b20f0bSLuiz Augusto von Dentz {
476002b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
476102b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
476202b20f0bSLuiz Augusto von Dentz 	int num = 0;
476302b20f0bSLuiz Augusto von Dentz 
476402b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
476502b20f0bSLuiz Augusto von Dentz 
4766bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4767bf4c6325SGustavo F. Padovan 
4768bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
476902b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
477002b20f0bSLuiz Augusto von Dentz 
477102b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
477202b20f0bSLuiz Augusto von Dentz 			continue;
477302b20f0bSLuiz Augusto von Dentz 
477402b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
477502b20f0bSLuiz Augusto von Dentz 			continue;
477602b20f0bSLuiz Augusto von Dentz 
477702b20f0bSLuiz Augusto von Dentz 		num++;
477802b20f0bSLuiz Augusto von Dentz 
47798192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
478002b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
478102b20f0bSLuiz Augusto von Dentz 
478202b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
478302b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
478402b20f0bSLuiz Augusto von Dentz 				continue;
478502b20f0bSLuiz Augusto von Dentz 			}
478602b20f0bSLuiz Augusto von Dentz 
478702b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
478802b20f0bSLuiz Augusto von Dentz 				continue;
478902b20f0bSLuiz Augusto von Dentz 
479002b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
479102b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
479202b20f0bSLuiz Augusto von Dentz 				continue;
479302b20f0bSLuiz Augusto von Dentz 
479402b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
479502b20f0bSLuiz Augusto von Dentz 
479602b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
479702b20f0bSLuiz Augusto von Dentz 			       skb->priority);
479802b20f0bSLuiz Augusto von Dentz 		}
479902b20f0bSLuiz Augusto von Dentz 
480002b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
480102b20f0bSLuiz Augusto von Dentz 			break;
480202b20f0bSLuiz Augusto von Dentz 	}
4803bf4c6325SGustavo F. Padovan 
4804bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4805bf4c6325SGustavo F. Padovan 
480602b20f0bSLuiz Augusto von Dentz }
480702b20f0bSLuiz Augusto von Dentz 
4808b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
4809b71d385aSAndrei Emeltchenko {
4810b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
4811b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
4812b71d385aSAndrei Emeltchenko }
4813b71d385aSAndrei Emeltchenko 
48146039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
48151da177e4SLinus Torvalds {
48164a964404SMarcel Holtmann 	if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
48171da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
48181da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
481963d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
48205f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
4821bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
48221da177e4SLinus Torvalds 	}
482363d2bc1bSAndrei Emeltchenko }
48241da177e4SLinus Torvalds 
48256039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
482663d2bc1bSAndrei Emeltchenko {
482763d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
482863d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
482963d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
483063d2bc1bSAndrei Emeltchenko 	int quote;
483163d2bc1bSAndrei Emeltchenko 
483263d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
483304837f64SMarcel Holtmann 
483473d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
483573d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
4836ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
4837ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
483873d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
483973d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
484073d80debSLuiz Augusto von Dentz 
4841ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
4842ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
4843ec1cce24SLuiz Augusto von Dentz 				break;
4844ec1cce24SLuiz Augusto von Dentz 
4845ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
4846ec1cce24SLuiz Augusto von Dentz 
484773d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
484873d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
484904837f64SMarcel Holtmann 
485057d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
48511da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
48521da177e4SLinus Torvalds 
48531da177e4SLinus Torvalds 			hdev->acl_cnt--;
485473d80debSLuiz Augusto von Dentz 			chan->sent++;
485573d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
48561da177e4SLinus Torvalds 		}
48571da177e4SLinus Torvalds 	}
485802b20f0bSLuiz Augusto von Dentz 
485902b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
486002b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
48611da177e4SLinus Torvalds }
48621da177e4SLinus Torvalds 
48636039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
4864b71d385aSAndrei Emeltchenko {
486563d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
4866b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
4867b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
4868b71d385aSAndrei Emeltchenko 	int quote;
4869bd1eb66bSAndrei Emeltchenko 	u8 type;
4870b71d385aSAndrei Emeltchenko 
487163d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
4872b71d385aSAndrei Emeltchenko 
4873bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
4874bd1eb66bSAndrei Emeltchenko 
4875bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
4876bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
4877bd1eb66bSAndrei Emeltchenko 	else
4878bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
4879bd1eb66bSAndrei Emeltchenko 
4880b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
4881bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
4882b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
4883b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
4884b71d385aSAndrei Emeltchenko 			int blocks;
4885b71d385aSAndrei Emeltchenko 
4886b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
4887b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
4888b71d385aSAndrei Emeltchenko 
4889b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
4890b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
4891b71d385aSAndrei Emeltchenko 				break;
4892b71d385aSAndrei Emeltchenko 
4893b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
4894b71d385aSAndrei Emeltchenko 
4895b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
4896b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
4897b71d385aSAndrei Emeltchenko 				return;
4898b71d385aSAndrei Emeltchenko 
4899b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
4900b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
4901b71d385aSAndrei Emeltchenko 
490257d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
4903b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
4904b71d385aSAndrei Emeltchenko 
4905b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
4906b71d385aSAndrei Emeltchenko 			quote -= blocks;
4907b71d385aSAndrei Emeltchenko 
4908b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
4909b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
4910b71d385aSAndrei Emeltchenko 		}
4911b71d385aSAndrei Emeltchenko 	}
4912b71d385aSAndrei Emeltchenko 
4913b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
4914bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
4915b71d385aSAndrei Emeltchenko }
4916b71d385aSAndrei Emeltchenko 
49176039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
4918b71d385aSAndrei Emeltchenko {
4919b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
4920b71d385aSAndrei Emeltchenko 
4921bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
4922bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR)
4923bd1eb66bSAndrei Emeltchenko 		return;
4924bd1eb66bSAndrei Emeltchenko 
4925bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
4926bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
4927b71d385aSAndrei Emeltchenko 		return;
4928b71d385aSAndrei Emeltchenko 
4929b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
4930b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
4931b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
4932b71d385aSAndrei Emeltchenko 		break;
4933b71d385aSAndrei Emeltchenko 
4934b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
4935b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
4936b71d385aSAndrei Emeltchenko 		break;
4937b71d385aSAndrei Emeltchenko 	}
4938b71d385aSAndrei Emeltchenko }
4939b71d385aSAndrei Emeltchenko 
49401da177e4SLinus Torvalds /* Schedule SCO */
49416039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev)
49421da177e4SLinus Torvalds {
49431da177e4SLinus Torvalds 	struct hci_conn *conn;
49441da177e4SLinus Torvalds 	struct sk_buff *skb;
49451da177e4SLinus Torvalds 	int quote;
49461da177e4SLinus Torvalds 
49471da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
49481da177e4SLinus Torvalds 
494952087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
495052087a79SLuiz Augusto von Dentz 		return;
495152087a79SLuiz Augusto von Dentz 
49521da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
49531da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
49541da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
495557d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
49561da177e4SLinus Torvalds 
49571da177e4SLinus Torvalds 			conn->sent++;
49581da177e4SLinus Torvalds 			if (conn->sent == ~0)
49591da177e4SLinus Torvalds 				conn->sent = 0;
49601da177e4SLinus Torvalds 		}
49611da177e4SLinus Torvalds 	}
49621da177e4SLinus Torvalds }
49631da177e4SLinus Torvalds 
49646039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev)
4965b6a0dc82SMarcel Holtmann {
4966b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
4967b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
4968b6a0dc82SMarcel Holtmann 	int quote;
4969b6a0dc82SMarcel Holtmann 
4970b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
4971b6a0dc82SMarcel Holtmann 
497252087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
497352087a79SLuiz Augusto von Dentz 		return;
497452087a79SLuiz Augusto von Dentz 
49758fc9ced3SGustavo Padovan 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
49768fc9ced3SGustavo Padovan 						     &quote))) {
4977b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
4978b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
497957d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
4980b6a0dc82SMarcel Holtmann 
4981b6a0dc82SMarcel Holtmann 			conn->sent++;
4982b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
4983b6a0dc82SMarcel Holtmann 				conn->sent = 0;
4984b6a0dc82SMarcel Holtmann 		}
4985b6a0dc82SMarcel Holtmann 	}
4986b6a0dc82SMarcel Holtmann }
4987b6a0dc82SMarcel Holtmann 
49886039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
49896ed58ec5SVille Tervo {
499073d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
49916ed58ec5SVille Tervo 	struct sk_buff *skb;
499202b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
49936ed58ec5SVille Tervo 
49946ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
49956ed58ec5SVille Tervo 
499652087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
499752087a79SLuiz Augusto von Dentz 		return;
499852087a79SLuiz Augusto von Dentz 
49994a964404SMarcel Holtmann 	if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
50006ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
50016ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
5002bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
50036ed58ec5SVille Tervo 		    time_after(jiffies, hdev->le_last_tx + HZ * 45))
5004bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
50056ed58ec5SVille Tervo 	}
50066ed58ec5SVille Tervo 
50076ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
500802b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
500973d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
5010ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
5011ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
501273d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
501373d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
50146ed58ec5SVille Tervo 
5015ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
5016ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
5017ec1cce24SLuiz Augusto von Dentz 				break;
5018ec1cce24SLuiz Augusto von Dentz 
5019ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
5020ec1cce24SLuiz Augusto von Dentz 
502157d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
50226ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
50236ed58ec5SVille Tervo 
50246ed58ec5SVille Tervo 			cnt--;
502573d80debSLuiz Augusto von Dentz 			chan->sent++;
502673d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
50276ed58ec5SVille Tervo 		}
50286ed58ec5SVille Tervo 	}
502973d80debSLuiz Augusto von Dentz 
50306ed58ec5SVille Tervo 	if (hdev->le_pkts)
50316ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
50326ed58ec5SVille Tervo 	else
50336ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
503402b20f0bSLuiz Augusto von Dentz 
503502b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
503602b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
50376ed58ec5SVille Tervo }
50386ed58ec5SVille Tervo 
50393eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
50401da177e4SLinus Torvalds {
50413eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
50421da177e4SLinus Torvalds 	struct sk_buff *skb;
50431da177e4SLinus Torvalds 
50446ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
50456ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
50461da177e4SLinus Torvalds 
504752de599eSMarcel Holtmann 	if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
50481da177e4SLinus Torvalds 		/* Schedule queues and send stuff to HCI driver */
50491da177e4SLinus Torvalds 		hci_sched_acl(hdev);
50501da177e4SLinus Torvalds 		hci_sched_sco(hdev);
5051b6a0dc82SMarcel Holtmann 		hci_sched_esco(hdev);
50526ed58ec5SVille Tervo 		hci_sched_le(hdev);
505352de599eSMarcel Holtmann 	}
50546ed58ec5SVille Tervo 
50551da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
50561da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
505757d17d70SMarcel Holtmann 		hci_send_frame(hdev, skb);
50581da177e4SLinus Torvalds }
50591da177e4SLinus Torvalds 
506025985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
50611da177e4SLinus Torvalds 
50621da177e4SLinus Torvalds /* ACL data packet */
50636039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
50641da177e4SLinus Torvalds {
50651da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
50661da177e4SLinus Torvalds 	struct hci_conn *conn;
50671da177e4SLinus Torvalds 	__u16 handle, flags;
50681da177e4SLinus Torvalds 
50691da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
50701da177e4SLinus Torvalds 
50711da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
50721da177e4SLinus Torvalds 	flags  = hci_flags(handle);
50731da177e4SLinus Torvalds 	handle = hci_handle(handle);
50741da177e4SLinus Torvalds 
5075f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
5076a8c5fb1aSGustavo Padovan 	       handle, flags);
50771da177e4SLinus Torvalds 
50781da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
50791da177e4SLinus Torvalds 
50801da177e4SLinus Torvalds 	hci_dev_lock(hdev);
50811da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
50821da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
50831da177e4SLinus Torvalds 
50841da177e4SLinus Torvalds 	if (conn) {
508565983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
508604837f64SMarcel Holtmann 
50871da177e4SLinus Torvalds 		/* Send to upper protocol */
5088686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
50891da177e4SLinus Torvalds 		return;
50901da177e4SLinus Torvalds 	} else {
50911da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
50921da177e4SLinus Torvalds 		       hdev->name, handle);
50931da177e4SLinus Torvalds 	}
50941da177e4SLinus Torvalds 
50951da177e4SLinus Torvalds 	kfree_skb(skb);
50961da177e4SLinus Torvalds }
50971da177e4SLinus Torvalds 
50981da177e4SLinus Torvalds /* SCO data packet */
50996039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
51001da177e4SLinus Torvalds {
51011da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
51021da177e4SLinus Torvalds 	struct hci_conn *conn;
51031da177e4SLinus Torvalds 	__u16 handle;
51041da177e4SLinus Torvalds 
51051da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
51061da177e4SLinus Torvalds 
51071da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
51081da177e4SLinus Torvalds 
5109f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle);
51101da177e4SLinus Torvalds 
51111da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
51121da177e4SLinus Torvalds 
51131da177e4SLinus Torvalds 	hci_dev_lock(hdev);
51141da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
51151da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
51161da177e4SLinus Torvalds 
51171da177e4SLinus Torvalds 	if (conn) {
51181da177e4SLinus Torvalds 		/* Send to upper protocol */
5119686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
51201da177e4SLinus Torvalds 		return;
51211da177e4SLinus Torvalds 	} else {
51221da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
51231da177e4SLinus Torvalds 		       hdev->name, handle);
51241da177e4SLinus Torvalds 	}
51251da177e4SLinus Torvalds 
51261da177e4SLinus Torvalds 	kfree_skb(skb);
51271da177e4SLinus Torvalds }
51281da177e4SLinus Torvalds 
51299238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
51309238f36aSJohan Hedberg {
51319238f36aSJohan Hedberg 	struct sk_buff *skb;
51329238f36aSJohan Hedberg 
51339238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
51349238f36aSJohan Hedberg 	if (!skb)
51359238f36aSJohan Hedberg 		return true;
51369238f36aSJohan Hedberg 
51379238f36aSJohan Hedberg 	return bt_cb(skb)->req.start;
51389238f36aSJohan Hedberg }
51399238f36aSJohan Hedberg 
514042c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
514142c6b129SJohan Hedberg {
514242c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
514342c6b129SJohan Hedberg 	struct sk_buff *skb;
514442c6b129SJohan Hedberg 	u16 opcode;
514542c6b129SJohan Hedberg 
514642c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
514742c6b129SJohan Hedberg 		return;
514842c6b129SJohan Hedberg 
514942c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
515042c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
515142c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
515242c6b129SJohan Hedberg 		return;
515342c6b129SJohan Hedberg 
515442c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
515542c6b129SJohan Hedberg 	if (!skb)
515642c6b129SJohan Hedberg 		return;
515742c6b129SJohan Hedberg 
515842c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
515942c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
516042c6b129SJohan Hedberg }
516142c6b129SJohan Hedberg 
51629238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status)
51639238f36aSJohan Hedberg {
51649238f36aSJohan Hedberg 	hci_req_complete_t req_complete = NULL;
51659238f36aSJohan Hedberg 	struct sk_buff *skb;
51669238f36aSJohan Hedberg 	unsigned long flags;
51679238f36aSJohan Hedberg 
51689238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
51699238f36aSJohan Hedberg 
517042c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
517142c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
51729238f36aSJohan Hedberg 	 */
517342c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
517442c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
517542c6b129SJohan Hedberg 		 * reset complete event during init and any pending
517642c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
517742c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
517842c6b129SJohan Hedberg 		 * command.
517942c6b129SJohan Hedberg 		 */
518042c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
518142c6b129SJohan Hedberg 			hci_resend_last(hdev);
518242c6b129SJohan Hedberg 
51839238f36aSJohan Hedberg 		return;
518442c6b129SJohan Hedberg 	}
51859238f36aSJohan Hedberg 
51869238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
51879238f36aSJohan Hedberg 	 * this request the request is not yet complete.
51889238f36aSJohan Hedberg 	 */
51899238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
51909238f36aSJohan Hedberg 		return;
51919238f36aSJohan Hedberg 
51929238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
51939238f36aSJohan Hedberg 	 * callback would be found in hdev->sent_cmd instead of the
51949238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
51959238f36aSJohan Hedberg 	 */
51969238f36aSJohan Hedberg 	if (hdev->sent_cmd) {
51979238f36aSJohan Hedberg 		req_complete = bt_cb(hdev->sent_cmd)->req.complete;
519853e21fbcSJohan Hedberg 
519953e21fbcSJohan Hedberg 		if (req_complete) {
520053e21fbcSJohan Hedberg 			/* We must set the complete callback to NULL to
520153e21fbcSJohan Hedberg 			 * avoid calling the callback more than once if
520253e21fbcSJohan Hedberg 			 * this function gets called again.
520353e21fbcSJohan Hedberg 			 */
520453e21fbcSJohan Hedberg 			bt_cb(hdev->sent_cmd)->req.complete = NULL;
520553e21fbcSJohan Hedberg 
52069238f36aSJohan Hedberg 			goto call_complete;
52079238f36aSJohan Hedberg 		}
520853e21fbcSJohan Hedberg 	}
52099238f36aSJohan Hedberg 
52109238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
52119238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
52129238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
52139238f36aSJohan Hedberg 		if (bt_cb(skb)->req.start) {
52149238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
52159238f36aSJohan Hedberg 			break;
52169238f36aSJohan Hedberg 		}
52179238f36aSJohan Hedberg 
52189238f36aSJohan Hedberg 		req_complete = bt_cb(skb)->req.complete;
52199238f36aSJohan Hedberg 		kfree_skb(skb);
52209238f36aSJohan Hedberg 	}
52219238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
52229238f36aSJohan Hedberg 
52239238f36aSJohan Hedberg call_complete:
52249238f36aSJohan Hedberg 	if (req_complete)
52259238f36aSJohan Hedberg 		req_complete(hdev, status);
52269238f36aSJohan Hedberg }
52279238f36aSJohan Hedberg 
5228b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
52291da177e4SLinus Torvalds {
5230b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
52311da177e4SLinus Torvalds 	struct sk_buff *skb;
52321da177e4SLinus Torvalds 
52331da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
52341da177e4SLinus Torvalds 
52351da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
5236cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
5237cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
5238cd82e61cSMarcel Holtmann 
52391da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
52401da177e4SLinus Torvalds 			/* Send copy to the sockets */
5241470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
52421da177e4SLinus Torvalds 		}
52431da177e4SLinus Torvalds 
5244fee746b0SMarcel Holtmann 		if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
52451da177e4SLinus Torvalds 			kfree_skb(skb);
52461da177e4SLinus Torvalds 			continue;
52471da177e4SLinus Torvalds 		}
52481da177e4SLinus Torvalds 
52491da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
52501da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
52510d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
52521da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
52531da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
52541da177e4SLinus Torvalds 				kfree_skb(skb);
52551da177e4SLinus Torvalds 				continue;
52563ff50b79SStephen Hemminger 			}
52571da177e4SLinus Torvalds 		}
52581da177e4SLinus Torvalds 
52591da177e4SLinus Torvalds 		/* Process frame */
52600d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
52611da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
5262b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
52631da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
52641da177e4SLinus Torvalds 			break;
52651da177e4SLinus Torvalds 
52661da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
52671da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
52681da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
52691da177e4SLinus Torvalds 			break;
52701da177e4SLinus Torvalds 
52711da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
52721da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
52731da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
52741da177e4SLinus Torvalds 			break;
52751da177e4SLinus Torvalds 
52761da177e4SLinus Torvalds 		default:
52771da177e4SLinus Torvalds 			kfree_skb(skb);
52781da177e4SLinus Torvalds 			break;
52791da177e4SLinus Torvalds 		}
52801da177e4SLinus Torvalds 	}
52811da177e4SLinus Torvalds }
52821da177e4SLinus Torvalds 
5283c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
52841da177e4SLinus Torvalds {
5285c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
52861da177e4SLinus Torvalds 	struct sk_buff *skb;
52871da177e4SLinus Torvalds 
52882104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
52892104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
52901da177e4SLinus Torvalds 
52911da177e4SLinus Torvalds 	/* Send queued commands */
52925a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
52935a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
52945a08ecceSAndrei Emeltchenko 		if (!skb)
52955a08ecceSAndrei Emeltchenko 			return;
52965a08ecceSAndrei Emeltchenko 
52971da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
52981da177e4SLinus Torvalds 
5299a675d7f1SMarcel Holtmann 		hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
530070f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
53011da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
530257d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
53037bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
530465cc2b49SMarcel Holtmann 				cancel_delayed_work(&hdev->cmd_timer);
53057bdb8a5cSSzymon Janc 			else
530665cc2b49SMarcel Holtmann 				schedule_delayed_work(&hdev->cmd_timer,
530765cc2b49SMarcel Holtmann 						      HCI_CMD_TIMEOUT);
53081da177e4SLinus Torvalds 		} else {
53091da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
5310c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
53111da177e4SLinus Torvalds 		}
53121da177e4SLinus Torvalds 	}
53131da177e4SLinus Torvalds }
5314b1efcc28SAndre Guedes 
5315a4790dbdSAndre Guedes static void update_background_scan_complete(struct hci_dev *hdev, u8 status)
5316a4790dbdSAndre Guedes {
5317a4790dbdSAndre Guedes 	if (status)
5318a4790dbdSAndre Guedes 		BT_DBG("HCI request failed to update background scanning: "
5319a4790dbdSAndre Guedes 		       "status 0x%2.2x", status);
5320a4790dbdSAndre Guedes }
5321a4790dbdSAndre Guedes 
5322a4790dbdSAndre Guedes /* This function controls the background scanning based on hdev->pend_le_conns
5323a4790dbdSAndre Guedes  * list. If there are pending LE connection we start the background scanning,
5324a4790dbdSAndre Guedes  * otherwise we stop it.
5325a4790dbdSAndre Guedes  *
5326a4790dbdSAndre Guedes  * This function requires the caller holds hdev->lock.
5327a4790dbdSAndre Guedes  */
5328a4790dbdSAndre Guedes void hci_update_background_scan(struct hci_dev *hdev)
5329a4790dbdSAndre Guedes {
5330a4790dbdSAndre Guedes 	struct hci_request req;
5331a4790dbdSAndre Guedes 	struct hci_conn *conn;
5332a4790dbdSAndre Guedes 	int err;
5333a4790dbdSAndre Guedes 
5334c20c02d5SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags) ||
5335c20c02d5SMarcel Holtmann 	    test_bit(HCI_INIT, &hdev->flags) ||
5336c20c02d5SMarcel Holtmann 	    test_bit(HCI_SETUP, &hdev->dev_flags) ||
5337d603b76bSMarcel Holtmann 	    test_bit(HCI_CONFIG, &hdev->dev_flags) ||
5338b8221770SMarcel Holtmann 	    test_bit(HCI_AUTO_OFF, &hdev->dev_flags) ||
5339c20c02d5SMarcel Holtmann 	    test_bit(HCI_UNREGISTER, &hdev->dev_flags))
53401c1697c0SMarcel Holtmann 		return;
53411c1697c0SMarcel Holtmann 
5342a70f4b5fSJohan Hedberg 	/* No point in doing scanning if LE support hasn't been enabled */
5343a70f4b5fSJohan Hedberg 	if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags))
5344a70f4b5fSJohan Hedberg 		return;
5345a70f4b5fSJohan Hedberg 
5346ae23ada4SJohan Hedberg 	/* If discovery is active don't interfere with it */
5347ae23ada4SJohan Hedberg 	if (hdev->discovery.state != DISCOVERY_STOPPED)
5348ae23ada4SJohan Hedberg 		return;
5349ae23ada4SJohan Hedberg 
5350ee3c3ca5SMarcel Holtmann 	/* Reset RSSI and UUID filters when starting background scanning
5351ee3c3ca5SMarcel Holtmann 	 * since these filters are meant for service discovery only.
5352ee3c3ca5SMarcel Holtmann 	 *
5353ee3c3ca5SMarcel Holtmann 	 * The Start Discovery and Start Service Discovery operations
5354ee3c3ca5SMarcel Holtmann 	 * ensure to set proper values for RSSI threshold and UUID
5355ee3c3ca5SMarcel Holtmann 	 * filter list. So it is safe to just reset them here.
5356ee3c3ca5SMarcel Holtmann 	 */
5357ee3c3ca5SMarcel Holtmann 	hci_discovery_filter_clear(hdev);
5358ee3c3ca5SMarcel Holtmann 
5359a4790dbdSAndre Guedes 	hci_req_init(&req, hdev);
5360a4790dbdSAndre Guedes 
5361d1d588c1SJohan Hedberg 	if (list_empty(&hdev->pend_le_conns) &&
536266f8455aSJohan Hedberg 	    list_empty(&hdev->pend_le_reports)) {
53630d2bf134SJohan Hedberg 		/* If there is no pending LE connections or devices
53640d2bf134SJohan Hedberg 		 * to be scanned for, we should stop the background
53650d2bf134SJohan Hedberg 		 * scanning.
5366a4790dbdSAndre Guedes 		 */
5367a4790dbdSAndre Guedes 
5368a4790dbdSAndre Guedes 		/* If controller is not scanning we are done. */
5369a4790dbdSAndre Guedes 		if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags))
5370a4790dbdSAndre Guedes 			return;
5371a4790dbdSAndre Guedes 
5372a4790dbdSAndre Guedes 		hci_req_add_le_scan_disable(&req);
5373a4790dbdSAndre Guedes 
5374a4790dbdSAndre Guedes 		BT_DBG("%s stopping background scanning", hdev->name);
5375a4790dbdSAndre Guedes 	} else {
5376a4790dbdSAndre Guedes 		/* If there is at least one pending LE connection, we should
5377a4790dbdSAndre Guedes 		 * keep the background scan running.
5378a4790dbdSAndre Guedes 		 */
5379a4790dbdSAndre Guedes 
5380a4790dbdSAndre Guedes 		/* If controller is connecting, we should not start scanning
5381a4790dbdSAndre Guedes 		 * since some controllers are not able to scan and connect at
5382a4790dbdSAndre Guedes 		 * the same time.
5383a4790dbdSAndre Guedes 		 */
5384a4790dbdSAndre Guedes 		conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
5385a4790dbdSAndre Guedes 		if (conn)
5386a4790dbdSAndre Guedes 			return;
5387a4790dbdSAndre Guedes 
53884340a124SAndre Guedes 		/* If controller is currently scanning, we stop it to ensure we
53894340a124SAndre Guedes 		 * don't miss any advertising (due to duplicates filter).
53904340a124SAndre Guedes 		 */
53914340a124SAndre Guedes 		if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
53924340a124SAndre Guedes 			hci_req_add_le_scan_disable(&req);
53934340a124SAndre Guedes 
53948ef30fd3SAndre Guedes 		hci_req_add_le_passive_scan(&req);
5395a4790dbdSAndre Guedes 
5396a4790dbdSAndre Guedes 		BT_DBG("%s starting background scanning", hdev->name);
5397a4790dbdSAndre Guedes 	}
5398a4790dbdSAndre Guedes 
5399a4790dbdSAndre Guedes 	err = hci_req_run(&req, update_background_scan_complete);
5400a4790dbdSAndre Guedes 	if (err)
5401a4790dbdSAndre Guedes 		BT_ERR("Failed to run HCI request: err %d", err);
5402a4790dbdSAndre Guedes }
5403432df05eSJohan Hedberg 
540422f433dcSJohan Hedberg static bool disconnected_whitelist_entries(struct hci_dev *hdev)
540522f433dcSJohan Hedberg {
540622f433dcSJohan Hedberg 	struct bdaddr_list *b;
540722f433dcSJohan Hedberg 
540822f433dcSJohan Hedberg 	list_for_each_entry(b, &hdev->whitelist, list) {
540922f433dcSJohan Hedberg 		struct hci_conn *conn;
541022f433dcSJohan Hedberg 
541122f433dcSJohan Hedberg 		conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &b->bdaddr);
541222f433dcSJohan Hedberg 		if (!conn)
541322f433dcSJohan Hedberg 			return true;
541422f433dcSJohan Hedberg 
541522f433dcSJohan Hedberg 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
541622f433dcSJohan Hedberg 			return true;
541722f433dcSJohan Hedberg 	}
541822f433dcSJohan Hedberg 
541922f433dcSJohan Hedberg 	return false;
542022f433dcSJohan Hedberg }
542122f433dcSJohan Hedberg 
54221d2dc5b7SJohan Hedberg void __hci_update_page_scan(struct hci_request *req)
5423432df05eSJohan Hedberg {
54241d2dc5b7SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
5425432df05eSJohan Hedberg 	u8 scan;
5426432df05eSJohan Hedberg 
5427432df05eSJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
5428432df05eSJohan Hedberg 		return;
5429432df05eSJohan Hedberg 
5430432df05eSJohan Hedberg 	if (!hdev_is_powered(hdev))
5431432df05eSJohan Hedberg 		return;
5432432df05eSJohan Hedberg 
5433432df05eSJohan Hedberg 	if (mgmt_powering_down(hdev))
5434432df05eSJohan Hedberg 		return;
5435432df05eSJohan Hedberg 
5436432df05eSJohan Hedberg 	if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags) ||
543722f433dcSJohan Hedberg 	    disconnected_whitelist_entries(hdev))
5438432df05eSJohan Hedberg 		scan = SCAN_PAGE;
5439432df05eSJohan Hedberg 	else
5440432df05eSJohan Hedberg 		scan = SCAN_DISABLED;
5441432df05eSJohan Hedberg 
5442432df05eSJohan Hedberg 	if (test_bit(HCI_PSCAN, &hdev->flags) == !!(scan & SCAN_PAGE))
5443432df05eSJohan Hedberg 		return;
5444432df05eSJohan Hedberg 
5445432df05eSJohan Hedberg 	if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
5446432df05eSJohan Hedberg 		scan |= SCAN_INQUIRY;
5447432df05eSJohan Hedberg 
5448432df05eSJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
54491d2dc5b7SJohan Hedberg }
54501d2dc5b7SJohan Hedberg 
54511d2dc5b7SJohan Hedberg void hci_update_page_scan(struct hci_dev *hdev)
54521d2dc5b7SJohan Hedberg {
54531d2dc5b7SJohan Hedberg 	struct hci_request req;
54541d2dc5b7SJohan Hedberg 
54551d2dc5b7SJohan Hedberg 	hci_req_init(&req, hdev);
54561d2dc5b7SJohan Hedberg 	__hci_update_page_scan(&req);
54571d2dc5b7SJohan Hedberg 	hci_req_run(&req, NULL);
5458432df05eSJohan Hedberg }
5459