xref: /openbmc/linux/net/bluetooth/hci_core.c (revision b32bba6c)
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 
574b32bba6cSMarcel Holtmann static ssize_t force_static_address_read(struct file *file,
575b32bba6cSMarcel Holtmann 					 char __user *user_buf,
576b32bba6cSMarcel Holtmann 					 size_t count, loff_t *ppos)
57792202185SMarcel Holtmann {
578b32bba6cSMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
579b32bba6cSMarcel Holtmann 	char buf[3];
58092202185SMarcel Holtmann 
581b32bba6cSMarcel Holtmann 	buf[0] = test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags) ? 'Y': 'N';
582b32bba6cSMarcel Holtmann 	buf[1] = '\n';
583b32bba6cSMarcel Holtmann 	buf[2] = '\0';
584b32bba6cSMarcel Holtmann 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
585b32bba6cSMarcel Holtmann }
586b32bba6cSMarcel Holtmann 
587b32bba6cSMarcel Holtmann static ssize_t force_static_address_write(struct file *file,
588b32bba6cSMarcel Holtmann 					  const char __user *user_buf,
589b32bba6cSMarcel Holtmann 					  size_t count, loff_t *ppos)
590b32bba6cSMarcel Holtmann {
591b32bba6cSMarcel Holtmann 	struct hci_dev *hdev = file->private_data;
592b32bba6cSMarcel Holtmann 	char buf[32];
593b32bba6cSMarcel Holtmann 	size_t buf_size = min(count, (sizeof(buf)-1));
594b32bba6cSMarcel Holtmann 	bool enable;
595b32bba6cSMarcel Holtmann 
596b32bba6cSMarcel Holtmann 	if (test_bit(HCI_UP, &hdev->flags))
597b32bba6cSMarcel Holtmann 		return -EBUSY;
598b32bba6cSMarcel Holtmann 
599b32bba6cSMarcel Holtmann 	if (copy_from_user(buf, user_buf, buf_size))
600b32bba6cSMarcel Holtmann 		return -EFAULT;
601b32bba6cSMarcel Holtmann 
602b32bba6cSMarcel Holtmann 	buf[buf_size] = '\0';
603b32bba6cSMarcel Holtmann 	if (strtobool(buf, &enable))
60492202185SMarcel Holtmann 		return -EINVAL;
60592202185SMarcel Holtmann 
606b32bba6cSMarcel Holtmann 	if (enable == test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags))
607b32bba6cSMarcel Holtmann 		return -EALREADY;
60892202185SMarcel Holtmann 
609b32bba6cSMarcel Holtmann 	change_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags);
610b32bba6cSMarcel Holtmann 
611b32bba6cSMarcel Holtmann 	return count;
61292202185SMarcel Holtmann }
61392202185SMarcel Holtmann 
614b32bba6cSMarcel Holtmann static const struct file_operations force_static_address_fops = {
615b32bba6cSMarcel Holtmann 	.open		= simple_open,
616b32bba6cSMarcel Holtmann 	.read		= force_static_address_read,
617b32bba6cSMarcel Holtmann 	.write		= force_static_address_write,
618b32bba6cSMarcel Holtmann 	.llseek		= default_llseek,
619b32bba6cSMarcel Holtmann };
62092202185SMarcel Holtmann 
6213698d704SMarcel Holtmann static int identity_resolving_keys_show(struct seq_file *f, void *ptr)
6223698d704SMarcel Holtmann {
6233698d704SMarcel Holtmann 	struct hci_dev *hdev = f->private;
6243698d704SMarcel Holtmann 	struct list_head *p, *n;
6253698d704SMarcel Holtmann 
6263698d704SMarcel Holtmann 	hci_dev_lock(hdev);
6273698d704SMarcel Holtmann 	list_for_each_safe(p, n, &hdev->identity_resolving_keys) {
6283698d704SMarcel Holtmann 		struct smp_irk *irk = list_entry(p, struct smp_irk, list);
6293698d704SMarcel Holtmann 		seq_printf(f, "%pMR (type %u) %*phN %pMR\n",
6303698d704SMarcel Holtmann 			   &irk->bdaddr, irk->addr_type,
6313698d704SMarcel Holtmann 			   16, irk->val, &irk->rpa);
6323698d704SMarcel Holtmann 	}
6333698d704SMarcel Holtmann 	hci_dev_unlock(hdev);
6343698d704SMarcel Holtmann 
6353698d704SMarcel Holtmann 	return 0;
6363698d704SMarcel Holtmann }
6373698d704SMarcel Holtmann 
6383698d704SMarcel Holtmann static int identity_resolving_keys_open(struct inode *inode, struct file *file)
6393698d704SMarcel Holtmann {
6403698d704SMarcel Holtmann 	return single_open(file, identity_resolving_keys_show,
6413698d704SMarcel Holtmann 			   inode->i_private);
6423698d704SMarcel Holtmann }
6433698d704SMarcel Holtmann 
6443698d704SMarcel Holtmann static const struct file_operations identity_resolving_keys_fops = {
6453698d704SMarcel Holtmann 	.open		= identity_resolving_keys_open,
6463698d704SMarcel Holtmann 	.read		= seq_read,
6473698d704SMarcel Holtmann 	.llseek		= seq_lseek,
6483698d704SMarcel Holtmann 	.release	= single_release,
6493698d704SMarcel Holtmann };
6503698d704SMarcel Holtmann 
6518f8625cdSMarcel Holtmann static int long_term_keys_show(struct seq_file *f, void *ptr)
6528f8625cdSMarcel Holtmann {
6538f8625cdSMarcel Holtmann 	struct hci_dev *hdev = f->private;
6548f8625cdSMarcel Holtmann 	struct list_head *p, *n;
6558f8625cdSMarcel Holtmann 
6568f8625cdSMarcel Holtmann 	hci_dev_lock(hdev);
657f813f1beSJohan Hedberg 	list_for_each_safe(p, n, &hdev->long_term_keys) {
6588f8625cdSMarcel Holtmann 		struct smp_ltk *ltk = list_entry(p, struct smp_ltk, list);
659f813f1beSJohan Hedberg 		seq_printf(f, "%pMR (type %u) %u 0x%02x %u %.4x %*phN %*phN\n",
6608f8625cdSMarcel Holtmann 			   &ltk->bdaddr, ltk->bdaddr_type, ltk->authenticated,
6618f8625cdSMarcel Holtmann 			   ltk->type, ltk->enc_size, __le16_to_cpu(ltk->ediv),
6628f8625cdSMarcel Holtmann 			   8, ltk->rand, 16, ltk->val);
6638f8625cdSMarcel Holtmann 	}
6648f8625cdSMarcel Holtmann 	hci_dev_unlock(hdev);
6658f8625cdSMarcel Holtmann 
6668f8625cdSMarcel Holtmann 	return 0;
6678f8625cdSMarcel Holtmann }
6688f8625cdSMarcel Holtmann 
6698f8625cdSMarcel Holtmann static int long_term_keys_open(struct inode *inode, struct file *file)
6708f8625cdSMarcel Holtmann {
6718f8625cdSMarcel Holtmann 	return single_open(file, long_term_keys_show, inode->i_private);
6728f8625cdSMarcel Holtmann }
6738f8625cdSMarcel Holtmann 
6748f8625cdSMarcel Holtmann static const struct file_operations long_term_keys_fops = {
6758f8625cdSMarcel Holtmann 	.open		= long_term_keys_open,
6768f8625cdSMarcel Holtmann 	.read		= seq_read,
6778f8625cdSMarcel Holtmann 	.llseek		= seq_lseek,
6788f8625cdSMarcel Holtmann 	.release	= single_release,
6798f8625cdSMarcel Holtmann };
6808f8625cdSMarcel Holtmann 
6814e70c7e7SMarcel Holtmann static int conn_min_interval_set(void *data, u64 val)
6824e70c7e7SMarcel Holtmann {
6834e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
6844e70c7e7SMarcel Holtmann 
6854e70c7e7SMarcel Holtmann 	if (val < 0x0006 || val > 0x0c80 || val > hdev->le_conn_max_interval)
6864e70c7e7SMarcel Holtmann 		return -EINVAL;
6874e70c7e7SMarcel Holtmann 
6884e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
6894e70c7e7SMarcel Holtmann 	hdev->le_conn_min_interval = val;
6904e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
6914e70c7e7SMarcel Holtmann 
6924e70c7e7SMarcel Holtmann 	return 0;
6934e70c7e7SMarcel Holtmann }
6944e70c7e7SMarcel Holtmann 
6954e70c7e7SMarcel Holtmann static int conn_min_interval_get(void *data, u64 *val)
6964e70c7e7SMarcel Holtmann {
6974e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
6984e70c7e7SMarcel Holtmann 
6994e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
7004e70c7e7SMarcel Holtmann 	*val = hdev->le_conn_min_interval;
7014e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
7024e70c7e7SMarcel Holtmann 
7034e70c7e7SMarcel Holtmann 	return 0;
7044e70c7e7SMarcel Holtmann }
7054e70c7e7SMarcel Holtmann 
7064e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_min_interval_fops, conn_min_interval_get,
7074e70c7e7SMarcel Holtmann 			conn_min_interval_set, "%llu\n");
7084e70c7e7SMarcel Holtmann 
7094e70c7e7SMarcel Holtmann static int conn_max_interval_set(void *data, u64 val)
7104e70c7e7SMarcel Holtmann {
7114e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
7124e70c7e7SMarcel Holtmann 
7134e70c7e7SMarcel Holtmann 	if (val < 0x0006 || val > 0x0c80 || val < hdev->le_conn_min_interval)
7144e70c7e7SMarcel Holtmann 		return -EINVAL;
7154e70c7e7SMarcel Holtmann 
7164e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
7174e70c7e7SMarcel Holtmann 	hdev->le_conn_max_interval = val;
7184e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
7194e70c7e7SMarcel Holtmann 
7204e70c7e7SMarcel Holtmann 	return 0;
7214e70c7e7SMarcel Holtmann }
7224e70c7e7SMarcel Holtmann 
7234e70c7e7SMarcel Holtmann static int conn_max_interval_get(void *data, u64 *val)
7244e70c7e7SMarcel Holtmann {
7254e70c7e7SMarcel Holtmann 	struct hci_dev *hdev = data;
7264e70c7e7SMarcel Holtmann 
7274e70c7e7SMarcel Holtmann 	hci_dev_lock(hdev);
7284e70c7e7SMarcel Holtmann 	*val = hdev->le_conn_max_interval;
7294e70c7e7SMarcel Holtmann 	hci_dev_unlock(hdev);
7304e70c7e7SMarcel Holtmann 
7314e70c7e7SMarcel Holtmann 	return 0;
7324e70c7e7SMarcel Holtmann }
7334e70c7e7SMarcel Holtmann 
7344e70c7e7SMarcel Holtmann DEFINE_SIMPLE_ATTRIBUTE(conn_max_interval_fops, conn_max_interval_get,
7354e70c7e7SMarcel Holtmann 			conn_max_interval_set, "%llu\n");
7364e70c7e7SMarcel Holtmann 
73789863109SJukka Rissanen static ssize_t lowpan_read(struct file *file, char __user *user_buf,
73889863109SJukka Rissanen 			   size_t count, loff_t *ppos)
73989863109SJukka Rissanen {
74089863109SJukka Rissanen 	struct hci_dev *hdev = file->private_data;
74189863109SJukka Rissanen 	char buf[3];
74289863109SJukka Rissanen 
74389863109SJukka Rissanen 	buf[0] = test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags) ? 'Y' : 'N';
74489863109SJukka Rissanen 	buf[1] = '\n';
74589863109SJukka Rissanen 	buf[2] = '\0';
74689863109SJukka Rissanen 	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
74789863109SJukka Rissanen }
74889863109SJukka Rissanen 
74989863109SJukka Rissanen static ssize_t lowpan_write(struct file *fp, const char __user *user_buffer,
75089863109SJukka Rissanen 			    size_t count, loff_t *position)
75189863109SJukka Rissanen {
75289863109SJukka Rissanen 	struct hci_dev *hdev = fp->private_data;
75389863109SJukka Rissanen 	bool enable;
75489863109SJukka Rissanen 	char buf[32];
75589863109SJukka Rissanen 	size_t buf_size = min(count, (sizeof(buf)-1));
75689863109SJukka Rissanen 
75789863109SJukka Rissanen 	if (copy_from_user(buf, user_buffer, buf_size))
75889863109SJukka Rissanen 		return -EFAULT;
75989863109SJukka Rissanen 
76089863109SJukka Rissanen 	buf[buf_size] = '\0';
76189863109SJukka Rissanen 
76289863109SJukka Rissanen 	if (strtobool(buf, &enable) < 0)
76389863109SJukka Rissanen 		return -EINVAL;
76489863109SJukka Rissanen 
76589863109SJukka Rissanen 	if (enable == test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags))
76689863109SJukka Rissanen 		return -EALREADY;
76789863109SJukka Rissanen 
76889863109SJukka Rissanen 	change_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags);
76989863109SJukka Rissanen 
77089863109SJukka Rissanen 	return count;
77189863109SJukka Rissanen }
77289863109SJukka Rissanen 
77389863109SJukka Rissanen static const struct file_operations lowpan_debugfs_fops = {
77489863109SJukka Rissanen 	.open		= simple_open,
77589863109SJukka Rissanen 	.read		= lowpan_read,
77689863109SJukka Rissanen 	.write		= lowpan_write,
77789863109SJukka Rissanen 	.llseek		= default_llseek,
77889863109SJukka Rissanen };
77989863109SJukka Rissanen 
7801da177e4SLinus Torvalds /* ---- HCI requests ---- */
7811da177e4SLinus Torvalds 
78242c6b129SJohan Hedberg static void hci_req_sync_complete(struct hci_dev *hdev, u8 result)
7831da177e4SLinus Torvalds {
78442c6b129SJohan Hedberg 	BT_DBG("%s result 0x%2.2x", hdev->name, result);
78575fb0e32SJohan Hedberg 
7861da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
7871da177e4SLinus Torvalds 		hdev->req_result = result;
7881da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_DONE;
7891da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
7901da177e4SLinus Torvalds 	}
7911da177e4SLinus Torvalds }
7921da177e4SLinus Torvalds 
7931da177e4SLinus Torvalds static void hci_req_cancel(struct hci_dev *hdev, int err)
7941da177e4SLinus Torvalds {
7951da177e4SLinus Torvalds 	BT_DBG("%s err 0x%2.2x", hdev->name, err);
7961da177e4SLinus Torvalds 
7971da177e4SLinus Torvalds 	if (hdev->req_status == HCI_REQ_PEND) {
7981da177e4SLinus Torvalds 		hdev->req_result = err;
7991da177e4SLinus Torvalds 		hdev->req_status = HCI_REQ_CANCELED;
8001da177e4SLinus Torvalds 		wake_up_interruptible(&hdev->req_wait_q);
8011da177e4SLinus Torvalds 	}
8021da177e4SLinus Torvalds }
8031da177e4SLinus Torvalds 
80477a63e0aSFengguang Wu static struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode,
80577a63e0aSFengguang Wu 					    u8 event)
80675e84b7cSJohan Hedberg {
80775e84b7cSJohan Hedberg 	struct hci_ev_cmd_complete *ev;
80875e84b7cSJohan Hedberg 	struct hci_event_hdr *hdr;
80975e84b7cSJohan Hedberg 	struct sk_buff *skb;
81075e84b7cSJohan Hedberg 
81175e84b7cSJohan Hedberg 	hci_dev_lock(hdev);
81275e84b7cSJohan Hedberg 
81375e84b7cSJohan Hedberg 	skb = hdev->recv_evt;
81475e84b7cSJohan Hedberg 	hdev->recv_evt = NULL;
81575e84b7cSJohan Hedberg 
81675e84b7cSJohan Hedberg 	hci_dev_unlock(hdev);
81775e84b7cSJohan Hedberg 
81875e84b7cSJohan Hedberg 	if (!skb)
81975e84b7cSJohan Hedberg 		return ERR_PTR(-ENODATA);
82075e84b7cSJohan Hedberg 
82175e84b7cSJohan Hedberg 	if (skb->len < sizeof(*hdr)) {
82275e84b7cSJohan Hedberg 		BT_ERR("Too short HCI event");
82375e84b7cSJohan Hedberg 		goto failed;
82475e84b7cSJohan Hedberg 	}
82575e84b7cSJohan Hedberg 
82675e84b7cSJohan Hedberg 	hdr = (void *) skb->data;
82775e84b7cSJohan Hedberg 	skb_pull(skb, HCI_EVENT_HDR_SIZE);
82875e84b7cSJohan Hedberg 
8297b1abbbeSJohan Hedberg 	if (event) {
8307b1abbbeSJohan Hedberg 		if (hdr->evt != event)
8317b1abbbeSJohan Hedberg 			goto failed;
8327b1abbbeSJohan Hedberg 		return skb;
8337b1abbbeSJohan Hedberg 	}
8347b1abbbeSJohan Hedberg 
83575e84b7cSJohan Hedberg 	if (hdr->evt != HCI_EV_CMD_COMPLETE) {
83675e84b7cSJohan Hedberg 		BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt);
83775e84b7cSJohan Hedberg 		goto failed;
83875e84b7cSJohan Hedberg 	}
83975e84b7cSJohan Hedberg 
84075e84b7cSJohan Hedberg 	if (skb->len < sizeof(*ev)) {
84175e84b7cSJohan Hedberg 		BT_ERR("Too short cmd_complete event");
84275e84b7cSJohan Hedberg 		goto failed;
84375e84b7cSJohan Hedberg 	}
84475e84b7cSJohan Hedberg 
84575e84b7cSJohan Hedberg 	ev = (void *) skb->data;
84675e84b7cSJohan Hedberg 	skb_pull(skb, sizeof(*ev));
84775e84b7cSJohan Hedberg 
84875e84b7cSJohan Hedberg 	if (opcode == __le16_to_cpu(ev->opcode))
84975e84b7cSJohan Hedberg 		return skb;
85075e84b7cSJohan Hedberg 
85175e84b7cSJohan Hedberg 	BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode,
85275e84b7cSJohan Hedberg 	       __le16_to_cpu(ev->opcode));
85375e84b7cSJohan Hedberg 
85475e84b7cSJohan Hedberg failed:
85575e84b7cSJohan Hedberg 	kfree_skb(skb);
85675e84b7cSJohan Hedberg 	return ERR_PTR(-ENODATA);
85775e84b7cSJohan Hedberg }
85875e84b7cSJohan Hedberg 
8597b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
86007dc93ddSJohan Hedberg 				  const void *param, u8 event, u32 timeout)
86175e84b7cSJohan Hedberg {
86275e84b7cSJohan Hedberg 	DECLARE_WAITQUEUE(wait, current);
86375e84b7cSJohan Hedberg 	struct hci_request req;
86475e84b7cSJohan Hedberg 	int err = 0;
86575e84b7cSJohan Hedberg 
86675e84b7cSJohan Hedberg 	BT_DBG("%s", hdev->name);
86775e84b7cSJohan Hedberg 
86875e84b7cSJohan Hedberg 	hci_req_init(&req, hdev);
86975e84b7cSJohan Hedberg 
8707b1abbbeSJohan Hedberg 	hci_req_add_ev(&req, opcode, plen, param, event);
87175e84b7cSJohan Hedberg 
87275e84b7cSJohan Hedberg 	hdev->req_status = HCI_REQ_PEND;
87375e84b7cSJohan Hedberg 
87475e84b7cSJohan Hedberg 	err = hci_req_run(&req, hci_req_sync_complete);
87575e84b7cSJohan Hedberg 	if (err < 0)
87675e84b7cSJohan Hedberg 		return ERR_PTR(err);
87775e84b7cSJohan Hedberg 
87875e84b7cSJohan Hedberg 	add_wait_queue(&hdev->req_wait_q, &wait);
87975e84b7cSJohan Hedberg 	set_current_state(TASK_INTERRUPTIBLE);
88075e84b7cSJohan Hedberg 
88175e84b7cSJohan Hedberg 	schedule_timeout(timeout);
88275e84b7cSJohan Hedberg 
88375e84b7cSJohan Hedberg 	remove_wait_queue(&hdev->req_wait_q, &wait);
88475e84b7cSJohan Hedberg 
88575e84b7cSJohan Hedberg 	if (signal_pending(current))
88675e84b7cSJohan Hedberg 		return ERR_PTR(-EINTR);
88775e84b7cSJohan Hedberg 
88875e84b7cSJohan Hedberg 	switch (hdev->req_status) {
88975e84b7cSJohan Hedberg 	case HCI_REQ_DONE:
89075e84b7cSJohan Hedberg 		err = -bt_to_errno(hdev->req_result);
89175e84b7cSJohan Hedberg 		break;
89275e84b7cSJohan Hedberg 
89375e84b7cSJohan Hedberg 	case HCI_REQ_CANCELED:
89475e84b7cSJohan Hedberg 		err = -hdev->req_result;
89575e84b7cSJohan Hedberg 		break;
89675e84b7cSJohan Hedberg 
89775e84b7cSJohan Hedberg 	default:
89875e84b7cSJohan Hedberg 		err = -ETIMEDOUT;
89975e84b7cSJohan Hedberg 		break;
90075e84b7cSJohan Hedberg 	}
90175e84b7cSJohan Hedberg 
90275e84b7cSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
90375e84b7cSJohan Hedberg 
90475e84b7cSJohan Hedberg 	BT_DBG("%s end: err %d", hdev->name, err);
90575e84b7cSJohan Hedberg 
90675e84b7cSJohan Hedberg 	if (err < 0)
90775e84b7cSJohan Hedberg 		return ERR_PTR(err);
90875e84b7cSJohan Hedberg 
9097b1abbbeSJohan Hedberg 	return hci_get_cmd_complete(hdev, opcode, event);
9107b1abbbeSJohan Hedberg }
9117b1abbbeSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync_ev);
9127b1abbbeSJohan Hedberg 
9137b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
91407dc93ddSJohan Hedberg 			       const void *param, u32 timeout)
9157b1abbbeSJohan Hedberg {
9167b1abbbeSJohan Hedberg 	return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout);
91775e84b7cSJohan Hedberg }
91875e84b7cSJohan Hedberg EXPORT_SYMBOL(__hci_cmd_sync);
91975e84b7cSJohan Hedberg 
9201da177e4SLinus Torvalds /* Execute request and wait for completion. */
92101178cd4SJohan Hedberg static int __hci_req_sync(struct hci_dev *hdev,
92242c6b129SJohan Hedberg 			  void (*func)(struct hci_request *req,
92342c6b129SJohan Hedberg 				      unsigned long opt),
9241da177e4SLinus Torvalds 			  unsigned long opt, __u32 timeout)
9251da177e4SLinus Torvalds {
92642c6b129SJohan Hedberg 	struct hci_request req;
9271da177e4SLinus Torvalds 	DECLARE_WAITQUEUE(wait, current);
9281da177e4SLinus Torvalds 	int err = 0;
9291da177e4SLinus Torvalds 
9301da177e4SLinus Torvalds 	BT_DBG("%s start", hdev->name);
9311da177e4SLinus Torvalds 
93242c6b129SJohan Hedberg 	hci_req_init(&req, hdev);
93342c6b129SJohan Hedberg 
9341da177e4SLinus Torvalds 	hdev->req_status = HCI_REQ_PEND;
9351da177e4SLinus Torvalds 
93642c6b129SJohan Hedberg 	func(&req, opt);
93753cce22dSJohan Hedberg 
93842c6b129SJohan Hedberg 	err = hci_req_run(&req, hci_req_sync_complete);
93942c6b129SJohan Hedberg 	if (err < 0) {
94053cce22dSJohan Hedberg 		hdev->req_status = 0;
941920c8300SAndre Guedes 
942920c8300SAndre Guedes 		/* ENODATA means the HCI request command queue is empty.
943920c8300SAndre Guedes 		 * This can happen when a request with conditionals doesn't
944920c8300SAndre Guedes 		 * trigger any commands to be sent. This is normal behavior
945920c8300SAndre Guedes 		 * and should not trigger an error return.
94642c6b129SJohan Hedberg 		 */
947920c8300SAndre Guedes 		if (err == -ENODATA)
94842c6b129SJohan Hedberg 			return 0;
949920c8300SAndre Guedes 
950920c8300SAndre Guedes 		return err;
95153cce22dSJohan Hedberg 	}
95253cce22dSJohan Hedberg 
953bc4445c7SAndre Guedes 	add_wait_queue(&hdev->req_wait_q, &wait);
954bc4445c7SAndre Guedes 	set_current_state(TASK_INTERRUPTIBLE);
955bc4445c7SAndre Guedes 
9561da177e4SLinus Torvalds 	schedule_timeout(timeout);
9571da177e4SLinus Torvalds 
9581da177e4SLinus Torvalds 	remove_wait_queue(&hdev->req_wait_q, &wait);
9591da177e4SLinus Torvalds 
9601da177e4SLinus Torvalds 	if (signal_pending(current))
9611da177e4SLinus Torvalds 		return -EINTR;
9621da177e4SLinus Torvalds 
9631da177e4SLinus Torvalds 	switch (hdev->req_status) {
9641da177e4SLinus Torvalds 	case HCI_REQ_DONE:
965e175072fSJoe Perches 		err = -bt_to_errno(hdev->req_result);
9661da177e4SLinus Torvalds 		break;
9671da177e4SLinus Torvalds 
9681da177e4SLinus Torvalds 	case HCI_REQ_CANCELED:
9691da177e4SLinus Torvalds 		err = -hdev->req_result;
9701da177e4SLinus Torvalds 		break;
9711da177e4SLinus Torvalds 
9721da177e4SLinus Torvalds 	default:
9731da177e4SLinus Torvalds 		err = -ETIMEDOUT;
9741da177e4SLinus Torvalds 		break;
9753ff50b79SStephen Hemminger 	}
9761da177e4SLinus Torvalds 
977a5040efaSJohan Hedberg 	hdev->req_status = hdev->req_result = 0;
9781da177e4SLinus Torvalds 
9791da177e4SLinus Torvalds 	BT_DBG("%s end: err %d", hdev->name, err);
9801da177e4SLinus Torvalds 
9811da177e4SLinus Torvalds 	return err;
9821da177e4SLinus Torvalds }
9831da177e4SLinus Torvalds 
98401178cd4SJohan Hedberg static int hci_req_sync(struct hci_dev *hdev,
98542c6b129SJohan Hedberg 			void (*req)(struct hci_request *req,
98642c6b129SJohan Hedberg 				    unsigned long opt),
9871da177e4SLinus Torvalds 			unsigned long opt, __u32 timeout)
9881da177e4SLinus Torvalds {
9891da177e4SLinus Torvalds 	int ret;
9901da177e4SLinus Torvalds 
9917c6a329eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags))
9927c6a329eSMarcel Holtmann 		return -ENETDOWN;
9937c6a329eSMarcel Holtmann 
9941da177e4SLinus Torvalds 	/* Serialize all requests */
9951da177e4SLinus Torvalds 	hci_req_lock(hdev);
99601178cd4SJohan Hedberg 	ret = __hci_req_sync(hdev, req, opt, timeout);
9971da177e4SLinus Torvalds 	hci_req_unlock(hdev);
9981da177e4SLinus Torvalds 
9991da177e4SLinus Torvalds 	return ret;
10001da177e4SLinus Torvalds }
10011da177e4SLinus Torvalds 
100242c6b129SJohan Hedberg static void hci_reset_req(struct hci_request *req, unsigned long opt)
10031da177e4SLinus Torvalds {
100442c6b129SJohan Hedberg 	BT_DBG("%s %ld", req->hdev->name, opt);
10051da177e4SLinus Torvalds 
10061da177e4SLinus Torvalds 	/* Reset device */
100742c6b129SJohan Hedberg 	set_bit(HCI_RESET, &req->hdev->flags);
100842c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_RESET, 0, NULL);
10091da177e4SLinus Torvalds }
10101da177e4SLinus Torvalds 
101142c6b129SJohan Hedberg static void bredr_init(struct hci_request *req)
10121da177e4SLinus Torvalds {
101342c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED;
10142455a3eaSAndrei Emeltchenko 
10151da177e4SLinus Torvalds 	/* Read Local Supported Features */
101642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
10171da177e4SLinus Torvalds 
10181143e5a6SMarcel Holtmann 	/* Read Local Version */
101942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
10202177bab5SJohan Hedberg 
10212177bab5SJohan Hedberg 	/* Read BD Address */
102242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
10231da177e4SLinus Torvalds }
10241da177e4SLinus Torvalds 
102542c6b129SJohan Hedberg static void amp_init(struct hci_request *req)
1026e61ef499SAndrei Emeltchenko {
102742c6b129SJohan Hedberg 	req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
10282455a3eaSAndrei Emeltchenko 
1029e61ef499SAndrei Emeltchenko 	/* Read Local Version */
103042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
10316bcbc489SAndrei Emeltchenko 
1032f6996cfeSMarcel Holtmann 	/* Read Local Supported Commands */
1033f6996cfeSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
1034f6996cfeSMarcel Holtmann 
1035f6996cfeSMarcel Holtmann 	/* Read Local Supported Features */
1036f6996cfeSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
1037f6996cfeSMarcel Holtmann 
10386bcbc489SAndrei Emeltchenko 	/* Read Local AMP Info */
103942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
1040e71dfabaSAndrei Emeltchenko 
1041e71dfabaSAndrei Emeltchenko 	/* Read Data Blk size */
104242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_DATA_BLOCK_SIZE, 0, NULL);
10437528ca1cSMarcel Holtmann 
1044f38ba941SMarcel Holtmann 	/* Read Flow Control Mode */
1045f38ba941SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_FLOW_CONTROL_MODE, 0, NULL);
1046f38ba941SMarcel Holtmann 
10477528ca1cSMarcel Holtmann 	/* Read Location Data */
10487528ca1cSMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL);
1049e61ef499SAndrei Emeltchenko }
1050e61ef499SAndrei Emeltchenko 
105142c6b129SJohan Hedberg static void hci_init1_req(struct hci_request *req, unsigned long opt)
1052e61ef499SAndrei Emeltchenko {
105342c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1054e61ef499SAndrei Emeltchenko 
1055e61ef499SAndrei Emeltchenko 	BT_DBG("%s %ld", hdev->name, opt);
1056e61ef499SAndrei Emeltchenko 
105711778716SAndrei Emeltchenko 	/* Reset */
105811778716SAndrei Emeltchenko 	if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
105942c6b129SJohan Hedberg 		hci_reset_req(req, 0);
106011778716SAndrei Emeltchenko 
1061e61ef499SAndrei Emeltchenko 	switch (hdev->dev_type) {
1062e61ef499SAndrei Emeltchenko 	case HCI_BREDR:
106342c6b129SJohan Hedberg 		bredr_init(req);
1064e61ef499SAndrei Emeltchenko 		break;
1065e61ef499SAndrei Emeltchenko 
1066e61ef499SAndrei Emeltchenko 	case HCI_AMP:
106742c6b129SJohan Hedberg 		amp_init(req);
1068e61ef499SAndrei Emeltchenko 		break;
1069e61ef499SAndrei Emeltchenko 
1070e61ef499SAndrei Emeltchenko 	default:
1071e61ef499SAndrei Emeltchenko 		BT_ERR("Unknown device type %d", hdev->dev_type);
1072e61ef499SAndrei Emeltchenko 		break;
1073e61ef499SAndrei Emeltchenko 	}
1074e61ef499SAndrei Emeltchenko }
1075e61ef499SAndrei Emeltchenko 
107642c6b129SJohan Hedberg static void bredr_setup(struct hci_request *req)
10772177bab5SJohan Hedberg {
10784ca048e3SMarcel Holtmann 	struct hci_dev *hdev = req->hdev;
10794ca048e3SMarcel Holtmann 
10802177bab5SJohan Hedberg 	__le16 param;
10812177bab5SJohan Hedberg 	__u8 flt_type;
10822177bab5SJohan Hedberg 
10832177bab5SJohan Hedberg 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
108442c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
10852177bab5SJohan Hedberg 
10862177bab5SJohan Hedberg 	/* Read Class of Device */
108742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
10882177bab5SJohan Hedberg 
10892177bab5SJohan Hedberg 	/* Read Local Name */
109042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_LOCAL_NAME, 0, NULL);
10912177bab5SJohan Hedberg 
10922177bab5SJohan Hedberg 	/* Read Voice Setting */
109342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_READ_VOICE_SETTING, 0, NULL);
10942177bab5SJohan Hedberg 
1095b4cb9fb2SMarcel Holtmann 	/* Read Number of Supported IAC */
1096b4cb9fb2SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_NUM_SUPPORTED_IAC, 0, NULL);
1097b4cb9fb2SMarcel Holtmann 
10984b836f39SMarcel Holtmann 	/* Read Current IAC LAP */
10994b836f39SMarcel Holtmann 	hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL);
11004b836f39SMarcel Holtmann 
11012177bab5SJohan Hedberg 	/* Clear Event Filters */
11022177bab5SJohan Hedberg 	flt_type = HCI_FLT_CLEAR_ALL;
110342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
11042177bab5SJohan Hedberg 
11052177bab5SJohan Hedberg 	/* Connection accept timeout ~20 secs */
11062177bab5SJohan Hedberg 	param = __constant_cpu_to_le16(0x7d00);
110742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
11082177bab5SJohan Hedberg 
11094ca048e3SMarcel Holtmann 	/* AVM Berlin (31), aka "BlueFRITZ!", reports version 1.2,
11104ca048e3SMarcel Holtmann 	 * but it does not support page scan related HCI commands.
11114ca048e3SMarcel Holtmann 	 */
11124ca048e3SMarcel Holtmann 	if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1) {
1113f332ec66SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_ACTIVITY, 0, NULL);
1114f332ec66SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_PAGE_SCAN_TYPE, 0, NULL);
1115f332ec66SJohan Hedberg 	}
11162177bab5SJohan Hedberg }
11172177bab5SJohan Hedberg 
111842c6b129SJohan Hedberg static void le_setup(struct hci_request *req)
11192177bab5SJohan Hedberg {
1120c73eee91SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1121c73eee91SJohan Hedberg 
11222177bab5SJohan Hedberg 	/* Read LE Buffer Size */
112342c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
11242177bab5SJohan Hedberg 
11252177bab5SJohan Hedberg 	/* Read LE Local Supported Features */
112642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
11272177bab5SJohan Hedberg 
11282177bab5SJohan Hedberg 	/* Read LE Advertising Channel TX Power */
112942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
11302177bab5SJohan Hedberg 
11312177bab5SJohan Hedberg 	/* Read LE White List Size */
113242c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL);
11332177bab5SJohan Hedberg 
11342177bab5SJohan Hedberg 	/* Read LE Supported States */
113542c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);
1136c73eee91SJohan Hedberg 
1137c73eee91SJohan Hedberg 	/* LE-only controllers have LE implicitly enabled */
1138c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
1139c73eee91SJohan Hedberg 		set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
11402177bab5SJohan Hedberg }
11412177bab5SJohan Hedberg 
11422177bab5SJohan Hedberg static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
11432177bab5SJohan Hedberg {
11442177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
11452177bab5SJohan Hedberg 		return 0x02;
11462177bab5SJohan Hedberg 
11472177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
11482177bab5SJohan Hedberg 		return 0x01;
11492177bab5SJohan Hedberg 
11502177bab5SJohan Hedberg 	if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
11512177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x0757)
11522177bab5SJohan Hedberg 		return 0x01;
11532177bab5SJohan Hedberg 
11542177bab5SJohan Hedberg 	if (hdev->manufacturer == 15) {
11552177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
11562177bab5SJohan Hedberg 			return 0x01;
11572177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
11582177bab5SJohan Hedberg 			return 0x01;
11592177bab5SJohan Hedberg 		if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
11602177bab5SJohan Hedberg 			return 0x01;
11612177bab5SJohan Hedberg 	}
11622177bab5SJohan Hedberg 
11632177bab5SJohan Hedberg 	if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
11642177bab5SJohan Hedberg 	    hdev->lmp_subver == 0x1805)
11652177bab5SJohan Hedberg 		return 0x01;
11662177bab5SJohan Hedberg 
11672177bab5SJohan Hedberg 	return 0x00;
11682177bab5SJohan Hedberg }
11692177bab5SJohan Hedberg 
117042c6b129SJohan Hedberg static void hci_setup_inquiry_mode(struct hci_request *req)
11712177bab5SJohan Hedberg {
11722177bab5SJohan Hedberg 	u8 mode;
11732177bab5SJohan Hedberg 
117442c6b129SJohan Hedberg 	mode = hci_get_inquiry_mode(req->hdev);
11752177bab5SJohan Hedberg 
117642c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
11772177bab5SJohan Hedberg }
11782177bab5SJohan Hedberg 
117942c6b129SJohan Hedberg static void hci_setup_event_mask(struct hci_request *req)
11802177bab5SJohan Hedberg {
118142c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
118242c6b129SJohan Hedberg 
11832177bab5SJohan Hedberg 	/* The second byte is 0xff instead of 0x9f (two reserved bits
11842177bab5SJohan Hedberg 	 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
11852177bab5SJohan Hedberg 	 * command otherwise.
11862177bab5SJohan Hedberg 	 */
11872177bab5SJohan Hedberg 	u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
11882177bab5SJohan Hedberg 
11892177bab5SJohan Hedberg 	/* CSR 1.1 dongles does not accept any bitfield so don't try to set
11902177bab5SJohan Hedberg 	 * any event mask for pre 1.2 devices.
11912177bab5SJohan Hedberg 	 */
11922177bab5SJohan Hedberg 	if (hdev->hci_ver < BLUETOOTH_VER_1_2)
11932177bab5SJohan Hedberg 		return;
11942177bab5SJohan Hedberg 
11952177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
11962177bab5SJohan Hedberg 		events[4] |= 0x01; /* Flow Specification Complete */
11972177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
11982177bab5SJohan Hedberg 		events[4] |= 0x04; /* Read Remote Extended Features Complete */
11992177bab5SJohan Hedberg 		events[5] |= 0x08; /* Synchronous Connection Complete */
12002177bab5SJohan Hedberg 		events[5] |= 0x10; /* Synchronous Connection Changed */
1201c7882cbdSMarcel Holtmann 	} else {
1202c7882cbdSMarcel Holtmann 		/* Use a different default for LE-only devices */
1203c7882cbdSMarcel Holtmann 		memset(events, 0, sizeof(events));
1204c7882cbdSMarcel Holtmann 		events[0] |= 0x10; /* Disconnection Complete */
1205c7882cbdSMarcel Holtmann 		events[0] |= 0x80; /* Encryption Change */
1206c7882cbdSMarcel Holtmann 		events[1] |= 0x08; /* Read Remote Version Information Complete */
1207c7882cbdSMarcel Holtmann 		events[1] |= 0x20; /* Command Complete */
1208c7882cbdSMarcel Holtmann 		events[1] |= 0x40; /* Command Status */
1209c7882cbdSMarcel Holtmann 		events[1] |= 0x80; /* Hardware Error */
1210c7882cbdSMarcel Holtmann 		events[2] |= 0x04; /* Number of Completed Packets */
1211c7882cbdSMarcel Holtmann 		events[3] |= 0x02; /* Data Buffer Overflow */
1212c7882cbdSMarcel Holtmann 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
12132177bab5SJohan Hedberg 	}
12142177bab5SJohan Hedberg 
12152177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
12162177bab5SJohan Hedberg 		events[4] |= 0x02; /* Inquiry Result with RSSI */
12172177bab5SJohan Hedberg 
12182177bab5SJohan Hedberg 	if (lmp_sniffsubr_capable(hdev))
12192177bab5SJohan Hedberg 		events[5] |= 0x20; /* Sniff Subrating */
12202177bab5SJohan Hedberg 
12212177bab5SJohan Hedberg 	if (lmp_pause_enc_capable(hdev))
12222177bab5SJohan Hedberg 		events[5] |= 0x80; /* Encryption Key Refresh Complete */
12232177bab5SJohan Hedberg 
12242177bab5SJohan Hedberg 	if (lmp_ext_inq_capable(hdev))
12252177bab5SJohan Hedberg 		events[5] |= 0x40; /* Extended Inquiry Result */
12262177bab5SJohan Hedberg 
12272177bab5SJohan Hedberg 	if (lmp_no_flush_capable(hdev))
12282177bab5SJohan Hedberg 		events[7] |= 0x01; /* Enhanced Flush Complete */
12292177bab5SJohan Hedberg 
12302177bab5SJohan Hedberg 	if (lmp_lsto_capable(hdev))
12312177bab5SJohan Hedberg 		events[6] |= 0x80; /* Link Supervision Timeout Changed */
12322177bab5SJohan Hedberg 
12332177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
12342177bab5SJohan Hedberg 		events[6] |= 0x01;	/* IO Capability Request */
12352177bab5SJohan Hedberg 		events[6] |= 0x02;	/* IO Capability Response */
12362177bab5SJohan Hedberg 		events[6] |= 0x04;	/* User Confirmation Request */
12372177bab5SJohan Hedberg 		events[6] |= 0x08;	/* User Passkey Request */
12382177bab5SJohan Hedberg 		events[6] |= 0x10;	/* Remote OOB Data Request */
12392177bab5SJohan Hedberg 		events[6] |= 0x20;	/* Simple Pairing Complete */
12402177bab5SJohan Hedberg 		events[7] |= 0x04;	/* User Passkey Notification */
12412177bab5SJohan Hedberg 		events[7] |= 0x08;	/* Keypress Notification */
12422177bab5SJohan Hedberg 		events[7] |= 0x10;	/* Remote Host Supported
12432177bab5SJohan Hedberg 					 * Features Notification
12442177bab5SJohan Hedberg 					 */
12452177bab5SJohan Hedberg 	}
12462177bab5SJohan Hedberg 
12472177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
12482177bab5SJohan Hedberg 		events[7] |= 0x20;	/* LE Meta-Event */
12492177bab5SJohan Hedberg 
125042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
12512177bab5SJohan Hedberg 
12522177bab5SJohan Hedberg 	if (lmp_le_capable(hdev)) {
12532177bab5SJohan Hedberg 		memset(events, 0, sizeof(events));
12542177bab5SJohan Hedberg 		events[0] = 0x1f;
125542c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK,
12562177bab5SJohan Hedberg 			    sizeof(events), events);
12572177bab5SJohan Hedberg 	}
12582177bab5SJohan Hedberg }
12592177bab5SJohan Hedberg 
126042c6b129SJohan Hedberg static void hci_init2_req(struct hci_request *req, unsigned long opt)
12612177bab5SJohan Hedberg {
126242c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
126342c6b129SJohan Hedberg 
12642177bab5SJohan Hedberg 	if (lmp_bredr_capable(hdev))
126542c6b129SJohan Hedberg 		bredr_setup(req);
126656f87901SJohan Hedberg 	else
126756f87901SJohan Hedberg 		clear_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
12682177bab5SJohan Hedberg 
12692177bab5SJohan Hedberg 	if (lmp_le_capable(hdev))
127042c6b129SJohan Hedberg 		le_setup(req);
12712177bab5SJohan Hedberg 
127242c6b129SJohan Hedberg 	hci_setup_event_mask(req);
12732177bab5SJohan Hedberg 
12743f8e2d75SJohan Hedberg 	/* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read
12753f8e2d75SJohan Hedberg 	 * local supported commands HCI command.
12763f8e2d75SJohan Hedberg 	 */
12773f8e2d75SJohan Hedberg 	if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1)
127842c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
12792177bab5SJohan Hedberg 
12802177bab5SJohan Hedberg 	if (lmp_ssp_capable(hdev)) {
128157af75a8SMarcel Holtmann 		/* When SSP is available, then the host features page
128257af75a8SMarcel Holtmann 		 * should also be available as well. However some
128357af75a8SMarcel Holtmann 		 * controllers list the max_page as 0 as long as SSP
128457af75a8SMarcel Holtmann 		 * has not been enabled. To achieve proper debugging
128557af75a8SMarcel Holtmann 		 * output, force the minimum max_page to 1 at least.
128657af75a8SMarcel Holtmann 		 */
128757af75a8SMarcel Holtmann 		hdev->max_page = 0x01;
128857af75a8SMarcel Holtmann 
12892177bab5SJohan Hedberg 		if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
12902177bab5SJohan Hedberg 			u8 mode = 0x01;
129142c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_SSP_MODE,
12922177bab5SJohan Hedberg 				    sizeof(mode), &mode);
12932177bab5SJohan Hedberg 		} else {
12942177bab5SJohan Hedberg 			struct hci_cp_write_eir cp;
12952177bab5SJohan Hedberg 
12962177bab5SJohan Hedberg 			memset(hdev->eir, 0, sizeof(hdev->eir));
12972177bab5SJohan Hedberg 			memset(&cp, 0, sizeof(cp));
12982177bab5SJohan Hedberg 
129942c6b129SJohan Hedberg 			hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
13002177bab5SJohan Hedberg 		}
13012177bab5SJohan Hedberg 	}
13022177bab5SJohan Hedberg 
13032177bab5SJohan Hedberg 	if (lmp_inq_rssi_capable(hdev))
130442c6b129SJohan Hedberg 		hci_setup_inquiry_mode(req);
13052177bab5SJohan Hedberg 
13062177bab5SJohan Hedberg 	if (lmp_inq_tx_pwr_capable(hdev))
130742c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
13082177bab5SJohan Hedberg 
13092177bab5SJohan Hedberg 	if (lmp_ext_feat_capable(hdev)) {
13102177bab5SJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
13112177bab5SJohan Hedberg 
13122177bab5SJohan Hedberg 		cp.page = 0x01;
131342c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
131442c6b129SJohan Hedberg 			    sizeof(cp), &cp);
13152177bab5SJohan Hedberg 	}
13162177bab5SJohan Hedberg 
13172177bab5SJohan Hedberg 	if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
13182177bab5SJohan Hedberg 		u8 enable = 1;
131942c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
13202177bab5SJohan Hedberg 			    &enable);
13212177bab5SJohan Hedberg 	}
13222177bab5SJohan Hedberg }
13232177bab5SJohan Hedberg 
132442c6b129SJohan Hedberg static void hci_setup_link_policy(struct hci_request *req)
13252177bab5SJohan Hedberg {
132642c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
13272177bab5SJohan Hedberg 	struct hci_cp_write_def_link_policy cp;
13282177bab5SJohan Hedberg 	u16 link_policy = 0;
13292177bab5SJohan Hedberg 
13302177bab5SJohan Hedberg 	if (lmp_rswitch_capable(hdev))
13312177bab5SJohan Hedberg 		link_policy |= HCI_LP_RSWITCH;
13322177bab5SJohan Hedberg 	if (lmp_hold_capable(hdev))
13332177bab5SJohan Hedberg 		link_policy |= HCI_LP_HOLD;
13342177bab5SJohan Hedberg 	if (lmp_sniff_capable(hdev))
13352177bab5SJohan Hedberg 		link_policy |= HCI_LP_SNIFF;
13362177bab5SJohan Hedberg 	if (lmp_park_capable(hdev))
13372177bab5SJohan Hedberg 		link_policy |= HCI_LP_PARK;
13382177bab5SJohan Hedberg 
13392177bab5SJohan Hedberg 	cp.policy = cpu_to_le16(link_policy);
134042c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp);
13412177bab5SJohan Hedberg }
13422177bab5SJohan Hedberg 
134342c6b129SJohan Hedberg static void hci_set_le_support(struct hci_request *req)
13442177bab5SJohan Hedberg {
134542c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
13462177bab5SJohan Hedberg 	struct hci_cp_write_le_host_supported cp;
13472177bab5SJohan Hedberg 
1348c73eee91SJohan Hedberg 	/* LE-only devices do not support explicit enablement */
1349c73eee91SJohan Hedberg 	if (!lmp_bredr_capable(hdev))
1350c73eee91SJohan Hedberg 		return;
1351c73eee91SJohan Hedberg 
13522177bab5SJohan Hedberg 	memset(&cp, 0, sizeof(cp));
13532177bab5SJohan Hedberg 
13542177bab5SJohan Hedberg 	if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
13552177bab5SJohan Hedberg 		cp.le = 0x01;
13562177bab5SJohan Hedberg 		cp.simul = lmp_le_br_capable(hdev);
13572177bab5SJohan Hedberg 	}
13582177bab5SJohan Hedberg 
13592177bab5SJohan Hedberg 	if (cp.le != lmp_host_le_capable(hdev))
136042c6b129SJohan Hedberg 		hci_req_add(req, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
13612177bab5SJohan Hedberg 			    &cp);
13622177bab5SJohan Hedberg }
13632177bab5SJohan Hedberg 
1364d62e6d67SJohan Hedberg static void hci_set_event_mask_page_2(struct hci_request *req)
1365d62e6d67SJohan Hedberg {
1366d62e6d67SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1367d62e6d67SJohan Hedberg 	u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1368d62e6d67SJohan Hedberg 
1369d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast master role is supported
1370d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
1371d62e6d67SJohan Hedberg 	 */
137253b834d2SMarcel Holtmann 	if (lmp_csb_master_capable(hdev)) {
1373d62e6d67SJohan Hedberg 		events[1] |= 0x40;	/* Triggered Clock Capture */
1374d62e6d67SJohan Hedberg 		events[1] |= 0x80;	/* Synchronization Train Complete */
1375d62e6d67SJohan Hedberg 		events[2] |= 0x10;	/* Slave Page Response Timeout */
1376d62e6d67SJohan Hedberg 		events[2] |= 0x20;	/* CSB Channel Map Change */
1377d62e6d67SJohan Hedberg 	}
1378d62e6d67SJohan Hedberg 
1379d62e6d67SJohan Hedberg 	/* If Connectionless Slave Broadcast slave role is supported
1380d62e6d67SJohan Hedberg 	 * enable all necessary events for it.
1381d62e6d67SJohan Hedberg 	 */
138253b834d2SMarcel Holtmann 	if (lmp_csb_slave_capable(hdev)) {
1383d62e6d67SJohan Hedberg 		events[2] |= 0x01;	/* Synchronization Train Received */
1384d62e6d67SJohan Hedberg 		events[2] |= 0x02;	/* CSB Receive */
1385d62e6d67SJohan Hedberg 		events[2] |= 0x04;	/* CSB Timeout */
1386d62e6d67SJohan Hedberg 		events[2] |= 0x08;	/* Truncated Page Complete */
1387d62e6d67SJohan Hedberg 	}
1388d62e6d67SJohan Hedberg 
138940c59fcbSMarcel Holtmann 	/* Enable Authenticated Payload Timeout Expired event if supported */
139040c59fcbSMarcel Holtmann 	if (lmp_ping_capable(hdev))
139140c59fcbSMarcel Holtmann 		events[2] |= 0x80;
139240c59fcbSMarcel Holtmann 
1393d62e6d67SJohan Hedberg 	hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events);
1394d62e6d67SJohan Hedberg }
1395d62e6d67SJohan Hedberg 
139642c6b129SJohan Hedberg static void hci_init3_req(struct hci_request *req, unsigned long opt)
13972177bab5SJohan Hedberg {
139842c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
1399d2c5d77fSJohan Hedberg 	u8 p;
140042c6b129SJohan Hedberg 
1401b8f4e068SGustavo Padovan 	/* Some Broadcom based Bluetooth controllers do not support the
1402b8f4e068SGustavo Padovan 	 * Delete Stored Link Key command. They are clearly indicating its
1403b8f4e068SGustavo Padovan 	 * absence in the bit mask of supported commands.
1404b8f4e068SGustavo Padovan 	 *
1405b8f4e068SGustavo Padovan 	 * Check the supported commands and only if the the command is marked
1406b8f4e068SGustavo Padovan 	 * as supported send it. If not supported assume that the controller
1407b8f4e068SGustavo Padovan 	 * does not have actual support for stored link keys which makes this
1408b8f4e068SGustavo Padovan 	 * command redundant anyway.
1409f9f462faSMarcel Holtmann 	 *
1410f9f462faSMarcel Holtmann 	 * Some controllers indicate that they support handling deleting
1411f9f462faSMarcel Holtmann 	 * stored link keys, but they don't. The quirk lets a driver
1412f9f462faSMarcel Holtmann 	 * just disable this command.
1413b8f4e068SGustavo Padovan 	 */
1414f9f462faSMarcel Holtmann 	if (hdev->commands[6] & 0x80 &&
1415f9f462faSMarcel Holtmann 	    !test_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks)) {
141659f45d57SJohan Hedberg 		struct hci_cp_delete_stored_link_key cp;
141759f45d57SJohan Hedberg 
141859f45d57SJohan Hedberg 		bacpy(&cp.bdaddr, BDADDR_ANY);
141959f45d57SJohan Hedberg 		cp.delete_all = 0x01;
142059f45d57SJohan Hedberg 		hci_req_add(req, HCI_OP_DELETE_STORED_LINK_KEY,
142159f45d57SJohan Hedberg 			    sizeof(cp), &cp);
142259f45d57SJohan Hedberg 	}
142359f45d57SJohan Hedberg 
14242177bab5SJohan Hedberg 	if (hdev->commands[5] & 0x10)
142542c6b129SJohan Hedberg 		hci_setup_link_policy(req);
14262177bab5SJohan Hedberg 
142779830f66SMarcel Holtmann 	if (lmp_le_capable(hdev)) {
1428b32bba6cSMarcel Holtmann 		/* If the controller has a public BD_ADDR, then by default
1429b32bba6cSMarcel Holtmann 		 * use that one. If this is a LE only controller without
1430b32bba6cSMarcel Holtmann 		 * a public address, default to the random address.
1431b32bba6cSMarcel Holtmann 		 *
1432b32bba6cSMarcel Holtmann 		 * For debugging purposes it is possible to force
1433b32bba6cSMarcel Holtmann 		 * controllers with a public address to use the
1434b32bba6cSMarcel Holtmann 		 * random address instead.
143579830f66SMarcel Holtmann 		 */
1436b32bba6cSMarcel Holtmann 		if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags) ||
1437b32bba6cSMarcel Holtmann 		    !bacmp(&hdev->bdaddr, BDADDR_ANY))
143879830f66SMarcel Holtmann 			hdev->own_addr_type = ADDR_LE_DEV_RANDOM;
1439b32bba6cSMarcel Holtmann 		else
1440b32bba6cSMarcel Holtmann 			hdev->own_addr_type = ADDR_LE_DEV_PUBLIC;
144179830f66SMarcel Holtmann 
144242c6b129SJohan Hedberg 		hci_set_le_support(req);
144379830f66SMarcel Holtmann 	}
1444d2c5d77fSJohan Hedberg 
1445d2c5d77fSJohan Hedberg 	/* Read features beyond page 1 if available */
1446d2c5d77fSJohan Hedberg 	for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
1447d2c5d77fSJohan Hedberg 		struct hci_cp_read_local_ext_features cp;
1448d2c5d77fSJohan Hedberg 
1449d2c5d77fSJohan Hedberg 		cp.page = p;
1450d2c5d77fSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_LOCAL_EXT_FEATURES,
1451d2c5d77fSJohan Hedberg 			    sizeof(cp), &cp);
1452d2c5d77fSJohan Hedberg 	}
14532177bab5SJohan Hedberg }
14542177bab5SJohan Hedberg 
14555d4e7e8dSJohan Hedberg static void hci_init4_req(struct hci_request *req, unsigned long opt)
14565d4e7e8dSJohan Hedberg {
14575d4e7e8dSJohan Hedberg 	struct hci_dev *hdev = req->hdev;
14585d4e7e8dSJohan Hedberg 
1459d62e6d67SJohan Hedberg 	/* Set event mask page 2 if the HCI command for it is supported */
1460d62e6d67SJohan Hedberg 	if (hdev->commands[22] & 0x04)
1461d62e6d67SJohan Hedberg 		hci_set_event_mask_page_2(req);
1462d62e6d67SJohan Hedberg 
14635d4e7e8dSJohan Hedberg 	/* Check for Synchronization Train support */
146453b834d2SMarcel Holtmann 	if (lmp_sync_train_capable(hdev))
14655d4e7e8dSJohan Hedberg 		hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL);
1466a6d0d690SMarcel Holtmann 
1467a6d0d690SMarcel Holtmann 	/* Enable Secure Connections if supported and configured */
14685afeac14SMarcel Holtmann 	if ((lmp_sc_capable(hdev) ||
14695afeac14SMarcel Holtmann 	     test_bit(HCI_FORCE_SC, &hdev->dev_flags)) &&
1470a6d0d690SMarcel Holtmann 	    test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
1471a6d0d690SMarcel Holtmann 		u8 support = 0x01;
1472a6d0d690SMarcel Holtmann 		hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT,
1473a6d0d690SMarcel Holtmann 			    sizeof(support), &support);
1474a6d0d690SMarcel Holtmann 	}
14755d4e7e8dSJohan Hedberg }
14765d4e7e8dSJohan Hedberg 
14772177bab5SJohan Hedberg static int __hci_init(struct hci_dev *hdev)
14782177bab5SJohan Hedberg {
14792177bab5SJohan Hedberg 	int err;
14802177bab5SJohan Hedberg 
14812177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init1_req, 0, HCI_INIT_TIMEOUT);
14822177bab5SJohan Hedberg 	if (err < 0)
14832177bab5SJohan Hedberg 		return err;
14842177bab5SJohan Hedberg 
14854b4148e9SMarcel Holtmann 	/* The Device Under Test (DUT) mode is special and available for
14864b4148e9SMarcel Holtmann 	 * all controller types. So just create it early on.
14874b4148e9SMarcel Holtmann 	 */
14884b4148e9SMarcel Holtmann 	if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
14894b4148e9SMarcel Holtmann 		debugfs_create_file("dut_mode", 0644, hdev->debugfs, hdev,
14904b4148e9SMarcel Holtmann 				    &dut_mode_fops);
14914b4148e9SMarcel Holtmann 	}
14924b4148e9SMarcel Holtmann 
14932177bab5SJohan Hedberg 	/* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode
14942177bab5SJohan Hedberg 	 * BR/EDR/LE type controllers. AMP controllers only need the
14952177bab5SJohan Hedberg 	 * first stage init.
14962177bab5SJohan Hedberg 	 */
14972177bab5SJohan Hedberg 	if (hdev->dev_type != HCI_BREDR)
14982177bab5SJohan Hedberg 		return 0;
14992177bab5SJohan Hedberg 
15002177bab5SJohan Hedberg 	err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT);
15012177bab5SJohan Hedberg 	if (err < 0)
15022177bab5SJohan Hedberg 		return err;
15032177bab5SJohan Hedberg 
15045d4e7e8dSJohan Hedberg 	err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT);
15055d4e7e8dSJohan Hedberg 	if (err < 0)
15065d4e7e8dSJohan Hedberg 		return err;
15075d4e7e8dSJohan Hedberg 
1508baf27f6eSMarcel Holtmann 	err = __hci_req_sync(hdev, hci_init4_req, 0, HCI_INIT_TIMEOUT);
1509baf27f6eSMarcel Holtmann 	if (err < 0)
1510baf27f6eSMarcel Holtmann 		return err;
1511baf27f6eSMarcel Holtmann 
1512baf27f6eSMarcel Holtmann 	/* Only create debugfs entries during the initial setup
1513baf27f6eSMarcel Holtmann 	 * phase and not every time the controller gets powered on.
1514baf27f6eSMarcel Holtmann 	 */
1515baf27f6eSMarcel Holtmann 	if (!test_bit(HCI_SETUP, &hdev->dev_flags))
1516baf27f6eSMarcel Holtmann 		return 0;
1517baf27f6eSMarcel Holtmann 
1518dfb826a8SMarcel Holtmann 	debugfs_create_file("features", 0444, hdev->debugfs, hdev,
1519dfb826a8SMarcel Holtmann 			    &features_fops);
1520ceeb3bc0SMarcel Holtmann 	debugfs_create_u16("manufacturer", 0444, hdev->debugfs,
1521ceeb3bc0SMarcel Holtmann 			   &hdev->manufacturer);
1522ceeb3bc0SMarcel Holtmann 	debugfs_create_u8("hci_version", 0444, hdev->debugfs, &hdev->hci_ver);
1523ceeb3bc0SMarcel Holtmann 	debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev);
152470afe0b8SMarcel Holtmann 	debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev,
152570afe0b8SMarcel Holtmann 			    &blacklist_fops);
152647219839SMarcel Holtmann 	debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops);
152747219839SMarcel Holtmann 
1528baf27f6eSMarcel Holtmann 	if (lmp_bredr_capable(hdev)) {
1529baf27f6eSMarcel Holtmann 		debugfs_create_file("inquiry_cache", 0444, hdev->debugfs,
1530baf27f6eSMarcel Holtmann 				    hdev, &inquiry_cache_fops);
153102d08d15SMarcel Holtmann 		debugfs_create_file("link_keys", 0400, hdev->debugfs,
153202d08d15SMarcel Holtmann 				    hdev, &link_keys_fops);
1533babdbb3cSMarcel Holtmann 		debugfs_create_file("dev_class", 0444, hdev->debugfs,
1534babdbb3cSMarcel Holtmann 				    hdev, &dev_class_fops);
1535041000b9SMarcel Holtmann 		debugfs_create_file("voice_setting", 0444, hdev->debugfs,
1536041000b9SMarcel Holtmann 				    hdev, &voice_setting_fops);
1537baf27f6eSMarcel Holtmann 	}
1538baf27f6eSMarcel Holtmann 
153906f5b778SMarcel Holtmann 	if (lmp_ssp_capable(hdev)) {
1540ebd1e33bSMarcel Holtmann 		debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs,
1541ebd1e33bSMarcel Holtmann 				    hdev, &auto_accept_delay_fops);
154206f5b778SMarcel Holtmann 		debugfs_create_file("ssp_debug_mode", 0644, hdev->debugfs,
154306f5b778SMarcel Holtmann 				    hdev, &ssp_debug_mode_fops);
15445afeac14SMarcel Holtmann 		debugfs_create_file("force_sc_support", 0644, hdev->debugfs,
15455afeac14SMarcel Holtmann 				    hdev, &force_sc_support_fops);
1546134c2a89SMarcel Holtmann 		debugfs_create_file("sc_only_mode", 0444, hdev->debugfs,
1547134c2a89SMarcel Holtmann 				    hdev, &sc_only_mode_fops);
154806f5b778SMarcel Holtmann 	}
1549ebd1e33bSMarcel Holtmann 
15502bfa3531SMarcel Holtmann 	if (lmp_sniff_capable(hdev)) {
15512bfa3531SMarcel Holtmann 		debugfs_create_file("idle_timeout", 0644, hdev->debugfs,
15522bfa3531SMarcel Holtmann 				    hdev, &idle_timeout_fops);
15532bfa3531SMarcel Holtmann 		debugfs_create_file("sniff_min_interval", 0644, hdev->debugfs,
15542bfa3531SMarcel Holtmann 				    hdev, &sniff_min_interval_fops);
15552bfa3531SMarcel Holtmann 		debugfs_create_file("sniff_max_interval", 0644, hdev->debugfs,
15562bfa3531SMarcel Holtmann 				    hdev, &sniff_max_interval_fops);
15572bfa3531SMarcel Holtmann 	}
15582bfa3531SMarcel Holtmann 
1559d0f729b8SMarcel Holtmann 	if (lmp_le_capable(hdev)) {
1560e7b8fc92SMarcel Holtmann 		debugfs_create_file("static_address", 0444, hdev->debugfs,
1561e7b8fc92SMarcel Holtmann 				    hdev, &static_address_fops);
1562b32bba6cSMarcel Holtmann 
1563b32bba6cSMarcel Holtmann 		/* For controllers with a public address, provide a debug
1564b32bba6cSMarcel Holtmann 		 * option to force the usage of the configured static
1565b32bba6cSMarcel Holtmann 		 * address. By default the public address is used.
1566b32bba6cSMarcel Holtmann 		 */
1567b32bba6cSMarcel Holtmann 		if (bacmp(&hdev->bdaddr, BDADDR_ANY))
1568b32bba6cSMarcel Holtmann 			debugfs_create_file("force_static_address", 0644,
1569b32bba6cSMarcel Holtmann 					    hdev->debugfs, hdev,
1570b32bba6cSMarcel Holtmann 					    &force_static_address_fops);
1571b32bba6cSMarcel Holtmann 
1572b32bba6cSMarcel Holtmann 		debugfs_create_u8("white_list_size", 0444, hdev->debugfs,
1573b32bba6cSMarcel Holtmann 				  &hdev->le_white_list_size);
15743698d704SMarcel Holtmann 		debugfs_create_file("identity_resolving_keys", 0400,
15753698d704SMarcel Holtmann 				    hdev->debugfs, hdev,
15763698d704SMarcel Holtmann 				    &identity_resolving_keys_fops);
15778f8625cdSMarcel Holtmann 		debugfs_create_file("long_term_keys", 0400, hdev->debugfs,
15788f8625cdSMarcel Holtmann 				    hdev, &long_term_keys_fops);
15794e70c7e7SMarcel Holtmann 		debugfs_create_file("conn_min_interval", 0644, hdev->debugfs,
15804e70c7e7SMarcel Holtmann 				    hdev, &conn_min_interval_fops);
15814e70c7e7SMarcel Holtmann 		debugfs_create_file("conn_max_interval", 0644, hdev->debugfs,
15824e70c7e7SMarcel Holtmann 				    hdev, &conn_max_interval_fops);
158389863109SJukka Rissanen 		debugfs_create_file("6lowpan", 0644, hdev->debugfs, hdev,
158489863109SJukka Rissanen 				    &lowpan_debugfs_fops);
1585d0f729b8SMarcel Holtmann 	}
1586e7b8fc92SMarcel Holtmann 
1587baf27f6eSMarcel Holtmann 	return 0;
15882177bab5SJohan Hedberg }
15892177bab5SJohan Hedberg 
159042c6b129SJohan Hedberg static void hci_scan_req(struct hci_request *req, unsigned long opt)
15911da177e4SLinus Torvalds {
15921da177e4SLinus Torvalds 	__u8 scan = opt;
15931da177e4SLinus Torvalds 
159442c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, scan);
15951da177e4SLinus Torvalds 
15961da177e4SLinus Torvalds 	/* Inquiry and Page scans */
159742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
15981da177e4SLinus Torvalds }
15991da177e4SLinus Torvalds 
160042c6b129SJohan Hedberg static void hci_auth_req(struct hci_request *req, unsigned long opt)
16011da177e4SLinus Torvalds {
16021da177e4SLinus Torvalds 	__u8 auth = opt;
16031da177e4SLinus Torvalds 
160442c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, auth);
16051da177e4SLinus Torvalds 
16061da177e4SLinus Torvalds 	/* Authentication */
160742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
16081da177e4SLinus Torvalds }
16091da177e4SLinus Torvalds 
161042c6b129SJohan Hedberg static void hci_encrypt_req(struct hci_request *req, unsigned long opt)
16111da177e4SLinus Torvalds {
16121da177e4SLinus Torvalds 	__u8 encrypt = opt;
16131da177e4SLinus Torvalds 
161442c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, encrypt);
16151da177e4SLinus Torvalds 
1616e4e8e37cSMarcel Holtmann 	/* Encryption */
161742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
16181da177e4SLinus Torvalds }
16191da177e4SLinus Torvalds 
162042c6b129SJohan Hedberg static void hci_linkpol_req(struct hci_request *req, unsigned long opt)
1621e4e8e37cSMarcel Holtmann {
1622e4e8e37cSMarcel Holtmann 	__le16 policy = cpu_to_le16(opt);
1623e4e8e37cSMarcel Holtmann 
162442c6b129SJohan Hedberg 	BT_DBG("%s %x", req->hdev->name, policy);
1625e4e8e37cSMarcel Holtmann 
1626e4e8e37cSMarcel Holtmann 	/* Default link policy */
162742c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
1628e4e8e37cSMarcel Holtmann }
1629e4e8e37cSMarcel Holtmann 
16301da177e4SLinus Torvalds /* Get HCI device by index.
16311da177e4SLinus Torvalds  * Device is held on return. */
16321da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index)
16331da177e4SLinus Torvalds {
16348035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev = NULL, *d;
16351da177e4SLinus Torvalds 
16361da177e4SLinus Torvalds 	BT_DBG("%d", index);
16371da177e4SLinus Torvalds 
16381da177e4SLinus Torvalds 	if (index < 0)
16391da177e4SLinus Torvalds 		return NULL;
16401da177e4SLinus Torvalds 
16411da177e4SLinus Torvalds 	read_lock(&hci_dev_list_lock);
16428035ded4SLuiz Augusto von Dentz 	list_for_each_entry(d, &hci_dev_list, list) {
16431da177e4SLinus Torvalds 		if (d->id == index) {
16441da177e4SLinus Torvalds 			hdev = hci_dev_hold(d);
16451da177e4SLinus Torvalds 			break;
16461da177e4SLinus Torvalds 		}
16471da177e4SLinus Torvalds 	}
16481da177e4SLinus Torvalds 	read_unlock(&hci_dev_list_lock);
16491da177e4SLinus Torvalds 	return hdev;
16501da177e4SLinus Torvalds }
16511da177e4SLinus Torvalds 
16521da177e4SLinus Torvalds /* ---- Inquiry support ---- */
1653ff9ef578SJohan Hedberg 
165430dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev)
165530dc78e1SJohan Hedberg {
165630dc78e1SJohan Hedberg 	struct discovery_state *discov = &hdev->discovery;
165730dc78e1SJohan Hedberg 
16586fbe195dSAndre Guedes 	switch (discov->state) {
1659343f935bSAndre Guedes 	case DISCOVERY_FINDING:
16606fbe195dSAndre Guedes 	case DISCOVERY_RESOLVING:
166130dc78e1SJohan Hedberg 		return true;
166230dc78e1SJohan Hedberg 
16636fbe195dSAndre Guedes 	default:
166430dc78e1SJohan Hedberg 		return false;
166530dc78e1SJohan Hedberg 	}
16666fbe195dSAndre Guedes }
166730dc78e1SJohan Hedberg 
1668ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state)
1669ff9ef578SJohan Hedberg {
1670ff9ef578SJohan Hedberg 	BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
1671ff9ef578SJohan Hedberg 
1672ff9ef578SJohan Hedberg 	if (hdev->discovery.state == state)
1673ff9ef578SJohan Hedberg 		return;
1674ff9ef578SJohan Hedberg 
1675ff9ef578SJohan Hedberg 	switch (state) {
1676ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPED:
16777b99b659SAndre Guedes 		if (hdev->discovery.state != DISCOVERY_STARTING)
1678ff9ef578SJohan Hedberg 			mgmt_discovering(hdev, 0);
1679ff9ef578SJohan Hedberg 		break;
1680ff9ef578SJohan Hedberg 	case DISCOVERY_STARTING:
1681ff9ef578SJohan Hedberg 		break;
1682343f935bSAndre Guedes 	case DISCOVERY_FINDING:
1683ff9ef578SJohan Hedberg 		mgmt_discovering(hdev, 1);
1684ff9ef578SJohan Hedberg 		break;
168530dc78e1SJohan Hedberg 	case DISCOVERY_RESOLVING:
168630dc78e1SJohan Hedberg 		break;
1687ff9ef578SJohan Hedberg 	case DISCOVERY_STOPPING:
1688ff9ef578SJohan Hedberg 		break;
1689ff9ef578SJohan Hedberg 	}
1690ff9ef578SJohan Hedberg 
1691ff9ef578SJohan Hedberg 	hdev->discovery.state = state;
1692ff9ef578SJohan Hedberg }
1693ff9ef578SJohan Hedberg 
16941f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev)
16951da177e4SLinus Torvalds {
169630883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1697b57c1a56SJohan Hedberg 	struct inquiry_entry *p, *n;
16981da177e4SLinus Torvalds 
1699561aafbcSJohan Hedberg 	list_for_each_entry_safe(p, n, &cache->all, all) {
1700561aafbcSJohan Hedberg 		list_del(&p->all);
1701b57c1a56SJohan Hedberg 		kfree(p);
17021da177e4SLinus Torvalds 	}
1703561aafbcSJohan Hedberg 
1704561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->unknown);
1705561aafbcSJohan Hedberg 	INIT_LIST_HEAD(&cache->resolve);
17061da177e4SLinus Torvalds }
17071da177e4SLinus Torvalds 
1708a8c5fb1aSGustavo Padovan struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
1709a8c5fb1aSGustavo Padovan 					       bdaddr_t *bdaddr)
17101da177e4SLinus Torvalds {
171130883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
17121da177e4SLinus Torvalds 	struct inquiry_entry *e;
17131da177e4SLinus Torvalds 
17146ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
17151da177e4SLinus Torvalds 
1716561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
17171da177e4SLinus Torvalds 		if (!bacmp(&e->data.bdaddr, bdaddr))
17181da177e4SLinus Torvalds 			return e;
17191da177e4SLinus Torvalds 	}
17201da177e4SLinus Torvalds 
1721b57c1a56SJohan Hedberg 	return NULL;
1722b57c1a56SJohan Hedberg }
1723b57c1a56SJohan Hedberg 
1724561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
1725561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr)
1726561aafbcSJohan Hedberg {
172730883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1728561aafbcSJohan Hedberg 	struct inquiry_entry *e;
1729561aafbcSJohan Hedberg 
17306ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, bdaddr);
1731561aafbcSJohan Hedberg 
1732561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->unknown, list) {
1733561aafbcSJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
1734561aafbcSJohan Hedberg 			return e;
1735561aafbcSJohan Hedberg 	}
1736561aafbcSJohan Hedberg 
1737561aafbcSJohan Hedberg 	return NULL;
1738561aafbcSJohan Hedberg }
1739561aafbcSJohan Hedberg 
174030dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
174130dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
174230dc78e1SJohan Hedberg 						       int state)
174330dc78e1SJohan Hedberg {
174430dc78e1SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
174530dc78e1SJohan Hedberg 	struct inquiry_entry *e;
174630dc78e1SJohan Hedberg 
17476ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
174830dc78e1SJohan Hedberg 
174930dc78e1SJohan Hedberg 	list_for_each_entry(e, &cache->resolve, list) {
175030dc78e1SJohan Hedberg 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
175130dc78e1SJohan Hedberg 			return e;
175230dc78e1SJohan Hedberg 		if (!bacmp(&e->data.bdaddr, bdaddr))
175330dc78e1SJohan Hedberg 			return e;
175430dc78e1SJohan Hedberg 	}
175530dc78e1SJohan Hedberg 
175630dc78e1SJohan Hedberg 	return NULL;
175730dc78e1SJohan Hedberg }
175830dc78e1SJohan Hedberg 
1759a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
1760a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie)
1761a3d4e20aSJohan Hedberg {
1762a3d4e20aSJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
1763a3d4e20aSJohan Hedberg 	struct list_head *pos = &cache->resolve;
1764a3d4e20aSJohan Hedberg 	struct inquiry_entry *p;
1765a3d4e20aSJohan Hedberg 
1766a3d4e20aSJohan Hedberg 	list_del(&ie->list);
1767a3d4e20aSJohan Hedberg 
1768a3d4e20aSJohan Hedberg 	list_for_each_entry(p, &cache->resolve, list) {
1769a3d4e20aSJohan Hedberg 		if (p->name_state != NAME_PENDING &&
1770a3d4e20aSJohan Hedberg 		    abs(p->data.rssi) >= abs(ie->data.rssi))
1771a3d4e20aSJohan Hedberg 			break;
1772a3d4e20aSJohan Hedberg 		pos = &p->list;
1773a3d4e20aSJohan Hedberg 	}
1774a3d4e20aSJohan Hedberg 
1775a3d4e20aSJohan Hedberg 	list_add(&ie->list, pos);
1776a3d4e20aSJohan Hedberg }
1777a3d4e20aSJohan Hedberg 
17783175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
1779388fc8faSJohan Hedberg 			      bool name_known, bool *ssp)
17801da177e4SLinus Torvalds {
178130883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
178270f23020SAndrei Emeltchenko 	struct inquiry_entry *ie;
17831da177e4SLinus Torvalds 
17846ed93dc6SAndrei Emeltchenko 	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
17851da177e4SLinus Torvalds 
17862b2fec4dSSzymon Janc 	hci_remove_remote_oob_data(hdev, &data->bdaddr);
17872b2fec4dSSzymon Janc 
1788388fc8faSJohan Hedberg 	if (ssp)
1789388fc8faSJohan Hedberg 		*ssp = data->ssp_mode;
1790388fc8faSJohan Hedberg 
179170f23020SAndrei Emeltchenko 	ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
1792a3d4e20aSJohan Hedberg 	if (ie) {
1793388fc8faSJohan Hedberg 		if (ie->data.ssp_mode && ssp)
1794388fc8faSJohan Hedberg 			*ssp = true;
1795388fc8faSJohan Hedberg 
1796a3d4e20aSJohan Hedberg 		if (ie->name_state == NAME_NEEDED &&
1797a3d4e20aSJohan Hedberg 		    data->rssi != ie->data.rssi) {
1798a3d4e20aSJohan Hedberg 			ie->data.rssi = data->rssi;
1799a3d4e20aSJohan Hedberg 			hci_inquiry_cache_update_resolve(hdev, ie);
1800a3d4e20aSJohan Hedberg 		}
1801a3d4e20aSJohan Hedberg 
1802561aafbcSJohan Hedberg 		goto update;
1803a3d4e20aSJohan Hedberg 	}
1804561aafbcSJohan Hedberg 
18051da177e4SLinus Torvalds 	/* Entry not in the cache. Add new one. */
180670f23020SAndrei Emeltchenko 	ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
180770f23020SAndrei Emeltchenko 	if (!ie)
18083175405bSJohan Hedberg 		return false;
180970f23020SAndrei Emeltchenko 
1810561aafbcSJohan Hedberg 	list_add(&ie->all, &cache->all);
1811561aafbcSJohan Hedberg 
1812561aafbcSJohan Hedberg 	if (name_known) {
1813561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
1814561aafbcSJohan Hedberg 	} else {
1815561aafbcSJohan Hedberg 		ie->name_state = NAME_NOT_KNOWN;
1816561aafbcSJohan Hedberg 		list_add(&ie->list, &cache->unknown);
1817561aafbcSJohan Hedberg 	}
1818561aafbcSJohan Hedberg 
1819561aafbcSJohan Hedberg update:
1820561aafbcSJohan Hedberg 	if (name_known && ie->name_state != NAME_KNOWN &&
1821561aafbcSJohan Hedberg 	    ie->name_state != NAME_PENDING) {
1822561aafbcSJohan Hedberg 		ie->name_state = NAME_KNOWN;
1823561aafbcSJohan Hedberg 		list_del(&ie->list);
18241da177e4SLinus Torvalds 	}
18251da177e4SLinus Torvalds 
182670f23020SAndrei Emeltchenko 	memcpy(&ie->data, data, sizeof(*data));
182770f23020SAndrei Emeltchenko 	ie->timestamp = jiffies;
18281da177e4SLinus Torvalds 	cache->timestamp = jiffies;
18293175405bSJohan Hedberg 
18303175405bSJohan Hedberg 	if (ie->name_state == NAME_NOT_KNOWN)
18313175405bSJohan Hedberg 		return false;
18323175405bSJohan Hedberg 
18333175405bSJohan Hedberg 	return true;
18341da177e4SLinus Torvalds }
18351da177e4SLinus Torvalds 
18361da177e4SLinus Torvalds static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
18371da177e4SLinus Torvalds {
183830883512SJohan Hedberg 	struct discovery_state *cache = &hdev->discovery;
18391da177e4SLinus Torvalds 	struct inquiry_info *info = (struct inquiry_info *) buf;
18401da177e4SLinus Torvalds 	struct inquiry_entry *e;
18411da177e4SLinus Torvalds 	int copied = 0;
18421da177e4SLinus Torvalds 
1843561aafbcSJohan Hedberg 	list_for_each_entry(e, &cache->all, all) {
18441da177e4SLinus Torvalds 		struct inquiry_data *data = &e->data;
1845b57c1a56SJohan Hedberg 
1846b57c1a56SJohan Hedberg 		if (copied >= num)
1847b57c1a56SJohan Hedberg 			break;
1848b57c1a56SJohan Hedberg 
18491da177e4SLinus Torvalds 		bacpy(&info->bdaddr, &data->bdaddr);
18501da177e4SLinus Torvalds 		info->pscan_rep_mode	= data->pscan_rep_mode;
18511da177e4SLinus Torvalds 		info->pscan_period_mode	= data->pscan_period_mode;
18521da177e4SLinus Torvalds 		info->pscan_mode	= data->pscan_mode;
18531da177e4SLinus Torvalds 		memcpy(info->dev_class, data->dev_class, 3);
18541da177e4SLinus Torvalds 		info->clock_offset	= data->clock_offset;
1855b57c1a56SJohan Hedberg 
18561da177e4SLinus Torvalds 		info++;
1857b57c1a56SJohan Hedberg 		copied++;
18581da177e4SLinus Torvalds 	}
18591da177e4SLinus Torvalds 
18601da177e4SLinus Torvalds 	BT_DBG("cache %p, copied %d", cache, copied);
18611da177e4SLinus Torvalds 	return copied;
18621da177e4SLinus Torvalds }
18631da177e4SLinus Torvalds 
186442c6b129SJohan Hedberg static void hci_inq_req(struct hci_request *req, unsigned long opt)
18651da177e4SLinus Torvalds {
18661da177e4SLinus Torvalds 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
186742c6b129SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
18681da177e4SLinus Torvalds 	struct hci_cp_inquiry cp;
18691da177e4SLinus Torvalds 
18701da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
18711da177e4SLinus Torvalds 
18721da177e4SLinus Torvalds 	if (test_bit(HCI_INQUIRY, &hdev->flags))
18731da177e4SLinus Torvalds 		return;
18741da177e4SLinus Torvalds 
18751da177e4SLinus Torvalds 	/* Start Inquiry */
18761da177e4SLinus Torvalds 	memcpy(&cp.lap, &ir->lap, 3);
18771da177e4SLinus Torvalds 	cp.length  = ir->length;
18781da177e4SLinus Torvalds 	cp.num_rsp = ir->num_rsp;
187942c6b129SJohan Hedberg 	hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
18801da177e4SLinus Torvalds }
18811da177e4SLinus Torvalds 
18823e13fa1eSAndre Guedes static int wait_inquiry(void *word)
18833e13fa1eSAndre Guedes {
18843e13fa1eSAndre Guedes 	schedule();
18853e13fa1eSAndre Guedes 	return signal_pending(current);
18863e13fa1eSAndre Guedes }
18873e13fa1eSAndre Guedes 
18881da177e4SLinus Torvalds int hci_inquiry(void __user *arg)
18891da177e4SLinus Torvalds {
18901da177e4SLinus Torvalds 	__u8 __user *ptr = arg;
18911da177e4SLinus Torvalds 	struct hci_inquiry_req ir;
18921da177e4SLinus Torvalds 	struct hci_dev *hdev;
18931da177e4SLinus Torvalds 	int err = 0, do_inquiry = 0, max_rsp;
18941da177e4SLinus Torvalds 	long timeo;
18951da177e4SLinus Torvalds 	__u8 *buf;
18961da177e4SLinus Torvalds 
18971da177e4SLinus Torvalds 	if (copy_from_user(&ir, ptr, sizeof(ir)))
18981da177e4SLinus Torvalds 		return -EFAULT;
18991da177e4SLinus Torvalds 
19005a08ecceSAndrei Emeltchenko 	hdev = hci_dev_get(ir.dev_id);
19015a08ecceSAndrei Emeltchenko 	if (!hdev)
19021da177e4SLinus Torvalds 		return -ENODEV;
19031da177e4SLinus Torvalds 
19040736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
19050736cfa8SMarcel Holtmann 		err = -EBUSY;
19060736cfa8SMarcel Holtmann 		goto done;
19070736cfa8SMarcel Holtmann 	}
19080736cfa8SMarcel Holtmann 
19095b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
19105b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
19115b69bef5SMarcel Holtmann 		goto done;
19125b69bef5SMarcel Holtmann 	}
19135b69bef5SMarcel Holtmann 
191456f87901SJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
191556f87901SJohan Hedberg 		err = -EOPNOTSUPP;
191656f87901SJohan Hedberg 		goto done;
191756f87901SJohan Hedberg 	}
191856f87901SJohan Hedberg 
191909fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
19201da177e4SLinus Torvalds 	if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
1921a8c5fb1aSGustavo Padovan 	    inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) {
19221f9b9a5dSAndre Guedes 		hci_inquiry_cache_flush(hdev);
19231da177e4SLinus Torvalds 		do_inquiry = 1;
19241da177e4SLinus Torvalds 	}
192509fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
19261da177e4SLinus Torvalds 
192704837f64SMarcel Holtmann 	timeo = ir.length * msecs_to_jiffies(2000);
192870f23020SAndrei Emeltchenko 
192970f23020SAndrei Emeltchenko 	if (do_inquiry) {
193001178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_inq_req, (unsigned long) &ir,
193101178cd4SJohan Hedberg 				   timeo);
193270f23020SAndrei Emeltchenko 		if (err < 0)
19331da177e4SLinus Torvalds 			goto done;
19343e13fa1eSAndre Guedes 
19353e13fa1eSAndre Guedes 		/* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
19363e13fa1eSAndre Guedes 		 * cleared). If it is interrupted by a signal, return -EINTR.
19373e13fa1eSAndre Guedes 		 */
19383e13fa1eSAndre Guedes 		if (wait_on_bit(&hdev->flags, HCI_INQUIRY, wait_inquiry,
19393e13fa1eSAndre Guedes 				TASK_INTERRUPTIBLE))
19403e13fa1eSAndre Guedes 			return -EINTR;
194170f23020SAndrei Emeltchenko 	}
19421da177e4SLinus Torvalds 
19438fc9ced3SGustavo Padovan 	/* for unlimited number of responses we will use buffer with
19448fc9ced3SGustavo Padovan 	 * 255 entries
19458fc9ced3SGustavo Padovan 	 */
19461da177e4SLinus Torvalds 	max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
19471da177e4SLinus Torvalds 
19481da177e4SLinus Torvalds 	/* cache_dump can't sleep. Therefore we allocate temp buffer and then
19491da177e4SLinus Torvalds 	 * copy it to the user space.
19501da177e4SLinus Torvalds 	 */
195170f23020SAndrei Emeltchenko 	buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL);
195270f23020SAndrei Emeltchenko 	if (!buf) {
19531da177e4SLinus Torvalds 		err = -ENOMEM;
19541da177e4SLinus Torvalds 		goto done;
19551da177e4SLinus Torvalds 	}
19561da177e4SLinus Torvalds 
195709fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
19581da177e4SLinus Torvalds 	ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
195909fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
19601da177e4SLinus Torvalds 
19611da177e4SLinus Torvalds 	BT_DBG("num_rsp %d", ir.num_rsp);
19621da177e4SLinus Torvalds 
19631da177e4SLinus Torvalds 	if (!copy_to_user(ptr, &ir, sizeof(ir))) {
19641da177e4SLinus Torvalds 		ptr += sizeof(ir);
19651da177e4SLinus Torvalds 		if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
19661da177e4SLinus Torvalds 				 ir.num_rsp))
19671da177e4SLinus Torvalds 			err = -EFAULT;
19681da177e4SLinus Torvalds 	} else
19691da177e4SLinus Torvalds 		err = -EFAULT;
19701da177e4SLinus Torvalds 
19711da177e4SLinus Torvalds 	kfree(buf);
19721da177e4SLinus Torvalds 
19731da177e4SLinus Torvalds done:
19741da177e4SLinus Torvalds 	hci_dev_put(hdev);
19751da177e4SLinus Torvalds 	return err;
19761da177e4SLinus Torvalds }
19771da177e4SLinus Torvalds 
1978cbed0ca1SJohan Hedberg static int hci_dev_do_open(struct hci_dev *hdev)
19791da177e4SLinus Torvalds {
19801da177e4SLinus Torvalds 	int ret = 0;
19811da177e4SLinus Torvalds 
19821da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
19831da177e4SLinus Torvalds 
19841da177e4SLinus Torvalds 	hci_req_lock(hdev);
19851da177e4SLinus Torvalds 
198694324962SJohan Hovold 	if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) {
198794324962SJohan Hovold 		ret = -ENODEV;
198894324962SJohan Hovold 		goto done;
198994324962SJohan Hovold 	}
199094324962SJohan Hovold 
1991a5c8f270SMarcel Holtmann 	if (!test_bit(HCI_SETUP, &hdev->dev_flags)) {
1992a5c8f270SMarcel Holtmann 		/* Check for rfkill but allow the HCI setup stage to
1993a5c8f270SMarcel Holtmann 		 * proceed (which in itself doesn't cause any RF activity).
1994bf543036SJohan Hedberg 		 */
1995a5c8f270SMarcel Holtmann 		if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) {
1996611b30f7SMarcel Holtmann 			ret = -ERFKILL;
1997611b30f7SMarcel Holtmann 			goto done;
1998611b30f7SMarcel Holtmann 		}
1999611b30f7SMarcel Holtmann 
2000a5c8f270SMarcel Holtmann 		/* Check for valid public address or a configured static
2001a5c8f270SMarcel Holtmann 		 * random adddress, but let the HCI setup proceed to
2002a5c8f270SMarcel Holtmann 		 * be able to determine if there is a public address
2003a5c8f270SMarcel Holtmann 		 * or not.
2004a5c8f270SMarcel Holtmann 		 *
2005c6beca0eSMarcel Holtmann 		 * In case of user channel usage, it is not important
2006c6beca0eSMarcel Holtmann 		 * if a public address or static random address is
2007c6beca0eSMarcel Holtmann 		 * available.
2008c6beca0eSMarcel Holtmann 		 *
2009a5c8f270SMarcel Holtmann 		 * This check is only valid for BR/EDR controllers
2010a5c8f270SMarcel Holtmann 		 * since AMP controllers do not have an address.
2011a5c8f270SMarcel Holtmann 		 */
2012c6beca0eSMarcel Holtmann 		if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
2013c6beca0eSMarcel Holtmann 		    hdev->dev_type == HCI_BREDR &&
2014a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
2015a5c8f270SMarcel Holtmann 		    !bacmp(&hdev->static_addr, BDADDR_ANY)) {
2016a5c8f270SMarcel Holtmann 			ret = -EADDRNOTAVAIL;
2017a5c8f270SMarcel Holtmann 			goto done;
2018a5c8f270SMarcel Holtmann 		}
2019a5c8f270SMarcel Holtmann 	}
2020a5c8f270SMarcel Holtmann 
20211da177e4SLinus Torvalds 	if (test_bit(HCI_UP, &hdev->flags)) {
20221da177e4SLinus Torvalds 		ret = -EALREADY;
20231da177e4SLinus Torvalds 		goto done;
20241da177e4SLinus Torvalds 	}
20251da177e4SLinus Torvalds 
20261da177e4SLinus Torvalds 	if (hdev->open(hdev)) {
20271da177e4SLinus Torvalds 		ret = -EIO;
20281da177e4SLinus Torvalds 		goto done;
20291da177e4SLinus Torvalds 	}
20301da177e4SLinus Torvalds 
20311da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
20321da177e4SLinus Torvalds 	set_bit(HCI_INIT, &hdev->flags);
2033f41c70c4SMarcel Holtmann 
2034f41c70c4SMarcel Holtmann 	if (hdev->setup && test_bit(HCI_SETUP, &hdev->dev_flags))
2035f41c70c4SMarcel Holtmann 		ret = hdev->setup(hdev);
2036f41c70c4SMarcel Holtmann 
2037f41c70c4SMarcel Holtmann 	if (!ret) {
2038f41c70c4SMarcel Holtmann 		if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
2039f41c70c4SMarcel Holtmann 			set_bit(HCI_RAW, &hdev->flags);
2040f41c70c4SMarcel Holtmann 
20410736cfa8SMarcel Holtmann 		if (!test_bit(HCI_RAW, &hdev->flags) &&
20420736cfa8SMarcel Holtmann 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
20432177bab5SJohan Hedberg 			ret = __hci_init(hdev);
20441da177e4SLinus Torvalds 	}
20451da177e4SLinus Torvalds 
2046f41c70c4SMarcel Holtmann 	clear_bit(HCI_INIT, &hdev->flags);
2047f41c70c4SMarcel Holtmann 
20481da177e4SLinus Torvalds 	if (!ret) {
20491da177e4SLinus Torvalds 		hci_dev_hold(hdev);
20501da177e4SLinus Torvalds 		set_bit(HCI_UP, &hdev->flags);
20511da177e4SLinus Torvalds 		hci_notify(hdev, HCI_DEV_UP);
2052bb4b2a9aSAndrei Emeltchenko 		if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
20530736cfa8SMarcel Holtmann 		    !test_bit(HCI_USER_CHANNEL, &hdev->dev_flags) &&
20541514b892SMarcel Holtmann 		    hdev->dev_type == HCI_BREDR) {
205509fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
2056744cf19eSJohan Hedberg 			mgmt_powered(hdev, 1);
205709fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
205856e5cb86SJohan Hedberg 		}
20591da177e4SLinus Torvalds 	} else {
20601da177e4SLinus Torvalds 		/* Init failed, cleanup */
20613eff45eaSGustavo F. Padovan 		flush_work(&hdev->tx_work);
2062c347b765SGustavo F. Padovan 		flush_work(&hdev->cmd_work);
2063b78752ccSMarcel Holtmann 		flush_work(&hdev->rx_work);
20641da177e4SLinus Torvalds 
20651da177e4SLinus Torvalds 		skb_queue_purge(&hdev->cmd_q);
20661da177e4SLinus Torvalds 		skb_queue_purge(&hdev->rx_q);
20671da177e4SLinus Torvalds 
20681da177e4SLinus Torvalds 		if (hdev->flush)
20691da177e4SLinus Torvalds 			hdev->flush(hdev);
20701da177e4SLinus Torvalds 
20711da177e4SLinus Torvalds 		if (hdev->sent_cmd) {
20721da177e4SLinus Torvalds 			kfree_skb(hdev->sent_cmd);
20731da177e4SLinus Torvalds 			hdev->sent_cmd = NULL;
20741da177e4SLinus Torvalds 		}
20751da177e4SLinus Torvalds 
20761da177e4SLinus Torvalds 		hdev->close(hdev);
20771da177e4SLinus Torvalds 		hdev->flags = 0;
20781da177e4SLinus Torvalds 	}
20791da177e4SLinus Torvalds 
20801da177e4SLinus Torvalds done:
20811da177e4SLinus Torvalds 	hci_req_unlock(hdev);
20821da177e4SLinus Torvalds 	return ret;
20831da177e4SLinus Torvalds }
20841da177e4SLinus Torvalds 
2085cbed0ca1SJohan Hedberg /* ---- HCI ioctl helpers ---- */
2086cbed0ca1SJohan Hedberg 
2087cbed0ca1SJohan Hedberg int hci_dev_open(__u16 dev)
2088cbed0ca1SJohan Hedberg {
2089cbed0ca1SJohan Hedberg 	struct hci_dev *hdev;
2090cbed0ca1SJohan Hedberg 	int err;
2091cbed0ca1SJohan Hedberg 
2092cbed0ca1SJohan Hedberg 	hdev = hci_dev_get(dev);
2093cbed0ca1SJohan Hedberg 	if (!hdev)
2094cbed0ca1SJohan Hedberg 		return -ENODEV;
2095cbed0ca1SJohan Hedberg 
2096e1d08f40SJohan Hedberg 	/* We need to ensure that no other power on/off work is pending
2097e1d08f40SJohan Hedberg 	 * before proceeding to call hci_dev_do_open. This is
2098e1d08f40SJohan Hedberg 	 * particularly important if the setup procedure has not yet
2099e1d08f40SJohan Hedberg 	 * completed.
2100e1d08f40SJohan Hedberg 	 */
2101e1d08f40SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
2102e1d08f40SJohan Hedberg 		cancel_delayed_work(&hdev->power_off);
2103e1d08f40SJohan Hedberg 
2104a5c8f270SMarcel Holtmann 	/* After this call it is guaranteed that the setup procedure
2105a5c8f270SMarcel Holtmann 	 * has finished. This means that error conditions like RFKILL
2106a5c8f270SMarcel Holtmann 	 * or no valid public or static random address apply.
2107a5c8f270SMarcel Holtmann 	 */
2108e1d08f40SJohan Hedberg 	flush_workqueue(hdev->req_workqueue);
2109e1d08f40SJohan Hedberg 
2110cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
2111cbed0ca1SJohan Hedberg 
2112cbed0ca1SJohan Hedberg 	hci_dev_put(hdev);
2113cbed0ca1SJohan Hedberg 
2114cbed0ca1SJohan Hedberg 	return err;
2115cbed0ca1SJohan Hedberg }
2116cbed0ca1SJohan Hedberg 
21171da177e4SLinus Torvalds static int hci_dev_do_close(struct hci_dev *hdev)
21181da177e4SLinus Torvalds {
21191da177e4SLinus Torvalds 	BT_DBG("%s %p", hdev->name, hdev);
21201da177e4SLinus Torvalds 
212178c04c0bSVinicius Costa Gomes 	cancel_delayed_work(&hdev->power_off);
212278c04c0bSVinicius Costa Gomes 
21231da177e4SLinus Torvalds 	hci_req_cancel(hdev, ENODEV);
21241da177e4SLinus Torvalds 	hci_req_lock(hdev);
21251da177e4SLinus Torvalds 
21261da177e4SLinus Torvalds 	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
2127b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
21281da177e4SLinus Torvalds 		hci_req_unlock(hdev);
21291da177e4SLinus Torvalds 		return 0;
21301da177e4SLinus Torvalds 	}
21311da177e4SLinus Torvalds 
21323eff45eaSGustavo F. Padovan 	/* Flush RX and TX works */
21333eff45eaSGustavo F. Padovan 	flush_work(&hdev->tx_work);
2134b78752ccSMarcel Holtmann 	flush_work(&hdev->rx_work);
21351da177e4SLinus Torvalds 
213616ab91abSJohan Hedberg 	if (hdev->discov_timeout > 0) {
2137e0f9309fSJohan Hedberg 		cancel_delayed_work(&hdev->discov_off);
213816ab91abSJohan Hedberg 		hdev->discov_timeout = 0;
21395e5282bbSJohan Hedberg 		clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
2140310a3d48SMarcel Holtmann 		clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
214116ab91abSJohan Hedberg 	}
214216ab91abSJohan Hedberg 
2143a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
21447d78525dSJohan Hedberg 		cancel_delayed_work(&hdev->service_cache);
21457d78525dSJohan Hedberg 
21467ba8b4beSAndre Guedes 	cancel_delayed_work_sync(&hdev->le_scan_disable);
21477ba8b4beSAndre Guedes 
214809fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
21491f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
21501da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
215109fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
21521da177e4SLinus Torvalds 
21531da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_DOWN);
21541da177e4SLinus Torvalds 
21551da177e4SLinus Torvalds 	if (hdev->flush)
21561da177e4SLinus Torvalds 		hdev->flush(hdev);
21571da177e4SLinus Torvalds 
21581da177e4SLinus Torvalds 	/* Reset device */
21591da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
21601da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
21618af59467SJohan Hedberg 	if (!test_bit(HCI_RAW, &hdev->flags) &&
21623a6afbd2SMarcel Holtmann 	    !test_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
2163a6c511c6SSzymon Janc 	    test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
21641da177e4SLinus Torvalds 		set_bit(HCI_INIT, &hdev->flags);
216501178cd4SJohan Hedberg 		__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
21661da177e4SLinus Torvalds 		clear_bit(HCI_INIT, &hdev->flags);
21671da177e4SLinus Torvalds 	}
21681da177e4SLinus Torvalds 
2169c347b765SGustavo F. Padovan 	/* flush cmd  work */
2170c347b765SGustavo F. Padovan 	flush_work(&hdev->cmd_work);
21711da177e4SLinus Torvalds 
21721da177e4SLinus Torvalds 	/* Drop queues */
21731da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
21741da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
21751da177e4SLinus Torvalds 	skb_queue_purge(&hdev->raw_q);
21761da177e4SLinus Torvalds 
21771da177e4SLinus Torvalds 	/* Drop last sent command */
21781da177e4SLinus Torvalds 	if (hdev->sent_cmd) {
2179b79f44c1SVinicius Costa Gomes 		del_timer_sync(&hdev->cmd_timer);
21801da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
21811da177e4SLinus Torvalds 		hdev->sent_cmd = NULL;
21821da177e4SLinus Torvalds 	}
21831da177e4SLinus Torvalds 
2184b6ddb638SJohan Hedberg 	kfree_skb(hdev->recv_evt);
2185b6ddb638SJohan Hedberg 	hdev->recv_evt = NULL;
2186b6ddb638SJohan Hedberg 
21871da177e4SLinus Torvalds 	/* After this point our queues are empty
21881da177e4SLinus Torvalds 	 * and no tasks are scheduled. */
21891da177e4SLinus Torvalds 	hdev->close(hdev);
21901da177e4SLinus Torvalds 
219135b973c9SJohan Hedberg 	/* Clear flags */
219235b973c9SJohan Hedberg 	hdev->flags = 0;
219335b973c9SJohan Hedberg 	hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
219435b973c9SJohan Hedberg 
219593c311a0SMarcel Holtmann 	if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
219693c311a0SMarcel Holtmann 		if (hdev->dev_type == HCI_BREDR) {
219709fd0de5SGustavo F. Padovan 			hci_dev_lock(hdev);
2198744cf19eSJohan Hedberg 			mgmt_powered(hdev, 0);
219909fd0de5SGustavo F. Padovan 			hci_dev_unlock(hdev);
22008ee56540SMarcel Holtmann 		}
220193c311a0SMarcel Holtmann 	}
22025add6af8SJohan Hedberg 
2203ced5c338SAndrei Emeltchenko 	/* Controller radio is available but is currently powered down */
2204536619e8SMarcel Holtmann 	hdev->amp_status = AMP_STATUS_POWERED_DOWN;
2205ced5c338SAndrei Emeltchenko 
2206e59fda8dSJohan Hedberg 	memset(hdev->eir, 0, sizeof(hdev->eir));
220709b3c3fbSJohan Hedberg 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
2208e59fda8dSJohan Hedberg 
22091da177e4SLinus Torvalds 	hci_req_unlock(hdev);
22101da177e4SLinus Torvalds 
22111da177e4SLinus Torvalds 	hci_dev_put(hdev);
22121da177e4SLinus Torvalds 	return 0;
22131da177e4SLinus Torvalds }
22141da177e4SLinus Torvalds 
22151da177e4SLinus Torvalds int hci_dev_close(__u16 dev)
22161da177e4SLinus Torvalds {
22171da177e4SLinus Torvalds 	struct hci_dev *hdev;
22181da177e4SLinus Torvalds 	int err;
22191da177e4SLinus Torvalds 
222070f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
222170f23020SAndrei Emeltchenko 	if (!hdev)
22221da177e4SLinus Torvalds 		return -ENODEV;
22238ee56540SMarcel Holtmann 
22240736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
22250736cfa8SMarcel Holtmann 		err = -EBUSY;
22260736cfa8SMarcel Holtmann 		goto done;
22270736cfa8SMarcel Holtmann 	}
22280736cfa8SMarcel Holtmann 
22298ee56540SMarcel Holtmann 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
22308ee56540SMarcel Holtmann 		cancel_delayed_work(&hdev->power_off);
22318ee56540SMarcel Holtmann 
22321da177e4SLinus Torvalds 	err = hci_dev_do_close(hdev);
22338ee56540SMarcel Holtmann 
22340736cfa8SMarcel Holtmann done:
22351da177e4SLinus Torvalds 	hci_dev_put(hdev);
22361da177e4SLinus Torvalds 	return err;
22371da177e4SLinus Torvalds }
22381da177e4SLinus Torvalds 
22391da177e4SLinus Torvalds int hci_dev_reset(__u16 dev)
22401da177e4SLinus Torvalds {
22411da177e4SLinus Torvalds 	struct hci_dev *hdev;
22421da177e4SLinus Torvalds 	int ret = 0;
22431da177e4SLinus Torvalds 
224470f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
224570f23020SAndrei Emeltchenko 	if (!hdev)
22461da177e4SLinus Torvalds 		return -ENODEV;
22471da177e4SLinus Torvalds 
22481da177e4SLinus Torvalds 	hci_req_lock(hdev);
22491da177e4SLinus Torvalds 
2250808a049eSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
2251808a049eSMarcel Holtmann 		ret = -ENETDOWN;
22521da177e4SLinus Torvalds 		goto done;
2253808a049eSMarcel Holtmann 	}
22541da177e4SLinus Torvalds 
22550736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
22560736cfa8SMarcel Holtmann 		ret = -EBUSY;
22570736cfa8SMarcel Holtmann 		goto done;
22580736cfa8SMarcel Holtmann 	}
22590736cfa8SMarcel Holtmann 
22601da177e4SLinus Torvalds 	/* Drop queues */
22611da177e4SLinus Torvalds 	skb_queue_purge(&hdev->rx_q);
22621da177e4SLinus Torvalds 	skb_queue_purge(&hdev->cmd_q);
22631da177e4SLinus Torvalds 
226409fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
22651f9b9a5dSAndre Guedes 	hci_inquiry_cache_flush(hdev);
22661da177e4SLinus Torvalds 	hci_conn_hash_flush(hdev);
226709fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
22681da177e4SLinus Torvalds 
22691da177e4SLinus Torvalds 	if (hdev->flush)
22701da177e4SLinus Torvalds 		hdev->flush(hdev);
22711da177e4SLinus Torvalds 
22721da177e4SLinus Torvalds 	atomic_set(&hdev->cmd_cnt, 1);
22736ed58ec5SVille Tervo 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
22741da177e4SLinus Torvalds 
22751da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags))
227601178cd4SJohan Hedberg 		ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
22771da177e4SLinus Torvalds 
22781da177e4SLinus Torvalds done:
22791da177e4SLinus Torvalds 	hci_req_unlock(hdev);
22801da177e4SLinus Torvalds 	hci_dev_put(hdev);
22811da177e4SLinus Torvalds 	return ret;
22821da177e4SLinus Torvalds }
22831da177e4SLinus Torvalds 
22841da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev)
22851da177e4SLinus Torvalds {
22861da177e4SLinus Torvalds 	struct hci_dev *hdev;
22871da177e4SLinus Torvalds 	int ret = 0;
22881da177e4SLinus Torvalds 
228970f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dev);
229070f23020SAndrei Emeltchenko 	if (!hdev)
22911da177e4SLinus Torvalds 		return -ENODEV;
22921da177e4SLinus Torvalds 
22930736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
22940736cfa8SMarcel Holtmann 		ret = -EBUSY;
22950736cfa8SMarcel Holtmann 		goto done;
22960736cfa8SMarcel Holtmann 	}
22970736cfa8SMarcel Holtmann 
22981da177e4SLinus Torvalds 	memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
22991da177e4SLinus Torvalds 
23000736cfa8SMarcel Holtmann done:
23011da177e4SLinus Torvalds 	hci_dev_put(hdev);
23021da177e4SLinus Torvalds 	return ret;
23031da177e4SLinus Torvalds }
23041da177e4SLinus Torvalds 
23051da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg)
23061da177e4SLinus Torvalds {
23071da177e4SLinus Torvalds 	struct hci_dev *hdev;
23081da177e4SLinus Torvalds 	struct hci_dev_req dr;
23091da177e4SLinus Torvalds 	int err = 0;
23101da177e4SLinus Torvalds 
23111da177e4SLinus Torvalds 	if (copy_from_user(&dr, arg, sizeof(dr)))
23121da177e4SLinus Torvalds 		return -EFAULT;
23131da177e4SLinus Torvalds 
231470f23020SAndrei Emeltchenko 	hdev = hci_dev_get(dr.dev_id);
231570f23020SAndrei Emeltchenko 	if (!hdev)
23161da177e4SLinus Torvalds 		return -ENODEV;
23171da177e4SLinus Torvalds 
23180736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
23190736cfa8SMarcel Holtmann 		err = -EBUSY;
23200736cfa8SMarcel Holtmann 		goto done;
23210736cfa8SMarcel Holtmann 	}
23220736cfa8SMarcel Holtmann 
23235b69bef5SMarcel Holtmann 	if (hdev->dev_type != HCI_BREDR) {
23245b69bef5SMarcel Holtmann 		err = -EOPNOTSUPP;
23255b69bef5SMarcel Holtmann 		goto done;
23265b69bef5SMarcel Holtmann 	}
23275b69bef5SMarcel Holtmann 
232856f87901SJohan Hedberg 	if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
232956f87901SJohan Hedberg 		err = -EOPNOTSUPP;
233056f87901SJohan Hedberg 		goto done;
233156f87901SJohan Hedberg 	}
233256f87901SJohan Hedberg 
23331da177e4SLinus Torvalds 	switch (cmd) {
23341da177e4SLinus Torvalds 	case HCISETAUTH:
233501178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
23365f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
23371da177e4SLinus Torvalds 		break;
23381da177e4SLinus Torvalds 
23391da177e4SLinus Torvalds 	case HCISETENCRYPT:
23401da177e4SLinus Torvalds 		if (!lmp_encrypt_capable(hdev)) {
23411da177e4SLinus Torvalds 			err = -EOPNOTSUPP;
23421da177e4SLinus Torvalds 			break;
23431da177e4SLinus Torvalds 		}
23441da177e4SLinus Torvalds 
23451da177e4SLinus Torvalds 		if (!test_bit(HCI_AUTH, &hdev->flags)) {
23461da177e4SLinus Torvalds 			/* Auth must be enabled first */
234701178cd4SJohan Hedberg 			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
23485f246e89SAndrei Emeltchenko 					   HCI_INIT_TIMEOUT);
23491da177e4SLinus Torvalds 			if (err)
23501da177e4SLinus Torvalds 				break;
23511da177e4SLinus Torvalds 		}
23521da177e4SLinus Torvalds 
235301178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
23545f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
23551da177e4SLinus Torvalds 		break;
23561da177e4SLinus Torvalds 
23571da177e4SLinus Torvalds 	case HCISETSCAN:
235801178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
23595f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
23601da177e4SLinus Torvalds 		break;
23611da177e4SLinus Torvalds 
23621da177e4SLinus Torvalds 	case HCISETLINKPOL:
236301178cd4SJohan Hedberg 		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
23645f246e89SAndrei Emeltchenko 				   HCI_INIT_TIMEOUT);
23651da177e4SLinus Torvalds 		break;
23661da177e4SLinus Torvalds 
23671da177e4SLinus Torvalds 	case HCISETLINKMODE:
2368e4e8e37cSMarcel Holtmann 		hdev->link_mode = ((__u16) dr.dev_opt) &
2369e4e8e37cSMarcel Holtmann 					(HCI_LM_MASTER | HCI_LM_ACCEPT);
2370e4e8e37cSMarcel Holtmann 		break;
2371e4e8e37cSMarcel Holtmann 
2372e4e8e37cSMarcel Holtmann 	case HCISETPTYPE:
2373e4e8e37cSMarcel Holtmann 		hdev->pkt_type = (__u16) dr.dev_opt;
23741da177e4SLinus Torvalds 		break;
23751da177e4SLinus Torvalds 
23761da177e4SLinus Torvalds 	case HCISETACLMTU:
23771da177e4SLinus Torvalds 		hdev->acl_mtu  = *((__u16 *) &dr.dev_opt + 1);
23781da177e4SLinus Torvalds 		hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
23791da177e4SLinus Torvalds 		break;
23801da177e4SLinus Torvalds 
23811da177e4SLinus Torvalds 	case HCISETSCOMTU:
23821da177e4SLinus Torvalds 		hdev->sco_mtu  = *((__u16 *) &dr.dev_opt + 1);
23831da177e4SLinus Torvalds 		hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
23841da177e4SLinus Torvalds 		break;
23851da177e4SLinus Torvalds 
23861da177e4SLinus Torvalds 	default:
23871da177e4SLinus Torvalds 		err = -EINVAL;
23881da177e4SLinus Torvalds 		break;
23891da177e4SLinus Torvalds 	}
2390e4e8e37cSMarcel Holtmann 
23910736cfa8SMarcel Holtmann done:
23921da177e4SLinus Torvalds 	hci_dev_put(hdev);
23931da177e4SLinus Torvalds 	return err;
23941da177e4SLinus Torvalds }
23951da177e4SLinus Torvalds 
23961da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg)
23971da177e4SLinus Torvalds {
23988035ded4SLuiz Augusto von Dentz 	struct hci_dev *hdev;
23991da177e4SLinus Torvalds 	struct hci_dev_list_req *dl;
24001da177e4SLinus Torvalds 	struct hci_dev_req *dr;
24011da177e4SLinus Torvalds 	int n = 0, size, err;
24021da177e4SLinus Torvalds 	__u16 dev_num;
24031da177e4SLinus Torvalds 
24041da177e4SLinus Torvalds 	if (get_user(dev_num, (__u16 __user *) arg))
24051da177e4SLinus Torvalds 		return -EFAULT;
24061da177e4SLinus Torvalds 
24071da177e4SLinus Torvalds 	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
24081da177e4SLinus Torvalds 		return -EINVAL;
24091da177e4SLinus Torvalds 
24101da177e4SLinus Torvalds 	size = sizeof(*dl) + dev_num * sizeof(*dr);
24111da177e4SLinus Torvalds 
241270f23020SAndrei Emeltchenko 	dl = kzalloc(size, GFP_KERNEL);
241370f23020SAndrei Emeltchenko 	if (!dl)
24141da177e4SLinus Torvalds 		return -ENOMEM;
24151da177e4SLinus Torvalds 
24161da177e4SLinus Torvalds 	dr = dl->dev_req;
24171da177e4SLinus Torvalds 
2418f20d09d5SGustavo F. Padovan 	read_lock(&hci_dev_list_lock);
24198035ded4SLuiz Augusto von Dentz 	list_for_each_entry(hdev, &hci_dev_list, list) {
2420a8b2d5c2SJohan Hedberg 		if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
2421e0f9309fSJohan Hedberg 			cancel_delayed_work(&hdev->power_off);
2422c542a06cSJohan Hedberg 
2423a8b2d5c2SJohan Hedberg 		if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2424a8b2d5c2SJohan Hedberg 			set_bit(HCI_PAIRABLE, &hdev->dev_flags);
2425c542a06cSJohan Hedberg 
24261da177e4SLinus Torvalds 		(dr + n)->dev_id  = hdev->id;
24271da177e4SLinus Torvalds 		(dr + n)->dev_opt = hdev->flags;
2428c542a06cSJohan Hedberg 
24291da177e4SLinus Torvalds 		if (++n >= dev_num)
24301da177e4SLinus Torvalds 			break;
24311da177e4SLinus Torvalds 	}
2432f20d09d5SGustavo F. Padovan 	read_unlock(&hci_dev_list_lock);
24331da177e4SLinus Torvalds 
24341da177e4SLinus Torvalds 	dl->dev_num = n;
24351da177e4SLinus Torvalds 	size = sizeof(*dl) + n * sizeof(*dr);
24361da177e4SLinus Torvalds 
24371da177e4SLinus Torvalds 	err = copy_to_user(arg, dl, size);
24381da177e4SLinus Torvalds 	kfree(dl);
24391da177e4SLinus Torvalds 
24401da177e4SLinus Torvalds 	return err ? -EFAULT : 0;
24411da177e4SLinus Torvalds }
24421da177e4SLinus Torvalds 
24431da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg)
24441da177e4SLinus Torvalds {
24451da177e4SLinus Torvalds 	struct hci_dev *hdev;
24461da177e4SLinus Torvalds 	struct hci_dev_info di;
24471da177e4SLinus Torvalds 	int err = 0;
24481da177e4SLinus Torvalds 
24491da177e4SLinus Torvalds 	if (copy_from_user(&di, arg, sizeof(di)))
24501da177e4SLinus Torvalds 		return -EFAULT;
24511da177e4SLinus Torvalds 
245270f23020SAndrei Emeltchenko 	hdev = hci_dev_get(di.dev_id);
245370f23020SAndrei Emeltchenko 	if (!hdev)
24541da177e4SLinus Torvalds 		return -ENODEV;
24551da177e4SLinus Torvalds 
2456a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags))
24573243553fSJohan Hedberg 		cancel_delayed_work_sync(&hdev->power_off);
2458ab81cbf9SJohan Hedberg 
2459a8b2d5c2SJohan Hedberg 	if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2460a8b2d5c2SJohan Hedberg 		set_bit(HCI_PAIRABLE, &hdev->dev_flags);
2461c542a06cSJohan Hedberg 
24621da177e4SLinus Torvalds 	strcpy(di.name, hdev->name);
24631da177e4SLinus Torvalds 	di.bdaddr   = hdev->bdaddr;
246460f2a3edSMarcel Holtmann 	di.type     = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4);
24651da177e4SLinus Torvalds 	di.flags    = hdev->flags;
24661da177e4SLinus Torvalds 	di.pkt_type = hdev->pkt_type;
2467572c7f84SJohan Hedberg 	if (lmp_bredr_capable(hdev)) {
24681da177e4SLinus Torvalds 		di.acl_mtu  = hdev->acl_mtu;
24691da177e4SLinus Torvalds 		di.acl_pkts = hdev->acl_pkts;
24701da177e4SLinus Torvalds 		di.sco_mtu  = hdev->sco_mtu;
24711da177e4SLinus Torvalds 		di.sco_pkts = hdev->sco_pkts;
2472572c7f84SJohan Hedberg 	} else {
2473572c7f84SJohan Hedberg 		di.acl_mtu  = hdev->le_mtu;
2474572c7f84SJohan Hedberg 		di.acl_pkts = hdev->le_pkts;
2475572c7f84SJohan Hedberg 		di.sco_mtu  = 0;
2476572c7f84SJohan Hedberg 		di.sco_pkts = 0;
2477572c7f84SJohan Hedberg 	}
24781da177e4SLinus Torvalds 	di.link_policy = hdev->link_policy;
24791da177e4SLinus Torvalds 	di.link_mode   = hdev->link_mode;
24801da177e4SLinus Torvalds 
24811da177e4SLinus Torvalds 	memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
24821da177e4SLinus Torvalds 	memcpy(&di.features, &hdev->features, sizeof(di.features));
24831da177e4SLinus Torvalds 
24841da177e4SLinus Torvalds 	if (copy_to_user(arg, &di, sizeof(di)))
24851da177e4SLinus Torvalds 		err = -EFAULT;
24861da177e4SLinus Torvalds 
24871da177e4SLinus Torvalds 	hci_dev_put(hdev);
24881da177e4SLinus Torvalds 
24891da177e4SLinus Torvalds 	return err;
24901da177e4SLinus Torvalds }
24911da177e4SLinus Torvalds 
24921da177e4SLinus Torvalds /* ---- Interface to HCI drivers ---- */
24931da177e4SLinus Torvalds 
2494611b30f7SMarcel Holtmann static int hci_rfkill_set_block(void *data, bool blocked)
2495611b30f7SMarcel Holtmann {
2496611b30f7SMarcel Holtmann 	struct hci_dev *hdev = data;
2497611b30f7SMarcel Holtmann 
2498611b30f7SMarcel Holtmann 	BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
2499611b30f7SMarcel Holtmann 
25000736cfa8SMarcel Holtmann 	if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
25010736cfa8SMarcel Holtmann 		return -EBUSY;
25020736cfa8SMarcel Holtmann 
25035e130367SJohan Hedberg 	if (blocked) {
25045e130367SJohan Hedberg 		set_bit(HCI_RFKILLED, &hdev->dev_flags);
2505bf543036SJohan Hedberg 		if (!test_bit(HCI_SETUP, &hdev->dev_flags))
2506611b30f7SMarcel Holtmann 			hci_dev_do_close(hdev);
25075e130367SJohan Hedberg 	} else {
25085e130367SJohan Hedberg 		clear_bit(HCI_RFKILLED, &hdev->dev_flags);
25095e130367SJohan Hedberg 	}
2510611b30f7SMarcel Holtmann 
2511611b30f7SMarcel Holtmann 	return 0;
2512611b30f7SMarcel Holtmann }
2513611b30f7SMarcel Holtmann 
2514611b30f7SMarcel Holtmann static const struct rfkill_ops hci_rfkill_ops = {
2515611b30f7SMarcel Holtmann 	.set_block = hci_rfkill_set_block,
2516611b30f7SMarcel Holtmann };
2517611b30f7SMarcel Holtmann 
2518ab81cbf9SJohan Hedberg static void hci_power_on(struct work_struct *work)
2519ab81cbf9SJohan Hedberg {
2520ab81cbf9SJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
252196570ffcSJohan Hedberg 	int err;
2522ab81cbf9SJohan Hedberg 
2523ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
2524ab81cbf9SJohan Hedberg 
2525cbed0ca1SJohan Hedberg 	err = hci_dev_do_open(hdev);
252696570ffcSJohan Hedberg 	if (err < 0) {
252796570ffcSJohan Hedberg 		mgmt_set_powered_failed(hdev, err);
2528ab81cbf9SJohan Hedberg 		return;
252996570ffcSJohan Hedberg 	}
2530ab81cbf9SJohan Hedberg 
2531a5c8f270SMarcel Holtmann 	/* During the HCI setup phase, a few error conditions are
2532a5c8f270SMarcel Holtmann 	 * ignored and they need to be checked now. If they are still
2533a5c8f270SMarcel Holtmann 	 * valid, it is important to turn the device back off.
2534a5c8f270SMarcel Holtmann 	 */
2535a5c8f270SMarcel Holtmann 	if (test_bit(HCI_RFKILLED, &hdev->dev_flags) ||
2536a5c8f270SMarcel Holtmann 	    (hdev->dev_type == HCI_BREDR &&
2537a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
2538a5c8f270SMarcel Holtmann 	     !bacmp(&hdev->static_addr, BDADDR_ANY))) {
2539bf543036SJohan Hedberg 		clear_bit(HCI_AUTO_OFF, &hdev->dev_flags);
2540bf543036SJohan Hedberg 		hci_dev_do_close(hdev);
2541bf543036SJohan Hedberg 	} else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
254219202573SJohan Hedberg 		queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
254319202573SJohan Hedberg 				   HCI_AUTO_OFF_TIMEOUT);
2544bf543036SJohan Hedberg 	}
2545ab81cbf9SJohan Hedberg 
2546a8b2d5c2SJohan Hedberg 	if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags))
2547744cf19eSJohan Hedberg 		mgmt_index_added(hdev);
2548ab81cbf9SJohan Hedberg }
2549ab81cbf9SJohan Hedberg 
2550ab81cbf9SJohan Hedberg static void hci_power_off(struct work_struct *work)
2551ab81cbf9SJohan Hedberg {
25523243553fSJohan Hedberg 	struct hci_dev *hdev = container_of(work, struct hci_dev,
25533243553fSJohan Hedberg 					    power_off.work);
2554ab81cbf9SJohan Hedberg 
2555ab81cbf9SJohan Hedberg 	BT_DBG("%s", hdev->name);
2556ab81cbf9SJohan Hedberg 
25578ee56540SMarcel Holtmann 	hci_dev_do_close(hdev);
2558ab81cbf9SJohan Hedberg }
2559ab81cbf9SJohan Hedberg 
256016ab91abSJohan Hedberg static void hci_discov_off(struct work_struct *work)
256116ab91abSJohan Hedberg {
256216ab91abSJohan Hedberg 	struct hci_dev *hdev;
256316ab91abSJohan Hedberg 
256416ab91abSJohan Hedberg 	hdev = container_of(work, struct hci_dev, discov_off.work);
256516ab91abSJohan Hedberg 
256616ab91abSJohan Hedberg 	BT_DBG("%s", hdev->name);
256716ab91abSJohan Hedberg 
2568d1967ff8SMarcel Holtmann 	mgmt_discoverable_timeout(hdev);
256916ab91abSJohan Hedberg }
257016ab91abSJohan Hedberg 
257135f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev)
25722aeb9a1aSJohan Hedberg {
25734821002cSJohan Hedberg 	struct bt_uuid *uuid, *tmp;
25742aeb9a1aSJohan Hedberg 
25754821002cSJohan Hedberg 	list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) {
25764821002cSJohan Hedberg 		list_del(&uuid->list);
25772aeb9a1aSJohan Hedberg 		kfree(uuid);
25782aeb9a1aSJohan Hedberg 	}
25792aeb9a1aSJohan Hedberg }
25802aeb9a1aSJohan Hedberg 
258135f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev)
258255ed8ca1SJohan Hedberg {
258355ed8ca1SJohan Hedberg 	struct list_head *p, *n;
258455ed8ca1SJohan Hedberg 
258555ed8ca1SJohan Hedberg 	list_for_each_safe(p, n, &hdev->link_keys) {
258655ed8ca1SJohan Hedberg 		struct link_key *key;
258755ed8ca1SJohan Hedberg 
258855ed8ca1SJohan Hedberg 		key = list_entry(p, struct link_key, list);
258955ed8ca1SJohan Hedberg 
259055ed8ca1SJohan Hedberg 		list_del(p);
259155ed8ca1SJohan Hedberg 		kfree(key);
259255ed8ca1SJohan Hedberg 	}
259355ed8ca1SJohan Hedberg }
259455ed8ca1SJohan Hedberg 
259535f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev)
2596b899efafSVinicius Costa Gomes {
2597b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
2598b899efafSVinicius Costa Gomes 
2599b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
2600b899efafSVinicius Costa Gomes 		list_del(&k->list);
2601b899efafSVinicius Costa Gomes 		kfree(k);
2602b899efafSVinicius Costa Gomes 	}
2603b899efafSVinicius Costa Gomes }
2604b899efafSVinicius Costa Gomes 
2605970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev)
2606970c4e46SJohan Hedberg {
2607970c4e46SJohan Hedberg 	struct smp_irk *k, *tmp;
2608970c4e46SJohan Hedberg 
2609970c4e46SJohan Hedberg 	list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) {
2610970c4e46SJohan Hedberg 		list_del(&k->list);
2611970c4e46SJohan Hedberg 		kfree(k);
2612970c4e46SJohan Hedberg 	}
2613970c4e46SJohan Hedberg }
2614970c4e46SJohan Hedberg 
261555ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
261655ed8ca1SJohan Hedberg {
261755ed8ca1SJohan Hedberg 	struct link_key *k;
261855ed8ca1SJohan Hedberg 
26198035ded4SLuiz Augusto von Dentz 	list_for_each_entry(k, &hdev->link_keys, list)
262055ed8ca1SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) == 0)
262155ed8ca1SJohan Hedberg 			return k;
262255ed8ca1SJohan Hedberg 
262355ed8ca1SJohan Hedberg 	return NULL;
262455ed8ca1SJohan Hedberg }
262555ed8ca1SJohan Hedberg 
2626745c0ce3SVishal Agarwal static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
2627d25e28abSJohan Hedberg 			       u8 key_type, u8 old_key_type)
2628d25e28abSJohan Hedberg {
2629d25e28abSJohan Hedberg 	/* Legacy key */
2630d25e28abSJohan Hedberg 	if (key_type < 0x03)
2631745c0ce3SVishal Agarwal 		return true;
2632d25e28abSJohan Hedberg 
2633d25e28abSJohan Hedberg 	/* Debug keys are insecure so don't store them persistently */
2634d25e28abSJohan Hedberg 	if (key_type == HCI_LK_DEBUG_COMBINATION)
2635745c0ce3SVishal Agarwal 		return false;
2636d25e28abSJohan Hedberg 
2637d25e28abSJohan Hedberg 	/* Changed combination key and there's no previous one */
2638d25e28abSJohan Hedberg 	if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
2639745c0ce3SVishal Agarwal 		return false;
2640d25e28abSJohan Hedberg 
2641d25e28abSJohan Hedberg 	/* Security mode 3 case */
2642d25e28abSJohan Hedberg 	if (!conn)
2643745c0ce3SVishal Agarwal 		return true;
2644d25e28abSJohan Hedberg 
2645d25e28abSJohan Hedberg 	/* Neither local nor remote side had no-bonding as requirement */
2646d25e28abSJohan Hedberg 	if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
2647745c0ce3SVishal Agarwal 		return true;
2648d25e28abSJohan Hedberg 
2649d25e28abSJohan Hedberg 	/* Local side had dedicated bonding as requirement */
2650d25e28abSJohan Hedberg 	if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
2651745c0ce3SVishal Agarwal 		return true;
2652d25e28abSJohan Hedberg 
2653d25e28abSJohan Hedberg 	/* Remote side had dedicated bonding as requirement */
2654d25e28abSJohan Hedberg 	if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
2655745c0ce3SVishal Agarwal 		return true;
2656d25e28abSJohan Hedberg 
2657d25e28abSJohan Hedberg 	/* If none of the above criteria match, then don't store the key
2658d25e28abSJohan Hedberg 	 * persistently */
2659745c0ce3SVishal Agarwal 	return false;
2660d25e28abSJohan Hedberg }
2661d25e28abSJohan Hedberg 
266298a0b845SJohan Hedberg static bool ltk_type_master(u8 type)
266398a0b845SJohan Hedberg {
266498a0b845SJohan Hedberg 	if (type == HCI_SMP_STK || type == HCI_SMP_LTK)
266598a0b845SJohan Hedberg 		return true;
266698a0b845SJohan Hedberg 
266798a0b845SJohan Hedberg 	return false;
266898a0b845SJohan Hedberg }
266998a0b845SJohan Hedberg 
267098a0b845SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8],
267198a0b845SJohan Hedberg 			     bool master)
267275d262c2SVinicius Costa Gomes {
2673c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
267475d262c2SVinicius Costa Gomes 
2675c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list) {
2676c9839a11SVinicius Costa Gomes 		if (k->ediv != ediv ||
2677c9839a11SVinicius Costa Gomes 		    memcmp(rand, k->rand, sizeof(k->rand)))
267875d262c2SVinicius Costa Gomes 			continue;
267975d262c2SVinicius Costa Gomes 
268098a0b845SJohan Hedberg 		if (ltk_type_master(k->type) != master)
268198a0b845SJohan Hedberg 			continue;
268298a0b845SJohan Hedberg 
268375d262c2SVinicius Costa Gomes 		return k;
268475d262c2SVinicius Costa Gomes 	}
268575d262c2SVinicius Costa Gomes 
268675d262c2SVinicius Costa Gomes 	return NULL;
268775d262c2SVinicius Costa Gomes }
268875d262c2SVinicius Costa Gomes 
2689c9839a11SVinicius Costa Gomes struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
269098a0b845SJohan Hedberg 				     u8 addr_type, bool master)
269175d262c2SVinicius Costa Gomes {
2692c9839a11SVinicius Costa Gomes 	struct smp_ltk *k;
269375d262c2SVinicius Costa Gomes 
2694c9839a11SVinicius Costa Gomes 	list_for_each_entry(k, &hdev->long_term_keys, list)
2695c9839a11SVinicius Costa Gomes 		if (addr_type == k->bdaddr_type &&
269698a0b845SJohan Hedberg 		    bacmp(bdaddr, &k->bdaddr) == 0 &&
269798a0b845SJohan Hedberg 		    ltk_type_master(k->type) == master)
269875d262c2SVinicius Costa Gomes 			return k;
269975d262c2SVinicius Costa Gomes 
270075d262c2SVinicius Costa Gomes 	return NULL;
270175d262c2SVinicius Costa Gomes }
270275d262c2SVinicius Costa Gomes 
2703970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa)
2704970c4e46SJohan Hedberg {
2705970c4e46SJohan Hedberg 	struct smp_irk *irk;
2706970c4e46SJohan Hedberg 
2707970c4e46SJohan Hedberg 	list_for_each_entry(irk, &hdev->identity_resolving_keys, list) {
2708970c4e46SJohan Hedberg 		if (!bacmp(&irk->rpa, rpa))
2709970c4e46SJohan Hedberg 			return irk;
2710970c4e46SJohan Hedberg 	}
2711970c4e46SJohan Hedberg 
2712970c4e46SJohan Hedberg 	list_for_each_entry(irk, &hdev->identity_resolving_keys, list) {
2713970c4e46SJohan Hedberg 		if (smp_irk_matches(hdev->tfm_aes, irk->val, rpa)) {
2714970c4e46SJohan Hedberg 			bacpy(&irk->rpa, rpa);
2715970c4e46SJohan Hedberg 			return irk;
2716970c4e46SJohan Hedberg 		}
2717970c4e46SJohan Hedberg 	}
2718970c4e46SJohan Hedberg 
2719970c4e46SJohan Hedberg 	return NULL;
2720970c4e46SJohan Hedberg }
2721970c4e46SJohan Hedberg 
2722970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
2723970c4e46SJohan Hedberg 				     u8 addr_type)
2724970c4e46SJohan Hedberg {
2725970c4e46SJohan Hedberg 	struct smp_irk *irk;
2726970c4e46SJohan Hedberg 
27276cfc9988SJohan Hedberg 	/* Identity Address must be public or static random */
27286cfc9988SJohan Hedberg 	if (addr_type == ADDR_LE_DEV_RANDOM && (bdaddr->b[5] & 0xc0) != 0xc0)
27296cfc9988SJohan Hedberg 		return NULL;
27306cfc9988SJohan Hedberg 
2731970c4e46SJohan Hedberg 	list_for_each_entry(irk, &hdev->identity_resolving_keys, list) {
2732970c4e46SJohan Hedberg 		if (addr_type == irk->addr_type &&
2733970c4e46SJohan Hedberg 		    bacmp(bdaddr, &irk->bdaddr) == 0)
2734970c4e46SJohan Hedberg 			return irk;
2735970c4e46SJohan Hedberg 	}
2736970c4e46SJohan Hedberg 
2737970c4e46SJohan Hedberg 	return NULL;
2738970c4e46SJohan Hedberg }
2739970c4e46SJohan Hedberg 
2740d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
2741d25e28abSJohan Hedberg 		     bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
274255ed8ca1SJohan Hedberg {
274355ed8ca1SJohan Hedberg 	struct link_key *key, *old_key;
2744745c0ce3SVishal Agarwal 	u8 old_key_type;
2745745c0ce3SVishal Agarwal 	bool persistent;
274655ed8ca1SJohan Hedberg 
274755ed8ca1SJohan Hedberg 	old_key = hci_find_link_key(hdev, bdaddr);
274855ed8ca1SJohan Hedberg 	if (old_key) {
274955ed8ca1SJohan Hedberg 		old_key_type = old_key->type;
275055ed8ca1SJohan Hedberg 		key = old_key;
275155ed8ca1SJohan Hedberg 	} else {
275212adcf3aSJohan Hedberg 		old_key_type = conn ? conn->key_type : 0xff;
27530a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
275455ed8ca1SJohan Hedberg 		if (!key)
275555ed8ca1SJohan Hedberg 			return -ENOMEM;
275655ed8ca1SJohan Hedberg 		list_add(&key->list, &hdev->link_keys);
275755ed8ca1SJohan Hedberg 	}
275855ed8ca1SJohan Hedberg 
27596ed93dc6SAndrei Emeltchenko 	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
276055ed8ca1SJohan Hedberg 
2761d25e28abSJohan Hedberg 	/* Some buggy controller combinations generate a changed
2762d25e28abSJohan Hedberg 	 * combination key for legacy pairing even when there's no
2763d25e28abSJohan Hedberg 	 * previous key */
2764d25e28abSJohan Hedberg 	if (type == HCI_LK_CHANGED_COMBINATION &&
2765a8c5fb1aSGustavo Padovan 	    (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) {
2766d25e28abSJohan Hedberg 		type = HCI_LK_COMBINATION;
2767655fe6ecSJohan Hedberg 		if (conn)
2768655fe6ecSJohan Hedberg 			conn->key_type = type;
2769655fe6ecSJohan Hedberg 	}
2770d25e28abSJohan Hedberg 
277155ed8ca1SJohan Hedberg 	bacpy(&key->bdaddr, bdaddr);
27729b3b4460SAndrei Emeltchenko 	memcpy(key->val, val, HCI_LINK_KEY_SIZE);
277355ed8ca1SJohan Hedberg 	key->pin_len = pin_len;
277455ed8ca1SJohan Hedberg 
2775b6020ba0SWaldemar Rymarkiewicz 	if (type == HCI_LK_CHANGED_COMBINATION)
277655ed8ca1SJohan Hedberg 		key->type = old_key_type;
27774748fed2SJohan Hedberg 	else
27784748fed2SJohan Hedberg 		key->type = type;
27794748fed2SJohan Hedberg 
27804df378a1SJohan Hedberg 	if (!new_key)
27814df378a1SJohan Hedberg 		return 0;
27824df378a1SJohan Hedberg 
27834df378a1SJohan Hedberg 	persistent = hci_persistent_key(hdev, conn, type, old_key_type);
27844df378a1SJohan Hedberg 
2785744cf19eSJohan Hedberg 	mgmt_new_link_key(hdev, key, persistent);
27864df378a1SJohan Hedberg 
27876ec5bcadSVishal Agarwal 	if (conn)
27886ec5bcadSVishal Agarwal 		conn->flush_key = !persistent;
278955ed8ca1SJohan Hedberg 
279055ed8ca1SJohan Hedberg 	return 0;
279155ed8ca1SJohan Hedberg }
279255ed8ca1SJohan Hedberg 
2793ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
279435d70271SJohan Hedberg 			    u8 addr_type, u8 type, u8 authenticated,
279535d70271SJohan Hedberg 			    u8 tk[16], u8 enc_size, __le16 ediv, u8 rand[8])
279675d262c2SVinicius Costa Gomes {
2797c9839a11SVinicius Costa Gomes 	struct smp_ltk *key, *old_key;
279898a0b845SJohan Hedberg 	bool master = ltk_type_master(type);
279975d262c2SVinicius Costa Gomes 
280098a0b845SJohan Hedberg 	old_key = hci_find_ltk_by_addr(hdev, bdaddr, addr_type, master);
2801c9839a11SVinicius Costa Gomes 	if (old_key)
280275d262c2SVinicius Costa Gomes 		key = old_key;
2803c9839a11SVinicius Costa Gomes 	else {
28040a14ab41SJohan Hedberg 		key = kzalloc(sizeof(*key), GFP_KERNEL);
280575d262c2SVinicius Costa Gomes 		if (!key)
2806ca9142b8SJohan Hedberg 			return NULL;
2807c9839a11SVinicius Costa Gomes 		list_add(&key->list, &hdev->long_term_keys);
280875d262c2SVinicius Costa Gomes 	}
280975d262c2SVinicius Costa Gomes 
281075d262c2SVinicius Costa Gomes 	bacpy(&key->bdaddr, bdaddr);
2811c9839a11SVinicius Costa Gomes 	key->bdaddr_type = addr_type;
2812c9839a11SVinicius Costa Gomes 	memcpy(key->val, tk, sizeof(key->val));
2813c9839a11SVinicius Costa Gomes 	key->authenticated = authenticated;
2814c9839a11SVinicius Costa Gomes 	key->ediv = ediv;
2815c9839a11SVinicius Costa Gomes 	key->enc_size = enc_size;
2816c9839a11SVinicius Costa Gomes 	key->type = type;
2817c9839a11SVinicius Costa Gomes 	memcpy(key->rand, rand, sizeof(key->rand));
281875d262c2SVinicius Costa Gomes 
2819ca9142b8SJohan Hedberg 	return key;
282075d262c2SVinicius Costa Gomes }
282175d262c2SVinicius Costa Gomes 
2822ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr,
2823ca9142b8SJohan Hedberg 			    u8 addr_type, u8 val[16], bdaddr_t *rpa)
2824970c4e46SJohan Hedberg {
2825970c4e46SJohan Hedberg 	struct smp_irk *irk;
2826970c4e46SJohan Hedberg 
2827970c4e46SJohan Hedberg 	irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type);
2828970c4e46SJohan Hedberg 	if (!irk) {
2829970c4e46SJohan Hedberg 		irk = kzalloc(sizeof(*irk), GFP_KERNEL);
2830970c4e46SJohan Hedberg 		if (!irk)
2831ca9142b8SJohan Hedberg 			return NULL;
2832970c4e46SJohan Hedberg 
2833970c4e46SJohan Hedberg 		bacpy(&irk->bdaddr, bdaddr);
2834970c4e46SJohan Hedberg 		irk->addr_type = addr_type;
2835970c4e46SJohan Hedberg 
2836970c4e46SJohan Hedberg 		list_add(&irk->list, &hdev->identity_resolving_keys);
2837970c4e46SJohan Hedberg 	}
2838970c4e46SJohan Hedberg 
2839970c4e46SJohan Hedberg 	memcpy(irk->val, val, 16);
2840970c4e46SJohan Hedberg 	bacpy(&irk->rpa, rpa);
2841970c4e46SJohan Hedberg 
2842ca9142b8SJohan Hedberg 	return irk;
2843970c4e46SJohan Hedberg }
2844970c4e46SJohan Hedberg 
284555ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
284655ed8ca1SJohan Hedberg {
284755ed8ca1SJohan Hedberg 	struct link_key *key;
284855ed8ca1SJohan Hedberg 
284955ed8ca1SJohan Hedberg 	key = hci_find_link_key(hdev, bdaddr);
285055ed8ca1SJohan Hedberg 	if (!key)
285155ed8ca1SJohan Hedberg 		return -ENOENT;
285255ed8ca1SJohan Hedberg 
28536ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
285455ed8ca1SJohan Hedberg 
285555ed8ca1SJohan Hedberg 	list_del(&key->list);
285655ed8ca1SJohan Hedberg 	kfree(key);
285755ed8ca1SJohan Hedberg 
285855ed8ca1SJohan Hedberg 	return 0;
285955ed8ca1SJohan Hedberg }
286055ed8ca1SJohan Hedberg 
2861e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type)
2862b899efafSVinicius Costa Gomes {
2863b899efafSVinicius Costa Gomes 	struct smp_ltk *k, *tmp;
2864c51ffa0bSJohan Hedberg 	int removed = 0;
2865b899efafSVinicius Costa Gomes 
2866b899efafSVinicius Costa Gomes 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
2867e0b2b27eSJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type)
2868b899efafSVinicius Costa Gomes 			continue;
2869b899efafSVinicius Costa Gomes 
28706ed93dc6SAndrei Emeltchenko 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
2871b899efafSVinicius Costa Gomes 
2872b899efafSVinicius Costa Gomes 		list_del(&k->list);
2873b899efafSVinicius Costa Gomes 		kfree(k);
2874c51ffa0bSJohan Hedberg 		removed++;
2875b899efafSVinicius Costa Gomes 	}
2876b899efafSVinicius Costa Gomes 
2877c51ffa0bSJohan Hedberg 	return removed ? 0 : -ENOENT;
2878b899efafSVinicius Costa Gomes }
2879b899efafSVinicius Costa Gomes 
2880a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type)
2881a7ec7338SJohan Hedberg {
2882a7ec7338SJohan Hedberg 	struct smp_irk *k, *tmp;
2883a7ec7338SJohan Hedberg 
2884a7ec7338SJohan Hedberg 	list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
2885a7ec7338SJohan Hedberg 		if (bacmp(bdaddr, &k->bdaddr) || k->addr_type != addr_type)
2886a7ec7338SJohan Hedberg 			continue;
2887a7ec7338SJohan Hedberg 
2888a7ec7338SJohan Hedberg 		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
2889a7ec7338SJohan Hedberg 
2890a7ec7338SJohan Hedberg 		list_del(&k->list);
2891a7ec7338SJohan Hedberg 		kfree(k);
2892a7ec7338SJohan Hedberg 	}
2893a7ec7338SJohan Hedberg }
2894a7ec7338SJohan Hedberg 
28956bd32326SVille Tervo /* HCI command timer function */
2896bda4f23aSAndrei Emeltchenko static void hci_cmd_timeout(unsigned long arg)
28976bd32326SVille Tervo {
28986bd32326SVille Tervo 	struct hci_dev *hdev = (void *) arg;
28996bd32326SVille Tervo 
2900bda4f23aSAndrei Emeltchenko 	if (hdev->sent_cmd) {
2901bda4f23aSAndrei Emeltchenko 		struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
2902bda4f23aSAndrei Emeltchenko 		u16 opcode = __le16_to_cpu(sent->opcode);
2903bda4f23aSAndrei Emeltchenko 
2904bda4f23aSAndrei Emeltchenko 		BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode);
2905bda4f23aSAndrei Emeltchenko 	} else {
29066bd32326SVille Tervo 		BT_ERR("%s command tx timeout", hdev->name);
2907bda4f23aSAndrei Emeltchenko 	}
2908bda4f23aSAndrei Emeltchenko 
29096bd32326SVille Tervo 	atomic_set(&hdev->cmd_cnt, 1);
2910c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
29116bd32326SVille Tervo }
29126bd32326SVille Tervo 
29132763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
29142763eda6SSzymon Janc 					  bdaddr_t *bdaddr)
29152763eda6SSzymon Janc {
29162763eda6SSzymon Janc 	struct oob_data *data;
29172763eda6SSzymon Janc 
29182763eda6SSzymon Janc 	list_for_each_entry(data, &hdev->remote_oob_data, list)
29192763eda6SSzymon Janc 		if (bacmp(bdaddr, &data->bdaddr) == 0)
29202763eda6SSzymon Janc 			return data;
29212763eda6SSzymon Janc 
29222763eda6SSzymon Janc 	return NULL;
29232763eda6SSzymon Janc }
29242763eda6SSzymon Janc 
29252763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
29262763eda6SSzymon Janc {
29272763eda6SSzymon Janc 	struct oob_data *data;
29282763eda6SSzymon Janc 
29292763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
29302763eda6SSzymon Janc 	if (!data)
29312763eda6SSzymon Janc 		return -ENOENT;
29322763eda6SSzymon Janc 
29336ed93dc6SAndrei Emeltchenko 	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
29342763eda6SSzymon Janc 
29352763eda6SSzymon Janc 	list_del(&data->list);
29362763eda6SSzymon Janc 	kfree(data);
29372763eda6SSzymon Janc 
29382763eda6SSzymon Janc 	return 0;
29392763eda6SSzymon Janc }
29402763eda6SSzymon Janc 
294135f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev)
29422763eda6SSzymon Janc {
29432763eda6SSzymon Janc 	struct oob_data *data, *n;
29442763eda6SSzymon Janc 
29452763eda6SSzymon Janc 	list_for_each_entry_safe(data, n, &hdev->remote_oob_data, list) {
29462763eda6SSzymon Janc 		list_del(&data->list);
29472763eda6SSzymon Janc 		kfree(data);
29482763eda6SSzymon Janc 	}
29492763eda6SSzymon Janc }
29502763eda6SSzymon Janc 
29510798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
29520798872eSMarcel Holtmann 			    u8 *hash, u8 *randomizer)
29532763eda6SSzymon Janc {
29542763eda6SSzymon Janc 	struct oob_data *data;
29552763eda6SSzymon Janc 
29562763eda6SSzymon Janc 	data = hci_find_remote_oob_data(hdev, bdaddr);
29572763eda6SSzymon Janc 	if (!data) {
29580a14ab41SJohan Hedberg 		data = kmalloc(sizeof(*data), GFP_KERNEL);
29592763eda6SSzymon Janc 		if (!data)
29602763eda6SSzymon Janc 			return -ENOMEM;
29612763eda6SSzymon Janc 
29622763eda6SSzymon Janc 		bacpy(&data->bdaddr, bdaddr);
29632763eda6SSzymon Janc 		list_add(&data->list, &hdev->remote_oob_data);
29642763eda6SSzymon Janc 	}
29652763eda6SSzymon Janc 
2966519ca9d0SMarcel Holtmann 	memcpy(data->hash192, hash, sizeof(data->hash192));
2967519ca9d0SMarcel Holtmann 	memcpy(data->randomizer192, randomizer, sizeof(data->randomizer192));
29682763eda6SSzymon Janc 
29690798872eSMarcel Holtmann 	memset(data->hash256, 0, sizeof(data->hash256));
29700798872eSMarcel Holtmann 	memset(data->randomizer256, 0, sizeof(data->randomizer256));
29710798872eSMarcel Holtmann 
29720798872eSMarcel Holtmann 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
29730798872eSMarcel Holtmann 
29740798872eSMarcel Holtmann 	return 0;
29750798872eSMarcel Holtmann }
29760798872eSMarcel Holtmann 
29770798872eSMarcel Holtmann int hci_add_remote_oob_ext_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
29780798872eSMarcel Holtmann 				u8 *hash192, u8 *randomizer192,
29790798872eSMarcel Holtmann 				u8 *hash256, u8 *randomizer256)
29800798872eSMarcel Holtmann {
29810798872eSMarcel Holtmann 	struct oob_data *data;
29820798872eSMarcel Holtmann 
29830798872eSMarcel Holtmann 	data = hci_find_remote_oob_data(hdev, bdaddr);
29840798872eSMarcel Holtmann 	if (!data) {
29850a14ab41SJohan Hedberg 		data = kmalloc(sizeof(*data), GFP_KERNEL);
29860798872eSMarcel Holtmann 		if (!data)
29870798872eSMarcel Holtmann 			return -ENOMEM;
29880798872eSMarcel Holtmann 
29890798872eSMarcel Holtmann 		bacpy(&data->bdaddr, bdaddr);
29900798872eSMarcel Holtmann 		list_add(&data->list, &hdev->remote_oob_data);
29910798872eSMarcel Holtmann 	}
29920798872eSMarcel Holtmann 
29930798872eSMarcel Holtmann 	memcpy(data->hash192, hash192, sizeof(data->hash192));
29940798872eSMarcel Holtmann 	memcpy(data->randomizer192, randomizer192, sizeof(data->randomizer192));
29950798872eSMarcel Holtmann 
29960798872eSMarcel Holtmann 	memcpy(data->hash256, hash256, sizeof(data->hash256));
29970798872eSMarcel Holtmann 	memcpy(data->randomizer256, randomizer256, sizeof(data->randomizer256));
29980798872eSMarcel Holtmann 
29996ed93dc6SAndrei Emeltchenko 	BT_DBG("%s for %pMR", hdev->name, bdaddr);
30002763eda6SSzymon Janc 
30012763eda6SSzymon Janc 	return 0;
30022763eda6SSzymon Janc }
30032763eda6SSzymon Janc 
3004b9ee0a78SMarcel Holtmann struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev,
3005b9ee0a78SMarcel Holtmann 					 bdaddr_t *bdaddr, u8 type)
3006b2a66aadSAntti Julku {
3007b2a66aadSAntti Julku 	struct bdaddr_list *b;
3008b2a66aadSAntti Julku 
3009b9ee0a78SMarcel Holtmann 	list_for_each_entry(b, &hdev->blacklist, list) {
3010b9ee0a78SMarcel Holtmann 		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
3011b2a66aadSAntti Julku 			return b;
3012b9ee0a78SMarcel Holtmann 	}
3013b2a66aadSAntti Julku 
3014b2a66aadSAntti Julku 	return NULL;
3015b2a66aadSAntti Julku }
3016b2a66aadSAntti Julku 
301735f7498aSJohan Hedberg void hci_blacklist_clear(struct hci_dev *hdev)
3018b2a66aadSAntti Julku {
3019b2a66aadSAntti Julku 	struct list_head *p, *n;
3020b2a66aadSAntti Julku 
3021b2a66aadSAntti Julku 	list_for_each_safe(p, n, &hdev->blacklist) {
3022b9ee0a78SMarcel Holtmann 		struct bdaddr_list *b = list_entry(p, struct bdaddr_list, list);
3023b2a66aadSAntti Julku 
3024b2a66aadSAntti Julku 		list_del(p);
3025b2a66aadSAntti Julku 		kfree(b);
3026b2a66aadSAntti Julku 	}
3027b2a66aadSAntti Julku }
3028b2a66aadSAntti Julku 
302988c1fe4bSJohan Hedberg int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3030b2a66aadSAntti Julku {
3031b2a66aadSAntti Julku 	struct bdaddr_list *entry;
3032b2a66aadSAntti Julku 
3033b9ee0a78SMarcel Holtmann 	if (!bacmp(bdaddr, BDADDR_ANY))
3034b2a66aadSAntti Julku 		return -EBADF;
3035b2a66aadSAntti Julku 
3036b9ee0a78SMarcel Holtmann 	if (hci_blacklist_lookup(hdev, bdaddr, type))
30375e762444SAntti Julku 		return -EEXIST;
3038b2a66aadSAntti Julku 
3039b2a66aadSAntti Julku 	entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
30405e762444SAntti Julku 	if (!entry)
30415e762444SAntti Julku 		return -ENOMEM;
3042b2a66aadSAntti Julku 
3043b2a66aadSAntti Julku 	bacpy(&entry->bdaddr, bdaddr);
3044b9ee0a78SMarcel Holtmann 	entry->bdaddr_type = type;
3045b2a66aadSAntti Julku 
3046b2a66aadSAntti Julku 	list_add(&entry->list, &hdev->blacklist);
3047b2a66aadSAntti Julku 
304888c1fe4bSJohan Hedberg 	return mgmt_device_blocked(hdev, bdaddr, type);
3049b2a66aadSAntti Julku }
3050b2a66aadSAntti Julku 
305188c1fe4bSJohan Hedberg int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3052b2a66aadSAntti Julku {
3053b2a66aadSAntti Julku 	struct bdaddr_list *entry;
3054b2a66aadSAntti Julku 
305535f7498aSJohan Hedberg 	if (!bacmp(bdaddr, BDADDR_ANY)) {
305635f7498aSJohan Hedberg 		hci_blacklist_clear(hdev);
305735f7498aSJohan Hedberg 		return 0;
305835f7498aSJohan Hedberg 	}
3059b2a66aadSAntti Julku 
3060b9ee0a78SMarcel Holtmann 	entry = hci_blacklist_lookup(hdev, bdaddr, type);
30611ec918ceSSzymon Janc 	if (!entry)
30625e762444SAntti Julku 		return -ENOENT;
3063b2a66aadSAntti Julku 
3064b2a66aadSAntti Julku 	list_del(&entry->list);
3065b2a66aadSAntti Julku 	kfree(entry);
3066b2a66aadSAntti Julku 
306788c1fe4bSJohan Hedberg 	return mgmt_device_unblocked(hdev, bdaddr, type);
3068b2a66aadSAntti Julku }
3069b2a66aadSAntti Julku 
307015819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
307115819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
307215819a70SAndre Guedes 					       bdaddr_t *addr, u8 addr_type)
307315819a70SAndre Guedes {
307415819a70SAndre Guedes 	struct hci_conn_params *params;
307515819a70SAndre Guedes 
307615819a70SAndre Guedes 	list_for_each_entry(params, &hdev->le_conn_params, list) {
307715819a70SAndre Guedes 		if (bacmp(&params->addr, addr) == 0 &&
307815819a70SAndre Guedes 		    params->addr_type == addr_type) {
307915819a70SAndre Guedes 			return params;
308015819a70SAndre Guedes 		}
308115819a70SAndre Guedes 	}
308215819a70SAndre Guedes 
308315819a70SAndre Guedes 	return NULL;
308415819a70SAndre Guedes }
308515819a70SAndre Guedes 
308615819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
308715819a70SAndre Guedes void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
308815819a70SAndre Guedes 			 u16 conn_min_interval, u16 conn_max_interval)
308915819a70SAndre Guedes {
309015819a70SAndre Guedes 	struct hci_conn_params *params;
309115819a70SAndre Guedes 
309215819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
309315819a70SAndre Guedes 	if (params) {
309415819a70SAndre Guedes 		params->conn_min_interval = conn_min_interval;
309515819a70SAndre Guedes 		params->conn_max_interval = conn_max_interval;
309615819a70SAndre Guedes 		return;
309715819a70SAndre Guedes 	}
309815819a70SAndre Guedes 
309915819a70SAndre Guedes 	params = kzalloc(sizeof(*params), GFP_KERNEL);
310015819a70SAndre Guedes 	if (!params) {
310115819a70SAndre Guedes 		BT_ERR("Out of memory");
310215819a70SAndre Guedes 		return;
310315819a70SAndre Guedes 	}
310415819a70SAndre Guedes 
310515819a70SAndre Guedes 	bacpy(&params->addr, addr);
310615819a70SAndre Guedes 	params->addr_type = addr_type;
310715819a70SAndre Guedes 	params->conn_min_interval = conn_min_interval;
310815819a70SAndre Guedes 	params->conn_max_interval = conn_max_interval;
310915819a70SAndre Guedes 
311015819a70SAndre Guedes 	list_add(&params->list, &hdev->le_conn_params);
311115819a70SAndre Guedes 
311215819a70SAndre Guedes 	BT_DBG("addr %pMR (type %u) conn_min_interval 0x%.4x "
311315819a70SAndre Guedes 	       "conn_max_interval 0x%.4x", addr, addr_type, conn_min_interval,
311415819a70SAndre Guedes 	       conn_max_interval);
311515819a70SAndre Guedes }
311615819a70SAndre Guedes 
311715819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
311815819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
311915819a70SAndre Guedes {
312015819a70SAndre Guedes 	struct hci_conn_params *params;
312115819a70SAndre Guedes 
312215819a70SAndre Guedes 	params = hci_conn_params_lookup(hdev, addr, addr_type);
312315819a70SAndre Guedes 	if (!params)
312415819a70SAndre Guedes 		return;
312515819a70SAndre Guedes 
312615819a70SAndre Guedes 	list_del(&params->list);
312715819a70SAndre Guedes 	kfree(params);
312815819a70SAndre Guedes 
312915819a70SAndre Guedes 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
313015819a70SAndre Guedes }
313115819a70SAndre Guedes 
313215819a70SAndre Guedes /* This function requires the caller holds hdev->lock */
313315819a70SAndre Guedes void hci_conn_params_clear(struct hci_dev *hdev)
313415819a70SAndre Guedes {
313515819a70SAndre Guedes 	struct hci_conn_params *params, *tmp;
313615819a70SAndre Guedes 
313715819a70SAndre Guedes 	list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
313815819a70SAndre Guedes 		list_del(&params->list);
313915819a70SAndre Guedes 		kfree(params);
314015819a70SAndre Guedes 	}
314115819a70SAndre Guedes 
314215819a70SAndre Guedes 	BT_DBG("All LE connection parameters were removed");
314315819a70SAndre Guedes }
314415819a70SAndre Guedes 
31454c87eaabSAndre Guedes static void inquiry_complete(struct hci_dev *hdev, u8 status)
31467ba8b4beSAndre Guedes {
31474c87eaabSAndre Guedes 	if (status) {
31484c87eaabSAndre Guedes 		BT_ERR("Failed to start inquiry: status %d", status);
31497ba8b4beSAndre Guedes 
31504c87eaabSAndre Guedes 		hci_dev_lock(hdev);
31514c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
31524c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
31534c87eaabSAndre Guedes 		return;
31544c87eaabSAndre Guedes 	}
31557ba8b4beSAndre Guedes }
31567ba8b4beSAndre Guedes 
31574c87eaabSAndre Guedes static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status)
31587ba8b4beSAndre Guedes {
31594c87eaabSAndre Guedes 	/* General inquiry access code (GIAC) */
31604c87eaabSAndre Guedes 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
31614c87eaabSAndre Guedes 	struct hci_request req;
31624c87eaabSAndre Guedes 	struct hci_cp_inquiry cp;
31637ba8b4beSAndre Guedes 	int err;
31647ba8b4beSAndre Guedes 
31654c87eaabSAndre Guedes 	if (status) {
31664c87eaabSAndre Guedes 		BT_ERR("Failed to disable LE scanning: status %d", status);
31674c87eaabSAndre Guedes 		return;
31687ba8b4beSAndre Guedes 	}
31697ba8b4beSAndre Guedes 
31704c87eaabSAndre Guedes 	switch (hdev->discovery.type) {
31714c87eaabSAndre Guedes 	case DISCOV_TYPE_LE:
31724c87eaabSAndre Guedes 		hci_dev_lock(hdev);
31734c87eaabSAndre Guedes 		hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
31744c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
31754c87eaabSAndre Guedes 		break;
31767dbfac1dSAndre Guedes 
31774c87eaabSAndre Guedes 	case DISCOV_TYPE_INTERLEAVED:
31784c87eaabSAndre Guedes 		hci_req_init(&req, hdev);
31797dbfac1dSAndre Guedes 
31807dbfac1dSAndre Guedes 		memset(&cp, 0, sizeof(cp));
31814c87eaabSAndre Guedes 		memcpy(&cp.lap, lap, sizeof(cp.lap));
31824c87eaabSAndre Guedes 		cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN;
31834c87eaabSAndre Guedes 		hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp);
31844c87eaabSAndre Guedes 
31854c87eaabSAndre Guedes 		hci_dev_lock(hdev);
31864c87eaabSAndre Guedes 
31874c87eaabSAndre Guedes 		hci_inquiry_cache_flush(hdev);
31884c87eaabSAndre Guedes 
31894c87eaabSAndre Guedes 		err = hci_req_run(&req, inquiry_complete);
31904c87eaabSAndre Guedes 		if (err) {
31914c87eaabSAndre Guedes 			BT_ERR("Inquiry request failed: err %d", err);
31924c87eaabSAndre Guedes 			hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
31937dbfac1dSAndre Guedes 		}
31947dbfac1dSAndre Guedes 
31954c87eaabSAndre Guedes 		hci_dev_unlock(hdev);
31964c87eaabSAndre Guedes 		break;
31974c87eaabSAndre Guedes 	}
31987dbfac1dSAndre Guedes }
31997dbfac1dSAndre Guedes 
32007ba8b4beSAndre Guedes static void le_scan_disable_work(struct work_struct *work)
32017ba8b4beSAndre Guedes {
32027ba8b4beSAndre Guedes 	struct hci_dev *hdev = container_of(work, struct hci_dev,
32037ba8b4beSAndre Guedes 					    le_scan_disable.work);
32047ba8b4beSAndre Guedes 	struct hci_cp_le_set_scan_enable cp;
32054c87eaabSAndre Guedes 	struct hci_request req;
32064c87eaabSAndre Guedes 	int err;
32077ba8b4beSAndre Guedes 
32087ba8b4beSAndre Guedes 	BT_DBG("%s", hdev->name);
32097ba8b4beSAndre Guedes 
32104c87eaabSAndre Guedes 	hci_req_init(&req, hdev);
32117ba8b4beSAndre Guedes 
32127ba8b4beSAndre Guedes 	memset(&cp, 0, sizeof(cp));
32134c87eaabSAndre Guedes 	cp.enable = LE_SCAN_DISABLE;
32144c87eaabSAndre Guedes 	hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
32157ba8b4beSAndre Guedes 
32164c87eaabSAndre Guedes 	err = hci_req_run(&req, le_scan_disable_work_complete);
32174c87eaabSAndre Guedes 	if (err)
32184c87eaabSAndre Guedes 		BT_ERR("Disable LE scanning request failed: err %d", err);
321928b75a89SAndre Guedes }
322028b75a89SAndre Guedes 
32219be0dab7SDavid Herrmann /* Alloc HCI device */
32229be0dab7SDavid Herrmann struct hci_dev *hci_alloc_dev(void)
32239be0dab7SDavid Herrmann {
32249be0dab7SDavid Herrmann 	struct hci_dev *hdev;
32259be0dab7SDavid Herrmann 
32269be0dab7SDavid Herrmann 	hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
32279be0dab7SDavid Herrmann 	if (!hdev)
32289be0dab7SDavid Herrmann 		return NULL;
32299be0dab7SDavid Herrmann 
3230b1b813d4SDavid Herrmann 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
3231b1b813d4SDavid Herrmann 	hdev->esco_type = (ESCO_HV1);
3232b1b813d4SDavid Herrmann 	hdev->link_mode = (HCI_LM_ACCEPT);
3233b4cb9fb2SMarcel Holtmann 	hdev->num_iac = 0x01;		/* One IAC support is mandatory */
3234b1b813d4SDavid Herrmann 	hdev->io_capability = 0x03;	/* No Input No Output */
3235bbaf444aSJohan Hedberg 	hdev->inq_tx_power = HCI_TX_POWER_INVALID;
3236bbaf444aSJohan Hedberg 	hdev->adv_tx_power = HCI_TX_POWER_INVALID;
3237b1b813d4SDavid Herrmann 
3238b1b813d4SDavid Herrmann 	hdev->sniff_max_interval = 800;
3239b1b813d4SDavid Herrmann 	hdev->sniff_min_interval = 80;
3240b1b813d4SDavid Herrmann 
3241bef64738SMarcel Holtmann 	hdev->le_scan_interval = 0x0060;
3242bef64738SMarcel Holtmann 	hdev->le_scan_window = 0x0030;
32434e70c7e7SMarcel Holtmann 	hdev->le_conn_min_interval = 0x0028;
32444e70c7e7SMarcel Holtmann 	hdev->le_conn_max_interval = 0x0038;
3245bef64738SMarcel Holtmann 
3246b1b813d4SDavid Herrmann 	mutex_init(&hdev->lock);
3247b1b813d4SDavid Herrmann 	mutex_init(&hdev->req_lock);
3248b1b813d4SDavid Herrmann 
3249b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->mgmt_pending);
3250b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->blacklist);
3251b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->uuids);
3252b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->link_keys);
3253b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->long_term_keys);
3254970c4e46SJohan Hedberg 	INIT_LIST_HEAD(&hdev->identity_resolving_keys);
3255b1b813d4SDavid Herrmann 	INIT_LIST_HEAD(&hdev->remote_oob_data);
325615819a70SAndre Guedes 	INIT_LIST_HEAD(&hdev->le_conn_params);
32576b536b5eSAndrei Emeltchenko 	INIT_LIST_HEAD(&hdev->conn_hash.list);
3258b1b813d4SDavid Herrmann 
3259b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->rx_work, hci_rx_work);
3260b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
3261b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->tx_work, hci_tx_work);
3262b1b813d4SDavid Herrmann 	INIT_WORK(&hdev->power_on, hci_power_on);
3263b1b813d4SDavid Herrmann 
3264b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
3265b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
3266b1b813d4SDavid Herrmann 	INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
3267b1b813d4SDavid Herrmann 
3268b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->rx_q);
3269b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->cmd_q);
3270b1b813d4SDavid Herrmann 	skb_queue_head_init(&hdev->raw_q);
3271b1b813d4SDavid Herrmann 
3272b1b813d4SDavid Herrmann 	init_waitqueue_head(&hdev->req_wait_q);
3273b1b813d4SDavid Herrmann 
3274bda4f23aSAndrei Emeltchenko 	setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev);
3275b1b813d4SDavid Herrmann 
3276b1b813d4SDavid Herrmann 	hci_init_sysfs(hdev);
3277b1b813d4SDavid Herrmann 	discovery_init(hdev);
32789be0dab7SDavid Herrmann 
32799be0dab7SDavid Herrmann 	return hdev;
32809be0dab7SDavid Herrmann }
32819be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_alloc_dev);
32829be0dab7SDavid Herrmann 
32839be0dab7SDavid Herrmann /* Free HCI device */
32849be0dab7SDavid Herrmann void hci_free_dev(struct hci_dev *hdev)
32859be0dab7SDavid Herrmann {
32869be0dab7SDavid Herrmann 	/* will free via device release */
32879be0dab7SDavid Herrmann 	put_device(&hdev->dev);
32889be0dab7SDavid Herrmann }
32899be0dab7SDavid Herrmann EXPORT_SYMBOL(hci_free_dev);
32909be0dab7SDavid Herrmann 
32911da177e4SLinus Torvalds /* Register HCI device */
32921da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev)
32931da177e4SLinus Torvalds {
3294b1b813d4SDavid Herrmann 	int id, error;
32951da177e4SLinus Torvalds 
3296010666a1SDavid Herrmann 	if (!hdev->open || !hdev->close)
32971da177e4SLinus Torvalds 		return -EINVAL;
32981da177e4SLinus Torvalds 
329908add513SMat Martineau 	/* Do not allow HCI_AMP devices to register at index 0,
330008add513SMat Martineau 	 * so the index can be used as the AMP controller ID.
330108add513SMat Martineau 	 */
33023df92b31SSasha Levin 	switch (hdev->dev_type) {
33033df92b31SSasha Levin 	case HCI_BREDR:
33043df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL);
33051da177e4SLinus Torvalds 		break;
33063df92b31SSasha Levin 	case HCI_AMP:
33073df92b31SSasha Levin 		id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL);
33083df92b31SSasha Levin 		break;
33093df92b31SSasha Levin 	default:
33103df92b31SSasha Levin 		return -EINVAL;
33111da177e4SLinus Torvalds 	}
33121da177e4SLinus Torvalds 
33133df92b31SSasha Levin 	if (id < 0)
33143df92b31SSasha Levin 		return id;
33153df92b31SSasha Levin 
33161da177e4SLinus Torvalds 	sprintf(hdev->name, "hci%d", id);
33171da177e4SLinus Torvalds 	hdev->id = id;
33182d8b3a11SAndrei Emeltchenko 
33192d8b3a11SAndrei Emeltchenko 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
33202d8b3a11SAndrei Emeltchenko 
3321d8537548SKees Cook 	hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
3322d8537548SKees Cook 					  WQ_MEM_RECLAIM, 1, hdev->name);
332333ca954dSDavid Herrmann 	if (!hdev->workqueue) {
332433ca954dSDavid Herrmann 		error = -ENOMEM;
332533ca954dSDavid Herrmann 		goto err;
332633ca954dSDavid Herrmann 	}
3327f48fd9c8SMarcel Holtmann 
3328d8537548SKees Cook 	hdev->req_workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
3329d8537548SKees Cook 					      WQ_MEM_RECLAIM, 1, hdev->name);
33306ead1bbcSJohan Hedberg 	if (!hdev->req_workqueue) {
33316ead1bbcSJohan Hedberg 		destroy_workqueue(hdev->workqueue);
33326ead1bbcSJohan Hedberg 		error = -ENOMEM;
33336ead1bbcSJohan Hedberg 		goto err;
33346ead1bbcSJohan Hedberg 	}
33356ead1bbcSJohan Hedberg 
33360153e2ecSMarcel Holtmann 	if (!IS_ERR_OR_NULL(bt_debugfs))
33370153e2ecSMarcel Holtmann 		hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs);
33380153e2ecSMarcel Holtmann 
3339bdc3e0f1SMarcel Holtmann 	dev_set_name(&hdev->dev, "%s", hdev->name);
3340bdc3e0f1SMarcel Holtmann 
334199780a7bSJohan Hedberg 	hdev->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0,
334299780a7bSJohan Hedberg 					       CRYPTO_ALG_ASYNC);
334399780a7bSJohan Hedberg 	if (IS_ERR(hdev->tfm_aes)) {
334499780a7bSJohan Hedberg 		BT_ERR("Unable to create crypto context");
334599780a7bSJohan Hedberg 		error = PTR_ERR(hdev->tfm_aes);
334699780a7bSJohan Hedberg 		hdev->tfm_aes = NULL;
334799780a7bSJohan Hedberg 		goto err_wqueue;
334899780a7bSJohan Hedberg 	}
334999780a7bSJohan Hedberg 
3350bdc3e0f1SMarcel Holtmann 	error = device_add(&hdev->dev);
335133ca954dSDavid Herrmann 	if (error < 0)
335299780a7bSJohan Hedberg 		goto err_tfm;
33531da177e4SLinus Torvalds 
3354611b30f7SMarcel Holtmann 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
3355a8c5fb1aSGustavo Padovan 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
3356a8c5fb1aSGustavo Padovan 				    hdev);
3357611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
3358611b30f7SMarcel Holtmann 		if (rfkill_register(hdev->rfkill) < 0) {
3359611b30f7SMarcel Holtmann 			rfkill_destroy(hdev->rfkill);
3360611b30f7SMarcel Holtmann 			hdev->rfkill = NULL;
3361611b30f7SMarcel Holtmann 		}
3362611b30f7SMarcel Holtmann 	}
3363611b30f7SMarcel Holtmann 
33645e130367SJohan Hedberg 	if (hdev->rfkill && rfkill_blocked(hdev->rfkill))
33655e130367SJohan Hedberg 		set_bit(HCI_RFKILLED, &hdev->dev_flags);
33665e130367SJohan Hedberg 
3367a8b2d5c2SJohan Hedberg 	set_bit(HCI_SETUP, &hdev->dev_flags);
3368004b0258SMarcel Holtmann 	set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
3369ce2be9acSAndrei Emeltchenko 
337001cd3404SMarcel Holtmann 	if (hdev->dev_type == HCI_BREDR) {
337156f87901SJohan Hedberg 		/* Assume BR/EDR support until proven otherwise (such as
337256f87901SJohan Hedberg 		 * through reading supported features during init.
337356f87901SJohan Hedberg 		 */
337456f87901SJohan Hedberg 		set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
337556f87901SJohan Hedberg 	}
3376ce2be9acSAndrei Emeltchenko 
3377fcee3377SGustavo Padovan 	write_lock(&hci_dev_list_lock);
3378fcee3377SGustavo Padovan 	list_add(&hdev->list, &hci_dev_list);
3379fcee3377SGustavo Padovan 	write_unlock(&hci_dev_list_lock);
3380fcee3377SGustavo Padovan 
33811da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_REG);
3382dc946bd8SDavid Herrmann 	hci_dev_hold(hdev);
33831da177e4SLinus Torvalds 
338419202573SJohan Hedberg 	queue_work(hdev->req_workqueue, &hdev->power_on);
3385fbe96d6fSMarcel Holtmann 
33861da177e4SLinus Torvalds 	return id;
3387f48fd9c8SMarcel Holtmann 
338899780a7bSJohan Hedberg err_tfm:
338999780a7bSJohan Hedberg 	crypto_free_blkcipher(hdev->tfm_aes);
339033ca954dSDavid Herrmann err_wqueue:
339133ca954dSDavid Herrmann 	destroy_workqueue(hdev->workqueue);
33926ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
339333ca954dSDavid Herrmann err:
33943df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, hdev->id);
3395f48fd9c8SMarcel Holtmann 
339633ca954dSDavid Herrmann 	return error;
33971da177e4SLinus Torvalds }
33981da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_dev);
33991da177e4SLinus Torvalds 
34001da177e4SLinus Torvalds /* Unregister HCI device */
340159735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev)
34021da177e4SLinus Torvalds {
34033df92b31SSasha Levin 	int i, id;
3404ef222013SMarcel Holtmann 
3405c13854ceSMarcel Holtmann 	BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
34061da177e4SLinus Torvalds 
340794324962SJohan Hovold 	set_bit(HCI_UNREGISTER, &hdev->dev_flags);
340894324962SJohan Hovold 
34093df92b31SSasha Levin 	id = hdev->id;
34103df92b31SSasha Levin 
3411f20d09d5SGustavo F. Padovan 	write_lock(&hci_dev_list_lock);
34121da177e4SLinus Torvalds 	list_del(&hdev->list);
3413f20d09d5SGustavo F. Padovan 	write_unlock(&hci_dev_list_lock);
34141da177e4SLinus Torvalds 
34151da177e4SLinus Torvalds 	hci_dev_do_close(hdev);
34161da177e4SLinus Torvalds 
3417cd4c5391SSuraj Sumangala 	for (i = 0; i < NUM_REASSEMBLY; i++)
3418ef222013SMarcel Holtmann 		kfree_skb(hdev->reassembly[i]);
3419ef222013SMarcel Holtmann 
3420b9b5ef18SGustavo Padovan 	cancel_work_sync(&hdev->power_on);
3421b9b5ef18SGustavo Padovan 
3422ab81cbf9SJohan Hedberg 	if (!test_bit(HCI_INIT, &hdev->flags) &&
3423a8b2d5c2SJohan Hedberg 	    !test_bit(HCI_SETUP, &hdev->dev_flags)) {
342409fd0de5SGustavo F. Padovan 		hci_dev_lock(hdev);
3425744cf19eSJohan Hedberg 		mgmt_index_removed(hdev);
342609fd0de5SGustavo F. Padovan 		hci_dev_unlock(hdev);
342756e5cb86SJohan Hedberg 	}
3428ab81cbf9SJohan Hedberg 
34292e58ef3eSJohan Hedberg 	/* mgmt_index_removed should take care of emptying the
34302e58ef3eSJohan Hedberg 	 * pending list */
34312e58ef3eSJohan Hedberg 	BUG_ON(!list_empty(&hdev->mgmt_pending));
34322e58ef3eSJohan Hedberg 
34331da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_UNREG);
34341da177e4SLinus Torvalds 
3435611b30f7SMarcel Holtmann 	if (hdev->rfkill) {
3436611b30f7SMarcel Holtmann 		rfkill_unregister(hdev->rfkill);
3437611b30f7SMarcel Holtmann 		rfkill_destroy(hdev->rfkill);
3438611b30f7SMarcel Holtmann 	}
3439611b30f7SMarcel Holtmann 
344099780a7bSJohan Hedberg 	if (hdev->tfm_aes)
344199780a7bSJohan Hedberg 		crypto_free_blkcipher(hdev->tfm_aes);
344299780a7bSJohan Hedberg 
3443bdc3e0f1SMarcel Holtmann 	device_del(&hdev->dev);
3444147e2d59SDave Young 
34450153e2ecSMarcel Holtmann 	debugfs_remove_recursive(hdev->debugfs);
34460153e2ecSMarcel Holtmann 
3447f48fd9c8SMarcel Holtmann 	destroy_workqueue(hdev->workqueue);
34486ead1bbcSJohan Hedberg 	destroy_workqueue(hdev->req_workqueue);
3449f48fd9c8SMarcel Holtmann 
345009fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
3451e2e0cacbSJohan Hedberg 	hci_blacklist_clear(hdev);
34522aeb9a1aSJohan Hedberg 	hci_uuids_clear(hdev);
345355ed8ca1SJohan Hedberg 	hci_link_keys_clear(hdev);
3454b899efafSVinicius Costa Gomes 	hci_smp_ltks_clear(hdev);
3455970c4e46SJohan Hedberg 	hci_smp_irks_clear(hdev);
34562763eda6SSzymon Janc 	hci_remote_oob_data_clear(hdev);
345715819a70SAndre Guedes 	hci_conn_params_clear(hdev);
345809fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
3459e2e0cacbSJohan Hedberg 
3460dc946bd8SDavid Herrmann 	hci_dev_put(hdev);
34613df92b31SSasha Levin 
34623df92b31SSasha Levin 	ida_simple_remove(&hci_index_ida, id);
34631da177e4SLinus Torvalds }
34641da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_dev);
34651da177e4SLinus Torvalds 
34661da177e4SLinus Torvalds /* Suspend HCI device */
34671da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev)
34681da177e4SLinus Torvalds {
34691da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_SUSPEND);
34701da177e4SLinus Torvalds 	return 0;
34711da177e4SLinus Torvalds }
34721da177e4SLinus Torvalds EXPORT_SYMBOL(hci_suspend_dev);
34731da177e4SLinus Torvalds 
34741da177e4SLinus Torvalds /* Resume HCI device */
34751da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev)
34761da177e4SLinus Torvalds {
34771da177e4SLinus Torvalds 	hci_notify(hdev, HCI_DEV_RESUME);
34781da177e4SLinus Torvalds 	return 0;
34791da177e4SLinus Torvalds }
34801da177e4SLinus Torvalds EXPORT_SYMBOL(hci_resume_dev);
34811da177e4SLinus Torvalds 
348276bca880SMarcel Holtmann /* Receive frame from HCI drivers */
3483e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
348476bca880SMarcel Holtmann {
348576bca880SMarcel Holtmann 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
348676bca880SMarcel Holtmann 		      && !test_bit(HCI_INIT, &hdev->flags))) {
348776bca880SMarcel Holtmann 		kfree_skb(skb);
348876bca880SMarcel Holtmann 		return -ENXIO;
348976bca880SMarcel Holtmann 	}
349076bca880SMarcel Holtmann 
3491d82603c6SJorrit Schippers 	/* Incoming skb */
349276bca880SMarcel Holtmann 	bt_cb(skb)->incoming = 1;
349376bca880SMarcel Holtmann 
349476bca880SMarcel Holtmann 	/* Time stamp */
349576bca880SMarcel Holtmann 	__net_timestamp(skb);
349676bca880SMarcel Holtmann 
349776bca880SMarcel Holtmann 	skb_queue_tail(&hdev->rx_q, skb);
3498b78752ccSMarcel Holtmann 	queue_work(hdev->workqueue, &hdev->rx_work);
3499c78ae283SMarcel Holtmann 
350076bca880SMarcel Holtmann 	return 0;
350176bca880SMarcel Holtmann }
350276bca880SMarcel Holtmann EXPORT_SYMBOL(hci_recv_frame);
350376bca880SMarcel Holtmann 
350433e882a5SSuraj Sumangala static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
35051e429f38SGustavo F. Padovan 			  int count, __u8 index)
350633e882a5SSuraj Sumangala {
350733e882a5SSuraj Sumangala 	int len = 0;
350833e882a5SSuraj Sumangala 	int hlen = 0;
350933e882a5SSuraj Sumangala 	int remain = count;
351033e882a5SSuraj Sumangala 	struct sk_buff *skb;
351133e882a5SSuraj Sumangala 	struct bt_skb_cb *scb;
351233e882a5SSuraj Sumangala 
351333e882a5SSuraj Sumangala 	if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
351433e882a5SSuraj Sumangala 	    index >= NUM_REASSEMBLY)
351533e882a5SSuraj Sumangala 		return -EILSEQ;
351633e882a5SSuraj Sumangala 
351733e882a5SSuraj Sumangala 	skb = hdev->reassembly[index];
351833e882a5SSuraj Sumangala 
351933e882a5SSuraj Sumangala 	if (!skb) {
352033e882a5SSuraj Sumangala 		switch (type) {
352133e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
352233e882a5SSuraj Sumangala 			len = HCI_MAX_FRAME_SIZE;
352333e882a5SSuraj Sumangala 			hlen = HCI_ACL_HDR_SIZE;
352433e882a5SSuraj Sumangala 			break;
352533e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
352633e882a5SSuraj Sumangala 			len = HCI_MAX_EVENT_SIZE;
352733e882a5SSuraj Sumangala 			hlen = HCI_EVENT_HDR_SIZE;
352833e882a5SSuraj Sumangala 			break;
352933e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
353033e882a5SSuraj Sumangala 			len = HCI_MAX_SCO_SIZE;
353133e882a5SSuraj Sumangala 			hlen = HCI_SCO_HDR_SIZE;
353233e882a5SSuraj Sumangala 			break;
353333e882a5SSuraj Sumangala 		}
353433e882a5SSuraj Sumangala 
35351e429f38SGustavo F. Padovan 		skb = bt_skb_alloc(len, GFP_ATOMIC);
353633e882a5SSuraj Sumangala 		if (!skb)
353733e882a5SSuraj Sumangala 			return -ENOMEM;
353833e882a5SSuraj Sumangala 
353933e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
354033e882a5SSuraj Sumangala 		scb->expect = hlen;
354133e882a5SSuraj Sumangala 		scb->pkt_type = type;
354233e882a5SSuraj Sumangala 
354333e882a5SSuraj Sumangala 		hdev->reassembly[index] = skb;
354433e882a5SSuraj Sumangala 	}
354533e882a5SSuraj Sumangala 
354633e882a5SSuraj Sumangala 	while (count) {
354733e882a5SSuraj Sumangala 		scb = (void *) skb->cb;
354889bb46d0SDan Carpenter 		len = min_t(uint, scb->expect, count);
354933e882a5SSuraj Sumangala 
355033e882a5SSuraj Sumangala 		memcpy(skb_put(skb, len), data, len);
355133e882a5SSuraj Sumangala 
355233e882a5SSuraj Sumangala 		count -= len;
355333e882a5SSuraj Sumangala 		data += len;
355433e882a5SSuraj Sumangala 		scb->expect -= len;
355533e882a5SSuraj Sumangala 		remain = count;
355633e882a5SSuraj Sumangala 
355733e882a5SSuraj Sumangala 		switch (type) {
355833e882a5SSuraj Sumangala 		case HCI_EVENT_PKT:
355933e882a5SSuraj Sumangala 			if (skb->len == HCI_EVENT_HDR_SIZE) {
356033e882a5SSuraj Sumangala 				struct hci_event_hdr *h = hci_event_hdr(skb);
356133e882a5SSuraj Sumangala 				scb->expect = h->plen;
356233e882a5SSuraj Sumangala 
356333e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
356433e882a5SSuraj Sumangala 					kfree_skb(skb);
356533e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
356633e882a5SSuraj Sumangala 					return -ENOMEM;
356733e882a5SSuraj Sumangala 				}
356833e882a5SSuraj Sumangala 			}
356933e882a5SSuraj Sumangala 			break;
357033e882a5SSuraj Sumangala 
357133e882a5SSuraj Sumangala 		case HCI_ACLDATA_PKT:
357233e882a5SSuraj Sumangala 			if (skb->len  == HCI_ACL_HDR_SIZE) {
357333e882a5SSuraj Sumangala 				struct hci_acl_hdr *h = hci_acl_hdr(skb);
357433e882a5SSuraj Sumangala 				scb->expect = __le16_to_cpu(h->dlen);
357533e882a5SSuraj Sumangala 
357633e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
357733e882a5SSuraj Sumangala 					kfree_skb(skb);
357833e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
357933e882a5SSuraj Sumangala 					return -ENOMEM;
358033e882a5SSuraj Sumangala 				}
358133e882a5SSuraj Sumangala 			}
358233e882a5SSuraj Sumangala 			break;
358333e882a5SSuraj Sumangala 
358433e882a5SSuraj Sumangala 		case HCI_SCODATA_PKT:
358533e882a5SSuraj Sumangala 			if (skb->len == HCI_SCO_HDR_SIZE) {
358633e882a5SSuraj Sumangala 				struct hci_sco_hdr *h = hci_sco_hdr(skb);
358733e882a5SSuraj Sumangala 				scb->expect = h->dlen;
358833e882a5SSuraj Sumangala 
358933e882a5SSuraj Sumangala 				if (skb_tailroom(skb) < scb->expect) {
359033e882a5SSuraj Sumangala 					kfree_skb(skb);
359133e882a5SSuraj Sumangala 					hdev->reassembly[index] = NULL;
359233e882a5SSuraj Sumangala 					return -ENOMEM;
359333e882a5SSuraj Sumangala 				}
359433e882a5SSuraj Sumangala 			}
359533e882a5SSuraj Sumangala 			break;
359633e882a5SSuraj Sumangala 		}
359733e882a5SSuraj Sumangala 
359833e882a5SSuraj Sumangala 		if (scb->expect == 0) {
359933e882a5SSuraj Sumangala 			/* Complete frame */
360033e882a5SSuraj Sumangala 
360133e882a5SSuraj Sumangala 			bt_cb(skb)->pkt_type = type;
3602e1a26170SMarcel Holtmann 			hci_recv_frame(hdev, skb);
360333e882a5SSuraj Sumangala 
360433e882a5SSuraj Sumangala 			hdev->reassembly[index] = NULL;
360533e882a5SSuraj Sumangala 			return remain;
360633e882a5SSuraj Sumangala 		}
360733e882a5SSuraj Sumangala 	}
360833e882a5SSuraj Sumangala 
360933e882a5SSuraj Sumangala 	return remain;
361033e882a5SSuraj Sumangala }
361133e882a5SSuraj Sumangala 
3612ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
3613ef222013SMarcel Holtmann {
3614f39a3c06SSuraj Sumangala 	int rem = 0;
3615f39a3c06SSuraj Sumangala 
3616ef222013SMarcel Holtmann 	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
3617ef222013SMarcel Holtmann 		return -EILSEQ;
3618ef222013SMarcel Holtmann 
3619da5f6c37SGustavo F. Padovan 	while (count) {
36201e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count, type - 1);
3621f39a3c06SSuraj Sumangala 		if (rem < 0)
3622f39a3c06SSuraj Sumangala 			return rem;
3623ef222013SMarcel Holtmann 
3624f39a3c06SSuraj Sumangala 		data += (count - rem);
3625f39a3c06SSuraj Sumangala 		count = rem;
3626f81c6224SJoe Perches 	}
3627ef222013SMarcel Holtmann 
3628f39a3c06SSuraj Sumangala 	return rem;
3629ef222013SMarcel Holtmann }
3630ef222013SMarcel Holtmann EXPORT_SYMBOL(hci_recv_fragment);
3631ef222013SMarcel Holtmann 
363299811510SSuraj Sumangala #define STREAM_REASSEMBLY 0
363399811510SSuraj Sumangala 
363499811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
363599811510SSuraj Sumangala {
363699811510SSuraj Sumangala 	int type;
363799811510SSuraj Sumangala 	int rem = 0;
363899811510SSuraj Sumangala 
3639da5f6c37SGustavo F. Padovan 	while (count) {
364099811510SSuraj Sumangala 		struct sk_buff *skb = hdev->reassembly[STREAM_REASSEMBLY];
364199811510SSuraj Sumangala 
364299811510SSuraj Sumangala 		if (!skb) {
364399811510SSuraj Sumangala 			struct { char type; } *pkt;
364499811510SSuraj Sumangala 
364599811510SSuraj Sumangala 			/* Start of the frame */
364699811510SSuraj Sumangala 			pkt = data;
364799811510SSuraj Sumangala 			type = pkt->type;
364899811510SSuraj Sumangala 
364999811510SSuraj Sumangala 			data++;
365099811510SSuraj Sumangala 			count--;
365199811510SSuraj Sumangala 		} else
365299811510SSuraj Sumangala 			type = bt_cb(skb)->pkt_type;
365399811510SSuraj Sumangala 
36541e429f38SGustavo F. Padovan 		rem = hci_reassembly(hdev, type, data, count,
36551e429f38SGustavo F. Padovan 				     STREAM_REASSEMBLY);
365699811510SSuraj Sumangala 		if (rem < 0)
365799811510SSuraj Sumangala 			return rem;
365899811510SSuraj Sumangala 
365999811510SSuraj Sumangala 		data += (count - rem);
366099811510SSuraj Sumangala 		count = rem;
3661f81c6224SJoe Perches 	}
366299811510SSuraj Sumangala 
366399811510SSuraj Sumangala 	return rem;
366499811510SSuraj Sumangala }
366599811510SSuraj Sumangala EXPORT_SYMBOL(hci_recv_stream_fragment);
366699811510SSuraj Sumangala 
36671da177e4SLinus Torvalds /* ---- Interface to upper protocols ---- */
36681da177e4SLinus Torvalds 
36691da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *cb)
36701da177e4SLinus Torvalds {
36711da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
36721da177e4SLinus Torvalds 
3673f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
36741da177e4SLinus Torvalds 	list_add(&cb->list, &hci_cb_list);
3675f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
36761da177e4SLinus Torvalds 
36771da177e4SLinus Torvalds 	return 0;
36781da177e4SLinus Torvalds }
36791da177e4SLinus Torvalds EXPORT_SYMBOL(hci_register_cb);
36801da177e4SLinus Torvalds 
36811da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *cb)
36821da177e4SLinus Torvalds {
36831da177e4SLinus Torvalds 	BT_DBG("%p name %s", cb, cb->name);
36841da177e4SLinus Torvalds 
3685f20d09d5SGustavo F. Padovan 	write_lock(&hci_cb_list_lock);
36861da177e4SLinus Torvalds 	list_del(&cb->list);
3687f20d09d5SGustavo F. Padovan 	write_unlock(&hci_cb_list_lock);
36881da177e4SLinus Torvalds 
36891da177e4SLinus Torvalds 	return 0;
36901da177e4SLinus Torvalds }
36911da177e4SLinus Torvalds EXPORT_SYMBOL(hci_unregister_cb);
36921da177e4SLinus Torvalds 
369351086991SMarcel Holtmann static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
36941da177e4SLinus Torvalds {
36950d48d939SMarcel Holtmann 	BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
36961da177e4SLinus Torvalds 
36971da177e4SLinus Torvalds 	/* Time stamp */
3698a61bbcf2SPatrick McHardy 	__net_timestamp(skb);
36991da177e4SLinus Torvalds 
3700cd82e61cSMarcel Holtmann 	/* Send copy to monitor */
3701cd82e61cSMarcel Holtmann 	hci_send_to_monitor(hdev, skb);
3702cd82e61cSMarcel Holtmann 
3703cd82e61cSMarcel Holtmann 	if (atomic_read(&hdev->promisc)) {
3704cd82e61cSMarcel Holtmann 		/* Send copy to the sockets */
3705470fe1b5SMarcel Holtmann 		hci_send_to_sock(hdev, skb);
37061da177e4SLinus Torvalds 	}
37071da177e4SLinus Torvalds 
37081da177e4SLinus Torvalds 	/* Get rid of skb owner, prior to sending to the driver. */
37091da177e4SLinus Torvalds 	skb_orphan(skb);
37101da177e4SLinus Torvalds 
37117bd8f09fSMarcel Holtmann 	if (hdev->send(hdev, skb) < 0)
371251086991SMarcel Holtmann 		BT_ERR("%s sending frame failed", hdev->name);
37131da177e4SLinus Torvalds }
37141da177e4SLinus Torvalds 
37153119ae95SJohan Hedberg void hci_req_init(struct hci_request *req, struct hci_dev *hdev)
37163119ae95SJohan Hedberg {
37173119ae95SJohan Hedberg 	skb_queue_head_init(&req->cmd_q);
37183119ae95SJohan Hedberg 	req->hdev = hdev;
37195d73e034SAndre Guedes 	req->err = 0;
37203119ae95SJohan Hedberg }
37213119ae95SJohan Hedberg 
37223119ae95SJohan Hedberg int hci_req_run(struct hci_request *req, hci_req_complete_t complete)
37233119ae95SJohan Hedberg {
37243119ae95SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
37253119ae95SJohan Hedberg 	struct sk_buff *skb;
37263119ae95SJohan Hedberg 	unsigned long flags;
37273119ae95SJohan Hedberg 
37283119ae95SJohan Hedberg 	BT_DBG("length %u", skb_queue_len(&req->cmd_q));
37293119ae95SJohan Hedberg 
37305d73e034SAndre Guedes 	/* If an error occured during request building, remove all HCI
37315d73e034SAndre Guedes 	 * commands queued on the HCI request queue.
37325d73e034SAndre Guedes 	 */
37335d73e034SAndre Guedes 	if (req->err) {
37345d73e034SAndre Guedes 		skb_queue_purge(&req->cmd_q);
37355d73e034SAndre Guedes 		return req->err;
37365d73e034SAndre Guedes 	}
37375d73e034SAndre Guedes 
37383119ae95SJohan Hedberg 	/* Do not allow empty requests */
37393119ae95SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
3740382b0c39SAndre Guedes 		return -ENODATA;
37413119ae95SJohan Hedberg 
37423119ae95SJohan Hedberg 	skb = skb_peek_tail(&req->cmd_q);
37433119ae95SJohan Hedberg 	bt_cb(skb)->req.complete = complete;
37443119ae95SJohan Hedberg 
37453119ae95SJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
37463119ae95SJohan Hedberg 	skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q);
37473119ae95SJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
37483119ae95SJohan Hedberg 
37493119ae95SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
37503119ae95SJohan Hedberg 
37513119ae95SJohan Hedberg 	return 0;
37523119ae95SJohan Hedberg }
37533119ae95SJohan Hedberg 
37541ca3a9d0SJohan Hedberg static struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode,
375507dc93ddSJohan Hedberg 				       u32 plen, const void *param)
37561da177e4SLinus Torvalds {
37571da177e4SLinus Torvalds 	int len = HCI_COMMAND_HDR_SIZE + plen;
37581da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
37591da177e4SLinus Torvalds 	struct sk_buff *skb;
37601da177e4SLinus Torvalds 
37611da177e4SLinus Torvalds 	skb = bt_skb_alloc(len, GFP_ATOMIC);
37621ca3a9d0SJohan Hedberg 	if (!skb)
37631ca3a9d0SJohan Hedberg 		return NULL;
37641da177e4SLinus Torvalds 
37651da177e4SLinus Torvalds 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
3766a9de9248SMarcel Holtmann 	hdr->opcode = cpu_to_le16(opcode);
37671da177e4SLinus Torvalds 	hdr->plen   = plen;
37681da177e4SLinus Torvalds 
37691da177e4SLinus Torvalds 	if (plen)
37701da177e4SLinus Torvalds 		memcpy(skb_put(skb, plen), param, plen);
37711da177e4SLinus Torvalds 
37721da177e4SLinus Torvalds 	BT_DBG("skb len %d", skb->len);
37731da177e4SLinus Torvalds 
37740d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
3775c78ae283SMarcel Holtmann 
37761ca3a9d0SJohan Hedberg 	return skb;
37771ca3a9d0SJohan Hedberg }
37781ca3a9d0SJohan Hedberg 
37791ca3a9d0SJohan Hedberg /* Send HCI command */
378007dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
378107dc93ddSJohan Hedberg 		 const void *param)
37821ca3a9d0SJohan Hedberg {
37831ca3a9d0SJohan Hedberg 	struct sk_buff *skb;
37841ca3a9d0SJohan Hedberg 
37851ca3a9d0SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
37861ca3a9d0SJohan Hedberg 
37871ca3a9d0SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
37881ca3a9d0SJohan Hedberg 	if (!skb) {
37891ca3a9d0SJohan Hedberg 		BT_ERR("%s no memory for command", hdev->name);
37901ca3a9d0SJohan Hedberg 		return -ENOMEM;
37911ca3a9d0SJohan Hedberg 	}
37921ca3a9d0SJohan Hedberg 
379311714b3dSJohan Hedberg 	/* Stand-alone HCI commands must be flaged as
379411714b3dSJohan Hedberg 	 * single-command requests.
379511714b3dSJohan Hedberg 	 */
379611714b3dSJohan Hedberg 	bt_cb(skb)->req.start = true;
379711714b3dSJohan Hedberg 
37981da177e4SLinus Torvalds 	skb_queue_tail(&hdev->cmd_q, skb);
3799c347b765SGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->cmd_work);
38001da177e4SLinus Torvalds 
38011da177e4SLinus Torvalds 	return 0;
38021da177e4SLinus Torvalds }
38031da177e4SLinus Torvalds 
380471c76a17SJohan Hedberg /* Queue a command to an asynchronous HCI request */
380507dc93ddSJohan Hedberg void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen,
380607dc93ddSJohan Hedberg 		    const void *param, u8 event)
380771c76a17SJohan Hedberg {
380871c76a17SJohan Hedberg 	struct hci_dev *hdev = req->hdev;
380971c76a17SJohan Hedberg 	struct sk_buff *skb;
381071c76a17SJohan Hedberg 
381171c76a17SJohan Hedberg 	BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen);
381271c76a17SJohan Hedberg 
381334739c1eSAndre Guedes 	/* If an error occured during request building, there is no point in
381434739c1eSAndre Guedes 	 * queueing the HCI command. We can simply return.
381534739c1eSAndre Guedes 	 */
381634739c1eSAndre Guedes 	if (req->err)
381734739c1eSAndre Guedes 		return;
381834739c1eSAndre Guedes 
381971c76a17SJohan Hedberg 	skb = hci_prepare_cmd(hdev, opcode, plen, param);
382071c76a17SJohan Hedberg 	if (!skb) {
38215d73e034SAndre Guedes 		BT_ERR("%s no memory for command (opcode 0x%4.4x)",
38225d73e034SAndre Guedes 		       hdev->name, opcode);
38235d73e034SAndre Guedes 		req->err = -ENOMEM;
3824e348fe6bSAndre Guedes 		return;
382571c76a17SJohan Hedberg 	}
382671c76a17SJohan Hedberg 
382771c76a17SJohan Hedberg 	if (skb_queue_empty(&req->cmd_q))
382871c76a17SJohan Hedberg 		bt_cb(skb)->req.start = true;
382971c76a17SJohan Hedberg 
383002350a72SJohan Hedberg 	bt_cb(skb)->req.event = event;
383102350a72SJohan Hedberg 
383271c76a17SJohan Hedberg 	skb_queue_tail(&req->cmd_q, skb);
383371c76a17SJohan Hedberg }
383471c76a17SJohan Hedberg 
383507dc93ddSJohan Hedberg void hci_req_add(struct hci_request *req, u16 opcode, u32 plen,
383607dc93ddSJohan Hedberg 		 const void *param)
383702350a72SJohan Hedberg {
383802350a72SJohan Hedberg 	hci_req_add_ev(req, opcode, plen, param, 0);
383902350a72SJohan Hedberg }
384002350a72SJohan Hedberg 
38411da177e4SLinus Torvalds /* Get data from the previously sent command */
3842a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
38431da177e4SLinus Torvalds {
38441da177e4SLinus Torvalds 	struct hci_command_hdr *hdr;
38451da177e4SLinus Torvalds 
38461da177e4SLinus Torvalds 	if (!hdev->sent_cmd)
38471da177e4SLinus Torvalds 		return NULL;
38481da177e4SLinus Torvalds 
38491da177e4SLinus Torvalds 	hdr = (void *) hdev->sent_cmd->data;
38501da177e4SLinus Torvalds 
3851a9de9248SMarcel Holtmann 	if (hdr->opcode != cpu_to_le16(opcode))
38521da177e4SLinus Torvalds 		return NULL;
38531da177e4SLinus Torvalds 
3854f0e09510SAndrei Emeltchenko 	BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
38551da177e4SLinus Torvalds 
38561da177e4SLinus Torvalds 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
38571da177e4SLinus Torvalds }
38581da177e4SLinus Torvalds 
38591da177e4SLinus Torvalds /* Send ACL data */
38601da177e4SLinus Torvalds static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
38611da177e4SLinus Torvalds {
38621da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr;
38631da177e4SLinus Torvalds 	int len = skb->len;
38641da177e4SLinus Torvalds 
3865badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_ACL_HDR_SIZE);
3866badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
38679c70220bSArnaldo Carvalho de Melo 	hdr = (struct hci_acl_hdr *)skb_transport_header(skb);
3868aca3192cSYOSHIFUJI Hideaki 	hdr->handle = cpu_to_le16(hci_handle_pack(handle, flags));
3869aca3192cSYOSHIFUJI Hideaki 	hdr->dlen   = cpu_to_le16(len);
38701da177e4SLinus Torvalds }
38711da177e4SLinus Torvalds 
3872ee22be7eSAndrei Emeltchenko static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
387373d80debSLuiz Augusto von Dentz 			  struct sk_buff *skb, __u16 flags)
38741da177e4SLinus Torvalds {
3875ee22be7eSAndrei Emeltchenko 	struct hci_conn *conn = chan->conn;
38761da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
38771da177e4SLinus Torvalds 	struct sk_buff *list;
38781da177e4SLinus Torvalds 
3879087bfd99SGustavo Padovan 	skb->len = skb_headlen(skb);
3880087bfd99SGustavo Padovan 	skb->data_len = 0;
3881087bfd99SGustavo Padovan 
3882087bfd99SGustavo Padovan 	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
3883204a6e54SAndrei Emeltchenko 
3884204a6e54SAndrei Emeltchenko 	switch (hdev->dev_type) {
3885204a6e54SAndrei Emeltchenko 	case HCI_BREDR:
3886087bfd99SGustavo Padovan 		hci_add_acl_hdr(skb, conn->handle, flags);
3887204a6e54SAndrei Emeltchenko 		break;
3888204a6e54SAndrei Emeltchenko 	case HCI_AMP:
3889204a6e54SAndrei Emeltchenko 		hci_add_acl_hdr(skb, chan->handle, flags);
3890204a6e54SAndrei Emeltchenko 		break;
3891204a6e54SAndrei Emeltchenko 	default:
3892204a6e54SAndrei Emeltchenko 		BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
3893204a6e54SAndrei Emeltchenko 		return;
3894204a6e54SAndrei Emeltchenko 	}
3895087bfd99SGustavo Padovan 
389670f23020SAndrei Emeltchenko 	list = skb_shinfo(skb)->frag_list;
389770f23020SAndrei Emeltchenko 	if (!list) {
38981da177e4SLinus Torvalds 		/* Non fragmented */
38991da177e4SLinus Torvalds 		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
39001da177e4SLinus Torvalds 
390173d80debSLuiz Augusto von Dentz 		skb_queue_tail(queue, skb);
39021da177e4SLinus Torvalds 	} else {
39031da177e4SLinus Torvalds 		/* Fragmented */
39041da177e4SLinus Torvalds 		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
39051da177e4SLinus Torvalds 
39061da177e4SLinus Torvalds 		skb_shinfo(skb)->frag_list = NULL;
39071da177e4SLinus Torvalds 
39081da177e4SLinus Torvalds 		/* Queue all fragments atomically */
3909af3e6359SGustavo F. Padovan 		spin_lock(&queue->lock);
39101da177e4SLinus Torvalds 
391173d80debSLuiz Augusto von Dentz 		__skb_queue_tail(queue, skb);
3912e702112fSAndrei Emeltchenko 
3913e702112fSAndrei Emeltchenko 		flags &= ~ACL_START;
3914e702112fSAndrei Emeltchenko 		flags |= ACL_CONT;
39151da177e4SLinus Torvalds 		do {
39161da177e4SLinus Torvalds 			skb = list; list = list->next;
39171da177e4SLinus Torvalds 
39180d48d939SMarcel Holtmann 			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
3919e702112fSAndrei Emeltchenko 			hci_add_acl_hdr(skb, conn->handle, flags);
39201da177e4SLinus Torvalds 
39211da177e4SLinus Torvalds 			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
39221da177e4SLinus Torvalds 
392373d80debSLuiz Augusto von Dentz 			__skb_queue_tail(queue, skb);
39241da177e4SLinus Torvalds 		} while (list);
39251da177e4SLinus Torvalds 
3926af3e6359SGustavo F. Padovan 		spin_unlock(&queue->lock);
39271da177e4SLinus Torvalds 	}
392873d80debSLuiz Augusto von Dentz }
392973d80debSLuiz Augusto von Dentz 
393073d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
393173d80debSLuiz Augusto von Dentz {
3932ee22be7eSAndrei Emeltchenko 	struct hci_dev *hdev = chan->conn->hdev;
393373d80debSLuiz Augusto von Dentz 
3934f0e09510SAndrei Emeltchenko 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
393573d80debSLuiz Augusto von Dentz 
3936ee22be7eSAndrei Emeltchenko 	hci_queue_acl(chan, &chan->data_q, skb, flags);
39371da177e4SLinus Torvalds 
39383eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
39391da177e4SLinus Torvalds }
39401da177e4SLinus Torvalds 
39411da177e4SLinus Torvalds /* Send SCO data */
39420d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
39431da177e4SLinus Torvalds {
39441da177e4SLinus Torvalds 	struct hci_dev *hdev = conn->hdev;
39451da177e4SLinus Torvalds 	struct hci_sco_hdr hdr;
39461da177e4SLinus Torvalds 
39471da177e4SLinus Torvalds 	BT_DBG("%s len %d", hdev->name, skb->len);
39481da177e4SLinus Torvalds 
3949aca3192cSYOSHIFUJI Hideaki 	hdr.handle = cpu_to_le16(conn->handle);
39501da177e4SLinus Torvalds 	hdr.dlen   = skb->len;
39511da177e4SLinus Torvalds 
3952badff6d0SArnaldo Carvalho de Melo 	skb_push(skb, HCI_SCO_HDR_SIZE);
3953badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
39549c70220bSArnaldo Carvalho de Melo 	memcpy(skb_transport_header(skb), &hdr, HCI_SCO_HDR_SIZE);
39551da177e4SLinus Torvalds 
39560d48d939SMarcel Holtmann 	bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
3957c78ae283SMarcel Holtmann 
39581da177e4SLinus Torvalds 	skb_queue_tail(&conn->data_q, skb);
39593eff45eaSGustavo F. Padovan 	queue_work(hdev->workqueue, &hdev->tx_work);
39601da177e4SLinus Torvalds }
39611da177e4SLinus Torvalds 
39621da177e4SLinus Torvalds /* ---- HCI TX task (outgoing data) ---- */
39631da177e4SLinus Torvalds 
39641da177e4SLinus Torvalds /* HCI Connection scheduler */
39656039aa73SGustavo Padovan static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,
3966a8c5fb1aSGustavo Padovan 				     int *quote)
39671da177e4SLinus Torvalds {
39681da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
39698035ded4SLuiz Augusto von Dentz 	struct hci_conn *conn = NULL, *c;
3970abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0;
39711da177e4SLinus Torvalds 
39721da177e4SLinus Torvalds 	/* We don't have to lock device here. Connections are always
39731da177e4SLinus Torvalds 	 * added and removed with TX task disabled. */
3974bf4c6325SGustavo F. Padovan 
3975bf4c6325SGustavo F. Padovan 	rcu_read_lock();
3976bf4c6325SGustavo F. Padovan 
3977bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
3978769be974SMarcel Holtmann 		if (c->type != type || skb_queue_empty(&c->data_q))
39791da177e4SLinus Torvalds 			continue;
3980769be974SMarcel Holtmann 
3981769be974SMarcel Holtmann 		if (c->state != BT_CONNECTED && c->state != BT_CONFIG)
3982769be974SMarcel Holtmann 			continue;
3983769be974SMarcel Holtmann 
39841da177e4SLinus Torvalds 		num++;
39851da177e4SLinus Torvalds 
39861da177e4SLinus Torvalds 		if (c->sent < min) {
39871da177e4SLinus Torvalds 			min  = c->sent;
39881da177e4SLinus Torvalds 			conn = c;
39891da177e4SLinus Torvalds 		}
399052087a79SLuiz Augusto von Dentz 
399152087a79SLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
399252087a79SLuiz Augusto von Dentz 			break;
39931da177e4SLinus Torvalds 	}
39941da177e4SLinus Torvalds 
3995bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
3996bf4c6325SGustavo F. Padovan 
39971da177e4SLinus Torvalds 	if (conn) {
39986ed58ec5SVille Tervo 		int cnt, q;
39996ed58ec5SVille Tervo 
40006ed58ec5SVille Tervo 		switch (conn->type) {
40016ed58ec5SVille Tervo 		case ACL_LINK:
40026ed58ec5SVille Tervo 			cnt = hdev->acl_cnt;
40036ed58ec5SVille Tervo 			break;
40046ed58ec5SVille Tervo 		case SCO_LINK:
40056ed58ec5SVille Tervo 		case ESCO_LINK:
40066ed58ec5SVille Tervo 			cnt = hdev->sco_cnt;
40076ed58ec5SVille Tervo 			break;
40086ed58ec5SVille Tervo 		case LE_LINK:
40096ed58ec5SVille Tervo 			cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
40106ed58ec5SVille Tervo 			break;
40116ed58ec5SVille Tervo 		default:
40126ed58ec5SVille Tervo 			cnt = 0;
40136ed58ec5SVille Tervo 			BT_ERR("Unknown link type");
40146ed58ec5SVille Tervo 		}
40156ed58ec5SVille Tervo 
40166ed58ec5SVille Tervo 		q = cnt / num;
40171da177e4SLinus Torvalds 		*quote = q ? q : 1;
40181da177e4SLinus Torvalds 	} else
40191da177e4SLinus Torvalds 		*quote = 0;
40201da177e4SLinus Torvalds 
40211da177e4SLinus Torvalds 	BT_DBG("conn %p quote %d", conn, *quote);
40221da177e4SLinus Torvalds 	return conn;
40231da177e4SLinus Torvalds }
40241da177e4SLinus Torvalds 
40256039aa73SGustavo Padovan static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
40261da177e4SLinus Torvalds {
40271da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
40281da177e4SLinus Torvalds 	struct hci_conn *c;
40291da177e4SLinus Torvalds 
4030bae1f5d9SVille Tervo 	BT_ERR("%s link tx timeout", hdev->name);
40311da177e4SLinus Torvalds 
4032bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4033bf4c6325SGustavo F. Padovan 
40341da177e4SLinus Torvalds 	/* Kill stalled connections */
4035bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
4036bae1f5d9SVille Tervo 		if (c->type == type && c->sent) {
40376ed93dc6SAndrei Emeltchenko 			BT_ERR("%s killing stalled connection %pMR",
40386ed93dc6SAndrei Emeltchenko 			       hdev->name, &c->dst);
4039bed71748SAndre Guedes 			hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
40401da177e4SLinus Torvalds 		}
40411da177e4SLinus Torvalds 	}
4042bf4c6325SGustavo F. Padovan 
4043bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
40441da177e4SLinus Torvalds }
40451da177e4SLinus Torvalds 
40466039aa73SGustavo Padovan static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
404773d80debSLuiz Augusto von Dentz 				      int *quote)
404873d80debSLuiz Augusto von Dentz {
404973d80debSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
405073d80debSLuiz Augusto von Dentz 	struct hci_chan *chan = NULL;
4051abc5de8fSMikel Astiz 	unsigned int num = 0, min = ~0, cur_prio = 0;
405273d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
405373d80debSLuiz Augusto von Dentz 	int cnt, q, conn_num = 0;
405473d80debSLuiz Augusto von Dentz 
405573d80debSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
405673d80debSLuiz Augusto von Dentz 
4057bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4058bf4c6325SGustavo F. Padovan 
4059bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
406073d80debSLuiz Augusto von Dentz 		struct hci_chan *tmp;
406173d80debSLuiz Augusto von Dentz 
406273d80debSLuiz Augusto von Dentz 		if (conn->type != type)
406373d80debSLuiz Augusto von Dentz 			continue;
406473d80debSLuiz Augusto von Dentz 
406573d80debSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
406673d80debSLuiz Augusto von Dentz 			continue;
406773d80debSLuiz Augusto von Dentz 
406873d80debSLuiz Augusto von Dentz 		conn_num++;
406973d80debSLuiz Augusto von Dentz 
40708192edefSGustavo F. Padovan 		list_for_each_entry_rcu(tmp, &conn->chan_list, list) {
407173d80debSLuiz Augusto von Dentz 			struct sk_buff *skb;
407273d80debSLuiz Augusto von Dentz 
407373d80debSLuiz Augusto von Dentz 			if (skb_queue_empty(&tmp->data_q))
407473d80debSLuiz Augusto von Dentz 				continue;
407573d80debSLuiz Augusto von Dentz 
407673d80debSLuiz Augusto von Dentz 			skb = skb_peek(&tmp->data_q);
407773d80debSLuiz Augusto von Dentz 			if (skb->priority < cur_prio)
407873d80debSLuiz Augusto von Dentz 				continue;
407973d80debSLuiz Augusto von Dentz 
408073d80debSLuiz Augusto von Dentz 			if (skb->priority > cur_prio) {
408173d80debSLuiz Augusto von Dentz 				num = 0;
408273d80debSLuiz Augusto von Dentz 				min = ~0;
408373d80debSLuiz Augusto von Dentz 				cur_prio = skb->priority;
408473d80debSLuiz Augusto von Dentz 			}
408573d80debSLuiz Augusto von Dentz 
408673d80debSLuiz Augusto von Dentz 			num++;
408773d80debSLuiz Augusto von Dentz 
408873d80debSLuiz Augusto von Dentz 			if (conn->sent < min) {
408973d80debSLuiz Augusto von Dentz 				min  = conn->sent;
409073d80debSLuiz Augusto von Dentz 				chan = tmp;
409173d80debSLuiz Augusto von Dentz 			}
409273d80debSLuiz Augusto von Dentz 		}
409373d80debSLuiz Augusto von Dentz 
409473d80debSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == conn_num)
409573d80debSLuiz Augusto von Dentz 			break;
409673d80debSLuiz Augusto von Dentz 	}
409773d80debSLuiz Augusto von Dentz 
4098bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4099bf4c6325SGustavo F. Padovan 
410073d80debSLuiz Augusto von Dentz 	if (!chan)
410173d80debSLuiz Augusto von Dentz 		return NULL;
410273d80debSLuiz Augusto von Dentz 
410373d80debSLuiz Augusto von Dentz 	switch (chan->conn->type) {
410473d80debSLuiz Augusto von Dentz 	case ACL_LINK:
410573d80debSLuiz Augusto von Dentz 		cnt = hdev->acl_cnt;
410673d80debSLuiz Augusto von Dentz 		break;
4107bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
4108bd1eb66bSAndrei Emeltchenko 		cnt = hdev->block_cnt;
4109bd1eb66bSAndrei Emeltchenko 		break;
411073d80debSLuiz Augusto von Dentz 	case SCO_LINK:
411173d80debSLuiz Augusto von Dentz 	case ESCO_LINK:
411273d80debSLuiz Augusto von Dentz 		cnt = hdev->sco_cnt;
411373d80debSLuiz Augusto von Dentz 		break;
411473d80debSLuiz Augusto von Dentz 	case LE_LINK:
411573d80debSLuiz Augusto von Dentz 		cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
411673d80debSLuiz Augusto von Dentz 		break;
411773d80debSLuiz Augusto von Dentz 	default:
411873d80debSLuiz Augusto von Dentz 		cnt = 0;
411973d80debSLuiz Augusto von Dentz 		BT_ERR("Unknown link type");
412073d80debSLuiz Augusto von Dentz 	}
412173d80debSLuiz Augusto von Dentz 
412273d80debSLuiz Augusto von Dentz 	q = cnt / num;
412373d80debSLuiz Augusto von Dentz 	*quote = q ? q : 1;
412473d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p quote %d", chan, *quote);
412573d80debSLuiz Augusto von Dentz 	return chan;
412673d80debSLuiz Augusto von Dentz }
412773d80debSLuiz Augusto von Dentz 
412802b20f0bSLuiz Augusto von Dentz static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
412902b20f0bSLuiz Augusto von Dentz {
413002b20f0bSLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
413102b20f0bSLuiz Augusto von Dentz 	struct hci_conn *conn;
413202b20f0bSLuiz Augusto von Dentz 	int num = 0;
413302b20f0bSLuiz Augusto von Dentz 
413402b20f0bSLuiz Augusto von Dentz 	BT_DBG("%s", hdev->name);
413502b20f0bSLuiz Augusto von Dentz 
4136bf4c6325SGustavo F. Padovan 	rcu_read_lock();
4137bf4c6325SGustavo F. Padovan 
4138bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(conn, &h->list, list) {
413902b20f0bSLuiz Augusto von Dentz 		struct hci_chan *chan;
414002b20f0bSLuiz Augusto von Dentz 
414102b20f0bSLuiz Augusto von Dentz 		if (conn->type != type)
414202b20f0bSLuiz Augusto von Dentz 			continue;
414302b20f0bSLuiz Augusto von Dentz 
414402b20f0bSLuiz Augusto von Dentz 		if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG)
414502b20f0bSLuiz Augusto von Dentz 			continue;
414602b20f0bSLuiz Augusto von Dentz 
414702b20f0bSLuiz Augusto von Dentz 		num++;
414802b20f0bSLuiz Augusto von Dentz 
41498192edefSGustavo F. Padovan 		list_for_each_entry_rcu(chan, &conn->chan_list, list) {
415002b20f0bSLuiz Augusto von Dentz 			struct sk_buff *skb;
415102b20f0bSLuiz Augusto von Dentz 
415202b20f0bSLuiz Augusto von Dentz 			if (chan->sent) {
415302b20f0bSLuiz Augusto von Dentz 				chan->sent = 0;
415402b20f0bSLuiz Augusto von Dentz 				continue;
415502b20f0bSLuiz Augusto von Dentz 			}
415602b20f0bSLuiz Augusto von Dentz 
415702b20f0bSLuiz Augusto von Dentz 			if (skb_queue_empty(&chan->data_q))
415802b20f0bSLuiz Augusto von Dentz 				continue;
415902b20f0bSLuiz Augusto von Dentz 
416002b20f0bSLuiz Augusto von Dentz 			skb = skb_peek(&chan->data_q);
416102b20f0bSLuiz Augusto von Dentz 			if (skb->priority >= HCI_PRIO_MAX - 1)
416202b20f0bSLuiz Augusto von Dentz 				continue;
416302b20f0bSLuiz Augusto von Dentz 
416402b20f0bSLuiz Augusto von Dentz 			skb->priority = HCI_PRIO_MAX - 1;
416502b20f0bSLuiz Augusto von Dentz 
416602b20f0bSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p promoted to %d", chan, skb,
416702b20f0bSLuiz Augusto von Dentz 			       skb->priority);
416802b20f0bSLuiz Augusto von Dentz 		}
416902b20f0bSLuiz Augusto von Dentz 
417002b20f0bSLuiz Augusto von Dentz 		if (hci_conn_num(hdev, type) == num)
417102b20f0bSLuiz Augusto von Dentz 			break;
417202b20f0bSLuiz Augusto von Dentz 	}
4173bf4c6325SGustavo F. Padovan 
4174bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
4175bf4c6325SGustavo F. Padovan 
417602b20f0bSLuiz Augusto von Dentz }
417702b20f0bSLuiz Augusto von Dentz 
4178b71d385aSAndrei Emeltchenko static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
4179b71d385aSAndrei Emeltchenko {
4180b71d385aSAndrei Emeltchenko 	/* Calculate count of blocks used by this packet */
4181b71d385aSAndrei Emeltchenko 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
4182b71d385aSAndrei Emeltchenko }
4183b71d385aSAndrei Emeltchenko 
41846039aa73SGustavo Padovan static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
41851da177e4SLinus Torvalds {
41861da177e4SLinus Torvalds 	if (!test_bit(HCI_RAW, &hdev->flags)) {
41871da177e4SLinus Torvalds 		/* ACL tx timeout must be longer than maximum
41881da177e4SLinus Torvalds 		 * link supervision timeout (40.9 seconds) */
418963d2bc1bSAndrei Emeltchenko 		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
41905f246e89SAndrei Emeltchenko 				       HCI_ACL_TX_TIMEOUT))
4191bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, ACL_LINK);
41921da177e4SLinus Torvalds 	}
419363d2bc1bSAndrei Emeltchenko }
41941da177e4SLinus Torvalds 
41956039aa73SGustavo Padovan static void hci_sched_acl_pkt(struct hci_dev *hdev)
419663d2bc1bSAndrei Emeltchenko {
419763d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->acl_cnt;
419863d2bc1bSAndrei Emeltchenko 	struct hci_chan *chan;
419963d2bc1bSAndrei Emeltchenko 	struct sk_buff *skb;
420063d2bc1bSAndrei Emeltchenko 	int quote;
420163d2bc1bSAndrei Emeltchenko 
420263d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
420304837f64SMarcel Holtmann 
420473d80debSLuiz Augusto von Dentz 	while (hdev->acl_cnt &&
420573d80debSLuiz Augusto von Dentz 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
4206ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
4207ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
420873d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
420973d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
421073d80debSLuiz Augusto von Dentz 
4211ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
4212ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
4213ec1cce24SLuiz Augusto von Dentz 				break;
4214ec1cce24SLuiz Augusto von Dentz 
4215ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
4216ec1cce24SLuiz Augusto von Dentz 
421773d80debSLuiz Augusto von Dentz 			hci_conn_enter_active_mode(chan->conn,
421873d80debSLuiz Augusto von Dentz 						   bt_cb(skb)->force_active);
421904837f64SMarcel Holtmann 
422057d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
42211da177e4SLinus Torvalds 			hdev->acl_last_tx = jiffies;
42221da177e4SLinus Torvalds 
42231da177e4SLinus Torvalds 			hdev->acl_cnt--;
422473d80debSLuiz Augusto von Dentz 			chan->sent++;
422573d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
42261da177e4SLinus Torvalds 		}
42271da177e4SLinus Torvalds 	}
422802b20f0bSLuiz Augusto von Dentz 
422902b20f0bSLuiz Augusto von Dentz 	if (cnt != hdev->acl_cnt)
423002b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, ACL_LINK);
42311da177e4SLinus Torvalds }
42321da177e4SLinus Torvalds 
42336039aa73SGustavo Padovan static void hci_sched_acl_blk(struct hci_dev *hdev)
4234b71d385aSAndrei Emeltchenko {
423563d2bc1bSAndrei Emeltchenko 	unsigned int cnt = hdev->block_cnt;
4236b71d385aSAndrei Emeltchenko 	struct hci_chan *chan;
4237b71d385aSAndrei Emeltchenko 	struct sk_buff *skb;
4238b71d385aSAndrei Emeltchenko 	int quote;
4239bd1eb66bSAndrei Emeltchenko 	u8 type;
4240b71d385aSAndrei Emeltchenko 
424163d2bc1bSAndrei Emeltchenko 	__check_timeout(hdev, cnt);
4242b71d385aSAndrei Emeltchenko 
4243bd1eb66bSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
4244bd1eb66bSAndrei Emeltchenko 
4245bd1eb66bSAndrei Emeltchenko 	if (hdev->dev_type == HCI_AMP)
4246bd1eb66bSAndrei Emeltchenko 		type = AMP_LINK;
4247bd1eb66bSAndrei Emeltchenko 	else
4248bd1eb66bSAndrei Emeltchenko 		type = ACL_LINK;
4249bd1eb66bSAndrei Emeltchenko 
4250b71d385aSAndrei Emeltchenko 	while (hdev->block_cnt > 0 &&
4251bd1eb66bSAndrei Emeltchenko 	       (chan = hci_chan_sent(hdev, type, &quote))) {
4252b71d385aSAndrei Emeltchenko 		u32 priority = (skb_peek(&chan->data_q))->priority;
4253b71d385aSAndrei Emeltchenko 		while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
4254b71d385aSAndrei Emeltchenko 			int blocks;
4255b71d385aSAndrei Emeltchenko 
4256b71d385aSAndrei Emeltchenko 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
4257b71d385aSAndrei Emeltchenko 			       skb->len, skb->priority);
4258b71d385aSAndrei Emeltchenko 
4259b71d385aSAndrei Emeltchenko 			/* Stop if priority has changed */
4260b71d385aSAndrei Emeltchenko 			if (skb->priority < priority)
4261b71d385aSAndrei Emeltchenko 				break;
4262b71d385aSAndrei Emeltchenko 
4263b71d385aSAndrei Emeltchenko 			skb = skb_dequeue(&chan->data_q);
4264b71d385aSAndrei Emeltchenko 
4265b71d385aSAndrei Emeltchenko 			blocks = __get_blocks(hdev, skb);
4266b71d385aSAndrei Emeltchenko 			if (blocks > hdev->block_cnt)
4267b71d385aSAndrei Emeltchenko 				return;
4268b71d385aSAndrei Emeltchenko 
4269b71d385aSAndrei Emeltchenko 			hci_conn_enter_active_mode(chan->conn,
4270b71d385aSAndrei Emeltchenko 						   bt_cb(skb)->force_active);
4271b71d385aSAndrei Emeltchenko 
427257d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
4273b71d385aSAndrei Emeltchenko 			hdev->acl_last_tx = jiffies;
4274b71d385aSAndrei Emeltchenko 
4275b71d385aSAndrei Emeltchenko 			hdev->block_cnt -= blocks;
4276b71d385aSAndrei Emeltchenko 			quote -= blocks;
4277b71d385aSAndrei Emeltchenko 
4278b71d385aSAndrei Emeltchenko 			chan->sent += blocks;
4279b71d385aSAndrei Emeltchenko 			chan->conn->sent += blocks;
4280b71d385aSAndrei Emeltchenko 		}
4281b71d385aSAndrei Emeltchenko 	}
4282b71d385aSAndrei Emeltchenko 
4283b71d385aSAndrei Emeltchenko 	if (cnt != hdev->block_cnt)
4284bd1eb66bSAndrei Emeltchenko 		hci_prio_recalculate(hdev, type);
4285b71d385aSAndrei Emeltchenko }
4286b71d385aSAndrei Emeltchenko 
42876039aa73SGustavo Padovan static void hci_sched_acl(struct hci_dev *hdev)
4288b71d385aSAndrei Emeltchenko {
4289b71d385aSAndrei Emeltchenko 	BT_DBG("%s", hdev->name);
4290b71d385aSAndrei Emeltchenko 
4291bd1eb66bSAndrei Emeltchenko 	/* No ACL link over BR/EDR controller */
4292bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR)
4293bd1eb66bSAndrei Emeltchenko 		return;
4294bd1eb66bSAndrei Emeltchenko 
4295bd1eb66bSAndrei Emeltchenko 	/* No AMP link over AMP controller */
4296bd1eb66bSAndrei Emeltchenko 	if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
4297b71d385aSAndrei Emeltchenko 		return;
4298b71d385aSAndrei Emeltchenko 
4299b71d385aSAndrei Emeltchenko 	switch (hdev->flow_ctl_mode) {
4300b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_PACKET_BASED:
4301b71d385aSAndrei Emeltchenko 		hci_sched_acl_pkt(hdev);
4302b71d385aSAndrei Emeltchenko 		break;
4303b71d385aSAndrei Emeltchenko 
4304b71d385aSAndrei Emeltchenko 	case HCI_FLOW_CTL_MODE_BLOCK_BASED:
4305b71d385aSAndrei Emeltchenko 		hci_sched_acl_blk(hdev);
4306b71d385aSAndrei Emeltchenko 		break;
4307b71d385aSAndrei Emeltchenko 	}
4308b71d385aSAndrei Emeltchenko }
4309b71d385aSAndrei Emeltchenko 
43101da177e4SLinus Torvalds /* Schedule SCO */
43116039aa73SGustavo Padovan static void hci_sched_sco(struct hci_dev *hdev)
43121da177e4SLinus Torvalds {
43131da177e4SLinus Torvalds 	struct hci_conn *conn;
43141da177e4SLinus Torvalds 	struct sk_buff *skb;
43151da177e4SLinus Torvalds 	int quote;
43161da177e4SLinus Torvalds 
43171da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
43181da177e4SLinus Torvalds 
431952087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, SCO_LINK))
432052087a79SLuiz Augusto von Dentz 		return;
432152087a79SLuiz Augusto von Dentz 
43221da177e4SLinus Torvalds 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
43231da177e4SLinus Torvalds 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
43241da177e4SLinus Torvalds 			BT_DBG("skb %p len %d", skb, skb->len);
432557d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
43261da177e4SLinus Torvalds 
43271da177e4SLinus Torvalds 			conn->sent++;
43281da177e4SLinus Torvalds 			if (conn->sent == ~0)
43291da177e4SLinus Torvalds 				conn->sent = 0;
43301da177e4SLinus Torvalds 		}
43311da177e4SLinus Torvalds 	}
43321da177e4SLinus Torvalds }
43331da177e4SLinus Torvalds 
43346039aa73SGustavo Padovan static void hci_sched_esco(struct hci_dev *hdev)
4335b6a0dc82SMarcel Holtmann {
4336b6a0dc82SMarcel Holtmann 	struct hci_conn *conn;
4337b6a0dc82SMarcel Holtmann 	struct sk_buff *skb;
4338b6a0dc82SMarcel Holtmann 	int quote;
4339b6a0dc82SMarcel Holtmann 
4340b6a0dc82SMarcel Holtmann 	BT_DBG("%s", hdev->name);
4341b6a0dc82SMarcel Holtmann 
434252087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, ESCO_LINK))
434352087a79SLuiz Augusto von Dentz 		return;
434452087a79SLuiz Augusto von Dentz 
43458fc9ced3SGustavo Padovan 	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK,
43468fc9ced3SGustavo Padovan 						     &quote))) {
4347b6a0dc82SMarcel Holtmann 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
4348b6a0dc82SMarcel Holtmann 			BT_DBG("skb %p len %d", skb, skb->len);
434957d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
4350b6a0dc82SMarcel Holtmann 
4351b6a0dc82SMarcel Holtmann 			conn->sent++;
4352b6a0dc82SMarcel Holtmann 			if (conn->sent == ~0)
4353b6a0dc82SMarcel Holtmann 				conn->sent = 0;
4354b6a0dc82SMarcel Holtmann 		}
4355b6a0dc82SMarcel Holtmann 	}
4356b6a0dc82SMarcel Holtmann }
4357b6a0dc82SMarcel Holtmann 
43586039aa73SGustavo Padovan static void hci_sched_le(struct hci_dev *hdev)
43596ed58ec5SVille Tervo {
436073d80debSLuiz Augusto von Dentz 	struct hci_chan *chan;
43616ed58ec5SVille Tervo 	struct sk_buff *skb;
436202b20f0bSLuiz Augusto von Dentz 	int quote, cnt, tmp;
43636ed58ec5SVille Tervo 
43646ed58ec5SVille Tervo 	BT_DBG("%s", hdev->name);
43656ed58ec5SVille Tervo 
436652087a79SLuiz Augusto von Dentz 	if (!hci_conn_num(hdev, LE_LINK))
436752087a79SLuiz Augusto von Dentz 		return;
436852087a79SLuiz Augusto von Dentz 
43696ed58ec5SVille Tervo 	if (!test_bit(HCI_RAW, &hdev->flags)) {
43706ed58ec5SVille Tervo 		/* LE tx timeout must be longer than maximum
43716ed58ec5SVille Tervo 		 * link supervision timeout (40.9 seconds) */
4372bae1f5d9SVille Tervo 		if (!hdev->le_cnt && hdev->le_pkts &&
43736ed58ec5SVille Tervo 		    time_after(jiffies, hdev->le_last_tx + HZ * 45))
4374bae1f5d9SVille Tervo 			hci_link_tx_to(hdev, LE_LINK);
43756ed58ec5SVille Tervo 	}
43766ed58ec5SVille Tervo 
43776ed58ec5SVille Tervo 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
437802b20f0bSLuiz Augusto von Dentz 	tmp = cnt;
437973d80debSLuiz Augusto von Dentz 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
4380ec1cce24SLuiz Augusto von Dentz 		u32 priority = (skb_peek(&chan->data_q))->priority;
4381ec1cce24SLuiz Augusto von Dentz 		while (quote-- && (skb = skb_peek(&chan->data_q))) {
438273d80debSLuiz Augusto von Dentz 			BT_DBG("chan %p skb %p len %d priority %u", chan, skb,
438373d80debSLuiz Augusto von Dentz 			       skb->len, skb->priority);
43846ed58ec5SVille Tervo 
4385ec1cce24SLuiz Augusto von Dentz 			/* Stop if priority has changed */
4386ec1cce24SLuiz Augusto von Dentz 			if (skb->priority < priority)
4387ec1cce24SLuiz Augusto von Dentz 				break;
4388ec1cce24SLuiz Augusto von Dentz 
4389ec1cce24SLuiz Augusto von Dentz 			skb = skb_dequeue(&chan->data_q);
4390ec1cce24SLuiz Augusto von Dentz 
439157d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
43926ed58ec5SVille Tervo 			hdev->le_last_tx = jiffies;
43936ed58ec5SVille Tervo 
43946ed58ec5SVille Tervo 			cnt--;
439573d80debSLuiz Augusto von Dentz 			chan->sent++;
439673d80debSLuiz Augusto von Dentz 			chan->conn->sent++;
43976ed58ec5SVille Tervo 		}
43986ed58ec5SVille Tervo 	}
439973d80debSLuiz Augusto von Dentz 
44006ed58ec5SVille Tervo 	if (hdev->le_pkts)
44016ed58ec5SVille Tervo 		hdev->le_cnt = cnt;
44026ed58ec5SVille Tervo 	else
44036ed58ec5SVille Tervo 		hdev->acl_cnt = cnt;
440402b20f0bSLuiz Augusto von Dentz 
440502b20f0bSLuiz Augusto von Dentz 	if (cnt != tmp)
440602b20f0bSLuiz Augusto von Dentz 		hci_prio_recalculate(hdev, LE_LINK);
44076ed58ec5SVille Tervo }
44086ed58ec5SVille Tervo 
44093eff45eaSGustavo F. Padovan static void hci_tx_work(struct work_struct *work)
44101da177e4SLinus Torvalds {
44113eff45eaSGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work);
44121da177e4SLinus Torvalds 	struct sk_buff *skb;
44131da177e4SLinus Torvalds 
44146ed58ec5SVille Tervo 	BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
44156ed58ec5SVille Tervo 	       hdev->sco_cnt, hdev->le_cnt);
44161da177e4SLinus Torvalds 
441752de599eSMarcel Holtmann 	if (!test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
44181da177e4SLinus Torvalds 		/* Schedule queues and send stuff to HCI driver */
44191da177e4SLinus Torvalds 		hci_sched_acl(hdev);
44201da177e4SLinus Torvalds 		hci_sched_sco(hdev);
4421b6a0dc82SMarcel Holtmann 		hci_sched_esco(hdev);
44226ed58ec5SVille Tervo 		hci_sched_le(hdev);
442352de599eSMarcel Holtmann 	}
44246ed58ec5SVille Tervo 
44251da177e4SLinus Torvalds 	/* Send next queued raw (unknown type) packet */
44261da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->raw_q)))
442757d17d70SMarcel Holtmann 		hci_send_frame(hdev, skb);
44281da177e4SLinus Torvalds }
44291da177e4SLinus Torvalds 
443025985edcSLucas De Marchi /* ----- HCI RX task (incoming data processing) ----- */
44311da177e4SLinus Torvalds 
44321da177e4SLinus Torvalds /* ACL data packet */
44336039aa73SGustavo Padovan static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
44341da177e4SLinus Torvalds {
44351da177e4SLinus Torvalds 	struct hci_acl_hdr *hdr = (void *) skb->data;
44361da177e4SLinus Torvalds 	struct hci_conn *conn;
44371da177e4SLinus Torvalds 	__u16 handle, flags;
44381da177e4SLinus Torvalds 
44391da177e4SLinus Torvalds 	skb_pull(skb, HCI_ACL_HDR_SIZE);
44401da177e4SLinus Torvalds 
44411da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
44421da177e4SLinus Torvalds 	flags  = hci_flags(handle);
44431da177e4SLinus Torvalds 	handle = hci_handle(handle);
44441da177e4SLinus Torvalds 
4445f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len,
4446a8c5fb1aSGustavo Padovan 	       handle, flags);
44471da177e4SLinus Torvalds 
44481da177e4SLinus Torvalds 	hdev->stat.acl_rx++;
44491da177e4SLinus Torvalds 
44501da177e4SLinus Torvalds 	hci_dev_lock(hdev);
44511da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
44521da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
44531da177e4SLinus Torvalds 
44541da177e4SLinus Torvalds 	if (conn) {
445565983fc7SMat Martineau 		hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
445604837f64SMarcel Holtmann 
44571da177e4SLinus Torvalds 		/* Send to upper protocol */
4458686ebf28SUlisses Furquim 		l2cap_recv_acldata(conn, skb, flags);
44591da177e4SLinus Torvalds 		return;
44601da177e4SLinus Torvalds 	} else {
44611da177e4SLinus Torvalds 		BT_ERR("%s ACL packet for unknown connection handle %d",
44621da177e4SLinus Torvalds 		       hdev->name, handle);
44631da177e4SLinus Torvalds 	}
44641da177e4SLinus Torvalds 
44651da177e4SLinus Torvalds 	kfree_skb(skb);
44661da177e4SLinus Torvalds }
44671da177e4SLinus Torvalds 
44681da177e4SLinus Torvalds /* SCO data packet */
44696039aa73SGustavo Padovan static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
44701da177e4SLinus Torvalds {
44711da177e4SLinus Torvalds 	struct hci_sco_hdr *hdr = (void *) skb->data;
44721da177e4SLinus Torvalds 	struct hci_conn *conn;
44731da177e4SLinus Torvalds 	__u16 handle;
44741da177e4SLinus Torvalds 
44751da177e4SLinus Torvalds 	skb_pull(skb, HCI_SCO_HDR_SIZE);
44761da177e4SLinus Torvalds 
44771da177e4SLinus Torvalds 	handle = __le16_to_cpu(hdr->handle);
44781da177e4SLinus Torvalds 
4479f0e09510SAndrei Emeltchenko 	BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle);
44801da177e4SLinus Torvalds 
44811da177e4SLinus Torvalds 	hdev->stat.sco_rx++;
44821da177e4SLinus Torvalds 
44831da177e4SLinus Torvalds 	hci_dev_lock(hdev);
44841da177e4SLinus Torvalds 	conn = hci_conn_hash_lookup_handle(hdev, handle);
44851da177e4SLinus Torvalds 	hci_dev_unlock(hdev);
44861da177e4SLinus Torvalds 
44871da177e4SLinus Torvalds 	if (conn) {
44881da177e4SLinus Torvalds 		/* Send to upper protocol */
4489686ebf28SUlisses Furquim 		sco_recv_scodata(conn, skb);
44901da177e4SLinus Torvalds 		return;
44911da177e4SLinus Torvalds 	} else {
44921da177e4SLinus Torvalds 		BT_ERR("%s SCO packet for unknown connection handle %d",
44931da177e4SLinus Torvalds 		       hdev->name, handle);
44941da177e4SLinus Torvalds 	}
44951da177e4SLinus Torvalds 
44961da177e4SLinus Torvalds 	kfree_skb(skb);
44971da177e4SLinus Torvalds }
44981da177e4SLinus Torvalds 
44999238f36aSJohan Hedberg static bool hci_req_is_complete(struct hci_dev *hdev)
45009238f36aSJohan Hedberg {
45019238f36aSJohan Hedberg 	struct sk_buff *skb;
45029238f36aSJohan Hedberg 
45039238f36aSJohan Hedberg 	skb = skb_peek(&hdev->cmd_q);
45049238f36aSJohan Hedberg 	if (!skb)
45059238f36aSJohan Hedberg 		return true;
45069238f36aSJohan Hedberg 
45079238f36aSJohan Hedberg 	return bt_cb(skb)->req.start;
45089238f36aSJohan Hedberg }
45099238f36aSJohan Hedberg 
451042c6b129SJohan Hedberg static void hci_resend_last(struct hci_dev *hdev)
451142c6b129SJohan Hedberg {
451242c6b129SJohan Hedberg 	struct hci_command_hdr *sent;
451342c6b129SJohan Hedberg 	struct sk_buff *skb;
451442c6b129SJohan Hedberg 	u16 opcode;
451542c6b129SJohan Hedberg 
451642c6b129SJohan Hedberg 	if (!hdev->sent_cmd)
451742c6b129SJohan Hedberg 		return;
451842c6b129SJohan Hedberg 
451942c6b129SJohan Hedberg 	sent = (void *) hdev->sent_cmd->data;
452042c6b129SJohan Hedberg 	opcode = __le16_to_cpu(sent->opcode);
452142c6b129SJohan Hedberg 	if (opcode == HCI_OP_RESET)
452242c6b129SJohan Hedberg 		return;
452342c6b129SJohan Hedberg 
452442c6b129SJohan Hedberg 	skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
452542c6b129SJohan Hedberg 	if (!skb)
452642c6b129SJohan Hedberg 		return;
452742c6b129SJohan Hedberg 
452842c6b129SJohan Hedberg 	skb_queue_head(&hdev->cmd_q, skb);
452942c6b129SJohan Hedberg 	queue_work(hdev->workqueue, &hdev->cmd_work);
453042c6b129SJohan Hedberg }
453142c6b129SJohan Hedberg 
45329238f36aSJohan Hedberg void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status)
45339238f36aSJohan Hedberg {
45349238f36aSJohan Hedberg 	hci_req_complete_t req_complete = NULL;
45359238f36aSJohan Hedberg 	struct sk_buff *skb;
45369238f36aSJohan Hedberg 	unsigned long flags;
45379238f36aSJohan Hedberg 
45389238f36aSJohan Hedberg 	BT_DBG("opcode 0x%04x status 0x%02x", opcode, status);
45399238f36aSJohan Hedberg 
454042c6b129SJohan Hedberg 	/* If the completed command doesn't match the last one that was
454142c6b129SJohan Hedberg 	 * sent we need to do special handling of it.
45429238f36aSJohan Hedberg 	 */
454342c6b129SJohan Hedberg 	if (!hci_sent_cmd_data(hdev, opcode)) {
454442c6b129SJohan Hedberg 		/* Some CSR based controllers generate a spontaneous
454542c6b129SJohan Hedberg 		 * reset complete event during init and any pending
454642c6b129SJohan Hedberg 		 * command will never be completed. In such a case we
454742c6b129SJohan Hedberg 		 * need to resend whatever was the last sent
454842c6b129SJohan Hedberg 		 * command.
454942c6b129SJohan Hedberg 		 */
455042c6b129SJohan Hedberg 		if (test_bit(HCI_INIT, &hdev->flags) && opcode == HCI_OP_RESET)
455142c6b129SJohan Hedberg 			hci_resend_last(hdev);
455242c6b129SJohan Hedberg 
45539238f36aSJohan Hedberg 		return;
455442c6b129SJohan Hedberg 	}
45559238f36aSJohan Hedberg 
45569238f36aSJohan Hedberg 	/* If the command succeeded and there's still more commands in
45579238f36aSJohan Hedberg 	 * this request the request is not yet complete.
45589238f36aSJohan Hedberg 	 */
45599238f36aSJohan Hedberg 	if (!status && !hci_req_is_complete(hdev))
45609238f36aSJohan Hedberg 		return;
45619238f36aSJohan Hedberg 
45629238f36aSJohan Hedberg 	/* If this was the last command in a request the complete
45639238f36aSJohan Hedberg 	 * callback would be found in hdev->sent_cmd instead of the
45649238f36aSJohan Hedberg 	 * command queue (hdev->cmd_q).
45659238f36aSJohan Hedberg 	 */
45669238f36aSJohan Hedberg 	if (hdev->sent_cmd) {
45679238f36aSJohan Hedberg 		req_complete = bt_cb(hdev->sent_cmd)->req.complete;
456853e21fbcSJohan Hedberg 
456953e21fbcSJohan Hedberg 		if (req_complete) {
457053e21fbcSJohan Hedberg 			/* We must set the complete callback to NULL to
457153e21fbcSJohan Hedberg 			 * avoid calling the callback more than once if
457253e21fbcSJohan Hedberg 			 * this function gets called again.
457353e21fbcSJohan Hedberg 			 */
457453e21fbcSJohan Hedberg 			bt_cb(hdev->sent_cmd)->req.complete = NULL;
457553e21fbcSJohan Hedberg 
45769238f36aSJohan Hedberg 			goto call_complete;
45779238f36aSJohan Hedberg 		}
457853e21fbcSJohan Hedberg 	}
45799238f36aSJohan Hedberg 
45809238f36aSJohan Hedberg 	/* Remove all pending commands belonging to this request */
45819238f36aSJohan Hedberg 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
45829238f36aSJohan Hedberg 	while ((skb = __skb_dequeue(&hdev->cmd_q))) {
45839238f36aSJohan Hedberg 		if (bt_cb(skb)->req.start) {
45849238f36aSJohan Hedberg 			__skb_queue_head(&hdev->cmd_q, skb);
45859238f36aSJohan Hedberg 			break;
45869238f36aSJohan Hedberg 		}
45879238f36aSJohan Hedberg 
45889238f36aSJohan Hedberg 		req_complete = bt_cb(skb)->req.complete;
45899238f36aSJohan Hedberg 		kfree_skb(skb);
45909238f36aSJohan Hedberg 	}
45919238f36aSJohan Hedberg 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
45929238f36aSJohan Hedberg 
45939238f36aSJohan Hedberg call_complete:
45949238f36aSJohan Hedberg 	if (req_complete)
45959238f36aSJohan Hedberg 		req_complete(hdev, status);
45969238f36aSJohan Hedberg }
45979238f36aSJohan Hedberg 
4598b78752ccSMarcel Holtmann static void hci_rx_work(struct work_struct *work)
45991da177e4SLinus Torvalds {
4600b78752ccSMarcel Holtmann 	struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work);
46011da177e4SLinus Torvalds 	struct sk_buff *skb;
46021da177e4SLinus Torvalds 
46031da177e4SLinus Torvalds 	BT_DBG("%s", hdev->name);
46041da177e4SLinus Torvalds 
46051da177e4SLinus Torvalds 	while ((skb = skb_dequeue(&hdev->rx_q))) {
4606cd82e61cSMarcel Holtmann 		/* Send copy to monitor */
4607cd82e61cSMarcel Holtmann 		hci_send_to_monitor(hdev, skb);
4608cd82e61cSMarcel Holtmann 
46091da177e4SLinus Torvalds 		if (atomic_read(&hdev->promisc)) {
46101da177e4SLinus Torvalds 			/* Send copy to the sockets */
4611470fe1b5SMarcel Holtmann 			hci_send_to_sock(hdev, skb);
46121da177e4SLinus Torvalds 		}
46131da177e4SLinus Torvalds 
46140736cfa8SMarcel Holtmann 		if (test_bit(HCI_RAW, &hdev->flags) ||
46150736cfa8SMarcel Holtmann 		    test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
46161da177e4SLinus Torvalds 			kfree_skb(skb);
46171da177e4SLinus Torvalds 			continue;
46181da177e4SLinus Torvalds 		}
46191da177e4SLinus Torvalds 
46201da177e4SLinus Torvalds 		if (test_bit(HCI_INIT, &hdev->flags)) {
46211da177e4SLinus Torvalds 			/* Don't process data packets in this states. */
46220d48d939SMarcel Holtmann 			switch (bt_cb(skb)->pkt_type) {
46231da177e4SLinus Torvalds 			case HCI_ACLDATA_PKT:
46241da177e4SLinus Torvalds 			case HCI_SCODATA_PKT:
46251da177e4SLinus Torvalds 				kfree_skb(skb);
46261da177e4SLinus Torvalds 				continue;
46273ff50b79SStephen Hemminger 			}
46281da177e4SLinus Torvalds 		}
46291da177e4SLinus Torvalds 
46301da177e4SLinus Torvalds 		/* Process frame */
46310d48d939SMarcel Holtmann 		switch (bt_cb(skb)->pkt_type) {
46321da177e4SLinus Torvalds 		case HCI_EVENT_PKT:
4633b78752ccSMarcel Holtmann 			BT_DBG("%s Event packet", hdev->name);
46341da177e4SLinus Torvalds 			hci_event_packet(hdev, skb);
46351da177e4SLinus Torvalds 			break;
46361da177e4SLinus Torvalds 
46371da177e4SLinus Torvalds 		case HCI_ACLDATA_PKT:
46381da177e4SLinus Torvalds 			BT_DBG("%s ACL data packet", hdev->name);
46391da177e4SLinus Torvalds 			hci_acldata_packet(hdev, skb);
46401da177e4SLinus Torvalds 			break;
46411da177e4SLinus Torvalds 
46421da177e4SLinus Torvalds 		case HCI_SCODATA_PKT:
46431da177e4SLinus Torvalds 			BT_DBG("%s SCO data packet", hdev->name);
46441da177e4SLinus Torvalds 			hci_scodata_packet(hdev, skb);
46451da177e4SLinus Torvalds 			break;
46461da177e4SLinus Torvalds 
46471da177e4SLinus Torvalds 		default:
46481da177e4SLinus Torvalds 			kfree_skb(skb);
46491da177e4SLinus Torvalds 			break;
46501da177e4SLinus Torvalds 		}
46511da177e4SLinus Torvalds 	}
46521da177e4SLinus Torvalds }
46531da177e4SLinus Torvalds 
4654c347b765SGustavo F. Padovan static void hci_cmd_work(struct work_struct *work)
46551da177e4SLinus Torvalds {
4656c347b765SGustavo F. Padovan 	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
46571da177e4SLinus Torvalds 	struct sk_buff *skb;
46581da177e4SLinus Torvalds 
46592104786bSAndrei Emeltchenko 	BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name,
46602104786bSAndrei Emeltchenko 	       atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q));
46611da177e4SLinus Torvalds 
46621da177e4SLinus Torvalds 	/* Send queued commands */
46635a08ecceSAndrei Emeltchenko 	if (atomic_read(&hdev->cmd_cnt)) {
46645a08ecceSAndrei Emeltchenko 		skb = skb_dequeue(&hdev->cmd_q);
46655a08ecceSAndrei Emeltchenko 		if (!skb)
46665a08ecceSAndrei Emeltchenko 			return;
46675a08ecceSAndrei Emeltchenko 
46681da177e4SLinus Torvalds 		kfree_skb(hdev->sent_cmd);
46691da177e4SLinus Torvalds 
4670a675d7f1SMarcel Holtmann 		hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
467170f23020SAndrei Emeltchenko 		if (hdev->sent_cmd) {
46721da177e4SLinus Torvalds 			atomic_dec(&hdev->cmd_cnt);
467357d17d70SMarcel Holtmann 			hci_send_frame(hdev, skb);
46747bdb8a5cSSzymon Janc 			if (test_bit(HCI_RESET, &hdev->flags))
46757bdb8a5cSSzymon Janc 				del_timer(&hdev->cmd_timer);
46767bdb8a5cSSzymon Janc 			else
46776bd32326SVille Tervo 				mod_timer(&hdev->cmd_timer,
46785f246e89SAndrei Emeltchenko 					  jiffies + HCI_CMD_TIMEOUT);
46791da177e4SLinus Torvalds 		} else {
46801da177e4SLinus Torvalds 			skb_queue_head(&hdev->cmd_q, skb);
4681c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
46821da177e4SLinus Torvalds 		}
46831da177e4SLinus Torvalds 	}
46841da177e4SLinus Torvalds }
4685