xref: /openbmc/linux/net/bluetooth/hci_core.c (revision 35d70271)
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>
371da177e4SLinus Torvalds 
38970c4e46SJohan Hedberg #include "smp.h"
39970c4e46SJohan Hedberg 
40b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work);
41c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work);
423eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work);
431da177e4SLinus Torvalds 
441da177e4SLinus Torvalds /* HCI device list */
451da177e4SLinus Torvalds LIST_HEAD(hci_dev_list);
461da177e4SLinus Torvalds DEFINE_RWLOCK(hci_dev_list_lock);
471da177e4SLinus Torvalds 
481da177e4SLinus Torvalds /* HCI callback list */
491da177e4SLinus Torvalds LIST_HEAD(hci_cb_list);
501da177e4SLinus Torvalds DEFINE_RWLOCK(hci_cb_list_lock);
511da177e4SLinus Torvalds 
523df92b31SSasha Levin /* HCI ID Numbering */
533df92b31SSasha Levin static DEFINE_IDA(hci_index_ida);
543df92b31SSasha Levin 
551da177e4SLinus Torvalds /* ---- HCI notifications ---- */
561da177e4SLinus Torvalds 
576516455dSMarcel Holtmann static void hci_notify(struct hci_dev *hdev, int event)
581da177e4SLinus Torvalds {
59040030efSMarcel Holtmann 	hci_sock_dev_event(hdev, event);
601da177e4SLinus Torvalds }
611da177e4SLinus Torvalds 
62baf27f6eSMarcel Holtmann /* ---- HCI debugfs entries ---- */
63baf27f6eSMarcel Holtmann 
644b4148e9SMarcel Holtmann static ssize_t dut_mode_read(struct file *file, char __user *user_buf,
654b4148e9SMarcel Holtmann 			     size_t count, loff_t *ppos)
664b4148e9SMarcel Holtmann {
674b4148e9SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
684b4148e9SMarcel Holtmann 	char buf[3];
694b4148e9SMarcel Holtmann 
704b4148e9SMarcel Holtmann 	buf[0] = test_bit(HCI_DUT_MODE, &hdev->dev_flags) ? 'Y': 'N';
714b4148e9SMarcel Holtmann 	buf[1] = '\n';
724b4148e9SMarcel Holtmann 	buf[2] = '\0';
734b4148e9SMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
744b4148e9SMarcel Holtmann }
754b4148e9SMarcel Holtmann 
764b4148e9SMarcel Holtmann static ssize_t dut_mode_write(struct file *file, const char __user *user_buf,
774b4148e9SMarcel Holtmann 			      size_t count, loff_t *ppos)
784b4148e9SMarcel Holtmann {
794b4148e9SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
804b4148e9SMarcel Holtmann 	struct sk_buff *skb;
814b4148e9SMarcel Holtmann 	char buf[32];
824b4148e9SMarcel Holtmann 	size_t buf_size = min(count, (sizeof(buf)-1));
834b4148e9SMarcel Holtmann 	bool enable;
844b4148e9SMarcel Holtmann 	int err;
854b4148e9SMarcel Holtmann 
864b4148e9SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
874b4148e9SMarcel Holtmann 		return -ENETDOWN;
884b4148e9SMarcel Holtmann 
894b4148e9SMarcel Holtmann 	if (copy_from_user(buf, user_buf, buf_size))
904b4148e9SMarcel Holtmann 		return -EFAULT;
914b4148e9SMarcel Holtmann 
924b4148e9SMarcel Holtmann 	buf[buf_size] = '\0';
934b4148e9SMarcel Holtmann 	if (strtobool(buf, &enable))
944b4148e9SMarcel Holtmann 		return -EINVAL;
954b4148e9SMarcel Holtmann 
964b4148e9SMarcel Holtmann 	if (enable == test_bit(HCI_DUT_MODE, &hdev->dev_flags))
974b4148e9SMarcel Holtmann 		return -EALREADY;
984b4148e9SMarcel Holtmann 
994b4148e9SMarcel Holtmann 	hci_req_lock(hdev);
1004b4148e9SMarcel Holtmann 	if (enable)
1014b4148e9SMarcel Holtmann 		skb = __hci_cmd_sync(hdev, HCI_OP_ENABLE_DUT_MODE, 0, NULL,
1024b4148e9SMarcel Holtmann 				     HCI_CMD_TIMEOUT);
1034b4148e9SMarcel Holtmann 	else
1044b4148e9SMarcel Holtmann 		skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL,
1054b4148e9SMarcel Holtmann 				     HCI_CMD_TIMEOUT);
1064b4148e9SMarcel Holtmann 	hci_req_unlock(hdev);
1074b4148e9SMarcel Holtmann 
1084b4148e9SMarcel Holtmann 	if (IS_ERR(skb))
1094b4148e9SMarcel Holtmann 		return PTR_ERR(skb);
1104b4148e9SMarcel Holtmann 
1114b4148e9SMarcel Holtmann 	err = -bt_to_errno(skb->data[0]);
1124b4148e9SMarcel Holtmann 	kfree_skb(skb);
1134b4148e9SMarcel Holtmann 
1144b4148e9SMarcel Holtmann 	if (err < 0)
1154b4148e9SMarcel Holtmann 		return err;
1164b4148e9SMarcel Holtmann 
1174b4148e9SMarcel Holtmann 	change_bit(HCI_DUT_MODE, &hdev->dev_flags);
1184b4148e9SMarcel Holtmann 
1194b4148e9SMarcel Holtmann 	return count;
1204b4148e9SMarcel Holtmann }
1214b4148e9SMarcel Holtmann 
1224b4148e9SMarcel Holtmann static const struct file_operations dut_mode_fops = {
1234b4148e9SMarcel Holtmann 	.open		= simple_open,
1244b4148e9SMarcel Holtmann 	.read		= dut_mode_read,
1254b4148e9SMarcel Holtmann 	.write		= dut_mode_write,
1264b4148e9SMarcel Holtmann 	.llseek		= default_llseek,
1274b4148e9SMarcel Holtmann };
1284b4148e9SMarcel Holtmann 
129dfb826a8SMarcel Holtmann static int features_show(struct seq_file *f, void *ptr)
130dfb826a8SMarcel Holtmann {
131dfb826a8SMarcel Holtmann 	struct hci_dev *hdev = f->private;
132dfb826a8SMarcel Holtmann 	u8 p;
133dfb826a8SMarcel Holtmann 
134dfb826a8SMarcel Holtmann 	hci_dev_lock(hdev);
135dfb826a8SMarcel Holtmann 	for (p = 0; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
136cfbb2b5bSMarcel Holtmann 		seq_printf(f, "%2u: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
137dfb826a8SMarcel Holtmann 			   "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", p,
138dfb826a8SMarcel Holtmann 			   hdev->features[p][0], hdev->features[p][1],
139dfb826a8SMarcel Holtmann 			   hdev->features[p][2], hdev->features[p][3],
140dfb826a8SMarcel Holtmann 			   hdev->features[p][4], hdev->features[p][5],
141dfb826a8SMarcel Holtmann 			   hdev->features[p][6], hdev->features[p][7]);
142dfb826a8SMarcel Holtmann 	}
143cfbb2b5bSMarcel Holtmann 	if (lmp_le_capable(hdev))
144cfbb2b5bSMarcel Holtmann 		seq_printf(f, "LE: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
145cfbb2b5bSMarcel Holtmann 			   "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n",
146cfbb2b5bSMarcel Holtmann 			   hdev->le_features[0], hdev->le_features[1],
147cfbb2b5bSMarcel Holtmann 			   hdev->le_features[2], hdev->le_features[3],
148cfbb2b5bSMarcel Holtmann 			   hdev->le_features[4], hdev->le_features[5],
149cfbb2b5bSMarcel Holtmann 			   hdev->le_features[6], hdev->le_features[7]);
150dfb826a8SMarcel Holtmann 	hci_dev_unlock(hdev);
151dfb826a8SMarcel Holtmann 
152dfb826a8SMarcel Holtmann 	return 0;
153dfb826a8SMarcel Holtmann }
154dfb826a8SMarcel Holtmann 
155dfb826a8SMarcel Holtmann static int features_open(struct inode *inode, struct file *file)
156dfb826a8SMarcel Holtmann {
157dfb826a8SMarcel Holtmann 	return single_open(file, features_show, inode->i_private);
158dfb826a8SMarcel Holtmann }
159dfb826a8SMarcel Holtmann 
160dfb826a8SMarcel Holtmann static const struct file_operations features_fops = {
161dfb826a8SMarcel Holtmann 	.open		= features_open,
162dfb826a8SMarcel Holtmann 	.read		= seq_read,
163dfb826a8SMarcel Holtmann 	.llseek		= seq_lseek,
164dfb826a8SMarcel Holtmann 	.release	= single_release,
165dfb826a8SMarcel Holtmann };
166dfb826a8SMarcel Holtmann 
16770afe0b8SMarcel Holtmann static int blacklist_show(struct seq_file *f, void *p)
16870afe0b8SMarcel Holtmann {
16970afe0b8SMarcel Holtmann 	struct hci_dev *hdev = f->private;
17070afe0b8SMarcel Holtmann 	struct bdaddr_list *b;
17170afe0b8SMarcel Holtmann 
17270afe0b8SMarcel Holtmann 	hci_dev_lock(hdev);
17370afe0b8SMarcel Holtmann 	list_for_each_entry(b, &hdev->blacklist, list)
174b25f0785SMarcel Holtmann 		seq_printf(f, "%pMR (type %u)\n", &b->bdaddr, b->bdaddr_type);
17570afe0b8SMarcel Holtmann 	hci_dev_unlock(hdev);
17670afe0b8SMarcel Holtmann 
17770afe0b8SMarcel Holtmann 	return 0;
17870afe0b8SMarcel Holtmann }
17970afe0b8SMarcel Holtmann 
18070afe0b8SMarcel Holtmann static int blacklist_open(struct inode *inode, struct file *file)
18170afe0b8SMarcel Holtmann {
18270afe0b8SMarcel Holtmann 	return single_open(file, blacklist_show, inode->i_private);
18370afe0b8SMarcel Holtmann }
18470afe0b8SMarcel Holtmann 
18570afe0b8SMarcel Holtmann static const struct file_operations blacklist_fops = {
18670afe0b8SMarcel Holtmann 	.open		= blacklist_open,
18770afe0b8SMarcel Holtmann 	.read		= seq_read,
18870afe0b8SMarcel Holtmann 	.llseek		= seq_lseek,
18970afe0b8SMarcel Holtmann 	.release	= single_release,
19070afe0b8SMarcel Holtmann };
19170afe0b8SMarcel Holtmann 
19247219839SMarcel Holtmann static int uuids_show(struct seq_file *f, void *p)
19347219839SMarcel Holtmann {
19447219839SMarcel Holtmann 	struct hci_dev *hdev = f->private;
19547219839SMarcel Holtmann 	struct bt_uuid *uuid;
19647219839SMarcel Holtmann 
19747219839SMarcel Holtmann 	hci_dev_lock(hdev);
19847219839SMarcel Holtmann 	list_for_each_entry(uuid, &hdev->uuids, list) {
19958f01aa9SMarcel Holtmann 		u8 i, val[16];
20047219839SMarcel Holtmann 
20158f01aa9SMarcel Holtmann 		/* The Bluetooth UUID values are stored in big endian,
20258f01aa9SMarcel Holtmann 		 * but with reversed byte order. So convert them into
20358f01aa9SMarcel Holtmann 		 * the right order for the %pUb modifier.
20458f01aa9SMarcel Holtmann 		 */
20558f01aa9SMarcel Holtmann 		for (i = 0; i < 16; i++)
20658f01aa9SMarcel Holtmann 			val[i] = uuid->uuid[15 - i];
20747219839SMarcel Holtmann 
20858f01aa9SMarcel Holtmann 		seq_printf(f, "%pUb\n", val);
20947219839SMarcel Holtmann 	}
21047219839SMarcel Holtmann 	hci_dev_unlock(hdev);
21147219839SMarcel Holtmann 
21247219839SMarcel Holtmann 	return 0;
21347219839SMarcel Holtmann }
21447219839SMarcel Holtmann 
21547219839SMarcel Holtmann static int uuids_open(struct inode *inode, struct file *file)
21647219839SMarcel Holtmann {
21747219839SMarcel Holtmann 	return single_open(file, uuids_show, inode->i_private);
21847219839SMarcel Holtmann }
21947219839SMarcel Holtmann 
22047219839SMarcel Holtmann static const struct file_operations uuids_fops = {
22147219839SMarcel Holtmann 	.open		= uuids_open,
22247219839SMarcel Holtmann 	.read		= seq_read,
22347219839SMarcel Holtmann 	.llseek		= seq_lseek,
22447219839SMarcel Holtmann 	.release	= single_release,
22547219839SMarcel Holtmann };
22647219839SMarcel Holtmann 
227baf27f6eSMarcel Holtmann static int inquiry_cache_show(struct seq_file *f, void *p)
228baf27f6eSMarcel Holtmann {
229baf27f6eSMarcel Holtmann 	struct hci_dev *hdev = f->private;
230baf27f6eSMarcel Holtmann 	struct discovery_state *cache = &hdev->discovery;
231baf27f6eSMarcel Holtmann 	struct inquiry_entry *e;
232baf27f6eSMarcel Holtmann 
233baf27f6eSMarcel Holtmann 	hci_dev_lock(hdev);
234baf27f6eSMarcel Holtmann 
235baf27f6eSMarcel Holtmann 	list_for_each_entry(e, &cache->all, all) {
236baf27f6eSMarcel Holtmann 		struct inquiry_data *data = &e->data;
237baf27f6eSMarcel Holtmann 		seq_printf(f, "%pMR %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n",
238baf27f6eSMarcel Holtmann 			   &data->bdaddr,
239baf27f6eSMarcel Holtmann 			   data->pscan_rep_mode, data->pscan_period_mode,
240baf27f6eSMarcel Holtmann 			   data->pscan_mode, data->dev_class[2],
241baf27f6eSMarcel Holtmann 			   data->dev_class[1], data->dev_class[0],
242baf27f6eSMarcel Holtmann 			   __le16_to_cpu(data->clock_offset),
243baf27f6eSMarcel Holtmann 			   data->rssi, data->ssp_mode, e->timestamp);
244baf27f6eSMarcel Holtmann 	}
245baf27f6eSMarcel Holtmann 
246baf27f6eSMarcel Holtmann 	hci_dev_unlock(hdev);
247baf27f6eSMarcel Holtmann 
248baf27f6eSMarcel Holtmann 	return 0;
249baf27f6eSMarcel Holtmann }
250baf27f6eSMarcel Holtmann 
251baf27f6eSMarcel Holtmann static int inquiry_cache_open(struct inode *inode, struct file *file)
252baf27f6eSMarcel Holtmann {
253baf27f6eSMarcel Holtmann 	return single_open(file, inquiry_cache_show, inode->i_private);
254baf27f6eSMarcel Holtmann }
255baf27f6eSMarcel Holtmann 
256baf27f6eSMarcel Holtmann static const struct file_operations inquiry_cache_fops = {
257baf27f6eSMarcel Holtmann 	.open		= inquiry_cache_open,
258baf27f6eSMarcel Holtmann 	.read		= seq_read,
259baf27f6eSMarcel Holtmann 	.llseek		= seq_lseek,
260baf27f6eSMarcel Holtmann 	.release	= single_release,
261baf27f6eSMarcel Holtmann };
262baf27f6eSMarcel Holtmann 
26302d08d15SMarcel Holtmann static int link_keys_show(struct seq_file *f, void *ptr)
26402d08d15SMarcel Holtmann {
26502d08d15SMarcel Holtmann 	struct hci_dev *hdev = f->private;
26602d08d15SMarcel Holtmann 	struct list_head *p, *n;
26702d08d15SMarcel Holtmann 
26802d08d15SMarcel Holtmann 	hci_dev_lock(hdev);
26902d08d15SMarcel Holtmann 	list_for_each_safe(p, n, &hdev->link_keys) {
27002d08d15SMarcel Holtmann 		struct link_key *key = list_entry(p, struct link_key, list);
27102d08d15SMarcel Holtmann 		seq_printf(f, "%pMR %u %*phN %u\n", &key->bdaddr, key->type,
27202d08d15SMarcel Holtmann 			   HCI_LINK_KEY_SIZE, key->val, key->pin_len);
27302d08d15SMarcel Holtmann 	}
27402d08d15SMarcel Holtmann 	hci_dev_unlock(hdev);
27502d08d15SMarcel Holtmann 
27602d08d15SMarcel Holtmann 	return 0;
27702d08d15SMarcel Holtmann }
27802d08d15SMarcel Holtmann 
27902d08d15SMarcel Holtmann static int link_keys_open(struct inode *inode, struct file *file)
28002d08d15SMarcel Holtmann {
28102d08d15SMarcel Holtmann 	return single_open(file, link_keys_show, inode->i_private);
28202d08d15SMarcel Holtmann }
28302d08d15SMarcel Holtmann 
28402d08d15SMarcel Holtmann static const struct file_operations link_keys_fops = {
28502d08d15SMarcel Holtmann 	.open		= link_keys_open,
28602d08d15SMarcel Holtmann 	.read		= seq_read,
28702d08d15SMarcel Holtmann 	.llseek		= seq_lseek,
28802d08d15SMarcel Holtmann 	.release	= single_release,
28902d08d15SMarcel Holtmann };
29002d08d15SMarcel Holtmann 
291babdbb3cSMarcel Holtmann static int dev_class_show(struct seq_file *f, void *ptr)
292babdbb3cSMarcel Holtmann {
293babdbb3cSMarcel Holtmann 	struct hci_dev *hdev = f->private;
294babdbb3cSMarcel Holtmann 
295babdbb3cSMarcel Holtmann 	hci_dev_lock(hdev);
296babdbb3cSMarcel Holtmann 	seq_printf(f, "0x%.2x%.2x%.2x\n", hdev->dev_class[2],
297babdbb3cSMarcel Holtmann 		   hdev->dev_class[1], hdev->dev_class[0]);
298babdbb3cSMarcel Holtmann 	hci_dev_unlock(hdev);
299babdbb3cSMarcel Holtmann 
300babdbb3cSMarcel Holtmann 	return 0;
301babdbb3cSMarcel Holtmann }
302babdbb3cSMarcel Holtmann 
303babdbb3cSMarcel Holtmann static int dev_class_open(struct inode *inode, struct file *file)
304babdbb3cSMarcel Holtmann {
305babdbb3cSMarcel Holtmann 	return single_open(file, dev_class_show, inode->i_private);
306babdbb3cSMarcel Holtmann }
307babdbb3cSMarcel Holtmann 
308babdbb3cSMarcel Holtmann static const struct file_operations dev_class_fops = {
309babdbb3cSMarcel Holtmann 	.open		= dev_class_open,
310babdbb3cSMarcel Holtmann 	.read		= seq_read,
311babdbb3cSMarcel Holtmann 	.llseek		= seq_lseek,
312babdbb3cSMarcel Holtmann 	.release	= single_release,
313babdbb3cSMarcel Holtmann };
314babdbb3cSMarcel Holtmann 
315041000b9SMarcel Holtmann static int voice_setting_get(void *data, u64 *val)
316041000b9SMarcel Holtmann {
317041000b9SMarcel Holtmann 	struct hci_dev *hdev = data;
318041000b9SMarcel Holtmann 
319041000b9SMarcel Holtmann 	hci_dev_lock(hdev);
320041000b9SMarcel Holtmann 	*val = hdev->voice_setting;
321041000b9SMarcel Holtmann 	hci_dev_unlock(hdev);
322041000b9SMarcel Holtmann 
323041000b9SMarcel Holtmann 	return 0;
324041000b9SMarcel Holtmann }
325041000b9SMarcel Holtmann 
326041000b9SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(voice_setting_fops, voice_setting_get,
327041000b9SMarcel Holtmann 			NULL, "0x%4.4llx\n");
328041000b9SMarcel Holtmann 
329ebd1e33bSMarcel Holtmann static int auto_accept_delay_set(void *data, u64 val)
330ebd1e33bSMarcel Holtmann {
331ebd1e33bSMarcel Holtmann 	struct hci_dev *hdev = data;
332ebd1e33bSMarcel Holtmann 
333ebd1e33bSMarcel Holtmann 	hci_dev_lock(hdev);
334ebd1e33bSMarcel Holtmann 	hdev->auto_accept_delay = val;
335ebd1e33bSMarcel Holtmann 	hci_dev_unlock(hdev);
336ebd1e33bSMarcel Holtmann 
337ebd1e33bSMarcel Holtmann 	return 0;
338ebd1e33bSMarcel Holtmann }
339ebd1e33bSMarcel Holtmann 
340ebd1e33bSMarcel Holtmann static int auto_accept_delay_get(void *data, u64 *val)
341ebd1e33bSMarcel Holtmann {
342ebd1e33bSMarcel Holtmann 	struct hci_dev *hdev = data;
343ebd1e33bSMarcel Holtmann 
344ebd1e33bSMarcel Holtmann 	hci_dev_lock(hdev);
345ebd1e33bSMarcel Holtmann 	*val = hdev->auto_accept_delay;
346ebd1e33bSMarcel Holtmann 	hci_dev_unlock(hdev);
347ebd1e33bSMarcel Holtmann 
348ebd1e33bSMarcel Holtmann 	return 0;
349ebd1e33bSMarcel Holtmann }
350ebd1e33bSMarcel Holtmann 
351ebd1e33bSMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get,
352ebd1e33bSMarcel Holtmann 			auto_accept_delay_set, "%llu\n");
353ebd1e33bSMarcel Holtmann 
35406f5b778SMarcel Holtmann static int ssp_debug_mode_set(void *data, u64 val)
35506f5b778SMarcel Holtmann {
35606f5b778SMarcel Holtmann 	struct hci_dev *hdev = data;
35706f5b778SMarcel Holtmann 	struct sk_buff *skb;
35806f5b778SMarcel Holtmann 	__u8 mode;
35906f5b778SMarcel Holtmann 	int err;
36006f5b778SMarcel Holtmann 
36106f5b778SMarcel Holtmann 	if (val != 0 && val != 1)
36206f5b778SMarcel Holtmann 		return -EINVAL;
36306f5b778SMarcel Holtmann 
36406f5b778SMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
36506f5b778SMarcel Holtmann 		return -ENETDOWN;
36606f5b778SMarcel Holtmann 
36706f5b778SMarcel Holtmann 	hci_req_lock(hdev);
36806f5b778SMarcel Holtmann 	mode = val;
36906f5b778SMarcel Holtmann 	skb = __hci_cmd_sync(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE, sizeof(mode),
37006f5b778SMarcel Holtmann 			     &mode, HCI_CMD_TIMEOUT);
37106f5b778SMarcel Holtmann 	hci_req_unlock(hdev);
37206f5b778SMarcel Holtmann 
37306f5b778SMarcel Holtmann 	if (IS_ERR(skb))
37406f5b778SMarcel Holtmann 		return PTR_ERR(skb);
37506f5b778SMarcel Holtmann 
37606f5b778SMarcel Holtmann 	err = -bt_to_errno(skb->data[0]);
37706f5b778SMarcel Holtmann 	kfree_skb(skb);
37806f5b778SMarcel Holtmann 
37906f5b778SMarcel Holtmann 	if (err < 0)
38006f5b778SMarcel Holtmann 		return err;
38106f5b778SMarcel Holtmann 
38206f5b778SMarcel Holtmann 	hci_dev_lock(hdev);
38306f5b778SMarcel Holtmann 	hdev->ssp_debug_mode = val;
38406f5b778SMarcel Holtmann 	hci_dev_unlock(hdev);
38506f5b778SMarcel Holtmann 
38606f5b778SMarcel Holtmann 	return 0;
38706f5b778SMarcel Holtmann }
38806f5b778SMarcel Holtmann 
38906f5b778SMarcel Holtmann static int ssp_debug_mode_get(void *data, u64 *val)
39006f5b778SMarcel Holtmann {
39106f5b778SMarcel Holtmann 	struct hci_dev *hdev = data;
39206f5b778SMarcel Holtmann 
39306f5b778SMarcel Holtmann 	hci_dev_lock(hdev);
39406f5b778SMarcel Holtmann 	*val = hdev->ssp_debug_mode;
39506f5b778SMarcel Holtmann 	hci_dev_unlock(hdev);
39606f5b778SMarcel Holtmann 
39706f5b778SMarcel Holtmann 	return 0;
39806f5b778SMarcel Holtmann }
39906f5b778SMarcel Holtmann 
40006f5b778SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(ssp_debug_mode_fops, ssp_debug_mode_get,
40106f5b778SMarcel Holtmann 			ssp_debug_mode_set, "%llu\n");
40206f5b778SMarcel Holtmann 
4035afeac14SMarcel Holtmann static ssize_t force_sc_support_read(struct file *file, char __user *user_buf,
4045afeac14SMarcel Holtmann 				     size_t count, loff_t *ppos)
4055afeac14SMarcel Holtmann {
4065afeac14SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
4075afeac14SMarcel Holtmann 	char buf[3];
4085afeac14SMarcel Holtmann 
4095afeac14SMarcel Holtmann 	buf[0] = test_bit(HCI_FORCE_SC, &hdev->dev_flags) ? 'Y': 'N';
4105afeac14SMarcel Holtmann 	buf[1] = '\n';
4115afeac14SMarcel Holtmann 	buf[2] = '\0';
4125afeac14SMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
4135afeac14SMarcel Holtmann }
4145afeac14SMarcel Holtmann 
4155afeac14SMarcel Holtmann static ssize_t force_sc_support_write(struct file *file,
4165afeac14SMarcel Holtmann 				      const char __user *user_buf,
4175afeac14SMarcel Holtmann 				      size_t count, loff_t *ppos)
4185afeac14SMarcel Holtmann {
4195afeac14SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
4205afeac14SMarcel Holtmann 	char buf[32];
4215afeac14SMarcel Holtmann 	size_t buf_size = min(count, (sizeof(buf)-1));
4225afeac14SMarcel Holtmann 	bool enable;
4235afeac14SMarcel Holtmann 
4245afeac14SMarcel Holtmann 	if (test_bit(HCI_UP, &hdev->flags))
4255afeac14SMarcel Holtmann 		return -EBUSY;
4265afeac14SMarcel Holtmann 
4275afeac14SMarcel Holtmann 	if (copy_from_user(buf, user_buf, buf_size))
4285afeac14SMarcel Holtmann 		return -EFAULT;
4295afeac14SMarcel Holtmann 
4305afeac14SMarcel Holtmann 	buf[buf_size] = '\0';
4315afeac14SMarcel Holtmann 	if (strtobool(buf, &enable))
4325afeac14SMarcel Holtmann 		return -EINVAL;
4335afeac14SMarcel Holtmann 
4345afeac14SMarcel Holtmann 	if (enable == test_bit(HCI_FORCE_SC, &hdev->dev_flags))
4355afeac14SMarcel Holtmann 		return -EALREADY;
4365afeac14SMarcel Holtmann 
4375afeac14SMarcel Holtmann 	change_bit(HCI_FORCE_SC, &hdev->dev_flags);
4385afeac14SMarcel Holtmann 
4395afeac14SMarcel Holtmann 	return count;
4405afeac14SMarcel Holtmann }
4415afeac14SMarcel Holtmann 
4425afeac14SMarcel Holtmann static const struct file_operations force_sc_support_fops = {
4435afeac14SMarcel Holtmann 	.open		= simple_open,
4445afeac14SMarcel Holtmann 	.read		= force_sc_support_read,
4455afeac14SMarcel Holtmann 	.write		= force_sc_support_write,
4465afeac14SMarcel Holtmann 	.llseek		= default_llseek,
4475afeac14SMarcel Holtmann };
4485afeac14SMarcel Holtmann 
449134c2a89SMarcel Holtmann static ssize_t sc_only_mode_read(struct file *file, char __user *user_buf,
450134c2a89SMarcel Holtmann 				 size_t count, loff_t *ppos)
451134c2a89SMarcel Holtmann {
452134c2a89SMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
453134c2a89SMarcel Holtmann 	char buf[3];
454134c2a89SMarcel Holtmann 
455134c2a89SMarcel Holtmann 	buf[0] = test_bit(HCI_SC_ONLY, &hdev->dev_flags) ? 'Y': 'N';
456134c2a89SMarcel Holtmann 	buf[1] = '\n';
457134c2a89SMarcel Holtmann 	buf[2] = '\0';
458134c2a89SMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
459134c2a89SMarcel Holtmann }
460134c2a89SMarcel Holtmann 
461134c2a89SMarcel Holtmann static const struct file_operations sc_only_mode_fops = {
462134c2a89SMarcel Holtmann 	.open		= simple_open,
463134c2a89SMarcel Holtmann 	.read		= sc_only_mode_read,
464134c2a89SMarcel Holtmann 	.llseek		= default_llseek,
465134c2a89SMarcel Holtmann };
466134c2a89SMarcel Holtmann 
4672bfa3531SMarcel Holtmann static int idle_timeout_set(void *data, u64 val)
4682bfa3531SMarcel Holtmann {
4692bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
4702bfa3531SMarcel Holtmann 
4712bfa3531SMarcel Holtmann 	if (val != 0 && (val < 500 || val > 3600000))
4722bfa3531SMarcel Holtmann 		return -EINVAL;
4732bfa3531SMarcel Holtmann 
4742bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
4752bfa3531SMarcel Holtmann 	hdev->idle_timeout = val;
4762bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
4772bfa3531SMarcel Holtmann 
4782bfa3531SMarcel Holtmann 	return 0;
4792bfa3531SMarcel Holtmann }
4802bfa3531SMarcel Holtmann 
4812bfa3531SMarcel Holtmann static int idle_timeout_get(void *data, u64 *val)
4822bfa3531SMarcel Holtmann {
4832bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
4842bfa3531SMarcel Holtmann 
4852bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
4862bfa3531SMarcel Holtmann 	*val = hdev->idle_timeout;
4872bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
4882bfa3531SMarcel Holtmann 
4892bfa3531SMarcel Holtmann 	return 0;
4902bfa3531SMarcel Holtmann }
4912bfa3531SMarcel Holtmann 
4922bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(idle_timeout_fops, idle_timeout_get,
4932bfa3531SMarcel Holtmann 			idle_timeout_set, "%llu\n");
4942bfa3531SMarcel Holtmann 
4952bfa3531SMarcel Holtmann static int sniff_min_interval_set(void *data, u64 val)
4962bfa3531SMarcel Holtmann {
4972bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
4982bfa3531SMarcel Holtmann 
4992bfa3531SMarcel Holtmann 	if (val == 0 || val % 2 || val > hdev->sniff_max_interval)
5002bfa3531SMarcel Holtmann 		return -EINVAL;
5012bfa3531SMarcel Holtmann 
5022bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5032bfa3531SMarcel Holtmann 	hdev->sniff_min_interval = val;
5042bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5052bfa3531SMarcel Holtmann 
5062bfa3531SMarcel Holtmann 	return 0;
5072bfa3531SMarcel Holtmann }
5082bfa3531SMarcel Holtmann 
5092bfa3531SMarcel Holtmann static int sniff_min_interval_get(void *data, u64 *val)
5102bfa3531SMarcel Holtmann {
5112bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
5122bfa3531SMarcel Holtmann 
5132bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5142bfa3531SMarcel Holtmann 	*val = hdev->sniff_min_interval;
5152bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5162bfa3531SMarcel Holtmann 
5172bfa3531SMarcel Holtmann 	return 0;
5182bfa3531SMarcel Holtmann }
5192bfa3531SMarcel Holtmann 
5202bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_min_interval_fops, sniff_min_interval_get,
5212bfa3531SMarcel Holtmann 			sniff_min_interval_set, "%llu\n");
5222bfa3531SMarcel Holtmann 
5232bfa3531SMarcel Holtmann static int sniff_max_interval_set(void *data, u64 val)
5242bfa3531SMarcel Holtmann {
5252bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
5262bfa3531SMarcel Holtmann 
5272bfa3531SMarcel Holtmann 	if (val == 0 || val % 2 || val < hdev->sniff_min_interval)
5282bfa3531SMarcel Holtmann 		return -EINVAL;
5292bfa3531SMarcel Holtmann 
5302bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5312bfa3531SMarcel Holtmann 	hdev->sniff_max_interval = val;
5322bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5332bfa3531SMarcel Holtmann 
5342bfa3531SMarcel Holtmann 	return 0;
5352bfa3531SMarcel Holtmann }
5362bfa3531SMarcel Holtmann 
5372bfa3531SMarcel Holtmann static int sniff_max_interval_get(void *data, u64 *val)
5382bfa3531SMarcel Holtmann {
5392bfa3531SMarcel Holtmann 	struct hci_dev *hdev = data;
5402bfa3531SMarcel Holtmann 
5412bfa3531SMarcel Holtmann 	hci_dev_lock(hdev);
5422bfa3531SMarcel Holtmann 	*val = hdev->sniff_max_interval;
5432bfa3531SMarcel Holtmann 	hci_dev_unlock(hdev);
5442bfa3531SMarcel Holtmann 
5452bfa3531SMarcel Holtmann 	return 0;
5462bfa3531SMarcel Holtmann }
5472bfa3531SMarcel Holtmann 
5482bfa3531SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(sniff_max_interval_fops, sniff_max_interval_get,
5492bfa3531SMarcel Holtmann 			sniff_max_interval_set, "%llu\n");
5502bfa3531SMarcel Holtmann 
551e7b8fc92SMarcel Holtmann static int static_address_show(struct seq_file *f, void *p)
552e7b8fc92SMarcel Holtmann {
553e7b8fc92SMarcel Holtmann 	struct hci_dev *hdev = f->private;
554e7b8fc92SMarcel Holtmann 
555e7b8fc92SMarcel Holtmann 	hci_dev_lock(hdev);
556e7b8fc92SMarcel Holtmann 	seq_printf(f, "%pMR\n", &hdev->static_addr);
557e7b8fc92SMarcel Holtmann 	hci_dev_unlock(hdev);
558e7b8fc92SMarcel Holtmann 
559e7b8fc92SMarcel Holtmann 	return 0;
560e7b8fc92SMarcel Holtmann }
561e7b8fc92SMarcel Holtmann 
562e7b8fc92SMarcel Holtmann static int static_address_open(struct inode *inode, struct file *file)
563e7b8fc92SMarcel Holtmann {
564e7b8fc92SMarcel Holtmann 	return single_open(file, static_address_show, inode->i_private);
565e7b8fc92SMarcel Holtmann }
566e7b8fc92SMarcel Holtmann 
567e7b8fc92SMarcel Holtmann static const struct file_operations static_address_fops = {
568e7b8fc92SMarcel Holtmann 	.open		= static_address_open,
569e7b8fc92SMarcel Holtmann 	.read		= seq_read,
570e7b8fc92SMarcel Holtmann 	.llseek		= seq_lseek,
571e7b8fc92SMarcel Holtmann 	.release	= single_release,
572e7b8fc92SMarcel Holtmann };
573e7b8fc92SMarcel Holtmann 
57492202185SMarcel Holtmann static int own_address_type_set(void *data, u64 val)
57592202185SMarcel Holtmann {
57692202185SMarcel Holtmann 	struct hci_dev *hdev = data;
57792202185SMarcel Holtmann 
57892202185SMarcel Holtmann 	if (val != 0 && val != 1)
57992202185SMarcel Holtmann 		return -EINVAL;
58092202185SMarcel Holtmann 
58192202185SMarcel Holtmann 	hci_dev_lock(hdev);
58292202185SMarcel Holtmann 	hdev->own_addr_type = val;
58392202185SMarcel Holtmann 	hci_dev_unlock(hdev);
58492202185SMarcel Holtmann 
58592202185SMarcel Holtmann 	return 0;
58692202185SMarcel Holtmann }
58792202185SMarcel Holtmann 
58892202185SMarcel Holtmann static int own_address_type_get(void *data, u64 *val)
58992202185SMarcel Holtmann {
59092202185SMarcel Holtmann 	struct hci_dev *hdev = data;
59192202185SMarcel Holtmann 
59292202185SMarcel Holtmann 	hci_dev_lock(hdev);
59392202185SMarcel Holtmann 	*val = hdev->own_addr_type;
59492202185SMarcel Holtmann 	hci_dev_unlock(hdev);
59592202185SMarcel Holtmann 
59692202185SMarcel Holtmann 	return 0;
59792202185SMarcel Holtmann }
59892202185SMarcel Holtmann 
59992202185SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(own_address_type_fops, own_address_type_get,
60092202185SMarcel Holtmann 			own_address_type_set, "%llu\n");
60192202185SMarcel Holtmann 
6023698d704SMarcel Holtmann static int identity_resolving_keys_show(struct seq_file *f, void *ptr)
6033698d704SMarcel Holtmann {
6043698d704SMarcel Holtmann 	struct hci_dev *hdev = f->private;
6053698d704SMarcel Holtmann 	struct list_head *p, *n;
6063698d704SMarcel Holtmann 
6073698d704SMarcel Holtmann 	hci_dev_lock(hdev);
6083698d704SMarcel Holtmann 	list_for_each_safe(p, n, &hdev->identity_resolving_keys) {
6093698d704SMarcel Holtmann 		struct smp_irk *irk = list_entry(p, struct smp_irk, list);
6103698d704SMarcel Holtmann 		seq_printf(f, "%pMR (type %u) %*phN %pMR\n",
6113698d704SMarcel Holtmann 			   &irk->bdaddr, irk->addr_type,
6123698d704SMarcel Holtmann 			   16, irk->val, &irk->rpa);
6133698d704SMarcel Holtmann 	}
6143698d704SMarcel Holtmann 	hci_dev_unlock(hdev);
6153698d704SMarcel Holtmann 
6163698d704SMarcel Holtmann 	return 0;
6173698d704SMarcel Holtmann }
6183698d704SMarcel Holtmann 
6193698d704SMarcel Holtmann static int identity_resolving_keys_open(struct inode *inode, struct file *file)
6203698d704SMarcel Holtmann {
6213698d704SMarcel Holtmann 	return single_open(file, identity_resolving_keys_show,
6223698d704SMarcel Holtmann 			   inode->i_private);
6233698d704SMarcel Holtmann }
6243698d704SMarcel Holtmann 
6253698d704SMarcel Holtmann static const struct file_operations identity_resolving_keys_fops = {
6263698d704SMarcel Holtmann 	.open		= identity_resolving_keys_open,
6273698d704SMarcel Holtmann 	.read		= seq_read,
6283698d704SMarcel Holtmann 	.llseek		= seq_lseek,
6293698d704SMarcel Holtmann 	.release	= single_release,
6303698d704SMarcel Holtmann };
6313698d704SMarcel Holtmann 
6328f8625cdSMarcel Holtmann static int long_term_keys_show(struct seq_file *f, void *ptr)
6338f8625cdSMarcel Holtmann {
6348f8625cdSMarcel Holtmann 	struct hci_dev *hdev = f->private;
6358f8625cdSMarcel Holtmann 	struct list_head *p, *n;
6368f8625cdSMarcel Holtmann 
6378f8625cdSMarcel Holtmann 	hci_dev_lock(hdev);
638f813f1beSJohan Hedberg 	list_for_each_safe(p, n, &hdev->long_term_keys) {
6398f8625cdSMarcel Holtmann 		struct smp_ltk *ltk = list_entry(p, struct smp_ltk, list);
640f813f1beSJohan Hedberg 		seq_printf(f, "%pMR (type %u) %u 0x%02x %u %.4x %*phN %*phN\n",
6418f8625cdSMarcel Holtmann 			   &ltk->bdaddr, ltk->bdaddr_type, ltk->authenticated,
6428f8625cdSMarcel Holtmann 			   ltk->type, ltk->enc_size, __le16_to_cpu(ltk->ediv),
6438f8625cdSMarcel Holtmann 			   8, ltk->rand, 16, ltk->val);
6448f8625cdSMarcel Holtmann 	}
6458f8625cdSMarcel Holtmann 	hci_dev_unlock(hdev);
6468f8625cdSMarcel Holtmann 
6478f8625cdSMarcel Holtmann 	return 0;
6488f8625cdSMarcel Holtmann }
6498f8625cdSMarcel Holtmann 
6508f8625cdSMarcel Holtmann static int long_term_keys_open(struct inode *inode, struct file *file)
6518f8625cdSMarcel Holtmann {
6528f8625cdSMarcel Holtmann 	return single_open(file, long_term_keys_show, inode->i_private);
6538f8625cdSMarcel Holtmann }
6548f8625cdSMarcel Holtmann 
6558f8625cdSMarcel Holtmann static const struct file_operations long_term_keys_fops = {
6568f8625cdSMarcel Holtmann 	.open		= long_term_keys_open,
6578f8625cdSMarcel Holtmann 	.read		= seq_read,
6588f8625cdSMarcel Holtmann 	.llseek		= seq_lseek,
6598f8625cdSMarcel Holtmann 	.release	= single_release,
6608f8625cdSMarcel Holtmann };
6618f8625cdSMarcel Holtmann 
6624e70c7e7SMarcel Holtmann static int conn_min_interval_set(void *data, u64 val)
6634e70c7e7SMarcel Holtmann {
6644e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
6654e70c7e7SMarcel Holtmann 
6664e70c7e7SMarcel Holtmann 	if (val < 0x0006 || val > 0x0c80 || val > hdev->le_conn_max_interval)
6674e70c7e7SMarcel Holtmann 		return -EINVAL;
6684e70c7e7SMarcel Holtmann 
6694e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
6704e70c7e7SMarcel Holtmann 	hdev->le_conn_min_interval = val;
6714e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
6724e70c7e7SMarcel Holtmann 
6734e70c7e7SMarcel Holtmann 	return 0;
6744e70c7e7SMarcel Holtmann }
6754e70c7e7SMarcel Holtmann 
6764e70c7e7SMarcel Holtmann static int conn_min_interval_get(void *data, u64 *val)
6774e70c7e7SMarcel Holtmann {
6784e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
6794e70c7e7SMarcel Holtmann 
6804e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
6814e70c7e7SMarcel Holtmann 	*val = hdev->le_conn_min_interval;
6824e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
6834e70c7e7SMarcel Holtmann 
6844e70c7e7SMarcel Holtmann 	return 0;
6854e70c7e7SMarcel Holtmann }
6864e70c7e7SMarcel Holtmann 
6874e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_min_interval_fops, conn_min_interval_get,
6884e70c7e7SMarcel Holtmann 			conn_min_interval_set, "%llu\n");
6894e70c7e7SMarcel Holtmann 
6904e70c7e7SMarcel Holtmann static int conn_max_interval_set(void *data, u64 val)
6914e70c7e7SMarcel Holtmann {
6924e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
6934e70c7e7SMarcel Holtmann 
6944e70c7e7SMarcel Holtmann 	if (val < 0x0006 || val > 0x0c80 || val < hdev->le_conn_min_interval)
6954e70c7e7SMarcel Holtmann 		return -EINVAL;
6964e70c7e7SMarcel Holtmann 
6974e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
6984e70c7e7SMarcel Holtmann 	hdev->le_conn_max_interval = val;
6994e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
7004e70c7e7SMarcel Holtmann 
7014e70c7e7SMarcel Holtmann 	return 0;
7024e70c7e7SMarcel Holtmann }
7034e70c7e7SMarcel Holtmann 
7044e70c7e7SMarcel Holtmann static int conn_max_interval_get(void *data, u64 *val)
7054e70c7e7SMarcel Holtmann {
7064e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
7074e70c7e7SMarcel Holtmann 
7084e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
7094e70c7e7SMarcel Holtmann 	*val = hdev->le_conn_max_interval;
7104e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
7114e70c7e7SMarcel Holtmann 
7124e70c7e7SMarcel Holtmann 	return 0;
7134e70c7e7SMarcel Holtmann }
7144e70c7e7SMarcel Holtmann 
7154e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get,
7164e70c7e7SMarcel Holtmann 			conn_max_interval_set, "%llu\n");
7174e70c7e7SMarcel Holtmann 
71889863109SJukka Rissanen static ssize_t lowpan_read(struct file *file, char __user *user_buf,
71989863109SJukka Rissanen 			   size_t count, loff_t *ppos)
72089863109SJukka Rissanen {
72189863109SJukka Rissanen 	struct hci_dev *hdev = file->private_data;
72289863109SJukka Rissanen 	char buf[3];
72389863109SJukka Rissanen 
72489863109SJukka Rissanen 	buf[0] = test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags) ? 'Y' : 'N';
72589863109SJukka Rissanen 	buf[1] = '\n';
72689863109SJukka Rissanen 	buf[2] = '\0';
72789863109SJukka Rissanen 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
72889863109SJukka Rissanen }
72989863109SJukka Rissanen 
73089863109SJukka Rissanen static ssize_t lowpan_write(struct file *fp, const char __user *user_buffer,
73189863109SJukka Rissanen 			    size_t count, loff_t *position)
73289863109SJukka Rissanen {
73389863109SJukka Rissanen 	struct hci_dev *hdev = fp->private_data;
73489863109SJukka Rissanen 	bool enable;
73589863109SJukka Rissanen 	char buf[32];
73689863109SJukka Rissanen 	size_t buf_size = min(count, (sizeof(buf)-1));
73789863109SJukka Rissanen 
73889863109SJukka Rissanen 	if (copy_from_user(buf, user_buffer, buf_size))
73989863109SJukka Rissanen 		return -EFAULT;
74089863109SJukka Rissanen 
74189863109SJukka Rissanen 	buf[buf_size] = '\0';
74289863109SJukka Rissanen 
74389863109SJukka Rissanen 	if (strtobool(buf, &enable) < 0)
74489863109SJukka Rissanen 		return -EINVAL;
74589863109SJukka Rissanen 
74689863109SJukka Rissanen 	if (enable == test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags))
74789863109SJukka Rissanen 		return -EALREADY;
74889863109SJukka Rissanen 
74989863109SJukka Rissanen 	change_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags);
75089863109SJukka Rissanen 
75189863109SJukka Rissanen 	return count;
75289863109SJukka Rissanen }
75389863109SJukka Rissanen 
75489863109SJukka Rissanen static const struct file_operations lowpan_debugfs_fops = {
75589863109SJukka Rissanen 	.open		= simple_open,
75689863109SJukka Rissanen 	.read		= lowpan_read,
75789863109SJukka Rissanen 	.write		= lowpan_write,
75889863109SJukka Rissanen 	.llseek		= default_llseek,
75989863109SJukka Rissanen };
76089863109SJukka Rissanen 
7611da177e4SLinus Torvalds /* ---- HCI requests ---- */
7621da177e4SLinus Torvalds 
76342c6b129SJohan Hedberg static void hci_req_sync_complete(struct hci_dev *hdev, u8 result)
7641da177e4SLinus Torvalds {
76542c6b129SJohan Hedberg 	BT_DBG("%s result 0x%2.2x", hdev->name, result);
76675fb0e32SJohan Hedberg 
7671da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
7681da177e4SLinus Torvalds 		hdev->req_result = result;
7691da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_DONE;
7701da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
7711da177e4SLinus Torvalds 	}
7721da177e4SLinus Torvalds }
7731da177e4SLinus Torvalds 
7741da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err)
7751da177e4SLinus Torvalds {
7761da177e4SLinus Torvalds 	BT_DBG("%s err 0x%2.2x", hdev->name, err);
7771da177e4SLinus Torvalds 
7781da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
7791da177e4SLinus Torvalds 		hdev->req_result = err;
7801da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_CANCELED;
7811da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
7821da177e4SLinus Torvalds 	}
7831da177e4SLinus Torvalds }
7841da177e4SLinus Torvalds 
78577a63e0aSFengguang Wu static struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode,
78677a63e0aSFengguang Wu 					    u8 event)
78775e84b7cSJohan Hedberg {
78875e84b7cSJohan Hedberg 	struct hci_ev_cmd_complete *ev;
78975e84b7cSJohan Hedberg 	struct hci_event_hdr *hdr;
79075e84b7cSJohan Hedberg 	struct sk_buff *skb;
79175e84b7cSJohan Hedberg 
79275e84b7cSJohan Hedberg 	hci_dev_lock(hdev);
79375e84b7cSJohan Hedberg 
79475e84b7cSJohan Hedberg 	skb = hdev->recv_evt;
79575e84b7cSJohan Hedberg 	hdev->recv_evt = NULL;
79675e84b7cSJohan Hedberg 
79775e84b7cSJohan Hedberg 	hci_dev_unlock(hdev);
79875e84b7cSJohan Hedberg 
79975e84b7cSJohan Hedberg 	if (!skb)
80075e84b7cSJohan Hedberg 		return ERR_PTR(-ENODATA);
80175e84b7cSJohan Hedberg 
80275e84b7cSJohan Hedberg 	if (skb->len < sizeof(*hdr)) {
80375e84b7cSJohan Hedberg 		BT_ERR("Too short HCI event");
80475e84b7cSJohan Hedberg 		goto failed;
80575e84b7cSJohan Hedberg 	}
80675e84b7cSJohan Hedberg 
80775e84b7cSJohan Hedberg 	hdr = (void *) skb->data;
80875e84b7cSJohan Hedberg 	skb_pull(skb, HCI_EVENT_HDR_SIZE);
80975e84b7cSJohan Hedberg 
8107b1abbbeSJohan Hedberg 	if (event) {
8117b1abbbeSJohan Hedberg 		if (hdr->evt != event)
8127b1abbbeSJohan Hedberg 			goto failed;
8137b1abbbeSJohan Hedberg 		return skb;
8147b1abbbeSJohan Hedberg 	}
8157b1abbbeSJohan Hedberg 
81675e84b7cSJohan Hedberg 	if (hdr->evt != HCI_EV_CMD_COMPLETE) {
81775e84b7cSJohan Hedberg 		BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt);
81875e84b7cSJohan Hedberg 		goto failed;
81975e84b7cSJohan Hedberg 	}
82075e84b7cSJohan Hedberg 
82175e84b7cSJohan Hedberg 	if (skb->len < sizeof(*ev)) {
82275e84b7cSJohan Hedberg 		BT_ERR("Too short cmd_complete event");
82375e84b7cSJohan Hedberg 		goto failed;
82475e84b7cSJohan Hedberg 	}
82575e84b7cSJohan Hedberg 
82675e84b7cSJohan Hedberg 	ev = (void *) skb->data;
82775e84b7cSJohan Hedberg 	skb_pull(skb, sizeof(*ev));
82875e84b7cSJohan Hedberg 
82975e84b7cSJohan Hedberg 	if (opcode == __le16_to_cpu(ev->opcode))
83075e84b7cSJohan Hedberg 		return skb;
83175e84b7cSJohan Hedberg 
83275e84b7cSJohan Hedberg 	BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode,
83375e84b7cSJohan Hedberg 	       __le16_to_cpu(ev->opcode));
83475e84b7cSJohan Hedberg 
83575e84b7cSJohan Hedberg failed:
83675e84b7cSJohan Hedberg 	kfree_skb(skb);
83775e84b7cSJohan Hedberg 	return ERR_PTR(-ENODATA);
83875e84b7cSJohan Hedberg }
83975e84b7cSJohan Hedberg 
8407b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
84107dc93ddSJohan Hedberg 				  const void *param, u8 event, u32 timeout)
84275e84b7cSJohan Hedberg {
84375e84b7cSJohan Hedberg 	DECLARE_WAITQUEUE(wait, current);
84475e84b7cSJohan Hedberg 	struct hci_request req;
84575e84b7cSJohan Hedberg 	int err = 0;
84675e84b7cSJohan Hedberg 
84775e84b7cSJohan Hedberg 	BT_DBG("%s", hdev->name);
84875e84b7cSJohan Hedberg 
84975e84b7cSJohan Hedberg 	hci_req_init(&req, hdev);
85075e84b7cSJohan Hedberg 
8517b1abbbeSJohan Hedberg 	hci_req_add_ev(&req, opcode, plen, param, event);
85275e84b7cSJohan Hedberg 
85375e84b7cSJohan Hedberg 	hdev->req_status = HCI_REQ_PEND;
85475e84b7cSJohan Hedberg 
85575e84b7cSJohan Hedberg 	err = hci_req_run(&req, hci_req_sync_complete);
85675e84b7cSJohan Hedberg 	if (err < 0)
85775e84b7cSJohan Hedberg 		return ERR_PTR(err);
85875e84b7cSJohan Hedberg 
85975e84b7cSJohan Hedberg 	add_wait_queue(&hdev->req_wait_q, &wait);
86075e84b7cSJohan Hedberg 	set_current_state(TASK_INTERRUPTIBLE);
86175e84b7cSJohan Hedberg 
86275e84b7cSJohan Hedberg 	schedule_timeout(timeout);
86375e84b7cSJohan Hedberg 
86475e84b7cSJohan Hedberg 	remove_wait_queue(&hdev->req_wait_q, &wait);
86575e84b7cSJohan Hedberg 
86675e84b7cSJohan Hedberg 	if (signal_pending(current))
86775e84b7cSJohan Hedberg 		return ERR_PTR(-EINTR);
86875e84b7cSJohan Hedberg 
86975e84b7cSJohan Hedberg 	switch (hdev->req_status) {
87075e84b7cSJohan Hedberg 	case HCI_REQ_DONE:
87175e84b7cSJohan Hedberg 		err = -bt_to_errno(hdev->req_result);
87275e84b7cSJohan Hedberg 		break;
87375e84b7cSJohan Hedberg 
87475e84b7cSJohan Hedberg 	case HCI_REQ_CANCELED:
87575e84b7cSJohan Hedberg 		err = -hdev->req_result;
87675e84b7cSJohan Hedberg 		break;
87775e84b7cSJohan Hedberg 
87875e84b7cSJohan Hedberg 	default:
87975e84b7cSJohan Hedberg 		err = -ETIMEDOUT;
88075e84b7cSJohan Hedberg 		break;
88175e84b7cSJohan Hedberg 	}
88275e84b7cSJohan Hedberg 
88375e84b7cSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
88475e84b7cSJohan Hedberg 
88575e84b7cSJohan Hedberg 	BT_DBG("%s end: err %d", hdev->name, err);
88675e84b7cSJohan Hedberg 
88775e84b7cSJohan Hedberg 	if (err < 0)
88875e84b7cSJohan Hedberg 		return ERR_PTR(err);
88975e84b7cSJohan Hedberg 
8907b1abbbeSJohan Hedberg 	return hci_get_cmd_complete(hdev, opcode, event);
8917b1abbbeSJohan Hedberg }
8927b1abbbeSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync_ev);
8937b1abbbeSJohan Hedberg 
8947b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
89507dc93ddSJohan Hedberg 			       const void *param, u32 timeout)
8967b1abbbeSJohan Hedberg {
8977b1abbbeSJohan Hedberg 	return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout);
89875e84b7cSJohan Hedberg }
89975e84b7cSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync);
90075e84b7cSJohan Hedberg 
9011da177e4SLinus Torvalds /* Execute request and wait for completion. */
90201178cd4SJohan Hedberg static int __hci_req_sync(struct hci_dev *hdev,
90342c6b129SJohan Hedberg 			  void (*func)(struct hci_request *req,
90442c6b129SJohan Hedberg 				      unsigned long opt),
9051da177e4SLinus Torvalds 			  unsigned long opt, __u32 timeout)
9061da177e4SLinus Torvalds {
90742c6b129SJohan Hedberg 	struct hci_request req;
9081da177e4SLinus Torvalds 	DECLARE_WAITQUEUE(wait, current);
9091da177e4SLinus Torvalds 	int err = 0;
9101da177e4SLinus Torvalds 
9111da177e4SLinus Torvalds 	BT_DBG("%s start", hdev->name);
9121da177e4SLinus Torvalds 
91342c6b129SJohan Hedberg 	hci_req_init(&req, hdev);
91442c6b129SJohan Hedberg 
9151da177e4SLinus Torvalds 	hdev->req_status = HCI_REQ_PEND;
9161da177e4SLinus Torvalds 
91742c6b129SJohan Hedberg 	func(&req, opt);
91853cce22dSJohan Hedberg 
91942c6b129SJohan Hedberg 	err = hci_req_run(&req, hci_req_sync_complete);
92042c6b129SJohan Hedberg 	if (err < 0) {
92153cce22dSJohan Hedberg 		hdev->req_status = 0;
922920c8300SAndre Guedes 
923920c8300SAndre Guedes 		/* ENODATA means the HCI request command queue is empty.
924920c8300SAndre Guedes 		 * This can happen when a request with conditionals doesn't
925920c8300SAndre Guedes 		 * trigger any commands to be sent. This is normal behavior
926920c8300SAndre Guedes 		 * and should not trigger an error return.
92742c6b129SJohan Hedberg 		 */
928920c8300SAndre Guedes 		if (err == -ENODATA)
92942c6b129SJohan Hedberg 			return 0;
930920c8300SAndre Guedes 
931920c8300SAndre Guedes 		return err;
93253cce22dSJohan Hedberg 	}
93353cce22dSJohan Hedberg 
934bc4445c7SAndre Guedes 	add_wait_queue(&hdev->req_wait_q, &wait);
935bc4445c7SAndre Guedes 	set_current_state(TASK_INTERRUPTIBLE);
936bc4445c7SAndre Guedes 
9371da177e4SLinus Torvalds 	schedule_timeout(timeout);
9381da177e4SLinus Torvalds 
9391da177e4SLinus Torvalds 	remove_wait_queue(&hdev->req_wait_q, &wait);
9401da177e4SLinus Torvalds 
9411da177e4SLinus Torvalds 	if (signal_pending(current))
9421da177e4SLinus Torvalds 		return -EINTR;
9431da177e4SLinus Torvalds 
9441da177e4SLinus Torvalds 	switch (hdev->req_status) {
9451da177e4SLinus Torvalds 	case HCI_REQ_DONE:
946e175072fSJoe Perches 		err = -bt_to_errno(hdev->req_result);
9471da177e4SLinus Torvalds 		break;
9481da177e4SLinus Torvalds 
9491da177e4SLinus Torvalds 	case HCI_REQ_CANCELED:
9501da177e4SLinus Torvalds 		err = -hdev->req_result;
9511da177e4SLinus Torvalds 		break;
9521da177e4SLinus Torvalds 
9531da177e4SLinus Torvalds 	default:
9541da177e4SLinus Torvalds 		err = -ETIMEDOUT;
9551da177e4SLinus Torvalds 		break;
9563ff50b79SStephen Hemminger 	}
9571da177e4SLinus Torvalds 
958a5040efaSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
9591da177e4SLinus Torvalds 
9601da177e4SLinus Torvalds 	BT_DBG("%s end: err %d", hdev->name, err);
9611da177e4SLinus Torvalds 
9621da177e4SLinus Torvalds 	return err;
9631da177e4SLinus Torvalds }
9641da177e4SLinus Torvalds 
96501178cd4SJohan Hedberg static int hci_req_sync(struct hci_dev *hdev,
96642c6b129SJohan Hedberg 			void (*req)(struct hci_request *req,
96742c6b129SJohan Hedberg 				    unsigned long opt),
9681da177e4SLinus Torvalds 			unsigned long opt, __u32 timeout)
9691da177e4SLinus Torvalds {
9701da177e4SLinus Torvalds 	int ret;
9711da177e4SLinus Torvalds 
9727c6a329eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
9737c6a329eSMarcel Holtmann 		return -ENETDOWN;
9747c6a329eSMarcel Holtmann 
9751da177e4SLinus Torvalds 	/* Serialize all requests */
9761da177e4SLinus Torvalds 	hci_req_lock(hdev);
97701178cd4SJohan Hedberg 	ret = __hci_req_sync(hdev, req, opt, timeout);
9781da177e4SLinus Torvalds 	hci_req_unlock(hdev);
9791da177e4SLinus Torvalds 
9801da177e4SLinus Torvalds 	return ret;
9811da177e4SLinus Torvalds }
9821da177e4SLinus Torvalds 
98342c6b129SJohan Hedberg static void hci_reset_req(struct hci_request *req, unsigned long opt)
9841da177e4SLinus Torvalds {
98542c6b129SJohan Hedberg 	BT_DBG("%s %ld", req->hdev->name, opt);
9861da177e4SLinus Torvalds 
9871da177e4SLinus Torvalds 	/* Reset device */
98842c6b129SJohan Hedberg 	set_bit(HCI_RESET, &req->hdev->flags);
98942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_RESET, 0, NULL);
9901da177e4SLinus Torvalds }
9911da177e4SLinus Torvalds 
99242c6b129SJohan Hedberg static void bredr_init(struct hci_request *req)
9931da177e4SLinus Torvalds {
99442c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
9952455a3eaSAndrei Emeltchenko 
9961da177e4SLinus Torvalds 	/* Read Local Supported Features */
99742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
9981da177e4SLinus Torvalds 
9991143e5a6SMarcel Holtmann 	/* Read Local Version */
100042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
10012177bab5SJohan Hedberg 
10022177bab5SJohan Hedberg 	/* Read BD Address */
100342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
10041da177e4SLinus Torvalds }
10051da177e4SLinus Torvalds 
100642c6b129SJohan Hedberg static void amp_init(struct hci_request *req)
1007e61ef499SAndrei Emeltchenko {
100842c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
10092455a3eaSAndrei Emeltchenko 
1010e61ef499SAndrei Emeltchenko 	/* Read Local Version */
101142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
10126bcbc489SAndrei Emeltchenko 
1013f6996cfeSMarcel Holtmann 	/* Read Local Supported Commands */
1014f6996cfeSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
1015f6996cfeSMarcel Holtmann 
1016f6996cfeSMarcel Holtmann 	/* Read Local Supported Features */
1017f6996cfeSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
1018f6996cfeSMarcel Holtmann 
10196bcbc489SAndrei Emeltchenko 	/* Read Local AMP Info */
102042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
1021e71dfabaSAndrei Emeltchenko 
1022e71dfabaSAndrei Emeltchenko 	/* Read Data Blk size */
102342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL);
10247528ca1cSMarcel Holtmann 
1025f38ba941SMarcel Holtmann 	/* Read Flow Control Mode */
1026f38ba941SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL);
1027f38ba941SMarcel Holtmann 
10287528ca1cSMarcel Holtmann 	/* Read Location Data */
10297528ca1cSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL);
1030e61ef499SAndrei Emeltchenko }
1031e61ef499SAndrei Emeltchenko 
103242c6b129SJohan Hedberg static void hci_init1_req(struct hci_request *req, unsigned long opt)
1033e61ef499SAndrei Emeltchenko {
103442c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1035e61ef499SAndrei Emeltchenko 
1036e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
1037e61ef499SAndrei Emeltchenko 
103811778716SAndrei Emeltchenko 	/* Reset */
103911778716SAndrei Emeltchenko 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
104042c6b129SJohan Hedberg 		hci_reset_req(req, 0);
104111778716SAndrei Emeltchenko 
1042e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
1043e61ef499SAndrei Emeltchenko 	case HCI_BREDR:
104442c6b129SJohan Hedberg 		bredr_init(req);
1045e61ef499SAndrei Emeltchenko 		break;
1046e61ef499SAndrei Emeltchenko 
1047e61ef499SAndrei Emeltchenko 	case HCI_AMP:
104842c6b129SJohan Hedberg 		amp_init(req);
1049e61ef499SAndrei Emeltchenko 		break;
1050e61ef499SAndrei Emeltchenko 
1051e61ef499SAndrei Emeltchenko 	default:
1052e61ef499SAndrei Emeltchenko 		BT_ERR("Unknown device type %d", hdev->dev_type);
1053e61ef499SAndrei Emeltchenko 		break;
1054e61ef499SAndrei Emeltchenko 	}
1055e61ef499SAndrei Emeltchenko }
1056e61ef499SAndrei Emeltchenko 
105742c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req)
10582177bab5SJohan Hedberg {
10594ca048e3SMarcel Holtmann 	struct hci_dev *hdev = req->hdev;
10604ca048e3SMarcel Holtmann 
10612177bab5SJohan Hedberg 	__le16 param;
10622177bab5SJohan Hedberg 	__u8 flt_type;
10632177bab5SJohan Hedberg 
10642177bab5SJohan Hedberg 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
106542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
10662177bab5SJohan Hedberg 
10672177bab5SJohan Hedberg 	/* Read Class of Device */
106842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
10692177bab5SJohan Hedberg 
10702177bab5SJohan Hedberg 	/* Read Local Name */
107142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL);
10722177bab5SJohan Hedberg 
10732177bab5SJohan Hedberg 	/* Read Voice Setting */
107442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL);
10752177bab5SJohan Hedberg 
1076b4cb9fb2SMarcel Holtmann 	/* Read Number of Supported IAC */
1077b4cb9fb2SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL);
1078b4cb9fb2SMarcel Holtmann 
10794b836f39SMarcel Holtmann 	/* Read Current IAC LAP */
10804b836f39SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL);
10814b836f39SMarcel Holtmann 
10822177bab5SJohan Hedberg 	/* Clear Event Filters */
10832177bab5SJohan Hedberg 	flt_type = HCI_FLT_CLEAR_ALL;
108442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
10852177bab5SJohan Hedberg 
10862177bab5SJohan Hedberg 	/* Connection accept timeout ~20 secs */
10872177bab5SJohan Hedberg 	param = __constant_cpu_to_le16(0x7d00);
108842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
10892177bab5SJohan Hedberg 
10904ca048e3SMarcel Holtmann 	/* AVM Berlin (31), aka "BlueFRITZ!", reports version 1.2,
10914ca048e3SMarcel Holtmann 	 * but it does not support page scan related HCI commands.
10924ca048e3SMarcel Holtmann 	 */
10934ca048e3SMarcel Holtmann 	if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) {
1094f332ec66SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL);
1095f332ec66SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL);
1096f332ec66SJohan Hedberg 	}
10972177bab5SJohan Hedberg }
10982177bab5SJohan Hedberg 
109942c6b129SJohan Hedberg static void le_setup(struct hci_request *req)
11002177bab5SJohan Hedberg {
1101c73eee91SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1102c73eee91SJohan Hedberg 
11032177bab5SJohan Hedberg 	/* Read LE Buffer Size */
110442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
11052177bab5SJohan Hedberg 
11062177bab5SJohan Hedberg 	/* Read LE Local Supported Features */
110742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
11082177bab5SJohan Hedberg 
11092177bab5SJohan Hedberg 	/* Read LE Advertising Channel TX Power */
111042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
11112177bab5SJohan Hedberg 
11122177bab5SJohan Hedberg 	/* Read LE White List Size */
111342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL);
11142177bab5SJohan Hedberg 
11152177bab5SJohan Hedberg 	/* Read LE Supported States */
111642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);
1117c73eee91SJohan Hedberg 
1118c73eee91SJohan Hedberg 	/* LE-only controllers have LE implicitly enabled */
1119c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
1120c73eee91SJohan Hedberg 		set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
11212177bab5SJohan Hedberg }
11222177bab5SJohan Hedberg 
11232177bab5SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
11242177bab5SJohan Hedberg {
11252177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
11262177bab5SJohan Hedberg 		return 0x02;
11272177bab5SJohan Hedberg 
11282177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
11292177bab5SJohan Hedberg 		return 0x01;
11302177bab5SJohan Hedberg 
11312177bab5SJohan Hedberg 	if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
11322177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x0757)
11332177bab5SJohan Hedberg 		return 0x01;
11342177bab5SJohan Hedberg 
11352177bab5SJohan Hedberg 	if (hdev->manufacturer == 15) {
11362177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
11372177bab5SJohan Hedberg 			return 0x01;
11382177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
11392177bab5SJohan Hedberg 			return 0x01;
11402177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
11412177bab5SJohan Hedberg 			return 0x01;
11422177bab5SJohan Hedberg 	}
11432177bab5SJohan Hedberg 
11442177bab5SJohan Hedberg 	if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
11452177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x1805)
11462177bab5SJohan Hedberg 		return 0x01;
11472177bab5SJohan Hedberg 
11482177bab5SJohan Hedberg 	return 0x00;
11492177bab5SJohan Hedberg }
11502177bab5SJohan Hedberg 
115142c6b129SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_request *req)
11522177bab5SJohan Hedberg {
11532177bab5SJohan Hedberg 	u8 mode;
11542177bab5SJohan Hedberg 
115542c6b129SJohan Hedberg 	mode = hci_get_inquiry_mode(req->hdev);
11562177bab5SJohan Hedberg 
115742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
11582177bab5SJohan Hedberg }
11592177bab5SJohan Hedberg 
116042c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req)
11612177bab5SJohan Hedberg {
116242c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
116342c6b129SJohan Hedberg 
11642177bab5SJohan Hedberg 	/* The second byte is 0xff instead of 0x9f (two reserved bits
11652177bab5SJohan Hedberg 	 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
11662177bab5SJohan Hedberg 	 * command otherwise.
11672177bab5SJohan Hedberg 	 */
11682177bab5SJohan Hedberg 	u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
11692177bab5SJohan Hedberg 
11702177bab5SJohan Hedberg 	/* CSR 1.1 dongles does not accept any bitfield so don't try to set
11712177bab5SJohan Hedberg 	 * any event mask for pre 1.2 devices.
11722177bab5SJohan Hedberg 	 */
11732177bab5SJohan Hedberg 	if (hdev->hci_ver < BLUETOOTH_VER_1_2)
11742177bab5SJohan Hedberg 		return;
11752177bab5SJohan Hedberg 
11762177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
11772177bab5SJohan Hedberg 		events[4] |= 0x01; /* Flow Specification Complete */
11782177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
11792177bab5SJohan Hedberg 		events[4] |= 0x04; /* Read Remote Extended Features Complete */
11802177bab5SJohan Hedberg 		events[5] |= 0x08; /* Synchronous Connection Complete */
11812177bab5SJohan Hedberg 		events[5] |= 0x10; /* Synchronous Connection Changed */
1182c7882cbdSMarcel Holtmann 	} else {
1183c7882cbdSMarcel Holtmann 		/* Use a different default for LE-only devices */
1184c7882cbdSMarcel Holtmann 		memset(events, 0, sizeof(events));
1185c7882cbdSMarcel Holtmann 		events[0] |= 0x10; /* Disconnection Complete */
1186c7882cbdSMarcel Holtmann 		events[0] |= 0x80; /* Encryption Change */
1187c7882cbdSMarcel Holtmann 		events[1] |= 0x08; /* Read Remote Version Information Complete */
1188c7882cbdSMarcel Holtmann 		events[1] |= 0x20; /* Command Complete */
1189c7882cbdSMarcel Holtmann 		events[1] |= 0x40; /* Command Status */
1190c7882cbdSMarcel Holtmann 		events[1] |= 0x80; /* Hardware Error */
1191c7882cbdSMarcel Holtmann 		events[2] |= 0x04; /* Number of Completed Packets */
1192c7882cbdSMarcel Holtmann 		events[3] |= 0x02; /* Data Buffer Overflow */
1193c7882cbdSMarcel Holtmann 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
11942177bab5SJohan Hedberg 	}
11952177bab5SJohan Hedberg 
11962177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
11972177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
11982177bab5SJohan Hedberg 
11992177bab5SJohan Hedberg 	if (lmp_sniffsubr_capable(hdev))
12002177bab5SJohan Hedberg 		events[5] |= 0x20; /* Sniff Subrating */
12012177bab5SJohan Hedberg 
12022177bab5SJohan Hedberg 	if (lmp_pause_enc_capable(hdev))
12032177bab5SJohan Hedberg 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
12042177bab5SJohan Hedberg 
12052177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
12062177bab5SJohan Hedberg 		events[5] |= 0x40; /* Extended Inquiry Result */
12072177bab5SJohan Hedberg 
12082177bab5SJohan Hedberg 	if (lmp_no_flush_capable(hdev))
12092177bab5SJohan Hedberg 		events[7] |= 0x01; /* Enhanced Flush Complete */
12102177bab5SJohan Hedberg 
12112177bab5SJohan Hedberg 	if (lmp_lsto_capable(hdev))
12122177bab5SJohan Hedberg 		events[6] |= 0x80; /* Link Supervision Timeout Changed */
12132177bab5SJohan Hedberg 
12142177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
12152177bab5SJohan Hedberg 		events[6] |= 0x01;	/* IO Capability Request */
12162177bab5SJohan Hedberg 		events[6] |= 0x02;	/* IO Capability Response */
12172177bab5SJohan Hedberg 		events[6] |= 0x04;	/* User Confirmation Request */
12182177bab5SJohan Hedberg 		events[6] |= 0x08;	/* User Passkey Request */
12192177bab5SJohan Hedberg 		events[6] |= 0x10;	/* Remote OOB Data Request */
12202177bab5SJohan Hedberg 		events[6] |= 0x20;	/* Simple Pairing Complete */
12212177bab5SJohan Hedberg 		events[7] |= 0x04;	/* User Passkey Notification */
12222177bab5SJohan Hedberg 		events[7] |= 0x08;	/* Keypress Notification */
12232177bab5SJohan Hedberg 		events[7] |= 0x10;	/* Remote Host Supported
12242177bab5SJohan Hedberg 					 * Features Notification
12252177bab5SJohan Hedberg 					 */
12262177bab5SJohan Hedberg 	}
12272177bab5SJohan Hedberg 
12282177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
12292177bab5SJohan Hedberg 		events[7] |= 0x20;	/* LE Meta-Event */
12302177bab5SJohan Hedberg 
123142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
12322177bab5SJohan Hedberg 
12332177bab5SJohan Hedberg 	if (lmp_le_capable(hdev)) {
12342177bab5SJohan Hedberg 		memset(events, 0, sizeof(events));
12352177bab5SJohan Hedberg 		events[0] = 0x1f;
123642c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK,
12372177bab5SJohan Hedberg 			    sizeof(events), events);
12382177bab5SJohan Hedberg 	}
12392177bab5SJohan Hedberg }
12402177bab5SJohan Hedberg 
124142c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt)
12422177bab5SJohan Hedberg {
124342c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
124442c6b129SJohan Hedberg 
12452177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev))
124642c6b129SJohan Hedberg 		bredr_setup(req);
124756f87901SJohan Hedberg 	else
124856f87901SJohan Hedberg 		clear_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
12492177bab5SJohan Hedberg 
12502177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
125142c6b129SJohan Hedberg 		le_setup(req);
12522177bab5SJohan Hedberg 
125342c6b129SJohan Hedberg 	hci_setup_event_mask(req);
12542177bab5SJohan Hedberg 
12553f8e2d75SJohan Hedberg 	/* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read
12563f8e2d75SJohan Hedberg 	 * local supported commands HCI command.
12573f8e2d75SJohan Hedberg 	 */
12583f8e2d75SJohan Hedberg 	if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1)
125942c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
12602177bab5SJohan Hedberg 
12612177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
126257af75a8SMarcel Holtmann 		/* When SSP is available, then the host features page
126357af75a8SMarcel Holtmann 		 * should also be available as well. However some
126457af75a8SMarcel Holtmann 		 * controllers list the max_page as 0 as long as SSP
126557af75a8SMarcel Holtmann 		 * has not been enabled. To achieve proper debugging
126657af75a8SMarcel Holtmann 		 * output, force the minimum max_page to 1 at least.
126757af75a8SMarcel Holtmann 		 */
126857af75a8SMarcel Holtmann 		hdev->max_page = 0x01;
126957af75a8SMarcel Holtmann 
12702177bab5SJohan Hedberg 		if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
12712177bab5SJohan Hedberg 			u8 mode = 0x01;
127242c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_SSP_MODE,
12732177bab5SJohan Hedberg 				    sizeof(mode), &mode);
12742177bab5SJohan Hedberg 		} else {
12752177bab5SJohan Hedberg 			struct hci_cp_write_eir cp;
12762177bab5SJohan Hedberg 
12772177bab5SJohan Hedberg 			memset(hdev->eir, 0, sizeof(hdev->eir));
12782177bab5SJohan Hedberg 			memset(&cp, 0, sizeof(cp));
12792177bab5SJohan Hedberg 
128042c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
12812177bab5SJohan Hedberg 		}
12822177bab5SJohan Hedberg 	}
12832177bab5SJohan Hedberg 
12842177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
128542c6b129SJohan Hedberg 		hci_setup_inquiry_mode(req);
12862177bab5SJohan Hedberg 
12872177bab5SJohan Hedberg 	if (lmp_inq_tx_pwr_capable(hdev))
128842c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
12892177bab5SJohan Hedberg 
12902177bab5SJohan Hedberg 	if (lmp_ext_feat_capable(hdev)) {
12912177bab5SJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
12922177bab5SJohan Hedberg 
12932177bab5SJohan Hedberg 		cp.page = 0x01;
129442c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
129542c6b129SJohan Hedberg 			    sizeof(cp), &cp);
12962177bab5SJohan Hedberg 	}
12972177bab5SJohan Hedberg 
12982177bab5SJohan Hedberg 	if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
12992177bab5SJohan Hedberg 		u8 enable = 1;
130042c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
13012177bab5SJohan Hedberg 			    &enable);
13022177bab5SJohan Hedberg 	}
13032177bab5SJohan Hedberg }
13042177bab5SJohan Hedberg 
130542c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req)
13062177bab5SJohan Hedberg {
130742c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
13082177bab5SJohan Hedberg 	struct hci_cp_write_def_link_policy cp;
13092177bab5SJohan Hedberg 	u16 link_policy = 0;
13102177bab5SJohan Hedberg 
13112177bab5SJohan Hedberg 	if (lmp_rswitch_capable(hdev))
13122177bab5SJohan Hedberg 		link_policy |= HCI_LP_RSWITCH;
13132177bab5SJohan Hedberg 	if (lmp_hold_capable(hdev))
13142177bab5SJohan Hedberg 		link_policy |= HCI_LP_HOLD;
13152177bab5SJohan Hedberg 	if (lmp_sniff_capable(hdev))
13162177bab5SJohan Hedberg 		link_policy |= HCI_LP_SNIFF;
13172177bab5SJohan Hedberg 	if (lmp_park_capable(hdev))
13182177bab5SJohan Hedberg 		link_policy |= HCI_LP_PARK;
13192177bab5SJohan Hedberg 
13202177bab5SJohan Hedberg 	cp.policy = cpu_to_le16(link_policy);
132142c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp);
13222177bab5SJohan Hedberg }
13232177bab5SJohan Hedberg 
132442c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req)
13252177bab5SJohan Hedberg {
132642c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
13272177bab5SJohan Hedberg 	struct hci_cp_write_le_host_supported cp;
13282177bab5SJohan Hedberg 
1329c73eee91SJohan Hedberg 	/* LE-only devices do not support explicit enablement */
1330c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
1331c73eee91SJohan Hedberg 		return;
1332c73eee91SJohan Hedberg 
13332177bab5SJohan Hedberg 	memset(&cp, 0, sizeof(cp));
13342177bab5SJohan Hedberg 
13352177bab5SJohan Hedberg 	if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
13362177bab5SJohan Hedberg 		cp.le = 0x01;
13372177bab5SJohan Hedberg 		cp.simul = lmp_le_br_capable(hdev);
13382177bab5SJohan Hedberg 	}
13392177bab5SJohan Hedberg 
13402177bab5SJohan Hedberg 	if (cp.le != lmp_host_le_capable(hdev))
134142c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
13422177bab5SJohan Hedberg 			    &cp);
13432177bab5SJohan Hedberg }
13442177bab5SJohan Hedberg 
1345d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req)
1346d62e6d67SJohan Hedberg {
1347d62e6d67SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1348d62e6d67SJohan Hedberg 	u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1349d62e6d67SJohan Hedberg 
1350d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast master role is supported
1351d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
1352d62e6d67SJohan Hedberg 	 */
135353b834d2SMarcel Holtmann 	if (lmp_csb_master_capable(hdev)) {
1354d62e6d67SJohan Hedberg 		events[1] |= 0x40;	/* Triggered Clock Capture */
1355d62e6d67SJohan Hedberg 		events[1] |= 0x80;	/* Synchronization Train Complete */
1356d62e6d67SJohan Hedberg 		events[2] |= 0x10;	/* Slave Page Response Timeout */
1357d62e6d67SJohan Hedberg 		events[2] |= 0x20;	/* CSB Channel Map Change */
1358d62e6d67SJohan Hedberg 	}
1359d62e6d67SJohan Hedberg 
1360d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast slave role is supported
1361d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
1362d62e6d67SJohan Hedberg 	 */
136353b834d2SMarcel Holtmann 	if (lmp_csb_slave_capable(hdev)) {
1364d62e6d67SJohan Hedberg 		events[2] |= 0x01;	/* Synchronization Train Received */
1365d62e6d67SJohan Hedberg 		events[2] |= 0x02;	/* CSB Receive */
1366d62e6d67SJohan Hedberg 		events[2] |= 0x04;	/* CSB Timeout */
1367d62e6d67SJohan Hedberg 		events[2] |= 0x08;	/* Truncated Page Complete */
1368d62e6d67SJohan Hedberg 	}
1369d62e6d67SJohan Hedberg 
137040c59fcbSMarcel Holtmann 	/* Enable Authenticated Payload Timeout Expired event if supported */
137140c59fcbSMarcel Holtmann 	if (lmp_ping_capable(hdev))
137240c59fcbSMarcel Holtmann 		events[2] |= 0x80;
137340c59fcbSMarcel Holtmann 
1374d62e6d67SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events);
1375d62e6d67SJohan Hedberg }
1376d62e6d67SJohan Hedberg 
137742c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt)
13782177bab5SJohan Hedberg {
137942c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1380d2c5d77fSJohan Hedberg 	u8 p;
138142c6b129SJohan Hedberg 
1382b8f4e068SGustavo Padovan 	/* Some Broadcom based Bluetooth controllers do not support the
1383b8f4e068SGustavo Padovan 	 * Delete Stored Link Key command. They are clearly indicating its
1384b8f4e068SGustavo Padovan 	 * absence in the bit mask of supported commands.
1385b8f4e068SGustavo Padovan 	 *
1386b8f4e068SGustavo Padovan 	 * Check the supported commands and only if the the command is marked
1387b8f4e068SGustavo Padovan 	 * as supported send it. If not supported assume that the controller
1388b8f4e068SGustavo Padovan 	 * does not have actual support for stored link keys which makes this
1389b8f4e068SGustavo Padovan 	 * command redundant anyway.
1390f9f462faSMarcel Holtmann 	 *
1391f9f462faSMarcel Holtmann 	 * Some controllers indicate that they support handling deleting
1392f9f462faSMarcel Holtmann 	 * stored link keys, but they don't. The quirk lets a driver
1393f9f462faSMarcel Holtmann 	 * just disable this command.
1394b8f4e068SGustavo Padovan 	 */
1395f9f462faSMarcel Holtmann 	if (hdev->commands[6] & 0x80 &&
1396f9f462faSMarcel Holtmann 	    !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) {
139759f45d57SJohan Hedberg 		struct hci_cp_delete_stored_link_key cp;
139859f45d57SJohan Hedberg 
139959f45d57SJohan Hedberg 		bacpy(&cp.bdaddr, BDADDR_ANY);
140059f45d57SJohan Hedberg 		cp.delete_all = 0x01;
140159f45d57SJohan Hedberg 		hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY,
140259f45d57SJohan Hedberg 			    sizeof(cp), &cp);
140359f45d57SJohan Hedberg 	}
140459f45d57SJohan Hedberg 
14052177bab5SJohan Hedberg 	if (hdev->commands[5] & 0x10)
140642c6b129SJohan Hedberg 		hci_setup_link_policy(req);
14072177bab5SJohan Hedberg 
140879830f66SMarcel Holtmann 	if (lmp_le_capable(hdev)) {
1409bef34c0aSMarcel Holtmann 		if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
1410bef34c0aSMarcel Holtmann 			/* If the controller has a public BD_ADDR, then
1411bef34c0aSMarcel Holtmann 			 * by default use that one. If this is a LE only
1412bef34c0aSMarcel Holtmann 			 * controller without a public address, default
1413bef34c0aSMarcel Holtmann 			 * to the random address.
141479830f66SMarcel Holtmann 			 */
141579830f66SMarcel Holtmann 			if (bacmp(&hdev->bdaddr, BDADDR_ANY))
141679830f66SMarcel Holtmann 				hdev->own_addr_type = ADDR_LE_DEV_PUBLIC;
141779830f66SMarcel Holtmann 			else
141879830f66SMarcel Holtmann 				hdev->own_addr_type = ADDR_LE_DEV_RANDOM;
1419bef34c0aSMarcel Holtmann 		}
142079830f66SMarcel Holtmann 
142142c6b129SJohan Hedberg 		hci_set_le_support(req);
142279830f66SMarcel Holtmann 	}
1423d2c5d77fSJohan Hedberg 
1424d2c5d77fSJohan Hedberg 	/* Read features beyond page 1 if available */
1425d2c5d77fSJohan Hedberg 	for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
1426d2c5d77fSJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
1427d2c5d77fSJohan Hedberg 
1428d2c5d77fSJohan Hedberg 		cp.page = p;
1429d2c5d77fSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
1430d2c5d77fSJohan Hedberg 			    sizeof(cp), &cp);
1431d2c5d77fSJohan Hedberg 	}
14322177bab5SJohan Hedberg }
14332177bab5SJohan Hedberg 
14345d4e7e8dSJohan Hedberg static void hci_init4_req(struct hci_request *req, unsigned long opt)
14355d4e7e8dSJohan Hedberg {
14365d4e7e8dSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
14375d4e7e8dSJohan Hedberg 
1438d62e6d67SJohan Hedberg 	/* Set event mask page 2 if the HCI command for it is supported */
1439d62e6d67SJohan Hedberg 	if (hdev->commands[22] & 0x04)
1440d62e6d67SJohan Hedberg 		hci_set_event_mask_page_2(req);
1441d62e6d67SJohan Hedberg 
14425d4e7e8dSJohan Hedberg 	/* Check for Synchronization Train support */
144353b834d2SMarcel Holtmann 	if (lmp_sync_train_capable(hdev))
14445d4e7e8dSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL);
1445a6d0d690SMarcel Holtmann 
1446a6d0d690SMarcel Holtmann 	/* Enable Secure Connections if supported and configured */
14475afeac14SMarcel Holtmann 	if ((lmp_sc_capable(hdev) ||
14485afeac14SMarcel Holtmann 	     test_bit(HCI_FORCE_SC, &hdev->dev_flags)) &&
1449a6d0d690SMarcel Holtmann 	    test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
1450a6d0d690SMarcel Holtmann 		u8 support = 0x01;
1451a6d0d690SMarcel Holtmann 		hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT,
1452a6d0d690SMarcel Holtmann 			    sizeof(support), &support);
1453a6d0d690SMarcel Holtmann 	}
14545d4e7e8dSJohan Hedberg }
14555d4e7e8dSJohan Hedberg 
14562177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev)
14572177bab5SJohan Hedberg {
14582177bab5SJohan Hedberg 	int err;
14592177bab5SJohan Hedberg 
14602177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT);
14612177bab5SJohan Hedberg 	if (err < 0)
14622177bab5SJohan Hedberg 		return err;
14632177bab5SJohan Hedberg 
14644b4148e9SMarcel Holtmann 	/* The Device Under Test (DUT) mode is special and available for
14654b4148e9SMarcel Holtmann 	 * all controller types. So just create it early on.
14664b4148e9SMarcel Holtmann 	 */
14674b4148e9SMarcel Holtmann 	if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
14684b4148e9SMarcel Holtmann 		debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev,
14694b4148e9SMarcel Holtmann 				    &dut_mode_fops);
14704b4148e9SMarcel Holtmann 	}
14714b4148e9SMarcel Holtmann 
14722177bab5SJohan Hedberg 	/* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode
14732177bab5SJohan Hedberg 	 * BR/EDR/LE type controllers. AMP controllers only need the
14742177bab5SJohan Hedberg 	 * first stage init.
14752177bab5SJohan Hedberg 	 */
14762177bab5SJohan Hedberg 	if (hdev->dev_type != HCI_BREDR)
14772177bab5SJohan Hedberg 		return 0;
14782177bab5SJohan Hedberg 
14792177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT);
14802177bab5SJohan Hedberg 	if (err < 0)
14812177bab5SJohan Hedberg 		return err;
14822177bab5SJohan Hedberg 
14835d4e7e8dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT);
14845d4e7e8dSJohan Hedberg 	if (err < 0)
14855d4e7e8dSJohan Hedberg 		return err;
14865d4e7e8dSJohan Hedberg 
1487baf27f6eSMarcel Holtmann 	err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT);
1488baf27f6eSMarcel Holtmann 	if (err < 0)
1489baf27f6eSMarcel Holtmann 		return err;
1490baf27f6eSMarcel Holtmann 
1491baf27f6eSMarcel Holtmann 	/* Only create debugfs entries during the initial setup
1492baf27f6eSMarcel Holtmann 	 * phase and not every time the controller gets powered on.
1493baf27f6eSMarcel Holtmann 	 */
1494baf27f6eSMarcel Holtmann 	if (!test_bit(HCI_SETUP, &hdev->dev_flags))
1495baf27f6eSMarcel Holtmann 		return 0;
1496baf27f6eSMarcel Holtmann 
1497dfb826a8SMarcel Holtmann 	debugfs_create_file("features", 0444, hdev->debugfs, hdev,
1498dfb826a8SMarcel Holtmann 			    &features_fops);
1499ceeb3bc0SMarcel Holtmann 	debugfs_create_u16("manufacturer", 0444, hdev->debugfs,
1500ceeb3bc0SMarcel Holtmann 			   &hdev->manufacturer);
1501ceeb3bc0SMarcel Holtmann 	debugfs_create_u8("hci_version", 0444, hdev->debugfs, &hdev->hci_ver);
1502ceeb3bc0SMarcel Holtmann 	debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev);
150370afe0b8SMarcel Holtmann 	debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev,
150470afe0b8SMarcel Holtmann 			    &blacklist_fops);
150547219839SMarcel Holtmann 	debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops);
150647219839SMarcel Holtmann 
1507baf27f6eSMarcel Holtmann 	if (lmp_bredr_capable(hdev)) {
1508baf27f6eSMarcel Holtmann 		debugfs_create_file("inquiry_cache", 0444, hdev->debugfs,
1509baf27f6eSMarcel Holtmann 				    hdev, &inquiry_cache_fops);
151002d08d15SMarcel Holtmann 		debugfs_create_file("link_keys", 0400, hdev->debugfs,
151102d08d15SMarcel Holtmann 				    hdev, &link_keys_fops);
1512babdbb3cSMarcel Holtmann 		debugfs_create_file("dev_class", 0444, hdev->debugfs,
1513babdbb3cSMarcel Holtmann 				    hdev, &dev_class_fops);
1514041000b9SMarcel Holtmann 		debugfs_create_file("voice_setting", 0444, hdev->debugfs,
1515041000b9SMarcel Holtmann 				    hdev, &voice_setting_fops);
1516baf27f6eSMarcel Holtmann 	}
1517baf27f6eSMarcel Holtmann 
151806f5b778SMarcel Holtmann 	if (lmp_ssp_capable(hdev)) {
1519ebd1e33bSMarcel Holtmann 		debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs,
1520ebd1e33bSMarcel Holtmann 				    hdev, &auto_accept_delay_fops);
152106f5b778SMarcel Holtmann 		debugfs_create_file("ssp_debug_mode", 0644, hdev->debugfs,
152206f5b778SMarcel Holtmann 				    hdev, &ssp_debug_mode_fops);
15235afeac14SMarcel Holtmann 		debugfs_create_file("force_sc_support", 0644, hdev->debugfs,
15245afeac14SMarcel Holtmann 				    hdev, &force_sc_support_fops);
1525134c2a89SMarcel Holtmann 		debugfs_create_file("sc_only_mode", 0444, hdev->debugfs,
1526134c2a89SMarcel Holtmann 				    hdev, &sc_only_mode_fops);
152706f5b778SMarcel Holtmann 	}
1528ebd1e33bSMarcel Holtmann 
15292bfa3531SMarcel Holtmann 	if (lmp_sniff_capable(hdev)) {
15302bfa3531SMarcel Holtmann 		debugfs_create_file("idle_timeout", 0644, hdev->debugfs,
15312bfa3531SMarcel Holtmann 				    hdev, &idle_timeout_fops);
15322bfa3531SMarcel Holtmann 		debugfs_create_file("sniff_min_interval", 0644, hdev->debugfs,
15332bfa3531SMarcel Holtmann 				    hdev, &sniff_min_interval_fops);
15342bfa3531SMarcel Holtmann 		debugfs_create_file("sniff_max_interval", 0644, hdev->debugfs,
15352bfa3531SMarcel Holtmann 				    hdev, &sniff_max_interval_fops);
15362bfa3531SMarcel Holtmann 	}
15372bfa3531SMarcel Holtmann 
1538d0f729b8SMarcel Holtmann 	if (lmp_le_capable(hdev)) {
1539d0f729b8SMarcel Holtmann 		debugfs_create_u8("white_list_size", 0444, hdev->debugfs,
1540d0f729b8SMarcel Holtmann 				  &hdev->le_white_list_size);
1541e7b8fc92SMarcel Holtmann 		debugfs_create_file("static_address", 0444, hdev->debugfs,
1542e7b8fc92SMarcel Holtmann 				   hdev, &static_address_fops);
154392202185SMarcel Holtmann 		debugfs_create_file("own_address_type", 0644, hdev->debugfs,
154492202185SMarcel Holtmann 				    hdev, &own_address_type_fops);
15453698d704SMarcel Holtmann 		debugfs_create_file("identity_resolving_keys", 0400,
15463698d704SMarcel Holtmann 				    hdev->debugfs, hdev,
15473698d704SMarcel Holtmann 				    &identity_resolving_keys_fops);
15488f8625cdSMarcel Holtmann 		debugfs_create_file("long_term_keys", 0400, hdev->debugfs,
15498f8625cdSMarcel Holtmann 				    hdev, &long_term_keys_fops);
15504e70c7e7SMarcel Holtmann 		debugfs_create_file("conn_min_interval", 0644, hdev->debugfs,
15514e70c7e7SMarcel Holtmann 				    hdev, &conn_min_interval_fops);
15524e70c7e7SMarcel Holtmann 		debugfs_create_file("conn_max_interval", 0644, hdev->debugfs,
15534e70c7e7SMarcel Holtmann 				    hdev, &conn_max_interval_fops);
155489863109SJukka Rissanen 		debugfs_create_file("6lowpan", 0644, hdev->debugfs, hdev,
155589863109SJukka Rissanen 				    &lowpan_debugfs_fops);
1556d0f729b8SMarcel Holtmann 	}
1557e7b8fc92SMarcel Holtmann 
1558baf27f6eSMarcel Holtmann 	return 0;
15592177bab5SJohan Hedberg }
15602177bab5SJohan Hedberg 
156142c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt)
15621da177e4SLinus Torvalds {
15631da177e4SLinus Torvalds 	__u8 scan = opt;
15641da177e4SLinus Torvalds 
156542c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, scan);
15661da177e4SLinus Torvalds 
15671da177e4SLinus Torvalds 	/* Inquiry and Page scans */
156842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
15691da177e4SLinus Torvalds }
15701da177e4SLinus Torvalds 
157142c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt)
15721da177e4SLinus Torvalds {
15731da177e4SLinus Torvalds 	__u8 auth = opt;
15741da177e4SLinus Torvalds 
157542c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, auth);
15761da177e4SLinus Torvalds 
15771da177e4SLinus Torvalds 	/* Authentication */
157842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
15791da177e4SLinus Torvalds }
15801da177e4SLinus Torvalds 
158142c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt)
15821da177e4SLinus Torvalds {
15831da177e4SLinus Torvalds 	__u8 encrypt = opt;
15841da177e4SLinus Torvalds 
158542c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, encrypt);
15861da177e4SLinus Torvalds 
1587e4e8e37cSMarcel Holtmann 	/* Encryption */
158842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
15891da177e4SLinus Torvalds }
15901da177e4SLinus Torvalds 
159142c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt)
1592e4e8e37cSMarcel Holtmann {
1593e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
1594e4e8e37cSMarcel Holtmann 
159542c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, policy);
1596e4e8e37cSMarcel Holtmann 
1597e4e8e37cSMarcel Holtmann 	/* Default link policy */
159842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
1599e4e8e37cSMarcel Holtmann }
1600e4e8e37cSMarcel Holtmann 
16011da177e4SLinus Torvalds /* Get HCI device by index.
16021da177e4SLinus Torvalds  * Device is held on return. */
16031da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
16041da177e4SLinus Torvalds {
16058035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
16061da177e4SLinus Torvalds 
16071da177e4SLinus Torvalds 	BT_DBG("%d", index);
16081da177e4SLinus Torvalds 
16091da177e4SLinus Torvalds 	if (index < 0)
16101da177e4SLinus Torvalds 		return NULL;
16111da177e4SLinus Torvalds 
16121da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
16138035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
16141da177e4SLinus Torvalds 		if (d->id == index) {
16151da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
16161da177e4SLinus Torvalds 			break;
16171da177e4SLinus Torvalds 		}
16181da177e4SLinus Torvalds 	}
16191da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
16201da177e4SLinus Torvalds 	return hdev;
16211da177e4SLinus Torvalds }
16221da177e4SLinus Torvalds 
16231da177e4SLinus Torvalds /* ---- Inquiry support ---- */
1624ff9ef578SJohan Hedberg 
162530dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
162630dc78e1SJohan Hedberg {
162730dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
162830dc78e1SJohan Hedberg 
16296fbe195dSAndre Guedes 	switch (discov->state) {
1630343f935bSAndre Guedes 	case DISCOVERY_FINDING:
16316fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
163230dc78e1SJohan Hedberg 		return true;
163330dc78e1SJohan Hedberg 
16346fbe195dSAndre Guedes 	default:
163530dc78e1SJohan Hedberg 		return false;
163630dc78e1SJohan Hedberg 	}
16376fbe195dSAndre Guedes }
163830dc78e1SJohan Hedberg 
1639ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
1640ff9ef578SJohan Hedberg {
1641ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
1642ff9ef578SJohan Hedberg 
1643ff9ef578SJohan Hedberg 	if (hdev->discovery.state == state)
1644ff9ef578SJohan Hedberg 		return;
1645ff9ef578SJohan Hedberg 
1646ff9ef578SJohan Hedberg 	switch (state) {
1647ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
16487b99b659SAndre Guedes 		if (hdev->discovery.state != DISCOVERY_STARTING)
1649ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
1650ff9ef578SJohan Hedberg 		break;
1651ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
1652ff9ef578SJohan Hedberg 		break;
1653343f935bSAndre Guedes 	case DISCOVERY_FINDING:
1654ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
1655ff9ef578SJohan Hedberg 		break;
165630dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
165730dc78e1SJohan Hedberg 		break;
1658ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
1659ff9ef578SJohan Hedberg 		break;
1660ff9ef578SJohan Hedberg 	}
1661ff9ef578SJohan Hedberg 
1662ff9ef578SJohan Hedberg 	hdev->discovery.state = state;
1663ff9ef578SJohan Hedberg }
1664ff9ef578SJohan Hedberg 
16651f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev)
16661da177e4SLinus Torvalds {
166730883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1668b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
16691da177e4SLinus Torvalds 
1670561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
1671561aafbcSJohan Hedberg 		list_del(&p->all);
1672b57c1a56SJohan Hedberg 		kfree(p);
16731da177e4SLinus Torvalds 	}
1674561aafbcSJohan Hedberg 
1675561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
1676561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
16771da177e4SLinus Torvalds }
16781da177e4SLinus Torvalds 
1679a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
1680a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
16811da177e4SLinus Torvalds {
168230883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
16831da177e4SLinus Torvalds 	struct inquiry_entry *e;
16841da177e4SLinus Torvalds 
16856ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
16861da177e4SLinus Torvalds 
1687561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
16881da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
16891da177e4SLinus Torvalds 			return e;
16901da177e4SLinus Torvalds 	}
16911da177e4SLinus Torvalds 
1692b57c1a56SJohan Hedberg 	return NULL;
1693b57c1a56SJohan Hedberg }
1694b57c1a56SJohan Hedberg 
1695561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
1696561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
1697561aafbcSJohan Hedberg {
169830883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1699561aafbcSJohan Hedberg 	struct inquiry_entry *e;
1700561aafbcSJohan Hedberg 
17016ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
1702561aafbcSJohan Hedberg 
1703561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
1704561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
1705561aafbcSJohan Hedberg 			return e;
1706561aafbcSJohan Hedberg 	}
1707561aafbcSJohan Hedberg 
1708561aafbcSJohan Hedberg 	return NULL;
1709561aafbcSJohan Hedberg }
1710561aafbcSJohan Hedberg 
171130dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
171230dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
171330dc78e1SJohan Hedberg 						       int state)
171430dc78e1SJohan Hedberg {
171530dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
171630dc78e1SJohan Hedberg 	struct inquiry_entry *e;
171730dc78e1SJohan Hedberg 
17186ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
171930dc78e1SJohan Hedberg 
172030dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
172130dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
172230dc78e1SJohan Hedberg 			return e;
172330dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
172430dc78e1SJohan Hedberg 			return e;
172530dc78e1SJohan Hedberg 	}
172630dc78e1SJohan Hedberg 
172730dc78e1SJohan Hedberg 	return NULL;
172830dc78e1SJohan Hedberg }
172930dc78e1SJohan Hedberg 
1730a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
1731a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
1732a3d4e20aSJohan Hedberg {
1733a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1734a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
1735a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
1736a3d4e20aSJohan Hedberg 
1737a3d4e20aSJohan Hedberg 	list_del(&ie->list);
1738a3d4e20aSJohan Hedberg 
1739a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
1740a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
1741a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
1742a3d4e20aSJohan Hedberg 			break;
1743a3d4e20aSJohan Hedberg 		pos = &p->list;
1744a3d4e20aSJohan Hedberg 	}
1745a3d4e20aSJohan Hedberg 
1746a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
1747a3d4e20aSJohan Hedberg }
1748a3d4e20aSJohan Hedberg 
17493175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
1750388fc8faSJohan Hedberg 			      bool name_known, bool *ssp)
17511da177e4SLinus Torvalds {
175230883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
175370f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
17541da177e4SLinus Torvalds 
17556ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
17561da177e4SLinus Torvalds 
17572b2fec4dSSzymon Janc 	hci_remove_remote_oob_data(hdev, &data->bdaddr);
17582b2fec4dSSzymon Janc 
1759388fc8faSJohan Hedberg 	if (ssp)
1760388fc8faSJohan Hedberg 		*ssp = data->ssp_mode;
1761388fc8faSJohan Hedberg 
176270f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
1763a3d4e20aSJohan Hedberg 	if (ie) {
1764388fc8faSJohan Hedberg 		if (ie->data.ssp_mode && ssp)
1765388fc8faSJohan Hedberg 			*ssp = true;
1766388fc8faSJohan Hedberg 
1767a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
1768a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
1769a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
1770a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
1771a3d4e20aSJohan Hedberg 		}
1772a3d4e20aSJohan Hedberg 
1773561aafbcSJohan Hedberg 		goto update;
1774a3d4e20aSJohan Hedberg 	}
1775561aafbcSJohan Hedberg 
17761da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
177770f23020SAndrei Emeltchenko 	ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
177870f23020SAndrei Emeltchenko 	if (!ie)
17793175405bSJohan Hedberg 		return false;
178070f23020SAndrei Emeltchenko 
1781561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
1782561aafbcSJohan Hedberg 
1783561aafbcSJohan Hedberg 	if (name_known) {
1784561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
1785561aafbcSJohan Hedberg 	} else {
1786561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
1787561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
1788561aafbcSJohan Hedberg 	}
1789561aafbcSJohan Hedberg 
1790561aafbcSJohan Hedberg update:
1791561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
1792561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
1793561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
1794561aafbcSJohan Hedberg 		list_del(&ie->list);
17951da177e4SLinus Torvalds 	}
17961da177e4SLinus Torvalds 
179770f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
179870f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
17991da177e4SLinus Torvalds 	cache->timestamp = jiffies;
18003175405bSJohan Hedberg 
18013175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
18023175405bSJohan Hedberg 		return false;
18033175405bSJohan Hedberg 
18043175405bSJohan Hedberg 	return true;
18051da177e4SLinus Torvalds }
18061da177e4SLinus Torvalds 
18071da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
18081da177e4SLinus Torvalds {
180930883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
18101da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
18111da177e4SLinus Torvalds 	struct inquiry_entry *e;
18121da177e4SLinus Torvalds 	int copied = 0;
18131da177e4SLinus Torvalds 
1814561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
18151da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
1816b57c1a56SJohan Hedberg 
1817b57c1a56SJohan Hedberg 		if (copied >= num)
1818b57c1a56SJohan Hedberg 			break;
1819b57c1a56SJohan Hedberg 
18201da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
18211da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
18221da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
18231da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
18241da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
18251da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
1826b57c1a56SJohan Hedberg 
18271da177e4SLinus Torvalds 		info++;
1828b57c1a56SJohan Hedberg 		copied++;
18291da177e4SLinus Torvalds 	}
18301da177e4SLinus Torvalds 
18311da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
18321da177e4SLinus Torvalds 	return copied;
18331da177e4SLinus Torvalds }
18341da177e4SLinus Torvalds 
183542c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt)
18361da177e4SLinus Torvalds {
18371da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
183842c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
18391da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
18401da177e4SLinus Torvalds 
18411da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
18421da177e4SLinus Torvalds 
18431da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
18441da177e4SLinus Torvalds 		return;
18451da177e4SLinus Torvalds 
18461da177e4SLinus Torvalds 	/* Start Inquiry */
18471da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
18481da177e4SLinus Torvalds 	cp.length  = ir->length;
18491da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
185042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
18511da177e4SLinus Torvalds }
18521da177e4SLinus Torvalds 
18533e13fa1eSAndre Guedes static int wait_inquiry(void *word)
18543e13fa1eSAndre Guedes {
18553e13fa1eSAndre Guedes 	schedule();
18563e13fa1eSAndre Guedes 	return signal_pending(current);
18573e13fa1eSAndre Guedes }
18583e13fa1eSAndre Guedes 
18591da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
18601da177e4SLinus Torvalds {
18611da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
18621da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
18631da177e4SLinus Torvalds 	struct hci_dev *hdev;
18641da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
18651da177e4SLinus Torvalds 	long timeo;
18661da177e4SLinus Torvalds 	__u8 *buf;
18671da177e4SLinus Torvalds 
18681da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
18691da177e4SLinus Torvalds 		return -EFAULT;
18701da177e4SLinus Torvalds 
18715a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
18725a08ecceSAndrei Emeltchenko 	if (!hdev)
18731da177e4SLinus Torvalds 		return -ENODEV;
18741da177e4SLinus Torvalds 
18750736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
18760736cfa8SMarcel Holtmann 		err = -EBUSY;
18770736cfa8SMarcel Holtmann 		goto done;
18780736cfa8SMarcel Holtmann 	}
18790736cfa8SMarcel Holtmann 
18805b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
18815b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
18825b69bef5SMarcel Holtmann 		goto done;
18835b69bef5SMarcel Holtmann 	}
18845b69bef5SMarcel Holtmann 
188556f87901SJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
188656f87901SJohan Hedberg 		err = -EOPNOTSUPP;
188756f87901SJohan Hedberg 		goto done;
188856f87901SJohan Hedberg 	}
188956f87901SJohan Hedberg 
189009fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
18911da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
1892a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
18931f9b9a5dSAndre Guedes 		hci_inquiry_cache_flush(hdev);
18941da177e4SLinus Torvalds 		do_inquiry = 1;
18951da177e4SLinus Torvalds 	}
189609fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
18971da177e4SLinus Torvalds 
189804837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
189970f23020SAndrei Emeltchenko 
190070f23020SAndrei Emeltchenko 	if (do_inquiry) {
190101178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
190201178cd4SJohan Hedberg 				   timeo);
190370f23020SAndrei Emeltchenko 		if (err < 0)
19041da177e4SLinus Torvalds 			goto done;
19053e13fa1eSAndre Guedes 
19063e13fa1eSAndre Guedes 		/* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
19073e13fa1eSAndre Guedes 		 * cleared). If it is interrupted by a signal, return -EINTR.
19083e13fa1eSAndre Guedes 		 */
19093e13fa1eSAndre Guedes 		if (wait_on_bit(&hdev->flags, HCI_INQUIRY, wait_inquiry,
19103e13fa1eSAndre Guedes 				TASK_INTERRUPTIBLE))
19113e13fa1eSAndre Guedes 			return -EINTR;
191270f23020SAndrei Emeltchenko 	}
19131da177e4SLinus Torvalds 
19148fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
19158fc9ced3SGustavo Padovan 	 * 255 entries
19168fc9ced3SGustavo Padovan 	 */
19171da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
19181da177e4SLinus Torvalds 
19191da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
19201da177e4SLinus Torvalds 	 * copy it to the user space.
19211da177e4SLinus Torvalds 	 */
192270f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
192370f23020SAndrei Emeltchenko 	if (!buf) {
19241da177e4SLinus Torvalds 		err = -ENOMEM;
19251da177e4SLinus Torvalds 		goto done;
19261da177e4SLinus Torvalds 	}
19271da177e4SLinus Torvalds 
192809fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
19291da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
193009fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
19311da177e4SLinus Torvalds 
19321da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
19331da177e4SLinus Torvalds 
19341da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
19351da177e4SLinus Torvalds 		ptr += sizeof(ir);
19361da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
19371da177e4SLinus Torvalds 				 ir.num_rsp))
19381da177e4SLinus Torvalds 			err = -EFAULT;
19391da177e4SLinus Torvalds 	} else
19401da177e4SLinus Torvalds 		err = -EFAULT;
19411da177e4SLinus Torvalds 
19421da177e4SLinus Torvalds 	kfree(buf);
19431da177e4SLinus Torvalds 
19441da177e4SLinus Torvalds done:
19451da177e4SLinus Torvalds 	hci_dev_put(hdev);
19461da177e4SLinus Torvalds 	return err;
19471da177e4SLinus Torvalds }
19481da177e4SLinus Torvalds 
1949cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev)
19501da177e4SLinus Torvalds {
19511da177e4SLinus Torvalds 	int ret = 0;
19521da177e4SLinus Torvalds 
19531da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
19541da177e4SLinus Torvalds 
19551da177e4SLinus Torvalds 	hci_req_lock(hdev);
19561da177e4SLinus Torvalds 
195794324962SJohan Hovold 	if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) {
195894324962SJohan Hovold 		ret = -ENODEV;
195994324962SJohan Hovold 		goto done;
196094324962SJohan Hovold 	}
196194324962SJohan Hovold 
1962a5c8f270SMarcel Holtmann 	if (!test_bit(HCI_SETUP, &hdev->dev_flags)) {
1963a5c8f270SMarcel Holtmann 		/* Check for rfkill but allow the HCI setup stage to
1964a5c8f270SMarcel Holtmann 		 * proceed (which in itself doesn't cause any RF activity).
1965bf543036SJohan Hedberg 		 */
1966a5c8f270SMarcel Holtmann 		if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) {
1967611b30f7SMarcel Holtmann 			ret = -ERFKILL;
1968611b30f7SMarcel Holtmann 			goto done;
1969611b30f7SMarcel Holtmann 		}
1970611b30f7SMarcel Holtmann 
1971a5c8f270SMarcel Holtmann 		/* Check for valid public address or a configured static
1972a5c8f270SMarcel Holtmann 		 * random adddress, but let the HCI setup proceed to
1973a5c8f270SMarcel Holtmann 		 * be able to determine if there is a public address
1974a5c8f270SMarcel Holtmann 		 * or not.
1975a5c8f270SMarcel Holtmann 		 *
1976c6beca0eSMarcel Holtmann 		 * In case of user channel usage, it is not important
1977c6beca0eSMarcel Holtmann 		 * if a public address or static random address is
1978c6beca0eSMarcel Holtmann 		 * available.
1979c6beca0eSMarcel Holtmann 		 *
1980a5c8f270SMarcel Holtmann 		 * This check is only valid for BR/EDR controllers
1981a5c8f270SMarcel Holtmann 		 * since AMP controllers do not have an address.
1982a5c8f270SMarcel Holtmann 		 */
1983c6beca0eSMarcel Holtmann 		if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
1984c6beca0eSMarcel Holtmann 		    hdev->dev_type == HCI_BREDR &&
1985a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
1986a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->static_addr, BDADDR_ANY)) {
1987a5c8f270SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
1988a5c8f270SMarcel Holtmann 			goto done;
1989a5c8f270SMarcel Holtmann 		}
1990a5c8f270SMarcel Holtmann 	}
1991a5c8f270SMarcel Holtmann 
19921da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
19931da177e4SLinus Torvalds 		ret = -EALREADY;
19941da177e4SLinus Torvalds 		goto done;
19951da177e4SLinus Torvalds 	}
19961da177e4SLinus Torvalds 
19971da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
19981da177e4SLinus Torvalds 		ret = -EIO;
19991da177e4SLinus Torvalds 		goto done;
20001da177e4SLinus Torvalds 	}
20011da177e4SLinus Torvalds 
20021da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
20031da177e4SLinus Torvalds 	set_bit(HCI_INIT, &hdev->flags);
2004f41c70c4SMarcel Holtmann 
2005f41c70c4SMarcel Holtmann 	if (hdev->setup && test_bit(HCI_SETUP, &hdev->dev_flags))
2006f41c70c4SMarcel Holtmann 		ret = hdev->setup(hdev);
2007f41c70c4SMarcel Holtmann 
2008f41c70c4SMarcel Holtmann 	if (!ret) {
2009f41c70c4SMarcel Holtmann 		if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
2010f41c70c4SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
2011f41c70c4SMarcel Holtmann 
20120736cfa8SMarcel Holtmann 		if (!test_bit(HCI_RAW, &hdev->flags) &&
20130736cfa8SMarcel Holtmann 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
20142177bab5SJohan Hedberg 			ret = __hci_init(hdev);
20151da177e4SLinus Torvalds 	}
20161da177e4SLinus Torvalds 
2017f41c70c4SMarcel Holtmann 	clear_bit(HCI_INIT, &hdev->flags);
2018f41c70c4SMarcel Holtmann 
20191da177e4SLinus Torvalds 	if (!ret) {
20201da177e4SLinus Torvalds 		hci_dev_hold(hdev);
20211da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
20221da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
2023bb4b2a9aSAndrei Emeltchenko 		if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
20240736cfa8SMarcel Holtmann 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
20251514b892SMarcel Holtmann 		    hdev->dev_type == HCI_BREDR) {
202609fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
2027744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
202809fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
202956e5cb86SJohan Hedberg 		}
20301da177e4SLinus Torvalds 	} else {
20311da177e4SLinus Torvalds 		/* Init failed, cleanup */
20323eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
2033c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
2034b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
20351da177e4SLinus Torvalds 
20361da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
20371da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
20381da177e4SLinus Torvalds 
20391da177e4SLinus Torvalds 		if (hdev->flush)
20401da177e4SLinus Torvalds 			hdev->flush(hdev);
20411da177e4SLinus Torvalds 
20421da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
20431da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
20441da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
20451da177e4SLinus Torvalds 		}
20461da177e4SLinus Torvalds 
20471da177e4SLinus Torvalds 		hdev->close(hdev);
20481da177e4SLinus Torvalds 		hdev->flags = 0;
20491da177e4SLinus Torvalds 	}
20501da177e4SLinus Torvalds 
20511da177e4SLinus Torvalds done:
20521da177e4SLinus Torvalds 	hci_req_unlock(hdev);
20531da177e4SLinus Torvalds 	return ret;
20541da177e4SLinus Torvalds }
20551da177e4SLinus Torvalds 
2056cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */
2057cbed0ca1SJohan Hedberg 
2058cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev)
2059cbed0ca1SJohan Hedberg {
2060cbed0ca1SJohan Hedberg 	struct hci_dev *hdev;
2061cbed0ca1SJohan Hedberg 	int err;
2062cbed0ca1SJohan Hedberg 
2063cbed0ca1SJohan Hedberg 	hdev = hci_dev_get(dev);
2064cbed0ca1SJohan Hedberg 	if (!hdev)
2065cbed0ca1SJohan Hedberg 		return -ENODEV;
2066cbed0ca1SJohan Hedberg 
2067e1d08f40SJohan Hedberg 	/* We need to ensure that no other power on/off work is pending
2068e1d08f40SJohan Hedberg 	 * before proceeding to call hci_dev_do_open. This is
2069e1d08f40SJohan Hedberg 	 * particularly important if the setup procedure has not yet
2070e1d08f40SJohan Hedberg 	 * completed.
2071e1d08f40SJohan Hedberg 	 */
2072e1d08f40SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
2073e1d08f40SJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
2074e1d08f40SJohan Hedberg 
2075a5c8f270SMarcel Holtmann 	/* After this call it is guaranteed that the setup procedure
2076a5c8f270SMarcel Holtmann 	 * has finished. This means that error conditions like RFKILL
2077a5c8f270SMarcel Holtmann 	 * or no valid public or static random address apply.
2078a5c8f270SMarcel Holtmann 	 */
2079e1d08f40SJohan Hedberg 	flush_workqueue(hdev->req_workqueue);
2080e1d08f40SJohan Hedberg 
2081cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
2082cbed0ca1SJohan Hedberg 
2083cbed0ca1SJohan Hedberg 	hci_dev_put(hdev);
2084cbed0ca1SJohan Hedberg 
2085cbed0ca1SJohan Hedberg 	return err;
2086cbed0ca1SJohan Hedberg }
2087cbed0ca1SJohan Hedberg 
20881da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
20891da177e4SLinus Torvalds {
20901da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
20911da177e4SLinus Torvalds 
209278c04c0bSVinicius Costa Gomes 	cancel_delayed_work(&hdev->power_off);
209378c04c0bSVinicius Costa Gomes 
20941da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
20951da177e4SLinus Torvalds 	hci_req_lock(hdev);
20961da177e4SLinus Torvalds 
20971da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
2098b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
20991da177e4SLinus Torvalds 		hci_req_unlock(hdev);
21001da177e4SLinus Torvalds 		return 0;
21011da177e4SLinus Torvalds 	}
21021da177e4SLinus Torvalds 
21033eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
21043eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
2105b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
21061da177e4SLinus Torvalds 
210716ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
2108e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
210916ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
21105e5282bbSJohan Hedberg 		clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
2111310a3d48SMarcel Holtmann 		clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
211216ab91abSJohan Hedberg 	}
211316ab91abSJohan Hedberg 
2114a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
21157d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
21167d78525dSJohan Hedberg 
21177ba8b4beSAndre Guedes 	cancel_delayed_work_sync(&hdev->le_scan_disable);
21187ba8b4beSAndre Guedes 
211909fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
21201f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
21211da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
212209fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
21231da177e4SLinus Torvalds 
21241da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
21251da177e4SLinus Torvalds 
21261da177e4SLinus Torvalds 	if (hdev->flush)
21271da177e4SLinus Torvalds 		hdev->flush(hdev);
21281da177e4SLinus Torvalds 
21291da177e4SLinus Torvalds 	/* Reset device */
21301da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
21311da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
21328af59467SJohan Hedberg 	if (!test_bit(HCI_RAW, &hdev->flags) &&
21333a6afbd2SMarcel Holtmann 	    !test_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
2134a6c511c6SSzymon Janc 	    test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
21351da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
213601178cd4SJohan Hedberg 		__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
21371da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
21381da177e4SLinus Torvalds 	}
21391da177e4SLinus Torvalds 
2140c347b765SGustavo F. Padovan 	/* flush cmd  work */
2141c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
21421da177e4SLinus Torvalds 
21431da177e4SLinus Torvalds 	/* Drop queues */
21441da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
21451da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
21461da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
21471da177e4SLinus Torvalds 
21481da177e4SLinus Torvalds 	/* Drop last sent command */
21491da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
2150b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
21511da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
21521da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
21531da177e4SLinus Torvalds 	}
21541da177e4SLinus Torvalds 
2155b6ddb638SJohan Hedberg 	kfree_skb(hdev->recv_evt);
2156b6ddb638SJohan Hedberg 	hdev->recv_evt = NULL;
2157b6ddb638SJohan Hedberg 
21581da177e4SLinus Torvalds 	/* After this point our queues are empty
21591da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
21601da177e4SLinus Torvalds 	hdev->close(hdev);
21611da177e4SLinus Torvalds 
216235b973c9SJohan Hedberg 	/* Clear flags */
216335b973c9SJohan Hedberg 	hdev->flags = 0;
216435b973c9SJohan Hedberg 	hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
216535b973c9SJohan Hedberg 
216693c311a0SMarcel Holtmann 	if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
216793c311a0SMarcel Holtmann 		if (hdev->dev_type == HCI_BREDR) {
216809fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
2169744cf19eSJohan Hedberg 			mgmt_powered(hdev, 0);
217009fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
21718ee56540SMarcel Holtmann 		}
217293c311a0SMarcel Holtmann 	}
21735add6af8SJohan Hedberg 
2174ced5c338SAndrei Emeltchenko 	/* Controller radio is available but is currently powered down */
2175536619e8SMarcel Holtmann 	hdev->amp_status = AMP_STATUS_POWERED_DOWN;
2176ced5c338SAndrei Emeltchenko 
2177e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
217809b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
2179e59fda8dSJohan Hedberg 
21801da177e4SLinus Torvalds 	hci_req_unlock(hdev);
21811da177e4SLinus Torvalds 
21821da177e4SLinus Torvalds 	hci_dev_put(hdev);
21831da177e4SLinus Torvalds 	return 0;
21841da177e4SLinus Torvalds }
21851da177e4SLinus Torvalds 
21861da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
21871da177e4SLinus Torvalds {
21881da177e4SLinus Torvalds 	struct hci_dev *hdev;
21891da177e4SLinus Torvalds 	int err;
21901da177e4SLinus Torvalds 
219170f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
219270f23020SAndrei Emeltchenko 	if (!hdev)
21931da177e4SLinus Torvalds 		return -ENODEV;
21948ee56540SMarcel Holtmann 
21950736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
21960736cfa8SMarcel Holtmann 		err = -EBUSY;
21970736cfa8SMarcel Holtmann 		goto done;
21980736cfa8SMarcel Holtmann 	}
21990736cfa8SMarcel Holtmann 
22008ee56540SMarcel Holtmann 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
22018ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
22028ee56540SMarcel Holtmann 
22031da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
22048ee56540SMarcel Holtmann 
22050736cfa8SMarcel Holtmann done:
22061da177e4SLinus Torvalds 	hci_dev_put(hdev);
22071da177e4SLinus Torvalds 	return err;
22081da177e4SLinus Torvalds }
22091da177e4SLinus Torvalds 
22101da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
22111da177e4SLinus Torvalds {
22121da177e4SLinus Torvalds 	struct hci_dev *hdev;
22131da177e4SLinus Torvalds 	int ret = 0;
22141da177e4SLinus Torvalds 
221570f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
221670f23020SAndrei Emeltchenko 	if (!hdev)
22171da177e4SLinus Torvalds 		return -ENODEV;
22181da177e4SLinus Torvalds 
22191da177e4SLinus Torvalds 	hci_req_lock(hdev);
22201da177e4SLinus Torvalds 
2221808a049eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
2222808a049eSMarcel Holtmann 		ret = -ENETDOWN;
22231da177e4SLinus Torvalds 		goto done;
2224808a049eSMarcel Holtmann 	}
22251da177e4SLinus Torvalds 
22260736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
22270736cfa8SMarcel Holtmann 		ret = -EBUSY;
22280736cfa8SMarcel Holtmann 		goto done;
22290736cfa8SMarcel Holtmann 	}
22300736cfa8SMarcel Holtmann 
22311da177e4SLinus Torvalds 	/* Drop queues */
22321da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
22331da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
22341da177e4SLinus Torvalds 
223509fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
22361f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
22371da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
223809fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
22391da177e4SLinus Torvalds 
22401da177e4SLinus Torvalds 	if (hdev->flush)
22411da177e4SLinus Torvalds 		hdev->flush(hdev);
22421da177e4SLinus Torvalds 
22431da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
22446ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
22451da177e4SLinus Torvalds 
22461da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags))
224701178cd4SJohan Hedberg 		ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
22481da177e4SLinus Torvalds 
22491da177e4SLinus Torvalds done:
22501da177e4SLinus Torvalds 	hci_req_unlock(hdev);
22511da177e4SLinus Torvalds 	hci_dev_put(hdev);
22521da177e4SLinus Torvalds 	return ret;
22531da177e4SLinus Torvalds }
22541da177e4SLinus Torvalds 
22551da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
22561da177e4SLinus Torvalds {
22571da177e4SLinus Torvalds 	struct hci_dev *hdev;
22581da177e4SLinus Torvalds 	int ret = 0;
22591da177e4SLinus Torvalds 
226070f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
226170f23020SAndrei Emeltchenko 	if (!hdev)
22621da177e4SLinus Torvalds 		return -ENODEV;
22631da177e4SLinus Torvalds 
22640736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
22650736cfa8SMarcel Holtmann 		ret = -EBUSY;
22660736cfa8SMarcel Holtmann 		goto done;
22670736cfa8SMarcel Holtmann 	}
22680736cfa8SMarcel Holtmann 
22691da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
22701da177e4SLinus Torvalds 
22710736cfa8SMarcel Holtmann done:
22721da177e4SLinus Torvalds 	hci_dev_put(hdev);
22731da177e4SLinus Torvalds 	return ret;
22741da177e4SLinus Torvalds }
22751da177e4SLinus Torvalds 
22761da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
22771da177e4SLinus Torvalds {
22781da177e4SLinus Torvalds 	struct hci_dev *hdev;
22791da177e4SLinus Torvalds 	struct hci_dev_req dr;
22801da177e4SLinus Torvalds 	int err = 0;
22811da177e4SLinus Torvalds 
22821da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
22831da177e4SLinus Torvalds 		return -EFAULT;
22841da177e4SLinus Torvalds 
228570f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
228670f23020SAndrei Emeltchenko 	if (!hdev)
22871da177e4SLinus Torvalds 		return -ENODEV;
22881da177e4SLinus Torvalds 
22890736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
22900736cfa8SMarcel Holtmann 		err = -EBUSY;
22910736cfa8SMarcel Holtmann 		goto done;
22920736cfa8SMarcel Holtmann 	}
22930736cfa8SMarcel Holtmann 
22945b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
22955b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
22965b69bef5SMarcel Holtmann 		goto done;
22975b69bef5SMarcel Holtmann 	}
22985b69bef5SMarcel Holtmann 
229956f87901SJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
230056f87901SJohan Hedberg 		err = -EOPNOTSUPP;
230156f87901SJohan Hedberg 		goto done;
230256f87901SJohan Hedberg 	}
230356f87901SJohan Hedberg 
23041da177e4SLinus Torvalds 	switch (cmd) {
23051da177e4SLinus Torvalds 	case HCISETAUTH:
230601178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
23075f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
23081da177e4SLinus Torvalds 		break;
23091da177e4SLinus Torvalds 
23101da177e4SLinus Torvalds 	case HCISETENCRYPT:
23111da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
23121da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
23131da177e4SLinus Torvalds 			break;
23141da177e4SLinus Torvalds 		}
23151da177e4SLinus Torvalds 
23161da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
23171da177e4SLinus Torvalds 			/* Auth must be enabled first */
231801178cd4SJohan Hedberg 			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
23195f246e89SAndrei Emeltchenko 					   HCI_INIT_TIMEOUT);
23201da177e4SLinus Torvalds 			if (err)
23211da177e4SLinus Torvalds 				break;
23221da177e4SLinus Torvalds 		}
23231da177e4SLinus Torvalds 
232401178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
23255f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
23261da177e4SLinus Torvalds 		break;
23271da177e4SLinus Torvalds 
23281da177e4SLinus Torvalds 	case HCISETSCAN:
232901178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
23305f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
23311da177e4SLinus Torvalds 		break;
23321da177e4SLinus Torvalds 
23331da177e4SLinus Torvalds 	case HCISETLINKPOL:
233401178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
23355f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
23361da177e4SLinus Torvalds 		break;
23371da177e4SLinus Torvalds 
23381da177e4SLinus Torvalds 	case HCISETLINKMODE:
2339e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
2340e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
2341e4e8e37cSMarcel Holtmann 		break;
2342e4e8e37cSMarcel Holtmann 
2343e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
2344e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
23451da177e4SLinus Torvalds 		break;
23461da177e4SLinus Torvalds 
23471da177e4SLinus Torvalds 	case HCISETACLMTU:
23481da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
23491da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
23501da177e4SLinus Torvalds 		break;
23511da177e4SLinus Torvalds 
23521da177e4SLinus Torvalds 	case HCISETSCOMTU:
23531da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
23541da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
23551da177e4SLinus Torvalds 		break;
23561da177e4SLinus Torvalds 
23571da177e4SLinus Torvalds 	default:
23581da177e4SLinus Torvalds 		err = -EINVAL;
23591da177e4SLinus Torvalds 		break;
23601da177e4SLinus Torvalds 	}
2361e4e8e37cSMarcel Holtmann 
23620736cfa8SMarcel Holtmann done:
23631da177e4SLinus Torvalds 	hci_dev_put(hdev);
23641da177e4SLinus Torvalds 	return err;
23651da177e4SLinus Torvalds }
23661da177e4SLinus Torvalds 
23671da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
23681da177e4SLinus Torvalds {
23698035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
23701da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
23711da177e4SLinus Torvalds 	struct hci_dev_req *dr;
23721da177e4SLinus Torvalds 	int n = 0, size, err;
23731da177e4SLinus Torvalds 	__u16 dev_num;
23741da177e4SLinus Torvalds 
23751da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
23761da177e4SLinus Torvalds 		return -EFAULT;
23771da177e4SLinus Torvalds 
23781da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
23791da177e4SLinus Torvalds 		return -EINVAL;
23801da177e4SLinus Torvalds 
23811da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
23821da177e4SLinus Torvalds 
238370f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
238470f23020SAndrei Emeltchenko 	if (!dl)
23851da177e4SLinus Torvalds 		return -ENOMEM;
23861da177e4SLinus Torvalds 
23871da177e4SLinus Torvalds 	dr = dl->dev_req;
23881da177e4SLinus Torvalds 
2389f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
23908035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
2391a8b2d5c2SJohan Hedberg 		if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
2392e0f9309fSJohan Hedberg 			cancel_delayed_work(&hdev->power_off);
2393c542a06cSJohan Hedberg 
2394a8b2d5c2SJohan Hedberg 		if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2395a8b2d5c2SJohan Hedberg 			set_bit(HCI_PAIRABLE, &hdev->dev_flags);
2396c542a06cSJohan Hedberg 
23971da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
23981da177e4SLinus Torvalds 		(dr + n)->dev_opt = hdev->flags;
2399c542a06cSJohan Hedberg 
24001da177e4SLinus Torvalds 		if (++n >= dev_num)
24011da177e4SLinus Torvalds 			break;
24021da177e4SLinus Torvalds 	}
2403f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
24041da177e4SLinus Torvalds 
24051da177e4SLinus Torvalds 	dl->dev_num = n;
24061da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
24071da177e4SLinus Torvalds 
24081da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
24091da177e4SLinus Torvalds 	kfree(dl);
24101da177e4SLinus Torvalds 
24111da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
24121da177e4SLinus Torvalds }
24131da177e4SLinus Torvalds 
24141da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
24151da177e4SLinus Torvalds {
24161da177e4SLinus Torvalds 	struct hci_dev *hdev;
24171da177e4SLinus Torvalds 	struct hci_dev_info di;
24181da177e4SLinus Torvalds 	int err = 0;
24191da177e4SLinus Torvalds 
24201da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
24211da177e4SLinus Torvalds 		return -EFAULT;
24221da177e4SLinus Torvalds 
242370f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
242470f23020SAndrei Emeltchenko 	if (!hdev)
24251da177e4SLinus Torvalds 		return -ENODEV;
24261da177e4SLinus Torvalds 
2427a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
24283243553fSJohan Hedberg 		cancel_delayed_work_sync(&hdev->power_off);
2429ab81cbf9SJohan Hedberg 
2430a8b2d5c2SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2431a8b2d5c2SJohan Hedberg 		set_bit(HCI_PAIRABLE, &hdev->dev_flags);
2432c542a06cSJohan Hedberg 
24331da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
24341da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
243560f2a3edSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4);
24361da177e4SLinus Torvalds 	di.flags    = hdev->flags;
24371da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
2438572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
24391da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
24401da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
24411da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
24421da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
2443572c7f84SJohan Hedberg 	} else {
2444572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
2445572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
2446572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
2447572c7f84SJohan Hedberg 		di.sco_pkts = 0;
2448572c7f84SJohan Hedberg 	}
24491da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
24501da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
24511da177e4SLinus Torvalds 
24521da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
24531da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
24541da177e4SLinus Torvalds 
24551da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
24561da177e4SLinus Torvalds 		err = -EFAULT;
24571da177e4SLinus Torvalds 
24581da177e4SLinus Torvalds 	hci_dev_put(hdev);
24591da177e4SLinus Torvalds 
24601da177e4SLinus Torvalds 	return err;
24611da177e4SLinus Torvalds }
24621da177e4SLinus Torvalds 
24631da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
24641da177e4SLinus Torvalds 
2465611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
2466611b30f7SMarcel Holtmann {
2467611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
2468611b30f7SMarcel Holtmann 
2469611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
2470611b30f7SMarcel Holtmann 
24710736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
24720736cfa8SMarcel Holtmann 		return -EBUSY;
24730736cfa8SMarcel Holtmann 
24745e130367SJohan Hedberg 	if (blocked) {
24755e130367SJohan Hedberg 		set_bit(HCI_RFKILLED, &hdev->dev_flags);
2476bf543036SJohan Hedberg 		if (!test_bit(HCI_SETUP, &hdev->dev_flags))
2477611b30f7SMarcel Holtmann 			hci_dev_do_close(hdev);
24785e130367SJohan Hedberg 	} else {
24795e130367SJohan Hedberg 		clear_bit(HCI_RFKILLED, &hdev->dev_flags);
24805e130367SJohan Hedberg 	}
2481611b30f7SMarcel Holtmann 
2482611b30f7SMarcel Holtmann 	return 0;
2483611b30f7SMarcel Holtmann }
2484611b30f7SMarcel Holtmann 
2485611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
2486611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
2487611b30f7SMarcel Holtmann };
2488611b30f7SMarcel Holtmann 
2489ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
2490ab81cbf9SJohan Hedberg {
2491ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
249296570ffcSJohan Hedberg 	int err;
2493ab81cbf9SJohan Hedberg 
2494ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
2495ab81cbf9SJohan Hedberg 
2496cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
249796570ffcSJohan Hedberg 	if (err < 0) {
249896570ffcSJohan Hedberg 		mgmt_set_powered_failed(hdev, err);
2499ab81cbf9SJohan Hedberg 		return;
250096570ffcSJohan Hedberg 	}
2501ab81cbf9SJohan Hedberg 
2502a5c8f270SMarcel Holtmann 	/* During the HCI setup phase, a few error conditions are
2503a5c8f270SMarcel Holtmann 	 * ignored and they need to be checked now. If they are still
2504a5c8f270SMarcel Holtmann 	 * valid, it is important to turn the device back off.
2505a5c8f270SMarcel Holtmann 	 */
2506a5c8f270SMarcel Holtmann 	if (test_bit(HCI_RFKILLED, &hdev->dev_flags) ||
2507a5c8f270SMarcel Holtmann 	    (hdev->dev_type == HCI_BREDR &&
2508a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
2509a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->static_addr, BDADDR_ANY))) {
2510bf543036SJohan Hedberg 		clear_bit(HCI_AUTO_OFF, &hdev->dev_flags);
2511bf543036SJohan Hedberg 		hci_dev_do_close(hdev);
2512bf543036SJohan Hedberg 	} else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
251319202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
251419202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
2515bf543036SJohan Hedberg 	}
2516ab81cbf9SJohan Hedberg 
2517a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags))
2518744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
2519ab81cbf9SJohan Hedberg }
2520ab81cbf9SJohan Hedberg 
2521ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
2522ab81cbf9SJohan Hedberg {
25233243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
25243243553fSJohan Hedberg 					    power_off.work);
2525ab81cbf9SJohan Hedberg 
2526ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
2527ab81cbf9SJohan Hedberg 
25288ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
2529ab81cbf9SJohan Hedberg }
2530ab81cbf9SJohan Hedberg 
253116ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
253216ab91abSJohan Hedberg {
253316ab91abSJohan Hedberg 	struct hci_dev *hdev;
253416ab91abSJohan Hedberg 
253516ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
253616ab91abSJohan Hedberg 
253716ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
253816ab91abSJohan Hedberg 
2539d1967ff8SMarcel Holtmann 	mgmt_discoverable_timeout(hdev);
254016ab91abSJohan Hedberg }
254116ab91abSJohan Hedberg 
254235f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev)
25432aeb9a1aSJohan Hedberg {
25444821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
25452aeb9a1aSJohan Hedberg 
25464821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
25474821002cSJohan Hedberg 		list_del(&uuid->list);
25482aeb9a1aSJohan Hedberg 		kfree(uuid);
25492aeb9a1aSJohan Hedberg 	}
25502aeb9a1aSJohan Hedberg }
25512aeb9a1aSJohan Hedberg 
255235f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev)
255355ed8ca1SJohan Hedberg {
255455ed8ca1SJohan Hedberg 	struct list_head *p, *n;
255555ed8ca1SJohan Hedberg 
255655ed8ca1SJohan Hedberg 	list_for_each_safe(p, n, &hdev->link_keys) {
255755ed8ca1SJohan Hedberg 		struct link_key *key;
255855ed8ca1SJohan Hedberg 
255955ed8ca1SJohan Hedberg 		key = list_entry(p, struct link_key, list);
256055ed8ca1SJohan Hedberg 
256155ed8ca1SJohan Hedberg 		list_del(p);
256255ed8ca1SJohan Hedberg 		kfree(key);
256355ed8ca1SJohan Hedberg 	}
256455ed8ca1SJohan Hedberg }
256555ed8ca1SJohan Hedberg 
256635f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev)
2567b899efafSVinicius Costa Gomes {
2568b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
2569b899efafSVinicius Costa Gomes 
2570b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
2571b899efafSVinicius Costa Gomes 		list_del(&k->list);
2572b899efafSVinicius Costa Gomes 		kfree(k);
2573b899efafSVinicius Costa Gomes 	}
2574b899efafSVinicius Costa Gomes }
2575b899efafSVinicius Costa Gomes 
2576970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev)
2577970c4e46SJohan Hedberg {
2578970c4e46SJohan Hedberg 	struct smp_irk *k, *tmp;
2579970c4e46SJohan Hedberg 
2580970c4e46SJohan Hedberg 	list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) {
2581970c4e46SJohan Hedberg 		list_del(&k->list);
2582970c4e46SJohan Hedberg 		kfree(k);
2583970c4e46SJohan Hedberg 	}
2584970c4e46SJohan Hedberg }
2585970c4e46SJohan Hedberg 
258655ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
258755ed8ca1SJohan Hedberg {
258855ed8ca1SJohan Hedberg 	struct link_key *k;
258955ed8ca1SJohan Hedberg 
25908035ded4SLuiz Augusto von Dentz 	list_for_each_entry(k, &hdev->link_keys, list)
259155ed8ca1SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0)
259255ed8ca1SJohan Hedberg 			return k;
259355ed8ca1SJohan Hedberg 
259455ed8ca1SJohan Hedberg 	return NULL;
259555ed8ca1SJohan Hedberg }
259655ed8ca1SJohan Hedberg 
2597745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
2598d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
2599d25e28abSJohan Hedberg {
2600d25e28abSJohan Hedberg 	/* Legacy key */
2601d25e28abSJohan Hedberg 	if (key_type < 0x03)
2602745c0ce3SVishal Agarwal 		return true;
2603d25e28abSJohan Hedberg 
2604d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
2605d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
2606745c0ce3SVishal Agarwal 		return false;
2607d25e28abSJohan Hedberg 
2608d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
2609d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
2610745c0ce3SVishal Agarwal 		return false;
2611d25e28abSJohan Hedberg 
2612d25e28abSJohan Hedberg 	/* Security mode 3 case */
2613d25e28abSJohan Hedberg 	if (!conn)
2614745c0ce3SVishal Agarwal 		return true;
2615d25e28abSJohan Hedberg 
2616d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
2617d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
2618745c0ce3SVishal Agarwal 		return true;
2619d25e28abSJohan Hedberg 
2620d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
2621d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
2622745c0ce3SVishal Agarwal 		return true;
2623d25e28abSJohan Hedberg 
2624d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
2625d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
2626745c0ce3SVishal Agarwal 		return true;
2627d25e28abSJohan Hedberg 
2628d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
2629d25e28abSJohan Hedberg 	 * persistently */
2630745c0ce3SVishal Agarwal 	return false;
2631d25e28abSJohan Hedberg }
2632d25e28abSJohan Hedberg 
263398a0b845SJohan Hedberg static bool ltk_type_master(u8 type)
263498a0b845SJohan Hedberg {
263598a0b845SJohan Hedberg 	if (type == HCI_SMP_STK || type == HCI_SMP_LTK)
263698a0b845SJohan Hedberg 		return true;
263798a0b845SJohan Hedberg 
263898a0b845SJohan Hedberg 	return false;
263998a0b845SJohan Hedberg }
264098a0b845SJohan Hedberg 
264198a0b845SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8],
264298a0b845SJohan Hedberg 			     bool master)
264375d262c2SVinicius Costa Gomes {
2644c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
264575d262c2SVinicius Costa Gomes 
2646c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list) {
2647c9839a11SVinicius Costa Gomes 		if (k->ediv != ediv ||
2648c9839a11SVinicius Costa Gomes 		    memcmp(rand, k->rand, sizeof(k->rand)))
264975d262c2SVinicius Costa Gomes 			continue;
265075d262c2SVinicius Costa Gomes 
265198a0b845SJohan Hedberg 		if (ltk_type_master(k->type) != master)
265298a0b845SJohan Hedberg 			continue;
265398a0b845SJohan Hedberg 
265475d262c2SVinicius Costa Gomes 		return k;
265575d262c2SVinicius Costa Gomes 	}
265675d262c2SVinicius Costa Gomes 
265775d262c2SVinicius Costa Gomes 	return NULL;
265875d262c2SVinicius Costa Gomes }
265975d262c2SVinicius Costa Gomes 
2660c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
266198a0b845SJohan Hedberg 				     u8 addr_type, bool master)
266275d262c2SVinicius Costa Gomes {
2663c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
266475d262c2SVinicius Costa Gomes 
2665c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list)
2666c9839a11SVinicius Costa Gomes 		if (addr_type == k->bdaddr_type &&
266798a0b845SJohan Hedberg 		    bacmp(bdaddr, &k->bdaddr) == 0 &&
266898a0b845SJohan Hedberg 		    ltk_type_master(k->type) == master)
266975d262c2SVinicius Costa Gomes 			return k;
267075d262c2SVinicius Costa Gomes 
267175d262c2SVinicius Costa Gomes 	return NULL;
267275d262c2SVinicius Costa Gomes }
267375d262c2SVinicius Costa Gomes 
2674970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa)
2675970c4e46SJohan Hedberg {
2676970c4e46SJohan Hedberg 	struct smp_irk *irk;
2677970c4e46SJohan Hedberg 
2678970c4e46SJohan Hedberg 	list_for_each_entry(irk, &hdev->identity_resolving_keys, list) {
2679970c4e46SJohan Hedberg 		if (!bacmp(&irk->rpa, rpa))
2680970c4e46SJohan Hedberg 			return irk;
2681970c4e46SJohan Hedberg 	}
2682970c4e46SJohan Hedberg 
2683970c4e46SJohan Hedberg 	list_for_each_entry(irk, &hdev->identity_resolving_keys, list) {
2684970c4e46SJohan Hedberg 		if (smp_irk_matches(hdev->tfm_aes, irk->val, rpa)) {
2685970c4e46SJohan Hedberg 			bacpy(&irk->rpa, rpa);
2686970c4e46SJohan Hedberg 			return irk;
2687970c4e46SJohan Hedberg 		}
2688970c4e46SJohan Hedberg 	}
2689970c4e46SJohan Hedberg 
2690970c4e46SJohan Hedberg 	return NULL;
2691970c4e46SJohan Hedberg }
2692970c4e46SJohan Hedberg 
2693970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
2694970c4e46SJohan Hedberg 				     u8 addr_type)
2695970c4e46SJohan Hedberg {
2696970c4e46SJohan Hedberg 	struct smp_irk *irk;
2697970c4e46SJohan Hedberg 
26986cfc9988SJohan Hedberg 	/* Identity Address must be public or static random */
26996cfc9988SJohan Hedberg 	if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0)
27006cfc9988SJohan Hedberg 		return NULL;
27016cfc9988SJohan Hedberg 
2702970c4e46SJohan Hedberg 	list_for_each_entry(irk, &hdev->identity_resolving_keys, list) {
2703970c4e46SJohan Hedberg 		if (addr_type == irk->addr_type &&
2704970c4e46SJohan Hedberg 		    bacmp(bdaddr, &irk->bdaddr) == 0)
2705970c4e46SJohan Hedberg 			return irk;
2706970c4e46SJohan Hedberg 	}
2707970c4e46SJohan Hedberg 
2708970c4e46SJohan Hedberg 	return NULL;
2709970c4e46SJohan Hedberg }
2710970c4e46SJohan Hedberg 
2711d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
2712d25e28abSJohan Hedberg 		     bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
271355ed8ca1SJohan Hedberg {
271455ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
2715745c0ce3SVishal Agarwal 	u8 old_key_type;
2716745c0ce3SVishal Agarwal 	bool persistent;
271755ed8ca1SJohan Hedberg 
271855ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
271955ed8ca1SJohan Hedberg 	if (old_key) {
272055ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
272155ed8ca1SJohan Hedberg 		key = old_key;
272255ed8ca1SJohan Hedberg 	} else {
272312adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
27240a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
272555ed8ca1SJohan Hedberg 		if (!key)
272655ed8ca1SJohan Hedberg 			return -ENOMEM;
272755ed8ca1SJohan Hedberg 		list_add(&key->list, &hdev->link_keys);
272855ed8ca1SJohan Hedberg 	}
272955ed8ca1SJohan Hedberg 
27306ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
273155ed8ca1SJohan Hedberg 
2732d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
2733d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
2734d25e28abSJohan Hedberg 	 * previous key */
2735d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
2736a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
2737d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
2738655fe6ecSJohan Hedberg 		if (conn)
2739655fe6ecSJohan Hedberg 			conn->key_type = type;
2740655fe6ecSJohan Hedberg 	}
2741d25e28abSJohan Hedberg 
274255ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
27439b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
274455ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
274555ed8ca1SJohan Hedberg 
2746b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
274755ed8ca1SJohan Hedberg 		key->type = old_key_type;
27484748fed2SJohan Hedberg 	else
27494748fed2SJohan Hedberg 		key->type = type;
27504748fed2SJohan Hedberg 
27514df378a1SJohan Hedberg 	if (!new_key)
27524df378a1SJohan Hedberg 		return 0;
27534df378a1SJohan Hedberg 
27544df378a1SJohan Hedberg 	persistent = hci_persistent_key(hdev, conn, type, old_key_type);
27554df378a1SJohan Hedberg 
2756744cf19eSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
27574df378a1SJohan Hedberg 
27586ec5bcadSVishal Agarwal 	if (conn)
27596ec5bcadSVishal Agarwal 		conn->flush_key = !persistent;
276055ed8ca1SJohan Hedberg 
276155ed8ca1SJohan Hedberg 	return 0;
276255ed8ca1SJohan Hedberg }
276355ed8ca1SJohan Hedberg 
2764ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
2765*35d70271SJohan Hedberg 			    u8 addr_type, u8 type, u8 authenticated,
2766*35d70271SJohan Hedberg 			    u8 tk[16], u8 enc_size, __le16 ediv, u8 rand[8])
276775d262c2SVinicius Costa Gomes {
2768c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
276998a0b845SJohan Hedberg 	bool master = ltk_type_master(type);
277075d262c2SVinicius Costa Gomes 
277198a0b845SJohan Hedberg 	old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type, master);
2772c9839a11SVinicius Costa Gomes 	if (old_key)
277375d262c2SVinicius Costa Gomes 		key = old_key;
2774c9839a11SVinicius Costa Gomes 	else {
27750a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
277675d262c2SVinicius Costa Gomes 		if (!key)
2777ca9142b8SJohan Hedberg 			return NULL;
2778c9839a11SVinicius Costa Gomes 		list_add(&key->list, &hdev->long_term_keys);
277975d262c2SVinicius Costa Gomes 	}
278075d262c2SVinicius Costa Gomes 
278175d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
2782c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
2783c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
2784c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
2785c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
2786c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
2787c9839a11SVinicius Costa Gomes 	key->type = type;
2788c9839a11SVinicius Costa Gomes 	memcpy(key->rand, rand, sizeof(key->rand));
278975d262c2SVinicius Costa Gomes 
2790ca9142b8SJohan Hedberg 	return key;
279175d262c2SVinicius Costa Gomes }
279275d262c2SVinicius Costa Gomes 
2793ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr,
2794ca9142b8SJohan Hedberg 			    u8 addr_type, u8 val[16], bdaddr_t *rpa)
2795970c4e46SJohan Hedberg {
2796970c4e46SJohan Hedberg 	struct smp_irk *irk;
2797970c4e46SJohan Hedberg 
2798970c4e46SJohan Hedberg 	irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type);
2799970c4e46SJohan Hedberg 	if (!irk) {
2800970c4e46SJohan Hedberg 		irk = kzalloc(sizeof(*irk), GFP_KERNEL);
2801970c4e46SJohan Hedberg 		if (!irk)
2802ca9142b8SJohan Hedberg 			return NULL;
2803970c4e46SJohan Hedberg 
2804970c4e46SJohan Hedberg 		bacpy(&irk->bdaddr, bdaddr);
2805970c4e46SJohan Hedberg 		irk->addr_type = addr_type;
2806970c4e46SJohan Hedberg 
2807970c4e46SJohan Hedberg 		list_add(&irk->list, &hdev->identity_resolving_keys);
2808970c4e46SJohan Hedberg 	}
2809970c4e46SJohan Hedberg 
2810970c4e46SJohan Hedberg 	memcpy(irk->val, val, 16);
2811970c4e46SJohan Hedberg 	bacpy(&irk->rpa, rpa);
2812970c4e46SJohan Hedberg 
2813ca9142b8SJohan Hedberg 	return irk;
2814970c4e46SJohan Hedberg }
2815970c4e46SJohan Hedberg 
281655ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
281755ed8ca1SJohan Hedberg {
281855ed8ca1SJohan Hedberg 	struct link_key *key;
281955ed8ca1SJohan Hedberg 
282055ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
282155ed8ca1SJohan Hedberg 	if (!key)
282255ed8ca1SJohan Hedberg 		return -ENOENT;
282355ed8ca1SJohan Hedberg 
28246ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
282555ed8ca1SJohan Hedberg 
282655ed8ca1SJohan Hedberg 	list_del(&key->list);
282755ed8ca1SJohan Hedberg 	kfree(key);
282855ed8ca1SJohan Hedberg 
282955ed8ca1SJohan Hedberg 	return 0;
283055ed8ca1SJohan Hedberg }
283155ed8ca1SJohan Hedberg 
2832e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type)
2833b899efafSVinicius Costa Gomes {
2834b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
2835c51ffa0bSJohan Hedberg 	int removed = 0;
2836b899efafSVinicius Costa Gomes 
2837b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
2838e0b2b27eSJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type)
2839b899efafSVinicius Costa Gomes 			continue;
2840b899efafSVinicius Costa Gomes 
28416ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
2842b899efafSVinicius Costa Gomes 
2843b899efafSVinicius Costa Gomes 		list_del(&k->list);
2844b899efafSVinicius Costa Gomes 		kfree(k);
2845c51ffa0bSJohan Hedberg 		removed++;
2846b899efafSVinicius Costa Gomes 	}
2847b899efafSVinicius Costa Gomes 
2848c51ffa0bSJohan Hedberg 	return removed ? 0 : -ENOENT;
2849b899efafSVinicius Costa Gomes }
2850b899efafSVinicius Costa Gomes 
2851a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type)
2852a7ec7338SJohan Hedberg {
2853a7ec7338SJohan Hedberg 	struct smp_irk *k, *tmp;
2854a7ec7338SJohan Hedberg 
2855a7ec7338SJohan Hedberg 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
2856a7ec7338SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type)
2857a7ec7338SJohan Hedberg 			continue;
2858a7ec7338SJohan Hedberg 
2859a7ec7338SJohan Hedberg 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
2860a7ec7338SJohan Hedberg 
2861a7ec7338SJohan Hedberg 		list_del(&k->list);
2862a7ec7338SJohan Hedberg 		kfree(k);
2863a7ec7338SJohan Hedberg 	}
2864a7ec7338SJohan Hedberg }
2865a7ec7338SJohan Hedberg 
28666bd32326SVille Tervo /* HCI command timer function */
2867bda4f23aSAndrei Emeltchenko static void hci_cmd_timeout(unsigned long arg)
28686bd32326SVille Tervo {
28696bd32326SVille Tervo 	struct hci_dev *hdev = (void *) arg;
28706bd32326SVille Tervo 
2871bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
2872bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
2873bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
2874bda4f23aSAndrei Emeltchenko 
2875bda4f23aSAndrei Emeltchenko 		BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode);
2876bda4f23aSAndrei Emeltchenko 	} else {
28776bd32326SVille Tervo 		BT_ERR("%s command tx timeout", hdev->name);
2878bda4f23aSAndrei Emeltchenko 	}
2879bda4f23aSAndrei Emeltchenko 
28806bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
2881c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
28826bd32326SVille Tervo }
28836bd32326SVille Tervo 
28842763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
28852763eda6SSzymon Janc 					  bdaddr_t *bdaddr)
28862763eda6SSzymon Janc {
28872763eda6SSzymon Janc 	struct oob_data *data;
28882763eda6SSzymon Janc 
28892763eda6SSzymon Janc 	list_for_each_entry(data, &hdev->remote_oob_data, list)
28902763eda6SSzymon Janc 		if (bacmp(bdaddr, &data->bdaddr) == 0)
28912763eda6SSzymon Janc 			return data;
28922763eda6SSzymon Janc 
28932763eda6SSzymon Janc 	return NULL;
28942763eda6SSzymon Janc }
28952763eda6SSzymon Janc 
28962763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
28972763eda6SSzymon Janc {
28982763eda6SSzymon Janc 	struct oob_data *data;
28992763eda6SSzymon Janc 
29002763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
29012763eda6SSzymon Janc 	if (!data)
29022763eda6SSzymon Janc 		return -ENOENT;
29032763eda6SSzymon Janc 
29046ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
29052763eda6SSzymon Janc 
29062763eda6SSzymon Janc 	list_del(&data->list);
29072763eda6SSzymon Janc 	kfree(data);
29082763eda6SSzymon Janc 
29092763eda6SSzymon Janc 	return 0;
29102763eda6SSzymon Janc }
29112763eda6SSzymon Janc 
291235f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev)
29132763eda6SSzymon Janc {
29142763eda6SSzymon Janc 	struct oob_data *data, *n;
29152763eda6SSzymon Janc 
29162763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
29172763eda6SSzymon Janc 		list_del(&data->list);
29182763eda6SSzymon Janc 		kfree(data);
29192763eda6SSzymon Janc 	}
29202763eda6SSzymon Janc }
29212763eda6SSzymon Janc 
29220798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
29230798872eSMarcel Holtmann 			    u8 *hash, u8 *randomizer)
29242763eda6SSzymon Janc {
29252763eda6SSzymon Janc 	struct oob_data *data;
29262763eda6SSzymon Janc 
29272763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
29282763eda6SSzymon Janc 	if (!data) {
29290a14ab41SJohan Hedberg 		data = kmalloc(sizeof(*data), GFP_KERNEL);
29302763eda6SSzymon Janc 		if (!data)
29312763eda6SSzymon Janc 			return -ENOMEM;
29322763eda6SSzymon Janc 
29332763eda6SSzymon Janc 		bacpy(&data->bdaddr, bdaddr);
29342763eda6SSzymon Janc 		list_add(&data->list, &hdev->remote_oob_data);
29352763eda6SSzymon Janc 	}
29362763eda6SSzymon Janc 
2937519ca9d0SMarcel Holtmann 	memcpy(data->hash192, hash, sizeof(data->hash192));
2938519ca9d0SMarcel Holtmann 	memcpy(data->randomizer192, randomizer, sizeof(data->randomizer192));
29392763eda6SSzymon Janc 
29400798872eSMarcel Holtmann 	memset(data->hash256, 0, sizeof(data->hash256));
29410798872eSMarcel Holtmann 	memset(data->randomizer256, 0, sizeof(data->randomizer256));
29420798872eSMarcel Holtmann 
29430798872eSMarcel Holtmann 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
29440798872eSMarcel Holtmann 
29450798872eSMarcel Holtmann 	return 0;
29460798872eSMarcel Holtmann }
29470798872eSMarcel Holtmann 
29480798872eSMarcel Holtmann int hci_add_remote_oob_ext_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
29490798872eSMarcel Holtmann 				u8 *hash192, u8 *randomizer192,
29500798872eSMarcel Holtmann 				u8 *hash256, u8 *randomizer256)
29510798872eSMarcel Holtmann {
29520798872eSMarcel Holtmann 	struct oob_data *data;
29530798872eSMarcel Holtmann 
29540798872eSMarcel Holtmann 	data = hci_find_remote_oob_data(hdev, bdaddr);
29550798872eSMarcel Holtmann 	if (!data) {
29560a14ab41SJohan Hedberg 		data = kmalloc(sizeof(*data), GFP_KERNEL);
29570798872eSMarcel Holtmann 		if (!data)
29580798872eSMarcel Holtmann 			return -ENOMEM;
29590798872eSMarcel Holtmann 
29600798872eSMarcel Holtmann 		bacpy(&data->bdaddr, bdaddr);
29610798872eSMarcel Holtmann 		list_add(&data->list, &hdev->remote_oob_data);
29620798872eSMarcel Holtmann 	}
29630798872eSMarcel Holtmann 
29640798872eSMarcel Holtmann 	memcpy(data->hash192, hash192, sizeof(data->hash192));
29650798872eSMarcel Holtmann 	memcpy(data->randomizer192, randomizer192, sizeof(data->randomizer192));
29660798872eSMarcel Holtmann 
29670798872eSMarcel Holtmann 	memcpy(data->hash256, hash256, sizeof(data->hash256));
29680798872eSMarcel Holtmann 	memcpy(data->randomizer256, randomizer256, sizeof(data->randomizer256));
29690798872eSMarcel Holtmann 
29706ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
29712763eda6SSzymon Janc 
29722763eda6SSzymon Janc 	return 0;
29732763eda6SSzymon Janc }
29742763eda6SSzymon Janc 
2975b9ee0a78SMarcel Holtmann struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev,
2976b9ee0a78SMarcel Holtmann 					 bdaddr_t *bdaddr, u8 type)
2977b2a66aadSAntti Julku {
2978b2a66aadSAntti Julku 	struct bdaddr_list *b;
2979b2a66aadSAntti Julku 
2980b9ee0a78SMarcel Holtmann 	list_for_each_entry(b, &hdev->blacklist, list) {
2981b9ee0a78SMarcel Holtmann 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
2982b2a66aadSAntti Julku 			return b;
2983b9ee0a78SMarcel Holtmann 	}
2984b2a66aadSAntti Julku 
2985b2a66aadSAntti Julku 	return NULL;
2986b2a66aadSAntti Julku }
2987b2a66aadSAntti Julku 
298835f7498aSJohan Hedberg void hci_blacklist_clear(struct hci_dev *hdev)
2989b2a66aadSAntti Julku {
2990b2a66aadSAntti Julku 	struct list_head *p, *n;
2991b2a66aadSAntti Julku 
2992b2a66aadSAntti Julku 	list_for_each_safe(p, n, &hdev->blacklist) {
2993b9ee0a78SMarcel Holtmann 		struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list);
2994b2a66aadSAntti Julku 
2995b2a66aadSAntti Julku 		list_del(p);
2996b2a66aadSAntti Julku 		kfree(b);
2997b2a66aadSAntti Julku 	}
2998b2a66aadSAntti Julku }
2999b2a66aadSAntti Julku 
300088c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3001b2a66aadSAntti Julku {
3002b2a66aadSAntti Julku 	struct bdaddr_list *entry;
3003b2a66aadSAntti Julku 
3004b9ee0a78SMarcel Holtmann 	if (!bacmp(bdaddr, BDADDR_ANY))
3005b2a66aadSAntti Julku 		return -EBADF;
3006b2a66aadSAntti Julku 
3007b9ee0a78SMarcel Holtmann 	if (hci_blacklist_lookup(hdev, bdaddr, type))
30085e762444SAntti Julku 		return -EEXIST;
3009b2a66aadSAntti Julku 
3010b2a66aadSAntti Julku 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
30115e762444SAntti Julku 	if (!entry)
30125e762444SAntti Julku 		return -ENOMEM;
3013b2a66aadSAntti Julku 
3014b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
3015b9ee0a78SMarcel Holtmann 	entry->bdaddr_type = type;
3016b2a66aadSAntti Julku 
3017b2a66aadSAntti Julku 	list_add(&entry->list, &hdev->blacklist);
3018b2a66aadSAntti Julku 
301988c1fe4bSJohan Hedberg 	return mgmt_device_blocked(hdev, bdaddr, type);
3020b2a66aadSAntti Julku }
3021b2a66aadSAntti Julku 
302288c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3023b2a66aadSAntti Julku {
3024b2a66aadSAntti Julku 	struct bdaddr_list *entry;
3025b2a66aadSAntti Julku 
302635f7498aSJohan Hedberg 	if (!bacmp(bdaddr, BDADDR_ANY)) {
302735f7498aSJohan Hedberg 		hci_blacklist_clear(hdev);
302835f7498aSJohan Hedberg 		return 0;
302935f7498aSJohan Hedberg 	}
3030b2a66aadSAntti Julku 
3031b9ee0a78SMarcel Holtmann 	entry = hci_blacklist_lookup(hdev, bdaddr, type);
30321ec918ceSSzymon Janc 	if (!entry)
30335e762444SAntti Julku 		return -ENOENT;
3034b2a66aadSAntti Julku 
3035b2a66aadSAntti Julku 	list_del(&entry->list);
3036b2a66aadSAntti Julku 	kfree(entry);
3037b2a66aadSAntti Julku 
303888c1fe4bSJohan Hedberg 	return mgmt_device_unblocked(hdev, bdaddr, type);
3039b2a66aadSAntti Julku }
3040b2a66aadSAntti Julku 
304115819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
304215819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
304315819a70SAndre Guedes 					       bdaddr_t *addr, u8 addr_type)
304415819a70SAndre Guedes {
304515819a70SAndre Guedes 	struct hci_conn_params *params;
304615819a70SAndre Guedes 
304715819a70SAndre Guedes 	list_for_each_entry(params, &hdev->le_conn_params, list) {
304815819a70SAndre Guedes 		if (bacmp(&params->addr, addr) == 0 &&
304915819a70SAndre Guedes 		    params->addr_type == addr_type) {
305015819a70SAndre Guedes 			return params;
305115819a70SAndre Guedes 		}
305215819a70SAndre Guedes 	}
305315819a70SAndre Guedes 
305415819a70SAndre Guedes 	return NULL;
305515819a70SAndre Guedes }
305615819a70SAndre Guedes 
305715819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
305815819a70SAndre Guedes void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
305915819a70SAndre Guedes 			 u16 conn_min_interval, u16 conn_max_interval)
306015819a70SAndre Guedes {
306115819a70SAndre Guedes 	struct hci_conn_params *params;
306215819a70SAndre Guedes 
306315819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
306415819a70SAndre Guedes 	if (params) {
306515819a70SAndre Guedes 		params->conn_min_interval = conn_min_interval;
306615819a70SAndre Guedes 		params->conn_max_interval = conn_max_interval;
306715819a70SAndre Guedes 		return;
306815819a70SAndre Guedes 	}
306915819a70SAndre Guedes 
307015819a70SAndre Guedes 	params = kzalloc(sizeof(*params), GFP_KERNEL);
307115819a70SAndre Guedes 	if (!params) {
307215819a70SAndre Guedes 		BT_ERR("Out of memory");
307315819a70SAndre Guedes 		return;
307415819a70SAndre Guedes 	}
307515819a70SAndre Guedes 
307615819a70SAndre Guedes 	bacpy(&params->addr, addr);
307715819a70SAndre Guedes 	params->addr_type = addr_type;
307815819a70SAndre Guedes 	params->conn_min_interval = conn_min_interval;
307915819a70SAndre Guedes 	params->conn_max_interval = conn_max_interval;
308015819a70SAndre Guedes 
308115819a70SAndre Guedes 	list_add(&params->list, &hdev->le_conn_params);
308215819a70SAndre Guedes 
308315819a70SAndre Guedes 	BT_DBG("addr %pMR (type %u) conn_min_interval 0x%.4x "
308415819a70SAndre Guedes 	       "conn_max_interval 0x%.4x", addr, addr_type, conn_min_interval,
308515819a70SAndre Guedes 	       conn_max_interval);
308615819a70SAndre Guedes }
308715819a70SAndre Guedes 
308815819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
308915819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
309015819a70SAndre Guedes {
309115819a70SAndre Guedes 	struct hci_conn_params *params;
309215819a70SAndre Guedes 
309315819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
309415819a70SAndre Guedes 	if (!params)
309515819a70SAndre Guedes 		return;
309615819a70SAndre Guedes 
309715819a70SAndre Guedes 	list_del(&params->list);
309815819a70SAndre Guedes 	kfree(params);
309915819a70SAndre Guedes 
310015819a70SAndre Guedes 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
310115819a70SAndre Guedes }
310215819a70SAndre Guedes 
310315819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
310415819a70SAndre Guedes void hci_conn_params_clear(struct hci_dev *hdev)
310515819a70SAndre Guedes {
310615819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
310715819a70SAndre Guedes 
310815819a70SAndre Guedes 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
310915819a70SAndre Guedes 		list_del(&params->list);
311015819a70SAndre Guedes 		kfree(params);
311115819a70SAndre Guedes 	}
311215819a70SAndre Guedes 
311315819a70SAndre Guedes 	BT_DBG("All LE connection parameters were removed");
311415819a70SAndre Guedes }
311515819a70SAndre Guedes 
31164c87eaabSAndre Guedes static void inquiry_complete(struct hci_dev *hdev, u8 status)
31177ba8b4beSAndre Guedes {
31184c87eaabSAndre Guedes 	if (status) {
31194c87eaabSAndre Guedes 		BT_ERR("Failed to start inquiry: status %d", status);
31207ba8b4beSAndre Guedes 
31214c87eaabSAndre Guedes 		hci_dev_lock(hdev);
31224c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
31234c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
31244c87eaabSAndre Guedes 		return;
31254c87eaabSAndre Guedes 	}
31267ba8b4beSAndre Guedes }
31277ba8b4beSAndre Guedes 
31284c87eaabSAndre Guedes static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status)
31297ba8b4beSAndre Guedes {
31304c87eaabSAndre Guedes 	/* General inquiry access code (GIAC) */
31314c87eaabSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
31324c87eaabSAndre Guedes 	struct hci_request req;
31334c87eaabSAndre Guedes 	struct hci_cp_inquiry cp;
31347ba8b4beSAndre Guedes 	int err;
31357ba8b4beSAndre Guedes 
31364c87eaabSAndre Guedes 	if (status) {
31374c87eaabSAndre Guedes 		BT_ERR("Failed to disable LE scanning: status %d", status);
31384c87eaabSAndre Guedes 		return;
31397ba8b4beSAndre Guedes 	}
31407ba8b4beSAndre Guedes 
31414c87eaabSAndre Guedes 	switch (hdev->discovery.type) {
31424c87eaabSAndre Guedes 	case DISCOV_TYPE_LE:
31434c87eaabSAndre Guedes 		hci_dev_lock(hdev);
31444c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
31454c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
31464c87eaabSAndre Guedes 		break;
31477dbfac1dSAndre Guedes 
31484c87eaabSAndre Guedes 	case DISCOV_TYPE_INTERLEAVED:
31494c87eaabSAndre Guedes 		hci_req_init(&req, hdev);
31507dbfac1dSAndre Guedes 
31517dbfac1dSAndre Guedes 		memset(&cp, 0, sizeof(cp));
31524c87eaabSAndre Guedes 		memcpy(&cp.lap, lap, sizeof(cp.lap));
31534c87eaabSAndre Guedes 		cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN;
31544c87eaabSAndre Guedes 		hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp);
31554c87eaabSAndre Guedes 
31564c87eaabSAndre Guedes 		hci_dev_lock(hdev);
31574c87eaabSAndre Guedes 
31584c87eaabSAndre Guedes 		hci_inquiry_cache_flush(hdev);
31594c87eaabSAndre Guedes 
31604c87eaabSAndre Guedes 		err = hci_req_run(&req, inquiry_complete);
31614c87eaabSAndre Guedes 		if (err) {
31624c87eaabSAndre Guedes 			BT_ERR("Inquiry request failed: err %d", err);
31634c87eaabSAndre Guedes 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
31647dbfac1dSAndre Guedes 		}
31657dbfac1dSAndre Guedes 
31664c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
31674c87eaabSAndre Guedes 		break;
31684c87eaabSAndre Guedes 	}
31697dbfac1dSAndre Guedes }
31707dbfac1dSAndre Guedes 
31717ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work)
31727ba8b4beSAndre Guedes {
31737ba8b4beSAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev,
31747ba8b4beSAndre Guedes 					    le_scan_disable.work);
31757ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
31764c87eaabSAndre Guedes 	struct hci_request req;
31774c87eaabSAndre Guedes 	int err;
31787ba8b4beSAndre Guedes 
31797ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
31807ba8b4beSAndre Guedes 
31814c87eaabSAndre Guedes 	hci_req_init(&req, hdev);
31827ba8b4beSAndre Guedes 
31837ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
31844c87eaabSAndre Guedes 	cp.enable = LE_SCAN_DISABLE;
31854c87eaabSAndre Guedes 	hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
31867ba8b4beSAndre Guedes 
31874c87eaabSAndre Guedes 	err = hci_req_run(&req, le_scan_disable_work_complete);
31884c87eaabSAndre Guedes 	if (err)
31894c87eaabSAndre Guedes 		BT_ERR("Disable LE scanning request failed: err %d", err);
319028b75a89SAndre Guedes }
319128b75a89SAndre Guedes 
31929be0dab7SDavid Herrmann /* Alloc HCI device */
31939be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void)
31949be0dab7SDavid Herrmann {
31959be0dab7SDavid Herrmann 	struct hci_dev *hdev;
31969be0dab7SDavid Herrmann 
31979be0dab7SDavid Herrmann 	hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
31989be0dab7SDavid Herrmann 	if (!hdev)
31999be0dab7SDavid Herrmann 		return NULL;
32009be0dab7SDavid Herrmann 
3201b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
3202b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
3203b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
3204b4cb9fb2SMarcel Holtmann 	hdev->num_iac = 0x01;		/* One IAC support is mandatory */
3205b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03;	/* No Input No Output */
3206bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
3207bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
3208b1b813d4SDavid Herrmann 
3209b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
3210b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
3211b1b813d4SDavid Herrmann 
3212bef64738SMarcel Holtmann 	hdev->le_scan_interval = 0x0060;
3213bef64738SMarcel Holtmann 	hdev->le_scan_window = 0x0030;
32144e70c7e7SMarcel Holtmann 	hdev->le_conn_min_interval = 0x0028;
32154e70c7e7SMarcel Holtmann 	hdev->le_conn_max_interval = 0x0038;
3216bef64738SMarcel Holtmann 
3217b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
3218b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
3219b1b813d4SDavid Herrmann 
3220b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
3221b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->blacklist);
3222b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
3223b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
3224b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
3225970c4e46SJohan Hedberg 	INIT_LIST_HEAD(&hdev->identity_resolving_keys);
3226b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
322715819a70SAndre Guedes 	INIT_LIST_HEAD(&hdev->le_conn_params);
32286b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
3229b1b813d4SDavid Herrmann 
3230b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
3231b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
3232b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
3233b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
3234b1b813d4SDavid Herrmann 
3235b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
3236b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
3237b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
3238b1b813d4SDavid Herrmann 
3239b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
3240b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
3241b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
3242b1b813d4SDavid Herrmann 
3243b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
3244b1b813d4SDavid Herrmann 
3245bda4f23aSAndrei Emeltchenko 	setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev);
3246b1b813d4SDavid Herrmann 
3247b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
3248b1b813d4SDavid Herrmann 	discovery_init(hdev);
32499be0dab7SDavid Herrmann 
32509be0dab7SDavid Herrmann 	return hdev;
32519be0dab7SDavid Herrmann }
32529be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev);
32539be0dab7SDavid Herrmann 
32549be0dab7SDavid Herrmann /* Free HCI device */
32559be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
32569be0dab7SDavid Herrmann {
32579be0dab7SDavid Herrmann 	/* will free via device release */
32589be0dab7SDavid Herrmann 	put_device(&hdev->dev);
32599be0dab7SDavid Herrmann }
32609be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
32619be0dab7SDavid Herrmann 
32621da177e4SLinus Torvalds /* Register HCI device */
32631da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
32641da177e4SLinus Torvalds {
3265b1b813d4SDavid Herrmann 	int id, error;
32661da177e4SLinus Torvalds 
3267010666a1SDavid Herrmann 	if (!hdev->open || !hdev->close)
32681da177e4SLinus Torvalds 		return -EINVAL;
32691da177e4SLinus Torvalds 
327008add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
327108add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
327208add513SMat Martineau 	 */
32733df92b31SSasha Levin 	switch (hdev->dev_type) {
32743df92b31SSasha Levin 	case HCI_BREDR:
32753df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
32761da177e4SLinus Torvalds 		break;
32773df92b31SSasha Levin 	case HCI_AMP:
32783df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
32793df92b31SSasha Levin 		break;
32803df92b31SSasha Levin 	default:
32813df92b31SSasha Levin 		return -EINVAL;
32821da177e4SLinus Torvalds 	}
32831da177e4SLinus Torvalds 
32843df92b31SSasha Levin 	if (id < 0)
32853df92b31SSasha Levin 		return id;
32863df92b31SSasha Levin 
32871da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
32881da177e4SLinus Torvalds 	hdev->id = id;
32892d8b3a11SAndrei Emeltchenko 
32902d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
32912d8b3a11SAndrei Emeltchenko 
3292d8537548SKees Cook 	hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
3293d8537548SKees Cook 					  WQ_MEM_RECLAIM, 1, hdev->name);
329433ca954dSDavid Herrmann 	if (!hdev->workqueue) {
329533ca954dSDavid Herrmann 		error = -ENOMEM;
329633ca954dSDavid Herrmann 		goto err;
329733ca954dSDavid Herrmann 	}
3298f48fd9c8SMarcel Holtmann 
3299d8537548SKees Cook 	hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
3300d8537548SKees Cook 					      WQ_MEM_RECLAIM, 1, hdev->name);
33016ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
33026ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
33036ead1bbcSJohan Hedberg 		error = -ENOMEM;
33046ead1bbcSJohan Hedberg 		goto err;
33056ead1bbcSJohan Hedberg 	}
33066ead1bbcSJohan Hedberg 
33070153e2ecSMarcel Holtmann 	if (!IS_ERR_OR_NULL(bt_debugfs))
33080153e2ecSMarcel Holtmann 		hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs);
33090153e2ecSMarcel Holtmann 
3310bdc3e0f1SMarcel Holtmann 	dev_set_name(&hdev->dev, "%s", hdev->name);
3311bdc3e0f1SMarcel Holtmann 
331299780a7bSJohan Hedberg 	hdev->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0,
331399780a7bSJohan Hedberg 					       CRYPTO_ALG_ASYNC);
331499780a7bSJohan Hedberg 	if (IS_ERR(hdev->tfm_aes)) {
331599780a7bSJohan Hedberg 		BT_ERR("Unable to create crypto context");
331699780a7bSJohan Hedberg 		error = PTR_ERR(hdev->tfm_aes);
331799780a7bSJohan Hedberg 		hdev->tfm_aes = NULL;
331899780a7bSJohan Hedberg 		goto err_wqueue;
331999780a7bSJohan Hedberg 	}
332099780a7bSJohan Hedberg 
3321bdc3e0f1SMarcel Holtmann 	error = device_add(&hdev->dev);
332233ca954dSDavid Herrmann 	if (error < 0)
332399780a7bSJohan Hedberg 		goto err_tfm;
33241da177e4SLinus Torvalds 
3325611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
3326a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
3327a8c5fb1aSGustavo Padovan 				    hdev);
3328611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
3329611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
3330611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
3331611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
3332611b30f7SMarcel Holtmann 		}
3333611b30f7SMarcel Holtmann 	}
3334611b30f7SMarcel Holtmann 
33355e130367SJohan Hedberg 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill))
33365e130367SJohan Hedberg 		set_bit(HCI_RFKILLED, &hdev->dev_flags);
33375e130367SJohan Hedberg 
3338a8b2d5c2SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->dev_flags);
3339004b0258SMarcel Holtmann 	set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
3340ce2be9acSAndrei Emeltchenko 
334101cd3404SMarcel Holtmann 	if (hdev->dev_type == HCI_BREDR) {
334256f87901SJohan Hedberg 		/* Assume BR/EDR support until proven otherwise (such as
334356f87901SJohan Hedberg 		 * through reading supported features during init.
334456f87901SJohan Hedberg 		 */
334556f87901SJohan Hedberg 		set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
334656f87901SJohan Hedberg 	}
3347ce2be9acSAndrei Emeltchenko 
3348fcee3377SGustavo Padovan 	write_lock(&hci_dev_list_lock);
3349fcee3377SGustavo Padovan 	list_add(&hdev->list, &hci_dev_list);
3350fcee3377SGustavo Padovan 	write_unlock(&hci_dev_list_lock);
3351fcee3377SGustavo Padovan 
33521da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
3353dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
33541da177e4SLinus Torvalds 
335519202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
3356fbe96d6fSMarcel Holtmann 
33571da177e4SLinus Torvalds 	return id;
3358f48fd9c8SMarcel Holtmann 
335999780a7bSJohan Hedberg err_tfm:
336099780a7bSJohan Hedberg 	crypto_free_blkcipher(hdev->tfm_aes);
336133ca954dSDavid Herrmann err_wqueue:
336233ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
33636ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
336433ca954dSDavid Herrmann err:
33653df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
3366f48fd9c8SMarcel Holtmann 
336733ca954dSDavid Herrmann 	return error;
33681da177e4SLinus Torvalds }
33691da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
33701da177e4SLinus Torvalds 
33711da177e4SLinus Torvalds /* Unregister HCI device */
337259735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
33731da177e4SLinus Torvalds {
33743df92b31SSasha Levin 	int i, id;
3375ef222013SMarcel Holtmann 
3376c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
33771da177e4SLinus Torvalds 
337894324962SJohan Hovold 	set_bit(HCI_UNREGISTER, &hdev->dev_flags);
337994324962SJohan Hovold 
33803df92b31SSasha Levin 	id = hdev->id;
33813df92b31SSasha Levin 
3382f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
33831da177e4SLinus Torvalds 	list_del(&hdev->list);
3384f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
33851da177e4SLinus Torvalds 
33861da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
33871da177e4SLinus Torvalds 
3388cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
3389ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
3390ef222013SMarcel Holtmann 
3391b9b5ef18SGustavo Padovan 	cancel_work_sync(&hdev->power_on);
3392b9b5ef18SGustavo Padovan 
3393ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
3394a8b2d5c2SJohan Hedberg 	    !test_bit(HCI_SETUP, &hdev->dev_flags)) {
339509fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
3396744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
339709fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
339856e5cb86SJohan Hedberg 	}
3399ab81cbf9SJohan Hedberg 
34002e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
34012e58ef3eSJohan Hedberg 	 * pending list */
34022e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
34032e58ef3eSJohan Hedberg 
34041da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
34051da177e4SLinus Torvalds 
3406611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
3407611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
3408611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
3409611b30f7SMarcel Holtmann 	}
3410611b30f7SMarcel Holtmann 
341199780a7bSJohan Hedberg 	if (hdev->tfm_aes)
341299780a7bSJohan Hedberg 		crypto_free_blkcipher(hdev->tfm_aes);
341399780a7bSJohan Hedberg 
3414bdc3e0f1SMarcel Holtmann 	device_del(&hdev->dev);
3415147e2d59SDave Young 
34160153e2ecSMarcel Holtmann 	debugfs_remove_recursive(hdev->debugfs);
34170153e2ecSMarcel Holtmann 
3418f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
34196ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
3420f48fd9c8SMarcel Holtmann 
342109fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
3422e2e0cacbSJohan Hedberg 	hci_blacklist_clear(hdev);
34232aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
342455ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
3425b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
3426970c4e46SJohan Hedberg 	hci_smp_irks_clear(hdev);
34272763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
342815819a70SAndre Guedes 	hci_conn_params_clear(hdev);
342909fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
3430e2e0cacbSJohan Hedberg 
3431dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
34323df92b31SSasha Levin 
34333df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, id);
34341da177e4SLinus Torvalds }
34351da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
34361da177e4SLinus Torvalds 
34371da177e4SLinus Torvalds /* Suspend HCI device */
34381da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
34391da177e4SLinus Torvalds {
34401da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
34411da177e4SLinus Torvalds 	return 0;
34421da177e4SLinus Torvalds }
34431da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
34441da177e4SLinus Torvalds 
34451da177e4SLinus Torvalds /* Resume HCI device */
34461da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
34471da177e4SLinus Torvalds {
34481da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
34491da177e4SLinus Torvalds 	return 0;
34501da177e4SLinus Torvalds }
34511da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
34521da177e4SLinus Torvalds 
345376bca880SMarcel Holtmann /* Receive frame from HCI drivers */
3454e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
345576bca880SMarcel Holtmann {
345676bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
345776bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
345876bca880SMarcel Holtmann 		kfree_skb(skb);
345976bca880SMarcel Holtmann 		return -ENXIO;
346076bca880SMarcel Holtmann 	}
346176bca880SMarcel Holtmann 
3462d82603c6SJorrit Schippers 	/* Incoming skb */
346376bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
346476bca880SMarcel Holtmann 
346576bca880SMarcel Holtmann 	/* Time stamp */
346676bca880SMarcel Holtmann 	__net_timestamp(skb);
346776bca880SMarcel Holtmann 
346876bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
3469b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
3470c78ae283SMarcel Holtmann 
347176bca880SMarcel Holtmann 	return 0;
347276bca880SMarcel Holtmann }
347376bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
347476bca880SMarcel Holtmann 
347533e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
34761e429f38SGustavo F. Padovan 			  int count, __u8 index)
347733e882a5SSuraj Sumangala {
347833e882a5SSuraj Sumangala 	int len = 0;
347933e882a5SSuraj Sumangala 	int hlen = 0;
348033e882a5SSuraj Sumangala 	int remain = count;
348133e882a5SSuraj Sumangala 	struct sk_buff *skb;
348233e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
348333e882a5SSuraj Sumangala 
348433e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
348533e882a5SSuraj Sumangala 	    index >= NUM_REASSEMBLY)
348633e882a5SSuraj Sumangala 		return -EILSEQ;
348733e882a5SSuraj Sumangala 
348833e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
348933e882a5SSuraj Sumangala 
349033e882a5SSuraj Sumangala 	if (!skb) {
349133e882a5SSuraj Sumangala 		switch (type) {
349233e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
349333e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
349433e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
349533e882a5SSuraj Sumangala 			break;
349633e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
349733e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
349833e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
349933e882a5SSuraj Sumangala 			break;
350033e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
350133e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
350233e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
350333e882a5SSuraj Sumangala 			break;
350433e882a5SSuraj Sumangala 		}
350533e882a5SSuraj Sumangala 
35061e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
350733e882a5SSuraj Sumangala 		if (!skb)
350833e882a5SSuraj Sumangala 			return -ENOMEM;
350933e882a5SSuraj Sumangala 
351033e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
351133e882a5SSuraj Sumangala 		scb->expect = hlen;
351233e882a5SSuraj Sumangala 		scb->pkt_type = type;
351333e882a5SSuraj Sumangala 
351433e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
351533e882a5SSuraj Sumangala 	}
351633e882a5SSuraj Sumangala 
351733e882a5SSuraj Sumangala 	while (count) {
351833e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
351989bb46d0SDan Carpenter 		len = min_t(uint, scb->expect, count);
352033e882a5SSuraj Sumangala 
352133e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
352233e882a5SSuraj Sumangala 
352333e882a5SSuraj Sumangala 		count -= len;
352433e882a5SSuraj Sumangala 		data += len;
352533e882a5SSuraj Sumangala 		scb->expect -= len;
352633e882a5SSuraj Sumangala 		remain = count;
352733e882a5SSuraj Sumangala 
352833e882a5SSuraj Sumangala 		switch (type) {
352933e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
353033e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
353133e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
353233e882a5SSuraj Sumangala 				scb->expect = h->plen;
353333e882a5SSuraj Sumangala 
353433e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
353533e882a5SSuraj Sumangala 					kfree_skb(skb);
353633e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
353733e882a5SSuraj Sumangala 					return -ENOMEM;
353833e882a5SSuraj Sumangala 				}
353933e882a5SSuraj Sumangala 			}
354033e882a5SSuraj Sumangala 			break;
354133e882a5SSuraj Sumangala 
354233e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
354333e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
354433e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
354533e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
354633e882a5SSuraj Sumangala 
354733e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
354833e882a5SSuraj Sumangala 					kfree_skb(skb);
354933e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
355033e882a5SSuraj Sumangala 					return -ENOMEM;
355133e882a5SSuraj Sumangala 				}
355233e882a5SSuraj Sumangala 			}
355333e882a5SSuraj Sumangala 			break;
355433e882a5SSuraj Sumangala 
355533e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
355633e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
355733e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
355833e882a5SSuraj Sumangala 				scb->expect = h->dlen;
355933e882a5SSuraj Sumangala 
356033e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
356133e882a5SSuraj Sumangala 					kfree_skb(skb);
356233e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
356333e882a5SSuraj Sumangala 					return -ENOMEM;
356433e882a5SSuraj Sumangala 				}
356533e882a5SSuraj Sumangala 			}
356633e882a5SSuraj Sumangala 			break;
356733e882a5SSuraj Sumangala 		}
356833e882a5SSuraj Sumangala 
356933e882a5SSuraj Sumangala 		if (scb->expect == 0) {
357033e882a5SSuraj Sumangala 			/* Complete frame */
357133e882a5SSuraj Sumangala 
357233e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
3573e1a26170SMarcel Holtmann 			hci_recv_frame(hdev, skb);
357433e882a5SSuraj Sumangala 
357533e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
357633e882a5SSuraj Sumangala 			return remain;
357733e882a5SSuraj Sumangala 		}
357833e882a5SSuraj Sumangala 	}
357933e882a5SSuraj Sumangala 
358033e882a5SSuraj Sumangala 	return remain;
358133e882a5SSuraj Sumangala }
358233e882a5SSuraj Sumangala 
3583ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
3584ef222013SMarcel Holtmann {
3585f39a3c06SSuraj Sumangala 	int rem = 0;
3586f39a3c06SSuraj Sumangala 
3587ef222013SMarcel Holtmann 	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
3588ef222013SMarcel Holtmann 		return -EILSEQ;
3589ef222013SMarcel Holtmann 
3590da5f6c37SGustavo F. Padovan 	while (count) {
35911e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count, type - 1);
3592f39a3c06SSuraj Sumangala 		if (rem < 0)
3593f39a3c06SSuraj Sumangala 			return rem;
3594ef222013SMarcel Holtmann 
3595f39a3c06SSuraj Sumangala 		data += (count - rem);
3596f39a3c06SSuraj Sumangala 		count = rem;
3597f81c6224SJoe Perches 	}
3598ef222013SMarcel Holtmann 
3599f39a3c06SSuraj Sumangala 	return rem;
3600ef222013SMarcel Holtmann }
3601ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment);
3602ef222013SMarcel Holtmann 
360399811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
360499811510SSuraj Sumangala 
360599811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
360699811510SSuraj Sumangala {
360799811510SSuraj Sumangala 	int type;
360899811510SSuraj Sumangala 	int rem = 0;
360999811510SSuraj Sumangala 
3610da5f6c37SGustavo F. Padovan 	while (count) {
361199811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
361299811510SSuraj Sumangala 
361399811510SSuraj Sumangala 		if (!skb) {
361499811510SSuraj Sumangala 			struct { char type; } *pkt;
361599811510SSuraj Sumangala 
361699811510SSuraj Sumangala 			/* Start of the frame */
361799811510SSuraj Sumangala 			pkt = data;
361899811510SSuraj Sumangala 			type = pkt->type;
361999811510SSuraj Sumangala 
362099811510SSuraj Sumangala 			data++;
362199811510SSuraj Sumangala 			count--;
362299811510SSuraj Sumangala 		} else
362399811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
362499811510SSuraj Sumangala 
36251e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
36261e429f38SGustavo F. Padovan 				     STREAM_REASSEMBLY);
362799811510SSuraj Sumangala 		if (rem < 0)
362899811510SSuraj Sumangala 			return rem;
362999811510SSuraj Sumangala 
363099811510SSuraj Sumangala 		data += (count - rem);
363199811510SSuraj Sumangala 		count = rem;
3632f81c6224SJoe Perches 	}
363399811510SSuraj Sumangala 
363499811510SSuraj Sumangala 	return rem;
363599811510SSuraj Sumangala }
363699811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
363799811510SSuraj Sumangala 
36381da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
36391da177e4SLinus Torvalds 
36401da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
36411da177e4SLinus Torvalds {
36421da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
36431da177e4SLinus Torvalds 
3644f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
36451da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
3646f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
36471da177e4SLinus Torvalds 
36481da177e4SLinus Torvalds 	return 0;
36491da177e4SLinus Torvalds }
36501da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
36511da177e4SLinus Torvalds 
36521da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
36531da177e4SLinus Torvalds {
36541da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
36551da177e4SLinus Torvalds 
3656f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
36571da177e4SLinus Torvalds 	list_del(&cb->list);
3658f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
36591da177e4SLinus Torvalds 
36601da177e4SLinus Torvalds 	return 0;
36611da177e4SLinus Torvalds }
36621da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
36631da177e4SLinus Torvalds 
366451086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
36651da177e4SLinus Torvalds {
36660d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
36671da177e4SLinus Torvalds 
36681da177e4SLinus Torvalds 	/* Time stamp */
3669a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
36701da177e4SLinus Torvalds 
3671cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
3672cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
3673cd82e61cSMarcel Holtmann 
3674cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
3675cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
3676470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
36771da177e4SLinus Torvalds 	}
36781da177e4SLinus Torvalds 
36791da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
36801da177e4SLinus Torvalds 	skb_orphan(skb);
36811da177e4SLinus Torvalds 
36827bd8f09fSMarcel Holtmann 	if (hdev->send(hdev, skb) < 0)
368351086991SMarcel Holtmann 		BT_ERR("%s sending frame failed", hdev->name);
36841da177e4SLinus Torvalds }
36851da177e4SLinus Torvalds 
36863119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev)
36873119ae95SJohan Hedberg {
36883119ae95SJohan Hedberg 	skb_queue_head_init(&req->cmd_q);
36893119ae95SJohan Hedberg 	req->hdev = hdev;
36905d73e034SAndre Guedes 	req->err = 0;
36913119ae95SJohan Hedberg }
36923119ae95SJohan Hedberg 
36933119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete)
36943119ae95SJohan Hedberg {
36953119ae95SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
36963119ae95SJohan Hedberg 	struct sk_buff *skb;
36973119ae95SJohan Hedberg 	unsigned long flags;
36983119ae95SJohan Hedberg 
36993119ae95SJohan Hedberg 	BT_DBG("length %u", skb_queue_len(&req->cmd_q));
37003119ae95SJohan Hedberg 
37015d73e034SAndre Guedes 	/* If an error occured during request building, remove all HCI
37025d73e034SAndre Guedes 	 * commands queued on the HCI request queue.
37035d73e034SAndre Guedes 	 */
37045d73e034SAndre Guedes 	if (req->err) {
37055d73e034SAndre Guedes 		skb_queue_purge(&req->cmd_q);
37065d73e034SAndre Guedes 		return req->err;
37075d73e034SAndre Guedes 	}
37085d73e034SAndre Guedes 
37093119ae95SJohan Hedberg 	/* Do not allow empty requests */
37103119ae95SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
3711382b0c39SAndre Guedes 		return -ENODATA;
37123119ae95SJohan Hedberg 
37133119ae95SJohan Hedberg 	skb = skb_peek_tail(&req->cmd_q);
37143119ae95SJohan Hedberg 	bt_cb(skb)->req.complete = complete;
37153119ae95SJohan Hedberg 
37163119ae95SJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
37173119ae95SJohan Hedberg 	skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q);
37183119ae95SJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
37193119ae95SJohan Hedberg 
37203119ae95SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
37213119ae95SJohan Hedberg 
37223119ae95SJohan Hedberg 	return 0;
37233119ae95SJohan Hedberg }
37243119ae95SJohan Hedberg 
37251ca3a9d0SJohan Hedberg static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode,
372607dc93ddSJohan Hedberg 				       u32 plen, const void *param)
37271da177e4SLinus Torvalds {
37281da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
37291da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
37301da177e4SLinus Torvalds 	struct sk_buff *skb;
37311da177e4SLinus Torvalds 
37321da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
37331ca3a9d0SJohan Hedberg 	if (!skb)
37341ca3a9d0SJohan Hedberg 		return NULL;
37351da177e4SLinus Torvalds 
37361da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
3737a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
37381da177e4SLinus Torvalds 	hdr->plen   = plen;
37391da177e4SLinus Torvalds 
37401da177e4SLinus Torvalds 	if (plen)
37411da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
37421da177e4SLinus Torvalds 
37431da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
37441da177e4SLinus Torvalds 
37450d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
3746c78ae283SMarcel Holtmann 
37471ca3a9d0SJohan Hedberg 	return skb;
37481ca3a9d0SJohan Hedberg }
37491ca3a9d0SJohan Hedberg 
37501ca3a9d0SJohan Hedberg /* Send HCI command */
375107dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
375207dc93ddSJohan Hedberg 		 const void *param)
37531ca3a9d0SJohan Hedberg {
37541ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
37551ca3a9d0SJohan Hedberg 
37561ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
37571ca3a9d0SJohan Hedberg 
37581ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
37591ca3a9d0SJohan Hedberg 	if (!skb) {
37601ca3a9d0SJohan Hedberg 		BT_ERR("%s no memory for command", hdev->name);
37611ca3a9d0SJohan Hedberg 		return -ENOMEM;
37621ca3a9d0SJohan Hedberg 	}
37631ca3a9d0SJohan Hedberg 
376411714b3dSJohan Hedberg 	/* Stand-alone HCI commands must be flaged as
376511714b3dSJohan Hedberg 	 * single-command requests.
376611714b3dSJohan Hedberg 	 */
376711714b3dSJohan Hedberg 	bt_cb(skb)->req.start = true;
376811714b3dSJohan Hedberg 
37691da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
3770c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
37711da177e4SLinus Torvalds 
37721da177e4SLinus Torvalds 	return 0;
37731da177e4SLinus Torvalds }
37741da177e4SLinus Torvalds 
377571c76a17SJohan Hedberg /* Queue a command to an asynchronous HCI request */
377607dc93ddSJohan Hedberg void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen,
377707dc93ddSJohan Hedberg 		    const void *param, u8 event)
377871c76a17SJohan Hedberg {
377971c76a17SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
378071c76a17SJohan Hedberg 	struct sk_buff *skb;
378171c76a17SJohan Hedberg 
378271c76a17SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
378371c76a17SJohan Hedberg 
378434739c1eSAndre Guedes 	/* If an error occured during request building, there is no point in
378534739c1eSAndre Guedes 	 * queueing the HCI command. We can simply return.
378634739c1eSAndre Guedes 	 */
378734739c1eSAndre Guedes 	if (req->err)
378834739c1eSAndre Guedes 		return;
378934739c1eSAndre Guedes 
379071c76a17SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
379171c76a17SJohan Hedberg 	if (!skb) {
37925d73e034SAndre Guedes 		BT_ERR("%s no memory for command (opcode 0x%4.4x)",
37935d73e034SAndre Guedes 		       hdev->name, opcode);
37945d73e034SAndre Guedes 		req->err = -ENOMEM;
3795e348fe6bSAndre Guedes 		return;
379671c76a17SJohan Hedberg 	}
379771c76a17SJohan Hedberg 
379871c76a17SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
379971c76a17SJohan Hedberg 		bt_cb(skb)->req.start = true;
380071c76a17SJohan Hedberg 
380102350a72SJohan Hedberg 	bt_cb(skb)->req.event = event;
380202350a72SJohan Hedberg 
380371c76a17SJohan Hedberg 	skb_queue_tail(&req->cmd_q, skb);
380471c76a17SJohan Hedberg }
380571c76a17SJohan Hedberg 
380607dc93ddSJohan Hedberg void hci_req_add(struct hci_request *req, u16 opcode, u32 plen,
380707dc93ddSJohan Hedberg 		 const void *param)
380802350a72SJohan Hedberg {
380902350a72SJohan Hedberg 	hci_req_add_ev(req, opcode, plen, param, 0);
381002350a72SJohan Hedberg }
381102350a72SJohan Hedberg 
38121da177e4SLinus Torvalds /* Get data from the previously sent command */
3813a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
38141da177e4SLinus Torvalds {
38151da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
38161da177e4SLinus Torvalds 
38171da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
38181da177e4SLinus Torvalds 		return NULL;
38191da177e4SLinus Torvalds 
38201da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
38211da177e4SLinus Torvalds 
3822a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
38231da177e4SLinus Torvalds 		return NULL;
38241da177e4SLinus Torvalds 
3825f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
38261da177e4SLinus Torvalds 
38271da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
38281da177e4SLinus Torvalds }
38291da177e4SLinus Torvalds 
38301da177e4SLinus Torvalds /* Send ACL data */
38311da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
38321da177e4SLinus Torvalds {
38331da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
38341da177e4SLinus Torvalds 	int len = skb->len;
38351da177e4SLinus Torvalds 
3836badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
3837badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
38389c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
3839aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
3840aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
38411da177e4SLinus Torvalds }
38421da177e4SLinus Torvalds 
3843ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
384473d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
38451da177e4SLinus Torvalds {
3846ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
38471da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
38481da177e4SLinus Torvalds 	struct sk_buff *list;
38491da177e4SLinus Torvalds 
3850087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
3851087bfd99SGustavo Padovan 	skb->data_len = 0;
3852087bfd99SGustavo Padovan 
3853087bfd99SGustavo Padovan 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
3854204a6e54SAndrei Emeltchenko 
3855204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
3856204a6e54SAndrei Emeltchenko 	case HCI_BREDR:
3857087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
3858204a6e54SAndrei Emeltchenko 		break;
3859204a6e54SAndrei Emeltchenko 	case HCI_AMP:
3860204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
3861204a6e54SAndrei Emeltchenko 		break;
3862204a6e54SAndrei Emeltchenko 	default:
3863204a6e54SAndrei Emeltchenko 		BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
3864204a6e54SAndrei Emeltchenko 		return;
3865204a6e54SAndrei Emeltchenko 	}
3866087bfd99SGustavo Padovan 
386770f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
386870f23020SAndrei Emeltchenko 	if (!list) {
38691da177e4SLinus Torvalds 		/* Non fragmented */
38701da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
38711da177e4SLinus Torvalds 
387273d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
38731da177e4SLinus Torvalds 	} else {
38741da177e4SLinus Torvalds 		/* Fragmented */
38751da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
38761da177e4SLinus Torvalds 
38771da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
38781da177e4SLinus Torvalds 
38791da177e4SLinus Torvalds 		/* Queue all fragments atomically */
3880af3e6359SGustavo F. Padovan 		spin_lock(&queue->lock);
38811da177e4SLinus Torvalds 
388273d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
3883e702112fSAndrei Emeltchenko 
3884e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
3885e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
38861da177e4SLinus Torvalds 		do {
38871da177e4SLinus Torvalds 			skb = list; list = list->next;
38881da177e4SLinus Torvalds 
38890d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
3890e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
38911da177e4SLinus Torvalds 
38921da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
38931da177e4SLinus Torvalds 
389473d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
38951da177e4SLinus Torvalds 		} while (list);
38961da177e4SLinus Torvalds 
3897af3e6359SGustavo F. Padovan 		spin_unlock(&queue->lock);
38981da177e4SLinus Torvalds 	}
389973d80debSLuiz Augusto von Dentz }
390073d80debSLuiz Augusto von Dentz 
390173d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
390273d80debSLuiz Augusto von Dentz {
3903ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
390473d80debSLuiz Augusto von Dentz 
3905f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
390673d80debSLuiz Augusto von Dentz 
3907ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
39081da177e4SLinus Torvalds 
39093eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
39101da177e4SLinus Torvalds }
39111da177e4SLinus Torvalds 
39121da177e4SLinus Torvalds /* Send SCO data */
39130d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
39141da177e4SLinus Torvalds {
39151da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
39161da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
39171da177e4SLinus Torvalds 
39181da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
39191da177e4SLinus Torvalds 
3920aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
39211da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
39221da177e4SLinus Torvalds 
3923badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
3924badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
39259c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
39261da177e4SLinus Torvalds 
39270d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
3928c78ae283SMarcel Holtmann 
39291da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
39303eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
39311da177e4SLinus Torvalds }
39321da177e4SLinus Torvalds 
39331da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
39341da177e4SLinus Torvalds 
39351da177e4SLinus Torvalds /* HCI Connection scheduler */
39366039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
3937a8c5fb1aSGustavo Padovan 				     int *quote)
39381da177e4SLinus Torvalds {
39391da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
39408035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
3941abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
39421da177e4SLinus Torvalds 
39431da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
39441da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
3945bf4c6325SGustavo F. Padovan 
3946bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3947bf4c6325SGustavo F. Padovan 
3948bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
3949769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
39501da177e4SLinus Torvalds 			continue;
3951769be974SMarcel Holtmann 
3952769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
3953769be974SMarcel Holtmann 			continue;
3954769be974SMarcel Holtmann 
39551da177e4SLinus Torvalds 		num++;
39561da177e4SLinus Torvalds 
39571da177e4SLinus Torvalds 		if (c->sent < min) {
39581da177e4SLinus Torvalds 			min  = c->sent;
39591da177e4SLinus Torvalds 			conn = c;
39601da177e4SLinus Torvalds 		}
396152087a79SLuiz Augusto von Dentz 
396252087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
396352087a79SLuiz Augusto von Dentz 			break;
39641da177e4SLinus Torvalds 	}
39651da177e4SLinus Torvalds 
3966bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3967bf4c6325SGustavo F. Padovan 
39681da177e4SLinus Torvalds 	if (conn) {
39696ed58ec5SVille Tervo 		int cnt, q;
39706ed58ec5SVille Tervo 
39716ed58ec5SVille Tervo 		switch (conn->type) {
39726ed58ec5SVille Tervo 		case ACL_LINK:
39736ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
39746ed58ec5SVille Tervo 			break;
39756ed58ec5SVille Tervo 		case SCO_LINK:
39766ed58ec5SVille Tervo 		case ESCO_LINK:
39776ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
39786ed58ec5SVille Tervo 			break;
39796ed58ec5SVille Tervo 		case LE_LINK:
39806ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
39816ed58ec5SVille Tervo 			break;
39826ed58ec5SVille Tervo 		default:
39836ed58ec5SVille Tervo 			cnt = 0;
39846ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
39856ed58ec5SVille Tervo 		}
39866ed58ec5SVille Tervo 
39876ed58ec5SVille Tervo 		q = cnt / num;
39881da177e4SLinus Torvalds 		*quote = q ? q : 1;
39891da177e4SLinus Torvalds 	} else
39901da177e4SLinus Torvalds 		*quote = 0;
39911da177e4SLinus Torvalds 
39921da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
39931da177e4SLinus Torvalds 	return conn;
39941da177e4SLinus Torvalds }
39951da177e4SLinus Torvalds 
39966039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
39971da177e4SLinus Torvalds {
39981da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
39991da177e4SLinus Torvalds 	struct hci_conn *c;
40001da177e4SLinus Torvalds 
4001bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
40021da177e4SLinus Torvalds 
4003bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4004bf4c6325SGustavo F. Padovan 
40051da177e4SLinus Torvalds 	/* Kill stalled connections */
4006bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
4007bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
40086ed93dc6SAndrei Emeltchenko 			BT_ERR("%s killing stalled connection %pMR",
40096ed93dc6SAndrei Emeltchenko 			       hdev->name, &c->dst);
4010bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
40111da177e4SLinus Torvalds 		}
40121da177e4SLinus Torvalds 	}
4013bf4c6325SGustavo F. Padovan 
4014bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
40151da177e4SLinus Torvalds }
40161da177e4SLinus Torvalds 
40176039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
401873d80debSLuiz Augusto von Dentz 				      int *quote)
401973d80debSLuiz Augusto von Dentz {
402073d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
402173d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
4022abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
402373d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
402473d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
402573d80debSLuiz Augusto von Dentz 
402673d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
402773d80debSLuiz Augusto von Dentz 
4028bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4029bf4c6325SGustavo F. Padovan 
4030bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
403173d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
403273d80debSLuiz Augusto von Dentz 
403373d80debSLuiz Augusto von Dentz 		if (conn->type != type)
403473d80debSLuiz Augusto von Dentz 			continue;
403573d80debSLuiz Augusto von Dentz 
403673d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
403773d80debSLuiz Augusto von Dentz 			continue;
403873d80debSLuiz Augusto von Dentz 
403973d80debSLuiz Augusto von Dentz 		conn_num++;
404073d80debSLuiz Augusto von Dentz 
40418192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
404273d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
404373d80debSLuiz Augusto von Dentz 
404473d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
404573d80debSLuiz Augusto von Dentz 				continue;
404673d80debSLuiz Augusto von Dentz 
404773d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
404873d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
404973d80debSLuiz Augusto von Dentz 				continue;
405073d80debSLuiz Augusto von Dentz 
405173d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
405273d80debSLuiz Augusto von Dentz 				num = 0;
405373d80debSLuiz Augusto von Dentz 				min = ~0;
405473d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
405573d80debSLuiz Augusto von Dentz 			}
405673d80debSLuiz Augusto von Dentz 
405773d80debSLuiz Augusto von Dentz 			num++;
405873d80debSLuiz Augusto von Dentz 
405973d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
406073d80debSLuiz Augusto von Dentz 				min  = conn->sent;
406173d80debSLuiz Augusto von Dentz 				chan = tmp;
406273d80debSLuiz Augusto von Dentz 			}
406373d80debSLuiz Augusto von Dentz 		}
406473d80debSLuiz Augusto von Dentz 
406573d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
406673d80debSLuiz Augusto von Dentz 			break;
406773d80debSLuiz Augusto von Dentz 	}
406873d80debSLuiz Augusto von Dentz 
4069bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4070bf4c6325SGustavo F. Padovan 
407173d80debSLuiz Augusto von Dentz 	if (!chan)
407273d80debSLuiz Augusto von Dentz 		return NULL;
407373d80debSLuiz Augusto von Dentz 
407473d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
407573d80debSLuiz Augusto von Dentz 	case ACL_LINK:
407673d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
407773d80debSLuiz Augusto von Dentz 		break;
4078bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
4079bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
4080bd1eb66bSAndrei Emeltchenko 		break;
408173d80debSLuiz Augusto von Dentz 	case SCO_LINK:
408273d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
408373d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
408473d80debSLuiz Augusto von Dentz 		break;
408573d80debSLuiz Augusto von Dentz 	case LE_LINK:
408673d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
408773d80debSLuiz Augusto von Dentz 		break;
408873d80debSLuiz Augusto von Dentz 	default:
408973d80debSLuiz Augusto von Dentz 		cnt = 0;
409073d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
409173d80debSLuiz Augusto von Dentz 	}
409273d80debSLuiz Augusto von Dentz 
409373d80debSLuiz Augusto von Dentz 	q = cnt / num;
409473d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
409573d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
409673d80debSLuiz Augusto von Dentz 	return chan;
409773d80debSLuiz Augusto von Dentz }
409873d80debSLuiz Augusto von Dentz 
409902b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
410002b20f0bSLuiz Augusto von Dentz {
410102b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
410202b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
410302b20f0bSLuiz Augusto von Dentz 	int num = 0;
410402b20f0bSLuiz Augusto von Dentz 
410502b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
410602b20f0bSLuiz Augusto von Dentz 
4107bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4108bf4c6325SGustavo F. Padovan 
4109bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
411002b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
411102b20f0bSLuiz Augusto von Dentz 
411202b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
411302b20f0bSLuiz Augusto von Dentz 			continue;
411402b20f0bSLuiz Augusto von Dentz 
411502b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
411602b20f0bSLuiz Augusto von Dentz 			continue;
411702b20f0bSLuiz Augusto von Dentz 
411802b20f0bSLuiz Augusto von Dentz 		num++;
411902b20f0bSLuiz Augusto von Dentz 
41208192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
412102b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
412202b20f0bSLuiz Augusto von Dentz 
412302b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
412402b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
412502b20f0bSLuiz Augusto von Dentz 				continue;
412602b20f0bSLuiz Augusto von Dentz 			}
412702b20f0bSLuiz Augusto von Dentz 
412802b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
412902b20f0bSLuiz Augusto von Dentz 				continue;
413002b20f0bSLuiz Augusto von Dentz 
413102b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
413202b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
413302b20f0bSLuiz Augusto von Dentz 				continue;
413402b20f0bSLuiz Augusto von Dentz 
413502b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
413602b20f0bSLuiz Augusto von Dentz 
413702b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
413802b20f0bSLuiz Augusto von Dentz 			       skb->priority);
413902b20f0bSLuiz Augusto von Dentz 		}
414002b20f0bSLuiz Augusto von Dentz 
414102b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
414202b20f0bSLuiz Augusto von Dentz 			break;
414302b20f0bSLuiz Augusto von Dentz 	}
4144bf4c6325SGustavo F. Padovan 
4145bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4146bf4c6325SGustavo F. Padovan 
414702b20f0bSLuiz Augusto von Dentz }
414802b20f0bSLuiz Augusto von Dentz 
4149b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
4150b71d385aSAndrei Emeltchenko {
4151b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
4152b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
4153b71d385aSAndrei Emeltchenko }
4154b71d385aSAndrei Emeltchenko 
41556039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
41561da177e4SLinus Torvalds {
41571da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
41581da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
41591da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
416063d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
41615f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
4162bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
41631da177e4SLinus Torvalds 	}
416463d2bc1bSAndrei Emeltchenko }
41651da177e4SLinus Torvalds 
41666039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
416763d2bc1bSAndrei Emeltchenko {
416863d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
416963d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
417063d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
417163d2bc1bSAndrei Emeltchenko 	int quote;
417263d2bc1bSAndrei Emeltchenko 
417363d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
417404837f64SMarcel Holtmann 
417573d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
417673d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
4177ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
4178ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
417973d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
418073d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
418173d80debSLuiz Augusto von Dentz 
4182ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
4183ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
4184ec1cce24SLuiz Augusto von Dentz 				break;
4185ec1cce24SLuiz Augusto von Dentz 
4186ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
4187ec1cce24SLuiz Augusto von Dentz 
418873d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
418973d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
419004837f64SMarcel Holtmann 
419157d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
41921da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
41931da177e4SLinus Torvalds 
41941da177e4SLinus Torvalds 			hdev->acl_cnt--;
419573d80debSLuiz Augusto von Dentz 			chan->sent++;
419673d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
41971da177e4SLinus Torvalds 		}
41981da177e4SLinus Torvalds 	}
419902b20f0bSLuiz Augusto von Dentz 
420002b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
420102b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
42021da177e4SLinus Torvalds }
42031da177e4SLinus Torvalds 
42046039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
4205b71d385aSAndrei Emeltchenko {
420663d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
4207b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
4208b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
4209b71d385aSAndrei Emeltchenko 	int quote;
4210bd1eb66bSAndrei Emeltchenko 	u8 type;
4211b71d385aSAndrei Emeltchenko 
421263d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
4213b71d385aSAndrei Emeltchenko 
4214bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
4215bd1eb66bSAndrei Emeltchenko 
4216bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
4217bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
4218bd1eb66bSAndrei Emeltchenko 	else
4219bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
4220bd1eb66bSAndrei Emeltchenko 
4221b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
4222bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
4223b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
4224b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
4225b71d385aSAndrei Emeltchenko 			int blocks;
4226b71d385aSAndrei Emeltchenko 
4227b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
4228b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
4229b71d385aSAndrei Emeltchenko 
4230b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
4231b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
4232b71d385aSAndrei Emeltchenko 				break;
4233b71d385aSAndrei Emeltchenko 
4234b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
4235b71d385aSAndrei Emeltchenko 
4236b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
4237b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
4238b71d385aSAndrei Emeltchenko 				return;
4239b71d385aSAndrei Emeltchenko 
4240b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
4241b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
4242b71d385aSAndrei Emeltchenko 
424357d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
4244b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
4245b71d385aSAndrei Emeltchenko 
4246b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
4247b71d385aSAndrei Emeltchenko 			quote -= blocks;
4248b71d385aSAndrei Emeltchenko 
4249b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
4250b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
4251b71d385aSAndrei Emeltchenko 		}
4252b71d385aSAndrei Emeltchenko 	}
4253b71d385aSAndrei Emeltchenko 
4254b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
4255bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
4256b71d385aSAndrei Emeltchenko }
4257b71d385aSAndrei Emeltchenko 
42586039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
4259b71d385aSAndrei Emeltchenko {
4260b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
4261b71d385aSAndrei Emeltchenko 
4262bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
4263bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR)
4264bd1eb66bSAndrei Emeltchenko 		return;
4265bd1eb66bSAndrei Emeltchenko 
4266bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
4267bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
4268b71d385aSAndrei Emeltchenko 		return;
4269b71d385aSAndrei Emeltchenko 
4270b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
4271b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
4272b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
4273b71d385aSAndrei Emeltchenko 		break;
4274b71d385aSAndrei Emeltchenko 
4275b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
4276b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
4277b71d385aSAndrei Emeltchenko 		break;
4278b71d385aSAndrei Emeltchenko 	}
4279b71d385aSAndrei Emeltchenko }
4280b71d385aSAndrei Emeltchenko 
42811da177e4SLinus Torvalds /* Schedule SCO */
42826039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev)
42831da177e4SLinus Torvalds {
42841da177e4SLinus Torvalds 	struct hci_conn *conn;
42851da177e4SLinus Torvalds 	struct sk_buff *skb;
42861da177e4SLinus Torvalds 	int quote;
42871da177e4SLinus Torvalds 
42881da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
42891da177e4SLinus Torvalds 
429052087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
429152087a79SLuiz Augusto von Dentz 		return;
429252087a79SLuiz Augusto von Dentz 
42931da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
42941da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
42951da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
429657d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
42971da177e4SLinus Torvalds 
42981da177e4SLinus Torvalds 			conn->sent++;
42991da177e4SLinus Torvalds 			if (conn->sent == ~0)
43001da177e4SLinus Torvalds 				conn->sent = 0;
43011da177e4SLinus Torvalds 		}
43021da177e4SLinus Torvalds 	}
43031da177e4SLinus Torvalds }
43041da177e4SLinus Torvalds 
43056039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev)
4306b6a0dc82SMarcel Holtmann {
4307b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
4308b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
4309b6a0dc82SMarcel Holtmann 	int quote;
4310b6a0dc82SMarcel Holtmann 
4311b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
4312b6a0dc82SMarcel Holtmann 
431352087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
431452087a79SLuiz Augusto von Dentz 		return;
431552087a79SLuiz Augusto von Dentz 
43168fc9ced3SGustavo Padovan 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
43178fc9ced3SGustavo Padovan 						     &quote))) {
4318b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
4319b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
432057d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
4321b6a0dc82SMarcel Holtmann 
4322b6a0dc82SMarcel Holtmann 			conn->sent++;
4323b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
4324b6a0dc82SMarcel Holtmann 				conn->sent = 0;
4325b6a0dc82SMarcel Holtmann 		}
4326b6a0dc82SMarcel Holtmann 	}
4327b6a0dc82SMarcel Holtmann }
4328b6a0dc82SMarcel Holtmann 
43296039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
43306ed58ec5SVille Tervo {
433173d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
43326ed58ec5SVille Tervo 	struct sk_buff *skb;
433302b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
43346ed58ec5SVille Tervo 
43356ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
43366ed58ec5SVille Tervo 
433752087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
433852087a79SLuiz Augusto von Dentz 		return;
433952087a79SLuiz Augusto von Dentz 
43406ed58ec5SVille Tervo 	if (!test_bit(HCI_RAW, &hdev->flags)) {
43416ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
43426ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
4343bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
43446ed58ec5SVille Tervo 		    time_after(jiffies, hdev->le_last_tx + HZ * 45))
4345bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
43466ed58ec5SVille Tervo 	}
43476ed58ec5SVille Tervo 
43486ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
434902b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
435073d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
4351ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
4352ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
435373d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
435473d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
43556ed58ec5SVille Tervo 
4356ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
4357ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
4358ec1cce24SLuiz Augusto von Dentz 				break;
4359ec1cce24SLuiz Augusto von Dentz 
4360ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
4361ec1cce24SLuiz Augusto von Dentz 
436257d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
43636ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
43646ed58ec5SVille Tervo 
43656ed58ec5SVille Tervo 			cnt--;
436673d80debSLuiz Augusto von Dentz 			chan->sent++;
436773d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
43686ed58ec5SVille Tervo 		}
43696ed58ec5SVille Tervo 	}
437073d80debSLuiz Augusto von Dentz 
43716ed58ec5SVille Tervo 	if (hdev->le_pkts)
43726ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
43736ed58ec5SVille Tervo 	else
43746ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
437502b20f0bSLuiz Augusto von Dentz 
437602b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
437702b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
43786ed58ec5SVille Tervo }
43796ed58ec5SVille Tervo 
43803eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
43811da177e4SLinus Torvalds {
43823eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
43831da177e4SLinus Torvalds 	struct sk_buff *skb;
43841da177e4SLinus Torvalds 
43856ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
43866ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
43871da177e4SLinus Torvalds 
438852de599eSMarcel Holtmann 	if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
43891da177e4SLinus Torvalds 		/* Schedule queues and send stuff to HCI driver */
43901da177e4SLinus Torvalds 		hci_sched_acl(hdev);
43911da177e4SLinus Torvalds 		hci_sched_sco(hdev);
4392b6a0dc82SMarcel Holtmann 		hci_sched_esco(hdev);
43936ed58ec5SVille Tervo 		hci_sched_le(hdev);
439452de599eSMarcel Holtmann 	}
43956ed58ec5SVille Tervo 
43961da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
43971da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
439857d17d70SMarcel Holtmann 		hci_send_frame(hdev, skb);
43991da177e4SLinus Torvalds }
44001da177e4SLinus Torvalds 
440125985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
44021da177e4SLinus Torvalds 
44031da177e4SLinus Torvalds /* ACL data packet */
44046039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
44051da177e4SLinus Torvalds {
44061da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
44071da177e4SLinus Torvalds 	struct hci_conn *conn;
44081da177e4SLinus Torvalds 	__u16 handle, flags;
44091da177e4SLinus Torvalds 
44101da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
44111da177e4SLinus Torvalds 
44121da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
44131da177e4SLinus Torvalds 	flags  = hci_flags(handle);
44141da177e4SLinus Torvalds 	handle = hci_handle(handle);
44151da177e4SLinus Torvalds 
4416f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
4417a8c5fb1aSGustavo Padovan 	       handle, flags);
44181da177e4SLinus Torvalds 
44191da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
44201da177e4SLinus Torvalds 
44211da177e4SLinus Torvalds 	hci_dev_lock(hdev);
44221da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
44231da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
44241da177e4SLinus Torvalds 
44251da177e4SLinus Torvalds 	if (conn) {
442665983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
442704837f64SMarcel Holtmann 
44281da177e4SLinus Torvalds 		/* Send to upper protocol */
4429686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
44301da177e4SLinus Torvalds 		return;
44311da177e4SLinus Torvalds 	} else {
44321da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
44331da177e4SLinus Torvalds 		       hdev->name, handle);
44341da177e4SLinus Torvalds 	}
44351da177e4SLinus Torvalds 
44361da177e4SLinus Torvalds 	kfree_skb(skb);
44371da177e4SLinus Torvalds }
44381da177e4SLinus Torvalds 
44391da177e4SLinus Torvalds /* SCO data packet */
44406039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
44411da177e4SLinus Torvalds {
44421da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
44431da177e4SLinus Torvalds 	struct hci_conn *conn;
44441da177e4SLinus Torvalds 	__u16 handle;
44451da177e4SLinus Torvalds 
44461da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
44471da177e4SLinus Torvalds 
44481da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
44491da177e4SLinus Torvalds 
4450f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle);
44511da177e4SLinus Torvalds 
44521da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
44531da177e4SLinus Torvalds 
44541da177e4SLinus Torvalds 	hci_dev_lock(hdev);
44551da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
44561da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
44571da177e4SLinus Torvalds 
44581da177e4SLinus Torvalds 	if (conn) {
44591da177e4SLinus Torvalds 		/* Send to upper protocol */
4460686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
44611da177e4SLinus Torvalds 		return;
44621da177e4SLinus Torvalds 	} else {
44631da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
44641da177e4SLinus Torvalds 		       hdev->name, handle);
44651da177e4SLinus Torvalds 	}
44661da177e4SLinus Torvalds 
44671da177e4SLinus Torvalds 	kfree_skb(skb);
44681da177e4SLinus Torvalds }
44691da177e4SLinus Torvalds 
44709238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
44719238f36aSJohan Hedberg {
44729238f36aSJohan Hedberg 	struct sk_buff *skb;
44739238f36aSJohan Hedberg 
44749238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
44759238f36aSJohan Hedberg 	if (!skb)
44769238f36aSJohan Hedberg 		return true;
44779238f36aSJohan Hedberg 
44789238f36aSJohan Hedberg 	return bt_cb(skb)->req.start;
44799238f36aSJohan Hedberg }
44809238f36aSJohan Hedberg 
448142c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
448242c6b129SJohan Hedberg {
448342c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
448442c6b129SJohan Hedberg 	struct sk_buff *skb;
448542c6b129SJohan Hedberg 	u16 opcode;
448642c6b129SJohan Hedberg 
448742c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
448842c6b129SJohan Hedberg 		return;
448942c6b129SJohan Hedberg 
449042c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
449142c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
449242c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
449342c6b129SJohan Hedberg 		return;
449442c6b129SJohan Hedberg 
449542c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
449642c6b129SJohan Hedberg 	if (!skb)
449742c6b129SJohan Hedberg 		return;
449842c6b129SJohan Hedberg 
449942c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
450042c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
450142c6b129SJohan Hedberg }
450242c6b129SJohan Hedberg 
45039238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status)
45049238f36aSJohan Hedberg {
45059238f36aSJohan Hedberg 	hci_req_complete_t req_complete = NULL;
45069238f36aSJohan Hedberg 	struct sk_buff *skb;
45079238f36aSJohan Hedberg 	unsigned long flags;
45089238f36aSJohan Hedberg 
45099238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
45109238f36aSJohan Hedberg 
451142c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
451242c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
45139238f36aSJohan Hedberg 	 */
451442c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
451542c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
451642c6b129SJohan Hedberg 		 * reset complete event during init and any pending
451742c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
451842c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
451942c6b129SJohan Hedberg 		 * command.
452042c6b129SJohan Hedberg 		 */
452142c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
452242c6b129SJohan Hedberg 			hci_resend_last(hdev);
452342c6b129SJohan Hedberg 
45249238f36aSJohan Hedberg 		return;
452542c6b129SJohan Hedberg 	}
45269238f36aSJohan Hedberg 
45279238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
45289238f36aSJohan Hedberg 	 * this request the request is not yet complete.
45299238f36aSJohan Hedberg 	 */
45309238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
45319238f36aSJohan Hedberg 		return;
45329238f36aSJohan Hedberg 
45339238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
45349238f36aSJohan Hedberg 	 * callback would be found in hdev->sent_cmd instead of the
45359238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
45369238f36aSJohan Hedberg 	 */
45379238f36aSJohan Hedberg 	if (hdev->sent_cmd) {
45389238f36aSJohan Hedberg 		req_complete = bt_cb(hdev->sent_cmd)->req.complete;
453953e21fbcSJohan Hedberg 
454053e21fbcSJohan Hedberg 		if (req_complete) {
454153e21fbcSJohan Hedberg 			/* We must set the complete callback to NULL to
454253e21fbcSJohan Hedberg 			 * avoid calling the callback more than once if
454353e21fbcSJohan Hedberg 			 * this function gets called again.
454453e21fbcSJohan Hedberg 			 */
454553e21fbcSJohan Hedberg 			bt_cb(hdev->sent_cmd)->req.complete = NULL;
454653e21fbcSJohan Hedberg 
45479238f36aSJohan Hedberg 			goto call_complete;
45489238f36aSJohan Hedberg 		}
454953e21fbcSJohan Hedberg 	}
45509238f36aSJohan Hedberg 
45519238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
45529238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
45539238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
45549238f36aSJohan Hedberg 		if (bt_cb(skb)->req.start) {
45559238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
45569238f36aSJohan Hedberg 			break;
45579238f36aSJohan Hedberg 		}
45589238f36aSJohan Hedberg 
45599238f36aSJohan Hedberg 		req_complete = bt_cb(skb)->req.complete;
45609238f36aSJohan Hedberg 		kfree_skb(skb);
45619238f36aSJohan Hedberg 	}
45629238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
45639238f36aSJohan Hedberg 
45649238f36aSJohan Hedberg call_complete:
45659238f36aSJohan Hedberg 	if (req_complete)
45669238f36aSJohan Hedberg 		req_complete(hdev, status);
45679238f36aSJohan Hedberg }
45689238f36aSJohan Hedberg 
4569b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
45701da177e4SLinus Torvalds {
4571b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
45721da177e4SLinus Torvalds 	struct sk_buff *skb;
45731da177e4SLinus Torvalds 
45741da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
45751da177e4SLinus Torvalds 
45761da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
4577cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
4578cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
4579cd82e61cSMarcel Holtmann 
45801da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
45811da177e4SLinus Torvalds 			/* Send copy to the sockets */
4582470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
45831da177e4SLinus Torvalds 		}
45841da177e4SLinus Torvalds 
45850736cfa8SMarcel Holtmann 		if (test_bit(HCI_RAW, &hdev->flags) ||
45860736cfa8SMarcel Holtmann 		    test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
45871da177e4SLinus Torvalds 			kfree_skb(skb);
45881da177e4SLinus Torvalds 			continue;
45891da177e4SLinus Torvalds 		}
45901da177e4SLinus Torvalds 
45911da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
45921da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
45930d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
45941da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
45951da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
45961da177e4SLinus Torvalds 				kfree_skb(skb);
45971da177e4SLinus Torvalds 				continue;
45983ff50b79SStephen Hemminger 			}
45991da177e4SLinus Torvalds 		}
46001da177e4SLinus Torvalds 
46011da177e4SLinus Torvalds 		/* Process frame */
46020d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
46031da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
4604b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
46051da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
46061da177e4SLinus Torvalds 			break;
46071da177e4SLinus Torvalds 
46081da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
46091da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
46101da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
46111da177e4SLinus Torvalds 			break;
46121da177e4SLinus Torvalds 
46131da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
46141da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
46151da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
46161da177e4SLinus Torvalds 			break;
46171da177e4SLinus Torvalds 
46181da177e4SLinus Torvalds 		default:
46191da177e4SLinus Torvalds 			kfree_skb(skb);
46201da177e4SLinus Torvalds 			break;
46211da177e4SLinus Torvalds 		}
46221da177e4SLinus Torvalds 	}
46231da177e4SLinus Torvalds }
46241da177e4SLinus Torvalds 
4625c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
46261da177e4SLinus Torvalds {
4627c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
46281da177e4SLinus Torvalds 	struct sk_buff *skb;
46291da177e4SLinus Torvalds 
46302104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
46312104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
46321da177e4SLinus Torvalds 
46331da177e4SLinus Torvalds 	/* Send queued commands */
46345a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
46355a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
46365a08ecceSAndrei Emeltchenko 		if (!skb)
46375a08ecceSAndrei Emeltchenko 			return;
46385a08ecceSAndrei Emeltchenko 
46391da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
46401da177e4SLinus Torvalds 
4641a675d7f1SMarcel Holtmann 		hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
464270f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
46431da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
464457d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
46457bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
46467bdb8a5cSSzymon Janc 				del_timer(&hdev->cmd_timer);
46477bdb8a5cSSzymon Janc 			else
46486bd32326SVille Tervo 				mod_timer(&hdev->cmd_timer,
46495f246e89SAndrei Emeltchenko 					  jiffies + HCI_CMD_TIMEOUT);
46501da177e4SLinus Torvalds 		} else {
46511da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
4652c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
46531da177e4SLinus Torvalds 		}
46541da177e4SLinus Torvalds 	}
46551da177e4SLinus Torvalds }
4656