xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 40f4938a)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds    BlueZ - Bluetooth protocol stack for Linux
31da177e4SLinus Torvalds    Copyright (C) 2000-2001 Qualcomm Incorporated
4590051deSGustavo F. Padovan    Copyright (C) 2011 ProFUSION Embedded Systems
51da177e4SLinus Torvalds 
61da177e4SLinus Torvalds    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
71da177e4SLinus Torvalds 
81da177e4SLinus Torvalds    This program is free software; you can redistribute it and/or modify
91da177e4SLinus Torvalds    it under the terms of the GNU General Public License version 2 as
101da177e4SLinus Torvalds    published by the Free Software Foundation;
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
131da177e4SLinus Torvalds    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
141da177e4SLinus Torvalds    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
151da177e4SLinus Torvalds    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
161da177e4SLinus Torvalds    CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
171da177e4SLinus Torvalds    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
181da177e4SLinus Torvalds    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
191da177e4SLinus Torvalds    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
201da177e4SLinus Torvalds 
211da177e4SLinus Torvalds    ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
221da177e4SLinus Torvalds    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
231da177e4SLinus Torvalds    SOFTWARE IS DISCLAIMED.
241da177e4SLinus Torvalds */
251da177e4SLinus Torvalds 
261da177e4SLinus Torvalds /* Bluetooth HCI core. */
271da177e4SLinus Torvalds 
288c520a59SGustavo Padovan #include <linux/export.h>
293df92b31SSasha Levin #include <linux/idr.h>
30611b30f7SMarcel Holtmann #include <linux/rfkill.h>
31baf27f6eSMarcel Holtmann #include <linux/debugfs.h>
3299780a7bSJohan Hedberg #include <linux/crypto.h>
3347219839SMarcel Holtmann #include <asm/unaligned.h>
341da177e4SLinus Torvalds 
351da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
361da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
374bc58f51SJohan Hedberg #include <net/bluetooth/l2cap.h>
38af58925cSMarcel Holtmann #include <net/bluetooth/mgmt.h>
391da177e4SLinus Torvalds 
40970c4e46SJohan Hedberg #include "smp.h"
41970c4e46SJohan Hedberg 
42b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work);
43c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work);
443eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work);
451da177e4SLinus Torvalds 
461da177e4SLinus Torvalds /* HCI device list */
471da177e4SLinus Torvalds LIST_HEAD(hci_dev_list);
481da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock);
491da177e4SLinus Torvalds 
501da177e4SLinus Torvalds /* HCI callback list */
511da177e4SLinus Torvalds LIST_HEAD(hci_cb_list);
521da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock);
531da177e4SLinus Torvalds 
543df92b31SSasha Levin /* HCI ID Numbering */
553df92b31SSasha Levin static DEFINE_IDA(hci_index_ida);
563df92b31SSasha Levin 
57899de765SMarcel Holtmann /* ----- HCI requests ----- */
58899de765SMarcel Holtmann 
59899de765SMarcel Holtmann #define HCI_REQ_DONE	  0
60899de765SMarcel Holtmann #define HCI_REQ_PEND	  1
61899de765SMarcel Holtmann #define HCI_REQ_CANCELED  2
62899de765SMarcel Holtmann 
63899de765SMarcel Holtmann #define hci_req_lock(d)		mutex_lock(&d->req_lock)
64899de765SMarcel Holtmann #define hci_req_unlock(d)	mutex_unlock(&d->req_lock)
65899de765SMarcel Holtmann 
661da177e4SLinus Torvalds /* ---- HCI notifications ---- */
671da177e4SLinus Torvalds 
686516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event)
691da177e4SLinus Torvalds {
70040030efSMarcel Holtmann 	hci_sock_dev_event(hdev, event);
711da177e4SLinus Torvalds }
721da177e4SLinus Torvalds 
73baf27f6eSMarcel Holtmann /* ---- HCI debugfs entries ---- */
74baf27f6eSMarcel Holtmann 
754b4148e9SMarcel Holtmann static ssize_t dut_mode_read(struct file *file, char __user *user_buf,
764b4148e9SMarcel Holtmann 			     size_t count, loff_t *ppos)
774b4148e9SMarcel Holtmann {
784b4148e9SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
794b4148e9SMarcel Holtmann 	char buf[3];
804b4148e9SMarcel Holtmann 
81111902f7SMarcel Holtmann 	buf[0] = test_bit(HCI_DUT_MODE, &hdev->dbg_flags) ? 'Y': 'N';
824b4148e9SMarcel Holtmann 	buf[1] = '\n';
834b4148e9SMarcel Holtmann 	buf[2] = '\0';
844b4148e9SMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
854b4148e9SMarcel Holtmann }
864b4148e9SMarcel Holtmann 
874b4148e9SMarcel Holtmann static ssize_t dut_mode_write(struct file *file, const char __user *user_buf,
884b4148e9SMarcel Holtmann 			      size_t count, loff_t *ppos)
894b4148e9SMarcel Holtmann {
904b4148e9SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
914b4148e9SMarcel Holtmann 	struct sk_buff *skb;
924b4148e9SMarcel Holtmann 	char buf[32];
934b4148e9SMarcel Holtmann 	size_t buf_size = min(count, (sizeof(buf)-1));
944b4148e9SMarcel Holtmann 	bool enable;
954b4148e9SMarcel Holtmann 	int err;
964b4148e9SMarcel Holtmann 
974b4148e9SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
984b4148e9SMarcel Holtmann 		return -ENETDOWN;
994b4148e9SMarcel Holtmann 
1004b4148e9SMarcel Holtmann 	if (copy_from_user(buf, user_buf, buf_size))
1014b4148e9SMarcel Holtmann 		return -EFAULT;
1024b4148e9SMarcel Holtmann 
1034b4148e9SMarcel Holtmann 	buf[buf_size] = '\0';
1044b4148e9SMarcel Holtmann 	if (strtobool(buf, &enable))
1054b4148e9SMarcel Holtmann 		return -EINVAL;
1064b4148e9SMarcel Holtmann 
107111902f7SMarcel Holtmann 	if (enable == test_bit(HCI_DUT_MODE, &hdev->dbg_flags))
1084b4148e9SMarcel Holtmann 		return -EALREADY;
1094b4148e9SMarcel Holtmann 
1104b4148e9SMarcel Holtmann 	hci_req_lock(hdev);
1114b4148e9SMarcel Holtmann 	if (enable)
1124b4148e9SMarcel Holtmann 		skb = __hci_cmd_sync(hdev, HCI_OP_ENABLE_DUT_MODE, 0, NULL,
1134b4148e9SMarcel Holtmann 				     HCI_CMD_TIMEOUT);
1144b4148e9SMarcel Holtmann 	else
1154b4148e9SMarcel Holtmann 		skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL,
1164b4148e9SMarcel Holtmann 				     HCI_CMD_TIMEOUT);
1174b4148e9SMarcel Holtmann 	hci_req_unlock(hdev);
1184b4148e9SMarcel Holtmann 
1194b4148e9SMarcel Holtmann 	if (IS_ERR(skb))
1204b4148e9SMarcel Holtmann 		return PTR_ERR(skb);
1214b4148e9SMarcel Holtmann 
1224b4148e9SMarcel Holtmann 	err = -bt_to_errno(skb->data[0]);
1234b4148e9SMarcel Holtmann 	kfree_skb(skb);
1244b4148e9SMarcel Holtmann 
1254b4148e9SMarcel Holtmann 	if (err < 0)
1264b4148e9SMarcel Holtmann 		return err;
1274b4148e9SMarcel Holtmann 
128111902f7SMarcel Holtmann 	change_bit(HCI_DUT_MODE, &hdev->dbg_flags);
1294b4148e9SMarcel Holtmann 
1304b4148e9SMarcel Holtmann 	return count;
1314b4148e9SMarcel Holtmann }
1324b4148e9SMarcel Holtmann 
1334b4148e9SMarcel Holtmann static const struct file_operations dut_mode_fops = {
1344b4148e9SMarcel Holtmann 	.open		= simple_open,
1354b4148e9SMarcel Holtmann 	.read		= dut_mode_read,
1364b4148e9SMarcel Holtmann 	.write		= dut_mode_write,
1374b4148e9SMarcel Holtmann 	.llseek		= default_llseek,
1384b4148e9SMarcel Holtmann };
1394b4148e9SMarcel Holtmann 
140dfb826a8SMarcel Holtmann static int features_show(struct seq_file *f, void *ptr)
141dfb826a8SMarcel Holtmann {
142dfb826a8SMarcel Holtmann 	struct hci_dev *hdev = f->private;
143dfb826a8SMarcel Holtmann 	u8 p;
144dfb826a8SMarcel Holtmann 
145dfb826a8SMarcel Holtmann 	hci_dev_lock(hdev);
146dfb826a8SMarcel Holtmann 	for (p = 0; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
147cfbb2b5bSMarcel Holtmann 		seq_printf(f, "%2u: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
148dfb826a8SMarcel Holtmann 			   "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", p,
149dfb826a8SMarcel Holtmann 			   hdev->features[p][0], hdev->features[p][1],
150dfb826a8SMarcel Holtmann 			   hdev->features[p][2], hdev->features[p][3],
151dfb826a8SMarcel Holtmann 			   hdev->features[p][4], hdev->features[p][5],
152dfb826a8SMarcel Holtmann 			   hdev->features[p][6], hdev->features[p][7]);
153dfb826a8SMarcel Holtmann 	}
154cfbb2b5bSMarcel Holtmann 	if (lmp_le_capable(hdev))
155cfbb2b5bSMarcel Holtmann 		seq_printf(f, "LE: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
156cfbb2b5bSMarcel Holtmann 			   "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n",
157cfbb2b5bSMarcel Holtmann 			   hdev->le_features[0], hdev->le_features[1],
158cfbb2b5bSMarcel Holtmann 			   hdev->le_features[2], hdev->le_features[3],
159cfbb2b5bSMarcel Holtmann 			   hdev->le_features[4], hdev->le_features[5],
160cfbb2b5bSMarcel Holtmann 			   hdev->le_features[6], hdev->le_features[7]);
161dfb826a8SMarcel Holtmann 	hci_dev_unlock(hdev);
162dfb826a8SMarcel Holtmann 
163dfb826a8SMarcel Holtmann 	return 0;
164dfb826a8SMarcel Holtmann }
165dfb826a8SMarcel Holtmann 
166dfb826a8SMarcel Holtmann static int features_open(struct inode *inode, struct file *file)
167dfb826a8SMarcel Holtmann {
168dfb826a8SMarcel Holtmann 	return single_open(file, features_show, inode->i_private);
169dfb826a8SMarcel Holtmann }
170dfb826a8SMarcel Holtmann 
171dfb826a8SMarcel Holtmann static const struct file_operations features_fops = {
172dfb826a8SMarcel Holtmann 	.open		= features_open,
173dfb826a8SMarcel Holtmann 	.read		= seq_read,
174dfb826a8SMarcel Holtmann 	.llseek		= seq_lseek,
175dfb826a8SMarcel Holtmann 	.release	= single_release,
176dfb826a8SMarcel Holtmann };
177dfb826a8SMarcel Holtmann 
17870afe0b8SMarcel Holtmann static int blacklist_show(struct seq_file *f, void *p)
17970afe0b8SMarcel Holtmann {
18070afe0b8SMarcel Holtmann 	struct hci_dev *hdev = f->private;
18170afe0b8SMarcel Holtmann 	struct bdaddr_list *b;
18270afe0b8SMarcel Holtmann 
18370afe0b8SMarcel Holtmann 	hci_dev_lock(hdev);
18470afe0b8SMarcel Holtmann 	list_for_each_entry(b, &hdev->blacklist, list)
185b25f0785SMarcel Holtmann 		seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type);
18670afe0b8SMarcel Holtmann 	hci_dev_unlock(hdev);
18770afe0b8SMarcel Holtmann 
18870afe0b8SMarcel Holtmann 	return 0;
18970afe0b8SMarcel Holtmann }
19070afe0b8SMarcel Holtmann 
19170afe0b8SMarcel Holtmann static int blacklist_open(struct inode *inode, struct file *file)
19270afe0b8SMarcel Holtmann {
19370afe0b8SMarcel Holtmann 	return single_open(file, blacklist_show, inode->i_private);
19470afe0b8SMarcel Holtmann }
19570afe0b8SMarcel Holtmann 
19670afe0b8SMarcel Holtmann static const struct file_operations blacklist_fops = {
19770afe0b8SMarcel Holtmann 	.open		= blacklist_open,
19870afe0b8SMarcel Holtmann 	.read		= seq_read,
19970afe0b8SMarcel Holtmann 	.llseek		= seq_lseek,
20070afe0b8SMarcel Holtmann 	.release	= single_release,
20170afe0b8SMarcel Holtmann };
20270afe0b8SMarcel Holtmann 
20347219839SMarcel Holtmann static int uuids_show(struct seq_file *f, void *p)
20447219839SMarcel Holtmann {
20547219839SMarcel Holtmann 	struct hci_dev *hdev = f->private;
20647219839SMarcel Holtmann 	struct bt_uuid *uuid;
20747219839SMarcel Holtmann 
20847219839SMarcel Holtmann 	hci_dev_lock(hdev);
20947219839SMarcel Holtmann 	list_for_each_entry(uuid, &hdev->uuids, list) {
21058f01aa9SMarcel Holtmann 		u8 i, val[16];
21147219839SMarcel Holtmann 
21258f01aa9SMarcel Holtmann 		/* The Bluetooth UUID values are stored in big endian,
21358f01aa9SMarcel Holtmann 		 * but with reversed byte order. So convert them into
21458f01aa9SMarcel Holtmann 		 * the right order for the %pUb modifier.
21558f01aa9SMarcel Holtmann 		 */
21658f01aa9SMarcel Holtmann 		for (i = 0; i < 16; i++)
21758f01aa9SMarcel Holtmann 			val[i] = uuid->uuid[15 - i];
21847219839SMarcel Holtmann 
21958f01aa9SMarcel Holtmann 		seq_printf(f, "%pUb\n", val);
22047219839SMarcel Holtmann 	}
22147219839SMarcel Holtmann 	hci_dev_unlock(hdev);
22247219839SMarcel Holtmann 
22347219839SMarcel Holtmann 	return 0;
22447219839SMarcel Holtmann }
22547219839SMarcel Holtmann 
22647219839SMarcel Holtmann static int uuids_open(struct inode *inode, struct file *file)
22747219839SMarcel Holtmann {
22847219839SMarcel Holtmann 	return single_open(file, uuids_show, inode->i_private);
22947219839SMarcel Holtmann }
23047219839SMarcel Holtmann 
23147219839SMarcel Holtmann static const struct file_operations uuids_fops = {
23247219839SMarcel Holtmann 	.open		= uuids_open,
23347219839SMarcel Holtmann 	.read		= seq_read,
23447219839SMarcel Holtmann 	.llseek		= seq_lseek,
23547219839SMarcel Holtmann 	.release	= single_release,
23647219839SMarcel Holtmann };
23747219839SMarcel Holtmann 
238baf27f6eSMarcel Holtmann static int inquiry_cache_show(struct seq_file *f, void *p)
239baf27f6eSMarcel Holtmann {
240baf27f6eSMarcel Holtmann 	struct hci_dev *hdev = f->private;
241baf27f6eSMarcel Holtmann 	struct discovery_state *cache = &hdev->discovery;
242baf27f6eSMarcel Holtmann 	struct inquiry_entry *e;
243baf27f6eSMarcel Holtmann 
244baf27f6eSMarcel Holtmann 	hci_dev_lock(hdev);
245baf27f6eSMarcel Holtmann 
246baf27f6eSMarcel Holtmann 	list_for_each_entry(e, &cache->all, all) {
247baf27f6eSMarcel Holtmann 		struct inquiry_data *data = &e->data;
248baf27f6eSMarcel Holtmann 		seq_printf(f, "%pMR %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n",
249baf27f6eSMarcel Holtmann 			   &data->bdaddr,
250baf27f6eSMarcel Holtmann 			   data->pscan_rep_mode, data->pscan_period_mode,
251baf27f6eSMarcel Holtmann 			   data->pscan_mode, data->dev_class[2],
252baf27f6eSMarcel Holtmann 			   data->dev_class[1], data->dev_class[0],
253baf27f6eSMarcel Holtmann 			   __le16_to_cpu(data->clock_offset),
254baf27f6eSMarcel Holtmann 			   data->rssi, data->ssp_mode, e->timestamp);
255baf27f6eSMarcel Holtmann 	}
256baf27f6eSMarcel Holtmann 
257baf27f6eSMarcel Holtmann 	hci_dev_unlock(hdev);
258baf27f6eSMarcel Holtmann 
259baf27f6eSMarcel Holtmann 	return 0;
260baf27f6eSMarcel Holtmann }
261baf27f6eSMarcel Holtmann 
262baf27f6eSMarcel Holtmann static int inquiry_cache_open(struct inode *inode, struct file *file)
263baf27f6eSMarcel Holtmann {
264baf27f6eSMarcel Holtmann 	return single_open(file, inquiry_cache_show, inode->i_private);
265baf27f6eSMarcel Holtmann }
266baf27f6eSMarcel Holtmann 
267baf27f6eSMarcel Holtmann static const struct file_operations inquiry_cache_fops = {
268baf27f6eSMarcel Holtmann 	.open		= inquiry_cache_open,
269baf27f6eSMarcel Holtmann 	.read		= seq_read,
270baf27f6eSMarcel Holtmann 	.llseek		= seq_lseek,
271baf27f6eSMarcel Holtmann 	.release	= single_release,
272baf27f6eSMarcel Holtmann };
273baf27f6eSMarcel Holtmann 
27402d08d15SMarcel Holtmann static int link_keys_show(struct seq_file *f, void *ptr)
27502d08d15SMarcel Holtmann {
27602d08d15SMarcel Holtmann 	struct hci_dev *hdev = f->private;
27702d08d15SMarcel Holtmann 	struct list_head *p, *n;
27802d08d15SMarcel Holtmann 
27902d08d15SMarcel Holtmann 	hci_dev_lock(hdev);
28002d08d15SMarcel Holtmann 	list_for_each_safe(p, n, &hdev->link_keys) {
28102d08d15SMarcel Holtmann 		struct link_key *key = list_entry(p, struct link_key, 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);
28402d08d15SMarcel Holtmann 	}
28502d08d15SMarcel Holtmann 	hci_dev_unlock(hdev);
28602d08d15SMarcel Holtmann 
28702d08d15SMarcel Holtmann 	return 0;
28802d08d15SMarcel Holtmann }
28902d08d15SMarcel Holtmann 
29002d08d15SMarcel Holtmann static int link_keys_open(struct inode *inode, struct file *file)
29102d08d15SMarcel Holtmann {
29202d08d15SMarcel Holtmann 	return single_open(file, link_keys_show, inode->i_private);
29302d08d15SMarcel Holtmann }
29402d08d15SMarcel Holtmann 
29502d08d15SMarcel Holtmann static const struct file_operations link_keys_fops = {
29602d08d15SMarcel Holtmann 	.open		= link_keys_open,
29702d08d15SMarcel Holtmann 	.read		= seq_read,
29802d08d15SMarcel Holtmann 	.llseek		= seq_lseek,
29902d08d15SMarcel Holtmann 	.release	= single_release,
30002d08d15SMarcel Holtmann };
30102d08d15SMarcel Holtmann 
302babdbb3cSMarcel Holtmann static int dev_class_show(struct seq_file *f, void *ptr)
303babdbb3cSMarcel Holtmann {
304babdbb3cSMarcel Holtmann 	struct hci_dev *hdev = f->private;
305babdbb3cSMarcel Holtmann 
306babdbb3cSMarcel Holtmann 	hci_dev_lock(hdev);
307babdbb3cSMarcel Holtmann 	seq_printf(f, "0x%.2x%.2x%.2x\n", hdev->dev_class[2],
308babdbb3cSMarcel Holtmann 		   hdev->dev_class[1], hdev->dev_class[0]);
309babdbb3cSMarcel Holtmann 	hci_dev_unlock(hdev);
310babdbb3cSMarcel Holtmann 
311babdbb3cSMarcel Holtmann 	return 0;
312babdbb3cSMarcel Holtmann }
313babdbb3cSMarcel Holtmann 
314babdbb3cSMarcel Holtmann static int dev_class_open(struct inode *inode, struct file *file)
315babdbb3cSMarcel Holtmann {
316babdbb3cSMarcel Holtmann 	return single_open(file, dev_class_show, inode->i_private);
317babdbb3cSMarcel Holtmann }
318babdbb3cSMarcel Holtmann 
319babdbb3cSMarcel Holtmann static const struct file_operations dev_class_fops = {
320babdbb3cSMarcel Holtmann 	.open		= dev_class_open,
321babdbb3cSMarcel Holtmann 	.read		= seq_read,
322babdbb3cSMarcel Holtmann 	.llseek		= seq_lseek,
323babdbb3cSMarcel Holtmann 	.release	= single_release,
324babdbb3cSMarcel Holtmann };
325babdbb3cSMarcel Holtmann 
326041000b9SMarcel Holtmann static int voice_setting_get(void *data, u64 *val)
327041000b9SMarcel Holtmann {
328041000b9SMarcel Holtmann 	struct hci_dev *hdev = data;
329041000b9SMarcel Holtmann 
330041000b9SMarcel Holtmann 	hci_dev_lock(hdev);
331041000b9SMarcel Holtmann 	*val = hdev->voice_setting;
332041000b9SMarcel Holtmann 	hci_dev_unlock(hdev);
333041000b9SMarcel Holtmann 
334041000b9SMarcel Holtmann 	return 0;
335041000b9SMarcel Holtmann }
336041000b9SMarcel Holtmann 
337041000b9SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(voice_setting_fops, voice_setting_get,
338041000b9SMarcel Holtmann 			NULL, "0x%4.4llx\n");
339041000b9SMarcel Holtmann 
340ebd1e33bSMarcel Holtmann static int auto_accept_delay_set(void *data, u64 val)
341ebd1e33bSMarcel Holtmann {
342ebd1e33bSMarcel Holtmann 	struct hci_dev *hdev = data;
343ebd1e33bSMarcel Holtmann 
344ebd1e33bSMarcel Holtmann 	hci_dev_lock(hdev);
345ebd1e33bSMarcel Holtmann 	hdev->auto_accept_delay = val;
346ebd1e33bSMarcel Holtmann 	hci_dev_unlock(hdev);
347ebd1e33bSMarcel Holtmann 
348ebd1e33bSMarcel Holtmann 	return 0;
349ebd1e33bSMarcel Holtmann }
350ebd1e33bSMarcel Holtmann 
351ebd1e33bSMarcel Holtmann static int auto_accept_delay_get(void *data, u64 *val)
352ebd1e33bSMarcel Holtmann {
353ebd1e33bSMarcel Holtmann 	struct hci_dev *hdev = data;
354ebd1e33bSMarcel Holtmann 
355ebd1e33bSMarcel Holtmann 	hci_dev_lock(hdev);
356ebd1e33bSMarcel Holtmann 	*val = hdev->auto_accept_delay;
357ebd1e33bSMarcel Holtmann 	hci_dev_unlock(hdev);
358ebd1e33bSMarcel Holtmann 
359ebd1e33bSMarcel Holtmann 	return 0;
360ebd1e33bSMarcel Holtmann }
361ebd1e33bSMarcel Holtmann 
362ebd1e33bSMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get,
363ebd1e33bSMarcel Holtmann 			auto_accept_delay_set, "%llu\n");
364ebd1e33bSMarcel Holtmann 
3655afeac14SMarcel Holtmann static ssize_t force_sc_support_read(struct file *file, char __user *user_buf,
3665afeac14SMarcel Holtmann 				     size_t count, loff_t *ppos)
3675afeac14SMarcel Holtmann {
3685afeac14SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
3695afeac14SMarcel Holtmann 	char buf[3];
3705afeac14SMarcel Holtmann 
371111902f7SMarcel Holtmann 	buf[0] = test_bit(HCI_FORCE_SC, &hdev->dbg_flags) ? 'Y': 'N';
3725afeac14SMarcel Holtmann 	buf[1] = '\n';
3735afeac14SMarcel Holtmann 	buf[2] = '\0';
3745afeac14SMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
3755afeac14SMarcel Holtmann }
3765afeac14SMarcel Holtmann 
3775afeac14SMarcel Holtmann static ssize_t force_sc_support_write(struct file *file,
3785afeac14SMarcel Holtmann 				      const char __user *user_buf,
3795afeac14SMarcel Holtmann 				      size_t count, loff_t *ppos)
3805afeac14SMarcel Holtmann {
3815afeac14SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
3825afeac14SMarcel Holtmann 	char buf[32];
3835afeac14SMarcel Holtmann 	size_t buf_size = min(count, (sizeof(buf)-1));
3845afeac14SMarcel Holtmann 	bool enable;
3855afeac14SMarcel Holtmann 
3865afeac14SMarcel Holtmann 	if (test_bit(HCI_UP, &hdev->flags))
3875afeac14SMarcel Holtmann 		return -EBUSY;
3885afeac14SMarcel Holtmann 
3895afeac14SMarcel Holtmann 	if (copy_from_user(buf, user_buf, buf_size))
3905afeac14SMarcel Holtmann 		return -EFAULT;
3915afeac14SMarcel Holtmann 
3925afeac14SMarcel Holtmann 	buf[buf_size] = '\0';
3935afeac14SMarcel Holtmann 	if (strtobool(buf, &enable))
3945afeac14SMarcel Holtmann 		return -EINVAL;
3955afeac14SMarcel Holtmann 
396111902f7SMarcel Holtmann 	if (enable == test_bit(HCI_FORCE_SC, &hdev->dbg_flags))
3975afeac14SMarcel Holtmann 		return -EALREADY;
3985afeac14SMarcel Holtmann 
399111902f7SMarcel Holtmann 	change_bit(HCI_FORCE_SC, &hdev->dbg_flags);
4005afeac14SMarcel Holtmann 
4015afeac14SMarcel Holtmann 	return count;
4025afeac14SMarcel Holtmann }
4035afeac14SMarcel Holtmann 
4045afeac14SMarcel Holtmann static const struct file_operations force_sc_support_fops = {
4055afeac14SMarcel Holtmann 	.open		= simple_open,
4065afeac14SMarcel Holtmann 	.read		= force_sc_support_read,
4075afeac14SMarcel Holtmann 	.write		= force_sc_support_write,
4085afeac14SMarcel Holtmann 	.llseek		= default_llseek,
4095afeac14SMarcel Holtmann };
4105afeac14SMarcel Holtmann 
411134c2a89SMarcel Holtmann static ssize_t sc_only_mode_read(struct file *file, char __user *user_buf,
412134c2a89SMarcel Holtmann 				 size_t count, loff_t *ppos)
413134c2a89SMarcel Holtmann {
414134c2a89SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
415134c2a89SMarcel Holtmann 	char buf[3];
416134c2a89SMarcel Holtmann 
417134c2a89SMarcel Holtmann 	buf[0] = test_bit(HCI_SC_ONLY, &hdev->dev_flags) ? 'Y': 'N';
418134c2a89SMarcel Holtmann 	buf[1] = '\n';
419134c2a89SMarcel Holtmann 	buf[2] = '\0';
420134c2a89SMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
421134c2a89SMarcel Holtmann }
422134c2a89SMarcel Holtmann 
423134c2a89SMarcel Holtmann static const struct file_operations sc_only_mode_fops = {
424134c2a89SMarcel Holtmann 	.open		= simple_open,
425134c2a89SMarcel Holtmann 	.read		= sc_only_mode_read,
426134c2a89SMarcel Holtmann 	.llseek		= default_llseek,
427134c2a89SMarcel Holtmann };
428134c2a89SMarcel Holtmann 
4292bfa3531SMarcel Holtmann static int idle_timeout_set(void *data, u64 val)
4302bfa3531SMarcel Holtmann {
4312bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
4322bfa3531SMarcel Holtmann 
4332bfa3531SMarcel Holtmann 	if (val != 0 && (val < 500 || val > 3600000))
4342bfa3531SMarcel Holtmann 		return -EINVAL;
4352bfa3531SMarcel Holtmann 
4362bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
4372bfa3531SMarcel Holtmann 	hdev->idle_timeout = val;
4382bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
4392bfa3531SMarcel Holtmann 
4402bfa3531SMarcel Holtmann 	return 0;
4412bfa3531SMarcel Holtmann }
4422bfa3531SMarcel Holtmann 
4432bfa3531SMarcel Holtmann static int idle_timeout_get(void *data, u64 *val)
4442bfa3531SMarcel Holtmann {
4452bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
4462bfa3531SMarcel Holtmann 
4472bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
4482bfa3531SMarcel Holtmann 	*val = hdev->idle_timeout;
4492bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
4502bfa3531SMarcel Holtmann 
4512bfa3531SMarcel Holtmann 	return 0;
4522bfa3531SMarcel Holtmann }
4532bfa3531SMarcel Holtmann 
4542bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(idle_timeout_fops, idle_timeout_get,
4552bfa3531SMarcel Holtmann 			idle_timeout_set, "%llu\n");
4562bfa3531SMarcel Holtmann 
457c982b2eaSJohan Hedberg static int rpa_timeout_set(void *data, u64 val)
458c982b2eaSJohan Hedberg {
459c982b2eaSJohan Hedberg 	struct hci_dev *hdev = data;
460c982b2eaSJohan Hedberg 
461c982b2eaSJohan Hedberg 	/* Require the RPA timeout to be at least 30 seconds and at most
462c982b2eaSJohan Hedberg 	 * 24 hours.
463c982b2eaSJohan Hedberg 	 */
464c982b2eaSJohan Hedberg 	if (val < 30 || val > (60 * 60 * 24))
465c982b2eaSJohan Hedberg 		return -EINVAL;
466c982b2eaSJohan Hedberg 
467c982b2eaSJohan Hedberg 	hci_dev_lock(hdev);
468c982b2eaSJohan Hedberg 	hdev->rpa_timeout = val;
469c982b2eaSJohan Hedberg 	hci_dev_unlock(hdev);
470c982b2eaSJohan Hedberg 
471c982b2eaSJohan Hedberg 	return 0;
472c982b2eaSJohan Hedberg }
473c982b2eaSJohan Hedberg 
474c982b2eaSJohan Hedberg static int rpa_timeout_get(void *data, u64 *val)
475c982b2eaSJohan Hedberg {
476c982b2eaSJohan Hedberg 	struct hci_dev *hdev = data;
477c982b2eaSJohan Hedberg 
478c982b2eaSJohan Hedberg 	hci_dev_lock(hdev);
479c982b2eaSJohan Hedberg 	*val = hdev->rpa_timeout;
480c982b2eaSJohan Hedberg 	hci_dev_unlock(hdev);
481c982b2eaSJohan Hedberg 
482c982b2eaSJohan Hedberg 	return 0;
483c982b2eaSJohan Hedberg }
484c982b2eaSJohan Hedberg 
485c982b2eaSJohan Hedberg DEFINE_SIMPLE_ATTRIBUTE(rpa_timeout_fops, rpa_timeout_get,
486c982b2eaSJohan Hedberg 			rpa_timeout_set, "%llu\n");
487c982b2eaSJohan Hedberg 
4882bfa3531SMarcel Holtmann static int sniff_min_interval_set(void *data, u64 val)
4892bfa3531SMarcel Holtmann {
4902bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
4912bfa3531SMarcel Holtmann 
4922bfa3531SMarcel Holtmann 	if (val == 0 || val % 2 || val > hdev->sniff_max_interval)
4932bfa3531SMarcel Holtmann 		return -EINVAL;
4942bfa3531SMarcel Holtmann 
4952bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
4962bfa3531SMarcel Holtmann 	hdev->sniff_min_interval = val;
4972bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
4982bfa3531SMarcel Holtmann 
4992bfa3531SMarcel Holtmann 	return 0;
5002bfa3531SMarcel Holtmann }
5012bfa3531SMarcel Holtmann 
5022bfa3531SMarcel Holtmann static int sniff_min_interval_get(void *data, u64 *val)
5032bfa3531SMarcel Holtmann {
5042bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
5052bfa3531SMarcel Holtmann 
5062bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5072bfa3531SMarcel Holtmann 	*val = hdev->sniff_min_interval;
5082bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5092bfa3531SMarcel Holtmann 
5102bfa3531SMarcel Holtmann 	return 0;
5112bfa3531SMarcel Holtmann }
5122bfa3531SMarcel Holtmann 
5132bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_min_interval_fops, sniff_min_interval_get,
5142bfa3531SMarcel Holtmann 			sniff_min_interval_set, "%llu\n");
5152bfa3531SMarcel Holtmann 
5162bfa3531SMarcel Holtmann static int sniff_max_interval_set(void *data, u64 val)
5172bfa3531SMarcel Holtmann {
5182bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
5192bfa3531SMarcel Holtmann 
5202bfa3531SMarcel Holtmann 	if (val == 0 || val % 2 || val < hdev->sniff_min_interval)
5212bfa3531SMarcel Holtmann 		return -EINVAL;
5222bfa3531SMarcel Holtmann 
5232bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5242bfa3531SMarcel Holtmann 	hdev->sniff_max_interval = val;
5252bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5262bfa3531SMarcel Holtmann 
5272bfa3531SMarcel Holtmann 	return 0;
5282bfa3531SMarcel Holtmann }
5292bfa3531SMarcel Holtmann 
5302bfa3531SMarcel Holtmann static int sniff_max_interval_get(void *data, u64 *val)
5312bfa3531SMarcel Holtmann {
5322bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
5332bfa3531SMarcel Holtmann 
5342bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5352bfa3531SMarcel Holtmann 	*val = hdev->sniff_max_interval;
5362bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5372bfa3531SMarcel Holtmann 
5382bfa3531SMarcel Holtmann 	return 0;
5392bfa3531SMarcel Holtmann }
5402bfa3531SMarcel Holtmann 
5412bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_max_interval_fops, sniff_max_interval_get,
5422bfa3531SMarcel Holtmann 			sniff_max_interval_set, "%llu\n");
5432bfa3531SMarcel Holtmann 
54431ad1691SAndrzej Kaczmarek static int conn_info_min_age_set(void *data, u64 val)
54531ad1691SAndrzej Kaczmarek {
54631ad1691SAndrzej Kaczmarek 	struct hci_dev *hdev = data;
54731ad1691SAndrzej Kaczmarek 
54831ad1691SAndrzej Kaczmarek 	if (val == 0 || val > hdev->conn_info_max_age)
54931ad1691SAndrzej Kaczmarek 		return -EINVAL;
55031ad1691SAndrzej Kaczmarek 
55131ad1691SAndrzej Kaczmarek 	hci_dev_lock(hdev);
55231ad1691SAndrzej Kaczmarek 	hdev->conn_info_min_age = val;
55331ad1691SAndrzej Kaczmarek 	hci_dev_unlock(hdev);
55431ad1691SAndrzej Kaczmarek 
55531ad1691SAndrzej Kaczmarek 	return 0;
55631ad1691SAndrzej Kaczmarek }
55731ad1691SAndrzej Kaczmarek 
55831ad1691SAndrzej Kaczmarek static int conn_info_min_age_get(void *data, u64 *val)
55931ad1691SAndrzej Kaczmarek {
56031ad1691SAndrzej Kaczmarek 	struct hci_dev *hdev = data;
56131ad1691SAndrzej Kaczmarek 
56231ad1691SAndrzej Kaczmarek 	hci_dev_lock(hdev);
56331ad1691SAndrzej Kaczmarek 	*val = hdev->conn_info_min_age;
56431ad1691SAndrzej Kaczmarek 	hci_dev_unlock(hdev);
56531ad1691SAndrzej Kaczmarek 
56631ad1691SAndrzej Kaczmarek 	return 0;
56731ad1691SAndrzej Kaczmarek }
56831ad1691SAndrzej Kaczmarek 
56931ad1691SAndrzej Kaczmarek DEFINE_SIMPLE_ATTRIBUTE(conn_info_min_age_fops, conn_info_min_age_get,
57031ad1691SAndrzej Kaczmarek 			conn_info_min_age_set, "%llu\n");
57131ad1691SAndrzej Kaczmarek 
57231ad1691SAndrzej Kaczmarek static int conn_info_max_age_set(void *data, u64 val)
57331ad1691SAndrzej Kaczmarek {
57431ad1691SAndrzej Kaczmarek 	struct hci_dev *hdev = data;
57531ad1691SAndrzej Kaczmarek 
57631ad1691SAndrzej Kaczmarek 	if (val == 0 || val < hdev->conn_info_min_age)
57731ad1691SAndrzej Kaczmarek 		return -EINVAL;
57831ad1691SAndrzej Kaczmarek 
57931ad1691SAndrzej Kaczmarek 	hci_dev_lock(hdev);
58031ad1691SAndrzej Kaczmarek 	hdev->conn_info_max_age = val;
58131ad1691SAndrzej Kaczmarek 	hci_dev_unlock(hdev);
58231ad1691SAndrzej Kaczmarek 
58331ad1691SAndrzej Kaczmarek 	return 0;
58431ad1691SAndrzej Kaczmarek }
58531ad1691SAndrzej Kaczmarek 
58631ad1691SAndrzej Kaczmarek static int conn_info_max_age_get(void *data, u64 *val)
58731ad1691SAndrzej Kaczmarek {
58831ad1691SAndrzej Kaczmarek 	struct hci_dev *hdev = data;
58931ad1691SAndrzej Kaczmarek 
59031ad1691SAndrzej Kaczmarek 	hci_dev_lock(hdev);
59131ad1691SAndrzej Kaczmarek 	*val = hdev->conn_info_max_age;
59231ad1691SAndrzej Kaczmarek 	hci_dev_unlock(hdev);
59331ad1691SAndrzej Kaczmarek 
59431ad1691SAndrzej Kaczmarek 	return 0;
59531ad1691SAndrzej Kaczmarek }
59631ad1691SAndrzej Kaczmarek 
59731ad1691SAndrzej Kaczmarek DEFINE_SIMPLE_ATTRIBUTE(conn_info_max_age_fops, conn_info_max_age_get,
59831ad1691SAndrzej Kaczmarek 			conn_info_max_age_set, "%llu\n");
59931ad1691SAndrzej Kaczmarek 
600ac345813SMarcel Holtmann static int identity_show(struct seq_file *f, void *p)
601ac345813SMarcel Holtmann {
602ac345813SMarcel Holtmann 	struct hci_dev *hdev = f->private;
603a1f4c318SJohan Hedberg 	bdaddr_t addr;
604ac345813SMarcel Holtmann 	u8 addr_type;
605ac345813SMarcel Holtmann 
606ac345813SMarcel Holtmann 	hci_dev_lock(hdev);
607ac345813SMarcel Holtmann 
608a1f4c318SJohan Hedberg 	hci_copy_identity_address(hdev, &addr, &addr_type);
609ac345813SMarcel Holtmann 
610a1f4c318SJohan Hedberg 	seq_printf(f, "%pMR (type %u) %*phN %pMR\n", &addr, addr_type,
611473deef2SMarcel Holtmann 		   16, hdev->irk, &hdev->rpa);
612ac345813SMarcel Holtmann 
613ac345813SMarcel Holtmann 	hci_dev_unlock(hdev);
614ac345813SMarcel Holtmann 
615ac345813SMarcel Holtmann 	return 0;
616ac345813SMarcel Holtmann }
617ac345813SMarcel Holtmann 
618ac345813SMarcel Holtmann static int identity_open(struct inode *inode, struct file *file)
619ac345813SMarcel Holtmann {
620ac345813SMarcel Holtmann 	return single_open(file, identity_show, inode->i_private);
621ac345813SMarcel Holtmann }
622ac345813SMarcel Holtmann 
623ac345813SMarcel Holtmann static const struct file_operations identity_fops = {
624ac345813SMarcel Holtmann 	.open		= identity_open,
625ac345813SMarcel Holtmann 	.read		= seq_read,
626ac345813SMarcel Holtmann 	.llseek		= seq_lseek,
627ac345813SMarcel Holtmann 	.release	= single_release,
628ac345813SMarcel Holtmann };
629ac345813SMarcel Holtmann 
6307a4cd51dSMarcel Holtmann static int random_address_show(struct seq_file *f, void *p)
6317a4cd51dSMarcel Holtmann {
6327a4cd51dSMarcel Holtmann 	struct hci_dev *hdev = f->private;
6337a4cd51dSMarcel Holtmann 
6347a4cd51dSMarcel Holtmann 	hci_dev_lock(hdev);
6357a4cd51dSMarcel Holtmann 	seq_printf(f, "%pMR\n", &hdev->random_addr);
6367a4cd51dSMarcel Holtmann 	hci_dev_unlock(hdev);
6377a4cd51dSMarcel Holtmann 
6387a4cd51dSMarcel Holtmann 	return 0;
6397a4cd51dSMarcel Holtmann }
6407a4cd51dSMarcel Holtmann 
6417a4cd51dSMarcel Holtmann static int random_address_open(struct inode *inode, struct file *file)
6427a4cd51dSMarcel Holtmann {
6437a4cd51dSMarcel Holtmann 	return single_open(file, random_address_show, inode->i_private);
6447a4cd51dSMarcel Holtmann }
6457a4cd51dSMarcel Holtmann 
6467a4cd51dSMarcel Holtmann static const struct file_operations random_address_fops = {
6477a4cd51dSMarcel Holtmann 	.open		= random_address_open,
6487a4cd51dSMarcel Holtmann 	.read		= seq_read,
6497a4cd51dSMarcel Holtmann 	.llseek		= seq_lseek,
6507a4cd51dSMarcel Holtmann 	.release	= single_release,
6517a4cd51dSMarcel Holtmann };
6527a4cd51dSMarcel Holtmann 
653e7b8fc92SMarcel Holtmann static int static_address_show(struct seq_file *f, void *p)
654e7b8fc92SMarcel Holtmann {
655e7b8fc92SMarcel Holtmann 	struct hci_dev *hdev = f->private;
656e7b8fc92SMarcel Holtmann 
657e7b8fc92SMarcel Holtmann 	hci_dev_lock(hdev);
658e7b8fc92SMarcel Holtmann 	seq_printf(f, "%pMR\n", &hdev->static_addr);
659e7b8fc92SMarcel Holtmann 	hci_dev_unlock(hdev);
660e7b8fc92SMarcel Holtmann 
661e7b8fc92SMarcel Holtmann 	return 0;
662e7b8fc92SMarcel Holtmann }
663e7b8fc92SMarcel Holtmann 
664e7b8fc92SMarcel Holtmann static int static_address_open(struct inode *inode, struct file *file)
665e7b8fc92SMarcel Holtmann {
666e7b8fc92SMarcel Holtmann 	return single_open(file, static_address_show, inode->i_private);
667e7b8fc92SMarcel Holtmann }
668e7b8fc92SMarcel Holtmann 
669e7b8fc92SMarcel Holtmann static const struct file_operations static_address_fops = {
670e7b8fc92SMarcel Holtmann 	.open		= static_address_open,
671e7b8fc92SMarcel Holtmann 	.read		= seq_read,
672e7b8fc92SMarcel Holtmann 	.llseek		= seq_lseek,
673e7b8fc92SMarcel Holtmann 	.release	= single_release,
674e7b8fc92SMarcel Holtmann };
675e7b8fc92SMarcel Holtmann 
676b32bba6cSMarcel Holtmann static ssize_t force_static_address_read(struct file *file,
677b32bba6cSMarcel Holtmann 					 char __user *user_buf,
678b32bba6cSMarcel Holtmann 					 size_t count, loff_t *ppos)
67992202185SMarcel Holtmann {
680b32bba6cSMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
681b32bba6cSMarcel Holtmann 	char buf[3];
68292202185SMarcel Holtmann 
683111902f7SMarcel Holtmann 	buf[0] = test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) ? 'Y': 'N';
684b32bba6cSMarcel Holtmann 	buf[1] = '\n';
685b32bba6cSMarcel Holtmann 	buf[2] = '\0';
686b32bba6cSMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
687b32bba6cSMarcel Holtmann }
688b32bba6cSMarcel Holtmann 
689b32bba6cSMarcel Holtmann static ssize_t force_static_address_write(struct file *file,
690b32bba6cSMarcel Holtmann 					  const char __user *user_buf,
691b32bba6cSMarcel Holtmann 					  size_t count, loff_t *ppos)
692b32bba6cSMarcel Holtmann {
693b32bba6cSMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
694b32bba6cSMarcel Holtmann 	char buf[32];
695b32bba6cSMarcel Holtmann 	size_t buf_size = min(count, (sizeof(buf)-1));
696b32bba6cSMarcel Holtmann 	bool enable;
697b32bba6cSMarcel Holtmann 
698b32bba6cSMarcel Holtmann 	if (test_bit(HCI_UP, &hdev->flags))
699b32bba6cSMarcel Holtmann 		return -EBUSY;
700b32bba6cSMarcel Holtmann 
701b32bba6cSMarcel Holtmann 	if (copy_from_user(buf, user_buf, buf_size))
702b32bba6cSMarcel Holtmann 		return -EFAULT;
703b32bba6cSMarcel Holtmann 
704b32bba6cSMarcel Holtmann 	buf[buf_size] = '\0';
705b32bba6cSMarcel Holtmann 	if (strtobool(buf, &enable))
70692202185SMarcel Holtmann 		return -EINVAL;
70792202185SMarcel Holtmann 
708111902f7SMarcel Holtmann 	if (enable == test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags))
709b32bba6cSMarcel Holtmann 		return -EALREADY;
71092202185SMarcel Holtmann 
711111902f7SMarcel Holtmann 	change_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags);
712b32bba6cSMarcel Holtmann 
713b32bba6cSMarcel Holtmann 	return count;
71492202185SMarcel Holtmann }
71592202185SMarcel Holtmann 
716b32bba6cSMarcel Holtmann static const struct file_operations force_static_address_fops = {
717b32bba6cSMarcel Holtmann 	.open		= simple_open,
718b32bba6cSMarcel Holtmann 	.read		= force_static_address_read,
719b32bba6cSMarcel Holtmann 	.write		= force_static_address_write,
720b32bba6cSMarcel Holtmann 	.llseek		= default_llseek,
721b32bba6cSMarcel Holtmann };
72292202185SMarcel Holtmann 
723d2ab0ac1SMarcel Holtmann static int white_list_show(struct seq_file *f, void *ptr)
724d2ab0ac1SMarcel Holtmann {
725d2ab0ac1SMarcel Holtmann 	struct hci_dev *hdev = f->private;
726d2ab0ac1SMarcel Holtmann 	struct bdaddr_list *b;
727d2ab0ac1SMarcel Holtmann 
728d2ab0ac1SMarcel Holtmann 	hci_dev_lock(hdev);
729d2ab0ac1SMarcel Holtmann 	list_for_each_entry(b, &hdev->le_white_list, list)
730d2ab0ac1SMarcel Holtmann 		seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type);
731d2ab0ac1SMarcel Holtmann 	hci_dev_unlock(hdev);
732d2ab0ac1SMarcel Holtmann 
733d2ab0ac1SMarcel Holtmann 	return 0;
734d2ab0ac1SMarcel Holtmann }
735d2ab0ac1SMarcel Holtmann 
736d2ab0ac1SMarcel Holtmann static int white_list_open(struct inode *inode, struct file *file)
737d2ab0ac1SMarcel Holtmann {
738d2ab0ac1SMarcel Holtmann 	return single_open(file, white_list_show, inode->i_private);
739d2ab0ac1SMarcel Holtmann }
740d2ab0ac1SMarcel Holtmann 
741d2ab0ac1SMarcel Holtmann static const struct file_operations white_list_fops = {
742d2ab0ac1SMarcel Holtmann 	.open		= white_list_open,
743d2ab0ac1SMarcel Holtmann 	.read		= seq_read,
744d2ab0ac1SMarcel Holtmann 	.llseek		= seq_lseek,
745d2ab0ac1SMarcel Holtmann 	.release	= single_release,
746d2ab0ac1SMarcel Holtmann };
747d2ab0ac1SMarcel Holtmann 
7483698d704SMarcel Holtmann static int identity_resolving_keys_show(struct seq_file *f, void *ptr)
7493698d704SMarcel Holtmann {
7503698d704SMarcel Holtmann 	struct hci_dev *hdev = f->private;
7513698d704SMarcel Holtmann 	struct list_head *p, *n;
7523698d704SMarcel Holtmann 
7533698d704SMarcel Holtmann 	hci_dev_lock(hdev);
7543698d704SMarcel Holtmann 	list_for_each_safe(p, n, &hdev->identity_resolving_keys) {
7553698d704SMarcel Holtmann 		struct smp_irk *irk = list_entry(p, struct smp_irk, list);
7563698d704SMarcel Holtmann 		seq_printf(f, "%pMR (type %u) %*phN %pMR\n",
7573698d704SMarcel Holtmann 			   &irk->bdaddr, irk->addr_type,
7583698d704SMarcel Holtmann 			   16, irk->val, &irk->rpa);
7593698d704SMarcel Holtmann 	}
7603698d704SMarcel Holtmann 	hci_dev_unlock(hdev);
7613698d704SMarcel Holtmann 
7623698d704SMarcel Holtmann 	return 0;
7633698d704SMarcel Holtmann }
7643698d704SMarcel Holtmann 
7653698d704SMarcel Holtmann static int identity_resolving_keys_open(struct inode *inode, struct file *file)
7663698d704SMarcel Holtmann {
7673698d704SMarcel Holtmann 	return single_open(file, identity_resolving_keys_show,
7683698d704SMarcel Holtmann 			   inode->i_private);
7693698d704SMarcel Holtmann }
7703698d704SMarcel Holtmann 
7713698d704SMarcel Holtmann static const struct file_operations identity_resolving_keys_fops = {
7723698d704SMarcel Holtmann 	.open		= identity_resolving_keys_open,
7733698d704SMarcel Holtmann 	.read		= seq_read,
7743698d704SMarcel Holtmann 	.llseek		= seq_lseek,
7753698d704SMarcel Holtmann 	.release	= single_release,
7763698d704SMarcel Holtmann };
7773698d704SMarcel Holtmann 
7788f8625cdSMarcel Holtmann static int long_term_keys_show(struct seq_file *f, void *ptr)
7798f8625cdSMarcel Holtmann {
7808f8625cdSMarcel Holtmann 	struct hci_dev *hdev = f->private;
7818f8625cdSMarcel Holtmann 	struct list_head *p, *n;
7828f8625cdSMarcel Holtmann 
7838f8625cdSMarcel Holtmann 	hci_dev_lock(hdev);
784f813f1beSJohan Hedberg 	list_for_each_safe(p, n, &hdev->long_term_keys) {
7858f8625cdSMarcel Holtmann 		struct smp_ltk *ltk = list_entry(p, struct smp_ltk, list);
786fe39c7b2SMarcel Holtmann 		seq_printf(f, "%pMR (type %u) %u 0x%02x %u %.4x %.16llx %*phN\n",
7878f8625cdSMarcel Holtmann 			   &ltk->bdaddr, ltk->bdaddr_type, ltk->authenticated,
7888f8625cdSMarcel Holtmann 			   ltk->type, ltk->enc_size, __le16_to_cpu(ltk->ediv),
789fe39c7b2SMarcel Holtmann 			   __le64_to_cpu(ltk->rand), 16, ltk->val);
7908f8625cdSMarcel Holtmann 	}
7918f8625cdSMarcel Holtmann 	hci_dev_unlock(hdev);
7928f8625cdSMarcel Holtmann 
7938f8625cdSMarcel Holtmann 	return 0;
7948f8625cdSMarcel Holtmann }
7958f8625cdSMarcel Holtmann 
7968f8625cdSMarcel Holtmann static int long_term_keys_open(struct inode *inode, struct file *file)
7978f8625cdSMarcel Holtmann {
7988f8625cdSMarcel Holtmann 	return single_open(file, long_term_keys_show, inode->i_private);
7998f8625cdSMarcel Holtmann }
8008f8625cdSMarcel Holtmann 
8018f8625cdSMarcel Holtmann static const struct file_operations long_term_keys_fops = {
8028f8625cdSMarcel Holtmann 	.open		= long_term_keys_open,
8038f8625cdSMarcel Holtmann 	.read		= seq_read,
8048f8625cdSMarcel Holtmann 	.llseek		= seq_lseek,
8058f8625cdSMarcel Holtmann 	.release	= single_release,
8068f8625cdSMarcel Holtmann };
8078f8625cdSMarcel Holtmann 
8084e70c7e7SMarcel Holtmann static int conn_min_interval_set(void *data, u64 val)
8094e70c7e7SMarcel Holtmann {
8104e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
8114e70c7e7SMarcel Holtmann 
8124e70c7e7SMarcel Holtmann 	if (val < 0x0006 || val > 0x0c80 || val > hdev->le_conn_max_interval)
8134e70c7e7SMarcel Holtmann 		return -EINVAL;
8144e70c7e7SMarcel Holtmann 
8154e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
8164e70c7e7SMarcel Holtmann 	hdev->le_conn_min_interval = val;
8174e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
8184e70c7e7SMarcel Holtmann 
8194e70c7e7SMarcel Holtmann 	return 0;
8204e70c7e7SMarcel Holtmann }
8214e70c7e7SMarcel Holtmann 
8224e70c7e7SMarcel Holtmann static int conn_min_interval_get(void *data, u64 *val)
8234e70c7e7SMarcel Holtmann {
8244e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
8254e70c7e7SMarcel Holtmann 
8264e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
8274e70c7e7SMarcel Holtmann 	*val = hdev->le_conn_min_interval;
8284e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
8294e70c7e7SMarcel Holtmann 
8304e70c7e7SMarcel Holtmann 	return 0;
8314e70c7e7SMarcel Holtmann }
8324e70c7e7SMarcel Holtmann 
8334e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_min_interval_fops, conn_min_interval_get,
8344e70c7e7SMarcel Holtmann 			conn_min_interval_set, "%llu\n");
8354e70c7e7SMarcel Holtmann 
8364e70c7e7SMarcel Holtmann static int conn_max_interval_set(void *data, u64 val)
8374e70c7e7SMarcel Holtmann {
8384e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
8394e70c7e7SMarcel Holtmann 
8404e70c7e7SMarcel Holtmann 	if (val < 0x0006 || val > 0x0c80 || val < hdev->le_conn_min_interval)
8414e70c7e7SMarcel Holtmann 		return -EINVAL;
8424e70c7e7SMarcel Holtmann 
8434e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
8444e70c7e7SMarcel Holtmann 	hdev->le_conn_max_interval = val;
8454e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
8464e70c7e7SMarcel Holtmann 
8474e70c7e7SMarcel Holtmann 	return 0;
8484e70c7e7SMarcel Holtmann }
8494e70c7e7SMarcel Holtmann 
8504e70c7e7SMarcel Holtmann static int conn_max_interval_get(void *data, u64 *val)
8514e70c7e7SMarcel Holtmann {
8524e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
8534e70c7e7SMarcel Holtmann 
8544e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
8554e70c7e7SMarcel Holtmann 	*val = hdev->le_conn_max_interval;
8564e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
8574e70c7e7SMarcel Holtmann 
8584e70c7e7SMarcel Holtmann 	return 0;
8594e70c7e7SMarcel Holtmann }
8604e70c7e7SMarcel Holtmann 
8614e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get,
8624e70c7e7SMarcel Holtmann 			conn_max_interval_set, "%llu\n");
8634e70c7e7SMarcel Holtmann 
864816a93d1SMarcel Holtmann static int conn_latency_set(void *data, u64 val)
865816a93d1SMarcel Holtmann {
866816a93d1SMarcel Holtmann 	struct hci_dev *hdev = data;
867816a93d1SMarcel Holtmann 
868816a93d1SMarcel Holtmann 	if (val > 0x01f3)
869816a93d1SMarcel Holtmann 		return -EINVAL;
870816a93d1SMarcel Holtmann 
871816a93d1SMarcel Holtmann 	hci_dev_lock(hdev);
872816a93d1SMarcel Holtmann 	hdev->le_conn_latency = val;
873816a93d1SMarcel Holtmann 	hci_dev_unlock(hdev);
874816a93d1SMarcel Holtmann 
875816a93d1SMarcel Holtmann 	return 0;
876816a93d1SMarcel Holtmann }
877816a93d1SMarcel Holtmann 
878816a93d1SMarcel Holtmann static int conn_latency_get(void *data, u64 *val)
879816a93d1SMarcel Holtmann {
880816a93d1SMarcel Holtmann 	struct hci_dev *hdev = data;
881816a93d1SMarcel Holtmann 
882816a93d1SMarcel Holtmann 	hci_dev_lock(hdev);
883816a93d1SMarcel Holtmann 	*val = hdev->le_conn_latency;
884816a93d1SMarcel Holtmann 	hci_dev_unlock(hdev);
885816a93d1SMarcel Holtmann 
886816a93d1SMarcel Holtmann 	return 0;
887816a93d1SMarcel Holtmann }
888816a93d1SMarcel Holtmann 
889816a93d1SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_latency_fops, conn_latency_get,
890816a93d1SMarcel Holtmann 			conn_latency_set, "%llu\n");
891816a93d1SMarcel Holtmann 
892f1649577SMarcel Holtmann static int supervision_timeout_set(void *data, u64 val)
893f1649577SMarcel Holtmann {
894f1649577SMarcel Holtmann 	struct hci_dev *hdev = data;
895f1649577SMarcel Holtmann 
896f1649577SMarcel Holtmann 	if (val < 0x000a || val > 0x0c80)
897f1649577SMarcel Holtmann 		return -EINVAL;
898f1649577SMarcel Holtmann 
899f1649577SMarcel Holtmann 	hci_dev_lock(hdev);
900f1649577SMarcel Holtmann 	hdev->le_supv_timeout = val;
901f1649577SMarcel Holtmann 	hci_dev_unlock(hdev);
902f1649577SMarcel Holtmann 
903f1649577SMarcel Holtmann 	return 0;
904f1649577SMarcel Holtmann }
905f1649577SMarcel Holtmann 
906f1649577SMarcel Holtmann static int supervision_timeout_get(void *data, u64 *val)
907f1649577SMarcel Holtmann {
908f1649577SMarcel Holtmann 	struct hci_dev *hdev = data;
909f1649577SMarcel Holtmann 
910f1649577SMarcel Holtmann 	hci_dev_lock(hdev);
911f1649577SMarcel Holtmann 	*val = hdev->le_supv_timeout;
912f1649577SMarcel Holtmann 	hci_dev_unlock(hdev);
913f1649577SMarcel Holtmann 
914f1649577SMarcel Holtmann 	return 0;
915f1649577SMarcel Holtmann }
916f1649577SMarcel Holtmann 
917f1649577SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(supervision_timeout_fops, supervision_timeout_get,
918f1649577SMarcel Holtmann 			supervision_timeout_set, "%llu\n");
919f1649577SMarcel Holtmann 
9203f959d46SMarcel Holtmann static int adv_channel_map_set(void *data, u64 val)
9213f959d46SMarcel Holtmann {
9223f959d46SMarcel Holtmann 	struct hci_dev *hdev = data;
9233f959d46SMarcel Holtmann 
9243f959d46SMarcel Holtmann 	if (val < 0x01 || val > 0x07)
9253f959d46SMarcel Holtmann 		return -EINVAL;
9263f959d46SMarcel Holtmann 
9273f959d46SMarcel Holtmann 	hci_dev_lock(hdev);
9283f959d46SMarcel Holtmann 	hdev->le_adv_channel_map = val;
9293f959d46SMarcel Holtmann 	hci_dev_unlock(hdev);
9303f959d46SMarcel Holtmann 
9313f959d46SMarcel Holtmann 	return 0;
9323f959d46SMarcel Holtmann }
9333f959d46SMarcel Holtmann 
9343f959d46SMarcel Holtmann static int adv_channel_map_get(void *data, u64 *val)
9353f959d46SMarcel Holtmann {
9363f959d46SMarcel Holtmann 	struct hci_dev *hdev = data;
9373f959d46SMarcel Holtmann 
9383f959d46SMarcel Holtmann 	hci_dev_lock(hdev);
9393f959d46SMarcel Holtmann 	*val = hdev->le_adv_channel_map;
9403f959d46SMarcel Holtmann 	hci_dev_unlock(hdev);
9413f959d46SMarcel Holtmann 
9423f959d46SMarcel Holtmann 	return 0;
9433f959d46SMarcel Holtmann }
9443f959d46SMarcel Holtmann 
9453f959d46SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(adv_channel_map_fops, adv_channel_map_get,
9463f959d46SMarcel Holtmann 			adv_channel_map_set, "%llu\n");
9473f959d46SMarcel Holtmann 
948729a1051SGeorg Lukas static int adv_min_interval_set(void *data, u64 val)
94989863109SJukka Rissanen {
950729a1051SGeorg Lukas 	struct hci_dev *hdev = data;
95189863109SJukka Rissanen 
952729a1051SGeorg Lukas 	if (val < 0x0020 || val > 0x4000 || val > hdev->le_adv_max_interval)
95389863109SJukka Rissanen 		return -EINVAL;
95489863109SJukka Rissanen 
9557d474e06SAndre Guedes 	hci_dev_lock(hdev);
956729a1051SGeorg Lukas 	hdev->le_adv_min_interval = val;
9577d474e06SAndre Guedes 	hci_dev_unlock(hdev);
9587d474e06SAndre Guedes 
9597d474e06SAndre Guedes 	return 0;
9607d474e06SAndre Guedes }
9617d474e06SAndre Guedes 
962729a1051SGeorg Lukas static int adv_min_interval_get(void *data, u64 *val)
9637d474e06SAndre Guedes {
964729a1051SGeorg Lukas 	struct hci_dev *hdev = data;
965729a1051SGeorg Lukas 
966729a1051SGeorg Lukas 	hci_dev_lock(hdev);
967729a1051SGeorg Lukas 	*val = hdev->le_adv_min_interval;
968729a1051SGeorg Lukas 	hci_dev_unlock(hdev);
969729a1051SGeorg Lukas 
970729a1051SGeorg Lukas 	return 0;
9717d474e06SAndre Guedes }
9727d474e06SAndre Guedes 
973729a1051SGeorg Lukas DEFINE_SIMPLE_ATTRIBUTE(adv_min_interval_fops, adv_min_interval_get,
974729a1051SGeorg Lukas 			adv_min_interval_set, "%llu\n");
9757d474e06SAndre Guedes 
976729a1051SGeorg Lukas static int adv_max_interval_set(void *data, u64 val)
977729a1051SGeorg Lukas {
978729a1051SGeorg Lukas 	struct hci_dev *hdev = data;
979729a1051SGeorg Lukas 
980729a1051SGeorg Lukas 	if (val < 0x0020 || val > 0x4000 || val < hdev->le_adv_min_interval)
9817d474e06SAndre Guedes 		return -EINVAL;
9827d474e06SAndre Guedes 
9837d474e06SAndre Guedes 	hci_dev_lock(hdev);
984729a1051SGeorg Lukas 	hdev->le_adv_max_interval = val;
9857d474e06SAndre Guedes 	hci_dev_unlock(hdev);
9867d474e06SAndre Guedes 
987729a1051SGeorg Lukas 	return 0;
9887d474e06SAndre Guedes }
9897d474e06SAndre Guedes 
990729a1051SGeorg Lukas static int adv_max_interval_get(void *data, u64 *val)
991729a1051SGeorg Lukas {
992729a1051SGeorg Lukas 	struct hci_dev *hdev = data;
993729a1051SGeorg Lukas 
9947d474e06SAndre Guedes 	hci_dev_lock(hdev);
995729a1051SGeorg Lukas 	*val = hdev->le_adv_max_interval;
9967d474e06SAndre Guedes 	hci_dev_unlock(hdev);
997729a1051SGeorg Lukas 
998729a1051SGeorg Lukas 	return 0;
999729a1051SGeorg Lukas }
1000729a1051SGeorg Lukas 
1001729a1051SGeorg Lukas DEFINE_SIMPLE_ATTRIBUTE(adv_max_interval_fops, adv_max_interval_get,
1002729a1051SGeorg Lukas 			adv_max_interval_set, "%llu\n");
1003729a1051SGeorg Lukas 
10040b3c7d37SMarcel Holtmann static int device_list_show(struct seq_file *f, void *ptr)
10057d474e06SAndre Guedes {
10060b3c7d37SMarcel Holtmann 	struct hci_dev *hdev = f->private;
10077d474e06SAndre Guedes 	struct hci_conn_params *p;
100840f4938aSMarcel Holtmann 	struct bdaddr_list *b;
10097d474e06SAndre Guedes 
10107d474e06SAndre Guedes 	hci_dev_lock(hdev);
101140f4938aSMarcel Holtmann 	list_for_each_entry(b, &hdev->whitelist, list)
101240f4938aSMarcel Holtmann 		seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type);
10137d474e06SAndre Guedes 	list_for_each_entry(p, &hdev->le_conn_params, list) {
101440f4938aSMarcel Holtmann 		seq_printf(f, "%pMR (type %u) %u\n", &p->addr, p->addr_type,
10157d474e06SAndre Guedes 			   p->auto_connect);
10167d474e06SAndre Guedes 	}
10177d474e06SAndre Guedes 	hci_dev_unlock(hdev);
10187d474e06SAndre Guedes 
10197d474e06SAndre Guedes 	return 0;
10207d474e06SAndre Guedes }
10217d474e06SAndre Guedes 
10220b3c7d37SMarcel Holtmann static int device_list_open(struct inode *inode, struct file *file)
10237d474e06SAndre Guedes {
10240b3c7d37SMarcel Holtmann 	return single_open(file, device_list_show, inode->i_private);
10257d474e06SAndre Guedes }
10267d474e06SAndre Guedes 
10270b3c7d37SMarcel Holtmann static const struct file_operations device_list_fops = {
10280b3c7d37SMarcel Holtmann 	.open		= device_list_open,
10297d474e06SAndre Guedes 	.read		= seq_read,
10307d474e06SAndre Guedes 	.llseek		= seq_lseek,
10317d474e06SAndre Guedes 	.release	= single_release,
10327d474e06SAndre Guedes };
10337d474e06SAndre Guedes 
10341da177e4SLinus Torvalds /* ---- HCI requests ---- */
10351da177e4SLinus Torvalds 
103642c6b129SJohan Hedberg static void hci_req_sync_complete(struct hci_dev *hdev, u8 result)
10371da177e4SLinus Torvalds {
103842c6b129SJohan Hedberg 	BT_DBG("%s result 0x%2.2x", hdev->name, result);
103975fb0e32SJohan Hedberg 
10401da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
10411da177e4SLinus Torvalds 		hdev->req_result = result;
10421da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_DONE;
10431da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
10441da177e4SLinus Torvalds 	}
10451da177e4SLinus Torvalds }
10461da177e4SLinus Torvalds 
10471da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err)
10481da177e4SLinus Torvalds {
10491da177e4SLinus Torvalds 	BT_DBG("%s err 0x%2.2x", hdev->name, err);
10501da177e4SLinus Torvalds 
10511da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
10521da177e4SLinus Torvalds 		hdev->req_result = err;
10531da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_CANCELED;
10541da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
10551da177e4SLinus Torvalds 	}
10561da177e4SLinus Torvalds }
10571da177e4SLinus Torvalds 
105877a63e0aSFengguang Wu static struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode,
105977a63e0aSFengguang Wu 					    u8 event)
106075e84b7cSJohan Hedberg {
106175e84b7cSJohan Hedberg 	struct hci_ev_cmd_complete *ev;
106275e84b7cSJohan Hedberg 	struct hci_event_hdr *hdr;
106375e84b7cSJohan Hedberg 	struct sk_buff *skb;
106475e84b7cSJohan Hedberg 
106575e84b7cSJohan Hedberg 	hci_dev_lock(hdev);
106675e84b7cSJohan Hedberg 
106775e84b7cSJohan Hedberg 	skb = hdev->recv_evt;
106875e84b7cSJohan Hedberg 	hdev->recv_evt = NULL;
106975e84b7cSJohan Hedberg 
107075e84b7cSJohan Hedberg 	hci_dev_unlock(hdev);
107175e84b7cSJohan Hedberg 
107275e84b7cSJohan Hedberg 	if (!skb)
107375e84b7cSJohan Hedberg 		return ERR_PTR(-ENODATA);
107475e84b7cSJohan Hedberg 
107575e84b7cSJohan Hedberg 	if (skb->len < sizeof(*hdr)) {
107675e84b7cSJohan Hedberg 		BT_ERR("Too short HCI event");
107775e84b7cSJohan Hedberg 		goto failed;
107875e84b7cSJohan Hedberg 	}
107975e84b7cSJohan Hedberg 
108075e84b7cSJohan Hedberg 	hdr = (void *) skb->data;
108175e84b7cSJohan Hedberg 	skb_pull(skb, HCI_EVENT_HDR_SIZE);
108275e84b7cSJohan Hedberg 
10837b1abbbeSJohan Hedberg 	if (event) {
10847b1abbbeSJohan Hedberg 		if (hdr->evt != event)
10857b1abbbeSJohan Hedberg 			goto failed;
10867b1abbbeSJohan Hedberg 		return skb;
10877b1abbbeSJohan Hedberg 	}
10887b1abbbeSJohan Hedberg 
108975e84b7cSJohan Hedberg 	if (hdr->evt != HCI_EV_CMD_COMPLETE) {
109075e84b7cSJohan Hedberg 		BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt);
109175e84b7cSJohan Hedberg 		goto failed;
109275e84b7cSJohan Hedberg 	}
109375e84b7cSJohan Hedberg 
109475e84b7cSJohan Hedberg 	if (skb->len < sizeof(*ev)) {
109575e84b7cSJohan Hedberg 		BT_ERR("Too short cmd_complete event");
109675e84b7cSJohan Hedberg 		goto failed;
109775e84b7cSJohan Hedberg 	}
109875e84b7cSJohan Hedberg 
109975e84b7cSJohan Hedberg 	ev = (void *) skb->data;
110075e84b7cSJohan Hedberg 	skb_pull(skb, sizeof(*ev));
110175e84b7cSJohan Hedberg 
110275e84b7cSJohan Hedberg 	if (opcode == __le16_to_cpu(ev->opcode))
110375e84b7cSJohan Hedberg 		return skb;
110475e84b7cSJohan Hedberg 
110575e84b7cSJohan Hedberg 	BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode,
110675e84b7cSJohan Hedberg 	       __le16_to_cpu(ev->opcode));
110775e84b7cSJohan Hedberg 
110875e84b7cSJohan Hedberg failed:
110975e84b7cSJohan Hedberg 	kfree_skb(skb);
111075e84b7cSJohan Hedberg 	return ERR_PTR(-ENODATA);
111175e84b7cSJohan Hedberg }
111275e84b7cSJohan Hedberg 
11137b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
111407dc93ddSJohan Hedberg 				  const void *param, u8 event, u32 timeout)
111575e84b7cSJohan Hedberg {
111675e84b7cSJohan Hedberg 	DECLARE_WAITQUEUE(wait, current);
111775e84b7cSJohan Hedberg 	struct hci_request req;
111875e84b7cSJohan Hedberg 	int err = 0;
111975e84b7cSJohan Hedberg 
112075e84b7cSJohan Hedberg 	BT_DBG("%s", hdev->name);
112175e84b7cSJohan Hedberg 
112275e84b7cSJohan Hedberg 	hci_req_init(&req, hdev);
112375e84b7cSJohan Hedberg 
11247b1abbbeSJohan Hedberg 	hci_req_add_ev(&req, opcode, plen, param, event);
112575e84b7cSJohan Hedberg 
112675e84b7cSJohan Hedberg 	hdev->req_status = HCI_REQ_PEND;
112775e84b7cSJohan Hedberg 
112875e84b7cSJohan Hedberg 	add_wait_queue(&hdev->req_wait_q, &wait);
112975e84b7cSJohan Hedberg 	set_current_state(TASK_INTERRUPTIBLE);
113075e84b7cSJohan Hedberg 
1131039fada5SChan-yeol Park 	err = hci_req_run(&req, hci_req_sync_complete);
1132039fada5SChan-yeol Park 	if (err < 0) {
1133039fada5SChan-yeol Park 		remove_wait_queue(&hdev->req_wait_q, &wait);
1134039fada5SChan-yeol Park 		return ERR_PTR(err);
1135039fada5SChan-yeol Park 	}
1136039fada5SChan-yeol Park 
113775e84b7cSJohan Hedberg 	schedule_timeout(timeout);
113875e84b7cSJohan Hedberg 
113975e84b7cSJohan Hedberg 	remove_wait_queue(&hdev->req_wait_q, &wait);
114075e84b7cSJohan Hedberg 
114175e84b7cSJohan Hedberg 	if (signal_pending(current))
114275e84b7cSJohan Hedberg 		return ERR_PTR(-EINTR);
114375e84b7cSJohan Hedberg 
114475e84b7cSJohan Hedberg 	switch (hdev->req_status) {
114575e84b7cSJohan Hedberg 	case HCI_REQ_DONE:
114675e84b7cSJohan Hedberg 		err = -bt_to_errno(hdev->req_result);
114775e84b7cSJohan Hedberg 		break;
114875e84b7cSJohan Hedberg 
114975e84b7cSJohan Hedberg 	case HCI_REQ_CANCELED:
115075e84b7cSJohan Hedberg 		err = -hdev->req_result;
115175e84b7cSJohan Hedberg 		break;
115275e84b7cSJohan Hedberg 
115375e84b7cSJohan Hedberg 	default:
115475e84b7cSJohan Hedberg 		err = -ETIMEDOUT;
115575e84b7cSJohan Hedberg 		break;
115675e84b7cSJohan Hedberg 	}
115775e84b7cSJohan Hedberg 
115875e84b7cSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
115975e84b7cSJohan Hedberg 
116075e84b7cSJohan Hedberg 	BT_DBG("%s end: err %d", hdev->name, err);
116175e84b7cSJohan Hedberg 
116275e84b7cSJohan Hedberg 	if (err < 0)
116375e84b7cSJohan Hedberg 		return ERR_PTR(err);
116475e84b7cSJohan Hedberg 
11657b1abbbeSJohan Hedberg 	return hci_get_cmd_complete(hdev, opcode, event);
11667b1abbbeSJohan Hedberg }
11677b1abbbeSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync_ev);
11687b1abbbeSJohan Hedberg 
11697b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
117007dc93ddSJohan Hedberg 			       const void *param, u32 timeout)
11717b1abbbeSJohan Hedberg {
11727b1abbbeSJohan Hedberg 	return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout);
117375e84b7cSJohan Hedberg }
117475e84b7cSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync);
117575e84b7cSJohan Hedberg 
11761da177e4SLinus Torvalds /* Execute request and wait for completion. */
117701178cd4SJohan Hedberg static int __hci_req_sync(struct hci_dev *hdev,
117842c6b129SJohan Hedberg 			  void (*func)(struct hci_request *req,
117942c6b129SJohan Hedberg 				      unsigned long opt),
11801da177e4SLinus Torvalds 			  unsigned long opt, __u32 timeout)
11811da177e4SLinus Torvalds {
118242c6b129SJohan Hedberg 	struct hci_request req;
11831da177e4SLinus Torvalds 	DECLARE_WAITQUEUE(wait, current);
11841da177e4SLinus Torvalds 	int err = 0;
11851da177e4SLinus Torvalds 
11861da177e4SLinus Torvalds 	BT_DBG("%s start", hdev->name);
11871da177e4SLinus Torvalds 
118842c6b129SJohan Hedberg 	hci_req_init(&req, hdev);
118942c6b129SJohan Hedberg 
11901da177e4SLinus Torvalds 	hdev->req_status = HCI_REQ_PEND;
11911da177e4SLinus Torvalds 
119242c6b129SJohan Hedberg 	func(&req, opt);
119353cce22dSJohan Hedberg 
1194039fada5SChan-yeol Park 	add_wait_queue(&hdev->req_wait_q, &wait);
1195039fada5SChan-yeol Park 	set_current_state(TASK_INTERRUPTIBLE);
1196039fada5SChan-yeol Park 
119742c6b129SJohan Hedberg 	err = hci_req_run(&req, hci_req_sync_complete);
119842c6b129SJohan Hedberg 	if (err < 0) {
119953cce22dSJohan Hedberg 		hdev->req_status = 0;
1200920c8300SAndre Guedes 
1201039fada5SChan-yeol Park 		remove_wait_queue(&hdev->req_wait_q, &wait);
1202039fada5SChan-yeol Park 
1203920c8300SAndre Guedes 		/* ENODATA means the HCI request command queue is empty.
1204920c8300SAndre Guedes 		 * This can happen when a request with conditionals doesn't
1205920c8300SAndre Guedes 		 * trigger any commands to be sent. This is normal behavior
1206920c8300SAndre Guedes 		 * and should not trigger an error return.
120742c6b129SJohan Hedberg 		 */
1208920c8300SAndre Guedes 		if (err == -ENODATA)
120942c6b129SJohan Hedberg 			return 0;
1210920c8300SAndre Guedes 
1211920c8300SAndre Guedes 		return err;
121253cce22dSJohan Hedberg 	}
121353cce22dSJohan Hedberg 
12141da177e4SLinus Torvalds 	schedule_timeout(timeout);
12151da177e4SLinus Torvalds 
12161da177e4SLinus Torvalds 	remove_wait_queue(&hdev->req_wait_q, &wait);
12171da177e4SLinus Torvalds 
12181da177e4SLinus Torvalds 	if (signal_pending(current))
12191da177e4SLinus Torvalds 		return -EINTR;
12201da177e4SLinus Torvalds 
12211da177e4SLinus Torvalds 	switch (hdev->req_status) {
12221da177e4SLinus Torvalds 	case HCI_REQ_DONE:
1223e175072fSJoe Perches 		err = -bt_to_errno(hdev->req_result);
12241da177e4SLinus Torvalds 		break;
12251da177e4SLinus Torvalds 
12261da177e4SLinus Torvalds 	case HCI_REQ_CANCELED:
12271da177e4SLinus Torvalds 		err = -hdev->req_result;
12281da177e4SLinus Torvalds 		break;
12291da177e4SLinus Torvalds 
12301da177e4SLinus Torvalds 	default:
12311da177e4SLinus Torvalds 		err = -ETIMEDOUT;
12321da177e4SLinus Torvalds 		break;
12333ff50b79SStephen Hemminger 	}
12341da177e4SLinus Torvalds 
1235a5040efaSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
12361da177e4SLinus Torvalds 
12371da177e4SLinus Torvalds 	BT_DBG("%s end: err %d", hdev->name, err);
12381da177e4SLinus Torvalds 
12391da177e4SLinus Torvalds 	return err;
12401da177e4SLinus Torvalds }
12411da177e4SLinus Torvalds 
124201178cd4SJohan Hedberg static int hci_req_sync(struct hci_dev *hdev,
124342c6b129SJohan Hedberg 			void (*req)(struct hci_request *req,
124442c6b129SJohan Hedberg 				    unsigned long opt),
12451da177e4SLinus Torvalds 			unsigned long opt, __u32 timeout)
12461da177e4SLinus Torvalds {
12471da177e4SLinus Torvalds 	int ret;
12481da177e4SLinus Torvalds 
12497c6a329eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
12507c6a329eSMarcel Holtmann 		return -ENETDOWN;
12517c6a329eSMarcel Holtmann 
12521da177e4SLinus Torvalds 	/* Serialize all requests */
12531da177e4SLinus Torvalds 	hci_req_lock(hdev);
125401178cd4SJohan Hedberg 	ret = __hci_req_sync(hdev, req, opt, timeout);
12551da177e4SLinus Torvalds 	hci_req_unlock(hdev);
12561da177e4SLinus Torvalds 
12571da177e4SLinus Torvalds 	return ret;
12581da177e4SLinus Torvalds }
12591da177e4SLinus Torvalds 
126042c6b129SJohan Hedberg static void hci_reset_req(struct hci_request *req, unsigned long opt)
12611da177e4SLinus Torvalds {
126242c6b129SJohan Hedberg 	BT_DBG("%s %ld", req->hdev->name, opt);
12631da177e4SLinus Torvalds 
12641da177e4SLinus Torvalds 	/* Reset device */
126542c6b129SJohan Hedberg 	set_bit(HCI_RESET, &req->hdev->flags);
126642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_RESET, 0, NULL);
12671da177e4SLinus Torvalds }
12681da177e4SLinus Torvalds 
126942c6b129SJohan Hedberg static void bredr_init(struct hci_request *req)
12701da177e4SLinus Torvalds {
127142c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
12722455a3eaSAndrei Emeltchenko 
12731da177e4SLinus Torvalds 	/* Read Local Supported Features */
127442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
12751da177e4SLinus Torvalds 
12761143e5a6SMarcel Holtmann 	/* Read Local Version */
127742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
12782177bab5SJohan Hedberg 
12792177bab5SJohan Hedberg 	/* Read BD Address */
128042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
12811da177e4SLinus Torvalds }
12821da177e4SLinus Torvalds 
128342c6b129SJohan Hedberg static void amp_init(struct hci_request *req)
1284e61ef499SAndrei Emeltchenko {
128542c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
12862455a3eaSAndrei Emeltchenko 
1287e61ef499SAndrei Emeltchenko 	/* Read Local Version */
128842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
12896bcbc489SAndrei Emeltchenko 
1290f6996cfeSMarcel Holtmann 	/* Read Local Supported Commands */
1291f6996cfeSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
1292f6996cfeSMarcel Holtmann 
1293f6996cfeSMarcel Holtmann 	/* Read Local Supported Features */
1294f6996cfeSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
1295f6996cfeSMarcel Holtmann 
12966bcbc489SAndrei Emeltchenko 	/* Read Local AMP Info */
129742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
1298e71dfabaSAndrei Emeltchenko 
1299e71dfabaSAndrei Emeltchenko 	/* Read Data Blk size */
130042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL);
13017528ca1cSMarcel Holtmann 
1302f38ba941SMarcel Holtmann 	/* Read Flow Control Mode */
1303f38ba941SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL);
1304f38ba941SMarcel Holtmann 
13057528ca1cSMarcel Holtmann 	/* Read Location Data */
13067528ca1cSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL);
1307e61ef499SAndrei Emeltchenko }
1308e61ef499SAndrei Emeltchenko 
130942c6b129SJohan Hedberg static void hci_init1_req(struct hci_request *req, unsigned long opt)
1310e61ef499SAndrei Emeltchenko {
131142c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1312e61ef499SAndrei Emeltchenko 
1313e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
1314e61ef499SAndrei Emeltchenko 
131511778716SAndrei Emeltchenko 	/* Reset */
131611778716SAndrei Emeltchenko 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
131742c6b129SJohan Hedberg 		hci_reset_req(req, 0);
131811778716SAndrei Emeltchenko 
1319e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
1320e61ef499SAndrei Emeltchenko 	case HCI_BREDR:
132142c6b129SJohan Hedberg 		bredr_init(req);
1322e61ef499SAndrei Emeltchenko 		break;
1323e61ef499SAndrei Emeltchenko 
1324e61ef499SAndrei Emeltchenko 	case HCI_AMP:
132542c6b129SJohan Hedberg 		amp_init(req);
1326e61ef499SAndrei Emeltchenko 		break;
1327e61ef499SAndrei Emeltchenko 
1328e61ef499SAndrei Emeltchenko 	default:
1329e61ef499SAndrei Emeltchenko 		BT_ERR("Unknown device type %d", hdev->dev_type);
1330e61ef499SAndrei Emeltchenko 		break;
1331e61ef499SAndrei Emeltchenko 	}
1332e61ef499SAndrei Emeltchenko }
1333e61ef499SAndrei Emeltchenko 
133442c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req)
13352177bab5SJohan Hedberg {
13364ca048e3SMarcel Holtmann 	struct hci_dev *hdev = req->hdev;
13374ca048e3SMarcel Holtmann 
13382177bab5SJohan Hedberg 	__le16 param;
13392177bab5SJohan Hedberg 	__u8 flt_type;
13402177bab5SJohan Hedberg 
13412177bab5SJohan Hedberg 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
134242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
13432177bab5SJohan Hedberg 
13442177bab5SJohan Hedberg 	/* Read Class of Device */
134542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
13462177bab5SJohan Hedberg 
13472177bab5SJohan Hedberg 	/* Read Local Name */
134842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL);
13492177bab5SJohan Hedberg 
13502177bab5SJohan Hedberg 	/* Read Voice Setting */
135142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL);
13522177bab5SJohan Hedberg 
1353b4cb9fb2SMarcel Holtmann 	/* Read Number of Supported IAC */
1354b4cb9fb2SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL);
1355b4cb9fb2SMarcel Holtmann 
13564b836f39SMarcel Holtmann 	/* Read Current IAC LAP */
13574b836f39SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL);
13584b836f39SMarcel Holtmann 
13592177bab5SJohan Hedberg 	/* Clear Event Filters */
13602177bab5SJohan Hedberg 	flt_type = HCI_FLT_CLEAR_ALL;
136142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
13622177bab5SJohan Hedberg 
13632177bab5SJohan Hedberg 	/* Connection accept timeout ~20 secs */
1364dcf4adbfSJoe Perches 	param = cpu_to_le16(0x7d00);
136542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
13662177bab5SJohan Hedberg 
13674ca048e3SMarcel Holtmann 	/* AVM Berlin (31), aka "BlueFRITZ!", reports version 1.2,
13684ca048e3SMarcel Holtmann 	 * but it does not support page scan related HCI commands.
13694ca048e3SMarcel Holtmann 	 */
13704ca048e3SMarcel Holtmann 	if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) {
1371f332ec66SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL);
1372f332ec66SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL);
1373f332ec66SJohan Hedberg 	}
13742177bab5SJohan Hedberg }
13752177bab5SJohan Hedberg 
137642c6b129SJohan Hedberg static void le_setup(struct hci_request *req)
13772177bab5SJohan Hedberg {
1378c73eee91SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1379c73eee91SJohan Hedberg 
13802177bab5SJohan Hedberg 	/* Read LE Buffer Size */
138142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
13822177bab5SJohan Hedberg 
13832177bab5SJohan Hedberg 	/* Read LE Local Supported Features */
138442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
13852177bab5SJohan Hedberg 
1386747d3f03SMarcel Holtmann 	/* Read LE Supported States */
1387747d3f03SMarcel Holtmann 	hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);
1388747d3f03SMarcel Holtmann 
13892177bab5SJohan Hedberg 	/* Read LE White List Size */
139042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL);
13912177bab5SJohan Hedberg 
1392747d3f03SMarcel Holtmann 	/* Clear LE White List */
1393747d3f03SMarcel Holtmann 	hci_req_add(req, HCI_OP_LE_CLEAR_WHITE_LIST, 0, NULL);
1394c73eee91SJohan Hedberg 
1395c73eee91SJohan Hedberg 	/* LE-only controllers have LE implicitly enabled */
1396c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
1397c73eee91SJohan Hedberg 		set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
13982177bab5SJohan Hedberg }
13992177bab5SJohan Hedberg 
14002177bab5SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
14012177bab5SJohan Hedberg {
14022177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
14032177bab5SJohan Hedberg 		return 0x02;
14042177bab5SJohan Hedberg 
14052177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
14062177bab5SJohan Hedberg 		return 0x01;
14072177bab5SJohan Hedberg 
14082177bab5SJohan Hedberg 	if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
14092177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x0757)
14102177bab5SJohan Hedberg 		return 0x01;
14112177bab5SJohan Hedberg 
14122177bab5SJohan Hedberg 	if (hdev->manufacturer == 15) {
14132177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
14142177bab5SJohan Hedberg 			return 0x01;
14152177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
14162177bab5SJohan Hedberg 			return 0x01;
14172177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
14182177bab5SJohan Hedberg 			return 0x01;
14192177bab5SJohan Hedberg 	}
14202177bab5SJohan Hedberg 
14212177bab5SJohan Hedberg 	if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
14222177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x1805)
14232177bab5SJohan Hedberg 		return 0x01;
14242177bab5SJohan Hedberg 
14252177bab5SJohan Hedberg 	return 0x00;
14262177bab5SJohan Hedberg }
14272177bab5SJohan Hedberg 
142842c6b129SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_request *req)
14292177bab5SJohan Hedberg {
14302177bab5SJohan Hedberg 	u8 mode;
14312177bab5SJohan Hedberg 
143242c6b129SJohan Hedberg 	mode = hci_get_inquiry_mode(req->hdev);
14332177bab5SJohan Hedberg 
143442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
14352177bab5SJohan Hedberg }
14362177bab5SJohan Hedberg 
143742c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req)
14382177bab5SJohan Hedberg {
143942c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
144042c6b129SJohan Hedberg 
14412177bab5SJohan Hedberg 	/* The second byte is 0xff instead of 0x9f (two reserved bits
14422177bab5SJohan Hedberg 	 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
14432177bab5SJohan Hedberg 	 * command otherwise.
14442177bab5SJohan Hedberg 	 */
14452177bab5SJohan Hedberg 	u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
14462177bab5SJohan Hedberg 
14472177bab5SJohan Hedberg 	/* CSR 1.1 dongles does not accept any bitfield so don't try to set
14482177bab5SJohan Hedberg 	 * any event mask for pre 1.2 devices.
14492177bab5SJohan Hedberg 	 */
14502177bab5SJohan Hedberg 	if (hdev->hci_ver < BLUETOOTH_VER_1_2)
14512177bab5SJohan Hedberg 		return;
14522177bab5SJohan Hedberg 
14532177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
14542177bab5SJohan Hedberg 		events[4] |= 0x01; /* Flow Specification Complete */
14552177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
14562177bab5SJohan Hedberg 		events[4] |= 0x04; /* Read Remote Extended Features Complete */
14572177bab5SJohan Hedberg 		events[5] |= 0x08; /* Synchronous Connection Complete */
14582177bab5SJohan Hedberg 		events[5] |= 0x10; /* Synchronous Connection Changed */
1459c7882cbdSMarcel Holtmann 	} else {
1460c7882cbdSMarcel Holtmann 		/* Use a different default for LE-only devices */
1461c7882cbdSMarcel Holtmann 		memset(events, 0, sizeof(events));
1462c7882cbdSMarcel Holtmann 		events[0] |= 0x10; /* Disconnection Complete */
1463c7882cbdSMarcel Holtmann 		events[1] |= 0x08; /* Read Remote Version Information Complete */
1464c7882cbdSMarcel Holtmann 		events[1] |= 0x20; /* Command Complete */
1465c7882cbdSMarcel Holtmann 		events[1] |= 0x40; /* Command Status */
1466c7882cbdSMarcel Holtmann 		events[1] |= 0x80; /* Hardware Error */
1467c7882cbdSMarcel Holtmann 		events[2] |= 0x04; /* Number of Completed Packets */
1468c7882cbdSMarcel Holtmann 		events[3] |= 0x02; /* Data Buffer Overflow */
14690da71f1bSMarcel Holtmann 
14700da71f1bSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_ENCRYPTION) {
14710da71f1bSMarcel Holtmann 			events[0] |= 0x80; /* Encryption Change */
1472c7882cbdSMarcel Holtmann 			events[5] |= 0x80; /* Encryption Key Refresh Complete */
14732177bab5SJohan Hedberg 		}
14740da71f1bSMarcel Holtmann 	}
14752177bab5SJohan Hedberg 
14762177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
14772177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
14782177bab5SJohan Hedberg 
14792177bab5SJohan Hedberg 	if (lmp_sniffsubr_capable(hdev))
14802177bab5SJohan Hedberg 		events[5] |= 0x20; /* Sniff Subrating */
14812177bab5SJohan Hedberg 
14822177bab5SJohan Hedberg 	if (lmp_pause_enc_capable(hdev))
14832177bab5SJohan Hedberg 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
14842177bab5SJohan Hedberg 
14852177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
14862177bab5SJohan Hedberg 		events[5] |= 0x40; /* Extended Inquiry Result */
14872177bab5SJohan Hedberg 
14882177bab5SJohan Hedberg 	if (lmp_no_flush_capable(hdev))
14892177bab5SJohan Hedberg 		events[7] |= 0x01; /* Enhanced Flush Complete */
14902177bab5SJohan Hedberg 
14912177bab5SJohan Hedberg 	if (lmp_lsto_capable(hdev))
14922177bab5SJohan Hedberg 		events[6] |= 0x80; /* Link Supervision Timeout Changed */
14932177bab5SJohan Hedberg 
14942177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
14952177bab5SJohan Hedberg 		events[6] |= 0x01;	/* IO Capability Request */
14962177bab5SJohan Hedberg 		events[6] |= 0x02;	/* IO Capability Response */
14972177bab5SJohan Hedberg 		events[6] |= 0x04;	/* User Confirmation Request */
14982177bab5SJohan Hedberg 		events[6] |= 0x08;	/* User Passkey Request */
14992177bab5SJohan Hedberg 		events[6] |= 0x10;	/* Remote OOB Data Request */
15002177bab5SJohan Hedberg 		events[6] |= 0x20;	/* Simple Pairing Complete */
15012177bab5SJohan Hedberg 		events[7] |= 0x04;	/* User Passkey Notification */
15022177bab5SJohan Hedberg 		events[7] |= 0x08;	/* Keypress Notification */
15032177bab5SJohan Hedberg 		events[7] |= 0x10;	/* Remote Host Supported
15042177bab5SJohan Hedberg 					 * Features Notification
15052177bab5SJohan Hedberg 					 */
15062177bab5SJohan Hedberg 	}
15072177bab5SJohan Hedberg 
15082177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
15092177bab5SJohan Hedberg 		events[7] |= 0x20;	/* LE Meta-Event */
15102177bab5SJohan Hedberg 
151142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
15122177bab5SJohan Hedberg }
15132177bab5SJohan Hedberg 
151442c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt)
15152177bab5SJohan Hedberg {
151642c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
151742c6b129SJohan Hedberg 
15182177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev))
151942c6b129SJohan Hedberg 		bredr_setup(req);
152056f87901SJohan Hedberg 	else
152156f87901SJohan Hedberg 		clear_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
15222177bab5SJohan Hedberg 
15232177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
152442c6b129SJohan Hedberg 		le_setup(req);
15252177bab5SJohan Hedberg 
15263f8e2d75SJohan Hedberg 	/* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read
15273f8e2d75SJohan Hedberg 	 * local supported commands HCI command.
15283f8e2d75SJohan Hedberg 	 */
15293f8e2d75SJohan Hedberg 	if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1)
153042c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
15312177bab5SJohan Hedberg 
15322177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
153357af75a8SMarcel Holtmann 		/* When SSP is available, then the host features page
153457af75a8SMarcel Holtmann 		 * should also be available as well. However some
153557af75a8SMarcel Holtmann 		 * controllers list the max_page as 0 as long as SSP
153657af75a8SMarcel Holtmann 		 * has not been enabled. To achieve proper debugging
153757af75a8SMarcel Holtmann 		 * output, force the minimum max_page to 1 at least.
153857af75a8SMarcel Holtmann 		 */
153957af75a8SMarcel Holtmann 		hdev->max_page = 0x01;
154057af75a8SMarcel Holtmann 
15412177bab5SJohan Hedberg 		if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
15422177bab5SJohan Hedberg 			u8 mode = 0x01;
154342c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_SSP_MODE,
15442177bab5SJohan Hedberg 				    sizeof(mode), &mode);
15452177bab5SJohan Hedberg 		} else {
15462177bab5SJohan Hedberg 			struct hci_cp_write_eir cp;
15472177bab5SJohan Hedberg 
15482177bab5SJohan Hedberg 			memset(hdev->eir, 0, sizeof(hdev->eir));
15492177bab5SJohan Hedberg 			memset(&cp, 0, sizeof(cp));
15502177bab5SJohan Hedberg 
155142c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
15522177bab5SJohan Hedberg 		}
15532177bab5SJohan Hedberg 	}
15542177bab5SJohan Hedberg 
15552177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
155642c6b129SJohan Hedberg 		hci_setup_inquiry_mode(req);
15572177bab5SJohan Hedberg 
15582177bab5SJohan Hedberg 	if (lmp_inq_tx_pwr_capable(hdev))
155942c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
15602177bab5SJohan Hedberg 
15612177bab5SJohan Hedberg 	if (lmp_ext_feat_capable(hdev)) {
15622177bab5SJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
15632177bab5SJohan Hedberg 
15642177bab5SJohan Hedberg 		cp.page = 0x01;
156542c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
156642c6b129SJohan Hedberg 			    sizeof(cp), &cp);
15672177bab5SJohan Hedberg 	}
15682177bab5SJohan Hedberg 
15692177bab5SJohan Hedberg 	if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
15702177bab5SJohan Hedberg 		u8 enable = 1;
157142c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
15722177bab5SJohan Hedberg 			    &enable);
15732177bab5SJohan Hedberg 	}
15742177bab5SJohan Hedberg }
15752177bab5SJohan Hedberg 
157642c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req)
15772177bab5SJohan Hedberg {
157842c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
15792177bab5SJohan Hedberg 	struct hci_cp_write_def_link_policy cp;
15802177bab5SJohan Hedberg 	u16 link_policy = 0;
15812177bab5SJohan Hedberg 
15822177bab5SJohan Hedberg 	if (lmp_rswitch_capable(hdev))
15832177bab5SJohan Hedberg 		link_policy |= HCI_LP_RSWITCH;
15842177bab5SJohan Hedberg 	if (lmp_hold_capable(hdev))
15852177bab5SJohan Hedberg 		link_policy |= HCI_LP_HOLD;
15862177bab5SJohan Hedberg 	if (lmp_sniff_capable(hdev))
15872177bab5SJohan Hedberg 		link_policy |= HCI_LP_SNIFF;
15882177bab5SJohan Hedberg 	if (lmp_park_capable(hdev))
15892177bab5SJohan Hedberg 		link_policy |= HCI_LP_PARK;
15902177bab5SJohan Hedberg 
15912177bab5SJohan Hedberg 	cp.policy = cpu_to_le16(link_policy);
159242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp);
15932177bab5SJohan Hedberg }
15942177bab5SJohan Hedberg 
159542c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req)
15962177bab5SJohan Hedberg {
159742c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
15982177bab5SJohan Hedberg 	struct hci_cp_write_le_host_supported cp;
15992177bab5SJohan Hedberg 
1600c73eee91SJohan Hedberg 	/* LE-only devices do not support explicit enablement */
1601c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
1602c73eee91SJohan Hedberg 		return;
1603c73eee91SJohan Hedberg 
16042177bab5SJohan Hedberg 	memset(&cp, 0, sizeof(cp));
16052177bab5SJohan Hedberg 
16062177bab5SJohan Hedberg 	if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
16072177bab5SJohan Hedberg 		cp.le = 0x01;
160832226e4fSMarcel Holtmann 		cp.simul = 0x00;
16092177bab5SJohan Hedberg 	}
16102177bab5SJohan Hedberg 
16112177bab5SJohan Hedberg 	if (cp.le != lmp_host_le_capable(hdev))
161242c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
16132177bab5SJohan Hedberg 			    &cp);
16142177bab5SJohan Hedberg }
16152177bab5SJohan Hedberg 
1616d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req)
1617d62e6d67SJohan Hedberg {
1618d62e6d67SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1619d62e6d67SJohan Hedberg 	u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1620d62e6d67SJohan Hedberg 
1621d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast master role is supported
1622d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
1623d62e6d67SJohan Hedberg 	 */
162453b834d2SMarcel Holtmann 	if (lmp_csb_master_capable(hdev)) {
1625d62e6d67SJohan Hedberg 		events[1] |= 0x40;	/* Triggered Clock Capture */
1626d62e6d67SJohan Hedberg 		events[1] |= 0x80;	/* Synchronization Train Complete */
1627d62e6d67SJohan Hedberg 		events[2] |= 0x10;	/* Slave Page Response Timeout */
1628d62e6d67SJohan Hedberg 		events[2] |= 0x20;	/* CSB Channel Map Change */
1629d62e6d67SJohan Hedberg 	}
1630d62e6d67SJohan Hedberg 
1631d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast slave role is supported
1632d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
1633d62e6d67SJohan Hedberg 	 */
163453b834d2SMarcel Holtmann 	if (lmp_csb_slave_capable(hdev)) {
1635d62e6d67SJohan Hedberg 		events[2] |= 0x01;	/* Synchronization Train Received */
1636d62e6d67SJohan Hedberg 		events[2] |= 0x02;	/* CSB Receive */
1637d62e6d67SJohan Hedberg 		events[2] |= 0x04;	/* CSB Timeout */
1638d62e6d67SJohan Hedberg 		events[2] |= 0x08;	/* Truncated Page Complete */
1639d62e6d67SJohan Hedberg 	}
1640d62e6d67SJohan Hedberg 
164140c59fcbSMarcel Holtmann 	/* Enable Authenticated Payload Timeout Expired event if supported */
1642cd7ca0ecSMarcel Holtmann 	if (lmp_ping_capable(hdev) || hdev->le_features[0] & HCI_LE_PING)
164340c59fcbSMarcel Holtmann 		events[2] |= 0x80;
164440c59fcbSMarcel Holtmann 
1645d62e6d67SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events);
1646d62e6d67SJohan Hedberg }
1647d62e6d67SJohan Hedberg 
164842c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt)
16492177bab5SJohan Hedberg {
165042c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1651d2c5d77fSJohan Hedberg 	u8 p;
165242c6b129SJohan Hedberg 
16530da71f1bSMarcel Holtmann 	hci_setup_event_mask(req);
16540da71f1bSMarcel Holtmann 
1655b8f4e068SGustavo Padovan 	/* Some Broadcom based Bluetooth controllers do not support the
1656b8f4e068SGustavo Padovan 	 * Delete Stored Link Key command. They are clearly indicating its
1657b8f4e068SGustavo Padovan 	 * absence in the bit mask of supported commands.
1658b8f4e068SGustavo Padovan 	 *
1659b8f4e068SGustavo Padovan 	 * Check the supported commands and only if the the command is marked
1660b8f4e068SGustavo Padovan 	 * as supported send it. If not supported assume that the controller
1661b8f4e068SGustavo Padovan 	 * does not have actual support for stored link keys which makes this
1662b8f4e068SGustavo Padovan 	 * command redundant anyway.
1663f9f462faSMarcel Holtmann 	 *
1664f9f462faSMarcel Holtmann 	 * Some controllers indicate that they support handling deleting
1665f9f462faSMarcel Holtmann 	 * stored link keys, but they don't. The quirk lets a driver
1666f9f462faSMarcel Holtmann 	 * just disable this command.
1667b8f4e068SGustavo Padovan 	 */
1668f9f462faSMarcel Holtmann 	if (hdev->commands[6] & 0x80 &&
1669f9f462faSMarcel Holtmann 	    !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) {
167059f45d57SJohan Hedberg 		struct hci_cp_delete_stored_link_key cp;
167159f45d57SJohan Hedberg 
167259f45d57SJohan Hedberg 		bacpy(&cp.bdaddr, BDADDR_ANY);
167359f45d57SJohan Hedberg 		cp.delete_all = 0x01;
167459f45d57SJohan Hedberg 		hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY,
167559f45d57SJohan Hedberg 			    sizeof(cp), &cp);
167659f45d57SJohan Hedberg 	}
167759f45d57SJohan Hedberg 
16782177bab5SJohan Hedberg 	if (hdev->commands[5] & 0x10)
167942c6b129SJohan Hedberg 		hci_setup_link_policy(req);
16802177bab5SJohan Hedberg 
16819193c6e8SAndre Guedes 	if (lmp_le_capable(hdev)) {
16829193c6e8SAndre Guedes 		u8 events[8];
16839193c6e8SAndre Guedes 
16849193c6e8SAndre Guedes 		memset(events, 0, sizeof(events));
16854d6c705bSMarcel Holtmann 		events[0] = 0x0f;
16864d6c705bSMarcel Holtmann 
16874d6c705bSMarcel Holtmann 		if (hdev->le_features[0] & HCI_LE_ENCRYPTION)
16884d6c705bSMarcel Holtmann 			events[0] |= 0x10;	/* LE Long Term Key Request */
1689662bc2e6SAndre Guedes 
1690662bc2e6SAndre Guedes 		/* If controller supports the Connection Parameters Request
1691662bc2e6SAndre Guedes 		 * Link Layer Procedure, enable the corresponding event.
1692662bc2e6SAndre Guedes 		 */
1693662bc2e6SAndre Guedes 		if (hdev->le_features[0] & HCI_LE_CONN_PARAM_REQ_PROC)
1694662bc2e6SAndre Guedes 			events[0] |= 0x20;	/* LE Remote Connection
1695662bc2e6SAndre Guedes 						 * Parameter Request
1696662bc2e6SAndre Guedes 						 */
1697662bc2e6SAndre Guedes 
16989193c6e8SAndre Guedes 		hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, sizeof(events),
16999193c6e8SAndre Guedes 			    events);
17009193c6e8SAndre Guedes 
170115a49ccaSMarcel Holtmann 		if (hdev->commands[25] & 0x40) {
170215a49ccaSMarcel Holtmann 			/* Read LE Advertising Channel TX Power */
170315a49ccaSMarcel Holtmann 			hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
170415a49ccaSMarcel Holtmann 		}
170515a49ccaSMarcel Holtmann 
170642c6b129SJohan Hedberg 		hci_set_le_support(req);
17079193c6e8SAndre Guedes 	}
1708d2c5d77fSJohan Hedberg 
1709d2c5d77fSJohan Hedberg 	/* Read features beyond page 1 if available */
1710d2c5d77fSJohan Hedberg 	for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
1711d2c5d77fSJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
1712d2c5d77fSJohan Hedberg 
1713d2c5d77fSJohan Hedberg 		cp.page = p;
1714d2c5d77fSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
1715d2c5d77fSJohan Hedberg 			    sizeof(cp), &cp);
1716d2c5d77fSJohan Hedberg 	}
17172177bab5SJohan Hedberg }
17182177bab5SJohan Hedberg 
17195d4e7e8dSJohan Hedberg static void hci_init4_req(struct hci_request *req, unsigned long opt)
17205d4e7e8dSJohan Hedberg {
17215d4e7e8dSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
17225d4e7e8dSJohan Hedberg 
1723d62e6d67SJohan Hedberg 	/* Set event mask page 2 if the HCI command for it is supported */
1724d62e6d67SJohan Hedberg 	if (hdev->commands[22] & 0x04)
1725d62e6d67SJohan Hedberg 		hci_set_event_mask_page_2(req);
1726d62e6d67SJohan Hedberg 
1727109e3191SMarcel Holtmann 	/* Read local codec list if the HCI command is supported */
1728109e3191SMarcel Holtmann 	if (hdev->commands[29] & 0x20)
1729109e3191SMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_LOCAL_CODECS, 0, NULL);
1730109e3191SMarcel Holtmann 
1731f4fe73edSMarcel Holtmann 	/* Get MWS transport configuration if the HCI command is supported */
1732f4fe73edSMarcel Holtmann 	if (hdev->commands[30] & 0x08)
1733f4fe73edSMarcel Holtmann 		hci_req_add(req, HCI_OP_GET_MWS_TRANSPORT_CONFIG, 0, NULL);
1734f4fe73edSMarcel Holtmann 
17355d4e7e8dSJohan Hedberg 	/* Check for Synchronization Train support */
173653b834d2SMarcel Holtmann 	if (lmp_sync_train_capable(hdev))
17375d4e7e8dSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL);
1738a6d0d690SMarcel Holtmann 
1739a6d0d690SMarcel Holtmann 	/* Enable Secure Connections if supported and configured */
17405afeac14SMarcel Holtmann 	if ((lmp_sc_capable(hdev) ||
1741111902f7SMarcel Holtmann 	     test_bit(HCI_FORCE_SC, &hdev->dbg_flags)) &&
1742a6d0d690SMarcel Holtmann 	    test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
1743a6d0d690SMarcel Holtmann 		u8 support = 0x01;
1744a6d0d690SMarcel Holtmann 		hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT,
1745a6d0d690SMarcel Holtmann 			    sizeof(support), &support);
1746a6d0d690SMarcel Holtmann 	}
17475d4e7e8dSJohan Hedberg }
17485d4e7e8dSJohan Hedberg 
17492177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev)
17502177bab5SJohan Hedberg {
17512177bab5SJohan Hedberg 	int err;
17522177bab5SJohan Hedberg 
17532177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT);
17542177bab5SJohan Hedberg 	if (err < 0)
17552177bab5SJohan Hedberg 		return err;
17562177bab5SJohan Hedberg 
17574b4148e9SMarcel Holtmann 	/* The Device Under Test (DUT) mode is special and available for
17584b4148e9SMarcel Holtmann 	 * all controller types. So just create it early on.
17594b4148e9SMarcel Holtmann 	 */
17604b4148e9SMarcel Holtmann 	if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
17614b4148e9SMarcel Holtmann 		debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev,
17624b4148e9SMarcel Holtmann 				    &dut_mode_fops);
17634b4148e9SMarcel Holtmann 	}
17644b4148e9SMarcel Holtmann 
17652177bab5SJohan Hedberg 	/* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode
17662177bab5SJohan Hedberg 	 * BR/EDR/LE type controllers. AMP controllers only need the
17672177bab5SJohan Hedberg 	 * first stage init.
17682177bab5SJohan Hedberg 	 */
17692177bab5SJohan Hedberg 	if (hdev->dev_type != HCI_BREDR)
17702177bab5SJohan Hedberg 		return 0;
17712177bab5SJohan Hedberg 
17722177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT);
17732177bab5SJohan Hedberg 	if (err < 0)
17742177bab5SJohan Hedberg 		return err;
17752177bab5SJohan Hedberg 
17765d4e7e8dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT);
17775d4e7e8dSJohan Hedberg 	if (err < 0)
17785d4e7e8dSJohan Hedberg 		return err;
17795d4e7e8dSJohan Hedberg 
1780baf27f6eSMarcel Holtmann 	err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT);
1781baf27f6eSMarcel Holtmann 	if (err < 0)
1782baf27f6eSMarcel Holtmann 		return err;
1783baf27f6eSMarcel Holtmann 
1784baf27f6eSMarcel Holtmann 	/* Only create debugfs entries during the initial setup
1785baf27f6eSMarcel Holtmann 	 * phase and not every time the controller gets powered on.
1786baf27f6eSMarcel Holtmann 	 */
1787baf27f6eSMarcel Holtmann 	if (!test_bit(HCI_SETUP, &hdev->dev_flags))
1788baf27f6eSMarcel Holtmann 		return 0;
1789baf27f6eSMarcel Holtmann 
1790dfb826a8SMarcel Holtmann 	debugfs_create_file("features", 0444, hdev->debugfs, hdev,
1791dfb826a8SMarcel Holtmann 			    &features_fops);
1792ceeb3bc0SMarcel Holtmann 	debugfs_create_u16("manufacturer", 0444, hdev->debugfs,
1793ceeb3bc0SMarcel Holtmann 			   &hdev->manufacturer);
1794ceeb3bc0SMarcel Holtmann 	debugfs_create_u8("hci_version", 0444, hdev->debugfs, &hdev->hci_ver);
1795ceeb3bc0SMarcel Holtmann 	debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev);
179640f4938aSMarcel Holtmann 	debugfs_create_file("device_list", 0444, hdev->debugfs, hdev,
179740f4938aSMarcel Holtmann 			    &device_list_fops);
179870afe0b8SMarcel Holtmann 	debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev,
179970afe0b8SMarcel Holtmann 			    &blacklist_fops);
180047219839SMarcel Holtmann 	debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops);
180147219839SMarcel Holtmann 
180231ad1691SAndrzej Kaczmarek 	debugfs_create_file("conn_info_min_age", 0644, hdev->debugfs, hdev,
180331ad1691SAndrzej Kaczmarek 			    &conn_info_min_age_fops);
180431ad1691SAndrzej Kaczmarek 	debugfs_create_file("conn_info_max_age", 0644, hdev->debugfs, hdev,
180531ad1691SAndrzej Kaczmarek 			    &conn_info_max_age_fops);
180631ad1691SAndrzej Kaczmarek 
1807baf27f6eSMarcel Holtmann 	if (lmp_bredr_capable(hdev)) {
1808baf27f6eSMarcel Holtmann 		debugfs_create_file("inquiry_cache", 0444, hdev->debugfs,
1809baf27f6eSMarcel Holtmann 				    hdev, &inquiry_cache_fops);
181002d08d15SMarcel Holtmann 		debugfs_create_file("link_keys", 0400, hdev->debugfs,
181102d08d15SMarcel Holtmann 				    hdev, &link_keys_fops);
1812babdbb3cSMarcel Holtmann 		debugfs_create_file("dev_class", 0444, hdev->debugfs,
1813babdbb3cSMarcel Holtmann 				    hdev, &dev_class_fops);
1814041000b9SMarcel Holtmann 		debugfs_create_file("voice_setting", 0444, hdev->debugfs,
1815041000b9SMarcel Holtmann 				    hdev, &voice_setting_fops);
1816baf27f6eSMarcel Holtmann 	}
1817baf27f6eSMarcel Holtmann 
181806f5b778SMarcel Holtmann 	if (lmp_ssp_capable(hdev)) {
1819ebd1e33bSMarcel Holtmann 		debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs,
1820ebd1e33bSMarcel Holtmann 				    hdev, &auto_accept_delay_fops);
18215afeac14SMarcel Holtmann 		debugfs_create_file("force_sc_support", 0644, hdev->debugfs,
18225afeac14SMarcel Holtmann 				    hdev, &force_sc_support_fops);
1823134c2a89SMarcel Holtmann 		debugfs_create_file("sc_only_mode", 0444, hdev->debugfs,
1824134c2a89SMarcel Holtmann 				    hdev, &sc_only_mode_fops);
182506f5b778SMarcel Holtmann 	}
1826ebd1e33bSMarcel Holtmann 
18272bfa3531SMarcel Holtmann 	if (lmp_sniff_capable(hdev)) {
18282bfa3531SMarcel Holtmann 		debugfs_create_file("idle_timeout", 0644, hdev->debugfs,
18292bfa3531SMarcel Holtmann 				    hdev, &idle_timeout_fops);
18302bfa3531SMarcel Holtmann 		debugfs_create_file("sniff_min_interval", 0644, hdev->debugfs,
18312bfa3531SMarcel Holtmann 				    hdev, &sniff_min_interval_fops);
18322bfa3531SMarcel Holtmann 		debugfs_create_file("sniff_max_interval", 0644, hdev->debugfs,
18332bfa3531SMarcel Holtmann 				    hdev, &sniff_max_interval_fops);
18342bfa3531SMarcel Holtmann 	}
18352bfa3531SMarcel Holtmann 
1836d0f729b8SMarcel Holtmann 	if (lmp_le_capable(hdev)) {
1837ac345813SMarcel Holtmann 		debugfs_create_file("identity", 0400, hdev->debugfs,
1838ac345813SMarcel Holtmann 				    hdev, &identity_fops);
1839ac345813SMarcel Holtmann 		debugfs_create_file("rpa_timeout", 0644, hdev->debugfs,
1840ac345813SMarcel Holtmann 				    hdev, &rpa_timeout_fops);
18417a4cd51dSMarcel Holtmann 		debugfs_create_file("random_address", 0444, hdev->debugfs,
18427a4cd51dSMarcel Holtmann 				    hdev, &random_address_fops);
1843e7b8fc92SMarcel Holtmann 		debugfs_create_file("static_address", 0444, hdev->debugfs,
1844e7b8fc92SMarcel Holtmann 				    hdev, &static_address_fops);
1845b32bba6cSMarcel Holtmann 
1846b32bba6cSMarcel Holtmann 		/* For controllers with a public address, provide a debug
1847b32bba6cSMarcel Holtmann 		 * option to force the usage of the configured static
1848b32bba6cSMarcel Holtmann 		 * address. By default the public address is used.
1849b32bba6cSMarcel Holtmann 		 */
1850b32bba6cSMarcel Holtmann 		if (bacmp(&hdev->bdaddr, BDADDR_ANY))
1851b32bba6cSMarcel Holtmann 			debugfs_create_file("force_static_address", 0644,
1852b32bba6cSMarcel Holtmann 					    hdev->debugfs, hdev,
1853b32bba6cSMarcel Holtmann 					    &force_static_address_fops);
1854b32bba6cSMarcel Holtmann 
1855b32bba6cSMarcel Holtmann 		debugfs_create_u8("white_list_size", 0444, hdev->debugfs,
1856b32bba6cSMarcel Holtmann 				  &hdev->le_white_list_size);
1857d2ab0ac1SMarcel Holtmann 		debugfs_create_file("white_list", 0444, hdev->debugfs, hdev,
1858d2ab0ac1SMarcel Holtmann 				    &white_list_fops);
18593698d704SMarcel Holtmann 		debugfs_create_file("identity_resolving_keys", 0400,
18603698d704SMarcel Holtmann 				    hdev->debugfs, hdev,
18613698d704SMarcel Holtmann 				    &identity_resolving_keys_fops);
18628f8625cdSMarcel Holtmann 		debugfs_create_file("long_term_keys", 0400, hdev->debugfs,
18638f8625cdSMarcel Holtmann 				    hdev, &long_term_keys_fops);
18644e70c7e7SMarcel Holtmann 		debugfs_create_file("conn_min_interval", 0644, hdev->debugfs,
18654e70c7e7SMarcel Holtmann 				    hdev, &conn_min_interval_fops);
18664e70c7e7SMarcel Holtmann 		debugfs_create_file("conn_max_interval", 0644, hdev->debugfs,
18674e70c7e7SMarcel Holtmann 				    hdev, &conn_max_interval_fops);
1868816a93d1SMarcel Holtmann 		debugfs_create_file("conn_latency", 0644, hdev->debugfs,
1869816a93d1SMarcel Holtmann 				    hdev, &conn_latency_fops);
1870f1649577SMarcel Holtmann 		debugfs_create_file("supervision_timeout", 0644, hdev->debugfs,
1871f1649577SMarcel Holtmann 				    hdev, &supervision_timeout_fops);
18723f959d46SMarcel Holtmann 		debugfs_create_file("adv_channel_map", 0644, hdev->debugfs,
18733f959d46SMarcel Holtmann 				    hdev, &adv_channel_map_fops);
1874729a1051SGeorg Lukas 		debugfs_create_file("adv_min_interval", 0644, hdev->debugfs,
1875729a1051SGeorg Lukas 				    hdev, &adv_min_interval_fops);
1876729a1051SGeorg Lukas 		debugfs_create_file("adv_max_interval", 0644, hdev->debugfs,
1877729a1051SGeorg Lukas 				    hdev, &adv_max_interval_fops);
1878b9a7a61eSLukasz Rymanowski 		debugfs_create_u16("discov_interleaved_timeout", 0644,
1879b9a7a61eSLukasz Rymanowski 				   hdev->debugfs,
1880b9a7a61eSLukasz Rymanowski 				   &hdev->discov_interleaved_timeout);
188154506918SJohan Hedberg 
1882711eafe3SJohan Hedberg 		smp_register(hdev);
1883d0f729b8SMarcel Holtmann 	}
1884e7b8fc92SMarcel Holtmann 
1885baf27f6eSMarcel Holtmann 	return 0;
18862177bab5SJohan Hedberg }
18872177bab5SJohan Hedberg 
18880ebca7d6SMarcel Holtmann static void hci_init0_req(struct hci_request *req, unsigned long opt)
18890ebca7d6SMarcel Holtmann {
18900ebca7d6SMarcel Holtmann 	struct hci_dev *hdev = req->hdev;
18910ebca7d6SMarcel Holtmann 
18920ebca7d6SMarcel Holtmann 	BT_DBG("%s %ld", hdev->name, opt);
18930ebca7d6SMarcel Holtmann 
18940ebca7d6SMarcel Holtmann 	/* Reset */
18950ebca7d6SMarcel Holtmann 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
18960ebca7d6SMarcel Holtmann 		hci_reset_req(req, 0);
18970ebca7d6SMarcel Holtmann 
18980ebca7d6SMarcel Holtmann 	/* Read Local Version */
18990ebca7d6SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
19000ebca7d6SMarcel Holtmann 
19010ebca7d6SMarcel Holtmann 	/* Read BD Address */
19020ebca7d6SMarcel Holtmann 	if (hdev->set_bdaddr)
19030ebca7d6SMarcel Holtmann 		hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
19040ebca7d6SMarcel Holtmann }
19050ebca7d6SMarcel Holtmann 
19060ebca7d6SMarcel Holtmann static int __hci_unconf_init(struct hci_dev *hdev)
19070ebca7d6SMarcel Holtmann {
19080ebca7d6SMarcel Holtmann 	int err;
19090ebca7d6SMarcel Holtmann 
1910cc78b44bSMarcel Holtmann 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
1911cc78b44bSMarcel Holtmann 		return 0;
1912cc78b44bSMarcel Holtmann 
19130ebca7d6SMarcel Holtmann 	err = __hci_req_sync(hdev, hci_init0_req, 0, HCI_INIT_TIMEOUT);
19140ebca7d6SMarcel Holtmann 	if (err < 0)
19150ebca7d6SMarcel Holtmann 		return err;
19160ebca7d6SMarcel Holtmann 
19170ebca7d6SMarcel Holtmann 	return 0;
19180ebca7d6SMarcel Holtmann }
19190ebca7d6SMarcel Holtmann 
192042c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt)
19211da177e4SLinus Torvalds {
19221da177e4SLinus Torvalds 	__u8 scan = opt;
19231da177e4SLinus Torvalds 
192442c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, scan);
19251da177e4SLinus Torvalds 
19261da177e4SLinus Torvalds 	/* Inquiry and Page scans */
192742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
19281da177e4SLinus Torvalds }
19291da177e4SLinus Torvalds 
193042c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt)
19311da177e4SLinus Torvalds {
19321da177e4SLinus Torvalds 	__u8 auth = opt;
19331da177e4SLinus Torvalds 
193442c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, auth);
19351da177e4SLinus Torvalds 
19361da177e4SLinus Torvalds 	/* Authentication */
193742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
19381da177e4SLinus Torvalds }
19391da177e4SLinus Torvalds 
194042c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt)
19411da177e4SLinus Torvalds {
19421da177e4SLinus Torvalds 	__u8 encrypt = opt;
19431da177e4SLinus Torvalds 
194442c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, encrypt);
19451da177e4SLinus Torvalds 
1946e4e8e37cSMarcel Holtmann 	/* Encryption */
194742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
19481da177e4SLinus Torvalds }
19491da177e4SLinus Torvalds 
195042c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt)
1951e4e8e37cSMarcel Holtmann {
1952e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
1953e4e8e37cSMarcel Holtmann 
195442c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, policy);
1955e4e8e37cSMarcel Holtmann 
1956e4e8e37cSMarcel Holtmann 	/* Default link policy */
195742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
1958e4e8e37cSMarcel Holtmann }
1959e4e8e37cSMarcel Holtmann 
19601da177e4SLinus Torvalds /* Get HCI device by index.
19611da177e4SLinus Torvalds  * Device is held on return. */
19621da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
19631da177e4SLinus Torvalds {
19648035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
19651da177e4SLinus Torvalds 
19661da177e4SLinus Torvalds 	BT_DBG("%d", index);
19671da177e4SLinus Torvalds 
19681da177e4SLinus Torvalds 	if (index < 0)
19691da177e4SLinus Torvalds 		return NULL;
19701da177e4SLinus Torvalds 
19711da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
19728035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
19731da177e4SLinus Torvalds 		if (d->id == index) {
19741da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
19751da177e4SLinus Torvalds 			break;
19761da177e4SLinus Torvalds 		}
19771da177e4SLinus Torvalds 	}
19781da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
19791da177e4SLinus Torvalds 	return hdev;
19801da177e4SLinus Torvalds }
19811da177e4SLinus Torvalds 
19821da177e4SLinus Torvalds /* ---- Inquiry support ---- */
1983ff9ef578SJohan Hedberg 
198430dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
198530dc78e1SJohan Hedberg {
198630dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
198730dc78e1SJohan Hedberg 
19886fbe195dSAndre Guedes 	switch (discov->state) {
1989343f935bSAndre Guedes 	case DISCOVERY_FINDING:
19906fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
199130dc78e1SJohan Hedberg 		return true;
199230dc78e1SJohan Hedberg 
19936fbe195dSAndre Guedes 	default:
199430dc78e1SJohan Hedberg 		return false;
199530dc78e1SJohan Hedberg 	}
19966fbe195dSAndre Guedes }
199730dc78e1SJohan Hedberg 
1998ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
1999ff9ef578SJohan Hedberg {
2000bb3e0a33SJohan Hedberg 	int old_state = hdev->discovery.state;
2001bb3e0a33SJohan Hedberg 
2002ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
2003ff9ef578SJohan Hedberg 
2004bb3e0a33SJohan Hedberg 	if (old_state == state)
2005ff9ef578SJohan Hedberg 		return;
2006ff9ef578SJohan Hedberg 
2007bb3e0a33SJohan Hedberg 	hdev->discovery.state = state;
2008bb3e0a33SJohan Hedberg 
2009ff9ef578SJohan Hedberg 	switch (state) {
2010ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
2011c54c3860SAndre Guedes 		hci_update_background_scan(hdev);
2012c54c3860SAndre Guedes 
2013bb3e0a33SJohan Hedberg 		if (old_state != DISCOVERY_STARTING)
2014ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
2015ff9ef578SJohan Hedberg 		break;
2016ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
2017ff9ef578SJohan Hedberg 		break;
2018343f935bSAndre Guedes 	case DISCOVERY_FINDING:
2019ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
2020ff9ef578SJohan Hedberg 		break;
202130dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
202230dc78e1SJohan Hedberg 		break;
2023ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
2024ff9ef578SJohan Hedberg 		break;
2025ff9ef578SJohan Hedberg 	}
2026ff9ef578SJohan Hedberg }
2027ff9ef578SJohan Hedberg 
20281f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev)
20291da177e4SLinus Torvalds {
203030883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
2031b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
20321da177e4SLinus Torvalds 
2033561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
2034561aafbcSJohan Hedberg 		list_del(&p->all);
2035b57c1a56SJohan Hedberg 		kfree(p);
20361da177e4SLinus Torvalds 	}
2037561aafbcSJohan Hedberg 
2038561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
2039561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
20401da177e4SLinus Torvalds }
20411da177e4SLinus Torvalds 
2042a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
2043a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
20441da177e4SLinus Torvalds {
204530883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
20461da177e4SLinus Torvalds 	struct inquiry_entry *e;
20471da177e4SLinus Torvalds 
20486ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
20491da177e4SLinus Torvalds 
2050561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
20511da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
20521da177e4SLinus Torvalds 			return e;
20531da177e4SLinus Torvalds 	}
20541da177e4SLinus Torvalds 
2055b57c1a56SJohan Hedberg 	return NULL;
2056b57c1a56SJohan Hedberg }
2057b57c1a56SJohan Hedberg 
2058561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
2059561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
2060561aafbcSJohan Hedberg {
206130883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
2062561aafbcSJohan Hedberg 	struct inquiry_entry *e;
2063561aafbcSJohan Hedberg 
20646ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
2065561aafbcSJohan Hedberg 
2066561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
2067561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
2068561aafbcSJohan Hedberg 			return e;
2069561aafbcSJohan Hedberg 	}
2070561aafbcSJohan Hedberg 
2071561aafbcSJohan Hedberg 	return NULL;
2072561aafbcSJohan Hedberg }
2073561aafbcSJohan Hedberg 
207430dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
207530dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
207630dc78e1SJohan Hedberg 						       int state)
207730dc78e1SJohan Hedberg {
207830dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
207930dc78e1SJohan Hedberg 	struct inquiry_entry *e;
208030dc78e1SJohan Hedberg 
20816ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
208230dc78e1SJohan Hedberg 
208330dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
208430dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
208530dc78e1SJohan Hedberg 			return e;
208630dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
208730dc78e1SJohan Hedberg 			return e;
208830dc78e1SJohan Hedberg 	}
208930dc78e1SJohan Hedberg 
209030dc78e1SJohan Hedberg 	return NULL;
209130dc78e1SJohan Hedberg }
209230dc78e1SJohan Hedberg 
2093a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
2094a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
2095a3d4e20aSJohan Hedberg {
2096a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
2097a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
2098a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
2099a3d4e20aSJohan Hedberg 
2100a3d4e20aSJohan Hedberg 	list_del(&ie->list);
2101a3d4e20aSJohan Hedberg 
2102a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
2103a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
2104a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
2105a3d4e20aSJohan Hedberg 			break;
2106a3d4e20aSJohan Hedberg 		pos = &p->list;
2107a3d4e20aSJohan Hedberg 	}
2108a3d4e20aSJohan Hedberg 
2109a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
2110a3d4e20aSJohan Hedberg }
2111a3d4e20aSJohan Hedberg 
2112af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
2113af58925cSMarcel Holtmann 			     bool name_known)
21141da177e4SLinus Torvalds {
211530883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
211670f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
2117af58925cSMarcel Holtmann 	u32 flags = 0;
21181da177e4SLinus Torvalds 
21196ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
21201da177e4SLinus Torvalds 
21212b2fec4dSSzymon Janc 	hci_remove_remote_oob_data(hdev, &data->bdaddr);
21222b2fec4dSSzymon Janc 
2123af58925cSMarcel Holtmann 	if (!data->ssp_mode)
2124af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
2125388fc8faSJohan Hedberg 
212670f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
2127a3d4e20aSJohan Hedberg 	if (ie) {
2128af58925cSMarcel Holtmann 		if (!ie->data.ssp_mode)
2129af58925cSMarcel Holtmann 			flags |= MGMT_DEV_FOUND_LEGACY_PAIRING;
2130388fc8faSJohan Hedberg 
2131a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
2132a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
2133a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
2134a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
2135a3d4e20aSJohan Hedberg 		}
2136a3d4e20aSJohan Hedberg 
2137561aafbcSJohan Hedberg 		goto update;
2138a3d4e20aSJohan Hedberg 	}
2139561aafbcSJohan Hedberg 
21401da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
214127f70f3eSJohan Hedberg 	ie = kzalloc(sizeof(*ie), GFP_KERNEL);
2142af58925cSMarcel Holtmann 	if (!ie) {
2143af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
2144af58925cSMarcel Holtmann 		goto done;
2145af58925cSMarcel Holtmann 	}
214670f23020SAndrei Emeltchenko 
2147561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
2148561aafbcSJohan Hedberg 
2149561aafbcSJohan Hedberg 	if (name_known) {
2150561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
2151561aafbcSJohan Hedberg 	} else {
2152561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
2153561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
2154561aafbcSJohan Hedberg 	}
2155561aafbcSJohan Hedberg 
2156561aafbcSJohan Hedberg update:
2157561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
2158561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
2159561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
2160561aafbcSJohan Hedberg 		list_del(&ie->list);
21611da177e4SLinus Torvalds 	}
21621da177e4SLinus Torvalds 
216370f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
216470f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
21651da177e4SLinus Torvalds 	cache->timestamp = jiffies;
21663175405bSJohan Hedberg 
21673175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
2168af58925cSMarcel Holtmann 		flags |= MGMT_DEV_FOUND_CONFIRM_NAME;
21693175405bSJohan Hedberg 
2170af58925cSMarcel Holtmann done:
2171af58925cSMarcel Holtmann 	return flags;
21721da177e4SLinus Torvalds }
21731da177e4SLinus Torvalds 
21741da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
21751da177e4SLinus Torvalds {
217630883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
21771da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
21781da177e4SLinus Torvalds 	struct inquiry_entry *e;
21791da177e4SLinus Torvalds 	int copied = 0;
21801da177e4SLinus Torvalds 
2181561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
21821da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
2183b57c1a56SJohan Hedberg 
2184b57c1a56SJohan Hedberg 		if (copied >= num)
2185b57c1a56SJohan Hedberg 			break;
2186b57c1a56SJohan Hedberg 
21871da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
21881da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
21891da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
21901da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
21911da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
21921da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
2193b57c1a56SJohan Hedberg 
21941da177e4SLinus Torvalds 		info++;
2195b57c1a56SJohan Hedberg 		copied++;
21961da177e4SLinus Torvalds 	}
21971da177e4SLinus Torvalds 
21981da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
21991da177e4SLinus Torvalds 	return copied;
22001da177e4SLinus Torvalds }
22011da177e4SLinus Torvalds 
220242c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt)
22031da177e4SLinus Torvalds {
22041da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
220542c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
22061da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
22071da177e4SLinus Torvalds 
22081da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
22091da177e4SLinus Torvalds 
22101da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
22111da177e4SLinus Torvalds 		return;
22121da177e4SLinus Torvalds 
22131da177e4SLinus Torvalds 	/* Start Inquiry */
22141da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
22151da177e4SLinus Torvalds 	cp.length  = ir->length;
22161da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
221742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
22181da177e4SLinus Torvalds }
22191da177e4SLinus Torvalds 
22201da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
22211da177e4SLinus Torvalds {
22221da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
22231da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
22241da177e4SLinus Torvalds 	struct hci_dev *hdev;
22251da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
22261da177e4SLinus Torvalds 	long timeo;
22271da177e4SLinus Torvalds 	__u8 *buf;
22281da177e4SLinus Torvalds 
22291da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
22301da177e4SLinus Torvalds 		return -EFAULT;
22311da177e4SLinus Torvalds 
22325a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
22335a08ecceSAndrei Emeltchenko 	if (!hdev)
22341da177e4SLinus Torvalds 		return -ENODEV;
22351da177e4SLinus Torvalds 
22360736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
22370736cfa8SMarcel Holtmann 		err = -EBUSY;
22380736cfa8SMarcel Holtmann 		goto done;
22390736cfa8SMarcel Holtmann 	}
22400736cfa8SMarcel Holtmann 
22414a964404SMarcel Holtmann 	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
2242fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
2243fee746b0SMarcel Holtmann 		goto done;
2244fee746b0SMarcel Holtmann 	}
2245fee746b0SMarcel Holtmann 
22465b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
22475b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
22485b69bef5SMarcel Holtmann 		goto done;
22495b69bef5SMarcel Holtmann 	}
22505b69bef5SMarcel Holtmann 
225156f87901SJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
225256f87901SJohan Hedberg 		err = -EOPNOTSUPP;
225356f87901SJohan Hedberg 		goto done;
225456f87901SJohan Hedberg 	}
225556f87901SJohan Hedberg 
225609fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
22571da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
2258a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
22591f9b9a5dSAndre Guedes 		hci_inquiry_cache_flush(hdev);
22601da177e4SLinus Torvalds 		do_inquiry = 1;
22611da177e4SLinus Torvalds 	}
226209fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
22631da177e4SLinus Torvalds 
226404837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
226570f23020SAndrei Emeltchenko 
226670f23020SAndrei Emeltchenko 	if (do_inquiry) {
226701178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
226801178cd4SJohan Hedberg 				   timeo);
226970f23020SAndrei Emeltchenko 		if (err < 0)
22701da177e4SLinus Torvalds 			goto done;
22713e13fa1eSAndre Guedes 
22723e13fa1eSAndre Guedes 		/* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
22733e13fa1eSAndre Guedes 		 * cleared). If it is interrupted by a signal, return -EINTR.
22743e13fa1eSAndre Guedes 		 */
227574316201SNeilBrown 		if (wait_on_bit(&hdev->flags, HCI_INQUIRY,
22763e13fa1eSAndre Guedes 				TASK_INTERRUPTIBLE))
22773e13fa1eSAndre Guedes 			return -EINTR;
227870f23020SAndrei Emeltchenko 	}
22791da177e4SLinus Torvalds 
22808fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
22818fc9ced3SGustavo Padovan 	 * 255 entries
22828fc9ced3SGustavo Padovan 	 */
22831da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
22841da177e4SLinus Torvalds 
22851da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
22861da177e4SLinus Torvalds 	 * copy it to the user space.
22871da177e4SLinus Torvalds 	 */
228870f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
228970f23020SAndrei Emeltchenko 	if (!buf) {
22901da177e4SLinus Torvalds 		err = -ENOMEM;
22911da177e4SLinus Torvalds 		goto done;
22921da177e4SLinus Torvalds 	}
22931da177e4SLinus Torvalds 
229409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
22951da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
229609fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
22971da177e4SLinus Torvalds 
22981da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
22991da177e4SLinus Torvalds 
23001da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
23011da177e4SLinus Torvalds 		ptr += sizeof(ir);
23021da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
23031da177e4SLinus Torvalds 				 ir.num_rsp))
23041da177e4SLinus Torvalds 			err = -EFAULT;
23051da177e4SLinus Torvalds 	} else
23061da177e4SLinus Torvalds 		err = -EFAULT;
23071da177e4SLinus Torvalds 
23081da177e4SLinus Torvalds 	kfree(buf);
23091da177e4SLinus Torvalds 
23101da177e4SLinus Torvalds done:
23111da177e4SLinus Torvalds 	hci_dev_put(hdev);
23121da177e4SLinus Torvalds 	return err;
23131da177e4SLinus Torvalds }
23141da177e4SLinus Torvalds 
2315cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev)
23161da177e4SLinus Torvalds {
23171da177e4SLinus Torvalds 	int ret = 0;
23181da177e4SLinus Torvalds 
23191da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
23201da177e4SLinus Torvalds 
23211da177e4SLinus Torvalds 	hci_req_lock(hdev);
23221da177e4SLinus Torvalds 
232394324962SJohan Hovold 	if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) {
232494324962SJohan Hovold 		ret = -ENODEV;
232594324962SJohan Hovold 		goto done;
232694324962SJohan Hovold 	}
232794324962SJohan Hovold 
2328d603b76bSMarcel Holtmann 	if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
2329d603b76bSMarcel Holtmann 	    !test_bit(HCI_CONFIG, &hdev->dev_flags)) {
2330a5c8f270SMarcel Holtmann 		/* Check for rfkill but allow the HCI setup stage to
2331a5c8f270SMarcel Holtmann 		 * proceed (which in itself doesn't cause any RF activity).
2332bf543036SJohan Hedberg 		 */
2333a5c8f270SMarcel Holtmann 		if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) {
2334611b30f7SMarcel Holtmann 			ret = -ERFKILL;
2335611b30f7SMarcel Holtmann 			goto done;
2336611b30f7SMarcel Holtmann 		}
2337611b30f7SMarcel Holtmann 
2338a5c8f270SMarcel Holtmann 		/* Check for valid public address or a configured static
2339a5c8f270SMarcel Holtmann 		 * random adddress, but let the HCI setup proceed to
2340a5c8f270SMarcel Holtmann 		 * be able to determine if there is a public address
2341a5c8f270SMarcel Holtmann 		 * or not.
2342a5c8f270SMarcel Holtmann 		 *
2343c6beca0eSMarcel Holtmann 		 * In case of user channel usage, it is not important
2344c6beca0eSMarcel Holtmann 		 * if a public address or static random address is
2345c6beca0eSMarcel Holtmann 		 * available.
2346c6beca0eSMarcel Holtmann 		 *
2347a5c8f270SMarcel Holtmann 		 * This check is only valid for BR/EDR controllers
2348a5c8f270SMarcel Holtmann 		 * since AMP controllers do not have an address.
2349a5c8f270SMarcel Holtmann 		 */
2350c6beca0eSMarcel Holtmann 		if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
2351c6beca0eSMarcel Holtmann 		    hdev->dev_type == HCI_BREDR &&
2352a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
2353a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->static_addr, BDADDR_ANY)) {
2354a5c8f270SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
2355a5c8f270SMarcel Holtmann 			goto done;
2356a5c8f270SMarcel Holtmann 		}
2357a5c8f270SMarcel Holtmann 	}
2358a5c8f270SMarcel Holtmann 
23591da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
23601da177e4SLinus Torvalds 		ret = -EALREADY;
23611da177e4SLinus Torvalds 		goto done;
23621da177e4SLinus Torvalds 	}
23631da177e4SLinus Torvalds 
23641da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
23651da177e4SLinus Torvalds 		ret = -EIO;
23661da177e4SLinus Torvalds 		goto done;
23671da177e4SLinus Torvalds 	}
23681da177e4SLinus Torvalds 
23691da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
23701da177e4SLinus Torvalds 	set_bit(HCI_INIT, &hdev->flags);
2371f41c70c4SMarcel Holtmann 
2372af202f84SMarcel Holtmann 	if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
2373af202f84SMarcel Holtmann 		if (hdev->setup)
2374f41c70c4SMarcel Holtmann 			ret = hdev->setup(hdev);
2375f41c70c4SMarcel Holtmann 
2376af202f84SMarcel Holtmann 		/* The transport driver can set these quirks before
2377af202f84SMarcel Holtmann 		 * creating the HCI device or in its setup callback.
2378af202f84SMarcel Holtmann 		 *
2379af202f84SMarcel Holtmann 		 * In case any of them is set, the controller has to
2380af202f84SMarcel Holtmann 		 * start up as unconfigured.
2381af202f84SMarcel Holtmann 		 */
2382eb1904f4SMarcel Holtmann 		if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) ||
2383eb1904f4SMarcel Holtmann 		    test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks))
238489bc22d2SMarcel Holtmann 			set_bit(HCI_UNCONFIGURED, &hdev->dev_flags);
2385f41c70c4SMarcel Holtmann 
23860ebca7d6SMarcel Holtmann 		/* For an unconfigured controller it is required to
23870ebca7d6SMarcel Holtmann 		 * read at least the version information provided by
23880ebca7d6SMarcel Holtmann 		 * the Read Local Version Information command.
23890ebca7d6SMarcel Holtmann 		 *
23900ebca7d6SMarcel Holtmann 		 * If the set_bdaddr driver callback is provided, then
23910ebca7d6SMarcel Holtmann 		 * also the original Bluetooth public device address
23920ebca7d6SMarcel Holtmann 		 * will be read using the Read BD Address command.
23930ebca7d6SMarcel Holtmann 		 */
23940ebca7d6SMarcel Holtmann 		if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
23950ebca7d6SMarcel Holtmann 			ret = __hci_unconf_init(hdev);
239689bc22d2SMarcel Holtmann 	}
239789bc22d2SMarcel Holtmann 
23989713c17bSMarcel Holtmann 	if (test_bit(HCI_CONFIG, &hdev->dev_flags)) {
23999713c17bSMarcel Holtmann 		/* If public address change is configured, ensure that
24009713c17bSMarcel Holtmann 		 * the address gets programmed. If the driver does not
24019713c17bSMarcel Holtmann 		 * support changing the public address, fail the power
24029713c17bSMarcel Holtmann 		 * on procedure.
240324c457e2SMarcel Holtmann 		 */
24049713c17bSMarcel Holtmann 		if (bacmp(&hdev->public_addr, BDADDR_ANY) &&
24059713c17bSMarcel Holtmann 		    hdev->set_bdaddr)
240624c457e2SMarcel Holtmann 			ret = hdev->set_bdaddr(hdev, &hdev->public_addr);
240724c457e2SMarcel Holtmann 		else
240824c457e2SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
240924c457e2SMarcel Holtmann 	}
241024c457e2SMarcel Holtmann 
2411f41c70c4SMarcel Holtmann 	if (!ret) {
24124a964404SMarcel Holtmann 		if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
24130736cfa8SMarcel Holtmann 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
24142177bab5SJohan Hedberg 			ret = __hci_init(hdev);
24151da177e4SLinus Torvalds 	}
24161da177e4SLinus Torvalds 
2417f41c70c4SMarcel Holtmann 	clear_bit(HCI_INIT, &hdev->flags);
2418f41c70c4SMarcel Holtmann 
24191da177e4SLinus Torvalds 	if (!ret) {
24201da177e4SLinus Torvalds 		hci_dev_hold(hdev);
2421d6bfd59cSJohan Hedberg 		set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags);
24221da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
24231da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
2424bb4b2a9aSAndrei Emeltchenko 		if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
2425d603b76bSMarcel Holtmann 		    !test_bit(HCI_CONFIG, &hdev->dev_flags) &&
24264a964404SMarcel Holtmann 		    !test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
24270736cfa8SMarcel Holtmann 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
24281514b892SMarcel Holtmann 		    hdev->dev_type == HCI_BREDR) {
242909fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
2430744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
243109fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
243256e5cb86SJohan Hedberg 		}
24331da177e4SLinus Torvalds 	} else {
24341da177e4SLinus Torvalds 		/* Init failed, cleanup */
24353eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
2436c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
2437b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
24381da177e4SLinus Torvalds 
24391da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
24401da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
24411da177e4SLinus Torvalds 
24421da177e4SLinus Torvalds 		if (hdev->flush)
24431da177e4SLinus Torvalds 			hdev->flush(hdev);
24441da177e4SLinus Torvalds 
24451da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
24461da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
24471da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
24481da177e4SLinus Torvalds 		}
24491da177e4SLinus Torvalds 
24501da177e4SLinus Torvalds 		hdev->close(hdev);
2451fee746b0SMarcel Holtmann 		hdev->flags &= BIT(HCI_RAW);
24521da177e4SLinus Torvalds 	}
24531da177e4SLinus Torvalds 
24541da177e4SLinus Torvalds done:
24551da177e4SLinus Torvalds 	hci_req_unlock(hdev);
24561da177e4SLinus Torvalds 	return ret;
24571da177e4SLinus Torvalds }
24581da177e4SLinus Torvalds 
2459cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */
2460cbed0ca1SJohan Hedberg 
2461cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev)
2462cbed0ca1SJohan Hedberg {
2463cbed0ca1SJohan Hedberg 	struct hci_dev *hdev;
2464cbed0ca1SJohan Hedberg 	int err;
2465cbed0ca1SJohan Hedberg 
2466cbed0ca1SJohan Hedberg 	hdev = hci_dev_get(dev);
2467cbed0ca1SJohan Hedberg 	if (!hdev)
2468cbed0ca1SJohan Hedberg 		return -ENODEV;
2469cbed0ca1SJohan Hedberg 
24704a964404SMarcel Holtmann 	/* Devices that are marked as unconfigured can only be powered
2471fee746b0SMarcel Holtmann 	 * up as user channel. Trying to bring them up as normal devices
2472fee746b0SMarcel Holtmann 	 * will result into a failure. Only user channel operation is
2473fee746b0SMarcel Holtmann 	 * possible.
2474fee746b0SMarcel Holtmann 	 *
2475fee746b0SMarcel Holtmann 	 * When this function is called for a user channel, the flag
2476fee746b0SMarcel Holtmann 	 * HCI_USER_CHANNEL will be set first before attempting to
2477fee746b0SMarcel Holtmann 	 * open the device.
2478fee746b0SMarcel Holtmann 	 */
24794a964404SMarcel Holtmann 	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
2480fee746b0SMarcel Holtmann 	    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
2481fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
2482fee746b0SMarcel Holtmann 		goto done;
2483fee746b0SMarcel Holtmann 	}
2484fee746b0SMarcel Holtmann 
2485e1d08f40SJohan Hedberg 	/* We need to ensure that no other power on/off work is pending
2486e1d08f40SJohan Hedberg 	 * before proceeding to call hci_dev_do_open. This is
2487e1d08f40SJohan Hedberg 	 * particularly important if the setup procedure has not yet
2488e1d08f40SJohan Hedberg 	 * completed.
2489e1d08f40SJohan Hedberg 	 */
2490e1d08f40SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
2491e1d08f40SJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
2492e1d08f40SJohan Hedberg 
2493a5c8f270SMarcel Holtmann 	/* After this call it is guaranteed that the setup procedure
2494a5c8f270SMarcel Holtmann 	 * has finished. This means that error conditions like RFKILL
2495a5c8f270SMarcel Holtmann 	 * or no valid public or static random address apply.
2496a5c8f270SMarcel Holtmann 	 */
2497e1d08f40SJohan Hedberg 	flush_workqueue(hdev->req_workqueue);
2498e1d08f40SJohan Hedberg 
249912aa4f0aSMarcel Holtmann 	/* For controllers not using the management interface and that
2500b6ae8457SJohan Hedberg 	 * are brought up using legacy ioctl, set the HCI_BONDABLE bit
250112aa4f0aSMarcel Holtmann 	 * so that pairing works for them. Once the management interface
250212aa4f0aSMarcel Holtmann 	 * is in use this bit will be cleared again and userspace has
250312aa4f0aSMarcel Holtmann 	 * to explicitly enable it.
250412aa4f0aSMarcel Holtmann 	 */
250512aa4f0aSMarcel Holtmann 	if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
250612aa4f0aSMarcel Holtmann 	    !test_bit(HCI_MGMT, &hdev->dev_flags))
2507b6ae8457SJohan Hedberg 		set_bit(HCI_BONDABLE, &hdev->dev_flags);
250812aa4f0aSMarcel Holtmann 
2509cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
2510cbed0ca1SJohan Hedberg 
2511fee746b0SMarcel Holtmann done:
2512cbed0ca1SJohan Hedberg 	hci_dev_put(hdev);
2513cbed0ca1SJohan Hedberg 	return err;
2514cbed0ca1SJohan Hedberg }
2515cbed0ca1SJohan Hedberg 
2516d7347f3cSJohan Hedberg /* This function requires the caller holds hdev->lock */
2517d7347f3cSJohan Hedberg static void hci_pend_le_actions_clear(struct hci_dev *hdev)
2518d7347f3cSJohan Hedberg {
2519d7347f3cSJohan Hedberg 	struct hci_conn_params *p;
2520d7347f3cSJohan Hedberg 
2521f161dd41SJohan Hedberg 	list_for_each_entry(p, &hdev->le_conn_params, list) {
2522f161dd41SJohan Hedberg 		if (p->conn) {
2523f161dd41SJohan Hedberg 			hci_conn_drop(p->conn);
2524f8aaf9b6SJohan Hedberg 			hci_conn_put(p->conn);
2525f161dd41SJohan Hedberg 			p->conn = NULL;
2526f161dd41SJohan Hedberg 		}
2527d7347f3cSJohan Hedberg 		list_del_init(&p->action);
2528f161dd41SJohan Hedberg 	}
2529d7347f3cSJohan Hedberg 
2530d7347f3cSJohan Hedberg 	BT_DBG("All LE pending actions cleared");
2531d7347f3cSJohan Hedberg }
2532d7347f3cSJohan Hedberg 
25331da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
25341da177e4SLinus Torvalds {
25351da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
25361da177e4SLinus Torvalds 
253778c04c0bSVinicius Costa Gomes 	cancel_delayed_work(&hdev->power_off);
253878c04c0bSVinicius Costa Gomes 
25391da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
25401da177e4SLinus Torvalds 	hci_req_lock(hdev);
25411da177e4SLinus Torvalds 
25421da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
254365cc2b49SMarcel Holtmann 		cancel_delayed_work_sync(&hdev->cmd_timer);
25441da177e4SLinus Torvalds 		hci_req_unlock(hdev);
25451da177e4SLinus Torvalds 		return 0;
25461da177e4SLinus Torvalds 	}
25471da177e4SLinus Torvalds 
25483eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
25493eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
2550b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
25511da177e4SLinus Torvalds 
255216ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
2553e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
255416ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
25555e5282bbSJohan Hedberg 		clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
2556310a3d48SMarcel Holtmann 		clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
255716ab91abSJohan Hedberg 	}
255816ab91abSJohan Hedberg 
2559a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
25607d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
25617d78525dSJohan Hedberg 
25627ba8b4beSAndre Guedes 	cancel_delayed_work_sync(&hdev->le_scan_disable);
25634518bb0fSJohan Hedberg 
25644518bb0fSJohan Hedberg 	if (test_bit(HCI_MGMT, &hdev->dev_flags))
2565d6bfd59cSJohan Hedberg 		cancel_delayed_work_sync(&hdev->rpa_expired);
25667ba8b4beSAndre Guedes 
256709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
25681f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
2569d7347f3cSJohan Hedberg 	hci_pend_le_actions_clear(hdev);
2570f161dd41SJohan Hedberg 	hci_conn_hash_flush(hdev);
257109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
25721da177e4SLinus Torvalds 
25731da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
25741da177e4SLinus Torvalds 
25751da177e4SLinus Torvalds 	if (hdev->flush)
25761da177e4SLinus Torvalds 		hdev->flush(hdev);
25771da177e4SLinus Torvalds 
25781da177e4SLinus Torvalds 	/* Reset device */
25791da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
25801da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
25814a964404SMarcel Holtmann 	if (!test_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
25824a964404SMarcel Holtmann 	    !test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) &&
2583a6c511c6SSzymon Janc 	    test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
25841da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
258501178cd4SJohan Hedberg 		__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
25861da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
25871da177e4SLinus Torvalds 	}
25881da177e4SLinus Torvalds 
2589c347b765SGustavo F. Padovan 	/* flush cmd  work */
2590c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
25911da177e4SLinus Torvalds 
25921da177e4SLinus Torvalds 	/* Drop queues */
25931da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
25941da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
25951da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
25961da177e4SLinus Torvalds 
25971da177e4SLinus Torvalds 	/* Drop last sent command */
25981da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
259965cc2b49SMarcel Holtmann 		cancel_delayed_work_sync(&hdev->cmd_timer);
26001da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
26011da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
26021da177e4SLinus Torvalds 	}
26031da177e4SLinus Torvalds 
2604b6ddb638SJohan Hedberg 	kfree_skb(hdev->recv_evt);
2605b6ddb638SJohan Hedberg 	hdev->recv_evt = NULL;
2606b6ddb638SJohan Hedberg 
26071da177e4SLinus Torvalds 	/* After this point our queues are empty
26081da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
26091da177e4SLinus Torvalds 	hdev->close(hdev);
26101da177e4SLinus Torvalds 
261135b973c9SJohan Hedberg 	/* Clear flags */
2612fee746b0SMarcel Holtmann 	hdev->flags &= BIT(HCI_RAW);
261335b973c9SJohan Hedberg 	hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
261435b973c9SJohan Hedberg 
261593c311a0SMarcel Holtmann 	if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
261693c311a0SMarcel Holtmann 		if (hdev->dev_type == HCI_BREDR) {
261709fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
2618744cf19eSJohan Hedberg 			mgmt_powered(hdev, 0);
261909fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
26208ee56540SMarcel Holtmann 		}
262193c311a0SMarcel Holtmann 	}
26225add6af8SJohan Hedberg 
2623ced5c338SAndrei Emeltchenko 	/* Controller radio is available but is currently powered down */
2624536619e8SMarcel Holtmann 	hdev->amp_status = AMP_STATUS_POWERED_DOWN;
2625ced5c338SAndrei Emeltchenko 
2626e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
262709b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
26287a4cd51dSMarcel Holtmann 	bacpy(&hdev->random_addr, BDADDR_ANY);
2629e59fda8dSJohan Hedberg 
26301da177e4SLinus Torvalds 	hci_req_unlock(hdev);
26311da177e4SLinus Torvalds 
26321da177e4SLinus Torvalds 	hci_dev_put(hdev);
26331da177e4SLinus Torvalds 	return 0;
26341da177e4SLinus Torvalds }
26351da177e4SLinus Torvalds 
26361da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
26371da177e4SLinus Torvalds {
26381da177e4SLinus Torvalds 	struct hci_dev *hdev;
26391da177e4SLinus Torvalds 	int err;
26401da177e4SLinus Torvalds 
264170f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
264270f23020SAndrei Emeltchenko 	if (!hdev)
26431da177e4SLinus Torvalds 		return -ENODEV;
26448ee56540SMarcel Holtmann 
26450736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
26460736cfa8SMarcel Holtmann 		err = -EBUSY;
26470736cfa8SMarcel Holtmann 		goto done;
26480736cfa8SMarcel Holtmann 	}
26490736cfa8SMarcel Holtmann 
26508ee56540SMarcel Holtmann 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
26518ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
26528ee56540SMarcel Holtmann 
26531da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
26548ee56540SMarcel Holtmann 
26550736cfa8SMarcel Holtmann done:
26561da177e4SLinus Torvalds 	hci_dev_put(hdev);
26571da177e4SLinus Torvalds 	return err;
26581da177e4SLinus Torvalds }
26591da177e4SLinus Torvalds 
26601da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
26611da177e4SLinus Torvalds {
26621da177e4SLinus Torvalds 	struct hci_dev *hdev;
26631da177e4SLinus Torvalds 	int ret = 0;
26641da177e4SLinus Torvalds 
266570f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
266670f23020SAndrei Emeltchenko 	if (!hdev)
26671da177e4SLinus Torvalds 		return -ENODEV;
26681da177e4SLinus Torvalds 
26691da177e4SLinus Torvalds 	hci_req_lock(hdev);
26701da177e4SLinus Torvalds 
2671808a049eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
2672808a049eSMarcel Holtmann 		ret = -ENETDOWN;
26731da177e4SLinus Torvalds 		goto done;
2674808a049eSMarcel Holtmann 	}
26751da177e4SLinus Torvalds 
26760736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
26770736cfa8SMarcel Holtmann 		ret = -EBUSY;
26780736cfa8SMarcel Holtmann 		goto done;
26790736cfa8SMarcel Holtmann 	}
26800736cfa8SMarcel Holtmann 
26814a964404SMarcel Holtmann 	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
2682fee746b0SMarcel Holtmann 		ret = -EOPNOTSUPP;
2683fee746b0SMarcel Holtmann 		goto done;
2684fee746b0SMarcel Holtmann 	}
2685fee746b0SMarcel Holtmann 
26861da177e4SLinus Torvalds 	/* Drop queues */
26871da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
26881da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
26891da177e4SLinus Torvalds 
269009fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
26911f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
26921da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
269309fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
26941da177e4SLinus Torvalds 
26951da177e4SLinus Torvalds 	if (hdev->flush)
26961da177e4SLinus Torvalds 		hdev->flush(hdev);
26971da177e4SLinus Torvalds 
26981da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
26996ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
27001da177e4SLinus Torvalds 
270101178cd4SJohan Hedberg 	ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
27021da177e4SLinus Torvalds 
27031da177e4SLinus Torvalds done:
27041da177e4SLinus Torvalds 	hci_req_unlock(hdev);
27051da177e4SLinus Torvalds 	hci_dev_put(hdev);
27061da177e4SLinus Torvalds 	return ret;
27071da177e4SLinus Torvalds }
27081da177e4SLinus Torvalds 
27091da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
27101da177e4SLinus Torvalds {
27111da177e4SLinus Torvalds 	struct hci_dev *hdev;
27121da177e4SLinus Torvalds 	int ret = 0;
27131da177e4SLinus Torvalds 
271470f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
271570f23020SAndrei Emeltchenko 	if (!hdev)
27161da177e4SLinus Torvalds 		return -ENODEV;
27171da177e4SLinus Torvalds 
27180736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
27190736cfa8SMarcel Holtmann 		ret = -EBUSY;
27200736cfa8SMarcel Holtmann 		goto done;
27210736cfa8SMarcel Holtmann 	}
27220736cfa8SMarcel Holtmann 
27234a964404SMarcel Holtmann 	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
2724fee746b0SMarcel Holtmann 		ret = -EOPNOTSUPP;
2725fee746b0SMarcel Holtmann 		goto done;
2726fee746b0SMarcel Holtmann 	}
2727fee746b0SMarcel Holtmann 
27281da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
27291da177e4SLinus Torvalds 
27300736cfa8SMarcel Holtmann done:
27311da177e4SLinus Torvalds 	hci_dev_put(hdev);
27321da177e4SLinus Torvalds 	return ret;
27331da177e4SLinus Torvalds }
27341da177e4SLinus Torvalds 
2735123abc08SJohan Hedberg static void hci_update_scan_state(struct hci_dev *hdev, u8 scan)
2736123abc08SJohan Hedberg {
2737bc6d2d04SJohan Hedberg 	bool conn_changed, discov_changed;
2738123abc08SJohan Hedberg 
2739123abc08SJohan Hedberg 	BT_DBG("%s scan 0x%02x", hdev->name, scan);
2740123abc08SJohan Hedberg 
2741123abc08SJohan Hedberg 	if ((scan & SCAN_PAGE))
2742123abc08SJohan Hedberg 		conn_changed = !test_and_set_bit(HCI_CONNECTABLE,
2743123abc08SJohan Hedberg 						 &hdev->dev_flags);
2744123abc08SJohan Hedberg 	else
2745123abc08SJohan Hedberg 		conn_changed = test_and_clear_bit(HCI_CONNECTABLE,
2746123abc08SJohan Hedberg 						  &hdev->dev_flags);
2747123abc08SJohan Hedberg 
2748bc6d2d04SJohan Hedberg 	if ((scan & SCAN_INQUIRY)) {
2749bc6d2d04SJohan Hedberg 		discov_changed = !test_and_set_bit(HCI_DISCOVERABLE,
2750bc6d2d04SJohan Hedberg 						   &hdev->dev_flags);
2751bc6d2d04SJohan Hedberg 	} else {
2752bc6d2d04SJohan Hedberg 		clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
2753bc6d2d04SJohan Hedberg 		discov_changed = test_and_clear_bit(HCI_DISCOVERABLE,
2754bc6d2d04SJohan Hedberg 						    &hdev->dev_flags);
2755bc6d2d04SJohan Hedberg 	}
2756bc6d2d04SJohan Hedberg 
2757123abc08SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2758123abc08SJohan Hedberg 		return;
2759123abc08SJohan Hedberg 
2760bc6d2d04SJohan Hedberg 	if (conn_changed || discov_changed) {
2761bc6d2d04SJohan Hedberg 		/* In case this was disabled through mgmt */
2762bc6d2d04SJohan Hedberg 		set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
2763bc6d2d04SJohan Hedberg 
2764bc6d2d04SJohan Hedberg 		if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags))
2765bc6d2d04SJohan Hedberg 			mgmt_update_adv_data(hdev);
2766bc6d2d04SJohan Hedberg 
2767123abc08SJohan Hedberg 		mgmt_new_settings(hdev);
2768123abc08SJohan Hedberg 	}
2769bc6d2d04SJohan Hedberg }
2770123abc08SJohan Hedberg 
27711da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
27721da177e4SLinus Torvalds {
27731da177e4SLinus Torvalds 	struct hci_dev *hdev;
27741da177e4SLinus Torvalds 	struct hci_dev_req dr;
27751da177e4SLinus Torvalds 	int err = 0;
27761da177e4SLinus Torvalds 
27771da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
27781da177e4SLinus Torvalds 		return -EFAULT;
27791da177e4SLinus Torvalds 
278070f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
278170f23020SAndrei Emeltchenko 	if (!hdev)
27821da177e4SLinus Torvalds 		return -ENODEV;
27831da177e4SLinus Torvalds 
27840736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
27850736cfa8SMarcel Holtmann 		err = -EBUSY;
27860736cfa8SMarcel Holtmann 		goto done;
27870736cfa8SMarcel Holtmann 	}
27880736cfa8SMarcel Holtmann 
27894a964404SMarcel Holtmann 	if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
2790fee746b0SMarcel Holtmann 		err = -EOPNOTSUPP;
2791fee746b0SMarcel Holtmann 		goto done;
2792fee746b0SMarcel Holtmann 	}
2793fee746b0SMarcel Holtmann 
27945b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
27955b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
27965b69bef5SMarcel Holtmann 		goto done;
27975b69bef5SMarcel Holtmann 	}
27985b69bef5SMarcel Holtmann 
279956f87901SJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
280056f87901SJohan Hedberg 		err = -EOPNOTSUPP;
280156f87901SJohan Hedberg 		goto done;
280256f87901SJohan Hedberg 	}
280356f87901SJohan Hedberg 
28041da177e4SLinus Torvalds 	switch (cmd) {
28051da177e4SLinus Torvalds 	case HCISETAUTH:
280601178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
28075f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
28081da177e4SLinus Torvalds 		break;
28091da177e4SLinus Torvalds 
28101da177e4SLinus Torvalds 	case HCISETENCRYPT:
28111da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
28121da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
28131da177e4SLinus Torvalds 			break;
28141da177e4SLinus Torvalds 		}
28151da177e4SLinus Torvalds 
28161da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
28171da177e4SLinus Torvalds 			/* Auth must be enabled first */
281801178cd4SJohan Hedberg 			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
28195f246e89SAndrei Emeltchenko 					   HCI_INIT_TIMEOUT);
28201da177e4SLinus Torvalds 			if (err)
28211da177e4SLinus Torvalds 				break;
28221da177e4SLinus Torvalds 		}
28231da177e4SLinus Torvalds 
282401178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
28255f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
28261da177e4SLinus Torvalds 		break;
28271da177e4SLinus Torvalds 
28281da177e4SLinus Torvalds 	case HCISETSCAN:
282901178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
28305f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
283191a668b0SJohan Hedberg 
2832bc6d2d04SJohan Hedberg 		/* Ensure that the connectable and discoverable states
2833bc6d2d04SJohan Hedberg 		 * get correctly modified as this was a non-mgmt change.
283491a668b0SJohan Hedberg 		 */
2835123abc08SJohan Hedberg 		if (!err)
2836123abc08SJohan Hedberg 			hci_update_scan_state(hdev, dr.dev_opt);
28371da177e4SLinus Torvalds 		break;
28381da177e4SLinus Torvalds 
28391da177e4SLinus Torvalds 	case HCISETLINKPOL:
284001178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
28415f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
28421da177e4SLinus Torvalds 		break;
28431da177e4SLinus Torvalds 
28441da177e4SLinus Torvalds 	case HCISETLINKMODE:
2845e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
2846e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
2847e4e8e37cSMarcel Holtmann 		break;
2848e4e8e37cSMarcel Holtmann 
2849e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
2850e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
28511da177e4SLinus Torvalds 		break;
28521da177e4SLinus Torvalds 
28531da177e4SLinus Torvalds 	case HCISETACLMTU:
28541da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
28551da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
28561da177e4SLinus Torvalds 		break;
28571da177e4SLinus Torvalds 
28581da177e4SLinus Torvalds 	case HCISETSCOMTU:
28591da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
28601da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
28611da177e4SLinus Torvalds 		break;
28621da177e4SLinus Torvalds 
28631da177e4SLinus Torvalds 	default:
28641da177e4SLinus Torvalds 		err = -EINVAL;
28651da177e4SLinus Torvalds 		break;
28661da177e4SLinus Torvalds 	}
2867e4e8e37cSMarcel Holtmann 
28680736cfa8SMarcel Holtmann done:
28691da177e4SLinus Torvalds 	hci_dev_put(hdev);
28701da177e4SLinus Torvalds 	return err;
28711da177e4SLinus Torvalds }
28721da177e4SLinus Torvalds 
28731da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
28741da177e4SLinus Torvalds {
28758035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
28761da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
28771da177e4SLinus Torvalds 	struct hci_dev_req *dr;
28781da177e4SLinus Torvalds 	int n = 0, size, err;
28791da177e4SLinus Torvalds 	__u16 dev_num;
28801da177e4SLinus Torvalds 
28811da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
28821da177e4SLinus Torvalds 		return -EFAULT;
28831da177e4SLinus Torvalds 
28841da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
28851da177e4SLinus Torvalds 		return -EINVAL;
28861da177e4SLinus Torvalds 
28871da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
28881da177e4SLinus Torvalds 
288970f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
289070f23020SAndrei Emeltchenko 	if (!dl)
28911da177e4SLinus Torvalds 		return -ENOMEM;
28921da177e4SLinus Torvalds 
28931da177e4SLinus Torvalds 	dr = dl->dev_req;
28941da177e4SLinus Torvalds 
2895f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
28968035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
28972e84d8dbSMarcel Holtmann 		unsigned long flags = hdev->flags;
2898c542a06cSJohan Hedberg 
28992e84d8dbSMarcel Holtmann 		/* When the auto-off is configured it means the transport
29002e84d8dbSMarcel Holtmann 		 * is running, but in that case still indicate that the
29012e84d8dbSMarcel Holtmann 		 * device is actually down.
29022e84d8dbSMarcel Holtmann 		 */
29032e84d8dbSMarcel Holtmann 		if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
29042e84d8dbSMarcel Holtmann 			flags &= ~BIT(HCI_UP);
2905c542a06cSJohan Hedberg 
29061da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
29072e84d8dbSMarcel Holtmann 		(dr + n)->dev_opt = flags;
2908c542a06cSJohan Hedberg 
29091da177e4SLinus Torvalds 		if (++n >= dev_num)
29101da177e4SLinus Torvalds 			break;
29111da177e4SLinus Torvalds 	}
2912f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
29131da177e4SLinus Torvalds 
29141da177e4SLinus Torvalds 	dl->dev_num = n;
29151da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
29161da177e4SLinus Torvalds 
29171da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
29181da177e4SLinus Torvalds 	kfree(dl);
29191da177e4SLinus Torvalds 
29201da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
29211da177e4SLinus Torvalds }
29221da177e4SLinus Torvalds 
29231da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
29241da177e4SLinus Torvalds {
29251da177e4SLinus Torvalds 	struct hci_dev *hdev;
29261da177e4SLinus Torvalds 	struct hci_dev_info di;
29272e84d8dbSMarcel Holtmann 	unsigned long flags;
29281da177e4SLinus Torvalds 	int err = 0;
29291da177e4SLinus Torvalds 
29301da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
29311da177e4SLinus Torvalds 		return -EFAULT;
29321da177e4SLinus Torvalds 
293370f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
293470f23020SAndrei Emeltchenko 	if (!hdev)
29351da177e4SLinus Torvalds 		return -ENODEV;
29361da177e4SLinus Torvalds 
29372e84d8dbSMarcel Holtmann 	/* When the auto-off is configured it means the transport
29382e84d8dbSMarcel Holtmann 	 * is running, but in that case still indicate that the
29392e84d8dbSMarcel Holtmann 	 * device is actually down.
29402e84d8dbSMarcel Holtmann 	 */
29412e84d8dbSMarcel Holtmann 	if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
29422e84d8dbSMarcel Holtmann 		flags = hdev->flags & ~BIT(HCI_UP);
29432e84d8dbSMarcel Holtmann 	else
29442e84d8dbSMarcel Holtmann 		flags = hdev->flags;
2945c542a06cSJohan Hedberg 
29461da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
29471da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
294860f2a3edSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4);
29492e84d8dbSMarcel Holtmann 	di.flags    = flags;
29501da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
2951572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
29521da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
29531da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
29541da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
29551da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
2956572c7f84SJohan Hedberg 	} else {
2957572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
2958572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
2959572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
2960572c7f84SJohan Hedberg 		di.sco_pkts = 0;
2961572c7f84SJohan Hedberg 	}
29621da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
29631da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
29641da177e4SLinus Torvalds 
29651da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
29661da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
29671da177e4SLinus Torvalds 
29681da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
29691da177e4SLinus Torvalds 		err = -EFAULT;
29701da177e4SLinus Torvalds 
29711da177e4SLinus Torvalds 	hci_dev_put(hdev);
29721da177e4SLinus Torvalds 
29731da177e4SLinus Torvalds 	return err;
29741da177e4SLinus Torvalds }
29751da177e4SLinus Torvalds 
29761da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
29771da177e4SLinus Torvalds 
2978611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
2979611b30f7SMarcel Holtmann {
2980611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
2981611b30f7SMarcel Holtmann 
2982611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
2983611b30f7SMarcel Holtmann 
29840736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
29850736cfa8SMarcel Holtmann 		return -EBUSY;
29860736cfa8SMarcel Holtmann 
29875e130367SJohan Hedberg 	if (blocked) {
29885e130367SJohan Hedberg 		set_bit(HCI_RFKILLED, &hdev->dev_flags);
2989d603b76bSMarcel Holtmann 		if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
2990d603b76bSMarcel Holtmann 		    !test_bit(HCI_CONFIG, &hdev->dev_flags))
2991611b30f7SMarcel Holtmann 			hci_dev_do_close(hdev);
29925e130367SJohan Hedberg 	} else {
29935e130367SJohan Hedberg 		clear_bit(HCI_RFKILLED, &hdev->dev_flags);
29945e130367SJohan Hedberg 	}
2995611b30f7SMarcel Holtmann 
2996611b30f7SMarcel Holtmann 	return 0;
2997611b30f7SMarcel Holtmann }
2998611b30f7SMarcel Holtmann 
2999611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
3000611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
3001611b30f7SMarcel Holtmann };
3002611b30f7SMarcel Holtmann 
3003ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
3004ab81cbf9SJohan Hedberg {
3005ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
300696570ffcSJohan Hedberg 	int err;
3007ab81cbf9SJohan Hedberg 
3008ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
3009ab81cbf9SJohan Hedberg 
3010cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
301196570ffcSJohan Hedberg 	if (err < 0) {
301296570ffcSJohan Hedberg 		mgmt_set_powered_failed(hdev, err);
3013ab81cbf9SJohan Hedberg 		return;
301496570ffcSJohan Hedberg 	}
3015ab81cbf9SJohan Hedberg 
3016a5c8f270SMarcel Holtmann 	/* During the HCI setup phase, a few error conditions are
3017a5c8f270SMarcel Holtmann 	 * ignored and they need to be checked now. If they are still
3018a5c8f270SMarcel Holtmann 	 * valid, it is important to turn the device back off.
3019a5c8f270SMarcel Holtmann 	 */
3020a5c8f270SMarcel Holtmann 	if (test_bit(HCI_RFKILLED, &hdev->dev_flags) ||
30214a964404SMarcel Holtmann 	    test_bit(HCI_UNCONFIGURED, &hdev->dev_flags) ||
3022a5c8f270SMarcel Holtmann 	    (hdev->dev_type == HCI_BREDR &&
3023a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
3024a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->static_addr, BDADDR_ANY))) {
3025bf543036SJohan Hedberg 		clear_bit(HCI_AUTO_OFF, &hdev->dev_flags);
3026bf543036SJohan Hedberg 		hci_dev_do_close(hdev);
3027bf543036SJohan Hedberg 	} else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
302819202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
302919202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
3030bf543036SJohan Hedberg 	}
3031ab81cbf9SJohan Hedberg 
3032fee746b0SMarcel Holtmann 	if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) {
30334a964404SMarcel Holtmann 		/* For unconfigured devices, set the HCI_RAW flag
30344a964404SMarcel Holtmann 		 * so that userspace can easily identify them.
30354a964404SMarcel Holtmann 		 */
30364a964404SMarcel Holtmann 		if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
30374a964404SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
30380602a8adSMarcel Holtmann 
30390602a8adSMarcel Holtmann 		/* For fully configured devices, this will send
30400602a8adSMarcel Holtmann 		 * the Index Added event. For unconfigured devices,
30410602a8adSMarcel Holtmann 		 * it will send Unconfigued Index Added event.
30420602a8adSMarcel Holtmann 		 *
30430602a8adSMarcel Holtmann 		 * Devices with HCI_QUIRK_RAW_DEVICE are ignored
30440602a8adSMarcel Holtmann 		 * and no event will be send.
30450602a8adSMarcel Holtmann 		 */
3046744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
3047d603b76bSMarcel Holtmann 	} else if (test_and_clear_bit(HCI_CONFIG, &hdev->dev_flags)) {
30485ea234d3SMarcel Holtmann 		/* When the controller is now configured, then it
30495ea234d3SMarcel Holtmann 		 * is important to clear the HCI_RAW flag.
30505ea234d3SMarcel Holtmann 		 */
30515ea234d3SMarcel Holtmann 		if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
30525ea234d3SMarcel Holtmann 			clear_bit(HCI_RAW, &hdev->flags);
30535ea234d3SMarcel Holtmann 
3054d603b76bSMarcel Holtmann 		/* Powering on the controller with HCI_CONFIG set only
3055d603b76bSMarcel Holtmann 		 * happens with the transition from unconfigured to
3056d603b76bSMarcel Holtmann 		 * configured. This will send the Index Added event.
3057d603b76bSMarcel Holtmann 		 */
3058d603b76bSMarcel Holtmann 		mgmt_index_added(hdev);
3059ab81cbf9SJohan Hedberg 	}
3060ab81cbf9SJohan Hedberg }
3061ab81cbf9SJohan Hedberg 
3062ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
3063ab81cbf9SJohan Hedberg {
30643243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
30653243553fSJohan Hedberg 					    power_off.work);
3066ab81cbf9SJohan Hedberg 
3067ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
3068ab81cbf9SJohan Hedberg 
30698ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
3070ab81cbf9SJohan Hedberg }
3071ab81cbf9SJohan Hedberg 
307216ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
307316ab91abSJohan Hedberg {
307416ab91abSJohan Hedberg 	struct hci_dev *hdev;
307516ab91abSJohan Hedberg 
307616ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
307716ab91abSJohan Hedberg 
307816ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
307916ab91abSJohan Hedberg 
3080d1967ff8SMarcel Holtmann 	mgmt_discoverable_timeout(hdev);
308116ab91abSJohan Hedberg }
308216ab91abSJohan Hedberg 
308335f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev)
30842aeb9a1aSJohan Hedberg {
30854821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
30862aeb9a1aSJohan Hedberg 
30874821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
30884821002cSJohan Hedberg 		list_del(&uuid->list);
30892aeb9a1aSJohan Hedberg 		kfree(uuid);
30902aeb9a1aSJohan Hedberg 	}
30912aeb9a1aSJohan Hedberg }
30922aeb9a1aSJohan Hedberg 
309335f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev)
309455ed8ca1SJohan Hedberg {
309555ed8ca1SJohan Hedberg 	struct list_head *p, *n;
309655ed8ca1SJohan Hedberg 
309755ed8ca1SJohan Hedberg 	list_for_each_safe(p, n, &hdev->link_keys) {
309855ed8ca1SJohan Hedberg 		struct link_key *key;
309955ed8ca1SJohan Hedberg 
310055ed8ca1SJohan Hedberg 		key = list_entry(p, struct link_key, list);
310155ed8ca1SJohan Hedberg 
310255ed8ca1SJohan Hedberg 		list_del(p);
310355ed8ca1SJohan Hedberg 		kfree(key);
310455ed8ca1SJohan Hedberg 	}
310555ed8ca1SJohan Hedberg }
310655ed8ca1SJohan Hedberg 
310735f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev)
3108b899efafSVinicius Costa Gomes {
3109b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
3110b899efafSVinicius Costa Gomes 
3111b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
3112b899efafSVinicius Costa Gomes 		list_del(&k->list);
3113b899efafSVinicius Costa Gomes 		kfree(k);
3114b899efafSVinicius Costa Gomes 	}
3115b899efafSVinicius Costa Gomes }
3116b899efafSVinicius Costa Gomes 
3117970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev)
3118970c4e46SJohan Hedberg {
3119970c4e46SJohan Hedberg 	struct smp_irk *k, *tmp;
3120970c4e46SJohan Hedberg 
3121970c4e46SJohan Hedberg 	list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) {
3122970c4e46SJohan Hedberg 		list_del(&k->list);
3123970c4e46SJohan Hedberg 		kfree(k);
3124970c4e46SJohan Hedberg 	}
3125970c4e46SJohan Hedberg }
3126970c4e46SJohan Hedberg 
312755ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
312855ed8ca1SJohan Hedberg {
312955ed8ca1SJohan Hedberg 	struct link_key *k;
313055ed8ca1SJohan Hedberg 
31318035ded4SLuiz Augusto von Dentz 	list_for_each_entry(k, &hdev->link_keys, list)
313255ed8ca1SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0)
313355ed8ca1SJohan Hedberg 			return k;
313455ed8ca1SJohan Hedberg 
313555ed8ca1SJohan Hedberg 	return NULL;
313655ed8ca1SJohan Hedberg }
313755ed8ca1SJohan Hedberg 
3138745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
3139d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
3140d25e28abSJohan Hedberg {
3141d25e28abSJohan Hedberg 	/* Legacy key */
3142d25e28abSJohan Hedberg 	if (key_type < 0x03)
3143745c0ce3SVishal Agarwal 		return true;
3144d25e28abSJohan Hedberg 
3145d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
3146d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
3147745c0ce3SVishal Agarwal 		return false;
3148d25e28abSJohan Hedberg 
3149d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
3150d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
3151745c0ce3SVishal Agarwal 		return false;
3152d25e28abSJohan Hedberg 
3153d25e28abSJohan Hedberg 	/* Security mode 3 case */
3154d25e28abSJohan Hedberg 	if (!conn)
3155745c0ce3SVishal Agarwal 		return true;
3156d25e28abSJohan Hedberg 
3157d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
3158d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
3159745c0ce3SVishal Agarwal 		return true;
3160d25e28abSJohan Hedberg 
3161d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
3162d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
3163745c0ce3SVishal Agarwal 		return true;
3164d25e28abSJohan Hedberg 
3165d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
3166d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
3167745c0ce3SVishal Agarwal 		return true;
3168d25e28abSJohan Hedberg 
3169d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
3170d25e28abSJohan Hedberg 	 * persistently */
3171745c0ce3SVishal Agarwal 	return false;
3172d25e28abSJohan Hedberg }
3173d25e28abSJohan Hedberg 
3174e804d25dSJohan Hedberg static u8 ltk_role(u8 type)
317598a0b845SJohan Hedberg {
3176e804d25dSJohan Hedberg 	if (type == SMP_LTK)
3177e804d25dSJohan Hedberg 		return HCI_ROLE_MASTER;
317898a0b845SJohan Hedberg 
3179e804d25dSJohan Hedberg 	return HCI_ROLE_SLAVE;
318098a0b845SJohan Hedberg }
318198a0b845SJohan Hedberg 
3182fe39c7b2SMarcel Holtmann struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, __le64 rand,
3183e804d25dSJohan Hedberg 			     u8 role)
318475d262c2SVinicius Costa Gomes {
3185c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
318675d262c2SVinicius Costa Gomes 
3187c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list) {
3188fe39c7b2SMarcel Holtmann 		if (k->ediv != ediv || k->rand != rand)
318975d262c2SVinicius Costa Gomes 			continue;
319075d262c2SVinicius Costa Gomes 
3191e804d25dSJohan Hedberg 		if (ltk_role(k->type) != role)
319298a0b845SJohan Hedberg 			continue;
319398a0b845SJohan Hedberg 
319475d262c2SVinicius Costa Gomes 		return k;
319575d262c2SVinicius Costa Gomes 	}
319675d262c2SVinicius Costa Gomes 
319775d262c2SVinicius Costa Gomes 	return NULL;
319875d262c2SVinicius Costa Gomes }
319975d262c2SVinicius Costa Gomes 
3200c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
3201e804d25dSJohan Hedberg 				     u8 addr_type, u8 role)
320275d262c2SVinicius Costa Gomes {
3203c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
320475d262c2SVinicius Costa Gomes 
3205c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list)
3206c9839a11SVinicius Costa Gomes 		if (addr_type == k->bdaddr_type &&
320798a0b845SJohan Hedberg 		    bacmp(bdaddr, &k->bdaddr) == 0 &&
3208e804d25dSJohan Hedberg 		    ltk_role(k->type) == role)
320975d262c2SVinicius Costa Gomes 			return k;
321075d262c2SVinicius Costa Gomes 
321175d262c2SVinicius Costa Gomes 	return NULL;
321275d262c2SVinicius Costa Gomes }
321375d262c2SVinicius Costa Gomes 
3214970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa)
3215970c4e46SJohan Hedberg {
3216970c4e46SJohan Hedberg 	struct smp_irk *irk;
3217970c4e46SJohan Hedberg 
3218970c4e46SJohan Hedberg 	list_for_each_entry(irk, &hdev->identity_resolving_keys, list) {
3219970c4e46SJohan Hedberg 		if (!bacmp(&irk->rpa, rpa))
3220970c4e46SJohan Hedberg 			return irk;
3221970c4e46SJohan Hedberg 	}
3222970c4e46SJohan Hedberg 
3223970c4e46SJohan Hedberg 	list_for_each_entry(irk, &hdev->identity_resolving_keys, list) {
3224defce9e8SJohan Hedberg 		if (smp_irk_matches(hdev, irk->val, rpa)) {
3225970c4e46SJohan Hedberg 			bacpy(&irk->rpa, rpa);
3226970c4e46SJohan Hedberg 			return irk;
3227970c4e46SJohan Hedberg 		}
3228970c4e46SJohan Hedberg 	}
3229970c4e46SJohan Hedberg 
3230970c4e46SJohan Hedberg 	return NULL;
3231970c4e46SJohan Hedberg }
3232970c4e46SJohan Hedberg 
3233970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
3234970c4e46SJohan Hedberg 				     u8 addr_type)
3235970c4e46SJohan Hedberg {
3236970c4e46SJohan Hedberg 	struct smp_irk *irk;
3237970c4e46SJohan Hedberg 
32386cfc9988SJohan Hedberg 	/* Identity Address must be public or static random */
32396cfc9988SJohan Hedberg 	if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0)
32406cfc9988SJohan Hedberg 		return NULL;
32416cfc9988SJohan Hedberg 
3242970c4e46SJohan Hedberg 	list_for_each_entry(irk, &hdev->identity_resolving_keys, list) {
3243970c4e46SJohan Hedberg 		if (addr_type == irk->addr_type &&
3244970c4e46SJohan Hedberg 		    bacmp(bdaddr, &irk->bdaddr) == 0)
3245970c4e46SJohan Hedberg 			return irk;
3246970c4e46SJohan Hedberg 	}
3247970c4e46SJohan Hedberg 
3248970c4e46SJohan Hedberg 	return NULL;
3249970c4e46SJohan Hedberg }
3250970c4e46SJohan Hedberg 
3251567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn,
32527652ff6aSJohan Hedberg 				  bdaddr_t *bdaddr, u8 *val, u8 type,
32537652ff6aSJohan Hedberg 				  u8 pin_len, bool *persistent)
325455ed8ca1SJohan Hedberg {
325555ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
3256745c0ce3SVishal Agarwal 	u8 old_key_type;
325755ed8ca1SJohan Hedberg 
325855ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
325955ed8ca1SJohan Hedberg 	if (old_key) {
326055ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
326155ed8ca1SJohan Hedberg 		key = old_key;
326255ed8ca1SJohan Hedberg 	} else {
326312adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
32640a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
326555ed8ca1SJohan Hedberg 		if (!key)
3266567fa2aaSJohan Hedberg 			return NULL;
326755ed8ca1SJohan Hedberg 		list_add(&key->list, &hdev->link_keys);
326855ed8ca1SJohan Hedberg 	}
326955ed8ca1SJohan Hedberg 
32706ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
327155ed8ca1SJohan Hedberg 
3272d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
3273d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
3274d25e28abSJohan Hedberg 	 * previous key */
3275d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
3276a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
3277d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
3278655fe6ecSJohan Hedberg 		if (conn)
3279655fe6ecSJohan Hedberg 			conn->key_type = type;
3280655fe6ecSJohan Hedberg 	}
3281d25e28abSJohan Hedberg 
328255ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
32839b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
328455ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
328555ed8ca1SJohan Hedberg 
3286b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
328755ed8ca1SJohan Hedberg 		key->type = old_key_type;
32884748fed2SJohan Hedberg 	else
32894748fed2SJohan Hedberg 		key->type = type;
32904748fed2SJohan Hedberg 
32917652ff6aSJohan Hedberg 	if (persistent)
32927652ff6aSJohan Hedberg 		*persistent = hci_persistent_key(hdev, conn, type,
32937652ff6aSJohan Hedberg 						 old_key_type);
32944df378a1SJohan Hedberg 
3295567fa2aaSJohan Hedberg 	return key;
329655ed8ca1SJohan Hedberg }
329755ed8ca1SJohan Hedberg 
3298ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
329935d70271SJohan Hedberg 			    u8 addr_type, u8 type, u8 authenticated,
3300fe39c7b2SMarcel Holtmann 			    u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand)
330175d262c2SVinicius Costa Gomes {
3302c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
3303e804d25dSJohan Hedberg 	u8 role = ltk_role(type);
330475d262c2SVinicius Costa Gomes 
3305e804d25dSJohan Hedberg 	old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type, role);
3306c9839a11SVinicius Costa Gomes 	if (old_key)
330775d262c2SVinicius Costa Gomes 		key = old_key;
3308c9839a11SVinicius Costa Gomes 	else {
33090a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
331075d262c2SVinicius Costa Gomes 		if (!key)
3311ca9142b8SJohan Hedberg 			return NULL;
3312c9839a11SVinicius Costa Gomes 		list_add(&key->list, &hdev->long_term_keys);
331375d262c2SVinicius Costa Gomes 	}
331475d262c2SVinicius Costa Gomes 
331575d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
3316c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
3317c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
3318c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
3319c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
3320fe39c7b2SMarcel Holtmann 	key->rand = rand;
3321c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
3322c9839a11SVinicius Costa Gomes 	key->type = type;
332375d262c2SVinicius Costa Gomes 
3324ca9142b8SJohan Hedberg 	return key;
332575d262c2SVinicius Costa Gomes }
332675d262c2SVinicius Costa Gomes 
3327ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr,
3328ca9142b8SJohan Hedberg 			    u8 addr_type, u8 val[16], bdaddr_t *rpa)
3329970c4e46SJohan Hedberg {
3330970c4e46SJohan Hedberg 	struct smp_irk *irk;
3331970c4e46SJohan Hedberg 
3332970c4e46SJohan Hedberg 	irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type);
3333970c4e46SJohan Hedberg 	if (!irk) {
3334970c4e46SJohan Hedberg 		irk = kzalloc(sizeof(*irk), GFP_KERNEL);
3335970c4e46SJohan Hedberg 		if (!irk)
3336ca9142b8SJohan Hedberg 			return NULL;
3337970c4e46SJohan Hedberg 
3338970c4e46SJohan Hedberg 		bacpy(&irk->bdaddr, bdaddr);
3339970c4e46SJohan Hedberg 		irk->addr_type = addr_type;
3340970c4e46SJohan Hedberg 
3341970c4e46SJohan Hedberg 		list_add(&irk->list, &hdev->identity_resolving_keys);
3342970c4e46SJohan Hedberg 	}
3343970c4e46SJohan Hedberg 
3344970c4e46SJohan Hedberg 	memcpy(irk->val, val, 16);
3345970c4e46SJohan Hedberg 	bacpy(&irk->rpa, rpa);
3346970c4e46SJohan Hedberg 
3347ca9142b8SJohan Hedberg 	return irk;
3348970c4e46SJohan Hedberg }
3349970c4e46SJohan Hedberg 
335055ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
335155ed8ca1SJohan Hedberg {
335255ed8ca1SJohan Hedberg 	struct link_key *key;
335355ed8ca1SJohan Hedberg 
335455ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
335555ed8ca1SJohan Hedberg 	if (!key)
335655ed8ca1SJohan Hedberg 		return -ENOENT;
335755ed8ca1SJohan Hedberg 
33586ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
335955ed8ca1SJohan Hedberg 
336055ed8ca1SJohan Hedberg 	list_del(&key->list);
336155ed8ca1SJohan Hedberg 	kfree(key);
336255ed8ca1SJohan Hedberg 
336355ed8ca1SJohan Hedberg 	return 0;
336455ed8ca1SJohan Hedberg }
336555ed8ca1SJohan Hedberg 
3366e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type)
3367b899efafSVinicius Costa Gomes {
3368b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
3369c51ffa0bSJohan Hedberg 	int removed = 0;
3370b899efafSVinicius Costa Gomes 
3371b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
3372e0b2b27eSJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type)
3373b899efafSVinicius Costa Gomes 			continue;
3374b899efafSVinicius Costa Gomes 
33756ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
3376b899efafSVinicius Costa Gomes 
3377b899efafSVinicius Costa Gomes 		list_del(&k->list);
3378b899efafSVinicius Costa Gomes 		kfree(k);
3379c51ffa0bSJohan Hedberg 		removed++;
3380b899efafSVinicius Costa Gomes 	}
3381b899efafSVinicius Costa Gomes 
3382c51ffa0bSJohan Hedberg 	return removed ? 0 : -ENOENT;
3383b899efafSVinicius Costa Gomes }
3384b899efafSVinicius Costa Gomes 
3385a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type)
3386a7ec7338SJohan Hedberg {
3387a7ec7338SJohan Hedberg 	struct smp_irk *k, *tmp;
3388a7ec7338SJohan Hedberg 
3389668b7b19SJohan Hedberg 	list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) {
3390a7ec7338SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type)
3391a7ec7338SJohan Hedberg 			continue;
3392a7ec7338SJohan Hedberg 
3393a7ec7338SJohan Hedberg 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
3394a7ec7338SJohan Hedberg 
3395a7ec7338SJohan Hedberg 		list_del(&k->list);
3396a7ec7338SJohan Hedberg 		kfree(k);
3397a7ec7338SJohan Hedberg 	}
3398a7ec7338SJohan Hedberg }
3399a7ec7338SJohan Hedberg 
34006bd32326SVille Tervo /* HCI command timer function */
340165cc2b49SMarcel Holtmann static void hci_cmd_timeout(struct work_struct *work)
34026bd32326SVille Tervo {
340365cc2b49SMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev,
340465cc2b49SMarcel Holtmann 					    cmd_timer.work);
34056bd32326SVille Tervo 
3406bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
3407bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
3408bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
3409bda4f23aSAndrei Emeltchenko 
3410bda4f23aSAndrei Emeltchenko 		BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode);
3411bda4f23aSAndrei Emeltchenko 	} else {
34126bd32326SVille Tervo 		BT_ERR("%s command tx timeout", hdev->name);
3413bda4f23aSAndrei Emeltchenko 	}
3414bda4f23aSAndrei Emeltchenko 
34156bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
3416c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
34176bd32326SVille Tervo }
34186bd32326SVille Tervo 
34192763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
34202763eda6SSzymon Janc 					  bdaddr_t *bdaddr)
34212763eda6SSzymon Janc {
34222763eda6SSzymon Janc 	struct oob_data *data;
34232763eda6SSzymon Janc 
34242763eda6SSzymon Janc 	list_for_each_entry(data, &hdev->remote_oob_data, list)
34252763eda6SSzymon Janc 		if (bacmp(bdaddr, &data->bdaddr) == 0)
34262763eda6SSzymon Janc 			return data;
34272763eda6SSzymon Janc 
34282763eda6SSzymon Janc 	return NULL;
34292763eda6SSzymon Janc }
34302763eda6SSzymon Janc 
34312763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
34322763eda6SSzymon Janc {
34332763eda6SSzymon Janc 	struct oob_data *data;
34342763eda6SSzymon Janc 
34352763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
34362763eda6SSzymon Janc 	if (!data)
34372763eda6SSzymon Janc 		return -ENOENT;
34382763eda6SSzymon Janc 
34396ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
34402763eda6SSzymon Janc 
34412763eda6SSzymon Janc 	list_del(&data->list);
34422763eda6SSzymon Janc 	kfree(data);
34432763eda6SSzymon Janc 
34442763eda6SSzymon Janc 	return 0;
34452763eda6SSzymon Janc }
34462763eda6SSzymon Janc 
344735f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev)
34482763eda6SSzymon Janc {
34492763eda6SSzymon Janc 	struct oob_data *data, *n;
34502763eda6SSzymon Janc 
34512763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
34522763eda6SSzymon Janc 		list_del(&data->list);
34532763eda6SSzymon Janc 		kfree(data);
34542763eda6SSzymon Janc 	}
34552763eda6SSzymon Janc }
34562763eda6SSzymon Janc 
34570798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
34580798872eSMarcel Holtmann 			    u8 *hash, u8 *randomizer)
34592763eda6SSzymon Janc {
34602763eda6SSzymon Janc 	struct oob_data *data;
34612763eda6SSzymon Janc 
34622763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
34632763eda6SSzymon Janc 	if (!data) {
34640a14ab41SJohan Hedberg 		data = kmalloc(sizeof(*data), GFP_KERNEL);
34652763eda6SSzymon Janc 		if (!data)
34662763eda6SSzymon Janc 			return -ENOMEM;
34672763eda6SSzymon Janc 
34682763eda6SSzymon Janc 		bacpy(&data->bdaddr, bdaddr);
34692763eda6SSzymon Janc 		list_add(&data->list, &hdev->remote_oob_data);
34702763eda6SSzymon Janc 	}
34712763eda6SSzymon Janc 
3472519ca9d0SMarcel Holtmann 	memcpy(data->hash192, hash, sizeof(data->hash192));
3473519ca9d0SMarcel Holtmann 	memcpy(data->randomizer192, randomizer, sizeof(data->randomizer192));
34742763eda6SSzymon Janc 
34750798872eSMarcel Holtmann 	memset(data->hash256, 0, sizeof(data->hash256));
34760798872eSMarcel Holtmann 	memset(data->randomizer256, 0, sizeof(data->randomizer256));
34770798872eSMarcel Holtmann 
34780798872eSMarcel Holtmann 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
34790798872eSMarcel Holtmann 
34800798872eSMarcel Holtmann 	return 0;
34810798872eSMarcel Holtmann }
34820798872eSMarcel Holtmann 
34830798872eSMarcel Holtmann int hci_add_remote_oob_ext_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
34840798872eSMarcel Holtmann 				u8 *hash192, u8 *randomizer192,
34850798872eSMarcel Holtmann 				u8 *hash256, u8 *randomizer256)
34860798872eSMarcel Holtmann {
34870798872eSMarcel Holtmann 	struct oob_data *data;
34880798872eSMarcel Holtmann 
34890798872eSMarcel Holtmann 	data = hci_find_remote_oob_data(hdev, bdaddr);
34900798872eSMarcel Holtmann 	if (!data) {
34910a14ab41SJohan Hedberg 		data = kmalloc(sizeof(*data), GFP_KERNEL);
34920798872eSMarcel Holtmann 		if (!data)
34930798872eSMarcel Holtmann 			return -ENOMEM;
34940798872eSMarcel Holtmann 
34950798872eSMarcel Holtmann 		bacpy(&data->bdaddr, bdaddr);
34960798872eSMarcel Holtmann 		list_add(&data->list, &hdev->remote_oob_data);
34970798872eSMarcel Holtmann 	}
34980798872eSMarcel Holtmann 
34990798872eSMarcel Holtmann 	memcpy(data->hash192, hash192, sizeof(data->hash192));
35000798872eSMarcel Holtmann 	memcpy(data->randomizer192, randomizer192, sizeof(data->randomizer192));
35010798872eSMarcel Holtmann 
35020798872eSMarcel Holtmann 	memcpy(data->hash256, hash256, sizeof(data->hash256));
35030798872eSMarcel Holtmann 	memcpy(data->randomizer256, randomizer256, sizeof(data->randomizer256));
35040798872eSMarcel Holtmann 
35056ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
35062763eda6SSzymon Janc 
35072763eda6SSzymon Janc 	return 0;
35082763eda6SSzymon Janc }
35092763eda6SSzymon Janc 
3510dcc36c16SJohan Hedberg struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
3511b9ee0a78SMarcel Holtmann 					 bdaddr_t *bdaddr, u8 type)
3512b2a66aadSAntti Julku {
3513b2a66aadSAntti Julku 	struct bdaddr_list *b;
3514b2a66aadSAntti Julku 
3515dcc36c16SJohan Hedberg 	list_for_each_entry(b, bdaddr_list, list) {
3516b9ee0a78SMarcel Holtmann 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
3517b2a66aadSAntti Julku 			return b;
3518b9ee0a78SMarcel Holtmann 	}
3519b2a66aadSAntti Julku 
3520b2a66aadSAntti Julku 	return NULL;
3521b2a66aadSAntti Julku }
3522b2a66aadSAntti Julku 
3523dcc36c16SJohan Hedberg void hci_bdaddr_list_clear(struct list_head *bdaddr_list)
3524b2a66aadSAntti Julku {
3525b2a66aadSAntti Julku 	struct list_head *p, *n;
3526b2a66aadSAntti Julku 
3527dcc36c16SJohan Hedberg 	list_for_each_safe(p, n, bdaddr_list) {
3528b9ee0a78SMarcel Holtmann 		struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list);
3529b2a66aadSAntti Julku 
3530b2a66aadSAntti Julku 		list_del(p);
3531b2a66aadSAntti Julku 		kfree(b);
3532b2a66aadSAntti Julku 	}
3533b2a66aadSAntti Julku }
3534b2a66aadSAntti Julku 
3535dcc36c16SJohan Hedberg int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type)
3536b2a66aadSAntti Julku {
3537b2a66aadSAntti Julku 	struct bdaddr_list *entry;
3538b2a66aadSAntti Julku 
3539b9ee0a78SMarcel Holtmann 	if (!bacmp(bdaddr, BDADDR_ANY))
3540b2a66aadSAntti Julku 		return -EBADF;
3541b2a66aadSAntti Julku 
3542dcc36c16SJohan Hedberg 	if (hci_bdaddr_list_lookup(list, bdaddr, type))
35435e762444SAntti Julku 		return -EEXIST;
3544b2a66aadSAntti Julku 
354527f70f3eSJohan Hedberg 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
35465e762444SAntti Julku 	if (!entry)
35475e762444SAntti Julku 		return -ENOMEM;
3548b2a66aadSAntti Julku 
3549b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
3550b9ee0a78SMarcel Holtmann 	entry->bdaddr_type = type;
3551b2a66aadSAntti Julku 
3552dcc36c16SJohan Hedberg 	list_add(&entry->list, list);
3553b2a66aadSAntti Julku 
35542a8357f2SJohan Hedberg 	return 0;
3555b2a66aadSAntti Julku }
3556b2a66aadSAntti Julku 
3557dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type)
3558b2a66aadSAntti Julku {
3559b2a66aadSAntti Julku 	struct bdaddr_list *entry;
3560b2a66aadSAntti Julku 
356135f7498aSJohan Hedberg 	if (!bacmp(bdaddr, BDADDR_ANY)) {
3562dcc36c16SJohan Hedberg 		hci_bdaddr_list_clear(list);
356335f7498aSJohan Hedberg 		return 0;
356435f7498aSJohan Hedberg 	}
3565b2a66aadSAntti Julku 
3566dcc36c16SJohan Hedberg 	entry = hci_bdaddr_list_lookup(list, bdaddr, type);
3567d2ab0ac1SMarcel Holtmann 	if (!entry)
3568d2ab0ac1SMarcel Holtmann 		return -ENOENT;
3569d2ab0ac1SMarcel Holtmann 
3570d2ab0ac1SMarcel Holtmann 	list_del(&entry->list);
3571d2ab0ac1SMarcel Holtmann 	kfree(entry);
3572d2ab0ac1SMarcel Holtmann 
3573d2ab0ac1SMarcel Holtmann 	return 0;
3574d2ab0ac1SMarcel Holtmann }
3575d2ab0ac1SMarcel Holtmann 
357615819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
357715819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
357815819a70SAndre Guedes 					       bdaddr_t *addr, u8 addr_type)
357915819a70SAndre Guedes {
358015819a70SAndre Guedes 	struct hci_conn_params *params;
358115819a70SAndre Guedes 
3582738f6185SJohan Hedberg 	/* The conn params list only contains identity addresses */
3583738f6185SJohan Hedberg 	if (!hci_is_identity_address(addr, addr_type))
3584738f6185SJohan Hedberg 		return NULL;
3585738f6185SJohan Hedberg 
358615819a70SAndre Guedes 	list_for_each_entry(params, &hdev->le_conn_params, list) {
358715819a70SAndre Guedes 		if (bacmp(&params->addr, addr) == 0 &&
358815819a70SAndre Guedes 		    params->addr_type == addr_type) {
358915819a70SAndre Guedes 			return params;
359015819a70SAndre Guedes 		}
359115819a70SAndre Guedes 	}
359215819a70SAndre Guedes 
359315819a70SAndre Guedes 	return NULL;
359415819a70SAndre Guedes }
359515819a70SAndre Guedes 
3596cef952ceSAndre Guedes static bool is_connected(struct hci_dev *hdev, bdaddr_t *addr, u8 type)
3597cef952ceSAndre Guedes {
3598cef952ceSAndre Guedes 	struct hci_conn *conn;
3599cef952ceSAndre Guedes 
3600cef952ceSAndre Guedes 	conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, addr);
3601cef952ceSAndre Guedes 	if (!conn)
3602cef952ceSAndre Guedes 		return false;
3603cef952ceSAndre Guedes 
3604cef952ceSAndre Guedes 	if (conn->dst_type != type)
3605cef952ceSAndre Guedes 		return false;
3606cef952ceSAndre Guedes 
3607cef952ceSAndre Guedes 	if (conn->state != BT_CONNECTED)
3608cef952ceSAndre Guedes 		return false;
3609cef952ceSAndre Guedes 
3610cef952ceSAndre Guedes 	return true;
3611cef952ceSAndre Guedes }
3612cef952ceSAndre Guedes 
361315819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
3614501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list,
36154b10966fSMarcel Holtmann 						  bdaddr_t *addr, u8 addr_type)
361615819a70SAndre Guedes {
3617912b42efSJohan Hedberg 	struct hci_conn_params *param;
361815819a70SAndre Guedes 
3619738f6185SJohan Hedberg 	/* The list only contains identity addresses */
3620738f6185SJohan Hedberg 	if (!hci_is_identity_address(addr, addr_type))
3621738f6185SJohan Hedberg 		return NULL;
362215819a70SAndre Guedes 
3623501f8827SJohan Hedberg 	list_for_each_entry(param, list, action) {
3624912b42efSJohan Hedberg 		if (bacmp(&param->addr, addr) == 0 &&
3625912b42efSJohan Hedberg 		    param->addr_type == addr_type)
3626912b42efSJohan Hedberg 			return param;
36274b10966fSMarcel Holtmann 	}
36284b10966fSMarcel Holtmann 
36294b10966fSMarcel Holtmann 	return NULL;
363015819a70SAndre Guedes }
363115819a70SAndre Guedes 
363215819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
363351d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev,
363451d167c0SMarcel Holtmann 					    bdaddr_t *addr, u8 addr_type)
363515819a70SAndre Guedes {
363615819a70SAndre Guedes 	struct hci_conn_params *params;
363715819a70SAndre Guedes 
3638c46245b3SJohan Hedberg 	if (!hci_is_identity_address(addr, addr_type))
363951d167c0SMarcel Holtmann 		return NULL;
3640a9b0a04cSAndre Guedes 
364115819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
3642cef952ceSAndre Guedes 	if (params)
364351d167c0SMarcel Holtmann 		return params;
364415819a70SAndre Guedes 
364515819a70SAndre Guedes 	params = kzalloc(sizeof(*params), GFP_KERNEL);
364615819a70SAndre Guedes 	if (!params) {
364715819a70SAndre Guedes 		BT_ERR("Out of memory");
364851d167c0SMarcel Holtmann 		return NULL;
364915819a70SAndre Guedes 	}
365015819a70SAndre Guedes 
365115819a70SAndre Guedes 	bacpy(&params->addr, addr);
365215819a70SAndre Guedes 	params->addr_type = addr_type;
3653cef952ceSAndre Guedes 
3654cef952ceSAndre Guedes 	list_add(&params->list, &hdev->le_conn_params);
365593450c75SJohan Hedberg 	INIT_LIST_HEAD(&params->action);
3656cef952ceSAndre Guedes 
3657bf5b3c8bSMarcel Holtmann 	params->conn_min_interval = hdev->le_conn_min_interval;
3658bf5b3c8bSMarcel Holtmann 	params->conn_max_interval = hdev->le_conn_max_interval;
3659bf5b3c8bSMarcel Holtmann 	params->conn_latency = hdev->le_conn_latency;
3660bf5b3c8bSMarcel Holtmann 	params->supervision_timeout = hdev->le_supv_timeout;
3661bf5b3c8bSMarcel Holtmann 	params->auto_connect = HCI_AUTO_CONN_DISABLED;
3662bf5b3c8bSMarcel Holtmann 
3663bf5b3c8bSMarcel Holtmann 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
3664bf5b3c8bSMarcel Holtmann 
366551d167c0SMarcel Holtmann 	return params;
3666bf5b3c8bSMarcel Holtmann }
3667bf5b3c8bSMarcel Holtmann 
3668bf5b3c8bSMarcel Holtmann /* This function requires the caller holds hdev->lock */
3669bf5b3c8bSMarcel Holtmann int hci_conn_params_set(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
3670d06b50ceSMarcel Holtmann 			u8 auto_connect)
367115819a70SAndre Guedes {
367215819a70SAndre Guedes 	struct hci_conn_params *params;
367315819a70SAndre Guedes 
36748c87aae1SMarcel Holtmann 	params = hci_conn_params_add(hdev, addr, addr_type);
36758c87aae1SMarcel Holtmann 	if (!params)
36768c87aae1SMarcel Holtmann 		return -EIO;
367715819a70SAndre Guedes 
367842ce26deSJohan Hedberg 	if (params->auto_connect == auto_connect)
367942ce26deSJohan Hedberg 		return 0;
368042ce26deSJohan Hedberg 
368166f8455aSJohan Hedberg 	list_del_init(&params->action);
368215819a70SAndre Guedes 
3683cef952ceSAndre Guedes 	switch (auto_connect) {
3684cef952ceSAndre Guedes 	case HCI_AUTO_CONN_DISABLED:
3685cef952ceSAndre Guedes 	case HCI_AUTO_CONN_LINK_LOSS:
368695305baaSJohan Hedberg 		hci_update_background_scan(hdev);
3687cef952ceSAndre Guedes 		break;
3688851efca8SJohan Hedberg 	case HCI_AUTO_CONN_REPORT:
368995305baaSJohan Hedberg 		list_add(&params->action, &hdev->pend_le_reports);
369095305baaSJohan Hedberg 		hci_update_background_scan(hdev);
3691851efca8SJohan Hedberg 		break;
36924b9e7e75SMarcel Holtmann 	case HCI_AUTO_CONN_DIRECT:
3693cef952ceSAndre Guedes 	case HCI_AUTO_CONN_ALWAYS:
369495305baaSJohan Hedberg 		if (!is_connected(hdev, addr, addr_type)) {
369595305baaSJohan Hedberg 			list_add(&params->action, &hdev->pend_le_conns);
369695305baaSJohan Hedberg 			hci_update_background_scan(hdev);
369795305baaSJohan Hedberg 		}
3698cef952ceSAndre Guedes 		break;
3699cef952ceSAndre Guedes 	}
370015819a70SAndre Guedes 
3701851efca8SJohan Hedberg 	params->auto_connect = auto_connect;
3702851efca8SJohan Hedberg 
3703d06b50ceSMarcel Holtmann 	BT_DBG("addr %pMR (type %u) auto_connect %u", addr, addr_type,
3704d06b50ceSMarcel Holtmann 	       auto_connect);
3705a9b0a04cSAndre Guedes 
3706a9b0a04cSAndre Guedes 	return 0;
370715819a70SAndre Guedes }
370815819a70SAndre Guedes 
3709f6c63249SJohan Hedberg static void hci_conn_params_free(struct hci_conn_params *params)
3710f6c63249SJohan Hedberg {
3711f6c63249SJohan Hedberg 	if (params->conn) {
3712f6c63249SJohan Hedberg 		hci_conn_drop(params->conn);
3713f6c63249SJohan Hedberg 		hci_conn_put(params->conn);
3714f6c63249SJohan Hedberg 	}
3715f6c63249SJohan Hedberg 
3716f6c63249SJohan Hedberg 	list_del(&params->action);
3717f6c63249SJohan Hedberg 	list_del(&params->list);
3718f6c63249SJohan Hedberg 	kfree(params);
3719f6c63249SJohan Hedberg }
3720f6c63249SJohan Hedberg 
372115819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
372215819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
372315819a70SAndre Guedes {
372415819a70SAndre Guedes 	struct hci_conn_params *params;
372515819a70SAndre Guedes 
372615819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
372715819a70SAndre Guedes 	if (!params)
372815819a70SAndre Guedes 		return;
372915819a70SAndre Guedes 
3730f6c63249SJohan Hedberg 	hci_conn_params_free(params);
373115819a70SAndre Guedes 
373295305baaSJohan Hedberg 	hci_update_background_scan(hdev);
373395305baaSJohan Hedberg 
373415819a70SAndre Guedes 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
373515819a70SAndre Guedes }
373615819a70SAndre Guedes 
373715819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
373855af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev)
373915819a70SAndre Guedes {
374015819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
374115819a70SAndre Guedes 
374215819a70SAndre Guedes 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
374355af49a8SJohan Hedberg 		if (params->auto_connect != HCI_AUTO_CONN_DISABLED)
374455af49a8SJohan Hedberg 			continue;
374515819a70SAndre Guedes 		list_del(&params->list);
374615819a70SAndre Guedes 		kfree(params);
374715819a70SAndre Guedes 	}
374815819a70SAndre Guedes 
374955af49a8SJohan Hedberg 	BT_DBG("All LE disabled connection parameters were removed");
375055af49a8SJohan Hedberg }
375155af49a8SJohan Hedberg 
375255af49a8SJohan Hedberg /* This function requires the caller holds hdev->lock */
3753373110c5SJohan Hedberg void hci_conn_params_clear_all(struct hci_dev *hdev)
375415819a70SAndre Guedes {
375515819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
375615819a70SAndre Guedes 
3757f6c63249SJohan Hedberg 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list)
3758f6c63249SJohan Hedberg 		hci_conn_params_free(params);
375915819a70SAndre Guedes 
3760a2f41a8fSJohan Hedberg 	hci_update_background_scan(hdev);
37611089b67dSMarcel Holtmann 
376215819a70SAndre Guedes 	BT_DBG("All LE connection parameters were removed");
376315819a70SAndre Guedes }
376415819a70SAndre Guedes 
37654c87eaabSAndre Guedes static void inquiry_complete(struct hci_dev *hdev, u8 status)
37667ba8b4beSAndre Guedes {
37674c87eaabSAndre Guedes 	if (status) {
37684c87eaabSAndre Guedes 		BT_ERR("Failed to start inquiry: status %d", status);
37697ba8b4beSAndre Guedes 
37704c87eaabSAndre Guedes 		hci_dev_lock(hdev);
37714c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
37724c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
37734c87eaabSAndre Guedes 		return;
37744c87eaabSAndre Guedes 	}
37757ba8b4beSAndre Guedes }
37767ba8b4beSAndre Guedes 
37774c87eaabSAndre Guedes static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status)
37787ba8b4beSAndre Guedes {
37794c87eaabSAndre Guedes 	/* General inquiry access code (GIAC) */
37804c87eaabSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
37814c87eaabSAndre Guedes 	struct hci_request req;
37824c87eaabSAndre Guedes 	struct hci_cp_inquiry cp;
37837ba8b4beSAndre Guedes 	int err;
37847ba8b4beSAndre Guedes 
37854c87eaabSAndre Guedes 	if (status) {
37864c87eaabSAndre Guedes 		BT_ERR("Failed to disable LE scanning: status %d", status);
37874c87eaabSAndre Guedes 		return;
37887ba8b4beSAndre Guedes 	}
37897ba8b4beSAndre Guedes 
37904c87eaabSAndre Guedes 	switch (hdev->discovery.type) {
37914c87eaabSAndre Guedes 	case DISCOV_TYPE_LE:
37924c87eaabSAndre Guedes 		hci_dev_lock(hdev);
37934c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
37944c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
37954c87eaabSAndre Guedes 		break;
37967dbfac1dSAndre Guedes 
37974c87eaabSAndre Guedes 	case DISCOV_TYPE_INTERLEAVED:
37984c87eaabSAndre Guedes 		hci_req_init(&req, hdev);
37997dbfac1dSAndre Guedes 
38007dbfac1dSAndre Guedes 		memset(&cp, 0, sizeof(cp));
38014c87eaabSAndre Guedes 		memcpy(&cp.lap, lap, sizeof(cp.lap));
38024c87eaabSAndre Guedes 		cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN;
38034c87eaabSAndre Guedes 		hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp);
38044c87eaabSAndre Guedes 
38054c87eaabSAndre Guedes 		hci_dev_lock(hdev);
38064c87eaabSAndre Guedes 
38074c87eaabSAndre Guedes 		hci_inquiry_cache_flush(hdev);
38084c87eaabSAndre Guedes 
38094c87eaabSAndre Guedes 		err = hci_req_run(&req, inquiry_complete);
38104c87eaabSAndre Guedes 		if (err) {
38114c87eaabSAndre Guedes 			BT_ERR("Inquiry request failed: err %d", err);
38124c87eaabSAndre Guedes 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
38137dbfac1dSAndre Guedes 		}
38147dbfac1dSAndre Guedes 
38154c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
38164c87eaabSAndre Guedes 		break;
38174c87eaabSAndre Guedes 	}
38187dbfac1dSAndre Guedes }
38197dbfac1dSAndre Guedes 
38207ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work)
38217ba8b4beSAndre Guedes {
38227ba8b4beSAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev,
38237ba8b4beSAndre Guedes 					    le_scan_disable.work);
38244c87eaabSAndre Guedes 	struct hci_request req;
38254c87eaabSAndre Guedes 	int err;
38267ba8b4beSAndre Guedes 
38277ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
38287ba8b4beSAndre Guedes 
38294c87eaabSAndre Guedes 	hci_req_init(&req, hdev);
38307ba8b4beSAndre Guedes 
3831b1efcc28SAndre Guedes 	hci_req_add_le_scan_disable(&req);
38327ba8b4beSAndre Guedes 
38334c87eaabSAndre Guedes 	err = hci_req_run(&req, le_scan_disable_work_complete);
38344c87eaabSAndre Guedes 	if (err)
38354c87eaabSAndre Guedes 		BT_ERR("Disable LE scanning request failed: err %d", err);
383628b75a89SAndre Guedes }
383728b75a89SAndre Guedes 
38388d97250eSJohan Hedberg static void set_random_addr(struct hci_request *req, bdaddr_t *rpa)
38398d97250eSJohan Hedberg {
38408d97250eSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
38418d97250eSJohan Hedberg 
38428d97250eSJohan Hedberg 	/* If we're advertising or initiating an LE connection we can't
38438d97250eSJohan Hedberg 	 * go ahead and change the random address at this time. This is
38448d97250eSJohan Hedberg 	 * because the eventual initiator address used for the
38458d97250eSJohan Hedberg 	 * subsequently created connection will be undefined (some
38468d97250eSJohan Hedberg 	 * controllers use the new address and others the one we had
38478d97250eSJohan Hedberg 	 * when the operation started).
38488d97250eSJohan Hedberg 	 *
38498d97250eSJohan Hedberg 	 * In this kind of scenario skip the update and let the random
38508d97250eSJohan Hedberg 	 * address be updated at the next cycle.
38518d97250eSJohan Hedberg 	 */
38525ce194c4SJohan Hedberg 	if (test_bit(HCI_LE_ADV, &hdev->dev_flags) ||
38538d97250eSJohan Hedberg 	    hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT)) {
38548d97250eSJohan Hedberg 		BT_DBG("Deferring random address update");
38559a783a13SJohan Hedberg 		set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags);
38568d97250eSJohan Hedberg 		return;
38578d97250eSJohan Hedberg 	}
38588d97250eSJohan Hedberg 
38598d97250eSJohan Hedberg 	hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6, rpa);
38608d97250eSJohan Hedberg }
38618d97250eSJohan Hedberg 
386294b1fc92SMarcel Holtmann int hci_update_random_address(struct hci_request *req, bool require_privacy,
386394b1fc92SMarcel Holtmann 			      u8 *own_addr_type)
3864ebd3a747SJohan Hedberg {
3865ebd3a747SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
3866ebd3a747SJohan Hedberg 	int err;
3867ebd3a747SJohan Hedberg 
3868ebd3a747SJohan Hedberg 	/* If privacy is enabled use a resolvable private address. If
38692b5224dcSMarcel Holtmann 	 * current RPA has expired or there is something else than
38702b5224dcSMarcel Holtmann 	 * the current RPA in use, then generate a new one.
3871ebd3a747SJohan Hedberg 	 */
3872ebd3a747SJohan Hedberg 	if (test_bit(HCI_PRIVACY, &hdev->dev_flags)) {
3873ebd3a747SJohan Hedberg 		int to;
3874ebd3a747SJohan Hedberg 
3875ebd3a747SJohan Hedberg 		*own_addr_type = ADDR_LE_DEV_RANDOM;
3876ebd3a747SJohan Hedberg 
3877ebd3a747SJohan Hedberg 		if (!test_and_clear_bit(HCI_RPA_EXPIRED, &hdev->dev_flags) &&
38782b5224dcSMarcel Holtmann 		    !bacmp(&hdev->random_addr, &hdev->rpa))
3879ebd3a747SJohan Hedberg 			return 0;
3880ebd3a747SJohan Hedberg 
3881defce9e8SJohan Hedberg 		err = smp_generate_rpa(hdev, hdev->irk, &hdev->rpa);
3882ebd3a747SJohan Hedberg 		if (err < 0) {
3883ebd3a747SJohan Hedberg 			BT_ERR("%s failed to generate new RPA", hdev->name);
3884ebd3a747SJohan Hedberg 			return err;
3885ebd3a747SJohan Hedberg 		}
3886ebd3a747SJohan Hedberg 
38878d97250eSJohan Hedberg 		set_random_addr(req, &hdev->rpa);
3888ebd3a747SJohan Hedberg 
3889ebd3a747SJohan Hedberg 		to = msecs_to_jiffies(hdev->rpa_timeout * 1000);
3890ebd3a747SJohan Hedberg 		queue_delayed_work(hdev->workqueue, &hdev->rpa_expired, to);
3891ebd3a747SJohan Hedberg 
3892ebd3a747SJohan Hedberg 		return 0;
3893ebd3a747SJohan Hedberg 	}
3894ebd3a747SJohan Hedberg 
389594b1fc92SMarcel Holtmann 	/* In case of required privacy without resolvable private address,
389694b1fc92SMarcel Holtmann 	 * use an unresolvable private address. This is useful for active
389794b1fc92SMarcel Holtmann 	 * scanning and non-connectable advertising.
389894b1fc92SMarcel Holtmann 	 */
389994b1fc92SMarcel Holtmann 	if (require_privacy) {
390094b1fc92SMarcel Holtmann 		bdaddr_t urpa;
390194b1fc92SMarcel Holtmann 
390294b1fc92SMarcel Holtmann 		get_random_bytes(&urpa, 6);
390394b1fc92SMarcel Holtmann 		urpa.b[5] &= 0x3f;	/* Clear two most significant bits */
390494b1fc92SMarcel Holtmann 
390594b1fc92SMarcel Holtmann 		*own_addr_type = ADDR_LE_DEV_RANDOM;
39068d97250eSJohan Hedberg 		set_random_addr(req, &urpa);
390794b1fc92SMarcel Holtmann 		return 0;
390894b1fc92SMarcel Holtmann 	}
390994b1fc92SMarcel Holtmann 
3910ebd3a747SJohan Hedberg 	/* If forcing static address is in use or there is no public
3911ebd3a747SJohan Hedberg 	 * address use the static address as random address (but skip
3912ebd3a747SJohan Hedberg 	 * the HCI command if the current random address is already the
3913ebd3a747SJohan Hedberg 	 * static one.
3914ebd3a747SJohan Hedberg 	 */
3915111902f7SMarcel Holtmann 	if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) ||
3916ebd3a747SJohan Hedberg 	    !bacmp(&hdev->bdaddr, BDADDR_ANY)) {
3917ebd3a747SJohan Hedberg 		*own_addr_type = ADDR_LE_DEV_RANDOM;
3918ebd3a747SJohan Hedberg 		if (bacmp(&hdev->static_addr, &hdev->random_addr))
3919ebd3a747SJohan Hedberg 			hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6,
3920ebd3a747SJohan Hedberg 				    &hdev->static_addr);
3921ebd3a747SJohan Hedberg 		return 0;
3922ebd3a747SJohan Hedberg 	}
3923ebd3a747SJohan Hedberg 
3924ebd3a747SJohan Hedberg 	/* Neither privacy nor static address is being used so use a
3925ebd3a747SJohan Hedberg 	 * public address.
3926ebd3a747SJohan Hedberg 	 */
3927ebd3a747SJohan Hedberg 	*own_addr_type = ADDR_LE_DEV_PUBLIC;
3928ebd3a747SJohan Hedberg 
3929ebd3a747SJohan Hedberg 	return 0;
3930ebd3a747SJohan Hedberg }
3931ebd3a747SJohan Hedberg 
3932a1f4c318SJohan Hedberg /* Copy the Identity Address of the controller.
3933a1f4c318SJohan Hedberg  *
3934a1f4c318SJohan Hedberg  * If the controller has a public BD_ADDR, then by default use that one.
3935a1f4c318SJohan Hedberg  * If this is a LE only controller without a public address, default to
3936a1f4c318SJohan Hedberg  * the static random address.
3937a1f4c318SJohan Hedberg  *
3938a1f4c318SJohan Hedberg  * For debugging purposes it is possible to force controllers with a
3939a1f4c318SJohan Hedberg  * public address to use the static random address instead.
3940a1f4c318SJohan Hedberg  */
3941a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
3942a1f4c318SJohan Hedberg 			       u8 *bdaddr_type)
3943a1f4c318SJohan Hedberg {
3944111902f7SMarcel Holtmann 	if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dbg_flags) ||
3945a1f4c318SJohan Hedberg 	    !bacmp(&hdev->bdaddr, BDADDR_ANY)) {
3946a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->static_addr);
3947a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_RANDOM;
3948a1f4c318SJohan Hedberg 	} else {
3949a1f4c318SJohan Hedberg 		bacpy(bdaddr, &hdev->bdaddr);
3950a1f4c318SJohan Hedberg 		*bdaddr_type = ADDR_LE_DEV_PUBLIC;
3951a1f4c318SJohan Hedberg 	}
3952a1f4c318SJohan Hedberg }
3953a1f4c318SJohan Hedberg 
39549be0dab7SDavid Herrmann /* Alloc HCI device */
39559be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void)
39569be0dab7SDavid Herrmann {
39579be0dab7SDavid Herrmann 	struct hci_dev *hdev;
39589be0dab7SDavid Herrmann 
395927f70f3eSJohan Hedberg 	hdev = kzalloc(sizeof(*hdev), GFP_KERNEL);
39609be0dab7SDavid Herrmann 	if (!hdev)
39619be0dab7SDavid Herrmann 		return NULL;
39629be0dab7SDavid Herrmann 
3963b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
3964b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
3965b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
3966b4cb9fb2SMarcel Holtmann 	hdev->num_iac = 0x01;		/* One IAC support is mandatory */
3967b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03;	/* No Input No Output */
396896c2103aSMarcel Holtmann 	hdev->manufacturer = 0xffff;	/* Default to internal use */
3969bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
3970bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
3971b1b813d4SDavid Herrmann 
3972b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
3973b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
3974b1b813d4SDavid Herrmann 
39753f959d46SMarcel Holtmann 	hdev->le_adv_channel_map = 0x07;
3976628531c9SGeorg Lukas 	hdev->le_adv_min_interval = 0x0800;
3977628531c9SGeorg Lukas 	hdev->le_adv_max_interval = 0x0800;
3978bef64738SMarcel Holtmann 	hdev->le_scan_interval = 0x0060;
3979bef64738SMarcel Holtmann 	hdev->le_scan_window = 0x0030;
39804e70c7e7SMarcel Holtmann 	hdev->le_conn_min_interval = 0x0028;
39814e70c7e7SMarcel Holtmann 	hdev->le_conn_max_interval = 0x0038;
398204fb7d90SMarcel Holtmann 	hdev->le_conn_latency = 0x0000;
398304fb7d90SMarcel Holtmann 	hdev->le_supv_timeout = 0x002a;
3984bef64738SMarcel Holtmann 
3985d6bfd59cSJohan Hedberg 	hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT;
3986b9a7a61eSLukasz Rymanowski 	hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT;
398731ad1691SAndrzej Kaczmarek 	hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE;
398831ad1691SAndrzej Kaczmarek 	hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE;
3989d6bfd59cSJohan Hedberg 
3990b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
3991b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
3992b1b813d4SDavid Herrmann 
3993b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
3994b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->blacklist);
39956659358eSJohan Hedberg 	INIT_LIST_HEAD(&hdev->whitelist);
3996b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
3997b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
3998b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
3999970c4e46SJohan Hedberg 	INIT_LIST_HEAD(&hdev->identity_resolving_keys);
4000b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
4001d2ab0ac1SMarcel Holtmann 	INIT_LIST_HEAD(&hdev->le_white_list);
400215819a70SAndre Guedes 	INIT_LIST_HEAD(&hdev->le_conn_params);
400377a77a30SAndre Guedes 	INIT_LIST_HEAD(&hdev->pend_le_conns);
400466f8455aSJohan Hedberg 	INIT_LIST_HEAD(&hdev->pend_le_reports);
40056b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
4006b1b813d4SDavid Herrmann 
4007b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
4008b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
4009b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
4010b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
4011b1b813d4SDavid Herrmann 
4012b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
4013b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
4014b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
4015b1b813d4SDavid Herrmann 
4016b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
4017b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
4018b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
4019b1b813d4SDavid Herrmann 
4020b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
4021b1b813d4SDavid Herrmann 
402265cc2b49SMarcel Holtmann 	INIT_DELAYED_WORK(&hdev->cmd_timer, hci_cmd_timeout);
4023b1b813d4SDavid Herrmann 
4024b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
4025b1b813d4SDavid Herrmann 	discovery_init(hdev);
40269be0dab7SDavid Herrmann 
40279be0dab7SDavid Herrmann 	return hdev;
40289be0dab7SDavid Herrmann }
40299be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev);
40309be0dab7SDavid Herrmann 
40319be0dab7SDavid Herrmann /* Free HCI device */
40329be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
40339be0dab7SDavid Herrmann {
40349be0dab7SDavid Herrmann 	/* will free via device release */
40359be0dab7SDavid Herrmann 	put_device(&hdev->dev);
40369be0dab7SDavid Herrmann }
40379be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
40389be0dab7SDavid Herrmann 
40391da177e4SLinus Torvalds /* Register HCI device */
40401da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
40411da177e4SLinus Torvalds {
4042b1b813d4SDavid Herrmann 	int id, error;
40431da177e4SLinus Torvalds 
404474292d5aSMarcel Holtmann 	if (!hdev->open || !hdev->close || !hdev->send)
40451da177e4SLinus Torvalds 		return -EINVAL;
40461da177e4SLinus Torvalds 
404708add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
404808add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
404908add513SMat Martineau 	 */
40503df92b31SSasha Levin 	switch (hdev->dev_type) {
40513df92b31SSasha Levin 	case HCI_BREDR:
40523df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
40531da177e4SLinus Torvalds 		break;
40543df92b31SSasha Levin 	case HCI_AMP:
40553df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
40563df92b31SSasha Levin 		break;
40573df92b31SSasha Levin 	default:
40583df92b31SSasha Levin 		return -EINVAL;
40591da177e4SLinus Torvalds 	}
40601da177e4SLinus Torvalds 
40613df92b31SSasha Levin 	if (id < 0)
40623df92b31SSasha Levin 		return id;
40633df92b31SSasha Levin 
40641da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
40651da177e4SLinus Torvalds 	hdev->id = id;
40662d8b3a11SAndrei Emeltchenko 
40672d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
40682d8b3a11SAndrei Emeltchenko 
4069d8537548SKees Cook 	hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
4070d8537548SKees Cook 					  WQ_MEM_RECLAIM, 1, hdev->name);
407133ca954dSDavid Herrmann 	if (!hdev->workqueue) {
407233ca954dSDavid Herrmann 		error = -ENOMEM;
407333ca954dSDavid Herrmann 		goto err;
407433ca954dSDavid Herrmann 	}
4075f48fd9c8SMarcel Holtmann 
4076d8537548SKees Cook 	hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
4077d8537548SKees Cook 					      WQ_MEM_RECLAIM, 1, hdev->name);
40786ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
40796ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
40806ead1bbcSJohan Hedberg 		error = -ENOMEM;
40816ead1bbcSJohan Hedberg 		goto err;
40826ead1bbcSJohan Hedberg 	}
40836ead1bbcSJohan Hedberg 
40840153e2ecSMarcel Holtmann 	if (!IS_ERR_OR_NULL(bt_debugfs))
40850153e2ecSMarcel Holtmann 		hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs);
40860153e2ecSMarcel Holtmann 
4087bdc3e0f1SMarcel Holtmann 	dev_set_name(&hdev->dev, "%s", hdev->name);
4088bdc3e0f1SMarcel Holtmann 
4089bdc3e0f1SMarcel Holtmann 	error = device_add(&hdev->dev);
409033ca954dSDavid Herrmann 	if (error < 0)
409154506918SJohan Hedberg 		goto err_wqueue;
40921da177e4SLinus Torvalds 
4093611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
4094a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
4095a8c5fb1aSGustavo Padovan 				    hdev);
4096611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
4097611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
4098611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
4099611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
4100611b30f7SMarcel Holtmann 		}
4101611b30f7SMarcel Holtmann 	}
4102611b30f7SMarcel Holtmann 
41035e130367SJohan Hedberg 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill))
41045e130367SJohan Hedberg 		set_bit(HCI_RFKILLED, &hdev->dev_flags);
41055e130367SJohan Hedberg 
4106a8b2d5c2SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->dev_flags);
4107004b0258SMarcel Holtmann 	set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
4108ce2be9acSAndrei Emeltchenko 
410901cd3404SMarcel Holtmann 	if (hdev->dev_type == HCI_BREDR) {
411056f87901SJohan Hedberg 		/* Assume BR/EDR support until proven otherwise (such as
411156f87901SJohan Hedberg 		 * through reading supported features during init.
411256f87901SJohan Hedberg 		 */
411356f87901SJohan Hedberg 		set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
411456f87901SJohan Hedberg 	}
4115ce2be9acSAndrei Emeltchenko 
4116fcee3377SGustavo Padovan 	write_lock(&hci_dev_list_lock);
4117fcee3377SGustavo Padovan 	list_add(&hdev->list, &hci_dev_list);
4118fcee3377SGustavo Padovan 	write_unlock(&hci_dev_list_lock);
4119fcee3377SGustavo Padovan 
41204a964404SMarcel Holtmann 	/* Devices that are marked for raw-only usage are unconfigured
41214a964404SMarcel Holtmann 	 * and should not be included in normal operation.
4122fee746b0SMarcel Holtmann 	 */
4123fee746b0SMarcel Holtmann 	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
41244a964404SMarcel Holtmann 		set_bit(HCI_UNCONFIGURED, &hdev->dev_flags);
4125fee746b0SMarcel Holtmann 
41261da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
4127dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
41281da177e4SLinus Torvalds 
412919202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
4130fbe96d6fSMarcel Holtmann 
41311da177e4SLinus Torvalds 	return id;
4132f48fd9c8SMarcel Holtmann 
413333ca954dSDavid Herrmann err_wqueue:
413433ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
41356ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
413633ca954dSDavid Herrmann err:
41373df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
4138f48fd9c8SMarcel Holtmann 
413933ca954dSDavid Herrmann 	return error;
41401da177e4SLinus Torvalds }
41411da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
41421da177e4SLinus Torvalds 
41431da177e4SLinus Torvalds /* Unregister HCI device */
414459735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
41451da177e4SLinus Torvalds {
41463df92b31SSasha Levin 	int i, id;
4147ef222013SMarcel Holtmann 
4148c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
41491da177e4SLinus Torvalds 
415094324962SJohan Hovold 	set_bit(HCI_UNREGISTER, &hdev->dev_flags);
415194324962SJohan Hovold 
41523df92b31SSasha Levin 	id = hdev->id;
41533df92b31SSasha Levin 
4154f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
41551da177e4SLinus Torvalds 	list_del(&hdev->list);
4156f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
41571da177e4SLinus Torvalds 
41581da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
41591da177e4SLinus Torvalds 
4160cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
4161ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
4162ef222013SMarcel Holtmann 
4163b9b5ef18SGustavo Padovan 	cancel_work_sync(&hdev->power_on);
4164b9b5ef18SGustavo Padovan 
4165ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
4166d603b76bSMarcel Holtmann 	    !test_bit(HCI_SETUP, &hdev->dev_flags) &&
4167d603b76bSMarcel Holtmann 	    !test_bit(HCI_CONFIG, &hdev->dev_flags)) {
416809fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
4169744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
417009fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
417156e5cb86SJohan Hedberg 	}
4172ab81cbf9SJohan Hedberg 
41732e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
41742e58ef3eSJohan Hedberg 	 * pending list */
41752e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
41762e58ef3eSJohan Hedberg 
41771da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
41781da177e4SLinus Torvalds 
4179611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
4180611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
4181611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
4182611b30f7SMarcel Holtmann 	}
4183611b30f7SMarcel Holtmann 
4184711eafe3SJohan Hedberg 	smp_unregister(hdev);
418599780a7bSJohan Hedberg 
4186bdc3e0f1SMarcel Holtmann 	device_del(&hdev->dev);
4187147e2d59SDave Young 
41880153e2ecSMarcel Holtmann 	debugfs_remove_recursive(hdev->debugfs);
41890153e2ecSMarcel Holtmann 
4190f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
41916ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
4192f48fd9c8SMarcel Holtmann 
419309fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
4194dcc36c16SJohan Hedberg 	hci_bdaddr_list_clear(&hdev->blacklist);
41956659358eSJohan Hedberg 	hci_bdaddr_list_clear(&hdev->whitelist);
41962aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
419755ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
4198b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
4199970c4e46SJohan Hedberg 	hci_smp_irks_clear(hdev);
42002763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
4201dcc36c16SJohan Hedberg 	hci_bdaddr_list_clear(&hdev->le_white_list);
4202373110c5SJohan Hedberg 	hci_conn_params_clear_all(hdev);
420309fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
4204e2e0cacbSJohan Hedberg 
4205dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
42063df92b31SSasha Levin 
42073df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, id);
42081da177e4SLinus Torvalds }
42091da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
42101da177e4SLinus Torvalds 
42111da177e4SLinus Torvalds /* Suspend HCI device */
42121da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
42131da177e4SLinus Torvalds {
42141da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
42151da177e4SLinus Torvalds 	return 0;
42161da177e4SLinus Torvalds }
42171da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
42181da177e4SLinus Torvalds 
42191da177e4SLinus Torvalds /* Resume HCI device */
42201da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
42211da177e4SLinus Torvalds {
42221da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
42231da177e4SLinus Torvalds 	return 0;
42241da177e4SLinus Torvalds }
42251da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
42261da177e4SLinus Torvalds 
422775e0569fSMarcel Holtmann /* Reset HCI device */
422875e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev)
422975e0569fSMarcel Holtmann {
423075e0569fSMarcel Holtmann 	const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 };
423175e0569fSMarcel Holtmann 	struct sk_buff *skb;
423275e0569fSMarcel Holtmann 
423375e0569fSMarcel Holtmann 	skb = bt_skb_alloc(3, GFP_ATOMIC);
423475e0569fSMarcel Holtmann 	if (!skb)
423575e0569fSMarcel Holtmann 		return -ENOMEM;
423675e0569fSMarcel Holtmann 
423775e0569fSMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
423875e0569fSMarcel Holtmann 	memcpy(skb_put(skb, 3), hw_err, 3);
423975e0569fSMarcel Holtmann 
424075e0569fSMarcel Holtmann 	/* Send Hardware Error to upper stack */
424175e0569fSMarcel Holtmann 	return hci_recv_frame(hdev, skb);
424275e0569fSMarcel Holtmann }
424375e0569fSMarcel Holtmann EXPORT_SYMBOL(hci_reset_dev);
424475e0569fSMarcel Holtmann 
424576bca880SMarcel Holtmann /* Receive frame from HCI drivers */
4246e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
424776bca880SMarcel Holtmann {
424876bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
424976bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
425076bca880SMarcel Holtmann 		kfree_skb(skb);
425176bca880SMarcel Holtmann 		return -ENXIO;
425276bca880SMarcel Holtmann 	}
425376bca880SMarcel Holtmann 
4254d82603c6SJorrit Schippers 	/* Incoming skb */
425576bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
425676bca880SMarcel Holtmann 
425776bca880SMarcel Holtmann 	/* Time stamp */
425876bca880SMarcel Holtmann 	__net_timestamp(skb);
425976bca880SMarcel Holtmann 
426076bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
4261b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
4262c78ae283SMarcel Holtmann 
426376bca880SMarcel Holtmann 	return 0;
426476bca880SMarcel Holtmann }
426576bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
426676bca880SMarcel Holtmann 
426733e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
42681e429f38SGustavo F. Padovan 			  int count, __u8 index)
426933e882a5SSuraj Sumangala {
427033e882a5SSuraj Sumangala 	int len = 0;
427133e882a5SSuraj Sumangala 	int hlen = 0;
427233e882a5SSuraj Sumangala 	int remain = count;
427333e882a5SSuraj Sumangala 	struct sk_buff *skb;
427433e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
427533e882a5SSuraj Sumangala 
427633e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
427733e882a5SSuraj Sumangala 	    index >= NUM_REASSEMBLY)
427833e882a5SSuraj Sumangala 		return -EILSEQ;
427933e882a5SSuraj Sumangala 
428033e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
428133e882a5SSuraj Sumangala 
428233e882a5SSuraj Sumangala 	if (!skb) {
428333e882a5SSuraj Sumangala 		switch (type) {
428433e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
428533e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
428633e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
428733e882a5SSuraj Sumangala 			break;
428833e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
428933e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
429033e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
429133e882a5SSuraj Sumangala 			break;
429233e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
429333e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
429433e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
429533e882a5SSuraj Sumangala 			break;
429633e882a5SSuraj Sumangala 		}
429733e882a5SSuraj Sumangala 
42981e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
429933e882a5SSuraj Sumangala 		if (!skb)
430033e882a5SSuraj Sumangala 			return -ENOMEM;
430133e882a5SSuraj Sumangala 
430233e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
430333e882a5SSuraj Sumangala 		scb->expect = hlen;
430433e882a5SSuraj Sumangala 		scb->pkt_type = type;
430533e882a5SSuraj Sumangala 
430633e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
430733e882a5SSuraj Sumangala 	}
430833e882a5SSuraj Sumangala 
430933e882a5SSuraj Sumangala 	while (count) {
431033e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
431189bb46d0SDan Carpenter 		len = min_t(uint, scb->expect, count);
431233e882a5SSuraj Sumangala 
431333e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
431433e882a5SSuraj Sumangala 
431533e882a5SSuraj Sumangala 		count -= len;
431633e882a5SSuraj Sumangala 		data += len;
431733e882a5SSuraj Sumangala 		scb->expect -= len;
431833e882a5SSuraj Sumangala 		remain = count;
431933e882a5SSuraj Sumangala 
432033e882a5SSuraj Sumangala 		switch (type) {
432133e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
432233e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
432333e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
432433e882a5SSuraj Sumangala 				scb->expect = h->plen;
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 		case HCI_ACLDATA_PKT:
433533e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
433633e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
433733e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
433833e882a5SSuraj Sumangala 
433933e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
434033e882a5SSuraj Sumangala 					kfree_skb(skb);
434133e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
434233e882a5SSuraj Sumangala 					return -ENOMEM;
434333e882a5SSuraj Sumangala 				}
434433e882a5SSuraj Sumangala 			}
434533e882a5SSuraj Sumangala 			break;
434633e882a5SSuraj Sumangala 
434733e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
434833e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
434933e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
435033e882a5SSuraj Sumangala 				scb->expect = h->dlen;
435133e882a5SSuraj Sumangala 
435233e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
435333e882a5SSuraj Sumangala 					kfree_skb(skb);
435433e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
435533e882a5SSuraj Sumangala 					return -ENOMEM;
435633e882a5SSuraj Sumangala 				}
435733e882a5SSuraj Sumangala 			}
435833e882a5SSuraj Sumangala 			break;
435933e882a5SSuraj Sumangala 		}
436033e882a5SSuraj Sumangala 
436133e882a5SSuraj Sumangala 		if (scb->expect == 0) {
436233e882a5SSuraj Sumangala 			/* Complete frame */
436333e882a5SSuraj Sumangala 
436433e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
4365e1a26170SMarcel Holtmann 			hci_recv_frame(hdev, skb);
436633e882a5SSuraj Sumangala 
436733e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
436833e882a5SSuraj Sumangala 			return remain;
436933e882a5SSuraj Sumangala 		}
437033e882a5SSuraj Sumangala 	}
437133e882a5SSuraj Sumangala 
437233e882a5SSuraj Sumangala 	return remain;
437333e882a5SSuraj Sumangala }
437433e882a5SSuraj Sumangala 
437599811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
437699811510SSuraj Sumangala 
437799811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
437899811510SSuraj Sumangala {
437999811510SSuraj Sumangala 	int type;
438099811510SSuraj Sumangala 	int rem = 0;
438199811510SSuraj Sumangala 
4382da5f6c37SGustavo F. Padovan 	while (count) {
438399811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
438499811510SSuraj Sumangala 
438599811510SSuraj Sumangala 		if (!skb) {
438699811510SSuraj Sumangala 			struct { char type; } *pkt;
438799811510SSuraj Sumangala 
438899811510SSuraj Sumangala 			/* Start of the frame */
438999811510SSuraj Sumangala 			pkt = data;
439099811510SSuraj Sumangala 			type = pkt->type;
439199811510SSuraj Sumangala 
439299811510SSuraj Sumangala 			data++;
439399811510SSuraj Sumangala 			count--;
439499811510SSuraj Sumangala 		} else
439599811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
439699811510SSuraj Sumangala 
43971e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
43981e429f38SGustavo F. Padovan 				     STREAM_REASSEMBLY);
439999811510SSuraj Sumangala 		if (rem < 0)
440099811510SSuraj Sumangala 			return rem;
440199811510SSuraj Sumangala 
440299811510SSuraj Sumangala 		data += (count - rem);
440399811510SSuraj Sumangala 		count = rem;
4404f81c6224SJoe Perches 	}
440599811510SSuraj Sumangala 
440699811510SSuraj Sumangala 	return rem;
440799811510SSuraj Sumangala }
440899811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
440999811510SSuraj Sumangala 
44101da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
44111da177e4SLinus Torvalds 
44121da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
44131da177e4SLinus Torvalds {
44141da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
44151da177e4SLinus Torvalds 
4416f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
44171da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
4418f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
44191da177e4SLinus Torvalds 
44201da177e4SLinus Torvalds 	return 0;
44211da177e4SLinus Torvalds }
44221da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
44231da177e4SLinus Torvalds 
44241da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
44251da177e4SLinus Torvalds {
44261da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
44271da177e4SLinus Torvalds 
4428f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
44291da177e4SLinus Torvalds 	list_del(&cb->list);
4430f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
44311da177e4SLinus Torvalds 
44321da177e4SLinus Torvalds 	return 0;
44331da177e4SLinus Torvalds }
44341da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
44351da177e4SLinus Torvalds 
443651086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
44371da177e4SLinus Torvalds {
4438cdc52faaSMarcel Holtmann 	int err;
4439cdc52faaSMarcel Holtmann 
44400d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
44411da177e4SLinus Torvalds 
44421da177e4SLinus Torvalds 	/* Time stamp */
4443a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
44441da177e4SLinus Torvalds 
4445cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
4446cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
4447cd82e61cSMarcel Holtmann 
4448cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
4449cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
4450470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
44511da177e4SLinus Torvalds 	}
44521da177e4SLinus Torvalds 
44531da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
44541da177e4SLinus Torvalds 	skb_orphan(skb);
44551da177e4SLinus Torvalds 
4456cdc52faaSMarcel Holtmann 	err = hdev->send(hdev, skb);
4457cdc52faaSMarcel Holtmann 	if (err < 0) {
4458cdc52faaSMarcel Holtmann 		BT_ERR("%s sending frame failed (%d)", hdev->name, err);
4459cdc52faaSMarcel Holtmann 		kfree_skb(skb);
4460cdc52faaSMarcel Holtmann 	}
44611da177e4SLinus Torvalds }
44621da177e4SLinus Torvalds 
44633119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev)
44643119ae95SJohan Hedberg {
44653119ae95SJohan Hedberg 	skb_queue_head_init(&req->cmd_q);
44663119ae95SJohan Hedberg 	req->hdev = hdev;
44675d73e034SAndre Guedes 	req->err = 0;
44683119ae95SJohan Hedberg }
44693119ae95SJohan Hedberg 
44703119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete)
44713119ae95SJohan Hedberg {
44723119ae95SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
44733119ae95SJohan Hedberg 	struct sk_buff *skb;
44743119ae95SJohan Hedberg 	unsigned long flags;
44753119ae95SJohan Hedberg 
44763119ae95SJohan Hedberg 	BT_DBG("length %u", skb_queue_len(&req->cmd_q));
44773119ae95SJohan Hedberg 
447849c922bbSStephen Hemminger 	/* If an error occurred during request building, remove all HCI
44795d73e034SAndre Guedes 	 * commands queued on the HCI request queue.
44805d73e034SAndre Guedes 	 */
44815d73e034SAndre Guedes 	if (req->err) {
44825d73e034SAndre Guedes 		skb_queue_purge(&req->cmd_q);
44835d73e034SAndre Guedes 		return req->err;
44845d73e034SAndre Guedes 	}
44855d73e034SAndre Guedes 
44863119ae95SJohan Hedberg 	/* Do not allow empty requests */
44873119ae95SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
4488382b0c39SAndre Guedes 		return -ENODATA;
44893119ae95SJohan Hedberg 
44903119ae95SJohan Hedberg 	skb = skb_peek_tail(&req->cmd_q);
44913119ae95SJohan Hedberg 	bt_cb(skb)->req.complete = complete;
44923119ae95SJohan Hedberg 
44933119ae95SJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
44943119ae95SJohan Hedberg 	skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q);
44953119ae95SJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
44963119ae95SJohan Hedberg 
44973119ae95SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
44983119ae95SJohan Hedberg 
44993119ae95SJohan Hedberg 	return 0;
45003119ae95SJohan Hedberg }
45013119ae95SJohan Hedberg 
4502899de765SMarcel Holtmann bool hci_req_pending(struct hci_dev *hdev)
4503899de765SMarcel Holtmann {
4504899de765SMarcel Holtmann 	return (hdev->req_status == HCI_REQ_PEND);
4505899de765SMarcel Holtmann }
4506899de765SMarcel Holtmann 
45071ca3a9d0SJohan Hedberg static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode,
450807dc93ddSJohan Hedberg 				       u32 plen, const void *param)
45091da177e4SLinus Torvalds {
45101da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
45111da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
45121da177e4SLinus Torvalds 	struct sk_buff *skb;
45131da177e4SLinus Torvalds 
45141da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
45151ca3a9d0SJohan Hedberg 	if (!skb)
45161ca3a9d0SJohan Hedberg 		return NULL;
45171da177e4SLinus Torvalds 
45181da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
4519a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
45201da177e4SLinus Torvalds 	hdr->plen   = plen;
45211da177e4SLinus Torvalds 
45221da177e4SLinus Torvalds 	if (plen)
45231da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
45241da177e4SLinus Torvalds 
45251da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
45261da177e4SLinus Torvalds 
45270d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
452843e73e4eSMarcel Holtmann 	bt_cb(skb)->opcode = opcode;
4529c78ae283SMarcel Holtmann 
45301ca3a9d0SJohan Hedberg 	return skb;
45311ca3a9d0SJohan Hedberg }
45321ca3a9d0SJohan Hedberg 
45331ca3a9d0SJohan Hedberg /* Send HCI command */
453407dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
453507dc93ddSJohan Hedberg 		 const void *param)
45361ca3a9d0SJohan Hedberg {
45371ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
45381ca3a9d0SJohan Hedberg 
45391ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
45401ca3a9d0SJohan Hedberg 
45411ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
45421ca3a9d0SJohan Hedberg 	if (!skb) {
45431ca3a9d0SJohan Hedberg 		BT_ERR("%s no memory for command", hdev->name);
45441ca3a9d0SJohan Hedberg 		return -ENOMEM;
45451ca3a9d0SJohan Hedberg 	}
45461ca3a9d0SJohan Hedberg 
454749c922bbSStephen Hemminger 	/* Stand-alone HCI commands must be flagged as
454811714b3dSJohan Hedberg 	 * single-command requests.
454911714b3dSJohan Hedberg 	 */
455011714b3dSJohan Hedberg 	bt_cb(skb)->req.start = true;
455111714b3dSJohan Hedberg 
45521da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
4553c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
45541da177e4SLinus Torvalds 
45551da177e4SLinus Torvalds 	return 0;
45561da177e4SLinus Torvalds }
45571da177e4SLinus Torvalds 
455871c76a17SJohan Hedberg /* Queue a command to an asynchronous HCI request */
455907dc93ddSJohan Hedberg void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen,
456007dc93ddSJohan Hedberg 		    const void *param, u8 event)
456171c76a17SJohan Hedberg {
456271c76a17SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
456371c76a17SJohan Hedberg 	struct sk_buff *skb;
456471c76a17SJohan Hedberg 
456571c76a17SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
456671c76a17SJohan Hedberg 
456749c922bbSStephen Hemminger 	/* If an error occurred during request building, there is no point in
456834739c1eSAndre Guedes 	 * queueing the HCI command. We can simply return.
456934739c1eSAndre Guedes 	 */
457034739c1eSAndre Guedes 	if (req->err)
457134739c1eSAndre Guedes 		return;
457234739c1eSAndre Guedes 
457371c76a17SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
457471c76a17SJohan Hedberg 	if (!skb) {
45755d73e034SAndre Guedes 		BT_ERR("%s no memory for command (opcode 0x%4.4x)",
45765d73e034SAndre Guedes 		       hdev->name, opcode);
45775d73e034SAndre Guedes 		req->err = -ENOMEM;
4578e348fe6bSAndre Guedes 		return;
457971c76a17SJohan Hedberg 	}
458071c76a17SJohan Hedberg 
458171c76a17SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
458271c76a17SJohan Hedberg 		bt_cb(skb)->req.start = true;
458371c76a17SJohan Hedberg 
458402350a72SJohan Hedberg 	bt_cb(skb)->req.event = event;
458502350a72SJohan Hedberg 
458671c76a17SJohan Hedberg 	skb_queue_tail(&req->cmd_q, skb);
458771c76a17SJohan Hedberg }
458871c76a17SJohan Hedberg 
458907dc93ddSJohan Hedberg void hci_req_add(struct hci_request *req, u16 opcode, u32 plen,
459007dc93ddSJohan Hedberg 		 const void *param)
459102350a72SJohan Hedberg {
459202350a72SJohan Hedberg 	hci_req_add_ev(req, opcode, plen, param, 0);
459302350a72SJohan Hedberg }
459402350a72SJohan Hedberg 
45951da177e4SLinus Torvalds /* Get data from the previously sent command */
4596a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
45971da177e4SLinus Torvalds {
45981da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
45991da177e4SLinus Torvalds 
46001da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
46011da177e4SLinus Torvalds 		return NULL;
46021da177e4SLinus Torvalds 
46031da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
46041da177e4SLinus Torvalds 
4605a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
46061da177e4SLinus Torvalds 		return NULL;
46071da177e4SLinus Torvalds 
4608f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
46091da177e4SLinus Torvalds 
46101da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
46111da177e4SLinus Torvalds }
46121da177e4SLinus Torvalds 
46131da177e4SLinus Torvalds /* Send ACL data */
46141da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
46151da177e4SLinus Torvalds {
46161da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
46171da177e4SLinus Torvalds 	int len = skb->len;
46181da177e4SLinus Torvalds 
4619badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
4620badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
46219c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
4622aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
4623aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
46241da177e4SLinus Torvalds }
46251da177e4SLinus Torvalds 
4626ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
462773d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
46281da177e4SLinus Torvalds {
4629ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
46301da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
46311da177e4SLinus Torvalds 	struct sk_buff *list;
46321da177e4SLinus Torvalds 
4633087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
4634087bfd99SGustavo Padovan 	skb->data_len = 0;
4635087bfd99SGustavo Padovan 
4636087bfd99SGustavo Padovan 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
4637204a6e54SAndrei Emeltchenko 
4638204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
4639204a6e54SAndrei Emeltchenko 	case HCI_BREDR:
4640087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
4641204a6e54SAndrei Emeltchenko 		break;
4642204a6e54SAndrei Emeltchenko 	case HCI_AMP:
4643204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
4644204a6e54SAndrei Emeltchenko 		break;
4645204a6e54SAndrei Emeltchenko 	default:
4646204a6e54SAndrei Emeltchenko 		BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
4647204a6e54SAndrei Emeltchenko 		return;
4648204a6e54SAndrei Emeltchenko 	}
4649087bfd99SGustavo Padovan 
465070f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
465170f23020SAndrei Emeltchenko 	if (!list) {
46521da177e4SLinus Torvalds 		/* Non fragmented */
46531da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
46541da177e4SLinus Torvalds 
465573d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
46561da177e4SLinus Torvalds 	} else {
46571da177e4SLinus Torvalds 		/* Fragmented */
46581da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
46591da177e4SLinus Torvalds 
46601da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
46611da177e4SLinus Torvalds 
46629cfd5a23SJukka Rissanen 		/* Queue all fragments atomically. We need to use spin_lock_bh
46639cfd5a23SJukka Rissanen 		 * here because of 6LoWPAN links, as there this function is
46649cfd5a23SJukka Rissanen 		 * called from softirq and using normal spin lock could cause
46659cfd5a23SJukka Rissanen 		 * deadlocks.
46669cfd5a23SJukka Rissanen 		 */
46679cfd5a23SJukka Rissanen 		spin_lock_bh(&queue->lock);
46681da177e4SLinus Torvalds 
466973d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
4670e702112fSAndrei Emeltchenko 
4671e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
4672e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
46731da177e4SLinus Torvalds 		do {
46741da177e4SLinus Torvalds 			skb = list; list = list->next;
46751da177e4SLinus Torvalds 
46760d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
4677e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
46781da177e4SLinus Torvalds 
46791da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
46801da177e4SLinus Torvalds 
468173d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
46821da177e4SLinus Torvalds 		} while (list);
46831da177e4SLinus Torvalds 
46849cfd5a23SJukka Rissanen 		spin_unlock_bh(&queue->lock);
46851da177e4SLinus Torvalds 	}
468673d80debSLuiz Augusto von Dentz }
468773d80debSLuiz Augusto von Dentz 
468873d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
468973d80debSLuiz Augusto von Dentz {
4690ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
469173d80debSLuiz Augusto von Dentz 
4692f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
469373d80debSLuiz Augusto von Dentz 
4694ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
46951da177e4SLinus Torvalds 
46963eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
46971da177e4SLinus Torvalds }
46981da177e4SLinus Torvalds 
46991da177e4SLinus Torvalds /* Send SCO data */
47000d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
47011da177e4SLinus Torvalds {
47021da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
47031da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
47041da177e4SLinus Torvalds 
47051da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
47061da177e4SLinus Torvalds 
4707aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
47081da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
47091da177e4SLinus Torvalds 
4710badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
4711badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
47129c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
47131da177e4SLinus Torvalds 
47140d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
4715c78ae283SMarcel Holtmann 
47161da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
47173eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
47181da177e4SLinus Torvalds }
47191da177e4SLinus Torvalds 
47201da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
47211da177e4SLinus Torvalds 
47221da177e4SLinus Torvalds /* HCI Connection scheduler */
47236039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
4724a8c5fb1aSGustavo Padovan 				     int *quote)
47251da177e4SLinus Torvalds {
47261da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
47278035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
4728abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
47291da177e4SLinus Torvalds 
47301da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
47311da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
4732bf4c6325SGustavo F. Padovan 
4733bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4734bf4c6325SGustavo F. Padovan 
4735bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
4736769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
47371da177e4SLinus Torvalds 			continue;
4738769be974SMarcel Holtmann 
4739769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
4740769be974SMarcel Holtmann 			continue;
4741769be974SMarcel Holtmann 
47421da177e4SLinus Torvalds 		num++;
47431da177e4SLinus Torvalds 
47441da177e4SLinus Torvalds 		if (c->sent < min) {
47451da177e4SLinus Torvalds 			min  = c->sent;
47461da177e4SLinus Torvalds 			conn = c;
47471da177e4SLinus Torvalds 		}
474852087a79SLuiz Augusto von Dentz 
474952087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
475052087a79SLuiz Augusto von Dentz 			break;
47511da177e4SLinus Torvalds 	}
47521da177e4SLinus Torvalds 
4753bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4754bf4c6325SGustavo F. Padovan 
47551da177e4SLinus Torvalds 	if (conn) {
47566ed58ec5SVille Tervo 		int cnt, q;
47576ed58ec5SVille Tervo 
47586ed58ec5SVille Tervo 		switch (conn->type) {
47596ed58ec5SVille Tervo 		case ACL_LINK:
47606ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
47616ed58ec5SVille Tervo 			break;
47626ed58ec5SVille Tervo 		case SCO_LINK:
47636ed58ec5SVille Tervo 		case ESCO_LINK:
47646ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
47656ed58ec5SVille Tervo 			break;
47666ed58ec5SVille Tervo 		case LE_LINK:
47676ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
47686ed58ec5SVille Tervo 			break;
47696ed58ec5SVille Tervo 		default:
47706ed58ec5SVille Tervo 			cnt = 0;
47716ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
47726ed58ec5SVille Tervo 		}
47736ed58ec5SVille Tervo 
47746ed58ec5SVille Tervo 		q = cnt / num;
47751da177e4SLinus Torvalds 		*quote = q ? q : 1;
47761da177e4SLinus Torvalds 	} else
47771da177e4SLinus Torvalds 		*quote = 0;
47781da177e4SLinus Torvalds 
47791da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
47801da177e4SLinus Torvalds 	return conn;
47811da177e4SLinus Torvalds }
47821da177e4SLinus Torvalds 
47836039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
47841da177e4SLinus Torvalds {
47851da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
47861da177e4SLinus Torvalds 	struct hci_conn *c;
47871da177e4SLinus Torvalds 
4788bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
47891da177e4SLinus Torvalds 
4790bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4791bf4c6325SGustavo F. Padovan 
47921da177e4SLinus Torvalds 	/* Kill stalled connections */
4793bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
4794bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
47956ed93dc6SAndrei Emeltchenko 			BT_ERR("%s killing stalled connection %pMR",
47966ed93dc6SAndrei Emeltchenko 			       hdev->name, &c->dst);
4797bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
47981da177e4SLinus Torvalds 		}
47991da177e4SLinus Torvalds 	}
4800bf4c6325SGustavo F. Padovan 
4801bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
48021da177e4SLinus Torvalds }
48031da177e4SLinus Torvalds 
48046039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
480573d80debSLuiz Augusto von Dentz 				      int *quote)
480673d80debSLuiz Augusto von Dentz {
480773d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
480873d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
4809abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
481073d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
481173d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
481273d80debSLuiz Augusto von Dentz 
481373d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
481473d80debSLuiz Augusto von Dentz 
4815bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4816bf4c6325SGustavo F. Padovan 
4817bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
481873d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
481973d80debSLuiz Augusto von Dentz 
482073d80debSLuiz Augusto von Dentz 		if (conn->type != type)
482173d80debSLuiz Augusto von Dentz 			continue;
482273d80debSLuiz Augusto von Dentz 
482373d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
482473d80debSLuiz Augusto von Dentz 			continue;
482573d80debSLuiz Augusto von Dentz 
482673d80debSLuiz Augusto von Dentz 		conn_num++;
482773d80debSLuiz Augusto von Dentz 
48288192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
482973d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
483073d80debSLuiz Augusto von Dentz 
483173d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
483273d80debSLuiz Augusto von Dentz 				continue;
483373d80debSLuiz Augusto von Dentz 
483473d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
483573d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
483673d80debSLuiz Augusto von Dentz 				continue;
483773d80debSLuiz Augusto von Dentz 
483873d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
483973d80debSLuiz Augusto von Dentz 				num = 0;
484073d80debSLuiz Augusto von Dentz 				min = ~0;
484173d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
484273d80debSLuiz Augusto von Dentz 			}
484373d80debSLuiz Augusto von Dentz 
484473d80debSLuiz Augusto von Dentz 			num++;
484573d80debSLuiz Augusto von Dentz 
484673d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
484773d80debSLuiz Augusto von Dentz 				min  = conn->sent;
484873d80debSLuiz Augusto von Dentz 				chan = tmp;
484973d80debSLuiz Augusto von Dentz 			}
485073d80debSLuiz Augusto von Dentz 		}
485173d80debSLuiz Augusto von Dentz 
485273d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
485373d80debSLuiz Augusto von Dentz 			break;
485473d80debSLuiz Augusto von Dentz 	}
485573d80debSLuiz Augusto von Dentz 
4856bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4857bf4c6325SGustavo F. Padovan 
485873d80debSLuiz Augusto von Dentz 	if (!chan)
485973d80debSLuiz Augusto von Dentz 		return NULL;
486073d80debSLuiz Augusto von Dentz 
486173d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
486273d80debSLuiz Augusto von Dentz 	case ACL_LINK:
486373d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
486473d80debSLuiz Augusto von Dentz 		break;
4865bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
4866bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
4867bd1eb66bSAndrei Emeltchenko 		break;
486873d80debSLuiz Augusto von Dentz 	case SCO_LINK:
486973d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
487073d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
487173d80debSLuiz Augusto von Dentz 		break;
487273d80debSLuiz Augusto von Dentz 	case LE_LINK:
487373d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
487473d80debSLuiz Augusto von Dentz 		break;
487573d80debSLuiz Augusto von Dentz 	default:
487673d80debSLuiz Augusto von Dentz 		cnt = 0;
487773d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
487873d80debSLuiz Augusto von Dentz 	}
487973d80debSLuiz Augusto von Dentz 
488073d80debSLuiz Augusto von Dentz 	q = cnt / num;
488173d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
488273d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
488373d80debSLuiz Augusto von Dentz 	return chan;
488473d80debSLuiz Augusto von Dentz }
488573d80debSLuiz Augusto von Dentz 
488602b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
488702b20f0bSLuiz Augusto von Dentz {
488802b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
488902b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
489002b20f0bSLuiz Augusto von Dentz 	int num = 0;
489102b20f0bSLuiz Augusto von Dentz 
489202b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
489302b20f0bSLuiz Augusto von Dentz 
4894bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4895bf4c6325SGustavo F. Padovan 
4896bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
489702b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
489802b20f0bSLuiz Augusto von Dentz 
489902b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
490002b20f0bSLuiz Augusto von Dentz 			continue;
490102b20f0bSLuiz Augusto von Dentz 
490202b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
490302b20f0bSLuiz Augusto von Dentz 			continue;
490402b20f0bSLuiz Augusto von Dentz 
490502b20f0bSLuiz Augusto von Dentz 		num++;
490602b20f0bSLuiz Augusto von Dentz 
49078192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
490802b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
490902b20f0bSLuiz Augusto von Dentz 
491002b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
491102b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
491202b20f0bSLuiz Augusto von Dentz 				continue;
491302b20f0bSLuiz Augusto von Dentz 			}
491402b20f0bSLuiz Augusto von Dentz 
491502b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
491602b20f0bSLuiz Augusto von Dentz 				continue;
491702b20f0bSLuiz Augusto von Dentz 
491802b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
491902b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
492002b20f0bSLuiz Augusto von Dentz 				continue;
492102b20f0bSLuiz Augusto von Dentz 
492202b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
492302b20f0bSLuiz Augusto von Dentz 
492402b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
492502b20f0bSLuiz Augusto von Dentz 			       skb->priority);
492602b20f0bSLuiz Augusto von Dentz 		}
492702b20f0bSLuiz Augusto von Dentz 
492802b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
492902b20f0bSLuiz Augusto von Dentz 			break;
493002b20f0bSLuiz Augusto von Dentz 	}
4931bf4c6325SGustavo F. Padovan 
4932bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4933bf4c6325SGustavo F. Padovan 
493402b20f0bSLuiz Augusto von Dentz }
493502b20f0bSLuiz Augusto von Dentz 
4936b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
4937b71d385aSAndrei Emeltchenko {
4938b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
4939b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
4940b71d385aSAndrei Emeltchenko }
4941b71d385aSAndrei Emeltchenko 
49426039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
49431da177e4SLinus Torvalds {
49444a964404SMarcel Holtmann 	if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
49451da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
49461da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
494763d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
49485f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
4949bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
49501da177e4SLinus Torvalds 	}
495163d2bc1bSAndrei Emeltchenko }
49521da177e4SLinus Torvalds 
49536039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
495463d2bc1bSAndrei Emeltchenko {
495563d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
495663d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
495763d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
495863d2bc1bSAndrei Emeltchenko 	int quote;
495963d2bc1bSAndrei Emeltchenko 
496063d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
496104837f64SMarcel Holtmann 
496273d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
496373d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
4964ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
4965ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
496673d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
496773d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
496873d80debSLuiz Augusto von Dentz 
4969ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
4970ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
4971ec1cce24SLuiz Augusto von Dentz 				break;
4972ec1cce24SLuiz Augusto von Dentz 
4973ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
4974ec1cce24SLuiz Augusto von Dentz 
497573d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
497673d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
497704837f64SMarcel Holtmann 
497857d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
49791da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
49801da177e4SLinus Torvalds 
49811da177e4SLinus Torvalds 			hdev->acl_cnt--;
498273d80debSLuiz Augusto von Dentz 			chan->sent++;
498373d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
49841da177e4SLinus Torvalds 		}
49851da177e4SLinus Torvalds 	}
498602b20f0bSLuiz Augusto von Dentz 
498702b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
498802b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
49891da177e4SLinus Torvalds }
49901da177e4SLinus Torvalds 
49916039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
4992b71d385aSAndrei Emeltchenko {
499363d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
4994b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
4995b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
4996b71d385aSAndrei Emeltchenko 	int quote;
4997bd1eb66bSAndrei Emeltchenko 	u8 type;
4998b71d385aSAndrei Emeltchenko 
499963d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
5000b71d385aSAndrei Emeltchenko 
5001bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
5002bd1eb66bSAndrei Emeltchenko 
5003bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
5004bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
5005bd1eb66bSAndrei Emeltchenko 	else
5006bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
5007bd1eb66bSAndrei Emeltchenko 
5008b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
5009bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
5010b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
5011b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
5012b71d385aSAndrei Emeltchenko 			int blocks;
5013b71d385aSAndrei Emeltchenko 
5014b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
5015b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
5016b71d385aSAndrei Emeltchenko 
5017b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
5018b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
5019b71d385aSAndrei Emeltchenko 				break;
5020b71d385aSAndrei Emeltchenko 
5021b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
5022b71d385aSAndrei Emeltchenko 
5023b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
5024b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
5025b71d385aSAndrei Emeltchenko 				return;
5026b71d385aSAndrei Emeltchenko 
5027b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
5028b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
5029b71d385aSAndrei Emeltchenko 
503057d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
5031b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
5032b71d385aSAndrei Emeltchenko 
5033b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
5034b71d385aSAndrei Emeltchenko 			quote -= blocks;
5035b71d385aSAndrei Emeltchenko 
5036b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
5037b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
5038b71d385aSAndrei Emeltchenko 		}
5039b71d385aSAndrei Emeltchenko 	}
5040b71d385aSAndrei Emeltchenko 
5041b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
5042bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
5043b71d385aSAndrei Emeltchenko }
5044b71d385aSAndrei Emeltchenko 
50456039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
5046b71d385aSAndrei Emeltchenko {
5047b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
5048b71d385aSAndrei Emeltchenko 
5049bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
5050bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR)
5051bd1eb66bSAndrei Emeltchenko 		return;
5052bd1eb66bSAndrei Emeltchenko 
5053bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
5054bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
5055b71d385aSAndrei Emeltchenko 		return;
5056b71d385aSAndrei Emeltchenko 
5057b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
5058b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
5059b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
5060b71d385aSAndrei Emeltchenko 		break;
5061b71d385aSAndrei Emeltchenko 
5062b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
5063b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
5064b71d385aSAndrei Emeltchenko 		break;
5065b71d385aSAndrei Emeltchenko 	}
5066b71d385aSAndrei Emeltchenko }
5067b71d385aSAndrei Emeltchenko 
50681da177e4SLinus Torvalds /* Schedule SCO */
50696039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev)
50701da177e4SLinus Torvalds {
50711da177e4SLinus Torvalds 	struct hci_conn *conn;
50721da177e4SLinus Torvalds 	struct sk_buff *skb;
50731da177e4SLinus Torvalds 	int quote;
50741da177e4SLinus Torvalds 
50751da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
50761da177e4SLinus Torvalds 
507752087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
507852087a79SLuiz Augusto von Dentz 		return;
507952087a79SLuiz Augusto von Dentz 
50801da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
50811da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
50821da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
508357d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
50841da177e4SLinus Torvalds 
50851da177e4SLinus Torvalds 			conn->sent++;
50861da177e4SLinus Torvalds 			if (conn->sent == ~0)
50871da177e4SLinus Torvalds 				conn->sent = 0;
50881da177e4SLinus Torvalds 		}
50891da177e4SLinus Torvalds 	}
50901da177e4SLinus Torvalds }
50911da177e4SLinus Torvalds 
50926039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev)
5093b6a0dc82SMarcel Holtmann {
5094b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
5095b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
5096b6a0dc82SMarcel Holtmann 	int quote;
5097b6a0dc82SMarcel Holtmann 
5098b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
5099b6a0dc82SMarcel Holtmann 
510052087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
510152087a79SLuiz Augusto von Dentz 		return;
510252087a79SLuiz Augusto von Dentz 
51038fc9ced3SGustavo Padovan 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
51048fc9ced3SGustavo Padovan 						     &quote))) {
5105b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
5106b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
510757d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
5108b6a0dc82SMarcel Holtmann 
5109b6a0dc82SMarcel Holtmann 			conn->sent++;
5110b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
5111b6a0dc82SMarcel Holtmann 				conn->sent = 0;
5112b6a0dc82SMarcel Holtmann 		}
5113b6a0dc82SMarcel Holtmann 	}
5114b6a0dc82SMarcel Holtmann }
5115b6a0dc82SMarcel Holtmann 
51166039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
51176ed58ec5SVille Tervo {
511873d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
51196ed58ec5SVille Tervo 	struct sk_buff *skb;
512002b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
51216ed58ec5SVille Tervo 
51226ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
51236ed58ec5SVille Tervo 
512452087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
512552087a79SLuiz Augusto von Dentz 		return;
512652087a79SLuiz Augusto von Dentz 
51274a964404SMarcel Holtmann 	if (!test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
51286ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
51296ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
5130bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
51316ed58ec5SVille Tervo 		    time_after(jiffies, hdev->le_last_tx + HZ * 45))
5132bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
51336ed58ec5SVille Tervo 	}
51346ed58ec5SVille Tervo 
51356ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
513602b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
513773d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
5138ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
5139ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
514073d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
514173d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
51426ed58ec5SVille Tervo 
5143ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
5144ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
5145ec1cce24SLuiz Augusto von Dentz 				break;
5146ec1cce24SLuiz Augusto von Dentz 
5147ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
5148ec1cce24SLuiz Augusto von Dentz 
514957d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
51506ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
51516ed58ec5SVille Tervo 
51526ed58ec5SVille Tervo 			cnt--;
515373d80debSLuiz Augusto von Dentz 			chan->sent++;
515473d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
51556ed58ec5SVille Tervo 		}
51566ed58ec5SVille Tervo 	}
515773d80debSLuiz Augusto von Dentz 
51586ed58ec5SVille Tervo 	if (hdev->le_pkts)
51596ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
51606ed58ec5SVille Tervo 	else
51616ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
516202b20f0bSLuiz Augusto von Dentz 
516302b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
516402b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
51656ed58ec5SVille Tervo }
51666ed58ec5SVille Tervo 
51673eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
51681da177e4SLinus Torvalds {
51693eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
51701da177e4SLinus Torvalds 	struct sk_buff *skb;
51711da177e4SLinus Torvalds 
51726ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
51736ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
51741da177e4SLinus Torvalds 
517552de599eSMarcel Holtmann 	if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
51761da177e4SLinus Torvalds 		/* Schedule queues and send stuff to HCI driver */
51771da177e4SLinus Torvalds 		hci_sched_acl(hdev);
51781da177e4SLinus Torvalds 		hci_sched_sco(hdev);
5179b6a0dc82SMarcel Holtmann 		hci_sched_esco(hdev);
51806ed58ec5SVille Tervo 		hci_sched_le(hdev);
518152de599eSMarcel Holtmann 	}
51826ed58ec5SVille Tervo 
51831da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
51841da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
518557d17d70SMarcel Holtmann 		hci_send_frame(hdev, skb);
51861da177e4SLinus Torvalds }
51871da177e4SLinus Torvalds 
518825985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
51891da177e4SLinus Torvalds 
51901da177e4SLinus Torvalds /* ACL data packet */
51916039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
51921da177e4SLinus Torvalds {
51931da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
51941da177e4SLinus Torvalds 	struct hci_conn *conn;
51951da177e4SLinus Torvalds 	__u16 handle, flags;
51961da177e4SLinus Torvalds 
51971da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
51981da177e4SLinus Torvalds 
51991da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
52001da177e4SLinus Torvalds 	flags  = hci_flags(handle);
52011da177e4SLinus Torvalds 	handle = hci_handle(handle);
52021da177e4SLinus Torvalds 
5203f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
5204a8c5fb1aSGustavo Padovan 	       handle, flags);
52051da177e4SLinus Torvalds 
52061da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
52071da177e4SLinus Torvalds 
52081da177e4SLinus Torvalds 	hci_dev_lock(hdev);
52091da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
52101da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
52111da177e4SLinus Torvalds 
52121da177e4SLinus Torvalds 	if (conn) {
521365983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
521404837f64SMarcel Holtmann 
52151da177e4SLinus Torvalds 		/* Send to upper protocol */
5216686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
52171da177e4SLinus Torvalds 		return;
52181da177e4SLinus Torvalds 	} else {
52191da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
52201da177e4SLinus Torvalds 		       hdev->name, handle);
52211da177e4SLinus Torvalds 	}
52221da177e4SLinus Torvalds 
52231da177e4SLinus Torvalds 	kfree_skb(skb);
52241da177e4SLinus Torvalds }
52251da177e4SLinus Torvalds 
52261da177e4SLinus Torvalds /* SCO data packet */
52276039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
52281da177e4SLinus Torvalds {
52291da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
52301da177e4SLinus Torvalds 	struct hci_conn *conn;
52311da177e4SLinus Torvalds 	__u16 handle;
52321da177e4SLinus Torvalds 
52331da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
52341da177e4SLinus Torvalds 
52351da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
52361da177e4SLinus Torvalds 
5237f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle);
52381da177e4SLinus Torvalds 
52391da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
52401da177e4SLinus Torvalds 
52411da177e4SLinus Torvalds 	hci_dev_lock(hdev);
52421da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
52431da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
52441da177e4SLinus Torvalds 
52451da177e4SLinus Torvalds 	if (conn) {
52461da177e4SLinus Torvalds 		/* Send to upper protocol */
5247686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
52481da177e4SLinus Torvalds 		return;
52491da177e4SLinus Torvalds 	} else {
52501da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
52511da177e4SLinus Torvalds 		       hdev->name, handle);
52521da177e4SLinus Torvalds 	}
52531da177e4SLinus Torvalds 
52541da177e4SLinus Torvalds 	kfree_skb(skb);
52551da177e4SLinus Torvalds }
52561da177e4SLinus Torvalds 
52579238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
52589238f36aSJohan Hedberg {
52599238f36aSJohan Hedberg 	struct sk_buff *skb;
52609238f36aSJohan Hedberg 
52619238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
52629238f36aSJohan Hedberg 	if (!skb)
52639238f36aSJohan Hedberg 		return true;
52649238f36aSJohan Hedberg 
52659238f36aSJohan Hedberg 	return bt_cb(skb)->req.start;
52669238f36aSJohan Hedberg }
52679238f36aSJohan Hedberg 
526842c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
526942c6b129SJohan Hedberg {
527042c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
527142c6b129SJohan Hedberg 	struct sk_buff *skb;
527242c6b129SJohan Hedberg 	u16 opcode;
527342c6b129SJohan Hedberg 
527442c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
527542c6b129SJohan Hedberg 		return;
527642c6b129SJohan Hedberg 
527742c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
527842c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
527942c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
528042c6b129SJohan Hedberg 		return;
528142c6b129SJohan Hedberg 
528242c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
528342c6b129SJohan Hedberg 	if (!skb)
528442c6b129SJohan Hedberg 		return;
528542c6b129SJohan Hedberg 
528642c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
528742c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
528842c6b129SJohan Hedberg }
528942c6b129SJohan Hedberg 
52909238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status)
52919238f36aSJohan Hedberg {
52929238f36aSJohan Hedberg 	hci_req_complete_t req_complete = NULL;
52939238f36aSJohan Hedberg 	struct sk_buff *skb;
52949238f36aSJohan Hedberg 	unsigned long flags;
52959238f36aSJohan Hedberg 
52969238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
52979238f36aSJohan Hedberg 
529842c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
529942c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
53009238f36aSJohan Hedberg 	 */
530142c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
530242c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
530342c6b129SJohan Hedberg 		 * reset complete event during init and any pending
530442c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
530542c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
530642c6b129SJohan Hedberg 		 * command.
530742c6b129SJohan Hedberg 		 */
530842c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
530942c6b129SJohan Hedberg 			hci_resend_last(hdev);
531042c6b129SJohan Hedberg 
53119238f36aSJohan Hedberg 		return;
531242c6b129SJohan Hedberg 	}
53139238f36aSJohan Hedberg 
53149238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
53159238f36aSJohan Hedberg 	 * this request the request is not yet complete.
53169238f36aSJohan Hedberg 	 */
53179238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
53189238f36aSJohan Hedberg 		return;
53199238f36aSJohan Hedberg 
53209238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
53219238f36aSJohan Hedberg 	 * callback would be found in hdev->sent_cmd instead of the
53229238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
53239238f36aSJohan Hedberg 	 */
53249238f36aSJohan Hedberg 	if (hdev->sent_cmd) {
53259238f36aSJohan Hedberg 		req_complete = bt_cb(hdev->sent_cmd)->req.complete;
532653e21fbcSJohan Hedberg 
532753e21fbcSJohan Hedberg 		if (req_complete) {
532853e21fbcSJohan Hedberg 			/* We must set the complete callback to NULL to
532953e21fbcSJohan Hedberg 			 * avoid calling the callback more than once if
533053e21fbcSJohan Hedberg 			 * this function gets called again.
533153e21fbcSJohan Hedberg 			 */
533253e21fbcSJohan Hedberg 			bt_cb(hdev->sent_cmd)->req.complete = NULL;
533353e21fbcSJohan Hedberg 
53349238f36aSJohan Hedberg 			goto call_complete;
53359238f36aSJohan Hedberg 		}
533653e21fbcSJohan Hedberg 	}
53379238f36aSJohan Hedberg 
53389238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
53399238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
53409238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
53419238f36aSJohan Hedberg 		if (bt_cb(skb)->req.start) {
53429238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
53439238f36aSJohan Hedberg 			break;
53449238f36aSJohan Hedberg 		}
53459238f36aSJohan Hedberg 
53469238f36aSJohan Hedberg 		req_complete = bt_cb(skb)->req.complete;
53479238f36aSJohan Hedberg 		kfree_skb(skb);
53489238f36aSJohan Hedberg 	}
53499238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
53509238f36aSJohan Hedberg 
53519238f36aSJohan Hedberg call_complete:
53529238f36aSJohan Hedberg 	if (req_complete)
53539238f36aSJohan Hedberg 		req_complete(hdev, status);
53549238f36aSJohan Hedberg }
53559238f36aSJohan Hedberg 
5356b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
53571da177e4SLinus Torvalds {
5358b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
53591da177e4SLinus Torvalds 	struct sk_buff *skb;
53601da177e4SLinus Torvalds 
53611da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
53621da177e4SLinus Torvalds 
53631da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
5364cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
5365cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
5366cd82e61cSMarcel Holtmann 
53671da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
53681da177e4SLinus Torvalds 			/* Send copy to the sockets */
5369470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
53701da177e4SLinus Torvalds 		}
53711da177e4SLinus Torvalds 
5372fee746b0SMarcel Holtmann 		if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
53731da177e4SLinus Torvalds 			kfree_skb(skb);
53741da177e4SLinus Torvalds 			continue;
53751da177e4SLinus Torvalds 		}
53761da177e4SLinus Torvalds 
53771da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
53781da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
53790d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
53801da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
53811da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
53821da177e4SLinus Torvalds 				kfree_skb(skb);
53831da177e4SLinus Torvalds 				continue;
53843ff50b79SStephen Hemminger 			}
53851da177e4SLinus Torvalds 		}
53861da177e4SLinus Torvalds 
53871da177e4SLinus Torvalds 		/* Process frame */
53880d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
53891da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
5390b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
53911da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
53921da177e4SLinus Torvalds 			break;
53931da177e4SLinus Torvalds 
53941da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
53951da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
53961da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
53971da177e4SLinus Torvalds 			break;
53981da177e4SLinus Torvalds 
53991da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
54001da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
54011da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
54021da177e4SLinus Torvalds 			break;
54031da177e4SLinus Torvalds 
54041da177e4SLinus Torvalds 		default:
54051da177e4SLinus Torvalds 			kfree_skb(skb);
54061da177e4SLinus Torvalds 			break;
54071da177e4SLinus Torvalds 		}
54081da177e4SLinus Torvalds 	}
54091da177e4SLinus Torvalds }
54101da177e4SLinus Torvalds 
5411c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
54121da177e4SLinus Torvalds {
5413c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
54141da177e4SLinus Torvalds 	struct sk_buff *skb;
54151da177e4SLinus Torvalds 
54162104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
54172104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
54181da177e4SLinus Torvalds 
54191da177e4SLinus Torvalds 	/* Send queued commands */
54205a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
54215a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
54225a08ecceSAndrei Emeltchenko 		if (!skb)
54235a08ecceSAndrei Emeltchenko 			return;
54245a08ecceSAndrei Emeltchenko 
54251da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
54261da177e4SLinus Torvalds 
5427a675d7f1SMarcel Holtmann 		hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
542870f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
54291da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
543057d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
54317bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
543265cc2b49SMarcel Holtmann 				cancel_delayed_work(&hdev->cmd_timer);
54337bdb8a5cSSzymon Janc 			else
543465cc2b49SMarcel Holtmann 				schedule_delayed_work(&hdev->cmd_timer,
543565cc2b49SMarcel Holtmann 						      HCI_CMD_TIMEOUT);
54361da177e4SLinus Torvalds 		} else {
54371da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
5438c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
54391da177e4SLinus Torvalds 		}
54401da177e4SLinus Torvalds 	}
54411da177e4SLinus Torvalds }
5442b1efcc28SAndre Guedes 
5443b1efcc28SAndre Guedes void hci_req_add_le_scan_disable(struct hci_request *req)
5444b1efcc28SAndre Guedes {
5445b1efcc28SAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
5446b1efcc28SAndre Guedes 
5447b1efcc28SAndre Guedes 	memset(&cp, 0, sizeof(cp));
5448b1efcc28SAndre Guedes 	cp.enable = LE_SCAN_DISABLE;
5449b1efcc28SAndre Guedes 	hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
5450b1efcc28SAndre Guedes }
5451a4790dbdSAndre Guedes 
54528540f6c0SMarcel Holtmann static void add_to_white_list(struct hci_request *req,
54538540f6c0SMarcel Holtmann 			      struct hci_conn_params *params)
54548540f6c0SMarcel Holtmann {
54558540f6c0SMarcel Holtmann 	struct hci_cp_le_add_to_white_list cp;
54568540f6c0SMarcel Holtmann 
54578540f6c0SMarcel Holtmann 	cp.bdaddr_type = params->addr_type;
54588540f6c0SMarcel Holtmann 	bacpy(&cp.bdaddr, &params->addr);
54598540f6c0SMarcel Holtmann 
54608540f6c0SMarcel Holtmann 	hci_req_add(req, HCI_OP_LE_ADD_TO_WHITE_LIST, sizeof(cp), &cp);
54618540f6c0SMarcel Holtmann }
54628540f6c0SMarcel Holtmann 
54638540f6c0SMarcel Holtmann static u8 update_white_list(struct hci_request *req)
54648540f6c0SMarcel Holtmann {
54658540f6c0SMarcel Holtmann 	struct hci_dev *hdev = req->hdev;
54668540f6c0SMarcel Holtmann 	struct hci_conn_params *params;
54678540f6c0SMarcel Holtmann 	struct bdaddr_list *b;
54688540f6c0SMarcel Holtmann 	uint8_t white_list_entries = 0;
54698540f6c0SMarcel Holtmann 
54708540f6c0SMarcel Holtmann 	/* Go through the current white list programmed into the
54718540f6c0SMarcel Holtmann 	 * controller one by one and check if that address is still
54728540f6c0SMarcel Holtmann 	 * in the list of pending connections or list of devices to
54738540f6c0SMarcel Holtmann 	 * report. If not present in either list, then queue the
54748540f6c0SMarcel Holtmann 	 * command to remove it from the controller.
54758540f6c0SMarcel Holtmann 	 */
54768540f6c0SMarcel Holtmann 	list_for_each_entry(b, &hdev->le_white_list, list) {
54778540f6c0SMarcel Holtmann 		struct hci_cp_le_del_from_white_list cp;
54788540f6c0SMarcel Holtmann 
54798540f6c0SMarcel Holtmann 		if (hci_pend_le_action_lookup(&hdev->pend_le_conns,
54808540f6c0SMarcel Holtmann 					      &b->bdaddr, b->bdaddr_type) ||
54818540f6c0SMarcel Holtmann 		    hci_pend_le_action_lookup(&hdev->pend_le_reports,
54828540f6c0SMarcel Holtmann 					      &b->bdaddr, b->bdaddr_type)) {
54838540f6c0SMarcel Holtmann 			white_list_entries++;
54848540f6c0SMarcel Holtmann 			continue;
54858540f6c0SMarcel Holtmann 		}
54868540f6c0SMarcel Holtmann 
54878540f6c0SMarcel Holtmann 		cp.bdaddr_type = b->bdaddr_type;
54888540f6c0SMarcel Holtmann 		bacpy(&cp.bdaddr, &b->bdaddr);
54898540f6c0SMarcel Holtmann 
54908540f6c0SMarcel Holtmann 		hci_req_add(req, HCI_OP_LE_DEL_FROM_WHITE_LIST,
54918540f6c0SMarcel Holtmann 			    sizeof(cp), &cp);
54928540f6c0SMarcel Holtmann 	}
54938540f6c0SMarcel Holtmann 
54948540f6c0SMarcel Holtmann 	/* Since all no longer valid white list entries have been
54958540f6c0SMarcel Holtmann 	 * removed, walk through the list of pending connections
54968540f6c0SMarcel Holtmann 	 * and ensure that any new device gets programmed into
54978540f6c0SMarcel Holtmann 	 * the controller.
54988540f6c0SMarcel Holtmann 	 *
54998540f6c0SMarcel Holtmann 	 * If the list of the devices is larger than the list of
55008540f6c0SMarcel Holtmann 	 * available white list entries in the controller, then
55018540f6c0SMarcel Holtmann 	 * just abort and return filer policy value to not use the
55028540f6c0SMarcel Holtmann 	 * white list.
55038540f6c0SMarcel Holtmann 	 */
55048540f6c0SMarcel Holtmann 	list_for_each_entry(params, &hdev->pend_le_conns, action) {
55058540f6c0SMarcel Holtmann 		if (hci_bdaddr_list_lookup(&hdev->le_white_list,
55068540f6c0SMarcel Holtmann 					   &params->addr, params->addr_type))
55078540f6c0SMarcel Holtmann 			continue;
55088540f6c0SMarcel Holtmann 
55098540f6c0SMarcel Holtmann 		if (white_list_entries >= hdev->le_white_list_size) {
55108540f6c0SMarcel Holtmann 			/* Select filter policy to accept all advertising */
55118540f6c0SMarcel Holtmann 			return 0x00;
55128540f6c0SMarcel Holtmann 		}
55138540f6c0SMarcel Holtmann 
551466d8e837SMarcel Holtmann 		if (hci_find_irk_by_addr(hdev, &params->addr,
551566d8e837SMarcel Holtmann 					 params->addr_type)) {
551666d8e837SMarcel Holtmann 			/* White list can not be used with RPAs */
551766d8e837SMarcel Holtmann 			return 0x00;
551866d8e837SMarcel Holtmann 		}
551966d8e837SMarcel Holtmann 
55208540f6c0SMarcel Holtmann 		white_list_entries++;
55218540f6c0SMarcel Holtmann 		add_to_white_list(req, params);
55228540f6c0SMarcel Holtmann 	}
55238540f6c0SMarcel Holtmann 
55248540f6c0SMarcel Holtmann 	/* After adding all new pending connections, walk through
55258540f6c0SMarcel Holtmann 	 * the list of pending reports and also add these to the
55268540f6c0SMarcel Holtmann 	 * white list if there is still space.
55278540f6c0SMarcel Holtmann 	 */
55288540f6c0SMarcel Holtmann 	list_for_each_entry(params, &hdev->pend_le_reports, action) {
55298540f6c0SMarcel Holtmann 		if (hci_bdaddr_list_lookup(&hdev->le_white_list,
55308540f6c0SMarcel Holtmann 					   &params->addr, params->addr_type))
55318540f6c0SMarcel Holtmann 			continue;
55328540f6c0SMarcel Holtmann 
55338540f6c0SMarcel Holtmann 		if (white_list_entries >= hdev->le_white_list_size) {
55348540f6c0SMarcel Holtmann 			/* Select filter policy to accept all advertising */
55358540f6c0SMarcel Holtmann 			return 0x00;
55368540f6c0SMarcel Holtmann 		}
55378540f6c0SMarcel Holtmann 
553866d8e837SMarcel Holtmann 		if (hci_find_irk_by_addr(hdev, &params->addr,
553966d8e837SMarcel Holtmann 					 params->addr_type)) {
554066d8e837SMarcel Holtmann 			/* White list can not be used with RPAs */
554166d8e837SMarcel Holtmann 			return 0x00;
554266d8e837SMarcel Holtmann 		}
554366d8e837SMarcel Holtmann 
55448540f6c0SMarcel Holtmann 		white_list_entries++;
55458540f6c0SMarcel Holtmann 		add_to_white_list(req, params);
55468540f6c0SMarcel Holtmann 	}
55478540f6c0SMarcel Holtmann 
55488540f6c0SMarcel Holtmann 	/* Select filter policy to use white list */
55498540f6c0SMarcel Holtmann 	return 0x01;
55508540f6c0SMarcel Holtmann }
55518540f6c0SMarcel Holtmann 
55528ef30fd3SAndre Guedes void hci_req_add_le_passive_scan(struct hci_request *req)
55538ef30fd3SAndre Guedes {
55548ef30fd3SAndre Guedes 	struct hci_cp_le_set_scan_param param_cp;
55558ef30fd3SAndre Guedes 	struct hci_cp_le_set_scan_enable enable_cp;
55568ef30fd3SAndre Guedes 	struct hci_dev *hdev = req->hdev;
55578ef30fd3SAndre Guedes 	u8 own_addr_type;
55588540f6c0SMarcel Holtmann 	u8 filter_policy;
55598ef30fd3SAndre Guedes 
55606ab535a7SMarcel Holtmann 	/* Set require_privacy to false since no SCAN_REQ are send
55616ab535a7SMarcel Holtmann 	 * during passive scanning. Not using an unresolvable address
55626ab535a7SMarcel Holtmann 	 * here is important so that peer devices using direct
55636ab535a7SMarcel Holtmann 	 * advertising with our address will be correctly reported
55646ab535a7SMarcel Holtmann 	 * by the controller.
55658ef30fd3SAndre Guedes 	 */
55666ab535a7SMarcel Holtmann 	if (hci_update_random_address(req, false, &own_addr_type))
55678ef30fd3SAndre Guedes 		return;
55688ef30fd3SAndre Guedes 
55698540f6c0SMarcel Holtmann 	/* Adding or removing entries from the white list must
55708540f6c0SMarcel Holtmann 	 * happen before enabling scanning. The controller does
55718540f6c0SMarcel Holtmann 	 * not allow white list modification while scanning.
55728540f6c0SMarcel Holtmann 	 */
55738540f6c0SMarcel Holtmann 	filter_policy = update_white_list(req);
55748540f6c0SMarcel Holtmann 
55758ef30fd3SAndre Guedes 	memset(&param_cp, 0, sizeof(param_cp));
55768ef30fd3SAndre Guedes 	param_cp.type = LE_SCAN_PASSIVE;
55778ef30fd3SAndre Guedes 	param_cp.interval = cpu_to_le16(hdev->le_scan_interval);
55788ef30fd3SAndre Guedes 	param_cp.window = cpu_to_le16(hdev->le_scan_window);
55798ef30fd3SAndre Guedes 	param_cp.own_address_type = own_addr_type;
55808540f6c0SMarcel Holtmann 	param_cp.filter_policy = filter_policy;
55818ef30fd3SAndre Guedes 	hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp),
55828ef30fd3SAndre Guedes 		    &param_cp);
55838ef30fd3SAndre Guedes 
55848ef30fd3SAndre Guedes 	memset(&enable_cp, 0, sizeof(enable_cp));
55858ef30fd3SAndre Guedes 	enable_cp.enable = LE_SCAN_ENABLE;
55864340a124SAndre Guedes 	enable_cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
55878ef30fd3SAndre Guedes 	hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp),
55888ef30fd3SAndre Guedes 		    &enable_cp);
55898ef30fd3SAndre Guedes }
55908ef30fd3SAndre Guedes 
5591a4790dbdSAndre Guedes static void update_background_scan_complete(struct hci_dev *hdev, u8 status)
5592a4790dbdSAndre Guedes {
5593a4790dbdSAndre Guedes 	if (status)
5594a4790dbdSAndre Guedes 		BT_DBG("HCI request failed to update background scanning: "
5595a4790dbdSAndre Guedes 		       "status 0x%2.2x", status);
5596a4790dbdSAndre Guedes }
5597a4790dbdSAndre Guedes 
5598a4790dbdSAndre Guedes /* This function controls the background scanning based on hdev->pend_le_conns
5599a4790dbdSAndre Guedes  * list. If there are pending LE connection we start the background scanning,
5600a4790dbdSAndre Guedes  * otherwise we stop it.
5601a4790dbdSAndre Guedes  *
5602a4790dbdSAndre Guedes  * This function requires the caller holds hdev->lock.
5603a4790dbdSAndre Guedes  */
5604a4790dbdSAndre Guedes void hci_update_background_scan(struct hci_dev *hdev)
5605a4790dbdSAndre Guedes {
5606a4790dbdSAndre Guedes 	struct hci_request req;
5607a4790dbdSAndre Guedes 	struct hci_conn *conn;
5608a4790dbdSAndre Guedes 	int err;
5609a4790dbdSAndre Guedes 
5610c20c02d5SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags) ||
5611c20c02d5SMarcel Holtmann 	    test_bit(HCI_INIT, &hdev->flags) ||
5612c20c02d5SMarcel Holtmann 	    test_bit(HCI_SETUP, &hdev->dev_flags) ||
5613d603b76bSMarcel Holtmann 	    test_bit(HCI_CONFIG, &hdev->dev_flags) ||
5614b8221770SMarcel Holtmann 	    test_bit(HCI_AUTO_OFF, &hdev->dev_flags) ||
5615c20c02d5SMarcel Holtmann 	    test_bit(HCI_UNREGISTER, &hdev->dev_flags))
56161c1697c0SMarcel Holtmann 		return;
56171c1697c0SMarcel Holtmann 
5618a70f4b5fSJohan Hedberg 	/* No point in doing scanning if LE support hasn't been enabled */
5619a70f4b5fSJohan Hedberg 	if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags))
5620a70f4b5fSJohan Hedberg 		return;
5621a70f4b5fSJohan Hedberg 
5622ae23ada4SJohan Hedberg 	/* If discovery is active don't interfere with it */
5623ae23ada4SJohan Hedberg 	if (hdev->discovery.state != DISCOVERY_STOPPED)
5624ae23ada4SJohan Hedberg 		return;
5625ae23ada4SJohan Hedberg 
5626a4790dbdSAndre Guedes 	hci_req_init(&req, hdev);
5627a4790dbdSAndre Guedes 
5628d1d588c1SJohan Hedberg 	if (list_empty(&hdev->pend_le_conns) &&
562966f8455aSJohan Hedberg 	    list_empty(&hdev->pend_le_reports)) {
56300d2bf134SJohan Hedberg 		/* If there is no pending LE connections or devices
56310d2bf134SJohan Hedberg 		 * to be scanned for, we should stop the background
56320d2bf134SJohan Hedberg 		 * scanning.
5633a4790dbdSAndre Guedes 		 */
5634a4790dbdSAndre Guedes 
5635a4790dbdSAndre Guedes 		/* If controller is not scanning we are done. */
5636a4790dbdSAndre Guedes 		if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags))
5637a4790dbdSAndre Guedes 			return;
5638a4790dbdSAndre Guedes 
5639a4790dbdSAndre Guedes 		hci_req_add_le_scan_disable(&req);
5640a4790dbdSAndre Guedes 
5641a4790dbdSAndre Guedes 		BT_DBG("%s stopping background scanning", hdev->name);
5642a4790dbdSAndre Guedes 	} else {
5643a4790dbdSAndre Guedes 		/* If there is at least one pending LE connection, we should
5644a4790dbdSAndre Guedes 		 * keep the background scan running.
5645a4790dbdSAndre Guedes 		 */
5646a4790dbdSAndre Guedes 
5647a4790dbdSAndre Guedes 		/* If controller is connecting, we should not start scanning
5648a4790dbdSAndre Guedes 		 * since some controllers are not able to scan and connect at
5649a4790dbdSAndre Guedes 		 * the same time.
5650a4790dbdSAndre Guedes 		 */
5651a4790dbdSAndre Guedes 		conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
5652a4790dbdSAndre Guedes 		if (conn)
5653a4790dbdSAndre Guedes 			return;
5654a4790dbdSAndre Guedes 
56554340a124SAndre Guedes 		/* If controller is currently scanning, we stop it to ensure we
56564340a124SAndre Guedes 		 * don't miss any advertising (due to duplicates filter).
56574340a124SAndre Guedes 		 */
56584340a124SAndre Guedes 		if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
56594340a124SAndre Guedes 			hci_req_add_le_scan_disable(&req);
56604340a124SAndre Guedes 
56618ef30fd3SAndre Guedes 		hci_req_add_le_passive_scan(&req);
5662a4790dbdSAndre Guedes 
5663a4790dbdSAndre Guedes 		BT_DBG("%s starting background scanning", hdev->name);
5664a4790dbdSAndre Guedes 	}
5665a4790dbdSAndre Guedes 
5666a4790dbdSAndre Guedes 	err = hci_req_run(&req, update_background_scan_complete);
5667a4790dbdSAndre Guedes 	if (err)
5668a4790dbdSAndre Guedes 		BT_ERR("Failed to run HCI request: err %d", err);
5669a4790dbdSAndre Guedes }
5670432df05eSJohan Hedberg 
567122f433dcSJohan Hedberg static bool disconnected_whitelist_entries(struct hci_dev *hdev)
567222f433dcSJohan Hedberg {
567322f433dcSJohan Hedberg 	struct bdaddr_list *b;
567422f433dcSJohan Hedberg 
567522f433dcSJohan Hedberg 	list_for_each_entry(b, &hdev->whitelist, list) {
567622f433dcSJohan Hedberg 		struct hci_conn *conn;
567722f433dcSJohan Hedberg 
567822f433dcSJohan Hedberg 		conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &b->bdaddr);
567922f433dcSJohan Hedberg 		if (!conn)
568022f433dcSJohan Hedberg 			return true;
568122f433dcSJohan Hedberg 
568222f433dcSJohan Hedberg 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
568322f433dcSJohan Hedberg 			return true;
568422f433dcSJohan Hedberg 	}
568522f433dcSJohan Hedberg 
568622f433dcSJohan Hedberg 	return false;
568722f433dcSJohan Hedberg }
568822f433dcSJohan Hedberg 
5689432df05eSJohan Hedberg void hci_update_page_scan(struct hci_dev *hdev, struct hci_request *req)
5690432df05eSJohan Hedberg {
5691432df05eSJohan Hedberg 	u8 scan;
5692432df05eSJohan Hedberg 
5693432df05eSJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
5694432df05eSJohan Hedberg 		return;
5695432df05eSJohan Hedberg 
5696432df05eSJohan Hedberg 	if (!hdev_is_powered(hdev))
5697432df05eSJohan Hedberg 		return;
5698432df05eSJohan Hedberg 
5699432df05eSJohan Hedberg 	if (mgmt_powering_down(hdev))
5700432df05eSJohan Hedberg 		return;
5701432df05eSJohan Hedberg 
5702432df05eSJohan Hedberg 	if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags) ||
570322f433dcSJohan Hedberg 	    disconnected_whitelist_entries(hdev))
5704432df05eSJohan Hedberg 		scan = SCAN_PAGE;
5705432df05eSJohan Hedberg 	else
5706432df05eSJohan Hedberg 		scan = SCAN_DISABLED;
5707432df05eSJohan Hedberg 
5708432df05eSJohan Hedberg 	if (test_bit(HCI_PSCAN, &hdev->flags) == !!(scan & SCAN_PAGE))
5709432df05eSJohan Hedberg 		return;
5710432df05eSJohan Hedberg 
5711432df05eSJohan Hedberg 	if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
5712432df05eSJohan Hedberg 		scan |= SCAN_INQUIRY;
5713432df05eSJohan Hedberg 
5714432df05eSJohan Hedberg 	if (req)
5715432df05eSJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
5716432df05eSJohan Hedberg 	else
5717432df05eSJohan Hedberg 		hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
5718432df05eSJohan Hedberg }
5719